diff options
author | andreasnaive <andreasnaive@gmail.com> | 2019-03-25 22:44:58 +0100 |
---|---|---|
committer | andreasnaive <andreasnaive@gmail.com> | 2019-03-25 22:44:58 +0100 |
commit | c24473ddff715ecec2e258a6eb38960cf8c8e98e (patch) | |
tree | 8ea44b6396a6129913c0aac13859b5de9965e972 /src/devices/video | |
parent | 009cba4fb8102102168ef32870892438327f3705 (diff) | |
parent | 598cd5227223c3b04ca31f0dbc1981256d9ea3ff (diff) |
conflict resolution (nw)
Diffstat (limited to 'src/devices/video')
102 files changed, 2631 insertions, 1742 deletions
diff --git a/src/devices/video/315_5124.cpp b/src/devices/video/315_5124.cpp index ef3b07d1f4f..90b94577376 100644 --- a/src/devices/video/315_5124.cpp +++ b/src/devices/video/315_5124.cpp @@ -88,12 +88,12 @@ PAL frame timing #define BOTTOM_BORDER 4 #define BOTTOM_BLANKING 5 -static constexpr uint8_t ntsc_192[6] = { 3, 13, 27, 192, 24, 3 }; -static constexpr uint8_t ntsc_224[6] = { 3, 13, 11, 224, 8, 3 }; -static constexpr uint8_t ntsc_240[6] = { 3, 13, 3, 240, 0, 3 }; -static constexpr uint8_t pal_192[6] = { 3, 13, 54, 192, 48, 3 }; -static constexpr uint8_t pal_224[6] = { 3, 13, 38, 224, 32, 3 }; -static constexpr uint8_t pal_240[6] = { 3, 13, 30, 240, 24, 3 }; +static constexpr u8 ntsc_192[6] = { 3, 13, 27, 192, 24, 3 }; +static constexpr u8 ntsc_224[6] = { 3, 13, 11, 224, 8, 3 }; +static constexpr u8 ntsc_240[6] = { 3, 13, 3, 240, 0, 3 }; +static constexpr u8 pal_192[6] = { 3, 13, 54, 192, 48, 3 }; +static constexpr u8 pal_224[6] = { 3, 13, 38, 224, 32, 3 }; +static constexpr u8 pal_240[6] = { 3, 13, 30, 240, 24, 3 }; #define VINT_HPOS 0 #define VINT_FLAG_HPOS 1 @@ -104,8 +104,8 @@ static constexpr uint8_t pal_240[6] = { 3, 13, 30, 240, 24, 3 }; #define SPROVR_HPOS 6 #define SPRCOL_BASEHPOS 7 -static constexpr uint8_t line_315_5124[8] = { 24, 24, 26, 28 /* not verified */, 21, 23, 24, 59 }; -static constexpr uint8_t line_315_5377[8] = { 26, 26, 27, 28 /* not verified */, 24, 28, 26, 62 }; +static constexpr u8 line_315_5124[8] = { 24, 24, 26, 28 /* not verified */, 21, 23, 24, 59 }; +static constexpr u8 line_315_5377[8] = { 26, 26, 27, 28 /* not verified */, 24, 28, 26, 62 }; #define DISPLAY_DISABLED_HPOS 24 /* not verified, works if above 18 (for 'pstrike2') and below 25 (for 'fantdizzy') */ #define DISPLAY_CB_HPOS 2 /* fixes 'roadrash' (SMS game) title scrolling, due to line counter reload timing */ @@ -164,20 +164,22 @@ void sega315_5377_device::sega315_5377_palette(palette_device &palette) const // default address map void sega315_5124_device::sega315_5124(address_map &map) { - map(0x0000, VRAM_SIZE-1).ram(); + if (!has_configured_map(0)) + map(0x0000, VRAM_SIZE-1).ram(); } -sega315_5124_device::sega315_5124_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +sega315_5124_device::sega315_5124_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : sega315_5124_device(mconfig, SEGA315_5124, tag, owner, clock, SEGA315_5124_CRAM_SIZE, 0x00, 0x0f, 4, 8, line_315_5124) { } -sega315_5124_device::sega315_5124_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t cram_size, uint8_t palette_offset, uint8_t reg_num_mask, int max_sprite_zoom_hcount, int max_sprite_zoom_vcount, const uint8_t *line_timing) +sega315_5124_device::sega315_5124_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 cram_size, u8 palette_offset, u8 reg_num_mask, int max_sprite_zoom_hcount, int max_sprite_zoom_vcount, const u8 *line_timing) : device_t(mconfig, type, tag, owner, clock) , device_memory_interface(mconfig, *this) , device_video_interface(mconfig, *this) + , device_mixer_interface(mconfig, *this, 2) , m_cram_size(cram_size) , m_line_timing(line_timing) , m_palette_offset(palette_offset) @@ -188,32 +190,33 @@ sega315_5124_device::sega315_5124_device(const machine_config &mconfig, device_t , m_int_cb(*this) , m_csync_cb(*this) , m_pause_cb(*this) - , m_space_config("videoram", ENDIANNESS_LITTLE, 8, 14, 0, address_map_constructor(), address_map_constructor(FUNC(sega315_5124_device::sega315_5124), this)) + , m_space_config("videoram", ENDIANNESS_LITTLE, 8, 14, 0, address_map_constructor(FUNC(sega315_5124_device::sega315_5124), this)) , m_palette(*this, "palette") + , m_snsnd(*this, "snsnd") { } -sega315_5246_device::sega315_5246_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +sega315_5246_device::sega315_5246_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : sega315_5124_device(mconfig, SEGA315_5246, tag, owner, clock, SEGA315_5124_CRAM_SIZE, 0x00, 0x0f, 8, 8, line_315_5124) { } -sega315_5246_device::sega315_5246_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t cram_size, uint8_t palette_offset, uint8_t reg_num_mask, int max_sprite_zoom_hcount, int max_sprite_zoom_vcount, const uint8_t *line_timing) +sega315_5246_device::sega315_5246_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 cram_size, u8 palette_offset, u8 reg_num_mask, int max_sprite_zoom_hcount, int max_sprite_zoom_vcount, const u8 *line_timing) : sega315_5124_device(mconfig, type, tag, owner, clock, cram_size, palette_offset, reg_num_mask, max_sprite_zoom_hcount, max_sprite_zoom_vcount, line_timing) { } // Embedded mode 4 support of the 315-5313 VDP (see 315_5313.cpp), used by Sega Genesis/Mega Drive -sega315_5313_mode4_device::sega315_5313_mode4_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t cram_size, uint8_t palette_offset, uint8_t reg_num_mask, int max_sprite_zoom_hcount, int max_sprite_zoom_vcount, const uint8_t *line_timing) +sega315_5313_mode4_device::sega315_5313_mode4_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 cram_size, u8 palette_offset, u8 reg_num_mask, int max_sprite_zoom_hcount, int max_sprite_zoom_vcount, const u8 *line_timing) : sega315_5246_device(mconfig, type, tag, owner, clock, cram_size, palette_offset, reg_num_mask, max_sprite_zoom_hcount, max_sprite_zoom_vcount, line_timing) { } -sega315_5377_device::sega315_5377_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +sega315_5377_device::sega315_5377_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : sega315_5246_device(mconfig, SEGA315_5377, tag, owner, clock, SEGA315_5377_CRAM_SIZE, 0x10, 0x0f, 8, 8, line_315_5377) { } @@ -328,7 +331,7 @@ void sega315_5124_device::set_frame_timing() } -READ8_MEMBER( sega315_5124_device::vcount_read ) +u8 sega315_5124_device::vcount_read() { const int active_scr_start = m_frame_timing[VERTICAL_SYNC] + m_frame_timing[TOP_BLANKING] + m_frame_timing[TOP_BORDER]; int vpos = screen().vpos(); @@ -344,7 +347,7 @@ READ8_MEMBER( sega315_5124_device::vcount_read ) } -READ8_MEMBER( sega315_5124_device::hcount_read ) +u8 sega315_5124_device::hcount_read() { return m_hcounter; } @@ -592,10 +595,10 @@ void sega315_5124_device::process_line_timer() } -READ8_MEMBER( sega315_5124_device::data_read ) +u8 sega315_5124_device::data_read() { /* Return data buffer contents */ - const uint8_t temp = m_buffer; + const u8 temp = m_buffer; /* Clear pending write flag */ m_pending_control_write = false; @@ -653,9 +656,9 @@ void sega315_5124_device::check_pending_flags() } -READ8_MEMBER( sega315_5124_device::control_read ) +u8 sega315_5124_device::control_read() { - uint8_t temp; + u8 temp; check_pending_flags(); temp = m_status; @@ -667,7 +670,7 @@ READ8_MEMBER( sega315_5124_device::control_read ) /* Clear status flags */ m_hint_occurred = false; - m_status = uint8_t(~(STATUS_VINT | STATUS_SPROVR | STATUS_SPRCOL)); + m_status = u8(~(STATUS_VINT | STATUS_SPROVR | STATUS_SPRCOL)); if (m_irq_state == 1) { @@ -682,7 +685,7 @@ READ8_MEMBER( sega315_5124_device::control_read ) } -void sega315_5124_device::write_memory(uint8_t data) +void sega315_5124_device::write_memory(u8 data) { switch (m_addrmode) { @@ -702,7 +705,7 @@ void sega315_5124_device::write_memory(uint8_t data) } -void sega315_5313_mode4_device::write_memory(uint8_t data) +void sega315_5313_mode4_device::write_memory(u8 data) { switch (m_addrmode) { @@ -720,7 +723,7 @@ void sega315_5313_mode4_device::write_memory(uint8_t data) } -WRITE8_MEMBER( sega315_5124_device::data_write ) +void sega315_5124_device::data_write(u8 data) { /* Clear pending write flag */ m_pending_control_write = false; @@ -730,7 +733,7 @@ WRITE8_MEMBER( sega315_5124_device::data_write ) } -void sega315_5124_device::load_vram_addr(uint8_t data) +void sega315_5124_device::load_vram_addr(u8 data) { // Seems like the latched data is passed straight through // to the address register when in the middle of doing a command. @@ -742,7 +745,7 @@ void sega315_5124_device::load_vram_addr(uint8_t data) } -void sega315_5313_mode4_device::load_vram_addr(uint8_t data) +void sega315_5313_mode4_device::load_vram_addr(u8 data) { if (m_pending_control_write) m_control_write_data_latch = data; @@ -751,7 +754,7 @@ void sega315_5313_mode4_device::load_vram_addr(uint8_t data) } -WRITE8_MEMBER( sega315_5124_device::control_write ) +void sega315_5124_device::control_write(u8 data) { if (!m_pending_control_write) { @@ -859,13 +862,13 @@ WRITE8_MEMBER( sega315_5124_device::control_write ) } -uint16_t sega315_5124_device::name_table_row_mode4(int row) +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); } -uint16_t sega315_5246_device::name_table_row_mode4(int row) +u16 sega315_5246_device::name_table_row_mode4(int row) { return (row >> 3) << 6; } @@ -897,7 +900,7 @@ void sega315_5124_device::draw_leftmost_pixels_mode4(int *line_buffer, int *prio // Load data of bit plane 1 for the selected tile. const int tmp_bit_plane_1 = space().read_byte((tile_selected << 5) + ((parse_line & 0x07) << 2) + 0x01); - const uint8_t pen_bit_1 = BIT(tmp_bit_plane_1, 7 - pixel_x); + const u8 pen_bit_1 = BIT(tmp_bit_plane_1, 7 - pixel_x); for (int pixel_plot_x = 0; pixel_plot_x < fine_x_scroll; pixel_plot_x++) { @@ -931,7 +934,7 @@ void sega315_5124_device::draw_scanline_mode4(int *line_buffer, int *priority_se const int fine_x_scroll = (x_scroll & 0x07); int scroll_mod; - uint16_t name_table_address; + u16 name_table_address; if (m_y_pixels != 192) { name_table_address = ((m_reg[0x02] & 0x0c) << 10) | 0x0700; @@ -953,7 +956,7 @@ 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 uint16_t tile_data = space().read_word(name_table_address + name_table_row_mode4((line + y_scroll) % scroll_mod) + table_column); + const u16 tile_data = space().read_word(name_table_address + name_table_row_mode4((line + y_scroll) % scroll_mod) + table_column); const int tile_selected = (tile_data & 0x01ff); const int priority_select = tile_data & PRIORITY_BIT; @@ -978,12 +981,12 @@ void sega315_5124_device::draw_scanline_mode4(int *line_buffer, int *priority_se for (int pixel_x = 0; pixel_x < 8; pixel_x++) { - const uint8_t pen_bit_0 = BIT(bit_plane_0, 7 - pixel_x); - const uint8_t pen_bit_1 = BIT(bit_plane_1, 7 - pixel_x); - const uint8_t pen_bit_2 = BIT(bit_plane_2, 7 - pixel_x); - const uint8_t pen_bit_3 = BIT(bit_plane_3, 7 - pixel_x); + const u8 pen_bit_0 = BIT(bit_plane_0, 7 - pixel_x); + const u8 pen_bit_1 = BIT(bit_plane_1, 7 - pixel_x); + const u8 pen_bit_2 = BIT(bit_plane_2, 7 - pixel_x); + const u8 pen_bit_3 = BIT(bit_plane_3, 7 - pixel_x); - uint8_t pen_selected = (pen_bit_3 << 3 | pen_bit_2 << 2 | pen_bit_1 << 1 | pen_bit_0); + u8 pen_selected = (pen_bit_3 << 3 | pen_bit_2 << 2 | pen_bit_1 << 1 | pen_bit_0); if (palette_selected) pen_selected |= 0x10; @@ -1000,25 +1003,25 @@ void sega315_5124_device::draw_scanline_mode4(int *line_buffer, int *priority_se } -uint16_t sega315_5124_device::sprite_attributes_addr_mode4(uint16_t base) +u16 sega315_5124_device::sprite_attributes_addr_mode4(u16 base) { return base & ((BIT(m_reg[0x05], 0) << 7) | 0x3f7f); } -uint16_t sega315_5246_device::sprite_attributes_addr_mode4(uint16_t base) +u16 sega315_5246_device::sprite_attributes_addr_mode4(u16 base) { return base; } -uint8_t sega315_5124_device::sprite_tile_mask_mode4(uint8_t tile_number) +u8 sega315_5124_device::sprite_tile_mask_mode4(u8 tile_number) { return tile_number & (((m_reg[0x06] & 0x03) << 6) | 0x3f); } -uint8_t sega315_5246_device::sprite_tile_mask_mode4(uint8_t tile_number) +u8 sega315_5246_device::sprite_tile_mask_mode4(u8 tile_number) { return tile_number; } @@ -1029,7 +1032,7 @@ void sega315_5124_device::sprite_count_overflow(int line, int sprite_index) /* Overflow is flagged only on active display and when VINT isn't active */ if (!(m_status & STATUS_VINT) && line >= 0 && line < m_frame_timing[ACTIVE_DISPLAY_V]) { - uint8_t sprite_number_bits; + u8 sprite_number_bits; m_pending_status |= STATUS_SPROVR; if (sprite_index < 14) sprite_number_bits = (sprite_index + 1) / 2; @@ -1096,7 +1099,7 @@ void sega315_5124_device::select_sprites(int line) { 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 uint8_t flags = space().read_byte(m_sprite_base + sprite_index + 3); + const u8 flags = space().read_byte(m_sprite_base + sprite_index + 3); int sprite_line = parse_line - sprite_y; @@ -1265,28 +1268,28 @@ void sega315_5124_device::draw_sprites_mode4(int *line_buffer, int *priority_sel bool sprite_col_occurred = false; int sprite_col_x = 255; - uint8_t collision_buffer[256] = { 0 }; + u8 collision_buffer[256] = { 0 }; // Draw sprite layer for (int sprite_buffer_index = m_sprite_count - 1; sprite_buffer_index >= 0; sprite_buffer_index--) { const int sprite_x = m_sprite_x[sprite_buffer_index]; const int sprite_tile_selected = m_sprite_tile_selected[sprite_buffer_index]; - const uint16_t sprite_pattern_line = m_sprite_pattern_line[sprite_buffer_index]; + const u16 sprite_pattern_line = m_sprite_pattern_line[sprite_buffer_index]; const int zoom_scale = sprite_buffer_index < m_max_sprite_zoom_hcount ? m_sprite_zoom_scale : 1; - const uint8_t bit_plane_0 = space().read_byte((sprite_tile_selected << 5) + sprite_pattern_line + 0x00); - const uint8_t bit_plane_1 = space().read_byte((sprite_tile_selected << 5) + sprite_pattern_line + 0x01); - const uint8_t bit_plane_2 = space().read_byte((sprite_tile_selected << 5) + sprite_pattern_line + 0x02); - const uint8_t bit_plane_3 = space().read_byte((sprite_tile_selected << 5) + sprite_pattern_line + 0x03); + const u8 bit_plane_0 = space().read_byte((sprite_tile_selected << 5) + sprite_pattern_line + 0x00); + const u8 bit_plane_1 = space().read_byte((sprite_tile_selected << 5) + sprite_pattern_line + 0x01); + const u8 bit_plane_2 = space().read_byte((sprite_tile_selected << 5) + sprite_pattern_line + 0x02); + const u8 bit_plane_3 = space().read_byte((sprite_tile_selected << 5) + sprite_pattern_line + 0x03); for (int pixel_x = 0; pixel_x < 8; pixel_x++) { - const uint8_t pen_bit_0 = BIT(bit_plane_0, 7 - pixel_x); - const uint8_t pen_bit_1 = BIT(bit_plane_1, 7 - pixel_x); - const uint8_t pen_bit_2 = BIT(bit_plane_2, 7 - pixel_x); - const uint8_t pen_bit_3 = BIT(bit_plane_3, 7 - pixel_x); - const uint8_t pen_selected = (pen_bit_3 << 3 | pen_bit_2 << 2 | pen_bit_1 << 1 | pen_bit_0) | 0x10; + const u8 pen_bit_0 = BIT(bit_plane_0, 7 - pixel_x); + const u8 pen_bit_1 = BIT(bit_plane_1, 7 - pixel_x); + const u8 pen_bit_2 = BIT(bit_plane_2, 7 - pixel_x); + const u8 pen_bit_3 = BIT(bit_plane_3, 7 - pixel_x); + const u8 pen_selected = (pen_bit_3 << 3 | pen_bit_2 << 2 | pen_bit_1 << 1 | pen_bit_0) | 0x10; if (pen_selected == 0x10) // Transparent palette so skip draw continue; @@ -1352,15 +1355,15 @@ void sega315_5124_device::draw_sprites_tms9918_mode(int *line_buffer, int line) bool sprite_col_occurred = false; int sprite_col_x = 255; - uint8_t collision_buffer[256] = { 0 }; + u8 collision_buffer[256] = { 0 }; /* Draw sprite layer */ for (int sprite_buffer_index = m_sprite_count - 1; sprite_buffer_index >= 0; sprite_buffer_index--) { int sprite_x = m_sprite_x[sprite_buffer_index]; int sprite_tile_selected = m_sprite_tile_selected[sprite_buffer_index]; - const uint16_t sprite_pattern_line = m_sprite_pattern_line[sprite_buffer_index]; - const uint8_t flags = m_sprite_flags[sprite_buffer_index]; + const u16 sprite_pattern_line = m_sprite_pattern_line[sprite_buffer_index]; + const u8 flags = m_sprite_flags[sprite_buffer_index]; const int pen_selected = m_palette_offset + (flags & 0x0f); const int zoom_scale = sprite_buffer_index < m_max_sprite_zoom_hcount ? m_sprite_zoom_scale : 1; @@ -1375,7 +1378,7 @@ void sega315_5124_device::draw_sprites_tms9918_mode(int *line_buffer, int line) sprite_x += (zoom_scale > 1 ? 16 : 8); } - uint8_t pattern = space().read_byte(sprite_pattern_line + sprite_tile_selected * 8); + u8 pattern = space().read_byte(sprite_pattern_line + sprite_tile_selected * 8); for (int pixel_x = 0; pixel_x < 8; pixel_x++) { @@ -1421,23 +1424,23 @@ 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 uint16_t name_table_base = ((m_reg[0x02] & 0x0f) << 10) + ((line >> 3) * 32); - const uint16_t color_base = ((m_reg[0x03] & 0x80) << 6); + const u16 name_table_base = ((m_reg[0x02] & 0x0f) << 10) + ((line >> 3) * 32); + const u16 color_base = ((m_reg[0x03] & 0x80) << 6); const int color_mask = ((m_reg[0x03] & 0x7f) << 3) | 0x07; - const uint16_t pattern_base = ((m_reg[0x04] & 0x04) << 11); + 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; /* Draw background layer */ for (int tile_column = 0; tile_column < 32; tile_column++) { - const uint8_t name = space().read_byte(name_table_base + tile_column); - const uint8_t pattern = space().read_byte(pattern_base + (((pattern_offset + name) & pattern_mask) * 8) + (line & 0x07) ); - const uint8_t colors = space().read_byte(color_base + (((pattern_offset + name) & color_mask) * 8) + (line & 0x07) ); + const u8 name = space().read_byte(name_table_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) ); for (int pixel_x = 0; pixel_x < 8; pixel_x++) { - uint8_t pen_selected; + u8 pen_selected; const int pixel_plot_x = (tile_column << 3) + pixel_x; if (BIT(pattern, 7 - pixel_x)) @@ -1462,16 +1465,16 @@ 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 uint16_t name_base = ((m_reg[0x02] & 0x0f) << 10) + ((line >> 3) * 32); - const uint16_t color_base = ((m_reg[0x03] << 6) & (VRAM_SIZE - 1)); - const uint16_t pattern_base = ((m_reg[0x04] << 11) & (VRAM_SIZE - 1)); + const u16 name_base = ((m_reg[0x02] & 0x0f) << 10) + ((line >> 3) * 32); + const u16 color_base = ((m_reg[0x03] << 6) & (VRAM_SIZE - 1)); + const u16 pattern_base = ((m_reg[0x04] << 11) & (VRAM_SIZE - 1)); /* Draw background layer */ for (int tile_column = 0; tile_column < 32; tile_column++) { - const uint8_t name = space().read_byte(name_base + tile_column); - const uint8_t pattern = space().read_byte(pattern_base + (name << 3) + (line & 0x07)); - const uint8_t colors = space().read_byte(color_base + (name >> 3)); + const u8 name = space().read_byte(name_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)); for (int pixel_x = 0; pixel_x < 8; pixel_x++) { @@ -1496,8 +1499,8 @@ 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 uint16_t name_base = ((m_reg[0x02] & 0x0f) << 10) + ((line >> 3) * 32); - const uint16_t pattern_base = ((m_reg[0x04] << 11) & (VRAM_SIZE - 1)); + const u16 name_base = ((m_reg[0x02] & 0x0f) << 10) + ((line >> 3) * 32); + const u16 pattern_base = ((m_reg[0x04] << 11) & (VRAM_SIZE - 1)); for (int pixel_plot_x = 0; pixel_plot_x < 8; pixel_plot_x++) { @@ -1507,8 +1510,8 @@ 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 uint8_t name = space().read_byte(name_base + tile_column); - const uint8_t pattern = space().read_byte(pattern_base + (name << 3) + (line & 0x07)); + const u8 name = space().read_byte(name_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++) { @@ -1536,14 +1539,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 uint16_t name_base = ((m_reg[0x02] & 0x0f) << 10) + ((line >> 3) * 32); - const uint16_t pattern_base = ((m_reg[0x04] << 11) & (VRAM_SIZE - 1)); + const u16 name_base = ((m_reg[0x02] & 0x0f) << 10) + ((line >> 3) * 32); + const u16 pattern_base = ((m_reg[0x04] << 11) & (VRAM_SIZE - 1)); /* Draw background layer */ for (int tile_column = 0; tile_column < 32; tile_column++) { - const uint8_t name = space().read_byte(name_base + tile_column); - const uint8_t pattern = space().read_byte(pattern_base + (name << 3) + (((line >> 3) & 3) << 1) + ((line & 4) >> 2)); + const u8 name = space().read_byte(name_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++) { @@ -1635,8 +1638,8 @@ void sega315_5124_device::draw_scanline(int pixel_offset_x, int pixel_plot_y, in void sega315_5124_device::blit_scanline(int *line_buffer, int *priority_selected, int pixel_offset_x, int pixel_plot_y, int line) { - uint32_t *p_bitmap = &m_tmpbitmap.pix32(pixel_plot_y + line, pixel_offset_x); - uint8_t *p_y1 = &m_y1_bitmap.pix8(pixel_plot_y + line, pixel_offset_x); + u32 *p_bitmap = &m_tmpbitmap.pix32(pixel_plot_y + line, pixel_offset_x); + u8 *p_y1 = &m_y1_bitmap.pix8(pixel_plot_y + line, pixel_offset_x); int x = 0; if (m_vdp_mode == 4 && BIT(m_reg[0x00], 5)) @@ -1667,8 +1670,8 @@ void sega315_5377_device::blit_scanline(int *line_buffer, int *priority_selected } else { - uint32_t *p_bitmap = &m_tmpbitmap.pix32(pixel_plot_y + line, pixel_offset_x); - uint8_t *p_y1 = &m_y1_bitmap.pix8(pixel_plot_y + line, pixel_offset_x); + u32 *p_bitmap = &m_tmpbitmap.pix32(pixel_plot_y + line, pixel_offset_x); + u8 *p_y1 = &m_y1_bitmap.pix8(pixel_plot_y + line, pixel_offset_x); int x = 0; /* border on left side of the GG active screen */ @@ -1756,9 +1759,9 @@ void sega315_5377_device::update_palette() } -void sega315_5124_device::cram_write(uint8_t data) +void sega315_5124_device::cram_write(u8 data) { - uint16_t address = m_addr & m_cram_mask; + u16 address = m_addr & m_cram_mask; if (data != m_CRAM[address]) { m_CRAM[address] = data; @@ -1767,7 +1770,7 @@ void sega315_5124_device::cram_write(uint8_t data) } -void sega315_5377_device::cram_write(uint8_t data) +void sega315_5377_device::cram_write(u8 data) { if (m_sega315_5124_compatibility_mode) { @@ -1777,7 +1780,7 @@ void sega315_5377_device::cram_write(uint8_t data) { if (m_addr & 1) { - uint16_t address = (m_addr & m_cram_mask) & ~1; + u16 address = (m_addr & m_cram_mask) & ~1; if (m_buffer != m_CRAM[address] || data != m_CRAM[address + 1]) { m_CRAM[address] = m_buffer; @@ -1789,7 +1792,7 @@ void sega315_5377_device::cram_write(uint8_t data) } -uint32_t sega315_5124_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +u32 sega315_5124_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { copybitmap(bitmap, m_tmpbitmap, 0, 0, 0, 0, cliprect); return 0; @@ -1819,7 +1822,7 @@ void sega315_5313_mode4_device::stop_timers() DEVICE INTERFACE *****************************************************************************/ -void sega315_5124_device::vdp_postload() +void sega315_5124_device::device_post_load() { set_frame_timing(); } @@ -1886,8 +1889,6 @@ void sega315_5124_device::device_start() save_item(NAME(m_max_sprite_zoom_hcount)); save_item(NAME(m_max_sprite_zoom_vcount)); save_item(NAME(m_CRAM)); - - machine().save().register_postload(save_prepost_delegate(FUNC(sega315_5124_device::vdp_postload), this)); } @@ -1899,7 +1900,7 @@ void sega315_5124_device::device_reset() m_reg[0x02] = 0x0e; m_reg[0x0a] = 0xff; - m_status = m_pending_status = uint8_t(~(STATUS_VINT | STATUS_SPROVR | STATUS_SPRCOL)); + m_status = m_pending_status = u8(~(STATUS_VINT | STATUS_SPROVR | STATUS_SPRCOL)); m_pending_sprcol_x = 0; m_pending_control_write = false; m_pending_hint = false; @@ -1934,6 +1935,8 @@ void sega315_5124_device::device_reset() void sega315_5124_device::device_add_mconfig(machine_config &config) { PALETTE(config, m_palette, FUNC(sega315_5124_device::sega315_5124_palette), SEGA315_5124_PALETTE_SIZE); + + SEGAPSG(config, m_snsnd, DERIVED_CLOCK(1, 3)).add_route(ALL_OUTPUTS, *this, 1.0, AUTO_ALLOC_INPUT, 0); } void sega315_5377_device::device_reset() @@ -1949,6 +1952,11 @@ void sega315_5377_device::device_reset() void sega315_5377_device::device_add_mconfig(machine_config &config) { sega315_5246_device::device_add_mconfig(config); + m_palette->set_entries(SEGA315_5377_PALETTE_SIZE); m_palette->set_init(FUNC(sega315_5377_device::sega315_5377_palette)); + + GAMEGEAR(config.replace(), m_snsnd, DERIVED_CLOCK(1, 3)); + m_snsnd->add_route(0, *this, 1.0, AUTO_ALLOC_INPUT, 0); + m_snsnd->add_route(1, *this, 1.0, AUTO_ALLOC_INPUT, 1); } diff --git a/src/devices/video/315_5124.h b/src/devices/video/315_5124.h index 3ff7b5165a1..b88cf5c38d7 100644 --- a/src/devices/video/315_5124.h +++ b/src/devices/video/315_5124.h @@ -13,6 +13,7 @@ #pragma once +#include "sound/sn76496.h" #include "emupal.h" #include "screen.h" @@ -28,7 +29,8 @@ DECLARE_DEVICE_TYPE(SEGA315_5377, sega315_5377_device) /* aka Gamegear (2 A class sega315_5124_device : public device_t, public device_memory_interface, - public device_video_interface + public device_video_interface, + public device_mixer_interface { public: static constexpr unsigned WIDTH = 342; /* 342 pixels */ @@ -51,23 +53,22 @@ public: // construction/destruction - sega315_5124_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + sega315_5124_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); void set_is_pal(bool is_pal) { m_is_pal = is_pal; } - template <class Object> devcb_base &set_int_callback(Object &&cb) { return m_int_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_csync_callback(Object &&cb) { return m_csync_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_pause_callback(Object &&cb) { return m_pause_cb.set_callback(std::forward<Object>(cb)); } auto irq() { return m_int_cb.bind(); } auto csync() { return m_csync_cb.bind(); } auto pause() { return m_pause_cb.bind(); } - DECLARE_READ8_MEMBER( data_read ); - DECLARE_WRITE8_MEMBER( data_write ); - DECLARE_READ8_MEMBER( control_read ); - DECLARE_WRITE8_MEMBER( control_write ); - DECLARE_READ8_MEMBER( vcount_read ); - DECLARE_READ8_MEMBER( hcount_read ); + void psg_w(u8 data) { m_snsnd->write(data); } + void psg_stereo_w(u8 data) { m_snsnd->stereo_w(data); } + u8 data_read(); + void data_write(u8 data); + u8 control_read(); + void control_write(u8 data); + u8 vcount_read(); + u8 hcount_read(); void hcount_latch() { hcount_latch_at_hpos(screen().hpos()); }; void hcount_latch_at_hpos(int hpos); @@ -76,7 +77,7 @@ public: bitmap_ind8 &get_y1_bitmap() { return m_y1_bitmap; }; /* update the screen */ - uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); virtual void set_sega315_5124_compatibility_mode(bool sega315_5124_compatibility_mode) { } @@ -84,9 +85,10 @@ protected: static constexpr unsigned SEGA315_5377_CRAM_SIZE = 0x40; /* 32 colors x 2 bytes per color = 64 bytes */ static constexpr unsigned SEGA315_5124_CRAM_SIZE = 0x20; /* 32 colors x 1 bytes per color = 32 bytes */ - sega315_5124_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t cram_size, uint8_t palette_offset, uint8_t reg_num_mask, int max_sprite_zoom_hcount, int max_sprite_zoom_vcount, const uint8_t *line_timing); + sega315_5124_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 cram_size, u8 palette_offset, u8 reg_num_mask, int max_sprite_zoom_hcount, int max_sprite_zoom_vcount, const u8 *line_timing); // device-level overrides + virtual void device_post_load() override; virtual void device_start() override; virtual void device_reset() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; @@ -101,9 +103,9 @@ protected: void set_display_settings(); void set_frame_timing(); virtual void update_palette(); - virtual void write_memory(uint8_t data); - virtual void cram_write(uint8_t data); - virtual void load_vram_addr(uint8_t data); + virtual void write_memory(u8 data); + virtual void cram_write(u8 data); + virtual void load_vram_addr(u8 data); virtual void select_display_mode(); virtual void select_extended_res_mode4(bool M1, bool M2, bool M3); virtual void select_sprites(int line); @@ -112,9 +114,9 @@ protected: virtual void draw_scanline(int pixel_offset_x, int pixel_plot_y, int line); virtual void blit_scanline(int *line_buffer, int *priority_selected, int pixel_offset_x, int pixel_plot_y, int line); virtual void draw_leftmost_pixels_mode4(int *line_buffer, int *priority_selected, int fine_x_scroll, int palette_selected, int tile_line); - virtual uint16_t name_table_row_mode4(int row); - virtual uint16_t sprite_attributes_addr_mode4(uint16_t base); - virtual uint8_t sprite_tile_mask_mode4(uint8_t tile_number); + virtual u16 name_table_row_mode4(int row); + virtual u16 sprite_attributes_addr_mode4(u16 base); + virtual u8 sprite_tile_mask_mode4(u8 tile_number); void process_line_timer(); void draw_scanline_mode4(int *line_buffer, int *priority_selected, int line); void draw_sprites_mode4(int *line_buffer, int *priority_selected, int line); @@ -125,44 +127,42 @@ protected: void draw_scanline_mode0(int *line_buffer, int line); void check_pending_flags(); - void vdp_postload(); - - uint8_t m_reg[16]; /* All the registers */ - uint8_t m_status; /* Status register */ - uint8_t m_pending_status; /* Pending status flags */ - uint8_t m_reg8copy; /* Internal copy of register 8 (X-Scroll) */ - uint8_t m_reg9copy; /* Internal copy of register 9 (Y-Scroll) */ - uint8_t m_addrmode; /* Type of VDP action */ - uint16_t m_addr; /* Contents of internal VDP address register */ - const uint8_t m_cram_size; /* CRAM size */ - uint8_t m_cram_mask; /* Mask to switch between SMS and GG CRAM sizes */ + u8 m_reg[16]; /* All the registers */ + u8 m_status; /* Status register */ + u8 m_pending_status; /* Pending status flags */ + u8 m_reg8copy; /* Internal copy of register 8 (X-Scroll) */ + u8 m_reg9copy; /* Internal copy of register 9 (Y-Scroll) */ + u8 m_addrmode; /* Type of VDP action */ + u16 m_addr; /* Contents of internal VDP address register */ + const u8 m_cram_size; /* CRAM size */ + u8 m_cram_mask; /* Mask to switch between SMS and GG CRAM sizes */ bool m_cram_dirty; /* Have there been any changes to the CRAM area */ bool m_hint_occurred; bool m_pending_hint; bool m_pending_control_write; int m_pending_sprcol_x; - uint8_t m_buffer; - uint8_t m_control_write_data_latch; + u8 m_buffer; + u8 m_control_write_data_latch; bool m_sega315_5124_compatibility_mode; /* when true, GG VDP behaves as SMS VDP */ int m_irq_state; /* The status of the IRQ line of the VDP */ int m_vdp_mode; /* Current mode of the VDP: 0,1,2,3,4 */ int m_y_pixels; /* 192, 224, 240 */ int m_draw_time; - uint8_t m_line_counter; - uint8_t m_hcounter; - uint8_t m_CRAM[SEGA315_5377_CRAM_SIZE]; /* CRAM */ - const uint8_t *m_frame_timing; - const uint8_t *m_line_timing; + u8 m_line_counter; + u8 m_hcounter; + u8 m_CRAM[SEGA315_5377_CRAM_SIZE]; /* CRAM */ + const u8 *m_frame_timing; + const u8 *m_line_timing; bitmap_rgb32 m_tmpbitmap; bitmap_ind8 m_y1_bitmap; - const uint8_t m_palette_offset; - const uint8_t m_reg_num_mask; + const u8 m_palette_offset; + const u8 m_reg_num_mask; bool m_display_disabled; - uint16_t m_sprite_base; - uint16_t m_sprite_pattern_line[8]; + u16 m_sprite_base; + u16 m_sprite_pattern_line[8]; int m_sprite_tile_selected[8]; int m_sprite_x[8]; - uint8_t m_sprite_flags[8]; + u8 m_sprite_flags[8]; int m_sprite_count; int m_sprite_height; int m_sprite_zoom_scale; @@ -195,20 +195,21 @@ protected: static constexpr device_timer_id TIMER_FLAGS = 7; required_device<palette_device> m_palette; + required_device<sn76496_base_device> m_snsnd; }; class sega315_5246_device : public sega315_5124_device { public: - sega315_5246_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + sega315_5246_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: - sega315_5246_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t cram_size, uint8_t palette_offset, uint8_t reg_num_mask, int max_sprite_zoom_hcount, int max_sprite_zoom_vcount, const uint8_t *line_timing); + sega315_5246_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 cram_size, u8 palette_offset, u8 reg_num_mask, int max_sprite_zoom_hcount, int max_sprite_zoom_vcount, const u8 *line_timing); - virtual uint16_t name_table_row_mode4(int row) override; - virtual uint16_t sprite_attributes_addr_mode4(uint16_t base) override; - virtual uint8_t sprite_tile_mask_mode4(uint8_t tile_number) override; + virtual u16 name_table_row_mode4(int row) override; + virtual u16 sprite_attributes_addr_mode4(u16 base) override; + virtual u8 sprite_tile_mask_mode4(u8 tile_number) override; virtual void select_extended_res_mode4(bool M1, bool M2, bool M3) override; }; @@ -216,18 +217,18 @@ protected: class sega315_5377_device : public sega315_5246_device { public: - sega315_5377_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + sega315_5377_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void set_sega315_5124_compatibility_mode(bool sega315_5124_compatibility_mode) override; protected: - sega315_5377_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t cram_size, uint8_t palette_offset, uint8_t reg_num_mask, int max_sprite_zoom_hcount, int max_sprite_zoom_vcount, const uint8_t *line_timing); + sega315_5377_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 cram_size, u8 palette_offset, u8 reg_num_mask, int max_sprite_zoom_hcount, int max_sprite_zoom_vcount, const u8 *line_timing); virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override; virtual void update_palette() override; - virtual void cram_write(uint8_t data) override; + virtual void cram_write(u8 data) override; virtual void blit_scanline(int *line_buffer, int *priority_selected, int pixel_offset_x, int pixel_plot_y, int line) override; private: @@ -242,10 +243,10 @@ public: void stop_timers(); protected: - sega315_5313_mode4_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t cram_size, uint8_t palette_offset, uint8_t reg_num_mask, int max_sprite_zoom_hcount, int max_sprite_zoom_vcount, const uint8_t *line_timing); + sega315_5313_mode4_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 cram_size, u8 palette_offset, u8 reg_num_mask, int max_sprite_zoom_hcount, int max_sprite_zoom_vcount, const u8 *line_timing); - virtual void write_memory(uint8_t data) override; - virtual void load_vram_addr(uint8_t data) override; + virtual void write_memory(u8 data) override; + virtual void load_vram_addr(u8 data) override; virtual void select_sprites(int line) override; virtual void sprite_collision(int line, int sprite_col_x) override; virtual void sprite_count_overflow(int line, int sprite_index) override; @@ -254,54 +255,4 @@ protected: virtual void draw_leftmost_pixels_mode4(int *line_buffer, int *priority_selected, int fine_x_scroll, int palette_selected, int tile_line) override; }; - -/*************************************************************************** - DEVICE CONFIGURATION MACROS -***************************************************************************/ - -#define MCFG_SEGA315_5124_SET_SCREEN MCFG_VIDEO_SET_SCREEN - -#define MCFG_SEGA315_5124_IS_PAL(_bool) \ - downcast<sega315_5124_device &>(*device).set_is_pal(_bool); - -#define MCFG_SEGA315_5124_INT_CB(_devcb) \ - downcast<sega315_5124_device &>(*device).set_int_callback(DEVCB_##_devcb); - -#define MCFG_SEGA315_5124_CSYNC_CB(_devcb) \ - downcast<sega315_5124_device &>(*device).set_csync_callback(DEVCB_##_devcb); - -#define MCFG_SEGA315_5124_PAUSE_CB(_devcb) \ - downcast<sega315_5124_device &>(*device).set_pause_callback(DEVCB_##_devcb); - - -#define MCFG_SEGA315_5246_SET_SCREEN MCFG_VIDEO_SET_SCREEN - -#define MCFG_SEGA315_5246_IS_PAL(_bool) \ - downcast<sega315_5246_device &>(*device).set_is_pal(_bool); - -#define MCFG_SEGA315_5246_INT_CB(_devcb) \ - downcast<sega315_5246_device &>(*device).set_int_callback(DEVCB_##_devcb); - -#define MCFG_SEGA315_5246_CSYNC_CB(_devcb) \ - downcast<sega315_5246_device &>(*device).set_csync_callback(DEVCB_##_devcb); - -#define MCFG_SEGA315_5246_PAUSE_CB(_devcb) \ - downcast<sega315_5246_device &>(*device).set_pause_callback(DEVCB_##_devcb); - - -#define MCFG_SEGA315_5377_SET_SCREEN MCFG_VIDEO_SET_SCREEN - -#define MCFG_SEGA315_5377_IS_PAL(_bool) \ - downcast<sega315_5377_device &>(*device).set_is_pal(_bool); - -#define MCFG_SEGA315_5377_INT_CB(_devcb) \ - downcast<sega315_5377_device &>(*device).set_int_callback(DEVCB_##_devcb); - -#define MCFG_SEGA315_5377_CSYNC_CB(_devcb) \ - downcast<sega315_5377_device &>(*device).set_csync_callback(DEVCB_##_devcb); - -#define MCFG_SEGA315_5377_PAUSE_CB(_devcb) \ - downcast<sega315_5377_device &>(*device).set_pause_callback(DEVCB_##_devcb); - - #endif // MAME_VIDEO_315_5124_H diff --git a/src/devices/video/315_5313.cpp b/src/devices/video/315_5313.cpp index 921c7011a29..b56f1349f59 100644 --- a/src/devices/video/315_5313.cpp +++ b/src/devices/video/315_5313.cpp @@ -161,7 +161,6 @@ DEFINE_DEVICE_TYPE(SEGA315_5313, sega315_5313_device, "sega315_5313", "Sega 315- sega315_5313_device::sega315_5313_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) // mode 4 support, for SMS compatibility, is implemented in 315_5124.cpp : sega315_5313_mode4_device(mconfig, SEGA315_5313, tag, owner, clock, SEGA315_5124_CRAM_SIZE, 0x00, 0x1f, 0, 0, line_315_5313_mode4) - , device_mixer_interface(mconfig, *this, 2) , m_render_bitmap(nullptr) , m_render_line(nullptr) , m_render_line_raw(nullptr) @@ -210,7 +209,6 @@ sega315_5313_device::sega315_5313_device(const machine_config &mconfig, const ch , m_palette_lookup_highlight(nullptr) , m_space68k(nullptr) , m_cpu68k(*this, finder_base::DUMMY_TAG) - , m_snsnd(*this, "snsnd") { m_use_alt_timing = 0; m_palwrite_base = -1; @@ -227,7 +225,7 @@ void sega315_5313_device::device_add_mconfig(machine_config &config) m_palette->set_entries(0x200); // more entries for 32X - not really the cleanest way to do this - SEGAPSG(config, m_snsnd, DERIVED_CLOCK(1, 15)).add_route(ALL_OUTPUTS, *this, 0.5, AUTO_ALLOC_INPUT, 0); + SEGAPSG(config.replace(), m_snsnd, DERIVED_CLOCK(1, 15)).add_route(ALL_OUTPUTS, *this, 0.5, AUTO_ALLOC_INPUT, 0); } TIMER_CALLBACK_MEMBER(sega315_5313_device::irq6_on_timer_callback) @@ -968,9 +966,9 @@ WRITE16_MEMBER( sega315_5313_device::vdp_w ) case 0x16: { // accessed by either segapsg_device or sn76496_device - if (m_snsnd && ACCESSING_BITS_0_7) - m_snsnd->write(data & 0xff); - //if (m_snsnd && ACCESSING_BITS_8_15) sn->write((data>>8) & 0xff); + if (ACCESSING_BITS_0_7) + psg_w(data & 0xff); + //if (ACCESSING_BITS_8_15) psg_w((data>>8) & 0xff); break; } diff --git a/src/devices/video/315_5313.h b/src/devices/video/315_5313.h index f2aae550f8b..28d1d995d97 100644 --- a/src/devices/video/315_5313.h +++ b/src/devices/video/315_5313.h @@ -9,49 +9,9 @@ #include "video/315_5124.h" #include "cpu/m68000/m68000.h" #include "machine/timer.h" -#include "sound/sn76496.h" -#define MCFG_SEGA315_5313_IS_PAL(_bool) \ - downcast<sega315_5313_device &>(*device).set_is_pal(_bool); - -#define MCFG_SEGA315_5313_INT_CB(_devcb) \ - downcast<sega315_5313_device &>(*device).set_int_callback(DEVCB_##_devcb); - -#define MCFG_SEGA315_5313_PAUSE_CB(_devcb) \ - downcast<sega315_5313_device &>(*device).set_pause_callback(DEVCB_##_devcb); - -#define MCFG_SEGA315_5313_SND_IRQ_CALLBACK(_write) \ - downcast<sega315_5313_device &>(*device).set_sndirqline_callback(DEVCB_##_write); - -#define MCFG_SEGA315_5313_LV6_IRQ_CALLBACK(_write) \ - downcast<sega315_5313_device &>(*device).set_lv6irqline_callback(DEVCB_##_write); - -#define MCFG_SEGA315_5313_LV4_IRQ_CALLBACK(_write) \ - downcast<sega315_5313_device &>(*device).set_lv4irqline_callback(DEVCB_##_write); - -#define MCFG_SEGA315_5313_ALT_TIMING(_data) \ - downcast<sega315_5313_device &>(*device).set_alt_timing(_data); - -#define MCFG_SEGA315_5313_PAL_WRITE_BASE(_data) \ - downcast<sega315_5313_device &>(*device).set_pal_write_base(_data); - -#define MCFG_SEGA315_5313_PALETTE(_palette_tag) \ - downcast<sega315_5313_device &>(*device).set_palette(_palette_tag); - - -// Temporary solution while 32x VDP mixing and scanline interrupting is moved outside MD VDP -#define MCFG_SEGA315_5313_32X_SCANLINE_CB(_class, _method) \ - downcast<sega315_5313_device &>(*device).set_md_32x_scanline(sega315_5313_device::md_32x_scanline_delegate(&_class::_method, #_class "::" #_method, this)); - -#define MCFG_SEGA315_5313_32X_INTERRUPT_CB(_class, _method) \ - downcast<sega315_5313_device &>(*device).set_md_32x_interrupt(sega315_5313_device::md_32x_interrupt_delegate(&_class::_method, #_class "::" #_method, this)); - -#define MCFG_SEGA315_5313_32X_SCANLINE_HELPER_CB(_class, _method) \ - downcast<sega315_5313_device &>(*device).set_md_32x_scanline_helper(sega315_5313_device::md_32x_scanline_helper_delegate(&_class::_method, #_class "::" #_method, this)); - - -class sega315_5313_device : public sega315_5313_mode4_device, public device_mixer_interface +class sega315_5313_device : public sega315_5313_mode4_device { public: template <typename T> @@ -67,9 +27,6 @@ public: typedef device_delegate<void (int scanline, int irq6)> md_32x_interrupt_delegate; typedef device_delegate<void (int scanline)> md_32x_scanline_helper_delegate; - template <class Object> devcb_base &set_sndirqline_callback(Object &&cb) { return m_sndirqline_callback.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_lv6irqline_callback(Object &&cb) { return m_lv6irqline_callback.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_lv4irqline_callback(Object &&cb) { return m_lv4irqline_callback.set_callback(std::forward<Object>(cb)); } auto snd_irq() { return m_sndirqline_callback.bind(); } auto lv6_irq() { return m_lv6irqline_callback.bind(); } auto lv4_irq() { return m_lv4irqline_callback.bind(); } @@ -78,9 +35,10 @@ public: void set_pal_write_base(int palwrite_base) { m_palwrite_base = palwrite_base; } template <typename T> void set_palette(T &&tag) { m_palette.set_tag(std::forward<T>(tag)); } - template <typename Object> void set_md_32x_scanline(Object &&cb) { m_32x_scanline_func = std::forward<Object>(cb); } - template <typename Object> void set_md_32x_interrupt(Object &&cb) { m_32x_interrupt_func = std::forward<Object>(cb); } - template <typename Object> void set_md_32x_scanline_helper(Object &&cb) { m_32x_scanline_helper_func = std::forward<Object>(cb); } + // Temporary solution while 32x VDP mixing and scanline interrupting is moved outside MD VDP + template <typename... T> void set_md_32x_scanline(T &&... args) { m_32x_scanline_func = md_32x_scanline_delegate(std::forward<T>(args)...); } + template <typename... T> void set_md_32x_interrupt(T &&... args) { m_32x_interrupt_func = md_32x_interrupt_delegate(std::forward<T>(args)...); } + template <typename... T> void set_md_32x_scanline_helper(T &&... args) { m_32x_scanline_helper_func = md_32x_scanline_helper_delegate(std::forward<T>(args)...); } int m_use_alt_timing; // use MAME scanline timer instead, render only one scanline to a single line buffer, to be rendered by a partial update call.. experimental @@ -228,7 +186,6 @@ private: address_space *m_space68k; required_device<m68000_base_device> m_cpu68k; - required_device<sn76496_base_device> m_snsnd; }; diff --git a/src/devices/video/cdp1862.cpp b/src/devices/video/cdp1862.cpp index 78985db211c..ba4375c54de 100644 --- a/src/devices/video/cdp1862.cpp +++ b/src/devices/video/cdp1862.cpp @@ -126,7 +126,7 @@ void cdp1862_device::device_reset() // dma_w - //------------------------------------------------- -WRITE8_MEMBER( cdp1862_device::dma_w ) +void cdp1862_device::dma_w(uint8_t data) { int rd = 1, bd = 1, gd = 1; int sx = screen().hpos() + 4; diff --git a/src/devices/video/cdp1862.h b/src/devices/video/cdp1862.h index 0ee90fa3bd6..8ab9716642b 100644 --- a/src/devices/video/cdp1862.h +++ b/src/devices/video/cdp1862.h @@ -49,7 +49,7 @@ public: void set_luminance(double r, double b, double g, double bkg) { m_lum_r = r; m_lum_b = b; m_lum_g = g; m_lum_bkg = bkg; } void set_chrominance(double r, double b, double g, double bkg) { m_chr_r = r; m_chr_b = b; m_chr_g = g; m_chr_bkg = bkg; } - DECLARE_WRITE8_MEMBER( dma_w ); + void dma_w(uint8_t data); DECLARE_WRITE_LINE_MEMBER( bkg_w ); DECLARE_WRITE_LINE_MEMBER( con_w ); diff --git a/src/devices/video/cesblit.h b/src/devices/video/cesblit.h index f22f16df260..d535921ef6b 100644 --- a/src/devices/video/cesblit.h +++ b/src/devices/video/cesblit.h @@ -11,21 +11,6 @@ #pragma once -/*************************************************************************** - INTERFACE CONFIGURATION MACROS -***************************************************************************/ - -#define MCFG_CESBLIT_ADD(_tag, _screen, _clock) \ - MCFG_DEVICE_ADD(_tag, CESBLIT, _clock) \ - MCFG_VIDEO_SET_SCREEN(_screen) - -#define MCFG_CESBLIT_MAP MCFG_DEVICE_PROGRAM_MAP - -#define MCFG_CESBLIT_COMPUTE_ADDR(_compute_addr) \ - downcast<cesblit_device &>(*device).set_compute_addr(_compute_addr); - -#define MCFG_CESBLIT_IRQ_CB(_devcb) \ - downcast<cesblit_device &>(*device).set_irq_callback(DEVCB_##_devcb); /*************************************************************************** TYPE DEFINITIONS @@ -41,11 +26,18 @@ public: typedef int (*compute_addr_t) (uint16_t reg_low, uint16_t reg_mid, uint16_t reg_high); // construction/destruction + template <typename T> + cesblit_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&screen_tag) + : cesblit_device(mconfig, tag, owner, clock) + { + set_screen(std::forward<T>(screen_tag)); + } + cesblit_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // configuration void set_compute_addr(compute_addr_t compute_addr) { m_compute_addr = compute_addr; } - template <class Object> devcb_base &set_irq_callback(Object &&cb) { return m_blit_irq_cb.set_callback(std::forward<Object>(cb)); } + auto irq_callback() { return m_blit_irq_cb.bind(); } DECLARE_WRITE16_MEMBER(color_w); DECLARE_WRITE16_MEMBER(addr_hi_w); diff --git a/src/devices/video/crt9007.cpp b/src/devices/video/crt9007.cpp index 40279d1316a..ff3893a4ca6 100644 --- a/src/devices/video/crt9007.cpp +++ b/src/devices/video/crt9007.cpp @@ -222,7 +222,8 @@ const int STATUS_LIGHT_PEN_UPDATE = 0x20; // default address map void crt9007_device::crt9007(address_map &map) { - map(0x0000, 0x3fff).ram(); + if (!has_configured_map(0)) + map(0x0000, 0x3fff).ram(); } @@ -456,7 +457,7 @@ crt9007_device::crt9007_device(const machine_config &mconfig, const char *tag, d device_t(mconfig, CRT9007, tag, owner, clock), device_memory_interface(mconfig, *this), device_video_interface(mconfig, *this), - m_space_config("videoram", ENDIANNESS_LITTLE, 8, 14, 0, address_map_constructor(), address_map_constructor(FUNC(crt9007_device::crt9007), this)), + m_space_config("videoram", ENDIANNESS_LITTLE, 8, 14, 0, address_map_constructor(FUNC(crt9007_device::crt9007), this)), m_write_int(*this), m_write_dmar(*this), m_write_hs(*this), diff --git a/src/devices/video/crt9021.h b/src/devices/video/crt9021.h index 2a7e513fdf2..65de1032a64 100644 --- a/src/devices/video/crt9021.h +++ b/src/devices/video/crt9021.h @@ -38,10 +38,6 @@ #define CRT9021_DRAW_CHARACTER_MEMBER(_name) void _name(bitmap_rgb32 &bitmap, int y, int x, uint8_t video, int intout) -#define MCFG_CRT9021_DRAW_CHARACTER_CALLBACK_OWNER(_class, _method) \ - downcast<crt9021_device &>(*device).set_display_callback(crt9021_device::draw_character_delegate(&_class::_method, #_class "::" #_method, this)); - - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -57,7 +53,7 @@ public: // construction/destruction crt9021_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template <typename Object> void set_display_callback(Object &&cb) { m_display_cb = std::forward<Object>(cb); } + template <typename... T> void set_display_callback(T &&... args) { m_display_cb = draw_character_delegate(std::forward<T>(args)...); } void write(uint8_t data) { m_data = data; } DECLARE_WRITE8_MEMBER( write ) { write(data); } diff --git a/src/devices/video/crt9028.cpp b/src/devices/video/crt9028.cpp new file mode 100644 index 00000000000..31c0c748420 --- /dev/null +++ b/src/devices/video/crt9028.cpp @@ -0,0 +1,371 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + Standard Microsystems CRT9028/9128 Video Terminal Logic Controller + + The CRT 9028 and CRT 9128 are single-chip terminal-oriented video + processors. The two differ from each other in their bus protocol + for accessing the address, data and status registers: the 9028 has + separate RD and WR strobes for an 8051 or similar microcontroller, + while the 9128 replaces these with DS and R/W inputs that are more + Z8-oriented. A separate address/data bus connects to a 2Kx8 static + RAM or similar as display memory. + + The internal 128-character set is mask-programmed, as are all + screen timings, with alternate vertical timings to allow operation + at either 60 Hz or 50 Hz. Mask parameters also determine the + polarity of the sync signals, the positioning of the underline + attribute and cursor and the dot patterns used for 6-segment wide + (block) graphics and 4-segment thin (line) graphics. + + TODO: implement timing and display functions + +**********************************************************************/ + +#include "emu.h" +#include "video/crt9028.h" +#include "screen.h" + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// device type definition +DEFINE_DEVICE_TYPE(CRT9028_000, crt9028_000_device, "crt9028_000", "CRT9028-000 VTLC") + +//************************************************************************** +// DEVICE IMPLEMENTATION +//************************************************************************** + +//------------------------------------------------- +// crt9028_device - constructor +//------------------------------------------------- + +crt9028_device::crt9028_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, + int dots_per_char, int chars_per_row, int horiz_blanking, int hsync_delay, int hsync_width, bool hsync_active, + int char_rows, int scans_per_char, bool vsync_active, + int vert_blanking, int vsync_delay, bool vsync_width, + int alt_vert_blanking, int alt_vsync_delay, bool alt_vsync_width, + int csync_delay, int csync_width, int underline, + u16 wide_gfx_seg1_4, u16 wide_gfx_seg2_5, u16 wide_gfx_seg3_6, u8 wide_gfx_pattern, + u16 thin_gfx_seg1, u16 thin_gfx_seg2, u16 thin_gfx_seg3, u16 thin_gfx_seg4, + u8 thin_gfx_dots1, u8 thin_gfx_dots2, u8 thin_gfx_dots3, u8 thin_gfx_dots4) + : device_t(mconfig, type, tag, owner, clock) + , device_memory_interface(mconfig, *this) + , device_video_interface(mconfig, *this) + , m_space_config("charram", ENDIANNESS_LITTLE, 8, 11, 0) + , m_charset(*this, "charset") + , m_hsync_callback(*this) + , m_vsync_callback(*this) + , m_dots_per_char(dots_per_char) + , m_chars_per_row(chars_per_row) + , m_horiz_blanking(horiz_blanking) + , m_hsync_delay(hsync_delay) + , m_hsync_width(hsync_width) + , m_hsync_active(hsync_active) + , m_char_rows(char_rows) + , m_scans_per_char(scans_per_char) + , m_vsync_active(vsync_active) + , m_vert_blanking{vert_blanking, alt_vert_blanking} + , m_vsync_delay{vsync_delay, alt_vsync_delay} + , m_vsync_width{vsync_width, alt_vsync_width} + , m_csync_delay(csync_delay) + , m_csync_width(csync_width) + , m_underline(underline) + , m_wide_gfx_seg{wide_gfx_seg1_4, wide_gfx_seg2_5, wide_gfx_seg3_6} + , m_wide_gfx_pattern(wide_gfx_pattern) + , m_thin_gfx_seg{thin_gfx_seg1, thin_gfx_seg2, thin_gfx_seg3, thin_gfx_seg4} + , m_thin_gfx_dots{thin_gfx_dots1, thin_gfx_dots2, thin_gfx_dots3, thin_gfx_dots4} + , m_address_register(0) +{ + // Mostly unused now + (void)m_hsync_delay; + (void)m_hsync_width; + (void)m_hsync_active; + (void)m_vsync_active; + (void)m_vsync_delay; + (void)m_vsync_width; + (void)m_csync_delay; + (void)m_csync_width; + (void)m_underline; + (void)m_wide_gfx_seg; + (void)m_wide_gfx_pattern; + (void)m_thin_gfx_seg; + (void)m_thin_gfx_dots; +} + + +//------------------------------------------------- +// crt9028_000_device - constructor +//------------------------------------------------- + +crt9028_000_device::crt9028_000_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : crt9028_device(mconfig, CRT9028_000, tag, owner, clock, + 7, 80, 20, 4, 8, false, + 24, 10, false, + 20, 4, 8, + 72, 30, 10, + 2, 8, 9, + 0x3c0, 0x038, 0x007, 0x0f, + 0x3e0, 0x020, 0x03f, 0x020, + 0x10, 0xff, 0x10, 0xff) +{ +} + + +//------------------------------------------------- +// device_config_complete - finalise device +// configuration +//------------------------------------------------- + +void crt9028_device::device_config_complete() +{ + if (!has_screen()) + return; + + if (screen().refresh_attoseconds() == 0) + { + int visible_scan_lines = m_char_rows * m_scans_per_char; + screen().set_raw(clock(), m_dots_per_char * (m_chars_per_row + m_horiz_blanking), 0, m_dots_per_char * m_chars_per_row, + visible_scan_lines + m_vert_blanking[0], 0, visible_scan_lines); + } + + if (!screen().has_screen_update()) + screen().set_screen_update(screen_update_rgb32_delegate(FUNC(crt9028_device::screen_update), this)); +} + + +//------------------------------------------------- +// memory_space_config - return the configuration +// for the address spaces +//------------------------------------------------- + +device_memory_interface::space_config_vector crt9028_device::memory_space_config() const +{ + return space_config_vector{std::make_pair(0, &m_space_config)}; +} + + +//------------------------------------------------- +// device_resolve_objects - resolve objects that +// may be needed for other devices to set +// initial conditions at start time +//------------------------------------------------- + +void crt9028_device::device_resolve_objects() +{ + m_hsync_callback.resolve_safe(); + m_vsync_callback.resolve_safe(); +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void crt9028_device::device_start() +{ + m_space = &space(0); + + save_item(NAME(m_address_register)); +} + + +//------------------------------------------------- +// screen_update - screen update method +//------------------------------------------------- + +u32 crt9028_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + return 0; +} + + +//------------------------------------------------- +// chip_reset - software reset command +//------------------------------------------------- + +void crt9028_device::chip_reset() +{ + logerror("%s: Chip reset\n", machine().describe_context()); +} + + +//------------------------------------------------- +// status_r - read status register +//------------------------------------------------- + +u8 crt9028_device::status_r() +{ + return 0x80; +} + + +//------------------------------------------------- +// filadd_w - set fill address register +//------------------------------------------------- + +void crt9028_device::filadd_w(u8 data) +{ + logerror("%s: Fill address = %03X\n", machine().describe_context(), data << 4); +} + + +//------------------------------------------------- +// tosadd_w - set top of screen address register +//------------------------------------------------- + +void crt9028_device::tosadd_w(u8 data) +{ + logerror("%s: Top of screen address = %03X\n", machine().describe_context(), data << 4); +} + + +//------------------------------------------------- +// curlo_w - set cursor low register +//------------------------------------------------- + +void crt9028_device::curlo_w(u8 data) +{ + logerror("%s: Cursor low = %02X\n", machine().describe_context(), data); +} + + +//------------------------------------------------- +// curhi_w - set cursor high/scroll register +//------------------------------------------------- + +void crt9028_device::curhi_w(u8 data) +{ + logerror("%s: Cursor high = %02X\n", machine().describe_context(), data); +} + + +//------------------------------------------------- +// attdat_w - set attribute data register +//------------------------------------------------- + +void crt9028_device::attdat_w(u8 data) +{ + logerror("%s: Attribute data = %02X\n", machine().describe_context(), data); +} + + +//------------------------------------------------- +// mode_w - set mode register +//------------------------------------------------- + +void crt9028_device::mode_w(u8 data) +{ + logerror("%s: Auto increment %sabled\n", machine().describe_context(), BIT(data, 7) ? "en" : "dis"); +} + + +//------------------------------------------------- +// character_r - read character from memory +//------------------------------------------------- + +u8 crt9028_device::character_r() +{ + return 0; +} + + +//------------------------------------------------- +// character_w - write character to memory +//------------------------------------------------- + +void crt9028_device::character_w(u8 data) +{ + logerror("%s: Character = %02X\n", machine().describe_context(), data); +} + + +//------------------------------------------------- +// read - read from data or status register +//------------------------------------------------- + +u8 crt9028_device::read(offs_t offset) +{ + if (BIT(offset, 0)) + return status_r(); + else if (m_address_register == 0xe) + return character_r(); + else + { + if (!machine().side_effects_disabled()) + logerror("Read from unknown or write-only register %X\n", m_address_register); + return 0; + } +} + + +//------------------------------------------------- +// write - write to data or address register +//------------------------------------------------- + +void crt9028_device::write(offs_t offset, u8 data) +{ + if (BIT(offset, 0)) + m_address_register = data & 0x0f; + else switch (m_address_register) + { + case 0x6: + chip_reset(); + break; + + case 0x8: + tosadd_w(data); + break; + + case 0x9: + curlo_w(data); + break; + + case 0xa: + curhi_w(data); + break; + + case 0xb: + filadd_w(data); + break; + + case 0xc: + attdat_w(data); + break; + + case 0xd: + character_w(data); + break; + + case 0xe: + mode_w(data); + break; + + default: + logerror("%s: Unknown register %X = %02X\n", machine().describe_context(), m_address_register, data); + break; + } +} + + +//************************************************************************** +// INTERNAL ROM +//************************************************************************** + +ROM_START(crt9028_000) + ROM_REGION(0x400, "charset", 0) + ROM_LOAD("crt9028_000.bin", 0x000, 0x400, NO_DUMP) +ROM_END + + +//------------------------------------------------- +// rom_region - return a pointer to the implicit +// rom region description for this device +//------------------------------------------------- + +const tiny_rom_entry *crt9028_000_device::device_rom_region() const +{ + return ROM_NAME(crt9028_000); +} diff --git a/src/devices/video/crt9028.h b/src/devices/video/crt9028.h new file mode 100644 index 00000000000..f0696519ed9 --- /dev/null +++ b/src/devices/video/crt9028.h @@ -0,0 +1,142 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + Standard Microsystems CRT9028/9128 Video Terminal Logic Controller + +*********************************************************************** + _____ _____ + DA8 1 |* \__/ | 40 DA7 + DA9 2 | | 39 DA6 + DA10 3 | | 38 DA5 + GND 4 | | 37 DA4 + XTAL2 5 | | 36 DA3 + XTAL1 6 | | 35 DA2 + /VIDEO 7 | | 34 DA1 + INTOUT 8 | | 33 DA0 + /DWR 9 | | 32 DB7 + DD0 10 | CRT 9028 | 31 DB6 + DD1 11 | CRT 9128 | 30 DB5 + DD2 12 | | 29 DB4 + DD3 13 | | 28 DB3 + DD4 14 | | 27 DB2 + DD5 15 | | 26 DB1 + DD6 16 | | 25 DB0 + DD7 17 | | 24 A/D + HSYNC 18 | | 23 /RD or /DS + VSYNC 19 | | 22 /WR or R/W + CSYNC 20 |______________| 21 VCC + +**********************************************************************/ + +#ifndef MAME_VIDEO_CRT9028_H +#define MAME_VIDEO_CRT9028_H + +#pragma once + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> crt9028_device + +class crt9028_device : public device_t, public device_memory_interface, public device_video_interface +{ +public: + // device configuration + auto hsync_callback() { return m_hsync_callback.bind(); } + auto vsync_callback() { return m_hsync_callback.bind(); } + + // read/write handlers + u8 read(offs_t offset); + void write(offs_t offset, u8 data); + + // screen update method + u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + +protected: + // base type constructor + crt9028_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, + int dots_per_char, int chars_per_row, int horiz_blanking, int hsync_delay, int hsync_width, bool hsync_active, + int char_rows, int scans_per_char, bool vsync_active, + int vert_blanking, int vsync_delay, bool vsync_width, + int alt_vert_blanking, int alt_vsync_delay, bool alt_vsync_width, + int csync_delay, int csync_width, int underline, + u16 wide_gfx_seg1_4, u16 wide_gfx_seg2_5, u16 wide_gfx_seg3_6, u8 wide_gfx_pattern, + u16 thin_gfx_seg1, u16 thin_gfx_seg2, u16 thin_gfx_seg3, u16 thin_gfx_seg4, + u8 thin_gfx_dots1, u8 thin_gfx_dots2, u8 thin_gfx_dots3, u8 thin_gfx_dots4); + + // device-specific overrides + virtual void device_config_complete() override; + virtual void device_resolve_objects() override; + virtual void device_start() override; + + // device_memory_interface overrides + virtual space_config_vector memory_space_config() const override; + +private: + // register helpers + void chip_reset(); + u8 status_r(); + void filadd_w(u8 data); + void tosadd_w(u8 data); + void curlo_w(u8 data); + void curhi_w(u8 data); + void attdat_w(u8 data); + void mode_w(u8 data); + u8 character_r(); + void character_w(u8 data); + + // address space for display memory + const address_space_config m_space_config; + address_space *m_space; + + // internal character set + required_region_ptr<u8> m_charset; + + // timing callbacks + devcb_write_line m_hsync_callback; + devcb_write_line m_vsync_callback; + + // mask parameters + const int m_dots_per_char; + const int m_chars_per_row; + const int m_horiz_blanking; + const int m_hsync_delay; + const int m_hsync_width; + const bool m_hsync_active; + const int m_char_rows; + const int m_scans_per_char; + const bool m_vsync_active; + const int m_vert_blanking[2]; + const int m_vsync_delay[2]; + const int m_vsync_width[2]; + const int m_csync_delay; + const int m_csync_width; + const int m_underline; + const u16 m_wide_gfx_seg[3]; + const u8 m_wide_gfx_pattern; + const u16 m_thin_gfx_seg[4]; + const u8 m_thin_gfx_dots[4]; + + // internal state + u8 m_address_register; +}; + +// ======================> crt9028_000_device + +class crt9028_000_device : public crt9028_device +{ +public: + // device constructor + crt9028_000_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // device-specific overrides + virtual const tiny_rom_entry *device_rom_region() const override; +}; + +// device type declarations +DECLARE_DEVICE_TYPE(CRT9028_000, crt9028_000_device) + +#endif // MAME_VIDEO_CRT9028_H diff --git a/src/devices/video/crtc_ega.cpp b/src/devices/video/crtc_ega.cpp index 01ee629ad43..7d03b09f131 100644 --- a/src/devices/video/crtc_ega.cpp +++ b/src/devices/video/crtc_ega.cpp @@ -51,13 +51,13 @@ void crtc_ega_device::device_post_load() } -WRITE8_MEMBER( crtc_ega_device::address_w ) +void crtc_ega_device::address_w(uint8_t data) { m_register_address_latch = data & 0x1f; } -READ8_MEMBER( crtc_ega_device::register_r ) +uint8_t crtc_ega_device::register_r() { uint8_t ret = 0; @@ -78,7 +78,7 @@ READ8_MEMBER( crtc_ega_device::register_r ) } -WRITE8_MEMBER( crtc_ega_device::register_w ) +void crtc_ega_device::register_w(uint8_t data) { LOG("%s CRTC_EGA: reg 0x%02x = 0x%02x\n", machine().describe_context(), m_register_address_latch, data); diff --git a/src/devices/video/crtc_ega.h b/src/devices/video/crtc_ega.h index e995cdf8a30..9d03177b494 100644 --- a/src/devices/video/crtc_ega.h +++ b/src/devices/video/crtc_ega.h @@ -17,34 +17,6 @@ #define CRTC_EGA_END_UPDATE(_name) void _name(bitmap_ind16 &bitmap, const rectangle &cliprect) - -#define MCFG_CRTC_EGA_SET_SCREEN MCFG_VIDEO_SET_SCREEN - -#define MCFG_CRTC_EGA_BEGIN_UPDATE_CB(_class, _method) \ - downcast<crtc_ega_device &>(*device).set_begin_update_callback(crtc_ega_device::begin_update_delegate(&_class::_method, #_class "::" #_method, this)); - -#define MCFG_CRTC_EGA_ROW_UPDATE_CB(_class, _method) \ - downcast<crtc_ega_device &>(*device).set_row_update_callback(crtc_ega_device::row_update_delegate(&_class::_method, #_class "::" #_method, this)); - -#define MCFG_CRTC_EGA_END_UPDATE_CB(_class, _method) \ - downcast<crtc_ega_device &>(*device).set_end_update_callback(crtc_ega_device::end_update_delegate(&_class::_method, #_class "::" #_method, this)); - -#define MCFG_CRTC_EGA_HPIXELS_PER_COLUMN(_pix) \ - downcast<crtc_ega_device &>(*device).config_set_hpixels_per_column(_pix); - -#define MCFG_CRTC_EGA_RES_OUT_DE_CB(_devcb) \ - downcast<crtc_ega_device &>(*device).set_res_out_de_callback(DEVCB_##_devcb); - -#define MCFG_CRTC_EGA_RES_OUT_HSYNC_CB(_devcb) \ - downcast<crtc_ega_device &>(*device).set_res_out_hsync_callback(DEVCB_##_devcb); - -#define MCFG_CRTC_EGA_RES_OUT_VSYNC_CB(_devcb) \ - downcast<crtc_ega_device &>(*device).set_res_out_vsync_callback(DEVCB_##_devcb); - -#define MCFG_CRTC_EGA_RES_OUT_VBLANK_CB(_devcb) \ - downcast<crtc_ega_device &>(*device).set_res_out_vblank_callback(DEVCB_##_devcb); - - class crtc_ega_device : public device_t, public device_video_interface { @@ -57,24 +29,24 @@ public: crtc_ega_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template <class Object> devcb_base &set_res_out_de_callback(Object &&cb) { return m_res_out_de_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_res_out_hsync_callback(Object &&cb) { return m_res_out_hsync_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_res_out_vsync_callback(Object &&cb) { return m_res_out_vsync_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_res_out_vblank_callback(Object &&cb) { return m_res_out_vblank_cb.set_callback(std::forward<Object>(cb)); } + auto res_out_de_callback() { return m_res_out_de_cb.bind(); } + auto res_out_hsync_callback() { return m_res_out_hsync_cb.bind(); } + auto res_out_vsync_callback() { return m_res_out_vsync_cb.bind(); } + auto res_out_vblank_callback() { return m_res_out_vblank_cb.bind(); } - template <typename Object> void set_begin_update_callback(Object &&cb) { m_begin_update_cb = std::forward<Object>(cb); } - template <typename Object> void set_row_update_callback(Object &&cb) { m_row_update_cb = std::forward<Object>(cb); } - template <typename Object> void set_end_update_callback(Object &&cb) { m_end_update_cb = std::forward<Object>(cb); } + template <typename... T> void set_begin_update_callback(T &&... args) { m_begin_update_cb = begin_update_delegate(std::forward<T>(args)...); } + template <typename... T> void set_row_update_callback(T &&... args) { m_row_update_cb = row_update_delegate(std::forward<T>(args)...); } + template <typename... T> void set_end_update_callback(T &&... args) { m_end_update_cb = end_update_delegate(std::forward<T>(args)...); } void config_set_hpixels_per_column(int hpixels_per_column) { m_hpixels_per_column = hpixels_per_column; } /* select one of the registers for reading or writing */ - DECLARE_WRITE8_MEMBER( address_w ); + void address_w(uint8_t data); /* read from the currently selected register */ - DECLARE_READ8_MEMBER( register_r ); + uint8_t register_r(); /* write to the currently selected register */ - DECLARE_WRITE8_MEMBER( register_w ); + void register_w(uint8_t data); /* return the current value on the MA0-MA15 pins */ uint16_t get_ma(); diff --git a/src/devices/video/decsfb.cpp b/src/devices/video/decsfb.cpp new file mode 100644 index 00000000000..166cc98f62b --- /dev/null +++ b/src/devices/video/decsfb.cpp @@ -0,0 +1,175 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont + +/* + * An emulation of the Digital Equipment Corporation SFB "Smart Frame Buffer" chip + * + * Used in: + * + * Accelerated TURBOChannel video cards for DECstations and AlphaStations + * On-board on some DECstations + * On-board on many AlphaStations + * + * Sources: + * + * http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-93-1.pdf + * + */ + +#include "emu.h" +#include "decsfb.h" + +#define MODE_SIMPLE 0 +#define MODE_OPAQUESTIPPLE 1 +#define MODE_OPAQUELINE 2 +#define MODE_TRANSPARENTSTIPPLE 5 +#define MODE_TRANSPARENTLINE 6 +#define MODE_COPY 7 + +#define LOG_GENERAL (1U << 0) +#define LOG_REG (1U << 1) +#define LOG_IRQ (1U << 2) + +//#define VERBOSE (LOG_GENERAL|LOG_REG||LOG_IRQ) + +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(DECSFB, decsfb_device, "decsfb", "Digital Equipment Corporation Smart Frame Buffer") + +decsfb_device::decsfb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, DECSFB, tag, owner, clock), + m_int_cb(*this) +{ +} + +void decsfb_device::device_start() +{ + m_int_cb.resolve_safe(); + + save_item(NAME(m_vram)); + save_item(NAME(m_regs)); + save_item(NAME(m_copy_src)); +} + +void decsfb_device::device_reset() +{ + m_copy_src = 1; +} + +/* + 0x100000 copy register 0 + 0x100004 copy register 1 + 0x100008 copy register 2 + 0x10000C copy register 3 + 0x100010 copy register 4 + 0x100014 copy register 5 + 0x100018 copy register 6 + 0x10001C copy register 7 + 0x100020 foreground register + 0x100024 background register + 0x100028 plane mask + 0x10002C pixel mask + 0x100030 cxt mode + 0x100034 boolean operation + 0x100038 pixel shift + 0x10003C line address + 0x100040 bresh 1 + 0x100044 bresh 2 + 0x100048 bresh 3 + 0x10004C bresh continue + 0x100050 deep register + 0x100054 start register + 0x100058 Clear Interrupt + 0x10005C reserved 2 + 0x100060 refresh count + 0x100064 video horiz + 0x100068 video vertical + 0x10006C refresh base + 0x100070 video valid + 0x100074 Interrupt Enable +*/ + +READ32_MEMBER(decsfb_device::read) +{ + return m_regs[offset]; +} + +WRITE32_MEMBER(decsfb_device::write) +{ + COMBINE_DATA(&m_regs[offset]); + + if ((offset == (0x30/4)) && (data = 7)) + { + m_copy_src = 1; + } +} + +READ32_MEMBER(decsfb_device::vram_r) +{ + return m_vram[offset]; +} + +WRITE32_MEMBER(decsfb_device::vram_w) +{ + switch (m_regs[0x30/4]) + { + case MODE_SIMPLE: // simple + COMBINE_DATA(&m_vram[offset]); + break; + + case MODE_TRANSPARENTSTIPPLE: + { + uint8_t *pVRAM = (uint8_t *)&m_vram[offset]; + uint8_t fgs[4]; + + fgs[0] = m_regs[0x20/4] >> 24; + fgs[1] = (m_regs[0x20/4] >> 16) & 0xff; + fgs[2] = (m_regs[0x20/4] >> 8) & 0xff; + fgs[3] = m_regs[0x20/4] & 0xff; + for (int x = 0; x < 32; x++) + { + if (data & (1<<(31-x))) + { + pVRAM[x] = fgs[x & 3]; + } + } + } + break; + + case MODE_COPY: + { + uint8_t *pVRAM = (uint8_t *)&m_vram[offset]; + uint8_t *pBuffer = (uint8_t *)&m_regs[0]; // first 8 32-bit regs are the copy buffer + + if (m_copy_src) + { + m_copy_src = 0; + + for (int x = 0; x < 32; x++) + { + if (data & (1<<(31-x))) + { + pBuffer[x] = pVRAM[x]; + } + } + } + else + { + m_copy_src = 1; + + for (int x = 0; x < 32; x++) + { + if (data & (1<<(31-x))) + { + pVRAM[x] = pBuffer[x]; + } + } + } + } + break; + + default: + logerror("SFB: Unsupported VRAM write %08x (mask %08x) at %08x in mode %x\n", data, mem_mask, offset<<2, m_regs[0x30/4]); + break; + } +} diff --git a/src/devices/video/decsfb.h b/src/devices/video/decsfb.h new file mode 100644 index 00000000000..52e6687ea40 --- /dev/null +++ b/src/devices/video/decsfb.h @@ -0,0 +1,38 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont + +#ifndef MAME_VIDEO_DECSFB_H +#define MAME_VIDEO_DECSFB_H + +#pragma once + +class decsfb_device : public device_t +{ +public: + decsfb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + auto int_cb() { return m_int_cb.bind(); } + + DECLARE_READ32_MEMBER( read ); + DECLARE_WRITE32_MEMBER( write ); + DECLARE_READ32_MEMBER( vram_r ); + DECLARE_WRITE32_MEMBER( vram_w ); + + u32 *get_vram() { return m_vram; } + +protected: + // standard device_interface overrides + virtual void device_start() override; + virtual void device_reset() override; + + devcb_write_line m_int_cb; + +private: + u32 m_vram[0x200000/4]; + u32 m_regs[0x80]; + int m_copy_src; +}; + +DECLARE_DEVICE_TYPE(DECSFB, decsfb_device) + +#endif // MAME_VIDEO_DECSFB_H diff --git a/src/devices/video/dl1416.h b/src/devices/video/dl1416.h index 2f98355b95d..446e37201dd 100644 --- a/src/devices/video/dl1416.h +++ b/src/devices/video/dl1416.h @@ -27,24 +27,12 @@ DECLARE_DEVICE_TYPE(DL1416T, dl1416_device) /*************************************************************************** - DEVICE CONFIGURATION MACROS -***************************************************************************/ - -#define MCFG_DL1414_UPDATE_HANDLER(_devcb) \ - downcast<dl1414_device &>(*device).set_update_handler(DEVCB_##_devcb); - -#define MCFG_DL1416_UPDATE_HANDLER(_devcb) \ - downcast<dl1414_device &>(*device).set_update_handler(DEVCB_##_devcb); - - -/*************************************************************************** TYPE DECLARATIONS ***************************************************************************/ class dl1414_device : public device_t { public: - template <typename Object> devcb_base &set_update_handler(Object &&cb) { return m_update_cb.set_callback(std::forward<Object>(cb)); } auto update() { return m_update_cb.bind(); } // signal-level interface diff --git a/src/devices/video/dm9368.h b/src/devices/video/dm9368.h index ae9956de30b..fb376541a07 100644 --- a/src/devices/video/dm9368.h +++ b/src/devices/video/dm9368.h @@ -23,19 +23,6 @@ #pragma once - -//************************************************************************** -// INTERFACE CONFIGURATION MACROS -//************************************************************************** - -#define MCFG_DM9368_UPDATE_CALLBACK(cb) \ - downcast<dm9368_device &>(*device).set_update_callback(DEVCB_##cb); - -#define MCFG_DM9368_RBO_CALLBACK(cb) \ - downcast<dm9368_device &>(*device).set_rbo_callback(DEVCB_##cb); - - - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -45,8 +32,6 @@ class dm9368_device : public device_t { public: - template <typename Obj> devcb_base &set_update_callback(Obj &&cb) { return m_update_cb.set_callback(std::forward<Obj>(cb)); } - template <typename Obj> devcb_base &set_rbo_callback(Obj &&cb) { return m_rbo_cb.set_callback(std::forward<Obj>(cb)); } auto update_cb() { return m_update_cb.bind(); } auto rbo_cb() { return m_rbo_cb.bind(); } diff --git a/src/devices/video/ef9340_1.h b/src/devices/video/ef9340_1.h index 88b1d91a163..4d687d227d6 100644 --- a/src/devices/video/ef9340_1.h +++ b/src/devices/video/ef9340_1.h @@ -15,16 +15,18 @@ #pragma once - -#define MCFG_EF9340_1_ADD(_tag, _clock, _screen_tag) \ - MCFG_DEVICE_ADD(_tag, EF9340_1, _clock) \ - MCFG_VIDEO_SET_SCREEN(_screen_tag) - class ef9340_1_device : public device_t, public device_video_interface { public: // construction/destruction + template <typename T> + ef9340_1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&screen_tag) + : ef9340_1_device(mconfig, tag, owner, clock) + { + set_screen(std::forward<T>(screen_tag)); + } + ef9340_1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); inline bitmap_ind16 *get_bitmap() { return &m_tmp_bitmap; } diff --git a/src/devices/video/ef9345.cpp b/src/devices/video/ef9345.cpp index 006d92855ba..1daf7b5fde7 100644 --- a/src/devices/video/ef9345.cpp +++ b/src/devices/video/ef9345.cpp @@ -35,7 +35,8 @@ DEFINE_DEVICE_TYPE(TS9347, ts9347_device, "ts9347", "TS9347") // default address map void ef9345_device::ef9345(address_map &map) { - map(0x0000, 0x3fff).ram(); + if (!has_configured_map(0)) + map(0x0000, 0x3fff).ram(); } //------------------------------------------------- @@ -113,7 +114,7 @@ ef9345_device::ef9345_device(const machine_config &mconfig, device_type type, co device_t(mconfig, type, tag, owner, clock), device_memory_interface(mconfig, *this), device_video_interface(mconfig, *this), - m_space_config("videoram", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(), address_map_constructor(FUNC(ef9345_device::ef9345), this)), + m_space_config("videoram", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(FUNC(ef9345_device::ef9345), this)), m_charset(*this, DEVICE_SELF), m_variant(variant), m_palette(*this, finder_base::DUMMY_TAG) @@ -212,7 +213,7 @@ void ef9345_device::device_timer(emu_timer &timer, device_timer_id id, int param void ef9345_device::set_busy_flag(int period) { m_bf = 1; - m_busy_timer->adjust(attotime::from_usec(period)); + m_busy_timer->adjust(attotime::from_nsec(period)); } // draw a char in 40 char line mode @@ -753,7 +754,7 @@ void ef9345_device::ef9345_exec(uint8_t cmd) { case 0x00: //KRF: R1,R2,R3->ram case 0x01: //KRF: R1,R2,R3->ram + increment - set_busy_flag(4); + set_busy_flag(4000); m_videoram->write_byte(a, m_registers[1]); m_videoram->write_byte(a + 0x0800, m_registers[2]); m_videoram->write_byte(a + 0x1000, m_registers[3]); @@ -761,14 +762,14 @@ void ef9345_device::ef9345_exec(uint8_t cmd) break; case 0x02: //KRG: R1,R2->ram case 0x03: //KRG: R1,R2->ram + increment - set_busy_flag(5.5); + set_busy_flag(5500); m_videoram->write_byte(a, m_registers[1]); m_videoram->write_byte(a + 0x0800, m_registers[2]); if (cmd&1) inc_x(7); break; case 0x08: //KRF: ram->R1,R2,R3 case 0x09: //KRF: ram->R1,R2,R3 + increment - set_busy_flag(7.5); + set_busy_flag(7500); m_registers[1] = m_videoram->read_byte(a); m_registers[2] = m_videoram->read_byte(a + 0x0800); m_registers[3] = m_videoram->read_byte(a + 0x1000); @@ -776,14 +777,14 @@ void ef9345_device::ef9345_exec(uint8_t cmd) break; case 0x0a: //KRG: ram->R1,R2 case 0x0b: //KRG: ram->R1,R2 + increment - set_busy_flag(7.5); + set_busy_flag(7500); m_registers[1] = m_videoram->read_byte(a); m_registers[2] = m_videoram->read_byte(a + 0x0800); if (cmd&1) inc_x(7); break; case 0x30: //OCT: R1->RAM, main pointer case 0x31: //OCT: R1->RAM, main pointer + inc - set_busy_flag(4); + set_busy_flag(4000); m_videoram->write_byte(indexram(7), m_registers[1]); if (cmd&1) @@ -795,7 +796,7 @@ void ef9345_device::ef9345_exec(uint8_t cmd) break; case 0x34: //OCT: R1->RAM, aux pointer case 0x35: //OCT: R1->RAM, aux pointer + inc - set_busy_flag(4); + set_busy_flag(4000); m_videoram->write_byte(indexram(5), m_registers[1]); if (cmd&1) @@ -803,7 +804,7 @@ void ef9345_device::ef9345_exec(uint8_t cmd) break; case 0x38: //OCT: RAM->R1, main pointer case 0x39: //OCT: RAM->R1, main pointer + inc - set_busy_flag(4.5); + set_busy_flag(4500); m_registers[1] = m_videoram->read_byte(indexram(7)); if (cmd&1) @@ -816,7 +817,7 @@ void ef9345_device::ef9345_exec(uint8_t cmd) break; case 0x3c: //OCT: RAM->R1, aux pointer case 0x3d: //OCT: RAM->R1, aux pointer + inc - set_busy_flag(4.5); + set_busy_flag(4500); m_registers[1] = m_videoram->read_byte(indexram(5)); if (cmd&1) @@ -824,7 +825,7 @@ void ef9345_device::ef9345_exec(uint8_t cmd) break; case 0x50: //KRL: 80 uint8_t - 12 bits write case 0x51: //KRL: 80 uint8_t - 12 bits write + inc - set_busy_flag(12.5); + set_busy_flag(12500); m_videoram->write_byte(a, m_registers[1]); switch((a / 0x0800) & 1) { @@ -850,7 +851,7 @@ void ef9345_device::ef9345_exec(uint8_t cmd) break; case 0x58: //KRL: 80 uint8_t - 12 bits read case 0x59: //KRL: 80 uint8_t - 12 bits read + inc - set_busy_flag(11.5); + set_busy_flag(11500); m_registers[1] = m_videoram->read_byte(a); switch((a / 0x0800) & 1) { @@ -879,7 +880,7 @@ void ef9345_device::ef9345_exec(uint8_t cmd) case 0x83: //IND: R1->PAT case 0x84: //IND: R1->DOR case 0x87: //IND: R1->ROR - set_busy_flag(2); + set_busy_flag(2000); switch(cmd&7) { case 1: m_tgs = m_registers[1]; break; @@ -897,7 +898,7 @@ void ef9345_device::ef9345_exec(uint8_t cmd) case 0x8b: //IND: PAT->R1 case 0x8c: //IND: DOR->R1 case 0x8f: //IND: ROR->R1 - set_busy_flag(3.5); + set_busy_flag(3500); switch(cmd&7) { case 0: m_registers[1] = m_charset[indexrom(7) & 0x1fff]; break; @@ -915,7 +916,7 @@ void ef9345_device::ef9345_exec(uint8_t cmd) case 0x99: //VSM: vertical sync mask set break; case 0xb0: //INY: increment Y - set_busy_flag(2); + set_busy_flag(2000); inc_y(6); m_state &= 0x8f; //reset S4(LXa), S5(LXm), S6(Al) break; @@ -936,7 +937,7 @@ void ef9345_device::ef9345_exec(uint8_t cmd) uint8_t n = (cmd>>4) - 0x0c; uint8_t r1 = (cmd&0x04) ? 7 : 5; uint8_t r2 = (cmd&0x04) ? 5 : 7; - int busy = 2; + int busy = 2000; for(i = 0; i < 1280; i++) { @@ -959,7 +960,7 @@ void ef9345_device::ef9345_exec(uint8_t cmd) inc_y(6); } - busy += 4 * n; + busy += 4000 * n; } m_state &= 0x8f; //reset S4(LXa), S5(LXm), S6(Al) set_busy_flag(busy); @@ -994,7 +995,7 @@ void ef9345_device::update_scanline(uint16_t scanline) if (scanline == 250) m_state &= 0xfb; - set_busy_flag(104); + set_busy_flag(104000); if (m_char_mode == MODE12x80 || m_char_mode == MODE8x80) { @@ -1047,7 +1048,7 @@ void ef9345_device::update_scanline(uint16_t scanline) } } -READ8_MEMBER( ef9345_device::data_r ) +uint8_t ef9345_device::data_r(offs_t offset) { if (offset & 7) return m_registers[offset & 7]; @@ -1060,7 +1061,7 @@ READ8_MEMBER( ef9345_device::data_r ) return m_state; } -WRITE8_MEMBER( ef9345_device::data_w ) +void ef9345_device::data_w(offs_t offset, uint8_t data) { m_registers[offset & 7] = data; diff --git a/src/devices/video/ef9345.h b/src/devices/video/ef9345.h index dfec7d080f2..d36811e8a60 100644 --- a/src/devices/video/ef9345.h +++ b/src/devices/video/ef9345.h @@ -15,8 +15,6 @@ #include "emupal.h" -#define MCFG_EF9345_PALETTE(_palette_tag) \ - downcast<ef9345_device &>(*device).set_palette_tag(_palette_tag); //************************************************************************** // TYPE DEFINITIONS @@ -36,8 +34,8 @@ public: template <typename T> void set_palette_tag(T &&tag) { m_palette.set_tag(std::forward<T>(tag)); } // device interface - DECLARE_READ8_MEMBER( data_r ); - DECLARE_WRITE8_MEMBER( data_w ); + uint8_t data_r(offs_t offset); + void data_w(offs_t offset, uint8_t data); void update_scanline(uint16_t scanline); uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); diff --git a/src/devices/video/ef9364.cpp b/src/devices/video/ef9364.cpp index ec324ff0e52..858b7309ca6 100644 --- a/src/devices/video/ef9364.cpp +++ b/src/devices/video/ef9364.cpp @@ -35,7 +35,8 @@ DEFINE_DEVICE_TYPE(EF9364, ef9364_device, "ef9364", "Thomson EF9364") //------------------------------------------------- void ef9364_device::ef9364(address_map &map) { - map(0x00000, ef9364_device::TXTPLANE_MAX_SIZE * ef9364_device::MAX_TXTPLANES - 1).ram(); + if (!has_configured_map(0)) + map(0x00000, ef9364_device::TXTPLANE_MAX_SIZE * ef9364_device::MAX_TXTPLANES - 1).ram(); } //------------------------------------------------- @@ -66,7 +67,7 @@ ef9364_device::ef9364_device(const machine_config &mconfig, const char *tag, dev device_t(mconfig, EF9364, tag, owner, clock), device_memory_interface(mconfig, *this), device_video_interface(mconfig, *this), - m_space_config("textram", ENDIANNESS_LITTLE, 8, 12, 0, address_map_constructor(), address_map_constructor(FUNC(ef9364_device::ef9364), this)), + m_space_config("textram", ENDIANNESS_LITTLE, 8, 12, 0, address_map_constructor(FUNC(ef9364_device::ef9364), this)), m_charset(*this, DEVICE_SELF), m_palette(*this, finder_base::DUMMY_TAG) { diff --git a/src/devices/video/ef9364.h b/src/devices/video/ef9364.h index 1082173733c..290ab8464df 100644 --- a/src/devices/video/ef9364.h +++ b/src/devices/video/ef9364.h @@ -15,14 +15,6 @@ #include "emupal.h" -#define MCFG_EF9364_PALETTE(_palette_tag) \ - downcast<ef9364_device &>(*device).set_palette_tag(_palette_tag); - -#define MCFG_EF9364_PAGES_CNT(_pages_number) \ - downcast<ef9364_device &>(*device).set_nb_of_pages(_pages_number); - -#define MCFG_EF9364_IRQ_HANDLER(_devcb) \ - downcast<ef9364_device &>(*device).set_irq_handler(DEVCB_##_devcb); //************************************************************************** // TYPE DEFINITIONS diff --git a/src/devices/video/ef9365.cpp b/src/devices/video/ef9365.cpp index 5023348c99e..5abc7d2dde8 100644 --- a/src/devices/video/ef9365.cpp +++ b/src/devices/video/ef9365.cpp @@ -168,7 +168,8 @@ const tiny_rom_entry *ef9365_device::device_rom_region() const //------------------------------------------------- void ef9365_device::ef9365(address_map &map) { - map(0x00000, ef9365_device::BITPLANE_MAX_SIZE * ef9365_device::MAX_BITPLANES - 1).ram(); + if (!has_configured_map(0)) + map(0x00000, ef9365_device::BITPLANE_MAX_SIZE * ef9365_device::MAX_BITPLANES - 1).ram(); } //------------------------------------------------- @@ -200,7 +201,7 @@ ef9365_device::ef9365_device(const machine_config &mconfig, const char *tag, dev device_t(mconfig, EF9365, tag, owner, clock), device_memory_interface(mconfig, *this), device_video_interface(mconfig, *this), - m_space_config("videoram", ENDIANNESS_LITTLE, 8, 18, 0, address_map_constructor(), address_map_constructor(FUNC(ef9365_device::ef9365), this)), + m_space_config("videoram", ENDIANNESS_LITTLE, 8, 18, 0, address_map_constructor(FUNC(ef9365_device::ef9365), this)), m_charset(*this, "ef9365"), m_palette(*this, finder_base::DUMMY_TAG), m_irq_handler(*this) @@ -1224,7 +1225,7 @@ void ef9365_device::update_scanline(uint16_t scanline) // data_r: Registers read access callback //------------------------------------------------- -READ8_MEMBER( ef9365_device::data_r ) +uint8_t ef9365_device::data_r(offs_t offset) { unsigned char return_value; @@ -1315,7 +1316,7 @@ READ8_MEMBER( ef9365_device::data_r ) // data_w: Registers write access callback //------------------------------------------------- -WRITE8_MEMBER( ef9365_device::data_w ) +void ef9365_device::data_w(offs_t offset, uint8_t data) { LOG("EF9365 [ %s ] <WR [ 0x%.2X ] - %s\n", register_names[offset&0xF],data, machine().describe_context() ); diff --git a/src/devices/video/ef9365.h b/src/devices/video/ef9365.h index 762989e6a03..be22ae6339b 100644 --- a/src/devices/video/ef9365.h +++ b/src/devices/video/ef9365.h @@ -15,17 +15,6 @@ #include "emupal.h" -#define MCFG_EF936X_PALETTE(palette_tag) \ - downcast<ef9365_device &>(*device).set_palette_tag(palette_tag); - -#define MCFG_EF936X_BITPLANES_CNT(bitplanes_number) \ - downcast<ef9365_device &>(*device).set_nb_bitplanes((bitplanes_number)); - -#define MCFG_EF936X_DISPLAYMODE(display_mode) \ - downcast<ef9365_device &>(*device).set_display_mode((ef9365_device::display_mode)); - -#define MCFG_EF936X_IRQ_HANDLER(cb) \ - downcast<ef9365_device &>(*device).set_irq_handler((DEVCB_##cb)); //************************************************************************** // TYPE DEFINITIONS @@ -54,11 +43,11 @@ public: template <typename T> void set_palette_tag(T &&tag) { m_palette.set_tag(std::forward<T>(tag)); } void set_nb_bitplanes(int nb_bitplanes ); void set_display_mode(int display_mode ); - template<class Object> devcb_base &set_irq_handler(Object object) { return m_irq_handler.set_callback(std::forward<Object>(object)); } + auto irq_handler() { return m_irq_handler.bind(); } // device interface - DECLARE_READ8_MEMBER( data_r ); - DECLARE_WRITE8_MEMBER( data_w ); + uint8_t data_r(offs_t offset); + void data_w(offs_t offset, uint8_t data); void update_scanline(uint16_t scanline); void set_color_filler( uint8_t color ); diff --git a/src/devices/video/epic12.h b/src/devices/video/epic12.h index a8fe41b069f..287dc08ebb3 100644 --- a/src/devices/video/epic12.h +++ b/src/devices/video/epic12.h @@ -6,12 +6,6 @@ #pragma once -#define MCFG_EPIC12_ADD(_tag) \ - MCFG_DEVICE_ADD(_tag, EPIC12, 0) - -#define MCFG_EPIC12_SET_MAINRAMSIZE( _rgn ) \ - downcast<epic12_device &>(*device).set_mainramsize(_rgn); - class epic12_device : public device_t, public device_video_interface { diff --git a/src/devices/video/fixfreq.cpp b/src/devices/video/fixfreq.cpp index a64c6d812b3..58eec1722e3 100644 --- a/src/devices/video/fixfreq.cpp +++ b/src/devices/video/fixfreq.cpp @@ -19,194 +19,216 @@ //#define VERBOSE 1 #include "logmacro.h" - /*************************************************************************** Fixed frequency monitor ***************************************************************************/ + + + // device type definition DEFINE_DEVICE_TYPE(FIXFREQ, fixedfreq_device, "fixfreq", "Fixed-Frequency Monochrome Monitor") -fixedfreq_device::fixedfreq_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, type, tag, owner, clock), - device_video_interface(mconfig, *this, false), - m_htotal(0), m_vtotal(0), m_vid(0), m_last_x(0), m_last_y(0), m_cur_bm(0), - // default to NTSC "704x480@30i" - m_monitor_clock(13500000), - m_hvisible(704), - m_hfrontporch(728), - m_hsync(791), - m_hbackporch(858), - m_vvisible(480), - m_vfrontporch(486), - m_vsync(492), - m_vbackporch(525), - m_fieldcount(2), - m_sync_threshold(0.3), - m_gain(1.0 / 3.7), - m_vint(0), m_int_trig(0), m_mult(0), m_sig_vsync(0), m_sig_composite(0), m_sig_field(0) +void fixedfreq_monitor_state::update_sync_channel(const time_type &time, const double newval) { -} + const time_type delta_time = time - m_last_sync_time; -fixedfreq_device::fixedfreq_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : fixedfreq_device(mconfig, FIXFREQ, tag, owner, clock) -{ + const int last_vsync = m_sig_vsync; + const int last_comp = m_sig_composite; + + m_vsync_filter += ((double) last_comp - m_vsync_filter) * (1.0 - exp(-delta_time * m_vsync_filter_timeconst)); + m_sig_composite = (newval < m_desc.m_sync_threshold) ? 1 : 0 ; + + m_sig_vsync = (m_vsync_filter > m_vsync_threshold) ? 1 : 0; + + if (!last_vsync && m_sig_vsync) + { + //LOG("VSYNC %d %d\n", m_last_x, m_last_y + m_sig_field); + m_last_y = m_desc.m_vbackporch - m_desc.m_vsync; + m_intf.vsync_start_cb(time - m_last_vsync_time); + m_last_vsync_time = time; + } + else if (last_vsync && !m_sig_vsync) + { + m_sig_field = last_comp; /* force false-progressive */ + m_sig_field = (m_sig_field ^ 1) ^ last_comp; /* if there is no field switch, auto switch */ + //LOG("Field: %d\n", m_sig_field); + } + + if (!last_comp && m_sig_composite) + { + /* TODO - time since last hsync and field detection */ + //LOG("HSYNC up %d\n", m_last_x); + // FIXME: pixels > 50 filters some spurious hysnc on line 27 in breakout + if (!m_sig_vsync && (m_last_x > m_desc.m_hscale * 100)) + { + m_last_y += m_desc.m_fieldcount; + m_last_x = 0; + m_line_time = time; + } + //if (m_last_y == 27) printf("HSYNC up %d %d\n", m_last_y, pixels); + } + else if (last_comp && !m_sig_composite) + { + /* falling composite */ + //LOG("HSYNC down %f %d %f\n", time * 1e6, m_last_x, m_sync_signal); + } + + m_sync_signal = newval; + m_last_sync_time = time; } -void fixedfreq_device::device_start() +void fixedfreq_monitor_state::update_bm(const time_type &time) { - m_htotal = 0; - m_vtotal = 0; - - m_vid = 0.0; - m_last_x = 0; - m_last_y = 0; - m_last_time = attotime::zero; - m_line_time = attotime::zero; - m_last_hsync_time = attotime::zero; - m_last_vsync_time = attotime::zero; - m_refresh = attotime::zero; - m_clock_period = attotime::zero; - //bitmap_rgb32 *m_bitmap[2]; - m_cur_bm = 0; + const int pixels = round((time - m_line_time) * m_desc.m_hscale / m_clock_period); + const int has_fields = (m_desc.m_fieldcount > 1) ? 1: 0; - /* sync separator */ - m_vint = 0.0; - m_int_trig = 0.0; - m_mult = 0.0; - - m_sig_vsync = 0; - m_sig_composite = 0; - m_sig_field = 0; - - m_bitmap[0] = nullptr; - m_bitmap[1] = nullptr; - //m_vblank_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(vga_device::vblank_timer_cb),this)); - recompute_parameters(false); - - save_item(NAME(m_vid)); - save_item(NAME(m_last_x)); - save_item(NAME(m_last_y)); - save_item(NAME(m_last_time)); - save_item(NAME(m_line_time)); - save_item(NAME(m_last_hsync_time)); - save_item(NAME(m_last_vsync_time)); - save_item(NAME(m_refresh)); - save_item(NAME(m_clock_period)); - //save_item(NAME(m_bitmap[0])); - //save_item(NAME(m_bitmap[1])); - save_item(NAME(m_cur_bm)); + uint32_t col(0xffff0000); // Mark sync areas - /* sync separator */ - save_item(NAME(m_vint)); - save_item(NAME(m_int_trig)); - save_item(NAME(m_mult)); + if (m_sync_signal >= m_desc.m_sync_threshold) + col = m_col; - save_item(NAME(m_sig_vsync)); - save_item(NAME(m_sig_composite)); - save_item(NAME(m_sig_field)); + m_intf.plot_hline(m_last_x, m_last_y + m_sig_field * has_fields, pixels - m_last_x, col); + m_last_x = pixels; +} +void fixedfreq_monitor_state::update_composite_monochrome(const time_type &time, const double data) +{ + update_bm(time); + update_sync_channel(time, data); + + int colv = (int) ((data - m_desc.m_sync_threshold) * m_desc.m_gain * 255.0); + if (colv > 255) + colv = 255; + if (colv < 0) + m_col = 0xffff0000; + else + m_col = 0xff000000 | (colv<<16) | (colv<<8) | colv; +} +void fixedfreq_monitor_state::update_red(const time_type &time, const double data) +{ + update_bm(time); + + int colv = (int) ((data - m_desc.m_sync_threshold) * m_desc.m_gain * 255.0); + if (colv > 255) + colv = 255; + if (colv < 0) + colv = 0; + m_col = (m_col & 0xff00ffff) | (colv<<16); +} +void fixedfreq_monitor_state::update_green(const time_type &time, const double data) +{ + update_bm(time); + //update_sync_channel(ctime, data); + + int colv = (int) ((data - m_desc.m_sync_threshold) * m_desc.m_gain * 255.0); + if (colv > 255) + colv = 255; + if (colv < 0) + colv = 0; + m_col = (m_col & 0xffff00ff) | (colv<<8); } -void fixedfreq_device::device_reset() +void fixedfreq_monitor_state::update_blue(const time_type &time, const double data) { - m_last_time = attotime::zero; - m_line_time = attotime::zero; - m_last_hsync_time = attotime::zero; - m_last_vsync_time = attotime::zero; - m_vint = 0; + update_bm(time); + //update_sync_channel(ctime, data); + + int colv = (int) ((data - m_desc.m_sync_threshold) * m_desc.m_gain * 255.0); + if (colv > 255) + colv = 255; + if (colv < 0) + colv = 0; + m_col = (m_col & 0xffffff00) | colv; } +void fixedfreq_monitor_state::update_sync(const time_type &time, const double data) +{ + update_bm(time); + update_sync_channel(time, data); +} -void fixedfreq_device::device_post_load() +fixedfreq_device::fixedfreq_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock), + device_video_interface(mconfig, *this, false), + m_cur_bm(0), + m_htotal(0), + m_vtotal(0), + m_refresh_period(time_type(0)), + m_monitor(), + m_state(m_monitor, *this) { - //recompute_parameters(true); } -void fixedfreq_device::recompute_parameters(bool postload) +fixedfreq_device::fixedfreq_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : fixedfreq_device(mconfig, FIXFREQ, tag, owner, clock) { - bool needs_realloc = (m_htotal != m_hbackporch) && (m_vtotal != m_vbackporch); +} - if (m_bitmap[0] != nullptr || needs_realloc) - m_bitmap[0] = nullptr; - if (m_bitmap[1] != nullptr || needs_realloc) - m_bitmap[1] = nullptr; +void fixedfreq_device::device_config_complete() +{ + if (!has_screen()) + return; - m_htotal = m_hbackporch; - m_vtotal = m_vbackporch; + if (!screen().refresh_attoseconds()) + screen().set_raw(m_monitor.m_monitor_clock, m_monitor.m_hbackporch, 0, + m_monitor.m_hbackporch, m_monitor.m_vbackporch, 0, + m_monitor.m_vbackporch); - /* sync separator */ + if (!screen().has_screen_update()) + screen().set_screen_update(screen_update_rgb32_delegate(FUNC(fixedfreq_device::screen_update), this)); +} - m_int_trig = (exp(- 3.0/(3.0+3.0))) - exp(-1.0); - m_mult = (double) (m_monitor_clock) / (double) m_htotal * 1.0; // / (3.0 + 3.0); - LOG("trigger %f with len %f\n", m_int_trig, 1e6 / m_mult); +void fixedfreq_device::device_start() +{ - m_bitmap[0] = std::make_unique<bitmap_rgb32>(m_htotal, m_vtotal); - m_bitmap[1] = std::make_unique<bitmap_rgb32>(m_htotal, m_vtotal); + m_refresh_period = time_type(0); + + m_cur_bm = 0; - rectangle visarea( - m_hbackporch - m_hfrontporch, - m_hbackporch - m_hfrontporch + m_hvisible - 1, - m_vbackporch - m_vfrontporch, - m_vbackporch - m_vfrontporch + m_vvisible - 1); + m_htotal = m_monitor.m_hbackporch; + m_vtotal = m_monitor.m_vbackporch; + m_bitmap[0] = std::make_unique<bitmap_rgb32>(m_htotal * m_monitor.m_hscale, m_vtotal); + m_bitmap[1] = std::make_unique<bitmap_rgb32>(m_htotal * m_monitor.m_hscale, m_vtotal); + + m_state.start(); + + // FIXME: will be done by netlist going forward + save_item(NAME(m_state.m_sync_signal)); + save_item(NAME(m_state.m_last_x)); + save_item(NAME(m_state.m_last_y)); + save_item(NAME(m_state.m_last_sync_time)); + save_item(NAME(m_state.m_line_time)); + save_item(NAME(m_state.m_last_hsync_time)); + save_item(NAME(m_state.m_last_vsync_time)); + save_item(NAME(m_refresh_period)); + save_item(NAME(m_state.m_clock_period)); + //save_item(NAME(m_bitmap[0])); + //save_item(NAME(m_bitmap[1])); + save_item(NAME(m_cur_bm)); - m_clock_period = attotime::from_hz(m_monitor_clock); + /* sync separator */ + save_item(NAME(m_state.m_vsync_filter)); + save_item(NAME(m_state.m_vsync_threshold)); + save_item(NAME(m_state.m_vsync_filter_timeconst)); - m_refresh = attotime::from_hz(m_monitor_clock) * m_vtotal * m_htotal; - screen().configure(m_htotal, m_vtotal, visarea, m_refresh.as_attoseconds()); + save_item(NAME(m_state.m_sig_vsync)); + save_item(NAME(m_state.m_sig_composite)); + save_item(NAME(m_state.m_sig_field)); } -void fixedfreq_device::update_screen_parameters(const attotime &refresh) +void fixedfreq_device::device_reset() { - rectangle visarea( -// m_hsync - m_hvisible, -// m_hsync - 1 , - m_hbackporch - m_hfrontporch, - m_hbackporch - m_hfrontporch + m_hvisible - 1, - m_vbackporch - m_vfrontporch, - m_vbackporch - m_vfrontporch + m_vvisible - 1); - - m_refresh = refresh; - screen().configure(m_htotal, m_vtotal, visarea, m_refresh.as_attoseconds()); + m_state.reset(); } -int fixedfreq_device::sync_separator(const attotime &time, double newval) +void fixedfreq_device::device_post_load() { - int last_vsync = m_sig_vsync; - int last_comp = m_sig_composite; - int ret = 0; - - m_vint += ((double) last_comp - m_vint) * (1.0 - exp(-time.as_double() * m_mult)); - m_sig_composite = (newval < m_sync_threshold) ? 1 : 0 ; - - m_sig_vsync = (m_vint > m_int_trig) ? 1 : 0; - - if (!last_vsync && m_sig_vsync) - { - /* TODO - time since last hsync and field detection */ - ret |= 1; - } - if (last_vsync && !m_sig_vsync) - { - m_sig_field = last_comp; /* force false-progressive */ - m_sig_field = (m_sig_field ^ 1) ^ last_comp; /* if there is no field switch, auto switch */ - LOG("Field: %d\n", m_sig_field); - } - if (!last_comp && m_sig_composite) - { - /* TODO - time since last hsync and field detection */ - ret |= 2; - } - if (last_comp && !m_sig_composite) - { - /* falling composite */ - ret |= 4; - } - return ret; + //recompute_parameters(); } uint32_t fixedfreq_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) @@ -216,72 +238,62 @@ uint32_t fixedfreq_device::screen_update(screen_device &screen, bitmap_rgb32 &bi return 0; } -NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_vid) +void fixedfreq_device::vsync_start_cb(double refresh_time) { - bitmap_rgb32 *bm = m_bitmap[m_cur_bm].get(); - const int has_fields = (m_fieldcount > 1) ? 1: 0; + // toggle bitmap + m_cur_bm ^= 1; - int pixels = round((time - m_line_time).as_double() / m_clock_period.as_double()); - attotime delta_time = (time - m_last_time); + rectangle visarea(m_monitor.minh(), m_monitor.maxh(), m_monitor.minv(), m_monitor.maxv()); - if (data == m_vid) - return; + m_refresh_period = refresh_time; + screen().configure(m_htotal * m_monitor.m_hscale, m_vtotal, visarea, DOUBLE_TO_ATTOSECONDS(m_refresh_period)); +} - ATTR_UNUSED int sync = sync_separator(delta_time, data); +void fixedfreq_device::plot_hline(int x, int y, int w, uint32_t col) +{ + bitmap_rgb32 *bm = m_bitmap[m_cur_bm].get(); + if (y < bm->height()) + bm->plot_box(x, y, w, 1, col); +} - if (m_last_y < bm->height()) - { - rgb_t col; +NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_composite_monochrome) +{ + // double is good enough for this exercise; - if (m_vid < m_sync_threshold) - // Mark sync areas - col = rgb_t(255, 0, 0); - else - { - int colv = (int) ((m_vid - m_sync_threshold) * m_gain * 255.0); - if (colv > 255) - colv = 255; - col = rgb_t(colv, colv, colv); - } + const time_type ctime = time.as_double(); + m_state.update_composite_monochrome(ctime, data); +} - bm->plot_box(m_last_x, m_last_y + m_sig_field * has_fields, pixels - m_last_x, 1, col); - m_last_x = pixels; - } - if (sync & 1) - { - LOG("VSYNC %d %d\n", pixels, m_last_y + m_sig_field); - } - if (sync & 2) - { - LOG("HSYNC up %d\n", pixels); - //if (m_last_y == 27) printf("HSYNC up %d %d\n", m_last_y, pixels); - } - if (sync & 4) - { - LOG("HSYNC down %f %d %f\n", time.as_double()* 1e6, pixels, m_vid); - } +NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_red) +{ + // double is good enough for this exercise; - if (sync & 1) - { - m_last_y = m_vbackporch - m_vsync; - // toggle bitmap - m_cur_bm ^= 1; - update_screen_parameters(time - m_last_vsync_time); - m_last_vsync_time = time; - } + const time_type ctime = time.as_double(); + m_state.update_red(ctime, data); +} - // FIXME: pixels > 50 filters some spurious hysnc on line 27 in breakout - if ((sync & 2) && !m_sig_vsync && (pixels > 100)) - { - m_last_y += m_fieldcount; - m_last_x = 0; - m_line_time = time; - } +NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_green) +{ + // double is good enough for this exercise; + + const time_type ctime = time.as_double(); + m_state.update_green(ctime, data); +} - m_last_time = time; - m_vid = data; +NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_blue) +{ + // double is good enough for this exercise; + const time_type ctime = time.as_double(); + m_state.update_blue(ctime, data); } +NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_sync) +{ + // double is good enough for this exercise; + + const time_type ctime = time.as_double(); + m_state.update_sync(ctime, data); +} /***************************************************************************/ diff --git a/src/devices/video/fixfreq.h b/src/devices/video/fixfreq.h index 10c52217e82..d85056d874b 100644 --- a/src/devices/video/fixfreq.h +++ b/src/devices/video/fixfreq.h @@ -17,139 +17,245 @@ #include "machine/netlist.h" #include "screen.h" +struct fixedfreq_monitor_desc +{ + fixedfreq_monitor_desc() + // default to NTSC "704x480@30i" + : m_monitor_clock(13500000), + m_hvisible(704), + m_hfrontporch(728), + m_hsync(791), + m_hbackporch(858), + m_vvisible(480), + m_vfrontporch(486), + m_vsync(492), + m_vbackporch(525), + m_fieldcount(2), + m_sync_threshold(0.3), + m_gain(1.0 / 3.7), + m_hscale(1) + {} + + int minh() const { return (m_hbackporch - m_hfrontporch) * m_hscale; } + int maxh() const { return (m_hbackporch - m_hfrontporch + m_hvisible) * m_hscale - 1; } + int minv() const { return m_vbackporch - m_vfrontporch; } + int maxv() const { return m_vbackporch - m_vfrontporch + m_vvisible - 1; } + + uint32_t m_monitor_clock; + int m_hvisible; + int m_hfrontporch; + int m_hsync; + int m_hbackporch; + int m_vvisible; + int m_vfrontporch; + int m_vsync; + int m_vbackporch; + int m_fieldcount; + double m_sync_threshold; + double m_gain; + int m_hscale; +}; + +struct fixedfreq_monitor_intf +{ + virtual ~fixedfreq_monitor_intf() = default; + virtual void vsync_start_cb(double refresh_time) = 0; + virtual void plot_hline(int x, int y, int w, uint32_t col) = 0; +}; -#define FIXFREQ_INTERFACE(name) \ - const fixedfreq_interface (name) = +struct fixedfreq_monitor_state +{ + using time_type = double; + + fixedfreq_monitor_state(fixedfreq_monitor_desc &desc, fixedfreq_monitor_intf &intf) + : m_desc(desc), + m_intf(intf), + m_sync_signal(0), + m_col(0), + m_last_x(0), + m_last_y(0), + m_last_sync_time(time_type(0)), + m_line_time(time_type(0)), + m_last_hsync_time(time_type(0)), + m_last_vsync_time(time_type(0)), + m_clock_period(time_type(0)), + m_vsync_filter(0), + m_vsync_threshold(0), + m_vsync_filter_timeconst(0), + m_sig_vsync(0), + m_sig_composite(0), + m_sig_field(0) + {} + + /*** + * \brief To be called after monitor parameters are set + */ + void start() + { + // FIXME: once moved to netlist this may no longer be necessary. + // Only copies constructor init -#define MCFG_FIXFREQ_ADD(_tag, _screen_tag) \ - MCFG_SCREEN_ADD(_screen_tag, RASTER) \ - MCFG_SCREEN_RAW_PARAMS(13500000, 858, 0, 858, 525, 0, 525) \ - MCFG_SCREEN_UPDATE_DEVICE(_tag, fixedfreq_device, screen_update) \ - MCFG_DEVICE_ADD(_tag, FIXFREQ, 0) \ - MCFG_VIDEO_SET_SCREEN(_screen_tag) + m_sync_signal = 0.0; + m_col = rgb_t(0,0,0); + m_last_x = 0; + m_last_y = 0; + m_last_sync_time = time_type(0); + m_line_time = time_type(0); + m_last_hsync_time = time_type(0); + m_last_vsync_time = time_type(0); + m_clock_period = time_type(0); -#define MCFG_FIXFREQ_MONITOR_CLOCK(_clock) \ - downcast<fixedfreq_device &>(*device).set_minitor_clock(_clock); + /* sync separator */ + m_vsync_filter = 0.0; + m_vsync_threshold = 0.0; + m_vsync_filter_timeconst = 0.0; -#define MCFG_FIXFREQ_HORZ_PARAMS(_visible, _frontporch, _sync, _backporch) \ - downcast<fixedfreq_device &>(*device).set_horz_params(_visible, _frontporch, _sync, _backporch); + m_sig_vsync = 0; + m_sig_composite = 0; + m_sig_field = 0; -#define MCFG_FIXFREQ_VERT_PARAMS(_visible, _frontporch, _sync, _backporch) \ - downcast<fixedfreq_device &>(*device).set_vert_params(_visible, _frontporch, _sync, _backporch); + // htotal = m_desc.m_hbackporch; + // vtotal = m_desc.m_vbackporch; -#define MCFG_FIXFREQ_FIELDCOUNT(_count) \ - downcast<fixedfreq_device &>(*device).set_fieldcount(_count); + /* sync separator */ -#define MCFG_FIXFREQ_SYNC_THRESHOLD(_threshold) \ - downcast<fixedfreq_device &>(*device).set_threshold(_threshold); + m_vsync_threshold = (exp(- 3.0/(3.0+3.0))) - exp(-1.0); + m_vsync_filter_timeconst = (double) (m_desc.m_monitor_clock) / (double) m_desc.m_hbackporch * 1.0; // / (3.0 + 3.0); + //LOG("trigger %f with len %f\n", m_vsync_threshold, 1e6 / m_vsync_filter_timeconst); -#define MCFG_FIXFREQ_GAIN(_gain) \ - downcast<fixedfreq_device &>(*device).set_gain(_gain); + m_clock_period = 1.0 / m_desc.m_monitor_clock; + m_intf.vsync_start_cb(m_clock_period * m_desc.m_vbackporch * m_desc.m_hbackporch); -// pre-defined configurations + } -//ModeLine "720x480@30i" 13.5 720 736 799 858 480 486 492 525 interlace -hsync -vsync -#define MCFG_FIXFREQ_MODE_NTSC720 \ - MCFG_FIXFREQ_MONITOR_CLOCK(13500000) \ - MCFG_FIXFREQ_HORZ_PARAMS(720, 736, 799, 858) \ - MCFG_FIXFREQ_VERT_PARAMS(480, 486, 492, 525) \ - MCFG_FIXFREQ_FIELDCOUNT(2) \ - MCFG_FIXFREQ_SYNC_THRESHOLD(0.3) + void reset() + { + m_last_sync_time = time_type(0); + m_line_time = time_type(0); + m_last_hsync_time = time_type(0); + m_last_vsync_time = time_type(0); + m_vsync_filter = 0; + } + + void update_sync_channel(const time_type &time, const double newval); + void update_bm(const time_type &time); + void update_composite_monochrome(const time_type &time, const double newval); + void update_red(const time_type &time, const double data); + void update_green(const time_type &time, const double data); + void update_blue(const time_type &time, const double data); + void update_sync(const time_type &time, const double data); -//ModeLine "704x480@30i" 13.5 704 728 791 858 480 486 492 525 -#define MCFG_FIXFREQ_MODE_NTSC704 \ - MCFG_FIXFREQ_MONITOR_CLOCK(13500000) \ - MCFG_FIXFREQ_HORZ_PARAMS(704, 728, 791, 858) \ - MCFG_FIXFREQ_VERT_PARAMS(480, 486, 492, 525) \ - MCFG_FIXFREQ_FIELDCOUNT(2) \ - MCFG_FIXFREQ_SYNC_THRESHOLD(0.3) + const fixedfreq_monitor_desc &m_desc; + fixedfreq_monitor_intf &m_intf; + double m_sync_signal; + uint32_t m_col; + int m_last_x; + int m_last_y; + time_type m_last_sync_time; + time_type m_line_time; + time_type m_last_hsync_time; + time_type m_last_vsync_time; + time_type m_clock_period; + + /* sync separator */ + double m_vsync_filter; + double m_vsync_threshold; + double m_vsync_filter_timeconst; + + int m_sig_vsync; + int m_sig_composite; + int m_sig_field; + +}; -// ======================> vga_device +// ======================> fixedfreq_device -class fixedfreq_device : public device_t, public device_video_interface +class fixedfreq_device : public device_t, public device_video_interface, + public fixedfreq_monitor_intf { public: + + using time_type = fixedfreq_monitor_state::time_type; + // construction/destruction - fixedfreq_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + fixedfreq_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); // inline configuration helpers - void set_minitor_clock(uint32_t clock) { m_monitor_clock = clock; } - void set_fieldcount(int count) { m_fieldcount = count; } - void set_threshold(double threshold) { m_sync_threshold = threshold; } - void set_gain(double gain) { m_gain = gain; } + void set_monitor_clock(uint32_t clock) { m_monitor.m_monitor_clock = clock; } + void set_fieldcount(int count) { m_monitor.m_fieldcount = count; } + void set_threshold(double threshold) { m_monitor.m_sync_threshold = threshold; } + void set_gain(double gain) { m_monitor.m_gain = gain; } void set_horz_params(int visible, int frontporch, int sync, int backporch) { - m_hvisible = visible; - m_hfrontporch = frontporch; - m_hsync = sync; - m_hbackporch = backporch; + m_monitor.m_hvisible = visible; + m_monitor.m_hfrontporch = frontporch; + m_monitor.m_hsync = sync; + m_monitor.m_hbackporch = backporch; } void set_vert_params(int visible, int frontporch, int sync, int backporch) { - m_vvisible = visible; - m_vfrontporch = frontporch; - m_vsync = sync; - m_vbackporch = backporch; + m_monitor.m_vvisible = visible; + m_monitor.m_vfrontporch = frontporch; + m_monitor.m_vsync = sync; + m_monitor.m_vbackporch = backporch; + } + void set_horz_scale(int hscale) { m_monitor.m_hscale = hscale; } + + // pre-defined configurations + void set_mode_ntsc720() //ModeLine "720x480@30i" 13.5 720 736 799 858 480 486 492 525 interlace -hsync -vsync + { + set_monitor_clock(13500000); + set_horz_params(720, 736, 799, 858); + set_vert_params(480, 486, 492, 525); + set_fieldcount(2); + set_threshold(0.3); + } + void set_mode_ntsc704() //ModeLine "704x480@30i" 13.5 704 728 791 858 480 486 492 525 + { + set_monitor_clock(13500000); + set_horz_params(704, 728, 791, 858); + set_vert_params(480, 486, 492, 525); + set_fieldcount(2); + set_threshold(0.3); } virtual uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - NETDEV_ANALOG_CALLBACK_MEMBER(update_vid); + NETDEV_ANALOG_CALLBACK_MEMBER(update_composite_monochrome); + NETDEV_ANALOG_CALLBACK_MEMBER(update_red); + NETDEV_ANALOG_CALLBACK_MEMBER(update_green); + NETDEV_ANALOG_CALLBACK_MEMBER(update_blue); + NETDEV_ANALOG_CALLBACK_MEMBER(update_sync); + protected: + fixedfreq_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); // device-level overrides + virtual void device_config_complete() override; virtual void device_start() override; virtual void device_reset() override; virtual void device_post_load() override; //virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); - void recompute_parameters(bool postload); - void update_screen_parameters(const attotime &refresh); + void vsync_start_cb(double refresh_time) override; + void plot_hline(int x, int y, int w, uint32_t col) override; private: - int sync_separator(const attotime &time, double newval); - + std::unique_ptr<bitmap_rgb32> m_bitmap[2]; + int m_cur_bm; int m_htotal; int m_vtotal; - double m_vid; - int m_last_x; - int m_last_y; - attotime m_last_time; - attotime m_line_time; - attotime m_last_hsync_time; - attotime m_last_vsync_time; - attotime m_refresh; - attotime m_clock_period; - std::unique_ptr<bitmap_rgb32> m_bitmap[2]; - int m_cur_bm; + time_type m_refresh_period; /* adjustable by drivers */ - uint32_t m_monitor_clock; - int m_hvisible; - int m_hfrontporch; - int m_hsync; - int m_hbackporch; - int m_vvisible; - int m_vfrontporch; - int m_vsync; - int m_vbackporch; - int m_fieldcount; - double m_sync_threshold; - double m_gain; - - /* sync separator */ - double m_vint; - double m_int_trig; - double m_mult; + fixedfreq_monitor_desc m_monitor; + fixedfreq_monitor_state m_state; - int m_sig_vsync; - int m_sig_composite; - int m_sig_field; }; diff --git a/src/devices/video/gba_lcd.cpp b/src/devices/video/gba_lcd.cpp index 36c8e83b27e..36214bb1ad4 100644 --- a/src/devices/video/gba_lcd.cpp +++ b/src/devices/video/gba_lcd.cpp @@ -1807,11 +1807,12 @@ void gba_lcd_device::device_reset() m_hbl_timer->adjust(attotime::never); } -MACHINE_CONFIG_START(gba_lcd_device::device_add_mconfig) - MCFG_SCREEN_ADD("screen", LCD) - MCFG_SCREEN_RAW_PARAMS(XTAL(16'777'216) / 4, 308, 0, 240, 228, 0, 160) - MCFG_SCREEN_UPDATE_DEVICE(DEVICE_SELF, gba_lcd_device, screen_update) - MCFG_SCREEN_PALETTE("palette") +void gba_lcd_device::device_add_mconfig(machine_config &config) +{ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD)); + screen.set_raw(XTAL(16'777'216) / 4, 308, 0, 240, 228, 0, 160); + screen.set_screen_update(FUNC(gba_lcd_device::screen_update)); + screen.set_palette("palette"); PALETTE(config, "palette", FUNC(gba_lcd_device::gba_palette), 32768); -MACHINE_CONFIG_END +} diff --git a/src/devices/video/gba_lcd.h b/src/devices/video/gba_lcd.h index 1332340e175..ed4c258acad 100644 --- a/src/devices/video/gba_lcd.h +++ b/src/devices/video/gba_lcd.h @@ -26,29 +26,6 @@ DECLARE_DEVICE_TYPE(GBA_LCD, gba_lcd_device) //************************************************************************** -// DEVICE CONFIGURATION MACROS -//************************************************************************** - -#define MCFG_GBA_LCD_ADD(_tag) \ - MCFG_DEVICE_ADD(_tag, GBA_LCD, 0) - -#define MCFG_GBA_LCD_INT_HBLANK(_devcb) \ - downcast<gba_lcd_device &>(*device).set_int_hblank_callback(DEVCB_##_devcb); - -#define MCFG_GBA_LCD_INT_VBLANK(_devcb) \ - downcast<gba_lcd_device &>(*device).set_int_vblank_callback(DEVCB_##_devcb); - -#define MCFG_GBA_LCD_INT_VCOUNT(_devcb) \ - downcast<gba_lcd_device &>(*device).set_int_vcount_callback(DEVCB_##_devcb); - -#define MCFG_GBA_LCD_DMA_HBLANK(_devcb) \ - downcast<gba_lcd_device &>(*device).set_dma_hblank_callback(DEVCB_##_devcb); - -#define MCFG_GBA_LCD_DMA_VBLANK(_devcb) \ - downcast<gba_lcd_device &>(*device).set_dma_vblank_callback(DEVCB_##_devcb); - - -//************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -99,11 +76,11 @@ public: TIMER_CALLBACK_MEMBER(perform_hbl); TIMER_CALLBACK_MEMBER(perform_scan); - template <class Object> devcb_base &set_int_hblank_callback(Object &&cb) { return m_int_hblank_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_int_vblank_callback(Object &&cb) { return m_int_vblank_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_int_vcount_callback(Object &&cb) { return m_int_vcount_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_dma_hblank_callback(Object &&cb) { return m_dma_hblank_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_dma_vblank_callback(Object &&cb) { return m_dma_vblank_cb.set_callback(std::forward<Object>(cb)); } + auto int_hblank_callback() { return m_int_hblank_cb.bind(); } + auto int_vblank_callback() { return m_int_vblank_cb.bind(); } + auto int_vcount_callback() { return m_int_vcount_cb.bind(); } + auto dma_hblank_callback() { return m_dma_hblank_cb.bind(); } + auto dma_vblank_callback() { return m_dma_vblank_cb.bind(); } protected: // device-level overrides diff --git a/src/devices/video/hd44102.h b/src/devices/video/hd44102.h index a484ce77478..1688a502441 100644 --- a/src/devices/video/hd44102.h +++ b/src/devices/video/hd44102.h @@ -12,19 +12,6 @@ #pragma once - - -///************************************************************************* -// INTERFACE CONFIGURATION MACROS -///************************************************************************* - -#define MCFG_HD44102_ADD(_tag, _screen_tag, _sx, _sy) \ - MCFG_DEVICE_ADD(_tag, HD44102, 0) \ - MCFG_VIDEO_SET_SCREEN(_screen_tag) \ - downcast<hd44102_device &>(*device).set_offsets(_sx, _sy); - - - ///************************************************************************* // TYPE DEFINITIONS ///************************************************************************* @@ -36,6 +23,14 @@ class hd44102_device : public device_t, { public: // construction/destruction + template <typename T> + hd44102_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&screen_tag, int sx, int sy) + :hd44102_device(mconfig, tag, owner, clock) + { + set_screen(std::forward<T>(screen_tag)); + set_offsets(sx, sy); + } + hd44102_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // inline configuration helpers diff --git a/src/devices/video/hd44780.h b/src/devices/video/hd44780.h index 65544ef6828..a6572536cf1 100644 --- a/src/devices/video/hd44780.h +++ b/src/devices/video/hd44780.h @@ -12,18 +12,6 @@ #pragma once -#define MCFG_HD44780_ADD( _tag ) \ - MCFG_DEVICE_ADD( _tag, HD44780, 0 ) - -#define MCFG_KS0066_F05_ADD( _tag ) \ - MCFG_DEVICE_ADD( _tag, KS0066_F05, 0 ) - -#define MCFG_HD44780_LCD_SIZE(_lines, _chars) \ - downcast<hd44780_device &>(*device).set_lcd_size(_lines, _chars); - -#define MCFG_HD44780_PIXEL_UPDATE_CB(_class, _method) \ - downcast<hd44780_device &>(*device).set_pixel_update_cb(&_class::_method, #_class "::" #_method, this); - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** diff --git a/src/devices/video/hd61830.cpp b/src/devices/video/hd61830.cpp index 7d0427ff2ba..a608c096b1e 100644 --- a/src/devices/video/hd61830.cpp +++ b/src/devices/video/hd61830.cpp @@ -27,7 +27,8 @@ decltype(HD61830) HD61830B = HD61830; // default address map void hd61830_device::hd61830(address_map &map) { - map(0x0000, 0xffff).ram(); + if (!has_configured_map(0)) + map(0x0000, 0xffff).ram(); } @@ -84,7 +85,7 @@ hd61830_device::hd61830_device(const machine_config &mconfig, const char *tag, d m_cac(0), m_blink(0), m_cursor(0), - m_space_config("videoram", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(), address_map_constructor(FUNC(hd61830_device::hd61830), this)), + m_space_config("videoram", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(FUNC(hd61830_device::hd61830), this)), m_char_rom(*this, "hd61830") { } diff --git a/src/devices/video/hd61830.h b/src/devices/video/hd61830.h index ab4278f9d89..f8579081ac1 100644 --- a/src/devices/video/hd61830.h +++ b/src/devices/video/hd61830.h @@ -12,17 +12,6 @@ #pragma once - - -//************************************************************************** -// INTERFACE CONFIGURATION MACROS -//************************************************************************** - -#define MCFG_HD61830_RD_CALLBACK(_read) \ - downcast<hd61830_device &>(*device).set_rd_rd_callback(DEVCB_##_read); - - - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -37,7 +26,7 @@ public: // construction/destruction hd61830_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template <class Object> devcb_base &set_rd_rd_callback(Object &&cb) { return m_read_rd.set_callback(std::forward<Object>(cb)); } + auto rd_rd_callback() { return m_read_rd.bind(); } DECLARE_READ8_MEMBER( status_r ); DECLARE_WRITE8_MEMBER( control_w ); diff --git a/src/devices/video/hd63484.h b/src/devices/video/hd63484.h index 885761d211b..73a321fc117 100644 --- a/src/devices/video/hd63484.h +++ b/src/devices/video/hd63484.h @@ -13,30 +13,8 @@ #pragma once - -/*************************************************************************** - DEVICE CONFIGURATION MACROS -***************************************************************************/ - -#define MCFG_HD63484_ADD(_tag, _clock, _map) \ - MCFG_DEVICE_ADD(_tag, HD63484, _clock) \ - MCFG_DEVICE_ADDRESS_MAP(0, _map) - -#define MCFG_HD63484_ADDRESS_MAP(_map) \ - MCFG_DEVICE_ADDRESS_MAP(0, _map) - -#define MCFG_HD63484_DISPLAY_CALLBACK_OWNER(_class, _method) \ - downcast<hd63484_device &>(*device).set_display_callback(hd63484_device::display_delegate(&_class::_method, #_class "::" #_method, this)); - -#define MCFG_HD63484_AUTO_CONFIGURE_SCREEN(_val) \ - downcast<hd63484_device &>(*device).set_auto_configure_screen(_val); - #define HD63484_DISPLAY_PIXELS_MEMBER(_name) void _name(bitmap_ind16 &bitmap, const rectangle &cliprect, int y, int x, uint16_t data) -#define MCFG_HD63484_EXTERNAL_SKEW(_val) \ - downcast<hd63484_device &>(*device).set_external_skew(_val); - - // ======================> hd63484_device class hd63484_device : public device_t, @@ -49,7 +27,7 @@ public: // construction/destruction hd63484_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template <typename Object> void set_display_callback(Object &&cb) { m_display_cb = std::forward<Object>(cb); } + template <typename... T> void set_display_callback(T &&... args) { m_display_cb = display_delegate(std::forward<T>(args)...); } void set_auto_configure_screen(bool auto_configure_screen) { m_auto_configure_screen = auto_configure_screen; } void set_external_skew(int skew) { m_external_skew = skew; } diff --git a/src/devices/video/hd66421.cpp b/src/devices/video/hd66421.cpp index 63283f498b0..bb03b80252e 100644 --- a/src/devices/video/hd66421.cpp +++ b/src/devices/video/hd66421.cpp @@ -74,7 +74,8 @@ DEFINE_DEVICE_TYPE(HD66421, hd66421_device, "hd66421", "Hitachi HD66421 LCD Cont // default address map void hd66421_device::hd66421(address_map &map) { - map(0x0000, HD66421_RAM_SIZE).ram(); + if (!has_configured_map(0)) + map(0x0000, HD66421_RAM_SIZE).ram(); } //------------------------------------------------- @@ -125,7 +126,7 @@ inline void hd66421_device::writebyte(offs_t address, uint8_t data) hd66421_device::hd66421_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, HD66421, tag, owner, clock) , device_memory_interface(mconfig, *this) - , m_space_config("videoram", ENDIANNESS_LITTLE, 8, 17, 0, address_map_constructor(), address_map_constructor(FUNC(hd66421_device::hd66421), this)) + , m_space_config("videoram", ENDIANNESS_LITTLE, 8, 17, 0, address_map_constructor(FUNC(hd66421_device::hd66421), this)) , m_cmd(0) , m_x(0) , m_y(0) diff --git a/src/devices/video/hlcd0515.cpp b/src/devices/video/hlcd0515.cpp index b7730332bfd..87abf50bc0e 100644 --- a/src/devices/video/hlcd0515.cpp +++ b/src/devices/video/hlcd0515.cpp @@ -26,27 +26,23 @@ DEFINE_DEVICE_TYPE(HLCD0530, hlcd0530_device, "hlcd0530", "Hughes HLCD 0530 LCD // constructor //------------------------------------------------- -hlcd0515_device::hlcd0515_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 colmax) - : device_t(mconfig, type, tag, owner, clock) - , m_colmax(colmax) - , m_write_cols(*this), m_write_data(*this) -{ -} +hlcd0515_device::hlcd0515_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 colmax) : + device_t(mconfig, type, tag, owner, clock), + m_colmax(colmax), + m_write_cols(*this), m_write_data(*this) +{ } -hlcd0515_device::hlcd0515_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : hlcd0515_device(mconfig, HLCD0515, tag, owner, clock, 25) -{ -} +hlcd0515_device::hlcd0515_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + hlcd0515_device(mconfig, HLCD0515, tag, owner, clock, 25) +{ } -hlcd0569_device::hlcd0569_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : hlcd0515_device(mconfig, HLCD0569, tag, owner, clock, 24) -{ -} +hlcd0569_device::hlcd0569_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + hlcd0515_device(mconfig, HLCD0569, tag, owner, clock, 24) +{ } -hlcd0530_device::hlcd0530_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : hlcd0515_device(mconfig, HLCD0530, tag, owner, clock, 24) -{ -} +hlcd0530_device::hlcd0530_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + hlcd0515_device(mconfig, HLCD0530, tag, owner, clock, 24) +{ } @@ -66,7 +62,7 @@ void hlcd0515_device::device_start() // zerofill m_cs = 0; - m_pclock = 0; + m_clk = 0; m_data = 0; m_count = 0; m_control = 0; @@ -79,7 +75,7 @@ void hlcd0515_device::device_start() // register for savestates save_item(NAME(m_cs)); - save_item(NAME(m_pclock)); + save_item(NAME(m_clk)); save_item(NAME(m_data)); save_item(NAME(m_count)); save_item(NAME(m_control)); @@ -157,12 +153,12 @@ void hlcd0515_device::clock_data(int col) } -WRITE_LINE_MEMBER(hlcd0515_device::write_clock) +WRITE_LINE_MEMBER(hlcd0515_device::clock_w) { state = (state) ? 1 : 0; // clock/shift data on falling edge - if (!m_cs && !state && m_pclock) + if (!m_cs && !state && m_clk) { if (m_count < 5) { @@ -179,11 +175,11 @@ WRITE_LINE_MEMBER(hlcd0515_device::write_clock) m_count++; } - m_pclock = state; + m_clk = state; } -WRITE_LINE_MEMBER(hlcd0515_device::write_cs) +WRITE_LINE_MEMBER(hlcd0515_device::cs_w) { state = (state) ? 1 : 0; diff --git a/src/devices/video/hlcd0515.h b/src/devices/video/hlcd0515.h index 5018978226d..1108890a1fb 100644 --- a/src/devices/video/hlcd0515.h +++ b/src/devices/video/hlcd0515.h @@ -50,9 +50,9 @@ public: auto write_cols() { return m_write_cols.bind(); } // COL/ROW pins (offset for ROW) auto write_data() { return m_write_data.bind(); } // DATA OUT pin, don't use on HLCD0569 - DECLARE_WRITE_LINE_MEMBER(write_clock); - DECLARE_WRITE_LINE_MEMBER(write_cs); - DECLARE_WRITE_LINE_MEMBER(write_data) { m_data = (state) ? 1 : 0; } + DECLARE_WRITE_LINE_MEMBER(clock_w); + DECLARE_WRITE_LINE_MEMBER(cs_w); + DECLARE_WRITE_LINE_MEMBER(data_w) { m_data = (state) ? 1 : 0; } protected: hlcd0515_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 colmax); @@ -67,7 +67,7 @@ protected: const u8 m_colmax; // number of column pins int m_cs; // input pin state - int m_pclock; // " + int m_clk; // " int m_data; // " int m_count; u8 m_control; diff --git a/src/devices/video/hlcd0538.cpp b/src/devices/video/hlcd0538.cpp index c409e6be528..12a188d07a0 100644 --- a/src/devices/video/hlcd0538.cpp +++ b/src/devices/video/hlcd0538.cpp @@ -23,22 +23,18 @@ DEFINE_DEVICE_TYPE(HLCD0539, hlcd0539_device, "hlcd0539", "Hughes HLCD 0539 LCD // constructor //------------------------------------------------- -hlcd0538_device::hlcd0538_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) - : device_t(mconfig, type, tag, owner, clock) - , m_write_cols(*this), m_write_interrupt(*this) -{ -} - -hlcd0538_device::hlcd0538_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : hlcd0538_device(mconfig, HLCD0538, tag, owner, clock) -{ -} +hlcd0538_device::hlcd0538_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : + device_t(mconfig, type, tag, owner, clock), + m_write_cols(*this), m_write_interrupt(*this) +{ } -hlcd0539_device::hlcd0539_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : hlcd0538_device(mconfig, HLCD0539, tag, owner, clock) -{ -} +hlcd0538_device::hlcd0538_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + hlcd0538_device(mconfig, HLCD0538, tag, owner, clock) +{ } +hlcd0539_device::hlcd0539_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + hlcd0538_device(mconfig, HLCD0539, tag, owner, clock) +{ } //------------------------------------------------- @@ -65,12 +61,11 @@ void hlcd0538_device::device_start() } - //------------------------------------------------- // handlers //------------------------------------------------- -WRITE_LINE_MEMBER(hlcd0538_device::write_clk) +WRITE_LINE_MEMBER(hlcd0538_device::clk_w) { state = (state) ? 1 : 0; @@ -81,7 +76,7 @@ WRITE_LINE_MEMBER(hlcd0538_device::write_clk) m_clk = state; } -WRITE_LINE_MEMBER(hlcd0538_device::write_lcd) +WRITE_LINE_MEMBER(hlcd0538_device::lcd_w) { state = (state) ? 1 : 0; diff --git a/src/devices/video/hlcd0538.h b/src/devices/video/hlcd0538.h index 187523e1076..bc1a78d16fc 100644 --- a/src/devices/video/hlcd0538.h +++ b/src/devices/video/hlcd0538.h @@ -43,15 +43,15 @@ class hlcd0538_device : public device_t { public: - hlcd0538_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + hlcd0538_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); // configuration helpers - auto write_cols_callback() { return m_write_cols.bind(); } // C/R pins (0538: d0-d7 for rows) - auto write_interrupt_callback() { return m_write_interrupt.bind(); } // INTERRUPT pin + auto write_cols() { return m_write_cols.bind(); } // C/R pins (0538: d0-d7 for rows) + auto write_interrupt() { return m_write_interrupt.bind(); } // INTERRUPT pin - DECLARE_WRITE_LINE_MEMBER(write_clk); - DECLARE_WRITE_LINE_MEMBER(write_lcd); - DECLARE_WRITE_LINE_MEMBER(write_data) { m_data = (state) ? 1 : 0; } + DECLARE_WRITE_LINE_MEMBER(clk_w); + DECLARE_WRITE_LINE_MEMBER(lcd_w); + DECLARE_WRITE_LINE_MEMBER(data_w) { m_data = (state) ? 1 : 0; } protected: hlcd0538_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); diff --git a/src/devices/video/huc6202.h b/src/devices/video/huc6202.h index a3e1a47b519..3ff175f0ece 100644 --- a/src/devices/video/huc6202.h +++ b/src/devices/video/huc6202.h @@ -12,61 +12,24 @@ #pragma once -#define MCFG_HUC6202_NEXT_PIXEL_0_CB(_devcb) \ - downcast<huc6202_device &>(*device).set_next_pixel_0_callback(DEVCB_##_devcb); - -#define MCFG_HUC6202_TIME_TIL_NEXT_EVENT_0_CB(_devcb) \ - downcast<huc6202_device &>(*device).set_time_til_next_event_0_callback(DEVCB_##_devcb); - -#define MCFG_HUC6202_VSYNC_CHANGED_0_CB(_devcb) \ - downcast<huc6202_device &>(*device).set_vsync_changed_0_callback(DEVCB_##_devcb); - -#define MCFG_HUC6202_HSYNC_CHANGED_0_CB(_devcb) \ - downcast<huc6202_device &>(*device).set_hsync_changed_0_callback(DEVCB_##_devcb); - -#define MCFG_HUC6202_READ_0_CB(_devcb) \ - downcast<huc6202_device &>(*device).set_read_0_callback(DEVCB_##_devcb); - -#define MCFG_HUC6202_WRITE_0_CB(_devcb) \ - downcast<huc6202_device &>(*device).set_write_0_callback(DEVCB_##_devcb); - -#define MCFG_HUC6202_NEXT_PIXEL_1_CB(_devcb) \ - downcast<huc6202_device &>(*device).set_next_pixel_1_callback(DEVCB_##_devcb); - -#define MCFG_HUC6202_TIME_TIL_NEXT_EVENT_1_CB(_devcb) \ - downcast<huc6202_device &>(*device).set_time_til_next_event_1_callback(DEVCB_##_devcb); - -#define MCFG_HUC6202_VSYNC_CHANGED_1_CB(_devcb) \ - downcast<huc6202_device &>(*device).set_vsync_changed_1_callback(DEVCB_##_devcb); - -#define MCFG_HUC6202_HSYNC_CHANGED_1_CB(_devcb) \ - downcast<huc6202_device &>(*device).set_hsync_changed_1_callback(DEVCB_##_devcb); - -#define MCFG_HUC6202_READ_1_CB(_devcb) \ - downcast<huc6202_device &>(*device).set_read_1_callback(DEVCB_##_devcb); - -#define MCFG_HUC6202_WRITE_1_CB(_devcb) \ - downcast<huc6202_device &>(*device).set_write_1_callback(DEVCB_##_devcb); - - class huc6202_device : public device_t { public: // construction/destruction huc6202_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template <class Object> devcb_base &set_next_pixel_0_callback(Object &&cb) { return m_next_pixel_0_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_time_til_next_event_0_callback(Object &&cb) { return m_time_til_next_event_0_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_vsync_changed_0_callback(Object &&cb) { return m_vsync_changed_0_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_hsync_changed_0_callback(Object &&cb) { return m_hsync_changed_0_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_read_0_callback(Object &&cb) { return m_read_0_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_write_0_callback(Object &&cb) { return m_write_0_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_next_pixel_1_callback(Object &&cb) { return m_next_pixel_1_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_time_til_next_event_1_callback(Object &&cb) { return m_time_til_next_event_1_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_vsync_changed_1_callback(Object &&cb) { return m_vsync_changed_1_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_hsync_changed_1_callback(Object &&cb) { return m_hsync_changed_1_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_read_1_callback(Object &&cb) { return m_read_1_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_write_1_callback(Object &&cb) { return m_write_1_cb.set_callback(std::forward<Object>(cb)); } + auto next_pixel_0_callback() { return m_next_pixel_0_cb.bind(); } + auto time_til_next_event_0_callback() { return m_time_til_next_event_0_cb.bind(); } + auto vsync_changed_0_callback() { return m_vsync_changed_0_cb.bind(); } + auto hsync_changed_0_callback() { return m_hsync_changed_0_cb.bind(); } + auto read_0_callback() { return m_read_0_cb.bind(); } + auto write_0_callback() { return m_write_0_cb.bind(); } + auto next_pixel_1_callback() { return m_next_pixel_1_cb.bind(); } + auto time_til_next_event_1_callback() { return m_time_til_next_event_1_cb.bind(); } + auto vsync_changed_1_callback() { return m_vsync_changed_1_cb.bind(); } + auto hsync_changed_1_callback() { return m_hsync_changed_1_cb.bind(); } + auto read_1_callback() { return m_read_1_cb.bind(); } + auto write_1_callback() { return m_write_1_cb.bind(); } DECLARE_READ8_MEMBER( read ); DECLARE_WRITE8_MEMBER( write ); diff --git a/src/devices/video/huc6260.h b/src/devices/video/huc6260.h index 8737d0432cf..695f60c9a05 100644 --- a/src/devices/video/huc6260.h +++ b/src/devices/video/huc6260.h @@ -12,19 +12,6 @@ #pragma once -#define MCFG_HUC6260_NEXT_PIXEL_DATA_CB(_devcb) \ - downcast<huc6260_device &>(*device).set_next_pixel_data_callback(DEVCB_##_devcb); - -#define MCFG_HUC6260_TIME_TIL_NEXT_EVENT_CB(_devcb) \ - downcast<huc6260_device &>(*device).set_time_til_next_event_callback(DEVCB_##_devcb); - -#define MCFG_HUC6260_VSYNC_CHANGED_CB(_devcb) \ - downcast<huc6260_device &>(*device).set_vsync_changed_callback(DEVCB_##_devcb); - -#define MCFG_HUC6260_HSYNC_CHANGED_CB(_devcb) \ - downcast<huc6260_device &>(*device).set_hsync_changed_callback(DEVCB_##_devcb); - - class huc6260_device : public device_t, public device_palette_interface, public device_video_interface @@ -40,10 +27,6 @@ public: // construction/destruction huc6260_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template <class Object> devcb_base &set_next_pixel_data_callback(Object &&cb) { return m_next_pixel_data_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_time_til_next_event_callback(Object &&cb) { return m_time_til_next_event_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_vsync_changed_callback(Object &&cb) { return m_vsync_changed_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_hsync_changed_callback(Object &&cb) { return m_hsync_changed_cb.set_callback(std::forward<Object>(cb)); } auto next_pixel_data() { return m_next_pixel_data_cb.bind(); } auto time_til_next_event() { return m_time_til_next_event_cb.bind(); } auto vsync_changed() { return m_vsync_changed_cb.bind(); } diff --git a/src/devices/video/huc6261.h b/src/devices/video/huc6261.h index 721ef88cc3a..33efd71fcd9 100644 --- a/src/devices/video/huc6261.h +++ b/src/devices/video/huc6261.h @@ -15,16 +15,6 @@ #include "video/huc6272.h" -#define MCFG_HUC6261_VDC1(_tag) \ - downcast<huc6261_device &>(*device).set_vdc1_tag(_tag); - -#define MCFG_HUC6261_VDC2(_tag) \ - downcast<huc6261_device &>(*device).set_vdc2_tag(_tag); - -#define MCFG_HUC6261_KING(_tag) \ - downcast<huc6261_device &>(*device).set_king_tag(_tag); - - class huc6261_device : public device_t, public device_video_interface { diff --git a/src/devices/video/huc6270.h b/src/devices/video/huc6270.h index 2ee9e0d6259..cd3a9f7acee 100644 --- a/src/devices/video/huc6270.h +++ b/src/devices/video/huc6270.h @@ -12,12 +12,6 @@ #pragma once -#define MCFG_HUC6270_VRAM_SIZE(_size) \ - downcast<huc6270_device &>(*device).set_vram_size(_size); - -#define MCFG_HUC6270_IRQ_CHANGED_CB(_devcb) \ - downcast<huc6270_device &>(*device).set_irq_changed_callback(DEVCB_##_devcb); - class huc6270_device : public device_t { public: @@ -25,7 +19,6 @@ public: huc6270_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); void set_vram_size(uint32_t vram_size) { m_vram_size = vram_size; } - template <class Object> devcb_base &set_irq_changed_callback(Object &&cb) { return m_irq_changed_cb.set_callback(std::forward<Object>(cb)); } auto irq() { return m_irq_changed_cb.bind(); } DECLARE_READ8_MEMBER( read ); diff --git a/src/devices/video/huc6271.cpp b/src/devices/video/huc6271.cpp index 7af976a820a..9f90ba8c3b3 100644 --- a/src/devices/video/huc6271.cpp +++ b/src/devices/video/huc6271.cpp @@ -29,13 +29,14 @@ DEFINE_DEVICE_TYPE(HUC6271, huc6271_device, "huc6271", "Hudson HuC6271 \"Rainbow void huc6271_device::data_map(address_map &map) { - map(0x000000, 0x0fffff).ram(); + if (!has_configured_map(0)) + map(0x000000, 0x0fffff).ram(); } huc6271_device::huc6271_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, HUC6271, tag, owner, clock) , device_memory_interface(mconfig, *this) - , m_data_space_config("data", ENDIANNESS_LITTLE, 32, 32, 0, address_map_constructor(), address_map_constructor(FUNC(huc6271_device::data_map), this)) + , m_data_space_config("data", ENDIANNESS_LITTLE, 32, 32, 0, address_map_constructor(FUNC(huc6271_device::data_map), this)) { } diff --git a/src/devices/video/huc6272.cpp b/src/devices/video/huc6272.cpp index c6e94bb9810..0fe5ec52159 100644 --- a/src/devices/video/huc6272.cpp +++ b/src/devices/video/huc6272.cpp @@ -25,13 +25,17 @@ DEFINE_DEVICE_TYPE(HUC6272, huc6272_device, "huc6272", "Hudson HuC6272 \"King\"" void huc6272_device::microprg_map(address_map &map) { - map(0x00, 0x0f).ram().share("microprg_ram"); + if (!has_configured_map(0)) + map(0x00, 0x0f).ram().share("microprg_ram"); } void huc6272_device::kram_map(address_map &map) { - map(0x000000, 0x0fffff).ram().share("kram_page0"); - map(0x100000, 0x1fffff).ram().share("kram_page1"); + if (!has_configured_map(1)) + { + map(0x000000, 0x0fffff).ram().share("kram_page0"); + map(0x100000, 0x1fffff).ram().share("kram_page1"); + } } @@ -49,8 +53,8 @@ huc6272_device::huc6272_device(const machine_config &mconfig, const char *tag, d m_huc6271(*this, finder_base::DUMMY_TAG), m_cdda_l(*this, "cdda_l"), m_cdda_r(*this, "cdda_r"), - m_program_space_config("microprg", ENDIANNESS_LITTLE, 16, 4, 0, address_map_constructor(), address_map_constructor(FUNC(huc6272_device::microprg_map), this)), - m_data_space_config("kram", ENDIANNESS_LITTLE, 32, 21, 0, address_map_constructor(), address_map_constructor(FUNC(huc6272_device::kram_map), this)), + m_program_space_config("microprg", ENDIANNESS_LITTLE, 16, 4, 0, address_map_constructor(FUNC(huc6272_device::microprg_map), this)), + m_data_space_config("kram", ENDIANNESS_LITTLE, 32, 21, 0, address_map_constructor(FUNC(huc6272_device::kram_map), this)), m_microprg_ram(*this, "microprg_ram"), m_kram_page0(*this, "kram_page0"), m_kram_page1(*this, "kram_page1"), diff --git a/src/devices/video/huc6272.h b/src/devices/video/huc6272.h index cd931a1dae9..8d7f0583600 100644 --- a/src/devices/video/huc6272.h +++ b/src/devices/video/huc6272.h @@ -18,17 +18,6 @@ //************************************************************************** -// INTERFACE CONFIGURATION MACROS -//************************************************************************** - -#define MCFG_HUC6272_IRQ_CHANGED_CB(cb) \ - downcast<huc6272_device &>(*device).set_irq_changed_callback((DEVCB_##cb)); - -#define MCFG_HUC6272_RAINBOW(tag) \ - downcast<huc6272_device &>(*device).set_rainbow_tag((tag)); - - -//************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -41,7 +30,7 @@ public: // construction/destruction huc6272_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template <class Object> devcb_base &set_irq_changed_callback(Object &&cb) { return m_irq_changed_cb.set_callback(std::forward<Object>(cb)); } + auto irq_changed_callback() { return m_irq_changed_cb.bind(); } template <typename T> void set_rainbow_tag(T &&tag) { m_huc6271.set_tag(std::forward<T>(tag)); } // I/O operations diff --git a/src/devices/video/i8244.cpp b/src/devices/video/i8244.cpp index 639174a84b8..a2d142b0410 100644 --- a/src/devices/video/i8244.cpp +++ b/src/devices/video/i8244.cpp @@ -130,6 +130,22 @@ i8245_device::i8245_device(const machine_config &mconfig, const char *tag, devic //------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void i8244_device::device_config_complete() +{ + if (!has_screen()) + return; + + if (!screen().refresh_attoseconds()) + screen().set_raw(clock(), LINE_CLOCKS, START_ACTIVE_SCAN, END_ACTIVE_SCAN, m_screen_lines, START_Y, START_Y + SCREEN_HEIGHT); +} + + +//------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- diff --git a/src/devices/video/i8244.h b/src/devices/video/i8244.h index 0bf0174cdba..2a46163073b 100644 --- a/src/devices/video/i8244.h +++ b/src/devices/video/i8244.h @@ -17,25 +17,6 @@ /*************************************************************************** - DEVICE CONFIGURATION MACROS -***************************************************************************/ - -#define MCFG_I8244_ADD(_tag, _clock, _screen_tag, _irq_cb, _postprocess_cb) \ - MCFG_DEVICE_ADD(_tag, I8244, _clock) \ - MCFG_VIDEO_SET_SCREEN(_screen_tag) \ - MCFG_I8244_IRQ_CB(_irq_cb) \ - MCFG_I8244_POSTPROCESS_CB(_postprocess_cb) -#define MCFG_I8244_IRQ_CB(_devcb) \ - downcast<i8244_device &>(*device).set_irq_cb(DEVCB_##_devcb); -#define MCFG_I8244_POSTPROCESS_CB(_devcb) \ - downcast<i8244_device &>(*device).set_postprocess_cb(DEVCB_##_devcb); -#define MCFG_I8245_ADD(_tag, _clock, _screen_tag, _irq_cb, _postprocess_cb) \ - MCFG_DEVICE_ADD(_tag, I8245, _clock) \ - MCFG_VIDEO_SET_SCREEN(_screen_tag) \ - MCFG_I8244_IRQ_CB(_irq_cb) \ - MCFG_I8244_POSTPROCESS_CB(_postprocess_cb ) - -/*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ @@ -51,8 +32,8 @@ public: i8244_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // configuration helpers - template <class Object> devcb_base &set_irq_cb(Object &&cb) { return m_irq_func.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_postprocess_cb(Object &&cb) { return m_postprocess_func.set_callback(std::forward<Object>(cb)); } + auto irq_cb() { return m_irq_func.bind(); } + auto postprocess_cb() { return m_postprocess_func.bind(); } DECLARE_READ8_MEMBER(read); DECLARE_WRITE8_MEMBER(write); @@ -109,6 +90,7 @@ protected: i8244_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int lines); // device-level overrides + virtual void device_config_complete() override; virtual void device_start() override; virtual void device_reset() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; diff --git a/src/devices/video/i8275.h b/src/devices/video/i8275.h index 44bede3ace4..f5d6b3633bc 100644 --- a/src/devices/video/i8275.h +++ b/src/devices/video/i8275.h @@ -44,26 +44,6 @@ #define I8275_DRAW_CHARACTER_MEMBER(_name) void _name(bitmap_rgb32 &bitmap, int x, int y, uint8_t linecount, uint8_t charcode, uint8_t lineattr, uint8_t lten, uint8_t rvv, uint8_t vsp, uint8_t gpa, uint8_t hlgt) -#define MCFG_I8275_CHARACTER_WIDTH(_value) \ - downcast<i8275_device &>(*device).set_character_width(_value); - -#define MCFG_I8275_DRAW_CHARACTER_CALLBACK_OWNER(_class, _method) \ - downcast<i8275_device &>(*device).set_display_callback(&_class::_method, #_class "::" #_method, this); - -#define MCFG_I8275_DRQ_CALLBACK(_write) \ - downcast<i8275_device &>(*device).set_drq_wr_callback(DEVCB_##_write); - -#define MCFG_I8275_IRQ_CALLBACK(_write) \ - downcast<i8275_device &>(*device).set_irq_wr_callback(DEVCB_##_write); - -#define MCFG_I8275_HRTC_CALLBACK(_write) \ - downcast<i8275_device &>(*device).set_hrtc_wr_callback(DEVCB_##_write); - -#define MCFG_I8275_VRTC_CALLBACK(_write) \ - downcast<i8275_device &>(*device).set_vrtc_wr_callback(DEVCB_##_write); - - - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -96,10 +76,6 @@ public: set_display_callback(draw_character_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr))); } - template <class Object> devcb_base &set_drq_wr_callback(Object &&cb) { return m_write_drq.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_irq_wr_callback(Object &&cb) { return m_write_irq.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_hrtc_wr_callback(Object &&cb) { return m_write_hrtc.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_vrtc_wr_callback(Object &&cb) { return m_write_vrtc.set_callback(std::forward<Object>(cb)); } auto drq_wr_callback() { return m_write_drq.bind(); } auto irq_wr_callback() { return m_write_irq.bind(); } auto hrtc_wr_callback() { return m_write_hrtc.bind(); } diff --git a/src/devices/video/ims_cvc.cpp b/src/devices/video/ims_cvc.cpp index 60b76604ef5..14ae0901769 100644 --- a/src/devices/video/ims_cvc.cpp +++ b/src/devices/video/ims_cvc.cpp @@ -10,7 +10,7 @@ * http://bitsavers.org/components/inmos/graphics/72-TRN-204-01_Graphics_Databook_Second_Edition_1990.pdf * * TODO - * - everything (skeleton only) + * - cursor */ #include "emu.h" @@ -18,7 +18,10 @@ #include "screen.h" -#define VERBOSE 0 +#define LOG_GENERAL (1U << 0) +#define LOG_CONFIG (1U << 1) + +//#define VERBOSE (LOG_GENERAL|LOG_CONFIG) #include "logmacro.h" DEFINE_DEVICE_TYPE(G300, g300_device, "g300", "INMOS G300 Colour Video Controller") @@ -27,9 +30,9 @@ DEFINE_DEVICE_TYPE(G364, g364_device, "g364", "INMOS G364 Colour Video Controlle ims_cvc_device::ims_cvc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock) - , device_memory_interface(mconfig, *this) , device_palette_interface(mconfig, *this) - , m_space_config("shared", ENDIANNESS_LITTLE, 32, 24) + , m_screen(*this, finder_base::DUMMY_TAG) + , m_vram(*this, finder_base::DUMMY_TAG) { } @@ -40,11 +43,12 @@ g300_device::g300_device(const machine_config &mconfig, const char *tag, device_ g332_device::g332_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : ims_cvc_device(mconfig, type, tag, owner, clock) + , m_microport(*this, "microport") { } g332_device::g332_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : ims_cvc_device(mconfig, G332, tag, owner, clock) + : g332_device(mconfig, G332, tag, owner, clock) { } @@ -53,11 +57,9 @@ g364_device::g364_device(const machine_config &mconfig, const char *tag, device_ { } -device_memory_interface::space_config_vector ims_cvc_device::memory_space_config() const +void g332_device::device_add_mconfig(machine_config &config) { - return space_config_vector{ - std::make_pair(0, &m_space_config) - }; + ADDRESS_MAP_BANK(config, m_microport).set_map(&g332_device::microport_map).set_options(ENDIANNESS_LITTLE, 32, 32); } void g300_device::map(address_map &map) @@ -69,18 +71,18 @@ void g300_device::map(address_map &map) map(0x000 << shift, (0x0ff << shift) | 0x3).rw(FUNC(g300_device::colour_palette_r), FUNC(g300_device::colour_palette_w)); // data path registers - map(0x121, (0x121 << shift) | 0x3).rw(FUNC(g300_device::halfsync_r), FUNC(g300_device::halfsync_w)); - map(0x122, (0x122 << shift) | 0x3).rw(FUNC(g300_device::backporch_r), FUNC(g300_device::backporch_w)); - map(0x123, (0x123 << shift) | 0x3).rw(FUNC(g300_device::display_r), FUNC(g300_device::display_w)); - map(0x124, (0x124 << shift) | 0x3).rw(FUNC(g300_device::shortdisplay_r), FUNC(g300_device::shortdisplay_w)); - map(0x125, (0x125 << shift) | 0x3).rw(FUNC(g300_device::broadpulse_r), FUNC(g300_device::broadpulse_w)); - map(0x126, (0x126 << shift) | 0x3).rw(FUNC(g300_device::vsync_r), FUNC(g300_device::vsync_w)); - map(0x127, (0x127 << shift) | 0x3).rw(FUNC(g300_device::vblank_r), FUNC(g300_device::vblank_w)); - map(0x128, (0x128 << shift) | 0x3).rw(FUNC(g300_device::vdisplay_r), FUNC(g300_device::vdisplay_w)); - map(0x129, (0x129 << shift) | 0x3).rw(FUNC(g300_device::linetime_r), FUNC(g300_device::linetime_w)); - map(0x12a, (0x12a << shift) | 0x3).rw(FUNC(g300_device::tos_r), FUNC(g300_device::tos_w)); - map(0x12b, (0x12b << shift) | 0x3).rw(FUNC(g300_device::meminit_r), FUNC(g300_device::meminit_w)); - map(0x12c, (0x12c << shift) | 0x3).rw(FUNC(g300_device::transferdelay_r), FUNC(g300_device::transferdelay_w)); + map(0x121 << shift, (0x121 << shift) | 0x3).rw(FUNC(g300_device::halfsync_r), FUNC(g300_device::halfsync_w)); + map(0x122 << shift, (0x122 << shift) | 0x3).rw(FUNC(g300_device::backporch_r), FUNC(g300_device::backporch_w)); + map(0x123 << shift, (0x123 << shift) | 0x3).rw(FUNC(g300_device::display_r), FUNC(g300_device::display_w)); + map(0x124 << shift, (0x124 << shift) | 0x3).rw(FUNC(g300_device::shortdisplay_r), FUNC(g300_device::shortdisplay_w)); + map(0x125 << shift, (0x125 << shift) | 0x3).rw(FUNC(g300_device::broadpulse_r), FUNC(g300_device::broadpulse_w)); + map(0x126 << shift, (0x126 << shift) | 0x3).rw(FUNC(g300_device::vsync_r), FUNC(g300_device::vsync_w)); + map(0x127 << shift, (0x127 << shift) | 0x3).rw(FUNC(g300_device::vblank_r), FUNC(g300_device::vblank_w)); + map(0x128 << shift, (0x128 << shift) | 0x3).rw(FUNC(g300_device::vdisplay_r), FUNC(g300_device::vdisplay_w)); + map(0x129 << shift, (0x129 << shift) | 0x3).rw(FUNC(g300_device::linetime_r), FUNC(g300_device::linetime_w)); + map(0x12a << shift, (0x12a << shift) | 0x3).rw(FUNC(g300_device::tos_r), FUNC(g300_device::tos_w)); + map(0x12b << shift, (0x12b << shift) | 0x3).rw(FUNC(g300_device::meminit_r), FUNC(g300_device::meminit_w)); + map(0x12c << shift, (0x12c << shift) | 0x3).rw(FUNC(g300_device::transferdelay_r), FUNC(g300_device::transferdelay_w)); map(0x140 << shift, (0x140 << shift) | 0x3).rw(FUNC(g300_device::mask_r), FUNC(g300_device::mask_w)); map(0x160 << shift, (0x160 << shift) | 0x3).rw(FUNC(g300_device::control_r), FUNC(g300_device::control_w)); @@ -90,37 +92,45 @@ void g300_device::map(address_map &map) void g332_device::map(address_map &map) { - // datasheet gives unshifted addresses - const int shift = 2; // TODO: 64 bit mode + map(0x0000, 0x1fff).m(m_microport, FUNC(address_map_bank_device::amap32)); +} + +void g332_device::microport_map(address_map &map) +{ + // datasheet uses unshifted addresses: configure the device map for 64 bit + // address mode, bank device does handles additional shift for 32 bit mode + const int shift = 3; - map(0x000 << shift, (0x000 << shift) | 0x3).w(FUNC(g332_device::boot_w)); + map(0x000 << shift, (0x000 << shift) | 0x7).w(FUNC(g332_device::boot_w)); // data path registers - map(0x021, (0x021 << shift) | 0x3).rw(FUNC(g332_device::halfsync_r), FUNC(g332_device::halfsync_w)); - map(0x022, (0x022 << shift) | 0x3).rw(FUNC(g332_device::backporch_r), FUNC(g332_device::backporch_w)); - map(0x023, (0x023 << shift) | 0x3).rw(FUNC(g332_device::display_r), FUNC(g332_device::display_w)); - map(0x024, (0x024 << shift) | 0x3).rw(FUNC(g332_device::shortdisplay_r), FUNC(g332_device::shortdisplay_w)); - map(0x025, (0x025 << shift) | 0x3).rw(FUNC(g332_device::broadpulse_r), FUNC(g332_device::broadpulse_w)); - map(0x026, (0x026 << shift) | 0x3).rw(FUNC(g332_device::vsync_r), FUNC(g332_device::vsync_w)); - map(0x027, (0x027 << shift) | 0x3).rw(FUNC(g332_device::vpreequalise_r), FUNC(g332_device::vpreequalise_w)); - map(0x028, (0x028 << shift) | 0x3).rw(FUNC(g332_device::vpostequalise_r), FUNC(g332_device::vpostequalise_w)); - map(0x029, (0x029 << shift) | 0x3).rw(FUNC(g332_device::vblank_r), FUNC(g332_device::vblank_w)); - map(0x02a, (0x02a << shift) | 0x3).rw(FUNC(g332_device::vdisplay_r), FUNC(g332_device::vdisplay_w)); - map(0x02b, (0x02b << shift) | 0x3).rw(FUNC(g332_device::linetime_r), FUNC(g332_device::linetime_w)); - map(0x02c, (0x02c << shift) | 0x3).rw(FUNC(g332_device::linestart_r), FUNC(g332_device::linestart_w)); - map(0x02d, (0x02d << shift) | 0x3).rw(FUNC(g332_device::meminit_r), FUNC(g332_device::meminit_w)); - map(0x02e, (0x02e << shift) | 0x3).rw(FUNC(g332_device::transferdelay_r), FUNC(g332_device::transferdelay_w)); - - map(0x040 << shift, (0x040 << shift) | 0x3).rw(FUNC(g332_device::mask_r), FUNC(g332_device::mask_w)); - map(0x060 << shift, (0x060 << shift) | 0x3).rw(FUNC(g332_device::control_a_r), FUNC(g332_device::control_a_w)); - map(0x070 << shift, (0x070 << shift) | 0x3).rw(FUNC(g332_device::control_b_r), FUNC(g332_device::control_b_w)); - map(0x080 << shift, (0x080 << shift) | 0x3).rw(FUNC(g332_device::tos_r), FUNC(g332_device::tos_w)); + map(0x021 << shift, (0x021 << shift) | 0x7).rw(FUNC(g332_device::halfsync_r), FUNC(g332_device::halfsync_w)); + map(0x022 << shift, (0x022 << shift) | 0x7).rw(FUNC(g332_device::backporch_r), FUNC(g332_device::backporch_w)); + map(0x023 << shift, (0x023 << shift) | 0x7).rw(FUNC(g332_device::display_r), FUNC(g332_device::display_w)); + map(0x024 << shift, (0x024 << shift) | 0x7).rw(FUNC(g332_device::shortdisplay_r), FUNC(g332_device::shortdisplay_w)); + map(0x025 << shift, (0x025 << shift) | 0x7).rw(FUNC(g332_device::broadpulse_r), FUNC(g332_device::broadpulse_w)); + map(0x026 << shift, (0x026 << shift) | 0x7).rw(FUNC(g332_device::vsync_r), FUNC(g332_device::vsync_w)); + map(0x027 << shift, (0x027 << shift) | 0x7).rw(FUNC(g332_device::vpreequalise_r), FUNC(g332_device::vpreequalise_w)); + map(0x028 << shift, (0x028 << shift) | 0x7).rw(FUNC(g332_device::vpostequalise_r), FUNC(g332_device::vpostequalise_w)); + map(0x029 << shift, (0x029 << shift) | 0x7).rw(FUNC(g332_device::vblank_r), FUNC(g332_device::vblank_w)); + map(0x02a << shift, (0x02a << shift) | 0x7).rw(FUNC(g332_device::vdisplay_r), FUNC(g332_device::vdisplay_w)); + map(0x02b << shift, (0x02b << shift) | 0x7).rw(FUNC(g332_device::linetime_r), FUNC(g332_device::linetime_w)); + map(0x02c << shift, (0x02c << shift) | 0x7).rw(FUNC(g332_device::linestart_r), FUNC(g332_device::linestart_w)); + map(0x02d << shift, (0x02d << shift) | 0x7).rw(FUNC(g332_device::meminit_r), FUNC(g332_device::meminit_w)); + map(0x02e << shift, (0x02e << shift) | 0x7).rw(FUNC(g332_device::transferdelay_r), FUNC(g332_device::transferdelay_w)); + + map(0x040 << shift, (0x040 << shift) | 0x7).rw(FUNC(g332_device::mask_r), FUNC(g332_device::mask_w)); + map(0x060 << shift, (0x060 << shift) | 0x7).rw(FUNC(g332_device::control_a_r), FUNC(g332_device::control_a_w)); + map(0x070 << shift, (0x070 << shift) | 0x7).rw(FUNC(g332_device::control_b_r), FUNC(g332_device::control_b_w)); + map(0x080 << shift, (0x080 << shift) | 0x7).rw(FUNC(g332_device::tos_r), FUNC(g332_device::tos_w)); // cursor palette (0a1-0a3) + map(0x0a1 << shift, (0x0a3 << shift) | 0x7).rw(FUNC(g332_device::cursor_palette_r), FUNC(g332_device::cursor_palette_w)); + // checksum registers (0c0-0c2) // colour palette - map(0x100 << shift, (0x1ff << shift) | 0x3).rw(FUNC(g332_device::colour_palette_r), FUNC(g332_device::colour_palette_w)); + map(0x100 << shift, (0x1ff << shift) | 0x7).rw(FUNC(g332_device::colour_palette_r), FUNC(g332_device::colour_palette_w)); // cursor store (200-3ff) // cursor position (0c7) @@ -128,13 +138,208 @@ void g332_device::map(address_map &map) void ims_cvc_device::device_start() { - m_space = &space(0); + save_item(NAME(m_halfsync)); + save_item(NAME(m_backporch)); + save_item(NAME(m_display)); + save_item(NAME(m_shortdisplay)); + save_item(NAME(m_broadpulse)); + save_item(NAME(m_vsync)); + save_item(NAME(m_vblank)); + save_item(NAME(m_vdisplay)); + save_item(NAME(m_linetime)); + save_item(NAME(m_meminit)); + save_item(NAME(m_transferdelay)); + + save_item(NAME(m_mask)); + save_item(NAME(m_tos)); + save_item(NAME(m_boot)); } void ims_cvc_device::device_reset() { } -void ims_cvc_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +void g300_device::device_start() +{ + ims_cvc_device::device_start(); + + save_item(NAME(m_control)); +} + +void g332_device::device_start() +{ + ims_cvc_device::device_start(); + + save_item(NAME(m_vpreequalise)); + save_item(NAME(m_vpostequalise)); + save_item(NAME(m_linestart)); + save_item(NAME(m_control_a)); + save_item(NAME(m_control_b)); +} + +void g332_device::device_reset() +{ + m_control_a = 0; +} + +u32 g300_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + offs_t address = m_tos; + + for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) + for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x++) + bitmap.pix(y, x) = pen_color(m_vram->read(address++) & m_mask); + + return 0; +} + +u32 g332_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { + offs_t address = m_tos; + + switch (m_control_a & PIXEL_BITS) + { + case BPP_1: + for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) + for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 8) + { + u8 pixel_data = m_vram->read(address++); + + bitmap.pix(y, x + 0) = pen_color(pixel_data & 0x1 & m_mask); pixel_data >>= 1; + bitmap.pix(y, x + 1) = pen_color(pixel_data & 0x1 & m_mask); pixel_data >>= 1; + bitmap.pix(y, x + 2) = pen_color(pixel_data & 0x1 & m_mask); pixel_data >>= 1; + bitmap.pix(y, x + 3) = pen_color(pixel_data & 0x1 & m_mask); pixel_data >>= 1; + bitmap.pix(y, x + 4) = pen_color(pixel_data & 0x1 & m_mask); pixel_data >>= 1; + bitmap.pix(y, x + 5) = pen_color(pixel_data & 0x1 & m_mask); pixel_data >>= 1; + bitmap.pix(y, x + 6) = pen_color(pixel_data & 0x1 & m_mask); pixel_data >>= 1; + bitmap.pix(y, x + 7) = pen_color(pixel_data & 0x1 & m_mask); + } + break; + + case BPP_2: + for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) + for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 4) + { + u8 pixel_data = m_vram->read(address++); + + bitmap.pix(y, x + 0) = pen_color(pixel_data & 0x3 & m_mask); pixel_data >>= 2; + bitmap.pix(y, x + 1) = pen_color(pixel_data & 0x3 & m_mask); pixel_data >>= 2; + bitmap.pix(y, x + 2) = pen_color(pixel_data & 0x3 & m_mask); pixel_data >>= 2; + bitmap.pix(y, x + 3) = pen_color(pixel_data & 0x3 & m_mask); + } + break; + + case BPP_4: + for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) + for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 2) + { + u8 pixel_data = m_vram->read(address++); + + bitmap.pix(y, x + 0) = pen_color(pixel_data & 0xf & m_mask); pixel_data >>= 4; + bitmap.pix(y, x + 1) = pen_color(pixel_data & 0xf & m_mask); + } + break; + + case BPP_8: + for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) + for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x++) + bitmap.pix(y, x) = pen_color(m_vram->read(address++) & m_mask); + break; + } + + return 0; +} + +u32 ims_cvc_device::colour_palette_r(offs_t offset) +{ + return 0; +} + +void ims_cvc_device::colour_palette_w(offs_t offset, u32 data, u32 mem_mask) +{ + set_pen_color(offset >> 1, data >> 16, data >> 8, data >> 0); +} + +u32 g332_device::cursor_palette_r(offs_t offset) +{ + return 0; +} + +void g332_device::cursor_palette_w(offs_t offset, u32 data, u32 mem_mask) +{ + set_pen_color(256 + (offset >> 1), data >> 16, data >> 8, data >> 0); +} + +void g332_device::boot_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOG("boot_w %s clock, multiplier %d, %d bit alignment (%s)\n", + (data & PLL_SELECT) ? "PLL" : "external", (data & PLL_MULTIPLIER), + (data & ALIGN_64) ? 64 : 32, machine().describe_context()); + + m_microport->set_shift((data & ALIGN_64) ? 0 : 1); + + mem_mask &= 0x00ffffffU; + COMBINE_DATA(&m_boot); +} + +void g332_device::control_a_w(offs_t offset, u32 data, u32 mem_mask) +{ + LOG("control_a_w 0x%08x (%s)\n", data, machine().describe_context()); + + mem_mask &= 0x00ffffffU; + COMBINE_DATA(&m_control_a); + + if (data & VTG_ENABLE) + { + LOGMASKED(LOG_CONFIG, "VTG %s, %s, %s mode\n", + (data & VTG_ENABLE) ? "enabled" : "disabled", + (data & INTL_ENABLE) ? ((data & INTL_FORMAT) ? "interlaced (CCIR)" : "interlaced (EIA)") : "non-interlaced", + (data & SLAVE_MODE) ? "slave" : "master"); + + LOGMASKED(LOG_CONFIG, "%s sync, %s digital sync, analogue %s\n", + (data & SYNC_PATTERN) ? "plain" : "tesselated", + (data & SYNC_FORMAT) ? "separate" : "composite", + (data & VIDEO_FORMAT) ? "video only" : "composite video + sync"); + + LOGMASKED(LOG_CONFIG, "%s, CBlank is %s, %s, %s\n", + (data & BLANK_LEVEL) ? "blanking pedestal" : "no blank pedestal", + (data & BLANK_IO) ? "ouput" : "input", + (data & BLANK_FUNC) ? "undelayed ClkDisable" : "delayed CBlank", + (data & BLANK_FORCE) ? "screen blanked" : (data & BLANK_DISABLE) ? "blanking disabled" : "blanking enabled"); + + LOGMASKED(LOG_CONFIG, "address increment %d, DMA %s, sync delay %d cycles\n", + (data & ADDR_INC) == INC_1 ? 1 : + (data & ADDR_INC) == INC_256 ? (data & INTL_ENABLE) ? 2 : 256 : + (data & ADDR_INC) == INC_512 ? 512 : 1024, + (data & DMA_DISABLE) ? "disabled" : "enabled", + (data & SYNC_DELAY) >> 15); + + LOGMASKED(LOG_CONFIG, "interleave %s, pixel sampling %s, %s bits per pixel, cursor %s\n", + (data & INTERLEAVE) ? "enabled" : "disabled", + (data & SAMPLE_DELAY) ? "delayed" : "standard", + (data & PIXEL_BITS) == BPP_1 ? "1" : + (data & PIXEL_BITS) == BPP_2 ? "2" : + (data & PIXEL_BITS) == BPP_4 ? "4" : + (data & PIXEL_BITS) == BPP_8 ? "8" : + (data & PIXEL_BITS) == BPP_15 ? "15" : + (data & PIXEL_BITS) == BPP_16 ? "16" : "unknown", + (data & CURSOR_DISABLE) ? "disabled" : "enabled"); + + LOG("display %d vdisplay %d\n", m_display, m_vdisplay); + LOG("linetime %d halfsync %d backporch %d broadpulse %d\n", m_linetime, m_halfsync, m_backporch, m_broadpulse); + LOG("vsync %d vpreequalise %d vpostequalise %d vblank %d\n", m_vsync, m_vpreequalise, m_vpostequalise, m_vblank); + + int const hbend = (m_halfsync + m_halfsync + m_backporch) << 2; + int const vbend = (m_vpreequalise + m_vpostequalise + m_vsync + m_vblank) >> 1; + int const width = m_linetime << 2; + int const height = vbend + (m_vdisplay >> 1); + + rectangle const visarea(hbend, hbend + (m_display << 2) - 1, vbend, height - 1); + + u32 const dotclock = (m_boot & PLL_SELECT) ? clock() * (m_boot & PLL_MULTIPLIER) : clock(); + attotime const refresh = attotime::from_hz(dotclock / (width * height)); + + m_screen->configure(width, height, visarea, refresh.as_attoseconds()); + m_screen->reset_origin(); + } } diff --git a/src/devices/video/ims_cvc.h b/src/devices/video/ims_cvc.h index 25c0163642d..82acfe5c6eb 100644 --- a/src/devices/video/ims_cvc.h +++ b/src/devices/video/ims_cvc.h @@ -5,15 +5,22 @@ #pragma once -class ims_cvc_device : - public device_t, - public device_memory_interface, - public device_palette_interface +#include "machine/bankdev.h" +#include "machine/ram.h" + +class ims_cvc_device + : public device_t + , public device_palette_interface { public: - virtual void map(address_map &map) = 0; + static constexpr feature_type imperfect_features() { return feature::GRAPHICS; } + + // configuration + template <typename T> void set_screen(T &&tag) { m_screen.set_tag(std::forward<T>(tag)); } + template <typename T> void set_vram(T &&tag) { m_vram.set_tag(std::forward<T>(tag)); } - void screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + virtual void map(address_map &map) = 0; + virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) = 0; protected: ims_cvc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); @@ -22,51 +29,47 @@ protected: virtual void device_start() override; virtual void device_reset() override; - // device_memory_interface overrides - virtual space_config_vector memory_space_config() const override; - // device_palette_interface overrides - virtual u32 palette_entries() const override { return 256; } // FIXME + virtual u32 palette_entries() const override { return 256; } - u32 colour_palette_r(const offs_t offset) { return 0; } - void colour_palette_w(const offs_t offset, const u32 data) {} + u32 colour_palette_r(const offs_t offset); + void colour_palette_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU); u32 halfsync_r() { return m_halfsync; } - void halfsync_w(const u32 data) { m_halfsync = data; } + void halfsync_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_halfsync); } u32 backporch_r() { return m_backporch; } - void backporch_w(const u32 data) { m_backporch = data; } + void backporch_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_backporch); } u32 display_r() { return m_display; } - void display_w(const u32 data) { m_display = data; } + void display_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_display); } u32 shortdisplay_r() { return m_shortdisplay; } - void shortdisplay_w(const u32 data) { m_shortdisplay = data; } + void shortdisplay_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_shortdisplay); } u32 broadpulse_r() { return m_broadpulse; } - void broadpulse_w(const u32 data) { m_broadpulse = data; } + void broadpulse_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_broadpulse); } u32 vsync_r() { return m_vsync; } - void vsync_w(const u32 data) { m_vsync = data; } + void vsync_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_vsync); } u32 vblank_r() { return m_vblank; } - void vblank_w(const u32 data) { m_vblank = data; } + void vblank_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_vblank); } u32 vdisplay_r() { return m_vdisplay; } - void vdisplay_w(const u32 data) { m_vdisplay = data; } + void vdisplay_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_vdisplay); } u32 linetime_r() { return m_linetime; } - void linetime_w(const u32 data) { m_linetime = data; } + void linetime_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_linetime); } //u32 tos_r() { return m_tos; } //void tos_w(const u32 data) { m_tos = data; } u32 meminit_r() { return m_meminit; } - void meminit_w(const u32 data) { m_meminit = data; } + void meminit_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_meminit); } u32 transferdelay_r() { return m_transferdelay; } - void transferdelay_w(const u32 data) { m_transferdelay = data; } + void transferdelay_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_transferdelay); } u32 mask_r() { return m_mask; } - void mask_w(const u32 data) { m_mask = data; } + void mask_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_mask); } u32 tos_r() { return m_tos; } - void tos_w(const u32 data) { m_tos = data; } + void tos_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_tos); } - void boot_w(const u32 data) { m_boot = data; } + virtual void boot_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_boot); } -private: - // device_memory_interface members - const address_space_config m_space_config; - address_space *m_space; + required_device<screen_device> m_screen; + required_device<ram_device> m_vram; +protected: // device state u32 m_halfsync; u32 m_backporch; @@ -92,9 +95,13 @@ public: virtual void map(address_map &map) override; + virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) override; + protected: + virtual void device_start() override; + u32 control_r() { return m_control; } - void control_w(const u32 data) { m_control = data; } + void control_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_control); } private: u32 m_control; @@ -107,21 +114,86 @@ public: virtual void map(address_map &map) override; + virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) override; + + enum boot_mask : u32 + { + PLL_MULTIPLIER = 0x000001f, // pll multiplier + PLL_SELECT = 0x0000020, // pll clock select + ALIGN_64 = 0x0000040, // 64 bit address alignment + }; + + enum control_a_mask + { + VTG_ENABLE = 0x000001, // video timing generator enable + INTL_ENABLE = 0x000002, // interlace enable + INTL_FORMAT = 0x000004, // ccir/eia interlace format + SLAVE_MODE = 0x000008, // slave/master operating mode + SYNC_PATTERN = 0x000010, // plain/tesselated sync + SYNC_FORMAT = 0x000020, // separate/composite sync + VIDEO_FORMAT = 0x000040, // video only/composite video + sync + BLANK_LEVEL = 0x000080, // blanking pedestal/no blank pedestal + BLANK_IO = 0x000100, // CBlank is output/input + BLANK_FUNC = 0x000200, // undelayed ClkDisable/delayed CBlank + BLANK_FORCE = 0x000400, // screen blanked/no action + BLANK_DISABLE = 0x000800, // blanking disabled/enabled + ADDR_INC = 0x003000, // VRAM address increment + DMA_DISABLE = 0x004000, // DMA disabled/enabled + SYNC_DELAY = 0x038000, + INTERLEAVE = 0x040000, // interleave enabled/disabled + SAMPLE_DELAY = 0x080000, + PIXEL_BITS = 0x700000, // bits per pixel + CURSOR_DISABLE = 0x800000, // cursor disabled/enabled + }; + enum control_a_addr_inc_mask + { + INC_1 = 0x000000, + INC_256 = 0x001000, + INC_512 = 0x002000, + INC_1024 = 0x003000, + }; + enum control_a_bpp_mask + { + BPP_1 = 0x000000, + BPP_2 = 0x100000, + BPP_4 = 0x200000, + BPP_8 = 0x300000, + BPP_15 = 0x400000, + BPP_16 = 0x500000, + }; + protected: g332_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + // device_t overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + virtual void device_reset() override; + + // device_palette_interface overrides + virtual u32 palette_entries() const override { return 256 + 3; } + + virtual void microport_map(address_map &map); + + virtual void boot_w(offs_t offset, u32 data, u32 mem_mask = 0x00ffffffU) override; + + u32 cursor_palette_r(const offs_t offset); + void cursor_palette_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU); + u32 vpreequalise_r() { return m_vpreequalise; } - void vpreequalise_w(const u32 data) { m_vpreequalise = data; } + void vpreequalise_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_vpreequalise); } u32 vpostequalise_r() { return m_vpostequalise; } - void vpostequalise_w(const u32 data) { m_vpostequalise = data; } + void vpostequalise_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_vpostequalise); } u32 linestart_r() { return m_linestart; } - void linestart_w(const u32 data) { m_linestart = data; } + void linestart_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_linestart); } u32 control_a_r() { return m_control_a; } - void control_a_w(const u32 data) { m_control_a = data; } + void control_a_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU); u32 control_b_r() { return m_control_b; } - void control_b_w(const u32 data) { m_control_b = data; } + void control_b_w(offs_t offset, u32 data, u32 mem_mask = 0xffffffffU) { COMBINE_DATA(&m_control_b); } private: + required_device<address_map_bank_device> m_microport; + u32 m_vpreequalise; u32 m_vpostequalise; u32 m_linestart; diff --git a/src/devices/video/jangou_blitter.h b/src/devices/video/jangou_blitter.h index 3ff34b50ae7..8bf4f4a56ec 100644 --- a/src/devices/video/jangou_blitter.h +++ b/src/devices/video/jangou_blitter.h @@ -7,14 +7,6 @@ #pragma once - -//************************************************************************** -// INTERFACE CONFIGURATION MACROS -//************************************************************************** - -#define MCFG_JANGOU_BLITTER_ADD(_tag,_freq) \ - MCFG_DEVICE_ADD(_tag, JANGOU_BLITTER, _freq) - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** diff --git a/src/devices/video/m50458.cpp b/src/devices/video/m50458.cpp index 41a6bd1651f..59e0f44cc43 100644 --- a/src/devices/video/m50458.cpp +++ b/src/devices/video/m50458.cpp @@ -31,15 +31,18 @@ DEFINE_DEVICE_TYPE(M50458, m50458_device, "m50458", "Mitsubishi M50458 OSD") void m50458_device::m50458_vram(address_map &map) { - map(0x0000, 0x023f).ram(); // vram - map(0x0240, 0x0241).w(FUNC(m50458_device::vreg_120_w)); - map(0x0242, 0x0243).w(FUNC(m50458_device::vreg_121_w)); - map(0x0244, 0x0245).w(FUNC(m50458_device::vreg_122_w)); - map(0x0246, 0x0247).w(FUNC(m50458_device::vreg_123_w)); - map(0x0248, 0x0249).w(FUNC(m50458_device::vreg_124_w)); - map(0x024a, 0x024b).w(FUNC(m50458_device::vreg_125_w)); - map(0x024c, 0x024d).w(FUNC(m50458_device::vreg_126_w)); - map(0x024e, 0x024f).w(FUNC(m50458_device::vreg_127_w)); + if (!has_configured_map(0)) + { + map(0x0000, 0x023f).ram(); // vram + map(0x0240, 0x0241).w(FUNC(m50458_device::vreg_120_w)); + map(0x0242, 0x0243).w(FUNC(m50458_device::vreg_121_w)); + map(0x0244, 0x0245).w(FUNC(m50458_device::vreg_122_w)); + map(0x0246, 0x0247).w(FUNC(m50458_device::vreg_123_w)); + map(0x0248, 0x0249).w(FUNC(m50458_device::vreg_124_w)); + map(0x024a, 0x024b).w(FUNC(m50458_device::vreg_125_w)); + map(0x024c, 0x024d).w(FUNC(m50458_device::vreg_126_w)); + map(0x024e, 0x024f).w(FUNC(m50458_device::vreg_127_w)); + } } // internal GFX ROM (TODO: GFXs in here should be 12x18, not 16x18) @@ -180,7 +183,7 @@ m50458_device::m50458_device(const machine_config &mconfig, const char *tag, dev : device_t(mconfig, M50458, tag, owner, clock) , device_memory_interface(mconfig, *this) , device_video_interface(mconfig, *this) - , m_space_config("videoram", ENDIANNESS_LITTLE, 16, 16, 0, address_map_constructor(), address_map_constructor(FUNC(m50458_device::m50458_vram), this)) + , m_space_config("videoram", ENDIANNESS_LITTLE, 16, 16, 0, address_map_constructor(FUNC(m50458_device::m50458_vram), this)) { } diff --git a/src/devices/video/m50458.h b/src/devices/video/m50458.h index 5be6ceaf08c..07113a93afe 100644 --- a/src/devices/video/m50458.h +++ b/src/devices/video/m50458.h @@ -12,16 +12,6 @@ Mitsubishi M50458 OSD chip #pragma once - -//************************************************************************** -// INTERFACE CONFIGURATION MACROS -//************************************************************************** - -#define MCFG_M50458_ADD(_tag,_freq,_screen) \ - MCFG_DEVICE_ADD(_tag, M50458,_freq) \ - MCFG_VIDEO_SET_SCREEN(_screen) - - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -34,6 +24,13 @@ class m50458_device : public device_t, { public: // construction/destruction + template <typename T> + m50458_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&screen_tag) + : m50458_device(mconfig, tag, owner, clock) + { + set_screen(std::forward<T>(screen_tag)); + } + m50458_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // I/O operations diff --git a/src/devices/video/mb88303.h b/src/devices/video/mb88303.h index 9c088d8d56b..f8804adff61 100644 --- a/src/devices/video/mb88303.h +++ b/src/devices/video/mb88303.h @@ -26,21 +26,6 @@ #pragma once - -//************************************************************************** -// INTERFACE CONFIGURATION MACROS -//************************************************************************** - -#define MCFG_MB88303_VOW_CALLBACK(_write) \ - downcast<mb88303_device &>(*device).set_vow_callback(DEVCB_##_write); - -#define MCFG_MB88303_VOBN_CALLBACK(_write) \ - downcast<mb88303_device &>(*device).set_vob_n_callback(DEVCB_##_write); - -#define MCFG_MB88303_DO_CALLBACK(_write) \ - downcast<mb88303_device &>(*device).set_do_callback(DEVCB_##_write); - - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -56,9 +41,9 @@ public: // construction/destruction mb88303_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template <class Object> devcb_base &set_vow_callback(Object &&cb) { return m_write_vow.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_vobn_callback(Object &&cb) { return m_write_vobn.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_do_callback(Object &&cb) { return m_write_do.set_callback(std::forward<Object>(cb)); } + auto vow_callback() { return m_write_vow.bind(); } + auto vobn_callback() { return m_write_vobn.bind(); } + auto do_callback() { return m_write_do.bind(); } DECLARE_WRITE8_MEMBER(da_w); DECLARE_WRITE_LINE_MEMBER(adm_w); diff --git a/src/devices/video/mb90082.cpp b/src/devices/video/mb90082.cpp index a3026aeb179..957669fb48b 100644 --- a/src/devices/video/mb90082.cpp +++ b/src/devices/video/mb90082.cpp @@ -25,10 +25,13 @@ DEFINE_DEVICE_TYPE(MB90082, mb90082_device, "mb90082", "Fujitsu MB90082 OSD") void mb90082_device::mb90082_vram(address_map &map) { - map(0x0000, 0x023f).ram(); // main screen vram - map(0x0400, 0x063f).ram(); // main screen attr + if (!has_configured_map(0)) + { + map(0x0000, 0x023f).ram(); // main screen vram + map(0x0400, 0x063f).ram(); // main screen attr // AM_RANGE(0x0800, 0x0a3f) AM_RAM // sub screen vram // AM_RANGE(0x0c00, 0x0e3f) AM_RAM // sub screen attr + } } /* charset is undumped, but apparently a normal ASCII one is enough for the time being (for example "fnt0808.x1" in Sharp X1) */ @@ -91,7 +94,7 @@ inline void mb90082_device::write_word(offs_t address, uint16_t data) mb90082_device::mb90082_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, MB90082, tag, owner, clock) , device_memory_interface(mconfig, *this) - , m_space_config("videoram", ENDIANNESS_LITTLE, 16, 16, 0, address_map_constructor(), address_map_constructor(FUNC(mb90082_device::mb90082_vram), this)) + , m_space_config("videoram", ENDIANNESS_LITTLE, 16, 16, 0, address_map_constructor(FUNC(mb90082_device::mb90082_vram), this)) { } diff --git a/src/devices/video/mb90082.h b/src/devices/video/mb90082.h index 3fa203f385f..5c6d2c46df3 100644 --- a/src/devices/video/mb90082.h +++ b/src/devices/video/mb90082.h @@ -12,14 +12,6 @@ #pragma once - -//************************************************************************** -// INTERFACE CONFIGURATION MACROS -//************************************************************************** - -#define MCFG_MB90082_ADD(_tag,_freq) \ - MCFG_DEVICE_ADD(_tag, MB90082, _freq) - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** diff --git a/src/devices/video/mb_vcu.cpp b/src/devices/video/mb_vcu.cpp index 8d0f921be12..96acc945359 100644 --- a/src/devices/video/mb_vcu.cpp +++ b/src/devices/video/mb_vcu.cpp @@ -38,16 +38,20 @@ DEFINE_DEVICE_TYPE(MB_VCU, mb_vcu_device, "mb_vcu", "Mazer Blazer custom VCU") void mb_vcu_device::mb_vcu_vram(address_map &map) { - map(0x00000, 0x7ffff).ram(); // enough for a 256x256x4 x 2 pages of framebuffer with 4 layers (TODO: doubled for simplicity) + if (!has_configured_map(0)) + map(0x00000, 0x7ffff).ram(); // enough for a 256x256x4 x 2 pages of framebuffer with 4 layers (TODO: doubled for simplicity) } void mb_vcu_device::mb_vcu_pal_ram(address_map &map) { - map(0x0000, 0x00ff).ram(); - map(0x0200, 0x02ff).ram(); - map(0x0400, 0x04ff).ram(); - map(0x0600, 0x06ff).rw(FUNC(mb_vcu_device::mb_vcu_paletteram_r), FUNC(mb_vcu_device::mb_vcu_paletteram_w)); + if (!has_configured_map(1)) + { + map(0x0000, 0x00ff).ram(); + map(0x0200, 0x02ff).ram(); + map(0x0400, 0x04ff).ram(); + map(0x0600, 0x06ff).rw(FUNC(mb_vcu_device::mb_vcu_paletteram_r), FUNC(mb_vcu_device::mb_vcu_paletteram_w)); + } } READ8_MEMBER( mb_vcu_device::mb_vcu_paletteram_r ) @@ -64,19 +68,19 @@ WRITE8_MEMBER( mb_vcu_device::mb_vcu_paletteram_w ) /* red component */ bit1 = (m_palram[offset] >> 7) & 0x01; bit0 = (m_palram[offset] >> 6) & 0x01; - r = combine_2_weights(m_weights_r, bit0, bit1); + r = combine_weights(m_weights_r, bit0, bit1); /* green component */ bit2 = (m_palram[offset] >> 5) & 0x01; bit1 = (m_palram[offset] >> 4) & 0x01; bit0 = (m_palram[offset] >> 3) & 0x01; - g = combine_3_weights(m_weights_g, bit0, bit1, bit2); + g = combine_weights(m_weights_g, bit0, bit1, bit2); /* blue component */ bit2 = (m_palram[offset] >> 2) & 0x01; bit1 = (m_palram[offset] >> 1) & 0x01; bit0 = (m_palram[offset] >> 0) & 0x01; - b = combine_3_weights(m_weights_b, bit0, bit1, bit2); + b = combine_weights(m_weights_b, bit0, bit1, bit2); m_palette->set_pen_color(offset, rgb_t(r, g, b)); } @@ -147,8 +151,8 @@ mb_vcu_device::mb_vcu_device(const machine_config &mconfig, const char *tag, dev : device_t(mconfig, MB_VCU, tag, owner, clock) , device_memory_interface(mconfig, *this) , device_video_interface(mconfig, *this) - , m_videoram_space_config("videoram", ENDIANNESS_LITTLE, 8, 19, 0, address_map_constructor(), address_map_constructor(FUNC(mb_vcu_device::mb_vcu_vram), this)) - , m_paletteram_space_config("palram", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(), address_map_constructor(FUNC(mb_vcu_device::mb_vcu_pal_ram), this)) + , m_videoram_space_config("videoram", ENDIANNESS_LITTLE, 8, 19, 0, address_map_constructor(FUNC(mb_vcu_device::mb_vcu_vram), this)) + , m_paletteram_space_config("palram", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(FUNC(mb_vcu_device::mb_vcu_pal_ram), this)) , m_cpu(*this, finder_base::DUMMY_TAG) , m_palette(*this, finder_base::DUMMY_TAG) { @@ -474,19 +478,19 @@ WRITE8_MEMBER( mb_vcu_device::background_color_w ) /* red component */ bit1 = (m_bk_color >> 7) & 0x01; bit0 = (m_bk_color >> 6) & 0x01; - r = combine_2_weights(m_weights_r, bit0, bit1); + r = combine_weights(m_weights_r, bit0, bit1); /* green component */ bit2 = (m_bk_color >> 5) & 0x01; bit1 = (m_bk_color >> 4) & 0x01; bit0 = (m_bk_color >> 3) & 0x01; - g = combine_3_weights(m_weights_g, bit0, bit1, bit2); + g = combine_weights(m_weights_g, bit0, bit1, bit2); /* blue component */ bit2 = (m_bk_color >> 2) & 0x01; bit1 = (m_bk_color >> 1) & 0x01; bit0 = (m_bk_color >> 0) & 0x01; - b = combine_3_weights(m_weights_b, bit0, bit1, bit2); + b = combine_weights(m_weights_b, bit0, bit1, bit2); m_palette->set_pen_color(0x100, rgb_t(r, g, b)); } diff --git a/src/devices/video/mb_vcu.h b/src/devices/video/mb_vcu.h index a8b53637a7d..90f0eea422a 100644 --- a/src/devices/video/mb_vcu.h +++ b/src/devices/video/mb_vcu.h @@ -23,8 +23,8 @@ public: mb_vcu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // configuration - void set_palette_tag(const char *tag) { m_palette.set_tag(tag); } - void set_cpu_tag(const char *tag) { m_cpu.set_tag(tag); } + template <typename T> void set_palette_tag(T &&tag) { m_palette.set_tag(std::forward<T>(tag)); } + template <typename T> void set_cpu_tag(T &&tag) { m_cpu.set_tag(std::forward<T>(tag)); } // I/O operations DECLARE_WRITE8_MEMBER( write_vregs ); @@ -86,15 +86,4 @@ private: // device type definition DECLARE_DEVICE_TYPE(MB_VCU, mb_vcu_device) - -//************************************************************************** -// INTERFACE CONFIGURATION MACROS -//************************************************************************** - -#define MCFG_MB_VCU_CPU(_tag) \ - downcast<mb_vcu_device &>(*device).set_cpu_tag(_tag); - -#define MCFG_MB_VCU_PALETTE(_palette_tag) \ - downcast<mb_vcu_device &>(*device).set_palette_tag(_palette_tag); - #endif // MAME_VIDEO_MB_VCU_H diff --git a/src/devices/video/mc6845.cpp b/src/devices/video/mc6845.cpp index 13c1c8a6155..82ec8408130 100644 --- a/src/devices/video/mc6845.cpp +++ b/src/devices/video/mc6845.cpp @@ -129,13 +129,13 @@ void mc6845_device::call_on_update_address(int strobe) } -void mc6845_device::write_address(uint8_t data) +void mc6845_device::address_w(uint8_t data) { m_register_address_latch = data & 0x1f; } -uint8_t mc6845_device::read_status() +uint8_t mc6845_device::status_r() { uint8_t ret = 0; @@ -178,7 +178,7 @@ void mc6845_device::transparent_update() } -uint8_t mc6845_device::read_register() +uint8_t mc6845_device::register_r() { uint8_t ret = 0; @@ -200,7 +200,7 @@ uint8_t mc6845_device::read_register() } -void mc6845_device::write_register(uint8_t data) +void mc6845_device::register_w(uint8_t data) { LOG("%s:M6845 reg 0x%02x = 0x%02x\n", machine().describe_context(), m_register_address_latch, data); @@ -253,13 +253,13 @@ void mc6845_device::write_register(uint8_t data) } -WRITE8_MEMBER( mos8563_device::address_w ) +void mos8563_device::address_w(uint8_t data) { m_register_address_latch = data & 0x3f; } -READ8_MEMBER( mos8563_device::status_r ) +uint8_t mos8563_device::status_r() { uint8_t ret = m_revision; @@ -279,7 +279,7 @@ READ8_MEMBER( mos8563_device::status_r ) } -READ8_MEMBER( mos8563_device::register_r ) +uint8_t mos8563_device::register_r() { uint8_t ret = 0xff; @@ -329,7 +329,7 @@ READ8_MEMBER( mos8563_device::register_r ) } -WRITE8_MEMBER( mos8563_device::register_w ) +void mos8563_device::register_w(uint8_t data) { LOG("%s:MOS8563 reg 0x%02x = 0x%02x\n", machine().describe_context(), m_register_address_latch, data); @@ -392,13 +392,13 @@ WRITE8_MEMBER( mos8563_device::register_w ) recompute_parameters(false); } -WRITE8_MEMBER( hd6345_device::address_w ) +void hd6345_device::address_w(uint8_t data) { m_register_address_latch = data & 0x3f; } -READ8_MEMBER( hd6345_device::register_r ) +uint8_t hd6345_device::register_r() { uint8_t ret = 0xff; @@ -416,7 +416,7 @@ READ8_MEMBER( hd6345_device::register_r ) return ret; } -WRITE8_MEMBER( hd6345_device::register_w ) +void hd6345_device::register_w(uint8_t data) { LOG("%s:HD6345 reg 0x%02x = 0x%02x\n", machine().describe_context(), m_register_address_latch, data); @@ -582,7 +582,7 @@ void mc6845_device::recompute_parameters(bool postload) m_hsync_off_pos = hsync_off_pos; m_vsync_on_pos = vsync_on_pos; m_vsync_off_pos = vsync_off_pos; - if (!postload) // set m_line_counter to 0 on normal operation, but not on postload + if ( (!m_reconfigure_cb.isnull()) && (!postload) ) m_line_counter = 0; } } @@ -659,6 +659,28 @@ void mc6845_device::update_upd_adr_timer() } +bool mc6845_device::match_line() +{ + /* Check if we've reached the end of active display */ + if ( m_line_counter == m_vert_disp ) + { + m_line_enable_ff = false; + m_current_disp_addr = m_disp_start_addr; + } + + /* Check if VSYNC should be enabled */ + if ( m_line_counter == m_vert_sync_pos ) + { + m_vsync_width_counter = 0; + m_vsync_ff = 1; + + return true; + } + + return false; +} + + void mc6845_device::handle_line_timer() { bool new_vsync = m_vsync; @@ -698,21 +720,8 @@ void mc6845_device::handle_line_timer() m_line_counter = ( m_line_counter + 1 ) & 0x7F; m_line_address = ( m_line_address + m_horiz_disp ) & 0x3fff; - /* Check if we've reached the end of active display */ - if ( m_line_counter == m_vert_disp ) - { - m_line_enable_ff = false; - m_current_disp_addr = m_disp_start_addr; - } - - /* Check if VSYNC should be enabled */ - if ( m_line_counter == m_vert_sync_pos ) - { - m_vsync_width_counter = 0; - m_vsync_ff = 1; - + if (match_line()) new_vsync = true; - } } else { @@ -731,6 +740,13 @@ void mc6845_device::handle_line_timer() m_line_counter = 0; m_line_address = m_disp_start_addr; m_line_enable_ff = true; + + if (m_supports_vert_sync_width) + { + if (match_line()) + new_vsync = true; + } + /* also update the cursor state now */ update_cursor_state(); @@ -1438,7 +1454,8 @@ device_memory_interface::space_config_vector mos8563_device::memory_space_config // default address maps void mos8563_device::mos8563_videoram_map(address_map &map) { - map(0x0000, 0xffff).ram(); + if (!has_configured_map(0)) + map(0x0000, 0xffff).ram(); } @@ -1505,7 +1522,7 @@ mos8563_device::mos8563_device(const machine_config &mconfig, device_type type, : mc6845_device(mconfig, type, tag, owner, clock), device_memory_interface(mconfig, *this), device_palette_interface(mconfig, *this), - m_videoram_space_config("videoram", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(), address_map_constructor(FUNC(mos8563_device::mos8563_videoram_map), this)) + m_videoram_space_config("videoram", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(FUNC(mos8563_device::mos8563_videoram_map), this)) { set_clock_scale(1.0/8); } diff --git a/src/devices/video/mc6845.h b/src/devices/video/mc6845.h index 1233651e07b..1bb0683ee85 100644 --- a/src/devices/video/mc6845.h +++ b/src/devices/video/mc6845.h @@ -61,20 +61,16 @@ public: auto out_vsync_callback() { return m_out_vsync_cb.bind(); } /* select one of the registers for reading or writing */ - DECLARE_WRITE8_MEMBER( address_w ) { write_address(data); } - void write_address(uint8_t data); + void address_w(uint8_t data); /* read from the status register */ - DECLARE_READ8_MEMBER( status_r ) { return read_status(); } - uint8_t read_status(); + uint8_t status_r(); /* read from the currently selected register */ - DECLARE_READ8_MEMBER( register_r ) { return read_register(); } - uint8_t read_register(); + uint8_t register_r(); /* write to the currently selected register */ - DECLARE_WRITE8_MEMBER( register_w ) { write_register(data); } - void write_register(uint8_t data); + void register_w(uint8_t data); // read display enable line state DECLARE_READ_LINE_MEMBER( de_r ); @@ -215,6 +211,7 @@ protected: void set_hsync(int state); void set_vsync(int state); void set_cur(int state); + bool match_line(); void handle_line_timer(); virtual void update_cursor_state(); virtual uint8_t draw_scanline(int y, bitmap_rgb32 &bitmap, const rectangle &cliprect); @@ -347,9 +344,9 @@ class hd6345_device : public mc6845_device public: hd6345_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - DECLARE_WRITE8_MEMBER(address_w); - DECLARE_READ8_MEMBER(register_r); - DECLARE_WRITE8_MEMBER(register_w); + void address_w(uint8_t data); + uint8_t register_r(); + void register_w(uint8_t data); protected: virtual void device_start() override; @@ -383,10 +380,10 @@ class mos8563_device : public mc6845_device, public: mos8563_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - DECLARE_WRITE8_MEMBER( address_w ); - DECLARE_READ8_MEMBER( status_r ); - DECLARE_READ8_MEMBER( register_r ); - DECLARE_WRITE8_MEMBER( register_w ); + void address_w(uint8_t data); + uint8_t status_r(); + uint8_t register_r(); + void register_w(uint8_t data); inline uint8_t read_videoram(offs_t offset); inline void write_videoram(offs_t offset, uint8_t data); diff --git a/src/devices/video/mc6847.cpp b/src/devices/video/mc6847.cpp index 84b48bc1526..4ef156632b0 100644 --- a/src/devices/video/mc6847.cpp +++ b/src/devices/video/mc6847.cpp @@ -132,14 +132,14 @@ const uint32_t mc6847_base_device::s_palette[mc6847_base_device::PALETTE_LENGTH] mc6847_friend_device::mc6847_friend_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const uint8_t *fontdata, bool is_mc6847t1, double tpfs, int field_sync_falling_edge_scanline, int divider, bool supports_partial_body_scanlines) : device_t(mconfig, type, tag, owner, clock) + , device_video_interface(mconfig, *this) , m_write_hsync(*this) , m_write_fsync(*this) , m_character_map(fontdata, is_mc6847t1) + , m_tpfs(tpfs) + , m_divider(divider) + , m_supports_partial_body_scanlines(supports_partial_body_scanlines) { - m_tpfs = tpfs; - m_divider = divider; - m_supports_partial_body_scanlines = supports_partial_body_scanlines; - // The MC6847 and the GIME apply field sync on different scanlines m_field_sync_falling_edge_scanline = field_sync_falling_edge_scanline; } @@ -577,6 +577,31 @@ void mc6847_base_device::setup_fixed_mode() //------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void mc6847_base_device::device_config_complete() +{ + if (!has_screen()) + return; + + if (!screen().refresh_attoseconds()) + { + // FIXME: use correct raw parameters rather than this nonsense + screen().set_refresh_hz(m_tpfs > 310.0 ? 50 : 60); + screen().set_size(320, 243); + screen().set_visarea(0, 320-1, 1, 241-1); + screen().set_vblank_time(0); + } + + if (!screen().has_screen_update()) + screen().set_screen_update(screen_update_rgb32_delegate(FUNC(mc6847_base_device::screen_update), this)); +} + + +//------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- diff --git a/src/devices/video/mc6847.h b/src/devices/video/mc6847.h index 3868420280b..b9e8e02ed4c 100644 --- a/src/devices/video/mc6847.h +++ b/src/devices/video/mc6847.h @@ -19,41 +19,6 @@ // MC6847 CONFIGURATION / INTERFACE //************************************************************************** -#define MCFG_SCREEN_MC6847_NTSC_ADD(_tag, _mctag) \ - MCFG_SCREEN_ADD(_tag, RASTER) \ - MCFG_SCREEN_UPDATE_DEVICE(_mctag, mc6847_base_device, screen_update) \ - MCFG_SCREEN_REFRESH_RATE(60) \ - MCFG_SCREEN_SIZE(320, 243) \ - MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 1, 241-1) \ - MCFG_SCREEN_VBLANK_TIME(0) - -#define MCFG_SCREEN_MC6847_PAL_ADD(_tag, _mctag) \ - MCFG_SCREEN_ADD(_tag, RASTER) \ - MCFG_SCREEN_UPDATE_DEVICE(_mctag, mc6847_base_device, screen_update) \ - MCFG_SCREEN_REFRESH_RATE(50) \ - MCFG_SCREEN_SIZE(320, 243) \ - MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 1, 241-1) \ - MCFG_SCREEN_VBLANK_TIME(0) - -#define MCFG_MC6847_HSYNC_CALLBACK(_write) \ - downcast<mc6847_friend_device &>(*device).set_hsync_wr_callback(DEVCB_##_write); - -#define MCFG_MC6847_FSYNC_CALLBACK(_write) \ - downcast<mc6847_friend_device &>(*device).set_fsync_wr_callback(DEVCB_##_write); - -#define MCFG_MC6847_CHARROM_CALLBACK(_class, _method) \ - downcast<mc6847_friend_device &>(*device).set_get_char_rom(mc6847_friend_device::get_char_rom_delegate(&_class::_method, #_class "::" #_method, this)); - -#define MCFG_MC6847_INPUT_CALLBACK(_read) \ - downcast<mc6847_base_device &>(*device).set_input_callback(DEVCB_##_read); - -#define MCFG_MC6847_FIXED_MODE(_mode) \ - downcast<mc6847_base_device &>(*device).set_get_fixed_mode(_mode); - -#define MCFG_MC6847_BW(_bw) \ - downcast<mc6847_base_device &>(*device).set_black_and_white(_bw); - - #define MC6847_GET_CHARROM_MEMBER(_name) uint8_t _name(uint8_t ch, int line) @@ -67,7 +32,7 @@ INPUT_PORTS_EXTERN(mc6847_artifacting); //************************************************************************** // base class so that the GIME emulation can access mc6847 stuff -class mc6847_friend_device : public device_t +class mc6847_friend_device : public device_t, public device_video_interface { public: // video mode constants @@ -86,12 +51,19 @@ public: bool hs_r() const { return m_horizontal_sync; } bool fs_r() const { return m_field_sync; } - template <class Object> devcb_base &set_hsync_wr_callback(Object &&cb) { return m_write_hsync.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_fsync_wr_callback(Object &&cb) { return m_write_fsync.set_callback(std::forward<Object>(cb)); } auto hsync_wr_callback() { return m_write_hsync.bind(); } auto fsync_wr_callback() { return m_write_fsync.bind(); } template <typename Object> void set_get_char_rom(Object &&cb) { m_charrom_cb = std::forward<Object>(cb); } + void set_get_char_rom(get_char_rom_delegate cb) { m_charrom_cb = cb; } + template <class FunctionClass> void set_get_char_rom(const char *devname, uint8_t (FunctionClass::*cb)(uint8_t, int), const char *name) + { + set_get_char_rom(get_char_rom_delegate(cb, name, devname, static_cast<FunctionClass *>(nullptr))); + } + template <class FunctionClass> void set_get_char_rom(uint8_t (FunctionClass::*cb)(uint8_t, int), const char *name) + { + set_get_char_rom(get_char_rom_delegate(cb, name, nullptr, static_cast<FunctionClass *>(nullptr))); + } protected: mc6847_friend_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, @@ -479,16 +451,19 @@ private: emu_timer *m_hsync_off_timer; emu_timer *m_fsync_timer; +protected: + const double m_tpfs; + +private: // incidentals - double m_tpfs; - int m_divider; + const int m_divider; int m_field_sync_falling_edge_scanline; bool m_wide; bool m_video_changed; uint16_t m_top_border_scanlines; uint16_t m_body_scanlines; bool m_recording_scanline; - bool m_supports_partial_body_scanlines; + const bool m_supports_partial_body_scanlines; // video state uint16_t m_physical_scanline; @@ -513,7 +488,6 @@ private: class mc6847_base_device : public mc6847_friend_device { public: - template <class Object> devcb_base &set_input_callback(Object &&cb) { return m_input_cb.set_callback(std::forward<Object>(cb)); } auto input_callback() { return m_input_cb.bind(); } void set_get_fixed_mode(uint8_t mode) { m_fixed_mode = mode; } @@ -524,18 +498,6 @@ public: updating is complete, end_update() */ uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - template <typename T, typename U> - static screen_device &add_pal_screen(machine_config &config, T &&screen_tag, U &&mc_tag) - { - screen_device &screen(SCREEN(config, std::forward<T>(screen_tag), SCREEN_TYPE_RASTER)); - screen.set_screen_update(std::forward<U>(mc_tag), FUNC(mc6847_base_device::screen_update)); - screen.set_refresh_hz(50); - screen.set_size(320, 243); - screen.set_visarea(0, 320-1, 1, 241-1); - screen.set_vblank_time(0); - return screen; - } - // mode changing operations DECLARE_WRITE_LINE_MEMBER( ag_w ) { change_mode(MODE_AG, state); } DECLARE_WRITE_LINE_MEMBER( gm2_w ) { change_mode(MODE_GM2, state); } @@ -550,6 +512,7 @@ protected: mc6847_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const uint8_t *fontdata, double tpfs); // device-level overrides + virtual void device_config_complete() override; virtual void device_start() override; virtual void device_reset() override; virtual ioport_constructor device_input_ports() const override; diff --git a/src/devices/video/mm5445.cpp b/src/devices/video/mm5445.cpp new file mode 100644 index 00000000000..6b857ed19b3 --- /dev/null +++ b/src/devices/video/mm5445.cpp @@ -0,0 +1,106 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + National Semiconductor MM5445 series VFD Driver + + TODO: + - brightness control input pin (sets output voltage level) + +*/ + +#include "emu.h" +#include "video/mm5445.h" + + +DEFINE_DEVICE_TYPE(MM5445, mm5445_device, "mm5445", "MM5445 VFD Driver") +DEFINE_DEVICE_TYPE(MM5446, mm5446_device, "mm5446", "MM5446 VFD Driver") +DEFINE_DEVICE_TYPE(MM5447, mm5447_device, "mm5447", "MM5447 VFD Driver") +DEFINE_DEVICE_TYPE(MM5448, mm5448_device, "mm5448", "MM5448 VFD Driver") + +//------------------------------------------------- +// constructor +//------------------------------------------------- + +mm5445_device::mm5445_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 outpins) : + device_t(mconfig, type, tag, owner, clock), + m_outmask((u64(1) << outpins) - 1), + m_write_output(*this) +{ } + +mm5445_device::mm5445_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + mm5445_device(mconfig, MM5445, tag, owner, clock, 33) +{ } + +mm5446_device::mm5446_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + mm5445_device(mconfig, MM5446, tag, owner, clock, 34) +{ } + +mm5447_device::mm5447_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + mm5445_device(mconfig, MM5447, tag, owner, clock, 34) +{ } + +mm5448_device::mm5448_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + mm5445_device(mconfig, MM5448, tag, owner, clock, 35) +{ } + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void mm5445_device::device_start() +{ + // resolve callbacks + m_write_output.resolve_safe(); + + // zerofill + m_clk = 0; + m_enable = 0; + m_data = 0; + m_shiftreg = 0; + m_shiftcount = 0; + + // register for savestates + save_item(NAME(m_clk)); + save_item(NAME(m_enable)); + save_item(NAME(m_data)); + save_item(NAME(m_shiftreg)); + save_item(NAME(m_shiftcount)); +} + + +//------------------------------------------------- +// handlers +//------------------------------------------------- + +WRITE_LINE_MEMBER(mm5445_device::clock_w) +{ + state = (state) ? 1 : 0; + bool rise = state && !m_clk; + m_clk = state; + + // clock on rising edge + if (rise) + { + u64 data_in = u64(m_data & ~m_enable) << 34; + u64 lead_in = ~m_shiftreg & data_in; + m_shiftreg = (m_shiftreg & ((u64(1) << 34) - 1)) | data_in; + + // leading 1 triggers shift start + if (m_shiftcount == 0 && !lead_in) + return; + + // output on 35th clock + if (m_shiftcount == 35) + { + m_shiftcount = 0; + m_write_output(0, m_shiftreg & m_outmask, ~u64(0)); + } + else + { + m_shiftreg >>= 1; + m_shiftcount++; + } + } +} diff --git a/src/devices/video/mm5445.h b/src/devices/video/mm5445.h new file mode 100644 index 00000000000..7d16d4f2ee2 --- /dev/null +++ b/src/devices/video/mm5445.h @@ -0,0 +1,101 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + National Semiconductor MM5445 series VFD Driver + +*/ + +#ifndef MAME_VIDEO_MM5445_H +#define MAME_VIDEO_MM5445_H + +#pragma once + +// pinout reference + +/* + ____ ____ + VDD 1 |* \_/ | 40 O18 + O17 2 | | 39 O19 + O16 3 | | 38 O20 + O15 4 | | 37 O21 + O14 5 | | 36 O22 + O13 6 | | 35 O23 + O12 7 | | 34 O24 + O11 8 | | 33 O25 + O10 9 | | 32 O26 + O9 10 | MM5445N | 31 O27 + O8 11 | | 30 O28 + O7 12 | | 29 O29 + O6 13 | | 28 O30 + O5 14 | | 27 O31 + O4 15 | | 26 O32 + O3 16 | | 25 O33 + O2 17 | | 24 BRIGHTNESS CONTROL + O1 18 | | 23 _DATA ENABLE + VGG 19 | | 22 DATA IN + VSS 20 |___________| 21 CLOCK IN + + O# = OUTPUT BIT # + MM5446, MM5448 don't have the brightness control pin, an extra output pin instead + MM5447, MM5448 don't have the data enable pin(always enabled), but another extra output pin +*/ + + +class mm5445_device : public device_t +{ +public: + mm5445_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + + // configuration helpers + auto output_cb() { return m_write_output.bind(); } + + DECLARE_WRITE_LINE_MEMBER(clock_w); + DECLARE_WRITE_LINE_MEMBER(enable_w) { m_enable = (state) ? 1 : 0; } // active low, unused on MM5447 and MM5448 + DECLARE_WRITE_LINE_MEMBER(data_w) { m_data = (state) ? 1 : 0; } + +protected: + mm5445_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 outpins); + + // device-level overrides + virtual void device_start() override; + + const u64 m_outmask; + + int m_clk; // input pin state + int m_enable; // " + int m_data; // " + + u64 m_shiftreg; + int m_shiftcount; + + // callbacks + devcb_write64 m_write_output; +}; + + +class mm5446_device : public mm5445_device +{ +public: + mm5446_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + +class mm5447_device : public mm5445_device +{ +public: + mm5447_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + +class mm5448_device : public mm5445_device +{ +public: + mm5448_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + + +DECLARE_DEVICE_TYPE(MM5445, mm5445_device) +DECLARE_DEVICE_TYPE(MM5446, mm5446_device) +DECLARE_DEVICE_TYPE(MM5447, mm5447_device) +DECLARE_DEVICE_TYPE(MM5448, mm5448_device) + +#endif // MAME_VIDEO_MM5445_H diff --git a/src/devices/video/mos6566.cpp b/src/devices/video/mos6566.cpp index a671448a4ab..b88cad06c64 100644 --- a/src/devices/video/mos6566.cpp +++ b/src/devices/video/mos6566.cpp @@ -227,12 +227,14 @@ DEFINE_DEVICE_TYPE(MOS8566, mos8566_device, "mos8566", "MOS 8566 VIC-II") // default address maps void mos6566_device::mos6566_videoram_map(address_map &map) { - map(0x0000, 0x3fff).ram(); + if (!has_configured_map(0)) + map(0x0000, 0x3fff).ram(); } void mos6566_device::mos6566_colorram_map(address_map &map) { - map(0x000, 0x3ff).ram(); + if (!has_configured_map(1)) + map(0x000, 0x3ff).ram(); } @@ -587,8 +589,8 @@ mos6566_device::mos6566_device(const machine_config &mconfig, device_type type, device_execute_interface(mconfig, *this), m_icount(0), m_variant(variant), - m_videoram_space_config("videoram", ENDIANNESS_LITTLE, 8, 14, 0, address_map_constructor(), address_map_constructor(FUNC(mos6566_device::mos6566_videoram_map), this)), - m_colorram_space_config("colorram", ENDIANNESS_LITTLE, 8, 10, 0, address_map_constructor(), address_map_constructor(FUNC(mos6566_device::mos6566_colorram_map), this)), + m_videoram_space_config("videoram", ENDIANNESS_LITTLE, 8, 14, 0, address_map_constructor(FUNC(mos6566_device::mos6566_videoram_map), this)), + m_colorram_space_config("colorram", ENDIANNESS_LITTLE, 8, 10, 0, address_map_constructor(FUNC(mos6566_device::mos6566_colorram_map), this)), m_write_irq(*this), m_write_ba(*this), m_write_aec(*this), @@ -2446,7 +2448,7 @@ uint32_t mos6566_device::screen_update(screen_device &screen, bitmap_rgb32 &bitm // read - //------------------------------------------------- -READ8_MEMBER( mos6566_device::read ) +uint8_t mos6566_device::read(offs_t offset) { uint8_t val = 0; @@ -2591,7 +2593,7 @@ READ8_MEMBER( mos6566_device::read ) // write - //------------------------------------------------- -WRITE8_MEMBER( mos6566_device::write ) +void mos6566_device::write(offs_t offset, uint8_t data) { DBG_LOG(2, "vic write", ("%.2x:%.2x\n", offset, data)); offset &= 0x3f; diff --git a/src/devices/video/mos6566.h b/src/devices/video/mos6566.h index 6f3a52dbab5..d1d7338e151 100644 --- a/src/devices/video/mos6566.h +++ b/src/devices/video/mos6566.h @@ -199,8 +199,8 @@ public: virtual space_config_vector memory_space_config() const override; - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); DECLARE_WRITE_LINE_MEMBER( lp_w ); diff --git a/src/devices/video/msm6222b.h b/src/devices/video/msm6222b.h index 9cf3623e25f..7a2cb00fd89 100644 --- a/src/devices/video/msm6222b.h +++ b/src/devices/video/msm6222b.h @@ -15,11 +15,6 @@ #pragma once -#define MCFG_MSM6222B_ADD( _tag ) \ - MCFG_DEVICE_ADD( _tag, MSM6222B, 0 ) - -#define MCFG_MSM6222B_01_ADD( _tag ) \ - MCFG_DEVICE_ADD( _tag, MSM6222B_01, 0 ) class msm6222b_device : public device_t { public: diff --git a/src/devices/video/msm6255.cpp b/src/devices/video/msm6255.cpp index ffca4414314..b1c83556103 100644 --- a/src/devices/video/msm6255.cpp +++ b/src/devices/video/msm6255.cpp @@ -63,7 +63,8 @@ void msm6255_device::map(address_map &map) // default address map void msm6255_device::msm6255(address_map &map) { - map(0x00000, 0xfffff).ram(); + if (!has_configured_map(0)) + map(0x00000, 0xfffff).ram(); } @@ -80,7 +81,7 @@ msm6255_device::msm6255_device(const machine_config &mconfig, const char *tag, d device_t(mconfig, MSM6255, tag, owner, clock), device_memory_interface(mconfig, *this), device_video_interface(mconfig, *this), - m_space_config("videoram", ENDIANNESS_LITTLE, 8, 20, 0, address_map_constructor(), address_map_constructor(FUNC(msm6255_device::msm6255), this)), + m_space_config("videoram", ENDIANNESS_LITTLE, 8, 20, 0, address_map_constructor(FUNC(msm6255_device::msm6255), this)), m_cursor(0) { } diff --git a/src/devices/video/nt7534.h b/src/devices/video/nt7534.h index 06e37d2bd26..75390f8acaa 100644 --- a/src/devices/video/nt7534.h +++ b/src/devices/video/nt7534.h @@ -12,9 +12,6 @@ #pragma once -#define MCFG_NT7534_PIXEL_UPDATE_CB(_class, _method) \ - downcast<nt7534_device &>(*device).set_pixel_update_cb(nt7534_device::pixel_update_delegate(&_class::_method, #_class "::" #_method, this)); - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -32,7 +29,7 @@ public: // construction/destruction nt7534_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); - template <typename Object> void set_pixel_update_cb(Object &&cb) { m_pixel_update_cb = std::forward<Object>(cb); } + template <typename... T> void set_pixel_update_cb(T &&... args) { m_pixel_update_cb = pixel_update_delegate(std::forward<T>(args)...); } // device interface virtual DECLARE_WRITE8_MEMBER(write); diff --git a/src/devices/video/pc_vga.cpp b/src/devices/video/pc_vga.cpp index 9bf529f7213..1170693a2db 100644 --- a/src/devices/video/pc_vga.cpp +++ b/src/devices/video/pc_vga.cpp @@ -2220,14 +2220,16 @@ WRITE8_MEMBER(vga_device::mem_linear_w) // device_add_mconfig - add device configuration //------------------------------------------------- -MACHINE_CONFIG_START(ati_vga_device::device_add_mconfig) - MCFG_MACH8_ADD_OWNER("8514a") +void ati_vga_device::device_add_mconfig(machine_config &config) +{ + MACH8(config, "8514a", 0).set_vga_owner(); EEPROM_93C46_16BIT(config, "ati_eeprom"); -MACHINE_CONFIG_END +} -MACHINE_CONFIG_START(s3_vga_device::device_add_mconfig) - MCFG_8514A_ADD_OWNER("8514a") -MACHINE_CONFIG_END +void s3_vga_device::device_add_mconfig(machine_config &config) +{ + IBM8514A(config, "8514a", 0).set_vga_owner(); +} /****************************************** diff --git a/src/devices/video/pc_vga.h b/src/devices/video/pc_vga.h index afde9bfdfd6..bab15da5673 100644 --- a/src/devices/video/pc_vga.h +++ b/src/devices/video/pc_vga.h @@ -415,14 +415,6 @@ private: // device type definition DECLARE_DEVICE_TYPE(IBM8514A, ibm8514a_device) -#define MCFG_8514A_ADD(_tag, _param) \ - MCFG_DEVICE_ADD(_tag, IBM8514A, 0) \ - downcast<ibm8514a_device*>(device)->set_vga(_param); - -#define MCFG_8514A_ADD_OWNER(_tag) \ - MCFG_DEVICE_ADD(_tag, IBM8514A, 0) \ - downcast<ibm8514a_device*>(device)->set_vga_owner(); - class mach8_device : public ibm8514a_device { @@ -496,13 +488,6 @@ private: // device type definition DECLARE_DEVICE_TYPE(MACH8, mach8_device) -#define MCFG_MACH8_ADD(_tag, _param) \ - MCFG_DEVICE_ADD(_tag, MACH8, 0) \ - downcast<mach8_device*>(device)->set_vga(_param); - -#define MCFG_MACH8_ADD_OWNER(_tag) \ - MCFG_DEVICE_ADD(_tag, MACH8, 0) \ - downcast<mach8_device*>(device)->set_vga_owner(); // ======================> tseng_vga_device diff --git a/src/devices/video/pcd8544.h b/src/devices/video/pcd8544.h index fee6fad00d8..069984e9483 100644 --- a/src/devices/video/pcd8544.h +++ b/src/devices/video/pcd8544.h @@ -18,12 +18,6 @@ #define PCD8544_SCREEN_UPDATE(name) void name(device_t &device, bitmap_ind16 &bitmap, const rectangle &cliprect , uint8_t *vram, int inv) -#define MCFG_PCD8544_ADD( _tag ) \ - MCFG_DEVICE_ADD( _tag, PCD8544, 0 ) - -#define MCFG_PCD8544_SCREEN_UPDATE_CALLBACK(_class, _method) \ - downcast<pcd8544_device &>(*device).set_screen_update_cb(pcd8544_device::screen_update_delegate(&_class::_method, #_class "::" #_method, this)); - // ======================> pcd8544_device @@ -34,7 +28,7 @@ public: // construction/destruction pcd8544_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template <typename Object> void set_screen_update_cb(Object &&cb) { m_screen_update_cb = std::forward<Object>(cb); } + template <typename... T> void set_screen_update_cb(T &&... args) { m_screen_update_cb = screen_update_delegate(std::forward<T>(args)...); } // device interface DECLARE_WRITE_LINE_MEMBER(sdin_w); diff --git a/src/devices/video/ppu2c0x.cpp b/src/devices/video/ppu2c0x.cpp index 341271ed6bf..8aa57660318 100644 --- a/src/devices/video/ppu2c0x.cpp +++ b/src/devices/video/ppu2c0x.cpp @@ -89,9 +89,12 @@ DEFINE_DEVICE_TYPE(PPU_2C05_04, ppu2c05_04_device, "ppu2c05_04", "2C05_04 PPU") // default address map void ppu2c0x_device::ppu2c0x(address_map &map) { - map(0x0000, 0x3eff).ram(); - map(0x3f00, 0x3fff).rw(FUNC(ppu2c0x_device::palette_read), FUNC(ppu2c0x_device::palette_write)); + if (!has_configured_map(0)) + { + map(0x0000, 0x3eff).ram(); + map(0x3f00, 0x3fff).rw(FUNC(ppu2c0x_device::palette_read), FUNC(ppu2c0x_device::palette_write)); // AM_RANGE(0x0000, 0x3fff) AM_RAM + } } //------------------------------------------------- @@ -125,7 +128,7 @@ ppu2c0x_device::ppu2c0x_device(const machine_config &mconfig, device_type type, , device_memory_interface(mconfig, *this) , device_video_interface(mconfig, *this) , device_palette_interface(mconfig, *this) - , m_space_config("videoram", ENDIANNESS_LITTLE, 8, 17, 0, address_map_constructor(), address_map_constructor(FUNC(ppu2c0x_device::ppu2c0x), this)) + , m_space_config("videoram", ENDIANNESS_LITTLE, 8, 17, 0, address_map_constructor(FUNC(ppu2c0x_device::ppu2c0x), this)) , m_cpu(*this, finder_base::DUMMY_TAG) , m_scanline(0) // reset the scanline count , m_int_callback(*this) @@ -229,7 +232,7 @@ void ppu2c0x_device::device_start() /* initialize the scanline handling portion */ m_scanline_timer->adjust(screen().time_until_pos(1)); - m_hblank_timer->adjust(m_cpu->cycles_to_attotime(86.67)); // ??? FIXME - hardcoding NTSC, need better calculation + m_hblank_timer->adjust(m_cpu->cycles_to_attotime(260) / 3); // ??? FIXME - hardcoding NTSC, need better calculation m_nmi_timer->adjust(attotime::never); /* allocate a screen bitmap, videomem and spriteram, a dirtychar array and the monochromatic colortable */ @@ -558,7 +561,7 @@ void ppu2c0x_device::device_timer(emu_timer &timer, device_timer_id id, int para next_scanline = 0; // Call us back when the hblank starts for this scanline - m_hblank_timer->adjust(m_cpu->cycles_to_attotime(86.67)); // ??? FIXME - hardcoding NTSC, need better calculation + m_hblank_timer->adjust(m_cpu->cycles_to_attotime(260) / 3); // ??? FIXME - hardcoding NTSC, need better calculation // trigger again at the start of the next scanline m_scanline_timer->adjust(screen().time_until_pos(next_scanline * m_scan_scale)); diff --git a/src/devices/video/ps2gs.cpp b/src/devices/video/ps2gs.cpp index 79ba24339d2..298b3779bbe 100644 --- a/src/devices/video/ps2gs.cpp +++ b/src/devices/video/ps2gs.cpp @@ -52,9 +52,10 @@ ps2_gs_device::~ps2_gs_device() { } -MACHINE_CONFIG_START(ps2_gs_device::device_add_mconfig) - MCFG_DEVICE_ADD(m_gif, SONYPS2_GIF, clock(), DEVICE_SELF, m_vu1) -MACHINE_CONFIG_END +void ps2_gs_device::device_add_mconfig(machine_config &config) +{ + SONYPS2_GIF(config, m_gif, clock(), DEVICE_SELF, m_vu1); +} void ps2_gs_device::device_start() { diff --git a/src/devices/video/ramdac.cpp b/src/devices/video/ramdac.cpp index dc45e106711..d651235f60c 100644 --- a/src/devices/video/ramdac.cpp +++ b/src/devices/video/ramdac.cpp @@ -19,10 +19,13 @@ // default address map void ramdac_device::ramdac_palram(address_map &map) { - map(0x000, 0x0ff).ram(); // R bank - map(0x100, 0x1ff).ram(); // G bank - map(0x200, 0x2ff).ram(); // B bank - map(0x300, 0x3ff).noprw(); + if (!has_configured_map(0)) + { + map(0x000, 0x0ff).ram(); // R bank + map(0x100, 0x1ff).ram(); // G bank + map(0x200, 0x2ff).ram(); // B bank + map(0x300, 0x3ff).noprw(); + } } //************************************************************************** @@ -44,7 +47,7 @@ DEFINE_DEVICE_TYPE(RAMDAC, ramdac_device, "ramdac", "RAMDAC") ramdac_device::ramdac_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, RAMDAC, tag, owner, clock), device_memory_interface(mconfig, *this), - m_space_config("videoram", ENDIANNESS_LITTLE, 8, 10, 0, address_map_constructor(), address_map_constructor(FUNC(ramdac_device::ramdac_palram), this)), + m_space_config("videoram", ENDIANNESS_LITTLE, 8, 10, 0, address_map_constructor(FUNC(ramdac_device::ramdac_palram), this)), m_palette(*this, finder_base::DUMMY_TAG), m_color_base(0), m_split_read_reg(0) diff --git a/src/devices/video/saa5050.h b/src/devices/video/saa5050.h index 6e1aa5cec6a..a9bb680f347 100644 --- a/src/devices/video/saa5050.h +++ b/src/devices/video/saa5050.h @@ -29,21 +29,6 @@ #pragma once - - -//************************************************************************** -// INTERFACE CONFIGURATION MACROS -//************************************************************************** - -#define MCFG_SAA5050_D_CALLBACK(_read) \ - downcast<saa5050_device &>(*device).set_d_rd_callback(DEVCB_##_read); - - -#define MCFG_SAA5050_SCREEN_SIZE(_cols, _rows, _size) \ - downcast<saa5050_device &>(*device).set_screen_size(_cols, _rows, _size); - - - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -58,7 +43,6 @@ public: void set_screen_size(int cols, int rows, int size) { m_cols = cols; m_rows = rows; m_size = size; } - template <class Object> devcb_base &set_d_rd_callback(Object &&cb) { return m_read_d.set_callback(std::forward<Object>(cb)); } auto d_cb() { return m_read_d.bind(); } // optional information overrides diff --git a/src/devices/video/scn2674.cpp b/src/devices/video/scn2674.cpp index 9baae770f4c..1e6cf3d68b5 100644 --- a/src/devices/video/scn2674.cpp +++ b/src/devices/video/scn2674.cpp @@ -25,7 +25,8 @@ DEFINE_DEVICE_TYPE(SCN2674, scn2674_device, "scn2674", "Signetics SCN2674 AVDC") // default address map void scn2674_device::scn2674_vram(address_map &map) { - map(0x0000, (1 << space_config(0)->addr_width()) - 1).noprw(); + if (!has_configured_map(0)) + map(0x0000, (1 << space_config(0)->addr_width()) - 1).noprw(); } scn2672_device::scn2672_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) @@ -44,12 +45,15 @@ scn2674_device::scn2674_device(const machine_config &mconfig, device_type type, , device_memory_interface(mconfig, *this) , m_intr_cb(*this) , m_breq_cb(*this) + , m_mbc_cb(*this) + , m_mbc_char_cb(*this) + , m_mbc_attr_cb(*this) , m_IR_pointer(0) , m_screen1_address(0), m_screen2_address(0) , m_cursor_address(0) , m_irq_register(0), m_status_register(0), m_irq_mask(0) , m_gfx_enabled(false) - , m_display_enabled(false), m_display_enabled_field(false), m_display_enabled_scanline(false) + , m_display_enabled(false), m_dadd_enabled(false), m_display_enabled_field(false), m_display_enabled_scanline(false) , m_cursor_enabled(false) , m_hpixels_per_column(0) , m_double_ht_wd(false) @@ -83,9 +87,11 @@ scn2674_device::scn2674_device(const machine_config &mconfig, device_type type, , m_char_buffer(0), m_attr_buffer(0) , m_linecounter(0), m_address(0), m_start1change(0) , m_scanline_timer(nullptr) + , m_breq_timer(nullptr) + , m_vblank_timer(nullptr) , m_char_space(nullptr), m_attr_space(nullptr) - , m_char_space_config("charram", ENDIANNESS_LITTLE, 8, extend_addressing ? 16 : 14, 0, address_map_constructor(), address_map_constructor(FUNC(scn2674_device::scn2674_vram), this)) - , m_attr_space_config("attrram", ENDIANNESS_LITTLE, 8, extend_addressing ? 16 : 14, 0, address_map_constructor(), address_map_constructor(FUNC(scn2674_device::scn2674_vram), this)) + , m_char_space_config("charram", ENDIANNESS_LITTLE, 8, extend_addressing ? 16 : 14, 0, address_map_constructor(FUNC(scn2674_device::scn2674_vram), this)) + , m_attr_space_config("attrram", ENDIANNESS_LITTLE, 8, extend_addressing ? 16 : 14, 0) { } @@ -105,7 +111,12 @@ void scn2674_device::device_start() m_display_cb.bind_relative_to(*owner()); m_intr_cb.resolve_safe(); m_breq_cb.resolve_safe(); - m_scanline_timer = timer_alloc(TIMER_SCANLINE); + m_mbc_cb.resolve_safe(); + m_mbc_char_cb.resolve(); + m_mbc_attr_cb.resolve(); + m_scanline_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(scn2674_device::scanline_timer), this)); + m_breq_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(scn2674_device::breq_timer), this)); + m_vblank_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(scn2674_device::vblank_timer), this)); screen().register_screen_bitmap(m_bitmap); m_char_space = &space(0); @@ -123,6 +134,7 @@ void scn2674_device::device_start() save_item(NAME(m_irq_mask)); save_item(NAME(m_gfx_enabled)); save_item(NAME(m_display_enabled)); + save_item(NAME(m_dadd_enabled)); save_item(NAME(m_display_enabled_field)); save_item(NAME(m_display_enabled_scanline)); save_item(NAME(m_cursor_enabled)); @@ -174,6 +186,7 @@ void scn2674_device::device_reset() m_irq_mask = 0; m_gfx_enabled = false; m_display_enabled = false; + m_dadd_enabled = false; m_display_enabled_field = false; m_display_enabled_scanline = false; m_cursor_enabled = false; @@ -551,9 +564,15 @@ void scn2674_device::set_display_enabled(bool enabled, int n) m_display_enabled = false; if (n == 1) + { LOGMASKED(LOG_COMMAND, "%s: Display off - float DADD bus\n", machine().describe_context()); + m_dadd_enabled = false; + } else + { LOGMASKED(LOG_COMMAND, "%s: Display off - no float DADD bus\n", machine().describe_context()); + m_dadd_enabled = true; + } } else { @@ -710,6 +729,9 @@ void scn2674_device::write_delayed_command(uint8_t data) case 0xbb: // write from cursor address to pointer address // TODO: transfer only during blank + m_display_enabled = false; + m_display_enabled_field = true; + m_display_enabled_scanline = false; for (i = m_cursor_address; i != m_screen2_address; i = ((i + 1) & 0xffff)) { m_char_space->write_byte(i, m_char_buffer); @@ -762,13 +784,17 @@ void scn2674_device::write_command(uint8_t data) m_IR_pointer = 0; m_irq_register = 0x00; m_status_register = 0x20; // RDFLG activated - m_linecounter = 0; m_irq_mask = 0x00; m_gfx_enabled = false; m_display_enabled = false; + m_dadd_enabled = false; m_cursor_enabled = false; m_use_row_table = false; m_intr_cb(CLEAR_LINE); + m_breq_cb(CLEAR_LINE); + m_mbc_cb(0); + m_breq_timer->adjust(attotime::never); + m_vblank_timer->adjust(attotime::never); } else { @@ -911,6 +937,8 @@ void scn2674_device::write(offs_t offset, uint8_t data) m_screen1_address = (m_screen1_address & 0x3f00) | data; if (!screen().vblank()) m_start1change = (m_linecounter / m_scanline_per_char_row) + 1; + else + m_start1change = 0; break; case 3: @@ -924,6 +952,8 @@ void scn2674_device::write(offs_t offset, uint8_t data) } if (!screen().vblank()) m_start1change = (m_linecounter / m_scanline_per_char_row) + 1; + else + m_start1change = 0; break; case 4: @@ -967,154 +997,200 @@ void scn2674_device::recompute_parameters() rectangle visarea(0, max_visible_x, 0, max_visible_y); screen().configure(horiz_pix_total, vert_pix_total, visarea, refresh.as_attoseconds()); - m_scanline_timer->adjust(screen().time_until_pos(0, 0), 0, screen().scan_period()); + m_linecounter = screen().vpos(); + m_scanline_timer->adjust(screen().time_until_pos((m_linecounter + 1) % vert_pix_total, 0), 0, screen().scan_period()); } -void scn2674_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +TIMER_CALLBACK_MEMBER(scn2674_device::scanline_timer) { - switch (id) + int dw = m_double_ht_wd ? m_double[0] : 0; // double width + if (((m_display_enabled_scanline) || (m_display_enabled_field && !m_interlace_enable)) && (!m_display_enabled)) { - case TIMER_SCANLINE: - { - int dw = m_double_ht_wd ? m_double[0] : 0; // double width - if (((m_display_enabled_scanline) || (m_display_enabled_field && !m_interlace_enable)) && (!m_display_enabled)) - { - m_display_enabled = true; - m_display_enabled_scanline = false; - m_display_enabled_field = false; - } + m_display_enabled = true; + m_dadd_enabled = true; + m_display_enabled_scanline = false; + m_display_enabled_field = false; + } - m_linecounter++; + m_linecounter++; - if (m_linecounter >= screen().height()) - { - m_linecounter = 0; - m_address = m_screen1_address; - } + if (m_linecounter >= screen().height()) + { + m_linecounter = 0; + m_address = m_screen1_address; + } - if (m_linecounter == (m_rows_per_screen * m_scanline_per_char_row)) - { - m_status_register |= 0x10; - if (BIT(m_irq_mask, 4)) - { - LOGMASKED(LOG_INTR, "V-Blank interrupt at line %d\n", m_linecounter); - m_irq_register |= 0x10; - m_intr_cb(ASSERT_LINE); - } - } + bool lastscan = m_linecounter == (m_rows_per_screen * m_scanline_per_char_row) - 1; + if (lastscan) + { + int horz_sync_begin = 2 * (m_equalizing_constant + 2 * m_horz_sync_width) - m_horz_sync_width - m_horz_back_porch; + m_vblank_timer->adjust(clocks_to_attotime(horz_sync_begin)); + } - if (m_linecounter >= (m_rows_per_screen * m_scanline_per_char_row)) - break; + if (m_linecounter >= (m_rows_per_screen * m_scanline_per_char_row)) + { + if (m_buffer_mode_select == 3 && m_linecounter == (screen().height() - 1)) + m_breq_timer->adjust(clocks_to_attotime(m_character_per_row + 1), ASSERT_LINE); + return; + } - int charrow = m_linecounter % m_scanline_per_char_row; - int tilerow = charrow; + int charrow = m_linecounter % m_scanline_per_char_row; + int tilerow = charrow; - // should be triggered at the start of each ROW (line zero for that row) - if (charrow == 0) - { - m_status_register |= 0x08; - if (BIT(m_irq_mask, 3)) - { - LOGMASKED(LOG_INTR, "Line Zero interrupt at line %d\n", m_linecounter); - m_irq_register |= 0x08; - m_intr_cb(ASSERT_LINE); - } - if (m_buffer_mode_select == 3) - m_breq_cb(ASSERT_LINE); - } - else if (m_buffer_mode_select == 3) - m_breq_cb(CLEAR_LINE); + // should be triggered at the start of each ROW (line zero for that row) + if (charrow == 0) + { + m_status_register |= 0x08; + if (BIT(m_irq_mask, 3)) + { + LOGMASKED(LOG_INTR, "Line Zero interrupt at line %d\n", m_linecounter); + m_irq_register |= 0x08; + m_intr_cb(ASSERT_LINE); + } + if (m_buffer_mode_select == 3) + { + m_mbc_cb(1); + m_breq_timer->adjust(clocks_to_attotime(m_character_per_row + 1), CLEAR_LINE); + } + } + else if (m_buffer_mode_select == 3 && charrow == (m_scanline_per_char_row - 1) && !lastscan) + m_breq_timer->adjust(clocks_to_attotime(m_character_per_row + 1), ASSERT_LINE); - // Handle screen splits - for (int s = 0; s < 2; s++) + // Handle screen splits + for (int s = 0; s < 2; s++) + { + if ((m_linecounter == ((m_split_register[s] + 1) * m_scanline_per_char_row)) && m_linecounter) + { + uint8_t flag = (s == 0) ? 0x04 : 0x01; + m_status_register |= flag; + if ((m_irq_mask & flag) != 0) { - if ((m_linecounter == ((m_split_register[s] + 1) * m_scanline_per_char_row)) && m_linecounter) - { - uint8_t flag = (s == 0) ? 0x04 : 0x01; - m_status_register |= flag; - if ((m_irq_mask & flag) != 0) - { - LOGMASKED(LOG_INTR, "Split Screen %d interrupt at line %d\n", s + 1, m_linecounter); - m_irq_register |= flag; - m_intr_cb(ASSERT_LINE); - } - if (m_spl[s]) - m_address = m_screen2_address; - if (!m_double_ht_wd) - dw = m_double[s]; - } + LOGMASKED(LOG_INTR, "Split Screen %d interrupt at line %d\n", s + 1, m_linecounter); + m_irq_register |= flag; + m_intr_cb(ASSERT_LINE); } + if (m_spl[s]) + m_address = m_screen2_address; + if (!m_double_ht_wd) + dw = m_double[s]; + } + } - if (!m_display_enabled) - break; + // WY-50 requires that normal row buffering take place even after a "display off" command + if (!m_dadd_enabled) + return; - if (m_use_row_table) - { - if (m_double_ht_wd) - dw = m_screen1_address >> 14; - if (!charrow) - { - uint16_t addr = m_screen2_address; - uint16_t line = m_char_space->read_word(addr); - m_screen1_address = line; - if (m_double_ht_wd) - { - dw = line >> 14; - line &= ~0xc000; - } - m_address = line; - addr += 2; - m_screen2_address = addr & 0x3fff; - } - } - else if (m_start1change && (m_start1change == (m_linecounter / m_scanline_per_char_row))) + if (m_use_row_table) + { + if (m_double_ht_wd) + dw = m_screen1_address >> 14; + if (!charrow) + { + uint16_t addr = m_screen2_address; + uint16_t line = m_char_space->read_word(addr); + m_screen1_address = line; + if (m_double_ht_wd) { - m_address = m_screen1_address; - m_start1change = 0; + dw = line >> 14; + line &= ~0xc000; } + m_address = line; + addr += 2; + m_screen2_address = addr & 0x3fff; + } + } + else if (m_start1change && (m_start1change == (m_linecounter / m_scanline_per_char_row))) + { + m_address = m_screen1_address; + m_start1change = 0; + } - if (dw == 2) - tilerow >>= 1; - else if (dw == 3) - tilerow = (charrow + m_scanline_per_char_row) >> 1; + if (dw == 2) + tilerow >>= 1; + else if (dw == 3) + tilerow = (charrow + m_scanline_per_char_row) >> 1; - uint16_t address = m_address; + uint16_t address = m_address; - for (int i = 0; i < m_character_per_row; i++) + const bool mbc = (charrow == 0) && (m_buffer_mode_select == 3); + const bool blink_on = (screen().frame_number() & (m_character_blink_rate_divisor >> 1)) != 0; + for (int i = 0; i < m_character_per_row; i++) + { + u8 charcode, attrcode = 0; + if (mbc && !m_mbc_char_cb.isnull()) + { + // row buffering DMA + charcode = m_mbc_char_cb(address); + m_char_space->write_byte(address, charcode); + if (m_attr_space != nullptr && !m_mbc_attr_cb.isnull()) { - bool cursor_on = ((address & 0x3fff) == m_cursor_address); - - if (!m_display_cb.isnull()) - m_display_cb(m_bitmap, - i * m_hpixels_per_column, - m_linecounter, - tilerow, - m_char_space->read_byte(address), - m_attr_space != nullptr ? m_attr_space->read_byte(address) : 0, - address, - (charrow >= m_cursor_first_scanline) && (charrow <= m_cursor_last_scanline) && cursor_on, - dw != 0, - m_gfx_enabled, - charrow == m_cursor_underline_position, - m_cursor_blink && (screen().frame_number() & m_cursor_rate_divisor)); - address = (address + 1) & 0xffff; - - if (address > ((m_display_buffer_last_address << 10) | 0x3ff)) - address = m_display_buffer_first_address; + attrcode = m_mbc_attr_cb(address); + m_attr_space->write_byte(address, attrcode); } + } + else + { + charcode = m_char_space->read_byte(address); + if (m_attr_space != nullptr) + attrcode = m_attr_space->read_byte(address); + } + + if (m_display_enabled && !m_display_cb.isnull()) + { + bool cursor_on = ((address & 0x3fff) == m_cursor_address) + && m_cursor_enabled + && (charrow >= m_cursor_first_scanline) + && (charrow <= m_cursor_last_scanline) + && (!m_cursor_blink || (screen().frame_number() & (m_cursor_rate_divisor >> 1)) != 0); + m_display_cb(m_bitmap, + i * m_hpixels_per_column, + m_linecounter, + tilerow, + charcode, + attrcode, + address, + cursor_on, + dw != 0, + m_gfx_enabled, + charrow == m_cursor_underline_position, + blink_on); - if (m_gfx_enabled || (charrow == (m_scanline_per_char_row - 1))) - m_address = address; } + address = (address + 1) & 0xffff; + + if (address > ((m_display_buffer_last_address << 10) | 0x3ff)) + address = m_display_buffer_first_address; + } + + if (!m_display_enabled) + std::fill_n(&m_bitmap.pix32(m_linecounter), m_character_per_row * m_hpixels_per_column, rgb_t::black()); + + if (m_gfx_enabled || (charrow == (m_scanline_per_char_row - 1))) + m_address = address; +} + +TIMER_CALLBACK_MEMBER(scn2674_device::breq_timer) +{ + LOGMASKED(LOG_INTR, "BREQ %sasserted at line %d\n", (param == ASSERT_LINE) ? "" : "de", m_linecounter); + m_breq_cb(param); + if (param == CLEAR_LINE) + m_mbc_cb(0); +} + +TIMER_CALLBACK_MEMBER(scn2674_device::vblank_timer) +{ + m_status_register |= 0x10; + if (BIT(m_irq_mask, 4)) + { + LOGMASKED(LOG_INTR, "V-Blank interrupt at line %d\n", m_linecounter); + m_irq_register |= 0x10; + m_intr_cb(ASSERT_LINE); } } uint32_t scn2674_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - if (!m_display_enabled) - m_bitmap.fill(rgb_t::black(), cliprect); - else - copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect); + copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect); return 0; } diff --git a/src/devices/video/scn2674.h b/src/devices/video/scn2674.h index 3090f740f8d..2b7367eeed0 100644 --- a/src/devices/video/scn2674.h +++ b/src/devices/video/scn2674.h @@ -23,6 +23,9 @@ public: // static configuration auto intr_callback() { return m_intr_cb.bind(); } auto breq_callback() { return m_breq_cb.bind(); } + auto mbc_callback() { return m_mbc_cb.bind(); } + auto mbc_char_callback() { return m_mbc_char_cb.bind(); } + auto mbc_attr_callback() { return m_mbc_attr_cb.bind(); } void set_character_width(int value) { m_hpixels_per_column = value; } template <class FunctionClass> @@ -54,14 +57,20 @@ protected: virtual void device_start() override; virtual void device_reset() override; - virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; virtual space_config_vector memory_space_config() const override; + TIMER_CALLBACK_MEMBER(scanline_timer); + TIMER_CALLBACK_MEMBER(breq_timer); + TIMER_CALLBACK_MEMBER(vblank_timer); + //protected: bitmap_rgb32 m_bitmap; devcb_write_line m_intr_cb; devcb_write_line m_breq_cb; + devcb_write_line m_mbc_cb; + devcb_read8 m_mbc_char_cb; + devcb_read8 m_mbc_attr_cb; uint8_t m_IR_pointer; uint16_t m_screen1_address; @@ -72,6 +81,7 @@ protected: uint8_t m_irq_mask; bool m_gfx_enabled; bool m_display_enabled; + bool m_dadd_enabled; bool m_display_enabled_field; bool m_display_enabled_scanline; bool m_cursor_enabled; @@ -129,14 +139,12 @@ protected: draw_character_delegate m_display_cb; emu_timer *m_scanline_timer; + emu_timer *m_breq_timer; + emu_timer *m_vblank_timer; address_space *m_char_space; address_space *m_attr_space; const address_space_config m_char_space_config; const address_space_config m_attr_space_config; - enum - { - TIMER_SCANLINE - }; }; class scn2672_device : public scn2674_device diff --git a/src/devices/video/sda5708.h b/src/devices/video/sda5708.h index eecb36e032c..4237675b95e 100644 --- a/src/devices/video/sda5708.h +++ b/src/devices/video/sda5708.h @@ -41,13 +41,6 @@ * */ -///************************************************************************* -// INTERFACE CONFIGURATION MACROS -///************************************************************************* - -#define MCFG_SDA5708_ADD(_tag) \ - MCFG_DEVICE_ADD(_tag, SDA5708, 0) - ///************************************************************************* // TYPE DEFINITIONS diff --git a/src/devices/video/sed1200.h b/src/devices/video/sed1200.h index 521bd4e027c..d6590af49ab 100644 --- a/src/devices/video/sed1200.h +++ b/src/devices/video/sed1200.h @@ -17,17 +17,6 @@ #pragma once -#define MCFG_SED1200D0A_ADD( _tag ) \ - MCFG_DEVICE_ADD( _tag, SED1200D0A, 0 ) - -#define MCFG_SED1200F0A_ADD( _tag ) \ - MCFG_DEVICE_ADD( _tag, SED1200F0A, 0 ) - -#define MCFG_SED1200D0B_ADD( _tag ) \ - MCFG_DEVICE_ADD( _tag, SED1200D0B, 0 ) - -#define MCFG_SED1200F0B_ADD( _tag ) \ - MCFG_DEVICE_ADD( _tag, SED1200F0B, 0 ) class sed1200_device : public device_t { public: diff --git a/src/devices/video/sed1330.cpp b/src/devices/video/sed1330.cpp index 5015bb0d43b..75eefb18c9d 100644 --- a/src/devices/video/sed1330.cpp +++ b/src/devices/video/sed1330.cpp @@ -68,7 +68,8 @@ DEFINE_DEVICE_TYPE(SED1330, sed1330_device, "sed1330", "Epson SED1330") // default address map void sed1330_device::sed1330(address_map &map) { - map(0x0000, 0xffff).ram(); + if (!has_configured_map(0)) + map(0x0000, 0xffff).ram(); } @@ -145,7 +146,7 @@ sed1330_device::sed1330_device(const machine_config &mconfig, const char *tag, d device_memory_interface(mconfig, *this), device_video_interface(mconfig, *this), m_bf(0), - m_space_config("videoram", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(), address_map_constructor(FUNC(sed1330_device::sed1330), this)) + m_space_config("videoram", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(FUNC(sed1330_device::sed1330), this)) { } diff --git a/src/devices/video/t6a04.h b/src/devices/video/t6a04.h index 0232ffc71a6..38906063f02 100644 --- a/src/devices/video/t6a04.h +++ b/src/devices/video/t6a04.h @@ -65,7 +65,4 @@ private: // device type definition DECLARE_DEVICE_TYPE(T6A04, t6a04_device) -#define MCFG_T6A04_SIZE(_width, _height) \ - downcast<t6a04_device &>(*device).set_size(_width, _height); - #endif // MAME_VIDEO_T6A04_H diff --git a/src/devices/video/tea1002.h b/src/devices/video/tea1002.h index 067ec5583bc..44898c625ac 100644 --- a/src/devices/video/tea1002.h +++ b/src/devices/video/tea1002.h @@ -25,15 +25,6 @@ #pragma once - -//************************************************************************** -// INTERFACE CONFIGURATION MACROS -//************************************************************************** - -#define MCFG_TEA1002_ADD(_tag, _clock) \ - MCFG_DEVICE_ADD(_tag, TEA1002, _clock) - - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** diff --git a/src/devices/video/tlc34076.cpp b/src/devices/video/tlc34076.cpp index c33b302a3b8..37dd95a40b1 100644 --- a/src/devices/video/tlc34076.cpp +++ b/src/devices/video/tlc34076.cpp @@ -127,7 +127,7 @@ void tlc34076_device::update_pen(uint8_t i) // read - read access //------------------------------------------------- -READ8_MEMBER( tlc34076_device::read ) +u8 tlc34076_device::read(offs_t offset) { uint8_t result; @@ -161,7 +161,7 @@ READ8_MEMBER( tlc34076_device::read ) // write - write access //------------------------------------------------- -WRITE8_MEMBER( tlc34076_device::write ) +void tlc34076_device::write(offs_t offset, u8 data) { // uint8_t oldval; diff --git a/src/devices/video/tlc34076.h b/src/devices/video/tlc34076.h index fb816dd1181..7c4b021bd27 100644 --- a/src/devices/video/tlc34076.h +++ b/src/devices/video/tlc34076.h @@ -41,8 +41,8 @@ public: void set_bits(tlc34076_bits bits) { m_dacbits = bits; } // public interface - DECLARE_READ8_MEMBER(read); - DECLARE_WRITE8_MEMBER(write); + u8 read(offs_t offset); + void write(offs_t offset, u8 data); protected: // device-level overrides @@ -66,15 +66,6 @@ private: }; -/*************************************************************************** - DEVICE CONFIGURATION MACROS -***************************************************************************/ - -#define MCFG_TLC34076_ADD(tag, bits) \ - MCFG_DEVICE_ADD((tag), TLC34076, 0) \ - downcast<tlc34076_device &>(*device).set_bits((tlc34076_device::bits)); - - DECLARE_DEVICE_TYPE(TLC34076, tlc34076_device) #endif // MAME_VIDEO_TLC34076_H diff --git a/src/devices/video/tms34061.cpp b/src/devices/video/tms34061.cpp index 397b412e586..8204facf1a1 100644 --- a/src/devices/video/tms34061.cpp +++ b/src/devices/video/tms34061.cpp @@ -32,7 +32,7 @@ DEFINE_DEVICE_TYPE(TMS34061, tms34061_device, "tms34061", "TI TMS34061 VSC") -tms34061_device::tms34061_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +tms34061_device::tms34061_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, TMS34061, tag, owner, clock), device_video_interface(mconfig, *this), m_rowshift(0), @@ -64,10 +64,10 @@ void tms34061_device::device_start() m_vrammask = m_vramsize - 1; /* allocate memory for VRAM */ - m_vram = auto_alloc_array_clear(machine(), uint8_t, m_vramsize + 256 * 2); + m_vram = auto_alloc_array_clear(machine(), u8, m_vramsize + 256 * 2); /* allocate memory for latch RAM */ - m_latchram = auto_alloc_array_clear(machine(), uint8_t, m_vramsize + 256 * 2); + m_latchram = auto_alloc_array_clear(machine(), u8, m_vramsize + 256 * 2); /* add some buffer space for VRAM and latch RAM */ m_vram += 256; @@ -171,7 +171,7 @@ TIMER_CALLBACK_MEMBER( tms34061_device::interrupt ) * *************************************/ -void tms34061_device::register_w(address_space &space, offs_t offset, uint8_t data) +void tms34061_device::register_w(offs_t offset, u8 data) { int scanline; int regnum = offset >> 2; @@ -242,10 +242,10 @@ void tms34061_device::register_w(address_space &space, offs_t offset, uint8_t da * *************************************/ -uint8_t tms34061_device::register_r(address_space &space, offs_t offset) +u8 tms34061_device::register_r(offs_t offset) { int regnum = offset >> 2; - uint16_t result; + u16 result; /* extract the correct portion of the register */ if (regnum < ARRAY_LENGTH(m_regs)) @@ -364,7 +364,7 @@ void tms34061_device::adjust_xyaddress(int offset) } -void tms34061_device::xypixel_w(address_space &space, int offset, uint8_t data) +void tms34061_device::xypixel_w(int offset, u8 data) { /* determine the offset, then adjust it */ offs_t pixeloffs = m_regs[TMS34061_XYADDRESS]; @@ -384,7 +384,7 @@ void tms34061_device::xypixel_w(address_space &space, int offset, uint8_t data) } -uint8_t tms34061_device::xypixel_r(address_space &space, int offset) +u8 tms34061_device::xypixel_r(int offset) { /* determine the offset, then adjust it */ offs_t pixeloffs = m_regs[TMS34061_XYADDRESS]; @@ -409,7 +409,7 @@ uint8_t tms34061_device::xypixel_r(address_space &space, int offset) * *************************************/ -void tms34061_device::write(address_space &space, int col, int row, int func, uint8_t data) +void tms34061_device::write(int col, int row, int func, u8 data) { offs_t offs; @@ -419,12 +419,12 @@ void tms34061_device::write(address_space &space, int col, int row, int func, ui /* both 0 and 2 map to register access */ case 0: case 2: - register_w(space, col, data); + register_w(col, data); break; /* function 1 maps to XY access; col is the address adjustment */ case 1: - xypixel_w(space, col, data); + xypixel_w(col, data); break; /* function 3 maps to direct access */ @@ -471,7 +471,7 @@ void tms34061_device::write(address_space &space, int col, int row, int func, ui } -uint8_t tms34061_device::read(address_space &space, int col, int row, int func) +u8 tms34061_device::read(int col, int row, int func) { int result = 0; offs_t offs; @@ -482,12 +482,12 @@ uint8_t tms34061_device::read(address_space &space, int col, int row, int func) /* both 0 and 2 map to register access */ case 0: case 2: - result = register_r(space, col); + result = register_r(col); break; /* function 1 maps to XY access; col is the address adjustment */ case 1: - result = xypixel_r(space, col); + result = xypixel_r(col); break; /* function 3 maps to direct access */ @@ -535,13 +535,13 @@ uint8_t tms34061_device::read(address_space &space, int col, int row, int func) * *************************************/ -READ8_MEMBER( tms34061_device::latch_r ) +u8 tms34061_device::latch_r() { return m_latchdata; } -WRITE8_MEMBER( tms34061_device::latch_w ) +void tms34061_device::latch_w(u8 data) { LOG("tms34061_latch = %02X\n", data); m_latchdata = data; diff --git a/src/devices/video/tms34061.h b/src/devices/video/tms34061.h index e4f92e75ac2..3b3e3d5f552 100644 --- a/src/devices/video/tms34061.h +++ b/src/devices/video/tms34061.h @@ -15,17 +15,6 @@ #pragma once -#define MCFG_TMS34061_ROWSHIFT(_shift) \ - downcast<tms34061_device &>(*device).set_rowshift(_shift); - -#define MCFG_TMS34061_VRAM_SIZE(_size) \ - downcast<tms34061_device &>(*device).set_vram_size(_size); - -#define MCFG_TMS34061_INTERRUPT_CB(_devcb) \ - downcast<tms34061_device &>(*device).set_interrupt_callback(DEVCB_##_devcb); - - - // ======================> tms34061_device class tms34061_device : public device_t, public device_video_interface @@ -34,36 +23,35 @@ public: /* display state structure */ struct tms34061_display { - uint8_t blanked; /* true if blanked */ - uint8_t *vram; /* base of VRAM */ - uint8_t *latchram; /* base of latch RAM */ - uint16_t *regs; /* pointer to array of registers */ + u8 blanked; /* true if blanked */ + u8 *vram; /* base of VRAM */ + u8 *latchram; /* base of latch RAM */ + u16 *regs; /* pointer to array of registers */ offs_t dispstart; /* display start */ }; // construction/destruction - tms34061_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + tms34061_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); - void set_rowshift(uint8_t rowshift) { m_rowshift = rowshift; } - void set_vram_size(uint32_t vramsize) { m_vramsize = vramsize; } - template <class Object> devcb_base &set_interrupt_callback(Object &&cb) { return m_interrupt_cb.set_callback(std::forward<Object>(cb)); } + void set_rowshift(u8 rowshift) { m_rowshift = rowshift; } + void set_vram_size(u32 vramsize) { m_vramsize = vramsize; } auto int_callback() { return m_interrupt_cb.bind(); } /* reads/writes to the 34061 */ - uint8_t read(address_space &space, int col, int row, int func); - void write(address_space &space, int col, int row, int func, uint8_t data); + u8 read(int col, int row, int func); + void write(int col, int row, int func, u8 data); /* latch settings */ - DECLARE_READ8_MEMBER( latch_r ); - DECLARE_WRITE8_MEMBER( latch_w ); + u8 latch_r(); + void latch_w(u8 data); /* video update handling */ void get_display_state(); bool blanked() const { return bool(m_display.blanked); } - uint8_t const &vram(unsigned row) const { return m_display.vram[row << m_rowshift]; } - uint16_t xyoffset() const { return m_display.regs[TMS34061_XYOFFSET]; } - uint16_t xyaddress() const { return m_display.regs[TMS34061_XYADDRESS]; } + u8 const &vram(unsigned row) const { return m_display.vram[row << m_rowshift]; } + u16 xyoffset() const { return m_display.regs[TMS34061_XYOFFSET]; } + u16 xyaddress() const { return m_display.regs[TMS34061_XYADDRESS]; } // TODO: encapsulate this properly tms34061_display m_display; @@ -98,27 +86,27 @@ private: TMS34061_REGCOUNT }; - uint8_t m_rowshift; /* VRAM address is (row << rowshift) | col */ - uint32_t m_vramsize; /* size of video RAM */ + u8 m_rowshift; /* VRAM address is (row << rowshift) | col */ + u32 m_vramsize; /* size of video RAM */ devcb_write_line m_interrupt_cb; /* interrupt gen callback */ - uint16_t m_regs[TMS34061_REGCOUNT]; - uint16_t m_xmask; - uint8_t m_yshift; - uint32_t m_vrammask; - uint8_t * m_vram; - uint8_t * m_latchram; - uint8_t m_latchdata; - uint8_t * m_shiftreg; - emu_timer * m_timer; + u16 m_regs[TMS34061_REGCOUNT]; + u16 m_xmask; + u8 m_yshift; + u32 m_vrammask; + u8 * m_vram; + u8 * m_latchram; + u8 m_latchdata; + u8 * m_shiftreg; + emu_timer * m_timer; void update_interrupts(); TIMER_CALLBACK_MEMBER( interrupt ); - void register_w(address_space &space, offs_t offset, uint8_t data); - uint8_t register_r(address_space &space, offs_t offset); + void register_w(offs_t offset, u8 data); + u8 register_r(offs_t offset); void adjust_xyaddress(int offset); - void xypixel_w(address_space &space, int offset, uint8_t data); - uint8_t xypixel_r(address_space &space, int offset); + void xypixel_w(int offset, u8 data); + u8 xypixel_r(int offset); }; // device type definition diff --git a/src/devices/video/tms3556.cpp b/src/devices/video/tms3556.cpp index c856735756f..80280fe5364 100644 --- a/src/devices/video/tms3556.cpp +++ b/src/devices/video/tms3556.cpp @@ -59,7 +59,8 @@ DEFINE_DEVICE_TYPE(TMS3556, tms3556_device, "tms3556", "Texas Instruments TMS355 // default address map void tms3556_device::tms3556(address_map &map) { - map(0x0000, 0xffff).ram(); + if (!has_configured_map(0)) + map(0x0000, 0xffff).ram(); } //------------------------------------------------- @@ -111,7 +112,7 @@ tms3556_device::tms3556_device(const machine_config &mconfig, const char *tag, d : device_t(mconfig, TMS3556, tag, owner, clock), device_memory_interface(mconfig, *this), device_video_interface(mconfig, *this), - m_space_config("videoram", ENDIANNESS_LITTLE, 8, 17, 0, address_map_constructor(), address_map_constructor(FUNC(tms3556_device::tms3556), this)), + m_space_config("videoram", ENDIANNESS_LITTLE, 8, 17, 0, address_map_constructor(FUNC(tms3556_device::tms3556), this)), m_reg(0), m_reg2(0), m_reg_access_phase(0), m_row_col_written(0), diff --git a/src/devices/video/tms3556.h b/src/devices/video/tms3556.h index 11146f8b21f..e20e02d09c3 100644 --- a/src/devices/video/tms3556.h +++ b/src/devices/video/tms3556.h @@ -19,12 +19,6 @@ /* if DOUBLE_WIDTH set, the horizontal resolution is doubled */ #define TMS3556_DOUBLE_WIDTH 0 -///************************************************************************* -// INTERFACE CONFIGURATION MACROS -///************************************************************************* - -#define MCFG_TMS3556_ADD(_tag) \ - MCFG_DEVICE_ADD(_tag, TMS3556, 0) ///************************************************************************* // TYPE DEFINITIONS diff --git a/src/devices/video/tms9927.cpp b/src/devices/video/tms9927.cpp index 9a43cb1f635..bc8e187f8e8 100644 --- a/src/devices/video/tms9927.cpp +++ b/src/devices/video/tms9927.cpp @@ -81,7 +81,7 @@ crt5057_device::crt5057_device(const machine_config &mconfig, const char *tag, d void tms9927_device::device_start() { assert(clock() > 0); - if (!(m_hpixels_per_column > 0)) fatalerror("TMS9927: number of pixels per column must be explicitly set using MCFG_TMS9927_CHAR_WIDTH()!\n"); + if (!(m_hpixels_per_column > 0)) fatalerror("TMS9927: number of pixels per column must be explicitly set using set_char_width()!\n"); // resolve callbacks m_write_vsyn.resolve_safe(); diff --git a/src/devices/video/tms9928a.cpp b/src/devices/video/tms9928a.cpp index bc31b1b1db9..c068d8b4ce8 100644 --- a/src/devices/video/tms9928a.cpp +++ b/src/devices/video/tms9928a.cpp @@ -52,11 +52,11 @@ DEFINE_DEVICE_TYPE(EFO90501, efo90501_device, "efo90501", "EFO90501 VDP") */ void tms9928a_device::memmap(address_map &map) { - map.global_mask(0x3fff); - map(0x0000, 0x3fff).ram(); + if (!has_configured_map(0)) + map(0x0000, 0x3fff).ram(); } -tms9928a_device::tms9928a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool is_50hz, bool is_reva, bool is_99) +tms9928a_device::tms9928a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint16_t horz_total, bool is_50hz, bool is_reva, bool is_99) : device_t(mconfig, type, tag, owner, clock) , device_memory_interface(mconfig, *this) , device_palette_interface(mconfig, *this) @@ -64,10 +64,11 @@ tms9928a_device::tms9928a_device(const machine_config &mconfig, device_type type , m_vram_size(0) , m_out_int_line_cb(*this) , m_out_gromclk_cb(*this) + , m_total_horz(horz_total) , m_50hz(is_50hz) , m_reva(is_reva) , m_99(is_99) - , m_space_config("vram", ENDIANNESS_BIG, 8, 14, 0, address_map_constructor(), address_map_constructor(FUNC(tms9928a_device::memmap), this)) + , m_space_config("vram", ENDIANNESS_BIG, 8, 14, 0, address_map_constructor(FUNC(tms9928a_device::memmap), this)) { } @@ -82,57 +83,57 @@ void tms9928a_device::device_config_complete() if (!screen().refresh_attoseconds()) { if (m_50hz) - screen().set_raw(clock() / 2, TOTAL_HORZ, HORZ_DISPLAY_START - 12, HORZ_DISPLAY_START + 256 + 12, + screen().set_raw(clock() / 2, m_total_horz, HORZ_DISPLAY_START - 12, HORZ_DISPLAY_START + 256 + 12, TOTAL_VERT_PAL, VERT_DISPLAY_START_PAL - 12, VERT_DISPLAY_START_PAL + 192 + 12); else - screen().set_raw(clock() / 2, TOTAL_HORZ, HORZ_DISPLAY_START - 12, HORZ_DISPLAY_START + 256 + 12, + screen().set_raw(clock() / 2, m_total_horz, HORZ_DISPLAY_START - 12, HORZ_DISPLAY_START + 256 + 12, TOTAL_VERT_NTSC, VERT_DISPLAY_START_NTSC - 12, VERT_DISPLAY_START_NTSC + 192 + 12); } } tms9928a_device::tms9928a_device( const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : tms9928a_device(mconfig, TMS9928A, tag, owner, clock, false, true, true) + : tms9928a_device(mconfig, TMS9928A, tag, owner, clock, 342, false, true, true) { } tms9129_device::tms9129_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : tms9928a_device(mconfig, TMS9129, tag, owner, clock, true, true, false) + : tms9928a_device(mconfig, TMS9129, tag, owner, clock, 342, true, true, false) { } tms9918_device::tms9918_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : tms9928a_device(mconfig, TMS9918, tag, owner, clock, false, false, true) + : tms9928a_device(mconfig, TMS9918, tag, owner, clock, 342, false, false, true) { } tms9918a_device::tms9918a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : tms9928a_device(mconfig, TMS9918A, tag, owner, clock, false, true, true) + : tms9928a_device(mconfig, TMS9918A, tag, owner, clock, 342, false, true, true) { } tms9118_device::tms9118_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : tms9928a_device(mconfig, TMS9118, tag, owner, clock, false, true, false) + : tms9928a_device(mconfig, TMS9118, tag, owner, clock, 342, false, true, false) { } tms9128_device::tms9128_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : tms9928a_device(mconfig, TMS9128, tag, owner, clock, false, true, false) + : tms9928a_device(mconfig, TMS9128, tag, owner, clock, 342, false, true, false) { } tms9929_device::tms9929_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : tms9928a_device(mconfig, TMS9929, tag, owner, clock, true, false, true) + : tms9928a_device(mconfig, TMS9929, tag, owner, clock, 342, true, false, true) { } tms9929a_device::tms9929a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : tms9928a_device(mconfig, TMS9929A, tag, owner, clock, true, true, true) + : tms9928a_device(mconfig, TMS9929A, tag, owner, clock, 342, true, true, true) { } efo90501_device::efo90501_device( const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : tms9928a_device(mconfig, EFO90501, tag, owner, clock, true, true, true) + : tms9928a_device(mconfig, EFO90501, tag, owner, clock, 346, true, true, true) { } @@ -143,7 +144,7 @@ device_memory_interface::space_config_vector tms9928a_device::memory_space_confi }; } -READ8_MEMBER( tms9928a_device::read ) +uint8_t tms9928a_device::read(offs_t offset) { uint8_t value = 0; @@ -155,7 +156,7 @@ READ8_MEMBER( tms9928a_device::read ) return value; } -WRITE8_MEMBER( tms9928a_device::write ) +void tms9928a_device::write(offs_t offset, uint8_t data) { if ((offset & 1) == 0) vram_write(data); @@ -165,11 +166,11 @@ WRITE8_MEMBER( tms9928a_device::write ) u8 tms9928a_device::vram_read() { - // prevent debugger from changing the address base - if (machine().side_effects_disabled()) return 0; - uint8_t data = m_ReadAhead; + // prevent debugger from changing the address base + if (machine().side_effects_disabled()) return data; + m_ReadAhead = m_vram_space->read_byte(m_Addr); m_Addr = (m_Addr + 1) & (m_vram_size - 1); m_latch = 0; @@ -192,11 +193,11 @@ void tms9928a_device::vram_write(u8 data) u8 tms9928a_device::register_read() { - // prevent debugger from changing the internal state - if (machine().side_effects_disabled()) return 0; - uint8_t data = m_StatusReg; + // prevent debugger from changing the internal state + if (machine().side_effects_disabled()) return data; + m_StatusReg = m_FifthSprite; check_interrupt(); m_latch = 0; @@ -371,7 +372,7 @@ void tms9928a_device::device_timer(emu_timer &timer, device_timer_id id, int par if ( y < 0 || y >= 192 || ! (m_Regs[1] & 0x40) ) { /* Draw backdrop colour */ - for ( int i = 0; i < TOTAL_HORZ; i++ ) + for ( int i = 0; i < m_total_horz; i++ ) p[i] = pen(BackColour); /* vblank is set at the last cycle of the first inactive line */ @@ -650,7 +651,7 @@ void tms9928a_device::device_timer(emu_timer &timer, device_timer_id id, int par } /* Right border */ - for ( int i = HORZ_DISPLAY_START + 256; i < TOTAL_HORZ; i++ ) + for ( int i = HORZ_DISPLAY_START + 256; i < m_total_horz; i++ ) p[i] = pen(BackColour); } @@ -734,7 +735,7 @@ void tms9928a_device::device_start() m_vram_space = &space(AS_DATA); /* back bitmap */ - m_tmpbmp.allocate(TOTAL_HORZ, TOTAL_VERT_PAL); + m_tmpbmp.allocate(m_total_horz, TOTAL_VERT_PAL); m_line_timer = timer_alloc(TIMER_LINE); m_gromclk_timer = timer_alloc(GROMCLK); diff --git a/src/devices/video/tms9928a.h b/src/devices/video/tms9928a.h index 0798183f0ea..72c466d464b 100644 --- a/src/devices/video/tms9928a.h +++ b/src/devices/video/tms9928a.h @@ -73,13 +73,8 @@ public: auto int_callback() { return m_out_int_line_cb.bind(); } auto gromclk_callback() { return m_out_gromclk_cb.bind(); } - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); - - DECLARE_READ8_MEMBER( vram_r ) { return vram_read(); } - DECLARE_WRITE8_MEMBER( vram_w ) { vram_write(data); } - DECLARE_READ8_MEMBER( register_r ) { return register_read(); } - DECLARE_WRITE8_MEMBER( register_w ) { register_write(data); } + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); u8 vram_read(); void vram_write(u8 data); @@ -94,7 +89,7 @@ public: void reset_line(int state) { if (state==ASSERT_LINE) device_reset(); } protected: - tms9928a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool is_50hz, bool is_reva, bool is_99); + tms9928a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint16_t horz_total, bool is_50hz, bool is_reva, bool is_99); // device-level overrides virtual void device_config_complete() override; @@ -139,6 +134,7 @@ private: uint16_t m_spritepattern; int m_colourmask; int m_patternmask; + const uint16_t m_total_horz; const bool m_50hz; const bool m_reva; const bool m_99; diff --git a/src/devices/video/upd3301.h b/src/devices/video/upd3301.h index 80e9346eb6c..147c12c5b7d 100644 --- a/src/devices/video/upd3301.h +++ b/src/devices/video/upd3301.h @@ -43,26 +43,6 @@ #define UPD3301_DRAW_CHARACTER_MEMBER(_name) void _name(bitmap_rgb32 &bitmap, int y, int sx, uint8_t cc, uint8_t lc, int hlgt, int rvv, int vsp, int sl0, int sl12, int csr, int gpa) -#define MCFG_UPD3301_CHARACTER_WIDTH(_value) \ - downcast<upd3301_device &>(*device).set_character_width(_value); - -#define MCFG_UPD3301_DRAW_CHARACTER_CALLBACK_OWNER(_class, _method) \ - downcast<upd3301_device &>(*device).set_display_callback(&_class::_method, #_class "::" #_method, this); - -#define MCFG_UPD3301_DRQ_CALLBACK(_write) \ - downcast<upd3301_device &>(*device).set_drq_wr_callback(DEVCB_##_write); - -#define MCFG_UPD3301_INT_CALLBACK(_write) \ - downcast<upd3301_device &>(*device).set_int_wr_callback(DEVCB_##_write); - -#define MCFG_UPD3301_HRTC_CALLBACK(_write) \ - downcast<upd3301_device &>(*device).set_hrtc_wr_callback(DEVCB_##_write); - -#define MCFG_UPD3301_VRTC_CALLBACK(_write) \ - downcast<upd3301_device &>(*device).set_vrtc_wr_callback(DEVCB_##_write); - - - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -93,10 +73,6 @@ public: set_display_callback(draw_character_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr))); } - template <class Object> devcb_base &set_drq_wr_callback(Object &&cb) { return m_write_drq.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_int_wr_callback(Object &&cb) { return m_write_int.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_hrtc_wr_callback(Object &&cb) { return m_write_hrtc.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_vrtc_wr_callback(Object &&cb) { return m_write_vrtc.set_callback(std::forward<Object>(cb)); } auto drq_wr_callback() { return m_write_drq.bind(); } auto int_wr_callback() { return m_write_int.bind(); } auto hrtc_wr_callback() { return m_write_hrtc.bind(); } diff --git a/src/devices/video/upd7220.cpp b/src/devices/video/upd7220.cpp index 16bbc507a5a..d8697222485 100644 --- a/src/devices/video/upd7220.cpp +++ b/src/devices/video/upd7220.cpp @@ -151,7 +151,8 @@ DEFINE_DEVICE_TYPE(UPD7220, upd7220_device, "upd7220", "NEC uPD7220") // default address map void upd7220_device::upd7220_vram(address_map &map) { - map(0x00000, 0x3ffff).ram(); + if (!has_configured_map(0)) + map(0x00000, 0x3ffff).ram(); } @@ -649,7 +650,7 @@ upd7220_device::upd7220_device(const machine_config &mconfig, const char *tag, d m_disp(0), m_gchr(0), m_bitmap_mod(0), - m_space_config("videoram", ENDIANNESS_LITTLE, 16, 18, 0, address_map_constructor(), address_map_constructor(FUNC(upd7220_device::upd7220_vram), this)) + m_space_config("videoram", ENDIANNESS_LITTLE, 16, 18, 0, address_map_constructor(FUNC(upd7220_device::upd7220_vram), this)) { for (int i = 0; i < 16; i++) { @@ -1447,7 +1448,7 @@ void upd7220_device::continue_command() // read - //------------------------------------------------- -READ8_MEMBER( upd7220_device::read ) +uint8_t upd7220_device::read(offs_t offset) { uint8_t data; @@ -1478,7 +1479,7 @@ READ8_MEMBER( upd7220_device::read ) // write - //------------------------------------------------- -WRITE8_MEMBER( upd7220_device::write ) +void upd7220_device::write(offs_t offset, uint8_t data) { if (offset & 1) { @@ -1501,7 +1502,7 @@ WRITE8_MEMBER( upd7220_device::write ) // dack_r - //------------------------------------------------- -READ8_MEMBER( upd7220_device::dack_r ) +uint8_t upd7220_device::dack_r() { return 0; } @@ -1511,7 +1512,7 @@ READ8_MEMBER( upd7220_device::dack_r ) // dack_w - //------------------------------------------------- -WRITE8_MEMBER( upd7220_device::dack_w ) +void upd7220_device::dack_w(uint8_t data) { } diff --git a/src/devices/video/upd7220.h b/src/devices/video/upd7220.h index 6a9837d90eb..7c7370c0cd9 100644 --- a/src/devices/video/upd7220.h +++ b/src/devices/video/upd7220.h @@ -62,19 +62,58 @@ public: // construction/destruction upd7220_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template <typename... T> void set_display_pixels_callback(T &&... args) { m_display_cb = display_pixels_delegate(std::forward<T>(args)...); } - template <typename... T> void set_draw_text_callback(T &&... args) { m_draw_text_cb = draw_text_delegate(std::forward<T>(args)...); } + // FIXME: these should be aware of current device for resolving the tag + template <class FunctionClass> + void set_display_pixels(void (FunctionClass::*init)(bitmap_rgb32 &, int, int, uint32_t), const char *name) + { + m_display_cb = display_pixels_delegate(init, name, nullptr, static_cast<FunctionClass *>(nullptr)); + } + template <class FunctionClass> + void set_display_pixels(void (FunctionClass::*init)(bitmap_rgb32 &, int, int, uint32_t) const, const char *name) + { + m_display_cb = display_pixels_delegate(init, name, nullptr, static_cast<FunctionClass *>(nullptr)); + } + template <class FunctionClass> + void set_display_pixels(const char *devname, void (FunctionClass::*init)(bitmap_rgb32 &, int, int, uint32_t), const char *name) + { + m_display_cb = display_pixels_delegate(init, name, devname, static_cast<FunctionClass *>(nullptr)); + } + template <class FunctionClass> + void set_display_pixels(const char *devname, void (FunctionClass::*init)(bitmap_rgb32 &, int, int, uint32_t) const, const char *name) + { + m_display_cb = display_pixels_delegate(init, name, devname, static_cast<FunctionClass *>(nullptr)); + } + template <class FunctionClass> + void set_draw_text(void (FunctionClass::*init)(bitmap_rgb32 &, uint32_t, int, int, int, int, int, int), const char *name) + { + m_draw_text_cb = draw_text_delegate(init, name, nullptr, static_cast<FunctionClass *>(nullptr)); + } + template <class FunctionClass> + void set_draw_text(void (FunctionClass::*init)(bitmap_rgb32 &, uint32_t, int, int, int, int, int, int) const, const char *name) + { + m_draw_text_cb = draw_text_delegate(init, name, nullptr, static_cast<FunctionClass *>(nullptr)); + } + template <class FunctionClass> + void set_draw_text(const char *devname, void (FunctionClass::*init)(bitmap_rgb32 &, uint32_t, int, int, int, int, int, int), const char *name) + { + m_draw_text_cb = draw_text_delegate(init, name, devname, static_cast<FunctionClass *>(nullptr)); + } + template <class FunctionClass> + void set_draw_text(const char *devname, void (FunctionClass::*init)(bitmap_rgb32 &, uint32_t, int, int, int, int, int, int) const, const char *name) + { + m_draw_text_cb = draw_text_delegate(init, name, devname, static_cast<FunctionClass *>(nullptr)); + } auto drq_wr_callback() { return m_write_drq.bind(); } auto hsync_wr_callback() { return m_write_hsync.bind(); } auto vsync_wr_callback() { return m_write_vsync.bind(); } auto blank_wr_callback() { return m_write_blank.bind(); } - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); - DECLARE_READ8_MEMBER( dack_r ); - DECLARE_WRITE8_MEMBER( dack_w ); + uint8_t dack_r(); + void dack_w(uint8_t data); DECLARE_WRITE_LINE_MEMBER( ext_sync_w ); DECLARE_WRITE_LINE_MEMBER( lpen_w ); diff --git a/src/devices/video/v9938.cpp b/src/devices/video/v9938.cpp index d33331eaa32..f7368efc485 100644 --- a/src/devices/video/v9938.cpp +++ b/src/devices/video/v9938.cpp @@ -369,7 +369,7 @@ uint32_t v99x8_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap return 0; } -READ8_MEMBER( v99x8_device::read ) +uint8_t v99x8_device::read(offs_t offset) { switch (offset & 3) { @@ -379,7 +379,7 @@ READ8_MEMBER( v99x8_device::read ) return 0xff; } -WRITE8_MEMBER( v99x8_device::write ) +void v99x8_device::write(offs_t offset, uint8_t data) { switch (offset & 3) { diff --git a/src/devices/video/v9938.h b/src/devices/video/v9938.h index 0e1a3640cb9..d0bbf7c48c5 100644 --- a/src/devices/video/v9938.h +++ b/src/devices/video/v9938.h @@ -54,8 +54,8 @@ public: uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - DECLARE_READ8_MEMBER( read ); - DECLARE_WRITE8_MEMBER( write ); + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); uint8_t vram_r(); uint8_t status_r(); diff --git a/src/devices/video/vector.h b/src/devices/video/vector.h index 919395f043a..6b473c3501c 100644 --- a/src/devices/video/vector.h +++ b/src/devices/video/vector.h @@ -62,7 +62,4 @@ private: // device type definition DECLARE_DEVICE_TYPE(VECTOR, vector_device) -#define MCFG_VECTOR_ADD(_tag) \ - MCFG_DEVICE_ADD(_tag, VECTOR, 0) - #endif // MAME_VIDEO_VECTOR_H diff --git a/src/devices/video/vic4567.h b/src/devices/video/vic4567.h index e680a3ff0cf..ecadbfe19d9 100644 --- a/src/devices/video/vic4567.h +++ b/src/devices/video/vic4567.h @@ -110,16 +110,16 @@ public: vic3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - void set_cpu_tag(const char *tag) { m_cpu.set_tag(tag); } + template <typename T> void set_cpu_tag(T &&tag) { m_cpu.set_tag(std::forward<T>(tag)); } void set_vic3_type(vic3_type type) { m_type = type; } - template <class Object> devcb_base &set_dma_read_callback(Object &&cb) { return m_dma_read_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_dma_read_color_callback(Object &&cb) { return m_dma_read_color_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_interrupt_callback(Object &&cb) { return m_interrupt_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_port_changed_callback(Object &&cb) { return m_port_changed_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_lightpen_button_callback(Object &&cb) { return m_lightpen_button_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_lightpen_x_callback(Object &&cb) { return m_lightpen_x_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_lightpen_y_callback(Object &&cb) { return m_lightpen_y_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_c64_mem_r_callback(Object &&cb) { return m_c64_mem_r_cb.set_callback(std::forward<Object>(cb)); } + auto dma_read_callback() { return m_dma_read_cb.bind(); } + auto dma_read_color_callback() { return m_dma_read_color_cb.bind(); } + auto interrupt_callback() { return m_interrupt_cb.bind(); } + auto port_changed_callback() { return m_port_changed_cb.bind(); } + auto lightpen_button_callback() { return m_lightpen_button_cb.bind(); } + auto lightpen_x_callback() { return m_lightpen_x_cb.bind(); } + auto lightpen_y_callback() { return m_lightpen_y_cb.bind(); } + auto c64_mem_r_callback() { return m_c64_mem_r_cb.bind(); } DECLARE_WRITE8_MEMBER(port_w); DECLARE_WRITE8_MEMBER(palette_w); @@ -236,35 +236,4 @@ private: DECLARE_DEVICE_TYPE(VIC3, vic3_device) - -#define MCFG_VIC3_CPU(tag) \ - downcast<vic3_device &>(*device).set_cpu_tag(tag); - -#define MCFG_VIC3_TYPE(type) \ - downcast<vic3_device &>(*device).set_vic3_type((vic3_device::vic3_type::type)); - -#define MCFG_VIC3_DMA_READ_CB(cb) \ - downcast<vic3_device &>(*device).set_dma_read_callback((DEVCB_##cb)); - -#define MCFG_VIC3_DMA_READ_COLOR_CB(cb) \ - downcast<vic3_device &>(*device).set_dma_read_color_callback((DEVCB_##cb)); - -#define MCFG_VIC3_INTERRUPT_CB(cb) \ - downcast<vic3_device &>(*device).set_interrupt_callback((DEVCB_##cb)); - -#define MCFG_VIC3_PORT_CHANGED_CB(cb) \ - downcast<vic3_device &>(*device).set_port_changed_callback((DEVCB_##cb)); - -#define MCFG_VIC3_LIGHTPEN_BUTTON_CB(cb) \ - downcast<vic3_device &>(*device).set_lightpen_button_callback((DEVCB_##cb)); - -#define MCFG_VIC3_LIGHTPEN_X_CB(cb) \ - downcast<vic3_device &>(*device).set_lightpen_x_callback((DEVCB_##cb)); - -#define MCFG_VIC3_LIGHTPEN_Y_CB(cb) \ - downcast<vic3_device &>(*device).set_lightpen_y_callback((DEVCB_##cb)); - -#define MCFG_VIC3_C64_MEM_R_CB(cb) \ - downcast<vic3_device &>(*device).set_c64_mem_r_callback((DEVCB_##cb)); - #endif // MAME_VIDEO_VIC4567_H diff --git a/src/devices/video/voodoo.h b/src/devices/video/voodoo.h index 5c39e867d85..26475f527de 100644 --- a/src/devices/video/voodoo.h +++ b/src/devices/video/voodoo.h @@ -1429,32 +1429,6 @@ enum #define STD_VOODOO_3_CLOCK 132000000 - -/*************************************************************************** - DEVICE CONFIGURATION MACROS -***************************************************************************/ - -#define MCFG_VOODOO_FBMEM(_value) \ - downcast<voodoo_device &>(*device).set_fbmem(_value); - -#define MCFG_VOODOO_TMUMEM(_value1, _value2) \ - downcast<voodoo_device &>(*device).set_tmumem(_value1, _value2); - -#define MCFG_VOODOO_SCREEN_TAG(_tag) \ - downcast<voodoo_device &>(*device).set_screen_tag(_tag); - -#define MCFG_VOODOO_CPU_TAG(_tag) \ - downcast<voodoo_device &>(*device).set_cpu_tag(_tag); - -#define MCFG_VOODOO_VBLANK_CB(_devcb) \ - downcast<voodoo_device &>(*device).set_vblank_callback(DEVCB_##_devcb); - -#define MCFG_VOODOO_STALL_CB(_devcb) \ - downcast<voodoo_device &>(*device).set_stall_callback(DEVCB_##_devcb); - -#define MCFG_VOODOO_PCIINT_CB(_devcb) \ - downcast<voodoo_device &>(*device).set_pciint_callback(DEVCB_##_devcb); - /*************************************************************************** FUNCTION PROTOTYPES ***************************************************************************/ @@ -1470,9 +1444,6 @@ public: void set_tmumem(int value1, int value2) { m_tmumem0 = value1; m_tmumem1 = value2; } template <typename T> void set_screen_tag(T &&tag) { m_screen_finder.set_tag(std::forward<T>(tag)); } template <typename T> void set_cpu_tag(T &&tag) { m_cpu_finder.set_tag(std::forward<T>(tag)); } - template <class Object> devcb_base &set_vblank_callback(Object &&cb) { return m_vblank.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_stall_callback(Object &&cb) { return m_stall.set_callback(std::forward<Object>(cb)); } - template <class Object> devcb_base &set_pciint_callback(Object &&cb) { return m_pciint.set_callback(std::forward<Object>(cb)); } auto vblank_callback() { return m_vblank.bind(); } auto stall_callback() { return m_stall.bind(); } auto pciint_callback() { return m_pciint.bind(); } diff --git a/src/devices/video/voodoo_pci.cpp b/src/devices/video/voodoo_pci.cpp index 82fc89aaa9a..5a78099e01a 100644 --- a/src/devices/video/voodoo_pci.cpp +++ b/src/devices/video/voodoo_pci.cpp @@ -6,27 +6,31 @@ #include "screen.h" -MACHINE_CONFIG_START(voodoo_1_pci_device::device_add_mconfig) - MCFG_DEVICE_ADD("voodoo", VOODOO_1, STD_VOODOO_1_CLOCK) - MCFG_VOODOO_FBMEM(4) - MCFG_VOODOO_TMUMEM(1, 0) -MACHINE_CONFIG_END - -MACHINE_CONFIG_START(voodoo_2_pci_device::device_add_mconfig) - MCFG_DEVICE_ADD("voodoo", VOODOO_2, STD_VOODOO_2_CLOCK) - MCFG_VOODOO_FBMEM(4) - MCFG_VOODOO_TMUMEM(1, 0) -MACHINE_CONFIG_END - -MACHINE_CONFIG_START(voodoo_banshee_pci_device::device_add_mconfig) - MCFG_DEVICE_ADD("voodoo", VOODOO_BANSHEE, STD_VOODOO_BANSHEE_CLOCK) - MCFG_VOODOO_FBMEM(16) -MACHINE_CONFIG_END - -MACHINE_CONFIG_START(voodoo_3_pci_device::device_add_mconfig) - MCFG_DEVICE_ADD("voodoo", VOODOO_3, STD_VOODOO_3_CLOCK) - MCFG_VOODOO_FBMEM(16) -MACHINE_CONFIG_END +void voodoo_1_pci_device::device_add_mconfig(machine_config &config) +{ + VOODOO_1(config, m_voodoo, STD_VOODOO_1_CLOCK); + m_voodoo->set_fbmem(4); + m_voodoo->set_tmumem(1, 0); +} + +void voodoo_2_pci_device::device_add_mconfig(machine_config &config) +{ + VOODOO_2(config, m_voodoo, STD_VOODOO_2_CLOCK); + m_voodoo->set_fbmem(4); + m_voodoo->set_tmumem(1, 0); +} + +void voodoo_banshee_pci_device::device_add_mconfig(machine_config &config) +{ + VOODOO_BANSHEE(config, m_voodoo, STD_VOODOO_BANSHEE_CLOCK); + m_voodoo->set_fbmem(16); +} + +void voodoo_3_pci_device::device_add_mconfig(machine_config &config) +{ + VOODOO_3(config, m_voodoo, STD_VOODOO_3_CLOCK); + m_voodoo->set_fbmem(16); +} DEFINE_DEVICE_TYPE(VOODOO_1_PCI, voodoo_1_pci_device, "voodoo_1_pci", "Voodoo 1 PCI") DEFINE_DEVICE_TYPE(VOODOO_2_PCI, voodoo_2_pci_device, "voodoo_2_pci", "Voodoo 2 PCI") @@ -42,22 +46,22 @@ void voodoo_pci_device::config_map(address_map &map) // VOODOO_1 & VOODOO_2 map void voodoo_pci_device::voodoo_reg_map(address_map &map) { - map(0x0, 0x00ffffff).rw("voodoo", FUNC(voodoo_device::voodoo_r), FUNC(voodoo_device::voodoo_w)); + map(0x0, 0x00ffffff).rw(m_voodoo, FUNC(voodoo_device::voodoo_r), FUNC(voodoo_device::voodoo_w)); } // VOODOO_BANSHEE and VOODOO_3 maps void voodoo_pci_device::banshee_reg_map(address_map &map) { - map(0x0, 0x01ffffff).rw("voodoo", FUNC(voodoo_banshee_device::banshee_r), FUNC(voodoo_banshee_device::banshee_w)); + map(0x0, 0x01ffffff).rw(m_voodoo, FUNC(voodoo_banshee_device::banshee_r), FUNC(voodoo_banshee_device::banshee_w)); } void voodoo_pci_device::lfb_map(address_map &map) { - map(0x0, 0x01ffffff).rw("voodoo", FUNC(voodoo_banshee_device::banshee_fb_r), FUNC(voodoo_banshee_device::banshee_fb_w)); + map(0x0, 0x01ffffff).rw(m_voodoo, FUNC(voodoo_banshee_device::banshee_fb_r), FUNC(voodoo_banshee_device::banshee_fb_w)); } void voodoo_pci_device::io_map(address_map &map) { - map(0x000, 0x0ff).rw("voodoo", FUNC(voodoo_banshee_device::banshee_io_r), FUNC(voodoo_banshee_device::banshee_io_w)); + map(0x000, 0x0ff).rw(m_voodoo, FUNC(voodoo_banshee_device::banshee_io_r), FUNC(voodoo_banshee_device::banshee_io_w)); } voodoo_pci_device::voodoo_pci_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) |