From 804fc3d1884ec450a47f878e1639ef511cfcd4cc Mon Sep 17 00:00:00 2001 From: hap Date: Sat, 29 Jun 2019 20:44:15 +0200 Subject: gamemachine, boris: use pwm_display (nw) --- src/devices/video/pwm.h | 1 + src/mame/drivers/aci_boris.cpp | 58 +++++++++--------------------- src/mame/drivers/aci_borisdpl.cpp | 53 ++++++++++++--------------- src/mame/drivers/aci_ggm.cpp | 19 +++++----- src/mame/drivers/gamemachine.cpp | 75 ++++++++++++++------------------------- src/mame/drivers/novag_mk1.cpp | 5 +-- src/mame/layout/aci_borisdpl.lay | 32 ++++++++--------- 7 files changed, 94 insertions(+), 149 deletions(-) diff --git a/src/devices/video/pwm.h b/src/devices/video/pwm.h index 6ef59e1f0db..dca3d76a29a 100644 --- a/src/devices/video/pwm.h +++ b/src/devices/video/pwm.h @@ -38,6 +38,7 @@ public: void matrix_partial(u8 start, u8 height, u64 rowsel, u64 rowdata, bool upd = true); void matrix(u64 rowsel, u64 rowdata, bool upd = true) { matrix_partial(0, m_height, rowsel, rowdata, upd); } void update(); // apply changes to m_rowdata + void clear() { matrix(0, 0); } // directly handle individual element (does not affect m_rowsel), y = row num, x = row bit int read_element(u8 y, u8 x) { return BIT(m_rowdata[y], x); } diff --git a/src/mame/drivers/aci_boris.cpp b/src/mame/drivers/aci_boris.cpp index 0165a7a4382..7d87bd3efd2 100644 --- a/src/mame/drivers/aci_boris.cpp +++ b/src/mame/drivers/aci_boris.cpp @@ -5,6 +5,7 @@ Applied Concepts Boris (electronic chess computer) +Hardware notes: - MK3850N-3 CPU @ 2 MHz from XTAL, MK3853N memory interface - 256 bytes RAM(2*2112), 2*AMI 2KB ROM (2nd ROM only half used) - 8-digit 16seg led panel @@ -23,7 +24,7 @@ ROM labeled 007-7027-00. #include "emu.h" #include "cpu/f8/f8.h" #include "machine/f3853.h" -#include "machine/timer.h" +#include "video/pwm.h" // internal artwork #include "aci_boris.lh" // clickable @@ -37,9 +38,8 @@ public: boris_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), - m_inputs(*this, "IN.%u", 0), - m_delay_display(*this, "delay_display_%u", 0), - m_out_digit(*this, "digit%u", 0U) + m_display(*this, "display"), + m_inputs(*this, "IN.%u", 0) { } void boris(machine_config &config); @@ -53,31 +53,25 @@ protected: private: // devices/pointers required_device m_maincpu; + required_device m_display; required_ioport_array<4> m_inputs; - required_device_array m_delay_display; - output_finder<8> m_out_digit; void main_map(address_map &map); void main_io(address_map &map); void update_reset(ioport_value state); - TIMER_DEVICE_CALLBACK_MEMBER(delay_display); + void update_display(); DECLARE_WRITE8_MEMBER(mux_w); DECLARE_WRITE8_MEMBER(digit_w); DECLARE_READ8_MEMBER(input_r); - void update_4042(); - u8 m_io[2]; // MK3850 I/O ports u8 m_4042; // 4042 latch output }; void boris_state::machine_start() { - // resolve handlers - m_out_digit.resolve(); - // zerofill memset(m_io, 0, sizeof(m_io)); m_4042 = 0; @@ -99,10 +93,7 @@ void boris_state::update_reset(ioport_value state) // clear display if (state) - { - for (int i = 0; i < 8; i++) - m_delay_display[i]->adjust(attotime::zero, i); - } + m_display->clear(); } @@ -113,39 +104,24 @@ void boris_state::update_reset(ioport_value state) // MK3850 ports/TTL -TIMER_DEVICE_CALLBACK_MEMBER(boris_state::delay_display) -{ - // 16 segments via port 1 and 4042 output (latched port 1) - u16 mask = (param & 8) ? 0xffff : 0; - m_out_digit[param & 7] = ~(m_4042 << 8 | m_io[1]) & mask; -} - -void boris_state::update_4042() +void boris_state::update_display() { // port 1 is latched as long as 4042 clock is low // (yes low, this is actually (~~m_io[0] & 8) since output ports are inverted) if (m_io[0] & 8) m_4042 = bitswap<8>(m_io[1],4,2,0,6,5,1,3,7); + + // 16 segments via port 1 and 4042 output (latched port 1) + u16 seg_data = ~(m_4042 << 8 | m_io[1]); + m_display->matrix(1 << (~m_io[0] & 7), seg_data); } WRITE8_MEMBER(boris_state::mux_w) { // IO00-IO02: 4028 A-C to digit/input mux (4028 D to GND) - u8 prev = ~m_io[0] & 7; - u8 sel = ~data & 7; - if (sel != prev) - { - // digits are strobed, so on falling edge, delay them going off to prevent flicker or stuck display - m_delay_display[prev]->adjust(attotime::from_msec(50), prev); - - // need a short delay on rising edge too, while boris sets up digit segments - // (it writes port 1, increments digit, latches port 1, writes port 1 again) - m_delay_display[sel]->adjust(attotime::from_usec(50), sel | 8); - } - // IO03: clock 4042 m_io[0] = data; - update_4042(); + update_display(); } READ8_MEMBER(boris_state::input_r) @@ -163,7 +139,7 @@ WRITE8_MEMBER(boris_state::digit_w) { // IO10-IO17: digit segments m_io[1] = data; - update_4042(); + update_display(); } @@ -239,9 +215,9 @@ void boris_state::boris(machine_config &config) smi.int_req_callback().set_inputline("maincpu", F8_INPUT_LINE_INT_REQ); /* video hardware */ - for (int i = 0; i < 8; i++) - TIMER(config, m_delay_display[i]).configure_generic(FUNC(boris_state::delay_display)); - + PWM_DISPLAY(config, m_display).set_size(8, 16); + m_display->set_segmask(0xff, 0xffff); + m_display->set_bri_levels(0.05); config.set_default_layout(layout_aci_boris); } diff --git a/src/mame/drivers/aci_borisdpl.cpp b/src/mame/drivers/aci_borisdpl.cpp index d54104c1097..f683ef09bf1 100644 --- a/src/mame/drivers/aci_borisdpl.cpp +++ b/src/mame/drivers/aci_borisdpl.cpp @@ -5,6 +5,7 @@ Applied Concepts Boris Diplomat +Hardware notes: - F3870 MCU (Motorola SC80265P or Fairchild SL90259) - 256 bytes RAM(2*2112-1) - 8-digit 7seg led panel @@ -19,7 +20,7 @@ as SL90259. #include "emu.h" #include "cpu/f8/f8.h" #include "machine/f3853.h" -#include "machine/timer.h" +#include "video/pwm.h" // internal artwork #include "aci_borisdpl.lh" // clickable @@ -33,9 +34,8 @@ public: borisdpl_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), - m_keypad(*this, "LINE%u", 1U), - m_delay_display(*this, "delay_display_%u", 0), - m_out_digit(*this, "digit%u", 0U) + m_display(*this, "display"), + m_inputs(*this, "IN.%u", 0) { } void borisdpl(machine_config &config); @@ -49,15 +49,13 @@ protected: private: // devices/pointers required_device m_maincpu; - required_ioport_array<4> m_keypad; - required_device_array m_delay_display; - output_finder<8> m_out_digit; + required_device m_display; + required_ioport_array<4> m_inputs; void main_map(address_map &map); void main_io(address_map &map); - TIMER_DEVICE_CALLBACK_MEMBER(delay_display); - + void update_display(); DECLARE_WRITE8_MEMBER(digit_w); DECLARE_READ8_MEMBER(input_r); DECLARE_WRITE8_MEMBER(matrix_w); @@ -71,22 +69,22 @@ private: std::unique_ptr m_ram; u8 m_ram_address; u8 m_matrix; + u8 m_digit_data; }; void borisdpl_state::machine_start() { - // resolve handlers - m_out_digit.resolve(); - // zerofill m_ram = make_unique_clear(0x100); m_ram_address = 0; m_matrix = 0; + m_digit_data = 0; // register for savestates save_pointer(NAME(m_ram), 0x100); save_item(NAME(m_ram_address)); save_item(NAME(m_matrix)); + save_item(NAME(m_digit_data)); } @@ -97,27 +95,23 @@ void borisdpl_state::machine_start() // F3870 ports -TIMER_DEVICE_CALLBACK_MEMBER(borisdpl_state::delay_display) +void borisdpl_state::update_display() { - // clear digits if inactive - if (param != (m_matrix & 7)) - m_out_digit[param] = 0; + m_display->matrix(1 << (m_matrix & 7), m_digit_data); } WRITE8_MEMBER(borisdpl_state::digit_w) { - // digit segments, update display here - m_out_digit[m_matrix & 7] = ~data & 0x7f; + // digit segments + m_digit_data = ~data & 0x7f; + update_display(); } WRITE8_MEMBER(borisdpl_state::matrix_w) { // d0-d2: MC14028B to input/digit select - // digits are strobed, so on falling edge, delay them going off to prevent flicker or stuck display - if ((data & 7) != (m_matrix & 7)) - m_delay_display[m_matrix & 7]->adjust(attotime::from_msec(20), m_matrix & 7); - m_matrix = data; + update_display(); } READ8_MEMBER(borisdpl_state::input_r) @@ -125,7 +119,7 @@ READ8_MEMBER(borisdpl_state::input_r) // d4-d7: multiplexed inputs (only one lane can be selected at the same time) u8 data = m_matrix; if ((m_matrix & 7) < 4) - data |= m_keypad[m_matrix & 3]->read() << 4; + data |= m_inputs[m_matrix & 3]->read() << 4; return data; } @@ -156,25 +150,25 @@ void borisdpl_state::main_io(address_map &map) ******************************************************************************/ static INPUT_PORTS_START( borisdpl ) - PORT_START("LINE1") + PORT_START("IN.0") PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0") PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_SPACE) PORT_CODE(KEYCODE_MINUS) PORT_NAME("-") PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("B/W") // black/white PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter") - PORT_START("LINE2") + PORT_START("IN.1") PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_A) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("A.1 / Pawn") PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_B) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("B.2 / Knight") PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_C) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("C.3 / Bishop") PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_K) PORT_NAME("Rank") - PORT_START("LINE3") + PORT_START("IN.2") PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_D) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("D.4 / Rook") PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("E.5 / Queen") PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("F.6 / King") PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Time") - PORT_START("LINE4") + PORT_START("IN.3") PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_G) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("G.7") PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_H) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("H.8") PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9 / Set") @@ -207,9 +201,8 @@ void borisdpl_state::borisdpl(machine_config &config) psu.write_b().set(FUNC(borisdpl_state::ram_address_w)); /* video hardware */ - for (int i = 0; i < 8; i++) - TIMER(config, m_delay_display[i]).configure_generic(FUNC(borisdpl_state::delay_display)); - + PWM_DISPLAY(config, m_display).set_size(8, 7); + m_display->set_segmask(0xff, 0x7f); config.set_default_layout(layout_aci_borisdpl); } diff --git a/src/mame/drivers/aci_ggm.cpp b/src/mame/drivers/aci_ggm.cpp index 26152f0d7f8..f210b60c5ae 100644 --- a/src/mame/drivers/aci_ggm.cpp +++ b/src/mame/drivers/aci_ggm.cpp @@ -13,6 +13,8 @@ TODO: - verify cartridge pinout, right now assume A0-A14 (max known cart size is 24KB). Boris/Sargon cartridge is A0-A11 and 2 CS lines. - auto-switch keypad overlays? no need for it yet +- (probably won't) add chesspieces to artwork? this machine supports more board + games than just chess: checkers, reversi, and even a blackjack game ******************************************************************************* @@ -103,7 +105,7 @@ private: void update_display(); TIMER_DEVICE_CALLBACK_MEMBER(ca1_off) { m_via->write_ca1(0); } - u8 m_digit_select; + u8 m_inp_mux; u16 m_digit_data; u8 m_shift_data; u8 m_shift_clock; @@ -123,13 +125,13 @@ private: void ggm_state::machine_start() { // zerofill - m_digit_select = 0; + m_inp_mux = 0; m_digit_data = 0; m_shift_data = 0; m_shift_clock = 0; // register for savestates - save_item(NAME(m_digit_select)); + save_item(NAME(m_inp_mux)); save_item(NAME(m_digit_data)); save_item(NAME(m_shift_data)); save_item(NAME(m_shift_clock)); @@ -155,10 +157,7 @@ void ggm_state::update_reset(ioport_value state) if (state) { m_via->reset(); - - // clear display - m_digit_select = 0; - update_display(); + m_display->clear(); } } @@ -192,7 +191,7 @@ READ8_MEMBER(ggm_state::cartridge_r) void ggm_state::update_display() { u16 data = bitswap<16>(m_digit_data,15,7,2,11,10,3,1,9,6,14,12,5,0,4,13,8); - m_display->matrix(m_digit_select, data); + m_display->matrix(m_inp_mux, data); } WRITE_LINE_MEMBER(ggm_state::shift_clock_w) @@ -215,7 +214,7 @@ WRITE_LINE_MEMBER(ggm_state::shift_data_w) WRITE8_MEMBER(ggm_state::select_w) { // input mux, digit select - m_digit_select = data; + m_inp_mux = data; update_display(); } @@ -233,7 +232,7 @@ READ8_MEMBER(ggm_state::input_r) // PB1-PB5: multiplexed inputs for (int i = 0; i < 4; i++) - if (BIT(m_digit_select, i)) + if (BIT(m_inp_mux, i)) data |= m_inputs[i]->read(); data = ~data << 1 & 0x3e; diff --git a/src/mame/drivers/gamemachine.cpp b/src/mame/drivers/gamemachine.cpp index 5287e6e6dc0..ea4205c8f7f 100644 --- a/src/mame/drivers/gamemachine.cpp +++ b/src/mame/drivers/gamemachine.cpp @@ -10,7 +10,7 @@ It was possibly created by VTech, but they didn't distribute it by themselves until later in 1980 as the Computer Game System. There's also a handheld version "Mini Game Machine". VTech later made a sequel "Game Machine 2" with 5 games. -hardware notes: +Hardware notes: - Mostek MK3870 MCU, 2KB internal ROM - 12 digits 7seg VFD panel - MC1455P(555 timer) + bunch of discrete components for sound @@ -20,6 +20,9 @@ TODO: the MK3870 has an internal /2 divider, this is way too slow when compared to video references of the game +BTANB: +- some digit segments get stuck after crashing in the GP game + ******************************************************************************* After boot, press a number to start a game: @@ -58,13 +61,16 @@ Grand Prix: #include "emu.h" #include "cpu/f8/f8.h" +#include "video/pwm.h" #include "machine/f3853.h" -#include "machine/timer.h" #include "speaker.h" #include "machine/netlist.h" #include "netlist/devices/net_lib.h" + +// internal artwork #include "tgm.lh" + /* * Netlist below provided under Creative Commons CC0 */ @@ -156,13 +162,9 @@ public: tgm_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), + m_display(*this, "display"), m_audio_pin(*this, "snd_nl:p%02u", 8U), - m_keypad(*this, "IN.%u", 0), - m_delay_display(*this, "delay_display_%u", 0), - m_out_digit(*this, "digit%u", 0U), - m_inp_mux(0), - m_digit_select(0), - m_digit_data(0) + m_inputs(*this, "IN.%u", 0) { } void tgm(machine_config &config); @@ -173,17 +175,14 @@ protected: private: // devices/pointers required_device m_maincpu; + required_device m_display; required_device_array m_audio_pin; - required_ioport_array<10> m_keypad; - required_device_array m_delay_display; - output_finder<12> m_out_digit; + required_ioport_array<10> m_inputs; void main_map(address_map &map); void main_io(address_map &map); - TIMER_DEVICE_CALLBACK_MEMBER(delay_display); - - void update_display(u16 edge); + void update_display(); DECLARE_WRITE8_MEMBER(mux1_w); DECLARE_WRITE8_MEMBER(mux2_w); DECLARE_WRITE8_MEMBER(digit_w); @@ -197,8 +196,10 @@ private: void tgm_state::machine_start() { - // resolve handlers - m_out_digit.resolve(); + // zerofill + m_inp_mux = 0; + m_digit_select = 0; + m_digit_data = 0; // register for savestates save_item(NAME(m_inp_mux)); @@ -212,42 +213,22 @@ void tgm_state::machine_start() Devices, I/O ******************************************************************************/ -// display handling - -TIMER_DEVICE_CALLBACK_MEMBER(tgm_state::delay_display) -{ - // clear VFD outputs - if (!BIT(m_digit_select, param)) - m_out_digit[param] = 0; -} +// MK3870 ports -void tgm_state::update_display(u16 edge) +void tgm_state::update_display() { - for (int i = 0; i < 12; i++) - { - // output VFD digit data - if (BIT(m_digit_select, i)) - m_out_digit[i] = m_digit_data; - - // they're strobed, so on falling edge, delay them going off to prevent flicker or stuck display - // BTANB: some digit segments get stuck after crashing in the GP game, it's not due to the simulated delay here - else if (BIT(edge, i)) - m_delay_display[i]->adjust(attotime::from_msec(20), i); - } + // output VFD digit data + m_display->matrix(m_digit_select, m_digit_data); } - -// MK3870 ports - WRITE8_MEMBER(tgm_state::mux1_w) { // P00-P06: input mux part m_inp_mux = (m_inp_mux & 7) | (data << 3 & 0x3f8); // P00-P07: digit select part - u16 prev = m_digit_select; m_digit_select = (m_digit_select & 0xf) | (data << 4); - update_display(m_digit_select ^ prev); + update_display(); } WRITE8_MEMBER(tgm_state::mux2_w) @@ -256,16 +237,15 @@ WRITE8_MEMBER(tgm_state::mux2_w) m_inp_mux = (m_inp_mux & 0x3f8) | (data >> 5 & 7); // P14-P17: digit select part - u16 prev = m_digit_select; m_digit_select = (m_digit_select & 0xff0) | (data >> 4 & 0xf); - update_display(m_digit_select ^ prev); + update_display(); } WRITE8_MEMBER(tgm_state::digit_w) { // P50-P57: digit 7seg data m_digit_data = bitswap<8>(data,0,1,2,3,4,5,6,7); - update_display(0); + update_display(); } READ8_MEMBER(tgm_state::input_r) @@ -275,7 +255,7 @@ READ8_MEMBER(tgm_state::input_r) // P12,P13: multiplexed inputs for (int i = 0; i < 10; i++) if (m_inp_mux >> i & 1) - data |= m_keypad[i]->read(); + data |= m_inputs[i]->read(); return data << 2; } @@ -372,9 +352,8 @@ void tgm_state::tgm(machine_config &config) psu.write_b().set(FUNC(tgm_state::digit_w)); /* video hardware */ - for (int i = 0; i < 12; i++) - TIMER(config, m_delay_display[i]).configure_generic(FUNC(tgm_state::delay_display)); - + PWM_DISPLAY(config, m_display).set_size(12, 8); + m_display->set_segmask(0xfff, 0xff); config.set_default_layout(layout_tgm); /* sound hardware */ diff --git a/src/mame/drivers/novag_mk1.cpp b/src/mame/drivers/novag_mk1.cpp index 776ce71f3b9..99b7bdfe621 100644 --- a/src/mame/drivers/novag_mk1.cpp +++ b/src/mame/drivers/novag_mk1.cpp @@ -165,10 +165,7 @@ void mk1_state::update_reset(ioport_value state) // clear display if (state) - { - m_digit_select = 0; - update_display(); - } + m_display->clear(); } diff --git a/src/mame/layout/aci_borisdpl.lay b/src/mame/layout/aci_borisdpl.lay index afe0bbd64c0..7af79a41443 100644 --- a/src/mame/layout/aci_borisdpl.lay +++ b/src/mame/layout/aci_borisdpl.lay @@ -294,25 +294,25 @@ - - - - - + + + + + - - - - - - + + + + + + - - - - - + + + + + -- cgit v1.2.3