Tricking c64 basic into clearing a hi-res screen quickly
retro64.altervista.org
retro64.altervista.org
Tricks like these, intentionally causing overflows, used to be the norm. You've got a tiny bit of hardware, which makes it easier to reason about overall behaviour (until the inevitable BSOD). You can generally tell when its safe to blow up your whole stack. And that kind of thing is fine to do.
The TMS9900 was a fast (for 1979) 16-bit CPU, however, and some fast routines could be tucked away in those 256 bytes of RAM to achieve some interesting effects (for example smooth horizontal scrolling in Parsec, on a machine with no scrolling registers).
The 2600 can also run self-modifying code in RAM, which I did: http://www.dos486.com/atari/
FMT Enter sub-interpreter
HTEX 'Hello, world' Displays horizontal text
FEND Exits sub-interpreter
[0] http://unige.ch/medecine/nouspikel/ti99/gpl.htm $ text="Back in the day, one of IBM's early databases worked by storing memory into the graphics buffer, outside the field of view of the monitor, because writing directly to that memory space was faster on the hardware than anywhere else. (My dad wrote it when working for National Mutual)." && printf "P6\n$((${#text} / 3)) 1\n255\n$text" > test.ppm
The result is kind of dim because none of the characters are greater than 0x80. You can brighten it by changing the 255 to, say, 127.The resulting file should open in most image viewing programs, though somewhat amusingly while writing this I messed up the format accidentally found a denial-of-service in Apple's ImageIO NetPBM parser :P
Memory was really tight and every byte was valuable. Also external memory was slow. Programs were often loaded in a compressed form and then uncompressed. Since the uncompressed version filled the available memory to the last byte it raised the question where to put the unpackers code.
A natural choice was to run it from video ram, which would be overwritten when the game started and the unpacker was not needed anymore. As slow as the C64 was, you could clearly identify the unpackers loop counters.
I have also heard the story that this trick was especially popular for pirated games. The crackers used to add their intros and they had to fit in somewhere into already filled to the brim memory. So they used compression to squeeze their intros in.
But why add only 1 character each time, why not add the string to itself? That would grow it exponentially and would require much fewer steps. Or is string concatenation much slower than character concatenation?
https://retro64.altervista.org/blog/garbage-collection-commo...
Which would limit the loop to 1 + 2 + 4 ... 128 = 255. You could start off with this, but making it work and filling exactly 8000 might be too complicated.
There may be a fast path for adding one character, but in any case bytes of program are a valuable resource with only 64k ram so having a second loop from nearest power of two to 8000 would be a waste of bytes.
On top of that, a handful of key internal BASIC routines are called indirectly through pointers. BASIC itself is in ROM and more or less immutable, but by redirecting those pointers you can have it call out to new code in RAM.
?SYNTAX TERROR