.PAGE	85
.TITLE "TURBODOS OPERATING SYSTEM TRACK FORMATTER FOR WESTERN DIGITAL 17xx"
.SBTTL "COPYRIGHT 1983, SOFTWARE 2000, INC."
;
; COPYRIGHT 1983, SOFTWARE 2000, INC.
;
; VERSION: 03/02/83
;
.IDENT	FMTWD		;MODULE ID
;
.INSERT	EQUATE		;SYMBOLIC EQUIVALENCES
;
	.LOC	.DATA.#	;LOCATE IN DATA AREA
;
INTLV::	.BYTE	1	;SECTOR INTERLEAVE
SECLST:	.BYTE	[27]0	;INTERLEAVED SECTOR LIST
KLP:	.WORD	0	;SECTOR LOOP ADDRESS
;
	.LOC	.PROG.#	;LOCATE IN PROGRAM AREA
;
TRKNIT::LDA	DENSTY#	;GET FORMAT DENSITY FLAG
	LXI	B,5500	;GET MAX SGL DENSITY TRACK LENGTH
	ORA	A	;FORMAT DENSITY FLAG=0?
	JRZ	..SD1	;IF SO, CONTINUE
	LXI	B,11000	;GET MAX DBL DENSITY TRACK LENGTH
..SD1:	LXI	H,.END.#  ;GET BEGINNING OF TRACK BUFFER
	DAD	B	;CALC END OF TRACK BUFFER
	XCHG		;END OF TRACK BUFFER TO DE-REG
	LHLD	OPSYS+1  ;GET TOP OF AVAILABLE MEMORY
	DSBC	D	;ENOUGH MEMORY FOR TRACK BUFFER?
	MVI	A,0FFH	;PRESET RETURN CODE=0FFH
	RC		;IF INSUFFICIENT MEMORY, DONE
	LXI	H,.END.#  ;GET BEGINNING OF TRACK BUFFER
	MOV	D,H	;TRACK BUFFER ADDRESS TO DE-REG
	MOV	E,L
	INX	D	;INCREMENT DE-REG
	MVI	M,0FFH	;PRESET TRACK BUFFER FILLER TO 0FFH
	LDA	DENSTY#	;GET FORMAT DENSITY FLAG
	ORA	A	;FORMAT DENSITY FLAG=0?
	JRZ	..SD2	;IF SO, CONTINUE
	MVI	M,04EH	;SET TRACK BUFFER FILLER TO 4EH
..SD2:	DCX	B	;DECREMENT TRACK BUFFER LENGTH
	LDIR		;INITIALIZE TRACK BUFFER
	LDA	INTLV	;GET SECTOR INTERLEAVE
	MOV	E,A	;SECTOR INTERLEAVE TO E-REG
	LDA	SECTRK#	;GET NUMBER OF SECTORS/TRACK
	STA	PDRSC#	;SET PD REQUEST SECTOR COUNT
	MOV	B,A	;NUMBER OF SECTORS/TRACK TO B-REG
	MOV	C,A	;NUMBER OF SECTORS/TRACK TO C-REG
	INR	C	;C=LIMIT TEST VALUE
	MVI	D,0	;D=CYCLE NUMBER
	LXI	H,SECLST  ;GET INTERLEAVED SECTOR LIST
..KV:	ADD	E	;INCREMENT SECTOR BY INTERLEAVE
	CMP	C	;SECTOR GREATER THAN MAX?
	JRC	..KL	;IF NOT, CONTINUE
	INR	D	;ELSE, INCREMENT CYCLE NUMBER
	MOV	A,D	;GET CYCLE NUMBER
..KL:	MOV	M,A	;STORE SECTOR NUMBER IN SECTOR LIST
	INX	H	;INCREMENT SECTOR LIST POINTER
	DJNZ	..KV	;CONTINUE FOR SECTORS/TRACK
	MOV	M,B	;MARK END OF SECTOR LIST
	LDA	SECSIZ#	;GET SECTOR SIZE
	ADD	A	;X2
	ADD	A	;X2=X4
	MOV	E,A	;TO DE-REG
	MVI	D,0	;DOUBLE LENGTH
	LXI	H,SDFTBL  ;GET SINGLE-DENSITY FORMAT TABLE
	LDA	DENSTY#	;GET FORMAT DENSITY FLAG
	ORA	A	;FORMAT DENSITY FLAG=0?
	JRZ	..SD3	;IF SO, CONTINUE
	LXI	H,DDFTBL-4  ;GET DOUBLE-DENSITY TABLE
..SD3:	DAD	D	;INDEX INTO TABLE
	MOV	E,M	;GET FORMAT COMMAND LIST ADDRESS
	INX	H
	MOV	D,M
	INX	H
	PUSH	D	;FORMAT COMMAND LIST TO IX-REG
	POP	X
	MOV	E,M	;GET SECTOR LOOP POINTER
	INX	H
	MOV	D,M
	SDED	KLP	;SAVE SECTOR LOOP ADDRESS
	LXI	D,.END.#  ;GET BEGINNING OF TRACK BUFFER
	LXI	H,SECLST  ;GET INTERLEAVED SECTOR LIST
..L:	LXI	B,..L	;GET LOOP TOP ADDRESS
	PUSH	B	;PUSH RETURN ADDRESS ON STACK
	MOV	C,0(X)	;GET SUBROUTINE ADDR FROM CMD LIST
	INX	X
	MOV	B,0(X)
	INX	X
	PUSH	B	;PUSH SUBROUTINE ADDRESS ON STACK
	RET		;TRANSFER TO SUBROUTINE
;
KLIT:	MOV	B,0(X)	;GET COUNT FROM COMMAND LIST
	INX	X
	MOV	A,0(X)	;GET BYTE FROM COMMAND LIST
	INX	X
..L:	STAX	D	;STORE IN TRACK BUFFER
	INX	D	;INCREMENT POINTER
	DJNZ	..L	;CONTINUE FOR COUNT
	RET		;DONE
;
KTRK:	LDA	PDRTRK#	;GET PD REQUEST TRACK NUMBER
	STAX	D	;STORE TRACK NUMBER IN TRACK BUFFER
	INX	D	;INCREMENT TRACK BUFFER POINTER
	RET		;DONE
;
KSID:	LDA	HEADNO#	;GET FORMAT HEAD NUMBER
	STAX	D	;STORE HEAD NUMBER IN TRACK BUFFER
	INX	D	;INCREMENT TRACK BUFFER POINTER
	RET		;DONE
;
KSEC:	MOV	A,M	;GET INTERLEAVED SECTOR NUMBER
	INX	H	;INCREMENT SECTOR LIST POINTER
	STAX	D	;STORE SECTOR IN TRACK BUFFER
	INX	D	;INCREMENT TRACK BUFFER POINTER
	RET		;DONE
;
KNXT:	LIXD	KLP	;RESET SECTOR LOOP POINTER
	MOV	A,M	;GET INTERLEAVED SECTOR NUMBER
	ORA	A	;END OF SECTOR LIST?
	RNZ		;IF NOT, CONTINUE
	POP	H	;ELSE, DISCARD RETURN ADDRESS
	LXI	H,.END.#  ;GET BEGINNING OF TRACK BUFFER
	SHLD	PDRDMA#	;SET PD REQUEST DMA ADDRESS
	XCHG		;HL=END/DE=START OF TRACK BUFFER
	ORA	A	;CLEAR CARRY FLAG
	DSBC	D	;CALC TRACK BUFFER LENGTH
	SHLD	PDRTC#	;SET PD REQUEST TRANSFER COUNT
	LDA	DENSTY#	;GET FORMAT DENSITY FLAG
	ORA	A	;FORMAT DENSITY FLAG=0?
	LDA	SECSIZ#	;GET SECTOR SIZE
	JRZ	..SD	;IF SINGLE DENSITY, CONTINUE
	SET	7,A	;ELSE, SET SIGN BIT ON SECTOR SIZE
..SD:	STA	PDRSEC#	;SET PD REQUEST SECTOR (LSB)
	LDA	HEADNO#	;GET FORMAT HEAD NUMBER
	ORA	A	;FORMAT HEAD NUMBER=0?
	LDA	GAPLEN#	;GET FORMAT GAP LENGTH
	JRZ	..HD0	;IF SO, CONTINUE
	SET	7,A	;ELSE, SET SIGN BIT ON GAP LENGTH
..HD0:	STA	PDRSEC#+1  ;SET PD REQUEST SECTOR (MSB)
	XRA	A	;SET RETURN CODE=0
	RET		;DONE
;
; FOLLOWING LIST DEFINES TRACK FORMAT
;
SDFTBL:			;SINGLE-DENSITY FORMATS
	.WORD	KLSTS0	;128 BYTE FORMAT LIST
	.WORD	KLPS0
	.WORD	KLSTS1	;256 BYTE FORMAT LIST
	.WORD	KLPS1
	.WORD	KLSTS2	;512 BYTE FORMAT LIST
	.WORD	KLPS2
;
DDFTBL:			;DOUBLE-DENSITY FORMATS
	.WORD	KLSTD1	;256 BYTE FORMAT LIST
	.WORD	KLPD1
	.WORD	KLSTD2	;512 BYTE FORMAT LIST
	.WORD	KLPD2
	.WORD	KLSTD3	;1,024 BYTE FORMAT LIST
	.WORD	KLPD3
;
.SALL
.DEFINE	.KLIT[N,V]	= [.WORD KLIT,(V<8)!N]
;
;	128 BYTE SECTOR, SINGLE DENSITY
;
KLSTS0:	.KLIT	40,0FFH	;40 FF'S
	.KLIT	6,0	;6 ZEROES
	.KLIT	1,0FCH	;INDEX MARK (FC)
KLPS0:	.KLIT	26,0FFH	;26 FF'S
	.KLIT	6,0	;6 ZEROES
	.KLIT	1,0FEH	;ID ADDRESS MARK (FE)
	.WORD	KTRK	;TRACK NUMBER
	.WORD	KSID	;SIDE NUMBER
	.WORD	KSEC	;SECTOR NUMBER
	.KLIT	1,0	;RECORD LENGTH
	.KLIT	1,0F7H	;CRC GENERATION (F7)
	.KLIT	11,0FFH	;11 FF'S (ADDR/DATA GAP)
	.KLIT	6,0	;6 ZEROES
	.KLIT	1,0FBH	;DATA ADDRESS MARK (FB)
	.KLIT	128,0E5H  ;128 E5'S
	.KLIT	1,0F7H	;CRC GENERATION (F7)
	.KLIT	1,0FFH	;1 FF
	.WORD	KNXT	;JMP KLP
;
;	256 BYTE SECTOR, SINGLE DENSITY
;
KLSTS1:	.KLIT	40,0FFH	;40 FF'S
	.KLIT	6,0	;6 ZEROES
	.KLIT	1,0FCH	;INDEX MARK (FC)
KLPS1:	.KLIT	26,0FFH	;26 FF'S
	.KLIT	6,0	;6 ZEROES
	.KLIT	1,0FEH	;ID ADDRESS MARK (FE)
	.WORD	KTRK	;TRACK NUMBER
	.WORD	KSID	;SIDE NUMBER
	.WORD	KSEC	;SECTOR NUMBER
	.KLIT	1,1	;RECORD LENGTH
	.KLIT	1,0F7H	;CRC GENERATION (F7)
	.KLIT	11,0FFH	;11 FF'S (ADDR/DATA GAP)
	.KLIT	6,0	;6 ZEROES
	.KLIT	1,0FBH	;DATA ADDRESS MARK (FB)
	.KLIT	128,0E5H  ;256 E5'S
	.KLIT	128,0E5H
	.KLIT	1,0F7H	;CRC GENERATION (F7)
	.KLIT	16,0FFH	;16 FF'S
	.WORD	KNXT	;JMP KLP
;
;	512 BYTE SECTOR, SINGLE DENSITY
;
KLSTS2:	.KLIT	40,0FFH  ;40 FF'S
	.KLIT	6,0	;6 ZEROES
	.KLIT	1,0FCH	;INDEX MARK (FC)
KLPS2:	.KLIT	26,0FFH	;26 FF'S
	.KLIT	6,0	;6 ZEROES
	.KLIT	1,0FEH	;ID ADDRESS MARK (FE)
	.WORD	KTRK	;TRACK NUMBER
	.WORD	KSID	;SIDE NUMBER
	.WORD	KSEC	;SECTOR NUMBER
	.KLIT	1,2	;RECORD LENGTH
	.KLIT	1,0F7H	;CRC GENERATION (F7)
	.KLIT	11,0FFH	;11 FF'S (ADDR/DATA GAP)
	.KLIT	6,0	;6 ZEROES
	.KLIT	1,0FBH	;DATA ADDRESS MARK (FB)
	.KLIT	128,0E5H  ;512 E5'S
	.KLIT	128,0E5H
	.KLIT	128,0E5H
	.KLIT	128,0E5H
	.KLIT	1,0F7H	;CRC GENERATION (F7)
	.KLIT	32,0FFH	;32 FF'S
	.WORD	KNXT	;JMP KLP
;
;	256 BYTE SECTOR, DOUBLE DENSITY
;
KLSTD1:	.KLIT	80,04EH	;80 4E'S
	.KLIT	12,0	;12 ZEROES
	.KLIT	3,0F6H	;3 F6'S
	.KLIT	1,0FCH	;INDEX MARK (FC)
KLPD1:	.KLIT	50,04EH	;50 4E'S
	.KLIT	12,0	;12 ZEROES
	.KLIT	3,0F5H	;3 F5'S
	.KLIT	1,0FEH	;ID ADDRESS MARK (FE)
	.WORD	KTRK	;TRACK NUMBER
	.WORD	KSID	;SIDE NUMBER
	.WORD	KSEC	;SECTOR NUMBER
	.KLIT	1,1	;RECORD LENGTH
	.KLIT	1,0F7H	;CRC GENERATION (F7)
	.KLIT	22,04EH	;22 4E'S (ADDR/DATA GAP)
	.KLIT	12,0	;12 ZEROES
	.KLIT	3,0F5H	;3 F5'S
	.KLIT	1,0FBH	;DATA ADDRESS MARK (FB)
	.KLIT	128,0E5H  ;256 E5'S
	.KLIT	128,0E5H
	.KLIT	1,0F7H	;CRC GENERATION (F7)
	.KLIT	4,04EH	;4 4E'S
	.WORD	KNXT	;JMP KLP
;
;	512 BYTE SECTOR, DOUBLE DENSITY
;
KLSTD2:	.KLIT	80,04EH	;80 4E'S
	.KLIT	12,0	;12 ZEROES
	.KLIT	3,0F6H	;3 F6'S
	.KLIT	1,0FCH	;INDEX MARK (FC)
KLPD2:	.KLIT	50,04EH	;50 4E'S
	.KLIT	12,0	;12 ZEROES
	.KLIT	3,0F5H	;3 F5'S
	.KLIT	1,0FEH	;ID ADDRESS MARK (FE)
	.WORD	KTRK	;TRACK NUMBER
	.WORD	KSID	;SIDE NUMBER
	.WORD	KSEC	;SECTOR NUMBER
	.KLIT	1,2	;RECORD LENGTH
	.KLIT	1,0F7H	;CRC GENERATION (F7)
	.KLIT	22,04EH	;22 4E'S (ADDR/DATA GAP)
	.KLIT	12,0	;12 ZEROES
	.KLIT	3,0F5H	;3 F5'S
	.KLIT	1,0FBH	;DATA ADDRESS MARK (FB)
	.KLIT	128,0E5H  ;512 E5'S
	.KLIT	128,0E5H
	.KLIT	128,0E5H
	.KLIT	128,0E5H
	.KLIT	1,0F7H	;CRC GENERATION (F7)
	.KLIT	34,04EH	;34 4E'S
	.WORD	KNXT	;JMP KLP
;
;	1,024 BYTE SECTOR, DOUBLE DENSITY
;
KLSTD3:	.KLIT	80,04EH	;80 4E'S
	.KLIT	12,0	;12 ZEROES
	.KLIT	3,0F6H	;3 F6'S
	.KLIT	1,0FCH	;INDEX MARK (FC)
KLPD3:	.KLIT	50,04EH	;50 4E'S
	.KLIT	12,0	;12 ZEROES
	.KLIT	3,0F5H	;3 F5'S
	.KLIT	1,0FEH	;ID ADDRESS MARK (FE)
	.WORD	KTRK	;TRACK NUMBER
	.WORD	KSID	;SIDE NUMBER
	.WORD	KSEC	;SECTOR NUMBER
	.KLIT	1,3	;RECORD LENGTH
	.KLIT	1,0F7H	;CRC GENERATION (F7)
	.KLIT	22,04EH	;22 4E'S (ADDR/DATA GAP)
	.KLIT	12,0	;12 ZEROES
	.KLIT	3,0F5H	;3 F5'S
	.KLIT	1,0FBH	;DATA ADDRESS MARK (FB)
	.KLIT	128,0E5H  ;1,024 E5'S
	.KLIT	128,0E5H
	.KLIT	128,0E5H
	.KLIT	128,0E5H
	.KLIT	128,0E5H
	.KLIT	128,0E5H
	.KLIT	128,0E5H
	.KLIT	128,0E5H
	.KLIT	1,0F7H	;CRC GENERATION (F7)
	.KLIT	66,04EH	;66 4E'S
	.WORD	KNXT	;JMP KLP
;
.XSYM
.END
