:TITLE[Timer]; SetTask[TTask]; OnPage[TimerInitPage]; *Initialize Notifies here to set up timers (this is throwaway code) InitTimers: TimerTemp _ (100000C), at[TimerInitLoc]; ClrTimers: LoadTimer[TimerTemp]; *Clear out all Timers RSImage _ T _ 0C; RS232 _ T; *Zap RS232 RTimer _ (50000C); *Set up the Refresh time RTimer _ (RTimer) OR (257C); *simple timer,value 10d,slot 17b TimerTemp _ (TimerTemp) + 1, ResetMemErrs; *Clear any pending memory errors LU _ (TimerTemp) AND (17C); *there are 16d timers REFR _ T _ (0C), dblgoto[InitDone, ClrTimers, ALU=0]; InitDone: LU _ Timer; *read to clear pending wakeups LOADTIMER[RTimer]; *load refresh timer TimerBasehi _ T, loadpage[TimerPage]; *initialize high base register RTCLOW _ 1c, gotop[TimerSetTPC]; *RTCLOW is made odd so that timer updating won't start *until the memory has been initialized. Onpage[TimerPage]; TimerSetTPC: call[TimerRet]; *Timer wakeups come here TimerWakeup: *Timer wakeups come here Dispatch[Timer,14,4]; TimerBase _ 400c, DISP[Timers]; *initialize low base register *Timer dispatch table for task 16 (all entries are not used) Timers: Refresh[REFR], goto[RefreshNext], AT[TimerTable,00] ;*slot 17 goto[BadTimerWake], T _ 16c, AT[TimerTable,01]; *slot 16 goto[BadTimerWake], T _ 15c, AT[TimerTable,02]; *slot 15 goto[BadTimerWake], T _ 14c, AT[TimerTable,03]; *slot 14 goto[BadTimerWake], T _ 13c, AT[TimerTable,04]; *slot 13 goto[BadTimerWake], T _ 12c, AT[TimerTable,05]; *slot 12 goto[BadTimerWake], T _ 11c, AT[TimerTable,06]; *slot 11 goto[BadTimerWake], T _ 10c, AT[TimerTable,07]; *slot 10 goto[BadTimerWake], T _ 7c, AT[TimerTable,10]; *slot 7 *Ethernet Output Notify slot (Add copies with EOTask1, EOTask2 ... if multiple controllers). TimerTemp _ OR[lshift[EOTask,14],AND[7400,EOTimerDoneLoc]]C, GOTO[TEONotify], AT[TimerTable,11]; goto[BadTimerWake], T _ 5c, AT[TimerTable,12]; *slot 5 goto[BadTimerWake], T _ 4c, AT[TimerTable,13]; *slot 4 goto[BadTimerWake], T _ 3c, AT[TimerTable,14]; *slot 3 goto[BadTimerWake], T _ 2c, AT[TimerTable,15]; *slot 2 goto[BadTimerWake], T _ 1c, AT[TimerTable,16]; *slot 1 goto[BadTimerWake], T _ 0c, AT[TimerTable,17]; *slot 0 *Wrong value in timer dispatch comes here with channel number in T: BadTimerWake: Breakpoint, return; *Notify for Ethernet output (Only one copy required) TEONotify: TimerTemp _ (TimerTemp) or (AND[0377, EOTimerDoneLoc]C); * Low 8 bits of APC APC&APCTask _ TimerTemp; *Notify Ethernet output task, don't restart timer TimerRet: return, AT[TimerTable,24]; *Must be MouseHalt+1 for proper restarting. *Refresh has been started. RefreshNext: AddToTimer[RTIMER]; *load the refresh timer * check for Midas halt CheckMidas: T _ (FFAULT) and (10000c); * check for Midas present and mouse halt lu _ (PRINTER) and (T); dblgoto[MouseHalt,CheckRTC,ALU#0]; MouseHalt: goto[.], SETFAULT, AT[TimerTable,23]; *Midas mouse halt is a task 16 breakpoint that was *not set by the user. Midas continues by going to location 7004 (which contains a return). CheckRTC: RTCLOW _ (RTCLOW) + (154c), dblgoto[RTCOff,UpdateRTC, ROdd]; RTCOff: RTCLOW _ 1c, goto[RTCRet]; *RTC has not been started yet. *Check for RTC update required. *The real time clock is set up for 100nsec main clock rate, i.e. 64us/timer round. *Each tick, we add 108d (154b) to RTCLOW, which will cause it to carry every *65536/108 = 606.8 times the code is run. 606.8 * 64 = 38836us. The equivalent *Alto number is 39009.5us, so the clock will run slightly fast. UpdateRTC: T _ 30c, skip[carry]; *RTCLOW overflowed. Increment VM 430 RTCRet: REFR _ (REFR) + (20C), return; *increment the refresh address PFetch1[TimerBase,TimerTemp]; *Increment VM 430 TimerTemp _ (TimerTemp)+1; PStore1[TimerBase,TimerTemp], goto[RTCRet]; :END[Timer];(1795)\1763f1 47f0 544f1 154f0 167f8 24f0 476f8 33f0