On 26 Oct 2002, Dosius wrote: > Date: 26 Oct 2002 08:34:47 -0700 > From: Dosius > Newsgroups: comp.emulators.apple2 > Subject: Proper banking mechanism for 128K? > > I have unsuccessfully tried to bump my emulator up to 128K. I can get > up to 112K, but something appears to be wrong with my mechanism for > paging in/out re: the language card space if I go 128. Does anyone > know how this works and can explain in "relatively plain English" ? > Thx. > > -dos. > Well, I hope this is "relatively plain English" (i.e. I hope this is English at all. :-) ) I've tried taking a look into your code (0.87) but could not understand what you are doing. It says: if (Addr<49152) return (byte) RAM[Addr]; This will not run as you neglect a) the 80col store switch, b) the $c008/9 softswitch (Read/Write Main ZP+Bank). I guess you have implemented these things now, however, in your latest release version I haven't found any traces of a $c008/9 softswitch handling. Perhaps you could post your source either to this newsgroup or directly to me. Otherwise it's a bit hard to help you. (In case you plan to emulate the Apple memory by copying the memory banks to and from some memory buffers, be warned! This takes far too much time IMO.) Well, here are some (useful?) explanations: The AppleII(e) memory is divided into lots of memory banks that may be affected by several softswitches. Here is a list: $0000 - $01ff : $c008/$c009 (note: ZP/Stack and LC use the same softswitch!) $0200 - $03ff : $c002/$c003/$c004/$c005 $0400 - $07ff : $c002/$c003/$c004/$c005/$c000/$c001/$c01c $0800 - $1fff : $c002/$c003/$c004/$c005 $2000 - $3fff : $c002/$c003/$c004/$c005/$c000/$c001/$c01c/$c01d $4000 - $bfff : $c002/$c003/$c004/$c005 ... $d000 - $ffff : $c008/$c009/$c08x As a result, it is not enough to return RAM[Addr] if the address is lower than $c000. Instead you have to do a detailed check which memory area you are accessing and which softswitch is affected, which would look like this: if (addr < 0xc000) { if (addr < 0x2000) { if (addr < 0x400) { if (addr < 0x200) { if ((sw[0x16] & 0x80) == 0) { return mem[addr]; } /* main 64 */ else { return mem[addr+0x10000]; } /* aux 64 */ } else { if ((sw[0x13] & 0x80) == 0) { return mem[addr]; } /* main 64 */ else { return mem[addr+0x10000]; } /* aux 64 */ } } else { if (addr < 0x800) { if ((sw[0x18] & 0x80) == 0) { if ((sw[0x13] & 0x80) == 0) { return mem[addr]; } /* main 64 */ else { return mem[addr+0x10000]; } /* aux 64 */ } else { if ((sw[0x1c] & 0x80) == 0) { return mem[addr]; } /* main 64 */ else { return mem[addr+0x10000]; } /* aux 64 */ } } else { if ((sw[0x13] & 0x80) == 0) { return mem[addr]; } /* main 64 */ else { return mem[addr+0x10000]; } /* aux 64 */ } } } else { if (addr < 0x4000) { if ( ((sw[0x18] & 0x80) == 0) || ((sw[0x1d] & 0x80) == 0)) { if ((sw[0x13] & 0x80) == 0) { return mem[addr]; } /* main 64 */ else { return mem[addr+0x10000]; } /* aux 64 */ } else { if ((sw[0x1c] & 0x80) == 0) { return mem[addr]; } /* main 64 */ else { return mem[addr+0x10000]; } /* aux 64 */ } } else { if ((sw[0x13] & 0x80) == 0) { return mem[addr]; } /* main 64 */ else { return mem[addr+0x10000]; } /* aux 64 */ } } } else { /* >= 0xc000 */ if (addr >= 0xd000) { /* LC and Rom */ if ((sw[0x12] & 0x80) == 0) { return mem[addr - 0xc000 + 0x20000]; } else { if ((sw[0x16] & 0x80) == 0) { if ((addr < 0xe000) && ((sw[0x11] & 0x80) == 0)) { return mem[addr - 0x1000]; } else { return mem[addr]; } } else { if ((addr < 0xe000) && ((sw[0x11] & 0x80) == 0)) { return mem[addr + 0x10000 - 0x1000]; } else { return mem[addr + 0x10000]; } } } } else ... $c000 - $cfff The same applies to Wr6502 (naturally :-) ). The code should be self-explaining, and I know it works. ( :-) ) As you can see, the LC is affected by $c008/$c009 and not $c002-$c005. Have you done it this way? If so, please specify your problem. Kind regards Holger