Zaehler: ; Zaehlroutine cmp cs:flag,0 ; Zaehlroutine aktiviert ? jz Ende_Zaehler ; nein => Sprung zum Ende dec cs:time ; ja => Zaehler dekrementieren jnz Ende_Zaehler ; Zaehler!=0 => Sprung zum Ende mov cs:flag,0 ; Zaehlroutine deaktivieren call cs:[hdl_adr] ; Handlerroutine aufrufen Ende_Zaehler: jmp cs:[old_adr] ; Alten Int 01Ch anspringen Install_Timer: ; INSTALL_TIMER cmp cs:installed,0 ; Schon installiert ? jnz Ende_Install ; Ja => Sprung zum Ende push ax ; Verwendete Register sichern push ds mov ax,0 mov ds,ax ; ds=0 (Interrupts liegen bei 0:Adresse) mov ax,ds:[070h] ; ax=offset Int 01Ch mov cs:[old_ofs],ax ; abspeichern mov ax,ds:[072h] ; ax=segment Int 01Ch mov cs:[old_seg],ax ; abspeichern cli ; Jetzt keinen Interrupt ! mov word ptr ds:[070h],offset Zaehler ; neue Int 01Ch Adresse setzen mov ds:[072h],cs sti ; Interrupts wieder zulassen mov cs:installed,1 ; Installflag setzen pop ds ; benutzte Register zuruecksichern pop ax Ende_Install: ret Remove_Timer: ; Remove_Timer cmp cs:installed,0 ; War was installiert ? jz Ende_Remove ; nein => Sprung zum Ende push ax ; benutzte Register sichern push ds mov ax,0 mov ds,ax ; ds=0 (Interruptadressen sind bei Segment 0) cli ; Jetzt keinen INTERRRRRRRRUPT !!!!!!!! mov ax,cs:[old_ofs] ; ax=alter Offset mov ds:[070h],ax ; und setzen mov ax,cs:[old_seg] ; ax=altes Segment mov ds:[072h],ax ; und setzen sti mov cs:flag,0 ; fuer spaetere Neuinstallation deaktivieren mov cs:installed,0 ; und Installationsflag loeschen pop ds ; Register zuruecksetzen pop ax Ende_Remove: ret ; ax DELAY ; bx Segmentadresse Handler ; cx Offsetadresse Handler ; Ausgabe: ax==0 => Erfolgreich installiert. ; ax==1 => Fehler aufgetreten (Timeout schon besetzt) SET_TIMEOUT: ; SET_TIMEOUT push bp ; Prolog mov bp,sp ; alten SP sichern sub sp,2 ; platz fuer return-code mov word ptr [bp-2],1 ; zunaechst mal Fehler annehmen cmp cs:installed,0 ; Zaehlroutine Installiert jnz No_Install ; Ja => weiter gehts call Install_Timer ; Nein => Gleich mal installieren No_Install: cmp cs:flag,0 ; Zaehlroutine schon aktiviert jnz Ende_Timeout ; => Anfrage ignorieren und zum Ende mov word ptr [bp-2],0 ; Ab jetzt kein Fehler mehr push ax ; benutzte Register sichern push dx push si mov si,182 ; Zeit in Ticks ausrechnen: mul si ; dx:ax=ax * 182 add ax,5 ; ax+5 (wegen Rundung) jnc no_carry ; kein Ueberlauf, alles ok inc dx ; Ueberlauf => noch eins zu dx dazu no_carry: ; d.h. dx:ax+=5 mov si,10 div si ; ax=dx:ax/10 (ax=ax*18.2 (gerundet)) mov cs:time,ax ; Zeit in Ticks setzen mov cs:hdl_ofs,cx ; Offset der Handlerroutine setzen mov cs:hdl_seg,bx ; Segment der Handlerroutine setzen mov cs:flag,1 ; und aktivieren pop si ; benutzte Register zuruecksichern pop dx pop ax Ende_Timeout: mov ax,[bp-2] ; Returncode nach ax mov sp,bp pop bp ret flag db 0 ; Aktivierungsflag fuer Zaehlroutine installed db 0 ; Installierungsflag time dw 0 ; Wartezeit in Ticks (1/18.2 s) hdl_adr equ this dword ; Handler-Adresse (seg:ofs) hdl_ofs dw 0 ; Offset von Handler-Adresse hdl_seg dw 0 ; Segment von Handler-Adresse old_adr equ this dword ; das Gleiche f. alten Int 01Ch old_ofs dw 0 old_seg dw 0