home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser-CD 1999 January / STC_CD_01_1999.iso / base / pd_ph105 / pd_lib.c < prev    next >
C/C++ Source or Header  |  2000-01-08  |  40KB  |  1,233 lines

  1. /*             V 1.05
  2.         (c) 1997,98 by Dimitri Junker
  3.             Adenauerallee 30
  4.             52066 Aachen    */
  5.             
  6. /* Dies sind die C-Funktionen, die in PD eingefügt werden können*/
  7. /* Zum Sprachgebrauch: Bei der 2 Monitorlösung unterscheide ich zwischen:
  8. AES-Monitor: der über den das AES ausgibt, also der an der Grafikkarte
  9. Bitmap-Monitor: der, der per Offscreen-Bitmap beschrieben wird
  10.     und am Original-Videoshifter hängt
  11.     
  12. Alle Routinennamen enden mit _1,_0,_2 oder _x, dabei bedeutet:
  13. _1 : Routinen für den 1 Monitorbetrieb
  14. _2 : Routinen für den 2 Monitorbetrieb
  15. _x : Routinen für die implementierung von XBRA (unabhängig von der Anzahl Monitore)
  16. _0 : alle anderen (unabhängig von der Anzahl Monitore)
  17. */
  18.     
  19. /* -------------------------------------------------------------------- */
  20. /*        Includes                                                        */
  21. /* -------------------------------------------------------------------- */
  22. #include <vdi.h>
  23. #include <aes.h>
  24. #include <stddef.h>
  25. #include "patch.h"
  26. #include "grafik.h"
  27.  
  28. /* -------------------------------------------------------------------- */
  29. /*       Makros. & Konstanten                                           */
  30. /* -------------------------------------------------------------------- */
  31.  
  32. #define min(a, b)             ((a) < (b) ? (a) : (b))
  33. #define _sysbase    (0x4f2l)
  34. #define        EdDI_1_1    1
  35. #define        NOVA        2
  36.  
  37. /* Die 3 logischen Monitore    */
  38. #define BITMAP_MON1        0
  39. #define BITMAP_MON2        1
  40. #define AES_MON            2
  41.  
  42. /* Die folgenden Konstanten beschreiben die vorhandene Grafikhardware*/
  43. #define ST_MOD        0
  44. #define TT_MOD        2
  45.  
  46. /* -------------------------------------------------------------------- */
  47. /*        typedefs                                                        */
  48. /* -------------------------------------------------------------------- */
  49.  
  50. typedef char BOOLEAN;
  51. typedef struct BL
  52. {    struct BL*        bl_next;
  53.     unsigned long    bl_len;
  54. }BLOCK;
  55.  
  56. typedef struct XB
  57. {
  58.     long         xb_magic;         /* "XBRA" = 0x58425241       */
  59.     long         xb_id;              /* ID aus vier ASCII-Zeichen */
  60.     struct XB    *xb_oldvec;     /* alter Wert des Vektors    */
  61.  
  62. } XBRA;
  63.  
  64. /* -------------------------------------------------------------------- */
  65. /*         lokale Funktionsprototypen                                        */
  66. /* -------------------------------------------------------------------- */
  67.  
  68. void prg_reset_a(void);
  69. void Set_Gd_trm(void);
  70. long init_sup_0(void);
  71. long init_sup_2(void);
  72. long set_mon_2(void);
  73. long  get_cookie_jar_0();
  74. BOOLEAN get_cookie_0(long cookie_name, LONG *cookie_value);
  75. void draw_menu(void);
  76. void v_opn_init_2( int *work_in_alt, int *handle,int *work_out );
  77. long  Supexec_0( long (*func)( ));
  78. void vdi_2( VDIPB *vdipb );
  79. BASPAG *get_act_pd_0(void);
  80. void tst_sysv_x(BLOCK *mem);
  81. void tst_1sysv_x(BLOCK *mem,int vec,XBRA **addr);
  82. int mfree_l1_0(BLOCK *mem);
  83. void mfree_a_sp_0(void);
  84. void mfree_a_sp(void);
  85. void res_sysv_x(void (*exchdlr)() ,int vec,XBRA **addr);
  86. int memcpyx( void *dest, const void *src, size_t len );
  87.  
  88. /* -------------------------------------------------------------------- */
  89. /*        Globale Variablen                                                */
  90. /* -------------------------------------------------------------------- */
  91.  
  92. extern MFDB M_pd;
  93. extern PDX X_pd;
  94. extern int b_23E58;
  95. extern void *Mem_l1,*Prg_a_sp;
  96. extern void (*Ptr_Gemd)(),(*Ptr_term)(),(*Ptr_scrd)(),(*Ptr_vb)() ;
  97. extern long My_id;
  98.  
  99. /* -------------------------------------------------------------------- */
  100. /*        Funktionen                                                        */
  101. /* -------------------------------------------------------------------- */
  102.  
  103.  
  104.  
  105. /* -------------------------------------------------------------------- */
  106. /*    Routinen die sowohl für den 1 als auch den 2 Monitorbetrieb         */
  107. /*    verwendet werden au₧er XBRA     ( _0)                                    */
  108. /* -------------------------------------------------------------------- */
  109.  
  110. /*------------------------------------------------------------------*/
  111. /*            long init_sup_0(void)                                    */
  112. /*                                                                    */
  113. /*            Der Teil der Initialisierung, der im Supervisormodus    */
  114. /*            ausgeführt werden mu₧. Wird von v_opn_init_1 und _2        */
  115. /*            benutzt.                                                */
  116. /*            Als long, damit es direkt von Supexec ausgeführt        */
  117. /*            werden kann                                             */
  118. /*        Parameter: keine                                            */
  119. /*        Rückgabe : 0 als Dummy                                        */
  120. /*                                                                    */
  121. /*        (c) Dimitri Junker                                            */
  122. /*                                                                    */
  123. /*------------------------------------------------------------------*/
  124.  
  125. long init_sup_0(void)
  126. {
  127.     /*     hier wird ermittelt, ob TRAP 6 oder 8 Byte auf den SSP    legt.
  128.         Shortframe oder Longframe                                    */
  129.  
  130.     X_pd.p_frame=((*(int *)0x59EL) ? 8 : 6 );
  131.     
  132.     /* Basepage ermitteln    */
  133.  
  134.     X_pd.p_bp=get_act_pd_0();
  135.  
  136.     return(0);
  137. }    
  138.  
  139.  
  140. /*------------------------------------------------------------------*/
  141. /*            BASPAG *get_act_pd_0(void)                                */
  142. /*                                                                    */
  143. /*            Basepage des aktuellen Proz. ermitteln                    */
  144. /*            nach Profibuch S.185                                    */
  145. /*                                                                    */
  146. /*        Parameter:     keine                                            */
  147. /*        Rückgabe :     die Basepage                                    */
  148. /*                                                                    */
  149. /*        (c) Dimitri Junker                                            */
  150. /*                                                                    */
  151. /*------------------------------------------------------------------*/
  152. BASPAG * get_act_pd_0(void)
  153. {    SYSHDR *os;
  154.     os=*(SYSHDR **)_sysbase;
  155.     os=os->os_base;
  156.     return((BASPAG *)*os->_run);
  157. }
  158.  
  159. /*------------------------------------------------------------------*/
  160. /*            void reset_0(void )                                        */
  161. /*                                                                    */
  162. /*             fügt beim Programm-Reset auch noch ein Fclose aller        */
  163. /*             offenen Dateien durch, ruft dann das Original auf        */
  164. /*                                                                    */
  165. /*        Parameter:     keine                                            */
  166. /*        Rückgabe :     keine                                            */
  167. /*                                                                    */
  168. /*        (c) Dimitri Junker                                            */
  169. /*                                                                    */
  170. /*------------------------------------------------------------------*/
  171.  
  172. void reset_0(void )
  173. {    int i;
  174.     long tst;
  175.     tst=64l;
  176.     for(i=6;i<32;i++) 
  177.     {    if((X_pd.p_flags[1]&tst)!=0l)
  178.             Fclose(i);
  179.         tst*=2l;
  180.     }
  181.     tst=1l;
  182.     for(i=32;i<64;i++) 
  183.     {    if((X_pd.p_flags[0]&tst)!=0l)
  184.             Fclose(i);
  185.         tst*=2l;
  186.     }
  187. /* Diese Abfrage ist eigentlich Teil des Original reset, wird aber
  188. beim Patch überschrieben, s. Patch.C    */
  189.     if(b_23E58!=-1)    
  190.         prg_reset_a();
  191.     
  192. }
  193.  
  194. /*------------------------------------------------------------------*/
  195. /*        BOOLEAN get_cookie_0(long cookie_name, LONG *cookie_value)    */
  196. /*        Ermittelt den Wert eines Cookies                            */
  197. /*        kommt auch in EASYFSEL.C vor                                */
  198. /*        Parameter:     cookie_name: Name des zu suchenden Cookies        */
  199. /*                    *cookie_value: Pointer für die Rückgabe            */
  200. /*        Rückgabe :     0,1: 1=erfolgreich                                */
  201. /*                    falls 1: Wert des Cookies in cookie_value        */
  202. /*                                                                    */
  203. /*        (c) Dimitri Junker                                            */
  204. /*                                                                    */
  205. /*------------------------------------------------------------------*/
  206.  
  207. BOOLEAN get_cookie_0(long cookie_name, LONG *cookie_value)
  208. {
  209.     LONG *cookie;
  210.     int ret;
  211.     
  212.     /* Zuerst einen Zeiger auf den Cookie holen */
  213.  
  214.     if((cookie = (long *)Supexec_0(get_cookie_jar_0))==NULL)
  215.         ret=0;
  216.     else
  217.     {
  218.         do
  219.         {
  220.             /* Ist es unser Cookie ? */
  221.             if(*cookie== cookie_name)
  222.                 break;
  223.             else
  224.             {
  225.                 /* nächster Cookie aus Jar */
  226.                 cookie = &(cookie[2]);
  227.             }
  228.         } 
  229.         while(cookie[0]);  /* solange nicht NULL-Cookie */
  230.     
  231.         if(!cookie[0])
  232.             ret=0;
  233.         else
  234.         {    *cookie_value=cookie[1];
  235.             ret=1;
  236.         }
  237.     }
  238.     return(ret);
  239. }
  240. /*------------------------------------------------------------------*/
  241. /*    long get_cookie_jar_0()                                            */
  242. /*                                                                    */
  243. /*    Ermittelt die Adresse des Cookie Jar.                            */
  244. /*        kommt auch in EASYFSEL.C vor                                */
  245. /*                                                                    */
  246. /*    Parameter:keine                                                     */
  247. /*    Rückgabe :Adresse, falls der Cookie Jar gefunden wurde,            */
  248. /*              NULL falls kein Cookie-Jar                            */
  249. /*  Besonderheit: mu₧ per Supexec aufgerufen werden                    */
  250. /*    (c) by Dimitri Junker 1996                                        */
  251. /*------------------------------------------------------------------*/
  252.  
  253. long  get_cookie_jar_0()
  254. {
  255.     LONG *cookiejar;
  256.  
  257.     cookiejar = *((LONG **) 0x5a0L);
  258.     return((long)cookiejar);
  259. }
  260.  
  261. /*------------------------------------------------------------------*/
  262. /*            void *malloc_high_0(unsigned long len)                    */
  263. /*                                                                    */
  264. /*             Diese Routine reserviert Speicher an möglichst hoher    */
  265. /*            Stelle. Sie entstand aus der Originalroutine, die ich     */
  266. /*            per Hand von Assembler nach C rückcompiliert habe.        */
  267. /*            Ursprünglich nur um zu sehen was sie macht. Dabei        */
  268. /*            fielen mir aber 2 Fehler auf, sie sind unten beschrieben*/
  269. /*                                                                    */
  270. /*        Parameter:     Die Länge des gewünschten Speichers                */
  271. /*        Rückgabe :     Pointer auf den reservierten Speicher oder        */
  272. /*                    NULL falls nicht erfolgreich                    */
  273. /*                                                                    */
  274. /*                                                                    */
  275. /*------------------------------------------------------------------*/
  276.  
  277. void *malloc_high_0(unsigned long len)
  278. {    BLOCK *block,*h_block_1,*h_block_2;
  279.     unsigned long len_1;
  280.     
  281.     len+=8;
  282.     len=(len+3)&0xfffffffcl;
  283.     h_block_1=NULL;
  284. /* Solange grö₧te Speicherblöcke reservieren wie >8 Byte vorhanden 
  285.     und verketten*/
  286.     while(1)
  287.     {    len_1=(long)Malloc(-1);
  288.         if(len_1<8)
  289.             break;
  290.         block=Malloc(len_1);
  291.         /* im Original wurde abgebrochen wenn Malloc erfolglos ist.
  292.             dies ist bei einem Multitasking-BS aber unsinnig    */
  293.         if(block)
  294.         {    block->bl_next=h_block_1;
  295.             block->bl_len=len_1;
  296.             h_block_1=block;
  297.         }
  298.     }
  299.     h_block_2=NULL;
  300.     block=h_block_1;    /* letzter erfolgreicher    */
  301. /*    sucht genügend gro₧en Block mit höchster Addresse    */
  302.     while(block)
  303.     {    if( block>h_block_2)
  304.         {    if(len <= block->bl_len)
  305.                 h_block_2 = block;
  306.         }
  307.         block=block->bl_next;
  308.     }
  309. /* Falls Block zu gro₧ nur oberen Teil reservieren    */
  310.     if(h_block_2)
  311.     {    /* in den beiden nächsten Zeilen habe ich die '64' eingefügt.
  312.             Grund: MagiC hat pro Block einen Overhead von 32 Byte, aus
  313.             Sicherheitsgründen habe ich mal das doppelte genommen    */
  314.         if(h_block_2->bl_len >= 8+len+64)
  315.         {    Mshrink(0,h_block_2,h_block_2->bl_len-len-64);
  316.             block=Malloc(len);
  317.         }
  318.         else
  319.             block=h_block_2;
  320.     }
  321. /* alle anderen freigeben    */
  322.     while(h_block_1)
  323.     {    h_block_2=h_block_1;
  324.         h_block_1=h_block_1->bl_next;
  325.         if(h_block_2!=block)
  326.             Mfree(h_block_2);
  327.     }
  328.     
  329. /* besser irgendwo als kein Speicher    */
  330.     if(!block)
  331.         block=Malloc(len);
  332. /* falls erfolgreich noch in Mem_l1 eintragen    */
  333.     if(!block)
  334.         return(NULL);
  335.     else
  336.     {    block->bl_next=Mem_l1;
  337.         Mem_l1=block;
  338.         block->bl_len=len;
  339.         return(&block[1]);
  340.     }
  341. }
  342. /*------------------------------------------------------------------*/
  343. /*            int mfree_l1_0(BLOCK *mem)                                */
  344. /*                                                                    */
  345. /*            PD verwaltet den Speicherplatz in verschiefdenen        */
  346. /*            verketteten Listen. Eine nenne ich Mem_l1.                */
  347. /*            Das Original gibt einen Speicherblock aus dieser Liste    */
  348. /*            frei. Da es sein könnte, da₧ dort Programmcode steht    */
  349. /*            prüfe ich zusätzlich, ob ein Systemvektor hierhin zeigt    */
  350. /*            Und entferne ihn ggf.                                    */
  351. /*                                                                    */
  352. /*        Parameter: der freizugebende Speicher                        */
  353. /*        Rückgabe : 0: erfolgreich                                    */
  354. /*                                                                    */
  355. /*                                                                    */
  356. /*------------------------------------------------------------------*/
  357.  
  358. int mfree_l1_0(BLOCK *mem)
  359. {    BLOCK *blk,*last;
  360.     int ret=-1;
  361.     mem--;
  362.     blk=Mem_l1;
  363.     last=(BLOCK *)&Mem_l1;
  364.     while(blk)
  365.     {    if(blk==mem)
  366.         {    last->bl_next=blk->bl_next;    /* Aus Kette entfernen    */
  367.             blk->bl_next=NULL;            /*nur ein Block auf XBRA testen    */
  368.             tst_sysv_x(blk);
  369.             ret=Mfree(blk);
  370.             break;
  371.         }
  372.         blk=blk->bl_next;
  373.     }
  374.     return(ret);
  375. }
  376.  
  377. /*------------------------------------------------------------------*/
  378. /*            void mfree_a_sp_0(void)                                    */
  379. /*                                                                    */
  380. /*        ähnlich wie die vorige Routine, allerdings wird hier der    */
  381. /*        gesammte Speicher aus der Liste Prg_a_sp freigegeben        */
  382. /*        dabei handelt es sich um den vom zu debuggenden Programm    */
  383. /*        mit Malloc oder Mxalloc reservierten Speicher                */
  384. /*        Parameter: keine                                            */
  385. /*                                                                    */
  386. /*        (c) Dimitri Junker                                            */
  387. /*                                                                    */
  388. /*------------------------------------------------------------------*/
  389.  
  390. void mfree_a_sp_0(void)
  391. {    tst_sysv_x(Prg_a_sp);
  392.     mfree_a_sp();    /* die Originalroutine    */
  393. }
  394.  
  395. /* -------------------------------------------------------------------- */
  396. /*    Routinen die für den 1  Monitorbetrieb verwendet werden ( _1)        */
  397. /* -------------------------------------------------------------------- */
  398.  
  399.  
  400.  
  401. /*------------------------------------------------------------------*/
  402. /*        void v_opn_init_1( int *work_in, int *handle,int *work_out )*/
  403. /*                                                                    */
  404. /*         Im Einmonitorbetrieb ist zwar keine Alternative zu v_opnvwk    */
  405. /*        nötig, aber da die Stelle gut für Initialisierung ist...    */
  406. /*        Hier wird die Basepage ermittelt, Falls eine NOVA-Karte        */
  407. /*        aktiv ist, wird der Mxalloc Modus auf 3 gesetzt, für andere    */
  408. /*        Karten einfach selber testen                                */
  409. /*                                                                    */
  410. /*        Parameter:     s. Original v_opnvwk                            */
  411. /*                                                                    */
  412. /*        (c) Dimitri Junker                                            */
  413. /*                                                                    */
  414. /*------------------------------------------------------------------*/
  415.  
  416. void v_opn_init_1( int *work_in, int *handle,int *work_out )
  417. {    ICB *icb;
  418.     Supexec_0(init_sup_0);
  419.     v_opnvwk(work_in,handle,work_out );
  420.     if (get_cookie_0('IMNE',(long *)&icb))
  421.         X_pd.p_bs_m=3;
  422.     X_pd.p_ms=-1;
  423. }
  424.  
  425. /*------------------------------------------------------------------*/
  426. /*        void vq_mouse_1( int handle, int *pstatus, int *x,int *y )    */
  427. /*                                                                    */
  428. /*            Ersetzt vq_mouse                                        */
  429. /*             Falls im 1-Monitorbetrieb in die Menüzeile geklickt     */
  430. /*            wird, diese restaurieren falls die rechte Maustaste     */
  431. /*            gedrückt wird: Mauszeiger aktivieren                    */
  432. /*                                                                    */
  433. /*        Parameter:     s.     vq_mouse                                    */
  434. /*                                                                    */
  435. /*        (c) Dimitri Junker                                            */
  436. /*                                                                    */
  437. /*------------------------------------------------------------------*/
  438.  
  439.  
  440. void vq_mouse_1( int handle, int *pstatus, int *x,int *y )
  441. {    vq_mouse(handle,pstatus,x,y );
  442.     if((*y<18 && *pstatus && !X_pd.p_ms)||X_pd.p_ms<0)
  443.         draw_menu();
  444.     if(*pstatus>1)            /*Eine andere Maustaste als die linke gedrückt*/
  445.     {    v_show_c(handle,0);
  446.         *pstatus&=1;        /*Vor PD verbergen    */
  447.     }
  448.     X_pd.p_ms=*pstatus;
  449. }
  450.  
  451.  
  452. /*------------------------------------------------------------------*/
  453. /*            void  Setscreen_1( void *laddr, void *paddr, int rez )    */
  454. /*                                                                    */
  455. /*            ersetzt Setscreen                                        */
  456. /*                                                                    */
  457. /*            Aus mir noch unklaren Gründen gibt es teilweise            */
  458. /*            Probleme mit Setscreen (Absturz). Wenn PD feststellt,    */
  459. /*            da₧ Setscreen nicht funktioniert, arbeitet es ohne.        */
  460. /*            Die einfachste Methode Setscreen nicht funktionieren zu */
  461. /*            lassen ist gar nichts zu tuen ->                        */
  462. /*        Parameter: s. Setscreen                                        */
  463. /*                                                                    */
  464. /*        (c) Dimitri Junker                                            */
  465. /*                                                                    */
  466. /*------------------------------------------------------------------*/
  467. #pragma warn -par
  468. void  Setscreen_1( void *laddr, void *paddr, int rez )
  469. {    }
  470. #pragma warn +par
  471.  
  472. /*------------------------------------------------------------------*/
  473. /*            void  *Mxalloc_1( long amount, int mode )                */
  474. /*            ersetzt Mxalloc                                            */
  475. /*                                                                    */
  476. /*            falls in v_opn_init_1 X_pd.p_bs_m umgesetzt wurde wird     */
  477. /*            nicht mehr ST-RAM für den 2. Bildschirm verwendet        */
  478. /*        Parameter:     s.Mxalloc                                        */
  479. /*                                                                    */
  480. /*        (c) Dimitri Junker                                            */
  481. /*                                                                    */
  482. /*------------------------------------------------------------------*/
  483.  
  484.  
  485. #pragma warn -par
  486. void  *Mxalloc_1( long amount, int mode )
  487. {    return(Mxalloc(amount,X_pd.p_bs_m ));
  488. }
  489. #pragma warn +par
  490.     
  491. /* -------------------------------------------------------------------- */
  492. /*    Routinen die für den 2  Monitorbetrieb verwendet werden ( _2)        */
  493. /* -------------------------------------------------------------------- */
  494.  
  495. /*------------------------------------------------------------------*/
  496. /*            void *Physbase_2(void)                                    */
  497. /*    und        void *Logbase_2(void)                                    */
  498. /*                                                                    */
  499. /*         Im 2 Monitorbetrieb müssen PD teilweise andere Phys- bzw.    */
  500. /*        Logbase Adressen gemeldet werden, als dies die                 */
  501. /*        Betriebssystemroutinen machen würden.                         */
  502. /*                                                                    */
  503. /*        Parameter:     keine                                            */
  504. /*        Rückgabe :     Die vorzugaukelnde Adresse                        */
  505. /*                                                                    */
  506. /*        (c) Dimitri Junker                                            */
  507. /*                                                                    */
  508. /*------------------------------------------------------------------*/
  509.  
  510. void *Physbase_2(void)
  511. {    if(X_pd.p_phys==AES_MON)
  512.         return(Physbase());
  513.     else
  514.         return(X_pd.p_baddr[X_pd.p_phys]);
  515. }
  516.  
  517. void *Logbase_2(void)
  518. {    if(X_pd.p_log==AES_MON)
  519.         return(Logbase());
  520.     else
  521.         return(X_pd.p_baddr[X_pd.p_log]);
  522. }
  523.  
  524. /*------------------------------------------------------------------*/
  525. /*    void v_opn_init_2( int *work_in_alt, int *handle,int *work_out )*/
  526. /*        ersetzt v_opnvwk                                            */
  527. /*                                                                    */
  528. /*         Diese Routine wird einmal statt der normalen v_opnvwk        */
  529. /*        ausgeführt,    sie öfnet keine virtuelle WS, sondern eine         */
  530. /*        Offscreenbitmap    an der Stelle, an der sich der                 */
  531. /*        Bildschirmspeicher befindet.                                */
  532. /*        Au₧erdem wird sie noch einmal von Mxalloc_2 aufgerufen, um    */
  533. /*        noch eine 2. Bitmap zu öffnen                                */
  534. /*        Beim 1. Aufruf wird auch noch einiges initialisiert,         */
  535. /*        daher der Name                                                */
  536. /*                                                                    */
  537. /*        Parameter: s. v_opnvwk                                        */
  538. /*                                                                    */
  539. /*        (c) Dimitri Junker                                            */
  540. /*                                                                    */
  541. /*------------------------------------------------------------------*/
  542.  
  543.  
  544. void v_opn_init_2( int *work_in_alt, int *handle,int *work_out )
  545. {    VDIPB vdipb;
  546.     int contrl[15], work_in[20],i,bm;
  547.     long farben,c_val;
  548.     int     (*do_eddi)(int bn);
  549.     ICB            *icb;
  550.     void *eddi;
  551. /* 1. oder 2. Aufruf?    */
  552.     if(X_pd.p_baddr[BITMAP_MON1])    /* Aufruf von Mxalloc für Bitmap[1]    */
  553.     {    bm=BITMAP_MON2;
  554.         contrl[6]=work_in[0] =X_pd.p_bhdl[AES_MON];
  555.     }
  556.     else                    /* Aufruf von PD für Bitmap[0]        */
  557.     {    bm=BITMAP_MON1;
  558.         if(get_cookie_0('_VDO', &c_val))    /* Grafikhardware ermitteln    */
  559.             X_pd.p_masch=(int)(c_val>>16);
  560.         else 
  561.             X_pd.p_masch=ST_MOD;
  562.         if (get_cookie_0('IMNE',(long *)&icb))    /* der NOVA-Cookie    */
  563.         {    if (icb->id < '2.63')            /* v_extnd ist fehlerhaft*/
  564.                 X_pd.p_nova_alt=1;
  565.             if (icb->id >= '2.00')            /* Zeichnen in Puffer erst ab Version 2.00:*/
  566.                 X_pd.p_vopn=NOVA;
  567.         }
  568.         if(!X_pd.p_vopn)
  569.         {    if(get_cookie_0('EdDI',(long *)&eddi))    /* Off-Screen Bitmaps ?    */
  570.             {    do_eddi=eddi;
  571.                 if(do_eddi(0)>=0x0110)
  572.                     X_pd.p_vopn=EdDI_1_1;
  573.                 else
  574.                 {    form_alert(1,"[3][Die VDI-Version unterstützt AFAIK|keine Offscreen-Bitmaps][Schade]");
  575.                     *handle=0;            /* Sollte PD zum Abbruch bewegen    */
  576.                     return;
  577.                 }
  578.             }
  579.         }
  580.         X_pd.p_pdhdl=handle;        /* hier speichert PD sein WS-Handel    */
  581.         X_pd.p_baddr[BITMAP_MON1]=(void *)Supexec_0(init_sup_2);
  582.         X_pd.p_phys=X_pd.p_log=AES_MON;            /* Aktuell AES-Monitor*/
  583.         X_pd.p_bhdl[AES_MON]=contrl[6]=work_in[0] = graf_handle(&i, &i, &i, &i);
  584.     }
  585.     /* Bitmap öffnen    */
  586.     M_pd.fd_addr=X_pd.p_baddr[bm];
  587.     contrl[0]=100;
  588.     contrl[1]=0;
  589.     contrl[4]=0;
  590.     contrl[5]=1;
  591.     for(i=1;i<11;i++)
  592.         work_in[i]=work_in_alt[i];
  593.     work_in[11] = M_pd.fd_w-1;
  594.     work_in[12] = M_pd.fd_h-1;
  595.  
  596.     vdipb.contrl=contrl;
  597.     vdipb.intin =work_in;
  598.     vdipb.intout=work_out;
  599.     vdipb.ptsout=work_out + 45;
  600.     /* nach NOVA oder EdDi Methode    */
  601.     if(X_pd.p_vopn==NOVA)
  602.     {    work_in[13]=M_pd.fd_nplanes;
  603.         work_in[14]=1;
  604.         contrl[2]=6;
  605.         contrl[3]=15;
  606.         *((void **)(&contrl[7])) =M_pd.fd_addr;
  607.  
  608.     }
  609.     else    /* EdDi 1.1    */
  610.     {    work_in[13]=278;        /*  Breite eines Pixels in Mikrometern    */
  611.         work_in[14]=278;        /*  Höhe eines Pixels in Mikrometern    */
  612.         farben=1<<M_pd.fd_nplanes;
  613.         *(long *)&work_in[15]=farben;
  614.         work_in[17]=M_pd.fd_nplanes;
  615.         work_in[18]=0;
  616.         work_in[19]=1;
  617.         contrl[2]=0;
  618.         contrl[3]=20;
  619.         *((MFDB **)(&contrl[7])) =&M_pd;
  620.     }
  621.     vdi_2( &vdipb );            /* v_opnbm oder v_opnvwk2    */
  622.     
  623.     X_pd.p_bhdl[bm]=*handle = contrl[6];
  624.  
  625. /* Bei meinen ersten Versuchen erschien die Schrift Wei₧ auf Wei₧,
  626.     deshalb sicherheitshalber auf Schwarz setzen    */
  627.     contrl[0]=22;
  628.     contrl[1]=0;
  629.     contrl[2]=0;
  630.     contrl[3]=1;
  631.     contrl[4]=1;
  632.     contrl[5]=0;
  633.     contrl[6]=*handle;
  634.     work_in[0]=1;
  635.     vdipb.intout=work_in+3;
  636.     vdipb.ptsout=work_in+12;
  637.     vdi_2( &vdipb );            /* vst_color    */
  638.     M_pd.fd_addr=X_pd.p_baddr[BITMAP_MON1];
  639. }
  640. /*------------------------------------------------------------------*/
  641. /*            long init_sup_2(void)                                    */
  642. /*                                                                    */
  643. /*         Der Teil von v_opn_init_2, der im Supervisormode ausgeführt    */
  644. /*        werden mu₧. Hier wird die Basepage ermittelt, die             */
  645. /*        Bildschirmadresse (Bitmap-Monitor) bestimmt die Auflösung     */
  646. /*        und die Farben gesetzt, letzteres wegen bildschirmschonern    */
  647. /*                                                                    */
  648. /*        Parameter: keine                                            */
  649. /*        Rückgabe :     Bildschirmadresse als long wegen Supexec        */
  650. /*                                                                    */
  651. /*        (c) Dimitri Junker                                            */
  652. /*                                                                    */
  653. /*------------------------------------------------------------------*/
  654.  
  655. long init_sup_2(void)
  656. {    long addr;
  657.     Supexec_0(init_sup_0);
  658.     addr=(long)(*(unsigned char *)0xffff8201l);
  659.     addr=addr<<8;
  660.     addr|=(long)(*(unsigned char *)0xffff8203l);
  661.     addr=addr<<8;
  662.     if(X_pd.p_masch!=ST_MOD)
  663.         addr|=(long)(*(unsigned char *)0xffff820dl);
  664.     *( char *)0xffff8260l=X_pd.p_res;
  665.     if(X_pd.p_masch==TT_MOD)
  666.     {    *( char *)0xffff8262l&=0xF8;
  667.         *( char *)0xffff8262l|=X_pd.p_res;
  668.         *( int *)0xffff85fcl=0;                /* Schwarz    */
  669.         *( int *)0xffff85fel=0xfff;            /* Wei₧        */
  670.     }
  671.     return(addr);
  672. }
  673. /*------------------------------------------------------------------*/
  674. /*            v_clsbm_2( int handle )                                    */
  675. /*            ersetzt v_clsvwk                                        */
  676. /*                                                                    */
  677. /*         Die 2 Bitmap-WS abmelden und Bildschirm löschen,            */
  678. /*        ist besser für den Monitor                                    */
  679. /*        Parameter: s. v_clsvwk, wird aber ignoriert                    */
  680. /*                                                                    */
  681. /*        (c) Dimitri Junker                                            */
  682. /*                                                                    */
  683. /*------------------------------------------------------------------*/
  684.  
  685. #pragma warn -par
  686. void v_clsbm_2( int handle )
  687. {    VDIPB vdipb;
  688.     int contrl[15],dummy[20],pxy[8];
  689. /* Bildschirm löschen    */
  690.     pxy[0]=pxy[1]=pxy[4]=pxy[5]=0;
  691.     pxy[2]=pxy[6]=M_pd.fd_w-1;
  692.     pxy[3]=pxy[7]=M_pd.fd_h-1;
  693.     M_pd.fd_addr=X_pd.p_baddr[BITMAP_MON1];
  694.     vro_cpyfm(X_pd.p_bhdl[BITMAP_MON1],ALL_BLACK,pxy,&M_pd,&M_pd);
  695.  
  696. /*    Beide Workstations schlie₧en    */
  697.     if(X_pd.p_vopn==NOVA)
  698.     {    v_clsvwk(X_pd.p_bhdl[BITMAP_MON1]);
  699.         v_clsvwk(X_pd.p_bhdl[BITMAP_MON2]);
  700.     }
  701.     else
  702.     {    contrl[0]=101;
  703.         contrl[1]=contrl[2]=contrl[3]=contrl[4]=0;
  704.         contrl[5]=1;
  705.         vdipb.contrl=contrl;
  706.         vdipb.intin =dummy;
  707.         vdipb.intout=dummy;
  708.         vdipb.ptsout=dummy;
  709.         contrl[6] = X_pd.p_bhdl[BITMAP_MON1];
  710.         vdi_2( &vdipb );
  711.         contrl[6] = X_pd.p_bhdl[BITMAP_MON2];
  712.         vdi_2( &vdipb );
  713.     }
  714. }
  715. /*------------------------------------------------------------------*/
  716. /*    void vq_extnd_nova_2( int handle, int owflag, int *work_out )    */
  717. /*                                                                    */
  718. /*        ersetzt vq_extnd                                            */
  719. /*                                                                    */
  720. /*         NOVA-VDI <2.63 gibt bei vq_extnd eine falsche Anzahl         */
  721. /*        Planes zurück                                                */
  722. /*                                                                    */
  723. /*        Parameter:     s. vq_extnd                                        */
  724. /*                                                                    */
  725. /*        (c) Dimitri Junker                                            */
  726. /*                                                                    */
  727. /*------------------------------------------------------------------*/
  728.  
  729. #pragma warn +par
  730. void vq_extnd_nova_2( int handle, int owflag, int *work_out )
  731. {    vq_extnd(handle,owflag,work_out );
  732.     if(owflag && X_pd.p_nova_alt)
  733.         work_out[4]=M_pd.fd_nplanes;
  734. }
  735.  
  736. /*------------------------------------------------------------------*/
  737. /*        void vq_mouse_2( int handle, int *pstatus, int *x,int *y )    */
  738. /*            ersetzt vq_mouse                                        */
  739. /*                                                                    */
  740. /*         Mauszeiger auf 2. Bildschirm zeichnen...                    */
  741. /*        es wird davon ausgegangen, da₧ die Auflösung des             */
  742. /*        AES-Monitors grö₧er oder gleich der des kleinen ist.        */
  743. /*        vq_mouse wird regelmä₧ig aufgerufen, deshalb pa₧t es hier    */
  744. /*                                                                    */
  745. /*        Parameter:     s.     vq_mouse                                    */
  746. /*                                                                    */
  747. /*        (c) Dimitri Junker                                            */
  748. /*                                                                    */
  749. /*------------------------------------------------------------------*/
  750. void vq_mouse_2( int handle, int *pstatus, int *x,int *y )
  751. {    int pxy[8],w,h,xv,yv;
  752.     MFDB m_s;
  753.     m_s=*&M_pd;
  754.     m_s.fd_w=m_s.fd_h=16;
  755.     m_s.fd_wdwidth=1;
  756.  
  757.     /* Die Mausposition und Status erfragen    */
  758.  
  759.     vq_mouse(handle,pstatus,x,y);
  760.     
  761.     /* Falls au₧erhalb des kleinen Bildschirms Offset verändern*/
  762.  
  763.     xv=*x-X_pd.p_x_offs;
  764.     if(xv<0)
  765.     {    X_pd.p_x_offs=*x;
  766.         *x=0;
  767.     }
  768.     else
  769.     {    if(xv>=M_pd.fd_w)
  770.         {    X_pd.p_x_offs=*x+1-M_pd.fd_w;
  771.             *x=M_pd.fd_w-1;
  772.         }
  773.         else
  774.             *x=xv;
  775.     }
  776.     yv=*y-X_pd.p_y_offs;
  777.     if(yv<0)
  778.     {    X_pd.p_y_offs=*y;
  779.         *y=0;
  780.     }
  781.     else
  782.     {    if(yv>=M_pd.fd_h)
  783.         {    X_pd.p_y_offs=*y+1-M_pd.fd_h;
  784.             *y=M_pd.fd_h-1;
  785.         }
  786.         else
  787.             *y=yv;
  788.     }
  789.     /* Falls die Maus sich bewegt hat mu₧ der Zeiger neu gezeichnet werden    
  790.     natürlich nur wenn nicht der AES-Monitor aktiv ist*/
  791.  
  792.     if((*x!=X_pd.p_x || *y!=X_pd.p_y)&& X_pd.p_phys!=AES_MON)
  793.     {    m_s.fd_addr=X_pd.p_msave;
  794.         /* Falls Mauszeiger an war Hintergrund restaurieren    */
  795.         if(X_pd.p_x!=-1)
  796.         {    w=min(16,M_pd.fd_w-X_pd.p_x)-1;
  797.             h=min(16,M_pd.fd_h-X_pd.p_y)-1;
  798.             pxy[0]=pxy[1]=0;
  799.             pxy[2]=w;
  800.             pxy[3]=h;
  801.             pxy[6]=w+(pxy[4]=X_pd.p_x);
  802.             pxy[7]=h+(pxy[5]=X_pd.p_y);
  803.             vro_cpyfm(handle,S_ONLY,pxy,&m_s,&M_pd);
  804.         }
  805.         /* Falls jetzt an: Mauszeiger zeichnen    */
  806.         if(!X_pd.p_ms)
  807.         {    w=min(16,M_pd.fd_w-*x)-1;
  808.             h=min(16,M_pd.fd_h-*y)-1;
  809.             pxy[2]=w+(pxy[0]=*x);
  810.             pxy[3]=h+(pxy[1]=*y);
  811.             pxy[4]=pxy[5]=0;
  812.             pxy[6]=w;
  813.             pxy[7]=h;
  814.             vro_cpyfm(handle,S_ONLY,pxy,&M_pd,&m_s);
  815.             m_s.fd_addr=X_pd.p_mmaske;
  816.             pxy[0]=pxy[1]=0;
  817.             pxy[2]=w;
  818.             pxy[3]=h;
  819.             pxy[6]=w+(pxy[4]=*x);
  820.             pxy[7]=h+(pxy[5]=*y);
  821.             vro_cpyfm(handle,NOTS_AND_D,pxy,&m_s,&M_pd);
  822.             m_s.fd_addr=X_pd.p_mzeiger;
  823.             vro_cpyfm(handle,S_OR_D,pxy,&m_s,&M_pd);
  824.             X_pd.p_x=*x;
  825.             X_pd.p_y=*y;
  826.         }
  827.         else
  828.             X_pd.p_x=-1;    /* beim nächsten mal nicht restaurieren    */
  829.     }
  830. }
  831. /*------------------------------------------------------------------*/
  832. /*            void hide_curs_2( void )                                */
  833. /*    und        void show_curs_2( void )                                */
  834. /*            ersetzt hide_curs und show_curs                            */
  835. /*                                                                    */
  836. /*         Ein- und ausschalten des Mauscursors mu₧ auf die 2 Monitore    */
  837. /*        verteilt werden.                                            */
  838. /*                                                                    */
  839. /*        Parameter: keine                                            */
  840. /*                                                                    */
  841. /*        (c) Dimitri Junker                                            */
  842. /*                                                                    */
  843. /*------------------------------------------------------------------*/
  844.  
  845. void hide_curs_2( void )
  846. {    int pxy[8],w,h;
  847.     MFDB m_s;
  848.     m_s=*&M_pd;
  849.     X_pd.p_ms++;
  850.     if(X_pd.p_phys==AES_MON)        /* AES-Monitor    */
  851.         v_hide_c(X_pd.p_bhdl[AES_MON]);
  852.     else                    /* Bitmap-Monitor    */
  853.     {    if(X_pd.p_x>-1)    /* Wenn er sichtbar war löschen */
  854.         {    m_s.fd_w=m_s.fd_h=16;
  855.             m_s.fd_wdwidth=1;
  856.             m_s.fd_addr=X_pd.p_msave;
  857.             w=min(16,M_pd.fd_w-X_pd.p_x)-1;
  858.             h=min(16,M_pd.fd_h-X_pd.p_y)-1;
  859.             pxy[0]=pxy[1]=0;
  860.             pxy[2]=w;
  861.             pxy[3]=h;
  862.             pxy[6]=w+(pxy[4]=X_pd.p_x);
  863.             pxy[7]=h+(pxy[5]=X_pd.p_y);
  864.             X_pd.p_x=-1;
  865.             vro_cpyfm(X_pd.p_bhdl[X_pd.p_phys],S_ONLY,pxy,&m_s,&M_pd);
  866.         }
  867.     }
  868. }
  869. void show_curs_2( void )
  870. {    int x,y,ps,reset=1;
  871.     if(reset)
  872.     {    if(X_pd.p_ms)
  873.             X_pd.p_ms--;
  874.     }
  875.     else
  876.         X_pd.p_ms=0;
  877.     
  878.     if(X_pd.p_phys==AES_MON)
  879.     {    if(!X_pd.p_ms)
  880.             reset=0;
  881.         v_show_c(X_pd.p_bhdl[AES_MON],reset);
  882.     }
  883.     else
  884.         vq_mouse_2(X_pd.p_bhdl[X_pd.p_phys],&ps,&x,&y);
  885. }
  886. #pragma warn -par
  887.  
  888. /*------------------------------------------------------------------*/
  889. /*            void  Setscreen_2( void *laddr, void *paddr, int rez )    */
  890. /*            ersetzt Setscreen                                        */
  891. /*                                                                    */
  892. /*         auch das Setscreen mu₧ auf die 2 Monitore verteilt werden    */
  893. /*                                                                    */
  894. /*        Parameter: s. Setscreen    rez wird in PD nie verwendet        */
  895. /*                                                                    */
  896. /*        (c) Dimitri Junker                                            */
  897. /*                                                                    */
  898. /*------------------------------------------------------------------*/
  899.  
  900. void  Setscreen_2( void *laddr, void *paddr, int rez )
  901. {    int monitor;
  902.     if((long)laddr!=-1l)    /* Logbase ändern?    */
  903.     {    if(X_pd.p_baddr[BITMAP_MON1]==laddr)    /* auf welchen virtuellen Monitor soll gesetzt werden?*/
  904.             monitor=BITMAP_MON1;
  905.         else
  906.         {    if(X_pd.p_baddr[BITMAP_MON2]==laddr)
  907.                 monitor=BITMAP_MON2;
  908.             else
  909.                 monitor=AES_MON;
  910.         }
  911.         *X_pd.p_pdhdl=X_pd.p_bhdl[monitor];    /* dadurch simulierenm, da₧ PD ein anderes Handle untergejubelt wird    */
  912.         X_pd.p_log=monitor;        /* und merken    */
  913.     }
  914.     if((long)paddr!=-1l)    /* Physbase ändern    */
  915.     {    if(X_pd.p_baddr[BITMAP_MON1]==paddr)    /* auf welchen virtuellen Monitor soll gesetzt werden?*/
  916.             monitor=BITMAP_MON1;
  917.         else
  918.         {    if(X_pd.p_baddr[BITMAP_MON2]==paddr)
  919.                 monitor=BITMAP_MON2;
  920.             else
  921.                 monitor=AES_MON;
  922.         }
  923.         hide_curs_2();
  924.         if(monitor!=AES_MON)                /* Bitmap-Monitor    */
  925.         {    M_pd.fd_addr=paddr; /* Adresse für Videoshifter umsetzen    */
  926.             Supexec_0(set_mon_2);
  927.         }        /* AES-Monitor ist ja immer sichtbar    */
  928.         X_pd.p_phys=monitor;
  929.         show_curs_2();
  930.     }
  931. }
  932. /*------------------------------------------------------------------*/
  933. /*            long set_mon_2(void)                                    */
  934. /*                                                                    */
  935. /*         Bildschirmadresse für Videoshifter setzen, also eine Art    */
  936. /*         Setscreen                                                     */
  937. /*                                                                    */
  938. /*        Parameter: über M_pd und X_pd                                */
  939. /*        Rückgabe :     0 als dummy wg. Supexec                            */
  940. /*                                                                    */
  941. /*        (c) Dimitri Junker                                            */
  942. /*                                                                    */
  943. /*------------------------------------------------------------------*/
  944.  
  945. /* Bildschirmadresse für Videoshifter setzen, also eine Art Setscreen */
  946. long set_mon_2(void)
  947. {
  948.     *(unsigned char *)0xffff8201l=(unsigned char)((long)M_pd.fd_addr>>16);
  949.     *(unsigned char *)0xffff8203l=(unsigned char)((long)M_pd.fd_addr>>8);
  950.     if(X_pd.p_masch!=ST_MOD)
  951.         *(unsigned char *)0xffff820dl=(unsigned char)M_pd.fd_addr;
  952.     return(0l);
  953. }
  954. /*------------------------------------------------------------------*/
  955. /*            void  *Mxalloc_2( long amount, int mode )                */
  956. /*                ersetzt Mxalloc                                        */
  957. /*                                                                    */
  958. /*    Mxalloc wird nur benutzt, um Speicher für den 2. und 3.         */
  959. /*    Bildschirm zu reservieren, da PD davon ausgeht, da₧ sie         */
  960. /*    ST-RAM benötigen. Da der Speicher für den 2. Bildschirm bereits */
  961. /*    vom AES reserviert ist, kann beim 1. Aufruf von Mxalloc der     */
  962. /*    Speicher zurückgegeben werden, auf den die VideoBase Register     */
  963. /*    zeigen. Da PD sicherheitshalber immer auf die nächste durch 256    */
  964. /*    teilbare Adresse aufrundet, und zwar so, da₧ wenn die von        */
  965. /*    Mxalloc zurückgegebene Adresse bereits durch 256 teilbar ist,     */
  966. /*    er 256 hinzuaddiert:                                            */
  967. /*    addr+=256;                                                        */
  968. /*    addr&=0xffffff00;                                                */
  969. /*                                                                    */
  970. /*    mu₧ diese Routine eine Adresse kleiner als Videobase            */
  971. /*  zurückgeben.                                                    */
  972. /*    PD ruft zuerst Mxalloc auf, wenn dieses einen Wert <=0             */
  973. /*    ( Assembler: ble ) zurückgibt wird nochmal mit Malloc probiert.    */
  974. /*  Es reicht also Mxalloc zu ersetzen, auch auf TOS Versionen         */
  975. /*    ohne Mxalloc.                                                    */
  976. /*    Problem:                                                        */
  977. /*    Falls Videobase nicht durch 256 teilbar ist, wird es Probleme    */
  978. /*    geben. Dies ist bei mir nie der Fall gewesen, das AES reserviert*/
  979. /*    wohl aus Kompatibilitätsgründen immer Speicher an einer            */
  980. /*    Seitengrenze. Falls aber irgendwann andere Programme den         */
  981. /*    2. Bildschirm nutzen, und evtl. Feinscrolling machen ist dies     */
  982. /*    nicht mehr gesichert. Dann mü₧te z.B. das Aufrunden weggepatcht    */
  983. /*    werden:        add.l        #$100,D0                                */
  984. /*                and.l        #-$100,D0                                */
  985. /*    dies kommt 2* vor                                                */
  986. /*    Oder in v_opnbm neuer Speicher reserviert werden.                */
  987. /*                                                                    */
  988. /*        Parameter: s. Mxalloc                                        */
  989. /*                                                                    */
  990. /*        (c) Dimitri Junker                                            */
  991. /*                                                                    */
  992. /*------------------------------------------------------------------*/
  993.  
  994.      
  995.  
  996. void  *Mxalloc_2( long amount, int mode )
  997. {    int work_in[11],work_out[65],i;
  998.     void *ret;
  999.     
  1000.     switch((int)X_pd.p_mxa)
  1001.     {    case 0:
  1002.             X_pd.p_mxa++;
  1003.             *X_pd.p_pdhdl=X_pd.p_bhdl[X_pd.p_log];
  1004.             ret=(void*)((long)X_pd.p_baddr[BITMAP_MON1]-2l);
  1005.             break;
  1006.         case 1:
  1007.             X_pd.p_mxa++;
  1008.             ret=Mxalloc(amount,mode );
  1009.             
  1010.             for(i=0;i<10;i++)
  1011.                 work_in[i]=1;
  1012.             work_in[10]=2;
  1013.             X_pd.p_baddr[BITMAP_MON2]=(void *)(((long)ret+256l)&0xffffff00l);
  1014.             v_opn_init_2(work_in,&X_pd.p_bhdl[BITMAP_MON2],work_out);
  1015.             break;
  1016.         default:            /* sollte zwar nicht vorkommen, aber...*/
  1017.             ret=Mxalloc(amount,mode );
  1018.     }
  1019.     return(ret);
  1020. }
  1021. /*------------------------------------------------------------------*/
  1022. /*        Routinen zur Implementierung von XBRA                        */
  1023. /*------------------------------------------------------------------*/
  1024.  
  1025. /*------------------------------------------------------------------*/
  1026. /*            void tst_sysv_x(BLOCK *mem)                                */
  1027. /*                                                                    */
  1028. /*                                                                    */
  1029. /*     Diese Routine prüft ob einer der Systemvektoren (1-107,256-263,    */
  1030. /*    und derzeit 17 weitere)    in einen freizugebenden Speicherblock    */
  1031. /*    zeigt. Dabei werden nicht nur die direkt im Systemvektor        */
  1032. /*    vorhandenen Adressen geprüft, sondern alle per XBRA verketteten.*/
  1033. /*    Die Speicherblöcke müssen PD typisch verkettet sein.             */
  1034. /*    mem zeigt auf den 1.                                            */
  1035. /*        Parameter:     mem s.o.                                        */
  1036. /*        Rückgabe :     keine                                            */
  1037. /*                                                                    */
  1038. /*        (c) Dimitri Junker                                            */
  1039. /*    Dank an Bernhard Held, der mir eine Liste der infragekommenden    */
  1040. /*    Vektoren zur Verfügung stellte.                                    */
  1041. /*------------------------------------------------------------------*/
  1042.  
  1043. void tst_sysv_x(BLOCK *mem)
  1044. {    int vec_nr,anz_addr;
  1045.     XBRA **vec_addr[]={ (XBRA **)0x42a,(XBRA **)0x46a,(XBRA **)0x46e,
  1046.          (XBRA **)0x472,(XBRA **)0x476,(XBRA **)0x47a,(XBRA **)0x47e,
  1047.          (XBRA **)0x4f6,(XBRA **)0x502,(XBRA **)0x506,(XBRA **)0x50a,
  1048.          (XBRA **)0x50e,(XBRA **)0x512,(XBRA **)0x592,(XBRA **)0x5a0,
  1049.          (XBRA **)0x5ac,(XBRA **)0x5b0};
  1050.  
  1051.     if(!mem)
  1052.         return;
  1053.     for(vec_nr=1;vec_nr<108;vec_nr++)    /* Vektoren 1-107     */
  1054.         tst_1sysv_x(mem,vec_nr,NULL);
  1055.     for(vec_nr=256;vec_nr<264;vec_nr++)    /* Vektoren 256-263    */
  1056.         tst_1sysv_x(mem,vec_nr,NULL);
  1057.     anz_addr=(int)(sizeof(vec_addr)/sizeof(*vec_addr));
  1058.     for(vec_nr=1;vec_nr<anz_addr;vec_nr++)    /* Vektoren an krummen Adressen    */
  1059.         tst_1sysv_x(mem,0,vec_addr[vec_nr]);
  1060.  
  1061. }
  1062. /*------------------------------------------------------------------*/
  1063. /*            void tst_1sysv_x(BLOCK *mem,int vec,XBRA **addr)        */
  1064. /*                                                                    */
  1065. /*                                                                    */
  1066. /*     Diese Routine prüft ob ein Systemvektor in einen freizugebenden    */
  1067. /*    Speicherblock zeigt.                                             */
  1068. /*    s.a. tst_sysv_x                                                    */
  1069. /*    Da es auch nichtinitialisierte Vektoren gibt, die ins Nirwana    */
  1070. /*    zeigen könnte es bei normaler Vorgehensweise zu Abstürzen        */
  1071. /*    kommen. memcpyx ist eine PD interne Routine, die versucht        */
  1072. /*    Speicher zu kopieren und zurückgibt ob dies erfolgreich war        */
  1073. /*    oder ob die Adresse ungültig war                                */
  1074. /*    Der zu prüfende Vektor kann auf 2 Arten übergeben werden,         */
  1075. /*    entweder als Vektornummer (s. Setexc) oder als Addresse            */
  1076. /*        Parameter:     mem: s. tst_sysv_x.                                */
  1077. /*                    vec: zu prüfender Vektor, wie für Setexc oder 0    */
  1078. /*                    addr: zu prüfender Vektor, wird nur benutzt     */
  1079. /*                            wenn vec=0                                */
  1080. /*        Rückgabe :     keine                                            */
  1081. /*                                                                    */
  1082. /*        (c) Dimitri Junker                                            */
  1083. /*                                                                    */
  1084. /*------------------------------------------------------------------*/
  1085.  
  1086. void tst_1sysv_x(BLOCK *mem,int vec,XBRA **addr)
  1087. {    XBRA sv,*svp,*last;
  1088.     BLOCK *bl;
  1089.     int do_del;
  1090.     if(vec)
  1091.         svp=((XBRA *)Setexc(vec,(void(*)())-1))-1;    /*Vektor holen    */
  1092.     else
  1093.         memcpyx(&svp,addr,sizeof(*addr));        /*Addr ist zwar gültig aber geschützt*/
  1094.     if(memcpyx(&sv, svp,sizeof(sv)))
  1095.         sv.xb_magic=0l;                            /*ungültige Adresse    */
  1096.     last=NULL;
  1097.     while(sv.xb_magic=='XBRA')    /* Nur die, die eine gültige XBRA Struktur haben    */
  1098.     {    bl=mem;
  1099.         do_del=0;
  1100. /* prüfen ob die Adresse in einem der Blöcke liegt    */
  1101.         {    if((long)svp>=(long)bl &&(long)svp<(long)bl+bl->bl_len) 
  1102.                 do_del=1;            /* löschen    */
  1103.         }while((bl=bl->bl_next)!=NULL && !do_del);
  1104.         if(do_del)
  1105.         {    if(!last)    /* am Anfang der Kette    */
  1106.                 if(vec)
  1107.                     Setexc(vec,(void(*)())svp->xb_oldvec);
  1108.                 else
  1109.                     memcpyx(addr,&svp->xb_oldvec,sizeof(*addr));
  1110.             else
  1111.                 last->xb_oldvec=svp->xb_oldvec;
  1112.             break;
  1113.         }
  1114.         else
  1115.             last=svp;
  1116.         svp=sv.xb_oldvec-1;
  1117.         if(memcpyx(&sv, svp,sizeof(sv)))
  1118.             sv.xb_magic=0l;
  1119.     }
  1120. }
  1121. /*------------------------------------------------------------------*/
  1122. /*            void tst_sysva_x(void)                                    */
  1123. /*                                                                    */
  1124. /*                                                                    */
  1125. /* tut das gleiche wie:                                                */
  1126. /*    {    tst_sysv_x(Mem_l1);                                            */
  1127. /*        tst_sysv_x(Prg_a_sp);                                        */
  1128. /*    }                                                                */
  1129. /*    aber schneller, denn bei obiger Methode mü₧ten alle                */
  1130. /*    Systemvektoren 2* durchsucht werden, so nur 1*.                 */
  1131. /*        Parameter: keine                                            */
  1132. /*                                                                    */
  1133. /*        (c) Dimitri Junker                                            */
  1134. /*                                                                    */
  1135. /*------------------------------------------------------------------*/
  1136.  
  1137. void tst_sysva_x(void)
  1138. {    BLOCK *bl,*all;
  1139.     bl=Mem_l1;
  1140.     if(bl)
  1141.     {    while(bl->bl_next)
  1142.             bl=bl->bl_next;
  1143.         bl->bl_next=Prg_a_sp;
  1144.         all=Mem_l1;
  1145.     }
  1146.     else
  1147.         all=Prg_a_sp;
  1148.     tst_sysv_x(all);
  1149.     if(bl)
  1150.         bl->bl_next=NULL;    /*wahrscheinlich unnötig    */
  1151. }
  1152. /*------------------------------------------------------------------*/
  1153. /*            void res_gd_trm_x(void)                                    */
  1154. /*                                                                    */
  1155. /*        restauriert Gemdos und etv_term nach XBRA                    */
  1156. /*        Parameter: keine                                            */
  1157. /*                                                                    */
  1158. /*        (c) Dimitri Junker                                            */
  1159. /*                                                                    */
  1160. /*------------------------------------------------------------------*/
  1161.     
  1162. /* Diese Routine ist die letzte die die Systemvektoren restauriert */
  1163. void res_gd_trm_x(void)
  1164. {    
  1165.     res_sysv_x(Ptr_Gemd,33,NULL);
  1166.     res_sysv_x(Ptr_term,258,NULL);
  1167. }
  1168. /*------------------------------------------------------------------*/
  1169. /*            void res_hcop_vb_x(void)                                */
  1170. /*                                                                    */
  1171. /*        restauriert Scrdmp und Vertical Blank nach XBRA                */
  1172. /*        Parameter: keine                                            */
  1173. /*                                                                    */
  1174. /*        (c) Dimitri Junker                                            */
  1175. /*                                                                    */
  1176. /*------------------------------------------------------------------*/
  1177.  
  1178. void res_hcop_vb_x(void)
  1179. {    
  1180.     res_sysv_x(Ptr_scrd,0,(XBRA **)0x502);
  1181.     res_sysv_x(Ptr_vb,28,NULL);
  1182. }
  1183.  
  1184. /*------------------------------------------------------------------*/
  1185. /*    void (*res_sysv_x(void (*exchdlr)() ,int vec,XBRA **addr)) ()    */
  1186. /*                                                                    */
  1187. /*                                                                    */
  1188. /*         eigene Routine aus XBRA Kette ausklinken. Eigentlich reicht    */
  1189. /*        dafür die Nummer, aber falls die XBRA Kette unterbrochen ist*/
  1190. /*        klappt das nicht. Deshalb kann für diesen Fall sozusagen     */
  1191. /*        klassisch der zu setzende Vektor angegeben werden, ist         */
  1192. /*        exchdlr=NULL, so wird nur XBRA berücksichtigt                */
  1193. /*        Parameter:     exchdlr: Originalwert                            */
  1194. /*                    vec: zu prüfender Vektor, wie für Setexc oder 0    */
  1195. /*                    addr: zu prüfender Vektor, wird nur benutzt     */
  1196. /*                            wenn vec=0                                */
  1197. /*        Rückgabe :     voriger Wert                                    */
  1198. /*                                                                    */
  1199. /*        (c) Dimitri Junker                                            */
  1200. /*                                                                    */
  1201. /*------------------------------------------------------------------*/
  1202.  
  1203. void res_sysv_x(void (*exchdlr)() ,int vec,XBRA **addr)
  1204. {    XBRA *svp,*last=NULL;
  1205.     if(vec)
  1206.         svp=((XBRA *)Setexc(vec,(void(*)())-1))-1;    /*Vektor holen    */
  1207.     else
  1208.         memcpyx(&svp,addr,sizeof(*addr));        /*Addr ist zwar gültig aber geschützt*/
  1209.     while(svp->xb_magic=='XBRA')    /* Nur die, die eine gültige XBRA Struktur haben    */
  1210.     {    if(svp->xb_id==My_id)
  1211.         {    if(!last)    /* am Anfang der Kette    */
  1212.             {    if(vec)
  1213.                     Setexc(vec,(void(*)())svp->xb_oldvec);
  1214.                 else
  1215.                     memcpyx(addr,&svp->xb_oldvec,sizeof(*addr));
  1216.             }
  1217.             else
  1218.                 last->xb_oldvec=svp->xb_oldvec;
  1219.             exchdlr=NULL;
  1220.             break;
  1221.         }
  1222.         else
  1223.             last=svp;
  1224.         svp=svp->xb_oldvec-1;
  1225.     }
  1226.     if(exchdlr)    /* dann ist wohl die XBRA Kette unterbrochen    */
  1227.     {    if(vec)
  1228.             Setexc(vec,exchdlr);
  1229.         else
  1230.             memcpyx(addr,&exchdlr,sizeof(*addr));
  1231.     }
  1232. }
  1233.