BDOS:	  EQU  0005	   ;BDOS ENTRY POINT
DCOM      EQU  010H        ;DISK COMMAND PORT
DSTAT     EQU  010H        ;DISK STATUS PORT
TRACK     EQU  011H        ;DISK TRACK COMMAND
SECTP     EQU  012H        ;DISK SECTOR PORT
DDATA     EQU  013H        ;DISK DATA PORT
SELECT	EQU	0F6B1H	;MONITOR ENTRY TO SELECT DRIVE
RESTOR	EQU	0F6F1H	;MONITOR ENTRY TO GO TO TRK 00
          ORG  0100H       ;LOAD & EX HERE
;
	JMP START		;JUMP AROUND MESSAGES


MSG1:	DB 'BIG-BOARD DISK FORMATTING PROGRAM'
	DB '     VER. 1.6'
	DB 0DH,0AH,0DH,0AH
	DB 'DRIVE TO BE FORMATTED? (A,B,C,D) : $'
MSG2:	DB 0DH,0AH,'READY TO FORMAT IN DRIVE '
DISKNO:	DS 1
	DB 0DH,0AH,'IS BLANK DISK READY TO FORMAT (Y-N)? $'
SELERR:	DB 0DH,0AH,'INVALID DRIVE SELECTION'
	DB 0DH,0AH,'ENTER A,B,C OR D : $'
MSG3:	DB 0DH,0AH,'DRIVE '
DISKID: DS 1
	DB ' NOT READY.',0DH,0AH,0AH
	DB 'PROGRAM RESTARTING ..........',0DH,0AH,0AH,'$'
DISKTMP DB 0
FMTDSK:	DS 1			;HOLDS DISK # TO BE USED
TEMP	DS 1
SPSAV:	DS 2			;SAVE AREA FOR CP/M STACK PTR
;
START:	LDA	066H		;SET UP NMI VECTOR
	STA TEMP		;FOR IMMEDIATE RETURN
	MVI	A,0C9H
	STA	066H
	LXI	H,0
	DAD	SP
	SHLD	SPSAV		;SAVE CP/M'S STACK PTR
	MVI	C,25		;INTERROGATE DRIVE NUMBER
	CALL BDOS
	STA DISKTMP		;SAVE COPY CURRENT DRIVE
REQ:	MVI C,9			;GET CODE FOR PRINT
	LXI D,MSG1		;GET ADDR OF MSG
	CALL BDOS
RESP:	MVI C,1			;GET CONSOLE CHAR
	CALL BDOS
	ANI	0DFH		;CONVERT TO UPPER CASE
	STA DISKNO		;PUT IN MSG
	STA DISKID
	SBI 65			;CONVERT TO BINARY
	STA	FMTDSK		;SAVE VALUE FOR SELDSK
	CPI	4		;CHECK FOR VALID RESPONSE
	JC	NXTDSK		;JUMP IF VALID DRIVE #
ERR:	MVI	C,9
	LXI	D,SELERR
	CALL	BDOS
	JMP	RESP		;ASK FOR DRIVE # AGAIN
NXTDSK:	MVI C,9			;GET CODE FOR PRINT
	LXI D,MSG2		;GET ADDR OF MSG
	CALL BDOS	
	EI			;ENABLE INTERRUPTS
	MVI C,1			;GET CONSOLE CHAR
	CALL BDOS
	CPI 'Y'			;WAS IT A YES
	JZ BEGIN		;START FORMATTING
	CPI 'Y'+20H	;CHECK FOR LOWER CASE 'Y'
	JZ BEGIN
	LDA	TEMP
	STA	066H		;RESTORE NMI VECTOR
	LHLD	SPSAV
	SPHL			;RESTORE CP/M STACK PTR
	LDA DISKTMP		;GET COPY OF ORIG LOGGED DISK
SELDSK:	MOV	C,A
	JMP	SELECT
;
;
; RESTORE DRIVE TO TRACK 00
;
BEGIN	LDA	FMTDSK	;DISK TO BE USED IN ACC
	CALL SELDSK	;SELECT DRIVE
	ORA	A	;SET FLAGS
	JZ	CONT	;JUMP IF SELECTION OK
	LXI	D,MSG3
	MVI	C,9
	CALL	BDOS	;PRINT ERROR MSG
	JMP	REQ	;START AGAIN
CONT	CALL	RESTOR
          MVI  C,0         ;SET TRACK NUMBER TO 0
          MVI  H,77        ;SET TOTAL TRACKS TO 77
NXTTRK    MVI  D,1         ;SECTOR NUMBER
          MVI  E,26        ;SET MAX # SECTORS  
          MVI  B,40        ;GAP 4 PREINDEX 40 BYTES OF FF
	DI			;DISABLE INTERRUPTS
          MVI  A,0F4H      ;LOAD TRACK WRITE COMMAND
          OUT  DCOM        ;ISSUE TRACK WRITE
	XTHL
	XTHL			;WASTE SOME TIME
; WRITE PREINDEX FILL
	MVI	A,0FFH
PREIND	HLT		;WAIT FOR DRQ
          OUT  DDATA       ;WRITE IT ON DISK
          DCR  B           ;COUNT =COUNT - 1
          JNZ  PREIND      ;GO BACK TILL B =0
	MVI	B,6	;WRITE 6 BYTES OF ZEROES
	XRA	A
PREIN2	HLT		;WAIT FOR DRQ
	OUT	DDATA
	DCR	B
	JNZ	PREIN2
;
; WRITE ADDRESS MARK ON TRACK
;
	MVI	A,0FCH		;LOAD ADDRESS MARK
	HLT		;WAIT FOR DRQ
          OUT  DDATA       ;WRITE IT ON DISK
;
; POST INDEX GAP
;
PID          MVI  B,26        ;SET # OF BYTES
	MVI	A,0FFH		;LOAD FILL DATA
POSTID	HLT		;WAIT FOR DRQ
          OUT  DDATA       ;WRITE IT ON DISK
          DCR  B           ;COUNT = COUNT - 1
          JNZ  POSTID      ;IF NOT 0 GO BACK
;
; PRE ID SECTION
;
ASECT     MVI  B,6         ;GET # OF BYTES
	XRA	A	;LOAD ZEROES
SECTOR	HLT		;WAIT FOR DRQ
          OUT  DDATA       ;WRITE IT ON TRACK
          DCR  B           ;COUNT = COUNT=1
          JNZ  SECTOR      ;JMP BACK IF NOT DONE
;
; WRITE ID ADDRESS MARK
;
	MVI	A,0FEH	;LOAD ADDRESS MARK
	HLT		;WAIT FOR DRQ
          OUT  DDATA       ;WRITE IT ON DISK
;
; WRITE TRACK NUMBER ON DISK
;
	MOV	A,C	;GET TRACK NUMBER
	HLT		;WAIT FOR DRQ
          OUT  DDATA       ;WRITE IT ON DISK
;
; WRITE ONE BYTE OF 00
;
	XRA	A
	HLT		;WAIT FOR DRQ
          OUT DDATA        ;WRITE IT ON DISK
;
; WRITE SECTOR # ON DISK
;
	MOV	A,D	;GET SECTOR NUMBER
	HLT		;WAIT FOR DRQ
          OUT DDATA        ;WRITE IT ON DISK
;
; ONE MORE BYTE 0
;
	XRA	A
	HLT		;WAIT FOR DRQ
          OUT  DDATA       ;WRITE IT ON DISK
          INR  D           ;BUMP SECT. #
;
; WRITE 2 CRC'S ON THIS SECTOR
;
	MVI	A,0F7H	;GET CRC PATTERN
	HLT		;WAIT FOR DRQ
          OUT DDATA        ;WRITE IT ON DISK
;
; PRE DATA 17 BYTES 
;
          MVI  B,11        ;SET COUNT
	MVI	A,0FFH
PREDAT	HLT		;WAIT FOR DRQ
          OUT  DDATA       ;WRITE IT ON DISK
          DCR  B           ;REDUCE COUNT BY 1
          JNZ  PREDAT      ;GO BACK IF NOT DONE
	MVI	B,6		;SET COUNT
	XRA	A	;SET DATA TO ZERO
PREDAT2	HLT			;WAIT FOR DRQ
	OUT	DDATA		;DO IT
	DCR	B		;DECREMENT COUNT
	JNZ	PREDAT2
;
; DATA ADDRESS MARK
;
	MVI	A,0FBH	;GET DATA ADDRESS MARK
	HLT		;WAIT FOR DRQ
          OUT  DDATA       ;WRITE IT ON DISK
;
; FILL DATA FIELD WITH E5
;
          MVI  B,128       ;SET FIELD LENGTH
	MVI	A,0E5H	;GET FILL BYTE
DFILL	HLT		;WAIT FOR DRQ
          OUT  DDATA       ;WRITE IT ON DISK
          DCR  B           ;DROP 1 FROM COUNT
          JNZ  DFILL       ;DO TILL 00
;
; WRITE CRC'S
;
	MVI	A,0F7H	;GET CRC BYTE
	HLT		;WAIT FOR DRQ
          OUT  DDATA       ;WRITE IT ON DISK
;
; END OF SECTOR FILL
;
	  DCR  E	   ;REDUCE SECTOR COUNT
	  JZ  ENDTRK	   ;IF 0 DO END OF TRACK RTN
	MVI	A,0FFH	;GET FILL CHAR.
DATGAP	HLT		;WAIT FOR DRQ
          OUT  DDATA       ;WRITE IT ON DISK
	  JMP  PID    ;GO BACK FOR MORE
;
; DO TRACK & SECTOR HOUSE KEEPING
;
ENDTRK	IN	DSTAT		;LOOK AT STATUS
	ANI	3		;CHECK FOR DRQ, BUSY
	JZ	DONE
	MVI	A,0FFH	;LOAD FILL CHAR.
	HLT			;WAIT FOR DRQ
          OUT  DDATA       ;WRITE IT ON DISK
          JMP  ENDTRK      ;DO UNTIL INTRQ
;
;
DONE          INR  C           ;BUMP TRACK #
          DCR  H           ;TRK COUNT =COUNT -1
          JNZ  BMPTRK      ;IF NOT 0 THEN DO MORE
	  JMP NXTDSK	   ;GO AGAIN

BMPTRK    MVI  A,43H       ;LOAD STEP IN
          OUT  DCOM        ;STEP IN
	XTHL
	XTHL		;DELAY
LOOP	IN	DSTAT	;CHECK STATUS
	ANI	01	;LOOK FOR BUSY
	JNZ	LOOP
	  JMP  NXTTRK
;
	END	0100H
          
