;************************************************************************
;
;   CP/M 2.2 Cold Boot Loader for Vector Graphic 8 inch FDC.
;
;	This loader is present on track 0 sector 1 and is loaded into
;	memory at 300h by the boot PROM ("V" command in the monitor or
;	by jumping to E800).
;
;   	Created 4/5/16 by Mike Douglas by modifying the Micro Resources 
;       cold boot loader for the Tarbell controller
;
;       To patch an update to this boot loader into a CP/M image created
;	and saved after running MOVCPM, use the following commands:
;	
;	A>DDT CPM56.COM    (specify the saved CP/M image file)
;	-IBOOT.HEX
;	-R600
;	-G0		   (Go zero, not "oh")
;
;*************************************************************************
MSIZE	EQU  56			;MEMORY SIZE IN DECIMAL KILO-BYTES	  

EXTBIOS	EQU  0C00H		;EXTRA BIOS ALLOCATION BEYOND 600H (3K)
CBASE	EQU  MSIZE*1024-1C00H-EXTBIOS	;LOAD ADDRESS OF CP/M
BOOTE	EQU  CBASE+1600H	;COLD BOOT ENTRY POINT.

NSECTS	EQU  51			;TOTAL SECTORS OF CP/M.
SPT	EQU  26			;NUMBER OF SECTORS PER TRACK	
RTCNT	EQU  10			;NUMBER OF RETRYS

DISK	EQU  0E0H		;DISK PORT BASE ADDRESS		  
DCOM	EQU  DISK		;COMMAND PORT (1793)
DSTAT	EQU  DISK		;STATUS PORT (1793)
TRACK	EQU  DISK+1		;TRACK PORT (1793)
SECT	EQU  DISK+2		;SECTOR PORT (1793)
DATA	EQU  DISK+3		;DATA PORT (1793)
DCONT	EQU  DISK+4		;CONTROL PORT (on FDC board)

;-------------------------------------------------------------------------
	ORG  0300H		;START OF LOADER.

ENTRY:	JMP  START		;FIRST INSTRUCTION MUST BE A JUMP
				;   SINCE BOOT PROM CHECKS FOR IT

START:	MVI  E,RTCNT		;GET RETRY COUNT.

BLOOP:	LXI  SP,100H		;SET STACK POINTER.
	LXI  H,CBASE		;CP/M STARTS HERE.
	MVI  D,NSECTS		;NUMBER OF SECTORS TO READ.
	MVI  C,2		;SECTOR NUMBER.

RNTRK:	MVI  B,4		;FOR HEAD LOAD.
	MOV  A,C		;SECTOR IN A.

RNSEC:	CALL READ		;READ FIRST SECTOR.
	DCR  D			;IF DONE,
	JZ   BOOTE		;GO TO CP/M.

	MVI  B,0		;FOR NO HEAD LOAD.
	INR  C			;INCREMENT TRACK COUNT.
	MOV  A,C		;DONE WITH
	CPI  SPT+1		;THIS TRACK?
	JC   RNSEC		;IF NOT, READ NEXT SECTOR.

	MVI  A,52H		;STEP COMMAND AT 10 MSEC. RATE.
	OUT  DCOM		;ISSUE IT.
	CALL WTCOMP		;WAIT FOR COMMAND TO COMPLETE
	
	MVI  C,1		;SECTOR NUMBER.
	JMP  RNTRK		;READ NEXT TRACK.

READ:	OUT  SECT		;SET SECTOR REGISTER.
	CALL CHECK		;CHECK FOR ERROR.
	MVI  A,88H		;COMMAND FOR READ.
	ORA  B			;GET HEAD LOAD BIT.
	OUT  DCOM		;ISSUE COMMAND.
	CALL RDSEC		;TRANSFER SECTOR TO MEMORY

CHECK:	IN   DSTAT		;READ STATUS.
	ANI  9DH		;LOOK AT ERROR BITS.
	RZ			;OK IF ZERO.
	DCR  E			;DECREMENT RETRY COUNT.
	JNZ  BLOOP		;TRY AGAIN IF NOT ZERO.
	STA  EC			;SAVE ERROR CODE.
	HLT			;ARGHHHH.....HALT

WTCOMP:	IN   DCONT		;ALLOWS NMI TO OCCUR
	NOP
	JMP  WTCOMP		;LOOP UNTIL NMI EXITS THIS

RDSEC:	IN   DCONT		;LOOK FOR DRQ BIT
	RRC
	JNC  RDSEC

	IN   DATA		;GET THE NEXT BYTE
	MOV  M,A		;STORE IN MEMORY
	INX  H
	JMP  RDSEC		;LOOP FOR ALL BYTES IN SECTOR

EC:				;ERROR CODE GOES HERE
	END
