// February 17, 1978 7:14 PM *** resident ***
get "zpDefs.bcpl"
// outgoing procedures:
external [
overlay
obtainBlock
maxBlockSize
getBlock
putBlock
trimBlock
giveUp
CheckPSerror
pushDTTstack
flushDTTstack
]
// incoming procedures:
external [
MoveBlock // SYSTEM
Allocate
Free
Gets
Closes
CreateDiskStream
PositionPage
ReadBlock
typeForm // ZPUTIL
FatalError
]
// incoming statics:
external [
@freeStorageZone // ZPINIT
@freeStorageSize
@overlayTable
@DTTstack
@DTTstackTop
keys // SYSTEM
]
//-------------------------------------------------------------------
let overlay(i) = valof [overlay
//-------------------------------------------------------------------
if overlayTable>>OVT.current eq i resultis true
let overlayStream=CreateDiskStream(lv(overlayTable>>OVT.fp), ksTypeReadOnly)
PositionPage(overlayStream, overlayTable>>OVT.pn↑i)
let ovl=vec 16
ReadBlock(overlayStream, ovl, 16)
let PCstart=ovl!0
ReadBlock(overlayStream, PCstart, ovl!4 - 16)
// relocate statics:
let relTable=PCstart + ovl!3 - 16
let relTableLength=2*relTable!0
for p=1 to relTableLength by 2 do
@(relTable!p)=relTable!(p+1) + PCstart
Closes(overlayStream)
overlayTable>>OVT.current=i
unless (overlayTable>>OVT.swat & (1 lshift (i-1))) eq 0 then [
typeForm(0, "Overlay ", 10, i, 0, ". Pause to SWAT*N")
Gets(keys)
]
resultis i
]overlay
//-------------------------------------------------------------------
and obtainBlock(n) = valof [obtainBlock
//-------------------------------------------------------------------
[ let r=Allocate(freeStorageZone, n, lv freeStorageSize)
if r resultis r
[ switchon pushDTTstack() into [
case 0: resultis 0
case 1: loop
case 2: break
] repeat
] repeat
]obtainBlock
//-------------------------------------------------------------------
and getBlock(n) =
//-------------------------------------------------------------------
Allocate(freeStorageZone, n, lv freeStorageSize)
//-------------------------------------------------------------------
and maxBlockSize() =
//-------------------------------------------------------------------
Allocate(freeStorageZone, #77777, lv freeStorageSize)
//-------------------------------------------------------------------
and putBlock(block) =
//-------------------------------------------------------------------
(block ? Free(freeStorageZone, block), 0)
//-------------------------------------------------------------------
and trimBlock(block, freeWord) be [
//-------------------------------------------------------------------
if @(block-1) eq 0 then block=block-1
let usedLength=freeWord-block+1
let freeLength=(-@(block-1))-usedLength
if freeLength ls 6 return
@(block-1)= -usedLength
@freeWord= -freeLength
Free(freeStorageZone, freeWord+1)
]
//-------------------------------------------------------------------
and giveUp(proc,p1,p2,p3,p4,p5,p6,p7,p8; numargs n) = valof [giveup
//-------------------------------------------------------------------
// proc is procedure name
// pi are free storage blocks to return
let p=lv p1
for i=0 to n-2 do putBlock(p!i)
typeForm(0,proc,0," Sorry, not enough storage: the command has been aborted*N")
resultis 0
]giveup
//-------------------------------------------------------------------
and CheckPSerror(error) = valof [
//-------------------------------------------------------------------
// check if out of storage
if error eq 1 then resultis 0
FatalError("PSpline", error)
]
//-------------------------------------------------------------------
and flushDTTstack() be [flushDTTstack
//-------------------------------------------------------------------
[ if pushDTTstack() eq 0 break ] repeat
maxBlockSize()
]flushDTTstack
//-------------------------------------------------------------------
and pushDTTstack() = valof [pushDTTstack
//-------------------------------------------------------------------
// DTTstackTop < 0 : error
if DTTstackTop ls 0 then typeForm(0,"[expunge] stack error*N")
// DTTstackTop = 0 : nothing to push down !
if DTTstackTop le 0 resultis 0
let count=DTTstack>>stackCOUNT.count
let code=DTTstack>>stackCOUNT.code
let total=count + code + 1
if code eq 0 then
for i=1 to count do putBlock(DTTstack!i)
DTTstackTop=DTTstackTop-total
if DTTstackTop gr 0 then
MoveBlock(DTTstack, DTTstack+total, DTTstackTop)
resultis code eq 0 ? 2, 1
// result 0: nothing to push down
// result 1: no storage freed
// result 2: some storage freed
]pushDTTstack