diff --git a/src/devices/video/hd44780.cpp b/src/devices/video/hd44780.cpp index 8a1a436befb..0c64922aa3f 100644 --- a/src/devices/video/hd44780.cpp +++ b/src/devices/video/hd44780.cpp @@ -57,6 +57,10 @@ hd44780_device::hd44780_device(const machine_config &mconfig, device_type type, : device_t(mconfig, type, tag, owner, clock) , m_cgrom(nullptr) , m_cgrom_region(*this, DEVICE_SELF) + , m_rs_input(0) + , m_rw_input(0) + , m_db_input(0) + , m_enabled(false) { } @@ -115,6 +119,10 @@ void hd44780_device::device_start() save_item(NAME(m_ddram)); save_item(NAME(m_cgram)); save_item(NAME(m_nibble)); + save_item(NAME(m_rs_input)); + save_item(NAME(m_rw_input)); + save_item(NAME(m_db_input)); + save_item(NAME(m_enabled)); save_item(NAME(m_rs_state)); save_item(NAME(m_rw_state)); } @@ -234,7 +242,7 @@ void hd44780_device::update_nibble(int rs, int rw) m_nibble = !m_nibble; } -inline void hd44780_device::pixel_update(bitmap_ind16 &bitmap, uint8_t line, uint8_t pos, uint8_t y, uint8_t x, int state) +inline void hd44780_device::pixel_update(bitmap_ind16 &bitmap, u8 line, u8 pos, u8 y, u8 x, int state) { if (!m_pixel_update_cb.isnull()) { @@ -242,7 +250,7 @@ inline void hd44780_device::pixel_update(bitmap_ind16 &bitmap, uint8_t line, uin } else { - uint8_t line_height = (m_char_size == 8) ? m_char_size : m_char_size + 1; + u8 line_height = (m_char_size == 8) ? m_char_size : m_char_size + 1; if (m_lines <= 2) { @@ -275,13 +283,13 @@ inline void hd44780_device::pixel_update(bitmap_ind16 &bitmap, uint8_t line, uin // device interface //************************************************************************** -const uint8_t *hd44780_device::render() +const u8 *hd44780_device::render() { memset(m_render_buf, 0, sizeof(m_render_buf)); if (m_display_on) { - uint8_t line_size = 80 / m_num_line; + u8 line_size = 80 / m_num_line; for (int line = 0; line < m_num_line; line++) { @@ -304,8 +312,8 @@ const uint8_t *hd44780_device::render() char_base = m_ddram[char_pos] * 0x10; } - const uint8_t * charset = (m_ddram[char_pos] < 0x10) ? m_cgram : m_cgrom; - uint8_t *dest = m_render_buf + 16 * (line * line_size + pos); + const u8 *charset = (m_ddram[char_pos] < 0x10) ? m_cgram : m_cgrom; + u8 *dest = m_render_buf + 16 * (line * line_size + pos); memcpy (dest, charset + char_base, m_char_size); if (char_pos == m_ac) @@ -327,15 +335,15 @@ const uint8_t *hd44780_device::render() uint32_t hd44780_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { bitmap.fill(0, cliprect); - const uint8_t *img = render(); + const u8 *img = render(); - uint8_t line_size = 80 / m_num_line; + u8 line_size = 80 / m_num_line; for (int line = 0; line < m_num_line; line++) { for (int pos = 0; pos < line_size; pos++) { - const uint8_t *src = img + 16 * (line * line_size + pos); + const u8 *src = img + 16 * (line * line_size + pos); for (int y = 0; y < m_char_size; y++) for (int x = 0; x < 5; x++) pixel_update(bitmap, line, pos, y, x, BIT(src[y], 4 - x)); @@ -347,6 +355,9 @@ uint32_t hd44780_device::screen_update(screen_device &screen, bitmap_ind16 &bitm u8 hd44780_device::read(offs_t offset) { + if (m_data_len == 4 && !machine().side_effects_disabled()) + update_nibble(offset & 0x01, 1); + switch (offset & 0x01) { case 0: return control_read(); @@ -358,6 +369,9 @@ u8 hd44780_device::read(offs_t offset) void hd44780_device::write(offs_t offset, u8 data) { + if (m_data_len == 4 && !machine().side_effects_disabled()) + update_nibble(offset & 0x01, 0); + switch (offset & 0x01) { case 0: control_write(data); break; @@ -365,12 +379,56 @@ void hd44780_device::write(offs_t offset, u8 data) } } +u8 hd44780_device::db_r() +{ + if (m_enabled && m_rw_input == 1) + { + switch (m_rs_input) + { + case 0: return control_read(); + case 1: return data_read(); + } + } + + return 0xff; +} + +void hd44780_device::db_w(u8 data) +{ + m_db_input = data; +} + +WRITE_LINE_MEMBER(hd44780_device::rs_w) +{ + m_rs_input = state; +} + +WRITE_LINE_MEMBER(hd44780_device::rw_w) +{ + m_rw_input = state; +} + +WRITE_LINE_MEMBER(hd44780_device::e_w) +{ + if (m_data_len == 4 && state && !m_enabled && !machine().side_effects_disabled()) + update_nibble(m_rs_input, m_rw_input); + + if (!state && m_enabled && m_rw_input == 0) + { + switch (m_rs_input) + { + case 0: control_write(m_db_input); break; + case 1: data_write(m_db_input); break; + } + } + + m_enabled = state; +} + void hd44780_device::control_write(u8 data) { if (m_data_len == 4) { - update_nibble(0, 0); - if (m_nibble) { m_ir = data & 0xf0; @@ -489,9 +547,6 @@ u8 hd44780_device::control_read() { if (m_data_len == 4) { - if (!machine().side_effects_disabled()) - update_nibble(0, 1); - if (m_nibble) return (m_busy_flag ? 0x80 : 0) | (m_ac & 0x70); else @@ -513,8 +568,6 @@ void hd44780_device::data_write(u8 data) if (m_data_len == 4) { - update_nibble(1, 0); - if (m_nibble) { m_dr = data & 0xf0; @@ -545,15 +598,12 @@ void hd44780_device::data_write(u8 data) u8 hd44780_device::data_read() { - uint8_t data = (m_active_ram == DDRAM) ? m_ddram[m_ac] : m_cgram[m_ac]; + u8 data = (m_active_ram == DDRAM) ? m_ddram[m_ac] : m_cgram[m_ac]; LOG("HD44780: %sRAM read %x %c\n", m_active_ram == DDRAM ? "DD" : "CG", m_ac, data); if (m_data_len == 4) { - if (!machine().side_effects_disabled()) - update_nibble(1, 1); - if (m_nibble) return data & 0xf0; else diff --git a/src/devices/video/hd44780.h b/src/devices/video/hd44780.h index a6572536cf1..c31cd67b426 100644 --- a/src/devices/video/hd44780.h +++ b/src/devices/video/hd44780.h @@ -16,7 +16,7 @@ // TYPE DEFINITIONS //************************************************************************** -#define HD44780_PIXEL_UPDATE(name) void name(bitmap_ind16 &bitmap, uint8_t line, uint8_t pos, uint8_t y, uint8_t x, int state) +#define HD44780_PIXEL_UPDATE(name) void name(bitmap_ind16 &bitmap, u8 line, u8 pos, u8 y, u8 x, int state) // ======================> hd44780_device @@ -24,7 +24,7 @@ class hd44780_device : public device_t { public: - typedef device_delegate pixel_update_delegate; + typedef device_delegate pixel_update_delegate; // construction/destruction hd44780_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); @@ -34,25 +34,31 @@ public: template void set_pixel_update_cb(T &&... args) { m_pixel_update_cb = pixel_update_delegate(std::forward(args)...); } void set_pixel_update_cb(pixel_update_delegate callback) { m_pixel_update_cb = callback; } template void set_pixel_update_cb(const char *devname, - void (FunctionClass::*callback)(bitmap_ind16 &, uint8_t, uint8_t, uint8_t, uint8_t, int), const char *name) + void (FunctionClass::*callback)(bitmap_ind16 &, u8, u8, u8, u8, int), const char *name) { set_pixel_update_cb(pixel_update_delegate(callback, name, devname, static_cast(nullptr))); } template void set_pixel_update_cb( - void (FunctionClass::*callback)(bitmap_ind16 &, uint8_t, uint8_t, uint8_t, uint8_t, int), const char *name) + void (FunctionClass::*callback)(bitmap_ind16 &, u8, u8, u8, u8, int), const char *name) { set_pixel_update_cb(pixel_update_delegate(callback, name, nullptr, static_cast(nullptr))); } // device interface - virtual void write(offs_t offset, u8 data); - virtual u8 read(offs_t offset); - virtual void control_write(u8 data); - virtual u8 control_read(); - virtual void data_write(u8 data); - virtual u8 data_read(); + void write(offs_t offset, u8 data); + u8 read(offs_t offset); + void control_w(u8 data) { write(0, data); } + u8 control_r() { return read(0); } + void data_w(u8 data) { write(1, data); } + u8 data_r() { return read(1); } - const uint8_t *render(); + u8 db_r(); + void db_w(u8 data); + DECLARE_WRITE_LINE_MEMBER(rs_w); + DECLARE_WRITE_LINE_MEMBER(rw_w); + DECLARE_WRITE_LINE_MEMBER(e_w); + + const u8 *render(); virtual uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); protected: @@ -81,6 +87,11 @@ protected: */ }; + virtual void control_write(u8 data); + virtual u8 control_read(); + virtual void data_write(u8 data); + virtual u8 data_read(); + void set_charset_type(int type); private: @@ -90,7 +101,7 @@ private: void update_ac(int direction); void update_nibble(int rs, int rw); void shift_display(int direction); - void pixel_update(bitmap_ind16 &bitmap, uint8_t line, uint8_t pos, uint8_t y, uint8_t x, int state); + void pixel_update(bitmap_ind16 &bitmap, u8 line, u8 pos, u8 y, u8 x, int state); // internal state static constexpr device_timer_id TIMER_BUSY = 0; @@ -99,35 +110,39 @@ private: emu_timer * m_blink_timer; emu_timer * m_busy_timer; - uint8_t m_lines; // number of lines - uint8_t m_chars; // chars for line + u8 m_lines; // number of lines + u8 m_chars; // chars for line pixel_update_delegate m_pixel_update_cb; // pixel update callback bool m_busy_flag; // busy flag - uint8_t m_ddram[0x80]; // internal display data RAM - uint8_t m_cgram[0x40]; // internal chargen RAM - uint8_t const *m_cgrom; - optional_region_ptr m_cgrom_region; // internal chargen ROM + u8 m_ddram[0x80]; // internal display data RAM + u8 m_cgram[0x40]; // internal chargen RAM + u8 const *m_cgrom; + optional_region_ptr m_cgrom_region; // internal chargen ROM int m_ac; // address counter - uint8_t m_dr; // data register - uint8_t m_ir; // instruction register - uint8_t m_active_ram; // DDRAM or CGRAM + u8 m_dr; // data register + u8 m_ir; // instruction register + u8 m_active_ram; // DDRAM or CGRAM bool m_display_on; // display on/off bool m_cursor_on; // cursor on/off bool m_blink_on; // blink on/off bool m_shift_on; // shift on/off int m_disp_shift; // display shift int m_direction; // auto increment/decrement (-1 or +1) - uint8_t m_data_len; // interface data length 4 or 8 bit - uint8_t m_num_line; // number of lines - uint8_t m_char_size; // char size 5x8 or 5x10 + u8 m_data_len; // interface data length 4 or 8 bit + u8 m_num_line; // number of lines + u8 m_char_size; // char size 5x8 or 5x10 bool m_blink; bool m_first_cmd; + int m_rs_input; + int m_rw_input; + u8 m_db_input; + bool m_enabled; int m_rs_state; int m_rw_state; bool m_nibble; int m_charset_type; - uint8_t m_render_buf[80 * 16]; + u8 m_render_buf[80 * 16]; enum { DDRAM, CGRAM }; }; diff --git a/src/mame/drivers/fb01.cpp b/src/mame/drivers/fb01.cpp index 21707c452cc..3c2202390da 100644 --- a/src/mame/drivers/fb01.cpp +++ b/src/mame/drivers/fb01.cpp @@ -89,8 +89,7 @@ void fb01_state::fb01_io(address_map &map) map(0x20, 0x20).portr("PANEL"); // 30-31 HD44780A - map(0x30, 0x30).rw("hd44780", FUNC(hd44780_device::control_read), FUNC(hd44780_device::control_write)); - map(0x31, 0x31).rw("hd44780", FUNC(hd44780_device::data_read), FUNC(hd44780_device::data_write)); + map(0x30, 0x31).rw("hd44780", FUNC(hd44780_device::read), FUNC(hd44780_device::write)); } diff --git a/src/mame/drivers/hprot1.cpp b/src/mame/drivers/hprot1.cpp index 2a30193de12..64c198ac95d 100644 --- a/src/mame/drivers/hprot1.cpp +++ b/src/mame/drivers/hprot1.cpp @@ -135,10 +135,10 @@ void hprot1_state::i80c31_io(address_map &map) { map(0x0000, 0x7fff).ram(); /*TODO: verify the mirror mask value for the HD44780 device */ - map(0xc000, 0xc000).mirror(0x13cf).w(m_lcdc, FUNC(hd44780_device::control_write)); - map(0xc010, 0xc010).mirror(0x13cf).w(m_lcdc, FUNC(hd44780_device::data_write)); - map(0xc020, 0xc020).mirror(0x13cf).r(m_lcdc, FUNC(hd44780_device::control_read)); - map(0xc030, 0xc030).mirror(0x13cf).r(m_lcdc, FUNC(hd44780_device::data_read)); + map(0xc000, 0xc000).mirror(0x13cf).w(m_lcdc, FUNC(hd44780_device::control_w)); + map(0xc010, 0xc010).mirror(0x13cf).w(m_lcdc, FUNC(hd44780_device::data_w)); + map(0xc020, 0xc020).mirror(0x13cf).r(m_lcdc, FUNC(hd44780_device::control_r)); + map(0xc030, 0xc030).mirror(0x13cf).r(m_lcdc, FUNC(hd44780_device::data_r)); /*TODO: attach the watchdog/brownout reset device: map(0xe000,0xe0??).mirror(?).r("adm965an", FUNC(adm965an_device::data_read)); */ } diff --git a/src/mame/drivers/icatel.cpp b/src/mame/drivers/icatel.cpp index 52581ce4300..c379af15e76 100644 --- a/src/mame/drivers/icatel.cpp +++ b/src/mame/drivers/icatel.cpp @@ -89,8 +89,7 @@ void icatel_state::i80c31_io(address_map &map) { map(0x0000, 0x3FFF).ram(); map(0x8000, 0x8002).ram(); /* HACK! */ - map(0x8040, 0x8040).mirror(0x3F1E).w(m_lcdc, FUNC(hd44780_device::control_write)); // not sure yet. CI12 (73LS273) - map(0x8041, 0x8041).mirror(0x3F1E).w(m_lcdc, FUNC(hd44780_device::data_write)); // not sure yet. CI12 + map(0x8040, 0x8041).mirror(0x3F1E).w(m_lcdc, FUNC(hd44780_device::write)); // not sure yet. CI12 (73LS273) map(0x8060, 0x8060).mirror(0x3F1F).rw(FUNC(icatel_state::ci8_r), FUNC(icatel_state::ci8_w)); map(0x8080, 0x8080).mirror(0x3F1F).rw(FUNC(icatel_state::ci16_r), FUNC(icatel_state::ci16_w)); // card reader (?) map(0x80C0, 0x80C0).mirror(0x3F1F).rw(FUNC(icatel_state::ci15_r), FUNC(icatel_state::ci15_w)); // 74LS244 (tristate buffer) diff --git a/src/mame/drivers/lcmate2.cpp b/src/mame/drivers/lcmate2.cpp index a03cf631c46..bb86aa81a75 100644 --- a/src/mame/drivers/lcmate2.cpp +++ b/src/mame/drivers/lcmate2.cpp @@ -111,10 +111,8 @@ void lcmate2_state::lcmate2_io(address_map &map) map(0x1000, 0x1000).w(FUNC(lcmate2_state::speaker_w)); map(0x1fff, 0x1fff).w(FUNC(lcmate2_state::bankswitch_w)); - map(0x3000, 0x3000).w(m_lcdc, FUNC(hd44780_device::control_write)); - map(0x3001, 0x3001).w(m_lcdc, FUNC(hd44780_device::data_write)); - map(0x3002, 0x3002).r(m_lcdc, FUNC(hd44780_device::control_read)); - map(0x3003, 0x3003).r(m_lcdc, FUNC(hd44780_device::data_read)); + map(0x3000, 0x3001).w(m_lcdc, FUNC(hd44780_device::write)); + map(0x3002, 0x3003).r(m_lcdc, FUNC(hd44780_device::read)); map(0x5000, 0x50ff).r(FUNC(lcmate2_state::key_r)); } diff --git a/src/mame/drivers/ml20.cpp b/src/mame/drivers/ml20.cpp index bd46607fdfe..29964942c1a 100644 --- a/src/mame/drivers/ml20.cpp +++ b/src/mame/drivers/ml20.cpp @@ -112,8 +112,8 @@ void ml20_state::mem_map(address_map &map) void ml20_state::io_map(address_map &map) { map(0x00, 0x0f).rw("rtc", FUNC(msm6242_device::read), FUNC(msm6242_device::write)); - map(0x10, 0x10).rw(m_lcdc, FUNC(hd44780_device::data_read), FUNC(hd44780_device::data_write)); - map(0x14, 0x14).rw(m_lcdc, FUNC(hd44780_device::control_read), FUNC(hd44780_device::control_write)); + map(0x10, 0x10).rw(m_lcdc, FUNC(hd44780_device::data_r), FUNC(hd44780_device::data_w)); + map(0x14, 0x14).rw(m_lcdc, FUNC(hd44780_device::control_r), FUNC(hd44780_device::control_w)); } static INPUT_PORTS_START( ml20 ) diff --git a/src/mame/drivers/pc2000.cpp b/src/mame/drivers/pc2000.cpp index 849bf3c0c5f..22582db66e6 100644 --- a/src/mame/drivers/pc2000.cpp +++ b/src/mame/drivers/pc2000.cpp @@ -364,7 +364,7 @@ READ8_MEMBER( pc1000_state::kb_r ) READ8_MEMBER( pc1000_state::lcdc_data_r ) { //logerror("lcdc data r\n"); - return m_lcdc->data_read() >> 4; + return m_lcdc->data_r() >> 4; } WRITE8_MEMBER( pc1000_state::lcdc_data_w ) @@ -372,19 +372,19 @@ WRITE8_MEMBER( pc1000_state::lcdc_data_w ) //popmessage("%s", (char*)m_maincpu->space(AS_PROGRAM).get_read_ptr(0x4290)); //logerror("lcdc data w %x\n", data); - m_lcdc->data_write(data << 4); + m_lcdc->data_w(data << 4); } READ8_MEMBER( pc1000_state::lcdc_control_r ) { //logerror("lcdc control r\n"); - return m_lcdc->control_read() >> 4; + return m_lcdc->control_r() >> 4; } WRITE8_MEMBER( pc1000_state::lcdc_control_w ) { //logerror("lcdc control w %x\n", data); - m_lcdc->control_write(data<<4); + m_lcdc->control_w(data<<4); } HD44780_PIXEL_UPDATE(pc1000_state::pc1000_pixel_update) diff --git a/src/mame/drivers/piggypas.cpp b/src/mame/drivers/piggypas.cpp index 400d87a235b..20b3a23f899 100644 --- a/src/mame/drivers/piggypas.cpp +++ b/src/mame/drivers/piggypas.cpp @@ -95,13 +95,14 @@ WRITE8_MEMBER(piggypas_state::led_strobe_w) READ8_MEMBER(piggypas_state::lcd_latch_r) { - return m_lcd_latch; + return m_hd44780->db_r(); } WRITE8_MEMBER(piggypas_state::lcd_latch_w) { // P1.7 might also be used to reset DS1232 watchdog m_lcd_latch = data; + m_hd44780->db_w(data); } WRITE8_MEMBER(piggypas_state::lcd_control_w) @@ -109,13 +110,9 @@ WRITE8_MEMBER(piggypas_state::lcd_control_w) // RXD (P3.0) = chip select // TXD (P3.1) = register select // INT0 (P3.2) = R/W - if (BIT(data, 0)) - { - if (BIT(data, 2)) - m_lcd_latch = m_hd44780->read(BIT(data, 1)); - else - m_hd44780->write(BIT(data, 1), m_lcd_latch); - } + m_hd44780->e_w(BIT(data, 0)); + m_hd44780->rs_w(BIT(data, 1)); + m_hd44780->rw_w(BIT(data, 2)); // T0 (P3.4) = output shift clock (serial data present at P1.0) // T1 (P3.5) = output latch enable diff --git a/src/mame/drivers/psion.cpp b/src/mame/drivers/psion.cpp index ae92011d2a4..7583a170ec7 100644 --- a/src/mame/drivers/psion.cpp +++ b/src/mame/drivers/psion.cpp @@ -252,8 +252,7 @@ void psion1_state::psion1_mem(address_map &map) { map(0x0000, 0x001f).rw(FUNC(psion1_state::hd63701_int_reg_r), FUNC(psion1_state::hd63701_int_reg_w)); map(0x0040, 0x00ff).ram().share("sys_register"); - map(0x2000, 0x2000).mirror(0x07fe).rw(m_lcdc, FUNC(hd44780_device::control_read), FUNC(hd44780_device::control_write)); - map(0x2001, 0x2001).mirror(0x07fe).rw(m_lcdc, FUNC(hd44780_device::data_read), FUNC(hd44780_device::data_write)); + map(0x2000, 0x2001).mirror(0x07fe).rw(m_lcdc, FUNC(hd44780_device::read), FUNC(hd44780_device::write)); map(0x2800, 0x2800).r(FUNC(psion1_state::reset_kb_counter_r)); map(0x2e00, 0x2e00).r(FUNC(psion1_state::switchoff_r)); map(0x3000, 0x3000).r(FUNC(psion1_state::inc_kb_counter_r)); diff --git a/src/mame/drivers/replicator.cpp b/src/mame/drivers/replicator.cpp index 972be03daf0..2e1495c94db 100644 --- a/src/mame/drivers/replicator.cpp +++ b/src/mame/drivers/replicator.cpp @@ -360,11 +360,7 @@ WRITE8_MEMBER(replicator_state::port_w) uint8_t lcd_data = shift_register_value & 0xF0; if (enable && RW==0){ - if (RS==0){ - m_lcdc->control_write(lcd_data); - } else { - m_lcdc->data_write(lcd_data); - } + m_lcdc->write(RS, lcd_data); } } } diff --git a/src/mame/drivers/ti630.cpp b/src/mame/drivers/ti630.cpp index 1bd7972cb07..2c3ae24f291 100644 --- a/src/mame/drivers/ti630.cpp +++ b/src/mame/drivers/ti630.cpp @@ -83,9 +83,9 @@ void ti630_state::init_ti630() void ti630_state::i80c31_io(address_map &map) { - map(0x0000, 0x0000) /*.mirror(?)*/ .w("hd44780", FUNC(hd44780_device::control_write)); - map(0x1000, 0x1000) /*.mirror(?)*/ .w("hd44780", FUNC(hd44780_device::data_write)); - map(0x2000, 0x2000) /*.mirror(?)*/ .r("hd44780", FUNC(hd44780_device::control_read)); + map(0x0000, 0x0000) /*.mirror(?)*/ .w("hd44780", FUNC(hd44780_device::control_w)); + map(0x1000, 0x1000) /*.mirror(?)*/ .w("hd44780", FUNC(hd44780_device::data_w)); + map(0x2000, 0x2000) /*.mirror(?)*/ .r("hd44780", FUNC(hd44780_device::control_r)); map(0x8000, 0xffff).ram(); /*TODO: verify the ammont of RAM and the correct address range to which it is mapped. This is just a first reasonable guess that apparently yields good results in the emulation */ } diff --git a/src/mame/machine/mulcd.h b/src/mame/machine/mulcd.h index 061a7efa0ad..2bf013a5dd5 100644 --- a/src/mame/machine/mulcd.h +++ b/src/mame/machine/mulcd.h @@ -19,10 +19,10 @@ public: void set_contrast(float contrast) { m_contrast = contrast; } void set_leds(u8 leds) { m_leds = leds; } - u8 data_read() { return m_lcd->data_read(); } - u8 control_read() { return m_lcd->control_read(); } - void data_write(u8 data) { m_lcd->data_write(data); } - void control_write(u8 data) { m_lcd->control_write(data); } + u8 data_read() { return m_lcd->data_r(); } + u8 control_read() { return m_lcd->control_r(); } + void data_write(u8 data) { m_lcd->data_w(data); } + void control_write(u8 data) { m_lcd->control_w(data); } protected: