From db18011bd8d523e7a33a74cac3956d6e83475db8 Mon Sep 17 00:00:00 2001 From: Angelo Salese Date: Fri, 7 Dec 2012 15:48:05 +0000 Subject: [PATCH] Preliminary support for Test Mode in upd1990a RTC device [Angelo Salese] --- src/emu/machine/upd1990a.c | 61 +++++++++++++++++++++++++++++++------- src/emu/machine/upd1990a.h | 2 ++ src/mess/drivers/pc9801.c | 4 +-- 3 files changed, 55 insertions(+), 12 deletions(-) diff --git a/src/emu/machine/upd1990a.c b/src/emu/machine/upd1990a.c index b131640d638..d13ba56b627 100644 --- a/src/emu/machine/upd1990a.c +++ b/src/emu/machine/upd1990a.c @@ -11,7 +11,8 @@ TODO: - - test mode + - set tp = 64 Hz when out of test mode + - test mode is mostly untested (is used by MS-DOS 6.2x in PC-98xx) */ @@ -97,6 +98,7 @@ void upd1990a_device::device_start() m_timer_clock->adjust(attotime::from_hz(clock() / 32768), 0, attotime::from_hz(clock() / 32768)); m_timer_tp = timer_alloc(TIMER_TP); m_timer_data_out = timer_alloc(TIMER_DATA_OUT); + m_timer_test_mode = timer_alloc(TIMER_TEST_MODE); // state saving save_item(NAME(m_time_counter)); @@ -150,6 +152,31 @@ void upd1990a_device::device_timer(emu_timer &timer, device_timer_id id, int par m_out_data_func(m_data_out); break; + + case TIMER_TEST_MODE: + if (m_oe) + { + /* time counter is advanced at 1024 Hz from "Second" counter input */ + int i; + + for(i=0;i<4;i++) + { + m_time_counter[i]++; + if(m_time_counter[i] != 0) + return; + } + } + else // parallel + { + /* each counter is advanced at 1024 Hz in parallel, overflow carry does not affect next counter */ + m_time_counter[0]++; + m_time_counter[1]++; + m_time_counter[2]++; + m_time_counter[3]++; + m_time_counter[4]++; + } + + break; } } @@ -214,6 +241,8 @@ WRITE_LINE_MEMBER( upd1990a_device::stb_w ) /* enable time counter */ m_timer_clock->enable(1); + m_timer_test_mode->enable(0); + /* 1 Hz data out pulse */ m_data_out = 1; m_timer_data_out->adjust(attotime::zero, 0, attotime::from_hz(1*2)); @@ -231,6 +260,8 @@ WRITE_LINE_MEMBER( upd1990a_device::stb_w ) /* disable data out pulse */ m_timer_data_out->enable(0); + m_timer_test_mode->enable(0); + /* output LSB of shift register */ m_data_out = BIT(m_shift_reg[0], 0); m_out_data_func(m_data_out); @@ -249,6 +280,8 @@ WRITE_LINE_MEMBER( upd1990a_device::stb_w ) /* disable data out pulse */ m_timer_data_out->enable(0); + m_timer_test_mode->enable(0); + /* output LSB of shift register */ m_data_out = BIT(m_shift_reg[0], 0); m_out_data_func(m_data_out); @@ -271,6 +304,8 @@ WRITE_LINE_MEMBER( upd1990a_device::stb_w ) /* enable time counter */ m_timer_clock->enable(1); + m_timer_test_mode->enable(0); + /* load time counter data into shift register */ for (int i = 0; i < 5; i++) { @@ -290,6 +325,8 @@ WRITE_LINE_MEMBER( upd1990a_device::stb_w ) case MODE_TP_64HZ_SET: if (LOG) logerror("uPD1990A '%s' TP = 64 Hz Set Mode\n", tag()); + m_timer_test_mode->enable(0); + /* 64 Hz time pulse */ m_timer_tp->adjust(attotime::zero, 0, attotime::from_hz(64*2)); break; @@ -297,6 +334,8 @@ WRITE_LINE_MEMBER( upd1990a_device::stb_w ) case MODE_TP_256HZ_SET: if (LOG) logerror("uPD1990A '%s' TP = 256 Hz Set Mode\n", tag()); + m_timer_test_mode->enable(0); + /* 256 Hz time pulse */ m_timer_tp->adjust(attotime::zero, 0, attotime::from_hz(256*2)); break; @@ -304,22 +343,24 @@ WRITE_LINE_MEMBER( upd1990a_device::stb_w ) case MODE_TP_2048HZ_SET: if (LOG) logerror("uPD1990A '%s' TP = 2048 Hz Set Mode\n", tag()); + m_timer_test_mode->enable(0); + /* 2048 Hz time pulse */ m_timer_tp->adjust(attotime::zero, 0, attotime::from_hz(2048*2)); break; case MODE_TEST: - if (LOG) logerror("uPD1990A '%s' Test Mode not supported!\n", tag()); + if (LOG) logerror("uPD1990A '%s' Test Mode\n", tag()); - if (m_oe) - { - /* time counter is advanced at 1024 Hz from "Second" counter input */ - } - else - { - /* each counter is advanced at 1024 Hz in parallel, overflow carry does not affect next counter */ - } + /* disable time counter */ + m_timer_clock->enable(0); + /* disable data out pulse */ + m_timer_data_out->enable(0); + + m_timer_test_mode->enable(1); + + m_timer_test_mode->adjust(attotime::zero, 0, attotime::from_hz(1024)); break; } } diff --git a/src/emu/machine/upd1990a.h b/src/emu/machine/upd1990a.h index 60f33937896..1d4d3385b0c 100644 --- a/src/emu/machine/upd1990a.h +++ b/src/emu/machine/upd1990a.h @@ -94,6 +94,7 @@ private: static const device_timer_id TIMER_CLOCK = 0; static const device_timer_id TIMER_TP = 1; static const device_timer_id TIMER_DATA_OUT = 2; + static const device_timer_id TIMER_TEST_MODE = 3; devcb_resolved_write_line m_out_data_func; devcb_resolved_write_line m_out_tp_func; @@ -115,6 +116,7 @@ private: emu_timer *m_timer_clock; emu_timer *m_timer_tp; emu_timer *m_timer_data_out; + emu_timer *m_timer_test_mode; }; diff --git a/src/mess/drivers/pc9801.c b/src/mess/drivers/pc9801.c index 7394446a80b..d64644d2693 100644 --- a/src/mess/drivers/pc9801.c +++ b/src/mess/drivers/pc9801.c @@ -854,7 +854,7 @@ WRITE8_MEMBER(pc9801_state::pc9801_20_w) m_rtc->c2_w((data & 0x04) >> 2); m_rtc->stb_w((data & 0x08) >> 3); m_rtc->clk_w((data & 0x10) >> 4); - m_rtc->data_in_w((data & 0x20) >> 5); + m_rtc->data_in_w(((data & 0x20) >> 5)); if(data & 0xc0) printf("RTC write to undefined bits %02x\n",data & 0xc0); } @@ -3147,7 +3147,7 @@ MACHINE_START_MEMBER(pc9801_state,pc9801_common) machine().device("maincpu")->execute().set_irq_acknowledge_callback(irq_callback); m_rtc->cs_w(1); - m_rtc->oe_w(1); + m_rtc->oe_w(0); // TODO: unknown connection, MS-DOS 6.2x wants this low somehow with the test mode m_ipl_rom = memregion("ipl")->base(); }