-----------------------------------
C64 Graphics
-----------------------------------
Unlike its competitors at the time,
the Commodore 64 completely lacked Basic instructions for
programming graphics and sound, requiring the user to read and
write contents to memory using PEEK and POKE instructions to
interact with the hardware (the various Basic extensions never
became a standard).
Furthermore, producing high-resolution graphics is complicated by
the fact that the graphics page is not linearly mapped in memory
but requires complex calculations to draw individual pixels.
It is possible to precalculate address tables to speed up
operations, however, to have reasonable performance, it is
necessary to use assembly.
The best results are obtained in assembly with pre-calculated
tables, at the cost of a large memory footprint; if execution
speed is not very important, a fairly compact assembly routine can
be created to perform the calculation.
The "Graphics1" and "Graphics2" routines I created allow you to
perform the main graphics functions: entering and exiting
high-resolution graphics mode (320x200), setting the background
and pixel colors, clearing the graphics page and drawing pixels on
the screen, limiting the x-coordinate to 255 for simplicity.
"Graphics1" is the most compact one (only 131 bytes), performs all
the calculations without the need of lookup tables and is
relocatable; "Graphics2" uses some arithmetics and two small
lookup tables, is about 16% bigger (152 bytes), plot is 30% faster
and is not relocatable.
Link to the assembly source code routine "Graphics1" with
comments: graphics1.txt
Link to a sample Basic program using the assembly routine
"Graphics1": graph1.bas
Link to the assembly source code routine "Graphics2" with
comments: graphics2.txt
Link to a sample Basic program using the assembly routine
"Graphics2": graph2.bas
I also wrote an optimized program in pure Basic V2 to compare
execution times.
Link to the pure Basic V2 program optimized for execution speed: graph3.bas
The Basic programs using machine language routines (a mix of Basic
and machine code) are at least twice as fast as the one written in
pure Basic V2, even though the pure Basic V2 program is optimized
for execution speed.
To compare the speed of the bare assembly routines without the
influence of the Basic part that slows down a lot the whole
execution, I wrote the test programs "test1.bas" and "test2.bas",
that fill the screen (256x200 pixels) using pure ML, respectively
the "graphics1" routines (fully calculated plot, no lookup tables)
and the "graphics2" routines (some arithmetics and two small
lookup tables). For comparison, the program "test3.bas" performs
the same test but is written in pure basic V2.
Link to the test program using the assembly routine "Graphics1": test1.bas
Link to the test program using the assembly routine "Graphics2": test2.bas
Link to the test program using pure basic V2 (very slow): test3.bas
You can run the Basic programs also in an emulator (I used VICE).
Here is the link of a disk image in d64 format used by VICE with
all the programs: graphics.d64
Attach the d64 disk image to drive 8 and load and run the Basic
programs.
Alternatively, you can view the programs in lower case in your
browser by clicking on the links in the tables below and
then copy and paste the programs themselves from your browser
window directly into VICE.
The output and the execution times of the programs on VICE
emulating a PAL C64 are reported below.
| Name | Type | Execution time (s) |
| graph1.bas | using "graphics1" ML routines (calculated) | 26 |
| graph2.bas | using "graphics2" ML routines (calculated + 2 LUT) | 26 |
| graph3.bas | using pure Basic V2 (optimized) | 55 |
| Name | Type | Execution time (s) |
| test1.bas | ML, fully calculated | 8 |
| test2.bas | ML, calculated + 2 small LUT | 5 |
| test3.bas | optimized BASIC V2 | 1474 |