From 54e92986a519785e4310d7ccdcaf7d03b81a3d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20M=C3=A5rtensson?= Date: Thu, 12 Mar 2026 17:52:03 +0100 Subject: [PATCH 1/2] Fix for handle 256bytes sectors format not to use fast seek which will add wrong data into the buffer --- src/BlueSCSI_disk.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BlueSCSI_disk.cpp b/src/BlueSCSI_disk.cpp index ecf28777..a61e76e5 100644 --- a/src/BlueSCSI_disk.cpp +++ b/src/BlueSCSI_disk.cpp @@ -2237,11 +2237,11 @@ static void start_dataInTransfer(uint8_t *buffer, uint32_t count) // Use direct sector I/O when fastseek is enabled (for fragmented files) // Contiguous files already use raw SD access, bypassing this path bool read_ok = false; - if (img.file.isFastSeekEnabled()) + uint32_t sectorCount = count >> 9; + if (img.file.isFastSeekEnabled() && sectorCount > 0) { // Convert byte position/count to sector units (>> 9 is / 512) uint32_t fileSector = img.file.position() >> 9; - uint32_t sectorCount = count >> 9; uint32_t sectorsRead = img.file.readSectorsDirect(fileSector, buffer, sectorCount); read_ok = (sectorsRead == sectorCount); if (read_ok) From 9b53261c92b78880a3b50887469b79f819546180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20M=C3=A5rtensson?= Date: Fri, 13 Mar 2026 09:15:22 +0100 Subject: [PATCH 2/2] More fixes for 256bytes sectors --- src/BlueSCSI_disk.cpp | 23 +++++++++++++++++++---- src/ImageBackingStore.cpp | 7 +++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/BlueSCSI_disk.cpp b/src/BlueSCSI_disk.cpp index a61e76e5..1479734d 100644 --- a/src/BlueSCSI_disk.cpp +++ b/src/BlueSCSI_disk.cpp @@ -2238,16 +2238,31 @@ static void start_dataInTransfer(uint8_t *buffer, uint32_t count) // Contiguous files already use raw SD access, bypassing this path bool read_ok = false; uint32_t sectorCount = count >> 9; - if (img.file.isFastSeekEnabled() && sectorCount > 0) + uint64_t filePos = img.file.position(); + bool posAligned = ((uint32_t)filePos % SD_SECTOR_SIZE) == 0; + if (img.file.isFastSeekEnabled() && sectorCount > 0 && posAligned) { // Convert byte position/count to sector units (>> 9 is / 512) - uint32_t fileSector = img.file.position() >> 9; + uint32_t fileSector = (uint32_t)filePos >> 9; uint32_t sectorsRead = img.file.readSectorsDirect(fileSector, buffer, sectorCount); read_ok = (sectorsRead == sectorCount); if (read_ok) { - // readSectorsDirect does NOT advance file position - do it manually - img.file.seek(img.file.position() + count); + uint32_t fullBytes = sectorCount * 512; + uint32_t remaining = count - fullBytes; + if (remaining > 0) + { + // Partial SD sector at end (e.g. odd number of 256-byte SCSI sectors) + // readSectorsDirect does NOT advance position, so seek past full sectors + // then use filesystem read for the remainder + img.file.seek(filePos + fullBytes); + read_ok = ((uint32_t)img.file.read(buffer + fullBytes, remaining) == remaining); + } + else + { + // readSectorsDirect does NOT advance file position - do it manually + img.file.seek(filePos + count); + } } } else diff --git a/src/ImageBackingStore.cpp b/src/ImageBackingStore.cpp index a6aee554..73bf61e1 100644 --- a/src/ImageBackingStore.cpp +++ b/src/ImageBackingStore.cpp @@ -303,6 +303,13 @@ ssize_t ImageBackingStore::read(void* buf, size_t count) uint32_t sectorcount = count / SD_SECTOR_SIZE; if (m_iscontiguous && (uint64_t)sectorcount * SD_SECTOR_SIZE != count) { + // Keep FsFile and raw-sector cursor in sync before changing access mode. + uint64_t pos = (uint64_t)(m_cursector - m_bgnsector) * SD_SECTOR_SIZE; + if (!m_israw && m_fsfile.isOpen() && !m_fsfile.seek(pos)) + { + logmsg("---- Failed to sync FsFile position during contiguous read fallback"); + return -1; + } dbgmsg("---- Unaligned access to image, falling back to SdFat access mode"); m_iscontiguous = false; }