;  EtherBootPatchCode.asm


; last edited by : Sturgis:    4-Oct-83 11:29:35

	get	"SysDefs.asm"
	get	"BootDefs.asm"
	get	"BootLinkDefs.asm"
	
	
; this module is expected to be loaded with BootSubs
	
	IMP	ErrorReport, IncrMP, PhaseToMP, PutMP, ReadMainMem
	IMP	Delay, BootInit, StartCPKernel, StartCP

; here is the actual start, this lands in 2000
	jmp	MultiEtherBootNextPhase
	

; comment the following when running outside burdock	

;	IMP	BootGo

; Un comment the following code when running outside burdock

	EXP	StartIOPBoot, StartNextPhase
StartIOPBoot: dw	0
StartNextPhase: dw	0
BootGo:	dw	0

; following definition for Burdock

StartIOPAddressHigh	equ	StartIOPAddress+1



; following is start of the patch

MultiEtherBootNextPhase:
	lhld	BootGoExt+1; we now have the address of BootGo in h,l
	lxi	d, 201H; (StartNextPhase-BootGo) within BootMain
	dad	d
	shld	StartIOPAddress; thus, this code will not run again
	call	CheckCP
	call	CollectSubBoot
	call	InformCPofSubBoot
	call	CheckCP
	lhld	StartIOPAddress
	pchl	; go to where StartIOPAddress says, 
		; i.e. BootMain.StartNextPhase
	
; user selected value in the lights		file number
;			 3				100'b
;			 6				101'b
;			20				120'b	
;			21				121'b
;		       . . . 
;			27				127'b

CollectSubBoot:
	lxi	h, 7777; display 7777 in MP
	call	PutMP
WaitAltDown:
	in	MiscInput1;  check if alt boot button down yet
	ani	AltBootMask
	jz	WaitAltDown; not yet
TryLoop:
	mvi	a, 3; try a sub boot of 3 first
	mvi	b, 100B; for a file number of 100'b 
	call	TrySubBoot
	rz	; user has selected a value
	mvi	a, 6; try a sub boot of 6 next
	mvi	b, 101B;  for a file number of 101'b
	call	TrySubBoot
	rz	; user has selected a value
	mvi	a, 20; now we start at 20 in the lights
	mvi     b, 120B; for a file number of 120'b
TryNext:
	call	TrySubBoot
	rz	; user has selected a value
	cpi	27; last value we shall try
	jz	TryLoop; last value has been tried
	inr	a
	inr	b
	jmp	TryNext

;returns with 0 if selected by user
;	the selected value is in uEsubBoot
;returns with the non zero values just tried and rejected by user

TrySubBoot:
	sta	subBootDisp
	mov	l, a
	mov	a, b
	sta	subBootVal
	mvi	h, 0
	call	PutMP
	lxi	h, AltBootDelay1
	call	Delay
	lxi	h, AltBootDelay2
	call	Delay
	in	MiscInput1
	ani	AltBootMask
	rz
	lda	subBootVal
	mov	b, a
	lda	subBootDisp
	ret
	
; the displayed sub boot value
subBootDisp:
	db	0
; the resulting value
subBootVal:
	db	0
	
; allow for test driving from burdock	
TestCollectSubBoot:
	call	CollectSubBoot
fyfy	jmp	fyfy

; following requires an IOP break at StartNextPhase
; note: can't call MoveLinkTableExt, as we just get the address in the LinkTable, which has not yet been filled in, and BootMain doesn't export MoveLinkTable.
TestPatch:
	ei		; enable interrupts for burdock
	lxi	sp,BootStackStart
	lxi	h,BootInit
	lxi	b, 8
	dad	b
	shld	callBootInit+1
callBootInit:
	call	0; computed address, ignore first part of boot init
	lxi	h, BootGo; imported from BootMain
	lxi	b, 25CH; listing shows MoveLinkTable = BootGo + 25C
	dad	b
	shld	callMoveLinkTable+1
callMoveLinkTable:
	call	0; computed address = MoveLinkTable
	jmp	MultiEtherBootNextPhase

; a place to loop while CP is running, for test purposes
IOPLoop:
	jmp	IOPLoop
	

; this code informs the CP of the subBoot number.  It depends on the modified initial IOP task code, so tests for it.

CPSetSubBootCmd	equ	7; this should be defined in boot defs, it is a command number beyond those in IOP boot and IOPMain.

InformCPofSubBoot:
	mvi	a, CPSetSubBootCmd
	call	WriteCPbyte
	lda	subBootVal
	call	WriteCPbyte
        call	ReadCPbyte
	mvi	b, 9
	cmp	b	; check for correct IOP task in CP
	rz		; ok
	mvi	c, -1
	jmp	ErrorReport
		
; following code to check if CP kernel is alive and well
CheckCP:	
	call	StartCPKernel; = StopCP, which is not exported
	call	StartCP
	ret

; following copied from BootSubs, as not exported
		
	
	
; following code exists in BootSubs, but entry is not exported

; Subroutine:  ReadCPbyte.
;  Read CP byte.
;  Byte returned in A register.
ReadCPbyte:
	in	CPStatus	;  Read the port interrupt bits
	ani	CPInIntMask	;  CPIn requesting an interrupt? 
	jz	ReadCPbyte		;  Zero means no interrupt
	in	CPIn		;  get data
	ret
	
; Subroutine:  WriteCPbyte.
;  Write CP byte.
;  Byte in A register written into port.
WriteCPbyte:
	out	CPOut		;  Output data
WaitCPOutAck:
	in	CPStatus	;  Read the port interrupt bits
	ani	CPOutIntMask	;  CPOut requesting an interrupt, i.e data read? 
	jz	WaitCPOutAck		;  Zero means no interrupt
	ret

; following exists in BootMain, but is not exported.
CPError:
	jmp	ErrorReport


	
	END	EtherBootPatchCode