Each LC/Saturn maintains its own local memmode. Rename global memmode to g_memmode
This commit is contained in:
parent
cffa53aff6
commit
c7335600c4
|
@ -51,7 +51,8 @@ LanguageCardUnit * LanguageCardUnit::create(UINT slot)
|
|||
|
||||
LanguageCardUnit::LanguageCardUnit(SS_CARDTYPE type, UINT slot) :
|
||||
Card(type, slot),
|
||||
m_uLastRamWrite(0)
|
||||
m_uLastRamWrite(0),
|
||||
m_memmode(kMemModeInitialState)
|
||||
{
|
||||
if (type != CT_Saturn128K && m_slot != LanguageCardUnit::kSlot0)
|
||||
ThrowErrorInvalidSlot();
|
||||
|
@ -77,7 +78,7 @@ BYTE __stdcall LanguageCardUnit::IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValu
|
|||
UINT uSlot = ((uAddr & 0xff) >> 4) - 8;
|
||||
LanguageCardUnit* pLC = (LanguageCardUnit*) MemGetSlotParameters(uSlot);
|
||||
|
||||
DWORD memmode = GetMemMode();
|
||||
DWORD memmode = pLC->GetLCMemMode();
|
||||
DWORD lastmemmode = memmode;
|
||||
memmode &= ~(MF_BANK2 | MF_HIGHRAM);
|
||||
|
||||
|
@ -104,7 +105,7 @@ BYTE __stdcall LanguageCardUnit::IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValu
|
|||
}
|
||||
|
||||
pLC->SetLastRamWrite( ((uAddr & 1) && !bWrite) ); // UTAIIe:5-23
|
||||
SetMemMode(memmode);
|
||||
pLC->SetLCMemMode(memmode);
|
||||
|
||||
//
|
||||
|
||||
|
@ -115,6 +116,7 @@ BYTE __stdcall LanguageCardUnit::IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValu
|
|||
// WRITE TABLES.
|
||||
if (lastmemmode != memmode)
|
||||
{
|
||||
SetMemMode((GetMemMode() & ~MF_LANGCARD_MASK) | (memmode & MF_LANGCARD_MASK));
|
||||
MemUpdatePaging(0); // Initialize=0
|
||||
}
|
||||
|
||||
|
@ -198,7 +200,7 @@ const std::string& LanguageCardSlot0::GetSnapshotCardName(void)
|
|||
|
||||
void LanguageCardSlot0::SaveLCState(YamlSaveHelper& yamlSaveHelper)
|
||||
{
|
||||
yamlSaveHelper.SaveHexUint32(SS_YAML_KEY_MEMORYMODE, GetMemMode() & (MF_WRITERAM|MF_HIGHRAM|MF_BANK2));
|
||||
yamlSaveHelper.SaveHexUint32(SS_YAML_KEY_MEMORYMODE, GetMemMode() & MF_LANGCARD_MASK);
|
||||
yamlSaveHelper.SaveUint(SS_YAML_KEY_LASTRAMWRITE, GetLastRamWrite() ? 1 : 0);
|
||||
}
|
||||
|
||||
|
@ -354,7 +356,7 @@ BYTE __stdcall Saturn128K::IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULO
|
|||
}
|
||||
else
|
||||
{
|
||||
memmode = GetMemMode();
|
||||
memmode = pLC->GetLCMemMode();
|
||||
lastmemmode = memmode;
|
||||
memmode &= ~(MF_BANK2 | MF_HIGHRAM);
|
||||
|
||||
|
@ -370,15 +372,18 @@ BYTE __stdcall Saturn128K::IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULO
|
|||
memmode &= ~MF_WRITERAM;
|
||||
|
||||
pLC->SetLastRamWrite(uAddr & 1); // Saturn differs from Apple's 16K LC: any access (LC is read-only)
|
||||
SetMemMode(memmode);
|
||||
pLC->SetLCMemMode(memmode);
|
||||
}
|
||||
|
||||
// NB. Unlike LC, no need to check if next opcode is STA $C002-5, as Saturn is not for //e
|
||||
// NB. Saturn can be put in any slot but MemOptimizeForModeChanging() currently only supports LC in slot 0.
|
||||
// . This optimization (check if next opcode is STA $C002-5) isn't essential, so skip it for now.
|
||||
|
||||
// IF THE MEMORY PAGING MODE HAS CHANGED, UPDATE OUR MEMORY IMAGES AND
|
||||
// WRITE TABLES.
|
||||
if ((lastmemmode != memmode) || bBankChanged)
|
||||
{
|
||||
if (lastmemmode != memmode)
|
||||
SetMemMode((GetMemMode() & ~MF_LANGCARD_MASK) | (memmode & MF_LANGCARD_MASK));
|
||||
MemUpdatePaging(0); // Initialize=0
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ public:
|
|||
|
||||
BOOL GetLastRamWrite(void) { return m_uLastRamWrite; }
|
||||
void SetLastRamWrite(BOOL count) { m_uLastRamWrite = count; }
|
||||
UINT GetLCMemMode(void) { return m_memmode; }
|
||||
void SetLCMemMode(UINT memmode) { m_memmode = memmode; }
|
||||
SS_CARDTYPE GetMemoryType(void) { return QueryType(); }
|
||||
bool IsOpcodeRMWabs(WORD addr);
|
||||
|
||||
|
@ -39,6 +41,7 @@ protected:
|
|||
|
||||
private:
|
||||
UINT m_uLastRamWrite;
|
||||
UINT m_memmode;
|
||||
};
|
||||
|
||||
//
|
||||
|
|
|
@ -76,20 +76,20 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
// . Sather uses INTCXROM instead of SLOTCXROM' (used by the Apple//e Tech Ref Manual), so keep to this
|
||||
// convention too since UTAIIe is the reference for most of the logic that we implement in the emulator.
|
||||
|
||||
#define SW_80STORE (memmode & MF_80STORE)
|
||||
#define SW_ALTZP (memmode & MF_ALTZP)
|
||||
#define SW_AUXREAD (memmode & MF_AUXREAD)
|
||||
#define SW_AUXWRITE (memmode & MF_AUXWRITE)
|
||||
#define SW_BANK2 (memmode & MF_BANK2)
|
||||
#define SW_HIGHRAM (memmode & MF_HIGHRAM)
|
||||
#define SW_HIRES (memmode & MF_HIRES)
|
||||
#define SW_PAGE2 (memmode & MF_PAGE2)
|
||||
#define SW_SLOTC3ROM (memmode & MF_SLOTC3ROM)
|
||||
#define SW_INTCXROM (memmode & MF_INTCXROM)
|
||||
#define SW_WRITERAM (memmode & MF_WRITERAM)
|
||||
#define SW_IOUDIS (memmode & MF_IOUDIS)
|
||||
#define SW_ALTROM0 (memmode & MF_ALTROM0) // For Copam Base64A
|
||||
#define SW_ALTROM1 (memmode & MF_ALTROM1) // For Copam Base64A
|
||||
#define SW_80STORE (g_memmode & MF_80STORE)
|
||||
#define SW_ALTZP (g_memmode & MF_ALTZP)
|
||||
#define SW_AUXREAD (g_memmode & MF_AUXREAD)
|
||||
#define SW_AUXWRITE (g_memmode & MF_AUXWRITE)
|
||||
#define SW_BANK2 (g_memmode & MF_BANK2)
|
||||
#define SW_HIGHRAM (g_memmode & MF_HIGHRAM)
|
||||
#define SW_HIRES (g_memmode & MF_HIRES)
|
||||
#define SW_PAGE2 (g_memmode & MF_PAGE2)
|
||||
#define SW_SLOTC3ROM (g_memmode & MF_SLOTC3ROM)
|
||||
#define SW_INTCXROM (g_memmode & MF_INTCXROM)
|
||||
#define SW_WRITERAM (g_memmode & MF_WRITERAM)
|
||||
#define SW_IOUDIS (g_memmode & MF_IOUDIS)
|
||||
#define SW_ALTROM0 (g_memmode & MF_ALTROM0) // For Copam Base64A
|
||||
#define SW_ALTROM1 (g_memmode & MF_ALTROM1) // For Copam Base64A
|
||||
|
||||
/*
|
||||
MEMORY MANAGEMENT SOFT SWITCHES
|
||||
|
@ -224,7 +224,7 @@ static LPBYTE pCxRomPeripheral = NULL;
|
|||
|
||||
static LPBYTE g_pMemMainLanguageCard = NULL;
|
||||
|
||||
static DWORD memmode = LanguageCardUnit::kMemModeInitialState;
|
||||
static DWORD g_memmode = LanguageCardUnit::kMemModeInitialState;
|
||||
static BOOL modechanging = 0; // An Optimisation: means delay calling UpdatePaging() for 1 instruction
|
||||
|
||||
static UINT memrompages = 1;
|
||||
|
@ -650,12 +650,12 @@ static BYTE __stdcall IOWrite_C07x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULON
|
|||
case 0xC: return IO_Null(pc, addr, bWrite, d, nExecutedCycles);
|
||||
case 0xD: return IO_Null(pc, addr, bWrite, d, nExecutedCycles);
|
||||
case 0xE: if (IS_APPLE2C())
|
||||
SetMemMode(memmode | MF_IOUDIS); // On: disable IOU access for addresses $C058 to $C05F; enable access to DHIRES switch
|
||||
SetMemMode(g_memmode | MF_IOUDIS); // On: disable IOU access for addresses $C058 to $C05F; enable access to DHIRES switch
|
||||
else
|
||||
return IO_Null(pc, addr, bWrite, d, nExecutedCycles);
|
||||
break;
|
||||
case 0xF: if (IS_APPLE2C())
|
||||
SetMemMode(memmode & ~MF_IOUDIS); // Off: enable IOU access for addresses $C058 to $C05F; disable access to DHIRES switch
|
||||
SetMemMode(g_memmode & ~MF_IOUDIS); // Off: enable IOU access for addresses $C058 to $C05F; disable access to DHIRES switch
|
||||
else
|
||||
return IO_Null(pc, addr, bWrite, d, nExecutedCycles);
|
||||
break;
|
||||
|
@ -1080,14 +1080,14 @@ static bool IsCardInSlot(UINT slot)
|
|||
|
||||
DWORD GetMemMode(void)
|
||||
{
|
||||
return memmode;
|
||||
return g_memmode;
|
||||
}
|
||||
|
||||
void SetMemMode(DWORD uNewMemMode)
|
||||
{
|
||||
#if defined(_DEBUG) && 0
|
||||
static DWORD dwOldDiff = 0;
|
||||
DWORD dwDiff = memmode ^ uNewMemMode;
|
||||
DWORD dwDiff = g_memmode ^ uNewMemMode;
|
||||
dwDiff &= ~(MF_SLOTC3ROM | MF_INTCXROM);
|
||||
if (dwOldDiff != dwDiff)
|
||||
{
|
||||
|
@ -1122,7 +1122,7 @@ void SetMemMode(DWORD uNewMemMode)
|
|||
OutputDebugString(str.c_str());
|
||||
}
|
||||
#endif
|
||||
memmode = uNewMemMode;
|
||||
g_memmode = uNewMemMode;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -1962,7 +1962,7 @@ void MemReset()
|
|||
mem = memimage;
|
||||
|
||||
// INITIALIZE PAGING, FILLING IN THE 64K MEMORY IMAGE
|
||||
ResetPaging(TRUE); // Initialize=1, init memmode
|
||||
ResetPaging(TRUE); // Initialize=1, init g_memmode
|
||||
MemAnnunciatorReset();
|
||||
|
||||
// INITIALIZE & RESET THE CPU
|
||||
|
@ -2026,7 +2026,7 @@ static void DebugFlip(WORD address, ULONG nExecutedCycles)
|
|||
BYTE __stdcall MemSetPaging(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nExecutedCycles)
|
||||
{
|
||||
address &= 0xFF;
|
||||
DWORD lastmemmode = memmode;
|
||||
DWORD lastmemmode = g_memmode;
|
||||
#if defined(_DEBUG) && defined(DEBUG_FLIP_TIMINGS)
|
||||
DebugFlip(address, nExecutedCycles);
|
||||
#endif
|
||||
|
@ -2036,22 +2036,22 @@ BYTE __stdcall MemSetPaging(WORD programcounter, WORD address, BYTE write, BYTE
|
|||
{
|
||||
switch (address)
|
||||
{
|
||||
case 0x00: SetMemMode(memmode & ~MF_80STORE); break;
|
||||
case 0x01: SetMemMode(memmode | MF_80STORE); break;
|
||||
case 0x02: SetMemMode(memmode & ~MF_AUXREAD); break;
|
||||
case 0x03: SetMemMode(memmode | MF_AUXREAD); break;
|
||||
case 0x04: SetMemMode(memmode & ~MF_AUXWRITE); break;
|
||||
case 0x05: SetMemMode(memmode | MF_AUXWRITE); break;
|
||||
case 0x06: SetMemMode(memmode & ~MF_INTCXROM); break;
|
||||
case 0x07: SetMemMode(memmode | MF_INTCXROM); break;
|
||||
case 0x08: SetMemMode(memmode & ~MF_ALTZP); break;
|
||||
case 0x09: SetMemMode(memmode | MF_ALTZP); break;
|
||||
case 0x0A: SetMemMode(memmode & ~MF_SLOTC3ROM); break;
|
||||
case 0x0B: SetMemMode(memmode | MF_SLOTC3ROM); break;
|
||||
case 0x54: SetMemMode(memmode & ~MF_PAGE2); break;
|
||||
case 0x55: SetMemMode(memmode | MF_PAGE2); break;
|
||||
case 0x56: SetMemMode(memmode & ~MF_HIRES); break;
|
||||
case 0x57: SetMemMode(memmode | MF_HIRES); break;
|
||||
case 0x00: SetMemMode(g_memmode & ~MF_80STORE); break;
|
||||
case 0x01: SetMemMode(g_memmode | MF_80STORE); break;
|
||||
case 0x02: SetMemMode(g_memmode & ~MF_AUXREAD); break;
|
||||
case 0x03: SetMemMode(g_memmode | MF_AUXREAD); break;
|
||||
case 0x04: SetMemMode(g_memmode & ~MF_AUXWRITE); break;
|
||||
case 0x05: SetMemMode(g_memmode | MF_AUXWRITE); break;
|
||||
case 0x06: SetMemMode(g_memmode & ~MF_INTCXROM); break;
|
||||
case 0x07: SetMemMode(g_memmode | MF_INTCXROM); break;
|
||||
case 0x08: SetMemMode(g_memmode & ~MF_ALTZP); break;
|
||||
case 0x09: SetMemMode(g_memmode | MF_ALTZP); break;
|
||||
case 0x0A: SetMemMode(g_memmode & ~MF_SLOTC3ROM); break;
|
||||
case 0x0B: SetMemMode(g_memmode | MF_SLOTC3ROM); break;
|
||||
case 0x54: SetMemMode(g_memmode & ~MF_PAGE2); break;
|
||||
case 0x55: SetMemMode(g_memmode | MF_PAGE2); break;
|
||||
case 0x56: SetMemMode(g_memmode & ~MF_HIRES); break;
|
||||
case 0x57: SetMemMode(g_memmode | MF_HIRES); break;
|
||||
#ifdef RAMWORKS
|
||||
case 0x71: // extended memory aux page number
|
||||
case 0x73: // Ramworks III set aux page number
|
||||
|
@ -2079,10 +2079,10 @@ BYTE __stdcall MemSetPaging(WORD programcounter, WORD address, BYTE write, BYTE
|
|||
{
|
||||
switch (address)
|
||||
{
|
||||
case 0x58: SetMemMode(memmode & ~MF_ALTROM0); break;
|
||||
case 0x59: SetMemMode(memmode | MF_ALTROM0); break;
|
||||
case 0x5A: SetMemMode(memmode & ~MF_ALTROM1); break;
|
||||
case 0x5B: SetMemMode(memmode | MF_ALTROM1); break;
|
||||
case 0x58: SetMemMode(g_memmode & ~MF_ALTROM0); break;
|
||||
case 0x59: SetMemMode(g_memmode | MF_ALTROM0); break;
|
||||
case 0x5A: SetMemMode(g_memmode & ~MF_ALTROM1); break;
|
||||
case 0x5B: SetMemMode(g_memmode | MF_ALTROM1); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2091,10 +2091,10 @@ BYTE __stdcall MemSetPaging(WORD programcounter, WORD address, BYTE write, BYTE
|
|||
|
||||
// IF THE MEMORY PAGING MODE HAS CHANGED, UPDATE OUR MEMORY IMAGES AND
|
||||
// WRITE TABLES.
|
||||
if ((lastmemmode != memmode) || modechanging)
|
||||
if ((lastmemmode != g_memmode) || modechanging)
|
||||
{
|
||||
// NB. Must check MF_SLOTC3ROM too, as IoHandlerCardsIn() depends on both MF_INTCXROM|MF_SLOTC3ROM
|
||||
if ((lastmemmode & (MF_INTCXROM|MF_SLOTC3ROM)) != (memmode & (MF_INTCXROM|MF_SLOTC3ROM)))
|
||||
if ((lastmemmode & (MF_INTCXROM|MF_SLOTC3ROM)) != (g_memmode & (MF_INTCXROM|MF_SLOTC3ROM)))
|
||||
{
|
||||
if (!SW_INTCXROM)
|
||||
{
|
||||
|
@ -2136,6 +2136,9 @@ bool MemOptimizeForModeChanging(WORD programcounter, WORD address)
|
|||
{
|
||||
if (IsAppleIIeOrAbove(GetApple2Type()))
|
||||
{
|
||||
if (programcounter > 0xFFFC) // Prevent out of bounds access!
|
||||
return false;
|
||||
|
||||
// IF THE EMULATED PROGRAM HAS JUST UPDATED THE MEMORY WRITE MODE AND IS
|
||||
// ABOUT TO UPDATE THE MEMORY READ MODE, HOLD OFF ON ANY PROCESSING UNTIL
|
||||
// IT DOES SO.
|
||||
|
@ -2149,6 +2152,8 @@ bool MemOptimizeForModeChanging(WORD programcounter, WORD address)
|
|||
return true;
|
||||
}
|
||||
|
||||
// TODO: support Saturn in any slot.
|
||||
// NB. GH#602 asks for any examples of this happening:
|
||||
if ((address >= 0x80) && (address <= 0x8F) && (programcounter < 0xC000) && // Now: LC
|
||||
(((*(LPDWORD)(mem+programcounter) & 0x00FFFEFF) == 0x00C0048D) || // Next: STA $C004(RAMWRTOFF) or STA $C005(RAMWRTON)
|
||||
((*(LPDWORD)(mem+programcounter) & 0x00FFFEFF) == 0x00C0028D))) // or STA $C002(RAMRDOFF) or STA $C003(RAMRDON)
|
||||
|
@ -2178,7 +2183,7 @@ void MemAnnunciatorReset(void)
|
|||
|
||||
if (IsCopamBase64A(GetApple2Type()))
|
||||
{
|
||||
SetMemMode(memmode & ~(MF_ALTROM0|MF_ALTROM1));
|
||||
SetMemMode(g_memmode & ~(MF_ALTROM0|MF_ALTROM1));
|
||||
UpdatePaging(FALSE); // Initialize=FALSE
|
||||
}
|
||||
}
|
||||
|
@ -2286,7 +2291,7 @@ void MemSaveSnapshot(YamlSaveHelper& yamlSaveHelper)
|
|||
// Scope so that "Memory" & "Main Memory" are at same indent level
|
||||
{
|
||||
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", MemGetSnapshotStructName().c_str());
|
||||
DWORD saveMemMode = memmode;
|
||||
DWORD saveMemMode = g_memmode;
|
||||
if (IsApple2PlusOrClone(GetApple2Type()))
|
||||
saveMemMode &= ~MF_LANGCARD_MASK; // For II,II+: clear LC bits - set later by slot-0 LC or Saturn
|
||||
yamlSaveHelper.SaveHexUint32(SS_YAML_KEY_MEMORYMODE, saveMemMode);
|
||||
|
|
Loading…
Reference in New Issue