TomHarte / CLK

A latency-hating emulator of: the Acorn Electron and Archimedes, Amstrad CPC, Apple II/II+/IIe and early Macintosh, Atari 2600 and ST, ColecoVision, Enterprise 64/128, Commodore Vic-20 and Amiga, MSX 1/2, Oric 1/Atmos, early PC compatibles, Sega Master System, Sinclair ZX80/81 and ZX Spectrum.
MIT License
910 stars 50 forks source link

Apple IIe INTCXROM sometimes remains active after reset #1345

Closed ryandesign closed 4 months ago

ryandesign commented 4 months ago

In the Apple IIe emulation, INTCXROM, the soft switch that causes ROM contents to appear in C100–CFFF instead of slot card memory, is unexpectedly active sometimes after pressing Reset. After this happens, commands that access cards, like PR#6, fail, since e.g. the code at C600 is no longer the disk booting code. I originally reported it as part of a Mockingboard problem in #1339 but the problem exists in older builds of Clock Signal that predate Mockingboard support.

The problem is easy to reproduce with this BASIC test program:

1?PEEK(49173)>127:GOTO1
2POKE49158,0:GOTO1

RUN the program and it repeatedly prints 1 if INTCXROM is active or 0 if it isn't. After a fresh start it should print 0s but if you Reset and RUN again, possibly a few times, it switches to printing 1s. To switch INTCXROM off and try again, you can RUN 2.

This change makes it easy to see when the soft switches are accessed:

diff --git a/Machines/Apple/AppleII/AuxiliaryMemorySwitches.hpp b/Machines/Apple/AppleII/AuxiliaryMemorySwitches.hpp
index 9c2e760ff..0e1d19853 100644
--- a/Machines/Apple/AppleII/AuxiliaryMemorySwitches.hpp
+++ b/Machines/Apple/AppleII/AuxiliaryMemorySwitches.hpp
@@ -106,6 +106,7 @@ template <typename Machine> class AuxiliaryMemorySwitches {

            if(address < 0xc000 || address >= 0xc058) return;

+           fprintf(stderr, "%X%c", address, is_read ? 'R' : 'W');
            switch(address) {
                default: break;

@@ -134,6 +135,7 @@ template <typename Machine> class AuxiliaryMemorySwitches {
                    if(!is_read) {
                        switches_.internal_CX_rom = address & 1;
                        set_card_paging();
+                       fprintf(stderr, " %s", address & 1 ? "    ON" : "OFF");
                    }
                break;

@@ -162,6 +164,7 @@ template <typename Machine> class AuxiliaryMemorySwitches {
                    set_main_paging();
                break;
            }
+           fprintf(stderr, "\n");
        }

        /// Provides part of the IIgs interface.

It looks like BASIC generally keeps INTCXROM switched on (C007W) but switches it off (C006W) briefly when there is a keystroke:

C006W OFF
C007W     ON
C006W OFF
C007W     ON
C006W OFF
C007W     ON
C006W OFF
C007W     ON

and when a newline is printed:

C006W OFF
C007W     ON
C001W
C055W
C054W
C000W
C006W OFF
C007W     ON
C001W
C055W
C054W
C000W

And sometimes when Reset is pressed, it forgets about switching it off:

C006W OFF
C007W     ON
C001W
C055W
C054W
C000W
C056R
C054R
C007W     ON
C001W
C055W
C054W
C000W
C007W     ON
C001W
C055W
C054W
C000W
C001W
C055W
C054W
C000W
C007W     ON
C001W
C055W
C054W
C000W
C007W     ON

Sather's Understanding the Apple IIe, page 5-28, says:

Like all MMU soft switches, INTCXROM, SLOTC3ROM, and INTC8ROM are reset when a system reset is detected.

Is Clock Signal implementing that?

TomHarte commented 4 months ago

No; I think that's unimplemented. As pure oversight. I'll get right onto it.

Thanks for looking into this in such crazy detail!