How can we display pretty PETSCII art on the C64 as quickly as possible only using BASIC?
You might recall we have been steadily building a C64 Text Adventure / game engine, and as part of the last update I created a fancy PETSCII intro screen.
The problem with it is it takes a long time to load. So long, in fact, that I put a “skip intro” feature into it, even though the end result is just a static piece of PETSCII art.
Ideally a welcome image should be either immediately visible, or as close as possible to that, while also being attractive. Is that possible on the C64?
Well, obviously, it is possible because people do it, some of the PETSCII editors even output .PRG binaries, and the option to use assembly is there if we want it too. This isn’t an assembly tutorial though, it is about C64 BASIC. Where does that leave us?
Optimising the BASIC PETSCII Display Loop
C64 BASIC is not the most efficient 6502 BASIC interpreter out there, but there are things you can do to speed it up, as you can see below:
That is roughly now twice as fast by my count. Certainly noticeable when side-by-side. Still not exactly flashing up on screen like it would be compiled with assembly, but it is better.
How did I speed it up?
First, small incremental improvements can be made by bunching up lines of code to instead be all in one line:
FOR I = 0 TO 999
READ C:
GET I$: IF I$ <> "" THEN RETURN
POKE 1024+I,C
NEXT I
Becomes …
FOR I = 0 TO 999 : READ C: POKE 1024+I,C : NEXT I
Losing the check for a keypress also makes a small difference – Giving the C64 less to do per loop.
Next, in the same pattern of giving the C64 less to do, perhaps we should ignore 32
characters as they are just blank spaces? We can put an IF
in there.
Surprisingly, the IF
check is so slow, it is quicker to output the spaces than check for them!
The final tweak we can do to this approach is remove the math.
FOR I = 1024 TO 2023 : READ C: POKE I,C: NEXT I
Before, we were adding the value of I
in each loop, but that is unnecessary when the FOR
loop does that anyway, we just need to configure it with the correct start and end numbers.
If we had unlimited memory we could eliminate the loop entirely, but this is retro computing in BASIC so that would be a speed optimisation at the expense of not being able to fit the rest of the text-heavy game into RAM!
So what can we do instead?
PRINT > POKE
It turns out that regular PRINT
is much faster than reading and displaying one character at a time, once for the PETSCII symbols and again for the colours, even when using POKE
. Who’d have thought?
I jest but as POKE
can only write one byte to memory, in lieu of a fast bulk memory copy routine, PRINT
is the closest thing we have.
The result is as good as we are going to get using pure BASIC I think, unless you know a better way?
This is one of the situations where a real or recreated C64 keyboard and the actual BASIC screen editor would come in handy, because I had to convert my existing PETSCII art first into CHR$
characters from the POKE
symbols, and then convert those into {}
tokens that my IDE tokeniser understands!
Obviously I didn’t do all the colours because the process was tedious enough. For the actual thing I will likely get out my C64 and do it the traditional way!
Conclusion
Entering PETSCII symbols directly from the Commodore 64 keyboard is not just the easiest way to create PETSCII art but the fastest to render? It certainly seems so, but I would love to know your thoughts, especially if there is a better way that I am missing …
See the code and the game as it currently stands over on my online retro programming editor here.