/
neogeo.cpp
12213 lines (9830 loc) · 773 KB
/
neogeo.cpp
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
// license:BSD-3-Clause
// copyright-holders:Bryan McPhail,Ernesto Corvi,Andrew Prime,Zsolt Vasvari
// thanks-to:Fuzz
/***************************************************************************
Neo-Geo hardware
Credits:
* This driver was made possible by the research done by
Charles MacDonald. For a detailed description of the Neo-Geo
hardware, please visit his page at:
http://cgfm2.emuviews.com/txt/mvstech.txt
* Presented to you by the Shin Emu Keikaku team.
* The following people have all spent probably far
too much time on this:
AVDB
Bryan McPhail
Fuzz
Ernesto Corvi
Andrew Prime
Zsolt Vasvari
Known driver issues/to-do's:
============================
* Fatal Fury 3 crashes during the ending - this doesn't occur if
the language is set to Japanese, maybe the English endings
are incomplete / buggy?
* Graphical Glitches caused by incorrect timing?
- Some raster effects are imperfect (off by a couple of lines)
* 68000 waitstates on ROM region access, determined by jumpers on cart
* AES Input clock is incorrect (24.167829MHz for NTSC systems, PAL is same?)
* PAL region AES behavior is not verified
Confirmed non-bugs:
* Bad zooming in the Kof2003 bootlegs - this is what happens
if you try and use the normal bios with a PCB set, it
looks like the bootleggers didn't care.
* Glitches at the edges of the screen - the real hardware
can display 320x224 but most of the games seem designed
to work with a width of 304, some less.
* Distorted jumping sound in Nightmare in the Dark
* Ninja Combat sometimes glitches
*****************************************************************************
The Neo-Geo Multi Video System (MVS), is an arcade system board, being
the first product in the Neo-Geo family, designed by Alpha Denshi (ADK)
and released in 1990 by SNK. It was known to the coin-op industry, and
offered arcade operators the ability to put up to 6 different arcade
titles into a single cabinet, a key economic consideration for operators
with limited floorspace (games for the Neo-Geo are cartridge based and are
easily exchangeable). It comes in many different cabinets but basically
consists of an add on board that can be linked to a standard Jamma system.
The system was discontinued in 2004.
Source (modified): http://en.wikipedia.org/wiki/Neo_Geo
MVS motherboards were produced in 1 / 2 / 4 and 6 Slot versions.
Known motherboards:
===================
+---------+------+-------+------------+-----------------------+--------------------------------------------------------------------------+
| Model | Year | Slots | Generation | Video chipset | Notes |
+---------+------+-------+------------+-----------------------+--------------------------------------------------------------------------+
| MV-1 | 1990 | 1 | 1 | PRO-B0/PRO-C0/LSPC-A0 | Original full-featured 1-slot board |
| MV-1F | | 1 | 2 | NEO-B1/LSPC2-A2 | 2nd-generation 1-slot board, no memory card headers |
| MV-1FZ | | 1 | 2 | NEO-B1/LSPC2-A2 | Cost-reduced MV-1F without LED displays/mahjong inputs/stereo output |
| MV-1FZS | | 1 | 2 | NEO-B1/LSPC2-A2 | Spanish MV-1FZ |
| MV-1A | 1995 | 1 | 3 | NEO-MGA/NEO-GRC | 3rd-generation 1-slot board, removes coin lockouts |
| MV-1ACH | 1995 | 1 | 3 | NEO-MGA/NEO-GRC | Chinese MV-1A |
| MV-1AX | | 1 | 3 | NEO-MGA/NEO-GRC | MV-1A with soldered BIOS |
| MV-1B | | 1 | 4 | NEO-GRC2 | 4th-generation 1-slot board, soldered BIOS, no SM1 ROM, 8-pin SIT header |
| MV-1C | 1999 | 1 | 5 | NEO-GRZ | Final iteration, vertical cartridge slot |
+---------+------+-------+------------+-----------------------+--------------------------------------------------------------------------+
| MV-2B | | 2 | 1 | PRO-B0/PRO-C0/LSPC-A0 | Original full-featured 2-slot board |
| MV-2F | | 2 | 2 | NEO-B1/LSPC2-A2 | 2nd-generation 2-slot board, onboard PCMCIA slot and 3.5mm jacks |
| MV-2FS | | 2 | 2 | NEO-B1/LSPC2-A2 | Spanish MV-2F |
+---------+------+-------+------------+-----------------------+--------------------------------------------------------------------------+
| MV-4 | 1990 | 4 | 1 | PRO-B0/PRO-C0/LSPC-A0 | Original 4-slot board |
| MV-4F | | 4 | 2 | NEO-B1/LSPC2-A2 | 2nd-generation 4-slot board |
| MV-4FS | | 4 | 2 | NEO-B1/LSPC2-A2 | Spanish MV-4 |
+---------+------+-------+------------+-----------------------+--------------------------------------------------------------------------+
| MV-6 | 1990 | 6 | 1 | PRO-B0/PRO-C0/LSPC-A0 | 2-board stack - mainboard and slot board |
+---------+------+-------+------------+-----------------------+--------------------------------------------------------------------------+
Other mainboards:
1 Slot:
NEO-MVH MV1-1
. NEO-MVH MV1A CHX ??
NEO-MVH MV1B (1996.1.19) (miniaturised, 8-pin header for irrmaze/kizuna4p)
. NEO-MVH MV1B CHX (1996.1.19) ??
NEO-MVH MV1B1 (1998.6.17)
NEO-MVH MV1C (1999.4.30)
NEO-MVH MV1FT (cost-reduced MV1T without memory card headers)
NEO-MVH MV1T
2 Slot:
NEO-MVH MV2
NEO-MVH MV2F-01
4 Slot:
NEO-MVH MV4-25 (US MV4?)
NEO-MVH MV4FT
NEO-MVH MV4FT2
6 Slot:
NEO-MVH MV6F
Neo-Geo Motherboard (info - courtesy of Guru):
NEO-MVH MV1
|---------------------------------------------------------------------|
| 4558 |
| HC04 HC32 |
| SP-S2.SP1 NEO-E0 000-L0.L0 LS244 AS04 |
| YM2610 |
| 4558 |
| 4558 5814 HC259 SFIX.SFIX |
| NEO-I0 |
| HA13001 YM3016 5814 |
--| |
| 4558 |
--| SM1.SM1 LS32 |
| |
| LSPC-A0 PRO-C0 LS244 |
| |
|J 68000 |
|A |
|M |
|M NEO-ZMC2 |
|A |
| LS273 NEO-G0 58256 58256 Z80A |
| 58256 58256 58256 58256 6116 |
| LS273 5864 |
--| LS05 5864 PRO-B0 |
| |
--| LS06 HC32 D4990A NEO-F0 24.000MHz |
| DSW1 BATT3.6V 32.768kHz NEO-D0 |
| 2003 2003 |
|---------------------------------------------------------------------|
Mainboard features
==================
+-------+----+-----+-----+-----+--------+--------+-------+-----+-------+-------+------+-----+---+--------+-------+------+
| |Vid |Slots|Edge |Coins|Counters|Lockouts|Mahjong|8-pin|Memcard|Mono/St|Phones|7-seg|EL | BIOS |Data In|Orient|
+-------+----+-----+-----+-----+--------+--------+-------+-----+-------+-------+------+-----+---+--------+-------+------+
|MV-1 | B0 | 1 |JAMMA| 2 | 2 | 2 | 2 | no |header |switch |header| yes |no | socket | yes |horiz |
|MV-1F | B1 | 1 |JAMMA| 2 | 2 | 2 | 2 | no | none |switch |header| yes |no | socket | no |horiz |
|MV-1FZ | B1 | 1 |JAMMA| 2 | 2 | 2 | 0 | no | none | mono | none | no |no | socket | yes |horiz |
|MV-1A |MGA | 1 |JAMMA| 2 | 2 | 0 | 0 | no | none | mono | none | no |no | socket | no |horiz |
|MV-1AX |MGA | 1 |JAMMA| 2 | 2 | 0 | 0 | no | none | mono | none | no |no |soldered| no |horiz |
|MV-1B |GRC2| 1 |JAMMA| 2 | 2 | 0 | 0 | yes | none | mono | none | no |no |soldered| no |horiz |
|MV-1C |GRZ | 1 |JAMMA| 2 | 2 | 0 | 0 | yes | none | mono | none | no |no |soldered| no | vert |
+-------+----+-----+-----+-----+--------+--------+-------+-----+-------+-------+------+-----+---+--------+-------+------+
|MV-2B | B0 | 2 | MVS | 4 | 2 | 2 | 2 | no |header | both |header| yes |yes| socket | no | vert |
|MV-2F | B1 | 2 | MVS | 4 | 2 | 2 | 2 | no |onboard| both |jacks | yes |yes| socket | no | vert |
+-------+----+-----+-----+-----+--------+--------+-------+-----+-------+-------+------+-----+---+--------+-------+------+
|MV-4-25| B0 | 4 | MVS | 4 | 2 | 2 | 2 | no |header | both |header| yes |yes| socket | no | vert |
|MV-4F | B1 | 4 | MVS | 4 | 2 | 2 | 2 | no |header | both |header| yes |yes| socket | no | vert |
+-------+----+-----+-----+-----+--------+--------+-------+-----+-------+-------+------+-----+---+--------+-------+------+
|MV-6 | B0 | 6 | MVS | 4 | 2 | 2 | 2 | no |header | both |header| yes |yes| socket | no | vert |
+-------+----+-----+-----+-----+--------+--------+-------+-----+-------+-------+------+-----+---+--------+-------+------+
* Function of the data input switch is unknown
* MVS connector has high-level single-ended stereo outputs and low-level mono output
* JAMMA connector has high-level balanced mono output
* Single-slot boards with stereo capability have a 4-pin stereo speaker header
* Boards with stereo support have headphone connectors or headers for them
* Newer single-slot boards have an 8-pin header for the trackball or 4-player interface (SIT)
*****************************************************************************
Neo-Geo game PCB infos:
=======================
The Neo-Geo games for AES (home) and MVS (arcade) systems are cartridge based.
Each cartridge consists of two PCBs: CHA and PROG.
.CHA PCB contains gfx data ('C' - rom), text layer data ('S' - rom) and sound driver ('M' - rom).
.PROG PCB contains sample data ('V' - rom) and program code ('P' - rom).
On most PCBs various custom/protection chips can also be found:
(Custom chip detail information (modified) from: http://wiki.neogeodev.org)
CHA:
. NEO-273 (C and S-ROM address latch)
. NEO-CMC 90G06CF7042 (NEO-273 logic / NEO-ZMC logic / C-ROM decryption / C and S-ROM multiplexer / S-ROM bankswitching)
. NEO-CMC 90G06CF7050 (NEO-273 logic / NEO-ZMC logic / C-ROM decryption / M-ROM decryption / C and S-ROM multiplexer / S-ROM bankswitching)
. NEO-ZMC (Z80 memory controller)
. NEO-ZMC2 (Z80 memory controller / Tile serializer)
. PRO-CT0 (C-ROM serializer and multiplexer?; used on early AES-CHA boards)
. SNK-9201 (C-ROM serializer and multiplexer?; used on early AES-CHA boards)
PROG:
. 0103 (QFP144) (Only found on Metal Slug X NEO-MVS PROGEOP board; function unknown)
. ALTERA (EPM7128SQC100-15) (P-ROM protection chip used for KOF98 NEO-MVS PROGSF1 board and Metal Slug X NEO-MVS PROGEOP board)
. NEO-COMA (Microcontroller; used for MULTI PLAY MODE, boards and sets see below)
. NEO-PCM2 (SNK 1999) (PCM functionality / V-ROM decryption / P-ROM decoding and bankswitching)
. NEO-PCM2 (PLAYMORE 2002) (PCM functionality / V-ROM decryption / P-ROM decoding and bankswitching)
. NEO-PVC (P-ROM decryption and bankswitching) / RAM
. NEO-SMA (P-ROM decryption and bankswitching / RNG / Storage of 256kb game data)
. PCM (ADPCM bus latches / V-ROM multiplexer)
. PRO-CT0 (On PROG board used for P-ROM protection -> Fatal Fury 2)
. SNK-9201 (On PROG board used for P-ROM protection -> Fatal Fury 2)
Known PCBs:
============
MVS CHA:
-- SNK --
. NEO-MVS CHA-32
. NEO-MVS CHA-8M
. NEO-MVS CHA42G
. NEO-MVS CHA42G-1
. NEO-MVS CHA 42G-2
. NEO-MVS CHA 42G-3
. NEO-MVS CHA42G-3B
. NEO-MVS CHA256
. NEO-MVS CHA256B
. NEO-MVS CHA512Y
. NEO-MVS CHAFIO (1999.6.14) - used with NEO-CMC 90G06C7042 or NEO-CMC 90G06C7050
. MVS CHAFIO REV1.0 (KOF-2001)
. NEO-MVS CHAFIO (SNK 2002) - MADE IN KOREA
-- SNKPLAYMORE --
. NEO-MVS CHAFIO (2003.7.24) - used only with NEO-CMC 90G06C7050
-- SNK development boards --
. NEO-MVS CHAMC2
MVS PROG:
-- SNK --
. NEO-MVS PROG-NAM
. NEO-MVS PROG-HERO
. NEO-MVS PROG-EP
. NEO-MVS PROG-8MB
. NEO-MVS PROGEP8M
. NEO-MVS PROG8M42
. NEO-MVS PROG16
. NEO-MVS PROG42G
. NEO-MVS PROG42G-COM
. NEO-MVS PROG42G-1
. NEO-MVS PROG-G2
. NEO-MVS PROG 4096
. NEO-MVS PROG 4096 B
. NEO-MVS PROGGSC
. NEO-MVS PROGSM
. NEO-MVS PROGSS3
. NEO-MVS PROGTOP
. NEO-MVS PROGSF1 (1998.6.17)
. NEO-MVS PROGSF1E (1998.6.18)
. NEO-MVS PROGEOP (1999.2.2)
. NEO-MVS PROGLBA (1999.4.12) - LBA-SUB (2000.2.24)
. NEO-MVS PROGBK1 (1994)
. NEO-MVS PROGBK1 (2001)
. NEO-MVS PROGBK2 (2000.3.21) - used with NEO-PCM2 (1999 SNK) or NEO-PCM2 (2002 PLAYMORE)
. MVS PROGBK2 REV1.0 (KOF-2001)
. NEO-MVS PROGBK2 (SNK 2002) - MADE IN KOREA
-- SNKPLAYMORE --
. NEO-MVS PROGBK2R (2003.8.26) - NEO-HYCS (2003.9.29)
. NEO-MVS PROGBK3R (2003.9.2) - NEO-HYCS (2003.9.29)
. NEO-MVS PROGBK3S (2003.10.1)
. NEO-MVS PROGBK2S (2003.10.18)
-- SNK development boards --
. NEO-MVS PROGMC2
AES CHA:
-- SNK --
. NEO-AEG CHA-32
. NEO-AEG CHA-8M
. NEO-AEG CHA42G
. NEO-AEG CHA42G-1
. NEO-AEG CHA42G-2B
. NEO-AEG CHA42G-3
. NEO-AEG CHA42G-4
. NEO-AEG CHA256
. NEO-AEG CHA256 B
. NEO-AEG CHA256[B]
. NEO-AEG CHA256BY
. NEO-AEG CHA256RY
. NEO-AEG CHA512Y
. NEO-AEG CHAFIO (1999.8.10) - used with NEO-CMC 90G06C7042 or NEO-CMC 90G06C7050
-- SNKPLAYMORE --
. NEO-AEG CHAFIO (2003.7.24) - used only with NEO-CMC 90G06C7050
AES PROG:
-- SNK --
. NEO-AEG PROG-NAM
. NEO-AEG PROG-HERO
. NEO-AEG PROG-4A
. NEO-AEG PROG-4B
. NEO-AEG PROG 8M42
. NEO-AEG PROG B
. NEO-AEG PROG16
. NEO-AEG PROG42G
. NEO-AEG PROG42G-COM
. NEO-AEG PROG42G-1
. NEO-AEG PROG-G2
. NEO-AEG PROG4096 B
. NEO-AEG PROGGS
. NEO-AEG PROGTOP2
. NEO-AEG PROGTOP2Y
. NEO-AEG PROGEOP (1999.4.2)
. NEO-AEG PROGLBA (1999.7.6)
. NEO-AEG PROGRK
. NEO-AEG PROGRKB
. NEO-AEG PROGBK1Y
. NEO-AEG PROGBK1F
-- PLAYMORE --
. NEO-AEG PROGBK2 (2002.4.1) - used with NEO-PCM2 (1999 SNK) or NEO-PCM2 (2002 PLAYMORE)
-- SNKPLAYMORE --
. NEO-AEG PROGBK3R (2003.8.29) - NEO-HYCS (2003.9.29)
. NEO-AEG PROGBK3S (2003.10.6)
. NEO-AEG PROGBK2S (2003.10.16)
Cartridge colours:
==================
MVS cartridges were produced in different colours.
Known cartridge colours:
. Black
. Blue
. Green
. Grey
. Red
. Transparent
. Transparent Blue
. Transparent Green
. White
. Yellow
The above listed only covers SNK / PLAYMORE / SNKPLAYMORE PCBs. There also exists a
wide range of 'bootleg' PCBs.
Unofficial PCBs from NG:DEV.TEAM:
MVS CHA:
GIGA CHAR Board 1.0 Rev. A
GIGA CHAR Board 1.5 Rev. 0
GIGA CHAR Board 1.5 Rev. C
MVS PROG:
GIGA PROG Board 1.0 Rev. B
GIGA PROG Board 1.5 Rev. A
GIGA PROG Board 1.5 Rev. C
Unofficial PCBs from NEOBITZ:
MVS CHA:
CHARBITZ1 2013.12.01
MVS PROG:
PROGBITZ1 2013.12.01
Neo-Geo game PCB infos by Johnboy
MVS cart pinout:
================
Kindly submitted by Apollo69 (apollo69@columbus.rr.com)
=================================================================
CTRG1 CTRG2
=================================================================
GND = 01A | 01B = GND GND = 01A | 01B = GND
GND = 02A | 02B = GND GND = 02A | 02B = GND
P0 = 03A | 03B = P1 GND = 03A | 03B = GND
P2 = 04A | 04B = P3 GND = 04A | 04B = GND
P4 = 05A | 05B = P5 D0 = 05A | 05B = A1
P6 = 06A | 06B = P7 D1 = 06A | 06B = A2
P8 = 07A | 07B = P9 D2 = 07A | 07B = A3
P10 = 08A | 08B = P11 D3 = 08A | 08B = A4
P12 = 09A | 09B = P13 D4 = 09A | 09B = A5
P14 = 10A | 10B = P15 D5 = 10A | 10B = A6
P16 = 11A | 11B = P17 D6 = 11A | 11B = A7
P18 = 12A | 12B = P19 D7 = 12A | 12B = A8
P20 = 13A | 13B = P21 D8 = 13A | 13B = A9
P22 = 14A | 14B = P23 D9 = 14A | 14B = A10
PCK1B = 15A | 15B = 24M D10 = 15A | 15B = A11
PCK2B = 16A | 16B = 12M D11 = 16A | 16B = A12
2H1 = 17A | 17B = 8M D12 = 17A | 17B = A13
CA4 = 18A | 18B = RESET D13 = 18A | 18B = A14
CR0 = 19A | 19B = CR1 D14 = 19A | 19B = A15
CR2 = 20A | 20B = CR3 D15 = 20A | 20B = A16
CR4 = 21A | 21B = CR5 R/W = 21A | 21B = A17
CR6 = 22A | 22B = CR7 AS = 22A | 22B = A18
CR8 = 23A | 23B = CR9 ROMOEU = 23A | 23B = A19
CR10 = 24A | 24B = CR11 ROMOEL = 24A | 24B = 68KCLKB
CR12 = 25A | 25B = CR13 PORTOEU = 25A | 25B = ROMWAIT
CR14 = 26A | 26B = CR15 PORTOEL = 26A | 26B = PWAIT0
CR16 = 27A | 27B = CR17 PORTWEU = 27A | 27B = PWAIT1
CR18 = 28A | 28B = CR19 PORTWEL = 28A | 28B = PDTACT
VCC = 29A | 29B = VCC VCC = 29A | 29B = VCC
VCC = 30A | 30B = VCC VCC = 30A | 30B = VCC
VCC = 31A | 31B = VCC VCC = 31A | 31B = VCC
VCC = 32A | 32B = VCC VCC = 32A | 32B = VCC
CR20 = 33A | 33B = CR21 PORTADRS = 33A | 33B = ROMOE
CR22 = 34A | 34B = CR23 NC = 34A | 34B = 4MB
CR24 = 35A | 35B = CR25 NC = 35A | 35B = RESET
CR26 = 36A | 36B = CR27 NC = 36A | 36B = NC
CR28 = 37A | 37B = CR29 NC = 37A | 37B = NC
CR30 = 38A | 38B = CR31 NC = 38A | 38B = NC
NC = 39A | 39B = FIX00 NC = 39A | 39B = NC
NC = 40A | 40B = FIX01 NC = 40A | 40B = NC
NC = 41A | 41B = FIX02 NC = 41A | 41B = SDPAD0
SLOTCS = 42A | 42B = FIX03 SLOTCS = 42A | 42B = SDPAD1
SDA0 = 43A | 43B = FIX04 SDPA8 = 43A | 43B = SDPAD2
SDA1 = 44A | 44B = FIX05 SDPA9 = 44A | 44B = SDPAD3
SDA2 = 45A | 45B = FIX06 SDPA10 = 45A | 45B = SDPAD4
SDA3 = 46A | 46B = FIX07 SDPA11 = 46A | 46B = SDPAD5
SDA4 = 47A | 47B = SDRD0 SDPMPX = 47A | 47B = SDPAD6
SDA5 = 48A | 48B = SDRD1 SDPOE = 48A | 48B = SDPAD7
SDA6 = 49A | 49B = SDROM SDRA8 = 49A | 49B = SDRAD0
SDA7 = 50A | 50B = SDMRD SDRA9 = 50A | 50B = SDRAD1
SDA8 = 51A | 51B = SDD0 SDRA20 = 51A | 51B = SDRAD2
SDA9 = 52A | 52B = SDD1 SDRA21 = 52A | 52B = SDRAD3
SDA10 = 53A | 53B = SDD2 SDRA22 = 53A | 53B = SDRAD4
SDA11 = 54A | 54B = SDD3 SDRA23 = 54A | 54B = SDRAD5
SDA12 = 55A | 55B = SDD4 SDRMPX = 55A | 55B = SDRAD6
SDA13 = 56A | 56B = SDD5 SDROE = 56A | 56B = SDRAD7
SDA14 = 57A | 57B = SDD6 GND = 57A | 57B = GND
SDA15 = 58A | 58B = SDD7 GND = 58A | 58B = GND
GND = 59A | 59B = GND GND = 59A | 59B = GND
GND = 60A | 60B = GND GND = 60A | 60B = GND
CTRG1 (CHA) = Contains gfx data ('C' - rom), text layer data ('S' - rom) and sound driver ('M' - rom)
CTRG2 (PROG) = Contains sample data ('V' - rom) and program code ('P' - rom)
NOTE: On CTRG2-B, The "A" lines start at "A1". If you trace this on an
actual cart, you will see that this is actually "A0" (A0 - A18).
These are from a very hard to read copy of the schematics, so
I hope that I got the pin names correct.
Apollo69 10/19/99
Edge connector pinout:
======================
Kindly submitted by Apollo69 (apollo69@columbus.rr.com)
=================================================================
MVS JAMMA
=================================================================
GND = A | 1 = GND GND = A | 1 = GND
GND = B | 2 = GND GND = B | 2 = GND
+5V = C | 3 = +5V +5V = C | 3 = +5V
+5V = D | 4 = +5V +5V = D | 4 = +5V
N/C = E | 5 = N/C E | 5
+12V = F | 6 = +12V +12V = F | 6 = +12V
key = H | 7 = key key = H | 7 = key
counter 2 = J | 8 = counter 1 counter 2 = J | 8 = counter 1
lockout 2 = K | 9 = lockout 1 lockout 2 = K | 9 = lockout 1
L speaker = L | 10 = R speaker speaker- = L | 10 = speaker+
test = M | 11 = audio+ audio GND = M | 11
green = N | 12 = red green = N | 12 = red
sync = P | 13 = blue sync = P | 13 = blue
service = R | 14 = video GND service = R | 14 = video GND
coin 4 2P = S | 15 = coin 3 1P S | 15 = test
coin 2 2P = T | 16 = coin 1 1P coin 2 2P = T | 16 = coin 1 1P
2P start = U | 17 = 1P start 2P start = U | 17 = 1P start
2P up = V | 18 = 1P up 2P up = V | 18 = 1P up
2P down = W | 19 = 1P down 2P down = W | 19 = 1P down
2P left = X | 20 = 1P left 2P left = X | 20 = 1P left
2P right = Y | 21 = 1P right 2P right = Y | 21 = 1P right
2P A = Z | 22 = 1P A 2P A = Z | 22 = 1P A
2P B = a | 23 = 1P B 2P B = a | 23 = 1P B
2P C = b | 24 = 1P C 2P C = b | 24 = 1P C
2P D = c | 25 = 1P D 2P D = c | 25 = 1P D
sel down = d | 26 = sel up d | 26 = data input
GND = e | 27 = GND GND = e | 27 = GND
GND = f | 28 = GND GND = f | 28 = GND
Later JAMMA systems drop coin lockouts and audio ground.
Some JAMMA systems omit data input switch.
*****************************************************************************
Watchdog:
=========
The watchdog timer will reset the system after ~0.13 seconds.
By cgfm's research, exactly 3,244,030 cycles (based on 24MHz clock).
Newer games force a reset using the following code (this from kof99):
009CDA 203C 0003 0D40 MOVE.L #0x30D40,D0
009CE0 5380 SUBQ.L #1,D0
009CE2 64FC BCC.S *-0x2 [0x9CE0]
Note however that there is a valid code path after this loop.
The watchdog is used as a form of protection on a number of games,
previously this was implemented as a specific hack which locked a single
address of SRAM.
What actually happens is if the game doesn't find valid data in the
backup ram it will initialize it, then sit in a loop. The watchdog
should then reset the system while it is in this loop. If the watchdog
fails to reset the system the code will continue and set a value in
backup ram to indicate that the protection check has failed.
****************************************************************************
Mahjong Panel notes (2009-03 FP):
=================================
* In Service Mode menu with mahjong panel active, controls are as
follows:
A = select / up (for options)
B = down (for options)
C = go to previous menu
E = up (for menu entries)
F = down (for menu entries)
G = left (for options)
H = right (for options)
* These only work with Japanese BIOS, but I think it's not a bug: I
doubt other BIOS were programmed to be compatible with mahjong panels
****************************************************************************
AES driver (home version of MVS)
Current emulation status:
- Cartridges run.
- Riding Hero runs in slow-mo due to the unemulated comm link MCU in the cartridge.
In MAME if dip SW6 is set to ON to enable link play, it runs the same way!
On AES there are no dipswitches, and so it always tries to talk to the MCU.
****************************************************************************/
#include "emu.h"
#include "neogeo.h"
#include "machine/nvram.h"
#include "machine/watchdog.h"
#include "softlist_dev.h"
#include "speaker.h"
#include "irrmaze.lh"
#include "neogeo.lh"
#define LOG_VIDEO_SYSTEM (1U << 1)
#define VERBOSE (0)
#include "logmacro.h"
class mvs_state : public ngarcade_base_state
{
public:
mvs_state(const machine_config &mconfig, device_type type, const char *tag)
: ngarcade_base_state(mconfig, type, tag)
{
}
// mainboard configurations
void cartslot_config(machine_config &config, unsigned count);
void cartslot_fixed(machine_config &config, char const *dflt);
void mv1fz(machine_config &config);
// fixed software configurations
void kizuna4p(machine_config &config);
void irrmaze(machine_config &config);
protected:
virtual void machine_start() override;
virtual void device_post_load() override;
virtual void output_strobe(uint8_t bits, uint8_t data) { }
virtual void set_outputs() { }
virtual void io_control_w(offs_t offset, uint8_t data) override;
private:
uint8_t m_output_data = 0;
uint8_t m_output_latch = 0;
};
class mvs_led_state : public mvs_state
{
public:
mvs_led_state(const machine_config &mconfig, device_type type, const char *tag)
: mvs_state(mconfig, type, tag)
, m_digits(*this, "digit%u", 1U)
{
}
// mainboard configurations
void mv1(machine_config &config);
void mv1f(machine_config &config);
// fixed software configurations
void neobase(machine_config &config);
void fatfur2(machine_config &config);
void kof97oro(machine_config &config);
void kog(machine_config &config);
void kof98(machine_config &config);
void mslugx(machine_config &config);
void kof99(machine_config &config);
void kof99k(machine_config &config);
void garou(machine_config &config);
void garouh(machine_config &config);
void garoubl(machine_config &config);
void mslug3(machine_config &config);
void mslug3a(machine_config &config);
void mslug3h(machine_config &config);
void mslug3b6(machine_config &config);
void kof2000(machine_config &config);
void kof2000n(machine_config &config);
void zupapa(machine_config &config);
void sengoku3(machine_config &config);
void kof2001(machine_config &config);
void cthd2k3(machine_config &config);
void ct2k3sp(machine_config &config);
void ct2k3sa(machine_config &config);
void kof2002(machine_config &config);
void kof2002b(machine_config &config);
void kf2k2pls(machine_config &config);
void kf2k2mp(machine_config &config);
void kf2k2mp2(machine_config &config);
void kof10th(machine_config &config);
void kf10thep(machine_config &config);
void kf2k5uni(machine_config &config);
void kof2k4se(machine_config &config);
void mslug5(machine_config &config);
void ms5plus(machine_config &config);
void mslug5b(machine_config &config);
void svc(machine_config &config);
void svcboot(machine_config &config);
void svcplus(machine_config &config);
void svcplusa(machine_config &config);
void svcsplus(machine_config &config);
void samsho5(machine_config &config);
void samsho5b(machine_config &config);
void kof2003(machine_config &config);
void kof2003h(machine_config &config);
void kf2k3bl(machine_config &config);
void kf2k3pl(machine_config &config);
void kf2k3upl(machine_config &config);
void samsh5sp(machine_config &config);
void neogeo_mj(machine_config &config);
void preisle2(machine_config &config);
void nitd(machine_config &config);
void s1945p(machine_config &config);
void lans2004(machine_config &config);
void pnyaa(machine_config &config);
void popbounc(machine_config &config);
void ganryu(machine_config &config);
void bangbead(machine_config &config);
void mslug4(machine_config &config);
void ms4plus(machine_config &config);
void rotd(machine_config &config);
void matrim(machine_config &config);
void matrimbl(machine_config &config);
void jockeygp(machine_config &config);
void vliner(machine_config &config);
void sbp(machine_config &config);
protected:
virtual void machine_start() override;
virtual void output_strobe(uint8_t bits, uint8_t data) override;
virtual void set_outputs() override;
void mv1_fixed(machine_config &config);
private:
output_finder<4> m_digits;
uint8_t m_led1_value = 0;
uint8_t m_led2_value = 0;
};
class mvs_led_el_state : public mvs_led_state
{
public:
mvs_led_el_state(const machine_config &mconfig, device_type type, const char *tag)
: mvs_led_state(mconfig, type, tag)
, m_lamps(*this, "lamp%u", 1U)
{
}
// mainboard configurations
void mv2f(machine_config &config);
void mv4f(machine_config &config);
void mv6f(machine_config &config);
protected:
virtual void machine_start() override;
virtual void output_strobe(uint8_t bits, uint8_t data) override;
virtual void set_outputs() override;
private:
output_finder<6> m_lamps;
uint8_t m_el_value = 0;
};
class aes_state : public aes_base_state
{
public:
aes_state(const machine_config &mconfig, device_type type, const char *tag)
: aes_base_state(mconfig, type, tag)
{
}
void aes_ntsc(machine_config &config);
protected:
virtual void machine_start() override;
virtual void device_post_load() override;
void aes_main_map(address_map &map);
};
/*************************************
*
* Main CPU interrupt generation
*
*************************************/
// The display counter is automatically reloaded with the load register contents on scanline 224,
// 1146 mclks from the rising edge of /HSYNC.
#define NEOGEO_VBLANK_RELOAD_HTIM (attotime::from_ticks(1146, NEOGEO_MASTER_CLOCK))
#define IRQ2CTRL_ENABLE (0x10)
#define IRQ2CTRL_LOAD_RELATIVE (0x20)
#define IRQ2CTRL_AUTOLOAD_VBLANK (0x40)
#define IRQ2CTRL_AUTOLOAD_REPEAT (0x80)
void neogeo_base_state::adjust_display_position_interrupt_timer()
{
attotime period = attotime::from_ticks((uint64_t)m_display_counter + 1, NEOGEO_PIXEL_CLOCK);
LOGMASKED(LOG_VIDEO_SYSTEM, "adjust_display_position_interrupt_timer current y: %02x current x: %02x target y: %x target x: %x\n", m_screen->vpos(), m_screen->hpos(), (m_display_counter + 1) / NEOGEO_HTOTAL, (m_display_counter + 1) % NEOGEO_HTOTAL);
m_display_position_interrupt_timer->adjust(period);
}
void neogeo_base_state::set_display_position_interrupt_control(uint16_t data)
{
m_display_position_interrupt_control = data;
}
void neogeo_base_state::set_display_counter_msb(uint16_t data)
{
m_display_counter = (m_display_counter & 0x0000ffff) | ((uint32_t)data << 16);
LOGMASKED(LOG_VIDEO_SYSTEM, "PC %06x: set_display_counter %08x\n", m_maincpu->pc(), m_display_counter);
}
void neogeo_base_state::set_display_counter_lsb(uint16_t data)
{
m_display_counter = (m_display_counter & 0xffff0000) | data;
LOGMASKED(LOG_VIDEO_SYSTEM, "PC %06x: set_display_counter %08x\n", m_maincpu->pc(), m_display_counter);
if (m_display_position_interrupt_control & IRQ2CTRL_LOAD_RELATIVE)
{
LOGMASKED(LOG_VIDEO_SYSTEM, "AUTOLOAD_RELATIVE ");
adjust_display_position_interrupt_timer();
}
}
void neogeo_base_state::update_interrupts()
{
m_maincpu->set_input_line(3, m_irq3_pending ? ASSERT_LINE : CLEAR_LINE);
m_maincpu->set_input_line(m_raster_level, m_display_position_interrupt_pending ? ASSERT_LINE : CLEAR_LINE);
m_maincpu->set_input_line(m_vblank_level, m_vblank_interrupt_pending ? ASSERT_LINE : CLEAR_LINE);
}
void neogeo_base_state::acknowledge_interrupt(uint16_t data)
{
if (data & 0x01)
m_irq3_pending = 0;
if (data & 0x02)
m_display_position_interrupt_pending = 0;
if (data & 0x04)
m_vblank_interrupt_pending = 0;
update_interrupts();
}
TIMER_CALLBACK_MEMBER(neogeo_base_state::display_position_interrupt_callback)
{
LOGMASKED(LOG_VIDEO_SYSTEM, "--- Scanline @ %d,%d\n", m_screen->vpos(), m_screen->hpos());
if (m_display_position_interrupt_control & IRQ2CTRL_ENABLE)
{
LOGMASKED(LOG_VIDEO_SYSTEM, "*** Scanline interrupt (IRQ2) *** y: %02x x: %02x\n", m_screen->vpos(), m_screen->hpos());
m_display_position_interrupt_pending = 1;
update_interrupts();
}
if (m_display_position_interrupt_control & IRQ2CTRL_AUTOLOAD_REPEAT)
{
LOGMASKED(LOG_VIDEO_SYSTEM, "AUTOLOAD_REPEAT ");
adjust_display_position_interrupt_timer();
}
}
TIMER_CALLBACK_MEMBER(neogeo_base_state::display_position_vblank_callback)
{
if (m_display_position_interrupt_control & IRQ2CTRL_AUTOLOAD_VBLANK)
{
LOGMASKED(LOG_VIDEO_SYSTEM, "AUTOLOAD_VBLANK ");
adjust_display_position_interrupt_timer();
}
/* set timer for next screen */
m_display_position_vblank_timer->adjust(m_screen->time_until_pos(NEOGEO_VBSTART) + NEOGEO_VBLANK_RELOAD_HTIM);
}
TIMER_CALLBACK_MEMBER(neogeo_base_state::vblank_interrupt_callback)
{
LOGMASKED(LOG_VIDEO_SYSTEM, "+++ VBLANK @ %d,%d\n", m_screen->vpos(), m_screen->hpos());
m_vblank_interrupt_pending = 1;
update_interrupts();
/* set timer for next screen */
m_vblank_interrupt_timer->adjust(m_screen->time_until_pos(NEOGEO_VBSTART) + NEOGEO_VBLANK_IRQ_HTIM);
}
void neogeo_base_state::create_interrupt_timers()
{
m_display_position_interrupt_timer = timer_alloc(FUNC(neogeo_base_state::display_position_interrupt_callback), this);
m_display_position_vblank_timer = timer_alloc(FUNC(neogeo_base_state::display_position_vblank_callback), this);
m_vblank_interrupt_timer = timer_alloc(FUNC(neogeo_base_state::vblank_interrupt_callback), this);
}
void neogeo_base_state::start_interrupt_timers()
{
m_vblank_interrupt_timer->adjust(m_screen->time_until_pos(NEOGEO_VBSTART) + NEOGEO_VBLANK_IRQ_HTIM);
m_display_position_vblank_timer->adjust(m_screen->time_until_pos(NEOGEO_VBSTART) + NEOGEO_VBLANK_RELOAD_HTIM);
}
/*************************************
*
* Audio CPU interrupt generation
*
*************************************/
void neogeo_base_state::audio_cpu_enable_nmi_w(offs_t offset, uint8_t data)
{
// out ($08) enables the nmi, out ($18) disables it
m_audionmi->in_w<1>(BIT(~offset, 4));
}
/*************************************
*
* Input ports / Controllers
*
*************************************/
uint16_t ngarcade_base_state::in0_edge_r()
{
return (m_edge->in0_r() << 8) | m_dsw->read();
}
uint16_t ngarcade_base_state::in0_edge_joy_r()
{
return ((m_edge->in0_r() & m_ctrl1->read_ctrl()) << 8) | m_dsw->read();
}
uint16_t ngarcade_base_state::in1_edge_r()
{
return (m_edge->in1_r() << 8) | 0xff;
}
uint16_t ngarcade_base_state::in1_edge_joy_r()
{
return ((m_edge->in1_r() & m_ctrl2->read_ctrl()) << 8) | 0xff;
}
CUSTOM_INPUT_MEMBER(ngarcade_base_state::startsel_edge_joy_r)
{
uint32_t ret = m_edge->read_start_sel() | ~0x05;
if (m_ctrl1)
ret &= (m_ctrl1->read_start_sel() << 0) | ~0x03;
if (m_ctrl2)
ret &= (m_ctrl2->read_start_sel() << 2) | ~0x0c;
return ret;
}
void neogeo_base_state::io_control_w(offs_t offset, uint8_t data)
{
switch (offset & 0x38) // TODO: the mask is supposedly less restrictive on AES?
{
case 0x00:
if (m_ctrl1) m_ctrl1->write_ctrlsel(data & 0x07);
if (m_ctrl2) m_ctrl2->write_ctrlsel((data >> 3) & 0x07);
if (m_edge) m_edge->write_ctrlsel(data & 0x3f); // FIXME: only MV-1B and MV-1C have this output
break;
case 0x08:
m_card_bank = data & 0x07;
break;
default:
logerror("%s: Unmapped I/O control write. Offset: %02x Data: %02x\n", machine().describe_context(), offset, data);
}
}
void ngarcade_base_state::io_control_w(offs_t offset, uint8_t data)
{
switch (offset & 0x78)
{
case 0x00:
case 0x08:
neogeo_base_state::io_control_w(offset, data);
break;
case 0x28:
m_upd4990a->data_in_w(BIT(data, 0));
m_upd4990a->clk_w(BIT(data, 1));
m_upd4990a->stb_w(BIT(data, 2));
break;
case 0x30:
case 0x70:
if (BIT(offset, 1))
machine().bookkeeping().coin_lockout_w(BIT(offset, 0), BIT(offset, 6));
else
machine().bookkeeping().coin_counter_w(BIT(offset, 0), BIT(offset, 6));
break;
default:
logerror("%s: Unmapped I/O control write. Offset: %02x Data: %02x\n", machine().describe_context(), offset, data);
}
}
void mvs_state::io_control_w(offs_t offset, uint8_t data)
{
switch (offset & 0x78)
{
case 0x10:
if (m_slots[data])
set_slot_idx(data);
break;
case 0x18:
// strobe on falling edge
output_strobe(m_output_latch & ~data, m_output_data);
m_output_latch = data;
set_outputs();
break;
case 0x20:
m_output_data = data;
break;
default:
ngarcade_base_state::io_control_w(offset, data);
}
}