summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/video/i8275.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/video/i8275.cpp')
-rw-r--r--src/devices/video/i8275.cpp546
1 files changed, 287 insertions, 259 deletions
diff --git a/src/devices/video/i8275.cpp b/src/devices/video/i8275.cpp
index ed3204b8d9f..3da93ce26e6 100644
--- a/src/devices/video/i8275.cpp
+++ b/src/devices/video/i8275.cpp
@@ -1,10 +1,25 @@
// license:BSD-3-Clause
-// copyright-holders:Curt Coder
+// copyright-holders:Curt Coder, AJR
/**********************************************************************
Intel 8275 Programmable CRT Controller
Intel 8276 Small Systems CRT Controller
+ This emulation allows up to four 8275 or 8276 CRTCs connected in
+ parallel and reading out their row buffers simultaneously. The
+ secondary CRTCs are assumed to use identical timings to the
+ primary CRTC and run in perfect sync with each other.
+
+ The features provided by 8276 are practically a subset of the
+ 8275. Light pen input, line attributes, invisible character
+ attributes and DMA bursts are not supported on the 8276. Also,
+ the DRQ and _DACK pins are renamed BRDY (Buffer Ready) and _BS
+ (Buffer Select), and the latter must be asserted coincident
+ with _WR (but not _CS). (Even in systems without a DMAC, the
+ processor usually does not write to the row buffer directly,
+ but enables some pseudo-DMA mode which causes memory read
+ operations to transmit data to the CRTC in the same cycle.)
+
**********************************************************************/
/*
@@ -31,46 +46,6 @@
//**************************************************************************
-static const int DMA_BURST_SPACING[] = { 0, 7, 15, 23, 31, 39, 47, 55 };
-
-
-#define DOUBLE_SPACED_ROWS \
- BIT(m_param[REG_SCN1], 7)
-
-#define CHARACTERS_PER_ROW \
- ((m_param[REG_SCN1] & 0x7f) + 1)
-
-#define VRTC_ROW_COUNT \
- ((m_param[REG_SCN2] >> 6) + 1)
-
-#define CHARACTER_ROWS_PER_FRAME \
- ((m_param[REG_SCN2] & 0x3f) + 1)
-
-#define UNDERLINE \
- (m_param[REG_SCN3] >> 4)
-
-#define SCANLINES_PER_ROW \
- ((m_param[REG_SCN3] & 0x0f) + 1)
-
-#define OFFSET_LINE_COUNTER \
- BIT(m_param[REG_SCN4], 7)
-
-#define VISIBLE_FIELD_ATTRIBUTE \
- BIT(m_param[REG_SCN4], 6)
-
-#define CURSOR_FORMAT \
- ((m_param[REG_SCN4] >> 4) & 0x03)
-
-#define HRTC_COUNT \
- (((m_param[REG_SCN4] & 0x0f) + 1) * 2)
-
-#define DMA_BURST_COUNT \
- (1 << (m_param[REG_DMA] & 0x03))
-
-#define DMA_BURST_SPACE \
- DMA_BURST_SPACING[(m_param[REG_DMA] >> 2) & 0x07]
-
-
const int i8275_device::character_attribute[3][16] =
{
{ 2, 2, 4, 4, 2, 4, 4, 4, 2, 4, 4, 0, 2, 0, 0, 0 },
@@ -108,11 +83,14 @@ i8275_device::i8275_device(const machine_config &mconfig, device_type type, cons
m_write_lc(*this),
m_display_cb(*this),
m_refresh_hack(false),
+ m_next_crtc(*this, finder_base::DUMMY_TAG),
+ m_is_crtc0(true),
m_status(0),
m_param_idx(0),
m_param_end(0),
m_buffer_idx(0),
m_fifo_idx(0),
+ m_fifo_idx_out(0),
m_dma_idx(0),
m_dma_last_char(0),
m_buffer_dma(0),
@@ -140,27 +118,32 @@ i8276_device::i8276_device(const machine_config &mconfig, const char *tag, devic
}
+void i8275_device::device_resolve_objects()
+{
+ if (m_next_crtc.found())
+ m_next_crtc->m_is_crtc0 = false;
+}
+
+
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void i8275_device::device_start()
{
- // get the screen device
- screen().register_screen_bitmap(m_bitmap);
-
- // resolve callbacks
- m_write_drq.resolve_safe();
- m_write_irq.resolve_safe();
- m_write_hrtc.resolve_safe();
- m_write_vrtc.resolve_safe();
- m_write_lc.resolve_safe();
- m_display_cb.resolve();
-
- // allocate timers
- m_hrtc_on_timer = timer_alloc(TIMER_HRTC_ON);
- m_drq_on_timer = timer_alloc(TIMER_DRQ_ON);
- m_scanline_timer = timer_alloc(TIMER_SCANLINE);
+ if (m_is_crtc0)
+ {
+ // get the screen device
+ screen().register_screen_bitmap(m_bitmap);
+
+ // resolve delegates
+ m_display_cb.resolve_safe();
+
+ // allocate timers
+ m_hrtc_on_timer = timer_alloc(FUNC(i8275_device::hrtc_on), this);
+ m_drq_on_timer = timer_alloc(FUNC(i8275_device::drq_on), this);
+ m_scanline_timer = timer_alloc(FUNC(i8275_device::scanline_tick), this);
+ }
// state saving
save_item(NAME(m_status));
@@ -169,6 +152,8 @@ void i8275_device::device_start()
save_item(NAME(m_param_end));
save_item(NAME(m_buffer[0]));
save_item(NAME(m_buffer[1]));
+ save_item(NAME(m_fifo[0]));
+ save_item(NAME(m_fifo[1]));
save_item(NAME(m_buffer_idx));
save_item(NAME(m_fifo_idx));
save_item(NAME(m_dma_idx));
@@ -210,16 +195,13 @@ void i8275_device::device_reset()
void i8275_device::vrtc_start()
{
- //LOG("I8275 y %u x %u VRTC 1\n", y, x);
- m_write_vrtc(1);
-
// reset field attributes
m_field_attr = 0;
// Intel datasheets imply DMA requests begin only after a "Start Display" command is issued.
// WY-100, however, expects a BRDY cycle from the 8276 after the program first configures and stops the display.
// This suggests that DMA bursts proceed as normal in this case, but any characters sent will not be displayed.
- m_buffer_idx = CHARACTERS_PER_ROW;
+ m_buffer_idx = characters_per_row();
m_dma_stop = false;
m_end_of_screen = !(m_status & ST_VE);
@@ -255,214 +237,247 @@ void i8275_device::dma_start()
m_dma_idx = 0;
m_dma_last_char = 0;
- m_drq_on_timer->adjust(clocks_to_attotime(DMA_BURST_SPACE));
+ if (m_is_crtc0)
+ m_drq_on_timer->adjust(clocks_to_attotime(dma_burst_space()));
}
//-------------------------------------------------
-// device_timer - handle timer events
+// timer events
//-------------------------------------------------
-void i8275_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+TIMER_CALLBACK_MEMBER(i8275_device::hrtc_on)
{
- //int y = screen().vpos();
- //int x = screen().hpos();
- int rc = m_scanline / SCANLINES_PER_ROW;
- int lc = m_scanline % SCANLINES_PER_ROW;
+ m_write_hrtc(1);
+}
- switch (id)
- {
- case TIMER_HRTC_ON:
- //LOG("I8275 y %u x %u HRTC 1\n", y, x);
- m_write_hrtc(1);
- break;
+TIMER_CALLBACK_MEMBER(i8275_device::drq_on)
+{
+ m_write_drq(1);
+}
- case TIMER_DRQ_ON:
- //LOG("I8275 y %u x %u DRQ 1\n", y, x);
- m_write_drq(1);
- break;
+TIMER_CALLBACK_MEMBER(i8275_device::scanline_tick)
+{
+ int rc = m_scanline / scanlines_per_row();
+ int lc = m_scanline % scanlines_per_row();
- case TIMER_SCANLINE:
- //LOG("I8275 y %u x %u HRTC 0\n", y, x);
- int line_counter = OFFSET_LINE_COUNTER ? ((lc - 1) % SCANLINES_PER_ROW) : lc;
- m_write_lc(line_counter);
- m_write_hrtc(0);
+ int line_counter = offset_line_counter() ? ((lc - 1) % scanlines_per_row()) : lc;
+ m_write_lc(line_counter);
+ m_write_hrtc(0);
- if (m_scanline == 0)
- vrtc_end();
+ if (m_scanline == 0)
+ vrtc_end();
- if (lc == 0 && m_scanline < m_vrtc_scanline)
+ if (lc == 0 && m_scanline < m_vrtc_scanline)
+ {
+ for (i8275_device *crtc = this; crtc != nullptr; crtc = crtc->m_next_crtc)
{
- if (!m_dma_stop && m_buffer_idx < CHARACTERS_PER_ROW)
+ if (!crtc->m_dma_stop && crtc->m_buffer_idx < characters_per_row())
{
- m_status |= ST_DU;
- m_dma_stop = true;
+ crtc->m_status |= ST_DU;
+ crtc->m_dma_stop = true;
// blank screen until after VRTC
- m_end_of_screen = true;
+ crtc->m_end_of_screen = true;
- //LOG("I8275 y %u x %u DMA Underrun\n", y, x);
-
- m_write_drq(0);
+ crtc->m_write_drq(0);
}
- if (!m_dma_stop)
+ if (!crtc->m_dma_stop)
{
// swap line buffers
- m_buffer_dma = !m_buffer_dma;
+ crtc->m_buffer_dma = !crtc->m_buffer_dma;
- if (m_scanline < (m_vrtc_scanline - SCANLINES_PER_ROW))
- dma_start();
+ if (m_scanline < (m_vrtc_scanline - scanlines_per_row()))
+ crtc->dma_start();
}
}
+ }
- if ((m_status & ST_IE) && !(m_status & ST_IR) && m_scanline == m_irq_scanline)
+ if (m_scanline == m_irq_scanline)
+ {
+ for (i8275_device *crtc = this; crtc != nullptr; crtc = crtc->m_next_crtc)
{
- //LOG("I8275 y %u x %u IRQ 1\n", y, x);
- m_status |= ST_IR;
- m_write_irq(ASSERT_LINE);
+ if ((crtc->m_status & ST_IE) && !(crtc->m_status & ST_IR))
+ {
+ crtc->m_status |= ST_IR;
+ crtc->m_write_irq(ASSERT_LINE);
+ }
}
+ }
- if (m_scanline == m_vrtc_scanline)
- vrtc_start();
+ if (m_scanline == m_vrtc_scanline)
+ {
+ //LOG("I8275 y %u x %u VRTC 1\n", y, x);
+ m_write_vrtc(1);
- if (!m_dma_stop && m_scanline == m_vrtc_drq_scanline)
+ for (i8275_device *crtc = this; crtc != nullptr; crtc = crtc->m_next_crtc)
+ crtc->vrtc_start();
+ }
+
+ if (m_scanline == m_vrtc_drq_scanline)
+ {
+ for (i8275_device *crtc = this; crtc != nullptr; crtc = crtc->m_next_crtc)
{
- // swap line buffers
- m_buffer_dma = !m_buffer_dma;
+ if (!crtc->m_dma_stop)
+ {
+ // swap line buffers
+ crtc->m_buffer_dma = !crtc->m_buffer_dma;
- // start DMA burst
- dma_start();
+ // start DMA burst
+ crtc->dma_start();
+ }
+ }
+ }
+
+ if (m_scanline < m_vrtc_scanline)
+ {
+ int end_of_row = 0;
+ int blank_row = 0;
+ {
+ int n = 0;
+ for (i8275_device *crtc = this; crtc != nullptr; crtc = crtc->m_next_crtc, n++)
+ {
+ if (crtc->m_end_of_screen || !(m_status & ST_VE))
+ end_of_row |= 1 << n;
+ if ((crtc->underline() >= 8) && ((lc == 0) || (lc == scanlines_per_row() - 1)))
+ blank_row |= 1 << n;
+ crtc->m_fifo_idx_out = 0;
+ crtc->m_field_attr = crtc->m_stored_attr;
+ }
}
- if ((m_status & ST_VE) && m_scanline < m_vrtc_scanline)
+ for (int sx = 0; sx < characters_per_row(); sx++)
{
- bool end_of_row = false;
- bool blank_row = (UNDERLINE >= 8) && ((lc == 0) || (lc == SCANLINES_PER_ROW - 1));
- int fifo_idx = 0;
- m_field_attr = m_stored_attr;
+ int n = 0;
+ uint32_t charcode = 0;
+ uint32_t attrcode = 0;
- for (int sx = 0; sx < CHARACTERS_PER_ROW; sx++)
+ for (i8275_device *crtc = this; crtc != nullptr; crtc = crtc->m_next_crtc, n++)
{
- int lineattr = 0;
-
- uint8_t data = (end_of_row || m_end_of_screen) ? 0 : m_buffer[!m_buffer_dma][sx];
- uint8_t attr = m_field_attr;
-
- if ((data & 0xc0) == 0x80)
- {
- // field attribute code
- m_field_attr = data & (FAC_H | FAC_B | FAC_GG | FAC_R | FAC_U);
-
- if (!VISIBLE_FIELD_ATTRIBUTE)
- {
- attr = m_field_attr;
- data = m_fifo[!m_buffer_dma][fifo_idx];
-
- fifo_idx++;
- fifo_idx &= 0xf;
-
- if (blank_row)
- attr |= FAC_B;
- else if (!(m_char_blink < 32))
- attr &= ~FAC_B;
- if (lc != UNDERLINE)
- attr &= ~FAC_U;
- }
- else
- {
- // simply blank the attribute character itself
- attr = FAC_B;
- }
- }
- else if (data >= 0xf0 || end_of_row || m_end_of_screen)
- {
- // special control character
- switch (data)
- {
- case SCC_END_OF_ROW:
- case SCC_END_OF_ROW_DMA:
- end_of_row = true;
- break;
-
- case SCC_END_OF_SCREEN:
- case SCC_END_OF_SCREEN_DMA:
- m_end_of_screen = true;
- break;
- }
- attr = FAC_B;
- }
- else if (data >= 0xc0)
- {
- // character attribute code
- attr = data & (m_char_blink < 32 ? (CA_H | CA_B) : CA_H);
-
- uint8_t ca;
- int cccc = (data >> 2) & 0x0f;
-
- if (lc < UNDERLINE)
- {
- ca = character_attribute[0][cccc];
- }
- else if (lc == UNDERLINE)
- {
- ca = character_attribute[1][cccc];
- }
- else
- {
- ca = character_attribute[2][cccc];
- }
-
- if (ca & CA_LTEN)
- attr |= FAC_U;
- if (ca & CA_VSP)
- attr |= FAC_B;
- lineattr = ca >> 2;
- }
- else
- {
- if (blank_row)
- attr |= FAC_B;
- else if (!(m_char_blink < 32))
- attr &= ~FAC_B;
- if (lc != UNDERLINE)
- attr &= ~FAC_U;
- }
-
- if ((rc == m_param[REG_CUR_ROW]) && (sx == m_param[REG_CUR_COL]))
- {
- if ((CURSOR_FORMAT & 0x02) || (m_cursor_blink < 16))
- {
- if (CURSOR_FORMAT & 0x01)
- attr |= (lc == UNDERLINE) ? FAC_U : 0;
- else
- attr ^= FAC_R;
- }
- }
-
- if (!m_display_cb.isnull())
- m_display_cb(m_bitmap,
+ auto [data, attr] = crtc->char_from_buffer(n, sx, rc, lc, end_of_row, blank_row);
+ charcode |= uint32_t(data) << (n * 8);
+ attrcode |= uint32_t(attr) << (n * 8);
+ }
+
+ m_display_cb(m_bitmap,
sx * m_hpixels_per_column, // x position on screen of starting point
m_scanline, // y position on screen
line_counter, // current line of char
- (data & 0x7f), // char code to be displayed
- lineattr, // line attribute code
- (attr & FAC_U) ? 1 : 0, // light enable signal
- (attr & FAC_R) ? 1 : 0, // reverse video signal
- (attr & FAC_B) ? 1 : 0, // video suppression
- (attr & FAC_GG) >> 2, // general purpose attribute code
- (attr & FAC_H) ? 1 : 0 // highlight
- );
- }
+ charcode, // char code to be displayed
+ attrcode);
+ }
+
+ if ((scanlines_per_row() - lc) == 1)
+ {
+ for (i8275_device *crtc = this; crtc != nullptr; crtc = crtc->m_next_crtc)
+ crtc->m_stored_attr = crtc->m_field_attr;
+ }
+ }
+
+ m_scanline++;
+ m_scanline %= ((character_rows_per_frame() + vrtc_row_count()) * scanlines_per_row());
+}
+
+
+std::pair<uint8_t, uint8_t> i8275_device::char_from_buffer(int n, int sx, int rc, int lc, int &end_of_row, int blank_row)
+{
+ uint8_t data = BIT(end_of_row, n) ? 0 : m_buffer[!m_buffer_dma][sx];
+ uint8_t attr = m_field_attr;
+ int lineattr = 0;
- if ((SCANLINES_PER_ROW - lc) == 1)
- m_stored_attr = m_field_attr;
+ if ((data & 0xc0) == 0x80)
+ {
+ // field attribute code
+ m_field_attr = data & (FAC_H | FAC_B | FAC_GG | FAC_R | FAC_U);
+
+ if (!visible_field_attribute())
+ {
+ attr = m_field_attr;
+ data = m_fifo[!m_buffer_dma][m_fifo_idx_out];
+
+ m_fifo_idx_out++;
+ m_fifo_idx_out &= 0xf;
+
+ if (BIT(blank_row, n))
+ attr |= FAC_B;
+ else if (!(m_char_blink < 32))
+ attr &= ~FAC_B;
+ if (lc != underline())
+ attr &= ~FAC_U;
}
+ else
+ {
+ // simply blank the attribute character itself
+ attr = FAC_B;
+ }
+ }
+ else if (data >= 0xf0 || BIT(end_of_row, n))
+ {
+ // special control character
+ switch (data)
+ {
+ case SCC_END_OF_ROW:
+ case SCC_END_OF_ROW_DMA:
+ end_of_row |= 1 << n;
+ break;
- m_scanline++;
- m_scanline %= ((CHARACTER_ROWS_PER_FRAME + VRTC_ROW_COUNT) * SCANLINES_PER_ROW);
- break;
+ case SCC_END_OF_SCREEN:
+ case SCC_END_OF_SCREEN_DMA:
+ m_end_of_screen = true;
+ break;
+ }
+ attr = FAC_B;
+ }
+ else if (data >= 0xc0)
+ {
+ // character attribute code
+ attr = data & (m_char_blink < 32 ? (CA_H | CA_B) : CA_H);
+
+ uint8_t ca;
+ int cccc = (data >> 2) & 0x0f;
+
+ if (lc < underline())
+ {
+ ca = character_attribute[0][cccc];
+ }
+ else if (lc == underline())
+ {
+ ca = character_attribute[1][cccc];
+ }
+ else
+ {
+ ca = character_attribute[2][cccc];
+ }
+
+ if (ca & CA_LTEN)
+ attr |= FAC_U;
+ if (ca & CA_VSP)
+ attr |= FAC_B;
+ lineattr = ca >> 2;
}
+ else
+ {
+ if (BIT(blank_row, n))
+ attr |= FAC_B;
+ else if (!(m_char_blink < 32))
+ attr &= ~FAC_B;
+ if (lc != underline())
+ attr &= ~FAC_U;
+ }
+
+ if ((rc == m_param[REG_CUR_ROW]) && (sx == m_param[REG_CUR_COL]))
+ {
+ if ((cursor_format() & 0x02) || (m_cursor_blink < 16))
+ {
+ if (cursor_format() & 0x01)
+ attr |= (lc == underline()) ? FAC_U : 0;
+ else
+ attr ^= FAC_R;
+ }
+ }
+
+ return std::make_pair(data & 0x7f, attr | lineattr << 6);
}
@@ -525,12 +540,15 @@ void i8275_device::write(offs_t offset, uint8_t data)
*/
if (m_preset)
{
- int hrtc_on_pos = CHARACTERS_PER_ROW * m_hpixels_per_column;
+ int hrtc_on_pos = characters_per_row() * m_hpixels_per_column;
m_preset = false;
- m_hrtc_on_timer->adjust(screen().time_until_pos(screen().vpos(), hrtc_on_pos), 0, screen().scan_period());
m_scanline = m_vrtc_drq_scanline;
- m_scanline_timer->adjust(screen().time_until_pos(m_vrtc_drq_scanline, 0), 0, screen().scan_period());
+ if (m_is_crtc0)
+ {
+ m_hrtc_on_timer->adjust(screen().time_until_pos(screen().vpos(), hrtc_on_pos), 0, screen().scan_period());
+ m_scanline_timer->adjust(screen().time_until_pos(m_vrtc_drq_scanline, 0), 0, screen().scan_period());
+ }
}
switch (data >> 5)
@@ -549,7 +567,8 @@ void i8275_device::write(offs_t offset, uint8_t data)
LOG("I8275 IRQ 0\n");
m_write_irq(CLEAR_LINE);
m_write_drq(0);
- m_drq_on_timer->adjust(attotime::never);
+ if (m_is_crtc0)
+ m_drq_on_timer->adjust(attotime::never);
m_dma_stop = true;
m_param_idx = REG_SCN1;
@@ -563,7 +582,7 @@ void i8275_device::write(offs_t offset, uint8_t data)
*/
case CMD_START_DISPLAY:
m_param[REG_DMA] = data;
- LOG("I8275 Start Display %u %u\n", DMA_BURST_COUNT, DMA_BURST_SPACE);
+ LOG("I8275 Start Display %u %u\n", dma_burst_count(), dma_burst_space());
m_dma_stop = false;
m_status |= (ST_IE | ST_VE);
break;
@@ -602,8 +621,11 @@ void i8275_device::write(offs_t offset, uint8_t data)
case CMD_PRESET_COUNTERS:
LOG("I8275 Preset Counters\n");
m_preset = true;
- m_scanline_timer->adjust(attotime::never);
- m_hrtc_on_timer->adjust(attotime::never);
+ if (m_is_crtc0)
+ {
+ m_scanline_timer->adjust(attotime::never);
+ m_hrtc_on_timer->adjust(attotime::never);
+ }
break;
}
}
@@ -631,7 +653,7 @@ void i8275_device::dack_w(uint8_t data)
m_write_drq(0);
- if (!VISIBLE_FIELD_ATTRIBUTE && ((m_dma_last_char & 0xc0) == 0x80))
+ if (!visible_field_attribute() && ((m_dma_last_char & 0xc0) == 0x80))
{
if (m_fifo_idx == 16)
{
@@ -644,7 +666,7 @@ void i8275_device::dack_w(uint8_t data)
data = 0;
}
- else if (m_buffer_idx < CHARACTERS_PER_ROW)
+ else if (m_buffer_idx < characters_per_row())
{
m_buffer[m_buffer_dma][m_buffer_idx++] = data;
}
@@ -655,27 +677,30 @@ void i8275_device::dack_w(uint8_t data)
{
case SCC_END_OF_ROW_DMA:
// stop DMA
- m_buffer_idx = CHARACTERS_PER_ROW;
+ m_buffer_idx = characters_per_row();
break;
case SCC_END_OF_SCREEN_DMA:
m_dma_stop = true;
- m_buffer_idx = CHARACTERS_PER_ROW;
+ m_buffer_idx = characters_per_row();
break;
default:
- if (m_buffer_idx == CHARACTERS_PER_ROW)
- {
- // stop DMA
- m_drq_on_timer->adjust(attotime::never);
- }
- else if (!(m_dma_idx % DMA_BURST_COUNT))
- {
- m_drq_on_timer->adjust(clocks_to_attotime(DMA_BURST_SPACE));
- }
- else
+ if (m_is_crtc0)
{
- m_drq_on_timer->adjust(attotime::zero);
+ if (m_buffer_idx == characters_per_row())
+ {
+ // stop DMA
+ m_drq_on_timer->adjust(attotime::never);
+ }
+ 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);
+ }
}
}
@@ -687,12 +712,12 @@ void i8275_device::dack_w(uint8_t data)
// lpen_w -
//-------------------------------------------------
-WRITE_LINE_MEMBER( i8275_device::lpen_w )
+void i8275_device::lpen_w(int state)
{
if (!m_lpen && state)
{
m_param[REG_LPEN_COL] = screen().hpos() / m_hpixels_per_column;
- m_param[REG_LPEN_ROW] = screen().vpos() / SCANLINES_PER_ROW;
+ m_param[REG_LPEN_ROW] = screen().vpos() / scanlines_per_row();
m_status |= ST_LP;
}
@@ -724,30 +749,33 @@ uint32_t i8275_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap
void i8275_device::recompute_parameters()
{
+ if (!m_is_crtc0)
+ return;
+
int y = screen().vpos();
- int horiz_pix_total = (CHARACTERS_PER_ROW + HRTC_COUNT) * m_hpixels_per_column;
- int vert_pix_total = (CHARACTER_ROWS_PER_FRAME + VRTC_ROW_COUNT) * SCANLINES_PER_ROW;
- attotime refresh = clocks_to_attotime((CHARACTERS_PER_ROW + HRTC_COUNT) * vert_pix_total);
- int max_visible_x = (CHARACTERS_PER_ROW * m_hpixels_per_column) - 1;
- int max_visible_y = (CHARACTER_ROWS_PER_FRAME * SCANLINES_PER_ROW) - 1;
+ int horiz_pix_total = (characters_per_row() + hrtc_count()) * m_hpixels_per_column;
+ int vert_pix_total = (character_rows_per_frame() + vrtc_row_count()) * scanlines_per_row();
+ attotime refresh = clocks_to_attotime((characters_per_row() + hrtc_count()) * vert_pix_total);
+ int max_visible_x = (characters_per_row() * m_hpixels_per_column) - 1;
+ int max_visible_y = (character_rows_per_frame() * scanlines_per_row()) - 1;
LOG("width %u height %u max_x %u max_y %u refresh %f\n", horiz_pix_total, vert_pix_total, max_visible_x, max_visible_y, refresh.as_hz());
rectangle visarea(0, max_visible_x, 0, max_visible_y);
screen().configure(horiz_pix_total, vert_pix_total, visarea, (m_refresh_hack ? screen().frame_period() : refresh).as_attoseconds());
- int hrtc_on_pos = CHARACTERS_PER_ROW * m_hpixels_per_column;
+ int hrtc_on_pos = characters_per_row() * m_hpixels_per_column;
m_hrtc_on_timer->adjust(screen().time_until_pos(y, hrtc_on_pos), 0, screen().scan_period());
- m_irq_scanline = (CHARACTER_ROWS_PER_FRAME - 1) * SCANLINES_PER_ROW;
- m_vrtc_scanline = CHARACTER_ROWS_PER_FRAME * SCANLINES_PER_ROW;
- m_vrtc_drq_scanline = vert_pix_total - SCANLINES_PER_ROW;
+ m_irq_scanline = (character_rows_per_frame() - 1) * scanlines_per_row();
+ m_vrtc_scanline = character_rows_per_frame() * scanlines_per_row();
+ m_vrtc_drq_scanline = vert_pix_total - scanlines_per_row();
LOG("irq_y %u vrtc_y %u drq_y %u\n", m_irq_scanline, m_vrtc_scanline, m_vrtc_drq_scanline);
m_scanline = y;
m_scanline_timer->adjust(screen().time_until_pos((y + 1) % vert_pix_total, 0), 0, screen().scan_period());
- if (DOUBLE_SPACED_ROWS) fatalerror("Double spaced rows not supported!");
+ if (double_spaced_rows()) fatalerror("Double spaced rows not supported!");
}