// IfsScavPrint.bcpl
// Copyright Xerox Corporation 1979
// Last modified December 28, 1979  3:59 AM by Boggs

get "IfsScavenger.decl"
get "AltoFileSys.d"
get "Disks.d"
get "Tfs.d"

external
[
// outgoing procedures
PrintTime; PrintPLME
PrintDiskError; PrintRealDA

// incoming procedures
PutTemplate; Ws
ReadCalendar; DoubleDifference

// incoming statics
dsp; pass; phase; plme
]

//----------------------------------------------------------------------------
let PrintTime(startTime) be
//----------------------------------------------------------------------------
[
let stopTime = vec 1; ReadCalendar(stopTime)
let seconds = DoubleDifference(stopTime, startTime)
if pass ne 0 then PutTemplate(dsp, "*N[$D-$D] ", pass, phase)
PutTemplate(dsp, "Time = $D:$2F0D", seconds/60, seconds rem 60)
]

//----------------------------------------------------------------------------
and PrintPLME(vda) be
//----------------------------------------------------------------------------
[
PutTemplate(dsp, "*N[$D-$D]*TFID $EUO;$UO, page number $UO, num chars $UO",
 pass, phase, lv plme>>PLME.sn1, plme>>PLME.vn,
 plme>>PLME.pn, plme>>PLME.numChars)
PutTemplate(dsp, "*N[$D-$D]*Tcurrent vda $UO, previous vda $UO, next vda $UO",
 pass, phase, vda, plme>>PLME.backP, plme>>PLME.nextP)
]

//----------------------------------------------------------------------------
and PrintDiskError(cb) be
//----------------------------------------------------------------------------
// Called from various Hard disk error routines.
[
if pass ne 0 then PutTemplate(dsp, "*N[$D-$D] ", pass, phase)
PutTemplate(dsp, "Hard disk error at vda $UO ($P)",
 cb>>CB.vDiskAddress, PrintRealDA, lv cb>>CB.diskAddress)
PrintDiskStatus("header", lv cb>>CB.CommH)
PrintDiskStatus("label", lv cb>>CB.CommL)
PrintDiskStatus("data", lv cb>>CB.CommD)
]

//----------------------------------------------------------------------------
and PrintDiskStatus(record, kcbBlock) be
//----------------------------------------------------------------------------
// Prints a record status block in human-readable form.
// 'record' is one of the strings "Header", "Label", or "Data".
// 'kcbBlock' is a KCBblock structure from a TFS control block.
[
if pass ne 0 then PutTemplate(dsp, "*N[$D-$D] ", pass, phase)
PutTemplate(dsp, "$S $S status: ",
 selecton kcbBlock>>KCBblock.Comm into
   [
   case diskRead: "read"
   case diskCheck: "check"
   case diskWrite: "write"
   case diskReset: "reset"
   case diskRestore: "restore"
   case diskNoop: "noop"
   default: "unknown action on"
   ], record)

for i = 0 to 15 do
   if (kcbBlock>>KCBblock.Status & 1 lshift i) ne 0 then
      Ws(selecton 1 lshift i into
         [
         case 100000b: "seekIncomplete "
         case 40000b: "cylinderOverflow "
         case 20000b: "deviceCheck "
         case 10000b: "notSelected "
         case 4000b: "notOnLine "
         case 2000b: "notReady "
         case 1000b: "sectorOverflow "
         case 400b: "writeDataLate "
         case 200b: "readDataLate "
         case 100b: "checkError "
         case 40b: "readOnly "
         case 20b: "offset "
         case 10b: "unfixableECC "
         default: ""
         ])
if kcbBlock>>KCBblock.Status eq 1 then Ws("Good")
if kcbBlock>>KCBblock.Status eq 0 then Ws("0")
]

//----------------------------------------------------------------------------
and PrintRealDA(stream, lvRealDA) be
//----------------------------------------------------------------------------
   PutTemplate(stream, "cyl $UD hd $UD sec $UD",
    lvRealDA>>DA.track, lvRealDA>>DA.head, lvRealDA>>DA.sector)