RTR logo

R. T. RUSSELL

BBC BASIC (86) Manual



BIGBASIC

Annex G to
BBCBASIC(86)

Introduction

BIGBASIC is a 'large memory model' version of BBCBASIC(86) which allows the 'heap' (where BBCBASIC(86) stores its variables and arrays) to exceed 64 Kbytes. A BIGBASIC program can therefore store and manipulate, in memory, an amount of data limited only by the RAM capacity of the computer (and the MS DOS limit of 640 Kbytes).

BIGBASIC incorporates all the features of BBCBASIC, but it is in no sense a replacement for BBCBASIC because, despite its advantages, it:

Consequently, whilst BIGBASIC offers advantages over BBCBASIC, the latter is still the better choice when your program and data combined do not exceed 64 Kbytes in size.

BIGBASIC appears to work just the same as BBCBASIC and only in rare circumstances will you need to be aware of the differences. The most obvious distinction is that HIMEM, and the addresses returned by DIM, may well have values in excess of &FFFF. HIMEM is typically about &79000 on a 640 Kbyte computer.

You do not need to understand the segmented architecture of the 8086 (80?86) processor's address space. In the same way that BBCBASIC presents the user with a virtual address space from &0000 to &FFFF, BIGBASIC provides a virtual address space from &00000 to a maximum of about &89000 in a 640 Kbyte computer. The exact value of the highest address depends on the version of MS DOS, what memory-resident programs are installed, etc.

Apart from the values of PAGE, TOP, LOMEM and HIMEM, the only occasions when you need to be aware of the (virtual) addresses within the data area are when you have reserved a block of memory with DIM. Locations within this block may be subsequently accessed by the indirection operators (?, ! and $), *LOAD and *SAVE and by the assembler.

This annex discusses the differences between BIGBASIC and BBCBASIC. You should refer to the main body of the manual for general information on the topics discussed here.


General Information

Memory Used

When run BIGBASIC by default reserves all but 64 Kbyte of the computer's memory. The 64 Kbyte is left so that 'external' commands can be run from within BIGBASIC. For example, *COPY to copy a file. The amount of memory reserved may be controlled by an optional switch in the command line. For example:
 = BIGBASIC /128
will try to reserve 128 Kbytes for the data area. (This is in addition to the memory needed for the interpreter's code.) If successful, this will result in HIMEM being set to &20000. If insufficient memory is available, all of the computer's memory will be taken leaving nothing for external commands. The command:
 = BIGBASIC /999
will result in the maximum possible amount of memory being reserved for BIGBASIC's use, since there will never be 999 Kbytes of memory free under MS DOS.

Stack

BIGBASIC's stack, which grows down from HIMEM, cannot exceed 64 Kbytes in size. This limits the depth of nesting of FOR...NEXT, REPEAT...UNTIL, GOSUB...RETURN, functions and procedures. However, the limit is a large one and is only likely to be encountered in deeply recursive programs. Using up all the available stack will result in an untrappable 'No room' error.

Variables and Arrays

Variables and arrays created by a BIGBASIC program, and the areas of memory reserved with DIM for assembler routines etc, can use all of the available memory between LOMEM and the bottom of the stack. This is in excess of about 500,000 bytes on a 640 Kbyte computer. If this space is filled, an untrappable 'No room' error occurs.

Very large arrays can be created, although the total number of elements cannot exceed 65536 (however many dimensions) and individual subscripts cannot exceed 65535. For example DIM A(65535) and DIM B(255,255) each create an array occupying &50000 (327680) bytes of memory. If there is insufficient space for the array, or the maximum subscript/number of dimensions is exceeded, a 'DIM space' error occurs.

Indirection

The indirection operators will accept 20-bit addresses in the range &00000 to &FFFFF. It must be emphasised that these are virtual addresses (offsets from the base of BIGBASIC's data area) rather than true machine addresses.

BIGRUN

A 'run only' version of BIGBASIC called BIGRUN is provided on the distribution disk. It shares all the attributes of BIGBASIC, including the optional command-line switch. In all other respects it is similar to BBCRUN and you should refer to the Annex entitled BBCRUN/BIGRUN for further details.


Assembler

Introduction

There are differences in the use of the assembler and the interfacing of assembly language routines with BIGBASIC (CALL and USR). These are discussed below.

Since the assembler necessarily works with 64K segments (the processor's instruction pointer is only 16 bits), BIGBASIC's data space is considered for this purpose as consisting of consecutive 64K regions (&00000 to &0FFFF, &10000 to &1FFFF, etc).

Program Counter

The assembler uses P% as the program counter (as usual) and the least significant 16 bits are assumed to be the value in the processor's instruction pointer. If, when assembling, the program counter attempts to cross the boundary between two 64K segments (in other words, if the least significant word of P% increments from &FFFF to &0000), a 'Wrap' error (code 98) occurs.

Calling Assembler Code Routines

When a CALL or USR is done, the least significant 16-bits of the address become the program counter (IP register) and the most significant 16-bits are converted into a segment value selecting the appropriate 64K region.

Addresses &0FF?? are still used to access the emulated BBC Micro Operating System calls to OSWORD and OSBYTE ('read character at cursor position' - &FFF4 and 'read character dot pattern' - &FFF1). Unlike BBCBASIC, these addresses are entirely possible as true assembly language entry points and must therefore be avoided when using the assembler. This problem may be circumvented by using CALL with at least one parameter (in addition to the address) which will call an assembler language routine even if its address is in the range &0FF00 to &0FFFF.

When an assembly language program uses absolutely-addressed RAM locations for temporary storage, these are best defined using DB, DW or DD within the assembler code itself. This will result in the locations being in the 'code segment' and their contents can then be accessed using a CS: segment override. For example:

mov cs:[savesp],sp  ; Temp save of stack pointer
    ........        ; Some code
    ........
mov sp,cs:[savesp]  ; Restore the stack pointer
    ........        ; Some more code
    ........
retf                ; Make sure you terminate
                    ; your program
.savesp DW 0        ; Define storage location.
The alternative of reserving the storage space outside of the assembler (using DIM), which is acceptable for the 'small model' BBCBASIC, creates the problem of determining which segment it is in. If the storage location's address is in the bottom 64K (less than &10000) then it will be in DS:, but this is an undesirable restriction.

Segment Registers

The segment registers are set up by CALL and USR as follows:
CS:    The code segment of the assembler routine. If in the bottom 64K of BIGBASIC's data space, this will be the same as DS:, if in the next 64K region, is will be DS:+&1000, and so on.
DS: BIGBASIC's primary data segment (corresponding to the bottom 64K of the data space). BIGBASIC's private workspace is from DS:0000 to DS:03FF. PAGE, TOP and LOMEM are always in this segment, as is CALL's parameter block.
ES: The segment value of the first item in CALL's parameter list (if any). This simplifies the task of writing an assembly language routine which is compatible with both BBCBASIC and BIGBASIC, so long as CALL has only one parameter (other than a string variable).
If there are no parameters to CALL (apart from the call address) the ES: register is set to the value if DS:
SS: BIGBASIC's stack segment (the 64K segment containing HIMEM). The assembly language routine can safely use a few tens of bytes of stack below SS:SP.
The SI register is set to &FFFF on entry to the assembler language routine. This allows the routine to test whether it was called from BBCBASIC or BIGBASIC, since BBCBASIC always sets SI to a value other than &FFFF on entry. Using this, it is possible to write assembly language library routines which run with both BBCBASIC and BIGBASIC.

OSWORD Parameter Block

The parameter block used by OSWORD (CALL &FFF1) is addressed by a 16-bit number (high byte in Y% and low byte in X%) for compatibility with the BBC Micro. Consequently, it must be in the bottom 64K of the data area. The best way to achieve this (assuming that LOMEM does not exceed &0FFFF7) is to ensure that it is reserved using DIM at the very beginning of the program, before any variables or other heap items are created. A 'resident' integer variable should be used (DIM X% 8, for example) otherwise the variable name itself will use up some heap space below the parameter block.


Keywords

CALL

Parameter Table

Because a 16-bit pointer is inadequate to locate a variable within BIGBASIC's extended address space the parameter table built by CALL is structured differently. The first byte is the number of parameters, as before, and each parameter item consists of 5 bytes (not 3 as with BBCBASIC) as follows:
Byte 0 The variable 'type', exactly as with BBCBASIC.
Bytes 1,2 The offset value of the variable or string descriptor.
Bytes 3,4   The segment value of the variable or string descriptor.

Parameter Formats

The contents of the (4-byte) string descriptor differ from BBCBASIC in that the 16-bit pointer (bytes 2 and 3 of the descriptor) are the segment address of the string, which always lies on a paragraph boundary (offset = &0000). The example below may help to make this clear.

Example

The following segment of assembler code locates the start of a string variable which is given as the second parameter of a CALL (CALL code, junk, string$). The string address is returned in es:bx and its length in cl.
mov bx,ds:[bp+7]    ; Get string descriptor offset
                    ;(note use of ds:)
mov es,ds:[bp+9]    ; Get string descriptor segment
                    ;(note use of ds:)
mov cl,es:[bx+0]    ; Get string length
mov es,es:[bx+2]    ; Get string segment
mov bx,0            ; Set string offset
Compare this with the equivalent routine for BBCBASIC
mov bx,[bp+5]       ; Get string descriptor offset
mov cl,[bx+0]       ; Get string length
mov bx,[bx+2]       ; Get string offset

EVAL

The EVAL function is more restricted in its use than with BBCBASIC. In particular, EVAL will not operate correctly if it attempts to activate any of the statements INPUT, READ or CALL via a user-defined function. For example, the following program will not work correctly.
100 PRINT EVAL("FNget*3")
110 END
120 :
130 DEF FNget
140 LOCAL A
140 INPUT "Enter a number ",A
150 = A

HIMEM

The default value of HIMEM depends on the amount of memory available. It is automatically set to the maximum possible value when BIGBASIC is run.

Although you are not prevented from doing so, attempting to set HIMEM higher than its initial value will probably crash the system.

HIMEM cannot be changed whilst BIGBASIC's stack is in use. In other words, from within a loop, subroutine, function or procedure. Any attempt to do so will result in a 'Mistake' error.

LOMEM and PAGE

LOMEM and PAGE must be in the range &00400 to &0FFFF (in other words, the bottom 64 Kbytes of the virtual address space). Attempting to set PAGE or LOMEM to a larger value will result in a 'Too big' error.

TOP

The value of TOP (the first free byte above the user's BIGBASIC program) cannot exceed &0FFFF. Consequently, with page set to its default value of &900, your program cannot exceed &F6FF (63231) bytes in length. Attempting to load a program which would cause TOP to exceed &FFFF will result in a 'No room' error.

USR

See the keyword CALL in this annex for details.


Operating System Interface

*LOAD and *SAVE

*LOAD and *SAVE will accept 20-bit (5 digit) virtual addresses. As with BBCBASIC, specifying a full eight digits for the address causes the first four digits to be interpreted as the segment value and the last four as the offset, overriding the virtual address mapping.

The maximum size of a *LOAD or *SAVE file is &FFFF (64K or 65535) bytes. If you try to *LOAD a file which is longer than this, only the first 65535 bytes of the file will be loaded. If you try to *SAVE a file longer than 65535 bytes, the length will be evaluated MOD 65536. In neither case will any error messages be displayed.


Data Structure Format

Integers and Reals

The format of data structures within BIGBASIC's heap is different from that of BBCBASIC. A program which peeks this area (hopefully, no programs poke it!) will not work correctly without alteration, The main difference is that all items are at paragraph-aligned addresses (integer multiples of 16 bytes) and all 16-bit pointers to heap items are the segment value; the offset is zero.

As described in the Annex entitled Format of Program and Variables in Memory, the smallest amount of space taken up by an integer or real variable is 8 bytes (descriptor and value). However, as mentioned above, heap space is allocated in 16 byte 'paragraphs'. The first character of a variable's name is held in the index of variable names and not in the variable descriptor. Consequently, you can use a variable name of up to 9 characters without increasing the amount of heap memory allocated to the variable.

Strings

The contents of the (4-byte) string descriptor differ from BBCBASIC in that the 16-bit pointer (bytes 2 and 3 of the descriptor) are the segment address of the string, which always lies on a paragraph boundary (offset = &0000). Thus, space for strings is allocated in 'paragraphs' of 16 bytes and the initial space allocated for a string is never less than a paragraph. Consequently, it may not be necessary to initialise string variables as described in the Annex entitled Format of Program and Variables in Memory in order to prevent the generation of 'garbage'.

See the keyword CALL in this Annex for details of how to find the start address of a string in assembler code.

Left CONTENTS

CONTINUE Right


Best viewed with Any Browser Valid HTML 3.2!
© Doug Mounter and Richard Russell 1999