diff --git a/bin/History.txt b/bin/History.txt index 7eaeeef0..152f821a 100644 --- a/bin/History.txt +++ b/bin/History.txt @@ -8,6 +8,12 @@ https://github.com/AppleWin/AppleWin/issues/new Tom Charlesworth +1.27.9.0 - 2 Oct 2018 +--------------------- +. [Bug #582] Support for partial disk II latch reads when accesses are very close. + - Fixes Curse of the Azure Bonds & Pool of Radiance (saving characters and creating disks). + + 1.27.8.0 - 9 Sep 2018 --------------------- . [Bug #555] Fix for showing 559th DHGR/DGR/TEXT80 vertical column (retaining 560-pixel display width). diff --git a/resource/Applewin.rc b/resource/Applewin.rc index 88b11363..8d985736 100644 --- a/resource/Applewin.rc +++ b/resource/Applewin.rc @@ -252,8 +252,8 @@ DISK_ICON ICON "DISK.ICO" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,27,8,0 - PRODUCTVERSION 1,27,8,0 + FILEVERSION 1,27,9,0 + PRODUCTVERSION 1,27,9,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -271,12 +271,12 @@ BEGIN VALUE "Comments", "https://github.com/AppleWin" VALUE "CompanyName", "AppleWin" VALUE "FileDescription", "Apple //e Emulator for Windows" - VALUE "FileVersion", "1, 27, 8, 0" + VALUE "FileVersion", "1, 27, 9, 0" VALUE "InternalName", "APPLEWIN" VALUE "LegalCopyright", " 1994-2018 Michael O'Brien, Oliver Schmidt, Tom Charlesworth, Michael Pohoreski, Nick Westgate, Linards Ticmanis" VALUE "OriginalFilename", "APPLEWIN.EXE" VALUE "ProductName", "Apple //e Emulator" - VALUE "ProductVersion", "1, 27, 8, 0" + VALUE "ProductVersion", "1, 27, 9, 0" END END BLOCK "VarFileInfo" diff --git a/source/Applewin.cpp b/source/Applewin.cpp index 5fa5dce3..6ec6a619 100644 --- a/source/Applewin.cpp +++ b/source/Applewin.cpp @@ -129,13 +129,16 @@ void LogFileTimeUntilFirstKeyReadReset(void) } // Log the time from emulation restart/reboot until the first key read: BIT $C000 -// . NB. AZTEC.DSK does prior LDY $C000 reads, but the BIT $C000 is at the "Press any key" message +// . AZTEC.DSK (DOS 3.3) does prior LDY $C000 reads, but the BIT $C000 is at the "Press any key" message +// . Phasor1.dsk / ProDOS 1.1.1: PC=E797: B1 50: LDA ($50),Y / "Select an Option:" message void LogFileTimeUntilFirstKeyRead(void) { if (!g_fh || bLogKeyReadDone) return; - if (mem[regs.pc-3] != 0x2C) // bit $c000 + if ( (mem[regs.pc-3] != 0x2C) // AZTEC: bit $c000 + && !((regs.pc-2) == 0xE797 && mem[regs.pc-2] == 0xB1 && mem[regs.pc-1] == 0x50) // Phasor1: lda ($50),y + ) return; DWORD dwTime = GetTickCount() - dwLogKeyReadTickStart; diff --git a/source/Debugger/Debugger_Display.cpp b/source/Debugger/Debugger_Display.cpp index eaf033dc..63a34037 100644 --- a/source/Debugger/Debugger_Display.cpp +++ b/source/Debugger/Debugger_Display.cpp @@ -1493,7 +1493,7 @@ int GetDisassemblyLine ( WORD nBaseAddress, DisasmLine_t & line_ ) if (! (bDisasmFormatFlags & DISASM_FORMAT_SYMBOL)) { - pTarget = FormatAddress( nTarget, nOpbyte ); + pTarget = FormatAddress( nTarget, (iOpmode != AM_R) ? nOpbyte : 3 ); // GH#587: For Bcc opcodes, pretend it's a 3-byte opcode to print a 16-bit target addr } // sprintf( sTarget, g_aOpmodes[ iOpmode ]._sFormat, pTarget ); diff --git a/source/Disk.cpp b/source/Disk.cpp index f81002a9..d3998ae7 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -86,6 +86,7 @@ static WORD phases = 0; // state bits for stepper magnet phases 0 - 3 static bool g_bSaveDiskImage = true; // Save the DiskImage name to Registry static UINT g_uSlot = 0; static unsigned __int64 g_uDiskLastCycle = 0; +static unsigned __int64 g_uDiskLastReadLatchCycle = 0; static FormatTrack g_formatTrack; static bool IsDriveValid( const int iDrive ); @@ -895,7 +896,23 @@ static void __stdcall DiskReadWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULO // but Sherwood Forest sets shift mode and reads with the drive off, so don't check for now if (!floppywritemode) { + const ULONG nReadCycleDiff = (ULONG) (g_nCumulativeCycles - g_uDiskLastReadLatchCycle); + + // Support partial nibble read if disk reads are very close: (GH#582) + // . 6 cycles (1st->2nd read) for DOS 3.3 / $BD34: "read with delays to see if disk is spinning." (Beneath Apple DOS) + // . 6 cycles (1st->2nd read) for Curse of the Azure Bonds (loop to see if disk is spinning) + // . 31 cycles is the max for a partial 8-bit nibble + const ULONG kReadAccessThreshold = enhancedisk ? 6 : 31; + + if (nReadCycleDiff <= kReadAccessThreshold) + { + UINT invalidBits = 8 - (nReadCycleDiff / 4); // 4 cycles per bit-cell + floppylatch = *(pFloppy->trackimage + pFloppy->byte) >> invalidBits; + return; // Early return so don't update: g_uDiskLastReadLatchCycle & pFloppy->byte + } + floppylatch = *(pFloppy->trackimage + pFloppy->byte); + g_uDiskLastReadLatchCycle = g_nCumulativeCycles; #if LOG_DISK_NIBBLES_READ #if LOG_DISK_NIBBLES_USE_RUNTIME_VAR @@ -959,6 +976,10 @@ void DiskReset(const bool bIsPowerCycle/*=false*/) if (bIsPowerCycle) // GH#460 { + // NB. This doesn't affect the drive head (ie. drive's track position) + // . The initial machine start-up state is track=0, but after a power-cycle the track could be any value. + // . (For DiskII firmware, this results in a subtle extra latch read in this latter case, for the track!=0 case) + g_aFloppyDrive[DRIVE_1].spinning = 0; g_aFloppyDrive[DRIVE_1].writelight = 0; g_aFloppyDrive[DRIVE_2].spinning = 0; @@ -1363,7 +1384,8 @@ int DiskSetSnapshot_v1(const SS_CARD_DISK2* const pSS) // Unit version history: // 2: Added: Format Track state & DiskLastCycle -static const UINT kUNIT_VERSION = 2; +// 3: Added: DiskLastReadLatchCycle +static const UINT kUNIT_VERSION = 3; #define SS_YAML_VALUE_CARD_DISK2 "Disk][" @@ -1375,6 +1397,7 @@ static const UINT kUNIT_VERSION = 2; #define SS_YAML_KEY_FLOPPY_MOTOR_ON "Floppy Motor On" #define SS_YAML_KEY_FLOPPY_WRITE_MODE "Floppy Write Mode" #define SS_YAML_KEY_LAST_CYCLE "Last Cycle" +#define SS_YAML_KEY_LAST_READ_LATCH_CYCLE "Last Read Latch Cycle" #define SS_YAML_KEY_DISK2UNIT "Unit" #define SS_YAML_KEY_FILENAME "Filename" @@ -1429,6 +1452,7 @@ void DiskSaveSnapshot(class YamlSaveHelper& yamlSaveHelper) yamlSaveHelper.SaveBool(SS_YAML_KEY_FLOPPY_MOTOR_ON, floppymotoron == TRUE); yamlSaveHelper.SaveBool(SS_YAML_KEY_FLOPPY_WRITE_MODE, floppywritemode == TRUE); yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_LAST_CYCLE, g_uDiskLastCycle); // v2 + yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_LAST_READ_LATCH_CYCLE, g_uDiskLastReadLatchCycle); // v3 g_formatTrack.SaveSnapshot(yamlSaveHelper); // v2 DiskSaveSnapshotDisk2Unit(yamlSaveHelper, DRIVE_1); @@ -1534,6 +1558,11 @@ bool DiskLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT vers g_formatTrack.LoadSnapshot(yamlLoadHelper); } + if (version >= 3) + { + g_uDiskLastReadLatchCycle = yamlLoadHelper.LoadUint64(SS_YAML_KEY_LAST_READ_LATCH_CYCLE); + } + // Eject all disks first in case Drive-2 contains disk to be inserted into Drive-1 for(UINT i=0; i= 4) && (address <= 5) && ((*(LPDWORD)(mem+programcounter) & 0x00FFFEFF) == 0x00C0028D)) { modechanging = 1; diff --git a/source/NTSC.cpp b/source/NTSC.cpp index 007ea275..ae0b1503 100644 --- a/source/NTSC.cpp +++ b/source/NTSC.cpp @@ -24,7 +24,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Applewin.h" #include "CPU.h" // CpuGetCyclesThisVideoFrame() #include "Frame.h" - #include "Memory.h" // MemGetMainPtr() MemGetBankPtr() + #include "Memory.h" // MemGetMainPtr() MemGetAuxPtr() #include "Video.h" // g_pFramebufferbits #include "NTSC.h"