:TITLE[GlobalDefs];*Last edited: 1 June 1981 by Fiala

*ASSEMBLY SWITCHES

Set[CSLOverlay,1];
*1 assembles DisplayInit to read the CSLKeyboard
*overlay if the attached keyboard is a CSL keyboard.
*DisplayInitPage has an extra 27b mi in this case.
Set[FinalOverlay,1];
*1 assembles Initialize.Mc to read in a final
*overlay before transferring control to StartNova.
Set[NoOverlays,IFE[Or[CSLOverlay,FinalOverlay],0,1,0]];
*NOTE: if NoOverlays is 0, map and storage init code in Initialize
*on pg. 16b is replaced by code which delays before and after the
*display of some MP codes; this results in 100b fewer mi on page 16b.
Set[WithMidas,0];
*1 assembles extra code for debugging with Midas:
* 5b mi in Fault on page 0
* 31b mi in Fault on MidasPage
* 4b mi in Timer on TimerPage
*NOTE: Include KernelOccupied.Dib for MicroD if
*WithMidas=1 else don’t bother.
Set[AltoMode,1];
*Default Mesa assemblies to Alto mode.
*(Pilot mode = 0, but no longer supported)
Set[CacheLocals,1];
*Indicate cache for Mesa locals 0 to 3
*(performance improvement affecting MesaLS and MesaX;
*presently, this MUST be 1 for AltoMode=1)
Set[SmallTalkMode,0];
*1 for SmallTalk instead of Mesa.
Set[LispMode,0];
*1 for Lisp instead of Mesa.
Set[ButteMode,0];
*1 for Butte instead of Mesa.
Set[AltoXMMode,Or[SmallTalkMode,ButteMode]];

MC[cEtherBoot,10];
*Etherboot control constant--10 for Net Exec,
*100 for Mesa Net Exec
MC[MaxStack,10];
*Largest referenceable stack address (when StkP
*points at MaxStack+1 to 17, trap occurs).
MC[MinPageCount,1000];
*Minimum number of pages at which to allow Initialize
*to continue with system initialization (if less than
*this, shows error code on MP if WithMidas=1).

%The following integers control assembly of speed improvements in the Alto
emulator that consume microstore for additional speed. Values should be
1 to assemble faster version, 0 to use slower but smaller version.
%
Set[neFastBltBlks,1];
*1 expends 53b mi to assemble faster versions of
*BLT and BLKS for a 4% to 9% speed improvement.
Set[neFastAGroup,1];
*1 expends 41b mi to assemble faster A-group
*for a 5% to 10% speed improvement.
Set[neBCPLI360,1];
*1 assembles BCPL runtime for JSR @360 to 370
*Expends 122b mi for a 25% speed improvement.
*Most storage is on nePage and cannot easily be moved.
Set[neBCPLI340,1];
*1 assembles BCPL runtime for JSR @340 to 357
*Expends 66b mi for a 3% to 8% speed improvement.
*Requires neBCPLI360 to be 1.
Set[neBCPL300,0];
*1 assembles BCPL runtime for JSR 300 to 332
*Expends 47b mi for a 0% to 2% speed improvement.
*Requires neBCPLI360 to be 1.
Set[neAltoTraps,0];
*1 assembles 30b mi on nePage that cause a breakpoint
*for illegal opcodes in the range 62000 - 67777.
Set[xoTraps,1];
*1 assembles 14b mi on xoPage for illegal opcodes
*in the range 61000b to 61037b.


IMReserve[17,377,1];
*Reserve location 7777b, which LoadRAM can’t handle.

*TASK DEFINITIONS
Set[BootTask,1];
*Task whose T-register used for booting
IFG[BootTask,3,ER[Initialize.requires.BootTask.be.0.to.3]];
Set[cdcTask,5];
*Color Display
Set[eoTask,6];
*Ethernet Output
Set[eiTask,Add[eoTask,1]];
*Ethernet Input
IFE[And[eoTask,14],And[eiTask,14],,ER[eoTask.and.eiTask.inconsistent]];
Set[rdcTask,10];
*Disk
Set[DpTask,12];
*Display
Set[TTask,16];
*Timer--wired-in, don’t change this one

*Other switch initialization--DON’T CHANGE THIS (init only)
Set[LFKeyBoard,0];
*Default left alone for CSL keyboard assembly,
*overruled for LF keyboard assembly


%PAGE AND PLACEMENT DEFINITIONS

Two debugging systems can be built from the sources: one to drive the LF
keyboard and one for the CSL keyboard (with either CSL or LF monitor);
a single system is built for boot loading from disk or ethernet that
automatically configures itself for the attached keyboard by loading the LF
keyboard driver with the normal microcode, but overwriting this with a CSL
keyboard driver from an overlay if appropriate. NOTE: the LF keyboard driver
is 74b mi larger than the CSL keyboard driver.

WithMidas, CSLOverlay, and FinalOverlay switches control assembly
configuration. WithMidas must be 1 to debug with Midas. For normal
debugging both overlay switches must be 0.

Pages 16 and 17 contain only initialization and Midas communication ucode,
and page 15 is sparsely populated with code that wouldn’t quite fit elsewhere.
For debugging, separate CSL and LF keyboard systems are built with
KernelOccupied and without Mesa floating point or jasmine scanner ucode.

For system releases, an LF keyboard system is assembled in which extra code
for the LF keyboard and other overflow are on page 15. The Initial program
leaves the resident and all overlays in storage starting at VM 1400. It
initializes map and storage and exits via LoadRAM, which loads the first
resident overlay into the microstore and transfers control into Initialize.Mc
at EGO or KGO. During DisplayInit, if the connected terminal has a CSL
keyboard, then the first overlay will be rolled in by LoadRAM; otherwise,
the first overlay will be passed over.

Just before jumping to StartNova, a final overlay overwrites pp 16 and 17;
this consists of the Jasmine, JasmineHalftone, and MesaFP modules.
The jasmine and halftone microcode is a natural overlay because
(a) it almost fills one page, which is an easy unit of management;
(b) nothing in the resident calls it (it is invoked by Mesa JRAM); and
(c) it uses the Printer interface, so it could not be debugged from Midas in
any case. MesaFP is also a convenient overlay because it is easy to trap all
FP opcodes to software when no microcode is present.

It would also be possible to make part of page 15 available to overlays.
One way to do this would be to determine the size of the resident stuff on
page 15 and IMReserve the balance of the page in the resident. Then
assemble the overlay with an IMReserve for the occupied part of page 15.
%
Set[InitPage,16];
*?b mi if NoOverlays=1 else 235b mi

Loca[InitBase,InitPage,200];
*InitBase to InitBase+6 are used
**Constants unused here--possibly needed by Lisp
MC[InitLocH,And[InitBase,7400]];
MC[InitLocL,And[InitBase,377]];
MC[K2InitLocL,InitLocL,0];
*7200 not presently in any .MLF files
MC[KInitLocL,InitLocL,3];
*7203 known to MakeLoaderFile .MLF files
MC[EInitLocL,InitLocL,4];
*7204 known to MakeLoaderFile .MLF files
Loca[DTabBase,16,240];
* 11b mi in Initialize.Mc (allow for growth)

Loca[DiskInitLoc,17,203];
* 32b mi
**NOTE: DisplayInitLoc value known to MakeLoaderFile .Mlf files
*DisplayInitLoc must be odd; DisplayInitLoc to DisplayInitLoc+6 are used
Loca[DisplayInitLoc,17,207];
*131b mi if CSLOverlay = 1, else 102b mi
Loca[EtherInitLoc,17,221];
* 24b mi
Loca[TimerInitLoc,17,223];
* 15b mi

Set[MidasPage,IFE[CSLOverlay,1,16,17]];
*31b mi in Fault.Mc if WithMidas=1

Set[DisplayPage,2];
*Display microcode--**whole page reserved for display
Loca[FldDoneLoc,DisplayPage,1];
*Must be odd
Loca[BootSV,DisplayPage,362];
*2b mi in Display.Mc if LFKeyBoard=0

Loca[KeyTable,15,0];
*40b mi keyboard translation table if LFKeyBoard=1
Set[lfKBPage,15];
*34b mi for LF keyboard posting code if LFKeyBoard=1
Set[DisplayPage2,15];
* 3b mi (SmallTalk only)
Set[DisplayPage3,15];
* 1b mi (SmallTalk only)
Set[bbXMPage,15];
*11b mi (not pages 4 to 7) (SmallTalk only)

Set[eePage,3];
*15b mi Ethernet StartIO microcode (task 0)
Loca[eeLocA,eePage,110];
*Overwritten location
Loca[eeLocB,eePage,111];
*Target of overwritten mi (JA must have
*odd parity)

*These four must be on the same page
Loca[eoStartLoc,3,120];*Output notify
Loca[eoTimerDoneLoc,3,130];*Output TimerDone notify
Loca[eiStartLoc,3,140];*Input notify
Loca[eiAbortLoc,3,150];*SIO abort notify

Set[TimerPage,3];
*45b mi (not pages 4 to 7); task 16 timers
Loca[TimerTable,TimerPage,0];
*0 to 25b used in this table

Set[rdcPage,14];
*Disk microcode

Set[DoIntPage,15];
*13b mi
Loca[DoIntLoc,DoIntPage,364];

*61b mi Color display controller
Loca[cdcInitLoc,15,222];
*(Mesa JRAM 56622 turns on)
Loca[cdcOffLoc,15,223];
*(Mesa JRAM 56623 turns off)

*For the final overlay
Set[JasPage,17];
*170b mi (not on 4 to 7) for Jasmine scanner
Loca[JasmineOn,JasPage,10];
Loca[JasmineOff,JasPage,11];
Loca[JasminePulse,JasPage,12];
Set[HalftonePage,17];
*124b mi (not on 4 to 7) for Jasmine halftone ucode
Loca[PrintLine,HalftonePage,0];

*Page 0 allocation is extremely tricky because some fault handling code
*overwrites equivalent code in Kernel. These are absolutely located
*to efficiently utilize mi that would otherwise have to be IMReserved.
*Old LoadRAM uses 300-337, 370-371 (new LoadRAM uses 300-331);
*Fault uses 0-1 (emulator buffer refill trap and fault entry),
* 100-112 and 120 (fault dispatching overwriting Kernel),
* 200, 202, 204 for notifies (could be moved);
* 340-357 (FixDisp in Fault.Mc).
Loca[MesaRefillLoc,0,2];
*Location of MesaRefill subroutine in MesaJ.Mc
*(for overlays with buffer refill code)
Loca[FixDisp,0,340];
*Not pages 4 to 7
Set[PNIPPage,0];
*12b mi (must be 0 because of branch to PFExit)
Set[LRJPage,0];
**Don’t change without coordinating all emulators
Loca[LRJStart,LRJpage,300];
Loca[LRJContinue,LRJpage,301];
*Old LoadRAM
* Set[LRJContinue,Add[LRJStart,0]];
* Set[ExchStkPLoc,Add[LRJStart,30]];
* Set[SetStkPLoc,Add[LRJStart,31]];

Set[QLoc,230];
*02b mi in Initialize for BadWakeup crash code
Set[RS232Page,1];
*07b mi in MesaX


*Mesa Emultor:
Set[opPage0,4];
*These cannot move since hardware forces the first mi
Set[opPage1,5];
*of each bytecode to start at 2001 + (4 * opcode)
Set[opPage2,6];
Set[opPage3,7];
Loca[KFCRLoc,opPage3,76];
Loca[P7TailLoc,opPage3,27];
**Don’t move--used by LRJ

Set[xfPage1,10];
Loca[xfPage1p,xfPage1,0];
Loca[xfType,xfPage1,140];
Loca[MiscDisp0,xfPage1,160];
Loca[MiscDisp1,xfPage1,200];
Loca[LoadGCLoc,xfPage1,220];

Set[prPage,11];
Set[XMiscPage,4];
*22b mi in Misc.Mc (also used by Alto emulator)
Set[CSPage,3];
*25b mi for CSum Misc opcode (not on pages 4 to 7)
Set[MStartPage,7];
*14b mi for MStart
Set[BLTPage,10];
*50b mi for various BLT opcodes in MesaX
Set[CBLPage,5];
*02b mi for subr used by WCBL and ICBL opcodes


Set[bbPage,12];
*BitBlt (used by both Alto and Mesa emulators)
Loca[bbIE,bbPage,200];
Loca[bbIF,bbPage,220];
Loca[bbI,bbPage,240];


*Alto/Nova emulator
Set[nePage,1];
Loca[neBase,nePage,0];
Loca[JmpFinLoc,nePage,3];
**Don’t move--reentry location for Alto LRJ
Loca[OpTab,nePage,20];
*Dispatch tables
Loca[IO0Tab,nePage,40];
Loca[IO1Tab,nePage,60];

*Pieces of the Alto emulator that can be placed on any page
Set[neStartPage,4];
*07b mi
Loca[neStartLoc,neStartPage,3]; **2003 known to MakeLoaderFile .MLF files
Set[neStartPage1,4];
*03b mi
Set[neStartPage2,4];
*06b mi
Set[neFixBPage,5];
*06b mi
Set[ConvertPage1,4];
*17b mi
Set[ConvertPage2,0];
*27b mi
Set[ConvertPage3,13];
*03b mi
Set[neBlksPage0,10];
*06b mi if neFastBltBlks=1
Set[neIntPage1,13];
*15b mi (not on pages 4 to 7)
Set[neMulPage,1];
*14b mi
Set[neDivPage,6];
*21b mi
Set[brGarbPage0,6];
*02b mi if neBCPLI360=1
Set[brGarbPage1,13];
*22b mi if neBCPLI360=1 (not on pages 4 to 7)
*(must be on page which has 377=copy of neRefill)
Set[brGarbPage2,0];
*06b mi if neBCPLI360=1
Set[neLRJPage,15];
*06b mi
Set[neCSPage,11];
*24b mi (not on pages 4 to 7)

Set[neIntPage0,3];
*61b mi if neFastBltBlks=1 (not on pages 4 to 7)
* else 15b mi (pages 4 to 7 ok)

Set[aoPage,13];
*Alto A-group (not on pages 4 to 7); 140b mi if
*neFastAGroup=1 else 77b
Set[xoPage,13];
*Alto extended ops
Loca[xoBase,xoPage,0];
Loca[xoTab0,xoPage,260];
Loca[xoTab1,xoPage,300];
:IF[neBCPLI340];
Set[br340Page,13];
*63b mi; must = xoPage (uses xoWRTRAM)
:ENDIF;

:IF[neBCPL300];
Set[brJsrPage,13];
*42b mi; can be moved without complications
:ENDIF;

IFE[And[CSPage,14],4,ER[CSPage.illegal.page.4.to.7]];
IFE[And[neIntPage1,14],4,ER[neIntPage1.illegal.page.4.to.7]];
IFE[And[neCSPage,14],4,ER[neCSPage.illegal.page.4.to.7]];
IFE[And[brGarbPage1,14],4,ER[brGarbPage1.illegal.page.4.to.7]];
IFE[neFastBltBlks,1,
IFE[And[neIntPage0,14],4,ER[neIntPage0.illegal.page.4.to.7]]];
IFE[And[aoPage,14],4,ER[aoPage.illegal.page.4.to.7]];
IFE[And[xoPage,14],4,ER[xoPage.illegal.page.4.to.7]];

*Registers for timer task
SetTask[TTask];
RV[RTCLOW,25];
*low half of Alto RealTime clock
*RM 326 is loaded with PageCount by RegInit1 in Initialize.Mc
RV[RConstant,27];
*Addend for RTCLOW
RV2[TimerBase,TimerBasehi,40];
*Base register containing 400b
RV[RSImage,42];
*The RS232 Image Register
RV[TimerTemp,43];
*Temporary
RV[RTIMER,57];
*constant for memory refresh timer
RV[REFR,77];
*refresh Address


*Kernel/Initial/Fault registers
SetTask[17];
RV[RXALU,76];
*ALU result and SALUF
RV[RXAPC,75];
*APCTask&APC
RV[RXCTASK,74];
*CTASK.NCIA
RV[RXPPB,73];
*Page,Parity,BootReason
RV[RXSTK,72];
*Stackpointer
RV[RTMP,71];
*temporary
*RV[RWSTAT,70];
*RV[RDATA,67];
RV[FFault,66];
*Flags tell what to do with fault
*Also used by LoadRam.
*RV[RADDR,65];
*RV[RCNT,64];
*RV[RW0,63];
*RV[RW1,62];


SetTask[0];

*Task 0 registers used during initialization only
RV[xCNT,35];

%Register definitions for Alto and Mesa emulators

For Mesa, RM 21, 44-53, 56-57, 66-73 are temps; RM 17, 25, and 64 are somewhat
temps (see comment later); RM 0 and 20 are unused; all other RM locations
have uses that must survive across opcodes.
**Maybe free RM 21 (CurrentTime) in MesaP.
%
*Mesa Stack cannot move because of hardware overflow/underflow checking.
RV[Stack0,1]; RV2[Stack1,Stack2,2]; RV4[Stack3,Stack4,Stack5,Stack6,4];
RV4[Stack7,Stack8,Stack9,Stack10,10]; RV2[Stack11,Stack12,14]; RV[Stack13,16];

RV2[CODE,CODEhi,22];

RV[NWW,24];
*Both Alto and Mesa

RV2[LOCAL,LOCALhi,26];

RV2[PCB,PCBhi,30];
*Alto and Mesa

RV2[MDS,MDShi,32];
*Alto and Mesa
RM[RMZero,IP[MDS]];
*Contains 0 for both Mesa and Alto
RM[RZero,IP[MDS]];
*Contains 0 for both Mesa and Alto

RV4[IBuf,IBuf1,IBuf2,IBuf3,34];
*4 word bytecode buffer for both Alto & Mesa

RV4[wBuf,wBuf1,wBuf2,wBuf3,40];
*wBuf temporary buffer
*(wBuf3 must be at xBuf-1 for Alto BLT)
RV4[xBuf,xBuf1,xBuf2,xBuf3,44];
*Temporary buffer (used by old LRJ--cannot move)
*Also used as temporaries by Fault.Mc
RV4[yBuf,yBuf1,yBuf2,yBuf3,50];
*Temporary buffer (used by new LRJ--don’t move)
*(yBuf must be at xBuf3+1 for Alto BLT)

:IF[CacheLocals];
*Cache Local0 to Local3 for Mesa
RV4[LocalCache0,LocalCache1,LocalCache2,LocalCache3,IP[wBuf]];
:ENDIF;

RV4[GLOBAL,GLOBALhi,xfMY,xfMX,54];
*For Mesa

*Constants
RV[R400,60];
*400 for both Alto and Mesa
RV[AllOnes,61];
*-1 for both Alto and Mesa (Only BitBlt uses AllOnes
*for Alto, so could eliminate)

RV[MemStat,62];
*Directs page fault handling by Fault.Mc

RV[xfWDC,63];
*Wakeup disable counter

RV2[LP,LPhi,66];
*Long pointer base pair. (used by LRJ--cannot move)

RV4[zBuf,zBuf1,zBuf2,zBuf3,70];
*Quadword used by MesaFP
*(Don’t move unless xfTemp def changed--see below)

*RTemp and RTemp1 are used by PNIP, which might be called by any task,
*so these registers must not overlay any Kernel registers (x62-x77). PNIP
*is most commonly called by task 17, so no conflicts on task 14-17 assignments
*is most important.
RV[RTemp,IP[yBuf2]];
*Both Alto and Mesa
RV[RTemp1,IP[yBuf3]];
*Both Alto and Mesa (used by LRJ--cannot move)

%These 1st 3 registers may be read by a MISC opcode. They are used to pass
values through xfer to trap procedures, so the sequence is load-the-register,
do-an-xfer, disable-interrupts, and then simple code sequence to read the
register and save its value. For this reason, these registers are reused in
the process code (because interrupts are off) and in BitBlt and the floating
point opcodes (because BitBlt is not in the trap sequence), but they may not
be used in opcodes which might appear in the trap procedure.
%
RV[xfXTPreg,25];
*Xfer trap parameter
RV[xfATPreg,64];
*Alloc trap parameter
RV[xfOTPreg,17];
*Other trap parameter

*These hold permanent state
RV[xfGFIWord,65];
*Holds word 0 of global frame
RV[xfBrkByte,74];
*(?) Can be used as temporary if left 0 when done
*75 used as ’Sticky’ by MesaFP.Mc
RV[TickCount,76];*For process timeout (Valid for Mesa only)
RV[xfXTSreg,77];

RV[RLink,IP[zBuf1]];
*Used in MesaP and ?
RV2[xfTemp,xfTemp1,IP[zBuf2]];
*(used by LRJ--cannot move)

RV2[LPdest,LPdesthi,IP[xfMY]];
*Long BLT

*Process registers (also use RLink, RTemp, RTemp1, xfTemp, WW, and ?)
*Is zBuf available here?
RV2[PBase,PBasehi,IP[MDS]];
*PSB base reg = MDS, NOT initialized anywhere
*(must change in the Post IME world)
RV[CurrentTime,21];
*Is this a temporary?
RV2[Queue1,Queue1hi,IP[xBuf]];
RV2[Queue2,Queue2hi,IP[xBuf2]];
RV[PRTime,IP[zBuf2]];
RV[Process,IP[zBuf3]];
RV[MQ,IP[LP]];
RV2[QTemp,QTemphi,IP[yBuf]];
RV[Prev,IP[xfXTPreg]];
RV[PRFlags,IP[xfATPreg]];
RV[EMLink,16];
*Only used by ExitMon
RV[IntType,IP[LPhi]];
RV[IntLevel,IP[xfMX]];
RV[ITemp,IP[yBuf]];
RV[ITemp1,IP[yBuf1]];

*Temporaries for xfer (also xfTemp, xfTemp1, xfMY, xfMX, and ?)
*Are xBuf, xBuf1, xBuf2, xBuf3, yBuf, and yBuf1 available here?
RV[xfTemp2,IP[LP]];
RV[xfCount,IP[LP]];
RV[xfFSI,IP[LPhi]];
RV[xfRlink,IP[RLink]];
RV[xfFrame,IP[zBuf]];

%Alto emulator registers:

Each AC is a base register (ACnhi, PCBhi, and DMAhi are initialized by
FixNBases called from StartNova). The stack predecessor to each AC must be
smashable by the A-group opcodes (since the StkP counter is 4 bits,
predecessor to 60, for example, is 77--watch out). rpACn registers point at
the StkP predecessor to ACn (for PFetch1’s, which do a push) and rwpACn
points at ACn.

For Alto, RM 3, 6-7, 21, 25, 40-53, 56-57, 64, 66-67, and 72-73 are temps;
RM 0, 12-13, 20, 62-63 are unused; all other RM locations have values that
must survive across opcodes; RM 6, 40-42, 51, 66, 70-71 used only by BitBlt.
**Note: although RM 63 is unused by Alto (xfWDC for Mesa), it seems necessary
to preserve it for Mesa traps to the Alto emulator.

If more registers are needed, modify BitBlt to use some of the Alto emulator’s
constants and restore them before exit (R177400-R177402 are good choices since
these are Mesa temporaries); using these for BitBlt instead of any of the
registers named above as used only by BitBlt would free these registers for
the Alto emulator.
%
*R177400 to R177403 must be in a quadword since PCF[R177400] is used as
*the equivalent to PCF.word + 177400; similarly for SkipPCF0 to SkipPCF3.
RV4[R177400,R177401,R177402,R177403,14];
RV4[SkipPCF0,SkipPCF1,SkipPCF2,SkipPCF3,74];

RV[CARRY,1];
*Alto carry bit in bit 0

*Also, the values are chosen so that the low 3 bits of the four will enumerate
*0, 2, 4, and 6, which allows the rwpACx pointers to be coincident with the
*four SkipPCFx registers.
RV2[AC2,AC2hi,4];
*3 smashed by A-group opcodes (used by Mesa BitBlt)
RV2[AC0,AC0hi,10];
*7 smashed by A-group (used by Mesa BitBlt, StartIO)
RV2[AC1,AC1hi,26];
*25 smashed by A-group
RV2[AC3,AC3hi,22];
*21 smashed by A-group

RV[rpAC0,54];
*Pointer to AC0-1
RV[rpAC1,2];
RV[rpAC2,IP[R177403]];
RV[rpAC3,55];
RV[rwpAC0,IP[SkipPCF2]];
*Pointer to AC0 in bits 8:15
RV[rwpAC1,IP[SkipPCF1]];
RV[rwpAC2,IP[SkipPCF0]];
RV[rwpAC3,IP[SkipPCF3]];

RV[SMA,7];
*Temporary for CONVERT
RV[xnXH,56];
*Temporary for CONVERT
RV[XBI,57];
*Temporary for CONVERT

*WW, ACTIVE, and DMA must not coincide with any registers that must survive
*across interrupt checks for BLT or BLKS.
RV2[WW,ACTIVE,56];
*WW also used by Mesa

RV2[DMA,DMAhi,64];

Macro[StkPCheck,IFG[IP[#1],MaxStack!,
IFG[20,IP[#1],ER[#1.not.referenceable.by.StkP]]]];
StkPCheck[AC0]; StkPCheck[AC1]; StkPCheck[AC2]; StkPCheck[AC3];
*See the code at StartNova in Alto.Mc if any of these errors occurs
IFE[IP[AC2],4,,ER[rpAC2.and.rwpAC2.became.no.good]];
IFE[IP[AC0],10,,ER[rwpAC0.became.non-coincident.with SkipPCF2]];
IFE[IP[AC1],26,,ER[rwpAC1.became.non-coincident.with SkipPCF1]];
IFE[IP[AC3],22,,ER[rwpAC3.became.non-coincident.with SkipPCF3]];

%BitBlt registers--these must not conflict with any inter-opcode storage
used by either Alto or Mesa emulators. Uses AC0, AC2, and AC2hi, which
must not conflict with Mesa; must not smash Stack0-1 which are holding Mesa
arguments, but may smash Stack2 up; may smash AC3; restores IBuf-IBuf3 before
exit; LocalCache0-3 restored for Mesa exit.

RM 0, 12-13, 20, and, 62 are available; bbDty is available after init;
RM 22 is available for the Alto emulator but not for Mesa;
RM 11, 14-16 are available for the Mesa emulator but not for Alto.
%
RV[bbDest,IP[xBuf]];
*Quadword buffer

RV2[bbSlx,bbSty,IP[IBuf]];
RV[bbSLast,IP[IBuf1]];

RV2[bbDlx,bbDty,IP[IBuf2]];
*bbDty available after init

RV[bbSrc,IP[yBuf]];
*Quadword buffer
RV[bbYHi,IP[yBuf]];
*Init temporary

RV2[bbSrcQLo,bbSrcQHi,56];
RV2[bbDestQLo,bbDestQHi,IP[zBuf]];

RV[bbGray,IP[wBuf]];
*Quadword buffer
RV[bbGray1,IP[wBuf1]];
RV[bbGray2,IP[wBuf2]];

RV[bbDLast,6];
RV2[bbItemWid,bbItemsLeft,6];
*bbItemWid only needed during early init

*Registers which need not be paired
RV[bbNegBitsLeft,3];
RV[bbDBMR,21];
RV[bbFunction,25];
RV[bbNegItemWid,64];
RV[bbSrcWLo,66];
RV[bbSBMR,67];
RV[bbNegSDNonOverlap,IP[zBuf2]];
RV[bbDestWLo,IP[zBuf3]];



*Constants

MC[IntPendingBit,10];

:END[GlobalDefs];