diff --git a/src/devices/video/sed1200.cpp b/src/devices/video/sed1200.cpp index 371832f579a..88503354873 100644 --- a/src/devices/video/sed1200.cpp +++ b/src/devices/video/sed1200.cpp @@ -4,7 +4,9 @@ SED1200 - A LCD controller. + A LCD controller similar to HD44780/SED1278 that drives a 20-character + display. Data input is 4 bits at a time. (SED1210 has a 40-character + display and 8-bit data input.) The D/F variants have a packaging difference (QFP80 vs. bare chip). @@ -16,10 +18,10 @@ #include "emu.h" #include "sed1200.h" -DEFINE_DEVICE_TYPE(SED1200D0A, sed1200d0a_device, "sed1200da", "Epson SED1200D-0A") -DEFINE_DEVICE_TYPE(SED1200F0A, sed1200f0a_device, "sed1200fa", "Epson SED1200F-0A") -DEFINE_DEVICE_TYPE(SED1200D0B, sed1200d0b_device, "sed1200db", "Epson SED1200D-0B") -DEFINE_DEVICE_TYPE(SED1200F0B, sed1200f0b_device, "sed1200fb", "Epson SED1200F-0B") +DEFINE_DEVICE_TYPE(SED1200D0A, sed1200d0a_device, "sed1200da", "Epson SED1200D-0A LCD Controller") +DEFINE_DEVICE_TYPE(SED1200F0A, sed1200f0a_device, "sed1200fa", "Epson SED1200F-0A LCD Controller") +DEFINE_DEVICE_TYPE(SED1200D0B, sed1200d0b_device, "sed1200db", "Epson SED1200D-0B LCD Controller") +DEFINE_DEVICE_TYPE(SED1200F0B, sed1200f0b_device, "sed1200fb", "Epson SED1200F-0B LCD Controller") ROM_START( sed1200x0a ) ROM_REGION( 0x800, "cgrom", 0 ) @@ -31,28 +33,40 @@ ROM_START( sed1200x0b ) ROM_LOAD( "sed1200-b.bin", 0x000, 0x800, CRC(d0741f51) SHA1(c8c856f1357286a2c8c806af81724a828345357e)) ROM_END -sed1200_device::sed1200_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : - device_t(mconfig, type, tag, owner, clock), cursor_direction(false), cursor_blinking(false), cursor_full(false), cursor_on(false), display_on(false), cursor_address(0), cgram_address(0), cgrom(nullptr) +sed1200_device::sed1200_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) + , cursor_direction(false) + , cursor_blinking(false) + , cursor_full(false) + , cursor_on(false) + , display_on(false) + , two_lines(false) + , cursor_address(0) + , cgram_address(0) + , cgrom(nullptr) + , chip_select(false) + , first_input(false) + , first_data(0) { } -sed1200d0a_device::sed1200d0a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - sed1200_device(mconfig, SED1200D0A, tag, owner, clock) +sed1200d0a_device::sed1200d0a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sed1200_device(mconfig, SED1200D0A, tag, owner, clock) { } -sed1200f0a_device::sed1200f0a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - sed1200_device(mconfig, SED1200F0A, tag, owner, clock) +sed1200f0a_device::sed1200f0a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sed1200_device(mconfig, SED1200F0A, tag, owner, clock) { } -sed1200d0b_device::sed1200d0b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - sed1200_device(mconfig, SED1200D0B, tag, owner, clock) +sed1200d0b_device::sed1200d0b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sed1200_device(mconfig, SED1200D0B, tag, owner, clock) { } -sed1200f0b_device::sed1200f0b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - sed1200_device(mconfig, SED1200F0B, tag, owner, clock) +sed1200f0b_device::sed1200f0b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sed1200_device(mconfig, SED1200F0B, tag, owner, clock) { } @@ -85,9 +99,33 @@ void sed1200_device::device_start() else cgrom = nullptr; + chip_select = false; + + save_item(NAME(cgram)); + save_item(NAME(ddram)); + save_item(NAME(cursor_direction)); + save_item(NAME(cursor_blinking)); + save_item(NAME(cursor_full)); + save_item(NAME(cursor_on)); + save_item(NAME(display_on)); + save_item(NAME(two_lines)); + save_item(NAME(cursor_address)); + save_item(NAME(cgram_address)); + save_item(NAME(chip_select)); + save_item(NAME(first_input)); + save_item(NAME(first_data)); + soft_reset(); } +void sed1200_device::cs_w(int state) +{ + if (chip_select != !state) { + chip_select = !state; + first_input = true; + } +} + void sed1200_device::soft_reset() { cursor_direction = false; @@ -95,11 +133,23 @@ void sed1200_device::soft_reset() cursor_full = false; cursor_on = false; display_on = false; + two_lines = false; cursor_address = 0x00; cgram_address = 0x00; } void sed1200_device::control_w(uint8_t data) +{ + if(chip_select) { + if(first_input) + first_data = data & 0x0f; + else + control_write(first_data << 4 | (data & 0x0f)); + first_input = !first_input; + } +} + +void sed1200_device::control_write(uint8_t data) { switch(data) { case 0x04: case 0x05: @@ -124,7 +174,8 @@ void sed1200_device::control_w(uint8_t data) soft_reset(); break; case 0x12: case 0x13: - break; // Number of lines selection + two_lines = data & 0x01; + break; default: if((data & 0xf0) == 0x20) cgram_address = (data & 3)*8; @@ -133,19 +184,34 @@ void sed1200_device::control_w(uint8_t data) if(cgram_address == 4*8) cgram_address = 0; } else if(data & 0x80) { - cursor_address = data & 0x40 ? 10 : 0; - cursor_address += (data & 0x3f) >= 10 ? 9 : data & 0x3f; + if (two_lines) { + cursor_address = data & 0x40 ? 10 : 0; + cursor_address += (data & 0x3f) >= 10 ? 9 : data & 0x3f; + } else + cursor_address = (data & 0x3f) >= 20 ? 19 : data & 0x3f; } break; } } -uint8_t sed1200_device::control_r() +uint8_t sed1200_device::busy_r() { + // TODO: bit 3 = busy flag return 0x00; } void sed1200_device::data_w(uint8_t data) +{ + if(chip_select) { + if(first_input) + first_data = data & 0x0f; + else + data_write(first_data << 4 | (data & 0x0f)); + first_input = !first_input; + } +} + +void sed1200_device::data_write(uint8_t data) { ddram[cursor_address] = data; cursor_step(); @@ -154,14 +220,10 @@ void sed1200_device::data_w(uint8_t data) void sed1200_device::cursor_step() { if(cursor_direction) { - if(cursor_address == 0 || cursor_address == 10) - cursor_address += 9; - else + if(cursor_address != 0 && (!two_lines || cursor_address != 10)) cursor_address --; } else { - if(cursor_address == 9 || cursor_address == 19) - cursor_address -= 9; - else + if((!two_lines || cursor_address != 9) && cursor_address != 19) cursor_address ++; } } diff --git a/src/devices/video/sed1200.h b/src/devices/video/sed1200.h index d6590af49ab..480ff9b454e 100644 --- a/src/devices/video/sed1200.h +++ b/src/devices/video/sed1200.h @@ -20,8 +20,9 @@ class sed1200_device : public device_t { public: + void cs_w(int state); void control_w(uint8_t data); - uint8_t control_r(); + uint8_t busy_r(); void data_w(uint8_t data); const uint8_t *render(); @@ -35,10 +36,16 @@ private: uint8_t cgram[4*8]; uint8_t ddram[10*2]; uint8_t render_buf[20*8]; - bool cursor_direction, cursor_blinking, cursor_full, cursor_on, display_on; + bool cursor_direction, cursor_blinking, cursor_full, cursor_on, display_on, two_lines; uint8_t cursor_address, cgram_address; const uint8_t *cgrom; + bool chip_select, first_input; + uint8_t first_data; + + void control_write(uint8_t data); + void data_write(uint8_t data); + void soft_reset(); void cursor_step(); }; diff --git a/src/mame/roland/roland_mt32.cpp b/src/mame/roland/roland_mt32.cpp index cba45237154..4a75aac74ee 100644 --- a/src/mame/roland/roland_mt32.cpp +++ b/src/mame/roland/roland_mt32.cpp @@ -275,15 +275,21 @@ void mt32_state::machine_reset() void mt32_state::lcd_ctrl_w(uint8_t data) { + lcd->cs_w(0); + lcd->control_w(data >> 4); lcd->control_w(data); - for(int i=0; i != lcd_data_buffer_pos; i++) + for(int i=0; i != lcd_data_buffer_pos; i++) { + lcd->data_w(lcd_data_buffer[i] >> 4); lcd->data_w(lcd_data_buffer[i]); + } + lcd->cs_w(1); lcd_data_buffer_pos = 0; } uint8_t mt32_state::lcd_ctrl_r() { - return lcd->control_r(); + // Note that this does not read from the actual LCD unit (whose /RD line is pulled high) + return 0; } void mt32_state::lcd_data_w(uint8_t data)