DataMuseum.dk

Presents historical artifacts from the history of:

Christian Rovsing CR7, CR8 & CR16 CP/M

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Christian Rovsing CR7, CR8 & CR16 CP/M

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦531c3782e⟧ TextFile

    Length: 21888 (0x5580)
    Types: TextFile
    Names: »FORMAT10.ASM«

Derivation

└─⟦1f6b46325⟧ Bits:30004393 CP/M-80 rel. 1 Utilities source disk
    └─ ⟦this⟧ »FORMAT10.ASM« 

TextFile


	TITLE 'CHRISTIAN ROVSING A/S DISK FORMATTING UTILITY'
	PAGE 43

;******************************************************************************
;	CHRISTIAN ROVSING - CP/M DISK FORMATTING PROGRAM
;******************************************************************************
;
;	HARD DISK FORMATTING PROGRAM FOR FORMATTING A SEGATE ST-406/412
;	5 1/4 INCH WINCHESTER DISK DRIVES. USE OF A MICRO COMPUTER
;	SYSTEMS INC. MCS-9205 MULTIBUS WINCHESTER DISK DRIVE CONTROLLER
;	IS REQUIRED.
;	THE WINCHESTER DISK CONTROLLER FIRMWARE SUPPORTS A PARAMETER
;	BLOCK FORMAT SIMILAR TO AN INTEL SBC 206 DISK CONTROLLER WITH 
;	A MODIFIED SET OF PARAMETERS THAT MAP TO THE CHARACTERISTICS OF
;	THE SEAGATE 5 1/4 INCH WINCHESTER DRIVE. THE CONTROLLER / DRIVE
;	CHARACTERISTICS ARE MAPPED AS FOLLOWS:
;
;		306 CYLINDERS
;		17 RECORDS PER CYLINDER
;		512 BYTE RECORDS
;
;	ACCESS AND CONTROL OF THE MINI FLOPPY WILL BE THROUGH THE DISK
;	CONTROLLER CIRCUITRY OF THE CHRISTIAN ROVSING A/S MP2 BOARD.
;	THE FLOPPY DISK FORMAT IS AS FOLLOWS:
;
;		77 TRACKS
;		16 RECORDS PER TRACK
;		TWO HEADS/SIDES
;		256 BYTE RECORDS
;		CP/M MAPS LOGICAL DRIVE E: TO THE MINI FLOPPY WITH
;		  ODD TRACKS ON HEAD 0 AND EVEN TRACKS ON HEAD 1
;
;	SINCE THE HARD DISK CONTROLLER (MSC 9205) DOES NOT FORMAT WITH
;	A USER SELECTABLE SECTOR FILL CHARACTER, THE FORMAT PROGRAM WILL
;	WRITE AN APPROPIATE NUMBER OF HARD DISK TRACKS WITH A "0E5H" DATA
;	PATTERN. THIS IS NECESSARY SO THAT THE CP/M DIRECTORY AREA LOOKS
;	EMPTY TO CP/M 2.2. THE MINIFLOPPY FORMAT OPTION CAUSES THE COMPLETE
;	DISK TO BE WRITTEN WITH SECTORS FILLED WITH 0E5H DATA.
;
	PAGE
;******************************************************************************
;
;
;GENERAL EQUATES
;
CR	EQU	0DH		;CARRIAGE RETURN CODE
LF	EQU	0AH		;LINE FEED CODE
BS	EQU	08H		;BACK SPACE CODE
BEL	EQU	07H		;BELL RING CODE
ESC	EQU	01BH		;ESCAPE CODE
TRUE	EQU	0FFFFH		;TRUE CODE
FALSE	EQU	NOT TRUE	;FALSE CODE
;
;
;LOGICAL DRIVE CONFIGURATION SELECTION
;
ONEMINI	EQU	TRUE		;SET TO TRUE IF HARDWARE IS CONFIGURED
				;...ONE MINI FLOPPY DRIVE. FALSE FOR
				;...TWO DRIVES.
MINISEL	EQU	04H		;BASE CP/M SELECT DESIGNATOR FOR MINI FLOPPY
				;UNIT: 04H FOR DRIVE E:
				;      05H FOR DRIVE F: ETC.
MAXDSK	EQU	000		;MAXIMUM DISK NUMBER
MAXTRK	EQU	305		;MAXIMUM TRACK NBR.
MAXREC	EQU	017		;MAXIMUM RECORD NUMBER
MAXPLAT	EQU	003		;MAXIMUM DRIVE PLATTER NUMBER
MAXSUR	EQU	000		;MAXIMUM DISK SURFACE NUMBER
SECSIZ	EQU	512		;NUMBER OF BYTES IN DISK RECORD
LASTE5	EQU	006		;LAST SURFACE CYLINDER TO FILL WITH E5
;
;
;DEFINE HARD DISK FORMAT FILLER CHARACTER
;
FMTCHAR	EQU	0E5H		;CP/M FORMAT FILLER BYTE
;
;
;SPECIAL HARD DISK ACCESS INSTRUCTION DEFINITION
;
DIFMT	EQU	02H		;FORMAT TRACK
;
	PAGE
;
; UNIT/MODE REGISTER FOR DISK DRIVES SELECT
;
;	BIT 7 - COMPENSATION    "1" ENABLES FLOPPY WRITE PRECOMPENSATION
;	BIT 6 - DRIVE TYPE      "1" SELECTS CLOCKING FOR A 5 1/4 DRIVE
;			        "0" SELECTS FOR AN 8 INCH UNIT
;	BIT 5 - DENSITY         "1" SETS FOR MFM DOUBLE DENSITY
;				"0" SELECTS FM SINGLE DENSITY
;
COMPEN	EQU	080H		;WRITE COMPENSATION ENABLE
MINIEN	EQU	040H		;MINI DRIVE ENABLE
DENSEL	EQU	020H		;BIT MASK FOR DENSITY SELECT
;
FSPT	EQU	016		;NUMBER OF MINI FLOPPY SECTORS PER TRACK
FSECSIZ	EQU	256		;NUMBER OF BYTES IN A MINI FLOPPY SECTOR
FSECCDE	EQU	001		;FLOPPY SECTOR HEADER SIZE CODE
FTPS	EQU	77		;NUMBER OF FLOPPY TRACKS PER SIDE
;
;
;
;DEFINE MEMORY BASED I/O MODULE ENTRY POINTS
;
MODBASE EQU	0F800H		;SET JUMP TABLE EQUIVALENT ADDRESSES
;
INITSER EQU	MODBASE+00	;INITIALIZE SERIAL I/O PORTS
;				;(NO PARAMETERS)
SETCBAUD EQU	MODBASE+03	;SET CONSOLE I/O BAUD RATE FACTOR
;				;(HL) = COUNTER TIMER PARAMETER VALUE
SETLBAUD EQU	MODBASE+06	;SET LINE PRINTER I/O BAUD RATE FACTOR
;				;(HL) = COUNTER TIMER VALUE
SETLRMSK EQU	MODBASE+09	;SET LINE PRINTER SIO RECEIVER MASK VALUE
				;(A) = LINE PRINTER SIO MASK BYTE
SETLRVAL EQU	MODBASE+012	;SET LINE PRINTER SIO RECEIVER POLL VALUE
;				;(A) = LINE PRINTER POLL VALUE
SETLTMSK EQU	MODBASE+015	;SET LINE PRINTER SIO TRANSMITTER MASK VALUE
;				;(A) = LINE PRINTER SIO MASK BYTE
SETLTVAL EQU	MODBASE+018	;SET LINE PRINTER SIO TRANSMITTER POLL VALUE
;				;(A) = LINE PRINTER SIO POLL VALUE BYTE
CONSTAT EQU	MODBASE+021	;GET CONSOLE STATUS
;				;RETURN (A)=00 FOR NOT READY INPUT
;				;	(A)=FF FOR READY INPUT
CONIN	EQU	MODBASE+024	;GO GET CONSOLE INPUT CHARACTER
;				;(A)=INPUT CONSOLE CHARACTER
CONOUT	EQU	MODBASE+027	;PUT OUT CONSOLE CHAR
;				;(C)=CHARACTER TO OUTPUT
LPTSTAT EQU	MODBASE+030	;GET LINE PRINTER STATUS
;				;RETURN (A)=00 FOR NOT NEXT OUTPUT
;				;	(A)=FF FOR READY OUTPUT
LPTIN	EQU	MODBASE+033	;GO GET LINE PRINTER INPUT CHARACTER
;				;(A)=INPUT LPT SERIAL PORT CHARACTER
LPTOUT	EQU	MODBASE+036	;PUT OUT LINE PRINTER CHARACTER
;				;(C)=LPT SERIAL OUTPUT CHARACTER
HUNIT	EQU	MODBASE+039	;SELECT HARD DISK UNIT NUMBER
;				;(C)=UNIT NUMBER ON MSC 9205 CONTROLLER
HPLAT	EQU	MODBASE+042	;SELECT HARD DISK PLATTER (HEAD) NUMBER 
;				;(C)=HEAD SELECT NUMBER
HSURF	EQU	MODBASE+045	;SELECT HARD DISK SURFACE(HEAD 2^2) NUMBER
;				;(C)=MSB OF HEAD NUMBER
HCYL	EQU	MODBASE+048	;SELECT HARD DISK CYLINDER NUMBER
;				;(BC)=CYLINDER NUMBER
HREC	EQU	MODBASE+051	;SELECT HARD DISK RECORD NUMBER
;				;(C)=RECORD NUMBER
HCNT	EQU	MODBASE+054	;SELECT HARD DISK SECTOR COUNT
;				;(C)=RECORD COUNT
HBADDR	EQU	MODBASE+057	;SET 9205 CONTROLLER DMA ADDRESS
;				;(BC)=16 BIT DATA BUFFER ADDRESS
HREST	EQU	MODBASE+060	;RESTORE SELECTED HARD DISK UNIT
;				;(A) RETURNS ERROR CODE
HREAD	EQU	MODBASE+063	;READ SELECTED SECTOR(S)
;				;(A) RETURNS ERROR CODE
HVERF	EQU	MODBASE+066	;VERIFY SELECTED SECTOR(S)
;				;(A) RETURNS ERROR CODE
HWRIT	EQU	MODBASE+069	;WRITE SELECTED SECTOR(S);
;				;(A) RETURNS ERROR CODE
HEXEC	EQU	MODBASE+072	;EXECUTE SPECIAL COMMAND OF MSC 9205
;				;(C) ENTRY WITH MSC 9205 COMMAND
;				;(A) RETURNS ERROR CODE
HRESET	EQU	MODBASE+075	;RESET HARD DISK CONTROLLER MSC 9205
;				;NO PARAMETERS
MUNIT	EQU	MODBASE+078	;SELECT MINI FLOPPY UNIT NUMBER
;				;(C)=FLOPPY PHYSICAL UNIT NUMBER
MSURF	EQU	MODBASE+081	;SELECT MINI FLOPPY SURFACE(HEAD) NUMBER
;				;(C)=FLOPPY SIDE NUMBER
MCYL	EQU	MODBASE+084	;SELECT MINI FLOPPY CYLINDER(TRACK) NUMBER
;				;(C)=FLOPPY TRACK NUMBER
MREC	EQU	MODBASE+087	;SELECT MINI FLOPPY RECORD NUMBER
;				;(C)=FLOPPY SECTOR NUMBER
MCNT	EQU	MODBASE+090	;SELECT MINI FLOPPY PHYSICAL SECTOR COUNT
;				;(C)=MINI FLOPPY SECTOR COUNT
MSIZE	EQU	MODBASE+093	;SELECT FLOPPY SECTOR SIZE (00)=256 BYTES
;				;(C)=MINI FLOPPY TRACK NUMBER
MBADDR	EQU	MODBASE+096	;SET FLOPPY DISK DATA BUFFER ADDRESS
;				;(BC)=FLOPPY BUFFER ADDRESS
MREST	EQU	MODBASE+099	;RESTORE SELECTED MINI FLOPPY UNIT
;				;(A)=RETURNS ERROR STATUS
MVERF	EQU	MODBASE+102	;VERIFY (READ) SELECTED SECTOR
;				;(A)=RETURNS STATUS
MWRIT	EQU	MODBASE+105	;D		;RESTORE CALLERS REGS
	POP	H
	RET
;
	PAGE
;
;CONSOLE OUTPUT ROUTINE (OUTPUT CHARACTER FROM C REG)
;
CO:
	PUSH	H		;SAVE REGISTERS
	PUSH	D
	PUSH	B
	LHLD	VECTAB		;GET POINTER BASE
	LXI	D,COTOFF	;GET OFFSET VALUE
	DAD	D
	LXI	D,CO1		;PUT A RET ONEMINI
	DB	'         OPTION (A,B,C,D,E OR F) = ','#'
	ENDIF
;
;
;******************************************************************************
;
;
MONITOR:
	CALL	CECHO		;GET OPERATOR ENTRY CHARACTER
	ANI	05FH		;CONVERT TO UPPER CASE
	SUI	'A'		;ADJUST TO ZERO VALUE
	CPI	04H
;
	JC	HDFMT		;GO DO HARD UNIT FORMAT
;
	CPI	04H		;CHECK FOR MINI FLOPPY E:
	JZ	MFFMT		;IF SO GO DO MINI FORMAT
;
	IF	NOT ONEMINI
	CPI	05H		;CHECK FOR MINI FLOPPY F:
	JZ	MFFMT
	ENDIF
;
	JMP	ERRR		;OPTION SELECT ERROR
;
	PAGE
;
;HERE IF WE WANT TO FORMAT A HARD DISK UNIT
;
HDFMT:
	PUSH	PSW		;SAVE CP/M DRIVE NUMBER
	MOV	C,A
	CALL	HPLAT		;GO SET HEAD/PLATTER NUMBER FOR CP/M DRIVE
	MVI	C,0
	CALL	HSURF
	LXI	D,GOMS1		;PRINT ARE YOU SURE MESSAGE
	CALL	CRTMS
	POP	PSW
	ADI	'A'		;SET FOR ASCII PRINTING OF DRIVE
	MOV	C,A
	CALL	CO
	LXI	D,GOMS2
	CALL	CRTMS
	CALL	CECHO		;GET OPERATOR INPUT
	ANI	05FH		;CONVERT RESPONSE TO UPPER CASE
	CPI	'Y'
	JNZ	ENDCHK		;IF NOT READY THEN GO TO END CHECK
;
	LXI	D,GOMS4		;PRINT SECOND MAKE SURE MESSAGE
	CALL	CRTMS
	CALL	CECHO		;GET OPERATOR RESPONSE
	ANI	05FH		;UPPER CASE
	CPI	'G'		;G FOR GO TO BE SURE
	JNZ	ENDCHK		;BALE OUT IF NOT REALLY READY
;
	CALL	CRLF
;
	CALL	FMDSK		;GO FORMAT THAT SELECTED UNIT
	CALL	E5FILL		;GO FILL TRACKS WITH 'E5'S
	JMP	FMTDONE
;
	PAGE
;
;HERE IF TO FORMAT A DISKETTE IN A MINI FLOPPY UNIT
;
MFFMT:
	PUSH	PSW
	SUI	MINISEL		;SET MINI FLOPPY BASE ADDRESS TO ZERO
	MOV	C,A		;SET MINI FLOPPY UNIT IN IOPB
	CALL	MUNIT
	MVI	C,COMPEN+MINIEN+DENSEL
	CALL	MMODE		;SET PROPER MINI FLOPPY MODE
	LXI	D,GOMS3		;PRINT READY MESSAGE FOR FLOPPY
	CALL	CRTMS
	POP	PSW
	ADI	'A'		;SET FOR ASCII UNIT NUMBER PRINTING
	MOV	C,A
	CALL	CO		;PRINT SELECTED MINI DESIGNATOR
	LXI	D,GOMS2
	CALL	CRTMS
	CALL	CECHO		;GET OPERATOR RESPONSE
	ANI	05FH		;UPPER CASE
	CPI	'Y'
	JNZ	ENDCHK		;END PROCESS IF NOT READY
;
	LXI	D,GOMS4		;PRINT SECOND MAKE SURE MESSAGE
	CALL	CRTMS
	CALL	CECHO		;GET OPERATOR RESPONSE
	ANI	05FH		;UPPER CASE
	CPI	'G'		;G FOR GO TO BE SURE
	JNZ	ENDCHK		;BALE OUT IF NOT REALLY READY
;
	CALL	CRLF
	CALL	FLOPFMT		;GO FORMAT SELECTED MINI FLOPPY
;
FMTDONE:
	LXI	D,FORDMS	;PRINT FORMAT COMPLETE MESSAGE
	CALL	CRTMS
	JMP	ENDCHK
;
	PAGE
;
GOMS1:
	DB	CR,LF,'READY TO FORMAT HARD DISK DRIVE ','#'
GOMS2:
	DB	': (Y/N) ','#'
GOMS3:
	DB	CR,LF,'HAS DISKETTE BEEN INSTALLED IN DRIVE ','#'
GOMS4:
	DB	CR,LF,'ALL INFORMATION ON DISK WILL BE ERASED. '
	DB	CR,LF,'TYPE "G" TO FORMAT OR "N" TO STOP (G/N) ','#'
FORDMS:
	DB	CR,LF,'FORMATTING COMPLETE',CR,LF,'#'
;
;
;******************************************************************************
;
;	OPERATION DONE OR ERROR EXIT POINT
;
;
ENDCHK:
	LXI	D,DONMSG	;PRINT DONE MESSAGE
	CALL	CRTMS
	CALL	CECHO		;GET OPERATOR ANSWER
	ANI	05FH		;CONVERT RESPONSE TO UPPER CASE
	CPI	'Y'		;SEE IF HE WANTS TO GO AGAIN
	JZ	SIGNON		;GO START ALL OVER AGAIN
;
	CALL	CRLF
	LHLD	VECTAB		;GET WARM BOOT JUMP ADDRESS
	PCHL			;GO TO WARM BOOT
;
;
DONMSG:
	DB	CR,LF,'MORE DISKS TO BE FORMATTED? (Y/N) ','#'
;
	PAGE
;******************************************************************************
;
;	GENERAL PURPOSE I/O SUBROUTINES 
;
;
CRLF:				;ROUTINE TO DO CONSOL CR AND LF
	MVI	C,CR
	CALL	CO
	MVI	C,LF
	CALL	CO
	RET
;
;
;
CECHO:				;ROUTINE TO GET AND ECHO A CHARACTER
	CALL	CI
	MOV	C,A
	PUSH	PSW
	CALL	CO
	POP	PSW
	ANI	07FH		;GET RID OF PARITY
	RET
;
;
;
NBL:				;ROUTINE TO CONVERT A BYTE TO A HEX NIBBLE
	SUI	'0'
	RC
	ADI	0E9H
	RC
	ADI	06H
	JP	NIO
	ADI	07H
	RC
NIO:
	ADI	10
	ORA	A
	RET
;
	PAGE
;
BYTEC:				;ROUTINE TO GET A HEX BYTE IN A
	CALL	CECHO		;GET CHARACTER
BYTC1:
	CALL	NBL		;CONVERT TO HEX
	JC	ERRR		;TO ERROR ROUTINE
	RLC
	RLC
	RLC
	RLC
	PUSH	PSW		;SAVE 1ST ENTRY
	CALL	CECHO		;GET 2ND CHARACTER
	CALL	NBL		;CONVERT IT TO HEX
	JC	ERRR
	POP	B		;RECOVER 1ST RESULT
	ORA	B		;COMBINE WITH 2ND
	RET
;
;
;
CONI:				;ROUTINE TO GET A 1 BYTE PARAMETER
	PUSH	B
	CALL	BYTEC
	POP	B
	RET
;
	PAGE
;
PARAM:				;ROUTINE TO INPUT 4 HEX CHARACTERS
	LXI	H,0
PARM1:
	CALL	CECHO		;GET INPUT
	CPI	0DH		;LOOK FOR RETURN
	RZ
	DAD	H
	DAD	H
	DAD	H
	DAD	H
	JC	ERRR
	CALL	NBL		;CONVERT ENTRY TO HEX
	JC	ERRR
	ORA	L
	MOV	L,A
	JMP	PARM1		;GO FOR NEXT CHARACTER
;
;
;
HLCO1:				;ROUTINE TO PRINT CONTENTS OF (HL)
	MOV	A,H
	CALL	BYTEO
	MOV	A,L
	CALL	BYTEO
	RET
;
	PAGE
;
BYTEO:				;ROUTINE TO OUTPUT A HEX BYTE TO THE CONSOLE
	PUSH	PSW
	CALL	BYTO1
	MOV	C,A
	CALL	CO
	POP	PSW
	CALL	BYTO2
	MOV	C,A
	CALL	CO
	RET
;
BYTO1:
	RRC
	RRC
	RRC
	RRC
BYTO2:
	ANI	0FH
	CPI	0AH
	JM	BYTO3
	ADI	07H
BYTO3:
	ADI	030H
	RET
;
;
;ERROR ON ENTRY OF OPERATOR PARAMETERS
;
ERRR:
	MVI	C,'?'		;OUTPUT UNKNOWN PARAMETER
	CALL	CO
	CALL	CRLF
	JMP	ENDCHK		;GO TO OPERATOR END CHECK SEQUENCE
;
	PAGE
;******************************************************************************
;
;
;CRTMS - ROUTINE TO DISPLAY A MESSAGE ON THE CRT. REGISTERS D AND E
;	 CONTAIN THE MESSAGE POINTER. END OF MESSAGE IS INDICATED BY
;	 A "#" CHARACTER.
;
;
CRTMS:				;ROUTINE PRINTS MESSAGE ON CRT
	LDAX	D
	CPI	'#'		;END MESSAGE MARKER
	RZ			;YES - RETURN
	MOV	C,A
	CALL	CO
	INX	D
	JMP	CRTMS
;
;
;******************************************************************************
;
;	SHORT DELAY ROUTINE FOR TIME DELAYS OF (A REG) X 1 MSEC
;
;
SDLY:
	MVI	L,070H		;ONE MILLISECOND TIME FACTOR
	DCR	L		;..COUNT IN (A)
	JNZ	$-1
	DCR	A
	JNZ	SDLY
	RET
;
	PAGE
;*********************************************************************
;
;	FORMAT WHOLE PLATTER OF 412 DRIVE DIRECT FIRMWARE
;
;
FMDSK:
	CALL	HREST		;RESTORE DRIVE AS REQUIRED BY CTLR
	ORA	A		;CHECK I/O STATUS
	JNZ	RESPERR
;
	LXI	H,0000H		;START WITH CYLINDER ZERO
	SHLD	CURCYL
FMCYL:
	LHLD	CURCYL		;SPECIFY CURRENT CYLINDER
	MOV	C,L		;SET IOPB FOR CYLINDER
	MOV	B,H
	CALL	HCYL
 	CALL	FMEXEC		;GO EXECUTE FORMAT FOR THIS TRACK
	LHLD	CURCYL
	INX	H		;INCREMENT CYLINDER NUMBER
	SHLD	CURCYL
	LXI	D,MAXTRK+1	;CHECK IF DONE WITH LAST CYLINDER
	XCHG
	CALL	CDEHL		;DOUBLE COMPARE
	JNZ	FMCYL		;GO DO NEXT CYLINDER IF NOT
	RET
;
;
;EXECUTE FORMAT INSTRUCTION FOR SELECTED CYLINDER
;
FMEXEC:
	MVI	C,DIFMT		;SETUP FORMAT INSTRUCTION
	CALL	HEXEC		;GO EXECUTE THIS COMMAND
	ORA	A
	JNZ	RESPERR		;BALE OUT IF ERROR
	RET
;
	PAGE
;******************************************************************************
;
;	MINI FLOPPY FORMAT ROUTINE WILL FORMAT ALL TRACKS ON BOTH 
;	SIDES OF A MINI FLOPPY DISKETTE. THE TRACK NUMBERS ARE CYCLED
;	TO TWICE THE NUMBER OF TRACKS PER SIDE SO THAT THE LEAST
;	SIGNIFICANT BIT BECOMES THE SIDE SELECT BIT FOR THE DOUBLE
;	HEADED TANDON TM100 96 TPI DRIVE.
;
FLOPFMT:
	CALL	MREST		;RESTORE SELECTED UNIT
	ORA	A		;CHECK RESTORE STATUS
	JNZ	FLPERR		;OUT IF ERROR
;
	XRA	A		;SET INITIAL TRACK TO ZERO
	STA	CURCYL
FLFMTLP:
	MVI	C,01H		;SET SECTOR DEFAULT TO 1
	CALL	MREC
	LDA	CURCYL		;TURN TRACK TO SIDE/PHYS TRACK
	PUSH	PSW
	ANI	01H		;FIND OUT WHAT THE SIDE NUMBER IS
	MOV	C,A
	CALL	MSURF		;SET MINI HEAD NUMBER
	POP	PSW
	ORA	A
	RAR			;DIVIDE TRACK BY 2
	MOV	C,A		;SEND PHYSICAL TRACK TO IOPB
	CALL	MCYL
;
	CALL	TRKFILL		;GO BUILD THE IMAGE FOR THIS TRACK 
	LXI	B,DATBF		;SET FLOPPY I/O POINTER ADDRESS
	CALL	MBADDR
	MVI	C,00H		;SET BLOCK WRITE SIZE
	CALL	MSIZE
	MVI	C,25		;SET NUMBER OF BLOCKS TO WRITE
	CALL	MCNT
	CALL	MWTRK		;GO ATTEMPT TO WRITE THE TRACK
	ORA	A
	JNZ	FLPERR		;IF WRITE ERROR THEN QUIT
;
	MVI	C,01H		;SET START SECTOR FOR VERIFY
	CALL	MREC
;
	MVI	C,00		;SET FLOPPY SIZE OF SECTOR
	CALL	MSIZE		;TO NUMBER OF UNITS
	MVI	C,16		;SET NUMBER OF SECTORS TO READ
	CALL	MCNT
	CALL	MREAD		;GO READ ALL SECTORS OF TRACK
	ORA	A
	JNZ	FLPERR		;GO REPORT ERROR IF SECTORS COULDN'T BE READ
;
	LXI	D,TRKMSG	;PRINT TRACK REPORT MESSAGE
	CALL	CRTMS
	LDA	CURCYL		;..AND JUST COMPLETED TRACK NUMBER
	CALL	BYTEO
;
	LDA	CURCYL		;SET FOR NEXT TRACK NUMBER
	INR	A
	STA	CURCYL		;SAVE OFF FOR I/O ROUTINE
	CPI	(FTPS*2)+1	;CHECK IF WEVE DONE ALL TRACKS
	JNZ	FLFMTLP
;
	RET
;
;MINI FLOPPY FORMAT TRACK REPORT MESSAGE
;
TRKMSG:
	DB	CR,'TRACK ','#'
;
	PAGE
;******************************************************************************
;
;	MINI FLOPPY TRACK IMAGE BUILDING ROUTINE
;
;	THIS BUILDS AN IMAGE INTO MEMORY FOR THE MINI FLOPPY
;	TRACK FORMAT IMAGE. VARIABLES REQUIRED TO BE SETUP
;	BEFORE ENTRY ARE "FLPTRK" WITH THE TRACK NUMBER AND
;	"FSIDE" WITH THE SIDE NUMBER.
;
TRKFILL:
	MVI	D,01H		;START SECTOR COUNT
	MVI	E,FSPT		;MAX NUMBER OF SECTORS ON TRACK
	LXI	H,DATBF		;POINT TO BUFFER FOR IMAGE BULID
;
;
;FIXUP PREINDEX GAP 4A
;
	MVI	B,80		;PREINDEX FILL 80 BYTES OF "4E"
	MVI	A,04EH
PREIND:
	MOV	M,A		;PUT 4E INTO BUFFER
	INX	H
	DCR	B		;CHECK BYTE COUNT
	JNZ	PREIND
;
	MVI	B,12		;SYNC 12 BYTES OF "00"
	MVI	A,00H
PREIND1:
	MOV	M,A		;PUT 00 INTO BUFFER
	INX	H
	DCR	B		;CHECK BYTE COUNT
	JNZ	PREIND1
;
;
;WRITE INDEX ADDRESS MARK ONTO TRACK HERE
;
	MVI	B,03		;THREE BYTES OF "F6"
	MVI	A,0F6H
IAM:
	MOV	M,A		;PUT F6 INTO BUFFER
	INX	H
	DCR	B		;CHECK BYTE COUNT
	JNZ	IAM
;
;
;WRITE INDEX MARK ITSELF
;
	MVI	M,0FCH		;ONE BYTE OF "F6"
	INX	H
;
;
;WRITE POST INDEX GAP 1
;
	MVI	B,50		;GAP 1 50 BYTES OF "4E"
	MVI	A,04EH
POSTID:
	MOV	M,A		;PUT 4E INTO BUFFER
	INX	H
	DCR	B		;CHECK BYTE COUNT
	JNZ	POSTID
;
;
;PRE SECTOR ID SYNC (ALSO ENTRY POINT TO DO NEXT SECTOR)
;
SECTOR:
	MVI	B,012		;12 BYTES OF "00"
	MVI	A,00H
SECSYNC:
	MOV	M,A		;PUT THE 00 INTO BUFFER
	INX	H
	DCR	B		;CHECK THE BYTE COUNT
	JNZ	SECSYNC
;
;
;WRITE SECTOR ID ADDRESS MARK
;
	MVI	B,03H		;THREE BYTES OF "F5"
	MVI	A,0F5H
SIDAM:
	MOV	M,A		;PUT F5 INTO BUFFER
	INX	H
	DCR	B		;CHECK THAT BYTE COUNT
	JNZ	SIDAM
;
;
;PUT SINGLE BYTE SECTOR ID MARK
;
	MVI	M,0FEH		;ONE BYTE "FE"
	INX	H
;
;
;WRITE TRACK NUMBER INTO ID FIELD
;
	LDA	CURCYL		;GET TRACK NUMBER VARIABLE
	PUSH	PSW
	ORA	A
	RAR			;DIVIDE TRACK BY 2
	MOV	M,A
	INX	H
;
;
;WRITE SIDE NUMBER INTO THE ID FIELD
;
	POP	PSW
	ANI	01H		;FIND OUT WHAT THE SIDE NUMBER IS
	MOV	M,A
	INX	H
;
;
;PUT SECTOR NUMBER INTO THE ID FIELD
;
	MOV	M,D		;GET SECTOR NUMBER FROM (D)
	INX	H
;
;
;PUT DATA FIELD LENGTH BYTE INTO THE ID FIELD
;
	MVI	M,FSECCDE	;02 FOR 512 BYTE SECTORS
				;01 FOR 256 BYTE SECTORS
				;00 FOR 128 BYTE SECTORS
	INX	H
;
;
;SET CODE TO WRITE TWO CRC'S ONTO THE TRACK
;
	MVI	M,0F7H		;ONE BYTE "F7"
	INX	H
;
;
;FILL GAP 2 BEFORE DATA FIELD
;
	MVI	B,22		;22 BYTES OF "4E"
	MVI	A,04EH
PREDAT:
	MOV	M,A		;PUT THE 4E INTO BUFFER
	INX	H
	DCR	B		;CHECK THAT BYTE COUNT
	JNZ	PREDAT
;
;
;FILL DATA FIELD SYNC AREA
;
	MVI	B,12		;12 BYTES OF "00"
	MVI	A,00H
PREDAT1:
	MOV	M,A		;PUT 00 INTO BUFFER
	INX	H
	DCR	B		;CHECK THAT BYTE COUNT ONE MORE TIME...
	JNZ	PREDAT1
;
;
;WRITE DATA ADDRESS MARK
;
	MVI	B,03		;THREE BYTES OF "F5"
	MVI	A,0F5H
DAM:
	MOV	M,A		;PUT THE F5 INTO BUFFER
	INX	H
	DCR	B		;BYTE COUNT CHECK
	JNZ	DAM
;
;
;ONE BYTE DATA FIELD MARK
;
	MVI	M,0FBH		;ONE BYTE OF 0FBH
	INX	H
;
;
;FILL DATA FIELD WITH 0E5H DATA
;
	LXI	B,FSECSIZ	;GET SECTOR BYTE COUNT
DFILL:
	MVI	M,0E5H		;PUT E5 INTO BUFFER
	INX	H
	DCX	B		;CHECK BYTE COUNT
	MOV	A,B
	ORA	C
	JNZ	DFILL
;
;
;SET CODE TO WRITE DATA FIELD CRC'S
;
	MVI	M,0F7H		;ONE BYTE CRC CODE (F7)
	INX	H
;
;
;END SECTOR FILL
;
	MVI	B,54		;54 BYTES OF "4E"
	MVI	A,04EH
DATGAP:
	MOV	M,A		;PUT THE 4E INTO BUFFER
	INX	H
	DCR	B
	JNZ	DATGAP
;
;
;CHECK IF DONE WITH LAST SECTOR IMAGE
;
	INR	D		;GET SECTOR NUMBER READY FOR NEXT LOOP
	DCR	E		;DEC TOTAL SECTOR COUNT
	JNZ	SECTOR		;OFF TO DO THAT AGAIN FOR NEXT SECTOR
;
;
;END TRACK FILL
;
	LXI	B,2300		;FILL TO END OF TRACK WITH "4E"
ETFILL:
	MVI	M,04EH		;PUT THE "4E" INTO BUFFER
	INX	H
	DCX	B		;CHECK THE BYTE COUNT
	MOV	A,B
	ORA	C
	JNZ 	ETFILL
;
	RET			;BUFFER NOW SETUP
;
	PAGE
;******************************************************************************
;
;	TRACK 2 0E5H DATA FILLING SUBROUTINE TO SET THE CP/M
;	DIRECTORY TRACK RIGHT FOR THE EMPTY FILLER BYTES
;
E5FILL:
	CALL	FILL		;PUT DATA INTO BUFFER
	LXI	H,0002H		;SET START CYLINDER 2
E5NTRK:
	PUSH	H		;SAVE CURRENT FILL CYLINDER NUMBER
	MOV	C,L		;SET IOPB CYLINDER
	MOV	B,H
	CALL	HCYL
	MVI	C,01		;START WITH FIRST RECORD
E5FLP:
	PUSH	B		;SAVE RECORD COUNTER
	CALL	HREC		;PUT RECORD INTO IOPB
	LXI	B,DATBF		;POINT CONTROLLER TO DATA BUFFER
	CALL	HBADDR
	CALL	HWRIT		;WRITE IT
	ORA	A
	JNZ	RESPERR		;BALE OUT IF ERROR
	CALL	HVERF		;VERIFY THAT ITS RIGHT
	ORA	A
	JNZ	RESPERR		;BALE OUT IF ERROR
;
	POP	B
	INR	C		;INCREMENT RECORD NUMBER
	MOV	A,C		;CHECK IF DONE
	CPI	MAXREC+1
	JNZ	E5FLP
;
	POP	H		;GET BACK JUST DONE CYLINDER NUMBER
	INX	H		;GET READY FOR NEXT ONE
	LXI	D,LASTE5+1	;SEE IF DONE WITH LAST TRACK
	CALL	CDEHL		;GO COMPARE
	JNZ	E5NTRK		;NOT DONE THEN GO DO NEXT TRACK
;
	RET			;GO BACK TO THOSE WHOM CALLED US
;
	PAGE
;
;DATA BUFFER FILL SUBROUTINE FOR THE FORMAT PROGRAM
;
FILL:
	MVI	D,FMTCHAR	;PUT FILL BYTE IN (D)
	LXI	H,DATBF		;POINT TO FILL AREA
	LXI	B,SECSIZ	;GET BUFFER SIZE
FILLP:
	MOV	M,D		;PUT BYTE IN
	INX	H		;INC BUFFER POINTER
	DCX	B		;DECREASE BYTE COUNT
	MOV	A,B
	ORA	C
	JNZ	FILLP		;DONE YET?
	RET
;
;
;******************************************************************************
;SHORT ROUTINE TO REPORT ERROR CODE ON OPERATION TO THE CONSOLE
;FOR A SIMPLE DEGREE OF FAULT ISOLATION. "STCHK" ERROR CODE IS REPORTED
;
;ENTRY POINT RESPERR: IS USED FOR HARD DISK WHILE
;ENTRY POINT FLPERR: IS USED FOR MINI FLOPPY ERROR REPORTING
;
RESPERR:			;ENTRY POINT FOR HARD DISK ERRORS
	PUSH	PSW		;SAVE THE ERROR CODE
	LXI	D,ERRMSG	;PRINT ERROR MESSAGE
	JMP	ERRFIN		;GO FINISH ERROR ROUTINE
FLPERR:				;ENTRY POINT FOR FLOPPY DISK ERRORS
	PUSH	PSW
	LXI	D,ERRMS2	;PRINT MINI FLOPPY ERROR MESSAGE
ERRFIN:
	CALL	CRTMS
	POP	PSW
	CALL	BYTEO		;OUTPUT ERROR CODE
	LXI	D,ERRMS1	;PRINT REST OF MESSAGE
	CALL	CRTMS
	JMP	ENDCHK
;
	PAGE
;
ERRMSG:
	DB	CR,LF,CR,LF,BEL,BEL,' *** HARD DISK I/O ERROR - CODE(','#'
;
ERRMS1:
	DB	') ***',CR,LF,'#'
;
ERRMS2:
	DB	CR,LF,CR,LF,BEL,BEL,' *** MINI FLOPPY DISK I/O '
	DB	'ERROR - CODE(','#'
;
;
;******************************************************************************
;
;	DATA PARAMETER STORAGE FOR DISK CONTROLLER
;
;
;
CURCYL:
	DW	0		;CURRENT CYLINDER CHECK
;
;
;FORMAT PROGRAM STACK AREA
;
	DS	80		;SETUP STORAGE FOR 40 LEVEL STACK
STCKK	EQU	$
;
;
;
;LOCAL RECORD BUFFER AND MINI FLOPPY TRACK IMAGE BUFFER
;
DATBF:
	DS	SECSIZ		;DATA RECORD BUFFER
;
	END
;
;+++...END OF FILE
«eof»