// SwatSysInOut.bcpl - save/restore Swatee
// Copyright Xerox Corporation 1979, 1982
// Last Modified May 6, 1982  3:40 PM by Taft

get "Swat.decl"
get "streams.d"

external
[
// outgoing procedures
SysOut; SysIn

// incoming procedures from Swat
ReportFail; SetFailPt; UnSetFailPt
SymSysIn; ResidentSysIn; BreakSysIn; StackSysIn
SymSysOut; ResidentSysOut; BreakSysOut; StackSysOut
StopSpy; ResidentSwapIn; VMCache; ReadString; SymReset

// incoming procedures from OS
Allocate; Free; Ws; Zero; Usc
OpenFile; Closes; Gets; Puts
ReadBlock; WriteBlock; FileLength
ReadDiskDescriptor; WriteDiskDescriptor

// incoming statics
swatVersion; sysZone; vm
]

//----------------------------------------------------------------------------
let SysOut() be
//----------------------------------------------------------------------------
[
let name = ReadString("SysOut file name: ")
if name eq 0 return
ReadDiskDescriptor()
let sysOut = OpenFile(name)
Free(sysZone, name)
let swatee = OpenFile("Swatee", ksTypeReadOnly) 

let buf = 0
SetFailPt(so)
   [
   StopSpy()
   VMCache(vm, vmFlush)

   let lenBuf = 77777b
   buf = Allocate(sysZone, lenBuf, lv lenBuf) repeatuntil buf ne 0
   let toDo = 377b*400b  //copy 377b pages from sysIn file to swatee
   while toDo ne 0 do
      [
      let read = ReadBlock(swatee, buf, Usc(lenBuf, toDo) le 0? lenBuf, toDo)
      WriteBlock(sysOut, buf, read)
      toDo = toDo - read
      ]
   Free(sysZone, buf); buf = 0

   // version number of Swat tells format of internal state that follows
   Puts(sysOut, 31415)
   Puts(sysOut, swatVersion)
   Puts(sysOut, 21718)

   // Dump the internal state of swat.
   ResidentSysOut(sysOut)
   BreakSysOut(sysOut)
   StackSysOut(sysOut)
   SymSysOut(sysOut)
   UnSetFailPt()
   ]

so: 

if buf ne 0 then Free(sysZone, buf)
Closes(sysOut)
Closes(swatee)
WriteDiskDescriptor()
]

//----------------------------------------------------------------------------
and SysIn() be
//----------------------------------------------------------------------------
[
let name = ReadString("SysIn file name: ")
if name eq 0 return
let sysIn = OpenFile(name, ksTypeReadOnly)
if sysIn eq 0 then [ Free(sysZone, name); ReportFail("File not found") ]
let swatee = OpenFile("Swatee")

let buf = 0
SetFailPt(si)
   [
   StopSpy()
   SymReset()
   VMCache(vm, vmFlushReset)

   let lenBuf = 77777b
   buf = Allocate(sysZone, lenBuf, lv lenBuf) repeatuntil buf ne 0
   let toDo = 377b*400b  //copy 377b pages from swatee to sysOut file
   while toDo ne 0 do
      [
      let read = ReadBlock(sysIn, buf, Usc(lenBuf, toDo) le 0? lenBuf, toDo)
      WriteBlock(swatee, buf, read)
      toDo = toDo - read
      ]
   Free(sysZone, buf); buf = 0

   // See if internal state format is compatible with this Swat
   let vers = vec 2; ReadBlock(sysIn, vers, 3)
   if vers!0 ne 31415 % vers!1 ls sysInOutVersion % vers!2 ne 21718 then
      [
      Ws("The SysIn file is incompatible with this version of Swat.*N")
      Ws("The core image is ok, but symbols, breakpoints etc are lost.*N")
      FileLength(sysIn)
      ]

   ResidentSysIn(sysIn)
   BreakSysIn(sysIn)
   StackSysIn(sysIn) 
   SymSysIn(sysIn, name)
   UnSetFailPt()
   ]

si:

Free(sysZone, name)
ResidentSwapIn()
if buf ne 0 then Free(sysZone, buf)
Closes(sysIn)
Closes(swatee)
]