Apple II Vapor Lock and the Floating Bus

First, I want to make it clear I didn't invent any of this. It has been well known since the early 80s. You can read more about this in Bob Bishop's 1982 Softalk article "Have an Apple Split" and Don Lancaster's Vapor Lock and Fun with Mixed Fields and Glitch Stomper articles. The technique was really not used that much, probably because it is difficult to use and not really officially supported by Apple.

So a quick bit of background: the Apple II has three display modes. Text (originally 40x24 uppercase only), Lores (40x48 15-color) and Hires (it's complicated, but roughly 280x192 6-color). Each mode has two pages you can switch between, and you can optionally swap in 4 lines of text for the bottom of the graphics modes, but that's it. No sprites, no palette rotation, no user-defined charsets, no scrolling. They aren't even linear framebuffers, they are split up in complex ways for complex Woz-related reasons (apparently it saved 2 chips from the design. Note: This text originally said it had to do with helping with the DRAM refresh, and while there is some other Woz-related funny business going on with getting the DRAM refresh for free, apparently it would be theoretically possible to have a linear framebuffer at the expense of a few more chips). We won't even get into the super-complicated rules of Hires that mean unless you carefully pick the colors in 7-pixel blocks you're going to get weird fringing artifacts.

This all sounds horrible, but remember this is 1977 and the system is made mostly out of discrete 7400 series logic and the fact that there's color available at all sets the Apple apart from most of its competitors at the time.

Anyway, you switch graphics modes on the Apple II by writing to memory-mapped addresses (soft switches). And there's no reason you can't do this at any time. Which gives the possibility of doing some neat effects if you switch between lores/hires mid screen, or switch between lores PAGE1 / lores PAGE2 to effectively double the vertical resolution, etc. Plenty of other 8-bit systems support such fun tricks.

The challenge on the Apple II is that there originally was no way to detect your current screen position. (Much later the IIe/IIc/IIgs added ways to detect this, but these methods were mutually incompatible).

So while the beam was scanning the screen, each of the 192 scanlines takes 65 cycles. 25 HBLANK cycles while the screen is blanked and returning to the left side of the screen, and 40 cycles of drawing. (also to make this work better, the Apple II actually stretches every 65th clock cycle to be extra long, which is an absurdity all to itself). After 192 lines, there are 4550 cycles of VBLANK as the beam returns to the top left.

If we could only find where we were in the scanning process, we could do fun effects by doing precise mode switches at opportune times. And it turns out there is a way, but it's an enormous hack.

We mentioned the Apple II plays some games to get DRAM refresh for free. The 6502 chip only uses memory during half of the 1MHz clock cycle. So on the other half, the video refresh circuitry reads the next value to display. (Woz scattered the memory addressing so these reads hit each DRAM page often enough to do the memory refresh automatically). Due to the capacitance of the "floating-bus" this last read value hangs around, and if you have the 6502 do a read of a write-only memory location (such as a soft switch) it will return that last video circuitry read.

So how does that help you? Well if you draw a known pattern in video memory (or even more clever if you are Lancaster, in the off-screen memory that gets scanned during a blank interval) you can carefully determine where the beam is.

Once you find the beam, you can then carefully cycle-count every instruction from then on out and flip modes at the right time to do your cool split-screen effects. Unlike normal graphics modes though you have to keep cycle counting and flipping things at exactly the same time through each 60Hz screen redraw or else things fall apart. Also, once you lose the lock, you have to recapture it somehow. You can't just poll a register to find when VBLANK starts as you can on some platforms.

Anyway, the code that does this is how the Apple2 Cycle Counting Megademo does its split screen effects.
Back to the megademo page