; ; Geraetetreiber zur Anpassung von Festplattenparametern im AT ; ; Quelle: c't 3/90, S.352 ; ; muss zu einer .SYS Datei assembliert werden fuer CONFIG.SYS ; MASM-Schalter: /dConfig.sys ; ; .286 ; sowieso nur ab ATs! code segment public 'ATCODE' atdrive proc far assume cs:code, ds:code, es:code org 0 header dd -1 ; Verbindung zum naechsten ; Treiber = Ende der Liste dw 8000h ; Geraete-Attribut-Wort dw strat ; Eintrittspunkt fuer ; Strategie-Routine dw intr ; Eintrittspunkt fuer ; Interruptroutine db 'ATDSKTAB' ; Geraetetreiber-Name ; ; Doppelwort-Pointer zum Anforderungskopf ; rh_ptr dd ? ; Pointer zum Anforderungskopf ; ; Tabelle fuer nicht-standardgemaesze Drive-Parameter ; disk_drive_1: ; SEAGATE ST251-0 Disk access time=40ms cyls_1 dw 820 ; Anzahl der Zylinder heads_1 db 6 ; Anzahl der Koepfe dw 0 ; nicht benutzt wpc_1 dw 0FFFFh ; Schreib-Vorkompensation ab Zylinder db 0 ; nicht benutzt ctl_1 db 0 ; Kontrollbyte dw 0 ; nicht benutzt db 0 ; nicht benutzt land_1 dw 820 ; Parkspur sect_1 db 17 ; Sektoren pro Spur db 0 ; nicht definiert disk_drive_2: ; aktuell nicht angeschossen cyls_2 dw 000 ; Anzahl der Zylinder heads_2 db 8 ; Anzahl der Koepfe dw 0 ; nicht benutzt wpc_2 dw 00000h ; Schreib-Vorkompensation ab Zylinder db 0 ; nicht benutzt ctl_2 db 0 ; Kontrollbyte dw 0 ; nicht benutzt db 0 ; nicht benutzt land_2 dw 000 ; Parkspur sect_2 db 00 ; Sektoren pro Spur db 0 ; nicht definiert ; ; Strategie-Routine des Geraetetreibers ; strat proc far ; Adresse des Anforderungskopfes sichern mov word ptr cs:[rh_ptr],bx mov word ptr cs:[rh_ptr+2],es ret strat endp ; ; Interrupt-Routine des Geraetetreibers ; intr proc far push ax ; Sichern allgemeiner Register push bx push dx push ds push es push di push cs ; lokale Daten adressierbar machen pop ds les di,[rh_ptr] ; ES:DI jetzt = Anforderungskopf mov bl,es:[di+2] ; setze BX = Befehlscode xor bh,bh cmp bx,0 ; Initialisierungsbefehl ? je init_st mov ax,8003h ; Nein --> Fehler je init_ed init_st: call init les di,[rh_ptr] ; Anforderungskopf nach ES:DI wiederherstellen init_ed: or ax,0100h ; Flag im Statuswort auf "erledigt" setzen mov es:[di+3],ax pop di pop es pop ds pop dx pop bx pop ax ret ; ; Initialisierungsroutine ; init proc near push es ; Adresse des Anforderungskopfes sichern push di xor ax,ax ; ES auf niedrigsten Speicherbereich setzen mov es,ax mov di,41h ; Int-Nummer nach DI shl di,1 ; Multiplikation mit 4 shl di,1 mov ax,offset disk_drive_1 ; Int-Vektor fuer Drive 1 setzen cli ; Interrupts ausschalten mov es:[di],ax mov es:[di]+2,cs sti ; Interrupts wieder einschalten mov di,46h ; Interrupt-Vektor fuer Drive 2 setzen shl di,1 shl di,1 mov ax,offset disk_drive_2 ; Int-Vektor fuer Drive 2 setzen cli ; Interrupts ausschalten mov es:[di],ax mov es:[di]+2,cs sti ; Interrupts wieder einschalten mov ah,9 ; Nachricht ausgeben mov dx,offset ident int 21h pop di ; Adresse des Fuehrungskopfes wiederherstellen pop es mov word ptr es:[di+14],offset init mov word ptr es:[di+16],cs xor ax,ax ret init endp cr equ 0Dh lf equ 0Ah eom equ '$' ident db cr,lf db 'AT Nonstandard Disk Drive Table Installed' db cr,lf,eom intr endp atdrive endp code ends end