;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;
;	D O R A D O   C o n t r o l   P r o g r a m
;
;		C o n t i n u o u s - R u n n i n g   C o d e
;
;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

;	filed on DoradoContinuous.masm
;	E. McCreight
;	last modified September 28, 1982  10:11 AM

	.EXPORT	Continuous,DoCallPtr,CallPtr,OnceOnly,Spin
	.EXPORT	PacifyWatchdog,CheckBootButton
	.EXPORT	PacifyWatchdogIfJumper

	.IMPORT	SetProblem,ClearProblem,Delay
	.IMPORT	TransientPowerProblem,CurrentPowerProblem
	.IMPORT	Problems,Overtemp,Shutdown
	.IMPORT	PowerOutOfSpec,BadSupplySpec
	.IMPORT	LoadDoradoCode,RebootDorado
	.IMPORT	Timer100ms,SupplyBadTime
	.IMPORT	DoAllConversions,BootTicksOff,BootPushCount
	.IMPORT	SetManifold,StopDorado,ClearDMManifold
	.IMPORT	PowerDownDisk,UnloadDiskHeads
	.IMPORT	PowerDownMinus2,PowerDownEverything
	.IMPORT	DisconnectMufMan
	.IMPORT	CBTemp
	.IMPORT	StartDoradoAtInitmap,ReadBNibble
	.IMPORT	MeltDownTemp

	.SHORT	Timer100ms,SupplyBadTime,PowerOutOfSpec,CBTemp

	.PREDEFINE	"MCS6502PREDEFS.SR"
	.GETNOLIST	"Doradoio.mdefs"

	.LOC	ContinuousData

DoCallPtr:
	.BLK	1	; eq 0 means don't do it; ne 0 means do the call
CallPtr:
	.BLK	2

DMTemp:
	.BLK	1
AlarmClockEnabled:
	.BLK	1
AlarmSetTime:
	.BLK	6

WatchdogTemp:
	.BLK	1

;	This is the code that runs all the time after the Dorado
;	has been started.

	.LOC	ContinuousCode

Continuous:
	JSR	DoAllConversions

	LDAI	0
	STA	BootPushCount
	STA	AlarmClockEnabled
	STA	DoCallPtr

	LDAI	2000,#LowAddrByte	; Extra Ram
	STA	CallPtr
	LDAI	2000,#HighAddrByte
	STA	CallPtr+1

Spin:
	LDA	DoCallPtr	; this allows debugging subroutines, etc.
	BEQ	DontCallThePtr

	JSR	CallIt
	JMP	Spin

CallIt:
	LDA	CallPtr+1
	PHA
	LDA	CallPtr
	PHA
	PHP
	RTI

DontCallThePtr:
	JSR	CheckBootButton

	JSR	DoAllConversions
	LDA	PowerOutOfSpec
	BEQ	SuppliesSeemOK

	LDAI	CurrentPowerProblem
	JSR	SetProblem
	LDAI	TransientPowerProblem
	JSR	SetProblem
	STA	BadSupplySpec
	LDXI	5	; note the timer setting when supply went bad
	SEI	; don't allow timer to change during copy

CopyTimerToSupplyBadTime:
	LDAX	Timer100ms
	STAX	SupplyBadTime
	DEX
	BPL	CopyTimerToSupplyBadTime

	CLI
	JMP	CheckForMeltdown

SuppliesSeemOK:
	LDAI	CurrentPowerProblem
	JSR	ClearProblem

CheckForMeltdown:
	LDA	CBTemp
	CMPI	-1
	BEQ	Spin	; board not installed
	CMP	MeltDownTemp	
	BCC	Spin	; cool enough

	LDAI	OverTemp
	JSR	SetProblem
	JMP	ShutDownTheDorado


DoConversionsOnce:
	JSR	DoAllConversions

OnceOnly:
	LDAI	0
	STA	DoCallPtr
	RTS

;	This code shuts down the Dorado and its disk, except for the
;	+5 volt power supply and one fan. It then waits for a message
;	from the boot button to re-awaken.

ShutDownTheDorado:
	LDAI	ShutDown
	JSR	SetProblem

	JSR	StopDorado	; stop the Dorado

	LDXI	ClearDMManifold	; de-assert any stop command from Dorado
	JSR	SetManifold

	LDXI	DisconnectMufMan	; assert IOReset, de-assert EclUp
	JSR	SetManifold

	LDXI	UnloadDiskHeads	; unload the disk heads
	JSR	SetManifold

	LDXI	20.	; wait for disk to brake
	JSR	Delay

	LDXI	PowerDownDisk	; shut down the disk power supplies
	JSR	SetManifold

	LDXI	PowerDownMinus2	; shut down the terminator power supply
	JSR	SetManifold

	LDXI	2.
	JSR	Delay

	LDXI	PowerDownEverything	; shut down the Ecl power supplies
	JSR	SetManifold

HangOnBootButton:	; wait for a boot operation
	JSR	CheckBootButton
	JSR	DoAllConversions
	JMP	HangOnBootButton

;	Routine to check the boot button and if it's just been
;	released, either restart the machine or power it down.
;	Also checks manifold register and alarm clock.

CheckBootButton:
	JSR	PacifyWatchdog

	LDA	Problems
	ANDI	Shutdown
	BNE	WeAreShutdown

	LDAI	0
	STA	AlarmClockEnabled

	LDA	BootTicksOff	; might the user still be sending?
	CMPI	15.	; wait 1.5 seconds for more
	BMI	CheckMsgFromDorado

	LDAI	0
	LDX	BootPushCount	; he's done.
	STA	BootPushCount	; reset the count

	CPXI	1
	BPL	HeBooted


CheckMsgFromDorado:
	LDA	MiscByte	; synchronize MiscByte read
	ANDI	0f
	STA	DMTemp
	LDA	MiscByte
	ANDI	0f
	CMP	DMTemp
	BNE	CheckMsgFromDorado

	CMPI	02
	BEQ	ShutdownIfNotDebug
	CMPI	03
	BEQ	SetAlarmAndShutDown
	CMPI	04
	BEQ	CoolBoot

HotBoot:
Ignore:
	RTS


HeBooted:
	DEX
	BEQ	HotBoot	; 1 push: the Dorado will take care of it

	DEX
	BEQ	WarmBoot	; 2 pushes: do INITMAP;G

	CPXI	5
	BCC	CoolBoot	; <7 pushes: reload microcode
	BCS	DoShutdown	; >=7 pushes: shut down



SetAlarmAndShutdown:
	JSR	SetAlarmFromBMux

ShutdownIfNotDebug:
	LDA	MCPBusL
	ANDI	SkipDiskWait'
	BEQ	Ignore

DoShutdown:
	PLA	; pop the call off the stack
	PLA
	JMP	ShutDownTheDorado

WarmBoot:
	JSR	StartDoradoAtInitmap
	RTS

CoolBoot:
	JSR	LoadDoradoCode
	RTS

WeAreShutdown:
	LDA	BootTicksOff	; might the user still be sending?
	CMPI	15.	; wait 1.5 seconds for more
	BMI	DoAlarmCheck

	LDAI	0
	LDX	BootPushCount	; he's done.
	STA	BootPushCount	; reset the count

	CPXI	1	; between 1 and 7 pushes means start up
	BMI	DoAlarmCheck
	CPXI	7
	BMI	BootFromShutdown

DoAlarmCheck:
	JSR	CheckAlarm
	BCC	Ignore

BootFromShutdown:
	LDAI	0
	STA	AlarmClockEnabled	; disable wake-up

	PLA	; remove a call from the stack
	PLA
	JMP	RebootDorado

SetAlarmFromBMux:
	JSR	StopDorado

	LDXI	5	; zero the alarm set time
	LDAI	0

ZeroSetTime:
	STAX	AlarmSetTime
	DEX
	BPL	ZeroSetTime

	LDAI	3	; read in 16 bits from the BMux as 25.6 second periods
	STA	DMTemp

ReadAnotherNibbleFromB:
	LDA	DMTemp	; low-order nibble first
	JSR	ReadBNibble
	PHA
	LDA	DMTemp
	LSRA
	ANDI	1
	EORI	1	; 3,2 => 0; 1,0 => 1
	TAX
	PLA
	LDYI	3

ShiftMoreBBits:
	LSRA
	RORX	AlarmSetTime+1
	DEY
	BPL	ShiftMoreBBits

	DEC	DMTemp
	BPL	ReadAnotherNibbleFromB

	LDXI	5	; add the alarm set time to the current time
	STX	DMTemp
	LDXI	0
	CLC
	SEI	; temporarily disable timer update

ComputeSetTime:
	LDAX	Timer100ms
	ADCX	AlarmSetTime
	STAX	AlarmSetTime
	INX
	DEC	DMTemp
	BPL	ComputeSetTime

	LDAI	1
	STA	AlarmClockEnabled	; enable wake-up

	CLI	; re-enable timer update
	RTS


CheckAlarm:
	CLC
	LDA	AlarmClockEnabled
	BEQ	NotTimeYet

	LDXI	5
CheckAnotherByte:	
	LDAX	Timer100ms
	CMPX	AlarmSetTime
	BCC	NotTimeYet
	DEX
	BPL	CheckAnotherByte

NotTimeYet:
	RTS


;	Let the watchdog timer know we're still alive by copying
;	WatchdogIn to WatchdogOut every once in a while.

PacifyWatchdogIfJumper:
	LDA	MCPBusL
	ANDI	SkipDiskWait'
	BNE	PacifyFinished

PacifyWatchdog:
	LDA	Watchdog
	ANDI	WatchdogIn
	RORA	; carries WatchdogIn to WatchdogOut
	STA	WatchdogTemp
	SEI
	LDA	Watchdog
	ANDI	0ff-WatchdogOut
	ORA	WatchdogTemp
	STA	Watchdog
	CLI

PacifyFinished:
	RTS

	.END