:IF[AltoMode];
  TITLE[MesaX--Alto.Mode];
:ELSE;
  TITLE[MesaX--Pilot.Mode];
:ENDIF;

*Dispatch base addresses
SET[xfPage1p, LSHIFT[xfPage1,10]];
SET[xftype, ADD[xfPage1p, 140]];
SET[xfWRtab, ADD[xfPage1p, 160]];
SET[xfRRtab, ADD[xfPage1p, 200]];
SET[MiscDisp, ADD[xfPage1p, 220]];

	OnPage[xfpage1];
*since xfPage1 has NextData's and NextInsts, it must have refill link at 377
xfRefill:	gotop[MesaRefill], Pfetch4[PC,IBUF,4], AT[OR[LSHIFT[xfPage1,10],377]];

xfRet:	return;
SaveRLink: xfRLink ← T, return;
EXMemStat:	MemStat ← EarlyXfer, return;

Xfer:	xfXTSreg ← rsh[xfXTSreg,1], goto[XferNTC, REven]; *Trap check
*Cause xfer trap with 0 as reason, xfMX as trap parameter
	T ← xfMX, LoadPage[7];
	xfXTSreg ← 0c, gotop[XTrap];
XferNTC:	dispatch[xfMX,16,2];	*entry for no trap check
	T ← xfMX, disp[XferType0];

*Control link is a frame pointer
XferType0:	xfCount ← T, skip[ALU#0], AT[xftype,0];	*save frame pointer
	RTEMP ← sControlFault, dblgoto[QTrap,QTrapF,MB]; *MB => don't free frame
	PFetch2[MDS,xfTemp], call[EXMemStat];	*Fetch G and PC
	T ← (LOCAL)-1, skip[MB];
	PFetch1[MDS,xfFSI];	*Start freeing the current frame
	T ← xfTemp; *New G
	lu ← (GLOBAL) xor (T), skip[ALU#0];
	T ← sUnbound, goto[StashMX]; *New G = 0
	GLOBAL ← T, goto[CValid,ALU=0]; *NewG # OldG => load G and C

GetGC:	PFetch4[MDS, IBUF], call[xfRet];  *Fetch global frame overhead
	call[LoadC];
	xfGfiWord ← T;

*Finish freeing the current frame if required.
CValid:	T ← (xfFSI) + (xfav), goto[FreeDone, MB];
	PFetch1[MDS, xfFrame]; *fetch the list head
	PStore1[LOCAL,xfFrame,0], call[xfRet];  *Store head of list into Local[0];
	PStore1[MDS, LOCAL];	*Store LOCAL into list head
:IF[AltoMode]; **************************************
FreeDone:
	T ← lsh[xfTemp1, 1], goto[PCok, r >= 0];
	T ← (Zero) - T;
	xfTemp ← (Zero) + (T) + 1, goto[PCokx];
:ELSE; **********************************************
FreeDone:
	T ← xfTemp1;
:ENDIF; *********************************************

PCok:	xfTemp ← T;
PCokx:	T ← xfCount, LoadPage[7];
	LOCAL ← T, gotop[XferGO];

*Control Link is a procedure descriptor
XferType1:	xfCount ← T, AT[xftype,1];  *save descriptor
	T ← xfgft;
	T ← (ldf[xfCount,0,11]) + (T);
	T ← (ldf[xfCount,0,11]) + (T); *  2*gfi + gft
	PFetch2[MDS,xfTemp], call[EXMemStat];  *Fetch G and the entry vector offset
	T ← xfTemp; *New G
	GLOBAL ← T, skip[ALU#0];
	T ← sUnbound, goto[StashMX];  *Trap
	PFetch4[MDS, IBUF]; *Fetch the global frame overhead
	T ← xfTemp1, task;  *Calculate the entry vector index
	xfCount ← (ldf[xfCount,11,5]) + (T) +1;
	xfCount ← lsh[xfCount,1], call[LoadC];  *  2*evi + 2
	xfGfiWord ← T, LoadPage[7];
	T ← xfCount, gotop[.+1];

	OnPage[7];
	PFetch2[CODE,xfTemp];  *fetch PC and FSI
LFCEntry:	T ← ldf[xfTemp1,10,10], goto[Alloc]; *Get a frame
AllocRetx:	PStore4[MDS, GLOBAL]; *Initialize frame
	xfTemp ← lsh[xfTemp,1]; *Form byte PC
	MNBR ← LOCAL, LOCAL ← t, NoRegILockOK, skip[MB];
	T ← MNBR, call[Free];
XferGO:	PCF ← xfTemp, TASK; *Enter here from XferType0
	MemStat ← XferFixup;
	T ← rsh[xfTemp,1];
	PFetch4[CODE,IBUF];
	PC ← T; *bypass kludge
	PC ← (PC) and not (3c);
	PFetch4[LOCAL,LocalCache0,4];
:IF[AltoMode]; ****************************************
	nop;	* allow page fault to happen before load page
	t←CODEhi, LoadPage[0];
	PChi←t, call[SwapBytes];
:ELSE; ************************************************
	t←CODEhi;
	PChi←t;
:ENDIF; ***********************************************
	T ← xfBrkByte;
	MemStat ← Normal, goto[DoBB, ALU#0];
DispMan:	T ← NextData[IBUF]; *must execute one instruction without interrupts
	xfBrkByte ← T, skip[ALU#0]; *skip over NOPs
	goto[DispMan];
DoBB1:	xfBrkByte ← (xfBrkByte) or (40400c);
DMx:	xfBrkByte ← lcy[xfBrkByte,2];
	APC&APCTask ← xfBrkByte;
	xfBrkByte ← zero, RETURN;

DoBB:	lu ← NextData[IBUF], Call[DoBB1]; *skip the instruction in IBUF

P7Tail:	lu ← NextInst[IBUF], AT[P7TailLoc];
P7Tailx:	MemStat ← Normal, NIRET;


*Control link is indirect
XferType2:	PFetch1[MDS,RTEMP], AT[xftype,2];
	call[xfRet];
	Dispatch[RTemp,16,2];
	T ← RTEMP, disp[XferType0];

*Control link is unbound whatsis
XferType3:	T ← sUnbound, goto[StashMX], AT[xftype,3];

*Load the C register from the global frame information in IBUF..IBUF2
LoadC:	T ← IBUF1, skip[REven];
	T ← sCSegSwappedOut, goto[StashMX];
	CODE ← T;
	lu ← ldf[IBUF2,0,10];
	lu ← ldf[IBUF2,10,2], skip[ALU=0]; *Check for short C
	T ← MDShi, goto[SetCODEhi];  *and use MDShi if so
	T ← IBUF2, skip[ALU=0];  *check for code out of bounds
	T ← IBUF2 ← (IBUF2) or (100c); *and set bits 1 and 9 if so
	T ← (lsh[IBUF2,10]) or (T);
SetCODEhi:	CODEhi ← T;
	T ← IBUF, return; *return GfiWord in T

	OnPage[7];
*Enter from @ALLOC or XferType1 with FSI in T.  Returns frame in T.
*Return to PushTP7 if MemStat.0 = 1, else to AllocRetx.
Alloc:
	T ← (lsh[R400,1]) + (T);
	PFetch1[MDS,xfFrame], task;	*the head of the list (can't fault)
	xfRSAV ← T;
	lu ← ldf[xfFrame,16,1], skip[ROdd];
	T ← xfFrame, dblgoto[FrType0, FrType2, ALU=0];
	T ← xfFrame, dblgoto[FrType1, FrType3, ALU=0];

FrType0:	PFetch1[MDS, RTemp1];	*Fetch Frame[0]
	T ← xfRSav;
	PStore1[MDS, RTemp1];	*Store into head of list
	T ← xfFrame;
	MemStat ← (MemStat) and not (100000c), dblgoto[AllocRetx, PushTP7, R>=0];

FrType2:	T ← rsh[xfFrame,2], goto[Alloc];	*Indirect
FrType3:	T ← rsh[xfFrame,2], goto[Alloc];	*Indirect

FrType1:	MemStat ← (MemStat) and not (100000c), goto[XATrap, R>=0];  *Trap - check for call from @ALLOC
	xfATPreg ← lsh[xfATPreg,2], call[SavePCInFrame]; *call was from @ALLOC
	LoadPage[xfPage1];
	RTEMP ← sAllocListEmpty, goto[QTrap]; *don't free frame

XATrap:	
	T ← xfMX;  *call was from Xfer - check for LFC
	xfATPreg ← T, goto[LFCAlloc,ALU=0];
	LoadPage[xfPage1], goto[DoAllocTrap];
LFCAlloc:	xfCount ← lsh[xfCount,1]; *Trap from LFC.  Fab procedure descriptor
	xfCount ← (xfCount) - (3c);
	T ← (xfGfiWord) and not (177c);
	T ← (xfCount) + (T); * + is important - don't use OR
	xfATPreg ← T, LoadPage[xfPage1];
DoAllocTrap:  RTEMP ← sAllocListEmpty, dblgoto[QTrap, QTrapF, MB];


*SUBROUTINE Free frees the frame in T.
Free:	T ← (AllOnes) + (T);
	PFetch1[MDS, xfFSI];	*get the frame's FSI
	xfFrame ← T, usectask; *bypass kludge - depends on MDS being 0
	T ← APC&APCTask, TASK;
	xfRLink ← T;
	xfFSI ← T ← (xfFSI) + (xfAV);
	PFetch1[MDS, RTemp1]; *Fetch list head
	T ← xfFrame ← (xfFrame) + 1;
	PStore1[MDS, RTemp1], task;	*Store head into frame
	T ← 100c; *Set MB ( => free finished)
	T ← xfFSI, SAluf ← T, task;
	PStore1[MDS, xfFrame];	*Store frame into head
	APC&APCTask ← xfRLink, goto[P7Ret];

	OnPage[xfPage1];
SaveState:	* usectask in calling instruction
	T ← APC&APCTASK, call[SaveRLink];	*save link in rlink
	T ← (xfTemp) + (11c);
	Pstore1[MDS, LOCAL], call[sv377];
	T ← (stkp) xor T;	* true stack pointer to T
	xfTemp2 ← T;
	T ← (xfTemp) + (10c), task;
	Pstore1[MDS, xfTemp2];
	T ← (xfTemp2) - (7c);
	xfTemp1 ← 10c, skip[carry];
	  xfTemp1 ← (xfTemp1) + T + 1;	* stack depth + 2 (8+(d-7)+1)
	stkp ← xfTemp1, T ← (xfTemp1) - 1;
svloop:	call[svpop];
	T ← (stkp) xor T;	* true stack pointer to T
	T ← (AllOnes) + T, goto[svloop, alu#0]; * T ← offset in saved stack
	apc&apctask ← xfRlink, goto[xfRet];

svpop:	T ← (xfTemp) + T;
	Pstore1[MDS, Stack];
sv377:	T ← (377c), return;

LoadStateNF: T ← 100c; *Entry from Process mechanism and MStart. Ensure no frame freeing.
	SAluf ← T; 
LoadState:
	T ← (xfTemp) + (10c);
	Pfetch1[MDS,xfBrkByte],  call[xfRet];
	T ← (xfTemp) + (11c);
	Pfetch1[MDS,xfMX];
	NWW ← (NWW) and not (100000c);
	T ← (xfTemp) + (12c);
	Pfetch1[MDS,xfMY], task;
	stkp ← RZero;
	T ← (xfBrkByte) and (17c);
	IBuf ← T;	* stack depth saved for stkp below
	xfTemp1 ← 10c;
	T ← (IBuf) - (7c);	* check for 7 or 8, T ← d-7
	xfBrkByte ← rsh[xfBrkByte,10], skip[carry];
	  xfTemp1 ← (xfTemp1) + T + 1;	* stack depth+2 (8+(d-7)+1)
	xfTemp2 ← T ← ZERO, call[ldloop];

ldloop: lu ← (xfTemp1) - T;
	T ← (xfTemp) + T, goto[ldpush, alu#0];
	stkp ← IBuf, goto[Xfer];

ldpush:	Pfetch1[MDS, Stack];
	xfTemp2 ← T ← (xfTemp2) + 1, return;  * return to ldloop

* In general, we want to do the FreeSub after all possible Xfer page faults
*  can occur, but before all other traps.

* UnBound, & cSwappedOut Traps come here
StashMX:	RTEMP ← T, TASK;  * RTEMP holds SD index (through Free)
	T ← xfMX;
	xfOTPreg ← T, dblgoto[QTrap,QTrapF, MB];

* XferTrap, AllocTrap, & Control Traps come here if they need to free the frame, else to QTrap
QTrapF:	T ← LOCAL, call[FreeX];

QTrap:	RTEMP ← (RTEMP) + (xfav);
	T ← (RTEMP) + (xfsdoffset);
	pfetch1[MDS,xfMX], goto[Xfer];

FreeX:	LoadPage[7];
	gotop[Free];

	onpage[opPage3];

*Start from Nova.
MStart:
	xfTemp ← T; *Pointer to State for LoadState
	T ← MDShi; *Initialize some Mesa Emulator registers
	GLOBALhi ← T;
	GLOBAL ← 1c; *Clobber G so that C will always be reloaded at the first Xfer
	LOCALhi ← T;
	MEMSTAT ← T ← 0c;
	xfMX ← 1c;
	NWW ← T; *Wipe out pending interrupts
	TickCount ← 3c, call[FFaultStack];
	Stack ← (Stack) or (1c); * FFAULT ← "trap on page fault"
	xfXTSReg ← T, loadpage[xfPage1];
	Local ← 0c, gotop[LoadStateNF];

FFaultStack:	RTEMP ← FFaultAdd;
	Stkp ← RTEMP, return;

SavePCInFrame:
	T ← CODE;	*CODEhi and PChi are equal, so we only need to worry about the low word
	T ← (PC) - (T); *15 bits, since code segments are < 32k.
:IF[AltoMode]; **************************************
	T ← ldf[GetRSpec[127], 14,3] + T, skip[R even];
	RTemp1 ← (Zero) - T, goto[StorPC];
	RTemp1 ← T, goto[StorPC];
:ELSE; **********************************************
	RTemp1 ← T;
	T ← PCFreg;
	RTemp1 ← (lsh[RTemp1,1]) + (T); *byte PC (relative to C) of the instruction to be executed
*when this frame next runs.
:ENDIF; *********************************************

StorPC:	Pstore1[LOCAL, RTEMP1, 1];
	T ← 100c; *Set MB
	T ← LOCAL, SALUF ← T;
	xfMY ← T, return;

GetLink:	lu ← xfGfiWord , goto[framelink,R even]; *xfGfiWord was set up by LoadC when this
*frame became current.
codelink:	PFETCH1[CODE,RTEMP], return;
framelink:	PFETCH1[GLOBAL,RTEMP], return;

	onpage[opPage3];

MesaRefill7:	gotop[MesaRefill], Pfetch4[PC,IBUF,4], at[3777];


*EFC0 - EFC16
@EFC0:	T ← (1c) , goto[efcr] , OPCODE[300];
@EFC1:	T ← (2c) , goto[efcr] , OPCODE[301];
@EFC2:	T ← (3c) , goto[efcr] , OPCODE[302];
@EFC3:	T ← (4c) , goto[efcr] , OPCODE[303];
@EFC4:	T ← (5c) , goto[efcr] , OPCODE[304];
@EFC5:	T ← (6c) , goto[efcr] , OPCODE[305];
@EFC6:	T ← (7c) , goto[efcr] , OPCODE[306];
@EFC7:	T ← (10c) , goto[efcr] , OPCODE[307];
@EFC8:	T ← (11c) , goto[efcr] , OPCODE[310];
@EFC9:	T ← (12c) , goto[efcr] , OPCODE[311];
@EFC10:	T ← (13c) , goto[efcr] , OPCODE[312];
@EFC11:	T ← (14c) , goto[efcr] , OPCODE[313];
@EFC12:	T ← (15c) , goto[efcr] , OPCODE[314];
@EFC13:	T ← (16c) , goto[efcr] , OPCODE[315];
@EFC14:	T ← (17c) , goto[efcr] , OPCODE[316];
@EFC15:	T ← (20c) , goto[efcr] , OPCODE[317];
@EFCB:	T ← CNextData[IBuf] + 1 , call[efcr], OPCODE[320];

efcr:
	T ← (zero) - T , call[GetLink];
	T ← RTEMP, goto[sfcr];


*LFC1 - LFC16
@LFC1:	GOTO[lfcr] , T ← xfCount ← ( 4C)  , OPCODE[321];
@LFC2:	GOTO[lfcr] , T ← xfCount ← ( 6C)  , OPCODE[322];
@LFC3:	GOTO[lfcr] , T ← xfCount ← (10C)  , OPCODE[323];
@LFC4:	GOTO[lfcr] , T ← xfCount ← (12C)  , OPCODE[324];
@LFC5:	GOTO[lfcr] , T ← xfCount ← (14C)  , OPCODE[325];
@LFC6:	GOTO[lfcr] , T ← xfCount ← (16C)  , OPCODE[326];
@LFC7:	GOTO[lfcr] , T ← xfCount ← (20C)  , OPCODE[327];
@LFC8:	GOTO[lfcr] , T ← xfCount ← (22C) , OPCODE[330];
@LFC9:	GOTO[lfcr] , T ← xfCount ← (24C) , OPCODE[331];
@LFC10:	GOTO[lfcr] , T ← xfCount ← (26C) , OPCODE[332];
@LFC11:	GOTO[lfcr] , T ← xfCount ← (30C) , OPCODE[333];
@LFC12:	GOTO[lfcr] , T ← xfCount ← (32C) , OPCODE[334];
@LFC13:	GOTO[lfcr] , T ← xfCount ← (34C) , OPCODE[335];
@LFC14:	GOTO[lfcr] , T ← xfCount ← (36C) , OPCODE[336];
@LFC15:	GOTO[lfcr] , T ← xfCount ← (40C) , OPCODE[337];
@LFC16:	GOTO[lfcr] , T ← xfCount ← (42C) , OPCODE[340];

@LFCB:	T ← NextData[IBuf] , OPCODE[341];
	xfcount ← (zero) + (T) + 1;
	T ← xfcount ← lsh[xfcount,1] , goto[lfcr];

lfcr:	PFetch2[CODE,xfTemp] , call[SavePCInFrame];
	xfXTSreg ← rsh[xfXTSreg,1], skip[ROdd];
	xfMX ← zero, goto[LFCEntry]; *in XferType1
*Cause trap with reason of 400, parameter of xfCount
	xfXTSreg ← 400c;
	T ← xfCount, goto[XTrap];

*SFC
@SFC:	T ← stack&-1 , OPCODE[342];
sfcr:	xfMX ← T , call[SavePCInFrame];
	loadpage[xfpage1];
	goto[Xfer];

*RET
@RET:	PFetch1[LOCAL,xfMX,2], OPCODE[343];  *fetch return link
*The following 4 instructions save L and G in LP and LPhi so that if a control
*trap occurs on a RET, the previous state can be obtained.
*	T ← LOCAL; 
*	bbSrcStartBitLo ← T;  *RM 12
*	T ← GLOBAL;
*	bbSrcStartBitHi ← T;  *RM 13
	xfXTSreg ← rsh[xfXTSreg,1], goto[RetTrap,ROdd];
	T ← RZero, LoadPage[xfPage1];
	xfMY ← SAluf ← T, gotop[XferNTC]; *MB=0  => free frame

RetTrap:	T ← 100c;
	SAluf ← T; *If RET traps, the frame is NOT freed
	T ← (LOCAL) + (6c);
	xfXTSreg ← 1000c;
XTrap:	xfXTPreg ← T, LoadPage[xfPage1];
	RTEMP ← sXferTrap, dblgotop[QTrap, QTrapF, MB];

*LLKB
@LLKB:	T ← NextData[IBuf] , OPCODE[344];
	call[GetLink] , T ← (zero) - (T) - 1;
	T ← RTEMP, goto[PushTP7];

*PORTO
@PORTO:	call[SavePCInFrame] , OPCODE[345];
	T ← stack&-1;
	task, xftemp ← T;
	pstore1[MDS,xfMY];
	task,T ← (zero) + (T) + 1;
	pfetch1[MDS,xfMX];
	T ← xftemp , loadpage[xfpage1];
	goto[Xfer] , xfMY ← T;

*PORTI
@PORTI:	lu ← xfMY , OPCODE[346];	
	goto[portinz,alu=0] , T ← xfMX;
	pstore1[MDS,Rzero],call[P7Ret];
	T ← (xfMX) + 1;
portinz:
	PSTORE1[MDS,xfMY];
	PFetch4[LOCAL,LocalCache0,4], goto[P7Tail]; *in case the port was in the active frame

*KFCB
@KFCB:
	T ← NextData[IBuf] , OPCODE[347];
kfcr:
	RTEMP ← T, call[SavePCInFrame], at[KFCRLoc];
	loadpage[xfpage1];
	goto[QTrap];

*DESCB
@DESCB:
	T ← xfGfiWord, OPCODE[350];
	RTEMP ← T;
descbcom:	T ← NextData[IBuf];
	RTEMP1 ← t;
	t ← (RTEMP) and not (177c);
	t ← (lsh[RTEMP1,1]) + (t) + 1;
	goto[P7Tail],stack&+1 ← t;

*DESCBS
@DESCBS:
	T ← (STACK&-1) + (xfgfioffset), OPCODE[351];
	pfetch1[MDS,RTEMP], goto[descbcom];



*BLT
@BLT:	LP ← 0c, OPCODE[352];
	LoadPage[xfpage1];
	T ← MDShi, gotop[.+1];
	OnPage[xfpage1];
BLTcom:	LPhi ← T;
	* fixup: fetch => count + 1; store => source-1, dest-1, count+1
	MemStat ← BltFixup,call[BLTx]; * set return address to BLTloop;

BLTloop:	lu ← stack&-1;
	goto[BLTdone,alu=0] , T ← stack&+1; *get source, point to count
	stack ← (stack) - 1; *decrement count
	pfetch1[LP,RTEMP];
	stack&+1; *point to dest
	T ← stack&-2; *get dest, point to source
	pstore1[MDS,RTEMP];
	stack ← (stack) + 1;*increment source
	Stack&+2;
	Stack ← (Stack) + 1, goto[BLTint, IntPending]; *increment dest
BLTx:	stack&-1, return; *point to count, return to BLTloop

BLTdone:	stack&-2;
BLTdonex:	PFetch4[LOCAL,LocalCache0,4];
	LoadPage[7];
	goto[P7Tail],MemStat ← Normal;

BLTint:	T ← (RZero) + 1;
BLTstop:	LoadPage[opPage0];
	PFetch4[LOCAL,LocalCache0,4], gotop[NOPint];

*BLTL
@BLTL:	T ← (Stack&-1) and (377c), OPCODE[353];
	LPdesthi ← T, loadpage[xfpage1];
	T ← LPdesthi ← (lsh[LPdesthi,10]) + (T) + 1, gotop[.+1];

	OnPage[xfpage1];
	LPdesthi ← (fixVA[LPdesthi]) OR T;
	T ← Stack&-2, loadpage[5];
	LPdest ← T, callp[StackLP];
	RTEMP1 ← (Zero);
	MemStat ← BltLFixup; * fixup: source+T, dest+T, count+1
	Stack&+3, call[BLTLloop];		* point to count

BLTLloop:	lu ← Stack;		* read count, point to source lo
	T ← RTEMP1, goto[BLTLdone,alu=0];
	pfetch1[LP,RTEMP];
	Stack ← (Stack) - 1;	* decrement count
	RTEMP1 ← (RTEMP1) + 1;	* increment offset
	pstore1[LPdest,RTEMP];
	goto[BLTLint, IntPending];
	return;	* goes to BLTLloop

BLTLdone:
	stack&-3, goto[BLTdonex];

BLTLint:
	Stack&-2;
	call[BLTLbump];	* wait for page fault before updating stack
	Stack&+2,call[BLTLbump];
	T ← (RZero) + 1, goto[BLTstop];

BLTLbump:
	Stack ← (Stack) + (T) + 1;
	Stack&+1, FreezeResult;
	Stack ← (Stack) + 1, UseCOutAsCIn, Return;

*BLTC
@BLTC:	T ← CODE, OPCODE[354];
	LP ← T, loadpage[xfpage1];
	T ← CODEhi, gotop[BLTcom];

*BLTCL
@BLTCL:	T ← sUnimplemented, goto[kfcr], Opcode[355];


*ALLOC
@ALLOC:
	MemStat ← 100000c, OPCODE[356];
	T ← stack&-1;
	xfATPreg ← T, goto[Alloc]; *set up in case trap occurs

PushTP7:	goto[P7Tail], stack&+1 ← t;
P7Ret:	return;


*FREE
@FREE:
	T ← Stack&-1, call[Free], OPCODE[357];
	lu ← NextInst[IBUF], call[P7Tailx];


*Increment Wakeup Disable Counter (Disable Interrupts)
@IWDC:	goto[P7Tail],xfwdc ← (xfwdc) + 1 , OPCODE[360];

*Decrement Wakeup Disable Counter (Enable Interrupts)
@DWDC:
	TASK, T ← (R400) or (52c), OPCODE[361];
	PFetch1[MDS,xftemp];
	T ← xftemp;
	NWW ← (NWW) or (T);
	RTEMP ← pRSImage, goto[DWDCnone, alu=0];	* see if any interrupts
	T ← (GetRSpec[103]) xor (377c);	* read Stkp
	Stkp ← RTEMP, RTEMP ← T, NoRegILockOK;
	T ← Stack ← (Stack) or (IntPendingBit); * set IntPending
	Stkp ← RTEMP, RS232 ← T;
DWDCnone:	xfwdc ← (xfwdc) - 1, goto[DispMan];

*STOP
@STOP:	NWW ← (NWW) or (100000c), call[SavePCInFrame], OPCODE[362];
	T ← currentstate;
	pfetch1[MDS,xftemp];
	loadpage[xfpage1];
	usectask,callp[SaveState];
	T ← 1c, call[FFaultStack];
	Stack ← (Stack) and not (T), loadpage[0]; * FFAULT ← "crash on page fault"
	PC ← StopStopPC, gotop[StartNova];

*CATCH
CATCH:	lu ← NextData[IBUF],call[P7Tail], Opcode[363];

*MISC - extended opcodes accessed by dispatching on alpha
@MISC:	T ← NextData[IBUF], opcode[364];
	LoadPage[xfPage1], RTEMP ← T;
	gotop[.+1], Dispatch[RTEMP, 14, 4];

	OnPage[xfPage1];
	Disp[@ASSOC];		* dispatch on second byte

* Associate - TOS contains map entry, (TOS-1) contains VP which is to get it.
@ASSOC:	T ← (Stack&-1) and not (100000C), AT[MiscDisp,0];
	Call[MapLP], xBuf ← T;
ASSOC1:	XMap[LP, xBuf, 0], goto[MiscTail];

* Set Flags
@SETF:	T ← (Stack&-1) and not (100000C), AT[MiscDisp,1];
	Call[MapLP], xBuf ← T;
	XMap[LP, xBuf, 0];
	T ← LSH[xBuf3,10];		* Put flags,,card,blk0 in left byte
	T ← xBuf1 ← (RHMASK[xBuf1]) OR (T); * blk1,rowaddr in low byte
	T ← (ZERO) or not (T);		* push old flags & page
	Stack&+1 ← T;			* push old flags & page
	lu ← (ldf[xBuf3,11,3]) -1; 	* =0 if map entry = VACANT
	goto[.+2,ALU#0], xBuf ← (xBuf) and (70000C);	* isolate new flags, ignore LogSE
	goto[ASSOC1], xBuf ← T;	* Vacant entry, use old flags, oldpage
	T ← (Stack) and not (170000C);	* Get old page number
	goto[ASSOC1], xBuf ← (xBuf) or (T);	* new flags, old page

*Subroutine MapLP creates a base register pair from a virtual page number for the Map opcodes.
MapLP:	T ← LSH[Stack,10];
	LP ← T;		* Set low Base
	T ← LHMask[Stack&-1];
	goto[xfRET,ALU>=0], LPhi ← T;	* Set high byte of high base
	LPhi ← (LPhi) OR (40000C), goto[xfRET];	* set bit 1 if 0 is set.



* Read & Write Ram format: stack=40:43,,addr, (stack-1)=40:43, (stack-2)=0:17, (stack-3)=20:37.
@ReadRam:	T ← LDF[Stack&-1, 4, 14], AT[MiscDisp,2];	* get address
	RTEMP ← T;
	call[CSRead], T ← 1C;	* read 20:37
	call[CSRead], T ← 0C;	* read 0:17 
	call[CSRead], T ← 3C;	* read 40:43
	T ← RTEMP; 
	GOTO[MiscTail], Stack ← (LSH[Stack, 14]) or (T);

* Subroutine CSRead reads control store for ReadRam opcode.
CSRead:	APCTASK&APC ← RTEMP;
	ReadCS;
	T ← CSData, AT[MiscDisp,22]; *successor of CSOp must be even
	return, Stack&+1 ← T;



MC[VersionID,0]; *Checks compatibility with LRJ'd code.

@LoadRamJ:
	T ← (Stack&-1) xor (1C), AT[MiscDisp,3];
	RTemp1←T, LoadPage[opPage1];	* save bits, jump complemented
	T ← (Stack&-1) and (377C), CallP[StackLPx];
	PFetch1[LP,RTemp,0], Call[MiscRet];
	LU ← (RTemp) xor (VersionID);
	T ← sUnimplemented, Goto[MiscTrap,Alu#0];
	T ← (SStkP&NStkP) xor (377C);
	RTemp ← FFaultAdd;
	StkP ← RTemp, RTemp ← T, NoRegILockOK;
	Stack ← (Stack) and not (1C);
	RTemp1 ← T ← (RTemp1) and (1C); * get jump flag (1 => no jump)
	xfTemp1 ← T, LoadPageExternal[LRJpage]; * allow tasking if not jumping
	StkP ← RTemp, GotoExternal[LRJStart];

MiscRet:	Return;

MiscTrap:	loadpage[OpPage3];
	gotop[kfcr];

		OnPage[xfPage1];

* Opcodes for Mesa Input/Output.  Stack[0:7]=XXX, Stack[10:13]=task no.,
*    Stack[14:17]=I/O register number.

@INPUT:	T ← Stack&-1, AT[MiscDisp,5];
	goto[MiscTail],Input[Stack];

@OUTPUT:	T ← Stack&-1, AT[MiscDisp,6];
	goto[MiscTail], Output[Stack];


*SetMaintenancePanel opcode
* just put value on stack
@SetMP:	T ← stack&-1, loadpage[0], at[MiscDisp, 10];
	callp[PNIP];
	lu ← NextInst[IBUF], call[MiscTailx];


*Read realtime clock (push[RM325]; push[MM430];
@RCLK:	loadpage[XMiscPage], at[MiscDisp, 11];
	T ← (R400) OR (30c), callp[MXRClk];
	Stack&+1 ← T; *Push[RM 325]
	T ← RTemp, goto[MiscPushT]; *Push [VM 430];

*Read printer
@RPRINTER:	T ← PRINTER, at[MiscDisp, 12];
	Stack&+1 ← T, goto[MiscTail];

*Write printer
@WPRINTER:	PRINTER ← Stack&-1, goto[MiscTail], AT[MiscDisp,13];

@XferL:	lu ← MNBR ← Stack&-1, AT[MiscDisp,14]; *new high base (8 bits)
	T ← Stack&-1, loadpage[opPage3];	*dest link
	xfMX ← T, call[SavePCInFrame];
	Stack&+1 ← T, loadpage[XMiscPage]; *push L (returned by SavePCInFrame)
	T ← MNBR, callp[SetMBases]; *Switch
	Stack&+1 ← T, goto[Xfer]; *Push old base

WMDS:	loadpage[XMiscPage], AT[MiscDisp,15];
	T ← Stack&-1, callp[SetMBases];
MiscTail:	lu ← NextInst[IBUF];
MiscTailx:	NIRET;

OnPage[XMiscPage];

SetMBases:	MNBR ← MDShi, MDShi ← T, NoRegILockOK; *Swap old and new bases
	MDShi ← T ← (lsh[MDShi, 10]) or (T); *make high and low bytes equal
	Globalhi ← T;
	LOCALhi ← T, Goto[SetIOBases];	*In Misc.Mc

SetTime:	loadpage[0], AT[MiscDisp,16];
	T ← Stack&-1, callp[SetClrRS232];
	skip[TimeOut];
	Stack&+1 ← 0c, goto[MiscTail];
	Stack&+1 ← 100000c, goto[MiscTail];

	OnPage[0];
SetClrRS232:
	RTemp ← T;
	RTemp1 ← pRSImage;
	T ← (GETRSPEC[103]) xor (377c);
	Stkp ← RTemp1, RTemp1 ← T, NoRegILockOK;
	T ← RTemp, dblgoto[SetIt,ClearIt,R<0];
SetIt:	Stack ← T ← (Stack) or (T), goto[SCRet];
ClearIt:	Stack ← T ← (Stack) and not (T), goto[SCRet];
SCRet:	Stkp ← RTemp1, RS232 ← T, return;

SetDefaultPartition: loadpage[XMiscPage], AT[MiscDisp,17];
	T ← Stack&-1, callp[MXPar];

MiscPushT:	lu ← NextInst[IBUF];
	Stack&+1 ← T, NIRET;


*BitBLT
BitBLT:	T ← Stack0, LoadPage[bbPage], Opcode[365];
	AC2 ← T, GotoP[MesaBitBLT];

*STARTIO
@STARTIO:	T ← stack&-1, LoadPage[EEPage], Opcode[366];
	goto[EESIO], RTEMP1 ← 1c; *RTEMP1 is the return indicator (Mesa/Nova)

*JRAM
@JRAM:	APCTask&APC ← Stack&-1, Goto[P7Ret], Opcode[367]; *Nova-flavored JMPRAM

*DST
@DST:	T ← NextData[IBuf] , Opcode[370];
	t ← (LOCAL) + (t) ,loadpage[xfpage1];
	usectask,call[SaveState] , xftemp ← t;
	T ← (xftemp) + (12c), TASK;
	Pstore1[MDS, xfMY];
RefillLocalCache:	PFetch4[LOCAL,LocalCache0,4], goto[P7Tail];

*LST
@LST:	T ← NextData[IBuf], Opcode[371];	
	call[SavePCInFrame],xfTemp ← T;* NextData must be before SavePC call 
	GOTO[LSTFgo], T ← (xfTemp);

*LSTF
@LSTF:	T ← RZero, Opcode[372];
	T ← NextData[IBUF], Saluf ← T;  *MB = 0  => free frame
LSTFgo:	T ← (LOCAL) + (T), LoadPage[xfpage1];
	GOTOp[LoadState], xfTemp ← T;	* xfTemp is pointer to saved state.

*WR
@WR:	T ← NextData[IBuf] , Opcode[374];
	xftemp ← T , loadpage[xfpage1];
	dispatch[xftemp,16,2];
	onpage[xfpage1];
	disp[xfwr] , T ← stack&-1;
xfwr:	goto[MiscTail] , xfwdc ← T ,    at[xfwrtab,1];
	goto[MiscTail] , xfXTSreg ← T , at[xfwrtab,2];
:IF[AltoMode];
:ELSE; **********************************************
	MDShi ← T , at[xfwrtab,3];
	T ← MDShi ← (LSH[MDShi,10]) + (T);
	LOCALhi ← T;
	GLOBALhi ← T, goto[MiscTail];
:ENDIF; *********************************************
*RR
@RR:	T ← NextData[IBuf] , Opcode[375];
	xftemp ← T , loadpage[xfpage1];
	dispatch[xftemp,15,3];
	onpage[xfpage1];
	LoadPage[4], disp[xfrr];
xfrr:	gotop[PushT], T ← xfwdc ,    at[xfrrtab,1];
	gotop[PushT], T ← xfXTSreg , at[xfrrtab,2];
	gotop[PushT], T ← xfXTPreg , at[xfrrtab,3];
	gotop[PushT], T ← xfATPreg , at[xfrrtab,4];
	gotop[PushT], T ← xfOTPreg , at[xfrrtab,5];
	gotop[PushT], T ← MDShi , at[xfrrtab,6];

*BRK
@BRK:	t ← zero , goto[kfcr] , Opcode[376];

*Cause pagefault trap - done only by fault, is not supposed to be encountered ininstruction stream.
TrapFlap:	T ← (PCFReg)-1, Opcode[377];	* back up PCF by one
	RTEMP ← T, LoadPage[FaultPage1];
	PCF ← RTEMP, gotop[StartMemTrap];

*Unused opcodes on page 7
	T ← sUnimplemented, goto[kfcr], Opcode[373];

:END[MesaX];