// PupControl.bcpl // Copyright Xerox Corporation 1979 // Last modified July 2, 1978 7:33 PM by Boggs get "Pup.decl" get "PupStats.decl" get "Puptest.decl" get "SysDefs.d" external [ //outgoing procedures SetFlag; Ows; MouseWatcher; Wss; GetStatistics; Ding SingleSelection; GetKeys; Confirm; GetName; GetString StateOfHost; UnAcked; ResetHost; InitHost; MiscServ //incoming procedures Allocate; Junta; CallSwat; Zero; DefaultArgs Block; Dismiss; CallContextList; Enqueue; Dequeue SetBitPos; GetFont; EraseBits; CharWidth; InvertLine Puts; Gets; Endofs; Resets; InitBootServ; AddNameToBFT SetTimer; TimerHasExpired; InitPupControl; PutTemplate GetPBI; ReleasePBI; CompletePup; FlushQueue CloseLevel1Socket; InitPupLevel1; OpenLevel1Socket SetAllocation; GetPartner; MayDayServ //incoming statics dsp; keys; zone; dis; trys; hT; ctxQ ] static [ trys ] manifest [ rtc = #430 display = #420 cursorY = #427 utilIn = #177030 ] //--------------------------------------------------------------------------- let PupControl() be Junta(levDisplay, AfterJunta) //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- and AfterJunta() be //--------------------------------------------------------------------------- [ InitPupControl() CallContextList(ctxQ!0) repeat ] //--------------------------------------------------------------------------- and InitHost(line, port) be //--------------------------------------------------------------------------- [ ResetHost(line) let soc = lv hT>>HT.soc↑line port>>Port.socket↑1 = 0 port>>Port.socket↑2 = socketPupControl OpenLevel1Socket(soc, 0, port) SetAllocation(soc, 2, 1, 1) hT>>HT.id↑line = @rtc Ows(hT>>HT.ds↑line, colNetHost, port) ] //--------------------------------------------------------------------------- and ResetHost(line) be //--------------------------------------------------------------------------- [ let soc = lv hT>>HT.soc↑line if soc>>PupSoc.frnPort.host ne 0 then CloseLevel1Socket(soc) Zero(lv hT>>HT.soc↑line, lenPupSoc) Zero(lv hT>>HT.cb↑line, lenCmmd) Zero(lv hT>>HT.stats↑line, lenStats) hT>>HT.selected↑line = false Resets(hT>>HT.ds↑line) ] //--------------------------------------------------------------------------- and StateOfHost(line) = selecton hT>>HT.stats↑line.state into //--------------------------------------------------------------------------- [ case stateStop: "Stop" case stateBSP: "BSP" case stateEFTP: "EFTP" default: " ? " ] //---------------------------------------------------------------------------- and GetStatistics(stream) be //---------------------------------------------------------------------------- [ let statSoc = vec lenPupSoc OpenLevel1Socket(statSoc, 0, table [ 0; 0; socketStatistics ]) for line = 1 to maxHosts do if hT>>HT.selected↑line & hT>>HT.soc↑line.frnPort.host then for try = 1 to tryHard do [ let pbi = nil let soc = lv hT>>HT.soc↑line [ pbi = GetPBI(statSoc, true); if pbi ne 0 break FlushQueue(lv statSoc>>PupSoc.iQ) Block() ] repeat pbi>>PBI.pup.dPort.net = soc>>PupSoc.frnPort.net pbi>>PBI.pup.dPort.host = soc>>PupSoc.frnPort.host pbi>>PBI.pup.words↑1 = soc>>PupSoc.frnPort.net CompletePup(pbi, typeSendStats, pupOvBytes+2) let gotIt = false let timer = nil; SetTimer(lv timer, 10) [ Block() repeatuntil statSoc>>PupSoc.iQ.head ne 0 % TimerHasExpired(lv timer) if TimerHasExpired(lv timer) break pbi = Dequeue(lv statSoc>>PupSoc.iQ) if pbi>>PBI.pup.sPort.host eq soc>>PupSoc.frnPort.host & pbi>>PBI.pup.type eq typeStatsAck then [ PrintEtherStats(stream, pbi); gotIt = true ] ReleasePBI(pbi) if gotIt break ] repeat if gotIt break ] CloseLevel1Socket(statSoc) ] //---------------------------------------------------------------------------- and PrintEtherStats(stream, pbi) be //---------------------------------------------------------------------------- [ PutTemplate(stream,"*N$UO#$UO#: ", pbi>>PBI.pup.sPort.net, pbi>>PBI.pup.sPort.host) let es = lv pbi>>PBI.pup.words↑2 PutTemplate(stream,"Rcv: good $UD, bad $UD, off $UD", es>>EtherStats.packetsRcvd, es>>EtherStats.numBadRcvStatus, es>>EtherStats.inputOff) PutTemplate(stream,"; Xmt: good $UD, bad $UD; I|O $UD", es>>EtherStats.packetsSent, es>>EtherStats.numBadXmtStatus, es>>EtherStats.numInUnderOut) Wss(stream,"*NLds:") for i = 0 to 15 do PutTemplate(stream, " $UD", es>>EtherStats.loadTable↑i) PutTemplate(stream, "; Ovf: $UD", es>>EtherStats.loadTable↑16) ] //---------------------------------------------------------------------------- and UnAcked() = valof //---------------------------------------------------------------------------- [ for i = 1 to maxHosts do if hT>>HT.cb↑i.cmmd ne 0 resultis true resultis false ] //---------------------------------------------------------------------------- and SetFlag(string, flag) be //---------------------------------------------------------------------------- [ Wss(dis, string) let ck = Confirm() trys = tryHard for i = 1 to maxHosts do if hT>>HT.selected↑i then [ hT>>HT.cb↑i.flags = ck? hT>>HT.cb↑i.flags % flag, hT>>HT.cb↑i.flags & not flag hT>>HT.cb↑i.cmmd = $T ] ] //---------------------------------------------------------------------------- and SingleSelection() = valof //---------------------------------------------------------------------------- [ let count,line = 0,0 for i = 1 to maxHosts do if hT>>HT.selected↑i then [ count = count+1; line = i ] if count ne 1 then [ Ding(dis) test count gr 1 ifso Wss(dis, "*NMultiple selection - command terminated") ifnot Wss(dis, "*NNo selection - command terminated") ] resultis count eq 1 ? line,0 ] //---------------------------------------------------------------------------- and Ows(stream, col, val, forceString; numargs na) be //---------------------------------------------------------------------------- //Write val to stream. col tells how to display val [ SetBitPos(stream, col<<Col.start) EraseBits(stream, col<<Col.width*10, 0) SetBitPos(stream, col<<Col.start) switchon na ls 4 ? col<<Col.type,1 into [ case 0: //Decimal number/10 [ PutTemplate(stream, "$UD0", val); endcase ] case 1: //bcpl string [ Wss(stream, val); endcase ] case 2: //Net#Host - val points to port structure [ PutTemplate(stream, "$UO#$UO", val>>Port.net, val>>Port.host) endcase ] case 3: //boolean [ Wss(stream, val ? "On","Off"); endcase ] ] ] //---------------------------------------------------------------------------- and GetKeys() = valof //---------------------------------------------------------------------------- [ Block() repeatwhile Endofs(keys) resultis Gets(keys) ] //---------------------------------------------------------------------------- and Confirm() = valof //---------------------------------------------------------------------------- [ Wss(dis," [Confirm] ") switchon GetKeys() into [ case $Y: case $y: case $*N: [ Wss(dis, "Yes."); resultis true ] case $N: case $n: [ Wss(dis, "No."); resultis false ] case $?: [ Wss(dis, " Yes or No: "); endcase ] default: [ Ding(dis); endcase ] ] repeat ] //---------------------------------------------------------------------------- and Ding(stream) be //---------------------------------------------------------------------------- [ InvertWindow(stream, true) Dismiss(25) InvertWindow(stream, false) ] //---------------------------------------------------------------------------- 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 ] //---------------------------------------------------------------------------- and Wss(stream, string) be //---------------------------------------------------------------------------- for i = 1 to string>>String.length do Puts(stream, string>>String.char↑i) //---------------------------------------------------------------------------- and GetName(port, soc1, soc2) = valof //---------------------------------------------------------------------------- [ let name = vec 127 unless GetString(name) resultis false resultis GetPartner(name, dis, port, soc1, soc2) ] //---------------------------------------------------------------------------- and GetString(addr) = valof //---------------------------------------------------------------------------- [ let count = 0 [ let char = GetKeys(); switchon char into [ case $*N: case $*S: [ Puts(dis, $*S) addr>>String.length = count resultis count ] case $*001: case $*010: [ if count ne 0 then [ EraseBits(dis, -CharWidth(dis, addr>>String.char↑count)) count = count-1 ] endcase ] case $*177: [ for i = count to 1 by -1 do EraseBits(dis, -CharWidth(dis, addr>>String.char↑i)) count = 0 endcase ] default: [ count = count+1 addr>>String.char↑count = char Puts(dis, char) endcase ] ] ] repeat ] //---------------------------------------------------------------------------- and MiscServ() be //a context //---------------------------------------------------------------------------- [ let socMisc = Allocate(zone,lenPupSoc) OpenLevel1Socket(socMisc, table [ 0; 0; socketMiscServices ]) InitBootServ(zone, ctxQ, socMisc) AddNameToBFT(bfnPupTest, "PupTest.boot") [ Block() repeatuntil socMisc>>PupSoc.iQ.head ne 0 let pbi = Dequeue(lv socMisc>>PupSoc.iQ) switchon pbi>>PBI.pup.type into [ case typeSendBootFile: [ MayDayServ(pbi); endcase ] default: ReleasePBI(pbi) ] ] repeat ] //---------------------------------------------------------------------------- and MouseWatcher() be //a context //---------------------------------------------------------------------------- //select and deselect lines [ Block() repeatwhile (@utilIn & 7) eq 7 let curY, button = @cursorY, @utilIn & 7 for i = 1 to maxHosts do if (curY ge hT>>HT.yMin↑i) & (curY ls hT>>HT.yMax↑i) then switchon button into [ case 3: //top or left or red [ ((hT>>HT.ds↑i)>>DS.cdcb)>>DCB.background = 1 hT>>HT.selected↑i = true break ] case 5: //bottom or right or green [ ((hT>>HT.ds↑i)>>DS.cdcb)>>DCB.background = 0 hT>>HT.selected↑i = false break ] ] ] repeat