home *** CD-ROM | disk | FTP | other *** search
- BCPL document of 25 Oct 85 17:38:21
-
- Compiler options
-
- Default values are given in square brackets.
-
- Front end:
-
- B [off] stack grows from high to low addresses -
- point VECs at the end, not beginning
- C [on] equate cases
- L [on] enable special LISP operators
- R [off] 'restricted' language
- Sn [4] set savespace size
- T [off] print parse tree
- Xn [large] set extension level to n
- $tag set tag to TRUE
- $tag' set tag to FALSE
- Dn - ignored -
-
- Code generator options:
-
- A [off] generate AOF
- B [on] ensure RB contains address of destination procedure on call
- C [off] stack checking
- P [off] profile and call counting
- K [off] call counting
- N [off] generate variable names in code
- S [on] produce compacter code at the expense of speed by compiling
- various sequences out of line
- Wn - ignored -
- Dn [0] set CG debug mode to n.
- I assure you, you don't want to use this
- On [1] set CG optimise mode to n
-
- Switch options must be preceded by + or -. Options may be separated by
- commas and spaces. Front end options are seperated from code generator
- ones by /.
-
- If the B front-end option is used, the code generated requires the support
- of a different (currently non-existent) mclib.
- The P code generator option currently generates only entry counts.
- The N code generator option is only partially implemented at present.
-
-
- The library
-
- 14 PutByte(vec, offset, value)
- 15 result := GetByte(vec, offset)
-
- 37 result := GBytes(hardware-address, size)
- 38 PBytes(hardware-address, size, data)
-
- 16 result := MulDiv(a, b, c)
- result = a*b/c
- result2 = a*b REM c
-
- 20 ch := CapitalCh(ch)
-
- 21 comparison := CompCh(ch1, ch2)
- result has the sign of ch1-ch2 (case folded)
-
- 22 comparison := CompString(s1, s2)
-
- 35 Stop
-
- 41 frameptr := Level()
-
- 42 LongJump(frameptr, lab)
- The frame value must be one that is reachable by chaining back
- from the current frame
-
- 43 Aptovec(proc, vec ub)
- Note that Aptovec uses a stack frame itself
-
- 48 CreateCo(function, stacksize)
-
- 49 successcode := DeleteCo(cptr)
-
- 50 CallCo(cptr, arg)
-
- 51 ResumeCo(cptr, arg)
-
- 52 CoWait(cptr)
-
- 54 vec := GetVec(upperbound)
-
- 55 FreeVec(vec)
-
- 56 size := MaxVec()
-
- 94 error status := SWI(number, args, results)
- args is a 10 word BCPL vector containing the values for
- R0 to R9 inclusive
- results is a 10 word BCPL vector to receive the values of
- R0 to R9 inclusive after the SWI
- error status is non-zero if the SWI gave rise to an error
-
- 96 Avalue := OSArgs(op, handle, data)
- result is negative if an error occurred.
- (otherwise, only significant when op=handle=0)
- result2 receives the returned data value.
-
- 97 byte := OSBGet(channel)
- (#x1fe returned at end of file)
- result is negative on an error.
-
- 98 error := OSBPut(byte, channel)
- result is 0 if OK, negative if an error occurred.
-
- 99 result := OSFind(op, arg)
- op=0, (close) arg is file handle
- op ~=0 (open) arg is file name (BCPL string), returns handle
-
- 100 result := OSFile(op, filename, args)
- filename is a BCPL string
- args is a BCPL vector containing the values wanted by Brazil
- OSFile in R2 to R5. Where these are addresses, they are
- hardware adresses (ie BCPL pointers shifted up two places).
- result is guaranteed valid only if op is 5
- If an error occurs, Result2 is returned non-zero
-
- 101 result := OSCLI(command)
- command is a BCPL string
- result is False if the command fails, True otherwise
- If the base of this program is not #x8000, then it tries to run the
- command as a sub-program.
-
- 102 error := OSWrCh(ch)
- result is negative if an error occurred
-
- 103 ch := OSRdCh()
- Result2 is the value of the carry flag result (cf OSWord 0)
-
- 104 result := OSByte(a, x, y).
- Result is return X value; Result2 is set to return Y value
-
- 93 result := OSByte2(a, x, y)
- Result is negative if an error;
- otherwise bottom byte = return x
- byte 1 = return y
- byte 2 is non-zero if return carry flag set
- (This is how OSByte should have been: I may later remove it in
- favour of this).
-
- 105 OSWord(number, buffer)
- If number=0 this does a Brazil ReadLine, and returns the length read
- as result and the value of the carry flag in Result2
- (TRUE if set, FALSE otherwise)
- If number~=0 does a Brazil OSWord; no result returned
-
- 106 buffer := TKRErr(buffer, maxlength)
- Moves the most recent error string into the given buffer.
- returns the (bcpl address of the) beffer, just as passed
-
- 140 MoveWords(direction, length, from, to)
- from and to are BCPL addresses
-
- 141 FillWords(base, length, value)
- Initialise !base to base!(length-1) to value.
- base is a BCPL address.
-
- 112 SetEventHandler(event number, data, treatment)
-
- Treatment may have one of the values:
- ev_ignore (0)
- ev_set_flag (1)
- data is the (BCPL) address of a word which onoccurrence of the
- event will be set to a non-zero value
- ev_call_proc (2)
- data is the hardware address of a piece of code tobe called when
- the event occurs. Call conditions are as for the Brazil
- event handler. No BCPL environment is set up for the call.
-
- ev_buffer (3)
- data is the address of a buffer to be used for the event values.
- The values written are
- (event number<<16) + (X value<<8) + Y value.
- The buffer is a structure of the form
- insertion_pointer = 0*4
- extraction_pointer = 1*4
- buffer_size = 2*4
- buffer = 3*4 // to (buffer_size+2)*4
- Values are inserted into the buffer using the algorithm
- buffer!insertion_pointer := value;
- $( LET new_i_p = insertion_pointer+1;
- IF new_i_p=buffer_size THEN new_i_p := 0;
- IF new_i_p~=extraction_pointer
- THEN insertion_pointer := new_i_p
- $)
- Escape flag update is treated as event number -1: acknowledgement is
- done automatically.
-
-
- 46 stream := FindInput(name)
- 47 stream := FindOutput(name)
- Special cases are
- VDU:
- RS423:
- RS232:
- PRINTER:
- NULL:
-
- 29 SelectInput(stream)
- 30 SelectOutput(stream)
-
- 27 stream := Input()
- 28 stream := Output()
-
- 24 ch := RdCh()
- 26 WrCh(ch)
-
- 44 ch := RdBin()
- 45 WrBin(byte)
-
- 76 EndRead()
- 77 EndWrite()
-
- 25 UnRdch()
-
- 66 count := ReadBytes(vector, offset, count)
- 67 WriteBytes(vector, offset, count)
-
- 59 Read.Offset(stream, vector)
- vector!0 is set to the sequential pointer for the file open on stream
-
- 60 Set.Offset(stream, vector)
- Sets the sequential pointer for the file open on stream to vector!0
-
- 61 filelength := Extent(stream)
-
- 78 n := ReadN()
-
- 23 NewLine()
- 36 NewPage()
-
- 19 WriteF(format, a, b, c, d, e, f, g, h, i, j, k)
-
- 18 WriteS(string)
-
- 79 WriteD(n, digits)
-
- 80 WriteN(n)
-
- 81 WriteHex(n, digits)
-
- 82 WriteOct(n, digits)
-
- 83 RdArgs(keys, argv, size)
- 85 FindArg(keys, w)
-
- 108 centisecondtime := Time()
- 109 timeofdaystring := TimeOfDay()
- 110 datestring := Date()
-
- 90 n := Random(n)
-
- 69 PackString(vector, string)
- 70 UnpackString(string, vector)
-
- 63 Abort(n)
- Called on hardware abort, or library-detected fatal fault. The call
- is as from the place of the fault; n = 0 for a software-detected
- fault or the Arthur error code for a hardware trap
- Note that global n is initialised to #xAE950000+4*n. If used as an
- address, this will give an address exception, and if branched to
- will give a prefetch abort.
-
- 64 BackTrace()
-
- 65 MapStore()
-
- Variables
- 89 random.state
- 40 stackbase
- 57 blocklist
- 144 vdustream
- 145 errorstream
-
-
-
- Section format
-
- SectionStart
- = "BCPL"
- & globinits-SectionStart
- = 8 bytes of section name (8 data bytes, not a string)
- = 20 bytes date and time compiled, also not a string.
- The BCPL system uses the format, eg
- "07 Oct 85 15:54:35",0,0.
- Anything different will give odd output from MapStore.
- = 0
-
- globinits
- & offset of global in section, global number
- ...
- & highest global number used, 0
-
- [ This bit will not be present when using a BCPL system which requires
- linking rather than joining
-
- & &12345678
-
- & offset of word in section requiring relocation
- ....
-
- & &87654321
- (note that global initialisations need to be relocated.
- There's laziness for you).
- ]
-
- Each procedure is preceded by a 12-byte header
- & -1
- = 7, first 7 characters of procedure name (filled with space)
- Compiled BCPL may preceed that with a word giving the address of static data
- for the section.
-
-
-
- Compiled code conventions
-
- Registers:
-
- RB 8
- RL 12
- RTS 11
- RP 10
- RG 9
- RGB 7
-
- There is an upwards-growing stack, addressed by two registers. RFP is the
- frame pointer, RTS the top of stack pointer (actually, it points to the first
- unused word above the stack). RTS is not always correct within procedures, but
- it always is on procedure call and must be on return.
-
- RG points at the base of the global vector; RGB addresses a set of subroutines
- within the library.
-
- On procedure entry, RB holds the address of the called procedure. It need not
- be preserved. RL holds the address of the caller's static data, and must be
- preserved. R14 holds the link: this must be written to both PC and PSR on
- return. R1 to R4 hold the first four arguments, with others on the stack
- above RTS in the usual way. Thus, a general procedure would look like:
- STMEA rts!, {rb, rp, rl, r14} ; save linkage
- SUB rp, rts, #16 ; new frame pointer
- STMEA rts!, {a1, ...} ; arguments
- ...
- MOV rts, rp ; unwind our frame
- LDMIB rp, {rp, rl, pc}^ ; no need to restore RB
-
- Functions return their result in R1.
-
- R0 to R6 and RB may be used without saving their values; so may R13 and
- moreover it is accessible from BCPL through the name NIL (assignment to NIL
- from BCPL has the side-effect of updating R6). R6 and R13 are guaranteed
- untouched by the library, and by BCPL code which does not update NIL.
-