i8275: Blank top and bottom row lines when underline is greater than 7

- Start offloading parts of the device_timer routine to helper functions (nw)
- Allow side effects of reads to be disabled (nw)
This commit is contained in:
AJR 2018-05-21 11:30:01 -04:00
parent fe342b9877
commit e796d56660
3 changed files with 84 additions and 62 deletions

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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];
}