1 // license:BSD-3-Clause
2 // copyright-holders:hap
3 // thanks-to:Sean Riddle
4 /***************************************************************************
5
6 National Semiconductor COP400 MCU handhelds or other simple devices,
7 mostly LED electronic games/toys.
8
9 TODO:
10 - why does h2hbaskbc(and clones) need a workaround on writing L pins?
11 - plus1: which sensor position is which colour?
12 - vidchal: Add screen and gun cursor with brightness detection callback,
13 and softwarelist for the video tapes. We'd also need a VHS player device.
14 The emulated lightgun itself appears to be working fine(eg. add a 30hz
15 timer to IN.3 to score +100)
16
17 ***************************************************************************/
18
19 #include "emu.h"
20 #include "cpu/cop400/cop400.h"
21 #include "video/pwm.h"
22 #include "machine/timer.h"
23 #include "sound/spkrdev.h"
24 #include "sound/dac.h"
25 #include "screen.h"
26 #include "speaker.h"
27
28 // internal artwork
29 #include "bship82.lh" // clickable
30 #include "ctstein.lh" // clickable
31 #include "einvaderc.lh"
32 #include "funjacks.lh" // clickable
33 #include "funrlgl.lh"
34 #include "h2hbaskbc.lh"
35 #include "h2hhockeyc.lh"
36 #include "h2hsoccerc.lh"
37 #include "lchicken.lh" // clickable
38 #include "lightfgt.lh" // clickable
39 #include "mdallas.lh"
40 #include "qkracer.lh"
41 #include "unkeinv.lh"
42 #include "vidchal.lh"
43
44 //#include "hh_cop400_test.lh" // common test-layout - use external artwork
45
46
47 class hh_cop400_state : public driver_device
48 {
49 public:
hh_cop400_state(const machine_config & mconfig,device_type type,const char * tag)50 hh_cop400_state(const machine_config &mconfig, device_type type, const char *tag) :
51 driver_device(mconfig, type, tag),
52 m_maincpu(*this, "maincpu"),
53 m_display(*this, "display"),
54 m_speaker(*this, "speaker"),
55 m_inputs(*this, "IN.%u", 0)
56 { }
57
58 // devices
59 required_device<cop400_cpu_device> m_maincpu;
60 optional_device<pwm_display_device> m_display;
61 optional_device<speaker_sound_device> m_speaker;
62 optional_ioport_array<6> m_inputs; // max 6
63
64 // misc common
65 u8 m_l; // MCU port L write data
66 u8 m_g; // MCU port G write data
67 u8 m_d; // MCU port D write data
68 int m_so; // MCU SO line state
69 int m_sk; // MCU SK line state
70 u16 m_inp_mux; // multiplexed inputs mask
71
72 u16 read_inputs(int columns, u16 colmask = ~0);
73 virtual DECLARE_INPUT_CHANGED_MEMBER(reset_button);
74
75 protected:
76 virtual void machine_start() override;
77 virtual void machine_reset() override;
78 };
79
80
81 // machine start/reset
82
machine_start()83 void hh_cop400_state::machine_start()
84 {
85 // zerofill
86 m_l = 0;
87 m_g = 0;
88 m_d = 0;
89 m_so = 0;
90 m_sk = 0;
91 m_inp_mux = ~0;
92
93 // register for savestates
94 save_item(NAME(m_l));
95 save_item(NAME(m_g));
96 save_item(NAME(m_d));
97 save_item(NAME(m_so));
98 save_item(NAME(m_sk));
99 save_item(NAME(m_inp_mux));
100 }
101
machine_reset()102 void hh_cop400_state::machine_reset()
103 {
104 }
105
106
107
108 /***************************************************************************
109
110 Helper Functions
111
112 ***************************************************************************/
113
114 // generic input handlers
115
read_inputs(int columns,u16 colmask)116 u16 hh_cop400_state::read_inputs(int columns, u16 colmask)
117 {
118 // active low
119 u16 ret = ~0 & colmask;
120
121 // read selected input rows
122 for (int i = 0; i < columns; i++)
123 if (~m_inp_mux >> i & 1)
124 ret &= m_inputs[i]->read();
125
126 return ret;
127 }
128
INPUT_CHANGED_MEMBER(hh_cop400_state::reset_button)129 INPUT_CHANGED_MEMBER(hh_cop400_state::reset_button)
130 {
131 // when an input is directly wired to MCU reset pin
132 m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? ASSERT_LINE : CLEAR_LINE);
133 }
134
135
136
137 /***************************************************************************
138
139 Minidrivers (subclass, I/O, Inputs, Machine Config, ROM Defs)
140
141 ***************************************************************************/
142
143 namespace {
144
145 /***************************************************************************
146
147 Castle Toy Einstein
148 * COP421 MCU label ~/927 COP421-NEZ/N
149 * 4 lamps, 1-bit sound
150
151 This is a Simon clone, the tones are not harmonic. Two models exist, each
152 with a different batteries setup, assume they're same otherwise.
153
154 ***************************************************************************/
155
156 class ctstein_state : public hh_cop400_state
157 {
158 public:
ctstein_state(const machine_config & mconfig,device_type type,const char * tag)159 ctstein_state(const machine_config &mconfig, device_type type, const char *tag) :
160 hh_cop400_state(mconfig, type, tag)
161 { }
162
163 void write_g(u8 data);
164 void write_l(u8 data);
165 u8 read_l();
166 void ctstein(machine_config &config);
167 };
168
169 // handlers
170
write_g(u8 data)171 void ctstein_state::write_g(u8 data)
172 {
173 // G0-G2: input mux
174 m_inp_mux = data & 7;
175 }
176
write_l(u8 data)177 void ctstein_state::write_l(u8 data)
178 {
179 // L0-L3: button lamps
180 m_display->matrix(1, data & 0xf);
181 }
182
read_l()183 u8 ctstein_state::read_l()
184 {
185 // L4-L7: multiplexed inputs
186 return read_inputs(3, 0xf) << 4 | 0xf;
187 }
188
189 // config
190
191 static INPUT_PORTS_START( ctstein )
192 PORT_START("IN.0") // G0 port L
DEF_STR(Difficulty)193 PORT_CONFNAME( 0x0f, 0x01^0x0f, DEF_STR( Difficulty ) )
194 PORT_CONFSETTING( 0x01^0x0f, "1" )
195 PORT_CONFSETTING( 0x02^0x0f, "2" )
196 PORT_CONFSETTING( 0x04^0x0f, "3" )
197 PORT_CONFSETTING( 0x08^0x0f, "4" )
198
199 PORT_START("IN.1") // G1 port L
200 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START )
201 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SELECT ) PORT_NAME("Best Score")
202 PORT_BIT( 0x0c, IP_ACTIVE_LOW, IPT_UNUSED )
203
204 PORT_START("IN.2") // G2 port L
205 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Red Button")
206 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Yellow Button")
207 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Green Button")
208 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Blue Button")
209 INPUT_PORTS_END
210
211 void ctstein_state::ctstein(machine_config &config)
212 {
213 /* basic machine hardware */
214 COP421(config, m_maincpu, 850000); // approximation - RC osc. R=12K, C=100pF
215 m_maincpu->set_config(COP400_CKI_DIVISOR_4, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed
216 m_maincpu->write_g().set(FUNC(ctstein_state::write_g));
217 m_maincpu->write_l().set(FUNC(ctstein_state::write_l));
218 m_maincpu->write_sk().set(m_speaker, FUNC(speaker_sound_device::level_w));
219 m_maincpu->read_l().set(FUNC(ctstein_state::read_l));
220
221 /* video hardware */
222 PWM_DISPLAY(config, m_display).set_size(1, 4);
223 config.set_default_layout(layout_ctstein);
224
225 /* sound hardware */
226 SPEAKER(config, "mono").front_center();
227 SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
228 }
229
230 // roms
231
232 ROM_START( ctstein )
233 ROM_REGION( 0x0400, "maincpu", 0 )
234 ROM_LOAD( "cop421-nez_n", 0x0000, 0x0400, CRC(16148e03) SHA1(b2b74891d36813d9a1eefd56a925054997c4b7f7) ) // 2nd half empty
235 ROM_END
236
237
238
239
240
241 /***************************************************************************
242
243 Coleco Head to Head: Electronic Basketball/Hockey/Soccer (model 2150/2160/2170)
244 * COP420 MCU label COP420L-NEZ/N
245 * 2-digit 7seg display, 41 other leds, 1-bit sound
246
247 3 Head to Head games were released using this MCU/ROM. They play very much
248 the same, only differing on game time. The PCB is pre-configured on G1+IN2
249 and IN3 to select the game.
250
251 An earlier revision of this runs on TMS1000, see hh_tms1k.cpp driver. Model
252 numbers are the same. From the outside, an easy way to spot the difference is
253 the Start/Display button: TMS1000 version button label is D, COP420 one is a *.
254 The COP420 version also plays much slower.
255
256 ***************************************************************************/
257
258 class h2hbaskbc_state : public hh_cop400_state
259 {
260 public:
h2hbaskbc_state(const machine_config & mconfig,device_type type,const char * tag)261 h2hbaskbc_state(const machine_config &mconfig, device_type type, const char *tag) :
262 hh_cop400_state(mconfig, type, tag)
263 { }
264
265 void write_d(u8 data);
266 void write_g(u8 data);
267 void write_l(u8 data);
268 u8 read_in();
269 void h2hsoccerc(machine_config &config);
270 void h2hbaskbc(machine_config &config);
271 void h2hhockeyc(machine_config &config);
272 };
273
274 // handlers
275
write_d(u8 data)276 void h2hbaskbc_state::write_d(u8 data)
277 {
278 // D: led select
279 m_d = data & 0xf;
280 }
281
write_g(u8 data)282 void h2hbaskbc_state::write_g(u8 data)
283 {
284 // G: led select, input mux
285 m_inp_mux = data;
286 m_g = data & 0xf;
287 }
288
write_l(u8 data)289 void h2hbaskbc_state::write_l(u8 data)
290 {
291 // D2,D3 double as multiplexer
292 u16 mask = ((m_d >> 2 & 1) * 0x00ff) | ((m_d >> 3 & 1) * 0xff00);
293 u16 sel = (m_g | m_d << 4 | m_g << 8 | m_d << 12) & mask;
294
295 // D2+G0,G1 are 7segs
296 // L0-L6: digit segments A-G, L0-L4: led data
297 m_display->matrix(sel, data);
298 }
299
read_in()300 u8 h2hbaskbc_state::read_in()
301 {
302 // IN: multiplexed inputs
303 return read_inputs(4, 7) | (m_inputs[4]->read() & 8);
304 }
305
306 // config
307
308 static INPUT_PORTS_START( h2hbaskbc )
309 PORT_START("IN.0") // G0 port IN
310 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_16WAY PORT_NAME("P1 Pass CW") // clockwise
311 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_16WAY PORT_NAME("P1 Pass CCW") // counter-clockwise
DEF_STR(Players)312 PORT_CONFNAME( 0x04, 0x04, DEF_STR( Players ) )
313 PORT_CONFSETTING( 0x04, "1" )
314 PORT_CONFSETTING( 0x00, "2" )
315
316 PORT_START("IN.1") // G1 port IN
317 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P1 Shoot")
318 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START ) PORT_NAME("Start/Display")
319 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_CUSTOM ) // factory set
320
321 PORT_START("IN.2") // G2 port IN
322 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_COCKTAIL PORT_16WAY PORT_NAME("P2 Defense Right")
323 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_COCKTAIL PORT_16WAY PORT_NAME("P2 Defense Left")
324 PORT_CONFNAME( 0x04, 0x04, DEF_STR( Difficulty ) )
325 PORT_CONFSETTING( 0x04, "1" )
326 PORT_CONFSETTING( 0x00, "2" )
327
328 PORT_START("IN.3") // G3 port IN
329 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
330 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
331 PORT_CONFNAME( 0x04, 0x04, "Factory Test" )
332 PORT_CONFSETTING( 0x04, DEF_STR( Off ) )
333 PORT_CONFSETTING( 0x00, DEF_STR( On ) )
334
335 PORT_START("IN.4") // IN3 (factory set)
336 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_CUSTOM )
337 INPUT_PORTS_END
338
339 static INPUT_PORTS_START( h2hhockeyc )
340 PORT_INCLUDE( h2hbaskbc )
341
342 PORT_MODIFY("IN.3")
343 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_COCKTAIL PORT_NAME("P2 Goalie Right")
344 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL PORT_NAME("P2 Goalie Left")
345
346 PORT_MODIFY("IN.4")
347 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_CUSTOM )
348 INPUT_PORTS_END
349
350 static INPUT_PORTS_START( h2hsoccerc )
351 PORT_INCLUDE( h2hhockeyc )
352
353 PORT_MODIFY("IN.1")
354 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_CUSTOM )
355 INPUT_PORTS_END
356
357 void h2hbaskbc_state::h2hbaskbc(machine_config &config)
358 {
359 /* basic machine hardware */
360 COP420(config, m_maincpu, 1000000); // approximation - RC osc. R=43K, C=101pF
361 m_maincpu->set_config(COP400_CKI_DIVISOR_16, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed
362 m_maincpu->write_d().set(FUNC(h2hbaskbc_state::write_d));
363 m_maincpu->write_g().set(FUNC(h2hbaskbc_state::write_g));
364 m_maincpu->write_l().set(FUNC(h2hbaskbc_state::write_l));
365 m_maincpu->read_in().set(FUNC(h2hbaskbc_state::read_in));
366 m_maincpu->write_so().set(m_speaker, FUNC(speaker_sound_device::level_w));
367
368 /* video hardware */
369 PWM_DISPLAY(config, m_display).set_size(16, 7);
370 m_display->set_segmask(3, 0x7f);
371 config.set_default_layout(layout_h2hbaskbc);
372
373 /* sound hardware */
374 SPEAKER(config, "mono").front_center();
375 SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
376 }
377
h2hhockeyc(machine_config & config)378 void h2hbaskbc_state::h2hhockeyc(machine_config &config)
379 {
380 h2hbaskbc(config);
381 config.set_default_layout(layout_h2hhockeyc);
382 }
383
h2hsoccerc(machine_config & config)384 void h2hbaskbc_state::h2hsoccerc(machine_config &config)
385 {
386 h2hbaskbc(config);
387 config.set_default_layout(layout_h2hsoccerc);
388 }
389
390 // roms
391
392 ROM_START( h2hbaskbc )
393 ROM_REGION( 0x0400, "maincpu", 0 )
394 ROM_LOAD( "cop420l-nmy", 0x0000, 0x0400, CRC(87152509) SHA1(acdb869b65d49b3b9855a557ed671cbbb0f61e2c) )
395 ROM_END
396
397 #define rom_h2hhockeyc rom_h2hbaskbc // dumped from Basketball
398 #define rom_h2hsoccerc rom_h2hbaskbc // "
399
400
401
402
403
404 /***************************************************************************
405
406 Entex Space Invader
407 * COP444L MCU label /B138 COPL444-HRZ/N INV II (die label HRZ COP 444L/A)
408 * 3 7seg LEDs, LED matrix and overlay mask, 1-bit sound
409
410 The first version was on TMS1100 (see hh_tms1k.c), this is the reprogrammed
411 second release with a gray case instead of black.
412
413 ***************************************************************************/
414
415 class einvaderc_state : public hh_cop400_state
416 {
417 public:
einvaderc_state(const machine_config & mconfig,device_type type,const char * tag)418 einvaderc_state(const machine_config &mconfig, device_type type, const char *tag) :
419 hh_cop400_state(mconfig, type, tag)
420 { }
421
422 void update_display();
423 void write_d(u8 data);
424 void write_g(u8 data);
425 DECLARE_WRITE_LINE_MEMBER(write_sk);
426 DECLARE_WRITE_LINE_MEMBER(write_so);
427 void write_l(u8 data);
428 void einvaderc(machine_config &config);
429 };
430
431 // handlers
432
update_display()433 void einvaderc_state::update_display()
434 {
435 u8 l = bitswap<8>(m_l,7,6,0,1,2,3,4,5);
436 u16 grid = (m_d | m_g << 4 | m_sk << 8 | m_so << 9) ^ 0x0ff;
437
438 m_display->matrix(grid, l);
439 }
440
write_d(u8 data)441 void einvaderc_state::write_d(u8 data)
442 {
443 // D: led grid 0-3 (D0-D2 are 7segs)
444 m_d = data;
445 update_display();
446 }
447
write_g(u8 data)448 void einvaderc_state::write_g(u8 data)
449 {
450 // G: led grid 4-7
451 m_g = data;
452 update_display();
453 }
454
WRITE_LINE_MEMBER(einvaderc_state::write_sk)455 WRITE_LINE_MEMBER(einvaderc_state::write_sk)
456 {
457 // SK: speaker out + led grid 8
458 m_speaker->level_w(state);
459 m_sk = state;
460 update_display();
461 }
462
WRITE_LINE_MEMBER(einvaderc_state::write_so)463 WRITE_LINE_MEMBER(einvaderc_state::write_so)
464 {
465 // SO: led grid 9
466 m_so = state;
467 update_display();
468 }
469
write_l(u8 data)470 void einvaderc_state::write_l(u8 data)
471 {
472 // L: led state/segment
473 m_l = data;
474 update_display();
475 }
476
477 // config
478
479 static INPUT_PORTS_START( einvaderc )
480 PORT_START("IN.0") // port IN
DEF_STR(Difficulty)481 PORT_CONFNAME( 0x01, 0x01, DEF_STR( Difficulty ) )
482 PORT_CONFSETTING( 0x01, "Amateur" )
483 PORT_CONFSETTING( 0x00, "Professional" )
484 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_16WAY
485 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_16WAY
486 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 )
487 INPUT_PORTS_END
488
489 void einvaderc_state::einvaderc(machine_config &config)
490 {
491 /* basic machine hardware */
492 COP444L(config, m_maincpu, 850000); // approximation - RC osc. R=47K, C=100pF
493 m_maincpu->set_config(COP400_CKI_DIVISOR_16, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed
494 m_maincpu->read_in().set_ioport("IN.0");
495 m_maincpu->write_d().set(FUNC(einvaderc_state::write_d));
496 m_maincpu->write_g().set(FUNC(einvaderc_state::write_g));
497 m_maincpu->write_sk().set(FUNC(einvaderc_state::write_sk));
498 m_maincpu->write_so().set(FUNC(einvaderc_state::write_so));
499 m_maincpu->write_l().set(FUNC(einvaderc_state::write_l));
500
501 /* video hardware */
502 screen_device &mask(SCREEN(config, "mask", SCREEN_TYPE_SVG));
503 mask.set_refresh_hz(60);
504 mask.set_size(919, 1080);
505 mask.set_visarea_full();
506
507 PWM_DISPLAY(config, m_display).set_size(10, 8);
508 m_display->set_segmask(7, 0x7f);
509 config.set_default_layout(layout_einvaderc);
510
511 /* sound hardware */
512 SPEAKER(config, "mono").front_center();
513 SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
514 }
515
516 // roms
517
518 ROM_START( einvaderc )
519 ROM_REGION( 0x0800, "maincpu", 0 )
520 ROM_LOAD( "copl444-hrz_n_inv_ii", 0x0000, 0x0800, CRC(76400f38) SHA1(0e92ab0517f7b7687293b189d30d57110df20fe0) )
521
522 ROM_REGION( 82104, "mask", 0)
523 ROM_LOAD( "einvaderc.svg", 0, 82104, CRC(0013227f) SHA1(44a3ac48c947369231f010559331ad16fcbef7be) )
524 ROM_END
525
526
527
528
529
530 /***************************************************************************
531
532 Gordon Barlow Design electronic Space Invaders game (unreleased, from patent US4345764)
533 * COP421 (likely a development chip)
534 * 36+9 LEDs, 1-bit sound
535
536 This game is presumedly unreleased. The title is unknown, the patent simply names
537 it "Hand-held electronic game". There is no mass-manufacture company assigned
538 to it either. The game seems unfinished(no scorekeeping, some bugs), and the design
539 is very complex. Player ship and bullets are on a moving "wand", a 2-way mirror
540 makes it appear on the same plane as the enemies and barriers.
541
542 ***************************************************************************/
543
544 class unkeinv_state : public hh_cop400_state
545 {
546 public:
unkeinv_state(const machine_config & mconfig,device_type type,const char * tag)547 unkeinv_state(const machine_config &mconfig, device_type type, const char *tag) :
548 hh_cop400_state(mconfig, type, tag)
549 { }
550
551 void update_display();
552 void write_g(u8 data);
553 void write_d(u8 data);
554 void write_l(u8 data);
555 u8 read_l();
556
557 void unkeinv(machine_config &config);
558 };
559
560 // handlers
561
update_display()562 void unkeinv_state::update_display()
563 {
564 m_display->matrix(m_g << 4 | m_d, m_l);
565 }
566
write_g(u8 data)567 void unkeinv_state::write_g(u8 data)
568 {
569 // G0,G1: led select part
570 // G2,G3: input mux
571 m_g = ~data & 0xf;
572 update_display();
573 }
574
write_d(u8 data)575 void unkeinv_state::write_d(u8 data)
576 {
577 // D0-D3: led select part
578 m_d = ~data & 0xf;
579 update_display();
580 }
581
write_l(u8 data)582 void unkeinv_state::write_l(u8 data)
583 {
584 // L0-L7: led data
585 m_l = ~data & 0xff;
586 update_display();
587 }
588
read_l()589 u8 unkeinv_state::read_l()
590 {
591 u8 ret = 0xff;
592
593 // L0-L5+G2: positional odd
594 // L0-L5+G3: positional even
595 u8 pos = m_inputs[1]->read();
596 if (m_g & 4 && pos & 1)
597 ret ^= (1 << (pos >> 1));
598 if (m_g & 8 && ~pos & 1)
599 ret ^= (1 << (pos >> 1));
600
601 // L7+G3: fire button
602 if (m_g & 8 && m_inputs[0]->read())
603 ret ^= 0x80;
604
605 return ret & ~m_l;
606 }
607
608 // config
609
610 static INPUT_PORTS_START( unkeinv )
611 PORT_START("IN.0")
612 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 )
613
614 PORT_START("IN.1")
615 PORT_BIT( 0x0f, 0x00, IPT_POSITIONAL ) PORT_POSITIONS(12) PORT_SENSITIVITY(10) PORT_KEYDELTA(1) PORT_CENTERDELTA(0)
616 INPUT_PORTS_END
617
unkeinv(machine_config & config)618 void unkeinv_state::unkeinv(machine_config &config)
619 {
620 /* basic machine hardware */
621 COP421(config, m_maincpu, 850000); // frequency guessed
622 m_maincpu->set_config(COP400_CKI_DIVISOR_4, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed
623 m_maincpu->write_g().set(FUNC(unkeinv_state::write_g));
624 m_maincpu->write_d().set(FUNC(unkeinv_state::write_d));
625 m_maincpu->write_l().set(FUNC(unkeinv_state::write_l));
626 m_maincpu->read_l().set(FUNC(unkeinv_state::read_l));
627 m_maincpu->read_l_tristate().set_constant(0xff);
628 m_maincpu->write_so().set(m_speaker, FUNC(speaker_sound_device::level_w));
629
630 /* video hardware */
631 PWM_DISPLAY(config, m_display).set_size(6, 8);
632 config.set_default_layout(layout_unkeinv);
633
634 /* sound hardware */
635 SPEAKER(config, "mono").front_center();
636 SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
637 }
638
639 // roms
640
641 ROM_START( unkeinv )
642 ROM_REGION( 0x0400, "maincpu", 0 )
643 ROM_LOAD( "cop421_us4345764", 0x0000, 0x0400, CRC(0068c3a3) SHA1(4e5fd566a5a26c066cc14623a9bd01e109ebf797) ) // typed in from patent US4345764, good print quality
644 ROM_END
645
646
647
648
649
650 /***************************************************************************
651
652 LJN I Took a Lickin' From a Chicken
653 * COP421 MCU label ~/005 COP421-NJC/N
654 * 11 leds, 1-bit sound, motor to a chicken on a spring
655
656 This toy includes 4 games: Tic Tac Toe, Chicken Sez, and Total Recall I/II.
657
658 known releases:
659 - USA: I Took a Lickin' From a Chicken
660 - Japan: Professor Chicken's Genius Classroom 「にわとり博士の天才教室」, published by Bandai
661 (not sure if it's the same ROM, or just licensed the outer shell)
662
663 ***************************************************************************/
664
665 class lchicken_state : public hh_cop400_state
666 {
667 public:
lchicken_state(const machine_config & mconfig,device_type type,const char * tag)668 lchicken_state(const machine_config &mconfig, device_type type, const char *tag) :
669 hh_cop400_state(mconfig, type, tag)
670 { }
671
672 u8 m_motor_pos;
673 TIMER_DEVICE_CALLBACK_MEMBER(motor_sim_tick);
674 DECLARE_READ_LINE_MEMBER(motor_switch_r);
675
676 void write_l(u8 data);
677 void write_d(u8 data);
678 void write_g(u8 data);
679 u8 read_g();
680 DECLARE_WRITE_LINE_MEMBER(write_so);
681 DECLARE_READ_LINE_MEMBER(read_si);
682 void lchicken(machine_config &config);
683
684 protected:
685 virtual void machine_start() override;
686 };
687
machine_start()688 void lchicken_state::machine_start()
689 {
690 hh_cop400_state::machine_start();
691
692 // zerofill, register for savestates
693 m_motor_pos = 0;
694 save_item(NAME(m_motor_pos));
695 }
696
697 // handlers
698
READ_LINE_MEMBER(lchicken_state::motor_switch_r)699 READ_LINE_MEMBER(lchicken_state::motor_switch_r)
700 {
701 return m_motor_pos > 0xe8; // approximation
702 }
703
TIMER_DEVICE_CALLBACK_MEMBER(lchicken_state::motor_sim_tick)704 TIMER_DEVICE_CALLBACK_MEMBER(lchicken_state::motor_sim_tick)
705 {
706 if (~m_inp_mux & 8)
707 {
708 m_motor_pos++;
709 output().set_value("motor_pos", 100 * (m_motor_pos / (float)0x100));
710 }
711 }
712
write_l(u8 data)713 void lchicken_state::write_l(u8 data)
714 {
715 // L0-L3: led data
716 // L4-L6: led select
717 // L7: N/C
718 m_display->matrix(data >> 4 & 7, ~data & 0xf);
719 }
720
write_d(u8 data)721 void lchicken_state::write_d(u8 data)
722 {
723 // D0-D3: input mux
724 // D3: motor on
725 m_inp_mux = data & 0xf;
726 output().set_value("motor_on", ~data >> 3 & 1);
727 }
728
write_g(u8 data)729 void lchicken_state::write_g(u8 data)
730 {
731 m_g = data;
732 }
733
read_g()734 u8 lchicken_state::read_g()
735 {
736 // G0-G3: multiplexed inputs
737 return read_inputs(4, m_g);
738 }
739
WRITE_LINE_MEMBER(lchicken_state::write_so)740 WRITE_LINE_MEMBER(lchicken_state::write_so)
741 {
742 // SO: speaker out
743 m_speaker->level_w(state);
744 m_so = state;
745 }
746
READ_LINE_MEMBER(lchicken_state::read_si)747 READ_LINE_MEMBER(lchicken_state::read_si)
748 {
749 // SI: SO
750 return m_so;
751 }
752
753 // config
754
755 static INPUT_PORTS_START( lchicken )
756 PORT_START("IN.0") // D0 port G
PORT_CODE(KEYCODE_3)757 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3")
758 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6")
759 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9")
760 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
761
762 PORT_START("IN.1") // D1 port G
763 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2")
764 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5")
765 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8")
766 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
767
768 PORT_START("IN.2") // D2 port G
769 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1")
770 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4")
771 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7")
772 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
773
774 PORT_START("IN.3") // D3 port G
775 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
776 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
777 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
778 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_READ_LINE_MEMBER(lchicken_state, motor_switch_r)
779 INPUT_PORTS_END
780
781 void lchicken_state::lchicken(machine_config &config)
782 {
783 /* basic machine hardware */
784 COP421(config, m_maincpu, 850000); // approximation - RC osc. R=12K, C=100pF
785 m_maincpu->set_config(COP400_CKI_DIVISOR_4, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed
786 m_maincpu->write_l().set(FUNC(lchicken_state::write_l));
787 m_maincpu->write_d().set(FUNC(lchicken_state::write_d));
788 m_maincpu->write_g().set(FUNC(lchicken_state::write_g));
789 m_maincpu->read_g().set(FUNC(lchicken_state::read_g));
790 m_maincpu->write_so().set(FUNC(lchicken_state::write_so));
791 m_maincpu->read_si().set(FUNC(lchicken_state::read_si));
792
793 TIMER(config, "chicken_motor").configure_periodic(FUNC(lchicken_state::motor_sim_tick), attotime::from_msec(6000/0x100)); // ~6sec for a full rotation
794
795 /* video hardware */
796 PWM_DISPLAY(config, m_display).set_size(3, 4);
797 config.set_default_layout(layout_lchicken);
798
799 /* sound hardware */
800 SPEAKER(config, "mono").front_center();
801 SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
802 }
803
804 // roms
805
806 ROM_START( lchicken )
807 ROM_REGION( 0x0400, "maincpu", 0 )
808 ROM_LOAD( "cop421-njc_n", 0x0000, 0x0400, CRC(319e7985) SHA1(9714327518f65ebefe38ac7911bed2b9b9c77307) )
809 ROM_END
810
811
812
813
814
815 /***************************************************************************
816
817 Mattel Funtronics: Jacks
818 * COP410L MCU bonded directly to PCB (die label COP410L/B NGS)
819 * 8 LEDs, 1-bit sound
820
821 ***************************************************************************/
822
823 class funjacks_state : public hh_cop400_state
824 {
825 public:
funjacks_state(const machine_config & mconfig,device_type type,const char * tag)826 funjacks_state(const machine_config &mconfig, device_type type, const char *tag) :
827 hh_cop400_state(mconfig, type, tag)
828 { }
829
830 void update_display();
831 void write_d(u8 data);
832 void write_l(u8 data);
833 void write_g(u8 data);
834 u8 read_l();
835 u8 read_g();
836 void funjacks(machine_config &config);
837 };
838
839 // handlers
840
update_display()841 void funjacks_state::update_display()
842 {
843 m_display->matrix(m_d, m_l);
844 }
845
write_d(u8 data)846 void funjacks_state::write_d(u8 data)
847 {
848 // D: led grid + input mux
849 m_inp_mux = data;
850 m_d = ~data & 0xf;
851 update_display();
852 }
853
write_l(u8 data)854 void funjacks_state::write_l(u8 data)
855 {
856 // L0,L1: led state
857 m_l = data & 3;
858 update_display();
859 }
860
write_g(u8 data)861 void funjacks_state::write_g(u8 data)
862 {
863 // G1: speaker out
864 m_speaker->level_w(data >> 1 & 1);
865 m_g = data;
866 }
867
read_l()868 u8 funjacks_state::read_l()
869 {
870 // L4,L5: multiplexed inputs
871 return read_inputs(3, 0x30) | m_l;
872 }
873
read_g()874 u8 funjacks_state::read_g()
875 {
876 // G1: speaker out state
877 // G2,G3: inputs
878 return m_inputs[3]->read() | (m_g & 2);
879 }
880
881 // config
882
883 static INPUT_PORTS_START( funjacks )
884 PORT_START("IN.0") // D0 port G
885 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON3 )
886 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 )
887
888 PORT_START("IN.1") // D1 port G
889 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 )
890 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON5 )
891
892 PORT_START("IN.2") // D2 port G
893 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON6 )
894 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) // positioned at 1 o'clock on panel, increment clockwise
895
896 PORT_START("IN.3") // port G
897 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
898 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_CUSTOM ) // speaker
899 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START )
DEF_STR(Players)900 PORT_CONFNAME( 0x08, 0x00, DEF_STR( Players ) )
901 PORT_CONFSETTING( 0x00, "1" )
902 PORT_CONFSETTING( 0x08, "2" )
903 INPUT_PORTS_END
904
905 void funjacks_state::funjacks(machine_config &config)
906 {
907 /* basic machine hardware */
908 COP410(config, m_maincpu, 750000); // approximation - RC osc. R=47K, C=56pF
909 m_maincpu->set_config(COP400_CKI_DIVISOR_8, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed
910 m_maincpu->write_d().set(FUNC(funjacks_state::write_d));
911 m_maincpu->write_l().set(FUNC(funjacks_state::write_l));
912 m_maincpu->write_g().set(FUNC(funjacks_state::write_g));
913 m_maincpu->read_l().set(FUNC(funjacks_state::read_l));
914 m_maincpu->read_g().set(FUNC(funjacks_state::read_g));
915
916 /* video hardware */
917 PWM_DISPLAY(config, m_display).set_size(4, 2);
918 config.set_default_layout(layout_funjacks);
919
920 /* sound hardware */
921 SPEAKER(config, "mono").front_center();
922 SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
923 }
924
925 // roms
926
927 ROM_START( funjacks )
928 ROM_REGION( 0x0200, "maincpu", 0 )
929 ROM_LOAD( "cop410l_b_ngs", 0x0000, 0x0200, CRC(863368ea) SHA1(f116cc27ae721b3a3e178fa13765808bdc275663) )
930 ROM_END
931
932
933
934
935
936 /***************************************************************************
937
938 Mattel Funtronics: Red Light Green Light
939 * COP410L MCU bonded directly to PCB (die label COP410L/B NHZ)
940 * 14 LEDs, 1-bit sound
941
942 known releases:
943 - USA: Funtronics: Red Light Green Light
944 - USA(rerelease): Funtronics: Hot Wheels Drag Race
945
946 ***************************************************************************/
947
948 class funrlgl_state : public hh_cop400_state
949 {
950 public:
funrlgl_state(const machine_config & mconfig,device_type type,const char * tag)951 funrlgl_state(const machine_config &mconfig, device_type type, const char *tag) :
952 hh_cop400_state(mconfig, type, tag)
953 { }
954
955 void update_display();
956 void write_d(u8 data);
957 void write_l(u8 data);
958 void write_g(u8 data);
959 void funrlgl(machine_config &config);
960 };
961
962 // handlers
963
update_display()964 void funrlgl_state::update_display()
965 {
966 m_display->matrix(m_d, m_l);
967 }
968
write_d(u8 data)969 void funrlgl_state::write_d(u8 data)
970 {
971 // D: led grid
972 m_d = ~data & 0xf;
973 update_display();
974 }
975
write_l(u8 data)976 void funrlgl_state::write_l(u8 data)
977 {
978 // L0-L3: led state
979 // L4-L7: N/C
980 m_l = ~data & 0xf;
981 update_display();
982 }
983
write_g(u8 data)984 void funrlgl_state::write_g(u8 data)
985 {
986 // G3: speaker out
987 m_speaker->level_w(data >> 3 & 1);
988 }
989
990 // config
991
992 static INPUT_PORTS_START( funrlgl )
993 PORT_START("IN.0") // port G
994 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
995 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
DEF_STR(Difficulty)996 PORT_CONFNAME( 0x04, 0x04, DEF_STR( Difficulty ) )
997 PORT_CONFSETTING( 0x04, "1" )
998 PORT_CONFSETTING( 0x00, "2" )
999 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
1000
1001 PORT_START("RESET")
1002 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_cop400_state, reset_button, 0)
1003 INPUT_PORTS_END
1004
1005 void funrlgl_state::funrlgl(machine_config &config)
1006 {
1007 /* basic machine hardware */
1008 COP410(config, m_maincpu, 750000); // approximation - RC osc. R=51K, C=91pF
1009 m_maincpu->set_config(COP400_CKI_DIVISOR_8, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed
1010 m_maincpu->write_d().set(FUNC(funrlgl_state::write_d));
1011 m_maincpu->write_l().set(FUNC(funrlgl_state::write_l));
1012 m_maincpu->read_l_tristate().set_constant(0xff);
1013 m_maincpu->write_g().set(FUNC(funrlgl_state::write_g));
1014 m_maincpu->read_g().set_ioport("IN.0");
1015
1016 /* video hardware */
1017 PWM_DISPLAY(config, m_display).set_size(4, 4);
1018 m_display->set_bri_levels(0.01, 0.1); // top led is brighter
1019 config.set_default_layout(layout_funrlgl);
1020
1021 /* sound hardware */
1022 SPEAKER(config, "mono").front_center();
1023 SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
1024 }
1025
1026 // roms
1027
1028 ROM_START( funrlgl )
1029 ROM_REGION( 0x0200, "maincpu", 0 )
1030 ROM_LOAD( "cop410l_b_nhz", 0x0000, 0x0200, CRC(4065c3ce) SHA1(f0bc8125d922949e0d7ab1ba89c805a836d20e09) )
1031 ROM_END
1032
1033
1034
1035
1036
1037 /***************************************************************************
1038
1039 Mattel Dalla$ (J.R. handheld)
1040 * COP444 MCU label COP444L-HYN/N
1041 * 8-digit 7seg display, 1-bit sound
1042
1043 This is a board game, only the handheld device is emulated here.
1044
1045 ***************************************************************************/
1046
1047 class mdallas_state : public hh_cop400_state
1048 {
1049 public:
mdallas_state(const machine_config & mconfig,device_type type,const char * tag)1050 mdallas_state(const machine_config &mconfig, device_type type, const char *tag) :
1051 hh_cop400_state(mconfig, type, tag)
1052 { }
1053
1054 void update_display();
1055 void write_l(u8 data);
1056 void write_d(u8 data);
1057 void write_g(u8 data);
1058 u8 read_in();
1059 void mdallas(machine_config &config);
1060 };
1061
1062 // handlers
1063
update_display()1064 void mdallas_state::update_display()
1065 {
1066 m_display->matrix(~(m_d << 4 | m_g), m_l);
1067 }
1068
write_l(u8 data)1069 void mdallas_state::write_l(u8 data)
1070 {
1071 // L: digit segment data
1072 m_l = data;
1073 update_display();
1074 }
1075
write_d(u8 data)1076 void mdallas_state::write_d(u8 data)
1077 {
1078 // D: select digit, input mux high
1079 m_inp_mux = (m_inp_mux & 0xf) | (data << 4 & 3);
1080 m_d = data & 0xf;
1081 update_display();
1082 }
1083
write_g(u8 data)1084 void mdallas_state::write_g(u8 data)
1085 {
1086 // G: select digit, input mux low
1087 m_inp_mux = (m_inp_mux & 0x30) | (data & 0xf);
1088 m_g = data & 0xf;
1089 update_display();
1090 }
1091
read_in()1092 u8 mdallas_state::read_in()
1093 {
1094 // IN: multiplexed inputs
1095 return read_inputs(6, 0xf);
1096 }
1097
1098 // config
1099
1100 /* physical button layout and labels is like this:
1101
1102 < ON> [YES] [NO] [NEXT]
1103 [<W] [^N] [Sv] [E>]
1104 [7] [8] [9] [STATUS]
1105 [4] [5] [6] [ASSETS]
1106 [1] [2] [3] [START]
1107 [CLEAR] [0] [MOVE] [ENTER]
1108 */
1109
1110 static INPUT_PORTS_START( mdallas )
1111 PORT_START("IN.0") // G0 port IN
PORT_CODE(KEYCODE_C)1112 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_C) PORT_CODE(KEYCODE_DEL) PORT_NAME("Clear")
1113 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0")
1114 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_M) PORT_NAME("Move")
1115 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter")
1116
1117 PORT_START("IN.1") // G1 port IN
1118 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1")
1119 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2")
1120 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3")
1121 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_S) PORT_NAME("Start")
1122
1123 PORT_START("IN.2") // G2 port IN
1124 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4")
1125 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5")
1126 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6")
1127 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_A) PORT_NAME("Assets")
1128
1129 PORT_START("IN.3") // G3 port IN
1130 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7")
1131 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8")
1132 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9")
1133 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_T) PORT_NAME("Status")
1134
1135 PORT_START("IN.4") // D0 port IN
1136 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_Q) PORT_NAME("West") // W
1137 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
1138 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_X) PORT_NAME("Next")
1139 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) PORT_NAME("East") // E
1140
1141 PORT_START("IN.5") // D1 port IN
1142 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_N) PORT_NAME("No")
1143 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_Y) PORT_NAME("Yes")
1144 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_NAME("South") // S
1145 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_W) PORT_NAME("North") // N
1146 INPUT_PORTS_END
1147
1148 void mdallas_state::mdallas(machine_config &config)
1149 {
1150 /* basic machine hardware */
1151 COP444L(config, m_maincpu, 1000000); // approximation - RC osc. R=57K, C=101pF
1152 m_maincpu->set_config(COP400_CKI_DIVISOR_16, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed
1153 m_maincpu->write_l().set(FUNC(mdallas_state::write_l));
1154 m_maincpu->write_d().set(FUNC(mdallas_state::write_d));
1155 m_maincpu->write_g().set(FUNC(mdallas_state::write_g));
1156 m_maincpu->read_in().set(FUNC(mdallas_state::read_in));
1157 m_maincpu->write_so().set(m_speaker, FUNC(speaker_sound_device::level_w));
1158
1159 /* video hardware */
1160 PWM_DISPLAY(config, m_display).set_size(8, 8);
1161 m_display->set_segmask(0xff, 0xff);
1162 config.set_default_layout(layout_mdallas);
1163
1164 /* sound hardware */
1165 SPEAKER(config, "mono").front_center();
1166 SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
1167 }
1168
1169 // roms
1170
1171 ROM_START( mdallas )
1172 ROM_REGION( 0x0800, "maincpu", 0 )
1173 ROM_LOAD( "copl444l-hyn_n", 0x0000, 0x0800, CRC(7848b78c) SHA1(778d24512180892f58c49df3c72ca77b2618d63b) )
1174 ROM_END
1175
1176
1177
1178
1179
1180 /***************************************************************************
1181
1182 Milton Bradley Plus One
1183 * COP410L MCU in 8-pin DIP, label ~/029 MM 57405 (die label COP410L/B NNE)
1184 * orientation sensor(4 directions), 1-bit sound
1185
1186 This is a board game, each player needs to rotate a triangular pyramid
1187 shaped piece the same as the previous player, plus 1.
1188
1189 ***************************************************************************/
1190
1191 class plus1_state : public hh_cop400_state
1192 {
1193 public:
plus1_state(const machine_config & mconfig,device_type type,const char * tag)1194 plus1_state(const machine_config &mconfig, device_type type, const char *tag) :
1195 hh_cop400_state(mconfig, type, tag)
1196 { }
1197
1198 void write_d(u8 data);
1199 void write_l(u8 data);
1200 u8 read_l();
1201 void plus1(machine_config &config);
1202 };
1203
1204 // handlers
1205
write_d(u8 data)1206 void plus1_state::write_d(u8 data)
1207 {
1208 // D0?: speaker out
1209 m_speaker->level_w(data & 1);
1210 }
1211
write_l(u8 data)1212 void plus1_state::write_l(u8 data)
1213 {
1214 m_l = data;
1215 }
1216
read_l()1217 u8 plus1_state::read_l()
1218 {
1219 // L: IN.1, mask with output
1220 return m_inputs[1]->read() & m_l;
1221 }
1222
1223 // config
1224
1225 static INPUT_PORTS_START( plus1 )
1226 PORT_START("IN.0") // port G
1227 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
1228 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Sensor Position 3")
1229 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Sensor Position 1")
1230 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
1231
1232 PORT_START("IN.1") // port L
1233 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Sensor Position 4")
1234 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
1235 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
1236 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Sensor Position 2")
1237 PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED )
1238 INPUT_PORTS_END
1239
plus1(machine_config & config)1240 void plus1_state::plus1(machine_config &config)
1241 {
1242 /* basic machine hardware */
1243 COP410(config, m_maincpu, 1000000); // approximation - RC osc. R=51K, C=100pF
1244 m_maincpu->set_config(COP400_CKI_DIVISOR_16, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed
1245 m_maincpu->write_d().set(FUNC(plus1_state::write_d));
1246 m_maincpu->read_g().set_ioport("IN.0");
1247 m_maincpu->write_l().set(FUNC(plus1_state::write_l));
1248 m_maincpu->read_l().set(FUNC(plus1_state::read_l));
1249
1250 /* no visual feedback! */
1251
1252 /* sound hardware */
1253 SPEAKER(config, "mono").front_center();
1254 SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
1255 }
1256
1257 // roms
1258
1259 ROM_START( plus1 )
1260 ROM_REGION( 0x0200, "maincpu", 0 )
1261 ROM_LOAD( "cop410l_b_nne", 0x0000, 0x0200, CRC(d861b80c) SHA1(4652f8ee0dd4c3c48b625285bb4f094d96434071) )
1262 ROM_END
1263
1264
1265
1266
1267
1268 /***************************************************************************
1269
1270 Milton Bradley Electronic Lightfight
1271 * COP421L MCU label /B119 COP421L-HLA/N
1272 * LED matrix, 1-bit sound
1273
1274 Xbox-shaped electronic game for 2 or more players, with long diagonal buttons
1275 next to each outer LED. The main object of the game is to pinpoint a light
1276 by pressing 2 buttons. To start, press a skill-level button(P2 button 7/8/9)
1277 after selecting a game mode(P1 button 6-10).
1278
1279 The game variations are:
1280 1: LightFight
1281 2: NightFight
1282 3: RiteSite
1283 4: QuiteBrite
1284 5: RightLight
1285
1286 ***************************************************************************/
1287
1288 class lightfgt_state : public hh_cop400_state
1289 {
1290 public:
lightfgt_state(const machine_config & mconfig,device_type type,const char * tag)1291 lightfgt_state(const machine_config &mconfig, device_type type, const char *tag) :
1292 hh_cop400_state(mconfig, type, tag)
1293 { }
1294
1295 void update_display();
1296 DECLARE_WRITE_LINE_MEMBER(write_so);
1297 void write_d(u8 data);
1298 void write_l(u8 data);
1299 u8 read_g();
1300 void lightfgt(machine_config &config);
1301 };
1302
1303 // handlers
1304
update_display()1305 void lightfgt_state::update_display()
1306 {
1307 u8 grid = (m_so | m_d << 1) ^ 0x1f;
1308 m_display->matrix(grid, m_l);
1309 }
1310
WRITE_LINE_MEMBER(lightfgt_state::write_so)1311 WRITE_LINE_MEMBER(lightfgt_state::write_so)
1312 {
1313 // SO: led grid 0 (and input mux)
1314 m_so = state;
1315 update_display();
1316 }
1317
write_d(u8 data)1318 void lightfgt_state::write_d(u8 data)
1319 {
1320 // D: led grid 1-4 (and input mux)
1321 m_d = data;
1322 update_display();
1323 }
1324
write_l(u8 data)1325 void lightfgt_state::write_l(u8 data)
1326 {
1327 // L0-L4: led state
1328 // L5-L7: N/C
1329 m_l = data & 0x1f;
1330 update_display();
1331 }
1332
read_g()1333 u8 lightfgt_state::read_g()
1334 {
1335 // G: multiplexed inputs
1336 m_inp_mux = m_d << 1 | m_so;
1337 return read_inputs(5, 0xf);
1338 }
1339
1340 // config
1341
1342 static INPUT_PORTS_START( lightfgt )
1343 PORT_START("IN.0") // SO port G
1344 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON6 )
1345 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) // note: button 1 is on the left side from player perspective
1346 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_COCKTAIL
1347 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON10 ) PORT_COCKTAIL
1348
1349 PORT_START("IN.1") // D0 port G
1350 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON7 )
1351 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 )
1352 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_COCKTAIL
1353 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON9 ) PORT_COCKTAIL
1354
1355 PORT_START("IN.2") // D1 port G
1356 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON8 )
1357 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON3 )
1358 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_COCKTAIL
1359 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_COCKTAIL
1360
1361 PORT_START("IN.3") // D2 port G
1362 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON9 )
1363 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON4 )
1364 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_COCKTAIL
1365 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_COCKTAIL
1366
1367 PORT_START("IN.4") // D3 port G
1368 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON10 )
1369 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON5 )
1370 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL
1371 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_COCKTAIL
1372 INPUT_PORTS_END
1373
lightfgt(machine_config & config)1374 void lightfgt_state::lightfgt(machine_config &config)
1375 {
1376 /* basic machine hardware */
1377 COP421(config, m_maincpu, 950000); // approximation - RC osc. R=82K, C=56pF
1378 m_maincpu->set_config(COP400_CKI_DIVISOR_16, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed
1379 m_maincpu->write_so().set(FUNC(lightfgt_state::write_so));
1380 m_maincpu->write_d().set(FUNC(lightfgt_state::write_d));
1381 m_maincpu->write_l().set(FUNC(lightfgt_state::write_l));
1382 m_maincpu->write_sk().set(m_speaker, FUNC(speaker_sound_device::level_w));
1383 m_maincpu->read_g().set(FUNC(lightfgt_state::read_g));
1384
1385 /* video hardware */
1386 PWM_DISPLAY(config, m_display).set_size(5, 5);
1387 config.set_default_layout(layout_lightfgt);
1388
1389 /* sound hardware */
1390 SPEAKER(config, "mono").front_center();
1391 SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
1392 }
1393
1394 // roms
1395
1396 ROM_START( lightfgt )
1397 ROM_REGION( 0x0400, "maincpu", 0 )
1398 ROM_LOAD( "cop421l-hla_n", 0x0000, 0x0400, CRC(aceb2d65) SHA1(2328cbb195faf93c575f3afa3a1fe0079180edd7) )
1399 ROM_END
1400
1401
1402
1403
1404
1405 /***************************************************************************
1406
1407 Milton Bradley Electronic Battleship (1982 version)
1408 * COP420 MCU label COP420-JWE/N
1409
1410 see hh_tms1k.cpp bship driver for more information
1411
1412 ***************************************************************************/
1413
1414 class bship82_state : public hh_cop400_state
1415 {
1416 public:
bship82_state(const machine_config & mconfig,device_type type,const char * tag)1417 bship82_state(const machine_config &mconfig, device_type type, const char *tag) :
1418 hh_cop400_state(mconfig, type, tag)
1419 { }
1420
1421 void write_d(u8 data);
1422 u8 read_l();
1423 u8 read_in();
1424 DECLARE_WRITE_LINE_MEMBER(write_so);
1425 void bship82(machine_config &config);
1426 };
1427
1428 // handlers
1429
write_d(u8 data)1430 void bship82_state::write_d(u8 data)
1431 {
1432 // D: input mux
1433 m_inp_mux = data;
1434 }
1435
read_l()1436 u8 bship82_state::read_l()
1437 {
1438 // L: multiplexed inputs
1439 return read_inputs(4, 0xff);
1440 }
1441
read_in()1442 u8 bship82_state::read_in()
1443 {
1444 // IN: multiplexed inputs
1445 return read_inputs(4, 0xf00) >> 8;
1446 }
1447
WRITE_LINE_MEMBER(bship82_state::write_so)1448 WRITE_LINE_MEMBER(bship82_state::write_so)
1449 {
1450 // SO: led
1451 m_display->matrix(1, state);
1452 }
1453
1454 // config
1455
1456 static INPUT_PORTS_START( bship82 )
1457 PORT_START("IN.0") // D0 ports L,IN
PORT_CODE(KEYCODE_BACKSPACE)1458 PORT_BIT( 0x001, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("P1 Clear Last Entry") // CLE
1459 PORT_BIT( 0x002, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_A) PORT_NAME("P1 A")
1460 PORT_BIT( 0x004, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_B) PORT_NAME("P1 B")
1461 PORT_BIT( 0x008, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_C) PORT_NAME("P1 C")
1462 PORT_BIT( 0x010, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_D) PORT_NAME("P1 D")
1463 PORT_BIT( 0x020, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_NAME("P1 E")
1464 PORT_BIT( 0x040, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_F) PORT_NAME("P1 F")
1465 PORT_BIT( 0x080, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_G) PORT_NAME("P1 G")
1466 PORT_BIT( 0x100, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_H) PORT_NAME("P1 H")
1467 PORT_BIT( 0x200, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_I) PORT_NAME("P1 I")
1468 PORT_BIT( 0x400, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_J) PORT_NAME("P1 J")
1469 PORT_BIT( 0x800, IP_ACTIVE_LOW, IPT_UNUSED )
1470
1471 PORT_START("IN.1") // D1 ports L,IN
1472 PORT_BIT( 0x001, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_DEL) PORT_NAME("P1 Clear Memory") // CM
1473 PORT_BIT( 0x002, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("P1 1")
1474 PORT_BIT( 0x004, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("P1 2")
1475 PORT_BIT( 0x008, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("P1 3")
1476 PORT_BIT( 0x010, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("P1 4")
1477 PORT_BIT( 0x020, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("P1 5")
1478 PORT_BIT( 0x040, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("P1 6")
1479 PORT_BIT( 0x080, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("P1 7")
1480 PORT_BIT( 0x100, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("P1 8")
1481 PORT_BIT( 0x200, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("P1 9")
1482 PORT_BIT( 0x400, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("P1 10")
1483 PORT_BIT( 0x800, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("P1 Fire")
1484
1485 PORT_START("IN.2") // D2 ports L,IN
1486 PORT_BIT( 0x001, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 Clear Last Entry") // CLE
1487 PORT_BIT( 0x002, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 A")
1488 PORT_BIT( 0x004, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 B")
1489 PORT_BIT( 0x008, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 C")
1490 PORT_BIT( 0x010, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 D")
1491 PORT_BIT( 0x020, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 E")
1492 PORT_BIT( 0x040, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 F")
1493 PORT_BIT( 0x080, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 G")
1494 PORT_BIT( 0x100, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 H")
1495 PORT_BIT( 0x200, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 I")
1496 PORT_BIT( 0x400, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 J")
1497 PORT_BIT( 0x800, IP_ACTIVE_LOW, IPT_UNUSED )
1498
1499 PORT_START("IN.3") // D3 ports L,IN
1500 PORT_BIT( 0x001, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 Clear Memory") // CM
1501 PORT_BIT( 0x002, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 1")
1502 PORT_BIT( 0x004, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 2")
1503 PORT_BIT( 0x008, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 3")
1504 PORT_BIT( 0x010, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 4")
1505 PORT_BIT( 0x020, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 5")
1506 PORT_BIT( 0x040, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 6")
1507 PORT_BIT( 0x080, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 7")
1508 PORT_BIT( 0x100, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 8")
1509 PORT_BIT( 0x200, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 9")
1510 PORT_BIT( 0x400, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 10")
1511 PORT_BIT( 0x800, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("P2 Fire")
1512
1513 PORT_START("IN.4") // SI
1514 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_CODE(KEYCODE_F1) PORT_NAME("Load/Go") // switch
1515 INPUT_PORTS_END
1516
1517 /*
1518
1519 http://www.seanriddle.com/bship82.txt
1520
1521 21 G0 3.9K resistor to speaker transistor base
1522 22 G1 2.2K resistor to speaker transistor base
1523 23 G2 1.0K resistor to speaker transistor base
1524 24 G3 speaker transistor base tied high 4.7K
1525
1526 speaker connection
1527 2N3904 transistor:
1528 emitter to 10ohm resistor to ground
1529 collector to 68ohm resistor to speaker (other speaker terminal to VCC)
1530 base pulled high with 4.7K resistor, connects directly to G3, 1K resistor to G2,
1531 2.2K resistor to G1, 3.9K resistor to G0
1532
1533 */
1534
1535 void bship82_state::bship82(machine_config &config)
1536 {
1537 /* basic machine hardware */
1538 COP420(config, m_maincpu, 750000); // approximation - RC osc. R=14K, C=100pF
1539 m_maincpu->set_config(COP400_CKI_DIVISOR_4, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed
1540 m_maincpu->write_d().set(FUNC(bship82_state::write_d));
1541 m_maincpu->write_g().set("dac", FUNC(dac_byte_interface::data_w));
1542 m_maincpu->read_l().set(FUNC(bship82_state::read_l));
1543 m_maincpu->read_in().set(FUNC(bship82_state::read_in));
1544 m_maincpu->write_so().set(FUNC(bship82_state::write_so));
1545 m_maincpu->read_si().set_ioport("IN.4");
1546
1547 /* video hardware */
1548 PWM_DISPLAY(config, m_display).set_size(1, 1);
1549 config.set_default_layout(layout_bship82);
1550
1551 /* sound hardware */
1552 SPEAKER(config, "mono").front_center();
1553 DAC_4BIT_BINARY_WEIGHTED_SIGN_MAGNITUDE(config, "dac").add_route(ALL_OUTPUTS, "mono", 0.125); // see above
1554 }
1555
1556 // roms
1557
1558 ROM_START( bship82 )
1559 ROM_REGION( 0x0400, "maincpu", 0 )
1560 ROM_LOAD( "cop420-jwe_n", 0x0000, 0x0400, CRC(5ea8111a) SHA1(34931463b806b48dce4f8ae2361512510bae0ebf) )
1561 ROM_END
1562
1563
1564
1565
1566
1567 /***************************************************************************
1568
1569 National Semiconductor QuizKid Racer (COP420 version)
1570 * COP420 MCU label COP420-NPG/N
1571 * 8-digit 7seg led display(1 custom digit), 1 green led, no sound
1572
1573 This is the COP420 version, the first release was on a MM5799 MCU.
1574
1575 ***************************************************************************/
1576
1577 class qkracer_state : public hh_cop400_state
1578 {
1579 public:
qkracer_state(const machine_config & mconfig,device_type type,const char * tag)1580 qkracer_state(const machine_config &mconfig, device_type type, const char *tag) :
1581 hh_cop400_state(mconfig, type, tag)
1582 { }
1583
1584 void update_display();
1585 void write_d(u8 data);
1586 void write_g(u8 data);
1587 void write_l(u8 data);
1588 u8 read_in();
1589 DECLARE_WRITE_LINE_MEMBER(write_sk);
1590 void qkracer(machine_config &config);
1591 };
1592
1593 // handlers
1594
update_display()1595 void qkracer_state::update_display()
1596 {
1597 m_display->matrix(~(m_d | m_g << 4 | m_sk << 8), m_l);
1598 }
1599
write_d(u8 data)1600 void qkracer_state::write_d(u8 data)
1601 {
1602 // D: select digit, D3: input mux high bit
1603 m_inp_mux = (m_inp_mux & 0xf) | (data << 1 & 0x10);
1604 m_d = data & 0xf;
1605 update_display();
1606 }
1607
write_g(u8 data)1608 void qkracer_state::write_g(u8 data)
1609 {
1610 // G: select digit, input mux
1611 m_inp_mux = (m_inp_mux & 0x10) | (data & 0xf);
1612 m_g = data & 0xf;
1613 update_display();
1614 }
1615
write_l(u8 data)1616 void qkracer_state::write_l(u8 data)
1617 {
1618 // L0-L6: digit segment data
1619 m_l = data & 0x7f;
1620 update_display();
1621 }
1622
read_in()1623 u8 qkracer_state::read_in()
1624 {
1625 // IN: multiplexed inputs
1626 return read_inputs(5, 0xf);
1627 }
1628
WRITE_LINE_MEMBER(qkracer_state::write_sk)1629 WRITE_LINE_MEMBER(qkracer_state::write_sk)
1630 {
1631 // SK: green led
1632 m_sk = state;
1633 update_display();
1634 }
1635
1636 // config
1637
1638 static INPUT_PORTS_START( qkracer )
1639 PORT_START("IN.0") // G0 port IN
PORT_CODE(KEYCODE_7)1640 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7")
1641 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8")
1642 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9")
1643 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_SLASH_PAD) PORT_NAME(UTF8_DIVIDE)
1644
1645 PORT_START("IN.1") // G1 port IN
1646 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4")
1647 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5")
1648 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6")
1649 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_ASTERISK) PORT_NAME(UTF8_MULTIPLY)
1650
1651 PORT_START("IN.2") // G2 port IN
1652 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1")
1653 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2")
1654 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3")
1655 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_MINUS_PAD) PORT_NAME("-")
1656
1657 PORT_START("IN.3") // G3 port IN
1658 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_MINUS) PORT_NAME("Slow")
1659 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_EQUALS) PORT_NAME("Fast")
1660 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0")
1661 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_PLUS_PAD) PORT_NAME("+")
1662
1663 PORT_START("IN.4") // D3 port IN
1664 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_Q) PORT_NAME("Amateur")
1665 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_W) PORT_NAME("Pro")
1666 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_NAME("Complex")
1667 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) PORT_NAME("Tables")
1668 INPUT_PORTS_END
1669
1670 void qkracer_state::qkracer(machine_config &config)
1671 {
1672 /* basic machine hardware */
1673 COP420(config, m_maincpu, 1000000); // approximation - RC osc. R=47K, C=100pF
1674 m_maincpu->set_config(COP400_CKI_DIVISOR_32, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed
1675 m_maincpu->write_d().set(FUNC(qkracer_state::write_d));
1676 m_maincpu->write_g().set(FUNC(qkracer_state::write_g));
1677 m_maincpu->write_l().set(FUNC(qkracer_state::write_l));
1678 m_maincpu->read_in().set(FUNC(qkracer_state::read_in));
1679 m_maincpu->write_sk().set(FUNC(qkracer_state::write_sk));
1680
1681 /* video hardware */
1682 PWM_DISPLAY(config, m_display).set_size(9, 7);
1683 m_display->set_segmask(0xdf, 0x7f);
1684 m_display->set_segmask(0x20, 0x41); // equals sign
1685 config.set_default_layout(layout_qkracer);
1686
1687 /* no sound! */
1688 }
1689
1690 // roms
1691
1692 ROM_START( qkracer )
1693 ROM_REGION( 0x0400, "maincpu", 0 )
1694 ROM_LOAD( "cop420-npg_n", 0x0000, 0x0400, CRC(17f8e538) SHA1(23d1a1819e6ba552d8da83da2948af1cf5b13d5b) )
1695 ROM_END
1696
1697
1698
1699
1700
1701 /***************************************************************************
1702
1703 Select Merchandise Video Challenger
1704 * COP420 MCU label COP420-TDX/N
1705 * 6-digit 7seg led display, 3 other leds, 4-bit sound
1706
1707 This is a lightgun with scorekeeping. The "games" themselves were released
1708 on VHS tapes. To determine scoring, the lightgun detects strobe lighting
1709 from objects in the video.
1710
1711 known releases:
1712 - Japan: Video Challenger, published by Takara
1713 - UK: Video Challenger, published by Bandai
1714 - Canada: Video Challenger, published by Irwin
1715
1716 ***************************************************************************/
1717
1718 class vidchal_state : public hh_cop400_state
1719 {
1720 public:
vidchal_state(const machine_config & mconfig,device_type type,const char * tag)1721 vidchal_state(const machine_config &mconfig, device_type type, const char *tag) :
1722 hh_cop400_state(mconfig, type, tag)
1723 { }
1724
1725 void update_display();
1726 void write_d(u8 data);
1727 void write_l(u8 data);
1728 DECLARE_WRITE_LINE_MEMBER(write_sk);
1729 void vidchal(machine_config &config);
1730 };
1731
1732 // handlers
1733
update_display()1734 void vidchal_state::update_display()
1735 {
1736 m_display->matrix(m_d | m_sk << 6, m_l);
1737 }
1738
write_d(u8 data)1739 void vidchal_state::write_d(u8 data)
1740 {
1741 // D: CD4028BE to digit select
1742 m_d = 1 << data & 0x3f;
1743 update_display();
1744 }
1745
write_l(u8 data)1746 void vidchal_state::write_l(u8 data)
1747 {
1748 // L: digit segment data
1749 m_l = bitswap<8>(data,0,3,1,5,4,7,2,6);
1750 update_display();
1751 }
1752
WRITE_LINE_MEMBER(vidchal_state::write_sk)1753 WRITE_LINE_MEMBER(vidchal_state::write_sk)
1754 {
1755 // SK: hit led
1756 m_sk = state;
1757 update_display();
1758 }
1759
1760 // config
1761
1762 static INPUT_PORTS_START( vidchal )
1763 PORT_START("IN.0") // port IN
1764 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 )
1765 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
1766 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_CODE(KEYCODE_F1)1767 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_F1) PORT_NAME("Light Sensor")
1768 INPUT_PORTS_END
1769
1770 void vidchal_state::vidchal(machine_config &config)
1771 {
1772 /* basic machine hardware */
1773 COP420(config, m_maincpu, 900000); // approximation
1774 m_maincpu->set_config(COP400_CKI_DIVISOR_4, COP400_CKO_OSCILLATOR_OUTPUT, false); // guessed
1775 m_maincpu->write_d().set(FUNC(vidchal_state::write_d));
1776 m_maincpu->write_g().set("dac", FUNC(dac_byte_interface::data_w));
1777 m_maincpu->write_l().set(FUNC(vidchal_state::write_l));
1778 m_maincpu->read_in().set_ioport("IN.0");
1779 m_maincpu->write_sk().set(FUNC(vidchal_state::write_sk));
1780
1781 /* video hardware */
1782 PWM_DISPLAY(config, m_display).set_size(6+1, 8);
1783 m_display->set_segmask(0x3f, 0xff);
1784 config.set_default_layout(layout_vidchal);
1785
1786 /* sound hardware */
1787 SPEAKER(config, "mono").front_center();
1788 DAC_4BIT_BINARY_WEIGHTED_SIGN_MAGNITUDE(config, "dac").add_route(ALL_OUTPUTS, "mono", 0.125); // unknown DAC
1789 }
1790
1791 // roms
1792
1793 ROM_START( vidchal )
1794 ROM_REGION( 0x0400, "maincpu", 0 )
1795 ROM_LOAD( "cop420-tdx_n", 0x0000, 0x0400, CRC(c9bd041c) SHA1(ab0dcaf4741620fa4c28ab75337a23d646af7626) )
1796 ROM_END
1797
1798
1799
1800 } // anonymous namespace
1801
1802 /***************************************************************************
1803
1804 Game driver(s)
1805
1806 ***************************************************************************/
1807
1808 // YEAR NAME PARENT CMP MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS
1809 CONS( 1979, ctstein, 0, 0, ctstein, ctstein, ctstein_state, empty_init, "Castle Toy", "Einstein (Castle Toy)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
1810
1811 CONS( 1980, h2hbaskbc, h2hbaskb, 0, h2hbaskbc, h2hbaskbc, h2hbaskbc_state, empty_init, "Coleco", "Head to Head: Electronic Basketball (COP420L version)", MACHINE_SUPPORTS_SAVE )
1812 CONS( 1980, h2hhockeyc, h2hhockey, 0, h2hhockeyc, h2hhockeyc, h2hbaskbc_state, empty_init, "Coleco", "Head to Head: Electronic Hockey (COP420L version)", MACHINE_SUPPORTS_SAVE )
1813 CONS( 1980, h2hsoccerc, 0, 0, h2hsoccerc, h2hsoccerc, h2hbaskbc_state, empty_init, "Coleco", "Head to Head: Electronic Soccer (COP420L version)", MACHINE_SUPPORTS_SAVE )
1814
1815 CONS( 1981, einvaderc, einvader, 0, einvaderc, einvaderc, einvaderc_state, empty_init, "Entex", "Space Invader (Entex, COP444L version)", MACHINE_SUPPORTS_SAVE )
1816
1817 CONS( 1980, unkeinv, 0, 0, unkeinv, unkeinv, unkeinv_state, empty_init, "Gordon Barlow Design", "unknown electronic Space Invaders game (patent)", MACHINE_SUPPORTS_SAVE )
1818
1819 CONS( 1980, lchicken, 0, 0, lchicken, lchicken, lchicken_state, empty_init, "LJN", "I Took a Lickin' From a Chicken", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_MECHANICAL )
1820
1821 CONS( 1979, funjacks, 0, 0, funjacks, funjacks, funjacks_state, empty_init, "Mattel", "Funtronics: Jacks", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
1822 CONS( 1979, funrlgl, 0, 0, funrlgl, funrlgl, funrlgl_state, empty_init, "Mattel", "Funtronics: Red Light Green Light", MACHINE_SUPPORTS_SAVE )
1823 CONS( 1981, mdallas, 0, 0, mdallas, mdallas, mdallas_state, empty_init, "Mattel", "Dalla$ (J.R. handheld)", MACHINE_SUPPORTS_SAVE ) // ***
1824
1825 CONS( 1980, plus1, 0, 0, plus1, plus1, plus1_state, empty_init, "Milton Bradley", "Plus One", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_CONTROLS ) // ***
1826 CONS( 1981, lightfgt, 0, 0, lightfgt, lightfgt, lightfgt_state, empty_init, "Milton Bradley", "Electronic Lightfight - The Games of Dueling Lights", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
1827 CONS( 1982, bship82, bship, 0, bship82, bship82, bship82_state, empty_init, "Milton Bradley", "Electronic Battleship (1982 version)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) // ***
1828
1829 CONS( 1978, qkracer, 0, 0, qkracer, qkracer, qkracer_state, empty_init, "National Semiconductor", "QuizKid Racer (COP420 version)", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND_HW )
1830
1831 CONS( 1987, vidchal, 0, 0, vidchal, vidchal, vidchal_state, empty_init, "Select Merchandise", "Video Challenger", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING )
1832
1833 // ***: As far as MAME is concerned, the game is emulated fine. But for it to be playable, it requires interaction
1834 // with other, unemulatable, things eg. game board/pieces, playing cards, pen & paper, etc.
1835