mirror of
https://github.com/livingcomputermuseum/Darkstar.git
synced 2026-02-28 17:39:41 +00:00
39 lines
38 KiB
Plaintext
39 lines
38 KiB
Plaintext
head 1.1;
|
|
branch 1.1.1;
|
|
access ;
|
|
symbols start:1.1.1.1 Xerox:1.1.1;
|
|
locks ; strict;
|
|
comment @# @;
|
|
|
|
|
|
1.1
|
|
date 2001.08.12.22.22.25; author freier; state Exp;
|
|
branches 1.1.1.1;
|
|
next ;
|
|
|
|
1.1.1.1
|
|
date 2001.08.12.22.22.25; author freier; state Exp;
|
|
branches ;
|
|
next ;
|
|
|
|
|
|
desc
|
|
@@
|
|
|
|
|
|
|
|
1.1
|
|
log
|
|
@Initial revision
|
|
@
|
|
text
|
|
@{File name: Process.mc
|
|
Description: Dandelion Process Microcode,
|
|
Author: JGS ,
|
|
Created: February 13, 1981 1:12 PM,
|
|
DEG 1-Sep-84 19:44:17 add copyright notice.
|
|
RXJ 30-Aug-83 9:03:43 new instruction set
|
|
AXD 5-Aug-83 16:04:37 new instruction set
|
|
JGS February 24, 1982 add Set Process Priority inst, bum 1 uinst
|
|
JGS January 18, 1982 12:30 PM fix ibempty, pccross, interrupt, no switch
|
|
JGS 8-Dec-81 20:54:29 Correct PC/Stack fixup on faults
|
|
JGS November 17, 1981 10:34 AM New instruction set
|
|
JGS March 26, 1981 10:43 AM to fix timing restrictions
|
|
JGS March 26, 1981 3:53 PM Change Wait to check condition.abortable
|
|
}
|
|
|
|
{ Copyright (C) 1981, 1982, 1983 by Xerox Corporation. All rights reserved.}
|
|
|
|
{*****************************************************************************
|
|
Definitions
|
|
*****************************************************************************}
|
|
|
|
Set[L2.Pop0IncrX, 0 {00xx}]; {also in Jump.mc}
|
|
|
|
{Offsets and Magic locations}
|
|
Set[PSB.link, 0];
|
|
Set[PSB.link.preempted, 1];
|
|
Set[PSB.link.permanent, 2];
|
|
Set[PSB.link.enterfailed, 4];
|
|
Set[PSB.flags, 1];
|
|
Set[PSB.flags.waiting, 2];
|
|
Set[PSB.context, 2];
|
|
Set[PSB.timeout, 3];
|
|
Set[PSB.mds, 4];
|
|
Set[PSB.SIZE, 8];
|
|
Set[Condition.wakeup, 1];
|
|
Set[Condition.abortable, 2];
|
|
Set[Monitor.lock, 1];
|
|
Set[FaultQueue.condition, 1];
|
|
Set[PDAHi, 1];
|
|
Set[PDA.ready, 0];
|
|
Set[PDA.count, 1];
|
|
Set[PDA.state, 10'b];
|
|
Set[PDA.interrupt, 20'b];
|
|
Set[PDA.lastCV, 36'b];
|
|
Set[PDA.fault, 60'b];
|
|
Set[StartPSB, 100'b];
|
|
Set[StartPSBMinus1Times2, Lshift[Sub[StartPSB,PSB.SIZE],1]];
|
|
|
|
{
|
|
uPFlags holds opcode dispatch values and general flags. Its encoding:
|
|
Bit Meaning
|
|
8 0: no Requeue, 1: Requeue occured
|
|
9 Interrupt
|
|
10 Process Trap
|
|
11 PCValid
|
|
12-15 Opcode dispatch
|
|
}
|
|
|
|
{Flag values}
|
|
Set[pME, 10]; Set[pMELoc, 0];
|
|
Set[pMR, 1];
|
|
Set[pMX, 12]; Set[pMXLoc, 2]
|
|
Set[pMW, 9];
|
|
Set[pNC, 4];
|
|
Set[pBC, 5];
|
|
Set[pREQ, 8];
|
|
Set[pSPP, 0A];
|
|
Set[pInt, 47]; Set[pIntLoc, 7]; {Also in Dandelion.df}
|
|
Set[pIdle, 77]; {pIdle MOD 16 = pInt MOD 16 = pIntLoc}
|
|
Set[pFault, 3];
|
|
Set[pFaultPC, 0D3];
|
|
Set[pFaultNoPC, 0E3];
|
|
Set[pTrap, 20];
|
|
|
|
Set[cPCInvalid, 10];
|
|
Set[cRequeueFlag, 80];
|
|
|
|
Set[L3.Normal, 0];
|
|
Set[L3.Interrupt, 1];
|
|
Set[L3.Fault, 3];
|
|
|
|
Set[L0.SrcOK, 0];
|
|
Set[L0.SrcNull, 1];
|
|
|
|
Set[L2.Fault, 1];
|
|
Set[L2.Trap, 0];{also L2.MR4 in QRead}
|
|
|
|
MacroDef[PRr, at[#1,10,PRRets]];
|
|
MacroDef[PMRr, at[#1,10,PMRRets]];
|
|
MacroDef[PFr, at[#1,10,PFRets]];
|
|
MacroDef[PWr, at[#1,10,PWRets]];
|
|
MacroDef[QRr, at[#1,10,QRRets]];
|
|
MacroDef[QWr, at[#1,10,QWRets]];
|
|
MacroDef[NQr, at[#1,10,NQRets]];
|
|
MacroDef[CQr, at[#1,10,CQRets]];
|
|
|
|
{PRead Returns}
|
|
Set[L2.LP0, 0];
|
|
Set[L2.MR3, 1];
|
|
Set[L2.NQ0, 3]; {also QRead}
|
|
Set[L2.DQ2, 4];
|
|
Set[L2.NQ1, 5];
|
|
Set[L2.MW2, 6]; {also PFetch, PWrite, QRead}
|
|
Set[L2.WH2, 7];
|
|
Set[L2.NQ3, 8];
|
|
Set[L2.RS3, 9];
|
|
Set[L2.LP1, 0A];{also PWRets}
|
|
Set[L2.AS0, 0B];
|
|
Set[L2.PLS0, 0C];
|
|
Set[L2.LP2, 0D];
|
|
Set[L2.TS0, 0E];
|
|
Set[L2.TS2, 0F];
|
|
|
|
|
|
{PMRead Returns}
|
|
|
|
Set[L2.WH0, 0]; {0 MOD 2}
|
|
Set[L2.RS0, 1]; {also PFetch}
|
|
Set[L2.DQ1, 3]; {3 MOD 4}
|
|
Set[L2.EM2, 4]; {0 MOD 2; also NQRets}
|
|
Set[L2.CQ3, 5];
|
|
Set[L2.CQ2, 6]; {0 MOD 2}
|
|
Set[L2.CQ1, 7]; {3 MOD 4}
|
|
|
|
|
|
{PFetch Returns}
|
|
|
|
Set[L2.RS2, 0]; {0 MOD 2}
|
|
Set[L2.RS0, 1]; {also PMRead}
|
|
Set[L2.SP0, 2]; {2 MOD 4}
|
|
Set[L2.SP1, 3]; {3 MOD 4; tied to L2.SP0}
|
|
Set[L2.LP5, 4];
|
|
Set[L2.DQ5, 5];
|
|
Set[L2.MW1, 6]; {also PRead, PWrite, QRead}
|
|
Set[L2.TS1, 7];
|
|
Set[L2.SPP, 8];
|
|
Set[L2.EF0, 9];
|
|
Set[L2.LP6, 0A];
|
|
|
|
|
|
{PWrite Returns}
|
|
|
|
Set[L2.WH1, 0];
|
|
Set[L2.DQ0, 7]; {3 MOD 4; also QRead}
|
|
Set[L2.AAS1, 9];
|
|
Set[L2.LP1, 0A]; {also PRead}
|
|
Set[L2.NQ4, 4];
|
|
Set[L2.SP2, 5];
|
|
Set[L2.MW2, 6]; {also PRead, QRead}
|
|
Set[L2.PSS0, 2];
|
|
Set[L2.PSS1, 8];
|
|
Set[L2.SP3, 1]; {1 MOD 4; paired with L2.ASS0}
|
|
Set[L2.AAS0, 3]; {3 MOD 4; contains SP1}
|
|
Set[L2.LP3, 0B];
|
|
Set[L2.FS1, 0C];
|
|
Set[L2.FreeState, 0D];{0F, paired with L2.FS0}
|
|
Set[L2.FS0, 0F];{0F, paired with FreeState}
|
|
|
|
|
|
{QRead Returns}
|
|
|
|
Set[L2.ME0, 4]; {also QWrite}
|
|
Set[L2.DQ0, 7]; {3 MOD 4; also PWrite}
|
|
Set[L2.MR0, 2];
|
|
Set[L2.CQ0, 1];
|
|
Set[L2.MR4, 0]; {also L2.Trap}
|
|
Set[L2.EM0, 5];
|
|
Set[L2.MW2, 6]; {also PRead, PWrite}
|
|
Set[L2.NQ0, 3]; {also PRead}
|
|
Set[L2.BC0, 8];
|
|
Set[L2.RQ0, 9];
|
|
Set[L2.F0, 0A];
|
|
|
|
|
|
{QWrite Returns}
|
|
|
|
Set[L2.ME0, 4]; {also QRead}
|
|
Set[L2.MR1, 1]; {also PRead}
|
|
Set[L2.DQ4, 2]; {0 MOD 2; DQm; paired with DQl}
|
|
{DQl has 3}
|
|
Set[L2.NQ2, 0];
|
|
Set[L2.MW3, 5]; {1 MOD 2}
|
|
Set[L2.NQ8, 6];
|
|
Set[L2.EM1, 7]; {3 MOD 4}
|
|
Set[L2.INT2, 8];
|
|
Set[L2.CQ4, 9]; {1 MOD 2}
|
|
|
|
|
|
{Requeue Returns}
|
|
|
|
Set[rhT.PT, 0]; {Must be zero}
|
|
Set[rhT.BC, 1];
|
|
Set[rhT.IntNN, 2];
|
|
Set[rhT.TS, 3];
|
|
{4 contains EMa}
|
|
Set[rhT.EM, 5]; {paired with EMa}
|
|
Set[rhT.Fault, 6];
|
|
Set[rhT.FaultNN, 7];
|
|
|
|
|
|
{*****************************************************************************
|
|
Monitor Entry
|
|
*****************************************************************************}
|
|
|
|
@@ME: T ¬ STK, push, L2¬0, c1, opcode[361'b];
|
|
rhTT ¬ TOS LRot0, STK ¬ TOS, c2;
|
|
MEf: UvQ1Hi ¬ TOS, pop, c3;
|
|
|
|
Map ¬ [rhTT, T], L1¬L1.Push, TT ¬ Monitor.lock, c1;
|
|
UvQ2 ¬ T, L0¬L0.ME, c2;
|
|
rhRx ¬ Rx ¬ MD, XDirtyDisp, pop, c3;
|
|
|
|
MAR ¬ [rhRx, T+0], BRANCH[MEa, MEb, 1], c1, WLMFRet[L0.ME];
|
|
MEb: TOS ¬ 1, L2Disp, c2;
|
|
Q ¬ MD or TT, XLDisp, BRANCH[MEc, MXa], c3;
|
|
|
|
MEc: MAR ¬ [rhRx, T+0], BRANCH[MEe, MEd, 2], c1;
|
|
MEe: MDR ¬ Q, IBDisp, c2;
|
|
MEg: PC ¬ PC + PC16, DISPNI[OpTable], c3;
|
|
|
|
MEa: Q ¬ T, GOTO[WLMapFix], c2;
|
|
MEd: Rx ¬ pME, pop, GOTO[Long1b], c2;
|
|
|
|
{*****************************************************************************
|
|
Monitor Exit
|
|
*****************************************************************************}
|
|
|
|
@@MX: T ¬ STK, push, L2¬1, c1, opcode[362'b];
|
|
rhTT ¬ TOS LRot0, STK ¬ TOS, GOTO[MEf], c2;
|
|
|
|
MXa: MAR ¬ [rhRx, T+0], CANCELBR[$,3], c1;
|
|
MDR ¬ Q and ~Monitor.lock, c2;
|
|
[] ¬ Q and uPMask, ZeroBr, c3;
|
|
|
|
BRANCH[MXb, MXc], c1;
|
|
MXc: PC ¬ PC + PC16, IBDisp, GOTO[SLa], c2;
|
|
MXb: Rx ¬ pMX, pop, GOTO[Long1b], c2;
|
|
|
|
|
|
|
|
{*****************************************************************************
|
|
Opcodes
|
|
*****************************************************************************}
|
|
@@MW: Rx ¬ pMW, GOTO[Long2], c1, at[2,10,ESC0n];
|
|
@@MR: Rx ¬ pMR, push, GOTO[Long2], c1, at[3,10,ESC0n];
|
|
@@NC: Rx ¬ pNC, push, GOTO[Long1], c1, at[4,10,ESC0n];
|
|
@@BC: Rx ¬ pBC, push, GOTO[Long1], c1, at[5,10,ESC0n];
|
|
@@REQ: Rx ¬ pREQ, GOTO[Long2], c1, at[6,10,ESC0n];
|
|
@@SPP: Rx ¬ pSPP, GOTO[Long1a], c1, at[0F,10,ESC0n];
|
|
|
|
Long2: T ¬ STK, pop, L0¬0, c2;
|
|
UvQ2Hi ¬ T, L0Disp, GOTO[Long2a], c3;
|
|
|
|
Long2a: T ¬ STK, pop, BRANCH[Long2b, Long1a], c1;
|
|
Long2b: UvQ2 ¬ T, c2;
|
|
TT ¬ 2, c3;
|
|
|
|
uStkDepth ¬ TT, c1;
|
|
Long1: T ¬ STK, pop, L0¬1, c2;
|
|
UvQ1Hi ¬ T, L0Disp, GOTO[Long2a], c3;
|
|
|
|
Long1a: PC ¬ PC - 1, pop, c2;
|
|
Long1b: UvQ1 ¬ T c3;
|
|
|
|
rhT ¬ rhT.PT, c1;
|
|
SaveRegs:
|
|
UrL ¬ L, c2;
|
|
UrG ¬ G, G ¬ rhG, c3;
|
|
|
|
UrGHi ¬ G, c1;
|
|
UrPC ¬ PC, PC ¬ rhPC, c2;
|
|
UrPCHi ¬ PC, c3;
|
|
|
|
L0¬L0.SrcOK, G ¬ PDA.lastCV{for interrupts}, c1;
|
|
uPFlags ¬ Rx, YDisp, L3¬L3.Normal, c2;
|
|
rhPC ¬ PDAHi, DISP4[Enter], c3;
|
|
|
|
PRestart:
|
|
uFaultParm0 ¬ G, c3;
|
|
|
|
stackP ¬ uStkDepth, c1;
|
|
TOS ¬ pFault, c2;
|
|
TT ¬ uPFlags, XDisp, push, c3;
|
|
|
|
G ¬ rhG, L2Disp, push, BRANCH[PFa, PFb, 7], c1;
|
|
PFa: uFaultParm1 ¬ G, BRANCH[PTrap, PFault], c2;
|
|
PFb: uFaultParm1 ¬ G, push, BRANCH[PTrap, PFault], c2;
|
|
PTrap: uPFlags ¬ Rx, GOTO[PTail1], c3;
|
|
PFault: uPFlags ¬ TOS, GOTO[Fault], c3;
|
|
|
|
|
|
{*****************************************************************************
|
|
Monitor Entry opcode
|
|
Entry:
|
|
UvQ1Hi,,UvQ1 hold virtual address of monitor lock to be entered
|
|
Exit:
|
|
*****************************************************************************}
|
|
Enter: uStkDepth ¬ 0, c1, at[pMELoc,10,Enter];
|
|
PC ¬ uPSB, c2;
|
|
EnterFailed:
|
|
L ¬ UvQ1Hi, L2¬L2.EF0{PFRets}, c3;
|
|
|
|
EFa: Map ¬ Q ¬ [rhPC, PC+PSB.link], c1;
|
|
rhG ¬ PDAHi, G ¬ PDA.ready, CALL[PFetch3], c2;
|
|
Rx ¬ MD, c3, PFr[L2.EF0];
|
|
|
|
MAR ¬ [rhTT, PC+PSB.link], c1;
|
|
MDR ¬ Rx or PSB.link.enterfailed, L2¬L2.DQ0{QRRets}, c2;
|
|
CallDQ: UvQ2Hi ¬ L, CALL[QRead1], c3;
|
|
|
|
{*****************************************************************************
|
|
Monitor ReEnter opcode
|
|
Entry:
|
|
UvQ1Hi,,UvQ1 hold virtual address of monitor lock to be entered
|
|
UvQ2Hi,,UvQ2 hold virtual address of condition variable just left
|
|
Exit:
|
|
*****************************************************************************}
|
|
ReEnter: G ¬ UvQ1, L2¬L2.MR0{QRRets}, c1, at[pMR,10,Enter];
|
|
CALL[Q1Read3], c2;
|
|
|
|
PC ¬ uPSB, BRANCH[MRa, MRb, 2], c1, QRr[L2.MR0];
|
|
|
|
MRb: UvQ2 ¬ G, GOTO[EnterFailed], c2;
|
|
|
|
MRa: G ¬ UvQ2, c2;
|
|
rhG ¬ UvQ2Hi, c3;
|
|
|
|
Map ¬ [rhG, G], L2¬L2.CQ0{QRRets}, c1;
|
|
TOS ¬ T, CALL[QRead3], c2;
|
|
PC ¬ uPSB, c3, CQr[pMR];
|
|
|
|
Map ¬ Q ¬ [rhPC, PC or PSB.flags], L2¬L2.MR3{PRRets}, c1;
|
|
Rx ¬ uPMask, CALL[PRead3], c2;
|
|
|
|
MAR ¬ [rhTT, PC+PSB.flags], L2¬L2.MR4{QRRets}, c1, PRr[L2.MR3];
|
|
MDR ¬ Ybus ¬ T and ~Rx, YDisp, CANCELBR[$,0], c2;
|
|
MRe: rhG ¬ UvQ1Hi, BRANCH[MRc, MRd, 0E], c3;
|
|
|
|
MRc: Map ¬ [rhG, G], L2¬L2.MR1{QWRets}, c1; {write locked monitor}
|
|
T ¬ TOS or Monitor.lock, push, CALL[QWrite3], c2;
|
|
TOS ¬ 1, push, c3, QWr[L2.MR1];
|
|
|
|
STK ¬ TOS, pop, GOTO[PTail2]{L not used}, c1;
|
|
|
|
MRd: Rx ¬ pTrap, CALL[Q2Read2], c1;
|
|
|
|
[] ¬ T and Condition.abortable, NZeroBr, CANCELBR[$,3], c1, QRr[L2.MR4];
|
|
G ¬ UvQ1, BRANCH[MRe, PRestart], c2;
|
|
|
|
|
|
{*****************************************************************************
|
|
Monitor Exit and Depart opcode
|
|
Entry:
|
|
UvQ1Hi,,UvQ1 hold virtual address of monitor lock to be exited
|
|
Exit:
|
|
*****************************************************************************}
|
|
Depart: G ¬ UvQ1, L2¬L2.EM0{QRRets}, c1, at[pMXLoc,10,Enter];
|
|
uStkDepth ¬ 0, CALL[Q1Read3], c2;
|
|
|
|
MXx: L ¬ UrL, GOTO[PTail2], c1;
|
|
|
|
|
|
{*****************************************************************************
|
|
Exit Monitor Subroutine
|
|
Entry:
|
|
rhG,,G hold virtual address of monitor lock to be exited
|
|
T has monitor lock
|
|
Exit:
|
|
*****************************************************************************}
|
|
ExitMonitor:
|
|
Map ¬ [rhG, G], L2¬L2.EM1{QWRets}, CANCELBR[$,3], c1, QRr[L2.EM0];
|
|
T ¬ T and ~Monitor.lock, CALL[QWrite3], c2;
|
|
T ¬ T and Q, ZeroBr, rhT ¬ rhT.EM{NQRets}, c3, QWr[L2.EM1];
|
|
|
|
Map ¬ Q ¬ [rhPC, T+PSB.link], L2¬L2.EM2{PMRets}, BRANCH[EMa, EMb], c1;
|
|
EMa: UvQ2 ¬ PDA.ready, CALL[PMRead3], c2;
|
|
|
|
L ¬ PDAHi, c1, PMRr[L2.EM2];
|
|
PC ¬ T, L2¬L2.DQ0{QRRets}, CALL[CallDQ], c2;
|
|
|
|
EMb: Xbus ¬ uPFlags, XLDisp, c2, NQr[rhT.EM];
|
|
PC ¬ uPSB, BRANCH[MXx, MWa, 2], c3;
|
|
|
|
|
|
{*****************************************************************************
|
|
Monitor Exit and Wait opcode
|
|
Entry:
|
|
UvQ1Hi,,UvQ1 hold virtual address of monitor lock to be exited
|
|
UvQ2Hi,,UvQ2 hold virtual address of condition on which to wait
|
|
TOS holds timeout value
|
|
Exit:
|
|
*****************************************************************************}
|
|
Wait: uTicks ¬ TOS, L2¬L2.CQ0{QRRets}, CALL[CleanSecond], c1, at[pMW,10,Enter];
|
|
|
|
rhG ¬ UvQ1Hi, c3, CQr[pMW];
|
|
|
|
Rx ¬ UvQ2, c1;
|
|
UvQTemp ¬ Rx, c2;
|
|
Rx ¬ UvQ2Hi, c3;
|
|
|
|
Map ¬ [rhG, G], L2¬L2.EM0{QRRets}, c1;
|
|
UvQTempHi ¬ Rx, CALL[QRead3], c2;
|
|
|
|
MWa: rhG ¬ G ¬ UvQTempHi, c1;
|
|
UvQ2Hi ¬ G, c2;
|
|
G ¬ UvQTemp, L2¬L2.MW2{QRRets, PFRets}, c3;
|
|
|
|
Map ¬ UvQ2 ¬ [rhG, G], CALL[QRead2], c1;
|
|
|
|
Map ¬ Q ¬ [rhPC, PC or PSB.flags], CANCELBR[PFetch2,3], c1, QRr[L2.MW2];
|
|
TOS ¬ MD, XLDisp, c3, PFr[L2.MW2];
|
|
|
|
[] ¬ T and Condition.abortable, ZeroBr, BRANCH[MWb, MWc, 2], c1;
|
|
MWb: Rx ¬ uPTC, CANCELBR[MWe, 1], c2;
|
|
MWc: Rx ¬ uPTC, BRANCH[MWd, MWe], c2;
|
|
MWd: GOTO[PTail1], c3;
|
|
MWe: Xbus ¬ T LRot0, XLDisp, c3;
|
|
|
|
L ¬ uTicks, ZeroBr, BRANCH[MWNoWW, MWWW, 2], c1;
|
|
MWNoWW: G ¬ PDA.ready, BRANCH[MWMakeTime, MWHaveTime], c2;
|
|
MWHaveTime:
|
|
Xbus ¬ 0, XDisp, GOTO[MWWriteTime], c3;
|
|
MWMakeTime:
|
|
L ¬ L + Rx, ZeroBr, c3;
|
|
|
|
MWWriteTime:
|
|
MAR ¬ [rhTT, PC + PSB.timeout], BRANCH[MWOK, MWInc], c1;
|
|
MWOK: MDR ¬ L, T ¬ 0+0+1, rhT¬rhT.PT, CANCELBR[MWf,0], c2;
|
|
MWInc: MDR ¬ T ¬ 0+0+1, rhT¬rhT.PT, CANCELBR[MWf,0], c2;
|
|
MWf: UvQ1Hi ¬ T, L2¬L2.DQ0{QRRets}, c3;
|
|
|
|
MAR ¬ [rhTT, PC + PSB.flags], c1;
|
|
MDR ¬ TOS or PSB.flags.waiting, CANCELBR[Q1Read3,0], c2;
|
|
|
|
MWWW: L2¬L2.MW3{QWRets}, CANCELBR[$,1], c2;
|
|
T ¬ T and ~Condition.wakeup, CALL[QWrite1], c3;
|
|
|
|
GOTO[PTail1], c3, QWr[L2.MW3];
|
|
|
|
|
|
{*****************************************************************************
|
|
Notify opcode
|
|
Entry:
|
|
UvQ1Hi,,UvQ1 hold virtual address of condition to be notified
|
|
Exit:
|
|
*****************************************************************************}
|
|
Notify: uStkDepth ¬ 0, L2¬L2.CQ0{QRRets}, CALL[CleanFirst], c1, at[pNC,10,Enter];
|
|
|
|
T ¬ T and Q, ZeroBr, L2¬L2.WH0{PMRRets}, c3, CQr[pNC];
|
|
|
|
Map ¬ Q ¬ [rhPC, T+PSB.link], BRANCH[NCa, NCb], c1;
|
|
NCa: L ¬ PDAHi, CALL[PMRead3], c2;
|
|
NCb: TT ¬ uPFlags, GOTO[PTail3], {L not used} c2;
|
|
|
|
|
|
{*****************************************************************************
|
|
Broadcast opcode
|
|
Entry:
|
|
UvQ1Hi,,UvQ1 hold virtual address of condition to be broadcast
|
|
Exit:
|
|
*****************************************************************************}
|
|
BCast: uStkDepth ¬ 0, L2¬L2.CQ0{QRRets}, CALL[CleanFirst], c1, at[pBC,10,Enter];
|
|
|
|
BCe: rhT ¬ rhT.BC{NQRets}, T ¬ T and Q, ZeroBr, c3, CQr[pBC];
|
|
|
|
BCd: Map ¬ Q ¬ [rhPC, T+PSB.link], L2¬L2.WH0{PMRRets}, BRANCH[BCa, BCb], c1;
|
|
BCa: L ¬ PDAHi, CALL[PMRead3], c2;
|
|
BCb: rhT ¬ rhT.PT, GOTO[MWd], c2;
|
|
|
|
BCc: G ¬ UvQ1, L2¬L2.BC0{QRRets}, c2, NQr[rhT.BC];
|
|
rhG ¬ UvQ1Hi, CALL[QRead1], c3;
|
|
|
|
CANCELBR[$,3], c1, QRr[L2.BC0];
|
|
GOTO[BCe], c2;
|
|
|
|
|
|
{*****************************************************************************
|
|
WakeHead subroutine
|
|
Entry: rhG, G contains virtual address of condition to wake
|
|
T contains queue.tail.link
|
|
L has PDAHi
|
|
Exit:
|
|
*****************************************************************************}
|
|
WakeHead:
|
|
Map ¬ Q ¬ [rhPC, T or PSB.timeout], L2¬L2.WH1{PWRets}, c1, PMRr[L2.WH0];
|
|
T ¬ 0, UvQ2 ¬ PDA.ready, CALL[PWrite3], c2;
|
|
PC ¬ Q - PSB.timeout, L2¬L2.WH2{PRRets}, c3, PWr[L2.WH1];
|
|
|
|
Map ¬ Q ¬ [rhPC, PC or PSB.flags], CALL[PRead2], c1;
|
|
|
|
MAR ¬ [rhTT, PC+PSB.flags], c1, PRr[L2.WH2];
|
|
MDR ¬ T and ~PSB.flags.waiting, L2¬L2.DQ0{QRRets}, CANCELBR[CallDQ,0], c2;
|
|
|
|
|
|
{*****************************************************************************
|
|
Requeue opcode
|
|
Entry:
|
|
UvQ1Hi,,UvQ1 hold virtual address of source queue
|
|
UvQ2Hi,,UvQ2 hold virtual address of destination queue
|
|
TOS has process
|
|
Exit:
|
|
*****************************************************************************}
|
|
Requeue:
|
|
PC ¬ TOS, L2¬L2.RQ0{QRRets}, CALL[Q2Read2], c1, at[pREQ,10,Enter];
|
|
|
|
G ¬ UvQ1, L2¬L2.DQ0{QRRets}, CANCELBR[$,3], c1, QRr[L2.RQ0];
|
|
rhG ¬ UvQ1Hi, [] ¬ G or UvQ1Hi, ZeroBr, c2;
|
|
L0¬L0.SrcOK, BRANCH[QRead1, RQa], c3;
|
|
|
|
RQa: Map ¬ Q ¬ [rhPC, PC+PSB.link], L2¬L2.DQ1{PMRRets}, GOTO[DQx], c1;
|
|
|
|
|
|
|
|
{*****************************************************************************
|
|
Set Process Priority opcode
|
|
Entry:
|
|
TOS has priority
|
|
Exit:
|
|
*****************************************************************************}
|
|
SetPP: TOS ¬ LRot1 TOS and 7, L2¬L2.SPP{PFRets}, c1, at[pSPP,10,Enter];
|
|
Rx ¬ ~uPPMask, c2;
|
|
PC ¬ uPSB, GOTO[EFa], c3;
|
|
|
|
Rx ¬ Rx and MD, c3, PFr[L2.SPP];
|
|
|
|
UvQ2 ¬ PDA.ready, c1;
|
|
L ¬ PDAHi, c2;
|
|
TOS ¬ TOS LRot12, c3;
|
|
|
|
MAR ¬ [rhTT, PC+PSB.link], c1;
|
|
MDR ¬ TOS or Rx, L2¬L2.DQ0{QRRets}, GOTO[CallDQ], c2;
|
|
|
|
{*****************************************************************************
|
|
Dequeue subroutine:
|
|
Entry:
|
|
rhT # 0 => src = NIL
|
|
UvQ1Hi,,UvQ1 has src
|
|
PC has process
|
|
Exit:
|
|
Returns to NQ
|
|
|
|
Register Usage
|
|
PC = process
|
|
T = temp
|
|
TOS = prev
|
|
Rx has queue
|
|
UvLPhigh has psb.link
|
|
*****************************************************************************}
|
|
Dequeue:
|
|
Map ¬ Q ¬ [rhPC, PC+PSB.link], L2¬L2.DQ1{PMRRets}, CANCELBR[$, 3], c1, QRr[L2.DQ0];
|
|
DQx: Rx ¬ T, CALL[PMRead3], c2;
|
|
|
|
TOS ¬ uPFlags, c1, PMRr[L2.DQ1];
|
|
TOS ¬ TOS or cRequeueFlag, c2;
|
|
uPFlags ¬ TOS, L0Disp, c3;
|
|
|
|
[] ¬ T - PC, ZeroBr, BRANCH[DQa, DQb] c1;
|
|
|
|
DQa: TOS ¬ 0, uPsbLink ¬ T, BRANCH[DQc, DQd], c2;{src#NIL}
|
|
DQb: TOS ¬ 0, uPsbLink ¬ T, BRANCH[DQe, DQf], c2;{src=NIL}
|
|
|
|
DQc: TOS ¬ Rx and uPMask2, GOTO[DQg], c3;{link.next#psb}
|
|
DQd: T ¬ Rx and uPMask2, GOTO[DQj], c3;{link.next=psb}
|
|
|
|
DQe: TOS ¬ PC, GOTO[DQg], c3;{link.next#psb}
|
|
DQf: GOTO[DQk], c3;{link.next=psb}
|
|
|
|
DQg: Map ¬ Q ¬ [rhPC, TOS+PSB.link], L2¬L2.DQ2{PRRets}, c1;
|
|
DQgh: TOS ¬ Q, CALL[PRead3], c2;
|
|
|
|
Q ¬ T and uPMask, c1, PRr[L2.DQ2];
|
|
[] ¬ Q - PC, ZeroBr, c2;
|
|
T ¬ T and ~uPMask, BRANCH[DQh, DQi], c3;
|
|
|
|
DQh: Map ¬ Q ¬ [rhPC, Q+PSB.link], L2¬L2.DQ2{PRRets}, GOTO[DQgh], c1;
|
|
|
|
DQi: MAR ¬ [rhTT, TOS+PSB.link], c1;
|
|
MDR ¬ T or uPsbLink, L0Disp, c2;
|
|
T ¬ Rx and uPMask2, BRANCH[DQj, DQk], c3;
|
|
|
|
DQj: [] ¬ T - PC, ZeroBr, c1;
|
|
T ¬ Rx and ~uPMask2, BRANCH[DQm, DQl], c2;
|
|
DQl: T ¬ TOS or T, L2¬L2.DQ4{QWRets}, c3;
|
|
|
|
Map ¬ [rhG, G], CALL[QWrite2], c1;
|
|
|
|
DQk: Map ¬ Q ¬ [rhPC, PC or PSB.flags], L2¬L2.DQ5{PFRets}, c1;
|
|
T ¬ ~uPMask, CALL[PFetch3], c2;
|
|
T ¬ MD and T, c3, PFr[L2.DQ5];
|
|
|
|
MAR ¬ [rhTT, PC+PSB.flags], c1;
|
|
MDR ¬ T or uPsbLink, CANCELBR[$,0], c2;
|
|
DQm: G ¬ UvQ2, GOTO[Enqueue], c3, QWr[L2.DQ4];
|
|
|
|
|
|
{*****************************************************************************
|
|
Enqueue subroutine:
|
|
Entry:
|
|
UvQ2Hi,,UvQ2 has dst
|
|
PC has process
|
|
rhT has return
|
|
Exit:
|
|
Register Usage
|
|
L has process.priority
|
|
T = temp
|
|
TOS = prev
|
|
Rx = queue, prev
|
|
*****************************************************************************}
|
|
Enqueue:
|
|
Map ¬ Q ¬ [rhPC, PC+PSB.link], L2¬L2.NQ0{QRRets, PRRets}, c1;
|
|
Rx ¬ uPPMask, CALL[PRead3], c2;
|
|
|
|
UreturnPC ¬ T, c1, PRr[L2.NQ0];
|
|
L ¬ T and uPPMask, CALL[Q2Read3], c2;
|
|
|
|
Q ¬ T and uPMask, ZeroBr, CANCELBR[$,3], c1, QRr[L2.NQ0];
|
|
T ¬ T and ~uPMask, BRANCH[NQb, NQc], c2;
|
|
|
|
NQc: T ¬ T or PC, L2¬L2.NQ8{QWRets}, c3;
|
|
|
|
Map ¬ [rhG, G], c1;
|
|
Q ¬ ~uPMask, CALL[QWrite3], c2;
|
|
T ¬ Q and UreturnPC, L2¬L2.NQ4{PWRets}, c3, QWr[L2.NQ8];
|
|
|
|
Map ¬ Q ¬ [rhPC, PC+PSB.link], c1;
|
|
T ¬ T or PC, CALL[PWrite3], c2;
|
|
|
|
NQb: TOS ¬ Q, uTemp ¬ T, L2¬L2.NQ1{PRRets}, c3;
|
|
|
|
Map ¬ Q ¬ [rhPC, TOS+PSB.link], c1;
|
|
uPsbLink ¬ T or PC, CALL[PRead3], c2;
|
|
|
|
Rx ¬ T and Rx, uT ¬ T, c1, PRr[L2.NQ1];
|
|
[] ¬ Rx - L, CarryBr, L2¬L2.NQ3{PRRets}, c2;
|
|
NQi: Rx ¬ T and uPMask, BRANCH[NQd, NQe], c3;
|
|
|
|
NQe: Map ¬ [rhG, G], L2¬L2.NQ2{QWRets}, c1;
|
|
T ¬ uPsbLink, CALL[QWrite3], c2;
|
|
Q ¬ ~uPMask, GOTO[NQg], c3, QWr[L2.NQ2];
|
|
|
|
NQd: Map ¬ Q ¬ [rhPC, Rx+PSB.link], CALL[PRead2], c1;
|
|
|
|
TT ¬ T and uPPMask, c1, PRr[L2.NQ3];
|
|
[] ¬ L - TT - 1, CarryBr, c2;
|
|
Q ¬ ~uPMask, BRANCH[NQf, NQg], c3;
|
|
|
|
NQf: TOS ¬ Rx, c1;
|
|
uT ¬ T, GOTO[NQi], c2;
|
|
|
|
NQg: Map ¬ [rhPC, PC+PSB.link], c1;
|
|
T ¬ Q and UreturnPC, c2;
|
|
TT ¬ rhTT ¬ MD, c3;
|
|
|
|
MAR ¬ [rhTT, PC+PSB.link], c1;
|
|
MDR ¬ T or Rx, c2;
|
|
T ¬ Q and uT, L2¬L2.NQ4{PWRets}, c3;
|
|
|
|
Map ¬ Q ¬ [rhPC, TOS+PSB.link], c1;
|
|
T ¬ T or PC, CALL[PWrite3], c2;
|
|
Xbus ¬ rhT, XDisp, c3, PWr[L2.NQ4];
|
|
|
|
NQRet: L ¬ UrL, DISP2[NQRets], c1;
|
|
|
|
|
|
{*****************************************************************************
|
|
Reschedule
|
|
Entry:
|
|
uPFlags.0: reSchedulePending BOOLEAN
|
|
uPFlags.1..3: 0: Opcode, 2: Trap, 4: Interrupt, 7: Idle,
|
|
5: Fault, 6: FaultNoPC
|
|
Exit:
|
|
Register Usage
|
|
*****************************************************************************}
|
|
|
|
PTail1: L ¬ UrL, c1;
|
|
PTail2: TT ¬ uPFlags, c2, NQr[rhT.PT];
|
|
PTail3: G ¬ UrG, L0¬L0.JRemap, c3;
|
|
|
|
rhG ¬ UrGHi, c1;
|
|
PC ¬ UrPC, L2¬L2.RSSpc, c2;
|
|
rhRx ¬ TT LRot12, XDisp, c3;
|
|
|
|
PTNormal:
|
|
TT ¬ UvPCpage, DISP4[PEnd], c1;
|
|
PEnd: PC ¬ PC + 1, IBDisp, GOTO[PDispNI], c2, at[0,10];
|
|
PC ¬ PC + PC16, IBDisp, GOTO[PDispNI], c2, at[1,10,PEnd];
|
|
T ¬ sProcessTrap, GOTO[Trapc3], c2, at[2,10,PEnd];
|
|
{not possible, c2, at[3,10,PEnd]};
|
|
[] ¬ PC - 1, PgCrOvDisp, push, L1¬L1.Refill, GOTO[PInt], c2, at[4,10,PEnd];
|
|
{not possible to have fault but no requeue, c2, at[5,10,PEnd]};
|
|
{not possible to have fault but no requeue, c2, at[6,10,PEnd];}
|
|
GOTO[SPIdle], {was in idle loop} c2, at[7,10,PEnd];
|
|
L1 ¬ 2, GOTO[StashPC2], c2, at[8,10,PEnd];
|
|
L1 ¬ 1, GOTO[StashPC1], c2, at[9,10,PEnd];
|
|
T ¬ sProcessTrap, GOTO[Trapc3], c2, at[0A,10,PEnd];
|
|
{not possible, c2, at[0B,10,PEnd]};
|
|
[] ¬ PC - 1, PgCrOvDisp, push, L1¬L1.Refill, GOTO[PInt], c2, at[0C,10,PEnd];
|
|
L1 ¬ 0, GOTO[StashPC0], c2, at[0D,10,PEnd];
|
|
GOTO[Reschedule], c2, at[0E,10,PEnd];
|
|
GOTO[SPIdle], {was in idle loop} c2, at[0F,10,PEnd];
|
|
|
|
PDispNI:
|
|
rhPC ¬ UrPCHi, DISPNI[OpTable], c3;
|
|
|
|
Reschedule: PC ¬ uPSB, L3Disp, GOTO[SaveProcess], c3, SPCr[L2.RSSpc];
|
|
|
|
PInt: TOS ¬ STK, pop, BRANCH[PInta, PIntb, 1], c3;
|
|
|
|
PInta: Xbus ¬ rhRx, XDisp, Q ¬ 0, L2¬L2.Pop0IncrX, c1;
|
|
PIntc: T ¬ PC, BRANCH[PIntd, PInte, 7], c2;
|
|
PIntd: rhTT ¬ UvChigh, GOTO[RReMap], c3;
|
|
PInte: Q ¬ UvC, L1¬0, c3;
|
|
|
|
L2¬L2.RSSpc, GOTO[StashPCa1], c1;
|
|
|
|
PIntb: TT ¬ 30, c1;
|
|
Ybus ¬ ~ErrnIBnStkp and TT, ZeroBr, c2;
|
|
TT ¬ UvPCpage, BRANCH[PIntf, PIntg], c3;
|
|
|
|
PIntf: Xbus ¬ rhRx, XDisp, Q ¬ 0, L2¬L2.Pop0IncrX, GOTO[PIntc], c1;
|
|
PIntg: TT ¬ TT + 0FF + 1, c1;
|
|
push, GOTO[PInt], c2;
|
|
|
|
|
|
SPIdle: G ¬ PDA.lastCV{for interrupts}, L2¬L2.RS0{PMRRets, PFRets}, c3;
|
|
|
|
SPRet: Map ¬ Q ¬ [rhPC, PDA.ready], CALL[PMRead2], c1;
|
|
|
|
Map ¬ Q ¬ [rhPC, T+PSB.link], ZeroBr, c1, PMRr[L2.RS0];
|
|
UreturnPC ¬ T, BRANCH[PFetch3, BusyWaita], c2;
|
|
PC ¬ MD and Q, L2¬L2.RS2{PFRets}, c3, PFr[L2.RS0];
|
|
|
|
PRSe: Map ¬ Q ¬ [rhPC, PC{+PSB.link}], uPSB ¬ PC, CALL[PFetch2], c1;
|
|
T ¬ MD, XDisp, c3, PFr[L2.RS2];
|
|
|
|
uPsbLink ¬ T, L1 ¬ 0C, DISP4[PRSa, 0C], c1;
|
|
PRSa: T ¬ RRot1 T and uPPMask, GOTO[PRSb], c2, at[0C,10,PRSa];
|
|
GOTO[PRSc], c2, at[0D,10,PRSa];
|
|
GOTO[PRSc], c2, at[0E,10,PRSa];
|
|
GOTO[PRSc], c2, at[0F,10,PRSa];
|
|
|
|
PRSb: T ¬ T LRot4, L2¬L2.RS3{PRRets}, c3;
|
|
|
|
Map ¬ Q ¬ [rhPC, PDA.state or T], CALL[PRead2], c1;
|
|
|
|
[] ¬ T, ZeroBr, L2¬L2.RS2{PFRets}, c1, PRr[L2.RS3];
|
|
[] ¬ UreturnPC xor PC, ZeroBr, BRANCH[PRSc, PRSd], c2;
|
|
|
|
PRSc: uGFI ¬ 0{Disable SameG in Xfer}, CANCELBR[LoadProcess,1], c3;
|
|
PRSd: PC ¬ uPsbLink and Q, BRANCH[PRSe, BusyWaitb], c3;
|
|
|
|
BusyWaita: Noop, c3;
|
|
|
|
BusyWaitb: T ¬ pIdle, c1;
|
|
[] ¬ uWDC, NZeroBr, c2;
|
|
IdleLoop: uPFlags ¬ T, MesaIntBr, BRANCH[$, WakeError], c3;
|
|
|
|
Rx ¬ uWP, BRANCH[NoInt, Interruptx], c1;
|
|
NoInt: GOTO[IdleLoop], c2;
|
|
|
|
WakeError: T ¬ sRescheduleError, CANCELBR[$, 1], c1;
|
|
GOTO[TrapGo], c2;
|
|
|
|
|
|
{*****************************************************************************
|
|
SaveProcess subroutine
|
|
Entry:
|
|
L3 has preemption booleon: 0 => FALSE, 1 => TRUE
|
|
Exit:
|
|
Register Usage
|
|
*****************************************************************************}
|
|
|
|
SaveProcess:
|
|
Map¬Q¬[rhPC,PC+PSB.link], BRANCH[SPa,SPb,2], L2¬L2.SP0{PFRets}, c1;
|
|
SPa: TOS ¬ ~PSB.link.preempted, CALL[PFetch3], c2;
|
|
SPb: TOS ¬ PSB.link.preempted, CALL[PFetch3], c2;
|
|
T ¬ MD and TOS, XDisp, GOTO[SPd], c3, PFr[L2.SP0];
|
|
T ¬ MD or TOS, XDisp, GOTO[SPc], c3, PFr[L2.SP1];
|
|
|
|
SPc: MAR ¬ [rhTT, PC+PSB.context], BRANCH[SPe, SPf, 0D], c1;
|
|
SPe: TT ¬ RRot1 T and uPPMask, CANCELBR[$,0], c2;
|
|
TT ¬ TT LRot4, GOTO[AllocSV], c3;
|
|
|
|
SPf: G ¬ ~ErrnIBnStkp, CANCELBR[$,0], L2¬1, c2;
|
|
TOS ¬ MD, uPsbLink ¬ T, GOTO[DSKg], c3;
|
|
|
|
SPd: MAR ¬ [rhTT, PC+PSB.context], BRANCH[SPi, SPh, 0D], c1;
|
|
SPh: uPsbLink ¬ T, CANCELBR[$,0], c2;
|
|
TOS ¬ MD, c3;
|
|
|
|
GOTO[PSSe], c1;
|
|
|
|
SPi: MDR ¬ UvL, CANCELBR[$,0], c2;
|
|
uPsbLink ¬ T, GOTO[SPj], c3;
|
|
|
|
PSSRet: T ¬ TOS, L2¬L2.SP2{PWRets}, c3, PWr[L2.SP3];
|
|
|
|
SPg: Map ¬ Q ¬ [rhPC, PC or PSB.context], CALL[PWrite2], c1;
|
|
Noop, c3, PWr[L2.SP2];
|
|
|
|
SPj: MAR ¬ [rhTT, PC+PSB.link], c1;
|
|
MDR ¬ uPsbLink, GOTO[SPIdle], c2;
|
|
|
|
{*****************************************************************************
|
|
AllocAndSave subroutine
|
|
Entry: T has priority
|
|
Exit: TOS has state
|
|
Register Usage
|
|
T, Q, rhRx, Rx, TOS, uTemp
|
|
*****************************************************************************}
|
|
|
|
AllocSV:
|
|
Map ¬ Q ¬ [rhPC, PDA.state or TT], L2¬L2.AS0{PRRets}, c1;
|
|
uTemp ¬ Q, c2;
|
|
rhTT ¬ TT ¬ MD, uPsbLink ¬ T, CALL[PR], c3;
|
|
|
|
Map ¬ Q ¬ [rhPC, T], c1, PRr[L2.AS0];
|
|
TOS ¬ Q, c2;
|
|
rhRx ¬ Rx ¬ MD, c3;
|
|
|
|
MAR ¬ [rhRx, T+0], c1;
|
|
T ¬ uTemp, c2;
|
|
Rx ¬ MD, c3;
|
|
|
|
MAR ¬ [rhTT, T+0], c1;
|
|
MDR ¬ Rx, c2;
|
|
G ¬ ~ErrnIBnStkp, L2¬1, GOTO[DSKg], c3;
|
|
|
|
PSSf: G ¬ 0F and G, c1;
|
|
T ¬ G or T, c2;
|
|
Q ¬ State.word, L2¬L2.PSS0{PWRets}, c3;
|
|
|
|
Map ¬ Q ¬ [rhPC, TOS + Q], CALL[PWrite2], c1;
|
|
T ¬ G + 4, NibCarryBr, c3, PWr[L2.PSS0];
|
|
|
|
Q ¬ Q - State.word, BRANCH[PSSa, PSSb], c1;
|
|
PSSa: stackP ¬ G ¬ G + 2, GOTO[PSSc], c2;
|
|
PSSb: stackP ¬ G ¬ 0E, GOTO[PSSc], c2;
|
|
PSSc: Q ¬ Q + G, push, L2¬L2.PSS1, c3;
|
|
|
|
PSSg: Map ¬ Q ¬ [rhPC, Q - 1], BRANCH[PSSd, PSSe], c1;
|
|
PSSd: T ¬ STK, pop, CALL[PWrite3], c2;
|
|
G ¬ G - 1, ZeroBr, GOTO[PSSg], c3, PWr[L2.PSS1];
|
|
|
|
PSSe: T ¬ UvL, L3Disp, c2;
|
|
Q ¬ TOS+State.frame, L2¬L2.SP3{PWRets}, BRANCH[AASa, AASb, 1], c3;
|
|
|
|
AASa: Map ¬ Q ¬ [rhPC, Q], CALL[PWrite2], pop, c1;
|
|
AASb: Map ¬ Q ¬ [rhPC, Q], CALL[PWrite2], pop, c1;
|
|
|
|
T ¬ uFaultParm0, L2¬L2.AAS1{PWRets}, c3, PWr[L2.AAS0];
|
|
|
|
Map ¬ Q ¬ [rhPC, Q+1], CALL[PWrite2], c1;
|
|
T ¬ uFaultParm1, L2¬L2.SP3{PWRets}, c3, PWr[L2.AAS1];
|
|
|
|
Map ¬ Q ¬ [rhPC, Q+1], CALL[PWrite2], c1;
|
|
|
|
|
|
|
|
{*****************************************************************************
|
|
LoadProcess subroutine
|
|
Entry: L has 0
|
|
Exit: Returns to EFCHaveLink
|
|
Register Usage
|
|
*****************************************************************************}
|
|
|
|
LoadProcess:
|
|
Map ¬ Q ¬ [rhPC, PC or PSB.context], c1;
|
|
uPCValid ¬ 0, L ¬ 0, c2;
|
|
rhTT ¬ TT ¬ MD, c3;
|
|
|
|
MAR ¬ [rhTT, Q + 0], c1;
|
|
L1Disp, Q ¬ ~PSB.link.preempted, c2;
|
|
TOS ¬ MD, DISP4[LPa, 0C], c3;
|
|
|
|
LPa: T ¬ uPsbLink, XDisp, GOTO[LPb], c1, at[0C,10,LPa];
|
|
MAR ¬ [rhTT, PC], GOTO[PLS], c1, at[0D,10,LPa];
|
|
MAR ¬ [rhTT, PC], GOTO[PLS], c1, at[0E,10,LPa];
|
|
MAR ¬ [rhTT, PC], GOTO[PLS], c1, at[0F,10,LPa];
|
|
|
|
LPb: stackP ¬ 0, rhT ¬ xtPSwitch, BRANCH[LPd, LPe, 0B], c2;
|
|
LPd: T ¬ TOS, GOTO[LPf], c3;
|
|
LPe: T ¬ T and ~PSB.link.enterfailed, push, c3;
|
|
|
|
Map ¬ Q ¬ [rhPC, PC or PSB.link], push, L2¬L2.LP1{PW}, c1;
|
|
STK ¬ 0, pop, CALL[PWrite3], c2;
|
|
T ¬ TOS, GOTO[LPf], c3, PWr[L2.LP1];
|
|
|
|
LPx: TOS ¬ TOS + State.frame, L2¬L2.LP6{PFets}, c3, PWr[L2.FS0];
|
|
|
|
Map ¬ Q ¬ [rhPC, TOS], CALL[PFetch2], c1;
|
|
T ¬ MD, c3, PFr[L2.LP6];
|
|
|
|
LPf: Map ¬ Q ¬ [rhPC, PC or PSB.mds], L2¬L2.LP5{PF}, c1;
|
|
UvL ¬ T, CALL[PFetch3], c2;
|
|
rhMDS ¬ TOS ¬ MD, LOOPHOLE[mdok], c3, PFr[L2.LP5];
|
|
|
|
UvMDS ¬ Q ¬ TOS, c1;
|
|
Rx ¬ XferType.pSwitch, L1¬L1.Xfer, c2;
|
|
uXferType ¬ Rx, GOTO[XFER], c3;
|
|
|
|
|
|
{*****************************************************************************
|
|
PLoadStack subroutine
|
|
Entry: T has state.word
|
|
TOS has stack pointer
|
|
Exit: TOS has state pointer
|
|
G has priority
|
|
Returns to FreeState
|
|
Register Usage
|
|
T, rhTT, TT, Q, Rx, TOS
|
|
*****************************************************************************}
|
|
|
|
PLS: MDR ¬ uPsbLink and Q, CANCELBR[$,0], c2;
|
|
Q ¬ State.word, c3;
|
|
|
|
Map ¬ Q ¬ [rhPC, TOS + Q], L2¬L2.PLS0{PR}, c1;
|
|
stackP ¬ 0, rhT ¬ xtPSwitch, CALL[PRead3], c2;
|
|
|
|
TT ¬ T LRot8, STK ¬ T, push, c1, PRr[L2.PLS0];
|
|
TT ¬ TT and 0FF, c2;
|
|
T ¬ T + 4, NibCarryBr, c3;
|
|
|
|
UBrkByte ¬ TT, BRANCH[PLSa, PLSb], c1;
|
|
PLSa: T ¬ T and 0F, GOTO[PLSc], c2;
|
|
PLSb: T ¬ 10, GOTO[PLSc], c2;
|
|
PLSc: Rx ¬ T - 2, c3;
|
|
|
|
Map ¬ Q ¬ [rhPC, TOS], c1;
|
|
PLSf: G ¬ RRot1 uPsbLink, c2;
|
|
rhTT ¬ TT ¬ MD, c3;
|
|
|
|
MAR ¬ [rhTT, Q+0], c1;
|
|
Rx ¬ Rx - 1, ZeroBr, c2;
|
|
T ¬ MD, STK ¬ T, push, BRANCH[PLSd, PLSe], c3;
|
|
|
|
PLSd: Map ¬ Q ¬ [rhPC, Q+1], GOTO[PLSf], c1;
|
|
|
|
PLSe: STK ¬ T, L1Disp, c1;
|
|
stackP ¬ uBlock0, BRANCH[FreeState, LPx, 0D], c2;
|
|
|
|
|
|
{*****************************************************************************
|
|
FreeState subroutine
|
|
*****************************************************************************}
|
|
|
|
FreeState:
|
|
T ¬ G LRot4, c3;
|
|
|
|
Map ¬ Q ¬ [rhPC, PDA.state], c1;
|
|
T ¬ T and 7, c2;
|
|
TT ¬ rhTT ¬ MD, c3;
|
|
|
|
MAR ¬ [rhTT, Q + T], c1;
|
|
MDR ¬ TOS, CANCELBR[$,0], c2;
|
|
T ¬ MD, L2¬L2.FS0{PWRets}, c3;
|
|
|
|
{Dicentra
|
|
Noop, c3;
|
|
|
|
MAR ¬ [rhTT, Q + T], c1;
|
|
CANCELBR[$,0], c2;
|
|
T ¬ MD, L2¬L2.FS0{PWRets}, c3;
|
|
}
|
|
Map ¬ Q ¬ [rhPC, TOS], CALL[PWrite2], c1;
|
|
|
|
|
|
{*****************************************************************************
|
|
Interrupt Handler
|
|
Entry:
|
|
CALLing sequence has done Rx ¬ pInt, GOTO[SaveRegs];
|
|
Exit:
|
|
Register Usage
|
|
*****************************************************************************}
|
|
Interrupt: Rx ¬ uWP, c1, at[pIntLoc,10,Enter];
|
|
Interruptx: ClrIntErr, uWP ¬ 0, L3¬L3.Interrupt, c2;
|
|
CVLoop: Rx ¬ RShift1 Rx, Xbus ¬ Rx LRot0, XLDisp, c3;
|
|
|
|
uWW ¬ Rx, NZeroBr, BRANCH[CheckNext, IntThisCV, 2], c1;
|
|
IntThisCV: Q ¬ PDA.interrupt + G, CANCELBR[$,1], c2;
|
|
[] ¬ G, rhG ¬ PDAHi, ZeroBr, c3;
|
|
|
|
Map ¬ UvQ1 ¬ [rhG, Q], BRANCH[Int, CheckTime], c1;
|
|
Int: uIntLevel ¬ G, G ¬ Q, L2¬L2.CQ0{QRRets}, CALL[QRead3], c2;
|
|
|
|
rhT ¬ rhT.IntNN{NQRets}, Q ¬ T and Q, ZeroBr, c3, CQr[pIntLoc];
|
|
|
|
Map ¬ Q ¬ [rhPC, Q+PSB.link], L2¬L2.WH0{PRRets}, BRANCH[INTa, INTb], c1;
|
|
INTa: L ¬ PDAHi, L0¬L0.SrcOK, CALL[PMRead3], {Do Naked Notify} c2;
|
|
INTb: L2¬L2.INT2{QWRets}, c2;
|
|
T ¬ T or 1, CALL[QWrite1], c3;
|
|
|
|
INTc: G ¬ uIntLevel, c3, QWr[L2.INT2];
|
|
|
|
Rx ¬ uWW, NZeroBr, c1;
|
|
CheckNext: G ¬ G - 2, BRANCH[IntDone, CVLoop], c2;
|
|
IntDone: GOTO[PTail1], c3;
|
|
|
|
IntDidNN: GOTO[INTc], c2, NQr[rhT.IntNN];
|
|
|
|
|
|
{*****************************************************************************
|
|
Fault Handler
|
|
Entry: T has FaultIndex*2
|
|
parameters stored in uFaultPram0 and uFaultParm1
|
|
CALLing sequence has done Rx ¬ pFault, GOTO[SaveRegs];
|
|
Exit:
|
|
Register Usage
|
|
*****************************************************************************}
|
|
Fault: UvQ2 ¬ T, L3¬L3.Fault, c1, at[pFault,10,Enter];
|
|
rhG ¬ G ¬ PDAHi, c2;
|
|
UvQ2Hi ¬ G, G ¬ PDA.ready, c3;
|
|
|
|
PC ¬ uPSB, L2¬L2.DQ0{QRRets}, c1;
|
|
rhT ¬ rhT.Fault{NQRets}, c2;
|
|
rhPC ¬ PDAHi, CALL[QRead1], c3;
|
|
|
|
rhT ¬ rhT.FaultNN{NQRets}, c2, NQr[rhT.Fault];
|
|
G ¬ UvQ2, L2¬L2.F0{QRRets}, c3;
|
|
|
|
Map ¬ G ¬ [rhG, G+FaultQueue.condition], c1;
|
|
UvQ2 ¬ PDA.ready, CALL[QRead3], c2;
|
|
|
|
Map ¬ Q ¬ [rhPC, T and Q], ZeroBr, CANCELBR[$,3], c1, QRr[L2.F0];
|
|
L ¬ PDAHi, L2¬L2.WH0{PMRRets}, BRANCH[PMRead3, Fb], c2;
|
|
Fb: PC ¬ Q or Condition.wakeup, c3;
|
|
|
|
MAR ¬ [rhTT, G+0], c1;
|
|
MDR ¬ PC, T ¬ uPCValid, NZeroBr, c2;
|
|
Fc: uGFI ¬ 0{Disable SameG in Xfer}, BRANCH[Fd, Fe], c3;
|
|
|
|
Fd: TT ¬ pFaultNoPC, GOTO[Ff], c1;
|
|
Fe: TT ¬ pFaultPC, GOTO[Ff], c1;
|
|
Ff: L ¬ UrL, GOTO[PTail3], c2;
|
|
|
|
FaultDidNN: [] ¬ uPCValid, NZeroBr, GOTO[Fc], c2, NQr[rhT.FaultNN];
|
|
|
|
|
|
{*****************************************************************************
|
|
Check For Timeouts
|
|
Entry:
|
|
Exit:
|
|
Register Usage
|
|
*****************************************************************************}
|
|
CheckTime: TT ¬ LShift1 uTickCount, XDisp, c2;
|
|
uTickCount ¬ TT, BRANCH[Scan, PTail1, 0B], c3;
|
|
|
|
Scan: L ¬ uPTC, L0¬L0.SrcNull, c1;
|
|
L ¬ L + 1, c2;
|
|
uPTC ¬ L, L2¬L2.TS0{PRRets}, c3;
|
|
|
|
Map ¬ Q ¬ [rhPC, PDA.count], c1;
|
|
PC ¬ StartPSB, CALL[PRead3], c2;
|
|
|
|
T ¬ T LRot4, c1, PRr[L2.TS0];
|
|
L ¬ T + StartPSBMinus1Times2, c2;
|
|
TSe: uStkDepth ¬ L, L2¬L2.TS2{PRRets}, c3;
|
|
|
|
Map ¬ Q ¬ [rhPC, PC or PSB.timeout],CALL[PRead2], c1;
|
|
|
|
Q ¬ T, ZeroBr, c1, PRr[L2.TS2];
|
|
[] ¬ Q xor uPTC, NZeroBr, BRANCH[TSa, TSb], c2;
|
|
TSa: Q ¬ PC + PC, BRANCH[TSc, TSd], c3;
|
|
|
|
TSc: MAR ¬ [rhTT, PC+PSB.timeout], c1;
|
|
MDR ¬ 0, rhT ¬ rhT.TS{NQRets}, CANCELBR[$,0], c2;
|
|
G ¬ PDAHi, L2¬L2.TS1{PFRets}, c3;
|
|
|
|
MAR ¬ [rhTT, PC + PSB.flags], c1;
|
|
CANCELBR[$,0], c2;
|
|
T ¬ MD, UvQ2Hi ¬ G, c3;
|
|
|
|
MAR ¬ [rhTT, PC + PSB.flags], c1;
|
|
MDR ¬ T and ~PSB.flags.waiting, CANCELBR[$,0], c2;
|
|
UvQ2 ¬ PDA.ready, GOTO[Dequeue], c3;
|
|
|
|
L ¬ uStkDepth, c2, NQr[rhT.TS];
|
|
TSb: Q ¬ PC + PC, CANCELBR[TSd, 1], c3;
|
|
|
|
TSd: [] ¬ Q xor uStkDepth, ZeroBr, c1;
|
|
PC ¬ PC + PSB.SIZE, BRANCH[TSe, TSf], c2;
|
|
TSf: uTickCount ¬ L xor ~L, GOTO[PTail1], c3;
|
|
|
|
|
|
|
|
{*****************************************************************************
|
|
CleanupQueue subroutine
|
|
Entry:
|
|
calling instruction in c1
|
|
L2 holds L2.CQ0{QRRets}
|
|
returns to uPFlags
|
|
Exit:
|
|
T holds condition queue
|
|
G holds UvQ1
|
|
Register Usage
|
|
PC = process
|
|
T = cleanup or link
|
|
Rx = head of queue
|
|
UreturnPC = condition and ~uPMask
|
|
MUST NOT USE L or TOS
|
|
*****************************************************************************}
|
|
|
|
CleanFirst: G ¬ UvQ1, CALL[Q1Read3], c2;
|
|
CleanSecond:
|
|
G ¬ UvQ2, CALL[Q2Read3], c2;
|
|
|
|
PC ¬ T and Q, ZeroBr, rhPC ¬ PDAHi, CANCELBR[$,3], c1, QRr[L2.CQ0];
|
|
T ¬ T and ~uPMask, BRANCH[CQNE, CQEmpty], c2;
|
|
CQNE: T ¬ T and ~Condition.wakeup, L2¬L2.CQ1{PMRRets}, c3;
|
|
|
|
Map ¬ Q ¬ [rhPC, PC or PSB.flags], c1;
|
|
UreturnPC ¬ T, CALL[PMRead3], c2;
|
|
|
|
[] ¬ T, ZeroBr, L2¬L2.CQ4{QWRets}, c1, PMRr[L2.CQ1];
|
|
CQLoop1: [] ¬ T - PC, ZeroBr, BRANCH[$, CQClean], c2;
|
|
[] ¬ T, ZeroBr, BRANCH[$, CQMakeEmpty], c3;
|
|
|
|
Map ¬ Q ¬ [rhPC, T or PSB.flags], L2¬L2.CQ2{PMRRets}, BRANCH[$, CQHead], c1;
|
|
PC ¬ T, CALL[PMRead3], c2;
|
|
|
|
L2¬L2.CQ4{QWRets}, GOTO[CQLoop1], c1, PMRr[L2.CQ2];
|
|
|
|
CQHead: Rx ¬ PC, c2;
|
|
L2¬L2.CQ3{PMRRets}, c3;
|
|
|
|
CQLoop2: Map ¬ Q ¬ [rhPC, PC], CALL[PMRead2], c1;
|
|
|
|
[] ¬ T - Rx, ZeroBr, L2¬L2.CQ4{QWRets}, c1, PMRr[L2.CQ3];
|
|
BRANCH[$, CQFoundTail], c2;
|
|
PC ¬ T, L2¬L2.CQ3{PMRRets}, GOTO[CQLoop2], c3;
|
|
|
|
CQFoundTail:
|
|
T ¬ UreturnPC or PC, CALL[QWrite1], c3;
|
|
|
|
CQMakeEmpty:
|
|
Map ¬ [rhG, G], CANCELBR[$,1], c1;
|
|
T ¬ UreturnPC, CALL[QWrite3], c2;
|
|
CQClean: T ¬ PC, CANCELBR[CQRet,1], GOTO[CQRet], c3;
|
|
|
|
CQEmpty: T ¬ 0, GOTO[CQRet], c3;
|
|
GOTO[CQRet], c3, QWr[L2.CQ4];
|
|
|
|
CQRet: Xbus ¬ uPFlags, XDisp, c1;
|
|
G ¬ UvQ1, DISP4[CQRets], c2;
|
|
|
|
|
|
{*****************************************************************************
|
|
PRead subroutine:
|
|
Entry:
|
|
c2, c3 => Q has virtual address; Map reference started by caller
|
|
L2 holds return
|
|
Exit State:
|
|
T has memory data
|
|
rhTT, TT, has real address
|
|
Q has uPMask
|
|
returnee executed on c1
|
|
*****************************************************************************}
|
|
PRead2: Noop, c2;
|
|
PRead3: TT ¬ rhTT ¬ MD, c3;
|
|
|
|
PR: MAR ¬ [rhTT, Q + 0], c1;
|
|
Q ¬ uPMask, L2Disp, c2;
|
|
T ¬ MD, DISP4[PRRets], c3;
|
|
|
|
{*****************************************************************************
|
|
PMRead subroutine:
|
|
Entry:
|
|
c2, c3 => Q has virtual address; Map reference started by caller
|
|
L2 holds return
|
|
Exit State:
|
|
T has memory data and uPMask
|
|
rhTT, TT, has real address
|
|
Q has uPMask
|
|
returnee executed on c1
|
|
*****************************************************************************}
|
|
PMRead2: Noop, c2;
|
|
PMRead3: TT ¬ rhTT ¬ MD, c3;
|
|
|
|
PMR: MAR ¬ [rhTT, Q + 0], c1;
|
|
Q ¬ uPMask, L2Disp, c2;
|
|
T ¬ MD and Q, DISP4[PMRRets], c3;
|
|
|
|
{*****************************************************************************
|
|
PFetch subroutine:
|
|
Entry:
|
|
c2, c3 => Q has virtual address; Map reference started by caller
|
|
L2 holds return
|
|
Exit State:
|
|
rhTT, TT, has real address
|
|
Q has uPMask
|
|
memory reference started
|
|
returnee executed on c3
|
|
*****************************************************************************}
|
|
PFetch2: Noop, c2;
|
|
PFetch3: TT ¬ rhTT ¬ MD, c3;
|
|
|
|
MAR ¬ [rhTT, Q + 0], L2Disp, c1;
|
|
Q ¬ uPMask, DISP4[PFRets], c2;
|
|
|
|
{*****************************************************************************
|
|
PWrite subroutine:
|
|
Entry:
|
|
Q has virtual address
|
|
calling instruction executed on c1 => Map reference started by caller
|
|
T has data to be written
|
|
L2 holds return
|
|
Exit State:
|
|
T has memory data
|
|
rhTT, TT, Q has real address
|
|
returnee executed on c3
|
|
*****************************************************************************}
|
|
PWrite2: Noop, c2;
|
|
PWrite3: TT ¬ rhTT ¬ MD, c3;
|
|
|
|
PW: MAR ¬ [rhTT, Q + 0], L2Disp, c1;
|
|
MDR ¬ T, RET[PWRets], c2;
|
|
|
|
|
|
{*****************************************************************************
|
|
QRead subroutine:
|
|
Entry:
|
|
rhG,,G has virtual address
|
|
L2 holds return
|
|
Exit State:
|
|
rhG, G has virtual address
|
|
T has MD and 77777B
|
|
XLDisp pending on MD to save ww bit
|
|
returnee executed on c1
|
|
*****************************************************************************}
|
|
QRead1: Map ¬ [rhG, G], c1;
|
|
QRead2: Noop, c2;
|
|
QRead3: TT ¬ rhTT ¬ MD, XDirtyDisp, c3;
|
|
|
|
QR: MAR ¬ [rhTT, G + 0], BRANCH[QRMpFx, QRMpOk, 1], c1;
|
|
QRMpOk: Q ¬ uPMask, L2Disp, c2;
|
|
T ¬ MD, XLDisp, RET[QRRets], c3;
|
|
|
|
QRMpFx: Noop, c2;
|
|
Xbus ¬ TT LRot0, XwdDisp, c3;
|
|
|
|
Map ¬ [rhG, G], DISP2[QRFlgFx], c1;
|
|
QRFlgFx: MDR ¬ TT or 10, GOTO[QRx], c2, at[0,4,QRFlgFx];
|
|
MDR ¬ TT or 10, GOTO[QRx], c2, at[1,4,QRFlgFx];
|
|
T ¬ qWriteProtect, L2¬L2.Fault, GOTO[PRestart], c2, at[2,4,QRFlgFx];
|
|
T ¬ qPageFault, L2¬L2.Fault, GOTO[PRestart], c2, at[3,4,QRFlgFx];
|
|
QRx: Xbus ¬ 2, XDisp, GOTO[QR], c3;
|
|
|
|
|
|
{*****************************************************************************
|
|
Q1Read subroutine:
|
|
Entry:
|
|
UvQ1Hi, UvQ1 has virtual address
|
|
calling instruction executed on c1
|
|
L2 holds return
|
|
Exit State:
|
|
same as QRead
|
|
*****************************************************************************}
|
|
Q1Read3: rhG ¬ UvQ1Hi, GOTO[QRead1], c3;
|
|
|
|
{*****************************************************************************
|
|
Q2Read subroutine:
|
|
Entry:
|
|
UvQ2Hi, UvQ2 has virtual address
|
|
calling instruction executed on c1
|
|
L2 holds return
|
|
Exit State:
|
|
same as QRead
|
|
*****************************************************************************}
|
|
Q2Read2: G ¬ UvQ2, c2;
|
|
Q2Read3: rhG ¬ UvQ2Hi, GOTO[QRead1], c3;
|
|
|
|
|
|
{*****************************************************************************
|
|
QWrite subroutine:
|
|
Entry:
|
|
rhG, G has virtual address
|
|
L2 holds return
|
|
T has data to be written
|
|
Exit State:
|
|
rhG, G has virtual address
|
|
returnee executed on c3
|
|
*****************************************************************************}
|
|
QWrite1: Map ¬ [rhG, G], c1;
|
|
QWrite2: Noop, c2;
|
|
QWrite3: TT ¬ MD, rhTT ¬ MD, XDirtyDisp, c3;
|
|
|
|
QW: MAR ¬ [rhTT, G + 0], BRANCH[QWMpFx, QWMpOk, 1], L2Disp, c1;
|
|
QWMpOk: MDR ¬ T, RET[QWRets], c2;
|
|
QWMpFx: CANCELBR[$,0F], c2;
|
|
Xbus ¬ TT LRot0, XwdDisp, c3;
|
|
|
|
Map ¬ [rhG, G], DISP2[QWFlgFx], c1;
|
|
QWFlgFx: MDR ¬ TT or 0A0, GOTO[QWx], c2, at[0,4,QWFlgFx];
|
|
MDR ¬ TT or 0A0, GOTO[QWx], c2, at[1,4,QWFlgFx];
|
|
T ¬ qWriteProtect, L2¬L2.Fault, GOTO[PRestart], c2, at[2,4,QWFlgFx];
|
|
T ¬ qPageFault, L2¬L2.Fault, GOTO[PRestart], c2, at[3,4,QWFlgFx];
|
|
QWx: Xbus ¬ 2, XDisp, GOTO[QW], c3;
|
|
|
|
|
|
{END}
|
|
@
|
|
|
|
|
|
1.1.1.1
|
|
log
|
|
@first add
|
|
@
|
|
text
|
|
@@
|