1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
|
// license:BSD-3-Clause
// copyright-holders:David Haywood
/*
Radica 'Mega Drive' and 'Genesis' clones
these were mini battery operated "TV Game" consoles with wired in controller and no cartslot
fully licensed by Sega
reproduction 'System on a Chip' hardware, not perfect, flaws will need emulating eventually.
not dumped
Genesis Volume 2
Genesis SF2 / GnG (PAL one is locked to PAL)
Outrun 2019 (probably identical ROM to MD version, just custom controller)
more?
*/
#include "emu.h"
#include "includes/megadriv.h"
#include "includes/megadriv_rad.h"
// todo, use actual MD map, easier once maps are part of base class.
void megadriv_radica_state::megadriv_base_map(address_map &map)
{
map(0x000000, 0x3fffff).r(FUNC(megadriv_radica_state::read)); /* Cartridge Program Rom */
map(0xa00000, 0xa01fff).rw(FUNC(megadriv_radica_state::megadriv_68k_read_z80_ram), FUNC(megadriv_radica_state::megadriv_68k_write_z80_ram));
map(0xa02000, 0xa03fff).w(FUNC(megadriv_radica_state::megadriv_68k_write_z80_ram));
map(0xa04000, 0xa04003).rw(FUNC(megadriv_radica_state::megadriv_68k_YM2612_read), FUNC(megadriv_radica_state::megadriv_68k_YM2612_write));
map(0xa06000, 0xa06001).w(FUNC(megadriv_radica_state::megadriv_68k_z80_bank_write));
map(0xa10000, 0xa1001f).rw(FUNC(megadriv_radica_state::megadriv_68k_io_read), FUNC(megadriv_radica_state::megadriv_68k_io_write));
map(0xa11100, 0xa11101).rw(FUNC(megadriv_radica_state::megadriv_68k_check_z80_bus), FUNC(megadriv_radica_state::megadriv_68k_req_z80_bus));
map(0xa11200, 0xa11201).w(FUNC(megadriv_radica_state::megadriv_68k_req_z80_reset));
map(0xc00000, 0xc0001f).rw(m_vdp, FUNC(sega315_5313_device::vdp_r), FUNC(sega315_5313_device::vdp_w));
map(0xe00000, 0xe0ffff).ram().mirror(0x1f0000).share("megadrive_ram");
}
void megadriv_radica_state::megadriv_radica_map(address_map &map)
{
megadriv_base_map(map);
map(0xa13000, 0xa130ff).r(FUNC(megadriv_radica_state::read_a13));
}
uint16_t megadriv_dgunl_state::read_a16300(offs_t offset, uint16_t mem_mask)
{
return 0x5a5a;
}
uint16_t megadriv_dgunl_state::read_a16302(offs_t offset, uint16_t mem_mask)
{
return m_a1630a;
}
void megadriv_dgunl_state::write_a1630a(offs_t offset, uint16_t data, uint16_t mem_mask)
{
m_a1630a = data;
m_bank = (data & 0x07) * 8;
}
void megadriv_ra145_state::write_a1630a(offs_t offset, uint16_t data, uint16_t mem_mask)
{
// the banking must know how big each game is to get the base location, as it only writes a game number?!
// it must also know to skip the unused copy of Golden Axe
// there must be a table somewhere, or, if this is actually an emulation based system, it must be scanning
// for headers somehow?
m_a1630a = data;
switch (data & 0xff)
{
// 0x0000000 = Block of unknown data/code
// 0x0040000 = 145 in 1 menu
// (includes unused Columns, Fatal Labyrinth, Blockout, Flicky, Shove It, Space Invaders 90 as part of menu data)
case 0x00: m_bank = 0x02c0000; break;// = Fantasia 00
case 0x01: m_bank = 0x0340000; break;// = Fire Shark 01
case 0x02: m_bank = 0x03c0000; break;// = James Bond 007 - The Duel 02 (BAD ROM)
case 0x03: m_bank = 0x0440000; break;// = Sunset Riders 03
case 0x04: m_bank = 0x04c0000; break;// = Robocop 3 04
case 0x05: m_bank = 0x0540000; break;// = Hokuto no Ken 05 (BAD ROM)
case 0x06: m_bank = 0x05c0000; break;// = Alien 3 06
case 0x07: m_bank = 0x0640000; break;// = Batman 07 (BAD ROM)
case 0x08: m_bank = 0x06c0000; break;// = Cat 08
case 0x09: m_bank = 0x0740000; break;// = DJ Boy 09
case 0x0a: m_bank = 0x07c0000; break;// = Rambo 3 0a (BAD ROM)
case 0x0b: m_bank = 0x0840000; break;// = Wardner 0b
case 0x0c: m_bank = 0x08c0000; break;// = Paperboy 0c
case 0x0d: m_bank = 0x0940000; break;// = Streets of Rage 0d
case 0x0e: m_bank = 0x09c0000; break;// = Tiny Toon Adventures 0e
case 0x0f: m_bank = 0x0a40000; break;// = Super Battleship 0f
case 0x10: m_bank = 0x0ac0000; break;// = Burning Force 10
case 0x11: m_bank = 0x0b40000; break;// = Cadash 11
case 0x12: m_bank = 0x0bc0000; break;// = Caesars Palace 12
case 0x13: m_bank = 0x0c40000; break;// = chase HQ 2 13
case 0x14: m_bank = 0x0cc0000; break;// = Wonderboy 3 14
case 0x15: m_bank = 0x0d40000; break;// = Fighting Master 15
case 0x16: m_bank = 0x0dc0000; break;// = The Flintstones 16
case 0x17: m_bank = 0x0e40000; break;// = Ariel the Little Mermaid 17
case 0x18: m_bank = 0x0ec0000; break;// = Hellfire 18
case 0x19: m_bank = 0x0f40000; break;// = Arrow Flash 19
case 0x1a: m_bank = 0x0fc0000; break;// = Shove It 1a
case 0x1b: m_bank = 0x1040000; break;// = Donkey Kong 99 1b
case 0x1c: m_bank = 0x1240000; break;// = Turtles Tournament 1c
case 0x1d: m_bank = 0x1440000; break;// = Thunder Force 2 1d (This is meant to be Revenge of Shinobi according to the menu, but incorrect game was in the ROM)
case 0x1e: m_bank = 0x14c0000; break;// = Wings of Wor 1e
case 0x1f: m_bank = 0x1540000; break;// = Wrestle War 1f
case 0x20: m_bank = 0x15c0000; break;// = Afterburner 2 20
case 0x21: m_bank = 0x1640000; break;// = Altered Beast 21
case 0x22: m_bank = 0x16c0000; break;// = Captain Planet 22
case 0x23: m_bank = 0x1740000; break;// = Bimimi Run 23
case 0x24: m_bank = 0x17c0000; break;// = Osomatsu 24
case 0x25: m_bank = 0x1840000; break;// = Castle of Illusion 25
case 0x26: m_bank = 0x18c0000; break;// = Crackdown 26
case 0x27: m_bank = 0x1940000; break;// = Crossfire 27
case 0x28: m_bank = 0x19c0000; break;// = Curse 28
case 0x29: m_bank = 0x1a40000; break;// = Dangerous Seed 29
case 0x2a: m_bank = 0x1ac0000; break;// = Dark Castle 2a
case 0x2b: m_bank = 0x1b40000; break;// = Darwin 2b
case 0x2c: m_bank = 0x1bc0000; break;// = Thunder Force 2 (duplicate?) 2c
case 0x2d: m_bank = 0x1c40000; break;// = Dynamite Duke 2d
case 0x2e: m_bank = 0x1cc0000; break;// = EA Hockey 2e
case 0x2f: m_bank = 0x1d40000; break;// = Elemenal Master 2f
case 0x30: m_bank = 0x1dc0000; break;// = Super Thunder Blade 30
case 0x31: m_bank = 0x1e40000; break;// = Target Earth 31
case 0x32: m_bank = 0x1ec0000; break;// = Rastan Saga 2 32
case 0x33: m_bank = 0x1f40000; break;// = Ghostbusters 33
case 0x34: m_bank = 0x1fc0000; break;// = Mahjong cop 34
case 0x35: m_bank = 0x2040000; break;// = High School Soccer 35
case 0x36: m_bank = 0x20c0000; break;// = Insector X 36
case 0x37: m_bank = 0x2140000; break;// = Pheilos 37
case 0x38: m_bank = 0x21c0000; break;// = Runark 38
case 0x39: m_bank = 0x2240000; break;// = Saint Sword 39
case 0x3a: m_bank = 0x22c0000; break;// = Shadow Dancer 3a
case 0x3b: m_bank = 0x2340000; break;// = Shiten Myooh 3b
case 0x3c: m_bank = 0x23c0000; break;// = Wani Wani World 3c
case 0x3d: m_bank = 0x2440000; break;// = Street Mmart 3d
case 0x3e: m_bank = 0x24c0000; break;// = Toki 3e
case 0x3f: m_bank = 0x2540000; break;// = Trouble Shooter 3f
case 0x40: m_bank = 0x25c0000; break;// = Truxton 40
case 0x41: m_bank = 0x2640000; break;// = James Pond 2 41
case 0x42: m_bank = 0x26c0000; break;// = Twin Hawk 42
case 0x43: m_bank = 0x2740000; break;// = Syd of Valis 43
case 0x44: m_bank = 0x27c0000; break;// = Zoom 44
case 0x45: m_bank = 0x2840000; break;// = Streets of Rage 2 45
case 0x46: m_bank = 0x2a40000; break;// = Sonic & Knuckles 46
case 0x47: m_bank = 0x2c40000; break;// = Comix Zone 47
case 0x48: m_bank = 0x2e40000; break;// = Rolling Thunder 2 48
case 0x49: m_bank = 0x2f40000; break;// = Bubble & Squeek 49
case 0x4a: m_bank = 0x2fc0000; break;// = Alex Kidd 4a
case 0x4b: m_bank = 0x3040000; break;// = Super Mario 2 4b
case 0x4c: m_bank = 0x3240000; break;// = NBA All Star 4c
case 0x4d: m_bank = 0x3340000; break;// = Bio Hazard Battle 4d
case 0x4e: m_bank = 0x3440000; break;// = Prince of Persia 4e
case 0x4f: m_bank = 0x3540000; break;// = Champions World Soccer 4f
case 0x50: m_bank = 0x3640000; break;// = Lotus 2 50
case 0x51: m_bank = 0x3740000; break;// = Grandia 51
case 0x52: m_bank = 0x37c0000; break;// = World Cup Soccer 52
case 0x53: m_bank = 0x3840000; break;// = Ultimate Mortal Kombat 3 53
case 0x54: m_bank = 0x3c40000; break;// = Street Fighter II (hacked MSI version) 54
case 0x55: m_bank = 0x3f40000; break;// = Verytex 55
case 0x56: m_bank = 0x3fc0000; break;// = Space Invaders 90 56
//This 32MBytes of the ROM has its own unused '666666 in 1 menu' and only references games
//within this block; it was probably released as a standalone using this 32Mbytes of ROM
// 0x4000000 = Block of unknown data/code
// 0x4040000 = 666666 in 1 menu
// (includes unused Columns, Fatal Labyrinth, Blockout, Flicky, Shove It, Space Invaders 90 as part of menu data)
// 0x42c0000 - Golden Axe -- (not used by 145-in-1 menu, no assigned number either?!)
case 0x57: m_bank = 0x4340000; break;// - Mega Bomberman 57
case 0x58: m_bank = 0x4440000; break;// - Dragon The Bruce Lee Story 58
case 0x59: m_bank = 0x4640000; break;// - Twinkle Tale 59
case 0x5a: m_bank = 0x4740000; break;// - Jewel Master 5a
case 0x5b: m_bank = 0x47c0000; break;// - Pacmania 5b
case 0x5c: m_bank = 0x4840000; break;// - X-Men 2 5c
case 0x5d: m_bank = 0x4a40000; break;// - Top Gear 2 5d
case 0x5e: m_bank = 0x4b40000; break;// - Brian Lara Cricket 5e
case 0x5f: m_bank = 0x4c40000; break;// - Garfield 5f
case 0x60: m_bank = 0x4e40000; break;// - Raiden Trad 60
case 0x61: m_bank = 0x4f40000; break;// - James Pond 61
case 0x62: m_bank = 0x4fc0000; break;// - Mega Panel 62
case 0x63: m_bank = 0x5040000; break;// - James Pond 3 63
case 0x64: m_bank = 0x5240000; break;// - Contra Hardcorps 64
case 0x65: m_bank = 0x5440000; break;// - International Superstar Soccer Deluxe 65
case 0x66: m_bank = 0x5640000; break;// - Double Dragon 3 (with Trainer) 66
case 0x67: m_bank = 0x5740000; break;// - Micro Machines 67
case 0x68: m_bank = 0x57c0000; break;// - Hard Drivin' 68
case 0x69: m_bank = 0x5840000; break;// - Dragon Ball Z 69
case 0x6a: m_bank = 0x5a40000; break;// - F1 World Championship Edition 6a
case 0x6b: m_bank = 0x5c40000; break;// - Megaman / Rockman -- (6b, but unused? probably due to save feature?)
case 0x6c: m_bank = 0x5e40000; break;// - Operation Vapor Trail 6c
case 0x6d: m_bank = 0x5f40000; break;// - Roadblasters 6d
case 0x6e: m_bank = 0x5fc0000; break;// - Super Volleyball 6e
//The final 32MBytes of the ROM has its own unused '888888 in 1 menu' and only references games
//within this block; it was probably released as a standalone using this 32Mbytes of ROM
// 0x6000000 = Block of unknown data/code
// 0x6040000 = 888888 in 1 menu
// (includes unused Columns, Fatal Labyrinth, Blockout, Flicky, Shove It, Space Invaders 90 as part of menu data)
case 0x6f: m_bank = 0x62c0000; break;// - Last Battle 6f
case 0x70: m_bank = 0x6340000; break;// - Shinobi III 70
case 0x71: m_bank = 0x6440000; break;// - Mickey Mania 71
case 0x72: m_bank = 0x6640000; break;// - Snow Bros 72
case 0x73: m_bank = 0x6740000; break;// - Space Harrier II 73
case 0x74: m_bank = 0x67c0000; break;// - Volfied 74
case 0x75: m_bank = 0x6840000; break;// - Goofy's Hysterical History Tour 75
case 0x76: m_bank = 0x6940000; break;// - Mighty Max 76
case 0x77: m_bank = 0x6a40000; break;// - Mr Nutz 77
case 0x78: m_bank = 0x6b40000; break;// - Sonic 2 78
case 0x79: m_bank = 0x6c40000; break;// - Ecco Jr. 79
case 0x7a: m_bank = 0x6d40000; break;// - Desert Demolition 7a
case 0x7b: m_bank = 0x6e40000; break;// - Midnight Resistance 7b
case 0x7c: m_bank = 0x6f40000; break;// - Spiderman vs The Kingpin 7c
case 0x7d: m_bank = 0x6fc0000; break;// - Trampoline Terror 7d
case 0x7e: m_bank = 0x7040000; break;// - MUSHA 7e
case 0x7f: m_bank = 0x70c0000; break;// - Sonic 7f
case 0x80: m_bank = 0x7140000; break;// - Thunder Force III 80
case 0x81: m_bank = 0x71c0000; break;// - Golden Axe (again) 81
// 0x7240000; break;// - Controller Test Menu -- (unused)
// 0x7340000; break;// - Controller Test Menu (again) -- (unused)
case 0x82: m_bank = 0x7440000; break;// - Wacky Worlds 82 (writes 93, incorrectly swapped in menu with Wacky Worlds)
case 0x83: m_bank = 0x7540000; break;// - Bonkers 83
case 0x84: m_bank = 0x7640000; break;// - Alisia Dragoon 84
case 0x85: m_bank = 0x7740000; break;// - Super Hang On 85
case 0x86: m_bank = 0x77c0000; break;// - Dragon's Eye Shanghai 3 86
case 0x87: m_bank = 0x7840000; break;// - Jimmy White's Whirlwind Snooker 87
case 0x88: m_bank = 0x78c0000; break;// - Home Alone 2 88
case 0x89: m_bank = 0x7940000; break;// - Xenon 2 (with trainer) 89
case 0x8a: m_bank = 0x79c0000; break;// - Hit the Ice 8a
case 0x8b: m_bank = 0x7a40000; break;// - Tale Spin 8b
case 0x8c: m_bank = 0x7ac0000; break;// - Puyo Puyo 8c
case 0x8d: m_bank = 0x7b40000; break;// - Rampart (with trainer) 8d
case 0x8e: m_bank = 0x7bc0000; break;// - Crue Ball 8e
case 0x8f: m_bank = 0x7c40000; break;// - Marble Madness 8f
case 0x90: m_bank = 0x7cc0000; break;// - Patlabor 90
case 0x91: m_bank = 0x7d40000; break;// - The Aquatic Games 91
case 0x92: m_bank = 0x7dc0000; break;// - King Salmon 92
case 0x93: m_bank = 0x7e40000; break;// - Fun n Games 93 (writes 82, incorrectly swapped in menu with Fun n Games)
case 0x94: m_bank = 0x7f40000; break;// - Gynoug 94
case 0x95: m_bank = 0x7fc0000; break;// - Ms. Pac-Man 95
default: m_bank = 0x0040000; break;
}
m_bank = m_bank / 0x10000;
}
void megadriv_dgunl_state::megadriv_dgunl_map(address_map &map)
{
megadriv_base_map(map);
map(0xa16300, 0xa16301).r(FUNC(megadriv_dgunl_state::read_a16300));
map(0xa16302, 0xa16303).r(FUNC(megadriv_dgunl_state::read_a16302));
map(0xa1630a, 0xa1630b).w(FUNC(megadriv_dgunl_state::write_a1630a));
}
uint16_t megadriv_radica_state::read(offs_t offset)
{
return m_rom[(((m_bank * 0x10000) + (offset << 1)) & (m_romsize - 1))/2];
}
uint16_t megadriv_radica_state::read_a13(offs_t offset)
{
if (offset < 0x80)
m_bank = offset & 0x3f;
// low bit gets set when selecting cannon fodder or mega lo mania in the rad_ssoc set, pointing to the wrong area, but rad_gen1 needs it for the menu
// as they're standalones it could just be different logic
if (m_bank != 0x3f)
m_bank &= 0x3e;
return 0;
}
// controller is wired directly into unit, no controller slots
static INPUT_PORTS_START( megadriv_radica_3button )
PORT_INCLUDE( md_common )
PORT_MODIFY("PAD1")
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START1 )
PORT_MODIFY("PAD2")
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START2 )
INPUT_PORTS_END
// the 6-in-1 and Sonic Gold units really only have a single wired controller, and no way to connect a 2nd one, despite having some 2 player games!
static INPUT_PORTS_START( megadriv_radica_3button_1player )
PORT_INCLUDE( megadriv_radica_3button )
PORT_MODIFY("PAD2")
PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
INPUT_PORTS_END
static INPUT_PORTS_START( megadriv_radica_6button )
PORT_INCLUDE( megadriv_radica_3button )
PORT_START("EXTRA1") /* Extra buttons for Joypad 1 (6 button + start + mode) NOT READ DIRECTLY */
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(1)
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(1)
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1)
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("EXTRA2") /* Extra buttons for Joypad 2 (6 button + start + mode) NOT READ DIRECTLY */
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(2)
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(2)
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2)
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("IN0")
PORT_START("UNK")
INPUT_PORTS_END
static INPUT_PORTS_START( megadriv_msi_6button )
PORT_INCLUDE( megadriv_radica_3button )
PORT_START("EXTRA1") /* Extra buttons for Joypad 1 (6 button + start + mode) NOT READ DIRECTLY */
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(1)
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(1)
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1)
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("EXTRA2") // no 2nd pad
PORT_BIT( 0x000f, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_MODIFY("PAD2") // no 2nd pad
PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("IN0")
PORT_START("UNK")
INPUT_PORTS_END
static INPUT_PORTS_START( megadriv_dgunl_1player )
PORT_INCLUDE( megadriv_radica_3button )
PORT_MODIFY("PAD1") // the unit only has 2 buttons, A and C, strings are changed to remove references to C, even if behavior in Pac-Mania still exists and differs between them
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNUSED ) // disable 'C'
//PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED ) // disable 'A'
PORT_MODIFY("PAD2")
PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
INPUT_PORTS_END
void megadriv_radica_6button_state::machine_start()
{
md_base_state::machine_start();
m_vdp->stop_timers();
m_io_pad_6b[0] = ioport("EXTRA1");
m_io_pad_6b[1] = ioport("EXTRA2");
m_io_pad_6b[2] = ioport("IN0");
m_io_pad_6b[3] = ioport("UNK");
// setup timers for 6 button pads
for (int i = 0; i < 3; i++)
m_io_timeout[i] = timer_alloc(FUNC(md_base_state::io_timeout_timer_callback), this);
save_item(NAME(m_bank));
}
void megadriv_radica_3button_state::machine_start()
{
md_base_state::machine_start();
m_vdp->stop_timers();
save_item(NAME(m_bank));
}
void megadriv_dgunl_state::machine_start()
{
megadriv_radica_3button_state::machine_start();
m_a1630a = 0;
save_item(NAME(m_a1630a));
}
void megadriv_ra145_state::machine_start()
{
md_base_state::machine_start();
m_vdp->stop_timers();
m_io_pad_6b[0] = ioport("EXTRA1");
m_io_pad_6b[1] = ioport("EXTRA2");
m_io_pad_6b[2] = ioport("IN0");
m_io_pad_6b[3] = ioport("UNK");
// setup timers for 6 button pads
for (int i = 0; i < 3; i++)
m_io_timeout[i] = timer_alloc(FUNC(md_base_state::io_timeout_timer_callback), this);
m_a1630a = 0;
save_item(NAME(m_a1630a));
save_item(NAME(m_bank));
}
void megadriv_ra145_state::machine_reset()
{
m_bank = 4;
md_base_state::machine_reset();
}
void megadriv_radica_3button_state::machine_reset()
{
m_bank = 0;
md_base_state::machine_reset();
}
void megadriv_radica_3button_state::megadriv_radica_3button_ntsc(machine_config &config)
{
md_ntsc(config);
m_maincpu->set_addrmap(AS_PROGRAM, &megadriv_radica_state::megadriv_radica_map);
}
void megadriv_radica_3button_state::megadriv_radica_3button_pal(machine_config &config)
{
md_pal(config);
m_maincpu->set_addrmap(AS_PROGRAM, &megadriv_radica_state::megadriv_radica_map);
}
void megadriv_radica_6button_state::megadriv_radica_6button_pal(machine_config &config)
{
md_pal(config);
m_maincpu->set_addrmap(AS_PROGRAM, &megadriv_radica_state::megadriv_radica_map);
}
void megadriv_radica_6button_state::megadriv_radica_6button_ntsc(machine_config &config)
{
md_ntsc(config);
m_maincpu->set_addrmap(AS_PROGRAM, &megadriv_radica_state::megadriv_radica_map);
}
void megadriv_dgunl_state::megadriv_dgunl_ntsc(machine_config &config)
{
md_ntsc(config);
m_maincpu->set_addrmap(AS_PROGRAM, &megadriv_dgunl_state::megadriv_dgunl_map);
}
ROM_START( rad_sf2 )
ROM_REGION( 0x400000, "maincpu", 0 )
ROM_LOAD16_WORD_SWAP( "radica_megadrive_streetfighter2_usa.bin", 0x000000, 0x400000, CRC(a4426df8) SHA1(091f2a95ebd091141de5bcb83562c6087708cb32) )
ROM_END
ROM_START( rad_sf2p )
ROM_REGION( 0x400000, "maincpu", 0 )
ROM_LOAD16_WORD_SWAP( "radica_megadrive_streetfighter2_uk.bin", 0x000000, 0x400000, CRC(868afb44) SHA1(f4339e36272c18b1d49aa4095127ed18e0961df6) )
ROM_END
ROM_START( rad_gen1 )
ROM_REGION( 0x400000, "maincpu", 0 )
ROM_LOAD16_WORD_SWAP( "radica_megadrive_vol1_blue_usa.bin", 0x000000, 0x400000, CRC(3b4c8438) SHA1(5ed9c053f9ebc8d4bf571d57e562cf347585d158) )
ROM_END
ROM_START( rad_md1 )
ROM_REGION( 0x400000, "maincpu", 0 )
ROM_LOAD16_WORD_SWAP( "radica_megadrive_vol1_blue_europe.bin", 0x000000, 0x400000, CRC(85867db1) SHA1(ddc596e2e68dc872bc0679a2de7a295b4c6d6b8e) )
ROM_END
ROM_START( rad_gen2 )
ROM_REGION( 0x400000, "maincpu", 0 )
ROM_LOAD16_WORD_SWAP( "radica_genesis_vol2_red_usa.bin", 0x000000, 0x400000, CRC(7c1a0f0e) SHA1(a6441f75a4cd48f1563aeafdfbdde00202d4067c) )
ROM_END
ROM_START( rad_md2 )
ROM_REGION( 0x400000, "maincpu", 0 )
ROM_LOAD16_WORD_SWAP( "radica_megadrive_vol2_red_uk.bin", 0x000000, 0x400000, CRC(b68fd025) SHA1(b8f9c505653d6dd2b62840f078f828360faf8abc) )
ROM_END
ROM_START( rad_ssoc )
ROM_REGION( 0x400000, "maincpu", 0 )
ROM_LOAD( "radica_sensiblesoccer_uk.bin", 0x000000, 0x400000, CRC(b8745ab3) SHA1(0ab3f26e5ffd288e5a3a5db676951b9095299eb0) ) // should be byteswapped?
ROM_END
ROM_START( rad_sonic )
ROM_REGION( 0x400000, "maincpu", 0 )
ROM_LOAD16_WORD_SWAP( "radica_supersonicgold_usa.bin", 0x000000, 0x400000, CRC(853c9140) SHA1(cf70a9cdd3be4d8d1b6195698db3a941f4908791) )
ROM_END
ROM_START( rad_sonicp )
ROM_REGION( 0x400000, "maincpu", 0 )
ROM_LOAD16_WORD_SWAP( "radica_supersonicgold_uk.bin", 0x000000, 0x400000, CRC(ed774018) SHA1(cc2f7183e128c947463e3a43a0184b835ea16db8) )
ROM_END
// once byteswapped this matches "outrun 2019 (usa) (beta).bin megadriv:outr2019up Out Run 2019 (USA, Prototype)"
// this was dumped from a PAL/UK unit, so maybe that 'beta' is really an alt Euro release, or was simply dumped from one of these Radica units and mislabeled?
ROM_START( rad_orun )
ROM_REGION( 0x400000, "maincpu", ROMREGION_ERASEFF )
ROM_LOAD16_WORD_SWAP( "outrun.bin", 0x000000, 0x100000, CRC(4fd6d653) SHA1(57f0e4550ff883e4bb7857caef2c893c21f80b42) )
ROM_END
ROM_START( msi_sf2 )
ROM_REGION( 0x400000, "maincpu", 0 )
// The first part of the ROM seems to be a boot ROM for the enhanced MD clone menus, even if it does nothing here
// and is probably leftover from one of the multigame systems, hacked to only launch one game. We should emulate it...
// .. but the game ROM starts at 0xc8000 so we can cheat for now
ROM_LOAD16_WORD_SWAP( "29lv320.bin", 0x000000, 0xc8000, CRC(465b12f0) SHA1(7a058f6feb4f08f56ae0f7369c2ca9a9fe2ed40e) )
ROM_CONTINUE(0x00000,0x338000)
ROM_END
ROM_START( dgunl3227 )
ROM_REGION( 0x400000, "maincpu", ROMREGION_ERASE00 )
// populated in init function
ROM_REGION( 0x400000, "rom", 0 )
ROM_LOAD16_WORD_SWAP( "myarcadepacman_s99jl032hbt1_9991227e_as_s29jl032h55tai01.bin", 0x000000, 0x400000, CRC(ecead966) SHA1(971e8da6eb720f670f4148c7e07922e4f24eb609) )
ROM_END
ROM_START( ra145 )
/*
Data for the following games is corrupt (ranges approximate, based on areas of inconsistent readout)
3c0000 - 43ffff - James Bond 007 - The Duel (400171 - 41c600 is corrupt)
4c0000 - 53ffff - Robocop 3 (507bd4 - 50ad43 is corrupt)
540000 - 5bffff - Hokuto no Ken (540006 - 55fff2 is corrupt)
640000 - 6bffff - Batman (640042 - 65ffaf is corrupt)
7c0000 - 7fffff - Rambo 3 (7e031a - 7fffb9 is corrupt)
Unfortunately as many of the games in this unit have been hacked, or are using pirate versions of the games
from the mid 90s (in a few cases, complete with trainers) that seem to have dropped out of circulation it
is not possible to repair the data in dump from the damaged unit.
The unit also includes a duplicate copy of Thunder Force II instead of Revenge of Shinobi, this however
is not a dump issue, nor is Wacky Worlds being swapped with Fun and Games in the menu
*/
ROM_REGION( 0x8000000, "maincpu", ROMREGION_ERASE00 )
ROM_LOAD16_WORD_SWAP( "ra145.bin", 0x000000, 0x8000000, BAD_DUMP CRC(30583950) SHA1(855eae232e3830a505f9bc1a26edb3a7d15ce4d1) )
ROM_END
void megadriv_radica_6button_state::init_megadriv_radica_6button_pal()
{
init_megadrie();
// 6 button game, so overwrite 3 button io handlers
m_megadrive_io_read_data_port_ptr = read8sm_delegate(*this, FUNC(md_base_state::megadrive_io_read_data_port_6button));
m_megadrive_io_write_data_port_ptr = write16sm_delegate(*this, FUNC(md_base_state::megadrive_io_write_data_port_6button));
}
void megadriv_radica_6button_state::init_megadriv_radica_6button_ntsc()
{
init_megadriv();
// 6 button game, so overwrite 3 button io handlers
m_megadrive_io_read_data_port_ptr = read8sm_delegate(*this, FUNC(md_base_state::megadrive_io_read_data_port_6button));
m_megadrive_io_write_data_port_ptr = write16sm_delegate(*this, FUNC(md_base_state::megadrive_io_write_data_port_6button));
}
void megadriv_dgunl_state::init_dgunl3227()
{
uint8_t* rom = memregion("rom")->base();
uint8_t* dst = memregion("maincpu")->base();
size_t len = memregion("rom")->bytes();
std::vector<u8> buffer(len);
for (int i = 0; i < len; i++)
buffer[i] = rom[i ^ 3];
std::copy(buffer.begin(), buffer.end(), &rom[0]);
int baseaddr, size, dstaddr;
//baseaddr = 0x200000; size = 0x40000; // unknown data (unused menu data maybe?)
//baseaddr = 0x240000; size = 0x20000; // 'sample' program with UWOL header later too (lower part of menu program)
//baseaddr = 0x260000; size = 0x20000; // pirate version of Columns with Sega text removed
//baseaddr = 0x280000; size = 0x20000; // Fatal Labyrinth
//baseaddr = 0x2a0000; size = 0x20000; // pirate version of Block Out with EA logo and text removed
//baseaddr = 0x2c0000; size = 0x20000; // Flicky
//baseaddr = 0x2e0000; size = 0x20000; // Shove It
//baseaddr = 0x300000; size = 0x40000; // pirate version of Space Invaders 90 with Taito logos and copyright removed (also upper part of menu program - has extra header + bits of code for '202 in 1' menu which has been hacked to run the 3-in-1 menu)
// the following 3 games are available to select from the menu on this system
//baseaddr = 0x340000; size = 0x40000; // Pac-Attack / Pac-Panic (used by this unit)
//baseaddr = 0x380000; size = 0x40000; // Pac-Mania (used by this unit)
//baseaddr = 0x3c0000; size = 0x40000; // Pac-Man (used by this unit) (2nd copy of header about halfway through?)
// copy 1st part of menu code
baseaddr = 0x240000;
size = 0x020000;
dstaddr = 0x000000;
for (int i = 0; i < size; i++)
{
dst[i + dstaddr] = rom[baseaddr + i];
}
// copy 2nd part of menu code
baseaddr = 0x300000;
size = 0x040000;
dstaddr = 0x0c0000;
for (int i = 0; i < size; i++)
{
dst[i + dstaddr] = rom[baseaddr + i];
}
// copy pac-panic to first bank
baseaddr = 0x340000;
size = 0x040000;
dstaddr = 0x100000;
for (int i = 0; i < size; i++)
{
dst[i + dstaddr] = rom[baseaddr + i];
}
// copy pac-mania to 2nd bank
baseaddr = 0x380000;
size = 0x040000;
dstaddr = 0x180000;
for (int i = 0; i < size; i++)
{
dst[i + dstaddr] = rom[baseaddr + i];
}
// copy pac-man to 3nd bank
baseaddr = 0x3c0000;
size = 0x040000;
dstaddr = 0x200000;
for (int i = 0; i < size; i++)
{
dst[i + dstaddr] = rom[baseaddr + i];
}
// other data isn't copied because it's never referenced, therefore we don't know how it gets accessed
init_megadriv();
}
void megadriv_ra145_state::init_ra145()
{
m_romsize = 0x8000000;
init_megadriv();
// 6 button game, so overwrite 3 button io handlers
m_megadrive_io_read_data_port_ptr = read8sm_delegate(*this, FUNC(md_base_state::megadrive_io_read_data_port_6button));
m_megadrive_io_write_data_port_ptr = write16sm_delegate(*this, FUNC(md_base_state::megadrive_io_write_data_port_6button));
}
// US versions show 'Genesis' on the menu, show a www.radicagames.com splash screen, and use NTSC versions of the ROMs, sometimes region locked
// EU versions show 'Mega Drive' on the menu, show a www.radicagames.com splash screen, and use PAL versions of the ROMs, sometimes region locked
// UK versions show "Mega Drive' on the menu, show a www.radicauk.com splash screen, and use PAL versions of the ROMs, sometimes region locked
CONS( 2004, rad_gen1, 0, 0, megadriv_radica_3button_ntsc, megadriv_radica_3button_1player, megadriv_radica_3button_state, init_megadriv, "Radica / Sega", "Genesis Collection Volume 1 (Radica, Arcade Legends) (USA)", 0)
CONS( 2004, rad_md1, rad_gen1, 0, megadriv_radica_3button_pal, megadriv_radica_3button_1player, megadriv_radica_3button_state, init_megadrie, "Radica / Sega", "Mega Drive Collection Volume 1 (Radica, Arcade Legends) (Europe)", 0)
// A UK version exists, showing the Radica UK boot screen
CONS( 2004, rad_gen2, 0, 0, megadriv_radica_3button_ntsc, megadriv_radica_3button_1player, megadriv_radica_3button_state, init_megadriv, "Radica / Sega", "Genesis Collection Volume 2 (Radica, Arcade Legends) (USA)", 0)
CONS( 2004, rad_md2, rad_gen2, 0, megadriv_radica_3button_pal, megadriv_radica_3button_1player, megadriv_radica_3button_state, init_megadrie, "Radica / Sega", "Mega Drive Collection Volume 2 (Radica, Arcade Legends) (UK)", 0)
// is there a Europe version with Radica Games boot screen and Mega Drive text?
// box calls this Volume 3
CONS( 2004, rad_sonic, 0, 0, megadriv_radica_3button_ntsc, megadriv_radica_3button_1player, megadriv_radica_3button_state, init_megadriv, "Radica / Sega", "Super Sonic Gold (Radica Plug & Play) (USA)", 0)
CONS( 2004, rad_sonicp,rad_sonic,0, megadriv_radica_3button_pal, megadriv_radica_3button_1player, megadriv_radica_3button_state, init_megadrie, "Radica / Sega", "Super Sonic Gold (Radica Plug & Play) (UK)", 0)
// is there a Europe version with Radica Games boot screen and Mega Drive text?
CONS( 2004, rad_sf2, 0, 0, megadriv_radica_6button_ntsc, megadriv_radica_6button, megadriv_radica_6button_state, init_megadriv_radica_6button_ntsc,"Radica / Capcom / Sega", "Street Fighter II: Special Champion Edition [Ghouls'n Ghosts] (Radica, Arcade Legends) (USA)", 0)
CONS( 2004, rad_sf2p, rad_sf2, 0, megadriv_radica_6button_pal, megadriv_radica_6button, megadriv_radica_6button_state, init_megadriv_radica_6button_pal, "Radica / Capcom / Sega", "Street Fighter II: Special Champion Edition [Ghouls'n Ghosts] (Radica, Arcade Legends) (UK)", 0)
// is there a Europe version with Radica Games boot screen and Mega Drive text?
// still branded as Arcade Legends even if none of these were ever arcade games, European exclusive
CONS( 2004, rad_ssoc, 0, 0, megadriv_radica_3button_pal, megadriv_radica_3button, megadriv_radica_3button_state, init_megadrie, "Radica / Sensible Software / Sega", "Sensible Soccer plus [Cannon Fodder, Mega lo Mania] (Radica, Arcade Legends) (UK)", 0)
// is there a Europe version with Radica Games boot screen and Mega Drive text?
// not region locked, no Radica logos, uncertain if other regions would differ
CONS( 2004, rad_orun, 0, 0, megadriv_radica_3button_pal, megadriv_radica_3button_1player, megadriv_radica_3button_state, init_megadrie, "Radica / Sega", "Out Run 2019 (Radica Plug & Play, UK)", 0)
// From a European unit but NTSC? - code is hacked from original USA Genesis game with region check still intact? (does the clone hardware always identify as such? or does the bypassed boot code skip the check?)
// TODO: move out of here eventually once the enhanced MD part is emulated rather than bypassed (it's probably the same as the 145-in-1 multigame unit, but modified to only include this single game)
CONS( 2018, msi_sf2, 0, 0, megadriv_radica_6button_ntsc, megadriv_msi_6button, megadriv_radica_6button_state, init_megadriv_radica_6button_ntsc, "MSI / Capcom / Sega", "Street Fighter II: Special Champion Edition (MSI Plug & Play) (Europe)", 0)
// Are these (dgunl3227, ra145) actually emulation based? there is a block of 0x40000 bytes at the start of the ROM that doesn't
// appear to be used, very similar in both units. Banking also seems entirely illogical unless something else is managing it.
// The menu code in both seems to have the same origin, containing a bunch of unused pirate versions of MD games.
// The version of SF2 in the 'ra145' unit is the same as the one in the MSI unit above, and expects region to report US even
// when some of the units run at PAL speed?
// It is also confirmed from real hardware videos that these units do not have the usual sprite limits (so masking effect on Sonic title screen fails)
// this is the only 'Pocket Player' unit to use Genesis on a Chip tech, the others are NES on a chip.
// some versions of this unit have an additional "Add Credits with 'A' or 'B'" screen after you select Pac-Man, this version does not.
CONS( 2018, dgunl3227, 0, 0, megadriv_dgunl_ntsc, megadriv_dgunl_1player, megadriv_dgunl_state, init_dgunl3227, "dreamGEAR", "My Arcade Pac-Man Pocket Player (DGUNL-3227)", 0 )
CONS( 2018, ra145, 0, 0, megadriv_dgunl_ntsc, megadriv_msi_6button, megadriv_ra145_state, init_ra145, "<unknown>", "Retro Arcade 16 Bits Classic Edition Mini TV Game Console - 145 Classic Games - TV Arcade Plug and Play (Mega Drive bootlegs)", MACHINE_NOT_WORKING )
|