// D1res.bcpl -- resident procedures // Last edited: 1 May 1980 get "mcommon.d" get "d1.d" manifest [ get "d1instrs.d" ] manifest [ get "d1dmux.d" ] manifest [ get "d1regmem.d" ] manifest [ get "d1pe.d" ] external [ // MIDAS MidasSwat // MINIT0 MStatus // MMPRGN UpdateMPDValues // MCMD ErrorAbort; PassiveOnly // D1I0 @SaveMIR; HWStatus; @DMuxTab; DChecked // D1TABLES @REGCON // D1ASM @MCXct; LoadMIR; LoadCPReg; @Xct; @XctR16; @XctR16C; @XctL16Q @XctL16T; @XctLFF; @DoStrobe; ReadDMux; LoadDMD; @SelectTask IMtoMIR; MIRtoIM; @D1Out; stReadOnly; stPassive; stRunning // D1MEM GetMic2; FixClock; ClearIMBDAddr DMuxSelect; @OldTask; @SaveTask; @SaveQ; SaveSTKP @SaveT; @SaveSRN; @SaveMCR // D1VM LookUpVA // Defined here GetRegData; MGetChecks; MGetRegData PutRegData; MPutChecks; MPutRegData ] static [ SaveVA ] //DMux items read out from the current, old, wrong, or checked versions //of DMuxTab according to the last button action on DMux let GetRegData(RegX,DVec) = valof [ let T = nil switchon RegX into [ case CPREGx: XctR16C(RLINK,DVec); endcase case MIRx: MIRtoIM(DVec,DMuxSelect+dSaveMIR); endcase case IMOUTx: MIRtoIM(DVec,DMuxSelect+dIMOUT); endcase case Qx: XctR16(RQ,DVec); endcase case CNTx: Xct(TFCNT); XctR16(RT,DVec); endcase case SHCx: Xct(TFSHC); XctR16(RT,DVec); endcase case MEMBXx: Xct(TFPTRS); DVec!0 = (XctR16C(RT,DVec) lshift 1) & 140000B endcase case STKPx: Xct(TFTIOA); T = XctR16(RT,DVec) lshift 8 Xct(TFPTRS); DVec!0 = T+(XctR16(RT,DVec) & 300B) endcase case TASKx: DVec!0 = SaveTask lshift 12; endcase case MCRx: DVec!0 = DMuxSelect!dMCR; endcase case PROCSRNx: DVec!0 = XctR16(RCONFG,DVec) & 170000B; endcase case CONFIGx: XctR16(RCONFG,DVec); endcase case PCXx: XctR16(RPCX,DVec); endcase case INSSETx: DVec!0 = #174000 & XctR16(RIFH,DVec); endcase case TESTSYNx: case STROBEx: case D1OUTx: resultis false //write-only case UPTIMEx: case TGLITCHx: T = RegX eq UPTIMEx ? 82,88 MCXct(BCLdHi+BHoldInt+BInt); MCXct(BCLdLo+BHoldInt+BInt+T) GetMic2(DVec); GetMic2(DVec+1); GetMic2(DVec+2) MCXct(BInt+BCNoop); FixClock(); endcase case EVCNTAx: XctR16(REVA,DVec); endcase case EVCNTBx: XctR16(REVB,DVec); endcase case AATOVAx: DVec!0 = SaveVA; endcase case ESTATx: DVec!0 = DMuxSelect!dESTAT; endcase default: MidasSwat(UndefRegXRead) ] resultis true ] and MGetChecks(CON) = valof [ let MachRunning = MStatus>>MStatus.MachRunning if MachRunning then unless CON<<MRType.RunAccess ne 0 do resultis false if MachRunning % PassiveOnly then unless CON<<MRType.Passive ne 0 do resultis false resultis true ] and MGetRegData(RegX,DVec,nil,Extension) = valof [ unless MGetChecks(REGCON!RegX) do resultis false let R = GetRegData(RegX,DVec) switchon RegX into [ case SHCx: case CNTx: case MEMBXx: case STKPx: XctL16T(SaveT); Xct(NOOP) case Qx: case PCXx: case CPREGx: case CONFIGx: case PROCSRNx: case INSSETx: case EVCNTAx: case EVCNTBx: LoadMIR(SaveMIR) default: endcase ] resultis R ] //Many Put's end with a NOOP, necessary if the final Xct is a load from //CPReg at t3 because the next instruction might smash CPReg. //For most registers, the minimal work necessary to load the register is //done in PutRegData, and the cleanup is done in MPutRegData. Things are //divided this way so "Test" and "TestAll" will run quickly. However, //registers read via the DMux must do everything in PutRegData. //Items whose read values are from the DMux are legal to write when //DChecked signals are being shown; when DMuxTab signals are being shown //the write is legal if there is some way to write the hardware item; //otherwise (OldDMuxTab or DWrong being shown), the write is illegal. //This includes MIR, IMOUT, and MCR. and PutRegData(RegX,DVec) = valof [ let D,T,U = DVec!0,nil,nil switchon RegX into [ case CPREGx: LoadCPReg(D); resultis true case MIRx: test DMuxSelect eq DChecked ifso [ IMtoMIR(DMuxSelect+dSaveMIR,DVec); resultis true ] ifnot test DMuxSelect eq DMuxTab ifso [ IMtoMIR(SaveMIR,DVec); endcase ] ifnot resultis false case IMOUTx: test DMuxSelect eq DChecked ifso [ IMtoMIR(DMuxSelect+dIMOUT,DVec); resultis true ] ifnot resultis false case Qx: XctL16Q(D); SaveQ = D; Xct(NOOP); resultis true case CNTx: XctL16Q(D); Xct(CNTFQ); resultis true case SHCx: XctL16Q(D); Xct(SHCFQ); resultis true case MEMBXx: XctLFF(LMBX0,D rshift 14); resultis true case STKPx: SaveSTKP = D<<lh; XctL16Q(SaveSTKP); Xct(STKPFQ) resultis true case TASKx: SelectTask(D rshift 12); endcase case PROCSRNx: SaveSRN = D rshift 12; XctL16Q(SaveSRN); Xct(SRNFQ) resultis true case MCRx: test DMuxSelect eq DMuxTab ifso [ SaveMCR = D; XctL16T(D); Xct(MCRFT) XctL16T(SaveT); Xct(NOOP); endcase ] ifnot test DMuxSelect eq DChecked ifso [ DMuxSelect!dMCR = D; resultis true ] ifnot resultis false case INSSETx: XctL16Q(((D & #14000) rshift 3)+#100000) Xct(ISEVFQ); endcase //IdCnt not writeable //**Leaves tags screwed up?? First reference held after writing this.** case TESTSYNx: OldTask = SelectTask(16B) XctL16T(FDMiss+DisHold+NoRef+NoWake) Xct(MCRFT); XctL16Q(D); Xct(NOOP) Xct(STORETQ); Xct(LTSYN); XctL16T(SaveMCR) Xct(MCRFT); XctL16T(SaveT); Xct(NOOP) XctL16Q(SaveQ); SelectTask(OldTask); endcase case STROBEx: DoStrobe(D); resultis true case D1OUTx: rv D1Out = D; resultis true case EVCNTBx: XctL16Q(D); Xct(EVBFQ); resultis true case AATOVAx: SaveVA = LookUpVA(D); resultis true //Convert ESTAT format: Build LoadDMD controls in T and HaltConditions in U case ESTATx: test DMuxSelect eq DMuxTab ifso [ T = (D & IMlhPEena) ne 0 ? PEHaltEnable+IMlhPEen,PEHaltEnable if (D & IMrhPEena) ne 0 do T = T+IMrhPEen if (D & IOBPEena) ne 0 do T = T+IOPEen if (D & RAMPEena) ne 0 do T = T+RAMPEen if (D & MemoryPEena) ne 0 do T = T+MemPEen if (D & MdPEena) ne 0 do T = T+MdPEen LoadDMD(T) HWStatus>>HWStatus.MIRdebugging = (D & MIRDebugena) ne 0 ? MIRdebug,0 ClearIMBDAddr() //Enable/disable MIRdebug feature ReadDMux(); resultis true ] ifnot test DMuxSelect eq DChecked ifso [ DMuxSelect!dESTAT = D; resultis true ] ifnot resultis false default: MidasSwat(UndefRegXWrite) ] LoadMIR(SaveMIR); ReadDMux(); resultis true ] and MPutChecks(CON) be [ if CON<<MRType.ReadOnly ne 0 do ErrorAbort(stReadOnly) let MachRunning = MStatus>>MStatus.MachRunning let PassiveWrite = CON<<MRType.PassiveWrite if MachRunning then unless (CON<<MRType.RunAccess ne 0) & (PassiveWrite ne 0) do ErrorAbort(stRunning) if PassiveOnly then if PassiveWrite eq 0 do ErrorAbort(stPassive) ] and MPutRegData(RegX,DVec,nil,nil) be [ MPutChecks(REGCON!RegX) test PutRegData(RegX,DVec) ifso [ switchon RegX into [ case CNTx: case SHCx: case STKPx: case PCXx: case PROCSRNx: case INSSETx: case EVCNTBx: XctL16Q(SaveQ); Xct(NOOP) case MEMBXx: case Qx: LoadMIR(SaveMIR); ReadDMux() //Mustn't do ReadDMux() after these two case STROBEx: case D1OUTx: default: endcase ] UpdateMPDValues() ] ifnot ErrorAbort(stReadOnly) //Only the DMux items ]