// PupAlComProca.bcpl - PUP level -1 driver for ComProc // Copyright Xerox Corporation 1979 // Last modified October 1, 1978 5:05 PM get "Pup0.decl" get "PupAlComProc.decl" external [ // outgoing procedures CPFinishProc; CPSwatContextProc; CPInterrupt StartCPT; StopCPT; StartCPR; StopCPR // incoming procedures CPOutputDone; CPInputDone Enqueue; Dequeue DisableInterrupts; EnableInterrupts; DestroyInterrupt // incoming statics pbiFreeQ; lenPup; cpNDB; cpLT savedCPFinishProc; lvUserFinishProc; lvSwatContextProc ] static savedCPSwatProc //---------------------------------------------------------------------------- let CPFinishProc() be //---------------------------------------------------------------------------- [ let mask = 0 for line = 0 to maxLine do [ (table [ mcChangeControlReg; 1401b ])(4*line, 300b) //rcvEnbl, sndEnbl if cpLT>>CPLT.cpLTE↑line.exists then [ cpLT>>CPLT.cpLTE↑line.iState = stateThrowAway cpLT>>CPLT.cpLTE↑line.oState = stateThrowAway mask = cpNDB>>CPNDB.lcb↑line.iCPLCB>>CPLCB.intMask ] ] DestroyInterrupt(mask) @lvSwatContextProc = savedCPSwatProc @lvUserFinishProc = savedCPFinishProc ] //---------------------------------------------------------------------------- and CPSwatContextProc() be //---------------------------------------------------------------------------- [ savedCPSwatProc = @lvSwatContextProc @lvSwatContextProc = table [ #024413 // lda 1 .+13 ; lineInhibit lshift 1 #101005 // mov 0 0 snr ; skip if leaving swat #125241 // movor 1 1 skp ; turn on line inhibit #125220 // movzr 1 1 ; turn off line inhibit #020410 // lda 0 .+10 ; maxLine * 4 #030410 // lda 2 .+10 ; 1 * 4 #065400 // changeControlReg #101005 // mov 0 0 snr #001401 // jmp 1 3 #142400 // sub 2 0 #000774 // jmp .-4 #001000 // line inhibit lshift 1 #000074 // maxLine * 4 #000004 // 1 * 4 ] ] //---------------------------------------------------------------------------- and CPInterrupt() be //---------------------------------------------------------------------------- // Control comes here when the ComProc microcode interrupts. [ for line = 0 to maxLine do if cpLT>>CPLT.cpLTE↑line.exists then [ let lcb = lv cpNDB>>CPNDB.lcb↑line //Check input LCBs. let cpLCB = lcb>>LCB.iCPLCB let firmStatus = cpLCB>>CPLCB.firmStatus if firmStatus ls 0 then [ //Dont look here again for a completed CPLCB cpLCB>>CPLCB.firmStatus = 0 //Take care of any errors that might have occured. switchon (firmStatus & 77777B) into [ case errorNone: [ lcb>>LCB.iPBI>>PBI.packetLength = ((lenPup+1) lshift 1) - (cpLCB>>CPLCB.byteCount & 77777B) CPInputDone(lcb) endcase ] case errorFatal: [ StopCPR(lcb) endcase ] case errorETX: [ lcb>>LCB.inputOverrun = lcb>>LCB.inputOverrun +1 endcase ] case errorSTX: case errorDLE: [ lcb>>LCB.lineControlError = lcb>>LCB.lineControlError +1 endcase ] case errorCRC: [ lcb>>LCB.badCRC = lcb>>LCB.badCRC +1 endcase ] ] //Restart reception of packets. if lcb>>LCB.iPBI eq 0 then lcb>>LCB.iPBI = Dequeue(pbiFreeQ) if lcb>>LCB.iPBI ne 0 then StartCPR(lcb) ] //CPInterrupt (cont'd) //check output LCBs. cpLCB = lcb>>LCB.oCPLCB firmStatus = cpLCB>>CPLCB.firmStatus if firmStatus ls 0 then [ //Dont look here again for a completed CPLCB cpLCB>>CPLCB.firmStatus = 0 //Take care of any errors that might have occured. switchon (firmStatus & 77777B) into [ case errorFatal: StopCPT(lcb) //fall through case errorNone: [ CPOutputDone(lcb) endcase ] default: StartCPT(lcb) ] ] ] ] //---------------------------------------------------------------------------- and StartCPR(lcb) be //---------------------------------------------------------------------------- // Start ComProc reception of a packet over the line represented by the LCB. // This procedure is called by InitAltoComProc to start things up, // by CPInterrupt when an input is complete to restart reception, and // by CPProcess to restart reception on a line that ran out of PBIs. [ DisableInterrupts() let cpLCB = lcb>>LCB.iCPLCB //Set up to input into iPBI. cpLCB>>CPLCB.byteCount = (lenPup+1) lshift 1 cpLCB>>CPLCB.bytePointer = lv (lcb>>LCB.iPBI)>>CPPBI.type cpLCB>>CPLCB.firmStatus = 0 cpLCB>>CPLCB.hardStatus = 0 cpLCB>>CPLCB.partialCRC = 0 //Link the CPLCB to the line's LTE. //The microcode is always watching for this to go non-zero. cpLT>>CPLT.cpLTE↑(lcb>>LCB.line).iLCB = cpLCB EnableInterrupts() ] //---------------------------------------------------------------------------- and StopCPR(lcb) be //---------------------------------------------------------------------------- // Stop ComProc reception of a packet over the line represented by the LCB. // This procedure is called by CPProcess when it detects a dead line. [ DisableInterrupts() //Put the line in throw-away state. let cpLTE = lv cpLT>>CPLT.cpLTE↑(lcb>>LCB.line) //Put the line in throw-away state, then //remove the CPLCB from the CPLTE, then //put the line back into BiSync input state. cpLTE>>CPLTE.iState = stateThrowAway cpLTE>>CPLTE.iLCB = 0 cpLTE>>CPLTE.iState = stateBiSyncInput EnableInterrupts() ] //---------------------------------------------------------------------------- and StartCPT(lcb) be //---------------------------------------------------------------------------- // Start ComProc transmission of a packet. [ DisableInterrupts() let cpLCB = lcb>>LCB.oCPLCB //Set up to output from oPBI. cpLCB>>CPLCB.byteCount = lcb>>LCB.oPBI>>PBI.packetLength cpLCB>>CPLCB.bytePointer = lv (lcb>>LCB.oPBI)>>CPPBI.type cpLCB>>CPLCB.firmStatus = 0 cpLCB>>CPLCB.hardStatus = 0 cpLCB>>CPLCB.partialCRC = 0 cpLT>>CPLT.cpLTE↑(lcb>>LCB.line).oLCB = cpLCB //Inform the EIA interface board that there is something new to do. (table [ mcChangeControlReg; 1401b ])(4*lcb>>LCB.line, 100100b) EnableInterrupts() ] //---------------------------------------------------------------------------- and StopCPT(lcb) be //---------------------------------------------------------------------------- // Disable ComProc transmission of a packet. [ DisableInterrupts() let cpLTE = lv cpLT>>CPLT.cpLTE↑(lcb>>LCB.line) //Put the line in throw-away state, then //remove the CPLCB from the CPLTE, then //put the line back into BiSync output state. cpLTE>>CPLTE.oState = stateThrowAway cpLTE>>CPLTE.oLCB = 0 cpLTE>>CPLTE.oState = stateBiSyncOutput EnableInterrupts() ]