summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2018-01-07 12:28:59 -0500
committer AJR <ajrhacker@users.noreply.github.com>2018-01-07 12:28:59 -0500
commit17973ac585aab60d571766b70cf6a6cc6d63b7de (patch)
tree3b9a419854d8c540b3a58e9dc569e71b955debb7
parent81d96c1e9459ce05a523def9688b0c6c9ffe91a7 (diff)
tms9927: Correct sync timings; add untested HSYN callback (nw)
-rw-r--r--src/devices/video/tms9927.cpp61
-rw-r--r--src/devices/video/tms9927.h24
-rw-r--r--src/mame/drivers/zms8085.cpp22
3 files changed, 79 insertions, 28 deletions
diff --git a/src/devices/video/tms9927.cpp b/src/devices/video/tms9927.cpp
index 95be89ba7b8..5ff1f686eb5 100644
--- a/src/devices/video/tms9927.cpp
+++ b/src/devices/video/tms9927.cpp
@@ -45,13 +45,14 @@ tms9927_device::tms9927_device(const machine_config &mconfig, device_type type,
: device_t(mconfig, type, tag, owner, clock)
, device_video_interface(mconfig, *this)
, m_write_vsyn(*this)
+ , m_write_hsyn(*this)
, m_hpixels_per_column(0)
, m_overscan_left(0)
, m_overscan_right(0)
, m_overscan_top(0)
, m_overscan_bottom(0)
, m_selfload(*this, finder_base::DUMMY_TAG)
- , m_reset(0)
+ , m_reset(false)
{
std::fill(std::begin(m_reg), std::end(m_reg), 0x00);
}
@@ -86,9 +87,11 @@ void tms9927_device::device_start()
// resolve callbacks
m_write_vsyn.resolve_safe();
+ m_write_hsyn.resolve();
// allocate timers
m_vsync_timer = timer_alloc(TIMER_VSYNC);
+ m_hsync_timer = timer_alloc(TIMER_HSYNC);
/* register for state saving */
machine().save().register_postload(save_prepost_delegate(FUNC(tms9927_device::state_postload), this));
@@ -96,6 +99,8 @@ void tms9927_device::device_start()
save_item(NAME(m_reg));
save_item(NAME(m_start_datarow));
save_item(NAME(m_reset));
+ save_item(NAME(m_vsyn));
+ save_item(NAME(m_hsyn));
}
//-------------------------------------------------
@@ -133,18 +138,36 @@ void tms9927_device::device_timer(emu_timer &timer, device_timer_id id, int para
{
case TIMER_VSYNC:
m_vsyn = !m_vsyn;
-
- m_write_vsyn(m_vsyn);
+ m_write_vsyn(m_vsyn ? 1 : 0);
if (m_vsyn)
{
- m_vsync_timer->adjust(screen().time_until_pos(3));
+ m_vsync_timer->adjust(screen().time_until_pos(m_vsyn_end, m_hsyn_start));
}
else
{
- m_vsync_timer->adjust(screen().time_until_pos(0));
+ m_vsync_timer->adjust(screen().time_until_pos(m_vsyn_start, m_hsyn_start));
}
break;
+
+ case TIMER_HSYNC:
+ m_hsyn = !m_hsyn;
+ m_write_hsyn(m_hsyn ? 1 : 0);
+
+ uint16_t vpos = screen().vpos();
+ if (m_hsyn)
+ {
+ screen().update_now();
+ if (screen().hpos() > m_hsyn_end)
+ vpos = (vpos + 1) % m_total_vpix;
+ m_hsync_timer->adjust(screen().time_until_pos(vpos, m_hsyn_end));
+ }
+ else
+ {
+ if (screen().hpos() > m_hsyn_start)
+ vpos = (vpos + 1) % m_total_vpix;
+ m_hsync_timer->adjust(screen().time_until_pos(vpos, m_hsyn_start));
+ }
}
}
@@ -247,11 +270,11 @@ READ8_MEMBER( tms9927_device::read )
READ_LINE_MEMBER(tms9927_device::bl_r)
{
- return (screen().vblank() || screen().hblank()) ? 1 : 0;
+ return (m_reset || screen().vblank() || screen().hblank()) ? 1 : 0;
}
-int tms9927_device::screen_reset()
+bool tms9927_device::screen_reset()
{
return m_reset;
}
@@ -263,7 +286,7 @@ int tms9927_device::upscroll_offset()
}
-int tms9927_device::cursor_bounds(rectangle &bounds)
+bool tms9927_device::cursor_bounds(rectangle &bounds)
{
int cursorx = CURSOR_CHAR_ADDRESS;
int cursory = CURSOR_ROW_ADDRESS;
@@ -279,9 +302,6 @@ int tms9927_device::cursor_bounds(rectangle &bounds)
void tms9927_device::recompute_parameters(bool postload)
{
- attoseconds_t refresh;
- rectangle visarea;
-
if (m_reset)
return;
@@ -295,7 +315,13 @@ void tms9927_device::recompute_parameters(bool postload)
m_start_datarow = (LAST_DISP_DATA_ROW + 1) % DATA_ROWS_PER_FRAME;
- osd_printf_debug("TMS9927: Total = %dx%d, Visible = %dx%d, Skew=%d, Upscroll=%d\n", m_total_hpix, m_total_vpix, m_visible_hpix, m_visible_vpix, SKEW_BITS, m_start_datarow);
+ m_hsyn_start = (m_visible_hpix + m_overscan_left + HSYNC_DELAY * m_hpixels_per_column) % m_total_hpix;
+ m_hsyn_end = (m_hsyn_start + HSYNC_WIDTH * m_hpixels_per_column) % m_total_hpix;
+
+ m_vsyn_start = (m_total_vpix + m_overscan_top - VERTICAL_DATA_START) % m_total_vpix;
+ m_vsyn_end = (m_vsyn_start + 3) % m_total_vpix;
+
+ osd_printf_debug("TMS9927: Total = %dx%d, Visible = %dx%d, HSync = %d-%d, VSync = %d-%d, Skew=%d, Upscroll=%d\n", m_total_hpix, m_total_vpix, m_visible_hpix, m_visible_vpix, m_hsyn_start, m_hsyn_end, m_vsyn_start, m_vsyn_end, SKEW_BITS, m_start_datarow);
/* see if it all makes sense */
m_valid_config = true;
@@ -317,14 +343,17 @@ void tms9927_device::recompute_parameters(bool postload)
return;
/* create a visible area */
- visarea.set(0, m_overscan_left + m_visible_hpix + m_overscan_right - 1,
+ rectangle visarea(0, m_overscan_left + m_visible_hpix + m_overscan_right - 1,
0, m_overscan_top + m_visible_vpix + m_overscan_bottom - 1);
- refresh = HZ_TO_ATTOSECONDS(m_clock) * m_total_hpix * m_total_vpix;
+ attoseconds_t refresh = HZ_TO_ATTOSECONDS(m_clock) * m_total_hpix * m_total_vpix;
screen().configure(m_total_hpix, m_total_vpix, visarea, refresh);
- m_vsyn = 0;
- m_vsync_timer->adjust(screen().time_until_pos(0, 0));
+ m_hsyn = false;
+ if (!m_write_hsyn.isnull())
+ m_hsync_timer->adjust(screen().time_until_pos(m_vsyn_start, m_hsyn_start));
+ m_vsyn = false;
+ m_vsync_timer->adjust(screen().time_until_pos(m_vsyn_start, m_hsyn_start));
}
diff --git a/src/devices/video/tms9927.h b/src/devices/video/tms9927.h
index 5358b9b271b..feb49a83be1 100644
--- a/src/devices/video/tms9927.h
+++ b/src/devices/video/tms9927.h
@@ -13,6 +13,9 @@
#define MCFG_TMS9927_VSYN_CALLBACK(_write) \
devcb = &tms9927_device::set_vsyn_wr_callback(*device, DEVCB_##_write);
+#define MCFG_TMS9927_HSYN_CALLBACK(_write) \
+ devcb = &tms9927_device::set_hsyn_wr_callback(*device, DEVCB_##_write);
+
#define MCFG_TMS9927_CHAR_WIDTH(_pixels) \
tms9927_device::set_char_width(*device, _pixels);
@@ -28,6 +31,7 @@ public:
tms9927_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template <class Object> static devcb_base &set_vsyn_wr_callback(device_t &device, Object &&cb) { return downcast<tms9927_device &>(device).m_write_vsyn.set_callback(std::forward<Object>(cb)); }
+ template <class Object> static devcb_base &set_hsyn_wr_callback(device_t &device, Object &&cb) { return downcast<tms9927_device &>(device).m_write_hsyn.set_callback(std::forward<Object>(cb)); }
static void set_char_width(device_t &device, int pixels) { downcast<tms9927_device &>(device).m_hpixels_per_column = pixels; }
static void set_region_tag(device_t &device, const char *tag) { downcast<tms9927_device &>(device).m_selfload.set_tag(tag); }
@@ -44,9 +48,9 @@ public:
DECLARE_READ_LINE_MEMBER(bl_r);
- int screen_reset();
+ bool screen_reset();
int upscroll_offset();
- int cursor_bounds(rectangle &bounds);
+ bool cursor_bounds(rectangle &bounds);
protected:
tms9927_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
@@ -60,7 +64,8 @@ protected:
private:
enum
{
- TIMER_VSYNC
+ TIMER_VSYNC,
+ TIMER_HSYNC
};
void state_postload();
@@ -68,6 +73,8 @@ private:
void generic_access(address_space &space, offs_t offset);
devcb_write_line m_write_vsyn;
+ devcb_write_line m_write_hsyn;
+
int m_hpixels_per_column; /* number of pixels per video memory address */
uint16_t m_overscan_left;
uint16_t m_overscan_right;
@@ -81,16 +88,19 @@ private:
uint32_t m_clock;
uint8_t m_reg[9];
uint8_t m_start_datarow;
- uint8_t m_reset;
+ bool m_reset;
+ bool m_vsyn;
+ bool m_hsyn;
/* derived state; no need to save */
- uint8_t m_valid_config;
+ bool m_valid_config;
uint16_t m_total_hpix, m_total_vpix;
uint16_t m_visible_hpix, m_visible_vpix;
-
- int m_vsyn;
+ uint16_t m_vsyn_start, m_vsyn_end;
+ uint16_t m_hsyn_start, m_hsyn_end;
emu_timer *m_vsync_timer;
+ emu_timer *m_hsync_timer;
};
diff --git a/src/mame/drivers/zms8085.cpp b/src/mame/drivers/zms8085.cpp
index f9ff27c46e8..7d8053d314a 100644
--- a/src/mame/drivers/zms8085.cpp
+++ b/src/mame/drivers/zms8085.cpp
@@ -30,6 +30,8 @@ public:
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+ DECLARE_READ8_MEMBER(special_r);
+
private:
required_device<cpu_device> m_maincpu;
required_device<screen_device> m_screen;
@@ -62,12 +64,19 @@ u32 zms8085_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, co
}
+READ8_MEMBER(zms8085_state::special_r)
+{
+ return 0x40;
+}
+
+
static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, zms8085_state )
- AM_RANGE(0x0000, 0x0fff) AM_ROM AM_REGION("maincpu", 0)
+ AM_RANGE(0x0000, 0x0fff) AM_ROM AM_REGION("maincpu", 0) AM_WRITENOP
AM_RANGE(0x1000, 0x1fff) AM_RAM AM_SHARE("mainram")
ADDRESS_MAP_END
static ADDRESS_MAP_START( io_map, AS_PROGRAM, 8, zms8085_state )
+ AM_RANGE(0x61, 0x61) AM_READ(special_r)
AM_RANGE(0x68, 0x68) AM_WRITENOP
ADDRESS_MAP_END
@@ -93,10 +102,13 @@ Crystal: 15.582000
***************************************************************************************************************/
ROM_START( zephyr )
- ROM_REGION(0x10000, "maincpu", 0)
- ROM_LOAD( "23-006-32c.bin", 0x0000, 0x0800, CRC(0a3a5447) SHA1(a8c25730a1d7e5b9c86e0d504afc923e931f9025) )
- ROM_LOAD( "23-067-004b.bin", 0x0800, 0x0800, CRC(37741104) SHA1(52b9998e0a8d4949e0dc7c3349b3681e13345061) )
- ROM_LOAD( "23-067-03b.bin", 0x1000, 0x0800, CRC(29cfa003) SHA1(9de7a8402173a2c448e54ee433ba3050db7b70bb) ) // this doesn't seem to fit
+ ROM_REGION(0x1000, "maincpu", 0)
+ ROM_DEFAULT_BIOS("test") // for now
+ ROM_SYSTEM_BIOS(0, "main", "Main program" )
+ ROMX_LOAD( "23-067-03b.bin", 0x0000, 0x0800, CRC(29cfa003) SHA1(9de7a8402173a2c448e54ee433ba3050db7b70bb), ROM_BIOS(1) )
+ ROMX_LOAD( "23-067-004b.bin", 0x0800, 0x0800, CRC(37741104) SHA1(52b9998e0a8d4949e0dc7c3349b3681e13345061), ROM_BIOS(1) )
+ ROM_SYSTEM_BIOS(1, "test", "Test program" )
+ ROMX_LOAD( "23-006-32c.bin", 0x0000, 0x0800, CRC(0a3a5447) SHA1(a8c25730a1d7e5b9c86e0d504afc923e931f9025), ROM_BIOS(2) )
ROM_REGION(0x0800, "chargen", 0)
ROM_LOAD( "23-066-02a.bin", 0x0000, 0x0800, CRC(d5650b6c) SHA1(e6333e59018d9904f12abb270db4ba28aeff1995) )