BASIC programs often contain machine code routines but they take up quite a lot of space in BASIC. An interesting way to reduce the amount of space that they take is to store the machine code in
REM statements. This is much more compact and also means that we can call the routine directly from the location it is stored in memory rather than having to copy it to a further location. This doesn't just apply to machine code, we could also do this for storing other data such as a custom character set.
How BASIC is Stored in Memory
A BASIC program consists of a series of BASIC lines followed by two 00 octets to signify the end of the program. The BASIC statements are condensed using tokens such as $8F for
Storing Machine Code in DATA Statements
A machine code routine in BASIC is often stored in
DATA statements and then copied to another area of memory for execution. However, this uses up more memory than storing the routine in
REM statements as we will see later.
The following BASIC program copies a machine code routine stored in
DATA statements into locations 673-692. The machine language routine we're using cycles the screen border and background colours and is from the article: Hand Assembling to Machine Code on the Commodore VIC-20.
10 FORA=673TO692:READB:POKEA,B:NEXTA 20 DATA173,15,144,162,255,142,15,144,160,255 30 DATA136,208,253,202,208,245,141,15,144,96 40 SYS673
Storing Machine Code in REM Statements
The machine code routine stored in
DATA statements above is position independent and is represented by the following octets which we can also see in the table below.
AD 0F 90 A2 FF 8E 0F 90 A0 FF 88 D0 FD CA D0 F5 8D 0F 90 60
On an unexpanded Vic, BASIC programs start at $1001 (4097). We would use a different location for Vics with more memory. To create a
REM statement with the above machine code we would enter the following in memory. We could easily
POKE the values from BASIC into memory starting at location 4097 ($1001) or we could use a simple hex loader or a machine language monitor.
|$1001||1C 10||Next line link. Here this is also the end of BASIC program - $101C|
|$1003||0A 00||Line number - 10|
|$1007||AD 0F 90 A2 FF 8E 0F 90 A0 FF 88 D0 FD CA D0 F5 8D 0F 90 60||Machine language routine|
|$101B||00||End of BASIC line|
|$101C||00 00||End of BASIC program|
After we have entered the line into memory we must remember to update locations 45/46 to indicate the end of our BASIC program and the start of variables.
Using VICMON to Create REM Statement Containing Machine Code
If we have a machine language monitor, such as VICMON, then the process is really easy. We just alter the bytes in memory, exit to BASIC, update the end of BASIC program pointer and then enter our
SYS statement on the following line.
In VICMON we first have to enable a virtual zero page otherwise the monitor would overwrite bytes in memory necessary for BASIC.
REM lines containing machine code at location $1001 (4097), the start of BASIC on an unexpanded Vic.
.M 1001 .:1001 1C 10 0A 00 8F .:1006 20 AD 0F 90 A2 .:100B FF 8E 0F 90 A0 .:1010 FF 88 D0 FD CA .:1015 D0 F5 8D 0F 90 .:101A 60 00 00 00
Exit to BASIC.
Move the pointer to end of BASIC program, which is the next location after the end of the BASIC program marker. This is stored in LSB MSB order and here is $101E (4126).
POKE 45, 30 POKE 46, 16
Add line to jump to the machine code contained in the
Memory Use Comparison
The following BASIC statement shows how much memory is free for BASIC programs.
On an unexpanded Vic, that has just been switched on, it shows 3581 bytes free.
The following table shows how much memory is used by the two programs above.
|Program Version||Memory free (bytes)||Usage (bytes)|
We can see from this table that the version of the program that stored the machine code routine in a
REM statement used 84 bytes less memory than the one that stored the routine in
DATA statements. It also saved using up memory at 673-692 which could possibly be used for something else.
This method is a great way to save memory in BASIC programs, however it isn't without its problems. The machine code routine can't contain a
00 byte as this indicates the end of the BASIC line. It isn't suitable for listings and it is a pain if we want to alter the machine code stored in the
REM statements. Despite this, it is an interesting method which gives us some incite into how BASIC is stored in memory and can be useful in certain situations.
The following video shows a machine code routine being entered into both
DATA statements and
REM statements. It also shows the code being run directly from the area in memory where it is embedded within the