OS RAM BASIC examples

Introduction

This page demonstrates how to get started programming in BASIC with the BooBip OS RAM module for the BBC Micro.

Text in the formatted blocks is BASIC code which can be entered at the BASIC prompt or added to a line of a program.

BASIC Memory Operators

BASIC has three memory access operators built in ?, ! and $. We can use these to control the OS RAM module no assembly language is required.

operator ?

The ? operator reads or writes one byte at the given address. It can be on the left or right of an = in an expression.

?&FF00 = 2
PRINT ?&C000
Operator !

The ! operator is similar to ? but accesses four bytes instead of one.

P%=&C000:!P%=&12345678
PRINT !&C000
Operator $

The $ operator is similar to ? but accesses a BASIC string instead of one byte. Please see the BBC Microcomputer User Guide for more information on the $ operator.

$&C000="Hello"
P%=&C000:A$=$P%:PRINT A$

Changing Operating Mode

When the machine is powered on the OS RAM module mode is set to ROM. For use with BASIC we need to change to ROM+RAM mode so extra memory is available. It is necessary to write 0 (zero) to the module when leaving ROM mode.

The ? or ! operators can be used.

REM change to ROM mode
?&FF00=&2

REM change from ROM mode to ROM+RAM mode with ?
?&FF00=2 : REM guarantee ROM mode
?&FF00=0 : REM module arm sequence
?&FF00=6 : REM select ROM+RAM mode

REM change from ROM mode to ROM+RAM mode with !
!&FF00=&60002 : REM rom->arm->rom+ram

In BASIC programs procedures can be used to change mode instead of using magic numbers which are obscure and easy to forget.

1000 DEFPROCmode_rom:?&FF00=2:E.
1010 DEFPROCmode_romram:!&FF00=&60002:E.
1020 DEFPROCmode_ram(B%):?&FF00=4+B%:E.

Changing Bank

The module has two memory banks A and B.

?&FF00=8:REM Read+Write Bank A
?&FF00=9:REM Read+Write Bank B
?&FF00=&A:REM Write Bank A
?&FF00=&B:REM Write Bank B
?&FF00=&C:REM Read Bank A
?&FF00=&D:REM Read Bank B
?&FF00=&E:REM Read Bank A, Write B
?&FF00=&F:REM Read Bank B, Write A

Example procedures. Where B% should be set to 0 for bank A and 1 for bank B.

2000 DEFPROCbank(B%):?&FF00=8+B%:E.
2010 DEFPROCbankwrite(B%):?&FF00=&A+B%:E.
2020 DEFPROCbankread(B%):?&FF00=&C+B%:E.
2030 DEFPROCbankrnw(B%):?&FF00=&E+B%:E.

PAGE, LOMEM and HIMEM

The extra memory can be used directly by BASIC for code or data by changing PAGE, LOMEM and HIMEM.

A quick summary of BASIC memory pointers follows. Please read the BBC Microcomputer User Guide or another reference for a detailed explaination of the BBC memory and BASIC.

  • PAGE : defines start memory address for BASIC program
  • TOP : end memory address for BASIC program (read only)
  • LOMEM : defines start of BASIC variable memory area
  • HIMEM : defines end of BASIC variable memory area

Normally PAGE is set before loading (LOAD or CHAIN) a BASIC program. LOMEM is set by BASIC to just after the end of the loaded program. HIMEM is set by BASIC to just below screen memory and again on screen MODE changes.

For example, on a Model B with DFS after power on:

>NEW
>MODE 7
>10PRINT"Hello"
>P."  PAGE  = ";~PAGE'"  TOP   = ";~TOP'"  LOMEM = ";~LOMEM'"  HIMEM = ";~HIMEM'"  HI-LO = ";HIMEM-LOMEM
  PAGE  = 1900
  TOP   = 190E
  LOMEM = 190E
  HIMEM = 7C00
  HI-LO = 25330

PAGE, LOMEM and HIMEM can be changed by the user. BASIC screen MODE commands automatically change HIMEM so screen mode should be selected before setting HIMEM. MODE also checks LOMEM to determine if enough free RAM is available for screen memory - so change screen mode before changing LOMEM or you may get the Bad Mode error message. Advanced users could use VDU 22,m to change screen mode while the program is running.

Screen mode change and BASIC pointer initialisation can be done at the beginning of the program, in a loader program or in an !BOOT file for example.

OS RAM for BASIC program and variables

All the following examples assume the computer has just been reset (CONTROL+BREAK or *BASIC) and that OS RAM is initially disabled (?&FF00=2).

Code: main memory, VARIABLES: OS RAM

This is perhaps the simplest option. Load the program with a LOAD or CHAIN command in main memory and use OS RAM for the program's variables. 15K of OS RAM memory is availble for program variables regardless of screen mode selected.

>0!&FF00=&60002:REM ROMRAM
>1?&FF00=8:REM Bank A
>5LOMEM=&C000
>6HIMEM=&FC00
>10P."HELLO"
>20A%=7
>30DIM mc% 512
>40P.A%,~mc%
>50P."  PAGE  = ";~PAGE'"  TOP   = ";~TOP'"  LOMEM = ";~LOMEM'"  HIMEM = ";~HIMEM'"  HI-LO = ";HIMEM-LOMEM
>RUN
HELLO
         7      C009
  PAGE  = 1900
  TOP   = 19C8
  LOMEM = C000
  HIMEM = FC00
  HI-LO = 15360

In this example the ROM+RAM mode selection and bank selection is done at the very beginning of the program before LOMEM is set and any BASIC variables are accessed.

Code: OS RAM, VARIABLES: MAin memory

This example uses main memory for BASIC variable storage and OS RAM to hold the program. The order of initialising screen mode and the BASIC memory pointers is important to avoid Bad Mode or Bad Program error messages.

>!&FF00=&60002:REM ROMRAM
>?&FF00=8:REM Bank A
>PAGE=&C000
>HIMEM=&FC00
>NEW
>0LOMEM=&1900
>1HIMEM=&7C00
>10P."HELLO"
>20A%=7
>30DIM mc% 512
>40P.A%,~mc%
>50P."  PAGE  = ";~PAGE'"  TOP   = ";~TOP'"  LOMEM = ";~LOMEM'"  HIMEM = ";~HIMEM'"  HI-LO = ";HIMEM-LOMEM
>RUN
HELLO
         7      1909
  PAGE  = C000
  TOP   = C09B
  LOMEM = 1900
  HIMEM = 7C00
  HI-LO = 25344

A loader program to perform the intialisation or !BOOT file would be needed to load such a program from a filing system (e.g. Disc). This is because we need to load code into OS RAM before the program is RUN.

See the later loader example.

Code: OS RAM, VARIABLES: OS RAM

Both BASIC program and BASIC variable storage can be placed in OS RAM. This leaves main memory free for graphics mode, user defined characters, user data (e.g. sprites) etc

As with the previous example a loader program would be recommended to perform the initialisation.

>!&FF00=&60002:REM ROMRAM
>?&FF00=8:REM Bank A
>PAGE=&C000
>HIMEM=&FC00
>NEW
>10P."HELLO"
>20A%=7
>30DIM mc% 512
>40P.A%,~mc%
>50P."  PAGE  = ";~PAGE'"  TOP   = ";~TOP'"  LOMEM = ";~LOMEM'"  HIMEM = ";~HIMEM'"  HI-LO = ";HIMEM-LOMEM
>RUN
HELLO
         7      C08E
  PAGE  = C000
  TOP   = C085
  LOMEM = C085
  HIMEM = FC00
  HI-LO = 15227

OS RAM for general purpose data

OS RAM can be used for any general purpose data that you might typically *LOAD in a BASIC program such as graphics sprites.

>!&FF00=&08060002:REM ROM+RAM mode & select bank A
>*LOAD mydata C000

The BASIC memory operators ?,! and $ can be used to fetch or store data in OS RAM.

>!&FF00=&08060002:REM ROM+RAM mode & select bank A
>MODE 1
>P."Hello"
>REM copy 4K of screen to OS RAM
>FORI%=0TO&FFFSTEP4:I%!&C000=I%!&3000:N.
>CLS
>REM copy it back
>FORI%=0TO&FFFSTEP4:I%!&3000=I%!&C000:N.

High Program Loader Example

A simple loader program or !BOOT script is recommended to load a BASIC program into OS RAM for execution. This saves manually typing the commands to enable OS RAM and initialise PAGE etc.

Loader
   10 MODE1
   20 !&FF00=&8060002:REM ROM+RAM, bank A
   30 PAGE=&C000
   40 HIMEM=&FC00
   50 CHAIN"HIPROG"

Save as "LOADER"

The loader program first selects graphics screen mode 1. Then it enables OS RAM module ROM+RAM mode and selects bank A. Next it sets up PAGE and HIMEM. Lastly if CHAINs the program we want to run from OS RAM.

Program
   10 PRINT"Hello"
   20 A%=7
   30 DIM mc% 512
   40 PRINTA%,~mc%
   50 PRINT"  PAGE  = ";~PAGE'"  TOP   = ";~TOP'"  LOMEM = ";~LOMEM'"  HIMEM = ";~HIMEM'"  HI-LO = ";HIMEM-LOMEM

Save as "HIPROG"

Run

Before running CHAIN on the loader program this example resets BASIC and displays the default PAGE & HIMEM.

>MODE7
>*BASIC
BASIC

>P."  PAGE  = ";~PAGE'"  TOP   = ";~TOP'"  LOMEM = ";~LOMEM'"  HIMEM = ";~HIMEM'"  HI-LO = ";HIMEM-LOMEM
  PAGE  = 1900
  TOP   = 1902
  LOMEM = 1902
  HIMEM = 7C00
  HI-LO = 25342
>CH."LOADER"
Hello
         7      C08E
  PAGE  = C000
  TOP   = C085
  LOMEM = C085
  HIMEM = FC00
  HI-LO = 15227
>

The BASIC program loaded by the loader does not need any OS RAM specific code in it. As long as it doesn't try to change screen mode with MODE then most programs will just happily run. So now you can run a program with 15K of code and variables while in a 20K graphics mode with PAGE at &1900 - the DFS default!

More uses

Whether a novice or expert programmer there are a lot of options the OS RAM module opens up. 30K of additional user RAM directly accessible from filing systems and BASIC makes a big difference on a BBC Micro.

Assemble large programs

BASIC 2 allows you to assemble 6502 code to memory area pointed to by O%. With OS RAM you can assemble very large machine code programs by setting O% to OS RAM. Because no main memory is needed for the output the source files can make good use of long descriptive labels and FUNCTIONs for macros.

Graphics

Alter your favourite sprite editor to hold the sprites in OS RAM memory.

Bulk processing

Deal with large blocks of data for bulk processing tasks like converting 8-bit sampled sounds to 4-bit log format for playback on the BBC. Data can easily be loaded and saved in large chunks with normal filesystem operations from BASIC scripts.

Games

Novice programmers can take advantage of 15K extra memory very simply.

Intermediate programmers could fairly easily use one bank for BASIC variables and the other bank for sprites and sounds which are plotted/played by some assembly code. Just switch bank before drawing and switch back when done!

More

Speed up programs with large lookup tables of computed values. Increase graphics resolution and colours in your programs. Process larger chunks of data in one go for speed up. Develop large programs too big to fit in a Model B's memory then minify them once they are working properly for a stock B. Combine with sideways RAM for 63K of contiguous user memory. Imagination is the limit!