// ResistState.bcpl

// Last modified November 6, 1979  2:40 PM

get "Resist.decl"
get "Streams.d"
get "AltoFileSys.d"

external
[
// outgoing procedures
InitState; ScalarState; StringState; ICState
GetBlock; PutBlock; ReEstablishStream

// incoming procedures
SymbolsObject; ObjectsString; MustLookupSymbol; ReportError
OpenFile; CreateDiskStream; JumpToFa
Gets; Puts; Allocate; Free; CallSwat

// outgoing statics
stateStream

// incoming statics
serialNumber; errorTolerance; maxNPins; stuffed
resName; outName; symbolTable
sysZone
]

static
[
stateStream
]

// ---------------------------------------------------------------------------
let InitState(restore) be
// ---------------------------------------------------------------------------
[
stateStream = OpenFile("Resist.state$", ksTypeReadWrite, wordItem)
if stateStream eq 0 then
   [ ReportError("Cannot restart -- Resist.state$ missing"); abort ]
ScalarState(restore, lv serialNumber, lv errorTolerance, lv maxNPins,
 lv stuffed)
StringState(restore, lv resName, lv outName)
]

// ---------------------------------------------------------------------------
and ScalarState(restore, lvScalar, nil, nil, nil, nil, nil, nil, nil, nil,
 nil, nil; numargs na) be
// ---------------------------------------------------------------------------
[
let lvLvScalar = lv lvScalar
for i = 0 to na-2 do
   test restore
      ifso @(lvLvScalar!i) = Gets(stateStream)
      ifnot Puts(stateStream, @(lvLvScalar!i))
]

// ---------------------------------------------------------------------------
and StringState(restore, lvString, nil, nil, nil, nil, nil, nil, nil, nil,
 nil, nil; numargs na) be
// ---------------------------------------------------------------------------
[
let lvLvString = lv lvString
for i = 0 to na-2 do
   test restore
      ifso
         [
         let word0 = Gets(stateStream)
         let lenString = word0<<String.length rshift 1 +1
         let string = Allocate(sysZone, lenString)
         string!0 = word0
         GetBlock(stateStream, string+1, lenString-1)
         @(lvLvString!i) = string
         ]
      ifnot
         [
         let string = @(lvLvString!i)
         let lenString = string>>String.length rshift 1 +1
         PutBlock(stateStream, string, lenString)
         ]
]

// ---------------------------------------------------------------------------
and ICState(restore, ic) = valof
// ---------------------------------------------------------------------------
[
test restore
   ifso
      [
      let icString = nil
      StringState(true, lv icString)
      ic = SymbolsObject(MustLookupSymbol(symbolTable, icString))
      Free(sysZone, icString)
      ]
   ifnot
      [
      let icString = ObjectsString(ic)
      StringState(false, lv icString)
      ]
for i = 1 to ic>>IC.nPins do
   ScalarState(restore, lv ic>>IC.pins↑i.expectedOhms)
resultis ic
]

// ---------------------------------------------------------------------------
and GetBlock(stream, block, length) be
// ---------------------------------------------------------------------------
   for i = 0 to length-1 do block!i = Gets(stream)

// ---------------------------------------------------------------------------
and PutBlock(stream, block, length) be
// ---------------------------------------------------------------------------
   for i = 0 to length-1 do Puts(stream, block!i)

// ---------------------------------------------------------------------------
and ReEstablishStream(cfa, ksType, itemSize) = valof
// ---------------------------------------------------------------------------
[
let stream = CreateDiskStream(lv cfa>>CFA.fp, ksType, itemSize)
if stream eq 0 then CallSwat("CreateDiskStream failed")
JumpToFa(stream, lv cfa>>CFA.fa)
resultis stream
]