On the Apple IIgs, the 256K of built-in main memory is divided into two sections: The "fast" RAM, banks 00 and 01, and the "slow" RAM, banks E0 and E1. CPU access to slow RAM required the CPU to slow to the 1MHz speed of the earlier Apple II models. (Later models with 1MB on board are similar, just with more fast RAM).

It's possible to set a soft switch ($C035) to control write shadowing, in which writes to bank 00 and 01 are copied automagically into banks E0 and E1. This allows the CPU to run at full speed while accessing this memory. The primary purpose of this was to allow the CPU to write data into the video buffer, which was in slow RAM, without slowing down.

But my question is how did this work? Obviously, something is copying this data, but how? The FPI cannot write the data to slow RAM itself, as it has no direct connection. Only the Mega II can write to slow RAM.

Based on looking at the schematic, the Mega II chip has access to the slow RAM - but it doesn't have access to the PH2 2.8MHz clock used on the CPU buses when in high speed mode. The FPI, on the other hand, generates the PH2 clock and also can see the CPU buses, but it doesn't connect to the slow RAM, and the only way it seems to be able to pass data to the Mega II is via the main buses which are shared with the CPU.

The FPI and Mega II share only one clock: The 14Mhz clock which was the master clock in older models. At 14MHz, the FPI could shift the address and data to the Mega II one bit at a time and still keep up with the CPU, but there doesn't seem to be any signal line suited for this.

Having the FPI sneak data to the Mega II when the CPU isn't looking turns out to have the same problems as having the Mega II copy the writes in real time.

The other thing I can think of is that the FPI disconnects the CPU from the bus long enough to send this data over to the Mega II. Normally you'd slow to 1MHz to send data to the Mega II this way - which would be unfortunate because it would pretty much defeat the whole point of the write shadowing. This seems unlikely because it seems like it would perform worse than not doing it at all, but maybe they have a way to do it without totally killing performance.

So I am out of ideas. Where's the magic?

  • 1
    Interesting and especially well prepared question. Thank you. AFAIR from my Apple II times, it's like your second asumption. the CPU gets slowed down for one clock. This isn't as bad as it seams, since 'useful' RAM access (i.e. screen writing) is in average less than 10% of all clocks even in the tightest of all loops. Worst case is a 2.5 MHz Apple :) – Raffzahn Jan 22 at 11:22
up vote 16 down vote accepted

That's an interesting and especially well prepared question. Thank you.

AFAIR your second asumption is right. When shadowing is enabled for a region (see below) the CPU gets synchronized and slowed down to 1 MHz during the writing cycle for a clock period.

This isn't as bad as it seams, since 'useful' RAM access (i.e. screen writing) is in average less than 10% of all clocks even in the tightest of all loops (*1). And the whole idea of shadowing is to restrict this slow down to just a single write cycle (on the 1MHz side). Reading the same location (or any other 'on' screen location) in 00/01 again isn't slowed down.

In fact, as long as it's only about writing to a screen region, direct access to E0/E1 for the same purpose isn't any slower at all. The CPU also gets slowed down to 1 MHz only for the access cycle (*2). But in this case, reading would also be slowed down. And with placeing a program in E0/E1 the machine will effectively slowed down to (a tiny bit more than) 1 MHz.

With shadowing, only writes do slow down, while reads are satisfied from fast memory (00/01). It's about squeezeing out the very last bit of speed when slow memory is involved. For all practical purpose the effective speed of a program using slow memory for screen data lingers between 2.0 and 2.8 MHz (*3) depending on the code structure and timing(*2). Shadow memory operation pushes it way toward the upper boundry, making use of slow memory not a real burden (*4).

Shadowing is realy only ment to speed up screen access. For everything else, needed for Apple II compatibility, direct access to E0/E1 is the only way. Schadowing is only available to 6 regions. They are partly overlaping and controlled via bits at E0/C035:

0 - 0400...07FF - Text1
1 - 2000...3FFF - HGR1
2 - 4000...5FFF - HGR2
3 - 2000...9FFF - Super Highres
4 - 2000...3FFF - Double Highres ($01/2000...)
5 - Unused
6 - C000...DFFF - Switches/Slot Memory
7 - Speed indicator

Shadowing will only be done for the region enabled. Thus only data written after the coresponding switch is on will reach E0/E1.

Concluion: Just switch it on and pump your data to the screen using 00/01.

Having said that, there might still be need to improve even upon shadowing. For example more sopisticated games do not just copy data to the screen, but issue more complex operations needing to manipulate data more than once before it is displayed (aka bitbliting) . Also double buffering might be a good idea to use all time for picture generation. Sheppy (*5) has writen a quite awesome answer about how to use shadowing and CPU tricks to implement double buffering and fastest possible screen copy by using the effects of shadow memory.

*1 - Just grab a sheet of paper and count execution cycles according to what the access is and in which region..

*2 - It's a bit more complex, as both memory systems are not simply synchronized in a way that the fast clock is a fraction less multiple of the slow clock. Thus there might be an additional waiting period of up to 4/5 of a 1 MHz cycle to synchronize. In worst case this means almost doubling the penalty. Sheppy mentiones this in another related questions answer.

*3 - Ofc, ignoring the optional stupidity to put code there.

*4 - Don't get fooled by horror stories told by experts. Do as told (*1) with the logic used in mind.

*5 - One of the demi-gods of Apple II programming and still arround.

Your Answer


By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.