Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
  You are not logged in - nap
10 PRINT Orthogonal With Sound [29 bytes]   [2021]

10 PRINT Orthogonal With Sound [29 bytes] Released by :
Artline Designs [web]

Release Date :
13 December 2021

Type :
C64 256b Intro

User rating:awaiting 8 votes (5 left)   See votestatistics

Credits :
Code .... Frostbyte of Artline Designs

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
Advanced
Navigate
Prev - Random - Next
Detailed Info
· Summaries (1)
· User Comments (3)
· Production Notes (1)
Fun Stuff
· Goofs
· Hidden Parts
· Trivia
Forum
· Discuss this release
Support CSDb
Help keep CSDb running:



Funding status:




About this site:
CSDb (Commodore 64 Scene Database) is a website which goal is to gather as much information and material about the scene around the commodore 64 computer - the worlds most popular home computer throughout time. Here you can find almost anything which was ever made for the commodore 64, and more is being added every day. As this website is scene related, you can mostly find demos, music and graphics made by the people who made the scene (the sceners), but you can also find a lot of the old classic games here. Try out the search box in the top right corner, or check out the CSDb main page for the latest additions.
Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.091 sec.