#PROGRAM /%BCR(DBM,15AM) #PROGRAM /%BDEBUG(DBM,15AM,22AM) #PROGRAM /%BEDI(DBM,15AM) #PROGRAM /%BEDO(DBM,15AM) #PROGRAM /%BEDSFILES(DBM,15AM) #PROGRAM /%BFIXEDSAVE(DBM,15AM) #PROGRAM /%BFLOAT(DBM,15AM) #PROGRAM /%BLIB0(DBM) #PROGRAM /%BOVERLAY(DBM,15AM) #PROGRAM /%BPOINTERS(DBM,15AM,22AM) #PROGRAM /%BSSO(DBM,15AM) #PROGRAM /%BSTART(DBM) #PROGRAM /%BSWITCHES(DBM,15AM) #PROGRAM /%BSYSTEM(DBM,15AM) #PROGRAM /%BTRACE(DBM,15AM,22AM) #PROGRAM /%BTRACESAVE(DBM,15AM) #PROGRAM /%BTR(DBM,15AM) #PROGRAM /%BTYROUTINE(DBM,15AM) #PROGRAM /LIB2(DBM,15AM,22AM) #PROGRAM /LIB4(DBM,15AM,22AM) #PROGRAM /%ROL(DBM,15AM) #PROGRAM /SEG1001(DBM,15AM,22AM) #PROGRAM /SEG1002(DBM,15AM,22AM) #PROGRAM /SEG1003(DBM,15AM,22AM) #PROGRAM /SEG1004(DBM,15AM,22AM) #PROGRAM /SEG1005(DBM,15AM,22AM) #PROGRAM /SEG1006(DBM,15AM,22AM) #PROGRAM /SEG1007(DBM,15AM,22AM) #PROGRAM XXXX99/%BBASICIO(DBM,15AM) #PROGRAM XXXX99/%BBASICPERI(DBM,15AM) #PROGRAM XXXX99/%BEXECUTE(DBM,15AM) #PROGRAM XXXX99/%BSAVE(DBM,15AM) #PROGRAM XXXX99/%BTPLPCP(DBM,15AM) #PROGRAM XXXX99/READCH(DBM,15AM) #PROGRAM XXXX99/WRITECH(DBM,15AM)Some of those are found in the PLAN source file PLANSEGMENTS, others are found in the BCPL source file BCPLLIB, but the source for the following segments seems to be missing:
%BFIXEDSAVE %BOVERLAY LIB2 SEG1001 SEG1002 SEG1003 SEG1004 SEG1005 SEG1006 SEG1007The code generator, CCMX, uses the segment LIB2 and the standard program description uses the segment SEG1001.
On examination of the code of SEG1001 it seems to be a version of %BLIB0 compiled with an earlier version of the compiler. For example SEG1001 includes use of #LOWER locations where the current version of the code generator uses literals. Similarly:
SEG1001 => %BLIB0 SEG1002 => %BDEBUG SEG1003 => %BSTART SEG1004 => LIB4 SEG1005 => LIB2 SEG1006 => %BTRACE SEG1007 => %BPOINTERSThis implies the only real lost source is for %BOVERLAY, %BFIXEDSAVE and LIB2.
%BOVERLAY contains a version of the subroutine entry and exit functions %BSAVE and %BRETURN that presumably implement overlay loading and unloading, they use the common block %AAOVDIR and the routine %ROL.
%BFIXEDSAVE contains a trivial versions of the %BSAVE and %BRETURN functions that contain no tracing or stack expansion functions.
LIB2 contains the BCPL functions:
GLOBAL $( NEWVEC1: 80 NEWWORD1: 81 RETURNVEC1: 82 RETURNWORD1: 83 NEWFREESTORE1: 84 RESTOREFREESTORE1: 85 SETUPVECASFREESTORE1: 86 REPORTFREESTORESTATE1: 88 FSERR1: 89 $)it seems to correspond to the GET file NHEAD2 which claims to be the "MODIFIED OXFORD FREE STORE SYSTEM". A version of LIB2 in PLAN has been extracted from the existing SUBGROUPSRB1 in preperation for recompiling the library.
Searching the web for some of these function names lead to the paper THE TEXT OF OSPub by Christopher Strachey and Joseph Stoy which describes a small operating system written in BCPL. Here is the code: freestore.bcpl.
using the OSPub routines as a template it has proved possible to recreate reasonable BCPL versions of some of the routines in LIB2, for example NEWVEC seems to correspond to:
LET NewVec[n] = VALOF $(NV IF n < 0 DO $( FSErr["Negative arg in NewVec"] FINISH $) IF (n = 0) LOGAND (FS!FWC NE END) DO $( LET w = FS!FWC // First word in FreeWordChain FS!FWC := RV w RESULTIS w $) $( LET BP = LV FS!FBC // Block Pointer LET B = RV BP // Block $(R IF B = END DO $( FSErr("Free Store exhausted"] FINISH $) IF B!SIZE >= n BREAK BP := LV B!NXTB B := RV BP $)R REPEAT IF B!SIZE > n DO RETURNVEC (B + n + 1, B!SIZE - n - 1) RESULTIS B $) $)NVA lightly modified version of the OSPub FREESTORE routine.
However attempts to re-create RETURNVEC have met with rather less success. The OSPub version of RETURNVEC starts:
AND ReturnVec[V, n] BE $(RV UNLESS FS!LB <= V <= V+n <= FS!UB DO $(PEND ... the vector being freed is not in the current free store ... area, just add it to the list of blocks to be freed ... when the free store area is changed RETURN $)PEND ... the vector being freed is in the current free store areag, ... add the block to the free chain, merging it with adjacent ... free words or blocks.The code for the LIB2 RETURNVEC function starts:
LET RETURNVEC[V, N] BE $(RV TEST FS!LB <= V <= V+N <= FS!UB THEN $( TEST N = 0 THEN $( V!0 := FS!FWC FS!FWC := V $) OR $( LET PB = @ FS!FBC LET B = !PB UNTIL B = 0 LOGOR B!NXTB > V DO $( PB := @ B!NXTB B := !PB $) V!SIZE := N V!NXTB := B !PB := V $) $)Which looks like an attempt was made to replace the original code by something like
TEST block not in arena THEN $( add to pending free chain $) ELSE $( free block $)but the sense of the tests was accidentally inversed and the code was "fixed" by changing the THEN leg of the TEST to add the block to the free chain rather than the pending free chain. Unfortunately this means the code to merge a freed block into adjacent blocks is lost.
This problem has been fixed by replacing the copy of RETURNVEC in SUBGROUPSRB1 with the RETURNVEC from OSPub.
SUBGROUPSRB1 can now be recreated from source.