Bug fixes

This commit is contained in:
Philip Smart
2026-04-30 13:58:33 +01:00
parent 0ae9764e77
commit 516426a8c7
5 changed files with 54 additions and 26 deletions

View File

@@ -2937,8 +2937,7 @@ uint8_t __func_in_RAM(Z80CPU_fetchOpcode)(void *context, uint16_t address)
// DRAM refresh: when fetching opcodes from virtual memory, the physical M1 cycle
// (which includes a RFSH bus cycle) is not generated. Physical DRAM on the host
// motherboard will decay without a refresh. Trigger a full M1 cycle but ignore
// the read opcode.
// motherboard will decay without a refresh.
if(cpu->refreshEnable)
{
Z80CPU_refreshDRAM(context, true, address, data);
@@ -3578,16 +3577,6 @@ uint8_t __func_in_RAM(Z80CPU_refreshDRAM)(void *context, bool read, uint16_t add
// Wait until the previous cycle completes before commencing new cycle.
WAIT_IRQ_SET(pio_1, smCycle);
// // No waiting, we just push 8 instructions which form T1/T2 and exit.
// PUSH_INSTR32(pio_1,
// smCycle,
// 0xfc0e, // set pins, 14 side 3 Set /M1 low
// 0x2013); // T1 wait 0 gpio, 35
// PUSH_INSTR32(pio_1,
// smCycle,
// 0xf80a, // set pins, 10 side 2 Set /M1 low, /MREQ low, /RD low
// (0x0000 + offsetCycle + 6)); // jmp offset+6, wait state loop.
// Push initial instructions to setup pin inactive state then execute the Refresh T3/T4 cycles.
PUSH_INSTR32(pio_1,
smCycle,

View File

@@ -925,8 +925,7 @@ uint8_t MZ80A_Init(t_Z80CPU *cpu, t_FlashAppConfigHeader *appConfig, t_drvConfig
// When the driver is PHYSICAL, interface ROM loading (MZ80A_readROMData) may have
// changed F000-FFFF from PHYSICAL to ROM type. Restore to PHYSICAL so the hardware
// ROM is used — virtual ROM + physical FDC hardware doesn't work because the virtual
// WD1773 DRQ can't toggle the real hardware's A10 line.
// ROM is used — the physical FDC hardware handles DRQ/A10 directly on the bus.
if (config->isPhysical)
{
for (int idx = 0xF000 / MEMORY_BLOCK_SIZE; idx < 0x10000 / MEMORY_BLOCK_SIZE; idx++)
@@ -934,6 +933,31 @@ uint8_t MZ80A_Init(t_Z80CPU *cpu, t_FlashAppConfigHeader *appConfig, t_drvConfig
cpu->_membankPtr[idx] = (MEMBANK_TYPE_PHYSICAL << 24) | (MZ80A_MEMBANK_0 << 16) | (idx * MEMORY_BLOCK_SIZE);
}
}
else
{
// VIRTUAL driver + PHYSICAL MZ80AFI interface: the floppy ROM is in virtual RAM
// but the FDC is physical hardware. Install a software A10 toggle handler that
// reads DRQ from the physical WD1773 to bridge the gap.
for (int ifIdx2 = 0; ifIdx2 < config->ifCount; ifIdx2++)
{
if (strncasecmp(config->ifConfig[ifIdx2].name, "MZ80AFI", 7) == 0 &&
config->ifConfig[ifIdx2].isPhysical)
{
MEMIO_SET(cpu, 0xF3FE, (t_MemoryFunc) MZ80AFI_IO_A10Toggle);
MEMIO_SET(cpu, 0xF3FF, (t_MemoryFunc) MZ80AFI_IO_A10Toggle);
break;
}
}
}
// When any interface uses physical hardware, RFS bank switching will change
// blocks from PHYSICAL to RAM type. The Z80 then fetches from virtual RAM
// without generating physical M1/RFSH cycles, causing host DRAM to decay.
// Force refreshEnable so Z80CPU_refreshDRAM is called during virtual fetches.
if (config->isPhysical)
{
cpu->refreshEnable = true;
}
// Install MZ-80A MEMSW/MEMSWR handlers, overriding any installed by RFS_Init.
// The MZ-80A has hardware MEMSW support — in PHYSICAL mode the handler must also
@@ -943,7 +967,7 @@ uint8_t MZ80A_Init(t_Z80CPU *cpu, t_FlashAppConfigHeader *appConfig, t_drvConfig
mz80aMemSwitch = false;
MEMIO_SET(cpu, MEMSW, (t_MemoryFunc) MZ80A_IO_MEMSW);
MEMIO_SET(cpu, MEMSWR, (t_MemoryFunc) MZ80A_IO_MEMSWR);
/*
// Debug: dump memory attributes for key blocks to verify tCycSync and waitStates.
debugf("MZ80A_Init: Memory attributes (bank 0):\r\n");
for (int idx = 0; idx < MEMORY_PAGE_BLOCKS; idx++)
@@ -958,7 +982,7 @@ uint8_t MZ80A_Init(t_Z80CPU *cpu, t_FlashAppConfigHeader *appConfig, t_drvConfig
idx, idx * MEMORY_BLOCK_SIZE, type, ws, ts, mbp);
}
}
*/
}
}

View File

@@ -43,6 +43,7 @@
#include "drivers/Sharp/MZ80AFI.h"
t_MZ80AFI *mz80afiCtrl; // Control structure for the MZ80AFI Floppy Disk Interface.
static bool mz80afiIsPhysical = false; // True when MZ80AFI interface is physical (hardware FDC).
// -----------------------------------------------------------------------------------------------
// Interface: Sharp MZ-80A Floppy Disk Interface Board (MZ80AFI).
@@ -57,7 +58,10 @@ uint8_t MZ80AFI_Init(t_Z80CPU *cpu, t_drvIFConfig *config)
// Locals.
uint8_t result = 0;
// Interface logic only for virtual device. Physical device doesnt need configuration.
// Physical device doesn't need virtual FDC setup. The A10 toggle handler for
// VIRTUAL driver + PHYSICAL interface is installed by MZ80A_Init, which has
// visibility of both the driver and interface physical flags.
mz80afiIsPhysical = config->isPhysical;
if (config->isPhysical)
return (0);
@@ -183,11 +187,14 @@ uint8_t MZ80AFI_TaskProcessor(t_Z80CPU *cpu, enum Z80CPU_TASK_NAME task, char *p
switch (task)
{
case FLOPPY_DISK_CHANGE:
int diskNo = atoi(strtok(param, ","));
char *fileName = strtok(NULL, ",");
if (fileName != NULL)
if (mz80afiCtrl)
{
wd1773_changeDisk(&mz80afiCtrl->fdc, fileName, diskNo);
int diskNo = atoi(strtok(param, ","));
char *fileName = strtok(NULL, ",");
if (fileName != NULL)
{
wd1773_changeDisk(&mz80afiCtrl->fdc, fileName, diskNo);
}
}
break;
@@ -212,12 +219,20 @@ uint8_t __func_in_RAM(MZ80AFI_IO_A10Toggle)(t_Z80CPU *cpu, bool read, uint16_t a
return data;
// When DRQ is active, force A10 high — F3FE reads as F7FE, F3FF reads as F7FF.
uint16_t effectiveAddr = addr;
if (mz80afiCtrl != NULL && mz80afiCtrl->fdc.drq)
bool drq = false;
if (mz80afiIsPhysical)
{
effectiveAddr = addr | 0x0400;
// Physical FDC: read WD1773 status register via physical bus.
// MZ-80A inverts the data bus for the FDC, so DRQ (bit 1) is 0 when active.
uint8_t status = Z80CPU_readPhysicalIO(cpu, 0xD8);
drq = !(status & 0x02);
}
else if (mz80afiCtrl != NULL)
{
drq = mz80afiCtrl->fdc.drq;
}
uint16_t effectiveAddr = drq ? (addr | 0x0400) : addr;
return cpu->_z80PSRAM->RAM[effectiveAddr];
}

View File

@@ -1 +1 @@
2.222
2.242

View File

@@ -1 +1 @@
2.209
2.226