From 7c21e42492fb546f4c1602e9536d05a874e0b47a Mon Sep 17 00:00:00 2001 From: Fabio D'Urso Date: Sun, 26 Oct 2025 21:12:23 +0000 Subject: [PATCH] ef9345: Move some code paths for the ts9347 variant in virtual functions --- src/devices/video/ef9345.cpp | 117 +++++++++++++++++++---------------- src/devices/video/ef9345.h | 27 +++++++- 2 files changed, 89 insertions(+), 55 deletions(-) diff --git a/src/devices/video/ef9345.cpp b/src/devices/video/ef9345.cpp index 8dff1a41cc03b..f0a1245aaee2c 100644 --- a/src/devices/video/ef9345.cpp +++ b/src/devices/video/ef9345.cpp @@ -20,12 +20,6 @@ #include -#define MODE24x40 0 -#define MODEVAR40 1 -#define MODE8x80 2 -#define MODE12x80 3 -#define MODE16x40 4 - //************************************************************************** // GLOBAL VARIABLES //************************************************************************** @@ -239,16 +233,7 @@ void ef9345_device::draw_char_80(uint8_t *c, uint16_t x, uint16_t y) // set then ef9345 mode void ef9345_device::set_video_mode(void) { - if (m_variant == EF9345_MODE::TYPE_TS9347) - { - // Only TGS 7 & 6 used for the char mode with the TS9347 - m_char_mode = ((m_tgs & 0xc0) >> 6); - } - else - { - // PAT 7, TGS 7 & 6 - m_char_mode = ((m_pat & 0x80) >> 5) | ((m_tgs & 0xc0) >> 6); - } + m_char_mode = parse_video_mode(); uint16_t new_width = (m_char_mode == MODE12x80 || m_char_mode == MODE8x80) ? 492 : 336; @@ -273,6 +258,27 @@ void ef9345_device::set_video_mode(void) m_block = 0x0800 * ((((m_ror & 0xf0) >> 4) | ((m_ror & 0x40) >> 5) | ((m_ror & 0x20) >> 3)) & 0x0c); } +ef9345_device::char_mode_t ef9345_device::parse_video_mode() const +{ + uint8_t selector = (BIT(m_pat, 7) << 2) | bitswap<2>(m_tgs, 7, 6); + switch (selector) + { + default: + logerror("Unknown EF9345 mode: 0x%x\n", selector); + [[fallthrough]]; + case 0b000: + return MODE24x40; + case 0b001: + return MODEVAR40; + case 0b100: + return MODE16x40; + case 0b011: + return MODE12x80; + case 0b010: + return MODE8x80; + } +} + // initialize the ef9345 accented chars void ef9345_device::init_accented_chars(void) { @@ -382,25 +388,7 @@ void ef9345_device::zoom(uint8_t *pix, uint16_t n) // calculate the address of the char x,y uint16_t ef9345_device::indexblock(uint16_t x, uint16_t y) { - uint16_t i = x, j; - - if (m_variant == EF9345_MODE::TYPE_EF9345) - { - // On the EF9345 the service row is always displayed at the top, and - // it can be fetched from either Y=0 or Y=1. - j = (y == 0) ? ((m_tgs & 0x20) >> 5) : ((m_ror & 0x1f) + y - 1); - } - else - { - // On the TS9347 the service row is displayed either at the top or at - // the bottom, and it is always fetched from Y=0. - if (m_tgs & 1) - j = (y == 24) ? 0 : ((m_ror & 0x1f) + y); - else - j = (y == 0) ? 0 : ((m_ror & 0x1f) + y - 1); - } - - j = (j > 31) ? (j - 24) : j; + uint16_t i = x, j = indexrow(y); //right side of a double width character if ((m_tgs & 0x80) == 0 && x > 0) @@ -413,6 +401,16 @@ uint16_t ef9345_device::indexblock(uint16_t x, uint16_t y) return 0x40 * j + i; } +uint16_t ef9345_device::indexrow(uint16_t y) +{ + uint16_t j; + + // On the EF9345 the service row can be fetched from either Y=0 or Y=1. + j = (y == 0) ? BIT(m_tgs, 5) : ((m_ror & 0x1f) + y - 1); + + return (j > 31) ? (j - 24) : j; +} + // applies the insert, flash, conceal and negative attributes, // considering whether the cursor is on this character or not. std::tuple ef9345_device::makecolors(uint8_t c0, uint8_t c1, bool insert, bool flash, bool conceal, bool negative, bool cursor) @@ -775,12 +773,6 @@ void ef9345_device::makechar(uint16_t x, uint16_t y) makechar_24x40(x, y); break; case MODEVAR40: - if (m_variant == EF9345_MODE::TYPE_TS9347) - { // TS9347 char mode definition is different. - makechar_16x40(x, y); - break; - } - [[fallthrough]]; case MODE8x80: logerror("Unemulated EF9345 mode: %02x\n", m_char_mode); break; @@ -788,17 +780,7 @@ void ef9345_device::makechar(uint16_t x, uint16_t y) makechar_12x80(x, y); break; case MODE16x40: - if (m_variant == EF9345_MODE::TYPE_TS9347) - { - logerror("Unemulated EF9345 mode: %02x\n", m_char_mode); - } - else - { - makechar_16x40(x, y); - } - break; - default: - logerror("Unknown EF9345 mode: %02x\n", m_char_mode); + makechar_16x40(x, y); break; } } @@ -1178,3 +1160,34 @@ void ef9345_device::data_w(offs_t offset, uint8_t data) if (offset & 8) ef9345_exec(m_registers[0] & 0xff); } + +ef9345_device::char_mode_t ts9347_device::parse_video_mode() const +{ + switch (bitswap<2>(m_tgs, 7, 6)) + { + case 0b00: + return MODE24x40; + case 0b01: + return MODE16x40; + case 0b11: + return MODE12x80; + case 0b10: + return MODE8x80; + default: // unreachable + abort(); + } +} + +uint16_t ts9347_device::indexrow(uint16_t y) +{ + uint16_t j; + + // On the TS9347 the service row is displayed either at the top or at + // the bottom, and it is always fetched from Y=0. + if (m_tgs & 1) + j = (y == 24) ? 0 : ((m_ror & 0x1f) + y); + else + j = (y == 0) ? 0 : ((m_ror & 0x1f) + y - 1); + + return (j > 31) ? (j - 24) : j; +} diff --git a/src/devices/video/ef9345.h b/src/devices/video/ef9345.h index b31e3f1745e3c..cb6c1305aed08 100644 --- a/src/devices/video/ef9345.h +++ b/src/devices/video/ef9345.h @@ -39,8 +39,18 @@ class ef9345_device : public device_t, void update_scanline(uint16_t scanline); uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); -protected: + enum char_mode_t : uint8_t { + // 40 column modes: + MODE24x40, // long codes + MODEVAR40, // variable codes + MODE16x40, // short codes + + // 80 column modes: + MODE8x80, // long codes + MODE12x80, // variable codes + }; +protected: enum class EF9345_MODE { TYPE_EF9345 = 0x001, TYPE_TS9347 = 0x002 @@ -67,7 +77,6 @@ class ef9345_device : public device_t, TIMER_CALLBACK_MEMBER(clear_busy_flag); TIMER_CALLBACK_MEMBER(blink_tick); -private: void set_busy_flag(int period); void set_video_mode(void); void init_accented_chars(void); @@ -77,6 +86,12 @@ class ef9345_device : public device_t, uint16_t indexblock(uint16_t x, uint16_t y); std::tuple makecolors(uint8_t c0, uint8_t c1, bool insert, bool flash, bool conceal, bool negative, bool cursor); + virtual char_mode_t parse_video_mode() const; + + // Computes the index of the memory row containing data for the y-th + // screen row. + virtual uint16_t indexrow(uint16_t y); + // Dispatch rendering of character (x, y) to one of the specialized // drawing functions (bichrome40/quadrichrome40/bichrome80). void makechar(uint16_t x, uint16_t y); @@ -105,7 +120,7 @@ class ef9345_device : public device_t, address_space *m_videoram; uint8_t m_bf; //busy flag - uint8_t m_char_mode; //40 or 80 chars for line + char_mode_t m_char_mode; //40 or 80 chars for line uint8_t m_acc_char[0x2000]; //accented chars uint8_t m_registers[8]; //registers R0-R7 uint8_t m_state; //status register @@ -135,8 +150,14 @@ class ts9347_device : public ef9345_device { public: ts9347_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + virtual char_mode_t parse_video_mode() const override; + virtual uint16_t indexrow(uint16_t y) override; }; +ALLOW_SAVE_TYPE(ef9345_device::char_mode_t) + // device type definition DECLARE_DEVICE_TYPE(EF9345, ef9345_device) DECLARE_DEVICE_TYPE(TS9347, ts9347_device)