// PupTestIO.bcpl
// Copyright Xerox Corporation 1979, 1982
// Last modified February 15, 1982 5:49 PM by Boggs
get "Pup.decl"
get "PupStats.decl"
get "PupTest.decl"
external
[
//outgoing procedures
GetString; GetNumber; PrintPort; Confirm
OpenPort; ComputeThruput; Ws; Wss
OtherSpigot; OtherSpigotProcess
PrintPupRT; RTTitle; RTEntry; PrintStatistics
//incoming procedures
Puts; Gets; Endofs; Resets
MoveBlock; Zero; DefaultArgs
Enqueue; Dequeue; Block
PutTemplate; EraseBits; CharWidth
OpenLevel1Socket; ReleasePBI; GetPartner
HLookup; HEnumerate
UpdateAverage; Divide32x16
//statics
dsp; keys
spigotQ; pupRT; pbiFreeQ
]
manifest realTimeClock = 430b
//----------------------------------------------------------------------------
let GetString(prompt, addr, echo, cr; numargs na) = valof
//----------------------------------------------------------------------------
[
//make a bcpl string from the keyboard
//if echo is true, echo the typed characters to the display
//returns false if del is typed (return to command level)
//addr is the address of the string that should get the result.
//prompt is a prompt string printed in the obvious places
if na ls 3 then echo = true
if na ls 4 then cr = true
Ws(prompt)
let count = 0
[
let char = Gets(keys)
switchon char into
[
case $*S: case $*N: case $*033:
[
Puts(dsp, (cr ? $*N, $*S))
addr>>String.length = count
resultis count ne 0
]
case $*177:
[ Ws("XXX"); Puts(dsp, (cr ? $*N, $*S)); resultis false ]
case $*001: case $*010:
[
if count then
[
if echo then
EraseBits(dsp, -CharWidth(dsp, addr>>String.char↑count))
count = count -1
]
endcase
]
default:
[
if count le 255 & char ge $*S & char le $*177 then
[
count = count + 1
addr>>String.char↑count = char
if echo then Puts(dsp, char)
]
endcase
]
]
] repeat
]
//----------------------------------------------------------------------------
and GetNumber(string) = valof
//----------------------------------------------------------------------------
[
Ws(string)
let res = 0
[
let char = Gets(keys)
switchon char into
[
case $0: case $1: case $2: case $3:
case $4: case $5: case $6: case $7:
[
Puts(dsp, char)
res = (res lshift 3) + (char & 7)
endcase
]
case $*001: case $*010:
[
EraseBits(dsp, -CharWidth(dsp, $0+(res&7)))
res = res rshift 3
endcase
]
case $*N: case $*S: case $*177: resultis res
]
] repeat
]
//----------------------------------------------------------------------------
and Confirm(prompt; numargs na) = valof
//----------------------------------------------------------------------------
[
if na gr 0 then Ws(prompt); Ws("[Confirm] ")
switchon Gets(keys) into
[
case $Y: case $y: case $*N:
[ Ws("Yes.*N"); resultis true ]
case $N: case $n: case $*177:
[ Ws("No.*N"); resultis false ]
default:
[ Ws("Yes or No*N"); endcase ]
]
] repeat
//----------------------------------------------------------------------------
and PrintPort(port) be
//----------------------------------------------------------------------------
PutTemplate(dsp,"[$UO#$UO#$UEO]", port>>Port.net, port>>Port.host,
lv port>>Port.socket)
//----------------------------------------------------------------------------
and OpenPort(string, soc, fs1, fs2, lclPort; numargs na) = valof
//----------------------------------------------------------------------------
[
DefaultArgs(lv na, -2, 0, 0, 0)
let frnPort = vec lenPort
let name = vec 40
[
unless GetString(string, name, true, false) resultis false
if GetPartner(name, dsp, frnPort, fs1, fs2) break
] repeat
OpenLevel1Socket(soc, lclPort, frnPort)
resultis true
]
//----------------------------------------------------------------------------
and Ws(string) be Wss(dsp, string)
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
and Wss(stream, string) be
//----------------------------------------------------------------------------
for i = 1 to string>>String.length do
Puts(stream, string>>String.char↑i)
//----------------------------------------------------------------------------
and ComputeThruput(tp) = valof
//----------------------------------------------------------------------------
[
let num = vec 1
MoveBlock(num, (alto? table [ 19; -28468], table [ 76; 19264]), 2)
Divide32x16(num, @realTimeClock-tp>>TP.timer)
PutTemplate(dsp, " [ $UD0 bytes/sec ]*N", num!1)
tp>>TP.thruput = num!1
tp>>TP.aveThruput = tp>>TP.aveThruput eq 0? tp>>TP.thruput,
UpdateAverage(tp>>TP.thruput, tp>>TP.aveThruput, 8)
]
//---------------------------------------------------------------------------
and PrintPupRT() be
//---------------------------------------------------------------------------
[
let PerNet(rte, lvCount) be
RTEntry(rte>>RTE.net, rte>>RTE.ndb>>NDB.localNet,
rte>>RTE.host, rte>>RTE.hops, lvCount)
let count = 0
RTTitle("Local routing table:")
HEnumerate(pupRT, PerNet, lv count)
Puts(dsp, $*N)
]
//----------------------------------------------------------------------------
and RTTitle(string) be
//----------------------------------------------------------------------------
[
Ws(string)
Ws("*N Net Via Hops | Net Via Hops | Net Via Hops | Net Via Hops")
Ws("*N -----------------|------------------|------------------|-----------------")
]
//----------------------------------------------------------------------------
and RTEntry(dNet, viaNet, viaHost, hops, lvCount) be
//----------------------------------------------------------------------------
[
if @lvCount rem 4 eq 0 then Ws("*N ")
PutTemplate(dsp, "$U3O $U3O#$U3F0O# $U2O ", dNet, viaNet, viaHost, hops)
unless @lvCount rem 4 eq 3 do Ws(" | ")
@lvCount = @lvCount +1
]
//----------------------------------------------------------------------------
and PrintStatistics() be
//----------------------------------------------------------------------------
[
let net = GetNumber("statistics for network ")
let rte = HLookup(pupRT, net)
if rte ne 0 then
[
let pbi = Dequeue(pbiFreeQ)
if rte>>RTE.ndb>>NDB.level0Stats(pbi, rte>>RTE.ndb) then
if rte>>RTE.hops eq 0 then
switchon pbi>>PBI.pup.words↑1 into
[
case netTypeEther:
[ PrintEtherStats(pbi); endcase ]
case netTypeSLA:
[ PrintSLAStats(pbi); endcase ]
]
Enqueue(pbiFreeQ, pbi)
]
]
//----------------------------------------------------------------------------
and PrintEtherStats(pbi) be
//----------------------------------------------------------------------------
[
Ws("*NEthernet Statistics:")
let es = lv pbi>>PBI.pup.words↑2
PutTemplate(dsp, "*nRcv: good $UD, bad $UD, off $UD",
es>>EtherStats.packetsRcvd, es>>EtherStats.numBadRcvStatus,
es>>EtherStats.inputOff)
PutTemplate(dsp, "; Xmt: good $UD, bad $UD; I|O $UD",
es>>EtherStats.packetsSent, es>>EtherStats.numBadXmtStatus,
es>>EtherStats.numInUnderOut)
Ws("*NLds:")
for i = 0 to 15 do
PutTemplate(dsp, " $UD", es>>EtherStats.loadTable↑i)
PutTemplate(dsp, "; Ovf: $UD", es>>EtherStats.loadTable↑16)
]
//----------------------------------------------------------------------------
and PrintSLAStats(pbi) be
//----------------------------------------------------------------------------
[
Ws("*NSLA Statistics:*N")
Ws(" ----Packets--- -----Bytes----- ------Errors------*n")
Ws("Line Sent Received Sent Received CRC Sync Control State*n")
let maxSLAHost = pbi>>PBI.pup.words↑2
let maxSLALine = pbi>>PBI.pup.words↑(maxSLAHost+3)
for line = 0 to maxSLALine do
[
let ss = lv pbi>>PBI.pup.words↑(maxSLAHost+4+lenSLAStats*line)
if ss>>SLAStats.state eq slaLineMissing loop
PutTemplate(dsp, "$3O$9ED$9ED$10ED$10ED $6D$6D$6D $S*n",
line, lv ss>>SLAStats.transmitPackets, lv ss>>SLAStats.receivePackets,
lv ss>>SLAStats.transmitBytes, lv ss>>SLAStats.receiveBytes,
ss>>SLAStats.badCRC, ss>>SLAStats.inputOverrun,
ss>>SLAStats.lineControlError,
selecton ss>>SLAStats.state into
[
case slaLineDown: "Down"
case slaLineUp: "Up"
case slaLineLoopedBack: "Looped back"
default: "?"
])
]
Ws("*nRouting table:*n")
for i = 1 to 4 do Ws("Host Line Hops ")
let count = 0
for i = 1 to maxSLAHost do
[
let rte = lv pbi>>PBI.pup.words↑(2+i)
if rte>>SLARTE.hopCnt ne #377 then
[
PutTemplate(dsp, "$S$3O $3O $3D", (count rem 4 eq 0? "*n", " "),
i, rte>>SLARTE.line, rte>>SLARTE.hopCnt)
count = count +1
]
]
Puts(dsp, $*n)
]
//---------------------------------------------------------------------------
and OtherSpigot(pbi) be Enqueue(spigotQ, pbi)
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
and OtherSpigotProcess() be
//---------------------------------------------------------------------------
[
while spigotQ!0 eq 0 do Block()
let pbi = Dequeue(spigotQ)
let startByte = 0
switchon pbi>>PBI.pup.type into
[
case typeAbort:
[
Ws("[Abort] ")
startByte = 3
endcase
]
case typeError:
[
Ws("[Error] ")
startByte = 25
endcase
]
case typeInterrupt:
[
Ws("[Interrupt] ")
startByte = 3
endcase
]
]
if startByte ne 0 then
[
for i = startByte to pbi>>PBI.pup.length-pupOvBytes do
Puts(dsp,pbi>>PBI.pup.bytes↑i)
Puts(dsp, $*N)
]
ReleasePBI(pbi)
] repeat