diff options
| author | 2019-12-27 02:04:52 +0100 | |
|---|---|---|
| committer | 2019-12-27 02:04:52 +0100 | |
| commit | 77e96735c4563fa538f106b41606afc40910872e (patch) | |
| tree | af6600c86ef2df40bfb2bbd36695c77e500158fd | |
| parent | dee55a8f5a05877e65cdc59d54a9325c93a612c9 (diff) | |
-cdimono2: Improved /DTACK hack and improved SLAVE/SCC comms. Gets rid of error on bootup.
| -rw-r--r-- | src/devices/cpu/m68000/m68000.h | 3 | ||||
| -rw-r--r-- | src/devices/cpu/m68000/m68kcpu.cpp | 46 | ||||
| -rw-r--r-- | src/devices/cpu/m68000/m68kcpu.h | 1 | ||||
| -rw-r--r-- | src/devices/cpu/m6805/m68hc05.cpp | 48 | ||||
| -rw-r--r-- | src/devices/cpu/m6805/m68hc05.h | 2 | ||||
| -rw-r--r-- | src/mame/drivers/cdi.cpp | 86 | ||||
| -rw-r--r-- | src/mame/includes/cdi.h | 4 |
7 files changed, 138 insertions, 52 deletions
diff --git a/src/devices/cpu/m68000/m68000.h b/src/devices/cpu/m68000/m68000.h index f4a3438c182..5a22c636704 100644 --- a/src/devices/cpu/m68000/m68000.h +++ b/src/devices/cpu/m68000/m68000.h @@ -170,6 +170,8 @@ public: void set_buserror_details(u32 fault_addr, u8 rw, u8 fc); void disable_interrupt_mixer() { m_interrupt_mixer = false; } void set_cpu_space(int space_id) { m_cpu_space_id = space_id; } + void assert_dtackn(); + void clear_dtackn(); protected: m68000_base_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, @@ -216,6 +218,7 @@ protected: u32 m_sr_mask; /* Implemented status register bits */ u32 m_instr_mode; /* Stores whether we are in instruction mode or group 0/1 exception mode */ u32 m_run_mode; /* Stores whether we are processing a reset, bus error, address error, or something else */ + int m_dtackn; /* Stores whether we are currently holding for data transfer acknowledge */ int m_has_pmmu; /* Indicates if a PMMU available (yes on 030, 040, no on EC030) */ int m_has_hmmu; /* Indicates if an Apple HMMU is available in place of the 68851 (020 only) */ int m_pmmu_enabled; /* Indicates if the PMMU is enabled */ diff --git a/src/devices/cpu/m68000/m68kcpu.cpp b/src/devices/cpu/m68000/m68kcpu.cpp index b685391ba7c..a515f9bce84 100644 --- a/src/devices/cpu/m68000/m68kcpu.cpp +++ b/src/devices/cpu/m68000/m68kcpu.cpp @@ -748,6 +748,16 @@ void m68000_base_device::postload() m68ki_jump(m_pc); } +void m68000_base_device::assert_dtackn() +{ + m_dtackn = 1; +} + +void m68000_base_device::clear_dtackn() +{ + m_dtackn = 0; +} + void m68000_base_device::m68k_cause_bus_error() { m_mmu_tmp_buserror_fc = m_mmu_tmp_fc; @@ -851,6 +861,13 @@ void m68000_base_device::execute_run() if (m_icount <= 0) return; } + if (m_dtackn) + { + logerror("%s: entered execute_run with /DTACK asserted, bailing\n", machine().describe_context()); + yield(); + return; + } + /* See if interrupts came in */ m68ki_check_interrupts(); @@ -901,12 +918,27 @@ void m68000_base_device::execute_run() { if (!m_pmmu_enabled) { + u32 tmp_dar[16]; + memcpy(tmp_dar, m_dar, sizeof(u32) * 16); + m_run_mode = RUN_MODE_NORMAL; /* Read an instruction and call its handler */ m_ir = m68ki_read_imm_16(); u16 state = m_state_table[m_ir]; (this->*m68k_handler_table[state])(); - m_icount -= m_cyc_instruction[m_ir]; + if (m_dtackn) + { + m_pc = m_ppc; + logerror("%s: instruction flagged /DTACK, bailing\n", machine().describe_context()); + memcpy(m_dar, tmp_dar, sizeof(u32) * 16); + m_icount--; + yield(); + return; + } + else + { + m_icount -= m_cyc_instruction[m_ir]; + } } else { @@ -1021,6 +1053,9 @@ void m68000_base_device::init_cpu_common(void) m_pmmu_enabled = 0; m_hmmu_enabled = 0; + /* initialize /DTACK */ + m_dtackn = 0; + /* The first call to this function initializes the opcode handler jump table */ if(!emulation_initialized) { @@ -1049,6 +1084,7 @@ void m68000_base_device::init_cpu_common(void) save_item(NAME(m_reset_cycles)); save_item(NAME(m_virq_state)); save_item(NAME(m_nmi_pending)); + save_item(NAME(m_dtackn)); save_item(NAME(m_has_pmmu)); save_item(NAME(m_has_hmmu)); save_item(NAME(m_pmmu_enabled)); @@ -1330,10 +1366,10 @@ void m68000_base_device::init16(address_space &space, address_space &ospace) auto ocache = ospace.cache<1, 0, ENDIANNESS_BIG>(); m_readimm16 = [ocache](offs_t address) -> u16 { return ocache->read_word(address); }; - m_read8 = [this](offs_t address) -> u8 { return m_space->read_byte(address); }; - m_read16 = [this](offs_t address) -> u16 { return m_space->read_word(address); }; - m_read32 = [this](offs_t address) -> u32 { return m_space->read_dword(address); }; - m_write8 = [this](offs_t address, u8 data) { m_space->write_word(address & ~1, data | (data << 8), address & 1 ? 0x00ff : 0xff00); }; + m_read8 = [this](offs_t address) -> u8 { return m_space->read_byte(address); }; + m_read16 = [this](offs_t address) -> u16 { return m_space->read_word(address); }; + m_read32 = [this](offs_t address) -> u32 { return m_space->read_dword(address); }; + m_write8 = [this](offs_t address, u8 data) { m_space->write_word(address & ~1, data | (data << 8), address & 1 ? 0x00ff : 0xff00); }; m_write16 = [this](offs_t address, u16 data) { m_space->write_word(address, data); }; m_write32 = [this](offs_t address, u32 data) { m_space->write_dword(address, data); }; } diff --git a/src/devices/cpu/m68000/m68kcpu.h b/src/devices/cpu/m68000/m68kcpu.h index 0326c0f4bd1..d8e903831c4 100644 --- a/src/devices/cpu/m68000/m68kcpu.h +++ b/src/devices/cpu/m68000/m68kcpu.h @@ -463,7 +463,6 @@ void set_irq_line(int irqline, int state); void m68k_cause_bus_error(); - static const u8 m68ki_shift_8_table[65]; static const u16 m68ki_shift_16_table[65]; static const u32 m68ki_shift_32_table[65]; diff --git a/src/devices/cpu/m6805/m68hc05.cpp b/src/devices/cpu/m6805/m68hc05.cpp index fa7eb82bc42..dca58d2e956 100644 --- a/src/devices/cpu/m6805/m68hc05.cpp +++ b/src/devices/cpu/m6805/m68hc05.cpp @@ -277,15 +277,24 @@ READ8_MEMBER(m68hc05_device::spcr_r) return m_spcr; } +void m68hc05_device::check_spi_interrupts() +{ + if (spcr_spie() && (m_spsr & 0x90)) + { + m_pending_interrupts |= M68HC05_INT_SPI; + } + else + { + m_pending_interrupts &= ~M68HC05_INT_SPI; + } +} + WRITE8_MEMBER(m68hc05_device::spcr_w) { if (spsr_modf()) { m_spsr &= ~0x10; - if (!spcr_spie() || !spsr_spif()) - { - m_pending_interrupts &= ~M68HC05_INT_SPI; - } + check_spi_interrupts(); } data &= 0xdf; m_spcr = data; @@ -299,7 +308,7 @@ WRITE8_MEMBER(m68hc05_device::spcr_w) READ8_MEMBER(m68hc05_device::spsr_r) { - LOGSPI("%s: read SPSR: %02x\n", machine().describe_context(), m_spsr); + //LOGSPI("%s: read SPSR: %02x\n", machine().describe_context(), m_spsr); return m_spsr; } @@ -312,6 +321,7 @@ READ8_MEMBER(m68hc05_device::spdr_r) { LOGSPI("%s: read SPDR: %02x\n", machine().describe_context(), m_sprr); m_spsr &= ~0xd0; + check_spi_interrupts(); return m_sprr; } @@ -324,6 +334,11 @@ WRITE8_MEMBER(m68hc05_device::spdr_w) return; } m_spdr = data; + if (spsr_spif()) + { + m_spsr &= ~0x80; + check_spi_interrupts(); + } if (spcr_spe()) { if (m_spi_tx_clocks != ~0U) @@ -365,14 +380,7 @@ WRITE_LINE_MEMBER(m68hc05_device::sck_in) m_sprr = m_spdr; m_spi_rx_cnt = 0; m_spsr |= 0x80; - if (spsr_spif() && spcr_spie()) - { - m_pending_interrupts |= M68HC05_INT_SPI; - } - else - { - m_pending_interrupts &= ~M68HC05_INT_SPI; - } + check_spi_interrupts(); } } } @@ -400,10 +408,7 @@ WRITE_LINE_MEMBER(m68hc05_device::ss_in) { m_spsr |= 0x10; m_spcr &= ~0x50; - if (spcr_spie()) - { - m_pending_interrupts |= M68HC05_INT_SPI; - } + check_spi_interrupts(); } } } @@ -1029,14 +1034,7 @@ void m68hc05_device::burn_cycles(unsigned count) m_spi_tx_clocks = ~0U; m_spi_run_clocks = 0; m_spsr |= 0x80; - if (spsr_spif() && spcr_spie()) - { - m_pending_interrupts |= M68HC05_INT_SPI; - } - else - { - m_pending_interrupts &= ~M68HC05_INT_SPI; - } + check_spi_interrupts(); } } m_sck_out_cb(m_sck); diff --git a/src/devices/cpu/m6805/m68hc05.h b/src/devices/cpu/m6805/m68hc05.h index dd8d5c8427d..4574a2a7d88 100644 --- a/src/devices/cpu/m6805/m68hc05.h +++ b/src/devices/cpu/m6805/m68hc05.h @@ -148,6 +148,8 @@ protected: virtual void run_cop(unsigned count); + void check_spi_interrupts(); + private: u8 port_value(unsigned offset) const; void update_port_irq(); diff --git a/src/mame/drivers/cdi.cpp b/src/mame/drivers/cdi.cpp index 2180d42cd8c..a6d0476f19d 100644 --- a/src/mame/drivers/cdi.cpp +++ b/src/mame/drivers/cdi.cpp @@ -145,24 +145,52 @@ READ16_MEMBER( cdimono2_state::uart_loopback_enable2 ) READ8_MEMBER(cdimono2_state::slave_glue_r) { - m_portd_data |= 0x80; - m_portc_data = 0xfc | ((offset >> 1) & 3); + if (m_maincpu_waiting) + { + logerror("%s: slave_glue_r: main CPU is waiting, bailing\n", machine().describe_context()); + return 0; + } + + if (!m_dtack_triggered) + { + logerror("%s: slave_glue_r: /DTACK not yet triggered, bailing\n", machine().describe_context()); + m_portd_data |= 0x80; + m_portc_data = 0xfc | ((offset >> 1) & 3); + m_slave->set_input_line(M68HC05_IRQ_LINE, ASSERT_LINE); + m_slave->set_input_line(M68HC05_IRQ_LINE, CLEAR_LINE); + m_maincpu->assert_dtackn(); + m_maincpu_waiting = true; + return 0; + } + + m_dtack_triggered = false; logerror("%s: slave_glue_r: %02x = %02x\n", machine().describe_context(), offset, m_porta_data); - m_slave->set_input_line(M68HC05_IRQ_LINE, ASSERT_LINE); - m_slave->set_input_line(M68HC05_IRQ_LINE, CLEAR_LINE); - m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); return m_porta_data; } WRITE8_MEMBER(cdimono2_state::slave_glue_w) { - logerror("%s: slave_glue_w: %02x = %02x\n", machine().describe_context(), offset, data); + m_porta_data = data; m_portc_data = 0xfc | ((offset >> 1) & 3); - m_porta_data = data & 0xff; - m_slave->set_input_line(M68HC05_IRQ_LINE, ASSERT_LINE); - m_slave->set_input_line(M68HC05_IRQ_LINE, CLEAR_LINE); m_portd_data &= ~0x80; - m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); + if (!m_dtack_triggered && !m_maincpu_waiting) + { + logerror("%s: slave_glue_w: %02x = %02x, asserting /DTACK\n", machine().describe_context(), offset, m_porta_data); + m_maincpu->assert_dtackn(); + m_slave->set_input_line(M68HC05_IRQ_LINE, ASSERT_LINE); + m_slave->set_input_line(M68HC05_IRQ_LINE, CLEAR_LINE); + m_maincpu_waiting = true; + m_dtack_triggered = false; + } + else if (m_maincpu_waiting) + { + logerror("%s: slave_glue_w: %02x = %02x, main CPU waiting\n", machine().describe_context(), offset, m_porta_data); + } + else + { + logerror("%s: slave_glue_w: %02x = %02x, /DTACK released\n", machine().describe_context(), offset, m_porta_data); + m_dtack_triggered = false; + } } WRITE8_MEMBER(cdimono2_state::controller_tx) @@ -341,6 +369,9 @@ void cdimono2_state::machine_start() save_item(NAME(m_disbit)); save_item(NAME(m_mouse_buffer)); save_item(NAME(m_mouse_idx)); + save_item(NAME(m_dtack_triggered)); + save_item(NAME(m_eat_write_dtack)); + save_item(NAME(m_maincpu_waiting)); m_mouse_timer = timer_alloc(0); } @@ -356,7 +387,7 @@ void cdimono2_state::machine_reset() { cdi_state::machine_reset(); m_porta_data = 0x00; - m_portb_data = 0x00; + m_portb_data = 0x40; m_portc_data = 0xfc; m_portd_data = 0x20; m_disdat = 0x00; @@ -367,6 +398,9 @@ void cdimono2_state::machine_reset() m_mouse_idx = 0x00; m_mouse_timer->adjust(attotime::never); m_servo->ss_in(0); + m_dtack_triggered = false; + m_eat_write_dtack = false; + m_maincpu_waiting = false; } void quizard_state::machine_start() @@ -650,31 +684,32 @@ uint32_t cdi_state::screen_update_cdimono1_lcd(screen_device &screen, bitmap_rgb READ8_MEMBER(cdimono2_state::slave_porta_r) { logerror("%s: slave_porta_r: %02x & %02x\n", machine().describe_context(), m_porta_data, mem_mask); - return m_porta_data & mem_mask; + return m_porta_data; } READ8_MEMBER(cdimono2_state::slave_portb_r) { logerror("%s: slave_portb_r: %02x & %02x\n", machine().describe_context(), m_portb_data, mem_mask); - return m_portb_data & mem_mask; + return m_portb_data; } READ8_MEMBER(cdimono2_state::slave_portc_r) { //logerror("%s: slave_portc_r: %02x & %02x\n", machine().describe_context(), m_portc_data, mem_mask); - return (m_portc_data & mem_mask) & 0x7f; + return m_portc_data; } READ8_MEMBER(cdimono2_state::slave_portd_r) { logerror("%s: slave_portd_r: %02x & %02x\n", machine().describe_context(), m_portd_data, mem_mask); - return m_portd_data & mem_mask; + return m_portd_data; } WRITE8_MEMBER(cdimono2_state::slave_porta_w) { - logerror("%s: slave_porta_w: %02x\n", machine().describe_context(), data); - m_porta_data = data; + logerror("%s: slave_porta_w: %02x & %02x\n", machine().describe_context(), data, mem_mask); + m_porta_data &= ~mem_mask; + m_porta_data |= data & mem_mask; } void cdimono2_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) @@ -694,11 +729,20 @@ void cdimono2_state::device_timer(emu_timer &timer, device_timer_id id, int para WRITE8_MEMBER(cdimono2_state::slave_portb_w) { const uint8_t old = m_portb_data; - m_portb_data = data; - logerror("%s: slave_portb_w: %02x\n", machine().describe_context(), data); - if (!(old & 0x40) && (data & 0x40)) + m_portb_data &= ~mem_mask; + m_portb_data |= data & mem_mask; + logerror("%s: slave_portb_w: %02x & %02x\n", machine().describe_context(), data, mem_mask); + if ((old & 0x40) && !(data & 0x40)) { - m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); + if (!m_eat_write_dtack) + { + logerror("%s: slave_portb_w: flagging /DTACK as triggered\n", machine().describe_context()); + m_maincpu->clear_dtackn(); + m_slave->yield(); + m_dtack_triggered = true; + m_maincpu_waiting = false; + } + m_eat_write_dtack = false; } if (!(old & 0x10) && (data & 0x10)) { diff --git a/src/mame/includes/cdi.h b/src/mame/includes/cdi.h index 2da173f3d7b..41c566b35c6 100644 --- a/src/mame/includes/cdi.h +++ b/src/mame/includes/cdi.h @@ -129,6 +129,10 @@ private: uint8_t m_mouse_buffer[6]; uint8_t m_mouse_idx; emu_timer *m_mouse_timer; + + bool m_dtack_triggered; + bool m_eat_write_dtack; + bool m_maincpu_waiting; }; class quizard_state : public cdi_state |
