;; Press Microcode -- "Scan Microcode" (Scan conversion pass)

; last modified by Butterfield, September 29, 1980 4:22 PM
; - change TRP10 and TRP11 end tests to be SH=0 - 9/29
; - ScanPutChar(TRP1), don’t mask down BELOChar.Bit - 8/8
; - add TRP10 and TRP11 dispatches - 3/18
; - include DispatchMc.mu inline and start to re-work it - 3/18
; - get lastMask using rightMask1 - 3/7
; - bum a word at TRP2 - 3/5/80

%0, 1777, 23, LOC23;
Used by RdRAM
%0, 1777, 24, LOC24;
and WriteRam in ScanConvert
%0, 1777, 37, TRAP1;
RAM trap location
$LREG
$R40;
#TriConMc.Mu;

; Additional emulator definitions
$AC2
$R1;
$AC3
$R0;
$PC
$R6;
$XREG
$R7;
$TEMP
$R5;Shared with SAD

$400
$400;

;R register availability:
; R10
; (R14 used by disk)
; R15-R17
; R35-R36
;
;S register availability:
; (R40 = last L in RAM)
; R41-R56 -- used by Slot, but can be re-used if Slot off.
; (R71-R76 used by disk)
; (R77 unusable)

; Notation:
;
** means TASK break may happen after this instruction
;
Note that an instruction line with ** may NOT have
;
branch conditions or BUS (i.e., anything that alters NEXT)
;
!a,b means the label a (which is the goto of this instruction)
;
is in a branch table with b.
;
;********************************************************************
; Trap handling stuff (copied from Ingalls)
; If trap is 70000 + disp field, this is a trap for us; dispatch
; on low order 3 bits to TRP0-TRP7. Otherwise, return the trap
; to the Emulator.

!637,1,TRAPX10; X10 microcode locn of TRAP
!645,1,TRAPX13; X13 location
;TRAP1; X21 location

!1,2,RETRAP,TRPDISP;

TRAPX10: T← 37, :TRPX;
TRAPX13: T← 37, :TRPX;
TRAP1:
T← 37, :TRPX;

TRPX:
L← T← XREG.T;Look for trap # 70000
TEMP← L;
T← 20;
L← LREG-T;
SH=0, TASK;
:RETRAP;** !RETRAP, TRPDISP
RETRAP: MAR← TRAPPC;
T← TEMP;
MD← PC;
MAR← TRAPPC+T+1;
NOP;
L← MD, TASK, :PCL;

; Trap dispatch to the various functions

!17,20,TRP0,TRP1,TRP2,TRP3,TRP4,TRP5,TRP6,TRP7,TRP10,TRP11;

TRPDISP: SINK← DISP, BUS; No out-of-range protection
:TRP0;

;********************************************************************
; BCPLRETL -- Do a "Bcpl return" with L as value of the function.
; BCPLRET -- Simply do a "Bcpl return"

BCPLRETL: AC0← L;
BCPLRET: L← AC3+1, TASK;
PCL:
PC← L;**
SWRET:
SWMODE;
:START;


;********************************************************************
; Definitions for Press scan conversion microcode
;
;
; G L O B A L
;
$ScanBitWc
$R70;Number of words/scan line
$mpSBuf
$R67;ScanLineIndex!s = pointer to scan-line buffer
;
already offset for any margin effects

$177770
$177770;
$177774
$177774;
$177776
$177776;
$170000
$170000;

; ScanPutChar
$ShiftCnt
$R66;
$nS
$R65;
$Fw
$R64;
$Fadr
$R63;
$Badr
$R62;
$FCNT
$R61;
$WLEFT
$R60;
$SubRet
$R57;
$Fb
$R56;
$FracPart
$R55;
$lastMask
$R54;
$leftMask
$R53;
$rightMask
$R52;
$leftMask1
$R51;
$rightMask1
$R50;
$initialFadr
$R47;
$thisW
$R46;
$inputShiftAmt
$R45;

$nextW
$R15;Must be an R register
$Badr0
$R16;Must be an R register
;TEMP
$R5;shared with SAD

; ScanPutDots (also ScanPutHalf)
$INADR
$R66;
$BIT
$R65;
$BBIT
$R64;
$BINCR
$R63;
$BBITINIT
$R62;
$BDIM
$R61;
$BSTATUS
$R60;
$BDELTA
$R57;
$INBIT
$R56;
$WORDOUT
$R55;
$BCOUNT
$R54;
$WORDIN
$R53;

; ScanPutHalf
$screenAddr
$R52;
$screenMod
$R51;
$screenCount
$R50;
$screen
$R47;
$cascadeDiag
$R46;
$black
$R45;
$white
$R44;
$range
$R43;
$threshold
$R42;
$errorBuff
$R41;
$error
$R36;R register for shifts
$error1
$R35;R register for shifts
$sample
$R17;R register for shifts
$MASK
$R3;

;
;ScanLoadVars(v)
;
v!0 = mpSBuf
;
v!1 = ScanBitWc

TRP0:
MAR← AC0;
NOP;
L←MD;
MAR← AC0+1;
mpSBuf← L;
L←MD, TASK;
ScanBitWc← L, :BCPLRET;**
;
;********************************************************************
; ScanPutChar(Soff, v) -- scan convert a character
;
v=> structure BELOChar describing character to do:
;
Cbit bit 1 =1
;
spare bit 3
;
hwbit 12;-Number of bits/sl
;
;
orbitXbit 4;scan line in band to start on (=Soff)
;
Bit bit 12;Address on scan line
;
;
bitOffsetbit 4;offset of char start in word of font
;
orbitSbit 12;nscanlines-1 left to do
;
;
Fadr word;Address of next font word
; returns 0 if no left-overs
; returns 4 (size BELOChar/16) if leftovers ; also ns and Fadr
;
fields of v are updated.

!17,20,CYCL0,CYCL1,CYCL2,CYCL3,CYCL4,CYCL5,CYCL6,CYCL7,CYCL8,CYCR7,CYCR6,CYCR5,CYCR4,CYCR3,CYCR2,CYCR1;

!17,20,wCycR0,wCycR1,wCycR2,wCycR3,wCycR4,wCycR5,wCycR6,wCycR7,wCycL8,wCycL7,wCycL6,wCycL5,wCycL4,wCycL3,wCycL2,wCycL1;

!17,20,PCleftMask0,PCleftMask1,PCleftMask2,PCleftMask3,PCleftMask4,PCleftMask5,PCleftMask6,PCleftMask7,PCleftMask10,PCleftMask11,PCleftMask12,PCleftMask13,PCleftMask14,PCleftMask15,PCleftMask16,PCleftMask17;

;3/7 !17,20,PClastMask0,PClastMask1,PClastMask2,PClastMask3,PClastMask4,
;3/7 PClastMask5,PClastMask6,PClastMask7,PClastMask10,PClastMask11,
;3/7 PClastMask12,PClastMask13,PClastMask14,PClastMask15,PClastMask16,
;3/7 PClastMask17;

!1,2,PCGOT1Mask,PCGOTlastMask; ;3/7
!1,2,PCGOTlastMask2,PCGOTlastMask1; ;3/7

!17,20,PC1Mask0,PC1Mask1,PC1Mask2,PC1Mask3,PC1Mask4,PC1Mask5,PC1Mask6,PC1Mask7,PC1Mask10,PC1Mask11,PC1Mask12,PC1Mask13,PC1Mask14,PC1Mask15,PC1Mask16,PC1Mask17;

!1,2,PCH2,PCH3;
!1,2,PCH0,PCH5;
!1,2,CHARL1,CHARL2;
!1,2,CHARLmore,CHARLlast;
!1,2,cycleThisW,ZthisW;
!1,2,CHARL5,CHARL6;
!1,2,CHARL,CHARL8;
!1,2,CHARL9,PCH1;
!1,2,CYRET0,CycleRet2;

;Note: Badr0 must be R reg for shifts

TRP1:
MAR←L←AC1+1;v
AC1←L;
;8/8
T← 7777;
;8/8
L← MD AND T;//let Bit=v>>BELOChar.Bit
L← MD;//let Bit=v>>BELOChar.Bit ;8/8
Badr0← L RSH 1;1 shift
T← 17;
L←LREG AND T,TASK;Compute skew
ShiftCnt←L;**//let ShiftCnt=(Bit)

T← 170000;
MAR←L←AC1-1;hw word
L← Badr0;
Badr0← L RSH 1;2 shifts
T←MD OR T;T←-hw
L←0-T;
Fb←L;//let Fb=-(#170000+v>>BELOChar.orbitW)

T←17;
L←Fb AND T;
FracPart←L;//let FracPart=Fb

SINK← FracPart, BUS;
;3/7
T← 170000, :PClastMask0;!PClastMask0,1,2,....
;3/7 PCGOTlastMask: lastMask←L;
//let lastMask=masks!(16-FracPart)
T← 0, BUS=0, :PC1Mask0;!PC1Mask0,1,2,.... ;3/7
PCGOTlastMask: ;3/7
T← ALLONES, SH<0; ;3/7
L← LREG XOR T, :PCGOTlastMask2; !PCGOTlastMask2,PCGOTlastMask1 ;3/7

PCGOTlastMask1: ;3/7
L← ALLONES; ;3/7
PCGOTlastMask2: ;3/7
lastMask←L;//let lastMask=masks!(16-FracPart) ;3/7

T←17;
L←Fb+T;
T←177760;
L←LREG AND T;
Fw←L;//let Fw=(Fb+15)/16

MAR←L←AC1+1;
AC1←L;
T←7777;
L←T←MD AND T;T←bitOffset,nS;L←nS
L←LREG+1;was nScanLines-1
nS←L,L←T;//let nS=v>>BELOChar.orbitS+1

T←170000;
L←T←LREG.T;
TEMP←L MLSH 1;
L←T←TEMP;
TEMP←L MLSH 1;
L←T←TEMP;
TEMP←L MLSH 1;
L←T←TEMP;
TEMP←L MLSH 1;
L←TEMP,TASK;
inputShiftAmt←L;//let inputShiftAmt=v>>BELOChar.bitOffset

SINK←ShiftCnt, BUS;
;3/7
T←ALLONES,:PC1Mask0;!PC1Mask0,...
T← ALLONES, BUS=0, :PC1Mask0; !PC1Mask0,... ;3/7
PCGOT1Mask: rightMask1←L;
//let rightMask1=-1 rshift ShiftCnt
L←rightMask1 XOR T;
leftMask1←L;//let leftMask1=not rightMask1

MAR← AC1+1;Fadr word
L← Badr0;
Badr0← L RSH 1;3 shifts
L←MD, TASK;
initialFadr←L;** initialFadr= first font address
L←Badr0;
Badr0← L RSH 1;4 th shift
T←AC0;Scan line number (0-15 decimal)
MAR← mpSBuf+T;
L← 20-T;
AC0←L;AC0= number of scan-lines to go to run out
T←MD-1;//let Badr=mpSBuf!Soff+(Bit rshift 4)

;Prepare to call CHARL to do one scan-line of the character
PCH0:
L←Badr0+T;L=first band address-1
Badr0←L, TASK;
Badr←L;**

SINK←inputShiftAmt,BUS;
T←ALLONES,:PCleftMask0;!PCleftMask0,PCleftMask1,...
PCGOTleftMask:
leftMask←L;//let leftMask=masks!inputShiftAmt
L←leftMask XOR T,TASK;
rightMask←L;//let rightMask=not leftMask

LOC23:
XMAR←L←initialFadr;
Fadr←L;
T←MD,:CycleInit;//let nextW=Cycle(Fadr!0,inputShiftAmt)
CycleRet1:
L←0;
WLEFT←L;//let WLEFT=0

T←20;
L← Fw-T, TASK;
FCNT← L, :CHARL;** FCNT = 20*(Fw-1)
PCH1:
L← nS-1;
nS←L, SH=0;
L←AC0-1, :PCH2;!PCH2,PCH3

;nS has not expired; more to do.
PCH2:
AC0←L, SH=0;
T←ScanBitWc, :PCH0;!PCH0,PCH5

;nS=0 -- character is completed
PCH3:
L←0, :BCPLRETL;No leftovers

;S=0 -- run out of band. Update BELOChar structure
PCH5:
L←T←inputShiftAmt;move to leftmost 4 bits
TEMP←L MRSH 1;
L←T←TEMP;
TEMP←L MRSH 1;
L←T←TEMP;
TEMP←L MRSH 1;
L←T←TEMP;
TEMP←L MRSH 1;
T←TEMP;

MAR←AC1;
L← nS-1;
L←LREG OR T, TASK;//v>>BELOChar.bitOffset=inputShiftAmt
MD← LREG;**//v>>BELOChar.orbitS=nS-1
MAR←AC1+1;Now restore Fadr to structure
L←4;
MD←initialFadr,:BCPLRETL;//v>>BELOChar.CoreAdr=Fadr
;//resultis size BELOChar/16

; Mask tables here to make above code somewhat more readable

;3/7 PClastMask0:
L← ALLONES, :PCGOTlastMask;
;3/7 PClastMask1:
L← 100000, :PCGOTlastMask;
;3/7 PClastMask2:
L← 140000, :PCGOTlastMask;
;3/7 PClastMask3:
L← 160000, :PCGOTlastMask;
;3/7 PClastMask4:
L← 170000, :PCGOTlastMask;
;3/7 PClastMask5:
L← 174000, :PCGOTlastMask;
;3/7 PClastMask6:
L← 176000, :PCGOTlastMask;
;3/7 PClastMask7:
L← 177000, :PCGOTlastMask;
;3/7 PClastMask10:
L← 177400, :PCGOTlastMask;
;3/7 PClastMask11:
L← 177600, :PCGOTlastMask;
;3/7 PClastMask12:
L← 177700, :PCGOTlastMask;
;3/7 PClastMask13:
L← 177740, :PCGOTlastMask;
;3/7 PClastMask14:
L← 177760, :PCGOTlastMask;
;3/7 PClastMask15:
L← 177770, :PCGOTlastMask;
;3/7 PClastMask16:
L← 177774, :PCGOTlastMask;
;3/7 PClastMask17:
L← 177776, :PCGOTlastMask;

PC1Mask0:
L← ALLONES, :PCGOT1Mask;
PC1Mask1:
L← 77777, :PCGOT1Mask;
PC1Mask2:
L← 37777, :PCGOT1Mask;
PC1Mask3:
L← 17777, :PCGOT1Mask;
PC1Mask4:
L← 7777, :PCGOT1Mask;
PC1Mask5:
L← 3777, :PCGOT1Mask;
PC1Mask6:
L← 1777, :PCGOT1Mask;
PC1Mask7:
L← 777, :PCGOT1Mask;
PC1Mask10:
L← 377, :PCGOT1Mask;
PC1Mask11:
L← 177, :PCGOT1Mask;
PC1Mask12:
L← 77, :PCGOT1Mask;
PC1Mask13:
L← 37, :PCGOT1Mask;
PC1Mask14:
L← 17, :PCGOT1Mask;
PC1Mask15:
L← 7, :PCGOT1Mask;
PC1Mask16:
L← 3, :PCGOT1Mask;
PC1Mask17:
L← ONE, :PCGOT1Mask;

PCleftMask0:
L← ALLONES, :PCGOTleftMask;
PCleftMask1:
L← 177776, :PCGOTleftMask;
PCleftMask2:
L← 177774, :PCGOTleftMask;
PCleftMask3:
L← 177770, :PCGOTleftMask;
PCleftMask4:
L← 177760, :PCGOTleftMask;
PCleftMask5:
L← 177740, :PCGOTleftMask;
PCleftMask6:
L← 177700, :PCGOTleftMask;
PCleftMask7:
L← 177600, :PCGOTleftMask;
PCleftMask10:
L← 177400, :PCGOTleftMask;
PCleftMask11:
L← 177000, :PCGOTleftMask;
PCleftMask12:
L← 176000, :PCGOTleftMask;
PCleftMask13:
L← 174000, :PCGOTleftMask;
PCleftMask14:
L← 170000, :PCGOTleftMask;
PCleftMask15:
L← 160000, :PCGOTleftMask;
PCleftMask16:
L← 140000, :PCGOTleftMask;
PCleftMask17:
L← 100000, :PCGOTleftMask;
;
;Character loop for one scan-line.
; Enter at CHARL with:
;
initialFadr+1 => next word of font to fetch
;
Badr+1 => next word to store in the band
;
ShiftCnt = shift amount for each font word (to the right)
;
FCNT+20 = 20* number of font words/scanline
;
MASK = -1 rshift ShiftCnt
; Exit to PCH1 with:
;
Fadr+1 => next word of font to fetch
;
ShiftCnt,MASK unchanged

;let thisW=nextW&leftMask
;nextW=Cycle(Fadr!j,inputShiftAmt)
;thisW=thisW+(rightMask&nextW)
CHARL:
T←leftMask;
L←nextW AND T;
thisW←L;//let thisW=nextW&leftMask

LOC24:
XMAR←L←Fadr+1;
Fadr←L;
L←MD, BUS=0, TASK;
nextW←L, :CHARL1;** !CHARL1,CHARL2

;Left cycle the non-zero font word by inputShiftAmt, and pick out some low bits
; (governed by MASK) to put in this band word.
CHARL1:
T←nextW, :Cycle;//nextW=Cycle(Fadr!j,inputShiftAmt)
CycleRet2:
T←rightMask,:CHARL3;
CHARL2:
T←rightMask;
CHARL3:
L←nextW AND T;
T←thisW;
L←LREG+T;
thisW←L;//thisW=thisW+(rightMask&nextW)

;if j eq Fw then
//update shiftAmt, mask w
; [ thisW=thisW&lastMask
; inputShiftAmt=inputShiftAmt+Fb
; initialFadr=initialFadr+inputShiftAmt/16
; inputShiftAmt=inputShiftAmt
; ]
SINK←FCNT,BUS=0;
L←T←thisW,:CHARLmore;
!1,2,CHARLmore,CHARLlast;
CHARLlast: L←lastMask AND T,TASK;
thisW←L;//thisW=thisW&lastMask
T←Fb;
L←inputShiftAmt+T;
inputShiftAmt←L;//inputShiftAmt=inputShiftAmt+Fb
TEMP←L RSH 1;
L←TEMP;
TEMP←L RSH 1;
L←TEMP;
TEMP←L RSH 1;
L←TEMP;
TEMP←L RSH 1;
T←initialFadr;
L←TEMP+T,TASK;
initialFadr←L;//initialFadr=initialFadr+inputShiftAmt/16
T←17;
L←inputShiftAmt AND T;
inputShiftAmt←L;//inputShiftAmt=inputShiftAmt
L←T←thisW,:CHARLmore;

;if thisW then
//Play only if non-zero
;
[ thisW=Cycle(thisW,16-ShiftCnt)
;
WLEFT=(thisW&rightMask1)%WLEFT
;
]
CHARLmore:
L←T←thisW,BUS=0;
NOP,:cycleThisW;!1,2,cycleThisW,ZthisW;
cycleWRet:
T←rightMask1;
L←thisW AND T;
T←WLEFT;
L←LREG OR T;
WLEFT←L;

;if WLEFT then
;
Badr!0=(Badr!0 % WLEFT)

ZthisW:
SINK←WLEFT,BUS=0;
NOP, :CHARL5;!CHARL5,CHARL6

;Because bits to "or" (W1) non-zero, must store
CHARL5:
MAR←Badr+1;
T←WLEFT;
L← MD OR T;
MAR←T←Badr+1;
WLEFT←L,L←T;
Badr← L, TASK;Bump Badr
MD← WLEFT, :CHARL7;**

;WLEFT=thisW&leftMask1
;Badr=Badr+1
CHARL6:
L←Badr+1, TASK;
Badr←L;**

;Compute WLEFT, the bits left over for next band word.
CHARL7:
T← leftMask1;
L← thisW AND T,TASK;Bits left over for next time
WLEFT← L;**

;If FCNT=0, we are done with the scan-line. Else FCNT←FCNT-20
L←T← FCNT;
L←177760 +T, SH=0;Test FCNT=0
FCNT←L, :CHARL;!CHARL,CHARL8

;End of loop, need to store final band word with any remaining bits
; Badr!0=(Badr!0 % WLEFT)
CHARL8:
MAR←Badr+1;
L←T← WLEFT,BUS=0;
L←MD OR T, :CHARL9;!CHARL9,PCH1
CHARL9: MAR←Badr+1;
NOP, TASK;
MD← LREG, :PCH1;**

;
;Cycle left.
; Enter at CYCLE with:
;
inputShiftAmt = count of places to cycle
;
T = bits
; Exit to CHARL2 with
;
nextW= cycled bits
; Note: nextW must be R register for shifts

CycleInit:
L←0;
SubRet←L,:Cycle;

Cycle:
SINK← inputShiftAmt, BUS;
L← T, TASK, :CYCL0;

CYCL0:
nextW← L, :CYRET;

CYCR4:
nextW←L MRSH 1;
CYCY3:
T←L←nextW, TASK;
CYCR3:
nextW←L MRSH 1;
CYCY2:
T←L←nextW, TASK;
CYCR2:
nextW←L MRSH 1;
CYCY1:
T←L←nextW; TASK;
CYCR1:
nextW←L MRSH 1, :CYRET;

CYCL4:
nextW←L MLSH 1;
CYCZ3:
T←L←nextW, TASK;
CYCL3:
nextW←L MLSH 1;
CYCZ2:
T←L←nextW, TASK;
CYCL2:
nextW←L MLSH 1;
CYCZ1:
T←L←nextW, TASK;
CYCL1:
nextW←L MLSH 1, :CYRET;

CYCL8:
nextW← L LCY 8, :CYRET;
CYCL7:
nextW← L LCY 8, :CYCY1;
CYCL6:
nextW← L LCY 8, :CYCY2;
CYCL5:
nextW← L LCY 8, :CYCY3;
CYCR7:
nextW← L LCY 8, :CYCZ1;
CYCR6:
nextW← L LCY 8, :CYCZ2;
CYCR5:
nextW← L LCY 8, :CYCZ3;

CYRET:
SINK←SubRet,BUS;
L←ONE,:CYRET0;!1,2,CYRET0,CycleRet2
CYRET0:
SubRet←L,:CycleRet1;

;thisW←thisW rCycle ShiftCnt
cycleThisW:
SINK← ShiftCnt, BUS;
L← T, TASK, :wCycR0;

wCycR0:
thisW← L, :cycleWRet;

wCycR4:
TEMP←L MRSH 1;
wCycY3:
T←L←TEMP, TASK;
wCycR3:
TEMP←L MRSH 1;
wCycY2:
T←L←TEMP, TASK;
wCycR2:
TEMP←L MRSH 1;
wCycY1:
T←L←TEMP; TASK;
wCycR1:
TEMP←L MRSH 1, :wCycRET;

wCycL4:
TEMP←L MLSH 1;
wCycZ3:
T←L←TEMP, TASK;
wCycL3:
TEMP←L MLSH 1;
wCycZ2:
T←L←TEMP, TASK;
wCycL2:
TEMP←L MLSH 1;
wCycZ1:
T←L←TEMP, TASK;
wCycL1:
TEMP←L MLSH 1, :wCycRET;

wCycL8:
TEMP← L LCY 8, :wCycRET;
wCycL7:
TEMP← L LCY 8, :wCycY1;
wCycL6:
TEMP← L LCY 8, :wCycY2;
wCycL5:
TEMP← L LCY 8, :wCycY3;
wCycR7:
TEMP← L LCY 8, :wCycZ1;
wCycR6:
TEMP← L LCY 8, :wCycZ2;
wCycR5:
TEMP← L LCY 8, :wCycZ3;

wCycRET:
L←TEMP;
thisW←L,:cycleWRet;
;
;********************************************************************
;ScanPutDots(Soff, v)
; Blows up a 1-bit bit map, and spits it out.
; Soff = scan-line number within band (0-15 decimal)
; v => BEDots entry:
;
H word ;;ignore
;
Bstart word -- starting bit position on scan-line
;
Bincr word -- =+1 if bit position increases, else -1
;
Bdim word -- -# of bits to output on the scan-line
;
Opaque bit
;
Smagnify bit
;
Bmagnify bit -- 20000 bit =1 => magnify on output
;
Code bit 13
;
Bdelta word -- decrement for DDA
;
BitBuf word -- pointer to first word of input data
;
BitPhase word -- bit position in word of first input sample
;
;DotsDeltaConst=#37777
;

$DOTSDELTACOnST $37777;

!17,20,SPDORM0,SPDORM1,SPDORM2,SPDORM3,SPDORM4,SPDORM5,SPDORM6,SPDORM7,SPDORM10,SPDORM11,SPDORM12,SPDORM13,SPDORM14,SPDORM15,SPDORM16,SPDORM17;

!17,20,SPDMASK0,SPDMASK1,SPDMASK2,SPDMASK3,SPDMASK4,SPDMASK5,SPDMASK6,SPDMASK7,SPDMASK10,SPDMASK11,SPDMASK12,SPDMASK13,SPDMASK14,SPDMASK15,SPDMASK16,SPDMASK17;

!1,2,SPD2,SPD1;
!1,2,SPD6,SPD4;
!1,2,SPD20,SPD8;
!1,2,SPD3,SPD9;
!1,2,SPD21,SPD23;
!1,2,SPD26,SPD28;
!1,2,SPD29,SPD40;
!1,2,SPD27,SPD41;
!1,2,SPD30,SPD3a;
!1,2,SPD20a,SPD31;
!1,2,SPHREE,SPDREE;


;TRP2:
MAR←AC1+1;Fetch Bstart
;
T←3;
;
L←AC1+T;
TRP2:
T← MAR← AC1 +1;Fetch Bstart
L← 2 +T;

AC1←L;
L←MD;
MAR←AC1-1;Fetch Bincr
Badr0←L RSH 1;1 shift
T←17;
L←LREG AND T;
T←MD;
BBIT←L, L←T, TASK;Bit offset in the word to begin output
BINCR←L;**
L←BINCR;
MAR←AC1, SH<0;
L←0, :SPD2;!SPD2,SPD1 -- branch if Bincr<0
SPD1:
L←17;Bincr<0
SPD2:
BBITINIT←L;
L←MD, TASK;
BDIM←L;**

MAR←L←AC1+1;Fetch word with Bmagnify in it;
AC1←L;
L←Badr0;
Badr0←L RSH 1;2nd shift
L←MD, TASK;
BSTATUS←L;**

MAR←L←AC1+1;Fetch Bdelta
AC1←L;
L←Badr0;
Badr0←L RSH 1;3rd shift
L←MD, TASK;
BDELTA←L;**

MAR←L←AC1+1;Fetch address of input bits
AC1←L;
L←MD-1, TASK;
INADR←L;** INADR=address of next word to get -1

MAR←L←AC1+1;Fetch bit position in word
AC1←L;
L←Badr0;
Badr0←L RSH 1;4th shift
T←MD;
L←17-T, TASK;
INBIT←L;**
T←AC0;

MAR←mpSBuf+T;Fetch scan-buffer
L←0;
WORDOUT←L;
T←Badr0;
L←MD+T, TASK;
Badr0←L;** Badr0 = band address

;Test for halftoning here
T←37;
L←BSTATUS AND T;
L←DOTSDELTACOnST,SH=0;
BCOUNT←L, :SPHREE;!SPHREE,SPDREE

;Get a Bit
SPD3:
L←INBIT-1, :SPD3z;Duplicated in order to address it
SPD3a:
L←INBIT-1;
SPD3z:
INBIT←L, SH<0;
L←17, :SPD6;!SPD6,SPD4
SPD4:
INBIT←L;Ran out of input word
SPDREE:
MAR←L←INADR+1;Fetch next input word
INADR←L;
L←MD, TASK;
WORDIN←L;**
SPD6:
SINK←INBIT,BUS;
T←WORDIN, :SPDMASK0;!SPDMASK0,1,2,...
SPD7:
BIT←L;**

;Get DDA
T←20000;
L←BSTATUS AND T;
T←BDELTA, SH=0;Test Bmagnify
L←BCOUNT-T, :SPD20;!SPD20,SPD8
SPD8:
BCOUNT←L, SH<0;Not magnifying -- do DDA
T←DOTSDELTACOnST, :SPD3;!SPD3,SPD9
SPD9:
L←BCOUNT+T, TASK;
BCOUNT←L;**

;Put a bit
SPD20:
L←BIT, :SPD20z;Duplicated in order to address it
SPD20a:
L←BIT;
SPD20z:
T←BBIT, SH=0;
L←BINCR+T, :SPD21;!SPD21,SPD23
SPD21:
BBIT←L, L←T;Must or a bit in
SINK←LREG, BUS;
T←WORDOUT, :SPDORM0;!SPDORM0,1,2,...
SPD22:
WORDOUT←L, :SPD24;**
SPD23:
BBIT←L;

SPD24:
T←177760;
L←BBIT AND T;
L←BDIM+1, SH=0;
BDIM←L, SH=0, :SPD26;!SPD26,SPD28

;Bbit has run below 0 or above 17, so must store a word.
SPD26:
MAR←Badr0, :SPD27;!SPD27,SPD41 -- to SPD41 if Bdim=0
SPD27:
L←BBITINIT;
BBIT←L;
T←WORDOUT;
L←MD OR T,TASK;
WORDOUT←L;**
T←BINCR;
MAR←Badr0;
L←Badr0+T;
Badr0←L, T←0;Badr0 R register => T←0
MD←WORDOUT, L←T, TASK;
WORDOUT←L;**

SPD28:
T←20000, :SPD29;!SPD29,SPD40 -- to SPD40 if Bdim=0
SPD29:
L←BSTATUS AND T;
T←BDELTA, SH=0;
L←BCOUNT-T, :SPD30;!SPD30,SPD3a -- if no magnify, goto getabit
SPD30:
BCOUNT←L, SH<0;
T←DOTSDELTACOnST, :SPD20a; !SPD20a,SPD31 -- if overflow,
SPD31:
L←BCOUNT+T, TASK;Add the constant
BCOUNT←L, :SPD3;**

; Finish out by storing the last word. Do not bother to update
; any variables in v as they dont matter

SPD40:
MAR←Badr0;
SPD41:
T←WORDOUT;
L←MD OR T;
MAR←Badr0;
T←0;
MD←LREG, L←T, :BCPLRETL;Return 0


;Mask table here to make above more readable.

SPDORM0:
L←100000 OR T, TASK, :SPD22;
SPDORM1:
L←40000 OR T, TASK, :SPD22;
SPDORM2:
L←20000 OR T, TASK, :SPD22;
SPDORM3:
L←10000 OR T, TASK, :SPD22;
SPDORM4:
L←4000 OR T, TASK, :SPD22;
SPDORM5:
L←2000 OR T, TASK, :SPD22;
SPDORM6:
L←1000 OR T, TASK, :SPD22;
SPDORM7:
L←400 OR T, TASK, :SPD22;
SPDORM10:
L←200 OR T, TASK, :SPD22;
SPDORM11:
L←100 OR T, TASK, :SPD22;
SPDORM12:
L←40 OR T, TASK, :SPD22;
SPDORM13:
L←20 OR T, TASK, :SPD22;
SPDORM14:
L←10 OR T, TASK, :SPD22;
SPDORM15:
L←4 OR T, TASK, :SPD22;
SPDORM16:
L←2 OR T, TASK, :SPD22;
SPDORM17:
L←ONE OR T, TASK, :SPD22;

SPDMASK0:
L←ONE AND T, TASK, :SPD7;
SPDMASK1:
L←2 AND T, TASK, :SPD7;
SPDMASK2:
L←4 AND T, TASK, :SPD7;
SPDMASK3:
L←10 AND T, TASK, :SPD7;
SPDMASK4:
L←20 AND T, TASK, :SPD7;
SPDMASK5:
L←40 AND T, TASK, :SPD7;
SPDMASK6:
L←100 AND T, TASK, :SPD7;
SPDMASK7:
L←200 AND T, TASK, :SPD7;
SPDMASK10:
L←400 AND T, TASK, :SPD7;
SPDMASK11:
L←1000 AND T, TASK, :SPD7;
SPDMASK12:
L←2000 AND T, TASK, :SPD7;
SPDMASK13:
L←4000 AND T, TASK, :SPD7;
SPDMASK14:
L←10000 AND T, TASK, :SPD7;
SPDMASK15:
L←20000 AND T, TASK, :SPD7;
SPDMASK16:
L←40000 AND T, TASK, :SPD7;
SPDMASK17:
L←100000 AND T, TASK, :SPD7;

;
;***************************************
;ScanPutHalf (finish initialization, and spit out the bits)

!17,20,hCYCR0,hCYCR1,hCYCR2,hCYCR3,hCYCR4,hCYCR5,hCYCR6,hCYCR7,hCYCL8,hCYCL7,hCYCL6,hCYCL5,hCYCL4,hCYCL3,hCYCL2,hCYCL1;

!17,20,SPHOrM0,SPHOrM1,SPHOrM2,SPHOrM3,SPHOrM4,SPHOrM5,SPHOrM6,SPHOrM7,SPHOrM10,SPHOrM11,SPHOrM12,SPHOrM13,SPHOrM14,SPHOrM15,SPHOrM16,SPHOrM17;

!17,20,SPHMask0,SPHMask1,SPHMask2,SPHMask3,SPHMask4,SPHMask5,SPHMask6,SPHMask7,SPHMask10,SPHMask11,SPHMask12,SPHMask13,SPHMask14,SPHMask15,SPHMask16,SPHMask17;

!1,2,SPH6,SPH4;
!1,2,SPH20,SPH8;
!1,2,SPH3,SPH9;
!1,2,SPH21,SPH23;
!1,2,SPH26,SPH28;
!1,2,SPH29,SPH40;
!1,2,SPH27,SPH41;
!1,2,SPH30,SPH3a;
!1,2,SPH20a,SPH31;
!1,2,SPHScreen,SPHNoScreen;
!1,2,NoRem,Rem;

SPHREE: T←17;
fix INBIT (20-bit-sampleSize instead of 17-bit)
T←BSTATUS.T;
L←INBIT+1;
L←LREG-T;
INBIT←L;
;!!NO ERROR DISTRIBUTION!!!MAR←L←AC1+1;
pick up Error Vec for error distribution
;!!NO ERROR DISTRIBUTION!!!AC1←L;
;!!NO ERROR DISTRIBUTION!!!T←BDIM;
;!!NO ERROR DISTRIBUTION!!!L←MD-T,TASK;
;!!NO ERROR DISTRIBUTION!!!errorBuff←L;
**

L←AC1+1;!!NO ERROR DISTRIBUTION!!!
MAR←L←LREG+1;
pick up Screen Modulus
AC1←L;
L←0;
cascadeDiag←L;
L←MD,TASK;
screenMod←L;
**

MAR←L←AC1+1;
pick up screen address
AC1←L;
L←MD,TASK;
screenAddr←L;
**

MAR←L←AC1+1;
pick up IMin
AC1←L;
L←MD,TASK;
black←L;
**

MAR←AC1+1;
pick up IMax
L←0;
screenCount←L;
screen←L;
L←MD,TASK;
white←L;
**

T←black;
L←white-T,TASK;
nextW←L LSH 1;
**
T←nextW-1;
!!FIX!!
L←0-T;
!!FIX!!
threshold←L;
!!FIX!!
L←nextW;
nextW←L LSH 1;
L←nextW,TASK;
range←L;
**range=(white-black)*4

T←37;
L←BSTATUS AND T;
L←LREG-1;
SINK←LREG,BUS;
NOP,:SPHMask0;
SPH2: MASK←L;
**

; !!BUG: threshold*2 is what’s needed !! T←white;
; !!BUG !! L←black-T,TASK;
; !!BUG !! threshold←L;
**
L←threshold-1;
error←L,:SPHRE;
**

;Get a sample point
SPH3:
T←17, :SPH3z;Duplicated in order to address it
SPH3a:
T←17;
SPH3z:
T←BSTATUS.T;sampleSize
L←INBIT-T;
INBIT←L, SH<0;
L←20-T, :SPH6;!SPH6,SPH4

SPH4:
INBIT←L;Ran out of input word
SPHRE:
MAR←L←INADR+1;Fetch next input word
INADR←L;
L←MD, TASK;
WORDIN←L;**

SPH6:
T←WORDIN,:hCYCLE;
SPH7:
T←MASK;
L←nextW AND T;
T←black;
L←LREG-T;
sample←L LSH 1;
L←sample;
sample←L LSH 1;*4 to avoid errors on 25% calculation

;Get DDA
T←20000;
L←BSTATUS AND T;
T←BDELTA, SH=0;Test Bmagnify
L←BCOUNT-T, :SPH20;!SPH20,SPH8
SPH8:
BCOUNT←L, SH<0;Not magnifying -- do DDA
T←DOTSDELTACOnST, :SPH3;!SPH3,SPH9
SPH9:
L←BCOUNT+T, TASK;
BCOUNT←L;**

;Put a bit
;add screen frequency, if called for
SPH20:
L←screenAddr,BUS=0,:SPH20z;Duplicated in order to address it
SPH20a:
L←screenAddr,BUS=0;
SPH20z:
T←screenCount,:SPHScreen;!SPHScreen,SPHNoScreen
SPHScreen:
MAR←screenAddr+T;
L←screenCount+1;
screenCount←L;
L←MD,TASK;
screen←L;**

T←screenMod;
L←screenCount XOR T;
NOP,SH=0;
L←0,:NoRem;!NoRem,Rem
Rem:
screenCount←L;
NoRem: T←screen-1,:SPHyyy;


;!!NO ERROR DISTRIBUTION!!!SPHNoScreen:T←BDIM;
;!!NO ERROR DISTRIBUTION!!!
MAR←errorBuff+T;
;!!NO ERROR DISTRIBUTION!!!
T←sample-1;
;!!NO ERROR DISTRIBUTION!!!
T←screen+T+1;screen+samplescreen+sample
;!!NO ERROR DISTRIBUTION!!!
L←error-T;error-(screen+sample)
;!!NO ERROR DISTRIBUTION!!!
T←MD;errorBuff!BDIM
;!!NO ERROR DISTRIBUTION!!!
L←LREG+T;errorBuff!BDIM+error-(screen+sample)
SPHNoScreen: T←screen-1;
!!NO ERROR DISTRIBUTION!!
SPHyyy: T←sample+T+1;
!!NO ERROR DISTRIBUTION!!
L←0-T;
!!NO ERROR DISTRIBUTION!!
;!!NO ERROR DISTRIBUTION!!
error←L;

;test error ge threshold then SetBit() or error=error+range
T←threshold;
L←LREG-T;
T←BBIT,SH<0;
L←BINCR+T,:SPH21;!SPH21,SPH23 (SetBit,SetBitReturn)
SPH21:
BBIT←L, L←T;Must or a bit in
SINK←LREG, BUS;
T←WORDOUT, :SPHOrM0;!SPHOrM0,1,2,...
SPH22:
WORDOUT←L;**
;!!NO ERROR DISTRIBUTION!!!
L←error, :SPH24;

;!!NO ERROR DISTRIBUTION!!!SPH23:
BBIT←L;
;!!NO ERROR DISTRIBUTION!!!T←range;
;!!NO ERROR DISTRIBUTION!!!L←error+T;
;!!NO ERROR DISTRIBUTION!!!error←L;

;now, compute cascading error
;distribution is : Down 25%, Diag 25%, Right 25%
;!!NO ERROR DISTRIBUTION!!!SPH24:
SH<0;put sign bit in low order of T for MAGIC
;!!NO ERROR DISTRIBUTION!!!T←0,:pos;!pos,neg
;!!NO ERROR DISTRIBUTION!!!neg: T←ONE;
;!!NO ERROR DISTRIBUTION!!!pos:
error←L MRSH 1;error=error/2 (error is signed number)
;!!NO ERROR DISTRIBUTION!!!
L←error,TASK;
;!!NO ERROR DISTRIBUTION!!!
error1←L MRSH 1;**error1=error/2 (error is signed number)

;errorBuff!BDIM=cascadeDiag+error1
//prev diag error + new down error
;!!NO ERROR DISTRIBUTION!!!
T←BDIM;
;!!NO ERROR DISTRIBUTION!!!
MAR←errorBuff+T;
;!!NO ERROR DISTRIBUTION!!!
T←error1;
;!!NO ERROR DISTRIBUTION!!!
L←cascadeDiag+T,TASK;
;!!NO ERROR DISTRIBUTION!!!
MD←LREG;**

;cascadeDiag=error1
;!!NO ERROR DISTRIBUTION!!!
L←error1,TASK;
;!!NO ERROR DISTRIBUTION!!!
cascadeDiag←L;**

SPH24: T←177760,:SPHxxx;
;!!NO ERROR DISTRIBUTION111
SPH23: BBIT←L;
;!!NO ERROR DISTRIBUTION111
T←177760;
SPHxxx:
L←BBIT AND T;
L←BDIM+1, SH=0;
BDIM←L, SH=0, :SPH26;!SPH26,SPH28

;Bbit has run below 0 or above 17, so must store a word.
SPH26:
MAR←Badr0, :SPH27;!SPH27,SPH41 -- to SPH41 if Bdim=0
SPH27:
L←BBITINIT;
BBIT←L;
T←WORDOUT;
L←MD OR T,TASK;
WORDOUT←L;**

T←BINCR;
MAR←Badr0;
L←Badr0+T;
Badr0←L, T←0;Badr0 R register => T←0
MD←WORDOUT, L←T, TASK;

WORDOUT←L;**

SPH28:
T←20000, :SPH29;!SPH29,SPH40 -- to SPH40 if Bdim=0
SPH29:
L←BSTATUS AND T;
T←BDELTA, SH=0;
L←BCOUNT-T, :SPH30;!SPH30,SPH3a -- if no magnify, goto getabit
SPH30:
BCOUNT←L, SH<0;
T←DOTSDELTACOnST, :SPH20a; !SPH20a,SPH31 -- if overflow,
SPH31:
L←BCOUNT+T, TASK;Add the constant
BCOUNT←L, :SPH3;**

; Finish out by storing the last word. Do not bother to update
; any variables in v as they dont matter

SPH40:
MAR←Badr0;
SPH41:
T←WORDOUT;
L←MD OR T;
MAR←Badr0;
T←0;
MD←LREG, L←T, :BCPLRETL;Return 0


;Mask table here to make above more readable.

SPHOrM0:
L←100000 OR T, TASK, :SPH22;
SPHOrM1:
L←40000 OR T, TASK, :SPH22;
SPHOrM2:
L←20000 OR T, TASK, :SPH22;
SPHOrM3:
L←10000 OR T, TASK, :SPH22;
SPHOrM4:
L←4000 OR T, TASK, :SPH22;
SPHOrM5:
L←2000 OR T, TASK, :SPH22;
SPHOrM6:
L←1000 OR T, TASK, :SPH22;
SPHOrM7:
L←400 OR T, TASK, :SPH22;
SPHOrM10:
L←200 OR T, TASK, :SPH22;
SPHOrM11:
L←100 OR T, TASK, :SPH22;
SPHOrM12:
L←40 OR T, TASK, :SPH22;
SPHOrM13:
L←20 OR T, TASK, :SPH22;
SPHOrM14:
L←10 OR T, TASK, :SPH22;
SPHOrM15:
L←4 OR T, TASK, :SPH22;
SPHOrM16:
L←2 OR T, TASK, :SPH22;
SPHOrM17:
L←ONE OR T, TASK, :SPH22;

SPHMask0:
L←ONE, TASK, :SPH2;
SPHMask1:
L←3 , TASK, :SPH2;
SPHMask2:
L←7 , TASK, :SPH2;
SPHMask3:
L←17 , TASK, :SPH2;
SPHMask4:
L←37 , TASK, :SPH2;
SPHMask5:
L←77 , TASK, :SPH2;
SPHMask6:
L←177 , TASK, :SPH2;
SPHMask7:
L←377 , TASK, :SPH2;
SPHMask10:
L← 777 , TASK, :SPH2;
SPHMask11:
L← 1777 , TASK, :SPH2;
SPHMask12:
L← 3777 , TASK, :SPH2;
SPHMask13:
L← 7777 , TASK, :SPH2;
SPHMask14:
L← 17777 , TASK, :SPH2;
SPHMask15:
L← 37777 , TASK, :SPH2;
SPHMask16:
L← 77777 , TASK, :SPH2;
SPHMask17:
L←177777 , TASK, :SPH2;

;Cycle right.
; Enter at CYCLE with:
;
INBIT = count of places to cycle
;
T = bits
; Exit to SPH7 with
;
nextW= cycled bits
; Note: nextW must be R register for shifts

hCYCLE:
SINK← INBIT, BUS;
L← T, TASK, :hCYCR0;

hCYCR0:
nextW← L, :SPH7;

hCYCR4:
nextW←L MRSH 1;
hCYCY3:
T←L←nextW, TASK;
hCYCR3:
nextW←L MRSH 1;
hCYCY2:
T←L←nextW, TASK;
hCYCR2:
nextW←L MRSH 1;
hCYCY1:
T←L←nextW; TASK;
hCYCR1:
nextW←L MRSH 1, :SPH7;

hCYCL4:
nextW←L MLSH 1;
hCYCZ3:
T←L←nextW, TASK;
hCYCL3:
nextW←L MLSH 1;
hCYCZ2:
T←L←nextW, TASK;
hCYCL2:
nextW←L MLSH 1;
hCYCZ1:
T←L←nextW, TASK;
hCYCL1:
nextW←L MLSH 1, :SPH7;

hCYCL8:
nextW← L LCY 8, :SPH7;
hCYCL7:
nextW← L LCY 8, :hCYCY1;
hCYCL6:
nextW← L LCY 8, :hCYCY2;
hCYCL5:
nextW← L LCY 8, :hCYCY3;
hCYCR7:
nextW← L LCY 8, :hCYCZ1;
hCYCR6:
nextW← L LCY 8, :hCYCZ2;
hCYCR5:
nextW← L LCY 8, :hCYCZ3;
;----------------------------------------------------------------------
; DoubleAdd (returns integer part)
;----------------------------------------------------------------------
!1,2,DPADNoCarry,DPADCarry;
TRP3: MAR←AC0;
destination AC
NOP;
L←MD;

MAR←AC0+1;
sample←L;high order of first term
L←MD;

MAR←AC1;
TEMP←L;low order of first term
L←MD;

MAR←AC1+1;
AC1←L;high order of second term
L←MD;

MAR←AC0+1;
T←TEMP;
L←LREG+T;LREG has low order of second term
MD←LREG;

T←sample,ALUCY;
MAR←AC0,:DPADNoCarry;
DPADCarry:
L←AC1+T+1,:DPADStore;
DPADNoCarry:
L←AC1+T,:DPADStore;
DPADStore:
MD←LREG,:BCPLRETL;

;----------------------------------------------------------------------
; DoubleSub
;----------------------------------------------------------------------
!1,2,DPSBNoCarry,DPSBCarry;
TRP4: MAR←AC0;
destination AC
NOP;
L←MD;

MAR←AC0+1;
sample←L;sample has high order word 1
L←MD;

MAR←AC1;
TEMP←L;TEMP has low order word 1
T←ALLONES;
L←MD XOR T;store complement of AC1

MAR←AC1+1;
AC1←L;AC1 has (NOT high order word 1)
L←MD;

MAR←AC0+1;
T←LREG;
L←TEMP-T;
MD←LREG;store low order=lowOrder1-lowOrder2

T←sample,ALUCY;
MAR←AC0,:DPSBNoCarry;
DPSBCarry:
L←AC1+T+1,:DPSBStore;
DPSBNoCarry:
L←AC1+T,:DPSBStore;
DPSBStore: MD←LREG,:BCPLRETL;

;----------------------------------------------------------------------
; DoubleShr
;----------------------------------------------------------------------
!1,2,DSHRpos,DSHRneg;
TRP5: MAR←AC0;
NOP;
L←MD;

MAR←AC0+1,SH<0;
AC1←L,T←0,:DSHRpos;!1,2,DSHRpos,DSHRneg;
DSHRneg: T←ALLONES;
DSHRpos: TEMP←L MRSH 1;
L←MD;

MAR←AC0;
T←AC1;unshifted high order (for carry)
AC1←L MRSH 1;
MD←TEMP;shifted high order

MAR←AC0+1;
L←TEMP;return integer part
MD←AC1,:BCPLRETL;

;

;Read(adr) returns contents of bank1 adr
TRP6:
XMAR←AC0;
NOP;
L←MD,:BCPLRETL;

;Write(adr,val) writes val into bank1 adr
TRP7:
XMAR←AC0;
NOP;
MD←AC1,:BCPLRET;

;BLT from bank1 to bank1 MoveBlock(dest1,src1,nwords)
!1,2,more10,done10;
TRP10:
T←3;
MAR←AC2+T;
NOP;
L←MD;
loop10:
range←L,SH=0;
XMAR←AC1,:more10;!1,2,more10,done10;
more10:
L←AC1+1;
AC1←L;
L←MD;
TEMP←L;
XMAR←AC0;
L←AC0+1;
AC0←L,TASK;
MD←TEMP;
L←range-1,:loop10;
done10: NOP,:BCPLRET;


;BLT from bank0 to bank1 MoveBlock(dest1,src0,nwords)
!1,2,more11,done11;
TRP11:
T←3;
MAR←AC2+T;
NOP;
L←MD;
loop11:
range←L,SH=0;
MAR←AC1,:more11;!1,2,more11,done11;
more11:
L←AC1+1;
AC1←L;
L←MD;
TEMP←L;
XMAR←AC0;
L←AC0+1;
AC0←L,TASK;
MD←TEMP;
L←range-1,:loop11;
done11: NOP,:BCPLRET;

;
;********************************************************************
$FOO
$R41

;TestExit -- store various values in low core, and exit
;TESTEXIT: MAR←20000;
;
NOP, TASK;
;
MD← LREG;
;
MAR←L←20000+1;
;
FOO←L,TASK;
;
MD← ShiftCnt;
;
MAR←L←FOO+1;
;
FOO←L,TASK;
;
MD← MASK;
;
MAR←L←FOO+1;
;
FOO←L,TASK;
;
MD← nS;
;
MAR←L←FOO+1;
;
FOO←L,TASK;
;
MD← Fw;
;
MAR←L←FOO+1;
;
FOO←L,TASK;
;
MD← Fadr;
;
MAR←L←FOO+1;
;
FOO←L,TASK;
;
MD← Badr;
;
MAR←L←FOO+1;
;
FOO←L,TASK;
;
MD← FCNT;
;
MAR←L←FOO+1;
;
FOO←L,TASK;
;
MD← WLEFT;
;
MAR←L←FOO+1;
;
FOO←L,TASK;
;
MD← W1;
;
MAR←L←FOO+1;
;
FOO←L,TASK;
;
MD← W2;
;
MAR←L←FOO+1;
;
FOO←L,TASK;
;
MD← nextW;
;
MAR←L←FOO+1;
;
FOO←L,TASK;
;
MD← Badr0;
;
MAR←L←FOO+1;
;
FOO←L,TASK;
;
MD← BCOUNT;
;
MAR←L←FOO+1;
;
FOO←L,TASK;
;
MD← WORDIN;
;
MAR←L←FOO+1;
;
FOO←L,TASK;
;
MD← PC;
;
:BCPLRET;
;