-
Notifications
You must be signed in to change notification settings - Fork 74
/
pacman.c
4382 lines (3615 loc) · 192 KB
/
pacman.c
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
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/***************************************************************************
Namco PuckMan
driver by Nicola Salmoria and many others
Games supported:
* PuckMan
* Pac-Man Plus
* Ms. Pac-Man
* Crush Roller
* Ponpoko
* Eyes
* Mr. TNT
* Gorkans
* Lizard Wizard
* The Glob
* Dream Shopper
* Van Van Car
* Ali Baba and 40 Thieves
* Jump Shot
* Shoot the Bull
* Big Bucks
* Driving Force
* Eight Ball Action
* Porky
Known issues:
* mystery items in Ali Baba don't work correctly because of protection
****************************************************************************
Pac-Man memory map (preliminary)
0000-3fff ROM
4000-43ff Video RAM
4400-47ff Color RAM
4c00-4fff RAM
8000-9fff ROM (Ms Pac-Man and Ponpoko only)
a000-bfff ROM (Ponpoko only)
memory mapped ports:
read:
5000 IN0
5040 IN1
5080 DSW 1
50c0 DSW 2 (Ponpoko only)
see the input_ports definition below for details on the input bits
write:
4ff0-4fff 8 pairs of two bytes:
the first byte contains the sprite image number (bits 2-7), Y flip (bit 0),
X flip (bit 1); the second byte the color
5000 interrupt enable
5001 sound enable
5002 ????
5003 flip screen
5004 1 player start lamp
5005 2 players start lamp
5006 coin lockout
5007 coin counter
5040-5044 sound voice 1 accumulator (nibbles) (used by the sound hardware only)
5045 sound voice 1 waveform (nibble)
5046-5049 sound voice 2 accumulator (nibbles) (used by the sound hardware only)
504a sound voice 2 waveform (nibble)
504b-504e sound voice 3 accumulator (nibbles) (used by the sound hardware only)
504f sound voice 3 waveform (nibble)
5050-5054 sound voice 1 frequency (nibbles)
5055 sound voice 1 volume (nibble)
5056-5059 sound voice 2 frequency (nibbles)
505a sound voice 2 volume (nibble)
505b-505e sound voice 3 frequency (nibbles)
505f sound voice 3 volume (nibble)
5060-506f Sprite coordinates, x/y pairs for 8 sprites
50c0 Watchdog reset
I/O ports:
OUT on port $0 sets the interrupt vector
****************************************************************************
Make Trax protection description:
Make Trax has a "Special" chip that it uses for copy protection.
The following chart shows when reads and writes may occur:
AAAAAAAA AAAAAAAA
11111100 00000000 <- address bits
54321098 76543210
xxx1xxxx 01xxxxxx - read data bits 4 and 7
xxx1xxxx 10xxxxxx - read data bits 6 and 7
xxx1xxxx 11xxxxxx - read data bits 0 through 5
xxx1xxxx 00xxx100 - write to Special
xxx1xxxx 00xxx101 - write to Special
xxx1xxxx 00xxx110 - write to Special
xxx1xxxx 00xxx111 - write to Special
In practical terms, it reads from Special when it reads from
location $5040-$50FF. Note that these locations overlap our
inputs and Dip Switches. Yuk.
I don't bother trapping the writes right now, because I don't
know how to interpret them. However, comparing against Crush
Roller gives most of the values necessary on the reads.
Instead of always reading from $5040, $5080, and $50C0, the Make
Trax programmers chose to read from a wide variety of locations,
probably to make debugging easier. To us, it means that for the most
part we can just assign a specific value to return for each address and
we'll be OK. This falls apart for the following addresses: $50C0, $508E,
$5090, and $5080. These addresses should return multiple values. The other
ugly thing happening is in the ROMs at $3AE5. It keeps checking for
different values of $50C0 and $5080, and weird things happen if it gets
the wrong values. The only way I've found around these is to patch the
ROMs using the same patches Crush Roller uses. The only thing to watch
with this is that changing the ROMs will break the beginning checksum.
That's why we use the rom opcode decode function to do our patches.
Incidentally, there are extremely few differences between Crush Roller
and Make Trax. About 98% of the differences appear to be either unused
bytes, the name of the game, or code related to the protection. I've
only spotted two or three actual differences in the games, and they all
seem minor.
If anybody cares, here's a list of disassembled addresses for every
read and write to the Special chip (not all of the reads are
specifically for checking the Special bits, some are for checking
player inputs and Dip Switches):
Writes: $0084, $012F, $0178, $023C, $0C4C, $1426, $1802, $1817,
$280C, $2C2E, $2E22, $3205, $3AB7, $3ACC, $3F3D, $3F40,
$3F4E, $3F5E
Reads: $01C8, $01D2, $0260, $030E, $040E, $0416, $046E, $0474,
$0560, $0568, $05B0, $05B8, $096D, $0972, $0981, $0C27,
$0C2C, $0F0A, $10B8, $10BE, $111F, $1127, $1156, $115E,
$11E3, $11E8, $18B7, $18BC, $18CA, $1973, $197A, $1BE7,
$1C06, $1C9F, $1CAA, $1D79, $213D, $2142, $2389, $238F,
$2AAE, $2BF4, $2E0A, $39D5, $39DA, $3AE2, $3AEA, $3EE0,
$3EE9, $3F07, $3F0D
****************************************************************************
Todo: fix the sets according to this
Puckman is labeled wrong. Puckman set 1 is
likely a bootleg since the protection is patched out, set 2 would likely
be correct if the roms were split differently. Nicola had said that he
had a readme that mentioned 2k roms, which is my understanding.
Although the board will accept either, it is likely they were all 2k or
all 4k, not mixed. Also the set labeled "harder?" is not:
Comparing files npacmod.6j and NAMCOPAC.6J
00000031: AF 25 ;3031 is sub for fail rom check.
00000032: C3 7C ;301c is sub for pass rom check
00000033: 1C E6 ;so it now clears the sum (reg A) and
00000034: 30 F0 ;jumps to pass if it fails rom check.
000007F8: 31 30 c 1981 / c 1980
0000080B: 40 4E ghost / nickname
0000080C: 47 49
0000080D: 48 43
0000080E: 4F 4B
0000080F: 53 4E
00000810: 54 41
00000811: 40 4D
00000812: 40 45
00000FFF: 00 F1 checksum
Dave Widel
****************************************************************************/
#include "driver.h"
#include "vidhrdw/generic.h"
#include "pacman.h"
#include "pengo.h"
#include "cpu/s2650/s2650.h"
static UINT8 speedcheat = 0; /* a well known hack allows to make Pac Man run at four times */
/* his usual speed. When we start the emulation, we check if the */
/* hack can be applied, and set this flag accordingly. */
/*************************************
*
* Machine init
*
*************************************/
MACHINE_INIT( pacman )
{
unsigned char *RAM = memory_region(REGION_CPU1);
/* check if the loaded set of ROMs allows the Pac Man speed hack */
if ((RAM[0x180b] == 0xbe && RAM[0x1ffd] == 0x00) ||
(RAM[0x180b] == 0x01 && RAM[0x1ffd] == 0xbd))
speedcheat = 1;
else
speedcheat = 0;
}
MACHINE_INIT( pacplus )
{
unsigned char *RAM = memory_region(REGION_CPU1);
/* check if the loaded set of ROMs allows the Pac Man speed hack */
if ((RAM[0x182d] == 0xbe && RAM[0x1ffd] == 0xff) ||
(RAM[0x182d] == 0x01 && RAM[0x1ffd] == 0xbc))
speedcheat = 1;
else
speedcheat = 0;
}
MACHINE_INIT( mschamp )
{
data8_t *rom = memory_region(REGION_CPU1) + 0x10000;
int bankaddr = ((readinputport(3) & 1) * 0x8000);
cpu_setbank(1,&rom[bankaddr]);
cpu_setbank(2,&rom[bankaddr+0x4000]);
}
MACHINE_INIT( piranha )
{
unsigned char *RAM = memory_region(REGION_CPU1);
/* check if the loaded set of ROMs allows the Pac Man speed hack */
if ((RAM[0x180b] == 0xbe && RAM[0x1ffd] == 0x00) ||
(RAM[0x180b] == 0x01 && RAM[0x1ffd] == 0xbd))
speedcheat = 1;
else
speedcheat = 0;
}
/*************************************
*
* Interrupts
*
*************************************/
static INTERRUPT_GEN( pacman_interrupt )
{
unsigned char *RAM = memory_region(REGION_CPU1);
/* speed up cheat */
if (speedcheat)
{
if (readinputport(4) & 1) /* check status of the fake dip switch */
{
/* activate the cheat */
RAM[0x180b] = 0x01;
RAM[0x1ffd] = 0xbd;
}
else
{
/* remove the cheat */
RAM[0x180b] = 0xbe;
RAM[0x1ffd] = 0x00;
}
}
irq0_line_hold();
}
static INTERRUPT_GEN( pacplus_interrupt )
{
unsigned char *RAM = memory_region(REGION_CPU1);
/* speed up cheat */
if (speedcheat)
{
if (readinputport(4) & 1) /* check status of the fake dip switch */
{
/* activate the cheat */
RAM[0x182d] = 0x01;
RAM[0x1ffd] = 0xbc;
}
else
{
/* remove the cheat */
RAM[0x182d] = 0xbe;
RAM[0x1ffd] = 0xff;
}
}
irq0_line_hold();
}
static INTERRUPT_GEN( mspacman_interrupt )
{
unsigned char *RAM = memory_region(REGION_CPU1);
/* speed up cheat */
if (speedcheat)
{
if (readinputport(4) & 1) /* check status of the fake dip switch */
{
/* activate the cheat */
RAM[0x1180b] = 0x01;
RAM[0x11ffd] = 0xbd;
}
else
{
/* remove the cheat */
RAM[0x1180b] = 0xbe;
RAM[0x11ffd] = 0x00;
}
}
irq0_line_hold();
}
/*
The piranha board has a sync bus controler card similar to Midway's pacman. It
stores the LSB of the interupt vector using port 00 but it alters the byte to prevent
it from running on normal pacman hardware and vice versa. I wrote a program to print
out the even numbers and the vectors they convert to. Thanks to Dave France for
burning the roms. The numbers that didn't print here convert to odd numbers. It's
slightly possible some numbers listed converted to odd numbers and coincidentally
printed a valid even number. Since it only uses 2 vectors($fa,$fc) I didn't complete
the table or attempt to find the algorythm.
David Widel
d_widel@hotmail.com
out vec out vec out vec out vec
c0 44 80 04 40 44 00 04
c2 40 82 00 42 C4 02 84
c4 C4 84 84 44 C4 04 00
c6 40 86 00
c8 4C 88 0C 48 4C 08 0C
ca 48 8A 08 4A CC 0A 8C
cc CC 8C 8C 4C 48 0C 08
ce 48 8E 08
d0 54 90 14 50 54 10 14
d2 50 92 10 52 D4 12 94
d4 D4 94 94 54 50 14 10
d6 50 96 10
d8 5C 98 1C 58 5C 18 1C
da 58 9A 18 5A DC 1A 9C
dc DC 9C 9C 5C 58 1C 18
de 58 9E 18
e0 64 a0 24 60 64 20 24
e2 60 a2 20 62 E4 22 A4
e4 E4 a4 A4 64 60 24 20
e6 60 a6 20
e8 6C a8 2C 68 6C 28 2C
ea 68 aA 28 6A EC 2A AC
ec EC aC AC 6C 68 2C 28
ee 68 aE 28
f0 74 b0 34 70 74 30 34
f2 70 b2 30 72 F4 32 84
f4 F4 b4 B4 74 70 34 30
f6 70 b6 30
f8 7C b8 3C 78 7C 38 3C
fa 78 bA 38 7A FC 3A BC
fc FC bC BC 7C 78 3C 38
fe 78 bE 38
Naughty Mouse uses the same board as Piranha with a different pal to encrypt the vectors.
Incidentally we don't know the actual name of this game. Other than the word naughty at
the top of the playfield there's no name. It shares some character data with the missing
game Woodpecker, they may be related.
I haven't examined the code thoroughly but what I
did look at(sprite buffer), was copied from Pacman. The addresses for the variables seem
to be the same as well.
*/
static WRITE_HANDLER( piranha_interrupt_vector_w)
{
if (data==0xfa) data=0x78;
if (data==0xfc) data=0xfc;
cpu_irq_line_vector_w( 0, 0, data );
}
static WRITE_HANDLER( nmouse_interrupt_vector_w)
{
if (data==0xbf) data=0x3c;
if (data==0xc6) data=0x40;
if (data==0xfc) data=0xfc;
cpu_irq_line_vector_w( 0, 0, data );
}
/*************************************
*
* LEDs/coin counters
*
*************************************/
static WRITE_HANDLER( pacman_leds_w )
{
set_led_status(offset,data & 1);
}
static WRITE_HANDLER( pacman_coin_counter_w )
{
coin_counter_w(offset,data & 1);
}
static WRITE_HANDLER( pacman_coin_lockout_global_w )
{
coin_lockout_global_w(~data & 0x01);
}
/*************************************
*
* Ali Baba sound
*
*************************************/
static WRITE_HANDLER( alibaba_sound_w )
{
/* since the sound region in Ali Baba is not contiguous, translate the
offset into the 0-0x1f range */
if (offset < 0x10)
pengo_sound_w(offset, data);
else if (offset < 0x20)
spriteram_2[offset - 0x10] = data;
else
pengo_sound_w(offset - 0x10, data);
}
static READ_HANDLER( alibaba_mystery_1_r )
{
// The return value determines what the mystery item is. Each bit corresponds
// to a question mark
return rand() & 0x0f;
}
static READ_HANDLER( alibaba_mystery_2_r )
{
static int mystery = 0;
// The single bit return value determines when the mystery is lit up.
// This is certainly wrong
mystery++;
return (mystery >> 10) & 1;
}
/*************************************
*
* Make Trax input handlers
*
*************************************/
static READ_HANDLER( maketrax_special_port2_r )
{
int data = input_port_2_r(offset);
int pc = activecpu_get_previouspc();
if ((pc == 0x1973) || (pc == 0x2389)) return data | 0x40;
switch (offset)
{
case 0x01:
case 0x04:
data |= 0x40; break;
case 0x05:
data |= 0xc0; break;
default:
data &= 0x3f; break;
}
return data;
}
static READ_HANDLER( maketrax_special_port3_r )
{
int pc = activecpu_get_previouspc();
if (pc == 0x040e) return 0x20;
if ((pc == 0x115e) || (pc == 0x3ae2)) return 0x00;
switch (offset)
{
case 0x00:
return 0x1f;
case 0x09:
return 0x30;
case 0x0c:
return 0x00;
default:
return 0x20;
}
}
static READ_HANDLER( korosuke_special_port2_r )
{
int data = input_port_2_r(offset);
int pc = activecpu_get_previouspc();
if ((pc == 0x196e) || (pc == 0x2387)) return data | 0x40;
switch (offset)
{
case 0x01:
case 0x04:
data |= 0x40; break;
case 0x05:
data |= 0xc0; break;
default:
data &= 0x3f; break;
}
return data;
}
static READ_HANDLER( korosuke_special_port3_r )
{
int pc = activecpu_get_previouspc();
if (pc == 0x0445) return 0x20;
if ((pc == 0x115b) || (pc == 0x3ae6)) return 0x00;
switch (offset)
{
case 0x00:
return 0x1f;
case 0x09:
return 0x30;
case 0x0c:
return 0x00;
default:
return 0x20;
}
}
/*************************************
*
* Zola kludge
*
*************************************/
static READ_HANDLER( mschamp_kludge_r )
{
static UINT8 counter;
return counter++;
}
/************************************
*
* Big Bucks questions roms handlers
*
************************************/
static int bigbucks_bank = 0;
static WRITE_HANDLER( bigbucks_bank_w )
{
bigbucks_bank = data;
}
static READ_HANDLER( bigbucks_question_r )
{
UINT8 *question = memory_region(REGION_USER1);
UINT8 ret;
ret = question[(bigbucks_bank << 16) | (offset ^ 0xffff)];
return ret;
}
/************************************
*
* S2650 cpu based games
*
************************************/
static INTERRUPT_GEN( s2650_interrupt )
{
cpu_set_irq_line_and_vector(0, 0, HOLD_LINE, 0x03);
}
static READ_HANDLER( s2650_mirror_r )
{
return cpu_readmem16(0x1000 + offset);
}
static WRITE_HANDLER( s2650_mirror_w )
{
cpu_writemem16(0x1000 + offset, data);
}
static READ_HANDLER( drivfrcp_port1_r )
{
switch (activecpu_get_pc())
{
case 0x0030:
case 0x0291:
return 0x01;
}
return 0;
}
static READ_HANDLER( _8bpm_port1_r )
{
switch (activecpu_get_pc())
{
case 0x0030:
case 0x0466:
return 0x01;
}
return 0;
}
static READ_HANDLER( porky_port1_r )
{
switch (activecpu_get_pc())
{
case 0x0034:
return 0x01;
}
return 0;
}
/*************************************
*
* Main CPU memory handlers
*
*************************************/
static MEMORY_READ_START( readmem )
{ 0x0000, 0x3fff, MRA_ROM },
{ 0x4000, 0x47ff, MRA_RAM }, /* video and color RAM */
{ 0x4c00, 0x4fff, MRA_RAM }, /* including sprite codes at 4ff0-4fff */
{ 0x5000, 0x503f, input_port_0_r }, /* IN0 */
{ 0x5040, 0x507f, input_port_1_r }, /* IN1 */
{ 0x5080, 0x50bf, input_port_2_r }, /* DSW1 */
{ 0x50c0, 0x50ff, input_port_3_r }, /* DSW2 */
{ 0x8000, 0xbfff, MRA_ROM }, /* Ms. Pac-Man / Ponpoko only */
MEMORY_END
static MEMORY_WRITE_START( writemem )
{ 0x0000, 0x3fff, MWA_ROM },
{ 0x4000, 0x43ff, videoram_w, &videoram, &videoram_size },
{ 0x4400, 0x47ff, colorram_w, &colorram },
{ 0x4c00, 0x4fef, MWA_RAM },
{ 0x4ff0, 0x4fff, MWA_RAM, &spriteram, &spriteram_size },
{ 0x5000, 0x5000, interrupt_enable_w },
{ 0x5001, 0x5001, pengo_sound_enable_w },
{ 0x5002, 0x5002, MWA_NOP },
{ 0x5003, 0x5003, pengo_flipscreen_w },
{ 0x5004, 0x5005, pacman_leds_w },
// { 0x5006, 0x5006, pacman_coin_lockout_global_w }, this breaks many games
{ 0x5007, 0x5007, pacman_coin_counter_w },
{ 0x5040, 0x505f, pengo_sound_w, &pengo_soundregs },
{ 0x5060, 0x506f, MWA_RAM, &spriteram_2 },
{ 0x50c0, 0x50c0, watchdog_reset_w },
{ 0x8000, 0xbfff, MWA_ROM }, /* Ms. Pac-Man / Ponpoko only */
{ 0xc000, 0xc3ff, videoram_w }, /* mirror address for video ram, */
{ 0xc400, 0xc7ef, colorram_w }, /* used to display HIGH SCORE and CREDITS */
{ 0xffff, 0xffff, MWA_NOP }, /* Eyes writes to this location to simplify code */
MEMORY_END
static MEMORY_READ_START( mschamp_readmem )
{ 0x0000, 0x3fff, MRA_BANK1 }, /* By Sil: Zola/Ms. Champ */
{ 0x4000, 0x47ff, MRA_RAM }, /* video and color RAM */
{ 0x4c00, 0x4fff, MRA_RAM }, /* including sprite codes at 4ff0-4fff */
{ 0x5000, 0x503f, input_port_0_r }, /* IN0 */
{ 0x5040, 0x507f, input_port_1_r }, /* IN1 */
{ 0x5080, 0x50bf, input_port_2_r }, /* DSW */
{ 0x8000, 0x9fff, MRA_BANK2 }, /* By Sil: Zola/Ms. Champ */
MEMORY_END
static MEMORY_READ_START( mspacman_readmem )
{ 0x0000, 0x3fff, MRA_BANK1 },
{ 0x4000, 0x47ff, MRA_RAM }, /* video and color RAM */
{ 0x4c00, 0x4fff, MRA_RAM }, /* including sprite codes at 4ff0-4fff */
{ 0x5000, 0x503f, input_port_0_r }, /* IN0 */
{ 0x5040, 0x507f, input_port_1_r }, /* IN1 */
{ 0x5080, 0x50bf, input_port_2_r }, /* DSW1 */
{ 0x50c0, 0x50ff, input_port_3_r }, /* DSW2 */
{ 0x8000, 0xbfff, MRA_BANK1 },
MEMORY_END
static MEMORY_WRITE_START( mspacman_writemem )
{ 0x0000, 0x3fff, MWA_BANK1 },
{ 0x4000, 0x43ff, videoram_w, &videoram, &videoram_size },
{ 0x4400, 0x47ff, colorram_w, &colorram },
{ 0x4c00, 0x4fef, MWA_RAM },
{ 0x4ff0, 0x4fff, MWA_RAM, &spriteram, &spriteram_size },
{ 0x5000, 0x5000, interrupt_enable_w },
{ 0x5001, 0x5001, pengo_sound_enable_w },
{ 0x5002, 0x5002, MWA_NOP },
{ 0x5003, 0x5003, pengo_flipscreen_w },
{ 0x5004, 0x5005, pacman_leds_w },
{ 0x5006, 0x5006, mspacman_activate_rom }, /* Not actually, just handy */
// { 0x5006, 0x5006, pacman_coin_lockout_global_w }, this breaks many games
{ 0x5007, 0x5007, pacman_coin_counter_w },
{ 0x5040, 0x505f, pengo_sound_w, &pengo_soundregs },
{ 0x5060, 0x506f, MWA_RAM, &spriteram_2 },
{ 0x50c0, 0x50c0, watchdog_reset_w },
{ 0x8000, 0xbfff, MWA_BANK1 }, /* Ms. Pac-Man / Ponpoko only */
{ 0xc000, 0xc3ff, videoram_w }, /* mirror address for video ram, */
{ 0xc400, 0xc7ef, colorram_w }, /* used to display HIGH SCORE and CREDITS */
{ 0xffff, 0xffff, MWA_NOP }, /* Eyes writes to this location to simplify code */
MEMORY_END
static MEMORY_READ_START( alibaba_readmem )
{ 0x0000, 0x3fff, MRA_ROM },
{ 0x4000, 0x47ff, MRA_RAM }, /* video and color RAM */
{ 0x4c00, 0x4fff, MRA_RAM }, /* including sprite codes at 4ef0-4eff */
{ 0x5000, 0x503f, input_port_0_r }, /* IN0 */
{ 0x5040, 0x507f, input_port_1_r }, /* IN1 */
{ 0x5080, 0x50bf, input_port_2_r }, /* DSW1 */
{ 0x50c0, 0x50c0, alibaba_mystery_1_r },
{ 0x50c1, 0x50c1, alibaba_mystery_2_r },
{ 0x8000, 0x8fff, MRA_ROM },
{ 0x9000, 0x93ff, MRA_RAM },
{ 0xa000, 0xa7ff, MRA_ROM },
MEMORY_END
static MEMORY_WRITE_START( alibaba_writemem )
{ 0x0000, 0x3fff, MWA_ROM },
{ 0x4000, 0x43ff, videoram_w, &videoram, &videoram_size },
{ 0x4400, 0x47ff, colorram_w, &colorram },
{ 0x4ef0, 0x4eff, MWA_RAM, &spriteram, &spriteram_size },
{ 0x4c00, 0x4fff, MWA_RAM },
{ 0x5000, 0x5000, watchdog_reset_w },
{ 0x5004, 0x5005, pacman_leds_w },
{ 0x5006, 0x5006, pacman_coin_lockout_global_w },
{ 0x5007, 0x5007, pacman_coin_counter_w },
{ 0x5040, 0x506f, alibaba_sound_w, &pengo_soundregs }, /* the sound region is not contiguous */
{ 0x5060, 0x506f, MWA_RAM, &spriteram_2 }, /* actually at 5050-505f, here to point to free RAM */
{ 0x50c0, 0x50c0, pengo_sound_enable_w },
{ 0x50c1, 0x50c1, pengo_flipscreen_w },
{ 0x50c2, 0x50c2, interrupt_enable_w },
{ 0x8000, 0x8fff, MWA_ROM },
{ 0x9000, 0x93ff, MWA_RAM },
{ 0xa000, 0xa7ff, MWA_ROM },
{ 0xc000, 0xc3ff, videoram_w }, /* mirror address for video ram, */
{ 0xc400, 0xc7ef, colorram_w }, /* used to display HIGH SCORE and CREDITS */
MEMORY_END
static MEMORY_READ_START( theglobp_readmem )
{ 0x0000, 0x3fff, MRA_BANK1 },
{ 0x4000, 0x47ff, MRA_RAM }, /* video and color RAM */
{ 0x4c00, 0x4fff, MRA_RAM }, /* including sprite codes at 4ff0-4fff */
{ 0x5000, 0x503f, input_port_0_r }, /* IN0 */
{ 0x5040, 0x507f, input_port_1_r }, /* IN1 */
{ 0x5080, 0x50bf, input_port_2_r }, /* DSW1 */
{ 0x50c0, 0x50ff, input_port_3_r }, /* DSW2 */
MEMORY_END
static MEMORY_READ_START( vanvan_readmem )
{ 0x0000, 0x3fff, MRA_ROM },
{ 0x4000, 0x47ff, MRA_RAM }, /* video and color RAM */
{ 0x4800, 0x4fff, MRA_RAM }, /* including sprite codes at 4ff0-4fff */
{ 0x5000, 0x5000, input_port_0_r }, /* IN0 */
{ 0x5040, 0x5040, input_port_1_r }, /* IN1 */
{ 0x5080, 0x5080, input_port_2_r }, /* DSW1 */
{ 0x50c0, 0x50c0, input_port_3_r }, /* DSW2 */
{ 0x8000, 0x8fff, MRA_ROM },
MEMORY_END
static MEMORY_WRITE_START( vanvan_writemem )
{ 0x0000, 0x3fff, MWA_ROM },
{ 0x4000, 0x43ff, videoram_w, &videoram, &videoram_size },
{ 0x4400, 0x47ff, colorram_w, &colorram },
{ 0x4800, 0x4fef, MWA_RAM },
{ 0x4ff0, 0x4fff, MWA_RAM, &spriteram, &spriteram_size },
{ 0x5000, 0x5000, interrupt_enable_w },
{ 0x5001, 0x5001, vanvan_bgcolor_w },
{ 0x5003, 0x5003, pengo_flipscreen_w },
{ 0x5005, 0x5006, MWA_NOP }, /* always written together with 5001 */
{ 0x5007, 0x5007, pacman_coin_counter_w },
{ 0x5060, 0x506f, MWA_RAM, &spriteram_2 },
{ 0x5080, 0x5080, MWA_NOP }, /* ??? toggled before reading 5000 */
{ 0x50c0, 0x50c0, watchdog_reset_w },
{ 0x8000, 0x8fff, MWA_ROM },
{ 0xb800, 0xb87f, MWA_NOP }, /* probably a leftover from development: the Sanritsu version */
/* writes the color lookup table here, while the Karateko version */
/* writes garbage. */
MEMORY_END
static MEMORY_READ_START( acitya_readmem )
{ 0x0000, 0x3fff, MRA_BANK1 },
{ 0x4000, 0x47ff, MRA_RAM }, /* video and color RAM */
{ 0x4c00, 0x4fff, MRA_RAM }, /* including sprite codes at 4ff0-4fff */
{ 0x5000, 0x503f, input_port_0_r }, /* IN0 */
{ 0x5040, 0x507f, input_port_1_r }, /* IN1 */
{ 0x5080, 0x50bf, input_port_2_r }, /* DSW1 */
{ 0x50c0, 0x50ff, input_port_3_r }, /* DSW2 */
{ 0x8000, 0xbfff, MRA_ROM }, /* Ms. Pac-Man / Ponpoko only */
MEMORY_END
static MEMORY_WRITE_START( bigbucks_writemem )
{ 0x0000, 0x3fff, MWA_ROM },
{ 0x4000, 0x43ff, videoram_w, &videoram, &videoram_size },
{ 0x4400, 0x47ff, colorram_w, &colorram },
{ 0x4c00, 0x4fbf, MWA_RAM },
{ 0x5000, 0x5000, interrupt_enable_w },
{ 0x5001, 0x5001, pengo_sound_enable_w },
{ 0x5003, 0x5003, pengo_flipscreen_w },
{ 0x5007, 0x5007, MWA_NOP }, //?
{ 0x5040, 0x505f, pengo_sound_w, &pengo_soundregs },
{ 0x50c0, 0x50c0, watchdog_reset_w },
{ 0x5100, 0x5100, MWA_NOP }, //?
{ 0x6000, 0x6000, bigbucks_bank_w },
{ 0x8000, 0x9fff, MWA_ROM },
MEMORY_END
static MEMORY_READ_START( s2650games_readmem )
{ 0x0000, 0x0fff, MRA_ROM },
{ 0x1500, 0x1500, input_port_0_r },
{ 0x1540, 0x1540, input_port_1_r },
{ 0x1580, 0x1580, input_port_2_r },
{ 0x1c00, 0x1fef, MRA_RAM },
{ 0x2000, 0x2fff, MRA_ROM },
{ 0x3000, 0x3fff, s2650_mirror_r },
{ 0x4000, 0x4fff, MRA_ROM },
{ 0x5000, 0x5fff, s2650_mirror_r },
{ 0x6000, 0x6fff, MRA_ROM },
{ 0x7000, 0x7fff, s2650_mirror_r },
MEMORY_END
static MEMORY_WRITE_START( s2650games_writemem )
{ 0x0000, 0x0fff, MWA_ROM },
{ 0x1000, 0x13ff, s2650games_colorram_w },
{ 0x1400, 0x141f, s2650games_scroll_w },
{ 0x1420, 0x148f, MWA_RAM },
{ 0x1490, 0x149f, MWA_RAM, &sprite_bank },
{ 0x14a0, 0x14bf, s2650games_tilesbank_w, &tiles_bankram },
{ 0x14c0, 0x14ff, MWA_RAM },
{ 0x1500, 0x1502, MWA_NOP },
{ 0x1503, 0x1503, s2650games_flipscreen_w },
{ 0x1504, 0x1506, MWA_NOP },
{ 0x1507, 0x1507, pacman_coin_counter_w },
{ 0x1508, 0x155f, MWA_RAM },
{ 0x1560, 0x156f, MWA_RAM, &spriteram_2 },
{ 0x1570, 0x157f, MWA_RAM },
{ 0x1586, 0x1587, MWA_NOP },
{ 0x15c0, 0x15c0, watchdog_reset_w },
{ 0x15c7, 0x15c7, MWA_RAM },
{ 0x1800, 0x1bff, s2650games_videoram_w, &videoram },
{ 0x1c00, 0x1fef, MWA_RAM },
{ 0x1ff0, 0x1fff, MWA_RAM, &spriteram, &spriteram_size },
{ 0x2000, 0x2fff, MWA_ROM },
{ 0x3000, 0x3fff, s2650_mirror_w },
{ 0x4000, 0x4fff, MWA_ROM },
{ 0x5000, 0x5fff, s2650_mirror_w },
{ 0x6000, 0x6fff, MWA_ROM },
{ 0x7000, 0x7fff, s2650_mirror_w },
MEMORY_END
/*************************************
*
* Main CPU port handlers
*
*************************************/
static PORT_WRITE_START( writeport )
{ 0x00, 0x00, interrupt_vector_w }, /* Pac-Man only */
PORT_END
static PORT_WRITE_START( vanvan_writeport )
{ 0x01, 0x01, SN76496_0_w },
{ 0x02, 0x02, SN76496_1_w },
PORT_END
static PORT_WRITE_START( dremshpr_writeport )
{ 0x06, 0x06, AY8910_write_port_0_w },
{ 0x07, 0x07, AY8910_control_port_0_w },
PORT_END
static PORT_WRITE_START( piranha_writeport )
{ 0x00, 0x00, piranha_interrupt_vector_w },
PORT_END
static PORT_WRITE_START( nmouse_writeport )
{ 0x00, 0x00, nmouse_interrupt_vector_w },
PORT_END
static PORT_READ_START( theglobp_readport )
{ 0x00, 0xff, theglobp_decrypt_rom }, /* Switch protection logic */
PORT_END
static PORT_READ_START( acitya_readport )
{ 0x00, 0xff, acitya_decrypt_rom }, /* Switch protection logic */
PORT_END
static PORT_READ_START( mschamp_readport )
{ 0x00,0x00, mschamp_kludge_r },
PORT_END
static PORT_READ_START( bigbucks_readport )
{ 0x0000, 0xffff, bigbucks_question_r },
PORT_END
static PORT_READ_START( drivfrcp_readport )
{ 0x00, 0x00, MRA_NOP },
{ 0x01, 0x01, drivfrcp_port1_r },
{ S2650_SENSE_PORT, S2650_SENSE_PORT, input_port_3_r },
PORT_END
static PORT_READ_START( _8bpm_readport )
{ 0x00, 0x00, MRA_NOP },
{ 0x01, 0x01, _8bpm_port1_r },
{ 0xe0, 0xe0, MRA_NOP },
{ S2650_SENSE_PORT, S2650_SENSE_PORT, input_port_3_r },
PORT_END
static PORT_READ_START( porky_readport )
{ 0x01, 0x01, porky_port1_r },
{ S2650_SENSE_PORT, S2650_SENSE_PORT, input_port_3_r },
PORT_END
static PORT_WRITE_START( s2650games_writeport )
{ S2650_DATA_PORT, S2650_DATA_PORT, SN76496_0_w },
PORT_END
/*************************************
*
* Port definitions
*
*************************************/
INPUT_PORTS_START( pacman )
PORT_START /* IN0 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_4WAY )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_4WAY )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_4WAY )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_4WAY )
PORT_BITX( 0x10, 0x10, IPT_DIPSWITCH_NAME | IPF_CHEAT, "Rack Test", KEYCODE_F1, IP_JOY_NONE )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_START /* IN1 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_4WAY | IPF_COCKTAIL )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_4WAY | IPF_COCKTAIL )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_4WAY | IPF_COCKTAIL )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_4WAY | IPF_COCKTAIL )
PORT_SERVICE( 0x10, IP_ACTIVE_LOW )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START2 )
PORT_DIPNAME(0x80, 0x80, DEF_STR( Cabinet ) )
PORT_DIPSETTING( 0x80, DEF_STR( Upright ) )
PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) )
PORT_START /* DSW 1 */
PORT_DIPNAME( 0x03, 0x01, DEF_STR( Coinage ) )
PORT_DIPSETTING( 0x03, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x01, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0x02, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
PORT_DIPNAME( 0x0c, 0x08, DEF_STR( Lives ) )
PORT_DIPSETTING( 0x00, "1" )
PORT_DIPSETTING( 0x04, "2" )
PORT_DIPSETTING( 0x08, "3" )
PORT_DIPSETTING( 0x0c, "5" )