diff --git a/src/devices/video/i8275.cpp b/src/devices/video/i8275.cpp index 6fbf71f211f..96484294ece 100644 --- a/src/devices/video/i8275.cpp +++ b/src/devices/video/i8275.cpp @@ -11,7 +11,6 @@ TODO: - double spaced rows - - blanking of top and bottom rows when underline MSB is set - end of row/screen - stop dma - preset counters - how it affects DMA and HRTC? @@ -120,7 +119,6 @@ i8275_device::i8275_device(const machine_config &mconfig, const char *tag, devic m_rvv(0), m_lten(0), m_scanline(0), - m_du(false), m_dma_stop(false), m_end_of_screen(false), m_preset(false), @@ -175,7 +173,6 @@ void i8275_device::device_start() save_item(NAME(m_irq_scanline)); save_item(NAME(m_vrtc_scanline)); save_item(NAME(m_vrtc_drq_scanline)); - save_item(NAME(m_du)); save_item(NAME(m_dma_stop)); save_item(NAME(m_end_of_screen)); save_item(NAME(m_preset)); @@ -199,6 +196,50 @@ void i8275_device::device_reset() } +//------------------------------------------------- +// vrtc_start - update for beginning of vertical +// retrace period +//------------------------------------------------- + +void i8275_device::vrtc_start() +{ + //LOG("I8275 y %u x %u VRTC 1\n", y, x); + m_write_vrtc(1); + + if (m_status & ST_VE) + { + // reset field attributes + m_hlgt = 0; + m_vsp = 0; + m_gpa = 0; + m_rvv = 0; + m_lten = 0; + + m_dma_stop = false; + m_end_of_screen = false; + + m_cursor_blink++; + m_cursor_blink &= 0x1f; + + m_char_blink++; + m_char_blink &= 0x3f; + m_stored_attr = 0; + } +} + + +//------------------------------------------------- +// vrtc_end - update for end of vertical retrace +// period +//------------------------------------------------- + +void i8275_device::vrtc_end() +{ + //LOG("I8275 y %u x %u VRTC 0\n", y, x); + m_write_vrtc(0); +} + + //------------------------------------------------- // device_timer - handle timer events //------------------------------------------------- @@ -227,10 +268,7 @@ void i8275_device::device_timer(emu_timer &timer, device_timer_id id, int param, m_write_hrtc(0); if (m_scanline == 0) - { - //LOG("I8275 y %u x %u VRTC 0\n", y, x); - m_write_vrtc(0); - } + vrtc_end(); if ((m_status & ST_VE) && m_scanline <= (m_vrtc_scanline - SCANLINES_PER_ROW)) { @@ -239,14 +277,17 @@ void i8275_device::device_timer(emu_timer &timer, device_timer_id id, int param, if (m_dma_idx < CHARACTERS_PER_ROW) { m_status |= ST_DU; - m_du = true; + m_dma_stop = true; + + // blank screen until after VRTC + m_end_of_screen = true; //LOG("I8275 y %u x %u DMA Underrun\n", y, x); m_write_drq(0); } - if (!m_du && !m_dma_stop) + if (!m_dma_stop) { // swap line buffers m_buffer_dma = !m_buffer_dma; @@ -263,42 +304,15 @@ void i8275_device::device_timer(emu_timer &timer, device_timer_id id, int param, } } - if (m_scanline == m_irq_scanline) + if ((m_status & ST_IE) && m_scanline == m_irq_scanline) { - if (m_status & ST_IE) - { - //LOG("I8275 y %u x %u IRQ 1\n", y, x); - m_status |= ST_IR; - m_write_irq(ASSERT_LINE); - } + //LOG("I8275 y %u x %u IRQ 1\n", y, x); + m_status |= ST_IR; + m_write_irq(ASSERT_LINE); } if (m_scanline == m_vrtc_scanline) - { - //LOG("I8275 y %u x %u VRTC 1\n", y, x); - m_write_vrtc(1); - - if (m_status & ST_VE) - { - // reset field attributes - m_hlgt = 0; - m_vsp = 0; - m_gpa = 0; - m_rvv = 0; - m_lten = 0; - - m_du = false; - m_dma_stop = false; - m_end_of_screen = false; - - m_cursor_blink++; - m_cursor_blink &= 0x1f; - - m_char_blink++; - m_char_blink &= 0x3f; - m_stored_attr = 0; - } - } + vrtc_start(); if ((m_status & ST_VE) && m_scanline == m_vrtc_drq_scanline) { @@ -315,7 +329,7 @@ void i8275_device::device_timer(emu_timer &timer, device_timer_id id, int param, if ((m_status & ST_VE) && m_scanline < m_vrtc_scanline) { int line_counter = OFFSET_LINE_COUNTER ? ((lc - 1) % SCANLINES_PER_ROW) : lc; - bool end_of_row = false; + bool end_of_row = (UNDERLINE >= 8) && ((lc == 0) || (lc == SCANLINES_PER_ROW - 1)); int fifo_idx = 0; m_hlgt = (m_stored_attr & FAC_H) ? 1 : 0; m_vsp = (m_stored_attr & FAC_B) ? 1 : 0; @@ -463,32 +477,38 @@ void i8275_device::device_timer(emu_timer &timer, device_timer_id id, int param, READ8_MEMBER( i8275_device::read ) { - uint8_t data; - if (offset & 0x01) { - data = m_status; + uint8_t status = m_status; - if (m_status & ST_IR) + if (!machine().side_effects_disabled()) { - //LOG("I8275 IRQ 0\n"); - m_write_irq(CLEAR_LINE); + if (m_status & ST_IR) + { + //LOG("I8275 IRQ 0\n"); + m_write_irq(CLEAR_LINE); + } + + m_status &= ~(ST_IR | ST_LP | ST_IC | ST_DU | ST_FO); } - m_status &= ~(ST_IR | ST_LP | ST_IC | ST_DU | ST_FO); + return status; } else { - data = m_param[m_param_idx]; - m_param_idx++; + uint8_t data = m_param[m_param_idx]; - if (m_param_idx > m_param_end) + if (!machine().side_effects_disabled()) { - m_status |= ST_IC; + m_param_idx++; + if (m_param_idx > m_param_end) + { + m_status |= ST_IC; + } } - } - return data; + return data; + } } diff --git a/src/devices/video/i8275.h b/src/devices/video/i8275.h index bf4dc21206f..f3d248643b4 100644 --- a/src/devices/video/i8275.h +++ b/src/devices/video/i8275.h @@ -103,6 +103,9 @@ protected: virtual void device_reset() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + void vrtc_start(); + void vrtc_end(); + void recompute_parameters(); enum @@ -213,7 +216,6 @@ protected: int m_irq_scanline; int m_vrtc_scanline; int m_vrtc_drq_scanline; - bool m_du; bool m_dma_stop; bool m_end_of_screen; bool m_preset; diff --git a/src/mame/drivers/ms6102.cpp b/src/mame/drivers/ms6102.cpp index ba5bedd6800..2b1183db73e 100644 --- a/src/mame/drivers/ms6102.cpp +++ b/src/mame/drivers/ms6102.cpp @@ -185,7 +185,7 @@ I8275_DRAW_CHARACTER_MEMBER(ms6102_state::display_pixels) { const rgb_t *palette = m_palette->palette()->entry_list_raw(); u8 gfx = (lten) ? 0xff : 0; - if (linecount < 12 && !vsp) + if (!vsp) gfx = m_p_chargen[linecount | (charcode << 4)]; if (rvv) @@ -284,23 +284,23 @@ void ms6102_state::machine_start() // copy over the ascii chars into their new positions (lines 0-7) for (i = 0x20; i < 0x80; i++) for (j = 0; j < 8; j++) - m_p_chargen[i*16+j] = m_p_chargen[0x1800+i*8+j]; + m_p_chargen[i*16+j+1] = m_p_chargen[0x1800+i*8+j]; // copy the russian symbols to codes 0xc0-0xff for now for (i = 0xc0; i < 0x100; i++) for (j = 0; j < 8; j++) - m_p_chargen[i*16+j] = m_p_chargen[0x1800+i*8+j]; + m_p_chargen[i*16+j+1] = m_p_chargen[0x1800+i*8+j]; // for punctuation, get the last 4 lines into place for (i = 0x20; i < 0x40; i++) for (j = 0; j < 4; j++) - m_p_chargen[i*16+8+j] = m_p_chargen[0x1700+i*8+j]; + m_p_chargen[i*16+8+j+1] = m_p_chargen[0x1700+i*8+j]; // for letters, get the last 4 lines into place for (i = 0x40; i < 0x80; i++) for (j = 0; j < 4; j++) - m_p_chargen[i*16+8+j] = m_p_chargen[0x1a00+i*8+j]; + m_p_chargen[i*16+8+j+1] = m_p_chargen[0x1a00+i*8+j]; // for russian, get the last 4 lines into place for (i = 0xc0; i < 0x100; i++) for (j = 0; j < 4; j++) - m_p_chargen[i*16+8+j] = m_p_chargen[0x1604+i*8+j]; + m_p_chargen[i*16+8+j+1] = m_p_chargen[0x1604+i*8+j]; }