mirror of
https://github.com/AppleWin/AppleWin.git
synced 2025-01-01 12:31:59 +00:00
Refactor Language Card (#593)
* Refactor Language Card: . MemSetPaging() now not used for $C080-C08F accesses. - Instead LC registers its own I/O handler like all other slot 1-7 cards. . Saturn uses base LC's 16K for bank0 * Move all 'modechanging = 0' to UpdatePaging()
This commit is contained in:
parent
f9b7d9326e
commit
42c58f54e7
@ -49,19 +49,28 @@ LanguageCardUnit::~LanguageCardUnit(void)
|
|||||||
SetMemMainLanguageCard(NULL);
|
SetMemMainLanguageCard(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD LanguageCardUnit::SetPaging(WORD address, DWORD memmode, BOOL& modechanging, bool write)
|
void LanguageCardUnit::InitializeIO(void)
|
||||||
{
|
{
|
||||||
|
RegisterIoHandler(kSlot0, &LanguageCardUnit::IO, &LanguageCardUnit::IO, NULL, NULL, this, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
BYTE __stdcall LanguageCardUnit::IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nExecutedCycles)
|
||||||
|
{
|
||||||
|
LanguageCardUnit* pLC = (LanguageCardUnit*) MemGetSlotParameters(kSlot0);
|
||||||
|
|
||||||
|
DWORD memmode = GetMemMode();
|
||||||
|
DWORD lastmemmode = memmode;
|
||||||
memmode &= ~(MF_BANK2 | MF_HIGHRAM);
|
memmode &= ~(MF_BANK2 | MF_HIGHRAM);
|
||||||
|
|
||||||
if (!(address & 8))
|
if (!(uAddr & 8))
|
||||||
memmode |= MF_BANK2;
|
memmode |= MF_BANK2;
|
||||||
|
|
||||||
if (((address & 2) >> 1) == (address & 1))
|
if (((uAddr & 2) >> 1) == (uAddr & 1))
|
||||||
memmode |= MF_HIGHRAM;
|
memmode |= MF_HIGHRAM;
|
||||||
|
|
||||||
if (address & 1) // GH#392
|
if (uAddr & 1) // GH#392
|
||||||
{
|
{
|
||||||
if (!write && GetLastRamWrite())
|
if (!bWrite && pLC->GetLastRamWrite())
|
||||||
{
|
{
|
||||||
memmode |= MF_WRITERAM; // UTAIIe:5-23
|
memmode |= MF_WRITERAM; // UTAIIe:5-23
|
||||||
}
|
}
|
||||||
@ -71,9 +80,36 @@ DWORD LanguageCardUnit::SetPaging(WORD address, DWORD memmode, BOOL& modechangin
|
|||||||
memmode &= ~MF_WRITERAM; // UTAIIe:5-23
|
memmode &= ~MF_WRITERAM; // UTAIIe:5-23
|
||||||
}
|
}
|
||||||
|
|
||||||
SetLastRamWrite( ((address & 1) && !write) ); // UTAIIe:5-23
|
pLC->SetLastRamWrite( ((uAddr & 1) && !bWrite) ); // UTAIIe:5-23
|
||||||
|
SetMemMode(memmode);
|
||||||
|
|
||||||
return memmode;
|
//
|
||||||
|
|
||||||
|
if (IS_APPLE2E)
|
||||||
|
{
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// NB. A 6502 interrupt occurring between these memory write & read updates could lead to incorrect behaviour.
|
||||||
|
// - although any data-race is probably a bug in the 6502 code too.
|
||||||
|
if ((PC < 0xC000) &&
|
||||||
|
(((*(LPDWORD)(mem+PC) & 0x00FFFEFF) == 0x00C0048D) || // Next: STA $C004 or STA $C005
|
||||||
|
((*(LPDWORD)(mem+PC) & 0x00FFFEFF) == 0x00C0028D))) // Next: STA $C002 or STA $C003
|
||||||
|
{
|
||||||
|
SetModeChanging(1);
|
||||||
|
return bWrite ? 0 : MemReadFloatingBus(nExecutedCycles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IF THE MEMORY PAGING MODE HAS CHANGED, UPDATE OUR MEMORY IMAGES AND
|
||||||
|
// WRITE TABLES.
|
||||||
|
if (lastmemmode != memmode)
|
||||||
|
{
|
||||||
|
MemUpdatePaging(0); // Initialize=0
|
||||||
|
}
|
||||||
|
|
||||||
|
return bWrite ? 0 : MemReadFloatingBus(nExecutedCycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
@ -94,7 +130,7 @@ LanguageCardSlot0::~LanguageCardSlot0(void)
|
|||||||
//
|
//
|
||||||
|
|
||||||
static const UINT kUNIT_LANGUAGECARD_VER = 1;
|
static const UINT kUNIT_LANGUAGECARD_VER = 1;
|
||||||
static const UINT kSLOT_LANGUAGECARD = 0;
|
static const UINT kSLOT_LANGUAGECARD = LanguageCardUnit::kSlot0;
|
||||||
|
|
||||||
#define SS_YAML_VALUE_CARD_LANGUAGECARD "Language Card"
|
#define SS_YAML_VALUE_CARD_LANGUAGECARD "Language Card"
|
||||||
|
|
||||||
@ -188,7 +224,9 @@ Saturn128K::Saturn128K(UINT banks)
|
|||||||
for (UINT i=0; i<kMaxSaturnBanks; i++)
|
for (UINT i=0; i<kMaxSaturnBanks; i++)
|
||||||
m_aSaturnBanks[i] = NULL;
|
m_aSaturnBanks[i] = NULL;
|
||||||
|
|
||||||
for (UINT i = 0; i < m_uSaturnTotalBanks; i++)
|
m_aSaturnBanks[0] = m_pMemory; // Reuse memory allocated in base ctor
|
||||||
|
|
||||||
|
for (UINT i = 1; i < m_uSaturnTotalBanks; i++)
|
||||||
m_aSaturnBanks[i] = (LPBYTE) VirtualAlloc(NULL, kMemBankSize, MEM_COMMIT, PAGE_READWRITE); // Saturn banks are 16K, max 8 banks/card
|
m_aSaturnBanks[i] = (LPBYTE) VirtualAlloc(NULL, kMemBankSize, MEM_COMMIT, PAGE_READWRITE); // Saturn banks are 16K, max 8 banks/card
|
||||||
|
|
||||||
SetMemMainLanguageCard( m_aSaturnBanks[ m_uSaturnActiveBank ] );
|
SetMemMainLanguageCard( m_aSaturnBanks[ m_uSaturnActiveBank ] );
|
||||||
@ -196,7 +234,9 @@ Saturn128K::Saturn128K(UINT banks)
|
|||||||
|
|
||||||
Saturn128K::~Saturn128K(void)
|
Saturn128K::~Saturn128K(void)
|
||||||
{
|
{
|
||||||
for (UINT i = 0; i < m_uSaturnTotalBanks; i++)
|
m_aSaturnBanks[0] = NULL; // just zero this - deallocated in base ctor
|
||||||
|
|
||||||
|
for (UINT i = 1; i < m_uSaturnTotalBanks; i++)
|
||||||
{
|
{
|
||||||
if (m_aSaturnBanks[i])
|
if (m_aSaturnBanks[i])
|
||||||
{
|
{
|
||||||
@ -216,7 +256,12 @@ UINT Saturn128K::GetActiveBank(void)
|
|||||||
return m_uSaturnActiveBank;
|
return m_uSaturnActiveBank;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD Saturn128K::SetPaging(WORD address, DWORD memmode, BOOL& modechanging, bool /*write*/)
|
void Saturn128K::InitializeIO(void)
|
||||||
|
{
|
||||||
|
RegisterIoHandler(kSlot0, &Saturn128K::IO, &Saturn128K::IO, NULL, NULL, this, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
BYTE __stdcall Saturn128K::IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nExecutedCycles)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Bin Addr.
|
Bin Addr.
|
||||||
@ -237,54 +282,70 @@ DWORD Saturn128K::SetPaging(WORD address, DWORD memmode, BOOL& modechanging, boo
|
|||||||
1110 $C0NE select 16K Bank 7
|
1110 $C0NE select 16K Bank 7
|
||||||
1111 $C0NF select 16K Bank 8
|
1111 $C0NF select 16K Bank 8
|
||||||
*/
|
*/
|
||||||
_ASSERT(m_uSaturnTotalBanks);
|
Saturn128K* pLC = (Saturn128K*) MemGetSlotParameters(kSlot0);
|
||||||
if (!m_uSaturnTotalBanks)
|
|
||||||
return memmode;
|
|
||||||
|
|
||||||
if (address & (1<<2))
|
_ASSERT(pLC->m_uSaturnTotalBanks);
|
||||||
|
if (!pLC->m_uSaturnTotalBanks)
|
||||||
|
return bWrite ? 0 : MemReadFloatingBus(nExecutedCycles);
|
||||||
|
|
||||||
|
bool bBankChanged = false;
|
||||||
|
DWORD memmode=0, lastmemmode=0;
|
||||||
|
|
||||||
|
if (uAddr & (1<<2))
|
||||||
{
|
{
|
||||||
m_uSaturnActiveBank = 0 // Saturn 128K Language Card Bank 0 .. 7
|
pLC->m_uSaturnActiveBank = 0 // Saturn 128K Language Card Bank 0 .. 7
|
||||||
| (address >> 1) & 4
|
| (uAddr >> 1) & 4
|
||||||
| (address >> 0) & 3;
|
| (uAddr >> 0) & 3;
|
||||||
|
|
||||||
if (m_uSaturnActiveBank >= m_uSaturnTotalBanks)
|
if (pLC->m_uSaturnActiveBank >= pLC->m_uSaturnTotalBanks)
|
||||||
{
|
{
|
||||||
// EG. Run RAMTEST128K tests on a Saturn 64K card
|
// EG. Run RAMTEST128K tests on a Saturn 64K card
|
||||||
// TODO: Saturn::UpdatePaging() should deal with this case:
|
// TODO: Saturn::UpdatePaging() should deal with this case:
|
||||||
// . Technically read floating-bus, write to nothing
|
// . Technically read floating-bus, write to nothing
|
||||||
// . But the mem cache doesn't support floating-bus reads from non-I/O space
|
// . But the mem cache doesn't support floating-bus reads from non-I/O space
|
||||||
m_uSaturnActiveBank = m_uSaturnTotalBanks-1; // FIXME: just prevent crash for now!
|
pLC->m_uSaturnActiveBank = pLC->m_uSaturnTotalBanks-1; // FIXME: just prevent crash for now!
|
||||||
}
|
}
|
||||||
|
|
||||||
SetMemMainLanguageCard( m_aSaturnBanks[ m_uSaturnActiveBank ] );
|
SetMemMainLanguageCard( pLC->m_aSaturnBanks[ pLC->m_uSaturnActiveBank ] );
|
||||||
|
bBankChanged = true;
|
||||||
modechanging = 1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
memmode = GetMemMode();
|
||||||
|
lastmemmode = memmode;
|
||||||
memmode &= ~(MF_BANK2 | MF_HIGHRAM);
|
memmode &= ~(MF_BANK2 | MF_HIGHRAM);
|
||||||
|
|
||||||
if (!(address & 8))
|
if (!(uAddr & 8))
|
||||||
memmode |= MF_BANK2;
|
memmode |= MF_BANK2;
|
||||||
|
|
||||||
if (((address & 2) >> 1) == (address & 1))
|
if (((uAddr & 2) >> 1) == (uAddr & 1))
|
||||||
memmode |= MF_HIGHRAM;
|
memmode |= MF_HIGHRAM;
|
||||||
|
|
||||||
if (address & 1 && GetLastRamWrite()) // Saturn differs from Apple's 16K LC: any access (LC is read-only)
|
if (uAddr & 1 && pLC->GetLastRamWrite())// Saturn differs from Apple's 16K LC: any access (LC is read-only)
|
||||||
memmode |= MF_WRITERAM;
|
memmode |= MF_WRITERAM;
|
||||||
else
|
else
|
||||||
memmode &= ~MF_WRITERAM;
|
memmode &= ~MF_WRITERAM;
|
||||||
|
|
||||||
SetLastRamWrite(address & 1); // Saturn differs from Apple's 16K LC: any access (LC is read-only)
|
pLC->SetLastRamWrite(uAddr & 1); // Saturn differs from Apple's 16K LC: any access (LC is read-only)
|
||||||
|
SetMemMode(memmode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return memmode;
|
// NB. Unlike LC, no need to check if next opcode is STA $C002-5, as Saturn is not for //e
|
||||||
|
|
||||||
|
// IF THE MEMORY PAGING MODE HAS CHANGED, UPDATE OUR MEMORY IMAGES AND
|
||||||
|
// WRITE TABLES.
|
||||||
|
if ((lastmemmode != memmode) || bBankChanged)
|
||||||
|
{
|
||||||
|
MemUpdatePaging(0); // Initialize=0
|
||||||
|
}
|
||||||
|
|
||||||
|
return bWrite ? 0 : MemReadFloatingBus(nExecutedCycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
static const UINT kUNIT_SATURN_VER = 1;
|
static const UINT kUNIT_SATURN_VER = 1;
|
||||||
static const UINT kSLOT_SATURN = 0;
|
static const UINT kSLOT_SATURN = LanguageCardUnit::kSlot0;
|
||||||
|
|
||||||
#define SS_YAML_VALUE_CARD_SATURN128 "Saturn 128"
|
#define SS_YAML_VALUE_CARD_SATURN128 "Saturn 128"
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ public:
|
|||||||
LanguageCardUnit(void);
|
LanguageCardUnit(void);
|
||||||
virtual ~LanguageCardUnit(void);
|
virtual ~LanguageCardUnit(void);
|
||||||
|
|
||||||
virtual DWORD SetPaging(WORD address, DWORD memmode, BOOL& modechanging, bool write);
|
virtual void InitializeIO(void);
|
||||||
virtual void SetMemorySize(UINT banks) {} // No-op for //e and slot-0 16K LC
|
virtual void SetMemorySize(UINT banks) {} // No-op for //e and slot-0 16K LC
|
||||||
virtual UINT GetActiveBank(void) { return 0; } // Always 0 as only 1x 16K bank
|
virtual UINT GetActiveBank(void) { return 0; } // Always 0 as only 1x 16K bank
|
||||||
virtual void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper) { _ASSERT(0); } // Not used for //e
|
virtual void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper) { _ASSERT(0); } // Not used for //e
|
||||||
@ -20,7 +20,10 @@ public:
|
|||||||
void SetLastRamWrite(BOOL count) { m_uLastRamWrite = count; }
|
void SetLastRamWrite(BOOL count) { m_uLastRamWrite = count; }
|
||||||
SS_CARDTYPE GetMemoryType(void) { return m_type; }
|
SS_CARDTYPE GetMemoryType(void) { return m_type; }
|
||||||
|
|
||||||
|
static BYTE __stdcall IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nExecutedCycles);
|
||||||
|
|
||||||
static const UINT kMemModeInitialState;
|
static const UINT kMemModeInitialState;
|
||||||
|
static const UINT kSlot0 = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SS_CARDTYPE m_type;
|
SS_CARDTYPE m_type;
|
||||||
@ -49,10 +52,10 @@ protected:
|
|||||||
void SaveLCState(class YamlSaveHelper& yamlSaveHelper);
|
void SaveLCState(class YamlSaveHelper& yamlSaveHelper);
|
||||||
void LoadLCState(class YamlLoadHelper& yamlLoadHelper);
|
void LoadLCState(class YamlLoadHelper& yamlLoadHelper);
|
||||||
|
|
||||||
|
LPBYTE m_pMemory;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string GetSnapshotMemStructName(void);
|
std::string GetSnapshotMemStructName(void);
|
||||||
|
|
||||||
LPBYTE m_pMemory;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -65,12 +68,14 @@ public:
|
|||||||
Saturn128K(UINT banks);
|
Saturn128K(UINT banks);
|
||||||
virtual ~Saturn128K(void);
|
virtual ~Saturn128K(void);
|
||||||
|
|
||||||
virtual DWORD SetPaging(WORD address, DWORD memmode, BOOL& modechanging, bool write);
|
virtual void InitializeIO(void);
|
||||||
virtual void SetMemorySize(UINT banks);
|
virtual void SetMemorySize(UINT banks);
|
||||||
virtual UINT GetActiveBank(void);
|
virtual UINT GetActiveBank(void);
|
||||||
virtual void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
|
virtual void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
|
||||||
virtual bool LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
|
virtual bool LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version);
|
||||||
|
|
||||||
|
static BYTE __stdcall IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nExecutedCycles);
|
||||||
|
|
||||||
// "The boards consist of 16K banks of memory (4 banks for the 64K board, 8 banks for the 128K), accessed one at a time" - Ref: "64K/128K RAM BOARD", Saturn Systems, Ch.1 Introduction(pg-5)
|
// "The boards consist of 16K banks of memory (4 banks for the 64K board, 8 banks for the 128K), accessed one at a time" - Ref: "64K/128K RAM BOARD", Saturn Systems, Ch.1 Introduction(pg-5)
|
||||||
static const UINT kMaxSaturnBanks = 8; // 8 * 16K = 128K
|
static const UINT kMaxSaturnBanks = 8; // 8 * 16K = 128K
|
||||||
static std::string GetSnapshotCardName(void);
|
static std::string GetSnapshotCardName(void);
|
||||||
|
@ -229,7 +229,7 @@ static void ResetDefaultMachineMemTypes(void)
|
|||||||
g_MemTypeAppleIIe = CT_Extended80Col;
|
g_MemTypeAppleIIe = CT_Extended80Col;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from MemInitialize(), MemLoadSnapshot()
|
// Called from MemInitialize(), MemLoadSnapshot(), MemSetSnapshot_v1()
|
||||||
static void SetExpansionMemTypeDefault(void)
|
static void SetExpansionMemTypeDefault(void)
|
||||||
{
|
{
|
||||||
SS_CARDTYPE defaultType = IsApple2Original(GetApple2Type()) ? g_MemTypeAppleII
|
SS_CARDTYPE defaultType = IsApple2Original(GetApple2Type()) ? g_MemTypeAppleII
|
||||||
@ -280,25 +280,28 @@ void SetExpansionMemType(const SS_CARDTYPE type)
|
|||||||
newSlotAuxCard = type;
|
newSlotAuxCard = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_Slot0 = newSlot0Card;
|
||||||
|
g_SlotAux = newSlotAuxCard;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateLanguageCard(void)
|
||||||
|
{
|
||||||
|
delete g_pLanguageCard;
|
||||||
|
g_pLanguageCard = NULL;
|
||||||
|
|
||||||
if (IsApple2PlusOrClone(GetApple2Type()))
|
if (IsApple2PlusOrClone(GetApple2Type()))
|
||||||
{
|
{
|
||||||
delete g_pLanguageCard;
|
if (g_Slot0 == CT_Saturn128K)
|
||||||
|
|
||||||
if (newSlot0Card == CT_Saturn128K)
|
|
||||||
g_pLanguageCard = new Saturn128K(g_uSaturnBanksFromCmdLine);
|
g_pLanguageCard = new Saturn128K(g_uSaturnBanksFromCmdLine);
|
||||||
else if (newSlot0Card == CT_LanguageCard)
|
else if (g_Slot0 == CT_LanguageCard)
|
||||||
g_pLanguageCard = new LanguageCardSlot0;
|
g_pLanguageCard = new LanguageCardSlot0;
|
||||||
else
|
else
|
||||||
g_pLanguageCard = NULL;
|
g_pLanguageCard = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delete g_pLanguageCard;
|
|
||||||
g_pLanguageCard = new LanguageCardUnit;
|
g_pLanguageCard = new LanguageCardUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_Slot0 = newSlot0Card;
|
|
||||||
g_SlotAux = newSlotAuxCard;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SS_CARDTYPE GetCurrentExpansionMemType(void)
|
SS_CARDTYPE GetCurrentExpansionMemType(void)
|
||||||
@ -969,6 +972,11 @@ static bool IsCardInSlot(const UINT uSlot)
|
|||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
|
void SetModeChanging(BOOL value)
|
||||||
|
{
|
||||||
|
modechanging = value;
|
||||||
|
}
|
||||||
|
|
||||||
DWORD GetMemMode(void)
|
DWORD GetMemMode(void)
|
||||||
{
|
{
|
||||||
return memmode;
|
return memmode;
|
||||||
@ -1037,6 +1045,8 @@ void MemUpdatePaging(BOOL initialize)
|
|||||||
|
|
||||||
static void UpdatePaging(BOOL initialize)
|
static void UpdatePaging(BOOL initialize)
|
||||||
{
|
{
|
||||||
|
modechanging = 0;
|
||||||
|
|
||||||
// SAVE THE CURRENT PAGING SHADOW TABLE
|
// SAVE THE CURRENT PAGING SHADOW TABLE
|
||||||
LPBYTE oldshadow[256];
|
LPBYTE oldshadow[256];
|
||||||
if (!initialize)
|
if (!initialize)
|
||||||
@ -1437,7 +1447,7 @@ void MemInitialize()
|
|||||||
SetExpansionMemTypeDefault();
|
SetExpansionMemTypeDefault();
|
||||||
|
|
||||||
#ifdef RAMWORKS
|
#ifdef RAMWORKS
|
||||||
if (GetCurrentExpansionMemType() == CT_RamWorksIII)
|
if (g_SlotAux == CT_RamWorksIII)
|
||||||
{
|
{
|
||||||
// allocate memory for RAMWorks III - up to 8MB
|
// allocate memory for RAMWorks III - up to 8MB
|
||||||
g_uActiveBank = 0;
|
g_uActiveBank = 0;
|
||||||
@ -1452,6 +1462,8 @@ void MemInitialize()
|
|||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
CreateLanguageCard();
|
||||||
|
|
||||||
MemInitializeROM();
|
MemInitializeROM();
|
||||||
MemInitializeCustomF8ROM();
|
MemInitializeCustomF8ROM();
|
||||||
MemInitializeIO();
|
MemInitializeIO();
|
||||||
@ -1580,9 +1592,10 @@ void MemInitializeCustomF8ROM(void)
|
|||||||
{
|
{
|
||||||
memcpy(memrom, OldRom, Apple2RomSize); // ROM at $D000...$FFFF
|
memcpy(memrom, OldRom, Apple2RomSize); // ROM at $D000...$FFFF
|
||||||
bRes = FALSE;
|
bRes = FALSE;
|
||||||
// NB. Keep g_hCustomRomF8 handle open - so that any next restart can load it again
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NB. If succeeded, then keep g_hCustomRomF8 handle open - so that any next restart can load it again
|
||||||
|
|
||||||
if (!bRes)
|
if (!bRes)
|
||||||
{
|
{
|
||||||
MessageBox( g_hFrameWindow, "Failed to read custom F8 rom", TEXT("AppleWin Error"), MB_OK );
|
MessageBox( g_hFrameWindow, "Failed to read custom F8 rom", TEXT("AppleWin Error"), MB_OK );
|
||||||
@ -1616,8 +1629,10 @@ void MemInitializeIO(void)
|
|||||||
{
|
{
|
||||||
InitIoHandlers();
|
InitIoHandlers();
|
||||||
|
|
||||||
const UINT uSlot = 0;
|
if (g_pLanguageCard)
|
||||||
RegisterIoHandler(uSlot, MemSetPaging, MemSetPaging, NULL, NULL, NULL, NULL);
|
g_pLanguageCard->InitializeIO();
|
||||||
|
else
|
||||||
|
RegisterIoHandler(LanguageCardUnit::kSlot0, IO_Null, IO_Null, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
// TODO: Cleanup peripheral setup!!!
|
// TODO: Cleanup peripheral setup!!!
|
||||||
PrintLoadRom(pCxRomPeripheral, 1); // $C100 : Parallel printer f/w
|
PrintLoadRom(pCxRomPeripheral, 1); // $C100 : Parallel printer f/w
|
||||||
@ -1904,12 +1919,7 @@ BYTE __stdcall MemSetPaging(WORD programcounter, WORD address, BYTE write, BYTE
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// DETERMINE THE NEW MEMORY PAGING MODE.
|
// DETERMINE THE NEW MEMORY PAGING MODE.
|
||||||
if (address >= 0x80 && address <= 0x8F)
|
if (!IS_APPLE2)
|
||||||
{
|
|
||||||
if (!IS_APPLE2 || (IsApple2PlusOrClone(GetApple2Type()) && g_Slot0 != CT_Empty))
|
|
||||||
SetMemMode( g_pLanguageCard->SetPaging(address, memmode, modechanging, write ? true : false) );
|
|
||||||
}
|
|
||||||
else if (!IS_APPLE2)
|
|
||||||
{
|
{
|
||||||
switch (address)
|
switch (address)
|
||||||
{
|
{
|
||||||
@ -1943,24 +1953,19 @@ BYTE __stdcall MemSetPaging(WORD programcounter, WORD address, BYTE write, BYTE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetCurrentExpansionMemType() != CT_Saturn128K) // TODO: Not sure this optimisation is valid for Saturn, so skip it for now
|
if (IS_APPLE2E)
|
||||||
{
|
{
|
||||||
// IF THE EMULATED PROGRAM HAS JUST UPDATE THE MEMORY WRITE MODE AND IS
|
// 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
|
// ABOUT TO UPDATE THE MEMORY READ MODE, HOLD OFF ON ANY PROCESSING UNTIL
|
||||||
// IT DOES SO.
|
// IT DOES SO.
|
||||||
//
|
//
|
||||||
// NB. A 6502 interrupt occurring between these memory write & read updates could lead to incorrect behaviour.
|
// NB. A 6502 interrupt occurring between these memory write & read updates could lead to incorrect behaviour.
|
||||||
// - although any data-race is probably a bug in the 6502 code too.
|
// - although any data-race is probably a bug in the 6502 code too.
|
||||||
if ((address >= 4) && (address <= 5) &&
|
if ((address >= 4) && (address <= 5) &&
|
||||||
((*(LPDWORD)(mem+programcounter) & 0x00FFFEFF) == 0x00C0028D)) {
|
((*(LPDWORD)(mem+programcounter) & 0x00FFFEFF) == 0x00C0028D)) // Next: STA $C002 or STA $C003
|
||||||
|
{
|
||||||
modechanging = 1;
|
modechanging = 1;
|
||||||
return write ? 0 : MemReadFloatingBus(1, nExecutedCycles);
|
return 0; // For $C004 & $C005: entry to this func is always via a write to $C004 or $C005
|
||||||
}
|
|
||||||
if ((address >= 0x80) && (address <= 0x8F) && (programcounter < 0xC000) &&
|
|
||||||
(((*(LPDWORD)(mem+programcounter) & 0x00FFFEFF) == 0x00C0048D) ||
|
|
||||||
((*(LPDWORD)(mem+programcounter) & 0x00FFFEFF) == 0x00C0028D))) {
|
|
||||||
modechanging = 1;
|
|
||||||
return write ? 0 : MemReadFloatingBus(1, nExecutedCycles);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1968,8 +1973,6 @@ BYTE __stdcall MemSetPaging(WORD programcounter, WORD address, BYTE write, BYTE
|
|||||||
// WRITE TABLES.
|
// WRITE TABLES.
|
||||||
if ((lastmemmode != memmode) || modechanging)
|
if ((lastmemmode != memmode) || modechanging)
|
||||||
{
|
{
|
||||||
modechanging = 0;
|
|
||||||
|
|
||||||
// NB. Must check MF_SLOTC3ROM too, as IoHandlerCardsIn() depends on both MF_INTCXROM|MF_SLOTC3ROM
|
// 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)) != (memmode & (MF_INTCXROM|MF_SLOTC3ROM)))
|
||||||
{
|
{
|
||||||
@ -2027,6 +2030,7 @@ void MemSetSnapshot_v1(const DWORD MemMode, const BOOL LastWriteRam, const BYTE*
|
|||||||
ResetDefaultMachineMemTypes();
|
ResetDefaultMachineMemTypes();
|
||||||
g_MemTypeAppleII = CT_LanguageCard; // SSv1 doesn't save machine type - so if current machine is Apple II then give it 64K + LC
|
g_MemTypeAppleII = CT_LanguageCard; // SSv1 doesn't save machine type - so if current machine is Apple II then give it 64K + LC
|
||||||
SetExpansionMemTypeDefault();
|
SetExpansionMemTypeDefault();
|
||||||
|
CreateLanguageCard(); // Create LC here, as for SSv1 there is no slot-0 state
|
||||||
|
|
||||||
SetMemMode(MemMode ^ MF_INTCXROM); // Convert from SLOTCXROM to INTCXROM
|
SetMemMode(MemMode ^ MF_INTCXROM); // Convert from SLOTCXROM to INTCXROM
|
||||||
SetLastRamWrite(LastWriteRam);
|
SetLastRamWrite(LastWriteRam);
|
||||||
@ -2037,7 +2041,6 @@ void MemSetSnapshot_v1(const DWORD MemMode, const BOOL LastWriteRam, const BYTE*
|
|||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
modechanging = 0;
|
|
||||||
// NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v1()
|
// NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v1()
|
||||||
UpdatePaging(1); // Initialize=1
|
UpdatePaging(1); // Initialize=1
|
||||||
}
|
}
|
||||||
@ -2133,8 +2136,12 @@ bool MemLoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version)
|
|||||||
// Create default LC type for AppleII machine (do prior to loading saved LC state)
|
// Create default LC type for AppleII machine (do prior to loading saved LC state)
|
||||||
ResetDefaultMachineMemTypes();
|
ResetDefaultMachineMemTypes();
|
||||||
if (version == 1)
|
if (version == 1)
|
||||||
g_MemTypeAppleII = CT_LanguageCard; // version=1: original Apple II always had a LC
|
g_MemTypeAppleII = CT_LanguageCard; // version=1: original Apple II always has a LC
|
||||||
|
else
|
||||||
|
g_MemTypeAppleIIPlus = CT_Empty; // version=2+: Apple II/II+ initially start with slot-0 empty
|
||||||
SetExpansionMemTypeDefault();
|
SetExpansionMemTypeDefault();
|
||||||
|
CreateLanguageCard(); // Create default LC now for: (a) //e which has no slot-0 LC (so this is final)
|
||||||
|
// (b) II/II+ which get re-created later if slot-0 has a card
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
@ -2181,7 +2188,6 @@ bool MemLoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version)
|
|||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
modechanging = 0;
|
|
||||||
// NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v2()
|
// NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v2()
|
||||||
UpdatePaging(1); // Initialize=1 (Still needed, even with call to MemUpdatePaging() - why?)
|
UpdatePaging(1); // Initialize=1 (Still needed, even with call to MemUpdatePaging() - why?)
|
||||||
// TC-TODO: At this point, the cards haven't been loaded, so the card's expansion ROM is unknown - so pointless(?) calling this now
|
// TC-TODO: At this point, the cards haven't been loaded, so the card's expansion ROM is unknown - so pointless(?) calling this now
|
||||||
|
@ -66,6 +66,7 @@ LPBYTE MemGetBankPtr(const UINT nBank);
|
|||||||
LPBYTE MemGetCxRomPeripheral();
|
LPBYTE MemGetCxRomPeripheral();
|
||||||
DWORD GetMemMode(void);
|
DWORD GetMemMode(void);
|
||||||
void SetMemMode(DWORD memmode);
|
void SetMemMode(DWORD memmode);
|
||||||
|
void SetModeChanging(BOOL value);
|
||||||
bool MemIsAddrCodeMemory(const USHORT addr);
|
bool MemIsAddrCodeMemory(const USHORT addr);
|
||||||
void MemInitialize ();
|
void MemInitialize ();
|
||||||
void MemInitializeROM(void);
|
void MemInitializeROM(void);
|
||||||
@ -92,6 +93,7 @@ BYTE __stdcall MemSetPaging(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExec
|
|||||||
enum SS_CARDTYPE;
|
enum SS_CARDTYPE;
|
||||||
void SetExpansionMemType(const SS_CARDTYPE type);
|
void SetExpansionMemType(const SS_CARDTYPE type);
|
||||||
SS_CARDTYPE GetCurrentExpansionMemType(void);
|
SS_CARDTYPE GetCurrentExpansionMemType(void);
|
||||||
|
void CreateLanguageCard(void);
|
||||||
|
|
||||||
void SetRamWorksMemorySize(UINT pages);
|
void SetRamWorksMemorySize(UINT pages);
|
||||||
UINT GetRamWorksActiveBank(void);
|
UINT GetRamWorksActiveBank(void);
|
||||||
|
@ -371,7 +371,6 @@ static void ParseSlots(YamlLoadHelper& yamlLoadHelper, UINT version)
|
|||||||
if (!yamlLoadHelper.GetSubMap(std::string(SS_YAML_KEY_STATE)))
|
if (!yamlLoadHelper.GetSubMap(std::string(SS_YAML_KEY_STATE)))
|
||||||
throw std::string(SS_YAML_KEY_UNIT ": Expected sub-map name: " SS_YAML_KEY_STATE);
|
throw std::string(SS_YAML_KEY_UNIT ": Expected sub-map name: " SS_YAML_KEY_STATE);
|
||||||
|
|
||||||
bool bIsCardSupported = true;
|
|
||||||
SS_CARDTYPE type = CT_Empty;
|
SS_CARDTYPE type = CT_Empty;
|
||||||
bool bRes = false;
|
bool bRes = false;
|
||||||
|
|
||||||
@ -420,21 +419,22 @@ static void ParseSlots(YamlLoadHelper& yamlLoadHelper, UINT version)
|
|||||||
{
|
{
|
||||||
type = CT_LanguageCard;
|
type = CT_LanguageCard;
|
||||||
SetExpansionMemType(type);
|
SetExpansionMemType(type);
|
||||||
|
CreateLanguageCard();
|
||||||
bRes = GetLanguageCard()->LoadSnapshot(yamlLoadHelper, slot, version);
|
bRes = GetLanguageCard()->LoadSnapshot(yamlLoadHelper, slot, version);
|
||||||
}
|
}
|
||||||
else if (card == Saturn128K::GetSnapshotCardName())
|
else if (card == Saturn128K::GetSnapshotCardName())
|
||||||
{
|
{
|
||||||
type = CT_Saturn128K;
|
type = CT_Saturn128K;
|
||||||
SetExpansionMemType(type);
|
SetExpansionMemType(type);
|
||||||
|
CreateLanguageCard();
|
||||||
bRes = GetLanguageCard()->LoadSnapshot(yamlLoadHelper, slot, version);
|
bRes = GetLanguageCard()->LoadSnapshot(yamlLoadHelper, slot, version);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bIsCardSupported = false;
|
|
||||||
throw std::string("Slots: Unknown card: " + card); // todo: don't throw - just ignore & continue
|
throw std::string("Slots: Unknown card: " + card); // todo: don't throw - just ignore & continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bRes && bIsCardSupported)
|
if (bRes)
|
||||||
{
|
{
|
||||||
m_ConfigNew.m_Slot[slot] = type;
|
m_ConfigNew.m_Slot[slot] = type;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user