| |
10 PRINT Orthogonal [20 bytes] [2021] |
Credits :
Download :
Look for downloads on external sites:
Pokefinder.org
Production Info Submitted by Frostbyte on 13 December 2021
-------------------------------------------------------------------------------
10 PRINT MAZE, ORTHOGONAL VERSION
-------------------------------------------------------------------------------
Size of executable: 20 bytes (29 bytes with sound)
Author: Frostbyte of Artline Designs
-------------------------------------------------------------------------------
This little sizecoding attempt was inspired by Logiker's 32 byte BASIC oneliner
that generates a pretty cool looking maze using six PETSCII chars:
0 ?mid$("123456",rnd(.)*6+1,1);:goto
(where '123456' are the six different chars to use)
I was curious about implementing the same in assembler, and how many bytes it'd
take at its smallest... Smallest I can achieve, that is. After a good amount of
research, and plenty of trial and error, this is what I came up with.
- The program overwrites part of the kernal's CHRGET routine that resides on
zero page at $73. This means that the program executes without a SYS command
by just pressing Return after load, and thus has just 2 bytes overhead instead
of the usual 14 bytes.
- After loading the program, when user presses Return, the CHRGET routine is
invoked at $73. When running the version without sound, a few CHRGET routine's
opcodes that we don't care about are executed before we get to $7C where our
infinite maze generating loop resides.
- In order to build the maze, we need to (reasonably) randomly select a char
from the six allowed, print it, and repeat ad infinitum. First we generate a
random(ish) number. This code takes 8 bytes.
- Then we grab the lowest 3 bits from the generated number, and use this value
as an index to the char table. As the index can be anything from 0 to 7, for
convenience, our char table is also 8 bytes long instead of 6.
- Now we'd need to have that table to fetch the char code from, but that'd be
another 8 bytes and we can't afford that many. Solution was to make the random
number generating code work double duty: Opcodes and operands are carefully
selected and arranged, so that they also match the character codes of the chars
we want to display. In other words, the char table itself randomly selects the
next char to display. Luckily for us, all of the valid chars are duplicated or
even quadruplicated in the charmap, which allowed us to cherry pick the 8 char
codes that would also work as executable code, and operands that wouldn't
cause a crash as RRA and ISC also modify the memory contents.
- After fetching the char from table, we just call a kernal routine at $ffd2 to
print it out on screen, loop back to the beginning, and rinse and repeat.
- The version with sound is 9 bytes longer and overwrites all but the first
command (INC $7a) of the CHRGET routine. A small caveat is that addresses
$7a and $7b which are in the middle of our program get overwritten when the
program is loaded. However, we take advantage of this - We replace the value in
$7b with '$d4', and include the aforementioned INC $7a into our loop, thus we
now have self modifying code that points to all SID registers.
With some experimentation,
ror $d4NN,x (where NN is incrementing and X is the previous table index)
sta ($7a),y (where A is the previous charcode and Y is $d4)
seemed to produce some rhythm as well as varying sounds that were not terribly
off-key, maybe even a bit melodic... in a slightly random way, of course. :)
References and resources:
- Logiker's 10 PRINT orthogonal [32 bytes]: 10 PRINT orthogonal [32 bytes]
- Groepaz's most excellent "No More Secrets" booklet about unintended opcodes:
No More Secrets V0.95
- Sizecoding tips about autostart etc.:
http://www.sizecoding.org/wiki/6502_based_CPUs#Autostart
- Info about CHRGET routine: https://www.c64-wiki.com/wiki/115-138
- PETSCII codes: https://sta.c64.org/cbm64pet.html
- C64 memory map: http://sta.c64.org/cbm64mem.html |
|
|
|
| Search CSDb |
| Navigate | |
|
| Detailed Info | |
|
| Fun Stuff | |
· Goofs · Hidden Parts · Trivia
|
|
| Forum | |
|
| Support CSDb | |
|
| |
|