summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author MooglyGuy <therealmogminer@gmail.com>2019-12-27 02:04:52 +0100
committer MooglyGuy <therealmogminer@gmail.com>2019-12-27 02:04:52 +0100
commit77e96735c4563fa538f106b41606afc40910872e (patch)
treeaf6600c86ef2df40bfb2bbd36695c77e500158fd
parentdee55a8f5a05877e65cdc59d54a9325c93a612c9 (diff)
-cdimono2: Improved /DTACK hack and improved SLAVE/SCC comms. Gets rid of error on bootup.
-rw-r--r--src/devices/cpu/m68000/m68000.h3
-rw-r--r--src/devices/cpu/m68000/m68kcpu.cpp46
-rw-r--r--src/devices/cpu/m68000/m68kcpu.h1
-rw-r--r--src/devices/cpu/m6805/m68hc05.cpp48
-rw-r--r--src/devices/cpu/m6805/m68hc05.h2
-rw-r--r--src/mame/drivers/cdi.cpp86
-rw-r--r--src/mame/includes/cdi.h4
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