mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
i8275: handle invisible field attributes and "end of row - stop dma" special code better; honor Video Enable bit.
Fixes MT05764. No visual change on mikromik, tim100, zorba, and radio86 clones.
This commit is contained in:
parent
e0ac072a29
commit
f652d21e16
@ -11,6 +11,9 @@
|
||||
TODO:
|
||||
|
||||
- double spaced rows
|
||||
- blanking of top and bottom rows when underline MSB is set
|
||||
- end of row/screen - stop dma
|
||||
- preset counters
|
||||
|
||||
*/
|
||||
|
||||
@ -106,6 +109,8 @@ i8275_device::i8275_device(const machine_config &mconfig, const char *tag, devic
|
||||
m_param_idx(0),
|
||||
m_param_end(0),
|
||||
m_buffer_idx(0),
|
||||
m_fifo_idx(0),
|
||||
m_dma_idx(0),
|
||||
m_fifo_next(false),
|
||||
m_buffer_dma(0),
|
||||
m_lpen(0),
|
||||
@ -156,6 +161,7 @@ void i8275_device::device_start()
|
||||
save_item(NAME(m_buffer[1]));
|
||||
save_item(NAME(m_buffer_idx));
|
||||
save_item(NAME(m_fifo_idx));
|
||||
save_item(NAME(m_dma_idx));
|
||||
save_item(NAME(m_fifo_next));
|
||||
save_item(NAME(m_buffer_dma));
|
||||
save_item(NAME(m_lpen));
|
||||
@ -215,8 +221,6 @@ void i8275_device::device_timer(emu_timer &timer, device_timer_id id, int param,
|
||||
break;
|
||||
|
||||
case TIMER_SCANLINE:
|
||||
if (!(m_status & ST_VE)) break;
|
||||
|
||||
//LOG("I8275 y %u x %u HRTC 0\n", y, x);
|
||||
m_write_hrtc(0);
|
||||
|
||||
@ -226,11 +230,11 @@ void i8275_device::device_timer(emu_timer &timer, device_timer_id id, int param,
|
||||
m_write_vrtc(0);
|
||||
}
|
||||
|
||||
if (m_scanline <= (m_vrtc_scanline - SCANLINES_PER_ROW))
|
||||
if ((m_status & ST_VE) && m_scanline <= (m_vrtc_scanline - SCANLINES_PER_ROW))
|
||||
{
|
||||
if (lc == 0)
|
||||
{
|
||||
if (m_buffer_idx < CHARACTERS_PER_ROW)
|
||||
if (m_dma_idx < CHARACTERS_PER_ROW)
|
||||
{
|
||||
m_status |= ST_DU;
|
||||
m_du = true;
|
||||
@ -246,6 +250,7 @@ void i8275_device::device_timer(emu_timer &timer, device_timer_id id, int param,
|
||||
m_buffer_dma = !m_buffer_dma;
|
||||
m_buffer_idx = 0;
|
||||
m_fifo_idx = 0;
|
||||
m_dma_idx = 0;
|
||||
|
||||
if ((m_scanline < (m_vrtc_scanline - SCANLINES_PER_ROW)))
|
||||
{
|
||||
@ -271,37 +276,41 @@ void i8275_device::device_timer(emu_timer &timer, device_timer_id id, int param,
|
||||
//LOG("I8275 y %u x %u VRTC 1\n", y, x);
|
||||
m_write_vrtc(1);
|
||||
|
||||
// reset field attributes
|
||||
m_hlgt = 0;
|
||||
m_vsp = 0;
|
||||
m_gpa = 0;
|
||||
m_rvv = 0,
|
||||
m_lten = 0;
|
||||
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_du = false;
|
||||
m_dma_stop = false;
|
||||
m_end_of_screen = false;
|
||||
|
||||
m_cursor_blink++;
|
||||
m_cursor_blink &= 0x1f;
|
||||
m_cursor_blink++;
|
||||
m_cursor_blink &= 0x1f;
|
||||
|
||||
m_char_blink++;
|
||||
m_char_blink &= 0x3f;
|
||||
m_stored_attr = 0;
|
||||
m_char_blink++;
|
||||
m_char_blink &= 0x3f;
|
||||
m_stored_attr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_scanline == m_vrtc_drq_scanline)
|
||||
if ((m_status & ST_VE) && m_scanline == m_vrtc_drq_scanline)
|
||||
{
|
||||
// swap line buffers
|
||||
m_buffer_dma = !m_buffer_dma;
|
||||
m_buffer_idx = 0;
|
||||
m_fifo_idx = 0;
|
||||
m_dma_idx = 0;
|
||||
|
||||
// start DMA burst
|
||||
m_drq_on_timer->adjust(clocks_to_attotime(DMA_BURST_SPACE));
|
||||
}
|
||||
|
||||
if (m_scanline < m_vrtc_scanline)
|
||||
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;
|
||||
@ -493,24 +502,41 @@ WRITE8_MEMBER( i8275_device::write )
|
||||
|
||||
switch (data >> 5)
|
||||
{
|
||||
/*
|
||||
* DMA requests stop;
|
||||
* IE is reset, interrupts are disabled;
|
||||
* VE is reset, VSP output is used to blank the screen;
|
||||
* HRTC and VRTC continue to run;
|
||||
* HRTC and VRTC timing are random on power-up.
|
||||
*/
|
||||
case CMD_RESET:
|
||||
LOG("I8275 Reset\n");
|
||||
|
||||
m_status &= ~ST_IE;
|
||||
m_status &= ~(ST_IE | ST_VE);
|
||||
LOG("I8275 IRQ 0\n");
|
||||
m_write_irq(CLEAR_LINE);
|
||||
m_write_drq(0);
|
||||
m_drq_on_timer->adjust(attotime::zero);
|
||||
|
||||
m_param_idx = REG_SCN1;
|
||||
m_param_end = REG_SCN4;
|
||||
break;
|
||||
|
||||
/*
|
||||
* IE is set, interrupts are enabled;
|
||||
* VE is set, video is enabled;
|
||||
* DMA requests begin.
|
||||
*/
|
||||
case CMD_START_DISPLAY:
|
||||
m_param[REG_DMA] = data;
|
||||
LOG("I8275 Start Display %u %u\n", DMA_BURST_COUNT, DMA_BURST_SPACE);
|
||||
m_status |= (ST_IE | ST_VE);
|
||||
break;
|
||||
|
||||
/*
|
||||
* interrupts remain enabled;
|
||||
* HRTC and VRTC continue to run.
|
||||
*/
|
||||
case CMD_STOP_DISPLAY:
|
||||
LOG("I8275 Stop Display\n");
|
||||
m_status &= ~ST_VE;
|
||||
@ -540,7 +566,6 @@ WRITE8_MEMBER( i8275_device::write )
|
||||
|
||||
case CMD_PRESET_COUNTERS:
|
||||
LOG("I8275 Preset Counters\n");
|
||||
m_scanline = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -566,7 +591,7 @@ WRITE8_MEMBER( i8275_device::write )
|
||||
|
||||
WRITE8_MEMBER( i8275_device::dack_w )
|
||||
{
|
||||
//LOG("I8275 y %u x %u DACK %04x:%02x %u\n", screen().vpos(), screen().hpos(), offset, data, m_buffer_idx);
|
||||
//LOG("I8275 y %u x %u DACK %04x:%02x %u (%u)\n", screen().vpos(), screen().hpos(), offset, data, m_buffer_idx, m_dma_idx);
|
||||
|
||||
m_write_drq(0);
|
||||
|
||||
@ -584,41 +609,43 @@ WRITE8_MEMBER( i8275_device::dack_w )
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_buffer_idx < ARRAY_LENGTH(m_buffer[m_buffer_dma]))
|
||||
if (m_dma_idx < ARRAY_LENGTH(m_buffer[m_buffer_dma]))
|
||||
m_buffer[m_buffer_dma][m_buffer_idx++] = data;
|
||||
|
||||
if (!VISIBLE_FIELD_ATTRIBUTE && ((data & 0xc0) == 0x80))
|
||||
{
|
||||
m_fifo_next = true;
|
||||
}
|
||||
}
|
||||
|
||||
switch (data)
|
||||
m_dma_idx++;
|
||||
|
||||
switch (data)
|
||||
{
|
||||
case SCC_END_OF_ROW_DMA:
|
||||
// stop DMA
|
||||
// TODO should read one more character if DMA burst not completed
|
||||
m_drq_on_timer->adjust(screen().time_until_pos(screen().vpos() + 1, 0));
|
||||
break;
|
||||
|
||||
case SCC_END_OF_SCREEN_DMA:
|
||||
m_dma_stop = true;
|
||||
// TODO should read one more character if DMA burst not completed
|
||||
break;
|
||||
|
||||
default:
|
||||
if (m_dma_idx == CHARACTERS_PER_ROW)
|
||||
{
|
||||
case SCC_END_OF_ROW_DMA:
|
||||
// stop DMA
|
||||
// TODO should read one more character if DMA burst not completed
|
||||
break;
|
||||
|
||||
case SCC_END_OF_SCREEN_DMA:
|
||||
m_dma_stop = true;
|
||||
// TODO should read one more character if DMA burst not completed
|
||||
break;
|
||||
|
||||
default:
|
||||
if (m_buffer_idx == CHARACTERS_PER_ROW)
|
||||
{
|
||||
// stop DMA
|
||||
}
|
||||
else if (!(m_buffer_idx % DMA_BURST_COUNT))
|
||||
{
|
||||
m_drq_on_timer->adjust(clocks_to_attotime(DMA_BURST_SPACE));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_drq_on_timer->adjust(attotime::zero);
|
||||
}
|
||||
}
|
||||
|
||||
else if (!(m_dma_idx % DMA_BURST_COUNT))
|
||||
{
|
||||
m_drq_on_timer->adjust(clocks_to_attotime(DMA_BURST_SPACE));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_drq_on_timer->adjust(attotime::zero);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -688,6 +715,7 @@ void i8275_device::recompute_parameters()
|
||||
LOG("irq_y %u vrtc_y %u drq_y %u\n", m_irq_scanline, m_vrtc_scanline, m_vrtc_drq_scanline);
|
||||
|
||||
m_scanline_timer->adjust(screen().time_until_pos(0, 0), 0, screen().scan_period());
|
||||
m_scanline = 0;
|
||||
|
||||
if (DOUBLE_SPACED_ROWS) fatalerror("Double spaced rows not supported!");
|
||||
}
|
||||
|
@ -197,6 +197,7 @@ protected:
|
||||
uint8_t m_fifo[2][16];
|
||||
int m_buffer_idx;
|
||||
int m_fifo_idx;
|
||||
int m_dma_idx;
|
||||
bool m_fifo_next;
|
||||
int m_buffer_dma;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user