diff --git a/source/CPU.cpp b/source/CPU.cpp index eb32b7ba..9a3e3368 100644 --- a/source/CPU.cpp +++ b/source/CPU.cpp @@ -441,11 +441,20 @@ static __forceinline void IRQ(ULONG& uExecutedCycles, BOOL& flagc, BOOL& flagn, //=========================================================================== -#define READ _READ -#define WRITE(value) _WRITE(value) +#define READ _READ_WITH_IO_F8xx +#define WRITE(value) _WRITE_WITH_IO_F8xx(value) #define HEATMAP_X(address) #include "CPU/cpu6502.h" // MOS 6502 + +#undef READ +#undef WRITE + +//------- + +#define READ _READ +#define WRITE(value) _WRITE(value) + #include "CPU/cpu65C02.h" // WDC 65C02 #undef READ @@ -454,8 +463,8 @@ static __forceinline void IRQ(ULONG& uExecutedCycles, BOOL& flagc, BOOL& flagn, //----------------- -#define READ Heatmap_ReadByte(addr, uExecutedCycles) -#define WRITE(value) Heatmap_WriteByte(addr, value, uExecutedCycles); +#define READ Heatmap_ReadByte_With_IO_F8xx(addr, uExecutedCycles) +#define WRITE(value) Heatmap_WriteByte_With_IO_F8xx(addr, value, uExecutedCycles); #define HEATMAP_X(address) Heatmap_X(address) @@ -465,6 +474,14 @@ static __forceinline void IRQ(ULONG& uExecutedCycles, BOOL& flagc, BOOL& flagn, #include "CPU/cpu6502.h" // MOS 6502 #undef Cpu6502 +#undef READ +#undef WRITE + +//------- + +#define READ Heatmap_ReadByte(addr, uExecutedCycles) +#define WRITE(value) Heatmap_WriteByte(addr, value, uExecutedCycles); + #define Cpu65C02 Cpu65C02_debug #include "CPU/cpu65C02.h" // WDC 65C02 #undef Cpu65C02 @@ -505,10 +522,10 @@ BYTE CpuRead(USHORT addr, ULONG uExecutedCycles) { if (g_nAppMode == MODE_RUNNING) { - return _READ; + return _READ_WITH_IO_F8xx; // Superset of _READ } - return Heatmap_ReadByte(addr, uExecutedCycles); + return Heatmap_ReadByte_With_IO_F8xx(addr, uExecutedCycles); } // Called by z80_WRMEM() @@ -516,11 +533,11 @@ void CpuWrite(USHORT addr, BYTE value, ULONG uExecutedCycles) { if (g_nAppMode == MODE_RUNNING) { - _WRITE(value); + _WRITE_WITH_IO_F8xx(value); // Superset of _WRITE return; } - Heatmap_WriteByte(addr, value, uExecutedCycles); + Heatmap_WriteByte_With_IO_F8xx(addr, value, uExecutedCycles); } //=========================================================================== diff --git a/source/CPU/cpu_general.inl b/source/CPU/cpu_general.inl index f8650099..451ba476 100644 --- a/source/CPU/cpu_general.inl +++ b/source/CPU/cpu_general.inl @@ -54,24 +54,45 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define PUSH(a) *(mem+regs.sp--) = (a); \ if (regs.sp < 0x100) \ regs.sp = 0x1FF; -#define _READ ( \ - ((addr & 0xF000) == 0xC000) \ - ? IORead[(addr>>4) & 0xFF](regs.pc,addr,0,0,uExecutedCycles) \ - : *(mem+addr) \ - ) +#define _READ ( \ + ((addr & 0xF000) == 0xC000) \ + ? IORead[(addr>>4) & 0xFF](regs.pc,addr,0,0,uExecutedCycles) \ + : *(mem+addr) \ + ) +#define _READ_WITH_IO_F8xx ( /* GH#827 */\ + ((addr & 0xF000) == 0xC000) \ + ? IORead[(addr>>4) & 0xFF](regs.pc,addr,0,0,uExecutedCycles) \ + : (addr >= 0xF800) \ + ? IO_F8xx(regs.pc,addr,0,0,uExecutedCycles) \ + : *(mem+addr) \ + ) #define SETNZ(a) { \ flagn = ((a) & 0x80); \ flagz = !((a) & 0xFF); \ } #define SETZ(a) flagz = !((a) & 0xFF); -#define _WRITE(a) { \ - memdirty[addr >> 8] = 0xFF; \ - LPBYTE page = memwrite[addr >> 8]; \ - if (page) \ - *(page+(addr & 0xFF)) = (BYTE)(a); \ - else if ((addr & 0xF000) == 0xC000) \ - IOWrite[(addr>>4) & 0xFF](regs.pc,addr,1,(BYTE)(a),uExecutedCycles); \ - } +#define _WRITE(a) { \ + { \ + memdirty[addr >> 8] = 0xFF; \ + LPBYTE page = memwrite[addr >> 8]; \ + if (page) \ + *(page+(addr & 0xFF)) = (BYTE)(a); \ + else if ((addr & 0xF000) == 0xC000) \ + IOWrite[(addr>>4) & 0xFF](regs.pc,addr,1,(BYTE)(a),uExecutedCycles);\ + } \ + } +#define _WRITE_WITH_IO_F8xx(a) { /* GH#827 */\ + if (addr >= 0xF800) \ + IO_F8xx(regs.pc,addr,1,(BYTE)(a),uExecutedCycles); \ + else { \ + memdirty[addr >> 8] = 0xFF; \ + LPBYTE page = memwrite[addr >> 8]; \ + if (page) \ + *(page+(addr & 0xFF)) = (BYTE)(a); \ + else if ((addr & 0xF000) == 0xC000) \ + IOWrite[(addr>>4) & 0xFF](regs.pc,addr,1,(BYTE)(a),uExecutedCycles);\ + } \ + } #define ON_PAGECROSS_REPLACE_HI_ADDR if ((base ^ addr) >> 8) {addr = (val<<8) | (addr&0xff);} /* GH#282 */ diff --git a/source/CPU/cpu_heatmap.inl b/source/CPU/cpu_heatmap.inl index f8e894bf..8d0a7696 100644 --- a/source/CPU/cpu_heatmap.inl +++ b/source/CPU/cpu_heatmap.inl @@ -53,8 +53,20 @@ inline uint8_t Heatmap_ReadByte(uint16_t addr, int uExecutedCycles) return _READ; } +inline uint8_t Heatmap_ReadByte_With_IO_F8xx(uint16_t addr, int uExecutedCycles) +{ + Heatmap_R(addr); + return _READ_WITH_IO_F8xx; +} + inline void Heatmap_WriteByte(uint16_t addr, uint16_t value, int uExecutedCycles) { Heatmap_W(addr); _WRITE(value); } + +inline void Heatmap_WriteByte_With_IO_F8xx(uint16_t addr, uint16_t value, int uExecutedCycles) +{ + Heatmap_W(addr); + _WRITE_WITH_IO_F8xx(value); +} diff --git a/source/Memory.cpp b/source/Memory.cpp index 0b4f528e..88df89da 100644 --- a/source/Memory.cpp +++ b/source/Memory.cpp @@ -849,17 +849,8 @@ static BYTE __stdcall IO_Cxxx(WORD programcounter, WORD address, BYTE write, BYT // NSC only for //e at internal C3/C8 ROMs, as II/II+ has no internal ROM here! (GH#827) if (!IS_APPLE2 && g_NoSlotClock && IsPotentialNoSlotClockAccess(address)) { - if (!write) - { - int data = 0; - if (g_NoSlotClock->Read(address, data)) - return (BYTE) data; - } - else - { - g_NoSlotClock->Write(address); - return 0; - } + if (g_NoSlotClock->ReadWrite(address, value, write)) + return value; } if (!IS_APPLE2 && SW_INTCXROM) @@ -908,6 +899,30 @@ static BYTE __stdcall IO_Cxxx(WORD programcounter, WORD address, BYTE write, BYT return mem[address]; } +BYTE __stdcall IO_F8xx(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles) // NSC for Apple II/II+ (GH#827) +{ + if (IS_APPLE2 && g_NoSlotClock && !SW_HIGHRAM) + { + if (g_NoSlotClock->ReadWrite(address, value, write)) + return value; + } + + // + + if (!write) + { + return *(mem+address); + } + else + { + memdirty[address >> 8] = 0xFF; + LPBYTE page = memwrite[address >> 8]; + if (page) + *(page+(address & 0xFF)) = value; + return 0; + } +} + //=========================================================================== static struct SlotInfo diff --git a/source/Memory.h b/source/Memory.h index 921d437a..c9a2b783 100644 --- a/source/Memory.h +++ b/source/Memory.h @@ -100,6 +100,8 @@ BYTE __stdcall IO_Null(WORD programcounter, WORD address, BYTE write, BYTE value BYTE __stdcall MemSetPaging(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles); +BYTE __stdcall IO_F8xx(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles); + enum SS_CARDTYPE; void SetExpansionMemType(const SS_CARDTYPE type); SS_CARDTYPE GetCurrentExpansionMemType(void); diff --git a/source/NoSlotClock.cpp b/source/NoSlotClock.cpp index 25a330e2..e78a7718 100644 --- a/source/NoSlotClock.cpp +++ b/source/NoSlotClock.cpp @@ -59,7 +59,20 @@ void CNoSlotClock::Reset() m_bWriteEnabled = true; } -bool CNoSlotClock::Read(int address, int& data) +bool CNoSlotClock::ReadWrite(int address, BYTE& data, BYTE write) +{ + if (!write) + { + return Read(address, data); + } + else + { + Write(address); + return true; + } +} + +bool CNoSlotClock::Read(int address, BYTE& data) { // this may read or write the clock (returns true if data is changed) if (address & 0x04) @@ -74,14 +87,14 @@ bool CNoSlotClock::Read(int address, int& data) void CNoSlotClock::Write(int address) { // this may read or write the clock - int dummy = 0; + BYTE dummy = 0; if (address & 0x04) ClockRead(dummy); else ClockWrite(address); } -bool CNoSlotClock::ClockRead(int& data) +bool CNoSlotClock::ClockRead(BYTE& data) { // for a ROM, A2 high = read, and data out (if any) is on D0 if (!m_bClockRegisterEnabled) @@ -243,7 +256,7 @@ void CNoSlotClock::RingRegister64::WriteBit(int data) m_Register = (data & 0x1) ? (m_Register | m_Mask) : (m_Register & ~m_Mask); } -void CNoSlotClock::RingRegister64::ReadBit(int& data) +void CNoSlotClock::RingRegister64::ReadBit(BYTE& data) { data = (m_Register & m_Mask) ? data | 1 : data & ~1; } diff --git a/source/NoSlotClock.h b/source/NoSlotClock.h index f2f773ad..60969943 100644 --- a/source/NoSlotClock.h +++ b/source/NoSlotClock.h @@ -40,7 +40,7 @@ class CNoSlotClock void WriteNibble(int data); void WriteBits(int data, int count); void WriteBit(int data); - void ReadBit(int& data); + void ReadBit(BYTE& data); bool CompareBit(int data); bool NextBit(); @@ -52,9 +52,8 @@ public: CNoSlotClock(); void Reset(); - bool Read(int address, int& data); - void Write(int address); - bool ClockRead(int& data); + bool ReadWrite(int address, BYTE& data, BYTE write); + bool ClockRead(BYTE& data); void ClockWrite(int address); void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper); @@ -66,6 +65,8 @@ public: RingRegister64 m_ComparisonRegister; private: + bool Read(int address, BYTE& data); + void Write(int address); void PopulateClockRegister(); std::string GetSnapshotStructName(void); diff --git a/test/TestCPU6502/TestCPU6502.cpp b/test/TestCPU6502/TestCPU6502.cpp index 445880d5..acc3c55b 100644 --- a/test/TestCPU6502/TestCPU6502.cpp +++ b/test/TestCPU6502/TestCPU6502.cpp @@ -17,6 +17,11 @@ LPBYTE memdirty = NULL; // TODO: Init iofunction IORead[256] = {0}; // TODO: Init iofunction IOWrite[256] = {0}; // TODO: Init +BYTE __stdcall IO_F8xx(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles) +{ + return 0; +} + // From CPU.cpp #define AF_SIGN 0x80 #define AF_OVERFLOW 0x40 @@ -83,11 +88,20 @@ void NTSC_VideoUpdateCycles( long cycles6502 ) #include "../../source/CPU/cpu_general.inl" #include "../../source/CPU/cpu_instructions.inl" -#define READ _READ -#define WRITE(a) _WRITE(a) +#define READ _READ_WITH_IO_F8xx +#define WRITE(a) _WRITE_WITH_IO_F8xx(a) #define HEATMAP_X(pc) #include "../../source/CPU/cpu6502.h" // MOS 6502 + +#undef READ +#undef WRITE + +//------- + +#define READ _READ +#define WRITE(a) _WRITE(a) + #include "../../source/CPU/cpu65C02.h" // WDC 65C02 #undef READ