:TITLE[GlobalDefs];*Last edited: 29 April 1980 by Fiala

*ASSEMBLY SWITCHES

IDF[MidasBoot, ,Set[MidasBoot,0]];
Set[AltoMode,0];
*Default Mesa assemblies to Pilot mode.
*Produce Alto mode by assembling AltoMode.Mc
*ahead of Mesa microcode sources.

%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 (also improves
*worst case time between Return from 44 to 41 cycles).
Set[neBCPLI360,1];
*1 assembles BCPL runtime for JSR @360 to 370
*Expends 122b mi for a 25% speed improvement.
*Almost all the storage is on nePage and cannot
*easily be moved elsewhere.
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.

*TASK DEFINITIONS
Set[cdcTask,5];
*Color Display
Set[EOtask,6];
*Ethernet Output
Set[EItask,7];
*Ethernet Input
Set[Ktask,10];
*Disk
Set[DpTask,12];
*Display
Set[TTask,16];
*Timer
*Set[RFTask,4];
*RS232 frame task
*Set[RBTask,5];
*RS232 bit task

*PAGE AND PLACEMENT DEFINITIONS
Set[InitPage,16]; *most of Initialize

*NOTE--all device-specific initialization is crammed onto the same page;
*This is throwaway code.
Set[DiskInitPage,17];
Set[DiskInitLoc,Add[LShift[DiskInitPage,10],203]];
Set[DisplayInitPage,17];
Set[DisplayInitLoc,Add[LShift[DisplayInitPage,10],207]];
Set[EtherInitPage,17];
Set[EtherInitLoc,Add[LShift[EtherInitPage,10],211]];
Set[TimerInitPage,17];
Set[TimerInitLoc,Add[LShift[TimerInitPage,10],213]];

Set[EEPage,3];
*Ethernet microcode
Set[EEBase,LShift[EEPage,10]];
Set[EESIOLoc,
Add[EEBase,20]];*Dispatch location for SIO
Set[EOPage,3];
Set[EOStartLoc,Add[LShift[EOPage,10],120]];*Output notify
Set[EOTimerDoneLoc,Add[LShift[EOPage,10],130]]; *Output TimerDone notify
Set[EIPage,3];
Set[EIStartLoc,Add[LShift[EIPage,10],140]];*Input notify
Set[EIAbortLoc,
Add[LShift[EIPage,10],150]];*SIO abort notify

Set[DisplayPage,2];
*Display microcode

Set[ColorDisplayPage,15];
*Color display
Set[cdcInitLoc,Add[LShift[ColorDisplayPage,10],123]];

Set[KPage,14];
*Disk microcde
Set[KPage2,15];
*More disk microcode

Set[TimerPage,0];
*task 16 timers
Set[TimerTable,Add[LShift[TimerPage,10],340]];
*40-long table

*LoadRam.Mc uses 300-337, 370-371

*Fault.Mc uses several dispatches and other page 0 locations:
*0 emulator buffer refill trap mi
*1 fault entry
*100-112, 120, 200, 202, 204, 377
Set[H4Disp,240];
Set[Mc2ErDisp,260];
Set[FaultPage1,15];

Set[FixDisp,Add[LShift[FaultPage1,10],100]];

*Initialize locations possibly needed elsewhere (e.g., Lisp)
Set[InitBase,Add[lshift[InitPage,10],200]];
Set[HardStart,Add[InitBase,1]];
Set[SoftStart,Add[InitBase,2]];
Set[DiskStart,Add[InitBase,3]];
Set[EtherStart,Add[InitBase,4]];
MC[InitLocL,And[InitBase,377]];
MC[KInitLocL,Add[And[InitBase,377],3]];
MC[EInitLocL,Add[And[InitBase,377],4]];
MC[InitLocH,And[InitBase,7400]];


*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];
Set[KFCRLoc,Add[LShift[oppage3,10],76]];
Set[P7TailLoc,Add[LShift[oppage3,10],27]];
Set[xfPage1,10];
Set[LoadGCLoc,Add[LShift[xfPage1,10],300]];
Set[prPage, 11];
Set[MulDivPage,4];
*multiply/divide
Set[XMiscPage,3];
*IME Opcodes

Set[LRJPage,0];
Set[LRJStart, Add[LShift[LRJpage,10],300]];
Set[LRJContinue, Add[LRJStart,1]];
Set[PNIPBase,156];

Set[bbPage,12];
*BitBlt (used by both Alto and Mesa emulators)
Set[bbBase,LShift[bbPage,10]];
Set[bbIA,Add[bbBase,100]];
Set[bbIB,Add[bbBase,120]];
Set[bbIC,Add[bbBase,140]];
Set[bbID,Add[bbBase,160]];
Set[bbIE,Add[bbBase,200]];
Set[bbIF,Add[bbBase,220]];
Set[bbI,Add[bbBase,240]];
Set[bbF,Add[bbBase,260]];

*Alto/Nova emulator
Set[nePage,1];
Set[neBase,LShift[nePage,10]];
Set[JmpFinLoc,Add[neBase,3]];
*Reentry location for Alto LRJ
*Dispatch base Addresses
Set[OpTab,Add[neBase,20]];
Set[JmpJsrTab,Add[neBase,40]];
Set[IszDszTab,Add[neBase,60]];
Set[LdaStaTab,Add[neBase,100]];
Set[IO0Tab,Add[neBase,120]];
Set[IO1Tab,Add[neBase,140]];
Set[RegOpTab,Add[neBase,160]];
:IF[neBCPLI360];
Set[neBR360,Add[neBase,200]];
:ENDIF;

*Pieces of the Alto emulator that can be placed on any page
Set[neFixBPage,15];
*6b mi
Set[ConvertPage1,4];
*17b mi
Set[ConvertPage2,13];
*27b mi
Set[ConvertPage3,1];
*03b mi
Set[neBlksPage0,10];
*06b mi if neFastBltBlks=1
Set[neIntPage1,3];
*15b mi (cannot put on pages 4 to 7)
Set[neMulPage,13];
*14b mi
Set[neDivPage,4];
*22b mi
Set[brGarbPage0,10];
*06b mi if neBCPLI360=1
Set[brGarbPage2,1];
*02b mi if neBCPLI360=1
Set[neLRJPage,4];
*12b mi

Set[neIntPage0,15];
*61b mi if neFastBltBlks=1 else 14b mi
:IF[neFastBltBlks];
Set[neIntP0Base,LShift[neIntPage0,10]];
Set[BltFTab,Add[neIntP0Base,320]];
Set[BltTab,Add[neIntP0Base,340]];
Set[BlksTab,Add[neIntP0Base,360]];
:ENDIF;

Set[aoPage,13];
*Alto A-group (142b mi
*(add 1 mi at aoSkip if aoPage .ne. xoPage)
Set[aoBase,LShift[aoPage,10]];
Set[aoCY0,Add[aoBase,20]];
*Only used if neFastAGroup=0
Set[aoFunc,Add[aoBase,40]];
Set[aoSH0,Add[aoBase,60]];
Set[aoSH1,Add[aoBase,100]];
Set[aoXitT0,Add[aoBase,120]];
Set[aoXitT1,Add[aoBase,140]];
Set[xoPage,13];
*Alto extended ops
Set[xoBase,LShift[xoPage,10]];
Set[xoTab0,Add[xoBase,260]];
Set[xoTab1,Add[xoBase,300]];
:IF[neBCPLI340];
Set[br340Page,13];
*63b mi; must = aoPage = xoPage (uses WRTRAM, aoSkip)
Set[br340Base,LShift[br340Page,10]];
Set[neBR340,Add[br340Base,220]];
:ENDIF;

:IF[neBCPL300];
Set[brJsrPage,13];
*42b mi; can be moved without complications
Set[brJsrBase,LShift[brJsrPage,10]];
Set[Bcpl300Odd,Add[brJsrBase,320]];
Set[Bcpl300Even,Add[brJsrBase,340]];
:ENDIF;

*Registers used for timers
SetTask[TTask];
RV[ClockLo,20];
*Pilot high resolution clock
RV[ClockHi,21];
RV[RTCLOW,25];
*low half of Alto RealTime clock
RV[TimerBase,40];
*Base register containing 400b
RV[TimerBasehi,41];
*High base register
MC[pTimerBasehi,341]; *Pointer to base for MDS change code
RV[RSImage,42];
*The RS232 Image Register
MC[pRSImage,342];
*pointer to RSImage
RV[TimerTemp,43];
*Temporary
RV[RTIMER,57];
*constant for memory refresh timer
RV[REFR,77];
*refresh Address


*Kernel 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[FFault, 66];
*Flags tell what to do with fault
MC[FFaultAdd, 366];
*Address of FFault

SetTask[0];

%Register definitions for Alto and Mesa emulators

For Mesa, RM 15-17, 25, 40-53, 56-57, 64, 66-67, 72-73, and 77 are temps;
RM 11 and 70-71 unused; status of RM 0 is unknown;
all other RM locations have uses that must survive across opcodes.
*may be able to free RM 15, 17, 77 (xfXTSreg).
%
*The Mesa Stack; locations cannot change because of hardware overflow
*checking.
RV[Stack0, 1];
RV[Stack1, 2];
RV[Stack2, 3];
RV[Stack3, 4];
RV[Stack4, 5];
RV[Stack5, 6];
RV[Stack6, 7];
RV[Stack7, 10];

*Registers containing constants
RV[R400,12];
*400 Valid for both Alto and Mesa
RV[AllOnes,13]; *-1 Valid for both Alto and Mesa
*RZero to RThree must be in a quadword for Alto, which uses PCF[RZero]
*as an equivalent to PCF.word
RV[RZero,14];
*0 Valid for both Alto and Mesa
RV[ROne,15];
*1 Only valid for Alto
RV[RTwo,16];
*2 Only valid for Alto
RV[RThree,17];
*3 Only valid for Alto


RV[LocalCache0,20];
*Cache Local0 to Local3 for Mesa
RV[LocalCache1,21];
RV[LocalCache2,22];
RV[LocalCache3,23];

RV[LOCAL, 26];
RV[LOCALhi, 27];

RV[PC, 30];
*Alto and Mesa
RV[PChi,31];

RV[MDS, 32];
*Alto and Mesa
RV[MDShi,33];

RV[PBase, 32];
*PSB base register = MDS, and is NOT initialized anywhere
RV[PBasehi,33];
*(must change in the Post IME world)

RV[IBuf, 34];
*4 word instruction buffer for both Alto & Mesa
RV[IBuf1,35];
RV[IBuf2,36];
RV[IBuf3,37];

RV[wBuf,40];
*wBuf quadword not explicitly used by Mesa (temporaries)
RV[wBuf1,41];
RV[wBuf2,42];
RV[wBuf3,43];
*Must be at xBuf-1 for Alto BLT

RV[xBuf, 44];
*Quadword temporary buffer (used by LRJ--cannot move)
MC[pxBuf,44]; *pointer to xBuf
RV[xBuf1,45];
RV[xBuf2,46];
RV[xBuf3,47];

RV[yBuf,50];
*yBuf quadword not explicitly used by Mesa (temporaries)
RV[yBuf1,51];
*yBuf must be at xBuf3+1 for Alto BLT
RV[yBuf2,52];
RV[yBuf3,53];

RV[GLOBAL, 54];
*must be quadaligned
RV[GLOBALhi,55];
RV[xfMY, 56];
*must be GLOBAL + 2
RV[xfMX, 57];

RV[LPdest, 56];
*Long BLT
RV[LPdesthi,57];

RV[CODE, 60];
RV[CODEhi, 61];

*Time registers for process timeout
RV[CurrentTime, 62];
RV[TickCount, 63];

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

RV[zBuf,70];
*zBuf quadword not explicitly used by Mesa (temporaries)
RV[zBuf1,71];
RV[zBuf2,72];
*(used by LRJ--cannot move)
RV[zBuf3,73];
*(used by LRJ--cannot move)

*Other
RV[RCNT,57];
*Used by Initialize, Ether, and MesaJ

*Process registers
RV[Queue1, IP[xBuf]];
RV[Queue1hi,IP[xBuf1]];
RV[Queue2, IP[xBuf2]];
RV[Queue2hi,IP[xBuf3]];
RV[PRTime, IP[zBuf2]];
RV[Process, IP[zBuf3]];
RV[MQ, 66];
RV[RTemp2, 67];
RV[QTemp, IP[yBuf]];
RV[QTemphi, IP[yBuf1]];
RV[ITemp, IP[yBuf]];
RV[ITemp1, IP[yBuf1]];
RV[Prev, 25];
RV[PRFlags, 64];
RV[IntType, 15];
RV[IntLevel, 57];
RV[EMLink, 10];

RV[xfTemp2, 66];
RV[xfCount, 67];
RV[xfXTPreg, 25];
RV[xfATPreg, 64];
RV[xfFrame,17];
RV[xfTemp, IP[zBuf2]];
*(used by LRJ--cannot move)
RV[xfTemp1, IP[zBuf3]];
*(used by LRJ--cannot move)
RV[xfFsi, IP[wBuf]];
RV[xfRlink, IP[wBuf1]];
RV[RLink, IP[wBuf1]];
RV[xfRsav, IP[wBuf2]];
RV[xfOTPreg, IP[wBuf3]];

RV[MemStat,16];
RV[xfGfiWord,65];
*holds word 0 of global frame
RV[xfBrkByte,74];
RV[EHostReg,75];*Ethernet host register (accessed by Ethernet code
*during SIO)
MC[pEHostRegx, 74];
*pointer used during Ethernet init (points to 74
*because INPUT to the stack does a push
RV[xfWDC, 76];
RV[xfXTSreg, 77];

%Alto emulator registers:

Each AC is a base register (ACnhi, PChi, 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, 20-21, 25, 40-53, 56-57, 64, 66-67, and 72-73 are
temporaries; RM 70-71 unused; RM 0 availability unknown; RM 76 (xfWDC) unused
but may use it eventually; all other RM locations have values that must
survive across opcodes; RM 6, 20, 40-42, 51, 66-67, 72-73 used only by BitBlt.

If more registers are needed, modify BitBlt to use RZero to RThree instead
of 40-43 and restore these for Alto interrupt/exit (need restore only RZero
for Mesa interrupt/exit); this will make 40-42 available for any use by
the Alto emulator.
%
RV[CARRY,1];
*Alto carry bit in bit 0
*3 smashed by A-group opcodes
RV[AC2,4];
*Used by Mesa BitBlt
RV[AC2hi,5];
*Used by Mesa BitBlt
*7 smashed by A-group opcodes
RV[AC0,10];
*Used by Mesa BitBlt
RV[AC0hi,11];
*25 smashed by A-group opcodes
RV[AC1,26];
RV[AC1hi,27];
*21 smashed by A-group opcodes
RV[AC3,22];
RV[AC3hi,23];

RV[NWW,24];
*Also used by Mesa
MC[pNWW,24];
*pointer to NWW

RV[R177400,77];
RV[rpAC0,74];
*Wraparound pointer to AC0-1
RV[rwpAC0,55];
*Pointer to AC0
RV[rpAC1,2];
RV[rwpAC1,54];
RV[rpAC2,17];
**Coincident with RThree
RV[rwpAC2,60];
RV[rpAC3,61];
RV[rwpAC3,63];

RV[RTemp,52];
RV[RTemp1,53];
*(used by LRJ--cannot move)

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.
RV[WW,56];
*WW also used by Mesa
RV[ACTIVE,57];
*must be WW+1

RV[DMA,64];
RV[DMAhi,65];

%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; smashes AC3; restores IBuf-IBuf3 before exit;
LocalCache0-3 (20-23) restored for Mesa exit.

RM 70-71 (and bbDty after init) are available here.
%
RV[bbDest,IP[xBuf]];
*Quad-word buffer

RV[bbSlx,IP[IBuf]];
RV[bbSty,IP[IBuf1]];
*paired with bbSlx
RV[bbSLast,IP[IBuf1]];

RV[bbDlx,IP[IBuf2]];
RV[bbDty,IP[IBuf3]];
*paired with bbDlx
*bbDty available after init

RV[bbSrc,IP[yBuf]];
*Quad-word buffer
RV[bbYHi,IP[yBuf]];
*Init temporary

RV[bbSrcQLo,56];
RV[bbSrcQHi,57];
*Paired with bbSrcQLo

RV[bbDestQLo,IP[zBuf2]];
RV[bbDestQHi,IP[zBuf3]];
*Paired with bbDestQLo

RV[bbGray,IP[wBuf]];
*Quad-word buffer
RV[bbGray1,IP[wBuf1]];
RV[bbGray2,IP[wBuf2]];

RV[bbDLast,6];
RV[bbItemWid,6];
*Only needed during early init
RV[bbItemsLeft,7];
*paired with bbItemWid

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

*Constants

MC[IntPendingBit, 10];

MC[xfAV, 1000];
MC[xfSDOffset, 100];
MC[xfGFT, 1400];

MC[Normal, 0];
* Things in MemStat
MC[FreeFrame, 10];
MC[EarlyXfer, 4];
MC[BltFixup, 3];
MC[BltLFixup, 2];
MC[XferFixup, 1];

*Frame formats
MC[xfPcOffset, 1];
* in L
MC[xfRetLinkOffset, 2];
* in L
MC[LocalZeroOffset, 4];
* in L
MC[xfGfiOffset, 0];
* in G
MC[GlobalZeroOffset, 3];
* in G

*StateVector format
MC[StkPOffset, 10];
MC[DestOffset, 11];
MC[SourceOffset, 12];

*SD indicies
MC[sStackError, 2];
MC[sWakeupError, 3];
MC[sXferTrap, 4];
MC[sUnimplemented,5];
MC[sAllocListEmpty, 6];
MC[sControlFault, 7];
MC[sCsegSwappedOut, 10];
MC[sPageFault, 11];
MC[sWriteProtect, 12];
MC[sUnbound, 13];
MC[sZeroDivisor, 14];
MC[sDivideCheck, 15];
MC[sHardwareError, 16];
MC[sProcessTrap, 17];
MC[sBoundsFault, 20];
MC[sPointerFault, 21];

MC[FirstProcess, 75];
MC[LastProcess, 76];
MC[FirstStateVector, 77];

MC[CurrentPSB, 21];
MC[ReadyQ, 22];
MC[CurrentState, 23];
MC[ReadyQhi, 1];

MC[IntStopPC,25];
*Nova entry point constants
MC[StopStopPC,26];
MC[MEStopPC,27];
MC[MXDStopPC,30];
MC[MREStopPC,31];
MC[MXWStopPC,32];
MC[NOTIFYStopPC,33];
MC[BCASTStopPC,34];
MC[REQUEUEStopPC,35];

* RS232 SIO Address constants
*Set[RS232SIOLoc, Add[LShift[EEPage,10], 370]];

:End[GlobalDefs];