#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,ScannerOff
2
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