BBCBASIC(86) runs under the MS-DOS (PC DOS) operating system. It requires about 32 kbytes of code space. The interpreter's code segment and data segment addresses are different and 64 kbytes of memory are available on most systems for the interpreter's variables and your BBCBASIC(86) program.
The interpreter's internal variables and programmable character definitions occupy &900 bytes of memory (default setting of PAGE) and this leaves &F700 (63232) bytes for your program and its variables in a computer with about 132k of memory. The exact memory requirement for a full 64 kbytes depends on the room taken up by your version of MS-DOS (PC DOS) and the way you have configured your computer (CONFIG.SYS and AUTOEXEC.BAT).
BBCBASIC(86) releases any memory surplus to its requirements so that other programs can be run from within BBCBASIC(86) using 'star' commands (see the Operating System Interface section for details).
By default, your program will start on the page boundary immediately following the interpreter's data area and the 'dynamic data structures' will immediately follow your program. The total group of the dynamic data structures is called the 'heap'. The base of the program control stack is located at HIMEM. HIMEM is usually at &10000, but it will probably be lower on computers with less than 128k of memory. (See above.)
As your program runs, the heap expands upwards towards the stack and the stack expands downwards towards the heap. If the two should meet, you get a 'No room' error. Fortunately, there is a limit to the amount by which the stack and the heap expand.
In general, the heap only expands whilst new variables are being declared. However, bad management of string variables can also cause the heap to expand.
In addition to running your program, the stack is also used 'internally' by the BBCBASIC(86) interpreter. Its size fluctuates but, in general, it expands every time you increase the depth of nesting of your program structure and every time you increase the number of local variables in use.
PAGE=&900 &500 &400 &0000
Start of program User defined characters Function key strings Interpreter's internal variables
&00-&6B | The static variables. 108 bytes holding the values of the 27 integer variables @% to Z% inclusive. The variable values are stored as described later in this Annex and they each occupy 4 bytes. |
&6C-&D7 | 54 2-byte values (108 bytes in all) which point to the first item in the linked lists of dynamic variables starting with the characters A to Z (26) and _ to z (28). If no variables starting with the given initial character exists, the pointer contains zero. |
&D8-&D9 | A 2-byte pointer to the linked list of function names, If no function is currently active, this contains zero. |
&DA-&DB | A 2-byte pointer to the linked list of procedure names. If no procedure is currently active, this contains zero. |
&DC-&DD | The 2-byte value of PAGE. |
&DE-&DF | The 2-byte value of TOP (TOP > PAGE). |
&E0-&E1 | The 2-byte value of LOMEM. |
&E2-&E3 | A 2-byte pointer to the first free location after the heap. |
&E4-&E5 | The 2-byte value of HIMEM (LOMEM <= FREE < HIMEM). |
&E6-&E7 | The 2-byte value of the stack pointer when an ON ERROR LOCAL statement is executed. |
&E8-&E9 | A 2-byte value holding the current TRACE status. TRACE OFF sets it to zero, TRACE ON to &FFFF and TRACE nnn sets it to nnn (line numbers less than nnn are traced). |
&EA-&EB | A 2-byte value holding the current AUTO line number. If zero, AUTO is not active. |
&EC-&ED | A 2-byte pointer to the tail of the ON ERROR statement in the user's program. If zero, no ON ERROR statement is active (ON ERROR OFF). |
&EE-&EF | A 2-byte pointer to the last error string (used by REPORT). |
&F0-&F1 | A 2-byte pointer to the current DATA item in the user's program. Initialised to point to the first data item (if any) when the program is RUN. |
&F2-&F3 | The 2-byte value of ERL (the line number at which the last error occurred). |
&F4-&F5 | BASIC copies the program text pointer to this location every so often (at the beginning of each line, for example). When an error occurs, it is used to determine ERL. |
&F6-&FA | A 33 bit pseudo random number updated by RND. Five bytes are used to hold this number, the fifth byte containing only the 33rd bit. |
&FB | The 1-byte value of COUNT (the number of printed characters output since the last new line). |
&FC | The 1-byte value of WIDTH. Zero signifies that BBCBASIC(86) inserts no automatic new-lines. |
&FD | The 1-byte value of ERR (the number of the last error). |
&FE | A byte containing the LISTO value. |
&FF | A 1-byte value containing the increment for the AUTO command. |
&100-&1FF | The string accumulator. |
&200-&2FF | The input buffer. |
&300-&36F | Miscellaneous and graphics workspace (112 bytes). |
&370-&39F | The 48-byte SOUND buffer. |
&3A0-&3BF | 32-bytes of ENVELOPE storage. |
&3C0-&3FF | A 64-byte path/filename buffer. |
|
|
|
HIMEM | The first address at the top of memory which is not available for use by BBCBASIC(86). The base of the program stack is set at HIMEM. (The first 'thing' stored on the stack goes at HIMEM-1.) |
LOMEM | The start address for the heap. The first of the dynamic data structures starts at LOMEM. |
TOP | The first free location after the end of your program. Unless
you have set LOMEM yourself, LOMEM=TOP.
You cannot directly set TOP. It alters as you enter
your program. The current length of your program is given by:
PRINT TOP-PAGE |
PAGE | The address of the start of your program. You can place several programs in memory and switch between them by using PAGE. Don't forget to control LOMEM as well. If you don't, the heap for one program might overwrite another program. |
Assigning a null string to stop$ prevents the space for the last entry in the array being recovered when it is emptied.10 DIM names$(10) 20 FOR i=0 TO 10 30 name$(i)=STRING$(20," ") 40 NEXT 50 stop$="" 60 FOR i=0 TO 10 70 name$(i)="" 80 NEXT
|
The first variable created for each starting character is accessed via the index and subsequently created variables are accessed via the index and the chain. Consequently, there is some speed advantage to be gained by arranging for all your variables to start with a different character. Unfortunately, this can lead to some pretty unreadable names and programs.
|
The smallest amount of space is taken up by a variable with a single letter name. The static integer variables, which are not included in the variable chains, use the names A% to Z%. Thus, the only single character names available for dynamic integer variables are a% to z% plus _% and `% (CHR$(96)). As shown below, integer variables with these names will occupy 8 bytes.
|
|
As with integer variables, variables with single character names occupy the least memory. (However, the names A to Z are available for dynamic real variables.) Whilst a real variable requires an extra byte to store the number, the '%' character is not needed in the name. Thus, integer and real variables with the same name occupy the same amount of memory. However, this does not hold for arrays, since the name is only stored once.
In the following examples, the bytes are shown in the more human-readable manner with the MSB on the left.
The value 5.5 would be stored as shown below.
Because the sign bit is assumed to be 1, this would become:
Mantissa Exponent .0011 0000 0000 0000 0000 0000 0000 0000 1000 0010 Sign Bit &30 00 00 00 &82
The equivalent in decimal is:
Mantissa Exponent .1011 0000 0000 0000 0000 0000 0000 0000 1000 0010 &B0 00 00 00 &82
(0.5+0.125+0.0625) * 2^(130-127)BBCBASIC(86) stores integer values in real variables in a special way which allows the faster integer arithmetic routines to be used if appropriate. The presence of an integer value in a real variable is indicated by the stored exponent being zero. Thus, if the stored exponent is zero, the real variable is being used to hold an integer and the 4 byte mantissa holds the number in normal integer format.
= 0.6875 * 2^3
= 0.6875 * 8
= 5.5
Depending on how it is put there, an integer value can be stored in a real variable in one of two ways. For example,
will set the exponent to zero and store the integer &00 00 00 05 in the mantissa. On the other hand,number=5
will set the exponent to &82 and the mantissa to &20 00 00 00.number=5.0
The two ways of storing an integer value are illustrated in the following four examples.
Example 1 | ||||||
number=5 | & 00 | 00 | 00 | 00 | 05 | Integer 5 |
Example 2 | ||||||
number=5.0 | & 82 | 20 | 00 | 00 | 00 | Real 5.0 |
This is treated as | ||||||
& 82 | A0 | 00 | 00 | 00 | ||
= = = |
(0.5+0.125)*2^(130-127) 0.625*8 5 | |||||
because the sign bit is assumed to be 1. | ||||||
Example 3 | ||||||
number=-5 | & 00 | FF | FF | FF | FB | |
The 2's complement gives | ||||||
& 00 | 00 | 00 | 00 | 05 | Integer -5 | |
Example 4 | ||||||
number=-5.0 | & 82 | A0 | 00 | 00 | 00 | Real -5.0 |
(The sign bit is already 1) | ||||||
= = Magnitude = |
(0.5+0.125)*2^(130-127) 0.625*8 5 |
If all this seems a little complicated, try using the program on the next page to accept a number from the keyboard and display the way it is stored in memory. The program displays the 4 bytes of the mantissa in 'human readable order' followed by the exponent byte. Look at what happens when you input first 5 and then 5.0 and you will see how this corresponds to the explanation given above. Then try -5 and -5.0 and then some other numbers. (The program is an example of the use of the byte indirection operator. See the Indirection section for details.)
The layout of the variable 'NMBR' in memory is shown below.
|
10 NUMBER=0 20 DIM A% -1 30 REPEAT 40 INPUT"NUMBER PLEASE "NUMBER 50 PRINT "& "; 60 : 70 REM Step through mantissa from MSB to LSB 80 FOR I%=2 TO 5 90 REM Look at value at address A%-I% 100 NUM$=STR$~(A%?-I%) 110 IF LEN(NUM$)=1 NUM$="0"+NUM$ 120 PRINT NUM$;" "; 130 NEXT 140 : 150 REM Look at exponent at address A%-1 160 N%=A%?-1 170 NUM$=STR$~(N%) 180 IF LEN(NUM$)=1 NUM$="0"+NUM$ 190 PRINT " & "+NUM$'' 200 UNTIL NUMBER=0
|
When a string variable is first created in memory, the characters of the string follow immediately after the two bytes containing the start address of the string and the current and maximum lengths are the same. While the current length of the string does not exceed its length when created, the characters of the string will follow the address bytes. When the string variable is set to a string which is longer than its original length, there will be insufficient room in the original position for the characters of the string. When this happens, the string will be placed on the top of the heap and the new start address will be loaded into the two address bytes. The original string space will remain, but it will be unusable. This unusable string space is called 'garbage'. See the Variables sub-section for ways to avoid creating garbage.
Because the original length and the current length of the string are each stored in a single byte in memory, the maximum length of a string held in a string variable is 255 characters.
would place &54 (T) at address &8000, &68 (h) at address &8001, etc. Because the string is placed at a predetermined location in memory it is called a 'fixed' string. Fixed strings are not included in the variable chains and they do not have the overheads associated with a string variable. However, since the length of the string is not stored, an explicit terminator (&0D) is used. Consequently, in the above example, byte &8010 would be set to &0D.$&8000="This is a string"
CONTENTS |
CONTINUE |