From a5c3b2d1a704083e98a1d087633013f5e1cd6f39 Mon Sep 17 00:00:00 2001 From: Scott Stone Date: Mon, 24 Feb 2014 01:19:43 +0000 Subject: [PATCH] (MESS) ql.c - Fixed up communication between main 68008 CPU and 8048 IPC so that making sound does not crash the machine. [Phill Harvey-Smith] --- src/mess/drivers/ql.c | 11 +++--- src/mess/includes/ql.h | 2 +- src/mess/machine/zx8302.c | 75 +++++++++++++++++---------------------- src/mess/machine/zx8302.h | 9 +++-- 4 files changed, 42 insertions(+), 55 deletions(-) diff --git a/src/mess/drivers/ql.c b/src/mess/drivers/ql.c index fde6ad15563..64c730212f9 100644 --- a/src/mess/drivers/ql.c +++ b/src/mess/drivers/ql.c @@ -162,7 +162,7 @@ READ8_MEMBER( ql_state::ipc_port2_r ) data |= m_ser2->rxd_r(); // COMDATA - data |= m_comdata << 7; + data |= m_comdata_to_ipc << 7; return data; } @@ -214,8 +214,6 @@ WRITE8_MEMBER( ql_state::ipc_port2_w ) m_ser2->write_dtr(!BIT(data, 5)); // COMDATA - m_comdata = BIT(data, 7); - m_zx8302->comdata_w(BIT(data, 7)); } @@ -355,7 +353,7 @@ void ql_state::sandy_set_control(UINT8 data) wd17xx_set_drive(m_fdc,1); wd17xx_set_side(m_fdc,(data & SANDY_SIDE_MASK) >> SANDY_SIDE_SHIFT); - if (data & SANDY_SIDE_MASK) + if ((data & SANDY_SIDE_MASK) & (LOG_DISK_READ | LOG_DISK_WRITE)) { logerror("Accessing side 1\n"); } @@ -730,9 +728,10 @@ WRITE_LINE_MEMBER( ql_state::ql_baudx4_w ) m_baudx4 = state; } +// CPU to IPC WRITE_LINE_MEMBER( ql_state::ql_comdata_w ) { - m_comdata = state; + m_comdata_to_ipc = state; } WRITE_LINE_MEMBER( ql_state::zx8302_mdselck_w ) @@ -906,7 +905,7 @@ void ql_state::machine_start() // register for state saving save_item(NAME(m_keylatch)); save_item(NAME(m_ipl)); - save_item(NAME(m_comdata)); + save_item(NAME(m_comdata_to_ipc)); save_item(NAME(m_baudx4)); save_item(NAME(m_printer_char)); save_item(NAME(m_disk_io_byte)); diff --git a/src/mess/includes/ql.h b/src/mess/includes/ql.h index e76534e997a..4cf92bd8214 100644 --- a/src/mess/includes/ql.h +++ b/src/mess/includes/ql.h @@ -144,7 +144,7 @@ public: /* IPC state */ UINT8 m_keylatch; int m_ipl; - int m_comdata; + int m_comdata_to_ipc; int m_baudx4; // Trump card & Sandy superdisk diff --git a/src/mess/machine/zx8302.c b/src/mess/machine/zx8302.c index ce56bf31b98..96e57914270 100644 --- a/src/mess/machine/zx8302.c +++ b/src/mess/machine/zx8302.c @@ -133,7 +133,7 @@ inline void zx8302_device::transmit_ipc_data() case IPC_START: if (LOG) logerror("ZX8302 '%s' COMDATA Start Bit\n", tag()); - m_out_comdata_func(0); + m_out_comdata_func(BIT(m_idr, 0)); m_ipc_busy = 1; m_ipc_state = IPC_DATA; break; @@ -141,20 +141,16 @@ inline void zx8302_device::transmit_ipc_data() case IPC_DATA: if (LOG) logerror("ZX8302 '%s' COMDATA Data Bit: %x\n", tag(), BIT(m_idr, 1)); - m_comdata = BIT(m_idr, 1); - m_out_comdata_func(m_comdata); + m_comdata_to_ipc = BIT(m_idr, 1); + m_out_comdata_func(m_comdata_to_ipc); m_ipc_state = IPC_STOP; break; case IPC_STOP: - if (!m_ipc_rx) - { - if (LOG) logerror("ZX8302 '%s' COMDATA Stop Bit\n", tag()); + if (LOG) logerror("ZX8302 '%s' COMDATA Stop Bit\n", tag()); - m_out_comdata_func(1); - m_ipc_busy = 0; - m_ipc_state = IPC_START; - } + m_out_comdata_func(BIT(m_idr, 2)); + m_ipc_busy = 0; break; } } @@ -178,10 +174,11 @@ zx8302_device::zx8302_device(const machine_config &mconfig, const char *tag, dev m_irq(0), m_ctr(time(NULL) + RTC_BASE_ADJUST), m_status(0), - m_comdata(1), + m_comdata_from_ipc(1), + m_comdata_to_cpu(1), + m_comdata_to_ipc(1), m_comctl(1), m_ipc_state(0), - m_ipc_rx(0), m_ipc_busy(0), m_baudx4(0), m_track(0) @@ -215,7 +212,6 @@ void zx8302_device::device_start() m_baudx4_timer = timer_alloc(TIMER_BAUDX4); m_rtc_timer = timer_alloc(TIMER_RTC); m_gap_timer = timer_alloc(TIMER_GAP); - m_ipc_timer = timer_alloc(TIMER_IPC); m_rtc_timer->adjust(attotime::zero, 0, attotime::from_hz(rtc_clock / 32768)); m_gap_timer->adjust(attotime::zero, 0, attotime::from_msec(31)); @@ -229,10 +225,11 @@ void zx8302_device::device_start() save_item(NAME(m_irq)); save_item(NAME(m_ctr)); save_item(NAME(m_status)); - save_item(NAME(m_comdata)); + save_item(NAME(m_comdata_from_ipc)); + save_item(NAME(m_comdata_to_cpu)); + save_item(NAME(m_comdata_to_ipc)); save_item(NAME(m_comctl)); save_item(NAME(m_ipc_state)); - save_item(NAME(m_ipc_rx)); save_item(NAME(m_ipc_busy)); save_item(NAME(m_baudx4)); save_item(NAME(m_mdv_data)); @@ -261,14 +258,6 @@ void zx8302_device::device_timer(emu_timer &timer, device_timer_id id, int param trigger_interrupt(INT_GAP); break; - case TIMER_IPC: - m_idr = param; - m_ipc_state = IPC_START; - m_ipc_rx = 0; - - transmit_ipc_data(); - break; - default: device_serial_interface::device_timer(timer, id, param, ptr); break; @@ -464,7 +453,7 @@ READ8_MEMBER( zx8302_device::status_r ) data |= m_ipc_busy << 6; // COMDATA - data |= m_comdata << 7; + data |= m_comdata_to_cpu << 7; if (LOG) logerror("ZX8302 '%s' Status: %02x\n", tag(), data); @@ -475,15 +464,25 @@ READ8_MEMBER( zx8302_device::status_r ) //------------------------------------------------- // ipc_command_w - IPC command //------------------------------------------------- +// When the main CPU writes to the IPC it writes the lsn of 18003 +// this is encoded as follows : +// +// b0 start bit +// b1 data bit +// b2 stop bit +// b3 extra stop bit. +// +// At startup the IPC sits in a loop waiting for the comdata bit to go +// high, the main CPU does this by writing 0x01 to output register. WRITE8_MEMBER( zx8302_device::ipc_command_w ) { if (LOG) logerror("ZX8302 '%s' IPC Command: %02x\n", tag(), data); - if (data != 0x01) - { - m_ipc_timer->adjust(attotime::from_nsec(480), data); - } + m_idr = data; + m_ipc_state = IPC_START; + + transmit_ipc_data(); } @@ -590,6 +589,7 @@ WRITE_LINE_MEMBER( zx8302_device::comctl_w ) if (state) { transmit_ipc_data(); + m_comdata_to_cpu = m_comdata_from_ipc; } } @@ -597,25 +597,14 @@ WRITE_LINE_MEMBER( zx8302_device::comctl_w ) //------------------------------------------------- // comdata_w - IPC COMDATA //------------------------------------------------- +// IPC writing comdata to CPU +// WRITE_LINE_MEMBER( zx8302_device::comdata_w ) { - if (LOG) logerror("ZX8302 '%s' COMDATA: %x\n", tag(), state); + if (LOG) logerror("ZX8302 '%s' COMDATA->CPU(pending): %x\n", tag(), state); - if (m_ipc_state == IPC_DATA || m_ipc_state == IPC_STOP) - { - if (m_ipc_rx) - { - m_ipc_rx = 0; - m_ipc_busy = 0; - m_ipc_state = IPC_START; - } - else - { - m_ipc_rx = 1; - m_comdata = state; - } - } + m_comdata_from_ipc = state; } diff --git a/src/mess/machine/zx8302.h b/src/mess/machine/zx8302.h index 415bd74f2f3..0a27b79a9e3 100644 --- a/src/mess/machine/zx8302.h +++ b/src/mess/machine/zx8302.h @@ -140,8 +140,7 @@ private: { TIMER_BAUDX4 = 0, TIMER_RTC, - TIMER_GAP, - TIMER_IPC + TIMER_GAP }; enum @@ -218,10 +217,11 @@ private: UINT8 m_status; // status register // IPC communication state - int m_comdata; // communication data + int m_comdata_from_ipc; // pending data from IPC->68000 + int m_comdata_to_cpu; // communication data IPC->68000 + int m_comdata_to_ipc; // communication data 68000->IPC int m_comctl; // communication control int m_ipc_state; // communication state - int m_ipc_rx; // receiving data from IPC int m_ipc_busy; // IPC busy int m_baudx4; // IPC baud x4 @@ -233,7 +233,6 @@ private: emu_timer *m_baudx4_timer; // baud x4 timer emu_timer *m_rtc_timer; // real time clock timer emu_timer *m_gap_timer; // microdrive gap timer - emu_timer *m_ipc_timer; // delayed IPC command timer };