The original BASIC oneliner Link to heading
There is a simple one-liner in Commodore 64 BASIC that is so well-known that a book has been written about it. The program code is so short that it is used as the title for the book:
10 PRINT CHR$(205.5 + RND(1)); : GOTO 10
, A whole book about a single line of
code. By ten authors.
When run, the code starts outputting a pseudo-random maze that goes on forever:
This is achieved by repeatedly outputting, at random, either character 205 or character 206 of the standard Commodore 64 character set. It takes up 26 bytes of memory.
The assembler language equivalent Link to heading
I saw a toot on mastodon by @ShaunBebbington with a version of this effect in Commodore 64 assembler language. After a few toots back and forth, I managed to shave some bytes off and ended up with this minimal version:
loop: lda #205
lsr $d012
adc #0
jsr $ffd2
bne loop
This takes up 12 bytes of memory and runs a bit faster than the original:
How it works:
lda #205
loads the accumulator with the value 205 (LoaD Accumulator)lsr $d012
does a Logical Shift Right of the$d012
address. This address is used by the graphics chip (VIC) and contains the y-position of the rasterbeam that is drawing the screen. By doing a shift right of this 8-bit value, the rightmost bit ‘falls off’ and ends up in the special carry flag (C), which is a 1-bit flag that is set when calculations overflow. We’re hoping here that the rightmost bit of$d012
is enough random-looking, so that C now holds a pseudo-random bitadc #0
adds 0 plus the carry bit (C) to the accumulator (ADd with Carry). The accumulator now has value205
or206
, depending on the value of the carry bit.jsr $ffd2
does a Jump to SubRoutine to the kernal routine calledCHROUT
that is hard coded into ROM. It prints out the character corresponding to the value loaded in the accumulator.bne loop
jumps back to the beginning. This should really be ajmp loop
because we want to jump back always, unconditionally. But, we use Branch when Not Equal here because this takes up 2 bytes in memory whilejmp loop
takes up 3. Because we know the condition is always true here, we can get away with this optimization here.