; residentes Programm fr AT-Rechner, um 720-KB-Disketten
; in MF-Laufwerken schreiben und lesen zu knnen

code            segment
                assume cs:code
                org     100h
start:
                jmp     init

newint13:
                cli                  ;Interrupts sperren
                cmp     ah, 0        ;Disk-Reset?
                jne     next         ;Nein, dann weiterprfen
                mov     cs:reset, 1  ;Resetflag setzen
                jmp     wpruef
next:
                mov     cs:reset, 0  ;Resetflag lschen
wpruef:
                cmp     ah, 3        ;Sektoren schreiben
                jg      oldint13     ;Nein, dann alter Int 13h
                cmp     ah, 2        ;Sektoren lesen
                jb      oldint13     ;Nein
                cmp     dl, 0        ;Laufwerk A
                ;Fr Laufwerk B cmp dl, 1 einfgen
                jne     oldint13     ;Nein
                cmp     ch, 0        ;Spur gráer als Null
                je      oldint13     ;Nein
                sti                  ;Interrupts zulassen
                pushf
                call    dword ptr cs:[int13]
                ;alte Int 13h Routine aufrufen
                jnc     ende         ;Kein Fehler aufgetreten
                cmp     ah, 4        ;Sektor nicht gefunden
                jne     weiter       ;Nein
                dec     cs:zaehler   ;decrement Fehlerzhler
                cmp     cs:zaehler, 0 ;schon alle Versuche?
                jne     weiter       ;Nein
                mov     cs:zaehler, 2 ;Fehlerzhler neu setzen
                cmp     cs:einstep, 1 ;schon Einzelstep?
                je      umschalt      ;Ja
                mov     cs:einstep, 1 ;Einzelstepflag
                call    step          ;Umschalten auf Einzelstep
                jmp     weiter
umschalt:
                mov     cs:einstep, 0 ;Umschalten auf Doppelstep
weiter:
                stc                  ;Fehlerkennung setzen
                jmp     ende

oldint13:
                sti                  ;Interrupt wieder zulassen
                pushf
                call    dword ptr cs:[int13] ;Int 13h aufrufen
                pushf                ;Flags retten
                cmp     dl, 0        ;nur Diskzugriffe auf A
                ;Fr Laufwerk B cmp dl, 1 einfgen
                jne     schluss       ;kein Diskzugriff
                cmp     cs:reset, 1   ;Resetflag gesetzt
                jne     schluss       ;Nein
                cmp     cs:einstep, 1 ;und Einzelstep
                jne     schluss       ;Nein
                call    step          ;Einzelstep einschalten
schluss:
                popf
ende:
                push    ax
                pushf
                pop     ax           ;Flagregister nach AX laden
                push    bp
                mov     bp, sp
                mov     ss:[bp+8], ax
                ;Flagregister aktualisieren
                pop     bp
                pop     ax

                iret

step            proc    near
                push    ax
                push    ds
                mov     ax, 0040h
                mov     ds, ax       ;Segmentregister
                and byte ptr ds:[0090h], 11011111b
;Fr Laufwerk B and byte ptr ds:[0091h], 11011111b einsetzen
                ;Umschalten auf Einzelstep
                pop     ds
                pop     ax
                ret
step            endp

int13           dd      ?            ;alter 13h Vektor
zaehler         db      ?            ;Fehlerzhler
einstep         db      ?            ;Einzelschrittflag
reset           db      ?            ;Resetflag

init:
                mov     zaehler, 2   ;Fehlerzhler laden
                mov     einstep, 0   ;kein Einzelstep
                mov     reset, 0     ;kein Reset
                mov     ah, 35h  ;lesen des alten 13h Vektors
                mov     al, 13h
                int     21h
                mov     word ptr int13, bx
                ;Offset des Vektors
                mov     word ptr int13+2, es
                ;Segment des Vektors
                mov     dx, offset newint13 ;neuer 13h Vektor
                mov     ah, 25h      ;Int 13h Vektor setzen
                mov     al, 13h
                int     21h
                mov     dx, offset ausgabe
                ;Zeichenkette ausgeben
                mov     ah, 9
                int     21h
                mov     ax, 3100h
        mov     dx, ((offset init-offset start)+10fh) shr 4
                int     21h          ;Programm resident beenden

ausgabe db 13,10,'5,25-720 KB Treiber fr 80286 und 386',13,10,'$'

code            ends
                end     start
