Lovebyte 2022 Apple II sizecoded Demos
Background
Lovebyte is a demoparty aimed directly
at sizecoding! Just like last year
I entered many Apple II demos.
I also entered a few Raspberry Pi/ARM/Linux demos which you can
find here as well as a bare-metal
Raspberry Pi bootsector demo which you can see
here.
Presentations
This year I took part in the "Ask Us Anything" segment
(part1)
Source Code
The full source code for all of these entries is available on my
dos33fsprogs
github project under the demos/lovebyte2022 directory.
The Entries
Oldschool 512B Bootsector -- Flyer
This one is almost like a video game, flying your ship across a retro-80s
landscape. The graphics take about half the space, the other half is
a stripped down Mockingboard player with music by MA2E.
The graphics are done using calls into the Apple II ROM. The gateways
and ship are shape tables drawn with XDRAW. (you may notice the
gateways are just the ship shape scaled up).
The frame rate is quite slow, there are many potential ways to speed things
up but none of them are easy to do it only 256 bytes.
It does do page flipping to avoid flicker.
Since the code is xor-ing the shapes to the screen, we can do the
invert-the-background trick with minimal extra code, but it was hard
to synchronize that to the music as the frame rate is much slower than
the music player.
The sound takes some shortcuts too. It assumes a Mockingboard in Slot#4
and only plays sound out of the left audio channel to save space.
The player is optimized for the specific song.
This one is a boot-sector demo. You might say, aren't Apple II boot-sectors
256 bytes? Yes they are, but you can specify in the first byte how many
sectors to load, so we specify two (though note, disk sectors are interleaved,
so you don't just write the second sector immediately following the first,
but actually at offset 7).
On Apple II machines a boot sector
program is loaded at $800, the first byte is how many sectors, and then
the loader (which fits entirely in 256B of ROM on the diskII controller
card!) jumps to $801 to start executing.
Typically the first thing you do is spend 3 bytes of code
turning off the floppy motor.
As a boot sector, the remaining 140k of the floppy
would be empty, which seems like a waste,
so I used Bzotto's
Picture Disk to add this image to the magnetic flux patterns
(in case you have a disk imager):
Finish: 5/8 512 Byte Oldschool Bootsector
Download: flyer_512.woz.zip
Video: https://youtu.be/MIIBbzcesaU
Sourcecode: flyer.s
Pouet:
https://www.pouet.net/prod.php?which=90947
Oldschool 256B -- Comet Song
I wanted to see if I could get a Mockingboard tune in a 256B demo.
FrenchTouch had already done this at Revision last year,
but their visualization was text-mode and I wanted to have graphics.
I managed to fit with 5 bytes to spare, but then with the help of
Qkumba freed up enough room for the flying comet visualization.
The code is actually loading half in the zero page, half in the stack.
This not only lets us use short memory accesses in the ZP, but we load things
so the music data ends up starting at $100 (the fixed stack location on 6502)
and since we carefully write the program to not otherwise
use the stack at all, we can point the stack pointer at the music
and use the 1-byte "PLA" (pull into accumulator)
to very compactly and efficiently walk through the data.
One of Qkumba's optimizations was to notice that the ay-3-8910 register
data we were skipping over at the start of the program actually
translated to valid and harmless 6502 code,
so we start out excuting the data rather
thank jumping past it to save a few bytes.
The music is another tune from MA2E that I probably squished out of
all recognition to fit. The player is optimized to play this particular
song. Interrupts/timers are not used at all, we depend on the graphics to be
simple/fast enough and just WAIT to get roughly a 20Hz update to
the Mockingboard registers. Again we assume the Mockingboard is in slot#4
and only write to the left speaker.
Finish: 24/32 256 Byte Oldschool Intro
Download: cometsong.dsk
Video: https://youtu.be/UeyCurR2J3c
Sourcecode: cometsong.s
Pouet: https://www.pouet.net/prod.php?which=91014
Oldschool 256B -- Orb
This one is really three effects, one that's 128B and two that are roughly
64B. You might think you could save some overhead by combining them, but
in reality they don't share much more than the HGR2 call.
The first effect is "Orb" which makes a neat pattern then has a growing
multi-colored circle. I came across this by accident when trying to write
compact Bresenham circles for hi-res Myst. The initial pattern you get
when you draw a circle of radius 0. The weird colors in the growing
circles are what happens if you set HCOLORs beyond the 7 that Applesoft
allows (basically it indexes into code beyond the color table
and uses the bit patterns as colors).
The second effect is a shimmery effect. The occasional static line
is actually again indexing out of bounds. Accidental but I left it
in because I thought it added character.
The final effect is endless colorful rectangles. This again was something
buggy I found working on hi-res Myst. It's decoding 5 bytes as descriptions
of how to draw squares, but instead of reading intentional data, it's using
random data from the Applesoft ROM.
Finish: 30/32 256 Byte Oldschool Intro
Download: orb.dsk
Video: https://youtu.be/Ag9W-0QQwVo
Sourcecode: orb.s
Pouet: https://www.pouet.net/prod.php?which=91019
Oldschool 128B -- Stargate
Flashing light warning.
This one was a buggy result when trying to get some lo-res tunnel
drawing code working. This was possibly my favorite entry for
Lovebyte, a shame it didn't place better. I tried adding some sound
too but wasn't able to get anything that sounded decent.
(On Apple II to click the built-in speaker it takes 3 bytes to
toggle a memory location. You can get music/sound of a sort if you
cycle count things [a stock Apple II has no timers] but it's really hard to
get anything more than clicks or static when size coding).
Finish: 11/18 128 Byte Oldschool Intro
Video: https://youtu.be/iCv3TVaH2_0
Download: stargate.dsk
Sourcecode: stargate.s
Pouet:
https://www.pouet.net/prod.php?which=90943
Oldschool 128B -- Rotate
This came out of a bug found when working on the "Thick Sine" demo. I was
trying to save space by not setting the carry, and it led to the rippling
effect. I realized I could use this plus page flipping to get sort
of a log rotating effect. There was also enough room to click the speaker
a bit.
Finish: 17/18 Oldschool 128 byte intro
Download: rotate.dsk
Video: https://youtu.be/611oYQnZYE8
Sourcecode: rotate.s
Pouet:
https://www.pouet.net/prod.php?which=90942
64B Intro -- dsr64
Using Apple II shape tables / XDRAW to rotate and scale the Desire logo.
It also manages to page flip to avoid flicker. The compact
page flipping code
is in my mind more impressive than the scaled/rotating vector art.
I do lean heavily on these shape table effects in demos because
you can get some impressive effects
in small size, and scaled vector graphics (in software) are one of
the few things the Apple II can do better than other 8-bit machines.
Finish: 4/18 Oldschool 64-byte Intro
Video: https://youtu.be/EYER9QaD_f0
Download: dsr_64.dsk
Sourcecode: dsr.s
Pouet:
https://www.pouet.net/prod.php?which=90924
64B Intro -- Thick Sine
Another effect I came across when trying to do something else, in this
case I was trying to draw circles. The big challenge here was getting
a sine lookup table in a space this small. The Applesoft ROM actually
has a cosine table of sorts built in (for use in the shapetable stuff)
but it's missing a term. That's why there's a gap in the middle of the
sine. It's possible to fix this with another couple of bytes, but I couldn't
figure out how to do that and get it to fit under 64B.
Finish: 14/18 Oldschool 64-byte Intro
Video: https://youtu.be/pODGwGvOT4g
Download: thick_sine.dsk
Sourcecode: thick_sine.s
Pouet: https://www.pouet.net/prod.php?which=90919
32B Intro -- Fuzzball
This one is actually only 29 bytes and I could probably shave
a few more bytes off if I set my mind to it.
This is another hi-res shape table thing. Again found by accident.
It's walking throuh RAM/ROM a page at a time
and using what it finds as a shapetable, rotating by (360/64)
degrees each step.
Because it's hitting uninitialized RAM, the actual effect you get varies
on what kind of RAM you have in your Apple II or emulator.
A simple speaker click in the main loop makes for surprisingly nice
sound effects.
Finish: 4/18 Oldschool 32-byte Intro
Download: fuzzball_32.dsk
Video: https://youtu.be/_87rEku8fWo
Sourcecode: fuzzball.s
Pouet:
https://www.pouet.net/prod.php?which=90997
Quick run on your own Apple II or emulator:
CALL -151
E7: 20 D8 F3 C8 84 E7 A0 00 A2 8C A9 60 20 11 F4 2C
F7: 30 C0 A9 00 A8 20 5D F6 E6 FA 4C ED 00
E7G
16B Intro -- Xdraw Wave
Found this while once again searching the Applesoft ROM for a pattern
that would make a good shape-table effect. Rotated this time,
and it ended up making a nice purple/green effect with the composite
artifacts.
The code loads at address $E7 in the zero page, which seems like an odd
choice. This is because $E7 is where the ROM looks for the HGR_SCALE
value for how big to scale the shapes. By starting our code there
that starts with JSR ($20) it sets up the scale to be 32 without us
having to do a separate load/store instruction.
Finish: 8/17 16B Oldschool Intro
Download: xdraw_wave_16.dsk
Video: https://youtu.be/V0ThN3SRsQc
Sourcecode: xdraw_wave.s
Pouet: https://www.pouet.net/prod.php?which=90973
Quick run on your own Apple II or emulator:
CALL -151
E7: 20 D8 F3 AA 20 11 F4 A0 F0 A9 05 20 5D F6 F0 F7
E7G
16B Intro Showcase -- Xdraw Diamond
Another xdraw/shapetable effect. I found this one by accident
while trying to save space by making the rotate value be the same
as the hi/low address location for the shape table. I actually like
this better than the xdraw_wave submission but I had already submitted
that one, which is why we ended up with two similar submissions to
this competition.
Finish: 6/17 16B Oldschool Intro
Download: diamond_xdraw16.dsk
Video: https://youtu.be/qPm7fMMr8Nk
Sourcecode: diamond_xdraw.s
Pouet: https://www.pouet.net/prod.php?which=90972
Quick run on your own Apple II or emulator:
CALL -151
E7: 20 D8 F3 AA 20 11 F4 A9 E7 AA A8 20 5D F6 F0 F7
E7G
8B Intro Showcase -- Tiny Gr
I finally managed an 8B demo that does graphics! This is tricky on the
Apple II because setting graphics mode takes 3 bytes, and a loop takes at
least 2 bytes, which only would leave 3 bytes for the effect. I was
stuck on this for a while, but then I discovered on systems with Applesoft
in ROM (which is the majority of Apple IIs you'll come across),
at boot the token parsing code is copied to the zero page
at address $B1. If you drop your code into the middle of this, you can
re-use some of the loop code for free.
In our case, the original loop is incrementing a memory location, loading
the value there, doing
some stuff, and branching conditionally. We drop in the middle, change
the address of the memory access to be further along in RAM (to make
it get to the exciting part within the minute deadline), switch to
graphics mode, call the character-out routine (which in graphics mode
prints/scrolls lo-res graphics) and finally we change the conditional
branch to check the overflow flag (which isn't being set, so in
effect making it a BRANCH ALWAYS branch).
What this is doing is just reading bytes from RAM and printing them, so
the effect will vary based on the RAM in your system. I actually
find this recording (on an Apple IIe Platinum) to be a lot more boring
than what you get on a II+ which has more stripes. It plays some sound
as it hits BEL characters, and then once it hits the $C000 I/O region
it clicks through the SPEAKER area, switches to hi-res mode, and then
finally crashes.
Finish: 8B showcase, no voting
Download: tiny_gr8.dsk
Video: https://www.youtube.com/watch?v=otYrCb8MU2s
Sourcecode: tiny_gr.s
Pouet: https://www.pouet.net/prod.php?which=90979
Quick run on your own Apple II or emulator:
CALL -151
B9: 78 2C 50 C0 20 F0 FD 50
B9G
See my Lovebyte 2022 entries for the Rapberry Pi platform
Back to my Demos
See my Apple II projects
See my writeups on my Apple II twitterbot demos