;Formatieren von Disketten in eigenen Formaten ;--------------------------------------------------------------------; ; Murphy 1987 ; ;--------------------------------------------------------------------; ;*** 24-2-87 .z80 SYS Macro Adresse ;;dient zum Aufruf einer Routine in der Systembank call 0FC5Ah defw Adresse endm BDOS Macro Code ld c,Code call 5 endm PRINT Macro Message ;; Ausgeben einer Meldung auf den Bildschirm mit Hilfe ;; der BDOS-Funktion 9. Ab "Message" muss der auszu- ;; gebende Text durch "$" beendet stehen. ld de,Message ;;Text - Adresse BDOS 9 ;Print String endm CR equ 13 ;Carriage Return LF equ 10 ;Line Feed Tracks equ 12h ;relative Position Heads equ 11h ;verschiedener Sektor1 equ 14h ;Formparameter Sekpertr equ 13h ;im DPB Sektlen equ 0Fh Gap_3 equ 18h Logflg equ 1Ah Fillbyte equ 0E5h ; *** Programmstart *** ld (Stackpointer),SP ;Eigener Stack, damit Start: ld SP,01000h ;in jeder Position ein ;Fehlerabbruch moeglich ld c,25 ;ist call 5 ;Aktives Drive holen ld (Old_Drive),A PRINT Hellomessage ld a,(Drive) ld c,a ld e,0FFh ;;*** nicht 1. Zugriff ! call 0FC1Bh ;;Select Drive ;*** SYS 03EBBh ;DPH-Adr. f. Drive in HL push hl dec hl dec hl SYS 03FE0h ;ld l,physik. Drive ld a,l ld (Phys_Drive),a pop de SYS 03F76h ;DPB in IX ld a,(ix+Logflg) ;Loginflag zwi- ld (Loginflag),a ;schenlagern, ld (ix+Logflg),0FFh ;beim Formatieren ;Login unterdruecken, call Forminfo ;Arbeitsformat PRINT mal_fragen ;anzeigen Security: call Getchr cp "J" ;nur wenn j,J,^J jr nz, Security ;formatieren ld b,2 ;Der FDC kann nur max ; 77 Tracks bei einem Recalbefehl steppen (weiss der ; Geier warum); daher evtl. 2 mal, damit auch von ; Trk 80 der Trk 0 erreichbar ist. Recal: push bc SYS 0E6Dh ;Motoren an ld b,77 ;Max. Wartezeit ld a,(Phys_Drive);annehmen; ld c,a ;C : Drive SYS 0D23h ;Recalibrate pop bc and 20h ;Seek End ? jr nz,Anfang ;Alles klar, kann djnz Recal ;losgehn ld de,Recalmessage;Was'n? jr fertich ;->Fehlermeldung Anfang: ld a,(ix+Heads) ;Headmax or a ld a,(ix+Tracks) ;Trackmax (s. Text) jr z,einhead add a,a einhead: ld b,a ;Tracks * Koepfe ld d,0FFh ;Track (-1) Format: push bc ;Zaehler inc d push de ;lfd. Track xor a ;Head Adresse 0 bit 0,(ix+Heads) ;1 Head --> Z jr z,einhd2 srl b ;Bit 0 --> C-Flag adc a,a ;Jeder zweite Track ;auf Seite 2 einhd2: ld e,a ;Head - Adr ld a,(Phys_Drive) add a,e add a,e ;Drive + 4*Head --> add a,e ;Unit Select (FDC) add a,e ld c,a ;C: Unit Select push de ;Track & Head bit 0,(ix+Heads) jr z,einhd3 ;Einseitiges Format ;Zweiseitig: srl d ;log. Track / 2 --> ;physik. Track einhd3: call info ;Anzeige von Track & call Anpassen ;Head pop de ;Jetzt wieder log. ld e,Fillbyte ;Track ! ld b,1 ;Bank fuer die Format- ;maskentabelle (TPA) ; HL : Formatmaske ; IX : Disk Parameter Block ; C : Drive & Head ; D : Zu formatierender Track (logischer !) SYS 08Fh ;Bios-Vektor fuer ;Formatieren pop de ;Lfd. Track- pop bc ;Zaehler jr nc,Error ;Oh ha ! Fehler djnz Format ;Noch'n Track? ;(wie im Goldrausch) ld de,Readymessage;(nanu kein Fehler) jr fertich Error: ld de,Writeprotect;(- oder gar nix jr z,fert2 ;im Schlitz) ld de,Errormessage;Knallharter Murks ! fertich: ld c,9 ;BDOS "String ausgeben" call 5 jr exit fert2: ld c,9 ;Schreibgeschuetzt oder gar call 5 ;keine Disk im Laufwerk call Getchr cp "R" jr z,Anfang ;Nochmal versuchen exit: ld a,(Loginflag) ;Altes Loginflag ld (ix+Logflg),a ;wieder herstellen ld a,(Old_Drive) ld c,a ld e,0FFh ;;*** nicht 1. Zugriff call 0FC1Bh ;;*** Select Drive PRINT weiter ;Noch weitere Disks ;im selben Format call Getchr cp "J" jp z,Start ld SP,(Stackpointer) ret Stackpointer: defw 0 Drive: defb 1 ;Systemvariable fuer das aktive Drive ;B: (A:0 ; B:1 ; C:2) Phys_Drive: defb 0 ;Physikalisches Laufwerk Old_Drive: defb 0 ;Altes Laufwerk zwischenspeichern Loginflag: ;Das Loginflag aus dem DPB wird defb 0 ;hier waehrend des Formatierens ;abgelegt ;--------------------------------------------------------------------; ; Unterprogramme ; ;--------------------------------------------------------------------; Anpassen: ;**** Format-Tabelle anpassen **** ; Fuer jeden Track muessen dem FDC Parameter uebergeben ; werden, anhand derer er hinterher beim Schreiben ; und Lesen erkennt, ob er zum Einen auf der richtigen ; Spur steht, und zum Anderen, ob er auf dieser Spur ; den richtigen Sektor gefunden hat. ld hl,Disktab push hl push bc push de ld a,(ix+Sektor1) ld c,(ix+Sektlen) ld b,(ix+Sekpertr) anp1: ld (hl),d ;Track anpassen inc hl ld (hl),e ;Head inc hl ld (hl),a ;Sektor inc hl ld (hl),c ;Sektorlaenge inc hl add a,5 ;naechste Sektornr. djnz anp2 jr Exanpass anp2: ld (hl),d ;Track anpassen inc hl ld (hl),e ;Head inc hl ld (hl),a ;Sektor inc hl ld (hl),c ;Sektorlaenge inc hl add a,-4 ;naechste Sektornr. djnz anp1 Exanpass: pop de pop bc pop hl ret Disktab: ; kann durch "DEFS 40" erzeugt werden ! ! ! ; so wird aber die Struktur deutlicher. defb Tracks ;Diese Tabelle muss fuer defb Heads ;jede Spur neu ini- defb Sektor1 + 0 ;tialisiert werden defb Sektlen defb Tracks defb Heads defb Sektor1 + 5 defb Sektlen defb Tracks defb Heads defb Sektor1 + 1 defb Sektlen defb Tracks defb Heads defb Sektor1 + 6 defb Sektlen defb Tracks defb Heads defb Sektor1 + 2 defb Sektlen defb Tracks defb Heads defb Sektor1 + 7 defb Sektlen defb Tracks defb Heads defb Sektor1 + 3 defb Sektlen defb Tracks defb Heads defb Sektor1 + 8 defb Sektlen defb Tracks defb Heads defb Sektor1 + 4 defb Sektlen defb Tracks ;Achtung ! 10. Sektor defb Heads ;wird i. A. nicht defb Sektor1 + 9 ;benutzt defb Sektlen Getchr: BDOS 1 ;Tastatureingabe cp 3 ;Abbruch durch ^C jr z,CTRL_C and 01Fh ; "a";"A" --> ^A or 040h ; --> "A" ret ;nur noch Grossbuchstaben! CTRL_C: ld de,Abbruch jp fertich printA: ;Dezimalausgabe von A --> Bildschirm ld l,a ld h,0 printHL: ; 5 Stellen mit Nullunterdrueckung ld d,0 ;30h , wenn Nullunterdr. ld bc,-10000 ;unerwuenscht call Decziffer ;5. Stelle ld bc,-1000 call Decziffer ;4. Stelle... ld bc,-100 call Decziffer ld bc,-10 call Decziffer ld a,l ;Letzte Stelle wird ; immer geprintet, auch wenn es eine Null ist. Decprnt: or 30h ;Ziffer --> ASCII push hl push de push bc ld e,a ;Ausgabe BDOS 2 pop bc pop de pop hl ret Decziffer: ld a,-1 ;Arbeitszaehler decloop: inc a ;Zaehlen, wie oft BC add hl,bc ;in HL enthalten ist jr c,decloop sbc hl,bc ;Rest zurueck -> HL or d ;Sowohl A als auch D Null? ret z ;Fuehrende Null ignorieren ld d,030h ;Beenden der Nullkennung jr Decprnt ;und Ausgabe Hexprint: push hl push de push bc push af and 0F0h ;High Digit ausmaskieren rlca ;--> low Digit rollen rlca rlca rlca call hexziffer ;Ausgeben pop af and 0Fh ;Low Digit call hexziffer pop bc pop de pop hl ret hexziffer: add a,"0" ;0-9 --> ASCII cp ("9"+1) jr c,ziffer add a,7 ;A-F --> Buchstabe ziffer: ld e,a BDOS 2 ;Ausgabe ret info: push bc ;Anzeige der gerade push de ;formatierten Spur push hl push de ;Track & Head push de PRINT trktext pop de ld a,d ;Track anzeigen call printA PRINT kopftext pop de ld a,e ;Head anzeigen call printA ld c,11 ;Get Console Status call 5 and a jr z,Notbreak ;Keine Taste gedrueckt call Getchr ;Durch ^C abbrechen call Getchr ;oder durch zweite Taste ;weitermachen Notbreak: pop hl pop de pop bc ret org 0200h Forminfo: PRINT Formtracks ;Formatparameter des ld a,(ix+Tracks) ;verwendeten Formats ;anzeigen call printA ;Anzahl der Spuren PRINT Form1sektor ;Basissektor ld a,(ix+Sektor1) call Hexprint PRINT Formheads ;Ein- oder zweiseitig ld a,(ix+Heads) inc A ;( weil 0 = einseitig call printA PRINT Formsekpertr ;Sektoren / Spur ld a,(ix+Sekpertr) call printA PRINT Formlen ;Laenge eines Sektors ld b,(ix+Sektlen) inc b ;ist im DPB als ld hl,64 ;log2 (Laenge/128 Bytes) ;abgelegt lencalc: add hl,hl djnz lencalc call printHL ret ;--------------------------------------------------------------------; ; Meldungen ; ;--------------------------------------------------------------------; org 0280h Hellomessage: defb CR,LF,LF defb "Diskettenformatierprogramm" defb " Murphy 1986" defb CR,LF,LF defb "Format:" defb "$" ;*** Meldungen fuer "info" / Anzeige der laufenden Spur org 0300h trktext: defb CR defb "Track : " defb "$" org 0380h kopftext: defb " Kopf : " defb "$" ;*** Fehlermeldungen bzw. Erfolgsmeldung org 0400h Readymessage: defb CR,LF,LF defb "Nun gut, das Formatieren hat " defb "geklappt" defb CR,LF,LF defb "$" org 0480h Errormessage: defb CR,LF,LF defb "Scheisse, geht nicht !" defb CR,LF,LF defb "$" org 0500h Writeprotect: defb CR,LF,LF defb "Versuch's mal mit einer nicht " defb "schreibgeschuetzten Diskette" defb CR,LF,LF defb "R-etry ? / .$" org 0580h Recalmessage: defb CR,LF,LF defb "Fehler beim Suchen von Spur Null !" defb CR,LF,LF defb "$" org 0600h Abbruch: defb CR,LF,LF defb "Abbruch der Formatierung" defb CR,LF,LF defb "$" org 0680h weiter: defb CR,LF,LF defb "Nochmal, oder ist jetzt endlich " defb "Schluss ?!" defb CR,LF,LF defb "( J / N )" defb "$" ;*** Meldungen fuer die Anzeige des verwendeten Formats org 0700h mal_fragen: defb CR,LF,LF defb "Format korrekt ? ( J / CTRL-C )" defb CR,LF,LF defb "." defb 8,"$" org 0780h Formtracks: defb CR,LF,LF defb "Spuren auf einer Seite : $" org 0800h Form1sektor: defb " Basissektor : $" org 0880h Formheads: defb CR,LF defb "Kopfanzahl : $" org 0900h Formsekpertr: defb CR,LF,LF defb "Sektoren / Track : $" org 0980h Formlen: defb " Sektorgroesse : $" end