//PupAlComProcInit.bcpl - Alto SLA initialization for ComProc interface // Code can be thrown away after use // Companion to PupAlComProcb.bcpl and PupAlComProca.bcpl // Copyright Xerox Corporation 1979, 1980 // Last modified March 9, 1980 6:21 PM by Taft get "Pup0.decl" get "PupAlComProc.decl" external [ //outgoing procedures InitAltoComProc //incoming procedures EncapsulateCPPup; SendCPPacket; SendCPStats CPPupFilter; CPRoutingFilter; StartCPR CPInterrupt; CPProcess; CPFinishProc; CPSwatContextProc InitializeContext; InitializeInterrupt; FindInterruptMask Allocate; Dequeue; Enqueue; SetBlock; Zero; SetTimer; Dismiss; Noop //outgoing statics cpNDB; cpLT; savedCPFinishProc; cpMcLoaded //incoming statics ndbQ; pbiIQ; pbiFreeQ; lenPup lvUserFinishProc ] static [ cpNDB; cpLT; savedCPFinishProc; cpMcLoaded ] //---------------------------------------------------------------------------- let InitAltoComProc(zone, ctxQ) be //---------------------------------------------------------------------------- //zone is where to get storage from //ctxQ is the context list on which to queue the interface process [ unless cpMcLoaded return //no microcode let atLeastOneLIM = false for line = 0 to maxLine do [ @(cpBase + 4*line + cpControl0) = 1 if @(cpBase + 4*line + cpControl0) eq 1 then [ atLeastOneLIM = true; break ] ] structure Vers: [ eng bit 4; build bit 4; mc bit 8 ] if (table [ #61014; #1401 ])()<>NDB.encapsulatePup = EncapsulateCPPup cpNDB>>NDB.level0Transmit = SendCPPacket cpNDB>>NDB.level0Stats = SendCPStats cpNDB>>NDB.destroy = Noop // not implemented yet cpNDB>>NDB.netType = netTypeSLA cpNDB>>NDB.deviceNum = 0 cpNDB>>NDB.pupPF.predicate = CPPupFilter cpNDB>>NDB.pupPF.queue = pbiIQ Enqueue(lv cpNDB>>NDB.pfQ, lv cpNDB>>NDB.pupPF) //InitAltoComProc (cont'd) //ComProc line control blocks for line = 0 to maxLine do [ let lcb = lv cpNDB>>CPNDB.lcb^line lcb>>LCB.line = line SetTimer(lv lcb>>LCB.rTimer, 0) ] //internal routing table SetBlock(lv cpNDB>>CPNDB.rt, -1, maxHost) cpNDB>>CPNDB.rPF.predicate = CPRoutingFilter cpNDB>>CPNDB.rPF.queue = lv cpNDB>>CPNDB.rIQ Enqueue(lv cpNDB>>NDB.pfQ, lv cpNDB>>CPNDB.rPF) Enqueue(ndbQ, cpNDB) //set up interface process Enqueue(ctxQ, InitializeContext(Allocate(zone, 150), 150, CPProcess)) //microcode Line Table // the +2 is for the CRC table pointer and a blank to pad to an even address cpLT = Allocate(zone, lenCPLT+2, false, true) Zero(cpLT, lenCPLT+2) //in particular all states = throwAway cpLT = cpLT+2 //CRC table let crcTable = Allocate(zone, 256) cpLT!-1 = crcTable for entry = 0 to 255 do [ let crc = 0 let value = entry for power = 0 to 7 do test (value & 1) eq 0 ifso value = value rshift 1 ifnot [ crc = crc xor (120001B rshift (7 - power)) value = (value rshift 1) xor 120001B ] crcTable!entry = crc ] //Assign an interrupt channel let intMask = InitializeInterrupt(Allocate(zone, 120), 120, FindInterruptMask(1), CPInterrupt) //Enable the microcode (table [ mcSetLineTab; #1401 ])(cpLT) //InitAltoComProc (cont'd) //Line Command Blocks for line = 0 to maxLine do [ let lcb = lv cpNDB>>CPNDB.lcb^line //Discover whether a LIM is plugged in. //We can handle up to maxLine lines, but if there are fewer LIMs // we can avoid wasting a pbi under receivers that don't exist. @(cpBase + 4*line + cpControl0) = 1 if @(cpBase + 4*line + cpControl0) ne 1 then //not there [ lcb>>LCB.state = slaLineMissing loop ] cpLT>>CPLT.cpLTE^line.exists = true let cpLCB = Allocate(zone, lenCPLCB, false, true) Zero(cpLCB, lenCPLCB) lcb>>LCB.iCPLCB = cpLCB cpLCB>>CPLCB.intMask = intMask cpLCB = Allocate(zone, lenCPLCB, false, true) Zero(cpLCB, lenCPLCB) lcb>>LCB.oCPLCB = cpLCB cpLCB>>CPLCB.intMask = intMask //Set up the hardware for reception. @(cpBase + 4*line + cpControl0) = 60B //DTR, RTS // @(cpBase + 4*line + cpControl0) = 64B //DTR, RTS, Wrap @(cpBase + 4*line + cpControl1) = 302B //8 bits, clock 0, synchronous @(cpBase + 4*line + cpSync) = 26B //SYN character //Put the microcode into BiSync state. let cpLTE = lv cpLT>>CPLT.cpLTE^line cpLTE>>CPLTE.iState = stateBiSyncInput cpLTE>>CPLTE.oState = stateBiSyncOutput //Start the receiver. lcb>>LCB.iPBI = Dequeue(pbiFreeQ) if lcb>>LCB.iPBI ne 0 then StartCPR(lcb) (table [ mcChangeControlReg; #1401 ])(4*line, #100200) //set rcvEnbl ] ]