1 // license:BSD-3-Clause
2 // copyright-holders:hap
3 // thanks-to:Kevin Horton
4 /***************************************************************************
5 
6   Hitachi HMCS40 MCU tabletops/handhelds or other simple devices,
7   most of them are VFD electronic games/toys.
8 
9   known chips:
10 
11   serial  device   etc.
12 ----------------------------------------------------------------
13  @A07     HD38750  1979, Bambino Knock-Em Out Boxing (ET-06B)
14  @A08     HD38750  1979, Bambino Dribble Away Basketball (ET-05)
15  @A45     HD38750  1981, VTech Invaders
16  *A56     HD38750  1981, Actronics(Hanzawa) Twinvader (small brown version)
17  *A58     HD38750  1981, Actronics(Hanzawa) Challenge Racer/Ludotronic(Hanzawa) Grand Prix Turbo
18  *A62     HD38750  1982, Actronics(Hanzawa) Pack'n Maze
19  *A67     HD38750  1982, Romtec Pucki & Monsters (ET-803)
20 
21  @A04     HD38800  1980, Gakken Heiankyo Alien
22  *A20     HD38800  1981, Entex Super Space Invader 2
23  @A25     HD38800  1981, Coleco Alien Attack
24  @A27     HD38800  1981, Bandai Packri Monster
25  @A31     HD38800  1981, Entex Select-A-Game cartridge: Space Invader 2 -> sag.cpp - also used in 2nd version of Super Space Invader 2!
26   A37     HD38800  1981, Entex Select-A-Game cartridge: Baseball 4      -> "
27   A38     HD38800  1981, Entex Select-A-Game cartridge: Pinball         -> "
28  *A41     HD38800  1982, Gakken Puck Monster
29  *A42     HD38800  1981, Akai GX-77
30  *A51     HD38800  1981, Actronics(Hanzawa) Twinvader (larger white version)
31  @A70     HD38800  1982, Coleco Galaxian
32  @A73     HD38800  1982, Mattel Star Hawk (PT-317B)
33  @A77     HD38800  1982, Bandai Frisky Tom (PT-327A)
34  @A88     HD38800  1982, Tomy Tron (THN-02)
35  @B01     HD38800  1982, Gakken Crazy Kong
36  @B19     HD38800  1982, Bandai Zaxxon
37  @B23     HD38800  1982, Tomy Kingman (THF-01II)
38  *B24     HD38800  1982, Actronics(Hanzawa) Wanted G-Man
39  *B29     HD38800  1984, Tomy Portable 6000 Bombman
40  *B31     HD38800  1983, Romtec Frog Prince (ET-806)
41  *B35     HD38800  1983, Bandai Gundam vs Gelgoog Zaku
42  *B42     HD38800  1983, Bandai Kiteyo Parman
43  @B43     HD38800  1983, Bandai Dokodemo Dorayaki Doraemon (PT-412)
44  *B48     HD38800  1983, Bandai Go Go Dynaman
45  @B52     HD38800  1983, Bandai Ultraman Monster Battle (PT-424)
46 
47  @A09     HD38820  1980, Mattel World Championship Baseball
48  @A13     HD38820  1981, Entex Galaxian 2
49  @A23     HD38820  1981, Entex Pac Man 2
50  @A28     HD38820  1981, Coleco Pac-Man (ver 1)
51  @A29     HD38820  1981, Coleco Pac-Man (ver 2)
52  *A32     HD38820  198?, Gakken Super Cobra
53  *A38     HD38820  1982, Entex Crazy Climber
54  @A42     HD38820  1982, Entex Stargate
55  @A43     HD38820  1982, Entex Turtles
56  @A45     HD38820  1982, Coleco Donkey Kong
57  @A49     HD38820  1983, Bandai Zackman
58  @A61     HD38820  1983, Coleco Ms. Pac-Man
59  @A63     HD38820  1983, Bandai Pengo
60  @A65     HD38820  1983, Bandai Burger Time (PT-389)
61  @A69     HD38820  1983, Gakken Dig Dug
62  @A70     HD38820  1983, Parker Brothers Q*Bert
63  *A75     HD38820  1983, Bandai Toukon Juohmaru
64  @A85     HD38820  1984, Bandai Machine Man (PT-438)
65  @A88     HD38820  1984, Bandai Pair Match (PT-460) (1/2)
66  @A89     HD38820  1984, Bandai Pair Match (PT-460) (2/2)
67 
68   A34     HD44801  1981, SciSys Mini Chess -> saitek_minichess.cpp
69   A50     HD44801  1981, CXG Sensor Computachess -> cxg_scptchess.cpp
70   A75     HD44801  1982, Alpha 8201 protection MCU -> machine/alpha8201.*
71  *A85     HD44801  1982, SciSys Travel Sensor / Travel Mate / Chesspartner 5000/6000
72  *A92     HD44801  1982, SciSys Play Bridge Computer
73   B35     HD44801  1983, Alpha 8302 protection MCU (see 8201)
74   B42     HD44801  1983, Alpha 8303 protection MCU (see 8201)
75  *B43     HD44801  1983, Alpha 8304 protection MCU (see 8201)
76   C57     HD44801  1985, Alpha 8505 protection MCU (see 8201)
77   C89     HD44801  1985, CXG Portachess (1985 version) -> cxg_scptchess.cpp
78 
79  *A86     HD44820  1983, Chess King Pocket Micro
80  *B63     HD44820  1985, CXG Pocket Chess (12 buttons)
81 
82  *A14     HD44840  1982, CXG Computachess II / Advanced Portachess
83 
84  *B55     HD44860  1987, Saitek Pro Bridge 100
85 
86  *A04     HD44868  1984, SciSys Rapier
87  *A07     HD44868  1984, Chess King Pocket Micro Deluxe
88  *A12     HD44868  1985, SciSys MK 10 / Pocket Chess
89  *A14     HD44868  1985, SciSys Kasparov Plus
90 
91   (* means undumped unless noted, @ denotes it's in this driver)
92 
93 
94   TODO:
95   - cgalaxn discrete sound (alien attacking sound effect)
96   - gckong glitchy jump on 1st level (rarely happens), caused by MCU stack overflow.
97     It can be tested by jumping up repeatedly at the start position under the ladder,
98     if the glitch happens there, you can jump onto the 2nd floor.
99   - epacman2 booting the game in demo mode, pacman should take the shortest route to
100     the upper-left power pill: mcu cycle/interrupt timing related
101   - kevtris's HMCS40 ROM dumps are incomplete, missing MCU factory test code from
102     the 2nd half of the ROM, none of the games access it though and it's impossible
103     to execute unless the chip is in testmode.
104   - Though very uncommon when compared to games with LED/lamp display, some
105     games may manipulate VFD plate brightness by strobing it longer/shorter,
106     eg. cgalaxn when a ship explodes.
107   - bzaxxon 3D effect is difficult to simulate
108   - improve/redo SVGs of: bzaxxon, bpengo, bbtime
109 
110 ***************************************************************************/
111 
112 #include "emu.h"
113 #include "cpu/hmcs40/hmcs40.h"
114 #include "cpu/cop400/cop400.h"
115 #include "video/pwm.h"
116 #include "machine/gen_latch.h"
117 #include "machine/timer.h"
118 #include "sound/spkrdev.h"
119 #include "screen.h"
120 #include "speaker.h"
121 
122 // internal artwork (complete)
123 #include "pairmtch.lh"
124 
125 // internal artwork (bezel overlay)
126 #include "bambball.lh"
127 #include "gckong.lh"
128 #include "mwcbaseb.lh"
129 #include "msthawk.lh"
130 #include "packmon.lh"
131 
132 //#include "hh_hmcs40_test.lh" // common test-layout - no svg artwork(yet), use external artwork
133 
134 
135 class hh_hmcs40_state : public driver_device
136 {
137 public:
hh_hmcs40_state(const machine_config & mconfig,device_type type,const char * tag)138 	hh_hmcs40_state(const machine_config &mconfig, device_type type, const char *tag) :
139 		driver_device(mconfig, type, tag),
140 		m_maincpu(*this, "maincpu"),
141 		m_display(*this, "display"),
142 		m_speaker(*this, "speaker"),
143 		m_inputs(*this, "IN.%u", 0)
144 	{ }
145 
146 	// devices
147 	required_device<hmcs40_cpu_device> m_maincpu;
148 	optional_device<pwm_display_device> m_display;
149 	optional_device<speaker_sound_device> m_speaker;
150 	optional_ioport_array<7> m_inputs; // max 7
151 
152 	// misc common
153 	u8 m_r[8];                      // MCU R ports write data (optional)
154 	u16 m_d;                        // MCU D port write data (optional)
155 	u8 m_int[2];                    // MCU INT0/1 pins state
156 	u16 m_inp_mux;                  // multiplexed inputs mask
157 
158 	u32 m_grid;                     // VFD current row data
159 	u64 m_plate;                    // VFD current column data
160 
161 	u16 read_inputs(int columns);
162 	void refresh_interrupts(void);
163 	void set_interrupt(int line, int state);
164 	DECLARE_INPUT_CHANGED_MEMBER(single_interrupt_line);
165 
166 protected:
167 	virtual void machine_start() override;
168 	virtual void machine_reset() override;
169 };
170 
171 
172 // machine start/reset
173 
machine_start()174 void hh_hmcs40_state::machine_start()
175 {
176 	// zerofill
177 	memset(m_r, 0, sizeof(m_r));
178 	memset(m_int, 0, sizeof(m_int));
179 	m_d = 0;
180 	m_inp_mux = 0;
181 	m_grid = 0;
182 	m_plate = 0;
183 
184 	// register for savestates
185 	save_item(NAME(m_r));
186 	save_item(NAME(m_int));
187 	save_item(NAME(m_d));
188 	save_item(NAME(m_inp_mux));
189 	save_item(NAME(m_grid));
190 	save_item(NAME(m_plate));
191 }
192 
machine_reset()193 void hh_hmcs40_state::machine_reset()
194 {
195 	refresh_interrupts();
196 }
197 
198 
199 
200 /***************************************************************************
201 
202   Helper Functions
203 
204 ***************************************************************************/
205 
206 // generic input handlers
207 
read_inputs(int columns)208 u16 hh_hmcs40_state::read_inputs(int columns)
209 {
210 	u16 ret = 0;
211 
212 	// read selected input rows
213 	for (int i = 0; i < columns; i++)
214 		if (m_inp_mux >> i & 1)
215 			ret |= m_inputs[i]->read();
216 
217 	return ret;
218 }
219 
220 
221 // interrupt handling
222 
refresh_interrupts()223 void hh_hmcs40_state::refresh_interrupts()
224 {
225 	for (int i = 0; i < 2; i++)
226 		m_maincpu->set_input_line(i, m_int[i] ? ASSERT_LINE : CLEAR_LINE);
227 }
228 
set_interrupt(int line,int state)229 void hh_hmcs40_state::set_interrupt(int line, int state)
230 {
231 	line = line ? 1 : 0;
232 	state = state ? 1 : 0;
233 
234 	if (state != m_int[line])
235 	{
236 		if (machine().phase() >= machine_phase::RESET)
237 			m_maincpu->set_input_line(line, state ? ASSERT_LINE : CLEAR_LINE);
238 		m_int[line] = state;
239 	}
240 }
241 
INPUT_CHANGED_MEMBER(hh_hmcs40_state::single_interrupt_line)242 INPUT_CHANGED_MEMBER(hh_hmcs40_state::single_interrupt_line)
243 {
244 	set_interrupt((int)param, newval);
245 }
246 
247 
248 
249 /***************************************************************************
250 
251   Minidrivers (subclass, I/O, Inputs, Machine Config, ROM Defs)
252 
253 ***************************************************************************/
254 
255 namespace {
256 
257 /***************************************************************************
258 
259   Bambino Dribble Away Basketball (manufactured in Japan)
260   * PCB label Emix Corp. ET-05
261   * Hitachi HD38750A08 MCU
262   * cyan VFD display Emix-106, with bezel overlay
263 
264 ***************************************************************************/
265 
266 class bambball_state : public hh_hmcs40_state
267 {
268 public:
bambball_state(const machine_config & mconfig,device_type type,const char * tag)269 	bambball_state(const machine_config &mconfig, device_type type, const char *tag) :
270 		hh_hmcs40_state(mconfig, type, tag)
271 	{ }
272 
273 	void plate_w(offs_t offset, u8 data);
274 	void grid_w(u16 data);
275 	u8 input_r();
276 	void bambball(machine_config &config);
277 };
278 
279 // handlers
280 
plate_w(offs_t offset,u8 data)281 void bambball_state::plate_w(offs_t offset, u8 data)
282 {
283 	// R1x-R3x(,D0-D3): vfd plate
284 	int shift = (offset - 1) * 4;
285 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
286 
287 	// update display
288 	u16 plate = bitswap<16>(m_plate,13,8,4,12,9,10,14,1,7,0,15,11,6,3,5,2);
289 	m_display->matrix(m_grid, plate);
290 }
291 
grid_w(u16 data)292 void bambball_state::grid_w(u16 data)
293 {
294 	// D4: speaker out
295 	m_speaker->level_w(data >> 4 & 1);
296 
297 	// D7-D10: input mux
298 	m_inp_mux = data >> 7 & 0xf;
299 
300 	// D7-D15: vfd grid
301 	m_grid = data >> 7 & 0x1ff;
302 
303 	// D0-D3: more plates (update display there)
304 	plate_w(3 + 1, data & 0xf);
305 }
306 
input_r()307 u8 bambball_state::input_r()
308 {
309 	// R0x: multiplexed inputs
310 	return read_inputs(4);
311 }
312 
313 // config
314 
315 static INPUT_PORTS_START( bambball )
316 	PORT_START("IN.0") // D7 port R0x
317 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Dribble Low")
318 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Dribble Medium")
319 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Dribble High")
320 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_NAME("Shoot")
321 
322 	PORT_START("IN.1") // D8 port R0x
323 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_16WAY
324 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_16WAY
325 	PORT_BIT( 0x0c, IP_ACTIVE_HIGH, IPT_UNUSED )
326 
327 	PORT_START("IN.2") // D9 port R0x
328 	PORT_BIT( 0x03, IP_ACTIVE_HIGH, IPT_UNUSED )
329 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START )
330 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("Display")
331 
332 	PORT_START("IN.3") // D10 port R0x
DEF_STR(Difficulty)333 	PORT_CONFNAME( 0x07, 0x01, DEF_STR( Difficulty ) )
334 	PORT_CONFSETTING(    0x01, "1" )
335 	PORT_CONFSETTING(    0x02, "2" )
336 	PORT_CONFSETTING(    0x04, "3" )
337 	PORT_CONFNAME( 0x08, 0x08, DEF_STR( Players ) )
338 	PORT_CONFSETTING(    0x08, "1" )
339 	PORT_CONFSETTING(    0x00, "2" )
340 INPUT_PORTS_END
341 
342 void bambball_state::bambball(machine_config &config)
343 {
344 	/* basic machine hardware */
345 	HD38750(config, m_maincpu, 400000); // approximation
346 	m_maincpu->read_r<0>().set(FUNC(bambball_state::input_r));
347 	m_maincpu->write_r<1>().set(FUNC(bambball_state::plate_w));
348 	m_maincpu->write_r<2>().set(FUNC(bambball_state::plate_w));
349 	m_maincpu->write_r<3>().set(FUNC(bambball_state::plate_w));
350 	m_maincpu->write_d().set(FUNC(bambball_state::grid_w));
351 
352 	/* video hardware */
353 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
354 	screen.set_refresh_hz(60);
355 	screen.set_size(1920, 478);
356 	screen.set_visarea_full();
357 
358 	PWM_DISPLAY(config, m_display).set_size(9, 16);
359 	config.set_default_layout(layout_bambball);
360 
361 	/* sound hardware */
362 	SPEAKER(config, "mono").front_center();
363 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
364 }
365 
366 // roms
367 
368 ROM_START( bambball )
369 	ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASE00 )
370 	ROM_LOAD( "hd38750a08", 0x0000, 0x0800, CRC(907fef18) SHA1(73fe7ca7c6332268a3a9abc5ac88ada2991012fb) )
371 	ROM_CONTINUE(           0x0f00, 0x0080 )
372 
373 	ROM_REGION( 281988, "screen", 0)
374 	ROM_LOAD( "bambball.svg", 0, 281988, CRC(63019194) SHA1(cbfb5b051d8f57f6b4d698796030850b3631ed56) )
375 ROM_END
376 
377 
378 
379 
380 
381 /***************************************************************************
382 
383   Bambino Knock-Em Out Boxing
384   * PCB label Emix Corp. ET-06B
385   * Hitachi HD38750A07 MCU
386   * cyan VFD display Emix-103, with blue or green color overlay
387 
388 ***************************************************************************/
389 
390 class bmboxing_state : public hh_hmcs40_state
391 {
392 public:
bmboxing_state(const machine_config & mconfig,device_type type,const char * tag)393 	bmboxing_state(const machine_config &mconfig, device_type type, const char *tag) :
394 		hh_hmcs40_state(mconfig, type, tag)
395 	{ }
396 
397 	void update_display();
398 	void plate_w(offs_t offset, u8 data);
399 	void grid_w(u16 data);
400 	u8 input_r();
401 	void bmboxing(machine_config &config);
402 };
403 
404 // handlers
405 
update_display()406 void bmboxing_state::update_display()
407 {
408 	u16 grid = bitswap<16>(m_grid,15,14,13,12,11,10,9,0,1,2,3,4,5,6,7,8);
409 	u32 plate = bitswap<16>(m_plate,15,14,13,12,1,2,0,3,11,4,10,7,5,6,9,8);
410 	m_display->matrix(grid, plate);
411 }
412 
plate_w(offs_t offset,u8 data)413 void bmboxing_state::plate_w(offs_t offset, u8 data)
414 {
415 	// R1x-R3x: vfd plate
416 	int shift = (offset - 1) * 4;
417 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
418 	update_display();
419 }
420 
grid_w(u16 data)421 void bmboxing_state::grid_w(u16 data)
422 {
423 	// D13: speaker out
424 	m_speaker->level_w(data >> 13 & 1);
425 
426 	// D9-D12: input mux
427 	m_inp_mux = data >> 9 & 0xf;
428 
429 	// D4-D12: vfd grid
430 	m_grid = data >> 4 & 0x1ff;
431 	update_display();
432 }
433 
input_r()434 u8 bmboxing_state::input_r()
435 {
436 	// R0x: multiplexed inputs
437 	return read_inputs(4);
438 }
439 
440 // config
441 
442 /* physical button layout and labels is like this:
443 
444     * left = P2 side *                                       * right = P1 side *
445 
446     [ BACK ]  [ HIGH ]        (players sw)                   [ HIGH ]  [ BACK ]
447                               1<--->2         [START/
448     [NORMAL]  [MEDIUM]                         RESET]        [MEDIUM]  [NORMAL]
449                               1<---OFF--->2
450     [ DUCK ]  [ LOW  ]        (skill lvl sw)                 [ LOW  ]  [ DUCK ]
451 */
452 
453 static INPUT_PORTS_START( bmboxing )
454 	PORT_START("IN.0") // D9 port R0x
PORT_CODE(KEYCODE_U)455 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_U) PORT_NAME("P1 Punch High")
456 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_J) PORT_NAME("P1 Punch Medium")
457 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_M) PORT_NAME("P1 Punch Low")
458 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
459 
460 	PORT_START("IN.1") // D10 port R0x
461 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_K) PORT_NAME("P1 Position Normal")
462 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_I) PORT_NAME("P1 Position Back")
463 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_COMMA) PORT_NAME("P1 Position Ducking")
464 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
465 
466 	PORT_START("IN.2") // D11 port R0x
467 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_W) PORT_NAME("P2 Punch High")
468 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_S) PORT_NAME("P2 Punch Medium")
469 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_X) PORT_NAME("P2 Punch Low")
470 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
471 
472 	PORT_START("IN.3") // D12 port R0x
473 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_A) PORT_NAME("P2 Position Normal")
474 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Q) PORT_NAME("P2 Position Back")
475 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Z) PORT_NAME("P2 Position Ducking")
476 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
477 
478 	PORT_START("IN.4") // port D
479 	PORT_CONFNAME( 0x0001, 0x0000, DEF_STR( Players ) )
480 	PORT_CONFSETTING(      0x0000, "1" )
481 	PORT_CONFSETTING(      0x0001, "2" )
482 	PORT_CONFNAME( 0x0002, 0x0000, DEF_STR( Difficulty ) )
483 	PORT_CONFSETTING(      0x0000, "1" )
484 	PORT_CONFSETTING(      0x0002, "2" )
485 	PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_START )
486 	PORT_BIT( 0xfff8, IP_ACTIVE_HIGH, IPT_UNUSED )
487 INPUT_PORTS_END
488 
489 void bmboxing_state::bmboxing(machine_config &config)
490 {
491 	/* basic machine hardware */
492 	HD38750(config, m_maincpu, 400000); // approximation
493 	m_maincpu->read_r<0>().set(FUNC(bmboxing_state::input_r));
494 	m_maincpu->write_r<1>().set(FUNC(bmboxing_state::plate_w));
495 	m_maincpu->write_r<2>().set(FUNC(bmboxing_state::plate_w));
496 	m_maincpu->write_r<3>().set(FUNC(bmboxing_state::plate_w));
497 	m_maincpu->write_d().set(FUNC(bmboxing_state::grid_w));
498 	m_maincpu->read_d().set_ioport("IN.4");
499 
500 	/* video hardware */
501 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
502 	screen.set_refresh_hz(60);
503 	screen.set_size(1920, 529);
504 	screen.set_visarea_full();
505 
506 	PWM_DISPLAY(config, m_display).set_size(9, 12);
507 
508 	/* sound hardware */
509 	SPEAKER(config, "mono").front_center();
510 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
511 }
512 
513 // roms
514 
515 ROM_START( bmboxing )
516 	ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASE00 )
517 	ROM_LOAD( "hd38750a07", 0x0000, 0x0800, CRC(7f33e259) SHA1(c5fcdd6bf060c96666354f09f0570c754f6ed4e0) )
518 	ROM_CONTINUE(           0x0f00, 0x0080 )
519 
520 	ROM_REGION( 257144, "screen", 0)
521 	ROM_LOAD( "bmboxing.svg", 0, 257144, CRC(dab81477) SHA1(28b0c844a311e2023ffa71d754e799059b7d050f) )
522 ROM_END
523 
524 
525 
526 
527 
528 /***************************************************************************
529 
530   Bandai Frisky Tom (manufactured in Japan)
531   * PCB label Kaken Corp., PT-327A
532   * Hitachi HD38800A77 MCU
533   * cyan/red/green VFD display Futaba DM-43ZK 2E
534 
535 ***************************************************************************/
536 
537 class bfriskyt_state : public hh_hmcs40_state
538 {
539 public:
bfriskyt_state(const machine_config & mconfig,device_type type,const char * tag)540 	bfriskyt_state(const machine_config &mconfig, device_type type, const char *tag) :
541 		hh_hmcs40_state(mconfig, type, tag)
542 	{ }
543 
544 	void update_display();
545 	void plate_w(offs_t offset, u8 data);
546 	void grid_w(u16 data);
547 
548 	void update_int1();
DECLARE_INPUT_CHANGED_MEMBER(input_changed)549 	DECLARE_INPUT_CHANGED_MEMBER(input_changed) { update_int1(); }
550 	void bfriskyt(machine_config &config);
551 };
552 
553 // handlers
554 
update_display()555 void bfriskyt_state::update_display()
556 {
557 	u16 grid = bitswap<16>(m_grid,15,14,13,12,11,10,9,8,0,1,2,3,4,5,6,7);
558 	u32 plate = bitswap<24>(m_plate,23,22,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21);
559 	m_display->matrix(grid, plate);
560 }
561 
plate_w(offs_t offset,u8 data)562 void bfriskyt_state::plate_w(offs_t offset, u8 data)
563 {
564 	// R0x-R3x: vfd plate
565 	int shift = offset * 4;
566 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
567 	update_display();
568 }
569 
grid_w(u16 data)570 void bfriskyt_state::grid_w(u16 data)
571 {
572 	// D6: speaker out
573 	m_speaker->level_w(data >> 6 & 1);
574 
575 	// D11-D15: input mux
576 	u8 inp_mux = data >> 11 & 0x1f;
577 	if (inp_mux != m_inp_mux)
578 	{
579 		m_inp_mux = inp_mux;
580 		update_int1();
581 	}
582 
583 	// D8-D15: vfd grid
584 	m_grid = data >> 8 & 0xff;
585 
586 	// D0-D5: more plates
587 	m_plate = (m_plate & 0x00ffff) | (data << 16 & 0x3f0000);
588 	update_display();
589 }
590 
update_int1()591 void bfriskyt_state::update_int1()
592 {
593 	// INT1 on multiplexed inputs
594 	set_interrupt(1, read_inputs(5));
595 }
596 
597 // config
598 
599 static INPUT_PORTS_START( bfriskyt )
600 	PORT_START("IN.0") // D11 INT1
601 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, bfriskyt_state, input_changed, 0)
602 
603 	PORT_START("IN.1") // D12 INT1
604 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, bfriskyt_state, input_changed, 0)
605 
606 	PORT_START("IN.2") // D13 INT1
607 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_CHANGED_MEMBER(DEVICE_SELF, bfriskyt_state, input_changed, 0)
608 
609 	PORT_START("IN.3") // D14 INT1
610 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_CHANGED_MEMBER(DEVICE_SELF, bfriskyt_state, input_changed, 0)
611 
612 	PORT_START("IN.4") // D15 INT1
613 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_CHANGED_MEMBER(DEVICE_SELF, bfriskyt_state, input_changed, 0)
614 
615 	PORT_START("IN.5") // INT0
616 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_hmcs40_state, single_interrupt_line, 0)
617 INPUT_PORTS_END
618 
bfriskyt(machine_config & config)619 void bfriskyt_state::bfriskyt(machine_config &config)
620 {
621 	/* basic machine hardware */
622 	HD38800(config, m_maincpu, 400000); // approximation
623 	m_maincpu->write_r<0>().set(FUNC(bfriskyt_state::plate_w));
624 	m_maincpu->write_r<1>().set(FUNC(bfriskyt_state::plate_w));
625 	m_maincpu->write_r<2>().set(FUNC(bfriskyt_state::plate_w));
626 	m_maincpu->write_r<3>().set(FUNC(bfriskyt_state::plate_w));
627 	m_maincpu->write_d().set(FUNC(bfriskyt_state::grid_w));
628 
629 	/* video hardware */
630 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
631 	screen.set_refresh_hz(60);
632 	screen.set_size(1920, 675);
633 	screen.set_visarea_full();
634 
635 	PWM_DISPLAY(config, m_display).set_size(8, 22);
636 
637 	/* sound hardware */
638 	SPEAKER(config, "mono").front_center();
639 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
640 }
641 
642 // roms
643 
644 ROM_START( bfriskyt )
645 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
646 	ROM_LOAD( "hd38800a77", 0x0000, 0x1000, CRC(a2445c4f) SHA1(0aaccfec90b66d27dae194d4462d88e654c41578) )
647 	ROM_CONTINUE(           0x1e80, 0x0100 )
648 
649 	ROM_REGION( 413577, "screen", 0)
650 	ROM_LOAD( "bfriskyt.svg", 0, 413577, CRC(17090264) SHA1(4512a8a91a459f2ddc258641c6d38c2f48f4160f) )
651 ROM_END
652 
653 
654 
655 
656 
657 /***************************************************************************
658 
659   Bandai Packri Monster (manufactured in Japan)
660   * PCB label DM-21ZA2
661   * Hitachi HD38800A27 MCU
662   * cyan/red/green VFD display Futaba DM-21ZK 2B, with bezel overlay
663 
664   known releases:
665   - Japan: FL Packri Monster
666   - USA(World?): Packri Monster
667   - USA/Canada: Hungry Monster, published by Tandy
668   - other: Gobble Man/Ogre Monster, published by Tandy
669 
670 ***************************************************************************/
671 
672 class packmon_state : public hh_hmcs40_state
673 {
674 public:
packmon_state(const machine_config & mconfig,device_type type,const char * tag)675 	packmon_state(const machine_config &mconfig, device_type type, const char *tag) :
676 		hh_hmcs40_state(mconfig, type, tag)
677 	{ }
678 
679 	void plate_w(offs_t offset, u8 data);
680 	void grid_w(u16 data);
681 	u16 input_r();
682 	void packmon(machine_config &config);
683 };
684 
685 // handlers
686 
plate_w(offs_t offset,u8 data)687 void packmon_state::plate_w(offs_t offset, u8 data)
688 {
689 	// R0x-R3x(,D0-D3): vfd plate
690 	int shift = offset * 4;
691 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
692 
693 	// update display
694 	u16 grid = bitswap<16>(m_grid,15,14,13,12,11,10,0,1,2,3,4,5,6,7,8,9);
695 	u32 plate = bitswap<24>(m_plate,23,22,21,20,0,1,2,3,4,5,6,19,18,17,16,15,14,13,12,11,10,9,8,7);
696 	m_display->matrix(grid, plate);
697 }
698 
grid_w(u16 data)699 void packmon_state::grid_w(u16 data)
700 {
701 	// D4: speaker out
702 	m_speaker->level_w(data >> 4 & 1);
703 
704 	// D11-D15: input mux
705 	m_inp_mux = data >> 11 & 0x1f;
706 
707 	// D6-D15: vfd grid
708 	m_grid = data >> 6 & 0x3ff;
709 
710 	// D0-D3: plate 9-12 (update display there)
711 	plate_w(4, data & 0xf);
712 }
713 
input_r()714 u16 packmon_state::input_r()
715 {
716 	// D5: multiplexed inputs
717 	return read_inputs(5) & 0x20;
718 }
719 
720 // config
721 
722 static INPUT_PORTS_START( packmon )
723 	PORT_START("IN.0") // D11 line D5
724 	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_START )
725 
726 	PORT_START("IN.1") // D12 line D5
727 	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
728 
729 	PORT_START("IN.2") // D13 line D5
730 	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
731 
732 	PORT_START("IN.3") // D14 line D5
733 	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
734 
735 	PORT_START("IN.4") // D15 line D5
736 	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
737 INPUT_PORTS_END
738 
packmon(machine_config & config)739 void packmon_state::packmon(machine_config &config)
740 {
741 	/* basic machine hardware */
742 	HD38800(config, m_maincpu, 400000); // approximation
743 	m_maincpu->write_r<0>().set(FUNC(packmon_state::plate_w));
744 	m_maincpu->write_r<1>().set(FUNC(packmon_state::plate_w));
745 	m_maincpu->write_r<2>().set(FUNC(packmon_state::plate_w));
746 	m_maincpu->write_r<3>().set(FUNC(packmon_state::plate_w));
747 	m_maincpu->write_d().set(FUNC(packmon_state::grid_w));
748 	m_maincpu->read_d().set(FUNC(packmon_state::input_r));
749 
750 	/* video hardware */
751 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
752 	screen.set_refresh_hz(60);
753 	screen.set_size(1920, 680);
754 	screen.set_visarea_full();
755 
756 	PWM_DISPLAY(config, m_display).set_size(10, 20);
757 	config.set_default_layout(layout_packmon);
758 
759 	/* sound hardware */
760 	SPEAKER(config, "mono").front_center();
761 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
762 }
763 
764 // roms
765 
766 ROM_START( packmon )
767 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
768 	ROM_LOAD( "hd38800a27", 0x0000, 0x1000, CRC(86e09e84) SHA1(ac7d3c43667d5720ca513f8ff51d146d9f2af124) )
769 	ROM_CONTINUE(           0x1e80, 0x0100 )
770 
771 	ROM_REGION( 224386, "screen", 0)
772 	ROM_LOAD( "packmon.svg", 0, 224386, CRC(b2ee5b6b) SHA1(e53b4d5a4118cc5fbec4656580c2aab76af8f8d7) )
773 ROM_END
774 
775 
776 
777 
778 
779 /***************************************************************************
780 
781   Bandai Zaxxon (manufactured in Japan, licensed from Sega)
782   * PCB label FL Zaxxon
783   * Hitachi HD38800B19 MCU
784   * cyan/red/blue VFD display NEC FIP11BM24T no. 4-8, half of it reflected
785     with a one-way mirror to give the illusion of a 3D display
786 
787 ***************************************************************************/
788 
789 class bzaxxon_state : public hh_hmcs40_state
790 {
791 public:
bzaxxon_state(const machine_config & mconfig,device_type type,const char * tag)792 	bzaxxon_state(const machine_config &mconfig, device_type type, const char *tag) :
793 		hh_hmcs40_state(mconfig, type, tag)
794 	{ }
795 
796 	void plate_w(offs_t offset, u8 data);
797 	void grid_w(u16 data);
798 
799 	void update_int1();
DECLARE_INPUT_CHANGED_MEMBER(input_changed)800 	DECLARE_INPUT_CHANGED_MEMBER(input_changed) { update_int1(); }
801 	void bzaxxon(machine_config &config);
802 };
803 
804 // handlers
805 
plate_w(offs_t offset,u8 data)806 void bzaxxon_state::plate_w(offs_t offset, u8 data)
807 {
808 	// R0x-R3x(,D0-D2): vfd plate
809 	int shift = offset * 4;
810 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
811 
812 	// update display
813 	u16 grid = bitswap<16>(m_grid,15,14,13,12,11,6,7,8,9,10,5,4,3,2,1,0);
814 	u32 plate = bitswap<24>(m_plate,23,22,21,20,5,7,0,1,2,3,4,6,19,16,17,18,15,14,13,12,10,8,9,11) | 0x800;
815 	m_display->matrix(grid, plate);
816 }
817 
grid_w(u16 data)818 void bzaxxon_state::grid_w(u16 data)
819 {
820 	// D4: speaker out
821 	m_speaker->level_w(data >> 4 & 1);
822 
823 	// D7-D10: input mux
824 	u8 inp_mux = data >> 7 & 0xf;
825 	if (inp_mux != m_inp_mux)
826 	{
827 		m_inp_mux = inp_mux;
828 		update_int1();
829 	}
830 
831 	// D5-D15: vfd grid
832 	m_grid = data >> 5 & 0x7ff;
833 
834 	// D0-D2: plate 7-9 (update display there)
835 	plate_w(4, data & 7);
836 }
837 
update_int1()838 void bzaxxon_state::update_int1()
839 {
840 	// INT1 on multiplexed inputs
841 	set_interrupt(1, read_inputs(4));
842 }
843 
844 // config
845 
846 static INPUT_PORTS_START( bzaxxon )
847 	PORT_START("IN.0") // D7 INT1
848 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_CHANGED_MEMBER(DEVICE_SELF, bzaxxon_state, input_changed, 0)
849 
850 	PORT_START("IN.1") // D8 INT1
851 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_CHANGED_MEMBER(DEVICE_SELF, bzaxxon_state, input_changed, 0)
852 
853 	PORT_START("IN.2") // D9 INT1
854 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_CHANGED_MEMBER(DEVICE_SELF, bzaxxon_state, input_changed, 0)
855 
856 	PORT_START("IN.3") // D10 INT1
857 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, bzaxxon_state, input_changed, 0)
858 
859 	PORT_START("IN.4") // INT0
860 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_hmcs40_state, single_interrupt_line, 0)
861 
862 	PORT_START("IN.5") // port D
863 	PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_SELECT )
864 	PORT_BIT( 0xfff7, IP_ACTIVE_HIGH, IPT_UNUSED )
865 INPUT_PORTS_END
866 
bzaxxon(machine_config & config)867 void bzaxxon_state::bzaxxon(machine_config &config)
868 {
869 	/* basic machine hardware */
870 	HD38800(config, m_maincpu, 450000); // approximation
871 	m_maincpu->write_r<0>().set(FUNC(bzaxxon_state::plate_w));
872 	m_maincpu->write_r<1>().set(FUNC(bzaxxon_state::plate_w));
873 	m_maincpu->write_r<2>().set(FUNC(bzaxxon_state::plate_w));
874 	m_maincpu->write_r<3>().set(FUNC(bzaxxon_state::plate_w));
875 	m_maincpu->write_d().set(FUNC(bzaxxon_state::grid_w));
876 	m_maincpu->read_d().set_ioport("IN.5");
877 
878 	/* video hardware */
879 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
880 	screen.set_refresh_hz(60);
881 	screen.set_size(613, 1080);
882 	screen.set_visarea_full();
883 
884 	PWM_DISPLAY(config, m_display).set_size(11, 20);
885 
886 	/* sound hardware */
887 	SPEAKER(config, "mono").front_center();
888 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
889 }
890 
891 // roms
892 
893 ROM_START( bzaxxon )
894 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
895 	ROM_LOAD( "hd38800b19", 0x0000, 0x1000, CRC(4fecb80d) SHA1(7adf079480ffd3825ad5ae1eaa4d892eecbcc42d) )
896 	ROM_CONTINUE(           0x1e80, 0x0100 )
897 
898 	ROM_REGION( 521080, "screen", 0)
899 	ROM_LOAD( "bzaxxon.svg", 0, 521080, BAD_DUMP CRC(f4fbb2de) SHA1(83db400e67d91ae4bfee3e8568ae9df94ebede19) )
900 ROM_END
901 
902 
903 
904 
905 
906 /***************************************************************************
907 
908   Bandai Zackman "The Pit, FL Exploration of Space" (manufactured in Japan)
909   * Hitachi QFP HD38820A49 MCU
910   * cyan/red/yellow VFD display Futaba DM-53Z 3E, with color overlay
911 
912 ***************************************************************************/
913 
914 class zackman_state : public hh_hmcs40_state
915 {
916 public:
zackman_state(const machine_config & mconfig,device_type type,const char * tag)917 	zackman_state(const machine_config &mconfig, device_type type, const char *tag) :
918 		hh_hmcs40_state(mconfig, type, tag)
919 	{ }
920 
921 	void plate_w(offs_t offset, u8 data);
922 	void grid_w(u16 data);
923 
924 	void update_int0();
DECLARE_INPUT_CHANGED_MEMBER(input_changed)925 	DECLARE_INPUT_CHANGED_MEMBER(input_changed) { update_int0(); }
926 	void zackman(machine_config &config);
927 };
928 
929 // handlers
930 
plate_w(offs_t offset,u8 data)931 void zackman_state::plate_w(offs_t offset, u8 data)
932 {
933 	// R0x-R6x(,D0,D1): vfd plate
934 	int shift = offset * 4;
935 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
936 
937 	// update display
938 	u8 grid = bitswap<8>(m_grid,0,1,2,3,4,5,6,7);
939 	u32 plate = bitswap<32>(m_plate,31,30,27,0,1,2,3,4,5,6,7,8,9,10,11,24,25,26,29,28,23,22,21,20,19,18,17,16,15,14,13,12);
940 	m_display->matrix(grid, plate);
941 }
942 
grid_w(u16 data)943 void zackman_state::grid_w(u16 data)
944 {
945 	// D2: speaker out
946 	m_speaker->level_w(data >> 2 & 1);
947 
948 	// D11-D14: input mux
949 	u8 inp_mux = data >> 11 & 0xf;
950 	if (inp_mux != m_inp_mux)
951 	{
952 		m_inp_mux = inp_mux;
953 		update_int0();
954 	}
955 
956 	// D8-D15: vfd grid
957 	m_grid = data >> 8 & 0xff;
958 
959 	// D0,D1: plate 12,13 (update display there)
960 	plate_w(7, data & 3);
961 }
962 
update_int0()963 void zackman_state::update_int0()
964 {
965 	// INT0 on multiplexed inputs
966 	set_interrupt(0, read_inputs(4));
967 }
968 
969 // config
970 
971 static INPUT_PORTS_START( zackman )
972 	PORT_START("IN.0") // D11 INT0
973 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_CHANGED_MEMBER(DEVICE_SELF, zackman_state, input_changed, 0)
974 
975 	PORT_START("IN.1") // D12 INT0
976 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_CHANGED_MEMBER(DEVICE_SELF, zackman_state, input_changed, 0)
977 
978 	PORT_START("IN.2") // D13 INT0
979 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, zackman_state, input_changed, 0)
980 
981 	PORT_START("IN.3") // D14 INT0
982 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_CHANGED_MEMBER(DEVICE_SELF, zackman_state, input_changed, 0)
983 
984 	PORT_START("IN.4") // INT1
985 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_hmcs40_state, single_interrupt_line, 1)
986 INPUT_PORTS_END
987 
zackman(machine_config & config)988 void zackman_state::zackman(machine_config &config)
989 {
990 	/* basic machine hardware */
991 	HD38820(config, m_maincpu, 400000); // approximation
992 	m_maincpu->write_r<0>().set(FUNC(zackman_state::plate_w));
993 	m_maincpu->write_r<1>().set(FUNC(zackman_state::plate_w));
994 	m_maincpu->write_r<2>().set(FUNC(zackman_state::plate_w));
995 	m_maincpu->write_r<3>().set(FUNC(zackman_state::plate_w));
996 	m_maincpu->write_r<4>().set(FUNC(zackman_state::plate_w));
997 	m_maincpu->write_r<5>().set(FUNC(zackman_state::plate_w));
998 	m_maincpu->write_r<6>().set(FUNC(zackman_state::plate_w));
999 	m_maincpu->write_d().set(FUNC(zackman_state::grid_w));
1000 
1001 	/* video hardware */
1002 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
1003 	screen.set_refresh_hz(60);
1004 	screen.set_size(487, 1080);
1005 	screen.set_visarea_full();
1006 
1007 	PWM_DISPLAY(config, m_display).set_size(8, 29);
1008 
1009 	/* sound hardware */
1010 	SPEAKER(config, "mono").front_center();
1011 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
1012 }
1013 
1014 // roms
1015 
1016 ROM_START( zackman )
1017 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
1018 	ROM_LOAD( "hd38820a49", 0x0000, 0x1000, CRC(b97f5ef6) SHA1(7fe20e8107361caf9ea657e504be1f8b10b8b03f) )
1019 	ROM_CONTINUE(           0x1e80, 0x0100 )
1020 
1021 	ROM_REGION( 910689, "screen", 0)
1022 	ROM_LOAD( "zackman.svg", 0, 910689, CRC(5f322820) SHA1(4210aff160e5de9a409aba8b915aaebff2a92647) )
1023 ROM_END
1024 
1025 
1026 
1027 
1028 
1029 /***************************************************************************
1030 
1031   Bandai Pengo (manufactured in Japan, licensed from Sega)
1032   * PCB label FL Pengo(in katakana)
1033   * Hitachi QFP HD38820A63 MCU
1034   * cyan/red/blue VFD display Futaba DM-68ZK 3D DM-63
1035 
1036 ***************************************************************************/
1037 
1038 class bpengo_state : public hh_hmcs40_state
1039 {
1040 public:
bpengo_state(const machine_config & mconfig,device_type type,const char * tag)1041 	bpengo_state(const machine_config &mconfig, device_type type, const char *tag) :
1042 		hh_hmcs40_state(mconfig, type, tag)
1043 	{ }
1044 
1045 	void update_display();
1046 	void plate_w(offs_t offset, u8 data);
1047 	void grid_w(u16 data);
1048 
1049 	void update_int0();
DECLARE_INPUT_CHANGED_MEMBER(input_changed)1050 	DECLARE_INPUT_CHANGED_MEMBER(input_changed) { update_int0(); }
1051 	void bpengo(machine_config &config);
1052 };
1053 
1054 // handlers
1055 
update_display()1056 void bpengo_state::update_display()
1057 {
1058 	u8 grid = bitswap<8>(m_grid,0,1,2,3,4,5,6,7);
1059 	u32 plate = bitswap<32>(m_plate,31,30,29,28,23,22,21,16,17,18,19,20,27,26,25,24,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
1060 	m_display->matrix(grid, plate);
1061 }
1062 
plate_w(offs_t offset,u8 data)1063 void bpengo_state::plate_w(offs_t offset, u8 data)
1064 {
1065 	// R0x-R6x: vfd plate
1066 	int shift = offset * 4;
1067 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
1068 	update_display();
1069 }
1070 
grid_w(u16 data)1071 void bpengo_state::grid_w(u16 data)
1072 {
1073 	// D10: speaker out
1074 	m_speaker->level_w(data >> 10 & 1);
1075 
1076 	// D12-D15: input mux
1077 	u8 inp_mux = data >> 12 & 0xf;
1078 	if (inp_mux != m_inp_mux)
1079 	{
1080 		m_inp_mux = inp_mux;
1081 		update_int0();
1082 	}
1083 
1084 	// D0-D7: vfd grid
1085 	m_grid = data & 0xff;
1086 	update_display();
1087 }
1088 
update_int0()1089 void bpengo_state::update_int0()
1090 {
1091 	// INT0 on multiplexed inputs
1092 	set_interrupt(0, read_inputs(4));
1093 }
1094 
1095 // config
1096 
1097 static INPUT_PORTS_START( bpengo )
1098 	PORT_START("IN.0") // D12 INT0
1099 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_CHANGED_MEMBER(DEVICE_SELF, bpengo_state, input_changed, 0)
1100 
1101 	PORT_START("IN.1") // D13 INT0
1102 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, bpengo_state, input_changed, 0)
1103 
1104 	PORT_START("IN.2") // D14 INT0
1105 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_CHANGED_MEMBER(DEVICE_SELF, bpengo_state, input_changed, 0)
1106 
1107 	PORT_START("IN.3") // D15 INT0
1108 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_CHANGED_MEMBER(DEVICE_SELF, bpengo_state, input_changed, 0)
1109 
1110 	PORT_START("IN.4") // INT1
1111 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_hmcs40_state, single_interrupt_line, 1)
1112 
1113 	PORT_START("IN.5") // port D
1114 	PORT_CONFNAME( 0x0800, 0x0000, "Factory Test" )
DEF_STR(Off)1115 	PORT_CONFSETTING(      0x0000, DEF_STR( Off ) )
1116 	PORT_CONFSETTING(      0x0800, DEF_STR( On ) )
1117 	PORT_BIT( 0xf7ff, IP_ACTIVE_HIGH, IPT_UNUSED )
1118 INPUT_PORTS_END
1119 
1120 void bpengo_state::bpengo(machine_config &config)
1121 {
1122 	/* basic machine hardware */
1123 	HD38820(config, m_maincpu, 400000); // approximation
1124 	m_maincpu->write_r<0>().set(FUNC(bpengo_state::plate_w));
1125 	m_maincpu->write_r<1>().set(FUNC(bpengo_state::plate_w));
1126 	m_maincpu->write_r<2>().set(FUNC(bpengo_state::plate_w));
1127 	m_maincpu->write_r<3>().set(FUNC(bpengo_state::plate_w));
1128 	m_maincpu->write_r<4>().set(FUNC(bpengo_state::plate_w));
1129 	m_maincpu->write_r<5>().set(FUNC(bpengo_state::plate_w));
1130 	m_maincpu->write_r<6>().set(FUNC(bpengo_state::plate_w));
1131 	m_maincpu->write_d().set(FUNC(bpengo_state::grid_w));
1132 	m_maincpu->read_d().set_ioport("IN.5");
1133 
1134 	/* video hardware */
1135 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
1136 	screen.set_refresh_hz(60);
1137 	screen.set_size(1920, 759);
1138 	screen.set_visarea_full();
1139 
1140 	PWM_DISPLAY(config, m_display).set_size(8, 25);
1141 
1142 	/* sound hardware */
1143 	SPEAKER(config, "mono").front_center();
1144 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
1145 }
1146 
1147 // roms
1148 
1149 ROM_START( bpengo )
1150 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
1151 	ROM_LOAD( "hd38820a63", 0x0000, 0x1000, CRC(ebd6bc64) SHA1(0a322c47b9553a2739a85908ce64b9650cf93d49) )
1152 	ROM_CONTINUE(           0x1e80, 0x0100 )
1153 
1154 	ROM_REGION( 744461, "screen", 0)
1155 	ROM_LOAD( "bpengo.svg", 0, 744461, BAD_DUMP CRC(2b9abaa5) SHA1(c70a6ac1fa757fdd3ababfe6e00573ef1410c1eb) )
1156 ROM_END
1157 
1158 
1159 
1160 
1161 
1162 /***************************************************************************
1163 
1164   Bandai Burger Time (manufactured in Japan, licensed from Data East)
1165   * PCB label Kaken Corp. PT-389 Burger Time
1166   * Hitachi QFP HD38820A65 MCU
1167   * cyan/red/green VFD display NEC FIP6AM25T no. 21-21
1168 
1169 ***************************************************************************/
1170 
1171 class bbtime_state : public hh_hmcs40_state
1172 {
1173 public:
bbtime_state(const machine_config & mconfig,device_type type,const char * tag)1174 	bbtime_state(const machine_config &mconfig, device_type type, const char *tag) :
1175 		hh_hmcs40_state(mconfig, type, tag)
1176 	{ }
1177 
1178 	void update_display();
1179 	void plate_w(offs_t offset, u8 data);
1180 	void grid_w(u16 data);
1181 
1182 	void update_int0();
DECLARE_INPUT_CHANGED_MEMBER(input_changed)1183 	DECLARE_INPUT_CHANGED_MEMBER(input_changed) { update_int0(); }
1184 	void bbtime(machine_config &config);
1185 };
1186 
1187 // handlers
1188 
update_display()1189 void bbtime_state::update_display()
1190 {
1191 	u8 grid = bitswap<8>(m_grid,7,6,0,1,2,3,4,5);
1192 	u32 plate = bitswap<32>(m_plate,31,30,29,28,25,24,26,27,22,23,15,14,12,11,10,8,7,6,4,1,5,9,13,3,2,16,17,18,19,20,0,21) | 0x1;
1193 	m_display->matrix(grid, plate);
1194 }
1195 
plate_w(offs_t offset,u8 data)1196 void bbtime_state::plate_w(offs_t offset, u8 data)
1197 {
1198 	// R0x-R6x: vfd plate
1199 	int shift = offset * 4;
1200 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
1201 	update_display();
1202 }
1203 
grid_w(u16 data)1204 void bbtime_state::grid_w(u16 data)
1205 {
1206 	// D3: speaker out
1207 	m_speaker->level_w(data >> 3 & 1);
1208 
1209 	// D10-D14: input mux
1210 	u8 inp_mux = data >> 10 & 0x1f;
1211 	if (inp_mux != m_inp_mux)
1212 	{
1213 		m_inp_mux = inp_mux;
1214 		update_int0();
1215 	}
1216 
1217 	// D4-D9: vfd grid
1218 	m_grid = data >> 4 & 0x3f;
1219 	update_display();
1220 }
1221 
update_int0()1222 void bbtime_state::update_int0()
1223 {
1224 	// INT0 on multiplexed inputs
1225 	set_interrupt(0, read_inputs(5));
1226 }
1227 
1228 // config
1229 
1230 static INPUT_PORTS_START( bbtime )
1231 	PORT_START("IN.0") // D10 INT0
1232 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_CHANGED_MEMBER(DEVICE_SELF, bbtime_state, input_changed, 0)
1233 
1234 	PORT_START("IN.1") // D11 INT0
1235 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_CHANGED_MEMBER(DEVICE_SELF, bbtime_state, input_changed, 0)
1236 
1237 	PORT_START("IN.2") // D12 INT0
1238 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, bbtime_state, input_changed, 0)
1239 
1240 	PORT_START("IN.3") // D13 INT0
1241 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_CHANGED_MEMBER(DEVICE_SELF, bbtime_state, input_changed, 0)
1242 
1243 	PORT_START("IN.4") // D14 INT0
1244 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, bbtime_state, input_changed, 0)
1245 
1246 	PORT_START("IN.5") // INT1
1247 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_hmcs40_state, single_interrupt_line, 1)
1248 INPUT_PORTS_END
1249 
bbtime(machine_config & config)1250 void bbtime_state::bbtime(machine_config &config)
1251 {
1252 	/* basic machine hardware */
1253 	HD38820(config, m_maincpu, 400000); // approximation
1254 	m_maincpu->write_r<0>().set(FUNC(bbtime_state::plate_w));
1255 	m_maincpu->write_r<1>().set(FUNC(bbtime_state::plate_w));
1256 	m_maincpu->write_r<2>().set(FUNC(bbtime_state::plate_w));
1257 	m_maincpu->write_r<3>().set(FUNC(bbtime_state::plate_w));
1258 	m_maincpu->write_r<4>().set(FUNC(bbtime_state::plate_w));
1259 	m_maincpu->write_r<5>().set(FUNC(bbtime_state::plate_w));
1260 	m_maincpu->write_r<6>().set(FUNC(bbtime_state::plate_w));
1261 	m_maincpu->write_d().set(FUNC(bbtime_state::grid_w));
1262 
1263 	/* video hardware */
1264 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
1265 	screen.set_refresh_hz(60);
1266 	screen.set_size(379, 1080);
1267 	screen.set_visarea_full();
1268 
1269 	PWM_DISPLAY(config, m_display).set_size(6, 28);
1270 
1271 	/* sound hardware */
1272 	SPEAKER(config, "mono").front_center();
1273 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
1274 }
1275 
1276 // roms
1277 
1278 ROM_START( bbtime )
1279 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
1280 	ROM_LOAD( "hd38820a65", 0x0000, 0x1000, CRC(33611faf) SHA1(29b6a30ed543688d31ec2aa18f7938fa4eef30b0) )
1281 	ROM_CONTINUE(           0x1e80, 0x0100 )
1282 
1283 	ROM_REGION( 461605, "screen", 0)
1284 	ROM_LOAD( "bbtime.svg", 0, 461605, BAD_DUMP CRC(5b335271) SHA1(46c45b711358e8397ae707668aecead9e341ab8a) )
1285 ROM_END
1286 
1287 
1288 
1289 
1290 
1291 /***************************************************************************
1292 
1293   Bandai Dokodemo Dorayaki Doraemon (FL LSI Game Push Up) (manufactured in Japan)
1294   * PCB label Kaken Corp PT-412 FL-Doreamon(in katakana)
1295   * Hitachi HD38800B43 MCU
1296   * cyan/red/blue VFD display Futaba DM-71
1297 
1298 ***************************************************************************/
1299 
1300 class bdoramon_state : public hh_hmcs40_state
1301 {
1302 public:
bdoramon_state(const machine_config & mconfig,device_type type,const char * tag)1303 	bdoramon_state(const machine_config &mconfig, device_type type, const char *tag) :
1304 		hh_hmcs40_state(mconfig, type, tag)
1305 	{ }
1306 
1307 	void plate_w(offs_t offset, u8 data);
1308 	void grid_w(u16 data);
1309 	void bdoramon(machine_config &config);
1310 };
1311 
1312 // handlers
1313 
plate_w(offs_t offset,u8 data)1314 void bdoramon_state::plate_w(offs_t offset, u8 data)
1315 {
1316 	// R0x-R3x(,D0-D3): vfd plate
1317 	int shift = offset * 4;
1318 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
1319 
1320 	// update display
1321 	u8 grid = bitswap<8>(m_grid,0,1,2,3,4,5,7,6);
1322 	u32 plate = bitswap<24>(m_plate,23,22,21,20,11,19,18,17,16,15,14,13,12,10,9,8,7,6,5,4,3,2,1,0);
1323 	m_display->matrix(grid, plate);
1324 }
1325 
grid_w(u16 data)1326 void bdoramon_state::grid_w(u16 data)
1327 {
1328 	// D7: speaker out
1329 	m_speaker->level_w(data >> 7 & 1);
1330 
1331 	// D8-D15: vfd grid
1332 	m_grid = data >> 8 & 0xff;
1333 
1334 	// D0-D3: plate 15-18 (update display there)
1335 	plate_w(4, data & 0xf);
1336 }
1337 
1338 // config
1339 
1340 static INPUT_PORTS_START( bdoramon )
1341 	PORT_START("IN.0") // INT0
1342 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_hmcs40_state, single_interrupt_line, 0)
1343 
1344 	PORT_START("IN.1") // INT1
1345 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_hmcs40_state, single_interrupt_line, 1)
1346 
1347 	PORT_START("IN.2") // port D
1348 	PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
1349 	PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
1350 	PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
1351 	PORT_BIT( 0xff8f, IP_ACTIVE_HIGH, IPT_UNUSED )
1352 
1353 	PORT_START("IN.3") // port R2x
1354 	PORT_BIT( 0x07, IP_ACTIVE_HIGH, IPT_UNUSED )
1355 	PORT_CONFNAME( 0x08, 0x00, "Factory Test" )
DEF_STR(Off)1356 	PORT_CONFSETTING(    0x00, DEF_STR( Off ) )
1357 	PORT_CONFSETTING(    0x08, DEF_STR( On ) )
1358 INPUT_PORTS_END
1359 
1360 void bdoramon_state::bdoramon(machine_config &config)
1361 {
1362 	/* basic machine hardware */
1363 	HD38800(config, m_maincpu, 400000); // approximation
1364 	m_maincpu->write_r<0>().set(FUNC(bdoramon_state::plate_w));
1365 	m_maincpu->write_r<1>().set(FUNC(bdoramon_state::plate_w));
1366 	m_maincpu->write_r<2>().set(FUNC(bdoramon_state::plate_w));
1367 	m_maincpu->read_r<2>().set_ioport("IN.3");
1368 	m_maincpu->write_r<3>().set(FUNC(bdoramon_state::plate_w));
1369 	m_maincpu->write_d().set(FUNC(bdoramon_state::grid_w));
1370 	m_maincpu->read_d().set_ioport("IN.2");
1371 
1372 	/* video hardware */
1373 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
1374 	screen.set_refresh_hz(60);
1375 	screen.set_size(1920, 668);
1376 	screen.set_visarea_full();
1377 
1378 	PWM_DISPLAY(config, m_display).set_size(8, 19);
1379 
1380 	/* sound hardware */
1381 	SPEAKER(config, "mono").front_center();
1382 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
1383 }
1384 
1385 // roms
1386 
1387 ROM_START( bdoramon )
1388 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
1389 	ROM_LOAD( "hd38800b43", 0x0000, 0x1000, CRC(9387ca42) SHA1(8937e208934b34bd9f49700aa50287dfc8bda76c) )
1390 	ROM_CONTINUE(           0x1e80, 0x0100 )
1391 
1392 	ROM_REGION( 624751, "screen", 0)
1393 	ROM_LOAD( "bdoramon.svg", 0, 624751, CRC(5dc4017c) SHA1(2091765de401969651b8eb22067572be72d12398) )
1394 ROM_END
1395 
1396 
1397 
1398 
1399 
1400 /***************************************************************************
1401 
1402   Bandai Ultraman Monster Battle (FL LSI Game Push Up) (manufactured in Japan)
1403   * PCB label Kaken Corp. PT-424 FL Ultra Man
1404   * Hitachi HD38800B52 MCU
1405   * cyan/red/blue VFD display NEC FIP8BM25T no. 21-8 2
1406 
1407 ***************************************************************************/
1408 
1409 class bultrman_state : public hh_hmcs40_state
1410 {
1411 public:
bultrman_state(const machine_config & mconfig,device_type type,const char * tag)1412 	bultrman_state(const machine_config &mconfig, device_type type, const char *tag) :
1413 		hh_hmcs40_state(mconfig, type, tag)
1414 	{ }
1415 
1416 	void plate_w(offs_t offset, u8 data);
1417 	void grid_w(u16 data);
1418 	void bultrman(machine_config &config);
1419 };
1420 
1421 // handlers
1422 
plate_w(offs_t offset,u8 data)1423 void bultrman_state::plate_w(offs_t offset, u8 data)
1424 {
1425 	// R0x-R3x(,D0-D2): vfd plate
1426 	int shift = offset * 4;
1427 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
1428 
1429 	// update display
1430 	u8 grid = bitswap<8>(m_grid,0,1,2,3,4,5,6,7);
1431 	u32 plate = bitswap<24>(m_plate,23,22,21,20,19,0,18,17,16,15,14,13,12,3,11,10,9,8,7,6,5,4,1,2);
1432 	m_display->matrix(grid, plate);
1433 }
1434 
grid_w(u16 data)1435 void bultrman_state::grid_w(u16 data)
1436 {
1437 	// D7: speaker out
1438 	m_speaker->level_w(data >> 7 & 1);
1439 
1440 	// D8-D15: vfd grid
1441 	m_grid = data >> 8 & 0xff;
1442 
1443 	// D0-D2: plate 15-17 (update display there)
1444 	plate_w(4, data & 7);
1445 }
1446 
1447 // config
1448 
1449 static INPUT_PORTS_START( bultrman )
1450 	PORT_START("IN.0") // INT0
1451 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_hmcs40_state, single_interrupt_line, 0)
1452 
1453 	PORT_START("IN.1") // port D
1454 	PORT_CONFNAME( 0x0010, 0x0000, "Factory Test" )
DEF_STR(Off)1455 	PORT_CONFSETTING(      0x0000, DEF_STR( Off ) )
1456 	PORT_CONFSETTING(      0x0010, DEF_STR( On ) )
1457 	PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
1458 	PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
1459 	PORT_BIT( 0xff8f, IP_ACTIVE_HIGH, IPT_UNUSED )
1460 INPUT_PORTS_END
1461 
1462 void bultrman_state::bultrman(machine_config &config)
1463 {
1464 	/* basic machine hardware */
1465 	HD38800(config, m_maincpu, 350000); // approximation
1466 	m_maincpu->write_r<0>().set(FUNC(bultrman_state::plate_w));
1467 	m_maincpu->write_r<1>().set(FUNC(bultrman_state::plate_w));
1468 	m_maincpu->write_r<2>().set(FUNC(bultrman_state::plate_w));
1469 	m_maincpu->write_r<3>().set(FUNC(bultrman_state::plate_w));
1470 	m_maincpu->write_d().set(FUNC(bultrman_state::grid_w));
1471 	m_maincpu->read_d().set_ioport("IN.1");
1472 
1473 	/* video hardware */
1474 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
1475 	screen.set_refresh_hz(60);
1476 	screen.set_size(1920, 673);
1477 	screen.set_visarea_full();
1478 
1479 	PWM_DISPLAY(config, m_display).set_size(8, 18);
1480 
1481 	/* sound hardware */
1482 	SPEAKER(config, "mono").front_center();
1483 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
1484 }
1485 
1486 // roms
1487 
1488 ROM_START( bultrman )
1489 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
1490 	ROM_LOAD( "hd38800b52", 0x0000, 0x1000, CRC(88d372dc) SHA1(f2ac3b89be8afe6fb65914ccebe1a56316b9472a) )
1491 	ROM_CONTINUE(           0x1e80, 0x0100 )
1492 
1493 	ROM_REGION( 405717, "screen", 0)
1494 	ROM_LOAD( "bultrman.svg", 0, 405717, CRC(13367971) SHA1(f294898712d1e146ff267bb1e3cfd059f972b248) )
1495 ROM_END
1496 
1497 
1498 
1499 
1500 
1501 /***************************************************************************
1502 
1503   Bandai Machine Man (FL Flat Type) (manufactured in Japan)
1504   * PCB label Kaken PT-438
1505   * Hitachi QFP HD38820A85 MCU
1506   * cyan/red/green VFD display NEC FIP5CM33T no. 4 21
1507 
1508 ***************************************************************************/
1509 
1510 class machiman_state : public hh_hmcs40_state
1511 {
1512 public:
machiman_state(const machine_config & mconfig,device_type type,const char * tag)1513 	machiman_state(const machine_config &mconfig, device_type type, const char *tag) :
1514 		hh_hmcs40_state(mconfig, type, tag)
1515 	{ }
1516 
1517 	void update_display();
1518 	void plate_w(offs_t offset, u8 data);
1519 	void grid_w(u16 data);
1520 	void machiman(machine_config &config);
1521 };
1522 
1523 // handlers
1524 
update_display()1525 void machiman_state::update_display()
1526 {
1527 	u32 plate = bitswap<24>(m_plate,23,22,21,20,19,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18);
1528 	m_display->matrix(m_grid, plate);
1529 }
1530 
plate_w(offs_t offset,u8 data)1531 void machiman_state::plate_w(offs_t offset, u8 data)
1532 {
1533 	// R0x-R3x,R6012: vfd plate
1534 	int shift = (offset == 6) ? 16 : offset * 4;
1535 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
1536 	update_display();
1537 }
1538 
grid_w(u16 data)1539 void machiman_state::grid_w(u16 data)
1540 {
1541 	// D13: speaker out
1542 	m_speaker->level_w(data >> 13 & 1);
1543 
1544 	// D0-D4: vfd grid
1545 	m_grid = data & 0x1f;
1546 	update_display();
1547 }
1548 
1549 // config
1550 
1551 static INPUT_PORTS_START( machiman )
1552 	PORT_START("IN.0") // INT0
1553 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_hmcs40_state, single_interrupt_line, 0)
1554 
1555 	PORT_START("IN.1") // port D
1556 	PORT_BIT( 0x3fff, IP_ACTIVE_HIGH, IPT_UNUSED )
1557 	PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY
1558 	PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY
1559 INPUT_PORTS_END
1560 
machiman(machine_config & config)1561 void machiman_state::machiman(machine_config &config)
1562 {
1563 	/* basic machine hardware */
1564 	HD38820(config, m_maincpu, 400000); // approximation
1565 	m_maincpu->write_r<0>().set(FUNC(machiman_state::plate_w));
1566 	m_maincpu->write_r<1>().set(FUNC(machiman_state::plate_w));
1567 	m_maincpu->write_r<2>().set(FUNC(machiman_state::plate_w));
1568 	m_maincpu->write_r<3>().set(FUNC(machiman_state::plate_w));
1569 	m_maincpu->write_r<6>().set(FUNC(machiman_state::plate_w));
1570 	m_maincpu->write_d().set(FUNC(machiman_state::grid_w));
1571 	m_maincpu->read_d().set_ioport("IN.1");
1572 
1573 	/* video hardware */
1574 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
1575 	screen.set_refresh_hz(60);
1576 	screen.set_size(1534, 1080);
1577 	screen.set_visarea_full();
1578 
1579 	PWM_DISPLAY(config, m_display).set_size(5, 19);
1580 
1581 	/* sound hardware */
1582 	SPEAKER(config, "mono").front_center();
1583 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
1584 }
1585 
1586 // roms
1587 
1588 ROM_START( machiman )
1589 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
1590 	ROM_LOAD( "hd38820a85", 0x0000, 0x1000, CRC(894b4954) SHA1(cab49638a326b031aa548301beb16f818759ef62) )
1591 	ROM_CONTINUE(           0x1e80, 0x0100 )
1592 
1593 	ROM_REGION( 374097, "screen", 0)
1594 	ROM_LOAD( "machiman.svg", 0, 374097, CRC(78af02ac) SHA1(1b4bbea3e46e1bf33149727d9725bc9b18652b9c) )
1595 ROM_END
1596 
1597 
1598 
1599 
1600 
1601 /***************************************************************************
1602 
1603   Bandai Pair Match (manufactured in Japan)
1604   * PCB label Kaken Corp. PT-460
1605   * Hitachi QFP HD38820A88 MCU(main), HD38820A89(audio)
1606   * cyan/red VFD display
1607 
1608   This is a memory game, the difference is instead of pictures, the player
1609   needs to match sound effects. It has an extra MCU for sound. The case is
1610   shaped like a glossy black pyramid. Star Trek fans will recognize it as
1611   a prop used in TNG Ten Forward.
1612 
1613 ***************************************************************************/
1614 
1615 class pairmtch_state : public hh_hmcs40_state
1616 {
1617 public:
pairmtch_state(const machine_config & mconfig,device_type type,const char * tag)1618 	pairmtch_state(const machine_config &mconfig, device_type type, const char *tag) :
1619 		hh_hmcs40_state(mconfig, type, tag),
1620 		m_audiocpu(*this, "audiocpu"),
1621 		m_soundlatch(*this, "soundlatch%u", 0)
1622 	{ }
1623 
1624 	required_device<hmcs40_cpu_device> m_audiocpu;
1625 	required_device_array<generic_latch_8_device, 2> m_soundlatch;
1626 
1627 	void update_display();
1628 	void plate_w(offs_t offset, u8 data);
1629 	void grid_w(u16 data);
1630 	u8 input_r();
1631 
1632 	void sound_w(u8 data);
1633 	void sound2_w(u8 data);
1634 	void speaker_w(u16 data);
1635 	void pairmtch(machine_config &config);
1636 };
1637 
1638 // handlers: maincpu side
1639 
update_display()1640 void pairmtch_state::update_display()
1641 {
1642 	m_display->matrix(m_grid, m_plate);
1643 }
1644 
plate_w(offs_t offset,u8 data)1645 void pairmtch_state::plate_w(offs_t offset, u8 data)
1646 {
1647 	// R2x,R3x,R6x: vfd plate
1648 	int shift = (offset == 6) ? 8 : (offset-2) * 4;
1649 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
1650 	update_display();
1651 }
1652 
grid_w(u16 data)1653 void pairmtch_state::grid_w(u16 data)
1654 {
1655 	// D7: sound reset (to audiocpu reset line)
1656 	m_audiocpu->set_input_line(INPUT_LINE_RESET, (data & 0x80) ? ASSERT_LINE : CLEAR_LINE);
1657 
1658 	// D9: sound start (to audiocpu INT0)
1659 	m_audiocpu->set_input_line(0, (data & 0x200) ? ASSERT_LINE : CLEAR_LINE);
1660 
1661 	// D10,D15: input mux
1662 	m_inp_mux = (data >> 10 & 1) | (data >> 14 & 2);
1663 
1664 	// D0-D5: vfd grid
1665 	m_grid = data & 0x3f;
1666 	update_display();
1667 }
1668 
input_r()1669 u8 pairmtch_state::input_r()
1670 {
1671 	// R4x: multiplexed inputs
1672 	return read_inputs(2);
1673 }
1674 
sound_w(u8 data)1675 void pairmtch_state::sound_w(u8 data)
1676 {
1677 	// R5x: soundlatch (to audiocpu R2x)
1678 	m_soundlatch[0]->write(bitswap<8>(data,7,6,5,4,0,1,2,3));
1679 }
1680 
1681 // handlers: audiocpu side
1682 
sound2_w(u8 data)1683 void pairmtch_state::sound2_w(u8 data)
1684 {
1685 	// R2x: soundlatch (to maincpu R5x)
1686 	m_soundlatch[1]->write(bitswap<8>(data,7,6,5,4,0,1,2,3));
1687 }
1688 
speaker_w(u16 data)1689 void pairmtch_state::speaker_w(u16 data)
1690 {
1691 	// D0: speaker out
1692 	m_speaker->level_w(data & 1);
1693 
1694 	// D1: sound ack (to maincpu INT0)
1695 	m_maincpu->set_input_line(0, (data & 2) ? ASSERT_LINE : CLEAR_LINE);
1696 }
1697 
1698 // config
1699 
1700 static INPUT_PORTS_START( pairmtch )
1701 	PORT_START("IN.0") // D10 port R4x
1702 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_COCKTAIL PORT_16WAY
1703 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_COCKTAIL PORT_16WAY
1704 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_COCKTAIL PORT_16WAY
1705 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_COCKTAIL PORT_16WAY
1706 
1707 	PORT_START("IN.1") // D15 port R4x
1708 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_16WAY
1709 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_16WAY
1710 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_16WAY
1711 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_16WAY
1712 
1713 	PORT_START("IN.2") // port D
1714 	PORT_CONFNAME( 0x0040, 0x0000, "Factory Test" )
DEF_STR(Off)1715 	PORT_CONFSETTING(      0x0000, DEF_STR( Off ) )
1716 	PORT_CONFSETTING(      0x0040, DEF_STR( On ) )
1717 	PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_COCKTAIL
1718 	PORT_CONFNAME( 0x0800, 0x0800, DEF_STR( Players ) )
1719 	PORT_CONFSETTING(      0x0800, "1" )
1720 	PORT_CONFSETTING(      0x0000, "2" )
1721 	PORT_CONFNAME( 0x3000, 0x2000, DEF_STR( Difficulty ) )
1722 	PORT_CONFSETTING(      0x2000, "1" )
1723 	PORT_CONFSETTING(      0x1000, "2" )
1724 	PORT_CONFSETTING(      0x0000, "3" )
1725 	PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_BUTTON1 )
1726 	PORT_BIT( 0x86bf, IP_ACTIVE_HIGH, IPT_UNUSED )
1727 INPUT_PORTS_END
1728 
1729 void pairmtch_state::pairmtch(machine_config &config)
1730 {
1731 	/* basic machine hardware */
1732 	HD38820(config, m_maincpu, 400000); // approximation
1733 	m_maincpu->write_r<2>().set(FUNC(pairmtch_state::plate_w));
1734 	m_maincpu->write_r<3>().set(FUNC(pairmtch_state::plate_w));
1735 	m_maincpu->read_r<4>().set(FUNC(pairmtch_state::input_r));
1736 	m_maincpu->write_r<5>().set(FUNC(pairmtch_state::sound_w));
1737 	m_maincpu->read_r<5>().set(m_soundlatch[1], FUNC(generic_latch_8_device::read));
1738 	m_maincpu->write_r<6>().set(FUNC(pairmtch_state::plate_w));
1739 	m_maincpu->write_d().set(FUNC(pairmtch_state::grid_w));
1740 	m_maincpu->read_d().set_ioport("IN.2");
1741 
1742 	HD38820(config, m_audiocpu, 400000); // approximation
1743 	m_audiocpu->write_r<2>().set(FUNC(pairmtch_state::sound2_w));
1744 	m_audiocpu->read_r<2>().set(m_soundlatch[0], FUNC(generic_latch_8_device::read));
1745 	m_audiocpu->write_d().set(FUNC(pairmtch_state::speaker_w));
1746 
1747 	config.set_perfect_quantum(m_maincpu);
1748 
1749 	/* video hardware */
1750 	PWM_DISPLAY(config, m_display).set_size(6, 12);
1751 	config.set_default_layout(layout_pairmtch);
1752 
1753 	/* sound hardware */
1754 	SPEAKER(config, "mono").front_center();
1755 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
1756 
1757 	GENERIC_LATCH_8(config, m_soundlatch[0]);
1758 	GENERIC_LATCH_8(config, m_soundlatch[1]);
1759 }
1760 
1761 // roms
1762 
1763 ROM_START( pairmtch )
1764 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
1765 	ROM_LOAD( "hd38820a88", 0x0000, 0x1000, CRC(ffa35730) SHA1(5a80b9025aaad2ac0ab0b1436a1355ae8cd3f868) )
1766 	ROM_CONTINUE(           0x1e80, 0x0100 )
1767 
1768 	ROM_REGION( 0x2000, "audiocpu", ROMREGION_ERASE00 )
1769 	ROM_LOAD( "hd38820a89", 0x0000, 0x1000, CRC(3533ec56) SHA1(556d69e78a0ee1bf766fce16ed58992d7272d57f) )
1770 	ROM_CONTINUE(           0x1e80, 0x0100 )
1771 ROM_END
1772 
1773 
1774 
1775 
1776 
1777 /***************************************************************************
1778 
1779   Coleco Alien Attack (manufactured in Taiwan)
1780   * Hitachi HD38800A25 MCU
1781   * cyan/red VFD display Futaba DM-19Z 1J
1782 
1783   It looks like Coleco took Gakken's Heiankyo Alien and turned it into a more
1784   action-oriented game.
1785 
1786 ***************************************************************************/
1787 
1788 class alnattck_state : public hh_hmcs40_state
1789 {
1790 public:
alnattck_state(const machine_config & mconfig,device_type type,const char * tag)1791 	alnattck_state(const machine_config &mconfig, device_type type, const char *tag) :
1792 		hh_hmcs40_state(mconfig, type, tag)
1793 	{ }
1794 
1795 	void plate_w(offs_t offset, u8 data);
1796 	void grid_w(u16 data);
1797 	u16 input_r();
1798 	void alnattck(machine_config &config);
1799 };
1800 
1801 // handlers
1802 
plate_w(offs_t offset,u8 data)1803 void alnattck_state::plate_w(offs_t offset, u8 data)
1804 {
1805 	// R0x-R3x(,D0-D3): vfd plate
1806 	int shift = offset * 4;
1807 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
1808 
1809 	// update display
1810 	u32 plate = bitswap<24>(m_plate,23,22,21,20,19,18,17,16,11,9,8,10,7,2,0,1,3,4,5,6,12,13,14,15);
1811 	m_display->matrix(m_grid, plate);
1812 }
1813 
grid_w(u16 data)1814 void alnattck_state::grid_w(u16 data)
1815 {
1816 	// D4: speaker out
1817 	m_speaker->level_w(data >> 4 & 1);
1818 
1819 	// D7-D13: input mux
1820 	m_inp_mux = data >> 7 & 0x7f;
1821 
1822 	// D6-D15: vfd grid
1823 	m_grid = data >> 6 & 0x3ff;
1824 
1825 	// D0-D3: plate 16-19 (update display there)
1826 	plate_w(4, data & 0xf);
1827 }
1828 
input_r()1829 u16 alnattck_state::input_r()
1830 {
1831 	// D5: multiplexed inputs
1832 	return read_inputs(7) & 0x20;
1833 }
1834 
1835 // config
1836 
1837 static INPUT_PORTS_START( alnattck )
1838 	PORT_START("IN.0") // D7 line D5
DEF_STR(Difficulty)1839 	PORT_CONFNAME( 0x20, 0x00, DEF_STR( Difficulty ) )
1840 	PORT_CONFSETTING(    0x00, "1" )
1841 	PORT_CONFSETTING(    0x20, "2" )
1842 
1843 	PORT_START("IN.1") // D8 line D5
1844 	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
1845 
1846 	PORT_START("IN.2") // D9 line D5
1847 	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
1848 
1849 	PORT_START("IN.3") // D10 line D5
1850 	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
1851 
1852 	PORT_START("IN.4") // D11 line D5
1853 	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
1854 
1855 	PORT_START("IN.5") // D12 line D5
1856 	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Move")
1857 
1858 	PORT_START("IN.6") // D13 line D5
1859 	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Fire")
1860 INPUT_PORTS_END
1861 
1862 void alnattck_state::alnattck(machine_config &config)
1863 {
1864 	/* basic machine hardware */
1865 	HD38800(config, m_maincpu, 400000); // approximation
1866 	m_maincpu->write_r<0>().set(FUNC(alnattck_state::plate_w));
1867 	m_maincpu->write_r<1>().set(FUNC(alnattck_state::plate_w));
1868 	m_maincpu->write_r<2>().set(FUNC(alnattck_state::plate_w));
1869 	m_maincpu->write_r<3>().set(FUNC(alnattck_state::plate_w));
1870 	m_maincpu->write_d().set(FUNC(alnattck_state::grid_w));
1871 	m_maincpu->read_d().set(FUNC(alnattck_state::input_r));
1872 
1873 	/* video hardware */
1874 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
1875 	screen.set_refresh_hz(60);
1876 	screen.set_size(1920, 700);
1877 	screen.set_visarea_full();
1878 
1879 	PWM_DISPLAY(config, m_display).set_size(10, 20);
1880 
1881 	/* sound hardware */
1882 	SPEAKER(config, "mono").front_center();
1883 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
1884 }
1885 
1886 // roms
1887 
1888 ROM_START( alnattck )
1889 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
1890 	ROM_LOAD( "hd38800a25", 0x0000, 0x1000, CRC(18b50869) SHA1(11e9d5f7b4ae818b077b0ee14a3b43190e20bff3) )
1891 	ROM_CONTINUE(           0x1e80, 0x0100 )
1892 
1893 	ROM_REGION( 564271, "screen", 0)
1894 	ROM_LOAD( "alnattck.svg", 0, 564271, CRC(5466d1d4) SHA1(3295272015969e58fddc53272769e1fc1bd4b355) )
1895 ROM_END
1896 
1897 
1898 
1899 
1900 
1901 /***************************************************************************
1902 
1903   Coleco Donkey Kong (manufactured in Taiwan, licensed from Nintendo)
1904   * PCB label Coleco Rev C 75790 DK
1905   * Hitachi QFP HD38820A45 MCU
1906   * RC circuit for speaker volume decay
1907   * cyan/red VFD display Futaba DM-47ZK 2K, with color overlay
1908 
1909 ***************************************************************************/
1910 
1911 class cdkong_state : public hh_hmcs40_state
1912 {
1913 public:
cdkong_state(const machine_config & mconfig,device_type type,const char * tag)1914 	cdkong_state(const machine_config &mconfig, device_type type, const char *tag) :
1915 		hh_hmcs40_state(mconfig, type, tag)
1916 	{ }
1917 
1918 	void update_display();
1919 	void plate_w(offs_t offset, u8 data);
1920 	void grid_w(u16 data);
1921 
1922 	void speaker_update();
1923 	TIMER_DEVICE_CALLBACK_MEMBER(speaker_decay_sim);
1924 	double m_speaker_volume;
1925 	void cdkong(machine_config &config);
1926 
1927 protected:
1928 	virtual void machine_start() override;
1929 
1930 	std::vector<double> m_speaker_levels;
1931 };
1932 
machine_start()1933 void cdkong_state::machine_start()
1934 {
1935 	hh_hmcs40_state::machine_start();
1936 
1937 	// zerofill/init
1938 	m_speaker_volume = 0;
1939 	save_item(NAME(m_speaker_volume));
1940 }
1941 
1942 // handlers
1943 
speaker_update()1944 void cdkong_state::speaker_update()
1945 {
1946 	if (m_r[1] & 8)
1947 		m_speaker_volume = 1.0;
1948 
1949 	int level = (m_d & 8) ? 0x7fff : 0;
1950 	m_speaker->level_w(level * m_speaker_volume);
1951 }
1952 
TIMER_DEVICE_CALLBACK_MEMBER(cdkong_state::speaker_decay_sim)1953 TIMER_DEVICE_CALLBACK_MEMBER(cdkong_state::speaker_decay_sim)
1954 {
1955 	// volume decays when speaker is off (divisor and timer period determine duration)
1956 	speaker_update();
1957 	m_speaker_volume /= 1.02;
1958 }
1959 
update_display()1960 void cdkong_state::update_display()
1961 {
1962 	u32 plate = bitswap<32>(m_plate,31,30,29,24,0,16,8,1,23,17,9,2,18,10,25,27,26,3,15,27,11,11,14,22,6,13,21,5,19,12,20,4) | 0x800800;
1963 	m_display->matrix(m_grid, plate);
1964 }
1965 
plate_w(offs_t offset,u8 data)1966 void cdkong_state::plate_w(offs_t offset, u8 data)
1967 {
1968 	// R13: speaker on
1969 	m_r[offset] = data;
1970 	speaker_update();
1971 
1972 	// R0x-R6x: vfd plate
1973 	int shift = offset * 4;
1974 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
1975 	update_display();
1976 }
1977 
grid_w(u16 data)1978 void cdkong_state::grid_w(u16 data)
1979 {
1980 	// D3: speaker out
1981 	m_d = data;
1982 	speaker_update();
1983 
1984 	// D4-D14: vfd grid
1985 	m_grid = data >> 4 & 0x7ff;
1986 	update_display();
1987 }
1988 
1989 // config
1990 
1991 static INPUT_PORTS_START( cdkong )
1992 	PORT_START("IN.0") // INT0
1993 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_hmcs40_state, single_interrupt_line, 0)
1994 
1995 	PORT_START("IN.1") // port D
1996 	PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
1997 	PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
1998 	PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
1999 	PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
2000 	PORT_BIT( 0x7ff8, IP_ACTIVE_HIGH, IPT_UNUSED )
2001 INPUT_PORTS_END
2002 
cdkong(machine_config & config)2003 void cdkong_state::cdkong(machine_config &config)
2004 {
2005 	/* basic machine hardware */
2006 	HD38820(config, m_maincpu, 400000); // approximation
2007 	m_maincpu->write_r<0>().set(FUNC(cdkong_state::plate_w));
2008 	m_maincpu->write_r<1>().set(FUNC(cdkong_state::plate_w));
2009 	m_maincpu->write_r<2>().set(FUNC(cdkong_state::plate_w));
2010 	m_maincpu->write_r<3>().set(FUNC(cdkong_state::plate_w));
2011 	m_maincpu->write_r<4>().set(FUNC(cdkong_state::plate_w));
2012 	m_maincpu->write_r<5>().set(FUNC(cdkong_state::plate_w));
2013 	m_maincpu->write_r<6>().set(FUNC(cdkong_state::plate_w));
2014 	m_maincpu->write_d().set(FUNC(cdkong_state::grid_w));
2015 	m_maincpu->read_d().set_ioport("IN.1");
2016 
2017 	/* video hardware */
2018 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
2019 	screen.set_refresh_hz(60);
2020 	screen.set_size(605, 1080);
2021 	screen.set_visarea_full();
2022 
2023 	PWM_DISPLAY(config, m_display).set_size(11, 29);
2024 
2025 	/* sound hardware */
2026 	SPEAKER(config, "mono").front_center();
2027 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
2028 
2029 	TIMER(config, "speaker_decay").configure_periodic(FUNC(cdkong_state::speaker_decay_sim), attotime::from_msec(1));
2030 
2031 	// set volume levels (set_output_gain is too slow for sub-frame intervals)
2032 	m_speaker_levels.resize(0x8000);
2033 	for (int i = 0; i < 0x8000; i++)
2034 		m_speaker_levels[i] = double(i) / 32768.0;
2035 	m_speaker->set_levels(0x8000, &m_speaker_levels[0]);
2036 }
2037 
2038 // roms
2039 
2040 ROM_START( cdkong )
2041 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
2042 	ROM_LOAD( "hd38820a45", 0x0000, 0x1000, CRC(196b8070) SHA1(da85d1eb4b048b77f3168630662ab94ec9baa262) )
2043 	ROM_CONTINUE(           0x1e80, 0x0100 )
2044 
2045 	ROM_REGION( 359199, "screen", 0)
2046 	ROM_LOAD( "cdkong.svg", 0, 359199, CRC(ba159fd5) SHA1(3188e2ed3234f39ac9ee93a485a7e73314bc3457) )
2047 ROM_END
2048 
2049 
2050 
2051 
2052 
2053 /***************************************************************************
2054 
2055   Coleco Galaxian (manufactured in Taiwan)
2056   * PCB label Coleco Rev A 75718
2057   * Hitachi HD38800A70 MCU
2058   * discrete sound (when alien attacks)
2059   * cyan/red VFD display Futaba DM-36Z 2H, with color overlay
2060 
2061   Select game mode on start:
2062   - P1 Left:  Galaxian (default game)
2063   - P1 Right: Midway's Attackers
2064   - P2 Left:  Head-to-Head Galaxian (2-player mode, short)
2065   - P2 Right: Head-to-Head Galaxian (2-player mode, long)
2066 
2067 ***************************************************************************/
2068 
2069 class cgalaxn_state : public hh_hmcs40_state
2070 {
2071 public:
cgalaxn_state(const machine_config & mconfig,device_type type,const char * tag)2072 	cgalaxn_state(const machine_config &mconfig, device_type type, const char *tag) :
2073 		hh_hmcs40_state(mconfig, type, tag)
2074 	{ }
2075 
2076 	void update_display();
2077 	void grid_w(offs_t offset, u8 data);
2078 	void plate_w(u16 data);
2079 	u8 input_r();
2080 
2081 	DECLARE_INPUT_CHANGED_MEMBER(player_switch);
2082 	void cgalaxn(machine_config &config);
2083 };
2084 
2085 // handlers
2086 
update_display()2087 void cgalaxn_state::update_display()
2088 {
2089 	u16 grid = bitswap<16>(m_grid,15,14,13,12,1,2,0,11,10,9,8,7,6,5,4,3);
2090 	u16 plate = bitswap<16>(m_plate,15,14,6,5,4,3,2,1,7,8,9,10,11,0,12,13);
2091 	m_display->matrix(grid, plate);
2092 }
2093 
INPUT_CHANGED_MEMBER(cgalaxn_state::player_switch)2094 INPUT_CHANGED_MEMBER(cgalaxn_state::player_switch)
2095 {
2096 	// 2-player switch directly enables plate 14
2097 	m_plate = (m_plate & 0x3fff) | (newval ? 0 : 0x4000);
2098 	update_display();
2099 }
2100 
grid_w(offs_t offset,u8 data)2101 void cgalaxn_state::grid_w(offs_t offset, u8 data)
2102 {
2103 	// R10,R11: input mux
2104 	if (offset == 1)
2105 		m_inp_mux = data & 3;
2106 
2107 	// R1x-R3x: vfd grid
2108 	int shift = (offset - 1) * 4;
2109 	m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
2110 	update_display();
2111 }
2112 
plate_w(u16 data)2113 void cgalaxn_state::plate_w(u16 data)
2114 {
2115 	// D0: speaker out
2116 	m_speaker->level_w(data & 1);
2117 
2118 	// D1: start alien attack whine sound effect (edge triggered)
2119 
2120 	// D2-D15: vfd plate
2121 	m_plate = (m_plate & 0x4000) | (data >> 2 & 0x3fff);
2122 	update_display();
2123 }
2124 
input_r()2125 u8 cgalaxn_state::input_r()
2126 {
2127 	// R0x: multiplexed inputs
2128 	return read_inputs(2);
2129 }
2130 
2131 // config
2132 
2133 static INPUT_PORTS_START( cgalaxn )
2134 	PORT_START("IN.0") // R10 port R0x
2135 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
2136 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
2137 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
2138 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
2139 
2140 	PORT_START("IN.1") // R11 port R0x
DEF_STR(Players)2141 	PORT_CONFNAME( 0x01, 0x01, DEF_STR( Players ) ) PORT_CHANGED_MEMBER(DEVICE_SELF, cgalaxn_state, player_switch, 0)
2142 	PORT_CONFSETTING(    0x01, "1" )
2143 	PORT_CONFSETTING(    0x00, "2" )
2144 	PORT_BIT( 0x0e, IP_ACTIVE_HIGH, IPT_UNUSED )
2145 
2146 	PORT_START("IN.2") // INT0
2147 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_hmcs40_state, single_interrupt_line, 0)
2148 
2149 	PORT_START("IN.3") // INT1
2150 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_hmcs40_state, single_interrupt_line, 1)
2151 INPUT_PORTS_END
2152 
2153 void cgalaxn_state::cgalaxn(machine_config &config)
2154 {
2155 	/* basic machine hardware */
2156 	HD38800(config, m_maincpu, 400000); // approximation
2157 	m_maincpu->read_r<0>().set(FUNC(cgalaxn_state::input_r));
2158 	m_maincpu->write_r<1>().set(FUNC(cgalaxn_state::grid_w));
2159 	m_maincpu->write_r<2>().set(FUNC(cgalaxn_state::grid_w));
2160 	m_maincpu->write_r<3>().set(FUNC(cgalaxn_state::grid_w));
2161 	m_maincpu->write_d().set(FUNC(cgalaxn_state::plate_w));
2162 
2163 	/* video hardware */
2164 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
2165 	screen.set_refresh_hz(60);
2166 	screen.set_size(526, 1080);
2167 	screen.set_visarea_full();
2168 
2169 	PWM_DISPLAY(config, m_display).set_size(12, 15);
2170 
2171 	/* sound hardware */
2172 	SPEAKER(config, "mono").front_center();
2173 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
2174 }
2175 
2176 // roms
2177 
2178 ROM_START( cgalaxn )
2179 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
2180 	ROM_LOAD( "hd38800a70", 0x0000, 0x1000, CRC(a4c5ed1d) SHA1(0f647cb78437d7e62411febf7c9ce3c5b6753a80) )
2181 	ROM_CONTINUE(           0x1e80, 0x0100 )
2182 
2183 	ROM_REGION( 712204, "screen", 0)
2184 	ROM_LOAD( "cgalaxn.svg", 0, 712204, CRC(67ec57bf) SHA1(195c9867b321da9768ce287d1060ceae50345dd4) )
2185 ROM_END
2186 
2187 
2188 
2189 
2190 
2191 /***************************************************************************
2192 
2193   Coleco Pac-Man (manufactured in Taiwan, licensed from Midway)
2194   * PCB label Coleco 75690
2195   * Hitachi QFP HD38820A28/29 MCU
2196   * cyan/red VFD display Futaba DM-34Z 2A, with color overlay
2197 
2198   known releases:
2199   - USA: Pac-Man, by Coleco (name-license from Midway)
2200   - Japan: Super Puck Monster, published by Gakken
2201 
2202   Select game mode on start:
2203   - P1 Right: Pac-Man (default game)
2204   - P1 Left:  Head-to-Head Pac-Man (2-player mode)
2205   - P1 Up:    Eat & Run
2206   - P1 Down:  Demo
2207 
2208   BTANB note: 1st version doesn't show the whole maze on power-on
2209 
2210 ***************************************************************************/
2211 
2212 class cpacman_state : public hh_hmcs40_state
2213 {
2214 public:
cpacman_state(const machine_config & mconfig,device_type type,const char * tag)2215 	cpacman_state(const machine_config &mconfig, device_type type, const char *tag) :
2216 		hh_hmcs40_state(mconfig, type, tag)
2217 	{ }
2218 
2219 	void plate_w(offs_t offset, u8 data);
2220 	void grid_w(u16 data);
2221 	u8 input_r();
2222 	void cpacman(machine_config &config);
2223 };
2224 
2225 // handlers
2226 
plate_w(offs_t offset,u8 data)2227 void cpacman_state::plate_w(offs_t offset, u8 data)
2228 {
2229 	// R1x-R6x(,D1,D2): vfd plate
2230 	int shift = (offset - 1) * 4;
2231 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
2232 
2233 	// update display
2234 	u16 grid = bitswap<16>(m_grid,15,14,13,12,11,0,1,2,3,4,5,6,7,8,9,10);
2235 	u32 plate = bitswap<32>(m_plate,31,30,29,28,27,0,1,2,3,8,9,10,11,16,17,18,19,25,26,23,22,21,20,24,15,14,13,12,4,5,6,7);
2236 	m_display->matrix(grid, plate);
2237 }
2238 
grid_w(u16 data)2239 void cpacman_state::grid_w(u16 data)
2240 {
2241 	// D0: speaker out
2242 	m_speaker->level_w(data & 1);
2243 
2244 	// D13-D15: input mux
2245 	m_inp_mux = data >> 13 & 7;
2246 
2247 	// D5-D15: vfd grid
2248 	m_grid = data >> 5 & 0x7ff;
2249 
2250 	// D1,D2: plate 8,14 (update display there)
2251 	plate_w(6 + 1, data >> 1 & 3);
2252 }
2253 
input_r()2254 u8 cpacman_state::input_r()
2255 {
2256 	// R0x: multiplexed inputs
2257 	return read_inputs(3);
2258 }
2259 
2260 // config
2261 
2262 static INPUT_PORTS_START( cpacman )
2263 	PORT_START("IN.0") // D13 port R0x
DEF_STR(Difficulty)2264 	PORT_CONFNAME( 0x01, 0x01, DEF_STR( Difficulty ) )
2265 	PORT_CONFSETTING(    0x00, "1" )
2266 	PORT_CONFSETTING(    0x01, "2" )
2267 	PORT_BIT( 0x0e, IP_ACTIVE_HIGH, IPT_UNUSED )
2268 
2269 	PORT_START("IN.1") // D14 port R0x
2270 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
2271 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
2272 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
2273 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
2274 
2275 	PORT_START("IN.2") // D15 port R0x
2276 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
2277 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
2278 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
2279 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
2280 INPUT_PORTS_END
2281 
2282 void cpacman_state::cpacman(machine_config &config)
2283 {
2284 	/* basic machine hardware */
2285 	HD38820(config, m_maincpu, 400000); // approximation
2286 	m_maincpu->read_r<0>().set(FUNC(cpacman_state::input_r));
2287 	m_maincpu->write_r<1>().set(FUNC(cpacman_state::plate_w));
2288 	m_maincpu->write_r<2>().set(FUNC(cpacman_state::plate_w));
2289 	m_maincpu->write_r<3>().set(FUNC(cpacman_state::plate_w));
2290 	m_maincpu->write_r<4>().set(FUNC(cpacman_state::plate_w));
2291 	m_maincpu->write_r<5>().set(FUNC(cpacman_state::plate_w));
2292 	m_maincpu->write_r<6>().set(FUNC(cpacman_state::plate_w));
2293 	m_maincpu->write_d().set(FUNC(cpacman_state::grid_w));
2294 
2295 	/* video hardware */
2296 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
2297 	screen.set_refresh_hz(60);
2298 	screen.set_size(484, 1080);
2299 	screen.set_visarea_full();
2300 
2301 	PWM_DISPLAY(config, m_display).set_size(11, 27);
2302 
2303 	/* sound hardware */
2304 	SPEAKER(config, "mono").front_center();
2305 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
2306 }
2307 
2308 // roms
2309 
2310 ROM_START( cpacman )
2311 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
2312 	ROM_LOAD( "hd38820a29", 0x0000, 0x1000, CRC(1082d577) SHA1(0ef73132bd41f6ca1e4c001ae19f7f7c97eaa8d1) )
2313 	ROM_CONTINUE(           0x1e80, 0x0100 )
2314 
2315 	ROM_REGION( 359765, "screen", 0)
2316 	ROM_LOAD( "cpacman.svg", 0, 359765, CRC(e3810a46) SHA1(d0994edd71a6adc8f238c71e360a8606ce397a14) )
2317 ROM_END
2318 
2319 ROM_START( cpacmanr1 )
2320 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
2321 	ROM_LOAD( "hd38820a28", 0x0000, 0x1000, CRC(d2ed57e5) SHA1(f56f1341485ac28ea9e6cc4d162fab18d8a4c977) )
2322 	ROM_CONTINUE(           0x1e80, 0x0100 )
2323 
2324 	ROM_REGION( 359765, "screen", 0)
2325 	ROM_LOAD( "cpacman.svg", 0, 359765, CRC(e3810a46) SHA1(d0994edd71a6adc8f238c71e360a8606ce397a14) )
2326 ROM_END
2327 
2328 
2329 
2330 
2331 
2332 /***************************************************************************
2333 
2334   Coleco Ms. Pac-Man (manufactured in Taiwan, licensed from Midway)
2335   * PCB label Coleco 911171
2336   * Hitachi QFP HD38820A61 MCU
2337   * cyan/red VFD display Futaba DM-60Z 3I, with color overlay
2338 
2339   Select game mode on start:
2340   - P1 Left:  Ms. Pac-Man (default game)
2341   - P1 Down:  Head-to-Head Ms. Pac-Man (2-player mode)
2342   - P1 Up:    Demo
2343 
2344   BTANB note: in demo-mode, she hardly ever walks to the upper two rows
2345 
2346 ***************************************************************************/
2347 
2348 class cmspacmn_state : public hh_hmcs40_state
2349 {
2350 public:
cmspacmn_state(const machine_config & mconfig,device_type type,const char * tag)2351 	cmspacmn_state(const machine_config &mconfig, device_type type, const char *tag) :
2352 		hh_hmcs40_state(mconfig, type, tag)
2353 	{ }
2354 
2355 	void plate_w(offs_t offset, u8 data);
2356 	void grid_w(u16 data);
2357 	u8 input_r();
2358 	void cmspacmn(machine_config &config);
2359 };
2360 
2361 // handlers
2362 
plate_w(offs_t offset,u8 data)2363 void cmspacmn_state::plate_w(offs_t offset, u8 data)
2364 {
2365 	// R1x-R6x(,D0,D1): vfd plate
2366 	int shift = (offset - 1) * 4;
2367 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
2368 
2369 	// update display
2370 	u16 grid = bitswap<16>(m_grid,15,14,13,11,10,9,8,7,6,5,4,3,2,1,0,1);
2371 	u32 plate = bitswap<32>(m_plate,14,13,12,4,5,6,7,24,23,25,22,21,20,13,24,3,19,14,12,11,24,2,10,8,7,25,0,9,1,18,17,16) | 0x1004080;
2372 	m_display->matrix(grid, u64(BIT(m_plate,15)) << 32 | plate);
2373 }
2374 
grid_w(u16 data)2375 void cmspacmn_state::grid_w(u16 data)
2376 {
2377 	// D2: speaker out
2378 	m_speaker->level_w(data >> 2 & 1);
2379 
2380 	// D13-D15: input mux
2381 	m_inp_mux = data >> 13 & 7;
2382 
2383 	// D5-D15: vfd grid
2384 	m_grid = data >> 5 & 0x7ff;
2385 
2386 	// D0,D1: more plates (update display there)
2387 	plate_w(6 + 1, data & 3);
2388 }
2389 
input_r()2390 u8 cmspacmn_state::input_r()
2391 {
2392 	// R0x: multiplexed inputs
2393 	return read_inputs(3);
2394 }
2395 
2396 // config
2397 
2398 static INPUT_PORTS_START( cmspacmn )
2399 	PORT_START("IN.0") // D13 port R0x
DEF_STR(Difficulty)2400 	PORT_CONFNAME( 0x01, 0x00, DEF_STR( Difficulty ) )
2401 	PORT_CONFSETTING(    0x00, "1" )
2402 	PORT_CONFSETTING(    0x01, "2" )
2403 	PORT_BIT( 0x0e, IP_ACTIVE_HIGH, IPT_UNUSED )
2404 
2405 	PORT_START("IN.1") // D14 port R0x
2406 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
2407 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
2408 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
2409 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
2410 
2411 	PORT_START("IN.2") // D15 port R0x
2412 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
2413 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
2414 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
2415 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
2416 INPUT_PORTS_END
2417 
2418 void cmspacmn_state::cmspacmn(machine_config &config)
2419 {
2420 	/* basic machine hardware */
2421 	HD38820(config, m_maincpu, 400000); // approximation
2422 	m_maincpu->read_r<0>().set(FUNC(cmspacmn_state::input_r));
2423 	m_maincpu->write_r<1>().set(FUNC(cmspacmn_state::plate_w));
2424 	m_maincpu->write_r<2>().set(FUNC(cmspacmn_state::plate_w));
2425 	m_maincpu->write_r<3>().set(FUNC(cmspacmn_state::plate_w));
2426 	m_maincpu->write_r<4>().set(FUNC(cmspacmn_state::plate_w));
2427 	m_maincpu->write_r<5>().set(FUNC(cmspacmn_state::plate_w));
2428 	m_maincpu->write_r<6>().set(FUNC(cmspacmn_state::plate_w));
2429 	m_maincpu->write_d().set(FUNC(cmspacmn_state::grid_w));
2430 
2431 	/* video hardware */
2432 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
2433 	screen.set_refresh_hz(60);
2434 	screen.set_size(481, 1080);
2435 	screen.set_visarea_full();
2436 
2437 	PWM_DISPLAY(config, m_display).set_size(12, 33);
2438 
2439 	/* sound hardware */
2440 	SPEAKER(config, "mono").front_center();
2441 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
2442 }
2443 
2444 // roms
2445 
2446 ROM_START( cmspacmn )
2447 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
2448 	ROM_LOAD( "hd38820a61", 0x0000, 0x1000, CRC(76276318) SHA1(9d6ff3f49b4cdaee5c9e238c1ed638bfb9b99aa7) )
2449 	ROM_CONTINUE(           0x1e80, 0x0100 )
2450 
2451 	ROM_REGION( 849327, "screen", 0)
2452 	ROM_LOAD( "cmspacmn.svg", 0, 849327, CRC(4110ad07) SHA1(76113a2ce0fb1c6dab4e26fd59a13dc89d950d75) )
2453 ROM_END
2454 
2455 
2456 
2457 
2458 
2459 /***************************************************************************
2460 
2461   Entex Galaxian 2 (manufactured in Japan)
2462   * PCB labels ENTEX GALAXIAN PB-118/116/097 80-210137/135/114
2463   * Hitachi QFP HD38820A13 MCU
2464   * cyan/red/green VFD display Futaba DM-20
2465 
2466   known releases:
2467   - USA: Galaxian 2
2468   - UK: Astro Invader (Hales/Entex)
2469 
2470 ***************************************************************************/
2471 
2472 class egalaxn2_state : public hh_hmcs40_state
2473 {
2474 public:
egalaxn2_state(const machine_config & mconfig,device_type type,const char * tag)2475 	egalaxn2_state(const machine_config &mconfig, device_type type, const char *tag) :
2476 		hh_hmcs40_state(mconfig, type, tag)
2477 	{ }
2478 
2479 	void update_display();
2480 	void plate_w(offs_t offset, u8 data);
2481 	void grid_w(u16 data);
2482 	u8 input_r();
2483 	void egalaxn2(machine_config &config);
2484 };
2485 
2486 // handlers
2487 
update_display()2488 void egalaxn2_state::update_display()
2489 {
2490 	u16 grid = bitswap<16>(m_grid,15,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14);
2491 	u32 plate = bitswap<24>(m_plate,23,22,21,20,15,14,13,12,7,6,5,4,3,2,1,0,19,18,17,16,11,10,9,8);
2492 	m_display->matrix(grid, plate);
2493 }
2494 
grid_w(u16 data)2495 void egalaxn2_state::grid_w(u16 data)
2496 {
2497 	// D0: speaker out
2498 	m_speaker->level_w(data & 1);
2499 
2500 	// D1-D4: input mux
2501 	m_inp_mux = data >> 1 & 0xf;
2502 
2503 	// D1-D15: vfd grid
2504 	m_grid = data >> 1 & 0x7fff;
2505 	update_display();
2506 }
2507 
plate_w(offs_t offset,u8 data)2508 void egalaxn2_state::plate_w(offs_t offset, u8 data)
2509 {
2510 	// R1x-R6x: vfd plate
2511 	int shift = (offset - 1) * 4;
2512 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
2513 	update_display();
2514 }
2515 
input_r()2516 u8 egalaxn2_state::input_r()
2517 {
2518 	// R0x: multiplexed inputs
2519 	return read_inputs(4);
2520 }
2521 
2522 // config
2523 
2524 static INPUT_PORTS_START( egalaxn2 )
2525 	PORT_START("IN.0") // D1 port R0x
2526 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
2527 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_16WAY
2528 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
2529 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_16WAY
2530 
2531 	PORT_START("IN.1") // D2 port R0x
2532 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_COCKTAIL PORT_16WAY
2533 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_COCKTAIL PORT_16WAY
2534 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_COCKTAIL PORT_16WAY
2535 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_COCKTAIL PORT_16WAY
2536 
2537 	PORT_START("IN.2") // D3 port R0x
2538 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 )
2539 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_COCKTAIL
2540 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
2541 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
2542 
2543 	PORT_START("IN.3") // D4 port R0x
2544 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
DEF_STR(Difficulty)2545 	PORT_CONFNAME( 0x02, 0x02, DEF_STR( Difficulty ) )
2546 	PORT_CONFSETTING(    0x02, "1" )
2547 	PORT_CONFSETTING(    0x00, "2" )
2548 	PORT_CONFNAME( 0x0c, 0x00, DEF_STR( Players ) )
2549 	PORT_CONFSETTING(    0x08, "0 (Demo)" ) // for Demo mode: need to hold down Fire button at power-on
2550 	PORT_CONFSETTING(    0x00, "1" )
2551 	PORT_CONFSETTING(    0x04, "2" )
2552 INPUT_PORTS_END
2553 
2554 void egalaxn2_state::egalaxn2(machine_config &config)
2555 {
2556 	/* basic machine hardware */
2557 	HD38820(config, m_maincpu, 400000); // approximation
2558 	m_maincpu->read_r<0>().set(FUNC(egalaxn2_state::input_r));
2559 	m_maincpu->write_r<1>().set(FUNC(egalaxn2_state::plate_w));
2560 	m_maincpu->write_r<2>().set(FUNC(egalaxn2_state::plate_w));
2561 	m_maincpu->write_r<3>().set(FUNC(egalaxn2_state::plate_w));
2562 	m_maincpu->write_r<4>().set(FUNC(egalaxn2_state::plate_w));
2563 	m_maincpu->write_r<5>().set(FUNC(egalaxn2_state::plate_w));
2564 	m_maincpu->write_r<6>().set(FUNC(egalaxn2_state::plate_w));
2565 	m_maincpu->write_d().set(FUNC(egalaxn2_state::grid_w));
2566 
2567 	/* video hardware */
2568 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
2569 	screen.set_refresh_hz(60);
2570 	screen.set_size(505, 1080);
2571 	screen.set_visarea_full();
2572 
2573 	PWM_DISPLAY(config, m_display).set_size(15, 24);
2574 
2575 	/* sound hardware */
2576 	SPEAKER(config, "mono").front_center();
2577 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
2578 }
2579 
2580 // roms
2581 
2582 ROM_START( egalaxn2 )
2583 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
2584 	ROM_LOAD( "hd38820a13", 0x0000, 0x1000, CRC(112b721b) SHA1(4a185bc57ea03fe64f61f7db4da37b16eeb0cb54) )
2585 	ROM_CONTINUE(           0x1e80, 0x0100 )
2586 
2587 	ROM_REGION( 507945, "screen", 0)
2588 	ROM_LOAD( "egalaxn2.svg", 0, 507945, CRC(b72a8721) SHA1(2d90fca6ce962710525b631e5bc8f75d79332b9d) )
2589 ROM_END
2590 
2591 
2592 
2593 
2594 
2595 /***************************************************************************
2596 
2597   Entex Pac Man 2 (manufactured in Japan)
2598   * PCB labels ENTEX PAC-MAN PB-093/094 80-210149/50/51
2599   * Hitachi QFP HD38820A23 MCU
2600   * cyan/red VFD display Futaba DM-28Z 1G(cyan Pac-Man) or DM-28 1K(orange Pac-Man)
2601 
2602   2 VFD revisions are known, the difference is Pac-Man's color: cyan or red.
2603 
2604 ***************************************************************************/
2605 
2606 class epacman2_state : public egalaxn2_state
2607 {
2608 public:
epacman2_state(const machine_config & mconfig,device_type type,const char * tag)2609 	epacman2_state(const machine_config &mconfig, device_type type, const char *tag) :
2610 		egalaxn2_state(mconfig, type, tag)
2611 	{ }
2612 
2613 	void epacman2(machine_config &config);
2614 };
2615 
2616 // handlers are identical to Galaxian 2, so we can use those
2617 
2618 // config
2619 
2620 static INPUT_PORTS_START( epacman2 )
2621 	PORT_START("IN.0") // D1 port R0x
2622 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_16WAY
2623 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_16WAY
2624 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_16WAY
2625 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_16WAY
2626 
2627 	PORT_START("IN.1") // D2 port R0x
2628 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_COCKTAIL PORT_16WAY
2629 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_COCKTAIL PORT_16WAY
2630 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_COCKTAIL PORT_16WAY
2631 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_COCKTAIL PORT_16WAY
2632 
2633 	PORT_START("IN.2") // D3 port R0x
2634 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("P1 Skill Control")
2635 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("Demo Light Test")
2636 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
2637 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
2638 
2639 	PORT_START("IN.3") // D4 port R0x
2640 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
DEF_STR(Difficulty)2641 	PORT_CONFNAME( 0x02, 0x02, DEF_STR( Difficulty ) )
2642 	PORT_CONFSETTING(    0x00, "1" )
2643 	PORT_CONFSETTING(    0x02, "2" )
2644 	PORT_CONFNAME( 0x0c, 0x04, DEF_STR( Players ) )
2645 	PORT_CONFSETTING(    0x08, "0 (Demo)" )
2646 	PORT_CONFSETTING(    0x04, "1" )
2647 	PORT_CONFSETTING(    0x00, "2" )
2648 INPUT_PORTS_END
2649 
2650 void epacman2_state::epacman2(machine_config &config)
2651 {
2652 	egalaxn2(config);
2653 
2654 	/* video hardware */
2655 	screen_device *screen = subdevice<screen_device>("screen");
2656 	screen->set_size(505, 1080);
2657 	screen->set_visarea_full();
2658 }
2659 
2660 // roms
2661 
2662 ROM_START( epacman2 )
2663 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
2664 	ROM_LOAD( "hd38820a23", 0x0000, 0x1000, CRC(6eab640f) SHA1(509bdd02be915089e13769f22a08e03509f03af4) )
2665 	ROM_CONTINUE(           0x1e80, 0x0100 )
2666 
2667 	ROM_REGION( 262480, "screen", 0)
2668 	ROM_LOAD( "epacman2.svg", 0, 262480, CRC(73bd9671) SHA1(a3ac754c0e060da50b65f3d0f9630d9c3d871650) )
2669 ROM_END
2670 
2671 ROM_START( epacman2r )
2672 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
2673 	ROM_LOAD( "hd38820a23", 0x0000, 0x1000, CRC(6eab640f) SHA1(509bdd02be915089e13769f22a08e03509f03af4) )
2674 	ROM_CONTINUE(           0x1e80, 0x0100 )
2675 
2676 	ROM_REGION( 262483, "screen", 0)
2677 	ROM_LOAD( "epacman2r.svg", 0, 262483, CRC(279b629a) SHA1(4c499fb143aadf4f6722b994a22a0d0d3c5150b6) )
2678 ROM_END
2679 
2680 
2681 
2682 
2683 
2684 /***************************************************************************
2685 
2686   Entex Super Space Invader 2 (black version)
2687   * Hitachi HD38800A31 MCU
2688   * cyan/red VFD display
2689 
2690   This version has the same MCU as the Select-A-Game cartridge. Maybe from
2691   surplus inventory after that console was discontinued?. It was also sold
2692   as "Super Alien Invader 2".
2693 
2694   Hold down the fire button at boot for demo mode to work.
2695 
2696 ***************************************************************************/
2697 
2698 class einvader2_state : public hh_hmcs40_state
2699 {
2700 public:
einvader2_state(const machine_config & mconfig,device_type type,const char * tag)2701 	einvader2_state(const machine_config &mconfig, device_type type, const char *tag) :
2702 		hh_hmcs40_state(mconfig, type, tag)
2703 	{ }
2704 
2705 	void update_display();
2706 	void plate_w(offs_t offset, u8 data);
2707 	void grid_w(u16 data);
2708 	u16 input_r();
2709 	void einvader2(machine_config &config);
2710 };
2711 
2712 // handlers
2713 
update_display()2714 void einvader2_state::update_display()
2715 {
2716 	m_display->matrix(m_grid, m_plate);
2717 }
2718 
plate_w(offs_t offset,u8 data)2719 void einvader2_state::plate_w(offs_t offset, u8 data)
2720 {
2721 	// R0x-R3x: vfd plate
2722 	int shift = offset * 4;
2723 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
2724 	update_display();
2725 }
2726 
grid_w(u16 data)2727 void einvader2_state::grid_w(u16 data)
2728 {
2729 	// D0: speaker out
2730 	m_speaker->level_w(data & 1);
2731 
2732 	// D3,D5,D6: input mux
2733 	m_inp_mux = (data >> 3 & 1) | (data >> 4 & 6);
2734 
2735 	// D1-D12: vfd grid
2736 	m_grid = data >> 1 & 0xfff;
2737 	update_display();
2738 }
2739 
input_r()2740 u16 einvader2_state::input_r()
2741 {
2742 	// D13-D15: multiplexed inputs
2743 	return read_inputs(3) << 13;
2744 }
2745 
2746 // config
2747 
2748 static INPUT_PORTS_START( einvader2 )
2749 	PORT_START("IN.0") // D3
2750 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_16WAY
2751 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_COCKTAIL PORT_16WAY
2752 	PORT_BIT( 0x04, 0x04, IPT_CUSTOM ) PORT_CONDITION("FAKE", 0x03, EQUALS, 0x01) // 1 player
2753 
2754 	PORT_START("IN.1") // D5
2755 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_16WAY
2756 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_COCKTAIL PORT_16WAY
2757 	PORT_BIT( 0x04, 0x04, IPT_CUSTOM ) PORT_CONDITION("FAKE", 0x03, EQUALS, 0x00) // demo
2758 
2759 	PORT_START("IN.2") // D6
2760 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 )
2761 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_COCKTAIL
2762 
2763 	PORT_START("FAKE") // shared D3/D5
DEF_STR(Players)2764 	PORT_CONFNAME( 0x03, 0x01, DEF_STR( Players ) )
2765 	PORT_CONFSETTING(    0x00, "Demo" )
2766 	PORT_CONFSETTING(    0x01, "1" )
2767 	PORT_CONFSETTING(    0x02, "2" )
2768 INPUT_PORTS_END
2769 
2770 void einvader2_state::einvader2(machine_config &config)
2771 {
2772 	/* basic machine hardware */
2773 	HD38800(config, m_maincpu, 450000); // approximation
2774 	m_maincpu->write_r<0>().set(FUNC(einvader2_state::plate_w));
2775 	m_maincpu->write_r<1>().set(FUNC(einvader2_state::plate_w));
2776 	m_maincpu->write_r<2>().set(FUNC(einvader2_state::plate_w));
2777 	m_maincpu->write_r<3>().set(FUNC(einvader2_state::plate_w));
2778 	m_maincpu->write_d().set(FUNC(einvader2_state::grid_w));
2779 	m_maincpu->read_d().set(FUNC(einvader2_state::input_r));
2780 
2781 	/* video hardware */
2782 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
2783 	screen.set_refresh_hz(60);
2784 	screen.set_size(469, 1080);
2785 	screen.set_visarea_full();
2786 
2787 	PWM_DISPLAY(config, m_display).set_size(12, 14);
2788 
2789 	/* sound hardware */
2790 	SPEAKER(config, "mono").front_center();
2791 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
2792 }
2793 
2794 // roms
2795 
2796 ROM_START( einvader2 )
2797 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
2798 	ROM_LOAD( "inv2_hd38800a31", 0x0000, 0x1000, CRC(10e39521) SHA1(41d86696e518ea071e75ed37d5dc63c0408c262e) )
2799 	ROM_CONTINUE(                0x1e80, 0x0100 )
2800 
2801 	ROM_REGION( 217430, "screen", 0)
2802 	ROM_LOAD( "einvader2.svg", 0, 217430, CRC(b082d9a3) SHA1(67f7e0314c69ba146751ea12cf490805b8660489) )
2803 ROM_END
2804 
2805 
2806 
2807 
2808 
2809 /***************************************************************************
2810 
2811   Entex Turtles (manufactured in Japan)
2812   * PCB label 560359
2813   * Hitachi QFP HD38820A43 MCU
2814   * COP411L sub MCU, label COP411L-KED/N
2815   * cyan/red/green VFD display NEC FIP15BM32T
2816 
2817 ***************************************************************************/
2818 
2819 class eturtles_state : public hh_hmcs40_state
2820 {
2821 public:
eturtles_state(const machine_config & mconfig,device_type type,const char * tag)2822 	eturtles_state(const machine_config &mconfig, device_type type, const char *tag) :
2823 		hh_hmcs40_state(mconfig, type, tag),
2824 		m_audiocpu(*this, "audiocpu"),
2825 		m_cop_irq(0)
2826 	{ }
2827 
2828 	required_device<cop411_cpu_device> m_audiocpu;
2829 
2830 	virtual void update_display();
2831 	void plate_w(offs_t offset, u8 data);
2832 	void grid_w(u16 data);
2833 
2834 	u8 m_cop_irq;
2835 	DECLARE_WRITE_LINE_MEMBER(speaker_w);
2836 	void cop_irq_w(u8 data);
2837 	u8 cop_latch_r();
2838 	u8 cop_ack_r();
2839 
2840 	void update_int();
DECLARE_INPUT_CHANGED_MEMBER(input_changed)2841 	DECLARE_INPUT_CHANGED_MEMBER(input_changed) { update_int(); }
2842 	void eturtles(machine_config &config);
2843 
2844 protected:
2845 	virtual void machine_start() override;
2846 };
2847 
machine_start()2848 void eturtles_state::machine_start()
2849 {
2850 	hh_hmcs40_state::machine_start();
2851 
2852 	// register for savestates
2853 	save_item(NAME(m_cop_irq));
2854 }
2855 
2856 // handlers: maincpu side
2857 
update_display()2858 void eturtles_state::update_display()
2859 {
2860 	u16 grid = bitswap<16>(m_grid,15,1,14,13,12,11,10,9,8,7,6,5,4,3,2,0);
2861 	u32 plate = bitswap<32>(m_plate,31,30,11,12,18,19,16,17,22,15,20,21,27,26,23,25,24,2,3,1,0,6,4,5,10,9,2,8,7,14,1,13);
2862 	m_display->matrix(grid, plate | (grid >> 5 & 8)); // grid 8 also forces plate 3 high
2863 }
2864 
plate_w(offs_t offset,u8 data)2865 void eturtles_state::plate_w(offs_t offset, u8 data)
2866 {
2867 	m_r[offset] = data;
2868 
2869 	// R0x-R6x: vfd plate
2870 	int shift = offset * 4;
2871 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
2872 	update_display();
2873 }
2874 
grid_w(u16 data)2875 void eturtles_state::grid_w(u16 data)
2876 {
2877 	m_d = data;
2878 
2879 	// D1-D6: input mux
2880 	u8 inp_mux = data >> 1 & 0x3f;
2881 	if (inp_mux != m_inp_mux)
2882 	{
2883 		m_inp_mux = inp_mux;
2884 		update_int();
2885 	}
2886 
2887 	// D1-D15: vfd grid
2888 	m_grid = data >> 1 & 0x7fff;
2889 	update_display();
2890 }
2891 
update_int()2892 void eturtles_state::update_int()
2893 {
2894 	// INT0/1 on multiplexed inputs, and from COP D0
2895 	u8 inp = read_inputs(6);
2896 	set_interrupt(0, (inp & 1) | m_cop_irq);
2897 	set_interrupt(1, inp & 2);
2898 }
2899 
2900 // handlers: COP side
2901 
WRITE_LINE_MEMBER(eturtles_state::speaker_w)2902 WRITE_LINE_MEMBER(eturtles_state::speaker_w)
2903 {
2904 	// SK: speaker out
2905 	m_speaker->level_w(!state);
2906 }
2907 
cop_irq_w(u8 data)2908 void eturtles_state::cop_irq_w(u8 data)
2909 {
2910 	// D0: maincpu INT0 (active low)
2911 	m_cop_irq = ~data & 1;
2912 	update_int();
2913 }
2914 
cop_latch_r()2915 u8 eturtles_state::cop_latch_r()
2916 {
2917 	// L0-L3: soundlatch from maincpu R0x
2918 	return m_r[0];
2919 }
2920 
cop_ack_r()2921 u8 eturtles_state::cop_ack_r()
2922 {
2923 	// G0: ack from maincpu D0
2924 	return m_d & 1;
2925 }
2926 
2927 // config
2928 
2929 static INPUT_PORTS_START( eturtles )
2930 	PORT_START("IN.0") // D1 INT0/1
2931 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0)
2932 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_COCKTAIL PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0)
2933 
2934 	PORT_START("IN.1") // D2 INT0/1
2935 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0)
2936 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_COCKTAIL PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0)
2937 
2938 	PORT_START("IN.2") // D3 INT0/1
2939 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0)
2940 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_COCKTAIL PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0)
2941 
2942 	PORT_START("IN.3") // D4 INT0/1
2943 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0)
2944 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_COCKTAIL PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0)
2945 
2946 	PORT_START("IN.4") // D5 INT0/1
DEF_STR(Difficulty)2947 	PORT_CONFNAME( 0x01, 0x01, DEF_STR( Difficulty ) ) PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0)
2948 	PORT_CONFSETTING(    0x01, "1" )
2949 	PORT_CONFSETTING(    0x00, "2" )
2950 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0)
2951 
2952 	PORT_START("IN.5") // D6 INT0/1
2953 	PORT_CONFNAME( 0x03, 0x00, DEF_STR( Players ) ) PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0)
2954 	PORT_CONFSETTING(    0x02, "0 (Demo)" )
2955 	PORT_CONFSETTING(    0x00, "1" )
2956 	PORT_CONFSETTING(    0x01, "2" )
2957 INPUT_PORTS_END
2958 
2959 void eturtles_state::eturtles(machine_config &config)
2960 {
2961 	/* basic machine hardware */
2962 	HD38820(config, m_maincpu, 400000); // approximation
2963 	m_maincpu->write_r<0>().set(FUNC(eturtles_state::plate_w));
2964 	m_maincpu->write_r<1>().set(FUNC(eturtles_state::plate_w));
2965 	m_maincpu->write_r<2>().set(FUNC(eturtles_state::plate_w));
2966 	m_maincpu->write_r<3>().set(FUNC(eturtles_state::plate_w));
2967 	m_maincpu->write_r<4>().set(FUNC(eturtles_state::plate_w));
2968 	m_maincpu->write_r<5>().set(FUNC(eturtles_state::plate_w));
2969 	m_maincpu->write_r<6>().set(FUNC(eturtles_state::plate_w));
2970 	m_maincpu->write_d().set(FUNC(eturtles_state::grid_w));
2971 
2972 	COP411(config, m_audiocpu, 215000); // approximation
2973 	m_audiocpu->set_config(COP400_CKI_DIVISOR_4, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed
2974 	m_audiocpu->write_sk().set(FUNC(eturtles_state::speaker_w));
2975 	m_audiocpu->write_d().set(FUNC(eturtles_state::cop_irq_w));
2976 	m_audiocpu->read_l().set(FUNC(eturtles_state::cop_latch_r));
2977 	m_audiocpu->read_g().set(FUNC(eturtles_state::cop_ack_r));
2978 
2979 	config.set_perfect_quantum(m_maincpu);
2980 
2981 	/* video hardware */
2982 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
2983 	screen.set_refresh_hz(60);
2984 	screen.set_size(484, 1080);
2985 	screen.set_visarea_full();
2986 
2987 	PWM_DISPLAY(config, m_display).set_size(15, 30);
2988 
2989 	/* sound hardware */
2990 	SPEAKER(config, "mono").front_center();
2991 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
2992 }
2993 
2994 // roms
2995 
2996 ROM_START( eturtles )
2997 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
2998 	ROM_LOAD( "hd38820a43", 0x0000, 0x1000, CRC(446aa4e2) SHA1(d1c0fb14ea7081def53b1174964b39eed1e5d5e6) )
2999 	ROM_CONTINUE(           0x1e80, 0x0100 )
3000 
3001 	ROM_REGION( 0x0200, "audiocpu", 0 )
3002 	ROM_LOAD( "cop411l-ked_n", 0x0000, 0x0200, CRC(503d26e9) SHA1(a53d24d62195bfbceff2e4a43199846e0950aef6) )
3003 
3004 	ROM_REGION( 1027626, "screen", 0)
3005 	ROM_LOAD( "eturtles.svg", 0, 1027626, CRC(b4f7abff) SHA1(e9b065a3a3fef3c71495002945724a86c2a68eb4) )
3006 ROM_END
3007 
3008 
3009 
3010 
3011 
3012 /***************************************************************************
3013 
3014   Entex Stargate (manufactured in Japan)
3015   * PCB label 5603521/31
3016   * Hitachi QFP HD38820A42 MCU
3017   * COP411L sub MCU, label ~/B8236 COP411L-KEC/N
3018   * cyan/red/green VFD display NEC FIP15AM32T (EL628-003) no. 2-421, with partial color overlay
3019 
3020 ***************************************************************************/
3021 
3022 class estargte_state : public eturtles_state
3023 {
3024 public:
estargte_state(const machine_config & mconfig,device_type type,const char * tag)3025 	estargte_state(const machine_config &mconfig, device_type type, const char *tag) :
3026 		eturtles_state(mconfig, type, tag)
3027 	{ }
3028 
3029 	virtual void update_display() override;
3030 	u8 cop_data_r();
3031 	void estargte(machine_config &config);
3032 };
3033 
3034 // handlers (most of it is in eturtles_state above)
3035 
update_display()3036 void estargte_state::update_display()
3037 {
3038 	u16 grid = bitswap<16>(m_grid,15,0,14,13,12,11,10,9,8,7,6,5,4,3,2,1);
3039 	u32 plate = bitswap<32>(m_plate,31,30,29,15,17,19,21,23,25,27,26,24,3,22,20,18,16,14,12,10,8,6,4,2,0,1,3,5,7,9,11,13);
3040 	m_display->matrix(grid, plate);
3041 }
3042 
cop_data_r()3043 u8 estargte_state::cop_data_r()
3044 {
3045 	// L0-L3: soundlatch from maincpu R0x
3046 	// L7: ack from maincpu D0
3047 	return m_r[0] | (m_d << 7 & 0x80);
3048 }
3049 
3050 // config
3051 
3052 static INPUT_PORTS_START( estargte )
3053 	PORT_START("IN.0") // D1 INT0/1
3054 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0) PORT_NAME("Inviso")
3055 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0) PORT_NAME("Smart Bomb")
3056 
3057 	PORT_START("IN.1") // D2 INT0/1
3058 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0) PORT_NAME("Fire")
3059 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0) PORT_NAME("Change Direction")
3060 
3061 	PORT_START("IN.2") // D3 INT0/1
3062 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0)
3063 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0)
3064 
3065 	PORT_START("IN.3") // D4 INT0/1
3066 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0) PORT_NAME("Thrust")
3067 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
3068 
3069 	PORT_START("IN.4") // D5 INT0/1
DEF_STR(Players)3070 	PORT_CONFNAME( 0x01, 0x00, DEF_STR( Players ) ) PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0)
3071 	PORT_CONFSETTING(    0x00, "0 (Demo)" ) // yes, same value as 1-player, hold the Inviso button at boot to enter demo mode
3072 	PORT_CONFSETTING(    0x00, "1" )
3073 	PORT_CONFSETTING(    0x01, "2" )
3074 	PORT_CONFNAME( 0x02, 0x02, DEF_STR( Difficulty ) ) PORT_CHANGED_MEMBER(DEVICE_SELF, eturtles_state, input_changed, 0)
3075 	PORT_CONFSETTING(    0x00, "1" )
3076 	PORT_CONFSETTING(    0x02, "2" )
3077 
3078 	PORT_START("IN.5") // D6 INT0/1
3079 	PORT_BIT( 0x03, IP_ACTIVE_HIGH, IPT_UNUSED )
3080 INPUT_PORTS_END
3081 
3082 void estargte_state::estargte(machine_config &config)
3083 {
3084 	/* basic machine hardware */
3085 	HD38820(config, m_maincpu, 400000); // approximation
3086 	m_maincpu->write_r<0>().set(FUNC(eturtles_state::plate_w));
3087 	m_maincpu->write_r<1>().set(FUNC(eturtles_state::plate_w));
3088 	m_maincpu->write_r<2>().set(FUNC(eturtles_state::plate_w));
3089 	m_maincpu->write_r<3>().set(FUNC(eturtles_state::plate_w));
3090 	m_maincpu->write_r<4>().set(FUNC(eturtles_state::plate_w));
3091 	m_maincpu->write_r<5>().set(FUNC(eturtles_state::plate_w));
3092 	m_maincpu->write_r<6>().set(FUNC(eturtles_state::plate_w));
3093 	m_maincpu->write_d().set(FUNC(eturtles_state::grid_w));
3094 
3095 	COP411(config, m_audiocpu, 190000); // approximation
3096 	m_audiocpu->set_config(COP400_CKI_DIVISOR_4, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed
3097 	m_audiocpu->write_sk().set(FUNC(eturtles_state::speaker_w));
3098 	m_audiocpu->write_d().set(FUNC(eturtles_state::cop_irq_w));
3099 	m_audiocpu->read_l().set(FUNC(estargte_state::cop_data_r));
3100 
3101 	config.set_perfect_quantum(m_maincpu);
3102 
3103 	/* video hardware */
3104 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
3105 	screen.set_refresh_hz(60);
3106 	screen.set_size(1920, 854);
3107 	screen.set_visarea_full();
3108 
3109 	PWM_DISPLAY(config, m_display).set_size(14, 29);
3110 
3111 	/* sound hardware */
3112 	SPEAKER(config, "mono").front_center();
3113 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
3114 }
3115 
3116 // roms
3117 
3118 ROM_START( estargte )
3119 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
3120 	ROM_LOAD( "hd38820a42", 0x0000, 0x1000, CRC(5f6d55a6) SHA1(0da32149790fa5f16097338fc80536b462169e0c) )
3121 	ROM_CONTINUE(           0x1e80, 0x0100 )
3122 
3123 	ROM_REGION( 0x0200, "audiocpu", 0 )
3124 	ROM_LOAD( "cop411l-kec_n", 0x0000, 0x0200, CRC(fbd3c2d3) SHA1(65b8b24d38678c3fa970bfd639e9449a75a28927) )
3125 
3126 	ROM_REGION( 462214, "screen", 0)
3127 	ROM_LOAD( "estargte.svg", 0, 462214, CRC(282cc090) SHA1(b0f3c21e9a529e5f1e33b90ca25ce3a097fb75a0) )
3128 ROM_END
3129 
3130 
3131 
3132 
3133 
3134 /***************************************************************************
3135 
3136   Gakken Heiankyo Alien (manufactured in Japan)
3137   * Hitachi HD38800A04 MCU
3138   * cyan/red VFD display Futaba DM-11Z 1H
3139 
3140   known releases:
3141   - Japan: Heiankyo Alien
3142   - USA: Earth Invaders, published by CGL
3143 
3144 ***************************************************************************/
3145 
3146 class ghalien_state : public hh_hmcs40_state
3147 {
3148 public:
ghalien_state(const machine_config & mconfig,device_type type,const char * tag)3149 	ghalien_state(const machine_config &mconfig, device_type type, const char *tag) :
3150 		hh_hmcs40_state(mconfig, type, tag)
3151 	{ }
3152 
3153 	void plate_w(offs_t offset, u8 data);
3154 	void grid_w(u16 data);
3155 	u16 input_r();
3156 	void ghalien(machine_config &config);
3157 };
3158 
3159 // handlers
3160 
plate_w(offs_t offset,u8 data)3161 void ghalien_state::plate_w(offs_t offset, u8 data)
3162 {
3163 	// R0x-R3x(,D10-D13): vfd plate
3164 	int shift = offset * 4;
3165 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
3166 
3167 	// update display
3168 	u16 grid = bitswap<16>(m_grid,15,14,13,12,11,10,0,1,2,3,4,5,6,7,8,9);
3169 	u32 plate = bitswap<24>(m_plate,23,22,21,20,14,12,10,8,9,13,15,2,0,1,3,11,7,5,4,6,19,17,16,18);
3170 	m_display->matrix(grid, plate);
3171 }
3172 
grid_w(u16 data)3173 void ghalien_state::grid_w(u16 data)
3174 {
3175 	// D14: speaker out
3176 	m_speaker->level_w(data >> 14 & 1);
3177 
3178 	// D0-D6: input mux
3179 	m_inp_mux = data & 0x7f;
3180 
3181 	// D0-D9: vfd grid
3182 	m_grid = data & 0x3ff;
3183 
3184 	// D10-D13: more plates (update display there)
3185 	plate_w(4, data >> 10 & 0xf);
3186 }
3187 
input_r()3188 u16 ghalien_state::input_r()
3189 {
3190 	// D15: multiplexed inputs
3191 	return read_inputs(7) & 0x8000;
3192 }
3193 
3194 // config
3195 
3196 static INPUT_PORTS_START( ghalien )
3197 	PORT_START("IN.0") // D0 line D15
3198 	PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_16WAY
3199 
3200 	PORT_START("IN.1") // D1 line D15
3201 	PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_16WAY
3202 
3203 	PORT_START("IN.2") // D2 line D15
3204 	PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_16WAY
3205 
3206 	PORT_START("IN.3") // D3 line D15
3207 	PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_16WAY
3208 
3209 	PORT_START("IN.4") // D4 line D15
3210 	PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Dig")
3211 
3212 	PORT_START("IN.5") // D5 line D15
3213 	PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Bury")
3214 
3215 	PORT_START("IN.6") // D6 line D15
DEF_STR(Difficulty)3216 	PORT_CONFNAME( 0x8000, 0x0000, DEF_STR( Difficulty ) )
3217 	PORT_CONFSETTING(      0x0000, "Amateur" )
3218 	PORT_CONFSETTING(      0x8000, "Professional" )
3219 INPUT_PORTS_END
3220 
3221 void ghalien_state::ghalien(machine_config &config)
3222 {
3223 	/* basic machine hardware */
3224 	HD38800(config, m_maincpu, 400000); // approximation
3225 	m_maincpu->write_r<0>().set(FUNC(ghalien_state::plate_w));
3226 	m_maincpu->write_r<1>().set(FUNC(ghalien_state::plate_w));
3227 	m_maincpu->write_r<2>().set(FUNC(ghalien_state::plate_w));
3228 	m_maincpu->write_r<3>().set(FUNC(ghalien_state::plate_w));
3229 	m_maincpu->write_d().set(FUNC(ghalien_state::grid_w));
3230 	m_maincpu->read_d().set(FUNC(ghalien_state::input_r));
3231 
3232 	/* video hardware */
3233 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
3234 	screen.set_refresh_hz(60);
3235 	screen.set_size(1920, 699);
3236 	screen.set_visarea_full();
3237 
3238 	PWM_DISPLAY(config, m_display).set_size(10, 20);
3239 
3240 	/* sound hardware */
3241 	SPEAKER(config, "mono").front_center();
3242 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
3243 }
3244 
3245 // roms
3246 
3247 ROM_START( ghalien )
3248 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
3249 	ROM_LOAD( "hd38800a04", 0x0000, 0x1000, CRC(019c3328) SHA1(9f1029c5c479f78350952c4f18747341ba5ea7a0) )
3250 	ROM_CONTINUE(           0x1e80, 0x0100 )
3251 
3252 	ROM_REGION( 462749, "screen", 0)
3253 	ROM_LOAD( "ghalien.svg", 0, 462749, CRC(1acbb1e8) SHA1(7bdeb840bc9080792e24812eba923bf84f7865a6) )
3254 ROM_END
3255 
3256 
3257 
3258 
3259 
3260 /***************************************************************************
3261 
3262   Gakken Crazy Kong (manufactured in Japan)
3263   * PCB label ZENY 5603601
3264   * Hitachi HD38800B01 MCU
3265   * cyan/red/blue VFD display Futaba DM-54Z 2H, with bezel overlay
3266 
3267   known releases:
3268   - Japan: Crazy Kong
3269   - USA: Super Kong, published by CGL
3270 
3271 ***************************************************************************/
3272 
3273 class gckong_state : public hh_hmcs40_state
3274 {
3275 public:
gckong_state(const machine_config & mconfig,device_type type,const char * tag)3276 	gckong_state(const machine_config &mconfig, device_type type, const char *tag) :
3277 		hh_hmcs40_state(mconfig, type, tag)
3278 	{ }
3279 
3280 	void plate_w(offs_t offset, u8 data);
3281 	void grid_w(u16 data);
3282 
3283 	void update_int1();
DECLARE_INPUT_CHANGED_MEMBER(input_changed)3284 	DECLARE_INPUT_CHANGED_MEMBER(input_changed) { update_int1(); }
3285 	void gckong(machine_config &config);
3286 };
3287 
3288 // handlers
3289 
plate_w(offs_t offset,u8 data)3290 void gckong_state::plate_w(offs_t offset, u8 data)
3291 {
3292 	// R0x-R3x(,D0,D1): vfd plate
3293 	int shift = offset * 4;
3294 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
3295 
3296 	// update display
3297 	u16 grid = bitswap<16>(m_grid,15,14,13,12,11,0,1,2,3,4,5,6,7,8,9,10);
3298 	u32 plate = bitswap<32>(m_plate,31,30,29,28,27,26,25,6,7,8,12,13,14,15,16,17,18,17,16,12,11,10,9,8,7,6,5,4,3,2,1,0) | 0x8000;
3299 	m_display->matrix(grid, plate);
3300 }
3301 
grid_w(u16 data)3302 void gckong_state::grid_w(u16 data)
3303 {
3304 	// D2: speaker out
3305 	m_speaker->level_w(data >> 2 & 1);
3306 
3307 	// D5-D8: input mux
3308 	u8 inp_mux = data >> 5 & 0xf;
3309 	if (inp_mux != m_inp_mux)
3310 	{
3311 		m_inp_mux = inp_mux;
3312 		update_int1();
3313 	}
3314 
3315 	// D5-D15: vfd grid
3316 	m_grid = data >> 5 & 0x7ff;
3317 
3318 	// D0,D1: more plates (update display there)
3319 	plate_w(4, data & 3);
3320 }
3321 
update_int1()3322 void gckong_state::update_int1()
3323 {
3324 	// INT1 on multiplexed inputs
3325 	set_interrupt(1, read_inputs(4));
3326 }
3327 
3328 // config
3329 
3330 static INPUT_PORTS_START( gckong )
3331 	PORT_START("IN.0") // D5 INT1
3332 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_CHANGED_MEMBER(DEVICE_SELF, gckong_state, input_changed, 0)
3333 
3334 	PORT_START("IN.1") // D6 INT1
3335 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, gckong_state, input_changed, 0)
3336 
3337 	PORT_START("IN.2") // D7 INT1
3338 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_CHANGED_MEMBER(DEVICE_SELF, gckong_state, input_changed, 0)
3339 
3340 	PORT_START("IN.3") // D8 INT1
3341 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_CHANGED_MEMBER(DEVICE_SELF, gckong_state, input_changed, 0)
3342 
3343 	PORT_START("IN.4") // INT0
3344 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_hmcs40_state, single_interrupt_line, 0)
3345 
3346 	PORT_START("IN.5") // port D
DEF_STR(Difficulty)3347 	PORT_CONFNAME( 0x0010, 0x0000, DEF_STR( Difficulty ) )
3348 	PORT_CONFSETTING(      0x0000, "A" )
3349 	PORT_CONFSETTING(      0x0010, "B" )
3350 	PORT_BIT( 0xffef, IP_ACTIVE_HIGH, IPT_UNUSED )
3351 INPUT_PORTS_END
3352 
3353 void gckong_state::gckong(machine_config &config)
3354 {
3355 	/* basic machine hardware */
3356 	HD38800(config, m_maincpu, 400000); // approximation
3357 	m_maincpu->write_r<0>().set(FUNC(gckong_state::plate_w));
3358 	m_maincpu->write_r<1>().set(FUNC(gckong_state::plate_w));
3359 	m_maincpu->write_r<2>().set(FUNC(gckong_state::plate_w));
3360 	m_maincpu->write_r<3>().set(FUNC(gckong_state::plate_w));
3361 	m_maincpu->write_d().set(FUNC(gckong_state::grid_w));
3362 	m_maincpu->read_d().set_ioport("IN.5");
3363 
3364 	/* video hardware */
3365 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
3366 	screen.set_refresh_hz(60);
3367 	screen.set_size(479, 1080);
3368 	screen.set_visarea_full();
3369 
3370 	PWM_DISPLAY(config, m_display).set_size(11, 32);
3371 	config.set_default_layout(layout_gckong);
3372 
3373 	/* sound hardware */
3374 	SPEAKER(config, "mono").front_center();
3375 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
3376 }
3377 
3378 // roms
3379 
3380 ROM_START( gckong )
3381 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
3382 	ROM_LOAD( "hd38800b01", 0x0000, 0x1000, CRC(d5a2cca3) SHA1(37bb5784383daab672ed1e0e2362c7a40d8d9b3f) )
3383 	ROM_CONTINUE(           0x1e80, 0x0100 )
3384 
3385 	ROM_REGION( 346588, "screen", 0)
3386 	ROM_LOAD( "gckong.svg", 0, 346588, CRC(317af984) SHA1(ff6323526d1f5e46eccf8fa8d979175895be75de) )
3387 ROM_END
3388 
3389 
3390 
3391 
3392 
3393 /***************************************************************************
3394 
3395   Gakken Dig Dug (manufactured in Japan)
3396   * PCB label Gakken DIG-DAG KS-004283(A/B)
3397   * Hitachi QFP HD38820A69 MCU
3398   * cyan/red/green VFD display Futaba DM-69Z 3F, with color overlay
3399 
3400 ***************************************************************************/
3401 
3402 class gdigdug_state : public hh_hmcs40_state
3403 {
3404 public:
gdigdug_state(const machine_config & mconfig,device_type type,const char * tag)3405 	gdigdug_state(const machine_config &mconfig, device_type type, const char *tag) :
3406 		hh_hmcs40_state(mconfig, type, tag)
3407 	{ }
3408 
3409 	void plate_w(offs_t offset, u8 data);
3410 	void grid_w(u16 data);
3411 
3412 	void update_int1();
DECLARE_INPUT_CHANGED_MEMBER(input_changed)3413 	DECLARE_INPUT_CHANGED_MEMBER(input_changed) { update_int1(); }
3414 	void gdigdug(machine_config &config);
3415 };
3416 
3417 // handlers
3418 
plate_w(offs_t offset,u8 data)3419 void gdigdug_state::plate_w(offs_t offset, u8 data)
3420 {
3421 	// R0x-R6x(,D0-D3): vfd plate
3422 	int shift = offset * 4;
3423 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
3424 
3425 	// update display
3426 	u32 plate = bitswap<32>(m_plate,30,31,0,1,2,3,4,5,6,7,20,21,22,27,26,25,28,29,24,23,15,14,13,12,8,9,10,11,19,18,17,16);
3427 	m_display->matrix(m_grid, plate);
3428 }
3429 
grid_w(u16 data)3430 void gdigdug_state::grid_w(u16 data)
3431 {
3432 	// D6: speaker out
3433 	m_speaker->level_w(data >> 6 & 1);
3434 
3435 	// D11-D15: input mux
3436 	u8 inp_mux = data >> 11 & 0x1f;
3437 	if (inp_mux != m_inp_mux)
3438 	{
3439 		m_inp_mux = inp_mux;
3440 		update_int1();
3441 	}
3442 
3443 	// D7-D15: vfd grid
3444 	m_grid = data >> 7 & 0x1ff;
3445 
3446 	// D0-D3: more plates (update display there)
3447 	plate_w(7, data & 0xf);
3448 }
3449 
update_int1()3450 void gdigdug_state::update_int1()
3451 {
3452 	// INT1 on multiplexed inputs
3453 	set_interrupt(1, read_inputs(5));
3454 }
3455 
3456 // config
3457 
3458 static INPUT_PORTS_START( gdigdug )
3459 	PORT_START("IN.0") // D11 INT1
3460 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_CHANGED_MEMBER(DEVICE_SELF, gdigdug_state, input_changed, 0)
3461 
3462 	PORT_START("IN.1") // D12 INT1
3463 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, gdigdug_state, input_changed, 0)
3464 
3465 	PORT_START("IN.2") // D13 INT1
3466 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_CHANGED_MEMBER(DEVICE_SELF, gdigdug_state, input_changed, 0)
3467 
3468 	PORT_START("IN.3") // D14 INT1
3469 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_CHANGED_MEMBER(DEVICE_SELF, gdigdug_state, input_changed, 0)
3470 
3471 	PORT_START("IN.4") // D15 INT1
3472 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_CHANGED_MEMBER(DEVICE_SELF, gdigdug_state, input_changed, 0)
3473 
3474 	PORT_START("IN.5") // INT0
3475 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_hmcs40_state, single_interrupt_line, 0)
3476 INPUT_PORTS_END
3477 
gdigdug(machine_config & config)3478 void gdigdug_state::gdigdug(machine_config &config)
3479 {
3480 	/* basic machine hardware */
3481 	HD38820(config, m_maincpu, 400000); // approximation
3482 	m_maincpu->write_r<0>().set(FUNC(gdigdug_state::plate_w));
3483 	m_maincpu->write_r<1>().set(FUNC(gdigdug_state::plate_w));
3484 	m_maincpu->write_r<2>().set(FUNC(gdigdug_state::plate_w));
3485 	m_maincpu->write_r<3>().set(FUNC(gdigdug_state::plate_w));
3486 	m_maincpu->write_r<4>().set(FUNC(gdigdug_state::plate_w));
3487 	m_maincpu->write_r<5>().set(FUNC(gdigdug_state::plate_w));
3488 	m_maincpu->write_r<6>().set(FUNC(gdigdug_state::plate_w));
3489 	m_maincpu->write_d().set(FUNC(gdigdug_state::grid_w));
3490 
3491 	/* video hardware */
3492 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
3493 	screen.set_refresh_hz(60);
3494 	screen.set_size(476, 1080);
3495 	screen.set_visarea_full();
3496 
3497 	PWM_DISPLAY(config, m_display).set_size(9, 32);
3498 
3499 	/* sound hardware */
3500 	SPEAKER(config, "mono").front_center();
3501 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
3502 }
3503 
3504 // roms
3505 
3506 ROM_START( gdigdug )
3507 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
3508 	ROM_LOAD( "hd38820a69", 0x0000, 0x1000, CRC(501165a9) SHA1(8a15d00c4aa66e870cadde33148426463560d2e6) )
3509 	ROM_CONTINUE(           0x1e80, 0x0100 )
3510 
3511 	ROM_REGION( 807990, "screen", 0)
3512 	ROM_LOAD( "gdigdug.svg", 0, 807990, CRC(a5b8392d) SHA1(3503829bb1a626a9e70115fb60b656dff8908144) )
3513 ROM_END
3514 
3515 
3516 
3517 
3518 
3519 /***************************************************************************
3520 
3521   Mattel World Championship Baseball
3522   * PCB label MEL-001 Baseball Rev. B
3523   * Hitachi QFP HD38820A09 MCU
3524   * cyan/red/green VFD display Futaba DM-24ZK 1G, with etched overlay
3525 
3526   To start the game in 2-player mode, simply turn the game on. For 1-player,
3527   turn the game on while holding the 1-key and use the visitor's side keypad
3528   to play offsense.
3529 
3530 ***************************************************************************/
3531 
3532 class mwcbaseb_state : public hh_hmcs40_state
3533 {
3534 public:
mwcbaseb_state(const machine_config & mconfig,device_type type,const char * tag)3535 	mwcbaseb_state(const machine_config &mconfig, device_type type, const char *tag) :
3536 		hh_hmcs40_state(mconfig, type, tag)
3537 	{ }
3538 
3539 	void update_display();
3540 	void plate_w(offs_t offset, u8 data);
3541 	void grid_w(u16 data);
3542 	void speaker_w(u8 data);
3543 	u8 input_r();
3544 	void mwcbaseb(machine_config &config);
3545 };
3546 
3547 // handlers
3548 
update_display()3549 void mwcbaseb_state::update_display()
3550 {
3551 	u8 grid = bitswap<8>(m_grid,0,1,2,3,4,5,6,7);
3552 	m_display->matrix(grid, m_plate);
3553 }
3554 
plate_w(offs_t offset,u8 data)3555 void mwcbaseb_state::plate_w(offs_t offset, u8 data)
3556 {
3557 	// R1x-R3x,R6x: vfd plate
3558 	int shift = (offset == 6) ? 12 : (offset - 1) * 4;
3559 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
3560 	update_display();
3561 }
3562 
grid_w(u16 data)3563 void mwcbaseb_state::grid_w(u16 data)
3564 {
3565 	// D9-D15: input mux
3566 	m_inp_mux = data >> 9 & 0x7f;
3567 
3568 	// D0-D7: vfd grid
3569 	m_grid = data & 0xff;
3570 	update_display();
3571 }
3572 
speaker_w(u8 data)3573 void mwcbaseb_state::speaker_w(u8 data)
3574 {
3575 	// R50,R51+R52(tied together): speaker out
3576 	m_speaker->level_w(data & 7);
3577 }
3578 
input_r()3579 u8 mwcbaseb_state::input_r()
3580 {
3581 	// R4x: multiplexed inputs
3582 	return read_inputs(7);
3583 }
3584 
3585 // config
3586 
3587 /* physical button layout and labels is like this:
3588 
3589         (visitor team side)                                       (home team side)
3590     COMP PITCH                     [SCORE]       [INNING]
3591     [1]      [2]      [3]                                     [1]      [2]      [3]
3592     NEW PITCHER       PINCH HITTER                            NEW PITCHER       PINCH HITTER
3593 
3594     [4]      [5]      [6]                                     [4]      [5]      [6]
3595     BACKWARD (pitch)  FORWARD                                 BACKWARD (pitch)  FORWARD
3596 
3597     [7]      [8]      [9]                                     [7]      [8]      [9]
3598 
3599     BUNT     NORMAL   HR SWING                                BUNT     NORMAL   HR SWING
3600     [CLEAR]  [0]      [ENTER]                                 [CLEAR]  [0]      [ENTER]
3601     SLOW     CURVE    FAST                                    SLOW     CURVE    FAST
3602 */
3603 
3604 static INPUT_PORTS_START( mwcbaseb )
3605 	PORT_START("IN.0") // D9 port R4x
PORT_CODE(KEYCODE_Y)3606 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Y) PORT_NAME("P2 4") // note: P1 = left/visitor, P2 = right/home
3607 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_NAME("P2 3")
3608 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_NAME("P2 2")
3609 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_NAME("P2 1")
3610 
3611 	PORT_START("IN.1") // D10 port R4x
3612 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_J) PORT_NAME("P2 8")
3613 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_H) PORT_NAME("P2 7")
3614 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_I) PORT_NAME("P2 6")
3615 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_U) PORT_NAME("P2 5")
3616 
3617 	PORT_START("IN.2") // D11 port R4x
3618 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_COMMA) PORT_NAME("P2 Enter")
3619 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_N) PORT_NAME("P2 Clear")
3620 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_M) PORT_NAME("P2 0")
3621 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_K) PORT_NAME("P2 9")
3622 
3623 	PORT_START("IN.3") // D12 port R4x
3624 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_T) PORT_NAME("Inning")
3625 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
3626 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
3627 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) PORT_NAME("Score")
3628 
3629 	PORT_START("IN.4") // D13 port R4x
3630 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_C) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("P1 Enter")
3631 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Z) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("P1 Clear")
3632 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_X) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("P1 0")
3633 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_D) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("P1 9")
3634 
3635 	PORT_START("IN.5") // D14 port R4x
3636 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_S) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("P1 8")
3637 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_A) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("P1 7")
3638 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("P1 6")
3639 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_W) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("P1 5")
3640 
3641 	PORT_START("IN.6") // D15 port R4x
3642 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Q) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("P1 4")
3643 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("P1 3")
3644 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("P1 2")
3645 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("P1 1")
3646 INPUT_PORTS_END
3647 
3648 void mwcbaseb_state::mwcbaseb(machine_config &config)
3649 {
3650 	/* basic machine hardware */
3651 	HD38820(config, m_maincpu, 400000); // approximation
3652 	m_maincpu->write_r<1>().set(FUNC(mwcbaseb_state::plate_w));
3653 	m_maincpu->write_r<2>().set(FUNC(mwcbaseb_state::plate_w));
3654 	m_maincpu->write_r<3>().set(FUNC(mwcbaseb_state::plate_w));
3655 	m_maincpu->read_r<4>().set(FUNC(mwcbaseb_state::input_r));
3656 	m_maincpu->write_r<5>().set(FUNC(mwcbaseb_state::speaker_w));
3657 	m_maincpu->write_r<6>().set(FUNC(mwcbaseb_state::plate_w));
3658 	m_maincpu->write_d().set(FUNC(mwcbaseb_state::grid_w));
3659 
3660 	/* video hardware */
3661 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
3662 	screen.set_refresh_hz(60);
3663 	screen.set_size(1920, 478);
3664 	screen.set_visarea_full();
3665 
3666 	PWM_DISPLAY(config, m_display).set_size(8, 16);
3667 	m_display->set_bri_levels(0.001); // cyan elements strobed very briefly?
3668 	config.set_default_layout(layout_mwcbaseb);
3669 
3670 	/* sound hardware */
3671 	SPEAKER(config, "mono").front_center();
3672 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
3673 	static const double speaker_levels[] = { 0.0, 0.5, -0.5, 0.0, -0.5, 0.0, -1.0, -0.5 };
3674 	m_speaker->set_levels(8, speaker_levels);
3675 }
3676 
3677 // roms
3678 
3679 ROM_START( mwcbaseb )
3680 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
3681 	ROM_LOAD( "hd38820a09", 0x0000, 0x1000, CRC(25ba7dc0) SHA1(69e0a867fdcf07b454b1faf835e576ae782432c0) )
3682 	ROM_CONTINUE(           0x1e80, 0x0100 )
3683 
3684 	ROM_REGION( 178441, "screen", 0)
3685 	ROM_LOAD( "mwcbaseb.svg", 0, 178441, CRC(0f631190) SHA1(74a10ad0630af5516f76d5bf5628483d21f6b7be) )
3686 ROM_END
3687 
3688 
3689 
3690 
3691 
3692 /***************************************************************************
3693 
3694   Mattel Star Hawk (manufactured in Japan)
3695   * PCB label Kaken, PT-317B
3696   * Hitachi HD38800A73 MCU
3697   * cyan/red VFD display Futaba DM-41ZK, with partial color overlay + bezel
3698 
3699   Before release, it was advertised as "Space Battle"(a Mattel Intellivision game).
3700   Kaken was a subsidiary of Bandai. Star Hawk shell design is the same as Bandai's
3701   games from the same era. It's likely that this was made under contract exclusively
3702   for Mattel. There is no indication that this game was released in Japan by Bandai.
3703 
3704 ***************************************************************************/
3705 
3706 class msthawk_state : public hh_hmcs40_state
3707 {
3708 public:
msthawk_state(const machine_config & mconfig,device_type type,const char * tag)3709 	msthawk_state(const machine_config &mconfig, device_type type, const char *tag) :
3710 		hh_hmcs40_state(mconfig, type, tag)
3711 	{ }
3712 
3713 	void update_display();
3714 	void plate_w(offs_t offset, u8 data);
3715 	void grid_w(u16 data);
3716 
3717 	void update_int0();
DECLARE_INPUT_CHANGED_MEMBER(input_changed)3718 	DECLARE_INPUT_CHANGED_MEMBER(input_changed) { update_int0(); }
3719 	void msthawk(machine_config &config);
3720 };
3721 
3722 // handlers
3723 
update_display()3724 void msthawk_state::update_display()
3725 {
3726 	u16 grid = bitswap<16>(m_grid,15,14,13,12,11,10,0,1,2,3,4,5,6,7,8,9);
3727 	u32 plate = bitswap<24>(m_plate,23,22,21,19,20,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
3728 	m_display->matrix(grid, plate);
3729 }
3730 
plate_w(offs_t offset,u8 data)3731 void msthawk_state::plate_w(offs_t offset, u8 data)
3732 {
3733 	// R0x-R3x: vfd plate
3734 	int shift = offset * 4;
3735 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
3736 	update_display();
3737 }
3738 
grid_w(u16 data)3739 void msthawk_state::grid_w(u16 data)
3740 {
3741 	// D5: speaker out
3742 	m_speaker->level_w(data >> 5 & 1);
3743 
3744 	// D10-D15: input mux
3745 	u8 inp_mux = data >> 10 & 0x3f;
3746 	if (inp_mux != m_inp_mux)
3747 	{
3748 		m_inp_mux = inp_mux;
3749 		update_int0();
3750 	}
3751 
3752 	// D6-D15: vfd grid
3753 	m_grid = data >> 6 & 0x3ff;
3754 
3755 	// D0-D4: more plates
3756 	m_plate = (m_plate & 0x00ffff) | (data << 16 & 0x1f0000);
3757 	update_display();
3758 }
3759 
update_int0()3760 void msthawk_state::update_int0()
3761 {
3762 	// INT0 on multiplexed inputs
3763 	set_interrupt(0, read_inputs(6));
3764 }
3765 
3766 // config
3767 
3768 static INPUT_PORTS_START( msthawk )
3769 	PORT_START("IN.0") // D10 INT0
3770 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_CHANGED_MEMBER(DEVICE_SELF, msthawk_state, input_changed, 0) PORT_NAME("Score")
3771 
3772 	PORT_START("IN.1") // D11 INT0
3773 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, msthawk_state, input_changed, 0) PORT_NAME("Land")
3774 
3775 	PORT_START("IN.2") // D12 INT0
3776 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_CHANGED_MEMBER(DEVICE_SELF, msthawk_state, input_changed, 0)
3777 
3778 	PORT_START("IN.3") // D13 INT0
3779 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_CHANGED_MEMBER(DEVICE_SELF, msthawk_state, input_changed, 0)
3780 
3781 	PORT_START("IN.4") // D14 INT0
3782 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, msthawk_state, input_changed, 0)
3783 
3784 	PORT_START("IN.5") // D15 INT0
3785 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_CHANGED_MEMBER(DEVICE_SELF, msthawk_state, input_changed, 0)
3786 
3787 	PORT_START("IN.6") // INT1
3788 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_hmcs40_state, single_interrupt_line, 1) PORT_NAME("Fire")
3789 INPUT_PORTS_END
3790 
msthawk(machine_config & config)3791 void msthawk_state::msthawk(machine_config &config)
3792 {
3793 	/* basic machine hardware */
3794 	HD38800(config, m_maincpu, 400000); // approximation
3795 	m_maincpu->write_r<0>().set(FUNC(msthawk_state::plate_w));
3796 	m_maincpu->write_r<1>().set(FUNC(msthawk_state::plate_w));
3797 	m_maincpu->write_r<2>().set(FUNC(msthawk_state::plate_w));
3798 	m_maincpu->write_r<3>().set(FUNC(msthawk_state::plate_w));
3799 	m_maincpu->write_d().set(FUNC(msthawk_state::grid_w));
3800 
3801 	/* video hardware */
3802 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
3803 	screen.set_refresh_hz(60);
3804 	screen.set_size(1920, 696);
3805 	screen.set_visarea_full();
3806 
3807 	PWM_DISPLAY(config, m_display).set_size(10, 21);
3808 	config.set_default_layout(layout_msthawk);
3809 
3810 	/* sound hardware */
3811 	SPEAKER(config, "mono").front_center();
3812 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
3813 }
3814 
3815 // roms
3816 
3817 ROM_START( msthawk )
3818 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
3819 	ROM_LOAD( "hd38800a73", 0x0000, 0x1000, CRC(a4f9a523) SHA1(465f06b02e2e7d2277218fd447830725790a816c) )
3820 	ROM_CONTINUE(           0x1e80, 0x0100 )
3821 
3822 	ROM_REGION( 191888, "screen", 0)
3823 	ROM_LOAD( "msthawk.svg", 0, 191888, CRC(a607fc0f) SHA1(282a412f6462128e09ee8bd18d682dda01297611) )
3824 ROM_END
3825 
3826 
3827 
3828 
3829 
3830 /***************************************************************************
3831 
3832   Parker Brothers Q*Bert
3833   * PCB label 13662 REV-4
3834   * Hitachi QFP HD38820A70 MCU
3835   * cyan/red/green/darkgreen VFD display Itron CP5137
3836 
3837 ***************************************************************************/
3838 
3839 class pbqbert_state : public hh_hmcs40_state
3840 {
3841 public:
pbqbert_state(const machine_config & mconfig,device_type type,const char * tag)3842 	pbqbert_state(const machine_config &mconfig, device_type type, const char *tag) :
3843 		hh_hmcs40_state(mconfig, type, tag)
3844 	{ }
3845 
3846 	void plate_w(offs_t offset, u8 data);
3847 	void grid_w(u16 data);
3848 	void pbqbert(machine_config &config);
3849 };
3850 
3851 // handlers
3852 
plate_w(offs_t offset,u8 data)3853 void pbqbert_state::plate_w(offs_t offset, u8 data)
3854 {
3855 	// R0x-R6x(,D8): vfd plate
3856 	int shift = offset * 4;
3857 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
3858 
3859 	// update display
3860 	u32 plate = bitswap<32>(m_plate,31,30,24,25,26,27,28,15,14,29,13,12,11,10,9,8,7,6,5,4,3,2,1,0,16,17,18,19,20,21,22,23) | 0x400000;
3861 	m_display->matrix(m_grid, plate);
3862 }
3863 
grid_w(u16 data)3864 void pbqbert_state::grid_w(u16 data)
3865 {
3866 	// D14: speaker out
3867 	m_speaker->level_w(data >> 14 & 1);
3868 
3869 	// D0-D7: vfd grid
3870 	m_grid = data & 0xff;
3871 
3872 	// D8: plate 25 (update display there)
3873 	plate_w(7, data >> 8 & 1);
3874 }
3875 
3876 // config
3877 
3878 static INPUT_PORTS_START( pbqbert )
3879 	PORT_START("IN.0") // port D
3880 	PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) // up-left
3881 	PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) // up-right
3882 	PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) // down-right
3883 	PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) // down-left
3884 	PORT_BIT( 0xe1ff, IP_ACTIVE_HIGH, IPT_UNUSED )
3885 INPUT_PORTS_END
3886 
pbqbert(machine_config & config)3887 void pbqbert_state::pbqbert(machine_config &config)
3888 {
3889 	/* basic machine hardware */
3890 	HD38820(config, m_maincpu, 400000); // approximation
3891 	m_maincpu->write_r<0>().set(FUNC(pbqbert_state::plate_w));
3892 	m_maincpu->write_r<1>().set(FUNC(pbqbert_state::plate_w));
3893 	m_maincpu->write_r<2>().set(FUNC(pbqbert_state::plate_w));
3894 	m_maincpu->write_r<3>().set(FUNC(pbqbert_state::plate_w));
3895 	m_maincpu->write_r<4>().set(FUNC(pbqbert_state::plate_w));
3896 	m_maincpu->write_r<5>().set(FUNC(pbqbert_state::plate_w));
3897 	m_maincpu->write_r<6>().set(FUNC(pbqbert_state::plate_w));
3898 	m_maincpu->write_d().set(FUNC(pbqbert_state::grid_w));
3899 	m_maincpu->read_d().set_ioport("IN.0");
3900 
3901 	/* video hardware */
3902 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
3903 	screen.set_refresh_hz(60);
3904 	screen.set_size(603, 1080);
3905 	screen.set_visarea_full();
3906 
3907 	PWM_DISPLAY(config, m_display).set_size(8, 30);
3908 
3909 	/* sound hardware */
3910 	SPEAKER(config, "mono").front_center();
3911 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
3912 }
3913 
3914 // roms
3915 
3916 ROM_START( pbqbert )
3917 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
3918 	ROM_LOAD( "hd38820a70", 0x0000, 0x1000, CRC(be7c80b4) SHA1(0617a80ef7fe188ea221de32e760d45fd4318c67) )
3919 	ROM_CONTINUE(           0x1e80, 0x0100 )
3920 
3921 	ROM_REGION( 456567, "screen", 0)
3922 	ROM_LOAD( "pbqbert.svg", 0, 456567, CRC(49853a62) SHA1(869377109fb7163e5ef5efadb26ce3955231f6ca) )
3923 ROM_END
3924 
3925 
3926 
3927 
3928 
3929 /***************************************************************************
3930 
3931   Tomy(tronic) Tron (manufactured in Japan)
3932   * PCB label THN-02 2E114E07
3933   * Hitachi HD38800A88 MCU
3934   * cyan/red/green VFD display NEC FIP10AM24T no. 2-8 1
3935 
3936 ***************************************************************************/
3937 
3938 class tmtron_state : public hh_hmcs40_state
3939 {
3940 public:
tmtron_state(const machine_config & mconfig,device_type type,const char * tag)3941 	tmtron_state(const machine_config &mconfig, device_type type, const char *tag) :
3942 		hh_hmcs40_state(mconfig, type, tag)
3943 	{ }
3944 
3945 	void update_display();
3946 	void plate_w(offs_t offset, u8 data);
3947 	void grid_w(u16 data);
3948 
3949 	void update_int1();
DECLARE_INPUT_CHANGED_MEMBER(input_changed)3950 	DECLARE_INPUT_CHANGED_MEMBER(input_changed) { update_int1(); }
3951 	void tmtron(machine_config &config);
3952 };
3953 
3954 // handlers
3955 
update_display()3956 void tmtron_state::update_display()
3957 {
3958 	u16 grid = bitswap<16>(m_grid,15,14,13,12,11,10,1,2,3,4,5,6,7,8,9,0);
3959 	u32 plate = bitswap<24>(m_plate,23,5,2,21,1,6,7,9,10,11,21,0,19,3,4,8,3,18,17,16,12,13,14,15);
3960 	m_display->matrix(grid, plate);
3961 }
3962 
plate_w(offs_t offset,u8 data)3963 void tmtron_state::plate_w(offs_t offset, u8 data)
3964 {
3965 	// R0x-R3x: vfd plate
3966 	int shift = offset * 4;
3967 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
3968 	update_display();
3969 }
3970 
grid_w(u16 data)3971 void tmtron_state::grid_w(u16 data)
3972 {
3973 	// D4: speaker out
3974 	m_speaker->level_w(data >> 4 & 1);
3975 
3976 	// D12-D15: input mux
3977 	u8 inp_mux = data >> 12 & 0xf;
3978 	if (inp_mux != m_inp_mux)
3979 	{
3980 		m_inp_mux = inp_mux;
3981 		update_int1();
3982 	}
3983 
3984 	// D6-D15: vfd grid
3985 	m_grid = data >> 6 & 0x3ff;
3986 
3987 	// D0-D3,D5: more plates
3988 	m_plate = (m_plate & 0x00ffff) | (data << 16 & 0x2f0000);
3989 	update_display();
3990 }
3991 
update_int1()3992 void tmtron_state::update_int1()
3993 {
3994 	// INT1 on multiplexed inputs
3995 	set_interrupt(1, read_inputs(4));
3996 }
3997 
3998 // config
3999 
4000 static INPUT_PORTS_START( tmtron )
4001 	PORT_START("IN.0") // D12 INT1
4002 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_16WAY PORT_CHANGED_MEMBER(DEVICE_SELF, tmtron_state, input_changed, 0)
4003 
4004 	PORT_START("IN.1") // D13 INT1
4005 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_16WAY PORT_CHANGED_MEMBER(DEVICE_SELF, tmtron_state, input_changed, 0)
4006 
4007 	PORT_START("IN.2") // D14 INT1
4008 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_16WAY PORT_CHANGED_MEMBER(DEVICE_SELF, tmtron_state, input_changed, 0)
4009 
4010 	PORT_START("IN.3") // D15 INT1
4011 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_16WAY PORT_CHANGED_MEMBER(DEVICE_SELF, tmtron_state, input_changed, 0)
4012 
4013 	PORT_START("IN.4") // INT0
4014 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_hmcs40_state, single_interrupt_line, 0)
4015 INPUT_PORTS_END
4016 
tmtron(machine_config & config)4017 void tmtron_state::tmtron(machine_config &config)
4018 {
4019 	/* basic machine hardware */
4020 	HD38800(config, m_maincpu, 400000); // approximation
4021 	m_maincpu->write_r<0>().set(FUNC(tmtron_state::plate_w));
4022 	m_maincpu->write_r<1>().set(FUNC(tmtron_state::plate_w));
4023 	m_maincpu->write_r<2>().set(FUNC(tmtron_state::plate_w));
4024 	m_maincpu->write_r<3>().set(FUNC(tmtron_state::plate_w));
4025 	m_maincpu->write_d().set(FUNC(tmtron_state::grid_w));
4026 
4027 	/* video hardware */
4028 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
4029 	screen.set_refresh_hz(60);
4030 	screen.set_size(1920, 662);
4031 	screen.set_visarea_full();
4032 
4033 	PWM_DISPLAY(config, m_display).set_size(10, 23);
4034 
4035 	/* sound hardware */
4036 	SPEAKER(config, "mono").front_center();
4037 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
4038 }
4039 
4040 // roms
4041 
4042 ROM_START( tmtron )
4043 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
4044 	ROM_LOAD( "hd38800a88", 0x0000, 0x1000, CRC(33db9670) SHA1(d6f747a59356526698784047bcfdbb59e79b9a23) )
4045 	ROM_CONTINUE(           0x1e80, 0x0100 )
4046 
4047 	ROM_REGION( 384174, "screen", 0)
4048 	ROM_LOAD( "tmtron.svg", 0, 384174, CRC(06bd9e63) SHA1(fb93013ec42dc05f7029ef3c3073c84867f0d077) )
4049 ROM_END
4050 
4051 
4052 
4053 
4054 
4055 /***************************************************************************
4056 
4057   Tomy Kingman (manufactured in Japan)
4058   * PCB label THF-01II 2E138E01/2E128E02
4059   * Hitachi HD38800B23 MCU
4060   * cyan/red/blue VFD display Futaba DM-65ZK 3A
4061 
4062 ***************************************************************************/
4063 
4064 class kingman_state : public hh_hmcs40_state
4065 {
4066 public:
kingman_state(const machine_config & mconfig,device_type type,const char * tag)4067 	kingman_state(const machine_config &mconfig, device_type type, const char *tag) :
4068 		hh_hmcs40_state(mconfig, type, tag)
4069 	{ }
4070 
4071 	void update_display();
4072 	void plate_w(offs_t offset, u8 data);
4073 	void grid_w(u16 data);
4074 
4075 	void update_int0();
DECLARE_INPUT_CHANGED_MEMBER(input_changed)4076 	DECLARE_INPUT_CHANGED_MEMBER(input_changed) { update_int0(); }
4077 	void kingman(machine_config &config);
4078 };
4079 
4080 // handlers
4081 
update_display()4082 void kingman_state::update_display()
4083 {
4084 	u16 grid = bitswap<16>(m_grid,15,14,13,12,11,10,9,0,1,2,3,4,5,6,7,8);
4085 	u32 plate = bitswap<24>(m_plate,23,6,7,5,4,3,2,1,0,13,12,20,19,18,17,16,10,11,9,8,14,15,13,12);
4086 	m_display->matrix(grid, plate);
4087 }
4088 
plate_w(offs_t offset,u8 data)4089 void kingman_state::plate_w(offs_t offset, u8 data)
4090 {
4091 	// R0x-R3x: vfd plate
4092 	int shift = offset * 4;
4093 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
4094 	update_display();
4095 }
4096 
grid_w(u16 data)4097 void kingman_state::grid_w(u16 data)
4098 {
4099 	// D6: speaker out
4100 	m_speaker->level_w(data >> 6 & 1);
4101 
4102 	// D12-D15: input mux
4103 	u8 inp_mux = data >> 12 & 0xf;
4104 	if (inp_mux != m_inp_mux)
4105 	{
4106 		m_inp_mux = inp_mux;
4107 		update_int0();
4108 	}
4109 
4110 	// D7-D15: vfd grid
4111 	m_grid = data >> 7 & 0x1ff;
4112 
4113 	// D0-D4: more plates
4114 	m_plate = (m_plate & 0x00ffff) | (data << 16 & 0x1f0000);
4115 	update_display();
4116 }
4117 
update_int0()4118 void kingman_state::update_int0()
4119 {
4120 	// INT0 on multiplexed inputs
4121 	set_interrupt(0, read_inputs(4));
4122 }
4123 
4124 // config
4125 
4126 static INPUT_PORTS_START( kingman )
4127 	PORT_START("IN.0") // D12 INT0
4128 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_CHANGED_MEMBER(DEVICE_SELF, kingman_state, input_changed, 0)
4129 
4130 	PORT_START("IN.1") // D13 INT0
4131 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_CHANGED_MEMBER(DEVICE_SELF, kingman_state, input_changed, 0)
4132 
4133 	PORT_START("IN.2") // D14 INT0
4134 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, kingman_state, input_changed, 0)
4135 
4136 	PORT_START("IN.3") // D15 INT0
4137 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_CHANGED_MEMBER(DEVICE_SELF, kingman_state, input_changed, 0)
4138 
4139 	PORT_START("IN.4") // INT1
4140 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_hmcs40_state, single_interrupt_line, 1)
4141 INPUT_PORTS_END
4142 
kingman(machine_config & config)4143 void kingman_state::kingman(machine_config &config)
4144 {
4145 	/* basic machine hardware */
4146 	HD38800(config, m_maincpu, 400000); // approximation
4147 	m_maincpu->write_r<0>().set(FUNC(kingman_state::plate_w));
4148 	m_maincpu->write_r<1>().set(FUNC(kingman_state::plate_w));
4149 	m_maincpu->write_r<2>().set(FUNC(kingman_state::plate_w));
4150 	m_maincpu->write_r<3>().set(FUNC(kingman_state::plate_w));
4151 	m_maincpu->write_d().set(FUNC(kingman_state::grid_w));
4152 
4153 	/* video hardware */
4154 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
4155 	screen.set_refresh_hz(60);
4156 	screen.set_size(374, 1080);
4157 	screen.set_visarea_full();
4158 
4159 	PWM_DISPLAY(config, m_display).set_size(9, 23);
4160 
4161 	/* sound hardware */
4162 	SPEAKER(config, "mono").front_center();
4163 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
4164 }
4165 
4166 // roms
4167 
4168 ROM_START( kingman )
4169 	ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASE00 )
4170 	ROM_LOAD( "hd38800b23", 0x0000, 0x1000, CRC(f8dfe14f) SHA1(660610d92ae7e5f92bddf5a3bcc2296b2ec3946b) )
4171 	ROM_CONTINUE(           0x1e80, 0x0100 )
4172 
4173 	ROM_REGION( 396320, "screen", 0)
4174 	ROM_LOAD( "kingman.svg", 0, 396320, CRC(3f52d2a9) SHA1(9291f1a1da3d19c3d6dedb995de0a5feba75b442) )
4175 ROM_END
4176 
4177 
4178 
4179 
4180 
4181 /***************************************************************************
4182 
4183   VTech Invaders (manufactured in Taiwan)
4184   * Hitachi HD38750A45 MCU
4185   * cyan/red VFD display Futaba DM-26Z 1G, with bezel
4186 
4187   known releases:
4188   - USA: Invaders/Sonic Invader
4189   - UK: Cosmic Invader, published by Grandstand
4190   - UK: Galactic Invaders, published by Prinztronic
4191 
4192 ***************************************************************************/
4193 
4194 class vinvader_state : public hh_hmcs40_state
4195 {
4196 public:
vinvader_state(const machine_config & mconfig,device_type type,const char * tag)4197 	vinvader_state(const machine_config &mconfig, device_type type, const char *tag) :
4198 		hh_hmcs40_state(mconfig, type, tag)
4199 	{ }
4200 
4201 	void plate_w(offs_t offset, u8 data);
4202 	void grid_w(u16 data);
4203 	void vinvader(machine_config &config);
4204 };
4205 
4206 // handlers
4207 
plate_w(offs_t offset,u8 data)4208 void vinvader_state::plate_w(offs_t offset, u8 data)
4209 {
4210 	// R1x-R3x(,D4-D6): vfd plate
4211 	int shift = (offset - 1) * 4;
4212 	m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
4213 
4214 	// update display
4215 	u16 plate = bitswap<16>(m_plate,15,11,7,3,10,6,14,2,9,5,13,1,8,4,12,0);
4216 	m_display->matrix(m_grid, plate);
4217 }
4218 
grid_w(u16 data)4219 void vinvader_state::grid_w(u16 data)
4220 {
4221 	// D0: speaker out
4222 	m_speaker->level_w(data & 1);
4223 
4224 	// D7-D15: vfd grid
4225 	m_grid = data >> 7 & 0x1ff;
4226 
4227 	// D4-D6: more plates (update display there)
4228 	plate_w(3 + 1, data >> 4 & 7);
4229 }
4230 
4231 // config
4232 
4233 static INPUT_PORTS_START( vinvader )
4234 	PORT_START("IN.0") // port R0x
4235 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
4236 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
4237 	PORT_BIT( 0x0c, IP_ACTIVE_HIGH, IPT_UNUSED )
4238 
4239 	PORT_START("IN.1") // port D
DEF_STR(Difficulty)4240 	PORT_CONFNAME( 0x0002, 0x0000, DEF_STR( Difficulty ) )
4241 	PORT_CONFSETTING(      0x0000, "1" )
4242 	PORT_CONFSETTING(      0x0002, "2" )
4243 	PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_BUTTON1 )
4244 	PORT_BIT( 0xfff5, IP_ACTIVE_HIGH, IPT_UNUSED )
4245 INPUT_PORTS_END
4246 
4247 void vinvader_state::vinvader(machine_config &config)
4248 {
4249 	/* basic machine hardware */
4250 	HD38750(config, m_maincpu, 300000); // approximation
4251 	m_maincpu->read_r<0>().set_ioport("IN.0");
4252 	m_maincpu->write_r<1>().set(FUNC(vinvader_state::plate_w));
4253 	m_maincpu->write_r<2>().set(FUNC(vinvader_state::plate_w));
4254 	m_maincpu->write_r<3>().set(FUNC(vinvader_state::plate_w));
4255 	m_maincpu->write_d().set(FUNC(vinvader_state::grid_w));
4256 	m_maincpu->read_d().set_ioport("IN.1");
4257 
4258 	/* video hardware */
4259 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
4260 	screen.set_refresh_hz(60);
4261 	screen.set_size(233, 1080);
4262 	screen.set_visarea_full();
4263 
4264 	PWM_DISPLAY(config, m_display).set_size(9, 12);
4265 
4266 	/* sound hardware */
4267 	SPEAKER(config, "mono").front_center();
4268 	SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
4269 }
4270 
4271 // roms
4272 
4273 ROM_START( vinvader )
4274 	ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASE00 )
4275 	ROM_LOAD( "hd38750a45", 0x0000, 0x0800, CRC(32de6056) SHA1(70238c6c40c3d513f8eced1cb81bdd4dbe12f16c) )
4276 	ROM_CONTINUE(           0x0f00, 0x0080 )
4277 
4278 	ROM_REGION( 166379, "screen", 0)
4279 	ROM_LOAD( "vinvader.svg", 0, 166379, CRC(b75c448e) SHA1(40d546f9fbdb446883e3ab0e3f678f1be8105159) )
4280 ROM_END
4281 
4282 
4283 
4284 } // anonymous namespace
4285 
4286 /***************************************************************************
4287 
4288   Game driver(s)
4289 
4290 ***************************************************************************/
4291 
4292 //    YEAR  NAME       PARENT   CMP MACHINE   INPUT     CLASS           INIT        COMPANY, FULLNAME, FLAGS
4293 CONS( 1979, bambball,  0,        0, bambball, bambball, bambball_state, empty_init, "Bambino", "Dribble Away Basketball", MACHINE_SUPPORTS_SAVE )
4294 CONS( 1979, bmboxing,  0,        0, bmboxing, bmboxing, bmboxing_state, empty_init, "Bambino", "Knock-Em Out Boxing", MACHINE_SUPPORTS_SAVE )
4295 
4296 CONS( 1982, bfriskyt,  0,        0, bfriskyt, bfriskyt, bfriskyt_state, empty_init, "Bandai", "Frisky Tom (Bandai)", MACHINE_SUPPORTS_SAVE )
4297 CONS( 1981, packmon,   0,        0, packmon,  packmon,  packmon_state,  empty_init, "Bandai", "Packri Monster", MACHINE_SUPPORTS_SAVE )
4298 CONS( 1982, bzaxxon,   0,        0, bzaxxon,  bzaxxon,  bzaxxon_state,  empty_init, "Bandai", "Zaxxon (Bandai)", MACHINE_SUPPORTS_SAVE )
4299 CONS( 1983, zackman,   0,        0, zackman,  zackman,  zackman_state,  empty_init, "Bandai", "Zackman", MACHINE_SUPPORTS_SAVE )
4300 CONS( 1983, bpengo,    0,        0, bpengo,   bpengo,   bpengo_state,   empty_init, "Bandai", "Pengo (Bandai)", MACHINE_SUPPORTS_SAVE )
4301 CONS( 1983, bbtime,    0,        0, bbtime,   bbtime,   bbtime_state,   empty_init, "Bandai", "Burger Time (Bandai)", MACHINE_SUPPORTS_SAVE )
4302 CONS( 1983, bdoramon,  0,        0, bdoramon, bdoramon, bdoramon_state, empty_init, "Bandai", "Dokodemo Dorayaki Doraemon", MACHINE_SUPPORTS_SAVE )
4303 CONS( 1983, bultrman,  0,        0, bultrman, bultrman, bultrman_state, empty_init, "Bandai", "Ultraman Monster Battle", MACHINE_SUPPORTS_SAVE )
4304 CONS( 1984, machiman,  0,        0, machiman, machiman, machiman_state, empty_init, "Bandai", "Machine Man", MACHINE_SUPPORTS_SAVE )
4305 CONS( 1984, pairmtch,  0,        0, pairmtch, pairmtch, pairmtch_state, empty_init, "Bandai", "Pair Match", MACHINE_SUPPORTS_SAVE )
4306 
4307 CONS( 1981, alnattck,  0,        0, alnattck, alnattck, alnattck_state, empty_init, "Coleco", "Alien Attack", MACHINE_SUPPORTS_SAVE )
4308 CONS( 1982, cdkong,    0,        0, cdkong,   cdkong,   cdkong_state,   empty_init, "Coleco", "Donkey Kong (Coleco)", MACHINE_SUPPORTS_SAVE )
4309 CONS( 1982, cgalaxn,   0,        0, cgalaxn,  cgalaxn,  cgalaxn_state,  empty_init, "Coleco", "Galaxian (Coleco)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND )
4310 CONS( 1981, cpacman,   0,        0, cpacman,  cpacman,  cpacman_state,  empty_init, "Coleco", "Pac-Man (Coleco, Rev. 29)", MACHINE_SUPPORTS_SAVE )
4311 CONS( 1981, cpacmanr1, cpacman,  0, cpacman,  cpacman,  cpacman_state,  empty_init, "Coleco", "Pac-Man (Coleco, Rev. 28)", MACHINE_SUPPORTS_SAVE )
4312 CONS( 1983, cmspacmn,  0,        0, cmspacmn, cmspacmn, cmspacmn_state, empty_init, "Coleco", "Ms. Pac-Man (Coleco)", MACHINE_SUPPORTS_SAVE )
4313 
4314 CONS( 1981, egalaxn2,  0,        0, egalaxn2, egalaxn2, egalaxn2_state, empty_init, "Entex", "Galaxian 2 (Entex)", MACHINE_SUPPORTS_SAVE )
4315 CONS( 1981, epacman2,  0,        0, epacman2, epacman2, epacman2_state, empty_init, "Entex", "Pac Man 2 (Entex, cyan Pacman)", MACHINE_SUPPORTS_SAVE )
4316 CONS( 1981, epacman2r, epacman2, 0, epacman2, epacman2, epacman2_state, empty_init, "Entex", "Pac Man 2 (Entex, red Pacman)", MACHINE_SUPPORTS_SAVE )
4317 CONS( 1982, einvader2, 0,        0, einvader2,einvader2,einvader2_state,empty_init, "Entex", "Super Space Invader 2 (Entex, black version)", MACHINE_SUPPORTS_SAVE )
4318 CONS( 1982, eturtles,  0,        0, eturtles, eturtles, eturtles_state, empty_init, "Entex", "Turtles (Entex)", MACHINE_SUPPORTS_SAVE )
4319 CONS( 1982, estargte,  0,        0, estargte, estargte, estargte_state, empty_init, "Entex", "Stargate (Entex)", MACHINE_SUPPORTS_SAVE )
4320 
4321 CONS( 1980, ghalien,   0,        0, ghalien,  ghalien,  ghalien_state,  empty_init, "Gakken", "Heiankyo Alien (Gakken)", MACHINE_SUPPORTS_SAVE )
4322 CONS( 1982, gckong,    0,        0, gckong,   gckong,   gckong_state,   empty_init, "Gakken", "Crazy Kong (Gakken)", MACHINE_SUPPORTS_SAVE )
4323 CONS( 1983, gdigdug,   0,        0, gdigdug,  gdigdug,  gdigdug_state,  empty_init, "Gakken", "Dig Dug (Gakken)", MACHINE_SUPPORTS_SAVE )
4324 
4325 CONS( 1980, mwcbaseb,  0,        0, mwcbaseb, mwcbaseb, mwcbaseb_state, empty_init, "Mattel", "World Championship Baseball", MACHINE_SUPPORTS_SAVE )
4326 CONS( 1982, msthawk,   0,        0, msthawk,  msthawk,  msthawk_state,  empty_init, "Mattel", "Star Hawk (Mattel)", MACHINE_SUPPORTS_SAVE )
4327 
4328 CONS( 1983, pbqbert,   0,        0, pbqbert,  pbqbert,  pbqbert_state,  empty_init, "Parker Brothers", "Q*Bert (Parker Brothers)", MACHINE_SUPPORTS_SAVE )
4329 
4330 CONS( 1982, tmtron,    0,        0, tmtron,   tmtron,   tmtron_state,   empty_init, "Tomy", "Tron (Tomy)", MACHINE_SUPPORTS_SAVE )
4331 CONS( 1982, kingman,   0,        0, kingman,  kingman,  kingman_state,  empty_init, "Tomy", "Kingman", MACHINE_SUPPORTS_SAVE )
4332 
4333 CONS( 1981, vinvader,  0,        0, vinvader, vinvader, vinvader_state, empty_init, "VTech", "Invaders (VTech)", MACHINE_SUPPORTS_SAVE )
4334