HDD: change writes so they are done in units of PAGE_SIZE(256B) to match reads

. making it easier to reason about DMA breakpoints (as they are now consistent for reads & writes)
This commit is contained in:
tomcw 2022-06-05 19:41:06 +01:00
parent 80c1150183
commit bb56b99af5
1 changed files with 22 additions and 27 deletions

View File

@ -462,6 +462,7 @@ BYTE __stdcall HarddiskInterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BY
CpuCalcCycles(nExecutedCycles);
const UINT CYCLES_FOR_DMA_RW_BLOCK = HD_BLOCK_SIZE;
const UINT PAGE_SIZE = 256;
BYTE r = DEVICE_OK;
pHDD->m_status_next = DISK_STATUS_READ;
@ -486,17 +487,15 @@ BYTE __stdcall HarddiskInterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BY
case 0x01: //read
if ((pHDD->m_diskblock * HD_BLOCK_SIZE) < ImageGetImageSize(pHDD->m_imagehandle))
{
bool breakpointHit = false;
bool bRes = ImageReadBlock(pHDD->m_imagehandle, pHDD->m_diskblock, pHDD->m_buf);
if (bRes)
{
pHDD->m_error = 0;
r = 0;
pCard->m_notBusyCycle = g_nCumulativeCycles + (UINT64)CYCLES_FOR_DMA_RW_BLOCK;
pHDD->m_buf_ptr = 0;
// Apple II's MMU could be setup so that read & write memory is different,
// so can't use 'mem' (like we can for HDD block writes)
const UINT PAGE_SIZE = 256;
WORD dstAddr = pHDD->m_memblock;
UINT remaining = HD_BLOCK_SIZE;
BYTE* pSrc = pHDD->m_buf;
@ -511,7 +510,6 @@ BYTE __stdcall HarddiskInterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BY
DebuggerBreakOnDmaToOrFromIoMemory(dstAddr, true); // GH#1007
//else // Show MessageBox?
pCard->m_notBusyCycle = 0; // DMA complete
bRes = false;
break;
}
@ -521,13 +519,7 @@ BYTE __stdcall HarddiskInterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BY
if (size > remaining) size = remaining; // clip the last memcpy for the unaligned case
if (g_nAppMode == MODE_STEPPING)
{
if (DebuggerCheckMemBreakpoints(dstAddr, size, true)) // GH#1103
{
// BP hit
pCard->m_notBusyCycle = 0; // DMA complete
}
}
breakpointHit = DebuggerCheckMemBreakpoints(dstAddr, size, true); // GH#1103
memcpy(page + (dstAddr & 0xff), pSrc, size);
pSrc += size;
@ -537,7 +529,15 @@ BYTE __stdcall HarddiskInterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BY
}
}
if (!bRes)
if (bRes)
{
pHDD->m_error = 0;
r = 0;
if (!breakpointHit)
pCard->m_notBusyCycle = g_nCumulativeCycles + (UINT64)CYCLES_FOR_DMA_RW_BLOCK;
}
else
{
pHDD->m_error = 1;
r = DEVICE_IO_ERROR;
@ -581,33 +581,28 @@ BYTE __stdcall HarddiskInterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BY
DebuggerBreakOnDmaToOrFromIoMemory(dstAddr, false);
//else // Show MessageBox?
pCard->m_notBusyCycle = 0; // DMA complete
bRes = false;
}
else
{
UINT size = HD_BLOCK_SIZE;
// NB. Do the writes in units of PAGE_SIZE so that DMA breakpoints are consistent with reads
WORD srcAddr = pHDD->m_memblock;
UINT remaining = HD_BLOCK_SIZE;
BYTE* pDst = pHDD->m_buf;
if (pHDD->m_memblock > (MEMORY_LENGTH - HD_BLOCK_SIZE)) // wraps at 64KiB boundary (GH#1007)
size = MEMORY_LENGTH - pHDD->m_memblock;
if (g_nAppMode == MODE_STEPPING)
breakpointHit = DebuggerCheckMemBreakpoints(srcAddr, size, false);
memcpy(pDst, mem + srcAddr, size);
if (HD_BLOCK_SIZE != size)
while (remaining)
{
pDst += size;
size = HD_BLOCK_SIZE - size;
srcAddr = 0x0000; // wrap around to 0x0000
UINT size = PAGE_SIZE - (srcAddr & 0xff);
if (size > remaining) size = remaining; // clip the last memcpy for the unaligned case
if (g_nAppMode == MODE_STEPPING)
breakpointHit = DebuggerCheckMemBreakpoints(srcAddr, size, false);
memcpy(pDst, mem + srcAddr, size);
pDst += size;
srcAddr = (srcAddr + size) & (MEMORY_LENGTH - 1); // wraps at 64KiB boundary
remaining -= size;
}
}