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