diff options
Diffstat (limited to 'src/devices/video/i82730.cpp')
-rw-r--r-- | src/devices/video/i82730.cpp | 615 |
1 files changed, 459 insertions, 156 deletions
diff --git a/src/devices/video/i82730.cpp b/src/devices/video/i82730.cpp index eeeedd3b4d1..4fb3e87e1f6 100644 --- a/src/devices/video/i82730.cpp +++ b/src/devices/video/i82730.cpp @@ -1,4 +1,4 @@ -// license:GPL-2.0+ +// license:BSD-3-Clause // copyright-holders:Dirk Best /*************************************************************************** @@ -13,14 +13,11 @@ #include "screen.h" - -//************************************************************************** -// CONSTANTS -//************************************************************************** - -#define VERBOSE 1 -#define VERBOSE_COMMANDS 1 -#define VERBOSE_DATASTREAM 0 +#define LOG_COMMANDS (1U << 1) +#define LOG_DATASTREAM (1U << 2) +//#define VERBOSE (LOG_GENERAL | LOG_COMMANDS | LOG_DATASTREAM) +#define VERBOSE (LOG_GENERAL) +#include "logmacro.h" //************************************************************************** @@ -29,22 +26,6 @@ DEFINE_DEVICE_TYPE(I82730, i82730_device, "i82730", "Intel 82730") -const char *const i82730_device::s_command_names[] = -{ - /* 00 */ "NOP", - /* 01 */ "START DISPLAY", - /* 02 */ "START VIRTUAL DISPLAY", - /* 03 */ "STOP DISPLAY", - /* 04 */ "MODE SET", - /* 05 */ "LOAD CBP", - /* 06 */ "LOAD INTMASK", - /* 07 */ "LPEN ENABLE", - /* 08 */ "READ STATUS", - /* 09 */ "LD CUR POS", - /* 0a */ "SELF TEST", - /* 0b */ "TEST ROW BUFFER" -}; - //************************************************************************** // LIVE DEVICE @@ -65,26 +46,20 @@ i82730_device::i82730_device(const machine_config &mconfig, const char *tag, dev m_initialized(false), m_mode_set(false), m_ca(0), + m_ca_latch(false), m_sysbus(0x00), m_ibp(0x0000), m_cbp(0x0000), - m_intmask(0xffff), - m_status(0x0000), - m_list_switch(0), - m_auto_line_feed(0), + m_list_switch(false), + m_auto_line_feed(false), m_max_dma_count(0), m_lptr(0), + m_status(0x0000), + m_intmask(0xffff), m_sptr(0), - m_dma_burst_space(0), - m_dma_burst_length(0), - m_hfldstrt(0), - m_margin(0), - m_lpr(0), - m_field_attribute_mask(0), - m_vsyncstp(0), - m_vfldstrt(0), - m_vfldstp(0), - m_frame_int_count(0), + m_row(nullptr), + m_dma_count(0), + m_row_count(0), m_row_index(0) { } @@ -98,14 +73,11 @@ void i82730_device::device_start() // register bitmap screen().register_screen_bitmap(m_bitmap); - // resolve callbacks - m_sint_handler.resolve_safe(); - // bind delegates m_update_row_cb.resolve(); // allocate row timer - m_row_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(i82730_device::row_update), this)); + m_row_timer = timer_alloc(FUNC(i82730_device::row_update), this); } //------------------------------------------------- @@ -120,6 +92,7 @@ void i82730_device::device_reset() m_mode_set = false; m_ca = 0; + m_ca_latch = false; m_status = 0x0000; } @@ -188,67 +161,121 @@ void i82730_device::mode_set() uint16_t tmp; tmp = read_word(mptr); - m_dma_burst_space = tmp & 0x7f; - m_dma_burst_length = (tmp >> 8) & 0x7f; + m_mb.burst_length = (tmp >> 8) & 0x7f; + m_mb.burst_space = tmp & 0x7f; tmp = read_word(mptr + 2); - uint8_t hsyncstp = tmp & 0xff; - uint8_t line_length = (tmp >> 8) & 0xff; + m_mb.line_length = (tmp >> 8) & 0xff; + m_mb.hsyncstp = tmp & 0xff; tmp = read_word(mptr + 4); - uint8_t hfldstp = tmp & 0xff; - m_hfldstrt = (tmp >> 8) & 0xff; + m_mb.hfldstrt = (tmp >> 8) & 0xff; + m_mb.hfldstp = tmp & 0xff; tmp = read_word(mptr + 6); - uint8_t hbrdstp = tmp & 0xff; - uint8_t hbrdstrt = (tmp >> 8) & 0xff; + m_mb.hbrdstrt = (tmp >> 8) & 0xff; + m_mb.hbrdstp = tmp & 0xff; tmp = read_word(mptr + 8); - m_margin = tmp & 0x1f; + m_mb.scroll_margin = tmp & 0x1f; tmp = read_word(mptr + 10); - m_lpr = tmp & 0x1f; + m_mb.rvv_row = bool(BIT(tmp, 11)); + m_mb.blk_row = bool(BIT(tmp, 10)); + m_mb.dbl_hgt = bool(BIT(tmp, 9)); + m_mb.wdef = bool(BIT(tmp, 8)); + m_mb.lpr = tmp & 0x1f; + + tmp = read_word(mptr + 12); + m_mb.nrmstrt = (tmp >> 8) & 0x1f; + m_mb.nrmstp = tmp & 0x1f; + + tmp = read_word(mptr + 14); + m_mb.supstrt = (tmp >> 8) & 0x1f; + m_mb.supstp = tmp & 0x1f; + + tmp = read_word(mptr + 16); + m_mb.substrt = (tmp >> 8) & 0x1f; + m_mb.substp = tmp & 0x1f; + + tmp = read_word(mptr + 18); + m_mb.cur1strt = (tmp >> 8) & 0x1f; + m_mb.cur1stp = tmp & 0x1f; + + tmp = read_word(mptr + 20); + m_mb.cur2strt = (tmp >> 8) & 0x1f; + m_mb.cur2stp = tmp & 0x1f; + + tmp = read_word(mptr + 22); + m_mb.u2_line_sel = (tmp >> 8) & 0x1f; + m_mb.u1_line_sel = tmp & 0x1f; tmp = read_word(mptr + 24); - m_field_attribute_mask = tmp & 0x7fff; + m_mb.field_attribute_mask = tmp & 0x7fff; tmp = read_word(mptr + 26); - uint16_t frame_length = tmp & 0x7ff; + m_mb.frame_length = tmp & 0x7ff; tmp = read_word(mptr + 28); - m_vsyncstp = tmp & 0x7ff; + m_mb.vsyncstp = tmp & 0x7ff; tmp = read_word(mptr + 30); - m_vfldstrt = tmp & 0x7ff; + m_mb.vfldstrt = tmp & 0x7ff; tmp = read_word(mptr + 32); - m_vfldstp = tmp & 0x7ff; + m_mb.vfldstp = tmp & 0x7ff; tmp = read_word(mptr + 38); - m_frame_int_count = tmp & 0x0f; + m_mb.duty_cyc_cursor = (tmp >> 12) & 0x0f; + m_mb.cursor_blink = (tmp >> 8) & 0x0f; + m_mb.frame_int_count = tmp & 0x0f; + + tmp = read_word(mptr + 40); + m_mb.duty_cyc_char = (tmp >> 12) & 0x0f; + m_mb.char_blink = (tmp >> 8) & 0x0f; + m_mb.ile = bool(BIT(tmp, 7)); + m_mb.rfe = bool(BIT(tmp, 6)); + m_mb.bpol = bool(BIT(tmp, 5)); + m_mb.bue = bool(BIT(tmp, 4)); + m_mb.cr2_cd = bool(BIT(tmp, 3)); + m_mb.cr1_cd = bool(BIT(tmp, 2)); + m_mb.cr2_be = bool(BIT(tmp, 1)); + m_mb.cr1_be = bool(BIT(tmp, 0)); + + tmp = read_word(mptr + 40); + m_mb.reverse_video = (tmp >> 12) & 0x0f; + m_mb.blinking_char = (tmp >> 8) & 0x0f; + m_mb.cr2_rvv = bool(BIT(tmp, 3)); + m_mb.cr1_rvv = bool(BIT(tmp, 2)); + m_mb.cr2_oe = bool(BIT(tmp, 1)); + m_mb.cr1_oe = bool(BIT(tmp, 0)); + + tmp = read_word(mptr + 42); + m_mb.abs_line_count = (tmp >> 12) & 0x0f; + m_mb.invisible_char = (tmp >> 8) & 0x0f; + m_mb.underline2 = (tmp >> 4) & 0x0f; + m_mb.underline1 = tmp & 0x0f; // setup screen mode - rectangle visarea(hbrdstrt * 16, hbrdstp * 16 - 1, m_vsyncstp, m_vfldstp + m_margin + 1 + m_lpr - 1); - attoseconds_t period = HZ_TO_ATTOSECONDS(clock() * 16) * line_length * 16 * frame_length; - screen().configure(line_length * 16, frame_length, visarea, period); + rectangle visarea(m_mb.hbrdstrt * 16, m_mb.hbrdstp * 16 - 1, m_mb.vsyncstp, m_mb.vfldstp + m_mb.scroll_margin + 1 + m_mb.lpr - 1); + attoseconds_t period = HZ_TO_ATTOSECONDS(clock() * 16) * m_mb.line_length * 16 * m_mb.frame_length; + screen().configure(m_mb.line_length * 16, m_mb.frame_length, visarea, period); // start display is now valid m_mode_set = true; - // adjust timer for the new mode - m_row_timer->adjust(screen().time_until_pos(0)); - // output some debug info - if (VERBOSE) - { - logerror("%s('%s'): ---- setting mode ----\n", shortname(), basetag()); - logerror("%s('%s'): dma burst length %02x, space %02x\n", shortname(), basetag(), m_dma_burst_length, m_dma_burst_space); - logerror("%s('%s'): margin %02x, lpr %02x\n", shortname(), basetag(), m_margin, m_lpr); - logerror("%s('%s'): hsyncstp: %02x, line_length: %02x, hfldstrt: %02x, hbrdstart: %02x, hfldstop: %02x, hbrdstop: %02x\n", - shortname(), basetag(), hsyncstp, line_length, m_hfldstrt, hbrdstrt, hfldstp, hbrdstp); - logerror("%s('%s'): frame_length %04x, vsyncstp: %04x, vfldstrt: %04x, vfldstp: %04x\n", - shortname(), basetag(), frame_length, m_vsyncstp, m_vfldstrt, m_vfldstp); - } + LOG( + "%s: ---- modeset ----\n" + " dma burst length %02x, space %02x\n" + " margin %02x, lpr %02x\n" + " hsyncstp: %02x, line_length: %02x, hfldstrt: %02x, hbrdstart: %02x, hfldstop: %02x, hbrdstop: %02x\n" + " frame_length %04x, vsyncstp: %04x, vfldstrt: %04x, vfldstp: %04x\n", + shortname(), + m_mb.burst_length, m_mb.burst_space, + m_mb.scroll_margin, m_mb.lpr, + m_mb.hsyncstp, m_mb.line_length, m_mb.hfldstrt, m_mb.hbrdstrt, m_mb.hfldstp, m_mb.hbrdstp, + m_mb.frame_length, m_mb.vsyncstp, m_mb.vfldstrt, m_mb.vfldstp); } void i82730_device::execute_command() @@ -256,16 +283,15 @@ void i82730_device::execute_command() uint8_t command = read_byte(m_cbp + 1); uint16_t tmp; - if (VERBOSE_COMMANDS && command < ARRAY_LENGTH(s_command_names)) - logerror("%s('%s'): executing command: %s [cbp = %08x]\n", shortname(), basetag(), s_command_names[command], m_cbp); - tmp = read_word(m_cbp + 2); - m_list_switch = BIT(tmp, 6); - m_auto_line_feed = BIT(tmp, 7); + m_list_switch = bool(BIT(tmp, 7)); + m_auto_line_feed = bool(BIT(tmp, 6)); tmp = read_word(m_cbp + 4); m_max_dma_count = tmp & 0xff; + LOGMASKED(LOG_COMMANDS, "list switch %d, autolf %d, dma count %02x\n", m_list_switch, m_auto_line_feed, m_max_dma_count); + switch (command) { // NOP @@ -274,68 +300,83 @@ void i82730_device::execute_command() // START DISPLAY case 0x01: + LOGMASKED(LOG_COMMANDS, "Executing command START DISPLAY\n"); if (m_mode_set) + { m_status = (m_status & ~VDIP) | DIP; + m_row_timer->adjust(screen().time_until_pos(0)); + } break; // START VIRTUAL DISPLAY case 0x02: - if (m_mode_set) - m_status = VDIP | (m_status & ~DIP); + LOGMASKED(LOG_COMMANDS, "Executing command START VIRTUAL DISPLAY - not implemented\n"); break; // STOP DISPLAY case 0x03: + LOGMASKED(LOG_COMMANDS, "Executing command STOP DISPLAY\n"); m_status &= ~(VDIP | DIP); + m_row_timer->reset(); break; // MODE SET case 0x04: + LOGMASKED(LOG_COMMANDS, "Executing command MODE SET\n"); mode_set(); break; // LOAD CBP case 0x05: + LOGMASKED(LOG_COMMANDS, "Executing command LOAD CBP\n"); m_cbp = (read_word(m_cbp + 16) << 16) | read_word(m_cbp + 14); + LOGMASKED(LOG_COMMANDS, "--> New value = %08x\n", m_cbp); execute_command(); break; // LOAD INTMASK case 0x06: + LOGMASKED(LOG_COMMANDS, "Executing command LOAD INTMASK\n"); m_intmask = read_word(m_cbp + 22); - if (VERBOSE_COMMANDS) - logerror("%s('%s'): intmask now %04x\n", shortname(), basetag(), m_intmask); + LOGMASKED(LOG_COMMANDS, "--> New value = %02x\n", m_intmask); break; // LPEN ENABLE case 0x07: - fatalerror("%s('%s'): Unimplemented command %s\n", shortname(), basetag(), s_command_names[command]); + LOGMASKED(LOG_COMMANDS, "Executing command LPEN ENABLE - not implemented\n"); break; // READ STATUS case 0x08: + LOGMASKED(LOG_COMMANDS, "Executing command READ STATUS\n"); write_word(m_cbp + 18, m_status); m_status &= (VDIP | DIP); break; // LD CUR POS case 0x09: - fatalerror("%s('%s'): Unimplemented command %s\n", shortname(), basetag(), s_command_names[command]); + LOGMASKED(LOG_COMMANDS, "Executing command LD CUR POS\n"); + tmp = read_word(m_cbp + 26); + m_cursor[0].y = (tmp >> 8) & 0xff; + m_cursor[0].x = tmp & 0xff; + tmp = read_word(m_cbp + 28); + m_cursor[1].y = (tmp >> 8) & 0xff; + m_cursor[1].x = tmp & 0xff; + LOGMASKED(LOG_COMMANDS, "--> Cursor %d, %d and %d, %d\n", m_cursor[0].x, m_cursor[0].y, m_cursor[1].x, m_cursor[1].y); break; // SELF TEST case 0x0a: - fatalerror("%s('%s'): Unimplemented command %s\n", shortname(), basetag(), s_command_names[command]); + LOGMASKED(LOG_COMMANDS, "Executing command SELF TEST - not implemented\n"); break; // TEST ROW BUFFER case 0x0b: - fatalerror("%s('%s'): Unimplemented command %s\n", shortname(), basetag(), s_command_names[command]); + LOGMASKED(LOG_COMMANDS, "Executing command TEST ROW BUFFER - not implemented\n"); break; default: - if (VERBOSE_COMMANDS) - logerror("%s('%s'): executing command: (reserved) [cbp = %08x]\n", shortname(), basetag(), m_cbp); + LOGMASKED(LOG_COMMANDS, "Executing command %02x - unknown\n", command); m_status |= RCC; update_interrupts(); break; @@ -345,11 +386,269 @@ void i82730_device::execute_command() write_word(m_cbp, read_word(m_cbp) & 0xff00); } +bool i82730_device::dscmd_endrow() +{ + LOGMASKED(LOG_DATASTREAM, "Executing datastream command ENDROW\n"); + + return true; +} + +bool i82730_device::dscmd_eof() +{ + LOGMASKED(LOG_DATASTREAM, "Executing datastream command EOF - not implemented\n"); + + return false; +} + +bool i82730_device::dscmd_eol() +{ + LOGMASKED(LOG_DATASTREAM, "Executing datastream command EOL\n"); + + m_sptr = (read_word(m_lptr + 2) << 16) | read_word(m_lptr); + m_lptr += 4; + + return true; +} + +bool i82730_device::dscmd_fulrowdescrpt(uint8_t param) +{ + LOGMASKED(LOG_DATASTREAM, "Executing datastream command FULROWDESCRPT %d\n", param); + + uint16_t tmp; + + if (param >= 1) + { + tmp = read_word(m_sptr); + m_sptr += 2; + m_mb.rvv_row = bool(BIT(tmp, 11)); + m_mb.blk_row = bool(BIT(tmp, 10)); + m_mb.dbl_hgt = bool(BIT(tmp, 9)); + m_mb.wdef = bool(BIT(tmp, 8)); + m_mb.lpr = tmp & 0x1f; + + LOGMASKED(LOG_DATASTREAM, "--> RVV_ROW %d, BLK_ROW %d, DBL_HGT %d, WDEF %d, LPR %d\n", m_mb.rvv_row, m_mb.blk_row, m_mb.dbl_hgt, m_mb.wdef, m_mb.lpr); + } + + if (param >= 2) + { + tmp = read_word(m_sptr); + m_sptr += 2; + m_mb.nrmstrt = (tmp >> 8) & 0x1f; + m_mb.nrmstp = tmp & 0x1f; + + LOGMASKED(LOG_DATASTREAM, "--> NRMSTRT %d, NRMSTP %d\n", m_mb.nrmstrt, m_mb.nrmstp); + } + + if (param >= 3) + { + tmp = read_word(m_sptr); + m_sptr += 2; + m_mb.supstrt = (tmp >> 8) & 0x1f; + m_mb.supstp = tmp & 0x1f; + + LOGMASKED(LOG_DATASTREAM, "--> SUPSTRT %d, SUPSTP %d\n", m_mb.supstrt, m_mb.supstp); + } + + if (param >= 4) + { + tmp = read_word(m_sptr); + m_sptr += 2; + m_mb.substrt = (tmp >> 8) & 0x1f; + m_mb.substp = tmp & 0x1f; + + LOGMASKED(LOG_DATASTREAM, "--> SUBSTRT %d, SUBSTP %d\n", m_mb.substrt, m_mb.substp); + } + + if (param >= 5) + { + tmp = read_word(m_sptr); + m_sptr += 2; + m_mb.cur1strt = (tmp >> 8) & 0x1f; + m_mb.cur1stp = tmp & 0x1f; + + LOGMASKED(LOG_DATASTREAM, "--> CUR1STRT %d, CUR1STP %d\n", m_mb.cur1strt, m_mb.cur1stp); + } + + if (param >= 6) + { + tmp = read_word(m_sptr); + m_sptr += 2; + m_mb.cur2strt = (tmp >> 8) & 0x1f; + m_mb.cur2stp = tmp & 0x1f; + + LOGMASKED(LOG_DATASTREAM, "--> CUR2STRT %d, CUR2STP %d\n", m_mb.cur2strt, m_mb.cur2stp); + } + + if (param >= 7) + { + tmp = read_word(m_sptr); + m_sptr += 2; + m_mb.u2_line_sel = (tmp >> 8) & 0x1f; + m_mb.u1_line_sel = tmp & 0x1f; + + LOGMASKED(LOG_DATASTREAM, "--> U2 LINE SEL %d, U1 LINE SEL %d\n", m_mb.u2_line_sel, m_mb.u1_line_sel); + } + + return false; +} + +bool i82730_device::dscmd_sl_scroll_strt(uint8_t param) +{ + LOGMASKED(LOG_DATASTREAM, "Executing datastream command SL SCROLL START %d - not implemented\n", param); + + return false; +} + +bool i82730_device::dscmd_sl_scroll_end(uint8_t param) +{ + LOGMASKED(LOG_DATASTREAM, "Executing datastream command SL SCROLL END %d - not implemented\n", param); + + return false; +} + +bool i82730_device::dscmd_tab_to(uint8_t param) +{ + LOGMASKED(LOG_DATASTREAM, "Executing datastream command TAB TO %d - not implemented\n", param); + + return false; +} + +bool i82730_device::dscmd_max_dma_count(uint8_t param) +{ + LOGMASKED(LOG_DATASTREAM, "Executing datastream command LD MAX DMA COUNT %02x\n", param); + + m_max_dma_count = param; + + return false; +} + +bool i82730_device::dscmd_endstrg() +{ + LOGMASKED(LOG_DATASTREAM, "Executing datastream command ENDSTRG\n"); + + m_sptr = (read_word(m_lptr + 2) << 16) | read_word(m_lptr); + m_lptr += 4; + + LOGMASKED(LOG_DATASTREAM, "--> SPTR %08x\n", m_sptr); + + return false; +} + +bool i82730_device::dscmd_skip(uint8_t param) +{ + LOGMASKED(LOG_DATASTREAM, "Executing datastream command SKIP %d - not implemented\n", param); + + return false; +} + +bool i82730_device::dscmd_repeat(uint8_t param) +{ + LOGMASKED(LOG_DATASTREAM, "Executing datastream command REPEAT %d\n", param); + + uint16_t data = read_word(m_sptr); + m_sptr += 2; + + LOGMASKED(LOG_DATASTREAM, "--> Repeating %02x\n", data); + + while (param--) + { + if (--m_dma_count && m_row_count < 200) + m_row[m_row_count++] = data; + else + return true; + } + + return false; +} + +bool i82730_device::dscmd_sub_sup(uint8_t param) +{ + LOGMASKED(LOG_DATASTREAM, "Executing datastream command SUP SUB - not implemented\n", param); + + return false; +} + +bool i82730_device::dscmd_rpt_sub_sup(uint8_t param) +{ + LOGMASKED(LOG_DATASTREAM, "Executing datastream command RPT SUP SUB - not implemented\n", param); + + return false; +} + +bool i82730_device::dscmd_set_gen_pur_attrib(uint8_t param) +{ + LOGMASKED(LOG_DATASTREAM, "Executing datastream command SET GEN PUR ATTRIB - not implemented\n", param); + + return false; +} + +bool i82730_device::dscmd_set_field_attrib() +{ + LOGMASKED(LOG_DATASTREAM, "Executing datastream command SET FIELD ATTRIB\n"); + + m_mb.field_attribute_mask = read_word(m_sptr) & 0x7fff; + m_sptr += 2; + + LOGMASKED(LOG_DATASTREAM, "--> New value = %04x\n", m_mb.field_attribute_mask); + + return false; +} + +bool i82730_device::dscmd_init_next_process() +{ + LOGMASKED(LOG_DATASTREAM, "Executing datastream command INIT NEXT PROCESS - not implemented\n"); + + return false; +} + +bool i82730_device::execute_datastream_command(uint8_t command, uint8_t param) +{ + // RESERVED + if (command >= 0x90 && command <= 0xbf) + { + LOGMASKED(LOG_DATASTREAM, "Executing reserved datastream command %02x\n", command); + + m_status |= RDC; + update_interrupts(); + + return false; + } + + // NOP + if (command >= 0xc0) + return false; + + // DATASTREAM COMMANDS + switch (command) + { + case 0x80: return dscmd_endrow(); + case 0x81: return dscmd_eof(); + case 0x82: return dscmd_eol(); + case 0x83: return dscmd_fulrowdescrpt(param); + case 0x84: return dscmd_sl_scroll_strt(param); + case 0x85: return dscmd_sl_scroll_end(param); + case 0x86: return dscmd_tab_to(param); + case 0x87: return dscmd_max_dma_count(param); + case 0x88: return dscmd_endstrg(); + case 0x89: return dscmd_skip(param); + case 0x8a: return dscmd_repeat(param); + case 0x8b: return dscmd_sub_sup(param); + case 0x8c: return dscmd_rpt_sub_sup(param); + case 0x8d: return dscmd_set_gen_pur_attrib(param); + case 0x8e: return dscmd_set_field_attrib(); + case 0x8f: return dscmd_init_next_process(); + } + + // should never get here + return false; +} + void i82730_device::load_row() { bool finished = false; - m_row[m_row_index].count = 0; + m_dma_count = m_max_dma_count; + m_row_count = 0; while (!finished) { @@ -358,44 +657,37 @@ void i82730_device::load_row() if (BIT(data, 15)) { - switch (data >> 8) - { - case 0x8e: - m_field_attribute_mask = read_word(m_sptr) & 0x7fff; - m_sptr += 2; - - if (VERBOSE_DATASTREAM) - logerror("%s('%s'): SET FIELD ATTRIB to %04x\n", shortname(), basetag(), m_field_attribute_mask); - - break; - - default: - fatalerror("%s('%s'): Unimplemented datastream command %02x\n", shortname(), basetag(), data >> 8); - } + finished = execute_datastream_command(data >> 8, data & 0xff); } else { - // maximum row size is 200 - if (m_row[m_row_index].count < m_max_dma_count && m_row[m_row_index].count < 200) + // fetch data + if (--m_dma_count > 0) { - m_row[m_row_index].data[m_row[m_row_index].count++] = data; + if (m_row_count < 200) + { + m_row[m_row_count++] = data; + } + else + { + // buffer overrun + m_status |= DBOR; + update_interrupts(); + finished = true; + } } else { -#if 0 - // move to next string? - if (m_auto_line_feed == 0) + if (!m_auto_line_feed) { m_sptr = (read_word(m_lptr + 2) << 16) | read_word(m_lptr); m_lptr += 4; } -#endif + finished = true; } } } - - m_sptr -= 2; } TIMER_CALLBACK_MEMBER( i82730_device::row_update ) @@ -408,10 +700,10 @@ TIMER_CALLBACK_MEMBER( i82730_device::row_update ) m_status &= (VDIP | DIP); // clear field attribute mask - m_field_attribute_mask = 0; + m_mb.field_attribute_mask = 0; // get listbase - if (m_list_switch) + if (m_list_switch == 0) m_lptr = (read_word(m_cbp + 8) << 16) | read_word(m_cbp + 6); else m_lptr = (read_word(m_cbp + 12) << 16) | read_word(m_cbp + 10); @@ -421,46 +713,52 @@ TIMER_CALLBACK_MEMBER( i82730_device::row_update ) // fetch initial row m_row_index = 0; + m_row = &m_row_buffer[m_row_index][0]; load_row(); } - else if (y >= m_vsyncstp && y < m_vfldstrt) + else if (y >= m_mb.vsyncstp && y < m_mb.vfldstrt) { // blank (top border) } - else if (y >= m_vfldstrt && y < m_vfldstp) + else if (y >= m_mb.vfldstrt && y < m_mb.vfldstp) { - uint8_t lc = (y - m_vfldstrt) % (m_lpr + 1); + uint8_t lc = (y - m_mb.vfldstrt) % (m_mb.lpr + 1); // call driver - m_update_row_cb(m_bitmap, m_row[m_row_index].data, lc, y - m_vsyncstp, m_row[m_row_index].count); + m_update_row_cb(m_bitmap, m_row, lc, y - m_mb.vsyncstp, m_row_count); // swap buffers at end of row - if (lc == m_lpr) + if (lc == m_mb.lpr) { m_row_index ^= 1; + m_row = &m_row_buffer[m_row_index][0]; + + // load status row data at end of regular display + if (y == (m_mb.vfldstp - 1)) + m_sptr = (read_word(m_cbp + 36) << 16) | read_word(m_cbp + 34); + load_row(); } } - else if (y >= m_vfldstp && y < m_vfldstp + m_margin + 1) + else if (y >= m_mb.vfldstp && y < m_mb.vfldstp + m_mb.scroll_margin + 1) { // margin } - else if (y >= m_vfldstp + m_margin + 1 && y < m_vfldstp + m_margin + 1 + m_lpr + 1) + else if (y >= m_mb.vfldstp + m_mb.scroll_margin + 1 && y < m_mb.vfldstp + m_mb.scroll_margin + 1 + m_mb.lpr + 1) { - uint8_t lc = (y - (m_vfldstp + m_margin + 1)) % (m_lpr + 1); - - m_sptr = (read_word(m_cbp + 36) << 16) | read_word(m_cbp + 34); - load_row(); + uint8_t lc = (y - (m_mb.vfldstp + m_mb.scroll_margin + 1)) % (m_mb.lpr + 1); // call driver - m_update_row_cb(m_bitmap, m_row[m_row_index].data, lc, y - m_vsyncstp, m_row[m_row_index].count); + m_update_row_cb(m_bitmap, m_row, lc, y - m_mb.vsyncstp, m_row_count); } - else if (y == m_vfldstp + m_margin + 1 + m_lpr + 1) + else if (y == m_mb.vfldstp + m_mb.scroll_margin + 1 + m_mb.lpr + 1) { - // todo: check ca + // check ca latch + if (m_ca_latch) + attention(); // frame interrupt? - if ((screen().frame_number() % m_frame_int_count) == 0) + if ((screen().frame_number() % m_mb.frame_int_count) == 0) m_status |= EONF; // check interrupts @@ -471,16 +769,27 @@ TIMER_CALLBACK_MEMBER( i82730_device::row_update ) // vblank } - m_row_timer->adjust(screen().time_until_pos((y + 1) % screen().height())); + // schedule next line (if enabled) + if (m_status & DIP) + m_row_timer->adjust(screen().time_until_pos((y + 1) % screen().height())); } -WRITE_LINE_MEMBER( i82730_device::ca_w ) +void i82730_device::attention() { - if (VERBOSE) - logerror("%s('%s'): ca_w %d\n", shortname(), basetag(), state); + execute_command(); + m_ca_latch = false; +} +void i82730_device::ca_w(int state) +{ // falling edge if (m_ca == 1 && state == 0) + m_ca_latch = true; + + m_ca = state; + + // check ca every cycle if the display isn't active + if (m_ca_latch && ((m_status & DIP) == 0)) { if (!m_initialized) { @@ -490,6 +799,8 @@ WRITE_LINE_MEMBER( i82730_device::ca_w ) // get intermediate block pointer m_ibp = (read_word(0xfffffffe) << 16) | read_word(0xfffffffc); + m_cbp = (read_word(m_ibp + 4) << 16) | read_word(m_ibp + 2); + // get system configuration byte uint8_t scb = read_byte(m_ibp + 6); @@ -500,37 +811,29 @@ WRITE_LINE_MEMBER( i82730_device::ca_w ) m_initialized = true; // output some debug info - if (VERBOSE) - { - logerror("%s('%s'): ---- initializing ----\n", shortname(), basetag()); - logerror("%s('%s'): %s system bus\n", shortname(), basetag(), sysbus_16bit() ? "16-bit" : "8-bit"); - logerror("%s('%s'): intermediate block pointer: %08x\n", shortname(), basetag(), m_ibp); - logerror("%s('%s'): addrbus: %s, clno: %d, clpos: %d, mode: %s, dtw16: %s, srdy: %s\n", shortname(), basetag(), - BIT(scb, 0) ? "32-bit" : "16-bit", (scb >> 1) & 0x03, (scb >> 3) & 0x03, - BIT(scb, 5) ? "master" : "slave", BIT(scb, 6) ? "16-bit" : "8-bit", BIT(scb, 7) ? "synchronous" : "asynchronous"); - } + LOG( + "%s: ---- initializing ----\n" + " %s-bit system bus\n" + " intermediate block pointer: %08x\n" + " addrbus: %s-bit, clno: %d, clpos: %d, mode: %s, dtw16: %s-bit, srdy: %s\n", + shortname(), + sysbus_16bit() ? "16" : "8", + m_ibp, + BIT(scb, 0) ? "32" : "16", BIT(scb, 1, 2), BIT(scb, 3, 2), + BIT(scb, 5) ? "master" : "slave", BIT(scb, 6) ? "16" : "8", BIT(scb, 7) ? "synchronous" : "asynchronous"); } - // fetch command block pointer - m_cbp = (read_word(m_ibp + 4) << 16) | read_word(m_ibp + 2); - - // and execute command - execute_command(); + attention(); } - - m_ca = state; } -WRITE_LINE_MEMBER( i82730_device::irst_w ) +void i82730_device::irst_w(int state) { - if (VERBOSE) - logerror("%s('%s'): irst_w %d\n", shortname(), basetag(), state); - m_sint_handler(0); } uint32_t i82730_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - copybitmap(bitmap, m_bitmap, 0, 0, m_hfldstrt * 16, 0, cliprect); + copybitmap(bitmap, m_bitmap, 0, 0, m_mb.hfldstrt * 16, 0, cliprect); return 0; } |