From 323914f25b0e8ae26fa0d98c4fe63e01eb184c0c Mon Sep 17 00:00:00 2001 From: hap Date: Sun, 8 Dec 2019 19:47:16 +0100 Subject: added Hitachi HD61603 LCD Driver (nw) --- scripts/src/video.lua | 12 +++++ scripts/target/mame/arcade.lua | 1 + scripts/target/mame/mess.lua | 1 + src/devices/video/hd61603.cpp | 101 +++++++++++++++++++++++++++++++++++++ src/devices/video/hd61603.h | 67 ++++++++++++++++++++++++ src/mame/drivers/cxg_dominator.cpp | 2 +- src/mame/drivers/cxg_sphinx40.cpp | 40 +++++++++++---- src/mame/layout/cxg_dominator.lay | 2 +- 8 files changed, 214 insertions(+), 12 deletions(-) create mode 100644 src/devices/video/hd61603.cpp create mode 100644 src/devices/video/hd61603.h diff --git a/scripts/src/video.lua b/scripts/src/video.lua index 2352d32e850..a1f5221b58a 100644 --- a/scripts/src/video.lua +++ b/scripts/src/video.lua @@ -351,6 +351,18 @@ if (VIDEOS["HD44780"]~=null) then } end +-------------------------------------------------- +-- +--@src/devices/video/hd61603.h,VIDEOS["HD61603"] = true +-------------------------------------------------- + +if (VIDEOS["HD61603"]~=null) then + files { + MAME_DIR .. "src/devices/video/hd61603.cpp", + MAME_DIR .. "src/devices/video/hd61603.h", + } +end + -------------------------------------------------- -- --@src/devices/video/hd61830.h,VIDEOS["HD61830"] = true diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 9c898354f47..727ca826da6 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -310,6 +310,7 @@ VIDEOS["FIXFREQ"] = true --VIDEOS["HD44102"] = true --VIDEOS["HD44352"] = true VIDEOS["HD44780"] = true +--VIDEOS["HD61603"] = true VIDEOS["HD61830"] = true VIDEOS["HD63484"] = true --VIDEOS["HD66421"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 3c3a07bf176..15887029603 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -330,6 +330,7 @@ VIDEOS["NT7534"] = true VIDEOS["HD44102"] = true VIDEOS["HD44352"] = true VIDEOS["HD44780"] = true +VIDEOS["HD61603"] = true VIDEOS["HD61830"] = true --VIDEOS["HD63484"] = true VIDEOS["HD66421"] = true diff --git a/src/devices/video/hd61603.cpp b/src/devices/video/hd61603.cpp new file mode 100644 index 00000000000..42fd0cbe8c1 --- /dev/null +++ b/src/devices/video/hd61603.cpp @@ -0,0 +1,101 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + +Hitachi HD61603 LCD Driver +64 segment outputs, no duty cycle + +TODO: +- OSC pin (input is resistor) +- SB pin, halts internal clock +- SYNC pin for chip cascading +- RE pin, resets count +- READY pin + +*/ + +#include "emu.h" +#include "video/hd61603.h" + + +DEFINE_DEVICE_TYPE(HD61603, hd61603_device, "hd61603", "Hitachi HD61603 LCD Driver") + +//------------------------------------------------- +// constructor +//------------------------------------------------- + +hd61603_device::hd61603_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + device_t(mconfig, HD61603, tag, owner, clock), + m_write_segs(*this) +{ } + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void hd61603_device::device_start() +{ + // resolve callbacks + m_write_segs.resolve_safe(); + + // register for savestates + save_item(NAME(m_blank)); + save_item(NAME(m_count)); + save_item(NAME(m_data)); + save_item(NAME(m_ram)); +} + + +//------------------------------------------------- +// handlers +//------------------------------------------------- + +void hd61603_device::refresh_output() +{ + m_write_segs(0, m_blank ? 0 : m_ram); +} + +void hd61603_device::data_w(u8 data) +{ + // 1-byte nop command + if (m_count == 0 && (data & 0xc) == 0xc) + return; + + // each command is 4 writes + m_data = (m_data << 4) | (data & 0xf); + m_count = (m_count + 1) & 3; + + if (m_count == 0) + { + switch (m_data >> 14 & 3) + { + // write byte + case 0: + { + u8 shift = (m_data >> 8 & 7) * 8; + u8 digit = bitswap<8>(m_data & 0xff, 0,1,2,3,4,5,6,7); + m_ram = (m_ram & ~(u64(0xff) << shift)) | u64(digit) << shift; + break; + } + + // write bit + case 1: + { + u64 mask = u64(1) << (m_data & 0x3f); + m_ram = (m_ram & ~mask) | ((m_data & 0x2000) ? mask : 0); + break; + } + + // set mode + case 2: + m_blank = BIT(m_data, 2); + break; + + default: + break; + } + + refresh_output(); + } +} diff --git a/src/devices/video/hd61603.h b/src/devices/video/hd61603.h new file mode 100644 index 00000000000..81bfcfa7913 --- /dev/null +++ b/src/devices/video/hd61603.h @@ -0,0 +1,67 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + Hitachi HD61603 LCD Driver + +*/ + +#ifndef MAME_VIDEO_HD61603_H +#define MAME_VIDEO_HD61603_H + +#pragma once + +/* + +quick pinout reference (80-pin QFP) + +pin desc +------------------------------ +1 = VDD +2 = READY +3 = _CS +4 = _WE +5 = _RE +6 = SB +7-10 = D3-D0 (data_w) +11 = VSS +12 = V3 +13 = COM0 +14-77 = SEG63-SEG0: LCD segment outputs +78 = SYNC +79,80 = OSC2,OSC1 + +*/ + + +class hd61603_device : public device_t +{ +public: + hd61603_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + // configuration helpers + auto write_segs() { return m_write_segs.bind(); } + + void data_w(u8 data); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_post_load() override { refresh_output(); } + +private: + void refresh_output(); + + u8 m_count = 0; + u16 m_data = 0; + u64 m_ram = 0; + int m_blank = 0; + + // callbacks + devcb_write64 m_write_segs; +}; + + +DECLARE_DEVICE_TYPE(HD61603, hd61603_device) + +#endif // MAME_VIDEO_HD61603_H diff --git a/src/mame/drivers/cxg_dominator.cpp b/src/mame/drivers/cxg_dominator.cpp index b8bb01958c6..bab30b0cc2d 100644 --- a/src/mame/drivers/cxg_dominator.cpp +++ b/src/mame/drivers/cxg_dominator.cpp @@ -89,7 +89,7 @@ void dominator_state::machine_start() I/O ******************************************************************************/ -// LCD +// LC7582 LCD WRITE64_MEMBER(dominator_state::lcd_s_w) { diff --git a/src/mame/drivers/cxg_sphinx40.cpp b/src/mame/drivers/cxg_sphinx40.cpp index 1875bc4ee59..abad5d898a4 100644 --- a/src/mame/drivers/cxg_sphinx40.cpp +++ b/src/mame/drivers/cxg_sphinx40.cpp @@ -19,7 +19,6 @@ TODO: - unmapped read from 0x200000, looks like expansion ROM - verify XTAL and irq source/frequency - identify buttons -- lcd Hardware notes: @@ -52,6 +51,7 @@ LCD module #include "sound/dac.h" #include "sound/volt_reg.h" #include "video/pwm.h" +#include "video/hd61603.h" #include "speaker.h" // internal artwork @@ -67,10 +67,11 @@ public: driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), m_pia(*this, "pia"), + m_lcd(*this, "lcd"), m_display(*this, "display"), m_board(*this, "board"), - m_dac(*this, "dac"), - m_inputs(*this, "IN.%u", 0) + m_inputs(*this, "IN.%u", 0), + m_digits(*this, "digit%u", 0U) { } // machine drivers @@ -83,25 +84,28 @@ private: // devices/pointers required_device m_maincpu; required_device m_pia; + required_device m_lcd; required_device m_display; required_device m_board; - required_device m_dac; required_ioport_array<4> m_inputs; + output_finder<8> m_digits; // address maps void main_map(address_map &map); void nvram_map(address_map &map); // I/O handlers - DECLARE_READ8_MEMBER(input_r); - DECLARE_WRITE8_MEMBER(input_w); - DECLARE_WRITE8_MEMBER(lcd_w); + DECLARE_WRITE64_MEMBER(lcd_seg_w); void update_display(); DECLARE_WRITE8_MEMBER(cb_mux_w); DECLARE_WRITE8_MEMBER(cb_leds_w); DECLARE_READ8_MEMBER(cb_r); + DECLARE_READ8_MEMBER(input_r); + DECLARE_WRITE8_MEMBER(input_w); + DECLARE_WRITE8_MEMBER(lcd_w); + u8 m_cb_mux = 0; u8 m_led_data = 0; u8 m_inp_mux = 0; @@ -109,6 +113,8 @@ private: void sphinx40_state::machine_start() { + m_digits.resolve(); + // register for savestates save_item(NAME(m_cb_mux)); save_item(NAME(m_led_data)); @@ -121,6 +127,18 @@ void sphinx40_state::machine_start() I/O ******************************************************************************/ +// HD61603 LCD + +WRITE64_MEMBER(sphinx40_state::lcd_seg_w) +{ + for (int i = 0; i < 8; i++) + { + m_digits[i] = data & 0xff; + data >>= 8; + } +} + + // 6821 PIA void sphinx40_state::update_display() @@ -178,7 +196,7 @@ READ8_MEMBER(sphinx40_state::input_r) WRITE8_MEMBER(sphinx40_state::lcd_w) { // d0-d3: HD61603 data - //printf("%X ",data); + m_lcd->data_w(data & 0xf); } @@ -271,7 +289,7 @@ void sphinx40_state::sphinx40(machine_config &config) PIA6821(config, m_pia, 0); m_pia->writepa_handler().set(FUNC(sphinx40_state::cb_mux_w)); m_pia->writepb_handler().set(FUNC(sphinx40_state::cb_leds_w)); - m_pia->cb2_handler().set(m_dac, FUNC(dac_bit_interface::write)); + m_pia->cb2_handler().set("dac", FUNC(dac_bit_interface::write)); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); ADDRESS_MAP_BANK(config, "nvram_map").set_map(&sphinx40_state::nvram_map).set_options(ENDIANNESS_BIG, 8, 11); @@ -281,13 +299,15 @@ void sphinx40_state::sphinx40(machine_config &config) m_board->set_delay(attotime::from_msec(150)); /* video hardware */ + HD61603(config, m_lcd, 0); + m_lcd->write_segs().set(FUNC(sphinx40_state::lcd_seg_w)); PWM_DISPLAY(config, m_display).set_size(8, 8); config.set_default_layout(layout_cxg_sphinx40); /* sound hardware */ SPEAKER(config, "speaker").front_center(); - DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25); + DAC_1BIT(config, "dac").add_route(ALL_OUTPUTS, "speaker", 0.25); VOLTAGE_REGULATOR(config, "vref").add_route(0, "dac", 1.0, DAC_VREF_POS_INPUT); } diff --git a/src/mame/layout/cxg_dominator.lay b/src/mame/layout/cxg_dominator.lay index 3a147e7e901..a00c1e21fea 100644 --- a/src/mame/layout/cxg_dominator.lay +++ b/src/mame/layout/cxg_dominator.lay @@ -537,7 +537,7 @@ - + -- cgit v1.2.3