diff options
Diffstat (limited to 'src/devices/video/315_5124.cpp')
-rw-r--r-- | src/devices/video/315_5124.cpp | 191 |
1 files changed, 135 insertions, 56 deletions
diff --git a/src/devices/video/315_5124.cpp b/src/devices/video/315_5124.cpp index 9a3a0f8c339..1f4bd1bf484 100644 --- a/src/devices/video/315_5124.cpp +++ b/src/devices/video/315_5124.cpp @@ -16,7 +16,7 @@ To do: - - Register 3 behaviour in mode 4 + - Mid-scanline changes - VRAM/CRAM access constraints @@ -68,6 +68,25 @@ PAL frame timing #include "video/315_5124.h" +/**************************************************************************** + * Configurable logging + ****************************************************************************/ + +#define LOG_GENERAL (1U << 0) +#define LOG_VIDMODE (1U << 1) +#define LOG_REGWRITE (1U << 2) +#define LOG_VCOUNTREAD (1U << 3) + +//#define VERBOSE (LOG_GENERAL | LOG_VIDMODE | LOG_REGWRITE | LOG_VCOUNTREAD) +//#define LOG_OUTPUT_FUNC printf +#include "logmacro.h" + +#define LOGVIDMODE(...) LOGMASKED(LOG_VIDMODE, __VA_ARGS__) +#define LOGREGWRITE(...) LOGMASKED(LOG_REGWRITE, __VA_ARGS__) +#define LOGVCOUNTREAD(...) LOGMASKED(LOG_VCOUNTREAD, __VA_ARGS__) + +/****************************************************************************/ + #define SEGA315_5124_PALETTE_SIZE (64 + 16) #define SEGA315_5377_PALETTE_SIZE 4096 @@ -337,7 +356,7 @@ void sega315_5124_device::select_display_mode() else if (!M1 && !M2 && M3) // Mode 3 (Multicolor Mode) */ m_vdp_mode = 3; else - logerror("Unknown video mode detected (M1 = %c, M2 = %c, M3 = %c, M4 = %c)\n", M1 ? '1' : '0', M2 ? '1' : '0', M3 ? '1' : '0', M4 ? '1' : '0'); + LOGVIDMODE("Unknown video mode detected (M1 = %c, M2 = %c, M3 = %c, M4 = %c)\n", M1 ? '1' : '0', M2 ? '1' : '0', M3 ? '1' : '0', M4 ? '1' : '0'); } } @@ -351,7 +370,7 @@ void sega315_5313_mode4_device::select_display_mode() { /* mode 5, not implemented */ m_vdp_mode = 5; - logerror("Switched to unimplemented video mode 5 !\n"); + LOGVIDMODE("Switched to unimplemented video mode 5 !\n"); } else { @@ -392,6 +411,24 @@ void sega315_5124_device::set_frame_timing() u8 sega315_5124_device::vcount_read() { + u8 vc = vcount(); + + LOGVCOUNTREAD( + "fr %d vpos %3d hpos %3d hc 0x%02X %s: vcount read value 0x%02X\n", + screen().frame_number(), + screen().vpos(), + screen_hpos(), + hcount(), + machine().describe_context(), + vc + ); + + return vc; +} + + +u8 sega315_5124_device::vcount() +{ const int active_scr_start = m_frame_timing[VERTICAL_SYNC] + m_frame_timing[TOP_BLANKING] + m_frame_timing[TOP_BORDER]; int vpos = screen().vpos(); @@ -415,13 +452,19 @@ u8 sega315_5124_device::hcount_read() void sega315_5124_device::hcount_latch() { + m_hcounter = hcount(); + m_hcounter_latched = true; +} + + +u8 sega315_5124_device::hcount() +{ /* The hcount value returned by the VDP seems to be based on the previous hpos */ int hclock = screen_hpos() - 1; if (hclock < 0) hclock += WIDTH; - m_hcounter = ((hclock - 46) >> 1) & 0xff; - m_hcounter_latched = true; + return ((hclock - 46) >> 1) & 0xff; } @@ -876,14 +919,14 @@ void sega315_5124_device::control_write(u8 data) break; } m_reg[reg_num] = m_addr & 0xff; - //logerror("%s: %s: setting register %x to %02x\n", machine().describe_context(), tag(), reg_num, m_addr & 0xff); + LOGREGWRITE("%s: %s: setting register %x to %02x\n", machine().describe_context(), tag(), reg_num, m_addr & 0xff); switch (reg_num) { case 0: set_display_settings(); if (BIT(m_addr, 1)) - logerror("overscan enabled.\n"); + LOGVIDMODE("overscan enabled.\n"); break; case 1: set_display_settings(); @@ -947,18 +990,6 @@ void sega315_5124_device::control_write(u8 data) } -u16 sega315_5124_device::name_table_row_mode4(int row) -{ - return ((row >> 3) << 6) & (((m_reg[0x02] & 0x01) << 10) | ((m_reg[0x04] & 0x03) << 11) | 0x23ff); -} - - -u16 sega315_5246_device::name_table_row_mode4(int row) -{ - return (row >> 3) << 6; -} - - void sega315_5124_device::draw_leftmost_pixels_mode4(int *line_buffer, int *priority_selected, int fine_x_scroll, int palette_selected, int tile_line) { // To draw the leftmost pixels when they aren't part of a tile column @@ -1009,6 +1040,42 @@ void sega315_5313_mode4_device::draw_leftmost_pixels_mode4(int *line_buffer, int } +u16 sega315_5124_device::name_row_mode4(u16 row) +{ + return row & (((m_reg[0x02] & 0x01) << 10) | 0x3bff); +} + + +u16 sega315_5246_device::name_row_mode4(u16 row) +{ + return row; +} + + +u16 sega315_5124_device::tile1_select_mode4(u16 tile_number) +{ + return tile_number & ((m_reg[0x03] << 1) | 1); +} + + +u16 sega315_5246_device::tile1_select_mode4(u16 tile_number) +{ + return tile_number; +} + + +u16 sega315_5124_device::tile2_select_mode4(u16 tile_number) +{ + return tile_number & (((m_reg[0x04] & 0x07) << 6) | 0x03f); +} + + +u16 sega315_5246_device::tile2_select_mode4(u16 tile_number) +{ + return tile_number; +} + + void sega315_5124_device::draw_scanline_mode4(int *line_buffer, int *priority_selected, int line) { /* if top 2 rows of screen not affected by horizontal scrolling, then x_scroll = 0 */ @@ -1019,15 +1086,15 @@ void sega315_5124_device::draw_scanline_mode4(int *line_buffer, int *priority_se const int fine_x_scroll = (x_scroll & 0x07); int scroll_mod; - u16 name_table_address; + u16 name_base; if (m_y_pixels != 192) { - name_table_address = ((m_reg[0x02] & 0x0c) << 10) | 0x0700; + name_base = ((m_reg[0x02] & 0x0c) << 10) | 0x0700; scroll_mod = 256; } else { - name_table_address = (m_reg[0x02] << 10) & 0x3800; + name_base = (m_reg[0x02] << 10) & 0x3800; scroll_mod = 224; } @@ -1041,9 +1108,11 @@ void sega315_5124_device::draw_scanline_mode4(int *line_buffer, int *priority_se /* vertical scrolling when bit 7 of reg[0x00] is set */ const int y_scroll = (BIT(m_reg[0x00], 7) && (tile_column > 23)) ? 0 : m_reg9copy; - const u16 tile_data = space().read_word(name_table_address + name_table_row_mode4((line + y_scroll) % scroll_mod) + table_column); + const u16 name_row = name_row_mode4((((line + y_scroll) % scroll_mod) >> 3) << 6); + const u16 tile_data = space().read_word(name_base + name_row + table_column); - const int tile_selected = (tile_data & 0x01ff); + const int tile1_selected = tile1_select_mode4(tile_data & 0x01ff); + const int tile2_selected = tile2_select_mode4(tile_data & 0x01ff); const int priority_select = tile_data & PRIORITY_BIT; const int palette_selected = BIT(tile_data, 11); const int vert_selected = BIT(tile_data, 10); @@ -1053,10 +1122,10 @@ void sega315_5124_device::draw_scanline_mode4(int *line_buffer, int *priority_se if (vert_selected) tile_line = 0x07 - tile_line; - const int bit_plane_0 = space().read_byte(((tile_selected << 5) + ((tile_line & 0x07) << 2)) + 0x00); - const int bit_plane_1 = space().read_byte(((tile_selected << 5) + ((tile_line & 0x07) << 2)) + 0x01); - const int bit_plane_2 = space().read_byte(((tile_selected << 5) + ((tile_line & 0x07) << 2)) + 0x02); - const int bit_plane_3 = space().read_byte(((tile_selected << 5) + ((tile_line & 0x07) << 2)) + 0x03); + const u8 bit_plane_0 = space().read_byte(((tile1_selected << 5) + ((tile_line & 0x07) << 2)) + 0x00); + const u8 bit_plane_1 = space().read_byte(((tile1_selected << 5) + ((tile_line & 0x07) << 2)) + 0x01); + const u8 bit_plane_2 = space().read_byte(((tile2_selected << 5) + ((tile_line & 0x07) << 2)) + 0x02); + const u8 bit_plane_3 = space().read_byte(((tile2_selected << 5) + ((tile_line & 0x07) << 2)) + 0x03); /* Column 0 is the leftmost tile column that completely entered in the screen. If the leftmost pixels aren't part of a complete tile, due to horizontal @@ -1088,25 +1157,25 @@ void sega315_5124_device::draw_scanline_mode4(int *line_buffer, int *priority_se } -u16 sega315_5124_device::sprite_attributes_addr_mode4(u16 base) +u8 sega315_5124_device::sprite_attribute_extra_offset_mode4(u8 offset) { - return base & ((BIT(m_reg[0x05], 0) << 7) | 0x3f7f); + return offset & ((BIT(m_reg[0x05], 0) << 7) | 0x7f); } -u16 sega315_5246_device::sprite_attributes_addr_mode4(u16 base) +u8 sega315_5246_device::sprite_attribute_extra_offset_mode4(u8 offset) { - return base; + return offset; } -u8 sega315_5124_device::sprite_tile_mask_mode4(u8 tile_number) +u8 sega315_5124_device::sprite_tile_select_mode4(u8 tile_number) { return tile_number & (((m_reg[0x06] & 0x03) << 6) | 0x3f); } -u8 sega315_5246_device::sprite_tile_mask_mode4(u8 tile_number) +u8 sega315_5246_device::sprite_tile_select_mode4(u8 tile_number) { return tile_number; } @@ -1140,20 +1209,25 @@ void sega315_5313_mode4_device::sprite_count_overflow(int line, int sprite_index void sega315_5124_device::select_sprites(int line) { + m_sprite_count = 0; + if (m_vdp_mode == 1) + { + /* Text mode, no sprite processing */ + return; + } + /* Check if SI is set */ m_sprite_height = BIT(m_reg[0x01], 1) ? 16 : 8; /* Check if MAG is set */ m_sprite_zoom_scale = BIT(m_reg[0x01], 0) ? 2 : 1; - m_sprite_count = 0; - - if (m_vdp_mode == 0 || m_vdp_mode == 2) + if (m_vdp_mode < 4) { /* TMS9918 compatibility sprites */ const int max_sprites = 4; - m_sprite_base = ((m_reg[0x05] & 0x7f) << 7); + m_sprite_attribute_base = ((m_reg[0x05] & 0x7f) << 7); for (int sprite_index = 0; (sprite_index < 32 * 4); sprite_index += 4) { @@ -1161,7 +1235,7 @@ void sega315_5124_device::select_sprites(int line) because the logical start point is slightly shifted on the scanline */ int parse_line = line - 1; - int sprite_y = space().read_byte(m_sprite_base + sprite_index); + int sprite_y = space().read_byte(m_sprite_attribute_base + sprite_index); if (sprite_y == 0xd0) break; @@ -1182,9 +1256,9 @@ void sega315_5124_device::select_sprites(int line) { if (m_sprite_count < max_sprites) { - const int sprite_x = space().read_byte(m_sprite_base + sprite_index + 1); - int sprite_tile_selected = space().read_byte(m_sprite_base + sprite_index + 2); - const u8 flags = space().read_byte(m_sprite_base + sprite_index + 3); + const int sprite_x = space().read_byte(m_sprite_attribute_base + sprite_index + 1); + int sprite_tile_selected = space().read_byte(m_sprite_attribute_base + sprite_index + 2); + const u8 flags = space().read_byte(m_sprite_attribute_base + sprite_index + 3); int sprite_line = parse_line - sprite_y; @@ -1219,7 +1293,8 @@ void sega315_5124_device::select_sprites(int line) const int max_sprites = 8; - m_sprite_base = (m_reg[0x05] << 7) & 0x3f00; + m_sprite_attribute_base = (m_reg[0x05] << 7) & 0x3f00; + const u16 sprite_attribute_extra_base = m_sprite_attribute_base + sprite_attribute_extra_offset_mode4(0x80); for (int sprite_index = 0; (sprite_index < 64); sprite_index++) { @@ -1227,7 +1302,7 @@ void sega315_5124_device::select_sprites(int line) because the logical start point is slightly shifted on the scanline */ int parse_line = line - 1; - int sprite_y = space().read_byte(m_sprite_base + sprite_index); + int sprite_y = space().read_byte(m_sprite_attribute_base + sprite_index); if (m_y_pixels == 192 && sprite_y == 0xd0) break; @@ -1249,10 +1324,10 @@ void sega315_5124_device::select_sprites(int line) if (m_sprite_count < max_sprites) { const int sprite_line = parse_line - sprite_y; - int sprite_x = space().read_byte(sprite_attributes_addr_mode4(m_sprite_base + 0x80) + (sprite_index << 1)); - int sprite_tile_selected = space().read_byte(sprite_attributes_addr_mode4(m_sprite_base + 0x81) + (sprite_index << 1)); + int sprite_x = space().read_byte(sprite_attribute_extra_base + (sprite_index << 1)); + int sprite_tile_number = space().read_byte(sprite_attribute_extra_base + (sprite_index << 1) + 1); - sprite_tile_selected = sprite_tile_mask_mode4(sprite_tile_selected); + int sprite_tile_selected = sprite_tile_select_mode4(sprite_tile_number); if (BIT(m_reg[0x00], 3)) sprite_x -= 0x08; /* sprite shift */ @@ -1509,17 +1584,18 @@ void sega315_5124_device::draw_sprites_tms9918_mode(int *line_buffer, int line) // Display mode 2 (Graphics II Mode) void sega315_5124_device::draw_scanline_mode2(int *line_buffer, int line) { - const u16 name_table_base = ((m_reg[0x02] & 0x0f) << 10) + ((line >> 3) * 32); + const u16 name_base = ((m_reg[0x02] & 0x0f) << 10); const u16 color_base = ((m_reg[0x03] & 0x80) << 6); const int color_mask = ((m_reg[0x03] & 0x7f) << 3) | 0x07; const u16 pattern_base = ((m_reg[0x04] & 0x04) << 11); const int pattern_mask = ((m_reg[0x04] & 0x03) << 8) | 0xff; const int pattern_offset = (line & 0xc0) << 2; + const u16 name_row_base = name_base + ((line >> 3) * 32); /* Draw background layer */ for (int tile_column = 0; tile_column < 32; tile_column++) { - const u8 name = space().read_byte(name_table_base + tile_column); + const u8 name = space().read_byte(name_row_base + tile_column); const u8 pattern = space().read_byte(pattern_base + (((pattern_offset + name) & pattern_mask) * 8) + (line & 0x07) ); const u8 colors = space().read_byte(color_base + (((pattern_offset + name) & color_mask) * 8) + (line & 0x07) ); @@ -1550,14 +1626,15 @@ void sega315_5124_device::draw_scanline_mode2(int *line_buffer, int line) // Display mode 0 (Graphics I Mode) void sega315_5124_device::draw_scanline_mode0(int *line_buffer, int line) { - const u16 name_base = ((m_reg[0x02] & 0x0f) << 10) + ((line >> 3) * 32); + const u16 name_base = ((m_reg[0x02] & 0x0f) << 10); const u16 color_base = ((m_reg[0x03] << 6) & (VRAM_SIZE - 1)); const u16 pattern_base = ((m_reg[0x04] << 11) & (VRAM_SIZE - 1)); + const u16 name_row_base = name_base + ((line >> 3) * 32); /* Draw background layer */ for (int tile_column = 0; tile_column < 32; tile_column++) { - const u8 name = space().read_byte(name_base + tile_column); + const u8 name = space().read_byte(name_row_base + tile_column); const u8 pattern = space().read_byte(pattern_base + (name << 3) + (line & 0x07)); const u8 colors = space().read_byte(color_base + (name >> 3)); @@ -1584,8 +1661,9 @@ void sega315_5124_device::draw_scanline_mode0(int *line_buffer, int line) // Display mode 1 (Text Mode) void sega315_5124_device::draw_scanline_mode1(int *line_buffer, int line) { - const u16 name_base = ((m_reg[0x02] & 0x0f) << 10) + ((line >> 3) * 32); + const u16 name_base = ((m_reg[0x02] & 0x0f) << 10); const u16 pattern_base = ((m_reg[0x04] << 11) & (VRAM_SIZE - 1)); + const u16 name_row_base = name_base + ((line >> 3) * 32); for (int pixel_plot_x = 0; pixel_plot_x < 8; pixel_plot_x++) { @@ -1595,7 +1673,7 @@ void sega315_5124_device::draw_scanline_mode1(int *line_buffer, int line) /* Draw background layer */ for (int tile_column = 0; tile_column < 40; tile_column++) { - const u8 name = space().read_byte(name_base + tile_column); + const u8 name = space().read_byte(name_row_base + tile_column); const u8 pattern = space().read_byte(pattern_base + (name << 3) + (line & 0x07)); for (int pixel_x = 0; pixel_x < 6; pixel_x++) @@ -1624,13 +1702,14 @@ void sega315_5124_device::draw_scanline_mode1(int *line_buffer, int line) // Display mode 3 (Multicolor Mode) void sega315_5124_device::draw_scanline_mode3(int *line_buffer, int line) { - const u16 name_base = ((m_reg[0x02] & 0x0f) << 10) + ((line >> 3) * 32); + const u16 name_base = ((m_reg[0x02] & 0x0f) << 10); const u16 pattern_base = ((m_reg[0x04] << 11) & (VRAM_SIZE - 1)); + const u16 name_row_base = name_base + ((line >> 3) * 32); /* Draw background layer */ for (int tile_column = 0; tile_column < 32; tile_column++) { - const u8 name = space().read_byte(name_base + tile_column); + const u8 name = space().read_byte(name_row_base + tile_column); const u8 pattern = space().read_byte(pattern_base + (name << 3) + (((line >> 3) & 3) << 1) + ((line & 4) >> 2)); for (int pixel_x = 0; pixel_x < 8; pixel_x++) @@ -1988,7 +2067,7 @@ void sega315_5124_device::device_start() //save_item(NAME(m_tmpbitmap)); //save_item(NAME(m_y1_bitmap)); save_item(NAME(m_draw_time)); - save_item(NAME(m_sprite_base)); + save_item(NAME(m_sprite_attribute_base)); save_item(NAME(m_sprite_pattern_line)); save_item(NAME(m_sprite_tile_selected)); save_item(NAME(m_sprite_x)); |