{ClockTest.mc, HGM, 4-Nov-84 2:29:29}
Reserve[0F5F, 0FFF]; {section used by the CP Kernel }
SetTask[0]; StartAddress[Go];
RegDef[LoopCount, R, 0];
RegDef[address, R, 1];
RegDef[rhAddr, RH, 1];
RegDef[found, R, 4];
RegDef[status, R, 5];
RegDef[oldClockLo, R, 06];
RegDef[oldClockHi, R, 07];
RegDef[clockLo, R, 08];
RegDef[clockHi, R, 09];
RegDef[clockP, R, 0A];
RegDef[ticks, R, 0B];
RegDef[ints, R, 0C];
RegDef[temp, R, 0D];
RegDef[LSB, R, 0E];
RegDef[oldLSB, U, 00];
RegDef[u16, U, 016];
RegDef[u17, U, 017];
RegDef[u18, U, 018];
RegDef[u19, U, 019];
Trap: temp ← RRot1 ErrnIBnStkp, ClrIntErr, CANCELBR[$, 0F], c1, at[0];
Xbus ← temp LRot0, XwdDisp, c2;
DISP2[TrapType], c3;
Parity: GOTO[GoToGo], c1, at[0,4,TrapType];
Init: GOTO[GoToGo], c1, at[1,4,TrapType];
Stack: GOTO[GoToGo], c1, at[2,4,TrapType];
IB: GOTO[GoToGo], c1, at[3,4,TrapType];
GoToGo:
Noop, c2;
Noop, GOTO[Go], c3;
Go: rhAddr ← 4, {Timers} c1;
address ← 90, c2;
address ← address LRot8 {9000}, c3;
Restart:
LoopCount ← 0, ClrIntErr, c1;
ExtCtrl ← 5, {Init Incr, Zero, UnBlank} c2;
GOTO[MainLoop], c3;
MainLoop:
ticks ← 0, c1;
Noop, c2;
ExtCtrl ← 5, {Init Incr, Zero, UnBlank} c3;
IO ← [rhAddr, address + 0], {Master Interrupt Control} c1;
MDR ← 0, {UnReset} c2;
temp ← address + 10, c3;
IO ← [rhAddr, address + 0], {Master Interrupt Control} c1;
MDR ← 0, {UnReset} c2;
temp ← address + 10, c3;
IO ← [rhAddr, temp + 06], {Cnt1 MSB} c1;
MDR ← 0, c2;
Noop, c3;
IO ← [rhAddr, temp + 07], {Cnt1 LSB} c1;
MDR ← 0, c2;
Noop, c3;
IO ← [rhAddr, temp + 08], {Cnt2 MSB} c1;
MDR ← 0, c2;
Noop, c3;
IO ← [rhAddr, temp + 09], {Cnt2 LSB} c1;
MDR ← 0, c2;
Noop, c3;
{PClk = 400ns. Counter runs off PClk/2. 50ms => count should be 62500 = F424.}
IO ← [rhAddr, temp + 0A], {Cnt3 MSB} c1;
MDR ← 0F4, c2;
Noop, c3;
IO ← [rhAddr, temp + 0B], {Cnt3 LSB} c1;
MDR ← 24, c2;
Noop, c3;
IO ← [rhAddr, temp + 0C], {Cnt 1 Mode} c1;
MDR ← 0A0, {Ext In, Pulse} c2;
Noop, c3;
IO ← [rhAddr, temp + 0D], {Cnt 2 Mode} c1;
MDR ← 080, {Pulse} c2;
Noop, c3;
IO ← [rhAddr, temp + 0E], {Cnt 3 Mode} c1;
MDR ← 080, {Pulse} c2;
temp ← address + 20, c3;
IO ← [rhAddr, temp + 0B], {Port B Direction} c1;
MDR ← 0FF, {All in} c2;
temp ← address + 10, c3;
IO ← [rhAddr, address + 06], {Port C Direction} c1;
MDR ← 0F, {All in. Beware of Boot'} c2;
Noop, c3;
IO ← [rhAddr, address + 1], {Master Config Control} c1;
MDR ← 0F3, {Enables, Link Timers} c2;
Noop, c3;
IO ← [rhAddr, address + 0A], {Counter 1 Cntrl} c1;
MDR ← 06, {Trgr} c2;
Noop, c3;
IO ← [rhAddr, address + 0B], {Counter 2 Cntrl} c1;
MDR ← 06, {Trgr} c2;
Noop, c3;
IO ← [rhAddr, address + 0C], {Counter 3 Cntrl} c1;
MDR ← 0C6, {Set IE, Trgr} c2;
Noop, c3;
IO ← [rhAddr, address + 0], {Master Interrupt Control} c1;
MDR ← 080, {MIE} c2;
temp ← address + 10, c3;
LoadOldClock:
IO ← [rhAddr, address + 0B], {Counter 2 Cntrl} c1;
MDR ← 0C, {RCC and GCB} c2;
oldClockLo ← found, c3;
IO ← [rhAddr, temp + 02], {Cnt 2 MSB} c1;
Noop, c2;
found ← MD, c3;
IO ← [rhAddr, temp + 03], {Cnt 2 LSB} c1;
found ← found LRot8, c2;
found ← found or MD, c3;
Noop, c1;
Noop, c2;
clockHi ← found, c3;
WaitForTick:
{Ouch, this isn't needed at 16MHZ, but it is at 10.}
IO ← [rhAddr, address + 0C], {Counter 3 Cntrl} c1;
MDR ← 0A4, {Reset IP, GCB} c2;
Noop, c3;
IO ← [rhAddr, address + 0A], {Counter 1 Cntrl} c1;
MDR ← 0C, {RCC and GCB} c2;
Noop, c3;
IO ← [rhAddr, temp + 00], {Cnt 1 MSB} c1;
Noop, c2;
found ← MD, c3;
IO ← [rhAddr, temp + 01], {Cnt 1 LSB} c1;
found ← found LRot8, c2;
found ← found or MD, c3;
Noop, c1;
Noop, c2;
oldClockLo ← found, c3;
IO ← [rhAddr, address + 0B], {Counter 2 Cntrl} c1;
MDR ← 0C, {RCC and GCB} c2;
Noop, c3;
IO ← [rhAddr, temp + 02], {Cnt 2 MSB} c1;
Noop, c2;
found ← MD, c3;
IO ← [rhAddr, temp + 03], {Cnt 2 LSB} c1;
found ← found LRot8, c2;
found ← found or MD, c3;
Noop, c1;
Noop, c2;
oldClockHi ← found, c3;
Noop, c1;
[] ← clockHi - oldClockHi, ZeroBr, c2;
BRANCH[$, WaitForTick], c3;
Noop, c1;
Noop, c2;
Noop, c3;
ClockLoop:
IO ← [rhAddr, address + 0A], {Counter 1 Cntrl} c1;
MDR ← 0C, {RCC and GCB} c2;
Noop, c3;
IO ← [rhAddr, temp + 00], {Cnt 1 MSB} c1;
Noop, c2;
found ← MD, c3;
IO ← [rhAddr, temp + 01], {Cnt 1 LSB} c1;
found ← found LRot8, c2;
found ← found or MD, c3;
IO ← [rhAddr, address + 0B], {Counter 2 Cntrl} c1;
MDR ← 0C, {RCC and GCB} c2;
clockLo ← found, c3;
IO ← [rhAddr, temp + 01], {Cnt 1 LSB} c1;
Noop, c2;
LSB ← MD, c3;
IO ← [rhAddr, temp + 02], {Cnt 2 MSB} c1;
Noop, c2;
found ← MD, c3;
IO ← [rhAddr, temp + 03], {Cnt 2 LSB} c1;
found ← found LRot8, c2;
found ← found or MD, c3;
Noop, c1;
Noop, c2;
clockHi ← found, c3;
IO ← [rhAddr, address + 0C], {Counter 3 Cntrl} c1;
MDR ← 0C, {RCC and GCB} c2;
Noop, c3;
IO ← [rhAddr, temp + 04], {Cnt 3 MSB} c1;
Noop, c2;
found ← MD, c3;
IO ← [rhAddr, temp + 05], {Cnt 3 LSB} c1;
found ← found LRot8, c2;
found ← found or MD, c3;
IO ← [rhAddr, address + 0C], {Counter 3 Status} c1;
clockP ← found, c2;
found ← MD, c3;
CheckClock:
Noop, c1;
[] ← oldClockLo - clockLo, ZeroBr, c2;
BRANCH[$, ClockLoDidntTick], c3;
Q ← oldClockLo - clockLo, c1;
[] ← Q and ~07, NZeroBr, c2;
BRANCH[$, ClockLoBackwards], c3;
Q ← oldClockHi - clockHi, c1;
[] ← Q and ~01, NZeroBr, c2;
BRANCH[$, ClockHiBackwards], c3;
oldLSB ← LSB, c1;
oldClockLo ← clockLo, c2;
oldClockHi ← clockHi, c3;
LoopCount ← LoopCount + 1, c1;
MesaIntBr, c2;
ints ← ExtStat, BRANCH[ClockLoop, ClockInt], c3;
ClockInt:
IO ← [rhAddr, address + 0C], {Counter 3 Cntrl} c1;
MDR ← 0A4, {Reset IP, GCB} c2;
ticks ← ticks + 1, c3;
{Beware: If the ClrIntErr happens too soon, we will get 2 interrupts on each tick.}
ExtCtrl ← 3, {Gets Bumped on rising edge} c1;
ExtCtrl ← 7, c2;
ClrIntErr, GOTO[ClockLoop], c3;
{------------------------------------------------------------------------------------}
ClockSpin:
IO ← [rhAddr, temp + 01], {Cnt 1 LSB} c1;
ExtCtrl ← 5, {Init Incr, Zero, UnBlank} c2;
clockLo ← MD, c3;
ClockSpinAgain:
IO ← [rhAddr, address + 0A], {Counter 1 Cntrl} c1;
MDR ← 0C, {RCC and GCB} c2;
Noop, c3;
IO ← [rhAddr, temp + 01], {Cnt 1 LSB} c1;
oldClockLo ← clockLo, c2;
clockLo ← MD, c3;
Noop, c1; Noop, c2; Noop, c3;
Noop, c1; Noop, c2; Noop, c3;
Noop, c1; Noop, c2; Noop, c3;
Noop, c1; Noop, c2; Noop, c3;
Noop, c1; Noop, c2; Noop, c3;
Noop, c1; Noop, c2; Noop, c3;
Noop, c1; Noop, c2; Noop, c3;
Noop, c1; Noop, c2; Noop, c3;
Noop, c1; Noop, c2; Noop, c3;
Noop, c1; Noop, c2; Noop, c3;
Noop, c1;
Q ← oldClockLo - clockLo, ZeroBr, c2;
Q ← Q and 0FF, BRANCH[$, ClockSpinAgain], c3;
Noop, c1;
[] ← Q and ~7, NZeroBr, c2;
BRANCH[$, ClockSpinQuirk], c3;
ClockSpinTicked:
Noop, c1;
Noop, c2;
LoopCount ← LoopCount + 1, GOTO[ClockSpinAgain], c3;
ClockSpinQuirk:
ExtCtrl ← 3, {Gets Bumped on rising edge} c1;
ExtCtrl ← 7, c2;
LoopCount ← 0, GOTO[ClockSpinAgain], c3;
{------------------------------------------------------------------------------------}
ClockLoDidntTick:
LoopCount ← 0, c1;
ExtCtrl ← 5, {Init Incr, Zero, UnBlank} c2;
GOTO[LoadOldClock], c3;
ClockLoBackwards:
LoopCount ← 0, c1;
ExtCtrl ← 5, {Init Incr, Zero, UnBlank} c2;
GOTO[LoadOldClock], c3;
ClockHiBackwards:
LoopCount ← 0, c1;
ExtCtrl ← 5, {Init Incr, Zero, UnBlank} c2;
GOTO[LoadOldClock], c3;
RCCAlreadySet:
LoopCount ← 0, c1;
ExtCtrl ← 5, {Init Incr, Zero, UnBlank} c2;
GOTO[LoadOldClock], c3;
RCCNotSet:
LoopCount ← 0, c1;
ExtCtrl ← 5, {Init Incr, Zero, UnBlank} c2;
GOTO[LoadOldClock], c3;
SnarfGoodies:
IO ← [rhAddr, temp + 06], {Cnt1 MSB} c1;
Noop, c2;
Q ← MD, c3;
IO ← [rhAddr, temp + 07], {Cnt1 LSB} c1;
u16 ← Q, c2;
Q ← MD, c3;
IO ← [rhAddr, temp + 08], {Cnt2 MSB} c1;
u17 ← Q, c2;
Q ← MD, c3;
IO ← [rhAddr, temp + 09], {Cnt2 LSB} c1;
u18 ← Q, c2;
Q ← MD, c3;
Noop, c1;
u19 ← Q, c2;
Noop, c3;
SnarfedGoodies:
Noop, c1;
Noop, c2;
GOTO[Restart], c3;
ResetTheChip:
IO ← [rhAddr, address + 0], {Master Interrupt Control} c1;
MDR ← 1, {Reset} c2;
temp ← address + 10, c3;
IO ← [rhAddr, address + 0], {Master Interrupt Control} c1;
MDR ← 0, {UnReset} c2;
GOTO[Restart], c3;
{------------------------------------------------------------------------------------}