This article appeared in the HOME COMPUTER ADVANCED COURSE MAGAZINE (c) 1984
In the first part of this series we looked at how an operating system is arranged in general terms and examined and, in particular, how the BBC Micro's OS is arranged. In this instalment, we'll look at how the BBC OS actually uses its memory, and how vectors are used in a computer operating system.
The BBC Micro makes use of various areas of memory, many of which have multiple functions. A typical example of this is page &9 of the memory - the area of RAM between locations &900 and &9FF - which is used, at different times, as the RS432 output buffer, a cassette output buffer, speech workspace and extended sound workspace! No one can accuse Acorn of not getting the most from its memory.
A further example is the block from &0E00 to &1900; in a BBC Micro with a cassette recorder as its filing system, this area of memory is free for use as BASIC program space. However, when a disc system is being used, this area is used as disc filing system workspace, reducing the amount of memory left for BASIC programs by over 2.5 Kbytes. This is extremely annoying in screen Modes 0 to 2, where memory is restricted anyway.
The final example of multiple use of memory is the area between &8000 to &BFFF. If a DFS ROM, a word processor or utility ROM is fitted in the machine, it will occupy this block. This is also the area of memory that the BASIC interpreter ROM resides in. These are called 'paged ROMs'; only one of them can be active at any one time. The ROM required is selected by the operating system, and 'switched in', or 'paged in' - hence the name. Under normal circumstances, the BASIC ROM is paged in, and the BASIC interpreter is running, thus enabling us to type in and execute BASIC programs. However, when we execute a DFS command, the OS pages the DFS ROM, executes the command, and then pages the BASIC ROM back in. During the execution of the DFS commands, the BASIC ROM is simply ignored. Other ROMs, such as the Telesoftware Filing System or the Wordwise wordprocessor chip, also occupy this memory space and are also paged in and out as required. It's probably just as well that the BBC Micro uses the same area of memory for several purposes, as otherwise there'd be little memory left for us to work with.
Once the OS has taken its share of the computer memory, what remains is the available user memory. The BASIC system variable PAGE contains the address of the Start of BASIC program area, and the variable HIMEM points to the start of the screen display memory; the space between is available for BASIC programs, variables and machine code programs. Type in this instruction to find these addresses, and the memory available for BASIC programs:
PRINT~PAGE, ~HIMEM ~(HIMEM-PAGE) "BYTES FREE"
In the following table, you'll find a brief description of the relative merits of different storage areas for machine code in the BBC Micro.
When Area is Suitable For Machine Type of Filing System Code Programs Tape: Disc: --------------------------------- --------------------- &0D00 - &0DFF Page &D - only if no paged ROMs are (o) X in the machine &0B00 - &0CFF Page &B and &C - if no user defined characters or user function keys (o) (o) are used in the program &0A00 - &0AFF Page &A - if serial inferface is not (o) (o) in use Space saved in BASIC program area in the DIM command --------------------------------- --------------------- o = OK; (o) = OK with Reservations; X = Not used
For most routines that are to be used in conjunction with BASIC programs, storing the code in the BASIC program area is the best method.
Once the machine code is in memory, it generally needs some workspace to allow it to run. Most 6502 machine code programs require some zero page locations as workspace, mainly because certain indexed addressing instructions will need zero page locations. Acorn have made extensive use of this page for the OS, but some locations have been set aside for machine code programming. A byte by byte account of what each of the OS locations does is little use to the programmer, and directly accessing these locations is not encouraged - the useful locations should be accessed by calling the appropriate OS versions, thus avoiding problems when a machine code program written under one OS version is run under a different version.
Zero page location Usage ------------------ ----- &FA - &FF OS &F8 / &F9 Unused in OS 1.2 &A0 - &F7 OS &90 - &9F Econet &70 - &8F Unused 0 - &6F BASIC
The two major routes we can take to use the routines in the BBC OS are the OSBYTE and OSWORD routines:
OSBYTE enables us to affect the behaviour of many OS routines, by passing control codes and parameters in the A, X and Y registers of the 6502. In BASIC, we can access the OSBYTE routines via the *FX command. *FX is followed by either two or three numbers: the first number is the control or function code passed to the A register; the second is the number passed to the X register; and the third is the number passed to the Y register. The third parameter is not required by all OSBYTE calls. In machine code, OSBYTE is called at address &FFF4. These two versions are equivalent in function:
BASIC Assembly Language ------ ----------------- *FX4,1 LDA #4 LDX #1 JSR &FFF4
The value in the A register defines exactly what a particular call to OSBYTE will do. The above call, for example, affects the actions of the cursor keys; the parameter passed over in the X register specifies whether the cursor keys retain their normal editing function or whether they simply return an ASCII code.
It's a sad fact of life that all OS routines cannot be affected by OSBYTE. Its main drawback is the limit on the number of parameters that you can pass over to the routine. If we ignore the contents of the A register, which tells the OS which routine within OSBYTE we wish to use, then we can only pass two parameters in the X and Y registers. If we want to pass any more than this then we use the second routine, OSWORD.
OSWORD enables us to do such things as sound generation, disc reads and writes, and so on. This is the difference between OSWORD and OSBYTE; OSBYTE affects *how* the OS does certain tasks, and OSWORD enables us to do particular tasks. OSWORD obtains its parameters from a *parameter block* that is pointed to on entry to the OSWORD routine by the 6502 X and Y registers. This parameter block is situated in RAM, and its size and arrangement depend upon the OSWORD call being made. The A register contains a function code that determines which of the OSWORD functions are to be executed by the OS. Once the registers and the parameter block have been prepared, OSWORD is called at address &FFF1. OSBYTE and OSWORD are the principal means of entry to the OS; because of their importance, we'll look at them in greater detail in later parts of the series.
Other OS routines are entered, from BASIC, by typing in an asterisk (*) followed by the command. The presence of the * causes the command following it to avoid the BASIC interpreter and be passed to an OS routine that bears the name OSCLI, meaning 'Operating System Command Line Interpreter'. This interprets the OS commands that are typed in and acts upon them by calling the appropriate routines in the OS. Such commands are often called * or Star Commands. The table shown lists those Star Commands recognised by the BBC; any not recognised, spelt incorrectly or without the correct number of parameters will usually give the "Bad command" error message.
Command Description and Comments ------- ------------------------ *HELP This will give the version number of the BASIC. It can also be used to gain information about other paged ROMs fitted - e.g. *HELP DFS *BASIC This command will enter the BASIC language. A variation of this command, such as *WORD, will enter a paged ROM, in this case View *CODE In OS 1.2 only. This enables the user to add new commands *LINE to the OS *KEY Used to program the function keys *MOTOR n Used to control the tape motor relay: n=0 turns the relay off and n=1 turns the relay on *ROM, *TAPE Used to initialise the appropriate filing system - i.e. *DISC, *NET *TAPE will enter the 1,200 baud tape filing system, and *DISC will enter the disc filing system *FX This enables the programmer to control the values of various OS variables, thus controlling the behaviour of the OS *RUN, *OPT These are all filing system commands and will be examined *LOAD, *. later in the series *CAT, *SAVE *SPOOL *SPOOL sends the screen output to the screen and to a file. *EXEC reads in data from a file as if it were being read from the keyboard *TV x,y Affects the vertical position of the screen and the screen interface: x=0 means no change in vertical position, x=1 moves the screen down one line, x=255 moves screen up one line; y=0 interlace on, y=1 interlace off. The effects of this command come into operation at the next mode change and stay in effect until a
- or another *TV command is issued
For further explanation of the use of these commands, consult the BBC Micro's user guide.
We can pass commands to the Command Line Interpreter (CLI) by using the OS routine or by the direct method. OSCLI's uses are twofold: first of all, it enables us to pass commands shown in the table to the CLI from machine code should we want to; and secondly it enables us to pass BASIC string variables over to the CLI. The programs that follow feature both these uses. Notice that the integer variables, A%, X% and Y%, pass their values directly into the A, X and Y registers. X% (or the X register) and Y% (or the Y register) point to the position in memory of the string of characters, that is to be treated as a * command, and is to be interpreted and executed by the OSCLI routine. X holds the low byte of the address and Y holds the high byte of the address.
BASIC version BASIC + Assembly Language Version ------------- --------------------------------- 10DIM C 100 10DIM C 100 20oscli=&FFF7 20oscli=&FFF7 30INPUT"ENTER COMMAND",$C 30FOR I%=0 TO 2 STEP 2 40$C=A$ 40P%=&C00 50X%=C MOD 256 50[ OPT I% 60Y%=C DIV 256 60.code LDX #C MOD 256 70CALL oscli 70 LDY #C DIV 256 80GOTO 30 80 JSR oscli 90 RTS 100]:NEXT I% 110INPUT "ENTER COMMAND ",A$ 120$C=A$ 130CALL code 140GOTO 110
Running this program produces a prompt: the user types in a * command, presses RETURN and the command will be executed. The rather odd-looking DIM statement in line 10 of both these programs forces the computer to set aside 100 bytes of memory in the space set aside for BASIC variables and initialises the variable 'C' with the address of the start of this block of memory. This 100 bytes can then be used for storing machine code programs, or, as in this case, data for machine code programs. The $C=A$ statement puts the bytes that make up the command string held in A$ into the block of 100 bytes, starting at the first byte reserved by the DIM command. In both programs, the X and Y registers (or the X% and Y% variables) are set up and the call is made to OSCLI. The command string is then executed.
This program is the basis of a routine for use in menu-driven programs, where it might be useful to allow the user to do things like catalogue discs or tapes without leaving the program. The command required is simply put in to the string variables and passed to OSCLI for execution. Typing *A$ will not work. The OS will attempt to execute a command called *A$, which simply doesn't exist!
Using this technique, it is also possible to pass numeric variables to a * command by using the STR$ function to convert them into strings. Normally, the CLI will not accept any variable names passed to it; it gives the Bad Command error message instead of trying to evaluate the variable concerned.
Any * command that is not recognised by the OS is passed over to any paged ROMs. Each one is asked if it recognises the command; if it does then it executes it. Commands not passed for execution in this fashion are then treated as bad commands *only if* a fast filing system, such as a disc drive, is not in use. If it is, then the disc will be inspected to see if it contains a file with the same name as the command (without the *). If it does, then the file is loaded into the machine and treated as a machine code program. This can cause *big* problems if the file isn't a machine code program! The computer usually 'hangs' until you put it out of its misery. If such a file isn't found then the "Bad Command" error message is printed.
BBC Micro Memory Map: --------------------- &FF00-&FFFF OS ROM &FEC0-&FEC1 ADC Chip &FEA0-&FEA2 6854 &FE80-&FE83 8271 Floppy Disc Controller &FE60-&FE7F User VIA &FE40-&FE5F System VIA &FE30 Paged ROM Select &FE20-&FE21 Video ULA &FE08 6850 &FE00-&FE07 6845 CRTC &FD00-&FDFF JIM &FC00-&FCFF FRED &C000-&FBFF OS ROM &8000-&BFFF BASIC ROM / Paged ROMs &7FFF RAM Top (Video RAM (HIMEM Changeable) (BASIC Stack boundaries) (Top of variables ?2+256*?3 (Variables (TOP (BASIC Program &1900 PAGE for Disc BASIC Program or DFS Workspace &E00 PAGE &D00-&DFF Paged ROM Wkspace or User Machine Code &C00-&CFF User-Defined Characters &B00-&BFF User-Defined Keys &900-&AFF BUFFERS &800-&8FF SOUND Workspace &400-&7FF BASIC Workspace &3E0-&3FF Keyboard Buffer &380-&3DF Tape System Variables &300-&37E VDU Wkspace for text/graphics &236-&2FF OS Workspace and Variables Written by FX Calls &200-&235 Vectors &100-&1FF 6502 stack &0-&FF Zero Page