:TITLE[GlobalDefs];
%
Edit by Ed Fiala 17 March 1982: eliminate PNIPBase, XWInInitLoc2, InitPage2,
EOMinitPage, eomLoBase, eomHiBase, all old 10 mb Ethernet stuff;
add TimerGoLoc, new 10 mb Ethernet stuff; move 10 mb code from page 3 to
page 1; move DeviceInitPage from 2 to 6 and InitPage from 16b to 4; insert
some error checks; shuffle task numbers.
Edit by Ed Fiala 19 February 1982: Absorb Initial’s MP codes; add
InitialPage1, PageCount, xPageCount, xStorageFaults, xHardBadPages,
xSoftBadPages for MemInit.Mc; eliminate RCnt, xfType, StopStopPC,
REQUEUEStopPC; add ExchStkPLoc and SetStkPLoc for new LoadRAM,
xfFaultGoLoc, StartDeviceInit, MC12, MCNoneCrash; absorb location defs from
Fault.Mc; move RSImage and NWW.
Edit by Ed Fiala 8 October 1981: Move MemStat to RM 0 freeing RM 24-25 for
CedarGC; move prTicks and prTime out of RM 0-77 area and add prSaveStkP
reg; move xfRSAV to free RM 64; create moPage and change xfRRtab & xfWRtab
to moRRtab & moWRtab; elim LFKeyboard, LFMonitor, FaultRefType,
FaultPage1, and CSPage; add MesaRefillLoc, WithTextBlt, WithGarbCollect,
WithFloatingPoint, MidasPage, FaultPNIX0, FaultPNIX1, StackErrorLoc, and
zBuf-zBuf3; set TimerPage = 14; move MP code defs to here from Fault,
MesaPDefs, and TextBlt; relocate XIStartLoc, StartIOLoc, CDCInitLoc,
CDCOffLoc.
Edit by Ed Fiala 29 April 1981 Add WithMidas, BootTask, BootSV, PFExitLoc,
defs for Cedar Jasmine, JasmineHalftone, Audio, and CDCTask drivers; elim
KeyPage & KeyTable defs (now on DisplayPage), DpTask, pRSImage,
pFaultParm, pFaultRefType, pXBuf, pNWW (now using IP[..]C for these),
EtherInitPage2,XWInitPage2, ClrDvPage, TimerInitPage1/2, LoadCSPage;
move StartIOPage, XWPage; move Timer registers not targets
of memory references into 322-337 area for Audio.Mc and Jasmine.Mc;
move NWW to non-emulator, MemStat to RM 25, temps at 65 to 51.
%

%Standard Pilot setting of these switches is: WithMidas=1, With3MB=1,
With10MB=1, WithMIOC=1, and all other switches 0.

Standard Cedar setting is CedarMode=1, WithFloatingPoint=1, WithGarbCollect=1,
With3MB=1, With10MB=1, WithCDC=1, and all other switches 0.
%
Set[WithMidas,0];
*1 reserves space for Midas Kernel and
*communication microcode; must be 0 for Audio.Mc,
*Jasmine.Mc, or other Printer interface devices.
*Mi consumed as follows: 31b mi on pg 17b in Fault,
*3b mi on pg 0 in Fault, 3b mi on pg 0 in Timer,
*and 117b mi on pg 17 IMReserved for Kernel.
Set[CedarMode,1];
*0 regular Pilot; 1 Cedar-specific changes
*(on 5 March 1982, affects und. opcode traps).
Set[WithTextBlt,0];
*1 for microcoded TextBlt else 0 (Can’t be used
*when WithGarbCollect=1 because of RM conflict;
*used only by Star).
Set[WithFloatingPoint,1];
*1 for microcoded floating point
Set[WithGarbCollect,1];
*1 for microcoded Cedar garbage collector

*NOTE: These switches control the assembly of DTab entries in Initialize.Mc.
*Code in XWSIO2.Mc is affected by With10MB and With3MB switches.
Set[WithTOR,0];
*1 for TOR io microcode (UIB and EOM)
Set[WithMIOC,0];
*1 for MIOC and its overlays.
Set[With10MB,1];
*1 for 10 mb Ethernet (ENXTask.Mc)
Set[With3MB,1];
*1 for 3 mb Ethernet (XWTask.Mc)
Set[WithCDC,1];
*1 for color display (CDCTask.Mc)

*NOTE: AltoMode=0 and CacheLocals=0 are mandatory.
Set[AltoMode,0];
*0 selects Pilot mode (must be 0)
Set[CacheLocals,0];
*0 for no cache, 1 for cache of locals 0 - 3

%TASK ASSIGNMENTS

Be sure edit Timer.mc if you change enxTask* or xoTask*.

Beware of expecting too many things to work. Duplicates in the following
assignments and/or device table in Initialize are mostly a convience allowing
one microcode version to run on many configurations rather than a way to
support the most complicated configuration you might build. In particular:
You can’t have a 2nd 3 mb Ethernet if you have an IFDC or an MIOC.
You can’t have a 2nd MIOC if you have a 10mb Ethernet.
%
Set[BootTask,1];
IFG[BootTask,3,ER[Initialize.requires.BootTask.be.0.to.3]];

*MakeTask check for a task number in the range 4 to 16.
Macro[MakeTask,Set[#1,#2]
IFG[#2,3,IFG[#2,16,ER[#1.task.too.big]],
ER[#1.task.number.too.small]]];

MakeTask[xoTask,10];
*1st 3mb Ethernet Output
MakeTask[xiTask,11];
*1st 3mb Ethernet Input
MakeTask[xoTask2,4];
*2nd 3mb Ethernet Output
MakeTask[xiTask2,5];
*2nd 3mb Ethernet Input

MakeTask[enxTask,7];
*1st 10 mb Ethernet in/out
MakeTask[enxTask2,6];
*2nd 10 mb Ethernet in/out
MakeTask[enxTask3,5];
*3rd 10 mb Ethernet in/out

MakeTask[cdcTask,6];
*Color display (1 wakeup/63 us; 27 percent)

*RDC uses registers for two tasks, so its task number should be even and
*the next task should not be used.
MakeTask[rdcTask,12];
*The display uses several registers for the next task (see Pilot1.Regs)
MakeTask[DisplayTask,14];
*(3 wakeups/28.8 us; 25 percent)
MakeTask[TTask,16];
*Can’t change; uses some task 15 registers.

MakeTask[ioTask1,4];
*1st MIOC task
MakeTask[ioTask2,6];
*2nd MIOC task
*MakeTask[fdtask,5];
*IFDC task (no longer supported)

*TOR TASK ASSIGNMENTS
MakeTask[eomLoTask,4];
*eomLo
MakeTask[eomHiTask,5];
*eomHi
MakeTask[uibTask,14];
*UIB

IFE[enxTask3,xiTask2,,
ER[Since.enxTask3.ne.xiTask2.fix.xoNotify2.enxNotify3.register.conflict]];

IFE[enxTask,xoTask,ER[enxTask.xoTask.conflict.affects.timers]];
IFE[enxTask2,xoTask,ER[enxTask2.xoTask.conflict.affects.timers]];
IFE[enxTask3,xoTask,ER[enxTask3.xoTask.conflict.affects.timers]];
IFE[enxTask,enxTask2,ER[enxTask.enxTask2.conflict.affects.timers]];
IFE[enxTask2,enxTask3,ER[enxTask2.enxTask3.conflict.affects.timers]];
IFE[enxTask,enxTask3,ER[enxTask.enxTask3.conflict.affects.timers]];

IFG[DisplayTask,rdcTask,,ER[DisplayTask.should.be.>.rdcTask]];
IFG[rdcTask,cdcTask,,ER[rdcTask.should.be.>.cdcTask]];
*IFG[rdcTask,xoTask,,ER[rdcTask.should.be.>.xoTask]];
IFG[xiTask,xoTask,,ER[xiTask.should.be.>.xoTask]];
IFG[xiTask2,xoTask2,,ER[xiTask2.should.be.>.xoTask2]];

IFE[And[DisplayTask,1],0,,ER[DisplayTask.must.be.even.because.>.20b.regs]];
IFE[And[rdcTask,1],0,,ER[rdcTask.must.be.even.because.>.20b.regs]];
IFE[TTask,16,,ER[TTask.must.remain.16]];

*INITIAL MICROCODE PAGE ASSIGNMENTS
Set[InitialPage,10];
Set[InitialPage1,11];
Set[SalLoaderPage,12];
Set[SalLoaderPage2,7];
Set[EtherPage,4];
Loca[MicrocodeLoadedLoc,InitialPage,200];
MC[MicrocodeAddress,1400];
*Where to put it in memory
Set[EtherBootLoc,1400];
*Known to PromDefs (***Where is this used???)


*PILOT1 INITIALIZATION PAGE ASSIGNMENTS
*NOTE: It is desirable to put throwaway initialization code on pages 4 to 7
*which we KNOW will be overwritten by Pilot2, leaving the rest of the
*microstore for dynamic assignment between Pilot1 and Pilot2.
Set[DeviceInitPage,6];
*Device initialization
Loca[DBootDoneLoc,DeviceInitPage,375];*Where is this used?
Loca[TimerInitLoc,DeviceInitPage,376];
Set[enxInitPage,DeviceInitPage];
Loca[enxInitLoc,enxInitPage,240];
Loca[enxInitLoc2,enxInitPage,242];
Loca[enxInitLoc3,enxInitPage,244];
Set[xwInitPage,DeviceInitPage];
Loca[xwInInitLoc,xwInitPage,230];
Loca[xwOutInitLoc,xwInitPage,234];
Loca[xwOutInitLoc2,xwInitPage,236];
Set[rdcInitPage,DeviceInitPage];
Loca[rdcInitBase,rdcInitPage,340];
Loca[rdcInitLoc,rdcInitPage,340];
Set[UIBInitPage,DeviceInitPage];
*TOR UIB
Loca[UIBInitLoc,UIBInitPage,220];
Loca[eomHiTaskInitLoc,DeviceInitPage,221];*TOR EOM
Loca[eomLoTaskInitLoc,DeviceInitPage,222];*TOR EOM

Set[DeviceInitPage2,5];
*More device initialization
Set[DisplayInitPage,DeviceInitPage2];
Loca[DisplayInitLoc,DisplayInitPage,207];
Loca[Task0NotifyLocA,DisplayInitPage,210];
Set[Task0NotifyLocB,Add[Task0NotifyLocA,1]]; *2611 in .Mlf files
Set[vOverlayLoadedLoc,Add[Task0NotifyLocB,1]]; *2612 in .Mlf files
Loca[Task0NotifyLocC,DisplayInitPage,215];
Loca[vContinueInitLoc,DisplayInitPage,206];
Loca[vSLCountLoc,DisplayInitPage,214];
Set[IOInitPage,DeviceInitPage2];
*MIOC initialization
Loca[IOInitLoc,IOInitPage,220];

Set[InitPage,4];
*Initialize module
Loca[BootStartLoc,4,372];*Not presently used (?)
Loca[SoftStartLoc,4,373];*2373 in .Mlf files
Loca[InitBase,InitPage,0];
Set[QretLoc,Add[InitBase,7]];
Set[Task0StartLoc,Add[InitBase,10]];

*PILOT1 RESIDENT PAGE ASSIGNMENTS--WILL REMAIN AFTER PILOT2 OVERWRITE
Loca[PFExitLoc,0,7];
Set[Qloc,5];*On page 0 so Qloc+1 won’t be overwritten, but
*Pilot2 can go ahead and overwrite Qloc
Set[FaultPage,0];
*In Fault.Mc
Loca[StartMemTrapLoc,FaultPage,16];
Loca[InitEndLoc,0,20];*In MesaX.Mc
Loca[FixDisp,FaultPage,100];
Loca[CrashLoc,FaultPage,134];
Loca[StackErrorLoc,FaultPage,136];
Loca[MC12,FaultPage,140];
Loca[EmuNotifyLoc,0,200];*Must be page 0
Loca[NonEmuNotifyLoc,0,202];*Must be page 0
Loca[ContNonEmuLoc,FaultPage,204];
Loca[NonEmuPFLoc,0,206];*205b to 210b are used (must be page 0)
Set[DoIntPage,0];
Set[NotifyInterruptPage,0];
Loca[NotifyInterruptLoc,0,360];*For NotifyInterrupt
Set[LRJPage,0];
Loca[LRJStart,LRJPage,300];
Set[LRJContinue,Add[LRJStart,1]];*For old LoadRAM; also works
*with new LoadRAM.
*Set[LRJGo,LRJPage,302];*Start and continue address
*for new LoadRAM
*Set[ExchStkPLoc,Add[LRJGo,30]];*Entry in new LoadRAM only
*Set[SetStkPLoc,Add[LRJGo,31]];*Entry in new LoadRAM only
Set[nePage,1];*Alto emulator page, def still needed by LoadRAM
Loca[JmpFinLoc,nePage,3];*Reentry location for Alto LRJ
Set[PNIPPage,0];
Loca[PNIPStart,PNIPPage,176];

Set[enxPage,1];
*10 mb Ethernet microcode
Loca[enxStartLoc,enxPage,110];*Input notify location
Loca[enxOTimerDoneLoc,enxPage,114];*Output notify location
Loca[enxDispTableLoc,enxPage,120];*TimerDone notify loc

Set[IOPage,2];
*MIOC code
Loca[IOStartLoc,IOPage,374];

Set[eomLoTaskPage,1];
Set[eomHiTaskPage,2];

Set[UIBpage,12]; *TOR UIB microcode
Set[DisplayPage,12];
*Display and keyboard microcode
Loca[vEndOfFieldLoc,DisplayPage,0];
Loca[BootSV,DisplayPage,1];

Set[rdcPage,13];
*SA4000 main task
Set[StartIOPage,13];
*Ethernet StartIO
Loca[StartIOLoc,StartIOPage,120];

Set[TimerPage,14];
Loca[TimerGoLoc,TimerPage,335];
Loca[TimerTable,TimerPage,340];
Loca[MidasHaltLoc,TimerPage,213];*Must be odd; 212-214 are used
Set[xwPage,14];
*3 mb Ethernet microcode
Loca[xiStartLoc,xwPage,143];*Input notify location
Loca[xoStartLoc,xwPage,152];*Output notify location
Loca[xoTimerDoneLoc,xwPage,154];*TimerDone notify loc
Loca[cdcInitLoc,14,222];
*JRam 56222 turns on color display controller
*Output with 0 argument to device cdcTask,,0
*turns it off.

Set[FDpage,17];
*IFDC code
Set[FDoffset,240];*IFDC dispatch table offset (must be mod 20)
Loca[FDinit,FDpage,Add[FDoffset,2]];*initial starting address
Set[MidasPage,17];
Set[MidasFaultLoc,112];*In Midas Kernel (used with GoToExternal)
Set[MidasBreakLoc,110];*In Midas Kernel (used with GoToExternal)

*PILOT2 PAGE ASSIGNMENTS
Loca[MesaRefillLoc,0,2];
Set[opPage0,4];
Loca[prFaultLoc,opPage0,300];
Set[MulDivPage,4];

Set[opPage1,5];
Set[BrkBPage,5];
*13b mi in MesaX; can move anywhere.

Set[opPage2,6];

Set[opPage3,7];
Loca[P7TailLoc,opPage3,27];*Known to LoadRAM--can’t easily move
Loca[KFCRLoc,opPage3,76];
Set[LoadGCPage,7];
* 5b mi in MesaX; can move anywhere.

:IF[WithTextBlt]; *************************************
Set[TxP1,10];
*TextBlt page
Loca[BBFAType0Disp,TxP1,140];
Loca[TxInitFuncDisp,TxP1,160];
Loca[TxCharFuncDisp,TxP1,200];
Loca[TxLoopFuncDisp,TxP1,220];
:ENDIF; ***********************************************
Set[moPage,10];
*Miscellaneous opcode page
Loca[moWRtab,moPage,260];
Loca[moRRtab,moPage,300];

Set[bbP1,11];
*bitblt page

Set[xfPage1,15];
Loca[ReadTimeLoc,xfPage1,0];
Loca[xfFaultGoLoc,xfPage1,1];
Loca[xfMSTab,xfPage1,120];
Loca[MiscDisp0,xfPage1,220];*For MesaX and MesaFP
Loca[MiscDisp1,xfPage1,240];*0 through 20b used
Loca[LoadGCLoc,xfPage1,300];

Set[prPage,16];


*CEDAR PAGE ASSIGNMENTS
*Audio.Mc uses timer slot 2b; Jasmine.Mc, slots 13b through 16b.
Set[audPage,17];
Loca[audGoLoc,audPage,200];*JRam start = 160000b+audGoLoc
Set[JasPage,17];
*164b mi (not on 4 to 7)
Loca[JasmineOn,JasPage,201];*JRam start = 160000b+JasmineOn
Loca[JasmineOff,JasPage,202];
Loca[JasminePulse,JasPage,203];
Set[HalftonePage,17];
*124b mi (not on 4 to 7)
Loca[PrintLine,HalftonePage,204];

*REGISTER DEFINITIONS FOR TIMER TASK, MIDAS KERNEL, ETC.

SetTask[TTask];

*320-377 are accessible as variables, but registers that are targets of
*PFetch/PStore by the timer task can only use 340-357.

*320-322 are used by DisplayTask.
RV[vCrystal,23];
*Contains 2*processor clock speed in mHz.

RV[xoNotify,24];
*Notify value for 1st 3 mb Ethernet output task
RV[xoNotify2,27];
*Notify value for 2nd 3 mb Ethernet output task
RV[enxNotify,25];
*Notify value for 10 mb Ethernet
RV[enxNotify2,26];
*Notify value for 10 mb Ethernet
RV[enxNotify3,27];
*Notify value for 10 mb Ethernet

RV2[ClockLo,ClockHi,30];
*Pilot 64d-cycle timer
RV[RTimer,32];
*Refresh timer

*RM 333 is unused
*RM 334-346 are used as temporaries by Audio.Mc.
*RM 334-351 are used as temporaries by Jasmine.Mc.
*RM 352-353 are smashed by PNIP on a crash or breakpoint, so they are
*ok to use as temporaries but inconvenient for permanent registers.

*Where Initial’s memory test results are left for the emulator.
RV4[xPageCount,xStorageFaults,xHardBadPages,xSoftBadPages,44];

*These permanent emulator registers are accessed through StkP
RV2[prTime,prTicks,54];
*Tick size(3), decremented at scan line 0
*Current tick count for timeout clock
RV2[RSImage,NWW,56];
*Image of RS232 hardware register
*New wakeups waiting

*REGISTER DEFINITIONS FOR KERNEL, INITIAL, AND FAULT.
SetTask[17];

RV4[PipeReg,PipeReg1,PipeReg2,PipeReg3,60]; *Pipe Ram Entry
RV2[PipeReg4,PipeReg5,64];
RV[FFault,66];
*Flags tell what to do with fault
RV[FaultParm,67];
*-1 => MOB fault
*positive => page fault, page in low 14 bits
*negative => write protect, page in low 14 bits
RV[RTMP,71];
*temporary
RV[RXStk,72];
*SStkP&NStkP
RV[RXPPB,73];
*Page&Par&Boot
RV[RXCTask,74];
*CTask.NCIA
RV[RXAPC,75];
*APCTask&APC
RV[RXALU,76];
*ALUResult&NSALUF
RV[Refr,77];
*Refresh address (task 17’s register); used by
*both Midas Kernel and Pilot TTask, so convenient
*not to move this.

*RM DEFS ALLOWING SYMBOLIC MIDAS DISPLAY FOR RM 100-107 AFTER MEMORY ERRORS
SetTask[4];
RV4[MapEntry,TaskNumber,RefType,CrashCode,0];
RV4[CardNumber,MapFlags,QuadAddr,Syndrome,4];

*REGISTER DEFINITIONS FOR MESA EMULATOR

SetTask[0];

RV[MemStat,0];
*Permanent variable controlling page fault handling

*Mesa Stack locations cannot move because of hardware overflow checking.
MC[MaxStack,16];
*Largest referenceable stack address
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];

*17-23 are temporaries

:IF[CacheLocals]; ************************************
*Quadword for cacheing Locals 0 to 3
***This must be assigned a valid location--current def won’t work
*RV4[LocalCache0,LocalCache1,LocalCache2,LocalCache3,20];

:ENDIF; **********************************************
*24-25 are permanent registers for CedarGC.
RV[prCurrentPsb,26];
*Points to front of ready queue.
RV[prPsbIndexMask,27];
*Contains a mask for the PsbIndex
RV2[PCB,PCBhi,30];
*PC base register pair
***Free one register by defining RZero equal to MDS.
RV2[RZero,R400,32];
*Constant 0, Constant 400
RV2[prPda,prPdaHi,32];
*Base register pair points to Process Data Area. Must be same as RZero and R400
RV2[LOCAL,LOCALhi,34];
RV2[MDS,MDShi,36];
*xfBrkByte not necessarily in quadword; xfGFIWord, CODE, and
*CODEhi must be 2nd to 4th words of quadword for MesaX Loadgc.
RV4[xfBrkByte,xfGFIWord,CODE,CODEhi,40];
*44-53 are temporaries.
RV4[GLOBAL,GLOBALhi,xfMY,TrapParm,54];
*xfMY (also used by MUL)
*and TrapParm are temps
RV4[IBuf,IBuf1,IBuf2,IBuf3,60];
*instruction buffer

*64-65 are permanent registers for CedarGC.
*66-73 are temporaries.

*AllOnes is used by Initialize.Mc, so it may not conflict with
*registers defined there (it may not be in the range 40b to 57b,
*and some other values are illegal also).
RV[AllOnes,74];
*75 is a permanent register (fpSticky) for MesaFP
RV[xfWDC,76];
RV[xfXTSreg,77];

*General temporaries
RV[RLink,17];
RV4[xBuf,xBuf1,xBuf2,xBuf3,44];
*Quadword temporary buffer
RV4[yBuf,yBuf1,yBuf2,yBuf3,50];
*For new LoadRAM
RV[RTemp,52];
RV[RTemp1,53];
RV[WW,56];
RV2[LPdest,LPdesthi,56];
*Long BLT
RV2[LP,LPhi,66];
*long pointer base pair

*XFER temporaries used in MesaX
RV[xfFSI,67];
RV[xfRlink,17];
RV[xfFrame,50];
RV[xfRSAV,51];
**Should assign a different number for this one
RV[xfTemp2,IP[LP]];
RV[xfCount,66];
*xfMX not necessarily in this same quadword; xfTemp-1, xfTemp, and
*xfTemp1 must be 2nd thru 4th words of quadword for Xfer.
RV4[xfMX,xfTemp-1,xfTemp,xfTemp1,70];
RV4[zBuf,zBuf1,zBuf2,zBuf3,70];

*BitBlt temporaries (Stack2 - Stack13 available because BitBlt args
*are always passed in Stack0 - Stack1)
*15, 20-23, and 51-52 are available temporaries here.
RV[bbArgPtr,1];
*pointer to BitBltArg table
RV[bbGrayWordIndex,1];
*Low order 4 bits
RV2[bbDestQLo,bbDestQHi,2];
*Dest Quad word address
RV2[bbSourceQLo,bbSourceQHi,4];
*Source Quadword address
RV[bbSourceBitOffset,6];
RV[bbItemsRemaining,7];
RV[bbDestBitOffset,10];
RV[bbDestBpl,11];
RV[bbItemWidth,12];
RV[bbSubitemDestBitOffset,13];
RV[bbFlags,14];
RV[bbGrayWord,16];
*Gray word
RV[bbNegItemWidth,17];
RV[bbDest,44];
*Quadword buffer
RV[bbSDNonOverlap,44];
RV[bbNegSDNonOverlap,50];
RV[bbDestWordOffset,53];
RV[bbSourceBpl,56];
*source bits per line
RV[bbSourceWordOffset,57];
RV[bbTouchPages,66];
RV[bbSubitemSourceBitOffset,67];
RV[bbSource,70];
*Quadword buffer
RV2[bbArgLo,bbArgHi,70];
*Points to BitBltArg table

*End of bitblt registers

:IF[WithTextBlt]; ***********************************
*TextBlt registers--all temporaries are used here.

*The following registers are in the stack on entry and reentry
RV[txrIndex,1];
*Stack 0
RV[txrBitPos,2];
*Stack 1
RV[txrMicaPos,3];
*Stack 2
RV[txrCount,4];
*Stack 3
RV[txrArgSPtr,5];
*Stack 4

*The following register is the same as txrArgSPtr above. On exit we
*return our result in the same stack register by which we recieved
*our argument pointer.
RV[txrResult,5];
*Stack 4

RV[txrDestBpl,6];
RV[txrMargin,7];

RV4[txrFontBodyLo,txrFontBodyHi,txrFlagLo,txrFlagHi,10];
RV[txrSrcBitOffset,12];
RV[txrDestBitOffset,13];

RV2[txrArgLo,txrArgHi,14];

RV[txrSrcImageWO,16];
RV[txrNegItemWidth,16];
RV[txrMicaWidth,17];

RV4[txrFunction,txrLast,txrTextLo,txrTextHi,20];

RV[txrDestBuf,44];
*Quadword block

RV[txrFlag,50];

RV[txrHeight,51];

RV2[txrDestLo,txrDestHi,52];
RV2[txrCoordLo,txrCoordHi,52];

RV2[txrFontLo,txrFontHi,56];

RV[txrBitWidth,64];
***HAVE TO MOVE THIS NOW

RV[txrSrcQWO,66];
RV[txrDestQWO,67];

RV[txrSrcBuf,70];
*Quadword block
RV[txrCharacter,70];
RV[txrSpace,71];

:ENDIF; *********************************************

%Temporary Process Registers

Notes on assignment of process registers.
(1) Process registers are used only (?) in MesaP and need not survive across
opcodes.
(2) There are insufficient registers to provide a unique register for each
requirement, so registers are assigned based upon analysis of the scope of
register use. When MesaX subroutines are called by process code, the MesaX
registers used must be included in the scoping.
(3) All process opcodes are minimal stack. Unfortunately, because much of the
code is also used during interrupts and fault notification we cannot, in
general, take advantage of minimal stack to use stack registers for process
temporaries. Since prMonitorQ(hi) are only used in paths originating with
process opcodes, they can and do overlap the stack.
%

RV2[prMonitorQ,prMonitorQhi,6];


RV[prReturnLink,17];
RV2[prConditionQ,prConditionQhi,20];
RV[prQueue,22];
*Used by Requeue
RV[prReady,22];
*Returned by Requeue
RV[prPsbIndex,23];

RV4[prPsbLink,prPsbFlags,prPsbContext,prPsbTimeout,44];


RV[prPsbLink.next,50];
*Used by Requeue
RV[prCleanupLink,50];
*Used by CleanUpCondition
RV[prRtnLink2,51];
*Used only for the NotifyWakeUp subroutine
*(by Interrupt & Fault notification)
RV[prSaveStkP,51];
*Used to remember StkP while accessing prTime,
*prTicks, etc. outside RM 0-77.
RV[prCondition,52];
*Contains ConditionQ↑
RV[prCurrentSAT,52];
*Used by Reschedule
RV[prPtrToSV,53];
*Used by Reschedule
RV[prMonitor,53];
*Contains Monitor↑

RV[prTimeout,56];
*Timeout parameter redefinition of WW
RV2[prData,prData1,56];
*Fault parameters (only one used now?)
RV[prPsbPriority,57];
*Used by Requeue
RV[prConditionTail,57];
*Used by CleanUpCondition
RV2[prQTemp,prQTempHi,66];
*Used by Requeue
RV2[prState,prStateHi,66];
*Used by Reschedule
RV[prQueueHead,66];
*Used by CleanUpCondition
RV[prQueueTail,67];
*Used by CleanUpCondition
RV[prPrevPsbLink,70];
*Used by Requeue
RV[prFlags,71];
*Flags
RV[prNextPsbLink,72];
*Used by Requeue
RV[prStackPointer,72];
*Used by Reschedule
RV[prPrevPsbIndex,73];
*Used by Requeue
RV[prFrame,73];
*Used by Reschedule

*End of process registers


*Following two definitions emphasize in the MicroD .Regs file that RM 352-353
*are clobbered by PNIP when executed on a fault; these registers aren’t
*directly mentioned in Initialize.Mc because PNIP is defined for task 0.
RM[FaultPNIPX0,Add[300,IP[RTemp]]];
RM[FaultPNIPX1,Add[300,IP[RTemp1]]];

*CONSTANTS

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

MC[IntPendingBit,10];

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

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

*Global frame
MC[xfGfiOffset,0];
MC[GlobalZeroOffset,3];

*Local frame
MC[xfPcOffset,1];
MC[xfRetLinkOffset,2];
MC[LocalZeroOffset,4];

*PDA (Process Data Area) format.
*The first Psb has a PsbIndex of 210. This permits us to use the
*same register to access the Pda and all of the Psbs.
MC[pdaReady,0];
*Word 0: points to tail of ready queue.
MC[pdaCount,1];
*Word 1: number of Psbs in the block.
MC[pdaTimeout,2];
*Word 2: Pointer to TimeoutVector (currently not used).
MC[pdaReserved,3];
*Word 3..7: Currently not used, = zero.
MC[pdaState,10];
*Word 10: Array[0..7] of Pointer To
*StateVector List. Indexed by priority.
MC[pdaInterrupt,20];
*Word 20: Array[0..WordSize) of
*InterruptVector : [Condition, Unspecified].
MC[pdaLastInterrupt,56];
*Word 56: last [Condition, Unspecified].
Set[qFaultOS,60];
*Word 60: Array[0..7] of
*FaultVector : [Queue, Condition].
MC[pdaFault,qFaultOS];
*MC form.
MC[pdaBlock,100];
*Word 100: Array[0..count) of Psb.
*Fault Offsets. Offsets from pda to Fault[fault]
MC[qFrameFaultOs, qFaultOS];
MC[qFrameFaultCOs, ADD[qFaultOS,1]];
*Fault[frame].condition
MC[qPageFaultOs, ADD[qFaultOS,2]];
MC[qWriteProtectOs, ADD[qFaultOS,4]];


*MemStat constants
* low three bits are dispatch code for page fault
* other bits are flags to Xfer
MC[Normal,0];
*Only normal PC fixup required on page fault
MC[BltLFixup,2];
*Special page fault fixup for BLTL
MC[BltFixup,3];
*Special page fault fixup for BLT
MC[EarlyXfer,4];
*Special page fault fixup for early Xfer
MC[XferFixup,5];
*Special page fault fixup for late Xfer
MC[BitBltFixup,6];
*Special page fault fixup for BitBlt
MC[Trap,40];
*The current Xfer is a Trap
MC[NoPushSD,100];
*Do not put source/dest above stack
MC[FreeFrame,200];
*Free old frame if Xfer is successful

MC[StartDeviceInit,150];
*104d indicates that Pilot microcode initialization
*has started.

*Crash codes for Maintenance Panel. NOTE: maintenance panels have been known
*to pick up occasional extra pulses, so codes 1 larger than those here
*sometimes are seen.

MC[RMCSCrash,170];
*120d to 135d RM or CS parity error possibly in
*combination with other errors. MP code is 120d plus:
* 1 if MC1 or MC2 error
* 2 if RM parity error
* 4 if CS parity error
* 8 if Stack overflow or underflow

%The following codes imply no RM or CS parity error or stack error. Many
codes show a mod 20d number + the task responsible for the error; mod 20d
allows the task number to be easily computed from the maintenance panel.
NOTE: code definitions with the pipe task added to them are offset by 15d to
compensate for the microcode’s algorithm, but comments are correct.
%
MC[MOBCrash,214];
*140d + current task. Map Out of Bounds during
*microcode init (traps to Mesa after init).
MC[H4PECrash,240];
*160d + current task. H4PE.
MC[LPCrash,264];
*180d + current task. Some fault when preceding mi
*was a LoadPage (Indicates microcode bug--report it).

MC[MC2Crash,327];
*200d + pipe task. MC2 error (Double bit failure
*or violation of Output-Output-PStore4 gotcha).

MC[MC1Crash,353];
*220d + pipe task. MC1 fault (i.e., page or write
*protect fault) during microcode init (traps to Mesa
*after init)
MC[BrkPCrash,360];
*240d + current task. SetFault (i.e., breakpont) by
*task, interpreted as follows:
* 0 emulator (no special uses)
* 1 unused (bad wakeup)
* 2 unused (bad wakeup)
* 3 unused (bad wakeup)
* 4 1st MIOC task, 2nd Ethernet 3mb or 10mb output
*task, or EOM low task.
* 5 3mb or 10mb 2nd Ethernet input task, IFDC task,
*color display task, or EOM high task.
* 6 2nd MIOC task or 1st 10mb Ethernet output task.
* 7 1st 10mb Ethernet input task.
* 8 RDC task.
* 9 unused (bad wakeup)
* 10 1st 3mb Ethernet output task.
* 11 1st 3mb Ethernet input task.
* 12 Display task or UIB task.
* 13 unused (bad wakeup).
* 14 timer task.
* 15 fault task.

MC[NoStateVectorError,164];
*116d--MesaP crash.
MC[MC22Crash,165];
*117d 2 MC2 errors
*MC[NextInstMPCode,166];
*118d--Hardware problem on some machines causing
*ResetErrors executed at the onset of a fault to be
*interpreted as a NextInst. The consequence is
*that SStkP ← StkP and PCX advance occurs;
*NO LONGER IMPLEMENTED.

MC[StkCrash,167];
*119d--Stack over/underflow
MC[MCNoneCrash,210];
*136d--MC12 error with no error indication in
*pipe--possibly PFetch4 experienced error
*correction, next reference faulted, and third
*reference slipped in erroneously.

%These MP codes are used by Initial, the boot loader that runs prior to
loading either AMesa or Pilot; fault and crash MP codes are identical to
those for Pilot, except that they are offset by InitialMPOffset. However,
InitialMPOffset .eq. 0, so they are the same now. In addition, Initial has
the "normal boot sequence" codes enumerated below and a few error MP codes of
its own. These codes are used in Initial.Mc, MemInit.Mc, and SA4000Loader.Mc.
%
Set[MinGoodPages,400];
*Minimum no. good pages (= 64k words)

Set[InitialMPOffset,0];
*Offset for fault crash MP codes
MC[MPOffset,1000];
*Offset for sequencing MP codes
*(displayed by ShowNumber).
MC[StartMapInit,274];
*700d
MC[NotEnoughMemory,275];
*701d (64k 16-bit words required)
MC[BadMap,276];
*702d (map must be perfect)
MC[StartDiskBoot,320];
*720d
MC[NoRDC,321];
*721d
MC[RDCReadError,322];
*722d
MC[StartDiskBootPilot,325];
*725d
MC[StartEtherBoot,344];
*740d Offset for set of boot numbers.
MC[NoUTVFC,345];
*741d

%If any storage board failures are found by Initial’s diagnostic, irrespective
of whether the pages are used or discarded, then 3 numbers will be shown on
the MP for 1.6 seconds each. The first number, indicating storage board(s)
affected by failures, has a range of 400d to 655d; it is interpreted
according to the table below. The second number is a count of hard bad pages
detected (ones with uncorrectable failures). The third number is a count of
soft bad pages (ones with correctable failures).
%
Set[TestingStorage,620];
*400d + n bit-encoded as follows:
* + 1 1st storage board has failure(s)
* + 2 2nd storage board has failure(s)
* + 4 3rd storage board has failure(s)
* + 8 4th storage board has failure(s)
* + 16 5th storage board has failure(s)
* + 32 6th storage board has failure(s)
* + 64 7th storage board has failure(s)
* + 128 8th storage board has failure(s)

MC[MPOffset256,400];
*Used by SA4000Loader
MC[MPCodeNoSoftBootCode,51];
*809d
MC[MPCodeNoGerm,52];
*810d
MC[MPCodeNoPilotBootVolume,53];
*811d
MC[MPCodeRDCLabelCheck,54];
*812d

:END[GlobalDefs];