Fix video generation; Fix MB/LC reads from mem

This commit is contained in:
tomcw
2025-03-13 21:47:21 +00:00
parent 6477871263
commit 7ed83f5045
6 changed files with 36 additions and 15 deletions

View File

@@ -418,8 +418,8 @@ UINT SY6522::GetOpcodeCyclesForRead(BYTE reg)
bool indx = false;
bool indy = false;
const BYTE opcodeMinus3 = mem[(::regs.pc - 3) & 0xffff];
const BYTE opcodeMinus2 = mem[(::regs.pc - 2) & 0xffff];
const BYTE opcodeMinus3 = ReadByteFromMemory((::regs.pc - 3) & 0xffff);
const BYTE opcodeMinus2 = ReadByteFromMemory((::regs.pc - 2) & 0xffff);
// Check 2-byte opcodes
if (((opcodeMinus2 & 0x0f) == 0x01) && ((opcodeMinus2 & 0x10) == 0x00)) // ora (zp,x), and (zp,x), ..., sbc (zp,x)
@@ -504,8 +504,8 @@ UINT SY6522::GetOpcodeCyclesForWrite(BYTE reg)
bool indx = false;
bool indy = false;
const BYTE opcodeMinus3 = mem[(::regs.pc - 3) & 0xffff];
const BYTE opcodeMinus2 = mem[(::regs.pc - 2) & 0xffff];
const BYTE opcodeMinus3 = ReadByteFromMemory((::regs.pc - 3) & 0xffff);
const BYTE opcodeMinus2 = ReadByteFromMemory((::regs.pc - 2) & 0xffff);
// Check 2-byte opcodes
if (opcodeMinus2 == 0x81) // sta (zp,x)
@@ -577,15 +577,15 @@ UINT SY6522::GetOpcodeCycles(BYTE reg, UINT zpOpcodeCycles, UINT opcodeCycles,
if (zpOpcode)
{
BYTE zp = mem[(::regs.pc - 1) & 0xffff];
BYTE zp = ReadByteFromMemory((::regs.pc - 1) & 0xffff);
if (indx) zp += ::regs.x;
zpAddr16 = (mem[zp] | (mem[(zp + 1) & 0xff] << 8));
zpAddr16 = (ReadByteFromMemory(zp) | (ReadByteFromMemory((zp + 1) & 0xff) << 8));
if (indy) zpAddr16 += ::regs.y;
}
if (opcode)
{
addr16 = mem[(::regs.pc - 2) & 0xffff] | (mem[(::regs.pc - 1) & 0xffff] << 8);
addr16 = ReadByteFromMemory((::regs.pc - 2) & 0xffff) | (ReadByteFromMemory((::regs.pc - 1) & 0xffff) << 8);
if (abs16y) addr16 += ::regs.y;
if (abs16x) addr16 += ::regs.x;
}

View File

@@ -643,6 +643,17 @@ void CpuWrite(USHORT addr, BYTE value, ULONG uExecutedCycles)
Heatmap_WriteByte_With_IO_F8xx(addr, value, uExecutedCycles);
}
BYTE ReadByteFromMemory(uint16_t addr)
{
if (GetIsMemCacheValid())
return mem[addr];
_ASSERT(memshadow[addr >> 8]); // Should never be NULL
if (memshadow[addr >> 8] == NULL) return 0x00;
return *(memshadow[addr >> 8] + (addr & 0xff));
}
//===========================================================================
// Description:

View File

@@ -47,6 +47,7 @@ void CpuLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT version);
BYTE CpuRead(USHORT addr, ULONG uExecutedCycles);
void CpuWrite(USHORT addr, BYTE value, ULONG uExecutedCycles);
BYTE ReadByteFromMemory(uint16_t addr);
enum eCpuType {CPU_UNKNOWN=0, CPU_6502=1, CPU_65C02, CPU_Z80}; // Don't change! Persisted to Registry

View File

@@ -160,13 +160,13 @@ BYTE __stdcall LanguageCardUnit::IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValu
bool LanguageCardUnit::IsOpcodeRMWabs(WORD addr)
{
BYTE param1 = mem[(regs.pc - 2) & 0xffff];
BYTE param2 = mem[(regs.pc - 1) & 0xffff];
BYTE param1 = ReadByteFromMemory((regs.pc - 2) & 0xffff);
BYTE param2 = ReadByteFromMemory((regs.pc - 1) & 0xffff);
if (param1 != (addr & 0xff) || param2 != 0xC0)
return false;
// GH#404, GH#700: INC $C083,X/C08B,X (RMW) to write enable the LC (any 6502/65C02/816)
BYTE opcode = mem[(regs.pc - 3) & 0xffff];
BYTE opcode = ReadByteFromMemory((regs.pc - 3) & 0xffff);
if (opcode == 0xFE && regs.x == 0) // INC abs,x
return true;

View File

@@ -271,6 +271,8 @@ static FILE * g_hMemTempFile = NULL;
BYTE __stdcall IO_Annunciator(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles);
static void FreeMemImage(void);
static bool g_isMemCacheValid = true; // is 'mem' valid
//=============================================================================
// Default memory types on a VM restart
@@ -440,6 +442,11 @@ LPBYTE GetCxRomPeripheral(void)
return pCxRomPeripheral; // Can be NULL if at MODE_LOGO
}
bool GetIsMemCacheValid(void)
{
return g_isMemCacheValid;
}
//=============================================================================
static BYTE __stdcall IORead_C00x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles)
@@ -1303,7 +1310,8 @@ static void UpdatePaging(BOOL initialize)
}
}
const bool alt = IsAppleIIe(GetApple2Type()) && (GetCardMgr().QueryAux() == CT_Empty || GetCardMgr().QueryAux() == CT_80Col);
g_isMemCacheValid = !(IsAppleIIe(GetApple2Type()) && (GetCardMgr().QueryAux() == CT_Empty || GetCardMgr().QueryAux() == CT_80Col));
// if (g_isMemCacheValid)
{
// MOVE MEMORY BACK AND FORTH AS NECESSARY BETWEEN THE SHADOW AREAS AND
// THE MAIN RAM IMAGE TO KEEP BOTH SETS OF MEMORY CONSISTENT WITH THE NEW
@@ -1324,7 +1332,7 @@ static void UpdatePaging(BOOL initialize)
((*(memdirty + loop) & 1) || (loop <= 1)))
{
*(memdirty + loop) &= ~1;
if (!alt) // DEBUG: move this "if" here (from above) so that this "for-loop" is run, and mem gets updated and the debugger (sort of) works!
if (g_isMemCacheValid) // DEBUG: move this "if" here (from above) so that this "for-loop" is run, and mem gets updated and the debugger (sort of) works!
memcpy(oldshadow[loop], mem + (loop << 8), 256);
}
@@ -1520,7 +1528,7 @@ LPBYTE MemGetAuxPtrWithLC(const WORD offset)
LPBYTE MemGetAuxPtr(const WORD offset)
{
LPBYTE lpMem = (memshadow[(offset >> 8)] == (memaux+(offset & 0xFF00)))
LPBYTE lpMem = g_isMemCacheValid && (memshadow[(offset >> 8)] == (memaux+(offset & 0xFF00)))
? mem+offset // Return 'mem' copy if possible, as page could be dirty
: memaux+offset;
@@ -1533,7 +1541,7 @@ LPBYTE MemGetAuxPtr(const WORD offset)
)
)
{
lpMem = (memshadow[(offset >> 8)] == (RWpages[0]+(offset & 0xFF00)))
lpMem = g_isMemCacheValid && (memshadow[(offset >> 8)] == (RWpages[0]+(offset & 0xFF00)))
? mem+offset
: RWpages[0]+offset;
}
@@ -1583,7 +1591,7 @@ LPBYTE MemGetMainPtrWithLC(const WORD offset)
LPBYTE MemGetMainPtr(const WORD offset)
{
return (memshadow[(offset >> 8)] == (memmain + (offset & 0xFF00)))
return g_isMemCacheValid && (memshadow[(offset >> 8)] == (memmain + (offset & 0xFF00)))
? mem + offset // Return 'mem' copy if possible, as page could be dirty
: memmain + offset;
}

View File

@@ -112,3 +112,4 @@ UINT GetRamWorksActiveBank(void);
void SetMemMainLanguageCard(LPBYTE ptr, UINT slot, bool bMemMain=false);
LPBYTE GetCxRomPeripheral(void);
bool GetIsMemCacheValid(void);