diff --git a/source/Disk.cpp b/source/Disk.cpp index 4ac08a95..4ddfbf36 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -1046,7 +1046,7 @@ void Disk2InterfaceCard::UpdateBitStreamOffsets(FloppyDisk& floppy) floppy.m_bitMask = 1 << remainder; } -void __stdcall Disk2InterfaceCard::ReadWriteWOZ(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG uExecutedCycles) +UINT Disk2InterfaceCard::DataLatchReadWriteCommonWOZ(ULONG uExecutedCycles) { /* m_floppyLoadMode = 0; */ FloppyDrive& drive = m_floppyDrive[m_currDrive]; @@ -1059,7 +1059,7 @@ void __stdcall Disk2InterfaceCard::ReadWriteWOZ(WORD pc, WORD addr, BYTE bWrite, { _ASSERT(0); // Can't happen for WOZ - ReadTrack() should return an empty track m_floppyLatch = 0xFF; - return; + return 0; } // Don't change latch if drive off after 1 second drive-off delay (UTAIIe page 9-13) @@ -1067,7 +1067,7 @@ void __stdcall Disk2InterfaceCard::ReadWriteWOZ(WORD pc, WORD addr, BYTE bWrite, // Note: Sherwood Forest sets shift mode and reads with the drive off. // TODO: And same for a write? if (!drive.m_spinning) // GH#599 - return; + return 0; CpuCalcCycles(uExecutedCycles); @@ -1095,118 +1095,145 @@ void __stdcall Disk2InterfaceCard::ReadWriteWOZ(WORD pc, WORD addr, BYTE bWrite, m_diskLastCycle = g_nCumulativeCycles; - // + return bitCellRemainder; +} - if (!m_floppyWriteMode) +void __stdcall Disk2InterfaceCard::DataLatchReadWOZ(WORD pc, WORD addr, BYTE d, ULONG uExecutedCycles) +{ + _ASSERT(!m_floppyWriteMode); + + const UINT bitCellRemainder = DataLatchReadWriteCommonWOZ(uExecutedCycles); + if (!bitCellRemainder) + return; + + // m_diskLastReadLatchCycle = g_nCumulativeCycles; // Not used by WOZ (only by NIB) + +#if LOG_DISK_NIBBLES_READ + bool newLatchData = false; +#endif + + FloppyDrive& drive = m_floppyDrive[m_currDrive]; + FloppyDisk& floppy = drive.m_disk; + + for (UINT i = 0; i < bitCellRemainder; i++) { - // m_diskLastReadLatchCycle = g_nCumulativeCycles; // Not used by WOZ (only by NIB) -#if LOG_DISK_NIBBLES_READ - bool newLatchData = false; -#endif + BYTE n = floppy.m_trackimage[floppy.m_byte]; - for (UINT i = 0; i < bitCellRemainder; i++) + drive.m_headWindow <<= 1; + drive.m_headWindow |= (n & floppy.m_bitMask) ? 1 : 0; + BYTE outputBit = (drive.m_headWindow & 0xf) ? (drive.m_headWindow >> 1) & 1 + : rand() & 1; + + floppy.m_bitMask >>= 1; + if (!floppy.m_bitMask) { - BYTE n = floppy.m_trackimage[floppy.m_byte]; + floppy.m_bitMask = 1 << 7; + floppy.m_byte++; + } - drive.m_headWindow <<= 1; - drive.m_headWindow |= (n & floppy.m_bitMask) ? 1 : 0; - BYTE outputBit = (drive.m_headWindow & 0xf) ? (drive.m_headWindow >> 1) & 1 - : rand() & 1; + floppy.m_bitOffset++; + if (floppy.m_bitOffset == floppy.m_bitCount) + { + floppy.m_bitMask = 1 << 7; + floppy.m_bitOffset = 0; + floppy.m_byte = 0; + } - floppy.m_bitMask >>= 1; - if (!floppy.m_bitMask) + if (m_resetSequencer) + { + m_resetSequencer = false; // LSS takes some cycles to reset (ref?) + continue; + } + + // + + m_shiftReg <<= 1; + m_shiftReg |= outputBit; + + if (m_latchDelay) + { + m_latchDelay -= 4; + if (m_latchDelay < 0) + m_latchDelay = 0; + + if (m_shiftReg) { - floppy.m_bitMask = 1 << 7; - floppy.m_byte++; + m_dbgLatchDelayedCnt = 0; } - - floppy.m_bitOffset++; - if (floppy.m_bitOffset == floppy.m_bitCount) + else // m_shiftReg==0 { - floppy.m_bitMask = 1 << 7; - floppy.m_bitOffset = 0; - floppy.m_byte = 0; - } + m_latchDelay += 4; // extend by 4us (so 7us again) - GH#662 - if (m_resetSequencer) - { - m_resetSequencer = false; // LSS takes some cycles to reset (ref?) - continue; - } - - // - - m_shiftReg <<= 1; - m_shiftReg |= outputBit; - - if (m_latchDelay) - { - m_latchDelay -= 4; - if (m_latchDelay < 0) - m_latchDelay = 0; - - if (m_shiftReg) - { - m_dbgLatchDelayedCnt = 0; - } - else // m_shiftReg==0 - { - m_latchDelay += 4; // extend by 4us (so 7us again) - GH#662 - - m_dbgLatchDelayedCnt++; + m_dbgLatchDelayedCnt++; #if LOG_DISK_NIBBLES_READ - if (m_dbgLatchDelayedCnt >= 3) - { - LOG_DISK("read: latch held due to 0: PC=%04X, cnt=%02X\r\n", regs.pc, m_dbgLatchDelayedCnt); - } -#endif - } - } - - if (!m_latchDelay) - { -#if LOG_DISK_NIBBLES_READ - if (newLatchData) + if (m_dbgLatchDelayedCnt >= 3) { - LOG_DISK("read skipped latch data: %04X = %02X\r\n", floppy.m_byte, m_floppyLatch); - newLatchData = false; + LOG_DISK("read: latch held due to 0: PC=%04X, cnt=%02X\r\n", regs.pc, m_dbgLatchDelayedCnt); } #endif - m_floppyLatch = m_shiftReg; - - if (m_shiftReg & 0x80) - { - m_latchDelay = 7; - m_shiftReg = 0; -#if LOG_DISK_NIBBLES_READ - // May not actually be read by 6502 (eg. Prologue's CHKSUM 4&4 nibble pair), but still pass to the log's nibble reader - m_formatTrack.DecodeLatchNibbleRead(m_floppyLatch); - newLatchData = true; -#endif - } } } -#if LOG_DISK_NIBBLES_READ - if (m_floppyLatch & 0x80) + if (!m_latchDelay) { - #if LOG_DISK_NIBBLES_USE_RUNTIME_VAR - if (m_bLogDisk_NibblesRW) - #endif +#if LOG_DISK_NIBBLES_READ + if (newLatchData) { - LOG_DISK("read %04X = %02X\r\n", floppy.m_byte, m_floppyLatch); + LOG_DISK("read skipped latch data: %04X = %02X\r\n", floppy.m_byte, m_floppyLatch); + newLatchData = false; + } +#endif + m_floppyLatch = m_shiftReg; + + if (m_shiftReg & 0x80) + { + m_latchDelay = 7; + m_shiftReg = 0; +#if LOG_DISK_NIBBLES_READ + // May not actually be read by 6502 (eg. Prologue's CHKSUM 4&4 nibble pair), but still pass to the log's nibble reader + m_formatTrack.DecodeLatchNibbleRead(m_floppyLatch); + newLatchData = true; +#endif } } -#endif } - else if (!floppy.m_bWriteProtected) // && m_floppyWriteMode + +#if LOG_DISK_NIBBLES_READ + if (m_floppyLatch & 0x80) + { +#if LOG_DISK_NIBBLES_USE_RUNTIME_VAR + if (m_bLogDisk_NibblesRW) +#endif + { + LOG_DISK("read %04X = %02X\r\n", floppy.m_byte, m_floppyLatch); + } + } +#endif + + // Show track status (GH#201) - NB. Prevent flooding of forcing UI to redraw!!! + if ((floppy.m_byte & 0xFF) == 0) + FrameDrawDiskStatus((HDC)0); +} + +void __stdcall Disk2InterfaceCard::DataLatchWriteWOZ(WORD pc, WORD addr, BYTE d, ULONG uExecutedCycles) +{ + _ASSERT(m_floppyWriteMode); + + const UINT bitCellRemainder = DataLatchReadWriteCommonWOZ(uExecutedCycles); + if (!bitCellRemainder) + return; + + FloppyDrive& drive = m_floppyDrive[m_currDrive]; + FloppyDisk& floppy = drive.m_disk; + + if (!floppy.m_bWriteProtected) { //TODO } // Show track status (GH#201) - NB. Prevent flooding of forcing UI to redraw!!! if ((floppy.m_byte & 0xFF) == 0) - FrameDrawDiskStatus( (HDC)0 ); + FrameDrawDiskStatus((HDC)0); } //=========================================================================== @@ -1516,9 +1543,7 @@ BYTE __stdcall Disk2InterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BYTE case 0x9: pCard->ControlMotor(pc, addr, bWrite, d, nExecutedCycles); break; case 0xA: pCard->Enable(pc, addr, bWrite, d, nExecutedCycles); break; case 0xB: pCard->Enable(pc, addr, bWrite, d, nExecutedCycles); break; - case 0xC: if (!isWOZ) pCard->ReadWrite(pc, addr, bWrite, d, nExecutedCycles); - else pCard->ReadWriteWOZ(pc, addr, bWrite, d, nExecutedCycles); - break; + case 0xC: if (!isWOZ) pCard->ReadWrite(pc, addr, bWrite, d, nExecutedCycles); break; case 0xD: pCard->LoadWriteProtect(pc, addr, bWrite, d, nExecutedCycles); break; case 0xE: pCard->SetReadMode(pc, addr, bWrite, d, nExecutedCycles); break; case 0xF: pCard->SetWriteMode(pc, addr, bWrite, d, nExecutedCycles); break; @@ -1526,9 +1551,14 @@ BYTE __stdcall Disk2InterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BYTE // only even addresses return the latch (UTAIIe Table 9.1) if (!(addr & 1)) + { + if (isWOZ) + pCard->DataLatchReadWOZ(pc, addr, d, nExecutedCycles); + return pCard->m_floppyLatch; - else - return MemReadFloatingBus(nExecutedCycles); + } + + return MemReadFloatingBus(nExecutedCycles); } BYTE __stdcall Disk2InterfaceCard::IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles) @@ -1553,9 +1583,7 @@ BYTE __stdcall Disk2InterfaceCard::IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE case 0x9: pCard->ControlMotor(pc, addr, bWrite, d, nExecutedCycles); break; case 0xA: pCard->Enable(pc, addr, bWrite, d, nExecutedCycles); break; case 0xB: pCard->Enable(pc, addr, bWrite, d, nExecutedCycles); break; - case 0xC: if (!isWOZ) pCard->ReadWrite(pc, addr, bWrite, d, nExecutedCycles); - else pCard->ReadWriteWOZ(pc, addr, bWrite, d, nExecutedCycles); - break; + case 0xC: if (!isWOZ) pCard->ReadWrite(pc, addr, bWrite, d, nExecutedCycles); break; case 0xD: pCard->LoadWriteProtect(pc, addr, bWrite, d, nExecutedCycles); break; case 0xE: pCard->SetReadMode(pc, addr, bWrite, d, nExecutedCycles); break; case 0xF: pCard->SetWriteMode(pc, addr, bWrite, d, nExecutedCycles); break; @@ -1565,7 +1593,11 @@ BYTE __stdcall Disk2InterfaceCard::IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE if (pCard->m_floppyWriteMode /* && m_floppyLoadMode */) { pCard->m_floppyLatch = d; + + if (isWOZ) + pCard->DataLatchWriteWOZ(pc, addr, d, nExecutedCycles); } + return 0; } diff --git a/source/Disk.h b/source/Disk.h index 6a2aacc3..4ceab3a8 100644 --- a/source/Disk.h +++ b/source/Disk.h @@ -188,6 +188,7 @@ private: UINT GetBitCellDelta(const BYTE optimalBitTiming); void UpdateBitStreamPosition(FloppyDisk& floppy, const ULONG bitCellDelta); void UpdateBitStreamOffsets(FloppyDisk& floppy); + UINT DataLatchReadWriteCommonWOZ(ULONG uExecutedCycles); void SaveSnapshotFloppy(YamlSaveHelper& yamlSaveHelper, UINT unit); void SaveSnapshotDriveUnit(YamlSaveHelper& yamlSaveHelper, UINT unit); bool LoadSnapshotFloppy(YamlLoadHelper& yamlLoadHelper, UINT unit, UINT version, std::vector& track); @@ -199,7 +200,8 @@ private: void __stdcall ControlMotor(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles); void __stdcall Enable(WORD, WORD address, BYTE, BYTE, ULONG uExecutedCycles); void __stdcall ReadWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG uExecutedCycles); - void __stdcall ReadWriteWOZ(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG uExecutedCycles); + void __stdcall DataLatchReadWOZ(WORD pc, WORD addr, BYTE d, ULONG uExecutedCycles); + void __stdcall DataLatchWriteWOZ(WORD pc, WORD addr, BYTE d, ULONG uExecutedCycles); void __stdcall LoadWriteProtect(WORD, WORD, BYTE write, BYTE value, ULONG); void __stdcall SetReadMode(WORD, WORD, BYTE, BYTE, ULONG); void __stdcall SetWriteMode(WORD, WORD, BYTE, BYTE, ULONG uExecutedCycles);