#altoconsts23.mu;get definitions,constant allocations
;On each MRT, decrement the ScanWait counter
;when =0, do a scanner start pulse, and reset counter to ITTIME
;(if counter=0 on entry, just do a reset)
;
;If the scanner is running, also check for input words, and smash
;them into ScanBuffer
;Dispatch definitions:
!17,20,ret,,,,,,,,MRT,,,,,PART;
!20,1,START;return address for emulator restart
!37,1,TRAP1;
;!120,1,MUL;!124,20,BLT,BLKS,,,,,,,,,,MUL,DIV,,BITBLT;
PART: TASK;
:PART;
;REGISTERS USED BY NOVA EMULATOR
$AC0$R3; ac’s are backwards because the hardware supplies
; the complement address when addressing from ir
$AC1$R2;
$AC2$R1;
$AC3$R0;
$NWW$R4;
$SAD$R5;
$PC$R6;
$XREG$R7;
$MTEMP$R25;
$LastL$R40; not a real S register, but rather L gated to the bus
$ScanWait $R14;
$ScanBuffer$R15;
$ScanData$R16;
$StoreCount$R17;
;halftone uses: 10,36,5,7
;available constants: 177024,25,26,34,40,42
$177024$177024;
$177026$177026;
;$Outport$177016
;$SafeLoc$177023
;$StepLoc$177020
$420$420;417 is StepState
$ScanCBHead$736;and 737 is Startcommand
$ScanTime$526;
$10000$10000;
$4000$4000;
$400$400;
$StatusDONE$177777;
$StatusDATALATE$177776;
;Clock (in refresh task) R11,R37
;Ethernet R12,R13
;Display controller: R20-R30
;Disk Controller: R31-R34
;Available: R5
rett:TASK;most general return (Return&TASK)
retn:NOP;return, do nop first (prev inst has task)
ret:SWMODE;
:START;back to ROM
!17,20,f0,f1,f2;,f3,f4,f5,f6,f7,f10,f11,f12,f13,f14,f15,f16,f17;
TRAP1: SINK←DISP,BUS;"or" low-order 8 bits of IR into "NEXT"
dispatch:NOP,:f0;
;funny locations for stepper control branch
%1,1777,520,fstep0;
%1,1777,521,fstep1;
%1,1777,522,fstep2;
%1,1777,523,fstep3;
%1,1777,1520,bstep0;
%1,1777,1521,bstep1;
%1,1777,1522,bstep2;
%1,1777,1523,bstep3;
;--------------------------------------------------------------------
; f2: set RMR
;--------------------------------------------------------------------
f2: RMR ← AC0,:rett;
;--------------------------------------------------------------------
; f0: stuffs appropriate S registers with global variables
;--------------------------------------------------------------------
$jctr$R41;counter for repeating/deleting pts in x dir
$black$R42;minimum value of data
$range$R43;max-min
$outpts$R44;number of points to put out per line
$inpts$R45;number of input points per line
$s1$R46;vector for storing error propogation
$Screen$R47;
$Screenx$R50;indexed output pointer
$CascadeRight$R51;error propogation to the right (R Reg for initial shift)
$distance$R52;
$yctr$R53;counter for repeating/deleting lines in y dir
$CascadeDiag$R54;error propogation diagonally right
$bitOffset$R55; bit number of first output bit in first output word (0=leftmost)
$temp$R56;
$lineCtr$R57;tell user how many lines have gone out
;Init(inpts,black,range,outpts,s1,bitOffset,nil,screen,distance)
f0: MAR←L←AC0;
NOP;
L←MD,TASK;
inpts←L;
MAR←L←AC0+1;
AC0←L;
L←MD,TASK;
black←L;
MAR←L←AC0+1;
AC0←L;
L←MD,TASK;
range←L;
MAR←L←AC0+1;
AC0←L;
L←MD,TASK;
outpts←L;
T←outpts;
L←0-T;
yctr←L,TASK;
jctr←L;
MAR←L←AC0+1;
AC0←L;
L←MD,TASK;
s1←L;
MAR←L←AC0+1;
AC0←L;
L←MD,TASK;
bitOffset←L;
MAR←L←AC0+1;
AC0←L;
L←MD,TASK;
Screen←L;
NOP;TASK RETURNS HERE: next instruction uses ALU←SReg
L←Screen-1,TASK;
Screenx←L;
MAR←L←AC0+1;
AC0←L;
L←MD,TASK;
distance←L,:ret;
;--------------------------------------------------------------------
; f1: does the halftone, updates globals
;--------------------------------------------------------------------
$val$R36;R reg for shift: value of next data point stored here
$error$R7;R register for shift (XREG: temp only)
$error1$R5;R register for shift: error rshift 1 (SAD: temp only)
$s1x$R10;R register for ALU action after TASK: address of next word in s1
$GETS$R60;address of next sample point in datavec
$xctr$R61;loop counter across x for reading input points
$emask$R62;sign bit propogation for shifts
$byteptr$R63;
$CurrentBits$R64;
$BitCount$R65;
!1,2,jdone,jloop;
!1,2,xloop,xdone;
!1,2,xloopL,xloopR;
!1,2,ndone,nloop;
!1,2,pos,neg;
!1,2,NoPut,PutWord;
;while yctr ls 0 do
f1:L←0-1;
lineCtr←L;
prloop:L←yctr;
L←lineCtr+1,SH<0;
lineCtr←L,:ndone;
nloop:L←inpts,TASK;
xctr←L;
L←AC0,TASK;
GETS←L;
;NOTE: error in from s1!0 is 1/4 range, so we multiply by 4 to keep the first line honest
;CascadeRight=(s1!0)*2
MAR←L←s1;
L←s1-1;we increment on the first store
s1x←L;
L←MD;
MTEMP←L LSH 1;
L←MTEMP;
MTEMP←L LSH 1;
L←MTEMP,TASK;
CascadeRight←L;
L←0;
CurrentBits←L;
CascadeDiag←L,TASK;
byteptr←L;
;read the initial word, and mask out the bits from bitOffset on (unless bit Offset = 0)
!1,2,getPriorBits,noPriorBits;
L←T←bitOffset;
L←20-T,SH=0;
BitCount←L,:getPriorBits;1,2,getPriorBits,noPriorBits
getPriorBits:L←BitCount-1;
T←LastL;
MAR←MASKTAB+T;
NOP;
L←MD;
XMAR←Screenx+1;
T←LastL;
L←MD AND NOT T,TASK;
CurrentBits←L;
noPriorBits:L←T←0;
;for i=1 to x do
;let val=(GETS(picfile)-black) lshift 2
xloop: L←ONE XOR T;
byteptr←L,SH=0;
MAR←GETS,:xloopL;
xloopL: T←177400;
L←MD AND T;
AC1←L LCY 8;
L←AC1,:GETdone;
xloopR: L←GETS+1;
GETS←L;
T←377;
L←MD AND T;
GETdone:T←black;
L←LastL-T,TASK;
val←L LSH 1;
L←val,TASK;
val←L LSH 1;
!1,2,SetBit,NoSetBit;
;while jctr ls 0 do
L←jctr;
whilej:T←val,SH<0;
L←CascadeRight-T,:jdone;
;test (CascadeRight-val) ls 0 then [ error=error+range] or SetBit()
jloop: error←L,SH<0;
T←range,:SetBit;
NoSetBit:L←error+T;
SetBitReturn:error←L,SH<0;
!1,2,checkOvPos,checkOvNeg;
T←range,:checkOvPos;
checkOvNeg:L←error+T;
L←error,SH<0,TASK;
!1,2,noNegOverflow,NegOverflow;
NOP,:noNegOverflow;
NegOverflow: T←range;
L←0-T,:neg;
checkOvPos:L←error-T;
L←error,SH<0;
!1,2,PosOverflow,noPosOverflow;
T←0,:PosOverflow;
PosOverflow: L←range,:noPosOverflow;
noNegOverflow:L←error;
neg:T←ONE;
;error=error rshift 1//arithmetic shift
noPosOverflow:error←L MRSH 1,:pos;
;error1=error rshift 1//arithmetic shift
pos:L←error,TASK;*************************************************
error1←L MRSH 1;
;s1!index=CascadeDiag+error1
T←error1;
MAR←L←s1x+1;
s1x←L;
L←CascadeDiag+T,TASK;********************************************
MD←LastL;
;CascadeRight=s1!index+error
;CascadeDiag=error1
L←error1;
MAR←s1x+1;
CascadeDiag←L;
T←error;TASK here bombs
L←MD+T;
CascadeRight←L;
L←BitCount-1;
BitCount←L,SH=0;
T←inpts,:NoPut;
PutWord:
L←Screenx+1;
Screenx←L;
XMAR←Screenx;MAR←L←Screenx+1;
;Screenx←L;
L←20;
BitCount←L,TASK;************************************************************
MD←CurrentBits;
L←0;
CurrentBits←L;
T←inpts;
NoPut:L←jctr+T;no task here: SH not preserved
jctr←L,:whilej;
jdone: T←outpts;
L←jctr-T,TASK;
jctr←L;
NOP;TASK RETURNS HERE: next instruction uses ALU←SReg
L←xctr-1;
xctr←L,SH=0;
T←byteptr,:xloop;
xdone:T←distance;
L←Screen+T,TASK;
Screen←L;
;put out last word,reset ScreenX
;if BitCount=20 then done
;otherwise, read previous value of Screenx!1
; mask out the first (20-BitCount) bits
; OR in CurrentBits
; write out
!1,2,workHard,easyTimeTime;
T←BitCount;
L←17-T;
L←BitCount-1,SH<0;
T←LastL,:workHard;!1,2,workHard,easyTimeTime;
workHard: MAR←MASKTAB+T;first pick up the mask
NOP;
L←MD,TASK;
temp←L;
XMAR←Screenx+1;now, the previous value
T←temp;
L←MD AND T;
XMAR←Screenx+1;and store it back
T←CurrentBits;
L←LastL OR T;LastL has (prev contents)&mask
MD←LastL;
easyTimeTime: L←Screen-1,TASK;
Screenx←L;
T←inpts;
L←yctr+T,TASK;
yctr←L,:prloop;
ndone: T←outpts;
L←yctr-T,TASK;
yctr←L;
L←lineCtr,TASK;
AC0←L,:retn;
;---------------------------------------------------------------
;setbit turns the bit (index) on.
;---------------------------------------------------------------
!37,40,GetBit,GetB1,GetB2,GetB3,GetB4,GetB5,GetB6,GetB7,GetB10,GetB11,GetB12,GetB13,GetB14,GetB15,GetB16,GetB17,GetB20;
;CurrentBits=CurrentBits % (#100000 rshift (index))
SetBit: SINK←BitCount,BUS;BitCount is between 20 and 1
T←CurrentBits,:GetBit;
GetBit:NOP;
GetB20: L←100000 OR T,TASK,:HaveBit;
GetB17: L←40000 OR T,TASK,:HaveBit;
GetB16: L←20000 OR T,TASK,:HaveBit;
GetB15: L←10000 OR T,TASK,:HaveBit;
GetB14: L←4000 OR T,TASK,:HaveBit;
GetB13: L←2000 OR T,TASK,:HaveBit;
GetB12: L←1000 OR T,TASK,:HaveBit;
GetB11: L←400 OR T,TASK,:HaveBit;
GetB10: L←200 OR T,TASK,:HaveBit;
GetB7: L←100 OR T,TASK,:HaveBit;
GetB6: L←40 OR T,TASK,:HaveBit;
GetB5: L←20 OR T,TASK,:HaveBit;
GetB4: L←10 OR T,TASK,:HaveBit;
GetB3: L←4 OR T,TASK,:HaveBit;
GetB2: L←2 OR T,TASK,:HaveBit;
GetB1: L←ONE OR T,TASK,:HaveBit;
HaveBit: CurrentBits←L;
L←error,:SetBitReturn;
;--------------------------------------------------------------------
; MRT: do start pulses off MRT task, for constant timing
;--------------------------------------------------------------------
;MEMORY REFRESH TASK AND MOUSE HANDLER
!17,20,TX0,TX6,TX3,TX2,TX8,TX5,TX1,TX7,TX4,,,,,,,;
!1,2,DOTIMER,NOTIMER;
!1,2,NOTIMERINT,TIMERINT;
!1,2,DOCUR,NOCUR;
!1,2,SHOWC,WAITC;
!1,2,SPCHK,NOSPCHK;
!1,2,NOCLK,CLOCK;
!1,1,MRTLAST;
!1,2,CNOTLAST,CLAST;
$CLOCKTEMP$R11;
$REFZERO $7774; REFRESH ZERO
$REFIIMSK $7777; REFRESH MASK
$R37$R37;
$CURX$R20;
$CURDATA$R21;
$YPOS$R27;
;* * * A T T E N T I O N * * *
;There are two versions of the Memory refresh code:
;AltoIIMRT4K.mu for refreshing 4K chips
;AltoIIMRT16K.mufor refreshing 16K chips
;first time initialization
MRT:MAR ← ScanTime;
L←0;
ScanBuffer←L;
StoreCount←L;
L←MD;
MAR ← 420-1;
ScanWait←L;
MD ← StoreCount;
;On each MRT, decrement the ScanWait counter
;when =0, do a scanner start pulse, and reset counter to ITTIME
;(if counter=0 on entry, just do a reset)
;
;If the scanner is running, also check for input words, and smash
;them into ScanBuffer
!1,2,ScannerOn,ScannerOff;
!1,2,checkInput,startScan;
!1,2,haveHead,noHead;
!1,2,haveCurrent,noCurrent;
!1,2,doMouse,doWord;
MRTloop: L←ScanWait-1,BUS=0;1
MAR←ScanTime,:ScannerOn; !1,2,ScannerOn,ScannerOff2
ScannerOn: NOP,SH=0;3
ScanWait←L,:checkInput;!1,2,checkInput,startScan;4
;unless StoreCount is 0, read bytes and decrement StoreCount
;between MAR←StepLoc and L←MD you need:
;5 NOPs if running at -11 volts
;6 NOPs if running at -10 volts
!1,2,doCount,noCount;
!1,2,oddByte,evenByte;
!1,2,read1,done1;
!1,2,doMouse1,doWord1;
!1,2,haveBuffer1,noBuffer1;
!1,2,read2,done2;
!1,2,doMouse2,doWord2;
!1,2,read3,done3;
!1,2,doMouse3,doWord3;
!1,2,haveBuffer3,noBuffer3;
!1,2,doMouse4,done4;
!1,2,StoreCountZero,noCountMouse;
checkInput: T ← StoreCount,BUS=0;5
T ← StoreCount,:doCount;!1,2,doCount,noCount;6
doCount: MAR←177024-1;SafeLoc;7
L ← ONE AND T;BUSODD doesn’t work for MRT8
T ← 377,SH=0;9
L ← MD,:oddByte;!1,2,oddByte,evenByte;10
;on even: must reset MAR to enable flop to toggle for step
evenByte: L ← MD AND T,SH<0,TASK;11
ScanData ← L LCY 8,:doMouse;!1,2,doMouse,doWord;12
doWord:MAR←T←20;13
MAR←177000+T;StepLoc;must allow 6 cycles before reading from XBus14
L ← StoreCount - 1;15
StoreCount ← L,SH=0,TASK;16
NOP,:read1;!1,2,read1,done1;17
read1: MAR←177024-1;in case TASK was taken18
NOP;19
T←377;20
L←MD;21
oddByte: T ← MD.T,SH<0;22
T ← ScanData OR T,:doMouse1;!1,2,doMouse1,doWord1;23
doWord1:MAR←ScanBuffer+1,BUS=0;24
L←ALLONES XOR T,:haveBuffer1; !1,2,haveBuffer1,noBuffer1;25
haveBuffer1:ScanData←L,TASK;2x
MD ← ScanData;2x
MAR←T←20;2x
MAR←177000+T;StepLoc;must allow 5 cycles before reading from XBus2x
L ← StoreCount - 1;3x
StoreCount ← L,SH=0;3x
L←ScanBuffer+1,:read2;!1,2,read2,done2;3x
noBuffer1:MAR←T←20;2x
MAR←177000+T;StepLoc;must allow 5 cycles before reading from XBus2x
L ← StoreCount - 1;3x
StoreCount ← L,SH=0;3x
L←0,:read2;!1,2,read2,done2;3x
read2: MAR←177024-1;in case TASK was taken;3x
ScanBuffer←L;3x
T←377;3x
L←MD;3x
L ← MD AND T,SH<0;3x
ScanData ← L LCY 8,:doMouse2;!1,2,doMouse2,doWord2;3x
doWord2:MAR←T←20;3x
MAR←177000+T;StepLoc;must allow 5 cycles before reading from XBus40
L ← StoreCount - 1;4x
StoreCount ← L,SH=0,TASK;4x
NOP,:read3;!1,2,read3,done3;43
read3: MAR←177024-1;in case TASK was taken;4x
NOP;4x
T←377;4x
L←MD;4x
T ← MD.T,SH<0;4x
T ← ScanData OR T,:doMouse3;!1,2,doMouse3,doWord3;4x
doWord3:MAR←ScanBuffer+1,BUS=0;5x
L←ALLONES XOR T,:haveBuffer3; !1,2,haveBuffer3,noBuffer3;5x
haveBuffer3:ScanData←L,TASK;5x
MD ← ScanData;5x
MAR←T←20;5x
MAR←177000+T;StepLoc;must allow 5 cycles before reading from XBus5x
L ← StoreCount - 1;5x
StoreCount ← L;5x
L←ScanBuffer+1,SH=0,TASK;
ScanBuffer←L,:doMouse4;!1,2,doMouse4,done4;
noBuffer3:MAR←T←20;5x
MAR←177000+T;StepLoc;must allow 5 cycles before reading from XBus5x
L ← StoreCount - 1;5x
StoreCount ← L,SH=0,TASK;
NOP,:doMouse4;!1,2,doMouse4,done4;
;make ScanBuffer non-zero (in case of no buffer)
done1: L←ALLONES,:done;18
done2: L←ALLONES,:done;33
done3: L←ALLONES,:done;44
done4: L←ALLONES,:done;59
done: ScanBuffer←L,:noMouse;60
;come here when storecount is exhausted
;if ScanBuffer = 0 then NOP (wait for next START time to examine CBHead)
;otherwise, mark current head "DONE", dequeue, and do next command
;(adjacent reads allow windowing, and stepper wants to go before next START)
;need to do something if requested read was odd number of bytes
noCount: SINK←ScanBuffer,BUS=0;7
MAR←ScanCBHead,:StoreCountZero;!1,2,StoreCountZero,noCountMouse;8
StoreCountZero:NOP;9
NOP;1x
L←MD+1,BUS=0;1x
!1,2,ScanCBHeadOK,ScanCBHead0;driver may have zeroed ScanCBHead
ScanBuffer←L,:ScanCBHeadOK;
ScanCBHead0: NOP,:noCurrent;
ScanCBHeadOK:
MAR ← ScanBuffer + 1;
NOP;
TASK;
MD ← StatusDONE;
MAR ← ScanBuffer - 1;
NOP;
NOP;
L ← MD;--link
MAR ← ScanCBHead;
MTEMP←L,L←0;5x
ScanBuffer←L,TASK;
MD←MTEMP,:noCurrent;
startScan:L←MD;5
;quick like a bunny pulse start, then (whew!) you can TASK
MAR←ScanCBHead+1;StartCommand6
T ← 10;get ready for faking 1770167
ScanWait←L; 8
L←MD;9
MAR←177026-T;Outport;10
T←200;11
ScanData←L;12
MD←ScanData,L←ScanData OR T;<0><START><SkipCount>;START=713
T←10;1x
MAR←177026-T;Outport;1x
MTEMP ← L,TASK;<1><START><SkipCount>;16-17
MD←MTEMP;1x
T ← 10;19
MAR← 177026-T;Outport;2x
NOP;2x
SINK←ScanBuffer,BUS=0;22
MD←ScanData,:haveCurrent;!1,2,haveCurrent,noCurrent;23
;there is a current scan buffer: mark it DataLate, clear CB queue
haveCurrent: MAR ← ScanCBHead;22
NOP;23
NOP;24
L←MD+1,BUS=0,TASK;25
!1,2,HeadOK,Head0;driver may have zeroed ScanCBHead
ScanBuffer ← L,:
HeadOK;!1,2,HeadOK,Head0;2x
HeadOK:MAR ← ScanBuffer;2x
NOP;28
TASK;29
MD ← StoreCount;30
MAR ← ScanBuffer + 1;31
NOP;32
TASK;3x
MD ← StatusDATALATE;3x
Head0:L←0;3x
MAR ← ScanCBHead;3x
ScanBuffer ← L;3x
StoreCount ← L;3x
MD ← ScanBuffer,:doMouse;39
;check for available input buffer
noCurrent: MAR←ScanCBHead;24
L←0;25
StoreCount←L;2x
L←MD,BUS=0;2x
ScanBuffer←L,:haveHead;!1,2,haveHead,noHead;2x
;ScanCB structure:
;link
;command (Read,Delay,Forward,Back)
;status/count (negative = status, pos=count)
;buffer
!3,4,CommandREAD,CommandDELAY,CommandFORWARD,CommandBACK;
haveHead:
MAR←L←ScanBuffer+1;29
ScanBuffer←L;3x
T ← 10;3x
SINK←MD,BUS;3x
L ← 177026-T,:CommandREAD;3x
!1,2,realBuffer,dummyBuffer;
CommandREAD: MAR ← L ← ScanBuffer+1;34
ScanBuffer ← L;35
NOP;36
L←MD;3x
MAR ← ScanBuffer + 1;3x
StoreCount ← L;doesn’t work for odd scan counts3x
NOP;40
L ← MD-1,BUS=0,TASK;4x
ScanBuffer ← L,:realBuffer;42
dummyBuffer: L←0;43
ScanBuffer←L,:noMouse;44
;DELAY: wait until next start pulse (just throw command away)
CommandDELAY: NOP,:dequeueCB;35
$521$521;
$523$523;
;MOTORCTL=5
;<00000000><ENABLE><MOTORCTL><xxxx>
;0101xxxx = disabled = 120 (521 available)
CommandBACK:
MAR ← 420-1;
MTEMP←L;set up to be Outport=177016
SINK ← MD,BUS;
MAR←MTEMP,:bstep0;Outport;34
;sequence is: 1,0,2,3
bstep0:L←523-1,:stepDone;#522
bstep1:L←521-1,:stepDone;#520
bstep2:L←523,:stepDone;#523
bstep3:L←521,:stepDone;#521
CommandFORWARD:
MAR ← 420-1;
MTEMP←L;set up to be Outport=177016
SINK ← MD,BUS;
MAR←MTEMP,:fstep0;Outport;34
;sequence is: 3,2,0,1
fstep0:L←521,:stepDone;#521
fstep1:L←523,:stepDone;#523
fstep2:L←521-1,:stepDone;#520
fstep3:L←523-1,:stepDone;#522
stepDone: ScanData←L;
MD←ScanData;<0><MOTORCTL><StepState>
T←200;
MAR←MTEMP;
L←ScanData OR T;
ScanData←L;
MD ← ScanData;<1><MOTORCTL><StepState>
MAR←MTEMP;
L←ScanData XOR T;
ScanData←L;
MD ← ScanData;<0><MOTORCTL><StepState>
MAR ← 420-1;store updated value
TASK;
MD←ScanData,:dequeueCB;
;take CB off queue, mark DONE, store ScanData into Outport
dequeueCB: MAR ← ScanBuffer + 1;43
NOP;44
TASK;4x
MD ← StatusDONE;4x
MAR ← ScanBuffer - 1;
NOP;
NOP;
L ← MD;--link
MAR ← ScanCBHead;5x
MTEMP←L,L←0;5x
ScanBuffer←L,TASK;5x
MD←MTEMP,:noMouse;59
ScannerOff: NOP;3
NOP;4
L←MD;5
ScanWait←L,:doMouse;6
realBuffer: MAR← R37,:MRTA;43
noHead: MAR← R37,:doMousex;29
doMouse1: MAR← R37,:doMousex;24
doMouse2: MAR← R37,:doMousex;39
doMouse3: MAR← R37,:MRTA;50
doMouse4: MAR← R37,:MRTA;
doMouse5: MAR← R37,:MRTA;59
noCountMouse: MAR← R37,:doMousex;9
;special code for long MRT cycles: don’t update mouse
noMouse: MAR←R37,:MRTA;63
doMouse:MAR← R37;**FIRST REFRESH CYCLE**40
doMousex:SINK← MOUSE, BUS;MOUSE DATA IS ANDED WITH 17B
MRTA:L← T← -2, :TX0;DISPATCH ON MOUSE CHANGE42,64
TX0:L← R37 AND NOT T, T← R37;INCREMENT CLOCK65
T← 3+T+1, SH=0;IE. T← T +4. IS INTV TIMER ON?66
L←REFIIMSK AND T,:DOTIMER;[DOTIMER,NOTIMER]ZERO HIGH 4 BITS67
NOTIMER: R37← L; STORE UPDATED CLOCK68(better have timer off)
NOTIMERINT: T← 2;NO STATE AT THIS POINT IN PUBLIC REGS69
MAR← R37 XOR T,T← R37;**SECOND REFRESH CYCLE**70
L← REFZERO AND T;ONLY THE CLOKCK BITS, PLEASE71
SH=0, TASK;TEST FOR CLOCK OVERFLOW72
:NOCLK;[NOCLK,CLOCK]73
NOCLK:T ← 200;81
MAR← R37 XOR T;**THIRD FEFRESH CYCLE**82
L← CURX, BLOCK;CLEARS WAKEUP REQUEST FF8x
T← 2 OR T, SH=0;NEED TO CHECK CURSOR?8x
MAR← R37 XOR T, :DOCUR;**FOURTH REFRESH CYCLE**85
NOCUR:CURDATA← L, TASK;86
MRTLAST:CURDATA← L, :MRTloop;END OF MAIN LOOP90
DOTIMER:R37← L;STORE UPDATED CLOCK
L←0;if we ever get here, swat break at 0
PC←L;
MAR← EIALOC;INTERVAL TIMER/EIA INTERFACE
L← 2 AND T;
SH=0, L← T← REFZERO.T;***V3 CHANGE (USED TO BE BIAS)
CURDATA←L, :SPCHK;CURDATA← CURRENT TIME WITHOUT CONTROL BITS
SPCHK:SINK← MD, BUS=0, TASK;CHECK FOR EIA LINE SPACING
SPIA::NOTIMERINT, CLOCKTEMP← L;
NOSPCHK:L←MD;CHECK FOR TIME = NOW
MAR←TRAPDISP-1;CONTAINS TIME AT WHICH INTERRUPT SHOULD HAPPEN
MTEMP←L;IF INTERRUPT IS CAUSED,
L← MD-T;LINE STATE WILL BE STORED
SH=0, TASK, L←MTEMP, :SPIA;
TIMERINT:MAR← ITQUAN;STORE THE THING IN CLOCKTEMP AT ITQUAN
L← CURDATA;
R37← L;
T←NWW;AND CAUSE AN INTERRUPT ON THE CHANNELS
MD←CLOCKTEMP;SPECIFIED BY ITQUAN+1
L←MD OR T, TASK;
NWW←L,:NOTIMERINT;
CLOCK:MAR← CLOCKLOC;R37 OVERFLOWED. UPDATE CLOCK74
NOP;75-76
L← MD+1;7x
MAR← CLOCKLOC;7x
MTEMP← L, TASK;79
MD← MTEMP, :NOCLK;80
DOCUR:L← T← YPOS;CHECK FOR VISIBLE CURSOR ON THIS SCAN86
SH < 0, L← 20-T-1; ***x13 change: the constant 20 was 1787
SH<0, L← 2+T, :SHOWC;88
WAITC:YPOS← L, L← 0, TASK, :MRTLAST;89
SHOWC:MAR← CLOCKLOC+T+1, :CNOTLAST;89
CNOTLAST:T← CURX, :CURF;90
CLAST:T← 0;90
CURF:YPOS← L, L← T;91
CURX← L;92
L← MD, TASK;93
CURDATA← L, :MRTloop;
;AFTER THIS DISPATCH, T WILL CONTAIN XCHANGE, L WILL CONTAIN YCHANGE-1
TX1:L← T← ONE +T, :M00;Y=0, X=143
TX2:L← T← ALLONES, :M00;Y=0, X=-143
TX3:L← T← 0, :M00;Y=1, X= 043
TX4:L← T← ONE AND T, :M00;Y=1, X=143
TX5:L← T← ALLONES XOR T, :M00;Y=1, X=-143
TX6:T← 0, :M00;Y= -1, X=043
TX7:T← ONE, :M00;Y= -1, X=143
TX8:T← ALLONES, :M00;Y= -1, X= -143
M00:MAR← MOUSELOC;START THE FETCH OF THE COORDINATES44
MTEMP← L;YCHANGE -145-46
L← MD+ T;X+ XCHANGE47
T← MD;Y48
T← MTEMP+ T+1;Y+ (YCHANGE-1) + 149
MTEMP← L, L← T;50
MAR← MOUSELOC;NOW RESTORE THE UPDATED COORDINATES51
CLOCKTEMP← L;52-53
MD← MTEMP, TASK;54
MD← CLOCKTEMP, :MRTA;55