Book Review

The Companion to the BBC Micro
By Ian Murray(Century)

Good home wanted for machine code

(not too near Basic programs) APPLY WITHIN

By IAN MURRAY

WHEN we received our review copy of Assembly Programming Made Easy for the BBC Micro, by lan Murray, we were so impressed that, instead of a review, we decided to print an extract — with the kind permission of the book's publishers. Century.

We're certain that, when you've read it, you too will be struck with the clarity of lan's easy-to-understand explanations, and want a copy for yourself.

So we've made obtaining this gentle guide to machine code programming as simple as possible by making it a Micro User special offer. See page 98 for full details.

The extract we've picked is on a subject we're often asked about — where exactly can you store machine code?

Knowing that the BBC Micro assembles its code to the memory location given by P% is one thing ... but how do you choose P% to ensure that the code is safe from, say Basic programs?

Read on, and lan Murray will show you just how easy it is!

THE assembly language on the BBC Micro is written as part of a Basic program. This is unique to the BBC machine as most other assemblers stand alone and have nothing whatever to do with Basic or any other language.

Obviously the machine code made by the assembler has to be found a safe home somewhere in the computer's memory. Preferably this home should not be part of or even near the Basic program itself.

If your Basic program with its assembly program "grows", then it may bump into where your machine code would like to rest. If your Basic program is unlikely ever to change in size, you may get away with putting the machine code near Basic. But best of all is to use the facilities provided for you by the BBC Micro.

You now need to know something about how the memory is divided up. You would be foolish to try and put "your" machine code where the designers of the BBC Micro have put "their" code.

You will find a version of Figure I in the user guide on Page 500. As you can see, the whole of the top half of the memory is just not available to you. Memory locations from 65535 decimal to 49152 decimal are all used by the operating system.

book-1.jpgFigure I: The BBC Micro's memory map

This operating system is responsible for all the ordinary and clever tricks of the BBC Micro, such as getting the tape loading and saving to work, defining the red function keys, scanning the keyboard for which key you have pressed and putting it on to the screen, allowing you to change colours on the screen easily and quickly. The list is endless.

Then the Basic language takes up locations 49151 decimal to 32768 decimal. Remember, Basic needs all this memory so that it can work out the machine code equivalent of the program that you typed in in human readable form. For the more technical of you, Basic in the BBC Micro is an "interpreted language".

book-2.jpg

This means that, though you may have a 500 line Basic program, it goes to work converting into machine code only the actual instruction it has to carry out next, leaving all the others unconverted until needed.

We are told by the manufacturers that, starting from the bottom, memory locations 0 to 3583 decimal are also reserved for use by the operating system.

This means that the only memory location available to the Basic program you write, with the assembly program inside it, the machine code generated by the assembly program and the screen graphics, is from 3584 decimal to 32767 decimal (on a Model B machine).

Whatever you write in your Basic program is stored by the operating system upwards from 3584 decimal. If you type the Basic command:

PRINT TOP

then the top memory address used by your program will appear on the screen. TOP is a word reserved by Basic for this purpose.

Similarly if you type into the machine:

PRINT LOMEM

that will tell you where Basic intends to keep the values associated with any of the variables used in your Basic program. Mostly it will be one different from TOP — but you can change this. The screen graphics need a slice of memory and this works down from location 32767 decimal. Where it finishes is shown by the Basic word HIMEM.

In every mode it is different. HIMEM is not the same in Mode 2 and Mode 7. Type into the machine:

MODE 2
PRINT HIMEM
MODE 7
PRINT HIMEM

You can think of HIMEM as a huge wall across memory. Most of the memory below HIMEM can be used by you in various ways.

None of the memory above HIMEM can be used by you as it is needed by either the screen, Basic language or the operating system.

But this is a wall with rollers under it. It is possible to roll the HIMEM wall down memory, creating empty space behind it and before the start of the screen graphics.

Typing in Mode 7 and PRINT HIMEM in a BBC Model B will have given you the answer 31744. If you type:

HIMEM = 31000

then you will have created 744 empty memory locations which are free for any machine code that you would like to pop into them. The first one free will be 31001 decimal. You can set the program counter to 31001 by typing:

LET P% =31001

and then all the machine code you assemble will slip into the memory locations free to it.

But beware! If it turns out that you need more than 744 memory locations the computer will not tell you — unless you ask — and certainly no error messages will appear.

So after you have finished assembling your program into machine code you would need to type:

PRINT P%

to find out if it was 31744 decimal - or perhaps more - so intruding into the area for Mode 7 screen graphics.

For the technically minded, now is the time to reveal that strictly speaking P% is not the true program counter. It is a variable used by Basic and the BBC operating system which usually shows what the program counter has stored in it. But it operates just like the program counter.

So Rule 1 for finding space for machine code is:

MOVE HIMEM down memory.
PLACE machine code between HIMEM and start of screen graphics.

Problems with Rule 1:

• You have to make certain that you reserve enough space and do not overwrite screen graphics.

• Any change of mode in your program will reset HIMEM and probably lead to screen graphics in the new mode over-writing your machine code.

• As TOP shows where the Basic program itself is, we could place our machine code in some memory locations above TOP. We can type:

LET P% = TOP + 1000

Our machine code would then be placed from "TOP + 1000" upwards. This may interfere with work space that Basic needs, which starts at HIMEM and works downwards towards LOMEM. But as a temporary measure in Mode 7 it will work adequately.

book-3.jpg

Rule 2 for finding space for machine code is:

SET the program counter to a suitable value above TOP.

Problems with Rule 2:

• The location above TOP that you set for the program counter must give Basic enough room to store its variable values.

• With a large Basic program in Mode 7 or even a small Basic program in Mode 2 you must make sure that your resetting of the program counter does not take you too near HIMEM or you will not allow yourself enough memory space.

You can, of course, try to overcome one of these disadvantages by shifting the LOMEM wall upwards and fitting your machine code between TOP and LOMEM.

Basic's variables are dealt with where LOMEM starts, so you would have unused space by doing this shift, like:

LOMEM = LOMEM + 250

This would give you 250 free memory locations. You would then need to type:

LET P% = TOP

Rule 3 for finding machine code space:

MOVE LOMEM upwards to a suitable new location.
SET the program counter to TOP

Disadvantages of Rule 3:

• You must give yourself enough space for your machine code, or you will overwrite where Basic keeps its variable values.

• You must move LOMEM upwards before any reference to any variable. Otherwise that variable will sit where it usually does, just one above TOP. Your machine code would then overwrite it.

• You may move LOMEM too close to HIMEM causing the Basic to "scramble".

As you remember from Figure I showing how the BBC Micro's memory is organised, there are interesting areas at the bottom of memory.

Just as we can move LOMEM and HIMEM around in memory, so we can move PAGE.

PAGE always has the memory location of the beginning of your Basic program. For tape-based machines this is always 3584 decimal (&E00 hex). For disc-based machines this is different. For technical reasons any movement of :he PAGE wall must be groups of 256 memory locations.

So we can type:

PAGE = PAGE + 512

This would give us 512 free memory locations from 3584 decimal upwards. We could then type:

LET P% = 3584 (for tape machines)

This is a bit messy. It would be better to type:

LET P% = PAGE - 512

This would mean it would not matter if you were using disc or tape machines.

Rule 4 for finding space for machine code is:

SET PAGE to a new value above its current value. This must be a multiple of 256.
SET the program counter to the old value of PAGE.

Disadvantages of Rule 4:

• Any new Basic program you now load must be forced to load above the machine code, either by manually resetting PAGE to the suitable value, or by specifying the load address when you do load it.

• If you need 260 memory locations for the machine code, then you will have to take the full 512 memory locations, which will mean wasting empty memory locations. This could be significant in a high resolution graphics program.

The BBC Micro's operating system seems (with tape-based machines) to have left memory locations 3328 decimal (&D00 hex) to 3583 decimal (&DFF hex) free for machine code use.

If this is enough space for you, then you can type:

LET P% = 3328

or

LET P% = &D00

These mean the same. &D00 is 3328 in the hexadecimal counting system which will be explained in detail later. Some of the games programs on the market hide their machine code at &D00. You may have noticed this.

Rule 5 for finding machine code space:

SET the program counter to 3328 decimal (&D00 hex).

Disadvantages of Rule 5:

• Very little space is available to you for the machine code before you start overwriting the Basic program beginning at 3584 decimal.

• If you have a disc based system, you will find that the system itself uses some of this memory. Then you may find that the machine code starts doing funny things to the disc drives (such as turning them on), or that any disc load operations are incorrect or that use of the Break key overwrites your machine code.

This is often the cause of problems you may have found with copying machine code games over to a disc system. These games probably had machine code sitting at &D00 hex.

Rule 5 can sometimes be extended to start at either 3072 decimal (&C00 hex) or 2816 decimal (&B00 hex). These memory locations also get round the problems with disc based machines.

But you can only use them if:

• Nowhere in your program do you use program (or user) defined characters. These are stored from 3072 decimal (&C00 hex) to 3327 decimal (&CFF hex).

• Nowhere in your program do you use the red function keys. Your plans for these keys are stored in memory locations 2816 decimal (&B00 hex) to 3071 decimal (&BFF hex).

But, as I said earlier, the BBC Micro does try to make life easy for you. The designers were aware that all these different hiding places for machine code could be annoying to organise. They invented a special Basic command which allows the BBC operating system to fit in your machine code wherever it can find space, thus taking the worry off your shoulders.

If you type:

LET P% = DIM A% 300

then the program counter is set to start at a 300-long block of memory locations which begins at A%. You do not need to know where the block of memory is, but you can find out by typing:

PRINT A%

This is the most common and useful method of hiding machine code, as it does not depend on what mode you are in or on PAGE, HIMEM or LOMEM.

Rule 6 for finding machine code space:

SET aside memory space with the DIM statement.
SET the program counter to the DIM statement.

Generally if the machine code is to be part of a Basic program, such as a games or educational program, then Rule 6 is the best method.

But if you want to engage in software protection or have a machine code sitting in the machine whatever Basic program is running, then you will have to choose one of the other rules. Probably it is best to hide short programs at 3328 decimal (&D00 hex).

book-4.jpg