trunk/src/mess/drivers/elecdet.c
| r244626 | r244627 | |
| 1 | | // license:BSD-3-Clause |
| 2 | | // copyright-holders:hap |
| 3 | | /*************************************************************************** |
| 4 | | |
| 5 | | Ideal Electronic Detective |
| 6 | | * TMS0980NLL MP6100A (die labeled 0980B-00) |
| 7 | | hardware (and concept) is very similar to Parker Bros Stop Thief |
| 8 | | |
| 9 | | This is an electronic board game. It requires game cards with suspect info, |
| 10 | | and good old pen and paper to record game progress. To start the game, enter |
| 11 | | difficulty(1-3), then number of players(1-4), then [ENTER]. Refer to the |
| 12 | | manual for more information. |
| 13 | | |
| 14 | | |
| 15 | | TODO: |
| 16 | | - MCU clock is unknown |
| 17 | | |
| 18 | | ***************************************************************************/ |
| 19 | | |
| 20 | | #include "emu.h" |
| 21 | | #include "cpu/tms0980/tms0980.h" |
| 22 | | #include "sound/speaker.h" |
| 23 | | |
| 24 | | #include "elecdet.lh" |
| 25 | | |
| 26 | | // master clock is unknown, the value below is an approximation |
| 27 | | #define MASTER_CLOCK (425000) |
| 28 | | |
| 29 | | |
| 30 | | class elecdet_state : public driver_device |
| 31 | | { |
| 32 | | public: |
| 33 | | elecdet_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 | | m_speaker(*this, "speaker") |
| 38 | | { } |
| 39 | | |
| 40 | | required_device<cpu_device> m_maincpu; |
| 41 | | required_ioport_array<5> m_button_matrix; |
| 42 | | required_device<speaker_sound_device> m_speaker; |
| 43 | | |
| 44 | | UINT16 m_o; |
| 45 | | bool m_power_on; |
| 46 | | |
| 47 | | UINT16 m_display_state[0x10]; |
| 48 | | UINT16 m_display_cache[0x10]; |
| 49 | | UINT8 m_display_decay[0x100]; |
| 50 | | |
| 51 | | DECLARE_READ8_MEMBER(read_k); |
| 52 | | DECLARE_WRITE16_MEMBER(write_o); |
| 53 | | DECLARE_WRITE16_MEMBER(write_r); |
| 54 | | |
| 55 | | DECLARE_INPUT_CHANGED_MEMBER(power_button); |
| 56 | | DECLARE_WRITE_LINE_MEMBER(auto_power_off); |
| 57 | | |
| 58 | | TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick); |
| 59 | | void display_update(); |
| 60 | | |
| 61 | | virtual void machine_reset(); |
| 62 | | virtual void machine_start(); |
| 63 | | }; |
| 64 | | |
| 65 | | |
| 66 | | |
| 67 | | /*************************************************************************** |
| 68 | | |
| 69 | | LED Display |
| 70 | | |
| 71 | | ***************************************************************************/ |
| 72 | | |
| 73 | | // The device strobes the outputs very fast, it is unnoticeable to the user. |
| 74 | | // To prevent flickering here, we need to simulate a decay. |
| 75 | | |
| 76 | | // decay time, in steps of 1ms |
| 77 | | #define DISPLAY_DECAY_TIME 40 |
| 78 | | |
| 79 | | void elecdet_state::display_update() |
| 80 | | { |
| 81 | | UINT16 active_state[0x10]; |
| 82 | | |
| 83 | | for (int i = 0; i < 0x10; i++) |
| 84 | | { |
| 85 | | active_state[i] = 0; |
| 86 | | |
| 87 | | for (int j = 0; j < 0x10; j++) |
| 88 | | { |
| 89 | | int di = j << 4 | i; |
| 90 | | |
| 91 | | // turn on powered segments |
| 92 | | if (m_power_on && m_display_state[i] >> j & 1) |
| 93 | | m_display_decay[di] = DISPLAY_DECAY_TIME; |
| 94 | | |
| 95 | | // determine active state |
| 96 | | int ds = (m_display_decay[di] != 0) ? 1 : 0; |
| 97 | | active_state[i] |= (ds << j); |
| 98 | | } |
| 99 | | } |
| 100 | | |
| 101 | | // on difference, send to output |
| 102 | | for (int i = 0; i < 0x10; i++) |
| 103 | | if (m_display_cache[i] != active_state[i]) |
| 104 | | output_set_digit_value(i, active_state[i]); |
| 105 | | |
| 106 | | memcpy(m_display_cache, active_state, sizeof(m_display_cache)); |
| 107 | | } |
| 108 | | |
| 109 | | TIMER_DEVICE_CALLBACK_MEMBER(elecdet_state::display_decay_tick) |
| 110 | | { |
| 111 | | // slowly turn off unpowered segments |
| 112 | | for (int i = 0; i < 0x100; i++) |
| 113 | | if (!(m_display_state[i & 0xf] >> (i>>4) & 1) && m_display_decay[i]) |
| 114 | | m_display_decay[i]--; |
| 115 | | |
| 116 | | display_update(); |
| 117 | | } |
| 118 | | |
| 119 | | |
| 120 | | |
| 121 | | /*************************************************************************** |
| 122 | | |
| 123 | | I/O |
| 124 | | |
| 125 | | ***************************************************************************/ |
| 126 | | |
| 127 | | READ8_MEMBER(elecdet_state::read_k) |
| 128 | | { |
| 129 | | // the Vss row is always on |
| 130 | | UINT8 k = m_button_matrix[4]->read(); |
| 131 | | |
| 132 | | // read selected button rows |
| 133 | | for (int i = 0; i < 4; i++) |
| 134 | | { |
| 135 | | const int ki[4] = { 0, 1, 4, 6 }; |
| 136 | | if (m_o >> ki[i] & 1) |
| 137 | | k |= m_button_matrix[i]->read(); |
| 138 | | } |
| 139 | | |
| 140 | | return k; |
| 141 | | } |
| 142 | | |
| 143 | | WRITE16_MEMBER(elecdet_state::write_r) |
| 144 | | { |
| 145 | | // R0-R6: select digit |
| 146 | | UINT8 o = BITSWAP8(m_o,7,5,2,1,4,0,6,3) & 0x7f; |
| 147 | | for (int i = 0; i < 7; i++) |
| 148 | | m_display_state[i] = (data >> i & 1) ? o : 0; |
| 149 | | |
| 150 | | display_update(); |
| 151 | | |
| 152 | | // R7,R8: speaker on |
| 153 | | m_speaker->level_w((data & 0x180 && m_o & 0x80) ? 1 : 0); |
| 154 | | } |
| 155 | | |
| 156 | | WRITE16_MEMBER(elecdet_state::write_o) |
| 157 | | { |
| 158 | | // O0,O1,O4,O6: input mux |
| 159 | | // O0-O6: led segments A-G |
| 160 | | // O7: speaker out |
| 161 | | m_o = data; |
| 162 | | } |
| 163 | | |
| 164 | | |
| 165 | | |
| 166 | | /*************************************************************************** |
| 167 | | |
| 168 | | Inputs |
| 169 | | |
| 170 | | ***************************************************************************/ |
| 171 | | |
| 172 | | INPUT_CHANGED_MEMBER(elecdet_state::power_button) |
| 173 | | { |
| 174 | | m_power_on = (bool)(FPTR)param; |
| 175 | | m_maincpu->set_input_line(INPUT_LINE_RESET, m_power_on ? CLEAR_LINE : ASSERT_LINE); |
| 176 | | } |
| 177 | | |
| 178 | | /* physical button layout and labels is like this: |
| 179 | | |
| 180 | | [1] [2] [3] [SUSPECT] |
| 181 | | [4] [5] [6] [PRIVATE QUESTION] |
| 182 | | [7] [8] [9] [I ACCUSE] |
| 183 | | [0] [ENTER] |
| 184 | | [ON] [OFF] [END TURN] |
| 185 | | */ |
| 186 | | |
| 187 | | static INPUT_PORTS_START( elecdet ) |
| 188 | | PORT_START("IN.0") // O0 pin18 |
| 189 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4") |
| 190 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 191 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6") |
| 192 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Q) PORT_NAME("Private Question") |
| 193 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5") |
| 194 | | |
| 195 | | PORT_START("IN.1") // O1 pin17 |
| 196 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 197 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 198 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0") |
| 199 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter") |
| 200 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 201 | | |
| 202 | | PORT_START("IN.2") // O4 pin14 |
| 203 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7") |
| 204 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 205 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9") |
| 206 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_A) PORT_NAME("I Accuse") |
| 207 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8") |
| 208 | | |
| 209 | | PORT_START("IN.3") // O6 pin12 |
| 210 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1") |
| 211 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 212 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3") |
| 213 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_S) PORT_NAME("Suspect") |
| 214 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2") |
| 215 | | |
| 216 | | // note: even though power buttons are on the matrix, they are not CPU-controlled |
| 217 | | PORT_START("IN.4") // Vss! |
| 218 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_PGUP) PORT_NAME("On") PORT_CHANGED_MEMBER(DEVICE_SELF, elecdet_state, power_button, (void *)true) |
| 219 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 220 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 221 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_NAME("End Turn") |
| 222 | | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_PGDN) PORT_NAME("Off") PORT_CHANGED_MEMBER(DEVICE_SELF, elecdet_state, power_button, (void *)false) |
| 223 | | INPUT_PORTS_END |
| 224 | | |
| 225 | | |
| 226 | | |
| 227 | | /*************************************************************************** |
| 228 | | |
| 229 | | Machine Config |
| 230 | | |
| 231 | | ***************************************************************************/ |
| 232 | | |
| 233 | | WRITE_LINE_MEMBER(elecdet_state::auto_power_off) |
| 234 | | { |
| 235 | | // TMS0980 auto power-off opcode |
| 236 | | if (state) |
| 237 | | { |
| 238 | | m_power_on = false; |
| 239 | | m_maincpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 240 | | } |
| 241 | | } |
| 242 | | |
| 243 | | |
| 244 | | void elecdet_state::machine_reset() |
| 245 | | { |
| 246 | | m_power_on = true; |
| 247 | | } |
| 248 | | |
| 249 | | void elecdet_state::machine_start() |
| 250 | | { |
| 251 | | // zerofill |
| 252 | | memset(m_display_state, 0, sizeof(m_display_state)); |
| 253 | | memset(m_display_cache, 0, sizeof(m_display_cache)); |
| 254 | | memset(m_display_decay, 0, sizeof(m_display_decay)); |
| 255 | | |
| 256 | | m_o = 0; |
| 257 | | m_power_on = false; |
| 258 | | |
| 259 | | // register for savestates |
| 260 | | save_item(NAME(m_display_state)); |
| 261 | | save_item(NAME(m_display_cache)); |
| 262 | | save_item(NAME(m_display_decay)); |
| 263 | | |
| 264 | | save_item(NAME(m_o)); |
| 265 | | save_item(NAME(m_power_on)); |
| 266 | | } |
| 267 | | |
| 268 | | |
| 269 | | static MACHINE_CONFIG_START( elecdet, elecdet_state ) |
| 270 | | |
| 271 | | /* basic machine hardware */ |
| 272 | | MCFG_CPU_ADD("maincpu", TMS0980, MASTER_CLOCK) |
| 273 | | MCFG_TMS1XXX_READ_K_CB(READ8(elecdet_state, read_k)) |
| 274 | | MCFG_TMS1XXX_WRITE_O_CB(WRITE16(elecdet_state, write_o)) |
| 275 | | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(elecdet_state, write_r)) |
| 276 | | MCFG_TMS1XXX_POWER_OFF_CB(WRITELINE(elecdet_state, auto_power_off)) |
| 277 | | |
| 278 | | MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", elecdet_state, display_decay_tick, attotime::from_msec(1)) |
| 279 | | |
| 280 | | MCFG_DEFAULT_LAYOUT(layout_elecdet) |
| 281 | | |
| 282 | | /* no video! */ |
| 283 | | |
| 284 | | /* sound hardware */ |
| 285 | | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 286 | | MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) |
| 287 | | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 288 | | MACHINE_CONFIG_END |
| 289 | | |
| 290 | | |
| 291 | | |
| 292 | | /*************************************************************************** |
| 293 | | |
| 294 | | Game driver(s) |
| 295 | | |
| 296 | | ***************************************************************************/ |
| 297 | | |
| 298 | | ROM_START( elecdet ) |
| 299 | | ROM_REGION( 0x1000, "maincpu", 0 ) |
| 300 | | ROM_LOAD( "tms0980nll_mp6100a", 0x0000, 0x1000, CRC(6f396bb8) SHA1(1f104d4ca9bee0d4572be4779b7551dfe20c4f04) ) |
| 301 | | |
| 302 | | ROM_REGION( 1246, "maincpu:ipla", 0 ) |
| 303 | | ROM_LOAD( "tms0980_default_ipla.pla", 0, 1246, CRC(42db9a38) SHA1(2d127d98028ec8ec6ea10c179c25e447b14ba4d0) ) |
| 304 | | ROM_REGION( 1982, "maincpu:mpla", 0 ) |
| 305 | | ROM_LOAD( "tms0980_default_mpla.pla", 0, 1982, CRC(3709014f) SHA1(d28ee59ded7f3b9dc3f0594a32a98391b6e9c961) ) |
| 306 | | ROM_REGION( 352, "maincpu:opla", 0 ) |
| 307 | | ROM_LOAD( "tms0980_elecdet_opla.pla", 0, 352, CRC(652d19c3) SHA1(75550c2b293453b6b9efed88c8cc77195a53161f) ) |
| 308 | | ROM_REGION( 157, "maincpu:spla", 0 ) |
| 309 | | ROM_LOAD( "tms0980_elecdet_spla.pla", 0, 157, CRC(399aa481) SHA1(72c56c58fde3fbb657d69647a9543b5f8fc74279) ) |
| 310 | | ROM_END |
| 311 | | |
| 312 | | |
| 313 | | CONS( 1979, elecdet, 0, 0, elecdet, elecdet, driver_device, 0, "Ideal", "Electronic Detective", GAME_SUPPORTS_SAVE ) |
trunk/src/mess/drivers/hh_tms1k.c
| r244626 | r244627 | |
| 15 | 15 | |
| 16 | 16 | #include "amaztron.lh" |
| 17 | 17 | #include "ebball.lh" |
| 18 | #include "elecdet.lh" |
| 18 | 19 | #include "comp4.lh" |
| 20 | #include "mathmagi.lh" |
| 19 | 21 | #include "simon.lh" |
| 22 | #include "starwbc.lh" |
| 23 | #include "tandy12.lh" |
| 20 | 24 | #include "tc4.lh" |
| 21 | 25 | |
| 22 | 26 | |
| r244626 | r244627 | |
| 28 | 32 | m_maincpu(*this, "maincpu"), |
| 29 | 33 | m_inp_matrix(*this, "IN"), |
| 30 | 34 | m_speaker(*this, "speaker"), |
| 35 | m_display_wait(33), |
| 31 | 36 | m_display_maxy(1), |
| 32 | | m_display_maxx(0), |
| 33 | | m_display_wait(50) |
| 37 | m_display_maxx(0) |
| 34 | 38 | { } |
| 35 | 39 | |
| 36 | 40 | required_device<cpu_device> m_maincpu; |
| r244626 | r244627 | |
| 40 | 44 | UINT16 m_r; |
| 41 | 45 | UINT16 m_o; |
| 42 | 46 | UINT16 m_inp_mux; |
| 47 | bool m_power_on; |
| 43 | 48 | |
| 49 | int m_display_wait; |
| 44 | 50 | int m_display_maxy; |
| 45 | 51 | int m_display_maxx; |
| 46 | | int m_display_wait; |
| 47 | 52 | |
| 48 | 53 | UINT32 m_display_state[0x20]; |
| 49 | 54 | UINT32 m_display_cache[0x20]; |
| r244626 | r244627 | |
| 55 | 60 | void display_update(); |
| 56 | 61 | |
| 57 | 62 | UINT8 read_inputs(int columns); |
| 63 | DECLARE_INPUT_CHANGED_MEMBER(tms0980_power_button); |
| 64 | DECLARE_WRITE_LINE_MEMBER(tms0980_auto_power_off); |
| 58 | 65 | |
| 59 | 66 | // game-specific handlers |
| 67 | void mathmagi_display(); |
| 68 | DECLARE_READ8_MEMBER(mathmagi_read_k); |
| 69 | DECLARE_WRITE16_MEMBER(mathmagi_write_r); |
| 70 | DECLARE_WRITE16_MEMBER(mathmagi_write_o); |
| 71 | |
| 60 | 72 | void amaztron_display(); |
| 61 | 73 | DECLARE_READ8_MEMBER(amaztron_read_k); |
| 74 | DECLARE_WRITE16_MEMBER(amaztron_write_r); |
| 62 | 75 | DECLARE_WRITE16_MEMBER(amaztron_write_o); |
| 63 | | DECLARE_WRITE16_MEMBER(amaztron_write_r); |
| 64 | 76 | |
| 65 | 77 | void tc4_display(); |
| 66 | 78 | DECLARE_READ8_MEMBER(tc4_read_k); |
| 79 | DECLARE_WRITE16_MEMBER(tc4_write_r); |
| 67 | 80 | DECLARE_WRITE16_MEMBER(tc4_write_o); |
| 68 | | DECLARE_WRITE16_MEMBER(tc4_write_r); |
| 69 | 81 | |
| 82 | DECLARE_READ8_MEMBER(elecdet_read_k); |
| 83 | DECLARE_WRITE16_MEMBER(elecdet_write_r); |
| 84 | DECLARE_WRITE16_MEMBER(elecdet_write_o); |
| 85 | |
| 86 | void starwbc_display(); |
| 87 | DECLARE_READ8_MEMBER(starwbc_read_k); |
| 88 | DECLARE_WRITE16_MEMBER(starwbc_write_r); |
| 89 | DECLARE_WRITE16_MEMBER(starwbc_write_o); |
| 90 | |
| 70 | 91 | DECLARE_READ8_MEMBER(comp4_read_k); |
| 92 | DECLARE_WRITE16_MEMBER(comp4_write_r); |
| 71 | 93 | DECLARE_WRITE16_MEMBER(comp4_write_o); |
| 72 | | DECLARE_WRITE16_MEMBER(comp4_write_r); |
| 73 | 94 | |
| 74 | 95 | DECLARE_READ8_MEMBER(simon_read_k); |
| 96 | DECLARE_WRITE16_MEMBER(simon_write_r); |
| 75 | 97 | DECLARE_WRITE16_MEMBER(simon_write_o); |
| 76 | | DECLARE_WRITE16_MEMBER(simon_write_r); |
| 77 | 98 | |
| 99 | void tandy12_display(); |
| 100 | DECLARE_READ8_MEMBER(tandy12_read_k); |
| 101 | DECLARE_WRITE16_MEMBER(tandy12_write_r); |
| 102 | DECLARE_WRITE16_MEMBER(tandy12_write_o); |
| 103 | |
| 104 | DECLARE_READ8_MEMBER(unk3403_read_k); |
| 105 | DECLARE_WRITE16_MEMBER(unk3403_write_r); |
| 106 | DECLARE_WRITE16_MEMBER(unk3403_write_o); |
| 107 | |
| 78 | 108 | virtual void machine_start(); |
| 109 | virtual void machine_reset(); |
| 79 | 110 | }; |
| 80 | 111 | |
| 81 | 112 | |
| r244626 | r244627 | |
| 90 | 121 | m_o = 0; |
| 91 | 122 | m_r = 0; |
| 92 | 123 | m_inp_mux = 0; |
| 124 | m_power_on = false; |
| 93 | 125 | |
| 94 | 126 | // register for savestates |
| 95 | 127 | save_item(NAME(m_display_maxy)); |
| r244626 | r244627 | |
| 104 | 136 | save_item(NAME(m_o)); |
| 105 | 137 | save_item(NAME(m_r)); |
| 106 | 138 | save_item(NAME(m_inp_mux)); |
| 139 | save_item(NAME(m_power_on)); |
| 107 | 140 | } |
| 108 | 141 | |
| 109 | 142 | |
| 143 | void hh_tms1k_state::machine_reset() |
| 144 | { |
| 145 | m_power_on = true; |
| 146 | } |
| 147 | |
| 110 | 148 | /*************************************************************************** |
| 111 | 149 | |
| 112 | 150 | Helper Functions |
| 113 | 151 | |
| 114 | 152 | ***************************************************************************/ |
| 115 | 153 | |
| 154 | // LED segments |
| 155 | enum |
| 156 | { |
| 157 | lA = 0x01, |
| 158 | lB = 0x02, |
| 159 | lC = 0x04, |
| 160 | lD = 0x08, |
| 161 | lE = 0x10, |
| 162 | lF = 0x20, |
| 163 | lG = 0x40, |
| 164 | lDP = 0x80 |
| 165 | }; |
| 116 | 166 | |
| 117 | 167 | // The device strobes the outputs very fast, it is unnoticeable to the user. |
| 118 | 168 | // To prevent flickering here, we need to simulate a decay. |
| r244626 | r244627 | |
| 129 | 179 | for (int x = 0; x < m_display_maxx; x++) |
| 130 | 180 | { |
| 131 | 181 | // turn on powered segments |
| 132 | | if (m_display_state[y] >> x & 1) |
| 182 | if (m_power_on && m_display_state[y] >> x & 1) |
| 133 | 183 | m_display_decay[y][x] = m_display_wait; |
| 134 | 184 | |
| 135 | 185 | // determine active state |
| r244626 | r244627 | |
| 177 | 227 | return k; |
| 178 | 228 | } |
| 179 | 229 | |
| 230 | INPUT_CHANGED_MEMBER(hh_tms1k_state::tms0980_power_button) |
| 231 | { |
| 232 | m_power_on = (bool)(FPTR)param; |
| 233 | m_maincpu->set_input_line(INPUT_LINE_RESET, m_power_on ? CLEAR_LINE : ASSERT_LINE); |
| 234 | } |
| 180 | 235 | |
| 236 | WRITE_LINE_MEMBER(hh_tms1k_state::tms0980_auto_power_off) |
| 237 | { |
| 238 | // TMS0980 auto power-off opcode |
| 239 | if (state) |
| 240 | { |
| 241 | m_power_on = false; |
| 242 | m_maincpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 243 | } |
| 244 | } |
| 181 | 245 | |
| 182 | 246 | /*************************************************************************** |
| 183 | 247 | |
| r244626 | r244627 | |
| 187 | 251 | |
| 188 | 252 | /*************************************************************************** |
| 189 | 253 | |
| 254 | APF Mathemagician |
| 255 | * TMS1100 MCU, labeled MP1030 |
| 256 | * 2 x DS8870N - Hex LED Digit Driver |
| 257 | * 2 x DS8861N - MOS-to-LED 5-Segment Driver |
| 258 | |
| 259 | This is a tabletop educational calculator. It came with plastic overlays |
| 260 | for playing different kind of games. Refer to the manual on how to use it. |
| 261 | In short, to start from scratch, press [SEL]. By default the device is in |
| 262 | calculator teaching mode. If [SEL] is followed with 1-6 and then [NXT], |
| 263 | one of the games is started. |
| 264 | |
| 265 | 1) Number Machine |
| 266 | 2) Countin' On |
| 267 | 3) Walk The Plank |
| 268 | 4) Gooey Gumdrop |
| 269 | 5) Football |
| 270 | 6) Lunar Lander |
| 271 | |
| 272 | |
| 273 | TODO: |
| 274 | - some of the led symbols are probably wrong, output PLA is unknown |
| 275 | - microinstructions PLA is not verified |
| 276 | |
| 277 | ***************************************************************************/ |
| 278 | |
| 279 | void hh_tms1k_state::mathmagi_display() |
| 280 | { |
| 281 | m_display_maxy = 11; |
| 282 | m_display_maxx = 8; |
| 283 | |
| 284 | // R0-R7: 7seg leds |
| 285 | for (int y = 0; y < 8; y++) |
| 286 | { |
| 287 | m_7seg_mask[y] = 0x7f; |
| 288 | m_display_state[y] = (m_r >> y & 1) ? ((m_o >> 1 & 0x7f) | (m_o << 7 & 0x80)) : 0; |
| 289 | } |
| 290 | |
| 291 | // R8: custom math symbols digit |
| 292 | // R9: custom equals digit |
| 293 | // R10: misc lamps |
| 294 | for (int y = 8; y < 11; y++) |
| 295 | m_display_state[y] = (m_r >> y & 1) ? m_o : 0; |
| 296 | |
| 297 | display_update(); |
| 298 | } |
| 299 | |
| 300 | READ8_MEMBER(hh_tms1k_state::mathmagi_read_k) |
| 301 | { |
| 302 | return read_inputs(6); |
| 303 | } |
| 304 | |
| 305 | |
| 306 | WRITE16_MEMBER(hh_tms1k_state::mathmagi_write_r) |
| 307 | { |
| 308 | // R3,R5-R7,R9,R10: input mux |
| 309 | m_inp_mux = (data >> 3 & 1) | (data >> 4 & 0xe) | (data >> 5 & 0x30); |
| 310 | |
| 311 | // +others: |
| 312 | m_r = data; |
| 313 | mathmagi_display(); |
| 314 | } |
| 315 | |
| 316 | WRITE16_MEMBER(hh_tms1k_state::mathmagi_write_o) |
| 317 | { |
| 318 | // O1-O7: led segments A-G |
| 319 | // O0: N/C |
| 320 | data = (data << 1 & 0xfe) | (data >> 7 & 1); // because opla is unknown |
| 321 | m_o = data; |
| 322 | } |
| 323 | |
| 324 | /* physical button layout and labels is like this: |
| 325 | |
| 326 | ON ONE [SEL] [NXT] [?] [/] |
| 327 | | | [7] [8] [9] [x] |
| 328 | OFF TWO [4] [5] [6] [-] |
| 329 | PLAYERS [1] [2] [3] [+] |
| 330 | [0] [_] [r] [=] |
| 331 | */ |
| 332 | |
| 333 | static INPUT_PORTS_START( mathmagi ) |
| 334 | PORT_START("IN.0") // R3 |
| 335 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1") |
| 336 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2") |
| 337 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3") |
| 338 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_MINUS_PAD) PORT_NAME("-") |
| 339 | |
| 340 | PORT_START("IN.1") // R5 |
| 341 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0") |
| 342 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_SPACE) PORT_NAME("_") // blank |
| 343 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) PORT_NAME("r") |
| 344 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_PLUS_PAD) PORT_NAME("+") |
| 345 | |
| 346 | PORT_START("IN.2") // R6 |
| 347 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4") |
| 348 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5") |
| 349 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6") |
| 350 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_ASTERISK) PORT_NAME(UTF8_MULTIPLY) |
| 351 | |
| 352 | PORT_START("IN.3") // R7 |
| 353 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_S) PORT_NAME("SEL") |
| 354 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_N) PORT_NAME("NXT") |
| 355 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_C) PORT_NAME("?") // check |
| 356 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("=") |
| 357 | |
| 358 | PORT_START("IN.4") // R9 |
| 359 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7") |
| 360 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8") |
| 361 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9") |
| 362 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_SLASH_PAD) PORT_NAME(UTF8_DIVIDE) |
| 363 | |
| 364 | PORT_START("IN.5") // R10 |
| 365 | PORT_CONFNAME( 0x01, 0x00, "Players") |
| 366 | PORT_CONFSETTING( 0x00, "1" ) |
| 367 | PORT_CONFSETTING( 0x01, "2" ) |
| 368 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 369 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 370 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 371 | INPUT_PORTS_END |
| 372 | |
| 373 | static const UINT16 mathmagi_output_pla[0x20] = |
| 374 | { |
| 375 | lA+lB+lC+lD+lE+lF, // 0 |
| 376 | lB+lC, // 1 |
| 377 | lA+lB+lG+lE+lD, // 2 |
| 378 | lA+lB+lG+lC+lD, // 3 |
| 379 | lF+lB+lG+lC, // 4 |
| 380 | lA+lF+lG+lC+lD, // 5 |
| 381 | lA+lF+lG+lC+lD+lE, // 6 |
| 382 | lA+lB+lC, // 7 |
| 383 | lA+lB+lC+lD+lE+lF+lG, // 8 |
| 384 | lA+lB+lG+lF+lC+lD, // 9 |
| 385 | lA+lB+lG+lE, // question mark |
| 386 | lE+lG, // r |
| 387 | lD, // underscore? |
| 388 | lA+lF+lG+lE+lD, // E |
| 389 | lG, // - |
| 390 | 0, // empty |
| 391 | 0, // empty |
| 392 | lG, // lamp 4 or MATH - |
| 393 | lD, // lamp 3 |
| 394 | lF+lE+lD+lC+lG, // b |
| 395 | lB, // lamp 2 |
| 396 | lB+lG, // MATH + |
| 397 | lB+lC, // MATH mul |
| 398 | lF+lG+lB+lC+lD, // y |
| 399 | lA, // lamp 1 |
| 400 | lA+lG, // MATH div |
| 401 | lA+lD, // EQUALS |
| 402 | 0, // ? |
| 403 | 0, // ? |
| 404 | lE+lD+lC+lG, // o |
| 405 | 0, // ? |
| 406 | lA+lF+lE+lD+lC // G |
| 407 | }; |
| 408 | |
| 409 | |
| 410 | static MACHINE_CONFIG_START( mathmagi, hh_tms1k_state ) |
| 411 | |
| 412 | /* basic machine hardware */ |
| 413 | MCFG_CPU_ADD("maincpu", TMS1100, 175000) // RC osc. R=68K, C=82pf -> ~175kHz |
| 414 | MCFG_TMS1XXX_OUTPUT_PLA(mathmagi_output_pla) |
| 415 | MCFG_TMS1XXX_READ_K_CB(READ8(hh_tms1k_state, mathmagi_read_k)) |
| 416 | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, mathmagi_write_r)) |
| 417 | MCFG_TMS1XXX_WRITE_O_CB(WRITE16(hh_tms1k_state, mathmagi_write_o)) |
| 418 | |
| 419 | MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) |
| 420 | MCFG_DEFAULT_LAYOUT(layout_mathmagi) |
| 421 | |
| 422 | /* no video! */ |
| 423 | |
| 424 | /* no sound! */ |
| 425 | MACHINE_CONFIG_END |
| 426 | |
| 427 | |
| 428 | |
| 429 | |
| 430 | |
| 431 | /*************************************************************************** |
| 432 | |
| 190 | 433 | Coleco Amaze-A-Tron, by Ralph Baer |
| 191 | 434 | * TMS1100 MCU, labeled MP3405(die label too) |
| 192 | 435 | |
| r244626 | r244627 | |
| 296 | 539 | /* basic machine hardware */ |
| 297 | 540 | MCFG_CPU_ADD("maincpu", TMS1100, 350000) // RC osc. R=33K?, C=100pf -> ~350kHz |
| 298 | 541 | MCFG_TMS1XXX_READ_K_CB(READ8(hh_tms1k_state, amaztron_read_k)) |
| 542 | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, amaztron_write_r)) |
| 299 | 543 | 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 | 544 | |
| 302 | 545 | MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) |
| 303 | | |
| 304 | 546 | MCFG_DEFAULT_LAYOUT(layout_amaztron) |
| 305 | 547 | |
| 306 | 548 | /* no video! */ |
| r244626 | r244627 | |
| 354 | 596 | |
| 355 | 597 | void hh_tms1k_state::tc4_display() |
| 356 | 598 | { |
| 599 | m_display_wait = 50; |
| 357 | 600 | m_display_maxy = 10; |
| 358 | 601 | m_display_maxx = 9; |
| 359 | 602 | |
| r244626 | r244627 | |
| 380 | 623 | return k; |
| 381 | 624 | } |
| 382 | 625 | |
| 383 | | WRITE16_MEMBER(hh_tms1k_state::tc4_write_o) |
| 384 | | { |
| 385 | | // O0-O7: leds/7segment |
| 386 | | m_o = data; |
| 387 | | tc4_display(); |
| 388 | | } |
| 389 | | |
| 390 | 626 | WRITE16_MEMBER(hh_tms1k_state::tc4_write_r) |
| 391 | 627 | { |
| 392 | 628 | // R10: speaker out |
| r244626 | r244627 | |
| 402 | 638 | tc4_display(); |
| 403 | 639 | } |
| 404 | 640 | |
| 641 | WRITE16_MEMBER(hh_tms1k_state::tc4_write_o) |
| 642 | { |
| 643 | // O0-O7: leds/7segment |
| 644 | m_o = data; |
| 645 | tc4_display(); |
| 646 | } |
| 405 | 647 | |
| 648 | |
| 406 | 649 | static INPUT_PORTS_START( tc4 ) |
| 407 | 650 | PORT_START("IN.0") // R0 |
| 408 | 651 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P1 Pass/Shoot Button 3") // right |
| r244626 | r244627 | |
| 453 | 696 | /* basic machine hardware */ |
| 454 | 697 | MCFG_CPU_ADD("maincpu", TMS1400, 450000) // approximation - RC osc. R=27.3K, C=100pf, but unknown RC curve |
| 455 | 698 | MCFG_TMS1XXX_READ_K_CB(READ8(hh_tms1k_state, tc4_read_k)) |
| 699 | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, tc4_write_r)) |
| 456 | 700 | MCFG_TMS1XXX_WRITE_O_CB(WRITE16(hh_tms1k_state, tc4_write_o)) |
| 457 | | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, tc4_write_r)) |
| 458 | 701 | |
| 459 | 702 | MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) |
| 460 | | |
| 461 | 703 | MCFG_DEFAULT_LAYOUT(layout_tc4) |
| 462 | 704 | |
| 463 | 705 | /* no video! */ |
| r244626 | r244627 | |
| 469 | 711 | MACHINE_CONFIG_END |
| 470 | 712 | |
| 471 | 713 | |
| 714 | /*************************************************************************** |
| 472 | 715 | |
| 716 | Entex Baseball |
| 717 | * TMS1000NLP MP0914 (die labeled MP0914A) |
| 718 | |
| 719 | ***************************************************************************/ |
| 720 | |
| 721 | // inputs |
| 722 | static INPUT_PORTS_START( ebball ) |
| 723 | INPUT_PORTS_END |
| 724 | |
| 725 | // machine config |
| 726 | static MACHINE_CONFIG_START( ebball, hh_tms1k_state ) |
| 727 | |
| 728 | /* basic machine hardware */ |
| 729 | MCFG_CPU_ADD("maincpu", TMS1000, 350000) // RC osc. R=43K, C=47pf -> ~350kHz |
| 730 | |
| 731 | MCFG_DEFAULT_LAYOUT(layout_ebball) |
| 732 | |
| 733 | /* no video! */ |
| 734 | |
| 735 | /* sound hardware */ |
| 736 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 737 | MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) |
| 738 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 739 | MACHINE_CONFIG_END |
| 740 | |
| 741 | |
| 742 | |
| 473 | 743 | /*************************************************************************** |
| 474 | 744 | |
| 745 | Ideal Electronic Detective |
| 746 | * TMS0980NLL MP6100A (die labeled 0980B-00) |
| 747 | hardware (and concept) is very similar to Parker Bros Stop Thief |
| 748 | |
| 749 | This is an electronic board game. It requires game cards with suspect info, |
| 750 | and good old pen and paper to record game progress. To start the game, enter |
| 751 | difficulty(1-3), then number of players(1-4), then [ENTER]. Refer to the |
| 752 | manual for more information. |
| 753 | |
| 754 | |
| 755 | TODO: |
| 756 | - MCU clock is unknown |
| 757 | |
| 758 | ***************************************************************************/ |
| 759 | |
| 760 | |
| 761 | READ8_MEMBER(hh_tms1k_state::elecdet_read_k) |
| 762 | { |
| 763 | // note: the Vss row is always on |
| 764 | return m_inp_matrix[4]->read() | read_inputs(4); |
| 765 | } |
| 766 | |
| 767 | WRITE16_MEMBER(hh_tms1k_state::elecdet_write_r) |
| 768 | { |
| 769 | m_display_maxy = 7; |
| 770 | m_display_maxx = 7; |
| 771 | |
| 772 | // R0-R6: select digit |
| 773 | UINT8 o = BITSWAP8(m_o,7,5,2,1,4,0,6,3); |
| 774 | for (int y = 0; y < m_display_maxy; y++) |
| 775 | { |
| 776 | m_7seg_mask[y] = 0x7f; |
| 777 | m_display_state[y] = (data >> y & 1) ? o : 0; |
| 778 | } |
| 779 | |
| 780 | display_update(); |
| 781 | |
| 782 | // R7,R8: speaker on |
| 783 | m_speaker->level_w((data & 0x180 && m_o & 0x80) ? 1 : 0); |
| 784 | } |
| 785 | |
| 786 | WRITE16_MEMBER(hh_tms1k_state::elecdet_write_o) |
| 787 | { |
| 788 | // O0,O1,O4,O6: input mux |
| 789 | m_inp_mux = (data & 3) | (data >> 2 & 4) | (data >> 3 & 8); |
| 790 | |
| 791 | // O0-O6: led segments A-G |
| 792 | // O7: speaker out |
| 793 | m_o = data; |
| 794 | } |
| 795 | |
| 796 | |
| 797 | /* physical button layout and labels is like this: |
| 798 | |
| 799 | [1] [2] [3] [SUSPECT] |
| 800 | [4] [5] [6] [PRIVATE QUESTION] |
| 801 | [7] [8] [9] [I ACCUSE] |
| 802 | [0] [ENTER] |
| 803 | [ON] [OFF] [END TURN] |
| 804 | */ |
| 805 | |
| 806 | static INPUT_PORTS_START( elecdet ) |
| 807 | PORT_START("IN.0") // O0 pin18 |
| 808 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4") |
| 809 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 810 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6") |
| 811 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Q) PORT_NAME("Private Question") |
| 812 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5") |
| 813 | |
| 814 | PORT_START("IN.1") // O1 pin17 |
| 815 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 816 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 817 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0") |
| 818 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter") |
| 819 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 820 | |
| 821 | PORT_START("IN.2") // O4 pin14 |
| 822 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7") |
| 823 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 824 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9") |
| 825 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_A) PORT_NAME("I Accuse") |
| 826 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8") |
| 827 | |
| 828 | PORT_START("IN.3") // O6 pin12 |
| 829 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1") |
| 830 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 831 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3") |
| 832 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_S) PORT_NAME("Suspect") |
| 833 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2") |
| 834 | |
| 835 | // note: even though power buttons are on the matrix, they are not CPU-controlled |
| 836 | PORT_START("IN.4") // Vss! |
| 837 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_PGUP) PORT_NAME("On") PORT_CHANGED_MEMBER(DEVICE_SELF, hh_tms1k_state, tms0980_power_button, (void *)true) |
| 838 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 839 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 840 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_NAME("End Turn") |
| 841 | PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_PGDN) PORT_NAME("Off") PORT_CHANGED_MEMBER(DEVICE_SELF, hh_tms1k_state, tms0980_power_button, (void *)false) |
| 842 | INPUT_PORTS_END |
| 843 | |
| 844 | |
| 845 | static MACHINE_CONFIG_START( elecdet, hh_tms1k_state ) |
| 846 | |
| 847 | /* basic machine hardware */ |
| 848 | MCFG_CPU_ADD("maincpu", TMS0980, 425000) // approximation - unknown freq |
| 849 | MCFG_TMS1XXX_READ_K_CB(READ8(hh_tms1k_state, elecdet_read_k)) |
| 850 | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, elecdet_write_r)) |
| 851 | MCFG_TMS1XXX_WRITE_O_CB(WRITE16(hh_tms1k_state, elecdet_write_o)) |
| 852 | MCFG_TMS1XXX_POWER_OFF_CB(WRITELINE(hh_tms1k_state, tms0980_auto_power_off)) |
| 853 | |
| 854 | MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) |
| 855 | MCFG_DEFAULT_LAYOUT(layout_elecdet) |
| 856 | |
| 857 | /* no video! */ |
| 858 | |
| 859 | /* sound hardware */ |
| 860 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 861 | MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) |
| 862 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 863 | MACHINE_CONFIG_END |
| 864 | |
| 865 | |
| 866 | |
| 867 | |
| 868 | |
| 869 | /*************************************************************************** |
| 870 | |
| 871 | Kenner Star Wars - Electronic Battle Command |
| 872 | * TMS1100 MCU, labeled MP3438A |
| 873 | |
| 874 | This is a small tabletop space-dogfighting game. To start the game, |
| 875 | press BASIC/INTER/ADV and enter P#(number of players), then |
| 876 | START TURN. Refer to the official manual for more information. |
| 877 | |
| 878 | ***************************************************************************/ |
| 879 | |
| 880 | void hh_tms1k_state::starwbc_display() |
| 881 | { |
| 882 | m_display_maxy = 10; |
| 883 | m_display_maxx = 8; |
| 884 | |
| 885 | UINT8 o = (m_o << 4 & 0xf0) | (m_o >> 4 & 0x0f); |
| 886 | for (int y = 0; y < m_display_maxy; y+=2) |
| 887 | { |
| 888 | m_display_state[y] = (m_r >> y & 1) ? o : 0; |
| 889 | |
| 890 | // R6,R8 are 7segs |
| 891 | if (y == 6 || y == 8) |
| 892 | m_7seg_mask[y] = 0x7f; |
| 893 | } |
| 894 | |
| 895 | display_update(); |
| 896 | } |
| 897 | |
| 898 | READ8_MEMBER(hh_tms1k_state::starwbc_read_k) |
| 899 | { |
| 900 | return read_inputs(5); |
| 901 | } |
| 902 | |
| 903 | WRITE16_MEMBER(hh_tms1k_state::starwbc_write_r) |
| 904 | { |
| 905 | // R0,R1,R3,R5,R7: input mux |
| 906 | m_inp_mux = (data & 3) | (data >> 1 & 4) | (data >> 2 & 8) | (data >> 3 & 0x10); |
| 907 | |
| 908 | // R9: piezo speaker |
| 909 | m_speaker->level_w(data >> 9 & 1); |
| 910 | |
| 911 | // R0,R2,R4,R6,R8: leds |
| 912 | m_r = data; |
| 913 | starwbc_display(); |
| 914 | } |
| 915 | |
| 916 | WRITE16_MEMBER(hh_tms1k_state::starwbc_write_o) |
| 917 | { |
| 918 | // O0-O7: leds state |
| 919 | m_o = data; |
| 920 | starwbc_display(); |
| 921 | } |
| 922 | |
| 923 | |
| 924 | |
| 925 | /* physical button layout and labels is like this: |
| 926 | |
| 927 | (reconnnaissance=yellow) (tactical reaction=green) |
| 928 | [MAGNA] [ENEMY] [EM] [BS] [SCR] |
| 929 | |
| 930 | [BASIC] [INTER] [START TURN] [END TURN] [MOVE] [FIRE] |
| 931 | [ADV] [P#] [<] [^] [>] [v] |
| 932 | (game=blue) (maneuvers=red) |
| 933 | */ |
| 934 | |
| 935 | static INPUT_PORTS_START( starwbc ) |
| 936 | PORT_START("IN.0") // R0 |
| 937 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_NAME("Basic Game") |
| 938 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_NAME("Intermediate Game") |
| 939 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("Advanced Game") |
| 940 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_N) PORT_NAME("Player Number") |
| 941 | |
| 942 | PORT_START("IN.1") // R1 |
| 943 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_ENTER) PORT_NAME("Start Turn") |
| 944 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_UNUSED) |
| 945 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_UNUSED) |
| 946 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CODE(KEYCODE_DEL) PORT_NAME("End Turn") |
| 947 | |
| 948 | PORT_START("IN.2") // R3 |
| 949 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("Magna Scan") // only used in adv. game |
| 950 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("Enemy Scan") // only used in adv. game |
| 951 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_UNUSED) |
| 952 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_NAME("Screen Up") |
| 953 | |
| 954 | PORT_START("IN.3") // R5 |
| 955 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Evasive Maneuvers") |
| 956 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_M) PORT_NAME("Move") |
| 957 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F) PORT_NAME("Fire") |
| 958 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_B) PORT_NAME("Battle Stations") |
| 959 | |
| 960 | PORT_START("IN.4") // R7 |
| 961 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_LEFT) PORT_NAME("Left") |
| 962 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_UP) PORT_NAME("Up") |
| 963 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_DOWN) PORT_NAME("Down") |
| 964 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Right") |
| 965 | INPUT_PORTS_END |
| 966 | |
| 967 | static MACHINE_CONFIG_START( starwbc, hh_tms1k_state ) |
| 968 | |
| 969 | /* basic machine hardware */ |
| 970 | MCFG_CPU_ADD("maincpu", TMS1100, 300000) // RC osc. R=51K, C=47pf -> ~300kHz |
| 971 | MCFG_TMS1XXX_READ_K_CB(READ8(hh_tms1k_state, starwbc_read_k)) |
| 972 | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, starwbc_write_r)) |
| 973 | MCFG_TMS1XXX_WRITE_O_CB(WRITE16(hh_tms1k_state, starwbc_write_o)) |
| 974 | |
| 975 | MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) |
| 976 | MCFG_DEFAULT_LAYOUT(layout_starwbc) |
| 977 | |
| 978 | /* no video! */ |
| 979 | |
| 980 | /* sound hardware */ |
| 981 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 982 | MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) |
| 983 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 984 | MACHINE_CONFIG_END |
| 985 | |
| 986 | |
| 987 | |
| 988 | |
| 989 | |
| 990 | /*************************************************************************** |
| 991 | |
| 475 | 992 | Milton Bradley Comp IV |
| 476 | 993 | * TMC0904NL CP0904A (die labeled 4A0970D-04A) |
| 477 | 994 | |
| r244626 | r244627 | |
| 542 | 1059 | /* basic machine hardware */ |
| 543 | 1060 | MCFG_CPU_ADD("maincpu", TMS0970, 250000) // approximation - unknown freq |
| 544 | 1061 | MCFG_TMS1XXX_READ_K_CB(READ8(hh_tms1k_state, comp4_read_k)) |
| 1062 | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, comp4_write_r)) |
| 545 | 1063 | 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 | 1064 | |
| 548 | 1065 | MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) |
| 549 | | |
| 550 | 1066 | MCFG_DEFAULT_LAYOUT(layout_comp4) |
| 551 | 1067 | |
| 552 | 1068 | /* no video! */ |
| r244626 | r244627 | |
| 572 | 1088 | |
| 573 | 1089 | ***************************************************************************/ |
| 574 | 1090 | |
| 575 | | |
| 576 | | |
| 577 | | |
| 578 | | |
| 579 | | /*************************************************************************** |
| 580 | | |
| 581 | | I/O |
| 582 | | |
| 583 | | ***************************************************************************/ |
| 584 | | |
| 585 | 1091 | READ8_MEMBER(hh_tms1k_state::simon_read_k) |
| 586 | 1092 | { |
| 587 | 1093 | return read_inputs(4); |
| r244626 | r244627 | |
| 647 | 1153 | /* basic machine hardware */ |
| 648 | 1154 | MCFG_CPU_ADD("maincpu", TMS1000, 350000) // RC osc. R=33K, C=100pf -> ~350kHz |
| 649 | 1155 | MCFG_TMS1XXX_READ_K_CB(READ8(hh_tms1k_state, simon_read_k)) |
| 1156 | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, simon_write_r)) |
| 650 | 1157 | 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 | 1158 | |
| 653 | 1159 | MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) |
| 654 | | |
| 655 | 1160 | MCFG_DEFAULT_LAYOUT(layout_simon) |
| 656 | 1161 | |
| 657 | 1162 | /* no video! */ |
| r244626 | r244627 | |
| 666 | 1171 | |
| 667 | 1172 | |
| 668 | 1173 | |
| 1174 | |
| 1175 | |
| 1176 | |
| 669 | 1177 | /*************************************************************************** |
| 670 | 1178 | |
| 671 | | Entex Baseball |
| 672 | | * TMS1000NLP MP0914 (die labeled MP0914A) |
| 1179 | Tandy Radio Shack Computerized Arcade (1981, 1982, 1995) |
| 1180 | * TMS1100 CD7282SL |
| 673 | 1181 | |
| 1182 | This handheld contains 12 minigames. It looks and plays like "Fabulous Fred" |
| 1183 | by the Japanese company Mego Corp. in 1980, which in turn is a mix of Merlin |
| 1184 | and Simon. Unlike Merlin and Simon, spin-offs like these were not successful. |
| 1185 | There were releases with and without the prefix "Tandy-12", I don't know |
| 1186 | which name was more common. Also not worth noting is that it needed five |
| 1187 | batteries; 4 C-cells and a 9-volt. |
| 1188 | |
| 1189 | Some of the games require accessories included with the toy (eg. the Baseball |
| 1190 | game is played with a board representing the playing field). To start a game, |
| 1191 | hold the [SELECT] button, then press [START] when the game button lights up. |
| 1192 | As always, refer to the official manual for more information. |
| 1193 | |
| 1194 | See below at the input defs for a list of the games. |
| 1195 | |
| 1196 | |
| 1197 | TODO: |
| 1198 | - output PLA is not verified |
| 1199 | - microinstructions PLA is not verified |
| 1200 | |
| 674 | 1201 | ***************************************************************************/ |
| 675 | 1202 | |
| 676 | | // inputs |
| 677 | | static INPUT_PORTS_START( ebball ) |
| 1203 | void hh_tms1k_state::tandy12_display() |
| 1204 | { |
| 1205 | m_display_maxx = 13; |
| 1206 | |
| 1207 | // O0-O7: button lamps 1-8, R0-R3: button lamps 9-12 |
| 1208 | m_display_state[0] = (m_o << 1 & 0x1fe) | (m_r << 9 & 0x1e00); |
| 1209 | display_update(); |
| 1210 | } |
| 1211 | |
| 1212 | READ8_MEMBER(hh_tms1k_state::tandy12_read_k) |
| 1213 | { |
| 1214 | return read_inputs(5); |
| 1215 | } |
| 1216 | |
| 1217 | WRITE16_MEMBER(hh_tms1k_state::tandy12_write_r) |
| 1218 | { |
| 1219 | // R10: speaker out |
| 1220 | m_speaker->level_w(data >> 10 & 1); |
| 1221 | |
| 1222 | // R5-R9: input mux |
| 1223 | m_inp_mux = data >> 5 & 0x1f; |
| 1224 | |
| 1225 | // other bits: |
| 1226 | m_r = data; |
| 1227 | tandy12_display(); |
| 1228 | } |
| 1229 | |
| 1230 | WRITE16_MEMBER(hh_tms1k_state::tandy12_write_o) |
| 1231 | { |
| 1232 | m_o = data; |
| 1233 | tandy12_display(); |
| 1234 | } |
| 1235 | |
| 1236 | |
| 1237 | /* physical button layout and labels is like this: |
| 1238 | |
| 1239 | REPEAT-2 SPACE-2 |
| 1240 | [O] OFF--ON [O] |
| 1241 | |
| 1242 | [purple]1 [blue]5 [l-green]9 |
| 1243 | ORGAN TAG-IT TREASURE HUNT |
| 1244 | |
| 1245 | [l-orange]2 [turquoise]6 [red]10 |
| 1246 | SONG WRITER ROULETTE COMPETE |
| 1247 | |
| 1248 | [pink]3 [yellow]7 [violet]11 |
| 1249 | REPEAT BASEBALL FIRE AWAY |
| 1250 | |
| 1251 | [green]4 [orange]8 [brown]12 |
| 1252 | TORPEDO REPEAT PLUS HIDE 'N SEEK |
| 1253 | |
| 1254 | [O] [O] [O] |
| 1255 | START SELECT PLAY-2/HIT-7 |
| 1256 | */ |
| 1257 | |
| 1258 | static INPUT_PORTS_START( tandy12 ) |
| 1259 | PORT_START("IN.0") // R5 |
| 1260 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_EQUALS) PORT_CODE(KEYCODE_PLUS_PAD) PORT_NAME("12") |
| 1261 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_MINUS) PORT_CODE(KEYCODE_MINUS_PAD) PORT_NAME("11") |
| 1262 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("10") |
| 1263 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9") |
| 1264 | |
| 1265 | PORT_START("IN.1") // R6 |
| 1266 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_T) PORT_NAME("Space-2") |
| 1267 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_NAME("Play-2/Hit-7") |
| 1268 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_W) PORT_NAME("Select") |
| 1269 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Q) PORT_NAME("Start") |
| 1270 | |
| 1271 | PORT_START("IN.2") // R7 |
| 1272 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) PORT_NAME("Repeat-2") |
| 1273 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 1274 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 1275 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 1276 | |
| 1277 | PORT_START("IN.3") // R8 |
| 1278 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4") |
| 1279 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3") |
| 1280 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2") |
| 1281 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1") |
| 1282 | |
| 1283 | PORT_START("IN.4") // R9 |
| 1284 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8") |
| 1285 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7") |
| 1286 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6") |
| 1287 | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5") |
| 678 | 1288 | INPUT_PORTS_END |
| 679 | 1289 | |
| 680 | | // machine config |
| 681 | | static MACHINE_CONFIG_START( ebball, hh_tms1k_state ) |
| 682 | 1290 | |
| 1291 | static const UINT16 tandy12_output_pla[0x20] = |
| 1292 | { |
| 1293 | // these are certain |
| 1294 | 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, |
| 1295 | 0x80, 0x00, 0x00, 0x00, 0x00, |
| 1296 | |
| 1297 | // rest is unused? |
| 1298 | 0x00, 0x00, 0x00, |
| 1299 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 1300 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| 1301 | }; |
| 1302 | |
| 1303 | |
| 1304 | static MACHINE_CONFIG_START( tandy12, hh_tms1k_state ) |
| 1305 | |
| 683 | 1306 | /* basic machine hardware */ |
| 684 | | MCFG_CPU_ADD("maincpu", TMS1000, 350000) // RC osc. R=43K, C=47pf -> ~350kHz |
| 1307 | MCFG_CPU_ADD("maincpu", TMS1100, 400000) // RC osc. R=39K, C=47pf -> ~400kHz |
| 1308 | MCFG_TMS1XXX_OUTPUT_PLA(tandy12_output_pla) |
| 1309 | MCFG_TMS1XXX_READ_K_CB(READ8(hh_tms1k_state, tandy12_read_k)) |
| 1310 | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, tandy12_write_r)) |
| 1311 | MCFG_TMS1XXX_WRITE_O_CB(WRITE16(hh_tms1k_state, tandy12_write_o)) |
| 685 | 1312 | |
| 686 | | MCFG_DEFAULT_LAYOUT(layout_ebball) |
| 1313 | MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) |
| 1314 | MCFG_DEFAULT_LAYOUT(layout_tandy12) |
| 687 | 1315 | |
| 688 | 1316 | /* no video! */ |
| 689 | 1317 | |
| r244626 | r244627 | |
| 697 | 1325 | |
| 698 | 1326 | /*************************************************************************** |
| 699 | 1327 | |
| 1328 | TMS1100NLL MP3403 DBS 7836 SINGAPORE some game board with 7-segs. |
| 1329 | |
| 1330 | What old electronic game is this? |
| 1331 | |
| 1332 | some clues: |
| 1333 | - it's from 1978 |
| 1334 | - Merlin is MP3404, Amaze-A-Tron is MP3405, this one is MP3403 |
| 1335 | - it plays some short jingles (you need to be lucky with button mashing), |
| 1336 | jingles feel like maybe a horse racing game, or casino |
| 1337 | |
| 1338 | ***************************************************************************/ |
| 1339 | |
| 1340 | READ8_MEMBER(hh_tms1k_state::unk3403_read_k) |
| 1341 | { |
| 1342 | return read_inputs(4); |
| 1343 | } |
| 1344 | |
| 1345 | WRITE16_MEMBER(hh_tms1k_state::unk3403_write_r) |
| 1346 | { |
| 1347 | // R4-R7: input mux |
| 1348 | m_inp_mux = data >> 4 & 0xf; |
| 1349 | |
| 1350 | // R9: speaker out |
| 1351 | m_speaker->level_w(data >> 9 & 1); |
| 1352 | |
| 1353 | // R10: maybe a switch or other button row? |
| 1354 | // others: ? |
| 1355 | } |
| 1356 | |
| 1357 | WRITE16_MEMBER(hh_tms1k_state::unk3403_write_o) |
| 1358 | { |
| 1359 | // ? |
| 1360 | } |
| 1361 | |
| 1362 | static INPUT_PORTS_START( unk3403 ) |
| 1363 | PORT_START("IN.0") // R4 |
| 1364 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) |
| 1365 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) |
| 1366 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) |
| 1367 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) |
| 1368 | |
| 1369 | PORT_START("IN.1") // R5 |
| 1370 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) |
| 1371 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) |
| 1372 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) |
| 1373 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) |
| 1374 | |
| 1375 | PORT_START("IN.2") // R6 |
| 1376 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) |
| 1377 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) |
| 1378 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) |
| 1379 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) // reset/newgame? |
| 1380 | |
| 1381 | PORT_START("IN.3") // R7 |
| 1382 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) |
| 1383 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) |
| 1384 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) |
| 1385 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) |
| 1386 | INPUT_PORTS_END |
| 1387 | |
| 1388 | static const UINT16 unk3403_output_pla[0x20] = |
| 1389 | { |
| 1390 | /* O output PLA configuration currently unknown */ |
| 1391 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
| 1392 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
| 1393 | 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, |
| 1394 | 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f |
| 1395 | }; |
| 1396 | |
| 1397 | |
| 1398 | static MACHINE_CONFIG_START( unk3403, hh_tms1k_state ) |
| 1399 | |
| 1400 | /* basic machine hardware */ |
| 1401 | MCFG_CPU_ADD("maincpu", TMS1100, 350000) // approximation - unknown freq |
| 1402 | MCFG_TMS1XXX_OUTPUT_PLA(unk3403_output_pla) |
| 1403 | MCFG_TMS1XXX_READ_K_CB(READ8(hh_tms1k_state, unk3403_read_k)) |
| 1404 | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, unk3403_write_r)) |
| 1405 | MCFG_TMS1XXX_WRITE_O_CB(WRITE16(hh_tms1k_state, unk3403_write_o)) |
| 1406 | |
| 1407 | /* no video! */ |
| 1408 | |
| 1409 | /* sound hardware */ |
| 1410 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 1411 | MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) |
| 1412 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 1413 | MACHINE_CONFIG_END |
| 1414 | |
| 1415 | |
| 1416 | /*************************************************************************** |
| 1417 | |
| 700 | 1418 | Game driver(s) |
| 701 | 1419 | |
| 702 | 1420 | ***************************************************************************/ |
| 703 | 1421 | |
| 704 | 1422 | |
| 1423 | ROM_START( mathmagi ) |
| 1424 | ROM_REGION( 0x800, "maincpu", 0 ) |
| 1425 | ROM_LOAD( "mp1030", 0x0000, 0x800, CRC(a81d7ccb) SHA1(4756ce42f1ea28ce5fe6498312f8306f10370969) ) |
| 1426 | |
| 1427 | ROM_REGION( 867, "maincpu:mpla", 0 ) |
| 1428 | ROM_LOAD( "tms1100_default_mpla.pla", 0, 867, BAD_DUMP CRC(62445fc9) SHA1(d6297f2a4bc7a870b76cc498d19dbb0ce7d69fec) ) // not verified |
| 1429 | ROM_REGION( 365, "maincpu:opla", 0 ) |
| 1430 | ROM_LOAD( "tms1100_mathmagi_opla.pla", 0, 365, NO_DUMP ) |
| 1431 | ROM_END |
| 1432 | |
| 1433 | |
| 705 | 1434 | ROM_START( amaztron ) |
| 706 | 1435 | ROM_REGION( 0x0800, "maincpu", 0 ) |
| 707 | 1436 | ROM_LOAD( "tms1100nll_mp3405", 0x0000, 0x0800, CRC(9cbc0009) SHA1(17772681271b59280687492f37fa0859998f041d) ) |
| r244626 | r244627 | |
| 737 | 1466 | ROM_END |
| 738 | 1467 | |
| 739 | 1468 | |
| 1469 | ROM_START( elecdet ) |
| 1470 | ROM_REGION( 0x1000, "maincpu", 0 ) |
| 1471 | ROM_LOAD( "tms0980nll_mp6100a", 0x0000, 0x1000, CRC(6f396bb8) SHA1(1f104d4ca9bee0d4572be4779b7551dfe20c4f04) ) |
| 1472 | |
| 1473 | ROM_REGION( 1246, "maincpu:ipla", 0 ) |
| 1474 | ROM_LOAD( "tms0980_default_ipla.pla", 0, 1246, CRC(42db9a38) SHA1(2d127d98028ec8ec6ea10c179c25e447b14ba4d0) ) |
| 1475 | ROM_REGION( 1982, "maincpu:mpla", 0 ) |
| 1476 | ROM_LOAD( "tms0980_default_mpla.pla", 0, 1982, CRC(3709014f) SHA1(d28ee59ded7f3b9dc3f0594a32a98391b6e9c961) ) |
| 1477 | ROM_REGION( 352, "maincpu:opla", 0 ) |
| 1478 | ROM_LOAD( "tms0980_elecdet_opla.pla", 0, 352, CRC(652d19c3) SHA1(75550c2b293453b6b9efed88c8cc77195a53161f) ) |
| 1479 | ROM_REGION( 157, "maincpu:spla", 0 ) |
| 1480 | ROM_LOAD( "tms0980_elecdet_spla.pla", 0, 157, CRC(399aa481) SHA1(72c56c58fde3fbb657d69647a9543b5f8fc74279) ) |
| 1481 | ROM_END |
| 1482 | |
| 1483 | |
| 1484 | ROM_START( starwbc ) |
| 1485 | ROM_REGION( 0x0800, "maincpu", 0 ) |
| 1486 | ROM_LOAD( "mp3438a", 0x0000, 0x0800, CRC(c12b7069) SHA1(d1f39c69a543c128023ba11cc6228bacdfab04de) ) |
| 1487 | |
| 1488 | ROM_REGION( 867, "maincpu:mpla", 0 ) |
| 1489 | ROM_LOAD( "tms1100_starwbc_mpla.pla", 0, 867, CRC(03574895) SHA1(04407cabfb3adee2ee5e4218612cb06c12c540f4) ) |
| 1490 | ROM_REGION( 365, "maincpu:opla", 0 ) |
| 1491 | ROM_LOAD( "tms1100_starwbc_opla.pla", 0, 365, CRC(d358a76d) SHA1(06b60b207540e9b726439141acadea9aba718013) ) |
| 1492 | ROM_END |
| 1493 | |
| 1494 | ROM_START( starwbcp ) |
| 1495 | ROM_REGION( 0x0800, "maincpu", 0 ) |
| 1496 | ROM_LOAD( "us4270755", 0x0000, 0x0800, BAD_DUMP CRC(fb3332f2) SHA1(a79ac81e239983cd699b7cfcc55f89b203b2c9ec) ) // from patent US4270755, may have errors |
| 1497 | |
| 1498 | ROM_REGION( 867, "maincpu:mpla", 0 ) |
| 1499 | ROM_LOAD( "tms1100_starwbc_mpla.pla", 0, 867, CRC(03574895) SHA1(04407cabfb3adee2ee5e4218612cb06c12c540f4) ) |
| 1500 | ROM_REGION( 365, "maincpu:opla", 0 ) |
| 1501 | ROM_LOAD( "tms1100_starwbc_opla.pla", 0, 365, CRC(d358a76d) SHA1(06b60b207540e9b726439141acadea9aba718013) ) |
| 1502 | ROM_END |
| 1503 | |
| 1504 | |
| 1505 | |
| 740 | 1506 | ROM_START( comp4 ) |
| 741 | 1507 | ROM_REGION( 0x0400, "maincpu", 0 ) |
| 742 | 1508 | ROM_LOAD( "tmc0904nl_cp0904a", 0x0000, 0x0400, CRC(6233ee1b) SHA1(738e109b38c97804b4ec52bed80b00a8634ad453) ) |
| r244626 | r244627 | |
| 762 | 1528 | ROM_LOAD( "tms1000_simon_opla.pla", 0, 365, CRC(2943c71b) SHA1(bd5bb55c57e7ba27e49c645937ec1d4e67506601) ) |
| 763 | 1529 | ROM_END |
| 764 | 1530 | |
| 1531 | ROM_START( tandy12 ) |
| 1532 | ROM_REGION( 0x800, "maincpu", 0 ) |
| 1533 | ROM_LOAD( "cd7282sl", 0x0000, 0x800, CRC(a10013dd) SHA1(42ebd3de3449f371b99937f9df39c240d15ac686) ) |
| 765 | 1534 | |
| 1535 | ROM_REGION( 867, "maincpu:mpla", 0 ) |
| 1536 | ROM_LOAD( "tms1100_default_mpla.pla", 0, 867, BAD_DUMP CRC(62445fc9) SHA1(d6297f2a4bc7a870b76cc498d19dbb0ce7d69fec) ) // not verified |
| 1537 | ROM_REGION( 365, "maincpu:opla", 0 ) |
| 1538 | ROM_LOAD( "tms1100_tandy12_opla.pla", 0, 365, NO_DUMP ) |
| 1539 | ROM_END |
| 766 | 1540 | |
| 1541 | ROM_START( unk3403 ) |
| 1542 | ROM_REGION( 0x0800, "maincpu", 0 ) |
| 1543 | ROM_LOAD( "tms1100nll_mp3403", 0x0000, 0x0800, CRC(9eabaa7d) SHA1(b1f54587ed7f2bbf3a5d49075c807296384c2b06) ) |
| 767 | 1544 | |
| 1545 | ROM_REGION( 867, "maincpu:mpla", 0 ) |
| 1546 | ROM_LOAD( "tms1100_default_mpla.pla", 0, 867, BAD_DUMP CRC(62445fc9) SHA1(d6297f2a4bc7a870b76cc498d19dbb0ce7d69fec) ) // not verified |
| 1547 | ROM_REGION( 365, "maincpu:opla", 0 ) |
| 1548 | ROM_LOAD( "tms1100_xxx_opla.pla", 0, 365, NO_DUMP ) |
| 1549 | ROM_END |
| 1550 | |
| 1551 | |
| 1552 | |
| 1553 | |
| 1554 | |
| 1555 | |
| 1556 | |
| 1557 | |
| 1558 | CONS( 1980, mathmagi, 0, 0, mathmagi, mathmagi, driver_device, 0, "APF Electronics Inc.", "Mathemagician", GAME_SUPPORTS_SAVE | GAME_NO_SOUND_HW ) |
| 1559 | |
| 768 | 1560 | CONS( 1979, amaztron, 0, 0, amaztron, amaztron, driver_device, 0, "Coleco", "Amaze-A-Tron", GAME_SUPPORTS_SAVE ) |
| 769 | 1561 | CONS( 1981, tc4, 0, 0, tc4, tc4, driver_device, 0, "Coleco", "Total Control 4", GAME_SUPPORTS_SAVE ) |
| 770 | 1562 | |
| 771 | 1563 | CONS( 1979, ebball, 0, 0, ebball, ebball, driver_device, 0, "Entex", "Baseball (Entex)", GAME_SUPPORTS_SAVE | GAME_NOT_WORKING ) |
| 772 | 1564 | |
| 1565 | CONS( 1979, elecdet, 0, 0, elecdet, elecdet, driver_device, 0, "Ideal", "Electronic Detective", GAME_SUPPORTS_SAVE ) |
| 1566 | |
| 1567 | CONS( 1979, starwbc, 0, 0, starwbc, starwbc, driver_device, 0, "Kenner", "Star Wars - Electronic Battle Command", GAME_SUPPORTS_SAVE ) |
| 1568 | CONS( 1979, starwbcp, starwbc, 0, starwbc, starwbc, driver_device, 0, "Kenner", "Star Wars - Electronic Battle Command (prototype)", GAME_SUPPORTS_SAVE ) |
| 1569 | |
| 773 | 1570 | CONS( 1977, comp4, 0, 0, comp4, comp4, driver_device, 0, "Milton Bradley", "Comp IV", GAME_SUPPORTS_SAVE | GAME_NO_SOUND_HW ) |
| 774 | 1571 | CONS( 1978, simon, 0, 0, simon, simon, driver_device, 0, "Milton Bradley", "Simon (Rev. A)", GAME_SUPPORTS_SAVE ) |
| 1572 | |
| 1573 | CONS( 1981, tandy12, 0, 0, tandy12, tandy12, driver_device, 0, "Tandy Radio Shack", "Tandy-12: Computerized Arcade", GAME_SUPPORTS_SAVE ) |
| 1574 | |
| 1575 | CONS( 1978, unk3403, 0, 0, unk3403, unk3403, driver_device, 0, "<unknown>", "unknown TMS1100 electronic game", GAME_SUPPORTS_SAVE | GAME_NOT_WORKING ) |
trunk/src/mess/drivers/starwbc.c
| r244626 | r244627 | |
| 1 | | // license:BSD-3-Clause |
| 2 | | // copyright-holders:hap |
| 3 | | /*************************************************************************** |
| 4 | | |
| 5 | | Kenner Star Wars - Electronic Battle Command |
| 6 | | * TMS1100 MCU, labeled MP3438A |
| 7 | | |
| 8 | | This is a small tabletop space-dogfighting game. To start the game, |
| 9 | | press BASIC/INTER/ADV and enter P#(number of players), then |
| 10 | | START TURN. 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 "starwbc.lh" |
| 19 | | |
| 20 | | // master clock is a single stage RC oscillator: R=51K, C=47pf, |
| 21 | | // according to the TMS 1000 series data manual this is around 350kHz |
| 22 | | #define MASTER_CLOCK (350000) |
| 23 | | |
| 24 | | |
| 25 | | class starwbc_state : public driver_device |
| 26 | | { |
| 27 | | public: |
| 28 | | starwbc_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<5> m_button_matrix; |
| 37 | | required_device<speaker_sound_device> m_speaker; |
| 38 | | |
| 39 | | UINT16 m_r; |
| 40 | | UINT16 m_o; |
| 41 | | |
| 42 | | UINT16 m_display_state[0x10]; |
| 43 | | UINT16 m_display_cache[0x10]; |
| 44 | | UINT8 m_display_decay[0x100]; |
| 45 | | |
| 46 | | DECLARE_READ8_MEMBER(read_k); |
| 47 | | DECLARE_WRITE16_MEMBER(write_o); |
| 48 | | DECLARE_WRITE16_MEMBER(write_r); |
| 49 | | |
| 50 | | TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick); |
| 51 | | void display_update(); |
| 52 | | void prepare_and_update(); |
| 53 | | |
| 54 | | virtual void machine_start(); |
| 55 | | }; |
| 56 | | |
| 57 | | |
| 58 | | |
| 59 | | /*************************************************************************** |
| 60 | | |
| 61 | | LED Display |
| 62 | | |
| 63 | | ***************************************************************************/ |
| 64 | | |
| 65 | | // The device strobes the outputs very fast, it is unnoticeable to the user. |
| 66 | | // To prevent flickering here, we need to simulate a decay. |
| 67 | | |
| 68 | | // decay time, in steps of 1ms |
| 69 | | #define DISPLAY_DECAY_TIME 40 |
| 70 | | |
| 71 | | void starwbc_state::display_update() |
| 72 | | { |
| 73 | | UINT16 active_state[0x10]; |
| 74 | | |
| 75 | | for (int i = 0; i < 0x10; i++) |
| 76 | | { |
| 77 | | active_state[i] = 0; |
| 78 | | |
| 79 | | for (int j = 0; j < 0x10; j++) |
| 80 | | { |
| 81 | | int di = j << 4 | i; |
| 82 | | |
| 83 | | // turn on powered segments |
| 84 | | if (m_display_state[i] >> j & 1) |
| 85 | | m_display_decay[di] = DISPLAY_DECAY_TIME; |
| 86 | | |
| 87 | | // determine active state |
| 88 | | int ds = (m_display_decay[di] != 0) ? 1 : 0; |
| 89 | | active_state[i] |= (ds << j); |
| 90 | | } |
| 91 | | } |
| 92 | | |
| 93 | | // on difference, send to output |
| 94 | | for (int i = 0; i < 0x10; i++) |
| 95 | | if (m_display_cache[i] != active_state[i]) |
| 96 | | { |
| 97 | | output_set_digit_value(i, active_state[i]); |
| 98 | | |
| 99 | | for (int j = 0; j < 8; j++) |
| 100 | | output_set_lamp_value(i*10 + j, active_state[i] >> j & 1); |
| 101 | | } |
| 102 | | |
| 103 | | memcpy(m_display_cache, active_state, sizeof(m_display_cache)); |
| 104 | | } |
| 105 | | |
| 106 | | TIMER_DEVICE_CALLBACK_MEMBER(starwbc_state::display_decay_tick) |
| 107 | | { |
| 108 | | // slowly turn off unpowered segments |
| 109 | | for (int i = 0; i < 0x100; i++) |
| 110 | | if (!(m_display_state[i & 0xf] >> (i>>4) & 1) && m_display_decay[i]) |
| 111 | | m_display_decay[i]--; |
| 112 | | |
| 113 | | display_update(); |
| 114 | | } |
| 115 | | |
| 116 | | void starwbc_state::prepare_and_update() |
| 117 | | { |
| 118 | | UINT8 o = (m_o << 4 & 0xf0) | (m_o >> 4 & 0x0f); |
| 119 | | const UINT8 mask[5] = { 0x30, 0xff, 0xff, 0x7f, 0x7f }; |
| 120 | | |
| 121 | | // R0,R2,R4,R6,R8 |
| 122 | | for (int i = 0; i < 5; i++) |
| 123 | | m_display_state[i*2] = (m_r >> (i*2) & 1) ? (o & mask[i]) : 0; |
| 124 | | |
| 125 | | display_update(); |
| 126 | | } |
| 127 | | |
| 128 | | |
| 129 | | |
| 130 | | /*************************************************************************** |
| 131 | | |
| 132 | | I/O |
| 133 | | |
| 134 | | ***************************************************************************/ |
| 135 | | |
| 136 | | READ8_MEMBER(starwbc_state::read_k) |
| 137 | | { |
| 138 | | UINT8 k = 0; |
| 139 | | |
| 140 | | // read selected button rows |
| 141 | | for (int i = 0; i < 5; i++) |
| 142 | | { |
| 143 | | const int ki[5] = { 0, 1, 3, 5, 7 }; |
| 144 | | if (m_r >> ki[i] & 1) |
| 145 | | k |= m_button_matrix[i]->read(); |
| 146 | | } |
| 147 | | |
| 148 | | return k; |
| 149 | | } |
| 150 | | |
| 151 | | WRITE16_MEMBER(starwbc_state::write_r) |
| 152 | | { |
| 153 | | // R0,R2,R4: select lamp row |
| 154 | | // R6,R8: select digit |
| 155 | | // R0,R1,R3,R5,R7: input mux |
| 156 | | // R9: piezo speaker |
| 157 | | m_speaker->level_w(data >> 9 & 1); |
| 158 | | |
| 159 | | m_r = data; |
| 160 | | prepare_and_update(); |
| 161 | | } |
| 162 | | |
| 163 | | WRITE16_MEMBER(starwbc_state::write_o) |
| 164 | | { |
| 165 | | // O0-O7: leds state |
| 166 | | m_o = data; |
| 167 | | prepare_and_update(); |
| 168 | | } |
| 169 | | |
| 170 | | |
| 171 | | |
| 172 | | /*************************************************************************** |
| 173 | | |
| 174 | | Inputs |
| 175 | | |
| 176 | | ***************************************************************************/ |
| 177 | | |
| 178 | | /* physical button layout and labels is like this: |
| 179 | | |
| 180 | | (reconnnaissance=yellow) (tactical reaction=green) |
| 181 | | [MAGNA] [ENEMY] [EM] [BS] [SCR] |
| 182 | | |
| 183 | | [BASIC] [INTER] [START TURN] [END TURN] [MOVE] [FIRE] |
| 184 | | [ADV] [P#] [<] [^] [>] [v] |
| 185 | | (game=blue) (maneuvers=red) */ |
| 186 | | |
| 187 | | static INPUT_PORTS_START( starwbc ) |
| 188 | | PORT_START("IN.0") // R0 |
| 189 | | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_NAME("Basic Game") |
| 190 | | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_NAME("Intermediate Game") |
| 191 | | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("Advanced Game") |
| 192 | | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_N) PORT_NAME("Player Number") |
| 193 | | |
| 194 | | PORT_START("IN.1") // R1 |
| 195 | | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_ENTER) PORT_NAME("Start Turn") |
| 196 | | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_UNUSED) |
| 197 | | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_UNUSED) |
| 198 | | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CODE(KEYCODE_DEL) PORT_NAME("End Turn") |
| 199 | | |
| 200 | | PORT_START("IN.2") // R3 |
| 201 | | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("Magna Scan") // only used in adv. game |
| 202 | | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("Enemy Scan") // only used in adv. game |
| 203 | | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_UNUSED) |
| 204 | | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_NAME("Screen Up") |
| 205 | | |
| 206 | | PORT_START("IN.3") // R5 |
| 207 | | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Evasive Maneuvers") |
| 208 | | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_M) PORT_NAME("Move") |
| 209 | | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F) PORT_NAME("Fire") |
| 210 | | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_B) PORT_NAME("Battle Stations") |
| 211 | | |
| 212 | | PORT_START("IN.4") // R7 |
| 213 | | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_LEFT) PORT_NAME("Left") |
| 214 | | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_UP) PORT_NAME("Up") |
| 215 | | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_DOWN) PORT_NAME("Down") |
| 216 | | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Right") |
| 217 | | INPUT_PORTS_END |
| 218 | | |
| 219 | | |
| 220 | | |
| 221 | | /*************************************************************************** |
| 222 | | |
| 223 | | Machine Config |
| 224 | | |
| 225 | | ***************************************************************************/ |
| 226 | | |
| 227 | | void starwbc_state::machine_start() |
| 228 | | { |
| 229 | | // zerofill |
| 230 | | memset(m_display_state, 0, sizeof(m_display_state)); |
| 231 | | memset(m_display_cache, 0, sizeof(m_display_cache)); |
| 232 | | memset(m_display_decay, 0, sizeof(m_display_decay)); |
| 233 | | |
| 234 | | m_r = 0; |
| 235 | | m_o = 0; |
| 236 | | |
| 237 | | // register for savestates |
| 238 | | save_item(NAME(m_display_state)); |
| 239 | | save_item(NAME(m_display_cache)); |
| 240 | | save_item(NAME(m_display_decay)); |
| 241 | | |
| 242 | | save_item(NAME(m_r)); |
| 243 | | save_item(NAME(m_o)); |
| 244 | | } |
| 245 | | |
| 246 | | |
| 247 | | static MACHINE_CONFIG_START( starwbc, starwbc_state ) |
| 248 | | |
| 249 | | /* basic machine hardware */ |
| 250 | | MCFG_CPU_ADD("maincpu", TMS1100, MASTER_CLOCK) |
| 251 | | MCFG_TMS1XXX_READ_K_CB(READ8(starwbc_state, read_k)) |
| 252 | | MCFG_TMS1XXX_WRITE_O_CB(WRITE16(starwbc_state, write_o)) |
| 253 | | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(starwbc_state, write_r)) |
| 254 | | |
| 255 | | MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", starwbc_state, display_decay_tick, attotime::from_msec(1)) |
| 256 | | |
| 257 | | MCFG_DEFAULT_LAYOUT(layout_starwbc) |
| 258 | | |
| 259 | | /* no video! */ |
| 260 | | |
| 261 | | /* sound hardware */ |
| 262 | | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 263 | | MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) |
| 264 | | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 265 | | MACHINE_CONFIG_END |
| 266 | | |
| 267 | | |
| 268 | | |
| 269 | | /*************************************************************************** |
| 270 | | |
| 271 | | Game driver(s) |
| 272 | | |
| 273 | | ***************************************************************************/ |
| 274 | | |
| 275 | | ROM_START( starwbc ) |
| 276 | | ROM_REGION( 0x0800, "maincpu", 0 ) |
| 277 | | ROM_LOAD( "mp3438a", 0x0000, 0x0800, CRC(c12b7069) SHA1(d1f39c69a543c128023ba11cc6228bacdfab04de) ) |
| 278 | | |
| 279 | | ROM_REGION( 867, "maincpu:mpla", 0 ) |
| 280 | | ROM_LOAD( "tms1100_starwbc_mpla.pla", 0, 867, CRC(03574895) SHA1(04407cabfb3adee2ee5e4218612cb06c12c540f4) ) |
| 281 | | ROM_REGION( 365, "maincpu:opla", 0 ) |
| 282 | | ROM_LOAD( "tms1100_starwbc_opla.pla", 0, 365, CRC(d358a76d) SHA1(06b60b207540e9b726439141acadea9aba718013) ) |
| 283 | | ROM_END |
| 284 | | |
| 285 | | ROM_START( starwbcp ) |
| 286 | | ROM_REGION( 0x0800, "maincpu", 0 ) |
| 287 | | ROM_LOAD( "us4270755", 0x0000, 0x0800, BAD_DUMP CRC(fb3332f2) SHA1(a79ac81e239983cd699b7cfcc55f89b203b2c9ec) ) // from patent US4270755, may have errors |
| 288 | | |
| 289 | | ROM_REGION( 867, "maincpu:mpla", 0 ) |
| 290 | | ROM_LOAD( "tms1100_starwbc_mpla.pla", 0, 867, CRC(03574895) SHA1(04407cabfb3adee2ee5e4218612cb06c12c540f4) ) |
| 291 | | ROM_REGION( 365, "maincpu:opla", 0 ) |
| 292 | | ROM_LOAD( "tms1100_starwbc_opla.pla", 0, 365, CRC(d358a76d) SHA1(06b60b207540e9b726439141acadea9aba718013) ) |
| 293 | | ROM_END |
| 294 | | |
| 295 | | |
| 296 | | CONS( 1979, starwbc, 0, 0, starwbc, starwbc, driver_device, 0, "Kenner", "Star Wars - Electronic Battle Command", GAME_SUPPORTS_SAVE ) |
| 297 | | CONS( 1979, starwbcp, starwbc, 0, starwbc, starwbc, driver_device, 0, "Kenner", "Star Wars - Electronic Battle Command (prototype)", GAME_SUPPORTS_SAVE ) |
trunk/src/mess/drivers/tandy12.c
| r244626 | r244627 | |
| 1 | | // license:BSD-3-Clause |
| 2 | | // copyright-holders:hap |
| 3 | | /*************************************************************************** |
| 4 | | |
| 5 | | Tandy Radio Shack Computerized Arcade (1981, 1982, 1995) |
| 6 | | * TMS1100 CD7282SL |
| 7 | | |
| 8 | | This handheld contains 12 minigames. It looks and plays like "Fabulous Fred" |
| 9 | | by the Japanese company Mego Corp. in 1980, which in turn is a mix of Merlin |
| 10 | | and Simon. Unlike Merlin and Simon, spin-offs like these were not successful. |
| 11 | | There were releases with and without the prefix "Tandy-12", I don't know |
| 12 | | which name was more common. Also not worth noting is that it needed five |
| 13 | | batteries; 4 C-cells and a 9-volt. |
| 14 | | |
| 15 | | Some of the games require accessories included with the toy (eg. the Baseball |
| 16 | | game is played with a board representing the playing field). To start a game, |
| 17 | | hold the [SELECT] button, then press [START] when the game button lights up. |
| 18 | | As always, refer to the official manual for more information. |
| 19 | | |
| 20 | | See below at the input defs for a list of the games. |
| 21 | | |
| 22 | | |
| 23 | | TODO: |
| 24 | | - output PLA is not verified |
| 25 | | - microinstructions PLA is not verified |
| 26 | | |
| 27 | | ***************************************************************************/ |
| 28 | | |
| 29 | | #include "emu.h" |
| 30 | | #include "cpu/tms0980/tms0980.h" |
| 31 | | #include "sound/speaker.h" |
| 32 | | |
| 33 | | #include "tandy12.lh" // clickable |
| 34 | | |
| 35 | | // master clock is a single stage RC oscillator: R=39K, C=47pf, |
| 36 | | // according to the TMS 1000 series data manual this is around 400kHz |
| 37 | | #define MASTER_CLOCK (400000) |
| 38 | | |
| 39 | | |
| 40 | | class tandy12_state : public driver_device |
| 41 | | { |
| 42 | | public: |
| 43 | | tandy12_state(const machine_config &mconfig, device_type type, const char *tag) |
| 44 | | : driver_device(mconfig, type, tag), |
| 45 | | m_maincpu(*this, "maincpu"), |
| 46 | | m_button_matrix(*this, "IN"), |
| 47 | | m_speaker(*this, "speaker") |
| 48 | | { } |
| 49 | | |
| 50 | | required_device<tms1xxx_cpu_device> m_maincpu; |
| 51 | | required_ioport_array<5> m_button_matrix; |
| 52 | | required_device<speaker_sound_device> m_speaker; |
| 53 | | |
| 54 | | UINT16 m_r; |
| 55 | | |
| 56 | | DECLARE_READ8_MEMBER(read_k); |
| 57 | | DECLARE_WRITE16_MEMBER(write_o); |
| 58 | | DECLARE_WRITE16_MEMBER(write_r); |
| 59 | | |
| 60 | | virtual void machine_start(); |
| 61 | | }; |
| 62 | | |
| 63 | | |
| 64 | | /*************************************************************************** |
| 65 | | |
| 66 | | I/O |
| 67 | | |
| 68 | | ***************************************************************************/ |
| 69 | | |
| 70 | | READ8_MEMBER(tandy12_state::read_k) |
| 71 | | { |
| 72 | | UINT8 k = 0; |
| 73 | | |
| 74 | | // read selected button rows |
| 75 | | for (int i = 0; i < 5; i++) |
| 76 | | if (m_r >> (i+5) & 1) |
| 77 | | k |= m_button_matrix[i]->read(); |
| 78 | | |
| 79 | | return k; |
| 80 | | } |
| 81 | | |
| 82 | | WRITE16_MEMBER(tandy12_state::write_o) |
| 83 | | { |
| 84 | | // O0-O7: button lamps 1-8 |
| 85 | | for (int i = 0; i < 8; i++) |
| 86 | | output_set_lamp_value(i+1, data >> i & 1); |
| 87 | | } |
| 88 | | |
| 89 | | WRITE16_MEMBER(tandy12_state::write_r) |
| 90 | | { |
| 91 | | // R0-R3: button lamps 9-12 |
| 92 | | for (int i = 0; i < 4; i++) |
| 93 | | output_set_lamp_value(i+1 + 8, data >> i & 1); |
| 94 | | |
| 95 | | // R10: speaker out |
| 96 | | m_speaker->level_w(data >> 10 & 1); |
| 97 | | |
| 98 | | // R5-R9: input mux |
| 99 | | m_r = data; |
| 100 | | } |
| 101 | | |
| 102 | | |
| 103 | | |
| 104 | | /*************************************************************************** |
| 105 | | |
| 106 | | Inputs |
| 107 | | |
| 108 | | ***************************************************************************/ |
| 109 | | |
| 110 | | /* physical button layout and labels is like this: |
| 111 | | |
| 112 | | REPEAT-2 SPACE-2 |
| 113 | | [O] OFF--ON [O] |
| 114 | | |
| 115 | | [purple]1 [blue]5 [l-green]9 |
| 116 | | ORGAN TAG-IT TREASURE HUNT |
| 117 | | |
| 118 | | [l-orange]2 [turquoise]6 [red]10 |
| 119 | | SONG WRITER ROULETTE COMPETE |
| 120 | | |
| 121 | | [pink]3 [yellow]7 [violet]11 |
| 122 | | REPEAT BASEBALL FIRE AWAY |
| 123 | | |
| 124 | | [green]4 [orange]8 [brown]12 |
| 125 | | TORPEDO REPEAT PLUS HIDE 'N SEEK |
| 126 | | |
| 127 | | [O] [O] [O] |
| 128 | | START SELECT PLAY-2/HIT-7 |
| 129 | | */ |
| 130 | | |
| 131 | | static INPUT_PORTS_START( tandy12 ) |
| 132 | | PORT_START("IN.0") // R5 |
| 133 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_EQUALS) PORT_CODE(KEYCODE_PLUS_PAD) PORT_NAME("12") |
| 134 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_MINUS) PORT_CODE(KEYCODE_MINUS_PAD) PORT_NAME("11") |
| 135 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("10") |
| 136 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9") |
| 137 | | |
| 138 | | PORT_START("IN.1") // R6 |
| 139 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_T) PORT_NAME("Space-2") |
| 140 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_NAME("Play-2/Hit-7") |
| 141 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_W) PORT_NAME("Select") |
| 142 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Q) PORT_NAME("Start") |
| 143 | | |
| 144 | | PORT_START("IN.2") // R7 |
| 145 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) PORT_NAME("Repeat-2") |
| 146 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 147 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 148 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 149 | | |
| 150 | | PORT_START("IN.3") // R8 |
| 151 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4") |
| 152 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3") |
| 153 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2") |
| 154 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1") |
| 155 | | |
| 156 | | PORT_START("IN.4") // R9 |
| 157 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8") |
| 158 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7") |
| 159 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6") |
| 160 | | PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5") |
| 161 | | INPUT_PORTS_END |
| 162 | | |
| 163 | | |
| 164 | | |
| 165 | | /*************************************************************************** |
| 166 | | |
| 167 | | Machine Config |
| 168 | | |
| 169 | | ***************************************************************************/ |
| 170 | | |
| 171 | | void tandy12_state::machine_start() |
| 172 | | { |
| 173 | | m_r = 0; |
| 174 | | save_item(NAME(m_r)); |
| 175 | | } |
| 176 | | |
| 177 | | |
| 178 | | static const UINT16 tandy12_output_pla[0x20] = |
| 179 | | { |
| 180 | | // these are certain |
| 181 | | 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, |
| 182 | | 0x80, 0x00, 0x00, 0x00, 0x00, |
| 183 | | |
| 184 | | // rest is unused? |
| 185 | | 0x00, 0x00, 0x00, |
| 186 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 187 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| 188 | | }; |
| 189 | | |
| 190 | | |
| 191 | | static MACHINE_CONFIG_START( tandy12, tandy12_state ) |
| 192 | | |
| 193 | | /* basic machine hardware */ |
| 194 | | MCFG_CPU_ADD("maincpu", TMS1100, MASTER_CLOCK) |
| 195 | | MCFG_TMS1XXX_OUTPUT_PLA(tandy12_output_pla) |
| 196 | | MCFG_TMS1XXX_READ_K_CB(READ8(tandy12_state, read_k)) |
| 197 | | MCFG_TMS1XXX_WRITE_O_CB(WRITE16(tandy12_state, write_o)) |
| 198 | | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(tandy12_state, write_r)) |
| 199 | | |
| 200 | | MCFG_DEFAULT_LAYOUT(layout_tandy12) |
| 201 | | |
| 202 | | /* no video! */ |
| 203 | | |
| 204 | | /* sound hardware */ |
| 205 | | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 206 | | MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) |
| 207 | | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 208 | | MACHINE_CONFIG_END |
| 209 | | |
| 210 | | |
| 211 | | |
| 212 | | /*************************************************************************** |
| 213 | | |
| 214 | | Game driver(s) |
| 215 | | |
| 216 | | ***************************************************************************/ |
| 217 | | |
| 218 | | ROM_START( tandy12 ) |
| 219 | | ROM_REGION( 0x800, "maincpu", 0 ) |
| 220 | | ROM_LOAD( "cd7282sl", 0x0000, 0x800, CRC(a10013dd) SHA1(42ebd3de3449f371b99937f9df39c240d15ac686) ) |
| 221 | | |
| 222 | | ROM_REGION( 867, "maincpu:mpla", 0 ) |
| 223 | | ROM_LOAD( "tms1100_default_mpla.pla", 0, 867, BAD_DUMP CRC(62445fc9) SHA1(d6297f2a4bc7a870b76cc498d19dbb0ce7d69fec) ) // not verified |
| 224 | | ROM_REGION( 365, "maincpu:opla", 0 ) |
| 225 | | ROM_LOAD( "tms1100_tandy12_opla.pla", 0, 365, NO_DUMP ) |
| 226 | | ROM_END |
| 227 | | |
| 228 | | |
| 229 | | CONS( 1981, tandy12, 0, 0, tandy12, tandy12, driver_device, 0, "Tandy Radio Shack", "Tandy-12: Computerized Arcade", GAME_SUPPORTS_SAVE ) |