	TITLE	JADE DOUBLE D DISK FORMATTER MODULE
;*********************************************************
;
;   FORMAT PROGRAM
;   (c) 1981  GRH Electronics, Cupertino, CA
;
;*********************************************************
;
;	REVISIONS:
;
;  1.0 - RELEASE
;
VERSION	EQU	'10'
;**********************************************************
;
; NOTE:	THIS MODULE MUST BE LINKED TO OTHER MODULE(S).
;
;	BIOS	- BIOS CALL LIBRARY
;	CPMIOB	- CP/M IO CALLS WITH PARAMS PASSED IN BC LIB.
;	ASCII	- ASCII RTNS LIBRARY
;	(MAIN ?)- WITH A WORD DEFINED AS $MEMRY FOR LINK
;**********************************************************
	SUBTTL	ASSEMBLER DIRECTIVES
;  CPMIOB.REL RTNS:
	EXTRN	SELDSK,SETDMA

;  BIOS.REL RTNS:
	EXTRN	SETTRK,SETSEC,RDSEC,WRSEC,FMTTRK,BSTDMA

;  ASCII.REL RTNS:
	EXTRN	EDITOR,CI,CO,$MEMRY

	ENTRY	FORMTC

	SUBTTL	DECLARATIONS
LF:	EQU	0AH	;LINE FEED
CR:	EQU	0DH	;CARRIAGE RETURN
CTRLC:	EQU	3	;REQUEST REBOOT CPM
SECSZ:	EQU	128D	;128 BYTES PER SECTOR
;
;   DRIVER MODULE DEFINITIONS
;
TRK0:	EQU	0	;TRACK 0
TRK1:	EQU	1	;TRACK 1
TRK2:	EQU	2	;TRACK 2
TRK76:	EQU	76D	;TRACK 76
IDSEC:	EQU	1	;ID SECTOR #
;
;   SYSTEM TRACKS COPY DEFINITIONS
;
;TK0LP:	EQU	$MEMRY		;SYSTEM TRACKS BUFFER
TK0FS:	EQU	1		;TRACK 0 1ST SECTOR
TK0LS:	EQU	26D		;TRACK 0 LAST SECTOR
TK0NS:	EQU	TK0LS-TK0FS+1	;TRACK 0 # SECTORS
;TK0LC:	EQU	TK0LP-128D	;TRACK 0 LOAD CONSTANT
TK0SZ:	EQU	3328D		;TRACK 0 LOAD SIZE
;TK1LP:	EQU	TK0LP+TK0SZ	;TRACK 1 TPA LOAD ADDR
TK1FS:	EQU	1		;TRACK 1 1ST SECTOR
TK1LS:	EQU	48D		;TRACK 1 LAST SECTOR
;
;   INJECTION MODULE DEFINITIONS
;
FMTEA:	EQU	1700H		;FORMAT EXECUTION ADDR
WDTRK:	EQU	5		;DD TRACK PORT
WDDTA:	EQU	7		;DD DATA PORT
XPDSH:	EQU	80H		;DATA SYNC HOLD PORT
ZEROS:	EQU	00000000B	;ALL ZEROS BYTE
ONES:	EQU	11111111B	;ALL ONES BYTE
;
;
;   BIOS VECTOR DEFINITIONS
;
BSRDS:	EQU	0	;BIOS READ FLAG
BSWRS:	EQU	1	;BIOS WRITE FLAG
LOGVC:	EQU	1	;DRV SEL DON'T LOGON
;
	SUBTTL	PROGRAM BEGINS
FORMTC:
INIT:	POP	HL		;SAVE RETURN ADDR
	LD	(RETADR),HL
	LD	(STKSAV),SP
	LD	HL,MSGBG	;OUTPUT MESSAGE
	CALL	MSGOT
FUNBG:	LD	HL,MSGFL	;OUTPUT FUNCTION LIST
	CALL	MSGOT
	CALL	CNSIN
	SUB	'1'		;IF INVALID INPUT THEN REPEAT
	JR	C,NOFUN
	CP	MAXFUN
	JR	NC,NOFUN
	SLA	A		;OFFSET := FUNC# * 2
	LD	HL,FUNTAB	;BASE
	LD	E,A
	LD	D,0
	ADD	HL,DE		;PTR := BASE + OFFSET
	LD	A,(HL)
	INC	HL
	LD	H,(HL)
	LD	L,A
	JP	(HL)
;
NOFUN:	LD	HL,MSGSE	;ELSE OUTPUT PROMPT
	ADD	'1'		;CONVERT BACK TO ASCII
	LD	(LTRSE),A	;STORE BAD SYMBOL
	CALL	MSGOT
	JR	FUNBG		;REPEAT
;
FUNTAB:	DW	FUN1	;'1' = DOUBLE DENSITY FORMAT
	DW	FUN2	;SINGLE DENSITY FORMAT
	DW	FUN3	;3740 FORMAT
	DW	FUN4	;SYSTEM TRACKS FORMAT
	DW	FUN5	;READ SYSTEM TRACKS
	DW	FUN6	;WRITE SYSTEM TRACKS
;
MAXFUN:	EQU	($ - FUNTAB) / 2

	SUBTTL	FUNCTION 1 - DOUBLE DENSITY FORMAT
;
FUN1:	LD	A,(DDFLG)	;SET FORMAT FLAGS
	LD	(FFLAG),A
	LD	HL,MSGFD	;SELECT DRIVE
	CALL	SELDR
	JR	C,FUNBG		;ERR- RESELECT
	LD	A,TRK0		;SET TRACK #
	LD	(TRKNO),A
	CALL	FMTSD		;FORMAT TRACK SDENS
	JR	NZ,FUN1		;ERR
	LD	A,TRK1		;SET NEXT TRACK #
	LD	(TRKNO),A
REPT:	CALL	FMTDD		;FORMAT TRACK IN DDENS
	JR	NZ,FUN1		;ERR
	LD	A,(TRKNO)	;IF LAST TRACK THEN DONE
	CP	TRK76
	JR	Z,ID
	INC	A		;ELSE DO NEXT TRACK
	LD	(TRKNO),A
	JR	REPT
;
ID:	LD	HL,IDSDD	;WRITE DDENS ID SECTOR
	CALL	WRTID
	JR	FUN1		;READY FOR ANOTHER DISK

	SUBTTL	FUNCTION 3 - FORMAT IBM 3740
;
FUN3:	LD	A,0		;SET 3740 FLAGS
	LD	(FFLAG),A
	LD	HL,MSGFD	;SELECT DRIVE
	CALL	SELDR
	JP	C,FUNBG		;ERR
	LD	A,TRK0		;SET UP FOR TRACK 0
	LD	(TRKNO),A
REPT3:	CALL	FMTSD		;FORMAT IN SDEN
	JR	NZ,FUN3		;ERR
	LD	A,(TRKNO)	;IF TRACK 76 THEN DONE
	CP	TRK76
	JR	Z,FUN3
	INC	A		;ELSE DO NEXT TRACK
	LD	(TRKNO),A
	JR	REPT3

	SUBTTL	FUNCTION 2 - FORMAT IN SINGLE DENSITY

FUN2:	LD	A,(SDFLG)	;SET SDENS FLAGS
	LD	(FFLAG),A
	LD	HL,MSGFD	;SELECT DRIVE
	CALL	SELDR
	JP	C,FUNBG		;TERM.
	LD	A,TRK0		;SET UP FOR TRACK 0
	LD	(TRKNO),A
	CALL	FMTSD		;FORMAT IN SDENS
	JR	NZ,FUN2		;ERR
	LD	A,TRK1		;SET UP FOR TRACK 1
	LD	(TRKNO),A
	CALL	FMTDD		;FORMAT IN DDENS
	JR	NZ,FUN2		;ERR
	LD	A,TRK2		;SET UP FOR TRACK 2
	LD	(TRKNO),A
REPT2:	CALL	FMTSD		;FORMAT TRACK IN SDENS
	JR	C,FUN2		;ERR
	LD	A,(TRKNO)
	CP	TRK76
	JR	Z,ID2
	INC	A		;ELSE DO NEXT TRACK
	LD	(TRKNO),A
	JR	REPT2
;
ID2:	LD	HL,IDSSD	;WRITE SINGLE DENS ID SECTOR
	CALL	WRTID
	JR	FUN2		;DO ANOTHER

	SUBTTL	FUNCTION 4 - FORMAT JADE SYSTEM TRACKS ONLY
;
FUN4:	LD	A,(SDFLG)	;SET FORMAT FLAGS
	LD	(FFLAG),A
	LD	HL,MSGFD	;SET DRIVE
	CALL	SELDR
	JP	C,FUNBG		;ERR
	LD	A,TRK0		;SET UP FOR TRACK 0
	LD	(TRKNO),A
	CALL	FMTSD		;FORMAT IN SDENS
	JR	NZ,FUN4		;ERR
	LD	A,TRK1		;SET UP FOR TRACK 1
	LD	(TRKNO),A
	CALL	FMTDD		;FORMAT IN DDENS
	JR	NZ,FUN4		;ERR
	LD	HL,IDSSD	;WRITE ID SECTOR
	CALL	WRTID
	JR	FUN4

	SUBTTL	FUNCTION 5 - READ SYSTEM TRACKS
;
FUN5:	LD	HL,MSGRS	;SELECT DRIVE
	CALL	SELDR
	JP	C,FUNBG		;DONE
	LD	A,BSRDS		;READ SYSTEM TRACKS
	LD	(RWOPV),A
	CALL	TRNSFR
	JP	FUNBG		;DONE

	SUBTTL	FUNCTION 6 - WRITE SYSTEM TRACKS
;
FUN6:	LD	HL,MSGWS	;SELECT DRIVE
	CALL	SELDR
	JP	C,FUNBG		;DONE
	LD	A,BSWRS		;WRITE SYSTEM TRACKS
	LD	(RWOPV),A
	CALL	TRNSFR
	JR	FUN6		;DO ANOTHER

	SUBTTL	TEXT UTILITIES
;
;  MESSAGE OUTPUT ROUTINE
;
MSGOT:	PUSH	AF		;SAVE CALLER FLAGS
	CALL	EDITOR
	POP	AF
	RET
;
;   CONSOLE LINKAGE
;
CNSIN:	CALL	CI
	CP	CTRLC		;IF CTRL-C THEN REBOOT
	RET	NZ
	LD	SP,(STKSAV)	;RESTORE PTRS
	LD	HL,(RETADR)
	PUSH	HL
	RET

	SUBTTL	WRITE DISKETTE IDENTITY
;
;   WRITE ID SECTOR
;
WRTID:	LD	B,H	     ;SET WRITE PTR TO ID SECTOR IMAGE
	LD	C,L
	CALL	BSTDMA
	LD	C,TRK0		;SET TRACK 0
	CALL	SETTRK
	LD	C,IDSEC		;SET ID SECTOR
	CALL	SETSEC
	CALL	WRSEC
	OR	A		;SET CONDITION CODES
	RET	Z		;IF NO ERRORS THEN RETURN
	LD	HL,MSGNC	;ELSE OUTPUT ERROR & RETURN
	CALL	MSGOT
	RET
	FORM
	SUBTTL	FORMAT TRACK DRIVER LINKAGE
;
;   FORMAT TRACK DRIVER
;
FMTSD:	LD	HL,FT3740	;SET INJECTION ADDR
	JR	STDMA
;
FMTDD:	LD	HL,FTJ48D	;SET INJECTION ADDR
STDMA:	LD	B,H	     ;SET UP FOR BIOS BLOCK MOVE TO DC
	LD	C,L
	CALL	BSTDMA
	LD	A,(TRKNO)	;SET TRACK #
	LD	C,A
	CALL	SETTRK
	LD	A,(FFLAG)    ;SET DCM FLAGS TO CONTROL DENSITY
	LD	C,A
	CALL	SETSEC
	CALL	FMTTRK
	OR	A		;IF NO ERROR THEN RETURN
	RET	Z
	LD	HL,MSGNC	;ELSE OUTPUT ERROR MSG
	CALL	MSGOT
	RET
	FORM
	SUBTTL	SYSTEM TRACKS TRANSFER SUBROUTINE
;
;   SYSTEM TRACKS TRANSFER FUNCTION
;
TRNSFR:	LD	HL,TK0SL	;SET SECTOR LIST ADDR
	INC	HL		;BYPASS ID SECT.
	LD	(SYSWP),HL	;SET WORK PTR
	LD	C,TRK0		;SET TRACK
	CALL	SETTRK
TK0S:	LD	HL,(SYSWP)	;SET SECTOR
	LD	C,(HL)
	CALL	SETSEC
	LD	HL,(SYSWP)	;SET DMA ADDR
	AND	A		;CLR CARRY
	LD	A,(HL)		;GET SECTOR #
	RRA			;SECTOR x 128
	LD	D,A
	LD	A,0
	RRA
	LD	E,A
	LD	HL,($MEMRY)	;TRACK 0 LOAD CONSTANT
	LD	BC,-128		;COMPENSATE FOR EXTERN ARITH.
	ADD	HL,BC
	ADD	HL,DE
	LD	B,H		;HL -> BC
	LD	C,L
	CALL	BSTDMA
	LD	A,(RWOPV)	;DO READ/WRITE OPERATION
	CALL	RWOP		;GO READ OR WRITE
	OR	A		;IF ERROR THEN EXIT
	JR	NZ,BLOW
	LD	HL,(SYSWP) ;IF LAST SECTOR ON 0 THEN GOTO TRK 1
	LD	A,(HL)
	CP	16H
	JR	Z,TRK1P
	INC	HL		;ELSE BUMP SECTOR & REPEAT
	LD	(SYSWP),HL
	JR	TK0S
;
TRK1P:	LD	HL,($MEMRY) 	;SET UP FOR TRACK 1
	LD	BC,TK0SZ	;COMPENSATE FOR EXTRN ARITH.
	ADD	HL,BC
	LD	(SYSWP),HL
	LD	A,TK1FS		;SET SECTOR 1
	LD	(SECNO),A
	LD	C,TRK1		;SET UP TRACK 1
	CALL	SETTRK
TK1S:	LD	A,(SECNO)	;SET UP SECTOR
	LD	C,A
	CALL	SETSEC
	LD	HL,(SYSWP)	;SET DMA ADDR
	LD	B,H		;HL -> BC
	LD	C,L
	CALL	BSTDMA
	LD	A,(RWOPV)	;DO READ/WRITE OPERATION
	CALL	RWOP
	OR	A		;IF ERROR THEN EXIT
	JR	NZ,BLOW
	LD	A,(SECNO)	;IF LAST SECTOR THEN RETURN
	CP	TK1LS
	RET	Z
	INC	A		;ELSE BUMP SECTOR & PTR
	LD	(SECNO),A
	LD	HL,(SYSWP)
	LD	DE,SECSZ
	ADD	HL,DE
	LD	(SYSWP),HL
	JR	TK1S		;REPEAT
;
BLOW:	LD	HL,MSGNC	;OUTPUT ERROR MSG
	CALL	MSGOT
	RET
;
RWOP:	OR	A		;IF > 0 THEN WRITE
	JP	NZ,WRSEC
	JP	RDSEC

	SUBTTL	SELECT DRIVE SUBR
;
;   SELECT DRIVE THRU BIOS
;
SELDR:	LD	(MSGSV),HL	;SAVE MESSAGE ADDR
REPTD:	LD	HL,(MSGSV)	;PRINT MESSAGE
	CALL	MSGOT
	CALL	CNSIN		;GET INPUT
	AND	5FH		;INSURE UPPER CASE
	CP	CR		;IF RETURN THEN EXIT
	JR	Z,EXITD
	LD	(DRLTR),A	;ELSE SAVE DRIVE LETTER & TEST FOR LEGAL
	LD	(LTRSE),A
	SUB	'A'
	JR	C,ILLG
	CP	4
	JR	C,NMBRD		;IF LEGAL THEN CONTINUE
ILLG:	LD	HL,MSGSE	;PRINT SELECT ERROR MESSAGE
	CALL	MSGOT
	JR	REPTD
;
EXITD:	SCF			;SET FLAG TO CALLING RTN
	RET
;
NMBRD:	LD	C,A		;SELECT DRIVE
	LD	E,LOGVC	    ;SELECT DRIVE BUT IGNORE READ ERROR
	CALL	SELDSK
	LD	HL,MSGXX	;PRINT TYPE CR WHEN READY MSG
	CALL	MSGOT
	CALL	CNSIN		;IF NOT CR THEN REPEAT
	CP	CR
	JR	NZ,REPTD
	AND	A		;ELSE CLEAR FLAG & RETURN
	RET

	SUBTTL	DATA AREAS

	DATA
;
;   WORKING VARIABLES
;
SYSWP:	DW	0	;ADDRESS POINTER
RWOPV:	DB	0	;READ OR WRITE VECTOR
MSGSV:	DW	0	;MESSAGE SAVE ADDR
TRKNO:	DB	0	;TRACK NUMBER HOLD
SECNO:	DB	0	;SECTOR NUMBER HOLD
FFLAG:	DB	0	;FORMAT FLAG (DCM)
RETADR:	DW	0	;MAIN PGM RETURN ADDR
STKSAV:	DW	0	;MAIN PGM STACK PTR
;
;   3740 SECTOR TRANSLATION
;
TK0SL:	DB	1,7,0DH,13H,19H,5
	DB	0BH,11H,17H,3,9H,0FH
	DB	15H,2,8H,0EH,14H,1AH
	DB	6,0CH,12H,18H,4,0AH
	DB	10H,16H

	SUBTTL	IDENTITY SECTORS
;
;   JADE SINGLE DENSITY IDENTITY SECTOR
;
IDSSD:	DB	'Jade DD Single density format '
	ORG	IDSSD+32
;
	DW	26D		;SECTORS PER TRACK
	DB	3		;BLOCK SHIFT FACTOR
	DB	7		;BLOCK MASK
	DB	0		;NULL MASK
	DW	242D		;DISK SIZE -1
	DW	63D		;DIRECTORY MAXIMUM
	DB	11000000B	;ALLOC 0
	DB	0		;ALLOC 1
	DW	16D		;CHECK SIZE
	DW	2		;TRACK OFFSET
;
	ORG	IDSSD + 30H	;LOCATE DCM BLK
;
	DB	6		;SECTOR STAGGER (TRNS)
SDFLG:	DB	00000010B      ;DISKETTE FLAGS (TYPE OF FORMAT)
;
	ORG	IDSSD+SECSZ	;EXTEND FULL SECTOR
	FORM
;
;   JADE DOUBLE DENSITY IDENTITY SECTOR
;
IDSDD:	DB	'Jade DD Double density format '
	ORG	IDSDD+20H
;
	DW	48D		;SECTORS PER TRK
	DB	4		;BLOCK SHIFT FACTOR
	DB	00001111B	;BLOCK MASK
	DB	1		;NULL MASK
	DW	224D		;DISK SIZE -1
	DW	63D		;DIRECTORY MAXIMUM
	DB	10000000B	;ALLOC 0
	DB	0		;ALLOC 1
	DW	16D		;CHECK SIZE
	DW	2		;TRACK OFFSET
;
	ORG	IDSDD+30H	;LOCATE DCM BLOCK
;
	DB	6		;SECTOR STAGGER (TRNS)
DDFLG:	DB	00000110B	;DISKETTE FLAGS (FORMAT TYPE)
;
	ORG	IDSDD+SECSZ	;EXTEND TO FULL SECTOR

	SUBTTL	TEXT MESSAGES
;
MSGBG:	DB	CR,LF,'Jade DD Disk Formatter',CR
	DB	'Ver 1.0  by Girvin Herr',CR
	DB	'(c) 1981   GRH Electronics, Cupertino, CA',CR
	DB	0
;
MSGFL:	DB	CR,LF,'******  Functions List  ******',CR
	DB	'1. Format Jade Double Density 8',22H,CR
	DB	'2. Format Jade Single Density 8',22H,CR
	DB	'3. Format IBM 3740 Standard 8',22H,CR
	DB	'4. Format system tracks only.',CR
	DB	'5. Read system tracks image.',CR
	DB	'6. Write system tracks image.',CR
	DB	'or use ctrl-C for return to main menu.',CR,LF
	DB	'Enter function number: ',0
;
MSGSE:	DB	CR,LF
LTRSE:	DB	' IS NOT A VALID SELECTION',0
;
MSGFD:	DB	CR,LF
	DB	'Write format on drive A-D (RETURN to reselect'
	DB	'): ',0
;
MSGRS:	DB	CR,LF
	DB	'Read system from drive: ',0
;
MSGWS:	DB	CR,LF
	DB	'Write system to drive (RETURN to re-select): '
	DB	0
;
MSGNC:	DB	CR,LF
	DB	'Transfer Incomplete',0
;
MSGXX:	DB	CR,LF
	DB	'Type RETURN when drive '
DRLTR:	DB	'  is ready. ',0

	SUBTTL	SINGLE DENSITY INJECTION MODULE FORMATTER

FT3740:	EQU	$
	DB	'FORMAT!'
	DB	'S'
;
	LD	HL,[SS3740 - FT3740 + FMTEA]
	LD	E,26D		;SET # SECTORS
BG3740:	LD	B,40D	;WRITE PREAMBLE: START WITH 40 FF BYTES
SRPT1:	IN	A,XPDSH		;WAIT FOR DATA REQ
	LD	A,ONES
	XOR	C
	OUT	WDDTA,A		;WRITE DATA
	DJNZ	SRPT1
	LD	B,6		;THEN WRITE 6 00H BYTES
SRPT2:	IN	A,XPDSH
	LD	A,ZEROS
	XOR	C
	OUT	WDDTA,A
	DJNZ	SRPT2
	IN	A,XPDSH		;WRITE INDEX MARK
	LD	A,0FCH
	XOR	C
	OUT	WDDTA,A
	LD	B,26D	 ;WRITE GAP 1 - START WITH 26 FFH BYTES
SRPT3:	IN	A,XPDSH
	LD	A,ONES
	XOR	C
	OUT	WDDTA,A
	DJNZ	SRPT3
RP3740:	LD	B,6	;THEN WRITE END OF GAP 3 - 6 00H BYTES
SRPT4:	IN	A,XPDSH
	LD	A,ZEROS
	XOR	C
	OUT	WDDTA,A
	DJNZ	SRPT4
	IN	A,XPDSH		;WRITE ID MARK
	LD	A,0FEH
	XOR	C
	OUT	WDDTA,A
	IN	A,XPDSH		;WRITE TRACK #
	IN	A,WDTRK
	OUT	WDDTA,A
	IN	A,XPDSH		;WRITE SIDE #
	LD	A,0
	XOR	C
	OUT	WDDTA,A
	IN	A,XPDSH		;WRITE SECTOR #
	LD	A,(HL)
	XOR	C
	OUT	WDDTA,A
	INC	HL
	IN	A,XPDSH		;WRITE SECTOR SIZE
	LD	A,0		;(128)
	XOR	C
	OUT	WDDTA,A
	IN	A,XPDSH	     ;WRITE CRC WORD (2 BYTES WRITTEN)
	LD	A,0F7H
	XOR	C
	OUT	WDDTA,A
	LD	B,11D	;WRITE GAP 2 - START WITH 11 FFH BYTES
SRPT5:	IN	A,XPDSH
	LD	A,ONES
	XOR	C
	OUT	WDDTA,A
	DJNZ	SRPT5
	LD	B,6		;THEN WRITE 6 00H BYTES
SRPT6:	IN	A,XPDSH
	LD	A,ZEROS
	XOR	C
	OUT	WDDTA,A
	DJNZ	SRPT6
	IN	A,XPDSH		;WRITE DATA MARK
	LD	A,0FBH
	XOR	C
	OUT	WDDTA,A
	LD	B,128D		;WRITE 128 E5 BYTES
SRPT7:	IN	A,XPDSH
	LD	A,0E5H
	XOR	C
	OUT	WDDTA,A
	DJNZ	SRPT7
	IN	A,XPDSH		;WRITE CRC WORD
	LD	A,0F7H
	XOR	C
	OUT	WDDTA,A
	LD	B,27D	;WRITE GAP 3 - START WITH 27 FFH BYTES
SRPT8:	IN	A,XPDSH
	LD	A,ONES
	XOR	C
	OUT	WDDTA,A
	DJNZ	SRPT8
	DEC	E		;# SECTORS -1
	JR	NZ,RP3740	;IF ANY LEFT THEN REPEAT
	LD	HL,0		;COUNT = 0
SRPT9:	IN	A,XPDSH
	LD	A,ONES		;WRITE GAP 4 UNTIL INTERRUPT
	XOR	C
	OUT	WDDTA,A
	INC	HL		;COUNT GAP 4 LENGTH
	JR	SRPT9
;
SS3740:	DB	1,2,3,4,5,6,7,8D,9D,10D,11D,12D,13D,14D,15D,16D
	DB	17D,18D,19D,20D,21D,22D,23D,24D,25D,26D

	SUBTTL	DOUBLE D DOUBLE DENSITY INJECTION MODULE

FTJ48D:	
	DB	'FORMAT!D'
;
	LD	HL,[SSJ48D - FTJ48D + FMTEA]
	LD	E,48D		;SECTOR COUNT
BGJ48D:	LD	B,80D	;WRITE PREAMBLE: START WITH 80 4E BYTES
DRPT1:	IN	A,XPDSH
	LD	A,4EH
	XOR	C
	OUT	WDDTA,A
	DJNZ	DRPT1
	LD	B,12D		;THEN WRITE 12 00H BYTES
DRPT10:	IN	A,XPDSH
	XOR	A
	XOR	C
	OUT	WDDTA,A
	DJNZ	DRPT10
	LD	B,3		;WRITE GAP C2 - 3 F6H BYTES
DRPT11:	IN	A,XPDSH
	LD	A,0F6H
	XOR	C
	OUT	WDDTA,A
	DJNZ	DRPT11
	IN	A,XPDSH		;WRITE INDEX MARK
	LD	A,0FCH
	XOR	C
	OUT	WDDTA,A
	LD	B,32D	;WRITE GAP 1 - START WITH 32 4EH BYTES
DRPT12:	IN	A,XPDSH
	LD	A,4EH
	XOR	C
	OUT	WDDTA,A
	DJNZ	DRPT12
RPJ48D:	LD	B,8D	;THEN WRITE END OF GAP 3 - 8 00H BYTES
DRPT2:	IN	A,XPDSH
	XOR	A
	XOR	C
	OUT	WDDTA,A
	DJNZ	DRPT2
	LD	B,3		;WRITE GAP A1 - 3 F5H BYTES
DRPT3:	IN	A,XPDSH
	LD	A,0F5H
	XOR	C
	OUT	WDDTA,A
	DJNZ	DRPT3
	IN	A,XPDSH		;WRITE ID MARK
	LD	A,0FEH
	XOR	C
	OUT	WDDTA,A
	IN	A,XPDSH		;WRITE TRACK #
	IN	A,WDTRK
	OUT	WDDTA,A
	IN	A,XPDSH		;WRITE SIDE #
	XOR	A
	XOR	C
	OUT	WDDTA,A
	IN	A,XPDSH		;WRITE SECTOR #
	LD	A,(HL)
	XOR	C
	OUT	WDDTA,A
	INC	HL
	IN	A,XPDSH		;WRITE SECTOR SIZE (128)
	LD	A,0
	XOR	C
	OUT	WDDTA,A
	IN	A,XPDSH		;WRITE CRC WORD
	LD	A,0F7H
	XOR	C
	OUT	WDDTA,A
	LD	B,22D	;WRITE GAP 2 - START WITH 22 4EH BYTES
DRPT4:	IN	A,XPDSH
	LD	A,4EH
	XOR	C
	OUT	WDDTA,A
	DJNZ	DRPT4
	LD	B,8D		;THEN WRITE 8 00H BYTES
DRPT5:	IN	A,XPDSH
	XOR	A
	XOR	C
	OUT	WDDTA,A
	DJNZ	DRPT5
	LD	B,3		;WRITE GAP A1 - 3 F5H BYTES
DRPT6:	IN	A,XPDSH
	LD	A,0F5H
	XOR	C
	OUT	WDDTA,A
	DJNZ	DRPT6
	IN	A,XPDSH		;WRITE DATA MARK
	LD	A,0FBH
	XOR	C
	OUT	WDDTA,A
	LD	B,128D		;WRITE 128 E5 BYTES
DRPT7:	IN	A,XPDSH
	LD	A,0E5H
	XOR	C
	OUT	WDDTA,A
	DJNZ	DRPT7
	IN	A,XPDSH		;WRITE CRC WORD
	LD	A,0F7H
	XOR	C
	OUT	WDDTA,A
	LD	B,24D	;WRITE GAP 3 - START WITH 24 4EH BYTES
DRPT8:	IN	A,XPDSH
	LD	A,4EH
	XOR	C
	OUT	WDDTA,A
	DJNZ	DRPT8
	DEC	E		;IF SECTORS LEFT THEN REPEAT
	JP	NZ,[RPJ48D - FTJ48D + FMTEA]
	LD	L,E
	LD	H,L
DRPT9:	IN	A,XPDSH
	LD	A,4EH	;WRITE GAP 4: 4EH BYTES UNTIL INTERRUPT
	XOR	C
	OUT	WDDTA,A
	INC	HL	;COUNT NUMBER OF GAP 4 BYTES
	JR	DRPT9
;
SSJ48D:	DB	1,5,9D,13D,17D,21D,25D,29D,33D,37D,41D,45D
	DB	2,6,10D,14D,18D,22D,26D,30D,34D,38D,42D,46D
	DB	3,7,11D,15D,19D,23D,27D,31D,35D,39D,43D,47D
	DB	4,8D,12D,16D,20D,24D,28D,32D,36D,40D,44D,48D
;
	END
