diff --git a/bin/History.txt b/bin/History.txt index cb358a3e..3918bdff 100644 --- a/bin/History.txt +++ b/bin/History.txt @@ -10,16 +10,24 @@ Tom Charlesworth 1.29.3.0 - 12 Oct 2019 ---------------------- -. [Bug #700] Fixed ProDOS8 2.5.0 alpha6 (support INC $C08B to set LC to write mode). +. [Change #692] Added command line switch to unplug HDD controller card on exit: + - -s7-empty-on-exit +. [Change #689] Added command line switches to set CPU speed and machine type: + - -clock-multiplier , where value is a [0.5-3.9] base-clock multiplier (ie. same as the Config UI's slider) + - -model +. [Change #666] Debugger: support showing video v,h and cycle count. + - videoinfo to configure display. + - added auto-run of DebuggerAutoRun.txt on AppleWin initial start-up. +. [Bug #700] Fixed ProDOS8 2.5.0 alpha6: + - support INC $C08B (and similar) to set LC to write mode - 65C02 only. + - support INC $C08B,X (X=0) to set LC to write mode - 6502/65C02/816. (Fixes #404) . [Bug #695] Fixed WOZ 'Taipan' not booting. - fixed reading write protect on a write access & support Sequencer Function. . [Bug #668] Fixed WOZ 'Seafox' not booting. - set machine = Unenhanced Apple //e or lower & need slot2 empty. - - disable SSC in slot-2 using: '-s2 empty' command line. + - disable SSC in slot-2 using: '-s2 empty' command line switch. - added '-s1 empty', '-s3 empty' and '-s6 empty' too. -. [Bug #666] Debugger: support showing video v,h and cycle count. - - videoinfo to configure display. - - added auto-run of DebuggerAutoRun.txt on AppleWin initial start-up. +. [Bug #404] a2audit.dsk 1.06 now working. (See #700) . [Bug #319] SmartPort return address was wrong when crossing page (fix to slot-7 HDD's firmware). . [PR #687] Replace char * with std::string. diff --git a/help/CommandLine.html b/help/CommandLine.html index 8a396b01..831b7cf9 100644 --- a/help/CommandLine.html +++ b/help/CommandLine.html @@ -19,6 +19,10 @@ Start with hard disk 1 plugged-in (and auto power-on the Apple II). NB. Hard disk controller card gets enabled.

-h2 <pathname>
Start with hard disk 2 plugged-in. NB. Hard disk controller card gets enabled.

+ -model <apple2|apple2p|apple2e|apple2ee>
+ Select the machine model: Apple II, Apple II+, Apple //e, Enhanced Apple //e.

+ -clock-multiplier <value>
+ Where value is between 0.5 and 3.9, and is a base-clock multiplier, roughly mapping to 0.5MHz - 3.9MHz

-s0 <saturn|saturn64|saturn128>
Insert a Saturn 64K or Saturn 128K card into slot 0 in the Apple II or II+ machines (or similar clone).
Where -s0 saturn is an alias for -s0 saturn128.

@@ -36,6 +40,8 @@ -s7 empty
Remove the hard disk controller card from slot 7.
Useful to allow a floppy disk to boot from slot 6, drive 1. Use in combination with -d1.

+ -s7-empty-on-exit
+ Remove the hard disk controller card from slot 7 on AppleWin exit.

-r <number of pages>
Emulate a RamWorks III card with 1 to 127 pages (each page is 64K, giving a max of 8MB) in the auxiliary slot in an Apple //e machine.

-load-state <savestate>
diff --git a/source/Applewin.cpp b/source/Applewin.cpp index 5d028141..b6cd6409 100644 --- a/source/Applewin.cpp +++ b/source/Applewin.cpp @@ -392,6 +392,27 @@ double Get6502BaseClock(void) return (GetVideoRefreshRate() == VR_50HZ) ? CLK_6502_PAL : CLK_6502_NTSC; } +void UseClockMultiplier(double clockMultiplier) +{ + if (clockMultiplier == 0.0) + return; + + if (clockMultiplier < 1.0) + { + if (clockMultiplier < 0.5) + clockMultiplier = 0.5; + g_dwSpeed = (ULONG)((clockMultiplier - 0.5) * 20); // [0.5..0.9] -> [0..9] + } + else + { + g_dwSpeed = (ULONG)(clockMultiplier * 10); + if (g_dwSpeed >= SPEED_MAX) + g_dwSpeed = SPEED_MAX - 1; + } + + SetCurrentCLK6502(); +} + void SetCurrentCLK6502(void) { static DWORD dwPrevSpeed = (DWORD) -1; @@ -1168,6 +1189,18 @@ static void InsertHardDisks(LPSTR szImageName_harddisk[NUM_HARDDISKS], bool& bBo MessageBox(g_hFrameWindow, "Failed to insert harddisk(s) - see log file", "Warning", MB_ICONASTERISK | MB_OK); } +static void UnplugHardDiskControllerCard(void) +{ + HD_SetEnabled(false); + + DWORD dwTmp; + if (REGLOAD(TEXT(REGVALUE_HDD_ENABLED), &dwTmp)) + { + if (dwTmp) + REGSAVE(TEXT(REGVALUE_HDD_ENABLED), 0); // Config: HDD Disabled + } +} + static bool CheckOldAppleWinVersion(void) { TCHAR szOldAppleWinVersion[VERSIONSTRING_SIZE + 1]; @@ -1202,6 +1235,7 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) bool bChangedDisplayResolution = false; bool bSlot0LanguageCard = false; bool bSlotEmpty[NUM_SLOTS] = {false,false,false,false,false,false,false,false}; + bool bSlot7EmptyOnExit = false; UINT bestWidth = 0, bestHeight = 0; LPSTR szImageName_drive[NUM_DRIVES] = {NULL,NULL}; LPSTR szImageName_harddisk[NUM_HARDDISKS] = {NULL,NULL}; @@ -1214,6 +1248,8 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) int newVideoStyleDisableMask = 0; VideoRefreshRate_e newVideoRefreshRate = VR_NONE; LPSTR szScreenshotFilename = NULL; + double clockMultiplier = 0.0; // 0 => not set from cmd-line + eApple2Type model = A2TYPE_MAX; while (*lpCmdLine) { @@ -1259,6 +1295,10 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) if (strcmp(lpCmdLine, "empty") == 0) bSlotEmpty[slot] = true; } + else if (strcmp(lpCmdLine, "-s7-empty-on-exit") == 0) + { + bSlot7EmptyOnExit = true; + } else if (strcmp(lpCmdLine, "-load-state") == 0) { lpCmdLine = GetCurrArg(lpNextArg); @@ -1460,6 +1500,28 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) szScreenshotFilename = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); } + else if (strcmp(lpCmdLine, "-clock-multiplier") == 0) + { + lpCmdLine = GetCurrArg(lpNextArg); + lpNextArg = GetNextArg(lpNextArg); + clockMultiplier = atof(lpCmdLine); + } + else if (strcmp(lpCmdLine, "-model") == 0) + { + lpCmdLine = GetCurrArg(lpNextArg); + lpNextArg = GetNextArg(lpNextArg); + + if (strcmp(lpCmdLine, "apple2") == 0) + model = A2TYPE_APPLE2; + else if (strcmp(lpCmdLine, "apple2p") == 0) + model = A2TYPE_APPLE2PLUS; + else if (strcmp(lpCmdLine, "apple2e") == 0) + model = A2TYPE_APPLE2E; + else if (strcmp(lpCmdLine, "apple2ee") == 0) + model = A2TYPE_APPLE2EENHANCED; + else + LogFileOutput("-model: unsupported type: %s\n", lpCmdLine); + } else if (_stricmp(lpCmdLine, "-50hz") == 0) // (case-insensitive) { newVideoRefreshRate = VR_50HZ; @@ -1580,6 +1642,9 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) LoadConfiguration(); LogFileOutput("Main: LoadConfiguration()\n"); + if (model != A2TYPE_MAX) + SetApple2Type(model); + if (newVideoType >= 0) { SetVideoType( (VideoType_e)newVideoType ); @@ -1594,6 +1659,9 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) SetCurrentCLK6502(); } + UseClockMultiplier(clockMultiplier); + clockMultiplier = 0.0; + // Apply the memory expansion switches after loading the Apple II machine type #ifdef RAMWORKS if (uRamWorksExPages) @@ -1819,5 +1887,8 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) if (g_hCustomRomF8 != INVALID_HANDLE_VALUE) CloseHandle(g_hCustomRomF8); + if (bSlot7EmptyOnExit) + UnplugHardDiskControllerCard(); + return 0; } diff --git a/source/Disk.cpp b/source/Disk.cpp index fdae09b5..2aefe359 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -1455,7 +1455,7 @@ bool Disk2InterfaceCard::UserSelectNewDiskImage(const int drive, LPCSTR pszFilen void __stdcall Disk2InterfaceCard::LoadWriteProtect(WORD, WORD, BYTE write, BYTE value, ULONG uExecutedCycles) { - _ASSERT(m_seqFunc.function == checkWriteProtAndInitWrite); + // NB. m_seqFunc.function == checkWriteProtAndInitWrite or shiftWrite (both OK) // Don't change latch if drive off after 1 second drive-off delay (UTAIIe page 9-13) // "DRIVES OFF forces the data register to hold its present state." (UTAIIe page 9-12) @@ -1651,7 +1651,7 @@ void Disk2InterfaceCard::SetSequencerFunction(WORD addr) if ((addr & 0xf) < 0xc) return; - switch (addr & 3) + switch ((addr & 3) ^ 2) { case 0: m_seqFunc.writeMode = 0; break; // $C08E,X (sequence addr A2 input) case 1: m_seqFunc.writeMode = 1; break; // $C08F,X (sequence addr A2 input) diff --git a/source/LanguageCard.cpp b/source/LanguageCard.cpp index 090835eb..f39a4141 100644 --- a/source/LanguageCard.cpp +++ b/source/LanguageCard.cpp @@ -103,7 +103,6 @@ BYTE __stdcall LanguageCardUnit::IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValu return bWrite ? 0 : MemReadFloatingBus(nExecutedCycles); } -// GH#700: INC $C083/C08B (RMW) to write enable the LC bool LanguageCardUnit::IsOpcodeRMWabs(WORD addr) { BYTE param1 = mem[(regs.pc - 2) & 0xffff]; @@ -111,7 +110,15 @@ bool LanguageCardUnit::IsOpcodeRMWabs(WORD addr) 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]; + if (opcode == 0xFE && regs.x == 0) // INC abs,x + return true; + + // GH#700: INC $C083/C08B (RMW) to write enable the LC (65C02 only) + if (GetMainCpu() != CPU_65C02) + return false; + if (opcode == 0xEE || // INC abs opcode == 0xCE || // DEC abs opcode == 0x6E || // ROR abs @@ -120,9 +127,8 @@ bool LanguageCardUnit::IsOpcodeRMWabs(WORD addr) opcode == 0x0E) // ASL abs return true; - if ((GetMainCpu() == CPU_65C02) && ( - opcode == 0x1C || // TRB abs - opcode == 0x0C)) // TSB abs + if (opcode == 0x1C || // TRB abs + opcode == 0x0C) // TSB abs return true; return false;