;==============================================================
; Bootstrap routine for Processor Technology's  Helios disks
; From page A2-2 of the PTDOS User's Manual
; Annotated by Martin Eberhard 21 April 2018
;==============================================================

;Bootstrap Equates

BSADR	equ	800h		;where this code loads
BOTLEN	equ	340h		;Boot Code length
LODADR	equ	0		;Load address
;                               ;(0 is assumed in the code)
EXEADR	equ	4		;execution address

;Helios Controller Ports (page 7-10)

HEBASE	equ	0F0h		;Helios controller base address
HESTAT	equ	HEBASE		;Status input
HETCMD	equ	HEBASE+1	;Transfer Command output
HETLL	equ	HEBASE+3	;Transfer Length Low output
HETLH	equ	HEBASE+4	;Transfer Length High output
HETAL	equ	HEBASE+5	;Transfer Address High output
				;also clears HESTAT
HETAH	equ	HEBASE+6	;Transfer Address High output
HEDCMD	equ	HEBASE+7	;Drive Command output

;Helios Status bits (page 7-4)

HSTC	equ	01h		;High=Transfer Complete
HSSRDY	equ	02h		;High=SREADY	
HSABRT	equ	04h		;High=Abort
HSCRCE	equ	08h		;High=CRC Error
HSCRCC	equ	10h		;High=CRC Checked
HSRDYN	equ	20h		;Low=Disk Ready
				;(selected, loaded, spinning)
HSSKCN	equ	40h		;Low=Seek Complete
HSIDXN	equ	80h		;Low=Index Hole Present

;Helios Transfer Command Bits, all active low (page 7-4)

HTNONE	equ	0FFh		;no command
HTERAN	equ	0FEh		;Low=Erase (page 7-36)
HTWRN	equ	0FDh		;Low=Write, High=Read
HTDATN	equ	0FBh		;Low=Data, High=header
HTENN	equ	0F7h		;Low=enable transfer

;Helios Drive Command Bits, all active low (page 7-5)

HDSTPN	equ	0FEh		;Low=step
HDSIN	equ	0FDh		;Low = step in, high=step out
HDDS1N	equ	0FBh		;Drive Select 1, active low
HDDS2N	equ	0F7h		;Drive Select 2, active low
HDRSTN	equ	0EFh		;Restore Disk, active low
HDHL0N	equ	0DFh		;Load Even Head, active low
HDHL1N	equ	0BFh		;Load Odd Head, active low
HDDSN	equ	07Fh		;Select Odd Disk, active low

;=================
;Beginning of Code
;=================
	ORG	BSADR

; Restore the drive to track 0 and cancel any prior command

BOOTS:	MVI	A,HDRSTN and HDHL0N ;restore, load head 0
	OUT	HEDCMD

	OUT	HETAL		;clear status

	MVI	A,HTNONE	;end any previous command
	OUT	HETCMD

BOOTL:	IN	HESTAT		;wait for restore complete
	ANI	HSSKCN
	JNZ	BOOTL

;Load head 0 and wait for 2 index holes to pass

	MVI	A,HDHL0N	;Load head 0 on unit 0
	OUT	HEDCMD

IFIN:	IN	HESTAT		;wait for index hole
	RLC			;test HSIDXN
	JC	IFIN

	LXI	D,9504/12	;stall for 9.5 mS
IFIN2:	DCX	D		;(5)
	MOV	A,D		;(5)
	ORA	E		;(4)
	JNZ	IFIN2		;(10) 12 uS stall loop

IFIN3:	IN	HESTAT		;wait for index hole
	RLC			;test HSIDXN
	JC	IFIN3

;Set up to read BOTLEN bytes from the next block
;(block 0) into RAM at address 0

SWAIT:	IN	HESTAT		;Wait for drive ready
	ANI	HSSRDY
	JZ	SWAIT

	MVI	A,BOTLEN and 0FFh ;set up transfer length
	OUT	HETLL
	MVI	A,BOTLEN/256
	OUT	HETLH

	XRA	A		;load at address 0
	OUT	HETAL
	OUT	HETAH

;Issue the read command and wait for it to complete

	MVI	A,(HTENN or HTDATN) and 0Fh
	OUT	HETCMD		;issue read data command

DLOOP:	IN	HESTAT		;Wait for done or CRC error
	ANI	HSTC or HSSRDY or HSCRCE
	JZ	DLOOP

;Retry the load if a CRC error is detected.
;Otherwise, execute the code you loaded.

	ANI	HSCRCE		;CRC error?
	JNZ	BOOTS		;y: start over

	JMP	EXEADR

	END	BSADR
