From 673fdc3b236ab65201527c9b558f91d0f4e03deb Mon Sep 17 00:00:00 2001 From: hap Date: Mon, 22 Mar 2021 18:02:44 +0100 Subject: New working machines -------------------- Brain Baffler [hap, Sean Riddle] Horoscope Computer [hap, Sean Riddle] --- src/devices/cpu/pps41/mm75op.cpp | 2 - src/devices/cpu/pps41/mm78la.cpp | 51 ++++- src/devices/cpu/pps41/mm78la.h | 47 +++-- src/devices/cpu/pps41/mm78laop.cpp | 56 ++++-- src/devices/cpu/pps41/mm78op.cpp | 8 +- src/devices/cpu/pps41/pps41base.cpp | 8 +- src/devices/cpu/pps41/pps41base.h | 6 +- src/mame/drivers/hh_pps41.cpp | 365 ++++++++++++++++++++++++++++++++++-- src/mame/drivers/hh_ucom4.cpp | 4 +- src/mame/layout/brainbaf.lay | 21 +++ src/mame/layout/horocomp.lay | 21 +++ src/mame/mame.lst | 2 + 12 files changed, 533 insertions(+), 58 deletions(-) create mode 100644 src/mame/layout/brainbaf.lay create mode 100644 src/mame/layout/horocomp.lay diff --git a/src/devices/cpu/pps41/mm75op.cpp b/src/devices/cpu/pps41/mm75op.cpp index e4ef365a03e..723f0b2497c 100644 --- a/src/devices/cpu/pps41/mm75op.cpp +++ b/src/devices/cpu/pps41/mm75op.cpp @@ -7,8 +7,6 @@ #include "mm75.h" -// opcodes (differences with mm76_device) - // unsupported opcodes void mm75_device::op_ios() diff --git a/src/devices/cpu/pps41/mm78la.cpp b/src/devices/cpu/pps41/mm78la.cpp index 205763a01e8..7419b031836 100644 --- a/src/devices/cpu/pps41/mm78la.cpp +++ b/src/devices/cpu/pps41/mm78la.cpp @@ -31,7 +31,7 @@ mm77la_device::mm77la_device(const machine_config &mconfig, const char *tag, dev // machine config void mm78la_device::device_add_mconfig(machine_config &config) { - PLA(config, "opla", 5, 14, 32).set_format(pla_device::FMT::BERKELEY); + PLA(config, "opla", 4, 2*14, 16).set_format(pla_device::FMT::BERKELEY); } void mm77la_device::device_add_mconfig(machine_config &config) @@ -44,12 +44,34 @@ void mm77la_device::device_add_mconfig(machine_config &config) void mm78la_device::device_start() { mm78_device::device_start(); + + set_d_pins(12); set_r_pins(14); + + // zerofill + m_tone_on = 0; + m_tone_freq = 0; + m_tone_count = 1; + m_spk_output = 2; + m_ios_state = 0; + + // register for savestates + save_item(NAME(m_tone_on)); + save_item(NAME(m_tone_freq)); + save_item(NAME(m_tone_count)); + save_item(NAME(m_spk_output)); + save_item(NAME(m_ios_state)); } void mm78la_device::device_reset() { + m_r_mask = 0; mm78_device::device_reset(); + + // reset speaker + m_ios_state = 0; + m_tone_on = false; + m_write_spk(m_spk_output); } void mm77la_device::device_start() @@ -62,3 +84,30 @@ void mm77la_device::device_reset() { mm78la_device::device_reset(); } + + +// speaker +void mm78la_device::cycle() +{ + mm78_device::cycle(); + + m_tone_count++; + + // toggle when counter matches + if (m_tone_on && m_tone_count == m_tone_freq) + { + toggle_speaker(); + reset_tone_count(); + } +} + +void mm78la_device::reset_tone_count() +{ + m_tone_count = 1; +} + +void mm78la_device::toggle_speaker() +{ + m_spk_output ^= 3; + m_write_spk(m_spk_output); +} diff --git a/src/devices/cpu/pps41/mm78la.h b/src/devices/cpu/pps41/mm78la.h index 6b6c1862b82..cb611ef5dcc 100644 --- a/src/devices/cpu/pps41/mm78la.h +++ b/src/devices/cpu/pps41/mm78la.h @@ -17,17 +17,17 @@ /* ____ ____ ____ ____ - BP 1 |* \_/ | 42 DIO9 BP 1 |* \_/ | 40 DIO9 - A 2 | | 41 DIO8 A 2 | | 39 DIO8 - Vdd 3 | | 40 DIO7 N/C 3 | | 38 DIO7 - VC 4 | | 39 DIO6 VC 4 | | 37 DIO6 - TEST 5 | | 38 DIO5 Vdd 5 | | 36 DIO5 - Vss 6 | | 37 DIO4 Vss 6 | | 35 DIO4 - PI4 7 | | 36 DIO3 TEST 7 | | 34 DIO3 - PI8 8 | | 35 DIO2 PI4 8 | | 33 DIO2 - PI3 9 | | 34 DIO1 PI8 9 | | 32 DIO1 - PI7 10 | MM78LA | 33 DIO0 PI3 10 | MM77LA | 31 DIO0 - PI6 11 | | 32 Vdd SPK PI7 11 | | 30 INT0 + BP 1 |* \_/ | 42 DIO9 DIO9 1 |* \_/ | 40 DIO8 + A 2 | | 41 DIO8 BP 2 | | 39 DIO7 + Vdd 3 | | 40 DIO7 A 3 | | 38 DIO6 + VC 4 | | 39 DIO6 VC 4 | | 37 DIO5 + TEST 5 | | 38 DIO5 Vdd 5 | | 36 DIO4 + Vss 6 | | 37 DIO4 Vss 6 | | 35 DIO3 + PI4 7 | | 36 DIO3 TEST 7 | | 34 DIO2 + PI8 8 | | 35 DIO2 PI4 8 | | 33 DIO1 + PI3 9 | | 34 DIO1 PI8 9 | | 32 DIO0 + PI7 10 | MM95 | 33 DIO0 PI3 10 | B8000 | 31 DIO10 + PI6 11 | MM78LA | 32 Vdd SPK PI7 11 | | 30 DIO11 PI2 12 | | 31 SPK R2 PI6 12 | | 29 SPK R2 PI5 13 | | 30 SPK R1 PI2 13 | | 28 Vdd SPK PI1 14 | | 29 RO01 PI5 14 | | 27 SPK R1 @@ -39,7 +39,8 @@ RO10 20 | | 23 RO07 RO07 20 |___________| 21 RO06 RO09 21 |___________| 22 RO08 - MM78LA = aka MM95, MM77LA = aka B80xx (no official documentation known for latter, pinout has guesses) + MM78LA = aka MM95, speaker pins can be used for 2 more DIO when speaker is not used. + For B8000 (I call it MM77LA), no documentation is known, pinout might not be accurate. */ class mm78la_device : public mm78_device @@ -56,13 +57,23 @@ protected: virtual void device_add_mconfig(machine_config &config) override; // opcode handlers - virtual void op_sos() override; - virtual void op_ros() override; - virtual void op_skisl() override; - virtual void op_ix() override; - virtual void op_ox() override; virtual void op_ioa() override; + virtual void op_ox() override; + virtual void op_ix() override; virtual void op_ios() override; + virtual void op_int0h() override; + virtual void op_int1l() override; + + // speaker + bool m_tone_on; + u8 m_tone_freq; + u8 m_tone_count; + u8 m_spk_output; + u8 m_ios_state; + + virtual void cycle() override; + void reset_tone_count(); + void toggle_speaker(); }; class mm77la_device : public mm78la_device @@ -75,6 +86,8 @@ protected: virtual void device_start() override; virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override; + + virtual void op_ix() override; }; diff --git a/src/devices/cpu/pps41/mm78laop.cpp b/src/devices/cpu/pps41/mm78laop.cpp index 18b2aa80fe2..da64b15de46 100644 --- a/src/devices/cpu/pps41/mm78laop.cpp +++ b/src/devices/cpu/pps41/mm78laop.cpp @@ -7,41 +7,67 @@ #include "mm78la.h" -// opcodes - // changed opcodes -void mm78la_device::op_sos() +void mm78la_device::op_ioa() { - op_todo(); + // IOA: output A+carry to lower half of RO pins + u16 mask = (1 << (m_r_pins / 2)) - 1; + m_r_output = (m_r_output & ~mask) | (m_c << 4 | m_a); + m_write_r(m_r_output); } -void mm78la_device::op_ros() +void mm78la_device::op_ox() { - op_todo(); + // OX: output A+carry to upper half of RO pins + u16 mask = (1 << (m_r_pins / 2)) - 1; + m_r_output = (m_r_output & mask) | (m_c << 4 | m_a) << (m_r_pins / 2); + m_write_r(m_r_output); } -void mm78la_device::op_skisl() +void mm78la_device::op_ix() { - op_todo(); + // IX: output A+carry to RO pins through PLA (MM78LA) + u32 out = ~m_opla->read(m_a) & 0x0fff'ffff; + out = bitswap<28>(out, 26,22,18,14,10,6,2,1,5,9,13,17,21,25, 27,23,19,15,11,7,3,0,4,8,12,16,20,24); + m_r_output = out >> (m_c ? 0 : 14) & 0x3fff; + m_write_r(m_r_output); } -void mm78la_device::op_ix() +void mm77la_device::op_ix() { - op_todo(); + // IX: output A to RO pins through PLA (MM77LA) + u16 out = ~m_opla->read(m_a) & 0x3ff; + m_r_output = bitswap<10>(out, 9,7,5,3,1,0,2,4,6,8); + m_write_r(m_r_output); } -void mm78la_device::op_ox() +void mm78la_device::op_ios() { - op_todo(); + // IOS: set tone frequency + m_tone_freq = m_tone_freq >> 4 | (m_a << 4); + + // state 1->2: turn on + if (m_ios_state == 1) + { + m_tone_on = true; + reset_tone_count(); + } + else + m_tone_on = false; + + // increment state machine + m_ios_state = (m_ios_state + 1) % 3; } -void mm78la_device::op_ioa() +void mm78la_device::op_int0h() { - op_todo(); + // INT0H: toggle speaker + toggle_speaker(); } -void mm78la_device::op_ios() +void mm78la_device::op_int1l() { + // INT1L: ? op_todo(); } diff --git a/src/devices/cpu/pps41/mm78op.cpp b/src/devices/cpu/pps41/mm78op.cpp index 13db81d05b8..ddf7221a682 100644 --- a/src/devices/cpu/pps41/mm78op.cpp +++ b/src/devices/cpu/pps41/mm78op.cpp @@ -7,8 +7,6 @@ #include "mm78.h" -// opcodes - // changed opcodes void mm78_device::op_lba() @@ -63,7 +61,7 @@ void mm78_device::op_sos() } u8 bl = m_ram_addr & 0xf; - if (bl < 10) + if (bl < m_d_pins) { m_d_output = (m_d_output | (1 << bl)) & m_d_mask; m_write_d(m_d_output); @@ -86,7 +84,7 @@ void mm78_device::op_ros() } u8 bl = m_ram_addr & 0xf; - if (bl < 10) + if (bl < m_d_pins) { m_d_output = m_d_output & ~(1 << bl); m_write_d(m_d_output); @@ -109,7 +107,7 @@ void mm78_device::op_skisl() } u8 bl = m_ram_addr & 0xf; - if (bl < 10) + if (bl < m_d_pins) m_skip = !BIT((m_d_output | m_read_d()) & m_d_mask, bl); else if (bl < 12) m_skip = !m_int_ff[~bl & 1]; diff --git a/src/devices/cpu/pps41/pps41base.cpp b/src/devices/cpu/pps41/pps41base.cpp index 0d3cb8e6d78..1c148f5dafc 100644 --- a/src/devices/cpu/pps41/pps41base.cpp +++ b/src/devices/cpu/pps41/pps41base.cpp @@ -44,7 +44,9 @@ TODO: but again does not explain why - allowed opcode after TAB should be limited - add MCU mask options, there's one for inverting interrupts -- finish MM78LA emulation +- does MM78LA support interrupts? the sparse documentation available says it does +- MM78LA mnemonics for changed opcodes is unknown +- no known documentation exists for MM77LA, mcu name is guessed */ @@ -68,7 +70,8 @@ pps41_base_device::pps41_base_device(const machine_config &mconfig, device_type m_write_r(*this), m_read_sdi(*this), m_write_sdo(*this), - m_write_ssc(*this) + m_write_ssc(*this), + m_write_spk(*this) { } @@ -92,6 +95,7 @@ void pps41_base_device::device_start() m_read_sdi.resolve_safe(1); m_write_sdo.resolve_safe(); m_write_ssc.resolve_safe(); + m_write_spk.resolve_safe(); // init RAM with 0xf for (int i = 0; i <= m_datamask; i++) diff --git a/src/devices/cpu/pps41/pps41base.h b/src/devices/cpu/pps41/pps41base.h index faeb6234723..d531b77042b 100644 --- a/src/devices/cpu/pps41/pps41base.h +++ b/src/devices/cpu/pps41/pps41base.h @@ -42,6 +42,9 @@ public: auto write_sdo() { return m_write_sdo.bind(); } auto write_ssc() { return m_write_ssc.bind(); } + // speaker output + auto write_spk() { return m_write_spk.bind(); } + // I/O access u16 d_output_r() { return m_d_output; } u16 r_output_r() { return m_r_output; } @@ -94,6 +97,7 @@ protected: devcb_read_line m_read_sdi; devcb_write_line m_write_sdo; devcb_write_line m_write_ssc; + devcb_write8 m_write_spk; // internal state, regs u16 m_pc; @@ -140,7 +144,7 @@ protected: void serial_shift(int state); void serial_clock(); - void cycle(); + virtual void cycle(); void increment_pc(); }; diff --git a/src/mame/drivers/hh_pps41.cpp b/src/mame/drivers/hh_pps41.cpp index b2db23137b9..8b94a02faeb 100644 --- a/src/mame/drivers/hh_pps41.cpp +++ b/src/mame/drivers/hh_pps41.cpp @@ -24,8 +24,10 @@ ROM source notes when dumped from another publisher, but confident it's the same #include "speaker.h" // internal artwork +#include "brainbaf.lh" #include "dunksunk.lh" #include "ftri1.lh" +#include "horocomp.lh" #include "mastmind.lh" #include "memoquiz.lh" #include "mwcfootb.lh" @@ -51,7 +53,7 @@ public: required_device m_maincpu; optional_device m_display; optional_device m_speaker; - optional_ioport_array<6> m_inputs; // max 6 + optional_ioport_array<11> m_inputs; // max 11 u16 m_inp_mux = 0; u32 m_grid = 0; @@ -104,8 +106,7 @@ u8 hh_pps41_state::read_inputs(int columns) if (m_inp_mux >> i & 1) ret |= m_inputs[i]->read(); - // active low by default - return ~ret; + return ret; } INPUT_CHANGED_MEMBER(hh_pps41_state::reset_button) @@ -290,7 +291,7 @@ void mastmind_state::write_r(u16 data) u8 mastmind_state::read_p() { // PI1-PI4: multiplexed inputs - return read_inputs(4); + return ~read_inputs(4); } // config @@ -441,7 +442,7 @@ void dunksunk_state::write_r(u16 data) // config static INPUT_PORTS_START( dunksunk ) - PORT_START("IN.0") // P + PORT_START("IN.0") // PI PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) @@ -567,7 +568,7 @@ void memoquiz_state::write_r(u16 data) u8 memoquiz_state::read_p() { // PI1-PI4: multiplexed inputs - return read_inputs(4); + return ~read_inputs(4); } // config @@ -635,6 +636,342 @@ ROM_END +/*************************************************************************** + + Mattel Brain Baffler (model 1080) + * PCB label: OLYMPOS KOREA, CM04-D102-001 REV D + * MM78LA MCU (label MM95 B9000-12, die label B9000) + * 8-digit 14seg LED display, 2-bit sound + + It includes 8 word games, most of them are meant for 2 players. + +***************************************************************************/ + +class brainbaf_state : public hh_pps41_state +{ +public: + brainbaf_state(const machine_config &mconfig, device_type type, const char *tag) : + hh_pps41_state(mconfig, type, tag) + { } + + void update_display(); + void write_d(u16 data); + void write_r(u16 data); + u8 read_p(); + void write_spk(u8 data); + void brainbaf(machine_config &config); +}; + +// handlers + +void brainbaf_state::update_display() +{ + m_display->matrix(m_inp_mux, bitswap<14>(m_r, 6,5,13,12,11,4,3,10,9,8,7,2,1,0)); +} + +void brainbaf_state::write_d(u16 data) +{ + // DIO0-DIO9: input mux + // DIO0-DIO7: digit select + m_inp_mux = data; + update_display(); +} + +void brainbaf_state::write_r(u16 data) +{ + // RO01-RO14: digit segment data + m_r = data; + update_display(); +} + +u8 brainbaf_state::read_p() +{ + // PI5-PI8: multiplexed inputs + return read_inputs(10) << 4; +} + +void brainbaf_state::write_spk(u8 data) +{ + // SPK: speaker out + m_speaker->level_w(data); +} + +// config + +static INPUT_PORTS_START( brainbaf ) + PORT_START("IN.0") // DIO0 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR('J') PORT_NAME("J-0") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F12) PORT_NAME("Player / Bonus R") + + PORT_START("IN.1") // DIO1 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('A') PORT_NAME("A-1") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_NAME("Player / Bonus L") + + PORT_START("IN.2") // DIO2 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR('B') PORT_NAME("B-2") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_NAME("Game") + + PORT_START("IN.3") // DIO3 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR('C') PORT_NAME("C-3") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F4) PORT_NAME("Go") + + PORT_START("IN.4") // DIO4 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR('D') PORT_NAME("D-4") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F5) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(13) PORT_NAME("Entry") + + PORT_START("IN.5") // DIO5 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR('E') PORT_NAME("E-5") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F6) PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_NAME("Clear") + + PORT_START("IN.6") // DIO6 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR('F') PORT_NAME("F-6") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F7) PORT_NAME("Refresh") + + PORT_START("IN.7") // DIO7 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_CHAR('G') PORT_NAME("G-7") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F8) PORT_NAME("Buy") + + PORT_START("IN.8") // DIO8 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR('H') PORT_NAME("H-8") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F9) PORT_NAME("Give-Up") + + PORT_START("IN.9") // DIO9 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR('I') PORT_NAME("I-9") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_CODE(KEYCODE_F11) PORT_NAME("Stop") // both STOP keys + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F10) PORT_NAME("Score") +INPUT_PORTS_END + +void brainbaf_state::brainbaf(machine_config &config) +{ + /* basic machine hardware */ + MM78LA(config, m_maincpu, 440000); // approximation - VC osc. R=10K + m_maincpu->write_d().set(FUNC(brainbaf_state::write_d)); + m_maincpu->write_r().set(FUNC(brainbaf_state::write_r)); + m_maincpu->read_p().set(FUNC(brainbaf_state::read_p)); + m_maincpu->write_spk().set(FUNC(brainbaf_state::write_spk)); + + /* video hardware */ + PWM_DISPLAY(config, m_display).set_size(8, 14); + m_display->set_segmask(0xff, 0x3fff); + config.set_default_layout(layout_brainbaf); + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, m_speaker); + static const double speaker_levels[4] = { 0.0, 1.0, -1.0, 0.0 }; + m_speaker->set_levels(4, speaker_levels); + m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25); +} + +// roms + +ROM_START( brainbaf ) + ROM_REGION( 0x0800, "maincpu", 0 ) + ROM_LOAD( "mm95_b9000-12", 0x0000, 0x0800, CRC(f7a4829c) SHA1(12f789d8264a969777764d31ea67067cc330a73c) ) + + ROM_REGION( 605, "maincpu:opla", 0 ) + ROM_LOAD( "mm78la_brainbaf_output.pla", 0, 605, CRC(4fae532f) SHA1(3a08c0fa3ce476c014280b3cfeb6aa37824ae503) ) +ROM_END + + + + + +/*************************************************************************** + + Mattel Horoscope Computer (model 1081) + * PCB label: DET. CM05-D102-001 REV D + * MM78LA MCU (label MM95 B9001-13, die label B9001) + * 8-digit 14seg LED display, 2-bit sound + + This is not a toy, but a fortune forecast. Date format is mm-dd-yy, it is + valid only from June 1 1979 until December 31 1987 + +***************************************************************************/ + +class horocomp_state : public hh_pps41_state +{ +public: + horocomp_state(const machine_config &mconfig, device_type type, const char *tag) : + hh_pps41_state(mconfig, type, tag) + { } + + void update_display(); + void write_d(u16 data); + void write_r(u16 data); + u8 read_p(); + void write_spk(u8 data); + void horocomp(machine_config &config); +}; + +// handlers + +void horocomp_state::update_display() +{ + // 7seg display is upside-down + u16 flip = m_r << 7 | m_r >> 7; + m_display->matrix(m_inp_mux, bitswap<14>(flip, 6,5,13,12,11,4,3,10,9,8,7,2,1,0)); +} + +void horocomp_state::write_d(u16 data) +{ + // DIO0-DIO9: input mux + // DIO0-DIO7: digit select + m_inp_mux = data; + update_display(); +} + +void horocomp_state::write_r(u16 data) +{ + // RO01-RO14: digit segment data + m_r = data; + update_display(); +} + +u8 horocomp_state::read_p() +{ + // PI4: mode switch + // PI5-PI8: multiplexed inputs + return read_inputs(10) << 4 | (m_inputs[10]->read() & 8); +} + +void horocomp_state::write_spk(u8 data) +{ + // SPK: speaker out + m_speaker->level_w(data); +} + +// config + +/* physical button layout and labels is like this: + + CAP. + AQU. [ ] SAG. + [ ] 9 [ ] + PIS. 8 SCO. + [ ] 7[ ] + +ARI.[ ]0 6[ ]LIB. + + [ ]1 5[ ] [ ] [ ] [ ] [ ] + TAU. 2 4 VIR. LOVE CAREER TRAVEL MONEY + [ ] 3 [ ] + GEM. [ ] LEO [ ] [ ] [ ] [ ] + CAN. FRIENDS SPIRIT FAMILY CREATIVE +*/ + +static INPUT_PORTS_START( horocomp ) + PORT_START("IN.0") // DIO0 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_L) PORT_NAME("Love") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_F) PORT_NAME("Friends") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0 / Aries") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("IN.1") // DIO1 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_C) PORT_NAME("Career") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_S) PORT_NAME("Spirit") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1 / Taurus") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("IN.2") // DIO2 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_T) PORT_NAME("Travel") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_A) PORT_NAME("Family") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2 / Gemini") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("IN.3") // DIO3 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_M) PORT_NAME("Money") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) PORT_NAME("Creative") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3 / Cancer") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("IN.4") // DIO4 + PORT_BIT( 0x03, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4 / Leo") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_MINUS) PORT_CODE(KEYCODE_MINUS_PAD) PORT_NAME("Aquarius / Reset") + + PORT_START("IN.5") // DIO5 + PORT_BIT( 0x03, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5 / Virgo") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_EQUALS) PORT_CODE(KEYCODE_PLUS_PAD) PORT_NAME("Pisces") + + PORT_START("IN.6") // DIO6 + PORT_BIT( 0x0b, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6 / Libra") + + PORT_START("IN.7") // DIO7 + PORT_BIT( 0x0b, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7 / Scorpio") + + PORT_START("IN.8") // DIO8 + PORT_BIT( 0x0b, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8 / Sagittarius") + + PORT_START("IN.9") // DIO9 + PORT_BIT( 0x0b, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9 / Capricorn") + + PORT_START("IN.10") // PI4 + PORT_CONFNAME( 0x08, 0x00, "Mode" ) + PORT_CONFSETTING( 0x08, "C" ) // compatibility + PORT_CONFSETTING( 0x00, "P" ) // personal +INPUT_PORTS_END + +void horocomp_state::horocomp(machine_config &config) +{ + /* basic machine hardware */ + MM78LA(config, m_maincpu, 440000); // approximation - VC osc. R=10K + m_maincpu->write_d().set(FUNC(horocomp_state::write_d)); + m_maincpu->write_r().set(FUNC(horocomp_state::write_r)); + m_maincpu->read_p().set(FUNC(horocomp_state::read_p)); + m_maincpu->write_spk().set(FUNC(horocomp_state::write_spk)); + + /* video hardware */ + PWM_DISPLAY(config, m_display).set_size(8, 14); + m_display->set_segmask(0xff, 0x3fff); + config.set_default_layout(layout_horocomp); + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, m_speaker); + static const double speaker_levels[4] = { 0.0, 1.0, -1.0, 0.0 }; + m_speaker->set_levels(4, speaker_levels); + m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25); +} + +// roms + +ROM_START( horocomp ) + ROM_REGION( 0x0800, "maincpu", 0 ) + ROM_LOAD( "mm95_b9001-13", 0x0000, 0x0800, CRC(d284a837) SHA1(02092db2a29b4bb7e9f86286601b67b2e9556476) ) + + ROM_REGION( 605, "maincpu:opla", 0 ) + ROM_LOAD( "mm78la_horocomp_output.pla", 0, 605, CRC(4fae532f) SHA1(3a08c0fa3ce476c014280b3cfeb6aa37824ae503) ) +ROM_END + + + + + /*************************************************************************** Mattel World Championship Football (model 3202) @@ -709,7 +1046,7 @@ void mwcfootb_state::main_write_r(u16 data) u8 mwcfootb_state::main_read_p() { // PI1-PI8: multiplexed inputs - return read_inputs(3); + return ~read_inputs(3); } // subcpu side @@ -895,7 +1232,7 @@ void scrabsen_state::write_r(u16 data) u8 scrabsen_state::read_p() { // PI1-PI7: multiplexed inputs - return read_inputs(5); + return ~read_inputs(5); } // config @@ -988,7 +1325,7 @@ ROM_END Selchow & Righter Reader's Digest Q&A * MM76EL MCU (label MM76EL B8654-11, die label B8654) - * 9-digit 7seg display(4 unused), 2-bit sound + * 9-digit 7seg LED display(4 unused), 2-bit sound The game requires question books. The player inputs a 3-digit code and answers 20 multiple-choice questions from the page. @@ -1046,7 +1383,7 @@ void rdqa_state::write_r(u16 data) u8 rdqa_state::read_p() { // PI1-PI5: multiplexed inputs - return read_inputs(4); + return ~read_inputs(4); } // config @@ -1133,11 +1470,13 @@ CONS( 1979, ftri1, 0, 0, ftri1, ftri1, ftri1_state, empty_in CONS( 1979, mastmind, 0, 0, mastmind, mastmind, mastmind_state, empty_init, "Invicta", "Electronic Master Mind (Invicta)", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND_HW ) CONS( 1979, smastmind, 0, 0, smastmind, mastmind, mastmind_state, empty_init, "Invicta", "Super-Sonic Electronic Master Mind", MACHINE_SUPPORTS_SAVE ) -CONS( 1980, dunksunk, 0, 0, dunksunk, dunksunk, dunksunk_state, empty_init, "Kmart", "Dunk 'n Sunk", MACHINE_SUPPORTS_SAVE ) +CONS( 1979, dunksunk, 0, 0, dunksunk, dunksunk, dunksunk_state, empty_init, "Kmart", "Dunk 'n Sunk", MACHINE_SUPPORTS_SAVE ) CONS( 1978, memoquiz, 0, 0, memoquiz, memoquiz, memoquiz_state, empty_init, "M.E.M. Belgium", "Memoquiz", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND_HW ) -CONS( 1981, mwcfootb, 0, 0, mwcfootb, mwcfootb, mwcfootb_state, empty_init, "Mattel", "World Championship Football", MACHINE_SUPPORTS_SAVE ) +CONS( 1979, brainbaf, 0, 0, brainbaf, brainbaf, brainbaf_state, empty_init, "Mattel", "Brain Baffler", MACHINE_SUPPORTS_SAVE ) +CONS( 1979, horocomp, 0, 0, horocomp, horocomp, horocomp_state, empty_init, "Mattel", "Horoscope Computer", MACHINE_SUPPORTS_SAVE ) +CONS( 1980, mwcfootb, 0, 0, mwcfootb, mwcfootb, mwcfootb_state, empty_init, "Mattel", "World Championship Football", MACHINE_SUPPORTS_SAVE ) -CONS( 1979, scrabsen, 0, 0, scrabsen, scrabsen, scrabsen_state, empty_init, "Selchow & Righter", "Scrabble Sensor - Electronic Word Game", MACHINE_SUPPORTS_SAVE ) +CONS( 1978, scrabsen, 0, 0, scrabsen, scrabsen, scrabsen_state, empty_init, "Selchow & Righter", "Scrabble Sensor - Electronic Word Game", MACHINE_SUPPORTS_SAVE ) CONS( 1980, rdqa, 0, 0, rdqa, rdqa, rdqa_state, empty_init, "Selchow & Righter", "Reader's Digest Q&A - Computer Question & Answer Game", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/hh_ucom4.cpp b/src/mame/drivers/hh_ucom4.cpp index 6f156c0d973..7d78ddc5e96 100644 --- a/src/mame/drivers/hh_ucom4.cpp +++ b/src/mame/drivers/hh_ucom4.cpp @@ -1482,8 +1482,8 @@ static INPUT_PORTS_START( efball ) PORT_CONFNAME( 0x02, 0x02, DEF_STR( Players ) ) PORT_CONFSETTING( 0x02, "1" ) PORT_CONFSETTING( 0x00, "2" ) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("P1 Down-Field") - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("P1 Score-Time") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START1 ) PORT_NAME("P1 Down-Field") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START2 ) PORT_NAME("P1 Score-Time") PORT_START("IN.1") // port B PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_16WAY diff --git a/src/mame/layout/brainbaf.lay b/src/mame/layout/brainbaf.lay new file mode 100644 index 00000000000..0bbb0bdfb89 --- /dev/null +++ b/src/mame/layout/brainbaf.lay @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/layout/horocomp.lay b/src/mame/layout/horocomp.lay new file mode 100644 index 00000000000..bc4b503b95d --- /dev/null +++ b/src/mame/layout/horocomp.lay @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 454b9e6ccd5..58356fba38d 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -16179,8 +16179,10 @@ us2pfball // US Games uspbball // US Games @source:hh_pps41.cpp +brainbaf // Mattel dunksunk // Kmart ftri1 // Fonas +horocomp // Mattel mastmind // Invicta memoquiz // MEM mwcfootb // Mattel -- cgit v1.2.3