// AIComm.bcpl
// Alto - 1822 Interface Test Program
// L. Stewart last modified: January 8, 1981 1:04 AM
// L. Stewart last modified: August 29, 1983 4:29 PM
//
to use non-NCP link

// This module contains packet building procedures

get "AIHW.d"
get "AIMenuDefs.d"
get "AITest.d"

external //Incoming Procedures
[
MasterClear //from AIWork.bcpl
StartInput
StartOutput
StartLastOutput
CheckBuffers //from AIWorkb.bcpl
Contents
]

external //Incoming Procedures from packages
[
Block //Context package
PutTemplate //Template package
SetTimer //Timer package
TimerHasExpired
Dismiss
]

external //Incoming OS Procedures
[
Wss
]

external //Outgoing Procedures in AIComm.bcpl
[
Communicate
CAPEcho
Receiver
SendNop
SendEcho
MakeIMPNop
MakePRUNop
MakeIMPEcho
MakePRUEcho
DecodeIMPMessage
]
external //Incoming Statics
[
iBuf //from AIWork.bcpl
oBuf
BufSize
cb
PacketLength //from AIWorkb.bcpl
PacketLoopCount
Blast //from AITest.bcpl
workS
red
]
external //Outgoing Statics
[
CommFlag
ReceiverOn
IMPCommMode
IMPHostNumber
IMPImpNumber
PRUHostNumber
IMPNop
PRUTop
IMPEchoLeader
PRUEchoLeader
]

static
[
CommFlag = 0
ReceiverOn = false
IMPHostNumber = #2
IMPImpNumber = #40
PRUHostNumber = #010230
IMPCommMode = true // Else PRU
IMPNop
PRUTop
IMPEchoLeader
PRUEchoLeader
SequenceNum = 0
]

let Communicate() be
[
MasterClear()
CommFlag = 0
SequenceNum = 0
ReceiverOn = true
SendNop(IMPCommMode ? 3,1)
for i = 1 to PacketLoopCount do
[
SendEcho()
if Blast then break
CommFlag = CommFlag+1
if red then Block() repeatuntil (Blast % (not CommFlag))
if Blast then break
]
until Blast do Block() // run receiver until told to stop
ReceiverOn = false
Block() // unglue receiver!
MasterClear()
]

and CAPEcho() be
[
MasterClear()
Wss(workS,"Push Shift-Lock to stop !s. ")
let timer = nil
let rx = nil
SetTimer(lv timer,500)
StartInput(iBuf,iBuf+BufSize)
rx = 1
until Blast do
[
Block()
if TimerHasExpired(lv timer) do
[
Wss(workS,"~")
SetTimer(lv timer,500)
loop
]
if (rx eq 1)&(cb>>CB.InputPost ne 0) do
[
test ((cb>>CB.InputPost)<<POST.uCodeStat eq allOK)
ifso
[
if ((@(#177037)&(#0200)) ne 0) do Wss(workS,"!")
StartOutput(iBuf,cb>>CB.InputPointer)
rx = 0
]
ifnot
[
Wss(workS,"#")
MasterClear()
StartInput(iBuf,iBuf+BufSize)
]
loop
]
if (rx eq 0)&(cb>>CB.OutputPost ne 0) do
[
rx = 1
StartInput(iBuf,iBuf+BufSize)
loop
]
]
MasterClear()
]

and Receiver() be
[
let timer = nil
Block() repeatuntil ReceiverOn
SetTimer(lv timer,1000) // ten seconds
StartInput(iBuf,iBuf+BufSize)
until Blast do
[
Block()
if TimerHasExpired(lv timer) do
[
Wss(workS,"~")
CommFlag = 0
break
]
if (cb>>CB.InputPost ne 0) do // input finished
[
Block() // give CommFlag a chance
if ((cb>>CB.InputPost)<<POST.uCodeStat eq iBufFull) do
[
Wss(workS,"Ovflw ")
break
]
DecodeIMPMessage(workS)
test IMPCommMode
ifso
[
if (iBuf>>IMPLeader.MType eq 0) then
[
test (iBuf>>IMPLeader.Host eq IMPHostNumber) & (iBuf>>IMPLeader.Imp eq IMPImpNumber) & (CommFlag gr 0)
ifso
[
Wss(workS,CheckBuffers(false,IMPLeaderlen) ? "!","?")
CommFlag = CommFlag-1
]
ifnot PutTemplate(workS,"[#$o/#$o]",iBuf>>IMPLeader.Host, iBuf>>IMPLeader.Imp)
]
]
ifnot // PRU mode
[
test (iBuf>>PRULeader.Source eq PRUHostNumber) & (iBuf>>PRULeader.Type eq 3) & (CommFlag gr 0) // info pkt
ifso
[
Wss(workS,CheckBuffers(false,PRULeaderlen) ? "!","?")
CommFlag = CommFlag-1
]
ifnot
[
test (iBuf>>PRULeader.Type eq 3)
ifso PutTemplate(workS,"[#$6UF0O]", iBuf>>PRULeader.Source)
ifnot PutTemplate(workS,"(#$6UF0O)", iBuf>>PRULeader.Source)
]
]
break
]
]
] repeat

and SendNop(howMany) be
[
let NopPacketSize = (IMPCommMode ? MakeIMPNop, MakePRUNop)()
for i = 1 to howMany do
[
StartLastOutput(oBuf,oBuf+NopPacketSize)
until (Blast % cb>>CB.OutputPost) do Block()
]
Dismiss(100)
]

and SendEcho() be
[
let EchoPacketSize = (IMPCommMode ? MakeIMPEcho, MakePRUEcho)()
StartLastOutput(oBuf,oBuf+PacketLength)
until (Blast % cb>>CB.OutputPost) do Block()
]

and MakeIMPNop() = valof
[
IMPNop = table
[
#007400;#4;#003400;#0;#0;#0
]
PacketLength = (PacketLength gr IMPLeaderlen) ? PacketLength,IMPLeaderlen
IMPNop>>IMPLeader.Host = IMPHostNumber
IMPNop>>IMPLeader.Imp = IMPImpNumber
for i = 0 to IMPLeaderlen-1 do oBuf!i = IMPNop!i
resultis IMPLeaderlen
]

and MakePRUNop() = valof
[
PRUTop = table
[
0;0;0;0;0;0;0;0;0;0;0;0;0;0
]
SequenceNum = SequenceNum + #1
PRUTop>>PRULeader.HdrLen = PRULeaderlen
PRUTop>>PRULeader.PktLen = PRULeaderlen+2
PRUTop>>PRULeader.SeqNum = SequenceNum
for i = 0 to PRULeaderlen-1 do oBuf!i = PRUTop!i
oBuf!PRULeaderlen = PRUHostNumber
oBuf!(PRULeaderlen+1) = PRUHostNumber
resultis PRULeaderlen+2
]

and MakeIMPEcho() = valof
[
IMPEchoLeader = table
[
#007400;#0;#003400;#0;#044000;#0
]
PacketLength = (PacketLength gr IMPLeaderlen) ? PacketLength,IMPLeaderlen
IMPEchoLeader>>IMPLeader.Host = IMPHostNumber
IMPEchoLeader>>IMPLeader.Imp = IMPImpNumber
IMPEchoLeader>>IMPLeader.MsgID = SequenceNum
SequenceNum = SequenceNum + #1
Contents()
for i = 0 to IMPLeaderlen-1 do oBuf!i = IMPEchoLeader!i
resultis IMPLeaderlen
]

and MakePRUEcho() = valof
[
PRUEchoLeader = table
[
0;0;0;0;#064001;0;0;0;0;0;0;0;0;0
]
SequenceNum = SequenceNum + #1
PRUEchoLeader>>PRULeader.Source = PRUHostNumber
PRUEchoLeader>>PRULeader.Destination = PRUHostNumber
PRUEchoLeader>>PRULeader.HdrLen = PRULeaderlen
PacketLength = (PacketLength gr PRULeaderlen) ? PacketLength,PRULeaderlen
PRUEchoLeader>>PRULeader.PktLen = PacketLength
PRUEchoLeader>>PRULeader.SeqNum = SequenceNum
Contents()
for i = 0 to PRULeaderlen-1 do oBuf!i = PRUEchoLeader!i
resultis PRULeaderlen
]

and DecodeIMPMessage(strm) be
[
let typeString=nil
let st=#177777
test IMPCommMode
ifso
[
typeString=selecton iBuf>>IMPLeader.MType into
[
case 0: "" //Regular Message
case 1: "LdrErr" //Error in Leader
case 2: "IMPGoingDown" //IMP going down
case 4: "Nop"
case 5: "r" //RFNM
case 6: "Host Dead"
case 7: "Destination Dead"
case 8: "DatErr" //Error In Data
case 9: "Incomplete Transmission"
case 10: "Reset"
case 11: "Refused, Try Again"
case 12: "Refused, Will Notify"
case 13: "Refused, Still Trying"
case 14: "Ready"
case 15: "Type15"
default: "Unknown"
]
if (iBuf>>IMPLeader.MType ne 0) & (iBuf>>IMPLeader.MType ne 5) then st = iBuf>>IMPLeader.SubType
Wss(strm, typeString)
if st ne #177777 then
[
PutTemplate(workS, "($d,#$o/#$o)", iBuf>>IMPLeader.SubType, iBuf>>IMPLeader.Host, iBuf>>IMPLeader.Imp)
]
]
ifnot
[
typeString=selecton iBuf>>PRULeader.Type into
[
case 0: "ROP "
case 1: "Label "
case 2: "Control "
case 3: "" //Regular Message
case 4: "CtlData "
case 5: "Command "
case 6: "PDP "
default: "Unknown "
]
Wss(strm, typeString)
]
]