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/secparam.inc | 1619 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1619 insertions(+) create mode 100644 tests/t_secdrive/secparam.inc (limited to 'tests/t_secdrive/secparam.inc') diff --git a/tests/t_secdrive/secparam.inc b/tests/t_secdrive/secparam.inc new file mode 100644 index 0000000..8bf8381 --- /dev/null +++ b/tests/t_secdrive/secparam.inc @@ -0,0 +1,1619 @@ +;***************************************************************************** +;* Sekund„rlaufwerkstreiber, Modul SecParam * +;* liefert Laufwerksparameter, falls fehlend im Bootsektor * +;* stellt das ganze Formatiermen zur Verfgung * +;***************************************************************************** + + section SecParam + +;***************************************************************************** +;* gemeinsam benutzte Meldungen * +;***************************************************************************** + +TrackMsg db "Spur (0..Spurzahl-1) : $" +HeadMsg db "Kopf (0..Kopfzahl-1) : $" +ConfirmMsg db "Sind Sie sicher ?$" +InterleaveMsg db "Interleave (1..Sektorzahl-1) : $" + +;***************************************************************************** +;* Routine BreakOnESC * +;* schaut nach, ob ESC gedrckt wurde * +;* Ausgabe: C=1, falls ja * +;***************************************************************************** + + GlobProc BreakOnESC + + push ax ; Register retten + mov ah,1 ; Tastaturpuffer antesten + int INT_Keyboard + clc ; Annahme nicht gedrckt + jz Ende + mov ah,0 ; Zeichen da: dies abholen + int INT_Keyboard + cmp al,ESC ; ist es ESC ? + clc ; Annahme nein + jne Ende + stc ; jawoll! +Ende: pop ax ; Register zurck + ret + + endp + +;***************************************************************************** +;* Routine YesNo * +;* fragt nach Ja oder Nein * +;* Ausgabe: C=0, falls ja * +;***************************************************************************** + + proc YesNo + + push ax ; Register retten + +QueryLoop: mov ah,DOS_RdChar ; ein Zeichen lesen + int INT_DOS + + cmp al,'a' ; Kleinbuchstaben ? + jb Upper + cmp al,'z' + ja Upper + add al,'A' + sub al,'a' +Upper: + cmp al,'J' ; akzeptierte Zeichen fr Ja + clc + je YNDone + cmp al,'Y' + clc + je YNDone + cmp al,'N' ; akzeptierte Zeichen fr Nein + stc + je YNDone + + PrChar BEL ; alles andere anmeckern + jmp QueryLoop + +YNDone: PrChar al ; Zeichen als Echo ausgeben + PrChar CR ; Zeilenvorschub + PrChar LF + pop ax ; Register zurck + + ret + + endp + +;***************************************************************************** +;* Routine ReadNumber * +;* liest einen Wert von 0..n in AX ein * +;* Eingabe: AX = Maximalwert * +;* DI = Zeiger auf Meldung * +;* Ausgabe: AX = eingelesene Zahl * +;***************************************************************************** + + proc ReadNumber + + push bx ; Register retten + push cx + push dx + push si + + mov si,ax ; Maximalwert retten +InLoop: mov dx,di ; Meldung ausgeben + mov ah,DOS_WrString + int INT_DOS + lea dx,[KeyBuffer] ; Zahl als String einlesen + mov ah,DOS_RdString + int INT_DOS + PrChar CR + PrChar LF + mov ax,0 ; jetzt Zeichen verarbeiten + mov cl,[KeyBuffer+1] + mov ch,0 + lea bx,[KeyBuffer+2] + jcxz InvFormat ; Nullschleife abfangen +ConvLoop: mov dx,10 ; bisheriges Ergebnis hochmultiplizieren + mul dx + mov dl,[bx] ; ein Zeichen holen + inc bx + sub dl,'0' ; ASCII-Offset abziehen + jc InvFormat ; bei Formatfehler abbrechen + cmp dl,9 ; nur 0..9 erlaubt + ja InvFormat + add al,dl ; dazuaddieren + adc ah,0 + loop ConvLoop + jmp ChkRange ; fertig: weiter zur Bereichsprfung +InvFormat: PrMsg InvMsg ; wenn fehlerhaft, meckern + jmp InLoop ; und nochmal versuchen +ChkRange: cmp ax,si ; auáerhalb Bereich ? + jbe OK + PrMsg OverMsg ; ja: meckern... + jmp InLoop ; ...und auf ein neues + +OK: pop si ; Register zurck + pop dx + pop cx + pop bx + + ret + +KeyBufferLen equ 30 ; 30 Zeichen sollten fr Zahlen reichen... +KeyBuffer db KeyBufferLen ; Maimall„nge fr DOS + db 0 ; effektive L„nge Eingabe + db KeyBufferLen dup (0) ; Platz fr Eingabe +InvMsg db "Ungltiges Zahlenformat",CR,LF,'$' +OverMsg db "Bereichsberschreitung",CR,LF,'$' + + endp + +;****************************************************************************** +;* eine Anzahl Leerzeichen ausgeben * +;* In : CX = Anzahl * +;****************************************************************************** + + globproc WriteSpc + + push dx ; Register retten + + jcxz NULL ; Nullschleife abfangen +Loop: mov ah,DOS_WrChar + mov dl,' ' + int INT_DOS + loop Loop + +NULL: pop dx ; Register zurck + ret + + endp + +;****************************************************************************** +;* vorzeichenlose Zahl dezimal ausgeben * +;* In : AX = Zahl * +;* CL = min. Stellenzahl * +;****************************************************************************** + + globproc WriteDec + + push di ; Register retten + push cx + push dx + + mov ch,0 ; CH z„hlt effektive Zeichenzahl +InLoop: sub dx,dx ; Stellendivision + mov di,10 ; gewnschtes Zahlensystem + div di + mov di,ax ; war es vorher 0 ? + or di,dx ; (wenn Quotient & Rest 0) + jnz NZero ; nein-->normal ausgeben + or ch,ch ; noch erste Stelle ? + jz NZero ; dann auf jeden Fall 0 ausgeben + mov dl,0f0h ; ansonsten Leerzeichen fr leading 0 +NZero: push dx ; Zeichen speichern... + inc ch ; ...und mitz„hlen + cmp ch,cl ; Mindestzahl ausgegeben ? + jb InLoop ; nein-->weiter + or ax,ax ; ansonsten: 0 ? + jnz InLoop ; nein, weitermachen + + shr cx,8 ; effektive Zahl nach CX +OLoop: pop dx ; ein Zeichen runterholen + add dl,'0' ; in ASCII konvertieren + mov ah,DOS_WrChar ; ber DOS ausgeben + int INT_DOS + loop OLoop + + pop dx + pop cx + pop di ; Register zurck + ret + + endp + +;****************************************************************************** +;* vorzeichenlose Zahl hexadezimal ausgeben * +;* In : AX = Zahl * +;* CL = min. Stellenzahl * +;****************************************************************************** + + globproc WriteHex + + push di ; Register retten + push cx + push dx + + mov ch,0 ; CH z„hlt effektive Zeichenzahl +InLoop: sub dx,dx ; Stellendivision + mov di,16 ; gewnschtes Zahlensystem + div di + mov di,ax ; war es vorher 0 ? + or di,dx ; (wenn Quotient & Rest 0) + jnz NZero ; nein-->normal ausgeben + or ch,ch ; noch erste Stelle ? + jz NZero ; dann auf jeden Fall 0 ausgeben + mov dl,0f0h ; ansonsten Leerzeichen fr leading 0 +NZero: push dx ; Zeichen speichern... + inc ch ; ...und mitz„hlen + cmp ch,cl ; Mindestzahl ausgegeben ? + jb InLoop ; nein-->weiter + or ax,ax ; ansonsten: 0 ? + jnz InLoop ; nein, weitermachen + + shr cx,8 ; effektive Zahl nach CX +OLoop: pop dx ; ein Zeichen runterholen + add dl,'0' ; in ASCII konvertieren + cmp dl,'9' + jbe NoHex + add dl,7 +NoHex: mov ah,DOS_WrChar ; ber DOS ausgeben + int INT_DOS + loop OLoop + + pop dx + pop cx + pop di ; Register zurck + ret + + endp + +;***************************************************************************** +;* Routine GeometryDefined - stellt fest, ob Geometrie fr ei Laufwerk defi- * +;* niert ist * +;* Eingabe: AL = Laufwerksnummer * +;* Ausgabe: C = 0, falls OK * +;***************************************************************************** + + proc GeometryDefined + + push di ; Register retten + call GetPTabAdr ; Tabellenadresse bilden + cmp word ptr[di+DrPar_Cyls],0 ; Zylinderzahl 0 ? + stc + je Fin + cmp byte ptr[di+DrPar_Heads],0 ; Kopfzahl 0 ? + stc + je Fin + cmp byte ptr[di+DrPar_NSecs],0 ; Sektorzahl 0 ? + stc + je Fin + clc ; alles OK +Fin: pop di ; Register zurck + ret + + endp + +;***************************************************************************** +;* Routine QueryRedefine - fragt nach, ob Geometrie neu definert werden soll * +;* Eingabe: AL = Laufwerk * +;* Ausgabe: C = 0, falls ja * +;***************************************************************************** + + proc QueryRedefine + + add al,'1' ; Laufwerksnummer in ASCII umrechnen + mov [UndefMsg2],al ; in Meldung einschreiben + PrMsg UndefMsg + PrMsg DoQueryMsg ; nachfragen, ob Definition erwnscht + call YesNo + ret + +UndefMsg db "Geometrie fr Laufwerk " +UndefMsg2 db " undefiniert.",CR,LF,"$" +DoQueryMsg db "Geometrie neu definieren ? $" + + endp + +;***************************************************************************** +;* Routine ReadGeomety - liest Laufwerksgeometrie vom Benutzer ein * +;* Eingabe: AL = phys. Laufwerksnummer * +;***************************************************************************** + + proc ReadGeometry + + push ax ; Register retten + push si + push di + + call GetPTabAdr ; Zeiger auf Parametertabelle holen + mov si,di + + lea di,[CylInpMsg] ; Zylinderzahl erfragen + mov ax,1024 + call ReadNumber + mov [si+DrPar_Cyls],ax + + lea di,[HeadInpMsg] ; Kopfzahl erfragen + mov ax,16 + call ReadNumber + mov [si+DrPar_Heads],al + + lea di,[RWCInpMsg] ; RWC-Zylinder erfragen + mov ax,65535 + call ReadNumber + mov [si+DrPar_RedWr],ax + + lea di,[PreInpMsg] ; Pr„kompensations-Zylinder erfragen + mov ax,65535 + call ReadNumber + mov [si+DrPar_PrComp],ax + + lea di,[ECCInpMsg] ; ECC-L„nge erfragen + mov ax,11 + call ReadNumber + mov [si+DrPar_ECCLen],ax + + mov al,[si+DrPar_Heads] ; Steuerbyte Bit 3=1, falls Platte + dec al + and al,8 ; mehr als 8 K”pfe hat + mov [si+DrPar_CByte],al + + mov al,0 ; Timeouts unbenutzt + mov [si+DrPar_TOut],al + mov [si+DrPar_FTOut],al + mov [si+DrPar_CTOut],al + + mov ax,[si+DrPar_Cyls] ; Parkzylinder=Zylinderzahl+1 + inc ax + mov [si+DrPar_LZone],ax + + lea di,[SecInpMsg] ; Sektorzahl erfragen + mov ax,255 + call ReadNumber + mov [si+DrPar_NSecs],al + + pop di ; Register zurck + pop si + pop ax + ret + +CylInpMsg db "Anzahl Zylinder (max. 1024) : $" +HeadInpMsg db "Anzahl K”pfe (max. 16) : $" +RWCInpMsg db "Startzylinder fr reduzierten Schreibstrom (max. 65535) : $" +PreInpMsg db "Startzylinder fr Pr„kompensation (max. 65535) : $" +ECCInpMsg db "max. ECC-Fehlerburstl„nge (5 oder 11) : $" +SecInpMsg db "Sektorzahl (max. 255) : $" + + endp + +;***************************************************************************** +;* Routine WriteGeoToDisk - schreibt Laufwerksgeometrie auf Platte * +;* Eingabe: AL = phys. Laufwerksnummer * +;* Ausgabe: C+AX = Fehlerstatus * +;***************************************************************************** + + proc WriteGeoToDisk + + push bx ; Register retten + push cx + push dx + push si + push di + push es + + mov dx,ds ; alles im folgenden im Datensegment + mov es,dx + + mov dl,al ; Laufwerksnummer retten + mov ah,0 ; Kopf 0, + sub bx,bx ; Spur 0, + mov cx,0101h ; Sektor 1 lesen + lea di,[SectorBuffer] + call ReadSectors + jc GeoError ; Abbruch bei Fehler + + mov al,dl ; Geometrietabelle adressieren + call GetPTabAdr + mov si,di ; selbige in MBR einschreiben + lea di,[SectorBuffer+DrPar_Offset] + mov cx,DrPar_Len/2 + cld + rep movsw + + mov al,dl ; jetzt den ganzen Kram zurckschreiben + mov ah,0 + sub bx,bx + mov cx,0101h + lea si,[SectorBuffer] + call WriteSectors + jc GeoError + +Fin: pop es ; Register zurck + pop di + pop si + pop dx + pop cx + pop bx + ret + +GeoError: mov ah,bl ; Fehlerausgabe + call WrErrorCode + jmp Fin + + endp + +;***************************************************************************** +;* Routine QueryParams * +;* Eingabe: AL = Laufwerksnummer * +;* AH = 1, falls Rckschreiben erlaubt * +;* Ausgabe: AL = 0: Laufwerk vergessen * +;* AL = 1: Mastersektor neu lesen * +;* AL = 2: Tabelle nur transient eingetragen, kein Neulesen * +;***************************************************************************** + + globproc QueryParams + + push bx ; Register retten + push cx + push dx + push si + push di + push es + + mov bx,ax ; Laufwerksnummer retten + call QueryRedefine ; nachfragen, ob Neudefinition erwnscht + mov al,0 ; Abbruch bei Nein + ljc Terminate + + mov al,bl ; Geometrie einlesen + call ReadGeometry + + shr bh,1 ; Rckschreiben erlaubt ? + cmc ; C=1-->verboten + jc NoWriteBack + + PrMsg WriteBackMsg ; nachfragen, ob Rckschreiben erwnscht + call YesNo +NoWriteBack: mov al,2 ; Neulesen bei Nein verhindern + jc Terminate + + mov al,bl + call WriteGeoToDisk + jc WrError + + mov al,1 ; Ergebnis: MBR-Lesen wiederholen + jmp Terminate +WrError: mov al,0 ; Schreibfehler: Laufwerk ignorieren + +Terminate: pop es ; Register zurck + pop di + pop si + pop dx + pop cx + pop bx + + ret + +WriteBackMsg db "Parametersatz zurckschreiben ? $" + + endp + +;**************************************************************************** +;* Laufwerksnummer einlesen * +;* Ausgabe: AL = Laufwerksnummer * +;**************************************************************************** + + proc InputDrive + + push dx ; Register retten + +RdLoop: PrMsg PromptMsg ; Anfrage ausgeben + mov ah,DOS_RdChar ; ein Zeichen holen + int INT_DOS + mov dl,al ; Zeichen retten + PrChar dl ; Laufwerk als Echo zurckgeben + PrChar CR + PrChar LF + sub dl,'1' ; nur 1 oder 2 erlaubt + jc RdLoop + cmp dl,MaxPDrives + jae RdLoop + mov al,dl ; Laufwerk in AL zurckgeben + + pop dx ; Register zurck + ret + +PromptMsg db "Laufwerksnummer (1 oder 2) : $" + + endp + +;**************************************************************************** +;* Men fr Plattenfunktionen * +;**************************************************************************** + + proc SelectDisk + + push ax ; Register sichern + push bx + push cx + push dx + push si + push di + push es + + mov dh,ah ; Rckschreibeflag sichern + call InputDrive + mov dl,al ; Laufwerksnummer sichern + + mov al,dl ; Geometrie noch undefiniert ? + call GeometryDefined + jnc IsOK ; Nein, alles in Butter + + mov al,dl ; nicht definiert: versuchen, + mov ah,0 ; Geometrie vom MBR zu lesen + mov bx,ds + mov es,bx + sub bx,bx + mov cx,0101h + lea di,[SectorBuffer] + call ReadSectors + jnc CopyTable ; kein Fehler->Tabelle auslesen + mov dh,0 ; wenn Fehler, nie zurckschreiben + jmp ReadManual ; und manuell probieren +CopyTable: lea si,[SectorBuffer+DrPar_Offset] + mov al,dl + call GetPTabAdr + mov cx,DrPar_Len/2 + cld + rep movsw + mov al,dl ; Geometrie jetzt da ? + call GeometryDefined + jnc IsOK ; falls ja, Ende + +ReadManual: mov al,dl ; fragen, ob Redefinition erwnscht + call QueryRedefine + jc NotOK ; falls nein, Abbruch + mov al,dl ; ansonsten einlesen + call ReadGeometry + shr dh,1 ; zurckschreiben ? + jnc IsOK + mov al,dl ; ja... + call WriteGeoToDisk ; Fehler ignorieren + +IsOK: mov [MomDrive],dl ; Laufwerk akzeptiert + +NotOK: pop es ; Register zurck + pop di + pop si + pop dx + pop cx + pop bx + pop ax + + ret + + endp + +;---------------------------------------------------------------------------- + + proc ChangeGeometry + + cmp [MomDrive],-1 ; Laufwerk berhaupt schon definiert ? + jne DriveDefined + call InputDrive ; nein: lesen & einschreiben + mov [MomDrive],al +DriveDefined: mov al,[MomDrive] ; neue Geometrie einlesen + call ReadGeometry + mov al,[MomDrive] + call WriteGeoToDisk ; die auch gleich zu schreiben versuchen + + ret + + endp + +;---------------------------------------------------------------------------- + + proc VerifyDisk + + pusha ; restlos alles... + + mov al,[MomDrive] ; erstmal sicherstellen, daá der + call SetDriveParams ; Kontroller die Geometrie kennt + + mov al,[MomDrive] ; die Geometrie brauchen wir auch + call GetPTabAdr + + PrMsg ESCMsg + sub bp,bp ; Fehlerz„hler + mov si,bp ; Zylinderz„hler + mov dx,bp ; Folgefehlerz„hler +CylLoop: mov dl,0 ; Kopfz„hler +HeadLoop: PrMsg CylMsg ; zu testende Spur ausgeben + mov ax,si + mov cl,4 + call WriteDec + PrMsg HeadMsg + mov al,dl + mov ah,0 + mov cl,2 + call WriteDec + PrChar CR + + mov al,[MomDrive] ; eine Spur testen + mov ah,dl + mov bx,si + mov cl,[di+DrPar_NSecs] + mov ch,1 + call VeriSectors + + jnc NoError ; evtl. Fehlerbehandlung + push ax + PrChar LF + pop ax + mov ah,[MomDrive] + call WrErrorCode + inc bp ; Fehlerz„hler rauf + inc dh + test dh,7 ; alle 8 Fehler in Reihe nachfragen + jnz NextTrack + PrMsg GoOnMsg + call YesNo + jc Terminate + jmp NextTrack +NoError: mov dh,0 ; eine Spur gut->Folgenz„hler l”schen +NextTrack: call BreakONESC ; Abbruch ? + jc Terminate + inc dl ; n„chster Kopf + cmp dl,[di+DrPar_Heads] + jb HeadLoop + inc si ; n„chster Zylinder + cmp si,[di+DrPar_Cyls] + ljb CylLoop + +Terminate: mov ax,bp ; Fehlerzahl ausgeben + mov cl,5 + call WriteDec + PrMsg ErrorMsg + + popa ; Register zurck + + ret + +EscMsg db "Verifizieren..",CR,LF,"Abbruch mit ",CR,LF,'$' +CylMsg db "Zylinder $" +HeadMsg db ", Kopf $" +GoOnMsg db "Test fortsetzen? $" +ErrorMsg: db " Fehler gefunden ",CR,LF,'$' + + endp + +;---------------------------------------------------------------------------- + + proc FormatDisk + + push ax ; Register retten + push bx + push cx + push di + push es + + mov al,[MomDrive] ; erstmal sicherstellen, daá der + call SetDriveParams ; Kontroller die Geometrie kennt + + mov al,[MomDrive] + call GetPTabAdr +InterLoop: mov al,[di+DrPar_NSecs] ; Maximum=Sektorzahl-1 + dec al + mov ah,0 + lea di,[InterleaveMsg] ; Interleave erfragen + call ReadNumber + or ax,ax ; Null wollen wir nicht + jz InterLoop + mov bl,al ; Interleave retten + PrMsg ConfirmMsg ; sicherheitshalber nachfragen + call YesNo + jc Fin + PrMsg NewLine + PrMsg FormatMsg + mov ah,bl ; Interleave zurck + mov al,[MomDrive] + call FormatUnit + jc FormatError ; Fehler beim Formatieren ? + +NoFormatError: PrMsg WriteMsg + lea di,[SectorBuffer] ; MBR erzeugen + cld + mov cx,SecSize/2-1 ; letztes Wort anders! + mov ax,ds + mov es,ax + sub ax,ax ; prinzipiell erstmal alles Nullen + rep stosw + mov word ptr[di],0aa55h ; Gltigkeitsflag am Ende + mov al,[MomDrive] ; Geometrietabelle eintragen + call GetPTabAdr + mov si,di + lea di,[SectorBuffer+DrPar_Offset] + mov cx,DrPar_Len/2 + rep movsw + mov al,[MomDrive] ; Sektor schreiben + mov ah,0 ; MBR auf Kopf 0, + mov bx,0 ; Spur 0, + mov cx,0101h ; Sektor 1 + lea si,[SectorBuffer] + call WriteSectors + jc FormatError ; Fehler beim Schreiben ? + +Fin: pop es ; Register zurck + pop di + pop cx + pop bx + pop ax + ret + +FormatError: cmp al,DErr_UserTerm ; Abbruch durch Benutzer ? + je Fin ; dann nicht meckern + push ax ; Fehlercode retten + pushf + PrMsg NewLine + popf + pop ax + mov ah,[MomDrive] ; Fehlermeldung ausgeben + call WrErrorCode + jmp Fin + +FormatMsg db "Formatieren...",CR,LF,'$' +WriteMsg db "MBR schreiben...",CR,LF,'$' + + endp + +;---------------------------------------------------------------------------- + + proc BadTrack + + push bx + push si + push di + + mov al,[MomDrive] ; Zeiger auf Geometrietabelle + call GetPTabAdr ; holen + mov si,di + + lea di,[TrackMsg] ; Spurnummer abfragen + mov ax,[si+DrPar_Cyls] + dec ax + call ReadNumber + mov bx,ax + lea di,[HeadMsg] ; Kopfnummer abfragen + mov ax,[si+DrPar_Heads] + dec ax + call ReadNumber + mov ah,al + push ax ; sicherheitshalber noch best„tigen + PrMsg ConfirmMsg + call YesNo + pop ax + jc NoError + mov al,[MomDrive] ; Spur markieren + call MarkBad + jnc NoError + push ax ; Fehlercode retten + pushf + PrMsg NewLine + popf + pop ax + mov ah,[MomDrive] + call WrErrorCode +NoError: + pop di + pop si + pop bx + + ret + + endp + +;---------------------------------------------------------------------------- + + proc FormTrack + + push bx + push si + push di + + mov al,[MomDrive] ; Zeiger auf Geometrietabelle + call GetPTabAdr ; holen + mov si,di + + lea di,[TrackMsg] ; Spurnummer abfragen + mov ax,[si+DrPar_Cyls] + dec ax + call ReadNumber + mov bx,ax + lea di,[HeadMsg] ; Kopfnummer abfragen + mov ax,[si+DrPar_Heads] + dec ax + call ReadNumber + mov ah,al + push ax ; Kopf retten +InterLoop: mov al,[si+DrPar_NSecs] ; Interleave-Maximum=Sektorzahl-1 + dec al + mov ah,0 + lea di,[InterleaveMsg] ; Interleave erfragen + call ReadNumber + or ax,ax ; Null wollen wir nicht + jz InterLoop + mov cl,al ; Interleave passend ablegen + PrMsg ConfirmMsg ; nochmal nachfragen + call YesNo + pop ax + jc NoError + mov al,[MomDrive] ; Kopf zurck + call FormatTrack + jnc NoError + push ax ; Fehlercode retten + pushf + PrMsg NewLine + popf + pop ax + mov ah,[MomDrive] + call WrErrorCode +NoError: + pop di + pop si + pop bx + + ret + + endp + +;---------------------------------------------------------------------------- + +; packt eine Sektorkoordinate ins BIOS-Format +; -->Zylinder=BX, Kopf=AH, Sektor=AL +; <--Zylinder/Sektor=BX, Kopf=AH + + proc PackCoordinate + + shl bh,6 + or bh,al + xchg bl,bh + ret + + endp + + proc UnpackCoordinate + + xchg bh,bl ; Zylinderbytes in richtige Reihenfolge + mov al,bh ; Sektor ausmaskieren + and al,00111111b + shr bh,6 ; Zylinder korrigieren + + ret + + endp + +; berechnet aus einer Sektorkoordinate die lineare Sektornummer +; -->Zylinder/Sektor=BX, Kopf=AH, Geometriezeiger=SI +; <--Sektornummer=DX/AX + + proc LinearizeCoordinate + + push bx + push cx + + mov cx,ax ; Kopf retten + mov al,bh ; Zylinder rekonstruieren + mov ah,bl + shr ah,6 + mov dl,[si+DrPar_Heads] + mov dh,0 + mul dx ; = Anzahl Spuren bis Zylinderbeginn + add al,ch ; Startkopf dazuaddieren + adc ah,0 ; bisher hoffentlich nur 16 Bit... + mov dl,[si+DrPar_NSecs] + mov dh,0 + mul dx ; = Anzahl Spuren bis Spurbeginn + and bl,3fh ; letztendlich Sektor-1 dazu + dec bl + add al,bl + adc ah,0 + adc dx,0 + + pop cx + pop bx + + ret + + endp + + proc MakePart + + push bx + push cx + push dx + push si + push di + push es + + PrMsg ConfirmMsg ; sind wir sicher ? + call YesNo + ljc End + + mov al,[MomDrive] ; Laufwerk rekalibrieren + call Recalibrate + ljc PartError + + mov al,[MomDrive] ; alten MBR auslesen + mov ah,0 + mov bx,0 + mov cx,0101h + mov si,ds + mov es,si + lea di,[SectorBuffer] + call ReadSectors + ljc PartError + + mov al,[MomDrive] ; Plattengeometrie holen + call GetPTabAdr + mov si,di + + lea di,[SectorBuffer+ParTab_Offset] ; an erste Tabelle schreiben + mov byte ptr [di+ParTab_BFlag],80h ; Partition aktiv + cmp byte ptr[si+DrPar_Heads],1 ; nur ein Kopf ? + ja MoreHeads + mov bx,1 ; ja: Start auf Zyl. 1, Kopf 0 + mov ah,0 + jmp WriteStart +MoreHeads: sub bx,bx ; nein: Start auf Zyl. 0, Kopf 1 + mov ah,1 +WriteStart: mov al,01h ; Startsektor immer 1 + call PackCoordinate + mov [di+ParTab_FHead],ah + mov [di+ParTab_FSecCyl],bx + call LinearizeCoordinate ; linearen Start schreiben + mov [di+ParTab_LinSec],ax + mov [di+ParTab_LinSec+2],dx + push dx + push ax + mov bx,[si+DrPar_Cyls] ; Ende: Zylinder n-2, Kopf n-1, Sektor n + sub bx,2 + mov ah,[si+DrPar_Heads] + dec ah + mov al,[si+DrPar_NSecs] + call PackCoordinate + mov [di+ParTab_LHead],ah + mov [di+ParTab_LSecCyl],bx + call LinearizeCoordinate ; Sektorzahl berechnen + pop bx ; dazu Start abziehen + sub ax,bx + pop bx + sbb dx,bx + add ax,1 ; !!! L„nge=Stop-Start+1 + adc dx,0 + mov [di+ParTab_NSecs],ax + mov [di+ParTab_NSecs+2],dx + or dx,dx ; falls >64K Sektoren, + jz NoBigDOS ; eine BigDOS-Partition + mov bl,6 + jmp TypeFound +NoBigDOS: cmp ax,32679 ; ab 32680 Sektoren 16-Bit-FAT + jb NoFAT16 + mov bl,04 + jmp TypeFound +NoFAT16: mov bl,1 ; kleine 12-Bit-Partition +TypeFound: mov [di+ParTab_Type],bl + add di,ParTab_Len ; die anderen 3 Partitionen l”schen + mov cx,3*(ParTab_Len/2) + sub ax,ax + cld + rep stosw + + mov al,[MomDrive] ; neuen MBR schreiben + mov ah,0 + mov bx,0 + mov cx,0101h + lea si,[SectorBuffer] + call WriteSectors + ljc PartError + +End: pop es + pop di + pop si + pop dx + pop cx + pop bx + + ret + +PartError: push ax ; Fehlercode retten + pushf + PrMsg NewLine + popf + pop ax + mov ah,[MomDrive] ; Fehlermeldung ausgeben + call WrErrorCode + jmp End + +ConfirmMsg: db "ACHTUNG! Alle bisherigen Partitionen auf der",CR,LF + db "Festplatte werden gel”scht! Fortfahren? $" + + endp + +;---------------------------------------------------------------------------- + + proc FormatPart + + pusha + + mov ax,ds ; wir arbeiten nur im Datensegment + mov es,ax + + PrMsg ConfirmMsg ; vorher nachfragen + call YesNo + ljc Ende + + mov al,[MomDrive] ; Laufwerk rekalibrieren + call Recalibrate + ljc LFormError + +; Schritt 1: MBR lesen + + mov al,[MomDrive] ; MBR auslesen, um Partitions- + mov ah,0 ; daten zu bekommen + mov bx,0 + mov cx,0101h + lea di,[SectorBuffer] + call ReadSectors + ljc LFormError + +; Schritt 2: Partitionsdaten in BPB kopieren + + lea di,[SectorBuffer+ParTab_Offset] ; auf Partitionsdaten + mov al,[di+ParTab_Type] ; muá prim„re Partition sein + cmp al,1 ; DOS 2.x FAT12? + je ParTypeOK + cmp al,4 ; DOS 3.x FAT16? + je ParTypeOK + cmp al,6 ; DOS 4.x BIGDOS? + je ParTypeOK + PrMsg InvParTypeMsg ; nichts dergleichen: Abbruch + jmp Ende +ParTypeOK: mov word ptr[BPB_SysID],'AF' ; FAT-Kennung in BPB eintragen + mov word ptr[BPB_SysID+2],'1T' ; FAT12/FAT16 + mov word ptr[BPB_SysID+5],' ' + mov ah,'2' ; Annahme FAT12 + cmp al,1 + je ParIsFAT12 ; wenn Typ=1, OK + mov ah,'6' ; ansonsten FAT16 +ParIsFAT12: mov byte ptr[BPB_SysID+4],ah + mov ax,[di+ParTab_NSecs] ; Sektorzahl in BPB schreiben + mov dx,[di+ParTab_NSecs+2] + mov word ptr[BPB_NumSecs32],ax + mov word ptr[BPB_NumSecs32+2],dx + or dx,dx ; falls < 64K Sektoren, + jz ParIsNotBig ; Gr”áe auch unten eintragen, + sub ax,ax ; ansonsten 0 +ParIsNotBig: mov [BPB_NumSecs16],ax + mov ax,word ptr[di+ParTab_LinSec] ; Startsektor umkopieren + mov dx,word ptr[di+ParTab_LinSec+2] + mov word ptr[BPB_LinStart],ax + mov word ptr[BPB_LinStart+2],dx + +; Schritt 3: Partitionsdaten in Partitionstabelle kopieren, damit wir die +; linearen Schreib/Lesefunktionen nutzen k”nnen + + mov [DrCnt],1 ; nur ein Laufwerk belegt + mov ah,[di+ParTab_FHead] ; Startkoordinate ablegen + mov bx,[di+ParTab_FSecCyl] + call UnpackCoordinate + mov [DrTab+DrTab_StartHead],ah + mov word ptr [DrTab+DrTab_StartCyl],bx + mov [DrTab+DrTab_StartSec],al + mov ax,[di+ParTab_LinSec] + mov word ptr [DrTab+DrTab_LinStart],ax + mov ax,[di+ParTab_LinSec+2] + mov word ptr [DrTab+DrTab_LinStart+2],ax + mov ax,[di+ParTab_NSecs] + mov word ptr [DrTab+DrTab_SecCnt],ax + mov ax,[di+ParTab_NSecs+2] + mov word ptr [DrTab+DrTab_SecCnt+2],ax + mov al,[MomDrive] ; Laufwerk einschreiben + mov [DrTab+DrTab_Drive],al + mov byte ptr[DrTab+DrTab_BPB],0 ; kein BPB + +; Schritt 4: konstante Felder in BPB eintragen + + mov [BPB_SecSize],SecSize ; Sektorgr”áe konstant 512 Byte + mov [BPB_ResvdSecs],1 ; nur Bootsektor reserviert + mov [BPB_NumFATs],2 ; 2 FATs ist DOS-Standard + mov [BPB_MediaID],0f8h ; Media-Byte fr Platten konstant + mov al,[MomDrive] + call GetPTabAdr + mov ah,0 + mov al,[di+DrPar_NSecs]; Plattenzylinder und -k”pfe + mov [BPB_SecsPerTrk],ax + mov al,[di+DrPar_Heads] + mov [BPB_Heads],ax + mov al,[MomDrive] ; Plattennummer+80h + add al,80h + mov [BPB_PhysNo],ax + mov [BPB_ExtID],29h ; Erkennung, daá erw. BPB gltig + mov ah,0 ; Seriennummer=Uhrzeit + int INT_Clock + mov word ptr[BPB_SerialNo],cx + mov word ptr[BPB_SerialNo+2],dx + lea di,[BPB_Name] ; Name ist leer + mov cx,11 + mov al,' ' + cld + rep stosb + +; Schritt 5: einige Sachen vom Anwender erfragen + +DirEntLoop: mov ax,1024 ; mehr ist wohl kaum sinnvoll + lea di,[DirEntriesMsg] + call ReadNumber + cmp ax,SecSize/32 ; weniger als ein Sektor ergibt + jb DirEntLoop ; keinen Sinn + mov [BPB_DirLen],ax ; Anzahl in BPB eintragen + mov dx,0 ; Directory-Sektorzahl berechnen + mov bx,SecSize/32 + div bx + or dx,dx ; ggfs. aufrunden + jz DirLenEven + inc ax +DirLenEven: mov [DirLen],ax + +; Schritt 6: Clusterl„nge berechnen + + mov ax,word ptr[BPB_NumSecs32] ; # Sektoren in Datenfeld + mov dx,word ptr[BPB_NumSecs32+2] ; und FATs berechnen + sub ax,[BPB_ResvdSecs] + sbb dx,0 + sub ax,[DirLen] + sbb dx,0 + mov bl,1 ; Annahme: m”glichst wenig Sektoren pro Cluster +ClusterLoop: or dx,dx ; wenn noch mehr als 64K Cluster, + jnz ClusterNxtLoop ; auf jeden Fall zu groá + cmp ax,4080 ; bei weniger als 4K Clustern + jb ClusterEndLoop ; auf jeden Fall OK + cmp [BPB_SysID+4],'2' ; sonst bei FAT12 + je ClusterNxtLoop ; auf jeden Fall zu viel + cmp ax,65510 ; bei FAT16 Vergleich auf 64K + jb ClusterEndLoop +ClusterNxtLoop: shl bl,1 ; zu viel: Cluster verdoppeln + js ClusterEndLoop ; bei 128 Sektoren/Cluster abbrechen + shr dx,1 ; Clusterzahl halbiert sich + rcr ax,1 + jmp ClusterLoop +ClusterEndLoop: mov [BPB_SecsPerClust],bl ; Ergebnis einschreiben + add ax,2 ; Dummy-Eintr„ge in FAT + adc dx,0 + mov bx,341 ; Anzahl FAT-Sektoren berechnen + cmp [BPB_SysID+4],'2' + jz Cluster12 + mov bx,256 +Cluster12: div bx + or dx,dx ; Sektorzahl aufrunden + jz FATLenEven + inc ax +FATLenEven: mov [BPB_SecsPerFAT],ax ; Anzahl FAT-Sektoren einschreiben + +; Schritt 7: Bootsektor aufbauen + + PrMsg WrBootSectMsg + lea di,[SectorBuffer] + cld + mov al,0ebh ; Dummy-Sprung einschreiben + stosb + mov al,0feh + stosb + mov al,90h + stosb + mov ax,'ES' ; OEM-ID einschreiben + stosw + mov ax,'DC' + stosw + mov ax,'IR' + stosw + mov ax,'EV' + stosw + lea si,[BPBBuffer] ; BPB einschreiben + mov cx,BPB_Length + rep movsb + mov cx,SectorBuffer+SecSize ; Rest vom Bootsektor nullen + sub cx,di + mov al,0 + rep stosb + mov ax,0 ; Bootsektor ist log. Sektor 0 + mov dx,ax + mov bl,0 ; Partition 0 + call TranslateParams + mov cl,1 ; nur ein Sektor + lea si,[SectorBuffer] + call WriteSectors + ljc LFormError + +; Schritt 8: Directory & FATs ausnullen + + lea di,[SectorBuffer] ; Sektorpuffer wird benutzt + mov cx,SecSize/2 + cld + sub ax,ax + rep stosw + PrMsg WrFATMsg + mov ax,[BPB_ResvdSecs] ; Startsektor FATs holen + sub dx,dx + lea si,[SectorBuffer] + mov cx,[BPB_SecsPerFAT] + add cx,cx ; beide FATs nullen +FATZeroLoop: push ax ; Sektornummer und -zahl retten + push cx + push dx + mov bl,0 + call TranslateParams + mov cl,1 + call WriteSectors + pop dx + pop cx + pop ax + ljc LFormError + add ax,1 ; n„chster Sektor + adc dx,0 + loop FATZeroLoop + push ax ; !!! PrMsg zerst”rt AX-Register + PrMsg WrDirMsg + pop ax + mov cx,[DirLen] ; dito fr Directory +DirZeroLoop: push ax + push cx + push dx + mov bl,0 + call TranslateParams + mov cl,1 + call WriteSectors + pop dx + pop cx + pop ax + ljc LFormError + add ax,1 ; n„chster Sektor + adc dx,0 + loop DirZeroLoop + +; Schritt 9: Sektoren testen und FAT initialisieren + + mov ax,[BPB_ResvdSecs] ; Datensektorbeginn berechnen + sub dx,dx + mov [FAT1Pos],ax ; Beginn 1. FAT hinter Bootsektor + mov [FAT1Pos+2],dx + add ax,[BPB_SecsPerFAT] ; Beginn 2. FAT hinter 1. FAT + adc dx,0 + mov [FAT2Pos],ax + mov [FAT2Pos+2],dx + add ax,[BPB_SecsPerFAT] + adc dx,0 + add ax,[DirLen] ; Datenbeginn hinter Directory + adc dx,0 + mov [DataPos],ax ; diesen Startsektor retten + mov [DataPos+2],dx + + mov ax,word ptr[BPB_NumSecs32] ; Anzahl Cluster berechnen + mov dx,word ptr[BPB_NumSecs32+2] + sub ax,[DataPos] + sbb dx,[DataPos+2] + mov bl,[BPB_SecsPerClust] ; / SecsPerCluster + mov bh,0 + div bx + mov [ClusterCnt],ax + + call ClearFATBuffer ; erste Elemente in FAT schreiben + mov ah,0ffh + mov al,[BPB_MediaID] + call WriteFAT + mov al,0ffh + call WriteFAT + PrMsg ESCMsg + mov ax,[DataPos] ; Schleifenvorbereitung + mov dx,[DataPos+2] + mov cx,[ClusterCnt] +VerifyLoop: push ax ; Z„hler retten + mov bp,cx + push dx + mov bl,0 ; immer Laufwerk 0 + call TranslateParams ; Cluster testlesen + mov cl,[BPB_SecsPerClust] + test bp,15 ; nur alle 16 Cluster schreiben + jnz NoWriteVeri + push ax ; Clusternummer ausgeben + push cx + PrMsg ClusterMsg + mov ax,[ClusterCnt] + sub ax,bp + add ax,2 ; erster Datencluster hat Nummer 2 + mov cl,5 + call WriteDec + PrChar CR + pop cx + pop ax +NoWriteVeri: call VeriSectors + mov ax,0 ; Annahme OK (SUB wrde C l”schen...) + jnc Verify_OK + mov ax,0fff7h +Verify_OK: call WriteFAT + pop dx ; Z„hler zurck + mov cx,bp + pop ax + add al,[BPB_SecsPerClust] + adc ah,0 + adc dx,0 + call BreakOnESC ; Abbruch durch Benutzer ? + jc Ende + loop VerifyLoop + cmp [FATBufferFill],0 ; Puffer rausschreiben + je NoFATFlush + call FlushFATBuffer +NoFATFlush: + +Ende: PrMsg NewLine + mov [DrCnt],0 ; sonst kommt jemand ins Schleudern... + popa + ret + +LFormError: push ax ; Fehlercode retten + pushf + PrMsg NewLine + popf + pop ax + mov ah,[MomDrive] ; Fehlermeldung ausgeben + call WrErrorCode + jmp Ende + +WriteFAT: push bx ; einen FAT-Eintrag schreiben + mov bx,ax + call WriteFATNibble ; Bit 0..3 schreiben + mov al,bl ; Bit 4..7 schreiben + shr al,4 + call WriteFATNIbble + mov al,bh ; Bit 8..11 schreiben + call WriteFATNibble + cmp [BPB_SysID+4],'2' ; evtl. Bit 12..15 schreiben + je WriteFAT12 + mov al,bh + shr al,4 + call WriteFATNibble +WriteFAT12: pop bx + ret + +WriteFATNibble: push bx + and al,15 ; Bit 0..3 ausmaskieren + jz SkipWriteNibble ; Nullen brauchen wir nicht schreiben + mov [MustFlushFAT],1 ; vermerken, daá Puffer nicht genullt ist + mov bx,[FATBufferFill] ; Bit 1.. enthalten Adresse + shr bx,1 + jnc WriteFATLower ; oben oder unten schreiben + shl al,4 +WriteFATLower: or FATBuffer[bx],al +SkipWriteNibble:inc [FATBufferFill] + cmp [FATBufferFill],SecSize*2 ; Sektor voll ? + jne WriteFAT_NFlush + call FlushFATBuffer +WriteFAT_NFlush:pop bx + ret + +FlushFATBuffer: push bx + push cx + push dx + push si + cmp [MustFlushFAT],0 ; nix zu tun ? + je SkipFlushDisk + mov ax,[FAT1Pos] ; erste FAT schreiben + mov dx,[FAT1Pos+2] + mov bl,0 + call TranslateParams + mov cl,1 + lea si,[FATBuffer] + call WriteSectors + mov ax,[FAT2Pos] ; zweite FAT schreiben + mov dx,[FAT2Pos+2] + mov bl,0 + call TranslateParams + mov cl,1 + lea si,[FATBuffer] + call WriteSectors +SkipFlushDisk: call ClearFATBuffer ; Zeiger wieder auf 0 + add [FAT1Pos],1 ; FAT-Sektornummern weiterz„hlen + adc [FAT1Pos+2],0 + add [FAT2Pos],1 + adc [FAT2Pos+2],0 + pop si + pop dx + pop cx + pop bx + ret + + +ClearFATBuffer: push cx + push di + cld + lea di,[FATBuffer] + mov cx,SecSize/2 + sub ax,ax + rep stosw + pop di + pop cx + mov [FATBufferFill],ax + mov [MustFlushFAT],al + ret + +ConfirmMsg db "ACHTUNG! Alle Daten gehen verloren! Fortfahren? $" +InvParTypeMsg db CR,LF,"Partition 1 hat ungltigen Typ oder ist undefiniert!",CR,LF,'$' +DirEntriesMsg db "Anzahl Eintr„ge im Wurzelverzeichnis (16..1024) : $" +WrBootSectMsg db "Schreibe Boot-Sektor...",CR,LF,'$' +WrFATMsg db "Initialisiere FATs...",CR,LF,'$' +WrDirMsg db "Initialisiere Wurzelverzeichnis...",CR,LF,'$' +ESCMsg db "Abbruch mit ",CR,LF,'$' +ClusterMsg db "Teste Cluster $" + +DirLen dw ? ; # Directory-Sektoren +ClusterCnt dw ? +FAT1Pos dw 2 dup (?) ; speichern Sektorz„hler w„hrend Test +FAT2Pos dw 2 dup (?) +DataPos dw 2 dup (?) + +BPBBuffer: ; Zwischenspeicher fr BPB +BPB_SecSize dw ? ; Sektorgr”áe in Bytes +BPB_SecsPerClust db ? ; Sektoren pro Cluster +BPB_ResvdSecs dw ? ; reservierte Sektoren (Bootsektor) +BPB_NumFATs db ? ; Anzahl FATs +BPB_DirLen dw ? ; Anzahl Eintr„ge im Directory +BPB_NumSecs16 dw ? ; Anzahl Sektoren, falls <32 MByte +BPB_MediaID db ? ; Media-Erkennungsbyte +BPB_SecsPerFAT dw ? ; Sektoren pro FAT +BPB_SecsPerTrk dw ? ; Sektoren pro Spur +BPB_Heads dw ? ; Anzahl K”pfe +BPB_LinStart dd ? ; linearer Startsektor auf Laufwerk +BPB_NumSecs32 dd ? ; Anzahl Sektoren, falls >=32 MByte +BPB_PhysNo dw ? ; physikalische Laufwerks-Nummer +BPB_ExtID db ? ; Erkennung, daá es ein erweiterter Boot-Record ist +BPB_SerialNo dd ? ; Seriennummer +BPB_Name db 11 dup (?) ; Name +BPB_SysID db 7 dup (?) ; Systemerkennung +BPB_Length equ $-BPBBuffer ; L„nge BPB + +FATBuffer db SecSize dup (?) ; Puffer, um FATs aufzubauen +MustFlushFAT db ? ; Flag, ob FAT-Puffer geschrieben werden muá +FATBufferFill dw ? ; Anzahl Nibbles in FAT-Puffer + + endp + +;---------------------------------------------------------------------------- + + globproc DiskMenu + + push ax ; Register retten + push cx + push di + + mov [spsave],sp ; Stack umschalten + mov [sssave],ss + mov ax,cs + mov ss,ax + lea sp,[Stack] + +MenuLoop: mov al,[MomDrive] ; Festplatten-Nr. in Kopfmeldung einschreiben + add al,'1' + cmp al,'0' + jnz DrivePresent ; falls Laufwerk noch undefiniert, - ausgeben + mov al,'-' +DrivePresent: mov [MenuMsg_Drv],al + PrMsg MenuMsg + mov al,[MomDrive] + cmp al,-1 ; falls <>-1, Geometrie ausgeben + je NoDrivePresent + call GetPTabAdr ; dazu Tabelle holen + mov ax,[di+DrPar_Cyls] + mov cl,5 + call WriteDec + PrMsg CylMsg + mov al,[di+DrPar_Heads] + mov ah,0 + mov cl,3 + call WriteDec + PrMsg HeadMsg + mov al,[di+DrPar_NSecs] + mov ah,0 + mov cl,3 + call WriteDec + PrMsg SecMsg +NoDrivePresent: + PrMsg MenuList + mov ah,DOS_RdChar + int INT_DOS + push ax + PrChar al + PrMsg TwoLines + pop ax + + cmp al,'0' ; 0 = Men verlassen + lje MenuEnd + + cmp al,'1' ; 1 = Platte wechseln + jne NoSelectDisk + mov ah,1 ; Rckschreiben erlaubt + call SelectDisk + jmp MenuLoop +NoSelectDisk: + cmp al,'2' ; 2 = Geometrie wechseln + jne NoChangeGeometry + call ChangeGeometry + jmp MenuLoop +NoChangeGeometry: + cmp [MomDrive],-1 ; fr alles weitere muá Platte gesetzt sein + jne DiskIsSelected + push ax + shl ax,8 ; Annahme: Geometrie nicht zurckschreiben + cmp ah,'3' + je NoWriteBack + inc al ; fr alles auáer low-level schon +NoWriteBack: call SelectDisk ; implizit Laufwerk erfragen + PrMsg NewLine + pop ax + cmp [MomDrive],-1 + lje MenuLoop ; wenn immer noch nicht gesetzt, Abbruch +DiskIsSelected: + cmp al,'3' ; 3 = Platte low-leveln + jne NoFormatDisk + call FormatDisk + jmp MenuLoop +NoFormatDisk: + cmp al,'4' ; 4 = Spur formatieren + jne NoFormTrack + call FormTrack + jmp MenuLoop +NoFormTrack: + cmp al,'5' ; 5 = Platte prflesen + jne NoBadTrack + call BadTrack + jmp MenuLoop +NoBadTrack: + cmp al,'6' ; 6 = Platte verifizieren + jne NoVerifyDisk + call VerifyDisk + jmp MenuLoop +NoVerifyDisk: + cmp al,'7' ; 7 = Partition anlegen + jne NoMakePart + call MakePart + jmp MenuLoop +NoMakePart: + cmp al,'8' ; 8 = Partition formatieren + jne NoFormatPart + call FormatPart + jmp MenuLoop +NoFormatPart: PrChar BEL ; alle anderen Angaben anmeckern + jmp MenuLoop +MenuEnd: mov ss,[sssave] ; Stack zurck + mov sp,[spsave] + + pop di + pop cx + pop ax ; Register zurck + + ret + +MenuMsg db CR,LF,"SECDRIVE Men Platte:" +MenuMsg_Drv db '-',CR,LF,'$' +CylMsg db " Zylinder,$" +HeadMsg db " K”pfe,$" +SecMsg db " Sektoren",CR,LF,'$' +MenuList db CR,LF + db "1 = Platte wechseln",CR,LF + db "2 = Geometrie neu definieren",CR,LF + db "3 = Platte formatieren",CR,LF + db "4 = Spur formatieren",CR,LF + db "5 = Defekte Spuren markieren",CR,LF + db "6 = Platte verifizieren",CR,LF + db "7 = Partition erstellen",CR,LF + db "8 = Partition log. formatieren",CR,LF + db "------------------------",CR,LF + db "0 = Men verlassen",CR,LF,'$' +spsave dw ? +sssave dw ? + + db 1024 dup (?) ; Programmstack +Stack: + + endp + +MomDrive db -1 +TwoLines: db CR,LF +NewLine: db CR,LF,'$' + + endsection -- cgit v1.2.3