// This code is filed under TDPUtil.bcpl
// Utility routines for the Diagnostic Program for Dual Density Alto Magnetic Tapes
// Last modified by Tim Diebert, March 5, 1981 4:48 PM
// Copyright Xerox, 1981

get "DDTapes.d"
get "MenuDefs.d"
get "AltoDefs.D"
get "TDPDefs.d"
get "TDPMenuNames.d"


structure String [ length byte; char↑1,1 byte ]

manifest
[
muchcore=#76000
// mode names
octal = 0
ascii = 1
ebcdic = 2
bytemode = 3
// ASCII stuff
CR = #15
]

structure BT:
[
char↑0,0 byte
]

let Dump(prompt,lvfield,length) be
[
length = (length + 1) rshift 1
let skip = #7
let mask = " $6UF0O"
let offmask = #177
let startlength = length
if (mode ne 0) do [ skip = #37; mask = "$C$C"]
if (mode eq 3) do [ skip = #7; mask = " $3UF0O $3UF0O"; offmask = #377]
Wss(dumpstream,prompt);
if LogFlag then PutTemplate(LogFile,prompt)
while (length ne 0) & (not Blue()) do
[
if ( (startlength-length+1) & skip) eq 1 do
[
PutTemplate(dumpstream,"*N <$5F0D>:",(startlength-length) lshift 1)
if LogFlag then PutTemplate(LogFile,"*N <$5F0D>:",(startlength-length) lshift 1)
while Yellow() do Block()
]
test (mode ne 0)
ifnot
[
PutTemplate(dumpstream,mask,@lvfield) // Space between entries
if LogFlag then PutTemplate(LogFile,mask,@lvfield)
]
ifso
[
if (mode eq 2) do AsciiXlate(lvfield,1)
PutTemplate(dumpstream, mask, @lvfield rshift 8, @lvfield & offmask)
if LogFlag then PutTemplate(LogFile, mask, @lvfield rshift 8, @lvfield & offmask)
]
lvfield=lvfield+1 // then get the new address
length=length-1
]
Wss(dumpstream,"*N") // and do a final CRLF
if LogFlag then PutTemplate(LogFile,"*N")
]

and DispDDStatus() be
[
// set up status messages
let temp = vec 17
BitMsg = temp
BitMsg!1 = " RDY"
BitMsg!2 = " ONL"
BitMsg!3 = " RWD"
BitMsg!4 = " FPT"
BitMsg!5 = " BOT"
BitMsg!6 = " EOT"
BitMsg!7 = " FMK"
BitMsg!8 = " NRZI "
BitMsg!9 = " HE "
BitMsg!10 = " SE "
BitMsg!11 = " DL"
BitMsg!12 = " RDP"
BitMsg!13 = " ICL "
BitMsg!14 = " HDWERR"
BitMsg!15 = " WFP "
BitMsg!16 = " CMDER"
let x=#17

PutTemplate(dsp, "*nCmd: $7UF0O Cnt: $D ", vtape>>VDDTCB.Command, vtape>>VDDTCB.ByteCount)

if LogFlag then PutTemplate(LogFile, "*nCmd: $O Cnt: $D ", vtape>>VDDTCB.Command, vtape>>VDDTCB.ByteCount)


let i=1
let TapeState=vtape>>DDTCB.Flags
Wss(dsp,"*N STATUS: ")
if LogFlag then PutTemplate(LogFile, "*N STATUS: ")
[
if (TapeState & #100000) ne 0 do
[
Puts(dsp,$*s)
Wss(dsp,BitMsg!i)
Puts(dsp,$*s)
if LogFlag then
[
Puts(LogFile,$*s)
Wss(LogFile,BitMsg!i)
Puts(LogFile,$*s)
]
]
TapeState = TapeState lshift 1
i=i+1
] repeatuntil i eq 17
]

and CompareData() = valof
[
let matchflag = true
let len = Min(vtape>>VDDTCB.ByteCount,writel)
let wordcnt = (len rshift 1) & #77777
if UBlockEq(vtape>>VDDTCB.ReadBuffer, vtape>>VDDTCB.WriteBuffer, wordcnt) do
[
let i = len - 1
if readbuf>>BT.char↑i eq writebuf>>BT.char↑i do resultis true
]

for i = 0 to len-1 do
if readbuf>>BT.char↑i ne writebuf>>BT.char↑i do
[
if matchflag do Wss(dumpstream,"*n---Buffers Differ---")
if matchflag & LogFlag do PutTemplate(LogFile, "*n---Buffers Differ---")
matchflag = false
PutTemplate(dumpstream,"*n Byte: $4F0D WriteBuf: $8UF0B ReadBuf: $8UF0B XOR: $8UF0B",
i, writebuf>>BT.char↑i, readbuf>>BT.char↑i, (writebuf>>BT.char↑i xor
readbuf>>BT.char↑i))
if LogFlag then PutTemplate(LogFile,"*n Byte: $4F0D WriteBuf: $8UF0B ReadBuf: $8UF0B XOR: $8UF0B",
i, writebuf>>BT.char↑i, readbuf>>BT.char↑i, (writebuf>>BT.char↑i xor readbuf>>BT.char↑i))
]
if matchflag do resultis true
resultis false
]

and CompareRoutine() be
[
let matchflag = true
let len = Min(vtape>>VDDTCB.ByteCount,writel)
let wordcnt = (len rshift 1) & #77777
if UBlockEq(vtape>>VDDTCB.ReadBuffer, vtape>>VDDTCB.WriteBuffer, wordcnt) do
[
let i = len - 1
if readbuf>>BT.char↑i eq writebuf>>BT.char↑i do
[
Wss(dumpstream, "*n---buffers match---")
return
]
]

for i = 0 to len-1 do
[
if Blue() return
if readbuf>>BT.char↑i ne writebuf>>BT.char↑i do
[
if matchflag do Wss(dumpstream,"*n---Buffers Differ---")
matchflag = false
PutTemplate(dumpstream,"*n Byte: $4F0D WriteBuf: $8UF0B ReadBuf: $8UF0B XOR: $8UF0B", i, writebuf>>BT.char↑i, readbuf>>BT.char↑i, (writebuf>>BT.char↑i xor readbuf>>BT.char↑i))
]
]
if matchflag do Wss(dumpstream, "*n---buffers match---")
]

and PatternRoutine() be
[
Wss(dumpstream,"*nUsing Default Pattern? ")
let ans = Gets(keys)
Puts(dumpstream,ans)
test ans eq $y % ans eq $Y % ans eq CR
ifso
[
for i = 0 to writel-1 do writebuf>>BT.char↑i = ( i & #377 )
]
ifnot
[
let patlen = nil
[
Wss(dumpstream,"*nPattern Length: ")
patlen = GetInt(10)
] repeatuntil patlen gr 0 & patlen le 32
for j = 0 to Min(patlen-1,writel-1) do
[
PutTemplate(dumpstream, "*nEntry Number $D (base 8): ", j)
writebuf>>BT.char↑j = GetInt(8)
]
if patlen ls writel do
for j = patlen to writel do
writebuf>>BT.char↑j = writebuf>>BT.char↑(j-patlen)
]
]

and GetInt(base) = valof
[
let ch = Gets(keys)
let total = 0
until Digit(ch) do ch = Gets(keys)
[
Puts(dumpstream,ch)
total = total * base + (ch-$0)
ch = Gets(keys)
] repeatwhile Digit(ch)
resultis total
]

and TapeTridentBoot() be
[
SetBLV(#177776) // all but task 0 back into ROM
StartIO(#100000) // boot!
@lvUserFinishProc=TapeTridentUFP
]

and SysStr(string) = valof
[
let streadl = string>>STRING.length rshift 1 + 1
let sysstring = Allocate (sysZone,streadl)
MoveBlock (sysstring,string,streadl)
resultis sysstring
]

and StrToInt(string) = valof
[
let total = 0
for i = 1 to string>>STRING.length do
total = total*10 + (string>>STRING.char↑i - $0)
resultis total
]

and Min(a,b) = a ls b ? a,b

and Digit(arg) = arg ge $0 & arg le $9

and Blue() = utilIn>>UtilIn.blue eq 0

and Yellow() = utilIn>>UtilIn.yellow eq 0

and TapeErrProc(foo) be
[
Wss(dsp, foo)
if LogFlag then
[
// write Ascii string to word stream. What a pain!
if foo>>String.length gr 1 then
for i = 1 to foo>>String.length-1 by 2 do
Puts(LogFile, foo>>String.char↑i lshift 8 + foo>>String.char↑(i+1))
Puts(LogFile, (foo>>String.length & 1) eq 0? 0,
foo>>String.char↑(foo>>String.length) lshift 8)
]
]


and DisplayCounts() be
[
PutTemplate(dsp,"*NPass: $D Ops: $D Rty: $D Rty>1: $D Rgp: $D LowThr: $D UR: $D Bad Data: $D ", NumReel, NumOperationsThisPass, NumRetries, NumRetriesgt1, NumReGaps, NumLowThreshold, NumPersistant, NumBadData)

if LogFlag then
[
PutTemplate(LogFile,"*NPass: $D Ops: $D Rty: $D Rty>1: $D Rgp: $D LowThr: $D UR: $D Bad Data: $D ", NumReel, NumOperationsThisPass, NumRetries, NumRetriesgt1, NumReGaps, NumLowThreshold, NumPersistant, NumBadData)
]

]