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