// MDmisc.bcpl -- miscellaneous services for MicroD
// last edited July 20, 1980 10:10 PM
get "mddecl.d"
external [ // defined here
StoreString // (str, zone) -> ptr
MaxBlock // (zone) -> length
ScratchZone // (base, length) -> zone
NextOverlay // ()
// Statics
PutTS
@Storage; @EndStorage
MinSpace
RealMin
// for initialization
GetLow; PutLow
GetStorage; PutStorage
RealPutTS
// OS replacements
Ws; Wss; Wo; Wos
]
external [
// OS
Allocate
CallSwat
Dvec
MoveBlock
Noop
Puts
Usc
Zero
dsp
// LoadOverlay
LoadOverlay
// Template
PutTemplate
// MDerr
Err
// MDmain
@OutputS
OverlayCFA; lvOverlayLoc; lOverlaySz
]
static [
PutTS // Noop or RealPutTS
Storage // top of temporary zone
EndStorage // bottom of permanent zone
MinSpace = -1
RealMin = -1
]
// Storage management
let GetStorage(nil, Size) = valof
[ PutTS("Get($O)", Size)
EndStorage = EndStorage-Size
CheckSpace()
Zero(EndStorage, Size)
resultis EndStorage
]
and CheckSpace() be
[ if Usc(Storage, EndStorage) ge 0 then
Err(Fatal, "Out of storage")
let gap = EndStorage-Storage
if Usc(gap, MinSpace) ls 0 then MinSpace = gap
]
and PutStorage(nil, Ptr, Size; numargs na) be
[ if na ls 3 then // called from system
[ PutTS("SysPut($O)", Ptr-EndStorage)
return
]
PutTS("Put($O)", Size)
if Ptr ne EndStorage then
CallSwat("Bad call on PutStorage")
EndStorage = Ptr+Size
]
and GetLow(nil, Size) = valof
[ PutTS("GetLow($O)", Size)
let Ptr = Storage
Storage = Storage+Size
CheckSpace()
Zero(Ptr, Size)
resultis Ptr
]
and PutLow(nil, Ptr, Size; numargs na) be
[ if na ls 3 then // called from system
[ PutTS("SysPutLow($O)", Storage-Ptr)
return
]
PutTS("PutLow($O)", Size)
if Ptr+Size ne Storage then
CallSwat("Bad call on PutLow")
Storage = Ptr
]
and RealPutTS(str, val) be
[ static [ lastCall0 = 0; lastCall1 = 0 ]
PutTemplate(OutputS, str, val)
let frame = ((lv str-4)!0)!0
let call0, call1 = frame!1, (frame!0)!1
if (call0 ne lastCall0) % (call1 ne lastCall1) then
[ PutTemplate(OutputS, " from $UO from $UO", call0, call1)
lastCall0, lastCall1 = call0, call1
]
Puts(OutputS, $*N)
]
and StoreString(str, zone) = valof
[ let nw = str>>BS.length rshift 1 + 1
let p = Allocate(zone, nw)
MoveBlock(p, str, nw)
resultis p
]
and MaxBlock(nil) = valof
[ if RealMin eq -1 then RealMin = MinSpace // assume large Get is going to be done
resultis EndStorage-Storage-1
]
and ScratchZone(ptr, len) = valof
[ static [ @szbeg; @szptr; @getsz; @putsz ]
szbeg = ptr
szptr = ptr+len
let GetScratch(nil, n) = valof
[ szptr = szptr-n
if szptr-szbeg ls 0 then Err(Fatal, "Scratch zone full")
resultis szptr
]
getsz = GetScratch
putsz = Noop
resultis lv getsz
]
and NextOverlay() be
[ let sz = lOverlaySz
Dvec(NextOverlay, lv sz)
let ptr = LoadOverlay(OverlayCFA, @lvOverlayLoc, EndStorage, ScratchZone(sz, lOverlaySz))
if ptr eq 0 then
Err(Fatal, "Out of storage")
Storage = ptr
CheckSpace()
lvOverlayLoc = lvOverlayLoc+1
]
// Replacements for OS
and Wo(x) be Wos(dsp, x)
and Wos(s, x) be PutTemplate(s, "$6UO", x)
and Ws(x) be Wss(dsp, x)
and Wss(s, x) be
[ structure S: [ length byte; char↑1,255 byte ]
for i = 1 to x>>S.length do Puts(s, x>>S.char↑i)
]