From 7a29bd8486f5a8f5e6a520ef0feee49e6f0b98a8 Mon Sep 17 00:00:00 2001 From: Curt Coder Date: Tue, 23 Oct 2012 17:15:29 +0000 Subject: [PATCH] (MESS) c128: VDC fixes. (nw) --- src/emu/video/mc6845.c | 207 +++++++++++++++++++++++++--------------- src/emu/video/mc6845.h | 7 ++ src/mess/drivers/c128.c | 46 +++++---- 3 files changed, 164 insertions(+), 96 deletions(-) diff --git a/src/emu/video/mc6845.c b/src/emu/video/mc6845.c index 2555908f4f5..6775b40d2e4 100644 --- a/src/emu/video/mc6845.c +++ b/src/emu/video/mc6845.c @@ -30,7 +30,6 @@ - horizontal scroll - vertical scroll - - pixel double width - bitmap modes - display enable begin/end @@ -78,6 +77,8 @@ const device_type MOS8568 = &device_creator; #define HSS_TEXT BIT(m_horiz_scroll, 7) #define ATTR_COLOR (attr & 0x0f) +#define ATTR_BACKGROUND (attr & 0x0f) +#define ATTR_FOREGROUND (attr >> 4) #define ATTR_BLINK BIT(attr, 4) #define ATTR_UNDERLINE BIT(attr, 5) #define ATTR_REVERSE BIT(attr, 6) @@ -276,14 +277,12 @@ WRITE8_MEMBER( mc6845_device::register_w ) WRITE8_MEMBER( mos8563_device::address_w ) { m_register_address_latch = data & 0x3f; - - m_update_ready_bit = 0; } READ8_MEMBER( mos8563_device::status_r ) { - UINT8 ret = 0; + UINT8 ret = m_revision; /* VBLANK bit */ if (!m_line_enable_ff) @@ -297,8 +296,6 @@ READ8_MEMBER( mos8563_device::status_r ) if (m_update_ready_bit) ret = ret | 0x80; - m_update_ready_bit = 1; - return ret; } @@ -314,13 +311,13 @@ READ8_MEMBER( mos8563_device::register_r ) case 0x02: ret = m_horiz_sync_pos; break; case 0x03: ret = m_sync_width; break; case 0x04: ret = m_vert_char_total; break; - case 0x05: ret = m_vert_total_adj; break; + case 0x05: ret = m_vert_total_adj | 0xc0; break; case 0x06: ret = m_vert_disp; break; case 0x07: ret = m_vert_sync_pos; break; - case 0x08: ret = m_mode_control; break; - case 0x09: ret = m_max_ras_addr; break; - case 0x0a: ret = m_cursor_start_ras; break; - case 0x0b: ret = m_cursor_end_ras; break; + case 0x08: ret = m_mode_control | 0xfc; break; + case 0x09: ret = m_max_ras_addr | 0xe0; break; + case 0x0a: ret = m_cursor_start_ras | 0x80; break; + case 0x0b: ret = m_cursor_end_ras | 0xe0; break; case 0x0c: ret = (m_disp_start_addr >> 8) & 0xff; break; case 0x0d: ret = (m_disp_start_addr >> 0) & 0xff; break; case 0x0e: ret = (m_cursor_addr >> 8) & 0xff; break; @@ -332,20 +329,20 @@ READ8_MEMBER( mos8563_device::register_r ) case 0x14: ret = (m_attribute_addr >> 8) & 0xff; break; case 0x15: ret = (m_attribute_addr >> 0) & 0xff; break; case 0x16: ret = m_horiz_char; break; - case 0x17: ret = m_vert_char_disp; break; + case 0x17: ret = m_vert_char_disp | 0xe0; break; case 0x18: ret = m_vert_scroll; break; case 0x19: ret = m_horiz_scroll; break; case 0x1a: ret = m_color; break; case 0x1b: ret = m_row_addr_incr; break; - case 0x1c: ret = m_char_base_addr; break; - case 0x1d: ret = m_underline_ras; break; - case 0x1e: ret = 0; break; + case 0x1c: ret = m_char_base_addr | 0x1f; break; + case 0x1d: ret = m_underline_ras | 0xe0; break; + case 0x1e: ret = m_word_count; break; case 0x1f: ret = read_videoram(m_update_addr++); break; case 0x20: ret = (m_block_addr >> 8) & 0xff; break; case 0x21: ret = (m_block_addr >> 0) & 0xff; break; case 0x22: ret = (m_de_begin >> 8) & 0xff; break; case 0x23: ret = (m_de_begin >> 0) & 0xff; break; - case 0x24: ret = m_dram_refresh; break; + case 0x24: ret = m_dram_refresh | 0xf0; break; case 0x25: ret = m_sync_polarity | 0x3f; break; } @@ -384,24 +381,25 @@ WRITE8_MEMBER( mos8563_device::register_w ) case 0x16: m_horiz_char = data & 0xff; break; case 0x17: m_vert_char_disp = data & 0x1f; break; case 0x18: m_vert_scroll = data & 0xff; break; - case 0x19: m_horiz_scroll = data & 0xff; break; + case 0x19: + { + int dbl = HSS_DBL; + m_horiz_scroll = data & 0xff; + if (dbl && !HSS_DBL) set_clock(m_clock << 1); + if (!dbl && HSS_DBL) set_clock(m_clock >> 1); + break; + } case 0x1a: m_color = data & 0xff; break; case 0x1b: m_row_addr_incr = data & 0xff; break; - case 0x1c: m_char_base_addr = data & 0xf0; break; + case 0x1c: m_char_base_addr = data & 0xe0; break; case 0x1d: m_underline_ras = data & 0x1f; break; case 0x1e: m_word_count = data & 0xff; - - do - { - UINT8 byte = VSS_COPY ? read_videoram(m_block_addr++) : m_data; - - write_videoram(m_update_addr++, byte); - } while (m_word_count-- > 0); + m_update_ready_bit = 0; + m_block_copy_timer->adjust( attotime::from_ticks( 1, m_clock ) ); break; case 0x1f: m_data = data & 0xff; - write_videoram(m_update_addr++, m_data); break; case 0x20: m_block_addr = ((data & 0xff) << 8) | (m_block_addr & 0x00ff); break; @@ -791,6 +789,33 @@ void mc6845_device::device_timer(emu_timer &timer, device_timer_id id, int param } +void mos8563_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch (id) + { + case TIMER_BLOCK_COPY: + { + UINT8 data = VSS_COPY ? read_videoram(m_block_addr++) : m_data; + + write_videoram(m_update_addr++, data); + + if (--m_word_count) + { + m_block_copy_timer->adjust( attotime::from_ticks( 1, m_clock ) ); + } + else + { + m_update_ready_bit = 1; + } + break; + } + default: + mc6845_device::device_timer(timer, id, param, ptr); + break; + } +} + + UINT16 mc6845_device::get_ma() { update_counters(); @@ -1186,6 +1211,9 @@ void mos8563_device::device_start() { mc6845_device::device_start(); + /* create the timers */ + m_block_copy_timer = timer_alloc(TIMER_BLOCK_COPY); + m_supports_status_reg_d5 = true; m_supports_status_reg_d6 = true; m_supports_status_reg_d7 = true; @@ -1210,6 +1238,17 @@ void mos8563_device::device_start() m_de_begin = 0; m_dram_refresh = 0; m_sync_polarity = 0; + + m_revision = 1; + + // initialize video RAM + UINT8 data = 0xff; + + for (offs_t offset = 0; offset < 0x10000; offset++) + { + write_videoram(offset, data); + data ^= 0xff; + } save_item(NAME(m_char_buffer)); save_item(NAME(m_attr_buffer)); @@ -1228,6 +1267,7 @@ void mos8563_device::device_start() save_item(NAME(m_de_begin)); save_item(NAME(m_dram_refresh)); save_item(NAME(m_sync_polarity)); + save_item(NAME(m_revision)); } @@ -1382,22 +1422,22 @@ mos8568_device::mos8568_device(const machine_config &mconfig, const char *tag, d // VICE palette static const rgb_t MOS8563_PALETTE[] = { - MAKE_RGB(0x00, 0x00, 0x00), - MAKE_RGB(0x20, 0x20, 0x20), - MAKE_RGB(0x00, 0x00, 0x80), - MAKE_RGB(0x00, 0x00, 0xff), - MAKE_RGB(0x00, 0x80, 0x00), - MAKE_RGB(0x00, 0xff, 0x00), - MAKE_RGB(0x00, 0x80, 0x80), - MAKE_RGB(0x00, 0xff, 0xff), - MAKE_RGB(0x80, 0x00, 0x00), - MAKE_RGB(0xff, 0x00, 0x00), - MAKE_RGB(0x80, 0x00, 0x80), - MAKE_RGB(0xff, 0x00, 0xff), - MAKE_RGB(0x80, 0x80, 0x00), - MAKE_RGB(0xff, 0xff, 0x00), - MAKE_RGB(0xc0, 0xc0, 0xc0), - MAKE_RGB(0xff, 0xff, 0xff) + RGB_BLACK, + MAKE_RGB(0x55, 0x55, 0x55), + MAKE_RGB(0x00, 0x00, 0xaa), + MAKE_RGB(0x55, 0x55, 0xff), + MAKE_RGB(0x00, 0xaa, 0x00), + MAKE_RGB(0x55, 0xff, 0x55), + MAKE_RGB(0x00, 0xaa, 0xaa), + MAKE_RGB(0x55, 0xff, 0xff), + MAKE_RGB(0xaa, 0x00, 0x00), + MAKE_RGB(0xff, 0x55, 0x55), + MAKE_RGB(0xaa, 0x00, 0xaa), + MAKE_RGB(0xff, 0x55, 0xff), + MAKE_RGB(0xaa, 0x55, 0x00), + MAKE_RGB(0xff, 0xff, 0x55), + MAKE_RGB(0xaa, 0xaa, 0xaa), + RGB_WHITE }; @@ -1436,65 +1476,80 @@ UINT8 mos8563_device::draw_scanline(int y, bitmap_rgb32 &bitmap, const rectangle void mos8563_device::update_row(bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT16 ma, UINT8 ra, UINT16 y, UINT8 x_count, INT8 cursor_x, void *param) { + ra += (m_vert_scroll & 0x0f); + ra &= 0x0f; + + UINT8 cth = (m_horiz_char >> 4) + (HSS_DBL ? 0 : 1); + UINT8 cdh = (m_horiz_char & 0x0f) + (HSS_DBL ? 0 : 1); + UINT8 cdv = m_vert_char_disp; + for (int column = 0; column < x_count; column++) { + UINT8 code = read_videoram(ma + column); + UINT8 attr = 0; + + int fg = m_color >> 4; + int bg = m_color & 0x0f; + + if (HSS_ATTR) + { + offs_t attr_addr = m_attribute_addr + ma + column; + attr = read_videoram(attr_addr); + } + if (HSS_TEXT) { - // TODO graphics + if (HSS_ATTR) + { + fg = ATTR_FOREGROUND; + bg = ATTR_BACKGROUND; + } + + if (VSS_RVS) code ^= 0xff; + + for (int bit = 0; bit < cdh; bit++) + { + int x = (m_horiz_scroll & 0x0f) - cth + (column * cth) + bit; + if (x < 0) x = 0; + int color = BIT(code, 7) ? fg : bg; + + bitmap.pix32(y, x) = MOS8563_PALETTE[color]; + } } else { - UINT16 code = read_videoram(ma + column); - - offs_t attr_addr = m_attribute_addr + (ma - m_disp_start_addr) + column; - UINT8 attr = 0; - - UINT8 cth = (m_horiz_char >> 4) + 1; - UINT8 cdh = (m_horiz_char & 0x0f) + 1; - UINT8 cdv = m_vert_char_disp; - - // attributes - int fg; - int bg = m_color & 0x0f; - if (HSS_ATTR) { - attr = read_videoram(attr_addr); fg = ATTR_COLOR; } - else - { - fg = m_color >> 4; - } offs_t font_addr; - code |= ATTR_ALTERNATE_CHARSET << 8; - if (m_max_ras_addr < 16) - font_addr = ((m_char_base_addr >> 5) << 13) | (code << 4) | ra; + { + font_addr = ((m_char_base_addr & 0xe0) << 8) | (ATTR_ALTERNATE_CHARSET << 12) | (code << 4) | (ra & 0x0f); + } else - font_addr = ((m_char_base_addr >> 5) << 13) | (code << 5) | ra; - + { + font_addr = ((m_char_base_addr & 0xc0) << 8) | (ATTR_ALTERNATE_CHARSET << 13) | (code << 5) | (ra & 0x1f); + } + UINT8 data = read_videoram(font_addr); - if (column == cursor_x) data = 0xff; if (ra >= cdv) data = 0; if (ATTR_UNDERLINE && (ra == m_underline_ras)) data = 0xff; if (ATTR_BLINK && !m_char_blink_state) data = 0; - - if (ATTR_REVERSE) - { - int temp = bg; - bg = fg; - fg = temp; - } + if (ATTR_REVERSE) data ^= 0xff; + if (column == cursor_x) data ^= 0xff; + if (VSS_RVS) data ^= 0xff; for (int bit = 0; bit < cdh; bit++) { - int x = (column * cth) + bit; + int x = (m_horiz_scroll & 0x0f) - cth + (column * cth) + bit; + if (x < 0) x = 0; + int color = BIT(data, 7) ? fg : bg; - bitmap.pix32(y, x) = MOS8563_PALETTE[(BIT(data, 7) ^ VSS_RVS) ? fg : bg]; + bitmap.pix32(y, x) = MOS8563_PALETTE[color]; if ((bit < 8) || !HSS_SEMI) data <<= 1; } diff --git a/src/emu/video/mc6845.h b/src/emu/video/mc6845.h index 3a3e3775f01..ccc0336bb72 100644 --- a/src/emu/video/mc6845.h +++ b/src/emu/video/mc6845.h @@ -401,6 +401,7 @@ protected: // device-level overrides virtual void device_start(); virtual void device_reset(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); const address_space_config m_videoram_space_config; @@ -427,8 +428,14 @@ protected: UINT8 m_dram_refresh; /* 0x24 */ UINT8 m_sync_polarity; /* 0x25 */ + int m_revision; + virtual void update_cursor_state(); virtual UINT8 draw_scanline(int y, bitmap_rgb32 &bitmap, const rectangle &cliprect, void *param); + + static const device_timer_id TIMER_BLOCK_COPY = 9; + + emu_timer *m_block_copy_timer; }; class mos8568_device : public mos8563_device diff --git a/src/mess/drivers/c128.c b/src/mess/drivers/c128.c index 49f81d64a7d..656fd5d5474 100644 --- a/src/mess/drivers/c128.c +++ b/src/mess/drivers/c128.c @@ -781,6 +781,29 @@ static MOS8722_INTERFACE( mmu_intf ) }; +//------------------------------------------------- +// mc6845_interface vdc_intf +//------------------------------------------------- + +static GFXDECODE_START( c128 ) + GFXDECODE_ENTRY( "charom", 0x0000, gfx_8x8x1, 0, 1 ) +GFXDECODE_END + +static const mc6845_interface vdc_intf = +{ + SCREEN_VDC_TAG, + 8, + NULL, + NULL, + NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + NULL +}; + + //------------------------------------------------- // MOS8564_INTERFACE( vic_intf ) //------------------------------------------------- @@ -814,25 +837,6 @@ static MOS8564_INTERFACE( vic_intf ) }; -//------------------------------------------------- -// mc6845_interface vdc_intf -//------------------------------------------------- - -static const mc6845_interface vdc_intf = -{ - SCREEN_VDC_TAG, - 8, - NULL, - NULL, - NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - DEVCB_NULL, - NULL -}; - - //------------------------------------------------- // MOS6581_INTERFACE( sid_intf ) //------------------------------------------------- @@ -1094,7 +1098,7 @@ READ8_MEMBER( c128_state::cpu_r) data |= m_cassette->sense_r() << 4; // CAPS LOCK - data |= !BIT(ioport("SPECIAL")->read(), 5) << 6; + data |= m_caps_lock << 6; return data; } @@ -1380,6 +1384,7 @@ static MACHINE_CONFIG_START( ntsc, c128_state ) // video hardware MCFG_MOS8563_ADD(MOS8563_TAG, SCREEN_VDC_TAG, VIC6567_CLOCK*2, vdc_intf, vdc_videoram_map) MCFG_MOS8564_ADD(MOS8564_TAG, SCREEN_VIC_TAG, VIC6567_CLOCK, vic_intf, vic_videoram_map, vic_colorram_map) + MCFG_GFXDECODE(c128) // sound hardware MCFG_SPEAKER_STANDARD_MONO("mono") @@ -1484,6 +1489,7 @@ static MACHINE_CONFIG_START( pal, c128_state ) // video hardware MCFG_MOS8563_ADD(MOS8563_TAG, SCREEN_VDC_TAG, VIC6569_CLOCK*2, vdc_intf, vdc_videoram_map) MCFG_MOS8566_ADD(MOS8564_TAG, SCREEN_VIC_TAG, VIC6569_CLOCK, vic_intf, vic_videoram_map, vic_colorram_map) + MCFG_GFXDECODE(c128) // sound hardware MCFG_SPEAKER_STANDARD_MONO("mono")