diff --git a/bin/History.txt b/bin/History.txt index 3435ce11..92a7d77b 100644 --- a/bin/History.txt +++ b/bin/History.txt @@ -9,6 +9,17 @@ https://github.com/AppleWin/AppleWin/issues/new Tom Charlesworth +1.29.11.0 - 27 Mar 2020 +----------------------- +. [Bug #771] Added new command line switch to load custom ROM: -rom . + - Supports 12KiB (at $D000) and 16KiB (at $C000) rom files. +. [Bug #765] Lancaster (Total Replay) hangs when starting second game. +. [Bug #734] DiskII controller card: support 13-sector firmware. + - The card auto-selects the firmware based on the .woz (v2 or higher) image properties. + - Only change the firmware at reset/reboot to avoid changing whilst running in $C6xx space! + - Fixes 'The Best of MUSE' & 'MicroChess 2.0' (#732) + + 1.29.10.0 - 13 Feb 2020 ----------------------- . [PR #756] Write support for WOZ1/WOZ2 images. @@ -21,8 +32,8 @@ Tom Charlesworth 1.29.9.0 - 26 Jan 2020 ---------------------- -. [Bug #752] Fixed double-clicking a registered file-type issue (regression introduced at 1.29.8.0). -. [Bug #750] Fixed Ctrl+Alt+Break wasn't emulating CTRL+OA+RESET (regression introduced at 1.29.8.0). +. [Bug #750] Fixed double-clicking a registered file-type issue (regression introduced at 1.29.8.0). +. [Bug #752] Fixed Ctrl+Alt+Break wasn't emulating CTRL+OA+RESET (regression introduced at 1.29.8.0). 1.29.8.0 - 19 Jan 2020 diff --git a/help/CommandLine.html b/help/CommandLine.html index 44d6ec0b..bd16fb56 100644 --- a/help/CommandLine.html +++ b/help/CommandLine.html @@ -64,8 +64,10 @@
  • nnnn: select a specific resolution with height=nnnn pixels
  • NB. This changes the display resolution (and restores on exit).

    + -rom <file>
    + Use custom 12K ROM (at $D000) for Apple II machine, or 16K ROM (at $C000) for Apple //e machine.

    -f8rom <file>
    - Use custom 2K ROM for any Apple II machine at [$F800..$FFFF]. <file> must be 2048 bytes long

    + Use custom 2K ROM for any Apple II machine at [$F800..$FFFF]. <file> must be 2048 bytes long.

    -videorom <file>
    Use an alternate custom 2K video ROM for Apple II or II+ machines (but not clones).
    Use an alternate European or custom 4K, 8K or 16K (top 8K only) video ROM for the original or Enhanced //e (but not clones).

    diff --git a/help/savestate.html b/help/savestate.html index b579bf52..33ad53a4 100644 --- a/help/savestate.html +++ b/help/savestate.html @@ -39,6 +39,7 @@
  • No-Slot clock (there's nothing to persist)
  • Using The Freeze's F8 ROM
  • Alternate F8 ROM
  • +
  • Alternate ROM
  • Alternate video ROM
  • Note: Only the file names of the disk images are stored in the .yaml file (not the diff --git a/resource/version.h b/resource/version.h index 0688de60..e7c78a31 100644 --- a/resource/version.h +++ b/resource/version.h @@ -1,4 +1,4 @@ -#define APPLEWIN_VERSION 1,29,10,0 +#define APPLEWIN_VERSION 1,29,11,0 #define xstr(a) str(a) #define str(a) #a diff --git a/source/Applewin.cpp b/source/Applewin.cpp index 480d72ef..9863081e 100644 --- a/source/Applewin.cpp +++ b/source/Applewin.cpp @@ -109,8 +109,10 @@ int g_nMemoryClearType = MIP_FF_FF_00_00; // Note: -1 = random MIP in Memory.c CardManager g_CardMgr; IPropertySheet& sg_PropertySheet = * new CPropertySheet; -HANDLE g_hCustomRomF8 = INVALID_HANDLE_VALUE; // Cmd-line specified custom ROM at $F800..$FFFF -static bool g_bCustomRomF8Failed = false; // Set if custom ROM file failed +HANDLE g_hCustomRomF8 = INVALID_HANDLE_VALUE; // Cmd-line specified custom F8 ROM at $F800..$FFFF +static bool g_bCustomRomF8Failed = false; // Set if custom F8 ROM file failed +HANDLE g_hCustomRom = INVALID_HANDLE_VALUE; // Cmd-line specified custom ROM at $C000..$FFFF(16KiB) or $D000..$FFFF(12KiB) +static bool g_bCustomRomFailed = false; // Set if custom ROM file failed static bool g_bEnableSpeech = false; #ifdef USE_SPEECH_API @@ -1541,6 +1543,18 @@ static bool ProcessCmdLine(LPSTR lpCmdLine) if ((g_hCustomRomF8 == INVALID_HANDLE_VALUE) || (GetFileSize(g_hCustomRomF8, NULL) != 0x800)) g_bCustomRomF8Failed = true; } + else if (strcmp(lpCmdLine, "-rom") == 0) // Use custom 16K at [$C000..$FFFF] or 12K ROM at [$D000..$FFFF] + { + lpCmdLine = GetCurrArg(lpNextArg); + lpNextArg = GetNextArg(lpNextArg); + + if (g_hCustomRom != INVALID_HANDLE_VALUE) // Stop resource leak if -rom is specified twice! + CloseHandle(g_hCustomRom); + + g_hCustomRom = CreateFile(lpCmdLine, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); + if ((g_hCustomRom == INVALID_HANDLE_VALUE) || ((GetFileSize(g_hCustomRom, NULL) != 0x4000) && (GetFileSize(g_hCustomRom, NULL) != 0x3000))) + g_bCustomRomFailed = true; + } else if (strcmp(lpCmdLine, "-videorom") == 0) // Use 2K (for II/II+). Use 4K,8K or 16K video ROM (for Enhanced //e) { lpCmdLine = GetCurrArg(lpNextArg); @@ -1957,9 +1971,12 @@ static void RepeatInitialization(void) g_cmdLine.bShutdown = true; } - if (g_bCustomRomF8Failed) + if (g_bCustomRomF8Failed || g_bCustomRomFailed || (g_hCustomRomF8 != INVALID_HANDLE_VALUE && g_hCustomRom != INVALID_HANDLE_VALUE)) { - std::string msg = "Failed to load custom F8 rom (not found or not exactly 2KiB)\n"; + std::string msg = g_bCustomRomF8Failed ? "Failed to load custom F8 rom (not found or not exactly 2KiB)\n" + : g_bCustomRomFailed ? "Failed to load custom rom (not found or not exactly 12KiB or 16KiB)\n" + : "Unsupported -rom and -f8rom being used at the same time\n"; + LogFileOutput("%s", msg.c_str()); MessageBox(g_hFrameWindow, msg.c_str(), TEXT("AppleWin Error"), MB_OK); g_cmdLine.bShutdown = true; @@ -2064,6 +2081,9 @@ static void Shutdown(void) if (g_hCustomRomF8 != INVALID_HANDLE_VALUE) CloseHandle(g_hCustomRomF8); + if (g_hCustomRom != INVALID_HANDLE_VALUE) + CloseHandle(g_hCustomRom); + if (g_cmdLine.bSlot7EmptyOnExit) UnplugHardDiskControllerCard(); } diff --git a/source/Applewin.h b/source/Applewin.h index a340f416..36a12974 100644 --- a/source/Applewin.h +++ b/source/Applewin.h @@ -54,7 +54,8 @@ extern int g_nMemoryClearType; // Cmd line switch: use specific MIP ( extern class CardManager g_CardMgr; -extern HANDLE g_hCustomRomF8; // NULL if no custom rom +extern HANDLE g_hCustomRomF8; // INVALID_HANDLE_VALUE if no custom F8 rom +extern HANDLE g_hCustomRom; // INVALID_HANDLE_VALUE if no custom rom #ifdef USE_SPEECH_API class CSpeech; diff --git a/source/Disk.cpp b/source/Disk.cpp index a505dc15..bc9ee963 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -1589,7 +1589,7 @@ void __stdcall Disk2InterfaceCard::LoadWriteProtect(WORD, WORD, BYTE write, BYTE const UINT bitCellDelta = GetBitCellDelta(uExecutedCycles); UpdateBitStreamPosition(floppy, bitCellDelta); // Fix E7-copy protection - // UpdateBitStreamPosition() must be done below ResetLSS, as the former clears m_resetSequencer. + // UpdateBitStreamPosition() must be done before ResetLSS, as the former clears m_resetSequencer (and the latter sets it). // . Commando.woz is sensitive to this. EG. It can crash after pressing 'J' (1 failure in 20 reboot repeats) ResetLogicStateSequencer(); // reset sequencer (UTAIIe page 9-21) } diff --git a/source/Memory.cpp b/source/Memory.cpp index cd968ee0..1315c9cb 100644 --- a/source/Memory.cpp +++ b/source/Memory.cpp @@ -1491,6 +1491,7 @@ void MemInitialize() CreateLanguageCard(); MemInitializeROM(); + MemInitializeCustomROM(); MemInitializeCustomF8ROM(); MemInitializeIO(); MemReset(); @@ -1608,15 +1609,14 @@ void MemInitializeCustomF8ROM(void) if (g_hCustomRomF8 != INVALID_HANDLE_VALUE) { - BYTE OldRom[Apple2RomSize]; // NB. 12KB on stack - memcpy(OldRom, memrom, Apple2RomSize); + std::vector oldRom(memrom, memrom+Apple2RomSize); // range ctor: [first,last) SetFilePointer(g_hCustomRomF8, 0, NULL, FILE_BEGIN); DWORD uNumBytesRead; BOOL bRes = ReadFile(g_hCustomRomF8, memrom+F8RomOffset, F8RomSize, &uNumBytesRead, NULL); if (uNumBytesRead != F8RomSize) { - memcpy(memrom, OldRom, Apple2RomSize); // ROM at $D000...$FFFF + memcpy(memrom, &oldRom[0], Apple2RomSize); // ROM at $D000...$FFFF bRes = FALSE; } @@ -1645,6 +1645,48 @@ void MemInitializeCustomF8ROM(void) } } +void MemInitializeCustomROM(void) +{ + if (g_hCustomRom == INVALID_HANDLE_VALUE) + return; + + SetFilePointer(g_hCustomRom, 0, NULL, FILE_BEGIN); + DWORD uNumBytesRead; + BOOL bRes = TRUE; + + if (GetFileSize(g_hCustomRom, NULL) == Apple2eRomSize) + { + std::vector oldRomC0(pCxRomInternal, pCxRomInternal+CxRomSize); // range ctor: [first,last) + bRes = ReadFile(g_hCustomRom, pCxRomInternal, CxRomSize, &uNumBytesRead, NULL); + if (uNumBytesRead != CxRomSize) + { + memcpy(pCxRomInternal, &oldRomC0[0], CxRomSize); // ROM at $C000...$CFFF + bRes = FALSE; + } + } + + if (bRes) + { + std::vector oldRom(memrom, memrom+Apple2RomSize); // range ctor: [first,last) + bRes = ReadFile(g_hCustomRom, memrom, Apple2RomSize, &uNumBytesRead, NULL); + if (uNumBytesRead != Apple2RomSize) + { + memcpy(memrom, &oldRom[0], Apple2RomSize); // ROM at $D000...$FFFF + bRes = FALSE; + } + } + + // NB. If succeeded, then keep g_hCustomRom handle open - so that any next restart can load it again + + if (!bRes) + { + MessageBox( g_hFrameWindow, "Failed to read custom rom", TEXT("AppleWin Error"), MB_OK ); + CloseHandle(g_hCustomRom); + g_hCustomRom = INVALID_HANDLE_VALUE; + // Failed, so use default rom... + } +} + // Called by: // . MemInitialize() // . Snapshot_LoadState_v2() diff --git a/source/Memory.h b/source/Memory.h index 7bff95f8..92fd978d 100644 --- a/source/Memory.h +++ b/source/Memory.h @@ -72,6 +72,7 @@ bool MemOptimizeForModeChanging(WORD programcounter, WORD address); bool MemIsAddrCodeMemory(const USHORT addr); void MemInitialize (); void MemInitializeROM(void); +void MemInitializeCustomROM(void); void MemInitializeCustomF8ROM(void); void MemInitializeIO(void); void MemInitializeCardExpansionRomFromSnapshot(void); diff --git a/source/SaveState.cpp b/source/SaveState.cpp index b83bfd14..33c57d2c 100644 --- a/source/SaveState.cpp +++ b/source/SaveState.cpp @@ -448,6 +448,7 @@ static void Snapshot_LoadState_v2(void) sg_PropertySheet.ApplyNewConfig(m_ConfigNew, ConfigOld); // Mainly just saves (some) new state to Registry MemInitializeROM(); + MemInitializeCustomROM(); MemInitializeCustomF8ROM(); MemInitializeIO(); MemInitializeCardExpansionRomFromSnapshot();