// ScavEdit -- Disk editor
// Copyright Xerox Corporation 1979, 1980, 1981, 1982
// Last modified May 2, 1982 2:25 PM by Boggs
get "AltoFileSys.d"
get "Disks.d"
get "BFS.d"
external
[
// outgoing procedures
EditDisk
// incoming procedures
Confirm; Ws; XferPage
PutTemplate; VirtualDiskDA
Puts; Gets; Resets
SimpleDspEraseBits; SimpleDspCharWidth
// incoming statics
sysZone; sysDisk; keys; dsp
label; data; logFlag
]
static
[
address; number; numberTyped; termChar
pageOpen; cellOpen; pageDirty
]
//-----------------------------------------------------------------------------------------
let EditDisk() be
//-----------------------------------------------------------------------------------------
[
logFlag = true //write log
Ws("*NDisk editor here. If you don't know what I am type 'Q<cr>' NOW!*N")
ExaminePage(true)
switchon GetNumber() into
[
case $/:
address = number
ExaminePage(not numberTyped)
endcase
case $↑: case $*L:
test numberTyped
ifso Ws(" ?")
ifnot
[
address = address + (termChar eq $*L? 1, -1)
ExaminePage(true)
]
endcase
case $\:
test numberTyped % not pageOpen
ifso Ws(" ?")
ifnot
[
address = VirtualDiskDA(sysDisk, lv label>>DL.previous)
ExaminePage(true)
]
endcase
case $L: case $l:
EditPage(label, 8)
endcase
case $D: case $d:
EditPage(data, 256)
endcase
case $Q: case $q:
if Confirm("*NQuit disk editor [confirm]") break
endcase
case $*N:
Puts(dsp, $*N)
pageOpen = false
endcase
case $*177: endcase
default: Ws(" ?"); endcase
] repeat
]
//-----------------------------------------------------------------------------------------
and EditPage(buffer, length) be
//-----------------------------------------------------------------------------------------
[
if numberTyped % not pageOpen then [ Ws(" ?"); return ]
let diskAddress = address; address = 0
let diskNumber = number; number = 0
pageDirty = false
PutTemplate(dsp, "*NEditing $S record*N", buffer eq label? "label", "data")
ExamineCell(buffer, length, true)
switchon GetNumber() into
[
case $/:
address = number
ExamineCell(buffer, length, not numberTyped)
endcase
case $↑: case $*L:
if DepositCell(buffer) then
[
address = address + (termChar eq $*L? 1, -1)
ExamineCell(buffer, length, true)
]
endcase
case $Q: case $q:
if Confirm("*NQuit page editor [confirm]") break
endcase
case $*N:
Puts(dsp, $*N)
DepositCell(buffer)
endcase
case $*177: endcase
default: Ws(" ?"); endcase
] repeat
number = diskNumber
address = diskAddress
if pageDirty then XferPage(DCwriteLD, address)
ExaminePage(true)
]
//-----------------------------------------------------------------------------------------
and ExaminePage(printAddress) be
//-----------------------------------------------------------------------------------------
[
if address eq eofDA then [ Ws(" ?"); pageOpen = false; return ]
if printAddress then PutTemplate(dsp, "*N$U6Ob", address)
Ws("/ ")
XferPage(DCreadLD, address)
number = VirtualDiskDA(sysDisk, lv label>>DL.next)
PutTemplate(dsp, "SN $EUOb, PN $UD, NC $UD, backP $UOb, nextP $UOb ",
lv label>>DL.fileId.serialNumber, label>>DL.pageNumber, label>>DL.numChars,
VirtualDiskDA(sysDisk, lv label>>DL.previous), number)
pageOpen = true
]
//-----------------------------------------------------------------------------------------
and ExamineCell(buffer, length, printAddress) be
//-----------------------------------------------------------------------------------------
[
if address uge length then
[ if termChar ne $*L then Ws(" ?"); cellOpen = false; return ]
if printAddress then PutTemplate(dsp, "*N$UOb", address)
if buffer eq label then Ws(selecton address into
[
case 0: " = next "
case 1: " = back "
case 2: " = 0 "
case 3: " = NC "
case 4: " = PN "
case 5: " = VN "
case 6: " = SN1 "
case 7: " = SN2 "
])
Ws("/ ")
PutTemplate(dsp, "$6UOb ", buffer!address)
if buffer eq data then //also display as characters
[
let left = buffer!address rshift 8
let right = buffer!address & 377b
PutTemplate(dsp, "$3UOb $3UOb ", left, right)
PrintChar(left)
PrintChar(right)
]
number = buffer!address
cellOpen = true
]
//-----------------------------------------------------------------------------------------
and PrintChar(char) be
//-----------------------------------------------------------------------------------------
[
if char ls 40b then PutTemplate(dsp, "↑$C", char+100b)
if char ge 40b & char ls 176b then Puts(dsp, char)
]
//-----------------------------------------------------------------------------------------
and DepositCell(buffer) = valof
//-----------------------------------------------------------------------------------------
[
if numberTyped test cellOpen
ifso
[
buffer!address = number
pageDirty = true
]
ifnot
[
Ws(" ?")
resultis false
]
cellOpen = false
resultis true
]
//-----------------------------------------------------------------------------------------
and GetNumber() = valof
//-----------------------------------------------------------------------------------------
[
manifest maxStringChars = 7 //6 octal digits + minus sign
let string = vec maxStringChars //1 char per word
let count = 0 //chars in string
[
termChar = Gets(keys)
switchon termChar into
[
case $0 to $7: case $-:
if (termChar eq $-) ? (count eq 0), (count ls maxStringChars) then
[
Puts(dsp, termChar)
count = count +1
string!count = termChar
]
endcase
case $*001: case $*010: //↑A, BS
if count ne 0 then
[
SimpleDspEraseBits(dsp, -SimpleDspCharWidth(dsp, string!count))
count = count -1
]
endcase
case $*027: //↑W
for i = count to 1 by -1 do
SimpleDspEraseBits(dsp, -SimpleDspCharWidth(dsp, string!i))
count = 0
endcase
case $*177: Ws(" XXX"); count = 0 //falls through
default: break
]
] repeat
numberTyped = count ne 0
if numberTyped then
[
number = 0
let minus = false
if string!1 eq $- then minus = true
for i = (minus? 2, 1) to count do
number = number lshift 3 + (string!i & 7)
if minus then number = -number
]
resultis termChar
]