summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/drivers/merlin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/drivers/merlin.c')
-rw-r--r--src/mess/drivers/merlin.c238
1 files changed, 115 insertions, 123 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
+ * 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.
- Parker Bros Merlin handheld computer game
-*/
+ 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<cpu_device> m_maincpu;
+ required_ioport_array<4> m_button_matrix;
required_device<speaker_sound_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<cpu_device> m_maincpu;
+ virtual void machine_start();
};
-#define LOG 0
-
-
-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
+ I/O
+***************************************************************************/
-/*
-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;
-
- 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;
+ 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();
+
+ 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);
}
+WRITE16_MEMBER(merlin_state::write_r)
+{
+ /* LEDs:
+
+ 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);
+}
-/*
- LEDs:
- R0
- R1 R2 R3
- R4 R5 R6
- R7 R8 R9
- R10
+/***************************************************************************
-When that particular R output is high, that LED is on.
-*/
+ Inputs
-WRITE16_MEMBER(merlin_state::write_r)
-{
- if (LOG)
- logerror( "write_r: write %04x\n", data );
-
- 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 ) );
-}
+***************************************************************************/
+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 )