From 282a6e03a53d1a1f66ea01d5fe3cfc8d35f6e2de Mon Sep 17 00:00:00 2001 From: hap Date: Tue, 4 Nov 2014 18:18:28 +0100 Subject: [PATCH] small cleanup to merlin.c, it is very similar to simon.c I want to redo the merlin layout later, make it more similar/appealing. --- src/mess/drivers/merlin.c | 238 ++++++++++++++++++------------------- src/mess/drivers/simon.c | 31 +++-- src/mess/layout/merlin.lay | 52 ++++---- src/mess/layout/simon.lay | 4 +- 4 files changed, 158 insertions(+), 167 deletions(-) diff --git a/src/mess/drivers/merlin.c b/src/mess/drivers/merlin.c index c5cc67d3421..d09fd00740b 100644 --- a/src/mess/drivers/merlin.c +++ b/src/mess/drivers/merlin.c @@ -1,73 +1,63 @@ -/* +/*************************************************************************** - Parker Bros Merlin handheld computer game + Parker Bros Merlin handheld computer game + * TMS1100NLL MP3404A-N2 (has internal ROM) + + Other games assumed to be on similar hardware: + - Dr. Smith - by Tomy, released in Japan (basically a white version of Merlin, + let's assume for now that the ROM contents is identical) + - Master Merlin + + Another sequel, called Split Second, looks like different hardware. -*/ + + TODO: + - accurate rc osc + - is the rom dump good? + +***************************************************************************/ #include "emu.h" #include "cpu/tms0980/tms0980.h" #include "sound/speaker.h" -/* Layout */ #include "merlin.lh" +// master clock is a single stage RC oscillator: R=?, C=? +#define MERLIN_RC_CLOCK (500000) + class merlin_state : public driver_device { public: merlin_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), - m_speaker(*this, "speaker") , - m_maincpu(*this, "maincpu") { } - - virtual void machine_start(); + m_maincpu(*this, "maincpu"), + m_button_matrix(*this, "O"), + m_speaker(*this, "speaker") + { } + required_device m_maincpu; + required_ioport_array<4> m_button_matrix; required_device m_speaker; + UINT16 m_o; + DECLARE_READ8_MEMBER(read_k); DECLARE_WRITE16_MEMBER(write_o); DECLARE_WRITE16_MEMBER(write_r); -protected: - UINT16 m_o; - UINT16 m_r; - required_device m_maincpu; + virtual void machine_start(); }; -#define LOG 0 +/*************************************************************************** + I/O -static INPUT_PORTS_START( merlin ) - PORT_START("O0") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_CODE(KEYCODE_0) PORT_NAME("R0") // R0 - PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_CODE(KEYCODE_1) PORT_NAME("R1") // R1 - PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON4) PORT_CODE(KEYCODE_3) PORT_NAME("R3") // R3 - PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_CODE(KEYCODE_2) PORT_NAME("R2") // R2 +***************************************************************************/ - PORT_START("O1") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON5) PORT_CODE(KEYCODE_4) PORT_NAME("R4") // R4 - PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON6) PORT_CODE(KEYCODE_5) PORT_NAME("R5") // R5 - PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON8) PORT_CODE(KEYCODE_7) PORT_NAME("R7") // R7 - PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON7) PORT_CODE(KEYCODE_6) PORT_NAME("R6") // R6 - - PORT_START("O2") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON9) PORT_CODE(KEYCODE_8) PORT_NAME("R8") // R8 - PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON10) PORT_CODE(KEYCODE_9) PORT_NAME("R9") // R9 - PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON13) PORT_CODE(KEYCODE_S) PORT_NAME("Same Game") // SG - same game - PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON11) PORT_CODE(KEYCODE_MINUS) PORT_NAME("R10") // R10 - - PORT_START("O3") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON15) PORT_CODE(KEYCODE_C) PORT_NAME("Comp Turn") // Comp Turn - PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON14) PORT_CODE(KEYCODE_H) PORT_NAME("Hit Me") // Hit me - PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON12) PORT_CODE(KEYCODE_N) PORT_NAME("New Game") // NG - new game - -INPUT_PORTS_END - - -/* -The keypad is a 4*4 matrix, connected like so: +/* The keypad is a 4*4 matrix, connected like so: +----+ +----+ +----+ +----+ O0 o---| R0 |--| R1 |--| R2 |--| R3 | @@ -88,97 +78,93 @@ O3 o------+----| CT |--| NG |--| HM | o o o o K1 K2 K8 K4 -SG = same game, CT = comp turn, NG = new game, HM = hit me -*/ +SG = same game, CT = comp turn, NG = new game, HM = hit me */ READ8_MEMBER(merlin_state::read_k) { - UINT8 data = 0; + UINT8 k = 0; + + // read selected button rows + for (int i = 0; i < 4; i++) + if (m_o & (1 << i)) + k |= m_button_matrix[i]->read(); - if (LOG) - logerror( "read_k\n" ); - - if ( m_o & 0x01 ) - { - data |= ioport("O0")->read(); - } - - if ( m_o & 0x02 ) - { - data |= ioport("O1")->read(); - } - - if ( m_o & 0x04 ) - { - data |= ioport("O2")->read(); - } - - if ( m_o & 0x08 ) - { - data |= ioport("O3")->read(); - } - - return data; + return k; } - -/* -The speaker is connected to O4 through O6. The 3 outputs are paralleled for -increased current driving capability. They are passed thru a 220 ohm resistor -and then to the speaker, which has the other side grounded. The software then -toggles these lines to make sounds and noises. (There is no audio generator -other than toggling it with a software delay between to make tones). -*/ - WRITE16_MEMBER(merlin_state::write_o) { - if (LOG) - logerror( "write_o: write %02x\n", data ); - + // O0-O3: input mux m_o = data; + /* The speaker is connected to O4 through O6. The 3 outputs are paralleled for + increased current driving capability. They are passed thru a 220 ohm resistor + and then to the speaker, which has the other side grounded. The software then + toggles these lines to make sounds and noises. (There is no audio generator + other than toggling it with a software delay between to make tones). */ m_speaker->level_w(m_o & 0x70); } - -/* - - LEDs: - - R0 - R1 R2 R3 - R4 R5 R6 - R7 R8 R9 - R10 - -When that particular R output is high, that LED is on. -*/ - WRITE16_MEMBER(merlin_state::write_r) { - if (LOG) - logerror( "write_r: write %04x\n", data ); + /* LEDs: - m_r = data; - - output_set_value( "led_0", BIT( m_r, 0 ) ); - output_set_value( "led_1", BIT( m_r, 1 ) ); - output_set_value( "led_2", BIT( m_r, 2 ) ); - output_set_value( "led_3", BIT( m_r, 3 ) ); - output_set_value( "led_4", BIT( m_r, 4 ) ); - output_set_value( "led_5", BIT( m_r, 5 ) ); - output_set_value( "led_6", BIT( m_r, 6 ) ); - output_set_value( "led_7", BIT( m_r, 7 ) ); - output_set_value( "led_8", BIT( m_r, 8 ) ); - output_set_value( "led_9", BIT( m_r, 9 ) ); - output_set_value( "led_10", BIT( m_r, 10 ) ); + R0 + R1 R2 R3 + R4 R5 R6 + R7 R8 R9 + R10 + */ + for (int i = 0; i < 11; i++) + output_set_lamp_value(i, data >> i & 1); } + +/*************************************************************************** + + Inputs + +***************************************************************************/ + +static INPUT_PORTS_START( merlin ) + PORT_START("O.0") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_CODE(KEYCODE_0) PORT_NAME("Button R0") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_CODE(KEYCODE_1) PORT_NAME("Button R1") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON4) PORT_CODE(KEYCODE_3) PORT_NAME("Button R3") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_CODE(KEYCODE_2) PORT_NAME("Button R2") + + PORT_START("O.1") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON5) PORT_CODE(KEYCODE_4) PORT_NAME("Button R4") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON6) PORT_CODE(KEYCODE_5) PORT_NAME("Button R5") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON8) PORT_CODE(KEYCODE_7) PORT_NAME("Button R7") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON7) PORT_CODE(KEYCODE_6) PORT_NAME("Button R6") + + PORT_START("O.2") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON9) PORT_CODE(KEYCODE_8) PORT_NAME("Button R8") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON10) PORT_CODE(KEYCODE_9) PORT_NAME("Button R9") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON13) PORT_CODE(KEYCODE_S) PORT_NAME("Same Game") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON11) PORT_CODE(KEYCODE_MINUS) PORT_NAME("Button R10") + + PORT_START("O.3") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON15) PORT_CODE(KEYCODE_C) PORT_NAME("Comp Turn") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON14) PORT_CODE(KEYCODE_H) PORT_NAME("Hit Me") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON12) PORT_CODE(KEYCODE_N) PORT_NAME("New Game") +INPUT_PORTS_END + + + +/*************************************************************************** + + Machine Config + +***************************************************************************/ + void merlin_state::machine_start() { + m_o = 0; save_item(NAME(m_o)); - save_item(NAME(m_r)); } @@ -193,20 +179,32 @@ static const UINT16 merlin_output_pla[0x20] = static MACHINE_CONFIG_START( merlin, merlin_state ) - MCFG_CPU_ADD( "maincpu", TMS1100, 500000 ) /* Clock may be wrong */ - MCFG_TMS1XXX_OUTPUT_PLA( merlin_output_pla ) - MCFG_TMS1XXX_READ_K( READ8( merlin_state, read_k ) ) - MCFG_TMS1XXX_WRITE_O( WRITE16( merlin_state, write_o ) ) - MCFG_TMS1XXX_WRITE_R( WRITE16( merlin_state, write_r ) ) + + /* basic machine hardware */ + MCFG_CPU_ADD( "maincpu", TMS1100, MERLIN_RC_CLOCK ) + MCFG_TMS1XXX_OUTPUT_PLA(merlin_output_pla) + MCFG_TMS1XXX_READ_K(READ8( merlin_state, read_k)) + MCFG_TMS1XXX_WRITE_O(WRITE16( merlin_state, write_o)) + MCFG_TMS1XXX_WRITE_R(WRITE16( merlin_state, write_r)) MCFG_DEFAULT_LAYOUT(layout_merlin) + /* no video! */ + + /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) MACHINE_CONFIG_END + +/*************************************************************************** + + Game driver(s) + +***************************************************************************/ + ROM_START( merlin ) ROM_REGION( 0x800, "maincpu", 0 ) // This rom needs verification, that's why it is marked as a bad dump @@ -216,11 +214,5 @@ ROM_START( merlin ) ROM_LOAD( "mp3404", 0x0000, 0x800, BAD_DUMP CRC(7515a75d) SHA1(76ca3605d3fde1df62f79b9bb1f534c2a2ae0229) ) ROM_END -/*************************************************************************** - Game driver(s) - -***************************************************************************/ - -/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ -CONS( 1978, merlin, 0, 0, merlin, merlin, driver_device, 0, "Parker Brothers", "Merlin", 0 ) +CONS( 1978, merlin, 0, 0, merlin, merlin, driver_device, 0, "Parker Brothers", "Merlin", GAME_SUPPORTS_SAVE ) diff --git a/src/mess/drivers/simon.c b/src/mess/drivers/simon.c index 72b35582439..690c55658f1 100644 --- a/src/mess/drivers/simon.c +++ b/src/mess/drivers/simon.c @@ -8,10 +8,15 @@ * TMS1000 (has internal ROM), SN75494 lamp driver Newer revisions have a smaller 16-pin MB4850 chip instead of the TMS1000. - It has been decapped, but we couldn't yet find the internal ROM. + This one has been decapped too, but we couldn't yet find the internal ROM. + + Other games assumed to be on similar hardware: + - Pocket Simon + - Super Simon TODO: + - accurate rc osc - where's the skill switch? ***************************************************************************/ @@ -22,6 +27,10 @@ #include "simon.lh" +// master clock is a single stage RC oscillator: R=?, C=? +// this is an approximation compared with old recordings +#define SIMON_RC_CLOCK (330000) + class simon_state : public driver_device { @@ -37,7 +46,6 @@ public: required_ioport_array<3> m_button_matrix; required_device m_speaker; - UINT16 m_o; UINT16 m_r; DECLARE_READ8_MEMBER(read_k); @@ -45,7 +53,6 @@ public: DECLARE_WRITE16_MEMBER(write_r); virtual void machine_start(); - virtual void machine_reset(); }; @@ -57,14 +64,14 @@ public: READ8_MEMBER(simon_state::read_k) { - UINT8 ret = 0; + UINT8 k = 0; // read selected button rows for (int i = 0; i < 3; i++) if (m_r & (1 << i)) - ret |= m_button_matrix[i]->read(); + k |= m_button_matrix[i]->read(); - return ret; + return k; } WRITE16_MEMBER(simon_state::write_r) @@ -85,7 +92,6 @@ WRITE16_MEMBER(simon_state::write_r) WRITE16_MEMBER(simon_state::write_o) { // N/C - m_o = data; } @@ -125,16 +131,9 @@ INPUT_PORTS_END ***************************************************************************/ -void simon_state::machine_reset() -{ -} - void simon_state::machine_start() { - m_o = 0; m_r = 0; - - save_item(NAME(m_o)); save_item(NAME(m_r)); } @@ -152,7 +151,7 @@ static const UINT16 simon_output_pla[0x20] = static MACHINE_CONFIG_START( simon, simon_state ) /* basic machine hardware */ - MCFG_CPU_ADD( "maincpu", TMS1000, 330000 ) // RC osc, approximation compared with recordings + MCFG_CPU_ADD( "maincpu", TMS1000, SIMON_RC_CLOCK ) MCFG_TMS1XXX_OUTPUT_PLA(simon_output_pla) MCFG_TMS1XXX_READ_K(READ8(simon_state, read_k)) MCFG_TMS1XXX_WRITE_O(WRITE16(simon_state, write_o)) @@ -172,7 +171,7 @@ MACHINE_CONFIG_END /*************************************************************************** - Game drivers + Game driver(s) ***************************************************************************/ diff --git a/src/mess/layout/merlin.lay b/src/mess/layout/merlin.lay index 5ab03f65e73..0e7859dcd76 100644 --- a/src/mess/layout/merlin.lay +++ b/src/mess/layout/merlin.lay @@ -370,98 +370,98 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/src/mess/layout/simon.lay b/src/mess/layout/simon.lay index a731b9ba223..5cf2414285d 100644 --- a/src/mess/layout/simon.lay +++ b/src/mess/layout/simon.lay @@ -49,7 +49,7 @@ - + @@ -60,7 +60,7 @@ - +