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