diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index dd34d60bfbc..4be35a2eaff 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -1210,6 +1210,18 @@ if (MACHINES["DS75161A"]~=null) then } end +--------------------------------------------------- +-- +--@src/devices/machine/ds8874.h,MACHINES["DS8874"] = true +--------------------------------------------------- + +if (MACHINES["DS8874"]~=null) then + files { + MAME_DIR .. "src/devices/machine/ds8874.cpp", + MAME_DIR .. "src/devices/machine/ds8874.h", + } +end + --------------------------------------------------- -- --@src/devices/machine/e0516.h,MACHINES["E0516"] = true diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index c12d77d42e8..9c37315a9e2 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -487,6 +487,7 @@ MACHINES["DS2401"] = true MACHINES["DS2404"] = true MACHINES["DS75160A"] = true MACHINES["DS75161A"] = true +--MACHINES["DS8874"] = true MACHINES["E0516"] = true MACHINES["E05A03"] = true MACHINES["E05A30"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index ba933d84b68..a3ce421a8c3 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -509,6 +509,7 @@ MACHINES["DS2401"] = true MACHINES["DS2404"] = true MACHINES["DS75160A"] = true MACHINES["DS75161A"] = true +MACHINES["DS8874"] = true MACHINES["E0516"] = true MACHINES["E05A03"] = true MACHINES["E05A30"] = true diff --git a/src/devices/machine/ds8874.cpp b/src/devices/machine/ds8874.cpp new file mode 100644 index 00000000000..f4d2f984e31 --- /dev/null +++ b/src/devices/machine/ds8874.cpp @@ -0,0 +1,84 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + +National Semiconductor DS8874 9-Digit Shift Input LED Driver + +It's basically a 9-bit generic shifter, outputs are active-low. +Only one output is active at a time. + +TODO: +- add 1-bit callbacks/read functions if necessary +- datasheet info is very sparse, so implementation may have errors +- low battery pin + +*/ + +#include "emu.h" +#include "machine/ds8874.h" + + +DEFINE_DEVICE_TYPE(DS8874, ds8874_device, "ds8874", "DS8874 LED Driver") + +//------------------------------------------------- +// constructor +//------------------------------------------------- + +ds8874_device::ds8874_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + device_t(mconfig, DS8874, tag, owner, clock), + m_write_output(*this) +{ } + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void ds8874_device::device_start() +{ + // resolve callbacks + m_write_output.resolve_safe(); + + // register for savestates + save_item(NAME(m_data)); + save_item(NAME(m_cp)); + save_item(NAME(m_shift)); +} + + +//------------------------------------------------- +// handlers +//------------------------------------------------- + +void ds8874_device::refresh_output() +{ + m_write_output(m_shift); +} + +WRITE_LINE_MEMBER(ds8874_device::data_w) +{ + state = (state) ? 1 : 0; + + // reset shift register at falling edge + if (!state && m_data) + { + m_shift = 0x1fe; + refresh_output(); + } + + m_data = state; +} + +WRITE_LINE_MEMBER(ds8874_device::cp_w) +{ + state = (state) ? 1 : 0; + + // clock shift register at any edge + if (state != m_cp && m_shift != 0xff) + { + m_shift = (m_shift << 1 & 0x1ff) | 1; + refresh_output(); + } + + m_cp = state; +} diff --git a/src/devices/machine/ds8874.h b/src/devices/machine/ds8874.h new file mode 100644 index 00000000000..686ed359080 --- /dev/null +++ b/src/devices/machine/ds8874.h @@ -0,0 +1,61 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + National Semiconductor DS8874 9-Digit Shift Input LED Driver + +*/ + +#ifndef MAME_MACHINE_DS8874_H +#define MAME_MACHINE_DS8874_H + +#pragma once + +// pinout reference + +/* + _______ + CP 1 |* | 14 Vcc + _DATA 2 | | 13 LOW BATT OUT + OUT 1 3 | | 12 OUT 9 + OUT 2 4 |DS8874N| 11 OUT 8 + OUT 3 5 | | 10 OUT 7 + OUT 4 6 | | 9 OUT 6 + GND 7 |_______| 8 OUT 5 + + CP = CLOCK PULSE + +*/ + + +class ds8874_device : public device_t +{ +public: + ds8874_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + + // configuration helpers + auto write_output() { return m_write_output.bind(); } // OUT pins + + DECLARE_WRITE_LINE_MEMBER(data_w); + DECLARE_WRITE_LINE_MEMBER(cp_w); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override { refresh_output(); } + +private: + void refresh_output(); + + int m_data = 0; + int m_cp = 0; + u16 m_shift = 0xff; + + // callbacks + devcb_write16 m_write_output; +}; + + +DECLARE_DEVICE_TYPE(DS8874, ds8874_device) + +#endif // MAME_MACHINE_DS8874_H diff --git a/src/mame/drivers/hh_tms1k.cpp b/src/mame/drivers/hh_tms1k.cpp index 7d24a5e37ef..89d3b1a09da 100644 --- a/src/mame/drivers/hh_tms1k.cpp +++ b/src/mame/drivers/hh_tms1k.cpp @@ -158,15 +158,17 @@ #include "emu.h" #include "includes/hh_tms1k.h" -#include "machine/tms1024.h" #include "machine/clock.h" +#include "machine/ds8874.h" #include "machine/timer.h" +#include "machine/tms1024.h" #include "sound/beep.h" #include "sound/s14001a.h" #include "sound/sn76477.h" #include "video/hlcd0515.h" #include "bus/generic/carts.h" #include "bus/generic/slot.h" + #include "softlist.h" #include "screen.h" #include "speaker.h" @@ -2779,9 +2781,13 @@ class cnfball_state : public hh_tms1k_state { public: cnfball_state(const machine_config &mconfig, device_type type, const char *tag) : - hh_tms1k_state(mconfig, type, tag) + hh_tms1k_state(mconfig, type, tag), + m_ds8874(*this, "ds8874") { } + required_device m_ds8874; + void ds8874_output_w(u16 data); + void update_display(); void write_r(u16 data); void write_o(u16 data); @@ -2793,7 +2799,13 @@ public: void cnfball_state::update_display() { - m_display->matrix(m_grid, m_o | (m_r << 6 & 0x700)); + m_display->matrix(~m_grid, m_o | (m_r << 6 & 0x700)); +} + +void cnfball_state::ds8874_output_w(u16 data) +{ + m_grid = data; + update_display(); } void cnfball_state::write_r(u16 data) @@ -2805,14 +2817,10 @@ void cnfball_state::write_r(u16 data) // R9,R10: input mux m_inp_mux = data >> 9 & 3; - // R0: DS8874N CP: clock pulse edge-triggered - // note: DS8874N CP goes back to K8 too, game relies on it - if ((data ^ m_r) & 1) - m_grid = m_grid << 1 & 0x1ff; - - // R1: DS8874N _DATA: reset shift register - if (~data & 2) - m_grid = 1; + // R0: DS8874N CP (note: it goes back to K8 too, game relies on it) + // R1: DS8874N _DATA + m_ds8874->cp_w(BIT(data, 0)); + m_ds8874->data_w(BIT(data, 1)); // R2-R4: led data m_r = data; @@ -2863,7 +2871,8 @@ void cnfball_state::cnfball(machine_config &config) m_maincpu->o().set(FUNC(cnfball_state::write_o)); /* video hardware */ - PWM_DISPLAY(config, m_display).set_size(10, 8+3); + DS8874(config, m_ds8874).write_output().set(FUNC(cnfball_state::ds8874_output_w)); + PWM_DISPLAY(config, m_display).set_size(9, 8+3); m_display->set_segmask(0xc3, 0x7f); m_display->set_segmask(0x38, 0xff); // only the middle 3 7segs have DP m_display->set_bri_levels(0.01, 0.1); // player led is brighter