diff --git a/src/devices/video/mc6845.cpp b/src/devices/video/mc6845.cpp index 0189bd96f7d..4fa82cf6c35 100644 --- a/src/devices/video/mc6845.cpp +++ b/src/devices/video/mc6845.cpp @@ -406,6 +406,9 @@ int mc6845_device::vsync_r() void mc6845_device::recompute_parameters(bool postload) { + bool zero_horizontal_width = (m_horiz_disp == 0); + bool zero_vertical_height = (m_vert_disp == 0); + uint16_t hsync_on_pos, hsync_off_pos, vsync_on_pos, vsync_off_pos; uint16_t video_char_height = m_max_ras_addr + (MODE_INTERLACE_AND_VIDEO ? m_interlace_adjust : m_noninterlace_adjust); // fix garbage at the bottom of the screen (eg victor9k) @@ -417,8 +420,22 @@ void mc6845_device::recompute_parameters(bool postload) uint16_t vert_pix_total = (m_vert_char_total + 1) * video_char_height + m_vert_total_adj; /* determine the visible area, avoid division by 0 */ - uint16_t max_visible_x = m_horiz_disp * m_hpixels_per_column - 1; - uint16_t max_visible_y = m_vert_disp * video_char_height - 1; + uint16_t visible_width = zero_horizontal_width ? m_visible_width : (m_horiz_disp * m_hpixels_per_column); + uint16_t visible_height = zero_vertical_height ? m_visible_height : (m_vert_disp * video_char_height); + + // Check to see visual width or height needs to be adjusted due to changes with total + if (zero_horizontal_width || zero_vertical_height) + { + if (visible_width > horiz_pix_total) + { + visible_width = horiz_pix_total; + } + + if (visible_height > vert_pix_total) + { + visible_height = vert_pix_total; + } + } /* determine the syncing positions */ uint8_t horiz_sync_char_width = m_sync_width & 0x0f; @@ -452,13 +469,13 @@ void mc6845_device::recompute_parameters(bool postload) /* update only if screen parameters changed, unless we are coming here after loading the saved state */ if (postload || (horiz_pix_total != m_horiz_pix_total) || (vert_pix_total != m_vert_pix_total) || - (max_visible_x != m_max_visible_x) || (max_visible_y != m_max_visible_y) || + (visible_width != m_visible_width) || (visible_height != m_visible_height) || (hsync_on_pos != m_hsync_on_pos) || (vsync_on_pos != m_vsync_on_pos) || (hsync_off_pos != m_hsync_off_pos) || (vsync_off_pos != m_vsync_off_pos)) { /* update the screen if we have valid data */ - if ((horiz_pix_total > 0) && (max_visible_x < horiz_pix_total) && - (vert_pix_total > 0) && (max_visible_y < vert_pix_total) && + if ((horiz_pix_total > 0) && (visible_width <= horiz_pix_total) && + (vert_pix_total > 0) && (visible_height <= vert_pix_total) && (hsync_on_pos <= horiz_pix_total) && (vsync_on_pos <= vert_pix_total) && (hsync_on_pos != hsync_off_pos)) { @@ -473,23 +490,33 @@ void mc6845_device::recompute_parameters(bool postload) // Also, the mode-register change needs to be added to the changed-parameter tests above. if (MODE_INTERLACE_AND_VIDEO) { - //max_visible_y *= 2; + //visible_height *= 2; //vert_pix_total *= 2; } if(m_show_border_area) + { visarea.set(0, horiz_pix_total-2, 0, vert_pix_total-2); + } else - visarea.set(0 + m_visarea_adjust_min_x, max_visible_x + m_visarea_adjust_max_x, 0 + m_visarea_adjust_min_y, max_visible_y + m_visarea_adjust_max_y); + { + visarea.set( + 0 + m_visarea_adjust_min_x, visible_width - 1 + m_visarea_adjust_max_x, + 0 + m_visarea_adjust_min_y, visible_height - 1 + m_visarea_adjust_max_y); + } - LOGCONF("M6845 config screen: HTOTAL: %d VTOTAL: %d MAX_X: %d MAX_Y: %d HSYNC: %d-%d VSYNC: %d-%d Freq: %ffps\n", - horiz_pix_total, vert_pix_total, max_visible_x, max_visible_y, hsync_on_pos, hsync_off_pos - 1, vsync_on_pos, vsync_off_pos - 1, refresh.as_hz()); + LOGCONF("M6845 config screen: HTOTAL: %d VTOTAL: %d VIS_WIDTH: %d VIS_HEIGHT: %d HSYNC: %d-%d VSYNC: %d-%d Freq: %ffps\n", + horiz_pix_total, vert_pix_total, visible_width, visible_height, hsync_on_pos, hsync_off_pos - 1, vsync_on_pos, vsync_off_pos - 1, refresh.as_hz()); if (has_screen()) + { screen().configure(horiz_pix_total, vert_pix_total, visarea, refresh.as_attoseconds()); + } if(!m_reconfigure_cb.isnull()) + { m_reconfigure_cb(horiz_pix_total, vert_pix_total, visarea, refresh.as_attoseconds()); + } m_has_valid_parameters = true; } @@ -498,8 +525,8 @@ void mc6845_device::recompute_parameters(bool postload) m_horiz_pix_total = horiz_pix_total; m_vert_pix_total = vert_pix_total; - m_max_visible_x = max_visible_x; - m_max_visible_y = max_visible_y; + m_visible_width = visible_width; + m_visible_height = visible_height; m_hsync_on_pos = hsync_on_pos; m_hsync_off_pos = hsync_off_pos; m_vsync_on_pos = vsync_on_pos; @@ -671,6 +698,7 @@ bool hd6845s_device::check_cursor_visible(uint16_t ra, uint16_t line_addr) TIMER_CALLBACK_MEMBER(mc6845_device::handle_line_timer) { bool new_vsync = m_vsync; + bool nonzero_horizontal_width = (m_horiz_disp != 0); m_character_counter = 0; m_cursor_x = -1; @@ -748,8 +776,11 @@ TIMER_CALLBACK_MEMBER(mc6845_device::handle_line_timer) if ( m_line_enable_ff ) { - /* Schedule DE off signal change */ - m_de_off_timer->adjust(cclks_to_attotime(m_horiz_disp)); + if (nonzero_horizontal_width) + { + /* Schedule DE off signal change */ + m_de_off_timer->adjust(cclks_to_attotime(m_horiz_disp)); + } /* Is cursor visible on this line? */ if (check_cursor_visible(m_raster_counter, m_line_address)) @@ -769,7 +800,7 @@ TIMER_CALLBACK_MEMBER(mc6845_device::handle_line_timer) /* Set VSYNC and DE signals */ set_vsync( new_vsync ); - set_de( m_line_enable_ff ? true : false ); + set_de( (m_line_enable_ff && nonzero_horizontal_width) ? true : false ); } @@ -914,6 +945,7 @@ uint8_t mc6845_device::draw_scanline(int y, bitmap_rgb32 &bitmap, const rectangl { /* compute the current raster line */ uint8_t ra = y % (m_max_ras_addr + (MODE_INTERLACE_AND_VIDEO ? m_interlace_adjust : m_noninterlace_adjust)); + bool nonzero_horizontal_width = (m_horiz_disp != 0); // Check if the cursor is visible and is on this scanline. int cursor_visible = check_cursor_visible(ra, m_current_disp_addr); @@ -922,7 +954,7 @@ uint8_t mc6845_device::draw_scanline(int y, bitmap_rgb32 &bitmap, const rectangl // is in units of characters and is relative to the start of the // displayable area, not relative to the screen bitmap origin. int8_t cursor_x = cursor_visible ? (m_cursor_addr - m_current_disp_addr) : -1; - int de = (y <= m_max_visible_y) ? 1 : 0; + int de = ((y < m_visible_height) && nonzero_horizontal_width) ? 1 : 0; int vbp = m_vert_pix_total - m_vsync_off_pos; if (vbp < 0) vbp = 0; int hbp = m_horiz_pix_total - m_hsync_off_pos; @@ -1036,10 +1068,11 @@ void mc6845_device::device_start() m_upd_adr_timer = timer_alloc(FUNC(mc6845_device::adr_update_tick), this); m_upd_trans_timer = timer_alloc(FUNC(mc6845_device::transparent_update_tick), this); - /* Use some large startup values */ - m_horiz_char_total = 0xff; + // Make sure m_horiz_char_total/m_vert_char_total are less than m_horiz_disp/m_vert_disp + // to avoid calculating startup resolution before values are valid + m_horiz_char_total = 0; m_max_ras_addr = 0x1f; - m_vert_char_total = 0x7f; + m_vert_char_total = 0; m_mode_control = 0x00; m_supports_disp_start_addr_r = false; // MC6845 can not read Display Start (double checked on datasheet) @@ -1059,13 +1092,13 @@ void mc6845_device::device_start() m_de = 0; m_sync_width = 1; m_horiz_pix_total = m_vert_pix_total = 0; - m_max_visible_x = m_max_visible_y = 0; + m_visible_width = m_visible_height = 0; m_hsync_on_pos = m_vsync_on_pos = 0; m_hsync_off_pos = m_vsync_off_pos = 0; m_vsync = m_hsync = 0; m_cur = 0; m_line_counter = 0; - m_horiz_disp = m_vert_disp = 0; + m_horiz_disp = m_vert_disp = 0x7f; m_vert_sync_pos = 0; m_vert_total_adj = 0; m_cursor_start_ras = m_cursor_end_ras = m_cursor_addr = 0; diff --git a/src/devices/video/mc6845.h b/src/devices/video/mc6845.h index 43338ca1777..eee768de1fe 100644 --- a/src/devices/video/mc6845.h +++ b/src/devices/video/mc6845.h @@ -202,8 +202,8 @@ protected: /* These computed are used to define the screen parameters for a driver */ uint16_t m_horiz_pix_total; uint16_t m_vert_pix_total; - uint16_t m_max_visible_x; - uint16_t m_max_visible_y; + uint16_t m_visible_width; + uint16_t m_visible_height; uint16_t m_hsync_on_pos; uint16_t m_hsync_off_pos; uint16_t m_vsync_on_pos; diff --git a/src/mame/heathkit/tlb.cpp b/src/mame/heathkit/tlb.cpp index 98347546c05..becfa6eb5f5 100644 --- a/src/mame/heathkit/tlb.cpp +++ b/src/mame/heathkit/tlb.cpp @@ -19,8 +19,6 @@ - 49/50 row mode only shows half the screen. - In 49/50 row mode, character descenders are cut off. - Screen saver does not disable the screen - - With superset slot option - - Screensaver freezes the screen instead of blanking the screen ****************************************************************************/ /*************************************************************************** @@ -873,6 +871,7 @@ ROM_START( h19 ) ROM_LOAD( "2716_444-37_h19keyb.u445", 0x0000, 0x0800, CRC(5c3e6972) SHA1(df49ce64ae48652346a91648c58178a34fb37d3c)) ROM_END + ROM_START( super19 ) // Super-19 ROM ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASEFF ) @@ -887,6 +886,7 @@ ROM_START( super19 ) ROM_LOAD( "2716_444-37_h19keyb.u445", 0x0000, 0x0800, CRC(5c3e6972) SHA1(df49ce64ae48652346a91648c58178a34fb37d3c)) ROM_END + ROM_START( superset ) // SuperSet ROM ROM_REGION( 0x4000, "maincpu", ROMREGION_ERASEFF ) @@ -905,6 +905,7 @@ ROM_START( superset ) ROM_LOAD( "2716_101-422_superset_kbd.u445", 0x0000, 0x0800, CRC(549d15b3) SHA1(981962e5e05bbdc5a66b0e86870853ce5596e877)) ROM_END + ROM_START( watz19 ) ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASEFF ) ROM_DEFAULT_BIOS("watzman-a") @@ -925,6 +926,7 @@ ROM_START( watz19 ) ROM_LOAD( "keybd.u445", 0x0000, 0x0800, CRC(58dc8217) SHA1(1b23705290bdf9fc6342065c6a528c04bff67b13)) ROM_END + ROM_START( ultra19 ) // Ultra ROM ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASEFF ) @@ -939,6 +941,7 @@ ROM_START( ultra19 ) ROM_LOAD( "2716_h19_ultra_keyboard.u445", 0x0000, 0x0800, CRC(76130c92) SHA1(ca39c602af48505139d2750a084b5f8f0e662ff7)) ROM_END + ROM_START( gp19 ) // GP-19 ROMs ROM_REGION( 0x3000, "maincpu", ROMREGION_ERASEFF ) @@ -955,6 +958,7 @@ ROM_START( gp19 ) ROM_LOAD( "2716_444-37_h19keyb.u445", 0x0000, 0x0800, CRC(5c3e6972) SHA1(df49ce64ae48652346a91648c58178a34fb37d3c)) ROM_END + ROM_START( imaginator ) // Program code ROM_REGION( 0x4000, "maincpu", ROMREGION_ERASEFF ) @@ -1096,6 +1100,7 @@ ioport_constructor heath_super19_tlb_device::device_input_ports() const return INPUT_PORTS_NAME(super19); } + /** * Superset ROM * @@ -1119,6 +1124,7 @@ void heath_superset_tlb_device::device_add_mconfig(machine_config &config) // per line updates are needed for onscreen menu to display properly m_screen->set_video_attributes(VIDEO_UPDATE_SCANLINE); + m_crtc->set_begin_update_callback(FUNC(heath_superset_tlb_device::crtc_begin_update)); m_crtc->set_update_row_callback(FUNC(heath_superset_tlb_device::crtc_update_row)); // link up the serial port outputs to font chip. @@ -1181,6 +1187,11 @@ void heath_superset_tlb_device::crtc_reg_w(offs_t reg, uint8_t val) heath_tlb_device::crtc_reg_w(reg, val); } +MC6845_BEGIN_UPDATE(heath_superset_tlb_device::crtc_begin_update) +{ + bitmap.fill(rgb_t::black(), cliprect); +} + MC6845_UPDATE_ROW(heath_superset_tlb_device::crtc_update_row) { rgb_t const *const palette = m_palette->palette()->entry_list_raw(); @@ -1243,6 +1254,7 @@ void heath_superset_tlb_device::out2_internal(int data) m_selected_char_set = (m_selected_char_set & 0x0a) | (data & 0x01); } + /** * Watzman ROM * @@ -1263,6 +1275,7 @@ ioport_constructor heath_watz_tlb_device::device_input_ports() const return INPUT_PORTS_NAME(watz19); } + /** * UltraROM * @@ -1301,6 +1314,7 @@ ioport_constructor heath_ultra_tlb_device::device_input_ports() const return INPUT_PORTS_NAME(ultra19); } + /** * Northwest Digital Systems GP-19 add-in board */ @@ -1397,7 +1411,6 @@ void heath_gp19_tlb_device::latch_u5_w(uint8_t data) } } - MC6845_UPDATE_ROW(heath_gp19_tlb_device::crtc_update_row) { rgb_t const *const palette = m_palette->palette()->entry_list_raw(); diff --git a/src/mame/heathkit/tlb.h b/src/mame/heathkit/tlb.h index 55b11d1c98d..1380f88dd69 100644 --- a/src/mame/heathkit/tlb.h +++ b/src/mame/heathkit/tlb.h @@ -169,6 +169,7 @@ protected: void mem_map(address_map &map); void io_map(address_map &map); + MC6845_BEGIN_UPDATE(crtc_begin_update); virtual MC6845_UPDATE_ROW(crtc_update_row) override; void dtr_internal(int data);