	TITLE 'Simple Format with FDC 0765'

; Testversion Laufwerk G

; MC80 Version 2.0
; 28.09.92

	;	Initial version
	;	DOUBLE density floppy only.

    ; Port Address Equates

	maclib ports

    ; Z80 macro library instruction definitions

	maclib z80

    ; common control characters

cr	equ 13
lf	equ 10
bell	equ 7

;**************************************************************
; Vereinbarungen
;**************************************************************

bdos	equ	5

p$765$cmd equ 0f4h
p$765$dat equ 0f5h
p$fdc$ctr equ 0f2h

ANZEI	EQU	0FF8EH
ANZLAE	EQU	18

;**************************************************************
; Programmstart
;**************************************************************

start:
	lxi	sp,stack
	lxi	d,msg1
	mvi	c,9
	call	bdos
;	LXI	H,FORM$MSG
;	LXI	D,ANZEI
;	LXI	B,ANZLAE
;	LDIR
	mvi	c,1
	call	bdos
	ani	0dfh
	sui	'G'
	jc	0
;	cpi	3

	cpi	1

	jnc	0
	sta	unit		; Laufwerk abspeichern G=0 .. I=2
xxx0:
;	lxi	h,formatk401-1
;	cpi	1
;	jrz	lw1sel
;	cpi	2
;	jrnz no80trk
	mvi	a,80
	sta	maxtrk
	xra	a
	sta	loopc
	lxi	h,formatk80-1
lw1sel:
	shld formatko
no80trk:
	call	ini765
	lxi	d,msganz
	mvi	c,9
	call	bdos
	mvi	a,0ffh
	sta	track	
loop:
	lda	unit
	ani	0fbh
	sta	unit		; reset HDS
	xra	a
	sta	head
	lda	track
	inr	a
	sta	track
	cpi	40
maxtrk equ $-1
	jz	forend
	call	seek
	call	anzeige
;
; Formatieren
;
	lxi	h,formlist
	mvi	b,5
	mvi	c,1
flistz:	lda	track
	mov	m,a		; Spur
	inx	h
	mvi	m,0		; Side
	inx	h
	mov	m,c		; Sector
	inx	h
	mvi	m,3		; Phys. Sektorlaenge
	inx	h
	inr	c
	djnz	flistz
	lxi	h,formatk400-1
formatko equ $-2
	lxi	b,0642h		; 6 Commandos
	di
	call	cmdfd1
	lxi	h,formlist
	lxi	b,1400h+p$765$dat

;**************************************************************
; Physical WRITE Entry non-DMA mode
;**************************************************************

	di
	call	wmfm
	lda	r$fdc$ctr
	setb	7,a
	out p$fdc$ctr		; Terminate Count
	res	7,a

;	nop
;	nop
;	nop

	out p$fdc$ctr		; reset TC
	EI			; Enable INT.
	call result		; Enter result phase
	jrnz error
	jr	loop
loopc equ $-1

;
; Formatieren Rueckseite
;
	lda unit
	ori 4			; set HDS
	sta unit
	mvi	a,1
	sta	head
	call	seek
	lxi	h,formlist
	mvi	b,5
	mvi	c,1
flistr:	lda	track
	mov	m,a		; Spur
	inx	h
	mvi	m,1		; Side
	inx	h
	mov	m,c		; Sector
	inx	h
	mvi	m,3		; Phys. Sektorlaenge
	inx	h
	inr	c
	djnz	flistr
	lxi	h,formatk80r-1
	lxi	b,0642h		; 6 Commandos
	di
	call	cmdfd1
	lxi	h,formlist
	lxi	b,1400h+p$765$dat

;**************************************************************
; Physical WRITE Entry non-DMA mode
;**************************************************************

	di
	call	wmfm
	lda	r$fdc$ctr
	setb	7,a
	out p$fdc$ctr		; Terminate Count
	res	7,a
	out p$fdc$ctr		; reset TC
	EI			; Enable INT.
	call result		; Enter result phase
	jz	loop

error:
	lxi	d,errmsg
	mvi	c,9
	call	bdos
forend:
	call	ini765
	xra	a
	out	p$fdc$ctr
	jmp	xxx0

wmfm:	in p$765$cmd
	rlc			; Bit 7 in Carry
	jrnc wmfm		; Request for Master ?
	rlc ! rlc
	rnc			; Execution mode ?
	ini
	dcx	h
	jnz wmfm		; repeat til done
wmfm1:	in p$765$cmd
	rlc			; Bit 7 in Carry
	jrnc wmfm1		; Request for Master ?
	rlc ! rlc
	rnc			; Execution mode ?
	ini
	dcx	h
	jnz wmfm1		; repeat til done
wmfm2:	in p$765$cmd
	rlc			; Bit 7 in Carry
	jrnc wmfm2		; Request for Master ?
	rlc ! rlc
	rnc			; Execution mode ?
	ini
	dcx	h
	jnz wmfm2		; repeat til done
wmfm3:	in p$765$cmd
	rlc			; Bit 7 in Carry
	jrnc wmfm3		; Request for Master ?
	rlc ! rlc
	rnc			; Execution mode ?
	ini
	dcx	h
	jnz wmfm3		; repeat til done
	ret


;
; Anzeige Read / Write
;
anzeige:
	LDA	track	; phys. Spur
	CALL	HEXASC
	SHLD	ANZTRK
	LXI	d,ANZEIG
	mvi	c,9
	jmp	bdos
;
; UNTERPROGRAMM FUR UMRECHNUNG HEX IN ASCII
;
HEXASC:
	MVI	L,'0'
HEXAS1:	sui	10
	JRC	HEXAS2
	INR	L
	JR	HEXAS1
HEXAS2:	ADI	'0'+10
	MOV	H,A
	RET
;
; ANZEIGEPUFFER LESE- / SCHREIBVORGANG
;
msg1:	db	0ch,0ah,'Insert Disk into Drive : ',24h
errmsg:	db	0dh,0ah,'Error during Formatting Track',0dh,0ah,'$'
msganz:	db	1bh,84h,80h,'Formatting Track :   $'
ANZEIG:	db	08h,08h
ANZTRK:	DB	'  $'
FORM$MSG:	DB	'F@O@R@M@A@T@7@6@5@'

formatk80:
;	db	2,3,5,100,0e5h
	db	0,3,5,100,0e5h

formatk80r:
;	db	6,3,5,100,0e5h
	db	4,3,5,100,0e5h
formatk400:
	db	0,3,5,100,0e5h
formatk401:
	db	1,3,5,100,0e5h
formlist:
	ds	20


;**************************************************************
; Floppy-Disk Interface using upD 765/P8282 Controller
;**************************************************************

ini765:	mvi	a,04h		; RESET FDC
	out	p$fdc$ctr
	nop
	nop
	nop
	xra	a
	out	p$fdc$ctr
	sta	r$fdc$ctr
ini765z:
	mvi b,0
ini765w:
	djnz ini765w		; delay
	in p$765$cmd ! cpi 80h	; request for master ?
	jrz specify		; no --> skip
	in p$765$dat		; else read data
	jr ini765z		; and try again

specify:
;	lxi h,spec5-1		; specify parameter
;	lda unit
;	cpi 2
;	jrc specify1
	lxi h,spec51-1
specify1:
	lxi b,0303h		; specify command parameter
	call cmdfd1		; send command

	call	recal
	; recalibrate drive to track zero
recal:
	lxi b,0207h		; Recal-cmd. =07 - 2 Byte
	call moto

	; sense drive interrupt status
sense:
	lxi b,0108h		; comd. =08 - 1 Byte
	call cmdfd
	call next		; fetch result
	mov b,a			; save it
	cpi 80h			; invalid cmd. ?
	cnz next		; no --> next result
	bit 5,b			; seek finnished ?
	jrz sense		; no --> loop back
	ret			; yes --> all done

;**************************************************************
; specify parameter for TEAC FD-55 B
;**************************************************************

; vorerst fuer 1.2-Laufwerke

spec5:
; Simon
;	db	1fh
;	db	03h
;	db	1bh

; Schiller
;	db	9fh
;	db	15h

; Kramer
	db	1fh		; xxxx=SRT xxxx=HUT
	db	33h		; xxxxxxx=HLT x=ND

spec51:	db	0e1h		; Werte von Loeber
;	db	03h
;	db	1101$1111B
	db	0001$0011B	; specify param. 5 1/4 TEAC B
				; HLT= 36 ms , HUT= 480 ms
				; SRT=  6 ms , NON-DMA MODE

;**************************************************************
; command table for upD 765
;**************************************************************

cmdtab:	db	046h		; MFM read command
unit:	db	0		; Head 0 / unit A
track:	db	0		; Track 0
head:	db	0		; Head 0
sector:	db	1		; Sector 1
N:	db	3		; N=3 1024 Bytes
EOT:	db	5		; EOT , 5 sectors per track
GPL:	db	25h		; GPL gap length
DTL:	db	-1		; DTL data terminal length

resltb:	ds	7		; result table for FDC
zdma:	ds	2		; current DMA-Address
r$fdc$ctr:
	db	0
motcot:
	db	0		; Time-counter for motor on

;**************************************************************
; sense drive status
;**************************************************************

sdrs:	lxi b,0204h		; SDRS-cmd. = 04 - 2 Bytes
	call cmdfd
	call next ! ret

;**************************************************************
; seek to track in A, drive in unit
;**************************************************************

seek:	
	lxi b,030fh		; SEEK-cmd. = 0F - 2 Bytes
	call moto
	jmp sense
;	call sense
;seekby:	in p$765$cmd
;	ani 0fh
;	jrnz seekby
;	ret

;**************************************************************
; motor off and select disk off
; calld by time-routine after 5 second
;**************************************************************

motoff:
	xra	a
	out	p$fdc$ctr
	sta	r$fdc$ctr
	ret

;**************************************************************
; motor on and select disk drive on
; wait until disk ready, then transmit cmd. in BC to FDC
;**************************************************************

moto:
	push b			; save cmd.
	lda	unit
	ani	03h
	ori	070h
	sta	r$fdc$ctr
moto1:	lda	r$fdc$ctr
	out p$fdc$ctr
	call sdrs ! bit 5,a	; Drive ready ?
	jrz moto1		; no --> Wait
	pop b

;**************************************************************
; Command to upD 765
; Transmitt command in BC to Floppy Disk Controller
; B=Number of Bytes to transmitt, C=command
;**************************************************************

cmdfd:	lxi h,cmdtab
cmdfd1:
	call delay			; wieder eingefuehrt
	in p$765$cmd
	ani 0c0h ! cpi 80h
	jrnz cmdfd1		; Request for Master ?
	mov a,c ! out p$765$dat	; send command
	inx h ! mov c,m
	djnz cmdfd1		; next command
	ret

;**************************************************************
; Verzoegerung fuer Statusflag 765
;**************************************************************

delay:	push b ! mvi b,0fh
delay1:	djnz delay1
	pop b ! ret

;**************************************************************
; next result
; read next result byte from FDC
;**************************************************************

next:
	call	delay		; wieder in Betrieb
	in p$765$cmd
	ani 0c0h ! cpi 0c0h
	jrnz next		; Request for Master ?
	in p$765$dat
	ret

;**************************************************************
; Fetch result from FDC
; check for R/W Errors, if any Z=0
;**************************************************************

result:	mvi b,6			; 7 results
	call next		; fetch it
	lxi h,resltb
	mov m,a			; store it
	ani 0c0h		;any Error in Status 0
	mov c,a
reslop:	call next
	inx h ! mov m,a
	djnz reslop
	mov a,c			; Error report Status 0
	ora a ! ret		; Return with Error in A

	ds	64
stack:
	end
