diff options
Diffstat (limited to 'src/devices/machine/amigafdc.cpp')
-rw-r--r-- | src/devices/machine/amigafdc.cpp | 64 |
1 files changed, 56 insertions, 8 deletions
diff --git a/src/devices/machine/amigafdc.cpp b/src/devices/machine/amigafdc.cpp index 4452af43493..ad83a268039 100644 --- a/src/devices/machine/amigafdc.cpp +++ b/src/devices/machine/amigafdc.cpp @@ -12,6 +12,18 @@ #include "formats/ipf_dsk.h" #include "amigafdc.h" +#define LOG_WARN (1U << 1) // Show warnings +#define LOG_DMA (1U << 2) // Show DMA setups +#define LOG_SYNC (1U << 3) // Show sync block setups + +#define VERBOSE (LOG_WARN | LOG_DMA | LOG_SYNC) + +#include "logmacro.h" + +#define LOGWARN(...) LOGMASKED(LOG_WARN, __VA_ARGS__) +#define LOGDMA(...) LOGMASKED(LOG_DMA, __VA_ARGS__) +#define LOGSYNC(...) LOGMASKED(LOG_SYNC, __VA_ARGS__) + DEFINE_DEVICE_TYPE(AMIGA_FDC, amiga_fdc_device, "amiga_fdc", "Amiga FDC") void amiga_fdc_device::floppy_formats(format_registration &fr) @@ -210,7 +222,12 @@ void amiga_fdc_device::live_run(const attotime &limit) } if(cur_live.bit_counter > 8) - fatalerror("amiga_fdc_device::live_run - cur_live.bit_counter > 8\n"); + { + // CHECKME: abreed, ghoulsvf Ghouls'n Goblins and lastnin2 at very least throws this + // is it a side effect of something else not happening at the right time or the assumption is right? + cur_live.bit_counter = 0; + LOGWARN("%s: live_run - cur_live.bit_counter > 8\n", machine().describe_context()); + } if(cur_live.bit_counter == 8) { live_delay(RUNNING_SYNCPOINT); @@ -233,7 +250,10 @@ void amiga_fdc_device::live_run(const attotime &limit) return; cur_live.bit_counter++; if(cur_live.bit_counter > 8) - fatalerror("amiga_fdc_device::live_run - cur_live.bit_counter > 8\n"); + { + cur_live.bit_counter = 0; + LOGWARN("%s: live_run - cur_live.bit_counter > 8\n", machine().describe_context()); + } if(cur_live.bit_counter == 8) { live_delay(RUNNING_SYNCPOINT); @@ -247,6 +267,14 @@ void amiga_fdc_device::live_run(const attotime &limit) if(!(dskbyt & 0x2000)) { if(cur_live.shift_reg == dsksync) { if(adkcon & 0x0400) { + // FIXME: exact dsksync behaviour + // - Some games currently writes two dsksync to the buffer (marked as "[FDC] dsksync"), + // removing one will make most of them happy. + // This is reported as 0-lower cylinder good and everything else as bad in the ATK suite; + // - Some games trashes memory, mostly the ones with "[FDC] dsksync bootblock": + // they attempt to load the tracks in AmigaDOS in the same way that's done by the + // Kickstart to check if the disk is bootable. + // This is reported as 0-upper cylinder bad in the ATK suite; if(dma_state == DMA_WAIT_START) { cur_live.bit_counter = 0; @@ -257,16 +285,22 @@ void amiga_fdc_device::live_run(const attotime &limit) cur_live.bit_counter = 0; dma_value = dma_read(); - } else + } else { + LOGSYNC("%s: DSKSYNC on %06x %d\n", this->tag(), dskpt, dma_state); dma_write(dsksync); + } } else if(dma_state != DMA_IDLE) { + LOGSYNC("%s: DSKSYNC on %06x %d\n", this->tag(), dskpt, dma_state); dma_write(dsksync); cur_live.bit_counter = 0; } else if(cur_live.bit_counter != 8) cur_live.bit_counter = 0; } + //else + // LOGSYNC("%s: no DSKSYNC\n", this->tag()); + dskbyt |= 0x1000; m_write_dsksyn(1); } else @@ -332,6 +366,11 @@ void amiga_fdc_device::dma_check() bool was_writing = dskbyt & 0x2000; dskbyt &= 0x9fff; if(dma_enabled()) { + LOGDMA("%s: DMA start dskpt=%08x dsklen=%04x dir=%s adkcon=%04x dsksync=%04x\n", + machine().describe_context(), + dskpt, dsklen & 0x3fff, BIT(dsklen, 14) ? "RAM->disk" : "disk->RAM", adkcon, dsksync + ); + if(dma_state == IDLE) { dma_state = adkcon & 0x0400 ? DMA_WAIT_START : DMA_RUNNING_BYTE_0; if(dma_state == DMA_RUNNING_BYTE_0) { @@ -344,7 +383,6 @@ void amiga_fdc_device::dma_check() } } } else { - dskbyt |= 0x4000; if(dsklen & 0x4000) dskbyt |= 0x2000; } @@ -355,7 +393,6 @@ void amiga_fdc_device::dma_check() cur_live.pll.stop_writing(floppy, cur_live.tm); if(!was_writing && (dskbyt & 0x2000)) cur_live.pll.start_writing(cur_live.tm); - } void amiga_fdc_device::adkcon_set(uint16_t data) @@ -409,6 +446,7 @@ uint16_t amiga_fdc_device::dskptl_r() void amiga_fdc_device::dsksync_w(uint16_t data) { live_sync(); + LOGSYNC("%s: DSKSYNC %04x\n", machine().describe_context(), data); dsksync = data; live_run(); } @@ -416,6 +454,7 @@ void amiga_fdc_device::dsksync_w(uint16_t data) void amiga_fdc_device::dmacon_set(uint16_t data) { live_sync(); + LOGDMA("%s: DMACON set DSKEN %d DMAEN %d (%04x)\n", machine().describe_context(), BIT(data, 4), BIT(data, 9), data); dmacon = data; dma_check(); live_run(); @@ -423,8 +462,15 @@ void amiga_fdc_device::dmacon_set(uint16_t data) uint16_t amiga_fdc_device::dskbytr_r() { - uint16_t res = dskbyt; - dskbyt &= 0x7fff; + uint16_t res = (dskbyt & ~0x4000); + // check if DMA is on + // logica2 diagnostic BIOS floppy test requires this + bool dmaon = (dma_state != DMA_IDLE) && ((dmacon & 0x0210) == 0x0210); + res |= dmaon << 14; + + // reset DSKBYT ready on read + if (!machine().side_effects_disabled()) + dskbyt &= 0x7fff; return res; } @@ -454,6 +500,7 @@ void amiga_fdc_device::ciaaprb_w(uint8_t data) live_sync(); + // FIXME: several sources claims that multiple drive selects is really possible if(!(data & 0x08)) floppy = floppy_devices[0]; else if(!(data & 0x10)) @@ -494,7 +541,8 @@ uint8_t amiga_fdc_device::ciaapra_r() { uint8_t ret = 0x3c; if(floppy) { - //if(!floppy->ready_r()) fixit: seems to not work well with multiple disk drives + // FIXME: seems to not work well with multiple disk drives + //if(!floppy->ready_r()) ret &= ~0x20; if(!floppy->trk00_r()) ret &= ~0x10; |