diff options
Diffstat (limited to 'src/devices/video/v9938.cpp')
-rw-r--r-- | src/devices/video/v9938.cpp | 187 |
1 files changed, 116 insertions, 71 deletions
diff --git a/src/devices/video/v9938.cpp b/src/devices/video/v9938.cpp index 906e92353f7..6a24e97f7d4 100644 --- a/src/devices/video/v9938.cpp +++ b/src/devices/video/v9938.cpp @@ -38,17 +38,17 @@ todo: #include "emu.h" #include "v9938.h" -#define LOG_WARN (1U<<1) -#define LOG_INT (1U<<2) -#define LOG_STATUS (1U<<3) -#define LOG_REGWRITE (1U<<4) -#define LOG_COMMAND (1U<<5) -#define LOG_MODE (1U<<6) -#define LOG_NOTIMP (1U<<7) -#define LOG_DETAIL (1U<<8) +#define LOG_WARN (1U << 1) +#define LOG_INT (1U << 2) +#define LOG_STATUS (1U << 3) +#define LOG_REGWRITE (1U << 4) +#define LOG_COMMAND (1U << 5) +#define LOG_MODE (1U << 6) +#define LOG_NOTIMP (1U << 7) +#define LOG_DETAIL (1U << 8) // Minimum log should be warnings -#define VERBOSE (LOG_GENERAL | LOG_WARN ) +#define VERBOSE (LOG_GENERAL | LOG_WARN) #include "logmacro.h" @@ -241,14 +241,14 @@ void v99x8_device::set_screen_parameters() } else { - // NYSC + // NTSC m_scanline_start = (m_cont_reg[9] & 0x80) ? 16 : 26; m_scanline_max = (m_cont_reg[9] & 0x80) ? 234 : 244; } m_visible_y = (m_cont_reg[9] & 0x80) ? 212 : 192; } - +// FIXME: this doesn't really allow for external clock configuration void v99x8_device::configure_pal_ntsc() { if (m_pal_ntsc) @@ -608,7 +608,6 @@ void v99x8_device::register_w(uint8_t data) void v99x8_device::device_start() { - m_int_callback.resolve_safe(); m_vdp_ops_count = 1; m_vdp_engine = nullptr; @@ -693,6 +692,7 @@ void v99x8_device::device_reset() m_cmd_write_first = m_pal_write_first = 0; m_int_state = 0; m_read_ahead = 0; m_address_latch = 0; // ??? + // FIXME: this drifts the scanline number wrt screen h/vpos m_scanline = 0; // MZ: The status registers 4 and 6 hold the high bits of the sprite // collision location. The unused bits are set to 1. @@ -811,6 +811,7 @@ void v99x8_device::check_int() ** called; because of this Mr. Ghost, Xevious and SD Snatcher don't ** run. As a patch it's called every scanline */ + // FIXME: breaks nichibutsu hrdvd.cpp & nichild.cpp, really needs INPUT_MERGER instead. m_int_callback(n); } @@ -1138,76 +1139,123 @@ void v99x8_device::mode_graphic1(uint32_t *ln, int line) void v99x8_device::mode_graphic23(uint32_t *ln, int line) { - pen_t fg, bg, pen; - int nametbl_addr, patterntbl_addr, colourtbl_addr; - int pattern, x, xx, line2, name, charcode, - colour, colourmask, patternmask, xxx; + const int colourmask = ((m_cont_reg[3] & 0x7f) << 3) | 7; + const int patternmask = ((m_cont_reg[4] & 0x03) << 8) | 0xff; + const int scrolled_y = (line + m_cont_reg[23]) & 0xff; + const int colourtbl_addr = ((m_cont_reg[3] & 0x80) << 6) + (m_cont_reg[10] << 14); + const int patterntbl_addr = ((m_cont_reg[4] & 0x3c) << 11); + const pen_t border_pen = pen16(m_cont_reg[7] & 0x0f); - colourmask = ((m_cont_reg[3] & 0x7f) * 8) | 7; - patternmask = ((m_cont_reg[4] & 0x03) * 256) | 0xff; + int nametbl_base = (m_cont_reg[2] << 10) + ((scrolled_y / 8) * 32); + int nametbl_offset = (m_cont_reg[26] & 0x1f); - nametbl_addr = (m_cont_reg[2] << 10); - colourtbl_addr = ((m_cont_reg[3] & 0x80) << 6) + (m_cont_reg[10] << 14); - patterntbl_addr = ((m_cont_reg[4] & 0x3c) << 11); + if (BIT(m_cont_reg[25], 0) && BIT(m_cont_reg[26], 5)) + nametbl_base ^= 0x8000; - line2 = (line + m_cont_reg[23]) & 255; - name = (line2/8)*32; + for (int x = m_offset_x * 2; x > 0; x--) + *ln++ = border_pen; - pen = pen16(m_cont_reg[7] & 0x0f); - xxx = m_offset_x * 2; - while (xxx--) *ln++ = pen; + int dot_scroll = m_cont_reg[27] & 0x07; + int pixels_to_mask = BIT(m_cont_reg[25], 1) ? 8 - dot_scroll : 0; + int pixels_to_draw = 256 - dot_scroll; + while (dot_scroll--) + { + *ln++ = border_pen; + *ln++ = border_pen; + } - for (x=0;x<32;x++) + do { - charcode = m_vram_space->read_byte(nametbl_addr + name) + (line2&0xc0)*4; - colour = m_vram_space->read_byte(colourtbl_addr + ((charcode&colourmask)*8+(line2&7))); - pattern = m_vram_space->read_byte(patterntbl_addr + ((charcode&patternmask)*8+(line2&7))); - fg = pen16(colour >> 4); - bg = pen16(colour & 15); - for (xx=0;xx<8;xx++) + const int charcode = m_vram_space->read_byte(nametbl_base + nametbl_offset) + ((scrolled_y & 0xc0) << 2); + const u8 colour = m_vram_space->read_byte(colourtbl_addr + ((charcode & colourmask) << 3) + (scrolled_y & 7)); + u8 pattern = m_vram_space->read_byte(patterntbl_addr + ((charcode & patternmask) << 3) + (scrolled_y & 7)); + const pen_t fg = pen16(colour >> 4); + const pen_t bg = pen16(colour & 0x0f); + for (int x = 0; x < 8 && pixels_to_draw > 0; x++) { - *ln++ = (pattern & 0x80) ? fg : bg; - *ln++ = (pattern & 0x80) ? fg : bg; + if (!pixels_to_mask) + { + *ln++ = (pattern & 0x80) ? fg : bg; + *ln++ = (pattern & 0x80) ? fg : bg; + } + else + { + pixels_to_mask--; + *ln++ = border_pen; + *ln++ = border_pen; + } + pixels_to_draw--; pattern <<= 1; } - name++; + nametbl_offset = (nametbl_offset + 1) & 0x1f; + if (BIT(m_cont_reg[25], 0) && !nametbl_offset) + nametbl_base ^= 0x8000; } + while (pixels_to_draw > 0); - xx = (16 - m_offset_x) * 2; - while (xx--) *ln++ = pen; + for (int x = (16 - m_offset_x) * 2; x > 0; x--) + *ln++ = border_pen; } void v99x8_device::mode_graphic4(uint32_t *ln, int line) { - int nametbl_addr, colour; - int line2, linemask, x, xx; - pen_t pen, pen_bg; + int linemask = ((m_cont_reg[2] & 0x1f) << 3) | 7; + const int scrolled_y = ((line + m_cont_reg[23]) & linemask) & 0xff; + const pen_t border_pen = pen16(m_cont_reg[7] & 0x0f); - linemask = ((m_cont_reg[2] & 0x1f) << 3) | 7; + int nametbl_base = ((m_cont_reg[2] & 0x40) << 10) + (scrolled_y << 7); + int nametbl_offset = (m_cont_reg[26] & 0x1f) << 2; + if (!BIT(m_cont_reg[25], 0) && BIT(m_cont_reg[2], 5) && v9938_second_field()) + nametbl_base += 0x8000; + if (BIT(m_cont_reg[25], 0) && BIT(m_cont_reg[26], 5)) + nametbl_base ^= 0x8000; - line2 = ((line + m_cont_reg[23]) & linemask) & 255; + for (int x = m_offset_x * 2; x > 0; x--) + *ln++ = border_pen; - nametbl_addr = ((m_cont_reg[2] & 0x40) << 10) + line2 * 128; - if ( (m_cont_reg[2] & 0x20) && v9938_second_field() ) - nametbl_addr += 0x8000; - - pen_bg = pen16(m_cont_reg[7] & 0x0f); - xx = m_offset_x * 2; - while (xx--) *ln++ = pen_bg; + int dot_scroll = m_cont_reg[27] & 0x07; + int pixels_to_mask = BIT(m_cont_reg[25], 1) ? 8 - dot_scroll : 0; + int pixels_to_draw = 256 - dot_scroll; + while (dot_scroll--) + { + *ln++ = border_pen; + *ln++ = border_pen; + } - for (x=0;x<128;x++) + do { - colour = m_vram_space->read_byte(nametbl_addr++); - pen = pen16(colour >> 4); - *ln++ = pen; - *ln++ = pen; - pen = pen16(colour & 15); - *ln++ = pen; - *ln++ = pen; + bool mask_pixel_1 = false; + bool mask_pixel_2 = false; + if (pixels_to_mask) + { + mask_pixel_1 = true; + pixels_to_mask--; + if (pixels_to_mask) + { + mask_pixel_2 = true; + pixels_to_mask--; + } + } + const u8 colour = m_vram_space->read_byte(nametbl_base + nametbl_offset); + const pen_t pen1 = mask_pixel_1 ? border_pen : pen16(colour >> 4); + const pen_t pen2 = mask_pixel_2 ? border_pen : pen16(colour & 0x0f); + *ln++ = pen1; + *ln++ = pen1; + pixels_to_draw--; + if (pixels_to_draw) + { + *ln++ = pen2; + *ln++ = pen2; + pixels_to_draw--; + } + nametbl_offset = (nametbl_offset + 1) & 0x7f; + if (BIT(m_cont_reg[25], 0) && !nametbl_offset) + nametbl_base ^= 0x8000; } + while (pixels_to_draw > 0); - xx = (16 - m_offset_x) * 2; - while (xx--) *ln++ = pen_bg; + for (int x = (16 - m_offset_x) * 2; x > 0; x--) + *ln++ = border_pen; } void v99x8_device::mode_graphic5(uint32_t *ln, int line) @@ -1424,20 +1472,17 @@ void v99x8_device::mode_graphic7(uint32_t *ln, int line) void v99x8_device::mode_unknown(uint32_t *ln, int line) { - pen_t fg, bg; - int x; - - fg = pen16(m_cont_reg[7] >> 4); - bg = pen16(m_cont_reg[7] & 15); + const pen_t fg = pen16(m_cont_reg[7] >> 4); + const pen_t bg = pen16(m_cont_reg[7] & 0x0f); - x = m_offset_x * 2; - while (x--) *ln++ = bg; + for (int x = m_offset_x * 2; x > 0; x--) + *ln++ = bg; - x = 512; - while (x--) *ln++ = fg; + for (int x = 512; x > 0; x--) + *ln++ = fg; - x = (16 - m_offset_x) * 2; - while (x--) *ln++ = bg; + for (int x = (16 - m_offset_x) * 2; x > 0; x--) + *ln++ = bg; } void v99x8_device::default_draw_sprite(uint32_t *ln, uint8_t *col) |