Preliminary support for Test Mode in upd1990a RTC device [Angelo Salese]

This commit is contained in:
Angelo Salese 2012-12-07 15:48:05 +00:00
parent 2986022ca0
commit db18011bd8
3 changed files with 55 additions and 12 deletions

View File

@ -11,7 +11,8 @@
TODO: 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_clock->adjust(attotime::from_hz(clock() / 32768), 0, attotime::from_hz(clock() / 32768));
m_timer_tp = timer_alloc(TIMER_TP); m_timer_tp = timer_alloc(TIMER_TP);
m_timer_data_out = timer_alloc(TIMER_DATA_OUT); m_timer_data_out = timer_alloc(TIMER_DATA_OUT);
m_timer_test_mode = timer_alloc(TIMER_TEST_MODE);
// state saving // state saving
save_item(NAME(m_time_counter)); 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); m_out_data_func(m_data_out);
break; 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 */ /* enable time counter */
m_timer_clock->enable(1); m_timer_clock->enable(1);
m_timer_test_mode->enable(0);
/* 1 Hz data out pulse */ /* 1 Hz data out pulse */
m_data_out = 1; m_data_out = 1;
m_timer_data_out->adjust(attotime::zero, 0, attotime::from_hz(1*2)); 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 */ /* disable data out pulse */
m_timer_data_out->enable(0); m_timer_data_out->enable(0);
m_timer_test_mode->enable(0);
/* output LSB of shift register */ /* output LSB of shift register */
m_data_out = BIT(m_shift_reg[0], 0); m_data_out = BIT(m_shift_reg[0], 0);
m_out_data_func(m_data_out); m_out_data_func(m_data_out);
@ -249,6 +280,8 @@ WRITE_LINE_MEMBER( upd1990a_device::stb_w )
/* disable data out pulse */ /* disable data out pulse */
m_timer_data_out->enable(0); m_timer_data_out->enable(0);
m_timer_test_mode->enable(0);
/* output LSB of shift register */ /* output LSB of shift register */
m_data_out = BIT(m_shift_reg[0], 0); m_data_out = BIT(m_shift_reg[0], 0);
m_out_data_func(m_data_out); m_out_data_func(m_data_out);
@ -271,6 +304,8 @@ WRITE_LINE_MEMBER( upd1990a_device::stb_w )
/* enable time counter */ /* enable time counter */
m_timer_clock->enable(1); m_timer_clock->enable(1);
m_timer_test_mode->enable(0);
/* load time counter data into shift register */ /* load time counter data into shift register */
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
{ {
@ -290,6 +325,8 @@ WRITE_LINE_MEMBER( upd1990a_device::stb_w )
case MODE_TP_64HZ_SET: case MODE_TP_64HZ_SET:
if (LOG) logerror("uPD1990A '%s' TP = 64 Hz Set Mode\n", tag()); if (LOG) logerror("uPD1990A '%s' TP = 64 Hz Set Mode\n", tag());
m_timer_test_mode->enable(0);
/* 64 Hz time pulse */ /* 64 Hz time pulse */
m_timer_tp->adjust(attotime::zero, 0, attotime::from_hz(64*2)); m_timer_tp->adjust(attotime::zero, 0, attotime::from_hz(64*2));
break; break;
@ -297,6 +334,8 @@ WRITE_LINE_MEMBER( upd1990a_device::stb_w )
case MODE_TP_256HZ_SET: case MODE_TP_256HZ_SET:
if (LOG) logerror("uPD1990A '%s' TP = 256 Hz Set Mode\n", tag()); if (LOG) logerror("uPD1990A '%s' TP = 256 Hz Set Mode\n", tag());
m_timer_test_mode->enable(0);
/* 256 Hz time pulse */ /* 256 Hz time pulse */
m_timer_tp->adjust(attotime::zero, 0, attotime::from_hz(256*2)); m_timer_tp->adjust(attotime::zero, 0, attotime::from_hz(256*2));
break; break;
@ -304,22 +343,24 @@ WRITE_LINE_MEMBER( upd1990a_device::stb_w )
case MODE_TP_2048HZ_SET: case MODE_TP_2048HZ_SET:
if (LOG) logerror("uPD1990A '%s' TP = 2048 Hz Set Mode\n", tag()); if (LOG) logerror("uPD1990A '%s' TP = 2048 Hz Set Mode\n", tag());
m_timer_test_mode->enable(0);
/* 2048 Hz time pulse */ /* 2048 Hz time pulse */
m_timer_tp->adjust(attotime::zero, 0, attotime::from_hz(2048*2)); m_timer_tp->adjust(attotime::zero, 0, attotime::from_hz(2048*2));
break; break;
case MODE_TEST: 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) /* disable time counter */
{ m_timer_clock->enable(0);
/* 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 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; break;
} }
} }

View File

@ -94,6 +94,7 @@ private:
static const device_timer_id TIMER_CLOCK = 0; static const device_timer_id TIMER_CLOCK = 0;
static const device_timer_id TIMER_TP = 1; static const device_timer_id TIMER_TP = 1;
static const device_timer_id TIMER_DATA_OUT = 2; 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_data_func;
devcb_resolved_write_line m_out_tp_func; devcb_resolved_write_line m_out_tp_func;
@ -115,6 +116,7 @@ private:
emu_timer *m_timer_clock; emu_timer *m_timer_clock;
emu_timer *m_timer_tp; emu_timer *m_timer_tp;
emu_timer *m_timer_data_out; emu_timer *m_timer_data_out;
emu_timer *m_timer_test_mode;
}; };

View File

@ -854,7 +854,7 @@ WRITE8_MEMBER(pc9801_state::pc9801_20_w)
m_rtc->c2_w((data & 0x04) >> 2); m_rtc->c2_w((data & 0x04) >> 2);
m_rtc->stb_w((data & 0x08) >> 3); m_rtc->stb_w((data & 0x08) >> 3);
m_rtc->clk_w((data & 0x10) >> 4); 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) if(data & 0xc0)
printf("RTC write to undefined bits %02x\n",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); machine().device("maincpu")->execute().set_irq_acknowledge_callback(irq_callback);
m_rtc->cs_w(1); 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(); m_ipl_rom = memregion("ipl")->base();
} }