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