1 // license:BSD-3-Clause
2 // copyright-holders:hap
3 // thanks-to:Kevin Horton, Sean Riddle
4 /***************************************************************************
5
6 NEC uCOM4 MCU tabletops/handhelds or other simple devices,
7 most of them (emulated ones) are VFD electronic games/toys.
8
9 Commonly used VFD(vacuum fluorescent display) are by NEC or Futaba.
10
11 NEC FIP9AM20T (example, Epoch Astro Command)
12 grcss
13
14 FIP = fluorescent indicator panel
15 g = number of grids
16 r = revision of the VFD
17 c = custom display
18 s = unique display part number
19
20
21 known chips:
22
23 serial device etc.
24 ----------------------------------------------------------------
25 *055 uPD546C 1979, Fidelity Checker Challenger (CR)
26
27 @017 uPD552C 1979, Bambino UFO Master-Blaster Station (ET-02)
28 @042 uPD552C 1980, Tomy Cosmic Combat (TN-??)
29 @043 uPD552C 1979, Bambino Kick The Goal Soccer (ET-10)
30 *044 uPD552C 1979, Bambino Lucky Puck Ice Hockey (ET-08)
31 @048 uPD552C 1980, Tomy Tennis (TN-04)
32 @049 uPD552C 1981, Bambino Safari (ET-11)
33 @054 uPD552C 1980, Epoch Invader From Space
34
35 @031 uPD553C 1979, Bambino Superstar Football (ET-03)
36 @049 uPD553C 1979, Mego Mini-Vid: Break Free
37 @055 uPD553C 1980, Bambino Space Laser Fight (ET-12)
38 *073 uPD553C 1980, Sony ST-J75 FM Stereo Tuner
39 @080 uPD553C 1980, Epoch Electronic Football
40 *102 uPD553C 1981, Bandai Block Out
41 @153 uPD553C 1981, Epoch Galaxy II
42 @160 uPD553C 1982, Tomy Pac Man (TN-08)
43 *167 uPD553C 1982, Sony SL models (betamax) (have dump)
44 @170 uPD553C 1982, Bandai Crazy Climber
45 @192 uPD553C 1982, Tomy Scramble (TN-10)
46 @202 uPD553C 1982, Epoch Astro Command
47 @206 uPD553C 1982, Epoch Dracula
48 *207 uPD553C 1982, Sony SL-J30 (tape/cd deck)
49 @209 uPD553C 1982, Tomy Caveman (TN-12)
50 @258 uPD553C 1984, Tomy Alien Chase (TN-16)
51 *296 uPD553C 1984, Epoch Computer Beam Gun Professional
52
53 @511 uPD557LC 1980, Takatoku Toys Game Robot 9/Mego Fabulous Fred
54 @512 uPD557LC 1980, Castle Toy Tactix
55 @513 uPD557LC 1980, Castle Toy Name That Tune
56
57 @060 uPD650C 1979, Mattel Computer Gin
58 *085 uPD650C 1980, Roland TR-808
59 *127 uPD650C 198?, Sony OA-S1100 Typecorder (subcpu, have dump)
60 128 uPD650C 1981, Roland TR-606 -> roland_tr606.cpp
61 133 uPD650C 1982, Roland TB-303 -> roland_tb303.cpp
62
63 (* means undumped unless noted, @ denotes it's in this driver)
64
65 ***************************************************************************/
66
67 #include "emu.h"
68 #include "cpu/ucom4/ucom4.h"
69 #include "video/pwm.h"
70 #include "video/hlcd0515.h"
71 #include "sound/spkrdev.h"
72 #include "screen.h"
73 #include "speaker.h"
74
75 // internal artwork (complete)
76 #include "ctntune.lh" // clickable
77 #include "efball.lh"
78 #include "grobot9.lh" // clickable
79 #include "mcompgin.lh"
80 #include "mvbfree.lh"
81 #include "tactix.lh" // clickable
82
83 // internal artwork (bezel overlay)
84 #include "tmtennis.lh"
85
86 //#include "hh_ucom4_test.lh" // common test-layout - no svg artwork(yet), use external artwork
87
88
89 class hh_ucom4_state : public driver_device
90 {
91 public:
hh_ucom4_state(const machine_config & mconfig,device_type type,const char * tag)92 hh_ucom4_state(const machine_config &mconfig, device_type type, const char *tag) :
93 driver_device(mconfig, type, tag),
94 m_maincpu(*this, "maincpu"),
95 m_display(*this, "display"),
96 m_speaker(*this, "speaker"),
97 m_inputs(*this, "IN.%u", 0)
98 { }
99
100 DECLARE_INPUT_CHANGED_MEMBER(single_interrupt_line);
101
102 protected:
103 virtual void machine_start() override;
104 virtual void machine_reset() override;
105
106 // devices
107 required_device<ucom4_cpu_device> m_maincpu;
108 optional_device<pwm_display_device> m_display;
109 optional_device<speaker_sound_device> m_speaker;
110 optional_ioport_array<6> m_inputs; // max 6
111
112 // misc common
113 u8 m_port[9]; // MCU port A-I write data (optional)
114 u8 m_int; // MCU INT pin state
115 u16 m_inp_mux; // multiplexed inputs mask
116
117 u32 m_grid; // VFD current row data
118 u32 m_plate; // VFD current column data
119
120 u8 read_inputs(int columns);
121 void refresh_interrupts(void);
122 void set_interrupt(int state);
123
124 enum
125 {
126 PORTA = 0,
127 PORTB,
128 PORTC,
129 PORTD,
130 PORTE,
131 PORTF,
132 PORTG,
133 PORTH,
134 PORTI
135 };
136 };
137
138
139 // machine start/reset
140
machine_start()141 void hh_ucom4_state::machine_start()
142 {
143 // zerofill
144 memset(m_port, 0, sizeof(m_port));
145 m_int = 0;
146 m_inp_mux = 0;
147 m_grid = 0;
148 m_plate = 0;
149
150 // register for savestates
151 save_item(NAME(m_port));
152 save_item(NAME(m_int));
153 save_item(NAME(m_inp_mux));
154 save_item(NAME(m_grid));
155 save_item(NAME(m_plate));
156 }
157
machine_reset()158 void hh_ucom4_state::machine_reset()
159 {
160 refresh_interrupts();
161 }
162
163
164
165 /***************************************************************************
166
167 Helper Functions
168
169 ***************************************************************************/
170
171 // generic input handlers
172
read_inputs(int columns)173 u8 hh_ucom4_state::read_inputs(int columns)
174 {
175 u8 ret = 0;
176
177 // read selected input rows
178 for (int i = 0; i < columns; i++)
179 if (m_inp_mux >> i & 1)
180 ret |= m_inputs[i]->read();
181
182 return ret;
183 }
184
185
186 // interrupt handling
187
refresh_interrupts()188 void hh_ucom4_state::refresh_interrupts()
189 {
190 m_maincpu->set_input_line(0, m_int ? ASSERT_LINE : CLEAR_LINE);
191 }
192
set_interrupt(int state)193 void hh_ucom4_state::set_interrupt(int state)
194 {
195 state = state ? 1 : 0;
196
197 if (state != m_int)
198 {
199 if (machine().phase() >= machine_phase::RESET)
200 m_maincpu->set_input_line(0, state ? ASSERT_LINE : CLEAR_LINE);
201 m_int = state;
202 }
203 }
204
INPUT_CHANGED_MEMBER(hh_ucom4_state::single_interrupt_line)205 INPUT_CHANGED_MEMBER(hh_ucom4_state::single_interrupt_line)
206 {
207 set_interrupt(newval);
208 }
209
210
211
212 /***************************************************************************
213
214 Minidrivers (subclass, I/O, Inputs, Machine Config, ROM Defs)
215
216 ***************************************************************************/
217
218 namespace {
219
220 /***************************************************************************
221
222 Bambino UFO Master-Blaster Station (manufactured in Japan)
223 * PCB label Emix Corp. ET-02
224 * NEC uCOM-44 MCU, label EMIX D552C 017
225 * cyan VFD display Emix-101, with blue color overlay
226
227 This is Bambino's first game, it is not known if ET-01 exists. Emix Corp.
228 wasn't initially a toy company, the first release was through Tomy. Emix
229 created the Bambino brand afterwards. It is claimed to be the first
230 computerized VFD game (true, unless TI Speak & Spell(1978), or even Invicta
231 Electronic Mastermind(1977) are considered games)
232
233 known releases:
234 - Japan: "Missile Guerilla Warfare Maneuvers", published by Tomy
235 - World: UFO Master-Blaster Station
236
237 ***************************************************************************/
238
239 class ufombs_state : public hh_ucom4_state
240 {
241 public:
ufombs_state(const machine_config & mconfig,device_type type,const char * tag)242 ufombs_state(const machine_config &mconfig, device_type type, const char *tag) :
243 hh_ucom4_state(mconfig, type, tag)
244 { }
245
246 void update_display();
247 void grid_w(offs_t offset, u8 data);
248 void plate_w(offs_t offset, u8 data);
249 void speaker_w(u8 data);
250 void ufombs(machine_config &config);
251 };
252
253 // handlers
254
update_display()255 void ufombs_state::update_display()
256 {
257 u16 grid = bitswap<16>(m_grid,15,14,13,12,11,10,9,3,2,1,0,4,5,6,7,8);
258 u16 plate = bitswap<16>(m_plate,15,14,13,12,11,7,10,6,9,5,8,4,0,1,2,3);
259 m_display->matrix(grid, plate);
260 }
261
grid_w(offs_t offset,u8 data)262 void ufombs_state::grid_w(offs_t offset, u8 data)
263 {
264 // F,G,H0: vfd grid
265 int shift = (offset - PORTF) * 4;
266 m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
267 update_display();
268 }
269
plate_w(offs_t offset,u8 data)270 void ufombs_state::plate_w(offs_t offset, u8 data)
271 {
272 // C,D012,I: vfd plate
273 int shift = (offset == PORTI) ? 8 : (offset - PORTC) * 4;
274 m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
275 update_display();
276 }
277
speaker_w(u8 data)278 void ufombs_state::speaker_w(u8 data)
279 {
280 // E01: speaker out
281 m_speaker->level_w(data & 3);
282 }
283
284 // config
285
286 static INPUT_PORTS_START( ufombs )
287 PORT_START("IN.0") // port A
288 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 )
289 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY
290 PORT_BIT( 0x04, 0x04, IPT_CUSTOM ) PORT_CONDITION("IN.0", 0x0a, EQUALS, 0x00) // pad in the middle, pressed when joystick is centered
291 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY
292
293 PORT_START("IN.1") // port B
DEF_STR(Difficulty)294 PORT_CONFNAME( 0x07, 0x01, DEF_STR( Difficulty ) )
295 PORT_CONFSETTING( 0x01, "1" )
296 PORT_CONFSETTING( 0x02, "2" )
297 PORT_CONFSETTING( 0x04, "3" )
298 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
299 INPUT_PORTS_END
300
301 void ufombs_state::ufombs(machine_config &config)
302 {
303 /* basic machine hardware */
304 NEC_D552(config, m_maincpu, 400000); // approximation
305 m_maincpu->read_a().set_ioport("IN.0");
306 m_maincpu->read_b().set_ioport("IN.1");
307 m_maincpu->write_c().set(FUNC(ufombs_state::plate_w));
308 m_maincpu->write_d().set(FUNC(ufombs_state::plate_w));
309 m_maincpu->write_e().set(FUNC(ufombs_state::speaker_w));
310 m_maincpu->write_f().set(FUNC(ufombs_state::grid_w));
311 m_maincpu->write_g().set(FUNC(ufombs_state::grid_w));
312 m_maincpu->write_h().set(FUNC(ufombs_state::grid_w));
313 m_maincpu->write_i().set(FUNC(ufombs_state::plate_w));
314
315 /* video hardware */
316 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
317 screen.set_refresh_hz(60);
318 screen.set_size(243, 1080);
319 screen.set_visarea_full();
320
321 PWM_DISPLAY(config, m_display).set_size(9, 10);
322
323 /* sound hardware */
324 SPEAKER(config, "mono").front_center();
325 SPEAKER_SOUND(config, m_speaker);
326 static const double speaker_levels[] = { 0.0, 1.0, -1.0, 0.0 };
327 m_speaker->set_levels(4, speaker_levels);
328 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
329 }
330
331 // roms
332
333 ROM_START( ufombs )
334 ROM_REGION( 0x0400, "maincpu", 0 )
335 ROM_LOAD( "d552c-017", 0x0000, 0x0400, CRC(0e208cb3) SHA1(57db6566916c94325e2b67ccb94b4ea3b233487d) )
336
337 ROM_REGION( 222395, "screen", 0)
338 ROM_LOAD( "ufombs.svg", 0, 222395, CRC(ae9fb93f) SHA1(165ea78eee93c503dbd277a56c41e3c63c534e38) )
339 ROM_END
340
341
342
343
344
345 /***************************************************************************
346
347 Bambino Superstar Football (manufactured in Japan)
348 * PCB label Emix Corp. ET-03
349 * NEC uCOM-43 MCU, label D553C 031
350 * cyan VFD display Emix-102, with bezel
351
352 The game was rereleased in 1982 as Classic Football (ET-0351), with an
353 improved cyan/green/red VFD.
354
355 Press the Kick button to start the game, an automatic sequence follows.
356 Then choose a formation(A,B,C) and either pass the ball, and/or start
357 running. For more information, refer to the official manual.
358
359 ***************************************************************************/
360
361 class ssfball_state : public hh_ucom4_state
362 {
363 public:
ssfball_state(const machine_config & mconfig,device_type type,const char * tag)364 ssfball_state(const machine_config &mconfig, device_type type, const char *tag) :
365 hh_ucom4_state(mconfig, type, tag)
366 { }
367
368 void update_display();
369 void grid_w(offs_t offset, u8 data);
370 void plate_w(offs_t offset, u8 data);
371 u8 input_b_r();
372 void ssfball(machine_config &config);
373 };
374
375 // handlers
376
update_display()377 void ssfball_state::update_display()
378 {
379 u32 plate = bitswap<24>(m_plate,23,22,21,20,19,11,7,3,12,17,13,18,16,14,15,10,9,8,0,1,2,4,5,6);
380 m_display->matrix(m_grid, plate);
381 }
382
grid_w(offs_t offset,u8 data)383 void ssfball_state::grid_w(offs_t offset, u8 data)
384 {
385 // C,D(,E3): vfd grid 0-7(,8)
386 int shift = (offset - PORTC) * 4;
387 m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
388 update_display();
389 }
390
plate_w(offs_t offset,u8 data)391 void ssfball_state::plate_w(offs_t offset, u8 data)
392 {
393 m_port[offset] = data;
394
395 // E,F,G,H,I(not all!): vfd plate
396 int shift = (offset - PORTE) * 4;
397 m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
398
399 // F3,G3: input mux + speaker
400 m_inp_mux = (m_port[PORTF] >> 3 & 1) | (m_port[PORTG] >> 2 & 2);
401 m_speaker->level_w(m_inp_mux);
402
403 // E3: vfd grid 8
404 if (offset == PORTE)
405 grid_w(offset, data >> 3 & 1);
406 else
407 update_display();
408 }
409
input_b_r()410 u8 ssfball_state::input_b_r()
411 {
412 // B: input port 2, where B3 is multiplexed
413 return m_inputs[2]->read() | read_inputs(2);
414 }
415
416 // config
417
418 /* physical button layout and labels is like this:
419
420 [A] [B] [C] [PASS] [KICK/
421 ^FORMATION^ DISPLAY]
422
423 [^]
424 [<>]
425 (game lvl sw) [v]
426 1<---OFF--->2
427 */
428
429 static INPUT_PORTS_START( ssfball )
430 PORT_START("IN.0") // F3 port B3
431 PORT_BIT( 0x07, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_CODE(KEYCODE_A)432 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_A) PORT_NAME("Formation A")
433
434 PORT_START("IN.1") // G3 port B3
435 PORT_BIT( 0x07, IP_ACTIVE_HIGH, IPT_UNUSED )
436 PORT_CONFNAME( 0x08, 0x00, "Game Level" )
437 PORT_CONFSETTING( 0x00, "1" )
438 PORT_CONFSETTING( 0x08, "2" )
439
440 PORT_START("IN.2") // port B
441 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("Kick/Display")
442 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_C) PORT_NAME("Formation C")
443 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_B) PORT_NAME("Formation B")
444 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_CUSTOM ) // multiplexed, handled in input_b_r
445
446 PORT_START("IN.3") // port A
447 PORT_BIT( 0x01, 0x01, IPT_CUSTOM ) PORT_CONDITION("FAKE", 0x03, NOTEQUALS, 0x00) // left/right
448 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_16WAY
449 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_16WAY
450 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Pass")
451
452 PORT_START("FAKE") // fake port for left/right combination
453 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_16WAY PORT_NAME("P1 Left/Right")
454 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_16WAY PORT_NAME("P1 Left/Right")
455 INPUT_PORTS_END
456
457 void ssfball_state::ssfball(machine_config &config)
458 {
459 /* basic machine hardware */
460 NEC_D553(config, m_maincpu, 400000); // approximation
461 m_maincpu->read_a().set_ioport("IN.3");
462 m_maincpu->read_b().set(FUNC(ssfball_state::input_b_r));
463 m_maincpu->write_c().set(FUNC(ssfball_state::grid_w));
464 m_maincpu->write_d().set(FUNC(ssfball_state::grid_w));
465 m_maincpu->write_e().set(FUNC(ssfball_state::plate_w));
466 m_maincpu->write_f().set(FUNC(ssfball_state::plate_w));
467 m_maincpu->write_g().set(FUNC(ssfball_state::plate_w));
468 m_maincpu->write_h().set(FUNC(ssfball_state::plate_w));
469 m_maincpu->write_i().set(FUNC(ssfball_state::plate_w));
470
471 /* video hardware */
472 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
473 screen.set_refresh_hz(60);
474 screen.set_size(1920, 482);
475 screen.set_visarea_full();
476
477 PWM_DISPLAY(config, m_display).set_size(9, 16);
478
479 /* sound hardware */
480 SPEAKER(config, "mono").front_center();
481 SPEAKER_SOUND(config, m_speaker);
482 static const double speaker_levels[] = { 0.0, 1.0, -1.0, 0.0 };
483 m_speaker->set_levels(4, speaker_levels);
484 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
485 }
486
487 // roms
488
489 ROM_START( ssfball )
490 ROM_REGION( 0x0800, "maincpu", 0 )
491 ROM_LOAD( "d553c-031", 0x0000, 0x0800, CRC(ff5d91d0) SHA1(9b2c0ae45f1e3535108ee5fef8a9010e00c8d5c3) )
492
493 ROM_REGION( 331352, "screen", 0)
494 ROM_LOAD( "ssfball.svg", 0, 331352, CRC(10cffb85) SHA1(c875f73a323d976088ffa1bc19f7bc865d4aac62) )
495 ROM_END
496
497 ROM_START( bmcfball )
498 ROM_REGION( 0x0800, "maincpu", 0 )
499 ROM_LOAD( "d553c-031", 0x0000, 0x0800, CRC(ff5d91d0) SHA1(9b2c0ae45f1e3535108ee5fef8a9010e00c8d5c3) )
500
501 ROM_REGION( 331352, "screen", 0)
502 ROM_LOAD( "bmcfball.svg", 0, 331352, CRC(43fbed1e) SHA1(28160e14b0879cd4dd9dab770c52c98f316ab653) )
503 ROM_END
504
505
506
507
508
509 /***************************************************************************
510
511 Bambino Kick The Goal Soccer
512 * PCB label Emix Corp. ET-10/08 (PCB is for 2 possible games)
513 * NEC uCOM-44 MCU, label D552C 043
514 * cyan VFD display Emix-105, with bezel overlay
515
516 Press the Display button twice to start the game. Action won't start until
517 player 1 presses one of the directional keys. In 2-player mode, player 2
518 controls the goalkeeper, defensive players are still controlled by the CPU.
519
520 ***************************************************************************/
521
522 class bmsoccer_state : public hh_ucom4_state
523 {
524 public:
bmsoccer_state(const machine_config & mconfig,device_type type,const char * tag)525 bmsoccer_state(const machine_config &mconfig, device_type type, const char *tag) :
526 hh_ucom4_state(mconfig, type, tag)
527 { }
528
529 void update_display();
530 void grid_w(offs_t offset, u8 data);
531 void plate_w(offs_t offset, u8 data);
532 u8 input_a_r();
533 void bmsoccer(machine_config &config);
534 };
535
536 // handlers
537
update_display()538 void bmsoccer_state::update_display()
539 {
540 u32 plate = bitswap<24>(m_plate,23,22,21,20,19,11,7,3,12,17,13,18,16,14,15,8,4,0,9,5,1,10,6,2);
541 m_display->matrix(m_grid, plate);
542 }
543
grid_w(offs_t offset,u8 data)544 void bmsoccer_state::grid_w(offs_t offset, u8 data)
545 {
546 // C01: input mux
547 if (offset == PORTC)
548 m_inp_mux = data & 3;
549
550 // C,D(,E3): vfd grid
551 int shift = (offset - PORTC) * 4;
552 m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
553 update_display();
554 }
555
plate_w(offs_t offset,u8 data)556 void bmsoccer_state::plate_w(offs_t offset, u8 data)
557 {
558 // G3: speaker out
559 if (offset == PORTG)
560 m_speaker->level_w(data >> 3 & 1);
561
562 // E012,F012,G012,H,I: vfd plate
563 int shift = (offset - PORTE) * 4;
564 m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
565
566 // E3: grid 8
567 if (offset == PORTE)
568 grid_w(offset, data >> 3 & 1);
569 else
570 update_display();
571 }
572
input_a_r()573 u8 bmsoccer_state::input_a_r()
574 {
575 // port A: multiplexed inputs
576 return read_inputs(2);
577 }
578
579 // config
580
581 static INPUT_PORTS_START( bmsoccer )
582 PORT_START("IN.0") // C0 port A
583 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_16WAY PORT_NAME("Ball-carrier Right")
584 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_16WAY PORT_NAME("Ball-carrier Down")
585 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_16WAY PORT_NAME("Ball-carrier Left")
586 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_16WAY PORT_NAME("Ball-carrier Up")
587
588 PORT_START("IN.1") // C1 port A
589 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_COCKTAIL PORT_16WAY PORT_NAME("Goalkeeper Left") // note: swap buttons if viewed from the same angle as player 1
590 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_COCKTAIL PORT_16WAY PORT_NAME("Goalkeeper Right")
591 PORT_BIT( 0x0c, IP_ACTIVE_HIGH, IPT_UNUSED )
592
593 PORT_START("IN.2") // port B
DEF_STR(Difficulty)594 PORT_CONFNAME( 0x01, 0x00, DEF_STR( Difficulty ) )
595 PORT_CONFSETTING( 0x00, "1" )
596 PORT_CONFSETTING( 0x01, "2" )
597 PORT_CONFNAME( 0x02, 0x00, DEF_STR( Players ) )
598 PORT_CONFSETTING( 0x00, "1" )
599 PORT_CONFSETTING( 0x02, "2" )
600 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Display/Banana Shoot")
601 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Shoot")
602 INPUT_PORTS_END
603
604 void bmsoccer_state::bmsoccer(machine_config &config)
605 {
606 /* basic machine hardware */
607 NEC_D552(config, m_maincpu, 400000); // approximation
608 m_maincpu->read_a().set(FUNC(bmsoccer_state::input_a_r));
609 m_maincpu->read_b().set_ioport("IN.2");
610 m_maincpu->write_c().set(FUNC(bmsoccer_state::grid_w));
611 m_maincpu->write_d().set(FUNC(bmsoccer_state::grid_w));
612 m_maincpu->write_e().set(FUNC(bmsoccer_state::plate_w));
613 m_maincpu->write_f().set(FUNC(bmsoccer_state::plate_w));
614 m_maincpu->write_g().set(FUNC(bmsoccer_state::plate_w));
615 m_maincpu->write_h().set(FUNC(bmsoccer_state::plate_w));
616 m_maincpu->write_i().set(FUNC(bmsoccer_state::plate_w));
617
618 /* video hardware */
619 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
620 screen.set_refresh_hz(60);
621 screen.set_size(271, 1080);
622 screen.set_visarea_full();
623
624 PWM_DISPLAY(config, m_display).set_size(9, 16);
625
626 /* sound hardware */
627 SPEAKER(config, "mono").front_center();
628 SPEAKER_SOUND(config, m_speaker);
629 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
630 }
631
632 // roms
633
634 ROM_START( bmsoccer )
635 ROM_REGION( 0x0400, "maincpu", 0 )
636 ROM_LOAD( "d552c-043", 0x0000, 0x0400, CRC(10c2a4ea) SHA1(6ebca7d406e22ff7a8cd529579b55a700da487b4) )
637
638 ROM_REGION( 273796, "screen", 0)
639 ROM_LOAD( "bmsoccer.svg", 0, 273796, CRC(4c88d9f8) SHA1(b4b82f26a09f54cd0b6a9d1c1a46796fbfcb578a) )
640 ROM_END
641
642
643
644
645
646 /***************************************************************************
647
648 Bambino Safari (manufactured in Japan)
649 * PCB label Emix Corp. ET-11
650 * NEC uCOM-44 MCU, label EMIX D552C 049
651 * cyan VFD display Emix-108
652
653 ***************************************************************************/
654
655 class bmsafari_state : public hh_ucom4_state
656 {
657 public:
bmsafari_state(const machine_config & mconfig,device_type type,const char * tag)658 bmsafari_state(const machine_config &mconfig, device_type type, const char *tag) :
659 hh_ucom4_state(mconfig, type, tag)
660 { }
661
662 void update_display();
663 void grid_w(offs_t offset, u8 data);
664 void plate_w(offs_t offset, u8 data);
665 void speaker_w(u8 data);
666 void bmsafari(machine_config &config);
667 };
668
669 // handlers
670
update_display()671 void bmsafari_state::update_display()
672 {
673 u16 grid = bitswap<16>(m_grid,15,14,13,12,11,10,9,0,1,2,3,4,5,6,7,8);
674 u16 plate = bitswap<16>(m_plate,15,14,13,12,11,7,10,2,9,5,8,4,0,1,6,3);
675 m_display->matrix(grid, plate);
676 }
677
grid_w(offs_t offset,u8 data)678 void bmsafari_state::grid_w(offs_t offset, u8 data)
679 {
680 // C,D(,E3): vfd grid
681 int shift = (offset - PORTC) * 4;
682 m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
683 update_display();
684 }
685
plate_w(offs_t offset,u8 data)686 void bmsafari_state::plate_w(offs_t offset, u8 data)
687 {
688 // E012,H,I: vfd plate
689 int shift = (offset == PORTE) ? 8 : (offset - PORTH) * 4;
690 m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
691
692 // E3: grid 0
693 if (offset == PORTE)
694 grid_w(offset, data >> 3 & 1);
695 else
696 update_display();
697 }
698
speaker_w(u8 data)699 void bmsafari_state::speaker_w(u8 data)
700 {
701 // G0: speaker out
702 m_speaker->level_w(data & 1);
703 }
704
705 // config
706
707 static INPUT_PORTS_START( bmsafari )
708 PORT_START("IN.0") // port A
DEF_STR(Difficulty)709 PORT_CONFNAME( 0x07, 0x04, DEF_STR( Difficulty ) )
710 PORT_CONFSETTING( 0x04, "1" )
711 PORT_CONFSETTING( 0x02, "2" )
712 PORT_CONFSETTING( 0x01, "3" )
713 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON1 )
714
715 PORT_START("IN.1") // port B
716 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_16WAY
717 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_16WAY
718 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_16WAY
719 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_16WAY
720 INPUT_PORTS_END
721
722 void bmsafari_state::bmsafari(machine_config &config)
723 {
724 /* basic machine hardware */
725 NEC_D552(config, m_maincpu, 400000); // approximation
726 m_maincpu->read_a().set_ioport("IN.0");
727 m_maincpu->read_b().set_ioport("IN.1");
728 m_maincpu->write_c().set(FUNC(bmsafari_state::grid_w));
729 m_maincpu->write_d().set(FUNC(bmsafari_state::grid_w));
730 m_maincpu->write_e().set(FUNC(bmsafari_state::plate_w));
731 m_maincpu->write_g().set(FUNC(bmsafari_state::speaker_w));
732 m_maincpu->write_h().set(FUNC(bmsafari_state::plate_w));
733 m_maincpu->write_i().set(FUNC(bmsafari_state::plate_w));
734
735 /* video hardware */
736 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
737 screen.set_refresh_hz(60);
738 screen.set_size(248, 1080);
739 screen.set_visarea_full();
740
741 PWM_DISPLAY(config, m_display).set_size(9, 10);
742
743 /* sound hardware */
744 SPEAKER(config, "mono").front_center();
745 SPEAKER_SOUND(config, m_speaker);
746 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
747 }
748
749 // roms
750
751 ROM_START( bmsafari )
752 ROM_REGION( 0x0400, "maincpu", 0 )
753 ROM_LOAD( "d552c-049", 0x0000, 0x0400, CRC(82fa3cbe) SHA1(019e7ec784e977eba09997fc46af253054fb222c) )
754
755 ROM_REGION( 275386, "screen", 0)
756 ROM_LOAD( "bmsafari.svg", 0, 275386, CRC(c24badbc) SHA1(b191f34155d6d4e834e7c6fe715d4bb76198ad72) )
757 ROM_END
758
759
760
761
762
763 /***************************************************************************
764
765 Bambino Space Laser Fight (manufactured in Japan)
766 * PCB label Emix Corp. ET-12
767 * NEC uCOM-43 MCU, label D553C 055
768 * cyan VFD display Emix-104, with blue or green color overlay
769
770 This is basically a revamp of their earlier Boxing game (ET-06), case and
771 buttons are exactly the same.
772
773 ***************************************************************************/
774
775 class splasfgt_state : public hh_ucom4_state
776 {
777 public:
splasfgt_state(const machine_config & mconfig,device_type type,const char * tag)778 splasfgt_state(const machine_config &mconfig, device_type type, const char *tag) :
779 hh_ucom4_state(mconfig, type, tag)
780 { }
781
782 void update_display();
783 void grid_w(offs_t offset, u8 data);
784 void plate_w(offs_t offset, u8 data);
785 u8 input_b_r();
786 void splasfgt(machine_config &config);
787 };
788
789 // handlers
790
update_display()791 void splasfgt_state::update_display()
792 {
793 u32 plate = bitswap<24>(m_plate,23,22,21,20,19,18,17,13,1,0,8,6,0,10,11,14,15,16,9,5,7,4,2,3);
794 m_display->matrix(m_grid, plate);
795 }
796
grid_w(offs_t offset,u8 data)797 void splasfgt_state::grid_w(offs_t offset, u8 data)
798 {
799 // G,H,I0: vfd grid
800 int shift = (offset - PORTG) * 4;
801 m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
802
803 // G(grid 0-3): input mux
804 m_inp_mux = m_grid & 0xf;
805
806 // I2: vfd plate 6
807 if (offset == PORTI)
808 plate_w(4 + PORTC, data >> 2 & 1);
809 else
810 update_display();
811 }
812
plate_w(offs_t offset,u8 data)813 void splasfgt_state::plate_w(offs_t offset, u8 data)
814 {
815 // F01: speaker out
816 if (offset == PORTF)
817 m_speaker->level_w(data & 3);
818
819 // C,D,E,F23(,I2): vfd plate
820 int shift = (offset - PORTC) * 4;
821 m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
822 update_display();
823 }
824
input_b_r()825 u8 splasfgt_state::input_b_r()
826 {
827 // B: multiplexed buttons
828 return read_inputs(4);
829 }
830
831 // config
832
833 /* physical button layout and labels is like this:
834
835 * left = P1 side * * right = P2 side * (note: in 1P mode, switch sides between turns)
836
837 [ JUMP ] [ HIGH ] (players sw) [ HIGH ] [ JUMP ]
838 1<--->2 [START/
839 [STRAIGHT] [MEDIUM] RESET] [MEDIUM] [STRAIGHT]
840 1<---OFF--->2
841 [ STOOP ] [ LOW ] (skill lvl sw) [ LOW ] [ STOOP ]
842 */
843
844 static INPUT_PORTS_START( splasfgt )
845 PORT_START("IN.0") // G0 port B
PORT_CODE(KEYCODE_A)846 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_A) PORT_NAME("P1 Position Straight")
847 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Q) PORT_NAME("P1 Position Jump")
848 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Z) PORT_NAME("P1 Position Stoop")
849 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
850
851 PORT_START("IN.1") // G1 port B
852 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_W) PORT_NAME("P1 Beam High")
853 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_S) PORT_NAME("P1 Beam Medium")
854 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_X) PORT_NAME("P1 Beam Low")
855 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
856
857 PORT_START("IN.2") // G2 port B
858 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_K) PORT_NAME("P2 Position Straight")
859 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_I) PORT_NAME("P2 Position Jump")
860 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_COMMA) PORT_NAME("P2 Position Stoop")
861 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
862
863 PORT_START("IN.3") // G3 port B
864 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_U) PORT_NAME("P2 Beam High")
865 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_J) PORT_NAME("P2 Beam Medium")
866 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_M) PORT_NAME("P2 Beam Low")
867 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
868
869 PORT_START("IN.4") // port A
870 PORT_CONFNAME( 0x01, 0x00, DEF_STR( Players ) )
871 PORT_CONFSETTING( 0x00, "1" )
872 PORT_CONFSETTING( 0x01, "2" )
873 PORT_CONFNAME( 0x02, 0x00, DEF_STR( Difficulty ) )
874 PORT_CONFSETTING( 0x00, "1" )
875 PORT_CONFSETTING( 0x02, "2" )
876 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START )
877 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
878 INPUT_PORTS_END
879
880 void splasfgt_state::splasfgt(machine_config &config)
881 {
882 /* basic machine hardware */
883 NEC_D553(config, m_maincpu, 400000); // approximation
884 m_maincpu->read_a().set_ioport("IN.4");
885 m_maincpu->read_b().set(FUNC(splasfgt_state::input_b_r));
886 m_maincpu->write_c().set(FUNC(splasfgt_state::plate_w));
887 m_maincpu->write_d().set(FUNC(splasfgt_state::plate_w));
888 m_maincpu->write_e().set(FUNC(splasfgt_state::plate_w));
889 m_maincpu->write_f().set(FUNC(splasfgt_state::plate_w));
890 m_maincpu->write_g().set(FUNC(splasfgt_state::grid_w));
891 m_maincpu->write_h().set(FUNC(splasfgt_state::grid_w));
892 m_maincpu->write_i().set(FUNC(splasfgt_state::grid_w));
893
894 /* video hardware */
895 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
896 screen.set_refresh_hz(60);
897 screen.set_size(1920, 476);
898 screen.set_visarea_full();
899
900 PWM_DISPLAY(config, m_display).set_size(9, 16);
901
902 /* sound hardware */
903 SPEAKER(config, "mono").front_center();
904 SPEAKER_SOUND(config, m_speaker);
905 static const double speaker_levels[] = { 0.0, 1.0, -1.0, 0.0 };
906 m_speaker->set_levels(4, speaker_levels);
907 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
908 }
909
910 // roms
911
912 ROM_START( splasfgt )
913 ROM_REGION( 0x0800, "maincpu", 0 )
914 ROM_LOAD( "d553c-055", 0x0000, 0x0800, CRC(eb471fbd) SHA1(f06cfe567bf6f9ed4dcdc88acdcfad50cd370a02) )
915
916 ROM_REGION( 246609, "screen", 0)
917 ROM_LOAD( "splasfgt.svg", 0, 246609, CRC(365fae43) SHA1(344c120c2efa92ada9171047affac801a06cf303) )
918 ROM_END
919
920
921
922
923
924 /***************************************************************************
925
926 Bandai Crazy Climber (manufactured in Japan)
927 * PCB labels SM-020/SM-021
928 * NEC uCOM-43 MCU, label D553C 170
929 * cyan/red/green VFD display NEC FIP6AM2-T no. 1-8 2, with partial color overlay and bezel
930
931 known releases:
932 - Japan: FL Crazy Climbing
933 - USA: Crazy Climber
934
935 ***************************************************************************/
936
937 class bcclimbr_state : public hh_ucom4_state
938 {
939 public:
bcclimbr_state(const machine_config & mconfig,device_type type,const char * tag)940 bcclimbr_state(const machine_config &mconfig, device_type type, const char *tag) :
941 hh_ucom4_state(mconfig, type, tag)
942 { }
943
944 void update_display();
945 void grid_w(offs_t offset, u8 data);
946 void plate_w(offs_t offset, u8 data);
947 void bcclimbr(machine_config &config);
948 };
949
950 // handlers
951
update_display()952 void bcclimbr_state::update_display()
953 {
954 u8 grid = bitswap<8>(m_grid,7,6,0,1,2,3,4,5);
955 u32 plate = bitswap<24>(m_plate,23,22,21,20,16,17,18,19,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
956 m_display->matrix(grid, plate);
957 }
958
grid_w(offs_t offset,u8 data)959 void bcclimbr_state::grid_w(offs_t offset, u8 data)
960 {
961 // I2: speaker out
962 if (offset == PORTI)
963 m_speaker->level_w(data >> 2 & 1);
964
965 // H,I01: vfd grid
966 int shift = (offset - PORTH) * 4;
967 m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
968 update_display();
969 }
970
plate_w(offs_t offset,u8 data)971 void bcclimbr_state::plate_w(offs_t offset, u8 data)
972 {
973 // C,D,E,F: vfd plate
974 int shift = (offset - PORTC) * 4;
975 m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
976 update_display();
977 }
978
979 // config
980
981 static INPUT_PORTS_START( bcclimbr )
982 PORT_START("IN.0") // port A
983 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START )
984 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_UP )
985 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_DOWN )
986 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_LEFT )
987
988 PORT_START("IN.1") // port B
989 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
990 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_UP )
991 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_DOWN )
992 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_RIGHT )
993 INPUT_PORTS_END
994
bcclimbr(machine_config & config)995 void bcclimbr_state::bcclimbr(machine_config &config)
996 {
997 /* basic machine hardware */
998 NEC_D553(config, m_maincpu, 400_kHz_XTAL);
999 m_maincpu->read_a().set_ioport("IN.0");
1000 m_maincpu->read_b().set_ioport("IN.1");
1001 m_maincpu->write_c().set(FUNC(bcclimbr_state::plate_w));
1002 m_maincpu->write_d().set(FUNC(bcclimbr_state::plate_w));
1003 m_maincpu->write_e().set(FUNC(bcclimbr_state::plate_w));
1004 m_maincpu->write_f().set(FUNC(bcclimbr_state::plate_w));
1005 m_maincpu->write_g().set(FUNC(bcclimbr_state::plate_w));
1006 m_maincpu->write_h().set(FUNC(bcclimbr_state::grid_w));
1007 m_maincpu->write_i().set(FUNC(bcclimbr_state::grid_w));
1008
1009 /* video hardware */
1010 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
1011 screen.set_refresh_hz(60);
1012 screen.set_size(310, 1080);
1013 screen.set_visarea_full();
1014
1015 PWM_DISPLAY(config, m_display).set_size(6, 20);
1016
1017 /* sound hardware */
1018 SPEAKER(config, "mono").front_center();
1019 SPEAKER_SOUND(config, m_speaker);
1020 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
1021 }
1022
1023 // roms
1024
1025 ROM_START( bcclimbr )
1026 ROM_REGION( 0x0800, "maincpu", 0 )
1027 ROM_LOAD( "d553c-170", 0x0000, 0x0800, CRC(fc2eabdb) SHA1(0f5cc854be7fdf105d9bd2114659d40c65f9d782) )
1028
1029 ROM_REGION( 219971, "screen", 0)
1030 ROM_LOAD( "bcclimbr.svg", 0, 219971, CRC(9c9102f4) SHA1(6a7e02fd1467a26c734b01724e23cef9e4917805) )
1031 ROM_END
1032
1033
1034
1035
1036
1037 /***************************************************************************
1038
1039 Castle Toy Tactix
1040 * NEC uCOM-43 MCU, label D557LC 512
1041 * 16 LEDs behind buttons
1042
1043 Tactix is similar to Merlin, for 1 or 2 players. In 2-player mode, simply
1044 don't press the Comp Turn button. The four included minigames are:
1045 1: Capture (reversi)
1046 2: Jump-Off (peg solitaire)
1047 3: Triple Play (3 in a row)
1048 4: Concentration (memory)
1049
1050 ***************************************************************************/
1051
1052 class tactix_state : public hh_ucom4_state
1053 {
1054 public:
tactix_state(const machine_config & mconfig,device_type type,const char * tag)1055 tactix_state(const machine_config &mconfig, device_type type, const char *tag) :
1056 hh_ucom4_state(mconfig, type, tag)
1057 { }
1058
1059 void leds_w(offs_t offset, u8 data);
1060 void speaker_w(u8 data);
1061 void input_w(offs_t offset, u8 data);
1062 u8 input_r();
1063 void tactix(machine_config &config);
1064 };
1065
1066 // handlers
1067
leds_w(offs_t offset,u8 data)1068 void tactix_state::leds_w(offs_t offset, u8 data)
1069 {
1070 // D,F: 4*4 led matrix
1071 m_port[offset] = data;
1072 m_display->matrix(m_port[PORTF], m_port[PORTD]);
1073 }
1074
speaker_w(u8 data)1075 void tactix_state::speaker_w(u8 data)
1076 {
1077 // G0: speaker out
1078 m_speaker->level_w(data & 1);
1079 }
1080
input_w(offs_t offset,u8 data)1081 void tactix_state::input_w(offs_t offset, u8 data)
1082 {
1083 // C,E0: input mux
1084 m_port[offset] = data;
1085 m_inp_mux = (m_port[PORTE] << 4 & 0x10) | m_port[PORTC];
1086 }
1087
input_r()1088 u8 tactix_state::input_r()
1089 {
1090 // A: multiplexed inputs
1091 return read_inputs(5);
1092 }
1093
1094 // config
1095
1096 static INPUT_PORTS_START( tactix )
1097 PORT_START("IN.0") // C0 port A
PORT_CODE(KEYCODE_1)1098 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_NAME("Button 1")
1099 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Q) PORT_NAME("Button 5")
1100 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_A) PORT_NAME("Button 9")
1101 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Z) PORT_NAME("Button 13")
1102
1103 PORT_START("IN.1") // C1 port A
1104 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_NAME("Button 2")
1105 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_W) PORT_NAME("Button 6")
1106 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_S) PORT_NAME("Button 10")
1107 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_X) PORT_NAME("Button 14")
1108
1109 PORT_START("IN.2") // C2 port A
1110 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_NAME("Button 3")
1111 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_NAME("Button 7")
1112 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_D) PORT_NAME("Button 11")
1113 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_C) PORT_NAME("Button 15")
1114
1115 PORT_START("IN.3") // C3 port A
1116 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_NAME("Button 4")
1117 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) PORT_NAME("Button 8")
1118 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_F) PORT_NAME("Button 12")
1119 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_V) PORT_NAME("Button 16")
1120
1121 PORT_START("IN.4") // E0 port A
1122 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_ENTER) PORT_NAME("New Game")
1123 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
1124 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_T) PORT_NAME("Comp Turn")
1125 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
1126 INPUT_PORTS_END
1127
1128 void tactix_state::tactix(machine_config &config)
1129 {
1130 /* basic machine hardware */
1131 NEC_D557L(config, m_maincpu, 200000); // approximation
1132 m_maincpu->read_a().set(FUNC(tactix_state::input_r));
1133 m_maincpu->write_c().set(FUNC(tactix_state::input_w));
1134 m_maincpu->write_d().set(FUNC(tactix_state::leds_w));
1135 m_maincpu->write_e().set(FUNC(tactix_state::input_w));
1136 m_maincpu->write_f().set(FUNC(tactix_state::leds_w));
1137 m_maincpu->write_g().set(FUNC(tactix_state::speaker_w));
1138
1139 /* video hardware */
1140 PWM_DISPLAY(config, m_display).set_size(4, 4);
1141 config.set_default_layout(layout_tactix);
1142
1143 /* sound hardware */
1144 SPEAKER(config, "mono").front_center();
1145 SPEAKER_SOUND(config, m_speaker);
1146 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
1147 }
1148
1149 // roms
1150
1151 ROM_START( tactix )
1152 ROM_REGION( 0x0800, "maincpu", 0 )
1153 ROM_LOAD( "d557lc-512", 0x0000, 0x0800, CRC(1df738cb) SHA1(15a5de28a3c03e6894d29c56b5b424983569ccf2) )
1154 ROM_END
1155
1156
1157
1158
1159
1160 /***************************************************************************
1161
1162 Castle Toy Name That Tune
1163 * NEC uCOM-43 MCU, label D557LC 513
1164 * 2 lamps, 1 7seg(+2 fake 7segs above a power-on lamp, showing "0")
1165
1166 This is a tabletop multiplayer game. Players are meant to place a bid,
1167 and guess the song (by announcing it to everyone).
1168
1169 ***************************************************************************/
1170
1171 class ctntune_state : public hh_ucom4_state
1172 {
1173 public:
ctntune_state(const machine_config & mconfig,device_type type,const char * tag)1174 ctntune_state(const machine_config &mconfig, device_type type, const char *tag) :
1175 hh_ucom4_state(mconfig, type, tag)
1176 { }
1177
1178 // start button powers unit back on
DECLARE_INPUT_CHANGED_MEMBER(start_button)1179 DECLARE_INPUT_CHANGED_MEMBER(start_button) { m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); }
1180
1181 void update_display();
1182 void _7seg_w(offs_t offset, u8 data);
1183 void speaker_w(u8 data);
1184 void input_w(offs_t offset, u8 data);
1185 u8 input_r();
1186 void ctntune(machine_config &config);
1187 };
1188
1189 // handlers
1190
update_display()1191 void ctntune_state::update_display()
1192 {
1193 u8 sel = m_port[PORTD] >> 3 & 1; // turn off display when power is off
1194 u8 lamps = m_port[PORTD] & 3;
1195 u8 digit = (m_port[PORTF] << 4 | m_port[PORTE]) & 0x7f;
1196
1197 m_display->matrix(sel, lamps << 7 | digit);
1198 }
1199
_7seg_w(offs_t offset,u8 data)1200 void ctntune_state::_7seg_w(offs_t offset, u8 data)
1201 {
1202 // E,F012: 7seg data, F3: N/C
1203 m_port[offset] = data;
1204 update_display();
1205 }
1206
speaker_w(u8 data)1207 void ctntune_state::speaker_w(u8 data)
1208 {
1209 // G0: speaker out
1210 m_speaker->level_w(data & 1);
1211 }
1212
input_w(offs_t offset,u8 data)1213 void ctntune_state::input_w(offs_t offset, u8 data)
1214 {
1215 // D3: trigger power-off on falling edge
1216 if (offset == PORTD && ~data & m_port[PORTD] & 8)
1217 m_maincpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
1218
1219 // C,D23: input mux
1220 // D0,D1: yellow, red lamp
1221 m_port[offset] = data;
1222 m_inp_mux = (m_port[PORTD] << 2 & 0x30) | m_port[PORTC];
1223 update_display();
1224 }
1225
input_r()1226 u8 ctntune_state::input_r()
1227 {
1228 // A: multiplexed inputs
1229 return read_inputs(6);
1230 }
1231
1232 // config
1233
1234 static INPUT_PORTS_START( ctntune )
1235 PORT_START("IN.0") // C0 port A
1236 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
1237 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("Button 1") // defaults to keyboard Z row
1238 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON9 ) PORT_NAME("Button 5")
1239 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON13 ) PORT_NAME("Button 9")
1240
1241 PORT_START("IN.1") // C1 port A
1242 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
1243 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("Button 2")
1244 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON10 ) PORT_NAME("Button 6")
1245 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON14 ) PORT_NAME("Button 10")
1246
1247 PORT_START("IN.2") // C2 port A
1248 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
1249 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_NAME("Button 3")
1250 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON11 ) PORT_NAME("Button 7")
1251 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Yellow Button")
1252
1253 PORT_START("IN.3") // C3 port A
1254 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
1255 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_NAME("Button 4")
1256 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON12 ) PORT_NAME("Button 8")
1257 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Red Button")
1258
1259 PORT_START("IN.4") // D2 port A
1260 PORT_BIT( 0x07, IP_ACTIVE_HIGH, IPT_UNUSED )
1261 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("Play Button")
1262
1263 PORT_START("IN.5") // D3 port A
1264 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START ) PORT_CHANGED_MEMBER(DEVICE_SELF, ctntune_state, start_button, 0)
1265 PORT_BIT( 0x0e, IP_ACTIVE_HIGH, IPT_UNUSED )
1266 INPUT_PORTS_END
1267
ctntune(machine_config & config)1268 void ctntune_state::ctntune(machine_config &config)
1269 {
1270 /* basic machine hardware */
1271 NEC_D557L(config, m_maincpu, 200000); // approximation
1272 m_maincpu->read_a().set(FUNC(ctntune_state::input_r));
1273 m_maincpu->write_c().set(FUNC(ctntune_state::input_w));
1274 m_maincpu->write_d().set(FUNC(ctntune_state::input_w));
1275 m_maincpu->write_e().set(FUNC(ctntune_state::_7seg_w));
1276 m_maincpu->write_f().set(FUNC(ctntune_state::_7seg_w));
1277 m_maincpu->write_g().set(FUNC(ctntune_state::speaker_w));
1278
1279 /* video hardware */
1280 PWM_DISPLAY(config, m_display).set_size(1, 7+2);
1281 m_display->set_segmask(1, 0x7f);
1282 config.set_default_layout(layout_ctntune);
1283
1284 /* sound hardware */
1285 SPEAKER(config, "mono").front_center();
1286 SPEAKER_SOUND(config, m_speaker);
1287 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
1288 }
1289
1290 // roms
1291
1292 ROM_START( ctntune )
1293 ROM_REGION( 0x0800, "maincpu", 0 )
1294 ROM_LOAD( "d557lc-513", 0x0000, 0x0800, CRC(cd85ee23) SHA1(32b8fc8cb92fc1fd27da9148788a09d3bcd46a92) )
1295 ROM_END
1296
1297
1298
1299
1300
1301 /***************************************************************************
1302
1303 Epoch Invader From Space (manufactured in Japan)
1304 * PCB labels 36010(A/B)
1305 * NEC uCOM-44 MCU, label D552C 054
1306 * cyan VFD display NEC FIP9AM18T tube no. 0D, with color overlay
1307
1308 known releases:
1309 - USA: Invader From Space
1310 - UK: Invader From Space, published by Grandstand
1311
1312 ***************************************************************************/
1313
1314 class invspace_state : public hh_ucom4_state
1315 {
1316 public:
invspace_state(const machine_config & mconfig,device_type type,const char * tag)1317 invspace_state(const machine_config &mconfig, device_type type, const char *tag) :
1318 hh_ucom4_state(mconfig, type, tag)
1319 { }
1320
1321 void update_display();
1322 void grid_w(offs_t offset, u8 data);
1323 void plate_w(offs_t offset, u8 data);
1324 void invspace(machine_config &config);
1325 };
1326
1327 // handlers
1328
update_display()1329 void invspace_state::update_display()
1330 {
1331 u16 grid = bitswap<16>(m_grid,15,14,13,12,11,10,8,9,7,6,5,4,3,2,1,0);
1332 u32 plate = bitswap<24>(m_plate,23,22,21,20,19,9,14,13,8,15,11,10,7,11,3,2,6,10,1,5,9,0,4,8);
1333 m_display->matrix(grid, plate);
1334 }
1335
grid_w(offs_t offset,u8 data)1336 void invspace_state::grid_w(offs_t offset, u8 data)
1337 {
1338 // I0: speaker out
1339 if (offset == PORTI)
1340 m_speaker->level_w(data & 1);
1341
1342 // C,D,I1: vfd grid
1343 int shift = (offset == PORTI) ? 8 : (offset - PORTC) * 4;
1344 m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
1345 update_display();
1346 }
1347
plate_w(offs_t offset,u8 data)1348 void invspace_state::plate_w(offs_t offset, u8 data)
1349 {
1350 // E,F,G,H123: vfd plate
1351 int shift = (offset - PORTE) * 4;
1352 m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
1353 update_display();
1354 }
1355
1356 // config
1357
1358 static INPUT_PORTS_START( invspace )
1359 PORT_START("IN.0") // port A
1360 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SELECT )
1361 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START )
1362 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 )
1363 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
1364
1365 PORT_START("IN.1") // port B
1366 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY
1367 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY
1368 PORT_BIT( 0x0c, IP_ACTIVE_HIGH, IPT_UNUSED )
1369 INPUT_PORTS_END
1370
invspace(machine_config & config)1371 void invspace_state::invspace(machine_config &config)
1372 {
1373 /* basic machine hardware */
1374 NEC_D552(config, m_maincpu, 400_kHz_XTAL);
1375 m_maincpu->read_a().set_ioport("IN.0");
1376 m_maincpu->read_b().set_ioport("IN.1");
1377 m_maincpu->write_c().set(FUNC(invspace_state::grid_w));
1378 m_maincpu->write_d().set(FUNC(invspace_state::grid_w));
1379 m_maincpu->write_e().set(FUNC(invspace_state::plate_w));
1380 m_maincpu->write_f().set(FUNC(invspace_state::plate_w));
1381 m_maincpu->write_g().set(FUNC(invspace_state::plate_w));
1382 m_maincpu->write_h().set(FUNC(invspace_state::plate_w));
1383 m_maincpu->write_i().set(FUNC(invspace_state::grid_w));
1384
1385 /* video hardware */
1386 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
1387 screen.set_refresh_hz(60);
1388 screen.set_size(289, 1080);
1389 screen.set_visarea_full();
1390
1391 PWM_DISPLAY(config, m_display).set_size(9, 19);
1392
1393 /* sound hardware */
1394 SPEAKER(config, "mono").front_center();
1395 SPEAKER_SOUND(config, m_speaker);
1396 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
1397 }
1398
1399 // roms
1400
1401 ROM_START( invspace )
1402 ROM_REGION( 0x0400, "maincpu", 0 )
1403 ROM_LOAD( "d552c-054", 0x0000, 0x0400, CRC(913d9c13) SHA1(f20edb5458e54d2f6d4e45e5d59efd87e05a6f3f) )
1404
1405 ROM_REGION( 110899, "screen", 0)
1406 ROM_LOAD( "invspace.svg", 0, 110899, CRC(ae794333) SHA1(3552215389f02e4ef1d608f7dfc84f0499a78ee2) )
1407 ROM_END
1408
1409
1410
1411
1412
1413 /***************************************************************************
1414
1415 Epoch Electronic Football (manufactured in Japan)
1416 * PCB labels 36020(A/B/C)
1417 * NEC uCOM-43 MCU, label D553C 080
1418 * cyan VFD display NEC FIP10AM15T tube no. 0F, with bezel overlay
1419
1420 known releases:
1421 - USA: Electronic Football (aka Pro-Bowl Football)
1422 - Japan: American Football
1423
1424 ***************************************************************************/
1425
1426 class efball_state : public hh_ucom4_state
1427 {
1428 public:
efball_state(const machine_config & mconfig,device_type type,const char * tag)1429 efball_state(const machine_config &mconfig, device_type type, const char *tag) :
1430 hh_ucom4_state(mconfig, type, tag)
1431 { }
1432
1433 void update_display();
1434 void grid_w(offs_t offset, u8 data);
1435 void plate_w(offs_t offset, u8 data);
1436 void efball(machine_config &config);
1437 };
1438
1439 // handlers
1440
update_display()1441 void efball_state::update_display()
1442 {
1443 u16 plate = bitswap<16>(m_plate,15,14,13,12,11,4,3,0,2,1,6,10,9,5,8,7);
1444 m_display->matrix(m_grid, plate);
1445 }
1446
grid_w(offs_t offset,u8 data)1447 void efball_state::grid_w(offs_t offset, u8 data)
1448 {
1449 // H2: speaker out
1450 if (offset == PORTH)
1451 m_speaker->level_w(data >> 2 & 1);
1452
1453 // F,G,H01: vfd grid
1454 int shift = (offset - PORTF) * 4;
1455 m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
1456 update_display();
1457 }
1458
plate_w(offs_t offset,u8 data)1459 void efball_state::plate_w(offs_t offset, u8 data)
1460 {
1461 // D,E,I: vfd plate
1462 int shift = (offset == PORTI) ? 8 : (offset - PORTD) * 4;
1463 m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
1464 update_display();
1465 }
1466
1467 // config
1468
1469 static INPUT_PORTS_START( efball )
1470 PORT_START("IN.0") // port A
DEF_STR(Difficulty)1471 PORT_CONFNAME( 0x01, 0x00, DEF_STR( Difficulty ) )
1472 PORT_CONFSETTING( 0x00, "Amateur" )
1473 PORT_CONFSETTING( 0x01, "Professional" )
1474 PORT_CONFNAME( 0x02, 0x02, DEF_STR( Players ) )
1475 PORT_CONFSETTING( 0x02, "1" )
1476 PORT_CONFSETTING( 0x00, "2" )
1477 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("P1 Down-Field")
1478 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("P1 Score-Time")
1479
1480 PORT_START("IN.1") // port B
1481 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_16WAY
1482 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_16WAY
1483 PORT_BIT( 0x04, 0x04, IPT_CUSTOM ) PORT_CONDITION("FAKE", 0x03, NOTEQUALS, 0x00) // left/right
1484 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P1 Pass")
1485
1486 PORT_START("IN.2") // port C
1487 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_COCKTAIL PORT_16WAY
1488 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_COCKTAIL PORT_16WAY
1489 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_COCKTAIL PORT_NAME("P2 Kick Return")
1490 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P1 Kick")
1491
1492 PORT_START("FAKE") // fake port for left/right combination
1493 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_16WAY PORT_NAME("P1 Left/Right")
1494 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_16WAY PORT_NAME("P1 Left/Right")
1495 INPUT_PORTS_END
1496
1497 void efball_state::efball(machine_config &config)
1498 {
1499 /* basic machine hardware */
1500 NEC_D553(config, m_maincpu, 400_kHz_XTAL);
1501 m_maincpu->read_a().set_ioport("IN.0");
1502 m_maincpu->read_b().set_ioport("IN.1");
1503 m_maincpu->read_c().set_ioport("IN.2");
1504 m_maincpu->write_d().set(FUNC(efball_state::plate_w));
1505 m_maincpu->write_e().set(FUNC(efball_state::plate_w));
1506 m_maincpu->write_f().set(FUNC(efball_state::grid_w));
1507 m_maincpu->write_g().set(FUNC(efball_state::grid_w));
1508 m_maincpu->write_h().set(FUNC(efball_state::grid_w));
1509 m_maincpu->write_i().set(FUNC(efball_state::plate_w));
1510
1511 /* video hardware */
1512 PWM_DISPLAY(config, m_display).set_size(10, 11);
1513 config.set_default_layout(layout_efball);
1514
1515 /* sound hardware */
1516 SPEAKER(config, "mono").front_center();
1517 SPEAKER_SOUND(config, m_speaker);
1518 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
1519 }
1520
1521 // roms
1522
1523 ROM_START( efball )
1524 ROM_REGION( 0x0800, "maincpu", 0 )
1525 ROM_LOAD( "d553c-080", 0x0000, 0x0800, CRC(54c1027f) SHA1(6cc98074dae9361fa8c0ed6501b6a57ad325ccbd) )
1526 ROM_END
1527
1528
1529
1530
1531
1532 /***************************************************************************
1533
1534 Epoch Galaxy II (manufactured in Japan)
1535 * PCB labels 19096/96062
1536 * NEC uCOM-43 MCU, label D553C 153
1537 * cyan/red VFD display NEC FIP10xM20T, with color overlay. x = multiple VFD
1538 revisions exist, with different graphics: rev B no. 1-8, rev. D no. 2-21.
1539
1540 known releases:
1541 - USA: Galaxy II
1542 - Japan: Astro Wars
1543 - UK: Astro Wars, published by Grandstand
1544
1545 ***************************************************************************/
1546
1547 class galaxy2_state : public hh_ucom4_state
1548 {
1549 public:
galaxy2_state(const machine_config & mconfig,device_type type,const char * tag)1550 galaxy2_state(const machine_config &mconfig, device_type type, const char *tag) :
1551 hh_ucom4_state(mconfig, type, tag)
1552 { }
1553
1554 void update_display();
1555 void grid_w(offs_t offset, u8 data);
1556 void plate_w(offs_t offset, u8 data);
1557 void galaxy2b(machine_config &config);
1558 void galaxy2(machine_config &config);
1559 };
1560
1561 // handlers
1562
update_display()1563 void galaxy2_state::update_display()
1564 {
1565 u16 grid = bitswap<16>(m_grid,15,14,13,12,11,10,0,1,2,3,4,5,6,7,8,9);
1566 u16 plate = bitswap<16>(m_plate,15,3,2,6,1,5,4,0,11,10,7,12,14,13,8,9);
1567 m_display->matrix(grid, plate);
1568 }
1569
grid_w(offs_t offset,u8 data)1570 void galaxy2_state::grid_w(offs_t offset, u8 data)
1571 {
1572 // E3: speaker out
1573 if (offset == PORTE)
1574 m_speaker->level_w(data >> 3 & 1);
1575
1576 // C,D,E01: vfd grid
1577 int shift = (offset - PORTC) * 4;
1578 m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
1579 update_display();
1580 }
1581
plate_w(offs_t offset,u8 data)1582 void galaxy2_state::plate_w(offs_t offset, u8 data)
1583 {
1584 // F,G,H,I: vfd plate
1585 int shift = (offset - PORTF) * 4;
1586 m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
1587 update_display();
1588 }
1589
1590 // config
1591
1592 static INPUT_PORTS_START( galaxy2 )
1593 PORT_START("IN.0") // port A
1594 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 )
1595 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY
1596 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY
1597 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
1598
1599 PORT_START("IN.1") // port B
1600 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SELECT )
1601 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START )
1602 PORT_BIT( 0x0c, IP_ACTIVE_HIGH, IPT_UNUSED )
1603 INPUT_PORTS_END
1604
galaxy2(machine_config & config)1605 void galaxy2_state::galaxy2(machine_config &config)
1606 {
1607 /* basic machine hardware */
1608 NEC_D553(config, m_maincpu, 400_kHz_XTAL);
1609 m_maincpu->read_a().set_ioport("IN.0");
1610 m_maincpu->read_b().set_ioport("IN.1");
1611 m_maincpu->write_c().set(FUNC(galaxy2_state::grid_w));
1612 m_maincpu->write_d().set(FUNC(galaxy2_state::grid_w));
1613 m_maincpu->write_e().set(FUNC(galaxy2_state::grid_w));
1614 m_maincpu->write_f().set(FUNC(galaxy2_state::plate_w));
1615 m_maincpu->write_g().set(FUNC(galaxy2_state::plate_w));
1616 m_maincpu->write_h().set(FUNC(galaxy2_state::plate_w));
1617 m_maincpu->write_i().set(FUNC(galaxy2_state::plate_w));
1618
1619 /* video hardware */
1620 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
1621 screen.set_refresh_hz(60);
1622 screen.set_size(304, 1080);
1623 screen.set_visarea_full();
1624
1625 PWM_DISPLAY(config, m_display).set_size(10, 15);
1626
1627 /* sound hardware */
1628 SPEAKER(config, "mono").front_center();
1629 SPEAKER_SOUND(config, m_speaker);
1630 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
1631 }
1632
galaxy2b(machine_config & config)1633 void galaxy2_state::galaxy2b(machine_config &config)
1634 {
1635 galaxy2(config);
1636
1637 /* video hardware */
1638 screen_device *screen = subdevice<screen_device>("screen");
1639 screen->set_size(306, 1080);
1640 screen->set_visarea_full();
1641 }
1642
1643 // roms
1644
1645 ROM_START( galaxy2 )
1646 ROM_REGION( 0x0800, "maincpu", 0 )
1647 ROM_LOAD( "d553c-153.s01", 0x0000, 0x0800, CRC(70d552b3) SHA1(72d50647701cb4bf85ea947a149a317aaec0f52c) )
1648
1649 ROM_REGION( 325057, "screen", 0)
1650 ROM_LOAD( "galaxy2d.svg", 0, 325057, CRC(b2d27a0e) SHA1(502ec22c324903ffe8ff235b9a3b8898dce17a64) )
1651 ROM_END
1652
1653 ROM_START( galaxy2b )
1654 ROM_REGION( 0x0800, "maincpu", 0 )
1655 ROM_LOAD( "d553c-153.s01", 0x0000, 0x0800, CRC(70d552b3) SHA1(72d50647701cb4bf85ea947a149a317aaec0f52c) )
1656
1657 ROM_REGION( 266377, "screen", 0)
1658 ROM_LOAD( "galaxy2b.svg", 0, 266377, CRC(8633cebb) SHA1(6c41f5e918e1522eb55ef24270900a1b2477722b) )
1659 ROM_END
1660
1661
1662
1663
1664
1665 /***************************************************************************
1666
1667 Epoch Astro Command (manufactured in Japan)
1668 * PCB labels 96111/96112
1669 * NEC uCOM-43 MCU, label D553C 202
1670 * cyan/red VFD display NEC FIP9AM20T no. 42-42, with color overlay + bezel
1671
1672 known releases:
1673 - Japan: Astro Command
1674 - USA: Astro Command, published by Tandy
1675 - UK: Scramble, published by Grandstand
1676
1677 ***************************************************************************/
1678
1679 class astrocmd_state : public hh_ucom4_state
1680 {
1681 public:
astrocmd_state(const machine_config & mconfig,device_type type,const char * tag)1682 astrocmd_state(const machine_config &mconfig, device_type type, const char *tag) :
1683 hh_ucom4_state(mconfig, type, tag)
1684 { }
1685
1686 void update_display();
1687 void grid_w(offs_t offset, u8 data);
1688 void plate_w(offs_t offset, u8 data);
1689 void astrocmd(machine_config &config);
1690 };
1691
1692 // handlers
1693
update_display()1694 void astrocmd_state::update_display()
1695 {
1696 u16 grid = bitswap<16>(m_grid,15,14,13,12,11,10,9,8,4,5,6,7,0,1,2,3);
1697 u32 plate = bitswap<24>(m_plate,23,22,21,20,19,3,2,12,13,14,15,16,17,18,0,1,4,8,5,9,7,11,6,10);
1698 m_display->matrix(grid, plate);
1699 }
1700
grid_w(offs_t offset,u8 data)1701 void astrocmd_state::grid_w(offs_t offset, u8 data)
1702 {
1703 // C,D(,E3): vfd grid
1704 int shift = (offset - PORTC) * 4;
1705 m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
1706 update_display();
1707 }
1708
plate_w(offs_t offset,u8 data)1709 void astrocmd_state::plate_w(offs_t offset, u8 data)
1710 {
1711 // E01,F,G,H,I: vfd plate
1712 int shift = (offset - PORTE) * 4;
1713 m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
1714
1715 if (offset == PORTE)
1716 {
1717 // E2: speaker out
1718 m_speaker->level_w(data >> 2 & 1);
1719
1720 // E3: vfd grid 8
1721 grid_w(offset, data >> 3 & 1);
1722 }
1723 else
1724 update_display();
1725 }
1726
1727 // config
1728
1729 static INPUT_PORTS_START( astrocmd )
1730 PORT_START("IN.0") // port A
1731 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SELECT )
1732 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START )
1733 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Missile")
1734 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Bomb")
1735
1736 PORT_START("IN.1") // port B
1737 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
1738 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
1739 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
1740 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
1741 INPUT_PORTS_END
1742
astrocmd(machine_config & config)1743 void astrocmd_state::astrocmd(machine_config &config)
1744 {
1745 /* basic machine hardware */
1746 NEC_D553(config, m_maincpu, 400_kHz_XTAL);
1747 m_maincpu->read_a().set_ioport("IN.0");
1748 m_maincpu->read_b().set_ioport("IN.1");
1749 m_maincpu->write_c().set(FUNC(astrocmd_state::grid_w));
1750 m_maincpu->write_d().set(FUNC(astrocmd_state::grid_w));
1751 m_maincpu->write_e().set(FUNC(astrocmd_state::plate_w));
1752 m_maincpu->write_f().set(FUNC(astrocmd_state::plate_w));
1753 m_maincpu->write_g().set(FUNC(astrocmd_state::plate_w));
1754 m_maincpu->write_h().set(FUNC(astrocmd_state::plate_w));
1755 m_maincpu->write_i().set(FUNC(astrocmd_state::plate_w));
1756
1757 /* video hardware */
1758 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
1759 screen.set_refresh_hz(60);
1760 screen.set_size(1920, 525);
1761 screen.set_visarea_full();
1762
1763 PWM_DISPLAY(config, m_display).set_size(9, 17);
1764
1765 /* sound hardware */
1766 SPEAKER(config, "mono").front_center();
1767 SPEAKER_SOUND(config, m_speaker);
1768 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
1769 }
1770
1771 // roms
1772
1773 ROM_START( astrocmd )
1774 ROM_REGION( 0x0800, "maincpu", 0 )
1775 ROM_LOAD( "d553c-202.s01", 0x0000, 0x0800, CRC(b4b34883) SHA1(6246d561c2df1f2124575d2ca671ef85b1819edd) )
1776
1777 ROM_REGION( 335362, "screen", 0)
1778 ROM_LOAD( "astrocmd.svg", 0, 335362, CRC(fe2cd30f) SHA1(898a3d9afc5dca6c63ae28aed2c8530716ad1c45) )
1779 ROM_END
1780
1781
1782
1783
1784
1785 /***************************************************************************
1786
1787 Epoch Dracula (manufactured in Japan)
1788 * PCB label 96121
1789 * NEC uCOM-43 MCU, label D553C 206
1790 * cyan/red/green VFD display NEC FIP8BM20T no. 2-42
1791
1792 known releases:
1793 - Japan: Dracula House, yellow case
1794 - USA: Dracula, red case
1795 - Other: Dracula, yellow case, published by Hales
1796
1797 ***************************************************************************/
1798
1799 class edracula_state : public hh_ucom4_state
1800 {
1801 public:
edracula_state(const machine_config & mconfig,device_type type,const char * tag)1802 edracula_state(const machine_config &mconfig, device_type type, const char *tag) :
1803 hh_ucom4_state(mconfig, type, tag)
1804 { }
1805
1806 void update_display();
1807 void grid_w(offs_t offset, u8 data);
1808 void plate_w(offs_t offset, u8 data);
1809 void edracula(machine_config &config);
1810 };
1811
1812 // handlers
1813
update_display()1814 void edracula_state::update_display()
1815 {
1816 m_display->matrix(m_grid, m_plate);
1817 }
1818
grid_w(offs_t offset,u8 data)1819 void edracula_state::grid_w(offs_t offset, u8 data)
1820 {
1821 // C,D: vfd grid
1822 int shift = (offset - PORTC) * 4;
1823 m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
1824 update_display();
1825 }
1826
plate_w(offs_t offset,u8 data)1827 void edracula_state::plate_w(offs_t offset, u8 data)
1828 {
1829 // I2: speaker out
1830 if (offset == PORTI)
1831 m_speaker->level_w(data >> 2 & 1);
1832
1833 // E,F,G,H,I01: vfd plate
1834 int shift = (offset - PORTE) * 4;
1835 m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
1836 update_display();
1837 }
1838
1839 // config
1840
1841 static INPUT_PORTS_START( edracula )
1842 PORT_START("IN.0") // port A
1843 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SELECT )
1844 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START )
1845 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 )
1846 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
1847
1848 PORT_START("IN.1") // port B
1849 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
1850 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
1851 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
1852 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
1853 INPUT_PORTS_END
1854
edracula(machine_config & config)1855 void edracula_state::edracula(machine_config &config)
1856 {
1857 /* basic machine hardware */
1858 NEC_D553(config, m_maincpu, 400_kHz_XTAL);
1859 m_maincpu->read_a().set_ioport("IN.0");
1860 m_maincpu->read_b().set_ioport("IN.1");
1861 m_maincpu->write_c().set(FUNC(edracula_state::grid_w));
1862 m_maincpu->write_d().set(FUNC(edracula_state::grid_w));
1863 m_maincpu->write_e().set(FUNC(edracula_state::plate_w));
1864 m_maincpu->write_f().set(FUNC(edracula_state::plate_w));
1865 m_maincpu->write_g().set(FUNC(edracula_state::plate_w));
1866 m_maincpu->write_h().set(FUNC(edracula_state::plate_w));
1867 m_maincpu->write_i().set(FUNC(edracula_state::plate_w));
1868
1869 /* video hardware */
1870 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
1871 screen.set_refresh_hz(60);
1872 screen.set_size(1920, 526);
1873 screen.set_visarea_full();
1874
1875 PWM_DISPLAY(config, m_display).set_size(8, 18);
1876
1877 /* sound hardware */
1878 SPEAKER(config, "mono").front_center();
1879 SPEAKER_SOUND(config, m_speaker);
1880 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
1881 }
1882
1883 // roms
1884
1885 ROM_START( edracula )
1886 ROM_REGION( 0x0800, "maincpu", 0 )
1887 ROM_LOAD( "d553c-206.s01", 0x0000, 0x0800, CRC(b524857b) SHA1(c1c89ed5dd4bb1e6e98462dc8fa5af2aa48d8ede) )
1888
1889 ROM_REGION( 794532, "screen", 0)
1890 ROM_LOAD( "edracula.svg", 0, 794532, CRC(d20e018c) SHA1(7f70f1d373c034ec8c93e27b7e3371578ddaf61b) )
1891 ROM_END
1892
1893
1894
1895
1896
1897 /***************************************************************************
1898
1899 Mattel Computer Gin
1900 * NEC uCOM-43 MCU, label D650C 060 (die label same)
1901 * Hughes HLCD0530 LCD driver, 5 by 14 segments LCD panel, no sound
1902
1903 ***************************************************************************/
1904
1905 class mcompgin_state : public hh_ucom4_state
1906 {
1907 public:
mcompgin_state(const machine_config & mconfig,device_type type,const char * tag)1908 mcompgin_state(const machine_config &mconfig, device_type type, const char *tag) :
1909 hh_ucom4_state(mconfig, type, tag),
1910 m_lcd(*this, "lcd")
1911 { }
1912
1913 required_device<hlcd0530_device> m_lcd;
1914
1915 void lcd_output_w(offs_t offset, u32 data);
1916 void lcd_w(u8 data);
1917 void mcompgin(machine_config &config);
1918 };
1919
1920 // handlers
1921
lcd_output_w(offs_t offset,u32 data)1922 void mcompgin_state::lcd_output_w(offs_t offset, u32 data)
1923 {
1924 // uses ROW0-4, COL11-24
1925 m_display->matrix(1 << offset, data);
1926 }
1927
lcd_w(u8 data)1928 void mcompgin_state::lcd_w(u8 data)
1929 {
1930 // E0: HLCD0530 _CS
1931 // E1: HLCD0530 clock
1932 // E2: HLCD0530 data in
1933 m_lcd->cs_w(data & 1);
1934 m_lcd->data_w(data >> 2 & 1);
1935 m_lcd->clock_w(data >> 1 & 1);
1936 }
1937
1938 // config
1939
1940 static INPUT_PORTS_START( mcompgin )
1941 PORT_START("IN.0") // port A
1942 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Select")
1943 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("Deal / Gin")
1944 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Discard")
1945 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Draw")
1946
1947 PORT_START("IN.1") // port B
1948 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("Compare")
1949 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("Score")
1950 PORT_BIT( 0x0c, IP_ACTIVE_HIGH, IPT_UNUSED )
1951 INPUT_PORTS_END
1952
mcompgin(machine_config & config)1953 void mcompgin_state::mcompgin(machine_config &config)
1954 {
1955 /* basic machine hardware */
1956 NEC_D650(config, m_maincpu, 400_kHz_XTAL); // TDK FCR400K
1957 m_maincpu->read_a().set_ioport("IN.0");
1958 m_maincpu->read_b().set_ioport("IN.1");
1959 m_maincpu->write_e().set(FUNC(mcompgin_state::lcd_w));
1960
1961 /* video hardware */
1962 HLCD0530(config, m_lcd, 500); // C=0.01uF
1963 m_lcd->write_cols().set(FUNC(mcompgin_state::lcd_output_w));
1964
1965 PWM_DISPLAY(config, m_display).set_size(8, 24);
1966
1967 config.set_default_layout(layout_mcompgin);
1968
1969 /* no sound! */
1970 }
1971
1972 // roms
1973
1974 ROM_START( mcompgin )
1975 ROM_REGION( 0x0800, "maincpu", 0 )
1976 ROM_LOAD( "d650c-060", 0x0000, 0x0800, CRC(985e6da6) SHA1(ea4102a10a5741f06297c5426156e4b2f0d85a68) )
1977 ROM_END
1978
1979
1980
1981
1982
1983 /***************************************************************************
1984
1985 Mego Mini-Vid: Break Free (manufactured in Japan)
1986 * PCB label Mego 79 rev F
1987 * NEC uCOM-43 MCU, label D553C 049
1988 * cyan VFD display Futaba DM-4.5 91
1989
1990 ***************************************************************************/
1991
1992 class mvbfree_state : public hh_ucom4_state
1993 {
1994 public:
mvbfree_state(const machine_config & mconfig,device_type type,const char * tag)1995 mvbfree_state(const machine_config &mconfig, device_type type, const char *tag) :
1996 hh_ucom4_state(mconfig, type, tag)
1997 { }
1998
1999 void update_display();
2000 void grid_w(offs_t offset, u8 data);
2001 void plate_w(offs_t offset, u8 data);
2002 void speaker_w(u8 data);
2003 void mvbfree(machine_config &config);
2004 };
2005
2006 // handlers
2007
update_display()2008 void mvbfree_state::update_display()
2009 {
2010 u16 grid = bitswap<16>(m_grid,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
2011 u16 plate = bitswap<16>(m_plate,15,14,13,12,11,10,0,1,2,3,4,5,6,7,8,9);
2012 m_display->matrix(grid, plate);
2013 }
2014
grid_w(offs_t offset,u8 data)2015 void mvbfree_state::grid_w(offs_t offset, u8 data)
2016 {
2017 // E23,F,G,H: vfd grid
2018 int shift = (offset - PORTE) * 4;
2019 m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
2020
2021 // E01: plate 0,1
2022 if (offset == PORTE)
2023 plate_w(2 + PORTC, data & 3);
2024 else
2025 update_display();
2026 }
2027
plate_w(offs_t offset,u8 data)2028 void mvbfree_state::plate_w(offs_t offset, u8 data)
2029 {
2030 // C,D(,E01): vfd plate
2031 int shift = (offset - PORTC) * 4;
2032 m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
2033 update_display();
2034 }
2035
speaker_w(u8 data)2036 void mvbfree_state::speaker_w(u8 data)
2037 {
2038 // I0: speaker out
2039 m_speaker->level_w(data & 1);
2040 }
2041
2042 // config
2043
2044 static INPUT_PORTS_START( mvbfree )
2045 PORT_START("IN.0") // port A
2046 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_COCKTAIL PORT_16WAY
2047 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_COCKTAIL PORT_16WAY
2048 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_16WAY
2049 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_16WAY
2050
2051 PORT_START("IN.1") // port B
2052 PORT_BIT( 0x03, IP_ACTIVE_HIGH, IPT_UNUSED ) // unimplemented p1/p2 buttons
2053 PORT_CONFNAME( 0x0c, 0x04, "Game Select")
2054 PORT_CONFSETTING( 0x04, "1" )
2055 PORT_CONFSETTING( 0x00, "2" )
2056 PORT_CONFSETTING( 0x08, "3" )
2057 INPUT_PORTS_END
2058
mvbfree(machine_config & config)2059 void mvbfree_state::mvbfree(machine_config &config)
2060 {
2061 /* basic machine hardware */
2062 NEC_D553(config, m_maincpu, 400000); // approximation
2063 m_maincpu->read_a().set_ioport("IN.0");
2064 m_maincpu->read_b().set_ioport("IN.1");
2065 m_maincpu->write_c().set(FUNC(mvbfree_state::plate_w));
2066 m_maincpu->write_d().set(FUNC(mvbfree_state::plate_w));
2067 m_maincpu->write_e().set(FUNC(mvbfree_state::grid_w));
2068 m_maincpu->write_f().set(FUNC(mvbfree_state::grid_w));
2069 m_maincpu->write_g().set(FUNC(mvbfree_state::grid_w));
2070 m_maincpu->write_h().set(FUNC(mvbfree_state::grid_w));
2071 m_maincpu->write_i().set(FUNC(mvbfree_state::speaker_w));
2072
2073 /* video hardware */
2074 PWM_DISPLAY(config, m_display).set_size(14, 10);
2075 config.set_default_layout(layout_mvbfree);
2076
2077 /* sound hardware */
2078 SPEAKER(config, "mono").front_center();
2079 SPEAKER_SOUND(config, m_speaker);
2080 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
2081 }
2082
2083 // roms
2084
2085 ROM_START( mvbfree )
2086 ROM_REGION( 0x0800, "maincpu", 0 )
2087 ROM_LOAD( "d553c-049", 0x0000, 0x0800, CRC(d64a8399) SHA1(97887e486fa29b1fc4a5a40cacf3c960f67aacbf) )
2088 ROM_END
2089
2090
2091
2092
2093
2094 /***************************************************************************
2095
2096 Takatoku Toys(T.T) Game Robot 9 「ゲームロボット九」
2097 * PCB label GAME ROBOT 7520
2098 * NEC uCOM-43 MCU, label TTGR-512 (die label NEC D557 511)
2099 * 9 lamps behind buttons
2100
2101 known releases:
2102 - Japan: Game Robot 9
2103 - USA: Fabulous Fred - The Ultimate Electronic Game, published by Mego
2104 - Mexico: Fabuloso Fred, published by Ensueño Toys (also released as
2105 12-button version, a clone of Tandy-12)
2106
2107 Accessories were included for some of the minigames.
2108
2109 ***************************************************************************/
2110
2111 class grobot9_state : public hh_ucom4_state
2112 {
2113 public:
grobot9_state(const machine_config & mconfig,device_type type,const char * tag)2114 grobot9_state(const machine_config &mconfig, device_type type, const char *tag) :
2115 hh_ucom4_state(mconfig, type, tag)
2116 { }
2117
2118 void lamps_w(offs_t offset, u8 data);
2119 void speaker_w(u8 data);
2120 void input_w(u8 data);
2121 u8 input_r();
2122 void grobot9(machine_config &config);
2123 };
2124
2125 // handlers
2126
lamps_w(offs_t offset,u8 data)2127 void grobot9_state::lamps_w(offs_t offset, u8 data)
2128 {
2129 if (offset == PORTE)
2130 {
2131 // E1: speaker out
2132 m_speaker->level_w(data >> 1 & 1);
2133
2134 // E3: input mux high bit
2135 m_inp_mux = (m_inp_mux & 7) | (data & 8);
2136 }
2137
2138 // D,F,E0: lamps
2139 m_port[offset] = data;
2140 m_display->matrix(1, m_port[PORTD] | m_port[PORTF] << 4 | m_port[PORTE] << 8);
2141 }
2142
input_w(u8 data)2143 void grobot9_state::input_w(u8 data)
2144 {
2145 // C012: input mux low
2146 m_inp_mux = (m_inp_mux & 8) | (data & 7);
2147 }
2148
input_r()2149 u8 grobot9_state::input_r()
2150 {
2151 // A: multiplexed inputs
2152 return read_inputs(5);
2153 }
2154
2155 // config
2156
2157 static INPUT_PORTS_START( grobot9 )
2158 PORT_START("IN.0") // C0 port A
PORT_CODE(KEYCODE_1)2159 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_Q) PORT_NAME("Button 1")
2160 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_W) PORT_NAME("Button 2")
2161 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_E) PORT_NAME("Button 3")
2162 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_D) PORT_NAME("Button 4")
2163
2164 PORT_START("IN.1") // C1 port A
2165 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_C) PORT_NAME("Button 5")
2166 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_X) PORT_NAME("Button 6")
2167 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_Z) PORT_NAME("Button 7")
2168 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_A) PORT_NAME("Button 8")
2169
2170 PORT_START("IN.2") // C2 port A
2171 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_S) PORT_NAME("Button 9")
2172 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_T) PORT_NAME("Rest")
2173 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Y) PORT_NAME("Eighth Note")
2174 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
2175
2176 PORT_START("IN.3") // E3 port A
2177 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_B) PORT_NAME("Select")
2178 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
2179 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_N) PORT_NAME("Hit")
2180 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) PORT_NAME("Repeat")
2181
2182 PORT_START("IN.4") // INT
2183 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_V) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_ucom4_state, single_interrupt_line, 0) PORT_NAME("Start-Pitch")
2184 INPUT_PORTS_END
2185
2186 void grobot9_state::grobot9(machine_config &config)
2187 {
2188 /* basic machine hardware */
2189 NEC_D557L(config, m_maincpu, 160000); // approximation
2190 m_maincpu->read_a().set(FUNC(grobot9_state::input_r));
2191 m_maincpu->write_c().set(FUNC(grobot9_state::input_w));
2192 m_maincpu->write_d().set(FUNC(grobot9_state::lamps_w));
2193 m_maincpu->write_e().set(FUNC(grobot9_state::lamps_w));
2194 m_maincpu->write_f().set(FUNC(grobot9_state::lamps_w));
2195
2196 /* video hardware */
2197 PWM_DISPLAY(config, m_display).set_size(1, 9);
2198 config.set_default_layout(layout_grobot9);
2199
2200 /* sound hardware */
2201 SPEAKER(config, "mono").front_center();
2202 SPEAKER_SOUND(config, m_speaker);
2203 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
2204 }
2205
2206 // roms
2207
2208 ROM_START( grobot9 )
2209 ROM_REGION( 0x0800, "maincpu", 0 )
2210 ROM_LOAD( "ttgr-511", 0x0000, 0x0800, CRC(1f25b2bb) SHA1(55ae7e23f6dd46cc6e1a65839327726678410c3a) )
2211 ROM_END
2212
2213
2214
2215
2216
2217 /***************************************************************************
2218
2219 Tomy(tronic) Cosmic Combat (manufactured in Japan)
2220 * PCB label 2E1019-E01
2221 * NEC uCOM-44 MCU, label D552C 042
2222 * cyan VFD display NEC FIP32AM18Y tube no. 0E, with color overlay
2223
2224 known releases:
2225 - USA: Cosmic Combat
2226 - Japan: Space Attack
2227
2228 ***************************************************************************/
2229
2230 class tccombat_state : public hh_ucom4_state
2231 {
2232 public:
tccombat_state(const machine_config & mconfig,device_type type,const char * tag)2233 tccombat_state(const machine_config &mconfig, device_type type, const char *tag) :
2234 hh_ucom4_state(mconfig, type, tag)
2235 { }
2236
2237 void update_display();
2238 void grid_w(offs_t offset, u8 data);
2239 void plate_w(offs_t offset, u8 data);
2240 void tccombat(machine_config &config);
2241 };
2242
2243 // handlers
2244
update_display()2245 void tccombat_state::update_display()
2246 {
2247 u16 grid = bitswap<16>(m_grid,15,14,13,12,11,10,9,8,3,2,1,0,7,6,5,4);
2248 u32 plate = bitswap<24>(m_plate,23,22,21,20,11,15,3,10,14,2,9,13,1,0,12,8,15,1,5,0,3,7,2,6);
2249 m_display->matrix(grid, plate);
2250 }
2251
grid_w(offs_t offset,u8 data)2252 void tccombat_state::grid_w(offs_t offset, u8 data)
2253 {
2254 // I1: speaker out
2255 if (offset == PORTI)
2256 m_speaker->level_w(data >> 1 & 1);
2257
2258 // C,D,I0: vfd grid
2259 int shift = (offset == PORTI) ? 8 : (offset - PORTC) * 4;
2260 m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
2261 update_display();
2262 }
2263
plate_w(offs_t offset,u8 data)2264 void tccombat_state::plate_w(offs_t offset, u8 data)
2265 {
2266 // E,F123,G,H: vfd plate
2267 int shift = (offset - PORTE) * 4;
2268 m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
2269 update_display();
2270 }
2271
2272 // config
2273
2274 static INPUT_PORTS_START( tccombat )
2275 PORT_START("IN.0") // port A
2276 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 )
DEF_STR(Difficulty)2277 PORT_CONFNAME( 0x02, 0x02, DEF_STR( Difficulty ) )
2278 PORT_CONFSETTING( 0x02, "1" )
2279 PORT_CONFSETTING( 0x00, "2" )
2280 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY
2281 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY
2282 INPUT_PORTS_END
2283
2284 void tccombat_state::tccombat(machine_config &config)
2285 {
2286 /* basic machine hardware */
2287 NEC_D552(config, m_maincpu, 400000); // approximation
2288 m_maincpu->read_a().set_ioport("IN.0");
2289 m_maincpu->write_c().set(FUNC(tccombat_state::grid_w));
2290 m_maincpu->write_d().set(FUNC(tccombat_state::grid_w));
2291 m_maincpu->write_e().set(FUNC(tccombat_state::plate_w));
2292 m_maincpu->write_f().set(FUNC(tccombat_state::plate_w));
2293 m_maincpu->write_g().set(FUNC(tccombat_state::plate_w));
2294 m_maincpu->write_h().set(FUNC(tccombat_state::plate_w));
2295 m_maincpu->write_i().set(FUNC(tccombat_state::grid_w));
2296
2297 /* video hardware */
2298 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
2299 screen.set_refresh_hz(60);
2300 screen.set_size(300, 1080);
2301 screen.set_visarea_full();
2302
2303 PWM_DISPLAY(config, m_display).set_size(9, 20);
2304
2305 /* sound hardware */
2306 SPEAKER(config, "mono").front_center();
2307 SPEAKER_SOUND(config, m_speaker);
2308 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
2309 }
2310
2311 // roms
2312
2313 ROM_START( tccombat )
2314 ROM_REGION( 0x0400, "maincpu", 0 )
2315 ROM_LOAD( "d552c-042", 0x0000, 0x0400, CRC(d7b5cfeb) SHA1(a267be8e43b7740758eb0881b655b1cc8aec43da) )
2316
2317 ROM_REGION( 210960, "screen", 0)
2318 ROM_LOAD( "tccombat.svg", 0, 210960, CRC(03e9eba6) SHA1(d558d3063da42dc7cc02b769bca06a3732418837) )
2319 ROM_END
2320
2321
2322
2323
2324
2325 /***************************************************************************
2326
2327 Tomy(tronic) Tennis (manufactured in Japan)
2328 * PCB label TOMY TN-04 TENNIS
2329 * NEC uCOM-44 MCU, label D552C 048
2330 * cyan VFD display NEC FIP11AM15T tube no. 0F, with overlay
2331
2332 The initial release of this game was in 1979, known as Pro-Tennis,
2333 it has a D553 instead of D552, with just a little over 50% ROM used.
2334
2335 Press the Serve button to start, then hit the ball by pressing one of the
2336 positional buttons when the ball flies over it.
2337
2338 ***************************************************************************/
2339
2340 class tmtennis_state : public hh_ucom4_state
2341 {
2342 public:
tmtennis_state(const machine_config & mconfig,device_type type,const char * tag)2343 tmtennis_state(const machine_config &mconfig, device_type type, const char *tag) :
2344 hh_ucom4_state(mconfig, type, tag)
2345 { }
2346
2347 void update_display();
2348 void grid_w(offs_t offset, u8 data);
2349 void plate_w(offs_t offset, u8 data);
2350 void port_e_w(u8 data);
2351 u8 input_r(offs_t offset);
2352
2353 void set_clock();
DECLARE_INPUT_CHANGED_MEMBER(difficulty_switch)2354 DECLARE_INPUT_CHANGED_MEMBER(difficulty_switch) { set_clock(); }
2355 void tmtennis(machine_config &config);
2356
2357 protected:
2358 virtual void machine_reset() override;
2359 };
2360
machine_reset()2361 void tmtennis_state::machine_reset()
2362 {
2363 hh_ucom4_state::machine_reset();
2364 set_clock();
2365 }
2366
2367 // handlers
2368
set_clock()2369 void tmtennis_state::set_clock()
2370 {
2371 // MCU clock is from an LC circuit oscillating by default at ~360kHz,
2372 // but on PRO1, the difficulty switch puts a capacitor across the LC circuit
2373 // to slow it down to ~260kHz.
2374 m_maincpu->set_unscaled_clock((m_inputs[1]->read() & 0x100) ? 260000 : 360000);
2375 }
2376
update_display()2377 void tmtennis_state::update_display()
2378 {
2379 m_display->matrix(m_grid, m_plate);
2380 }
2381
grid_w(offs_t offset,u8 data)2382 void tmtennis_state::grid_w(offs_t offset, u8 data)
2383 {
2384 // G,H,I: vfd grid
2385 int shift = (offset - PORTG) * 4;
2386 m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
2387 update_display();
2388 }
2389
plate_w(offs_t offset,u8 data)2390 void tmtennis_state::plate_w(offs_t offset, u8 data)
2391 {
2392 // C,D,F: vfd plate
2393 int shift = (offset == PORTF) ? 8 : (offset - PORTC) * 4;
2394 m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
2395 update_display();
2396 }
2397
port_e_w(u8 data)2398 void tmtennis_state::port_e_w(u8 data)
2399 {
2400 // E01: input mux
2401 // E2: speaker out
2402 // E3: N/C
2403 m_inp_mux = data & 3;
2404 m_speaker->level_w(data >> 2 & 1);
2405 }
2406
input_r(offs_t offset)2407 u8 tmtennis_state::input_r(offs_t offset)
2408 {
2409 // A,B: multiplexed buttons
2410 return ~read_inputs(2) >> (offset*4);
2411 }
2412
2413 // config
2414
2415 /* Pro-Tennis physical button layout and labels is like this:
2416
2417 * left = P2/CPU side * * right = P1 side *
2418
2419 [SERVE] [1] [2] [3] [3] [2] [1] [SERVE]
2420 [4] [5] [6] [6] [5] [4]
2421
2422 PRACTICE<--PRO1-->PRO2 1PLAYER<--OFF-->2PLAYER
2423 */
2424
2425 static INPUT_PORTS_START( tmtennis )
2426 PORT_START("IN.0") // E0 port A/B
2427 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START1 ) PORT_NAME("P1 Serve")
2428 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 ) PORT_NAME("P2 Serve")
PORT_CODE(KEYCODE_O)2429 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_O) PORT_NAME("P1 Button 1")
2430 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_L) PORT_NAME("P1 Button 4")
2431 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_I) PORT_NAME("P1 Button 2")
2432 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_K) PORT_NAME("P1 Button 5")
2433 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_U) PORT_NAME("P1 Button 3")
2434 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_J) PORT_NAME("P1 Button 6")
2435
2436 PORT_START("IN.1") // E1 port A/B
2437 PORT_CONFNAME( 0x101, 0x100, DEF_STR( Difficulty ) ) PORT_CHANGED_MEMBER(DEVICE_SELF, tmtennis_state, difficulty_switch, 0)
2438 PORT_CONFSETTING( 0x001, "Practice" )
2439 PORT_CONFSETTING( 0x100, "Pro 1" ) // -> difficulty_switch
2440 PORT_CONFSETTING( 0x000, "Pro 2" )
2441 PORT_CONFNAME( 0x02, 0x00, DEF_STR( Players ) )
2442 PORT_CONFSETTING( 0x00, "1" )
2443 PORT_CONFSETTING( 0x02, "2" )
2444 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Q) PORT_NAME("P2 Button 1")
2445 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_A) PORT_NAME("P2 Button 4")
2446 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_W) PORT_NAME("P2 Button 2")
2447 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_S) PORT_NAME("P2 Button 5")
2448 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_NAME("P2 Button 3")
2449 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_D) PORT_NAME("P2 Button 6")
2450 INPUT_PORTS_END
2451
2452 void tmtennis_state::tmtennis(machine_config &config)
2453 {
2454 /* basic machine hardware */
2455 NEC_D552(config, m_maincpu, 360000); // see set_clock
2456 m_maincpu->read_a().set(FUNC(tmtennis_state::input_r));
2457 m_maincpu->read_b().set(FUNC(tmtennis_state::input_r));
2458 m_maincpu->write_c().set(FUNC(tmtennis_state::plate_w));
2459 m_maincpu->write_d().set(FUNC(tmtennis_state::plate_w));
2460 m_maincpu->write_e().set(FUNC(tmtennis_state::port_e_w));
2461 m_maincpu->write_f().set(FUNC(tmtennis_state::plate_w));
2462 m_maincpu->write_g().set(FUNC(tmtennis_state::grid_w));
2463 m_maincpu->write_h().set(FUNC(tmtennis_state::grid_w));
2464 m_maincpu->write_i().set(FUNC(tmtennis_state::grid_w));
2465
2466 /* video hardware */
2467 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
2468 screen.set_refresh_hz(60);
2469 screen.set_size(1920, 417);
2470 screen.set_visarea_full();
2471
2472 PWM_DISPLAY(config, m_display).set_size(12, 12);
2473 config.set_default_layout(layout_tmtennis);
2474
2475 /* sound hardware */
2476 SPEAKER(config, "mono").front_center();
2477 SPEAKER_SOUND(config, m_speaker);
2478 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
2479 }
2480
2481 // roms
2482
2483 ROM_START( tmtennis )
2484 ROM_REGION( 0x0400, "maincpu", 0 )
2485 ROM_LOAD( "d552c-048", 0x0000, 0x0400, CRC(78702003) SHA1(4d427d4dbeed901770c682338867f58c7b54eee3) )
2486
2487 ROM_REGION( 204490, "screen", 0)
2488 ROM_LOAD( "tmtennis.svg", 0, 204490, CRC(ed0086e9) SHA1(26a5b2f0a9cd70401187146e1495aee80020658b) )
2489 ROM_END
2490
2491
2492
2493
2494
2495 /***************************************************************************
2496
2497 Tomy(tronic) Pac-Man (manufactured in Japan)
2498 * PCB label TN-08 2E108E01
2499 * NEC uCOM-43 MCU, label D553C 160
2500 * cyan/red/green VFD display NEC FIP8AM18T no. 2-21
2501 * bright yellow round casing
2502
2503 known releases:
2504 - Japan: Puck Man
2505 - USA: Pac Man
2506 - UK: Puckman (Tomy), and also published by Grandstand as Munchman
2507 - Australia: Pac Man-1, published by Futuretronics
2508
2509 The game will start automatically after turning it on. This Pac Man refuses
2510 to eat dots with his butt, you can only eat them going right-to-left.
2511
2512 ***************************************************************************/
2513
2514 class tmpacman_state : public hh_ucom4_state
2515 {
2516 public:
tmpacman_state(const machine_config & mconfig,device_type type,const char * tag)2517 tmpacman_state(const machine_config &mconfig, device_type type, const char *tag) :
2518 hh_ucom4_state(mconfig, type, tag)
2519 { }
2520
2521 void update_display();
2522 void grid_w(offs_t offset, u8 data);
2523 void plate_w(offs_t offset, u8 data);
2524 void tmpacman(machine_config &config);
2525 };
2526
2527 // handlers
2528
update_display()2529 void tmpacman_state::update_display()
2530 {
2531 u8 grid = bitswap<8>(m_grid,0,1,2,3,4,5,6,7);
2532 u32 plate = bitswap<24>(m_plate,23,22,21,20,19,16,17,18,11,10,9,8,0,2,3,1,4,5,6,7,12,13,14,15) | 0x100;
2533 m_display->matrix(grid, plate);
2534 }
2535
grid_w(offs_t offset,u8 data)2536 void tmpacman_state::grid_w(offs_t offset, u8 data)
2537 {
2538 // C,D: vfd grid
2539 int shift = (offset - PORTC) * 4;
2540 m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
2541 update_display();
2542 }
2543
plate_w(offs_t offset,u8 data)2544 void tmpacman_state::plate_w(offs_t offset, u8 data)
2545 {
2546 // E1: speaker out
2547 if (offset == PORTE)
2548 m_speaker->level_w(data >> 1 & 1);
2549
2550 // E023,F,G,H,I: vfd plate
2551 int shift = (offset - PORTE) * 4;
2552 m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
2553 update_display();
2554 }
2555
2556 // config
2557
2558 static INPUT_PORTS_START( tmpacman )
2559 PORT_START("IN.0") // port A
2560 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_16WAY
2561 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_16WAY
2562 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_16WAY
2563 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_16WAY
2564
2565 PORT_START("IN.1") // port B
DEF_STR(Difficulty)2566 PORT_CONFNAME( 0x01, 0x00, DEF_STR( Difficulty ) )
2567 PORT_CONFSETTING( 0x00, "Amateur" )
2568 PORT_CONFSETTING( 0x01, "Professional" )
2569 PORT_BIT( 0x0e, IP_ACTIVE_HIGH, IPT_UNUSED )
2570 INPUT_PORTS_END
2571
2572 void tmpacman_state::tmpacman(machine_config &config)
2573 {
2574 /* basic machine hardware */
2575 NEC_D553(config, m_maincpu, 430_kHz_XTAL);
2576 m_maincpu->read_a().set_ioport("IN.0");
2577 m_maincpu->read_b().set_ioport("IN.1");
2578 m_maincpu->write_c().set(FUNC(tmpacman_state::grid_w));
2579 m_maincpu->write_d().set(FUNC(tmpacman_state::grid_w));
2580 m_maincpu->write_e().set(FUNC(tmpacman_state::plate_w));
2581 m_maincpu->write_f().set(FUNC(tmpacman_state::plate_w));
2582 m_maincpu->write_g().set(FUNC(tmpacman_state::plate_w));
2583 m_maincpu->write_h().set(FUNC(tmpacman_state::plate_w));
2584 m_maincpu->write_i().set(FUNC(tmpacman_state::plate_w));
2585
2586 /* video hardware */
2587 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
2588 screen.set_refresh_hz(60);
2589 screen.set_size(1920, 508);
2590 screen.set_visarea_full();
2591
2592 PWM_DISPLAY(config, m_display).set_size(8, 19);
2593
2594 /* sound hardware */
2595 SPEAKER(config, "mono").front_center();
2596 SPEAKER_SOUND(config, m_speaker);
2597 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
2598 }
2599
2600 // roms
2601
2602 ROM_START( tmpacman )
2603 ROM_REGION( 0x0800, "maincpu", 0 )
2604 ROM_LOAD( "d553c-160", 0x0000, 0x0800, CRC(b21a8af7) SHA1(e3122be1873ce76a4067386bf250802776f0c2f9) )
2605
2606 ROM_REGION( 230216, "screen", 0)
2607 ROM_LOAD( "tmpacman.svg", 0, 230216, CRC(2ab5c0f1) SHA1(b2b6482b03c28515dc76fd3d6034c8b7e6bf6efc) )
2608 ROM_END
2609
2610
2611
2612
2613
2614 /***************************************************************************
2615
2616 Tomy(tronic) Scramble (manufactured in Japan)
2617 * PCB label TN-10 2E114E01
2618 * NEC uCOM-43 MCU, label D553C 192
2619 * cyan/red/green VFD display NEC FIP10CM20T no. 2-41
2620
2621 known releases:
2622 - World: Scramble
2623 - USA: Scramble, published by Tandy
2624 - UK: Astro Blaster, published by Hales (Epoch Astro Command was named Scramble)
2625 - Germany: Rambler
2626
2627 ***************************************************************************/
2628
2629 class tmscramb_state : public hh_ucom4_state
2630 {
2631 public:
tmscramb_state(const machine_config & mconfig,device_type type,const char * tag)2632 tmscramb_state(const machine_config &mconfig, device_type type, const char *tag) :
2633 hh_ucom4_state(mconfig, type, tag)
2634 { }
2635
2636 void update_display();
2637 void grid_w(offs_t offset, u8 data);
2638 void plate_w(offs_t offset, u8 data);
2639 void tmscramb(machine_config &config);
2640 };
2641
2642 // handlers
2643
update_display()2644 void tmscramb_state::update_display()
2645 {
2646 u32 plate = bitswap<24>(m_plate,23,22,21,20,19,18,17,3,15,2,14,1,13,16,0,12,8,4,9,5,10,6,11,7) | 0x400;
2647 m_display->matrix(m_grid, plate);
2648 }
2649
grid_w(offs_t offset,u8 data)2650 void tmscramb_state::grid_w(offs_t offset, u8 data)
2651 {
2652 // I2: speaker out
2653 if (offset == PORTI)
2654 m_speaker->level_w(data >> 2 & 1);
2655
2656 // C,D,I01: vfd grid
2657 int shift = (offset == PORTI) ? 8 : (offset - PORTC) * 4;
2658 m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
2659 update_display();
2660 }
2661
plate_w(offs_t offset,u8 data)2662 void tmscramb_state::plate_w(offs_t offset, u8 data)
2663 {
2664 // E,F,G,H: vfd plate
2665 int shift = (offset - PORTE) * 4;
2666 m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
2667 update_display();
2668 }
2669
2670 // config
2671
2672 static INPUT_PORTS_START( tmscramb )
2673 PORT_START("IN.0") // port A
DEF_STR(Difficulty)2674 PORT_CONFNAME( 0x01, 0x00, DEF_STR( Difficulty ) )
2675 PORT_CONFSETTING( 0x00, "Amateur" )
2676 PORT_CONFSETTING( 0x01, "Professional" )
2677 PORT_BIT( 0x0e, IP_ACTIVE_HIGH, IPT_BUTTON1 )
2678
2679 PORT_START("IN.1") // port B
2680 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_2WAY
2681 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_2WAY
2682 PORT_BIT( 0x0c, IP_ACTIVE_HIGH, IPT_UNUSED )
2683 INPUT_PORTS_END
2684
2685 void tmscramb_state::tmscramb(machine_config &config)
2686 {
2687 /* basic machine hardware */
2688 NEC_D553(config, m_maincpu, 400_kHz_XTAL);
2689 m_maincpu->read_a().set_ioport("IN.0");
2690 m_maincpu->read_b().set_ioport("IN.1");
2691 m_maincpu->write_c().set(FUNC(tmscramb_state::grid_w));
2692 m_maincpu->write_d().set(FUNC(tmscramb_state::grid_w));
2693 m_maincpu->write_e().set(FUNC(tmscramb_state::plate_w));
2694 m_maincpu->write_f().set(FUNC(tmscramb_state::plate_w));
2695 m_maincpu->write_g().set(FUNC(tmscramb_state::plate_w));
2696 m_maincpu->write_h().set(FUNC(tmscramb_state::plate_w));
2697 m_maincpu->write_i().set(FUNC(tmscramb_state::grid_w));
2698
2699 /* video hardware */
2700 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
2701 screen.set_refresh_hz(60);
2702 screen.set_size(1920, 556);
2703 screen.set_visarea_full();
2704
2705 PWM_DISPLAY(config, m_display).set_size(10, 17);
2706
2707 /* sound hardware */
2708 SPEAKER(config, "mono").front_center();
2709 SPEAKER_SOUND(config, m_speaker);
2710 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
2711 }
2712
2713 // roms
2714
2715 ROM_START( tmscramb )
2716 ROM_REGION( 0x0800, "maincpu", 0 )
2717 ROM_LOAD( "d553c-192", 0x0000, 0x0800, CRC(00fcc501) SHA1(a7771e934bf8268c83f38c7ec0acc668836e0939) )
2718
2719 ROM_REGION( 235601, "screen", 0)
2720 ROM_LOAD( "tmscramb.svg", 0, 235601, CRC(9e76219a) SHA1(275273b98d378c9313dd73a3b86cc661a824b7af) )
2721 ROM_END
2722
2723
2724
2725
2726
2727 /***************************************************************************
2728
2729 Tomy(tronic) Caveman (manufactured in Japan)
2730 * PCB label TN-12 2E114E03
2731 * NEC uCOM-43 MCU, label D553C 209
2732 * cyan/red/green VFD display NEC FIP8AM20T no. 2-42
2733
2734 known releases:
2735 - World: Caveman
2736 - USA: Caveman, published by Tandy
2737 - UK: Cave Man - Jr. Caveman vs Dinosaur, published by Grandstand
2738
2739 ***************************************************************************/
2740
2741 class tcaveman_state : public hh_ucom4_state
2742 {
2743 public:
tcaveman_state(const machine_config & mconfig,device_type type,const char * tag)2744 tcaveman_state(const machine_config &mconfig, device_type type, const char *tag) :
2745 hh_ucom4_state(mconfig, type, tag)
2746 { }
2747
2748 void update_display();
2749 void grid_w(offs_t offset, u8 data);
2750 void plate_w(offs_t offset, u8 data);
2751 void tcaveman(machine_config &config);
2752 };
2753
2754 // handlers
2755
update_display()2756 void tcaveman_state::update_display()
2757 {
2758 u8 grid = bitswap<8>(m_grid,0,1,2,3,4,5,6,7);
2759 u32 plate = bitswap<24>(m_plate,23,22,21,20,19,10,11,5,6,7,8,0,9,2,18,17,16,3,15,14,13,12,4,1) | 0x40;
2760 m_display->matrix(grid, plate);
2761 }
2762
grid_w(offs_t offset,u8 data)2763 void tcaveman_state::grid_w(offs_t offset, u8 data)
2764 {
2765 // C,D: vfd grid
2766 int shift = (offset - PORTC) * 4;
2767 m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
2768 update_display();
2769 }
2770
plate_w(offs_t offset,u8 data)2771 void tcaveman_state::plate_w(offs_t offset, u8 data)
2772 {
2773 // E3: speaker out
2774 if (offset == PORTE)
2775 m_speaker->level_w(data >> 3 & 1);
2776
2777 // E012,F,G,H,I: vfd plate
2778 int shift = (offset - PORTE) * 4;
2779 m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
2780 update_display();
2781 }
2782
2783 // config
2784
2785 static INPUT_PORTS_START( tcaveman )
2786 PORT_START("IN.0") // port A
2787 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
2788 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
2789 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 )
DEF_STR(Difficulty)2790 PORT_CONFNAME( 0x08, 0x00, DEF_STR( Difficulty ) )
2791 PORT_CONFSETTING( 0x00, "Amateur" )
2792 PORT_CONFSETTING( 0x08, "Professional" )
2793 INPUT_PORTS_END
2794
2795 void tcaveman_state::tcaveman(machine_config &config)
2796 {
2797 /* basic machine hardware */
2798 NEC_D553(config, m_maincpu, 400_kHz_XTAL);
2799 m_maincpu->read_a().set_ioport("IN.0");
2800 m_maincpu->write_c().set(FUNC(tcaveman_state::grid_w));
2801 m_maincpu->write_d().set(FUNC(tcaveman_state::grid_w));
2802 m_maincpu->write_e().set(FUNC(tcaveman_state::plate_w));
2803 m_maincpu->write_f().set(FUNC(tcaveman_state::plate_w));
2804 m_maincpu->write_g().set(FUNC(tcaveman_state::plate_w));
2805 m_maincpu->write_h().set(FUNC(tcaveman_state::plate_w));
2806 m_maincpu->write_i().set(FUNC(tcaveman_state::plate_w));
2807
2808 /* video hardware */
2809 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
2810 screen.set_refresh_hz(60);
2811 screen.set_size(1920, 559);
2812 screen.set_visarea_full();
2813
2814 PWM_DISPLAY(config, m_display).set_size(8, 19);
2815
2816 /* sound hardware */
2817 SPEAKER(config, "mono").front_center();
2818 SPEAKER_SOUND(config, m_speaker);
2819 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
2820 }
2821
2822 // roms
2823
2824 ROM_START( tcaveman )
2825 ROM_REGION( 0x0800, "maincpu", 0 )
2826 ROM_LOAD( "d553c-209", 0x0000, 0x0800, CRC(d230d4b7) SHA1(2fb12b60410f5567c5e3afab7b8f5aa855d283be) )
2827
2828 ROM_REGION( 306952, "screen", 0)
2829 ROM_LOAD( "tcaveman.svg", 0, 306952, CRC(a0588b14) SHA1(f67edf579963fc19bc7f9d268329cbc0230712d8) )
2830 ROM_END
2831
2832
2833
2834
2835
2836 /***************************************************************************
2837
2838 Tomy Alien Chase (manufactured in Japan)
2839 * PCB label TN-16 2E121B01
2840 * NEC uCOM-43 MCU, label D553C 258
2841 * red/green VFD display NEC FIP9AM24T, with color overlay, 2-sided*
2842
2843 *Player one views the VFD from the front (grid+filament side) while the
2844 opposite player views it from the back side (through the conductive traces),
2845 basically a mirror-image.
2846
2847 To start the game, simply press [UP]. Hold a joystick direction to move around.
2848
2849 ***************************************************************************/
2850
2851 class alnchase_state : public hh_ucom4_state
2852 {
2853 public:
alnchase_state(const machine_config & mconfig,device_type type,const char * tag)2854 alnchase_state(const machine_config &mconfig, device_type type, const char *tag) :
2855 hh_ucom4_state(mconfig, type, tag)
2856 { }
2857
2858 void output_w(offs_t offset, u8 data);
2859 u8 input_r();
2860 void alnchase(machine_config &config);
2861 };
2862
2863 // handlers
2864
output_w(offs_t offset,u8 data)2865 void alnchase_state::output_w(offs_t offset, u8 data)
2866 {
2867 if (offset <= PORTE)
2868 {
2869 // C,D,E0: vfd grid
2870 int shift = (offset - PORTC) * 4;
2871 m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
2872
2873 // C0(grid 0): input enable PL1
2874 // D0(grid 4): input enable PL2
2875 m_inp_mux = (m_grid & 1) | (m_grid >> 3 & 2);
2876
2877 // E1: speaker out
2878 if (offset == PORTE)
2879 m_speaker->level_w(data >> 1 & 1);
2880 }
2881
2882 if (offset >= PORTE)
2883 {
2884 // E23,F,G,H,I: vfd plate
2885 int shift = (offset - PORTE) * 4;
2886 m_plate = ((m_plate << 2 & ~(0xf << shift)) | (data << shift)) >> 2;
2887 }
2888
2889 m_display->matrix(m_grid, m_plate);
2890 }
2891
input_r()2892 u8 alnchase_state::input_r()
2893 {
2894 // A: multiplexed buttons
2895 return read_inputs(2);
2896 }
2897
2898 // config
2899
2900 /* physical button layout and labels is like this:
2901
2902 POWER SOUND LEVEL PLAYER
2903 ON ON PRO TWO START
2904 o o | |
2905 | | | | [joystick]
2906 | | o o
2907 OFF OFF AMA ONE GAME 0,1,2,3
2908
2909 1 PLAYER SIDE
2910
2911 other player side only has a joystick
2912 */
2913
2914 static INPUT_PORTS_START( alnchase )
2915 PORT_START("IN.0") // C0 port A
2916 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
2917 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
2918 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
2919 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
2920
2921 PORT_START("IN.1") // D0 port A
2922 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) // on non-mirrored view, swap P2 left/right
2923 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) // "
2924 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
2925 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
2926
2927 PORT_START("IN.2") // port B
DEF_STR(Players)2928 PORT_CONFNAME( 0x01, 0x01, DEF_STR( Players ) )
2929 PORT_CONFSETTING( 0x01, "1" )
2930 PORT_CONFSETTING( 0x00, "2" )
2931 PORT_CONFNAME( 0x02, 0x00, DEF_STR( Difficulty ) )
2932 PORT_CONFSETTING( 0x00, "Amateur" )
2933 PORT_CONFSETTING( 0x02, "Professional" )
2934 PORT_BIT( 0x0c, IP_ACTIVE_HIGH, IPT_UNUSED )
2935 INPUT_PORTS_END
2936
2937 void alnchase_state::alnchase(machine_config &config)
2938 {
2939 /* basic machine hardware */
2940 NEC_D553(config, m_maincpu, 400_kHz_XTAL);
2941 m_maincpu->read_a().set(FUNC(alnchase_state::input_r));
2942 m_maincpu->read_b().set_ioport("IN.2");
2943 m_maincpu->write_c().set(FUNC(alnchase_state::output_w));
2944 m_maincpu->write_d().set(FUNC(alnchase_state::output_w));
2945 m_maincpu->write_e().set(FUNC(alnchase_state::output_w));
2946 m_maincpu->write_f().set(FUNC(alnchase_state::output_w));
2947 m_maincpu->write_g().set(FUNC(alnchase_state::output_w));
2948 m_maincpu->write_h().set(FUNC(alnchase_state::output_w));
2949 m_maincpu->write_i().set(FUNC(alnchase_state::output_w));
2950
2951 /* video hardware */
2952 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
2953 screen.set_refresh_hz(60);
2954 screen.set_size(365, 1080);
2955 screen.set_visarea_full();
2956
2957 PWM_DISPLAY(config, m_display).set_size(9, 17);
2958
2959 /* sound hardware */
2960 SPEAKER(config, "mono").front_center();
2961 SPEAKER_SOUND(config, m_speaker);
2962 m_speaker->add_route(ALL_OUTPUTS, "mono", 0.25);
2963 }
2964
2965 // roms
2966
2967 ROM_START( alnchase )
2968 ROM_REGION( 0x0800, "maincpu", 0 )
2969 ROM_LOAD( "d553c-258", 0x0000, 0x0800, CRC(c5284ff5) SHA1(6a20aaacc9748f0e0335958f3cea482e36153704) )
2970
2971 ROM_REGION( 576864, "screen", 0)
2972 ROM_LOAD( "alnchase.svg", 0, 576864, CRC(fe7c7078) SHA1(0d201eeaeb291ded14c0759d1d3d5b2491cf0792) )
2973 ROM_END
2974
2975
2976
2977 } // anonymous namespace
2978
2979 /***************************************************************************
2980
2981 Game driver(s)
2982
2983 ***************************************************************************/
2984
2985 // YEAR NAME PARENT CMP MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS
2986 CONS( 1979, ufombs, 0, 0, ufombs, ufombs, ufombs_state, empty_init, "Bambino", "UFO Master-Blaster Station", MACHINE_SUPPORTS_SAVE )
2987 CONS( 1979, ssfball, 0, 0, ssfball, ssfball, ssfball_state, empty_init, "Bambino", "Superstar Football (Bambino)", MACHINE_SUPPORTS_SAVE )
2988 CONS( 1982, bmcfball, ssfball, 0, ssfball, ssfball, ssfball_state, empty_init, "Bambino", "Classic Football (Bambino)", MACHINE_SUPPORTS_SAVE )
2989 CONS( 1979, bmsoccer, 0, 0, bmsoccer, bmsoccer, bmsoccer_state, empty_init, "Bambino", "Kick The Goal Soccer", MACHINE_SUPPORTS_SAVE )
2990 CONS( 1981, bmsafari, 0, 0, bmsafari, bmsafari, bmsafari_state, empty_init, "Bambino", "Safari (Bambino)", MACHINE_SUPPORTS_SAVE )
2991 CONS( 1980, splasfgt, 0, 0, splasfgt, splasfgt, splasfgt_state, empty_init, "Bambino", "Space Laser Fight", MACHINE_SUPPORTS_SAVE )
2992
2993 CONS( 1982, bcclimbr, 0, 0, bcclimbr, bcclimbr, bcclimbr_state, empty_init, "Bandai", "Crazy Climber (Bandai)", MACHINE_SUPPORTS_SAVE )
2994
2995 CONS( 1980, tactix, 0, 0, tactix, tactix, tactix_state, empty_init, "Castle Toy", "Tactix (Castle Toy)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
2996 CONS( 1980, ctntune, 0, 0, ctntune, ctntune, ctntune_state, empty_init, "Castle Toy", "Name That Tune (Castle Toy)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) // ***
2997
2998 CONS( 1980, invspace, 0, 0, invspace, invspace, invspace_state, empty_init, "Epoch", "Invader From Space", MACHINE_SUPPORTS_SAVE )
2999 CONS( 1980, efball, 0, 0, efball, efball, efball_state, empty_init, "Epoch", "Electronic Football (Epoch)", MACHINE_SUPPORTS_SAVE )
3000 CONS( 1981, galaxy2, 0, 0, galaxy2, galaxy2, galaxy2_state, empty_init, "Epoch", "Galaxy II (VFD Rev. D)", MACHINE_SUPPORTS_SAVE )
3001 CONS( 1981, galaxy2b, galaxy2, 0, galaxy2b, galaxy2, galaxy2_state, empty_init, "Epoch", "Galaxy II (VFD Rev. B)", MACHINE_SUPPORTS_SAVE )
3002 CONS( 1982, astrocmd, 0, 0, astrocmd, astrocmd, astrocmd_state, empty_init, "Epoch", "Astro Command", MACHINE_SUPPORTS_SAVE )
3003 CONS( 1982, edracula, 0, 0, edracula, edracula, edracula_state, empty_init, "Epoch", "Dracula (Epoch)", MACHINE_SUPPORTS_SAVE )
3004
3005 CONS( 1979, mcompgin, 0, 0, mcompgin, mcompgin, mcompgin_state, empty_init, "Mattel", "Computer Gin", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND_HW )
3006
3007 CONS( 1979, mvbfree, 0, 0, mvbfree, mvbfree, mvbfree_state, empty_init, "Mego", "Mini-Vid: Break Free", MACHINE_SUPPORTS_SAVE )
3008
3009 CONS( 1980, grobot9, 0, 0, grobot9, grobot9, grobot9_state, empty_init, "Takatoku Toys", "Game Robot 9", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) // some of the minigames: ***
3010
3011 CONS( 1980, tccombat, 0, 0, tccombat, tccombat, tccombat_state, empty_init, "Tomy", "Cosmic Combat", MACHINE_SUPPORTS_SAVE )
3012 CONS( 1980, tmtennis, 0, 0, tmtennis, tmtennis, tmtennis_state, empty_init, "Tomy", "Tennis (Tomy)", MACHINE_SUPPORTS_SAVE )
3013 CONS( 1982, tmpacman, 0, 0, tmpacman, tmpacman, tmpacman_state, empty_init, "Tomy", "Pac Man (Tomy)", MACHINE_SUPPORTS_SAVE )
3014 CONS( 1982, tmscramb, 0, 0, tmscramb, tmscramb, tmscramb_state, empty_init, "Tomy", "Scramble (Tomy)", MACHINE_SUPPORTS_SAVE )
3015 CONS( 1982, tcaveman, 0, 0, tcaveman, tcaveman, tcaveman_state, empty_init, "Tomy", "Caveman (Tomy)", MACHINE_SUPPORTS_SAVE )
3016 CONS( 1984, alnchase, 0, 0, alnchase, alnchase, alnchase_state, empty_init, "Tomy", "Alien Chase", MACHINE_SUPPORTS_SAVE )
3017
3018 // ***: As far as MAME is concerned, the game is emulated fine. But for it to be playable, it requires interaction
3019 // with other, unemulatable, things eg. game board/pieces, playing cards, pen & paper, etc.
3020