fds: Fixed IRQ regression + IRQ timer improvements. Fixes MT8041. (#9010)

* fds: Fixed IRQ regression + IRQ timer improvements. Fixes MT8041.

* fix typo
This commit is contained in:
0kmg 2021-12-18 03:16:18 -09:00 committed by GitHub
parent de4ac4e41d
commit 9eccbfde84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 17 deletions

View File

@ -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
}
}
}

View File

@ -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;

View File

@ -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);
}