;-----------------------------------------------------------------------------
; CPM Format Rossendorf FORMATZ.COM
; (c) 1989 F.Schwarzenberg, Version 2.0
; disassembliert Volker Pohlers 2006+2025
;-----------------------------------------------------------------------------

		cpu	z80
		page	0

FDCPORTS	EQU 'ROSSENDORF'	; orig. FORMATZ.COM
;FDCPORTS	EQU 'ROBOTRON'		; Version für Robotron-Floppy-Modul

BDOS		equ	5

		org 100h

		nop
		nop
		nop
		ld	sp, 100h

loc_106:				; Hauptprogramm
		jp	form

;------------------------------------------------------------------------------
; physischer Disketten-Transfer
;------------------------------------------------------------------------------

		include biosfdc.inc

;------------------------------------------------------------------------------
;
;------------------------------------------------------------------------------


; 8 Byte Buffer	FT-Daten
ftbuf:		db	100		; field_4
		db	42		; field_5
byte_368:	db	0		; field_6 Anz. Systemspuren
byte_369:	db	1		; field_7 H Anz. Seiten
stp:		db	0		; FT.STP
lasttrk:	db	80		; USEDTRK

dttab:		dw	ttab1		; Adresse Sektorversatztabelle
LW_TYP:		db	0		; A=0 80 Spur DS
					; A=1 80 Spur SS
					; A=2 40 Spur DS
					; A=3 40 Spur SS
selFormat:	db	0		; selektiertes Format (0..9)
aktSysLW:	db	0		; aktuelles System-Laufwerk
fVerify:	db	0		; Verify-Flag: 0-ohne, FF-mit Verify

; Sektorversatztabellen
ttab1:		db	2
		db	3
		db	4
		db	5
		db	1

ttab2:		db	9
		db	8
		db	7
		db	6
		db	5
		db	4
		db	3
		db	2
		db	1

ttab3:		db	16
		db	15
		db	14
		db	13
		db	12
		db	11
		db	10
		db	9
		db	8
		db	7
		db	6
		db	5
		db	4
		db	3
		db	2
		db	1

aSpur:		db	"Spur: $"
aKopf:		db	"  Kopf: $"
AFormatierung:	db	0Ch
		db	"Formatierung von CP/M-Disketten",0Dh,0Ah
		db	"      fuer CP/M-Z9001",0Ah,0Dh
		db	"(c) 1989 F.Schwarzenberg  Version 2.0",0Dh,0Ah
		db	"zu formatierende Diskette",0Dh,0Ah
		db	"erst nach Aufforderung einlegen!",0Dh,0Ah,0Ah
		db	"Laufwerk ([A|B] Enter=A) $"

aDisketteInLauf:db	0Ah,0Dh
		db	"Diskette in Laufwerk A: einlegen!",0Ah,0Dh
		db	"Diskette wird geloescht",0Dh,0Ah
		db	"([j|v]/n)(v: mit Verify)? $"

aFormateFuerLwT:db	"Formate fuer LW-Typ 80 Spuren DS (1.6)",0Ah,0Dh,0Ah,0Dh
		db	"0= 800K 4= 400K (80SS) 8= 200K (40SS)",0Ah,0Dh
		db	"1= 780K 5= 400K (40DS) 9= 148K (40SS)",0Ah,0Dh
		db	"2= 720K*6= 360K*(40DS)",0Ah,0Dh
		db	"3= 624K 7= 308K (80SS)",0Ah,0Dh
		db	"* -> IBM-PC-Format mit Bootblock",0Ah,0Dh
		db	"Welches Format? $"
		db	0

aFormateFuerL_0:db	"Formate fuer LW-Typ 80 Spuren SS (1.4)",0Ah,0Dh,0Ah,0Dh
		db	"0= 400K (80SS)     2= 200K",0Ah,0Dh
		db	"1= 308K (80SS)     3= 148K",0Ah,0Dh,0Ah,0Dh
		db	"Welches Format? $"
		db	0

aFormateFuerL_1:db	"Formate fuer LW-Typ 40 Spuren DS",0A0h,0Dh,0Ah,0Dh
		db	"0= 400K (40DS)     2= 200k (40SS)",0Ah,0Dh
		db	"1= 360K ( IBM)     3= 148  (40SS)",0Ah,0Dh,0Ah,0Dh
		db	"Welches Format? $"
		db	0

aFormateFuerL_2:db	"Formate fuer LW-Typ 40 Spuren SS (1.2)",0A0h,0Dh,0Ah,0Dh
		db	"0= 200k      1= 148K",0Ah,0Dh,0Ah,0Dh
		db	"Welches Format? $"
		db	0

;------------------------------------------------------------------------------
; Format-Tabellen
;------------------------------------------------------------------------------

;format_info	struc ;	(sizeof=0xc)
;N:		db	?		; relative Sektorlänge 2^N; 3 => 1024 Byte
;EOT:		db	?		; Anzahl Sektoren
;GPL:		db	?		; Anzahl der Lückenbytes in GAP3
;DTL:		db	?		; Datenlänge (bei N>0 = 0FFh)
;field_4:	db	?		; 
;field_5:	db	?		; 
;field_6:	db	?		; Anzahl Systemspuren
;field_7:	db	?		; Anzahl Seiten/Köpfe
;FT.STP:	db	?		; Anzahl Stepimpulse
;USEDTRK:	db	?		; genutzte Anzahl phys.	Spuren
;field_A:	dw	?		; Adresse translation table
;format_info	ends


tform80ds:	db	10		; Anzahl Formatbeschreibungen
;Format	0 800K
		db	3		; N
		db	5		; EOT
		db	20h		; GPL
		db	0FFh		; DTL
		db	100		; field_4
		db	32		; field_5
		db	0		; field_6
		db	1		; field_7
		db	1		; FT.STP
		db	80		; USEDTRK
		dw	ttab1		; field_A
;Format	1 780K
		db	3		; N
		db	5		; EOT
		db	20h		; GPL
		db	0FFh		; DTL
		db	100		; field_4
		db	32		; field_5
		db	2		; field_6
		db	1		; field_7
		db	1		; FT.STP
		db	80		; USEDTRK
		dw	ttab1		; field_A
;Format	2 720K MSDOS
		db	2		; N
		db	9		; EOT
		db	2Ah		; GPL
		db	0FFh		; DTL
		db	80		; field_4
		db	42		; field_5
		db	0		; field_6
		db	1		; field_7
		db	1		; FT.STP
		db	80		; USEDTRK
		dw	ttab2		; field_A
;Format	3 624K
		db	1		; N
		db	10h		; EOT
		db	20h		; GPL
		db	0FFh		; DTL
		db	50		; field_4
		db	32		; field_5
		db	2		; field_6
		db	1		; field_7
		db	1		; FT.STP
		db	80		; USEDTRK
		dw	ttab3		; field_A
;Format	4 400K (80SS)
		db	3		; N
		db	5		; EOT
		db	20h		; GPL
		db	0FFh		; DTL
		db	100		; field_4
		db	32		; field_5
		db	0		; field_6
		db	0		; field_7
		db	1		; FT.STP
		db	80		; USEDTRK
		dw	ttab1		; field_A
;Format	5 400K (40DS)
		db	3		; N
		db	5		; EOT
		db	20h		; GPL
		db	0FFh		; DTL
		db	100		; field_4
		db	32		; field_5
		db	0		; field_6
		db	1		; field_7
		db	2		; FT.STP
		db	40		; USEDTRK
		dw	ttab1		; field_A
;Format	6 360K MSDOS (40DS)
		db	2		; N
		db	9		; EOT
		db	2Ah		; GPL
		db	0FFh		; DTL
		db	80		; field_4
		db	42		; field_5
		db	0		; field_6
		db	1		; field_7
		db	2		; FT.STP
		db	40		; USEDTRK
		dw	ttab2		; field_A
;Format	7 308K (80SS)
		db	1		; N
		db	10h		; EOT
		db	20h		; GPL
		db	0FFh		; DTL
		db	50		; field_4
		db	32		; field_5
		db	3		; field_6
		db	0		; field_7
		db	1		; FT.STP
		db	80		; USEDTRK
		dw	ttab3		; field_A
;Format	8 200K (40SS)
		db	3		; N
		db	5		; EOT
		db	20h		; GPL
		db	0FFh		; DTL
		db	100		; field_4
		db	32		; field_5
		db	0		; field_6
		db	0		; field_7
		db	2		; FT.STP
		db	40		; USEDTRK
		dw	ttab1		; field_A
;Format	9 148K (40SS)
		db	1		; N
		db	10h		; EOT
		db	20h		; GPL
		db	0FFh		; DTL
		db	50		; field_4
		db	32		; field_5
		db	3		; field_6
		db	0		; field_7
		db	2		; FT.STP
		db	40		; USEDTRK
		dw	ttab3		; field_A

tform80ss:	db	4		; Anzahl Formatbeschreibungen
;Format	0 400K (80SS)
		db	3		; N
		db	5		; EOT
		db	20h		; GPL
		db	0FFh		; DTL
		db	100		; field_4
		db	32		; field_5
		db	0		; field_6
		db	0		; field_7
		db	1		; FT.STP
		db	80		; USEDTRK
		dw	ttab1		; field_A
;Format	1 308K (80SS)
		db	1		; N
		db	10h		; EOT
		db	20h		; GPL
		db	0FFh		; DTL
		db	50		; field_4
		db	32		; field_5
		db	3		; field_6
		db	0		; field_7
		db	1		; FT.STP
		db	80		; USEDTRK
		dw	ttab3		; field_A
;Format	2 200K
		db	3		; N
		db	5		; EOT
		db	20h		; GPL
		db	0FFh		; DTL
		db	100		; field_4
		db	32		; field_5
		db	0		; field_6
		db	0		; field_7
		db	2		; FT.STP
		db	40		; USEDTRK
		dw	ttab1		; field_A
;Format	3 148K
		db	1		; N
		db	10h		; EOT
		db	20h		; GPL
		db	0FFh		; DTL
		db	50		; field_4
		db	32		; field_5
		db	3		; field_6
		db	0		; field_7
		db	2		; FT.STP
		db	40		; USEDTRK
		dw	ttab3		; field_A

tform40ds:	db	4		; Anzahl Formatbeschreibungen
;Format	0 400K (40DS)
		db	3		; N
		db	5		; EOT
		db	20h		; GPL
		db	0FFh		; DTL
		db	100		; field_4
		db	32		; field_5
		db	0		; field_6
		db	1		; field_7
		db	1		; FT.STP
		db	40		; USEDTRK
		dw	ttab1		; field_A
;Format	1 360K ( IBM)
		db	2		; N
		db	9		; EOT
		db	2Ah		; GPL
		db	0FFh		; DTL
		db	80		; field_4
		db	42		; field_5
		db	0		; field_6
		db	1		; field_7
		db	1		; FT.STP
		db	40		; USEDTRK
		dw	ttab2		; field_A
;Format	2 200k (40SS)
		db	3		; N
		db	5		; EOT
		db	20h		; GPL
		db	0FFh		; DTL
		db	100		; field_4
		db	32		; field_5
		db	0		; field_6
		db	0		; field_7
		db	1		; FT.STP
		db	40		; USEDTRK
		dw	ttab1		; field_A
;Format	3 148  (40SS)
		db	1		; N
		db	10h		; EOT
		db	20h		; GPL
		db	0FFh		; DTL
		db	50		; field_4
		db	32		; field_5
		db	3		; field_6
		db	0		; field_7
		db	1		; FT.STP
		db	40		; USEDTRK
		dw	ttab3		; field_A

tform40ss:	db	2		; Anzahl Formatbeschreibungen
;Format	1 200k
		db	3		; N
		db	5		; EOT
		db	20h		; GPL
		db	0FFh		; DTL
		db	100		; field_4
		db	32		; field_5
		db	0		; field_6
		db	0		; field_7
		db	1		; FT.STP
		db	40		; USEDTRK
		dw	ttab1		; field_A
;Format	2 148K
		db	1		; N
		db	10h		; EOT
		db	20h		; GPL
		db	0FFh		; DTL
		db	50		; field_4
		db	32		; field_5
		db	3		; field_6
		db	0		; field_7
		db	1		; FT.STP
		db	40		; USEDTRK
		dw	ttab3		; field_A

;
; Tastaturabfrage
;
CONSI:		ld	c, 1
		call	BDOS

;
; Ausgabe Kursor runter
;
CUDOWN:		ld	c, 2		; Konsolenausgabe
		push	af
		ld	e, 0Ah		; Cursor runter
		call	BDOS
		pop	af

;
; Ausgabe ENTER
;
ENTER:		push	af
		ld	e, 0Dh
		ld	c, 2
		call	BDOS
		pop	af
		ret

;
; Ausgabe Register A als Dezimalzahl
;
print_a:	ld	hl, aTrack	; "$"
		or	a		; A=ft.trk
		jr	z, print_trk2	; wenn A=0, so keine Konvertierung nötig
		ld	b, a		; sonst	A kopieren
		xor	a		; A=0
print_trk1:	add	a, 1		; und konvertieren in BCD-Zahl
		daa
		djnz	print_trk1
print_trk2:	ld	(hl), a		; Wandlung in Dezimalzahl
		ld	a, 33h ; '3'
		rrd
		inc	hl
		ld	(hl), a
		ld	de, aTrack	; "$"
		ld	c, 9		; Ausgabe Zeichenkette
		jp	5

aTrack:		db	0
		db	0
		db	"$"

asc_800:	db	"               $"

;------------------------------------------------------------------------------
; Hauptprogramm
;------------------------------------------------------------------------------

form:		xor	a		; Hauptprogramm
		ld	(UNIT),	a	; Laufwerk
		ld	(fVerify), a	; Verify-Flag: 0-ohne, FF-mit Verify
		ld	(aLeseFehler+0Fh), a
		
		ld	a, 3		; LW1+2
		ld	(dFDCZ1), a	; Merkzelle FDC Zusatzregister

		ld	de, AFormatierung ; CLS, Copyright etc., Laufwerksauswahl
		ld	c, 9		; Zeichenkette ausgeben
		call	BDOS
		call	CONSI
		and	5Fh ; '_'
		cp	0Dh		; <ENTER>
		jr	z, form1	; vorausgewähltes Laufwerk bleibt
		cp	3		; <STOP>
		jp	z, 0		; Abbruch, zurück ins CPM
		cp	1Bh		; <ESC>
		jr	z, form		; Hauptprogramm
		sub	41h ; 'A'
		jr	c, form		; Hauptprogramm
		cp	2
		jr	nc, form	; Hauptprogramm
		ld	(FormLW), a	; Laufwerk merken
		ld	(UNIT),	a	; Laufwerk
form1:		ld	c, 25		; Abfrage aktuelles Laufwerk
		call	BDOS
		ld	(aktSysLW), a	; aktuelles System-Laufwerk
		ld	a, (FormLW)	; zu formatierendes Laufwerk 0=A, 1=B
		add	a, 41h ; 'A'
		ld	(aDisketteInLauf+17h), a ; LW in Text reinbasteln
		ld	e, 0
		ld	c, 31		; DPB-Adresse holen
					; ret HL=DPB-Adresse
		call	BDOS
		ld	a, (FormLW)	; zu formatierendes Laufwerk 0=A, 1=B
		or	a
		jr	z, form2	; Sprung wenn LW="A"
		ld	bc, 33h	; '3'   ; in Z9001-CBIOS Länge eines erweiterten DBP
		add	hl, bc		; HL=Adr. DPB LW B:
form2:		ld	bc, 15h		; Offset im DBP	auf Laufwerkscode
		add	hl, bc
		ld	a, (FormLW)	; zu formatierendes Laufwerk 0=A, 1=B
		cp	(hl)		; Vergleich mit	LW-Kennung im erweiterten Z9001-CBIOS
		ld	de, aSystemfehlerFa ; "Systemfehler (falsches System)!\n\r$"
		jp	nz, error1
		inc	hl
		ld	b, 0		; B=0 bei 80 Spuren
		ld	a, 80
		cp	(hl)		; gesamt 80 Spuren?
		jr	z, form3
		ld	a, 40		; gesamt 40 Spuren?
		cp	(hl)
		ld	de, aFalscheLaufwer ; "falsche Laufwerk-Parameter\n\r$"
		jp	nz, error1
		set	1, b		; B=2 bei 40 Spuren
form3:		inc	hl
		inc	hl		; HL=translation-Tabelle f. LW im Z9001-CBIOS
		ld	a, (hl)
		cpl
		and	1		; 1=SS,	0=DS
		add	a, b
		ld	(LW_TYP), a	; A=0 80 Spur DS
					; A=1 80 Spur SS
					; A=2 40 Spur DS
					; A=3 40 Spur SS
		ld	hl, tform80ds	; Anzahl Formatbeschreibungen
		ld	de, aFormateFuerLwT ; "Formate fuer LW-Typ 80 Spuren DS (1.6)\n"...
		or	a
		jr	z, form4	; A=0 80 Spur DS
		dec	a
		ld	hl, tform80ss
		ld	de, aFormateFuerL_0 ; "Formate fuer LW-Typ 80 Spuren SS (1.4)\n"...
		jr	z, form4	; A=1 80 Spur SS
		dec	a
		ld	hl, tform40ds
		ld	de, aFormateFuerL_1 ; "Formate fuer LW-Typ 40 Spuren DSá\r\n\r0= "...
		jr	z, form4	; A=2 40 Spur DS
		ld	hl, tform40ss
		ld	de, aFormateFuerL_2 ; "Formate fuer LW-Typ 40 Spuren SS (1.2)á"...
form4:		push	hl
		ld	c, 9		; Zeichenkette ausgeben
		call	BDOS
		call	CONSI		; Formatauswahl	(0..9)
		sub	30h ; '0'
		pop	hl
		jp	c, form		; Wiederholung,	wenn A < 0
		cp	10
		jr	c, form5	; weiter wenn A	< 10
		and	5Fh ; '_'
		sub	7
form5:		cp	(hl)		; HL=Adr. Formattabelle, (HL) =	Anzahl der möglichen Formate
		jp	nc, form	; Rücksprung, wenn ausgewähltes	Format nicht ex.
		push	hl
		ld	(selFormat), a	; selektiertes Format (0..9)
		xor	a		; A=0
		ld	(blkcnt), a	; Anzahl gelesener Blöcke (Import MSDOS	Bootdaten)
		ld	a, (aktSysLW)	; aktuelles System-Laufwerk
		ld	e, a
		ld	c, 14		; Laufwerk anwählen
		call	BDOS
		ld	a, (LW_TYP)	; A=0 80 Spur DS
					; A=1 80 Spur SS
					; A=2 40 Spur DS
					; A=3 40 Spur SS
		or	a
		jp	z, form6	; 80 Spur DS
		cp	2
		jp	nz, form11	; wenn 40-Spur-Laufwerk
		ld	a, (selFormat)	; selektiertes Format (0..9)
		cp	1
		jp	nz, form11
		ld	a, 6
		jr	form7
form6:		ld	a, (selFormat)	; 80 Spur DS
		cp	2		; Format 2 = 720K MSDOS
		jr	z, form7
		cp	6		; Format 6 = 360K MSDOS
		jp	nz, form11	; wenn kein MSDOS-FORMAT, auch nicht Boootblock laden
;
; MSDOS-Bootblock laden
;
form7:		cp	6		; Format 6 = 360K MSDOS, also Filename patchen
		jr	nz, form8
		ld	a, '3'
		ld	(FCB+5), a
		ld	a, '6'
		ld	(FCB+6), a
form8:		ld	c, 37		; Laufwerk zurücksetzen
		ld	de, (aktSysLW)	; aktuelles System-Laufwerk
		inc	de
		call	BDOS
		ld	hl, FCB+12	; FCB mit 00 initialsieren (außer Filename)
		ld	de, FCB+13
		ld	bc, FCBend-FCB-3
		ld	(hl), 0
		ldir
		ld	de, FCB
		ld	c, 15		; Datei	öffnen
		call	BDOS
		inc	a
		jr	nz, form9	; wenn kein Fehler
		; sonst Fehlermeldung
		ld	de, aBootblockdatei ; "Bootblockdatei nicht vorhanden oder feh"...
		ld	c, 9		; Zeichenkette ausgeben
		call	BDOS
		ld	c, 1		; Konsoleneingabe
		call	BDOS
		cp	1Bh		; <ESC>
		jr	z, form11
		cp	3		; <STOP>
		jr	nz, form8
		pop	hl
		jp	form		; Hauptprogramm
		; Datei laden nach wrbuf
form9:		ld	de, wrbuf-80h	; DMA-Buffer
		ld	(ft.adr), de
		ld	c, 26		; DMA-Adresse setzen
		call	BDOS
		xor	a		; A=0
		ld	(blkcnt), a	; Anzahl gelesener Blöcke (Import MSDOS	Bootdaten)
form10:		ld	hl, (ft.adr)
		ld	bc, 80h		; Record Size
		add	hl, bc
		ld	(ft.adr), hl
		ex	de, hl
		ld	c, 26		; DMA-Adresse setzen
		call	BDOS
		ld	de, FCB
		ld	c, 20		; sequentiell Lesen
		call	BDOS
		ld	hl, blkcnt	; Anzahl gelesener Blöcke (Import MSDOS	Bootdaten)
		inc	(hl)
		or	a
		jr	z, form10
		dec	(hl)
		ld	c, 16		; Datei	schließen
		ld	de, FCB
		call	BDOS
;
;
;
form11:		pop	hl		; HL=Formattabelle
		inc	hl		; Adr. 1.Formatinfo
		ld	a, (selFormat)	; selektiertes Format (0..9)
		ld	b, a
		add	a, a
		add	a, a
		add	a, b
		add	a, a
		add	a, b
		add	a, b		; A=A*12 (Länge	Formatinfo)
		ld	c, a
		ld	b, 0
		add	hl, bc		; HL=Adr. selektierte Formatinfo
		ld	de, N		; zu CTAB, biosfdc.ins
		ld	bc, 4		; kopiere 4 Werte N, EOT, GPL, DTL
		ldir
		ld	de, ftbuf	; 8 Byte Buffer	FT-Daten
		ld	bc, 8		; kopiere 12 Byte nach ftbuf
		ldir
		ld	a, (stp)
		ld	(ft.stp), a
		ld	a, (lasttrk)
		ld	(form19+1), a	; (dieses Feld wird in Formatauswahl gepatcht)
		ld	a, (byte_368)	; field_6
		ld	(fmtrk2+1), a	; (dieses Byte wird durch die Formatauswahl gepatcht)
		ld	de, aDisketteInLauf ; "\n\rDiskette in Laufwerk A: einlegen!\n\rDi"...
		ld	c, 9		; Zeichenkette ausgeben
		call	BDOS
		ld	c, 1		; Konsoleneingabe
		call	BDOS
		and	5Fh ; '_'
		cp	'J'
		jr	z, form12	; J-Formatieren
		cp	'V'             ; V-mit Verify
		jp	nz, form	; Hauptprogramm
		ld	a, 0FFh
		ld	(fVerify), a	; Verify-Flag: 0-ohne, FF-mit Verify
form12:		call	CUDOWN		; Ausgabe Kursor runter
		call	CUDOWN		; Ausgabe Kursor runter
		ld	a, (ftbuf)	; 8 Byte Buffer	FT-Daten
		ld	(GPL), a	; Anzahl Lückenbytes in	GAP3

	IF CPMSYSTEM = 'ROBOTRON'
		ld	a, (ft.lwn)
		or	a
		ld	a, 1
		jr	z, fdrv0
		rlca
fdrv0:		ld	hl, dFDCZ1
		and	(hl)
		out	(FDCZ),	a		; Motor an
		ld	(dFDCZ2), a
	ENDIF

		call	recal2		; Spur 0 einstellen (2 Versuche)
		jp	nz, error	; Ausgabe Fehlermeldung, Abbruch
		xor	a
		ld	(HED), a	; Kopfnummer/Seite (0/1)

	; Spur formatieren
form13:		ld	(ft.trk), a
		push	af
		call	ENTER		; Ausgabe ENTER
		ld	de, aSpur	; "Spur: $"
		ld	c, 9		; Zeichenkette ausgeben
		call	BDOS
		pop	af
		call	print_a		; Ausgabe Register A als Dezimalzahl
		ld	e, ' '
		ld	c, 2		; Konsolenausgabe
		call	BDOS
		ld	a, (HED)	; Kopfnummer/Seite (0/1)
		ld	e, 9Eh 		; Grafikzeichen Strich oben
		or	a
		jr	z, form14
		ld	e, 0F8h		; Grafikzeichen Strich unten
form14:		ld	c, 2		; Konsolenausgabe
		call	BDOS
		;
		di
		call	fmtrk		; Formatieren einer Spur 
		ei
		;
		ld	a, (fVerify)	; Verify-Flag: 0-ohne, FF-mit Verify
		or	a
		jr	z, form16
	;Verify	
		ld	a, (HED)	; Kopfnummer/Seite (0/1)
		ld	(ft.sid), a
		rrca
		and	80h
		or	38h
		ld	(ft.kom), a
		ld	hl, rdbuff	; Bufferadr
		ld	(ft.adr), hl
		ld	a, (EOT)	; Nummer des letzten Sektors der Spur
		ld	(ft.anz), a
		ld	a, (N)		; relative Sektorlänge (2^N mit	N=0..3,	also 1024 Byte)
		ld	(ft.len), a
		ld	a, 1
		ld	(ft.sec), a
		ld	a, (FormLW)	; zu formatierendes Laufwerk 0=A, 1=B
		ld	(ft.lwn), a
		call	floppy
		push	af
		ld	a, (ft.anz)
		ld	(EOT), a	; Nummer des letzten Sektors der Spur
		pop	af
		or	a
		ld	(aLeseFehler+0Fh), a
		ld	de, asc_800	; "               $"
		jr	z, form15
		ld	de, aLeseFehler	; "  Lese-Fehler:  $"
form15:		ld	c, 9		; Zeichenkette ausgeben
		call	BDOS
	; Abbrechen?
form16:		ld	a, (25h)	; Z9001-KEYBU, Tastaturbuffer
		cp	3		; <STOP>
		jp	z, form20	; ja -> Abbruch
	; nächste Spur	
		ld	a, (ft.trk)
		ld	c, a
		ld	a, (byte_369)	; field_7
		or	a
		jr	z, form17
		ld	a, (HED)	; Kopfnummer/Seite (0/1)
		xor	1		; toggle Seite
		ld	(HED), a	; Kopfnummer/Seite (0/1)
		jr	nz, form18
form17:		inc	c
form18:		ld	a, c
form19:		cp	80		; lasttrk (dieses Feld wird in Formatauswahl gepatcht)
		jp	nz, form13	; letzte Spur erreicht?
	
	; 	
form20:		call	ENTER		; Ausgabe ENTER
	IF CPMSYSTEM = 'ROBOTRON'
		ld	a,(dFDCZ2)
		out	(FDCZ),	a	; Motor an
	ENDIF
		call	recal2		; Spur 0 einstellen (2 Versuche)
		ld	a, (blkcnt)	; Anzahl gelesener Blöcke (Import MSDOS	Bootdaten)
		or	a
		jr	z, form21	; Sprung, wenn kein MSDOS-Format
;
;Schreibe MSDOS-Bootblock
;
		ld	hl, wrbuf	; Beginn BOOT-Block
		ld	(ft.adr), hl
		ld	a, 1111100b
		ld	(ft.kom), a
		ld	a, (FormLW)	; zu formatierendes Laufwerk 0=A, 1=B
		ld	(ft.lwn), a
		xor	a
		ld	(ft.trk), a
		ld	(ft.sid), a
		inc	a
		ld	(ft.sec), a
		inc	a
		ld	(ft.len), a
		ld	a, (blkcnt)	; Anzahl gelesener Blöcke (Import MSDOS	Bootdaten)
		srl	a
		srl	a
		ld	(ft.anz), a
		call	floppy		; Bootblock schreiben
		or	a
		jp	z, 0		; alles	ok, also zurück	ins CPM
		ld	(aSchreibfehlerF+10h), a
		ld	de, aSchreibfehlerF ; "Schreibfehler! \" \"\n\rfehlerhafter DOS-Bo"...
		ld	c, 9		; Zeichenkette ausgeben
		call	BDOS		; sonst	Fehlercode ausgeben
;
; 
;
form21:		ld	a, (aLeseFehler+0Fh)
		or	a
		jp	z, 0		; zurück ins CPM
		ld	de, aFehlerBeimForm ; "Fehler beim Formatieren!\r\n Verwenden Si"...
		ld	c, 9		; Zeichenkette ausgeben
		call	BDOS
		jp	0		; zurück ins CPM


;------------------------------------------------------------------------------
; Formatieren einer Spur 
; vgl. Format Kramer-MC
;------------------------------------------------------------------------------

fmtrk:
	IF CPMSYSTEM = 'ROBOTRON'
		ld	a,(dFDCZ2)
		out	(FDCZ),	a		; Motor an
	ENDIF

		ld	ix, (dttab)	; Adresse Sektorversatztabelle
		call	seek		; Spur einstellen
	; Aufbau ID-Tabelle fmtab
		ld	a, (EOT)	; Nummer des letzten Sektors der Spur (5..16)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
		add	a, a
		add	a, a		; A=4*A
		sub	1
		ld	b, 0
		ld	c, a
		ld	hl, fmtab+10	; freier Platz 10 Byte für Kommando
					; (5 würden reichen)
		add	hl, bc
		ld	a, (EOT)
		ld	c, a		; c= Anz. Sektoren
fmtrk1:		ld	a, (N)		; N relative Sektorlänge (2^N mit N=0..3, also 3-1024 Byte)
					; N - Byteanzahl je Datenblock
		ld	(hl), a
		dec	hl
		ld	a, (ix+0)	; R - Aufzeichnungsnummer, Blocknummer
		ld	(hl), a
		dec	hl
		ld	a, (HED)	; H Kopfnummer/Seite (0/1)
		ld	(hl), a
		dec	hl
		ld	a, (ft.trk)	; C - Spur
		ld	(hl), a
		inc	ix		; nächsten Sektorversatz
		dec	hl
		dec	c
		jr	nz, fmtrk1
	;	
		ld	a, (ft.trk)	; Anzahl Sektoren
fmtrk2:		cp	0		; field_6 (dieses Byte wird durch die Formatauswahl gepatcht)
		ld	a, 0E5h		; Zeichen 'leer' für CPM-Disketten
		jr	nc, fmtrk3	; kein Systemspur
		ld	a, 53h		; Zeichen 'leer' für Systemspuren
		; Voranstellen Kommando vor ID-Tabelle
		; hl = fmtab+10
fmtrk3:		ld	(hl), a		; Aufzuschreibendes Byte
		dec	hl
		ld	a, (GPL)	; Anzahl Lückenbytes in	GAP3
		ld	(hl), a		; Lücke 3
		dec	hl
		ld	a, (EOT)	; Nummer des letzten Sektors der Spur
		ld	(hl), a		; Sektoren/Spur
		dec	hl
		ld	a, (N)		; relative Sektorlänge (2^N mit	N=0..3,	also 1024 Byte)
		ld	(hl), a		; Bytes/Sektor
		dec	hl
		ld	a, (UNIT)	; Laufwerk
		and	3
		ld	b, a
		ld	a, (HED)	; Kopfnummer/Seite (0/1)
		rlca
		rlca
		or	b
		ld	(hl), a		; HDS/DS1/DS0
		dec	hl		; HL:=fmtab+5
		;
		ld	b, 6		; Anzahl Kommandobytes f. FDC (5+1)
		ld	c, 4Dh 		; Kommando Format a Track
		call	wcom1		; in FDC schreiben
		call	fmtrk4		; und ID-Tabelle schreiben
		
		;TC senden
	IF CPMSYSTEM = 'ROBOTRON'
		ld	a, (dFDCZ2)
		or	10h		; TC senden
		out	(FDCZ),	a
		xor	10h		; TC wieder auf low
		out	(FDCZ),	a
	ELSE
		out	(FDCZ),	a	; bei ROSSENDORF: TC senden
	ENDIF
		
		call	ErrorEval	; Fehlerauswertung
		or	a
		ret	z
		cp	'W'
		jp	nz, error	; Ausgabe Fehlermeldung, Abbruch
		call	error		; Ausgabe Fehlermeldung, Abbruch
		jp	0

;------------------------------------------------------------------------------
; Formatierschleife fuer eine Spur
; ID-Tabelle senden
;------------------------------------------------------------------------------

fmtrk4:		ld	c, DFDC
		ld	a, (EOT)	; Nummer des letzten Sektors der Spur
		add	a, a
		add	a, a
		ld	b, a		; B=4*A = Anzahl
fmtrk5:		in	a, (CFDC)
		rlca			; RQM-Test
		jr	nc, fmtrk5
		rlca			; DIO
		rlca			; NON-DMA
		ret	nc		; Fertig ?
		outi
		jr	nz, fmtrk5
		ret

;------------------------------------------------------------------------------
; Ausgabe Fehlermeldung, Abbruch
;------------------------------------------------------------------------------

error:		cp	'R'             ; Fehler "drive not ready"
		jr	z, error0
		ld	(aError+2), a
		ld	de, aError	; "   : ERROR$"
		ld	c, 9		; Zeichenkette ausgeben
		jp	5

error0:		ld	de, aDriveNotReady ; "Drive not ready\r\n$"
error1:		ld	c, 9		; Zeichenkette ausgeben
		call	BDOS
		jp	0

;------------------------------------------------------------------------------
;
;------------------------------------------------------------------------------

aBootblockdatei:db	"Bootblockdatei nicht vorhanden oder fehlerhaft!",0Ah,0Dh
		db	"Diskette einlegen!(ESC=ohne Bootblock): $"

aSchreibfehlerF:db	"Schreibfehler! ",22h," ",22h,0Ah,0Dh
		db	"fehlerhafter DOS-Bootblock!$"
blkcnt:		db	0		; Anzahl gelesener Blöcke (Import MSDOS	Bootdaten)
aSystemfehlerFa:db	"Systemfehler (falsches System)!",0Ah,0Dh,"$"
aFalscheLaufwer:db	"falsche Laufwerk-Parameter",0Ah,0Dh,"$"
aLeseFehler:	db	"  Lese-Fehler:  $"
aFehlerBeimForm:db	"Fehler beim Formatieren!",0Dh,0Ah
		db	" Verwenden Sie POWER (TEST)",0Dh,0Ah
		db	" zum Ueberpruefen der Diskette$"
aDriveNotReady:	db	"Drive not ready",0Dh,0Ah,"$"
		db	0
aError:		db	"   : ERROR$"
FormLW:		db	0		; zu formatierendes Laufwerk 0=A, 1=B

; ID-TABELLE
fmtab:		ds	50		; Ablage der Formatierungsinfo 
					; 4 Byte pro Sektor (N, R, H, C)

FCB:		db	0
		db	"BOOT720 DAT"
		ds	24
FCBend:		equ	$

rdbuff:		equ	$		; Lesebuffer bei verify
		ds	1400h		; 5 KByte
wrbuf:		equ	$		; Buffer für BOOT720.DAT


		end
