; TSR-HANDLER ; written by ; Frank Riemenschneider ; Postfach 730309 ; 3000 Hannover 71 ; Beim ersten Aufruf wird der Handler installiert. Es stehen die Routinen ; TSRINST (Pointer auf TSR-Pascal Prozedur,Hotkeys), ; tpesTINST ; sowie TSRUNINST ; fr einen Aufruf von Turbo-Pascal zur Verfgung. ; Beim zweiten Aufruf wird der Handler wieder deaktiviert. CODE segment byte public assume cs:CODE, ds:CODE, es:CODE public tsrinst public testInst public tsruninst ;Aktivierung der neuen Interrupt-Routinen tsrinst proc near push bp ;BP auf dem Stack sichern mov bp,sp ;SP nach BP bertragen push es ;ES auf dem Stack sichern ; Die Pascal-Programm-Segmentregister retten mov cs:tpss,ss mov cs:tpsp,sp mov cs:tpes,es mov cs:tpds,ds mov bx,[bp+8] ;Pointer auf TSR-Prozedur holen mov cs:tsradr,bx ;und sichern mov bx,[bp+6] ;Maske fr Hotkey holen und merken mov cs:hotkey,bx ;und sichern ;PSP des Pascal-Programms sichern mov ax,cs sub ax,10h ;256 Byte abziehen mov cs:tppspseg,ax ;Segmentadresse merken ;Adresse des INDOS-Flags sichern mov ah,34h ;Adresse INDOS-Flag holen int 21h mov cs:indosofs,bx ;und merken mov cs:indosseg,es ;DTA-Adresse des Pascal-Programms merken mov ah,2fh ;DTA-Adresse holen int 21h mov cs:tpdtaofs,bx mov cs:tpdtaseg,es ;und merken ;Installationsflag (TSR bereits installiert) setzen mov ax,11111 mov cs:aktflag,ax ;Adressen der umzuleitenden Interrupt-Handler merken mov ax,3509h ;Interrupt-Vektor 9h sichern int 21h mov cs:int9ofs,bx mov cs:int9seg,es mov ax,3513h ;Interrupt-Vektor 13h sichern int 21h mov cs:int13ofs,bx mov cs:int13seg,es mov ax,3516h ;Interrupt-Vektor 16h sichern int 21h mov cs:int16ofs,bx mov cs:int16seg,es ;Zurcksetzen des Interrupt-Vektors 9h verhindern mov ah,20h mov al,1 mov dl,0 int 61h ;Installation der Interrupt-Vektoren push ds ;Datensegment merken mov ax,cs ;Segment ist immer Codesegment mov ds,ax mov ax,2509h ;Interrupt-Vektor 9h setzen mov dx,offset int09 int 21h mov ax,2513h ;Interrupt-Vektor 13h setzen mov dx,offset int13 int 21h mov ax,2516h ;Interrupt-Vektor 16h setzen mov dx,offset int16 int 21h pop ds ;DS wieder vom Stack holen ;Programm resident beenden mov ax,3100h mov dx,[bp+4] ;Anzahl der reservierten Paragraphen int 21h ;Programm beenden tsrinst endp ; testINST: stellt fest, ob das Programm bereits installiert ist ; Rckgabe-Wert : 1, wenn das Programm installiert ist, sonst 0 testinst proc near mov ax,3509h ;Interrupt-Vektor 9h holen int 21h ;DOS-Interrupt holt Segadresse nach ES mov di,offset aktflag ;Installationsflag holen mov ax,11111 ;Vergleichswert holen mov dl,0 ;Annahme : Nicht identisch cmp ax,es:[di] ;mit Installationsflag vergleichen jne notinst ;ungleich : Nicht installiert mov dl,1 ;gleich : Installiert notinst: mov al,dl ;Return-Code nach AL holen ret ;zurck zum Aufrufer testinst endp ;Ende der Prozedur ; TSRUNINST: reinstalliert das TSR-Programm tsruninst proc near push ds ;DS auf dem Stack sichern mov ax,3509h ;Holt Segmentadresse der neuen int 21h ;Interrupt-Routinen cli mov ax,2509h ;Alten Interrupt-Vektor 9h setzen mov ds,es:int9seg mov dx,es:int9ofs int 21h mov ax,2513h ;Alten Interrupt-Vektor 13h setzen mov ds,es:int13seg mov dx,es:int13ofs int 21h mov ax,2516h ;Alten Interrupt-Vektor 16h setzen mov ds,es:int16seg mov dx,es:int16ofs int 21h sti ;Interrupts wieder erlauben mov es,es:tppspseg ;PSP-Segmentadresse des TSR-Programms mov cx,es ;holen mov es,es:[02ch] ;Segmentadresse Environment aus PSP holen mov ah,49h int 21h ;Speicher freigeben mov es,cx mov ah,49h int 21h ;Speicher freigeben pop ds ;DS wieder vom Stack holen ret tsruninst endp ;Ende der Prozedur ;Die neue Interrupt 09h-Routine int09 proc far pushf ;Aufruf der alten Routine call cs:int9ptr cli ;Interrupts verbieten cmp cs:rekflag,0 ;TSR-Programm bereits aktiv? jne notsr ;Ja, Ende ! cmp cs:int13flag,0 ;BIOS-Disk-Interrupt aktiv? jne notsr ;Ja, Ende ! push ax push es xor ax,ax ;Hot-Key bet„tigt ? mov es,ax mov ax,word ptr es:[417h] and ax,cs:hotkey cmp ax,cs:hotkey pop es pop ax jne notsr ;Nein, Ende ! push ds push bx lds bx,cs:indos cmp byte ptr [bx],0 ;INDOS-Flag holen pop bx pop ds ;DOS-Funktion aktiv ? je tsrstart ;Nein, TSR-Aufruf m”glich ! push ax mov ah,cs:int16flag ;BIOS-Flag prfen cmp ah,0 ;= 0, dann warten auf Tastendruck pop ax jnz notsr ;Nein, Ende ! tsrstart: call tsrbegin ;TSR-Programm aufrufen notsr: sti ;Interrupts wieder zulassen iret ;zurck zum unterbrochenen Programm int09 endp ;TSR-Programm aktivieren tsrbegin proc near mov cs:rekflag,1 ;TSR-Rekursions-Flag setzen mov cs:stseg,ss ;aktuelles Stacksegment und Stack- mov cs:stptr,sp ;zeiger merken mov ss,cs:tpss ;den Stack des Pascal-Programms mov sp,cs:tpsp ;aktivieren push es ;die Register auf dem Stack push ds ;des Pascal-Programms sichern push di push si push bp push dx push cx push bx push ax mov cx,64 mov ds,cs:stseg mov si,cs:stptr ;DOS-Stack sichern lab1: push word ptr [si] inc si inc si loop lab1 mov ah,51h ;Adresse des PSP holen int 21h mov cs:pspseg,bx ;und merken mov ah,2fh ;DTA-Adresse holen int 21h mov cs:dtaofs,bx mov cs:dtaseg,es ;und merken mov ah,50h ;PSP des Pascal-Programms setzen mov bx,cs:tppspseg int 21h mov ah,1ah ;DTA-Adresse des Pascal-Programms setzen mov dx,cs:tpdtaofs mov ds,cs:tpdtaseg int 21h mov ds,cs:tpds ;Segment-Register fr das Pascal- mov es,cs:tpes ;Programm setzen sti ;Interrupts wieder zulassen call cs:tsradr ;TSR-Programm aufrufen cli ;Interrupts verbieten mov ah,1ah ;DTA-Adresse des unterbrochenden mov dx,cs:dtaofs mov ds,cs:dtaseg int 21h ;Programms setzen mov ah,50h ;PSP des unterbrochenden mov bx,cs:pspseg int 21h ;Programms setzen mov cx,64 mov ds,cs:stseg ;DOS-Stack vom Stack des mov si,cs:stptr add si,128 ;Pascal-Programms holen lab2: dec si dec si pop word ptr [si] loop lab2 pop ax ;Register vom pop bx ;Stack des Pascal-Programms holen pop cx pop dx pop bp pop si pop di pop ds pop es mov ss,cs:stseg ;Stack des unterbrochenden Programms mov sp,cs:stptr ;restaurieren mov cs:rekflag,0 ;TSR-Rekursions-Flag zurcksetzen ret tsrbegin endp ;Die neue Interrupt 13h-Routine int13 proc far mov cs:int13flag,1 ;BIOS-Disk-Interrupt aktiv pushf ;Aufruf der alten Interrupt 13h-Routine call cs:int13ptr mov cs:int13flag, 0 ;BIOS-Disk-Interrupt nicht mehr aktiv ret 2 ;zurck zum unterbrochenden Programm int13 endp ;Die neue Interrupt 16h-Routine int16 proc far mov cs:int16flag,ah ;BIOS-Funktionsnummer merken pushf ;Aufruf der alten Interrupt 16h-Routine call cs:int16ptr mov cs:int16flag,111 ;BIOS-Interrupt nicht mehr aktiv ret 2 ;zurck zum unterbrochenden Programm int16 endp ; Variablen aktflag dw 0 ;Aktivierungs-Flag tpss dw 0 ;Stacksegment des Pascal-Programms tpsp dw 0 ;Stackpointer des Pascal-Programms tpds dw 0 ;Datensegment des Pascal-Programms tpes dw 0 ;Extrasegment des Pascal-Programms tpdtaofs dw 0 ;DTA-Adresse des Pascal-Programms tpdtaseg dw 0 tppspseg dw 0 ;Segmentadresse des PSP des Pascal-Prog. tsradr dw 0 ;Adresse der TSR-Prozedur hotkey dw 0 ;Hotkey-Maske fr BIOS-Tastaturflag rekflag db 0 ;Rekursionsflag int13flag db 0 ;BIOS-Disk-Interrupt-Flag int16flag db 111 ;BIOS-Tastatur-Interrupt-Flag indos equ this dword ;Pointer auf das DOS Indos-Flag indosofs dw 0 ;INDOS-Flag Offsetadresse indosseg dw 0 ;INDOS-Flag Segmentadresse int13ptr equ this dword ;Alter Interrupt-Vektor 13h int13ofs dw 0 ;Interrupt-Vektor 13h Offsetadresse int13seg dw 0 ;Interrupt-Vektor 13h Segmentadresse int16ptr equ this dword ;Alter Interrupt-Vektor 16h int16ofs dw 0 ;Interrupt-Vektor 16h Offsetadresse int16seg dw 0 ;Interrupt-Vektor 16h Segmentadresse int9ptr equ this dword ;Alter Interrupt-Vektor 9h int9ofs dw 0 ;Interrupt-Vektor 9h Offsetadresse int9seg dw 0 ;Interrupt-Vektor 9h Segmentadresse dtaofs dw 0 ;DTA-Adresse (Offset) dtaseg dw 0 ;DTA-Adresse (Segment) pspseg dw 0 ;Segmentadresse des PSP stseg dw 0 ;Stacksegment des unterbrochenden Prog. stptr dw 0 ;Stackpointer des unterbrochenden Prog. CODE ends ;Ende des Codesegments end