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 lines followed by two 00 bytes to signify the end of the program. The BASIC statements are condensed using tokens such as $8F for REM
. To see a more detailed explaination have a look at: Basic Line Storage on the VIC-20.
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 bytes 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.
Location | Octets | Explanation |
---|---|---|
$1001 | 1C 10 | Next line link. Here this is also the end of BASIC program - $101C |
$1003 | 0A 00 | Line number - 10 |
$1005 | 8F | REM token |
$1006 | 20 | Space character |
$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.
.E 1200
Enter 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.
.X
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 REM
statement.
20 SYS4103
Memory Use Comparison
The following BASIC statement shows how much memory is free for BASIC programs.
PRINT FRE(0)
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) |
---|---|---|
DATA statements | 3460 | 121 |
REM statement | 3544 | 37 |
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.
Conclusion
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.
Video
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 REM
statement.