From 4830ec15d8637deb0c8c23218b39cefed5032198 Mon Sep 17 00:00:00 2001 From: smf- Date: Sun, 26 Jan 2014 21:57:16 +0000 Subject: [PATCH] Converted MSM58321 to DEVCB2, uses level logic rather than edge detection for strobes (as per datasheet), added nvram interface as there are some configuration bits to save, added support for 12 and 24 hour. It defaults to 12 hour, but you can configure it in the driver to default to 24H. You can configure what year 0 is in the driver, which is used when setting the date at startup. [smf] --- src/emu/machine/msm58321.c | 536 +++++++++++++++++++++++++++---------- src/emu/machine/msm58321.h | 90 ++++--- src/mess/drivers/pc100.c | 48 +++- src/mess/drivers/v1050.c | 35 ++- src/mess/includes/v1050.h | 17 +- 5 files changed, 530 insertions(+), 196 deletions(-) diff --git a/src/emu/machine/msm58321.c b/src/emu/machine/msm58321.c index bfbd12ca363..573067609d6 100644 --- a/src/emu/machine/msm58321.c +++ b/src/emu/machine/msm58321.c @@ -13,11 +13,11 @@ TODO: - - 12/24 hour - - AM/PM - leap year - stop + - test - reset + - busy - reference registers */ @@ -57,6 +57,36 @@ enum REGISTER_REF1 }; +static const char *reg_name(UINT8 address) +{ + switch(address) + { + case REGISTER_S1: return "S1"; + case REGISTER_S10: return "S10"; + case REGISTER_MI1: return "MI1"; + case REGISTER_MI10: return "MI10"; + case REGISTER_H1: return "H1"; + case REGISTER_H10: return "H10"; + case REGISTER_W: return "W"; + case REGISTER_D1: return "D1"; + case REGISTER_D10: return "D10"; + case REGISTER_MO1: return "MO1"; + case REGISTER_MO10: return "MO10"; + case REGISTER_Y1: return "Y1"; + case REGISTER_Y10: return "Y10"; + case REGISTER_RESET: return "RESET"; + case REGISTER_REF0: return "REF0"; + case REGISTER_REF1: return "REF1"; + } + + return "INVALID REGISTER"; +} + +enum +{ + H10_PM = 4, + H10_24 = 8 +}; //************************************************************************** @@ -69,7 +99,39 @@ enum inline int msm58321_device::read_counter(int counter) { - return (m_reg[counter + 1] * 10) + m_reg[counter]; + int data = m_reg[counter]; + + if (counter == REGISTER_H1) + { + int h10 = m_reg[REGISTER_H10]; + + if (h10 & H10_24) + { + data += (h10 & 3) * 10; + } + else + { + data += (h10 & 1) * 10; + + if (h10 & H10_PM) + { + if (data != 12) + { + data += 12; + } + } + else if (data == 12) + { + data = 0; + } + } + } + else + { + data += (m_reg[counter + 1] * 10); + } + + return data; } @@ -77,50 +139,71 @@ inline int msm58321_device::read_counter(int counter) // write_counter - //------------------------------------------------- -inline void msm58321_device::write_counter(int counter, int value) +inline void msm58321_device::write_counter(int address, int data) { - m_reg[counter] = value % 10; - m_reg[counter + 1] = value / 10; + int flag = 0; + + switch (address) + { + case REGISTER_H1: + flag = m_reg[REGISTER_H10] & H10_24; + if (!flag) + { + if (data >= 12) + { + data -= 12; + flag = H10_PM; + } + + if (data == 0) + { + data = 12; + } + } + break; + + case REGISTER_D1: + flag = (m_reg[REGISTER_D10] & ~3); + break; + } + + m_reg[address] = data % 10; + m_reg[address + 1] = (data / 10) | flag; } -//************************************************************************** -// LIVE DEVICE -//************************************************************************** - //------------------------------------------------- // msm58321_device - constructor //------------------------------------------------- msm58321_device::msm58321_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, MSM58321, "MSM58321", tag, owner, clock, "msm58321", __FILE__), - device_rtc_interface(mconfig, *this), - m_cs2(0) + device_rtc_interface(mconfig, *this), + device_nvram_interface(mconfig, *this), + m_d0_handler(*this), + m_d1_handler(*this), + m_d2_handler(*this), + m_d3_handler(*this), + m_busy_handler(*this), + m_cs2(0), + m_write(0), + m_read(0), + m_d0_in(0), + m_d0_out(0), + m_d1_in(0), + m_d1_out(0), + m_d2_in(0), + m_d2_out(0), + m_d3_in(0), + m_d3_out(0), + m_address_write(0), + m_busy(0), + m_stop(0), + m_test(0), + m_cs1(0), + m_address(0xf) { - for (int i = 0; i < 13; i++) - m_reg[i] = 0; -} - - -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void msm58321_device::device_config_complete() -{ - // inherit a copy of the static data - const msm58321_interface *intf = reinterpret_cast(static_config()); - if (intf != NULL) - *static_cast(this) = *intf; - - // or initialize to defaults if none provided - else - { - memset(&m_out_busy_cb, 0, sizeof(m_out_busy_cb)); - } } @@ -131,7 +214,11 @@ void msm58321_device::device_config_complete() void msm58321_device::device_start() { // resolve callbacks - m_out_busy_func.resolve(m_out_busy_cb, *this); + m_d0_handler.resolve_safe(); + m_d1_handler.resolve_safe(); + m_d2_handler.resolve_safe(); + m_d3_handler.resolve_safe(); + m_busy_handler.resolve_safe(); // allocate timers m_clock_timer = timer_alloc(TIMER_CLOCK); @@ -141,25 +228,28 @@ void msm58321_device::device_start() m_busy_timer->adjust(attotime::from_hz(clock() / 16384), 0, attotime::from_hz(clock() / 16384)); // state saving - save_item(NAME(m_cs1)); save_item(NAME(m_cs2)); - save_item(NAME(m_busy)); - save_item(NAME(m_read)); save_item(NAME(m_write)); + save_item(NAME(m_read)); + save_item(NAME(m_d0_in)); + save_item(NAME(m_d0_out)); + save_item(NAME(m_d1_in)); + save_item(NAME(m_d1_out)); + save_item(NAME(m_d2_in)); + save_item(NAME(m_d2_out)); + save_item(NAME(m_d3_in)); + save_item(NAME(m_d3_out)); save_item(NAME(m_address_write)); - save_item(NAME(m_reg)); - save_item(NAME(m_latch)); + save_item(NAME(m_busy)); + save_item(NAME(m_stop)); + save_item(NAME(m_test)); + save_item(NAME(m_cs1)); save_item(NAME(m_address)); -} + save_item(NAME(m_reg)); - -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void msm58321_device::device_reset() -{ set_current_time(machine()); + + update_output(); } @@ -176,8 +266,8 @@ void msm58321_device::device_timer(emu_timer &timer, device_timer_id id, int par break; case TIMER_BUSY: - m_out_busy_func(m_busy); m_busy = !m_busy; + m_busy_handler(m_busy); break; } } @@ -189,135 +279,203 @@ void msm58321_device::device_timer(emu_timer &timer, device_timer_id id, int par void msm58321_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) { - write_counter(REGISTER_Y1, year); + write_counter(REGISTER_Y1, (year - m_year0) % 100); write_counter(REGISTER_MO1, month); write_counter(REGISTER_D1, day); m_reg[REGISTER_W] = day_of_week; write_counter(REGISTER_H1, hour); write_counter(REGISTER_MI1, minute); write_counter(REGISTER_S1, second); + + update_output(); +} + +//------------------------------------------------- +// nvram_default - called to initialize NVRAM to +// its default state +//------------------------------------------------- + +void msm58321_device::nvram_default() +{ + for (int i = 0; i < 13; i++) + m_reg[i] = 0; + + if (m_default_24h) + m_reg[REGISTER_H10] = H10_24; + + clock_updated(); } //------------------------------------------------- -// read - +// nvram_read - called to read NVRAM from the +// .nv file //------------------------------------------------- -READ8_MEMBER( msm58321_device::read ) +void msm58321_device::nvram_read(emu_file &file) { - UINT8 data = 0; + file.read(m_reg, sizeof(m_reg)); - if (m_cs1 && m_cs2) - { - if (m_read) - { - switch (m_address) - { - case REGISTER_RESET: - break; - - case REGISTER_REF0: - case REGISTER_REF1: - break; - - default: - data = m_reg[m_address]; - break; - } - } - - if (m_write) - { - if (m_address >= REGISTER_REF0) - { - // TODO: output reference values - } - } - } - - if (LOG) logerror("MSM58321 '%s' Register Read %01x: %01x\n", tag(), m_address, data & 0x0f); - - return data; + clock_updated(); } //------------------------------------------------- -// write - +// nvram_write - called to write NVRAM to the +// .nv file //------------------------------------------------- -WRITE8_MEMBER( msm58321_device::write ) +void msm58321_device::nvram_write(emu_file &file) { - // latch data for future use - m_latch = data & 0x0f; + file.write(m_reg, sizeof(m_reg)); +} - if (!m_cs1 || !m_cs2) return; +//------------------------------------------------- +// update_output - +//------------------------------------------------- - if (m_address_write) +void msm58321_device::update_output() +{ + UINT8 data = 0xf; + + if (m_cs1 && m_cs2 && m_read) { - if (LOG) logerror("MSM58321 '%s' Latch Address %01x\n", tag(), m_latch); - - // latch address - m_address = m_latch; - } - - if (m_write) - { - switch(m_address) + switch (m_address) { case REGISTER_RESET: - if (LOG) logerror("MSM58321 '%s' Reset\n", tag()); + data = 0; break; case REGISTER_REF0: case REGISTER_REF1: - if (LOG) logerror("MSM58321 '%s' Reference Signal\n", tag()); + // TODO: output reference values + data = 0; break; default: - if (LOG) logerror("MSM58321 '%s' Register Write %01x: %01x\n", tag(), m_address, data & 0x0f); - m_reg[m_address] = m_latch & 0x0f; - - set_time(false, read_counter(REGISTER_Y1), read_counter(REGISTER_MO1), read_counter(REGISTER_D1), m_reg[REGISTER_W], - read_counter(REGISTER_H1), read_counter(REGISTER_MI1), read_counter(REGISTER_S1)); + data = m_reg[m_address]; break; } + + if (LOG) logerror("MSM58321 '%s' Register Read %s (%01x): %01x\n", tag(), reg_name(m_address), m_address, data & 0x0f); + } + + int d0 = (data >> 0) & 1; + if (m_d0_out != d0) + { + m_d0_out = d0; + m_d0_handler(d0); + } + + int d1 = (data >> 1) & 1; + if (m_d1_out != d1) + { + m_d1_out = d1; + m_d1_handler(d1); + } + + int d2 = (data >> 2) & 1; + if (m_d2_out != d2) + { + m_d2_out = d2; + m_d2_handler(d2); + } + + int d3 = (data >> 3) & 1; + if (m_d3_out != d3) + { + m_d3_out = d3; + m_d3_handler(d3); } } //------------------------------------------------- -// cs1_w - +// update_input() - //------------------------------------------------- -WRITE_LINE_MEMBER( msm58321_device::cs1_w ) +void msm58321_device::update_input() { - if (LOG) logerror("MSM58321 '%s' CS1: %u\n", tag(), state); + if (m_cs1 && m_cs2) + { + UINT8 data = m_d0_in | (m_d1_in << 1) | (m_d2_in << 2) | (m_d3_in << 3); - m_cs1 = state; + if (m_address_write) + { + if (LOG) logerror("MSM58321 '%s' Latch Address %01x\n", tag(), data); + + // latch address + m_address = data; + } + + if (m_write) + { + switch(m_address) + { + case REGISTER_RESET: + if (LOG) logerror("MSM58321 '%s' Reset\n", tag()); + break; + + case REGISTER_REF0: + case REGISTER_REF1: + if (LOG) logerror("MSM58321 '%s' Reference Signal\n", tag()); + break; + + default: + if (LOG) logerror("MSM58321 '%s' Register Write %s (%01x): %01x\n", tag(), reg_name(m_address), m_address, data); + + switch (m_address) + { + case REGISTER_S10: + case REGISTER_MI10: + case REGISTER_W: + m_reg[m_address] = data & 7; + break; + + case REGISTER_H10: + if (data & H10_24) + { + // "When D3 = 1 is written, the D2 bit is reset inside the IC." + // but it doesn't say if this is done immediately or on the next update + m_reg[m_address] = data & ~H10_PM; + } + else + { + m_reg[m_address] = data; + } + break; + + case REGISTER_MO10: + m_reg[m_address] = data & 1; + break; + + default: + m_reg[m_address] = data; + break; + } + + set_time(false, read_counter(REGISTER_Y1) + m_year0, read_counter(REGISTER_MO1), read_counter(REGISTER_D1), m_reg[REGISTER_W], + read_counter(REGISTER_H1), read_counter(REGISTER_MI1), read_counter(REGISTER_S1)); + break; + } + } + } } - //------------------------------------------------- // cs2_w - //------------------------------------------------- WRITE_LINE_MEMBER( msm58321_device::cs2_w ) { - if (LOG) logerror("MSM58321 '%s' CS2: %u\n", tag(), state); + if (m_cs2 != state) + { + if (LOG) logerror("MSM58321 '%s' CS2: %u\n", tag(), state); - m_cs2 = state; -} + m_cs2 = state; - -//------------------------------------------------- -// read_w - -//------------------------------------------------- - -WRITE_LINE_MEMBER( msm58321_device::read_w ) -{ - if (LOG) logerror("MSM58321 '%s' READ: %u\n", tag(), state); - - m_read = state; + update_input(); + } } @@ -327,9 +485,92 @@ WRITE_LINE_MEMBER( msm58321_device::read_w ) WRITE_LINE_MEMBER( msm58321_device::write_w ) { - if (LOG) logerror("MSM58321 '%s' WRITE: %u\n", tag(), state); + if (m_write != state) + { + if (LOG) logerror("MSM58321 '%s' WRITE: %u\n", tag(), state); - m_write = state; + m_write = state; + + update_input(); + } +} + + +//------------------------------------------------- +// read_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( msm58321_device::read_w ) +{ + if (m_read != state) + { + if (LOG) logerror("MSM58321 '%s' READ: %u\n", tag(), state); + + m_read = state; + + update_output(); + } +} + + + +//------------------------------------------------- +// d0_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( msm58321_device::d0_w ) +{ + if (m_d0_in != state) + { + m_d0_in = state; + + update_input(); + } +} + + +//------------------------------------------------- +// d1_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( msm58321_device::d1_w ) +{ + if (m_d1_in != state) + { + m_d1_in = state; + + update_input(); + } +} + + +//------------------------------------------------- +// d2_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( msm58321_device::d2_w ) +{ + if (m_d2_in != state) + { + m_d2_in = state; + + update_input(); + } +} + + +//------------------------------------------------- +// d3_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( msm58321_device::d3_w ) +{ + if (m_d3_in != state) + { + m_d3_in = state; + + update_input(); + } } @@ -339,16 +580,13 @@ WRITE_LINE_MEMBER( msm58321_device::write_w ) WRITE_LINE_MEMBER( msm58321_device::address_write_w ) { - if (LOG) logerror("MSM58321 '%s' ADDRESS WRITE: %u\n", tag(), state); - - m_address_write = state; - - if (m_address_write) + if (m_address_write != state) { - if (LOG) logerror("MSM58321 '%s' Latch Address %01x\n", tag(), m_latch); + if (LOG) logerror("MSM58321 '%s' ADDRESS WRITE: %u\n", tag(), state); - // latch address - m_address = m_latch; + m_address_write = state; + + update_input(); } } @@ -359,7 +597,12 @@ WRITE_LINE_MEMBER( msm58321_device::address_write_w ) WRITE_LINE_MEMBER( msm58321_device::stop_w ) { - if (LOG) logerror("MSM58321 '%s' STOP: %u\n", tag(), state); + if (m_stop != state) + { + if (LOG) logerror("MSM58321 '%s' STOP: %u\n", tag(), state); + + m_stop = state; + } } @@ -369,15 +612,28 @@ WRITE_LINE_MEMBER( msm58321_device::stop_w ) WRITE_LINE_MEMBER( msm58321_device::test_w ) { - if (LOG) logerror("MSM58321 '%s' TEST: %u\n", tag(), state); + if (m_test != state) + { + if (LOG) logerror("MSM58321 '%s' TEST: %u\n", tag(), state); + + m_test = state; + } } + //------------------------------------------------- -// busy_r - +// cs1_w - //------------------------------------------------- -READ_LINE_MEMBER( msm58321_device::busy_r ) +WRITE_LINE_MEMBER( msm58321_device::cs1_w ) { - return m_busy; + if (m_cs1 != state) + { + if (LOG) logerror("MSM58321 '%s' CS1: %u\n", tag(), state); + + m_cs1 = state; + + update_input(); + } } diff --git a/src/emu/machine/msm58321.h b/src/emu/machine/msm58321.h index 808c642f16a..f759328bc80 100644 --- a/src/emu/machine/msm58321.h +++ b/src/emu/machine/msm58321.h @@ -33,79 +33,109 @@ // INTERFACE CONFIGURATION MACROS //************************************************************************** -#define MCFG_MSM58321_ADD(_tag, _clock, _config) \ - MCFG_DEVICE_ADD(_tag, MSM58321, _clock) \ - MCFG_DEVICE_CONFIG(_config) +#define MCFG_MSM58321_D0_HANDLER(_devcb) \ + devcb = &msm58321_device::set_d0_handler(*device, DEVCB2_##_devcb); -#define MSM58321_INTERFACE(name) \ - const msm58321_interface (name) = +#define MCFG_MSM58321_D1_HANDLER(_devcb) \ + devcb = &msm58321_device::set_d1_handler(*device, DEVCB2_##_devcb); +#define MCFG_MSM58321_D2_HANDLER(_devcb) \ + devcb = &msm58321_device::set_d2_handler(*device, DEVCB2_##_devcb); +#define MCFG_MSM58321_D3_HANDLER(_devcb) \ + devcb = &msm58321_device::set_d3_handler(*device, DEVCB2_##_devcb); -//************************************************************************** -// TYPE DEFINITIONS -//************************************************************************** - -// ======================> msm58321_interface - -struct msm58321_interface -{ - devcb_write_line m_out_busy_cb; -}; +#define MCFG_MSM58321_BUSY_HANDLER(_devcb) \ + devcb = &msm58321_device::set_busy_handler(*device, DEVCB2_##_devcb); +#define MCFG_MSM58321_YEAR0(_year0) \ + msm58321_device::set_year0(*device, _year0); +#define MCFG_MSM58321_DEFAULT_24H(_default_24h) \ + msm58321_device::set_default_24h(*device, _default_24h); // ======================> msm58321_device class msm58321_device : public device_t, public device_rtc_interface, - public msm58321_interface + public device_nvram_interface { public: // construction/destruction msm58321_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + // static configuration helpers + template static devcb2_base &set_d0_handler(device_t &device, _Object object) { return downcast(device).m_d0_handler.set_callback(object); } + template static devcb2_base &set_d1_handler(device_t &device, _Object object) { return downcast(device).m_d1_handler.set_callback(object); } + template static devcb2_base &set_d2_handler(device_t &device, _Object object) { return downcast(device).m_d2_handler.set_callback(object); } + template static devcb2_base &set_d3_handler(device_t &device, _Object object) { return downcast(device).m_d3_handler.set_callback(object); } + template static devcb2_base &set_busy_handler(device_t &device, _Object object) { return downcast(device).m_busy_handler.set_callback(object); } + static void set_year0(device_t &device, int year0) { downcast(device).m_year0 = year0; } + static void set_default_24h(device_t &device, bool default_24h) { downcast(device).m_default_24h = default_24h; } - DECLARE_WRITE_LINE_MEMBER( cs1_w ); DECLARE_WRITE_LINE_MEMBER( cs2_w ); - DECLARE_WRITE_LINE_MEMBER( read_w ); DECLARE_WRITE_LINE_MEMBER( write_w ); + DECLARE_WRITE_LINE_MEMBER( read_w ); + DECLARE_WRITE_LINE_MEMBER( d0_w ); + DECLARE_WRITE_LINE_MEMBER( d1_w ); + DECLARE_WRITE_LINE_MEMBER( d2_w ); + DECLARE_WRITE_LINE_MEMBER( d3_w ); DECLARE_WRITE_LINE_MEMBER( address_write_w ); DECLARE_WRITE_LINE_MEMBER( stop_w ); DECLARE_WRITE_LINE_MEMBER( test_w ); - DECLARE_READ_LINE_MEMBER( busy_r ); + DECLARE_WRITE_LINE_MEMBER( cs1_w ); protected: // device-level overrides - virtual void device_config_complete(); virtual void device_start(); - virtual void device_reset(); virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); // device_rtc_interface overrides virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second); + virtual bool rtc_feature_y2k() { return m_year0 != 0; } + + // device_nvram_interface overrides + virtual void nvram_default(); + virtual void nvram_read(emu_file &file); + virtual void nvram_write(emu_file &file); private: static const device_timer_id TIMER_CLOCK = 0; static const device_timer_id TIMER_BUSY = 1; + void update_input(); + void update_output(); + inline int read_counter(int counter); inline void write_counter(int counter, int value); - devcb_resolved_write_line m_out_busy_func; + int m_year0; + bool m_default_24h; + devcb2_write_line m_d0_handler; + devcb2_write_line m_d1_handler; + devcb2_write_line m_d2_handler; + devcb2_write_line m_d3_handler; + devcb2_write_line m_busy_handler; - int m_cs1; // chip select 1 int m_cs2; // chip select 2 - int m_busy; // busy flag - int m_read; // read data int m_write; // write data + int m_read; // read data + int m_d0_in; // d0 + int m_d0_out; // d0 + int m_d1_in; // d1 + int m_d1_out; // d1 + int m_d2_in; // d2 + int m_d2_out; // d2 + int m_d3_in; // d3 + int m_d3_out; // d3 int m_address_write; // write address + int m_busy; // busy flag + int m_stop; // stop flag + int m_test; // test flag + int m_cs1; // chip select 1 - UINT8 m_reg[13]; // registers - UINT8 m_latch; // data latch (not present in real chip) UINT8 m_address; // address latch + UINT8 m_reg[13]; // registers // timers emu_timer *m_clock_timer; @@ -116,6 +146,4 @@ private: // device type definition extern const device_type MSM58321; - - #endif diff --git a/src/mess/drivers/pc100.c b/src/mess/drivers/pc100.c index a6bc54ed6b6..9e22886433f 100644 --- a/src/mess/drivers/pc100.c +++ b/src/mess/drivers/pc100.c @@ -71,7 +71,10 @@ public: m_rtc(*this, "rtc"), m_palram(*this, "palram"), m_maincpu(*this, "maincpu"), - m_beeper(*this, "beeper") { } + m_beeper(*this, "beeper"), + m_rtc_portc(0) + { + } required_device m_rtc; required_shared_ptr m_palram; @@ -94,6 +97,8 @@ public: DECLARE_WRITE8_MEMBER(upper_mask_w); DECLARE_WRITE8_MEMBER(crtc_bank_w); DECLARE_WRITE8_MEMBER(rtc_porta_w); + DECLARE_READ8_MEMBER(rtc_portc_r); + DECLARE_WRITE8_MEMBER(rtc_portc_w); DECLARE_WRITE_LINE_MEMBER(pc100_set_int_line); UINT16 *m_kanji_rom; UINT16 *m_vram; @@ -121,6 +126,12 @@ public: IRQ_CALLBACK_MEMBER(pc100_irq_callback); required_device m_maincpu; required_device m_beeper; + + WRITE_LINE_MEMBER(rtc_portc_0_w) { m_rtc_portc = (m_rtc_portc & ~(1 << 0)) | ((state & 1) << 0); } + WRITE_LINE_MEMBER(rtc_portc_1_w) { m_rtc_portc = (m_rtc_portc & ~(1 << 1)) | ((state & 1) << 1); } + WRITE_LINE_MEMBER(rtc_portc_2_w) { m_rtc_portc = (m_rtc_portc & ~(1 << 2)) | ((state & 1) << 2); } + WRITE_LINE_MEMBER(rtc_portc_3_w) { m_rtc_portc = (m_rtc_portc & ~(1 << 3)) | ((state & 1) << 3); } + UINT8 m_rtc_portc; }; void pc100_state::video_start() @@ -363,9 +374,22 @@ WRITE8_MEMBER( pc100_state::rtc_porta_w ) ---- ---x write */ - m_rtc->write_w(data & 1); - m_rtc->read_w((data & 2) >> 1); - m_rtc->cs1_w((data & 4) >> 2); + m_rtc->write_w((data >> 0) & 1); + m_rtc->read_w((data >> 1) & 1); + m_rtc->cs1_w((data >> 2) & 1); +} + +WRITE8_MEMBER( pc100_state::rtc_portc_w ) +{ + m_rtc->d0_w((data >> 0) & 1); + m_rtc->d1_w((data >> 1) & 1); + m_rtc->d2_w((data >> 2) & 1); + m_rtc->d3_w((data >> 3) & 1); +} + +READ8_MEMBER( pc100_state::rtc_portc_r ) +{ + return m_rtc_portc; } static I8255A_INTERFACE( pc100_ppi8255_interface_1 ) @@ -374,8 +398,8 @@ static I8255A_INTERFACE( pc100_ppi8255_interface_1 ) DEVCB_DRIVER_MEMBER(pc100_state, rtc_porta_w), DEVCB_NULL, DEVCB_NULL, - DEVCB_DEVICE_MEMBER("rtc", msm58321_device, read), - DEVCB_DEVICE_MEMBER("rtc", msm58321_device, write) + DEVCB_DRIVER_MEMBER(pc100_state, rtc_portc_r), + DEVCB_DRIVER_MEMBER(pc100_state, rtc_portc_w) }; @@ -475,11 +499,6 @@ static SLOT_INTERFACE_START( pc100_floppies ) SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) SLOT_INTERFACE_END -static MSM58321_INTERFACE( rtc_intf ) -{ - DEVCB_NULL -}; - #define MASTER_CLOCK 6988800 static MACHINE_CONFIG_START( pc100, pc100_state ) @@ -497,7 +516,12 @@ static MACHINE_CONFIG_START( pc100, pc100_state ) MCFG_I8255_ADD( "ppi8255_2", pc100_ppi8255_interface_2 ) MCFG_PIC8259_ADD( "pic8259", WRITELINE(pc100_state, pc100_set_int_line), GND, NULL ) MCFG_UPD765A_ADD("upd765", true, true) - MCFG_MSM58321_ADD("rtc", XTAL_32_768kHz, rtc_intf) + + MCFG_DEVICE_ADD("rtc", MSM58321, XTAL_32_768kHz) + MCFG_MSM58321_D0_HANDLER(WRITELINE(pc100_state, rtc_portc_0_w)) + MCFG_MSM58321_D1_HANDLER(WRITELINE(pc100_state, rtc_portc_1_w)) + MCFG_MSM58321_D2_HANDLER(WRITELINE(pc100_state, rtc_portc_2_w)) + MCFG_MSM58321_D3_HANDLER(WRITELINE(pc100_state, rtc_portc_3_w)) MCFG_FLOPPY_DRIVE_ADD("upd765:0", pc100_floppies, "525hd", floppy_image_device::default_floppy_formats) MCFG_FLOPPY_DRIVE_ADD("upd765:1", pc100_floppies, "525hd", floppy_image_device::default_floppy_formats) diff --git a/src/mess/drivers/v1050.c b/src/mess/drivers/v1050.c index 6f90dc2de08..0d8c2cdef28 100644 --- a/src/mess/drivers/v1050.c +++ b/src/mess/drivers/v1050.c @@ -671,13 +671,6 @@ static I8214_INTERFACE( pic_intf ) DEVCB_NULL }; -// MSM58321 Interface - -static MSM58321_INTERFACE( rtc_intf ) -{ - DEVCB_NULL -}; - // Display 8255A Interface WRITE8_MEMBER(v1050_state::disp_ppi_pc_w) @@ -864,6 +857,19 @@ WRITE8_MEMBER( v1050_state::rtc_ppi_pb_w ) m_int_mask = data; } +READ8_MEMBER( v1050_state::rtc_ppi_pa_r ) +{ + return m_rtc_ppi_pa; +} + +WRITE8_MEMBER( v1050_state::rtc_ppi_pa_w ) +{ + m_rtc->d0_w((data >> 0) & 1); + m_rtc->d1_w((data >> 1) & 1); + m_rtc->d2_w((data >> 2) & 1); + m_rtc->d3_w((data >> 3) & 1); +} + READ8_MEMBER( v1050_state::rtc_ppi_pc_r ) { /* @@ -881,7 +887,7 @@ READ8_MEMBER( v1050_state::rtc_ppi_pc_r ) */ - return m_rtc->busy_r() << 3; + return m_rtc_ppi_pc; } WRITE8_MEMBER( v1050_state::rtc_ppi_pc_w ) @@ -909,8 +915,8 @@ WRITE8_MEMBER( v1050_state::rtc_ppi_pc_w ) static I8255A_INTERFACE( rtc_ppi_intf ) { - DEVCB_DEVICE_MEMBER(MSM58321RS_TAG, msm58321_device, read), - DEVCB_DEVICE_MEMBER(MSM58321RS_TAG, msm58321_device, write), + DEVCB_DRIVER_MEMBER(v1050_state, rtc_ppi_pa_r), + DEVCB_DRIVER_MEMBER(v1050_state, rtc_ppi_pa_w), DEVCB_NULL, DEVCB_DRIVER_MEMBER(v1050_state, rtc_ppi_pb_w), DEVCB_DRIVER_MEMBER(v1050_state, rtc_ppi_pc_r), @@ -1119,7 +1125,14 @@ static MACHINE_CONFIG_START( v1050, v1050_state ) // devices MCFG_I8214_ADD(UPB8214_TAG, XTAL_16MHz/4, pic_intf) - MCFG_MSM58321_ADD(MSM58321RS_TAG, XTAL_32_768kHz, rtc_intf) + + MCFG_DEVICE_ADD(MSM58321RS_TAG, MSM58321, XTAL_32_768kHz) + MCFG_MSM58321_D0_HANDLER(WRITELINE(v1050_state, rtc_ppi_pa_0_w)) + MCFG_MSM58321_D1_HANDLER(WRITELINE(v1050_state, rtc_ppi_pa_1_w)) + MCFG_MSM58321_D2_HANDLER(WRITELINE(v1050_state, rtc_ppi_pa_2_w)) + MCFG_MSM58321_D3_HANDLER(WRITELINE(v1050_state, rtc_ppi_pa_3_w)) + MCFG_MSM58321_BUSY_HANDLER(WRITELINE(v1050_state, rtc_ppi_pc_3_w)) + MCFG_I8255A_ADD(I8255A_DISP_TAG, disp_ppi_intf) MCFG_I8255A_ADD(I8255A_MISC_TAG, misc_ppi_intf) MCFG_I8255A_ADD(I8255A_RTC_TAG, rtc_ppi_intf) diff --git a/src/mess/includes/v1050.h b/src/mess/includes/v1050.h index 02aaab281ae..4c4bc12fb3f 100644 --- a/src/mess/includes/v1050.h +++ b/src/mess/includes/v1050.h @@ -85,8 +85,11 @@ public: m_sasibus(*this, SASIBUS_TAG ":host"), m_rom(*this, Z80_TAG), m_video_ram(*this, "video_ram"), - m_attr_ram(*this, "attr_ram") - { } + m_attr_ram(*this, "attr_ram"), + m_rtc_ppi_pa(0), + m_rtc_ppi_pc(0) + { + } required_device m_maincpu; required_device m_subcpu; @@ -130,6 +133,8 @@ public: DECLARE_WRITE8_MEMBER( p2_w ); DECLARE_WRITE8_MEMBER( misc_ppi_pa_w ); DECLARE_WRITE8_MEMBER( misc_ppi_pc_w ); + DECLARE_READ8_MEMBER( rtc_ppi_pa_r ); + DECLARE_WRITE8_MEMBER( rtc_ppi_pa_w ); DECLARE_WRITE8_MEMBER( rtc_ppi_pb_w ); DECLARE_READ8_MEMBER( rtc_ppi_pc_r ); DECLARE_WRITE8_MEMBER( rtc_ppi_pc_w ); @@ -148,6 +153,14 @@ public: DECLARE_READ8_MEMBER( sasi_status_r ); DECLARE_WRITE8_MEMBER( sasi_ctrl_w ); + WRITE_LINE_MEMBER( rtc_ppi_pa_0_w ){ m_rtc_ppi_pa = (m_rtc_ppi_pa & ~(1 << 0)) | ((state & 1) << 0); } + WRITE_LINE_MEMBER( rtc_ppi_pa_1_w ){ m_rtc_ppi_pa = (m_rtc_ppi_pa & ~(1 << 1)) | ((state & 1) << 1); } + WRITE_LINE_MEMBER( rtc_ppi_pa_2_w ){ m_rtc_ppi_pa = (m_rtc_ppi_pa & ~(1 << 2)) | ((state & 1) << 2); } + WRITE_LINE_MEMBER( rtc_ppi_pa_3_w ){ m_rtc_ppi_pa = (m_rtc_ppi_pa & ~(1 << 3)) | ((state & 1) << 3); } + UINT8 m_rtc_ppi_pa; + WRITE_LINE_MEMBER( rtc_ppi_pc_3_w ){ m_rtc_ppi_pc = (m_rtc_ppi_pc & ~(1 << 3)) | ((state & 1) << 3); } + UINT8 m_rtc_ppi_pc; + void bankswitch(); void update_fdc(); void set_interrupt(UINT8 mask, int state);