;NEW DOUBLE DENSITY FORMAT PROGRAM FOR MICROMATION DOUBLER
;
;		FEB 1, 1979
;
CONTROLLER	EQU	0F800H

STEPTIME	EQU	CONTROLLER+410H

WRCONT		EQU	CONTROLLER+600H
RDSTAT		EQU	WRCONT
RDMARK		EQU	WRCONT+5
RDDATA		EQU	WRCONT+6
WRCLK		EQU	WRCONT+1
WRMRKCRC	EQU	WRCONT+4
WRMARK		EQU	WRCONT+5
WRDATA		EQU	WRCONT+6
WRCRC		EQU	WRCONT+7


BOOT		EQU	0
BDOS		EQU	5

HEADSETTLE	EQU	35D
STEPSETTLE	EQU	10D
LF		EQU	0AH
CR		EQU	0DH


	ORG	100H

	LXI	SP,100H
	CALL	HELLO
	CALL	GETDRIVE
	STA	DRIVE
REPEAT	CALL	INDISK
	CALL	SELDSK
	CALL	READY
	CALL	PROTECT
	CALL	HOME
				;READY TO START FORMATTING
	MVI	C,0		;TRACK NUMBER
	CALL	SDFORM
	CALL	YSFORM
	CALL	STEPIN
	INR	C
	CALL	SDFORM
	CALL	YSFORM

LOOP	CALL	STEPIN
	INR	C
	CALL	DDFORM
	CALL	YDFORM
	MOV	A,C
	CPI	43D
	CZ	SETAB43
	CPI	76D
	JNZ	LOOP

BYE	MVI	C,9
	LXI	D,LOGOFF
	CALL	BDOS
BYE1	CALL	CONIN
	CPI	'R'
	JZ	REPEAT
	CPI	CR
	JNZ	BYE1
	JMP	BOOT

LOGOFF	DB	LF,'TYPE R TO REPEAT',CR,LF
	DB	'TYPE RETURN TO REBOOT'
	DB	CR,LF,'$'


CONTROL	DB	0FFH
ABOVE43	DB	10H


;	SUBROUTINES FOLLOW

SETAB43	MVI	A,50H
	STA	ABOVE43
	RET


CONIN	LHLD	1
	MVI	L,9
	PCHL


HELLO	MVI	C,9
	LXI	D,LOGON
	CALL	BDOS
	RET

LOGON	DB	'DOUBLE DENSITY FORMAT PROGRAM FOR A '
	DB	CONTROLLER/1000H + 37H
	DB	CONTROLLER/100H MOD 10H + 30H
	DB	'00 SYSTEM'
	DB	CR,LF,'$'


GETDRIVE LXI	H,80H
GD1	INX	H
	MOV	A,M
	CPI	0
	JZ	PROMPT
	CPI	'A'
	JC	GD1
	CPI	'E'
	JNC	GD1
	RET

PROMPT	MVI	C,9
	LXI	D,PRMSG
	CALL	BDOS
NOGOOD	CALL	CONIN
	CPI	'A'
	JC	NOGOOD
	CPI	'E'
	JNC	NOGOOD
	RET

PRMSG	DB	'OBJECT DRIVE? A,B,C,D'
	DB	CR,LF,'$'


INDISK	MVI	C,9
	LXI	D,INMSG
	CALL	BDOS
INWAIT	CALL	CONIN
	CPI	CR
	JNZ	INWAIT
	RET

INMSG	DB	'INSERT NEW DISK IN DRIVE '
DRIVE	DB	0,CR,LF
	DB	'THEN TYPE RETURN'
	DB	CR,LF,'$'


SELDSK	LDA	DRIVE
	SUI	40H
	MOV	C,A
	MVI	A,7FH
SEL1	RRC
	DCR	C
	JNZ	SEL1
	STA	CONTROL
	STA	WRCONT
	LDA	RDMARK
	MVI	B,HEADSETTLE
	CALL	DELAY
	RET


DELAY			;DELAYS (B) MILLISECONDS
	LDA	CONTROL
	ORI	4
	STA	WRCONT
DL1	MVI	L,31D
DL2	LDA	RDDATA
	DCR	L
	JNZ	DL2
	DCR	B
	JNZ	DL1
	RET


READY	LDA	RDSTAT
	ANI	80H
	RZ
	MVI	C,9
	LXI	D,RDYMSG
	CALL	BDOS
RDY1	LDA	RDMARK
	LDA	RDSTAT
	ANI	80H
	JNZ	RDY1
	RET

RDYMSG	DB	'DRIVE NOT READY'
	DB	CR,LF,'$'


PROTECT	LDA	RDSTAT
	ANI	4
	RNZ
	MVI	C,9
	LXI	D,PROTMSG
	CALL	BDOS
	POP	B		;THROW AWAY RETURN ADDRESS
	JMP	BYE

PROTMSG	DB	'DISK IS WRITE PROTECTED'
	DB	CR,LF,'$'


HOME	LDA	RDSTAT
	ANI	2
	JZ	HOME1
	CALL	STEPOUT
	JMP	HOME
HOME1	MVI	B,STEPSETTLE
	CALL	DELAY
	RET


STEPOUT	LDA	CONTROL
	ORI	2
	JMP	STEP

STEPIN	LDA	CONTROL
	ANI	0FDH

STEP	LXI	D,WRCONT
	STAX	D
	DCR	A
	STAX	D
	INR	A
	STAX	D
	LDA	RDMARK
	LDA	STEPTIME
	MOV	B,A
	CALL	DELAY
	RET



YSFORM	LDA	RDSTAT
	ANI	40H		;DOUBLE SIDED DISKETTE?
	RNZ			;NO, RETURN
	LDA	CONTROL
	ANI	7FH
	JMP	S1

SDFORM	LDA	CONTROL
S1	STA	WRCONT
	LDA	ABOVE43
	STA	WRCLK
	MVI	B,0		;SECTOR NUMBER
	LXI	D,WRDATA
	MVI	L,72D
S2	LDA	RDSTAT
	ANI	10H		;WAIT FOR NO INDEX
	JZ	S2
S3	LDA	RDSTAT
	ANI	10H		;NOW WAIT FOR LEADING EDGE OF INDEX
	JNZ	S3
	MVI	A,0FFH
S4	STAX	D		;73 FF'S
	DCR	L
	JNZ	S4
	STAX	D
SECTOR	XRA	A
	STAX	D		;6 00'S
	INR	B		;INCREMENT SECTOR NUMBER
	STAX	D
	XCHG
	MVI	E,0
	MOV	M,E
	LDA	ABOVE43
	MOV	M,E
	ORI	80H
	STA	WRCLK
	MOV	M,E
	XRA	A
	XCHG
	STAX	D
	MVI	A,0FEH
	STA	WRMRKCRC	;ID MARK
	MOV	A,C
	STAX	D		;TRACK
	XRA	A
	STAX	D		;00
	MOV	A,B
	STAX	D		;SECTOR
	XRA	A
	STAX	D		;00
	MVI	A,0FFH
	STA	WRCRC		;CRC
	STA	WRCRC		;CRC
	MVI	L,10D
S5	STAX	D		;11 FF'S
	DCR	L
	JNZ	S5
	STAX	D
	XRA	A
	STAX	D		;6 00'S
	STAX	D
	LDA	ABOVE43
	STA	WRCLK		;SET UP FOR DATA MARK
	XRA	A
	STAX	D
	STAX	D
	STAX	D
	STAX	D
	MVI	A,0FBH
	STA	WRMRKCRC	;DATA MARK
	MVI	L,7FH
	MVI	A,0E5H
S6	STAX	D		;128 E5'S
	DCR	L
	JNZ	S6
	STAX	D
	MVI	A,0FFH
	STA	WRCRC		;CRC
	MVI	L,25D
	STA	WRCRC		;CRC
S7	STAX	D		;27 FF'S
	DCR	L
	JNZ	S7
	STAX	D
	MOV	A,B
	CPI	26D		;LAST SECTOR?
	MVI	A,0FFH
	STAX	D
	JNZ	SECTOR
S8	STAX	D		;INSERT FF'S UNTIL INDEX
	LDA	RDSTAT
	ANI	10H
	MVI	A,0FFH
	STAX	D
	JNZ	S8
	XRA	A
	STA	WRCLK
	MVI	B,1
	CALL	DELAY
	RET


YDFORM	LDA	RDSTAT
	ANI	40H		;DOUBLE SIDED DISKETTE?
	RNZ			;NO, RETURN
	LDA	CONTROL
	ANI	7BH
	JMP	D1


DDFORM	LDA	CONTROL
	ORI	80H
	ANI	0FBH
D1	STA	WRCONT
	LDA	ABOVE43
	STA	WRCLK
ERRETRY	MVI	B,0		;SECTOR NUMBER
	LXI	D,WRDATA
	MVI	L,46D
D2	LDA	RDSTAT
	ANI	10H		;WAIT FOR NO INDEX
	JZ	D2
D3	LDA	RDSTAT
	ANI	10H		;WAIT FOR LEADING EDGE OF INDEX
	JNZ	D3
	MVI	A,4EH
D4	STAX	D		;46 4E'S
	DCR	L
	JNZ	D4
DSECTOR STAX	D
	INR	B		;INCREMENT SECTOR NUMBER
	MVI	L,16D
D5	STAX	D		;18 4E'S
	DCR	L
	JNZ	D5
	STAX	D
	XRA	A
	STAX	D		;6 00'S
	STAX	D
	STAX	D
	STAX	D
	STAX	D
	STAX	D
	MVI	A,0A1H
	STA	WRMRKCRC	;ID MARK
	MVI	A,0FEH
	STAX	D		;FE
	MOV	A,C
	STAX	D		;TRACK
	MOV	A,B
	STAX	D		;SECTOR
	MVI	A,4EH
	STA	WRCRC		;CRC
	STA	WRCRC		;CRC
	MVI	L,21D
D6	STAX	D		;22 4E'S
	DCR	L
	JNZ	D6
	STAX	D
	XRA	A
	STAX	D		;6 00'S
	STAX	D
	STAX	D
	STAX	D
	STAX	D
	STAX	D
	MVI	A,0A1H
	STA	WRMRKCRC	;DATA MARK
	MVI	L,7FH
	MVI	A,0E5H
D7	STAX	D		;128 E5'S
	DCR	L
	JNZ	D7
	STAX	D
	MVI	A,4EH
	STA	WRCRC		;CRC
	STA	WRCRC		;CRC
	STAX	D		;4 4E'S
	MOV	L,A
	STAX	D
	STAX	D
	MOV	A,B
	CPI	52D		;LAST SECTOR?
	MOV	A,L
	STAX	D
	JNZ	DSECTOR
	STAX	D
	XCHG
	MVI	D,0
D8	MOV	M,E		;4E'S UNTIL INDEX
	INR	D
	JZ	ERROR
	MOV	M,E
	LDA	RDSTAT
	MOV	M,E
	ANI	10H
	MOV	M,E
	JNZ	D8
	XRA	A
	STA	WRCLK
	MVI	B,1
	CALL	DELAY
	RET

ERROR	PUSH	B
	MVI	C,9
	LXI	D,ERRMSG
	CALL	BDOS
	POP	B
	JMP	ERRETRY

ERRMSG	DB	'DRIVE ROTATIONAL SPEED OUT OF TOLERANCE',CR,LF
	DB	'REFORMATTING TRACK',CR,LF,'$'
