From 9eccbfde84b0148660f172d4ec04eb49b2400796 Mon Sep 17 00:00:00 2001 From: 0kmg <9137159+0kmg@users.noreply.github.com> Date: Sat, 18 Dec 2021 03:16:18 -0900 Subject: fds: Fixed IRQ regression + IRQ timer improvements. Fixes MT8041. (#9010) * fds: Fixed IRQ regression + IRQ timer improvements. Fixes MT8041. * fix typo --- src/devices/bus/nes/disksys.cpp | 56 ++++++++++++++++++++++++++++++----------- src/devices/bus/nes/disksys.h | 3 ++- src/mame/drivers/nes.cpp | 4 +-- 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/devices/bus/nes/disksys.cpp b/src/devices/bus/nes/disksys.cpp index 2eae2960536..d3f10eb27cc 100644 --- a/src/devices/bus/nes/disksys.cpp +++ b/src/devices/bus/nes/disksys.cpp @@ -13,8 +13,6 @@ TODO: - convert floppy drive + fds format to modern code! - - add sound bits - - stop IRQ from using HOLD_LINE ***********************************************************************************************************/ @@ -110,7 +108,7 @@ nes_disksys_device::nes_disksys_device(const machine_config &mconfig, const char , m_disk(*this, "floppy0") , m_sound(*this, "rp2c33snd") , irq_timer(nullptr) - , m_irq_count(0), m_irq_count_latch(0), m_irq_enable(0), m_irq_transfer(0), m_fds_motor_on(0), m_fds_door_closed(0), m_fds_current_side(0), m_fds_head_position(0), m_fds_status0(0), m_read_mode(0), m_drive_ready(0) + , m_irq_count(0), m_irq_count_latch(0), m_irq_enable(0), m_irq_repeat(0), m_irq_transfer(0), m_disk_reg_enable(0), m_fds_motor_on(0), m_fds_door_closed(0), m_fds_current_side(0), m_fds_head_position(0), m_fds_status0(0), m_read_mode(0), m_drive_ready(0) , m_fds_sides(0), m_fds_last_side(0), m_fds_count(0) { } @@ -134,9 +132,11 @@ void nes_disksys_device::device_start() save_item(NAME(m_read_mode)); save_item(NAME(m_drive_ready)); save_item(NAME(m_irq_enable)); + save_item(NAME(m_irq_repeat)); save_item(NAME(m_irq_transfer)); save_item(NAME(m_irq_count)); save_item(NAME(m_irq_count_latch)); + save_item(NAME(m_disk_reg_enable)); save_item(NAME(m_fds_last_side)); save_item(NAME(m_fds_count)); @@ -159,7 +159,9 @@ void nes_disksys_device::pcb_reset() m_irq_count = 0; m_irq_count_latch = 0; m_irq_enable = 0; + m_irq_repeat = 0; m_irq_transfer = 0; + m_disk_reg_enable = 0; m_fds_count = 0; m_fds_last_side = 0; @@ -212,8 +214,12 @@ uint8_t nes_disksys_device::read_m(offs_t offset) void nes_disksys_device::hblank_irq(int scanline, int vblank, int blanked) { +// FIXME: This looks like a gross hack that ties the disk byte transfer IRQ to the PPU. Seriously? if (m_irq_transfer) - hold_irq_line(); + { + set_irq_line(ASSERT_LINE); + m_fds_status0 |= 0x02; + } } void nes_disksys_device::write_ex(offs_t offset, uint8_t data) @@ -236,12 +242,25 @@ void nes_disksys_device::write_ex(offs_t offset, uint8_t data) m_irq_count_latch = (m_irq_count_latch & 0x00ff) | (data << 8); break; case 0x02: - m_irq_count = m_irq_count_latch; - m_irq_enable = BIT(data, 1); + if (m_disk_reg_enable) + { + m_irq_repeat = BIT(data, 0); + m_irq_enable = BIT(data, 1); + if (m_irq_enable) + m_irq_count = m_irq_count_latch; + else + set_irq_line(CLEAR_LINE); + } break; case 0x03: // bit0 - Enable disk I/O registers // bit1 - Enable sound I/O registers + m_disk_reg_enable = BIT(data, 0); + if (!m_disk_reg_enable) + { + m_irq_enable = 0; + set_irq_line(CLEAR_LINE); + } m_sound_en = BIT(data, 1); break; case 0x04: @@ -249,6 +268,9 @@ void nes_disksys_device::write_ex(offs_t offset, uint8_t data) // TEST! if (m_fds_data && m_fds_current_side && !m_read_mode) m_fds_data[(m_fds_current_side - 1) * 65500 + m_fds_head_position++] = data; + // clear the byte transfer flag + m_fds_status0 &= ~0x02; + set_irq_line(CLEAR_LINE); break; case 0x05: // $4025 - FDS Control @@ -317,8 +339,9 @@ uint8_t nes_disksys_device::read_ex(offs_t offset) // bit6 - End of Head (1 when disk head is on the most inner track) // bit7 - Disk Data Read/Write Enable (1 when disk is readable/writable) ret = m_fds_status0 | 0x80; - // clear the disk IRQ detect flag - m_fds_status0 &= ~0x01; + // clear the disk IRQ detect and byte transfer flags + m_fds_status0 &= ~0x03; + set_irq_line(CLEAR_LINE); break; case 0x11: // $4031 - data latch @@ -337,6 +360,9 @@ uint8_t nes_disksys_device::read_ex(offs_t offset) } else ret = 0; + // clear the byte transfer flag + m_fds_status0 &= ~0x02; + set_irq_line(CLEAR_LINE); break; case 0x12: // $4032 - disk status 1: @@ -384,15 +410,17 @@ void nes_disksys_device::device_timer(emu_timer &timer, device_timer_id id, int { if (id == TIMER_IRQ) { - if (m_irq_enable && m_irq_count) + if (m_irq_enable) { - m_irq_count--; - if (!m_irq_count) + if (m_irq_count) + m_irq_count--; + else { - hold_irq_line(); - m_irq_enable = 0; + set_irq_line(ASSERT_LINE); + m_irq_count = m_irq_count_latch; + if (!m_irq_repeat) + m_irq_enable = 0; m_fds_status0 |= 0x01; - m_irq_count_latch = 0; // used in Kaettekita Mario Bros } } } diff --git a/src/devices/bus/nes/disksys.h b/src/devices/bus/nes/disksys.h index 1b5fed37e77..a8b3b3e5725 100644 --- a/src/devices/bus/nes/disksys.h +++ b/src/devices/bus/nes/disksys.h @@ -55,7 +55,8 @@ private: void unload_disk(device_image_interface &image); uint16_t m_irq_count, m_irq_count_latch; - int m_irq_enable, m_irq_transfer; + int m_irq_enable, m_irq_repeat, m_irq_transfer; + int m_disk_reg_enable; bool m_sound_en; uint8_t m_fds_motor_on; diff --git a/src/mame/drivers/nes.cpp b/src/mame/drivers/nes.cpp index 20ca8933276..71cd23fa615 100644 --- a/src/mame/drivers/nes.cpp +++ b/src/mame/drivers/nes.cpp @@ -223,7 +223,7 @@ void nes_state::fds(machine_config &config) MCFG_MACHINE_RESET_OVERRIDE(nes_state, fds) config.device_remove("nes_slot"); - NES_DISKSYS(config, "disk", 0); + NES_DISKSYS(config, "disk", NTSC_APU_CLOCK); config.device_remove("cart_list"); config.device_remove("cass_list"); @@ -269,7 +269,7 @@ void nes_state::famitwin(machine_config &config) m_cartslot->set_must_be_loaded(false); - NES_DISKSYS(config, "disk", 0); + NES_DISKSYS(config, "disk", NTSC_APU_CLOCK); } -- cgit v1.2.3