Example Program


	.Z80
	TITLE FDC TRACK READER
	ASEG
	ORG	100H

BDOS	EQU	5		; BDOS entry point

; Assumes FDC is at its standard I/O address

CMDREG	EQU	192		; Write: FDC Command register
STATREG	EQU	192		; Read:  FDC Status register
TRAKREG	EQU	193		; FDC Track register
SECTREG	EQU	194		; FDC Sector register
DATAREG	EQU	195		; FDC Data register
LATCH	EQU	200		; FDC board control latch

START:  LD	HL,FIN		; program end
	LD	DE,6300		; length of work space
CLEAR:  LD	A,0		; Clears work space
	LD	(HL),A
	INC	HL
	DEC	DE
	CP	D
	JR	NZ,CLEAR
	CP	E
	JR	NZ,CLEAR
; Select 8-inch when performing all seeks so that 3ms step
; rate can be achieved
	LD	A,94
	OUT	(LATCH),A	; Select DO,SO,DDEN, No ints,8-inch
	LD	A,8
	OUT	(CMDREG),A	; 'Restore' head to track 0
	CALL	WAIT		; Wait for ready
	LD	A,80
	OUT	(DATAREG),A	; Load data register with 80
	LD	A,24
	OUT	(CMDREG),A	; Make it 'seek' track 80
	CALL	WAIT		; WAIT until FDC ready
	LD	A,8
	OUT	(CMDREG),A	; 'Restore' it to track 0 again
	CALL	WAIT
	CALL	READ		; Read the track data
	JR	PRINT		; and print it out.

; Subroutine to wait for FDC ready

WAIT:	LD	B,6
WAIT1:  DJNZ	WAIT1		; Delay 12µs before status is valid
WAIT2:  IN	A,(STATREG)
	AND	1
	JR	NZ,WAIT2	; Wait until FDC is not busy
	RET

READ:	LD	HL,FIN
	LD	C,DATAREG
READY:  IN	A,(STATREG)	; Loop until drive is ready
	BIT	7,A
	JR	NZ,READY
				; When reading or writing to a sector
				; write the sector and track number to the
				; respective registers at this point
	LD	A,30		; Set to 3.5 or 5.25 drive
	OUT	(LATCH),A
	LD	A,228		; Read track command
	OUT	(CMDREG),A	; Initiate track read
	LD	B,6
DEL:	DJNZ	DEL		; Short delay

LOOP:	IN	A,(STATREG)	; Get status
	RRCA
	RET	NC		; return if finished (BUSY not set)
	RRCA
	JR	NC,LOOP		; If no data request then loop
	INI			; Read data to (HL) and inc HL
	JR	LOOP		; The timing of this loop is critical

; SAMPLE READ AND WRITE SECTOR ROUTINES

; Read a sector
; Call with A = xxxMxESx
; where: M = multiple sector flag
; E = 15ms delay flag
; S = side select flag
; This routine sets the remaining bits to a command
; compatible with all the WD279x series FDCs.

RDSEC:  AND	8EH
	OR	88H
	LD	C,DATAREG
	OUT	(CMDREG),A
	LD	B,6
RDEL:	DJNZ	RDEL
RLOOP:  IN	A,(STATREG)	; Get status
	RRCA
	RET	NC		; return if finished
	RRCA
	JR	NC,RLOOP	; If no data request then loop
	INI			; Read data to (HL) and inc HL
	JR	RLOOP		; The timing of this loop is critical



; write a sector
; call with A = xxxMxESx
; where: M = multiple sector flag
;	E = 15ms delay flag
;	s = side select flag
;	This routine sets the remaining bits to a command
;	compatible with all the WD279x series FDCs.

WRSEC:  AND	8EH
	OR	0A8H
	LD	C,DATAREG
	OUT	(CMDREG),A
	LD	B,6
WDEL:	DJNZ	WDEL
WLOOP:  IN	A,(STATREG)	; Get status
	RRCA
	RET	NC		; return if finished (busy not set)
	RRCA
	JR	NC,WLOOP	; If no data request then loop
	OUTI			; Write data from (HL) and inc (HL)




JR	WLOOP			; The timing of this loop is critical

				; END OF ROUTINES

PRINT:  LD	DE,6293		; The code from here onwards
LD	HL,FIN			; displays the read data (and 
NEXT:	LD	A,(HL)		; address markers etc.) from
	RRA			; memory in hex. on the screen.
	RRA
	RRA
	RRA
	AND	15
	LD	BC,TABLE
	PUSH	HL
	PUSH	DE
	LD	H,0
	LD	L,A
	ADD	HL, BC
	LD	E,(HL)
	LD	C,2
	CALL	5
	POP	DE
	POP	HL
	LD	A,(HL)
	AND	15
	LD	BC,TABLE
	PUSH	HL
	PUSH	DE
	LD	H,0
	LD	L,A
	ADD	HL,BC
	LD	E,(HL)
	LD	C,2

	CALL	BDOS
	LD	E,' '
	LD	C,2
	CALL	BDOS
	LD	E,' '
	LD	C,2
	CALL	BDOS
	POP	DE
	POP	HL
	INC	HL
	DEC	DE
	LD	A,D
	CP	0
	JR	NZ,NEXT
	LD	A,E
	CP	0
	JR	NZ,NEXT
	RET

TABLE:	DB	'0123456789ABCDEF'


FIN:
	END





Macros:

Symbols:
BDOS	0005	CLEAR	0106	CMDREG  00C0	DATARE  00C3
DEL	0153	FIN	01EB	LATCH	00C8	LOOP	0155
NEXT	0194	PRINT	018E	RDEL	016A	RDSEC	0160
READ	013E	READY	0143	RLQOP	016C	SECTRE  00C2
START	0100	STATRE  00C0	TABLE	01DB	TRAKRE  00C1
WAIT	0133	WAIT1	0135	WAIT2	0137	WDEL	0181
WLOOP	0183	WRSEC	0177

No  Fatal error(s)