BIGBASIC incorporates all the features of BBCBASIC, but it is in no sense a replacement for BBCBASIC because, despite its advantages, it:
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.
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 /128
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.= BIGBASIC /999
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.
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).
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:
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.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 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.
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.
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.
Compare this with the equivalent routine for BBCBASICmov 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
mov bx,[bp+5] ; Get string descriptor offset mov cl,[bx+0] ; Get string length mov bx,[bx+2] ; Get string offset
100 PRINT EVAL("FNget*3") 110 END 120 : 130 DEF FNget 140 LOCAL A 140 INPUT "Enter a number ",A 150 = A
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.
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.
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.
See the keyword CALL in this Annex for details of how to find the start address of a string in assembler code.