BBC BASIC for the PDP-11 ======================== J.G.Harston, 70 Camm Street, Walkley, Sheffield S6 3TR http://mdfs.net/Software/PDP11/BBCBasic Date: 12-Feb-2009 BBC BASIC (PDP11) (C) Copyright J.G.Harston 1989,2009 1. Introduction BBC BASIC (PDP11) has been designed to be as compatible as possible with Version 4 of the 6502 BBC BASIC resident in the BBC Micro Master series. The language syntax is not always identical to that of the 6502 version, but in most cases the PDP-11 version is more tolerant. BBC BASIC uses UNIX TRAP calls to interface with the host system. It can be installed in a suitable directory such as /usr/bin. BBC BASIC (PDP11) is started with a 'bbcbasic' command, and on startup will display a startup message similar to: PDP11 BBC BASIC IV Version 1.00 (C) Copyright J.G.Harston 1989,2008 > *Quit will return to the calling process, *Help will report the current host interface version. 2. Memory utilisation BBC BASIC (PDP11) requires about 16K of code space, resulting in a value of PAGE of about &3E00. The remainder of the user memory is available for BASIC programs, variables (heap) and stack. Depending on the system, HIMEM can have a value up to &FF00. 3. Commands, statements and functions The syntax of BASIC commands, statements and functions are the same as the 6502 BASIC for the BBC Micro version (BASIC 4). Some commands and functions are implemented by calling operating system entry points via Unix TRAP instructions and, of supported, by PDPTube EMT instructions, so their functionality depends on the level of support implemented by the host interface. 4. Special characters ! 32-bit indirection $ String variable or string indirection % Integer variable or precedes binary constant & Precedes hexadecimal constant &o Precedes octal constant ' New line in PRINT or INPUT * Precedes an "operating system" command : Separates statements typed on the same line ; Introduce comment in assembler, suppress action in PRINT ? 8-bit indirection (PEEK & POKE) [ Enter assembler ] Exit assembler ~ Convert to hex (PRINT and STR$) # Convert to octal (PRINT and STR$) / Convert to binary (PRINT and STR$) \ Line continuation character 5. Variables Variable names may be of unlimited length and all characters are significant. Variable names must start with a letter. They can only contain the characters A..Z, a..z, 0..9 and underline. Embedded keywords are allowed. Upper and lower case variable names are distinguished. The following types of variable are allowed: A real numeric A% integer numeric A$ string The variables A%..Z% are regarded as special in that they are not cleared by the commands or statements RUN, CHAIN and CLEAR. In addition A%, B%, C%, D%, E%, F%, X% and Y% have special uses in CALL and USR routines and O% & P% have special meanings in the assembler (code origin and program counter respectively). The special variable @% controls numeric print formatting. The variables @%..Z% are called "static variables", all other variables are called "dynamic variables". Real variables have a range of approximately +-1E-38 to +-1E38 and numeric functions evaluate to 9 significant figure accuracy. Internally every real number is stored in 40 bits. Integer variables are stored in 32 bits and have a range of -2,147,483,648 to 2,147,483,647. String variables may contain from 0 to 255 characters. All arrays must be dimensioned before use. All statements can also be used as direct commands. 6. Immediate Commands Immediate commands can only be enter at the BASIC prompt. An attempt to use them in a program will give the 'Mistake' error. Command Function AUTO [start][,inc] Generate line numbers. DELETE start,end Delete program lines. LIST [line][,line] List all or part of program. LISTO number Control indentation in LIST. LOAD "filename" Load a program into memory. NEW Delete current program & variables. OLD Recover a program deleted by NEW. RENUMBER [start][,inc] Renumber the program lines. SAVE ["filename"] Save the current program to disk. If the first line of the program is a line 'REM > filename' then SAVE with no filename will use the filename in the REM statement. 7. Program Statements The following statements can be used in programs or directly from the BASIC prompt. CALL address[,arg list] Call assembly language routine. CLEAR Clear dynamic variables. DATA list Data for READ statement. DEF FNname[(arg list)] Define a function. DEF PROCname[(arg list)] Define a procedure. DIM var(sub1[,sub2...])[,..] Dimension one or more arrays. DIM var exp [,var exp...] Reserve space for assembler etc. END Terminate program. ENDPROC Return from a procedure. ERROR [EXT] n,string Generate an error with error number n and text string. If EXT is present, terminates the program and returns n to the calling process. FOR var=exp TO exp [STEP exp] Begin a FOR...NEXT loop. GOSUB exp Call a BASIC subroutine. GOTO exp Branch to specified line. HIMEM=exp Set top of memory used by BASIC. IF exp THEN stmts [ELSE stmt] Do statement(s) if exp non-zero. IF exp THEN line [ELSE line] Branch if exp non-zero. LEFT$(strvar[,length])=string Overwrites leftmost characters of string. [LET] var = exp Assignment. LOAD "filename",addr Loads data into memory at the specified address. LOCAL var[,var...] Declare variables local to function or procedure. LOCAL ERROR LOCAL DATA LOMEM=exp Set start address of dynamic variable storage. MID$(strvar,position[,length])=string Overwrites middle characters of string NEXT [var[,var...]] End FOR...NEXT loop. ON exp GOTO line,line.. [ELSE line] Computed GOTO. ON exp GOSUB line,line.. [ELSE line] Computed GOSUB. ON exp PROCname.. [ELSE PROCname] Computed PROC call. ON ERROR LOCAL Localise error handler ON ERROR stmts Do statement(s) on error. ON ERROR OFF Restore default error handling. PAGE=exp Set memory address of current user's program. PROCname[(parameter list)] Call a procedure. PROC(exp)[(parameter list)] Indirectly call a procedure. READ var[,var...] Read data from DATA statement(s). REM any text Remark REPEAT Begin a REPEAT...UNTIL loop. REPORT Print error message for last error. RESTORE [line] Reset data pointer to beginning or to specified line. RESTORE DATA RESTORE ERROR RETURN Return from subroutine. RIGHT$(strvar[,count])=string Overwrites rightmost characters of string. RUN Run the current program. RUN str Load and run program. SAVE "filename",start,end Save data from memory between the specified addresses. STOP Stop program and print message. TRACE ON Start trace mode. TRACE OFF End trace mode. TRACE exp Trace lines less than exp. UNTIL exp Terminate loop if exp is non-zero. WIDTH exp Set print output width. 8. Operators Symbol Function + Addition or string concatenation. - Negation or subtraction. * Multiplication. / Division. ^ Involution (raise to power). EOR Bitwise exclusive-OR (integer). OR Bitwise OR (integer). AND Bitwise AND (integer). MOD Modulus (integer result). DIV Integer division (integer result). = Equality. <> Inequality. < Less than. > Greater than. <= Less than or equal. >= Greater than or equal. The precedence of operators is: 1. Expressions in parentheses, functions, negation, NOT. 2. ^ 3. *, /, MOD, DIV 4. +, - 5. =, <, >, <>, <=, >= 6. AND 7. OR, EOR 9. Arithmetic Functions Function Action ! num 32-bit indirection ? num 8-bit indirection | num 40-bit indirection - num Unary minus + num Unary plus ^ var Address of variable ABS num Absolute value of numeric value. ACS num Arc-cosine of numeric value, in radians. ASN num Arc-sine of numeric value, in radians. ATN num Arc-tangent of numeric value, in radians. COS num Cosine of radian numeric value. DEG num Value in degrees of radian numeric value. EXP num e raised to the power of numeric value. INT num Largest integer less than numeric value. LN num Natural logarithm of numeric value. LOG num Base-ten logarithm of numeric value. NOT One's complement (integer). PI Returns 3.14159265. RAD num Radian value of numeric value in degrees. RND[(exp)] RND returns random 32-bit integer. RND(-n) seeds sequence. RND(0) repeats last value in RND(1) form. RND(1) returns number between 0 and 0.999999999 RND(n) returns random integer between 1 and n. SGN num 1 if exp>0, 0 if exp=0, -1 if exp<0. SIN num Sine of radian numeric value. SQR num Square root of numeric value. TAN num Tangent of radian numeric value. 10. String Functions Function Action "text" Constant string. $ num cr-terminated string indirection. $$ num null-terminated string indirection. ASC str Returns ASCII value of first character of string. Returns -1 if null string. CHR$ num Returns one-character string with ASCII value of exp. EVAL str Evaluates str as an expression and returns resulting number or string. INSTR(r,s[,n]) Returns position of string s in string r, optionally starting at position n. LEFT$(str,exp) Returns leftmost exp characters of string. LEFT$(str) Returns leftmost LEN(str)-1 characters of string. LEN str Returns length of string (0-255). MID$(str,m[,n]) Returns sub-string from position m, of length n or to end. RIGHT$(str,exp) Returns rightmost exp characters of string. RIGHT$(str) Returns rightmost one character of string. STR$[~|#|/] exp Returns string representation of exp in decimal, hex, octal or binary. STRING$(n,str) Returns a string consisting of n copies of str. VAL str Returns numeric value of str. IF str does not begin with a signed or unsigned numeric constant, VAL returns zero. 11. Program Functions COUNT Returns number of characters printed since last new line. DIM(array()) Returns size of array. END Returns end of BASIC's variable heap. ERL Returns line number of last error. ERR Returns error number of last error. FALSE Returns zero. FNname[(parameter list)] Call named user-defined numeric or string function. FN(exp)[(parameter list)] Indierctly call user-defined numeric or string function. HIMEM Returns top of memory used by BASIC. LOMEM Returns start address of dynamic variable storage. PAGE Returns memory address of current user's program. REPORT$ Returns error message for last error. TOP Returns first address after end of user's program. TRUE Returns -1. USR Calls a machine code routine and returns integer. WIDTH Returns print output width. 12. I/O Statements CLG Sends VDU 16 to the output stream to clear the graphics area of the screen and set it to the currently selected graphics background colour using the current background plotting action (set by GCOL). CLS Sends VDU 12 to the output stream to clear the text area of the screen and set it to the currently selected text background colour. The text cursor is moved to the 'home' position (0,0) at the top left-hand corner of the text area. COLOUR l Sends VDU 17,n to the output stream to select the current text colour. COLOUR l,p Sends VDU 19,l,p,0,0,0 to the output stream to set the palette entry for logical colour l to physical colour p. COLOUR l,r,g,b Sends VDU 19,l,16,r,g,b to the output stream to set the palette entry for logical colour l to physical colour r,g,b. If l is negative, then sends VDU 19,l,24,r,g,b to the VDU to set the physical colour of the border. DRAW x,y Draws a line in the current graphics foreground colour from the last point visited to the X and Y specified. The screen is always 1024 pixels wide and 1280 pixels high in all screen modes. DRAW x,y is equivalent to PLOT 5,x,y. ENVELOPE a,b,c,d,e,f,g,h,i,j,k,l,m,n Used in conjunction with SOUND to control the pitch and/or amplitude of a sound whilst it is playing. GCOL [m,],c Sets the current graphics foreground or background colour and plotting mode. Sends VDU 18,m,c to the VDU. If m is not specified, 0 is used. The modes are: 0 Plot the colour specified. 1 OR the colour with the colour that is already there. 2 AND the colour with the colour that is already there. 3 Exclusive-OR the colour with the colour that is already there. 4 Invert the colour that is already there. INPUT [LINE]["prompt"[,]]var[,var] Request input from user. Comma after prompt causes question mark. If LINE is present, accepts the whole line including commas, quotes, etc. MODE n Sets the screen display mode. The screen is cleared and all the graphics and text parameters (colours, origin, etc) are reset to their default values. Sends VDU 22,n to the output stream. MOVE x,y Moves the graphics cursor to an absolute position without drawing a line. The screen is always 1024 pixels wide and 1280 pixels high in all screen modes. MOVE x,y is equivalent to PLOT 4,x,y. OFF Turns the cursor off by sending VDU 23,1,0,0,0,0,0,0,0,0 to the output stream. ON Turns the cursor on by sending VDU 23,1,1,0,0,0,0,0,0,0 to the output stream. OSCLI string Pass string to "operating system" to execute a command. PLOT [k,]x,y A multi-purpose drawing statement. Two or three numeric values follow the PLOT keyword: the first specifies the type of point, circle, triangle, line etc. to be drawn; the second and third values give the X and Y coordinates to be used (in that order). If only two numeric values are given, then k=69 is used to plot a single point. The two most commonly used statements, PLOT 4 and PLOT 5, have the duplicate keywords MOVE and DRAW. PLOT sends VDU 25,k,x MOD 256,x DIV 256,y MOD 256,y DIV 256 to the output stream. The following PLOT codes are defined: PLOT 0 Move to a position relative to the last point. PLOT 1 Draw line relative in graphics foreground colour. PLOT 2 Draw line relative in logical inverse colour. PLOT 3 Draw line relative in graphics background colour. PLOT 4 Move to an absolute position. PLOT 5 Draw line absolute in graphics foreground colour. PLOT 6 Draw line absolute in logical inverse colour. PLOT 7 Draw line absolute in graphics background colour. PLOT 8-15 Last point in line omitted when inverted plotting used. PLOT 16-23 Lines are drawn dotted. PLOT 24-31 Lines are drawn dotted, omiting last point. PLOT 32-39 Solid line, first point omitted. PLOT 40-47 Solid line, both end points omitted. PLOT 48-55 Dotted line, initial point omitted. PLOT 56-63 Dotted line, both end points omitted. PLOT 64-71 Single point is plotted. PLOT 72-79 Horizontal line filling. PLOT 80-87 Plot and fill a triangle formed by the specified position and the last two points visited. PLOT 88-95 Horizontal line blanking. PRINT [TAB(x[,y])][SPC n]['][;][~][#][/][exp[,exp...][;] Print data to output stream. SOUND OFF Turns off sound output. SOUND ON Turns on sound output. SOUND channel,loudness,pitch,duration Generates sounds according to the parameters as follows: channel Bits 0 & 1 are the channel number (1-3). If bit 4 is set, the sound queue is flushed and the new sound is started immediately. loudness Values from -15 to -1 select a sound of amplitude 15 to 1 respectively with constant pitch, zero selects silence and values from 1 to 15 select an envelope (see ENVELOPE statement). pitch This selects the initial pitch. Middle C is 53, and a semitone change in pitch is a change of 4. duration Values from 0 to 254 select the duration of the sound, in units of approximately 1/20 second. The value -1 causes an indefinite sound, which can be stopped only by issuing another SOUND statement with the "flush" bit set or by pressing the ESCape key. TIME=exp Sets system elapsed time counter. The program needs to be running with appropriate permissions for this to be effective, otherwise there is no effect. TIME$=string Sets the system real-time clock. The program needs to be running with appropriate permissions for this to be effective, otherwise there is no effect. The string must be one of the following formats: hh:mm:ss for time only dd Mon yyy for date only Day,dd Mon yyyy.hh:mm:ss for full date and time Where: Day is the day of the week (Mon, Tue, etc). dd is the day of the month (01, 02, etc). Mon is the abbreviated month name (Jan, Feb ,etc). yyyy is the year (2003, 2004, etc). hh is hours (00 to 23). mm is minutes (00 to 59). ss is seconds (00 to 59). VDU exp[,|;[exp...]][|] Sends a list of numeric arguments to the VDU. A 16-bit value can be sent if the value is followed by a ';'. It is sent as a pair of characters, least significant byte first. If the expression list is terminated with | then nine following zeros are sent. 13. I/O Functions ADVAL channel Returns information about input devices such as a joystick or mouse, if fitted, or the number of free spaces in a buffer. ADVAL(0) joystick buttons ADVAL(-1) bytes in keyboard buffer ADVAL(1) joystick 1 X-position ADVAL(-2) bytes in serial input buffer ADVAL(2) joystick 1 Y-position ADVAL(-3) free space in serial output ADVAL(3) joystick 2 X-position ADVAL(-4) free space in printer output ADVAL(4) joystick 2 Y-position ADVAL(-5) free space in chn 0 SOUND queue ADVAL(-6) free space in chn 1 SOUND queue ADVAL(7) mouse X position ADVAL(-7) free space in chn 2 SOUND queue ADVAL(8) mouse Y position ADVAL(-8) free space in chn 3 SOUND queue ADVAL(-9) bytes in mouse input buffer ADVAL(-10) bytes in MIDI input buffer ADVAL(-11) free space in MIDI output buffer GET/GET$ Waits for keypress and returns ASCII value or one-character string. GET(port) Reads a value from the specified I/O port. GET/GET$(x,y) Reads a character from the specified character position. INKEY/INKEY$ exp With a positive argument waits for the specified maximum time in centiseconds for a character from the current input stream, or returns "" or -1 if no key pressed. With a negative argument returns the host type or checks for an individual keypress. MODE Returns current screen mode. OSCLI str Passes a string to be interpreted as an 'operating system' command and returns the return/exit value POINT(x,y) Returns the colour of the screen at the coordinates specified. If the point is outside the graphics window, then -1 is returned. POS Returns the current horizontal position of the text cursor on the screen. The left hand column is 0 and the right hand column is one fewer than the number of text columns in the current display MODE. TIME Returns the system elapsed time clock in centiseconds. TIME$ Reads the system real-time clock, returning a 24-character string in the following format: Day,dd Mon yyyy.hh:mm:ss Where: Day is the day of the week (Mon, Tue, etc). dd is the day of the month (01, 02, etc). Mon is the abbreviated month name (Jan, Feb ,etc). yyyy is the year (2003, 2004, etc). hh is hours (00 to 23). mm is minutes (00 to 59). ss is seconds (00 to 59). If no real-time clock is available, a null string is returned. VDU num Returns the VDU variable at offset num. VPOS Returns the vertical position of the text cursor. The top row is row 0 and the bottom row is one fewer than the number of text rows in the current display MODE. 14. File I/O statements BPUT#chan,exp Write least-significant byte of exp to output stream. BPUT#chan,string[;] Write string to output stream, followed by if ';' not present. CHAIN string Load and run a program. CLOSE#chn Closes the specified channel. IF chn=0 close all files. EXT#chn=exp Sets the extent of an open file. INPUT#chn,var[,var...] Reads data from an opened file with multiple calls to BGET. PRINT#chn,exp[,exp...] Writes data to an opened file with multiple calls to BPUT. PTR#chn=exp Sets the current pointer for an open file. 15. File I/O Functions BGET#chn Reads a byte from a channel previously opened with OPENIN or OPENUP. EOF#chn Returns TRUE if at the end of the opened file specified by the handle. EXT#chn Returns the total length of the opened file specified by the handle. GET$#chn Read a - or -terminated string from an open file. OPENIN str Opens a file for reading and returns the channel number of the file. A returned value of zero signifies that the specified file was not found, or could not be opened for some other reason. OPENOUT str Opens a file for writing and returns the channel number of the file. If the specified file does not exist it is created. If the specified file already exists it is truncated to zero length and all the data in the file is lost. A returned value of zero indicates that the specified file could not be created. OPENUP str Opens a file for update (reading and writing) and returns the channel number of the file. A returned value of zero signifies that the specified file was not found on the disk, or could not be opened for some other reason. PTR#chn Returns the current pointer for an open file. 16. Print Formatting By default, strings are printed left-justified and numbers are printed right-justified in a print zone. Numeric quantities will be printed left- justified if preceded by a semicolon (;). A comma (,) causes a tab to the beginning of the next print zone, unless the cursor is already at the start of a zone. An apostrophe (') in a PRINT or INPUT statement forces a new-line. A trailing semicolon in a PRINT statement suppresses the new-line. TAB(x), TAB(x,y) and SPC(n) may be used in PRINT and INPUT statements to position the cursor. A tilde (~) causes numbers to be printed in hex, a hash (#) causes numbers to be printed in octal, and a slash (/) causes numbers to be printed in binary. The variable @% controls numeric formatting as follows: LS byte: Width of print zone, 0-255. Normally 10. Byte 2 : Number of significant figures or decimal places. Maximum 10. Byte 3 : Print format type: 0 - General format (default) 1 - Exponential format 2 - Fixed format. MS byte: STR$ flag. If zero then STR$ formats in G9 mode. If nonzero zero then STR$ formats according to bytes 2 & 3 of @%. Examples Result @%=&2010A 01234567890123456789 PRINT "HELLO",8 HELLO 8.0 PRINT "HELLO" 8 HELLO 8.0 PRINT "HELLO";8 HELLO8.0 PRINT "HELLO",;8 HELLO 8.0 Value G9 G2 E2 F2 @%=&90A @%=&20A @%=&1020A @%=&2020A .001 1E-3 1E-3 1.0E-3 0.00 .006 6E-3 6E-3 6.0E-3 0.01 .01 1E-2 1E-2 1.0E-2 0.01 .1 0.1 0.1 1.0E-1 0.10 1 1 1 1.0E0 1.00 10 10 10 1.0E1 10.00 100 100 1E2 1.0E2 100.00 1000 1000 1E3 1.0E3 1000.00 17. Error codes Immediate Mode Only (error code 0): Silly RENUMBER space LINE space Disastrous and untrappable: Bad program No room Sorry Trappable: 1 Out of range 4 Mistake 5 Missing , 6 Type mismatch 7 No FN 9 Missing " 10 Bad DIM 11 DIM space 12 Not LOCAL 13 No PROC 14 Array 15 Subscript 16 Syntax error 17 Escape 18 Division by zero 19 String too long 20 Too big 21 -ve root 22 Log range 23 Accuracy lost 24 Exp range 26 No such variable 27 Missing ) 28 Bad HEX 29 No such FN/PROC 30 Bad call 31 Arguments 32 No FOR 33 Can't match FOR 34 FOR variable 36 No TO 38 No GOSUB 39 ON syntax 40 ON range 41 No such line 42 Out of DATA 43 No REPEAT 45 Missing # 190 Directory full 192 Too many open files 196 File exists 198 Disk full 200 Close error 204 Bad name 214 File not found 222 Channel 253 Bad string 254 Bad command 18. Indirection operators Indirection is the process which is provided by PEEK and POKE in other dialects of BASIC. There are three indirection operators: Name Purpose No. of bytes affected ? query byte indirection operator 1 ! pling word indirection operator 4 | bar real indirection operator 5 $ dollar cr-string indirection operator 1 to 256 $$ double-dollar null-string indirection operator 1 to 256 Y=PEEK(X) is equivalent to Y=?X POKE X,Y is equivalent to ?X=Y ! acts on four successive bytes. For example, !M=&12345678 would load &78 into address M, &56 into address M+1, &34 into address M+2 and &12 into address M+3. | acts on five successive bytes. For example, |M=0.5 would load &xx into address M, &xx into address M+1, &xx into address M+2, &xx into address M+3 and &xx into address M+4. $ writes a string followed by carriage return, CHR$13, into memory at a specified address, e.g. $M="ABCDEF" will place the ASCII characters A to F in locations M to M+5 and will load &0D into address M+6. $$ writes a string followed by a null, CHR$0, into memory at a specified address, e.g. $$M="ABCDEF" will place the ASCII characters A to F in locations M to M+5 and will load &00 into address M+6. Query (?) and pling (!) can also be used as binary operators, e.g. M?3 means "the contents of memory location M+3". The left-hand operand must be a variable, not a constant. The power of indirection operators is in the way they can be used to create your own data structures. For example you may need a structure consisting of a 10 character string, an 8-bit number and a reference to a similar structure. If M is the address of the start of the structure then: $M is the string M?11 is the 8-bit number M!12 is the address of the related structure. In this way you can create and manipulate linked lists and tree structures in memory, very easily. 19. Access to machine code The USR function and the CALL statement provide a flexible interface between BASIC and machine code routines. Both USR and CALL initialise the PDP-11's registers prior to the machine-code call as follows: R0 register = A% R1 register = B% R2 register = C% R3 register = D% R4 register = E% R5 register = F% R6 register = stack with return address at the top R7 register = entry point of machine code routine USR(address) Calls the machine-code routine and returns a 32-bit integer made up of the contents of the R0 and R1 (least-significant to most- significant) on return from the routine. CALL address[,parameter list] Sets up a parameter block on the stack containing details of the parameters, along with a return address, in the following format: Return address 2 bytes at (sp) Number of parameters 1 byte at 2(sp) Parameter type 1 byte at 3(sp) Parameter address 2 bytes at 4(sp) Parameter type ) repeated as often as necessary Parameter address ) The parameter types are: Code No. Parameter Type Example 0 Byte (8 bits) ?A% 4 Word (32 bits) !A% or A% 5 Real (40 bits) A 128 Movable string A$ 129 Fixed string $A% 130 Fixed string $$A% Parameters are passed by reference and may be changed by the machine-code routine. Except in the case of a movable string (normal string variable), the parameter address given is the absolute address at which the item is stored. In the case of movable strings (type 129) it is the address of a 4-byte parameter block containing the current length, the maximum length and the start address of the string (LSB first) in that order. Integer variables are stored in twos complement form with their least significant byte first. CR-terminated fixed strings are stored as the characters of the string followed by a carriage return (&0D). Null-terminated fixed strings are stored as the characters of the string followed by a null (&00). Floating point variables are stored in binary floating point format with their least significant byte first; the fifth byte is the exponent. The mantissa is stored as a binary fraction in sign and magnitude format. Bit 7 of the most significant byte is the sign bit and, for the purposes of calculating the magnitude of the number, this bit is assumed to be set to one. The exponent is stored as an integer in excess 128 format (to find the exponent subtract 128 from the value in the fifth byte). If the exponent byte of a floating point number is zero, the number is an integer stored in integer format in the mantissa bytes. Thus an integer can be represented in two different ways in a real variable. For example the value +5 can be stored as: 05 00 00 00 00 Integer 5 00 00 00 20 82 (0.5 + 0.125) * 2^3 USR or a CALL to an address in the &FF00-&FFFF range accesses various OS functions as detailed in section 20. 20. Operating system interface All Operating System ("star") commands are passed to the host to implement. The *QUIT command is checked for to exit the current program. CALLs and USRs to addresses in the range &FF00 to &FFFF provide access to the machine operating system, as with the BBC microcomputer. The PDP-11's R0, R1 and R2 registers are initialised to the integer variables A%, X% and Y% respectively. If X%<256, then R1 is set to X%+256*Y%. If calling OSARGS, OSBGET or OSBPUT, then R1 is set to Y% and R2 is set to X%. In the case of USR, the returned 32-bit value is composed of the PDP-11's R2, R1 and R0 registers corresponding to the 6502's Y, X and A registers, most significant to least significant, as follows: b0-b7 = R0 b8-b15 = R1 b16-b31 = R2 21. The VDU system Control Characters: The following VDU codes are defined. BBC BASIC itself does not implement the actions specified, it just issues the byte sequence. The output from BBC BASIC can be piped into a suitable VDU driver to implement the VDU sequences with a command such as bbcbasic | bbcvdu VDU 0 Null. VDU 1,n Send byte to printer. VDU 2 Enable printer. VDU 3 Disables printer. VDU 4 Causes text to be written at the text cursor. VDU 5 Causes text to be written at the graphics cursor. VDU 6 Enables VDU output. Cancels the effect of VDU 21. VDU 7 Causes a "beep". VDU 8 Moves the text cursor left one character. VDU 9 Moves the text cursor right one character. VDU 10 Moves the text cursor down one line. VDU 11 Moves the text cursor up one line. VDU 12 CLS: Clears the text window to the current text background colour and moves the text cursor to (0,0). VDU 13 Moves the text cursor to the left-hand edge of the window, but does not move it vertically. VDU 14 Enter paged mode. VDU 15 Stop paging. VDU 16 CLG: Clears the graphics window using the current background GCOL action and colour. VDU 17,n COLOUR n: Sets the text foreground, background or border colour. VDU 18,a,c GCOL a,c: Sets the graphics colour and plot action. VDU 19,l,p,r,g,b Sets the logical to physical colour mapping. VDU 20 Sets text and graphics colours to their default values (background black, foreground white) and resets the palette. VDU 21 Disable VDU output. All VDU commands except 6 are ignored. VDU 22,n MODE n: Selects a new screen mode and resets all screen driver variables (colours, palette, windows, cursor positions, graphics origin etc.). VDU 23,n,r1,r2,r3,r4,r5,r6,r7,r8 Program user-defined graphics characters, and various VDU functions. VDU 24,leftx;bottomy;rightx;topy; Define graphics window. VDU 25,n,x;y; PLOT k,x,y: Performs a PLOT action. VDU 26 Reset text and graphics windows to their default positions (filling the whole screen), home text cursor, move graphics cursor to 0,0 and reset the graphics origin to 0,0. VDU 27 Do nothing. VDU 28,leftx,bottomy,rightx,topy Set a text window. The text cursor is moved to the new home position. VDU 29,x;y; Move the graphics origin to the specified coordinates. VDU 30 Home the text cursor, to the top-left hand corner of the text window. VDU 31,x,y TAB(x,y): Moves the cursor to the position (x,y) if within the text window. If the coordinates are invalid they are ignored. VDU 127 Backspace the cursor by one position and delete the character there. 22. Operating System Commands The following commands are implemented by the host code that interfaces BBC BASIC to the host system. *| *| comment Everything after the | is ignored. */ */filename [parameters] Abbreviation for *RUN. *BASIC *BASIC [filename] Enter BBC BASIC. *CAT *CAT [drive] Catalogue the default or specified drive. *DELETE *DELETE file Erase file. *FX *FX a[,b[,c]] *GO *GO [addr [parameters]] Call code at address, or enter MOS command prompt if no address. *HELP *HELP [words] Display information on system. *LOAD *LOAD file [aaaa] Load file to hex address aaaa. *QUIT *QUIT Return to calling process, if supported. *RUN *RUN file [parameters] Load and execute the specified file, passing it any parameters. *SAVE *SAVE file ssss eeee Save RAM from hex address ssss to address eeee-1. *SAVE file ssss +llll Save RAM from address ssss with length llll. If a *command is not recognised, it is passed to the host to execute. A "star" command cannot contain variable names and must be the last item on a program line. To include a variable name use the OSCLI statement, e.g. to delete a file whose name is known only at run time: OSCLI "DELETE "+filename$ 23. Random access files BBC BASIC supports both random access and the ability to modify (update) a previously written file. Random access is performed by a single pointer (PTR#chn) which can be positioned anywhere in the file. The pointer is automatically incremented after every read or write operation (using BGET#, BPUT#, INPUT# or PRINT#). Examples: 100 REM Read a file backwards 110 in%=OPENIN(filename$):size=EXT#in% 120 FOR point=size-1 TO 0 STEP -1 130 PTR#in%=point : PRINT CHR$(BGET#in%); 140 NEXT : CLOSE #in% 100 REM Update a "record" in a random-access file 110 in%=OPENUP(filename$) 120 PTR#in%=record_number*record_length 130 PRINT #in%,new_data,new_data$ 140 CLOSE #in% 24. Host Environment The host system can be identified in several ways: A%=0:X%=1:os%=((USR&FFF4)AND&FF00)DIV256 returns 8 to indicate UNIX. If OSBYTE 0 returns 8, then INKEY-256 returns: &F6: OpenBSD &F7: FreeBSD &F9: Linux &FE: NetBSD A%=0:Y%=0:fs%=(USR&FFDA)AND&FF returns 24 to indicate a UNIX filing system. 25. Memory layout Variable in the heap: ^variable ---v name, &00, exponent, mantissa b0-b7, mantissa b8-b15, mantissa b16-b23, mantissa b24-b31 name, '%', &00, b0-b7, b8-b15, b16-b23, b24-b31 name, '$', &00, addr b0-b7, addr b8-b15, space, length name, ['%', '$'], '(', &00, num of dims, dim, {dim...}, data, {data...} ^variable() ---^ ^variable(dims{, dims...}) ---^ Stack layout: Internal memory: ^@%-512 : Input buffer, string can be fetched with $(^@%-512) ^@%-256 : String buffer, string can be fetched with $(^@%-256) ^@% : Integer variables ^@%+108 : Pointers to dynamic variables A%=EVAL("0:"+text$):token$=$(^@%-254) will tokenise text$ and put it in token$