diff --git a/scripts/src/video.lua b/scripts/src/video.lua index e1c5160b439..2352d32e850 100644 --- a/scripts/src/video.lua +++ b/scripts/src/video.lua @@ -543,6 +543,18 @@ if (VIDEOS["IMS_CVC"]~=null) then } end +-------------------------------------------------- +-- +--@src/devices/video/lc7582.h,VIDEOS["LC7582"] = true +-------------------------------------------------- + +if (VIDEOS["LC7582"]~=null) then + files { + MAME_DIR .. "src/devices/video/lc7582.cpp", + MAME_DIR .. "src/devices/video/lc7582.h", + } +end + -------------------------------------------------- -- --@src/devices/video/m50458.h,VIDEOS["M50458"] = true diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 2cb0b2950a0..4d2d0dd01fb 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -324,6 +324,7 @@ VIDEOS["I4100"] = true --VIDEOS["I8244"] = true VIDEOS["I8275"] = true VIDEOS["JANGOU_BLITTER"] = true +--VIDEOS["LC7582"] = true VIDEOS["M50458"] = true VIDEOS["MB90082"] = true VIDEOS["MB_VCU"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 79b3f22bf68..2617c5b555a 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -346,6 +346,7 @@ VIDEOS["I8244"] = true VIDEOS["I82730"] = true VIDEOS["I8275"] = true VIDEOS["IMS_CVC"] = true +VIDEOS["LC7582"] = true --VIDEOS["M50458"] = true --VIDEOS["MB90082"] = true --VIDEOS["MB_VCU"] = true diff --git a/src/devices/video/lc7582.cpp b/src/devices/video/lc7582.cpp new file mode 100644 index 00000000000..d062486e827 --- /dev/null +++ b/src/devices/video/lc7582.cpp @@ -0,0 +1,100 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + +Sanyo LC7582 LCD Driver + +53 outputs (static), or 106 outputs (1/2 duty) + +TODO: +- OSC pin (input is R/C) +- AD/DSP function + +*/ + +#include "emu.h" +#include "video/lc7582.h" + + +DEFINE_DEVICE_TYPE(LC7582, lc7582_device, "lc7582", "Sanyo LC7582 LCD Driver") + +//------------------------------------------------- +// constructor +//------------------------------------------------- + +lc7582_device::lc7582_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : + device_t(mconfig, type, tag, owner, clock), + m_latch{0, 0}, + m_write_segs(*this) +{ } + +lc7582_device::lc7582_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + lc7582_device(mconfig, LC7582, tag, owner, clock) +{ } + + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void lc7582_device::device_start() +{ + // resolve callbacks + m_write_segs.resolve_safe(); + + // register for savestates + save_item(NAME(m_data)); + save_item(NAME(m_ce)); + save_item(NAME(m_clk)); + save_item(NAME(m_blank)); + save_item(NAME(m_duty)); + save_item(NAME(m_addsp)); + save_item(NAME(m_shift)); + save_item(NAME(m_latch)); +} + + +//------------------------------------------------- +// handlers +//------------------------------------------------- + +void lc7582_device::refresh_output() +{ + m_write_segs(0, m_blank ? 0 : m_latch[0]); + m_write_segs(1, (m_blank || !m_duty) ? 0 : m_latch[1]); +} + +WRITE_LINE_MEMBER(lc7582_device::clk_w) +{ + state = (state) ? 1 : 0; + + // clock shift register + if (state && !m_clk) + m_shift = m_shift >> 1 | u64(m_data) << 55; + + m_clk = state; +} + +WRITE_LINE_MEMBER(lc7582_device::ce_w) +{ + state = (state) ? 1 : 0; + + // latch at falling edge + if (!state && m_ce) + { + // d53: DP (drive mode select, aka duty) + // d54: DQ (AD/DSP function) + // d55: commons + if (!BIT(m_shift, 55)) + { + m_duty = BIT(m_shift, 53); + m_addsp = BIT(m_shift, 54); + } + + m_latch[BIT(m_shift, 55)] = m_shift & u64(0x1f'ffff'ffff'ffff); + refresh_output(); + } + + m_ce = state; +} diff --git a/src/devices/video/lc7582.h b/src/devices/video/lc7582.h new file mode 100644 index 00000000000..7aea77814ac --- /dev/null +++ b/src/devices/video/lc7582.h @@ -0,0 +1,71 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + Sanyo LC7582 LCD Driver + +*/ + +#ifndef MAME_VIDEO_LC7582_H +#define MAME_VIDEO_LC7582_H + +#pragma once + +/* + +quick pinout reference (64-pin QFP) + +1-54: S1-S53 segment outputs, pin 24 N/C, pins 45-54 also used with AD/DSP +55: OSC +56: Vdd +57: _INH +58: Vlcd +59: Vss +60: CE \ +61: CLK | serial input +62: DATA / +63,64: COM1/COM2 outputs + +*/ + + +class lc7582_device : public device_t +{ +public: + lc7582_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + // configuration helpers + auto write_segs() { return m_write_segs.bind(); } // S pins, COM1/COM2 in offset + + DECLARE_WRITE_LINE_MEMBER(data_w) { m_data = (state) ? 1 : 0; } + DECLARE_WRITE_LINE_MEMBER(clk_w); + DECLARE_WRITE_LINE_MEMBER(ce_w); + DECLARE_WRITE_LINE_MEMBER(inh_w) { m_blank = bool(state); refresh_output(); } + +protected: + lc7582_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + + // device-level overrides + virtual void device_start() override; + virtual void device_post_load() override { refresh_output(); } + + void refresh_output(); + + int m_data = 0; + int m_ce = 0; + int m_clk = 0; + bool m_blank = false; + + int m_duty = 0; + int m_addsp = 0; + u64 m_shift = 0; + u64 m_latch[2]; + + // callbacks + devcb_write64 m_write_segs; +}; + + +DECLARE_DEVICE_TYPE(LC7582, lc7582_device) + +#endif // MAME_VIDEO_LC7582_H diff --git a/src/mame/drivers/cxg_dominator.cpp b/src/mame/drivers/cxg_dominator.cpp index 264095a060b..ba27bbf2d96 100644 --- a/src/mame/drivers/cxg_dominator.cpp +++ b/src/mame/drivers/cxg_dominator.cpp @@ -19,7 +19,6 @@ It's also used in the newer Mephisto Modena. TODO: - artwork - buttons -- lcd ******************************************************************************/ @@ -30,7 +29,7 @@ TODO: #include "sound/dac.h" #include "sound/volt_reg.h" #include "video/pwm.h" -//#include "video/lc7582.h" +#include "video/lc7582.h" #include "speaker.h" // internal artwork @@ -45,10 +44,13 @@ public: dominator_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), + 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), + m_dp(*this, "dp%u", 0U) { } // machine drivers @@ -60,15 +62,19 @@ protected: private: // devices/pointers required_device m_maincpu; + required_device m_lcd; required_device m_display; required_device m_board; required_device m_dac; required_ioport_array<2> m_inputs; + output_finder<8> m_digits; + output_finder<2> m_dp; // address maps void main_map(address_map &map); // I/O handlers + DECLARE_WRITE64_MEMBER(lcd_s_w); DECLARE_WRITE8_MEMBER(control_w); DECLARE_WRITE8_MEMBER(leds_w); DECLARE_READ8_MEMBER(input_r); @@ -76,6 +82,8 @@ private: void dominator_state::machine_start() { + m_digits.resolve(); + m_dp.resolve(); } @@ -84,11 +92,39 @@ void dominator_state::machine_start() I/O ******************************************************************************/ +// LCD + +WRITE64_MEMBER(dominator_state::lcd_s_w) +{ + u8 d[4]; + + // 1st digit: S1-S9, unused middle vertical segments + // 2nd digit: S10-S18, unused bottom-right diagonal segment + // 3rd digit: S21-S27 + // 4th digit: S28-S34 + d[0] = bitswap<9>(data >> 0 & 0x1ff, 2,7,5,4,3,1,0,8,6) & 0x7f; + d[1] = bitswap<9>(data >> 9 & 0x1ff, 7,6,4,2,0,8,5,3,1) & 0x7f; + d[2] = bitswap<7>(data >> 20 & 0x7f, 3,5,1,0,2,6,4); + d[3] = bitswap<7>(data >> 27 & 0x7f, 4,2,0,6,5,3,1); + + for (int i = 0; i < 4; i++) + m_digits[offset * 4 + i] = d[i]; + + // colon: S17 (part of 2nd digit) + m_dp[offset] = BIT(data, 16); +} + + +// TTL + WRITE8_MEMBER(dominator_state::control_w) { // d0: LC7582 DATA // d1: LC7582 CLK // d2: LC7582 CE + m_lcd->data_w(BIT(data, 0)); + m_lcd->clk_w(BIT(data, 1)); + m_lcd->ce_w(BIT(data, 2)); // d3: speaker out m_dac->write(BIT(data, 3)); @@ -170,7 +206,7 @@ void dominator_state::dominator(machine_config &config) R65C02(config, m_maincpu, 4_MHz_XTAL); m_maincpu->set_addrmap(AS_PROGRAM, &dominator_state::main_map); - const attotime irq_period = attotime::from_hz(4_MHz_XTAL / 0x4000); // from 4020 + const attotime irq_period = attotime::from_hz(4_MHz_XTAL / 0x2000); // from 4020 m_maincpu->set_periodic_int(FUNC(dominator_state::nmi_line_pulse), irq_period); SENSORBOARD(config, m_board).set_type(sensorboard_device::BUTTONS); @@ -178,6 +214,9 @@ void dominator_state::dominator(machine_config &config) m_board->set_delay(attotime::from_msec(150)); /* video hardware */ + LC7582(config, m_lcd, 0); + m_lcd->write_segs().set(FUNC(dominator_state::lcd_s_w)); + PWM_DISPLAY(config, m_display).set_size(10, 8); //config.set_default_layout(layout_cxg_dominator); diff --git a/src/mame/drivers/hh_tms1k.cpp b/src/mame/drivers/hh_tms1k.cpp index 8abea869492..0463f4ac7cb 100644 --- a/src/mame/drivers/hh_tms1k.cpp +++ b/src/mame/drivers/hh_tms1k.cpp @@ -54,6 +54,7 @@ @MP1218 TMS1100 1980, Entex Basketball 2 (6010) @MP1219 TMS1100 1980, U.S. Games Super Sports-4 @MP1221 TMS1100 1980, Entex Raise The Devil (6011) + *MP1231 TMS1100 1983, Tandy 3-in-1 Sports Arena (model 60-2178) *MP1296 TMS1100? 1982, Entex Black Knight @MP1312 TMS1100 1983, Gakken FX-Micom R-165/Tandy Radio Shack Science Fair Microcomputer Trainer *MP1359 TMS1100? 1985, Capsela CRC2000