// MemBash.bcpl -- Maxc2 memory contention diagnostic // Assumes a memory diagnostic (e.g., DGMR) running on Maxc // Last modified June 4, 1978 5:51 PM get "streams.d" external [ Ws; Wss; Gets; Puts; Endofs; Resets; Noop; MoveBlock; Zero CreateDisplayStream; ShowDisplayStream; StartIO MemRead; MemWrite; MemRMW InputSMI; OutputSMI; OutputSMIPulse InputSMIErrors; OutputSMITest; ExecuteMicroInstruction; LoadBus; ReadBus LoadRam; SetBLV; USetBLV RamImage; dsp; keys; lvUserFinishProc; adrMTBS ] static [ AltoOperation; NextAdr altoNumber; maxcNumber; numberTyped; altoCode; testAdr displayEnabled = true startAdr = #21 savedUserFinishProc fatalSE = false; fatalPBF = false adrMTBS //external wanted by AltIOUtila.asm ] manifest [ //Maxc processor states (software convention) stateRunning = 0 //processor running stateBreakpoint = 1 //at micro-breakpoint stateLocalMemPE = 2 //local memory parity error stateMainBusPE = 3 //main memory bus parity error stateHalted = 4 //halted for other reason //SMI input addresses smiRUN = #200 //processor run status smiB0 = #203 //processor bus smiB1 = #202 smiB2 = #201 smiJKERRS = #43 //memory errors for quadrants J and K smiLMERRS = #44 //memory errors for quadrants L and M //SMI output addresses smiBR0 = #213 //processor bus smiBR1 = #212 smiBR2 = #211 smiPIR0 = #217 smiPIR1 = #216 //pseudo-instruction register smiPIR2 = #215 smiPIR3 = #214 smiCR = #210 //control register smiPLMR = #40 //physical/logical memory module register smiCONFR = #41 //memory configuration register smiRESR = #42 //memory error reset register ] structure RUN: //processor run status [ blank bit 8 running bit //processor is running notBreakpoint bit //not at micro breakpoint localPE bit //local memory parity error mainPE bit //main memory data bus parity error ] structure QErr^0,3 byte //memory error register (2 words) manifest //layout assuming byte right-justified [ qeTimeout = #40 qeDIP = #20 qeAPE = #10 qePBF = #4 qeDE = #2 qeSE = #1 ] manifest //processor control register [ crEIC = #100000 //enable instruction controlled changes crEB = #40000 //enable changes to branch conditions crEIMA = #20000 //enable changes to IMA crENPC = #10000 //enable changes to NPC crNOTSS = #4000 //don't single step crSetRun = #2000 //set the run flipflop crReset = #1000 //reset processor-memory interface crEPIR = #400 //execute instructions from PIR rather than IM crRegToB = #200 //put BR register on processor bus crIntOn = #100 //enable micro-interrupts crStrobe = #40 //generate interprocessor signal //normal value sent to CR (e.g., when setting Strobe) crNormal = crEIC+crEB+crEIMA+crENPC+crNOTSS+crIntOn ] structure PLMR: //physical/logical module register [ blank bit 7 disableCorrection bit logicalModule bit 3 physicalModule bit 3 quadrant bit 2 ] structure CONFR: //configuration register [ blank bit 4 eFER bit //enable reporting of fatal errors configuration bit 3 //address/quadrant map jSEF bit //quadrant J single errors fatal jPBFF bit //quadrant J parity bit failures fatal kSEF bit kPBFF bit lSEF bit lPBFF bit mSEF bit mPBFF bit ] manifest allSEF = #252 manifest allPBFF = #125 manifest enableFER = #4000 structure RESR: //error reset register (all bits complemented) [ blank bit 8 jResetErrors bit //reset errors in quadrant J jResetQuadrant bit //completely reset quadrant J kResetErrors bit kResetQuadrant bit lResetErrors bit lResetQuadrant bit mResetErrors bit mResetQuadrant bit ] manifest allResetErrors = #125 manifest allResetQuadrant = #252 structure SMIErr: //SMI error register [ blank bit 11 comb bit //communication strobe B (unused) coma bit //communication strobe A nfer bit //non-fatal error fer bit //fatal error blank bit ] manifest smiErrorMask = #12 //bits that we care about (coma, fer) // --------------------------------------------------------------------------- let MemBash() be // --------------------------------------------------------------------------- [ Ws("MemBash of June 4, 1978") //load the special Ram microcode RamImage!0 = #077376 //run tasks 0, 10, 17 in Ram let res = LoadRam(RamImage, true) //load and boot if res ls 0 then Ws("*nFailed to load Alto Ram -- Ram or Ethernet board broken") if res gr 0 then Ws("*nMicrocode constants wrong, beware!") savedUserFinishProc = @lvUserFinishProc @lvUserFinishProc = MyFinishProc Ws("*nAlto MI State Address Maxc State MAR KMAR Memory State") let ds = vec 15000 ds = CreateDisplayStream(30, ds, 15000) ShowDisplayStream(ds) dsp = ds OutputSMITest(#16) ConfigureMemory(0, 0) let v = vec 2; maxcNumber = v let v = vec 1; testAdr = v; Zero(testAdr, 2) AltoOperation = MemRead NextAdr = IncrementAdr Command() ] // --------------------------------------------------------------------------- and Command() be // --------------------------------------------------------------------------- [ Ws("*n**") let char = GetKeys() switchon char into [ case $G: case $g: [ if Confirm("Go") then DoTest() endcase ] case $A: case $a: [ Ws("Alto operation = ") switchon GetKeys() into [ case $R: case $r: [ Ws("Read"); AltoOperation = MemRead; endcase ] case $W: case $w: [ Ws("Write"); AltoOperation = MemWrite; endcase ] case $M: case $m: [ Ws("Modify"); AltoOperation = MemRMW; endcase ] case $?: [ Ws("? Read, Write, Modify"); loop ] default: [ Oop(); loop ] ] Ws(", address sequence = ") switchon GetKeys() into [ case $S: case $s: [ Ws("Sequential"); NextAdr = IncrementAdr; endcase ] case $R: case $r: [ Ws("Repeat at address: ") test GetNumber() eq $*n & numberTyped ifso MoveBlock(testAdr, maxcNumber+1, 2) ifnot [ Oop(); loop ] NextAdr = Noop endcase ] case $?: [ Ws("? Sequential, Repeat"); loop ] default: [ Oop(); loop ] ] endcase ] case $M: case $m: [ Ws("Maxc start address = ") test GetNumber() eq $*n & numberTyped ifso startAdr = altoNumber ifnot Oop() endcase ] case $D: case $d: [ if Confirm(displayEnabled? "Don't display errors", "Display errors") then displayEnabled = not displayEnabled endcase ] case $Z: case $z: [ if Confirm("Zap memory") then ResetMemory() endcase ] case $Q: case $q: [ if Confirm("Quit") then finish endcase ] case $?: [ Ws("? Alto operation, Maxc start adr, Go, Display, Zap, Quit") endcase ] case $*n: case $*s: endcase default: Oop(char) ] ] repeat // --------------------------------------------------------------------------- and DoTest() be // --------------------------------------------------------------------------- [ Ws("*nTest running, hit any key to stop") StartMaxc(startAdr) [ Zero(maxcNumber, 3) altoCode = AltoOperation(testAdr, maxcNumber) let smiErr = InputSMIErrors() if altoCode ne 0 % smiErr<>QErr^q & mask) ne 0 then Puts(dsp,$J+q) ] ] ] // --------------------------------------------------------------------------- and StartMaxc(microAdr; numargs na) be // --------------------------------------------------------------------------- //start Maxc running at the specified micro-address, or just //resume it if microAdr is not specified [ if na gr 0 then [ let maxcData = vec 3 maxcData!0 = 0 maxcData!1 = microAdr rshift 4 maxcData!2 = microAdr lshift 12 LoadBus(maxcData) ExecuteMicroInstruction( // NPC_BR, ENPC table [ #040102; #077546; #000000; #020000; #113600 ]) maxcData!2 = (maxcData!2+#10000) & #170000 if maxcData!2 eq 0 then maxcData!1 = maxcData!1 + 1 LoadBus(maxcData) ExecuteMicroInstruction( // NPC_BR, ENPC, EIMA table [ #040102; #077546; #000000; #020000; #133600 ]) ExecuteMicroInstruction( // IRET, INHINT table [ #040102; #077546; #000152; #000000; #103400 ]) ] ExecuteMicroInstruction( // WRESTART, KWRESTART table [ #040102; #077546; #000110; #160000; #103400 ]) ExecuteMicroInstruction( // FRZBALUBC, EIC, EB, ENPC, EIMA, NOTSS, Strobe table [ #040102; #077546; #000155; #000000; #177140 ]) InputSMIErrors() ] // --------------------------------------------------------------------------- and StopMaxcForcefully() be // --------------------------------------------------------------------------- OutputSMI(smiCR,not (crEIC+crEB+crEIMA+crENPC+crIntOn)) // --------------------------------------------------------------------------- and MaxcState() = valof // --------------------------------------------------------------------------- [ let runReg = InputSMI(smiRUN) if runReg<