From 333b605b2afd472b823aeda0adf0e8b1ea9843c0 Mon Sep 17 00:00:00 2001 From: fishsoupisgood Date: Mon, 27 May 2019 02:41:51 +0100 Subject: initial commit from asl-1.41r8.tar.gz --- tests/t_secdrive/wd1003at.inc | 952 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 952 insertions(+) create mode 100644 tests/t_secdrive/wd1003at.inc (limited to 'tests/t_secdrive/wd1003at.inc') diff --git a/tests/t_secdrive/wd1003at.inc b/tests/t_secdrive/wd1003at.inc new file mode 100644 index 0000000..7714eec --- /dev/null +++ b/tests/t_secdrive/wd1003at.inc @@ -0,0 +1,952 @@ +;****************************************************************************** +;* * +;* Includedatei fr SECMAIN.ASM * +;* liefert low-level-Routinen fr SecMain * +;* Version hier fr WD1003-kompatible Kontroller: * +;* MFM, RLL, ESDI, AT-Bus * +;* * +;* Historie: 28.12.1994 herberkopiert aus Hauptmodul * +;* 30.12.1994 LowLevelIdent * +;* 19. 1.1995 Workaround fr LCS6220 * +;****************************************************************************** + + section wd1003at + +Base1 equ 170h ; Basisadresse Task-File +Base2 equ 370h ; Basisadresse Floppy-Teil +Task_Data equ Base1+0 ; Datentransferregister (R/W) +Task_Error equ Base1+1 ; genauerer Fehlercode (R) +Task_PreComp equ Base1+1 ; erster Zylinder Pr„komp. (/4, nur W) +Task_SecCnt equ Base1+2 ; Zahl zu transferierender Sektoren (R/W) +Task_SecNum equ Base1+3 ; Startsektor (R/W) +Task_CylLo equ Base1+4 ; Startzylinder Bit 0..7 (R/W) +Task_CylHi equ Base1+5 ; Startzylinder Bit 8..n (R/W) +Task_DrHead equ Base1+6 ; Laufwerk/Startkopf (R/W) +Task_Status equ Base1+7 ; Status Laufwerk & Controller (R) +Task_Command equ Base1+7 ; Kommando Controller (W) +Task_FDiskReg equ Base2+6 ; Bit 3=1: >8 K”pfe + +Cmd_Restore equ 10h ; Kommando: Rekalibrieren +Cmd_Seek equ 70h ; Kommando: Zylinder anfahren +Cmd_Read equ 20h ; Kommando: Sektoren lesen +Cmd_Write equ 30h ; Kommando: Sektoren schreiben +Cmd_Format equ 50h ; Kommando: Spur formatieren +Cmd_Verify equ 40h ; Kommando: Sektoren auf Lesbarkeit prfen +Cmd_Diagnose equ 90h ; Kommando: Selbsttest +Cmd_SetParams equ 91h ; Kommando: Laufwerksparameter setzen + + proc WriteParams + + mov [axsave],ax + mov [cxsave],cx + PrChar ' ' + mov ax,bx + mov cl,5 + call WriteDec + PrChar ' ' + mov al,byte ptr[axsave+1] + mov ah,0 + mov cl,2 + call WriteDec + PrChar ' ' + mov al,byte ptr[cxsave+1] + mov ah,0 + mov cl,2 + call WriteDec + PrChar ' ' + mov al,byte ptr[cxsave] + mov ah,0 + mov cl,2 + call WriteDec + PrChar ' ' + mov ax,es + mov cl,4 + call WriteHex + PrChar ':' + mov ax,bp + mov cl,4 + call WriteHex + mov ax,[axsave] + mov cx,[cxsave] + ret + +cxsave dw ? +axsave dw ? + + endp + +;****************************************************************************** +;* Workaround fr LCS6220: Wird direkt nach dem Einschalten ein Seek ausge- * +;* fhrt, gibt der Kontroller f„lschlicherweise Daten aus und blockiert alle * +;* weiteren Kommandos. Diese Routine r„umt einfach den Puffer leer... * +;****************************************************************************** + + proc ClearBuffer + + push dx ; Register retten + push ax + +RdLoop: mov dx,Task_Status ; Bit 3 noch gesetzt ? + in al,dx + btst al,3 + jz RdLoopEnd ; nein --> fertig + mov dx,Task_Data + in ax,dx + jmp RdLoop +RdLoopEnd: + pop ax ; Register zurck + pop dx + + ret + + endp + +;****************************************************************************** +;* Interleave-Tabelle berechnen * +;* In : AL = Sektorzahl * +;* AH = Interleave * +;* DH = Bad-Flag * +;****************************************************************************** + + proc SetInterleaveBuffer + + pusha ; Register retten + push es + + push ax ; Sektorpuffer initialisieren + mov ax,ds + mov es,ax + sub ax,ax + lea di,[SectorBuffer] + mov cx,SecSize/2 + cld + rep stosw + pop ax + + sub di,di ; DI=Adresse in Puffer=(phys. Sektor-1)*2 + mov dl,dh ; DL = Bad-Flag + mov dh,1 ; DH=log. Sektornummer + mov cl,al ; CX=Schleifenz„hler + mov ch,0 + mov bl,al ; Sektorzahl*2 nach BX + mov bh,0 + add bx,bx + mov si,ax ; Interleave*2 nach SI + shr si,8 + add si,si +InterLoop: cmp byte ptr SectorBuffer[di],0 ; Eintrag frei ? + je Inter_FreeFound ; ja, beenden + add di,2 ; nein, linear weitersuchen + cmp di,bx + jb InterLoop + mov di,0 ; Wrap-Around bercksichtigen + jmp InterLoop +Inter_FreeFound:mov word ptr SectorBuffer[di],dx ; Sektor einschreiben + add di,si ; Interleave-Sprung dazu + cmp di,bx ; Modulo Sektorzahl + jb Inter_NoWrap + sub di,bx +Inter_NoWrap: inc dh ; n„chster log. Sektor + loop InterLoop + + pop es ; Register zurck + popa + + ret + + endp + +;****************************************************************************** +;* Laufwerk und Sonderwerte einprogrammieren * +;* In : AL = Laufwerk * +;* AH = Kopf * +;****************************************************************************** + + proc SetDriveEnv + + push di ; Register retten + push dx + mov dx,ax ; Laufwerk/Kopf retten + + call GetPTabAdr ; Tabellenadresse holen + + mov al,dl ; Laufwerk und Kopf zusammenbauen + shl al,4 + or al,dh + or al,0a0h + mov dx,Task_DrHead + out dx,al + mov ax,[di+DrPar_PrComp] ; Startzylinder Pr„kompensation + shr ax,2 + mov dl,Lo(Task_PreComp) + out dx,al + mov al,[di+DrPar_CByte] ; Wert fr Fixed Disk Register + mov dx,Task_FDiskReg + out dx,al + call WaitBusy + + clc ; Ende ohne Fehler + pop dx + pop di + ret + + endp + +;****************************************************************************** +;* Zylinder- und Sektorparameter an Kontroller ausgeben * +;* In : BX = Startzylinder * +;* CL = Sektorzahl * +;* CH = Startsektor * +;****************************************************************************** + + proc SetTransParams + + push dx ; Register retten + + mov dx,Task_CylLo ; Startzylinder programmieren + mov al,bl + out dx,al + mov dx,Task_CylHi ;*** + mov al,bh + out dx,al + mov dx,Task_SecNum ; Startsektor... ;*** + mov al,ch + out dx,al + mov dx,Task_SecCnt ; ...und Sektorzahl ;*** + mov al,cl + out dx,al + + pop dx ; Register zurck + ret + + endp + +;****************************************************************************** +;* warten, bis Controller bereit oder Fehler * +;* Out : AL = letzter Status * +;****************************************************************************** + + proc WaitBusy + + push dx ; Register retten + mov dx,Task_Status ; auf Statusregister +Loop: in al,dx ; Status lesen + btst al,7 ; Bit 7 noch gesetzt ? + jnz Loop ; ja--> weiter pollen + pop dx ; Register zurck + ret + + endp + +;****************************************************************************** +;* warten, bis Laufwerk bereit * +;* Out : AL = letzter Status * +;****************************************************************************** + + proc WaitDrive + + push dx ; Register retten + mov dx,Task_Status ; auf Statusregister +Loop: in al,dx ; Status lesen + btst al,7 ; Bit 7 = 0 ? ( Controller Busy ) + jnz Loop + btst al,6 ; Bit 6 = 1 ? ( Drive not Ready ) + jz Loop + btst al,4 ; Bit 4 = 1 ? ( Seek not complete ) + jz Loop + pop dx + ret + + endp + +;****************************************************************************** +;* warten, bis Datentransfer erforderlich * +;* Out : AL = letzter Status * +;* C = 1, falls Fehler * +;****************************************************************************** + + proc WaitData + + push dx ; Register retten + mov dx,Task_Status ; auf Statusregister +Loop: in al,dx ; Status lesen + btst al,7 ; Bit 7 = 0 ? + jnz Loop + btst al,3 ; Bit 3 = 1 ? + jz Loop + pop dx ; Register zurck + ret + + endp + +;****************************************************************************** +;* Status bilden * +;* Out : C+AX = Status * +;****************************************************************************** + + proc BuildError + + push dx ; Register retten + + mov dx,Task_Status ; Statusregister lesen + in al,dx + mov ah,al + btst ah,0 ; Fehlerflag gesetzt ? + clc + jz End ; kein Fehler + + mov dx,Task_Error ; ja: Error-Register lesen ;*** + in al,dx + stc + +End: pop dx ; Register zurck + ret + + endp + +;****************************************************************************** +;* Begráungsmeldung ausgeben: * +;****************************************************************************** + + globproc LowLevelIdent + + push ax ; Register retten + + PrMsg IdentMsg + + pop ax + + ret + +IdentMsg db "Low-Level-Routinen fr WD1003-WAH und kompatible Controller",CR,LF,'$' + + endp + +;****************************************************************************** +;* Controller-Diagnose: * +;* Out : AL = Diagnosecode * +;****************************************************************************** + + globproc ContDiag + + push cx ; Register retten + push dx + + mov dx,Task_Status ; das erste Mal mit Timeout warten + sub cx,cx +BWait: in al,dx + btst al,7 ; auf NOT BUSY warten + loopnz BWait ; oder bis 64K Durchl„ufe durch + or cx,cx ; Timeout ? + jne NTOut + mov al,Diag_Timeout ; ja: Fehlercode setzen... + jmp End ; ...und Feierabend + +NTOut: mov al,CMD_Diagnose ; Selbsttest starten + mov dl,Lo(Task_Command) + out dx,al + call WaitBusy ; auf Fertigstellung warten + mov dl,Lo(Task_Error) ; Ergebnis laden + in al,dx + +End: pop dx ; Register zurck + pop cx + ret + + endp + +;****************************************************************************** +;* Dem Kontroller die Laufwerksgeometrie mitteilen * +;* In : AL = Laufwerk * +;* Out : C = 1-->Fehler * +;****************************************************************************** + + globproc SetDriveParams + + push di ; Register retten + push dx + mov dl,al ; Laufwerk retten + + call GetPTabAdr ; Adresse Parametertabelle holen + + call WaitBusy ; Kontroller muá frei sein + + mov al,dl ; Kopfzahl/Laufwerk vorbesetzen + shl al,4 + mov ah,[di+DrPar_Heads] + dec ah ; Maximalnummer anstelle Gesamtzahl + or al,ah + or al,0a0h + mov dx,Task_DrHead + out dx,al + mov dl,Lo(Task_SecCnt) ; Sektorzahl setzen + mov al,[di+DrPar_NSecs] + out dx,al + + mov dl,Lo(Task_Command) ; Parameter bertragen + mov al,Cmd_SetParams + out dx,al + + call WaitBusy ; auf Fertigstellung warten + + clc ; Ende ohne Fehler + pop dx + pop di + ret + + endp + +;****************************************************************************** +;* Laufwerk rekalibrieren, gleichzeitig Test, ob vorhanden * +;* In : AL = Laufwerk * +;* Out : C + AX = Status * +;****************************************************************************** + + globproc Recalibrate + + push cx ; Register retten + push dx + + mov cx,ax ; Laufwerk retten + call WaitBusy ; warten, bis Controller frei + + mov dx,Task_DrHead ; Laufwerk eintragen + mov al,cl + shl al,4 + add al,0a0h + out dx,al + + mov dl,Lo(Task_Status) ; Laufwerk muss jetzt bereit sein, + in al,dx ; da sich einige Kontroller sonst im + and al,50h ; folgenden aufh„ngen, falls + cmp al,50h ; keine Platte angeschlossen ist. + stc ; falls nicht bereit, Fehler simulieren + mov al,4 ; "Aborted Command" + jne TotEnde + mov al,0 + mov dl,Lo(Task_CylLo) ; erstmal auf die sanfte Tour: + out dx,al ; Spur 0 anfahren + mov dl,Lo(Task_CylHi) + out dx,al + mov dl,Lo(Task_Command) + mov al,Cmd_Seek + out dx,al + call WaitBusy + call BuildError + jnc Ende ; wenn OK: fertig + + call ClearBuffer ; falls sich der Longshine verheddert... + mov dl,Lo(Task_Command) ; 2. Anlauf: echtes Restore + mov al,Cmd_Restore + out dx,al + + call WaitBusy ; auf Controller warten + +Ende: call BuildError ; Status einlesen +TotEnde: + pop dx ; Register zurck + pop cx + ret + + endp + +;****************************************************************************** +;* Sektor(en) lesen * +;* In : AL = Laufwerk * +;* AH = Startkopf * +;* BX = Startzylinder * +;* CL = Sektorzahl * +;* CH = Startsektor * +;* ES:DI = Zeiger auf Datenpuffer * +;* Out : C+AX = Fehlerstatus * +;****************************************************************************** + + globproc ReadSectors + + push si ; Register sichern + push dx + push bp + + if debug + PrChar 'R' + mov bp,di + call WriteParams + endif + + sub bp,bp ; Fehlerz„hler auf 0 + +Retry: push ax ; Parameter sichern + push bx + push cx + push di + + mov si,ax ; Laufwerk/Kopf retten + call WaitBusy ; warten, bis Ruhe im Wald + + mov ax,si + call SetDriveEnv ; Laufwerk jetzt schon setzen, damit + ; korr. Ready-Signal abgefragt wird + call WaitDrive ; bis Laufwerk bereit + + call SetTransParams ; restliche Parameter ausgeben + + mov ch,0 ; Sektorzahl nach SI + mov si,cx + mov dx,Task_Command ; Kommando triggern + mov al,Cmd_Read + out dx,al + + mov dx,Task_Data ; Vorbereitung fr INSW + cld +Loop: call WaitBusy ; auf gelesenen Sektor warten + btst al,0 ; Fehler ? + jnz Again ; -->neu aufsetzen + call WaitData + btst al,0 + jnz Again + call WaitDrive + btst al,0 + jnz Again + mov cx,SecSize/2 ; Daten transferieren + rep insw ; bagger, schaufel + dec si ; n„chster Sektor + jnz Loop + +End: pop di ; Parameter nicht mehr gebraucht + pop cx + pop bx + pop ax +Term: if debug + PrChar CR + PrChar LF + endif + call BuildError + pop bp + pop dx + pop si + + ret + +Again: inc bp ; Fehlerz„hler rauf + cmp bp,MaxRetry ; zu oft aufgetreten ? + jae End + + pop di ; nein: Parameter vom Stack + pop cx + pop bx + pop ax + mov si,ax ; Laufwerk retten + call Recalibrate ; auf Spur 0 zurck + jc Term ; bei erneutem Fehler Abbruch + mov ax,si + call SetDriveParams ; Parameter neu initialisieren + mov ax,si + jmp Retry ; neuer Versuch + + + endp + +;****************************************************************************** +;* Sektor(en) verifizieren * +;* In : AL = Laufwerk * +;* AH = Startkopf * +;* BX = Startzylinder * +;* CL = Sektorzahl * +;* CH = Startsektor * +;* Out : C+AX = Fehlerstatus * +;****************************************************************************** + + globproc VeriSectors + + push si ; Register sichern + push dx + push bp + + if debug + PrChar 'V' + mov bp,0 + call WriteParams + endif + + sub bp,bp ; Fehlerz„hler auf 0 + +Retry: push ax ; Parameter sichern + push bx + push cx + + mov si,ax ; Laufwerk/Kopf retten + call WaitBusy ; warten, bis Ruhe im Wald + + mov ax,si + call SetDriveEnv ; Laufwerk jetzt schon setzen, damit + ; korr. Ready-Signal abgefragt wird + call WaitDrive ; bis Laufwerk bereit + + call SetTransParams ; restliche Parameter ausgeben + + mov dx,Task_Command ; Kommando triggern + mov al,Cmd_Verify + out dx,al + + call WaitBusy ; auf Fertigstellung warten + mov cx,16 ; einige Kontroller brauchen +DelStat: loop DelStat ; etwas fr das Fehlerflag + mov dx,Task_Status + in al,dx + btst al,0 ; Fehler ? + jnz Again ; -->neu aufsetzen + call WaitDrive + btst al,0 + jnz Again + +Ende: pop cx ; Parameter nicht mehr gebraucht + pop bx + pop ax +Term: if debug + PrChar CR + PrChar LF + endif + call BuildError + pop bp + pop dx + pop si + + ret + +Again: inc bp ; Fehlerz„hler rauf + cmp bp,MaxRetry ; zu oft aufgetreten ? + jae Ende + + pop cx ; nein: Parameter vom Stack + pop bx + pop ax + mov si,ax ; Laufwerk retten + call Recalibrate ; auf Spur 0 zurck + jc Term ; bei erneutem Fehler Abbruch + mov ax,si + call SetDriveParams ; Parameter neu initialisieren + mov ax,si + jmp Retry ; neuer Versuch + mov ax,si + endp + +;****************************************************************************** +;* Sektor(en) schreiben * +;* In : AL = Laufwerk * +;* AH = Startkopf * +;* BX = Startzylinder * +;* CL = Sektorzahl * +;* CH = Startsektor * +;* ES:SI = Zeiger auf Datenpuffer * +;* Out : C+AX = Fehlerstatus * +;****************************************************************************** + + globproc WriteSectors + + push di ; Register sichern + push dx + push bp + + if debug + PrChar 'W' + mov bp,si + call WriteParams + endif + + xor bp,bp ; Fehlerz„hler auf 0 + +Retry: push ax ; Parameter sichern + push bx + push cx + push si + + mov di,ax ; Laufwerk/Kopf retten + call WaitBusy ; warten, bis Ruhe im Wald + + mov ax,di + call SetDriveEnv ; Laufwerk jetzt schon setzen, damit + ; korr. Ready-Signal abgefragt wird + call WaitDrive ; bis Laufwerk bereit + + call SetTransParams ; restliche Parameter ausgeben + + mov ch,0 ; Sektorzahl nach DI + mov di,cx + mov dx,Task_Command ; Kommando triggern + mov al,Cmd_Write + out dx,al + + mov dx,Task_Data ; Vorbereitung fr OUTSW + cld +Loop: call WaitBusy ; auf Datenbereitschaft warten + btst al,0 ; Fehler ? + jnz Again ; ja-->neu aufsetzen + call WaitData + btst al,0 + jnz Again + call WaitDrive + btst al,0 + jnz Again + mov cx,SecSize/2 ; Daten transferieren + seges + rep outsw ; bagger, schaufel + call WaitBusy ; warten, bis Transfer fertig + btst al,0 + jnz Again + dec di ; n„chster Sektor + jnz Loop + +End: pop si ; Parameter nicht mehr gebraucht + pop cx + pop bx + pop ax +Term: if debug + PrChar CR + PrChar LF + endif + call BuildError + pop bp + pop dx + pop di + + ret + +Again: inc bp ; Fehlerz„hler rauf + cmp bp,MaxRetry ; zu oft aufgetreten ? + jae End + + pop si ; nein: Parameter vom Stack + pop cx + pop bx + pop ax + mov di,ax ; Laufwerk retten + call Recalibrate ; auf Spur 0 zurck + jc Term ; bei erneutem Fehler Abbruch + mov ax,di + call SetDriveParams ; Parameter neu initialisieren + mov ax,di + jmp Retry ; neuer Versuch + + endp + +;****************************************************************************** +;* Laufwerk formatieren * +;* In : AL = Laufwerk * +;* AH = Interleave * +;* Out : C+AX = Fehlerstatus * +;****************************************************************************** + + globproc FormatUnit + + push bx + push cx + push dx + push si + push di + push bp + + mov bx,ax ; Interleave retten + PrMsg ESCMsg + mov ax,bx + call GetPTabAdr ; Parametertabelle->DI + mov ax,bx + mov dh,0 ; gute Spuren schreiben + mov al,[di+DrPar_NSecs] + call SetInterleaveBuffer ; Tabelle berechnen + mov ax,bx + call Recalibrate ; Kontroller reinitialisieren + jc Fin + mov ax,bx + mov bp,[di+DrPar_Cyls] ; Zylinderz„hler in BP (abw„rts) + dec bp + mov dl,al ; Laufwerk in DL + cld +CylLoop: mov dh,0 ; Kopf in dh +HeadLoop: call WaitBusy ; warten, bis WD1003 frei + call WriteCoords ; Bildschirmausgabe + mov ax,dx ; Laufwerk+Kopf progr. + call SetDriveEnv + mov bx,bp ; Zylinder+Sektor progr. + mov cl,[di+DrPar_NSecs] + mov ch,1 + call SetTransParams + mov bx,dx + mov dx,Task_Command + mov al,Cmd_Format + out dx,al + call WaitData ; Sektortabelle schicken + mov cx,SecSize/2 + mov dx,Task_Data + lea si,[SectorBuffer] + rep outsw + call WaitBusy ; warten, bis Kontroller fertig + shr al,1 ; Fehlerbit in Carry laden + jnc GoOn + PrMsg ErrorMsg ; falls Fehler, Meldung ausgeben + mov dx,bx + call WriteCoords + PrChar LF +GoOn: mov dx,bx ; Laufwerk und Kopf zurck + call BreakOnESC ; will der Benutzer abbrechen ? + jc UserTerm ; ja, Abbruch + inc dh ; n„chster Kopf + cmp dh,[di+DrPar_Heads] + jb HeadLoop + dec bp ; n„chster Zylinder + jns CylLoop +TermLoop: mov al,dl ; damit die Seek-Rate wieder stimmt + call Recalibrate + +Fin: push ax ; Fehlerstatus halten + pushf + PrChar LF + popf ; Fehlerstatus zurck + pop ax + pop bp + pop di + pop si + pop dx + pop cx + pop bx + ret + +UserTerm: mov al,dl ; Abbruch durch Benutzer: noch schnell + call Recalibrate ; rekalibrieren + jc Fin ; Fehler dabei ? + stc ; Ansonsten Sonderfehlercode + mov al,DErr_UserTerm + jmp Fin + +WriteCoords: push ax ; Kopf/Zylinder ausgeben + push cx + + PrMsg CylMsg + mov ax,bp + mov cl,6 + call WriteDec + PrMsg HeadMsg + mov al,dh + mov ah,0 + mov cl,3 + call WriteDec + PrChar CR + + pop cx + pop ax + ret + +ESCMsg: db "Abbruch mit ",CR,LF,'$' +CylMsg: db "Zylinder $" +HeadMsg: db ", Kopf $" +ErrorMsg: db "Formatierfehler auf $" + + endp + +;****************************************************************************** +;* Spur formatieren * +;* In : AL = Laufwerk * +;* AH = Kopf * +;* BX = Zylinder * +;* CL = Interleave * +;* Out : C+AX = Fehlerstatus * +;****************************************************************************** + + globproc FormatTrack + + push bx ; Register retten + push cx + push dx + push si + push di + push bp + + mov bp,ax ; Laufwerk & Kopf retten + call Recalibrate ; Laufwerk sicherheitshalber rekalibrieren + mov ax,bp + call GetPTabAdr ; Sektortabelle aufbauen + mov dh,0 ; fehlerhafte Sektoren schreiben + mov ah,cl ; Interleave vorgeben + mov al,[di+DrPar_NSecs] + call SetInterleaveBuffer + mov ax,bp ; Laufwerk und Kopf zurck + call SetDriveEnv ; in Kontroller einprogrammieren + mov cl,[di+DrPar_NSecs] ; Sektor& Zylinder einschreiben + mov ch,1 + call SetTransParams + mov dx,Task_Command ; Kommando schicken + mov al,Cmd_Format + out dx,al + call WaitData ; Sektortabelle schicken + mov cx,SecSize/2 + mov dx,Task_Data + lea si,[SectorBuffer] + rep outsw + call WaitBusy ; warten, bis Kontroller fertig + jc Fin ; Abbruch bei Fehler + mov ax,bp ; Laufwerk nochmal rekalibrieren + call Recalibrate ; damit Steprate stimmt + +Fin: pop bp + pop di + pop si + pop dx + pop cx + pop bx + ret + + endp + +;****************************************************************************** +;* Spur als defekt markieren * +;* In : AL = Laufwerk * +;* AH = Kopf * +;* BX = Zylinder * +;* Out : C+AX = Fehlerstatus * +;****************************************************************************** + + globproc MarkBad + + push bx ; Register retten + push cx + push dx + push si + push di + push bp + + mov bp,ax ; Laufwerk & Kopf retten + call Recalibrate ; Laufwerk sicherheitshalber rekalibrieren + mov ax,bp + call GetPTabAdr ;Sektortabelle aufbauen + mov dh,80h ; fehlerhafte Sektoren schreiben + mov ah,3 ; Interleave ist ziemlich egal... + mov al,[di+DrPar_NSecs] + call SetInterleaveBuffer + mov ax,bp ; Laufwerk und Kopf zurck + call SetDriveEnv ; in Kontroller einprogrammieren + mov cl,[di+DrPar_NSecs] ; Sektor& Zylinder einschreiben + mov ch,1 + call SetTransParams + mov dx,Task_Command ; Kommando schicken + mov al,Cmd_Format + out dx,al + call WaitData ; Sektortabelle schicken + mov cx,SecSize/2 + mov dx,Task_Data + lea si,[SectorBuffer] + rep outsw + call WaitBusy ; warten, bis Kontroller fertig + jc Fin ; Abbruch bei Fehler + mov ax,bp ; Laufwerk nochmal rekalibrieren + call Recalibrate ; damit Steprate stimmt + +Fin: pop bp + pop di + pop si + pop dx + pop cx + pop bx + ret + + endp + + endsection -- cgit v1.2.3