//d0reg.bcpl hardware interface procedures for register read/write // Last edited: 9 June 1980 get "mcommon.d" get "d0.d" manifest [ get "d0regmem.d" ] external [ // MINIT0 MStatus // MIDAS MidasSwat // MMPRGN UpdateMPDValues // MASM GetField; PutField // MCMD ErrorAbort; @WssCSS; WnsCSSD; PassiveOnly // D0I0 DVx // D0I1 d0rnvr; d0wnvr // D0TABLES @REGCON // D0ASM stReadOnly; stRunning; stPassive; stNotInVM; sendbyte // D0MRW sovlcurr; sovlput; readrr; wrtrr; readt; readtpc // D0VM LookUpAA; LookUpVA; @VirtualP //Defined here for use by machine-independent code GetRegData; MGetRegData; PutRegData; MPutRegData // Defined here for use by D0go, D0asm, etc. ReadAllRegs; PutAllRegs; ReadRegisters; MGetChecks; MPutChecks MakeVA; MakeAA ] static [ SaveVA ] let ReadRegisters() be [ readrr(RXALU,lv DVx!0) //read the volatile registers first readrr(RXSTK,lv DVx!1) readrr(RXAPC,lv DVx!6) readrr(RXCTASK,lv DVx!7) readrr(RXPPB,lv DVx!8) DVx!8 = DVx!8 xor #77 //BootReason is read inverted sendbyte(sovlput(d0rnvr)) //send and execute overlay to get the others readrr(stack0,lv DVx!2) //MemSyndrome readrr(stack1,lv DVx!3) //CycleControl, PCX, PCF readrr(stack2,lv DVx!4) //DB,SB readrr(stack3,lv DVx!5) //MNBR ] and ReadAllRegs() be [ ReadRegisters(); UpdateMPDValues() ] and PutAllRegs() be [ wrtrr(RXALU,lv DVx!0) //volatile first.. CTASK is written in StartD0 wrtrr(RXSTK,lv DVx!1) wrtrr(RXAPC,lv DVx!6) wrtrr(RXPPB,lv DVx!8) //now the non-volatile registers //NOTE: must be very careful about overlays, as they smash Stack2-stack5. sovlput(d0wnvr) //send overlay to get them written. Dont execute it yet. wrtrr(stack0,lv DVx!3) //PCF wrtrr(stack1,lv DVx!4) //DB,SB wrtrr(stack2,lv DVx!5) //MNBR sendbyte(EXOVLcode) //execute the overlay ] //Called from GetRegData, GetMemData and MakeVA(Addr) = VirtualP ? LookUpVA(Addr),Addr //Called from PutRegData, PutMemData (but VirtualP should only be true //when these are called from MPutRegData and MPutMemData). and MakeAA(Addr) = valof [ if VirtualP do [ Addr = LookUpAA(Addr) if Addr < 0 then ErrorAbort(stNotInVM) ] resultis Addr ] and GetRegData(RegX,DVec) = valof [ let T = nil switchon RegX into [ case APCTASKx: DVec!0 = DVx>>srbus.apctask lshift (16-size srbus.apctask); endcase case APCx: DVec!0 = MakeVA(DVx>>srbus.apc) lshift 4; endcase case CTASKx: DVec!0 = DVx>>srbus.ctask lshift (16-size srbus.ctask); endcase case CIAx: DVec!0 = MakeVA(#7777 xor DVx>>srbus.ncia) lshift 4; endcase case CYCLECONTROLx: DVec!0 = DVx>>srbus.cyclecontrol lshift (16-size srbus.cyclecontrol); endcase case PAGEx: DVec!0 = DVx>>srbus.page lshift (16-size srbus.page); endcase case PARITYx: DVec!0 = DVx>>srbus.parity lshift (16-size srbus.parity); endcase case BOOTREASONx: DVec!0 = DVx>>srbus.bootreason lshift (16-size srbus.bootreason) endcase case PCXREGx: DVec!0 = DVx>>srbus.pcxreg lshift (16-size srbus.pcxreg); endcase case PCFREGx: DVec!0 = DVx>>srbus.pcfreg lshift (16-size srbus.pcfreg); endcase case DBREGx: DVec!0 = DVx>>srbus.dbreg lshift (16-size srbus.dbreg); endcase case SBREGx: DVec!0 = DVx>>srbus.sbreg lshift (16-size srbus.sbreg); endcase case MNBRx: DVec!0 = DVx>>srbus.mnbr lshift (16-size srbus.mnbr); endcase case ALURESULTx: DVec!0 = DVx>>srbus.aluresult lshift (16-size srbus.aluresult) endcase case SALUFx: DVec!0 = DVx>>srbus.saluf lshift (16-size srbus.saluf); endcase case SSTKPx: DVec!0 = DVx>>srbus.sstkp lshift (16-size srbus.sstkp); endcase case STKPx: DVec!0 = DVx>>srbus.stkp lshift (16-size srbus.stkp); endcase case MEMSYNDROMEx: DVec!0 = DVx>>srbus.memsyndrome lshift (16-size srbus.memsyndrome) endcase case CALLERx: readtpc(DVx>>srbus.ctask,DVec) DVec!0 = MakeVA((DVec!0 & #7760)+((DVec!0-1) & #17)) lshift 4 endcase case AATOVAx: DVec!0 = SaveVA; endcase default: MidasSwat(UndGRegX) ] resultis true ] //Called by MGetRegData and MGetMemData--resultis false if not ok to //read, else true. and MGetChecks(CON) = valof [ let MachRunning = MStatus>>MStatus.MachRunning if MachRunning then if CON<<MRType.RunAccess eq 0 do resultis false if MachRunning % PassiveOnly then if CON<<MRType.Passive eq 0 do resultis false resultis true ] and MGetRegData(RegX,DataVec,nil,Extension) = MGetChecks(REGCON!RegX) ? GetRegData(RegX,DataVec),false and PutRegData(RegX,DVec) = valof [ let T = DVec!0 switchon RegX into [ case APCTASKx: DVx>>srbus.apctask = T rshift (16-size srbus.apctask); endcase case APCx: DVx>>srbus.apc = MakeAA(T rshift (16-size srbus.apc)); endcase case CTASKx: DVx>>srbus.ctask = T rshift (16-size srbus.ctask); endcase case CIAx: DVx>>srbus.ncia = #7777 xor MakeAA(T rshift (16-size srbus.ncia)) endcase case CYCLECONTROLx: DVx>>srbus.cyclecontrol = T rshift (16-size srbus.cyclecontrol); endcase //case PAGEx: // DVx>>srbus.page = T rshift (16-size srbus.page); endcase //case PCXREGx: // DVx>>srbus.pcxreg = T rshift (16-size srbus.pcxreg); endcase //case PCFREGx: // DVx>>srbus.pcfreg = T rshift (16-size srbus.pcfreg); endcase case DBREGx: DVx>>srbus.dbreg = T rshift (16-size srbus.dbreg); endcase case SBREGx: DVx>>srbus.sbreg = T rshift (16-size srbus.sbreg); endcase case MNBRx: DVx>>srbus.mnbr = T rshift (16-size srbus.mnbr); endcase case ALURESULTx: DVx>>srbus.aluresult = T rshift (16-size srbus.aluresult); endcase case SALUFx: DVx>>srbus.saluf = T rshift (16-size srbus.saluf); endcase //case SSTKPx: // DVx>>srbus.sstkp = T rshift (16-size srbus.sstkp); endcase case STKPx: DVx>>srbus.stkp = T rshift (16-size srbus.stkp); endcase case AATOVAx: SaveVA = LookUpVA(T); endcase default: MidasSwat(UndPRegX) ] //***The hardware should be written here*** resultis true ] //Called by MPutRegData and MPutMemData--ErrorAbort if illegal to write 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,Extension) be [ MPutChecks(REGCON!RegX) test PutRegData(RegX,DVec) ifso UpdateMPDValues() ifnot ErrorAbort() ]