// D1res.bcpl -- resident procedures 11 May 1983
get "mcommon.d"
get "d1.d"
manifest [ get "d1instrs.d" ]
manifest [ get "d1dmux.d" ]
manifest [ get "d1regmem.d" ]
external [
// OS
DoubleAdd
// MIDAS
MidasSwat
// MINIT0
@MBlock; MStatus
// MASM
WssCS1
// MDATA
GoVec; VMBase
// MIOC
DWns
// MMENU
WssMark
// MMPRGN
UpdateMPDValues
// MCMD
ErrorAbort; WnsCS1; CmdCS1; PassiveOnly
// D1I0
@SaveMIR; BreakMIR; OldGFrame; HWStatus
@DMuxTab; @OldDMuxTab; DWrong; DChecked
// D1MICRES
ChangeAltoControl
// D1ACTIONS
AbsAct; VirtAct; DMuxAct; PassiveAct; ActiveAct
// D1ASM
@MCXct; LoadMIR; @Xct; @XctR16; @XctR16C; @XctR16Link; @XctL16Q
@XctL16T; @XctLFF; @DoStrobe; @SetALUF; ReadDMux; @SelectTask
@CheckStopped
// D1MEM
DMuxSelect; @SaveTPC; @SaveTask; @SaveLINK
@SaveQ; SaveALUFM16; SaveALUFM0; SaveSTKP; SaveTIOA
@SaveT; @SaveRBase; @SaveMBase; @SaveSRN; @SaveMCR; SaveR0
// D1VM
@VirtualP
// D1POKE
PassivePending
// D1CONFIG
log2pgsize; log2rows; IMXmask
// Defined here
FinishHardware; DetachHardware; FormHWMenu; HWShowAddr
HWAlwaysUpdate; ReadAllRegs; RestoreD1Temps; DoNOPs
BreakTPC; BreakTask; BR36Saved; UnBreakDefault
]
static
[ BreakTPC; BreakTask; BR36Saved; UnBreakDefault
]
//Form conditional parts of machine-dependent command menu
let FormHWMenu() be
[ test VirtualP //Print current mode in menu, bound to opposite action
ifso WssMark(VirtAct!0,AbsAct)
ifnot WssMark(AbsAct!0,VirtAct)
//Active←Passive←PrePassive are in a ring such that the menu name printed
//is the current mode bound to the next state in the ring.
test PassiveOnly
ifso WssMark(PassiveAct!0,ActiveAct)
ifnot test PassivePending
ifso WssMark("PrePassive",PassiveAct)
ifnot WssMark(ActiveAct!0,PassiveAct)
//For the DMux action, print current display mode as the action name,
//although command files will always have "DMux" as the name.
WssMark((DMuxSelect eq DMuxTab ? DMuxAct!0,
(DMuxSelect eq OldDMuxTab ? "OldDMux",
(DMuxSelect eq DWrong ? "DWrong","DChk"))),DMuxAct)
]
//This is called prior to exit from Midas
and FinishHardware() be
[ DetachHardware(); rv #370 = OldGFrame
]
//Give baseboard control of the muffler/manifold system
//Restore hardware as though about to continue unless machine is running
//(and allow for possible boot).
and DetachHardware() be
[ unless (MStatus>>MStatus.MachRunning) % (CheckStopped() eq 0) do
[ RestoreD1Temps(); DoStrobe(Clock)
]
ChangeAltoControl(BAltoControl+BCNoop)
HWStatus>>HWStatus.ConnectedMachine = -1
]
//Called from ShowAddr in MMPRGN
and HWShowAddr(MemX,AVec) be
[ let AVec0,AVec1 = vec 1,vec 1
if MemX eq VMx do
[ MBlock(AVec0,AVec,2); DoubleAdd(AVec0,VMBase)
AVec1!0 = AVec0!0 rshift log2pgsize
AVec1!1 = (AVec0!0 lshift (16-log2pgsize))+
(AVec0!1 rshift log2pgsize)
WssCS1("uses MAP "); DWns(CmdCS1,AVec1)
let Row = (AVec0!1 rshift 4) & (-1 rshift (16-log2rows))
WssCS1(", ROW "); WnsCS1(Row)
]
]
//Return 1 if this item should be always updated, else 0; called from
//SetAddr in MMPRGN. Returns 1 if AlwaysUpdate bit set in MEMCON/REGCON
//or for the COM-ERRS and MIR-PES items in MADDR, or for the OUTOFSPEC,
//BADSUPPLYSPEC, or PROBLEMS words in $ABSOLUTE.
and HWAlwaysUpdate(MorRCON,X,AVec) = valof
[ resultis MorRCON<<MRType.AlwaysUpdate ne 0 ? 1,
selecton X into
[
case MADDRx: ((AVec!1 eq 11B) % (AVec!1 eq 12B)) ? 1,0
case ABSOLx: ((AVec!1 eq #1) % (AVec!1 eq #147) % (AVec!1 eq #150)) ? 1,0
default: 0
]
]
and RestoreD1Temps() be
[ SelectTask(GoVec>>Go.Task)
unless PassiveOnly do
[ XctL16Q(SaveALUFM0); Xct(LAF0)
XctL16Q(SaveALUFM16); Xct(SetALUF(LAF0,16B))
XctL16Q(SaveQ); Xct(NOOP)
]
LoadMIR(BreakMIR)
]
//Code ne 0 prevents ReadDMux
//Code eq 1 prevents changing Break and Continue info
and ReadAllRegs(Code) be
[ if Code eq 0 do ReadDMux()
if Code ne 1 do //Setup for possible Continue now
[ GoVec>>Go.Addr,GoVec>>Go.Task = DMuxTab!dCIA,SaveTask
let ciainc = (DMuxTab!dCIAINC) & IMXmask
BreakTPC = (ciainc & 177700B)+((ciainc-1) & 77B)
DMuxTab!dOLDCIA = BreakTPC
UnBreakDefault = BreakTPC
BreakTask = DMuxTab!dCTD
MBlock(BreakMIR,SaveMIR,4)
]
SaveTPC,SaveMCR,BR36Saved = DMuxTab!dCIA,DMuxTab!dMCR,false
unless PassiveOnly do
[
//ReadDMux sets UseCPReg. Have to undo that and do NOOP to finish
//possible read of LINK
XctR16Link(NOOP,lv SaveLINK)
//Propagate task stuff through levels on processor boards by doing two
//NOOP's; do many more NOOP's as a precaution against HOLD.
DoNOPs(30)
SaveLINK = not XctR16Link(RLINK,lv SaveLINK)
XctR16(RT,lv SaveT); XctR16(RQ,lv SaveQ)
Xct(TFMD)
Xct(TFTIOA); SaveSTKP = XctR16(RT,lv SaveTIOA)<<rh
//ALUFM[0]←"B" control
XctL16Q(25B); Xct(LAF0T); XctR16(RT,lv SaveALUFM0)
//ALUFM[16]←"not A" control
XctL16Q(1B); Xct(SetALUF(LAF0T,16B)); XctR16(RT,lv SaveALUFM16)
Xct(TFPTRS)
SaveMBase = (XctR16(RT,lv SaveRBase))<<Pointers.MemBase
SaveRBase = SaveRBase<<Pointers.RBase
SaveSRN = XctR16(RCONFG,lv SaveSRN) rshift 12
XctLFF(LRB0,0); XctR16(RRM0,lv SaveR0); XctLFF(LRB0,SaveRBase)
XctL16Q(SaveQ); Xct(NOOP) //Restore
XctL16T(SaveT); Xct(NOOP); LoadMIR(SaveMIR)
]
UpdateMPDValues()
]
//Procedure to do Xct(NOOP) specified number of times
and DoNOPs(N) be for I = 1 to N do Xct(NOOP)