// AIWorkb.bcpl
// Alto - 1822 Interface Test Program
// L. Stewart last modified: January 4, 1981 6:10 PM

// This module contains support procedures

get "AIMenuDefs.d"
get "AIMenuNames.d"
get "AIEditMenuNames.d"
get "AIHW.d"
get "AItest.d"

external //Incoming Procedures from Packages
[
Block //Context package
CreateStringStream //Strings package
PutTemplate //Template package
Dismiss //Altotimer package
ReadPackedRAM //Packed Ram package
Random //Random number gen package
SetBLV //LoadRam package
]

external //OS procedures
[
Closes; Gets; OpenFile; StartIO; Wss; Ws; ShowDisplayStream
Endofs
]
external //Incoming Procedures
[
SetInterruptMasks //from AIWork
]
external //Outgoing Procedures
[
WriteCStat
PutBoxTemplate
GetBoxNumber
GetBoxString
BlinkBox
EditPacket
SetResults
PrintBuffers
LoaduCode
SilentBoot
Update
Type
Contents
Cleanup
SetInterrupts
CheckBuffers
]

external //Incoming OS Statics
[
keys
]

external //Incoming Statics
[
iBuf //from AIWork
oBuf
BufSize
cb
CMask //from AITest
IMask
OMask
cInterrupt
iInterrupt
oInterrupt
red
yellow
blue
Menu
workS
menuStream
menuS
Blast
IMPNop //from AIComm
PRUTop
IMPEchoLeader
PRUEchoLeader
]

external //Outgoing Statics (in AIWorkb.bcpl)
[
PacketType //Imp?, Pru?, or what
PacketLength //echo test packet size
BufferPrintCount // PrintBuffers
uCodeFname //Name of packed Ram file
SBootVector //Boot Vector
updateInterval //Pinging process
AutoUpdateSwitch
PacketPattern //echo test data pattern
PacketLoopCount //test repititions
cIntSwitch //Interrupt enables
iIntSwitch
oIntSwitch
eMenuData //Edit menu handle
]

static
[
PacketType = typeRandom
PacketLength = 12
BufferPrintCount = 0
uCodeFname
SBootVector = #177736 // SilentBoot /task 5
updateInterval = 10 //Pinging process (tenths of seconds)
AutoUpdateSwitch = true
PacketLoopCount = 1
PacketPattern = #170360
cIntSwitch = false // interrupts on completion
iIntSwitch = false
oIntSwitch = false
]

static
[
eMenuData
index
M
Msel
]

let WriteCStat(stat;numargs na) be
[
PutBoxTemplate(Menu!ICountv,"#$6UF0O",cb>>CB.InputPointer-iBuf)
PutBoxTemplate(Menu!OCountv,"#$6UF0O",cb>>CB.OutputPointer-oBuf)
PutBoxTemplate(Menu!IPostv,"#$6UF0O",cb>>CB.InputPost)
PutBoxTemplate(Menu!OPostv,"#$6UF0O",cb>>CB.OutputPost)
PutBoxTemplate(Menu!CPostv,"#$6UF0O",cb>>CB.ControlPost)
test na le 0 ifso
[
FlipBox(Menu!status1,0)
FlipBox(Menu!status2,0)
FlipBox(Menu!status3,0)
]
ifnot
[
PutBoxTemplate(Menu!status1,stat<<POST.HostNotReady ? "Host Down", "Host Up")
PutBoxTemplate(Menu!status2,stat<<POST.ImpNotReady ? "Imp Down", "Imp Up")
PutBoxTemplate(Menu!status3,stat<<POST.ImpWasDown ? "Imp Was Down", " ")
]
]

and PutBoxTemplate(box,template,par1) be
[
let string = vec 16
let ss = CreateStringStream(string,30)
PutTemplate(ss,template,par1)
Closes(ss)
FlipBox(box,0)
WriteBox(box,string)
]

and GetBoxNumber(box,lvnumber) be
[
let first = true
let char = nil
let oldnumber = @lvnumber
PutBoxTemplate(box,"#$6UF0O",@lvnumber)
BlinkBox(box, 20)
@lvnumber = 0
[
if not blue while Endofs(keys) do
[
Block()
if Blast break
]
test Blast%blue ifso char = $*177
ifnot char = Gets(keys)
switchon char into
[
case $#: endcase
case $*n: // carriage return
[
if first then @lvnumber = oldnumber
break
]
case $*177: //break
[
@lvnumber = oldnumber
PutBoxTemplate(box,"#$6UF0O",@lvnumber)
break
]
case $0: case $1: case $2: case $3:
case $4: case $5: case $6: case $7:
[
@lvnumber = (@lvnumber * 8) + (char - $0)
endcase
]
case $*010: //backspace
[
@lvnumber = (@lvnumber rshift 3)
endcase
]
default: BlinkBox(box,20)
]
PutBoxTemplate(box,"#$6UF0O",@lvnumber)
first = false
] repeat
]

and GetBoxString(box,string) be
[
let first = true
let oldstring = string
PutBoxTemplate(box,"$S",string)
string>>STRING.length = 0
[
let length = string>>STRING.length
while Endofs(keys) do
[
Block()
if Blast break
]
let char = Blast ? $*177,Gets(keys)
switchon char into
[
case $*n: // carriage return
[
if first then docase $*177
break
]
case $*177: //break
[
string = oldstring
PutBoxTemplate(box,"$S",string)
break
]
case $*010: //backspace
[
if length gr 0 then string>>STRING.length = length-1
endcase
]
case $.:
[
if length ls 16 then string>>STRING.length = length+1
string>>STRING.char↑(length+1) = char
endcase
]
default:
[
if ((char ge $A)&(char le $Z)) docase $.
if ((char ge $a)&(char le $z)) docase $.
if ((char ge $0)&(char le $9)) docase $.
BlinkBox(box,20)
endcase
]
]
PutBoxTemplate(box,"$S",string)
first = false
] repeat
]

and BlinkBox(box,time) be
[
FlipBox(box)
Dismiss(time)
FlipBox(box)
]

and EditPacket() be
[
let buf,len = nil,nil
let r,y,b = nil,nil,nil
if blue return
M = eMenuData!0
ShowDisplayStream(menuStream,DSbelow,menuS)
until Blast do
[
Block()
Msel = ScanMenu(M,0,true)
r = (Msel & mred) ne 0
y = (Msel & myellow) ne 0
b = (Msel & mblue) ne 0
Msel = (Msel & #377)
switchon (Msel) into
[
case EPrint: PrintBuffers(r,y,b); endcase
case EIBuffer: buf = iBuf;len = PacketLength; docase EAdr
case EOBuffer: buf = oBuf;len = PacketLength; docase EAdr
case EIMPNop: buf = IMPNop;len = IMPLeaderlen; docase EAdr
case EIMPEcho: buf = IMPEchoLeader;len = IMPLeaderlen; docase EAdr
case EPRUEcho: buf = PRUEchoLeader;len = PRULeaderlen; docase EAdr
case EPRUTop: buf = PRUTop;len = PRULeaderlen; docase EAdr
case EAdr:
[
if (index ge len) then index = (len-1) rem 8
if r then index = 0
if b & (index le (len-8)) then index = index + 8
if y & (index gr 7) then index = index - 8
PutBoxTemplate(M!EAdr,"#$6UF0O",index)
for i = E0 to E7 do PutBoxTemplate(M!i,(index+i-E0 gr len) ? " ","#$6UF0O",buf!(index+i-E0))
endcase
if Msel eq EAdr then Msel = 0
]
case EQuit: FlipBox(M!Msel); break
case E0: case E1: case E2: case E3:
case E4: case E5: case E6: case E7:
if (index+Msel-E0 le len) then GetBoxNumber(M!Msel,lv buf!(index+Msel-E0))
Msel = 0
default:
]
if Msel then FlipBox(M!Msel)
]
ShowDisplayStream(menuStream,DSdelete)
]

and SetResults(ires,ores) be
[
let string = nil
let ustat = nil
ustat = ores ? (cb>>CB.OutputPost)<<POST.uCodeStat, 0
switchon ustat into
[
case allOK: string = "Output Done"; endcase
default: string = " "; endcase
]
PutBoxTemplate(Menu!status5,string)
ustat = ires ? (cb>>CB.InputPost)<<POST.uCodeStat, 0
switchon ustat into
[
case allOK: string = "Input Done"; endcase
case iBufFull: string = "Input Full"; endcase
case iBufLenZero: string = "Input BLZ"; endcase
case iBufFullDone: string = "Input RFull"; endcase
default: string = " "; endcase
]
PutBoxTemplate(Menu!status4,string)
]

and PrintBuffers(r,y,b) be
[
let errors = false
if r then BufferPrintCount = 0
if b & (BufferPrintCount ls (PacketLength-8))
then BufferPrintCount = BufferPrintCount + 8
if y & (BufferPrintCount gr 7) then BufferPrintCount = BufferPrintCount - 8
PutTemplate(workS,"*nOut: $UO:",BufferPrintCount)
let endc = BufferPrintCount + 7
if endc ge PacketLength then endc = PacketLength-1
for i = BufferPrintCount to endc do PutTemplate(workS," #$6UF0O",oBuf!i)
PutTemplate(workS,"*n In: $UO:",BufferPrintCount)
for i = BufferPrintCount to endc do PutTemplate(workS," #$6UF0O",iBuf!i)
for i = BufferPrintCount to endc do if iBuf!i ne oBuf!i then errors = true
if errors do
[
PutTemplate(workS,"*nxor: $UO:",BufferPrintCount)
for i = BufferPrintCount to endc do PutTemplate(workS," #$6UF0O",oBuf!i xor iBuf!i)
]
]

and LoaduCode() be
[
let RamStream = nil
BlinkBox(Menu!buCodeFname,50)
RamStream=OpenFile(uCodeFname,ksTypeReadOnly)
test RamStream eq 0
ifso Wss(workS,"Open Failed...*n")
ifnot
[
let res = ReadPackedRAM(RamStream)
if (res ne 0) then Ws("Ram Loading Error...*n")
Closes(RamStream)
]
]

and SilentBoot() be
[
BlinkBox(Menu!bBootVector,50)
SetBLV(SBootVector)
StartIO(#100000)
]

and Update() be
[
if red do GetBoxNumber(Menu!Updatev,lv updateInterval)
updateInterval = (updateInterval ls 1) ? 1, updateInterval
if blue % yellow do
[
AutoUpdateSwitch = not AutoUpdateSwitch
PutBoxTemplate(Menu!Updatev,AutoUpdateSwitch ? "#$6UF0O"," OFF",updateInterval)
]
]

and Type() be
[
PacketType = (PacketType + 1) rem maxTypeCount
let string = selecton PacketType into
[
case typeConstant: "Constant"
case typeRandom: "Random"
case typeEdit: "Edit"
]
red = false
PutBoxTemplate(Menu!Typev,string)
BlinkBox(Menu!bContents,30)
Contents()
]

and Contents() be
[
let string = nil
let number = nil
switchon PacketType into
[
case typeConstant:
[
if red then GetBoxNumber(Menu!Contentsv,lv PacketPattern)
string = "#$6UF0O"
number = PacketPattern
for i = 0 to PacketLength-1 do oBuf!i=PacketPattern
endcase
]
case typeRandom:
[
string = "Random"
if red then for i = 0 to PacketLength-1 do oBuf!i=Random()
endcase
]
case typeEdit:
[
string = "Edit..."
endcase
]
]
PutBoxTemplate(Menu!Contentsv,string,number)
]

and Cleanup() be
[
SetBLV(#177776)
StartIO(#100000)
finish
]

and SetInterrupts(arg) be
[
let string = vec 40
let ss = CreateStringStream(string,30)
if arg do
[
if red then cIntSwitch = not cIntSwitch
if yellow then iIntSwitch = not iIntSwitch
if blue then oIntSwitch = not oIntSwitch
]
let cc = cIntSwitch ? $c,$*s
let ic = iIntSwitch ? $i,$*s
let oc = oIntSwitch ? $o,$*s
test cIntSwitch%iIntSwitch%oIntSwitch
ifso PutTemplate(ss,"$C$C$C",cc,ic,oc)
ifnot PutTemplate(ss,"Off")
Closes(ss)
cc = cIntSwitch ? CMask,0
ic = iIntSwitch ? IMask,0
oc = oIntSwitch ? OMask,0
SetInterruptMasks(cc,ic,oc)
PutBoxTemplate(Menu!Interruptsv,"$S",string)
]

and CheckBuffers(switch,skip;numargs na) = valof
[
let errors = 0
if (na le 1) then skip = 0
for i = skip to PacketLength-1 do
[
if iBuf!i ne oBuf!i then errors = errors+1
]
if errors eq 0 resultis true
if switch then PutTemplate(workS," #$6UF0O ",errors)
resultis false
]