diff --git a/src/mame/ensoniq/esqvfd.cpp b/src/mame/ensoniq/esqvfd.cpp index f6bbb92ede1db..8f3b181604ead 100644 --- a/src/mame/ensoniq/esqvfd.cpp +++ b/src/mame/ensoniq/esqvfd.cpp @@ -17,8 +17,8 @@ DEFINE_DEVICE_TYPE(ESQ2X40_SQ1, esq2x40_sq1_device, "esq2x40_sq1", "Ensoniq 2x40 DEFINE_DEVICE_TYPE(ESQ2X40_VFX, esq2x40_vfx_device, "esq2x40_vfx", "Ensoniq 2x40 VFD (VFX Family variant)") // adapted from bfm_bd1, rearranged to work with ASCII data used by the Ensoniq h/w -static const uint16_t font[]= -{ // FEDC BA98 7654 3210 +static const uint16_t font[] = { + // FEDC BA98 7654 3210 0x0000, // 0000 0000 0000 0000 (space) 0x0000, // 0000 0000 0000 0000 ! (not defined) 0x0009, // 0000 0000 0000 1001 ". @@ -121,35 +121,39 @@ esqvfd_device::esqvfd_device(const machine_config &mconfig, device_type type, co device_t(mconfig, type, tag, owner, clock), m_vfds(std::move(std::get<0>(dimensions))), m_rows(std::get<1>(dimensions)), - m_cols(std::get<2>(dimensions)) -{ + m_cols(std::get<2>(dimensions)) { } -void esqvfd_device::device_start() -{ +void esqvfd_device::device_start() { m_vfds->resolve(); + save_item(NAME(m_cursx)); + save_item(NAME(m_cursy)); + save_item(NAME(m_savedx)); + save_item(NAME(m_savedy)); + save_item(NAME(m_curattr)); + save_item(NAME(m_chars)); + save_item(NAME(m_attrs)); + save_item(NAME(m_dirty)); + save_item(NAME(m_lastchar)); + save_item(NAME(m_blink_on)); } -void esqvfd_device::device_reset() -{ +void esqvfd_device::device_reset() { m_cursx = m_cursy = 0; m_savedx = m_savedy = 0; m_curattr = AT_NORMAL; m_lastchar = 0; + m_blink_on = false; memset(m_chars, 0, sizeof(m_chars)); memset(m_attrs, 0, sizeof(m_attrs)); memset(m_dirty, 1, sizeof(m_attrs)); } // generic display update; can override from child classes if not good enough -void esqvfd_device::update_display() -{ - for (int row = 0; row < m_rows; row++) - { - for (int col = 0; col < m_cols; col++) - { - if (m_dirty[row][col]) - { +void esqvfd_device::update_display() { + for (int row = 0; row < m_rows; row++) { + for (int col = 0; col < m_cols; col++) { + if (m_dirty[row][col]) { uint32_t segdata = conv_segments(font[m_chars[row][col]]); // digits: @@ -164,11 +168,9 @@ void esqvfd_device::update_display() } } -inline void esqvfd_device::cursor_left() -{ +inline void esqvfd_device::cursor_left() { m_cursx--; - if (m_cursx < 0) - { + if (m_cursx < 0) { m_cursx += m_cols; m_cursy--; if (m_cursy < 0) @@ -176,11 +178,9 @@ inline void esqvfd_device::cursor_left() } } -inline void esqvfd_device::cursor_right() -{ +inline void esqvfd_device::cursor_right() { m_cursx++; - if (m_cursx >= m_cols) - { + if (m_cursx >= m_cols) { m_cursx -= m_cols; m_cursy++; if (m_cursy >= m_rows) @@ -213,20 +213,15 @@ void esqvfd_device::clear() { /* 2x40 VFD display used in the ESQ-1, VFX-SD, SD-1, and others */ -void esq2x40_device::device_add_mconfig(machine_config &config) -{ +void esq2x40_device::device_add_mconfig(machine_config &config) { config.set_default_layout(layout_esq2by40); } -void esq2x40_device::write_char(uint8_t data) -{ - // ESQ-1 sends (cursor move) 0xfa 0xYY to mark YY characters as underlined at the current cursor location - if (m_lastchar == 0xfa) - { - for (uint8_t j = 0; j < m_rows; j++) - { - for (uint8_t i = 0; i < m_cols; i++) - { +void esq2x40_device::write_char(uint8_t data) { + if (m_lastchar == 0xfa) { + // ESQ-1 sends (cursor move) 0xfa 0xYY to mark YY characters as underlined at the current cursor location + for (uint8_t j = 0; j < m_rows; j++) { + for (uint8_t i = 0; i < m_cols; i++) { if (m_cursy == j && i >= m_cursx && i < m_cursx + data) m_attrs[j][i] |= AT_UNDERLINE; else @@ -239,19 +234,20 @@ void esq2x40_device::write_char(uint8_t data) m_lastchar = 0; update_display(); return; + } else if (m_lastchar == 0xff) { + // 0xff light commands are followed by a byte indicating the light and + // its requested status. Ignore this. + m_lastchar = 0; + return; } m_lastchar = data; - if ((data >= 0x80) && (data < 0xd0)) - { + if ((data >= 0x80) && (data < 0xd0)) { m_cursy = ((data & 0x7f) >= 40) ? 1 : 0; m_cursx = (data & 0x7f) % 40; - } - else if (data >= 0xd0) - { - switch (data) - { + } else if (data >= 0xd0) { + switch (data) { case 0xd0: // blink start m_curattr |= AT_BLINK; break; @@ -280,6 +276,10 @@ void esq2x40_device::write_char(uint8_t data) clear(); break; + case 0xe8: // also cancel attributes + m_curattr = 0; + break; + case 0xf5: // save cursor position m_savedx = m_cursx; m_savedy = m_cursy; @@ -295,50 +295,41 @@ void esq2x40_device::write_char(uint8_t data) clear(); break; + case 0xff: // light status; ignore. Next byte will also be ignored. + break; + default: -// printf("Unknown control code %02x\n", data); break; } - } - else - { - if ((data >= 0x20) && (data <= 0x5f)) - { - m_chars[m_cursy][m_cursx] = data - ' '; - m_attrs[m_cursy][m_cursx] = m_curattr; - m_dirty[m_cursy][m_cursx] = 1; + } else if ((data >= 0x20) && (data <= 0x5f)) { + m_chars[m_cursy][m_cursx] = data - ' '; + m_attrs[m_cursy][m_cursx] = m_curattr; + m_dirty[m_cursy][m_cursx] = 1; - cursor_right(); - } + cursor_right(); } update_display(); } -bool esq2x40_device::write_contents(std::ostream &o) -{ +bool esq2x40_device::write_contents(std::ostream &o) { o.put((char) 0xd6); // clear screen uint8_t attrs = 0; - for (int row = 0; row < 2; row++) - { + for (int row = 0; row < 2; row++) { o.put((char) (0x80 + (40 * row))); // move to first column this row - for (int col = 0; col < 40; col++) - { - if (m_attrs[row][col] != attrs) - { + for (int col = 0; col < 40; col++) { + if (m_attrs[row][col] != attrs) { attrs = m_attrs[row][col]; o.put((char) 0xd1); // all attributes off - if (attrs & AT_BLINK) - { + if (attrs & AT_BLINK) { o.put((char) 0xd0); // blink on } - if (attrs & AT_UNDERLINE) - { + if (attrs & AT_UNDERLINE) { o.put((char) 0xd3); // underline } } @@ -360,12 +351,10 @@ bool esq2x40_device::write_contents(std::ostream &o) esq2x40_device::esq2x40_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : - esqvfd_device(mconfig, type, tag, owner, clock, make_dimensions<2, 40>(*this)) -{ + esqvfd_device(mconfig, type, tag, owner, clock, make_dimensions<2, 40>(*this)) { } esq2x40_device::esq2x40_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - esq2x40_device(mconfig, ESQ2X40, tag, owner, clock) -{ + esq2x40_device(mconfig, ESQ2X40, tag, owner, clock) { } ROM_START( esq2x40_vfx_device ) @@ -373,48 +362,39 @@ ROM_START( esq2x40_vfx_device ) ROM_LOAD( "esqvfd_font_vfx.bin", 0, 192, CRC(58dc335b) SHA1(097fc3e1930a49ab61f73ea7a6191c892004f823) ) ROM_END -const tiny_rom_entry *esq2x40_vfx_device::device_rom_region() const -{ +const tiny_rom_entry *esq2x40_vfx_device::device_rom_region() const { return ROM_NAME( esq2x40_vfx_device ); } esq2x40_vfx_device::esq2x40_vfx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : esq2x40_device(mconfig, ESQ2X40_VFX, tag, owner, clock), - m_font(*this, "font") -{ + m_font(*this, "font") { } -void esq2x40_vfx_device::device_add_mconfig(machine_config &config) -{ +void esq2x40_vfx_device::device_add_mconfig(machine_config &config) { // Do not set a default layout. This display must be used // within a layout that includes the VFD elements, such as // vfx.lay, vfxsd.lay or sd1.lay. } // Handles blinking of underline and of entire character, -void esq2x40_vfx_device::update_display() -{ - for (int row = 0; row < m_rows; row++) - { - for (int col = 0; col < m_cols; col++) - { - if (m_dirty[row][col]) - { +void esq2x40_vfx_device::update_display() { + for (int row = 0; row < m_rows; row++) { + for (int col = 0; col < m_cols; col++) { + if (m_dirty[row][col]) { uint8_t c = m_chars[row][col]; uint16_t char_segments = m_font[c < 96 ? c : 0]; auto attr = m_attrs[row][col]; uint16_t segments; - if ((attr & AT_BLINK) && !m_blink_on) // something is blinked off - { + if ((attr & AT_BLINK) && !m_blink_on) { + // something is blinked off if (attr & AT_UNDERLINE) // blink the underline off segments = char_segments; else // there is no underline, blink the entire character segments = 0; - } - else - { + } else { if (attr & AT_UNDERLINE) segments = char_segments | 0x8000; else @@ -432,18 +412,14 @@ void esq2x40_vfx_device::update_display() /* 1x22 display from the VFX (not right, but it'll do for now) */ -void esq1x22_device::device_add_mconfig(machine_config &config) -{ +void esq1x22_device::device_add_mconfig(machine_config &config) { config.set_default_layout(layout_esq1by22); } -void esq1x22_device::write_char(uint8_t data) -{ - if (data >= 0x60) - { - switch (data) - { +void esq1x22_device::write_char(uint8_t data) { + if (data >= 0x60) { + switch (data) { case 'f': // clear screen m_cursx = m_cursy = 0; memset(m_chars, 0, sizeof(m_chars)); @@ -455,17 +431,13 @@ void esq1x22_device::write_char(uint8_t data) printf("Unhandled control code %02x\n", data); break; } - } - else - { - if ((data >= 0x20) && (data <= 0x5f)) - { + } else { + if ((data >= 0x20) && (data <= 0x5f)) { m_chars[0][m_cursx] = data - ' '; m_dirty[0][m_cursx] = 1; m_cursx++; - if (m_cursx >= 23) - { + if (m_cursx >= 23) { m_cursx = 23; } } @@ -475,71 +447,53 @@ void esq1x22_device::write_char(uint8_t data) } esq1x22_device::esq1x22_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - esqvfd_device(mconfig, ESQ1X22, tag, owner, clock, make_dimensions<1, 22>(*this)) -{ + esqvfd_device(mconfig, ESQ1X22, tag, owner, clock, make_dimensions<1, 22>(*this)) { } /* SQ-1 display, I think it's really an LCD but we'll deal with it for now */ -void esq2x40_sq1_device::device_add_mconfig(machine_config &config) -{ +void esq2x40_sq1_device::device_add_mconfig(machine_config &config) { config.set_default_layout(layout_esq2by40); // we use the normal 2x40 layout } -void esq2x40_sq1_device::write_char(uint8_t data) -{ - if (data == 0x09) // musical note - { +void esq2x40_sq1_device::write_char(uint8_t data) { + if (data == 0x09) { + // musical note data = '^'; // approximate for now } - if (m_wait87shift) - { + if (m_wait87shift) { m_cursy = (data >> 4) & 0xf; m_cursx = data & 0xf; m_wait87shift = false; - } - else if (m_wait88shift) - { + } else if (m_wait88shift) { m_wait88shift = false; - } - else if ((data >= 0x20) && (data <= 0x7f)) - { + } else if ((data >= 0x20) && (data <= 0x7f)) { m_chars[m_cursy][m_cursx] = data - ' '; m_attrs[m_cursy][m_cursx] = m_curattr; m_dirty[m_cursy][m_cursx] = 1; m_cursx++; - if (m_cursx >= 39) - { + if (m_cursx >= 39) { m_cursx = 39; } update_display(); - } - else if (data == 0x83) - { + } else if (data == 0x83) { m_cursx = m_cursy = 0; memset(m_chars, 0, sizeof(m_chars)); memset(m_attrs, 0, sizeof(m_attrs)); memset(m_dirty, 1, sizeof(m_dirty)); - } - else if (data == 0x87) - { + } else if (data == 0x87) { m_wait87shift = true; - } - else if (data == 0x88) - { + } else if (data == 0x88) { m_wait88shift = true; - } - else - { + } else { // printf("SQ-1 unhandled display char %02x\n", data); } } esq2x40_sq1_device::esq2x40_sq1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - esqvfd_device(mconfig, ESQ2X40_SQ1, tag, owner, clock, make_dimensions<2, 40>(*this)) -{ + esqvfd_device(mconfig, ESQ2X40_SQ1, tag, owner, clock, make_dimensions<2, 40>(*this)) { m_wait87shift = false; m_wait88shift = false; }