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