diff options
author | 2019-05-06 20:26:05 -0400 | |
---|---|---|
committer | 2019-05-06 20:27:20 -0400 | |
commit | 610897fd3823ae7d5377534202faed56c30b13df (patch) | |
tree | 4dd225b8ee31c0b737abf49e8366ba544f79de0f | |
parent | 43c856c9e9d5f38051fb02e19d47f35fcef6a5f6 (diff) |
Preliminary emulation of T6963C and related LCD controllers
-rw-r--r-- | scripts/src/video.lua | 12 | ||||
-rw-r--r-- | scripts/target/mame/arcade.lua | 1 | ||||
-rw-r--r-- | scripts/target/mame/mess.lua | 1 | ||||
-rw-r--r-- | src/devices/video/t6963c.cpp | 311 | ||||
-rw-r--r-- | src/devices/video/t6963c.h | 93 | ||||
-rw-r--r-- | src/mame/drivers/krz2000.cpp | 20 |
6 files changed, 422 insertions, 16 deletions
diff --git a/scripts/src/video.lua b/scripts/src/video.lua index 069c2fc802d..042be7e2a19 100644 --- a/scripts/src/video.lua +++ b/scripts/src/video.lua @@ -816,6 +816,18 @@ end -------------------------------------------------- -- +--@src/devices/video/t6963c.h,VIDEOS["T6963C"] = true +-------------------------------------------------- + +if (VIDEOS["T6963C"]~=null) then + files { + MAME_DIR .. "src/devices/video/t6963c.cpp", + MAME_DIR .. "src/devices/video/t6963c.h", + } +end + +-------------------------------------------------- +-- --@src/devices/video/t6a04.h,VIDEOS["T6A04"] = true -------------------------------------------------- diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index df0e9e9d88a..8ddb6d6b7bc 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -341,6 +341,7 @@ VIDEOS["SCN2674"] = true --VIDEOS["SED1520"] = true VIDEOS["SNES_PPU"] = true VIDEOS["STVVDP"] = true +--VIDEOS["T6963C"] = true --VIDEOS["T6A04"] = true VIDEOS["TLC34076"] = true VIDEOS["TMS34061"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index a6c4b24d22f..714f6a56732 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -360,6 +360,7 @@ VIDEOS["SED1330"] = true VIDEOS["SED1520"] = true VIDEOS["SNES_PPU"] = true VIDEOS["STVVDP"] = true +VIDEOS["T6963C"] = true VIDEOS["T6A04"] = true VIDEOS["TEA1002"] = true --VIDEOS["TLC34076"] = true diff --git a/src/devices/video/t6963c.cpp b/src/devices/video/t6963c.cpp new file mode 100644 index 00000000000..0a07a1a7553 --- /dev/null +++ b/src/devices/video/t6963c.cpp @@ -0,0 +1,311 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + Toshiba T6963C Dot Matrix LCD Controller + Sharp LM24014H Dot Matrix LCD Unit + +**********************************************************************/ + +#include "emu.h" +#include "t6963c.h" + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// device type definitions +DEFINE_DEVICE_TYPE(T6963C, t6963c_device, "t6963c", "T6963C LCD Controller") +DEFINE_DEVICE_TYPE(LM24014H, lm24014h_device, "lm24014h", "LM24014H LCD Unit (240x64)") + + +//************************************************************************** +// T6963C LCD CONTROLLER +//************************************************************************** + +ALLOW_SAVE_TYPE(t6963c_device::auto_mode); + +//------------------------------------------------- +// t6963c_device - constructor +//------------------------------------------------- + +t6963c_device::t6963c_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, T6963C, tag, owner, clock) + , device_memory_interface(mconfig, *this) + , m_display_config("display", ENDIANNESS_LITTLE, 8, 16, 0) + , m_cgrom(*this, "cgrom", 0x400) + , m_display_ram(nullptr) + , m_data(0) + , m_adp(0) + , m_auto_mode(auto_mode::NONE) +{ +} + + +//------------------------------------------------- +// memory_space_config - return the configuration +// for the device's address spaces +//------------------------------------------------- + +device_memory_interface::space_config_vector t6963c_device::memory_space_config() const +{ + return space_config_vector { + std::make_pair(0, &m_display_config), + }; +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void t6963c_device::device_start() +{ + m_display_ram = &space(0); + + save_item(NAME(m_data)); + save_item(NAME(m_adp)); + save_item(NAME(m_auto_mode)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void t6963c_device::device_reset() +{ + m_auto_mode = auto_mode::NONE; +} + + +//------------------------------------------------- +// read - read from the status or data register +//------------------------------------------------- + +u8 t6963c_device::read(offs_t offset) +{ + return BIT(offset, 0) ? 0x0b : 0x00; +} + + +//------------------------------------------------- +// write - write to the command or data register +//------------------------------------------------- + +void t6963c_device::write(offs_t offset, u8 data) +{ + if (BIT(offset, 0)) + { + // Command register + do_command(data); + } + else + { + // Data register + if (m_auto_mode == auto_mode::WRITE) + { + logerror("%s: Auto write %02X to %04X\n", machine().describe_context(), data, m_adp); + m_display_ram->write_byte(m_adp++, data); + } + else + m_data = (u16(data) << 8) | (data >> 8); + } +} + + +//------------------------------------------------- +// do_command - decode and execute one command +//------------------------------------------------- + +void t6963c_device::do_command(u8 cmd) +{ + if ((cmd & 0xf0) == 0x20) + { + switch (cmd & 0x0f) + { + case 0x01: + logerror("%s: Setting cursor pointer X:Y = %02X:%02X\n", machine().describe_context(), m_data & 0xff, m_data >> 8); + break; + + case 0x02: + logerror("%s: Setting offset register for CG RAM at %04X to %04XH\n", + machine().describe_context(), + (m_data & 0x1f) << 11, + (m_data & 0x1f) << 11 | 0x7ff); + break; + + case 0x04: + logerror("%s: Setting address pointer = %04X\n", machine().describe_context(), m_data); + m_adp = m_data; + break; + + default: + logerror("%s: Setting unknown pointer = %04X\n", machine().describe_context(), m_data); + break; + } + } + else if ((cmd & 0xfd) == 0x40) + { + logerror("%s: Setting %s home address = %04X\n", machine().describe_context(), + BIT(cmd, 1) ? "graphic" : "text", + m_data); + } + else if ((cmd & 0xfd) == 0x41) + { + logerror("%s: Setting %s area = %d columns\n", machine().describe_context(), + BIT(cmd, 1) ? "graphic" : "text", + m_data); + } + else if ((cmd & 0xf0) == 0x80) + { + logerror("%s: %s mode, %s\n", machine().describe_context(), + (cmd & 0x07) == 0x00 ? "OR" + : (cmd & 0x07) == 0x01 ? "EXOR" + : (cmd & 0x07) == 0x03 ? "AND" + : (cmd & 0x07) == 0x04 ? "Text attribute" + : "Unknown", + BIT(cmd, 3) ? "external CG RAM" : "internal CG ROM"); + } + else if ((cmd & 0xf0) == 0x90) + { + if (cmd == 0x90) + logerror("%s: Display off\n", machine().describe_context()); + else + logerror("%s: Text %s, graphic %s, cursor %s, blink %s\n", + machine().describe_context(), + BIT(cmd, 3) ? "on" : "off", + BIT(cmd, 2) ? "on" : "off", + BIT(cmd, 1) ? "on" : "off", + BIT(cmd, 0) ? "on" : "off"); + } + else if ((cmd & 0xf8) == 0xa0) + { + logerror("%s: Select %d-line cursor\n", machine().describe_context(), (cmd & 0x07) + 1); + } + else if ((cmd & 0xfe) == 0xb0) + { + logerror("%s: Set data auto %s\n", machine().describe_context(), BIT(cmd, 0) ? "read" : "write"); + m_auto_mode = BIT(cmd, 0) ? auto_mode::READ : auto_mode::WRITE; + } + else if (cmd == 0xb2) + { + logerror("%s: Auto reset\n", machine().describe_context()); + m_auto_mode = auto_mode::NONE; + } + else if ((cmd & 0xf0) == 0xc0) + { + if (BIT(cmd, 0)) + { + logerror("%s: Read data from %04X and %s ADP\n", machine().describe_context(), + BIT(cmd, 0) ? "read" : "write", + m_adp, + (cmd & 0x0e) == 0x00 ? "increment" + : (cmd & 0x0e) == 0x02 ? "decrement" + : (cmd & 0x0e) == 0x04 ? "nonvariable" + : "invalid"); + } + else + { + logerror("%s: Write %02X to %04X and %s ADP\n", machine().describe_context(), + m_data >> 8, + m_adp, + (cmd & 0x0e) == 0x00 ? "increment" + : (cmd & 0x0e) == 0x02 ? "decrement" + : (cmd & 0x0e) == 0x04 ? "nonvariable" + : "invalid"); + + m_display_ram->write_byte(m_adp, m_data >> 8); + if ((cmd & 0x0e) == 0x00) + ++m_adp; + else if ((cmd & 0x0e) == 0x02) + --m_adp; + } + } + else if (cmd == 0xe0) + { + logerror("%s: Screen peek\n", machine().describe_context()); + } + else if (cmd == 0xe8) + { + logerror("%s: Screen copy\n", machine().describe_context()); + } + else if ((cmd & 0xf0) == 0xf0) + { + logerror("%s: %s bit %d\n", machine().describe_context(), + BIT(cmd, 3) ? "Set" : "Reset", + cmd & 0x07); + } + else + { + logerror("%s: Unknown command %02X\n", machine().describe_context(), cmd); + } +} + + +//************************************************************************** +// T6963C-BASED LCD UNITS +//************************************************************************** + +//------------------------------------------------- +// lm24014h_device - constructor +//------------------------------------------------- + +lm24014h_device::lm24014h_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, LM24014H, tag, owner, clock) + , m_lcdc(*this, "lcdc") +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void lm24014h_device::device_start() +{ +} + + +//------------------------------------------------- +// ram_map - address map for display memory +//------------------------------------------------- + +void lm24014h_device::ram_map(address_map &map) +{ + map.global_mask(0x1fff); + map(0x0000, 0x1fff).ram(); // TC5564AFL-15 +} + + +//------------------------------------------------- +// device_add_mconfig - add device-specific +// machine configuration +//------------------------------------------------- + +void lm24014h_device::device_add_mconfig(machine_config &config) +{ + T6963C(config, m_lcdc, 0); // XTAL is unknown + m_lcdc->set_addrmap(0, &lm24014h_device::ram_map); +} + + +//------------------------------------------------- +// lm24014h - ROM definition +//------------------------------------------------- + +ROM_START(lm24014h) + ROM_REGION(0x400, "lcdc:cgrom", 0) + ROM_LOAD("lm24014w_0101.bin", 0x000, 0x400, CRC(ba5f0719) SHA1(4680d3ae99102369b4145604ee7c25fa83760784)) +ROM_END + + +//------------------------------------------------- +// device_rom_region - return a pointer to the +// rom region description for this device +//------------------------------------------------- + +const tiny_rom_entry *lm24014h_device::device_rom_region() const +{ + return ROM_NAME(lm24014h); +} diff --git a/src/devices/video/t6963c.h b/src/devices/video/t6963c.h new file mode 100644 index 00000000000..6eabc1bc4c0 --- /dev/null +++ b/src/devices/video/t6963c.h @@ -0,0 +1,93 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + Toshiba T6963C Dot Matrix LCD Controller + Sharp LM24014H Dot Matrix LCD Unit + +**********************************************************************/ + +#ifndef MAME_VIDEO_T6963C_H +#define MAME_VIDEO_T6963C_H 1 + +#pragma once + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> t6963c_device + +class t6963c_device : public device_t, public device_memory_interface +{ + enum class auto_mode : u8 + { + READ = 0, + WRITE = 1, + NONE = 2 + }; + +public: + // construction/destruction + t6963c_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + // CPU read/write access + u8 read(offs_t offset); + void write(offs_t offset, u8 data); + + static constexpr feature_type unemulated_features() { return feature::GRAPHICS; } + +protected: + // device-specific overrides + virtual void device_start() override; + virtual void device_reset() override; + + // device_memory_interface overrides + virtual space_config_vector memory_space_config() const override; + +private: + // internal helpers + void do_command(u8 cmd); + + // configuration and object finders + address_space_config m_display_config; + required_region_ptr<u8> m_cgrom; + address_space *m_display_ram; + + // internal state + u16 m_data; + u16 m_adp; + auto_mode m_auto_mode; +}; + +// ======================> lm24014h_device + +class lm24014h_device : public device_t +{ +public: + // construction/destruction + lm24014h_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + + // CPU read/write access + u8 read(offs_t offset) { return m_lcdc->read(offset); } + void write(offs_t offset, u8 data) { m_lcdc->write(offset, data); } + +protected: + // device-specific overrides + virtual void device_start() override; + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + +private: + // internal configuration + void ram_map(address_map &map); + + // internal LCD controller + required_device<t6963c_device> m_lcdc; +}; + +// device type declarations +DECLARE_DEVICE_TYPE(T6963C, t6963c_device) +DECLARE_DEVICE_TYPE(LM24014H, lm24014h_device) + +#endif // MAME_VIDEO_T6963C_H diff --git a/src/mame/drivers/krz2000.cpp b/src/mame/drivers/krz2000.cpp index 341ea6e2d62..6e622905596 100644 --- a/src/mame/drivers/krz2000.cpp +++ b/src/mame/drivers/krz2000.cpp @@ -26,6 +26,7 @@ #include "machine/ncr5380n.h" #include "machine/nscsi_cd.h" #include "machine/nscsi_hd.h" +#include "video/t6963c.h" #include "screen.h" #include "emupal.h" #include "softlist.h" @@ -54,26 +55,11 @@ private: required_device<address_map_bank_device> m_1m_bank; required_shared_ptr<uint16_t> m_mainram; - DECLARE_READ16_MEMBER(lcd_r); - DECLARE_WRITE16_MEMBER(lcd_w); DECLARE_WRITE16_MEMBER(ctrl_w); void k2000_palette(palette_device &palette) const; }; -// LCD controller is byte-wide, data at 0, status/control at 1. -READ16_MEMBER(k2000_state::lcd_r) -{ - return 0x0b0b; -} -WRITE16_MEMBER(k2000_state::lcd_w) -{ - if (offset == 0) - { - printf("%c", data & 0x7f); - } -} - WRITE16_MEMBER(k2000_state::ctrl_w) { data &= 0xff; @@ -98,7 +84,7 @@ void k2000_state::k2000_map(address_map &map) // word writes to 000180 region - unknown // word writes to 000240 region - unknown map(0x000000, 0x1fffff).m(m_1m_bank, FUNC(address_map_bank_device::amap16)); - map(0x700000, 0x700003).rw(FUNC(k2000_state::lcd_r), FUNC(k2000_state::lcd_w)); + map(0x700000, 0x700003).rw("lcd", FUNC(lm24014h_device::read), FUNC(lm24014h_device::write)).umask16(0x00ff); map(0x7e0000, 0x7e0001).w(FUNC(k2000_state::ctrl_w)); } @@ -117,6 +103,8 @@ void k2000_state::k2000(machine_config &config) ADDRESS_MAP_BANK(config, "bank1m").set_map(&k2000_state::bank_map_1m).set_options(ENDIANNESS_BIG, 16, 24, 0x200000); + LM24014H(config, "lcd"); + SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); } |