FMTBOO ;		* * * * * * * * * * * * *
 ;		*  PROGRAM BY KIM WATT  *
 ;		* BREEZE COMPUTING INC. *
 ;		*     P.O. BOX  1013    *
 ;		* BERKLEY, MICH.  48072 *
 ;		*    (313)  288-9422    *
 ;		* * * * * * * * * * * * * 
 ;
 ;
 	ORG	4200H		;ALL LOADERS START HERE
 ENTRY	DI			;CAN'T BE BOTHERED
 	LD	SP,4200H	;BUILDS DOWNWARD
 	CALL	DISPLY		;DISPLAY FOLLOWING MESS.
 ;  PROGRAM EXECUTION WILL BE RETURNED TO THE FIRST
 ;	INSTRUCTION AFTER BYTE 0.
 	DEFB	1CH		;HOME CURSOR BYTE
 	DEFB	1FH		;CLEAR TO END OF SCREEN
 ;	USER DISPLAY MESSAGE
 	DEFM	'-FORMAT loader by Kim Watt-'
 	DEFW	0D0DH
 	DEFB	0		;END OF MESSAGE MARKER
 	LD	DE,0300H	;START TRACK/SECTOR
 	LD	BC,6D00H	;LOAD ADDRESS
 SELECT	PUSH	BC		;SAVE LOAD ADDRESS
 	LD	HL,20		;# OF SECTORS TO READ
 	PUSH	HL		;SAVE ON STACK
 AGAIN	LD	A,1		;SELECT
 	LD	(37E1H),A	;	DRIVE 0
 ;
 	CALL	READ		;READ A SECTOR
 	JR	NZ,ERROR	;UNSUCCESSFUL READ
 	POP	HL		;GET SECTOR COUNT
 	DEC	L		;DECREMENT COUNTER
 	JP	Z,LOADED	;ENTRY POINT
 ; THIS RETURN INSTRUCTION WILL TRANSFER CONTROL
 ;	TO THE PROGRAM THAT WAS JUST LOADED.
 ;	USER MAY POP THIS VALUE AND JUMP ELSEWHERE.
 	PUSH	HL		;PUSH COUNT BACK ON STACK
 	INC	E		;INCREMENT SECTOR POINTER
 	LD	A,E		;TEST IS SECTOR COUNT IS
 	SUB	0AH		;   OVER 10
 	JP	NZ,AGAIN	;BACK FOR NEXT SECTOR
 	LD	E,A		;SECTOR COUNT -10
 	INC	D		;INCREMENT TRACK COUNT
 	JP	AGAIN		;GET NEXT SECTOR
 READ	PUSH	BC		;SAVE BEGINNING POINTER
 	CALL	READIT		;READ THE SECTOR
 	POP	HL		;CURRENT LOAD POINTER
 	RET	Z		;READ WAS SUCCESSFUL
 ;  IF THE FIRST READ IS UNSUCCESSFUL, ONE MORE TRY !
 	LD	B,H		;TRANSFER POINTER
 	LD	C,L		;   TO BYTE COUNTER
 READIT	LD	(37EEH),DE	;TRACK/SECTOR TO SEEK
 	LD	HL,37ECH	;COMMAND REGISTER
 	LD	(HL),1BH	;SEEK COMMAND
 ;	RESULT:	LOAD HEAD
 ;		DO NOT VERIFY
 ;		STEPPER MOTOR AT 20 MS.
 ;		SEEK TRACK AND SECTOR
 	PUSH	AF
 	POP	AF
 	PUSH	AF
 	POP	AF
 ;  SMALL DELAY FOR THE CONTROLLER STATUS TO BECOME VALID
 TESTBZ	LD	A,(HL)		;GET CONTROLLER STATUS
 	RRCA			;BIT 0 IS SET IF COMMAND
 	JP	C,TESTBZ	;	IN PROGRESS
 	LD	(HL),88H	;READ SECTOR BYTE
 ;	RESULT:	SINGLE SECTOR READ
 ;		IBM 3740 DATA FORMAT (STANDARD)
 ;		HEAD ASSUMED ENGAGED
 	PUSH	DE		;SAVE TRACK/SECTOR
 	LD	DE,37EFH	;DATA TRANSFER ADDRESS
 	PUSH	BC
 	POP	BC
 	PUSH	BC
 	POP	BC
 ;  SMALL DELAY FOR THE CONTROLLER STATUS TO BECOME VALID
 	JP	BZTEST		;WAIT FOR READY
 TEST	RRCA			;BIT 0 SET IF BUSY
 	JP	NC,TEST1	;NOT READY YET
 BZTEST	LD	A,(HL)		;GET STATUS BYTE
 	BIT	1,A		;BIT 1 IS SET IF 37EF
 	JP	Z,TEST		;  CONTAINS VALID BYTE
 	LD	A,(DE)		;GET THE NEW BYTE
 	LD	(BC),A		;SAVE IN BUFFER
 	INC	BC		;POINT TO NEXT LOAD ADDR.
 	JP	BZTEST		;WAIT FOR NEXT BYTE
 TEST1	LD	A,(HL)		;GET STATUS BYTE
 	AND	1CH		;ERROR FLAGS
 ;	COULD BE COMPARE WITH C5 TO TEST ACTUAL VALIDITY
 	POP	DE		;RESTORE LOAD POINTER
 	RET	Z		;SUCCESSFUL READ
 	LD	(HL),0D0H	;FORCE INTERRUPT OF DISK
 	RET			;DISK ERROR
 ERROR	CALL	DISPLY		;DISPLAY MESSAGE
 	DEFB	17H		;VIDEO DOUBLE SIZE
 ;  USER ERROR MESSAGE IF I/O ERROR DURING LOAD PROCESS
 	DEFM	'! DISK ERROR !'
 	DEFB	0		;END OF MESSAGE
 	JR	WAIT
 ;  ADDRESS OF WHERE ERROR WAS GENERATED IS ON STACK
 ;	USER MAY RETRY-TO READ BY PRESSING ANY KEY
 DISPLY	POP	DE		;GET DATA POINTER
 DISLP	LD	HL,(4020H)	;GET CURSOR POSITION
 	LD	A,(DE)		;GET A BYTE
 	INC	DE		;POINT TO NEXT
 	OR	A		;FLAGS
 	JR	Z,DISDN		;TERMINATOR
 	CP	20H		;DISPLAYABLE ?
 	JR	C,DISCTL
 	LD	(HL),A		;DISPLAY BYTE
 	CP	(HL)		;STILL THERE ?
 	JR	Z,DISOK
 	SUB	20H		;MAKE IT UPPER CASE
 	LD	(HL),A		;RE-WRITE IT
 DISOK	INC	HL		;ADVANCE CURSOR
 	LD	(4020H),HL	;UPDATE CURSOR
 	JR	DISLP
 DISCTL	PUSH	DE
 	CALL	33H
 	POP	DE
 	JR	DISLP
 DISDN	PUSH	DE		;RETURN ADDRESS
 	RET			;GO TO IT
 LOADED	LD	A,(3840H)
 	BIT	2,A
 	JP	NZ,6D00H
 	CALL	DISPLY
 	DEFM	'Loading Completed.'
 	DEFB	0DH
 	DEFM	'Mount your DOS. Re-boot.'
 	DEFB	0
 WAIT	JR	WAIT
 	END	ENTRY
RETURN ADDRESS
 	RET			;GO TO IT
 LOADED	LD	A,(3840H)
 	BIT	2,A
 	JP	NZ,6D00H
 	CALL	DISPLY
 	DEFM	'Loading Com