
	SUBTTL	'FORMAT ROUTINES'

**	FMT - FORMAT IN CURRENT DENSITY

FMT
	ORLI	P1,DDEN		;SELECT FM
	IN	A,P2
	ANLI	A,$FF-CFCLR	;GET CURRENT CONFIG
	XRLI	A,CFSSSD
	JZ	FMT1		;IF SS/SD

**	FMTD - FORMAT IN DUAL DENSITY

FMTD
	ANLI	P1,$FF-DDEN	;SELECT MFM


;	SEND ACKNOWLEDGE

FMT1
	LNGCAL	SENDAK

;	DO RESET SEQUENCE

	ANLI	P2,$FF-HKNOWN	;INDICATE HEAD POSITION UNKNOWN
	ANLI	P1,$FF-MR	;SEND RESET TO 1770
	PAUSE	R0,US500
	ORLI	P1,MR		;REMOVE RESET
	PAUSE	R0,US500
	SETREG	WCMD
	MOVI	A,FRCINT
	MOVX	XR0,A		;INITIATE FORCED INTERRUPT
	PAUSE	R0,US200

;	INITIALIZE DATA FRAMES FOR ERROR

	IN	A,P2
	RL	A
	RL	A
	ANLI	A,$80
	DECR	A		;OFFSET TO FIRST BYTE OF DATA FRAME
	MOV	R3,A		;SAVE IT
	MOV	R0,A
	CLR	A
	MOV	XR0,A
	DECR	R0
	MOV	XR0,A
	CPL	A
	DECR	R0
	MOV	XR0,A
	DECR	R0
	MOV	XR0,A
	MOVI	R0,CSTAT
	MOVI	XR0,$04		;STATUS FOR UNSUCCESSFUL OPERATION

;	SET FLAG TO INDICATE FORMAT

	CLR	F1

;	RESTORE TO TRACK 0

FMT2
	ANLI	P2,$FF-HKNOWN	;INDICATE HEAD POSITON UNKNOWN
	SETREG	WCMD
	MOVI	A,REST
	MOVX	XR0,A		;SEND RESTORE COMMAND TO 1770

	MOVI	R0,SEC3		;TRIP COUNT FOR 3-SECOND DELAY
	CLR	A
	MOV	T,A		;RESET TIMER
	STRT	T

FMT3
	JTF	FMT4
FMT5
	IN	A,P1
	ANLI	A,INTRQ
	JZ	FMT3		;IF NOT DONE

	STOP	T
	SETREG	RSTA
	MOVX	A,XR0		;READ STATUS TO CLEAR INTRQ
	SETREG	WTRK
	CLR	A
	MOVX	XR0,A		;UPDATE TRACK REG TO 0
	MOV	R2,A		;INIT R2 = TRACK
	ANLI	P1,$FF-SSO	;SELECT SIDE 0
	PAUSE	R0,US500
	JUMP	FMT6		;GO TO TRACK LOOP

FMT4
	DJNZ	R0,FMT5		;IF NOT TIMED OUT

;	PROCESS ERROR

FMT7
	STOP	T
	SETREG	WCMD
	MOVI	A,FRCINT
	MOVX	XR0,A		;DO FORCED INTERRUPT
	PAUSE	R0,US200
	CLR	F1
	CPL	F1		;INDICATE ERROR
	MOV	A,R3
	MOV	R0,A		;DATA FRAME LENGTH
	LNGJMP	SEND		;SEND ERROR, GO TO IDLE

;	MAIN TRACK LOOP
;	SEEK DESIRED TRACK

FMT6
	SETREG	WDAT
	MOV	A,R2		;GET DESIRED TRACK
	MOVX	XR0,A		;WRITE IT TO DATA REG
	ANLI	P2,$FF-HKNOWN	;INDICATE HEAD POSITION UNKNOWN
	SETREG	WCMD
	MOVI	A,SEEK
	MOVX	XR0,A		;ISSUE SEEK COMMAND
	CLR	A
	MOV	T,A
	JTF	FMT8		;CLEAR TIMER OVERFLOW FLAG
FMT8
	MOVI	R0,SEC1		;TRIP COUNT FOR 1-SECOND TIMEOUT

FMT9
	JTF	FMT10
FMT11
	IN	A,P1
	ANLI	A,INTRQ
	JZ	FMT9		;IF NOT DONE

	STOP	T
	SETREG	RSTA
	MOVX	XR0,A		;READ STATUS REG TO CLEAR INTRQ
	JUMP	ILV		;GO CONSTRUCT INTERLEAVE TABLE

FMT10
	DJNZ	R0,FMT11	;IF NOT TIMED OUT
	JUMP	FMT7		;GO PROCESS ERROR

;	CONSTRUCT SECTOR INTERLEAVE TABLE IN INTERNAL RAM

ILV

;	SET R4 = NUMBER OF SECTORS PER TRACK
;	    R5 = -(SECTOR INTERLEAVE FACTOR)
;	    R1 = INIT INDEX INTO INTERLEAVE TABLE

	MOVI	R4,18		;18 SECTORS PER TRACK
	MOVI	R5,$100-9	;SECTOR INTERLEAVE FACTOR OF 9
	IN	A,P2
	JB5	ILV1		;IF 128 BYTES/SECTOR
	JF0	ILV2		;IF FAST MODE
	MOVI	R5,$100-15	;SECTOR INTERLEAVE OF 15
ILV2
	DIS	I
	ORLI	P2,SECTSZ
	IN	A,P2
	JB5	ILV3		;IF MINIFLOPPY
	MOVI	R4,16		;16 SECTORS/TRACK FOR MICROFLOPPY
ILV3
	ANLI	P2,$FF-SECTSZ
	EN	I
	JUMP	ILV4
ILV1
	IN	A,P1
	JB3	ILV4		;IF FM
	MOVI	R4,26		;26 SECTORS/TRACK
	MOVI	R5,$100-13	;SECTOR INTERLEAVE OF 13

;	CLEAR THE INTERLEAVE TABLE

ILV4
	MOV	A,R4
	ADDI	A,$7F
	MOV	R6,A		;SAVE INIT INDEX INTO TABLE
	MOV	R1,A
ILV5
	MOVI	XR1,0		;STORE 0 IN TABLE
	DECR	R1		;ADVANCE POINTER
	MOV	A,R1
	JB7	ILV5		;IF NOT DONE WITH TABLE

;	FILL THE TABLE

	MOV	A,R6
	JUMP	ILV7
ILV6
	MOV	A,R1		;TABLE INDEX
	ADD	A,R5		;ADD INTERLEAVE FACTOR
ILV8
	JB7	ILV7		;IF STILL WITHIN RANGE
	ADD	A,R4		;WRAP POINTER
ILV7
	MOV	R1,A
	MOV	A,XR1
	JZ	ILV9		;IF TABLE ENTRY NOT YET USED
	DECR	R1
	MOV	A,R1
	JUMP	ILV8		;USE NEXT ENTRY
ILV9
	IN	A,P1
	ANLI	A,SSO
	JNZ	ILV10		;IF SECOND SIDE
	MOV	A,R0
	CPL	A
	ADD	A,R4
	ADDI	A,2		;REFLECT SECTOR NUMBER
	JUMP	ILV11
ILV10
	MOV	A,R0
ILV11
	MOV	XR1,A		;STORE SECTOR NUMBER IN TABLE
	DJNZ	R0,ILV6		;IF MORE SECTORS TO DO
	MOV	A,R6
	MOV	R1,A		;R1 = INIT INDEX INTO TABLE

;	DO WRITE TRACK

WTR
	JF1	VFY		;IF VERIFY

;	SET R4 = GAP FILLER
;	    R5 = PRE-MARK GAP LENGTH
;	    R6 = POST-ID GAP LENGTH
;	    R7 = POST-DATA GAP LENGTH
;	    R0 = POST-INDEX GAP LENGTH - 1

	MOVI	R4,$00
	MOVI	R5,6
	MOVI	R6,11
	MOVI	R7,12
	MOVI	R0,39
	IN	A,P1
	JB3	WTR1		;IF FM
	MOVI	R4,$4E
	MOVI	R5,12
	MOVI	R6,22
	MOVI	R7,24
	MOVI	R0,59

;	ISSUE WRITE TRACK COMMAND

WTR1
	SETREG	WCMD
	MOVI	A,WRTRK
	MOVX	XR0,A
	SETREG	WDAT
	CLR	A
	MOV	T,A		;RESET THE TIMER
	JTF	WTR2		;CLEAR TIMER OVERFLOW FLAG
WTR2
	MOVI	A,SEC1		;TRIP COUNT FOR 1 SECOND TIMEOUT
	XCH	A,R4
	STRT	T

;	WRITE POST-INDEX GAP (GAP I)

WTR3
	JTF	WTR4
WTR5
	JNDRQ	WTR3
	JNDRQ	WTR3		;FILTER DRQ GLITCHES
WTR50
	MOVX	XR0,A		;WRITE A GAP BYTE
	DJNZ	R0,WTR5		;IF NOT DONE WITH GAP
	MOV	T,A		;RESET THE TIMER
	JTF	WTR9		;RESET TIMER OVERFLOW FLAG
WTR9
	JDRQ	WTR10
WTR11
	JTF	WTR12
	JNDRQ	WTR11
WTR10
	MOVX	XR0,A		;WRITE LAST BYTE OF GAP
	MOV	R4,A

;	SECTOR LOOP

WTR6

;	WRITE PRE-IDAM GAP (END OF GAP III)

	MOV	A,R5
	MOV	R0,A
	CLR	A
	JDRQ	WTR44
WTR8
	JTF	WTR12
WTR13
	JNDRQ	WTR8
WTR44
	MOVX	XR0,A
	DJNZ	R0,WTR13

;	WRITE MFM SYNC MARKS

	IN	A,P1
	JB3	WTR14		;IF FM
	MOVI	A,$F5		;F5 WRITES MFM SYNC MARK
	JDRQ	WTR15
WTR16
	JTF	WTR12
	JNDRQ	WTR16
WTR15
	MOVX	XR0,A
	MOVI	R0,2		;WRITE 2 MORE SYNC MARKS
WTR17
	JTF	WTR12
WTR18
	JNDRQ	WTR17
	MOVX	XR0,A
	DJNZ	R0,WTR18

;	WRITE ID FIELD

WTR14
	MOVI	A,$FE		;ID ADDRESS MARK (IDAM)
	JDRQ	WTR19
WTR20
	JTF	WTR12
	JNDRQ	WTR20
WTR19
	MOVX	XR0,A		;WRITE IDAM

	MOV	A,R2		;TRACK NUMBER
WTR21
	JTF	WTR12
	JNDRQ	WTR21
	MOVX	XR0,A		;WRITE TRACK NUMBER

	IN	A,P1
	RR	A
	RR	A
	RR	A
	ANLI	A,1		;SIDE NUMBER
	JDRQ	WTR38
WTR22
	JTF	WTR12
	JNDRQ	WTR22
WTR38
	MOVX	XR0,A		;WRITE SIDE NUMBER

	MOV	A,XR1		;SECTOR NUMBER FROM INTERLEAVE TABLE
	DECR	R1		;ADVANCE INTERLEAVE POINTER
WTR23
	JTF	WTR12
	JNDRQ	WTR23
	MOVX	XR0,A		;WRITE SECTOR NUMBER

	IN	A,P2
	JB5	WTR24		;IF SECTOR SIZE IS 128
	INCR	R0
WTR24
	MOV	A,R0		;SECTOR SIZE CODE
WTR25
	JTF	WTR12
	JNDRQ	WTR25
	MOVX	XR0,A		;WRITE SECTOR SIZE CODE

	MOVI	A,$F7		;F7 WRITES CRC
WTR26
	JTF	WTR12
	JNDRQ	WTR26
	MOVX	XR0,A		;WRITE CRC

;	WRITE POST-ID GAP (START OF GAP II)

	MOV	A,R6
	MOV	R0,A		;LENGTH OF POST-ID GAP
	MOV	A,R4		;GAP FILLER
WTR27
	JTF	WTR12
WTR28
	JNDRQ	WTR27
	MOVX	XR0,A
	DJNZ	R0,WTR28

;	WRITE PRE-DAM GAP (END OF GAP II)

	MOV	A,R5
	MOV	R0,A
	CLR	A
	MOV	T,A		;RESET THE TIMER
WTR29
	JTF	WTR12
WTR30
	JNDRQ	WTR29
	MOVX	XR0,A
	DJNZ	R0,WTR30

;	WRITE MFM SYNC MARKS

	IN	A,P1
	JB3	WTR35		;IF FM
	MOVI	A,$F5		;F5 WRITES MFM SYNC MARK
	JDRQ	WTR32
WTR31
	JTF	WTR12
	JNDRQ	WTR31
WTR32
	MOVX	XR0,A
	MOVI	R0,2		;WRITE 2 MORE SYNC MARKS
WTR33
	JTF	WTR12
WTR34
	JNDRQ	WTR33
	MOVX	XR0,A
	DJNZ	R0,WTR34

;	WRITE DATA FIELD

WTR35
	MOVI	A,$FB		;FB IS DATA ADDRESS MARK (DAM)
	JDRQ	WTR37
WTR36
	JTF	WTR12
	JNDRQ	WTR36
WTR37
	MOVX	XR0,A		;WRITE DAM

	MOV	A,R3
	MOV	R0,A
	INCR	R0		;SECTOR SIZE
	MOVI	A,$FF		;DATA BYTE = FF
WTR39
	JTF	WTR12
WTR40
	JNDRQ	WTR39
	MOVX	XR0,A		;WRITE DATA BYTE
	DJNZ	R0,WTR40	;IF MORE DATA

	MOVI	A,$F7		;F7 WRITES CRC
WTR41
	JTF	WTR12
	JNDRQ	WTR41
	MOVX	XR0,A		;WRITE CRC

;	WRITE POST-DATA GAP (START OF GAP III)

	MOV	A,R7		;LENGTH OF POST-DATA GAP
	MOV	R0,A
	MOV	A,R4		;GAP FILLER BYTE
WTR42
	JTF	WTR12
WTR43
	JNDRQ	WTR42
	MOVX	XR0,A		;WRITE A GAP BYTE
	DJNZ	WTR43

;	SEE IF MORE SECTORS TO WRITE

	MOV	A,R1
	JB7	WTR6		;IF MORE SECTORS

;	WRITE GAP IV

	MOVI	R0,SEC1		;TRIP COUNT FOR 1 SECOND TIMEOUT
WTR45
	MOV	A,R4		;GAP FILLER BYTE
	JNDRQ	WTR46
	MOVX	XR0,A		;WRITE GAP BYTE
WTR46
	IN	A,P1
	JB2	WTR47		;IF DONE
	MOV	A,R4
	JNDRQ	WTR48
	MOVX	XR0,A		;WRITE GAP BYTE
WTR48
	JTF	WTR49
	JUMP	WTR45
WTR49
	DJNZ	R0,WTR45	;IF NOT TIMED OUT

;	HANDLE TIMEOUT

WTR12
	JUMP	FMT7

WTR4
	JNDRQ	WTR51
	JDRQ	WTR50		;FILTER DRQ GLITCHES
WTR51
	DJNZ	WTR5		;IF NOT TIMED OUT
	IN	A,P1
	CPL	A
	JB2	WTR52		;IF OPERATION NOT COMPLETE
	SETREG	RSTA
	MOVX	A,XR0		;READ STATUS
	CPL	A
	JB6	WTR52		;IF NOT WRITE PROTECT
	MOVI	R0,CSTAT
	MOVI	XR0,$0C		;STATUS FOR WRITE PROTECT
WTR52
	JUMP	FMT7

;	HANDLE WRITE TRACK OPERATION COMPLETE

WTR47
	SETREG	RSTA
	MOVX	A,XR0		;READ STATUS
	ANLI	A,$44		;RELEVANT STATUS BITS
	JNZ	WTR52		;IF ERROR
	JUMP	FMT12		;GO TO NEXT TRACK

**	VERIFY TRACK

VFY
