From 2463aae54588a726a2edbdaa14e147fc7c19fa5e Mon Sep 17 00:00:00 2001 From: tomcw <tomcw@users.noreply.github.com> Date: Sat, 6 Apr 2019 15:17:18 +0100 Subject: [PATCH] Updates for DHGR MIX and detection (#633): . Support DHGR MIX mode and AN2 off to invert bit7 (undocumented) . Improve the video-mode precondition to check for 80COL access occurring before $C05F --- source/Memory.cpp | 34 +++++++++++++++++++++------------- source/Memory.h | 5 +++-- source/NTSC.cpp | 6 ++++++ source/RGBMonitor.cpp | 21 ++++++++++++++++++--- source/RGBMonitor.h | 2 +- 5 files changed, 49 insertions(+), 19 deletions(-) diff --git a/source/Memory.cpp b/source/Memory.cpp index 9b63b340..5c551104 100644 --- a/source/Memory.cpp +++ b/source/Memory.cpp @@ -2058,6 +2058,13 @@ LPVOID MemGetSlotParameters(UINT uSlot) //=========================================================================== +bool MemGetAnnunciator(UINT annunciator) +{ + return g_Annunciator[annunciator]; +} + +//=========================================================================== + // NB. Don't need to save 'modechanging', as this is just an optimisation to save calling UpdatePaging() twice. // . If we were to save the state when 'modechanging' is set, then on restoring the state, the 6502 code will immediately update the read memory mode. // . This will work correctly. @@ -2078,7 +2085,8 @@ static const UINT kUNIT_AUXSLOT_VER = 2; // Unit version history: // 2: Added: RGB card state -static const UINT kUNIT_VER = 2; +// 3: Extended: RGB card state ('80COL changed') +static const UINT kUNIT_CARD_VER = 3; #define SS_YAML_VALUE_CARD_80COL "80 Column" #define SS_YAML_VALUE_CARD_EXTENDED80COL "Extended 80 Column" @@ -2156,14 +2164,14 @@ void MemSaveSnapshot(YamlSaveHelper& yamlSaveHelper) MemSaveSnapshotMemory(yamlSaveHelper, true); } -bool MemLoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version) +bool MemLoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT unitVersion) { if (!yamlLoadHelper.GetSubMap(MemGetSnapshotStructName())) return false; // Create default LC type for AppleII machine (do prior to loading saved LC state) ResetDefaultMachineMemTypes(); - if (version == 1) + if (unitVersion == 1) 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 @@ -2178,7 +2186,7 @@ bool MemLoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version) g_eExpansionRomType = (eExpansionRomType) yamlLoadHelper.LoadUint(SS_YAML_KEY_EXPANSIONROMTYPE); g_uPeripheralRomSlot = yamlLoadHelper.LoadUint(SS_YAML_KEY_PERIPHERALROMSLOT); - if (version == 1) + if (unitVersion == 1) { SetMemMode( yamlLoadHelper.LoadUint(SS_YAML_KEY_MEMORYMODE) ^ MF_INTCXROM ); // Convert from SLOTCXROM to INTCXROM SetLastRamWrite( yamlLoadHelper.LoadUint(SS_YAML_KEY_LASTRAMWRITE) ? TRUE : FALSE ); @@ -2194,7 +2202,7 @@ bool MemLoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version) SetLastRamWrite( yamlLoadHelper.LoadUint(SS_YAML_KEY_LASTRAMWRITE) ? TRUE : FALSE ); // NB. This is set later for II,II+ by slot-0 LC or Saturn } - if (version == 3) + if (unitVersion == 3) { for (UINT i=0; i<kNumAnnunciators; i++) { @@ -2213,7 +2221,7 @@ bool MemLoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version) memset(memmain+0xC000, 0, LanguageCardSlot0::kMemBankSize); // Clear it, as high 16K may not be in the save-state's "Main Memory" (eg. the case of II+ Saturn replacing //e LC) yamlLoadHelper.LoadMemory(memmain, _6502_MEM_END+1); - if (version == 1 && IsApple2PlusOrClone(GetApple2Type())) + if (unitVersion == 1 && IsApple2PlusOrClone(GetApple2Type())) { // v1 for II/II+ doesn't have a dedicated slot-0 LC, instead the 16K is stored as the top 16K of memmain memcpy(g_pMemMainLanguageCard, memmain+0xC000, LanguageCardSlot0::kMemBankSize); @@ -2256,7 +2264,7 @@ void MemSaveSnapshotAux(YamlSaveHelper& yamlSaveHelper) SS_YAML_VALUE_CARD_RAMWORKSIII; yamlSaveHelper.SaveString(SS_YAML_KEY_CARD, card.c_str()); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_VERSION, kUNIT_VER); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_VERSION, kUNIT_CARD_VER); // Card state { @@ -2348,7 +2356,7 @@ static void MemLoadSnapshotAuxVer1(YamlLoadHelper& yamlLoadHelper) MemLoadSnapshotAuxCommon(yamlLoadHelper, card); } -static void MemLoadSnapshotAuxVer2(YamlLoadHelper& yamlLoadHelper, UINT unitVersion) +static void MemLoadSnapshotAuxVer2(YamlLoadHelper& yamlLoadHelper) { std::string card = yamlLoadHelper.LoadString(SS_YAML_KEY_CARD); UINT cardVersion = yamlLoadHelper.LoadUint(SS_YAML_KEY_VERSION); @@ -2358,18 +2366,18 @@ static void MemLoadSnapshotAuxVer2(YamlLoadHelper& yamlLoadHelper, UINT unitVers MemLoadSnapshotAuxCommon(yamlLoadHelper, card); - RGB_LoadSnapshot(yamlLoadHelper); + RGB_LoadSnapshot(yamlLoadHelper, cardVersion); } -bool MemLoadSnapshotAux(YamlLoadHelper& yamlLoadHelper, UINT version) +bool MemLoadSnapshotAux(YamlLoadHelper& yamlLoadHelper, UINT unitVersion) { - if (version < 1 || version > kUNIT_AUXSLOT_VER) + if (unitVersion < 1 || unitVersion > kUNIT_AUXSLOT_VER) throw std::string(SS_YAML_KEY_UNIT ": AuxSlot: Version mismatch"); - if (version == 1) + if (unitVersion == 1) MemLoadSnapshotAuxVer1(yamlLoadHelper); else - MemLoadSnapshotAuxVer2(yamlLoadHelper, version); + MemLoadSnapshotAuxVer2(yamlLoadHelper); return true; } diff --git a/source/Memory.h b/source/Memory.h index 6f4c440f..8e2a4a58 100644 --- a/source/Memory.h +++ b/source/Memory.h @@ -80,11 +80,12 @@ void MemReset (); void MemResetPaging (); void MemUpdatePaging(BOOL initialize); LPVOID MemGetSlotParameters (UINT uSlot); +bool MemGetAnnunciator(UINT annunciator); std::string MemGetSnapshotUnitAuxSlotName(void); void MemSaveSnapshot(class YamlSaveHelper& yamlSaveHelper); -bool MemLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT version); +bool MemLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT unitVersion); void MemSaveSnapshotAux(class YamlSaveHelper& yamlSaveHelper); -bool MemLoadSnapshotAux(class YamlLoadHelper& yamlLoadHelper, UINT version); +bool MemLoadSnapshotAux(class YamlLoadHelper& yamlLoadHelper, UINT unitVersion); BYTE __stdcall IO_Null(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles); diff --git a/source/NTSC.cpp b/source/NTSC.cpp index 95e7c54f..186e3ba5 100644 --- a/source/NTSC.cpp +++ b/source/NTSC.cpp @@ -1378,6 +1378,12 @@ void updateScreenDoubleHires80Simplified (long cycles6502 ) // wsUpdateVideoDblH uint8_t a = *MemGetAuxPtr(addr); uint8_t m = *MemGetMainPtr(addr); + if (RGB_IsMixMode() && !MemGetAnnunciator(2)) // AN2 inverts high bit? (GH#633) + { + a ^= 0x80; + m ^= 0x80; + } + if (RGB_Is160Mode()) { int width = UpdateDHiRes160Cell(g_nVideoClockHorz-VIDEO_SCANNER_HORZ_START, g_nVideoClockVert, addr, g_pVideoAddress); diff --git a/source/RGBMonitor.cpp b/source/RGBMonitor.cpp index 81d41d34..93a8a0db 100644 --- a/source/RGBMonitor.cpp +++ b/source/RGBMonitor.cpp @@ -738,6 +738,7 @@ void VideoInitializeOriginal(baseColors_t pBaseNtscColors) static UINT g_rgbFlags = 0; static UINT g_rgbMode = 0; static WORD g_rgbPrevAN3Addr = 0; +static bool g_rgbSet80COL = false; // Video7 RGB card: // . Clock in the !80COL state to define the 2 flags: F2, F1 @@ -745,7 +746,13 @@ static WORD g_rgbPrevAN3Addr = 0; // . NB. There's a final 5th AN3 transition to set DHGR mode void RGB_SetVideoMode(WORD address) { - if ((address&~1) != 0x5E) // 0x5E or 0x5F? + if ((address&~1) == 0x0C) // 0x0C or 0x0D? (80COL) + { + g_rgbSet80COL = true; + return; + } + + if ((address&~1) != 0x5E) // 0x5E or 0x5F? (DHIRES) return; // Precondition before toggling AN3: @@ -754,10 +761,12 @@ void RGB_SetVideoMode(WORD address) // . (*) "King's Quest 1" - see routine at 0x5FD7 (trigger by pressing TAB twice) // . Apple II desktop sets DHGR B&W mode with HIRES off! (GH#631) // Maybe there is no video-mode precondition? - if (g_uVideoMode & VF_MIXED) + // . After setting 80COL on/off then need a 0x5E->0x5F toggle. So if we see a 0x5F then reset (GH#633) + if ((g_uVideoMode & VF_MIXED) || (g_rgbSet80COL && address == 0x5F)) { g_rgbMode = 0; g_rgbPrevAN3Addr = 0; + g_rgbSet80COL = false; return; } @@ -769,6 +778,7 @@ void RGB_SetVideoMode(WORD address) } g_rgbPrevAN3Addr = address; + g_rgbSet80COL = false; } bool RGB_Is140Mode(void) // Extended 80-Column Text/AppleColor Card's Mode 2 @@ -806,6 +816,7 @@ void RGB_ResetState(void) #define SS_YAML_KEY_RGB_FLAGS "RGB mode flags" #define SS_YAML_KEY_RGB_MODE "RGB mode" #define SS_YAML_KEY_RGB_PREVIOUS_AN3 "Previous AN3" +#define SS_YAML_KEY_RGB_80COL_CHANGED "80COL changed" void RGB_SaveSnapshot(YamlSaveHelper& yamlSaveHelper) { @@ -814,9 +825,10 @@ void RGB_SaveSnapshot(YamlSaveHelper& yamlSaveHelper) yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_RGB_FLAGS, g_rgbFlags); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_RGB_MODE, g_rgbMode); yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_RGB_PREVIOUS_AN3, g_rgbPrevAN3Addr); + yamlSaveHelper.SaveBool(SS_YAML_KEY_RGB_80COL_CHANGED, g_rgbSet80COL); } -void RGB_LoadSnapshot(YamlLoadHelper& yamlLoadHelper) +void RGB_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT cardVersion) { if (!yamlLoadHelper.GetSubMap(SS_YAML_KEY_RGB_CARD)) throw std::string("Card: Expected key: ") + std::string(SS_YAML_KEY_RGB_CARD); @@ -825,5 +837,8 @@ void RGB_LoadSnapshot(YamlLoadHelper& yamlLoadHelper) g_rgbMode = yamlLoadHelper.LoadUint(SS_YAML_KEY_RGB_MODE); g_rgbPrevAN3Addr = yamlLoadHelper.LoadUint(SS_YAML_KEY_RGB_PREVIOUS_AN3); + if (cardVersion >= 3) + g_rgbSet80COL = yamlLoadHelper.LoadBool(SS_YAML_KEY_RGB_80COL_CHANGED); + yamlLoadHelper.PopMap(); } diff --git a/source/RGBMonitor.h b/source/RGBMonitor.h index 0f7a16b8..b6b26ab7 100644 --- a/source/RGBMonitor.h +++ b/source/RGBMonitor.h @@ -16,4 +16,4 @@ bool RGB_Is560Mode(void); void RGB_ResetState(void); void RGB_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper); -void RGB_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper); +void RGB_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT cardVersion);