// SwatVM.bcpl - virtual memory
// Copyright Xerox Corporation 1980, 1982
// Last modified March 24, 1982  4:09 PM by Boggs

get "Swat.decl"
get "Altodefs.d"

external
[
// outgoing procedures
VMSpace; VMFetch; VMStore; VMSwap; VMCache; VMPrint

// incoming procedures
CreateKVM; CreateNVM; ReportFail; StopSpy
SymReset; DelAllBreaks; ResidentSwapIn; StackSwapIn

PutTemplate; Wss; ReadString; StringCompare
Allocate; Free; Zero; SetBlock; MoveBlock; Noop

// outgoing statics
vm

// incoming statics
sysZone
]

static vm

//----------------------------------------------------------------------------
structure CVM:		// Core Virtual Memory
//----------------------------------------------------------------------------
[
@VM
userBank0 word		// user's bank reg for task 0
]
manifest lenCVM = size CVM/16

//----------------------------------------------------------------------------
let VMSpace() be	// ↑Z command
//----------------------------------------------------------------------------
[
let string = ReadString("Target address space: "); if string eq 0 return

let newVM = nil
test StringCompare(string, "Bank0") eq 0 %
     StringCompare(string, "Bank1") eq 0 %
     StringCompare(string, "Bank2") eq 0 %
     StringCompare(string, "Bank3") eq 0
   ifso newVM = CreateCVM(string)
   ifnot test string>>String.char↑1 eq $[
      ifso newVM = CreateNVM(string)
      ifnot newVM = CreateKVM(string)

StopSpy()
DelAllBreaks()
SymReset()
(vm>>VM.destroy)(vm)
vm = newVM
StackSwapIn()
ResidentSwapIn()
]

//----------------------------------------------------------------------------
and VMFetch(addr) = (vm>>VM.fetch)(vm, addr)
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
and VMStore(addr, val) be (vm>>VM.store)(vm, addr, val)
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
and VMSwap() be (vm>>VM.swap)(vm)
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
and VMCache(action) be (vm>>VM.cache)(vm, action)
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
and VMPrint(stream, verbose) be
//----------------------------------------------------------------------------
[
PutTemplate(stream, "Address space: $S", vm>>VM.name)
if verbose then (vm>>VM.print)(vm, stream)
]

//----------------------------------------------------------------------------
and CreateCVM(string) = valof
//----------------------------------------------------------------------------
[
let bank = selecton string>>String.char↑(string>>String.length) into
   [
   case $0: 0
   case $1: 1
   case $2: 2
   case $3: 3
   default: -1
   ]
if bank eq -1 then ReportFail(" ??")
let machineType = (table [ 61014b; 1401b ])()<<VERS.eng
if bank ne 0 then unless machineType eq 3 % machineType eq 5 do
   ReportFail("This machine does not have extended memory")
let cvm = Allocate(sysZone, lenCVM)
SetBlock(cvm, Noop, lenVM)
cvm>>VM.destroy = CVMDestroy
cvm>>VM.name = string
cvm>>VM.type = vmTypeCore
test bank eq 0
   ifso
      [
      cvm>>VM.fetch = Bank0Fetch
      cvm>>VM.store = Bank0Store
      ]
   ifnot
      [
      cvm>>VM.fetch = XMFetch
      cvm>>VM.store = XMStore
      cvm>>CVM.userBank0 = bankRegs!0
      bankRegs!0 = bank
      ]
MoveBlock(cursorBitMap, table [ 100000b; 140000b; 160000b; 170000b;
 174000b; 176000b; 177000b; 170000b; 154000b; 114000b; 006000b;
 006000b; 003000b; 003000b; 001400b; 001400b ], 16)
resultis cvm
]

//----------------------------------------------------------------------------
and Bank0Fetch(cvm, addr) = @addr
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
and Bank0Store(cvm, addr, val) be @addr = val
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
and XMFetch(cvm, addr) = (table [ 61025b; 1401b ])(nil, addr)
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
and XMStore(cvm, addr, val) be (table [ 61026b; 1401b ])(val, addr)
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
and CVMDestroy(cvm) be
//----------------------------------------------------------------------------
[
bankRegs!0 = cvm>>CVM.userBank0
Free(sysZone, cvm>>CVM.name)
Free(sysZone, cvm)
]