;************************************************************************
;
;    MICRO RESOURCES CP/M 2.2 COLD BOOT LOADER FOR TARBELL CONTROLLER
;
;    Updated 11/15/17 by Mike Douglas to work with track-buffered
;    CP/M 2.2b on the Poly-88. This required changing the formula
;    for the CBASE equate (the address at which CP/M loads) to account
;    for the additional 3K of memory space used by the track buffered
;    BIOS. See the EXTBIOS (extra BIOS memory) equate. Also, the ORG
;    for the loader was changed to 0100h from 0000h so required
;    interrupt vectors on page zero are not clobbered.
;
;************************************************************************
;
;	TRACK ZERO SECTOR 1 COLD BOOT LOADER PROGRAM. THIS PROGRAM IS
;	PLACED INTO RAM AT ADDRESS 0100H BY THE PROM BOOT LOADER.
;
;       To patch an update to this loader into a CP/M image created
;	and saved after running MOVCPM, use the following commands:
;
;	   A>DDT CPM58.COM    (specify the saved CP/M image file)
;	   -IBOOT.HEX
;	   -R800
;	   -G0
;
;	COPYRIGHT 1982
;	MICHAEL J. KARAS
;	MICRO RESOURCES
;
MSIZE	EQU  58			;MEMORY SIZE IN DECIMAL KILO-BYTES

SPT	EQU  26			;NUMBER OF SECTORS PER TRACK.
DISK	EQU  0E8H		;DISK PORT BASE ADDRESS.

DCOM	EQU  DISK		;COMMAND PORT.
DSTAT	EQU  DISK		;STATUS PORT.
TRACK	EQU  DISK+1		;TRACK PORT.
SECT	EQU  DISK+2		;SECTOR PORT.
DATA	EQU  DISK+3		;DATA PORT.
WAIT	EQU  DISK+4		;WAIT PORT.
DCONT	EQU  DISK+4		;CONTROL PORT.

EXTBIOS	EQU  0C00H		;EXTRA BIOS ALLOCATION BEYOND 600H (3K)
CBASE	EQU  MSIZE*1024-1C00H-EXTBIOS	;BIAS FOR LARGER THAN 20K BYTE MEMORY
CPMB	EQU  CBASE		;START OF CP/M.
BOOTE	EQU  CBASE+1600H	;COLD BOOT ENTRY POINT.
NSECTS	EQU  51			;TOTAL SECTORS OF CP/M.
RTCNT	EQU  10			;NUMBER OF RETRYS.

	ORG  0100H		;START OF LOADER (CAN'T BE ON PAGE ZERO)

BOOT:
	MVI  E,RTCNT		;GET RETRY COUNT.
	DI			;DISABLE INTERRUPTS
BLOOP:
	LXI  SP,100H		;SET STACK POINTER.
	LXI  H,CPMB		;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.
	IN   WAIT		;WAIT UNTIL DONE.
	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.
RLOOP:
	IN   WAIT		;WAIT FOR DRQ.
	ORA  A			;SET FLAGS.
	JP   CHECK		;JUMP IF DONE.
	IN   DATA		;READ DATA.
	MOV  M,A		;PUT IN MEMORY.
	INX  H			;INCREMENT POINTER.
	JMP  RLOOP		;LOOP UNTIL DONE.

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.
HERE:
	HLT			;ARGHHHH.....HALT

EC:	DS   1			;FAILURE ERROR CODE

	END
