A Version of Future Crew's Second Reality for Apple II





Details

Second Reality, the famous MS-DOS demo, but on an Apple II...

Finished first place in the Retro Demo category at Demosplash 2023


Videos

Video capture from an actual Apple IIe:

System Requirements


Downloads

Disk Images

Source


You can vote for this on pouet (you'll see the crew there aren't big fans): Apple ][ Reality

Mini-faq


Platform Notes

Apple II limitations

I'm sure I have long detailed explanations of the Apple II limitations elsewhere on this site, but a quick refresher. Apple II has a 1MHz 6502 processor. A "base" model can be assumed to have 48k of RAM and 16k of ROM (with a fairly popular bank-switched 16k RAM expansion available, although you can only have 12k of that active at once). Graphics RAM takes up a large chunk of this room, lo-res graphics has two 1k pages but hi-res takes up the whole range from $2000-$5FFF (16k) if you use both pages. A lot of my effects use page flipping so you often need another off-screen buffer (another 8k) only leaving around 16k for actual code.

No hardware graphics acceleration of any sort except page flipping. Graphics are complicated but roughly you have hi-res which is 140x192 in 6 colors (with some color clash) and 40x48 in blocky lo-res with 16 colors. The memory map for the graphics modes is weird and interleaved. The hi-res mode is 3.5 pixels per byte, the high bit picks a palette, and it's NTSC artifact color so lots of other issues. Something as simple as trying to write orange ($AA) to all of the 8k hi-res frame buffer in order will actually give you 40 blue/orange alternating columns that appear in a venetian blind effect, it takes a lot of work to just get a pixel of a color you want on the screen.

Stock Apple II has just a bitbang speaker. To do any sort of interesting music generally requires most of the CPU. This is why most demos run on an optional sound card, in this case a Mockingboard which has a few AY-3-8910 sound chips. This has the added benefit of providing a regular timing interrupt too, something the Apple II doesn't have by default.

Specific Model Support

This currently requires an Apple IIe with 128k. I'm not actually using any advanced IIe features (65c02, double-graphics modes, lowercase, 80-column, etc). I'm mostly using the extra RAM like a ramdisk so I don't have to pause the music to read from disk. I'm hoping to maybe shrink things down so it will run on a 64k system (which would allow running on a II+ with language card)

Disk II note

The Apple Disk II drive is an amazing piece of Woz engineering, but it's controlled with cycle-accurate bitbanging of the hardware. It's essentially a hard real-time task. Having interrupts enabled would make disk accesses fail. There are two groups who've managed to get disk loads happening while playing music: Fast Loader by French Touch with and Low Tech by Imphobia. I should probably look into how they got things to work though I think it's complex.

The disk code I use is by Qkumba. It's super fast. I'm using that with raw disk sector reads, there's no filesystem on the disk (no AppleDOS or ProDOS).

Code Notes

Overall Framework

This is the first demo I've written that was big enough to not all fit in memory at once. I have written Apple II games that needed some sort of overlay-style framework but usually those are more forgiving of pausing at some point for disk loads.

The disk images are booters, there's no OS present. It uses qkumba's qboot boot sector which provides fast disk routines to load consecutive sectors into memory very quickly. Roughly 4k is loaded into the area of $1000-$1FFF which provides the disk loading code, the main framework code, lookup tables (mostly for hi-res row addresses as they are non-consecutive/interlaced), and some common routines.

The music, music player, and the AUX memory copy routines are loaded into the ``language card'' bank switched area at $D000. The built in ROM firmware is swapped out and not used at all during the demo. A custom AUX (high 64k) copy routine is used as the ROM one is slow, and we put it in the language card because we use the ``keep the same stack page and zero-page while AUX mem is active '' mode which for some reason also leaves the language card memory alone when bank switching.

Generally the effects are loaded to $6000 which is above the two hi-res pages. If we need an off-screen copy of graphics while page flipping we'll use $6000-$7FFF for that and load our code at $8000. For lo-res effects you can load lower, down to $2000, which provides a lot more room, and is why the 3d flyover code can be much larger than the other effects.

For this code at least I tried to avoid reading from disk as much as possible, so the high memory was used as a sort of RAMDISK, at the start of the demo a lot of the effects were pre-loaded there, and then copied in while needed. The benefit of this is the music can keep playing while this is happening. As mentioned elsewhere in this page you can't really play music while the disk is being read. I might try to cram things to fit on a 64k Apple II+ but in that case there might be few second pauses when loads happen (the Disk II is much faster than the c64 floppy drive, but even with qkumba's code it takes a noticeable amount of time to load in a few tracks worth of data).

PT3 Music Player

The music is in the Vortex-tracker PT3 format (usually used for ZX-Spectrum music, the Mockingboard I use has the same AY-3-8910 sound chips).

I have a library I made that plays PT3 files on 6502 processors. In the process of making this demo I found a bug (only shows up if you have more than 42 patterns in the sound file). My fix for that bug was flawed and made the credits music crash, which I was debugging late at night right before the deadline.

Finding a PT3 copy of the main theme by z00m is what inspired me to do this whole project. Special thanks to mA2E for making a PT3 version of the into music at the very last minute.

Compression

I make a lot of use of ZX02 compression to make things fit. It's a wonder it all fits on just two 140k floppies (and the second floppy has a lot of spare room).

Effects summary

Fake Bios Why not make an Apple II pretend to be a PC. Nothing that exciting here though adapting an 8-pixel wide font to the 7-pixel wide Apple II was a pain.

It actually is doing some system detection here so the output varies based on your hardware setup.
Intro The pan across the landscape is a 2-pixel horizontal scroll which is really hard to do on Apple II. There's no hardware scrolling. Each byte of hi-res memory is 3.5 pixels, so when scrolling you have to cross byte boundaries. The bits are in LSB (least-significant bit) order but also the top bit doesn't scroll (it's a palette bit) and if you're not careful the colors will swap. It's jerky because I'm not using page-flipping here (that would be even more complex). I'm using lookup tables. Oddly the technique I'm using is based on a writeup I found on my system recently that I had saved off of usenet in 1996 for some reason.

No hardware sprites on the Apple II either. I'm actually just moving chunks of memory here for ths ships and not really doing sprites. I have the y-coord a bit off which makes a bit of a warping effect but I thought it looked cool and left it.
Chessboard There were a lot of better ways I could have done this, but I'm just using sprites to cheat a bit. I didn't have time to hack up a real 3d-render, or even some sort of triangle-drawing library. I made the chessboard orange instead of purple as due to the color palettes things interact better (you can't have purple/green in the same 3.5 pixel chunk of screen as blue/orange). You still see some fringing at the edges, that's because the proper way to do this would be to have a mask to mask off the transparent parts of the sprite but that would make it slower and also use a lot more RAM that what I'm doing which is doing transparency at 3.5 pixel boundaries. Also while you can only have your X-position be on multiples of 3.5 pixels, it does handle automatically shifting the sprite data to make sure the colors still look right for both odd/even columns.
Tunnel I wasted a week trying to get a good tunnel effect and gave up (after some very interesting results ( 1 2 3 4 )) from buggy code. Drawing circles is a pain on 6502. So for this I just took 2 screenshots and page flip. I think this captures best the fast pace of the original.

A lot of tunnel code involves multiply, divide, and trig functions and that all makes a 6502 assembly programmer weep. Though the c64 people pulled it off for their version so I should try to find out how they did it.

Note that the Second Reality effect is a bit more interesting that a plain tunnel as it wiggles the camera around too.
Circles / Interference The circle code and some of the interference code are based on code from Hellmood's famous Memories demo. I should have tried to make actual circular interference patterns but just cheated and used some existing code that gave vaguely similar patterns. As I said before, drawing circles quickly when you don't have multiply or trig functions is a pain. Lookup tables and self-modifying code only get you so far.

I did manage to get sound sync on the falling bars, that was tricky (although depending how you watch the video the sync might not match up for you)
Monster Graphic The graphics are mostly automated conversions. I have been using Kris Kennaway's iipix converter. However it sometimes needs some tweaking and works better on photos than on drawings. In the end I often just reduce images to a low number of colors and then fill manually with dither patterns.

The scroll here is a quick hack, it needed to be fast. It's actually going 7 color pixels at a time as the naive 3.5 approach would make the colors swap each step and I didn't have time to make a version that did things properly.
New Way to Scroll Just two images with page flipping, didn't have time to do this properly.

Not only would I have to somehow map a font texture to a 3d surface, but even just masking off the leaves would be a pain.
Lens/ Rotozoom Done in lo-res for speed. The lens part I meant to do some sort of warping when drawing the transparent sprite. I was going to use colors to specify an offset to get when looking up the warped pixels from the background. As a placeholder I was just anding the colors in, and it actually looked OK as an effect and I never had time to implement things properly.

You might miss it, but the music is paused so that a sound sample can be played out the speaker.

Rotozoom is based on previous rotozoom code I had. Instead of a color border I should wrap, it's just the only fast way to do that is a power-of-two wrap but the Apple II screen is 40x48 and I haven't had time to figure out a good way of managing that. I could easily do 32x32 but getting a smooth transition from 40x48 is tricky.
Plasma I'd been trying for years to get a hi-res plasma going on the Apple II. In the end this is based on French Touch's Plasmagoria plasma code, but converted for hi-res. It only draws ever other line for speed. As far as I know no one has ever done full-screen hi-res plasma on Apple II before.
Plasmacube I think this is my favorite effect. Again the French Touch code, but with my own masking applied. The masks have R/G/B components to apply different color lookups to the underlying plasma. The cubes are pre-rendered. Only 8 steps, but they compress really well. I probably have room for 16 steps but ran out of time.
Bouncing Dots I meant to do something fancier. In the end it looked surprisingly well. It's not doing any of the fancy patterns in the original though, but this is one case I might be able to approximate it with enough lookup tables.

This is a case I've since looked at the actual code (and the modern remake) but everyone uses either OpenGL or the original code is doing deep VGA tricks so it'll be tricky to port over the exact algorithm.
Transmission I had a really nice hi-res version of the background, but couldn't figure out a good way to do the sword in hi-res without a huge amount of work (diagonal sprites, color clash). So in the end I went with lo-res which I think worked out OK. I even got the "transmission" line said there if you listen closely. There's a glitch at the start due to a disk access and I didn't have time to fix it, I should have cleared the screen to black before it happened, in fact I thought I had so not sure why it didn't.
Ocean Voxels Fully cheating on this one. It's just screengrabs hand-colored by me and being decompressed via ZX02 full speed. This takes up 24k which is much larger than most of the other effects.
Polar Lady I wanted to make it bounce, even had various plans for trying to do it (it's not easy, again because of the weird way pixels work on hi-res, you can't just scale them out slightly without weird color effects). In the end I just had to settle for a quick vertical scroll.
3D-scene As you might guess this is not rendered in 3d. It's a bunch of rectangles being drawn really quickly.

I started out optimizing the rectangle lists by hand, this is something I did for a lot of my Apple II bot entries.

Hand optimizing took forever, so I wrote a program that given a lo-res screen will attempt to find optimal rectangle coverage. It's about 10-20 percent worse than by hand, but so much faster. I still take the 4fps screen grabs and convert them to 40x48 with proper lo-res color selection by hand. You'll notice it stops before the actual end, ran out of time. And then it switches to hi-res and sprites for the finale.
Credits Using 4am's font and libs here. The scroll in of the thumbnail is not perfect, didn't have time to scroll it in from off screen properly. The final credits are again a little jerky as I'm not using page flipping.

Development Notes

2 December 2023

I've slowly been working on getting a better version of the DOTS effect. Took the original source, made a minimal Linux/SDL 8086/VGA emulator to make sure I understood what was going on. It's a bit intense for 6502 with 512 dots each with 4 multiplies and 3 divides per dot. Made a pre-recorded version which is decent but much too large. Seeing if I can size-code a decent effect out of things. I'll post my writeup once I get it done.

21 November 2023

Managed to have this project on the front page of both Hacker News and Slashdot. I probably would have been really excited about the Slashdot thing 25 years ago. I was an extremely early follower of Slashdot, back when it was still the "News" section of Rob Malda's personal webpage (I found that because I bought a Linux t-shirt from him off of a posting from comp.os.linux.announce on usenet). For those curious, in the end I got more hits to the video from slashdot than hackernews (you can see the two peaks in this youtube analytics graph):


12 November 2023 -- Release v1.2

Updated to include the full 3d scene in the credits (before stopped 2/3 of the way through as I ran out of time). It just barely fits, I need to see if maybe using ZX02 compression instead would reduce the filesize.

8 November 2023 -- Release v1.1

Released an update, should now work on IIc and IIgs systems. Tested on MAME. On IIgs you'll need to make sure you have a Mockingboard enabled, then press ctrl-cmd-esc and select that you have your own card in Slot 4.

4 November 2023

Up late finding a bug in the music player which was introduced by my fix for large files a few days ago. During the competition their machine crashed due to music issues, hope my code isn't still buggy :(

3 November 2023

After a lot of late nights managed to get something together just before the Demosplash deadline.

29 October 2023

I unwisely have spent the last month or so trying to put together a real version of this for Demosplash, so I guess watch this space.

15 August 2023 -- Release v0.1

I really should be working on other stuff. I stumbled across the AY-3-8910 PT3 music for this by z00m, and then of course needed some visuals.

The graphics were converted using Kris Kennaway's ii-pix program though it was a hassle getting all the python dependencies going.

I had pre-existing rotozoom code. Ideally I'd fix it to wrap at the edges but turns out that'd be a pain.
Other VMW Software Demos
Other Apple II Projects
Back to the VMW Software Productions Page