Maya Grab [Day 17] – Using Assembler in BASIC

Task for today was to include the assembler code into the BASIC program and to replace old drawing routines with the newly created ones which run much faster. By the way, it’s been said that assembler code runs from 10 to 1000 times faster than BASIC, depending on what the code is actually doing.

I didn’t wanted to load any external files; the game should be stored in one file. So the assembler code needs to be written from BASIC directly into the desired location in memory and that’s the upper RAM located at address $C000. It’s the same procedure like transferring data for sprites; POKE-ing values to specific address. Meaning, the compiled code should be stored like data. Now, I’m pretty sure that there is a easier way (or some helper tools) to generate BASIC data from a compiled assembler code; but I did it the hard way. KickAssembler compiled the code and build a .prg file with a pointer to store the program at address $C000. So first the .prg file needs to be loaded. Then I used a MONITOR to dump the memory between $C000 and $C0B0 where the assembler code is stored. The code is shown in byte format, but hexadecimal, so I wrote a little tool which converts comma separated hexadecimal values into decimal and voala, there is the data needed for BASIC.

60005 REM *****************************
60010 REM * MACHINE LANGUAGE CODE     *
60015 REM *****************************
60020 :
60025 FOR I=0 TO 183
60030 READ A: POKE M+I,A
60035 NEXT

The whole assembler code fits in 183 bytes, actually 175, but I’ve put some zeroes at the end. This loop reads the data and stores it into address 49152 ($C000). This subroutine needs to be called only once when the game starts.

.label ClearRoom=$c052
.label ClearScreenPart=$c08e
.label ClearItemsDirections=$c07a
.label DrawFrame=$c000
.label ClearInputMessage=$c066

Probably every compiler after building the code is kind enough to provide a symbols file with addresses for every subroutine. The values must be converted to decimal for the SYS command which will be called from BASIC.

SYS 49234: REM CLEAR ROOM
SYS 49274: REM CLEAR ITEMS AND DIRECTIONS
SYS 49152: REM DRAW FRAME
SYS 49254: REM CLEAR INPUT MESSAGE

This is how it looks like at the end in BASIC when calling the assembler subroutines.

While entering the new data I’ve ran out of memory for the first time. Needed to remove old drawing routines first before continuing the work. What’s left to complete the original game is only the interpreter. Before even starting that, I need to make as much space as possible, since only 23 bytes are left.

Program size: 38888 bytes, on disk 37084 bytes or 146 blocks
Free BASIC memory: 23 bytes
Used BASIC commands: –

Source code BASIC
Source code ASM

* * * * *