// STATEINIT.BCPL	Initialization for STATE.BCPL

get "state.d"


external [
// OS
	CallSwat; InitializeZone; sysZone; lvSysZone

// Program
	StateBlockSize

//STATE.BCPL
	GetStorage; EndStorage; Storage; NoStore; StateBlock; StatePtr

// Defined here
	StorageInit; SaveStatics
]

manifest [ codePtr = #335 ]

//Initialize the storage area, rebuild sysZone after Junta, allocate the
//StateBlock for subsequent use of BeginSave and SaveState.  FirstStatic
//is Layout!26 and LastStatic is Layout!27 as passed to the entry procedure
//by CallSubsys.  ErrRtn is called by GetStorage with the string
//"Out of storage", if storage is exhausted.
let StorageInit(FirstStatic,LastStatic,
		sysZoneSize,StackSize,ErrRtn; numargs NA) be
[	if NA < 5 then
	[ ErrRtn = CallSwat
	  if NA < 4 then StackSize = #4000
	]
	Storage = (rv codePtr)
	EndStorage = (lv sysZoneSize) - 10 - StackSize
	rv codePtr = EndStorage
	NoStore = ErrRtn eq 0 ? CallSwat,ErrRtn
	if (NA > 2) & (sysZoneSize ne 0) do
	[ sysZone = InitializeZone(GetStorage(sysZoneSize),sysZoneSize,
		0,ErrRtn)
	  rv lvSysZone = sysZone
	]
	StateBlock = GetStorage(StateBlockSize)
	StateBlock>>State.FirstS = FirstStatic
	StateBlock>>State.NStats = LastStatic-FirstStatic+1
	StatePtr = size State/16
]


//Fill in alternate words of StateBlock with pointers to page-zero statics
//to be saved.  The values are filled in by SaveState.

and SaveStatics(lv1,lv2,lv3,lv4,lv5,lv6,lv7,lv8,lv9,lv10,
	lv11,lv12,lv13,lv14,lv15,lv16,lv17,lv18,lv19,lv20; numargs NA) be
//Know that BCPL puts the args in sequential order on the stack
[	if NA > 20 then CallSwat("Too many args to SaveStatics")
	while NA > 0 do
	[ NA = NA-1; StateBlock!StatePtr = (lv lv1)!NA
	  StatePtr = StatePtr+2
	]
	if StatePtr > StateBlockSize then CallSwat("StateBlock too small")
]