// AltIODisplay.bcpl -- handles parts of Alto display other // than command window. Also contains // various display subroutines // Last modified December 13, 1982 9:43 AM get "altio.decl" get "streams.d" get "AltoDefs.d" external [ //outgoing procedures MaxcTerminal; MaxcKeyboard; MaxcTerminal1 DiabloError; UpdateRegisterDisplay; DisplayParityError Display20Bit; Display36Bit; Display40Bit; PrintOctalField Ding //incoming procedures Ws; Wss; Gets; Puts; Resets; Stateofs; Block Allocate; Free; Dismiss; PutTemplate; SetTimer; TimerHasExpired MyFrame; GotoFrame; ResetLine GetKeys MemRead; MemReadBlock32; MemReadBlock40; DisplaceMaxcAdr TakeDLSOutput; GiveDLSInput //outgoing statics tDsp; hDsp; hShow; hNoShow; updateDisplayValid; displayActive diabloStr; diabloCopy; keepDisplayOn //incoming statics sysZone; dsp; resetExecuted; adrMTBS; parityData ] static [ tDsp; hDsp; hShow; hNoShow; updateDisplayValid; displayActive diabloStr diabloCopy = false diabloBusy = false diabloHung = false keepDisplayOn = false ] manifest ecDiabloPrinterCheck = 2501 // --------------------------------------------------------------------------- let MaxcTerminal() be // --------------------------------------------------------------------------- //context simulating Maxc DLS terminal 0 in bottom window [ let char = TakeDLSOutput(0) & #177 switchon char into [ case $*007: //bell [ Ding(tDsp); endcase ] case $*n: //ignore carriage return endcase case $*l: //turn line feed into carriage return char = $*n //fall into default case default: Puts(tDsp, char) if diabloCopy then DiabloPrint(char) ] ] repeat // --------------------------------------------------------------------------- and MaxcKeyboard() be GiveDLSInput(0, GetKeys()) repeat // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- and MaxcTerminal1() be // --------------------------------------------------------------------------- //context simulating Maxc DLS terminal 1 using Diablo printer [ let char = TakeDLSOutput(1) & #177 switchon char into [ case $*n: //ignore carriage return endcase case $*l: //turn line feed into carriage return char = $*n //fall into default case default: DiabloPrint(char) ] ] repeat // --------------------------------------------------------------------------- and DiabloPrint(char) be // --------------------------------------------------------------------------- [ while diabloBusy do Block() if diabloHung then test Stateofs(diabloStr) //now ready? ifso [ diabloHung = false; Resets(diabloStr) ] //yes, time to try again ifnot return //no, throw char away diabloBusy = true diabloStr>>ST.par1 = MyFrame() Puts(diabloStr, char) if diabloHung then [ Ws("*nDiablo printer not ready*n") Ding(dsp) ] diabloBusy = false ] // --------------------------------------------------------------------------- and DiabloError(str, ec) be // --------------------------------------------------------------------------- //Errors procedure called from within Diablo Printer package [ if ec eq ecDiabloPrinterCheck then Resets(str) diabloHung = true GotoFrame(str>>ST.par1) ] // --------------------------------------------------------------------------- and UpdateRegisterDisplay() be // --------------------------------------------------------------------------- //context that updates the Maxc register display in top window [ structure Bytes^1,80 byte Resets(hShow); Resets(hDsp) //clear the register display window Block() repeatuntil resetExecuted let regAdr = vec 3*5 let textBuf = Allocate(sysZone, 41) let maxcAdr = vec 1 DisplaceMaxcAdr(xNVMSG, maxcAdr) MemReadBlock32(maxcAdr, textBuf, 20) //read 80 bytes of text MemReadBlock40(maxcAdr, regAdr, 5) //read 5 words of pointers updateDisplayValid = true for i = 0 to 29 do //test for reasonable looking stuff in header if textBuf!i eq 0 % (textBuf!i & #100200) ne 0 then updateDisplayValid = false unless updateDisplayValid do [ //nothing to display, clear the window Free(sysZone, textBuf) Dismiss(1000) //wait 10 seconds and try again loop ] for i = 1 to 80 do Puts(hDsp, textBuf>>Bytes^i) //display text line Free(sysZone, textBuf) Puts(hDsp, $*n) for i = 0 to 4 do [ Block() //don't hog the machine Wss(hDsp, " ") Display20Bit(hDsp, regAdr+3*i+1) Wss(hDsp," ") ] displayActive = true let timer = nil while updateDisplayValid do [ //refresh the data portion of the display once per second ResetLine(hNoShow) //the stream not being shown now for i = 0 to 4 do [ //read and display current values of Maxc registers Block() let maxcData = vec 3 MemRead(regAdr+3*i+1, maxcData) Display36Bit(hNoShow, maxcData) Wss(hNoShow, " ") ] //swap the updating display streams hDsp>>DS.ldcb>>DCB.next = hNoShow>>DS.fdcb let t = hShow; hShow = hNoShow; hNoShow = t Dismiss(100) // If nothing interesting is happening, turn off the display if displayActive % keepDisplayOn then [ SetTimer(lv timer, 12000); displayActive = false ] if TimerHasExpired(lv timer) then [ let save420 = @#420 @#420 = 0 while not (displayActive % keepDisplayOn) & updateDisplayValid do Dismiss(100) @#420 = save420 ] ] ] repeat // --------------------------------------------------------------------------- and DisplayParityError() be // --------------------------------------------------------------------------- //displays and prints data for an Alto parity error [ let str = lv SplitStream - offset ST.puts/16 //make split stream Wss(str, "*nAn Alto memory parity error has occurred.") PutTemplate(str, "*nDCBR=$UO, KNMAR=$UO, DWA=$UO, CBA=$UO, PC=$UO, SAD=$UO", parityData>>ParData.dcbr, parityData>>ParData.knmar, parityData>>ParData.dwa, parityData>>ParData.cba, parityData>>ParData.pc, parityData>>ParData.sad) PutTemplate(str, selecton parityData>>ParData.numErrors into [ case 0: "*nNo errors found during sweep." case 1: "*n$UD error found: address=$UO, contents=$UO." default: "*n$UD errors found; first address=$UO, contents=$UO." ], parityData>>ParData.numErrors, parityData>>ParData.errorAdr, parityData>>ParData.errorData) DiabloPrint($*n) parityData>>ParData.flag = 0 ] // --------------------------------------------------------------------------- and SplitStream(nil, char) be // --------------------------------------------------------------------------- [ Puts(dsp, char); DiabloPrint(char) ] // --------------------------------------------------------------------------- and Display20Bit(str, adr) be PrintOctalField(str, adr, 0, 19) // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- and Display36Bit(str, adr) be // --------------------------------------------------------------------------- [ PrintOctalField(str, adr, 0, 17) Puts(str, $*s) PrintOctalField(str, adr, 18, 35) ] // --------------------------------------------------------------------------- and Display40Bit(str, adr) be // --------------------------------------------------------------------------- [ test (adr!2 & #7400) ne 0 ifso PrintOctalField(str, adr, 36, 39) ifnot Wss(str, " ") Puts(str, $*s) Display36Bit(str, adr) ] // --------------------------------------------------------------------------- and PrintOctalField(str, adr, firstBit, lastBit) be // --------------------------------------------------------------------------- [ let r = (lastBit-firstBit) rem 3 firstBit = firstBit+r let mask = (2 lshift r)-1 [ let q, r = firstBit rshift 4, firstBit Puts(str, $0 + ((adr!(q-1) lshift (1+r) + adr!q rshift (15-r)) & mask)) firstBit = firstBit+3 mask = 7 ] repeatuntil firstBit gr lastBit ] // --------------------------------------------------------------------------- and Ding(stream) be // --------------------------------------------------------------------------- [ InvertWindow(stream, 1) Dismiss(50) InvertWindow(stream, 0) ] // --------------------------------------------------------------------------- and InvertWindow(stream, background) be // --------------------------------------------------------------------------- [ let dcb = stream>>DS.fdcb [ dcb>>DCB.background = background if dcb eq stream>>DS.ldcb return dcb = dcb>>DCB.next ] repeat ]