FASTCO ;		* * * * * * * * * * * * *
 ;		*  Program by Kim Watt  *
 ;		* Breeze Computing Inc. *
 ;		*     P.O. Box  1013    *
 ;		* Berkley, Mich.  48072 *
 ;		*    (313)  288-9422    *
 ;		* * * * * * * * * * * * *
 ;
 ;
 ;
 	ORG	5000H
 STACK	EQU	4F00H		;BELOW PROGRAM
 SRCDR	DEFB	1		;SOURCE DRIVE 0
 DESDR1	DEFB	2		;DESTINATION DRIVE 1
 DESDR2	DEFB	0FFH		;DESTINATION DRIVE 2
 DESDR3	DEFB	0FFH		;DESTINATION DRIVE 3
 TRACKS	DEFB	35		;# OF TRACKS
 TRAK	DEFB	00H		;CURRENT TRACK
 DRIVE	DEFB	0		;WORKING DRIVE
 MARK	DEFS	10		;ADDRESS MARKS FOR 10 SEC
 ;  USE 01H FOR FAST STEPPER ON RESTORE
 RESTOR	DEFB	0BH		;RESTORE BYTE
 READ	DEFB	88H		;READ SECTOR BYTE
 WRITE	DEFB	0F4H		;WRITE TRACK BYTE
 ;  USE 11H FOR FAST STEPPER ON SEEK
 SEEK	DEFB	1BH		;SEEK BYTE
 STEPIN	DEFB	5BH		;STEP IN BYTE
 ;  FOLLOWING IS A TRACK LOCKOUT TABLE. 0 = COPY, FF = NO
 ;	LOCKED OUT TRACKS WILL NOT BE FORMATTED
 LOCK	DEFW	00H	;1,0
 	DEFW	00H	;3,2
 	DEFW	00H	;5,4
 	DEFW	00H	;7,6
 	DEFW	00H	;9,8
 	DEFW	00H	;11,10
 	DEFW	00H	;13,12
 	DEFW	00H	;15,14
 	DEFW	00H	;17,16
 	DEFW	00H	;19,18
 	DEFW	00H	;21,20
 	DEFW	00H	;23,22
 	DEFW	00H	;25,24
 	DEFW	00H	;27,26
 	DEFW	00H	;29,28
 	DEFW	00H	;31,30
 	DEFW	00H	;33,32
 	DEFW	0FF00H	;35,34
 	DEFW	0FFFFH	;37,36
 	DEFW	0FFFFH	;39,38
 ;  ORDER THAT SECTORS ARE WRITTEN IN TRACK
 ORDER	DEFB	0
 	DEFB	5
 	DEFB	1
 	DEFB	6
 	DEFB	2
 	DEFB	7
 	DEFB	3
 	DEFB	8
 	DEFB	4
 	DEFB	9
 	DEFB	0FFH		;TERMINATOR
 COPY	CALL	STATCK		;CHECK STATUS & RESTORE
 	LD	HL,TRAK		;CURRENT COPY TRACK
 	LD	(HL),0		;START WITH TRACK 0
 	CALL	DISPLY
 	DEFW	0D0DH
 	DEFM	'      '
 	DEFB	0
 	CALL	GOFMT		;FORMAT ALL DISKS FIRST
 	LD	HL,TRAK		;POINT TO CURRENT TRACK
 	LD	(HL),0		;MAKE IT ZERO
 	CALL	DISPLY		;SEPARATE DISPLAYS
 	DEFW	0D0DH
 	DEFM	'      '
 	DEFB	0
 COPYLP	CALL	READTR		;READ TRACK INTO BUFFER
 	CALL	WRITTR		;FORMAT & WRITE TRACK
 	LD	HL,TRAK		;POINT TO CURRENT TRACK
 	INC	(HL)		;ADD ONE MORE
 	LD	A,(TRACKS)	;GET # OF TRACKS TO COPY
 	CP	(HL)		;END ?
 	JR	NC,COPYLP	;TRY SOME MORE
 ;  COPY NOW DONE
 	CALL	1C9H		;CLEAR SCREEN
 	CALL	DISPLY
 	DEFM	'Full Diskette Copy Done !'
 	DEFW	0D0DH
 	DEFM	'<E>xit program or <R>estart ? '
 	DEFB	0
 KYTEST	LD	A,(3801H)	;KEYBOARD MEMORY
 	CP	32		;	E ?
 	JP	Z,0		;REBOOT
 	LD	A,(3804H)	;KEYBOARD MEMORY
 	CP	4		;	R ?
 	JR	NZ,KYTEST	;WAIT SOME MORE
 ENTRY	DI			;DISABLE INTERRUPTS
 	LD	SP,STACK	;BELOW PROGRAM
 	CALL	1C9H		;CLEAR SCREEN
 	CALL	DISPLY
 	DEFM	'-BREEZE SPECIAL COPY UTILITY-'
 	DEFW	0D0DH
 	DEFM	'Program by Kim Watt'
 	DEFB	0DH
 	DEFM	'Copyright (C) 1980'
 	DEFB	0DH
 	DEFM	'Breeze Computing Inc.'
 	DEFB	0DH
 	DEFM	'P.O. Box 1013'
 	DEFB	0DH
 	DEFM	'Berkley, Mich.  48072'
 	DEFB	0DH
 	DEFM	'(313) 288-9422'
 	DEFW	0D0DH
 	DEFM	'Press <ENTER> to begin ! '
 	DEFB	0
 	LD	BC,0
 	CALL	60H
 	CALL	ENTRWT		;WAIT FOR ENTER KEY
 	CALL	1C9H		;CLEAR SCREEN
 	CALL	DISPLY		;PROMPT
 	DEFM	'SOURCE DISK to be mounted on DRIVE '
 	DEFB	0
 	LD	A,(SRCDR)	;GET SOURCE DRIVE
 	CALL	FIXBIT		;CONVERT TO ASCII
 	CALL	33H		;DISPLAY BYTE
 	CALL	DISPLY
 	DEFB	0DH
 	DEFM	'DESTINATION DISK to be mounted on DRIVE(S) '
 	DEFB	0
 	LD	A,(DESDR1)	;GET DESTINATION DRIVE 1
 	CALL	FIXBIT		;CONVERT TO ASCII
 	CALL	33H		;DISPLAY BYTE
 	LD	A,(DESDR2)	;GET DESTINATION DRIVE 2
 	CP	0FFH		;NOT THIS ONE IF 0FFH
 	JR	Z,NOMORE
 	PUSH	AF
 	LD	A,','		;WRITE A COMMA
 	CALL	33H
 	POP	AF
 	CALL	FIXBIT		;ADJUST TO ASCII
 	CALL	33H
 	LD	A,(DESDR3)	;GET DESTINATION DRIVE 3
 	CP	0FFH
 	JR	Z,NOMORE
 	PUSH	AF
 	LD	A,','		;WRITE A COMMA
 	CALL	33H
 	POP	AF
 	CALL	FIXBIT
 	CALL	33H
 NOMORE	CALL	DISPLY		;PROMPT
 	DEFW	0D0DH
 	DEFM	'Press <ENTER> when all disks mounted ! '
 	DEFB	0
 	LD	BC,0
 	CALL	60H
 	CALL	ENTRWT		;WAIT FOR ENTER KEY
 	JP	COPY		;DO COPY
 ENTRWT	LD	A,(3840H)	;KEYBOARD MEMORY
 	CP	1		;	ENTER ?
 	JR	NZ,ENTRWT	;SCAN SOME MORE
 	RET			;DONE
 FIXBIT	LD	B,0		;COUNTER
 	OR	A		;RESET CARRY FLAG
 FIXMLP	RRCA			;SHIFT OUT BIT 1
 	JR	C,FIXDON	;FOUND THE BIT
 	INC	B		;NEXT DRIVE
 	JR	FIXMLP		;TRY AGAIN
 FIXDON	LD	A,B		;PASS BACK TO ACCUM
 	ADD	A,30H		;ADD ASCII
 	RET			;DONE
 READTR	LD	A,(TRAK)	;GET CURRENT TRACK
 	LD	E,A
 	LD	D,0		;DE CONTAINS TRACK
 	LD	HL,LOCK		;LOCKOUT TABLE
 	ADD	HL,DE		;POINT TO CURRENT BYTE
 	LD	A,(HL)		;GET THE BYTE
 	OR	A		;SET FLAGS
 	JP	NZ,PASSIT	;NZ = SKIP TRACK
 	JP	READEM		;READ 10 SECTORS
 MOVE	CALL	DISPLY
 	DEFB	0DH
 	DEFM	'<E>xit or <R>estart ? '
 	DEFB	0
 	JP	KYTEST
 FILLFF	LD	C,0FFH		;FILL BYTE
 FILL	CALL	FILL1
 	DJNZ	FILL
 	RET
 FILL1	LD	(IX),C		;PUT INTO BUFFER
 	INC	IX		;BUMP IT
 	RET			;THAT'S ALL
 SELECT	LD	(37E1H),A	;SELECT DRIVE
 	RET			;THAT'S ALL
 DISPLY	POP	DE		;POINT TO DATA
 DISLP	LD	HL,(4020H)	;GET CURSOR POSITION
 	LD	A,(DE)		;GET A BYTE
 	INC	DE		;POINT TO NEXT
 	OR	A		;SET FLAGS
 	JR	Z,DISDN		;TERMINATOR
 	CP	0DH		;CARRIAGE RETURN ?
 	JR	Z,CARRET	;DO IT
 	LD	(HL),A		;WRITE BYTE
 	CP	(HL)		;IS IT STILL THERE ?
 	JR	Z,NDSID		;LOWERCASE INSTALLED
 	SUB	20H		;REMOVE LOWER CASE
 	LD	(HL),A		;PUT IT BACK
 NDSID	INC	HL		;POINT TO NEXT
 	LD	(4020H),HL	;UPDATE CURSOR
 	JR	DISLP		;DO SOME MORE
 CARRET	EXX
 	LD	A,0DH
 	CALL	33H
 	EXX
 	JR	DISLP		;KEEP GOING
 DISDN	PUSH	DE		;SAVE RETURN ADDRESS
 	RET			;GO TO IT
 ;  CHECK DISK STATUS & RESTORE ALL DRIVES
 STATCK	LD	A,(SRCDR)	;GET SOURCE DRIVE
 	LD	B,0		;DON'T CHECK WRITE PROT.
 	CALL	CHEKIT		;CHECK STATUS & RESTORE
 	LD	A,(DESDR1)	;DESTINATION DRIVE 1
 	LD	B,1		;DO CHECK WRITE PROTECT
 	CALL	CHEKIT
 	LD	A,(DESDR2)	;DESTINATION DRIVE 2
 	OR	A		;FLAGS SET
 	RET	NZ		;INACTIVE UNLESS 0
 	LD	B,1
 	CALL	CHEKIT
 	LD	A,(DESDR3)	;DEST. DRIVE 3
 	OR	A		;FLAGS
 	RET	NZ		;INACTIVE
 	LD	B,1		;CHECK WRITE PROT.
 	CALL	CHEKIT		;CHECK IT OUT
 	RET			;ALL DONE
 CHEKIT	LD	(DRIVE),A	;SAVE DRIVE
 	CALL	SELECT		;SELECT IT
 	PUSH	AF		;SAVE DRIVE ON STACK
 	PUSH	BC
 	LD	BC,0		;WAIT 1 SECOND
 	CALL	60H		;ROM DELAY LOOP
 	POP	BC		;RESTORE FLAG
 	DEC	B		;CHECK WRITE PROT ?
 	JR	Z,CHEKYS	;YES
 	CALL	CHECK1		;SKIP READ PROTECT
 	JR	CKOK
 CHEKYS	CALL	CHECK		;WRITE PROTECTED ?
 CKOK	POP	AF		;GET DRIVE BACK
 	CALL	SELECT		;RESELECT IT
 	LD	E,A		;SAVE DRIVE HERE
 	LD	A,(RESTOR)	;GET RESTORE BYTE
 	LD	(37ECH),A	;PERFORM
 	LD	BC,0		;WAIT ANOTHER SECOND
 	CALL	60H
 CHEKWT	LD	A,E		;GET DRIVE BACK
 	CALL	SELECT		;KEEP RESELECTING
 	LD	A,(37ECH)	;GET STATUS BYTE
 	RRCA			;SHIFT OUT BUSY BIT
 	JR	C,CHEKWT	;WAIT TILL DONE
 	RET			;DONE WITH RESTORE
 CHECK	LD	A,(37ECH)	;GET STATUS BYTE
 	LD	HL,NOTRDY
 	BIT	7,A
 	JP	NZ,ERROR
 	LD	HL,WRPTC
 	BIT	6,A		;WRITE PROTECTED ?
 	JP	NZ,ERROR	;CAN'T HAVE THAT !
 CHECK1	LD	A,(37ECH)
 	LD	HL,NOTRDY
 	BIT	7,A		;DRIVE NOT READY ?
 	JP	NZ,ERROR
 	LD	BC,00CDH	;TIME LOOP
 	LD	HL,NOSYS
 LOOPAA	DEC	BC		;REDUCE COUNT
 	LD	A,B
 	OR	C		;ANY BITS ON ?
 	JP	Z,ERROR		;NO SYSTEM IN DRIVE
 	LD	A,(37ECH)
 	AND	02H		;BIT 1
 	JR	NZ,LOOPAA	;WAIT SOME MORE
 	LD	BC,199DH
 	LD	HL,NODOOR
 LOOPAB	DEC	BC
 	LD	A,B
 	OR	C
 	JP	Z,ERROR
 	LD	A,(37ECH)
 	AND	02H
 	JR	Z,LOOPAB	;READY TO NOT READY ?
 	LD	DE,0
 	LD	BC,00BAH
 	LD	HL,NODISK	;NO DISK IN DRIVE ?
 LOOPAC	DEC	BC
 	LD	A,B
 	OR	C
 	JP	Z,ERROR
 	INC	DE		;DIAGNOSTIC COUNTER
 	LD	A,(37ECH)
 	AND	02H
 	JR	NZ,LOOPAC
 	LD	BC,1720H
 	LD	HL,NODOOR	;DOOR NOT CLOSED ?
 LOOPAD	DEC	BC
 	LD	A,B
 	OR	C
 	JP	Z,ERROR
 	INC	DE
 	LD	A,(37ECH)
 	AND	02H
 	JR	Z,LOOPAD
 	LD	HL,0EACBH
 	ADD	HL,DE
 	LD	HL,HARDSC	;HARD SECTORED DISK ?
 	JP	NC,ERROR
 	RET			;ALL DONE
 NOTRDY	DEFW	0D0DH
 	DEFM	'Drive is NOT READY.'
 	DEFB	0
 NOTINS	DEFW	0D0DH
 	DEFM	'Drive NOT IN SYSTEM.'
 	DEFB	0
 NOSYS	DEFW	0D0DH
 	DEFM	'NO SYSTEM in drive.'
 	DEFB	0
 NODOOR	DEFW	0D0DH
 	DEFM	'DOOR not closed.'
 	DEFB	0
 NODISK	DEFW	0D0DH
 	DEFM	'NO DISK in drive.'
 	DEFB	0
 HARDSC	DEFW	0D0DH
 	DEFM	'Disk is HARD SECTORED and unusable.'
 	DEFB	0
 WRPTC	DEFW	0D0DH
 	DEFM	'Destination disk is WRITE PROTECTED.'
 	DEFB	0
 ERROR	CALL	ERSHOW		;DISPLAY ERROR
 	CALL	DISPLY
 	DEFW	0D0DH
 	DEFM	'Press <ENTER> when condition has been'
 	DEFM	' corrected ! '
 	DEFB	0
 	CALL	ENTRWT		;WAIT FOR ENTER KEY
 	JP	ENTRY		;START OVER
 ERSHOW	LD	A,(HL)		;GET A BYTE
 	OR	A
 	INC	HL		;POINT TO NEXT
 	RET	Z
 	CALL	33H
 	JR	ERSHOW
 WRITTR	LD	A,(DESDR1)	;GET FIRST DESTIN. DR.
 	CALL	WRITES		;WRITE 10 SECTORS
 	LD	A,(DESDR2)	;GET NEXT DEST. DRIVE
 	OR	A		;FLAGS
 	RET	NZ		;NZ=SKIP
 	CALL	WRITES
 	LD	A,(DESDR3)
 	OR	A
 	RET	NZ
 	CALL	WRITES
 	RET			;DONE WITH ALL DRIVES
 FORMAT	PUSH	IX		;MUST SAVE
 	CALL	FIXFMT		;SET UP BUFFER
 	POP	IX		;RESTORE IT
 	LD	A,(DRIVE)	;GET DRIVE
 	CALL	SELECT		;SELECT IT
 	LD	BC,BUFFER	;FORMAT BUFFER
 	LD	DE,37EFH	;DATA TRANSFER ADDRESS
 	LD	HL,37ECH	;COMMAND REGISTER
 	LD	A,(WRITE)	;GET FORMAT BYTE
 	LD	(HL),A		;GIVE TO CONTROLLER
 	PUSH	AF
 	POP	AF
 	PUSH	AF
 	POP	AF
 	JR	FMTBZ		;TEST BUSY
 BZFMT	RRCA			;SHIFT BIT 0
 	JR	NC,FMTDON	;DONE WITH WRITE
 FMTBZ	LD	A,(HL)		;GET STATUS BYTE
 	BIT	1,A		;READY FOR DATA ?
 	JR	Z,BZFMT		;WAIT SOME MORE
 	LD	A,(BC)		;GET BYTE FROM BUFFER
 	LD	(DE),A		;GIVE TO CONTROLLER
 	INC	BC		;POINT TO NEXT BYTE
 	JR	FMTBZ		;WAIT FOR NEXT READY
 FMTDON	LD	A,(HL)		;CLEAR LATCH
 	RET			;DONE
 STEP	LD	A,(DRIVE)	;CURRENT WORKING DRIVE
 	CALL	SELECT		;SELECT IT
 	LD	A,(STEPIN)	;GET STEP IN BYTE
 	LD	HL,37ECH	;COMMAND/STATUS REGISTER
 	LD	(HL),A		;DO IT
 	PUSH	AF		;WAIT 12 MS.
 	POP	AF
 	PUSH	AF
 	POP	AF
 STPWAT	LD	A,(DRIVE)	;DRIVE
 	CALL	SELECT		;KEEP RESELECTING
 	LD	A,(HL)		;GET STATUS BYTE
 	BIT	0,A		;COMMAND IN PROGRESS ?
 	JR	NZ,STPWAT
 	BIT	2,A		;POSITIONED OVER 0 ?
 	JP	NZ,FMERR	;FORMAT ERROR
 	BIT	7,A		;NOT READY
 	JP	NZ,FMERR
 	RET			;DONE WITH IT ALL
 PASSIT	POP	HL		;POP RETURN ADDRESS
 	INC	HL		;SKIP OVER WRITE COMMAND
 	INC	HL
 	INC	HL
 	JP	(HL)		;GO BACK
 FIXFMT	LD	IX,BUFFER	;POINT TO BUFFER
 	LD	DE,ORDER	;SECTOR ORDER
 	LD	B,0EH		;POST INDEX GAP
 	CALL	FILLFF		;FILL WITH 0FFH'S
 FIXLP	LD	B,6		;SYNC FIELD
 	LD	C,0		;ALL BITS RESET
 	CALL	FILL
 	LD	C,0FEH		;ID ADDRESS MARK
 	CALL	FILL1
 	LD	A,(TRAK)	;GET TRACK
 	LD	C,A
 	CALL	FILL1
 	LD	C,0		;HEAD # (1 IF 2 SIDED)
 	CALL	FILL1
 	LD	A,(DE)		;GET SECTOR
 	LD	C,A
 	CALL	FILL1
 	LD	C,1		;SECTOR SIZE (256 BYTES)
 	CALL	FILL1
 	LD	C,0F7H		;CRC GENERATOR BYTE
 	CALL	FILL1
 	LD	C,0FFH		;POST INDEX GAP
 	CALL	FILL1
 	LD	B,0BH
 	CALL	FILLFF
 	LD	B,6		;SYNC FIELD
 	LD	C,0		;ALL BITS OFF
 	CALL	FILL
 	LD	C,0F9H		;DATA MARK
 	CALL	FILL1
 	LD	B,0		;256 BYTES OF DATA
 	LD	C,0E5H		;FILL BYTE
 	CALL	FILL
 	LD	C,0F7H		;GENERATE CRC CHARS.
 	CALL	FILL1
 	LD	C,0FFH		;POST DATA GAP
 	CALL	FILL1
 	LD	B,0BH
 	CALL	FILLFF
 	INC	DE		;POINT TO NEXT BYTE
 	LD	A,(DE)		;GET NEXT BYTE
 	INC	A		;TERMINATOR ? (0FFH)
 	JR	NZ,FIXLP	;DO NEXT SECTOR
 	LD	B,58H		;END OF TRACK GAP
 	CALL	FILLFF		;FILL WITH 0FFH
 	RET			;BUFFER ALL SET TO GO
 ;  ROUTINE TO READ MULTIPLE SECTORS INTO RAM
 READEM	LD	A,(TRAK)	;GET TRACK
 	LD	D,A
 	LD	IX,MARK		;ID ADDRESS TABLE
 	LD	BC,SECBUF	;I/O BUFFER
 	LD	HL,10		;10 SECTORS TO READ
 	LD	E,0		;START WITH SECTOR 0
 	LD	A,(SRCDR)	;GET SOURCE DRIVE
 	CALL	SELECT		;SELECT IT
 READLP	PUSH	HL		;SAVE COUNT
 	CALL	READ2		;READ ONE SECTOR
 	JP	NZ,RDERR	;READ ERROR AFTER 2 TRIES
 	POP	HL		;GET COUNT BACK
 	INC	E		;NEXT SECTOR
 	INC	IX		;NEXT ID MARK
 	DEC	L		;REDUCE COUNT
 	JR	NZ,READLP	;DO NEXT SECTOR
 	LD	B,10		;FIX ID ADDRESS MARKS
 	LD	IX,MARK		;POINT TO 'EM
 REPLP	LD	A,(IX)		;GET A BYTE
 	AND	60H		;KEEP BITS 5 & 6 ONLY
 	RRA			;SHIFT TO LOWER 2 BITS
 	RRA
 	RRA
 	RRA
 	RRA
 	OR	0A8H		;MAKE A WRITE BYTE
 	LD	(IX),A		;GIVE IT BACK
 	INC	IX		;POINT TO NEXT
 	DJNZ	REPLP		;DO IT 10 TIMES
 	RET			;DONE
 READ2	PUSH	BC		;SAVE LOAD ADDRESS
 	CALL	READ1		;READ IT ONE TIME
 	POP	HL		;LOAD ADDRESS INTO HL
 	RET	Z		;SUCCESSFUL AFTER 1 TRY
 	LD	B,H		;RESET LOAD ADDRESS
 	LD	C,L		;	INTO BC
 READ1	PUSH	DE
 	PUSH	HL
 	PUSH	BC
 	LD	A,D
 	CALL	HEXCV		;CONVERT TO ASCII
 	LD	(RTR),BC
 	LD	A,E
 	ADD	A,30H
 	LD	(RSC),A
 	EXX
 	LD	A,1DH		;BEGINNING OF LINE
 	CALL	33H		;DO IT
 	EXX
 	CALL	DISPLY
 	DEFM	'Reading Track '
 RTR	DEFM	'00, Sector '
 RSC	DEFM	'0.'
 	DEFB	0
 	POP	BC
 	POP	HL
 	POP	DE
 	LD	A,(SRCDR)	;GET SOURCE DRIVE
 	LD	(37EEH),DE	;TRACK/SECTOR
 	LD	HL,37ECH	;COMMAND REGISTER
 	LD	(HL),1BH	;PASS TO CONTROLLER
 	PUSH	AF		;8 MS DELAY
 	POP	AF
 	PUSH	AF
 	POP	AF
 READBZ	LD	A,(HL)		;GET STATUS BYTE
 	RRCA			;SHIFT BUSY BIT
 	JR	C,READBZ	;NOT FOUND YET
 	LD	(HL),88H	;PASS TO CONTROLLER
 	PUSH	DE		;SAVE TRACK/SECTOR
 	LD	DE,37EFH	;DATA TRANSFER ADDRESS
 	PUSH	BC		;4 MORE MS DELAY
 	POP	BC
 	JR	RDTEST		;READ TEST
 RDDONE	RRCA			;SHIFT COMMAND DONE BIT
 	JR	NC,READOK	;NOT SET = DONE
 RDTEST	LD	A,(HL)		;GET STATUS
 	BIT	1,A		;VALID DATA PRESENT ?
 	JR	Z,RDDONE	;IS READ DONE ?
 	LD	A,(DE)		;GET THE VALID BYTE
 	LD	(BC),A		;PUT INTO LOAD BUFFER
 	INC	BC		;POINT TO NEXT
 	JR	RDTEST		;ANY MORE DATA ?
 READOK	LD	A,(HL)		;GET STATUS/RESET LATCH
 	LD	(IX),A		;SAVE FOR LATER
 	AND	5CH		;SET STATUS FLAGS
 	POP	DE		;RESTORE TRK/SEC
 	RET			;Z FLAG IS RESET/ERROR
 ;  ROUTINE TO WRITE DISK SECTORS
 WRITES	LD	(DRIVE),A	;PASS DRIVE
 	CALL	SELECT		;SELECT IT
 	LD	A,(TRAK)	;GET CURRENT TRACK
 	LD	D,A		;INTO D
 	LD	IX,MARK		;ID ADDRESS MARK
 	LD	BC,SECBUF	;I/O BUFFER
 	LD	HL,10		;10 SECTORS
 	LD	E,0		;START WITH SECTOR 0
 WRLOOP	PUSH	HL		;SAVE COUNT
 	CALL	WRITE2		;2 TRIES
 	POP	HL		;RESTORE COUNT
 	JP	NZ,WRERR	;WRITE ERROR
 	INC	E		;NEXT SECTOR
 	INC	IX		;NEXT ID MARKER
 	DEC	L		;REDUCE COUNT
 	LD	A,(TRAK)	;GET TRACK
 	LD	D,A		;GIVE IT TO D
 	JR	NZ,WRLOOP	;GO SOME MORE
 	RET			;DONE WITH ROUTINE
 WRITE2	PUSH	BC		;SAVE LOAD ADDRESS
 	CALL	WRITE1		;TRY IT ONCE
 	POP	HL		;LOAD ADDRESS
 	RET	Z		;GOOD AFTER 1 TRY
 	LD	B,H		;RESET LOAD ADDRESS
 	LD	C,L
 WRITE1	PUSH	DE
 	PUSH	HL
 	PUSH	BC
 	LD	A,D		;GET TRACK
 	CALL	HEXCV		;MAKE IT ASCII
 	LD	(WTR),BC
 	LD	A,E
 	ADD	A,30H		;ADJUST TO ASCII
 	LD	(WSR),A
 	EXX
 	LD	A,1DH		;BEGINNING OF LINE
 	CALL	33H
 	EXX
 	CALL	DISPLY
 	DEFM	'Writing Track '
 WTR	DEFM	'00, Sector '
 WSR	DEFM	'0.'
 	DEFB	0
 	POP	BC
 	POP	HL
 	POP	DE
 	LD	(37EEH),DE	;TRACK/SECTOR
 	CALL	SELECT
 	LD	HL,37ECH	;COMMAND REGISTER
 	LD	(HL),1BH	;PASS TO CONTROLLER
 	PUSH	BC		;10 MS. DELAY
 	POP	BC
 	PUSH	BC
 	POP	BC
 WRBZ	LD	A,(HL)		;GET STATUS BYTE
 	RRCA			;SHIFT OUT BUSY BIT
 	JR	C,WRBZ		;WAIT SOME MORE
 	LD	A,(IX)		;GET WRITE ID BYTE
 	LD	(HL),A		;PERFORM MACRO
 	PUSH	DE		;SAVE TRACK/SECTOR
 	LD	DE,37EFH	;DATA TRANSFER ADDRESS
 	PUSH	BC		;SMALL DELAY
 	POP	BC
 	PUSH	BC
 	POP	BC
 	JR	WRTST		;START TRANSFER
 TSTWR	RRCA			;BIT 0 SET ?
 	JR	NC,WROK
 WRTST	LD	A,(HL)		;GET STATUS BYTE
 	BIT	1,A		;READY FOR DATA ?
 	JR	Z,TSTWR		;WAIT SOME MORE
 	LD	A,(BC)		;GET ONE BYTE
 	LD	(DE),A		;PUT INTO CONTROLLER REG
 	INC	BC		;BUMP POINTER
 	JR	WRTST		;ANY MORE ?
 WROK	LD	A,(HL)		;GET STATUS/RESET LATCH
 	AND	7CH		;DATA LOST ?
 	POP	DE		;RESTORE STACK
 	RET	Z		;DONE
 	LD	(HL),0D0H	;FORCE INTERRUPT
 	RET			;DONE NOW
 HEXCV	LD	C,30H
 HEXCV1	SUB	0AH
 	JR	C,HEXCV2
 	INC	C
 	JR	HEXCV1
 HEXCV2	ADD	A,3AH
 	LD	B,A
 	RET
 GOFMT	LD	A,(DESDR1)	;DESTINATION DRIVE 1
 	CALL	DOFORM
 	LD	A,(DESDR2)	;DEST. DRIVE 2
 	OR	A
 	CALL	Z,DOFORM
 	LD	A,(DESDR3)
 	OR	A
 	CALL	Z,DOFORM
 	RET
 DOFORM	LD	(DRIVE),A	;SAVE DRIVE
 	LD	IY,LOCK		;LOCKOUT TABLE
 	LD	HL,TRAK
 	LD	(HL),0		;CURRENT TRACK
 FORMLP	LD	A,(TRAK)	;GET CURRENT TRACK
 	LD	HL,TRACKS	;TOTAL NUMBER
 	CP	(HL)		;SAME ?
 	JP	Z,FMTBYE	;DONE FORMAT, RESTORE
 	LD	A,(IY)		;GET LOCKOUT BYTE
 	OR	A		;FLAGS
 	JP	NZ,SKIP		;SKIP THAT ONE
 	LD	A,(TRAK)	;GET TRACK BACK
 	CALL	HEXCV		;MAKE IT ASCII
 	LD	(FMOOTR),BC
 	EXX
 	LD	A,1DH
 	CALL	33H
 	EXX
 	CALL	DISPLY
 	DEFM	'Formatting Track '
 FMOOTR	DEFM	'00.'
 	DEFB	0
 	CALL	FORMAT		;FORMAT THE TRACK
 SKIP	CALL	STEP		;STEP IN TO NEXT TRACK
 	LD	HL,TRAK		;POINT TO TRACK
 	INC	(HL)		;ADD ONE MORE
 	INC	IY		;NEXT LOCKOUT BYTE
 	JP	FORMLP		;DO SOME MORE
 WMSG1	DEFB	0DH
 	DEFM	'Drive NOT READY ! '
 	DEFB	0
 WMSG2	DEFB	0DH
 	DEFM	'Diskette WRITE PROTECTED ! '
 	DEFB	0
 WMSG3	DEFB	0DH
 	DEFM	'Write fault from drive ! '
 	DEFB	0
 WMSG4	DEFB	0DH
 	DEFM	'Sector NOT FOUND ! '
 	DEFB	0
 WMSG5	DEFB	0DH
 	DEFM	'DATA LOST during write operation ! '
 	DEFB	0
 WMSG6	DEFB	0DH
 	DEFM	'UNKNOWN ERROR occured during write ! '
 	DEFB	0
 WRERR	LD	HL,WMSG1
 	BIT	7,A		;DRIVE NOT READY
 	JR	NZ,WEONE
 	BIT	6,A		;WRITE PROTECTED
 	LD	HL,WMSG2
 	JR	NZ,WEONE
 	BIT	5,A		;FROM DRIVE
 	LD	HL,WMSG3
 	JR	NZ,WEONE
 	BIT	4,A		;SEC NOT FOUND
 	LD	HL,WMSG4
 	JR	NZ,WEONE
 	BIT	2,A		;DATA LOST
 	LD	HL,WMSG5
 	JR	NZ,WEONE
 	LD	HL,WMSG6
 WEONE	CALL	ERSHOW		;SHOW ERROR MESSAGE
 	JP	MOVE
 RDERR	LD	HL,RDMSG
 	CALL	ERSHOW
 	JP	MOVE
 WRMSG	DEFW	0D0DH
 	DEFM	'WRITE ERROR has occured ! '
 	DEFB	0
 RDMSG	DEFW	0D0DH
 	DEFM	'READ ERROR has occured ! '
 	DEFB	0
 FMERR	LD	HL,FMMSG
 	CALL	ERSHOW
 	JP	MOVE
 FMMSG	DEFW	0D0DH
 	DEFM	'FORMAT ERROR has occured ! '
 	DEFB	0
 FMTBYE	LD	A,(DRIVE)	;GET WORKING DRIVE
 	CALL	SELECT		;SELECT IT
 	LD	A,(RESTOR)	;GET RESTORE BYTE
 	LD	(37ECH),A	;PERFORM
 	LD	BC,0		;WAIT 1 SECOND
 	CALL	60H
 BYEWT	LD	A,(DRIVE)
 	CALL	SELECT
 	LD	A,(37ECH)
 	RRCA
 	JR	C,BYEWT
 	RET
 SECBUF	DEFS	2560		;10 SECTOR I/O BUFFER
 BUFFER	DEFB	0		;TILL END OF MEMORY
 	END	ENTRY
 	LD	BC,0		;WAIT 1 SECO