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

  1. /*            Patch_PD V1.05
  2.         (c) 1997,98 by Dimitri Junker
  3.             Adenauerallee 30
  4.             52066 Aachen    */
  5.  
  6. #define PRGNAME "PATCH_PD"
  7. #define PRGVERS "1.05"
  8.  
  9. /* -------------------------------------------------------------------- */
  10. /*        Includes                                                        */
  11. /* -------------------------------------------------------------------- */
  12.  
  13. #include "easyfsel.h"
  14. #include "patch.h"
  15.  
  16. #include <vdi.h>
  17. #include <aes.h>
  18. #include <string.h>
  19. #include <stdlib.h>
  20.  
  21.  
  22. /* -------------------------------------------------------------------- */
  23. /*       Makros. & Konstanten                                           */
  24. /* -------------------------------------------------------------------- */
  25.  
  26. #define MAX_SYM 400
  27. #define MAX_REL    400
  28. #define MAX_NR    200
  29.  
  30. #define MAGIC 0x4EFA001CL
  31.  
  32. /* Originalroutinen aus PD    */
  33. #define        DRAW_MENU        0
  34. #define        SHOW_CURS        1
  35. #define        HIDE_CURS        2
  36. #define        RESET            3
  37. #define        RESET_A            4
  38. #define        MALLOC_H        5
  39. #define        MFREEL1            6
  40. #define        BOMB28            7
  41. #define        BOMB33            45
  42. #define        BOMBEN            8
  43. #define        RESMYEXC        9
  44. #define        SETMYEXC        10
  45. #define        BOMB4            11
  46. #define        TRACE            12
  47. #define        NOPRIV            13
  48. #define        LINEA            14
  49. #define        AESVDI            15
  50. #define        TOS1            16
  51. #define        MEMCPYX            17
  52. #define        ESC_H_ETC        18
  53. #define        RESGDT            19
  54. #define        MFREEAS            20
  55. #define        GEMDOS2            21
  56. #define        SETGDT            22
  57. #define        GEMDOS2A        23
  58. #define        ETVTRM            24
  59. #define        FCLOSE            25
  60. #define        SETEXC            26
  61. #define        MXALLOC            27
  62. #define        MSHRINK            28
  63. #define        MFREE            29
  64. #define        MALLOC            30
  65. #define        SETSCREEN        31
  66. #define        PHYSBASE        32
  67. #define        LOGBASE            33
  68. #define        GRAF_HANDLE        34
  69. #define        FORM_ALERT        35
  70. #define        V_SHOW_C        36
  71. #define        V_OPNVWK        37
  72. #define        V_HIDE_C        38
  73. #define        V_CLSVWK        39
  74. #define        VRO_CPYFM        40
  75. #define        VQ_MOUSE        41
  76. #define        VQ_EXTND        42
  77. #define        SETHCV            43
  78. #define        RESHCV            44
  79. #define        ANZ_ROUT        46
  80.  
  81. /* und Daten (DATA, BSS    )    */
  82. #define        B_23E58            0
  83. #define        MEM_L1            1
  84. #define        B_2AD06            2
  85. #define        ANZBOMB            3
  86. #define        GDSEMA1            4
  87. #define        ORSR2            5
  88. #define        PRG_ASP            6
  89. #define        USEOGEM            7
  90. #define        ALTHLP            8
  91. #define        ANZ_DAT            9
  92.  
  93.  
  94. /* -------------------------------------------------------------------- */
  95. /*        typedefs                                                        */
  96. /* -------------------------------------------------------------------- */
  97. typedef struct
  98. {        UBYTE    *text;        /* Das Textsegment usw    */
  99.         long    tot_len;    /* Gesamtlänge        */
  100.         UBYTE    *reloz;        /* Reloziertabelle    */
  101.         long    rel_len;    /* Länge der Reloziertabele    */
  102.         UBYTE     *data;        /* Datasegment        */
  103. }PD_ORI;
  104.  
  105. /* Adresse und Name einer Routine    */
  106. typedef struct
  107. {    long        addr;
  108.     char        name[30];
  109. }PD_ROUT;
  110.  
  111. /* Programmheader    */
  112. typedef struct
  113. {    int        ph_branch;
  114.     long    ph_tlen;            /* Länge des TEXT-Abschnitts    */
  115.     long    ph_dlen;            /* Länge des DATA-Abschnitts    */
  116.     long    ph_blen;            /* Länge des BSS-Abschnitts    */
  117.     long    ph_slen;            /* Länge des Symboltabelle    */
  118.     long    ph_res1;            /* reserviert    */
  119.     long    ph_prgflags;        /* Flags                    */
  120.     int        ph_absflag;            /* 0:Relozierungsinfo vorh.        */
  121. }PH;
  122. /* Typdefinition für den Dateiheader einer Borland-Object-Datei */
  123. typedef struct
  124. {    unsigned long magic;        /* 0x4EFA001C */
  125.     unsigned long imageBytes;
  126.     unsigned long symInfoBytes;
  127.     unsigned long nameBytes;
  128.     unsigned long versionInfo;
  129.     unsigned long debugInfo;
  130.     unsigned long reserved1;
  131.     unsigned long reserved2;
  132. } LIBHEADER;
  133.  
  134. /* neue Routinen...    */
  135. typedef struct
  136. {    long    reloz[MAX_REL];        /* neue Adressen die reloziert werden müssen    */
  137.     int     anz_r;                /* deren Anzahl    */
  138.     int     neues[MAX_NR];        /* Nummer für N_ROUT    */
  139.     int     neue;                /* Anzahl neue Routinen    */
  140.     long    ersetze[MAX_NR][2];    /* Ersetze Adresse[0] durch [1]    */
  141.     int     ers;                /* Anzahl zu ersetzender        */
  142.     long     reset;                /* Adresse der reset Routine    */
  143. }N_ROUT;
  144.  
  145. /* Typedefinition für die Einträge in der Symboltabelle */
  146. typedef struct
  147. {    char Type;                     /* Typeintrag */
  148.     unsigned char Position;     /* Offset */
  149.     int Wert;                     /* Name */
  150. } SYMENTRY;
  151. typedef struct
  152. {    char    *sy_name;            /* Name des Symbols                    */
  153.     long    sy_atxt;            /* Adresse relativ zum TEXT Anfang    */
  154.     char    *sy_aram;            /* aktuelle Adresse im RAM            */
  155.     SYMENTRY *sy_stab;            /* Beginn in Symboltable            */
  156.     long    sy_len;                /* Länge                            */
  157.     int        sy_rel2;            /* relativ zu.für Entrypoints,sonst-1*/
  158. }SYMB;
  159.  
  160. /* -------------------------------------------------------------------- */
  161. /*         lokale Funktionsprototypen                                        */
  162. /* -------------------------------------------------------------------- */
  163.  
  164. void fill_DATA(MFDB *m_pd,PDX *x_pd);
  165. void get_lib(char *f_name,int monitore);
  166. void get_pd(PH *ph,PD_ORI *pd_o,int monitore);
  167. int find_sym(char *name,int flag);
  168. void einf(int ar_nr,char *nr_name,PH *ph,N_ROUT *n_rout);
  169. int init(void);
  170. void write_neu(N_ROUT *n_rout);
  171. void suche_rout1(long anz_word,unsigned int p_txt[]);
  172. void suche_dat_bss(unsigned int p_txt[],PH *ph);
  173. void suche_rout2(long anz_word,unsigned int p_txt[]);
  174. void set_namen(void);
  175. void save_addr(void);
  176. void save_addr_txt(void);
  177. int read_addr(void);
  178. void get_addr(PH *ph,PD_ORI *pd_o);
  179. void write_cfg(int monitore,PD_ORI *pd_o);
  180. void write_new_pd(PH *ph_neu,PH *ph_alt,int monitore,PD_ORI *pd_o,N_ROUT *n_rout);
  181. void routinen_einf(PH *ph_neu,int monitore,PD_ORI *pd_o,N_ROUT *n_rout);
  182.  
  183. /* -------------------------------------------------------------------- */
  184. /*        Globale Variablen                                                */
  185. /* -------------------------------------------------------------------- */
  186.  
  187. int Anz_sym=0;
  188. FILE *F_in=NULL,*F_out=NULL;
  189. SYMB Sym[MAX_SYM];
  190.  
  191. long Reset_any,Version_ptr,Pd_cfg,Ndat_len,Nbss_len;
  192. PD_ROUT Pd_r[ANZ_ROUT],Pd_d[ANZ_DAT];
  193. char Flag[ANZ_ROUT],Version_txt[100], File_n[500]="",*Ndat_aram;
  194.  
  195. /* -------------------------------------------------------------------- */
  196. /*        Funktionen                                                        */
  197. /* -------------------------------------------------------------------- */
  198.  
  199. /*------------------------------------------------------------------*/
  200. /*            main ( int argc, const char *argv[] )                    */
  201. /*            na was wohl                                                */
  202. /*                                                                    */
  203. /*            wird ein Pfad übergeben, so wird versucht dieses PD        */
  204. /*            zu patchen, ADDR_DAT wird ignoriert                        */
  205. /*            sonst wird versucht alle Daten aus PD_ADDR.DAT zu lesen    */
  206. /*        Parameter:     es kann ein PD_PRG Pfad übergeben werden        */
  207. /*        Rückgabe :     0                                                */
  208. /*                                                                    */
  209. /*        (c) Dimitri Junker                                            */
  210. /*                                                                    */
  211. /*------------------------------------------------------------------*/
  212. int main ( int argc, const char *argv[] )
  213. {    int monitore,v_hdl,addr_bek=0;
  214.      PH    ph_alt,ph_neu;
  215.      N_ROUT n_rout;
  216.     PD_ORI pd_o;
  217.     pd_o.tot_len=0l;
  218.     if(argc>1)
  219.         strcpy(File_n,argv[1]);            /* übergebenes File analysieren    */
  220.     else
  221.         addr_bek=read_addr();            /* versuchen Adressen aus PD_ADDR.DAT zu lesen    */
  222.     if(!addr_bek)
  223.     {    get_addr(&ph_alt,&pd_o);        /* dann auf die harte Tour        */
  224.         save_addr();
  225.         save_addr_txt();
  226.     }
  227.  
  228.  
  229.     v_hdl=init();
  230.  
  231.     monitore=form_alert(1,"[2][Soll eine Ein- oder|Zweimonitorversion erstellt werden][ 1 | 2 ]");
  232.  
  233.     /* Laden    */
  234.     
  235.     get_lib("PD_LIB.LIB",monitore);        /* die neuen Routinen laden            */
  236.     get_pd(&ph_alt,&pd_o,monitore);        /* das Original PD.PRG laden    */
  237.  
  238.     ph_neu=ph_alt;                        /* noch sind beide gleich    */
  239. /* Zeiger auf DATA-Bereich und Reloziertabelle    */
  240.  
  241.     pd_o.data=&pd_o.text[ph_alt.ph_tlen];
  242.     pd_o.reloz=&pd_o.data[ph_alt.ph_dlen];
  243.     pd_o.rel_len=pd_o.tot_len-ph_alt.ph_tlen-ph_alt.ph_dlen;
  244.  
  245.  
  246. /* PD.CFG ->Pi.CFG    mit i=1,2    jedes PD erhält sein eigenes CFG    */
  247.     
  248.     pd_o.text[Pd_cfg+1l]=(UBYTE)('0'+monitore);
  249.  
  250. /* Der Hauptteil    */
  251.     routinen_einf(&ph_neu,monitore,&pd_o,&n_rout);
  252.     write_new_pd(&ph_neu,&ph_alt,monitore,&pd_o,&n_rout);
  253.     write_cfg(monitore,&pd_o);
  254.     v_clsvwk(v_hdl);
  255.     return(0);
  256.  
  257. }
  258.  
  259. /*------------------------------------------------------------------*/
  260. /*void routinen_einf(PH *ph_neu,int monitore,PD_ORI *pd_o,N_ROUT *n_rout)    */
  261. /*                                                                    */
  262. /*                                                                    */
  263. /* Neue Routinen einbinden, und teilweise alte ersetzen             */
  264. /* Rautinen die mit einf(-1,... eingefügt werden sind neue Routinen,*/
  265. /* die i.A. nur von anderen neuen aufgerufen werden, die anderen    */
  266. /* ersetzen Originalroutinen, in den Komentaren gehe ich meist nur     */
  267. /* auf letztere ein                                                    */
  268. /*        Parameter:    ph_neu Programmheader des neuen PD                */
  269. /*                    monitore: 1 oder 2 Monitore                        */
  270. /*                    pd_o: Infos zum Original PD                        */
  271. /*                    n_rout: die neuen Routinen                        */
  272. /*        Rückgabe :     keine                                            */
  273. /*                                                                    */
  274. /*        (c) Dimitri Junker                                            */
  275. /*                                                                    */
  276. /*------------------------------------------------------------------*/
  277.  
  278. void routinen_einf(PH *ph_neu,int monitore,PD_ORI *pd_o,N_ROUT *n_rout)
  279. {
  280.     n_rout->anz_r=n_rout->neue=n_rout->ers=0;
  281.     
  282. /* Phys- und Logbase ersetzen    */
  283.     if(monitore==2)
  284.     {    einf(PHYSBASE,"Physbase_2",ph_neu,n_rout);
  285.         einf(LOGBASE,"Logbase_2",ph_neu,n_rout);
  286.     }
  287.     
  288. /* v_opnvwk und v_clsvwk ersetzen. Da erstere ganz am Anfang
  289.     aufgerufen wird, finden hier auch sonstige Initialisierungen
  290.     statt.     */
  291.  
  292.     einf(-1,"Supexec_0",ph_neu,n_rout);
  293.     einf(-1,"get_cookie_0",ph_neu,n_rout);
  294.     einf(-1,"get_cookie_jar_0",ph_neu,n_rout);
  295.     einf(-1,"get_act_pd_0",ph_neu,n_rout);
  296.     einf(-1,"init_sup_0",ph_neu,n_rout);
  297.     einf(MALLOC_H,"malloc_high_0",ph_neu,n_rout);
  298.     
  299.     if(monitore==2)
  300.     {    einf(-1,"init_sup_2",ph_neu,n_rout);
  301.         einf(-1,"vdi_2",ph_neu,n_rout);
  302.         einf(V_OPNVWK,"v_opn_init_2",ph_neu,n_rout);
  303.         einf(V_CLSVWK,"v_clsbm_2",ph_neu,n_rout);
  304.     }
  305.     else
  306.         einf(V_OPNVWK,"v_opn_init_1",ph_neu,n_rout);
  307.         
  308. /* Für NOVA-VDI    <2.63 behebt einen Fehler in den teils noch aktuellen
  309.     NOVA-VDI Versionen */
  310.     if(monitore==2)
  311.     {    einf(VQ_EXTND,"vq_extnd_nova_2",ph_neu,n_rout);
  312.  
  313. /* Mauszeiger auf 2. Monitor zeichnen, ein/ausschalten    */
  314.  
  315.         einf(VQ_MOUSE,"vq_mouse_2",ph_neu,n_rout);
  316.         einf(HIDE_CURS,"hide_curs_2",ph_neu,n_rout);
  317.         einf(SHOW_CURS,"show_curs_2",ph_neu,n_rout);
  318.     }
  319.     
  320.     else    /*    Neuzeichnen der Menüzeile auf Mausdruck    bei einem Monitor*/
  321.         einf(VQ_MOUSE,"vq_mouse_1",ph_neu,n_rout);
  322.  
  323. /* Setscreen und Mxalloc    */
  324.     if(monitore==2)
  325.     {    einf(-1,"set_mon_2",ph_neu,n_rout);
  326.         einf(SETSCREEN,"Setscreen_2",ph_neu,n_rout);
  327.         einf(MXALLOC,"Mxalloc_2",ph_neu,n_rout);
  328.     }
  329.     else
  330.     {    einf(MXALLOC,"Mxalloc_1",ph_neu,n_rout);
  331.  
  332. /*  Benutzung von Setscreen evtl Abstellen    */
  333.         if(form_alert(1,"[2][Darf Setscreen verwendet werden?][ Ja | Nein ]")==2)
  334.             einf(SETSCREEN,"Setscreen_1",ph_neu,n_rout);
  335.     }
  336.     
  337. /*  Vektoren mit XBRA verbiegen    */
  338.     einf(-1,"tst_id_0",ph_neu,n_rout);
  339.     einf(SETMYEXC,"set_my_exc_x",ph_neu,n_rout);
  340.     einf(RESMYEXC,"res_my_exc_x",ph_neu,n_rout);
  341.     einf(SETGDT,"set_gd_trm_x",ph_neu,n_rout);
  342.     einf(SETEXC,"set_etvc_x",ph_neu,n_rout);
  343.     einf(-1,"tst_1sysv_x",ph_neu,n_rout);
  344.     einf(-1,"tst_sysv_x",ph_neu,n_rout);
  345.     einf(-1,"tst_sysva_x",ph_neu,n_rout);
  346.     einf(MFREEL1,"mfree_l1_0",ph_neu,n_rout);
  347.     einf(MFREEAS,"mfree_a_sp_0",ph_neu,n_rout);
  348.     einf(-1,"res_sysv_x",ph_neu,n_rout);
  349.     einf(RESGDT,"res_gd_trm_x",ph_neu,n_rout);
  350.     einf(SETHCV,"set_hcop_vb_x",ph_neu,n_rout);
  351.     einf(RESHCV,"res_hcop_vb_x",ph_neu,n_rout);
  352.  
  353. /*  Bei Reset auch Fclose() ausführen 
  354.     PD springt nicht nur per jsr, sondern auch per bsr in diese Routine,
  355.     da diese Sprünge nicht erkannt werden, überschreibe ich unten den
  356.     Anfang der Routine mit:
  357.     nop
  358.     jmp reset
  359.     Durch das nop kommt reset an eine Speicherstelle, an der auch im Original
  360.     eine absolute Adresse steht, somit braucht die Reloziertabelle nicht
  361.     angepa₧t zu werden.    Dadurch kann ich natürlich nicht mehr nach reset
  362.     springen, sondern nur noch in den ungeänderten Teil (reset_a)        */
  363.  
  364.     n_rout->reset=ph_neu->ph_tlen;
  365.     einf(RESET,"reset_0",ph_neu,n_rout);
  366.  
  367. /*  Ausgabe von ESC H (Cursor home) evtl Abstellen    */
  368.     if(Pd_r[ESC_H_ETC].addr)
  369.     {    switch(form_alert(2,"[2][Wann soll ESC H (Cursor home)|ausgegeben werden?][ nie |1. Run |jedes Run]"))
  370.         {    case 1:    /* nie*/
  371.                 pd_o->text[Pd_r[ESC_H_ETC].addr+6]=0x60;        /* bne durch bra ersetzen*/
  372.                 break;
  373.             case 3: /* immer */
  374.                 pd_o->text[Pd_r[ESC_H_ETC].addr+6]=0x6b;        /* bne durch bmi ersetzen*/
  375.                 break;
  376.         }
  377.     }
  378.     else
  379.         form_alert(1,"[1][Kann ESC H Korektur nicht ausführen,| da Adresse unbekannt ][ OK ]");
  380.     if(n_rout->neue>=MAX_NR)
  381.     {    form_alert(1,"[3][MAX_NR mu₧ erhöht werden!][Mach ich]");
  382.         exit(0);
  383.     }
  384.     
  385. }
  386.  
  387. /*------------------------------------------------------------------*/
  388. /*void write_new_pd(PH *ph_neu,PH *ph_alt,int monitore,PD_ORI *pd_o,N_ROUT *n_rout)    */
  389. /*                                                                    */
  390. /*                                                                    */
  391. /* neues PD zusammenbasteln und schreiben                            */    
  392. /*        und zwar in der Reihenfolge:                                */
  393. /*        - TEXT aus PD.PRG                                            */
  394. /*        - TEXT aus PD_LIB.LIB                                        */
  395. /*        - DATA aus PD.PRG                                            */
  396. /*        - M_PD    (in der 2Monitorversion)                            */
  397. /*        - X_PD                                                        */
  398. /*        - DATA aus PD_LIB.LIB                                        */
  399. /*        - BSS aus PD.PRG                                            */
  400. /*        - BSS aus PD_LIB.LIB                                        */
  401. /*        - Reloziertabelle                                            */
  402. /*        die BSS werden natürlich nicht geschrieben                    */
  403. /*        Parameter:    ph_neu Programmheader des neuen PD                */
  404. /*                    ph_alt Programmheader des alten PD                */
  405. /*                    monitore: 1 oder 2 Monitore                        */
  406. /*                    pd_o: Infos zum Original PD                        */
  407. /*                    n_rout: die neuen Routinen                        */
  408. /*        Rückgabe :     keine                                            */
  409. /*                                                                    */
  410. /*        (c) Dimitri Junker                                            */
  411. /*                                                                    */
  412. /*------------------------------------------------------------------*/
  413.  
  414. void write_new_pd(PH *ph_neu,PH *ph_alt,int monitore,PD_ORI *pd_o,N_ROUT *n_rout)
  415. {     unsigned char offs;
  416.     long st_bss,diff_bss,*rel_addr,rel_4_t,akt_rel,diff_dat,lst_rel,
  417.         lst_t_rel,addr,st_data;
  418.     int i,j;
  419.     MFDB m_pd;
  420.     PDX x_pd;
  421.  
  422. /*    Verschieben der Adressen von DATA aus PD.PRG um:                */
  423.  
  424.     diff_dat=ph_neu->ph_tlen-ph_alt->ph_tlen;
  425.  
  426. /* Zusätzliches DATA einfügen        */
  427.  
  428.     if(monitore==2)
  429.     {    Sym[find_sym("M_pd",1)].sy_atxt=ph_neu->ph_tlen+ph_neu->ph_dlen;
  430.         ph_neu->ph_dlen+=sizeof(MFDB);
  431.     }
  432.     
  433.     Sym[find_sym("X_pd",1)].sy_atxt=ph_neu->ph_tlen+ph_neu->ph_dlen;
  434.     ph_neu->ph_dlen+=sizeof(PDX);
  435.  
  436. /* Verweise in neuen TEXT auf DATA,BSS aus PD_LIB.    sy_atext enthält den Abstand zum
  437.     Segmentbeginn, es mu₧ also der Segmentbeginn hinzuaddiert werden. Au₧erdem
  438.     ist dies ein guter Ort um die Global Entrypoints von der relativen Adressierung zur
  439.     absoluten zu ändern    */
  440.  
  441.     st_data=ph_neu->ph_tlen+ph_neu->ph_dlen;
  442.     ph_neu->ph_dlen+=Ndat_len;
  443.     st_bss=ph_neu->ph_tlen+ph_neu->ph_dlen+ph_neu->ph_blen;
  444.     ph_neu->ph_blen+=Nbss_len;
  445.     
  446.     for(i=0;i<Anz_sym;i++)
  447.     {    switch(Sym[i].sy_rel2)
  448.         {    case -1:            /* normal        */
  449.                 break;
  450.             case -2:            /* neues Data    */
  451.                 Sym[i].sy_atxt+=st_data;
  452.                 Sym[i].sy_rel2=-1;
  453.                 break;
  454.             case -3:            /* neues BSS    */
  455.                 Sym[i].sy_atxt+=st_bss;
  456.                 Sym[i].sy_rel2=-1;
  457.                 break;
  458.             default:            /* Global Entrypoint    */
  459.                 if(Sym[Sym[i].sy_rel2].sy_atxt)    /* Funktionsanfang    */
  460.                 {    Sym[i].sy_atxt+=Sym[Sym[i].sy_rel2].sy_atxt;
  461.                     Sym[i].sy_rel2=-1;
  462.                 }
  463.                 else
  464.                     Sym[i].sy_atxt=0l;
  465.         }
  466.     }
  467.  
  468. /*    Verschieben der Adressen von BSS aus PD.PRG    um:            */
  469.  
  470.     diff_bss=diff_dat+ph_neu->ph_dlen-ph_alt->ph_dlen;
  471.  
  472.     st_bss=ph_alt->ph_tlen+ph_alt->ph_dlen;            /* Start von BSS in PD.PRG    */
  473.     
  474.     
  475. /* Verweise in neuen TEXT auf alte DATA,BSS    */
  476.  
  477.     for(i=0;i<ANZ_DAT;i++)
  478.     {    if(Pd_d[i].addr<st_bss)        /* DATA    */
  479.             Sym[find_sym(Pd_d[i].name,1)].sy_atxt=Pd_d[i].addr+diff_dat;
  480.         else                        /* BSS    */
  481.             Sym[find_sym(Pd_d[i].name,1)].sy_atxt=Pd_d[i].addr+diff_bss;
  482.     }
  483.  
  484.  
  485. /*    In altem TEXT Sprungadressen nach DATA,BSS und auf geänderte 
  486.         Funktionen verschieben und Stelle in Reloziertabelle merken,
  487.         an der das TEXT-Segment endet (lst_rel)    
  488.         Die Reloziertabelle beginnt mit der ersten Adresse wo eine absolute
  489.         Adresse steht (long) und dann jeweils offsets bis zur nächsten (Byte)*/
  490.  
  491.     lst_rel=*((long *)pd_o->reloz);
  492.     lst_rel&=0xffffff00l;            /*    So braucht die erste Adresse nicht als Sonderfall behandelt zu werden*/
  493.     
  494.     for(i=3;i<pd_o->rel_len;i++)
  495.     {    if(pd_o->reloz[i]==1)        /* Offset 1 bedeutet da₧ 254 Byte nichts kommt*/
  496.             akt_rel=lst_rel+254l;
  497.         else
  498.         {    akt_rel=lst_rel+(long)pd_o->reloz[i];
  499.             rel_addr=(long *)&pd_o->text[akt_rel];
  500.             if((*rel_addr)>=st_bss)                    /* Zeiger auf BSS    */
  501.                 *rel_addr+=diff_bss;
  502.             else
  503.             {    if((*rel_addr)>=ph_alt->ph_tlen)    /* Zeiger auf DATA */
  504.                     *rel_addr+=diff_dat;
  505.                 else                                /* Zeiger auf TEXT bleiben, es sei denn die Funktion wurde ersetzt    */
  506.                 {    for(j=0;j<n_rout->ers;j++)
  507.                     {    if(*rel_addr==n_rout->ersetze[j][0])    /* Zeiger auf geänderte Funktion    */
  508.                             *rel_addr=n_rout->ersetze[j][1];
  509.                     }
  510.                 }
  511.             }
  512.         }
  513.         if(akt_rel>=ph_alt->ph_tlen && lst_rel<ph_alt->ph_tlen)    /*altes TEXT fertig    */
  514.         {    rel_4_t=i;                /* Anzahl Reloziereinträge für text    */
  515.             lst_t_rel=lst_rel;        /* letzter Reloziereintrag für text    (Adressse)*/ 
  516.         }
  517.         lst_rel=akt_rel;
  518.     }
  519.                         
  520. /* Einfügen von jmp auf reset in Originalroutine auf neue Routine        */
  521.     if(Pd_r[RESET].addr)
  522.     {    *(int  *)&pd_o->text[Pd_r[RESET].addr  ]=0x4e71;        /* nop        */
  523.         *(int  *)&pd_o->text[Pd_r[RESET].addr+2]=0x4ef9;        /* jmp        */
  524.         *(long *)&pd_o->text[Pd_r[RESET].addr+4]=n_rout->reset;        /* reset    */
  525.     }
  526.     else
  527.         form_alert(1,"[1][Kann Fclose bei Programm Reset| nicht einfügen, da die Adresse| unbekannt ist][ OK ]");
  528.  
  529.     /* TEXT schreiben    */
  530.     fwrite(ph_neu,sizeof(PH),1,F_out);        /* neuer Header                */
  531.     fwrite(pd_o->text,1,ph_alt->ph_tlen,F_out);    /*geändertes altes TEXT Segment    */
  532.     write_neu(n_rout);                            /* die neuen Routinen        */
  533.  
  534.     /* DATA Schreiben    */
  535.  
  536.     fwrite(pd_o->data,1,ph_alt->ph_dlen,F_out);    /*DATA Segment von PD.PRG schreiben    */
  537.      fill_DATA(&m_pd,&x_pd);                /* die neuen DATA's initialisieren    */
  538.     if(monitore==2)
  539.         fwrite(&m_pd,1,sizeof(MFDB),F_out);        /*neues DATA für 2 Monitorbetrieb    */
  540.     fwrite(&x_pd,1,sizeof(PDX),F_out);            /*neues DATA                */
  541.     fwrite(Ndat_aram,1,Ndat_len,F_out);            /*neues DATA aus PD_LIB                */
  542.     
  543.     /* Reloziertabelle schreiben    */
  544.     fwrite(pd_o->reloz,1,rel_4_t,F_out);            /*Realloziertabelle für TEXT von PD.PRG schreiben    */
  545.  
  546.     /* Realloziertabelle für neue Routinen erzeugen    */
  547.  
  548.     n_rout->reloz[n_rout->anz_r++]=lst_t_rel+(long)pd_o->reloz[rel_4_t]+diff_dat;    /*die 1. Adresse in DATA    */
  549.     for(i=0;i<n_rout->anz_r;i++)
  550.     {    addr=n_rout->reloz[i];
  551.         while(addr!=lst_t_rel)
  552.         {    if((addr-lst_t_rel)>254)
  553.             {    offs=1;
  554.                 lst_t_rel+=254;
  555.             }
  556.             else
  557.             {    offs=(unsigned char)(addr-lst_t_rel);
  558.                 lst_t_rel=addr;
  559.             }
  560.             fwrite(&offs,1,1,F_out);                    /* weiteres Offset anfügen    */
  561.         }
  562.     }
  563.     /*Realloziertabelle für DATA von PD.PRG schreiben, das neue DATA enthält
  564.         keine Adressen ->keine Reloziertabelle    */
  565.     rel_4_t++;
  566.     fwrite(&pd_o->reloz[rel_4_t],1,pd_o->rel_len-rel_4_t,F_out);
  567.     fclose(F_out);
  568. }
  569. /*------------------------------------------------------------------*/
  570. /*            void write_cfg(int monitore,PD_ORI *pd_o)                */
  571. /*                                                                    */
  572. /*                                                                    */
  573. /*         PD.CFG nach Pi.CFG kopieren, und dabei ggf auf                 */
  574. /*        ALLWAYS ADDRESS setzen                                        */
  575. /*        Parameter:     monitore: 1 oder 2 Monitore                        */
  576. /*                    pd_o wird nur benutzt um den Speicherplatz         */
  577. /*                        von text zu    benutzen                        */
  578. /*        Rückgabe :     keine                                            */
  579. /*                                                                    */
  580. /*        (c) Dimitri Junker                                            */
  581. /*                                                                    */
  582. /*------------------------------------------------------------------*/
  583.  
  584. void write_cfg(int monitore,PD_ORI *pd_o)
  585. {    
  586.     FILE *fi_cfg,*fo_cfg;
  587.     char dat_n[50]="PD.CFG";
  588.     long c_len;
  589.  
  590.     /* PD.CFG bestimmen    */
  591.     build_filename(File_n,File_n,"PD.CFG");
  592.  
  593.     while((fi_cfg=fopen(File_n,"rb"))==NULL)
  594.     {    strcpy(strrchr(File_n,'\\')+1,"*.CFG");
  595.         if(!easy_fsel(File_n,dat_n,"PD.CFG aussuchen1"))
  596.             exit(0);
  597.         build_filename(File_n,File_n,dat_n);
  598.     }
  599.  
  600.     /* neues CFG bestimmen    */
  601.     if(monitore==2)
  602.         build_filename(File_n,File_n,"P2.CFG");
  603.     else
  604.         build_filename(File_n,File_n,"P1.CFG");
  605.  
  606.     /* Das cfg nur schreiben, wenn nicht bereits eines existiert, sonst
  607.     gehen jedesmal alle Einstellungen verloren    */
  608.     if(!exist(File_n))
  609.     {    c_len=fread(pd_o->text,1,pd_o->tot_len,fi_cfg);
  610.         fclose(fi_cfg);
  611.         if(monitore==2)
  612.             pd_o->text[7]=pd_o->text[21]='\0';        /*Switch always by adress    */
  613.         if((fo_cfg=fopen(File_n,"wb"))==NULL)
  614.         {    form_alert(1,"[3][Kann neues PD.CFG nicht schreiben][Schade]");
  615.             exit(0);
  616.         }
  617.         fwrite(pd_o->text,1,c_len,fo_cfg);
  618.         fclose(fo_cfg);
  619.     }
  620. }
  621.  
  622.  
  623. /*    ar_ sind Variablen die mit den Alten Routinen zusammenhängen
  624.     nr_ sind Variablen die mit den Neuen Routinen zusammenhängen
  625.     
  626.     hier werden Routinen eingefügt (nur über Pointer) au₧erdem kann eine
  627.     Original PD-Routine (ar_nr) angegeben werden, die durch die neue
  628.     (nr_name) ersetzt wird.    Dies klappt allerdings bisher nur, wenn
  629.     die Routine durch einen Absoluten Call aufgerufen wird, nicht bei
  630.     bsr u.ä., da nur die Adressen der Reloziertabelle benutzt werden */
  631.  
  632. void einf(int ar_nr,char *nr_name,PH *ph,N_ROUT *n_rout)
  633. {    int nr_nr;
  634.     char fehler[100];
  635.     nr_nr=find_sym(nr_name,1);
  636.     Sym[nr_nr].sy_atxt=ph->ph_tlen;        /*Adresse relativ zu Programmanfang*/
  637.     n_rout->neues[n_rout->neue++]=nr_nr;
  638.     if(ar_nr>-1)                        /* ersetzen?    */
  639.     {    if(Pd_r[ar_nr].addr)
  640.         {    n_rout->ersetze[n_rout->ers][0]=Pd_r[ar_nr].addr;
  641.             n_rout->ersetze[n_rout->ers++][1]=Sym[nr_nr].sy_atxt;
  642.         }
  643.         else
  644.         {    sprintf(fehler,"[1][Beim Ersetzen von %s ist die|Adresse der Originalroutine unbekannt ][Abbruch]",Pd_r[ar_nr].name);
  645.             form_alert( 1,fehler);
  646.             exit(0);
  647.         }
  648.     }
  649.     ph->ph_tlen+=Sym[nr_nr].sy_len;
  650. }
  651.  
  652. /*------------------------------------------------------------------*/
  653. /*            void write_neu(N_ROUT *n_rout)                            */
  654. /*                                                                    */
  655. /*                                                                    */
  656. /*        hier werden die neuen Routinen geschrieben (File) und        */
  657. /*        gleichzeitig die Adressen eingesetzt (mit der Symboltabelle)*/
  658. /*        ar_ sind Variablen die mit den Alten Routinen zusammenhängen*/
  659. /*        nr_ sind Variablen die mit den Neuen Routinen zusammenhängen*/
  660. /*        Parameter:     die neuen Routinen                                */
  661. /*        Rückgabe :     keine                                            */
  662. /*                                                                    */
  663. /*        (c) Dimitri Junker                                            */
  664. /*                                                                    */
  665. /*------------------------------------------------------------------*/
  666.  
  667. void write_neu(N_ROUT *n_rout)
  668. {    char fehler[100],*ptr;
  669.      long pos,delta;
  670.      SYMENTRY *sym_e;
  671.     int i,j,nr_nr,weiter,err=0,ziel_err;
  672.     for(j=0;j<n_rout->neue;j++)                /* die neuen Routinen    */
  673.     {    nr_nr=n_rout->neues[j];
  674.         pos=Sym[nr_nr].sy_atxt;            /* Adresse relativ zu TEXT-Anfang    */
  675.         ptr=&Sym[nr_nr].sy_aram[-pos];    /* Hilfspointer    */
  676.         if((sym_e=Sym[nr_nr].sy_stab)==NULL)
  677.         {    sprintf(fehler,"[1][%s ist nicht global definiert][Abbruch]",Sym[nr_nr].sy_name);
  678.             form_alert( 1,fehler);
  679.             exit(0);
  680.         }    
  681.         weiter=1;
  682.         for(i=0;weiter;i++)        /* Die Symboltabelle durchgehen    */
  683.         {    pos+=sym_e[i].Position;
  684.             switch((int)sym_e[i].Type)
  685.             {    case 2:            /*Advance eigentl *256 aber 1* ist schon */
  686.                     pos+=(int)sym_e[i].Position*255;
  687.                     break;
  688.                 case 4:            /*Start new data segment: */
  689.                 case 7:            /*Define new global module: */
  690.                 case 9:            /*Define new local module: */
  691.                     weiter=0;    /*Neue Routine    */
  692.                     break;
  693.                 case 11:        /*Absolut long reference to: */
  694.                     if(!Sym[sym_e[i].Wert].sy_atxt)    
  695.                     {    ziel_err=i;
  696.                         weiter=0;
  697.                         if(Sym[sym_e[i].Wert].sy_rel2!=-1)
  698.                             err=3;
  699.                         else
  700.                             err=1;
  701.                     }
  702.                     else
  703.                     {    *(long *)&ptr[pos]+=Sym[sym_e[i].Wert].sy_atxt;
  704.                         n_rout->reloz[n_rout->anz_r++]=pos;
  705.                     }
  706.                     break;
  707.                 case 14:        /*PC-relative word reference to: */
  708.                     if(Sym[sym_e[i].Wert].sy_atxt==0l)
  709.                     {    ziel_err=i;
  710.                         if(Sym[sym_e[i].Wert].sy_rel2!=-1)
  711.                             err=3;
  712.                         else
  713.                             err=1;
  714.                         weiter=0;
  715.                     }
  716.                     else
  717.                     {    delta=(Sym[sym_e[i].Wert].sy_atxt-pos);
  718.                         if(labs(delta)<0x7ffel)
  719.                             *(int *)&ptr[pos]=(int)delta;
  720.                         else
  721.                         {    err=2;
  722.                             ziel_err=i;
  723.                         }
  724.                         
  725.                     }
  726.                     break;
  727.                 case 1:            /*End of object */
  728.                 case 3:            /*Start new text segment: */
  729.                 case 5:            /*Start new bss segment: */
  730.                 case 6:            /*Start new offset segment: */
  731.                     sprintf(fehler,"[1][%s| hat einen unerwarteten|Eintrag in Symboltabelle|bzw an unerwarteter Stelle][Abbruch]",Sym[nr_nr].sy_name);
  732.                     form_alert( 1,fehler);
  733.                     exit(0);
  734.                     break;        /*hier ignorieren    */
  735.             }
  736.         }
  737.         switch(err)
  738.         {    case 0:    /* alles OK    */
  739.                 break;
  740.             case 2:    /* relativer Sprung zu gro₧    */
  741.                 sprintf(fehler,"[3][Der Verwei₧ von '%s'|nach '%s'|ist für einen relativen Sprung zu gro₧.][Abbruch]",Sym[nr_nr].sy_name,Sym[sym_e[ziel_err].Wert].sy_name);
  742.                 form_alert( 1,fehler);
  743.                 exit(0);
  744.                 break;
  745.             case 1:
  746.                 sprintf(fehler,"[3][Beim Einfügen von '%s'|ist die Adresse von '%s'|unbekannt ][Abbruch]",Sym[nr_nr].sy_name,Sym[sym_e[ziel_err].Wert].sy_name);
  747.                 form_alert( 1,fehler);
  748.                 exit(0);
  749.                 break;
  750.             case 3:
  751.                 sprintf(fehler,"[3][Beim Einfügen von '%s'|ist die Adresse von '%s'|nur relativ zu %s|bekannt.][Abbruch]",Sym[nr_nr].sy_name,Sym[sym_e[ziel_err].Wert].sy_name,Sym[Sym[sym_e[ziel_err].Wert].sy_rel2].sy_name);
  752.                 form_alert( 1,fehler);
  753.                 exit(0);
  754.                 break;
  755.         }
  756.         fwrite(Sym[nr_nr].sy_aram,1,Sym[nr_nr].sy_len,F_out);    /*die neuen Routinen    */
  757.         
  758.     }
  759.     if(n_rout->anz_r>=MAX_REL)
  760.     {    form_alert(1,"[3][MAX_REL mu₧ erhöht werden!][Mach ich]");
  761.         exit(0);
  762.     }
  763. }
  764.  
  765. /*------------------------------------------------------------------*/
  766. /*            void fill_DATA(MFDB *m_pd,PDX *x_pd)                    */
  767. /*                                                                    */
  768. /*                                                                    */
  769. /*    Hier werden die Globalen Daten gesetzt.                            */
  770. /*  Dieses Patchprogramm verkraftete früher noch kein DATA-Segment    */
  771. /*    aus PD_LIB.LIB. Deshalb mu₧en alle Daten in die als extern        */
  772. /*    deklarierten Strukturen X_pd und M_pd gelegt werden                */
  773. /*    Jetzt können zwar DATA und BSS benutzt werden, aber:            */
  774. /*    "never change a running system"                                    */
  775. /*    Au₧erdem habe ich da noch Neuerungen vor, die so einfacher sind.*/
  776. /*    PD läuft lt. Handbuch nur in hoher Auflösung, aus Erfahrung aber*/
  777. /*    auch in TT-MID, 1024*768*8,.... Sinnvoll sind von den             */
  778. /*    Standardauflösungen also nur ST-High(2) und TT-MID(4). Trotzdem    */
  779. /*    funktioniert bei mir für den Zweimonitorbetrieb nur ST-HIGH,    */
  780. /*    und zwar weil das NOVA-VDI keine 4-Bit Bitmaps unterstützt.        */
  781. /*    v_opnbm gibt also Handle 0 zurück, dies wird von PD aber nicht     */
  782. /*    getestet, sondern es wird normal vq_extnd aufgerufen.            */
  783. /*    Dieses gibt dann als Auflösung 0*0 zurück, da₧ erscheint PD     */
  784. /*    etwas wenig, und er gibt die Meldung aus, da₧ er nicht in LOW    */
  785. /*    läuft. Selbst wenn ein anderer VDI-Triber 4 Planes unterstützt, */
  786. /*    ist es recht unwahrscheinlich, da₧ er auch das seltsame            */
  787. /*    ATARI-Format anwendet. Wahrscheinlich bleibt also nur ST-HIGH.    */
  788. /*  Man könnte natürlich den Treiber 1-Plane ausgeben lassen, und     */
  789. /*    dies selber    nach 4 Plane ATARI wandeln, aber das dürfte einiges */
  790. /*    an Zeit    verbrauchen.                                            */
  791. /*        Parameter:     die beiden zu füllenden Strukturen                */
  792. /*        Rückgabe :     keine, bzw der Inhalt gefüllten Strukturen        */
  793. /*                                                                    */
  794. /*        (c) Dimitri Junker                                            */
  795. /*                                                                    */
  796. /*------------------------------------------------------------------*/
  797.  
  798. void fill_DATA(MFDB *m_pd,PDX *x_pd)
  799. {    memset(x_pd,0,sizeof(PDX));
  800.     memset(m_pd,0,sizeof(MFDB));
  801.     x_pd->p_x=-1;
  802.     x_pd->p_res=2;                    /* Auflösung, s.o.    */
  803.     x_pd->p_mmaske[0]=0xc000a000l;
  804.     x_pd->p_mmaske[1]=0x90008800l;
  805.     x_pd->p_mmaske[2]=0x84008200l;
  806.     x_pd->p_mmaske[3]=0x81008080l;
  807.     x_pd->p_mmaske[4]=0x80408020l;
  808.     x_pd->p_mmaske[5]=0x801081f0l;
  809.     x_pd->p_mmaske[6]=0x89009480l;
  810.     x_pd->p_mmaske[7]=0xa480c380l;
  811.     x_pd->p_mzeiger[0]=0x00004000l;
  812.     x_pd->p_mzeiger[1]=0x60007000l;
  813.     x_pd->p_mzeiger[2]=0x78007c00l;
  814.     x_pd->p_mzeiger[3]=0x7e007f00l;
  815.     x_pd->p_mzeiger[4]=0x7f807fc0l;
  816.     x_pd->p_mzeiger[5]=0x7fe07e00l;
  817.     x_pd->p_mzeiger[6]=0x76006300l;
  818.     x_pd->p_mzeiger[7]=0x43000000l;
  819.     x_pd->p_vopn=0;
  820.     x_pd->p_nova_alt=0;
  821.     m_pd->fd_w=640;
  822.     m_pd->fd_h=400;
  823.     m_pd->fd_nplanes=1;
  824.     m_pd->fd_wdwidth=m_pd->fd_w/16;
  825. }
  826. /*------------------------------------------------------------------*/
  827. /*            void get_lib(char *f_name,int monitore)                    */
  828. /*                                                                    */
  829. /*                                                                    */
  830. /* Lädt die LIB der neuen Funktionen, incl. Symboltabelle            */
  831. /*        Parameter:     neuer Programmheader                            */
  832. /*                    Pfad der LIB und Anzahl Monitore                */
  833. /*        Rückgabe :     nur in globalen Var.                            */
  834. /*                                                                    */
  835. /*        (c) Dimitri Junker                                            */
  836. /*                                                                    */
  837. /*------------------------------------------------------------------*/
  838.  
  839. void get_lib(char *f_name,int monitore)
  840. {    FILE *f_obj;
  841.      LIBHEADER lh;
  842.     SYMENTRY *sym_e;
  843.      char fehler[200],*o_txt,*rel2_a=NULL;
  844.      long rest,len,pos=0l,s_bss=0l,s_data=0l;
  845.     int i,anz_ent,lst,s_len,ep,sym,rel2_i=-1;
  846.     f_obj=fopen(f_name,"rb");
  847.     if(!f_obj)
  848.     {    sprintf(fehler,"[1][Kann %s|nicht öffnen][Abbruch]",f_name);
  849.         form_alert( 1,fehler);
  850.         exit(0);
  851.     }
  852.     fread(&lh,sizeof(LIBHEADER),1,f_obj);    /* Header des Objectfiles    */
  853.     if(lh.magic!=MAGIC)
  854.     {    sprintf(fehler,"[1][Kann %s|nicht verstehen][Abbruch]",f_name);
  855.         form_alert( 1,fehler);
  856.         exit(0);
  857.     }
  858.     len=lh.imageBytes+lh.symInfoBytes+lh.nameBytes+1;
  859.     if((o_txt=malloc(len))==NULL)
  860.     {    form_alert( 1,"[1][Nicht genug Speicher][Abbruch]");
  861.         exit(0);
  862.     }
  863.     fread(o_txt,1,len,f_obj);    /* IMAGE+SYMBOLS  von *.lib laden    */
  864.     fclose(f_obj);
  865.     /* In der Lib wird immer die XBRA Kennung 'PDeb' verwendet 
  866.         für die 2 Monitor-Version soll aber PDEB verwendet werden*/
  867.     if(monitore==2)
  868.     {    for(i=0;i<lh.imageBytes;i+=2)
  869.         {    if(!memcmp(&o_txt[i],"XBRAPDeb",8))
  870.                 memcpy(&o_txt[i+6],"EB",2);
  871.         }
  872.     }
  873.     /* Symboltabelle laden    */
  874.     rest=lh.nameBytes;
  875.     Sym[0].sy_name=&o_txt[lh.imageBytes+lh.symInfoBytes+1];
  876.     while(rest)
  877.     {    s_len=(int)Sym[Anz_sym].sy_name[-1];
  878.         Sym[Anz_sym].sy_name[-1]='\0';
  879.         rest-=(long)(s_len+1);
  880.         Sym[Anz_sym+1].sy_name=&Sym[Anz_sym].sy_name[s_len+1];
  881.         if(!s_len)
  882.             Sym[Anz_sym].sy_name--;
  883.         Sym[Anz_sym].sy_rel2=rel2_i;
  884.         Sym[Anz_sym++].sy_atxt=0;
  885.     }
  886.     if(Anz_sym>=MAX_SYM-1)    /* kann nur während der Entwicklungsphase vorkommen*/
  887.     {    sprintf(fehler,"[3][zu viele Symbols, erhöhe MAX_SYM|auf mindestens:%i][Schade]",Anz_sym);
  888.         form_alert(1,fehler);
  889.         exit(0);
  890.     }
  891.  
  892.     /* Symboltabelle analysieren    */
  893.     
  894.     Sym[Anz_sym-1].sy_name[s_len]='\0';
  895.     sym_e=(SYMENTRY *)&o_txt[lh.imageBytes];
  896.     anz_ent=(int)(lh.symInfoBytes/sizeof(SYMENTRY));
  897.     lst=Anz_sym;        /* da stört's nicht mehr    */
  898.     for(i=0;i<anz_ent;i++)
  899.     {    pos+=sym_e[i].Position;
  900.         switch((int)sym_e[i].Type)
  901.         {    case 1:            /*End of object */
  902.                 Nbss_len=pos-s_bss;
  903.                 break;
  904.             case 2:            /*Advance eigentl *256 aber 1* ist schon */
  905.                 pos+=(int)sym_e[i].Position*255;
  906.                 break;
  907.             case 4:            /*Start new data segment: */
  908.                 Sym[lst].sy_len+=pos;
  909.                 lst=MAX_SYM-1;
  910.                 Ndat_aram=(char *)&o_txt[pos];
  911.                 s_data=pos;
  912.                 rel2_a=(char *)&o_txt[pos];
  913.                 rel2_i=-2;
  914.                 break;
  915.             case 5:            /*Start new bss segment: */
  916.                 Sym[lst].sy_len+=pos;
  917.                 lst=MAX_SYM-1;
  918.                 Ndat_len=pos-s_data;
  919.                 s_bss=pos;
  920.                 rel2_a=(char *)&o_txt[pos];
  921.                 rel2_i=-3;
  922.                 break;
  923.             case 7:            /*Define new global module: */
  924.             case 9:            /*Define new local module: */
  925.                 Sym[lst].sy_len+=pos;
  926.                 lst=sym_e[i].Wert;
  927.                 Sym[lst].sy_aram=(char *)&o_txt[pos];
  928.                 Sym[lst].sy_atxt=Sym[lst].sy_aram-rel2_a;
  929.                 Sym[lst].sy_stab=&sym_e[i+1];
  930.                 Sym[lst].sy_len=-pos;
  931.                 Sym[lst].sy_rel2=rel2_i;
  932.                 break;
  933.             case 8:            /*Global entrypoint: */
  934.                 ep=sym_e[i].Wert;
  935.                 Sym[ep].sy_aram=(char *)&o_txt[pos];
  936.                 Sym[ep].sy_stab=&sym_e[i+1];
  937.                 Sym[ep].sy_len=0l;
  938.                 Sym[ep].sy_atxt=Sym[ep].sy_aram-Sym[lst].sy_aram;
  939.                 Sym[ep].sy_rel2=lst;
  940.                 break;
  941.             case 3:            /*Start new text segment: */
  942.             case 6:            /*Start new offset segment: */
  943.             case 11:        /*Absolut long reference to: */
  944.             case 14:        /*PC-relative word reference to: */
  945.             case 10:        /*Local entrypoint: */
  946.                 break;        /*hier ignorieren    */
  947.             default:
  948.                 sprintf(fehler,"[1][%s|enthält Symboltyp: %i][Abbruch]",f_name,(int)sym_e[i].Type);
  949.                 form_alert( 1,fehler);
  950.                 exit(0);
  951.                 break;
  952.         }
  953.     }
  954.     for(i=0;i<ANZ_ROUT;i++)
  955.     {    if((sym=find_sym(Pd_r[i].name,0))>-1)
  956.             Sym[sym].sy_atxt=Pd_r[i].addr;
  957.     }
  958. }
  959. /*------------------------------------------------------------------*/
  960. /*            int find_sym(char *name,int flag)                        */
  961. /*                                                                    */
  962. /*                                                                    */
  963. /*         Sucht einen Symboleintrag                                    */
  964. /*        Parameter:     name: Name des Eintrags                            */
  965. /*                    flag: soll bei nicht finden abgebrochen werden?    */
  966. /*        Rückgabe :     index des Symbols                                */
  967. /*                                                                    */
  968. /*        (c) Dimitri Junker                                            */
  969. /*                                                                    */
  970. /*------------------------------------------------------------------*/
  971.  
  972. /* Sucht einen Symboleintrag    */
  973. int find_sym(char *name,int flag)
  974. {    int i,ret=-1;
  975.     char fehler[100];
  976.     for(i=0;i<Anz_sym;i++)
  977.     {    if(!strcmp(Sym[i].sy_name,name))
  978.         {    ret=i;
  979.             break;
  980.         }
  981.     }
  982.     if(ret<0 && flag)
  983.     {    sprintf(fehler,"[1][%s ist nicht|in PD_LIB.LIB][Abbruch]",name);
  984.         form_alert( 1,fehler);
  985.         exit(0);
  986.     }
  987.     return(ret);
  988. }
  989. /*------------------------------------------------------------------*/
  990. /*            void get_pd(PH *ph,PD_ORI *pd_o,int monitore)            */
  991. /*                                                                    */
  992. /*                                                                    */
  993. /*             lädt das original PD.PRG                                */
  994. /*            öffnet das File für das neue Pd_i.PRG                    */
  995. /*        Parameter:     ph: da soll der Programmheader rein                */
  996. /*                    pd_o: da sonstige Infos zu PD.PRG                */
  997. /*                    monitore: nicht schon wieder                    */
  998. /*        Rückgabe :     in ph und pd_o                                    */
  999. /*                                                                    */
  1000. /*        (c) Dimitri Junker                                            */
  1001. /*                                                                    */
  1002. /*------------------------------------------------------------------*/
  1003.  
  1004.  
  1005. void get_pd(PH *ph,PD_ORI *pd_o,int monitore)
  1006. {    char dat_n[50]="*.PRG";
  1007.     
  1008. /* Original PD suchen    */
  1009.  
  1010.  
  1011.     if(!F_in)            /* noch nicht in get_addr geladen    */
  1012.     {    if(*File_n)        /* aber bereits ein Name gesetzt    */
  1013.             F_in=fopen(File_n,"rb");
  1014.         else
  1015.              get_akt_path(File_n);
  1016.     }
  1017.     while(!F_in)
  1018.     {    strcpy(strrchr(File_n,'\\')+1,"*.PRG");
  1019.         if(!easy_fsel(File_n,dat_n,"PD aussuchen2"))
  1020.             exit(0);
  1021.         build_filename(File_n,File_n,dat_n);
  1022.         
  1023.         F_in=fopen(File_n,"rb");
  1024.     }
  1025. /* File für neues PD öffnen    */
  1026.     if(monitore==2)
  1027.         build_filename(File_n,File_n,"pd_2.prg");
  1028.     else
  1029.         build_filename(File_n,File_n,"pd_1.prg");
  1030.     F_out=fopen(File_n,"wb");
  1031.     if(!F_in || !F_out)
  1032.     {    form_alert( 2,"[1][Das angegebene File kann nicht|geöffnet werden][Abbruch]");
  1033.         exit(0);
  1034.     }
  1035. /* laden und analysieren    */
  1036.     if(!pd_o->tot_len)
  1037.     {    pd_o->tot_len=lof(F_in)-0x1c;
  1038.         fseek(F_in,0,SEEK_SET);
  1039.         fread(ph,sizeof(PH),1,F_in);        /* Programmheader von PD.PRG laden */
  1040.         if((pd_o->text=malloc(pd_o->tot_len))==NULL)
  1041.         {    form_alert( 2,"[1][Nicht genug Speicher][Abbruch]");
  1042.             exit(0);
  1043.         }
  1044.         fread(pd_o->text,1,pd_o->tot_len,F_in);                /* PD.PRG laden    */
  1045.     }
  1046.     if(strcmp(Version_txt,(char *)&pd_o->text[Version_ptr]))
  1047.     {    form_alert(2,"[1][Dies ist eine mir fremde PD-Version! Falls| es sich nicht um einen Fehler handelt| Bitte PD_ADDR.DAT löschen und Programm neu starten][Bis dann]");
  1048.         exit(0);
  1049.     }
  1050. }
  1051. /*------------------------------------------------------------------*/
  1052. /*            int init(void)                                            */
  1053. /*                                                                    */
  1054. /*                                                                    */
  1055. /*         Öffnet die Workstation u.ä.                                */
  1056. /*        Parameter: keine                                            */
  1057. /*        Rückgabe : VDI handle                                        */
  1058. /*                                                                    */
  1059. /*        (c) Dimitri Junker                                            */
  1060. /*                                                                    */
  1061. /*------------------------------------------------------------------*/
  1062.  
  1063. int init(void)
  1064. {      int handle;
  1065.     int int_in[11]= {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2};
  1066.     int int_out[57];
  1067.     int dummy;
  1068.     /* Programm anmelden */
  1069.     appl_init();
  1070.     handle=graf_handle(&dummy,&dummy,&dummy,&dummy);
  1071.       v_opnvwk(int_in,&handle,int_out);
  1072.  
  1073.     return(handle);
  1074. }
  1075. /*------------------------------------------------------------------*/
  1076. /*            int get_addr(PH *ph,PD_ORI *pd_o)                        */
  1077. /*                                                                    */
  1078. /*                                                                    */
  1079. /*         Dise Routine versucht, die für den Patch nötigen Adressen    */
  1080. /*        aus einer beliebigen PD Version zu ermitteln.                 */
  1081. /*        Parameter:     Infos zu PD                                        */
  1082. /*        Rückgabe :     keine                                            */
  1083. /*                                                                    */
  1084. /*        (c) Dimitri Junker                                            */
  1085. /*                                                                    */
  1086. /*------------------------------------------------------------------*/
  1087.  
  1088.  
  1089.  
  1090. void get_addr(PH *ph,PD_ORI *pd_o)
  1091. {    char dat_n[50]="";
  1092.     memset(Flag,0,ANZ_ROUT);
  1093.     if(*File_n)
  1094.         F_in=fopen(File_n,"rb");
  1095.     if(!F_in)
  1096.          get_akt_path(File_n);
  1097.     while(!F_in)
  1098.     {    strcpy(strrchr(File_n,'\\')+1,"*.PRG");
  1099.         if(!easy_fsel(File_n,dat_n,"PD aussuchen"))
  1100.             exit(0);
  1101.         build_filename(File_n,File_n,dat_n);
  1102.         
  1103.         F_in=fopen(File_n,"rb");
  1104.     }
  1105.     if(!F_in )
  1106.     {    form_alert( 2,"[1][Das angegebene File kann nicht|geöffnet werden][Abbruch]");
  1107.         exit(0);
  1108.     }
  1109.     pd_o->tot_len=lof(F_in)-0x1c;
  1110.     fseek(F_in,0,SEEK_SET);
  1111.     fread(ph,sizeof(PH),1,F_in);        /* Programmheader von PD.PRG laden */
  1112.     if((pd_o->text=malloc(pd_o->tot_len))==NULL)
  1113.     {    form_alert( 2,"[1][Nicht genug Speicher][Abbruch]");
  1114.         exit(0);
  1115.     }
  1116.     fread(pd_o->text,1,pd_o->tot_len,F_in);                /* PD.PRG laden    */
  1117.     set_namen();    
  1118.     suche_rout1(ph->ph_tlen/2l,(UWORD *)pd_o->text);
  1119.     suche_dat_bss((UWORD *)pd_o->text,ph);
  1120.     suche_rout2(ph->ph_tlen/2l,(UWORD *)pd_o->text);
  1121. }
  1122. /*------------------------------------------------------------------*/
  1123. /*            void suche_rout1(long anz_word,unsigned int p_txt[])    */
  1124. /*                                                                    */
  1125. /*                                                                    */
  1126. /*         Hier werden Routinen Anhand, zumindest bei mir, eindeutiger    */
  1127. /*        Sequenzen gesucht                                            */
  1128. /*    Die Komentare haben folgende Bedeutung:                            */
  1129. /*        name    offs:    Inhalt                                        */
  1130. /*        offs ist also der Offset vom Anfang der Routine name, und     */
  1131. /*        dort steht Inhalt                                            */
  1132. /*        Parameter: Programmcode und seine Länge in Worten            */
  1133. /*        Rückgabe :     keine                                            */
  1134. /*                                                                    */
  1135. /*        (c) Dimitri Junker                                            */
  1136. /*                                                                    */
  1137. /*------------------------------------------------------------------*/
  1138.  
  1139.  
  1140. void suche_rout1(long anz_word,unsigned int p_txt[])
  1141. {    long i,sys_rout;
  1142.     for(i=0;i<anz_word;i++)
  1143.     {    switch(p_txt[i])
  1144.         {    case 0x14:            /*draw_menu    2a:    0014 322a 0016 302a    */
  1145.                 if(p_txt[i+1]==0x322a && p_txt[i+2]==0x0016 && p_txt[i+3]==0x302a)
  1146.                 {    Pd_r[DRAW_MENU].addr=i*2l-0x2al;
  1147.                     Flag[DRAW_MENU]++;
  1148.                 }
  1149.                 break;
  1150.             case 0x3e:            /*Fclose    c:    003e 4e41 584f 245f    */
  1151.                 if(p_txt[i+1]==0x4e41 && p_txt[i+2]==0x584f && p_txt[i+3]==0x245f)
  1152.                 {    Pd_r[FCLOSE].addr=i*2l-0xcl;
  1153.                     Flag[FCLOSE]++;
  1154.                 }
  1155.                 break;
  1156.             case 0x027c:        /* Bomben    8:    027c dfff 4ef9    */
  1157.                 if(p_txt[i+1]==0xdfff && p_txt[i+2]==0x4ef9)
  1158.                 {    Pd_r[BOMBEN].addr=i*2l-8l;
  1159.                     Flag[BOMBEN]++;
  1160.                 }
  1161.                 
  1162.                 break;
  1163.             case 0x223c:
  1164.                 switch(p_txt[i+1])
  1165.                 {    case 0x4D00:            /* graf_handel    4:    223C 4D00 0500    */
  1166.                         if(p_txt[i+2]==0x0500)
  1167.                         {    Pd_r[GRAF_HANDLE].addr=i*2l-4l;
  1168.                             Flag[GRAF_HANDLE]++;
  1169.                         }
  1170.                         break;
  1171.                     case 0x3401:        /* form_alert    c: 223c 3401 0101*/
  1172.                         if(p_txt[i+2]==0x0101)
  1173.                         {    Pd_r[FORM_ALERT].addr=i*2l-0xcl;
  1174.                             Flag[FORM_ALERT]++;
  1175.                         }
  1176.                         break;
  1177.                 }
  1178.                 break;
  1179.             case 0x3EBC:        /* Setexc    4:    3ebc 0005 4e4d    */
  1180.                 if(p_txt[i+1]==0x0005 && p_txt[i+2]==0x4e4d)
  1181.                 {    Pd_r[SETEXC].addr=i*2l-4l;
  1182.                     Flag[SETEXC]++;
  1183.                 }
  1184.                 
  1185.                 break;
  1186.             case 0x3f3c:    /* move.w    #,-(sp)    */
  1187.                 switch(p_txt[i+1])
  1188.                 {    case 0x0002:    /* Physbase        2:    3F3C 0002 4E4E    */
  1189.                         if(p_txt[i+2]==0x4E4E)
  1190.                         {    Pd_r[PHYSBASE].addr=i*2l-0x2l;
  1191.                             Flag[PHYSBASE]++;
  1192.                         }
  1193.                         break;
  1194.                     case 0x0003:    /* Logbase        2:    3F3C 0003 4E4E        */
  1195.                         if(p_txt[i+2]==0x4E4E)
  1196.                         {    Pd_r[LOGBASE].addr=i*2l-0x2l;
  1197.                             Flag[LOGBASE]++;
  1198.                         }
  1199.                         break;
  1200.                     case 0x0005:    
  1201.                         if(p_txt[i+2]==0x4E4E)    /* Setscreen    8:    3F3C 0005 4E4E    */
  1202.                         {    Pd_r[SETSCREEN].addr=i*2l-0x8l;
  1203.                             Flag[SETSCREEN]++;
  1204.                         }
  1205.                         else    /*set_my_exc 10: 001a 3f03 3f3c 0005    */
  1206.                         {    if(p_txt[i-1]==0x3f03 && p_txt[i-2]==0x001a )
  1207.                             {    Pd_r[SETMYEXC].addr=i*2l-0x14l;
  1208.                                 Flag[SETMYEXC]++;
  1209.                             }
  1210.                         }
  1211.                         break;
  1212.                     case 0x0021:    /* Set_Gd_trm    1e: 2f08 3f3c 0021*/
  1213.                         if(p_txt[i-1]==0x2f08)
  1214.                         {    Pd_r[SETGDT].addr=i*2l-0x20l;
  1215.                             Flag[SETGDT]++;
  1216.                         }
  1217.                         else        /*Res_Gd_trm    8: 3f3c 0021*/
  1218.                         {    Pd_r[RESGDT].addr=i*2l-0x8l;
  1219.                             Flag[RESGDT]++;
  1220.                         }
  1221.                         break;
  1222.                     case 0x0044:    /* Mxalloc        6:    3F3C 0044 4E41    */
  1223.                         if(p_txt[i+2]==0x4E41)
  1224.                         {    Pd_r[MXALLOC].addr=i*2l-0x6l;
  1225.                             Flag[MXALLOC]++;
  1226.                         }
  1227.                         break;
  1228.                     case 0x0048:    /* Malloc        0: 4852 2f00 3F3C 0048    */
  1229.                         if(p_txt[i-2]==0x4852)
  1230.                         {    Pd_r[MALLOC].addr=i*2l-0x4l;
  1231.                             Flag[MALLOC]++;
  1232.                         }
  1233.                         break;
  1234.                     case 0x0049:    
  1235.                         switch(p_txt[i-1])
  1236.                         {    case 0x4850:    /* Mfree        2: 4850 3F3C 0049    */
  1237.                                 Pd_r[MFREE].addr=i*2l-0x4l;
  1238.                                 Flag[MFREE]++;
  1239.                                 break;
  1240.                             case 0x2F0B:    /* mfree_a_sp    e: 2F0B 3F3C 0049    */
  1241.                                 Pd_r[MFREEAS].addr=i*2l-0x10l;
  1242.                                 Flag[MFREEAS]++;
  1243.                                 break;
  1244.                         }
  1245.                         break;
  1246.                     case 0x004A:    /* Mshrink        6: 3F00 3F3C 004A    */
  1247.                         if(p_txt[i-1]==0x3F00)
  1248.                         {    Pd_r[MSHRINK].addr=i*2l-0x8l;
  1249.                             Flag[MSHRINK]++;
  1250.                         }
  1251.                         break;
  1252.                 }
  1253.                 break;
  1254.             case 0x4afc:            /* ILLEGAL    */
  1255.                 switch(p_txt[i+1])
  1256.                 {    case 0x2648:    /* memcpyx        0: 48e7 0818 4afc 2648*/
  1257.                         if(p_txt[i-1]==0x0818 && p_txt[i-2]==0x48e7)
  1258.                         {    Pd_r[MEMCPYX].addr=i*2l-0x04l;
  1259.                             Flag[MEMCPYX]++;
  1260.                         }
  1261.                         break;
  1262.                     case 0x23f8:    /* set_hcop_vb  : 6: 4afc 23f8 0502 */
  1263.                         if(p_txt[i+2]==0x502)
  1264.                         {    Pd_r[SETHCV].addr=i*2l-0x06l;
  1265.                             Flag[SETHCV]++;
  1266.                         }
  1267.                         break;
  1268.                     case 0x21f9:    /* res_hcop_vb        0: 4afc 21f9 ; 10: 0502*/
  1269.                         if(p_txt[i+8]==0x502)
  1270.                         {    Pd_r[RESHCV].addr=i*2l-0x0l;
  1271.                             Flag[RESHCV]++;
  1272.                         }
  1273.                         break;
  1274.                 }
  1275.                 break;
  1276.             case 0x4e68:    
  1277.                 if(p_txt[i+1]==0x082f)
  1278.                 {    switch(p_txt[i+6])
  1279.                     {    case 0x000A:    /* Gemdos2    16: 4e68 082f und 22: 000A    */
  1280.                             Pd_r[GEMDOS2].addr=i*2l-0x16l;
  1281.                             Flag[GEMDOS2]++;
  1282.                             break;
  1283.                         case 0x000C:    /* Gemdos2a    16: 4e68 082f und 22: 000C    */
  1284.                             Pd_r[GEMDOS2A].addr=i*2l-0x16l;
  1285.                             Flag[GEMDOS2A]++;
  1286.                             break;
  1287.                     }
  1288.                 }
  1289.                 break;
  1290.             case 0x6606:        /* Etv_term        16:    6606 40e7*/
  1291.                 if(p_txt[i+1]==0x40e7)
  1292.                 {    Pd_r[ETVTRM].addr=i*2l-0x16l;
  1293.                     Flag[ETVTRM]++;
  1294.                 }
  1295.                 break;
  1296.             case 0x701B:        /* esc_h_etc    8: 701B        10: 7048*/
  1297.                 if( p_txt[i+4]==0x7048)
  1298.                 {    Pd_r[ESC_H_ETC].addr=i*2l-0x8l;
  1299.                     Flag[ESC_H_ETC]++;
  1300.                 }
  1301.                 break;
  1302.             case 0x7073:        /* v_opnvwk        36:    7073 4E42*/
  1303.                 if(p_txt[i+1]==0x4E42)
  1304.                 {    Pd_r[V_OPNVWK].addr=i*2l-0x36l;
  1305.                     Flag[V_OPNVWK]++;
  1306.                 }
  1307.                 break;
  1308.             case 0x7265:        /* v_clsvwk        0:    7265 7400*/
  1309.                 if(p_txt[i+1]==0x7400)
  1310.                 {    Pd_r[V_CLSVWK].addr=i*2l;
  1311.                     Flag[V_CLSVWK]++;
  1312.                 }
  1313.                 break;
  1314.             case 0x7266:        /* vq_extnd        16:    7266 7401*/
  1315.                 if(p_txt[i+1]==0x7401)
  1316.                 {    Pd_r[VQ_EXTND].addr=i*2l-0x16l;
  1317.                     Flag[VQ_EXTND]++;
  1318.                 }
  1319.                 break;
  1320.             case 0x726D:        /* vro_cpyfm    16:    726D 243C 0004    */
  1321.                 if(p_txt[i+1]==0x243C && p_txt[i+2]==0x0004)
  1322.                 {    Pd_r[VRO_CPYFM].addr=i*2l-0x16l;
  1323.                     Flag[VRO_CPYFM]++;
  1324.                 }
  1325.                 break;
  1326.             case 0x727A:        /* v_show_c        6:    727A 7401*/
  1327.                 if(p_txt[i+1]==0x7401)
  1328.                 {    Pd_r[V_SHOW_C].addr=i*2l-6l;
  1329.                     Flag[V_SHOW_C]++;
  1330.                 }
  1331.                 break;
  1332.             case 0x727B:        /* v_hide_c    =    0:    727B 7400*/
  1333.                 if(p_txt[i+1]==0x7400)
  1334.                 {    Pd_r[V_HIDE_C].addr=i*2l;
  1335.                     Flag[V_HIDE_C]++;
  1336.                 }
  1337.                 break;
  1338.             case 0x727C:        /* vq_mouse    4:    727C 7400*/
  1339.                 if(p_txt[i+1]==0x7400)
  1340.                 {    Pd_r[VQ_MOUSE].addr=i*2l-4l;
  1341.                     Flag[VQ_MOUSE]++;
  1342.                 }
  1343.                 break;
  1344.             case 0xC0BC:        /* Malloc_high    12:    C0BC FFFF FFFC*/
  1345.                 if(p_txt[i+1]==0xFFFF && p_txt[i+2]==0xFFFC)
  1346.                 {    Pd_r[MALLOC_H].addr=i*2l-12l;
  1347.                     Flag[MALLOC_H]++;
  1348.                 }
  1349.                 break;
  1350.             case 'PD':            /* 'PDeb' bzw 'PDEB' sollte im Original nicht vorkommen*/
  1351.                 if(p_txt[i+1]=='eb' ||p_txt[i+1]=='EB' )
  1352.                 {    if(form_alert(1,"[2][Könnte es sein da₧ es sich hier bereits|um eine gepatchte Version handelt?][ Ja | Nein ]")==1)
  1353.                     {    form_alert(1,"[3][Dann ist ein Patch unmöglich][Schade]");
  1354.                         exit(0);
  1355.                     }
  1356.                 }
  1357.                 break;
  1358.             
  1359.         }
  1360.     }
  1361.     /* Die folgenden Routinen können direkt aus der Adresse von set_my_exc
  1362.         abgeleitet werden    */
  1363.  
  1364.     sys_rout=Pd_r[SETMYEXC].addr+0x2al;    /* ab hier steht Sprungtabelle für setexc    */
  1365.     i=sys_rout/2l;
  1366.     Pd_r[BOMB4].addr    =sys_rout+(long)*((int *)&p_txt[i+ 4l]);
  1367.     Pd_r[NOPRIV].addr    =sys_rout+(long)*((int *)&p_txt[i+ 8l]);
  1368.     Pd_r[TRACE].addr    =sys_rout+(long)*((int *)&p_txt[i+ 9l]);
  1369.     Pd_r[LINEA].addr    =sys_rout+(long)*((int *)&p_txt[i+10l]);
  1370.     Pd_r[AESVDI].addr    =sys_rout+(long)*((int *)&p_txt[i+34l]);
  1371.     Pd_r[TOS1].addr    =sys_rout+(long)*((int *)&p_txt[i+46l])+6l;    /* direkt hinter XBIOS    */
  1372.     Flag[BOMB4]=Flag[NOPRIV]=Flag[TRACE]=Flag[LINEA]=Flag[AESVDI]=Flag[TOS1]=1;
  1373.  
  1374. }
  1375. /*------------------------------------------------------------------*/
  1376. /*            void suche_dat_bss(unsigned int p_txt[],PH *ph)            */
  1377. /*                                                                    */
  1378. /*                                                                    */
  1379. /*         Hier werden die Adressen zu Daten gesucht (DATA +BSS)         */
  1380. /*        DATA dadurch, das der Inhalt gesucht wird,                    */
  1381. /*        BSS durch Zugriffe in bereits bekannten Routinen            */
  1382. /*        Parameter: Programmcode und -header                            */
  1383. /*        Rückgabe :     keine                                            */
  1384. /*                                                                    */
  1385. /*        (c) Dimitri Junker                                            */
  1386. /*                                                                    */
  1387. /*------------------------------------------------------------------*/
  1388.  
  1389.  
  1390. void suche_dat_bss(unsigned int p_txt[],PH *ph)
  1391. {    long i;
  1392.     char *p_txtc,*p_datc;
  1393.     p_txtc=(char *)p_txt;
  1394.     p_datc=&p_txtc[ph->ph_tlen];
  1395.     /* Datas suchen    */
  1396.     for(i=0;i<ph->ph_dlen;i++)
  1397.     {    switch(p_datc[i])
  1398.         {    case 'P':
  1399.                 if(!strcmp(&p_datc[i],"PD.CFG"))
  1400.                     Pd_cfg=ph->ph_tlen+i;
  1401.                 break;
  1402.             case 'U':        
  1403.                 if(!strcmp(&p_datc[i],"User program not yet terminated|Reset program anyway?"))
  1404.                     Reset_any=ph->ph_tlen+i;
  1405.                 break;
  1406.             case 'V':        
  1407.                 if(!strncmp(&p_datc[i],"Vers",4))
  1408.                 {    Version_ptr=ph->ph_tlen+i;
  1409.                     strcpy(Version_txt,&p_datc[i]);
  1410.                 }
  1411.                 break;
  1412.  
  1413.         }
  1414.     }
  1415.     /* BSS bestimmen    */
  1416.     Pd_d[B_2AD06].addr=*((long *)&p_txtc[Pd_r[SETGDT].addr+0x14l]);
  1417.     Pd_d[PRG_ASP].addr=*((long *)&p_txtc[Pd_r[SETGDT].addr+0x4l]);
  1418.     Pd_d[USEOGEM].addr=*((long *)&p_txtc[Pd_r[SETGDT].addr+0xal]);
  1419. /*    Pd_d[PTRTERM].addr=*((long *)&p_txtc[Pd_r[SETGDT].addr+0x44l]);    */
  1420.     Pd_d[ANZBOMB].addr=*((long *)&p_txtc[Pd_r[BOMB4].addr+0xcl]);
  1421.     Pd_d[GDSEMA1].addr=*((long *)&p_txtc[Pd_r[BOMBEN].addr+0x2l]);
  1422.     Pd_d[ORSR2].addr=*((long *)&p_txtc[Pd_r[TOS1].addr-0x4l])-176;
  1423.     Pd_d[ALTHLP].addr=*((long *)&p_txtc[Pd_r[SETHCV].addr+0x2l]);
  1424.     if(*((int *)&p_txtc[Pd_r[MALLOC_H].addr+0xAEl])==0x26b9)
  1425.         Pd_d[MEM_L1].addr=*((long *)&p_txtc[Pd_r[MALLOC_H].addr+0xB0l]);
  1426.     else
  1427.     {    form_alert(1,"[3][Kann Mem_l1 nicht bestimmen][Schade]");
  1428.         exit(0);
  1429.     }
  1430.     return;
  1431. }
  1432. /*------------------------------------------------------------------*/
  1433. /*            void suche_rout2(long anz_word,unsigned int p_txt[])    */
  1434. /*                                                                    */
  1435. /*                                                                    */
  1436. /*        wie suche_rout1, allerdings werden bereits vorher bestimmte    */
  1437. /*        Adressen benötigt                                            */
  1438. /*        Parameter: Programmcode und seine Länge in Worten            */
  1439. /*        Rückgabe :     keine                                            */
  1440. /*                                                                    */
  1441. /*        (c) Dimitri Junker                                            */
  1442. /*                                                                    */
  1443. /*------------------------------------------------------------------*/
  1444.  
  1445.  
  1446. void suche_rout2(long anz_word,unsigned int p_txt[])
  1447. {    long i;
  1448.     int j;
  1449.     char fehler[200];
  1450.     for(i=0;i<anz_word;i++)
  1451.     {    switch(p_txt[i])
  1452.         {    case 0x33FC:        /*BombXY    0:    33FC XY Anz_Bomb*/
  1453.                 if( *(long *)&p_txt[i+2] ==Pd_d[ANZBOMB].addr )
  1454.                 {    switch(p_txt[i+1])
  1455.                     {    case 0x1c:    /* Bomb28    */
  1456.                             if(p_txt[i-1]==0x4e75)
  1457.                             {    Pd_r[BOMB28].addr=i*2l;
  1458.                                 Flag[BOMB28]++;
  1459.                             }
  1460.                             break;
  1461.                         case 0x21:    /* Bomb33    */
  1462.                             Pd_r[BOMB33].addr=i*2l;
  1463.                             Flag[BOMB33]++;
  1464.                             break;
  1465.                     }
  1466.                 }
  1467.                 break;
  1468.             case 0x41f9:        /*reset        12: 41f9 reset_any*/
  1469.                 if( *(long *)&p_txt[i+1] ==Reset_any )
  1470.                 {    Pd_r[RESET].addr=i*2l-0x12l;
  1471.                     Flag[RESET]++;
  1472.                     Pd_r[RESET_A].addr=Pd_r[RESET].addr+10l;
  1473.                     Flag[RESET_A]++;
  1474.                     Pd_d[B_23E58].addr=*(long *)&p_txt[i-7l];
  1475.                 }
  1476.                 break;
  1477.             case 0x47f9:    /* lea nach a3    */
  1478.                 if( *(long *)&p_txt[i+1] ==Pd_d[ORSR2].addr &&p_txt[i+4]==0x2f1b)    /*res_my_exc    4:    47f9 or_srout2 7602 2f1b*/
  1479.                 {    Pd_r[RESMYEXC].addr=i*2l-4;
  1480.                     Flag[RESMYEXC]++;
  1481.                 }
  1482.                 else
  1483.                 {    if( *(long *)&p_txt[i+1] ==Pd_d[MEM_L1].addr)    /*mfree_l1    8:    47f9 Mem_l1*/
  1484.                     {    Pd_r[MFREEL1].addr=i*2l-8;
  1485.                         Flag[MFREEL1]++;
  1486.                     }
  1487.                 }
  1488.                 break;
  1489.             case 0x4eb9:        /* jsr*/
  1490.                 if(p_txt[i+3]==0x4e75)
  1491.                 {    if( *(long *)&p_txt[i+1] ==Pd_r[V_SHOW_C].addr)    /*Show_curs    10:    4eb9 v_show_c.l 4e75 */
  1492.                     {    Pd_r[SHOW_CURS].addr=i*2l-0x10l;
  1493.                         Flag[SHOW_CURS]++;
  1494.                     }
  1495.                     if( *(long *)&p_txt[i+1] ==Pd_r[V_HIDE_C].addr)    /*Hide_curs    16:    4eb9 v_hide_c.l 4e75 */
  1496.                     {    Pd_r[HIDE_CURS].addr=i*2l-0x16l;
  1497.                         Flag[HIDE_CURS]++;
  1498.                     }
  1499.                 }
  1500.                 break;
  1501.         }
  1502.     }
  1503. /* Prüfen ob alle Routinen genau 1* gefunden wurden    */
  1504.     for(j=0;j<ANZ_ROUT;j++)
  1505.     {    if(Flag[j]!=1)
  1506.         {    sprintf(fehler,"[3][Routine %i: %s|wurde %i * gefunden][Abbruch|Weiter]",j,Pd_r[j].name,Flag[j]);
  1507.             if(form_alert(1,fehler)==1)
  1508.                 exit(0);
  1509.         }
  1510.     }    
  1511. }
  1512. /*------------------------------------------------------------------*/
  1513. /*            void set_namen(void)                                    */
  1514. /*                                                                    */
  1515. /*     Setzen der Namen in den Feldern Pd_r, Pd_d                        */
  1516. /*                                                                    */
  1517. /*        Parameter: keine                                            */
  1518. /*        Rückgabe : keine                                            */
  1519. /*                                                                    */
  1520. /*        (c) Dimitri Junker                                            */
  1521. /*                                                                    */
  1522. /*------------------------------------------------------------------*/
  1523.  
  1524. void set_namen(void)
  1525. {    strcpy(Pd_r[DRAW_MENU].name,"draw_menu");
  1526.     strcpy(Pd_r[SHOW_CURS].name,"show_curs");
  1527.     strcpy(Pd_r[HIDE_CURS].name,"hide_curs");
  1528.     strcpy(Pd_r[RESET].name,"prg_reset");
  1529.     strcpy(Pd_r[RESET_A].name,"prg_reset_a");
  1530.     strcpy(Pd_r[MALLOC_H].name,"malloc_high");
  1531.     strcpy(Pd_r[MFREEL1].name,"mfree_l1");
  1532.     strcpy(Pd_r[BOMB28].name,"Bomb28");
  1533.     strcpy(Pd_r[BOMB33].name,"Bomb33");
  1534.     strcpy(Pd_r[BOMBEN].name,"Bomben");
  1535.     strcpy(Pd_r[RESMYEXC].name,"res_my_exc");
  1536.     strcpy(Pd_r[SETMYEXC].name,"set_my_exc");
  1537.     strcpy(Pd_r[BOMB4].name,"Bomb4");
  1538.     strcpy(Pd_r[TRACE].name,"Trace");
  1539.     strcpy(Pd_r[NOPRIV].name,"NoPriv");
  1540.     strcpy(Pd_r[LINEA].name,"LineA");
  1541.     strcpy(Pd_r[AESVDI].name,"AesVdi");
  1542.     strcpy(Pd_r[TOS1].name,"Tos1");
  1543.     strcpy(Pd_r[MEMCPYX].name,"memcpyx");
  1544.     strcpy(Pd_r[ESC_H_ETC].name,"esc_h_etc");
  1545.     strcpy(Pd_r[RESGDT].name,"Res_Gd_trm");
  1546.     strcpy(Pd_r[MFREEAS].name,"mfree_a_sp");
  1547.     strcpy(Pd_r[GEMDOS2].name,"Gemdos2");
  1548.     strcpy(Pd_r[SETGDT].name,"Set_Gd_trm");
  1549.     strcpy(Pd_r[SETHCV].name,"set_hcop_vb");
  1550.     strcpy(Pd_r[RESHCV].name,"res_hcop_vb");
  1551.     strcpy(Pd_r[GEMDOS2A].name,"Gemdos2a");
  1552.     strcpy(Pd_r[ETVTRM].name,"Etv_term");
  1553.     strcpy(Pd_r[FCLOSE].name,"Fclose");
  1554.     strcpy(Pd_r[SETEXC].name,"Setexc");
  1555.     strcpy(Pd_r[MXALLOC].name,"Mxalloc");
  1556.     strcpy(Pd_r[MSHRINK].name,"Mshrink");
  1557.     strcpy(Pd_r[MFREE].name,"Mfree");
  1558.     strcpy(Pd_r[MALLOC].name,"Malloc");
  1559.     strcpy(Pd_r[SETSCREEN].name,"Setscreen");
  1560.     strcpy(Pd_r[PHYSBASE].name,"Physbase");
  1561.     strcpy(Pd_r[LOGBASE].name,"Logbase");
  1562.     strcpy(Pd_r[GRAF_HANDLE].name,"graf_handle");
  1563.     strcpy(Pd_r[FORM_ALERT].name,"form_alert");
  1564.     strcpy(Pd_r[V_SHOW_C].name,"v_show_c");
  1565.     strcpy(Pd_r[V_OPNVWK].name,"v_opnvwk");
  1566.     strcpy(Pd_r[V_HIDE_C].name,"v_hide_c");
  1567.     strcpy(Pd_r[V_CLSVWK].name,"v_clsvwk");
  1568.     strcpy(Pd_r[VRO_CPYFM].name,"vro_cpyfm");
  1569.     strcpy(Pd_r[VQ_MOUSE].name,"vq_mouse");
  1570.     strcpy(Pd_r[VQ_EXTND].name,"vq_extnd");
  1571.  
  1572.     
  1573.     strcpy(Pd_d[B_23E58].name,"b_23E58");
  1574.     strcpy(Pd_d[MEM_L1].name,"Mem_l1");
  1575.     strcpy(Pd_d[B_2AD06].name,"B_2AD06");
  1576.     strcpy(Pd_d[ANZBOMB].name,"AnzBomben");
  1577.     strcpy(Pd_d[GDSEMA1].name,"GD_sema1");
  1578.     strcpy(Pd_d[ORSR2].name,"or_srout2");
  1579.     strcpy(Pd_d[ALTHLP].name,"Alt_Hlp");
  1580.     strcpy(Pd_d[PRG_ASP].name,"Prg_a_sp");
  1581. /*    strcpy(Pd_d[PTRTERM].name,"Ptr_term");    */
  1582.     strcpy(Pd_d[USEOGEM].name,"use_or_gem");
  1583. }
  1584.  
  1585. /*------------------------------------------------------------------*/
  1586. /*            int read_addr(void)                                        */
  1587. /*                                                                    */
  1588. /*                                                                    */
  1589. /*         Statt mit get_addr ermittelt können die Adressen auch aus     */
  1590. /*        einem DAT File gelesen werden                                */
  1591. /*        Parameter: keine                                            */
  1592. /*        Rückgabe : erfolgreich?                                        */
  1593. /*                                                                    */
  1594. /*        (c) Dimitri Junker                                            */
  1595. /*                                                                    */
  1596. /*------------------------------------------------------------------*/
  1597.  
  1598. int read_addr(void)
  1599. {    FILE *file;
  1600.     char f_vers[10];
  1601.     char prgvers[]=PRGVERS;
  1602.     int anz,ret=1;
  1603.     if((file=fopen("PD_ADDR.DAT","rb"))==NULL)
  1604.         return(0);     /* dann halt nicht    */
  1605.     fgets(f_vers,9,file);
  1606.     *strchr(f_vers,'\n')='\0';
  1607.     if(strcmp(f_vers,prgvers))
  1608.         ret=0;
  1609.     else
  1610.     {    fread(&anz,sizeof(int),1,file);
  1611.         if(anz==ANZ_ROUT)
  1612.             fread(Pd_r,sizeof(PD_ROUT),ANZ_ROUT,file);
  1613.         else
  1614.             ret=0;
  1615.     }
  1616.     if(ret)
  1617.     {    fread(&anz,sizeof(int),1,file);
  1618.         if(anz==ANZ_DAT)
  1619.             fread(Pd_d,sizeof(PD_ROUT),ANZ_DAT,file);
  1620.         else
  1621.             ret=0;
  1622.     }
  1623.     if(ret)
  1624.     {    fread(&Pd_cfg,sizeof(long),1,file);
  1625.         fgets(File_n,(int)sizeof(File_n)-1,file);
  1626.         *strchr(File_n,'\n')='\0';
  1627.         fread(&Version_ptr,sizeof(long),1,file);
  1628.         fgets(Version_txt,(int)sizeof(Version_txt)-1,file);
  1629.         *strchr(Version_txt,'\n')='\0';
  1630.     }
  1631.     fclose(file);
  1632.     return(ret);
  1633. }
  1634. /*------------------------------------------------------------------*/
  1635. /*            void save_addr(void)                                    */
  1636. /*                                                                    */
  1637. /*                                                                    */
  1638. /* gefundene Adressen für nächstesmal merken                        */
  1639. /*        Parameter: keine                                            */
  1640. /*        Rückgabe : keine                                            */
  1641. /*                                                                    */
  1642. /*        (c) Dimitri Junker                                            */
  1643. /*                                                                    */
  1644. /*------------------------------------------------------------------*/
  1645.  
  1646. void save_addr(void)
  1647. {    FILE *file;
  1648.     int anz=ANZ_ROUT;
  1649.     char prgvers[]=PRGVERS;
  1650.     if((file=fopen("PD_ADDR.DAT","wb"))==NULL)
  1651.         return;     /* dann halt nicht    */
  1652.     fputs(prgvers,file);
  1653.     fputc('\n',file);
  1654.     fwrite(&anz,sizeof(int),1,file);
  1655.     fwrite(Pd_r,sizeof(PD_ROUT),ANZ_ROUT,file);
  1656.     anz=ANZ_DAT;
  1657.     fwrite(&anz,sizeof(int),1,file);
  1658.     fwrite(Pd_d,sizeof(PD_ROUT),ANZ_DAT,file);
  1659.     fwrite(&Pd_cfg,sizeof(long),1,file);
  1660.     fputs(File_n,file);
  1661.     fputc('\n',file);
  1662.     fwrite(&Version_ptr,sizeof(long),1,file);
  1663.     fputs(Version_txt,file);
  1664.     fputc('\n',file);
  1665.     fclose(file);
  1666. }
  1667. /*------------------------------------------------------------------*/
  1668. /*            void save_addr_txt(void)                                */
  1669. /*                                                                    */
  1670. /*                                                                    */
  1671. /* Nur zu Kontrollzwecken noch eine Klartextversion    von save_addr    */
  1672. /*        Parameter: keine                                            */
  1673. /*        Rückgabe : keine                                            */
  1674. /*                                                                    */
  1675. /*        (c) Dimitri Junker                                            */
  1676. /*                                                                    */
  1677. /*------------------------------------------------------------------*/
  1678.  
  1679. void save_addr_txt(void)
  1680. {    FILE *file;
  1681.     int anz=ANZ_ROUT,i;
  1682.     char prgvers[]=PRGVERS;
  1683.     if((file=fopen("PD_ADDR.TXT","w"))==NULL)
  1684.         return;     /* dann halt nicht    */
  1685.     fprintf(file,"Dieses File ist nur zu Kontrollzwecken.\n");
  1686.     fprintf(file,"Es ist einfacher zu lesen als das DAT File.\n");
  1687.     fprintf(file,"Programmversion: %s\n",prgvers);
  1688.     fprintf(file,"Anzahl Routinen: %i\n",anz);
  1689.     for(i=0;i<ANZ_ROUT;i++)
  1690.         fprintf(file,"Pd_r[%i]={%s ; %lX} \n",i,Pd_r[i].name,Pd_r[i].addr);
  1691.     anz=ANZ_DAT;
  1692.     fprintf(file,"Anzahl Daten: %i\n",anz);
  1693.     for(i=0;i<ANZ_DAT;i++)
  1694.         fprintf(file,"Pd_d[%i]={%s ; %lX} \n",i,Pd_d[i].name,Pd_d[i].addr);
  1695.  
  1696.     fprintf(file,"Pd_cfg=%lX\n",Pd_cfg);
  1697.     fprintf(file,"PD Version Pointer: %s\n",Version_ptr);
  1698.     fprintf(file,"PD Version: %s\n",Version_txt);
  1699.     fclose(file);
  1700. }