trunk/src/mess/drivers/amaztron.c
| r243825 | r243826 | |
| 1 | | // license:BSD-3-Clause |
| 2 | | // copyright-holders:hap |
| 3 | | /*************************************************************************** |
| 4 | | |
| 5 | | Coleco Amaze-A-Tron, by Ralph Baer |
| 6 | | * TMS1100 MCU, labeled MP3405(die label too) |
| 7 | | |
| 8 | | This is an electronic board game with a selection of 8 maze games, |
| 9 | | most of them for 2 players. A 5x5 playing grid and four markers are |
| 10 | | required to play. Refer to the official manual for more information. |
| 11 | | |
| 12 | | ***************************************************************************/ |
| 13 | | |
| 14 | | #include "emu.h" |
| 15 | | #include "cpu/tms0980/tms0980.h" |
| 16 | | #include "sound/speaker.h" |
| 17 | | |
| 18 | | #include "amaztron.lh" |
| 19 | | |
| 20 | | // master clock is a single stage RC oscillator: R=33K?, C=100pf, |
| 21 | | // according to the TMS 1000 series data manual this is around 350kHz |
| 22 | | #define MASTER_CLOCK (350000) |
| 23 | | |
| 24 | | |
| 25 | | class amaztron_state : public driver_device |
| 26 | | { |
| 27 | | public: |
| 28 | | amaztron_state(const machine_config &mconfig, device_type type, const char *tag) |
| 29 | | : driver_device(mconfig, type, tag), |
| 30 | | m_maincpu(*this, "maincpu"), |
| 31 | | m_button_matrix(*this, "IN"), |
| 32 | | m_speaker(*this, "speaker") |
| 33 | | { } |
| 34 | | |
| 35 | | required_device<cpu_device> m_maincpu; |
| 36 | | required_ioport_array<6> m_button_matrix; |
| 37 | | required_device<speaker_sound_device> m_speaker; |
| 38 | | |
| 39 | | UINT16 m_r; |
| 40 | | UINT16 m_o; |
| 41 | | |
| 42 | | DECLARE_READ8_MEMBER(read_k); |
| 43 | | DECLARE_WRITE16_MEMBER(write_o); |
| 44 | | DECLARE_WRITE16_MEMBER(write_r); |
| 45 | | |
| 46 | | void leds_update(); |
| 47 | | |
| 48 | | virtual void machine_start(); |
| 49 | | }; |
| 50 | | |
| 51 | | |
| 52 | | |
| 53 | | /*************************************************************************** |
| 54 | | |
| 55 | | I/O |
| 56 | | |
| 57 | | ***************************************************************************/ |
| 58 | | |
| 59 | | void amaztron_state::leds_update() |
| 60 | | { |
| 61 | | for (int i = 0; i < 2; i++) |
| 62 | | if (m_r >> (i + 8) & 1) |
| 63 | | output_set_digit_value(i, m_o); |
| 64 | | } |
| 65 | | |
| 66 | | READ8_MEMBER(amaztron_state::read_k) |
| 67 | | { |
| 68 | | UINT8 k = 0; |
| 69 | | |
| 70 | | // read selected button rows |
| 71 | | for (int i = 0; i < 6; i++) |
| 72 | | { |
| 73 | | if (m_r >> i & 1) |
| 74 | | k |= m_button_matrix[i]->read(); |
| 75 | | } |
| 76 | | |
| 77 | | // the 5th row is tied to K4+K8 |
| 78 | | if (k & 0x10) k |= 0xc; |
| 79 | | return k & 0xf; |
| 80 | | } |
| 81 | | |
| 82 | | WRITE16_MEMBER(amaztron_state::write_r) |
| 83 | | { |
| 84 | | // R0-R5: input mux |
| 85 | | // R6,R7: lamps |
| 86 | | output_set_lamp_value(0, data >> 6 & 1); |
| 87 | | output_set_lamp_value(1, data >> 7 & 1); |
| 88 | | |
| 89 | | // R8,R9: select digit |
| 90 | | m_r = data; |
| 91 | | leds_update(); |
| 92 | | |
| 93 | | // R10: speaker out |
| 94 | | m_speaker->level_w(data >> 10 & 1); |
| 95 | | } |
| 96 | | |
| 97 | | WRITE16_MEMBER(amaztron_state::write_o) |
| 98 | | { |
| 99 | | // O0-O6: digit segments |
| 100 | | // O7: N/C |
| 101 | | m_o = data & 0x7f; |
| 102 | | leds_update(); |
| 103 | | } |
| 104 | | |
| 105 | | |
| 106 | | |
| 107 | | /*************************************************************************** |
| 108 | | |
| 109 | | Inputs |
| 110 | | |
| 111 | | ***************************************************************************/ |
| 112 | | |
| 113 | | static INPUT_PORTS_START( amaztron ) |
| 114 | | PORT_START("IN.0") // R0 |
| 115 | | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_NAME("Button 1") |
| 116 | | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_NAME("Button 6") |
| 117 | | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("Button 11") |
| 118 | | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_A) PORT_NAME("Button 16") |
| 119 | | PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Z) PORT_NAME("Button 21") |
| 120 | | |
| 121 | | PORT_START("IN.1") // R1 |
| 122 | | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_NAME("Button 2") |
| 123 | | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_7) PORT_NAME("Button 7") |
| 124 | | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("Button 12") |
| 125 | | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_NAME("Button 17") |
| 126 | | PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_X) PORT_NAME("Button 22") |
| 127 | | |
| 128 | | PORT_START("IN.2") // R2 |
| 129 | | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("Button 3") |
| 130 | | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) PORT_NAME("Button 8") |
| 131 | | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Button 13") |
| 132 | | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_D) PORT_NAME("Button 18") |
| 133 | | PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_C) PORT_NAME("Button 23") |
| 134 | | |
| 135 | | PORT_START("IN.3") // R3 |
| 136 | | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_NAME("Button 4") |
| 137 | | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_9) PORT_NAME("Button 9") |
| 138 | | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_NAME("Button 14") |
| 139 | | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F) PORT_NAME("Button 19") |
| 140 | | PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_V) PORT_NAME("Button 24") |
| 141 | | |
| 142 | | PORT_START("IN.4") // R4 |
| 143 | | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_NAME("Button 5") |
| 144 | | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_0) PORT_NAME("Button 10") |
| 145 | | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Button 15") |
| 146 | | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_G) PORT_NAME("Button 20") |
| 147 | | PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_B) PORT_NAME("Button 25") |
| 148 | | |
| 149 | | PORT_START("IN.5") // R5 |
| 150 | | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_M) PORT_NAME("Game Select") |
| 151 | | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_N) PORT_NAME("Game Start") |
| 152 | | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_UNUSED) |
| 153 | | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_UNUSED) |
| 154 | | PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_UNUSED) |
| 155 | | INPUT_PORTS_END |
| 156 | | |
| 157 | | |
| 158 | | |
| 159 | | /*************************************************************************** |
| 160 | | |
| 161 | | Machine Config |
| 162 | | |
| 163 | | ***************************************************************************/ |
| 164 | | |
| 165 | | void amaztron_state::machine_start() |
| 166 | | { |
| 167 | | m_r = 0; |
| 168 | | m_o = 0; |
| 169 | | |
| 170 | | save_item(NAME(m_r)); |
| 171 | | save_item(NAME(m_o)); |
| 172 | | } |
| 173 | | |
| 174 | | |
| 175 | | static MACHINE_CONFIG_START( amaztron, amaztron_state ) |
| 176 | | |
| 177 | | /* basic machine hardware */ |
| 178 | | MCFG_CPU_ADD("maincpu", TMS1100, MASTER_CLOCK) |
| 179 | | MCFG_TMS1XXX_READ_K_CB(READ8(amaztron_state, read_k)) |
| 180 | | MCFG_TMS1XXX_WRITE_O_CB(WRITE16(amaztron_state, write_o)) |
| 181 | | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(amaztron_state, write_r)) |
| 182 | | |
| 183 | | MCFG_DEFAULT_LAYOUT(layout_amaztron) |
| 184 | | |
| 185 | | /* no video! */ |
| 186 | | |
| 187 | | /* sound hardware */ |
| 188 | | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 189 | | MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) |
| 190 | | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 191 | | MACHINE_CONFIG_END |
| 192 | | |
| 193 | | |
| 194 | | |
| 195 | | /*************************************************************************** |
| 196 | | |
| 197 | | Game driver(s) |
| 198 | | |
| 199 | | ***************************************************************************/ |
| 200 | | |
| 201 | | ROM_START( amaztron ) |
| 202 | | ROM_REGION( 0x0800, "maincpu", 0 ) |
| 203 | | ROM_LOAD( "tms1100nll_mp3405", 0x0000, 0x0800, CRC(9cbc0009) SHA1(17772681271b59280687492f37fa0859998f041d) ) |
| 204 | | |
| 205 | | ROM_REGION( 867, "maincpu:mpla", 0 ) |
| 206 | | ROM_LOAD( "tms1100_amaztron_mpla.pla", 0, 867, CRC(03574895) SHA1(04407cabfb3adee2ee5e4218612cb06c12c540f4) ) |
| 207 | | ROM_REGION( 365, "maincpu:opla", 0 ) |
| 208 | | ROM_LOAD( "tms1100_amaztron_opla.pla", 0, 365, CRC(f3875384) SHA1(3c256a3db4f0aa9d93cf78124db39f4cbdc57e4a) ) |
| 209 | | ROM_END |
| 210 | | |
| 211 | | |
| 212 | | CONS( 1979, amaztron, 0, 0, amaztron, amaztron, driver_device, 0, "Coleco", "Amaze-A-Tron", GAME_SUPPORTS_SAVE ) |
trunk/src/mess/drivers/comp4.c
| r243825 | r243826 | |
| 1 | | // license:BSD-3-Clause |
| 2 | | // copyright-holders:hap |
| 3 | | /*************************************************************************** |
| 4 | | |
| 5 | | Milton Bradley Comp IV |
| 6 | | * TMC0904NL CP0904A (die labeled 4A0970D-04A) |
| 7 | | |
| 8 | | This is small tabletop Mastermind game; a code-breaking game where the player |
| 9 | | needs to find out the correct sequence of colours (numbers in our case). |
| 10 | | It is known as Logic 5 in Europe, and as Pythaligoras in Japan. |
| 11 | | |
| 12 | | Press the R key to start, followed by a set of unique numbers and E. |
| 13 | | Refer to the official manual for more information. |
| 14 | | |
| 15 | | |
| 16 | | TODO: |
| 17 | | - MCU clock is unknown |
| 18 | | |
| 19 | | ***************************************************************************/ |
| 20 | | |
| 21 | | #include "emu.h" |
| 22 | | #include "cpu/tms0980/tms0980.h" |
| 23 | | |
| 24 | | #include "comp4.lh" |
| 25 | | |
| 26 | | // master clock is unknown, the value below is an approximation |
| 27 | | #define MASTER_CLOCK (250000) |
| 28 | | |
| 29 | | |
| 30 | | class comp4_state : public driver_device |
| 31 | | { |
| 32 | | public: |
| 33 | | comp4_state(const machine_config &mconfig, device_type type, const char *tag) |
| 34 | | : driver_device(mconfig, type, tag), |
| 35 | | m_maincpu(*this, "maincpu"), |
| 36 | | m_button_matrix(*this, "IN") |
| 37 | | { } |
| 38 | | |
| 39 | | required_device<cpu_device> m_maincpu; |
| 40 | | required_ioport_array<3> m_button_matrix; |
| 41 | | |
| 42 | | UINT16 m_o; |
| 43 | | |
| 44 | | UINT16 m_display_state; |
| 45 | | UINT8 m_display_decay[0x10]; |
| 46 | | |
| 47 | | DECLARE_READ8_MEMBER(read_k); |
| 48 | | DECLARE_WRITE16_MEMBER(write_o); |
| 49 | | DECLARE_WRITE16_MEMBER(write_r); |
| 50 | | |
| 51 | | TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick); |
| 52 | | void display_update(); |
| 53 | | |
| 54 | | virtual void machine_start(); |
| 55 | | }; |
| 56 | | |
| 57 | | |
| 58 | | /*************************************************************************** |
| 59 | | |
| 60 | | LED Display |
| 61 | | |
| 62 | | ***************************************************************************/ |
| 63 | | |
| 64 | | // The device strobes the outputs very fast, it is unnoticeable to the user. |
| 65 | | // To prevent flickering here, we need to simulate a decay. |
| 66 | | |
| 67 | | // decay time, in steps of 1ms |
| 68 | | #define DISPLAY_DECAY_TIME 25 |
| 69 | | |
| 70 | | void comp4_state::display_update() |
| 71 | | { |
| 72 | | for (int i = 0; i < 0x10; i++) |
| 73 | | { |
| 74 | | // turn on powered segments |
| 75 | | if (m_display_state >> i & 1) |
| 76 | | m_display_decay[i] = DISPLAY_DECAY_TIME; |
| 77 | | |
| 78 | | // send to output |
| 79 | | output_set_lamp_value(i, (m_display_decay[i] != 0) ? 1 : 0); |
| 80 | | } |
| 81 | | } |
| 82 | | |
| 83 | | TIMER_DEVICE_CALLBACK_MEMBER(comp4_state::display_decay_tick) |
| 84 | | { |
| 85 | | // slowly turn off unpowered segments |
| 86 | | for (int i = 0; i < 0x10; i++) |
| 87 | | if (!(m_display_state >> i & 1) && m_display_decay[i]) |
| 88 | | m_display_decay[i]--; |
| 89 | | |
| 90 | | display_update(); |
| 91 | | } |
| 92 | | |
| 93 | | |
| 94 | | |
| 95 | | /*************************************************************************** |
| 96 | | |
| 97 | | I/O |
| 98 | | |
| 99 | | ***************************************************************************/ |
| 100 | | |
| 101 | | READ8_MEMBER(comp4_state::read_k) |
| 102 | | { |
| 103 | | UINT8 k = 0; |
| 104 | | |
| 105 | | // read selected button rows |
| 106 | | for (int i = 0; i < 3; i++) |
| 107 | | if (m_o >> (i+1) & 1) |
| 108 | | k |= m_button_matrix[i]->read(); |
| 109 | | |
| 110 | | return k; |
| 111 | | } |
| 112 | | |
| 113 | | WRITE16_MEMBER(comp4_state::write_r) |
| 114 | | { |
| 115 | | // LEDs: |
| 116 | | // R4 R9 |
| 117 | | // R10! R8 |
| 118 | | // R2 R7 |
| 119 | | // R1 R6 |
| 120 | | // R0 R5 |
| 121 | | m_display_state = data; |
| 122 | | display_update(); |
| 123 | | } |
| 124 | | |
| 125 | | WRITE16_MEMBER(comp4_state::write_o) |
| 126 | | { |
| 127 | | // O0: LEDs common (always writes 1) |
| 128 | | // O1-O3: input mux |
| 129 | | // other bits: N/C |
| 130 | | m_o = data; |
| 131 | | } |
| 132 | | |
| 133 | | |
| 134 | | |
| 135 | | /*************************************************************************** |
| 136 | | |
| 137 | | Inputs |
| 138 | | |
| 139 | | ***************************************************************************/ |
| 140 | | |
| 141 | | static INPUT_PORTS_START( comp4 ) |
| 142 | | PORT_START("IN.0") // O1 |
| 143 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("R") |
| 144 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1") |
| 145 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4") |
| 146 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7") |
| 147 | | |
| 148 | | PORT_START("IN.1") // O2 |
| 149 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0") |
| 150 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2") |
| 151 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5") |
| 152 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8") |
| 153 | | |
| 154 | | PORT_START("IN.2") // O3 |
| 155 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("E") |
| 156 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3") |
| 157 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6") |
| 158 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9") |
| 159 | | INPUT_PORTS_END |
| 160 | | |
| 161 | | |
| 162 | | |
| 163 | | /*************************************************************************** |
| 164 | | |
| 165 | | Machine Config |
| 166 | | |
| 167 | | ***************************************************************************/ |
| 168 | | |
| 169 | | void comp4_state::machine_start() |
| 170 | | { |
| 171 | | // zerofill |
| 172 | | m_display_state = 0; |
| 173 | | memset(m_display_decay, 0, sizeof(m_display_decay)); |
| 174 | | |
| 175 | | m_o = 0; |
| 176 | | |
| 177 | | // register for savestates |
| 178 | | save_item(NAME(m_display_state)); |
| 179 | | save_item(NAME(m_display_decay)); |
| 180 | | |
| 181 | | save_item(NAME(m_o)); |
| 182 | | } |
| 183 | | |
| 184 | | |
| 185 | | static MACHINE_CONFIG_START( comp4, comp4_state ) |
| 186 | | |
| 187 | | /* basic machine hardware */ |
| 188 | | MCFG_CPU_ADD("maincpu", TMS0970, MASTER_CLOCK) |
| 189 | | MCFG_TMS1XXX_READ_K_CB(READ8(comp4_state, read_k)) |
| 190 | | MCFG_TMS1XXX_WRITE_O_CB(WRITE16(comp4_state, write_o)) |
| 191 | | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(comp4_state, write_r)) |
| 192 | | |
| 193 | | MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", comp4_state, display_decay_tick, attotime::from_msec(1)) |
| 194 | | |
| 195 | | MCFG_DEFAULT_LAYOUT(layout_comp4) |
| 196 | | |
| 197 | | /* no video! */ |
| 198 | | |
| 199 | | /* no sound! */ |
| 200 | | MACHINE_CONFIG_END |
| 201 | | |
| 202 | | |
| 203 | | |
| 204 | | /*************************************************************************** |
| 205 | | |
| 206 | | Game driver(s) |
| 207 | | |
| 208 | | ***************************************************************************/ |
| 209 | | |
| 210 | | ROM_START( comp4 ) |
| 211 | | ROM_REGION( 0x0400, "maincpu", 0 ) |
| 212 | | ROM_LOAD( "tmc0904nl_cp0904a", 0x0000, 0x0400, CRC(6233ee1b) SHA1(738e109b38c97804b4ec52bed80b00a8634ad453) ) |
| 213 | | |
| 214 | | ROM_REGION( 782, "maincpu:ipla", 0 ) |
| 215 | | ROM_LOAD( "tms0970_default_ipla.pla", 0, 782, CRC(e038fc44) SHA1(dfc280f6d0a5828d1bb14fcd59ac29caf2c2d981) ) |
| 216 | | ROM_REGION( 860, "maincpu:mpla", 0 ) |
| 217 | | ROM_LOAD( "tms0970_comp4_mpla.pla", 0, 860, CRC(ee9d7d9e) SHA1(25484e18f6a07f7cdb21a07220e2f2a82fadfe7b) ) |
| 218 | | ROM_REGION( 352, "maincpu:opla", 0 ) |
| 219 | | ROM_LOAD( "tms0970_comp4_opla.pla", 0, 352, CRC(a0f887d1) SHA1(3c666663d484d5bed81e1014f8715aab8a3d489f) ) |
| 220 | | ROM_REGION( 157, "maincpu:spla", 0 ) |
| 221 | | ROM_LOAD( "tms0970_comp4_spla.pla", 0, 157, CRC(e5bddd90) SHA1(4b1c6512c70e5bcd23c2dbf0c88cd8aa2c632a10) ) |
| 222 | | ROM_END |
| 223 | | |
| 224 | | |
| 225 | | CONS( 1977, comp4, 0, 0, comp4, comp4, driver_device, 0, "Milton Bradley", "Comp IV", GAME_SUPPORTS_SAVE | GAME_NO_SOUND_HW ) |
trunk/src/mess/drivers/hh_tms1k.c
| r243825 | r243826 | |
| 13 | 13 | #include "cpu/tms0980/tms0980.h" |
| 14 | 14 | #include "sound/speaker.h" |
| 15 | 15 | |
| 16 | #include "amaztron.lh" |
| 16 | 17 | #include "ebball.lh" |
| 18 | #include "comp4.lh" |
| 19 | #include "simon.lh" |
| 17 | 20 | #include "tc4.lh" |
| 18 | 21 | |
| 19 | 22 | |
| r243825 | r243826 | |
| 25 | 28 | m_maincpu(*this, "maincpu"), |
| 26 | 29 | m_inp_matrix(*this, "IN"), |
| 27 | 30 | m_speaker(*this, "speaker"), |
| 28 | | m_display_maxy(0), |
| 31 | m_display_maxy(1), |
| 29 | 32 | m_display_maxx(0), |
| 30 | 33 | m_display_wait(50) |
| 31 | 34 | { } |
| r243825 | r243826 | |
| 46 | 49 | UINT32 m_display_cache[0x20]; |
| 47 | 50 | UINT8 m_display_decay[0x20][0x20]; |
| 48 | 51 | UINT16 m_7seg_mask[0x20]; |
| 52 | |
| 53 | TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick); |
| 54 | bool index_is_7segled(int index); |
| 55 | void display_update(); |
| 49 | 56 | |
| 50 | 57 | UINT8 read_inputs(int columns); |
| 51 | 58 | |
| 52 | 59 | // game-specific handlers |
| 60 | void amaztron_display(); |
| 61 | DECLARE_READ8_MEMBER(amaztron_read_k); |
| 62 | DECLARE_WRITE16_MEMBER(amaztron_write_o); |
| 63 | DECLARE_WRITE16_MEMBER(amaztron_write_r); |
| 64 | |
| 53 | 65 | void tc4_display(); |
| 54 | 66 | DECLARE_READ8_MEMBER(tc4_read_k); |
| 55 | 67 | DECLARE_WRITE16_MEMBER(tc4_write_o); |
| 56 | 68 | DECLARE_WRITE16_MEMBER(tc4_write_r); |
| 57 | 69 | |
| 58 | | TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick); |
| 59 | | bool index_is_7segled(int index); |
| 60 | | void display_update(); |
| 70 | DECLARE_READ8_MEMBER(comp4_read_k); |
| 71 | DECLARE_WRITE16_MEMBER(comp4_write_o); |
| 72 | DECLARE_WRITE16_MEMBER(comp4_write_r); |
| 61 | 73 | |
| 74 | DECLARE_READ8_MEMBER(simon_read_k); |
| 75 | DECLARE_WRITE16_MEMBER(simon_write_o); |
| 76 | DECLARE_WRITE16_MEMBER(simon_write_r); |
| 62 | 77 | |
| 63 | 78 | virtual void machine_start(); |
| 64 | 79 | }; |
| r243825 | r243826 | |
| 172 | 187 | |
| 173 | 188 | /*************************************************************************** |
| 174 | 189 | |
| 190 | Coleco Amaze-A-Tron, by Ralph Baer |
| 191 | * TMS1100 MCU, labeled MP3405(die label too) |
| 192 | |
| 193 | This is an electronic board game with a selection of 8 maze games, |
| 194 | most of them for 2 players. A 5x5 playing grid and four markers are |
| 195 | required to play. Refer to the official manual for more information. |
| 196 | |
| 197 | ***************************************************************************/ |
| 198 | |
| 199 | |
| 200 | void hh_tms1k_state::amaztron_display() |
| 201 | { |
| 202 | m_display_maxy = 3; |
| 203 | m_display_maxx = 8; |
| 204 | |
| 205 | // R8,R9: select digit |
| 206 | for (int y = 0; y < 2; y++) |
| 207 | { |
| 208 | m_7seg_mask[y] = 0x7f; |
| 209 | m_display_state[y] = (m_r >> (y + 8) & 1) ? m_o : 0; |
| 210 | } |
| 211 | |
| 212 | // R6,R7: lamps -> lamp20, lamp21 |
| 213 | m_display_state[2] = m_r >> 6 & 3; |
| 214 | |
| 215 | display_update(); |
| 216 | } |
| 217 | |
| 218 | READ8_MEMBER(hh_tms1k_state::amaztron_read_k) |
| 219 | { |
| 220 | UINT8 k = read_inputs(6); |
| 221 | |
| 222 | // the 5th column is tied to K4+K8 |
| 223 | if (k & 0x10) k |= 0xc; |
| 224 | return k & 0xf; |
| 225 | } |
| 226 | |
| 227 | WRITE16_MEMBER(hh_tms1k_state::amaztron_write_r) |
| 228 | { |
| 229 | // R0-R5: input mux |
| 230 | m_inp_mux = data & 0x3f; |
| 231 | |
| 232 | // R10: speaker out |
| 233 | m_speaker->level_w(data >> 10 & 1); |
| 234 | |
| 235 | // other bits: |
| 236 | m_r = data; |
| 237 | amaztron_display(); |
| 238 | } |
| 239 | |
| 240 | WRITE16_MEMBER(hh_tms1k_state::amaztron_write_o) |
| 241 | { |
| 242 | // O0-O6: digit segments |
| 243 | // O7: N/C |
| 244 | m_o = data & 0x7f; |
| 245 | amaztron_display(); |
| 246 | } |
| 247 | |
| 248 | |
| 249 | static INPUT_PORTS_START( amaztron ) |
| 250 | PORT_START("IN.0") // R0 |
| 251 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_NAME("Button 1") |
| 252 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_NAME("Button 6") |
| 253 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("Button 11") |
| 254 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_A) PORT_NAME("Button 16") |
| 255 | PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Z) PORT_NAME("Button 21") |
| 256 | |
| 257 | PORT_START("IN.1") // R1 |
| 258 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_NAME("Button 2") |
| 259 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_7) PORT_NAME("Button 7") |
| 260 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("Button 12") |
| 261 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_NAME("Button 17") |
| 262 | PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_X) PORT_NAME("Button 22") |
| 263 | |
| 264 | PORT_START("IN.2") // R2 |
| 265 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("Button 3") |
| 266 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) PORT_NAME("Button 8") |
| 267 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Button 13") |
| 268 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_D) PORT_NAME("Button 18") |
| 269 | PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_C) PORT_NAME("Button 23") |
| 270 | |
| 271 | PORT_START("IN.3") // R3 |
| 272 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_NAME("Button 4") |
| 273 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_9) PORT_NAME("Button 9") |
| 274 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_NAME("Button 14") |
| 275 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F) PORT_NAME("Button 19") |
| 276 | PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_V) PORT_NAME("Button 24") |
| 277 | |
| 278 | PORT_START("IN.4") // R4 |
| 279 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_NAME("Button 5") |
| 280 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_0) PORT_NAME("Button 10") |
| 281 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Button 15") |
| 282 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_G) PORT_NAME("Button 20") |
| 283 | PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_B) PORT_NAME("Button 25") |
| 284 | |
| 285 | PORT_START("IN.5") // R5 |
| 286 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_M) PORT_NAME("Game Select") |
| 287 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_N) PORT_NAME("Game Start") |
| 288 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_UNUSED) |
| 289 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_UNUSED) |
| 290 | PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_UNUSED) |
| 291 | INPUT_PORTS_END |
| 292 | |
| 293 | |
| 294 | static MACHINE_CONFIG_START( amaztron, hh_tms1k_state ) |
| 295 | |
| 296 | /* basic machine hardware */ |
| 297 | MCFG_CPU_ADD("maincpu", TMS1100, 350000) // RC osc. R=33K?, C=100pf -> ~350kHz |
| 298 | MCFG_TMS1XXX_READ_K_CB(READ8(hh_tms1k_state, amaztron_read_k)) |
| 299 | MCFG_TMS1XXX_WRITE_O_CB(WRITE16(hh_tms1k_state, amaztron_write_o)) |
| 300 | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, amaztron_write_r)) |
| 301 | |
| 302 | MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) |
| 303 | |
| 304 | MCFG_DEFAULT_LAYOUT(layout_amaztron) |
| 305 | |
| 306 | /* no video! */ |
| 307 | |
| 308 | /* sound hardware */ |
| 309 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 310 | MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) |
| 311 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 312 | MACHINE_CONFIG_END |
| 313 | |
| 314 | |
| 315 | |
| 316 | |
| 317 | /*************************************************************************** |
| 318 | |
| 175 | 319 | Coleco Total Control 4 |
| 176 | 320 | * TMS1400NLL MP7334-N2 (die labeled MP7334) |
| 177 | 321 | |
| r243825 | r243826 | |
| 328 | 472 | |
| 329 | 473 | /*************************************************************************** |
| 330 | 474 | |
| 475 | Milton Bradley Comp IV |
| 476 | * TMC0904NL CP0904A (die labeled 4A0970D-04A) |
| 477 | |
| 478 | This is small tabletop Mastermind game; a code-breaking game where the player |
| 479 | needs to find out the correct sequence of colours (numbers in our case). |
| 480 | It is known as Logic 5 in Europe, and as Pythaligoras in Japan. |
| 481 | |
| 482 | Press the R key to start, followed by a set of unique numbers and E. |
| 483 | Refer to the official manual for more information. |
| 484 | |
| 485 | |
| 486 | TODO: |
| 487 | - MCU clock is unknown |
| 488 | |
| 489 | ***************************************************************************/ |
| 490 | |
| 491 | READ8_MEMBER(hh_tms1k_state::comp4_read_k) |
| 492 | { |
| 493 | return read_inputs(3); |
| 494 | } |
| 495 | |
| 496 | WRITE16_MEMBER(hh_tms1k_state::comp4_write_r) |
| 497 | { |
| 498 | // leds: |
| 499 | // R4 R9 |
| 500 | // R10! R8 |
| 501 | // R2 R7 |
| 502 | // R1 R6 |
| 503 | // R0 R5 |
| 504 | m_display_maxx = 11; |
| 505 | m_display_state[0] = data; |
| 506 | display_update(); |
| 507 | } |
| 508 | |
| 509 | WRITE16_MEMBER(hh_tms1k_state::comp4_write_o) |
| 510 | { |
| 511 | // O0: leds common (always writes 1) |
| 512 | // O1-O3: input mux |
| 513 | // other bits: N/C |
| 514 | m_inp_mux = data >> 1 & 7; |
| 515 | } |
| 516 | |
| 517 | |
| 518 | static INPUT_PORTS_START( comp4 ) |
| 519 | PORT_START("IN.0") // O1 |
| 520 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("R") |
| 521 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1") |
| 522 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4") |
| 523 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7") |
| 524 | |
| 525 | PORT_START("IN.1") // O2 |
| 526 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0") |
| 527 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2") |
| 528 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5") |
| 529 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8") |
| 530 | |
| 531 | PORT_START("IN.2") // O3 |
| 532 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("E") |
| 533 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3") |
| 534 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6") |
| 535 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9") |
| 536 | INPUT_PORTS_END |
| 537 | |
| 538 | |
| 539 | |
| 540 | static MACHINE_CONFIG_START( comp4, hh_tms1k_state ) |
| 541 | |
| 542 | /* basic machine hardware */ |
| 543 | MCFG_CPU_ADD("maincpu", TMS0970, 250000) // approximation - unknown freq |
| 544 | MCFG_TMS1XXX_READ_K_CB(READ8(hh_tms1k_state, comp4_read_k)) |
| 545 | MCFG_TMS1XXX_WRITE_O_CB(WRITE16(hh_tms1k_state, comp4_write_o)) |
| 546 | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, comp4_write_r)) |
| 547 | |
| 548 | MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) |
| 549 | |
| 550 | MCFG_DEFAULT_LAYOUT(layout_comp4) |
| 551 | |
| 552 | /* no video! */ |
| 553 | |
| 554 | /* no sound! */ |
| 555 | MACHINE_CONFIG_END |
| 556 | |
| 557 | |
| 558 | /*************************************************************************** |
| 559 | |
| 560 | Milton Bradley Simon, created by Ralph Baer |
| 561 | |
| 562 | Revision A hardware: |
| 563 | * TMS1000 (has internal ROM), DS75494 lamp driver |
| 564 | |
| 565 | Newer revisions have a smaller 16-pin MB4850 chip instead of the TMS1000. |
| 566 | This one has been decapped too, but we couldn't find an internal ROM. |
| 567 | It is possibly a cost-reduced custom ASIC specifically for Simon. |
| 568 | |
| 569 | Other games assumed to be on similar hardware: |
| 570 | - Pocket Simon, but there's a chance it only exists with MB4850 chip |
| 571 | - Super Simon (TMS1100) |
| 572 | |
| 573 | ***************************************************************************/ |
| 574 | |
| 575 | |
| 576 | |
| 577 | |
| 578 | |
| 579 | /*************************************************************************** |
| 580 | |
| 581 | I/O |
| 582 | |
| 583 | ***************************************************************************/ |
| 584 | |
| 585 | READ8_MEMBER(hh_tms1k_state::simon_read_k) |
| 586 | { |
| 587 | return read_inputs(4); |
| 588 | } |
| 589 | |
| 590 | WRITE16_MEMBER(hh_tms1k_state::simon_write_r) |
| 591 | { |
| 592 | // R4-R8 go through an 75494 IC first: |
| 593 | // R4 -> 75494 IN6 -> green lamp |
| 594 | // R5 -> 75494 IN3 -> red lamp |
| 595 | // R6 -> 75494 IN5 -> yellow lamp |
| 596 | // R7 -> 75494 IN2 -> blue lamp |
| 597 | m_display_maxx = 4; |
| 598 | m_display_state[0] = data >> 4 & 0xf; |
| 599 | display_update(); |
| 600 | |
| 601 | // R8 -> 75494 IN0 -> speaker |
| 602 | m_speaker->level_w(data >> 8 & 1); |
| 603 | |
| 604 | // R0,R1,R2,R9: input mux |
| 605 | // R3: GND |
| 606 | // other bits: N/C |
| 607 | m_inp_mux = (data & 7) | (data >> 6 & 8); |
| 608 | } |
| 609 | |
| 610 | WRITE16_MEMBER(hh_tms1k_state::simon_write_o) |
| 611 | { |
| 612 | // N/C |
| 613 | } |
| 614 | |
| 615 | |
| 616 | static INPUT_PORTS_START( simon ) |
| 617 | PORT_START("IN.0") // R0 |
| 618 | PORT_CONFNAME( 0x07, 0x02, "Game Select") |
| 619 | PORT_CONFSETTING( 0x02, "1" ) |
| 620 | PORT_CONFSETTING( 0x01, "2" ) |
| 621 | PORT_CONFSETTING( 0x04, "3" ) |
| 622 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 623 | |
| 624 | PORT_START("IN.1") // R1 |
| 625 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("Green Button") |
| 626 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("Red Button") |
| 627 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_NAME("Yellow Button") |
| 628 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_NAME("Blue Button") |
| 629 | |
| 630 | PORT_START("IN.2") // R2 |
| 631 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("Start") |
| 632 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Last") |
| 633 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Longest") |
| 634 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 635 | |
| 636 | PORT_START("IN.3") // R9 |
| 637 | PORT_CONFNAME( 0x0f, 0x01, "Skill Level") |
| 638 | PORT_CONFSETTING( 0x02, "1" ) |
| 639 | PORT_CONFSETTING( 0x04, "2" ) |
| 640 | PORT_CONFSETTING( 0x08, "3" ) |
| 641 | PORT_CONFSETTING( 0x01, "4" ) |
| 642 | INPUT_PORTS_END |
| 643 | |
| 644 | |
| 645 | static MACHINE_CONFIG_START( simon, hh_tms1k_state ) |
| 646 | |
| 647 | /* basic machine hardware */ |
| 648 | MCFG_CPU_ADD("maincpu", TMS1000, 350000) // RC osc. R=33K, C=100pf -> ~350kHz |
| 649 | MCFG_TMS1XXX_READ_K_CB(READ8(hh_tms1k_state, simon_read_k)) |
| 650 | MCFG_TMS1XXX_WRITE_O_CB(WRITE16(hh_tms1k_state, simon_write_o)) |
| 651 | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, simon_write_r)) |
| 652 | |
| 653 | MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) |
| 654 | |
| 655 | MCFG_DEFAULT_LAYOUT(layout_simon) |
| 656 | |
| 657 | /* no video! */ |
| 658 | |
| 659 | /* sound hardware */ |
| 660 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 661 | MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) |
| 662 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 663 | MACHINE_CONFIG_END |
| 664 | |
| 665 | |
| 666 | |
| 667 | |
| 668 | |
| 669 | /*************************************************************************** |
| 670 | |
| 331 | 671 | Entex Baseball |
| 332 | 672 | * TMS1000NLP MP0914 (die labeled MP0914A) |
| 333 | 673 | |
| r243825 | r243826 | |
| 361 | 701 | |
| 362 | 702 | ***************************************************************************/ |
| 363 | 703 | |
| 704 | |
| 705 | ROM_START( amaztron ) |
| 706 | ROM_REGION( 0x0800, "maincpu", 0 ) |
| 707 | ROM_LOAD( "tms1100nll_mp3405", 0x0000, 0x0800, CRC(9cbc0009) SHA1(17772681271b59280687492f37fa0859998f041d) ) |
| 708 | |
| 709 | ROM_REGION( 867, "maincpu:mpla", 0 ) |
| 710 | ROM_LOAD( "tms1100_amaztron_mpla.pla", 0, 867, CRC(03574895) SHA1(04407cabfb3adee2ee5e4218612cb06c12c540f4) ) |
| 711 | ROM_REGION( 365, "maincpu:opla", 0 ) |
| 712 | ROM_LOAD( "tms1100_amaztron_opla.pla", 0, 365, CRC(f3875384) SHA1(3c256a3db4f0aa9d93cf78124db39f4cbdc57e4a) ) |
| 713 | ROM_END |
| 714 | |
| 715 | |
| 716 | |
| 717 | |
| 364 | 718 | ROM_START( tc4 ) |
| 365 | 719 | ROM_REGION( 0x1000, "maincpu", 0 ) |
| 366 | 720 | ROM_LOAD( "tms1400nll_mp7334", 0x0000, 0x1000, CRC(923f3821) SHA1(a9ae342d7ff8dae1dedcd1e4984bcfae68586581) ) |
| r243825 | r243826 | |
| 383 | 737 | ROM_END |
| 384 | 738 | |
| 385 | 739 | |
| 740 | ROM_START( comp4 ) |
| 741 | ROM_REGION( 0x0400, "maincpu", 0 ) |
| 742 | ROM_LOAD( "tmc0904nl_cp0904a", 0x0000, 0x0400, CRC(6233ee1b) SHA1(738e109b38c97804b4ec52bed80b00a8634ad453) ) |
| 743 | |
| 744 | ROM_REGION( 782, "maincpu:ipla", 0 ) |
| 745 | ROM_LOAD( "tms0970_default_ipla.pla", 0, 782, CRC(e038fc44) SHA1(dfc280f6d0a5828d1bb14fcd59ac29caf2c2d981) ) |
| 746 | ROM_REGION( 860, "maincpu:mpla", 0 ) |
| 747 | ROM_LOAD( "tms0970_comp4_mpla.pla", 0, 860, CRC(ee9d7d9e) SHA1(25484e18f6a07f7cdb21a07220e2f2a82fadfe7b) ) |
| 748 | ROM_REGION( 352, "maincpu:opla", 0 ) |
| 749 | ROM_LOAD( "tms0970_comp4_opla.pla", 0, 352, CRC(a0f887d1) SHA1(3c666663d484d5bed81e1014f8715aab8a3d489f) ) |
| 750 | ROM_REGION( 157, "maincpu:spla", 0 ) |
| 751 | ROM_LOAD( "tms0970_comp4_spla.pla", 0, 157, CRC(e5bddd90) SHA1(4b1c6512c70e5bcd23c2dbf0c88cd8aa2c632a10) ) |
| 752 | ROM_END |
| 753 | |
| 754 | |
| 755 | ROM_START( simon ) |
| 756 | ROM_REGION( 0x0400, "maincpu", 0 ) |
| 757 | ROM_LOAD( "tms1000.u1", 0x0000, 0x0400, CRC(9961719d) SHA1(35dddb018a8a2b31f377ab49c1f0cb76951b81c0) ) |
| 758 | |
| 759 | ROM_REGION( 867, "maincpu:mpla", 0 ) |
| 760 | ROM_LOAD( "tms1000_simon_mpla.pla", 0, 867, CRC(52f7c1f1) SHA1(dbc2634dcb98eac173ad0209df487cad413d08a5) ) |
| 761 | ROM_REGION( 365, "maincpu:opla", 0 ) |
| 762 | ROM_LOAD( "tms1000_simon_opla.pla", 0, 365, CRC(2943c71b) SHA1(bd5bb55c57e7ba27e49c645937ec1d4e67506601) ) |
| 763 | ROM_END |
| 764 | |
| 765 | |
| 766 | |
| 767 | |
| 768 | CONS( 1979, amaztron, 0, 0, amaztron, amaztron, driver_device, 0, "Coleco", "Amaze-A-Tron", GAME_SUPPORTS_SAVE ) |
| 769 | CONS( 1981, tc4, 0, 0, tc4, tc4, driver_device, 0, "Coleco", "Total Control 4", GAME_SUPPORTS_SAVE ) |
| 770 | |
| 386 | 771 | CONS( 1979, ebball, 0, 0, ebball, ebball, driver_device, 0, "Entex", "Baseball (Entex)", GAME_SUPPORTS_SAVE | GAME_NOT_WORKING ) |
| 387 | 772 | |
| 388 | | CONS( 1981, tc4, 0, 0, tc4, tc4, driver_device, 0, "Coleco", "Total Control 4", GAME_SUPPORTS_SAVE ) |
| 773 | CONS( 1977, comp4, 0, 0, comp4, comp4, driver_device, 0, "Milton Bradley", "Comp IV", GAME_SUPPORTS_SAVE | GAME_NO_SOUND_HW ) |
| 774 | CONS( 1978, simon, 0, 0, simon, simon, driver_device, 0, "Milton Bradley", "Simon (Rev. A)", GAME_SUPPORTS_SAVE ) |
trunk/src/mess/drivers/simon.c
| r243825 | r243826 | |
| 1 | | // license:BSD-3-Clause |
| 2 | | // copyright-holders:hap |
| 3 | | /*************************************************************************** |
| 4 | | |
| 5 | | Milton Bradley Simon, created by Ralph Baer |
| 6 | | |
| 7 | | Revision A hardware: |
| 8 | | * TMS1000 (has internal ROM), DS75494 lamp driver |
| 9 | | |
| 10 | | Newer revisions have a smaller 16-pin MB4850 chip instead of the TMS1000. |
| 11 | | This one has been decapped too, but we couldn't find an internal ROM. |
| 12 | | It is possibly a cost-reduced custom ASIC specifically for Simon. |
| 13 | | |
| 14 | | Other games assumed to be on similar hardware: |
| 15 | | - Pocket Simon, but there's a chance it only exists with MB4850 chip |
| 16 | | - Super Simon (TMS1100) |
| 17 | | |
| 18 | | ***************************************************************************/ |
| 19 | | |
| 20 | | #include "emu.h" |
| 21 | | #include "cpu/tms0980/tms0980.h" |
| 22 | | #include "sound/speaker.h" |
| 23 | | |
| 24 | | #include "simon.lh" // clickable |
| 25 | | |
| 26 | | // master clock is a single stage RC oscillator: R=33K, C=100pf, |
| 27 | | // according to the TMS 1000 series data manual this is around 350kHz |
| 28 | | #define MASTER_CLOCK (350000) |
| 29 | | |
| 30 | | |
| 31 | | class simon_state : public driver_device |
| 32 | | { |
| 33 | | public: |
| 34 | | simon_state(const machine_config &mconfig, device_type type, const char *tag) |
| 35 | | : driver_device(mconfig, type, tag), |
| 36 | | m_maincpu(*this, "maincpu"), |
| 37 | | m_button_matrix(*this, "IN"), |
| 38 | | m_speaker(*this, "speaker") |
| 39 | | { } |
| 40 | | |
| 41 | | required_device<cpu_device> m_maincpu; |
| 42 | | required_ioport_array<4> m_button_matrix; |
| 43 | | required_device<speaker_sound_device> m_speaker; |
| 44 | | |
| 45 | | UINT16 m_r; |
| 46 | | |
| 47 | | DECLARE_READ8_MEMBER(read_k); |
| 48 | | DECLARE_WRITE16_MEMBER(write_o); |
| 49 | | DECLARE_WRITE16_MEMBER(write_r); |
| 50 | | |
| 51 | | virtual void machine_start(); |
| 52 | | }; |
| 53 | | |
| 54 | | |
| 55 | | /*************************************************************************** |
| 56 | | |
| 57 | | I/O |
| 58 | | |
| 59 | | ***************************************************************************/ |
| 60 | | |
| 61 | | READ8_MEMBER(simon_state::read_k) |
| 62 | | { |
| 63 | | UINT8 k = 0; |
| 64 | | |
| 65 | | // read selected button rows |
| 66 | | for (int i = 0; i < 4; i++) |
| 67 | | { |
| 68 | | const int ki[4] = { 0, 1, 2, 9 }; |
| 69 | | if (m_r >> ki[i] & 1) |
| 70 | | k |= m_button_matrix[i]->read(); |
| 71 | | } |
| 72 | | |
| 73 | | return k; |
| 74 | | } |
| 75 | | |
| 76 | | WRITE16_MEMBER(simon_state::write_r) |
| 77 | | { |
| 78 | | // R4-R8 go through an 75494 IC first: |
| 79 | | // R4 -> 75494 IN6 -> green lamp |
| 80 | | // R5 -> 75494 IN3 -> red lamp |
| 81 | | // R6 -> 75494 IN5 -> yellow lamp |
| 82 | | // R7 -> 75494 IN2 -> blue lamp |
| 83 | | for (int i = 0; i < 4; i++) |
| 84 | | output_set_lamp_value(i, data >> (4 + i) & 1); |
| 85 | | |
| 86 | | // R8 -> 75494 IN0 -> speaker |
| 87 | | m_speaker->level_w(data >> 8 & 1); |
| 88 | | |
| 89 | | // R0,R1,R2,R9: input mux |
| 90 | | // R3: GND |
| 91 | | // other bits: N/C |
| 92 | | m_r = data; |
| 93 | | } |
| 94 | | |
| 95 | | WRITE16_MEMBER(simon_state::write_o) |
| 96 | | { |
| 97 | | // N/C |
| 98 | | } |
| 99 | | |
| 100 | | |
| 101 | | |
| 102 | | /*************************************************************************** |
| 103 | | |
| 104 | | Inputs |
| 105 | | |
| 106 | | ***************************************************************************/ |
| 107 | | |
| 108 | | static INPUT_PORTS_START( simon ) |
| 109 | | PORT_START("IN.0") // R0 |
| 110 | | PORT_CONFNAME( 0x07, 0x02, "Game Select") |
| 111 | | PORT_CONFSETTING( 0x02, "1" ) |
| 112 | | PORT_CONFSETTING( 0x01, "2" ) |
| 113 | | PORT_CONFSETTING( 0x04, "3" ) |
| 114 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 115 | | |
| 116 | | PORT_START("IN.1") // R1 |
| 117 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("Green Button") |
| 118 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("Red Button") |
| 119 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_NAME("Yellow Button") |
| 120 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_NAME("Blue Button") |
| 121 | | |
| 122 | | PORT_START("IN.2") // R2 |
| 123 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("Start") |
| 124 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Last") |
| 125 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Longest") |
| 126 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 127 | | |
| 128 | | PORT_START("IN.3") // R9 |
| 129 | | PORT_CONFNAME( 0x0f, 0x01, "Skill Level") |
| 130 | | PORT_CONFSETTING( 0x02, "1" ) |
| 131 | | PORT_CONFSETTING( 0x04, "2" ) |
| 132 | | PORT_CONFSETTING( 0x08, "3" ) |
| 133 | | PORT_CONFSETTING( 0x01, "4" ) |
| 134 | | INPUT_PORTS_END |
| 135 | | |
| 136 | | |
| 137 | | |
| 138 | | /*************************************************************************** |
| 139 | | |
| 140 | | Machine Config |
| 141 | | |
| 142 | | ***************************************************************************/ |
| 143 | | |
| 144 | | void simon_state::machine_start() |
| 145 | | { |
| 146 | | m_r = 0; |
| 147 | | save_item(NAME(m_r)); |
| 148 | | } |
| 149 | | |
| 150 | | |
| 151 | | static MACHINE_CONFIG_START( simon, simon_state ) |
| 152 | | |
| 153 | | /* basic machine hardware */ |
| 154 | | MCFG_CPU_ADD("maincpu", TMS1000, MASTER_CLOCK) |
| 155 | | MCFG_TMS1XXX_READ_K_CB(READ8(simon_state, read_k)) |
| 156 | | MCFG_TMS1XXX_WRITE_O_CB(WRITE16(simon_state, write_o)) |
| 157 | | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(simon_state, write_r)) |
| 158 | | |
| 159 | | MCFG_DEFAULT_LAYOUT(layout_simon) |
| 160 | | |
| 161 | | /* no video! */ |
| 162 | | |
| 163 | | /* sound hardware */ |
| 164 | | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 165 | | MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) |
| 166 | | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 167 | | MACHINE_CONFIG_END |
| 168 | | |
| 169 | | |
| 170 | | |
| 171 | | /*************************************************************************** |
| 172 | | |
| 173 | | Game driver(s) |
| 174 | | |
| 175 | | ***************************************************************************/ |
| 176 | | |
| 177 | | ROM_START( simon ) |
| 178 | | ROM_REGION( 0x0400, "maincpu", 0 ) |
| 179 | | ROM_LOAD( "tms1000.u1", 0x0000, 0x0400, CRC(9961719d) SHA1(35dddb018a8a2b31f377ab49c1f0cb76951b81c0) ) |
| 180 | | |
| 181 | | ROM_REGION( 867, "maincpu:mpla", 0 ) |
| 182 | | ROM_LOAD( "tms1000_simon_mpla.pla", 0, 867, CRC(52f7c1f1) SHA1(dbc2634dcb98eac173ad0209df487cad413d08a5) ) |
| 183 | | ROM_REGION( 365, "maincpu:opla", 0 ) |
| 184 | | ROM_LOAD( "tms1000_simon_opla.pla", 0, 365, CRC(2943c71b) SHA1(bd5bb55c57e7ba27e49c645937ec1d4e67506601) ) |
| 185 | | ROM_END |
| 186 | | |
| 187 | | |
| 188 | | CONS( 1978, simon, 0, 0, simon, simon, driver_device, 0, "Milton Bradley", "Simon (Rev. A)", GAME_SUPPORTS_SAVE ) |