Apple II "DSR Scroll" 256B Demo


Presented at Outline 2022 Demoparty

By -=DEsIRE=-: code by deater

Should run on any Apple II+/IIe/IIc


Video

Capture on an actual Apple IIe Platinum.

Sourcecode and Disk Image

You can get the disk image here: dsr_scroll.dsk (140k), 28 May 2022

You can get the submission here: dsrscroll_small.zip (64k), 28 May 2022

You can get the sourcecode here in the demos/outline2022 directory of my dos33fsprogs github repository:
git clone https://github.com/deater/dos33fsprogs/
Vote for this at Pouet

Run-through of the Effects

A lot of things are squeezed into 256 bytes here.

Hi-res Shape Table Wiggle



This is using the Apple II "shape table" support. These are routines in ROM that can draw scalable / rotating vector art. Often this is slow, so in this case we just draw two frames and then use page flipping to flip between them.

Lo-res Scrolling with Overlay



This is in Apple II lo-res mode. A background is scrolled with a bitmap overlay. The code can draw an arbitrary 16x8 black and white bitmap. This desire image was provided by Jade/HMD.

We draw the background, then the overlay off screen then use page flipping. This avoids most of the flicker/tearing.

The colors look random, we didn't have room to fit a nice geometric pattern. For the random color values we just grab data from the ROM. We start at address $F800 and we increment the top byte each note.

The lo-res display is interleaved in weird ways (thanks, Woz!). We take advantage of this and only write out 8 lines, each 128 bytes long. These get wrapped with the interleave, and is why there's a slight triangular pattern to the backgrounds.

For the horizontal scrolling we just increment the lookup by 1 byte each beat. For vertical scrolling we increment by 8 bytes. The area scrolled I think is a 32x8 chunk (dating to when I had a custom pattern to scroll) but it was long enough ago I don't actually remember how the code works anymore. I'll update this once I go back and figure it out.

Text Scrolling



On Apple II the lo-res and text modes use the same RAM, you just have to hit a soft-switch to flip between the two. So it's an easy effect to get.

More Patterns



Originally I started lower in ROM which just gave varying patterns. However I left things run a while and get some more more interesting effects when the pointer wrapped around and to the bottom of memory where RAM lives.

Since this is RAM, the effect you get depends on RAM contents. I tried various offsets and settled as this one being nice, though there are some odd screens.

The weird scrolling small lines is $0200 where the BASIC input buffer lives. The above weirdness is when it gets to $0400 which is the lo-res page1, so it's getting weird feedback where it's reading/writing values at the same time.

We briefly get back to random patterns again at $0C00, that's because it's using the running program code as input here. If you look carefully some of the values change a bit, which is the self-modifying code being used.

Some of the pages are all black or all white. This is how the RAM chips in my actual Apple IIe platinum initialize at boot (it seems to alternate one page all 1s, next all 0s). On a II+ or emulator instead you get much more interesting looking stripe effects, as those assume your RAM initializes to alternating $00/$FF pattern.

Sound Effects

I had maybe 32 bytes to work with and was trying to get some sound. Not enough room for Mockingboard, so trying to use the built in Apple II speaker. This is a challenge, you can toggle a click on the speaker by accessing $C030, but there's no timers, no interrupts, you have to cycle count yourself.

There's an obscure game for the Apple II called Pollywog by Alan Wootton that I think has a very nice sound to it. So I was trying to get something similar going. I didn't really have enough room to really get the frequencies right, and I'm using the WAIT monitor routine for timing which doesn't have the best granularity. Sound could be worse, but I was hoping for something a bit better.

Other Notes

You might say, isn't this demo just a 64-byte and a 128-byte demo merged together with a few extra effects? The answer is sort of. It turns out it can be hard to have a multi-effect demo because you have to add some sort of counter to track which effect you are in, and then switch at the right time. This takes more code than you think. It also limits the demo a bit, I'd have preferred if the hi-res and text-mode sections lasted less time, but it took a lot less code to have each effect last 64 frames (which had the nice effect that you cycle back to the beginning automatically when you have an 8-bit overflow at 256).

Also, the Apple II lets you load binaries anywhere in memory. So for my smaller (128B and smaller) demos I often load them into the zero page. On 6502 processors the zero page is the first 256 bytes of memory, and memory accesses to this region are smaller (2 bytes rather than 3 bytes). Loading a demo there can often save 5-10 bytes depending on what you're doing, as it makes data loads and self-modifying stores shorter.

For this demo I couldn't really fit things in the zero page. For one usually you can't load too low in memory or you'll overwrite the zero page addresses needed by the DOS that's loading your program. You can have your program just overflow into page 1 (the stack) as the stack grows down so the low addresses are usually fine to use (and you can also be really sneaky and have your data in the stack and use push/pull PHA/PLA for single-byte memory reads, see my Comet Song Demo that does this).

For this particular demo I didn't try to fit in zero page because I use the BASIC shapetable routines, which use a bunch of zero page addresses in the $D0-EF range, which means it's hard to load a 256-byte demo in any useful range. If I was really clever I might have found a way around this as those addresses are only used in the init code of the demo, but in the end it was simpler to just load our demo at $C00 and take the hit for not being able to fit in the zero page.

Outline helps here, as the rules let you not count header bytes. On Apple II DOS3.3 the binaries have a 4-byte header that most normal filseystems would have in the fs metadata (file size and load address). So we have an extra 4 bytes to use here that we wouldn't have had for a lovebyte submission. This is why in the CATALOG on the loading screen it lists the filesize as three 256-byte blocks (256 + 4 byte header takes two blocks to hold, the third block is the disk metadata (sector list), on DOS3.3 this gets charged against your filesize in the file listing).
Back to my Demos