mirror of
https://github.com/libretro/mame2003-plus-libretro.git
synced 2026-11-11 03:01:26 -10:00
Compare commits
147
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86676fd030 | ||
|
|
101a3c4615 | ||
|
|
ffc68e38d9 | ||
|
|
080e2f8916 | ||
|
|
65d2272c9b | ||
|
|
db6bffdae0 | ||
|
|
c6a547a379 | ||
|
|
17c28f93c1 | ||
|
|
da65b34feb | ||
|
|
d53b244990 | ||
|
|
5865842962 | ||
|
|
9525caa7e8 | ||
|
|
483d854518 | ||
|
|
4e96962446 | ||
|
|
67e99574d4 | ||
|
|
ca0dc1a147 | ||
|
|
45d3576576 | ||
|
|
8ff668596c | ||
|
|
1c23227c79 | ||
|
|
39fcb104e2 | ||
|
|
d8ddd5b9f5 | ||
|
|
a514e1f0ac | ||
|
|
d0dd053834 | ||
|
|
73fcfe418d | ||
|
|
e36928faac | ||
|
|
7d9da4e99a | ||
|
|
0f2695d091 | ||
|
|
b96cd8c43a | ||
|
|
76a64e85dd | ||
|
|
d9ef30cf14 | ||
|
|
1a3ae77e39 | ||
|
|
d483d33314 | ||
|
|
3c9fe3a43b | ||
|
|
81fac8a81a | ||
|
|
b3cf0a37d2 | ||
|
|
4f83ca25f1 | ||
|
|
a275f8dfc4 | ||
|
|
2df7f7b29d | ||
|
|
8ed414a1f5 | ||
|
|
d708f399f7 | ||
|
|
dc3148e25a | ||
|
|
ee687592a7 | ||
|
|
5e0aeb4cb4 | ||
|
|
620c7ba7d1 | ||
|
|
4a9ed46a7b | ||
|
|
969075a5ae | ||
|
|
440a6dc232 | ||
|
|
3234504360 | ||
|
|
7ebb758a6a | ||
|
|
ffc7666884 | ||
|
|
da3a90f659 | ||
|
|
0f88b8feae | ||
|
|
1624990be3 | ||
|
|
25900bae57 | ||
|
|
8343ab6b0e | ||
|
|
38a7da6eac | ||
|
|
f1abec1d1a | ||
|
|
59f7ca7c30 | ||
|
|
9aece938b6 | ||
|
|
505733a2df | ||
|
|
23a56e6afe | ||
|
|
28bb883273 | ||
|
|
149c6e2640 | ||
|
|
5bd572a2b8 | ||
|
|
5262c77700 | ||
|
|
a27a08f661 | ||
|
|
2a14d0c3f8 | ||
|
|
f32b6d8a95 | ||
|
|
0aaf055d11 | ||
|
|
c53f2b4206 | ||
|
|
0b06ca52dc | ||
|
|
7b46a717d8 | ||
|
|
ce908de1c1 | ||
|
|
fbd9882765 | ||
|
|
1d96012a6f | ||
|
|
a6087d4e1a | ||
|
|
fdb7a57451 | ||
|
|
b2855ef3b1 | ||
|
|
98ea5e6469 | ||
|
|
6b20b595a4 | ||
|
|
804b9baabc | ||
|
|
5443426940 | ||
|
|
94ee7d65ee | ||
|
|
f61aa3a0b5 | ||
|
|
c797619396 | ||
|
|
9029a8abec | ||
|
|
5563d70290 | ||
|
|
23c1680f56 | ||
|
|
f518b40918 | ||
|
|
521a327dd9 | ||
|
|
8a9224a9a6 | ||
|
|
cfac240042 | ||
|
|
c5233bcb58 | ||
|
|
a5e5261093 | ||
|
|
92c7b8e475 | ||
|
|
62eca3b507 | ||
|
|
b8df278931 | ||
|
|
d3d8defb48 | ||
|
|
bf6a7455d7 | ||
|
|
89a47488e9 | ||
|
|
b12d6012b5 | ||
|
|
2decddc0b5 | ||
|
|
fd01c495ad | ||
|
|
eb611beff8 | ||
|
|
4a79de6337 | ||
|
|
7b1ad60b94 | ||
|
|
b5ca65f5fd | ||
|
|
5f39e722a5 | ||
|
|
74a1af5baf | ||
|
|
ccaebab82e | ||
|
|
aa2b32f913 | ||
|
|
b0068b501e | ||
|
|
3277597377 | ||
|
|
da8c86f159 | ||
|
|
e05caba0aa | ||
|
|
9d9d1ed901 | ||
|
|
155d68254c | ||
|
|
0fe5665808 | ||
|
|
97cb277199 | ||
|
|
d73ba22c26 | ||
|
|
64de9b21ed | ||
|
|
1104e225f9 | ||
|
|
21c9f8ffd4 | ||
|
|
10315f744e | ||
|
|
b52156ee5d | ||
|
|
a0ab0427b9 | ||
|
|
c620bfebef | ||
|
|
f073a5af73 | ||
|
|
0d9a325c96 | ||
|
|
31419303cb | ||
|
|
0077ef7e41 | ||
|
|
546424f3cd | ||
|
|
8393e124af | ||
|
|
0f72193fcc | ||
|
|
5da0428c7f | ||
|
|
e059bb0fe8 | ||
|
|
6e6f19aa43 | ||
|
|
9bbb94cf6d | ||
|
|
d3ac6c95f2 | ||
|
|
3a2f7f39b1 | ||
|
|
07a41088de | ||
|
|
21256d2412 | ||
|
|
a045126dad | ||
|
|
6c514a3242 | ||
|
|
dc1f391a83 | ||
|
|
93159c0ce9 | ||
|
|
5bbb84086c |
No files matched your search
+23
-1
@@ -29,6 +29,7 @@ The list of direct contributors to the MAME 2003-Plus github repository can be f
|
||||
* Bare Knuckle II (chinese bootleg of Megadrive version)
|
||||
* Bare Knuckle III (bootleg of Megadrive version)
|
||||
* Baryon: Future Assault
|
||||
* Beastie Feastie (Epos Tristar 9000) - Romset `beastf`; the Pac-Man conversion is now `beastfp`, as in current MAME
|
||||
* Big Fight - Big Trouble In The Atlantic Ocean
|
||||
* Bomb Kick
|
||||
* Boogie Wings
|
||||
@@ -155,6 +156,7 @@ The list of direct contributors to the MAME 2003-Plus github repository can be f
|
||||
* Ms. Pacman Twin
|
||||
* Mrs. Dynamite
|
||||
* Multi Champ Deluxe * Mature *
|
||||
* New Zero Team
|
||||
* Ninja Kazan
|
||||
* Oo Parts (Japan, Prototype)
|
||||
* Opa Opa (Rev A Unprotected)
|
||||
@@ -186,7 +188,11 @@ The list of direct contributors to the MAME 2003-Plus github repository can be f
|
||||
* Racing Beat
|
||||
* Racing Hero
|
||||
* Rage Of The Dragons
|
||||
* Raiden II
|
||||
* Raiden DX
|
||||
* Raiden II / Raiden DX New
|
||||
* Recalhorn (prototype)
|
||||
* Revenger '84 (newer) - Romset `revngr84`; the older set `revenger` is a bad dump and stays not working
|
||||
* Riot
|
||||
* Rolling Crush
|
||||
* Round Up 5 - Super Delta Force
|
||||
@@ -218,8 +224,11 @@ The list of direct contributors to the MAME 2003-Plus github repository can be f
|
||||
* Space Raider
|
||||
* Spectrum 2000 (Euro)
|
||||
* Squash
|
||||
* Stadium Cross (World, linkable) and (US) - Romsets `scrossa`, `scrossu`; `scross` now uses the ROM names of current MAME
|
||||
* Star Fire 2
|
||||
* Steel Worker
|
||||
* Street Fighter III 3rd Strike: Fight for the Future (Widescreen 20220908, Bank Bank hack) - Romset `sfiii3ws`
|
||||
* Street Fighter Zero 3 Mix v0.32 (Zero800 hack, CPS2Turbo) - Romset `sfz3mix`, optional music samples `sfz3mix.zip`
|
||||
* Success Joe
|
||||
* Super Bishi Bashi Championship (ver JAA, 2 Players)
|
||||
* Super Bubble Bobble (Sun Mixing, Megadrive clone hardware)
|
||||
@@ -268,6 +277,7 @@ The list of direct contributors to the MAME 2003-Plus github repository can be f
|
||||
* Woodpecker
|
||||
* World Cup Volley 95
|
||||
* Xeno Crisis
|
||||
* Zero Team 2000
|
||||
* Zintrick
|
||||
* Zupapa
|
||||
|
||||
@@ -452,11 +462,13 @@ The list of direct contributors to the MAME 2003-Plus github repository can be f
|
||||
* Phantasm - Romset `phantasm`
|
||||
* Photo Y2k - Romset `photoy2k`
|
||||
* Pigskin 621AD - Romset `pigskin`
|
||||
* Princess Clara Daisakusen - Romset `prikura`
|
||||
* Power Drive - Romset `powerdrv`
|
||||
* Prebillian - `pbillian`
|
||||
* Pro Baseball Skill Tryout - `tryout`
|
||||
* Puzzle King (PacMan 2 with Tetris & HyperMan 2 & Snow Bros - `4in1boot`
|
||||
* Rabbit - Romset `rabbit` - no sound
|
||||
* Raiden II - Romset `raiden2`
|
||||
* Rampage - Romsets `rampage` and `rampage2`
|
||||
* Risky Challenge - Romset `riskchal`
|
||||
* Rohga Armor Force - Romsets `rohga`, `rohgah`, `rohgau`
|
||||
@@ -487,6 +499,7 @@ The list of direct contributors to the MAME 2003-Plus github repository can be f
|
||||
* Tapper - Romset `tapper`
|
||||
* Target Ball (Nude) - Romset `tgtball`
|
||||
* Task Force Harrier - Romsets `tharrier` and `tharierj`
|
||||
* The Dealer - Romset `dealer` - Epos Tristar 9000 board from current MAME
|
||||
* Thunder Blade - Romsets `thndrbld` and `thndrbld1`
|
||||
* Thunder Dragon - Romset `tdragon` - Minor sound issues remaining
|
||||
* Thunder Strike - Romset `tstrike`
|
||||
@@ -1159,6 +1172,15 @@ could crash on the score calc between levels is sorted [amadvance, arcadez]
|
||||
* Ported across from FBL dink's fix for the broken text gfx layer in the Japanese version Of Cameltry [dink, arcadez]
|
||||
* Added support for Jammin a rare Atari prototype music game to the Donkey Kong driver [arcadez]
|
||||
* Added Saurian Front a super rare Williams prototype of Midway's Strike Force to the midyunit driver [arcadez]
|
||||
* Added Adventure Canoe to the taitosj driver [arcadez, jackphilippi, dink]
|
||||
* Added Adventure Canoe to the taitosj driver [arcadez, jackphilippi, dink]
|
||||
* Added support for Ketsui: Kizuna Jigoku Tachi - IKD 2007 Special Version to pgm.c [arcadez]
|
||||
* Fixed a protection related problem with powerups in Burning Force [MAMEDev, arcadez]
|
||||
* Extended IREM Drum sample support to Lode Runner 3 and 4 [dink, arcadez]
|
||||
* Improved the dip switch options for Data East's Break Thru [arcadez]
|
||||
* Fixed BG GFX colours for Crater Raider [MAMEDev, arcadez]
|
||||
* Fixed multiple sound sample issues in TAD CORP's Toki [MAMEDev, arcadez]
|
||||
* Fixed sound sample playing for SEGA's Zaxxon [MAMEDev, arcadez]
|
||||
* Fixed Palette banking problems for Pleiads [MAMEDev, arcadez]
|
||||
* Added fixes from later MAME so that Princess Clara Daisakusen now works [MAMEDev, arcadez]
|
||||
* Ported a new raiden2.c driver Raiden II Raiden DX and Zero Team etc etc now playable [Salvia, MAMEDev, FBN, vanni and claude, arcadez]
|
||||
|
||||
@@ -462,6 +462,7 @@ else ifeq ($(platform), psp1)
|
||||
AR = psp-ar$(EXE_EXT)
|
||||
PLATCFLAGS += -DPSP
|
||||
CFLAGS += -G0
|
||||
CFLAGS += -Wno-incompatible-pointer-types
|
||||
STATIC_LINKING = 1
|
||||
|
||||
# Vita
|
||||
|
||||
+128
-3
@@ -134,6 +134,7 @@ CPUS+=I8039@
|
||||
CPUS+=I8048@
|
||||
CPUS+=N7751@
|
||||
CPUS+=I8X41@
|
||||
CPUS+=I8051@
|
||||
CPUS+=M6800@
|
||||
CPUS+=M6801@
|
||||
CPUS+=M6802@
|
||||
@@ -167,17 +168,26 @@ CPUS+=Z8000@
|
||||
CPUS+=TMS32010@
|
||||
CPUS+=TMS32025@
|
||||
CPUS+=TMS32031@
|
||||
CPUS+=I960@
|
||||
CPUS+=MB86233@
|
||||
CPUS+=MB86235@
|
||||
CPUS+=ADSP21062@
|
||||
CPUS+=CCPU@
|
||||
CPUS+=ADSP2100@
|
||||
CPUS+=ADSP2101@
|
||||
CPUS+=ADSP2104@
|
||||
CPUS+=ADSP2105@
|
||||
CPUS+=ADSP2115@
|
||||
CPUS+=ADSP2181@
|
||||
CPUS+=PSXCPU@
|
||||
CPUS+=H83002@
|
||||
CPUS+=MN10200@
|
||||
CPUS+=M37702@
|
||||
CPUS+=ASAP@
|
||||
CPUS+=UPD7810@
|
||||
CPUS+=UPD7807@
|
||||
CPUS+=ARM@
|
||||
CPUS+=ARM7@
|
||||
CPUS+=JAGUAR@
|
||||
CPUS+=R3000@
|
||||
CPUS+=R4600@
|
||||
@@ -243,6 +253,7 @@ SOUNDS+=SEGAPCM@
|
||||
SOUNDS+=RF5C68@
|
||||
SOUNDS+=CEM3394@
|
||||
SOUNDS+=C140@
|
||||
SOUNDS+=C352@
|
||||
SOUNDS+=QSOUND@
|
||||
SOUNDS+=SAA1099@
|
||||
SOUNDS+=IREMGA20@
|
||||
@@ -367,7 +378,7 @@ SOURCES_C += \
|
||||
$(CORE_DIR)/vidhrdw/gridlee_vidhrdw.c $(CORE_DIR)/sndhrdw/gridlee_sndhrdw.c $(CORE_DIR)/drivers/gridlee.c \
|
||||
$(CORE_DIR)/drivers/seattle.c $(CORE_DIR)/vidhrdw/voodoo_vidhrdw.c \
|
||||
$(CORE_DIR)/vidhrdw/exterm_vidhrdw.c $(CORE_DIR)/drivers/exterm.c \
|
||||
$(CORE_DIR)/machine/midwayic.c $(CORE_DIR)/sndhrdw/dcs.c \
|
||||
$(CORE_DIR)/machine/midwayic.c $(CORE_DIR)/machine/smc91c9x.c $(CORE_DIR)/sndhrdw/dcs.c \
|
||||
$(CORE_DIR)/machine/midyunit_machine.c $(CORE_DIR)/vidhrdw/midyunit_vidhrdw.c $(CORE_DIR)/drivers/midyunit.c \
|
||||
$(CORE_DIR)/drivers/midxunit.c \
|
||||
$(CORE_DIR)/machine/midwunit_machine.c $(CORE_DIR)/drivers/midwunit.c \
|
||||
@@ -481,7 +492,8 @@ SOURCES_C += \
|
||||
$(CORE_DIR)/vidhrdw/mitchell_vidhrdw.c $(CORE_DIR)/drivers/mitchell.c \
|
||||
$(CORE_DIR)/vidhrdw/cbasebal_vidhrdw.c $(CORE_DIR)/drivers/cbasebal.c \
|
||||
$(CORE_DIR)/vidhrdw/cps1_vidhrdw.c $(CORE_DIR)/drivers/cps1.c $(CORE_DIR)/drivers/cps2.c $(CORE_DIR)/machine/cps2crypt.c\
|
||||
$(CORE_DIR)/drivers/zn.c \
|
||||
$(CORE_DIR)/drivers/zn.c $(CORE_DIR)/sndhrdw/taitozoom.c $(CORE_DIR)/sound/zsg2.c $(CORE_DIR)/cpu/tms57002/tms57002.c \
|
||||
$(CORE_DIR)/drivers/cps3.c $(CORE_DIR)/sndhrdw/cps3_sndhrdw.c \
|
||||
$(CORE_DIR)/vidhrdw/tms34061_vidhrdw.c \
|
||||
$(CORE_DIR)/machine/capbowl_machine.c $(CORE_DIR)/vidhrdw/capbowl_vidhrdw.c $(CORE_DIR)/drivers/capbowl.c \
|
||||
$(CORE_DIR)/vidhrdw/itech8_vidhrdw.c $(CORE_DIR)/drivers/itech8.c \
|
||||
@@ -1042,6 +1054,9 @@ SOURCES_C += \
|
||||
$(CORE_DIR)/drivers/n8080.c \
|
||||
$(CORE_DIR)/drivers/mirax.c \
|
||||
$(CORE_DIR)/machine/model1_machine.c $(CORE_DIR)/vidhrdw/model1_vidhrdw.c $(CORE_DIR)/drivers/model1.c \
|
||||
$(CORE_DIR)/machine/model2_machine.c $(CORE_DIR)/vidhrdw/model2_vidhrdw.c $(CORE_DIR)/drivers/model2.c \
|
||||
$(CORE_DIR)/sndhrdw/segadsb.c $(CORE_DIR)/sound/mpeg_audio.c \
|
||||
$(CORE_DIR)/machine/sega315_5881.c $(CORE_DIR)/machine/sega315_5838.c \
|
||||
$(CORE_DIR)/drivers/calorie.c \
|
||||
$(CORE_DIR)/machine/mc8123.c \
|
||||
$(CORE_DIR)/machine/namcoio_machine.c \
|
||||
@@ -1092,6 +1107,14 @@ else
|
||||
CPUDEFS += -DHAS_ADSP2115=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring ADSP2181@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
CPUDEFS += -DHAS_ADSP2181=1
|
||||
HAS_ADSP2100 = 1
|
||||
else
|
||||
CPUDEFS += -DHAS_ADSP2181=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring Z80@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
CPUDEFS += -DHAS_Z80=1
|
||||
@@ -1432,6 +1455,15 @@ else
|
||||
CPUDEFS += -DHAS_I8X41=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring I8051@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/i8051
|
||||
CPUDEFS += -DHAS_I8051=1
|
||||
SOURCES_C += $(CORE_DIR)/cpu/i8051/i8051.c
|
||||
else
|
||||
CPUDEFS += -DHAS_I8051=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring M6800@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/m6800
|
||||
@@ -1825,6 +1857,42 @@ else
|
||||
CPUDEFS += -DHAS_TMS32025=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring MB86233@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/mb86233
|
||||
CPUDEFS += -DHAS_MB86233=1
|
||||
SOURCES_C += $(CORE_DIR)/cpu/mb86233/mb86233.c
|
||||
else
|
||||
CPUDEFS += -DHAS_MB86233=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring MB86235@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/mb86235
|
||||
CPUDEFS += -DHAS_MB86235=1
|
||||
SOURCES_C += $(CORE_DIR)/cpu/mb86235/mb86235.c
|
||||
else
|
||||
CPUDEFS += -DHAS_MB86235=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring ADSP21062@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/sharc
|
||||
CPUDEFS += -DHAS_ADSP21062=1
|
||||
SOURCES_C += $(CORE_DIR)/cpu/sharc/sharc.c
|
||||
else
|
||||
CPUDEFS += -DHAS_ADSP21062=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring I960@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/i960
|
||||
CPUDEFS += -DHAS_I960=1
|
||||
SOURCES_C += $(CORE_DIR)/cpu/i960/i960.c
|
||||
else
|
||||
CPUDEFS += -DHAS_I960=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring TMS32031@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/tms32031
|
||||
@@ -1862,6 +1930,33 @@ else
|
||||
CPUDEFS += -DHAS_PSXCPU=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring H83002@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/h83002
|
||||
CPUDEFS += -DHAS_H83002=1
|
||||
SOURCES_C += $(CORE_DIR)/cpu/h83002/h83002.c
|
||||
else
|
||||
CPUDEFS += -DHAS_H83002=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring MN10200@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/mn10200
|
||||
CPUDEFS += -DHAS_MN10200=1
|
||||
SOURCES_C += $(CORE_DIR)/cpu/mn10200/mn10200.c
|
||||
else
|
||||
CPUDEFS += -DHAS_MN10200=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring M37702@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/m37710
|
||||
CPUDEFS += -DHAS_M37702=1
|
||||
SOURCES_C += $(CORE_DIR)/cpu/m37710/m37710.c $(CORE_DIR)/cpu/m37710/m37710o0.c $(CORE_DIR)/cpu/m37710/m37710o1.c $(CORE_DIR)/cpu/m37710/m37710o2.c $(CORE_DIR)/cpu/m37710/m37710o3.c
|
||||
else
|
||||
CPUDEFS += -DHAS_M37702=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring ASAP@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/asap
|
||||
@@ -1911,6 +2006,15 @@ else
|
||||
CPUDEFS += -DHAS_ARM=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring ARM7@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/arm7
|
||||
CPUDEFS += -DHAS_ARM7=1
|
||||
SOURCES_C += $(CORE_DIR)/cpu/arm7/arm7.c
|
||||
else
|
||||
CPUDEFS += -DHAS_ARM7=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring JAGUAR@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/jaguar
|
||||
@@ -2507,6 +2611,14 @@ else
|
||||
SOUNDDEFS += -DHAS_C140=0
|
||||
endif
|
||||
|
||||
SOUND=$(strip $(findstring C352@,$(SOUNDS)))
|
||||
ifneq ($(SOUND),)
|
||||
SOUNDDEFS += -DHAS_C352=1
|
||||
SOURCES_C += $(CORE_DIR)/sound/c352.c
|
||||
else
|
||||
SOUNDDEFS += -DHAS_C352=0
|
||||
endif
|
||||
|
||||
SOUND=$(strip $(findstring QSOUND@,$(SOUNDS)))
|
||||
ifneq ($(SOUND),)
|
||||
SOUNDDEFS += -DHAS_QSOUND=1
|
||||
@@ -2660,9 +2772,19 @@ SOUNDDEFS += -DHAS_ICS2115=0
|
||||
endif
|
||||
|
||||
SOURCES_C += \
|
||||
$(CORE_DIR)/lib/mame-chd/chd.c \
|
||||
$(CORE_DIR)/lib/mame-chd/mame_sha1.c
|
||||
|
||||
# libchdr: reads the hard disk CHDs (every version, zlib/LZMA/Huffman/FLAC)
|
||||
SOURCES_C += \
|
||||
$(CORE_DIR)/lib/libchdr/src/libchdr_bitstream.c \
|
||||
$(CORE_DIR)/lib/libchdr/src/libchdr_cdrom.c \
|
||||
$(CORE_DIR)/lib/libchdr/src/libchdr_chd.c \
|
||||
$(CORE_DIR)/lib/libchdr/src/libchdr_flac.c \
|
||||
$(CORE_DIR)/lib/libchdr/src/libchdr_huffman.c \
|
||||
$(CORE_DIR)/lib/libchdr/deps/lzma/LzFind.c \
|
||||
$(CORE_DIR)/lib/libchdr/deps/lzma/LzmaDec.c \
|
||||
$(CORE_DIR)/lib/libchdr/deps/lzma/LzmaEnc.c
|
||||
|
||||
SOURCES_C += \
|
||||
$(CORE_DIR)/libretro-deps/libFLAC/bitreader.c \
|
||||
$(CORE_DIR)/libretro-deps/libFLAC/cpu.c \
|
||||
@@ -2689,6 +2811,9 @@ SOURCES_C += \
|
||||
$(CORE_DIR)/lib/zlib/unzip.c \
|
||||
$(CORE_DIR)/lib/zlib/zutil.c
|
||||
|
||||
# sljit: run-time code generator of the MIPS recompilers (empty where they are not supported)
|
||||
SOURCES_C += $(CORE_DIR)/lib/sljit/sljit_mame.c
|
||||
|
||||
ifeq ($(STATIC_LINKING),1)
|
||||
else
|
||||
SOURCES_C += \
|
||||
|
||||
+76
-1
@@ -624,6 +624,7 @@ endif
|
||||
|
||||
ifneq (,$(filter $(INCLUDE_DRV),drv_backfire core_none))
|
||||
CPUS+=ARM@
|
||||
CPUS+=ARM7@
|
||||
SOUNDS+=YMZ280B@
|
||||
SOURCES_C += \
|
||||
$(CORE_DIR)/machine/decocrpt.c \
|
||||
@@ -1072,6 +1073,14 @@ else
|
||||
CPUDEFS += -DHAS_ADSP2115=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring ADSP2181@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
CPUDEFS += -DHAS_ADSP2181=1
|
||||
HAS_ADSP2100 = 1
|
||||
else
|
||||
CPUDEFS += -DHAS_ADSP2181=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring Z80@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
CPUDEFS += -DHAS_Z80=1
|
||||
@@ -1412,6 +1421,15 @@ else
|
||||
CPUDEFS += -DHAS_I8X41=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring I8051@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/i8051
|
||||
CPUDEFS += -DHAS_I8051=1
|
||||
SOURCES_C += $(CORE_DIR)/cpu/i8051/i8051.c
|
||||
else
|
||||
CPUDEFS += -DHAS_I8051=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring M6800@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/m6800
|
||||
@@ -1842,6 +1860,33 @@ else
|
||||
CPUDEFS += -DHAS_PSXCPU=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring H83002@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/h83002
|
||||
CPUDEFS += -DHAS_H83002=1
|
||||
SOURCES_C += $(CORE_DIR)/cpu/h83002/h83002.c
|
||||
else
|
||||
CPUDEFS += -DHAS_H83002=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring MN10200@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/mn10200
|
||||
CPUDEFS += -DHAS_MN10200=1
|
||||
SOURCES_C += $(CORE_DIR)/cpu/mn10200/mn10200.c
|
||||
else
|
||||
CPUDEFS += -DHAS_MN10200=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring M37702@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/m37710
|
||||
CPUDEFS += -DHAS_M37702=1
|
||||
SOURCES_C += $(CORE_DIR)/cpu/m37710/m37710.c $(CORE_DIR)/cpu/m37710/m37710o0.c $(CORE_DIR)/cpu/m37710/m37710o1.c $(CORE_DIR)/cpu/m37710/m37710o2.c $(CORE_DIR)/cpu/m37710/m37710o3.c
|
||||
else
|
||||
CPUDEFS += -DHAS_M37702=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring ASAP@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/asap
|
||||
@@ -1891,6 +1936,15 @@ else
|
||||
CPUDEFS += -DHAS_ARM=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring ARM7@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/arm7
|
||||
CPUDEFS += -DHAS_ARM7=1
|
||||
SOURCES_C += $(CORE_DIR)/cpu/arm7/arm7.c
|
||||
else
|
||||
CPUDEFS += -DHAS_ARM7=0
|
||||
endif
|
||||
|
||||
CPU=$(strip $(findstring JAGUAR@,$(CPUS)))
|
||||
ifneq ($(CPU),)
|
||||
OBJDIRS += $(CORE_DIR)/cpu/jaguar
|
||||
@@ -2487,6 +2541,14 @@ else
|
||||
SOUNDDEFS += -DHAS_C140=0
|
||||
endif
|
||||
|
||||
SOUND=$(strip $(findstring C352@,$(SOUNDS)))
|
||||
ifneq ($(SOUND),)
|
||||
SOUNDDEFS += -DHAS_C352=1
|
||||
SOURCES_C += $(CORE_DIR)/sound/c352.c
|
||||
else
|
||||
SOUNDDEFS += -DHAS_C352=0
|
||||
endif
|
||||
|
||||
SOUND=$(strip $(findstring QSOUND@,$(SOUNDS)))
|
||||
ifneq ($(SOUND),)
|
||||
SOUNDDEFS += -DHAS_QSOUND=1
|
||||
@@ -2640,9 +2702,19 @@ SOUNDDEFS += -DHAS_ICS2115=0
|
||||
endif
|
||||
|
||||
SOURCES_C += \
|
||||
$(CORE_DIR)/lib/mame-chd/chd.c \
|
||||
$(CORE_DIR)/lib/mame-chd/mame_sha1.c
|
||||
|
||||
# libchdr: reads the hard disk CHDs (every version, zlib/LZMA/Huffman/FLAC)
|
||||
SOURCES_C += \
|
||||
$(CORE_DIR)/lib/libchdr/src/libchdr_bitstream.c \
|
||||
$(CORE_DIR)/lib/libchdr/src/libchdr_cdrom.c \
|
||||
$(CORE_DIR)/lib/libchdr/src/libchdr_chd.c \
|
||||
$(CORE_DIR)/lib/libchdr/src/libchdr_flac.c \
|
||||
$(CORE_DIR)/lib/libchdr/src/libchdr_huffman.c \
|
||||
$(CORE_DIR)/lib/libchdr/deps/lzma/LzFind.c \
|
||||
$(CORE_DIR)/lib/libchdr/deps/lzma/LzmaDec.c \
|
||||
$(CORE_DIR)/lib/libchdr/deps/lzma/LzmaEnc.c
|
||||
|
||||
SOURCES_C += \
|
||||
$(CORE_DIR)/libretro-deps/libFLAC/bitreader.c \
|
||||
$(CORE_DIR)/libretro-deps/libFLAC/cpu.c \
|
||||
@@ -2692,6 +2764,9 @@ SOURCES_C += \
|
||||
$(CORE_DIR)/lib/zlib/uncompr.c \
|
||||
$(CORE_DIR)/lib/zlib/unzip.c \
|
||||
$(CORE_DIR)/lib/zlib/zutil.c
|
||||
|
||||
# sljit: run-time code generator of the MIPS recompilers (empty where they are not supported)
|
||||
SOURCES_C += $(CORE_DIR)/lib/sljit/sljit_mame.c
|
||||
endif
|
||||
|
||||
ifeq ($(ZLIB_UNCOMPRESS), 1)
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
# Capcom CPS-3: how the driver works and where it differs from the hardware
|
||||
|
||||
Sets: `redearth`, `warzard`, `sfiii`, `sfiii2`, `jojo`, `sfiii3`, `jojoba`
|
||||
and their clones (53 in all, MAME's list without the multi-game bootlegs),
|
||||
plus `sfiii4n`, the "4rd Arrange Edition 2013" hack of 3rd Strike that
|
||||
FBNeo has and MAME does not.
|
||||
|
||||
Files: `src/drivers/cps3.c` (memory map, flash SIMMs, video, DMA, sets),
|
||||
`src/sndhrdw/cps3_sndhrdw.c` (the 16 voice sample chip). A C89 port of
|
||||
current MAME's `cps3.cpp` and `cps3_a.cpp`.
|
||||
|
||||
## The board
|
||||
|
||||
- A custom Hitachi SH-2 at 25 MHz that decrypts what it reads from the BIOS,
|
||||
the program SIMMs and its cache RAM, with a per-game key stored in the
|
||||
cartridge.
|
||||
- The game in flash SIMMs: two SIMMs of 4 Fujitsu 29F016A chips (2 MB each)
|
||||
for the program, up to four SIMMs of 8 chips for graphics and samples.
|
||||
- 2D video: sprites with zoom, tilemaps drawn as sprites, a text layer,
|
||||
palette DMA with fades, character DMA with RLE decompression.
|
||||
- 16 voices of 8-bit samples read from the graphics SIMMs.
|
||||
- A SCSI CD-ROM drive: the BIOS writes the game from the CD into the SIMMs.
|
||||
|
||||
## No CD drive
|
||||
|
||||
The CD drive is not emulated. All sets run from SIMMs already written:
|
||||
|
||||
- The "NO CD" sets come with their SIMMs and a BIOS that does not look for a
|
||||
drive, as in MAME.
|
||||
- The CD sets (Europe, USA, Japan, Asia, Hispanic versions) get the SIMM data
|
||||
of their version, the same as the NO CD set of that date (the SIMM
|
||||
contents do not depend on the region, the BIOS does). As in FBNeo, which
|
||||
plays them the same way. MAME needs the CD image instead.
|
||||
- The CD BIOSes would stop on the missing drive. The BIOS has a flag the
|
||||
no-CD BIOSes have set (byte 0x1fecc, bit 0); the driver sets it, and the
|
||||
game runs from the SIMMs.
|
||||
- The Red Earth / Warzard CD BIOSes have no such flag: the driver starts the
|
||||
game from the SIMMs as the BIOS would (PC and SP from the program's vector
|
||||
table, VBR on it), as FBNeo does.
|
||||
|
||||
The flash chips answer the Fujitsu command set (ID, program, erase), but
|
||||
what is written to them is not saved: no set writes them while playing.
|
||||
|
||||
## Region
|
||||
|
||||
The region is not a switch on the board: it is a byte in the cart's flash
|
||||
(the low nibble of the BIOS byte 0x1fecb, 0x1fedb on Red Earth / Warzard),
|
||||
which the BIOS and the games read. A fake DIP switch, "Region", patches it at
|
||||
reset, as in FBNeo: Japan, Asia, Europe, USA, Hispanic, Brazil, Oceania or
|
||||
the second Asia code, or "As BIOS" to keep the dumped value. The default is
|
||||
Europe for every set, whatever region its BIOS has; 2nd Impact, which had no
|
||||
European release, defaults to USA. It changes the boot screen colour, the
|
||||
warnings, the coin settings, the language and the title (Warzard in Japan,
|
||||
Red Earth elsewhere). Change it, then reset.
|
||||
|
||||
The game options (coins, difficulty, monitor flip, language...) are in the
|
||||
games' own test menu (F2) and kept in the cart's EEPROM, saved as NVRAM.
|
||||
|
||||
## Encryption
|
||||
|
||||
The BIOS is decrypted at load. The program SIMMs are kept as dumped and also
|
||||
decrypted into a copy the CPU fetches opcodes from; data reads come out
|
||||
decrypted, as the custom CPU reads them. Two hooks in the SH-2 core (both
|
||||
optional, unused by the other SH-2 drivers) do this:
|
||||
|
||||
- `opcode_read`: the opcode fetch, from the BIOS, the decrypted program copy
|
||||
or the decrypted copy of the cache RAM.
|
||||
- `dma_read_hook`: the SH-2 DMA bypasses the decryption on the real board;
|
||||
the hook re-encrypts what the handlers decrypted.
|
||||
|
||||
`sfiii2` runs off a "dead" cartridge: the key is gone and its program is
|
||||
stored with code encrypted and data not, as in MAME.
|
||||
|
||||
## Video
|
||||
|
||||
The renderer is MAME's: sprites and tilemaps go to a render buffer of
|
||||
palette indexes (with the shadow/highlight blend bits), which is copied to the
|
||||
screen through the full screen zoom; the text layer is drawn on top. Tiles
|
||||
are read straight from the character RAM (no gfx elements to keep dirty).
|
||||
Colours are 15-bit with no extension of the low bits, as on the board (its
|
||||
video DAC has them grounded). The screen width follows the CRTC registers, as
|
||||
in MAME (384 pixels in the games checked).
|
||||
|
||||
## Idle loop
|
||||
|
||||
Each game waits for the vblank interrupt by reading a word of the main RAM
|
||||
in a loop. When the loop reads it, the CPU skips to the next event (the
|
||||
addresses are FBNeo's, one per game and version). Speed goes from about
|
||||
4.5x to 12-16x real time on an x86 core. The games run the same; only the
|
||||
attract mode can pick other fighters, since the games draw random numbers
|
||||
from the time spent in that loop.
|
||||
|
||||
## Sound
|
||||
|
||||
MAME's sound device: 16 voices, signed 8-bit samples, the board clock / 3 /
|
||||
384 (37.3 kHz), loop and end addresses, a volume per side. Levels checked
|
||||
against MAME's WAV output of the same attract mode.
|
||||
|
||||
## ROM loading of merged sets
|
||||
|
||||
Merged sets keep the files of the clones in subfolders of the parent's zip,
|
||||
with the same names (`sfiii3n/sfiii3-simm1.0`, `sfiii3nr1/sfiii3-simm1.0`).
|
||||
The ROM loader of this core matched by name only and took the first one.
|
||||
It now looks for the expected CRC first, then for the name, so merged,
|
||||
split and non-merged sets all load.
|
||||
|
||||
## Checked
|
||||
|
||||
- Attract mode of `sfiii3n`, `jojoba`, `sfiii2n`, `jojon`, `sfiiin`,
|
||||
`redearthn` against MAME 0.264 at the same frames: the same screens.
|
||||
- A game of 3rd Strike (coin, character select, fight).
|
||||
- CD sets: the regional warning screens, then the game (`sfiii3`, `sfiii3u`,
|
||||
`sfiiih`, `sfiii2`, `jojor2`, `jojobaner2`, `warzard`).
|
||||
- Save states: loaded in a new process, the game goes on frame for frame.
|
||||
- Big-endian: the PowerPC build renders as x86.
|
||||
@@ -0,0 +1,203 @@
|
||||
# Sega Model 1: how the driver works and where it differs from the hardware
|
||||
|
||||
Sets: `vr`, `vformula`, `vf`, `swa`, `swaj`, `wingwar`, `wingwaru`,
|
||||
`wingwarj`, `wingwar360`, `netmerc`.
|
||||
|
||||
Files: `src/drivers/model1.c` (boards, maps, ROMs), `src/machine/model1_machine.c`
|
||||
(the TGP), `src/vidhrdw/model1_vidhrdw.c` (the renderer, ported from current
|
||||
MAME), `src/sndhrdw/segadsb.c` (the Digital Sound Board of Star Wars Arcade).
|
||||
|
||||
## The TGP (geometry coprocessor)
|
||||
|
||||
The TGP is a Fujitsu MB86233 DSP running a program from a 315-xxxx ROM:
|
||||
315-5573 (Virtua Racing, Virtua Formula), 315-5724 (Virtua Fighter), 315-5711
|
||||
(Star Wars Arcade, Wing War, NetMerc). The V60 sends it commands (a function
|
||||
number and its arguments) through a FIFO and reads the results back.
|
||||
|
||||
The driver runs the TGP functions in C (high level emulation, HLE), started
|
||||
from MAME 0.215, the last MAME with an HLE TGP. In MAME 0.215 Virtua Racing had
|
||||
no HLE at all and Star Wars Arcade and Wing War did not work.
|
||||
|
||||
### Checked against the real program
|
||||
|
||||
The core also contains the MB86233 (from the Model 2 work), so the real TGP
|
||||
program can run next to the HLE. A development build (`-DMODEL1_TGP_DEV`)
|
||||
reads `MODEL1_TGP` from the environment:
|
||||
|
||||
- `lle`: the game runs on the real TGP program only.
|
||||
- `oracle`: the game runs on the real TGP program, the HLE gets the same
|
||||
input, and every call is compared: function, arguments, the results of
|
||||
both. The pairing follows the input stream (a call ends when the DSP takes
|
||||
the next function word), so a function giving a wrong number of results
|
||||
does not shift the others. The TGP RAM both sides keep is compared every
|
||||
frame. Every 600 frames it prints, for each function, the calls that were
|
||||
exact, near (rounding), wrong, or gave a wrong number of results.
|
||||
|
||||
With this, every function the games call was rewritten from the DSP program
|
||||
until the results match bit for bit: same table lookups (sine, 1/x, 1/sqrt,
|
||||
atan come from the TGP's table ROM through its I/O ports, with one
|
||||
multiply-subtract step), same order of the sums, same comparisons (the ALU's
|
||||
`-0` is neither negative nor positive). Checked on attract and play of
|
||||
`vr` (three tracks), `vformula`, `vf`, `swa`, `wingwar`, `wingwar360` and
|
||||
`netmerc`: no call differs and the TGP RAM stays identical.
|
||||
|
||||
Virtua Fighter's program (315-5724) is marked as a bad dump in MAME, but it
|
||||
runs the game on the MB86233 core, so it is checked the same way. About half
|
||||
of its functions differ from 315-5573 (matrix stack and saved matrices at
|
||||
other addresses, the camera, collision bitmaps, ground box test, list walks
|
||||
in the copro RAM), so it has its own table. MAME 0.215 used the Virtua Racing
|
||||
table for it, with guessed camera functions (one returned random numbers),
|
||||
which put the camera far from the fighters. For Virtua Fighter the oracle
|
||||
also compares the TGP's internal RAM after every call. Over 9000 frames of
|
||||
attract and fights, 55 functions and 3.8 million calls give the same results
|
||||
and the same RAM.
|
||||
|
||||
The table lookups, the copro RAM (0x2000 words; with address bit 0x40000 set
|
||||
the address steps by 4) and the list functions follow current MAME.
|
||||
|
||||
### Program bugs reproduced
|
||||
|
||||
The HLE reproduces what the real programs do, bugs included, because the
|
||||
games run with them on the real boards:
|
||||
|
||||
- 315-5711 `roty` starts its first sum from the DSP's `d` register, which
|
||||
still holds the dispatch address (a denormal): the first matrix element
|
||||
gets `0x6c` added to it.
|
||||
- 315-5711 `normalize` never loads y; it uses whatever the scratch word at
|
||||
`$71` holds from an earlier function (tracked by the HLE).
|
||||
- 315-5711 `f47` starts its sum of squares from the z difference.
|
||||
- 315-5711 `fsqrt` skips the mantissa step and does not return a square root.
|
||||
- The matrix stack keeps 7 levels; past them the depth only counts (315-5711
|
||||
pushes again past 8, while its pops past 7 only count). The matrix slots
|
||||
and the 315-5711 accumulator stack sit in the same TGP RAM, as on the
|
||||
board.
|
||||
- 315-5711 `f52` (0x34, matrix inverse; Star Wars Arcade calls it) works
|
||||
by cofactors, never reads the first element, ORs two elements where a
|
||||
subtract is expected, and adds in the second element the scratch word
|
||||
`$11` an earlier function left (push, multiply and read leave a matrix
|
||||
element or argument there; tracked by the HLE).
|
||||
- 315-5711 `f56` (0x38, segment against a polygon list) stops at the first
|
||||
polygon hit, not the nearest one.
|
||||
- The 315-5711 games use the current matrix before setting it: the HLE starts
|
||||
from what the TGP RAM holds at power on (zeros in the emulated TGP).
|
||||
|
||||
### What is not emulated
|
||||
|
||||
- Table entries a program leaves empty (it returns at once) take no
|
||||
arguments and give no results; 315-5724 functions no game was seen calling
|
||||
are not emulated, except the simple ones (normalize, divide, set the
|
||||
translation).
|
||||
- 315-5711 functions no game was seen calling: self tests 0x04, 0x3d, 0x3e
|
||||
(results 0), 0x42 (matrix stack pop and multiply, with bugs overwriting the
|
||||
stack), 0x21 (the program jumps into the middle of another function). They
|
||||
take and give the right number of words so the command stream stays in step.
|
||||
|
||||
### ROMs
|
||||
|
||||
The TGP program ROM stays in the sets as in current MAME. For Star Wars
|
||||
Arcade, Wing War and NetMerc the HLE follows 315-5711 with CRC 6a21f304, as
|
||||
current MAME. An older dump (CRC c5ddb8fc) differs in two words: the entry
|
||||
of `f52` (which then reads the wrong RAM and gives NaNs) and the end test
|
||||
of `f56`. It loads with a checksum warning; the HLE does not use the ROM.
|
||||
|
||||
The V60 reaches the TGP in its I/O space as well as in memory, with the
|
||||
same mirrors as current MAME: Wing War sends its boot command (8, clear the
|
||||
matrix stack) with an OUT to a mirror of the FIFO, and the real program
|
||||
waits for it before taking any other command.
|
||||
|
||||
## I/O board
|
||||
|
||||
The Model 1 I/O board (model1io, model1io2: a Z80 with its own BIOS) is
|
||||
simulated: inputs, DIP switches, analog channels and the backup are put where
|
||||
the games read them in the 2 KB dual port RAM:
|
||||
|
||||
00-07 analog channels
|
||||
08-0a IN0 - IN2 (active low)
|
||||
0b-0d DSW1 - DSW3 (active low, all off)
|
||||
0e board switches
|
||||
0f outputs (lamps, coin counters)
|
||||
11 drive board / motion base output
|
||||
20 command (2 store the backup 0x100-0x1ff, 3 load it), 21 status
|
||||
|
||||
The DIP switches must read as off: 0 turned on the debug displays of Virtua
|
||||
Racing and NetMerc. The backup is saved in the NVRAM file.
|
||||
|
||||
## Sound
|
||||
|
||||
Model 1 sound board (68000, two MultiPCM, YM3438) behind an i8251 UART at
|
||||
31250 baud, as current MAME. Star Wars Arcade also has the Digital Sound
|
||||
Board (Z80 + MPEG audio), which listens to the sound board's UART.
|
||||
|
||||
The simulated I/O board answers at once, so the V60 sends its first sound
|
||||
commands before the 68000 has finished its init. The real UART holds one byte
|
||||
and would lose the others; Virtua Fighter then stayed silent. The bytes for
|
||||
the 68000 are kept in a queue.
|
||||
|
||||
Virtua Racing and Virtua Fighter play no sound in attract mode with their
|
||||
default settings, as on the board.
|
||||
|
||||
## Save states
|
||||
|
||||
Besides the RAMs and registers, a save state keeps what MAME 0.78 does not
|
||||
save by itself and what a game sets only once: the TGP FIFOs (a state can
|
||||
fall between the words of a command, or before the V60 read the results),
|
||||
the data ROM bank, the time left of the interval and UART timers, and the
|
||||
renderer's view (viewport, light, light parameters: Virtua Fighter sends
|
||||
them only when a stage starts, and without them a loaded state drew the
|
||||
fighters black). Checked by loading in a new process: Virtua Fighter and
|
||||
Virtua Racing's attract mode go on frame for frame as in a straight run
|
||||
(analog controls: see Open questions).
|
||||
|
||||
## Other boards
|
||||
|
||||
- Link board (Virtua Racing, Virtua Formula, Wing War): not emulated; the
|
||||
games see it with its CPU in reset and run stand-alone.
|
||||
- R360 motion base (`wingwar360`): the game states it sends are answered as
|
||||
the real base does, so a game starts. No motion.
|
||||
- Polhemus tracker (`netmerc`): the board (a 386 with its own program) that
|
||||
tracks the visor is not emulated. As in current MAME, the visor pose the
|
||||
game reads at dual port RAM 0x80-0x8b (x, y, z, then three angles in
|
||||
radians * 8192) is set once at reset, looking ahead. The gun on its mount
|
||||
is not tracked: it uses the stick (analog channels 0 and 2), and moving
|
||||
goes where the gun points.
|
||||
- NetMerc gun mount calibration: the ends of both axes are kept in the
|
||||
backup RAM (0x38 / 0x3c horizontal, 0x40 / 0x44 vertical). At boot the
|
||||
game sets its factory calibration (0x46-0xc4, 0x21-0x69) only when one of
|
||||
them is zero, so a new NetMerc backup RAM is 0-filled (the other games
|
||||
get 1s, which Virtua Fighter needs): with 1s it kept them, divided by
|
||||
zero, spun the gun, failed its checksum and stayed on one attract
|
||||
screen. The stick covers the same range as the factory calibration.
|
||||
- NetMerc sound: `mpr-18134` (the first sample ROM of the first MultiPCM)
|
||||
is a bad dump, all 0xff, in the only set known (MAME has the same one).
|
||||
That MultiPCM has no sample table, so the music it plays is silent; the
|
||||
effects, on the second MultiPCM, play.
|
||||
- NetMerc defaults (test menu, GAME ASSIGNMENTS): country Japan, attract
|
||||
sound off, so attract mode is silent and starts with the Japan warning.
|
||||
|
||||
## Video
|
||||
|
||||
`model1_vidhrdw.c` is a C port of current MAME's `model1_v.cpp`. Two choices
|
||||
keep the output the same on every CPU: float to int conversions follow x86
|
||||
(out of range gives `INT_MIN`, other CPUs saturate), and the files of the TGP
|
||||
and the renderer are compiled without fused multiply-add (GCC and clang fuse
|
||||
`a*b+c` on PowerPC and ARM64). Big-endian PowerPC renders pixel for pixel as
|
||||
x86.
|
||||
|
||||
Polygons with the moire flag (Virtua Fighter's shadows) are drawn as a
|
||||
checkerboard, every other pixel, as in current MAME; a 720p capture of a
|
||||
real Virtua Fighter board shows the same pattern.
|
||||
|
||||
Compared with captures of real boards: Virtua Fighter (the stages up to
|
||||
Akira's: backgrounds, floors, colours, lighting, camera, shadows), Virtua
|
||||
Racing (Bay Bridge: start grid, bridge, HUD), Star Wars Arcade (attract:
|
||||
Star Destroyer, cockpit battle, hangar), Wing War and NetMerc.
|
||||
|
||||
## Open questions
|
||||
|
||||
- Virtua Fighter: the eight stages up to Akira's were compared with a
|
||||
capture of a real board (backgrounds, floors, colours, camera); Dural's
|
||||
stage and the bonus stage were not.
|
||||
- After loading a state during play, an analog control (Virtua Racing's
|
||||
accelerator) starts again from its rest position: the core's input
|
||||
system does not save it. Digital inputs and attract mode go on as in a
|
||||
straight run.
|
||||
@@ -0,0 +1,501 @@
|
||||
# Sega Model 2: choices that differ from the hardware
|
||||
|
||||
The Model 2 driver (`src/drivers/model2.c`) emulates the boards as the games
|
||||
see them. In a few places the hardware is not available or not emulated, and
|
||||
the driver does something simpler. Each of those choices is listed here, with
|
||||
the reason and its consequences.
|
||||
|
||||
## Communication board (network link)
|
||||
|
||||
The communication board links cabinets for multi-player games over a network.
|
||||
It is not emulated: there is no network.
|
||||
|
||||
For most games the board reads as **absent** (the CN register reads 0xff).
|
||||
The games that look for it then run as single machines.
|
||||
|
||||
### Virtual-On: board present, link always stand-alone
|
||||
|
||||
Sets: `von`, `vonu`, `vonj`.
|
||||
|
||||
**Why.** Virtual-On does not start a game without the board, even on a
|
||||
machine set to stand-alone. At boot (addresses from `von`):
|
||||
|
||||
1. `0x185d0` sets the defaults: role stand-alone, link mode 0.
|
||||
2. `0x18920` reads the link ID from the backup RAM (byte `0x1d00028`:
|
||||
0 slave, 1 master, other values stand-alone; the factory setting is 2).
|
||||
3. `0xc6480` initialises the link. It reads the board's CN register first.
|
||||
Without a board it prints "THERE IS NO COMMUNICATION BOARD!", sets the
|
||||
link mode to 0xff and returns, without looking at the link ID.
|
||||
|
||||
With link mode 0xff the game never leaves the attract mode: after a coin the
|
||||
screen stays black and silent (game mode 4, sub-state 0 waits on a status
|
||||
word that stays 0xff).
|
||||
|
||||
With a board present, step 3 enables it (CN=1) and waits for the board's
|
||||
firmware to report ready (ZFG=1, read as bit 7 of the FG register going to
|
||||
0). With the link ID on stand-alone it then returns at once and the game never
|
||||
uses the link. A board that is present but never ready stops the game at boot;
|
||||
this is also what the current MAME device does without its network
|
||||
simulation, and MAME lists these sets as not working.
|
||||
|
||||
**What the driver does.**
|
||||
|
||||
- The board reads as present and reports ready as soon as the game enables
|
||||
it (`m2comm_ctrl_w`, CN=1 sets ZFG=1). Its shared RAM is plain RAM.
|
||||
- The link ID always reads as stand-alone (`von_linkid_r`, installed over the
|
||||
backup RAM dword at `0x1d00028`). Writes still go to the backup RAM.
|
||||
|
||||
**Consequences.**
|
||||
|
||||
- Master and slave are not available. The test menu always shows
|
||||
stand-alone, whatever is chosen there.
|
||||
- The game computes the backup RAM checksum by reading through the same
|
||||
handler, so the checksum stays valid and the other settings are kept.
|
||||
- An NVRAM from another emulator with the link set to master or slave fails
|
||||
the checksum once: the game then restores its factory settings.
|
||||
|
||||
**How it was checked.** A valid NVRAM with the link ID on slave (checksum
|
||||
recomputed with the game's own CRC, table at `0x2f20` in `von`) stops at boot
|
||||
on "THIS IS SLAVE SITE" without the override. With the override, the same
|
||||
NVRAM boots, plays a game, and keeps its other settings.
|
||||
|
||||
**Not added: `vonr` (Virtual-On Relay).** That version always sets its role
|
||||
to relay (`0xf1cf0` writes 0) before the link is initialised, and then waits
|
||||
for the network. It cannot run as a single machine.
|
||||
|
||||
### Daytona USA: factory link ID forced to single at start-up
|
||||
|
||||
Sets: `daytona`, `daytonase`, `daytona93`, `daytonas`.
|
||||
|
||||
**Why.** Daytona USA runs without the board, but its factory settings in the
|
||||
program ROM set the link ID to master. On a new NVRAM (or after a factory
|
||||
reset) the game uses those settings and keeps looking for the other cabinets
|
||||
("NETWORK CHECKING"), so a game never starts.
|
||||
|
||||
**What the driver does.** When the game is loaded, `DRIVER_INIT( daytona )`
|
||||
finds the factory settings table in the program ROM (it starts with
|
||||
`SEGA@\x82`) and changes the link ID at offset 0x0b from 1 (master) to
|
||||
0 (single). The board reads as absent.
|
||||
|
||||
| Set | Table | Factory link ID | Patched |
|
||||
|---|---|---|---|
|
||||
| `daytona` | `0x39d60` | 1 (master) | yes |
|
||||
| `daytonase` | `0x3ab20` | 1 (master) | yes |
|
||||
| `daytonas` | `0x3c570` | 1 (master) | yes |
|
||||
| `daytona93` | `0x3c150` | 0 (single) | no, already single |
|
||||
|
||||
**Consequences.**
|
||||
|
||||
- Only the factory value changes. A link ID already saved in the NVRAM is
|
||||
kept, and the setting can still be changed in the test menu. Set to master
|
||||
or slave, the game waits for the network as on the real hardware; set it
|
||||
back to single to play.
|
||||
- Restoring the factory settings from the test menu gives single, not
|
||||
master.
|
||||
|
||||
### Motor Raid
|
||||
|
||||
Sets: `motoraid`.
|
||||
|
||||
The game has link code ("Network Check"), but with the board absent it
|
||||
starts and plays with its factory settings. Nothing is changed.
|
||||
|
||||
## Model 1 I/O board (original Model 2)
|
||||
|
||||
Sets: `daytona` and clones, `vcop`, `vcopa`.
|
||||
|
||||
The original Model 2 reads its inputs through a Model 1 I/O board: a Z80
|
||||
with its own BIOS, behind a dual-port RAM at `0x1c00000`.
|
||||
|
||||
- With the BIOS (`model1io.zip` for Daytona USA, `model1io2.zip` for Virtua
|
||||
Cop), the board runs its own firmware on an emulated Z80.
|
||||
- Without it, the board's firmware is simulated: the driver writes the
|
||||
inputs, the analog channels and the light guns where the games read them,
|
||||
and handles the backup commands. Both BIOS files are optional ROMs.
|
||||
|
||||
## INDY 500 and Over Rev (Model 2B, `indy500` machine)
|
||||
|
||||
Sets: `indy500`, `indy500d`, `indy500to`, `overrevb`, `overrevba`.
|
||||
|
||||
- **Drive board (force feedback).** The games write their commands to it
|
||||
through port E of the 315-5649 and never wait for an answer. It is not
|
||||
emulated: the writes are ignored, as in MAME when no drive board program
|
||||
is loaded.
|
||||
- **Communication board program.** The Over Rev sets list the communication
|
||||
board program (`epr-18643.7`) as in MAME. Its CPU is not run, so the ROM
|
||||
is optional: the sets load with or without it.
|
||||
- **Over Rev parent.** As in MAME, the parent `overrev` is the Model 2C
|
||||
version (see the Model 2C sections), so `overrevb` and `overrevba` load
|
||||
from `overrev.zip`. The I/O board BIOS entries (`model1io`, `model1io2`),
|
||||
like the other BIOS sets of the core, are not in the game list: loading
|
||||
their zip reports that there is no such game instead of starting a
|
||||
machine without a program.
|
||||
- **Inverted pedals.** Over Rev reads its pedals inverted (0xff released), as
|
||||
`PORT_REVERSE` in MAME. The driver inverts those channels itself.
|
||||
|
||||
Super GT 24h (`sgt24h`) runs on the same machine. Its pedals are read
|
||||
inverted too, and it uses the same driver init as Over Rev.
|
||||
|
||||
## Sound link (MIDI input of the SCSP)
|
||||
|
||||
On Model 2A and later the i960 sends its sound commands through a UART to the
|
||||
MIDI input of the SCSP. The driver sends a byte only when the SCSP input
|
||||
queue has room, so no command is lost; while the queue is full the UART
|
||||
reports itself busy and the game waits.
|
||||
|
||||
The SCSP input queue holds 32 bytes, as in current MAME (the original MAME
|
||||
0.78 code had 8). With 8 bytes Super GT 24h hung at the end of its boot: the
|
||||
sound program does not read the queue for a while, and the game sends sound
|
||||
commands from its vertical blank interrupt, so it waited there for several
|
||||
frames. Its frame timer (same interrupt priority) expired meanwhile; the
|
||||
i960 records such an interrupt in its interrupt table, which this game keeps
|
||||
in ROM, so the interrupt was lost and the main loop waited for the timer
|
||||
forever (black screen after "STAND ALONE"). With 32 bytes the commands fit
|
||||
and the game plays.
|
||||
|
||||
## Rail Chase 2: mirrored sample ROMs
|
||||
|
||||
Sets: `rchase2`.
|
||||
|
||||
The sound board takes either four 16 Mbit sample ROMs (IC32, IC33, IC34,
|
||||
IC35) or two 32 Mbit ones (IC32, IC34). Rail Chase 2 has two 16 Mbit ROMs in
|
||||
the 32 Mbit positions IC32 and IC34. A 16 Mbit ROM there ignores the top
|
||||
address line, so it shows up twice: the region at 0x200000 mirrors IC32 and
|
||||
the one at 0x600000 mirrors IC34.
|
||||
|
||||
The sound program streams some effects through the 68000 into ring buffers
|
||||
in sound RAM, reading them from those mirrors (the title screen animation
|
||||
reads its stream from 0xa1e97c, inside the mirror of IC32). MAME loads the
|
||||
ROMs at 0x000000 and 0x400000 and leaves the mirrors empty, so those effects
|
||||
play silence: the title animation is silent and some in-game effects are
|
||||
missing, as reported for MAME (mametesters 09393).
|
||||
|
||||
The ROM definition loads each ROM a second time into its mirror (`ROM_RELOAD`), as the same fix proposed to MAME.
|
||||
|
||||
**How it was checked.** Current MAME (built from source, October 2026), with
|
||||
no input, plays nothing during the title animation (22-30 s, 56-62 s and
|
||||
90-96 s of the attract mode), as this core did before the change. With the
|
||||
same mirroring added to MAME's `init_rchase2`, MAME plays the title
|
||||
animation sound at the same points as this core. The billboard ROM
|
||||
(`segabill`), not dumped here, was an empty placeholder in that MAME test; it
|
||||
drives the score display only. With it the title
|
||||
animation has its sound and the in-game sound is about a third louder (the
|
||||
effects that were missing). The video is unchanged. The other Model 2 sets
|
||||
fill every ROM position they use, or (`dynabb`) use the four-ROM layout, where
|
||||
an empty socket is not a mirror.
|
||||
|
||||
## Sound: the SCSP effect DSP
|
||||
|
||||
Sets: every SCSP game that loads a DSP program (Dead or Alive among them).
|
||||
|
||||
The SCSP has a small DSP for effects (reverb, echo). The slots send their
|
||||
output to it (ISEL, IMXL), it runs its microprogram once per sample with its
|
||||
delay lines in the sound RAM (RBP, RBL), and its 16 outputs are mixed with
|
||||
the EFSDL and EFPAN of slots 0-15. The SCSP of this core did not emulate it,
|
||||
so those effects were missing, and the sounds a game sends only to the DSP
|
||||
were silent. The DSP is now the one of current MAME (`src/sound/scspdsp.c`),
|
||||
compared with MAME's on the Dead or Alive program and on random programs:
|
||||
same outputs, registers and delay RAM, sample by sample.
|
||||
|
||||
**Dead or Alive and the MADRS registers.** The DSP reads its delay line
|
||||
addresses from the MADRS registers (`0x780-0x7bf`). MAME also writes the
|
||||
range `0x7c0-0x7ff` to MADRS, as a mirror. Dead or Alive loads MADRS and then
|
||||
clears `0x7c0-0x7ff`, so in MAME every delay line address becomes 0: the
|
||||
reverb feeds back into one word, its output drifts to a DC level and
|
||||
saturates, and the sound breaks up and then goes silent (listed in MAME's
|
||||
known issues for `doa`). The mirror is not from the hardware: it replaced an
|
||||
out-of-bounds write in 2014, and Mednafen (checked on Saturn hardware) maps
|
||||
MADRS at `0x780-0x7bf` only. Here `0x7c0-0x7ff` is ignored and reads as 0.
|
||||
|
||||
**Master volume.** The SCSP master volume (MVOL) now scales the output once
|
||||
the game has written it, as in MAME. Dead or Alive keeps it at 0 for the
|
||||
first seconds while its DSP starts on an uninitialised delay RAM; without
|
||||
MVOL that start was audible as a burst of noise. The games that use 15 (the
|
||||
maximum) sound exactly as before.
|
||||
|
||||
**How it was checked.** MAME with the mirror removed plays the Dead or Alive
|
||||
attract mode for over 11 minutes without the DC drift (it saturated within
|
||||
the first minute before). In this core the games that do not start the DSP
|
||||
produce exactly the same audio as before.
|
||||
|
||||
## Video: tile layers and polygons
|
||||
|
||||
The tile layers (System 24 tilemaps A and B) are mixed among themselves
|
||||
first, A over B whatever their priority bits; the priority bit of the
|
||||
pixel that wins then puts it behind or in front of the polygons. MAME draws
|
||||
each priority on its own (the low tiles of A and B, the polygons, the high
|
||||
tiles of A and B), so a high tile of B covers a low tile of A: on the
|
||||
Virtua Cop 2 stage select the city map (tilemap B, priority set) hid
|
||||
"SHOOT TO SELECT" (tilemap A), as listed in MAME's known issues for
|
||||
`vcop2`. The other Model 2 games checked look the same as before.
|
||||
|
||||
## Video: black polygon pixels
|
||||
|
||||
The polygons are drawn into their own buffer, then laid over the tile
|
||||
layers. MAME's buffer holds `rgb_t` pixels, whose alpha byte makes a drawn
|
||||
black pixel (0xff000000) different from an empty one (0). This core stored
|
||||
plain RGB and took every black pixel as empty, so wherever a polygon was
|
||||
pure black the layer behind showed through: blue car shadows and missing
|
||||
dust in Sega Rally, blue tyres and shadows in INDY 500 and Super GT, the
|
||||
sky behind black clothes in Dead or Alive, the attract backgrounds of Motor
|
||||
Raid. Drawn pixels now carry the same opaque marker in the top byte. All the
|
||||
Model 2 games were compared before and after; the changed pixels are the
|
||||
black ones, and they now match MAME.
|
||||
|
||||
## Sega Rally Championship (Model 2A)
|
||||
|
||||
Sets: `srallyc`, `srallycb`, `srallycc`, `srallycdx`, `srallycdxa`.
|
||||
|
||||
- **Gear lever.** The H-pattern lever is read on port C bits 4-6. As for
|
||||
Daytona USA it is built from two buttons, shift up and shift down.
|
||||
- **Drive board.** The force feedback board is written to through port E and
|
||||
never answers; it is not emulated. Its program (`epr-17891`) and the
|
||||
communication board program (`epr-16726`) are not listed.
|
||||
- **Start grid.** MAME lists the initial placement of a few opponent cars as
|
||||
slightly wrong, depending on the i960 clock. Here, with the i960 at half
|
||||
and at double its clock, only one of the 8 start grid objects moves, by
|
||||
about 0.3 units (it is still settling when the race starts). Compared with
|
||||
a video of a real Model 2A-CRX, aligned on the race clock (chase view,
|
||||
full throttle): same speed (220 km/h at 0'04"0), same course, and the
|
||||
first opponent appears at the end of the village at 0'05"0 in both, at the
|
||||
same distance up to 0'06"0. Nothing is changed.
|
||||
|
||||
## Manx TT Superbike (Model 2A)
|
||||
|
||||
Sets: `manxtt` (DX/Twin, Revision D), `manxttc` (DX/Twin, Revision C),
|
||||
`manxttdx` (DX).
|
||||
|
||||
- **Cabinet type.** The MAME sets include an EEPROM image that sets the
|
||||
cabinet type: DX for `manxtt`, Twin for `manxttc`. A new NVRAM starts from
|
||||
it (`REGION_PROMS`, 16-bit little-endian as in MAME). The type can still be
|
||||
changed in the test menu.
|
||||
- **Motion slider (DX).** The DX bike moves; its drive board takes commands
|
||||
on port E of the 315-5649 and answers on port D. At boot the game shows
|
||||
"ACTIVE MOTION SLIDER / NOW CHECKING SYSTEM" (code at `0x5f580` in
|
||||
`manxtt`): after command `0x3d` it waits up to 846 frames for status
|
||||
`0xce`, sends the bike center value, then waits for `0xcd`. Without an
|
||||
answer it shows "Error! ... Not Respond" and never starts; MAME stops
|
||||
there (its known issue "no escape from active motion slider tutorial").
|
||||
The board is simulated with those two answers: `0xce` while the command is
|
||||
`0x3d`, `0xcd` otherwise. The board's error codes (`0xb0`-`0xb7`: first
|
||||
setting, encoder, overcurrent, overheat, bank volume, ROM, RAM, centering)
|
||||
are never sent. The bike does not move, of course.
|
||||
- **Model 1 sound board (DX).** The DX cabinet has a Model 1 sound board
|
||||
(68000, YM3438, two MultiPCM) next to the SCSP, for extra sounds. It runs as
|
||||
a fourth CPU (`REGION_CPU4`, samples in `REGION_SOUND2`/`REGION_SOUND3`)
|
||||
and gets the same sound commands from the i960 UART, as in MAME. Its replies
|
||||
are not passed back: the i960 reads the SCSP's.
|
||||
- **Communication board.** Its program (`epr-18643a`) is not listed; the
|
||||
board is not emulated and the game runs as a single machine.
|
||||
|
||||
## Sky Target (Model 2A)
|
||||
|
||||
Sets: `skytargt`.
|
||||
|
||||
The stick is on analog channels 0 (Y) and 2 (X, reversed), as in MAME.
|
||||
Machine gun, missile and view change are buttons 1-3.
|
||||
|
||||
## Air Walkers (Model 2A)
|
||||
|
||||
Sets: `airwlkrs`.
|
||||
|
||||
Up to four players on two input ports: port F bit 7 selects players 1-2 or
|
||||
3-4 on ports C and D, and the matching start buttons on IN0 bits 4-5, as in
|
||||
MAME.
|
||||
|
||||
## Hanguk Pro Yagu 98 (Model 2A)
|
||||
|
||||
Sets: `hpyagu98`.
|
||||
|
||||
The game stops with "Error #1" unless the NVRAM holds what its boot code
|
||||
checks: EEPROM words 4-5, the string "98KOREA PRO B.B." at the start of the
|
||||
backup RAM, a magic dword at `0x398` (`v * 3 + 0x3e82 == 0xf0c891a2`), and the
|
||||
settings block at `0x10` with its CRC (a copy at `0x1d4` restores it when
|
||||
only one is valid). MAME lists two hand-made images, EEPROM and backup RAM,
|
||||
with the settings of Dynamite Baseball 97. A new NVRAM starts from them, as in
|
||||
MAME (`REGION_PROMS` and `REGION_GFX1`); older sets without these two files
|
||||
stop on "Error #1".
|
||||
|
||||
## Desert Tank (original Model 2)
|
||||
|
||||
Sets: `desert`.
|
||||
|
||||
Model 1 I/O board as Daytona USA (its BIOS runs when `model1io.zip` is
|
||||
present). Steering, accelerator and brake on the I/O board analog inputs,
|
||||
the shift lever as a toggle, as in MAME.
|
||||
|
||||
## Model 2C: the TGPx4 (MB86235)
|
||||
|
||||
The Model 2C boards replace the TGP with a Fujitsu MB86235 "TGPx4". Its
|
||||
interpreter comes from current MAME (`src/cpu/mb86235`, in C89), with the
|
||||
program memory, the external bus (buffer RAM at `0x400000`, the copro data
|
||||
ROM at `0x800000`) and the two FIFOs as driver callbacks. As in MAME, the
|
||||
CPU waits in halt until the i960 has sent its program, and a read from the
|
||||
empty input FIFO repeats the instruction once the i960 pushes a value. Two
|
||||
places differ from MAME, where its code is plainly a slip:
|
||||
|
||||
- **FEA/FES** (exponent add/subtract) keep the sign and the mantissa and
|
||||
change only the exponent field; MAME keeps only the exponent field.
|
||||
- **EBL** (the low 14 bits of the external base register) is written as the
|
||||
low bits; MAME shifts the value up as for EBU.
|
||||
|
||||
None of the games checked showed a difference from either change.
|
||||
|
||||
The 2C games run faster than real time here, where MAME runs them at about
|
||||
70%.
|
||||
|
||||
## Video: polygon clipping
|
||||
|
||||
A polygon is clipped against four planes, and a convex one gains at most one
|
||||
vertex for each, so MAME's buffers hold 8. A bad polygon (self-crossing, or
|
||||
with NaN coordinates) can double its vertices at each plane: Top Skater's
|
||||
models drawn with the standard object format overflowed the buffers and
|
||||
crashed the core. The buffers now hold 64 vertices and only polygons that
|
||||
still fit in 8 are kept.
|
||||
|
||||
## Top Skater (Model 2C)
|
||||
|
||||
Sets: `topskatr`, `topskatru`, `topskatruo`, `topskatrj`.
|
||||
|
||||
The game uploads its own geometrizer program (MAME's notes: "a slightly
|
||||
different geometry code"), and MAME shows no 3D. Its object data command
|
||||
(`0x11`, the second bank of command numbers) reads a compact polygon list:
|
||||
the attribute word, then only the points, three words for a triangle and
|
||||
six for a quad. The standard format (no normals) also has three unused
|
||||
normal words and, for triangles, an unused point. Read with the standard
|
||||
format, every polygon after the first was garbage. The driver reads the
|
||||
compact format for command `0x11` in this game only; the skaters, the
|
||||
board, the ramps and the crowd are all drawn. The command word also carries the
|
||||
center select in bits 6-7, as the rasterizer command does: the speed meter
|
||||
is drawn around the window's second vanishing point, in the bottom left
|
||||
corner. Compared with a video of the arcade game: the course, the HUD and
|
||||
the speed meter are in the same places.
|
||||
|
||||
The program's command `0x1b` loads a second matrix and `0x1c` copies the
|
||||
first matrix's translation into it; a vertex whose x has the lowest bit set
|
||||
goes through the second matrix (the skinned joints of the skaters). MAME
|
||||
pull request #16444 (jkind73, open) found the compact format and the second
|
||||
matrix too.
|
||||
|
||||
The board has two foot sensors (front and tail), on while a foot stands on
|
||||
it. MAME reads them active low, so with no input both feet are off the
|
||||
board: the skater always jumps, floats 16 units above the ground with the
|
||||
camera close behind, and its shadow (which the game puts on the ground
|
||||
under the light) is far below, off screen. Here they are on at rest and a
|
||||
button lifts a foot. Compared with a video of the arcade game at the same
|
||||
race time, the skater now rides crouched, the camera is at the same
|
||||
distance and the shadow is under the board. The attract demos, played by
|
||||
the game, matched the video before already (shadows included).
|
||||
|
||||
The analog inputs are curving (channel 0, stick X) and slide (channel 1);
|
||||
MAME puts both on the same axis, here slide is on stick Y so a pad can
|
||||
reach both.
|
||||
|
||||
The music is on the DSB2 MPEG board (see the music board section).
|
||||
|
||||
## Sega Ski Super G (Model 2C)
|
||||
|
||||
Sets: `skisuprg`.
|
||||
|
||||
The drive board answers on port D to the commands on port E. At boot the
|
||||
game shows "CHECK DRIVE BOARD" (code at `0x88b10`): it clears port E and
|
||||
waits for `0xce` (ready), sends the inclining center and waits for `0xff`
|
||||
(taken), within 479 frames; without an answer it stops on "DRIVE BOARD
|
||||
TROUBLE CODE: FF", as in MAME. In game, `0xb0`-`0xb7` are board errors
|
||||
(init, encoder, overload, overheat, bank volume, ROM...). The board is
|
||||
simulated: `0xce` while port E is 0, `0xff` otherwise. The game then runs
|
||||
through the World Series and the races.
|
||||
|
||||
Swing is on analog channel 0 (stick Y), inclining on channel 1 (stick X),
|
||||
the foot sensors on port D are not read (port D is the drive board).
|
||||
|
||||
## Sega Touring Car Championship and Top Skater: music board (DSB)
|
||||
|
||||
Sets: `stcc`, `stccb`, `stcca`, `stcco` (DSB, Z80) and the Top Skater sets
|
||||
(DSB2, 68000).
|
||||
|
||||
Their music is MPEG audio (layer II, 32 kHz stereo) on a Digital Sound
|
||||
Board, from current MAME (`dsbz80.cpp`, `dsb2.cpp` and the decoder
|
||||
`mpeg_audio.cpp`, in C89: `src/sndhrdw/segadsb.c`, `src/sound/mpeg_audio.c`).
|
||||
The board's CPU gets the game's sound commands on its i8251, from the same
|
||||
line as the SCSP (each byte the i960 sends goes to both), and drives the
|
||||
decoder: start and end addresses, play, loop, stop, volume and stereo mode
|
||||
for the DSB; a command FIFO and a 1 kHz timer interrupt for the DSB2. The
|
||||
decoded audio is its own stream, mixed 9 dB under the SCSP's full level
|
||||
(MAME mixes both at full level). The level was measured on two recordings
|
||||
of Top Skater cabinets: with the music and the sound effects of the core as
|
||||
separate tracks of the same run, aligned on the attract mode, the
|
||||
recordings came out with the music 9 dB lower against the effects (within
|
||||
1 dB, both recordings); at full level the music also clipped. The decoded
|
||||
music itself matches the recordings (spectral correlation 0.9-0.97). The
|
||||
recordings play the music about 0.45% faster than the core's 32 kHz
|
||||
(emulated time); not changed, it may be the recordings. Touring Car's DSB
|
||||
uses the same level (no recording checked).
|
||||
|
||||
The decoder never reads past the MPEG ROM (MAME guards this on the DSB2
|
||||
only). The drive board and the communication board programs are not
|
||||
listed.
|
||||
|
||||
## The House of the Dead (Model 2C)
|
||||
|
||||
Sets: `hotd`, `hotdo`.
|
||||
|
||||
The guns work as in Virtua Cop 2 (the 315-5649 serial channel), with the
|
||||
ranges of MAME's `hotd` ports. MAME's prototype `hotdp` is not listed: one
|
||||
of its texture ROMs was never dumped.
|
||||
|
||||
## Other Model 2C sets
|
||||
|
||||
`waverunr`, `bel`, `segawski`, `dynamcopc` and `overrev` (now the Model 2C
|
||||
parent of the Model 2B sets) run with the inputs of MAME.
|
||||
|
||||
## Motor Raid - Twin/DX (Model 2A)
|
||||
|
||||
Sets: `motoraiddx`.
|
||||
|
||||
The DX cabinet has a moving bike, run by a drive board on the 315-5649
|
||||
ports: the game writes commands to port E (inverted) and reads the board's
|
||||
status on port D. The drive board's program is not dumped and MAME lists the
|
||||
set as not working: the game stops at "DRIVEBOARD NOT RESPONSE ERROR".
|
||||
|
||||
The board is simulated, as for Manx TT DX. From the cabinet check (code
|
||||
copied to RAM at `0x2158d0`, ROM `0xc58d0`):
|
||||
|
||||
- port D reads `0xcd` when the board is ready; the check then skips the
|
||||
initialisation and centring steps (which wait for `0xcf` and `0xce`);
|
||||
- the wire test sends commands `0xe0`-`0xef` and expects bit `n & 7`
|
||||
cleared (table at ROM `0xc5720`); the simulation answers the same.
|
||||
|
||||
The bike does not move, the game runs as on a working cabinet.
|
||||
|
||||
## Rail Chase 2 (`rchase2a`)
|
||||
|
||||
A second program for Rail Chase 2 that reads the guns the other way round
|
||||
(maybe a factory conversion). The guns are centred at `0x80` over the full
|
||||
range, as MAME's `rchase2a` ports.
|
||||
|
||||
## Daytona USA hacks
|
||||
|
||||
Sets: `daytonat`, `daytonata` (Turbo hack), `daytonam` (To The MAXX),
|
||||
`daytonagtx` (GTX 2004 Edition). Hacks by Kyle Hodgetts, listed by MAME as
|
||||
not working; here they play.
|
||||
|
||||
- **To The MAXX**: the kit has a PIC 16F84 in socket IC15. It answers at
|
||||
`0x240000`, where the third program ROM (`maxx.14`) is seen. As MAME:
|
||||
16-bit reads of the first 32 bytes step a 4-bit counter and return the
|
||||
PIC's answer.
|
||||
- **GTX 2004**: a banked ROM over the data ROMs at `0x2c00000`. Reads of
|
||||
some bytes switch the bank, as MAME (`0xff00c` and `0xf0003` bank 0,
|
||||
`0xff000` bank 1, `0xffffc` the empty bank 2).
|
||||
|
||||
## Not added
|
||||
|
||||
- **Royal Ascot II** (`rascot2`): a horse racing terminal made for the
|
||||
SegaNet network. It waits for the network ("SegaNet Wait Status" in MAME)
|
||||
and never starts a race as a single machine.
|
||||
|
||||
- **Power Sled** (`powsled`, `powsledr`, `powsledm`): a network of
|
||||
cabinets run by a Main unit, whose program was never dumped (MAME's
|
||||
`powsledm` is a hack of the Relay program). Every version waits on the
|
||||
network ("NETWORK: NG") in MAME, and would need the whole network to be
|
||||
simulated.
|
||||
Binary file not shown.
+5393
-5295
File diff suppressed because it is too large.
Load diff
+293
-293
@@ -1654,100 +1654,100 @@
|
||||
40love:0:8546:03:001:"Game" Score = 30 Now! CPU
|
||||
|
||||
; [ Idol Janshi Su-Chi-Pie 2 (v1.1) ]
|
||||
47pie2:0:FEE00118:63:000:Infinite Credits
|
||||
:47pie2:00000020:FEE00B01:00000005:FFFFFFFF:Infinite Time
|
||||
:47pie2:00010020:FEE00B97:00000000:FFFFFFFF:Infinite Time (2/2)
|
||||
:47pie2:00000000:FEE01788:00000009:FFFFFFFF:Infinite Bonus Game Left
|
||||
:47pie2:00000101:FEE01784:00000020:FFFFFFFF:Select Change Point
|
||||
:47pie2:60000000:00000000:00000000:00000000:[ The winning hand cheat must be activated when ]
|
||||
:47pie2:60000000:00000000:00000000:00000000:[ there are 14 tiles in your hand, then press ]
|
||||
:47pie2:60000000:00000000:00000000:00000000:[ the RON key ('Z' by default). The tiles do not ]
|
||||
:47pie2:60000000:00000000:00000000:00000000:[ visually change until you make a move. ]
|
||||
:47pie2:00300001:FEE00868:34000000:FFFFFFFF:Get winning hand Now!
|
||||
:47pie2:00310001:FEE0086C:34000000:FFFFFFFF:Get winning hand Now! (02/14)
|
||||
:47pie2:00310001:FEE00870:34000000:FFFFFFFF:Get winning hand Now! (03/14)
|
||||
:47pie2:00310001:FEE00874:34000001:FFFFFFFF:Get winning hand Now! (04/14)
|
||||
:47pie2:00310001:FEE00878:34000001:FFFFFFFF:Get winning hand Now! (05/14)
|
||||
:47pie2:00310001:FEE0087C:34000001:FFFFFFFF:Get winning hand Now! (06/14)
|
||||
:47pie2:00310001:FEE00880:34000002:FFFFFFFF:Get winning hand Now! (07/14)
|
||||
:47pie2:00310001:FEE00884:34000002:FFFFFFFF:Get winning hand Now! (08/14)
|
||||
:47pie2:00310001:FEE00888:34000002:FFFFFFFF:Get winning hand Now! (09/14)
|
||||
:47pie2:00310001:FEE0088C:34000003:FFFFFFFF:Get winning hand Now! (10/14)
|
||||
:47pie2:00310001:FEE00890:34000003:FFFFFFFF:Get winning hand Now! (11/14)
|
||||
:47pie2:00310001:FEE00894:34000003:FFFFFFFF:Get winning hand Now! (12/14)
|
||||
:47pie2:00310001:FEE00898:34000004:FFFFFFFF:Get winning hand Now! (13/14)
|
||||
:47pie2:00310001:FEE0089C:34000004:FFFFFFFF:Get winning hand Now! (14/14)
|
||||
:47pie2:00300000:FEE00868:34000000:FFFFFFFF:Always winning hand
|
||||
:47pie2:00310000:FEE0086C:34000000:FFFFFFFF:Always winning hand (02/14)
|
||||
:47pie2:00310000:FEE00870:34000000:FFFFFFFF:Always winning hand (03/14)
|
||||
:47pie2:00310000:FEE00874:34000001:FFFFFFFF:Always winning hand (04/14)
|
||||
:47pie2:00310000:FEE00878:34000001:FFFFFFFF:Always winning hand (05/14)
|
||||
:47pie2:00310000:FEE0087C:34000001:FFFFFFFF:Always winning hand (06/14)
|
||||
:47pie2:00310000:FEE00880:34000002:FFFFFFFF:Always winning hand (07/14)
|
||||
:47pie2:00310000:FEE00884:34000002:FFFFFFFF:Always winning hand (08/14)
|
||||
:47pie2:00310000:FEE00888:34000002:FFFFFFFF:Always winning hand (09/14)
|
||||
:47pie2:00310000:FEE0088C:34000003:FFFFFFFF:Always winning hand (10/14)
|
||||
:47pie2:00310000:FEE00890:34000003:FFFFFFFF:Always winning hand (11/14)
|
||||
:47pie2:00310000:FEE00894:34000003:FFFFFFFF:Always winning hand (12/14)
|
||||
:47pie2:00310000:FEE00898:34000004:FFFFFFFF:Always winning hand (13/14)
|
||||
:47pie2:00310000:FEE0089C:34000004:FFFFFFFF:Always winning hand (14/14)
|
||||
:47pie2:00000000:FEE00F48:00000009:FFFFFFFF:Infinite "Sue-Chi Stick"
|
||||
:47pie2:00000000:FEE00F4C:00000009:FFFFFFFF:Infinite "Fire Sekkan"
|
||||
:47pie2:00000000:FEE00F50:00000009:FFFFFFFF:Infinite "Special Syoukan"
|
||||
:47pie2:00000000:FEE00F54:00000009:FFFFFFFF:Infinite "Helper"
|
||||
:47pie2:00000000:FEE00F58:00000009:FFFFFFFF:Infinite "Hyper Eye"
|
||||
:47pie2:00000000:FEE00B08:0000001F:FFFFFFFF:Always Join All Associates:If you don't join associates who Peach Pie, Lemon Pie, Cherry Pie and Milky Pie the game's end is the bad one.
|
||||
:47pie2:00000000:FEE00AF8:00000004:FFFFFFFF:Start on Shiho Katagiri:Turn this cheat OFF after you've started the game
|
||||
:47pie2:00000000:FEE00AF8:00000005:FFFFFFFF:Start on Sesir.D:Turn this cheat OFF after you've started the game
|
||||
:47pie2:00000000:FEE00AF8:00000006:FFFFFFFF:Start on Sesir.D (Final):Turn this cheat OFF after you've started the game
|
||||
suchie2:0:FEE00118:63:000:Infinite Credits
|
||||
:suchie2:00000020:FEE00B01:00000005:FFFFFFFF:Infinite Time
|
||||
:suchie2:00010020:FEE00B97:00000000:FFFFFFFF:Infinite Time (2/2)
|
||||
:suchie2:00000000:FEE01788:00000009:FFFFFFFF:Infinite Bonus Game Left
|
||||
:suchie2:00000101:FEE01784:00000020:FFFFFFFF:Select Change Point
|
||||
:suchie2:60000000:00000000:00000000:00000000:[ The winning hand cheat must be activated when ]
|
||||
:suchie2:60000000:00000000:00000000:00000000:[ there are 14 tiles in your hand, then press ]
|
||||
:suchie2:60000000:00000000:00000000:00000000:[ the RON key ('Z' by default). The tiles do not ]
|
||||
:suchie2:60000000:00000000:00000000:00000000:[ visually change until you make a move. ]
|
||||
:suchie2:00300001:FEE00868:34000000:FFFFFFFF:Get winning hand Now!
|
||||
:suchie2:00310001:FEE0086C:34000000:FFFFFFFF:Get winning hand Now! (02/14)
|
||||
:suchie2:00310001:FEE00870:34000000:FFFFFFFF:Get winning hand Now! (03/14)
|
||||
:suchie2:00310001:FEE00874:34000001:FFFFFFFF:Get winning hand Now! (04/14)
|
||||
:suchie2:00310001:FEE00878:34000001:FFFFFFFF:Get winning hand Now! (05/14)
|
||||
:suchie2:00310001:FEE0087C:34000001:FFFFFFFF:Get winning hand Now! (06/14)
|
||||
:suchie2:00310001:FEE00880:34000002:FFFFFFFF:Get winning hand Now! (07/14)
|
||||
:suchie2:00310001:FEE00884:34000002:FFFFFFFF:Get winning hand Now! (08/14)
|
||||
:suchie2:00310001:FEE00888:34000002:FFFFFFFF:Get winning hand Now! (09/14)
|
||||
:suchie2:00310001:FEE0088C:34000003:FFFFFFFF:Get winning hand Now! (10/14)
|
||||
:suchie2:00310001:FEE00890:34000003:FFFFFFFF:Get winning hand Now! (11/14)
|
||||
:suchie2:00310001:FEE00894:34000003:FFFFFFFF:Get winning hand Now! (12/14)
|
||||
:suchie2:00310001:FEE00898:34000004:FFFFFFFF:Get winning hand Now! (13/14)
|
||||
:suchie2:00310001:FEE0089C:34000004:FFFFFFFF:Get winning hand Now! (14/14)
|
||||
:suchie2:00300000:FEE00868:34000000:FFFFFFFF:Always winning hand
|
||||
:suchie2:00310000:FEE0086C:34000000:FFFFFFFF:Always winning hand (02/14)
|
||||
:suchie2:00310000:FEE00870:34000000:FFFFFFFF:Always winning hand (03/14)
|
||||
:suchie2:00310000:FEE00874:34000001:FFFFFFFF:Always winning hand (04/14)
|
||||
:suchie2:00310000:FEE00878:34000001:FFFFFFFF:Always winning hand (05/14)
|
||||
:suchie2:00310000:FEE0087C:34000001:FFFFFFFF:Always winning hand (06/14)
|
||||
:suchie2:00310000:FEE00880:34000002:FFFFFFFF:Always winning hand (07/14)
|
||||
:suchie2:00310000:FEE00884:34000002:FFFFFFFF:Always winning hand (08/14)
|
||||
:suchie2:00310000:FEE00888:34000002:FFFFFFFF:Always winning hand (09/14)
|
||||
:suchie2:00310000:FEE0088C:34000003:FFFFFFFF:Always winning hand (10/14)
|
||||
:suchie2:00310000:FEE00890:34000003:FFFFFFFF:Always winning hand (11/14)
|
||||
:suchie2:00310000:FEE00894:34000003:FFFFFFFF:Always winning hand (12/14)
|
||||
:suchie2:00310000:FEE00898:34000004:FFFFFFFF:Always winning hand (13/14)
|
||||
:suchie2:00310000:FEE0089C:34000004:FFFFFFFF:Always winning hand (14/14)
|
||||
:suchie2:00000000:FEE00F48:00000009:FFFFFFFF:Infinite "Sue-Chi Stick"
|
||||
:suchie2:00000000:FEE00F4C:00000009:FFFFFFFF:Infinite "Fire Sekkan"
|
||||
:suchie2:00000000:FEE00F50:00000009:FFFFFFFF:Infinite "Special Syoukan"
|
||||
:suchie2:00000000:FEE00F54:00000009:FFFFFFFF:Infinite "Helper"
|
||||
:suchie2:00000000:FEE00F58:00000009:FFFFFFFF:Infinite "Hyper Eye"
|
||||
:suchie2:00000000:FEE00B08:0000001F:FFFFFFFF:Always Join All Associates:If you don't join associates who Peach Pie, Lemon Pie, Cherry Pie and Milky Pie the game's end is the bad one.
|
||||
:suchie2:00000000:FEE00AF8:00000004:FFFFFFFF:Start on Shiho Katagiri:Turn this cheat OFF after you've started the game
|
||||
:suchie2:00000000:FEE00AF8:00000005:FFFFFFFF:Start on Sesir.D:Turn this cheat OFF after you've started the game
|
||||
:suchie2:00000000:FEE00AF8:00000006:FFFFFFFF:Start on Sesir.D (Final):Turn this cheat OFF after you've started the game
|
||||
|
||||
; [ Idol Janshi Su-Chi-Pie 2 (v1.0) ]
|
||||
47pie2o:0:FEE00118:63:000:Infinite Credits
|
||||
:47pie2o:00000020:FEE00B01:00000005:FFFFFFFF:Infinite Time
|
||||
:47pie2o:00010020:FEE00B97:00000000:FFFFFFFF:Infinite Time (2/2)
|
||||
:47pie2o:00000000:FEE01788:00000009:FFFFFFFF:Infinite Bonus Game Left
|
||||
:47pie2o:00000101:FEE01784:00000020:FFFFFFFF:Select Change Point
|
||||
:47pie2o:60000000:00000000:00000000:00000000:[ The winning hand cheat must be activated when ]
|
||||
:47pie2o:60000000:00000000:00000000:00000000:[ there are 14 tiles in your hand, then press ]
|
||||
:47pie2o:60000000:00000000:00000000:00000000:[ the RON key ('Z' by default). The tiles do not ]
|
||||
:47pie2o:60000000:00000000:00000000:00000000:[ visually change until you make a move. ]
|
||||
:47pie2o:00300001:FEE00868:34000000:FFFFFFFF:Get winning hand Now!
|
||||
:47pie2o:00310001:FEE0086C:34000000:FFFFFFFF:Get winning hand Now! (02/14)
|
||||
:47pie2o:00310001:FEE00870:34000000:FFFFFFFF:Get winning hand Now! (03/14)
|
||||
:47pie2o:00310001:FEE00874:34000001:FFFFFFFF:Get winning hand Now! (04/14)
|
||||
:47pie2o:00310001:FEE00878:34000001:FFFFFFFF:Get winning hand Now! (05/14)
|
||||
:47pie2o:00310001:FEE0087C:34000001:FFFFFFFF:Get winning hand Now! (06/14)
|
||||
:47pie2o:00310001:FEE00880:34000002:FFFFFFFF:Get winning hand Now! (07/14)
|
||||
:47pie2o:00310001:FEE00884:34000002:FFFFFFFF:Get winning hand Now! (08/14)
|
||||
:47pie2o:00310001:FEE00888:34000002:FFFFFFFF:Get winning hand Now! (09/14)
|
||||
:47pie2o:00310001:FEE0088C:34000003:FFFFFFFF:Get winning hand Now! (10/14)
|
||||
:47pie2o:00310001:FEE00890:34000003:FFFFFFFF:Get winning hand Now! (11/14)
|
||||
:47pie2o:00310001:FEE00894:34000003:FFFFFFFF:Get winning hand Now! (12/14)
|
||||
:47pie2o:00310001:FEE00898:34000004:FFFFFFFF:Get winning hand Now! (13/14)
|
||||
:47pie2o:00310001:FEE0089C:34000004:FFFFFFFF:Get winning hand Now! (14/14)
|
||||
:47pie2o:00300000:FEE00868:34000000:FFFFFFFF:Always winning hand
|
||||
:47pie2o:00310000:FEE0086C:34000000:FFFFFFFF:Always winning hand (02/14)
|
||||
:47pie2o:00310000:FEE00870:34000000:FFFFFFFF:Always winning hand (03/14)
|
||||
:47pie2o:00310000:FEE00874:34000001:FFFFFFFF:Always winning hand (04/14)
|
||||
:47pie2o:00310000:FEE00878:34000001:FFFFFFFF:Always winning hand (05/14)
|
||||
:47pie2o:00310000:FEE0087C:34000001:FFFFFFFF:Always winning hand (06/14)
|
||||
:47pie2o:00310000:FEE00880:34000002:FFFFFFFF:Always winning hand (07/14)
|
||||
:47pie2o:00310000:FEE00884:34000002:FFFFFFFF:Always winning hand (08/14)
|
||||
:47pie2o:00310000:FEE00888:34000002:FFFFFFFF:Always winning hand (09/14)
|
||||
:47pie2o:00310000:FEE0088C:34000003:FFFFFFFF:Always winning hand (10/14)
|
||||
:47pie2o:00310000:FEE00890:34000003:FFFFFFFF:Always winning hand (11/14)
|
||||
:47pie2o:00310000:FEE00894:34000003:FFFFFFFF:Always winning hand (12/14)
|
||||
:47pie2o:00310000:FEE00898:34000004:FFFFFFFF:Always winning hand (13/14)
|
||||
:47pie2o:00310000:FEE0089C:34000004:FFFFFFFF:Always winning hand (14/14)
|
||||
:47pie2o:00000000:FEE00F48:00000009:FFFFFFFF:Infinite "Sue-Chi Stick"
|
||||
:47pie2o:00000000:FEE00F4C:00000009:FFFFFFFF:Infinite "Fire Sekkan"
|
||||
:47pie2o:00000000:FEE00F50:00000009:FFFFFFFF:Infinite "Special Syoukan"
|
||||
:47pie2o:00000000:FEE00F54:00000009:FFFFFFFF:Infinite "Helper"
|
||||
:47pie2o:00000000:FEE00F58:00000009:FFFFFFFF:Infinite "Hyper Eye"
|
||||
:47pie2o:00000000:FEE00B08:0000001F:FFFFFFFF:Always Join All Associates:If you don't join associates who Peach Pie, Lemon Pie, Cherry Pie and Milky Pie the game's end is the bad one.
|
||||
:47pie2o:00000000:FEE00AF8:00000004:FFFFFFFF:Start on Shiho Katagiri:Turn this cheat OFF after you've started the game
|
||||
:47pie2o:00000000:FEE00AF8:00000005:FFFFFFFF:Start on Sesir.D:Turn this cheat OFF after you've started the game
|
||||
:47pie2o:00000000:FEE00AF8:00000006:FFFFFFFF:Start on Sesir.D (Final):Turn this cheat OFF after you've started the game
|
||||
suchie2o:0:FEE00118:63:000:Infinite Credits
|
||||
:suchie2o:00000020:FEE00B01:00000005:FFFFFFFF:Infinite Time
|
||||
:suchie2o:00010020:FEE00B97:00000000:FFFFFFFF:Infinite Time (2/2)
|
||||
:suchie2o:00000000:FEE01788:00000009:FFFFFFFF:Infinite Bonus Game Left
|
||||
:suchie2o:00000101:FEE01784:00000020:FFFFFFFF:Select Change Point
|
||||
:suchie2o:60000000:00000000:00000000:00000000:[ The winning hand cheat must be activated when ]
|
||||
:suchie2o:60000000:00000000:00000000:00000000:[ there are 14 tiles in your hand, then press ]
|
||||
:suchie2o:60000000:00000000:00000000:00000000:[ the RON key ('Z' by default). The tiles do not ]
|
||||
:suchie2o:60000000:00000000:00000000:00000000:[ visually change until you make a move. ]
|
||||
:suchie2o:00300001:FEE00868:34000000:FFFFFFFF:Get winning hand Now!
|
||||
:suchie2o:00310001:FEE0086C:34000000:FFFFFFFF:Get winning hand Now! (02/14)
|
||||
:suchie2o:00310001:FEE00870:34000000:FFFFFFFF:Get winning hand Now! (03/14)
|
||||
:suchie2o:00310001:FEE00874:34000001:FFFFFFFF:Get winning hand Now! (04/14)
|
||||
:suchie2o:00310001:FEE00878:34000001:FFFFFFFF:Get winning hand Now! (05/14)
|
||||
:suchie2o:00310001:FEE0087C:34000001:FFFFFFFF:Get winning hand Now! (06/14)
|
||||
:suchie2o:00310001:FEE00880:34000002:FFFFFFFF:Get winning hand Now! (07/14)
|
||||
:suchie2o:00310001:FEE00884:34000002:FFFFFFFF:Get winning hand Now! (08/14)
|
||||
:suchie2o:00310001:FEE00888:34000002:FFFFFFFF:Get winning hand Now! (09/14)
|
||||
:suchie2o:00310001:FEE0088C:34000003:FFFFFFFF:Get winning hand Now! (10/14)
|
||||
:suchie2o:00310001:FEE00890:34000003:FFFFFFFF:Get winning hand Now! (11/14)
|
||||
:suchie2o:00310001:FEE00894:34000003:FFFFFFFF:Get winning hand Now! (12/14)
|
||||
:suchie2o:00310001:FEE00898:34000004:FFFFFFFF:Get winning hand Now! (13/14)
|
||||
:suchie2o:00310001:FEE0089C:34000004:FFFFFFFF:Get winning hand Now! (14/14)
|
||||
:suchie2o:00300000:FEE00868:34000000:FFFFFFFF:Always winning hand
|
||||
:suchie2o:00310000:FEE0086C:34000000:FFFFFFFF:Always winning hand (02/14)
|
||||
:suchie2o:00310000:FEE00870:34000000:FFFFFFFF:Always winning hand (03/14)
|
||||
:suchie2o:00310000:FEE00874:34000001:FFFFFFFF:Always winning hand (04/14)
|
||||
:suchie2o:00310000:FEE00878:34000001:FFFFFFFF:Always winning hand (05/14)
|
||||
:suchie2o:00310000:FEE0087C:34000001:FFFFFFFF:Always winning hand (06/14)
|
||||
:suchie2o:00310000:FEE00880:34000002:FFFFFFFF:Always winning hand (07/14)
|
||||
:suchie2o:00310000:FEE00884:34000002:FFFFFFFF:Always winning hand (08/14)
|
||||
:suchie2o:00310000:FEE00888:34000002:FFFFFFFF:Always winning hand (09/14)
|
||||
:suchie2o:00310000:FEE0088C:34000003:FFFFFFFF:Always winning hand (10/14)
|
||||
:suchie2o:00310000:FEE00890:34000003:FFFFFFFF:Always winning hand (11/14)
|
||||
:suchie2o:00310000:FEE00894:34000003:FFFFFFFF:Always winning hand (12/14)
|
||||
:suchie2o:00310000:FEE00898:34000004:FFFFFFFF:Always winning hand (13/14)
|
||||
:suchie2o:00310000:FEE0089C:34000004:FFFFFFFF:Always winning hand (14/14)
|
||||
:suchie2o:00000000:FEE00F48:00000009:FFFFFFFF:Infinite "Sue-Chi Stick"
|
||||
:suchie2o:00000000:FEE00F4C:00000009:FFFFFFFF:Infinite "Fire Sekkan"
|
||||
:suchie2o:00000000:FEE00F50:00000009:FFFFFFFF:Infinite "Special Syoukan"
|
||||
:suchie2o:00000000:FEE00F54:00000009:FFFFFFFF:Infinite "Helper"
|
||||
:suchie2o:00000000:FEE00F58:00000009:FFFFFFFF:Infinite "Hyper Eye"
|
||||
:suchie2o:00000000:FEE00B08:0000001F:FFFFFFFF:Always Join All Associates:If you don't join associates who Peach Pie, Lemon Pie, Cherry Pie and Milky Pie the game's end is the bad one.
|
||||
:suchie2o:00000000:FEE00AF8:00000004:FFFFFFFF:Start on Shiho Katagiri:Turn this cheat OFF after you've started the game
|
||||
:suchie2o:00000000:FEE00AF8:00000005:FFFFFFFF:Start on Sesir.D:Turn this cheat OFF after you've started the game
|
||||
:suchie2o:00000000:FEE00AF8:00000006:FFFFFFFF:Start on Sesir.D (Final):Turn this cheat OFF after you've started the game
|
||||
|
||||
; [ 4-D Warriors ]
|
||||
4dwarrio:0:C028:09:000:Infinite Credits
|
||||
@@ -8368,9 +8368,9 @@ bcstry:0:0000:00:999:[ forums. ]:REASON 1
|
||||
beaminv:0:1847:08:000:Infinite Lives
|
||||
|
||||
; [ Beastie Feastie ]
|
||||
beastf:0:4C96:05:000:Infinite Lives PL1
|
||||
beastf:0:4C98:05:000:Infinite Lives PL2
|
||||
beastf:0:4C9D:A8:000:Infinite Energy
|
||||
beastfp:0:4C96:05:000:Infinite Lives PL1
|
||||
beastfp:0:4C98:05:000:Infinite Lives PL2
|
||||
beastfp:0:4C9D:A8:000:Infinite Energy
|
||||
|
||||
; [ Beastorizer (bootleg) ]
|
||||
beastrzb:0:0000:00:999:[ There are no cheats ]:REASON 1
|
||||
@@ -14897,34 +14897,34 @@ chopperb:0:E409:AA:000:Infinite Circle Bombs PL2
|
||||
chopperb:0:E409:FF:000:Infinite Atomic Bombs PL2
|
||||
|
||||
; [ Choplifter ]
|
||||
chplft:0:C02D:95:000:Infinite Lives
|
||||
chplft:0:E118:C8:000:Infinite Fuel
|
||||
chplft:0:C303:41:000:Invincibility
|
||||
chplft:0:C084:01:000:Always Have Prisoners
|
||||
chplft:0:C085:20:001:Finish Level Level Now!
|
||||
chplft:0:C083:00:001:No dead hostages
|
||||
chplft:0:C084:08:001:Max. load hostages = 08
|
||||
chplft:0:C084:20:001:Max. load hostages = 20
|
||||
choplift:0:C02D:95:000:Infinite Lives
|
||||
choplift:0:E118:C8:000:Infinite Fuel
|
||||
choplift:0:C303:41:000:Invincibility
|
||||
choplift:0:C084:01:000:Always Have Prisoners
|
||||
choplift:0:C085:20:001:Finish Level Level Now!
|
||||
choplift:0:C083:00:001:No dead hostages
|
||||
choplift:0:C084:08:001:Max. load hostages = 08
|
||||
choplift:0:C084:20:001:Max. load hostages = 20
|
||||
|
||||
; [ Choplifter (alternate) ]
|
||||
chplftb:0:C02D:95:000:Infinite Lives
|
||||
chplftb:0:E118:C8:000:Infinite Fuel
|
||||
chplftb:0:C303:41:000:Invincibility
|
||||
chplftb:0:C084:01:000:Always Have Prisoners
|
||||
chplftb:0:C085:20:001:Finish Level Level Now!
|
||||
chplftb:0:C083:00:001:No dead hostages
|
||||
chplftb:0:C084:08:001:Max. load hostages = 08
|
||||
chplftb:0:C084:20:001:Max. load hostages = 20
|
||||
chopliftu:0:C02D:95:000:Infinite Lives
|
||||
chopliftu:0:E118:C8:000:Infinite Fuel
|
||||
chopliftu:0:C303:41:000:Invincibility
|
||||
chopliftu:0:C084:01:000:Always Have Prisoners
|
||||
chopliftu:0:C085:20:001:Finish Level Level Now!
|
||||
chopliftu:0:C083:00:001:No dead hostages
|
||||
chopliftu:0:C084:08:001:Max. load hostages = 08
|
||||
chopliftu:0:C084:20:001:Max. load hostages = 20
|
||||
|
||||
; [ Choplifter (bootleg) ]
|
||||
chplftbl:0:C02D:95:000:Infinite Lives PL1
|
||||
chplftbl:0:E118:C8:000:Infinite Fuel
|
||||
chplftbl:0:C303:41:000:Invincibility
|
||||
chplftbl:0:C084:01:000:Always Have Prisoners
|
||||
chplftbl:0:C085:20:001:Finish Level Level Now!
|
||||
chplftbl:0:C083:00:001:No dead hostages
|
||||
chplftbl:0:C084:08:001:Max. load hostages = 08
|
||||
chplftbl:0:C084:20:001:Max. load hostages = 20
|
||||
chopliftbl:0:C02D:95:000:Infinite Lives PL1
|
||||
chopliftbl:0:E118:C8:000:Infinite Fuel
|
||||
chopliftbl:0:C303:41:000:Invincibility
|
||||
chopliftbl:0:C084:01:000:Always Have Prisoners
|
||||
chopliftbl:0:C085:20:001:Finish Level Level Now!
|
||||
chopliftbl:0:C083:00:001:No dead hostages
|
||||
chopliftbl:0:C084:08:001:Max. load hostages = 08
|
||||
chopliftbl:0:C084:20:001:Max. load hostages = 20
|
||||
|
||||
; [ Chequered Flag ]
|
||||
chqflag:0:05C6:63:000:Infinite Credits
|
||||
@@ -19027,9 +19027,9 @@ dakkochn:0:0000:00:999:[ for it on the cheat ]:REASON 1
|
||||
dakkochn:0:0000:00:999:[ forums. ]:REASON 1
|
||||
|
||||
; [ Dancing Eyes (DC1/VER.A) ]
|
||||
danceyes:0:002B51DC:09:000:Infinite Credits
|
||||
danceyes:0:002B51A0:01:000:Always See Through Mode
|
||||
:danceyes:00000500:0021F064:0000000E:FFFFFFFF:Select Stage
|
||||
danceyesj:0:002B51DC:09:000:Infinite Credits
|
||||
danceyesj:0:002B51A0:01:000:Always See Through Mode
|
||||
:danceyesj:00000500:0021F064:0000000E:FFFFFFFF:Select Stage
|
||||
|
||||
; [ Danchi de Hanafuoda ]
|
||||
danchih:0:0000:00:999:[ This game hasn't even ]:REASON 11
|
||||
@@ -31430,24 +31430,24 @@ dungeonm:0:0FFFFF:02:100:Region Switch = US:Dungeon Magic
|
||||
dungeonm:0:0FFFFF:03:100:Region Switch = World:Dungeon Magic
|
||||
|
||||
; [ Dunk Mania (DM1/VER.C) ]
|
||||
dunkmnia:0:001DD096:FF:000:Infinite Time
|
||||
dunkmnia:0:001DD095:FF:500:Infinite Time (2/3)
|
||||
dunkmnia:0:001DD094:FF:500:Infinite Time (3/3)
|
||||
dunkmnia:0:001DD096:00:001:Finish this Period Now!
|
||||
dunkmnia:0:001DD095:00:501:Finish this Period Now! (2/3)
|
||||
dunkmnia:0:001DD094:01:501:Finish this Period Now! (3/3)
|
||||
:dunkmnia:00300060:001DD098:00012875:FFFFFFFF:Infinite Shot Time
|
||||
:dunkmnia:00300001:001DD098:00000001:FFFFFFFF:No Shot Time Left Now!:For the best effect assign this cheat an activation key and use it whenever the other side has the ball!
|
||||
dunkmnia:0:001DD4E8:00:000:Score always = 0 PL1
|
||||
dunkmnia:0:001DD4E8:7F:000:Score always = 127 PL1
|
||||
dunkmnia:0:001DD4E8:00:001:Set score = 0 Now! PL1
|
||||
dunkmnia:0:001DD4E8:32:001:Set score = 50 Now! PL1
|
||||
dunkmnia:0:001DD4E8:7F:070:Select score Now! PL1
|
||||
dunkmnia:0:001DD4F4:00:000:Score always = 0 PL2
|
||||
dunkmnia:0:001DD4F4:7F:000:Score always = 127 PL2
|
||||
dunkmnia:0:001DD4F4:00:001:Set score = 0 Now! PL2
|
||||
dunkmnia:0:001DD4F4:32:001:Set score = 50 Now! PL2
|
||||
dunkmnia:0:001DD4F4:7F:070:Select score Now! PL2
|
||||
dunkmniajc:0:001DD096:FF:000:Infinite Time
|
||||
dunkmniajc:0:001DD095:FF:500:Infinite Time (2/3)
|
||||
dunkmniajc:0:001DD094:FF:500:Infinite Time (3/3)
|
||||
dunkmniajc:0:001DD096:00:001:Finish this Period Now!
|
||||
dunkmniajc:0:001DD095:00:501:Finish this Period Now! (2/3)
|
||||
dunkmniajc:0:001DD094:01:501:Finish this Period Now! (3/3)
|
||||
:dunkmniajc:00300060:001DD098:00012875:FFFFFFFF:Infinite Shot Time
|
||||
:dunkmniajc:00300001:001DD098:00000001:FFFFFFFF:No Shot Time Left Now!:For the best effect assign this cheat an activation key and use it whenever the other side has the ball!
|
||||
dunkmniajc:0:001DD4E8:00:000:Score always = 0 PL1
|
||||
dunkmniajc:0:001DD4E8:7F:000:Score always = 127 PL1
|
||||
dunkmniajc:0:001DD4E8:00:001:Set score = 0 Now! PL1
|
||||
dunkmniajc:0:001DD4E8:32:001:Set score = 50 Now! PL1
|
||||
dunkmniajc:0:001DD4E8:7F:070:Select score Now! PL1
|
||||
dunkmniajc:0:001DD4F4:00:000:Score always = 0 PL2
|
||||
dunkmniajc:0:001DD4F4:7F:000:Score always = 127 PL2
|
||||
dunkmniajc:0:001DD4F4:00:001:Set score = 0 Now! PL2
|
||||
dunkmniajc:0:001DD4F4:32:001:Set score = 50 Now! PL2
|
||||
dunkmniajc:0:001DD4F4:7F:070:Select score Now! PL2
|
||||
|
||||
; [ Dunk Shot ]
|
||||
dunkshot:0:0000:00:999:[ There are no cheats ]:REASON 1
|
||||
@@ -31844,19 +31844,19 @@ eggvntdx:0:000680C8:05:000:Infinite Lives PL2
|
||||
eggvntdx:0:000680BA:63:000:Always have 99 hits PL2
|
||||
|
||||
; [ Ehrgeiz (EG3/VER.A) ]
|
||||
ehrgeiz:0:0000:00:999:[ This game hasn't even ]:REASON 11
|
||||
ehrgeiz:0:0000:00:999:[ been looked at due to ]:REASON 11
|
||||
ehrgeiz:0:0000:00:999:[ time constraints - Too]:REASON 11
|
||||
ehrgeiz:0:0000:00:999:[ many games and so ]:REASON 11
|
||||
ehrgeiz:0:0000:00:999:[ little time. It is ]:REASON 11
|
||||
ehrgeiz:0:0000:00:999:[ even possible that ]:REASON 11
|
||||
ehrgeiz:0:0000:00:999:[ this game may be a ]:REASON 11
|
||||
ehrgeiz:0:0000:00:999:[ clone of an existing ]:REASON 11
|
||||
ehrgeiz:0:0000:00:999:[ game which may have ]:REASON 11
|
||||
ehrgeiz:0:0000:00:999:[ cheats. Please search ]:REASON 11
|
||||
ehrgeiz:0:0000:00:999:[ the cheat forums ]:REASON 11
|
||||
ehrgeiz:0:0000:00:999:[ before posting cheat ]:REASON 11
|
||||
ehrgeiz:0:0000:00:999:[ requests/cheat finding]:REASON 11
|
||||
ehrgeizua:0:0000:00:999:[ This game hasn't even ]:REASON 11
|
||||
ehrgeizua:0:0000:00:999:[ been looked at due to ]:REASON 11
|
||||
ehrgeizua:0:0000:00:999:[ time constraints - Too]:REASON 11
|
||||
ehrgeizua:0:0000:00:999:[ many games and so ]:REASON 11
|
||||
ehrgeizua:0:0000:00:999:[ little time. It is ]:REASON 11
|
||||
ehrgeizua:0:0000:00:999:[ even possible that ]:REASON 11
|
||||
ehrgeizua:0:0000:00:999:[ this game may be a ]:REASON 11
|
||||
ehrgeizua:0:0000:00:999:[ clone of an existing ]:REASON 11
|
||||
ehrgeizua:0:0000:00:999:[ game which may have ]:REASON 11
|
||||
ehrgeizua:0:0000:00:999:[ cheats. Please search ]:REASON 11
|
||||
ehrgeizua:0:0000:00:999:[ the cheat forums ]:REASON 11
|
||||
ehrgeizua:0:0000:00:999:[ before posting cheat ]:REASON 11
|
||||
ehrgeizua:0:0000:00:999:[ requests/cheat finding]:REASON 11
|
||||
|
||||
; [ Eight Forces ]
|
||||
eightfrc:0:201D50:07:000:Infinite Lives PL1
|
||||
@@ -33676,19 +33676,19 @@ fghthstw:0:001005DD:00:001:Drain All Energy Now! PL2
|
||||
fghthstw:0:00100B00:00:501:Drain All Energy Now! PL2 (2/2)
|
||||
|
||||
; [ Fighting Layer (FTL0/VER.A) ]
|
||||
fgtlayer:0:0000:00:999:[ This game hasn't even ]:REASON 11
|
||||
fgtlayer:0:0000:00:999:[ been looked at due to ]:REASON 11
|
||||
fgtlayer:0:0000:00:999:[ time constraints - Too]:REASON 11
|
||||
fgtlayer:0:0000:00:999:[ many games and so ]:REASON 11
|
||||
fgtlayer:0:0000:00:999:[ little time. It is ]:REASON 11
|
||||
fgtlayer:0:0000:00:999:[ even possible that ]:REASON 11
|
||||
fgtlayer:0:0000:00:999:[ this game may be a ]:REASON 11
|
||||
fgtlayer:0:0000:00:999:[ clone of an existing ]:REASON 11
|
||||
fgtlayer:0:0000:00:999:[ game which may have ]:REASON 11
|
||||
fgtlayer:0:0000:00:999:[ cheats. Please search ]:REASON 11
|
||||
fgtlayer:0:0000:00:999:[ the cheat forums ]:REASON 11
|
||||
fgtlayer:0:0000:00:999:[ before posting cheat ]:REASON 11
|
||||
fgtlayer:0:0000:00:999:[ requests/cheat finding]:REASON 11
|
||||
fgtlayerja:0:0000:00:999:[ This game hasn't even ]:REASON 11
|
||||
fgtlayerja:0:0000:00:999:[ been looked at due to ]:REASON 11
|
||||
fgtlayerja:0:0000:00:999:[ time constraints - Too]:REASON 11
|
||||
fgtlayerja:0:0000:00:999:[ many games and so ]:REASON 11
|
||||
fgtlayerja:0:0000:00:999:[ little time. It is ]:REASON 11
|
||||
fgtlayerja:0:0000:00:999:[ even possible that ]:REASON 11
|
||||
fgtlayerja:0:0000:00:999:[ this game may be a ]:REASON 11
|
||||
fgtlayerja:0:0000:00:999:[ clone of an existing ]:REASON 11
|
||||
fgtlayerja:0:0000:00:999:[ game which may have ]:REASON 11
|
||||
fgtlayerja:0:0000:00:999:[ cheats. Please search ]:REASON 11
|
||||
fgtlayerja:0:0000:00:999:[ the cheat forums ]:REASON 11
|
||||
fgtlayerja:0:0000:00:999:[ before posting cheat ]:REASON 11
|
||||
fgtlayerja:0:0000:00:999:[ requests/cheat finding]:REASON 11
|
||||
|
||||
; [ Fighting Hawk (World) ]
|
||||
fhawk:0:9012:09:000:Infinite Bombs
|
||||
@@ -42660,25 +42660,25 @@ hattrick:0:015F:99:073:Select Score RED TEAM
|
||||
hattrick:0:013A:99:073:Select Score BLUE TEAM
|
||||
|
||||
; [ Hayaoshi Quiz Ouza Ketteisen ]
|
||||
hayaosi1:0:0000:00:999:[ This game should be ]:REASON 10
|
||||
hayaosi1:0:0000:00:999:[ quite straighforward ]:REASON 10
|
||||
hayaosi1:0:0000:00:999:[ enough to find cheats ]:REASON 10
|
||||
hayaosi1:0:0000:00:999:[ for. But no cheats ]:REASON 10
|
||||
hayaosi1:0:0000:00:999:[ have been submitted ]:REASON 10
|
||||
hayaosi1:0:0000:00:999:[ at the time this cheat]:REASON 10
|
||||
hayaosi1:0:0000:00:999:[ file was compiled ]:REASON 10
|
||||
hayaosi1:0:0000:00:999:[ due to the game ]:REASON 10
|
||||
hayaosi1:0:0000:00:999:[ generating zero ]:REASON 10
|
||||
hayaosi1:0:0000:00:999:[ interest from cheat ]:REASON 10
|
||||
hayaosi1:0:0000:00:999:[ finders. If you have ]:REASON 10
|
||||
hayaosi1:0:0000:00:999:[ made some cheats for ]:REASON 10
|
||||
hayaosi1:0:0000:00:999:[ this game please post ]:REASON 10
|
||||
hayaosi1:0:0000:00:999:[ them on the cheat ]:REASON 10
|
||||
hayaosi1:0:0000:00:999:[ forums. Don't forget ]:REASON 10
|
||||
hayaosi1:0:0000:00:999:[ to search the cheat ]:REASON 10
|
||||
hayaosi1:0:0000:00:999:[ forums first though as]:REASON 10
|
||||
hayaosi1:0:0000:00:999:[ cheats may have been ]:REASON 10
|
||||
hayaosi1:0:0000:00:999:[ found in the meanwhile]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ This game should be ]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ quite straighforward ]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ enough to find cheats ]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ for. But no cheats ]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ have been submitted ]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ at the time this cheat]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ file was compiled ]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ due to the game ]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ generating zero ]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ interest from cheat ]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ finders. If you have ]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ made some cheats for ]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ this game please post ]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ them on the cheat ]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ forums. Don't forget ]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ to search the cheat ]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ forums first though as]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ cheats may have been ]:REASON 10
|
||||
hayaosi2:0:0000:00:999:[ found in the meanwhile]:REASON 10
|
||||
|
||||
; [ Heavy Barrel (US) ]
|
||||
hbarrel:0:FF8032:80:000:Invincibility PL1
|
||||
@@ -67783,9 +67783,9 @@ mrdoy:0:E0F3:01:000:One red monster PL2
|
||||
mrdoy:0:E0F3:00:000:NO red monsters PL2
|
||||
|
||||
; [ Mr Driller (DRI1/VER.A2) ]
|
||||
mrdrillr:0:002C4560:09:000:Infinite Credits
|
||||
mrdrillr:0:0021D5F8:0A:000:Infinite Lives
|
||||
mrdrillr:0:0029EBF9:4A:000:Infinite Air
|
||||
mrdrillrja2:0:002C4560:09:000:Infinite Credits
|
||||
mrdrillrja2:0:0021D5F8:0A:000:Infinite Lives
|
||||
mrdrillrja2:0:0029EBF9:4A:000:Infinite Air
|
||||
|
||||
; [ Mr Driller 2 ]
|
||||
mrdrilr2:0:0000:00:999:[ There are no cheats ]:REASON 1
|
||||
@@ -117379,38 +117379,38 @@ soulclba:0:0000:00:999:[ for it on the cheat ]:REASON 1
|
||||
soulclba:0:0000:00:999:[ forums. ]:REASON 1
|
||||
|
||||
; [ Soul Calibur (SOC14/VER.C) ]
|
||||
soulclbr:0:0000:00:999:[ There are no cheats ]:REASON 1
|
||||
soulclbr:0:0000:00:999:[ for this game as it ]:REASON 1
|
||||
soulclbr:0:0000:00:999:[ didn't work the last ]:REASON 1
|
||||
soulclbr:0:0000:00:999:[ time it was tested. ]:REASON 1
|
||||
soulclbr:0:0000:00:999:[ If the game now works ]:REASON 1
|
||||
soulclbr:0:0000:00:999:[ please request cheats ]:REASON 1
|
||||
soulclbr:0:0000:00:999:[ for it on the cheat ]:REASON 1
|
||||
soulclbr:0:0000:00:999:[ forums. ]:REASON 1
|
||||
soulclbrja2:0:0000:00:999:[ There are no cheats ]:REASON 1
|
||||
soulclbrja2:0:0000:00:999:[ for this game as it ]:REASON 1
|
||||
soulclbrja2:0:0000:00:999:[ didn't work the last ]:REASON 1
|
||||
soulclbrja2:0:0000:00:999:[ time it was tested. ]:REASON 1
|
||||
soulclbrja2:0:0000:00:999:[ If the game now works ]:REASON 1
|
||||
soulclbrja2:0:0000:00:999:[ please request cheats ]:REASON 1
|
||||
soulclbrja2:0:0000:00:999:[ for it on the cheat ]:REASON 1
|
||||
soulclbrja2:0:0000:00:999:[ forums. ]:REASON 1
|
||||
|
||||
; [ Soul Edge (SO3/VER.A) ]
|
||||
souledga:0:000EFFD4:63:000:Infinite Time
|
||||
souledga:0:000EFFD4:00:001:Finish this Round Now!
|
||||
souledga:0:002D602E:F0:000:Infinite Energy PL1
|
||||
souledga:0:002D602E:00:001:Drain All Energy Now! PL1
|
||||
souledga:0:002D6160:60:000:Always have Maximum Power PL1
|
||||
souledga:0:002D6160:00:001:Drain All Power Now! PL1
|
||||
souledga:0:002D9D72:F0:000:Infinite Energy PL2
|
||||
souledga:0:002D9D72:00:001:Drain All Energy Now! PL2
|
||||
souledga:0:002D9EA4:60:000:Always have Maximum Power PL2
|
||||
souledga:0:002D9EA4:00:001:Drain All Power Now! PL2
|
||||
souledgeua:0:000EFFD4:63:000:Infinite Time
|
||||
souledgeua:0:000EFFD4:00:001:Finish this Round Now!
|
||||
souledgeua:0:002D602E:F0:000:Infinite Energy PL1
|
||||
souledgeua:0:002D602E:00:001:Drain All Energy Now! PL1
|
||||
souledgeua:0:002D6160:60:000:Always have Maximum Power PL1
|
||||
souledgeua:0:002D6160:00:001:Drain All Power Now! PL1
|
||||
souledgeua:0:002D9D72:F0:000:Infinite Energy PL2
|
||||
souledgeua:0:002D9D72:00:001:Drain All Energy Now! PL2
|
||||
souledgeua:0:002D9EA4:60:000:Always have Maximum Power PL2
|
||||
souledgeua:0:002D9EA4:00:001:Drain All Power Now! PL2
|
||||
|
||||
; [ Soul Edge (SO1/VER.A) ]
|
||||
souledgb:0:000EFFD4:63:000:Infinite Time
|
||||
souledgb:0:000EFFD4:00:001:Finish this Round Now!
|
||||
souledgb:0:002D602E:F0:000:Infinite Energy PL1
|
||||
souledgb:0:002D602E:00:001:Drain All Energy Now! PL1
|
||||
souledgb:0:002D6160:60:000:Always have Maximum Power PL1
|
||||
souledgb:0:002D6160:00:001:Drain All Power Now! PL1
|
||||
souledgb:0:002D9D72:F0:000:Infinite Energy PL2
|
||||
souledgb:0:002D9D72:00:001:Drain All Energy Now! PL2
|
||||
souledgb:0:002D9EA4:60:000:Always have Maximum Power PL2
|
||||
souledgb:0:002D9EA4:00:001:Drain All Power Now! PL2
|
||||
souledgeja:0:000EFFD4:63:000:Infinite Time
|
||||
souledgeja:0:000EFFD4:00:001:Finish this Round Now!
|
||||
souledgeja:0:002D602E:F0:000:Infinite Energy PL1
|
||||
souledgeja:0:002D602E:00:001:Drain All Energy Now! PL1
|
||||
souledgeja:0:002D6160:60:000:Always have Maximum Power PL1
|
||||
souledgeja:0:002D6160:00:001:Drain All Power Now! PL1
|
||||
souledgeja:0:002D9D72:F0:000:Infinite Energy PL2
|
||||
souledgeja:0:002D9D72:00:001:Drain All Energy Now! PL2
|
||||
souledgeja:0:002D9EA4:60:000:Always have Maximum Power PL2
|
||||
souledgeja:0:002D9EA4:00:001:Drain All Power Now! PL2
|
||||
|
||||
; [ Soul Edge Ver. II (SO4/VER.C) ]
|
||||
souledge:0:00121F44:63:000:Infinite Time
|
||||
@@ -124535,19 +124535,19 @@ starshpp:0:0083:99:000:Infinite Fuel
|
||||
starshpp:0:00A0:0A:000:Infinite Torpedos
|
||||
|
||||
; [ Star Sweep (STP1/VER.A) ]
|
||||
starswep:0:0000:00:999:[ This game hasn't even ]:REASON 11
|
||||
starswep:0:0000:00:999:[ been looked at due to ]:REASON 11
|
||||
starswep:0:0000:00:999:[ time constraints - Too]:REASON 11
|
||||
starswep:0:0000:00:999:[ many games and so ]:REASON 11
|
||||
starswep:0:0000:00:999:[ little time. It is ]:REASON 11
|
||||
starswep:0:0000:00:999:[ even possible that ]:REASON 11
|
||||
starswep:0:0000:00:999:[ this game may be a ]:REASON 11
|
||||
starswep:0:0000:00:999:[ clone of an existing ]:REASON 11
|
||||
starswep:0:0000:00:999:[ game which may have ]:REASON 11
|
||||
starswep:0:0000:00:999:[ cheats. Please search ]:REASON 11
|
||||
starswep:0:0000:00:999:[ the cheat forums ]:REASON 11
|
||||
starswep:0:0000:00:999:[ before posting cheat ]:REASON 11
|
||||
starswep:0:0000:00:999:[ requests/cheat finding]:REASON 11
|
||||
starswepj:0:0000:00:999:[ This game hasn't even ]:REASON 11
|
||||
starswepj:0:0000:00:999:[ been looked at due to ]:REASON 11
|
||||
starswepj:0:0000:00:999:[ time constraints - Too]:REASON 11
|
||||
starswepj:0:0000:00:999:[ many games and so ]:REASON 11
|
||||
starswepj:0:0000:00:999:[ little time. It is ]:REASON 11
|
||||
starswepj:0:0000:00:999:[ even possible that ]:REASON 11
|
||||
starswepj:0:0000:00:999:[ this game may be a ]:REASON 11
|
||||
starswepj:0:0000:00:999:[ clone of an existing ]:REASON 11
|
||||
starswepj:0:0000:00:999:[ game which may have ]:REASON 11
|
||||
starswepj:0:0000:00:999:[ cheats. Please search ]:REASON 11
|
||||
starswepj:0:0000:00:999:[ the cheat forums ]:REASON 11
|
||||
starswepj:0:0000:00:999:[ before posting cheat ]:REASON 11
|
||||
starswepj:0:0000:00:999:[ requests/cheat finding]:REASON 11
|
||||
|
||||
; [ Star Trek ]
|
||||
startrek:0:CE17:04:000:Infinite Shield
|
||||
@@ -126978,61 +126978,52 @@ tekipaki:0:080C07:FF:070:Select current level PL1
|
||||
tekipaki:0:081C07:FF:070:Select current level PL2
|
||||
|
||||
; [ Tekken (TE4/VER.C) ]
|
||||
tekken:0:00267038:09:000:Infinite Credits
|
||||
:tekken:00100000:002648BC:00001730:FFFFFFFF:Infinite Time
|
||||
:tekken:00100001:002648BC:00000001:FFFFFFFF:Finish this Round Now!
|
||||
:tekken:00000000:00264AF6:0000007D:FFFFFFFF:Infinite Energy PL1
|
||||
:tekken:00000001:00264AF6:00000000:FFFFFFFF:Drain all Energy Now! PL1
|
||||
:tekken:00000000:00265B2E:0000007D:FFFFFFFF:Infinite Energy PL2
|
||||
:tekken:00000001:00265B2E:00000000:FFFFFFFF:Drain all Energy Now! PL2
|
||||
tekkenac:0:00267038:09:000:Infinite Credits
|
||||
:tekkenac:00100000:002648BC:00001730:FFFFFFFF:Infinite Time
|
||||
:tekkenac:00100001:002648BC:00000001:FFFFFFFF:Finish this Round Now!
|
||||
:tekkenac:00000000:00264AF6:0000007D:FFFFFFFF:Infinite Energy PL1
|
||||
:tekkenac:00000001:00264AF6:00000000:FFFFFFFF:Drain all Energy Now! PL1
|
||||
:tekkenac:00000000:00265B2E:0000007D:FFFFFFFF:Infinite Energy PL2
|
||||
:tekkenac:00000001:00265B2E:00000000:FFFFFFFF:Drain all Energy Now! PL2
|
||||
|
||||
; [ Tekken 2 Ver.B (TES3/VER.B) ]
|
||||
tekken2:0:00301CEC:09:000:Infinite Credits
|
||||
:tekken2:00100000:0030F174:00001732:FFFFFFFF:Infinite Time
|
||||
:tekken2:00100001:0030F174:00000001:FFFFFFFF:Finish this Round Now!
|
||||
tekken2:0:0030CA6A:7E:000:Infinite Energy PL1
|
||||
tekken2:0:0030CA6A:00:001:Drain All Energy Now! PL1
|
||||
tekken2:0:0030DEEA:7E:000:Infinite Energy PL2
|
||||
tekken2:0:0030DEEA:00:001:Drain All Energy Now! PL2
|
||||
tekken2ub:0:00301CEC:09:000:Infinite Credits
|
||||
:tekken2ub:00100000:0030F174:00001732:FFFFFFFF:Infinite Time
|
||||
:tekken2ub:00100001:0030F174:00000001:FFFFFFFF:Finish this Round Now!
|
||||
tekken2ub:0:0030CA6A:7E:000:Infinite Energy PL1
|
||||
tekken2ub:0:0030CA6A:00:001:Drain All Energy Now! PL1
|
||||
tekken2ub:0:0030DEEA:7E:000:Infinite Energy PL2
|
||||
tekken2ub:0:0030DEEA:00:001:Drain All Energy Now! PL2
|
||||
|
||||
; [ Tekken 2 Ver.B (TES2/VER.B) ]
|
||||
tekken2a:0:00301CEC:09:000:Infinite Credits
|
||||
:tekken2a:00100000:0030F174:00001732:FFFFFFFF:Infinite Time
|
||||
:tekken2a:00100001:0030F174:00000001:FFFFFFFF:Finish this Round Now!
|
||||
tekken2a:0:0030CA6A:7E:000:Infinite Energy PL1
|
||||
tekken2a:0:0030CA6A:00:001:Drain All Energy Now! PL1
|
||||
tekken2a:0:0030DEEA:7E:000:Infinite Energy PL2
|
||||
tekken2a:0:0030DEEA:00:001:Drain All Energy Now! PL2
|
||||
tekken2b:0:00301CEC:09:000:Infinite Credits
|
||||
:tekken2b:00100000:0030F174:00001732:FFFFFFFF:Infinite Time
|
||||
:tekken2b:00100001:0030F174:00000001:FFFFFFFF:Finish this Round Now!
|
||||
tekken2b:0:0030CA6A:7E:000:Infinite Energy PL1
|
||||
tekken2b:0:0030CA6A:00:001:Drain All Energy Now! PL1
|
||||
tekken2b:0:0030DEEA:7E:000:Infinite Energy PL2
|
||||
tekken2b:0:0030DEEA:00:001:Drain All Energy Now! PL2
|
||||
|
||||
; [ Tekken 2 (TES2/VER.A) ]
|
||||
tekken2b:0:002FA4A0:09:000:Infinite Credits
|
||||
:tekken2b:00100000:00307928:00001732:FFFFFFFF:Infinite Time
|
||||
:tekken2b:00100001:00307928:00000001:FFFFFFFF:Finish this Round Now!
|
||||
tekken2b:0:0030521E:7E:000:Infinite Energy PL1
|
||||
tekken2b:0:0030521E:00:001:Drain All Energy Now! PL1
|
||||
tekken2b:0:0030669E:7E:000:Infinite Energy PL2
|
||||
tekken2b:0:0030669E:00:001:Drain All Energy Now! PL2
|
||||
tekken2a:0:002FA4A0:09:000:Infinite Credits
|
||||
:tekken2a:00100000:00307928:00001732:FFFFFFFF:Infinite Time
|
||||
:tekken2a:00100001:00307928:00000001:FFFFFFFF:Finish this Round Now!
|
||||
tekken2a:0:0030521E:7E:000:Infinite Energy PL1
|
||||
tekken2a:0:0030521E:00:001:Drain All Energy Now! PL1
|
||||
tekken2a:0:0030669E:7E:000:Infinite Energy PL2
|
||||
tekken2a:0:0030669E:00:001:Drain All Energy Now! PL2
|
||||
|
||||
; [ Tekken 3 (TET1/VER.E1) ]
|
||||
tekken3:0:0021FB8C:32:000:Infinite Time
|
||||
tekken3:0:0021FB8D:17:500:Infinite Time (2/2)
|
||||
tekken3:0:0021FB8C:01:001:Finish this Round Now!
|
||||
tekken3:0:0021FB8D:00:501:Finish this Round Now! (2/2)
|
||||
tekken3:0:0031E492:82:000:Infinite Energy PL1
|
||||
tekken3:0:0031E492:00:001:Drain All Energy Now! PL1
|
||||
tekken3:0:0031FF76:82:000:Infinite Energy PL2
|
||||
tekken3:0:0031FF76:00:001:Drain All Energy Now! PL2
|
||||
tekken3je1:0:0021FB8C:32:000:Infinite Time
|
||||
tekken3je1:0:0021FB8D:17:500:Infinite Time (2/2)
|
||||
tekken3je1:0:0021FB8C:01:001:Finish this Round Now!
|
||||
tekken3je1:0:0021FB8D:00:501:Finish this Round Now! (2/2)
|
||||
tekken3je1:0:0031E492:82:000:Infinite Energy PL1
|
||||
tekken3je1:0:0031E492:00:001:Drain All Energy Now! PL1
|
||||
tekken3je1:0:0031FF76:82:000:Infinite Energy PL2
|
||||
tekken3je1:0:0031FF76:00:001:Drain All Energy Now! PL2
|
||||
|
||||
; [ Tekken (TE2/VER.B) ]
|
||||
tekkena:0:00266CE0:09:000:Infinite Credits
|
||||
:tekkena:00100000:00264564:00001730:FFFFFFFF:Infinite Time
|
||||
:tekkena:00100001:00264564:00000001:FFFFFFFF:Finish this Round Now!
|
||||
:tekkena:00000000:0026479E:0000007D:FFFFFFFF:Infinite Energy PL1
|
||||
:tekkena:00000001:0026479E:00000000:FFFFFFFF:Drain all Energy Now! PL1
|
||||
:tekkena:00000000:002657D6:0000007D:FFFFFFFF:Infinite Energy PL2
|
||||
:tekkena:00000001:002657D6:00000000:FFFFFFFF:Drain all Energy Now! PL2
|
||||
|
||||
; [ Tekken (TE1/VER.B) ]
|
||||
tekkenb:0:00266CE0:09:000:Infinite Credits
|
||||
:tekkenb:00100000:00264564:00001730:FFFFFFFF:Infinite Time
|
||||
:tekkenb:00100001:00264564:00000001:FFFFFFFF:Finish this Round Now!
|
||||
@@ -127041,15 +127032,24 @@ tekkenb:0:00266CE0:09:000:Infinite Credits
|
||||
:tekkenb:00000000:002657D6:0000007D:FFFFFFFF:Infinite Energy PL2
|
||||
:tekkenb:00000001:002657D6:00000000:FFFFFFFF:Drain all Energy Now! PL2
|
||||
|
||||
; [ Tekken (TE1/VER.B) ]
|
||||
tekkenjb:0:00266CE0:09:000:Infinite Credits
|
||||
:tekkenjb:00100000:00264564:00001730:FFFFFFFF:Infinite Time
|
||||
:tekkenjb:00100001:00264564:00000001:FFFFFFFF:Finish this Round Now!
|
||||
:tekkenjb:00000000:0026479E:0000007D:FFFFFFFF:Infinite Energy PL1
|
||||
:tekkenjb:00000001:0026479E:00000000:FFFFFFFF:Drain all Energy Now! PL1
|
||||
:tekkenjb:00000000:002657D6:0000007D:FFFFFFFF:Infinite Energy PL2
|
||||
:tekkenjb:00000001:002657D6:00000000:FFFFFFFF:Drain all Energy Now! PL2
|
||||
|
||||
; [ Tekken Tag Tournament (TEG3/VER.B) ]
|
||||
tekkentt:0:0000:00:999:[ There are no cheats ]:REASON 1
|
||||
tekkentt:0:0000:00:999:[ for this game as it ]:REASON 1
|
||||
tekkentt:0:0000:00:999:[ didn't work the last ]:REASON 1
|
||||
tekkentt:0:0000:00:999:[ time it was tested. ]:REASON 1
|
||||
tekkentt:0:0000:00:999:[ If the game now works ]:REASON 1
|
||||
tekkentt:0:0000:00:999:[ please request cheats ]:REASON 1
|
||||
tekkentt:0:0000:00:999:[ for it on the cheat ]:REASON 1
|
||||
tekkentt:0:0000:00:999:[ forums. ]:REASON 1
|
||||
tektagtub:0:0000:00:999:[ There are no cheats ]:REASON 1
|
||||
tektagtub:0:0000:00:999:[ for this game as it ]:REASON 1
|
||||
tektagtub:0:0000:00:999:[ didn't work the last ]:REASON 1
|
||||
tektagtub:0:0000:00:999:[ time it was tested. ]:REASON 1
|
||||
tektagtub:0:0000:00:999:[ If the game now works ]:REASON 1
|
||||
tektagtub:0:0000:00:999:[ please request cheats ]:REASON 1
|
||||
tektagtub:0:0000:00:999:[ for it on the cheat ]:REASON 1
|
||||
tektagtub:0:0000:00:999:[ forums. ]:REASON 1
|
||||
|
||||
; [ Tel Jan ]
|
||||
teljan:0:06002FD7:09:000:Infinite Credits
|
||||
@@ -138936,17 +138936,17 @@ xenophob:0:0607ED:FF:000:Infinite Health PL2
|
||||
xenophob:0:0608AD:FF:000:Infinite Health PL3
|
||||
|
||||
; [ Xevious 3D/G (XV31/VER.A) ]
|
||||
xevi3dg:0:000EE8C0:09:000:Infinite Credits
|
||||
xevi3dg:0:00150DC8:06:000:Infinite Lives PL1
|
||||
xevi3dg:0:00126358:01:000:Invincibility PL1
|
||||
xevi3dg:0:00150DB0:01:000:Always have Laser Gun PL1
|
||||
xevi3dg:0:00150DB0:02:000:Always have Homing Weapon PL1
|
||||
xevi3dg:0:00115BDC:02:000:Maximum Fire Power PL1
|
||||
xevi3dg:0:00150DCC:06:000:Infinite Lives PL2
|
||||
xevi3dg:0:00126204:01:000:Invincibility PL2
|
||||
xevi3dg:0:00150DB4:01:000:Always have Laser Gun PL2
|
||||
xevi3dg:0:00150DB4:02:000:Always have Homing Weapon PL2
|
||||
xevi3dg:0:001171B0:02:000:Maximum Fire Power PL2
|
||||
xevi3dgj:0:000EE8C0:09:000:Infinite Credits
|
||||
xevi3dgj:0:00150DC8:06:000:Infinite Lives PL1
|
||||
xevi3dgj:0:00126358:01:000:Invincibility PL1
|
||||
xevi3dgj:0:00150DB0:01:000:Always have Laser Gun PL1
|
||||
xevi3dgj:0:00150DB0:02:000:Always have Homing Weapon PL1
|
||||
xevi3dgj:0:00115BDC:02:000:Maximum Fire Power PL1
|
||||
xevi3dgj:0:00150DCC:06:000:Infinite Lives PL2
|
||||
xevi3dgj:0:00126204:01:000:Invincibility PL2
|
||||
xevi3dgj:0:00150DB4:01:000:Always have Laser Gun PL2
|
||||
xevi3dgj:0:00150DB4:02:000:Always have Homing Weapon PL2
|
||||
xevi3dgj:0:001171B0:02:000:Maximum Fire Power PL2
|
||||
|
||||
; [ Xevios ]
|
||||
xevios:0:8183:09:000:Infinite Lives
|
||||
|
||||
@@ -1688,6 +1688,7 @@ batriderhk:
|
||||
|
||||
mrdrillrj:
|
||||
mrdrillr:
|
||||
mrdrillrja2:
|
||||
0:201038:288:76:76
|
||||
|
||||
sfiii3:
|
||||
@@ -1829,6 +1830,7 @@ spf2xjd:
|
||||
spf2ta:
|
||||
spf2th:
|
||||
spf2td:
|
||||
spf2xpri:
|
||||
0:ffd7aa:4e:00:02
|
||||
0:ff8081:1:01:01
|
||||
|
||||
@@ -3270,7 +3272,7 @@ theglob2:
|
||||
0:7c4b:1:01:01
|
||||
0:7c51:1:80:80
|
||||
|
||||
beastf:
|
||||
beastfp:
|
||||
0:4c46:3c:4d:00
|
||||
0:4c8a:1:01:01
|
||||
0:4cb0:1:15:15
|
||||
|
||||
+24
-24
@@ -20586,7 +20586,7 @@ Commodore Amiga (1990)
|
||||
$end
|
||||
|
||||
|
||||
$info=beastf,
|
||||
$info=beastf,beastfp,
|
||||
$bio
|
||||
|
||||
Beastie Feastie (c) 1984 Epos Corporation.
|
||||
@@ -39674,7 +39674,7 @@ Graphic : Kim Eun Ae, Hong Young Joo, Whang O-Sik, Hong Dae Hyun
|
||||
$end
|
||||
|
||||
|
||||
$info=chplft,chplftb,chplftbl,
|
||||
$info=choplift,chopliftu,chopliftbl,
|
||||
$bio
|
||||
|
||||
Choplifter (c) 1985 Sega.
|
||||
@@ -49927,7 +49927,7 @@ The title of this game translates from Japanese as 'Hanafuda at the Apartments'.
|
||||
$end
|
||||
|
||||
|
||||
$info=danceyes,
|
||||
$info=danceyes,danceyesu,danceyesj,
|
||||
$bio
|
||||
|
||||
Dancing Eyes (c) 08/1996 Namco.
|
||||
@@ -63256,7 +63256,7 @@ This game is also known as "Dataeast's Hoops".
|
||||
$end
|
||||
|
||||
|
||||
$info=dunkmnia,dunkmnic,
|
||||
$info=dunkmnia,dunkmniajc,
|
||||
$bio
|
||||
|
||||
Dunk Mania (c) 1995 Namco.
|
||||
@@ -68525,7 +68525,7 @@ Designed by : Luis Sanchez
|
||||
$end
|
||||
|
||||
|
||||
$info=ehrgeiz,ehrgeiza,
|
||||
$info=ehrgeiz,ehrgeizua,ehrgeizja,
|
||||
$bio
|
||||
|
||||
EZ : Ehrgeiz - God Bless The Ring (c) 1998 Square / Namco.
|
||||
@@ -71900,7 +71900,7 @@ Buttons : 2
|
||||
$end
|
||||
|
||||
|
||||
$info=fgtlayer,
|
||||
$info=fgtlayer,fgtlayerja,
|
||||
$bio
|
||||
|
||||
Fighting Layer (c) 12/1998 Arika.
|
||||
@@ -95537,7 +95537,7 @@ King Records released a limited-edition soundtrack album for this game (Konami G
|
||||
$end
|
||||
|
||||
|
||||
$info=hayaosi1,
|
||||
$info=hayaosi2,
|
||||
$bio
|
||||
|
||||
Hayaoshi Quiz Ouza Ketteisen (c) 1994 Jaleco.
|
||||
@@ -100624,7 +100624,7 @@ Sega Saturn (1996, "Sega Ages : Rouka ni Ichidant-R")
|
||||
$end
|
||||
|
||||
|
||||
$info=47pie2,47pie2o,
|
||||
$info=suchie2,suchie2o,
|
||||
$bio
|
||||
|
||||
Idol Janshi Suchi-Pai II (c) 1994 Jaleco.
|
||||
@@ -146695,7 +146695,7 @@ MSX (1985)
|
||||
$end
|
||||
|
||||
|
||||
$info=mrdrillr,
|
||||
$info=mrdrillr,mrdrillrja2,
|
||||
$bio
|
||||
|
||||
Mr. Driller (c) 1999 Namco.
|
||||
@@ -153222,7 +153222,7 @@ PC [MS Windows] (2005, "Taito Legends")
|
||||
$end
|
||||
|
||||
|
||||
$info=nzerotea,
|
||||
$info=nzeroteam,nzeroteama,nzeroteamb,zerotm2k,
|
||||
$bio
|
||||
|
||||
New Zero Team (c) 1993 Seibu Kaihatsu.
|
||||
@@ -168550,7 +168550,7 @@ Sony PlayStation 2 (2002, "Gunvari Collection + Time Crisis")
|
||||
$end
|
||||
|
||||
|
||||
$info=ptblank2,
|
||||
$info=ptblank2,ptblank2a,ptblank2b,ptblank2c,ptblank2ua,gunbarla,
|
||||
$bio
|
||||
|
||||
Point Blank 2 (c) 1999 Namco.
|
||||
@@ -182610,7 +182610,7 @@ PC [MS-DOS, CD-ROM]
|
||||
$end
|
||||
|
||||
|
||||
$info=raidndx,raidndxa,raidndxb,raidndxj,raidndxm,
|
||||
$info=raidendx,raidendxg,raidendxpt,raidendxa1,raidendxa2,raidendxk,raidendxu,raidendxnl,raidendxj,raidendxja,raidendxch,r2dx_v33,r2dx_v33_r2,
|
||||
$bio
|
||||
|
||||
Raiden DX (c) 1994 Seibu Kaihatsu.
|
||||
@@ -183143,7 +183143,7 @@ Level 15 : Before the boss appears, do not shoot any small tanks. Two small tank
|
||||
$end
|
||||
|
||||
|
||||
$info=raiden2,raiden2a,raiden2b,raiden2c,raiden2e,
|
||||
$info=raiden2,raiden2g,raiden2gb,raiden2hk,raiden2j,raiden2sw,raiden2u,raiden2f,raiden2nl,raiden2es,raiden2i,raiden2au,raiden2e,raiden2eub,raiden2eua,raiden2eg,raiden2eup,raiden2ea,raiden2eu,raiden2k,raiden2dx,
|
||||
$bio
|
||||
|
||||
Raiden II (c) 1993 Seibu Kaihatsu.
|
||||
@@ -187724,7 +187724,7 @@ Total planner / Total cordinator : The Alive
|
||||
$end
|
||||
|
||||
|
||||
$info=revenger,
|
||||
$info=revenger,revngr84,
|
||||
$bio
|
||||
|
||||
Revenger (c) 1984 Epos.
|
||||
@@ -210976,7 +210976,7 @@ Sega Saturn (1997)
|
||||
$end
|
||||
|
||||
|
||||
$info=soulclbr,soulclba,soulclbb,
|
||||
$info=soulclbr,soulclbrab,soulclbrac,soulclbrub,soulclbruc,soulclbrja2,soulclbrjb,soulclbrjc,
|
||||
$bio
|
||||
|
||||
Soul Calibur (c) 07/1998 Namco.
|
||||
@@ -211061,7 +211061,7 @@ Sega Dreamcast (1999) : The new Weapon Master mode made it's debut in this versi
|
||||
$end
|
||||
|
||||
|
||||
$info=souledga,souledgb,souledgc,
|
||||
$info=souledgea,souledgeua,souledgeja,
|
||||
$bio
|
||||
|
||||
Soul Edge (c) 1995 Namco.
|
||||
@@ -211188,7 +211188,7 @@ Sony PlayStation (1996)
|
||||
$end
|
||||
|
||||
|
||||
$info=souledge,
|
||||
$info=souledge,souledgeuc,
|
||||
$bio
|
||||
|
||||
Soul Edge Ver. II (c) 1996 Namco.
|
||||
@@ -219296,7 +219296,7 @@ Sega Saturn (1997, "Sega Memorial Selection Vol.2")
|
||||
$end
|
||||
|
||||
|
||||
$info=starswep,
|
||||
$info=starswep,starswepj,
|
||||
$bio
|
||||
|
||||
Star Sweep (c) 07/1997 Axela.
|
||||
@@ -243474,7 +243474,7 @@ Music composed by : Tomoaki Takanohashi
|
||||
$end
|
||||
|
||||
|
||||
$info=tekken,tekkena,tekkenb,tekkenc,
|
||||
$info=tekken,tekkenac,tekkenb,tekkenjb,
|
||||
$bio
|
||||
|
||||
Tekken (c) 12/1994 Namco.
|
||||
@@ -243635,7 +243635,7 @@ Sony PlayStation 2 (2005, "NamCollection") : Japan release only.
|
||||
$end
|
||||
|
||||
|
||||
$info=tekken2,tekken2a,tekken2b,
|
||||
$info=tekken2,tekken2b,tekken2ud,tekken2ub,tekken2jc,tekken2jb,tekken2a,tekken2ua,
|
||||
$bio
|
||||
|
||||
Tekken 2 (c) 08/1995 Namco.
|
||||
@@ -243867,7 +243867,7 @@ Sony PlayStation 2 (2005, "Tekken 5 Ultimate Collectors Edition")
|
||||
$end
|
||||
|
||||
|
||||
$info=tekken3,tekken3a,
|
||||
$info=tekken3,tekken3je1,
|
||||
$bio
|
||||
|
||||
Tekken 3 (c) 1996 Namco.
|
||||
@@ -244067,7 +244067,7 @@ Sony PlayStation 2 (2005, "Tekken 5 Ultimate Collectors Edition")
|
||||
$end
|
||||
|
||||
|
||||
$info=tektagt,tektagta,
|
||||
$info=tektagt,tektagtub,tektagtuc1,tektagtjc1,
|
||||
$bio
|
||||
|
||||
Tekken Tag Tournament (c) 1999 Namco.
|
||||
@@ -275757,7 +275757,7 @@ F.A.Q. by Kevin Butler A.K.A. War Doc
|
||||
$end
|
||||
|
||||
|
||||
$info=xevi3dg,
|
||||
$info=xevi3dg,xevi3dga,xevi3dgj,
|
||||
$bio
|
||||
|
||||
Xevious 3D/G (c) 04/1995 Namco.
|
||||
@@ -278372,7 +278372,7 @@ This game is known in Japan as "Gekitsui Oh".
|
||||
$end
|
||||
|
||||
|
||||
$info=zeroteam,zeroteaa,zeroteab,
|
||||
$info=zeroteam,zeroteama,zeroteamb,zeroteamc,zeroteamd,zeroteame,zeroteams,zeroteamsr,
|
||||
$bio
|
||||
|
||||
Zero Team (c) 1993 Seibu Kaihatsu.
|
||||
|
||||
+26778
-2870
File diff suppressed because it is too large.
Load diff
+96
-87
@@ -16,31 +16,6 @@
|
||||
/*#define LOG_LOAD */
|
||||
|
||||
|
||||
const char *chd_error_text[] =
|
||||
{
|
||||
"CHDERR_NONE",
|
||||
"CHDERR_NO_INTERFACE",
|
||||
"CHDERR_OUT_OF_MEMORY",
|
||||
"CHDERR_INVALID_FILE",
|
||||
"CHDERR_INVALID_PARAMETER",
|
||||
"CHDERR_INVALID_DATA",
|
||||
"CHDERR_FILE_NOT_FOUND",
|
||||
"CHDERR_REQUIRES_PARENT",
|
||||
"CHDERR_FILE_NOT_WRITEABLE",
|
||||
"CHDERR_READ_ERROR",
|
||||
"CHDERR_WRITE_ERROR",
|
||||
"CHDERR_CODEC_ERROR",
|
||||
"CHDERR_INVALID_PARENT",
|
||||
"CHDERR_HUNK_OUT_OF_RANGE",
|
||||
"CHDERR_DECOMPRESSION_ERROR",
|
||||
"CHDERR_COMPRESSION_ERROR",
|
||||
"CHDERR_CANT_CREATE_FILE",
|
||||
"CHDERR_CANT_VERIFY",
|
||||
"CHDERR_NOT_SUPPORTED",
|
||||
"CHDERR_METADATA_NOT_FOUND",
|
||||
"CHDERR_INVALID_METADATA_SIZE",
|
||||
"CHDERR_UNSUPPORTED_VERSION"
|
||||
};
|
||||
/***************************************************************************
|
||||
Constants
|
||||
***************************************************************************/
|
||||
@@ -182,7 +157,7 @@ size_t generic_nvram_size;
|
||||
data8_t *generic_nvram;
|
||||
|
||||
/* disks */
|
||||
static struct chd_file *disk_handle[4];
|
||||
static struct hard_disk_file *disk_handle[4];
|
||||
|
||||
/* system BIOS */
|
||||
static int system_bios;
|
||||
@@ -1051,7 +1026,7 @@ void end_resource_tracking(void)
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
struct chd_file *get_disk_handle(int diskindex)
|
||||
struct hard_disk_file *get_disk_handle(int diskindex)
|
||||
{
|
||||
return disk_handle[diskindex];
|
||||
}
|
||||
@@ -1824,11 +1799,14 @@ static int process_disk_entries(struct rom_load_data *romdata, const struct RomM
|
||||
/* handle files */
|
||||
if (ROMENTRY_ISFILE(romp))
|
||||
{
|
||||
struct chd_file *source, *diff = NULL;
|
||||
struct chd_header header;
|
||||
const struct GameDriver *drv;
|
||||
struct hard_disk_file *disk;
|
||||
mame_file *source = NULL, *diff = NULL;
|
||||
UINT8 *legacydata = NULL;
|
||||
UINT32 legacysize = 0;
|
||||
char filename[1024], *c;
|
||||
char acthash[HASH_BUF_SIZE];
|
||||
int err;
|
||||
char datahash[HASH_BUF_SIZE], imagehash[HASH_BUF_SIZE];
|
||||
const char *error;
|
||||
|
||||
/* make the filename of the source */
|
||||
strcpy(filename, ROM_GETNAME(romp));
|
||||
@@ -1838,83 +1816,114 @@ static int process_disk_entries(struct rom_load_data *romdata, const struct RomM
|
||||
else
|
||||
strcat(filename, ".chd");
|
||||
|
||||
/* first open the source drive */
|
||||
/* look for it in the ROM path, up the chain through the parents */
|
||||
log_cb(RETRO_LOG_INFO, LOGPRE "Opening disk image: %s\n", filename);
|
||||
source = chd_open(filename, 0, NULL);
|
||||
for (drv = Machine->gamedrv; drv != NULL && source == NULL; drv = drv->clone_of)
|
||||
source = mame_fopen(drv->name, filename, FILETYPE_IMAGE, 0);
|
||||
if (!source)
|
||||
{
|
||||
if (chd_get_last_error() == CHDERR_UNSUPPORTED_VERSION)
|
||||
log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s UNSUPPORTED CHD VERSION\n", filename);
|
||||
else
|
||||
log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s NOT FOUND\n", filename);
|
||||
log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s NOT FOUND\n", filename);
|
||||
romdata->errors++;
|
||||
romp++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* get the header and extract the MD5/SHA1 */
|
||||
header = *chd_get_header(source);
|
||||
hash_data_clear(acthash);
|
||||
hash_data_insert_binary_checksum(acthash, HASH_MD5, header.md5);
|
||||
hash_data_insert_binary_checksum(acthash, HASH_SHA1, header.sha1);
|
||||
|
||||
/* verify the MD5 */
|
||||
if (!hash_data_is_equal(ROM_GETHASHDATA(romp), acthash, 0))
|
||||
{
|
||||
log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s WRONG CHECKSUMS:\n", filename);
|
||||
dump_wrong_and_correct_checksums(romdata, ROM_GETHASHDATA(romp), acthash);
|
||||
romdata->warnings++;
|
||||
}
|
||||
|
||||
/* if not read-only, make the diff file */
|
||||
/* if not read-only, open or create the differencing file */
|
||||
if (!DISK_ISREADONLY(romp))
|
||||
{
|
||||
/* make the filename of the diff */
|
||||
strcpy(filename, ROM_GETNAME(romp));
|
||||
c = strrchr(filename, '.');
|
||||
char diffname[1024];
|
||||
|
||||
strcpy(diffname, ROM_GETNAME(romp));
|
||||
c = strrchr(diffname, '.');
|
||||
if (c)
|
||||
strcpy(c, ".dif");
|
||||
else
|
||||
strcat(filename, ".dif");
|
||||
strcat(diffname, ".dif");
|
||||
|
||||
log_cb(RETRO_LOG_INFO, LOGPRE "Opening differencing image: %s\n", diffname);
|
||||
diff = mame_fopen(NULL, diffname, FILETYPE_IMAGE_DIFF, 1);
|
||||
|
||||
/* one made by older versions of the core (a CHD v3): keep its */
|
||||
/* contents to import them, and the file itself as <name>.dif.old */
|
||||
if (diff)
|
||||
{
|
||||
UINT8 tag[8];
|
||||
UINT64 size = mame_fsize(diff);
|
||||
|
||||
mame_fseek(diff, 0, SEEK_SET);
|
||||
if (size >= sizeof(tag) && size < 0x80000000 &&
|
||||
mame_fread(diff, tag, sizeof(tag)) == sizeof(tag) && memcmp(tag, "MComprHD", 8) == 0)
|
||||
{
|
||||
char oldname[1024 + 4];
|
||||
|
||||
legacydata = malloc((size_t)size);
|
||||
if (legacydata)
|
||||
{
|
||||
mame_fseek(diff, 0, SEEK_SET);
|
||||
if (mame_fread(diff, legacydata, (UINT32)size) == size)
|
||||
legacysize = (UINT32)size;
|
||||
else
|
||||
{
|
||||
free(legacydata);
|
||||
legacydata = NULL;
|
||||
}
|
||||
}
|
||||
mame_fclose(diff);
|
||||
|
||||
/* keep the file even if it could not be read, so nothing is lost */
|
||||
sprintf(oldname, "%s.old", diffname);
|
||||
if (osd_rename(FILETYPE_IMAGE_DIFF, diffname, oldname))
|
||||
log_cb(RETRO_LOG_INFO, LOGPRE "Old-format differencing image kept as %s\n", oldname);
|
||||
else
|
||||
log_cb(RETRO_LOG_WARN, LOGPRE "Old-format differencing image could not be kept as %s\n", oldname);
|
||||
diff = mame_fopen(NULL, diffname, FILETYPE_IMAGE_DIFF, 1);
|
||||
}
|
||||
mame_fseek(diff, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
/* try to open the diff */
|
||||
log_cb(RETRO_LOG_INFO, LOGPRE "Opening differencing image: %s\n", filename);
|
||||
diff = chd_open(filename, 1, source);
|
||||
if (!diff)
|
||||
{
|
||||
/* didn't work; try creating it instead */
|
||||
log_cb(RETRO_LOG_INFO, LOGPRE "Creating differencing image: %s\n", filename);
|
||||
err = chd_create(filename, 0, 0, CHDCOMPRESSION_NONE, source);
|
||||
if (err != CHDERR_NONE)
|
||||
{
|
||||
if (chd_get_last_error() == CHDERR_UNSUPPORTED_VERSION)
|
||||
log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s UNSUPPORTED CHD VERSION\n", filename);
|
||||
else
|
||||
log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s: CAN'T CREATE DIFF FILE Error code %s\n", filename, chd_error_text[err]);
|
||||
romdata->errors++;
|
||||
romp++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* open the newly-created diff file */
|
||||
log_cb(RETRO_LOG_INFO, LOGPRE "Opening new differencing image: %s\n", filename);
|
||||
diff = chd_open(filename, 1, source);
|
||||
if (!diff)
|
||||
{
|
||||
if (chd_get_last_error() == CHDERR_UNSUPPORTED_VERSION)
|
||||
log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s UNSUPPORTED CHD VERSION\n", filename);
|
||||
else
|
||||
log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s: CAN'T OPEN DIFF FILE Error code %s\n", filename, chd_error_text[err]);
|
||||
romdata->errors++;
|
||||
romp++;
|
||||
continue;
|
||||
}
|
||||
log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s: CAN'T OPEN OR CREATE DIFF FILE\n", diffname);
|
||||
free(legacydata);
|
||||
mame_fclose(source);
|
||||
romdata->errors++;
|
||||
romp++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* open the disk */
|
||||
disk = hard_disk_open(source, diff, &error);
|
||||
if (!disk)
|
||||
{
|
||||
log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s: CAN'T OPEN DISK IMAGE (%s)\n", filename, error);
|
||||
free(legacydata);
|
||||
romdata->errors++;
|
||||
romp++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* bring over what the game wrote with older versions of the core */
|
||||
if (legacydata)
|
||||
{
|
||||
hard_disk_import_legacy_diff(disk, legacydata, legacysize);
|
||||
free(legacydata);
|
||||
}
|
||||
|
||||
/* verify the checksums: older sets list those of the data (the same for */
|
||||
/* every CHD version of a dump), current MAME the one of a v5 image */
|
||||
hard_disk_get_hashes(disk, datahash, imagehash);
|
||||
if (!hash_data_is_equal(ROM_GETHASHDATA(romp), datahash, 0) &&
|
||||
!hash_data_is_equal(ROM_GETHASHDATA(romp), imagehash, 0))
|
||||
{
|
||||
log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s WRONG CHECKSUMS:\n", filename);
|
||||
dump_wrong_and_correct_checksums(romdata, ROM_GETHASHDATA(romp), datahash);
|
||||
romdata->warnings++;
|
||||
}
|
||||
|
||||
/* we're okay, set the handle */
|
||||
log_cb(RETRO_LOG_DEBUG, LOGPRE "Assigning to handle %d\n", DISK_GETINDEX(romp));
|
||||
disk_handle[DISK_GETINDEX(romp)] = DISK_ISREADONLY(romp) ? source : diff;
|
||||
disk_handle[DISK_GETINDEX(romp)] = disk;
|
||||
romp++;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -457,7 +457,7 @@ struct mame_bitmap *auto_bitmap_alloc(int width,int height);
|
||||
struct mame_bitmap *auto_bitmap_alloc_depth(int width,int height,int depth);
|
||||
|
||||
/* disk handling */
|
||||
struct chd_file *get_disk_handle(int diskindex);
|
||||
struct hard_disk_file *get_disk_handle(int diskindex);
|
||||
|
||||
/* ROM processing */
|
||||
int rom_load(const struct RomModule *romp);
|
||||
|
||||
@@ -14699,6 +14699,37 @@ const char *sf_get_ctrl_name(int type)
|
||||
return "";
|
||||
}
|
||||
|
||||
const struct ControlInfo sfrush_ctrl =
|
||||
{
|
||||
false, /* 45_degree_rotation for joystick(s) */
|
||||
false, /* alternating_controls */
|
||||
false, /* mirrored_controls */
|
||||
"Wheel, accelerator and brake on player 1 (the shifter stays in the last gear chosen). Clutch, music and the four track buttons are on player 2.", /* control_details */
|
||||
&sfrush_get_ctrl_name
|
||||
};
|
||||
|
||||
const char *sfrush_get_ctrl_name(int type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case IPT_BUTTON1: return BTN1 "1st Gear / Music";
|
||||
case IPT_BUTTON2: return BTN2 "2nd Gear / Track 1";
|
||||
case IPT_BUTTON3: return BTN3 "3rd Gear / Track 2";
|
||||
case IPT_BUTTON4: return BTN4 "4th Gear / Track 3";
|
||||
case IPT_BUTTON5: return BTN5 "Track 4";
|
||||
case IPT_BUTTON7: return BTN7 "View 1";
|
||||
case IPT_BUTTON8: return BTN8 "View 2";
|
||||
case IPT_BUTTON9: return "B9: View 3";
|
||||
case IPT_BUTTON10: return "B10: Reverse";
|
||||
case IPT_PEDAL: return "Accelerator / Clutch";
|
||||
case IPT_PEDAL2: return "Brake";
|
||||
case IPT_PADDLE: return "Steer Left";
|
||||
case (IPT_PADDLE + IPT_EXTENSION): return "Steer Right";
|
||||
} /* end of switch */
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
const struct ControlInfo sfa2_ctrl =
|
||||
{
|
||||
false, /* 45_degree_rotation for joystick(s) */
|
||||
|
||||
@@ -2440,6 +2440,9 @@ const char *stratgyx_get_ctrl_name(int type);
|
||||
extern const struct ControlInfo sf_ctrl;
|
||||
const char *sf_get_ctrl_name(int type);
|
||||
|
||||
extern const struct ControlInfo sfrush_ctrl;
|
||||
const char *sfrush_get_ctrl_name(int type);
|
||||
|
||||
extern const struct ControlInfo sfa2_ctrl;
|
||||
const char *sfa2_get_ctrl_name(int type);
|
||||
|
||||
|
||||
+789
-45
@@ -368,6 +368,27 @@ static void wr_px(INT32 val) { adsp2100.px = val; }
|
||||
static void wr_ifc(INT32 val)
|
||||
{
|
||||
adsp2100.ifc = val;
|
||||
#if (HAS_ADSP2181)
|
||||
if (chip_type == CHIP_TYPE_ADSP2181)
|
||||
{
|
||||
if (val & 0x0002) adsp2100.irq_latch[ADSP2181_IRQ0] = 0;
|
||||
if (val & 0x0004) adsp2100.irq_latch[ADSP2181_IRQ1] = 0;
|
||||
if (val & 0x0008) adsp2100.irq_latch[ADSP2181_BDMA] = 0;
|
||||
if (val & 0x0010) adsp2100.irq_latch[ADSP2181_IRQE] = 0;
|
||||
if (val & 0x0020) adsp2100.irq_latch[ADSP2181_SPORT0_RX] = 0;
|
||||
if (val & 0x0040) adsp2100.irq_latch[ADSP2181_SPORT0_TX] = 0;
|
||||
if (val & 0x0080) adsp2100.irq_latch[ADSP2181_IRQ2] = 0;
|
||||
if (val & 0x0200) adsp2100.irq_latch[ADSP2181_IRQ0] = 1;
|
||||
if (val & 0x0400) adsp2100.irq_latch[ADSP2181_IRQ1] = 1;
|
||||
if (val & 0x0800) adsp2100.irq_latch[ADSP2181_BDMA] = 1;
|
||||
if (val & 0x1000) adsp2100.irq_latch[ADSP2181_IRQE] = 1;
|
||||
if (val & 0x2000) adsp2100.irq_latch[ADSP2181_SPORT0_RX] = 1;
|
||||
if (val & 0x4000) adsp2100.irq_latch[ADSP2181_SPORT0_TX] = 1;
|
||||
if (val & 0x8000) adsp2100.irq_latch[ADSP2181_IRQ2] = 1;
|
||||
check_irqs();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (val & 0x002) adsp2100.irq_latch[ADSP2101_IRQ0] = 0;
|
||||
if (val & 0x004) adsp2100.irq_latch[ADSP2101_IRQ1] = 0;
|
||||
if (val & 0x008) adsp2100.irq_latch[ADSP2101_SPORT0_RX] = 0;
|
||||
@@ -384,6 +405,25 @@ static void wr_tx0(INT32 val) { if (sport_tx_callback) (*sport_tx_callback)(0, v
|
||||
static void wr_tx1(INT32 val) { if (sport_tx_callback) (*sport_tx_callback)(1, val); }
|
||||
static void wr_owrctr(INT32 val) { adsp2100.cntr = val & 0x3fff; }
|
||||
static void wr_topstack(INT32 val) { pc_stack_push_val(val & 0x3fff); }
|
||||
/* ADSP-2181: the memory overlay registers (group 1, 14 and 15) */
|
||||
static void wr_pmovlay(INT32 val)
|
||||
{
|
||||
#if (HAS_ADSP2181)
|
||||
if (chip_type == CHIP_TYPE_ADSP2181)
|
||||
adsp2100.pmovlay = val & 0x3fff;
|
||||
#endif
|
||||
}
|
||||
static void wr_dmovlay(INT32 val)
|
||||
{
|
||||
#if (HAS_ADSP2181)
|
||||
if (chip_type == CHIP_TYPE_ADSP2181)
|
||||
{
|
||||
adsp2100.dmovlay = val & 0x3fff;
|
||||
if (dmovlay_callback)
|
||||
(*dmovlay_callback)(adsp2100.dmovlay);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define WRITE_REG(grp,reg,val) ((*wr_reg[grp][reg])(val))
|
||||
|
||||
@@ -395,7 +435,7 @@ static void (*wr_reg[4][16])(INT32) =
|
||||
},
|
||||
{
|
||||
wr_i0, wr_i1, wr_i2, wr_i3, wr_m0, wr_m1, wr_m2, wr_m3,
|
||||
wr_l0, wr_l1, wr_l2, wr_l3, wr_inval, wr_inval, wr_inval, wr_inval
|
||||
wr_l0, wr_l1, wr_l2, wr_l3, wr_inval, wr_inval, wr_pmovlay, wr_dmovlay
|
||||
},
|
||||
{
|
||||
wr_i4, wr_i5, wr_i6, wr_i7, wr_m4, wr_m5, wr_m6, wr_m7,
|
||||
@@ -469,6 +509,13 @@ static INT32 rd_px(void) { return adsp2100.px; }
|
||||
static INT32 rd_rx0(void) { if (sport_rx_callback) return (*sport_rx_callback)(0); else return 0; }
|
||||
static INT32 rd_rx1(void) { if (sport_rx_callback) return (*sport_rx_callback)(1); else return 0; }
|
||||
static INT32 rd_stacktop(void) { return pc_stack_pop_val(); }
|
||||
#if (HAS_ADSP2181)
|
||||
static INT32 rd_pmovlay(void) { return (chip_type == CHIP_TYPE_ADSP2181) ? adsp2100.pmovlay : 0; }
|
||||
static INT32 rd_dmovlay(void) { return (chip_type == CHIP_TYPE_ADSP2181) ? adsp2100.dmovlay : 0; }
|
||||
#else
|
||||
#define rd_pmovlay rd_inval
|
||||
#define rd_dmovlay rd_inval
|
||||
#endif
|
||||
|
||||
#define READ_REG(grp,reg) ((*rd_reg[grp][reg])())
|
||||
|
||||
@@ -480,7 +527,7 @@ static INT32 (*rd_reg[4][16])(void) =
|
||||
},
|
||||
{
|
||||
rd_i0, rd_i1, rd_i2, rd_i3, rd_m0, rd_m1, rd_m2, rd_m3,
|
||||
rd_l0, rd_l1, rd_l2, rd_l3, rd_inval, rd_inval, rd_inval, rd_inval
|
||||
rd_l0, rd_l1, rd_l2, rd_l3, rd_inval, rd_inval, rd_pmovlay, rd_dmovlay
|
||||
},
|
||||
{
|
||||
rd_i4, rd_i5, rd_i6, rd_i7, rd_m4, rd_m5, rd_m6, rd_m7,
|
||||
@@ -498,16 +545,23 @@ static INT32 (*rd_reg[4][16])(void) =
|
||||
Modulus addressing logic
|
||||
===========================================================================*/
|
||||
|
||||
static INLINE void modify_address(UINT32 ireg, UINT32 mreg)
|
||||
/* index register 'i' plus 'm', kept in its circular buffer; 'wrap14' (a
|
||||
constant, set only in the ADSP-2181 interpreter loop) first keeps the
|
||||
sum to 14 bits, as in current MAME: an index that steps below 0 wraps
|
||||
to the top of memory instead of going out of the address space */
|
||||
static INLINE ADSP_ALWAYS_INLINE UINT32 dag_step(UINT32 i, INT32 m, UINT32 base, UINT32 l, int wrap14)
|
||||
{
|
||||
UINT32 base = adsp2100.base[ireg];
|
||||
UINT32 i = adsp2100.i[ireg];
|
||||
UINT32 l = adsp2100.l[ireg];
|
||||
|
||||
i += adsp2100.m[mreg];
|
||||
i += m;
|
||||
if (wrap14)
|
||||
i &= 0x3fff;
|
||||
if (i < base) i += l;
|
||||
else if (i >= base + l) i -= l;
|
||||
adsp2100.i[ireg] = i;
|
||||
return i;
|
||||
}
|
||||
|
||||
static INLINE ADSP_ALWAYS_INLINE void modify_address(UINT32 ireg, UINT32 mreg, int wrap14)
|
||||
{
|
||||
adsp2100.i[ireg] = dag_step(adsp2100.i[ireg], adsp2100.m[mreg], adsp2100.base[ireg], adsp2100.l[ireg], wrap14);
|
||||
}
|
||||
|
||||
|
||||
@@ -516,7 +570,7 @@ static INLINE void modify_address(UINT32 ireg, UINT32 mreg)
|
||||
Data memory accessors
|
||||
===========================================================================*/
|
||||
|
||||
static INLINE void data_write_dag1(UINT32 op, INT32 val)
|
||||
static INLINE ADSP_ALWAYS_INLINE void data_write_dag1_f(UINT32 op, INT32 val, int fast)
|
||||
{
|
||||
UINT32 ireg = (op >> 2) & 3;
|
||||
UINT32 mreg = op & 3;
|
||||
@@ -527,19 +581,16 @@ static INLINE void data_write_dag1(UINT32 op, INT32 val)
|
||||
if ( adsp2100.mstat & MSTAT_REVERSE )
|
||||
{
|
||||
UINT32 ir = reverse_table[ i & 0x3fff ];
|
||||
WWORD_DATA(ir, val);
|
||||
WWORD_DATA_F(ir, val, fast);
|
||||
}
|
||||
else
|
||||
WWORD_DATA(i, val);
|
||||
WWORD_DATA_F(i, val, fast);
|
||||
|
||||
i += adsp2100.m[mreg];
|
||||
if (i < base) i += l;
|
||||
else if (i >= base + l) i -= l;
|
||||
adsp2100.i[ireg] = i;
|
||||
adsp2100.i[ireg] = dag_step(i, adsp2100.m[mreg], base, l, fast & 2);
|
||||
}
|
||||
|
||||
|
||||
static INLINE UINT32 data_read_dag1(UINT32 op)
|
||||
static INLINE ADSP_ALWAYS_INLINE UINT32 data_read_dag1_f(UINT32 op, int fast)
|
||||
{
|
||||
UINT32 ireg = (op >> 2) & 3;
|
||||
UINT32 mreg = op & 3;
|
||||
@@ -551,20 +602,17 @@ static INLINE UINT32 data_read_dag1(UINT32 op)
|
||||
if (adsp2100.mstat & MSTAT_REVERSE)
|
||||
{
|
||||
UINT32 ir = reverse_table[i & 0x3fff];
|
||||
res = RWORD_DATA(ir);
|
||||
res = RWORD_DATA_F(ir, fast);
|
||||
}
|
||||
else
|
||||
res = RWORD_DATA(i);
|
||||
res = RWORD_DATA_F(i, fast);
|
||||
|
||||
i += adsp2100.m[mreg];
|
||||
if (i < base) i += l;
|
||||
else if (i >= base + l) i -= l;
|
||||
adsp2100.i[ireg] = i;
|
||||
adsp2100.i[ireg] = dag_step(i, adsp2100.m[mreg], base, l, fast & 2);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static INLINE void data_write_dag2(UINT32 op, INT32 val)
|
||||
static INLINE ADSP_ALWAYS_INLINE void data_write_dag2_f(UINT32 op, INT32 val, int fast)
|
||||
{
|
||||
UINT32 ireg = 4 + ((op >> 2) & 3);
|
||||
UINT32 mreg = 4 + (op & 3);
|
||||
@@ -572,16 +620,13 @@ static INLINE void data_write_dag2(UINT32 op, INT32 val)
|
||||
UINT32 i = adsp2100.i[ireg];
|
||||
UINT32 l = adsp2100.l[ireg];
|
||||
|
||||
WWORD_DATA(i, val);
|
||||
WWORD_DATA_F(i, val, fast);
|
||||
|
||||
i += adsp2100.m[mreg];
|
||||
if (i < base) i += l;
|
||||
else if (i >= base + l) i -= l;
|
||||
adsp2100.i[ireg] = i;
|
||||
adsp2100.i[ireg] = dag_step(i, adsp2100.m[mreg], base, l, fast & 2);
|
||||
}
|
||||
|
||||
|
||||
static INLINE UINT32 data_read_dag2(UINT32 op)
|
||||
static INLINE ADSP_ALWAYS_INLINE UINT32 data_read_dag2_f(UINT32 op, int fast)
|
||||
{
|
||||
UINT32 ireg = 4 + ((op >> 2) & 3);
|
||||
UINT32 mreg = 4 + (op & 3);
|
||||
@@ -589,21 +634,25 @@ static INLINE UINT32 data_read_dag2(UINT32 op)
|
||||
UINT32 i = adsp2100.i[ireg];
|
||||
UINT32 l = adsp2100.l[ireg];
|
||||
|
||||
UINT32 res = RWORD_DATA(i);
|
||||
UINT32 res = RWORD_DATA_F(i, fast);
|
||||
|
||||
i += adsp2100.m[mreg];
|
||||
if (i < base) i += l;
|
||||
else if (i >= base + l) i -= l;
|
||||
adsp2100.i[ireg] = i;
|
||||
adsp2100.i[ireg] = dag_step(i, adsp2100.m[mreg], base, l, fast & 2);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* the interpreter's accessors; 'fast': bit 0 for the recompiler (direct
|
||||
pointers), bit 1 for the ADSP-2181 (14-bit index wrap) */
|
||||
#define data_write_dag1(op, val) data_write_dag1_f(op, val, 0)
|
||||
#define data_read_dag1(op) data_read_dag1_f(op, 0)
|
||||
#define data_write_dag2(op, val) data_write_dag2_f(op, val, 0)
|
||||
#define data_read_dag2(op) data_read_dag2_f(op, 0)
|
||||
|
||||
/*===========================================================================
|
||||
Program memory accessors
|
||||
===========================================================================*/
|
||||
|
||||
static INLINE void pgm_write_dag2(UINT32 op, INT32 val)
|
||||
static INLINE ADSP_ALWAYS_INLINE void pgm_write_dag2(UINT32 op, INT32 val, int wrap14)
|
||||
{
|
||||
UINT32 ireg = 4 + ((op >> 2) & 3);
|
||||
UINT32 mreg = 4 + (op & 3);
|
||||
@@ -613,14 +662,11 @@ static INLINE void pgm_write_dag2(UINT32 op, INT32 val)
|
||||
|
||||
WWORD_PGM(i, (val << 8) | adsp2100.px);
|
||||
|
||||
i += adsp2100.m[mreg];
|
||||
if (i < base) i += l;
|
||||
else if (i >= base + l) i -= l;
|
||||
adsp2100.i[ireg] = i;
|
||||
adsp2100.i[ireg] = dag_step(i, adsp2100.m[mreg], base, l, wrap14);
|
||||
}
|
||||
|
||||
|
||||
static INLINE UINT32 pgm_read_dag2(UINT32 op)
|
||||
static INLINE ADSP_ALWAYS_INLINE UINT32 pgm_read_dag2(UINT32 op, int wrap14)
|
||||
{
|
||||
UINT32 ireg = 4 + ((op >> 2) & 3);
|
||||
UINT32 mreg = 4 + (op & 3);
|
||||
@@ -633,10 +679,7 @@ static INLINE UINT32 pgm_read_dag2(UINT32 op)
|
||||
adsp2100.px = res;
|
||||
res >>= 8;
|
||||
|
||||
i += adsp2100.m[mreg];
|
||||
if (i < base) i += l;
|
||||
else if (i >= base + l) i -= l;
|
||||
adsp2100.i[ireg] = i;
|
||||
adsp2100.i[ireg] = dag_step(i, adsp2100.m[mreg], base, l, wrap14);
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -1326,6 +1369,707 @@ void mac_op_mf(int op)
|
||||
|
||||
|
||||
|
||||
#if (HAS_ADSP2181)
|
||||
|
||||
/*===========================================================================
|
||||
ADSP-2181 only: ALU with a constant as Y, ALU with no result (NONE =),
|
||||
MAC with X as both operands (X * X); the operations above, with
|
||||
the other operand
|
||||
===========================================================================*/
|
||||
|
||||
static const INT32 alu_constants[32] =
|
||||
{
|
||||
0x0001, 0xfffe, 0x0002, 0xfffd, 0x0004, 0xfffb, 0x0008, 0xfff7,
|
||||
0x0010, 0xffef, 0x0020, 0xffdf, 0x0040, 0xffbf, 0x0080, 0xff7f,
|
||||
0x0100, 0xfeff, 0x0200, 0xfdff, 0x0400, 0xfbff, 0x0800, 0xf7ff,
|
||||
0x1000, 0xefff, 0x2000, 0xdfff, 0x4000, 0xbfff, 0x8000, 0x7fff
|
||||
};
|
||||
|
||||
static void alu_op_ar_const(int op)
|
||||
{
|
||||
INT32 xop = (op >> 8) & 7;
|
||||
INT32 yop = alu_constants[((op >> 5) & 7) | (((op >> 11) & 3) << 3)];
|
||||
INT32 res;
|
||||
|
||||
/*switch ((op >> 13) & 15)*/
|
||||
switch (op & (15<<13)) /*JB*/
|
||||
{
|
||||
case 0x00<<13:
|
||||
/* Y Clear when y = 0 */
|
||||
res = yop;
|
||||
CALC_NZ(res);
|
||||
break;
|
||||
case 0x01<<13:
|
||||
/* Y + 1 PASS 1 when y = 0 */
|
||||
res = yop + 1;
|
||||
CALC_NZ(res);
|
||||
if (yop == 0x7fff) SET_V;
|
||||
else if (yop == 0xffff) SET_C;
|
||||
break;
|
||||
case 0x02<<13:
|
||||
/* X + Y + C */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
yop += GET_C >> 3;
|
||||
res = xop + yop;
|
||||
CALC_NZVC(xop, yop, res);
|
||||
break;
|
||||
case 0x03<<13:
|
||||
/* X + Y X when y = 0 */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = xop + yop;
|
||||
CALC_NZVC(xop, yop, res);
|
||||
break;
|
||||
case 0x04<<13:
|
||||
/* NOT Y */
|
||||
res = yop ^ 0xffff;
|
||||
CALC_NZ(res);
|
||||
break;
|
||||
case 0x05<<13:
|
||||
/* -Y */
|
||||
res = -yop;
|
||||
CALC_NZ(res);
|
||||
if (yop == 0x8000) SET_V;
|
||||
if (yop == 0x0000) SET_C;
|
||||
break;
|
||||
case 0x06<<13:
|
||||
/* X - Y + C - 1 X + C - 1 when y = 0 */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = xop - yop + (GET_C >> 3) - 1;
|
||||
CALC_NZVC_SUB(xop, yop, res);
|
||||
break;
|
||||
case 0x07<<13:
|
||||
/* X - Y */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = xop - yop;
|
||||
CALC_NZVC_SUB(xop, yop, res);
|
||||
break;
|
||||
case 0x08<<13:
|
||||
/* Y - 1 PASS -1 when y = 0 */
|
||||
res = yop - 1;
|
||||
CALC_NZ(res);
|
||||
if (yop == 0x8000) SET_V;
|
||||
else if (yop == 0x0000) SET_C;
|
||||
break;
|
||||
case 0x09<<13:
|
||||
/* Y - X -X when y = 0 */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = yop - xop;
|
||||
CALC_NZVC_SUB(yop, xop, res);
|
||||
break;
|
||||
case 0x0a<<13:
|
||||
/* Y - X + C - 1 -X + C - 1 when y = 0 */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = yop - xop + (GET_C >> 3) - 1;
|
||||
CALC_NZVC_SUB(yop, xop, res);
|
||||
break;
|
||||
case 0x0b<<13:
|
||||
/* NOT X */
|
||||
res = ALU_GETXREG_UNSIGNED(xop) ^ 0xffff;
|
||||
CALC_NZ(res);
|
||||
break;
|
||||
case 0x0c<<13:
|
||||
/* X AND Y */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = xop & yop;
|
||||
CALC_NZ(res);
|
||||
break;
|
||||
case 0x0d<<13:
|
||||
/* X OR Y */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = xop | yop;
|
||||
CALC_NZ(res);
|
||||
break;
|
||||
case 0x0e<<13:
|
||||
/* X XOR Y */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = xop ^ yop;
|
||||
CALC_NZ(res);
|
||||
break;
|
||||
case 0x0f<<13:
|
||||
/* ABS X */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = (xop & 0x8000) ? -xop : xop;
|
||||
if (xop == 0) SET_Z;
|
||||
if (xop == 0x8000) SET_N, SET_V;
|
||||
CLR_S;
|
||||
if (xop & 0x8000) SET_S;
|
||||
break;
|
||||
default:
|
||||
res = 0; /* just to keep the compiler happy */
|
||||
break;
|
||||
}
|
||||
|
||||
/* saturate */
|
||||
if ((adsp2100.mstat & MSTAT_SATURATE) && GET_V) res = GET_C ? -32768 : 32767;
|
||||
|
||||
/* set the final value */
|
||||
adsp2100.core.ar.u = res;
|
||||
}
|
||||
|
||||
static void alu_op_af_const(int op)
|
||||
{
|
||||
INT32 xop = (op >> 8) & 7;
|
||||
INT32 yop = alu_constants[((op >> 5) & 7) | (((op >> 11) & 3) << 3)];
|
||||
INT32 res;
|
||||
|
||||
/* switch ((op >> 13) & 15)*/
|
||||
switch (op & (15<<13)) /*JB*/
|
||||
{
|
||||
case 0x00<<13:
|
||||
/* Y Clear when y = 0 */
|
||||
res = yop;
|
||||
CALC_NZ(res);
|
||||
break;
|
||||
case 0x01<<13:
|
||||
/* Y + 1 PASS 1 when y = 0 */
|
||||
res = yop + 1;
|
||||
CALC_NZ(res);
|
||||
if (yop == 0x7fff) SET_V;
|
||||
else if (yop == 0xffff) SET_C;
|
||||
break;
|
||||
case 0x02<<13:
|
||||
/* X + Y + C */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
yop += GET_C >> 3;
|
||||
res = xop + yop;
|
||||
CALC_NZVC(xop, yop, res);
|
||||
break;
|
||||
case 0x03<<13:
|
||||
/* X + Y X when y = 0 */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = xop + yop;
|
||||
CALC_NZVC(xop, yop, res);
|
||||
break;
|
||||
case 0x04<<13:
|
||||
/* NOT Y */
|
||||
res = yop ^ 0xffff;
|
||||
CALC_NZ(res);
|
||||
break;
|
||||
case 0x05<<13:
|
||||
/* -Y */
|
||||
res = -yop;
|
||||
CALC_NZ(res);
|
||||
if (yop == 0x8000) SET_V;
|
||||
if (yop == 0x0000) SET_C;
|
||||
break;
|
||||
case 0x06<<13:
|
||||
/* X - Y + C - 1 X + C - 1 when y = 0 */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = xop - yop + (GET_C >> 3) - 1;
|
||||
CALC_NZVC_SUB(xop, yop, res);
|
||||
break;
|
||||
case 0x07<<13:
|
||||
/* X - Y */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = xop - yop;
|
||||
CALC_NZVC_SUB(xop, yop, res);
|
||||
break;
|
||||
case 0x08<<13:
|
||||
/* Y - 1 PASS -1 when y = 0 */
|
||||
res = yop - 1;
|
||||
CALC_NZ(res);
|
||||
if (yop == 0x8000) SET_V;
|
||||
else if (yop == 0x0000) SET_C;
|
||||
break;
|
||||
case 0x09<<13:
|
||||
/* Y - X -X when y = 0 */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = yop - xop;
|
||||
CALC_NZVC_SUB(yop, xop, res);
|
||||
break;
|
||||
case 0x0a<<13:
|
||||
/* Y - X + C - 1 -X + C - 1 when y = 0 */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = yop - xop + (GET_C >> 3) - 1;
|
||||
CALC_NZVC_SUB(yop, xop, res);
|
||||
break;
|
||||
case 0x0b<<13:
|
||||
/* NOT X */
|
||||
res = ALU_GETXREG_UNSIGNED(xop) ^ 0xffff;
|
||||
CALC_NZ(res);
|
||||
break;
|
||||
case 0x0c<<13:
|
||||
/* X AND Y */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = xop & yop;
|
||||
CALC_NZ(res);
|
||||
break;
|
||||
case 0x0d<<13:
|
||||
/* X OR Y */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = xop | yop;
|
||||
CALC_NZ(res);
|
||||
break;
|
||||
case 0x0e<<13:
|
||||
/* X XOR Y */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = xop ^ yop;
|
||||
CALC_NZ(res);
|
||||
break;
|
||||
case 0x0f<<13:
|
||||
/* ABS X */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = (xop & 0x8000) ? -xop : xop;
|
||||
if (xop == 0) SET_Z;
|
||||
if (xop == 0x8000) SET_N, SET_V;
|
||||
CLR_S;
|
||||
if (xop & 0x8000) SET_S;
|
||||
break;
|
||||
default:
|
||||
res = 0; /* just to keep the compiler happy */
|
||||
break;
|
||||
}
|
||||
|
||||
/* set the final value */
|
||||
adsp2100.core.af.u = res;
|
||||
}
|
||||
|
||||
static void alu_op_none(int op)
|
||||
{
|
||||
INT32 xop = (op >> 8) & 7;
|
||||
INT32 yop = (op >> 11) & 3;
|
||||
INT32 res;
|
||||
|
||||
/*switch ((op >> 13) & 15)*/
|
||||
switch (op & (15<<13)) /*JB*/
|
||||
{
|
||||
case 0x00<<13:
|
||||
/* Y Clear when y = 0 */
|
||||
res = ALU_GETYREG_UNSIGNED(yop);
|
||||
CALC_NZ(res);
|
||||
break;
|
||||
case 0x01<<13:
|
||||
/* Y + 1 PASS 1 when y = 0 */
|
||||
yop = ALU_GETYREG_UNSIGNED(yop);
|
||||
res = yop + 1;
|
||||
CALC_NZ(res);
|
||||
if (yop == 0x7fff) SET_V;
|
||||
else if (yop == 0xffff) SET_C;
|
||||
break;
|
||||
case 0x02<<13:
|
||||
/* X + Y + C */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
yop = ALU_GETYREG_UNSIGNED(yop);
|
||||
yop += GET_C >> 3;
|
||||
res = xop + yop;
|
||||
CALC_NZVC(xop, yop, res);
|
||||
break;
|
||||
case 0x03<<13:
|
||||
/* X + Y X when y = 0 */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
yop = ALU_GETYREG_UNSIGNED(yop);
|
||||
res = xop + yop;
|
||||
CALC_NZVC(xop, yop, res);
|
||||
break;
|
||||
case 0x04<<13:
|
||||
/* NOT Y */
|
||||
res = ALU_GETYREG_UNSIGNED(yop) ^ 0xffff;
|
||||
CALC_NZ(res);
|
||||
break;
|
||||
case 0x05<<13:
|
||||
/* -Y */
|
||||
yop = ALU_GETYREG_UNSIGNED(yop);
|
||||
res = -yop;
|
||||
CALC_NZ(res);
|
||||
if (yop == 0x8000) SET_V;
|
||||
if (yop == 0x0000) SET_C;
|
||||
break;
|
||||
case 0x06<<13:
|
||||
/* X - Y + C - 1 X + C - 1 when y = 0 */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
yop = ALU_GETYREG_UNSIGNED(yop);
|
||||
res = xop - yop + (GET_C >> 3) - 1;
|
||||
CALC_NZVC_SUB(xop, yop, res);
|
||||
break;
|
||||
case 0x07<<13:
|
||||
/* X - Y */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
yop = ALU_GETYREG_UNSIGNED(yop);
|
||||
res = xop - yop;
|
||||
CALC_NZVC_SUB(xop, yop, res);
|
||||
break;
|
||||
case 0x08<<13:
|
||||
/* Y - 1 PASS -1 when y = 0 */
|
||||
yop = ALU_GETYREG_UNSIGNED(yop);
|
||||
res = yop - 1;
|
||||
CALC_NZ(res);
|
||||
if (yop == 0x8000) SET_V;
|
||||
else if (yop == 0x0000) SET_C;
|
||||
break;
|
||||
case 0x09<<13:
|
||||
/* Y - X -X when y = 0 */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
yop = ALU_GETYREG_UNSIGNED(yop);
|
||||
res = yop - xop;
|
||||
CALC_NZVC_SUB(yop, xop, res);
|
||||
break;
|
||||
case 0x0a<<13:
|
||||
/* Y - X + C - 1 -X + C - 1 when y = 0 */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
yop = ALU_GETYREG_UNSIGNED(yop);
|
||||
res = yop - xop + (GET_C >> 3) - 1;
|
||||
CALC_NZVC_SUB(yop, xop, res);
|
||||
break;
|
||||
case 0x0b<<13:
|
||||
/* NOT X */
|
||||
res = ALU_GETXREG_UNSIGNED(xop) ^ 0xffff;
|
||||
CALC_NZ(res);
|
||||
break;
|
||||
case 0x0c<<13:
|
||||
/* X AND Y */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
yop = ALU_GETYREG_UNSIGNED(yop);
|
||||
res = xop & yop;
|
||||
CALC_NZ(res);
|
||||
break;
|
||||
case 0x0d<<13:
|
||||
/* X OR Y */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
yop = ALU_GETYREG_UNSIGNED(yop);
|
||||
res = xop | yop;
|
||||
CALC_NZ(res);
|
||||
break;
|
||||
case 0x0e<<13:
|
||||
/* X XOR Y */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
yop = ALU_GETYREG_UNSIGNED(yop);
|
||||
res = xop ^ yop;
|
||||
CALC_NZ(res);
|
||||
break;
|
||||
case 0x0f<<13:
|
||||
/* ABS X */
|
||||
xop = ALU_GETXREG_UNSIGNED(xop);
|
||||
res = (xop & 0x8000) ? -xop : xop;
|
||||
if (xop == 0) SET_Z;
|
||||
if (xop == 0x8000) SET_N, SET_V;
|
||||
CLR_S;
|
||||
if (xop & 0x8000) SET_S;
|
||||
break;
|
||||
default:
|
||||
res = 0; /* just to keep the compiler happy */
|
||||
break;
|
||||
}
|
||||
|
||||
/* no result: only the flags */
|
||||
(void)res;
|
||||
}
|
||||
|
||||
static void mac_op_mr_xop(int op)
|
||||
{
|
||||
INT8 shift = ((adsp2100.mstat & MSTAT_INTEGER) >> 4) ^ 1;
|
||||
INT32 xop = (op >> 8) & 7;
|
||||
INT32 yop;
|
||||
INT32 temp;
|
||||
INT64 res;
|
||||
|
||||
/* switch ((op >> 13) & 15)*/
|
||||
switch (op & (15<<13)) /*JB*/
|
||||
{
|
||||
case 0x00<<13:
|
||||
/* no-op */
|
||||
return;
|
||||
case 0x01<<13:
|
||||
/* X * Y (RND) */
|
||||
xop = MAC_GETXREG_SIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = (INT64)temp;
|
||||
#ifdef ADSP_TWEAK
|
||||
if ((res & 0xffff) == 0x8000) res &= ~((UINT64)0x10000);
|
||||
else res += (res & 0x8000) << 1;
|
||||
#else
|
||||
temp &= 0xffff;
|
||||
res += 0x8000;
|
||||
if ( temp == 0x8000 )
|
||||
res &= ~((UINT64)0x10000);
|
||||
#endif
|
||||
break;
|
||||
case 0x02<<13:
|
||||
/* MR + X * Y (RND) */
|
||||
xop = MAC_GETXREG_SIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr + (INT64)temp;
|
||||
#ifdef ADSP_TWEAK
|
||||
if ((res & 0xffff) == 0x8000) res &= ~((UINT64)0x10000);
|
||||
else res += (res & 0x8000) << 1;
|
||||
#else
|
||||
temp &= 0xffff;
|
||||
res += 0x8000;
|
||||
if ( temp == 0x8000 )
|
||||
res &= ~((UINT64)0x10000);
|
||||
#endif
|
||||
break;
|
||||
case 0x03<<13:
|
||||
/* MR - X * Y (RND) */
|
||||
xop = MAC_GETXREG_SIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr - (INT64)temp;
|
||||
#ifdef ADSP_TWEAK
|
||||
if ((res & 0xffff) == 0x8000) res &= ~((UINT64)0x10000);
|
||||
else res += (res & 0x8000) << 1;
|
||||
#else
|
||||
temp &= 0xffff;
|
||||
res += 0x8000;
|
||||
if ( temp == 0x8000 )
|
||||
res &= ~((UINT64)0x10000);
|
||||
#endif
|
||||
break;
|
||||
case 0x04<<13:
|
||||
/* X * Y (SS) Clear when y = 0 */
|
||||
xop = MAC_GETXREG_SIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = (INT64)temp;
|
||||
break;
|
||||
case 0x05<<13:
|
||||
/* X * Y (SU) */
|
||||
xop = MAC_GETXREG_SIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = (INT64)temp;
|
||||
break;
|
||||
case 0x06<<13:
|
||||
/* X * Y (US) */
|
||||
xop = MAC_GETXREG_UNSIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = (INT64)temp;
|
||||
break;
|
||||
case 0x07<<13:
|
||||
/* X * Y (UU) */
|
||||
xop = MAC_GETXREG_UNSIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = (INT64)temp;
|
||||
break;
|
||||
case 0x08<<13:
|
||||
/* MR + X * Y (SS) */
|
||||
xop = MAC_GETXREG_SIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr + (INT64)temp;
|
||||
break;
|
||||
case 0x09<<13:
|
||||
/* MR + X * Y (SU) */
|
||||
xop = MAC_GETXREG_SIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr + (INT64)temp;
|
||||
break;
|
||||
case 0x0a<<13:
|
||||
/* MR + X * Y (US) */
|
||||
xop = MAC_GETXREG_UNSIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr + (INT64)temp;
|
||||
break;
|
||||
case 0x0b<<13:
|
||||
/* MR + X * Y (UU) */
|
||||
xop = MAC_GETXREG_UNSIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr + (INT64)temp;
|
||||
break;
|
||||
case 0x0c<<13:
|
||||
/* MR - X * Y (SS) */
|
||||
xop = MAC_GETXREG_SIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr - (INT64)temp;
|
||||
break;
|
||||
case 0x0d<<13:
|
||||
/* MR - X * Y (SU) */
|
||||
xop = MAC_GETXREG_SIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr - (INT64)temp;
|
||||
break;
|
||||
case 0x0e<<13:
|
||||
/* MR - X * Y (US) */
|
||||
xop = MAC_GETXREG_UNSIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr - (INT64)temp;
|
||||
break;
|
||||
case 0x0f<<13:
|
||||
/* MR - X * Y (UU) */
|
||||
xop = MAC_GETXREG_UNSIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr - (INT64)temp;
|
||||
break;
|
||||
default:
|
||||
res = 0; /* just to keep the compiler happy */
|
||||
break;
|
||||
}
|
||||
|
||||
/* set the final value */
|
||||
temp = (res >> 31) & 0x1ff;
|
||||
CLR_MV;
|
||||
if (temp != 0x000 && temp != 0x1ff) SET_MV;
|
||||
adsp2100.core.mr.mr = res;
|
||||
}
|
||||
|
||||
static void mac_op_mf_xop(int op)
|
||||
{
|
||||
INT8 shift = ((adsp2100.mstat & MSTAT_INTEGER) >> 4) ^ 1;
|
||||
INT32 xop = (op >> 8) & 7;
|
||||
INT32 yop;
|
||||
INT32 temp;
|
||||
INT64 res;
|
||||
|
||||
/* switch ((op >> 13) & 15)*/
|
||||
switch (op & (15<<13)) /*JB*/
|
||||
{
|
||||
case 0x00<<13:
|
||||
/* no-op */
|
||||
return;
|
||||
case 0x01<<13:
|
||||
/* X * Y (RND) */
|
||||
xop = MAC_GETXREG_SIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = (INT64)temp;
|
||||
#ifdef ADSP_TWEAK
|
||||
if ((res & 0xffff) == 0x8000) res &= ~((UINT64)0x10000);
|
||||
else res += (res & 0x8000) << 1;
|
||||
#else
|
||||
temp &= 0xffff;
|
||||
res += 0x8000;
|
||||
if ( temp == 0x8000 )
|
||||
res &= ~((UINT64)0x10000);
|
||||
#endif
|
||||
break;
|
||||
case 0x02<<13:
|
||||
/* MR + X * Y (RND) */
|
||||
xop = MAC_GETXREG_SIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr + (INT64)temp;
|
||||
#ifdef ADSP_TWEAK
|
||||
if ((res & 0xffff) == 0x8000) res &= ~((UINT64)0x10000);
|
||||
else res += (res & 0x8000) << 1;
|
||||
#else
|
||||
temp &= 0xffff;
|
||||
res += 0x8000;
|
||||
if ( temp == 0x8000 )
|
||||
res &= ~((UINT64)0x10000);
|
||||
#endif
|
||||
break;
|
||||
case 0x03<<13:
|
||||
/* MR - X * Y (RND) */
|
||||
xop = MAC_GETXREG_SIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr - (INT64)temp;
|
||||
#ifdef ADSP_TWEAK
|
||||
if ((res & 0xffff) == 0x8000) res &= ~((UINT64)0x10000);
|
||||
else res += (res & 0x8000) << 1;
|
||||
#else
|
||||
temp &= 0xffff;
|
||||
res += 0x8000;
|
||||
if ( temp == 0x8000 )
|
||||
res &= ~((UINT64)0x10000);
|
||||
#endif
|
||||
break;
|
||||
case 0x04<<13:
|
||||
/* X * Y (SS) Clear when y = 0 */
|
||||
xop = MAC_GETXREG_SIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = (INT64)temp;
|
||||
break;
|
||||
case 0x05<<13:
|
||||
/* X * Y (SU) */
|
||||
xop = MAC_GETXREG_SIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = (INT64)temp;
|
||||
break;
|
||||
case 0x06<<13:
|
||||
/* X * Y (US) */
|
||||
xop = MAC_GETXREG_UNSIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = (INT64)temp;
|
||||
break;
|
||||
case 0x07<<13:
|
||||
/* X * Y (UU) */
|
||||
xop = MAC_GETXREG_UNSIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = (INT64)temp;
|
||||
break;
|
||||
case 0x08<<13:
|
||||
/* MR + X * Y (SS) */
|
||||
xop = MAC_GETXREG_SIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr + (INT64)temp;
|
||||
break;
|
||||
case 0x09<<13:
|
||||
/* MR + X * Y (SU) */
|
||||
xop = MAC_GETXREG_SIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr + (INT64)temp;
|
||||
break;
|
||||
case 0x0a<<13:
|
||||
/* MR + X * Y (US) */
|
||||
xop = MAC_GETXREG_UNSIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr + (INT64)temp;
|
||||
break;
|
||||
case 0x0b<<13:
|
||||
/* MR + X * Y (UU) */
|
||||
xop = MAC_GETXREG_UNSIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr + (INT64)temp;
|
||||
break;
|
||||
case 0x0c<<13:
|
||||
/* MR - X * Y (SS) */
|
||||
xop = MAC_GETXREG_SIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr - (INT64)temp;
|
||||
break;
|
||||
case 0x0d<<13:
|
||||
/* MR - X * Y (SU) */
|
||||
xop = MAC_GETXREG_SIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr - (INT64)temp;
|
||||
break;
|
||||
case 0x0e<<13:
|
||||
/* MR - X * Y (US) */
|
||||
xop = MAC_GETXREG_UNSIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr - (INT64)temp;
|
||||
break;
|
||||
case 0x0f<<13:
|
||||
/* MR - X * Y (UU) */
|
||||
xop = MAC_GETXREG_UNSIGNED(xop);
|
||||
yop = xop;
|
||||
temp = (xop * yop) << shift;
|
||||
res = adsp2100.core.mr.mr - (INT64)temp;
|
||||
break;
|
||||
default:
|
||||
res = 0; /* just to keep the compiler happy */
|
||||
break;
|
||||
}
|
||||
|
||||
/* set the final value */
|
||||
adsp2100.core.mf.u = (UINT32)res >> 16;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*===========================================================================
|
||||
SHIFT operations (result in SR/SE/SB)
|
||||
===========================================================================*/
|
||||
|
||||
+1201
-686
File diff suppressed because it is too large.
Load diff
@@ -92,6 +92,13 @@ extern unsigned adsp2100_get_reg(int regnum);
|
||||
extern void adsp2100_set_reg(int regnum, unsigned val);
|
||||
extern void adsp2100_set_irq_line(int irqline, int state);
|
||||
extern void adsp2100_set_irq_callback(int (*callback)(int irqline));
|
||||
/* exact skip of one-instruction NOP delay loops: off unless a driver enables it */
|
||||
extern void adsp2100_set_nop_loop_skip(int enable);
|
||||
/* optional recompiler (adsp2100jit.c): off unless a driver enables it */
|
||||
extern int adsp2100_jit_available(void);
|
||||
extern void adsp2100_set_jit(int enable);
|
||||
/* data memory words [start, end] read through a handler with no side effects */
|
||||
extern void adsp2100_jit_pure_read(UINT32 start, UINT32 end);
|
||||
extern const char *adsp2100_info(void *context, int regnum);
|
||||
extern unsigned adsp2100_dasm(char *buffer, unsigned pc);
|
||||
|
||||
@@ -262,4 +269,56 @@ extern void adsp2115_set_tx_callback( TX_CALLBACK cb );
|
||||
extern void adsp2115_load_boot_data(data8_t *srcdata, data32_t *dstdata);
|
||||
#endif
|
||||
|
||||
#if (HAS_ADSP2181)
|
||||
/**************************************************************************
|
||||
* ADSP2181 section
|
||||
*
|
||||
* 16K words of program RAM and 16K words of data RAM on the chip: the
|
||||
* driver maps them (program memory at ADSP2181_PGM_OFFSET, data memory
|
||||
* at ADSP2181_DATA_OFFSET), with its control registers at 0x3fe0-0x3fff
|
||||
* of data memory. The I/O space (IO(x) instructions) and the data memory
|
||||
* overlay (DMOVLAY) go through the callbacks below
|
||||
**************************************************************************/
|
||||
|
||||
#define ADSP2181_DATA_OFFSET ADSP2100_DATA_OFFSET
|
||||
#define ADSP2181_PGM_OFFSET ADSP2100_PGM_OFFSET
|
||||
#define ADSP2181_SIZE ADSP2100_SIZE
|
||||
|
||||
#define adsp2181_icount adsp2100_icount
|
||||
|
||||
#define ADSP2181_IRQ0 0 /* IRQ0 */
|
||||
#define ADSP2181_SPORT1_RX 0 /* SPORT1 receive IRQ */
|
||||
#define ADSP2181_IRQ1 1 /* IRQ1 */
|
||||
#define ADSP2181_SPORT1_TX 1 /* SPORT1 transmit IRQ */
|
||||
#define ADSP2181_IRQ2 2 /* IRQ2 */
|
||||
#define ADSP2181_SPORT0_RX 3 /* SPORT0 receive IRQ */
|
||||
#define ADSP2181_SPORT0_TX 4 /* SPORT0 transmit IRQ */
|
||||
#define ADSP2181_TIMER 5 /* internal timer IRQ */
|
||||
#define ADSP2181_IRQE 6 /* IRQE */
|
||||
#define ADSP2181_BDMA 7 /* BDMA */
|
||||
#define ADSP2181_IRQL1 8 /* IRQL1 */
|
||||
#define ADSP2181_IRQL0 9 /* IRQL0 */
|
||||
|
||||
typedef UINT16 (*ADSP2181_IO_READ)( UINT32 offset );
|
||||
typedef void (*ADSP2181_IO_WRITE)( UINT32 offset, UINT16 data );
|
||||
typedef void (*ADSP2181_DMOVLAY)( UINT32 dmovlay );
|
||||
|
||||
extern void adsp2181_init(void);
|
||||
extern void adsp2181_reset(void *param);
|
||||
extern void adsp2181_exit(void);
|
||||
extern int adsp2181_execute(int cycles);
|
||||
extern unsigned adsp2181_get_context(void *dst);
|
||||
extern void adsp2181_set_context(void *src);
|
||||
extern unsigned adsp2181_get_reg(int regnum);
|
||||
extern void adsp2181_set_reg(int regnum, unsigned val);
|
||||
extern void adsp2181_set_irq_line(int irqline, int state);
|
||||
extern void adsp2181_set_irq_callback(int (*callback)(int irqline));
|
||||
extern const char *adsp2181_info(void *context, int regnum);
|
||||
extern unsigned adsp2181_dasm(char *buffer, unsigned pc);
|
||||
extern void adsp2181_set_rx_callback( RX_CALLBACK cb );
|
||||
extern void adsp2181_set_tx_callback( TX_CALLBACK cb );
|
||||
extern void adsp2181_set_io_callbacks( ADSP2181_IO_READ rd, ADSP2181_IO_WRITE wr );
|
||||
extern void adsp2181_set_dmovlay_callback( ADSP2181_DMOVLAY cb );
|
||||
#endif
|
||||
|
||||
#endif /* _ADSP2100_H */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,235 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* arm7.c
|
||||
* Portable CPU Emulator for 32-bit ARM v3/4/5/6
|
||||
*
|
||||
* Copyright Steve Ellenoff, all rights reserved.
|
||||
* Thumb, DSP, and MMU support and many bugfixes by R. Belmont and Ryan Holtz.
|
||||
*
|
||||
* - This source code is released as freeware for non-commercial purposes.
|
||||
* - You are free to use and redistribute this code in modified or
|
||||
* unmodified form, provided you list me in the credits.
|
||||
* - If you modify this source code, you must add a notice to each modified
|
||||
* source file that it has been changed. If you're a nice person, you
|
||||
* will clearly mark each change too. :)
|
||||
* - If you wish to use this for commercial purposes, please contact me at
|
||||
* sellenoff@hotmail.com
|
||||
* - The author of this copywritten work reserves the right to change the
|
||||
* terms of its usage and license at any time, including retroactively
|
||||
* - This entire notice must remain in the source code.
|
||||
*
|
||||
* This work is based on:
|
||||
* #1) 'Atmel Corporation ARM7TDMI (Thumb) Datasheet - January 1999'
|
||||
* #2) Arm 2/3/6 emulator By Bryan McPhail (bmcphail@tendril.co.uk) and Phil Stroffolino (MAME CORE 0.76)
|
||||
*
|
||||
*****************************************************************************
|
||||
|
||||
mame2003-plus: modified. The core files (arm7core.c/h, arm7exec.c) are
|
||||
those of MAME 0.139, with the memory accesses going through this
|
||||
version's 32-bit little endian memory system (cpu_readmem32ledw...) and
|
||||
the state in one static structure; this file is the cpu interface of
|
||||
this version. ARMv4T (ARM7TDMI): no MMU, no coprocessors.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "state.h"
|
||||
#include "arm7.h"
|
||||
#include "arm7core.h"
|
||||
|
||||
#define LOG(x) logerror x
|
||||
#define fatalerror logerror
|
||||
#define ENDIANNESS_BIG 1
|
||||
|
||||
/* the memory handlers of the core (arm7core.c) */
|
||||
#define READ8(addr) arm7_cpu_read8(cpustate, addr)
|
||||
#define WRITE8(addr,data) arm7_cpu_write8(cpustate, addr,data)
|
||||
#define READ16(addr) arm7_cpu_read16(cpustate, addr)
|
||||
#define WRITE16(addr,data) arm7_cpu_write16(cpustate, addr,data)
|
||||
#define READ32(addr) arm7_cpu_read32(cpustate, addr)
|
||||
#define WRITE32(addr,data) arm7_cpu_write32(cpustate, addr,data)
|
||||
#define PTR_READ32 &arm7_cpu_read32
|
||||
#define PTR_WRITE32 &arm7_cpu_write32
|
||||
|
||||
#define ARM7REG(reg) cpustate->sArmRegister[reg]
|
||||
#define ARM7_ICOUNT arm7_ICount
|
||||
|
||||
static arm_state arm7_state;
|
||||
int arm7_ICount;
|
||||
|
||||
/* the core's inline functions are local to this file */
|
||||
#undef INLINE
|
||||
#if defined( _MSC_VER )
|
||||
#define INLINE static __inline
|
||||
#elif defined( __GNUC__ )
|
||||
#define INLINE static __inline__
|
||||
#else
|
||||
#define INLINE static
|
||||
#endif
|
||||
|
||||
/* ARMv5 helpers the core refers to (CLZ, QADD...): not reached on the ARMv4T */
|
||||
INLINE UINT32 count_leading_zeros(UINT32 val)
|
||||
{
|
||||
UINT32 count = 0;
|
||||
if (val == 0)
|
||||
return 32;
|
||||
while (!(val & 0x80000000))
|
||||
{
|
||||
count++;
|
||||
val <<= 1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
INLINE INT64 saturate_qbit_overflow(arm_state *cpustate, INT64 res)
|
||||
{
|
||||
if (res > 2147483647) /* INT32_MAX */
|
||||
{
|
||||
res = 2147483647;
|
||||
SET_CPSR(GET_CPSR | Q_MASK);
|
||||
}
|
||||
else if (res < (-2147483647-1)) /* INT32_MIN */
|
||||
{
|
||||
res = (-2147483647-1);
|
||||
SET_CPSR(GET_CPSR | Q_MASK);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/* no MMU on the ARM7TDMI: the core only calls this when one is enabled */
|
||||
INLINE UINT32 arm7_tlb_translate(arm_state *cpustate, UINT32 vaddr)
|
||||
{
|
||||
return vaddr;
|
||||
}
|
||||
|
||||
#include "arm7core.c"
|
||||
|
||||
void arm7_init(void)
|
||||
{
|
||||
arm_state *cpustate = &arm7_state;
|
||||
|
||||
memset(cpustate, 0, sizeof(*cpustate));
|
||||
cpustate->archRev = 4;
|
||||
cpustate->archFlags = eARM_ARCHFLAGS_T;
|
||||
arm7_core_init(cpustate, "arm7", cpu_getactivecpu());
|
||||
}
|
||||
|
||||
void arm7_reset(void *param)
|
||||
{
|
||||
arm7_core_reset(&arm7_state);
|
||||
}
|
||||
|
||||
void arm7_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
int arm7_execute(int cycles)
|
||||
{
|
||||
arm7_ICount = cycles;
|
||||
#include "arm7exec.c"
|
||||
return cycles - arm7_ICount;
|
||||
}
|
||||
|
||||
unsigned arm7_get_context(void *dst)
|
||||
{
|
||||
if (dst)
|
||||
memcpy(dst, &arm7_state, sizeof(arm7_state));
|
||||
return sizeof(arm7_state);
|
||||
}
|
||||
|
||||
void arm7_set_context(void *src)
|
||||
{
|
||||
if (src)
|
||||
memcpy(&arm7_state, src, sizeof(arm7_state));
|
||||
}
|
||||
|
||||
unsigned arm7_get_reg(int regnum)
|
||||
{
|
||||
arm_state *cpustate = &arm7_state;
|
||||
|
||||
switch (regnum)
|
||||
{
|
||||
case REG_PC:
|
||||
case ARM7_PC: return R15;
|
||||
case REG_SP: return GetRegister(cpustate, 13);
|
||||
case REG_PREVIOUSPC: return 0;
|
||||
case ARM7_CPSR: return GET_CPSR;
|
||||
}
|
||||
if (regnum >= ARM7_R0 && regnum <= ARM7_R15)
|
||||
return GetRegister(cpustate, regnum - ARM7_R0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void arm7_set_reg(int regnum, unsigned val)
|
||||
{
|
||||
arm_state *cpustate = &arm7_state;
|
||||
|
||||
switch (regnum)
|
||||
{
|
||||
case REG_PC:
|
||||
case ARM7_PC: R15 = val; return;
|
||||
case REG_SP: SetRegister(cpustate, 13, val); return;
|
||||
case ARM7_CPSR: SET_CPSR(val); return;
|
||||
}
|
||||
if (regnum >= ARM7_R0 && regnum <= ARM7_R15)
|
||||
SetRegister(cpustate, regnum - ARM7_R0, val);
|
||||
}
|
||||
|
||||
void arm7_set_irq_line(int irqline, int state)
|
||||
{
|
||||
arm7_core_set_irq_line(&arm7_state, irqline, state);
|
||||
}
|
||||
|
||||
void arm7_set_irq_callback(int (*callback)(int irqline))
|
||||
{
|
||||
arm7_state.irq_callback = callback;
|
||||
}
|
||||
|
||||
const char *arm7_info(void *context, int regnum)
|
||||
{
|
||||
static char buffer[16][64];
|
||||
static int which = 0;
|
||||
arm_state *cpustate = context ? (arm_state *)context : &arm7_state;
|
||||
|
||||
which = (which + 1) % 16;
|
||||
buffer[which][0] = '\0';
|
||||
|
||||
if (regnum >= CPU_INFO_REG + ARM7_R0 && regnum <= CPU_INFO_REG + ARM7_R15)
|
||||
{
|
||||
sprintf(buffer[which], "R%-3d:%08x", regnum - CPU_INFO_REG - ARM7_R0, GetRegister(cpustate, regnum - CPU_INFO_REG - ARM7_R0));
|
||||
return buffer[which];
|
||||
}
|
||||
switch (regnum)
|
||||
{
|
||||
case CPU_INFO_REG + ARM7_PC: sprintf(buffer[which], "PC :%08x", R15); break;
|
||||
case CPU_INFO_REG + ARM7_CPSR: sprintf(buffer[which], "CPSR:%08x", GET_CPSR); break;
|
||||
case CPU_INFO_FLAGS:
|
||||
sprintf(buffer[which], "%c%c%c%c%c%c%c %s",
|
||||
(GET_CPSR & N_MASK) ? 'N' : '-',
|
||||
(GET_CPSR & Z_MASK) ? 'Z' : '-',
|
||||
(GET_CPSR & C_MASK) ? 'C' : '-',
|
||||
(GET_CPSR & V_MASK) ? 'V' : '-',
|
||||
(GET_CPSR & I_MASK) ? 'I' : '-',
|
||||
(GET_CPSR & F_MASK) ? 'F' : '-',
|
||||
(GET_CPSR & T_MASK) ? 'T' : '-',
|
||||
GetModeText(GET_CPSR));
|
||||
break;
|
||||
case CPU_INFO_NAME: return "ARM7";
|
||||
case CPU_INFO_FAMILY: return "Acorn Risc Machine";
|
||||
case CPU_INFO_VERSION: return "2.0 (MAME 0.139 core)";
|
||||
case CPU_INFO_FILE: return __FILE__;
|
||||
case CPU_INFO_CREDITS: return "Copyright Steve Ellenoff, [email protected]";
|
||||
}
|
||||
return buffer[which];
|
||||
}
|
||||
|
||||
unsigned arm7_dasm(char *buffer, unsigned pc)
|
||||
{
|
||||
if (T_IS_SET(arm7_state.sArmRegister[eCPSR]))
|
||||
{
|
||||
sprintf(buffer, "$%04x", cpu_readmem32ledw_word(pc & ~1));
|
||||
return 2;
|
||||
}
|
||||
sprintf(buffer, "$%08x", cpu_readmem32ledw_dword(pc & ~3));
|
||||
return 4;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* arm7.h
|
||||
* Portable ARM7TDMI CPU Emulator
|
||||
*
|
||||
* Copyright Steve Ellenoff, all rights reserved.
|
||||
* Thumb, DSP, and MMU support and many bugfixes by R. Belmont and Ryan Holtz.
|
||||
* (see arm7core.c for the full notice)
|
||||
*
|
||||
* mame2003-plus: the MAME 0.139 core with the cpu interface of this
|
||||
* version (one ARM7 at a time, 32-bit little endian bus).
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef ARM7_H
|
||||
#define ARM7_H
|
||||
|
||||
#include "driver.h"
|
||||
|
||||
/* interrupt lines and exceptions */
|
||||
#define ARM7_IRQ_LINE 0
|
||||
#define ARM7_FIRQ_LINE 1
|
||||
#define ARM7_ABORT_EXCEPTION 2
|
||||
#define ARM7_ABORT_PREFETCH_EXCEPTION 3
|
||||
#define ARM7_UNDEFINE_EXCEPTION 4
|
||||
|
||||
|
||||
extern int arm7_ICount;
|
||||
|
||||
extern void arm7_init(void);
|
||||
extern void arm7_reset(void *param);
|
||||
extern void arm7_exit(void);
|
||||
extern int arm7_execute(int cycles);
|
||||
extern unsigned arm7_get_context(void *dst);
|
||||
extern void arm7_set_context(void *src);
|
||||
extern unsigned arm7_get_reg(int regnum);
|
||||
extern void arm7_set_reg(int regnum, unsigned val);
|
||||
extern void arm7_set_irq_line(int irqline, int state);
|
||||
extern void arm7_set_irq_callback(int (*callback)(int irqline));
|
||||
extern const char *arm7_info(void *context, int regnum);
|
||||
extern unsigned arm7_dasm(char *buffer, unsigned pc);
|
||||
|
||||
#endif /* ARM7_H */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,488 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* arm7core.h
|
||||
* Portable ARM7TDMI Core Emulator
|
||||
*
|
||||
* Copyright Steve Ellenoff, all rights reserved.
|
||||
*
|
||||
* - This source code is released as freeware for non-commercial purposes.
|
||||
* - You are free to use and redistribute this code in modified or
|
||||
* unmodified form, provided you list me in the credits.
|
||||
* - If you modify this source code, you must add a notice to each modified
|
||||
* source file that it has been changed. If you're a nice person, you
|
||||
* will clearly mark each change too. :)
|
||||
* - If you wish to use this for commercial purposes, please contact me at
|
||||
* sellenoff@hotmail.com
|
||||
* - The author of this copywritten work reserves the right to change the
|
||||
* terms of its usage and license at any time, including retroactively
|
||||
* - This entire notice must remain in the source code.
|
||||
*
|
||||
* This work is based on:
|
||||
* #1) 'Atmel Corporation ARM7TDMI (Thumb) Datasheet - January 1999'
|
||||
* #2) Arm 2/3/6 emulator By Bryan McPhail (bmcphail@tendril.co.uk) and Phil Stroffolino (MAME CORE 0.76)
|
||||
*
|
||||
*****************************************************************************
|
||||
|
||||
This file contains everything related to the arm7 core itself, and is presumed
|
||||
to be cpu implementation non-specific, ie, applies to only the core.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#ifndef __ARM7CORE_H__
|
||||
#define __ARM7CORE_H__
|
||||
|
||||
|
||||
/****************************************************************************************************
|
||||
* INTERRUPT LINES/EXCEPTIONS
|
||||
***************************************************************************************************/
|
||||
/* ARM7_IRQ_LINE .. ARM7_UNDEFINE_EXCEPTION: in arm7.h */
|
||||
#define ARM7_NUM_LINES 5
|
||||
/* Really there's only 1 ABORT Line.. and cpu decides whether it's during data fetch or prefetch, but we let the user specify */
|
||||
|
||||
/****************************************************************************************************
|
||||
* ARM7 CORE REGISTERS
|
||||
***************************************************************************************************/
|
||||
enum
|
||||
{
|
||||
ARM7_PC = 0,
|
||||
ARM7_R0, ARM7_R1, ARM7_R2, ARM7_R3, ARM7_R4, ARM7_R5, ARM7_R6, ARM7_R7,
|
||||
ARM7_R8, ARM7_R9, ARM7_R10, ARM7_R11, ARM7_R12, ARM7_R13, ARM7_R14, ARM7_R15,
|
||||
ARM7_FR8, ARM7_FR9, ARM7_FR10, ARM7_FR11, ARM7_FR12, ARM7_FR13, ARM7_FR14,
|
||||
ARM7_IR13, ARM7_IR14, ARM7_SR13, ARM7_SR14, ARM7_FSPSR, ARM7_ISPSR, ARM7_SSPSR,
|
||||
ARM7_CPSR, ARM7_AR13, ARM7_AR14, ARM7_ASPSR, ARM7_UR13, ARM7_UR14, ARM7_USPSR
|
||||
};
|
||||
|
||||
/* There are 36 Unique - 32 bit processor registers */
|
||||
/* Each mode has 17 registers (except user & system, which have 16) */
|
||||
/* This is a list of each *unique* register */
|
||||
enum
|
||||
{
|
||||
/* All modes have the following */
|
||||
eR0 = 0, eR1, eR2, eR3, eR4, eR5, eR6, eR7,
|
||||
eR8, eR9, eR10, eR11, eR12,
|
||||
eR13, /* Stack Pointer */
|
||||
eR14, /* Link Register (holds return address) */
|
||||
eR15, /* Program Counter */
|
||||
eCPSR, /* Current Status Program Register */
|
||||
|
||||
/* Fast Interrupt - Bank switched registers */
|
||||
eR8_FIQ, eR9_FIQ, eR10_FIQ, eR11_FIQ, eR12_FIQ, eR13_FIQ, eR14_FIQ, eSPSR_FIQ,
|
||||
|
||||
/* IRQ - Bank switched registers */
|
||||
eR13_IRQ, eR14_IRQ, eSPSR_IRQ,
|
||||
|
||||
/* Supervisor/Service Mode - Bank switched registers */
|
||||
eR13_SVC, eR14_SVC, eSPSR_SVC,
|
||||
|
||||
/* Abort Mode - Bank switched registers */
|
||||
eR13_ABT, eR14_ABT, eSPSR_ABT,
|
||||
|
||||
/* Undefined Mode - Bank switched registers */
|
||||
eR13_UND, eR14_UND, eSPSR_UND,
|
||||
|
||||
kNumRegisters
|
||||
};
|
||||
|
||||
/* Coprocessor-related macros */
|
||||
#define COPRO_TLB_BASE cpustate->tlbBase
|
||||
#define COPRO_TLB_BASE_MASK 0xffffc000
|
||||
#define COPRO_TLB_VADDR_FLTI_MASK 0xfff00000
|
||||
#define COPRO_TLB_VADDR_FLTI_MASK_SHIFT 18
|
||||
#define COPRO_TLB_VADDR_CSLTI_MASK 0x000ff000
|
||||
#define COPRO_TLB_VADDR_CSLTI_MASK_SHIFT 10
|
||||
#define COPRO_TLB_VADDR_FSLTI_MASK 0x000ffc00
|
||||
#define COPRO_TLB_VADDR_FSLTI_MASK_SHIFT 8
|
||||
#define COPRO_TLB_CFLD_ADDR_MASK 0xfffffc00
|
||||
#define COPRO_TLB_CFLD_ADDR_MASK_SHIFT 10
|
||||
#define COPRO_TLB_SECTION_PAGE_MASK 0xfff00000
|
||||
#define COPRO_TLB_LARGE_PAGE_MASK 0xffff0000
|
||||
#define COPRO_TLB_SMALL_PAGE_MASK 0xfffff000
|
||||
#define COPRO_TLB_TINY_PAGE_MASK 0xfffffc00
|
||||
#define COPRO_TLB_UNMAPPED 0
|
||||
#define COPRO_TLB_LARGE_PAGE 1
|
||||
#define COPRO_TLB_SMALL_PAGE 2
|
||||
#define COPRO_TLB_TINY_PAGE 3
|
||||
#define COPRO_TLB_COARSE_TABLE 1
|
||||
#define COPRO_TLB_SECTION_TABLE 2
|
||||
#define COPRO_TLB_FINE_TABLE 3
|
||||
|
||||
#define COPRO_CTRL cpustate->control
|
||||
#define COPRO_CTRL_MMU_EN 0x00000001
|
||||
#define COPRO_CTRL_ADDRFAULT_EN 0x00000002
|
||||
#define COPRO_CTRL_DCACHE_EN 0x00000004
|
||||
#define COPRO_CTRL_WRITEBUF_EN 0x00000008
|
||||
#define COPRO_CTRL_ENDIAN 0x00000080
|
||||
#define COPRO_CTRL_SYSTEM 0x00000100
|
||||
#define COPRO_CTRL_ROM 0x00000200
|
||||
#define COPRO_CTRL_ICACHE_EN 0x00001000
|
||||
#define COPRO_CTRL_INTVEC_ADJUST 0x00002000
|
||||
#define COPRO_CTRL_ADDRFAULT_EN_SHIFT 1
|
||||
#define COPRO_CTRL_DCACHE_EN_SHIFT 2
|
||||
#define COPRO_CTRL_WRITEBUF_EN_SHIFT 3
|
||||
#define COPRO_CTRL_ENDIAN_SHIFT 7
|
||||
#define COPRO_CTRL_SYSTEM_SHIFT 8
|
||||
#define COPRO_CTRL_ROM_SHIFT 9
|
||||
#define COPRO_CTRL_ICACHE_EN_SHIFT 12
|
||||
#define COPRO_CTRL_INTVEC_ADJUST_SHIFT 13
|
||||
#define COPRO_CTRL_LITTLE_ENDIAN 0
|
||||
#define COPRO_CTRL_BIG_ENDIAN 1
|
||||
#define COPRO_CTRL_INTVEC_0 0
|
||||
#define COPRO_CTRL_INTVEC_F 1
|
||||
#define COPRO_CTRL_MASK 0x0000338f
|
||||
|
||||
/* Coprocessor Registers */
|
||||
#define ARM7COPRO_REGS \
|
||||
UINT32 control; \
|
||||
UINT32 tlbBase;
|
||||
|
||||
enum
|
||||
{
|
||||
eARM_ARCHFLAGS_T = 1, /* Thumb present */
|
||||
eARM_ARCHFLAGS_E = 2, /* extended DSP operations present (only for v5+) */
|
||||
eARM_ARCHFLAGS_J = 4, /* "Jazelle" (direct execution of Java bytecode) */
|
||||
eARM_ARCHFLAGS_MMU = 8, /* has on-board MMU (traditional ARM style like the SA1110) */
|
||||
eARM_ARCHFLAGS_SA = 16, /* StrongARM extensions (enhanced TLB) */
|
||||
eARM_ARCHFLAGS_XSCALE = 32 /* XScale extensions (CP14, enhanced TLB) */
|
||||
};
|
||||
|
||||
#define ARM7CORE_REGS \
|
||||
UINT32 sArmRegister[kNumRegisters]; \
|
||||
UINT8 pendingIrq; \
|
||||
UINT8 pendingFiq; \
|
||||
UINT8 pendingAbtD; \
|
||||
UINT8 pendingAbtP; \
|
||||
UINT8 pendingUnd; \
|
||||
UINT8 pendingSwi; \
|
||||
INT32 iCount; \
|
||||
int endian; \
|
||||
int (*irq_callback)(int irqline);
|
||||
|
||||
|
||||
/* CPU state struct */
|
||||
typedef struct
|
||||
{
|
||||
ARM7CORE_REGS /* these must be included in your cpu specific register implementation */
|
||||
ARM7COPRO_REGS
|
||||
|
||||
UINT8 archRev; /* ARM architecture revision (3, 4, and 5 are valid) */
|
||||
UINT8 archFlags; /* architecture flags */
|
||||
|
||||
} arm_state;
|
||||
|
||||
/****************************************************************************************************
|
||||
* VARIOUS INTERNAL STRUCS/DEFINES/ETC..
|
||||
***************************************************************************************************/
|
||||
/* Mode values come from bit 4-0 of CPSR, but we are ignoring bit 4 here, since bit 4 always = 1 for valid modes */
|
||||
enum
|
||||
{
|
||||
eARM7_MODE_USER = 0x0, /* Bit: 4-0 = 10000 */
|
||||
eARM7_MODE_FIQ = 0x1, /* Bit: 4-0 = 10001 */
|
||||
eARM7_MODE_IRQ = 0x2, /* Bit: 4-0 = 10010 */
|
||||
eARM7_MODE_SVC = 0x3, /* Bit: 4-0 = 10011 */
|
||||
eARM7_MODE_ABT = 0x7, /* Bit: 4-0 = 10111 */
|
||||
eARM7_MODE_UND = 0xb, /* Bit: 4-0 = 11011 */
|
||||
eARM7_MODE_SYS = 0xf /* Bit: 4-0 = 11111 */
|
||||
};
|
||||
|
||||
#define ARM7_NUM_MODES 0x10
|
||||
|
||||
static const int thumbCycles[256] =
|
||||
{
|
||||
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0 */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 1 */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 2 */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 3 */
|
||||
1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 4 */
|
||||
2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 5 */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /* 6 */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /* 7 */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /* 8 */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /* 9 */
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* a */
|
||||
1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 4, 1, 1, /* b */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* c */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, /* d */
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* e */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 /* f */
|
||||
};
|
||||
|
||||
/* 17 processor registers are visible at any given time,
|
||||
* banked depending on processor mode.
|
||||
*/
|
||||
|
||||
static const int sRegisterTable[ARM7_NUM_MODES][18] =
|
||||
{
|
||||
{ /* USR */
|
||||
eR0, eR1, eR2, eR3, eR4, eR5, eR6, eR7,
|
||||
eR8, eR9, eR10, eR11, eR12,
|
||||
eR13, eR14,
|
||||
eR15, eCPSR /* No SPSR in this mode */
|
||||
},
|
||||
{ /* FIQ */
|
||||
eR0, eR1, eR2, eR3, eR4, eR5, eR6, eR7,
|
||||
eR8_FIQ, eR9_FIQ, eR10_FIQ, eR11_FIQ, eR12_FIQ,
|
||||
eR13_FIQ, eR14_FIQ,
|
||||
eR15, eCPSR, eSPSR_FIQ
|
||||
},
|
||||
{ /* IRQ */
|
||||
eR0, eR1, eR2, eR3, eR4, eR5, eR6, eR7,
|
||||
eR8, eR9, eR10, eR11, eR12,
|
||||
eR13_IRQ, eR14_IRQ,
|
||||
eR15, eCPSR, eSPSR_IRQ
|
||||
},
|
||||
{ /* SVC */
|
||||
eR0, eR1, eR2, eR3, eR4, eR5, eR6, eR7,
|
||||
eR8, eR9, eR10, eR11, eR12,
|
||||
eR13_SVC, eR14_SVC,
|
||||
eR15, eCPSR, eSPSR_SVC
|
||||
},
|
||||
{0}, {0}, {0}, /* values for modes 4,5,6 are not valid */
|
||||
{ /* ABT */
|
||||
eR0, eR1, eR2, eR3, eR4, eR5, eR6, eR7,
|
||||
eR8, eR9, eR10, eR11, eR12,
|
||||
eR13_ABT, eR14_ABT,
|
||||
eR15, eCPSR, eSPSR_ABT
|
||||
},
|
||||
{0}, {0}, {0}, /* values for modes 8,9,a are not valid! */
|
||||
{ /* UND */
|
||||
eR0, eR1, eR2, eR3, eR4, eR5, eR6, eR7,
|
||||
eR8, eR9, eR10, eR11, eR12,
|
||||
eR13_UND, eR14_UND,
|
||||
eR15, eCPSR, eSPSR_UND
|
||||
},
|
||||
{0}, {0}, {0}, /* values for modes c,d, e are not valid! */
|
||||
{ /* SYS */
|
||||
eR0, eR1, eR2, eR3, eR4, eR5, eR6, eR7,
|
||||
eR8, eR9, eR10, eR11, eR12,
|
||||
eR13, eR14,
|
||||
eR15, eCPSR /* No SPSR in this mode */
|
||||
}
|
||||
};
|
||||
|
||||
#define N_BIT 31
|
||||
#define Z_BIT 30
|
||||
#define C_BIT 29
|
||||
#define V_BIT 28
|
||||
#define Q_BIT 27
|
||||
#define I_BIT 7
|
||||
#define F_BIT 6
|
||||
#define T_BIT 5 /* Thumb mode */
|
||||
|
||||
#define N_MASK ((UINT32)(1 << N_BIT)) /* Negative flag */
|
||||
#define Z_MASK ((UINT32)(1 << Z_BIT)) /* Zero flag */
|
||||
#define C_MASK ((UINT32)(1 << C_BIT)) /* Carry flag */
|
||||
#define V_MASK ((UINT32)(1 << V_BIT)) /* oVerflow flag */
|
||||
#define Q_MASK ((UINT32)(1 << Q_BIT)) /* signed overflow for QADD, MAC */
|
||||
#define I_MASK ((UINT32)(1 << I_BIT)) /* Interrupt request disable */
|
||||
#define F_MASK ((UINT32)(1 << F_BIT)) /* Fast interrupt request disable */
|
||||
#define T_MASK ((UINT32)(1 << T_BIT)) /* Thumb Mode flag */
|
||||
|
||||
#define N_IS_SET(pc) ((pc) & N_MASK)
|
||||
#define Z_IS_SET(pc) ((pc) & Z_MASK)
|
||||
#define C_IS_SET(pc) ((pc) & C_MASK)
|
||||
#define V_IS_SET(pc) ((pc) & V_MASK)
|
||||
#define Q_IS_SET(pc) ((pc) & Q_MASK)
|
||||
#define I_IS_SET(pc) ((pc) & I_MASK)
|
||||
#define F_IS_SET(pc) ((pc) & F_MASK)
|
||||
#define T_IS_SET(pc) ((pc) & T_MASK)
|
||||
|
||||
#define N_IS_CLEAR(pc) (!N_IS_SET(pc))
|
||||
#define Z_IS_CLEAR(pc) (!Z_IS_SET(pc))
|
||||
#define C_IS_CLEAR(pc) (!C_IS_SET(pc))
|
||||
#define V_IS_CLEAR(pc) (!V_IS_SET(pc))
|
||||
#define Q_IS_CLEAR(pc) (!Q_IS_SET(pc))
|
||||
#define I_IS_CLEAR(pc) (!I_IS_SET(pc))
|
||||
#define F_IS_CLEAR(pc) (!F_IS_SET(pc))
|
||||
#define T_IS_CLEAR(pc) (!T_IS_SET(pc))
|
||||
|
||||
/* Deconstructing an instruction */
|
||||
/* todo: use these in all places (including dasm file) */
|
||||
#define INSN_COND ((UINT32)0xf0000000u)
|
||||
#define INSN_SDT_L ((UINT32)0x00100000u)
|
||||
#define INSN_SDT_W ((UINT32)0x00200000u)
|
||||
#define INSN_SDT_B ((UINT32)0x00400000u)
|
||||
#define INSN_SDT_U ((UINT32)0x00800000u)
|
||||
#define INSN_SDT_P ((UINT32)0x01000000u)
|
||||
#define INSN_BDT_L ((UINT32)0x00100000u)
|
||||
#define INSN_BDT_W ((UINT32)0x00200000u)
|
||||
#define INSN_BDT_S ((UINT32)0x00400000u)
|
||||
#define INSN_BDT_U ((UINT32)0x00800000u)
|
||||
#define INSN_BDT_P ((UINT32)0x01000000u)
|
||||
#define INSN_BDT_REGS ((UINT32)0x0000ffffu)
|
||||
#define INSN_SDT_IMM ((UINT32)0x00000fffu)
|
||||
#define INSN_MUL_A ((UINT32)0x00200000u)
|
||||
#define INSN_MUL_RM ((UINT32)0x0000000fu)
|
||||
#define INSN_MUL_RS ((UINT32)0x00000f00u)
|
||||
#define INSN_MUL_RN ((UINT32)0x0000f000u)
|
||||
#define INSN_MUL_RD ((UINT32)0x000f0000u)
|
||||
#define INSN_I ((UINT32)0x02000000u)
|
||||
#define INSN_OPCODE ((UINT32)0x01e00000u)
|
||||
#define INSN_S ((UINT32)0x00100000u)
|
||||
#define INSN_BL ((UINT32)0x01000000u)
|
||||
#define INSN_BRANCH ((UINT32)0x00ffffffu)
|
||||
#define INSN_SWI ((UINT32)0x00ffffffu)
|
||||
#define INSN_RN ((UINT32)0x000f0000u)
|
||||
#define INSN_RD ((UINT32)0x0000f000u)
|
||||
#define INSN_OP2 ((UINT32)0x00000fffu)
|
||||
#define INSN_OP2_SHIFT ((UINT32)0x00000f80u)
|
||||
#define INSN_OP2_SHIFT_TYPE ((UINT32)0x00000070u)
|
||||
#define INSN_OP2_RM ((UINT32)0x0000000fu)
|
||||
#define INSN_OP2_ROTATE ((UINT32)0x00000f00u)
|
||||
#define INSN_OP2_IMM ((UINT32)0x000000ffu)
|
||||
#define INSN_OP2_SHIFT_TYPE_SHIFT 4
|
||||
#define INSN_OP2_SHIFT_SHIFT 7
|
||||
#define INSN_OP2_ROTATE_SHIFT 8
|
||||
#define INSN_MUL_RS_SHIFT 8
|
||||
#define INSN_MUL_RN_SHIFT 12
|
||||
#define INSN_MUL_RD_SHIFT 16
|
||||
#define INSN_OPCODE_SHIFT 21
|
||||
#define INSN_RN_SHIFT 16
|
||||
#define INSN_RD_SHIFT 12
|
||||
#define INSN_COND_SHIFT 28
|
||||
|
||||
#define INSN_COPRO_N ((UINT32) 0x00100000u)
|
||||
#define INSN_COPRO_CREG ((UINT32) 0x000f0000u)
|
||||
#define INSN_COPRO_AREG ((UINT32) 0x0000f000u)
|
||||
#define INSN_COPRO_CPNUM ((UINT32) 0x00000f00u)
|
||||
#define INSN_COPRO_OP2 ((UINT32) 0x000000e0u)
|
||||
#define INSN_COPRO_OP3 ((UINT32) 0x0000000fu)
|
||||
#define INSN_COPRO_N_SHIFT 20
|
||||
#define INSN_COPRO_CREG_SHIFT 16
|
||||
#define INSN_COPRO_AREG_SHIFT 12
|
||||
#define INSN_COPRO_CPNUM_SHIFT 8
|
||||
#define INSN_COPRO_OP2_SHIFT 5
|
||||
|
||||
#define THUMB_INSN_TYPE ((UINT16)0xf000)
|
||||
#define THUMB_COND_TYPE ((UINT16)0x0f00)
|
||||
#define THUMB_GROUP4_TYPE ((UINT16)0x0c00)
|
||||
#define THUMB_GROUP5_TYPE ((UINT16)0x0e00)
|
||||
#define THUMB_GROUP5_RM ((UINT16)0x01c0)
|
||||
#define THUMB_GROUP5_RN ((UINT16)0x0038)
|
||||
#define THUMB_GROUP5_RD ((UINT16)0x0007)
|
||||
#define THUMB_ADDSUB_RNIMM ((UINT16)0x01c0)
|
||||
#define THUMB_ADDSUB_RS ((UINT16)0x0038)
|
||||
#define THUMB_ADDSUB_RD ((UINT16)0x0007)
|
||||
#define THUMB_INSN_ADDSUB ((UINT16)0x0800)
|
||||
#define THUMB_INSN_CMP ((UINT16)0x0800)
|
||||
#define THUMB_INSN_SUB ((UINT16)0x0800)
|
||||
#define THUMB_INSN_IMM_RD ((UINT16)0x0700)
|
||||
#define THUMB_INSN_IMM_S ((UINT16)0x0080)
|
||||
#define THUMB_INSN_IMM ((UINT16)0x00ff)
|
||||
#define THUMB_ADDSUB_TYPE ((UINT16)0x0600)
|
||||
#define THUMB_HIREG_OP ((UINT16)0x0300)
|
||||
#define THUMB_HIREG_H ((UINT16)0x00c0)
|
||||
#define THUMB_HIREG_RS ((UINT16)0x0038)
|
||||
#define THUMB_HIREG_RD ((UINT16)0x0007)
|
||||
#define THUMB_STACKOP_TYPE ((UINT16)0x0f00)
|
||||
#define THUMB_STACKOP_L ((UINT16)0x0800)
|
||||
#define THUMB_STACKOP_RD ((UINT16)0x0700)
|
||||
#define THUMB_ALUOP_TYPE ((UINT16)0x03c0)
|
||||
#define THUMB_BLOP_LO ((UINT16)0x0800)
|
||||
#define THUMB_BLOP_OFFS ((UINT16)0x07ff)
|
||||
#define THUMB_SHIFT_R ((UINT16)0x0800)
|
||||
#define THUMB_SHIFT_AMT ((UINT16)0x07c0)
|
||||
#define THUMB_HALFOP_L ((UINT16)0x0800)
|
||||
#define THUMB_HALFOP_OFFS ((UINT16)0x07c0)
|
||||
#define THUMB_BRANCH_OFFS ((UINT16)0x07ff)
|
||||
#define THUMB_LSOP_L ((UINT16)0x0800)
|
||||
#define THUMB_LSOP_OFFS ((UINT16)0x07c0)
|
||||
#define THUMB_MULTLS ((UINT16)0x0800)
|
||||
#define THUMB_MULTLS_BASE ((UINT16)0x0700)
|
||||
#define THUMB_RELADDR_SP ((UINT16)0x0800)
|
||||
#define THUMB_RELADDR_RD ((UINT16)0x0700)
|
||||
#define THUMB_INSN_TYPE_SHIFT 12
|
||||
#define THUMB_COND_TYPE_SHIFT 8
|
||||
#define THUMB_GROUP4_TYPE_SHIFT 10
|
||||
#define THUMB_GROUP5_TYPE_SHIFT 9
|
||||
#define THUMB_ADDSUB_TYPE_SHIFT 9
|
||||
#define THUMB_INSN_IMM_RD_SHIFT 8
|
||||
#define THUMB_STACKOP_TYPE_SHIFT 8
|
||||
#define THUMB_HIREG_OP_SHIFT 8
|
||||
#define THUMB_STACKOP_RD_SHIFT 8
|
||||
#define THUMB_MULTLS_BASE_SHIFT 8
|
||||
#define THUMB_RELADDR_RD_SHIFT 8
|
||||
#define THUMB_HIREG_H_SHIFT 6
|
||||
#define THUMB_HIREG_RS_SHIFT 3
|
||||
#define THUMB_ALUOP_TYPE_SHIFT 6
|
||||
#define THUMB_SHIFT_AMT_SHIFT 6
|
||||
#define THUMB_HALFOP_OFFS_SHIFT 6
|
||||
#define THUMB_LSOP_OFFS_SHIFT 6
|
||||
#define THUMB_GROUP5_RM_SHIFT 6
|
||||
#define THUMB_GROUP5_RN_SHIFT 3
|
||||
#define THUMB_GROUP5_RD_SHIFT 0
|
||||
#define THUMB_ADDSUB_RNIMM_SHIFT 6
|
||||
#define THUMB_ADDSUB_RS_SHIFT 3
|
||||
#define THUMB_ADDSUB_RD_SHIFT 0
|
||||
|
||||
enum
|
||||
{
|
||||
OPCODE_AND, /* 0000 */
|
||||
OPCODE_EOR, /* 0001 */
|
||||
OPCODE_SUB, /* 0010 */
|
||||
OPCODE_RSB, /* 0011 */
|
||||
OPCODE_ADD, /* 0100 */
|
||||
OPCODE_ADC, /* 0101 */
|
||||
OPCODE_SBC, /* 0110 */
|
||||
OPCODE_RSC, /* 0111 */
|
||||
OPCODE_TST, /* 1000 */
|
||||
OPCODE_TEQ, /* 1001 */
|
||||
OPCODE_CMP, /* 1010 */
|
||||
OPCODE_CMN, /* 1011 */
|
||||
OPCODE_ORR, /* 1100 */
|
||||
OPCODE_MOV, /* 1101 */
|
||||
OPCODE_BIC, /* 1110 */
|
||||
OPCODE_MVN /* 1111 */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
COND_EQ = 0, /* Z equal */
|
||||
COND_NE, /* ~Z not equal */
|
||||
COND_CS, COND_HS = 2, /* C unsigned higher or same */
|
||||
COND_CC, COND_LO = 3, /* ~C unsigned lower */
|
||||
COND_MI, /* N negative */
|
||||
COND_PL, /* ~N positive or zero */
|
||||
COND_VS, /* V overflow */
|
||||
COND_VC, /* ~V no overflow */
|
||||
COND_HI, /* C && ~Z unsigned higher */
|
||||
COND_LS, /* ~C || Z unsigned lower or same */
|
||||
COND_GE, /* N == V greater or equal */
|
||||
COND_LT, /* N != V less than */
|
||||
COND_GT, /* ~Z && N == V greater than */
|
||||
COND_LE, /* Z || N != V less than or equal */
|
||||
COND_AL, /* 1 always */
|
||||
COND_NV /* 0 never */
|
||||
};
|
||||
|
||||
#define LSL(v, s) ((v) << (s))
|
||||
#define LSR(v, s) ((v) >> (s))
|
||||
#define ROL(v, s) (LSL((v), (s)) | (LSR((v), 32u - (s))))
|
||||
#define ROR(v, s) (LSR((v), (s)) | (LSL((v), 32u - (s))))
|
||||
|
||||
/* Convenience Macros */
|
||||
#define R15 ARM7REG(eR15)
|
||||
#define SPSR 17 /* SPSR is always the 18th register in our 0 based array sRegisterTable[][18] */
|
||||
#define GET_CPSR ARM7REG(eCPSR)
|
||||
#define SET_CPSR(v) (GET_CPSR = (v))
|
||||
#define MODE_FLAG 0xF /* Mode bits are 4:0 of CPSR, but we ignore bit 4. */
|
||||
#define GET_MODE (GET_CPSR & MODE_FLAG)
|
||||
#define SIGN_BIT ((UINT32)(1 << 31))
|
||||
#define SIGN_BITS_DIFFER(a, b) (((a) ^ (b)) >> 31)
|
||||
/* I really don't know why these were set to 16-bit, the thumb registers are still 32-bit ... */
|
||||
#define THUMB_SIGN_BIT ((UINT32)(1 << 31))
|
||||
#define THUMB_SIGN_BITS_DIFFER(a, b) (((a)^(b)) >> 31)
|
||||
|
||||
/* At one point I thought these needed to be cpu implementation specific, but they don't.. */
|
||||
#define GET_REGISTER(state, reg) GetRegister(state, reg)
|
||||
#define SET_REGISTER(state, reg, val) SetRegister(state, reg, val)
|
||||
#define ARM7_CHECKIRQ arm7_check_irq_state(cpustate)
|
||||
|
||||
#ifdef UNUSED_DEFINITION
|
||||
extern char *(*arm7_dasm_cop_dt_callback)(arm_state *cpustate, char *pBuf, UINT32 opcode, char *pConditionCode, char *pBuf0);
|
||||
extern char *(*arm7_dasm_cop_rt_callback)(arm_state *cpustate, char *pBuf, UINT32 opcode, char *pConditionCode, char *pBuf0);
|
||||
extern char *(*arm7_dasm_cop_do_callback)(arm_state *cpustate, char *pBuf, UINT32 opcode, char *pConditionCode, char *pBuf0);
|
||||
#endif
|
||||
|
||||
#endif /* __ARM7CORE_H__ */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,930 @@
|
||||
/***************************************************************************
|
||||
|
||||
h83002.c: Hitachi H8/3002 microcontroller emulator
|
||||
|
||||
Original by The_Author & DynaChicken for the ZiNc emulator.
|
||||
MAME changes by R. Belmont, Luca Elia, and Tomasz Slanina.
|
||||
|
||||
TS 20060412 Added exts.l, sub.l, divxs.w (buggy), jsr @reg, rotxl.l reg, mov.l @(adr, reg), reg
|
||||
LE 20070903 Added divxu.b shal.l extu.w dec.l #Imm,Rd subx.b
|
||||
LE 20080202 Separated 3002/3044/3007, Added or.l shal.l rotl.l not.l neg.l exts.w
|
||||
sub/or/xor.l #Imm:32,ERd bset/bnot/bclr.b Rn,@ERd bst/bist.b #Imm:3,@ERd bnot.b #Imm:3,@ERd
|
||||
LE 20090128 Added mov.l ers,@aa:16; bild #xx:3,rd; eepmov.b; bnot #xx:3,@aa:8
|
||||
|
||||
mame2003-plus: backported from the legacy H8/3xx core of MAME 0.152
|
||||
(h8_16.c, h8ops.h, h8periph.c) to the MAME 0.78 CPU interface.
|
||||
Only the H8/3002 model is kept. The on-chip RAM and peripheral
|
||||
registers are handled inside the core, the on-chip I/O ports are
|
||||
routed to the driver through h8_3002_set_io_handlers().
|
||||
|
||||
This core keeps a single global context: get/set_context are no-ops,
|
||||
so only one H8/3002 can exist in a machine (System 12 uses one).
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "cpuintrf.h"
|
||||
#include "memory.h"
|
||||
#include "mamedbg.h"
|
||||
#include "state.h"
|
||||
#include "timer.h"
|
||||
#include "mame.h"
|
||||
#include "driver.h"
|
||||
#include "h83002.h"
|
||||
|
||||
/* H8_LOG((fmt, ...)): debug log, compiled out */
|
||||
#define H8_LOG(x) do { } while (0)
|
||||
|
||||
#define H8_SP (7)
|
||||
|
||||
/* on-chip resources of the H8/3002 */
|
||||
#define H8_IRAM_START 0xfffd10
|
||||
#define H8_IRAM_END 0xffff0f
|
||||
#define H8_REG_START 0xffff10
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* main CPU stuff */
|
||||
UINT32 h8err;
|
||||
UINT32 regs[8];
|
||||
UINT32 pc, ppc;
|
||||
|
||||
UINT32 irq_req[3];
|
||||
|
||||
UINT8 ccr, exr;
|
||||
UINT8 h8nflag, h8vflag, h8cflag, h8zflag, h8iflag, h8hflag;
|
||||
UINT8 h8uflag, h8uiflag;
|
||||
UINT8 incheckirqs;
|
||||
|
||||
UINT8 has_exr;
|
||||
int mode_8bit;
|
||||
|
||||
int (*irq_cb)(int irqline);
|
||||
|
||||
/* onboard peripherals stuff */
|
||||
UINT8 per_regs[0x100];
|
||||
UINT8 iram[H8_IRAM_END - H8_IRAM_START + 1];
|
||||
|
||||
UINT16 h8TCNT[5];
|
||||
UINT8 h8TSTR;
|
||||
|
||||
mame_timer *timer[5];
|
||||
int timer_running[5]; /* timer[] armed (not TIME_NEVER / disabled) */
|
||||
UINT16 tcnt_start[5]; /* TCNT when the timer was last armed */
|
||||
double tcnt_offset[5]; /* time counted before the timer was last armed by a state load */
|
||||
double save_left[5], save_elapsed[5]; /* saved timer state (time left < 0: not armed) */
|
||||
int clock;
|
||||
} h83xx_state;
|
||||
|
||||
static h83xx_state h8state;
|
||||
|
||||
/* cycles left in the timeslice: cpuexec reads and adjusts it (abort,
|
||||
cycles run), so the core counts down this very variable */
|
||||
int h8_3002_ICount;
|
||||
|
||||
static h8_io_read_func h8_io_read = NULL;
|
||||
static h8_io_write_func h8_io_write = NULL;
|
||||
|
||||
void h8_3002_set_io_handlers(h8_io_read_func readfn, h8_io_write_func writefn)
|
||||
{
|
||||
h8_io_read = readfn;
|
||||
h8_io_write = writefn;
|
||||
}
|
||||
|
||||
static data8_t h8_io_read_byte(int port)
|
||||
{
|
||||
return h8_io_read ? h8_io_read(port) : 0;
|
||||
}
|
||||
|
||||
static void h8_io_write_byte(int port, data8_t data)
|
||||
{
|
||||
if (h8_io_write)
|
||||
h8_io_write(port, data);
|
||||
}
|
||||
|
||||
static UINT8 h8_register_read8(h83xx_state *h8, UINT32 address);
|
||||
static void h8_register_write8(h83xx_state *h8, UINT32 address, UINT8 val);
|
||||
void h8_3002_InterruptRequest(h83xx_state *h8, UINT8 source, UINT8 state);
|
||||
|
||||
/***************************************************************************
|
||||
memory access (external bus via the 0.78 memory system, on-chip
|
||||
RAM/registers handled here)
|
||||
***************************************************************************/
|
||||
|
||||
static UINT8 h8_read8(h83xx_state *h8, UINT32 address)
|
||||
{
|
||||
address &= 0xffffff;
|
||||
if (address >= H8_IRAM_START)
|
||||
{
|
||||
if (address <= H8_IRAM_END)
|
||||
return h8->iram[address - H8_IRAM_START];
|
||||
return h8_register_read8(h8, address);
|
||||
}
|
||||
return cpu_readmem24bew(address);
|
||||
}
|
||||
|
||||
static void h8_write8(h83xx_state *h8, UINT32 address, UINT8 data)
|
||||
{
|
||||
address &= 0xffffff;
|
||||
if (address >= H8_IRAM_START)
|
||||
{
|
||||
if (address <= H8_IRAM_END)
|
||||
h8->iram[address - H8_IRAM_START] = data;
|
||||
else
|
||||
h8_register_write8(h8, address, data);
|
||||
return;
|
||||
}
|
||||
cpu_writemem24bew(address, data);
|
||||
}
|
||||
|
||||
static UINT16 h8_read16(h83xx_state *h8, UINT32 address)
|
||||
{
|
||||
address &= 0xfffffe;
|
||||
if (address >= H8_IRAM_START)
|
||||
return (h8_read8(h8, address) << 8) | h8_read8(h8, address + 1);
|
||||
return cpu_readmem24bew_word(address);
|
||||
}
|
||||
|
||||
static void h8_write16(h83xx_state *h8, UINT32 address, UINT16 data)
|
||||
{
|
||||
address &= 0xfffffe;
|
||||
if (address >= H8_IRAM_START)
|
||||
{
|
||||
h8_write8(h8, address, data >> 8);
|
||||
h8_write8(h8, address + 1, data & 0xff);
|
||||
return;
|
||||
}
|
||||
cpu_writemem24bew_word(address, data);
|
||||
}
|
||||
|
||||
static UINT16 h8_readop16(h83xx_state *h8, UINT32 address)
|
||||
{
|
||||
address &= 0xfffffe;
|
||||
if (address >= H8_IRAM_START)
|
||||
return h8_read16(h8, address);
|
||||
return cpu_readop16(address);
|
||||
}
|
||||
|
||||
#define h8_mem_read8(x) h8_read8(h8, x)
|
||||
#define h8_mem_read16(z, x) h8_read16(h8, x)
|
||||
#define h8_mem_write8(x, y) h8_write8(h8, x, y)
|
||||
#define h8_mem_write16(z, x, y) h8_write16(h8, x, y)
|
||||
|
||||
/* timing macros
|
||||
note: we assume a system 12 - type setup where external access is 3+1 states
|
||||
timing will be off somewhat for other configurations. */
|
||||
#define H8_IFETCH_TIMING(x) h8_3002_ICount -= (x) * 4;
|
||||
#define H8_BRANCH_TIMING(x) h8_3002_ICount -= (x) * 4;
|
||||
#define H8_STACK_TIMING(x) h8_3002_ICount -= (x) * 4;
|
||||
#define H8_BYTE_TIMING(x, adr) if (address24 >= 0xffff10) h8_3002_ICount -= (x) * 3; else h8_3002_ICount -= (x) * 4;
|
||||
#define H8_WORD_TIMING(x, adr) if (address24 >= 0xffff10) h8_3002_ICount -= (x) * 3; else h8_3002_ICount -= (x) * 4;
|
||||
#define H8_IOP_TIMING(x) h8_3002_ICount -= (x);
|
||||
|
||||
static UINT32 h8_mem_read32(h83xx_state *h8, UINT32 address)
|
||||
{
|
||||
UINT32 result = h8_read16(h8, address) << 16;
|
||||
return result | h8_read16(h8, address + 2);
|
||||
}
|
||||
|
||||
static void h8_mem_write32(h83xx_state *h8, UINT32 address, UINT32 data)
|
||||
{
|
||||
h8_write16(h8, address, data >> 16);
|
||||
h8_write16(h8, address + 2, data);
|
||||
}
|
||||
|
||||
static void h8_check_irqs(h83xx_state *h8);
|
||||
|
||||
/***************************************************************************
|
||||
implementation
|
||||
***************************************************************************/
|
||||
|
||||
void h8_3002_InterruptRequest(h83xx_state *h8, UINT8 source, UINT8 state)
|
||||
{
|
||||
int request = source / 32;
|
||||
int bit = source % 32;
|
||||
|
||||
/* don't allow clear on external interrupts */
|
||||
if ((source <= 17) && (state == 0)) return;
|
||||
|
||||
if (state)
|
||||
h8->irq_req[request] |= (1<<bit);
|
||||
else
|
||||
h8->irq_req[request] &= ~(1<<bit);
|
||||
}
|
||||
|
||||
static UINT8 h8_get_ccr(h83xx_state *h8)
|
||||
{
|
||||
h8->ccr = 0;
|
||||
if(h8->h8nflag)h8->ccr |= H8_NFLAG;
|
||||
if(h8->h8zflag)h8->ccr |= H8_ZFLAG;
|
||||
if(h8->h8vflag)h8->ccr |= H8_VFLAG;
|
||||
if(h8->h8cflag)h8->ccr |= H8_CFLAG;
|
||||
if(h8->h8uflag)h8->ccr |= H8_UFLAG;
|
||||
if(h8->h8hflag)h8->ccr |= H8_HFLAG;
|
||||
if(h8->h8uiflag)h8->ccr |= H8_UIFLAG;
|
||||
if(h8->h8iflag)h8->ccr |= H8_IFLAG;
|
||||
return h8->ccr;
|
||||
}
|
||||
|
||||
static UINT8 h8_get_exr(h83xx_state *h8)
|
||||
{
|
||||
return h8->exr;
|
||||
}
|
||||
|
||||
/* CCR into the flag bytes, without taking interrupts */
|
||||
static void h8_unpack_ccr(h83xx_state *h8, UINT8 data)
|
||||
{
|
||||
h8->ccr = data;
|
||||
|
||||
h8->h8nflag = (data & H8_NFLAG) ? 1 : 0;
|
||||
h8->h8zflag = (data & H8_ZFLAG) ? 1 : 0;
|
||||
h8->h8vflag = (data & H8_VFLAG) ? 1 : 0;
|
||||
h8->h8cflag = (data & H8_CFLAG) ? 1 : 0;
|
||||
h8->h8hflag = (data & H8_HFLAG) ? 1 : 0;
|
||||
h8->h8iflag = (data & H8_IFLAG) ? 1 : 0;
|
||||
h8->h8uflag = (data & H8_UFLAG) ? 1 : 0;
|
||||
h8->h8uiflag = (data & H8_UIFLAG) ? 1 : 0;
|
||||
}
|
||||
|
||||
static void h8_set_ccr(h83xx_state *h8, UINT8 data)
|
||||
{
|
||||
h8_unpack_ccr(h8, data);
|
||||
|
||||
if (!h8->incheckirqs) h8_check_irqs(h8);
|
||||
}
|
||||
|
||||
static void h8_set_exr(h83xx_state *h8, UINT8 data)
|
||||
{
|
||||
h8->exr = data;
|
||||
}
|
||||
|
||||
/* register numbers come from opcode bits: keep them inside regs[] */
|
||||
static INT16 h8_getreg16(h83xx_state *h8, UINT8 reg)
|
||||
{
|
||||
reg &= 15;
|
||||
if(reg > 7)
|
||||
return h8->regs[reg-8]>>16;
|
||||
else
|
||||
return h8->regs[reg];
|
||||
}
|
||||
|
||||
static void h8_setreg16(h83xx_state *h8, UINT8 reg, UINT16 data)
|
||||
{
|
||||
reg &= 15;
|
||||
if(reg > 7)
|
||||
{
|
||||
h8->regs[reg-8] &= 0xffff;
|
||||
h8->regs[reg-8] |= data<<16;
|
||||
}
|
||||
else
|
||||
{
|
||||
h8->regs[reg] &= 0xffff0000;
|
||||
h8->regs[reg] |= data;
|
||||
}
|
||||
}
|
||||
|
||||
static UINT8 h8_getreg8(h83xx_state *h8, UINT8 reg)
|
||||
{
|
||||
reg &= 15;
|
||||
if(reg > 7)
|
||||
return h8->regs[reg-8];
|
||||
else
|
||||
return h8->regs[reg]>>8;
|
||||
}
|
||||
|
||||
static void h8_setreg8(h83xx_state *h8, UINT8 reg, UINT8 data)
|
||||
{
|
||||
reg &= 15;
|
||||
if(reg > 7)
|
||||
{
|
||||
h8->regs[reg-8] &= 0xffffff00;
|
||||
h8->regs[reg-8] |= data;
|
||||
}
|
||||
else
|
||||
{
|
||||
h8->regs[reg] &= 0xffff00ff;
|
||||
h8->regs[reg] |= data<<8;
|
||||
}
|
||||
}
|
||||
|
||||
static UINT32 h8_getreg32(h83xx_state *h8, UINT8 reg)
|
||||
{
|
||||
return h8->regs[reg & 7];
|
||||
}
|
||||
|
||||
static void h8_setreg32(h83xx_state *h8, UINT8 reg, UINT32 data)
|
||||
{
|
||||
h8->regs[reg & 7] = data;
|
||||
}
|
||||
|
||||
static void h8_GenException(h83xx_state *h8, UINT8 vectornr)
|
||||
{
|
||||
/* push PC on stack (extended mode stack push!) */
|
||||
h8_setreg32(h8, H8_SP, h8_getreg32(h8, H8_SP)-4);
|
||||
h8_mem_write32(h8, h8_getreg32(h8, H8_SP), h8->pc | (h8_get_ccr(h8)<<24));
|
||||
|
||||
/* generate address from vector */
|
||||
h8_set_ccr(h8, h8_get_ccr(h8) | 0x80);
|
||||
if (h8->h8uiflag == 0)
|
||||
h8_set_ccr(h8, h8_get_ccr(h8) | 0x40);
|
||||
h8->pc = h8_mem_read32(h8, vectornr * 4) & 0xffffff;
|
||||
|
||||
/* I couldn't find timing info for exceptions, so this is a guess (based on JSR/BSR) */
|
||||
H8_IFETCH_TIMING(2);
|
||||
H8_STACK_TIMING(2);
|
||||
}
|
||||
|
||||
static int h8_get_priority(h83xx_state *h8, UINT8 bit)
|
||||
{
|
||||
int res = 0;
|
||||
switch(bit)
|
||||
{
|
||||
case 12: /* IRQ0 */
|
||||
if (h8->per_regs[0xF8]&0x80) res = 1;
|
||||
break;
|
||||
case 13: /* IRQ1 */
|
||||
if (h8->per_regs[0xF8]&0x40) res = 1;
|
||||
break;
|
||||
case 14: /* IRQ2 */
|
||||
case 15: /* IRQ3 */
|
||||
if (h8->per_regs[0xF8]&0x20) res = 1;
|
||||
break;
|
||||
case 16: /* IRQ4 */
|
||||
case 17: /* IRQ5 */
|
||||
if (h8->per_regs[0xF8]&0x10) res = 1;
|
||||
break;
|
||||
case 53: /* SCI0 Rx */
|
||||
if (!(h8->per_regs[0xB2]&0x40)) res = -2;
|
||||
else if (h8->per_regs[0xF9]&0x08) res = 1;
|
||||
break;
|
||||
case 54: /* SCI0 Tx Empty */
|
||||
if (!(h8->per_regs[0xB2]&0x80)) res = -2;
|
||||
else if (h8->per_regs[0xF9]&0x08) res = 1;
|
||||
break;
|
||||
case 55: /* SCI0 Tx End */
|
||||
if (!(h8->per_regs[0xB2]&0x04)) res = -2;
|
||||
else if (h8->per_regs[0xF9]&0x08) res = 1;
|
||||
break;
|
||||
case 57: /* SCI1 Rx */
|
||||
if (!(h8->per_regs[0xBA]&0x40)) res = -2;
|
||||
else if (h8->per_regs[0xF9]&0x04) res = 1;
|
||||
break;
|
||||
case 58: /* SCI1 Tx Empty */
|
||||
if (!(h8->per_regs[0xBA]&0x80)) res = -2;
|
||||
else if (h8->per_regs[0xF9]&0x04) res = 1;
|
||||
break;
|
||||
case 59: /* SCI1 Tx End */
|
||||
if (!(h8->per_regs[0xBA]&0x04)) res = -2;
|
||||
else if (h8->per_regs[0xF9]&0x04) res = 1;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static void h8_check_irqs(h83xx_state *h8)
|
||||
{
|
||||
int lv = -1;
|
||||
|
||||
h8->incheckirqs = 1;
|
||||
|
||||
if (h8->has_exr)
|
||||
{
|
||||
lv = (h8->exr & 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (h8->h8iflag == 0)
|
||||
{
|
||||
lv = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((h8->per_regs[0xF2]&0x08)/*SYSCR*/ == 0)
|
||||
{
|
||||
if (h8->h8uiflag == 0)
|
||||
lv = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* any interrupts wanted and can accept ? */
|
||||
if(((h8->irq_req[0] != 0) || (h8->irq_req[1]!= 0) || (h8->irq_req[2] != 0)) && (lv >= 0))
|
||||
{
|
||||
UINT8 bit, source;
|
||||
/* which one ? */
|
||||
for(bit = 0, source = 0xff; source == 0xff && bit < 32; bit++)
|
||||
{
|
||||
if( h8->irq_req[0] & (1<<bit) )
|
||||
{
|
||||
if (h8_get_priority(h8, bit) >= lv)
|
||||
{
|
||||
h8->irq_req[0] &= ~(1<<bit);
|
||||
source = bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(bit = 0; source == 0xff && bit < 32; bit++)
|
||||
{
|
||||
if( h8->irq_req[1] & (1<<bit) )
|
||||
{
|
||||
if (h8_get_priority(h8, bit + 32) >= lv)
|
||||
{
|
||||
h8->irq_req[1] &= ~(1<<bit);
|
||||
source = bit + 32;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(bit = 0; source == 0xff && bit < 32; bit++)
|
||||
{
|
||||
if( h8->irq_req[2] & (1<<bit) )
|
||||
{
|
||||
if (h8_get_priority(h8, bit + 64) >= lv)
|
||||
{
|
||||
h8->irq_req[2] &= ~(1<<bit);
|
||||
source = bit + 64;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* call the MAME callback if it's one of the 6 external IRQs */
|
||||
if (source >= 12 && source <= 17)
|
||||
{
|
||||
if (h8->irq_cb)
|
||||
(*h8->irq_cb)(source - 12 + H8_IRQ0);
|
||||
}
|
||||
|
||||
if (source != 0xff)
|
||||
h8_GenException(h8, source);
|
||||
}
|
||||
|
||||
h8->incheckirqs = 0;
|
||||
}
|
||||
|
||||
#define H8_ADDR_MASK 0xffffff
|
||||
static UINT32 h8_idle_start, h8_idle_end; /* polled memory (end 0 = off) */
|
||||
static UINT32 h8_idle_pc; /* loop start last reached */
|
||||
static int h8_idle_since; /* instructions since then */
|
||||
static int h8_idle_cycles; /* h8_3002_ICount then */
|
||||
|
||||
void h8_3002_set_idle_poll(UINT32 start, UINT32 end)
|
||||
{
|
||||
h8_idle_start = start;
|
||||
h8_idle_end = end;
|
||||
}
|
||||
|
||||
/* at "mov.b @aa:24, Rd": the start of a polling loop? skip passes */
|
||||
static void h8_idle_check(h83xx_state *h8)
|
||||
{
|
||||
UINT32 address = ((UINT32)h8_readop16(h8, h8->pc + 2) << 16) | h8_readop16(h8, h8->pc + 4);
|
||||
UINT16 branch = h8_readop16(h8, h8->pc + 6);
|
||||
|
||||
address &= 0xffffff;
|
||||
if (address < h8_idle_start || address > h8_idle_end || (branch != 0x46f8 && branch != 0x47f8))
|
||||
{
|
||||
h8_idle_since = -1;
|
||||
return;
|
||||
}
|
||||
/* one whole pass just ran: skip the passes that still fit */
|
||||
if (h8->pc == h8_idle_pc && h8_idle_since == 2)
|
||||
{
|
||||
int pass = h8_idle_cycles - h8_3002_ICount;
|
||||
if (pass > 0 && h8_3002_ICount > pass)
|
||||
h8_3002_ICount -= ((h8_3002_ICount - 1) / pass) * pass;
|
||||
}
|
||||
h8_idle_pc = h8->pc;
|
||||
h8_idle_since = 0;
|
||||
h8_idle_cycles = h8_3002_ICount;
|
||||
}
|
||||
|
||||
#include "h8ops.h"
|
||||
|
||||
/***************************************************************************
|
||||
on-chip peripherals (ITU timers, ports, serial, ADC)
|
||||
***************************************************************************/
|
||||
|
||||
/* timer registers */
|
||||
#define TSTR (0x60)
|
||||
#define TIER0 (0x66)
|
||||
#define TIER1 (0x70)
|
||||
#define TIER2 (0x7a)
|
||||
#define TIER3 (0x84)
|
||||
#define TIER4 (0x94)
|
||||
#define TSR0 (0x67)
|
||||
#define TSR1 (0x71)
|
||||
#define TSR2 (0x7b)
|
||||
#define TSR3 (0x85)
|
||||
#define TSR4 (0x95)
|
||||
#define TCR0 (0x64)
|
||||
#define TCR1 (0x6e)
|
||||
#define TCR2 (0x78)
|
||||
#define TCR3 (0x82)
|
||||
#define TCR4 (0x92)
|
||||
|
||||
static const UINT8 tsr[5] = { TSR0, TSR1, TSR2, TSR3, TSR4 };
|
||||
static const UINT8 tier[5] = { TIER0, TIER1, TIER2, TIER3, TIER4 };
|
||||
static const UINT8 tcr[5] = { TCR0, TCR1, TCR2, TCR3, TCR4 };
|
||||
static const int tscales[4] = { 1, 2, 4, 8 };
|
||||
|
||||
static void h8itu_timer_expire(int which)
|
||||
{
|
||||
h83xx_state *h8 = &h8state;
|
||||
|
||||
timer_adjust(h8->timer[which], TIME_NEVER, 0, 0);
|
||||
h8->timer_running[which] = 0;
|
||||
h8->tcnt_offset[which] = 0;
|
||||
h8->tcnt_start[which] = 0;
|
||||
h8->h8TCNT[which] = 0;
|
||||
h8->per_regs[tsr[which]] |= 4;
|
||||
/* interrupt on overflow ? */
|
||||
if(h8->per_regs[tier[which]] & 4)
|
||||
{
|
||||
h8_3002_InterruptRequest(h8, 26 + 4*which, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void h8_itu_refresh_timer(h83xx_state *h8, int tnum)
|
||||
{
|
||||
int ourTCR = h8->per_regs[tcr[tnum]];
|
||||
int ourTVAL = h8->h8TCNT[tnum];
|
||||
double period;
|
||||
|
||||
period = TIME_IN_HZ(h8->clock) * tscales[ourTCR & 3] * (65536 - ourTVAL);
|
||||
|
||||
if (ourTCR & 4)
|
||||
H8_LOG(("H8/3002: Timer %d is using an external clock. Unsupported!\n", tnum));
|
||||
|
||||
timer_adjust(h8->timer[tnum], period, tnum, 0);
|
||||
h8->timer_running[tnum] = 1;
|
||||
h8->tcnt_start[tnum] = ourTVAL;
|
||||
h8->tcnt_offset[tnum] = 0;
|
||||
}
|
||||
|
||||
static void h8_itu_sync_timers(h83xx_state *h8, int tnum)
|
||||
{
|
||||
int ourTCR = h8->per_regs[tcr[tnum]];
|
||||
double cycle_time, cur;
|
||||
|
||||
/* get the time per unit */
|
||||
cycle_time = TIME_IN_HZ(h8->clock) * tscales[ourTCR & 3];
|
||||
cur = timer_timeelapsed(h8->timer[tnum]) + h8->tcnt_offset[tnum];
|
||||
|
||||
/* counted from the TCNT value the timer was armed with */
|
||||
h8->h8TCNT[tnum] = (UINT16)(h8->tcnt_start[tnum] + (UINT32)(cur / cycle_time));
|
||||
}
|
||||
|
||||
static UINT8 h8_itu_read8(h83xx_state *h8, UINT8 reg)
|
||||
{
|
||||
switch(reg)
|
||||
{
|
||||
case 0x60: return h8->h8TSTR;
|
||||
case 0x68: h8_itu_sync_timers(h8, 0); return h8->h8TCNT[0]>>8;
|
||||
case 0x69: h8_itu_sync_timers(h8, 0); return h8->h8TCNT[0]&0xff;
|
||||
case 0x72: h8_itu_sync_timers(h8, 1); return h8->h8TCNT[1]>>8;
|
||||
case 0x73: h8_itu_sync_timers(h8, 1); return h8->h8TCNT[1]&0xff;
|
||||
case 0x7c: h8_itu_sync_timers(h8, 2); return h8->h8TCNT[2]>>8;
|
||||
case 0x7d: h8_itu_sync_timers(h8, 2); return h8->h8TCNT[2]&0xff;
|
||||
case 0x86: h8_itu_sync_timers(h8, 3); return h8->h8TCNT[3]>>8;
|
||||
case 0x87: h8_itu_sync_timers(h8, 3); return h8->h8TCNT[3]&0xff;
|
||||
default: return h8->per_regs[reg];
|
||||
}
|
||||
}
|
||||
|
||||
static void h8_itu_write8(h83xx_state *h8, UINT8 reg, UINT8 val)
|
||||
{
|
||||
int t;
|
||||
|
||||
h8->per_regs[reg] = val;
|
||||
switch(reg)
|
||||
{
|
||||
case 0x60:
|
||||
for (t = 0; t < 5; t++)
|
||||
if ((val & (1 << t)) && !(h8->h8TSTR & (1 << t)))
|
||||
h8_itu_refresh_timer(h8, t);
|
||||
h8->h8TSTR = val;
|
||||
break;
|
||||
case 0x68: h8->h8TCNT[0] = (val<<8) | (h8->h8TCNT[0] & 0xff); if (h8->h8TSTR & 0x01) h8_itu_refresh_timer(h8, 0); break;
|
||||
case 0x69: h8->h8TCNT[0] = (val) | (h8->h8TCNT[0] & 0xff00); if (h8->h8TSTR & 0x01) h8_itu_refresh_timer(h8, 0); break;
|
||||
case 0x72: h8->h8TCNT[1] = (val<<8) | (h8->h8TCNT[1] & 0xff); if (h8->h8TSTR & 0x02) h8_itu_refresh_timer(h8, 1); break;
|
||||
case 0x73: h8->h8TCNT[1] = (val) | (h8->h8TCNT[1] & 0xff00); if (h8->h8TSTR & 0x02) h8_itu_refresh_timer(h8, 1); break;
|
||||
case 0x7c: h8->h8TCNT[2] = (val<<8) | (h8->h8TCNT[2] & 0xff); if (h8->h8TSTR & 0x04) h8_itu_refresh_timer(h8, 2); break;
|
||||
case 0x7d: h8->h8TCNT[2] = (val) | (h8->h8TCNT[2] & 0xff00); if (h8->h8TSTR & 0x04) h8_itu_refresh_timer(h8, 2); break;
|
||||
case 0x86: h8->h8TCNT[3] = (val<<8) | (h8->h8TCNT[3] & 0xff); if (h8->h8TSTR & 0x08) h8_itu_refresh_timer(h8, 3); break;
|
||||
case 0x87: h8->h8TCNT[3] = (val) | (h8->h8TCNT[3] & 0xff00); if (h8->h8TSTR & 0x08) h8_itu_refresh_timer(h8, 3); break;
|
||||
case 0x96: h8->h8TCNT[4] = (val<<8) | (h8->h8TCNT[4] & 0xff); if (h8->h8TSTR & 0x10) h8_itu_refresh_timer(h8, 4); break;
|
||||
case 0x97: h8->h8TCNT[4] = (val) | (h8->h8TCNT[4] & 0xff00); if (h8->h8TSTR & 0x10) h8_itu_refresh_timer(h8, 4); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
static UINT8 h8_ISR_r(h83xx_state *h8)
|
||||
{
|
||||
UINT8 res = 0;
|
||||
int i;
|
||||
for (i = 0; i < 6; i++)
|
||||
if (h8->irq_req[0] & (1 << (12+i))) res |= (1 << i);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void h8_ISR_w(h83xx_state *h8, UINT8 val)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 6; i++)
|
||||
if ((~val) & (1 << i)) h8->irq_req[0] &= ~(1 << (12+i));
|
||||
}
|
||||
|
||||
static UINT8 h8_register_read8(h83xx_state *h8, UINT32 address)
|
||||
{
|
||||
UINT8 val;
|
||||
UINT8 reg = address & 0xff;
|
||||
|
||||
if(reg >= 0x60 && reg <= 0x9f)
|
||||
return h8_itu_read8(h8, reg);
|
||||
|
||||
switch(reg)
|
||||
{
|
||||
case 0xb4: /* serial port A status */
|
||||
val = h8->per_regs[reg];
|
||||
val |= 0xc4; /* transmit finished, receive ready, no errors */
|
||||
break;
|
||||
case 0xb5: val = h8_io_read_byte(H8_SERIAL_0); break; /* serial port A receive */
|
||||
case 0xbc: /* serial port B status */
|
||||
val = h8->per_regs[reg];
|
||||
val |= 0xc4; /* transmit finished, receive ready, no errors */
|
||||
break;
|
||||
case 0xbd: val = h8_io_read_byte(H8_SERIAL_1); break; /* serial port B receive */
|
||||
case 0xe0: val = h8_io_read_byte(H8_ADC_0_H); break;
|
||||
case 0xe1: val = h8_io_read_byte(H8_ADC_0_L); break;
|
||||
case 0xe2: val = h8_io_read_byte(H8_ADC_1_H); break;
|
||||
case 0xe3: val = h8_io_read_byte(H8_ADC_1_L); break;
|
||||
case 0xe4: val = h8_io_read_byte(H8_ADC_2_H); break;
|
||||
case 0xe5: val = h8_io_read_byte(H8_ADC_2_L); break;
|
||||
case 0xe6: val = h8_io_read_byte(H8_ADC_3_H); break;
|
||||
case 0xe7: val = h8_io_read_byte(H8_ADC_3_L); break;
|
||||
case 0xe8: val = 0x80; break; /* adc status */
|
||||
case 0xc7: val = h8_io_read_byte(H8_PORT_4); break; /* port 4 data */
|
||||
case 0xcb: val = h8_io_read_byte(H8_PORT_6); break; /* port 6 data */
|
||||
case 0xce: val = h8_io_read_byte(H8_PORT_7); break; /* port 7 data */
|
||||
case 0xcf: val = h8_io_read_byte(H8_PORT_8); break; /* port 8 data */
|
||||
case 0xd2: val = h8_io_read_byte(H8_PORT_9); break; /* port 9 data */
|
||||
case 0xd3: val = h8_io_read_byte(H8_PORT_A); break; /* port a data */
|
||||
case 0xd6: val = h8_io_read_byte(H8_PORT_B); break; /* port b data */
|
||||
case 0xf6: val = h8_ISR_r(h8); break;
|
||||
default: val = h8->per_regs[reg]; break;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void h8_register_write8(h83xx_state *h8, UINT32 address, UINT8 val)
|
||||
{
|
||||
UINT8 reg = address & 0xff;
|
||||
|
||||
if(reg >= 0x60 && reg <= 0x9f)
|
||||
h8_itu_write8(h8, reg, val);
|
||||
|
||||
switch (reg)
|
||||
{
|
||||
case 0xb3: /* serial 0 send */
|
||||
h8_io_write_byte(H8_SERIAL_0, val);
|
||||
h8_3002_InterruptRequest(h8, 54, 1);
|
||||
h8_3002_InterruptRequest(h8, 55, 1);
|
||||
break;
|
||||
case 0xbb: /* serial 1 send */
|
||||
h8_io_write_byte(H8_SERIAL_1, val);
|
||||
h8_3002_InterruptRequest(h8, 58, 1);
|
||||
h8_3002_InterruptRequest(h8, 59, 1);
|
||||
break;
|
||||
case 0xc7: h8_io_write_byte(H8_PORT_4, val); break;
|
||||
case 0xcb: h8_io_write_byte(H8_PORT_6, val); break;
|
||||
case 0xce: h8_io_write_byte(H8_PORT_7, val); break;
|
||||
case 0xcf: h8_io_write_byte(H8_PORT_8, val); break;
|
||||
case 0xd2: h8_io_write_byte(H8_PORT_9, val); break;
|
||||
case 0xd3: h8_io_write_byte(H8_PORT_A, val); break;
|
||||
case 0xd6: h8_io_write_byte(H8_PORT_B, val); break;
|
||||
case 0xf6: h8_ISR_w(h8, val); break;
|
||||
}
|
||||
|
||||
h8->per_regs[reg] = val;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
MAME 0.78 interface
|
||||
***************************************************************************/
|
||||
|
||||
/* the ITU timers are MAME timers, which a state does not hold: save how
|
||||
long each one has run and how long it has left, and re-arm them on load */
|
||||
static void h8_onstatesave(void)
|
||||
{
|
||||
h83xx_state *h8 = &h8state;
|
||||
int i;
|
||||
|
||||
/* the live flags are the flag bytes: ccr holds them in the state */
|
||||
h8_get_ccr(h8);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
h8->save_left[i] = h8->timer_running[i] ? timer_timeleft(h8->timer[i]) : -1;
|
||||
h8->save_elapsed[i] = timer_timeelapsed(h8->timer[i]) + h8->tcnt_offset[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void h8_onstateload(void)
|
||||
{
|
||||
h83xx_state *h8 = &h8state;
|
||||
int i;
|
||||
|
||||
/* flags only: a load must not take an interrupt */
|
||||
h8_unpack_ccr(h8, h8->ccr);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
if (h8->save_left[i] >= 0)
|
||||
{
|
||||
timer_adjust(h8->timer[i], h8->save_left[i], i, 0);
|
||||
h8->timer_running[i] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
timer_adjust(h8->timer[i], TIME_NEVER, 0, 0);
|
||||
timer_enable(h8->timer[i], 0);
|
||||
h8->timer_running[i] = 0;
|
||||
}
|
||||
h8->tcnt_offset[i] = h8->save_elapsed[i];
|
||||
}
|
||||
}
|
||||
|
||||
void h8_3002_init(void)
|
||||
{
|
||||
h83xx_state *h8 = &h8state;
|
||||
int cpu = cpu_getactivecpu();
|
||||
int i;
|
||||
|
||||
memset(h8, 0, sizeof(*h8));
|
||||
h8->h8iflag = 1;
|
||||
h8->mode_8bit = 0;
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
h8->timer[i] = timer_alloc(h8itu_timer_expire);
|
||||
|
||||
state_save_register_UINT32("h8_3002", cpu, "h8err", &h8->h8err, 1);
|
||||
state_save_register_UINT32("h8_3002", cpu, "regs", h8->regs, 8);
|
||||
state_save_register_UINT32("h8_3002", cpu, "pc", &h8->pc, 1);
|
||||
state_save_register_UINT32("h8_3002", cpu, "ppc", &h8->ppc, 1);
|
||||
state_save_register_UINT32("h8_3002", cpu, "irq_req", h8->irq_req, 3);
|
||||
state_save_register_UINT8 ("h8_3002", cpu, "ccr", &h8->ccr, 1);
|
||||
state_save_register_UINT8 ("h8_3002", cpu, "per_regs", h8->per_regs, 0x100);
|
||||
state_save_register_UINT8 ("h8_3002", cpu, "iram", h8->iram, sizeof(h8->iram));
|
||||
state_save_register_UINT8 ("h8_3002", cpu, "h8TSTR", &h8->h8TSTR, 1);
|
||||
state_save_register_UINT16("h8_3002", cpu, "h8TCNT", h8->h8TCNT, 5);
|
||||
state_save_register_UINT16("h8_3002", cpu, "tcnt_start", h8->tcnt_start, 5);
|
||||
state_save_register_double("h8_3002", cpu, "timer_left", h8->save_left, 5);
|
||||
state_save_register_double("h8_3002", cpu, "timer_elapsed", h8->save_elapsed, 5);
|
||||
state_save_register_func_presave(h8_onstatesave);
|
||||
state_save_register_func_postload(h8_onstateload);
|
||||
}
|
||||
|
||||
void h8_3002_reset(void *param)
|
||||
{
|
||||
h83xx_state *h8 = &h8state;
|
||||
int i;
|
||||
|
||||
h8->clock = Machine->drv->cpu[cpu_getactivecpu()].cpu_clock;
|
||||
|
||||
h8->h8err = 0;
|
||||
memset(h8->regs, 0, sizeof(h8->regs));
|
||||
memset(h8->irq_req, 0, sizeof(h8->irq_req));
|
||||
memset(h8->per_regs, 0, sizeof(h8->per_regs));
|
||||
h8->incheckirqs = 0;
|
||||
h8->exr = 0;
|
||||
h8->has_exr = 0;
|
||||
h8_set_ccr(h8, H8_IFLAG);
|
||||
|
||||
h8->pc = h8_mem_read32(h8, 0) & 0xffffff;
|
||||
h8->ppc = h8->pc;
|
||||
|
||||
/* disable timers */
|
||||
h8->h8TSTR = 0;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
h8->h8TCNT[i] = 0;
|
||||
timer_adjust(h8->timer[i], TIME_NEVER, 0, 0);
|
||||
h8->timer_running[i] = 0;
|
||||
h8->tcnt_start[i] = 0;
|
||||
h8->tcnt_offset[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void h8_3002_exit(void)
|
||||
{
|
||||
h8_idle_end = 0;
|
||||
}
|
||||
|
||||
/* single instance (one H8/3002 per machine): the state lives in h8state,
|
||||
contexts are not swapped */
|
||||
unsigned h8_3002_get_context(void *dst)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void h8_3002_set_context(void *src)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned h8_3002_get_reg(int regnum)
|
||||
{
|
||||
h83xx_state *h8 = &h8state;
|
||||
|
||||
switch (regnum)
|
||||
{
|
||||
case REG_PC:
|
||||
case H8_PC: return h8->pc;
|
||||
case REG_PREVIOUSPC: return h8->ppc;
|
||||
case REG_SP: return h8->regs[7];
|
||||
case H8_CCR: return h8_get_ccr(h8);
|
||||
case H8_E0: case H8_E1: case H8_E2: case H8_E3:
|
||||
case H8_E4: case H8_E5: case H8_E6: case H8_E7:
|
||||
return h8->regs[regnum - H8_E0];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void h8_3002_set_reg(int regnum, unsigned val)
|
||||
{
|
||||
h83xx_state *h8 = &h8state;
|
||||
|
||||
switch (regnum)
|
||||
{
|
||||
case REG_PC:
|
||||
case H8_PC: h8->pc = val & 0xffffff; break;
|
||||
case REG_SP: h8->regs[7] = val; break;
|
||||
case H8_CCR: h8_set_ccr(h8, val); break;
|
||||
case H8_E0: case H8_E1: case H8_E2: case H8_E3:
|
||||
case H8_E4: case H8_E5: case H8_E6: case H8_E7:
|
||||
h8->regs[regnum - H8_E0] = val; break;
|
||||
}
|
||||
}
|
||||
|
||||
void h8_3002_set_irq_line(int irqline, int state)
|
||||
{
|
||||
h83xx_state *h8 = &h8state;
|
||||
int asserted = (state != CLEAR_LINE && state != INTERNAL_CLEAR_LINE);
|
||||
|
||||
switch (irqline)
|
||||
{
|
||||
case H8_IRQ0: case H8_IRQ1: case H8_IRQ2:
|
||||
case H8_IRQ3: case H8_IRQ4: case H8_IRQ5:
|
||||
h8_3002_InterruptRequest(h8, 12 + irqline - H8_IRQ0, asserted);
|
||||
break;
|
||||
case H8_SCI_0_RX: h8_3002_InterruptRequest(h8, 53, asserted); break;
|
||||
case H8_SCI_1_RX: h8_3002_InterruptRequest(h8, 57, asserted); break;
|
||||
}
|
||||
}
|
||||
|
||||
void h8_3002_set_irq_callback(int (*callback)(int irqline))
|
||||
{
|
||||
h8state.irq_cb = callback;
|
||||
}
|
||||
|
||||
const char *h8_3002_info(void *context, int regnum)
|
||||
{
|
||||
static char buffer[16][47+1];
|
||||
static int which = 0;
|
||||
h83xx_state *h8 = &h8state;
|
||||
|
||||
which = (which+1) % 16;
|
||||
buffer[which][0] = '\0';
|
||||
|
||||
switch (regnum)
|
||||
{
|
||||
case CPU_INFO_REG+H8_PC: sprintf(buffer[which], "PC :%06X", h8->pc); break;
|
||||
case CPU_INFO_REG+H8_CCR: sprintf(buffer[which], "CCR :%02X", h8_get_ccr(h8)); break;
|
||||
case CPU_INFO_REG+H8_E0: sprintf(buffer[which], "ER0 :%08X", h8->regs[0]); break;
|
||||
case CPU_INFO_REG+H8_E1: sprintf(buffer[which], "ER1 :%08X", h8->regs[1]); break;
|
||||
case CPU_INFO_REG+H8_E2: sprintf(buffer[which], "ER2 :%08X", h8->regs[2]); break;
|
||||
case CPU_INFO_REG+H8_E3: sprintf(buffer[which], "ER3 :%08X", h8->regs[3]); break;
|
||||
case CPU_INFO_REG+H8_E4: sprintf(buffer[which], "ER4 :%08X", h8->regs[4]); break;
|
||||
case CPU_INFO_REG+H8_E5: sprintf(buffer[which], "ER5 :%08X", h8->regs[5]); break;
|
||||
case CPU_INFO_REG+H8_E6: sprintf(buffer[which], "ER6 :%08X", h8->regs[6]); break;
|
||||
case CPU_INFO_REG+H8_E7: sprintf(buffer[which], " SP :%08X", h8->regs[7]); break;
|
||||
case CPU_INFO_FLAGS:
|
||||
sprintf(buffer[which], "%c%c%c%c%c%c%c%c",
|
||||
h8->h8iflag ? 'I':'i', h8->h8uiflag ? 'U':'u',
|
||||
h8->h8hflag ? 'H':'h', h8->h8uflag ? 'U':'u',
|
||||
h8->h8nflag ? 'N':'n', h8->h8zflag ? 'Z':'z',
|
||||
h8->h8vflag ? 'V':'v', h8->h8cflag ? 'C':'c');
|
||||
break;
|
||||
case CPU_INFO_NAME: return "H8/3002";
|
||||
case CPU_INFO_FAMILY: return "Hitachi H8/300";
|
||||
case CPU_INFO_VERSION: return "1.0";
|
||||
case CPU_INFO_FILE: return __FILE__;
|
||||
case CPU_INFO_CREDITS: return "The_Author & DynaChicken (ZiNc), R. Belmont, Luca Elia, Tomasz Slanina";
|
||||
}
|
||||
return buffer[which];
|
||||
}
|
||||
|
||||
unsigned h8_3002_dasm(char *buffer, unsigned pc)
|
||||
{
|
||||
sprintf(buffer, "$%04X", h8_read16(&h8state, pc));
|
||||
return 2;
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/***************************************************************************
|
||||
|
||||
h83002.h : Public constants and function defs for the H8/3002 emulator.
|
||||
|
||||
Backported to the MAME 0.78 CPU interface (mame2003-plus) from the legacy
|
||||
H8/3xx core of MAME 0.152 (original by The_Author & DynaChicken for ZiNc,
|
||||
MAME changes by R. Belmont, Luca Elia, Tomasz Slanina, Tim Schuerewegen,
|
||||
O. Galibert).
|
||||
|
||||
Only the H8/3002 (16-bit, advanced mode, 24-bit address space) is
|
||||
supported. On-chip RAM (0xfffd10-0xffff0f) and the on-chip peripheral
|
||||
registers (0xffff10-0xffffff) are handled inside the core.
|
||||
|
||||
The 0.78 I/O port space is sized after the data bus (16 bit), so the
|
||||
H8 on-chip ports, ADC and serial channels are routed to the driver
|
||||
through the callbacks below instead of a PORT map.
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _H83002_H_
|
||||
#define _H83002_H_
|
||||
|
||||
#include "osd_cpu.h"
|
||||
|
||||
#define H8_IFLAG 0x80
|
||||
#define H8_UIFLAG 0x40
|
||||
#define H8_HFLAG 0x20
|
||||
#define H8_UFLAG 0x10
|
||||
#define H8_NFLAG 0x08
|
||||
#define H8_ZFLAG 0x04
|
||||
#define H8_VFLAG 0x02
|
||||
#define H8_CFLAG 0x01
|
||||
|
||||
/* registers */
|
||||
enum
|
||||
{
|
||||
H8_E0 = 1,
|
||||
H8_E1,
|
||||
H8_E2,
|
||||
H8_E3,
|
||||
H8_E4,
|
||||
H8_E5,
|
||||
H8_E6,
|
||||
H8_E7,
|
||||
|
||||
H8_PC,
|
||||
H8_CCR
|
||||
};
|
||||
|
||||
/* external interrupt lines */
|
||||
enum
|
||||
{
|
||||
H8_IRQ0 = 0,
|
||||
H8_IRQ1,
|
||||
H8_IRQ2,
|
||||
H8_IRQ3,
|
||||
H8_IRQ4,
|
||||
H8_IRQ5,
|
||||
|
||||
H8_SCI_0_RX, /* incoming character on SCI 0 */
|
||||
H8_SCI_1_RX /* incoming character on SCI 1 */
|
||||
};
|
||||
|
||||
/* I/O "ports" passed to the driver callbacks */
|
||||
enum
|
||||
{
|
||||
/* digital I/O ports */
|
||||
H8_PORT_4 = 3,
|
||||
H8_PORT_6 = 5,
|
||||
H8_PORT_7,
|
||||
H8_PORT_8,
|
||||
H8_PORT_9,
|
||||
H8_PORT_A,
|
||||
H8_PORT_B,
|
||||
|
||||
/* analog inputs */
|
||||
H8_ADC_0_H = 0x20,
|
||||
H8_ADC_0_L,
|
||||
H8_ADC_1_H,
|
||||
H8_ADC_1_L,
|
||||
H8_ADC_2_H,
|
||||
H8_ADC_2_L,
|
||||
H8_ADC_3_H,
|
||||
H8_ADC_3_L,
|
||||
|
||||
/* serial ports */
|
||||
H8_SERIAL_0 = 0x30,
|
||||
H8_SERIAL_1
|
||||
};
|
||||
|
||||
typedef data8_t (*h8_io_read_func)(int port);
|
||||
typedef void (*h8_io_write_func)(int port, data8_t data);
|
||||
|
||||
/* hook the on-chip ports/ADC/serial to the driver (call before reset) */
|
||||
void h8_3002_set_io_handlers(h8_io_read_func readfn, h8_io_write_func writefn);
|
||||
/*
|
||||
Speedup (end 0 = off): memory in start-end only changes outside the
|
||||
H8's timeslice (other CPUs, the H8's own interrupts) and reading it has
|
||||
no side effects. A polling loop on it, "mov.b @aa:24, Rd / bne (or
|
||||
beq) back", leaves the same state on every pass, so once one pass has
|
||||
run in a timeslice the whole passes that still fit are skipped:
|
||||
registers, memory and cycles end up exactly as if they had run.
|
||||
*/
|
||||
void h8_3002_set_idle_poll(UINT32 start, UINT32 end);
|
||||
|
||||
extern int h8_3002_ICount;
|
||||
|
||||
void h8_3002_init(void);
|
||||
void h8_3002_reset(void *param);
|
||||
void h8_3002_exit(void);
|
||||
int h8_3002_execute(int cycles);
|
||||
unsigned h8_3002_get_context(void *dst);
|
||||
void h8_3002_set_context(void *src);
|
||||
unsigned h8_3002_get_reg(int regnum);
|
||||
void h8_3002_set_reg(int regnum, unsigned val);
|
||||
void h8_3002_set_irq_line(int irqline, int state);
|
||||
void h8_3002_set_irq_callback(int (*callback)(int irqline));
|
||||
const char *h8_3002_info(void *context, int regnum);
|
||||
unsigned h8_3002_dasm(char *buffer, unsigned pc);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,104 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* i8051.h
|
||||
* Portable MCS-51 Family Emulator
|
||||
*
|
||||
* Copyright Steve Ellenoff, all rights reserved.
|
||||
*
|
||||
* - This source code is released as freeware for non-commercial purposes.
|
||||
* - You are free to use and redistribute this code in modified or
|
||||
* unmodified form, provided you list me in the credits.
|
||||
* - If you modify this source code, you must add a notice to each modified
|
||||
* source file that it has been changed. If you're a nice person, you
|
||||
* will clearly mark each change too. :)
|
||||
* - If you wish to use this for commercial purposes, please contact me at
|
||||
* sellenoff@hotmail.com
|
||||
* - The author of this copywritten work reserves the right to change the
|
||||
* terms of its usage and license at any time, including retroactively
|
||||
* - This entire notice must remain in the source code.
|
||||
*
|
||||
* October 2008, Couriersud: Major rewrite (MAME 0.128-0.139 mcs51 core)
|
||||
*
|
||||
* MODIFIED for mame2003-plus: backported from MAME 0.139 src/emu/cpu/mcs51
|
||||
* to the MAME 0.78 cpu_interface. DS5002FP and 80C52 variants removed,
|
||||
* internal RAM/SFRs kept inside the CPU context, MOVX routed through
|
||||
* per-CPU driver handlers (the 0.78 core has no DATA address space).
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _I8051_H
|
||||
#define _I8051_H
|
||||
|
||||
#include "cpuintrf.h"
|
||||
#include "osd_cpu.h"
|
||||
#include "memory.h"
|
||||
|
||||
/* The MCS-51 runs one machine cycle every 12 oscillator clocks.
|
||||
Give the CPU clock in the machine driver as XTAL / I8051_CLOCK_DIVIDER. */
|
||||
#define I8051_CLOCK_DIVIDER 12
|
||||
|
||||
/****************************************************************************
|
||||
* Input lines (use with cpu_set_irq_line)
|
||||
* INT0/INT1 follow the TCON IT0/IT1 setting (edge or level);
|
||||
* T0/T1 count 0->1 transitions when the timer is in counter mode,
|
||||
* so drive them with PULSE_LINE.
|
||||
****************************************************************************/
|
||||
enum
|
||||
{
|
||||
I8051_INT0_LINE = 0, /* P3.2: External Interrupt 0 */
|
||||
I8051_INT1_LINE, /* P3.3: External Interrupt 1 */
|
||||
I8051_RX_LINE, /* P3.0: Serial Port Receive Line */
|
||||
I8051_T0_LINE, /* P3.4: Timer 0 External Input */
|
||||
I8051_T1_LINE, /* P3.5: Timer 1 External Input */
|
||||
I8051_INPUT_LINES
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Port space: the four parallel ports. Map them in the MCU's
|
||||
* PORT_READ/PORT_WRITE tables, e.g. { I8051_P1, I8051_P1, mcu_p1_w }
|
||||
****************************************************************************/
|
||||
#define I8051_P0 0x00
|
||||
#define I8051_P1 0x01
|
||||
#define I8051_P2 0x02
|
||||
#define I8051_P3 0x03
|
||||
|
||||
/****************************************************************************
|
||||
* Registers
|
||||
****************************************************************************/
|
||||
enum
|
||||
{
|
||||
I8051_PC=1, I8051_SP, I8051_PSW, I8051_ACC, I8051_B, I8051_DPH, I8051_DPL, I8051_IE,
|
||||
I8051_R0, I8051_R1, I8051_R2, I8051_R3, I8051_R4, I8051_R5, I8051_R6, I8051_R7, I8051_RB
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public functions
|
||||
****************************************************************************/
|
||||
extern int i8051_ICount;
|
||||
|
||||
extern void i8051_init(void);
|
||||
extern void i8051_reset(void *param);
|
||||
extern void i8051_exit(void);
|
||||
extern int i8051_execute(int cycles);
|
||||
extern unsigned i8051_get_context(void *dst);
|
||||
extern void i8051_set_context(void *src);
|
||||
extern unsigned i8051_get_reg(int regnum);
|
||||
extern void i8051_set_reg(int regnum, unsigned val);
|
||||
extern void i8051_set_irq_line(int irqline, int state);
|
||||
extern void i8051_set_irq_callback(int (*callback)(int irqline));
|
||||
extern const char *i8051_info(void *context, int regnum);
|
||||
extern unsigned i8051_dasm(char *buffer, unsigned pc);
|
||||
|
||||
/* External data memory (MOVX). Called from MACHINE_INIT; cpunum is the MCU's
|
||||
CPU index. Unmapped reads return 0xff, unmapped writes are dropped. */
|
||||
extern void i8051_set_movx_handlers(int cpunum, read8_handler rd, write8_handler wr);
|
||||
|
||||
/* Serial port hooks (optional). */
|
||||
extern void i8051_set_serial_tx_callback(int cpunum, void (*callback)(int data));
|
||||
extern void i8051_set_serial_rx_callback(int cpunum, int (*callback)(void));
|
||||
|
||||
/* The 8751 is an 8051 with internal EPROM: the driver loads the dump in the
|
||||
MCU's CPU region exactly as for the 8051. */
|
||||
#define CPU_I8751 CPU_I8051
|
||||
|
||||
#endif /* _I8051_H */
|
||||
@@ -0,0 +1,981 @@
|
||||
/* MODIFIED for mame2003-plus: C89 comments, device reference removed (backport of MAME 0.139 mcs51ops.c) */
|
||||
/*******************************************************************************************
|
||||
NOTE: All registers are accessed directly, instead of using the SFR_R() function for speed
|
||||
Direct register access is availabe from the R_(register name) macros.. ex: ACC for the ACC
|
||||
with the exception of the PC
|
||||
********************************************************************************************/
|
||||
|
||||
/*ACALL code addr 1: aaa1 0001 */
|
||||
OPHANDLER( acall )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab code address byte */
|
||||
PUSH_PC(); /*Save PC to the stack */
|
||||
/*Thanks Gerrit for help with this! :) */
|
||||
PC = (PC & 0xf800) | ((r & 0xe0) << 3) | addr;
|
||||
}
|
||||
|
||||
/*ADD A, #data 1: 0010 0100 */
|
||||
OPHANDLER( add_a_byte )
|
||||
{
|
||||
UINT8 data = ROP_ARG(PC++); /*Grab data */
|
||||
UINT8 result = ACC + data; /*Add data to accumulator */
|
||||
DO_ADD_FLAGS(ACC,data,0); /*Set Flags */
|
||||
SET_ACC(result); /*Store 8 bit result of addtion in ACC */
|
||||
}
|
||||
|
||||
/*ADD A, data addr 1: 0010 0101 */
|
||||
OPHANDLER( add_a_mem )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
UINT8 data = IRAM_R(addr); /*Grab data from data address */
|
||||
UINT8 result = ACC + data; /*Add data to accumulator */
|
||||
DO_ADD_FLAGS(ACC,data,0); /*Set Flags */
|
||||
SET_ACC(result); /*Store 8 bit result of addtion in ACC */
|
||||
}
|
||||
|
||||
/*ADD A, @R0/@R1 1: 0010 011i */
|
||||
OPHANDLER( add_a_ir )
|
||||
{
|
||||
UINT8 data = IRAM_IR(R_REG(r)); /*Grab data from memory pointed to by R0 or R1 */
|
||||
UINT8 result = ACC + data; /*Add data to accumulator */
|
||||
DO_ADD_FLAGS(ACC,data,0); /*Set Flags */
|
||||
SET_ACC(result); /*Store 8 bit result of addtion in ACC */
|
||||
}
|
||||
|
||||
/*ADD A, R0 to R7 1: 0010 1rrr */
|
||||
OPHANDLER( add_a_r )
|
||||
{
|
||||
UINT8 data = R_REG(r); /*Grab data from R0 - R7 */
|
||||
UINT8 result = ACC + data; /*Add data to accumulator */
|
||||
DO_ADD_FLAGS(ACC,data,0); /*Set Flags */
|
||||
SET_ACC(result); /*Store 8 bit result of addtion in ACC */
|
||||
}
|
||||
|
||||
/*ADDC A, #data 1: 0011 0100 */
|
||||
OPHANDLER( addc_a_byte )
|
||||
{
|
||||
UINT8 data = ROP_ARG(PC++); /*Grab data */
|
||||
UINT8 result = ACC + data + GET_CY; /*Add data + carry flag to accumulator */
|
||||
DO_ADD_FLAGS(ACC,data,GET_CY); /*Set Flags */
|
||||
SET_ACC(result); /*Store 8 bit result of addtion in ACC */
|
||||
}
|
||||
|
||||
/*ADDC A, data addr 1: 0011 0101 */
|
||||
OPHANDLER( addc_a_mem )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
UINT8 data = IRAM_R(addr); /*Grab data from data address */
|
||||
UINT8 result = ACC + data + GET_CY; /*Add data + carry flag to accumulator */
|
||||
DO_ADD_FLAGS(ACC,data,GET_CY); /*Set Flags */
|
||||
SET_ACC(result); /*Store 8 bit result of addtion in ACC */
|
||||
}
|
||||
|
||||
/*ADDC A, @R0/@R1 1: 0011 011i */
|
||||
OPHANDLER( addc_a_ir )
|
||||
{
|
||||
UINT8 data = IRAM_IR(R_REG(r)); /*Grab data from memory pointed to by R0 or R1 */
|
||||
UINT8 result = ACC + data + GET_CY; /*Add data + carry flag to accumulator */
|
||||
DO_ADD_FLAGS(ACC,data,GET_CY); /*Set Flags */
|
||||
SET_ACC(result); /*Store 8 bit result of addtion in ACC */
|
||||
}
|
||||
|
||||
/*ADDC A, R0 to R7 1: 0011 1rrr */
|
||||
OPHANDLER( addc_a_r )
|
||||
{
|
||||
UINT8 data = R_REG(r); /*Grab data from R0 - R7 */
|
||||
UINT8 result = ACC + data + GET_CY; /*Add data + carry flag to accumulator */
|
||||
DO_ADD_FLAGS(ACC,data,GET_CY); /*Set Flags */
|
||||
SET_ACC(result); /*Store 8 bit result of addtion in ACC */
|
||||
}
|
||||
|
||||
/*AJMP code addr 1: aaa0 0001 */
|
||||
OPHANDLER( ajmp )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab code address byte */
|
||||
/*Thanks Gerrit for help with this! :) */
|
||||
PC = (PC & 0xf800) | ((r & 0xe0) << 3) | addr;
|
||||
}
|
||||
|
||||
/*ANL data addr, A 1: 0101 0010 */
|
||||
OPHANDLER( anl_mem_a )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
UINT8 data = IRAM_R(addr); /*Grab data from data address */
|
||||
IRAM_W(addr,data & ACC); /*Set data address value to it's value Logical AND with ACC */
|
||||
}
|
||||
|
||||
/*ANL data addr, #data 1: 0101 0011 */
|
||||
OPHANDLER( anl_mem_byte )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
UINT8 data = ROP_ARG(PC++); /*Grab data */
|
||||
UINT8 srcdata = IRAM_R(addr); /*Grab data from data address */
|
||||
IRAM_W(addr,srcdata & data); /*Set data address value to it's value Logical AND with Data */
|
||||
}
|
||||
|
||||
/*ANL A, #data 1: 0101 0100 */
|
||||
OPHANDLER( anl_a_byte )
|
||||
{
|
||||
UINT8 data = ROP_ARG(PC++); /*Grab data */
|
||||
SET_ACC(ACC & data); /*Set ACC to value of ACC Logical AND with Data */
|
||||
}
|
||||
|
||||
/*ANL A, data addr 1: 0101 0101 */
|
||||
OPHANDLER( anl_a_mem )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
UINT8 data = IRAM_R(addr); /*Grab data from data address */
|
||||
SET_ACC(ACC & data); /*Set ACC to value of ACC Logical AND with Data */
|
||||
}
|
||||
|
||||
/*ANL A, @RO/@R1 1: 0101 011i */
|
||||
OPHANDLER( anl_a_ir )
|
||||
{
|
||||
UINT8 data = IRAM_IR(R_REG(r)); /*Grab data from address R0 or R1 points to */
|
||||
SET_ACC(ACC & data); /*Set ACC to value of ACC Logical AND with Data */
|
||||
}
|
||||
|
||||
/*ANL A, RO to R7 1: 0101 1rrr */
|
||||
OPHANDLER( anl_a_r )
|
||||
{
|
||||
UINT8 data = R_REG(r); /*Grab data from R0 - R7 */
|
||||
SET_ACC(ACC & data); /*Set ACC to value of ACC Logical AND with Data */
|
||||
}
|
||||
|
||||
/*ANL C, bit addr 1: 1000 0010 */
|
||||
OPHANDLER( anl_c_bitaddr )
|
||||
{
|
||||
int cy = GET_CY;
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab bit address */
|
||||
UINT8 bit = BIT_R(addr); /*Grab bit data from bit address */
|
||||
SET_CY( (cy & bit) ); /*Set Carry flag to Carry Flag Value Logical AND with Bit */
|
||||
}
|
||||
|
||||
/*ANL C,/bit addr 1: 1011 0000 */
|
||||
OPHANDLER( anl_c_nbitaddr )
|
||||
{
|
||||
int cy = GET_CY;
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab bit address */
|
||||
UINT8 bit = BIT_R(addr); /*Grab bit data from bit address */
|
||||
bit = ((~bit)&1); /*Complement bit */
|
||||
SET_CY( (cy & bit) ); /*Set Carry flag to Carry Flag Value Logical AND with Complemented Bit */
|
||||
}
|
||||
|
||||
/*CJNE A, #data, code addr 1: 1011 0100 */
|
||||
OPHANDLER( cjne_a_byte )
|
||||
{
|
||||
UINT8 data = ROP_ARG(PC++); /*Grab data */
|
||||
INT8 rel_addr = ROP_ARG(PC++); /*Grab relative code address */
|
||||
|
||||
if(ACC != data) /*Jump if values are not equal */
|
||||
{
|
||||
PC = PC + rel_addr;
|
||||
}
|
||||
|
||||
/*Set carry flag to 1 if 1st compare value is < 2nd compare value */
|
||||
SET_CY( (ACC < data) );
|
||||
}
|
||||
|
||||
/*CJNE A, data addr, code addr 1: 1011 0101 */
|
||||
OPHANDLER( cjne_a_mem )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
INT8 rel_addr = ROP_ARG(PC++); /*Grab relative code address */
|
||||
UINT8 data = IRAM_R(addr); /*Pull value from data address */
|
||||
|
||||
if(ACC != data) /*Jump if values are not equal */
|
||||
{
|
||||
PC = PC + rel_addr;
|
||||
}
|
||||
|
||||
/*Set carry flag to 1 if 1st compare value is < 2nd compare value */
|
||||
SET_CY( (ACC < data) );
|
||||
}
|
||||
|
||||
/*CJNE @R0/@R1, #data, code addr 1: 1011 011i */
|
||||
OPHANDLER( cjne_ir_byte )
|
||||
{
|
||||
UINT8 data = ROP_ARG(PC++); /*Grab data */
|
||||
INT8 rel_addr = ROP_ARG(PC++); /*Grab relative code address */
|
||||
UINT8 srcdata = IRAM_IR(R_REG(r)); /*Grab value pointed to by R0 or R1 */
|
||||
|
||||
if(srcdata != data) /*Jump if values are not equal */
|
||||
{
|
||||
PC = PC + rel_addr;
|
||||
}
|
||||
|
||||
/*Set carry flag to 1 if 1st compare value is < 2nd compare value */
|
||||
SET_CY( (srcdata < data) );
|
||||
}
|
||||
|
||||
/*CJNE R0 to R7, #data, code addr 1: 1011 1rrr */
|
||||
OPHANDLER( cjne_r_byte )
|
||||
{
|
||||
UINT8 data = ROP_ARG(PC++); /*Grab data */
|
||||
INT8 rel_addr = ROP_ARG(PC++); /*Grab relative code address */
|
||||
UINT8 srcdata = R_REG(r); /*Grab value of R0 - R7 */
|
||||
|
||||
if(srcdata != data) /*Jump if values are not equal */
|
||||
{
|
||||
PC = PC + rel_addr;
|
||||
}
|
||||
|
||||
/*Set carry flag to 1 if 1st compare value is < 2nd compare value */
|
||||
SET_CY( (srcdata < data) );
|
||||
}
|
||||
|
||||
/*CLR bit addr 1: 1100 0010 */
|
||||
OPHANDLER( clr_bitaddr )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab bit address */
|
||||
BIT_W(addr,0); /*Clear bit at specified bit address */
|
||||
}
|
||||
|
||||
/*CLR C 1: 1100 0011 */
|
||||
OPHANDLER( clr_c )
|
||||
{
|
||||
SET_CY(0); /*Clear Carry Flag */
|
||||
}
|
||||
|
||||
/*CLR A 1: 1110 0100 */
|
||||
OPHANDLER( clr_a )
|
||||
{
|
||||
SET_ACC(0); /*Clear Accumulator */
|
||||
}
|
||||
|
||||
/*CPL bit addr 1: 1011 0010 */
|
||||
OPHANDLER( cpl_bitaddr )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab bit address */
|
||||
UINT8 data = (~BIT_R(addr))&1;
|
||||
BIT_W(addr,data); /*Complement bit at specified bit address */
|
||||
}
|
||||
|
||||
/*CPL C 1: 1011 0011 */
|
||||
OPHANDLER( cpl_c )
|
||||
{
|
||||
UINT8 bit = (~GET_CY)&1; /*Complement Carry Flag */
|
||||
SET_CY(bit);
|
||||
}
|
||||
|
||||
/*CPL A 1: 1111 0100 */
|
||||
OPHANDLER( cpl_a )
|
||||
{
|
||||
UINT8 data = ((~ACC)&0xff);
|
||||
SET_ACC(data); /*Complement Accumulator */
|
||||
}
|
||||
|
||||
/*DA A 1: 1101 0100 */
|
||||
OPHANDLER( da_a )
|
||||
{
|
||||
/*From several sources, since none said the same thing:
|
||||
The decimal adjust instruction is associated with the use of the ADD and ADDC instructions.
|
||||
The eight-bit value in the accumulator is adjusted to form two BCD digits of four bits each.
|
||||
If the accumulator contents bits 0-3 are greater than 9, OR the AC flag is set, then six is added to
|
||||
produce a proper BCD digit.
|
||||
If the carry is set, OR the four high bits 4-7 exceed nine, six is added to the value of these bits.
|
||||
The carry flag will be set if the result is > 0x99, but not cleared otherwise */
|
||||
|
||||
UINT16 new_acc = ACC & 0xff;
|
||||
if(GET_AC || (new_acc & 0x0f) > 0x09)
|
||||
new_acc += 0x06;
|
||||
if(GET_CY || ((new_acc & 0xf0) > 0x90) || (new_acc & ~0xff))
|
||||
new_acc += 0x60;
|
||||
SET_ACC(new_acc&0xff);
|
||||
if(new_acc & ~0xff)
|
||||
SET_CY(1);
|
||||
}
|
||||
|
||||
/*DEC A 1: 0001 0100 */
|
||||
OPHANDLER( dec_a )
|
||||
{
|
||||
SET_ACC(ACC-1);
|
||||
}
|
||||
|
||||
/*DEC data addr 1: 0001 0101 */
|
||||
OPHANDLER( dec_mem )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
UINT8 data = IRAM_R(addr);
|
||||
IRAM_W(addr,data-1);
|
||||
}
|
||||
|
||||
/*DEC @R0/@R1 1: 0001 011i */
|
||||
OPHANDLER( dec_ir )
|
||||
{
|
||||
UINT8 data = IRAM_IR(R_REG(r));
|
||||
IRAM_W(R_REG(r),data-1);
|
||||
}
|
||||
|
||||
/*DEC R0 to R7 1: 0001 1rrr */
|
||||
OPHANDLER( dec_r )
|
||||
{
|
||||
SET_REG(r, R_REG(r) - 1);
|
||||
}
|
||||
|
||||
/*DIV AB 1: 1000 0100 */
|
||||
OPHANDLER( div_ab )
|
||||
{
|
||||
if( B == 0 ) {
|
||||
/*Overflow flag is set! */
|
||||
SET_OV(1);
|
||||
/*Really the values are undefined according to the manual, but we'll just leave them as is.. */
|
||||
/*SET_ACC(0xff); */
|
||||
/*SFR_W(B,0xff); */
|
||||
}
|
||||
else {
|
||||
int a = (int)ACC / B;
|
||||
int b = (int)ACC % B;
|
||||
/*A gets quotient byte, B gets remainder byte */
|
||||
SET_ACC(a);
|
||||
B = b;
|
||||
/*Overflow flag is cleared */
|
||||
SET_OV(0);
|
||||
}
|
||||
/*Carry Flag is always cleared */
|
||||
SET_CY(0);
|
||||
}
|
||||
|
||||
/*DJNZ data addr, code addr 1: 1101 0101 */
|
||||
OPHANDLER( djnz_mem )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
INT8 rel_addr = ROP_ARG(PC++); /*Grab relative code address */
|
||||
IRAM_W(addr,IRAM_R(addr) - 1); /*Decrement value contained at data address */
|
||||
if(IRAM_R(addr) != 0) /*Branch if contents of data address is not 0 */
|
||||
{
|
||||
PC = PC + rel_addr;
|
||||
}
|
||||
}
|
||||
|
||||
/*DJNZ R0 to R7,code addr 1: 1101 1rrr */
|
||||
OPHANDLER( djnz_r )
|
||||
{
|
||||
INT8 rel_addr = ROP_ARG(PC++); /*Grab relative code address */
|
||||
SET_REG(r ,R_REG(r) - 1); /*Decrement value */
|
||||
if(R_REG(r) != 0) /*Branch if contents of R0 - R7 is not 0 */
|
||||
{
|
||||
PC = PC + rel_addr;
|
||||
}
|
||||
}
|
||||
|
||||
/*INC A 1: 0000 0100 */
|
||||
OPHANDLER( inc_a )
|
||||
{
|
||||
SET_ACC(ACC+1);
|
||||
}
|
||||
|
||||
/*INC data addr 1: 0000 0101 */
|
||||
OPHANDLER( inc_mem )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
UINT8 data = IRAM_R(addr);
|
||||
IRAM_W(addr,data+1);
|
||||
}
|
||||
|
||||
/*INC @R0/@R1 1: 0000 011i */
|
||||
OPHANDLER( inc_ir )
|
||||
{
|
||||
UINT8 data = IRAM_IR(R_REG(r));
|
||||
IRAM_W(R_REG(r),data+1);
|
||||
}
|
||||
|
||||
/*INC R0 to R7 1: 0000 1rrr */
|
||||
OPHANDLER( inc_r )
|
||||
{
|
||||
UINT8 data = R_REG(r);
|
||||
SET_REG(r, data + 1);
|
||||
}
|
||||
|
||||
/*INC DPTR 1: 1010 0011 */
|
||||
OPHANDLER( inc_dptr )
|
||||
{
|
||||
UINT16 dptr = (DPTR)+1;
|
||||
SET_DPTR(dptr);
|
||||
}
|
||||
|
||||
/*JB bit addr, code addr 1: 0010 0000 */
|
||||
OPHANDLER( jb )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab bit address */
|
||||
INT8 rel_addr = ROP_ARG(PC++); /*Grab relative code address */
|
||||
if(BIT_R(addr)) /*If bit set at specified bit address, jump */
|
||||
{
|
||||
PC = PC + rel_addr;
|
||||
}
|
||||
}
|
||||
|
||||
/*JBC bit addr, code addr 1: 0001 0000 */
|
||||
OPHANDLER( jbc )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab bit address */
|
||||
INT8 rel_addr = ROP_ARG(PC++); /*Grab relative code address */
|
||||
if(BIT_R(addr)) { /*If bit set at specified bit address, jump */
|
||||
PC = PC + rel_addr;
|
||||
BIT_W(addr,0); /*Clear Bit also */
|
||||
}
|
||||
}
|
||||
|
||||
/*JC code addr 1: 0100 0000 */
|
||||
OPHANDLER( jc )
|
||||
{
|
||||
INT8 rel_addr = ROP_ARG(PC++); /*Grab relative code address */
|
||||
if(GET_CY) /*Jump if Carry Flag Set */
|
||||
{
|
||||
PC = PC + rel_addr;
|
||||
}
|
||||
}
|
||||
|
||||
/*JMP @A+DPTR 1: 0111 0011 */
|
||||
OPHANDLER( jmp_iadptr )
|
||||
{
|
||||
PC = ACC + DPTR;
|
||||
}
|
||||
|
||||
/*JNB bit addr, code addr 1: 0011 0000 */
|
||||
OPHANDLER( jnb )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab bit address */
|
||||
INT8 rel_addr = ROP_ARG(PC++); /*Grab relative code address */
|
||||
if(!BIT_R(addr)) /*If bit NOT set at specified bit address, jump */
|
||||
{
|
||||
PC = PC + rel_addr;
|
||||
}
|
||||
}
|
||||
|
||||
/*JNC code addr 1: 0101 0000 */
|
||||
OPHANDLER( jnc )
|
||||
{
|
||||
INT8 rel_addr = ROP_ARG(PC++); /*Grab relative code address */
|
||||
if(!GET_CY) /*Jump if Carry Flag not set */
|
||||
{
|
||||
PC = PC + rel_addr;
|
||||
}
|
||||
}
|
||||
|
||||
/*JNZ code addr 1: 0111 0000 */
|
||||
OPHANDLER( jnz )
|
||||
{
|
||||
INT8 rel_addr = ROP_ARG(PC++); /*Grab relative code address */
|
||||
if(ACC != 0) /*Branch if ACC is not 0 */
|
||||
{
|
||||
PC = PC+rel_addr;
|
||||
}
|
||||
}
|
||||
|
||||
/*JZ code addr 1: 0110 0000 */
|
||||
OPHANDLER( jz )
|
||||
{
|
||||
INT8 rel_addr = ROP_ARG(PC++); /*Grab relative code address */
|
||||
if(ACC == 0) /*Branch if ACC is 0 */
|
||||
{
|
||||
PC = PC+rel_addr;
|
||||
}
|
||||
}
|
||||
|
||||
/*LCALL code addr 1: 0001 0010 */
|
||||
OPHANDLER( lcall )
|
||||
{
|
||||
UINT8 addr_hi, addr_lo;
|
||||
addr_hi = ROP_ARG(PC++);
|
||||
addr_lo = ROP_ARG(PC++);
|
||||
PUSH_PC();
|
||||
PC = (UINT16)((addr_hi<<8) | addr_lo);
|
||||
}
|
||||
|
||||
/*LJMP code addr 1: 0000 0010 */
|
||||
OPHANDLER( ljmp )
|
||||
{
|
||||
UINT8 addr_hi, addr_lo;
|
||||
addr_hi = ROP_ARG(PC++);
|
||||
addr_lo = ROP_ARG(PC++);
|
||||
PC = (UINT16)((addr_hi<<8) | addr_lo);
|
||||
}
|
||||
|
||||
/*MOV A, #data 1: 0111 0100 */
|
||||
OPHANDLER( mov_a_byte )
|
||||
{
|
||||
UINT8 data = ROP_ARG(PC++); /*Grab data */
|
||||
SET_ACC(data); /*Store data to ACC */
|
||||
}
|
||||
|
||||
/*MOV A, data addr 1: 1110 0101 */
|
||||
OPHANDLER( mov_a_mem )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
SET_ACC(IRAM_R(addr)); /*Store contents of data address to ACC */
|
||||
}
|
||||
|
||||
/*MOV A,@RO/@R1 1: 1110 011i */
|
||||
OPHANDLER( mov_a_ir )
|
||||
{
|
||||
SET_ACC(IRAM_IR(R_REG(r))); /*Store contents of address pointed by R0 or R1 to ACC */
|
||||
}
|
||||
|
||||
/*MOV A,R0 to R7 1: 1110 1rrr */
|
||||
OPHANDLER( mov_a_r )
|
||||
{
|
||||
SET_ACC(R_REG(r)); /*Store contents of R0 - R7 to ACC */
|
||||
}
|
||||
|
||||
/*MOV data addr, #data 1: 0111 0101 */
|
||||
OPHANDLER( mov_mem_byte )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
UINT8 data = ROP_ARG(PC++); /*Grab data */
|
||||
IRAM_W(addr,data); /*Store data to data address location */
|
||||
}
|
||||
|
||||
/*MOV data addr, data addr 1: 1000 0101 */
|
||||
OPHANDLER( mov_mem_mem )
|
||||
{
|
||||
/*1st address is src, 2nd is dst, but the mov command works as mov dst,src) */
|
||||
UINT8 src,dst;
|
||||
src = ROP_ARG(PC++); /*Grab source data address */
|
||||
dst = ROP_ARG(PC++); /*Grab destination data address */
|
||||
IRAM_W(dst,IRAM_R(src)); /*Read source address contents and store to destination address */
|
||||
}
|
||||
|
||||
/*MOV @R0/@R1, #data 1: 0111 011i */
|
||||
OPHANDLER( mov_ir_byte )
|
||||
{
|
||||
UINT8 data = ROP_ARG(PC++); /*Grab data */
|
||||
IRAM_IW(R_REG(r),data); /*Store data to address pointed by R0 or R1 */
|
||||
}
|
||||
|
||||
/*MOV R0 to R7, #data 1: 0111 1rrr */
|
||||
OPHANDLER( mov_r_byte )
|
||||
{
|
||||
UINT8 data = ROP_ARG(PC++); /*Grab data */
|
||||
SET_REG(r, data); /*Store to R0 - R7 */
|
||||
}
|
||||
|
||||
/*MOV data addr, @R0/@R1 1: 1000 011i */
|
||||
OPHANDLER( mov_mem_ir )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
IRAM_W(addr,IRAM_IR(R_REG(r))); /*Store contents pointed to by R0 or R1 to data address */
|
||||
}
|
||||
|
||||
/*MOV data addr,R0 to R7 1: 1000 1rrr */
|
||||
OPHANDLER( mov_mem_r )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
IRAM_W(addr,R_REG(r)); /*Store contents of R0 - R7 to data address */
|
||||
}
|
||||
|
||||
/*MOV DPTR, #data16 1: 1001 0000 */
|
||||
OPHANDLER( mov_dptr_byte )
|
||||
{
|
||||
UINT8 data_hi, data_lo;
|
||||
data_hi = ROP_ARG(PC++); /*Grab hi byte */
|
||||
data_lo = ROP_ARG(PC++); /*Grab lo byte */
|
||||
SET_DPTR((UINT16)((data_hi<<8)|data_lo)); /*Store to DPTR */
|
||||
}
|
||||
|
||||
/*MOV bit addr, C 1: 1001 0010 */
|
||||
OPHANDLER( mov_bitaddr_c )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab bit address */
|
||||
BIT_W(addr,GET_CY); /*Store Carry Flag to Bit Address */
|
||||
}
|
||||
|
||||
/*MOV @R0/@R1, data addr 1: 1010 011i */
|
||||
OPHANDLER( mov_ir_mem )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
IRAM_IW(R_REG(r),IRAM_R(addr)); /*Store data from data address to address pointed to by R0 or R1 */
|
||||
}
|
||||
|
||||
/*MOV R0 to R7, data addr 1: 1010 1rrr */
|
||||
OPHANDLER( mov_r_mem )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
SET_REG(r, IRAM_R(addr)); /*Store to R0 - R7 */
|
||||
}
|
||||
|
||||
/*MOV data addr, A 1: 1111 0101 */
|
||||
OPHANDLER( mov_mem_a )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
IRAM_W(addr,ACC); /*Store A to data address */
|
||||
}
|
||||
|
||||
/*MOV @R0/@R1, A 1: 1111 011i */
|
||||
OPHANDLER( mov_ir_a )
|
||||
{
|
||||
IRAM_IW(R_REG(r),ACC); /*Store A to location pointed to by R0 or R1 */
|
||||
}
|
||||
|
||||
/*MOV R0 to R7, A 1: 1111 1rrr */
|
||||
OPHANDLER( mov_r_a )
|
||||
{
|
||||
SET_REG(r, ACC); /*Store A to R0-R7 */
|
||||
}
|
||||
|
||||
/*MOVC A, @A + PC 1: 1000 0011 */
|
||||
OPHANDLER( movc_a_iapc )
|
||||
{
|
||||
UINT8 data;
|
||||
data = CODEMEM_R(ACC+PC); /*Move a byte from CODE(Program) Memory and store to ACC */
|
||||
SET_ACC(data);
|
||||
}
|
||||
|
||||
/*MOV C, bit addr 1: 1010 0010 */
|
||||
OPHANDLER( mov_c_bitaddr )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab bit address */
|
||||
SET_CY( (BIT_R(addr)) ); /*Store Bit from Bit Address to Carry Flag */
|
||||
}
|
||||
|
||||
/*MOVC A, @A + DPTR 1: 1001 0011 */
|
||||
OPHANDLER( movc_a_iadptr )
|
||||
{
|
||||
UINT8 data;
|
||||
data = CODEMEM_R(ACC + DPTR); /*Move a byte from CODE(Program) Memory and store to ACC */
|
||||
SET_ACC(data);
|
||||
}
|
||||
|
||||
/*MOVX A,@DPTR 1: 1110 0000 */
|
||||
/*(Move External Ram 16 bit address to A) */
|
||||
OPHANDLER( movx_a_idptr )
|
||||
{
|
||||
/* UINT8 byte = DATAMEM_R(R_DPTR); //Grab 1 byte from External DATA memory pointed to by dptr */
|
||||
UINT32 addr = ERAM_ADDR(DPTR, 0xFFFF);
|
||||
UINT8 byte = DATAMEM_R(addr); /*Grab 1 byte from External DATA memory pointed to by dptr */
|
||||
SET_ACC(byte); /*Store to ACC */
|
||||
}
|
||||
|
||||
/*MOVX A, @R0/@R1 1: 1110 001i */
|
||||
/*(Move External Ram 8 bit address to A) */
|
||||
OPHANDLER( movx_a_ir )
|
||||
{
|
||||
UINT32 addr = ERAM_ADDR(R_REG(r),0xFF); /*Grab address by reading location pointed to by R0 or R1 */
|
||||
UINT8 byte = DATAMEM_R(addr); /*Grab 1 byte from External DATA memory pointed to by address */
|
||||
SET_ACC(byte); /*Store to ACC */
|
||||
}
|
||||
|
||||
/*MOVX @DPTR,A 1: 1111 0000 */
|
||||
/*(Move A to External Ram 16 bit address) */
|
||||
OPHANDLER( movx_idptr_a )
|
||||
{
|
||||
/* DATAMEM_W(R_DPTR, ACC); //Store ACC to External DATA memory address pointed to by DPTR */
|
||||
UINT32 addr = ERAM_ADDR(DPTR, 0xFFFF);
|
||||
DATAMEM_W(addr, ACC); /*Store ACC to External DATA memory address pointed to by DPTR */
|
||||
}
|
||||
|
||||
/*MOVX @R0/@R1,A 1: 1111 001i */
|
||||
/*(Move A to External Ram 8 bit address) */
|
||||
OPHANDLER( movx_ir_a )
|
||||
{
|
||||
UINT32 addr = ERAM_ADDR(R_REG(r),0xFF); /*Grab address by reading location pointed to by R0 or R1 */
|
||||
DATAMEM_W(addr, ACC); /*Store ACC to External DATA memory address */
|
||||
}
|
||||
|
||||
/*MUL AB 1: 1010 0100 */
|
||||
OPHANDLER( mul_ab )
|
||||
{
|
||||
UINT16 result = ACC * B;
|
||||
/*A gets lo bits, B gets hi bits of result */
|
||||
B = (UINT8) ((result & 0xFF00) >> 8);
|
||||
SET_ACC((UINT8)(result & 0x00FF));
|
||||
/*Set flags */
|
||||
SET_OV( ((result & 0x100) >> 8) ); /*Set/Clear Overflow Flag if result > 255 */
|
||||
SET_CY(0); /*Carry Flag always cleared */
|
||||
}
|
||||
|
||||
/*NOP 1: 0000 0000 */
|
||||
OPHANDLER( nop )
|
||||
{
|
||||
}
|
||||
|
||||
/*ORL data addr, A 1: 0100 0010 */
|
||||
OPHANDLER( orl_mem_a )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
UINT8 data = IRAM_R(addr); /*Grab data from data address */
|
||||
IRAM_W(addr,data | ACC); /*Set data address value to it's value Logical OR with ACC */
|
||||
}
|
||||
|
||||
/*ORL data addr, #data 1: 0100 0011 */
|
||||
OPHANDLER( orl_mem_byte )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
UINT8 data = ROP_ARG(PC++); /*Grab data */
|
||||
UINT8 srcdata = IRAM_R(addr); /*Grab data from data address */
|
||||
IRAM_W(addr,srcdata | data); /*Set data address value to it's value Logical OR with Data */
|
||||
}
|
||||
|
||||
/*ORL A, #data 1: 0100 0100 */
|
||||
OPHANDLER( orl_a_byte )
|
||||
{
|
||||
UINT8 data = ROP_ARG(PC++); /*Grab data */
|
||||
SET_ACC(ACC | data); /*Set ACC to value of ACC Logical OR with Data */
|
||||
}
|
||||
|
||||
/*ORL A, data addr 1: 0100 0101 */
|
||||
OPHANDLER( orl_a_mem )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
UINT8 data = IRAM_R(addr); /*Grab data from data address */
|
||||
SET_ACC(ACC | data); /*Set ACC to value of ACC Logical OR with Data */
|
||||
}
|
||||
|
||||
/*ORL A, @RO/@R1 1: 0100 011i */
|
||||
OPHANDLER( orl_a_ir )
|
||||
{
|
||||
UINT8 data = IRAM_IR(R_REG(r)); /*Grab data from address R0 or R1 points to */
|
||||
SET_ACC(ACC | data); /*Set ACC to value of ACC Logical OR with Data */
|
||||
}
|
||||
|
||||
/*ORL A, RO to R7 1: 0100 1rrr */
|
||||
OPHANDLER( orl_a_r )
|
||||
{
|
||||
UINT8 data = R_REG(r); /*Grab data from R0 - R7 */
|
||||
SET_ACC(ACC | data); /*Set ACC to value of ACC Logical OR with Data */
|
||||
}
|
||||
|
||||
/*ORL C, bit addr 1: 0111 0010 */
|
||||
OPHANDLER( orl_c_bitaddr )
|
||||
{
|
||||
int cy = GET_CY;
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab bit address */
|
||||
UINT8 bit = BIT_R(addr); /*Grab bit data from bit address */
|
||||
SET_CY( (cy | bit) ); /*Set Carry flag to Carry Flag Value Logical OR with Bit */
|
||||
}
|
||||
|
||||
/*ORL C, /bit addr 1: 1010 0000 */
|
||||
OPHANDLER( orl_c_nbitaddr )
|
||||
{
|
||||
int cy = GET_CY;
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab bit address */
|
||||
UINT8 bit = BIT_R(addr); /*Grab bit data from bit address */
|
||||
bit = ((~bit)&1); /*Complement bit */
|
||||
SET_CY( (cy | bit) ); /*Set Carry flag to Carry Flag Value Logical OR with Complemented Bit */
|
||||
}
|
||||
|
||||
/*POP data addr 1: 1101 0000 */
|
||||
OPHANDLER( pop )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
IRAM_W(addr, IRAM_IR(SP)); /*Store to contents of data addr, data pointed to by Stack - IRAM_IR needed to access upper 128 bytes of stack */
|
||||
/*IRAM_IW(addr, IRAM_IR(R_SP)); //Store to contents of data addr, data pointed to by Stack - doesn't work, sfr's are not restored this way and it's not an indirect access anyway */
|
||||
SP = SP-1; /*Decrement SP */
|
||||
}
|
||||
|
||||
/*PUSH data addr 1: 1100 0000 */
|
||||
OPHANDLER( push )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
UINT8 tmpSP = SP+1; /*Grab and Increment Stack Pointer */
|
||||
SP = tmpSP; /* "" */
|
||||
IRAM_IW(tmpSP, IRAM_R(addr)); /*Store to stack contents of data address - IRAM_IW needed to store to upper 128 bytes of stack, however, can't use IRAM_IR because that won't store the sfrs and it's not an indirect access anyway */
|
||||
}
|
||||
|
||||
/*RET 1: 0010 0010 */
|
||||
OPHANDLER( ret )
|
||||
{
|
||||
POP_PC();
|
||||
}
|
||||
|
||||
/*RETI 1: 0011 0010 */
|
||||
OPHANDLER( reti )
|
||||
{
|
||||
POP_PC();
|
||||
CLEAR_CURRENT_IRQ();
|
||||
}
|
||||
|
||||
/*RL A 1: 0010 0011 */
|
||||
OPHANDLER( rl_a )
|
||||
{
|
||||
/*Left Shift A, Bit 7 carries to Bit 0 */
|
||||
int carry = ((ACC & 0x80) >> 7);
|
||||
int data = (ACC<<1) & 0xfe;
|
||||
SET_ACC( data | carry);
|
||||
}
|
||||
|
||||
/*RLC A 1: 0011 0011 */
|
||||
OPHANDLER( rlc_a )
|
||||
{
|
||||
/*Left Shift A, Bit 7 goes to Carry Flag, Original Carry Flag goes to Bit 0 of ACC */
|
||||
int carry = ((ACC & 0x80) >> 7);
|
||||
int data = ((ACC<<1) & 0xfe) | GET_CY;
|
||||
SET_ACC( data);
|
||||
SET_CY(carry);
|
||||
}
|
||||
|
||||
/*RR A 1: 0000 0011 */
|
||||
OPHANDLER( rr_a )
|
||||
{
|
||||
/*Right Shift A, Bit 0 carries to Bit 7 */
|
||||
int carry = ((ACC & 1) << 7);
|
||||
int data = (ACC>>1) & 0x7f;
|
||||
SET_ACC( data | carry);
|
||||
}
|
||||
|
||||
/*RRC A 1: 0001 0011 */
|
||||
OPHANDLER( rrc_a )
|
||||
{
|
||||
/*Right Shift A, Bit 0 goes to Carry Flag, Bit 7 of ACC gets set to original Carry Flag */
|
||||
int carry = (ACC & 1);
|
||||
int data = ((ACC>>1) & 0x7f) | (GET_CY<<7);
|
||||
SET_ACC( data);
|
||||
SET_CY(carry);
|
||||
}
|
||||
|
||||
/*SETB C 1: 1101 0011 */
|
||||
OPHANDLER( setb_c )
|
||||
{
|
||||
SET_CY(1); /*Set Carry Flag */
|
||||
}
|
||||
|
||||
/*SETB bit addr 1: 1101 0010 */
|
||||
OPHANDLER( setb_bitaddr )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab bit address */
|
||||
BIT_W(addr,1); /*Set Bit at Bit Address */
|
||||
}
|
||||
|
||||
/*SJMP code addr 1: 1000 0000 */
|
||||
OPHANDLER( sjmp )
|
||||
{
|
||||
INT8 rel_addr = ROP_ARG(PC++); /*Grab relative code address */
|
||||
PC = PC + rel_addr; /*Update PC */
|
||||
}
|
||||
|
||||
/*SUBB A, #data 1: 1001 0100 */
|
||||
OPHANDLER( subb_a_byte )
|
||||
{
|
||||
UINT8 data = ROP_ARG(PC++); /*Grab data */
|
||||
UINT8 result = ACC - data - GET_CY; /*Subtract data & carry flag from accumulator */
|
||||
DO_SUB_FLAGS(ACC,data,GET_CY); /*Set Flags */
|
||||
SET_ACC(result); /*Store 8 bit result of addtion in ACC */
|
||||
|
||||
}
|
||||
|
||||
/*SUBB A, data addr 1: 1001 0101 */
|
||||
OPHANDLER( subb_a_mem )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
UINT8 data = IRAM_R(addr); /*Grab data from data address */
|
||||
UINT8 result = ACC - data - GET_CY; /*Subtract data & carry flag from accumulator */
|
||||
DO_SUB_FLAGS(ACC,data,GET_CY); /*Set Flags */
|
||||
SET_ACC(result); /*Store 8 bit result of addtion in ACC */
|
||||
}
|
||||
|
||||
/*SUBB A, @R0/@R1 1: 1001 011i */
|
||||
OPHANDLER( subb_a_ir )
|
||||
{
|
||||
UINT8 data = IRAM_IR(R_REG(r)); /*Grab data from memory pointed to by R0 or R1 */
|
||||
UINT8 result = ACC - data - GET_CY; /*Subtract data & carry flag from accumulator */
|
||||
DO_SUB_FLAGS(ACC,data,GET_CY); /*Set Flags */
|
||||
SET_ACC(result); /*Store 8 bit result of addtion in ACC */
|
||||
}
|
||||
|
||||
/*SUBB A, R0 to R7 1: 1001 1rrr */
|
||||
OPHANDLER( subb_a_r )
|
||||
{
|
||||
UINT8 data = R_REG(r); /*Grab data from R0 - R7 */
|
||||
UINT8 result = ACC - data - GET_CY; /*Subtract data & carry flag from accumulator */
|
||||
DO_SUB_FLAGS(ACC,data,GET_CY); /*Set Flags */
|
||||
SET_ACC(result); /*Store 8 bit result of addtion in ACC */
|
||||
}
|
||||
|
||||
/*SWAP A 1: 1100 0100 */
|
||||
OPHANDLER( swap_a )
|
||||
{
|
||||
UINT8 a_nib_lo, a_nib_hi;
|
||||
a_nib_hi = (ACC & 0x0f) << 4; /*Grab lo byte of ACC and move to hi */
|
||||
a_nib_lo = (ACC & 0xf0) >> 4; /*Grab hi byte of ACC and move to lo */
|
||||
SET_ACC( a_nib_hi | a_nib_lo);
|
||||
}
|
||||
|
||||
/*XCH A, data addr 1: 1100 0101 */
|
||||
OPHANDLER( xch_a_mem )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
UINT8 data = IRAM_R(addr); /*Grab data */
|
||||
UINT8 oldACC = ACC; /*Hold value of ACC */
|
||||
SET_ACC(data); /*Sets ACC to data */
|
||||
IRAM_W(addr,oldACC); /*Sets data address to old value of ACC */
|
||||
}
|
||||
|
||||
/*XCH A, @RO/@R1 1: 1100 011i */
|
||||
OPHANDLER( xch_a_ir )
|
||||
{
|
||||
UINT8 data = IRAM_IR(R_REG(r)); /*Grab data pointed to by R0 or R1 */
|
||||
UINT8 oldACC = ACC; /*Hold value of ACC */
|
||||
SET_ACC(data); /*Sets ACC to data */
|
||||
IRAM_W(R_REG(r),oldACC); /*Sets data address to old value of ACC */
|
||||
}
|
||||
|
||||
/*XCH A, RO to R7 1: 1100 1rrr */
|
||||
OPHANDLER( xch_a_r )
|
||||
{
|
||||
UINT8 data = R_REG(r); /*Grab data from R0-R7 */
|
||||
UINT8 oldACC = ACC; /*Hold value of ACC */
|
||||
SET_ACC(data); /*Sets ACC to data */
|
||||
SET_REG(r, oldACC); /*Sets data address to old value of ACC */
|
||||
}
|
||||
|
||||
/*XCHD A, @R0/@R1 1: 1101 011i */
|
||||
OPHANDLER( xchd_a_ir )
|
||||
{
|
||||
UINT8 acc, ir_data;
|
||||
ir_data = IRAM_IR(R_REG(r)); /*Grab data pointed to by R0 or R1 */
|
||||
acc = ACC; /*Grab ACC value */
|
||||
SET_ACC( (acc & 0xf0) | (ir_data & 0x0f) ); /*Set ACC to lower nibble of data pointed to by R0 or R1 */
|
||||
IRAM_W(R_REG(r), (ir_data & 0xf0) | (acc & 0x0f) ); /*Set data pointed to by R0 or R1 to lower nibble of ACC */
|
||||
}
|
||||
|
||||
/*XRL data addr, A 1: 0110 0010 */
|
||||
OPHANDLER( xrl_mem_a )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
UINT8 data = IRAM_R(addr); /*Grab data from data address */
|
||||
IRAM_W(addr,data ^ ACC); /*Set data address value to it's value Logical XOR with ACC */
|
||||
}
|
||||
|
||||
/*XRL data addr, #data 1: 0110 0011 */
|
||||
OPHANDLER( xrl_mem_byte )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
UINT8 data = ROP_ARG(PC++); /*Grab data */
|
||||
UINT8 srcdata = IRAM_R(addr); /*Grab data from data address */
|
||||
IRAM_W(addr,srcdata ^ data); /*Set data address value to it's value Logical XOR with Data */
|
||||
}
|
||||
|
||||
/*XRL A, #data 1: 0110 0100 */
|
||||
OPHANDLER( xrl_a_byte )
|
||||
{
|
||||
UINT8 data = ROP_ARG(PC++); /*Grab data */
|
||||
SET_ACC(ACC ^ data); /*Set ACC to value of ACC Logical XOR with Data */
|
||||
}
|
||||
|
||||
/*XRL A, data addr 1: 0110 0101 */
|
||||
OPHANDLER( xrl_a_mem )
|
||||
{
|
||||
UINT8 addr = ROP_ARG(PC++); /*Grab data address */
|
||||
UINT8 data = IRAM_R(addr); /*Grab data from data address */
|
||||
SET_ACC(ACC ^ data); /*Set ACC to value of ACC Logical XOR with Data */
|
||||
}
|
||||
|
||||
/*XRL A, @R0/@R1 1: 0110 011i */
|
||||
OPHANDLER( xrl_a_ir )
|
||||
{
|
||||
UINT8 data = IRAM_IR(R_REG(r)); /*Grab data from address R0 or R1 points to */
|
||||
SET_ACC(ACC ^ data); /*Set ACC to value of ACC Logical XOR with Data */
|
||||
}
|
||||
|
||||
/*XRL A, R0 to R7 1: 0110 1rrr */
|
||||
OPHANDLER( xrl_a_r )
|
||||
{
|
||||
UINT8 data = R_REG(r); /*Grab data from R0 - R7 */
|
||||
SET_ACC(ACC ^ data); /*Set ACC to value of ACC Logical XOR with Data */
|
||||
}
|
||||
|
||||
/*illegal opcodes */
|
||||
OPHANDLER( illegal )
|
||||
{
|
||||
LOG(("i8051 #%d: illegal opcode at 0x%03x: %02x\n", cpu_getactivecpu(), PC-1, r));
|
||||
}
|
||||
+2783
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,67 @@
|
||||
/***************************************************************************
|
||||
|
||||
Intel 80960KA/KB, from current MAME (src/devices/cpu/i960,
|
||||
copyright Farfetch'd, R. Belmont, BSD-3-Clause), in C for MAME 2003.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef I960_H
|
||||
#define I960_H
|
||||
|
||||
#include "osd_cpu.h"
|
||||
|
||||
enum
|
||||
{
|
||||
I960_PFP = 0,
|
||||
I960_SP = 1,
|
||||
I960_RIP = 2,
|
||||
I960_FP = 31
|
||||
};
|
||||
|
||||
/* register numbers for get_reg / set_reg */
|
||||
enum
|
||||
{
|
||||
I960_IPREG = 1, I960_PIPREG, I960_SATREG, I960_PRCBREG, I960_PCREG, I960_ACREG,
|
||||
I960_R0REG
|
||||
/* I960_R0REG + n: r0..r15 g0..g15 */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
I960_IRQ0 = 0,
|
||||
I960_IRQ1 = 1,
|
||||
I960_IRQ2 = 2,
|
||||
I960_IRQ3 = 3
|
||||
};
|
||||
|
||||
extern int i960_icount;
|
||||
|
||||
extern void i960_init(void);
|
||||
extern void i960_reset(void *param);
|
||||
extern void i960_exit(void);
|
||||
extern int i960_execute(int cycles);
|
||||
extern unsigned i960_get_context(void *dst);
|
||||
extern void i960_set_context(void *src);
|
||||
extern unsigned i960_get_reg(int regnum);
|
||||
extern void i960_set_reg(int regnum, unsigned val);
|
||||
extern void i960_set_irq_line(int irqline, int state);
|
||||
extern void i960_set_irq_callback(int (*callback)(int irqline));
|
||||
extern const char *i960_info(void *context, int regnum);
|
||||
extern unsigned i960_dasm(char *buffer, unsigned pc);
|
||||
|
||||
/* Model 2: a FIFO access that cannot complete now (copro FIFO empty or
|
||||
full) repeats the instruction later; a multi-word access already half
|
||||
done resumes where it stopped (current MAME, i960_stall) */
|
||||
extern void i960_stall(void);
|
||||
/* the regions where ldl/ldt/ldq/stl/stt/stq step through the addresses
|
||||
(current MAME's BURST flag); elsewhere (FIFOs, registers) every word
|
||||
goes to the same address. NULL: everywhere. */
|
||||
extern void i960_set_burst_callback(int (*is_burst)(UINT32 address));
|
||||
|
||||
/* the addresses an idle loop may read: reading them has no side effect
|
||||
and their contents change only between timeslices (RAM, a status
|
||||
register updated by an interrupt). NULL (default): idle loops are not
|
||||
skipped. */
|
||||
extern void i960_set_idle_read_callback(int (*read_ok)(UINT32 address));
|
||||
|
||||
#endif
|
||||
@@ -470,6 +470,19 @@ void konami_set_reg(int regnum, unsigned val)
|
||||
/****************************************************************************/
|
||||
void konami_init(void)
|
||||
{
|
||||
int cpu = cpu_getactivecpu();
|
||||
state_save_register_UINT16("konami", cpu, "PC", &PC, 1);
|
||||
state_save_register_UINT16("konami", cpu, "U", &U, 1);
|
||||
state_save_register_UINT16("konami", cpu, "S", &S, 1);
|
||||
state_save_register_UINT16("konami", cpu, "X", &X, 1);
|
||||
state_save_register_UINT16("konami", cpu, "Y", &Y, 1);
|
||||
state_save_register_UINT16("konami", cpu, "D", &D, 1);
|
||||
state_save_register_UINT8("konami", cpu, "DP", &DP, 1);
|
||||
state_save_register_UINT8("konami", cpu, "CC", &CC, 1);
|
||||
state_save_register_UINT8("konami", cpu, "INT", &konami.int_state, 1);
|
||||
state_save_register_UINT8("konami", cpu, "NMI", &konami.nmi_state, 1);
|
||||
state_save_register_UINT8("konami", cpu, "IRQ", &konami.irq_state[0], 1);
|
||||
state_save_register_UINT8("konami", cpu, "FIRQ", &konami.irq_state[1], 1);
|
||||
}
|
||||
|
||||
void konami_reset(void *param)
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,165 @@
|
||||
#ifndef HEADER__M37710
|
||||
#define HEADER__M37710
|
||||
|
||||
/* ======================================================================== */
|
||||
/* =============================== COPYRIGHT ============================== */
|
||||
/* ======================================================================== */
|
||||
/*
|
||||
|
||||
M37710 CPU Emulator v0.1
|
||||
|
||||
mame2003-plus: backported from MAME 0.121 to the 0.78 CPU interface.
|
||||
The on-chip registers (0x00-0x7f), on-chip RAM (0x80-0x27f) and, for the
|
||||
M37702 with internal mask ROM, the internal ROM (0xc000-0xffff) are
|
||||
handled inside the core. The on-chip I/O ports and ADC are routed to the
|
||||
driver through m37710_set_io_handlers(). Single instance only.
|
||||
|
||||
*/
|
||||
|
||||
#include "osd_cpu.h"
|
||||
|
||||
/* ======================================================================== */
|
||||
/* =============================== DEFINES ================================ */
|
||||
/* ======================================================================== */
|
||||
/*
|
||||
Input lines - used with cpu_set_irq_line() and the like.
|
||||
WARNING: these are in the same order as the vector table for simplicity.
|
||||
Do not alter this order!
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
/* these interrupts are maskable */
|
||||
M37710_LINE_ADC = 0,
|
||||
M37710_LINE_UART1XMIT,
|
||||
M37710_LINE_UART1RECV,
|
||||
M37710_LINE_UART0XMIT,
|
||||
M37710_LINE_UART0RECV,
|
||||
M37710_LINE_TIMERB2,
|
||||
M37710_LINE_TIMERB1,
|
||||
M37710_LINE_TIMERB0,
|
||||
M37710_LINE_TIMERA4,
|
||||
M37710_LINE_TIMERA3,
|
||||
M37710_LINE_TIMERA2,
|
||||
M37710_LINE_TIMERA1,
|
||||
M37710_LINE_TIMERA0,
|
||||
M37710_LINE_IRQ2,
|
||||
M37710_LINE_IRQ1,
|
||||
M37710_LINE_IRQ0,
|
||||
/* these interrupts are non-maskable */
|
||||
M37710_LINE_WATCHDOG,
|
||||
M37710_LINE_DEBUG,
|
||||
M37710_LINE_BRK,
|
||||
M37710_LINE_ZERODIV,
|
||||
M37710_LINE_RESET,
|
||||
|
||||
/* these are not interrupts, they're signals external hardware can send */
|
||||
M37710_LINE_TIMERA0TICK,
|
||||
M37710_LINE_TIMERA1TICK,
|
||||
M37710_LINE_TIMERA2TICK,
|
||||
M37710_LINE_TIMERA3TICK,
|
||||
M37710_LINE_TIMERA4TICK,
|
||||
M37710_LINE_TIMERB0TICK,
|
||||
M37710_LINE_TIMERB1TICK,
|
||||
M37710_LINE_TIMERB2TICK,
|
||||
|
||||
M37710_LINE_MAX
|
||||
};
|
||||
|
||||
/* Registers - used by m37710_set_reg() and m37710_get_reg() */
|
||||
enum
|
||||
{
|
||||
M37710_PC=1, M37710_S, M37710_P, M37710_A, M37710_B, M37710_X, M37710_Y,
|
||||
M37710_PB, M37710_DB, M37710_D, M37710_E,
|
||||
M37710_NMI_STATE, M37710_IRQ_STATE
|
||||
};
|
||||
|
||||
|
||||
/* I/O ports */
|
||||
enum
|
||||
{
|
||||
M37710_PORT0 = 0,
|
||||
M37710_PORT1, M37710_PORT2, M37710_PORT3, M37710_PORT4,
|
||||
M37710_PORT5, M37710_PORT6, M37710_PORT7, M37710_PORT8,
|
||||
|
||||
M37710_ADC0_L = 0x10, M37710_ADC0_H,
|
||||
M37710_ADC1_L, M37710_ADC1_H, M37710_ADC2_L, M37710_ADC2_H, M37710_ADC3_L, M37710_ADC3_H,
|
||||
M37710_ADC4_L, M37710_ADC4_H, M37710_ADC5_L, M37710_ADC5_H, M37710_ADC6_L, M37710_ADC6_H,
|
||||
M37710_ADC7_L, M37710_ADC7_H,
|
||||
|
||||
M37710_SER0_REC = 0x20,
|
||||
M37710_SER0_XMIT, M37710_SER1_REC, M37710_SER1_XMIT
|
||||
};
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== PROTOTYPES ============================== */
|
||||
/* ======================================================================== */
|
||||
|
||||
typedef data8_t (*m37710_io_read_func)(int port);
|
||||
typedef void (*m37710_io_write_func)(int port, data8_t data);
|
||||
|
||||
/* hook the on-chip ports/ADC to the driver */
|
||||
void m37710_set_io_handlers(m37710_io_read_func readfn, m37710_io_write_func writefn);
|
||||
/* M37702 with internal mask ROM: 16KB mapped at 0xc000-0xffff (NULL = external) */
|
||||
void m37710_set_internal_rom(const UINT8 *rom);
|
||||
/*
|
||||
Speedup (0 = off): 'pc' (bank | address) starts a loop of 'count'
|
||||
instructions that only polls memory written by interrupts (such as
|
||||
"lda dp / beq loop"), so every pass leaves the same state. Once one
|
||||
pass has run inside a timeslice, the whole passes that still fit in
|
||||
it are skipped: registers, memory and cycles end up exactly as if
|
||||
they had run.
|
||||
*/
|
||||
void m37710_set_idle_loop(UINT32 pc, int count);
|
||||
|
||||
extern int m37710_ICount; /* cycle count */
|
||||
|
||||
void m37710_init(void);
|
||||
void m37710_reset(void *param);
|
||||
void m37710_exit(void);
|
||||
int m37710_execute(int cycles);
|
||||
unsigned m37710_get_context(void *dst);
|
||||
void m37710_set_context(void *src);
|
||||
unsigned m37710_get_reg(int regnum);
|
||||
void m37710_set_reg(int regnum, unsigned val);
|
||||
void m37710_set_irq_line(int irqline, int state);
|
||||
void m37710_set_irq_callback(int (*callback)(int irqline));
|
||||
const char *m37710_info(void *context, int regnum);
|
||||
unsigned m37710_dasm(char *buffer, unsigned pc);
|
||||
|
||||
#define m37702_ICount m37710_ICount
|
||||
#define m37702_init m37710_init
|
||||
#define m37702_reset m37710_reset
|
||||
#define m37702_exit m37710_exit
|
||||
#define m37702_execute m37710_execute
|
||||
#define m37702_get_context m37710_get_context
|
||||
#define m37702_set_context m37710_set_context
|
||||
#define m37702_get_reg m37710_get_reg
|
||||
#define m37702_set_reg m37710_set_reg
|
||||
#define m37702_set_irq_line m37710_set_irq_line
|
||||
#define m37702_set_irq_callback m37710_set_irq_callback
|
||||
#define m37702_info m37710_info
|
||||
#define m37702_dasm m37710_dasm
|
||||
|
||||
/* memory access, including the on-chip resources */
|
||||
UINT8 m37710_mem_read8(UINT32 address);
|
||||
UINT16 m37710_mem_read16(UINT32 address);
|
||||
void m37710_mem_write8(UINT32 address, UINT8 data);
|
||||
void m37710_mem_write16(UINT32 address, UINT16 data);
|
||||
|
||||
#undef M37710_CALL_DEBUGGER
|
||||
|
||||
#define M37710_CALL_DEBUGGER CALL_MAME_DEBUG
|
||||
#define m37710_read_8(addr) m37710_mem_read8(addr)
|
||||
#define m37710_write_8(addr,data) m37710_mem_write8(addr,data)
|
||||
#define m37710_read_8_immediate(A) m37710_mem_read8(A)
|
||||
#define m37710_read_16(addr) m37710_mem_read16(addr)
|
||||
#define m37710_write_16(addr,data) m37710_mem_write16(addr,data)
|
||||
#define m37710_jumping(A)
|
||||
#define m37710_branching(A)
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== END OF FILE ============================= */
|
||||
/* ======================================================================== */
|
||||
|
||||
#endif /* HEADER__M37710 */
|
||||
@@ -0,0 +1,323 @@
|
||||
/* M37710/M37702 core internals: from MAME 0.121 (MAME license; R. Belmont,
|
||||
based on the G65816 core by Karl Stenerud) */
|
||||
|
||||
#ifndef HEADER__M37710CM
|
||||
#define HEADER__M37710CM
|
||||
|
||||
#define m37710i_branching(A)
|
||||
#define m37710i_jumping(A)
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ================================ INCLUDES ============================== */
|
||||
/* ======================================================================== */
|
||||
|
||||
#include <limits.h>
|
||||
#include "driver.h"
|
||||
#include "cpuintrf.h"
|
||||
#include "mamedbg.h"
|
||||
#include "m37710.h"
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ================================ GENERAL =============================== */
|
||||
/* ======================================================================== */
|
||||
|
||||
/* Fallback on static if we don't have inline */
|
||||
|
||||
|
||||
/* This should be set to the default size of your processor (min 16 bit) */
|
||||
#undef uint
|
||||
#define uint unsigned int
|
||||
|
||||
#undef uint8
|
||||
#define uint8 unsigned char
|
||||
|
||||
#undef int8
|
||||
|
||||
/* Allow for architectures that don't have 8-bit sizes */
|
||||
#if UCHAR_MAX == 0xff
|
||||
#define int8 char
|
||||
#define MAKE_INT_8(A) (int8)((A)&0xff)
|
||||
#else
|
||||
#define int8 int
|
||||
static INLINE int MAKE_INT_8(int A) {return (A & 0x80) ? A | ~0xff : A & 0xff;}
|
||||
#endif /* UCHAR_MAX == 0xff */
|
||||
|
||||
#define MAKE_UINT_8(A) ((A)&0xff)
|
||||
#define MAKE_UINT_16(A) ((A)&0xffff)
|
||||
#define MAKE_UINT_24(A) ((A)&0xffffff)
|
||||
|
||||
/* Bits */
|
||||
#define BIT_0 0x01
|
||||
#define BIT_1 0x02
|
||||
#define BIT_2 0x04
|
||||
#define BIT_3 0x08
|
||||
#define BIT_4 0x10
|
||||
#define BIT_5 0x20
|
||||
#define BIT_6 0x40
|
||||
#define BIT_7 0x80
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ================================== CPU ================================= */
|
||||
/* ======================================================================== */
|
||||
|
||||
/* CPU Structure */
|
||||
typedef struct
|
||||
{
|
||||
uint a; /* Accumulator */
|
||||
uint b; /* holds high byte of accumulator */
|
||||
uint ba; /* Secondary Accumulator */
|
||||
uint bb; /* holds high byte of secondary accumulator */
|
||||
uint x; /* Index Register X */
|
||||
uint y; /* Index Register Y */
|
||||
uint s; /* Stack Pointer */
|
||||
uint pc; /* Program Counter */
|
||||
uint ppc; /* Previous Program Counter */
|
||||
uint pb; /* Program Bank (shifted left 16) */
|
||||
uint db; /* Data Bank (shifted left 16) */
|
||||
uint d; /* Direct Register */
|
||||
uint flag_e; /* Emulation Mode Flag */
|
||||
uint flag_m; /* Memory/Accumulator Select Flag */
|
||||
uint flag_x; /* Index Select Flag */
|
||||
uint flag_n; /* Negative Flag */
|
||||
uint flag_v; /* Overflow Flag */
|
||||
uint flag_d; /* Decimal Mode Flag */
|
||||
uint flag_i; /* Interrupt Mask Flag */
|
||||
uint flag_z; /* Zero Flag (inverted) */
|
||||
uint flag_c; /* Carry Flag */
|
||||
uint line_irq; /* Bitmask of pending IRQs */
|
||||
uint ipl; /* Interrupt priority level (top of PSW) */
|
||||
uint ir; /* Instruction Register */
|
||||
uint im; /* Immediate load value */
|
||||
uint im2; /* Immediate load target */
|
||||
uint im3; /* Immediate load target */
|
||||
uint im4; /* Immediate load target */
|
||||
uint irq_delay; /* delay 1 instruction before checking irq */
|
||||
uint irq_level; /* irq level */
|
||||
int (*int_ack)(int); /* Interrupt Acknowledge */
|
||||
uint stopped; /* Sets how the CPU is stopped */
|
||||
void (**opcodes)(void); /* opcodes with no prefix */
|
||||
void (**opcodes42)(void); /* opcodes with 0x42 prefix */
|
||||
void (**opcodes89)(void); /* opcodes with 0x89 prefix */
|
||||
uint (*get_reg)(int regnum);
|
||||
void (*set_reg)(int regnum, uint val);
|
||||
void (*set_line)(int line, int state);
|
||||
int (*execute)(int cycles);
|
||||
|
||||
/* on-board peripheral stuff */
|
||||
UINT8 m37710_regs[128];
|
||||
double reload[8];
|
||||
mame_timer *timers[8];
|
||||
double timer_left[8]; /* saved: time left of each timer (< 0: not armed) */
|
||||
} m37710i_cpu_struct;
|
||||
|
||||
extern m37710i_cpu_struct m37710i_cpu;
|
||||
extern UINT32 m37710_idle_pc;
|
||||
extern int m37710_idle_count, m37710_idle_since, m37710_idle_clocks;
|
||||
extern int m37710_ICount;
|
||||
extern uint m37710i_source;
|
||||
extern uint m37710i_destination;
|
||||
extern uint m37710i_adc_tbl[];
|
||||
extern uint m37710i_sbc_tbl[];
|
||||
|
||||
extern void (**m37710i_opcodes[])(void);
|
||||
extern void (**m37710i_opcodes2[])(void);
|
||||
extern void (**m37710i_opcodes3[])(void);
|
||||
extern uint (*m37710i_get_reg[])(int regnum);
|
||||
extern void (*m37710i_set_reg[])(int regnum, uint val);
|
||||
extern void (*m37710i_set_line[])(int line, int state);
|
||||
extern int (*m37710i_execute[])(int cycles);
|
||||
|
||||
#define REG_A m37710i_cpu.a /* Accumulator */
|
||||
#define REG_B m37710i_cpu.b /* Accumulator hi byte */
|
||||
#define REG_BA m37710i_cpu.ba /* Secondary Accumulator */
|
||||
#define REG_BB m37710i_cpu.bb /* Secondary Accumulator hi byte */
|
||||
#define REG_X m37710i_cpu.x /* Index X Register */
|
||||
#define REG_Y m37710i_cpu.y /* Index Y Register */
|
||||
#define REG_S m37710i_cpu.s /* Stack Pointer */
|
||||
#define REG_PC m37710i_cpu.pc /* Program Counter */
|
||||
#define REG_PPC m37710i_cpu.ppc /* Previous Program Counter */
|
||||
#define REG_PB m37710i_cpu.pb /* Program Bank */
|
||||
#define REG_DB m37710i_cpu.db /* Data Bank */
|
||||
#define REG_D m37710i_cpu.d /* Direct Register */
|
||||
#define FLAG_M m37710i_cpu.flag_m /* Memory/Accumulator Select Flag */
|
||||
#define FLAG_X m37710i_cpu.flag_x /* Index Select Flag */
|
||||
#define FLAG_N m37710i_cpu.flag_n /* Negative Flag */
|
||||
#define FLAG_V m37710i_cpu.flag_v /* Overflow Flag */
|
||||
#define FLAG_D m37710i_cpu.flag_d /* Decimal Mode Flag */
|
||||
#define FLAG_I m37710i_cpu.flag_i /* Interrupt Mask Flag */
|
||||
#define FLAG_Z m37710i_cpu.flag_z /* Zero Flag (inverted) */
|
||||
#define FLAG_C m37710i_cpu.flag_c /* Carry Flag */
|
||||
#define LINE_IRQ m37710i_cpu.line_irq /* Status of the IRQ line */
|
||||
#define REG_IR m37710i_cpu.ir /* Instruction Register */
|
||||
#define REG_IM m37710i_cpu.im /* Immediate load value */
|
||||
#define REG_IM2 m37710i_cpu.im2 /* Immediate load target */
|
||||
#define REG_IM3 m37710i_cpu.im3 /* Immediate load target */
|
||||
#define REG_IM4 m37710i_cpu.im4 /* Immediate load target */
|
||||
#define INT_ACK m37710i_cpu.int_ack /* Interrupt Acknowledge function pointer */
|
||||
#define CLOCKS m37710_ICount /* Clock cycles remaining */
|
||||
#define IRQ_DELAY m37710i_cpu.irq_delay /* Delay 1 instruction before checking IRQ */
|
||||
#define CPU_STOPPED m37710i_cpu.stopped /* Stopped status of the CPU */
|
||||
|
||||
#define FTABLE_OPCODES m37710i_cpu.opcodes
|
||||
#define FTABLE_OPCODES2 m37710i_cpu.opcodes42
|
||||
#define FTABLE_OPCODES3 m37710i_cpu.opcodes89
|
||||
#define FTABLE_GET_REG m37710i_cpu.get_reg
|
||||
#define FTABLE_SET_REG m37710i_cpu.set_reg
|
||||
#define FTABLE_SET_LINE m37710i_cpu.set_line
|
||||
#define FTABLE_EXECUTE m37710i_cpu.execute
|
||||
|
||||
#define SRC m37710i_source /* Source Operand */
|
||||
#define DST m37710i_destination /* Destination Operand */
|
||||
|
||||
#define STOP_LEVEL_WAI 1
|
||||
#define STOP_LEVEL_STOP 2
|
||||
|
||||
#define EXECUTION_MODE_M0X0 0
|
||||
#define EXECUTION_MODE_M0X1 1
|
||||
#define EXECUTION_MODE_M1X0 2
|
||||
#define EXECUTION_MODE_M1X1 3
|
||||
|
||||
static INLINE void m37710i_set_execution_mode(uint mode)
|
||||
{
|
||||
FTABLE_OPCODES = m37710i_opcodes[mode];
|
||||
FTABLE_OPCODES2 = m37710i_opcodes2[mode];
|
||||
FTABLE_OPCODES3 = m37710i_opcodes3[mode];
|
||||
FTABLE_GET_REG = m37710i_get_reg[mode];
|
||||
FTABLE_SET_REG = m37710i_set_reg[mode];
|
||||
FTABLE_SET_LINE = m37710i_set_line[mode];
|
||||
FTABLE_EXECUTE = m37710i_execute[mode];
|
||||
}
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ================================= CLOCK ================================ */
|
||||
/* ======================================================================== */
|
||||
|
||||
#define CLK_OP 1
|
||||
#define CLK_R8 1
|
||||
#define CLK_R16 2
|
||||
#define CLK_R24 3
|
||||
#define CLK_W8 1
|
||||
#define CLK_W16 2
|
||||
#define CLK_W24 3
|
||||
#define CLK_RMW8 3
|
||||
#define CLK_RMW16 5
|
||||
|
||||
#define CLK_IMPLIED 1
|
||||
#define CLK_IMPLIED 1
|
||||
#define CLK_RELATIVE_8 1
|
||||
#define CLK_RELATIVE_16 2
|
||||
#define CLK_IMM 0
|
||||
#define CLK_AI 4
|
||||
#define CLK_AXI 4
|
||||
#define CLK_A 2
|
||||
#define CLK_AL 3
|
||||
#define CLK_ALX 3
|
||||
#define CLK_AX 2
|
||||
#define CLK_AY 2
|
||||
#define CLK_D 1
|
||||
#define CLK_DI 3
|
||||
#define CLK_DIY 3
|
||||
#define CLK_DLI 4
|
||||
#define CLK_DLIY 4
|
||||
#define CLK_DX 2
|
||||
#define CLK_DXI 4
|
||||
#define CLK_DY 2
|
||||
#define CLK_S 2
|
||||
#define CLK_SIY 5
|
||||
|
||||
/* AX and AY addressing modes take 1 extra cycle when writing */
|
||||
#define CLK_W_IMM 0
|
||||
#define CLK_W_AI 4
|
||||
#define CLK_W_AXI 4
|
||||
#define CLK_W_A 2
|
||||
#define CLK_W_AL 3
|
||||
#define CLK_W_ALX 3
|
||||
#define CLK_W_AX 3
|
||||
#define CLK_W_AY 3
|
||||
#define CLK_W_D 1
|
||||
#define CLK_W_DI 3
|
||||
#define CLK_W_DIY 3
|
||||
#define CLK_W_DLI 4
|
||||
#define CLK_W_DLIY 4
|
||||
#define CLK_W_DX 2
|
||||
#define CLK_W_DXI 4
|
||||
#define CLK_W_DY 2
|
||||
#define CLK_W_S 2
|
||||
#define CLK_W_SIY 5
|
||||
|
||||
#define CLK(A) CLOCKS -= (A)
|
||||
#define USE_ALL_CLKS() CLOCKS = 0
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================ STATUS REGISTER =========================== */
|
||||
/* ======================================================================== */
|
||||
|
||||
/* Flag positions in Processor Status Register */
|
||||
/* common */
|
||||
#define FLAGPOS_N BIT_7 /* Negative */
|
||||
#define FLAGPOS_V BIT_6 /* Overflow */
|
||||
#define FLAGPOS_D BIT_3 /* Decimal Mode */
|
||||
#define FLAGPOS_I BIT_2 /* Interrupt Mask */
|
||||
#define FLAGPOS_Z BIT_1 /* Zero */
|
||||
#define FLAGPOS_C BIT_0 /* Carry */
|
||||
/* emulation */
|
||||
#define FLAGPOS_R BIT_5 /* Reserved */
|
||||
#define FLAGPOS_B BIT_4 /* BRK Instruction */
|
||||
/* native */
|
||||
#define FLAGPOS_M BIT_5 /* Mem/Reg Select */
|
||||
#define FLAGPOS_X BIT_4 /* Index Select */
|
||||
|
||||
#define EFLAG_SET 1
|
||||
#define EFLAG_CLEAR 0
|
||||
#define MFLAG_SET FLAGPOS_M
|
||||
#define MFLAG_CLEAR 0
|
||||
#define XFLAG_SET FLAGPOS_X
|
||||
#define XFLAG_CLEAR 0
|
||||
#define NFLAG_SET 0x80
|
||||
#define NFLAG_CLEAR 0
|
||||
#define VFLAG_SET 0x80
|
||||
#define VFLAG_CLEAR 0
|
||||
#define DFLAG_SET FLAGPOS_D
|
||||
#define DFLAG_CLEAR 0
|
||||
#define IFLAG_SET FLAGPOS_I
|
||||
#define IFLAG_CLEAR 0
|
||||
#define BFLAG_SET FLAGPOS_B
|
||||
#define BFLAG_CLEAR 0
|
||||
#define ZFLAG_SET 0
|
||||
#define ZFLAG_CLEAR 1
|
||||
#define CFLAG_SET 0x100
|
||||
#define CFLAG_CLEAR 0
|
||||
|
||||
/* Codition code tests */
|
||||
#define COND_CC() (!(FLAG_C&0x100)) /* Carry Clear */
|
||||
#define COND_CS() (FLAG_C&0x100) /* Carry Set */
|
||||
#define COND_EQ() (!FLAG_Z) /* Equal */
|
||||
#define COND_NE() FLAG_Z /* Not Equal */
|
||||
#define COND_MI() (FLAG_N&0x80) /* Minus */
|
||||
#define COND_PL() (!(FLAG_N&0x80)) /* Plus */
|
||||
#define COND_VC() (!(FLAG_V&0x80)) /* Overflow Clear */
|
||||
#define COND_VS() (FLAG_V&0x80) /* Overflow Set */
|
||||
|
||||
/* Set Overflow flag in math operations */
|
||||
#define VFLAG_ADD_8(S, D, R) ((S^R) & (D^R))
|
||||
#define VFLAG_ADD_16(S, D, R) (((S^R) & (D^R))>>8)
|
||||
#define VFLAG_SUB_8(S, D, R) ((S^D) & (R^D))
|
||||
#define VFLAG_SUB_16(S, D, R) (((S^D) & (R^D))>>8)
|
||||
|
||||
#define CFLAG_8(A) (A)
|
||||
#define CFLAG_16(A) ((A)>>8)
|
||||
#define NFLAG_8(A) (A)
|
||||
#define NFLAG_16(A) ((A)>>8)
|
||||
|
||||
#define CFLAG_AS_1() ((FLAG_C>>8)&1)
|
||||
|
||||
/* update IRQ state (internal use only) */
|
||||
void m37710i_update_irqs(void);
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ================================== CPU ================================= */
|
||||
/* ======================================================================== */
|
||||
#endif /* HEADER__M37710CM */
|
||||
@@ -0,0 +1,4 @@
|
||||
/* M37710 opcode table instance: from MAME 0.121 (MAME license; R. Belmont) */
|
||||
#include "m37710cm.h"
|
||||
#define EXECUTION_MODE EXECUTION_MODE_M0X0
|
||||
#include "m37710op.h"
|
||||
@@ -0,0 +1,4 @@
|
||||
/* M37710 opcode table instance: from MAME 0.121 (MAME license; R. Belmont) */
|
||||
#include "m37710cm.h"
|
||||
#define EXECUTION_MODE EXECUTION_MODE_M0X1
|
||||
#include "m37710op.h"
|
||||
@@ -0,0 +1,4 @@
|
||||
/* M37710 opcode table instance: from MAME 0.121 (MAME license; R. Belmont) */
|
||||
#include "m37710cm.h"
|
||||
#define EXECUTION_MODE EXECUTION_MODE_M1X0
|
||||
#include "m37710op.h"
|
||||
@@ -0,0 +1,4 @@
|
||||
/* M37710 opcode table instance: from MAME 0.121 (MAME license; R. Belmont) */
|
||||
#include "m37710cm.h"
|
||||
#define EXECUTION_MODE EXECUTION_MODE_M1X1
|
||||
#include "m37710op.h"
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,46 @@
|
||||
/***************************************************************************
|
||||
|
||||
Fujitsu MB86233/MB86234 (TGP), from current MAME
|
||||
(src/devices/cpu/mb86233, copyright Olivier Galibert, BSD-3-Clause),
|
||||
in C for MAME 2003. The four address spaces (program, data, io and
|
||||
register file) are driver callbacks.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MB86233_H
|
||||
#define MB86233_H
|
||||
|
||||
#include "osd_cpu.h"
|
||||
|
||||
struct mb86233_config
|
||||
{
|
||||
UINT32 (*prog_r)( UINT32 offset );
|
||||
UINT32 (*data_r)( UINT32 offset );
|
||||
void (*data_w)( UINT32 offset, UINT32 data );
|
||||
UINT32 (*io_r)( UINT32 offset );
|
||||
void (*io_w)( UINT32 offset, UINT32 data );
|
||||
UINT32 (*rf_r)( UINT32 offset );
|
||||
void (*rf_w)( UINT32 offset, UINT32 data );
|
||||
};
|
||||
|
||||
extern int mb86233_icount;
|
||||
|
||||
extern void mb86233_init(void);
|
||||
extern void mb86233_reset(void *param);
|
||||
extern void mb86233_exit(void);
|
||||
extern int mb86233_execute(int cycles);
|
||||
extern unsigned mb86233_get_context(void *dst);
|
||||
extern void mb86233_set_context(void *src);
|
||||
extern unsigned mb86233_get_reg(int regnum);
|
||||
extern void mb86233_set_reg(int regnum, unsigned val);
|
||||
extern void mb86233_set_irq_line(int irqline, int state);
|
||||
extern void mb86233_set_irq_callback(int (*callback)(int irqline));
|
||||
extern const char *mb86233_info(void *context, int regnum);
|
||||
extern unsigned mb86233_dasm(char *buffer, unsigned pc);
|
||||
|
||||
/* a memory callback that cannot complete now (FIFO empty or full):
|
||||
the instruction is repeated */
|
||||
extern void mb86233_stall(void);
|
||||
extern void mb86233_gpio_w(int pin, int state);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,50 @@
|
||||
/***************************************************************************
|
||||
|
||||
Fujitsu MB86235 "TGPx4", from current MAME
|
||||
(src/devices/cpu/mb86235; copyright Angelo Salese, ElSemi, Ville Linde,
|
||||
Matthew Daniels, BSD-3-Clause), the interpreter in C for MAME 2003.
|
||||
Program memory, the external bus and the FIFOs are driver callbacks;
|
||||
the internal A and B bus RAMs are part of the CPU.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MB86235_H
|
||||
#define MB86235_H
|
||||
|
||||
#include "osd_cpu.h"
|
||||
|
||||
#define MB86235_FIFO_IFF 0 /* input FIFO full */
|
||||
#define MB86235_FIFO_IFE 1 /* input FIFO empty */
|
||||
#define MB86235_FIFO_OFF 2 /* output FIFO full */
|
||||
#define MB86235_FIFO_OFE 3 /* output FIFO empty */
|
||||
|
||||
struct mb86235_config
|
||||
{
|
||||
UINT64 (*prog_r)( UINT32 offset ); /* 64-bit words, 12-bit address */
|
||||
UINT32 (*ext_r)( UINT32 offset ); /* external bus, dword address */
|
||||
void (*ext_w)( UINT32 offset, UINT32 data );
|
||||
UINT32 (*fifoin_r)( void ); /* calls mb86235_stall() when empty */
|
||||
void (*fifoout_w)( UINT32 data );
|
||||
int (*fifo_flag)( int which );
|
||||
void (*fifo_clear)( int which ); /* 0: input, 1: output */
|
||||
};
|
||||
|
||||
extern int mb86235_icount;
|
||||
|
||||
extern void mb86235_init(void);
|
||||
extern void mb86235_reset(void *param);
|
||||
extern void mb86235_exit(void);
|
||||
extern int mb86235_execute(int cycles);
|
||||
extern unsigned mb86235_get_context(void *dst);
|
||||
extern void mb86235_set_context(void *src);
|
||||
extern unsigned mb86235_get_reg(int regnum);
|
||||
extern void mb86235_set_reg(int regnum, unsigned val);
|
||||
extern void mb86235_set_irq_line(int irqline, int state);
|
||||
extern void mb86235_set_irq_callback(int (*callback)(int irqline));
|
||||
extern const char *mb86235_info(void *context, int regnum);
|
||||
extern unsigned mb86235_dasm(char *buffer, unsigned pc);
|
||||
|
||||
/* a FIFO read that cannot complete now: the instruction is repeated */
|
||||
extern void mb86235_stall(void);
|
||||
|
||||
#endif
|
||||
+457
-1
@@ -13,6 +13,7 @@
|
||||
**
|
||||
**#################################################################################################*/
|
||||
|
||||
#include "mips3jit.h"
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
@@ -21,6 +22,7 @@
|
||||
#include "driver.h"
|
||||
#include "mamedbg.h"
|
||||
#include "mips3.h"
|
||||
#include "state.h"
|
||||
|
||||
|
||||
#define ENABLE_OVERFLOWS 0
|
||||
@@ -292,6 +294,193 @@ static const memory_handlers le_memory =
|
||||
|
||||
|
||||
|
||||
/*###################################################################################################
|
||||
** OPTIONAL SPEEDUPS
|
||||
**
|
||||
** Off unless a driver enables them (currently only Killer Instinct):
|
||||
** - fast RAM: plain RAM regions read and written through a direct pointer
|
||||
** instead of the memory system, including instruction fetch;
|
||||
** - idle loop: a loop that polls the COP0 Cause register for an interrupt
|
||||
** gives up the rest of its timeslice instead of spinning.
|
||||
** They live outside the CPU context and are cleared by mips3_init().
|
||||
**#################################################################################################*/
|
||||
|
||||
#define MIPS3_MAX_FASTRAM 8
|
||||
|
||||
struct mips3_fastram
|
||||
{
|
||||
offs_t start;
|
||||
offs_t end;
|
||||
UINT8 * base;
|
||||
UINT8 readonly;
|
||||
int wait; /* cycles each data read costs (wait states), 0 = none */
|
||||
};
|
||||
|
||||
static struct mips3_fastram fastram[MIPS3_MAX_FASTRAM];
|
||||
static int fastram_count;
|
||||
static offs_t fastram_byte_xor, fastram_word_xor;
|
||||
static memory_handlers fastram_slow; /* handlers for everything else */
|
||||
static int fastram_has_wait; /* a region with read wait states exists */
|
||||
|
||||
/* exact skip of the loops that poll Cause for an interrupt (see cause_poll_skip) */
|
||||
#define MIPS3_MAX_POLLREAD 4
|
||||
static int cause_poll_enabled;
|
||||
static struct { offs_t start, end; } pollread[MIPS3_MAX_POLLREAD];
|
||||
static int pollread_count;
|
||||
|
||||
|
||||
void mips3_add_fastram(offs_t start, offs_t end, int readonly, void *base)
|
||||
{
|
||||
mips3_add_fastram_wait(start, end, readonly, base, 0);
|
||||
}
|
||||
|
||||
/* the same, with wait states: each data read (not instruction fetch) costs */
|
||||
/* wait cycles, as a slow ROM does (instruction fetch and translation stay direct) */
|
||||
void mips3_add_fastram_wait(offs_t start, offs_t end, int readonly, void *base, int wait)
|
||||
{
|
||||
if (fastram_count < MIPS3_MAX_FASTRAM)
|
||||
{
|
||||
fastram[fastram_count].start = start;
|
||||
fastram[fastram_count].end = end;
|
||||
fastram[fastram_count].base = (UINT8 *)base;
|
||||
fastram[fastram_count].readonly = readonly;
|
||||
fastram[fastram_count].wait = wait;
|
||||
if (wait)
|
||||
fastram_has_wait = 1;
|
||||
fastram_count++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mips3_set_cause_poll_skip(int enable)
|
||||
{
|
||||
cause_poll_enabled = enable;
|
||||
}
|
||||
|
||||
|
||||
void mips3_add_poll_read(offs_t start, offs_t end)
|
||||
{
|
||||
if (pollread_count < MIPS3_MAX_POLLREAD)
|
||||
{
|
||||
pollread[pollread_count].start = start;
|
||||
pollread[pollread_count].end = end;
|
||||
pollread_count++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static struct mips3_fastram *fastram_last = &fastram[0];
|
||||
|
||||
/* recompiler hook (mips3jit.c): a write may hit translated code */
|
||||
static INLINE void jit_check_write(const void *host);
|
||||
|
||||
static INLINE struct mips3_fastram *find_fastram(offs_t address)
|
||||
{
|
||||
struct mips3_fastram *r = fastram_last;
|
||||
int i;
|
||||
|
||||
/* most accesses hit the same region as the previous one */
|
||||
if (address - r->start <= r->end - r->start)
|
||||
return r;
|
||||
for (i = 0; i < fastram_count; i++)
|
||||
if (address - fastram[i].start <= fastram[i].end - fastram[i].start)
|
||||
return fastram_last = &fastram[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static data8_t fastram_readbyte(offs_t address)
|
||||
{
|
||||
struct mips3_fastram *r = find_fastram(address);
|
||||
if (r) { mips3_icount -= r->wait; return r->base[(address - r->start) ^ fastram_byte_xor]; }
|
||||
return (*fastram_slow.readbyte)(address);
|
||||
}
|
||||
|
||||
static data16_t fastram_readword(offs_t address)
|
||||
{
|
||||
struct mips3_fastram *r = find_fastram(address);
|
||||
if (r) { mips3_icount -= r->wait; return *(data16_t *)&r->base[(address - r->start) ^ fastram_word_xor]; }
|
||||
return (*fastram_slow.readword)(address);
|
||||
}
|
||||
|
||||
static data32_t fastram_readlong(offs_t address)
|
||||
{
|
||||
struct mips3_fastram *r = find_fastram(address);
|
||||
if (r) { mips3_icount -= r->wait; return *(data32_t *)&r->base[address - r->start]; }
|
||||
return (*fastram_slow.readlong)(address);
|
||||
}
|
||||
|
||||
static UINT64 fastram_readdouble(offs_t address)
|
||||
{
|
||||
struct mips3_fastram *r = find_fastram(address);
|
||||
if (r && address + 7 <= r->end)
|
||||
{
|
||||
UINT64 first;
|
||||
UINT64 second;
|
||||
mips3_icount -= r->wait;
|
||||
first = *(data32_t *)&r->base[address - r->start];
|
||||
second = *(data32_t *)&r->base[address + 4 - r->start];
|
||||
return mips3.bigendian ? ((first << 32) | second) : (first | (second << 32));
|
||||
}
|
||||
return (*fastram_slow.readdouble)(address);
|
||||
}
|
||||
|
||||
static void fastram_writebyte(offs_t address, data8_t data)
|
||||
{
|
||||
struct mips3_fastram *r = find_fastram(address);
|
||||
if (r && !r->readonly) { jit_check_write(&r->base[address - r->start]); r->base[(address - r->start) ^ fastram_byte_xor] = data; return; }
|
||||
(*fastram_slow.writebyte)(address, data);
|
||||
}
|
||||
|
||||
static void fastram_writeword(offs_t address, data16_t data)
|
||||
{
|
||||
struct mips3_fastram *r = find_fastram(address);
|
||||
if (r && !r->readonly) { jit_check_write(&r->base[address - r->start]); *(data16_t *)&r->base[(address - r->start) ^ fastram_word_xor] = data; return; }
|
||||
(*fastram_slow.writeword)(address, data);
|
||||
}
|
||||
|
||||
static void fastram_writelong(offs_t address, data32_t data)
|
||||
{
|
||||
struct mips3_fastram *r = find_fastram(address);
|
||||
if (r && !r->readonly) { jit_check_write(&r->base[address - r->start]); *(data32_t *)&r->base[address - r->start] = data; return; }
|
||||
(*fastram_slow.writelong)(address, data);
|
||||
}
|
||||
|
||||
static void fastram_writedouble(offs_t address, UINT64 data)
|
||||
{
|
||||
struct mips3_fastram *r = find_fastram(address);
|
||||
if (r && !r->readonly && address + 7 <= r->end)
|
||||
{
|
||||
jit_check_write(&r->base[address - r->start]);
|
||||
jit_check_write(&r->base[address + 4 - r->start]);
|
||||
*(data32_t *)&r->base[address - r->start] = mips3.bigendian ? (data32_t)(data >> 32) : (data32_t)data;
|
||||
*(data32_t *)&r->base[address + 4 - r->start] = mips3.bigendian ? (data32_t)data : (data32_t)(data >> 32);
|
||||
return;
|
||||
}
|
||||
(*fastram_slow.writedouble)(address, data);
|
||||
}
|
||||
|
||||
static const memory_handlers fastram_memory =
|
||||
{
|
||||
fastram_readbyte, fastram_readword, fastram_readlong, fastram_readdouble,
|
||||
fastram_writebyte, fastram_writeword, fastram_writelong, fastram_writedouble
|
||||
};
|
||||
|
||||
/* switch the memory handlers when fast RAM is in use */
|
||||
static void fastram_attach(void)
|
||||
{
|
||||
if (!fastram_count || mips3.memory.readlong == fastram_readlong)
|
||||
return;
|
||||
fastram_slow = mips3.bigendian ? be_memory : le_memory;
|
||||
fastram_byte_xor = mips3.bigendian ? BYTE4_XOR_BE(0) : BYTE4_XOR_LE(0);
|
||||
fastram_word_xor = mips3.bigendian ? WORD_XOR_BE(0) : WORD_XOR_LE(0);
|
||||
mips3.memory = fastram_memory;
|
||||
}
|
||||
|
||||
|
||||
#include "mips3jit.c"
|
||||
|
||||
|
||||
|
||||
/*###################################################################################################
|
||||
** MEMORY ACCESSORS
|
||||
**#################################################################################################*/
|
||||
@@ -439,9 +628,66 @@ static void compare_int_callback(int cpu)
|
||||
}
|
||||
|
||||
|
||||
/* the Compare interrupt timer is not saved by the core: whether it is set
|
||||
is. After a load it is set again from Count and Compare, in cycles of
|
||||
this CPU, as a write to Compare sets it (both functions run in the
|
||||
context of this CPU) */
|
||||
static UINT8 compare_timer_set;
|
||||
|
||||
static void mips3_presave(void)
|
||||
{
|
||||
compare_timer_set = (timer_timeleft(mips3.compare_int_timer) < TIME_NEVER / 2);
|
||||
}
|
||||
|
||||
static void mips3_postload(void)
|
||||
{
|
||||
int cpunum = cpu_getactivecpu();
|
||||
|
||||
timer_adjust(mips3.compare_int_timer, TIME_NEVER, cpunum, 0);
|
||||
if (compare_timer_set)
|
||||
{
|
||||
UINT32 count = (cpu_gettotalcycles64(cpunum) - mips3.count_zero_time) / 2;
|
||||
UINT32 cyclesleft = (UINT32)mips3.cpr[0][COP0_Compare] - count;
|
||||
timer_adjust(mips3.compare_int_timer, TIME_IN_CYCLES(((UINT64)cyclesleft * 2), cpunum), cpunum, 0);
|
||||
}
|
||||
|
||||
if (mips3.bigendian)
|
||||
change_pc32bedw(mips3.pc);
|
||||
else
|
||||
change_pc32ledw(mips3.pc);
|
||||
}
|
||||
|
||||
void mips3_init(void)
|
||||
{
|
||||
int cpunum = cpu_getactivecpu();
|
||||
|
||||
/* optional speedups are off until a driver asks for them */
|
||||
fastram_count = 0;
|
||||
fastram_has_wait = 0;
|
||||
fastram_last = &fastram[0];
|
||||
mips3_set_jit(0);
|
||||
cause_poll_enabled = 0;
|
||||
pollread_count = 0;
|
||||
|
||||
mips3.compare_int_timer = timer_alloc(compare_int_callback);
|
||||
|
||||
/* save states: the registers of the active context, swapped in per CPU
|
||||
when the state is saved; the 64-bit registers as pairs of 32 bits */
|
||||
state_save_register_UINT32("mips3", cpunum, "pc", &mips3.pc, 1);
|
||||
state_save_register_UINT32("mips3", cpunum, "hi", (UINT32 *)&mips3.hi, 2);
|
||||
state_save_register_UINT32("mips3", cpunum, "lo", (UINT32 *)&mips3.lo, 2);
|
||||
state_save_register_UINT32("mips3", cpunum, "r", (UINT32 *)mips3.r, 32 * 2);
|
||||
state_save_register_UINT32("mips3", cpunum, "cpr", (UINT32 *)mips3.cpr, 4 * 32 * 2);
|
||||
state_save_register_UINT32("mips3", cpunum, "ccr", (UINT32 *)mips3.ccr, 4 * 32 * 2);
|
||||
state_save_register_UINT8 ("mips3", cpunum, "cf", mips3.cf, 4);
|
||||
state_save_register_UINT32("mips3", cpunum, "ppc", &mips3.ppc, 1);
|
||||
state_save_register_UINT32("mips3", cpunum, "nextpc", &mips3.nextpc, 1);
|
||||
state_save_register_int ("mips3", cpunum, "op", &mips3.op);
|
||||
state_save_register_int ("mips3", cpunum, "interrupt_cycles", &mips3.interrupt_cycles);
|
||||
state_save_register_UINT32("mips3", cpunum, "count_zero_time", (UINT32 *)&mips3.count_zero_time, 2);
|
||||
state_save_register_UINT8 ("mips3", cpunum, "compare_timer_set", &compare_timer_set, 1);
|
||||
state_save_register_func_presave(mips3_presave);
|
||||
state_save_register_func_postload(mips3_postload);
|
||||
}
|
||||
|
||||
|
||||
@@ -535,6 +781,8 @@ void r5000le_reset(void *param)
|
||||
|
||||
void mips3_exit(void)
|
||||
{
|
||||
mips3_set_jit(0);
|
||||
|
||||
/* free cache memory */
|
||||
if (mips3.icache)
|
||||
free(mips3.icache);
|
||||
@@ -624,6 +872,9 @@ static INLINE void set_cop0_reg(int idx, UINT64 val)
|
||||
mips3.cpr[0][idx] = val;
|
||||
if (diff & 0x8000)
|
||||
update_cycle_counting();
|
||||
/* the recompiler translates FPU instructions only while COP1 is usable */
|
||||
if (diff & SR_COP1)
|
||||
jit_flush();
|
||||
check_irqs();
|
||||
break;
|
||||
}
|
||||
@@ -682,6 +933,155 @@ static void logtlbentry(void)
|
||||
logonetlbentry(1);
|
||||
}
|
||||
|
||||
/*
|
||||
Exact skip of the loops that wait for an interrupt by polling Cause.
|
||||
|
||||
Within a timeslice nothing changes Cause: interrupt lines and the
|
||||
Count/Compare timer only change between timeslices. So every pass of
|
||||
such a loop leaves the same state, except for counters, and the whole
|
||||
passes that still fit in the timeslice can be skipped: registers and
|
||||
cycles end up exactly as if they had run. The last passes always run
|
||||
normally. Called by the MFC0 of Cause (mips3.ppc), after its read.
|
||||
|
||||
The loop, from the branch target L to the backward branch and its
|
||||
delay slot, may only hold:
|
||||
mfc0 rt, Cause (this instruction, once)
|
||||
andi rt, rt, mask (Cause & mask is 0 now)
|
||||
nop
|
||||
lw/lh/lb $zero, off(rb) (rb + off in a range declared free of
|
||||
side effects, mips3_add_poll_read)
|
||||
beq rc, $zero, outside (a timeout counter)
|
||||
beq rt, $zero, L (the loop branch, last)
|
||||
delay slot: nop, or addi/addiu rc, rc, imm (a counter)
|
||||
A timeout counter must count down by 1 and stays at 1 or more.
|
||||
*/
|
||||
static void cause_poll_skip(UINT32 mfc0_op)
|
||||
{
|
||||
UINT32 pc = mips3.ppc, a, op, branch_pc = 0, rt = (mfc0_op >> 16) & 31, mask = 0;
|
||||
int count, i, n, cost, rc = -1, timeout = 0;
|
||||
INT32 imm = 0;
|
||||
UINT32 body[16];
|
||||
|
||||
if (rt == 0 || mips3.nextpc != ~0)
|
||||
return;
|
||||
|
||||
/* find the backward branch beq rt, $zero, L with L <= pc */
|
||||
for (a = pc + 4; a < pc + 4 * 12; a += 4)
|
||||
{
|
||||
op = ROPCODE(a);
|
||||
if ((op >> 26) == 0x04 && ((op >> 21) & 31) == rt && ((op >> 16) & 31) == 0)
|
||||
{
|
||||
UINT32 target = a + 4 + ((INT32)(INT16)op << 2);
|
||||
if (target <= pc && pc - target < 4 * 8)
|
||||
{
|
||||
branch_pc = a;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!branch_pc)
|
||||
return;
|
||||
{
|
||||
UINT32 target = branch_pc + 4 + ((INT32)(INT16)ROPCODE(branch_pc) << 2);
|
||||
count = (branch_pc + 8 - target) / 4;
|
||||
if (count > 16)
|
||||
return;
|
||||
for (i = 0; i < count; i++)
|
||||
body[i] = ROPCODE(target + i * 4);
|
||||
a = target;
|
||||
}
|
||||
|
||||
/* check every instruction of the loop */
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
UINT32 ia = a + i * 4;
|
||||
op = body[i];
|
||||
if (ia == pc)
|
||||
continue;
|
||||
if (ia == branch_pc)
|
||||
continue;
|
||||
if (op == 0)
|
||||
continue;
|
||||
if (ia == branch_pc + 4)
|
||||
{
|
||||
/* delay slot: a counter */
|
||||
if (((op >> 26) == 0x08 || (op >> 26) == 0x09) && ((op >> 21) & 31) == ((op >> 16) & 31) &&
|
||||
((op >> 16) & 31) != 0 && ((op >> 16) & 31) != rt)
|
||||
{
|
||||
rc = (op >> 16) & 31;
|
||||
imm = (INT16)op;
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ((op >> 26) == 0x0c && ((op >> 21) & 31) == rt && ((op >> 16) & 31) == rt)
|
||||
{
|
||||
/* the mask, between the mfc0 and the branch */
|
||||
if (ia < pc || ia > branch_pc)
|
||||
return;
|
||||
mask |= op & 0xffff;
|
||||
continue;
|
||||
}
|
||||
if (((op >> 26) == 0x23 || (op >> 26) == 0x21 || (op >> 26) == 0x20) && ((op >> 16) & 31) == 0)
|
||||
{
|
||||
UINT32 address = (UINT32)mips3.r[(op >> 21) & 31] + (INT16)op;
|
||||
int p, ok = 0;
|
||||
for (p = 0; p < pollread_count; p++)
|
||||
if (address >= pollread[p].start && address <= pollread[p].end)
|
||||
ok = 1;
|
||||
if (ok)
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
if ((op >> 26) == 0x04 && ((op >> 16) & 31) == 0 && ((op >> 21) & 31) != rt)
|
||||
{
|
||||
/* a timeout: beq rc, $zero, out of the loop */
|
||||
UINT32 target = ia + 4 + ((INT32)(INT16)op << 2);
|
||||
if (target >= a && target <= branch_pc + 4)
|
||||
return;
|
||||
if (timeout)
|
||||
return;
|
||||
timeout = (op >> 21) & 31;
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!mask || (CAUSE & mask))
|
||||
return;
|
||||
if (timeout && (timeout != rc || imm != -1))
|
||||
return;
|
||||
|
||||
/* whole passes that fit, leaving at least two to run normally */
|
||||
cost = count + 25;
|
||||
n = mips3_icount / cost - 2;
|
||||
if (n <= 0)
|
||||
return;
|
||||
if (rc >= 0)
|
||||
{
|
||||
INT64 value = (INT32)(UINT32)mips3.r[rc];
|
||||
if (timeout)
|
||||
{
|
||||
if (value <= 1)
|
||||
return;
|
||||
if (n > value - 1)
|
||||
n = (int)(value - 1);
|
||||
}
|
||||
else if ((body[(branch_pc + 4 - a) / 4] >> 26) == 0x08)
|
||||
{
|
||||
/* ADDI traps on overflow: stop before it */
|
||||
INT64 limit = imm > 0 ? ((INT64)0x7fffffff - value) / imm : (value + (INT64)0x80000000) / -imm;
|
||||
if (imm == 0)
|
||||
limit = n;
|
||||
if (n > limit)
|
||||
n = (int)limit;
|
||||
}
|
||||
if (n <= 0)
|
||||
return;
|
||||
mips3.r[rc] = (INT64)(INT32)((UINT32)value + (UINT32)(imm * n));
|
||||
}
|
||||
mips3_icount -= n * cost;
|
||||
}
|
||||
|
||||
static INLINE void handle_cop0(UINT32 op)
|
||||
{
|
||||
if ((SR & SR_KSU_MASK) != SR_KSU_KERNEL && !(SR & SR_COP0))
|
||||
@@ -689,7 +1089,11 @@ static INLINE void handle_cop0(UINT32 op)
|
||||
|
||||
switch (RSREG)
|
||||
{
|
||||
case 0x00: /* MFCz */ if (RTREG) RTVAL64 = (INT32)get_cop0_reg(RDREG); break;
|
||||
case 0x00: /* MFCz */ if (RTREG) RTVAL64 = (INT32)get_cop0_reg(RDREG);
|
||||
/* optional: whole passes of a loop waiting for an interrupt in Cause */
|
||||
if (cause_poll_enabled && RDREG == COP0_Cause)
|
||||
cause_poll_skip(op);
|
||||
break;
|
||||
case 0x01: /* DMFCz */ if (RTREG) RTVAL64 = get_cop0_reg(RDREG); break;
|
||||
case 0x02: /* CFCz */ if (RTREG) RTVAL64 = (INT32)get_cop0_creg(RDREG); break;
|
||||
case 0x04: /* MTCz */ set_cop0_reg(RDREG, RTVAL32); break;
|
||||
@@ -1119,6 +1523,14 @@ static INLINE void handle_cop1(UINT32 op)
|
||||
|
||||
|
||||
|
||||
/* a COP1 instruction (not a branch) from translated code: exactly the interpreter's */
|
||||
static void jit_cop1_helper(UINT32 op)
|
||||
{
|
||||
handle_cop1(op);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*###################################################################################################
|
||||
** COP1X (FPU EXTRA) EXECUTION HANDLING
|
||||
**#################################################################################################*/
|
||||
@@ -1283,6 +1695,9 @@ int mips3_execute(int cycles)
|
||||
change_pc32bedw(mips3.pc);
|
||||
|
||||
|
||||
/* optional fast RAM (see mips3_add_fastram) */
|
||||
fastram_attach();
|
||||
|
||||
/* check for IRQs */
|
||||
check_irqs();
|
||||
|
||||
@@ -1297,6 +1712,47 @@ int mips3_execute(int cycles)
|
||||
mips3.ppc = mips3.pc;
|
||||
CALL_MAME_DEBUG;
|
||||
|
||||
#if MIPS3_JIT_SUPPORTED
|
||||
/* recompiled block, when there are enough cycles left for all of it */
|
||||
if (jit_enabled && mips3.nextpc == ~0)
|
||||
{
|
||||
struct jit_block *block = jit_lookup(mips3.pc);
|
||||
if (block && (int)block->len <= mips3_icount)
|
||||
{
|
||||
/* run blocks back to back while they fit in the timeslice; */
|
||||
/* each takes its own cycles, and none taken means a side exit */
|
||||
/* before its first instruction, which the interpreter then runs */
|
||||
int ran = 0, stalled = 0;
|
||||
for (;;)
|
||||
{
|
||||
int before = mips3_icount;
|
||||
mips3.pc = ((jit_func)block->code)();
|
||||
if (mips3_icount == before)
|
||||
{
|
||||
stalled = 1;
|
||||
break;
|
||||
}
|
||||
ran = 1;
|
||||
if (mips3_icount <= 0)
|
||||
break;
|
||||
block = jit_lookup(mips3.pc);
|
||||
if (!block || (int)block->len > mips3_icount)
|
||||
break;
|
||||
}
|
||||
if (ran)
|
||||
{
|
||||
change_pc32bedw(mips3.pc);
|
||||
if (!stalled)
|
||||
{
|
||||
mips3.ppc = mips3.pc - 4;
|
||||
continue;
|
||||
}
|
||||
mips3.ppc = mips3.pc;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* instruction fetch */
|
||||
op = ROPCODE(mips3.pc);
|
||||
|
||||
|
||||
@@ -183,6 +183,20 @@ extern void r5000le_reset(void *param);
|
||||
|
||||
void mips3drc_set_options(UINT8 cpunum, UINT32 opts);
|
||||
|
||||
/* optional speedups for a single MIPS3 CPU, off by default; set them up in DRIVER_INIT */
|
||||
/* plain RAM accessed through a direct pointer (no handlers may sit in the range) */
|
||||
void mips3_add_fastram(offs_t start, offs_t end, int readonly, void *base);
|
||||
void mips3_add_fastram_wait(offs_t start, offs_t end, int readonly, void *base, int wait);
|
||||
/* skip, exactly, the whole passes of loops waiting for an interrupt in Cause (see mips3.c) */
|
||||
void mips3_set_cause_poll_skip(int enable);
|
||||
/* loads from this range, into $zero, have no side effects (they may sit in such a loop) */
|
||||
void mips3_add_poll_read(offs_t start, offs_t end);
|
||||
/* recompile integer code in fast RAM with sljit, where supported (x86 and ARM, 32 and 64-bit) */
|
||||
void mips3_set_jit(int enable);
|
||||
void mips3_ram_written(offs_t address, UINT32 bytes);
|
||||
/* nonzero when this build has the recompiler (x86/ARM hosts that allow run-time code) */
|
||||
int mips3_jit_available(void);
|
||||
|
||||
|
||||
|
||||
#endif /* _MIPS3_H */
|
||||
@@ -5830,3 +5830,49 @@ unsigned mips3_dasm(char *buffer, unsigned pc)
|
||||
return 4;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*###################################################################################################
|
||||
** OPTIONAL SPEEDUPS (see mips3.h)
|
||||
**
|
||||
** This x86 recompiler is built instead of mips3.c when X86_MIPS3_DRC is set (32-bit x86 hosts).
|
||||
** The speedups declared in mips3.h live in mips3.c; here they are accepted and ignored, so
|
||||
** drivers that request them (Killer Instinct) still link and run, just without them.
|
||||
**#################################################################################################*/
|
||||
|
||||
void mips3_add_fastram(offs_t start, offs_t end, int readonly, void *base)
|
||||
{
|
||||
(void)start; (void)end; (void)readonly; (void)base;
|
||||
}
|
||||
|
||||
void mips3_add_fastram_wait(offs_t start, offs_t end, int readonly, void *base, int wait)
|
||||
{
|
||||
(void)start; (void)end; (void)readonly; (void)base; (void)wait;
|
||||
}
|
||||
|
||||
void mips3_set_cause_poll_skip(int enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
void mips3_add_poll_read(offs_t start, offs_t end)
|
||||
{
|
||||
(void)start; (void)end;
|
||||
}
|
||||
|
||||
void mips3_set_jit(int enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
int mips3_jit_available(void)
|
||||
{
|
||||
/* no sljit recompiler in this build: the "MIPS Dynarec" core option stays hidden */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mips3_ram_written(offs_t address, UINT32 bytes)
|
||||
{
|
||||
/* no translations to drop in this build */
|
||||
(void)address; (void)bytes;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,18 @@
|
||||
/***************************************************************************
|
||||
|
||||
mips3jit.h
|
||||
|
||||
Host support of the MIPS3 recompiler: the bundled sljit, configured
|
||||
and built once for all the recompilers (src/lib/sljit/sljit_mame.h).
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MIPS3JIT_H
|
||||
#define MIPS3JIT_H
|
||||
|
||||
/* the sljit build shared by the recompilers decides where they run */
|
||||
#include "../../lib/sljit/sljit_mame.h"
|
||||
|
||||
#define MIPS3_JIT_SUPPORTED SLJIT_MAME_SUPPORTED
|
||||
|
||||
#endif /* MIPS3JIT_H */
|
||||
@@ -213,6 +213,17 @@ extern void mips_set_irq_callback(int (*callback)(int irqline));
|
||||
extern const char *mips_info(void *context, int regnum);
|
||||
extern unsigned mips_dasm(char *buffer, UINT32 pc);
|
||||
|
||||
/* optional speedups, off unless a driver enables them */
|
||||
/* loads and stores in a plain RAM region use a direct pointer */
|
||||
extern void psxcpu_add_fastram(offs_t start, offs_t end, int readonly, void *base);
|
||||
/* fast RAM written behind the CPU's back (DMA, driver patches) */
|
||||
extern void psxcpu_ram_written(const void *host, UINT32 bytes);
|
||||
/* recompiler (sljit), where supported. The fast RAM table and the
|
||||
recompiler state are global, not part of the CPU context: one PSXCPU
|
||||
per machine. */
|
||||
extern int psxcpu_jit_available(void);
|
||||
extern void psxcpu_set_jit(int enable);
|
||||
|
||||
#ifdef MAME_DEBUG
|
||||
extern unsigned DasmMIPS(char *buff, unsigned _pc);
|
||||
#endif
|
||||
|
||||
+1331
-1923
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,941 @@
|
||||
/***************************************************************************
|
||||
|
||||
PlayStation Geometry Transformation Engine, as current MAME
|
||||
(src/devices/cpu/psx/gte.cpp, copyright smf, BSD-3-Clause), in C.
|
||||
|
||||
The hardware divide (reciprocal table, result capped at 0x1ffff and
|
||||
flagged), the 44-bit accumulators with their overflow flags, the
|
||||
register moves (IRGB/ORGB, LZCS/LZCR, the sign extended control
|
||||
registers, FLAG) of current MAME.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#define GTE_SF( op ) ( ( op >> 19 ) & 1 )
|
||||
#define GTE_MX( op ) ( ( op >> 17 ) & 3 )
|
||||
#define GTE_V( op ) ( ( op >> 15 ) & 3 )
|
||||
#define GTE_CV( op ) ( ( op >> 13 ) & 3 )
|
||||
#define GTE_LM( op ) ( ( op >> 10 ) & 1 )
|
||||
#define GTE_FUNCT( op ) ( op & 63 )
|
||||
|
||||
static int m_sf;
|
||||
static INT64 m_mac0;
|
||||
static INT64 m_mac1;
|
||||
static INT64 m_mac2;
|
||||
static INT64 m_mac3;
|
||||
|
||||
static INLINE int count_leading_zeros32( UINT32 v )
|
||||
{
|
||||
int n = 0;
|
||||
if( v == 0 )
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
while( ( v & 0x80000000 ) == 0 )
|
||||
{
|
||||
v <<= 1;
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/* a 44-bit accumulator with sticky overflow flags (MAME's int44) */
|
||||
typedef struct
|
||||
{
|
||||
INT64 value;
|
||||
int pos;
|
||||
int neg;
|
||||
} int44;
|
||||
|
||||
static INLINE int44 i44( INT64 value )
|
||||
{
|
||||
int44 r;
|
||||
r.value = value;
|
||||
r.pos = value > ( ( (INT64)1 << 43 ) - 1 );
|
||||
r.neg = value < -( (INT64)1 << 43 );
|
||||
return r;
|
||||
}
|
||||
|
||||
static INLINE int44 i44_add( int44 a, INT64 add )
|
||||
{
|
||||
int44 r;
|
||||
INT64 value = (INT64)( (UINT64)( a.value + add ) << 20 ) >> 20;
|
||||
r.value = value;
|
||||
r.pos = a.pos || ( value < 0 && a.value >= 0 && add >= 0 );
|
||||
r.neg = a.neg || ( value >= 0 && a.value < 0 && add < 0 );
|
||||
return r;
|
||||
}
|
||||
|
||||
#define VX0 ( (*(INT16 *)&mipscpu.cp2dr[ 0 ].w.l) )
|
||||
#define VY0 ( (*(INT16 *)&mipscpu.cp2dr[ 0 ].w.h) )
|
||||
#define VZ0 ( (*(INT16 *)&mipscpu.cp2dr[ 1 ].w.l) )
|
||||
#define VX1 ( mipscpu.cp2dr[ 2 ].w.l )
|
||||
#define VY1 ( mipscpu.cp2dr[ 2 ].w.h )
|
||||
#define VZ1 ( mipscpu.cp2dr[ 3 ].w.l )
|
||||
#define VX2 ( mipscpu.cp2dr[ 4 ].w.l )
|
||||
#define VY2 ( mipscpu.cp2dr[ 4 ].w.h )
|
||||
#define VZ2 ( mipscpu.cp2dr[ 5 ].w.l )
|
||||
#define R ( mipscpu.cp2dr[ 6 ].b.l )
|
||||
#define G ( mipscpu.cp2dr[ 6 ].b.h )
|
||||
#define B ( mipscpu.cp2dr[ 6 ].b.h2 )
|
||||
#define CODE ( mipscpu.cp2dr[ 6 ].b.h3 )
|
||||
#define OTZ ( mipscpu.cp2dr[ 7 ].w.l )
|
||||
#define IR0 ( (*(INT16 *)&mipscpu.cp2dr[ 8 ].w.l) )
|
||||
#define IR1 ( (*(INT16 *)&mipscpu.cp2dr[ 9 ].w.l) )
|
||||
#define IR2 ( (*(INT16 *)&mipscpu.cp2dr[ 10 ].w.l) )
|
||||
#define IR3 ( (*(INT16 *)&mipscpu.cp2dr[ 11 ].w.l) )
|
||||
#define SXY0 ( mipscpu.cp2dr[ 12 ].d )
|
||||
#define SX0 ( (*(INT16 *)&mipscpu.cp2dr[ 12 ].w.l) )
|
||||
#define SY0 ( (*(INT16 *)&mipscpu.cp2dr[ 12 ].w.h) )
|
||||
#define SXY1 ( mipscpu.cp2dr[ 13 ].d )
|
||||
#define SX1 ( (*(INT16 *)&mipscpu.cp2dr[ 13 ].w.l) )
|
||||
#define SY1 ( (*(INT16 *)&mipscpu.cp2dr[ 13 ].w.h) )
|
||||
#define SXY2 ( mipscpu.cp2dr[ 14 ].d )
|
||||
#define SX2 ( (*(INT16 *)&mipscpu.cp2dr[ 14 ].w.l) )
|
||||
#define SY2 ( (*(INT16 *)&mipscpu.cp2dr[ 14 ].w.h) )
|
||||
#define SXYP ( mipscpu.cp2dr[ 15 ].d )
|
||||
#define SXP ( (*(INT16 *)&mipscpu.cp2dr[ 15 ].w.l) )
|
||||
#define SYP ( (*(INT16 *)&mipscpu.cp2dr[ 15 ].w.h) )
|
||||
#define SZ0 ( mipscpu.cp2dr[ 16 ].w.l )
|
||||
#define SZ1 ( mipscpu.cp2dr[ 17 ].w.l )
|
||||
#define SZ2 ( mipscpu.cp2dr[ 18 ].w.l )
|
||||
#define SZ3 ( mipscpu.cp2dr[ 19 ].w.l )
|
||||
#define RGB0 ( mipscpu.cp2dr[ 20 ].d )
|
||||
#define R0 ( mipscpu.cp2dr[ 20 ].b.l )
|
||||
#define G0 ( mipscpu.cp2dr[ 20 ].b.h )
|
||||
#define B0 ( mipscpu.cp2dr[ 20 ].b.h2 )
|
||||
#define CD0 ( mipscpu.cp2dr[ 20 ].b.h3 )
|
||||
#define RGB1 ( mipscpu.cp2dr[ 21 ].d )
|
||||
#define R1 ( mipscpu.cp2dr[ 21 ].b.l )
|
||||
#define G1 ( mipscpu.cp2dr[ 21 ].b.h )
|
||||
#define B1 ( mipscpu.cp2dr[ 21 ].b.h2 )
|
||||
#define CD1 ( mipscpu.cp2dr[ 21 ].b.h3 )
|
||||
#define RGB2 ( mipscpu.cp2dr[ 22 ].d )
|
||||
#define R2 ( mipscpu.cp2dr[ 22 ].b.l )
|
||||
#define G2 ( mipscpu.cp2dr[ 22 ].b.h )
|
||||
#define B2 ( mipscpu.cp2dr[ 22 ].b.h2 )
|
||||
#define CD2 ( mipscpu.cp2dr[ 22 ].b.h3 )
|
||||
#define RES1 ( mipscpu.cp2dr[ 23 ].d )
|
||||
#define MAC0 ( (*(INT32 *)&mipscpu.cp2dr[ 24 ].d) )
|
||||
#define MAC1 ( (*(INT32 *)&mipscpu.cp2dr[ 25 ].d) )
|
||||
#define MAC2 ( (*(INT32 *)&mipscpu.cp2dr[ 26 ].d) )
|
||||
#define MAC3 ( (*(INT32 *)&mipscpu.cp2dr[ 27 ].d) )
|
||||
#define IRGB ( mipscpu.cp2dr[ 28 ].d )
|
||||
#define ORGB ( mipscpu.cp2dr[ 29 ].d )
|
||||
#define LZCS ( mipscpu.cp2dr[ 30 ].d )
|
||||
#define LZCR ( mipscpu.cp2dr[ 31 ].d )
|
||||
|
||||
#define R11 ( (*(INT16 *)&mipscpu.cp2cr[ 0 ].w.l) )
|
||||
#define R12 ( (*(INT16 *)&mipscpu.cp2cr[ 0 ].w.h) )
|
||||
#define R13 ( (*(INT16 *)&mipscpu.cp2cr[ 1 ].w.l) )
|
||||
#define R21 ( (*(INT16 *)&mipscpu.cp2cr[ 1 ].w.h) )
|
||||
#define R22 ( (*(INT16 *)&mipscpu.cp2cr[ 2 ].w.l) )
|
||||
#define R23 ( (*(INT16 *)&mipscpu.cp2cr[ 2 ].w.h) )
|
||||
#define R31 ( (*(INT16 *)&mipscpu.cp2cr[ 3 ].w.l) )
|
||||
#define R32 ( (*(INT16 *)&mipscpu.cp2cr[ 3 ].w.h) )
|
||||
#define R33 ( (*(INT16 *)&mipscpu.cp2cr[ 4 ].w.l) )
|
||||
#define TRX ( (*(INT32 *)&mipscpu.cp2cr[ 5 ].d) )
|
||||
#define TRY ( (*(INT32 *)&mipscpu.cp2cr[ 6 ].d) )
|
||||
#define TRZ ( (*(INT32 *)&mipscpu.cp2cr[ 7 ].d) )
|
||||
#define L11 ( (*(INT16 *)&mipscpu.cp2cr[ 8 ].w.l) )
|
||||
#define L12 ( (*(INT16 *)&mipscpu.cp2cr[ 8 ].w.h) )
|
||||
#define L13 ( (*(INT16 *)&mipscpu.cp2cr[ 9 ].w.l) )
|
||||
#define L21 ( (*(INT16 *)&mipscpu.cp2cr[ 9 ].w.h) )
|
||||
#define L22 ( (*(INT16 *)&mipscpu.cp2cr[ 10 ].w.l) )
|
||||
#define L23 ( (*(INT16 *)&mipscpu.cp2cr[ 10 ].w.h) )
|
||||
#define L31 ( (*(INT16 *)&mipscpu.cp2cr[ 11 ].w.l) )
|
||||
#define L32 ( (*(INT16 *)&mipscpu.cp2cr[ 11 ].w.h) )
|
||||
#define L33 ( (*(INT16 *)&mipscpu.cp2cr[ 12 ].w.l) )
|
||||
#define RBK ( (*(INT32 *)&mipscpu.cp2cr[ 13 ].d) )
|
||||
#define GBK ( (*(INT32 *)&mipscpu.cp2cr[ 14 ].d) )
|
||||
#define BBK ( (*(INT32 *)&mipscpu.cp2cr[ 15 ].d) )
|
||||
#define LR1 ( (*(INT16 *)&mipscpu.cp2cr[ 16 ].w.l) )
|
||||
#define LR2 ( (*(INT16 *)&mipscpu.cp2cr[ 16 ].w.h) )
|
||||
#define LR3 ( (*(INT16 *)&mipscpu.cp2cr[ 17 ].w.l) )
|
||||
#define LG1 ( (*(INT16 *)&mipscpu.cp2cr[ 17 ].w.h) )
|
||||
#define LG2 ( (*(INT16 *)&mipscpu.cp2cr[ 18 ].w.l) )
|
||||
#define LG3 ( (*(INT16 *)&mipscpu.cp2cr[ 18 ].w.h) )
|
||||
#define LB1 ( (*(INT16 *)&mipscpu.cp2cr[ 19 ].w.l) )
|
||||
#define LB2 ( (*(INT16 *)&mipscpu.cp2cr[ 19 ].w.h) )
|
||||
#define LB3 ( (*(INT16 *)&mipscpu.cp2cr[ 20 ].w.l) )
|
||||
#define RFC ( (*(INT32 *)&mipscpu.cp2cr[ 21 ].d) )
|
||||
#define GFC ( (*(INT32 *)&mipscpu.cp2cr[ 22 ].d) )
|
||||
#define BFC ( (*(INT32 *)&mipscpu.cp2cr[ 23 ].d) )
|
||||
#define OFX ( (*(INT32 *)&mipscpu.cp2cr[ 24 ].d) )
|
||||
#define OFY ( (*(INT32 *)&mipscpu.cp2cr[ 25 ].d) )
|
||||
#define H ( (*(INT16 *)&mipscpu.cp2cr[ 26 ].w.l) )
|
||||
#define DQA ( (*(INT16 *)&mipscpu.cp2cr[ 27 ].w.l) )
|
||||
#define DQB ( (*(INT32 *)&mipscpu.cp2cr[ 28 ].d) )
|
||||
#define ZSF3 ( (*(INT16 *)&mipscpu.cp2cr[ 29 ].w.l) )
|
||||
#define ZSF4 ( (*(INT16 *)&mipscpu.cp2cr[ 30 ].w.l) )
|
||||
#define FLAG ( mipscpu.cp2cr[ 31 ].d )
|
||||
|
||||
#define VX( n ) ( n < 3 ? (*(INT16 *)&mipscpu.cp2dr[ n << 1 ].w.l) : IR1 )
|
||||
#define VY( n ) ( n < 3 ? (*(INT16 *)&mipscpu.cp2dr[ n << 1 ].w.h) : IR2 )
|
||||
#define VZ( n ) ( n < 3 ? (*(INT16 *)&mipscpu.cp2dr[ ( n << 1 ) + 1 ].w.l) : IR3 )
|
||||
#define MX11( n ) ( n < 3 ? (*(INT16 *)&mipscpu.cp2cr[ ( n << 3 ) ].w.l) : -R << 4 )
|
||||
#define MX12( n ) ( n < 3 ? (*(INT16 *)&mipscpu.cp2cr[ ( n << 3 ) ].w.h) : R << 4 )
|
||||
#define MX13( n ) ( n < 3 ? (*(INT16 *)&mipscpu.cp2cr[ ( n << 3 ) + 1 ].w.l) : IR0 )
|
||||
#define MX21( n ) ( n < 3 ? (*(INT16 *)&mipscpu.cp2cr[ ( n << 3 ) + 1 ].w.h) : R13 )
|
||||
#define MX22( n ) ( n < 3 ? (*(INT16 *)&mipscpu.cp2cr[ ( n << 3 ) + 2 ].w.l) : R13 )
|
||||
#define MX23( n ) ( n < 3 ? (*(INT16 *)&mipscpu.cp2cr[ ( n << 3 ) + 2 ].w.h) : R13 )
|
||||
#define MX31( n ) ( n < 3 ? (*(INT16 *)&mipscpu.cp2cr[ ( n << 3 ) + 3 ].w.l) : R22 )
|
||||
#define MX32( n ) ( n < 3 ? (*(INT16 *)&mipscpu.cp2cr[ ( n << 3 ) + 3 ].w.h) : R22 )
|
||||
#define MX33( n ) ( n < 3 ? (*(INT16 *)&mipscpu.cp2cr[ ( n << 3 ) + 4 ].w.l) : R22 )
|
||||
#define CV1( n ) ( n < 3 ? (*(INT32 *)&mipscpu.cp2cr[ ( n << 3 ) + 5 ].d) : 0 )
|
||||
#define CV2( n ) ( n < 3 ? (*(INT32 *)&mipscpu.cp2cr[ ( n << 3 ) + 6 ].d) : 0 )
|
||||
#define CV3( n ) ( n < 3 ? (*(INT32 *)&mipscpu.cp2cr[ ( n << 3 ) + 7 ].d) : 0 )
|
||||
|
||||
static INT32 LIM( INT32 value, INT32 max, INT32 min, UINT32 flag )
|
||||
{
|
||||
if( value > max )
|
||||
{
|
||||
FLAG |= flag;
|
||||
return max;
|
||||
}
|
||||
else if( value < min )
|
||||
{
|
||||
FLAG |= flag;
|
||||
return min;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static UINT32 getcp2dr( int reg )
|
||||
{
|
||||
switch( reg )
|
||||
{
|
||||
case 1:
|
||||
case 3:
|
||||
case 5:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
mipscpu.cp2dr[ reg ].d = (INT32)(*(INT16 *)&mipscpu.cp2dr[ reg ].w.l);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
case 16:
|
||||
case 17:
|
||||
case 18:
|
||||
case 19:
|
||||
mipscpu.cp2dr[ reg ].d = (UINT32)mipscpu.cp2dr[ reg ].w.l;
|
||||
break;
|
||||
|
||||
case 15:
|
||||
mipscpu.cp2dr[ reg ].d = SXY2;
|
||||
break;
|
||||
|
||||
case 28:
|
||||
case 29:
|
||||
mipscpu.cp2dr[ reg ].d = LIM( IR1 >> 7, 0x1f, 0, 0 ) | ( LIM( IR2 >> 7, 0x1f, 0, 0 ) << 5 ) | ( LIM( IR3 >> 7, 0x1f, 0, 0 ) << 10 );
|
||||
break;
|
||||
}
|
||||
return mipscpu.cp2dr[ reg ].d;
|
||||
}
|
||||
|
||||
static void setcp2dr( int reg, UINT32 value )
|
||||
{
|
||||
|
||||
switch( reg )
|
||||
{
|
||||
case 15:
|
||||
SXY0 = SXY1;
|
||||
SXY1 = SXY2;
|
||||
SXY2 = value;
|
||||
break;
|
||||
|
||||
case 28:
|
||||
IR1 = ( value & 0x1f ) << 7;
|
||||
IR2 = ( value & 0x3e0 ) << 2;
|
||||
IR3 = ( value & 0x7c00 ) >> 3;
|
||||
break;
|
||||
|
||||
case 30:
|
||||
LZCR = ( value & 0x80000000 ) == 0 ? count_leading_zeros32( value ) : count_leading_zeros32( ~value );
|
||||
break;
|
||||
|
||||
case 31:
|
||||
return;
|
||||
}
|
||||
|
||||
mipscpu.cp2dr[ reg ].d = value;
|
||||
}
|
||||
|
||||
static UINT32 getcp2cr( int reg )
|
||||
{
|
||||
|
||||
return mipscpu.cp2cr[ reg ].d;
|
||||
}
|
||||
|
||||
static void setcp2cr( int reg, UINT32 value )
|
||||
{
|
||||
|
||||
switch( reg )
|
||||
{
|
||||
case 4:
|
||||
case 12:
|
||||
case 20:
|
||||
case 26:
|
||||
case 27:
|
||||
case 29:
|
||||
case 30:
|
||||
value = (INT32)(INT16) value;
|
||||
break;
|
||||
|
||||
case 31:
|
||||
value = value & 0x7ffff000;
|
||||
if( ( value & 0x7f87e000 ) != 0 )
|
||||
{
|
||||
value |= 0x80000000;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
mipscpu.cp2cr[ reg ].d = value;
|
||||
}
|
||||
|
||||
static INLINE INT64 gte_shift( INT64 a, int sf )
|
||||
{
|
||||
if( sf > 0 )
|
||||
{
|
||||
return a >> 12;
|
||||
}
|
||||
else if( sf < 0 )
|
||||
{
|
||||
return a << 12;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static INT32 BOUNDS( int44 value, UINT32 max_flag, UINT32 min_flag )
|
||||
{
|
||||
if( value.pos )
|
||||
{
|
||||
FLAG |= max_flag;
|
||||
}
|
||||
|
||||
if( value.neg )
|
||||
{
|
||||
FLAG |= min_flag;
|
||||
}
|
||||
|
||||
return gte_shift( value.value, m_sf );
|
||||
}
|
||||
|
||||
static INLINE UINT32 gte_divide( UINT16 numerator, UINT16 denominator )
|
||||
{
|
||||
if( numerator < ( denominator * 2 ) )
|
||||
{
|
||||
static const UINT8 table[] =
|
||||
{
|
||||
0xff, 0xfd, 0xfb, 0xf9, 0xf7, 0xf5, 0xf3, 0xf1, 0xef, 0xee, 0xec, 0xea, 0xe8, 0xe6, 0xe4, 0xe3,
|
||||
0xe1, 0xdf, 0xdd, 0xdc, 0xda, 0xd8, 0xd6, 0xd5, 0xd3, 0xd1, 0xd0, 0xce, 0xcd, 0xcb, 0xc9, 0xc8,
|
||||
0xc6, 0xc5, 0xc3, 0xc1, 0xc0, 0xbe, 0xbd, 0xbb, 0xba, 0xb8, 0xb7, 0xb5, 0xb4, 0xb2, 0xb1, 0xb0,
|
||||
0xae, 0xad, 0xab, 0xaa, 0xa9, 0xa7, 0xa6, 0xa4, 0xa3, 0xa2, 0xa0, 0x9f, 0x9e, 0x9c, 0x9b, 0x9a,
|
||||
0x99, 0x97, 0x96, 0x95, 0x94, 0x92, 0x91, 0x90, 0x8f, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x87, 0x86,
|
||||
0x85, 0x84, 0x83, 0x82, 0x81, 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0x77, 0x75, 0x74,
|
||||
0x73, 0x72, 0x71, 0x70, 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64,
|
||||
0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e, 0x5d, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58, 0x57, 0x56, 0x55,
|
||||
0x54, 0x53, 0x53, 0x52, 0x51, 0x50, 0x4f, 0x4e, 0x4d, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48, 0x48,
|
||||
0x47, 0x46, 0x45, 0x44, 0x43, 0x43, 0x42, 0x41, 0x40, 0x3f, 0x3f, 0x3e, 0x3d, 0x3c, 0x3c, 0x3b,
|
||||
0x3a, 0x39, 0x39, 0x38, 0x37, 0x36, 0x36, 0x35, 0x34, 0x33, 0x33, 0x32, 0x31, 0x31, 0x30, 0x2f,
|
||||
0x2e, 0x2e, 0x2d, 0x2c, 0x2c, 0x2b, 0x2a, 0x2a, 0x29, 0x28, 0x28, 0x27, 0x26, 0x26, 0x25, 0x24,
|
||||
0x24, 0x23, 0x22, 0x22, 0x21, 0x20, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
|
||||
0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13, 0x12, 0x12, 0x11, 0x11,
|
||||
0x10, 0x0f, 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08,
|
||||
0x07, 0x07, 0x06, 0x06, 0x05, 0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00,
|
||||
0x00
|
||||
};
|
||||
|
||||
int shift = ( count_leading_zeros32( denominator ) - 16 );
|
||||
int r1 = ( denominator << shift ) & 0x7fff;
|
||||
int r2 = table[ ( ( r1 + 0x40 ) >> 7 ) ] + 0x101;
|
||||
int r3 = ( ( 0x80 - ( r2 * ( r1 + 0x8000 ) ) ) >> 8 ) & 0x1ffff;
|
||||
UINT32 reciprocal = ( ( r2 * r3 ) + 0x80 ) >> 8;
|
||||
|
||||
return (UINT32)( ( ( (UINT64)reciprocal * ( (UINT32)numerator << shift ) ) + 0x8000 ) >> 16 );
|
||||
}
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
/* Setting bits 12 & 19-22 in FLAG does not set bit 31 */
|
||||
|
||||
static INT32 A1i( int44 a ) { m_mac1 = a.value; return BOUNDS( a, ( 1U << 31 ) | ( 1 << 30 ), ( 1U << 31 ) | ( 1 << 27 ) ); }
|
||||
static INT32 A1( INT64 a ) { return A1i( i44( a ) ); }
|
||||
static INT32 A2i( int44 a ) { m_mac2 = a.value; return BOUNDS( a, ( 1U << 31 ) | ( 1 << 29 ), ( 1U << 31 ) | ( 1 << 26 ) ); }
|
||||
static INT32 A2( INT64 a ) { return A2i( i44( a ) ); }
|
||||
static INT32 A3i( int44 a ) { m_mac3 = a.value; return BOUNDS( a, ( 1U << 31 ) | ( 1 << 28 ), ( 1U << 31 ) | ( 1 << 25 ) ); }
|
||||
static INT32 A3( INT64 a ) { return A3i( i44( a ) ); }
|
||||
static INT32 Lm_B1( INT32 a, int lm ) { return LIM( a, 0x7fff, -0x8000 * !lm, ( 1U << 31 ) | ( 1 << 24 ) ); }
|
||||
static INT32 Lm_B2( INT32 a, int lm ) { return LIM( a, 0x7fff, -0x8000 * !lm, ( 1U << 31 ) | ( 1 << 23 ) ); }
|
||||
static INT32 Lm_B3( INT32 a, int lm ) { return LIM( a, 0x7fff, -0x8000 * !lm, ( 1 << 22 ) ); }
|
||||
|
||||
static INT32 Lm_B3_sf( INT64 value, int sf, int lm )
|
||||
{
|
||||
INT32 value_sf = (INT32)gte_shift( value, sf );
|
||||
INT32 value_12 = (INT32)gte_shift( value, 1 );
|
||||
int max = 0x7fff;
|
||||
int min = 0;
|
||||
if( lm == 0 )
|
||||
{
|
||||
min = -0x8000;
|
||||
}
|
||||
|
||||
if( value_12 < -0x8000 || value_12 > 0x7fff )
|
||||
{
|
||||
FLAG |= ( 1 << 22 );
|
||||
}
|
||||
|
||||
if( value_sf > max )
|
||||
{
|
||||
return max;
|
||||
}
|
||||
else if( value_sf < min )
|
||||
{
|
||||
return min;
|
||||
}
|
||||
|
||||
return value_sf;
|
||||
}
|
||||
|
||||
static INT32 Lm_C1( INT32 a ) { return LIM( a, 0x00ff, 0x0000, ( 1 << 21 ) ); }
|
||||
static INT32 Lm_C2( INT32 a ) { return LIM( a, 0x00ff, 0x0000, ( 1 << 20 ) ); }
|
||||
static INT32 Lm_C3( INT32 a ) { return LIM( a, 0x00ff, 0x0000, ( 1 << 19 ) ); }
|
||||
static INT32 Lm_D( INT64 a, int sf ) { return LIM( gte_shift( a, sf ), 0xffff, 0x0000, ( 1U << 31 ) | ( 1 << 18 ) ); }
|
||||
|
||||
static UINT32 Lm_E( UINT32 result )
|
||||
{
|
||||
if( result == 0xffffffff )
|
||||
{
|
||||
FLAG |= ( 1U << 31 ) | ( 1 << 17 );
|
||||
return 0x1ffff;
|
||||
}
|
||||
|
||||
if( result > 0x1ffff )
|
||||
{
|
||||
return 0x1ffff;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static INT64 F( INT64 a )
|
||||
{
|
||||
m_mac0 = a;
|
||||
|
||||
if( a > 0x7fffffff )
|
||||
{
|
||||
FLAG |= ( 1U << 31 ) | ( 1 << 16 );
|
||||
}
|
||||
|
||||
if( a < -( (INT64)1 << 31 ) )
|
||||
{
|
||||
FLAG |= ( 1U << 31 ) | ( 1 << 15 );
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static INT32 Lm_G1( INT64 a )
|
||||
{
|
||||
if( a > 0x3ff )
|
||||
{
|
||||
FLAG |= ( 1U << 31 ) | ( 1 << 14 );
|
||||
return 0x3ff;
|
||||
}
|
||||
|
||||
if( a < -0x400 )
|
||||
{
|
||||
FLAG |= ( 1U << 31 ) | ( 1 << 14 );
|
||||
return -0x400;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static INT32 Lm_G2( INT64 a )
|
||||
{
|
||||
if( a > 0x3ff )
|
||||
{
|
||||
FLAG |= ( 1U << 31 ) | ( 1 << 13 );
|
||||
return 0x3ff;
|
||||
}
|
||||
|
||||
if( a < -0x400 )
|
||||
{
|
||||
FLAG |= ( 1U << 31 ) | ( 1 << 13 );
|
||||
return -0x400;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
static INT32 Lm_H( INT64 value, int sf )
|
||||
{
|
||||
INT64 value_sf = gte_shift( value, sf );
|
||||
INT32 value_12 = (INT32)gte_shift( value, 1 );
|
||||
int max = 0x1000;
|
||||
int min = 0x0000;
|
||||
|
||||
if( value_sf < min || value_sf > max )
|
||||
{
|
||||
FLAG |= ( 1 << 12 );
|
||||
}
|
||||
|
||||
if( value_12 > max )
|
||||
{
|
||||
return max;
|
||||
}
|
||||
|
||||
if( value_12 < min )
|
||||
{
|
||||
return min;
|
||||
}
|
||||
|
||||
return value_12;
|
||||
}
|
||||
|
||||
static int gte_docop2( int gteop )
|
||||
{
|
||||
int v;
|
||||
int lm;
|
||||
int cv;
|
||||
int mx;
|
||||
INT32 h_over_sz3 = 0;
|
||||
|
||||
lm = GTE_LM( gteop );
|
||||
m_sf = GTE_SF( gteop );
|
||||
|
||||
FLAG = 0;
|
||||
|
||||
switch( GTE_FUNCT( gteop ) )
|
||||
{
|
||||
case 0x00: /* drop through to RTPS */
|
||||
case 0x01:
|
||||
|
||||
MAC1 = A1i( i44_add( i44_add( i44_add( i44( (INT64) TRX << 12 ), ( R11 * VX0 ) ), ( R12 * VY0 ) ), ( R13 * VZ0 ) ) );
|
||||
MAC2 = A2i( i44_add( i44_add( i44_add( i44( (INT64) TRY << 12 ), ( R21 * VX0 ) ), ( R22 * VY0 ) ), ( R23 * VZ0 ) ) );
|
||||
MAC3 = A3i( i44_add( i44_add( i44_add( i44( (INT64) TRZ << 12 ), ( R31 * VX0 ) ), ( R32 * VY0 ) ), ( R33 * VZ0 ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3_sf( m_mac3, m_sf, lm );
|
||||
SZ0 = SZ1;
|
||||
SZ1 = SZ2;
|
||||
SZ2 = SZ3;
|
||||
SZ3 = Lm_D( m_mac3, 1 );
|
||||
h_over_sz3 = Lm_E( gte_divide( H, SZ3 ) );
|
||||
SXY0 = SXY1;
|
||||
SXY1 = SXY2;
|
||||
SX2 = Lm_G1( F( (INT64) OFX + ( (INT64) IR1 * h_over_sz3 ) ) >> 16 );
|
||||
SY2 = Lm_G2( F( (INT64) OFY + ( (INT64) IR2 * h_over_sz3 ) ) >> 16 );
|
||||
MAC0 = F( (INT64) DQB + ( (INT64) DQA * h_over_sz3 ) );
|
||||
IR0 = Lm_H( m_mac0, 1 );
|
||||
return 1;
|
||||
|
||||
case 0x06:
|
||||
|
||||
MAC0 = F( (INT64) ( SX0 * SY1 ) + ( SX1 * SY2 ) + ( SX2 * SY0 ) - ( SX0 * SY2 ) - ( SX1 * SY0 ) - ( SX2 * SY1 ) );
|
||||
return 1;
|
||||
|
||||
case 0x0c:
|
||||
|
||||
MAC1 = A1( (INT64) ( R22 * IR3 ) - ( R33 * IR2 ) );
|
||||
MAC2 = A2( (INT64) ( R33 * IR1 ) - ( R11 * IR3 ) );
|
||||
MAC3 = A3( (INT64) ( R11 * IR2 ) - ( R22 * IR1 ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
return 1;
|
||||
|
||||
case 0x10:
|
||||
|
||||
MAC1 = A1( ( R << 16 ) + ( IR0 * Lm_B1( A1( ( (INT64) RFC << 12 ) - ( R << 16 ) ), 0 ) ) );
|
||||
MAC2 = A2( ( G << 16 ) + ( IR0 * Lm_B2( A2( ( (INT64) GFC << 12 ) - ( G << 16 ) ), 0 ) ) );
|
||||
MAC3 = A3( ( B << 16 ) + ( IR0 * Lm_B3( A3( ( (INT64) BFC << 12 ) - ( B << 16 ) ), 0 ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
RGB0 = RGB1;
|
||||
RGB1 = RGB2;
|
||||
CD2 = CODE;
|
||||
R2 = Lm_C1( MAC1 >> 4 );
|
||||
G2 = Lm_C2( MAC2 >> 4 );
|
||||
B2 = Lm_C3( MAC3 >> 4 );
|
||||
return 1;
|
||||
|
||||
case 0x11:
|
||||
|
||||
MAC1 = A1( ( IR1 << 12 ) + ( IR0 * Lm_B1( A1( ( (INT64) RFC << 12 ) - ( IR1 << 12 ) ), 0 ) ) );
|
||||
MAC2 = A2( ( IR2 << 12 ) + ( IR0 * Lm_B2( A2( ( (INT64) GFC << 12 ) - ( IR2 << 12 ) ), 0 ) ) );
|
||||
MAC3 = A3( ( IR3 << 12 ) + ( IR0 * Lm_B3( A3( ( (INT64) BFC << 12 ) - ( IR3 << 12 ) ), 0 ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
RGB0 = RGB1;
|
||||
RGB1 = RGB2;
|
||||
CD2 = CODE;
|
||||
R2 = Lm_C1( MAC1 >> 4 );
|
||||
G2 = Lm_C2( MAC2 >> 4 );
|
||||
B2 = Lm_C3( MAC3 >> 4 );
|
||||
return 1;
|
||||
|
||||
case 0x12:
|
||||
|
||||
mx = GTE_MX( gteop );
|
||||
v = GTE_V( gteop );
|
||||
cv = GTE_CV( gteop );
|
||||
|
||||
switch( cv )
|
||||
{
|
||||
case 2:
|
||||
MAC1 = A1( (INT64) ( MX12( mx ) * VY( v ) ) + ( MX13( mx ) * VZ( v ) ) );
|
||||
MAC2 = A2( (INT64) ( MX22( mx ) * VY( v ) ) + ( MX23( mx ) * VZ( v ) ) );
|
||||
MAC3 = A3( (INT64) ( MX32( mx ) * VY( v ) ) + ( MX33( mx ) * VZ( v ) ) );
|
||||
Lm_B1( A1( ( (INT64) CV1( cv ) << 12 ) + ( MX11( mx ) * VX( v ) ) ), 0 );
|
||||
Lm_B2( A2( ( (INT64) CV2( cv ) << 12 ) + ( MX21( mx ) * VX( v ) ) ), 0 );
|
||||
Lm_B3( A3( ( (INT64) CV3( cv ) << 12 ) + ( MX31( mx ) * VX( v ) ) ), 0 );
|
||||
break;
|
||||
|
||||
default:
|
||||
MAC1 = A1i( i44_add( i44_add( i44_add( i44( (INT64) CV1( cv ) << 12 ), ( MX11( mx ) * VX( v ) ) ), ( MX12( mx ) * VY( v ) ) ), ( MX13( mx ) * VZ( v ) ) ) );
|
||||
MAC2 = A2i( i44_add( i44_add( i44_add( i44( (INT64) CV2( cv ) << 12 ), ( MX21( mx ) * VX( v ) ) ), ( MX22( mx ) * VY( v ) ) ), ( MX23( mx ) * VZ( v ) ) ) );
|
||||
MAC3 = A3i( i44_add( i44_add( i44_add( i44( (INT64) CV3( cv ) << 12 ), ( MX31( mx ) * VX( v ) ) ), ( MX32( mx ) * VY( v ) ) ), ( MX33( mx ) * VZ( v ) ) ) );
|
||||
break;
|
||||
}
|
||||
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
return 1;
|
||||
|
||||
case 0x13:
|
||||
|
||||
MAC1 = A1( (INT64) ( L11 * VX0 ) + ( L12 * VY0 ) + ( L13 * VZ0 ) );
|
||||
MAC2 = A2( (INT64) ( L21 * VX0 ) + ( L22 * VY0 ) + ( L23 * VZ0 ) );
|
||||
MAC3 = A3( (INT64) ( L31 * VX0 ) + ( L32 * VY0 ) + ( L33 * VZ0 ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
MAC1 = A1i( i44_add( i44_add( i44_add( i44( (INT64) RBK << 12 ), ( LR1 * IR1 ) ), ( LR2 * IR2 ) ), ( LR3 * IR3 ) ) );
|
||||
MAC2 = A2i( i44_add( i44_add( i44_add( i44( (INT64) GBK << 12 ), ( LG1 * IR1 ) ), ( LG2 * IR2 ) ), ( LG3 * IR3 ) ) );
|
||||
MAC3 = A3i( i44_add( i44_add( i44_add( i44( (INT64) BBK << 12 ), ( LB1 * IR1 ) ), ( LB2 * IR2 ) ), ( LB3 * IR3 ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
MAC1 = A1( ( ( R << 4 ) * IR1 ) + ( IR0 * Lm_B1( A1( ( (INT64) RFC << 12 ) - ( ( R << 4 ) * IR1 ) ), 0 ) ) );
|
||||
MAC2 = A2( ( ( G << 4 ) * IR2 ) + ( IR0 * Lm_B2( A2( ( (INT64) GFC << 12 ) - ( ( G << 4 ) * IR2 ) ), 0 ) ) );
|
||||
MAC3 = A3( ( ( B << 4 ) * IR3 ) + ( IR0 * Lm_B3( A3( ( (INT64) BFC << 12 ) - ( ( B << 4 ) * IR3 ) ), 0 ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
RGB0 = RGB1;
|
||||
RGB1 = RGB2;
|
||||
CD2 = CODE;
|
||||
R2 = Lm_C1( MAC1 >> 4 );
|
||||
G2 = Lm_C2( MAC2 >> 4 );
|
||||
B2 = Lm_C3( MAC3 >> 4 );
|
||||
return 1;
|
||||
|
||||
case 0x14:
|
||||
|
||||
MAC1 = A1i( i44_add( i44_add( i44_add( i44( (INT64) RBK << 12 ), ( LR1 * IR1 ) ), ( LR2 * IR2 ) ), ( LR3 * IR3 ) ) );
|
||||
MAC2 = A2i( i44_add( i44_add( i44_add( i44( (INT64) GBK << 12 ), ( LG1 * IR1 ) ), ( LG2 * IR2 ) ), ( LG3 * IR3 ) ) );
|
||||
MAC3 = A3i( i44_add( i44_add( i44_add( i44( (INT64) BBK << 12 ), ( LB1 * IR1 ) ), ( LB2 * IR2 ) ), ( LB3 * IR3 ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
MAC1 = A1( ( ( R << 4 ) * IR1 ) + ( IR0 * Lm_B1( A1( ( (INT64) RFC << 12 ) - ( ( R << 4 ) * IR1 ) ), 0 ) ) );
|
||||
MAC2 = A2( ( ( G << 4 ) * IR2 ) + ( IR0 * Lm_B2( A2( ( (INT64) GFC << 12 ) - ( ( G << 4 ) * IR2 ) ), 0 ) ) );
|
||||
MAC3 = A3( ( ( B << 4 ) * IR3 ) + ( IR0 * Lm_B3( A3( ( (INT64) BFC << 12 ) - ( ( B << 4 ) * IR3 ) ), 0 ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
RGB0 = RGB1;
|
||||
RGB1 = RGB2;
|
||||
CD2 = CODE;
|
||||
R2 = Lm_C1( MAC1 >> 4 );
|
||||
G2 = Lm_C2( MAC2 >> 4 );
|
||||
B2 = Lm_C3( MAC3 >> 4 );
|
||||
return 1;
|
||||
|
||||
case 0x16:
|
||||
|
||||
for( v = 0; v < 3; v++ )
|
||||
{
|
||||
MAC1 = A1( (INT64) ( L11 * VX( v ) ) + ( L12 * VY( v ) ) + ( L13 * VZ( v ) ) );
|
||||
MAC2 = A2( (INT64) ( L21 * VX( v ) ) + ( L22 * VY( v ) ) + ( L23 * VZ( v ) ) );
|
||||
MAC3 = A3( (INT64) ( L31 * VX( v ) ) + ( L32 * VY( v ) ) + ( L33 * VZ( v ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
MAC1 = A1i( i44_add( i44_add( i44_add( i44( (INT64) RBK << 12 ), ( LR1 * IR1 ) ), ( LR2 * IR2 ) ), ( LR3 * IR3 ) ) );
|
||||
MAC2 = A2i( i44_add( i44_add( i44_add( i44( (INT64) GBK << 12 ), ( LG1 * IR1 ) ), ( LG2 * IR2 ) ), ( LG3 * IR3 ) ) );
|
||||
MAC3 = A3i( i44_add( i44_add( i44_add( i44( (INT64) BBK << 12 ), ( LB1 * IR1 ) ), ( LB2 * IR2 ) ), ( LB3 * IR3 ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
MAC1 = A1( ( ( R << 4 ) * IR1 ) + ( IR0 * Lm_B1( A1( ( (INT64) RFC << 12 ) - ( ( R << 4 ) * IR1 ) ), 0 ) ) );
|
||||
MAC2 = A2( ( ( G << 4 ) * IR2 ) + ( IR0 * Lm_B2( A2( ( (INT64) GFC << 12 ) - ( ( G << 4 ) * IR2 ) ), 0 ) ) );
|
||||
MAC3 = A3( ( ( B << 4 ) * IR3 ) + ( IR0 * Lm_B3( A3( ( (INT64) BFC << 12 ) - ( ( B << 4 ) * IR3 ) ), 0 ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
RGB0 = RGB1;
|
||||
RGB1 = RGB2;
|
||||
CD2 = CODE;
|
||||
R2 = Lm_C1( MAC1 >> 4 );
|
||||
G2 = Lm_C2( MAC2 >> 4 );
|
||||
B2 = Lm_C3( MAC3 >> 4 );
|
||||
}
|
||||
return 1;
|
||||
|
||||
case 0x1b:
|
||||
|
||||
MAC1 = A1( (INT64) ( L11 * VX0 ) + ( L12 * VY0 ) + ( L13 * VZ0 ) );
|
||||
MAC2 = A2( (INT64) ( L21 * VX0 ) + ( L22 * VY0 ) + ( L23 * VZ0 ) );
|
||||
MAC3 = A3( (INT64) ( L31 * VX0 ) + ( L32 * VY0 ) + ( L33 * VZ0 ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
MAC1 = A1i( i44_add( i44_add( i44_add( i44( (INT64) RBK << 12 ), ( LR1 * IR1 ) ), ( LR2 * IR2 ) ), ( LR3 * IR3 ) ) );
|
||||
MAC2 = A2i( i44_add( i44_add( i44_add( i44( (INT64) GBK << 12 ), ( LG1 * IR1 ) ), ( LG2 * IR2 ) ), ( LG3 * IR3 ) ) );
|
||||
MAC3 = A3i( i44_add( i44_add( i44_add( i44( (INT64) BBK << 12 ), ( LB1 * IR1 ) ), ( LB2 * IR2 ) ), ( LB3 * IR3 ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
MAC1 = A1( ( R << 4 ) * IR1 );
|
||||
MAC2 = A2( ( G << 4 ) * IR2 );
|
||||
MAC3 = A3( ( B << 4 ) * IR3 );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
RGB0 = RGB1;
|
||||
RGB1 = RGB2;
|
||||
CD2 = CODE;
|
||||
R2 = Lm_C1( MAC1 >> 4 );
|
||||
G2 = Lm_C2( MAC2 >> 4 );
|
||||
B2 = Lm_C3( MAC3 >> 4 );
|
||||
return 1;
|
||||
|
||||
case 0x1c:
|
||||
|
||||
MAC1 = A1i( i44_add( i44_add( i44_add( i44( ( (INT64) RBK ) << 12 ), ( LR1 * IR1 ) ), ( LR2 * IR2 ) ), ( LR3 * IR3 ) ) );
|
||||
MAC2 = A2i( i44_add( i44_add( i44_add( i44( ( (INT64) GBK ) << 12 ), ( LG1 * IR1 ) ), ( LG2 * IR2 ) ), ( LG3 * IR3 ) ) );
|
||||
MAC3 = A3i( i44_add( i44_add( i44_add( i44( ( (INT64) BBK ) << 12 ), ( LB1 * IR1 ) ), ( LB2 * IR2 ) ), ( LB3 * IR3 ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
MAC1 = A1( ( R << 4 ) * IR1 );
|
||||
MAC2 = A2( ( G << 4 ) * IR2 );
|
||||
MAC3 = A3( ( B << 4 ) * IR3 );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
RGB0 = RGB1;
|
||||
RGB1 = RGB2;
|
||||
CD2 = CODE;
|
||||
R2 = Lm_C1( MAC1 >> 4 );
|
||||
G2 = Lm_C2( MAC2 >> 4 );
|
||||
B2 = Lm_C3( MAC3 >> 4 );
|
||||
return 1;
|
||||
|
||||
case 0x1e:
|
||||
|
||||
MAC1 = A1( (INT64) ( L11 * VX0 ) + ( L12 * VY0 ) + ( L13 * VZ0 ) );
|
||||
MAC2 = A2( (INT64) ( L21 * VX0 ) + ( L22 * VY0 ) + ( L23 * VZ0 ) );
|
||||
MAC3 = A3( (INT64) ( L31 * VX0 ) + ( L32 * VY0 ) + ( L33 * VZ0 ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
MAC1 = A1i( i44_add( i44_add( i44_add( i44( (INT64) RBK << 12 ), ( LR1 * IR1 ) ), ( LR2 * IR2 ) ), ( LR3 * IR3 ) ) );
|
||||
MAC2 = A2i( i44_add( i44_add( i44_add( i44( (INT64) GBK << 12 ), ( LG1 * IR1 ) ), ( LG2 * IR2 ) ), ( LG3 * IR3 ) ) );
|
||||
MAC3 = A3i( i44_add( i44_add( i44_add( i44( (INT64) BBK << 12 ), ( LB1 * IR1 ) ), ( LB2 * IR2 ) ), ( LB3 * IR3 ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
RGB0 = RGB1;
|
||||
RGB1 = RGB2;
|
||||
CD2 = CODE;
|
||||
R2 = Lm_C1( MAC1 >> 4 );
|
||||
G2 = Lm_C2( MAC2 >> 4 );
|
||||
B2 = Lm_C3( MAC3 >> 4 );
|
||||
return 1;
|
||||
|
||||
case 0x20:
|
||||
|
||||
for( v = 0; v < 3; v++ )
|
||||
{
|
||||
MAC1 = A1( (INT64) ( L11 * VX( v ) ) + ( L12 * VY( v ) ) + ( L13 * VZ( v ) ) );
|
||||
MAC2 = A2( (INT64) ( L21 * VX( v ) ) + ( L22 * VY( v ) ) + ( L23 * VZ( v ) ) );
|
||||
MAC3 = A3( (INT64) ( L31 * VX( v ) ) + ( L32 * VY( v ) ) + ( L33 * VZ( v ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
MAC1 = A1i( i44_add( i44_add( i44_add( i44( (INT64) RBK << 12 ), ( LR1 * IR1 ) ), ( LR2 * IR2 ) ), ( LR3 * IR3 ) ) );
|
||||
MAC2 = A2i( i44_add( i44_add( i44_add( i44( (INT64) GBK << 12 ), ( LG1 * IR1 ) ), ( LG2 * IR2 ) ), ( LG3 * IR3 ) ) );
|
||||
MAC3 = A3i( i44_add( i44_add( i44_add( i44( (INT64) BBK << 12 ), ( LB1 * IR1 ) ), ( LB2 * IR2 ) ), ( LB3 * IR3 ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
RGB0 = RGB1;
|
||||
RGB1 = RGB2;
|
||||
CD2 = CODE;
|
||||
R2 = Lm_C1( MAC1 >> 4 );
|
||||
G2 = Lm_C2( MAC2 >> 4 );
|
||||
B2 = Lm_C3( MAC3 >> 4 );
|
||||
}
|
||||
return 1;
|
||||
|
||||
case 0x28:
|
||||
|
||||
MAC1 = A1( IR1 * IR1 );
|
||||
MAC2 = A2( IR2 * IR2 );
|
||||
MAC3 = A3( IR3 * IR3 );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
return 1;
|
||||
|
||||
case 0x1a: /* end of NCDT */
|
||||
case 0x29:
|
||||
|
||||
MAC1 = A1( ( ( R << 4 ) * IR1 ) + ( IR0 * Lm_B1( A1( ( (INT64) RFC << 12 ) - ( ( R << 4 ) * IR1 ) ), 0 ) ) );
|
||||
MAC2 = A2( ( ( G << 4 ) * IR2 ) + ( IR0 * Lm_B2( A2( ( (INT64) GFC << 12 ) - ( ( G << 4 ) * IR2 ) ), 0 ) ) );
|
||||
MAC3 = A3( ( ( B << 4 ) * IR3 ) + ( IR0 * Lm_B3( A3( ( (INT64) BFC << 12 ) - ( ( B << 4 ) * IR3 ) ), 0 ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
RGB0 = RGB1;
|
||||
RGB1 = RGB2;
|
||||
CD2 = CODE;
|
||||
R2 = Lm_C1( MAC1 >> 4 );
|
||||
G2 = Lm_C2( MAC2 >> 4 );
|
||||
B2 = Lm_C3( MAC3 >> 4 );
|
||||
return 1;
|
||||
|
||||
case 0x2a:
|
||||
|
||||
for( v = 0; v < 3; v++ )
|
||||
{
|
||||
MAC1 = A1( ( R0 << 16 ) + ( IR0 * Lm_B1( A1( ( (INT64) RFC << 12 ) - ( R0 << 16 ) ), 0 ) ) );
|
||||
MAC2 = A2( ( G0 << 16 ) + ( IR0 * Lm_B2( A2( ( (INT64) GFC << 12 ) - ( G0 << 16 ) ), 0 ) ) );
|
||||
MAC3 = A3( ( B0 << 16 ) + ( IR0 * Lm_B3( A3( ( (INT64) BFC << 12 ) - ( B0 << 16 ) ), 0 ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
RGB0 = RGB1;
|
||||
RGB1 = RGB2;
|
||||
CD2 = CODE;
|
||||
R2 = Lm_C1( MAC1 >> 4 );
|
||||
G2 = Lm_C2( MAC2 >> 4 );
|
||||
B2 = Lm_C3( MAC3 >> 4 );
|
||||
}
|
||||
return 1;
|
||||
|
||||
case 0x2d:
|
||||
|
||||
MAC0 = F( (INT64) ( ZSF3 * SZ1 ) + ( ZSF3 * SZ2 ) + ( ZSF3 * SZ3 ) );
|
||||
OTZ = Lm_D( m_mac0, 1 );
|
||||
return 1;
|
||||
|
||||
case 0x2e:
|
||||
|
||||
MAC0 = F( (INT64) ( ZSF4 * SZ0 ) + ( ZSF4 * SZ1 ) + ( ZSF4 * SZ2 ) + ( ZSF4 * SZ3 ) );
|
||||
OTZ = Lm_D( m_mac0, 1 );
|
||||
return 1;
|
||||
|
||||
case 0x30:
|
||||
|
||||
for( v = 0; v < 3; v++ )
|
||||
{
|
||||
MAC1 = A1i( i44_add( i44_add( i44_add( i44( (INT64) TRX << 12 ), ( R11 * VX( v ) ) ), ( R12 * VY( v ) ) ), ( R13 * VZ( v ) ) ) );
|
||||
MAC2 = A2i( i44_add( i44_add( i44_add( i44( (INT64) TRY << 12 ), ( R21 * VX( v ) ) ), ( R22 * VY( v ) ) ), ( R23 * VZ( v ) ) ) );
|
||||
MAC3 = A3i( i44_add( i44_add( i44_add( i44( (INT64) TRZ << 12 ), ( R31 * VX( v ) ) ), ( R32 * VY( v ) ) ), ( R33 * VZ( v ) ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3_sf( m_mac3, m_sf, lm );
|
||||
SZ0 = SZ1;
|
||||
SZ1 = SZ2;
|
||||
SZ2 = SZ3;
|
||||
SZ3 = Lm_D( m_mac3, 1 );
|
||||
h_over_sz3 = Lm_E( gte_divide( H, SZ3 ) );
|
||||
SXY0 = SXY1;
|
||||
SXY1 = SXY2;
|
||||
SX2 = Lm_G1( F( (INT64) OFX + ( (INT64) IR1 * h_over_sz3 ) ) >> 16 );
|
||||
SY2 = Lm_G2( F( (INT64) OFY + ( (INT64) IR2 * h_over_sz3 ) ) >> 16 );
|
||||
}
|
||||
|
||||
MAC0 = F( (INT64) DQB + ( (INT64) DQA * h_over_sz3 ) );
|
||||
IR0 = Lm_H( m_mac0, 1 );
|
||||
return 1;
|
||||
|
||||
case 0x3d:
|
||||
|
||||
MAC1 = A1( IR0 * IR1 );
|
||||
MAC2 = A2( IR0 * IR2 );
|
||||
MAC3 = A3( IR0 * IR3 );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
RGB0 = RGB1;
|
||||
RGB1 = RGB2;
|
||||
CD2 = CODE;
|
||||
R2 = Lm_C1( MAC1 >> 4 );
|
||||
G2 = Lm_C2( MAC2 >> 4 );
|
||||
B2 = Lm_C3( MAC3 >> 4 );
|
||||
return 1;
|
||||
|
||||
case 0x3e:
|
||||
|
||||
MAC1 = A1( gte_shift( MAC1, -m_sf ) + ( IR0 * IR1 ) );
|
||||
MAC2 = A2( gte_shift( MAC2, -m_sf ) + ( IR0 * IR2 ) );
|
||||
MAC3 = A3( gte_shift( MAC3, -m_sf ) + ( IR0 * IR3 ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
RGB0 = RGB1;
|
||||
RGB1 = RGB2;
|
||||
CD2 = CODE;
|
||||
R2 = Lm_C1( MAC1 >> 4 );
|
||||
G2 = Lm_C2( MAC2 >> 4 );
|
||||
B2 = Lm_C3( MAC3 >> 4 );
|
||||
return 1;
|
||||
|
||||
case 0x3f:
|
||||
|
||||
for( v = 0; v < 3; v++ )
|
||||
{
|
||||
MAC1 = A1( (INT64) ( L11 * VX( v ) ) + ( L12 * VY( v ) ) + ( L13 * VZ( v ) ) );
|
||||
MAC2 = A2( (INT64) ( L21 * VX( v ) ) + ( L22 * VY( v ) ) + ( L23 * VZ( v ) ) );
|
||||
MAC3 = A3( (INT64) ( L31 * VX( v ) ) + ( L32 * VY( v ) ) + ( L33 * VZ( v ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
MAC1 = A1i( i44_add( i44_add( i44_add( i44( (INT64) RBK << 12 ), ( LR1 * IR1 ) ), ( LR2 * IR2 ) ), ( LR3 * IR3 ) ) );
|
||||
MAC2 = A2i( i44_add( i44_add( i44_add( i44( (INT64) GBK << 12 ), ( LG1 * IR1 ) ), ( LG2 * IR2 ) ), ( LG3 * IR3 ) ) );
|
||||
MAC3 = A3i( i44_add( i44_add( i44_add( i44( (INT64) BBK << 12 ), ( LB1 * IR1 ) ), ( LB2 * IR2 ) ), ( LB3 * IR3 ) ) );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
MAC1 = A1( ( R << 4 ) * IR1 );
|
||||
MAC2 = A2( ( G << 4 ) * IR2 );
|
||||
MAC3 = A3( ( B << 4 ) * IR3 );
|
||||
IR1 = Lm_B1( MAC1, lm );
|
||||
IR2 = Lm_B2( MAC2, lm );
|
||||
IR3 = Lm_B3( MAC3, lm );
|
||||
RGB0 = RGB1;
|
||||
RGB1 = RGB2;
|
||||
CD2 = CODE;
|
||||
R2 = Lm_C1( MAC1 >> 4 );
|
||||
G2 = Lm_C2( MAC2 >> 4 );
|
||||
B2 = Lm_C3( MAC3 >> 4 );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,588 @@
|
||||
/***************************************************************************
|
||||
|
||||
psxloop.c
|
||||
|
||||
Exact skip of the PSX CPU's wait loops (included by psx_cpu.c).
|
||||
|
||||
Within a timeslice nothing but the CPU itself changes main RAM or the
|
||||
CPU state: interrupts, timers, DMA and the other CPUs only act between
|
||||
timeslices. A loop that waits for an interrupt therefore repeats the
|
||||
same work until the timeslice ends, and the whole passes that still fit
|
||||
can be done at once: registers, memory and cycles end up exactly as if
|
||||
they had run (one cycle per instruction, as the interpreter counts),
|
||||
and the last pass runs normally. Three kinds of loops are recognised:
|
||||
|
||||
LOOP_PURE a short loop of loads and register arithmetic, no stores, no
|
||||
other branch, where no register is read before the pass
|
||||
writes it: every pass leaves the same state (for example
|
||||
"lhu v0,x(v1); nop; beqz v0,loop"). The recompiler has its
|
||||
own version of this one (jit_is_idle_loop).
|
||||
LOOP_COUNT "b<cond> r,self" with "addiu r,r,-1" in the delay slot: a
|
||||
plain countdown.
|
||||
LOOP_VSYNC the wait in the PsyQ libraries' VSync(): a timeout counter on
|
||||
the stack, decremented and stored every pass, and a RAM word
|
||||
compared with a target (used by most System 11/12 games).
|
||||
LOOP_RNG the VBLANK wait of Tekken 3 / Tekken Tag Tournament: every pass
|
||||
steps two random number generators in RAM (x = 5x + 1 and
|
||||
x = (x + 1) * 69069) while a flag in RAM stays 0.
|
||||
|
||||
The loop's code is checked word by word every time before a skip, so
|
||||
a changed program is never skipped by mistake. Main RAM and the BIOS
|
||||
must be fast RAM (psxcpu_add_fastram) for any of this to apply; loads
|
||||
from anything else (I/O, shared RAM) are never skipped over.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#define LOOP_PURE 1
|
||||
#define LOOP_COUNT 2
|
||||
#define LOOP_VSYNC 3
|
||||
#define LOOP_RNG 4
|
||||
|
||||
/* build with -DPSX_LOOPSKIP=0 to compare against the plain interpreter */
|
||||
#ifndef PSX_LOOPSKIP
|
||||
#define PSX_LOOPSKIP 1
|
||||
#endif
|
||||
static int loopskip_enabled = PSX_LOOPSKIP;
|
||||
|
||||
/* a word of code or data in fast RAM, or 0 if it is not there */
|
||||
static int loop_word( UINT32 address, UINT32 *word )
|
||||
{
|
||||
struct psx_fastram *r = find_fastram( address, 4 );
|
||||
if( r == NULL || ( address & 3 ) != 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
*word = *(UINT32 *)&r->base[ address - r->start ];
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* host pointer of a writable RAM word away from translated code, or NULL */
|
||||
static UINT32 *loop_data( UINT32 address )
|
||||
{
|
||||
struct psx_fastram *r = find_fastram( address, 4 );
|
||||
UINT8 *host;
|
||||
if( r == NULL || r->readonly || ( address & 3 ) != 0 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
host = &r->base[ address - r->start ];
|
||||
#if PSXJIT_SUPPORTED
|
||||
if( jit_code_present && jit_codemap[ jit_codemap_index( host ) ] )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
return (UINT32 *)host;
|
||||
}
|
||||
|
||||
static UINT32 loop_branch_target( UINT32 op, UINT32 pc )
|
||||
{
|
||||
return pc + 4 + ( (INT32)(INT16)op << 2 );
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
* LOOP_PURE
|
||||
*************************************/
|
||||
|
||||
/* registers read and written by an allowed loop instruction; 0 if not allowed */
|
||||
static int loop_pure_op( UINT32 op, UINT32 *reads, UINT32 *writes, int *load )
|
||||
{
|
||||
UINT32 rs = INS_RS( op ), rt = INS_RT( op ), rd = INS_RD( op );
|
||||
|
||||
*reads = 0; *writes = 0; *load = 0;
|
||||
switch( INS_OP( op ) )
|
||||
{
|
||||
case 0x00: /* SPECIAL */
|
||||
switch( op & 63 )
|
||||
{
|
||||
case 0x00: case 0x02: case 0x03: /* SLL SRL SRA */
|
||||
*reads = 1 << rt; *writes = 1 << rd; return 1;
|
||||
case 0x04: case 0x06: case 0x07: /* SLLV SRLV SRAV */
|
||||
case 0x21: case 0x23: case 0x24: case 0x25: /* ADDU SUBU AND OR */
|
||||
case 0x26: case 0x27: case 0x2a: case 0x2b: /* XOR NOR SLT SLTU */
|
||||
*reads = ( 1 << rs ) | ( 1 << rt ); *writes = 1 << rd; return 1;
|
||||
}
|
||||
return 0;
|
||||
case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: /* ADDIU SLTI SLTIU ANDI ORI XORI */
|
||||
*reads = 1 << rs; *writes = 1 << rt; return 1;
|
||||
case 0x0f: /* LUI */
|
||||
*writes = 1 << rt; return 1;
|
||||
case 0x20: case 0x21: case 0x23: case 0x24: case 0x25: /* LB LH LW LBU LHU */
|
||||
*reads = 1 << rs; *writes = 1 << rt; *load = 1; return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* registers read by the closing branch, or -1 if 'op' is not a usable branch to 'target' */
|
||||
static int loop_pure_branch( UINT32 op, UINT32 pc, UINT32 target, UINT32 *reads )
|
||||
{
|
||||
UINT32 rs = INS_RS( op ), rt = INS_RT( op );
|
||||
switch( INS_OP( op ) )
|
||||
{
|
||||
case 0x01: /* BLTZ BGEZ */
|
||||
if( rt != 0x00 && rt != 0x01 ) return -1;
|
||||
*reads = 1 << rs;
|
||||
break;
|
||||
case 0x04: case 0x05: /* BEQ BNE */
|
||||
*reads = ( 1 << rs ) | ( 1 << rt );
|
||||
break;
|
||||
case 0x06: case 0x07: /* BLEZ BGTZ */
|
||||
if( rt != 0 ) return -1;
|
||||
*reads = 1 << rs;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return loop_branch_target( op, pc ) == target ? 0 : -1;
|
||||
}
|
||||
|
||||
/*
|
||||
The loop at 'l' as LOOP_PURE: the branch closing it in *branch, or 0.
|
||||
Same rules as the recompiler's jit_is_idle_loop, plus no instruction
|
||||
may use a register loaded by the one before it (the load delay would
|
||||
make it see the previous pass's value).
|
||||
*/
|
||||
static int loop_is_pure( UINT32 l, UINT32 *branch )
|
||||
{
|
||||
UINT32 ops[ 18 ], reads[ 18 ], writes[ 18 ], all = 0, written = 0, b;
|
||||
int load[ 18 ], n, i, found = -1;
|
||||
|
||||
for( n = 0; n < 16; n++ )
|
||||
{
|
||||
UINT32 r;
|
||||
if( !loop_word( l + n * 4, &ops[ n ] ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if( loop_pure_branch( ops[ n ], l + n * 4, l, &r ) == 0 )
|
||||
{
|
||||
found = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( found < 0 || !loop_word( l + ( found + 1 ) * 4, &ops[ found + 1 ] ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
b = l + found * 4;
|
||||
for( i = 0; i <= found + 1; i++ )
|
||||
{
|
||||
if( i == found )
|
||||
{
|
||||
loop_pure_branch( ops[ i ], b, l, &reads[ i ] );
|
||||
writes[ i ] = 0;
|
||||
load[ i ] = 0;
|
||||
}
|
||||
else if( !loop_pure_op( ops[ i ], &reads[ i ], &writes[ i ], &load[ i ] ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
all |= writes[ i ];
|
||||
}
|
||||
for( i = 0; i <= found + 1; i++ )
|
||||
{
|
||||
if( reads[ i ] & all & ~written & ~1 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if( i > 0 && load[ i - 1 ] && ( reads[ i ] & writes[ i - 1 ] & ~1 ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
written |= writes[ i ];
|
||||
}
|
||||
/* the slot's load must not reach into the next pass */
|
||||
if( load[ found + 1 ] )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
*branch = b;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
* LOOP_COUNT
|
||||
*************************************/
|
||||
|
||||
/* "b<cond> r,self" + "addiu r,r,-1": the register, or -1 */
|
||||
static int loop_is_count( UINT32 l )
|
||||
{
|
||||
UINT32 op, slot, r;
|
||||
if( !loop_word( l, &op ) || !loop_word( l + 4, &slot ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if( loop_branch_target( op, l ) != l )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
r = INS_RS( op );
|
||||
if( r == 0 || slot != ( 0x24000000 | ( r << 21 ) | ( r << 16 ) | 0xffff ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if( ( INS_OP( op ) == 0x01 && INS_RT( op ) == 0x01 ) || /* BGEZ */
|
||||
( INS_OP( op ) == 0x07 && INS_RT( op ) == 0x00 ) || /* BGTZ */
|
||||
( INS_OP( op ) == 0x05 && INS_RT( op ) == 0x00 ) ) /* BNE r,zero */
|
||||
{
|
||||
return (int)r;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
* LOOP_VSYNC
|
||||
*************************************/
|
||||
|
||||
/*
|
||||
L+0 lw v0,16(sp) X+0 lui v0,hi
|
||||
L+1 nop X+1 lw v0,lo(v0)
|
||||
L+2 addiu v0,v0,-1 X+2 nop
|
||||
L+3 sw v0,16(sp) X+3 slt v0,v0,a0
|
||||
L+4 lw v0,16(sp) X+4 bnez v0,L
|
||||
L+5 nop X+5 nop
|
||||
L+6 bne v0,v1,X
|
||||
L+7 nop
|
||||
One pass is 14 instructions; the RAM word at hi:lo is in *global.
|
||||
*/
|
||||
static int loop_is_vsync( UINT32 l, UINT32 *global )
|
||||
{
|
||||
static const UINT32 head[ 8 ] = { 0x8fa20010, 0, 0x2442ffff, 0xafa20010, 0x8fa20010, 0, 0, 0 };
|
||||
UINT32 w[ 8 ], x, lui, lw, i;
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
if( !loop_word( l + i * 4, &w[ i ] ) || ( i != 6 && w[ i ] != head[ i ] ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if( ( w[ 6 ] & 0xffff0000 ) != 0x14430000 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
x = loop_branch_target( w[ 6 ], l + 24 );
|
||||
if( x <= l + 28 || x - l > 64 * 4 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if( !loop_word( x, &lui ) || ( lui & 0xffff0000 ) != 0x3c020000 ||
|
||||
!loop_word( x + 4, &lw ) || ( lw & 0xffff0000 ) != 0x8c420000 ||
|
||||
!loop_word( x + 8, &w[ 0 ] ) || w[ 0 ] != 0 ||
|
||||
!loop_word( x + 12, &w[ 1 ] ) || w[ 1 ] != 0x0044102a ||
|
||||
!loop_word( x + 16, &w[ 2 ] ) || ( w[ 2 ] & 0xffff0000 ) != 0x14400000 || loop_branch_target( w[ 2 ], x + 16 ) != l ||
|
||||
!loop_word( x + 20, &w[ 3 ] ) || w[ 3 ] != 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
*global = ( ( lui & 0xffff ) << 16 ) + (INT32)(INT16)lw;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
* LOOP_RNG
|
||||
*************************************/
|
||||
|
||||
/*
|
||||
L+0 jal F F+0 lw v1,o1(gp)
|
||||
L+1 nop F+1 nop
|
||||
L+2 lui v1,h2 F+2 sll v0,v1,2
|
||||
L+3 lw v1,o2(v1) F+3 addu v0,v0,v1
|
||||
L+4 lw a0,o3(gp) F+4 addiu v0,v0,1
|
||||
L+5 addiu v1,v1,1 F+5 sw v0,o1(gp)
|
||||
L+6.. v0 = v1 * 69069 F+6 jr ra
|
||||
L+16 lui at,h2 F+7 nop
|
||||
L+17 sw v0,o2(at)
|
||||
L+18 beqz a0,L
|
||||
L+19 lui v0,slot
|
||||
One pass is 28 instructions.
|
||||
*/
|
||||
static const UINT32 loop_rng_mul[ 10 ] =
|
||||
{
|
||||
0x00031140, 0x00431021, 0x00021080, 0x00431023, 0x00021080,
|
||||
0x00431023, 0x00021080, 0x00431021, 0x00021940, 0x00431021
|
||||
};
|
||||
|
||||
struct loop_rng
|
||||
{
|
||||
UINT32 x1, x2, flag; /* addresses: generator 1 (5x + 1), generator 2, flag */
|
||||
UINT32 at, v0; /* the values left in at and v0 */
|
||||
};
|
||||
|
||||
static int loop_is_rng( UINT32 l, struct loop_rng *g )
|
||||
{
|
||||
UINT32 w[ 20 ], f[ 8 ], fa, i, gp = mipscpu.r[ 28 ];
|
||||
|
||||
for( i = 0; i < 20; i++ )
|
||||
{
|
||||
if( !loop_word( l + i * 4, &w[ i ] ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if( INS_OP( w[ 0 ] ) != 0x03 || w[ 1 ] != 0 ||
|
||||
( w[ 2 ] & 0xffff0000 ) != 0x3c030000 || ( w[ 3 ] & 0xffff0000 ) != 0x8c630000 ||
|
||||
( w[ 4 ] & 0xffff0000 ) != 0x8f840000 || w[ 5 ] != 0x24630001 ||
|
||||
( w[ 16 ] & 0xffff0000 ) != 0x3c010000 || ( w[ 16 ] & 0xffff ) != ( w[ 2 ] & 0xffff ) ||
|
||||
( w[ 17 ] & 0xffff0000 ) != 0xac220000 || ( w[ 17 ] & 0xffff ) != ( w[ 3 ] & 0xffff ) ||
|
||||
( w[ 18 ] & 0xffff0000 ) != 0x10800000 || loop_branch_target( w[ 18 ], l + 72 ) != l ||
|
||||
( w[ 19 ] & 0xffff0000 ) != 0x3c020000 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
for( i = 0; i < 10; i++ )
|
||||
{
|
||||
if( w[ 6 + i ] != loop_rng_mul[ i ] )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fa = ( ( l + 4 ) & 0xf0000000 ) | ( ( w[ 0 ] & 0x03ffffff ) << 2 );
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
if( !loop_word( fa + i * 4, &f[ i ] ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if( ( f[ 0 ] & 0xffff0000 ) != 0x8f830000 || f[ 1 ] != 0 || f[ 2 ] != 0x00031080 || f[ 3 ] != 0x00431021 ||
|
||||
f[ 4 ] != 0x24420001 || ( f[ 5 ] & 0xffff0000 ) != 0xaf820000 || ( f[ 5 ] & 0xffff ) != ( f[ 0 ] & 0xffff ) ||
|
||||
f[ 6 ] != 0x03e00008 || f[ 7 ] != 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
g->x1 = gp + (INT32)(INT16)f[ 0 ];
|
||||
g->x2 = ( ( w[ 2 ] & 0xffff ) << 16 ) + (INT32)(INT16)w[ 3 ];
|
||||
g->flag = gp + (INT32)(INT16)w[ 4 ];
|
||||
g->at = ( w[ 16 ] & 0xffff ) << 16;
|
||||
g->v0 = ( w[ 19 ] & 0xffff ) << 16;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
* Skipping
|
||||
*************************************/
|
||||
|
||||
/* whole passes of 'pass' cycles that fit, leaving between 1 and 'pass' cycles */
|
||||
static INLINE UINT32 loop_passes( UINT32 pass )
|
||||
{
|
||||
if( mips_ICount <= (int)pass )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return ( (UINT32)mips_ICount - 1 ) / pass;
|
||||
}
|
||||
|
||||
static int loop_state_ok( void )
|
||||
{
|
||||
return loopskip_enabled && mipscpu.delayr == 0 && ( mipscpu.cp0r[ CP0_SR ] & ( SR_ISC | SR_KUC ) ) == 0;
|
||||
}
|
||||
|
||||
/* LOOP_COUNT, LOOP_VSYNC and LOOP_RNG at 'l' (the start of a pass) */
|
||||
static void loop_skip_at( UINT32 l )
|
||||
{
|
||||
UINT32 n, global;
|
||||
int r;
|
||||
struct loop_rng g;
|
||||
|
||||
if( !loop_state_ok() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( ( r = loop_is_count( l ) ) > 0 )
|
||||
{
|
||||
/* passes still taking the branch, counting the one starting now */
|
||||
UINT32 op = 0, v = mipscpu.r[ r ], left;
|
||||
loop_word( l, &op );
|
||||
if( INS_OP( op ) == 0x01 ) /* BGEZ: while v >= 0 */
|
||||
left = (INT32)v >= 0 ? v + 1 : 0;
|
||||
else /* BGTZ, BNE zero: while v > 0 */
|
||||
left = (INT32)v > 0 ? v : 0;
|
||||
n = loop_passes( 2 );
|
||||
if( left < 1 )
|
||||
return;
|
||||
if( n > left - 1 )
|
||||
n = left - 1;
|
||||
if( n == 0 )
|
||||
return;
|
||||
mipscpu.r[ r ] = v - n;
|
||||
mips_ICount -= n * 2;
|
||||
return;
|
||||
}
|
||||
|
||||
if( loop_is_vsync( l, &global ) )
|
||||
{
|
||||
UINT32 *counter = loop_data( mipscpu.r[ 29 ] + 16 ), value, until;
|
||||
if( counter == NULL || !loop_word( global, &value ) || global == mipscpu.r[ 29 ] + 16 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
/* the RAM word must keep the loop going */
|
||||
if( !( (INT32)value < (INT32)mipscpu.r[ 4 ] ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
/* passes before the counter reaches v1 (the timeout), that pass not included */
|
||||
until = *counter - mipscpu.r[ 3 ];
|
||||
n = loop_passes( 14 );
|
||||
if( until != 0 && n > until - 1 )
|
||||
{
|
||||
n = until - 1;
|
||||
}
|
||||
if( n == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
*counter -= n;
|
||||
mipscpu.r[ 2 ] = 1;
|
||||
mips_ICount -= n * 14;
|
||||
return;
|
||||
}
|
||||
|
||||
if( loop_is_rng( l, &g ) )
|
||||
{
|
||||
UINT32 *x1 = loop_data( g.x1 ), *x2 = loop_data( g.x2 ), flag, a, b, k, last = 0;
|
||||
if( x1 == NULL || x2 == NULL || !loop_word( g.flag, &flag ) || flag != 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
/* the three words must be distinct, so the stores leave the flag alone */
|
||||
if( g.x1 == g.x2 || g.flag == g.x1 || g.flag == g.x2 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
n = loop_passes( 28 );
|
||||
if( n == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
a = *x1;
|
||||
b = *x2;
|
||||
for( k = 0; k < n; k++ )
|
||||
{
|
||||
a = a * 5 + 1;
|
||||
last = b;
|
||||
b = ( b + 1 ) * 69069;
|
||||
}
|
||||
*x1 = a;
|
||||
*x2 = b;
|
||||
mipscpu.r[ 1 ] = g.at;
|
||||
mipscpu.r[ 2 ] = g.v0;
|
||||
mipscpu.r[ 3 ] = last + 1;
|
||||
mipscpu.r[ 4 ] = 0;
|
||||
mipscpu.r[ 31 ] = l + 8;
|
||||
mips_ICount -= n * 28;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* the kind of loop starting at 'l', for the recompiler (LOOP_PURE is not reported) */
|
||||
static int loop_kind( UINT32 l )
|
||||
{
|
||||
UINT32 global;
|
||||
struct loop_rng g;
|
||||
if( !loopskip_enabled )
|
||||
{
|
||||
return LOOP_NONE;
|
||||
}
|
||||
if( loop_is_count( l ) > 0 )
|
||||
{
|
||||
return LOOP_COUNT;
|
||||
}
|
||||
if( loop_is_vsync( l, &global ) )
|
||||
{
|
||||
return LOOP_VSYNC;
|
||||
}
|
||||
if( loop_is_rng( l, &g ) )
|
||||
{
|
||||
return LOOP_RNG;
|
||||
}
|
||||
return LOOP_NONE;
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
* Interpreter hook
|
||||
*************************************/
|
||||
|
||||
/*
|
||||
Called by the interpreter when the PC moves back to 'l' (a taken
|
||||
backward branch or jump) from the instruction at 'from'. LOOP_PURE
|
||||
needs one whole pass seen first: from the previous arrival at 'l' to
|
||||
the loop's own branch, touching nothing but fast RAM (psx_slow_access).
|
||||
*/
|
||||
#define LOOP_CACHE_SIZE 1024
|
||||
|
||||
static struct
|
||||
{
|
||||
UINT32 pc, op, branch;
|
||||
UINT8 kind;
|
||||
} loop_cache[ LOOP_CACHE_SIZE ];
|
||||
|
||||
static UINT32 loop_pure_pc;
|
||||
|
||||
static void loop_arrive( UINT32 l, UINT32 from )
|
||||
{
|
||||
UINT32 op, idx = ( l >> 2 ) & ( LOOP_CACHE_SIZE - 1 );
|
||||
int armed = loop_pure_armed && loop_pure_pc == l && !psx_slow_access;
|
||||
|
||||
loop_pure_armed = 0;
|
||||
if( !loop_word( l, &op ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if( loop_cache[ idx ].pc != l || loop_cache[ idx ].op != op )
|
||||
{
|
||||
UINT32 branch;
|
||||
loop_cache[ idx ].pc = l;
|
||||
loop_cache[ idx ].op = op;
|
||||
loop_cache[ idx ].kind = loop_is_pure( l, &branch ) ? LOOP_PURE : LOOP_NONE;
|
||||
loop_cache[ idx ].branch = branch;
|
||||
if( loop_cache[ idx ].kind == LOOP_NONE )
|
||||
{
|
||||
/* the other kinds are told by their first words */
|
||||
UINT32 global;
|
||||
struct loop_rng g;
|
||||
if( loop_is_count( l ) > 0 || loop_is_vsync( l, &global ) || loop_is_rng( l, &g ) )
|
||||
{
|
||||
loop_cache[ idx ].kind = LOOP_COUNT; /* "one of the checked kinds" */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch( loop_cache[ idx ].kind )
|
||||
{
|
||||
case LOOP_PURE:
|
||||
{
|
||||
UINT32 branch;
|
||||
/* a whole pass ran since the last arrival: back here from the slot of the loop's own branch */
|
||||
if( armed && from == loop_cache[ idx ].branch + 4 && loop_state_ok() &&
|
||||
loop_is_pure( l, &branch ) && branch == loop_cache[ idx ].branch )
|
||||
{
|
||||
UINT32 pass = ( branch + 8 - l ) / 4;
|
||||
mips_ICount -= loop_passes( pass ) * pass;
|
||||
}
|
||||
loop_pure_pc = l;
|
||||
loop_pure_armed = 1;
|
||||
psx_slow_access = 0;
|
||||
}
|
||||
break;
|
||||
case LOOP_COUNT:
|
||||
loop_skip_at( l );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* recompiled code: the skip at a loop head inside a block */
|
||||
#if PSXJIT_SUPPORTED
|
||||
static void SLJIT_FUNC loop_skip_helper( sljit_u32 l )
|
||||
{
|
||||
loop_skip_at( l );
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,67 @@
|
||||
/***************************************************************************
|
||||
|
||||
mn10200.h : Panasonic MN10200 (MN1020012A) emulator
|
||||
|
||||
Backported to the MAME 0.78 CPU interface (mame2003-plus) from current
|
||||
MAME (Olivier Galibert, R. Belmont, hap). The on-chip peripherals
|
||||
(interrupt controller, 8-bit timers, ports) are at 0xfc00-0xffff and
|
||||
handled inside the core; the four ports go to the driver through the
|
||||
callbacks below.
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _MN10200_H_
|
||||
#define _MN10200_H_
|
||||
|
||||
#include "osd_cpu.h"
|
||||
|
||||
enum
|
||||
{
|
||||
MN10200_PC = 1,
|
||||
MN10200_PSW,
|
||||
MN10200_MDR,
|
||||
MN10200_D0,
|
||||
MN10200_D1,
|
||||
MN10200_D2,
|
||||
MN10200_D3,
|
||||
MN10200_A0,
|
||||
MN10200_A1,
|
||||
MN10200_A2,
|
||||
MN10200_A3,
|
||||
MN10200_NMICR,
|
||||
MN10200_IAGR
|
||||
};
|
||||
|
||||
/* external interrupt pins */
|
||||
enum
|
||||
{
|
||||
MN10200_IRQ0 = 0,
|
||||
MN10200_IRQ1,
|
||||
MN10200_IRQ2,
|
||||
MN10200_IRQ3,
|
||||
|
||||
MN10200_MAX_EXT_IRQ
|
||||
};
|
||||
|
||||
typedef data8_t (*mn10200_port_read_func)(int port);
|
||||
typedef void (*mn10200_port_write_func)(int port, data8_t data);
|
||||
|
||||
/* hook the ports 0-3 to the driver (call before reset; NULL: open bus) */
|
||||
void mn10200_set_port_handlers(mn10200_port_read_func readfn, mn10200_port_write_func writefn);
|
||||
|
||||
extern int mn10200_ICount;
|
||||
|
||||
void mn10200_init(void);
|
||||
void mn10200_reset(void *param);
|
||||
void mn10200_exit(void);
|
||||
int mn10200_execute(int cycles);
|
||||
unsigned mn10200_get_context(void *dst);
|
||||
void mn10200_set_context(void *src);
|
||||
unsigned mn10200_get_reg(int regnum);
|
||||
void mn10200_set_reg(int regnum, unsigned val);
|
||||
void mn10200_set_irq_line(int irqline, int state);
|
||||
void mn10200_set_irq_callback(int (*callback)(int irqline));
|
||||
const char *mn10200_info(void *context, int regnum);
|
||||
unsigned mn10200_dasm(char *buffer, unsigned pc);
|
||||
|
||||
#endif
|
||||
+54
-33
@@ -145,6 +145,8 @@ typedef struct
|
||||
int dma_timer_active[2];
|
||||
|
||||
int is_slave, cpu_number;
|
||||
data16_t (*opcode_read)(offs_t pc);
|
||||
data32_t (*dma_read_hook)(UINT32 src, UINT32 dst, data32_t data, int size);
|
||||
} SH2;
|
||||
|
||||
int sh2_icount;
|
||||
@@ -152,8 +154,8 @@ static SH2 sh2;
|
||||
|
||||
/* Atrocious hack that makes the soldivid music correct*/
|
||||
|
||||
/*static const int div_tab[4] = { 3, 5, 7, 0 };*/
|
||||
static const int div_tab[4] = { 3, 5, 3, 0 };
|
||||
/* FRT clock: internal clock / 8, / 32, / 128, external */
|
||||
static const int div_tab[4] = { 3, 5, 7, 0 };
|
||||
|
||||
enum {
|
||||
ICF = 0x00800000,
|
||||
@@ -1143,22 +1145,20 @@ static INLINE void MAC_L(UINT32 m, UINT32 n)
|
||||
}
|
||||
if (sh2.sr & S)
|
||||
{
|
||||
Res0 = sh2.macl + Res0;
|
||||
if (sh2.macl > Res0)
|
||||
Res2++;
|
||||
Res2 += (sh2.mach & 0x0000ffff);
|
||||
if (((INT32) Res2 < 0) && (Res2 < 0xffff8000))
|
||||
/* full 64-bit accumulate, saturated to the 48-bit range with the sign of the product (as MAME) */
|
||||
UINT64 sum = ((((UINT64)sh2.mach) << 32) | sh2.macl) + ((((UINT64)Res2) << 32) | Res0);
|
||||
UINT32 sum_hi = (UINT32)(sum >> 32);
|
||||
|
||||
/* outside 0xffff800000000000 .. 0x00007fffffffffff */
|
||||
if (sum_hi > 0x00007fff && sum_hi < 0xffff8000)
|
||||
{
|
||||
Res2 = 0x00008000;
|
||||
Res0 = 0x00000000;
|
||||
if (fnLmL < 0)
|
||||
sum = ((UINT64)0xffff8000) << 32;
|
||||
else
|
||||
sum = (((UINT64)0x00007fff) << 32) | 0xffffffff;
|
||||
}
|
||||
else if (((INT32) Res2 > 0) && (Res2 > 0x00007fff))
|
||||
{
|
||||
Res2 = 0x00007fff;
|
||||
Res0 = 0xffffffff;
|
||||
}
|
||||
sh2.mach = Res2;
|
||||
sh2.macl = Res0;
|
||||
sh2.mach = (UINT32)(sum >> 32);
|
||||
sh2.macl = (UINT32)sum;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1208,12 +1208,19 @@ static INLINE void MAC_W(UINT32 m, UINT32 n)
|
||||
if (sh2.sr & S)
|
||||
{
|
||||
if (ans == 1)
|
||||
{
|
||||
/* both addends with the same sign: the sign change is an overflow */
|
||||
if (src == 0)
|
||||
{
|
||||
if (src == 0)
|
||||
sh2.macl = 0x7fffffff;
|
||||
if (src == 2)
|
||||
sh2.macl = 0x80000000;
|
||||
sh2.macl = 0x7fffffff;
|
||||
sh2.mach |= 1;
|
||||
}
|
||||
else if (src == 2)
|
||||
{
|
||||
sh2.macl = 0x80000000;
|
||||
sh2.mach |= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2307,7 +2314,11 @@ void sh2_reset(void *param)
|
||||
memset(sh2.m, 0, 0x200);
|
||||
|
||||
if(conf)
|
||||
{
|
||||
sh2.is_slave = conf->is_slave;
|
||||
sh2.opcode_read = conf->opcode_read;
|
||||
sh2.dma_read_hook = conf->dma_read_hook;
|
||||
}
|
||||
else
|
||||
sh2.is_slave = 0;
|
||||
|
||||
@@ -2343,12 +2354,12 @@ int sh2_execute(int cycles)
|
||||
|
||||
if (sh2.delay)
|
||||
{
|
||||
opcode = RW(sh2.delay & AM);
|
||||
opcode = sh2.opcode_read ? sh2.opcode_read(sh2.delay) : RW(sh2.delay & AM);
|
||||
change_pc32bedw(sh2.pc & AM);
|
||||
sh2.pc -= 2;
|
||||
}
|
||||
else
|
||||
opcode = RW(sh2.pc & AM);
|
||||
opcode = sh2.opcode_read ? sh2.opcode_read(sh2.pc) : RW(sh2.pc & AM);
|
||||
|
||||
CALL_MAME_DEBUG;
|
||||
|
||||
@@ -2407,9 +2418,15 @@ static void sh2_timer_resync(void)
|
||||
int divider = div_tab[(sh2.m[5] >> 8) & 3];
|
||||
UINT32 cur_time = cpunum_gettotalcycles(sh2.cpu_number);
|
||||
|
||||
if(divider)
|
||||
sh2.frc += (cur_time - sh2.frc_base) >> divider;
|
||||
sh2.frc_base = cur_time;
|
||||
UINT32 add = (cur_time - sh2.frc_base) >> divider;
|
||||
|
||||
/* keep the cycles that don't make a whole count yet (as MAME) */
|
||||
if (add > 0)
|
||||
{
|
||||
if (divider)
|
||||
sh2.frc += add;
|
||||
sh2.frc_base = cur_time;
|
||||
}
|
||||
}
|
||||
|
||||
static void sh2_timer_activate(void)
|
||||
@@ -2536,6 +2553,10 @@ static void sh2_dmac_callback(int dma)
|
||||
cpuintrf_pop_context();
|
||||
}
|
||||
|
||||
/* a unit read by the internal DMA, through the optional hook */
|
||||
#define DMA_READ(src, dst, data, size) \
|
||||
(sh2.dma_read_hook ? sh2.dma_read_hook((src), (dst), (data), (size)) : (data))
|
||||
|
||||
static void sh2_dmac_check(int dma)
|
||||
{
|
||||
if(sh2.m[0x63+4*dma] & sh2.m[0x6c] & 1)
|
||||
@@ -2575,7 +2596,7 @@ static void sh2_dmac_check(int dma)
|
||||
src --;
|
||||
if(incd == 2)
|
||||
dst --;
|
||||
cpu_writemem32bedw(dst, cpu_readmem32bedw(src));
|
||||
cpu_writemem32bedw(dst, DMA_READ(src, dst, cpu_readmem32bedw(src), 0));
|
||||
if(incs == 1)
|
||||
src ++;
|
||||
if(incd == 1)
|
||||
@@ -2591,7 +2612,7 @@ static void sh2_dmac_check(int dma)
|
||||
src -= 2;
|
||||
if(incd == 2)
|
||||
dst -= 2;
|
||||
cpu_writemem32bedw_word(dst, cpu_readmem32bedw_word(src));
|
||||
cpu_writemem32bedw_word(dst, DMA_READ(src, dst, cpu_readmem32bedw_word(src), 1));
|
||||
if(incs == 1)
|
||||
src += 2;
|
||||
if(incd == 1)
|
||||
@@ -2607,7 +2628,7 @@ static void sh2_dmac_check(int dma)
|
||||
src -= 4;
|
||||
if(incd == 2)
|
||||
dst -= 4;
|
||||
cpu_writemem32bedw_dword(dst, cpu_readmem32bedw_dword(src));
|
||||
cpu_writemem32bedw_dword(dst, DMA_READ(src, dst, cpu_readmem32bedw_dword(src), 2));
|
||||
if(incs == 1)
|
||||
src += 4;
|
||||
if(incd == 1)
|
||||
@@ -2622,10 +2643,10 @@ static void sh2_dmac_check(int dma)
|
||||
{
|
||||
if(incd == 2)
|
||||
dst -= 16;
|
||||
cpu_writemem32bedw_dword(dst, cpu_readmem32bedw_dword(src));
|
||||
cpu_writemem32bedw_dword(dst+4, cpu_readmem32bedw_dword(src+4));
|
||||
cpu_writemem32bedw_dword(dst+8, cpu_readmem32bedw_dword(src+8));
|
||||
cpu_writemem32bedw_dword(dst+12, cpu_readmem32bedw_dword(src+12));
|
||||
cpu_writemem32bedw_dword(dst, DMA_READ(src, dst, cpu_readmem32bedw_dword(src), 2));
|
||||
cpu_writemem32bedw_dword(dst+4, DMA_READ(src+4, dst+4, cpu_readmem32bedw_dword(src+4), 2));
|
||||
cpu_writemem32bedw_dword(dst+8, DMA_READ(src+8, dst+8, cpu_readmem32bedw_dword(src+8), 2));
|
||||
cpu_writemem32bedw_dword(dst+12, DMA_READ(src+12, dst+12, cpu_readmem32bedw_dword(src+12), 2));
|
||||
src += 16;
|
||||
if(incd == 1)
|
||||
dst += 16;
|
||||
@@ -2739,7 +2760,7 @@ WRITE32_HANDLER( sh2_internal_w )
|
||||
{
|
||||
INT64 a = sh2.m[0x45] | ((UINT64)(sh2.m[0x44]) << 32);
|
||||
INT64 b = sh2.m[0x40];
|
||||
log_cb(RETRO_LOG_DEBUG, LOGPRE "SH2 #%d div+mod %lld/%lld\n", cpu_getactivecpu(), a, b);
|
||||
log_cb(RETRO_LOG_DEBUG, LOGPRE "SH2 #%d div+mod %08x%08x/%08x\n", cpu_getactivecpu(), sh2.m[0x44], sh2.m[0x45], sh2.m[0x40]);
|
||||
if (b)
|
||||
{
|
||||
INT64 q = a / b;
|
||||
|
||||
@@ -60,6 +60,13 @@ extern int sh2_icount; /* cycle count */
|
||||
struct sh2_config
|
||||
{
|
||||
int is_slave;
|
||||
/* optional: opcode fetch, for CPUs that decrypt opcodes (CPS-3);
|
||||
NULL fetches opcodes as data */
|
||||
data16_t (*opcode_read)(offs_t pc);
|
||||
/* optional: called for each unit an internal DMA transfer reads, can
|
||||
change the data (CPS-3: the DMA bypasses the decryption);
|
||||
size 0 byte, 1 word, 2 long */
|
||||
data32_t (*dma_read_hook)(UINT32 src, UINT32 dst, data32_t data, int size);
|
||||
};
|
||||
|
||||
extern void sh2_init(void);
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,98 @@
|
||||
/***************************************************************************
|
||||
|
||||
Analog Devices ADSP-21062 "SHARC", from current MAME
|
||||
(src/devices/cpu/sharc, copyright Ville Linde, BSD-3-Clause),
|
||||
translated to C for MAME 2003. Interpreter only (no recompiler).
|
||||
|
||||
The internal memory (two 32K x 32-bit blocks, with the 48-bit program
|
||||
and 16-bit short-word views) and the IOP registers live inside the
|
||||
core. External data memory (and external program memory, if any)
|
||||
is reached through driver callbacks in the config passed to the CPU
|
||||
with MDRV_CPU_CONFIG; the mame2003 memory system is not used.
|
||||
|
||||
Only one SHARC per machine is supported (the state is static).
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef SHARC_H
|
||||
#define SHARC_H
|
||||
|
||||
#include "osd_cpu.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SHARC_BOOT_MODE_EPROM = 0,
|
||||
SHARC_BOOT_MODE_HOST,
|
||||
SHARC_BOOT_MODE_LINK,
|
||||
SHARC_BOOT_MODE_NOBOOT
|
||||
};
|
||||
|
||||
/* interrupt lines for set_irq_line (IRQ0-2 pins) */
|
||||
enum
|
||||
{
|
||||
SHARC_IRQ0 = 0,
|
||||
SHARC_IRQ1 = 1,
|
||||
SHARC_IRQ2 = 2
|
||||
};
|
||||
|
||||
/* register numbers for get_reg / set_reg (also CPU_INFO_REG + n) */
|
||||
enum
|
||||
{
|
||||
SHARC_PC = 1, SHARC_PCSTK, SHARC_PCSTKP, SHARC_LSTKP, SHARC_FADDR, SHARC_DADDR,
|
||||
SHARC_MODE1, SHARC_MODE2, SHARC_ASTAT, SHARC_STKY, SHARC_IRPTL, SHARC_IMASK,
|
||||
SHARC_USTAT1, SHARC_USTAT2, SHARC_LCNTR, SHARC_CURLCNTR, SHARC_STSTKP,
|
||||
SHARC_R0,
|
||||
SHARC_R15 = SHARC_R0 + 15,
|
||||
SHARC_I0,
|
||||
SHARC_I15 = SHARC_I0 + 15
|
||||
};
|
||||
|
||||
struct sharc_config
|
||||
{
|
||||
int boot_mode; /* SHARC_BOOT_MODE_xxx (MAME default: HOST) */
|
||||
UINT32 (*data_r)(UINT32 address); /* external DM, 32-bit words, word address */
|
||||
void (*data_w)(UINT32 address, UINT32 data);
|
||||
void (*flag_out)(int flag, int state); /* FLAG0-3 outputs, may be NULL */
|
||||
/* optional, may be NULL (unmapped: reads 0): external program memory,
|
||||
48-bit words in the low bits, word address */
|
||||
UINT64 (*pgm_r)(UINT32 address);
|
||||
void (*pgm_w)(UINT32 address, UINT64 data);
|
||||
};
|
||||
|
||||
extern int sharc_icount;
|
||||
|
||||
/* CPU interface */
|
||||
extern void sharc_init(void);
|
||||
extern void sharc_reset(void *param);
|
||||
extern void sharc_exit(void);
|
||||
extern int sharc_execute(int cycles);
|
||||
extern unsigned sharc_get_context(void *dst);
|
||||
extern void sharc_set_context(void *src);
|
||||
extern unsigned sharc_get_reg(int regnum);
|
||||
extern void sharc_set_reg(int regnum, unsigned val);
|
||||
extern void sharc_set_irq_line(int irqline, int state);
|
||||
extern void sharc_set_irq_callback(int (*callback)(int irqline));
|
||||
extern const char *sharc_info(void *context, int regnum);
|
||||
extern unsigned sharc_dasm(char *buffer, unsigned pc);
|
||||
|
||||
/* helpers acting on the (single) SHARC; safe to call while another CPU
|
||||
is executing, e.g. from the host CPU's memory handlers */
|
||||
|
||||
/* MAME external_iop_write: host write to an IOP register */
|
||||
extern void sharc_external_iop_write(UINT32 address, UINT32 data);
|
||||
/* MAME external_dma_write: host write to the external port DMA buffer
|
||||
(host boot); with 16/48 packing, address % 3 selects the 16-bit piece */
|
||||
extern void sharc_external_dma_write(UINT32 address, UINT64 data);
|
||||
/* MAME set_flag_input: FLAG0-3 pins configured as inputs */
|
||||
extern void sharc_set_flag_input(int flag_num, int state);
|
||||
/* MAME write_stall: while asserted, the core does not execute */
|
||||
extern void sharc_write_stall(int state);
|
||||
|
||||
/* to be called from a data_r/data_w callback that cannot complete now
|
||||
(FIFO empty/full): the access must not be committed by the driver
|
||||
(the value returned by data_r is ignored); the core ends the
|
||||
timeslice and executes the same instruction again next time, with no
|
||||
side effects committed. A stalled DMA transfer cycle is retried. */
|
||||
extern void sharc_stall(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,335 @@
|
||||
/***************************************************************************
|
||||
|
||||
ADSP-21062 SHARC DMA operations, from current MAME
|
||||
(src/devices/cpu/sharc/sharcdma.hxx, copyright Ville Linde,
|
||||
BSD-3-Clause), translated to C for MAME 2003.
|
||||
Included from sharc.c, not compiled on its own.
|
||||
|
||||
Only the interpreter paths are translated: MAME uses the DMA timer
|
||||
(sharc_dma_callback) with the recompiler only; the interpreter
|
||||
transfers one DMA word per instruction (dma_run_cycle).
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#define DMA_PMODE_NO_PACKING 0
|
||||
#define DMA_PMODE_16_32 1
|
||||
#define DMA_PMODE_16_48 2
|
||||
#define DMA_PMODE_32_48 3
|
||||
#define DMA_PMODE_8_48 4
|
||||
|
||||
static void schedule_chained_dma_op(int channel, UINT32 dma_chain_ptr, int chained_direction)
|
||||
{
|
||||
UINT32 op_ptr = 0x20000 + (dma_chain_ptr & 0x1ffff);
|
||||
|
||||
UINT32 int_index = dm_read32(op_ptr - 0);
|
||||
UINT32 int_modifier = dm_read32(op_ptr - 1);
|
||||
UINT32 int_count = dm_read32(op_ptr - 2);
|
||||
UINT32 chain_ptr = dm_read32(op_ptr - 3);
|
||||
/*UINT32 gen_purpose = dm_read32(op_ptr - 4);*/
|
||||
UINT32 ext_index = dm_read32(op_ptr - 5);
|
||||
UINT32 ext_modifier = dm_read32(op_ptr - 6);
|
||||
UINT32 ext_count = dm_read32(op_ptr - 7);
|
||||
|
||||
if (m_core->dma_op[channel].active)
|
||||
{
|
||||
/* MAME: fatal error */
|
||||
sharc_error("SHARC: schedule_chained_dma_op: DMA operation already scheduled at %08X!\n", m_core->pc);
|
||||
}
|
||||
|
||||
if (chained_direction) /* Transmit to external */
|
||||
{
|
||||
m_core->dma_op[channel].dst = ext_index;
|
||||
m_core->dma_op[channel].dst_modifier = (INT32)ext_modifier;
|
||||
m_core->dma_op[channel].dst_count = (INT32)ext_count;
|
||||
m_core->dma_op[channel].src = int_index;
|
||||
m_core->dma_op[channel].src_modifier = (INT32)int_modifier;
|
||||
m_core->dma_op[channel].src_count = (INT32)int_count;
|
||||
}
|
||||
else /* Receive from external */
|
||||
{
|
||||
m_core->dma_op[channel].src = ext_index;
|
||||
m_core->dma_op[channel].src_modifier = (INT32)ext_modifier;
|
||||
m_core->dma_op[channel].src_count = (INT32)ext_count;
|
||||
m_core->dma_op[channel].dst = int_index;
|
||||
m_core->dma_op[channel].dst_modifier = (INT32)int_modifier;
|
||||
m_core->dma_op[channel].dst_count = (INT32)int_count;
|
||||
}
|
||||
|
||||
m_core->dma_op[channel].pmode = 0;
|
||||
m_core->dma_op[channel].chain_ptr = chain_ptr;
|
||||
m_core->dma_op[channel].chained_direction = chained_direction;
|
||||
|
||||
m_core->dma_op[channel].chained = 1;
|
||||
m_core->dma_op[channel].active = 1;
|
||||
|
||||
/* enable busy flag */
|
||||
m_core->dma_status |= (1 << channel);
|
||||
}
|
||||
|
||||
static void schedule_dma_op(int channel, UINT32 src, UINT32 dst, int src_modifier, int dst_modifier, int src_count, int dst_count, int pmode)
|
||||
{
|
||||
if (m_core->dma_op[channel].active)
|
||||
{
|
||||
/* MAME: fatal error */
|
||||
sharc_error("SHARC: schedule_dma_op: DMA operation already scheduled at %08X!\n", m_core->pc);
|
||||
}
|
||||
|
||||
m_core->dma_op[channel].src = src;
|
||||
m_core->dma_op[channel].dst = dst;
|
||||
m_core->dma_op[channel].src_modifier = src_modifier;
|
||||
m_core->dma_op[channel].dst_modifier = dst_modifier;
|
||||
m_core->dma_op[channel].src_count = src_count;
|
||||
m_core->dma_op[channel].dst_count = dst_count;
|
||||
m_core->dma_op[channel].pmode = pmode;
|
||||
m_core->dma_op[channel].chain_ptr = 0;
|
||||
|
||||
m_core->dma_op[channel].chained = 0;
|
||||
m_core->dma_op[channel].active = 1;
|
||||
|
||||
/* enable busy flag */
|
||||
m_core->dma_status |= (1 << channel);
|
||||
}
|
||||
|
||||
/* one DMA transfer; returns 1 if a driver callback stalled it (port:
|
||||
nothing is committed then, and the same transfer is retried later) */
|
||||
static int dma_run_cycle(int channel)
|
||||
{
|
||||
if (m_core->dma_status & (1 << channel))
|
||||
{
|
||||
UINT32 src = m_core->dma_op[channel].src;
|
||||
UINT32 dst = m_core->dma_op[channel].dst;
|
||||
int src_modifier = m_core->dma_op[channel].src_modifier;
|
||||
int dst_modifier = m_core->dma_op[channel].dst_modifier;
|
||||
int src_count = m_core->dma_op[channel].src_count;
|
||||
int pmode = m_core->dma_op[channel].pmode;
|
||||
|
||||
m_core->stalled = 0;
|
||||
|
||||
switch (pmode)
|
||||
{
|
||||
case DMA_PMODE_NO_PACKING:
|
||||
{
|
||||
UINT32 data = dm_read32(src);
|
||||
if (m_core->stalled) break;
|
||||
dm_write32(dst, data);
|
||||
src += src_modifier;
|
||||
dst += dst_modifier;
|
||||
src_count--;
|
||||
break;
|
||||
}
|
||||
case DMA_PMODE_16_32:
|
||||
{
|
||||
UINT32 data = (dm_read32(src + 0) & 0xffff) << 16;
|
||||
data |= dm_read32(src + 1) & 0xffff;
|
||||
if (m_core->stalled) break;
|
||||
|
||||
dm_write32(dst, data);
|
||||
src += src_modifier * 2;
|
||||
dst += dst_modifier;
|
||||
src_count -= 2;
|
||||
break;
|
||||
}
|
||||
case DMA_PMODE_8_48:
|
||||
{
|
||||
UINT64 data = ((UINT64)(dm_read32(src + 0) & 0xff) << 0);
|
||||
data |= ((UINT64)(dm_read32(src + 1) & 0xff) << 8);
|
||||
data |= ((UINT64)(dm_read32(src + 2) & 0xff) << 16);
|
||||
data |= ((UINT64)(dm_read32(src + 3) & 0xff) << 24);
|
||||
data |= ((UINT64)(dm_read32(src + 4) & 0xff) << 32);
|
||||
data |= ((UINT64)(dm_read32(src + 5) & 0xff) << 40);
|
||||
if (m_core->stalled) break;
|
||||
|
||||
pm_write48(dst, data);
|
||||
src += src_modifier * 6;
|
||||
dst += dst_modifier;
|
||||
src_count -= 6;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
/* MAME: fatal error */
|
||||
sharc_error("SHARC: dma_op: unimplemented packing mode %d\n", pmode);
|
||||
/* drop the transfer instead of looping on it forever */
|
||||
src_count = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_core->stalled)
|
||||
{
|
||||
m_core->stalled = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
m_core->dma_op[channel].src_count = src_count;
|
||||
m_core->dma_op[channel].src = src;
|
||||
m_core->dma_op[channel].dst = dst;
|
||||
|
||||
if (src_count <= 0)
|
||||
{
|
||||
/* clear busy flag */
|
||||
m_core->dma_status &= ~(1 << channel);
|
||||
|
||||
m_core->dma_op[channel].active = 0;
|
||||
|
||||
/* raise interrupt if
|
||||
* non-chained DMA
|
||||
* chained-DMA with PCI set in the next chain pointer */
|
||||
if (!m_core->dma_op[channel].chained || (m_core->dma_op[channel].chained && (m_core->dma_op[channel].chain_ptr & 0x20000)))
|
||||
{
|
||||
m_core->irptl |= (1 << (channel + 10));
|
||||
|
||||
/* DMA interrupt */
|
||||
if (m_core->imask & (1 << (channel + 10)))
|
||||
{
|
||||
m_core->irq_pending |= 1 << (channel + 10);
|
||||
}
|
||||
}
|
||||
|
||||
/* schedule chained op if chaining */
|
||||
if ((m_core->dma_op[channel].chain_ptr & 0x1ffff) != 0)
|
||||
{
|
||||
schedule_chained_dma_op(channel, m_core->dma_op[channel].chain_ptr, m_core->dma_op[channel].chained_direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* whole transfer at once (used by the EPROM boot) */
|
||||
static void dma_op(int channel)
|
||||
{
|
||||
int i;
|
||||
UINT32 src = m_core->dma_op[channel].src;
|
||||
UINT32 dst = m_core->dma_op[channel].dst;
|
||||
int src_modifier = m_core->dma_op[channel].src_modifier;
|
||||
int dst_modifier = m_core->dma_op[channel].dst_modifier;
|
||||
int src_count = m_core->dma_op[channel].src_count;
|
||||
int pmode = m_core->dma_op[channel].pmode;
|
||||
|
||||
switch (pmode)
|
||||
{
|
||||
case DMA_PMODE_NO_PACKING:
|
||||
{
|
||||
for (i=0; i < src_count; i++)
|
||||
{
|
||||
UINT32 data = dm_read32(src);
|
||||
dm_write32(dst, data);
|
||||
src += src_modifier;
|
||||
dst += dst_modifier;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DMA_PMODE_16_32:
|
||||
{
|
||||
int length = src_count/2;
|
||||
for (i=0; i < length; i++)
|
||||
{
|
||||
UINT32 data = (dm_read32(src+0) & 0xffff) << 16;
|
||||
data |= dm_read32(src+1) & 0xffff;
|
||||
|
||||
dm_write32(dst, data);
|
||||
src += src_modifier * 2;
|
||||
dst += dst_modifier;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DMA_PMODE_8_48:
|
||||
{
|
||||
int length = src_count/6;
|
||||
for (i=0; i < length; i++)
|
||||
{
|
||||
UINT64 data = ((UINT64)(dm_read32(src+0) & 0xff) << 0);
|
||||
data |= ((UINT64)(dm_read32(src+1) & 0xff) << 8);
|
||||
data |= ((UINT64)(dm_read32(src+2) & 0xff) << 16);
|
||||
data |= ((UINT64)(dm_read32(src+3) & 0xff) << 24);
|
||||
data |= ((UINT64)(dm_read32(src+4) & 0xff) << 32);
|
||||
data |= ((UINT64)(dm_read32(src+5) & 0xff) << 40);
|
||||
|
||||
pm_write48(dst, data);
|
||||
src += src_modifier * 6;
|
||||
dst += dst_modifier;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
/* MAME: fatal error */
|
||||
sharc_error("SHARC: dma_op: unimplemented packing mode %d\n", pmode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (channel == 6)
|
||||
{
|
||||
m_core->irptl |= (1 << (channel+10));
|
||||
|
||||
/* DMA interrupt */
|
||||
if (m_core->imask & (1 << (channel+10)))
|
||||
{
|
||||
m_core->irq_pending |= 1 << (channel+10);
|
||||
}
|
||||
}
|
||||
|
||||
/* clear busy flag */
|
||||
m_core->dma_status &= ~(1 << channel);
|
||||
|
||||
m_core->dma_op[channel].active = 0;
|
||||
}
|
||||
|
||||
static void sharc_dma_exec(int channel)
|
||||
{
|
||||
UINT32 src, dst;
|
||||
UINT32 src_count, dst_count;
|
||||
UINT32 src_modifier, dst_modifier;
|
||||
int chen, tran, dtype, pmode, ishake, intio;
|
||||
|
||||
chen = (m_core->dma[channel].control >> 1) & 0x1;
|
||||
tran = (m_core->dma[channel].control >> 2) & 0x1;
|
||||
dtype = (m_core->dma[channel].control >> 5) & 0x1;
|
||||
pmode = (m_core->dma[channel].control >> 6) & 0x3;
|
||||
ishake = (m_core->dma[channel].control >> 10) & 0x1;
|
||||
intio = (m_core->dma[channel].control >> 11) & 0x1;
|
||||
|
||||
/* MAME: fatal errors */
|
||||
if (ishake)
|
||||
sharc_error("SHARC: dma_exec: handshake not supported\n");
|
||||
if (intio)
|
||||
sharc_error("SHARC: dma_exec: single-word interrupt enable not supported\n");
|
||||
|
||||
|
||||
if (chen) /* Chained DMA */
|
||||
{
|
||||
UINT32 dma_chain_ptr = m_core->dma[channel].chain_ptr & 0x1ffff;
|
||||
|
||||
schedule_chained_dma_op(channel, dma_chain_ptr, tran);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tran) /* Transmit to external */
|
||||
{
|
||||
dst = m_core->dma[channel].ext_index;
|
||||
dst_modifier = m_core->dma[channel].ext_modifier;
|
||||
dst_count = m_core->dma[channel].ext_count;
|
||||
src = (m_core->dma[channel].int_index & 0x1ffff) | 0x20000;
|
||||
src_modifier = m_core->dma[channel].int_modifier;
|
||||
src_count = m_core->dma[channel].int_count;
|
||||
}
|
||||
else /* Receive from external */
|
||||
{
|
||||
src = m_core->dma[channel].ext_index;
|
||||
src_modifier = m_core->dma[channel].ext_modifier;
|
||||
src_count = m_core->dma[channel].ext_count;
|
||||
dst = (m_core->dma[channel].int_index & 0x1ffff) | 0x20000;
|
||||
dst_modifier = m_core->dma[channel].int_modifier;
|
||||
dst_count = m_core->dma[channel].int_count;
|
||||
}
|
||||
|
||||
if (dtype)
|
||||
{
|
||||
pmode = DMA_PMODE_8_48;
|
||||
}
|
||||
|
||||
schedule_dma_op(channel, src, dst, (INT32)src_modifier, (INT32)dst_modifier, (INT32)src_count, (INT32)dst_count, pmode);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -617,7 +617,9 @@ static void mmfm_b(void) { MMFM(B,0x10); }
|
||||
COUNT_CYCLES(2); \
|
||||
{ \
|
||||
INT32 rd = R##DSTREG; \
|
||||
SET_N(R##REG(rd)^0x80000000); \
|
||||
/* only the 34020 sets N; on the 34010 MMTM leaves it */ \
|
||||
if (state.is_34020) \
|
||||
SET_N(R##REG(rd)^0x80000000); \
|
||||
for (i = 0; i < 16; i++) \
|
||||
{ \
|
||||
if (l & 0x8000) \
|
||||
|
||||
+52
-10
@@ -153,6 +153,13 @@ static UINT8 external_host_access;
|
||||
static void * dpyint_timer[MAX_CPU]; /* Display interrupt timer */
|
||||
static void * vsblnk_timer[MAX_CPU]; /* VBLANK start timer */
|
||||
|
||||
/* internal interrupts are delivered through TIME_NOW timers, which the */
|
||||
/* core does not save; remember the queued ones so a save state taken */
|
||||
/* while one is pending does not lose it */
|
||||
static UINT32 pending_internal[MAX_CPU];
|
||||
static int pending_generation[MAX_CPU];
|
||||
|
||||
|
||||
/* default configuration */
|
||||
static struct tms34010_config default_config =
|
||||
{
|
||||
@@ -843,6 +850,12 @@ void tms34010_init(void)
|
||||
vsblnk_timer[i] = timer_alloc(vsblnk_callback);
|
||||
}
|
||||
|
||||
/* allocate the shiftreg here rather than in reset, so the pointer */
|
||||
/* registered below is valid (a NULL entry zeroes the state size) */
|
||||
state.shiftreg = malloc(SHIFTREG_SIZE);
|
||||
if (state.shiftreg)
|
||||
memset(state.shiftreg, 0, SHIFTREG_SIZE);
|
||||
|
||||
cpunum = cpu_getactivecpu();
|
||||
state_save_register_UINT32("tms34010", cpunum, "OP", &state.op, 1);
|
||||
state_save_register_UINT32("tms34010", cpunum, "PC", &state.pc, 1);
|
||||
@@ -871,6 +884,9 @@ void tms34010_init(void)
|
||||
state_save_register_int("tms34010", cpunum, "gfxcycles", &state.gfxcycles);
|
||||
state_save_register_int("tms34010", cpunum, "luvcount", &state.last_update_vcount);
|
||||
state_save_register_int("tms34010", cpunum, "ICount", &tms34010_ICount);
|
||||
pending_internal[cpunum] = 0;
|
||||
pending_generation[cpunum] = 0;
|
||||
state_save_register_UINT32("tms34010", cpunum, "PENDINT", &pending_internal[cpunum], 1);
|
||||
state_save_register_func_presave(tms34010_state_presave);
|
||||
state_save_register_func_postload(tms34010_state_postload);
|
||||
}
|
||||
@@ -878,13 +894,13 @@ void tms34010_init(void)
|
||||
void tms34010_reset(void *param)
|
||||
{
|
||||
struct tms34010_config *config = param ? param : &default_config;
|
||||
UINT16 *shiftreg = state.shiftreg;
|
||||
|
||||
/* zap the state and copy in the config pointer */
|
||||
/* zap the state and copy in the config pointer; keep the shiftreg */
|
||||
/* allocated in init, it is registered for save states */
|
||||
memset(&state, 0, sizeof(state));
|
||||
state.config = config;
|
||||
|
||||
/* allocate the shiftreg */
|
||||
state.shiftreg = malloc(SHIFTREG_SIZE);
|
||||
state.shiftreg = shiftreg;
|
||||
|
||||
/* fetch the initial PC and reset the state */
|
||||
PC = RLONG(0xffffffe0) & 0xfffffff0;
|
||||
@@ -1198,10 +1214,23 @@ void tms34020_set_irq_callback(int (*callback)(int irqline))
|
||||
** Generate internal interrupt
|
||||
*#################################################################################################*/
|
||||
|
||||
static void internal_interrupt_callback(int param);
|
||||
|
||||
static void queue_internal_interrupt(int cpunum, int type)
|
||||
{
|
||||
pending_internal[cpunum] |= type;
|
||||
timer_set(TIME_NOW, cpunum | (type << 8) | ((pending_generation[cpunum] & 0x7f) << 24), internal_interrupt_callback);
|
||||
}
|
||||
|
||||
static void internal_interrupt_callback(int param)
|
||||
{
|
||||
int cpunum = param & 0xff;
|
||||
int type = param >> 8;
|
||||
int type = (param >> 8) & 0xffff;
|
||||
|
||||
/* ignore interrupts queued before a state load, they were re-queued */
|
||||
if (((param >> 24) & 0x7f) != (pending_generation[cpunum] & 0x7f))
|
||||
return;
|
||||
pending_internal[cpunum] &= ~type;
|
||||
|
||||
/* call through to the CPU to generate the int */
|
||||
cpuintrf_push_context(cpunum);
|
||||
@@ -1553,7 +1582,7 @@ static void dpyint_callback(int cpunum)
|
||||
|
||||
/* set the CPU's context and queue an interrupt */
|
||||
cpuintrf_push_context(cpunum);
|
||||
timer_set(TIME_NOW, cpunum | (TMS34010_DI << 8), internal_interrupt_callback);
|
||||
queue_internal_interrupt(cpunum, TMS34010_DI);
|
||||
|
||||
/* allow a callback so we can update before they are likely to do nasty things */
|
||||
if (state.config->display_int_callback)
|
||||
@@ -1678,7 +1707,7 @@ WRITE16_HANDLER( tms34010_io_register_w )
|
||||
|
||||
/* NMI issued? */
|
||||
if (data & 0x0100)
|
||||
timer_set(TIME_NOW, cpunum | (TMS34010_NMI << 8), internal_interrupt_callback);
|
||||
queue_internal_interrupt(cpunum, TMS34010_NMI);
|
||||
break;
|
||||
|
||||
case REG_HSTCTLL:
|
||||
@@ -1715,7 +1744,7 @@ WRITE16_HANDLER( tms34010_io_register_w )
|
||||
|
||||
/* input interrupt? (should really be state-based, but the functions don't exist!) */
|
||||
if (!(oldreg & 0x0008) && (newreg & 0x0008))
|
||||
timer_set(TIME_NOW, cpunum | (TMS34010_HI << 8), internal_interrupt_callback);
|
||||
queue_internal_interrupt(cpunum, TMS34010_HI);
|
||||
else if ((oldreg & 0x0008) && !(newreg & 0x0008))
|
||||
IOREG(REG_INTPEND) &= ~TMS34010_HI;
|
||||
break;
|
||||
@@ -1845,7 +1874,7 @@ WRITE16_HANDLER( tms34020_io_register_w )
|
||||
|
||||
/* NMI issued? */
|
||||
if (data & 0x0100)
|
||||
timer_set(TIME_NOW, cpunum | (TMS34010_NMI << 8), internal_interrupt_callback);
|
||||
queue_internal_interrupt(cpunum, TMS34010_NMI);
|
||||
break;
|
||||
|
||||
case REG020_HSTCTLL:
|
||||
@@ -1880,7 +1909,7 @@ WRITE16_HANDLER( tms34020_io_register_w )
|
||||
|
||||
/* input interrupt? (should really be state-based, but the functions don't exist!) */
|
||||
if (!(oldreg & 0x0008) && (newreg & 0x0008))
|
||||
timer_set(TIME_NOW, cpunum | (TMS34010_HI << 8), internal_interrupt_callback);
|
||||
queue_internal_interrupt(cpunum, TMS34010_HI);
|
||||
else if ((oldreg & 0x0008) && !(newreg & 0x0008))
|
||||
IOREG(REG020_INTPEND) &= ~TMS34010_HI;
|
||||
break;
|
||||
@@ -2150,6 +2179,19 @@ static void tms34010_state_postload(void)
|
||||
tms34010_io_register_w(REG_DPYINT,IOREG(REG_DPYINT),0);
|
||||
set_raster_op();
|
||||
set_pixel_function();
|
||||
|
||||
/* re-queue the internal interrupts that were pending at save time */
|
||||
{
|
||||
int cpunum = cpu_getactivecpu();
|
||||
UINT32 pending = pending_internal[cpunum];
|
||||
int bit;
|
||||
|
||||
pending_generation[cpunum]++;
|
||||
pending_internal[cpunum] = 0;
|
||||
for (bit = 0; bit < 16; bit++)
|
||||
if (pending & (1 << bit))
|
||||
queue_internal_interrupt(cpunum, 1 << bit);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,38 @@
|
||||
/***************************************************************************
|
||||
|
||||
TMS57002 "DASP" emulator
|
||||
|
||||
Backported to mame2003-plus from current MAME src/devices/cpu/tms57002
|
||||
(Olivier Galibert). Not a scheduled CPU here: it runs one sample period
|
||||
at a time from the sound stream of the board that has it, as in MAME
|
||||
where each stream sample syncs it.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef TMS57002_H
|
||||
#define TMS57002_H
|
||||
|
||||
#include "osd_cpu.h"
|
||||
|
||||
void tms57002dsp_init( void );
|
||||
void tms57002dsp_reset( void );
|
||||
void tms57002dsp_state_register( void );
|
||||
|
||||
/* host port */
|
||||
UINT8 tms57002dsp_data_r( void );
|
||||
void tms57002dsp_data_w( UINT8 data );
|
||||
void tms57002dsp_pload_w( int state );
|
||||
void tms57002dsp_cload_w( int state );
|
||||
int tms57002dsp_empty_r( void );
|
||||
int tms57002dsp_fifo_count( void ); /* coefficient updates waiting */
|
||||
/* called with the "update FIFO empty" line when it changes */
|
||||
void tms57002dsp_set_empty_callback( void (*callback)( int state ) );
|
||||
|
||||
/*
|
||||
One sample period: the four inputs (16-bit samples), the four outputs
|
||||
of the previous period (16-bit), then the DSP runs its program for the
|
||||
next one (cycles: instruction clock / sample rate).
|
||||
*/
|
||||
void tms57002dsp_sample( const INT32 *in, INT32 *out, int cycles );
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
@@ -360,6 +360,7 @@ static void base_init(const char *type)
|
||||
|
||||
v60.irq_cb = v60_default_irq_cb;
|
||||
v60.irq_line = CLEAR_LINE;
|
||||
v60_set_idle_loops(NULL, 0);
|
||||
v60.nmi_line = CLEAR_LINE;
|
||||
|
||||
state_save_register_UINT32(type, cpu, "reg", v60.reg, 68);
|
||||
@@ -410,6 +411,7 @@ void v60_reset(void *param)
|
||||
|
||||
void v60_exit(void)
|
||||
{
|
||||
v60_set_idle_loops(NULL, 0);
|
||||
}
|
||||
|
||||
static void v60_do_irq(int vector)
|
||||
@@ -485,9 +487,73 @@ void v60_set_irq_callback(int (*irq_cb)(int irqline))
|
||||
|
||||
/* Actual cycles/instruction is unknown*/
|
||||
|
||||
/*
|
||||
Idle loop fast-forward (opt-in, set by the driver with v60_set_idle_loops)
|
||||
|
||||
A game that waits for an interrupt by polling RAM spends most of its time
|
||||
in a loop like "[inc counter] / test mem / branch back". Only the CPU
|
||||
itself can change that RAM, and the interrupt line does not change while
|
||||
the CPU runs its slice. So once a whole iteration has run without an
|
||||
interrupt (the branch back came exactly one iteration of cycles after the
|
||||
previous one), every further iteration of the slice is the same: the
|
||||
counter goes up by one and 8 cycles are spent per instruction. This runs
|
||||
those iterations at once, leaving the last one and the end of the slice
|
||||
to the interpreter, so the CPU state, the counter and the cycle count are
|
||||
exactly what the instruction-by-instruction run gives.
|
||||
|
||||
The whole uninterrupted iteration is needed: an interrupt taken between
|
||||
the test and the branch returns to the branch with the flags of the old
|
||||
test, so a branch back alone does not prove that the loop goes on.
|
||||
*/
|
||||
|
||||
static const struct v60_idle_loop *v60_idle;
|
||||
static int v60_idle_count;
|
||||
static int v60_idle_armed; /* index + 1 of the loop seen at the last branch back in this slice */
|
||||
static int v60_idle_icount; /* v60_ICount at that branch back */
|
||||
|
||||
void v60_set_idle_loops(const struct v60_idle_loop *loops, int count)
|
||||
{
|
||||
v60_idle = loops;
|
||||
v60_idle_count = loops ? count : 0;
|
||||
v60_idle_armed = 0;
|
||||
}
|
||||
|
||||
static void v60_idle_fast_forward(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < v60_idle_count; i++)
|
||||
{
|
||||
const struct v60_idle_loop *l = &v60_idle[i];
|
||||
if (PC == l->start && PPC == l->branch)
|
||||
{
|
||||
int iteration = 8 * l->instructions;
|
||||
if (v60_idle_armed == i + 1 && v60_idle_icount - v60_ICount == iteration)
|
||||
{
|
||||
int k = v60_ICount / iteration - 1;
|
||||
if (k > 0)
|
||||
{
|
||||
v60_ICount -= k * iteration;
|
||||
switch (l->counter)
|
||||
{
|
||||
case V60_IDLE_COUNTER_REG: v60.reg[l->counter_addr] += k; break;
|
||||
case V60_IDLE_COUNTER_MEM8: MemWrite8(l->counter_addr, (UINT8)(MemRead8(l->counter_addr) + k)); break;
|
||||
case V60_IDLE_COUNTER_MEM16: MemWrite16(l->counter_addr, (UINT16)(MemRead16(l->counter_addr) + k)); break;
|
||||
case V60_IDLE_COUNTER_MEM32: MemWrite32(l->counter_addr, MemRead32(l->counter_addr) + k); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
v60_idle_armed = i + 1;
|
||||
v60_idle_icount = v60_ICount;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int v60_execute(int cycles)
|
||||
{
|
||||
v60_ICount = cycles;
|
||||
v60_idle_armed = 0;
|
||||
if(v60.irq_line != CLEAR_LINE)
|
||||
v60_try_irq();
|
||||
while(v60_ICount >= 0) {
|
||||
@@ -497,6 +563,8 @@ int v60_execute(int cycles)
|
||||
PC += OpCodeTable[OpRead8(PC)]();
|
||||
if(v60.irq_line != CLEAR_LINE)
|
||||
v60_try_irq();
|
||||
if(v60_idle_count)
|
||||
v60_idle_fast_forward();
|
||||
}
|
||||
|
||||
return cycles - v60_ICount;
|
||||
|
||||
@@ -112,4 +112,27 @@ const char *v70_info(void *context, int regnum);
|
||||
#define v70_set_reg v60_set_reg
|
||||
#define v70_set_irq_line v60_set_irq_line
|
||||
#define v70_set_irq_callback v60_set_irq_callback
|
||||
/* idle loop fast-forward: a loop of "instructions" instructions from "start"
|
||||
to the branch back at "branch", that only polls RAM and optionally counts
|
||||
its iterations in a register or in memory (see v60.c) */
|
||||
enum
|
||||
{
|
||||
V60_IDLE_COUNTER_NONE = 0,
|
||||
V60_IDLE_COUNTER_REG,
|
||||
V60_IDLE_COUNTER_MEM8,
|
||||
V60_IDLE_COUNTER_MEM16,
|
||||
V60_IDLE_COUNTER_MEM32
|
||||
};
|
||||
|
||||
struct v60_idle_loop
|
||||
{
|
||||
UINT32 start;
|
||||
UINT32 branch;
|
||||
int instructions;
|
||||
int counter;
|
||||
UINT32 counter_addr; /* register number or address */
|
||||
};
|
||||
|
||||
void v60_set_idle_loops(const struct v60_idle_loop *loops, int count);
|
||||
|
||||
#endif
|
||||
@@ -163,6 +163,50 @@ struct cpuinfo
|
||||
|
||||
static struct cpuinfo cpu[MAX_CPU];
|
||||
|
||||
/* The lasting suspend reasons of each CPU (held in reset, halted or
|
||||
disabled), kept for save states. Without them a loaded save state keeps
|
||||
the suspend state of the board that loads it: a sound CPU that was held
|
||||
in reset at that moment is reset again when the game releases its reset
|
||||
line, and it restarts its program while the main CPU does not. The
|
||||
short-lived reasons (spin, trigger) are not kept: the loaded CPU simply
|
||||
runs until it waits again. */
|
||||
#define SUSPEND_LASTING_REASONS (SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE)
|
||||
static INT32 saved_suspend[MAX_CPU];
|
||||
|
||||
/* Each CPU's local time (how far it ran past the timer system's time) and
|
||||
cycle count, kept with a save: without them a loaded CPU keeps the offset
|
||||
it had when the save was loaded, a few cycles off, and a game that polls
|
||||
another CPU drifts from the run it was saved from. */
|
||||
static double saved_localtime[MAX_CPU];
|
||||
static UINT32 saved_cycles[MAX_CPU * 2];
|
||||
|
||||
static void cpu_suspend_presave(void)
|
||||
{
|
||||
int cpunum;
|
||||
|
||||
for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
|
||||
{
|
||||
saved_suspend[cpunum] = cpu[cpunum].nextsuspend & SUSPEND_LASTING_REASONS;
|
||||
saved_localtime[cpunum] = cpu[cpunum].localtime;
|
||||
saved_cycles[cpunum * 2] = (UINT32)cpu[cpunum].totalcycles;
|
||||
saved_cycles[cpunum * 2 + 1] = (UINT32)(cpu[cpunum].totalcycles >> 32);
|
||||
}
|
||||
}
|
||||
|
||||
static void cpu_suspend_postload(void)
|
||||
{
|
||||
int cpunum;
|
||||
|
||||
for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
|
||||
{
|
||||
cpu[cpunum].suspend = cpu[cpunum].nextsuspend = saved_suspend[cpunum] & SUSPEND_LASTING_REASONS;
|
||||
if (saved_suspend[cpunum])
|
||||
cpu[cpunum].eatcycles = cpu[cpunum].nexteatcycles = 1;
|
||||
cpu[cpunum].localtime = saved_localtime[cpunum];
|
||||
cpu[cpunum].totalcycles = ((UINT64)saved_cycles[cpunum * 2 + 1] << 32) | saved_cycles[cpunum * 2];
|
||||
}
|
||||
}
|
||||
|
||||
static int time_to_reset;
|
||||
static int time_to_quit;
|
||||
|
||||
@@ -269,6 +313,11 @@ int cpu_init(void)
|
||||
/* save some stuff in tag 0 */
|
||||
state_save_set_current_tag(0);
|
||||
state_save_register_INT32("cpu", 0, "watchdog count", &watchdog_counter, 1);
|
||||
state_save_register_INT32("cpu", 0, "suspend", saved_suspend, cpu_gettotalcpu());
|
||||
state_save_register_double("cpu", 0, "localtime", saved_localtime, cpu_gettotalcpu());
|
||||
state_save_register_UINT32("cpu", 0, "totalcycles", saved_cycles, cpu_gettotalcpu() * 2);
|
||||
state_save_register_func_presave(cpu_suspend_presave);
|
||||
state_save_register_func_postload(cpu_suspend_postload);
|
||||
|
||||
/* reset the IRQ lines and save those */
|
||||
if (cpuint_init())
|
||||
@@ -797,6 +846,30 @@ int cpunum_is_suspended(int cpunum, int reason)
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Trigger suspension helpers for
|
||||
* save states
|
||||
*
|
||||
*************************************/
|
||||
|
||||
int cpunum_get_suspend_trigger(int cpunum)
|
||||
{
|
||||
VERIFY_CPUNUM(0, cpunum_get_suspend_trigger);
|
||||
if (!(cpu[cpunum].nextsuspend & SUSPEND_REASON_TRIGGER))
|
||||
return 0;
|
||||
return cpu[cpunum].trigger;
|
||||
}
|
||||
|
||||
void cpunum_suspend_until_trigger(int cpunum, int trigger, int eatcycles)
|
||||
{
|
||||
VERIFY_CPUNUM_VOID(cpunum_suspend_until_trigger);
|
||||
cpunum_suspend(cpunum, SUSPEND_REASON_TRIGGER, eatcycles);
|
||||
cpu[cpunum].trigger = trigger;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Returns the current scaling factor
|
||||
|
||||
@@ -162,6 +162,11 @@ void cpunum_resume(int cpunum, int reason);
|
||||
/* Returns true if the given CPU is suspended for any of the given reasons */
|
||||
int cpunum_is_suspended(int cpunum, int reason);
|
||||
|
||||
/* Trigger a CPU is waiting for (0 if none), and suspend a CPU until a
|
||||
trigger; used by drivers to keep a trigger wait across save states */
|
||||
int cpunum_get_suspend_trigger(int cpunum);
|
||||
void cpunum_suspend_until_trigger(int cpunum, int trigger, int eatcycles);
|
||||
|
||||
/* Aborts the timeslice for the active CPU */
|
||||
void activecpu_abort_timeslice(void);
|
||||
|
||||
|
||||
@@ -62,6 +62,26 @@ static INT32 irq_line_vector[MAX_CPU][MAX_IRQ_LINES];
|
||||
static INT32 irq_event_queue[MAX_CPU][MAX_IRQ_EVENTS];
|
||||
static int irq_event_index[MAX_CPU];
|
||||
|
||||
static void cpu_empty_event_queue(int cpunum);
|
||||
|
||||
/* A save made at the end of a frame finds the VBLANK interrupt still in the
|
||||
queue (it is emptied by a timer at the same time, which runs in the next
|
||||
frame). The queue is saved with the game, and a load sets that timer again,
|
||||
or the CPU misses that interrupt: a game that does its work every other
|
||||
frame then runs one frame late after loading. */
|
||||
static void cpuint_postload(void)
|
||||
{
|
||||
int cpunum;
|
||||
|
||||
for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
|
||||
{
|
||||
if (irq_event_index[cpunum] > MAX_IRQ_EVENTS)
|
||||
irq_event_index[cpunum] = MAX_IRQ_EVENTS;
|
||||
if (irq_event_index[cpunum] > 0)
|
||||
timer_set(TIME_NOW, cpunum, cpu_empty_event_queue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
@@ -131,6 +151,10 @@ int cpuint_init(void)
|
||||
state_save_register_INT32("cpu", 0, "irq vector", &interrupt_vector[0][0],cpu_gettotalcpu() * MAX_IRQ_LINES);
|
||||
state_save_register_UINT8("cpu", 0, "irqline state", &irq_line_state[0][0], cpu_gettotalcpu() * MAX_IRQ_LINES);
|
||||
state_save_register_INT32("cpu", 0, "irqline vector", &irq_line_vector[0][0], cpu_gettotalcpu() * MAX_IRQ_LINES);
|
||||
state_save_register_INT32("cpu", 0, "irq event queue", &irq_event_queue[0][0], cpu_gettotalcpu() * MAX_IRQ_EVENTS);
|
||||
for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
|
||||
state_save_register_int("cpu", cpunum, "irq events", &irq_event_index[cpunum]);
|
||||
state_save_register_func_postload(cpuint_postload);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+90
-1
@@ -76,6 +76,9 @@
|
||||
#if (HAS_I8X41)
|
||||
#include "cpu/i8x41/i8x41.h"
|
||||
#endif
|
||||
#if (HAS_I8051)
|
||||
#include "cpu/i8051/i8051.h"
|
||||
#endif
|
||||
#if (HAS_M6800 || HAS_M6801 || HAS_M6802 || HAS_M6803 || HAS_M6808 || HAS_HD63701)
|
||||
#include "cpu/m6800/m6800.h"
|
||||
#endif
|
||||
@@ -118,18 +121,39 @@
|
||||
#if (HAS_TMS32025)
|
||||
#include "cpu/tms32025/tms32025.h"
|
||||
#endif
|
||||
#if (HAS_I960)
|
||||
#include "cpu/i960/i960.h"
|
||||
#endif
|
||||
#if (HAS_MB86233)
|
||||
#include "cpu/mb86233/mb86233.h"
|
||||
#endif
|
||||
#if (HAS_MB86235)
|
||||
#include "cpu/mb86235/mb86235.h"
|
||||
#endif
|
||||
#if (HAS_ADSP21062)
|
||||
#include "cpu/sharc/sharc.h"
|
||||
#endif
|
||||
#if (HAS_TMS32031)
|
||||
#include "cpu/tms32031/tms32031.h"
|
||||
#endif
|
||||
#if (HAS_CCPU)
|
||||
#include "cpu/ccpu/ccpu.h"
|
||||
#endif
|
||||
#if (HAS_ADSP2100 || HAS_ADSP2101 || HAS_ADSP2104 || HAS_ADSP2105 || HAS_ADSP2115)
|
||||
#if (HAS_ADSP2100 || HAS_ADSP2101 || HAS_ADSP2104 || HAS_ADSP2105 || HAS_ADSP2115 || HAS_ADSP2181)
|
||||
#include "cpu/adsp2100/adsp2100.h"
|
||||
#endif
|
||||
#if (HAS_PSXCPU)
|
||||
#include "cpu/mips/psx.h"
|
||||
#endif
|
||||
#if (HAS_MN10200)
|
||||
#include "cpu/mn10200/mn10200.h"
|
||||
#endif
|
||||
#if (HAS_H83002)
|
||||
#include "cpu/h83002/h83002.h"
|
||||
#endif
|
||||
#if (HAS_M37702)
|
||||
#include "cpu/m37710/m37710.h"
|
||||
#endif
|
||||
#if (HAS_ASAP)
|
||||
#include "cpu/asap/asap.h"
|
||||
#endif
|
||||
@@ -148,6 +172,9 @@
|
||||
#if (HAS_ARM)
|
||||
#include "cpu/arm/arm.h"
|
||||
#endif
|
||||
#if (HAS_ARM7)
|
||||
#include "cpu/arm7/arm7.h"
|
||||
#endif
|
||||
#if (HAS_SH2)
|
||||
#include "cpu/sh2/sh2.h"
|
||||
#endif
|
||||
@@ -429,6 +456,9 @@ const struct cpu_interface cpuintrf[] =
|
||||
#if (HAS_I8X41)
|
||||
CPU0(I8X41, i8x41, 1, 0,1.00, 8, 16, 0,16,LE,1, 2 ),
|
||||
#endif
|
||||
#if (HAS_I8051)
|
||||
CPU0(I8051, i8051, 5, 0,1.00, 8, 16, 0,16,LE,1, 3 ),
|
||||
#endif
|
||||
#if (HAS_M6800)
|
||||
CPU0(M6800, m6800, 1, 0,1.00, 8, 16, 0,16,BE,1, 4 ),
|
||||
#endif
|
||||
@@ -553,9 +583,23 @@ const struct cpu_interface cpuintrf[] =
|
||||
#if (HAS_ADSP2115)
|
||||
CPU3(ADSP2115, adsp2115, 4, 0,1.00,16,17lew, -1,15,LE,2, 4 ),
|
||||
#endif
|
||||
#if (HAS_ADSP2181)
|
||||
CPU3(ADSP2181, adsp2181, 10, 0,1.00,16,17lew, -1,15,LE,2, 4 ),
|
||||
#endif
|
||||
#if (HAS_PSXCPU)
|
||||
CPU0(PSXCPU, mips, 1, 0,1.00,32,32ledw, 0,32,LE,4, 4 ),
|
||||
#endif
|
||||
#if (HAS_H83002)
|
||||
CPU0(H83002, h8_3002, 8, 0,1.00,16,24bew, 0,24,BE,2,10 ),
|
||||
#endif
|
||||
#if (HAS_MN10200)
|
||||
CPU0(MN10200, mn10200, 4, 0,1.00,16,24lew, 0,24,LE,1, 6 ),
|
||||
#endif
|
||||
#if (HAS_M37702)
|
||||
/* 16 cpuint lines: the maskable ones (M37710_LINE_ADC..IRQ0); the
|
||||
non-maskable and timer tick lines are raised by the core itself */
|
||||
CPU0(M37702, m37702, 16, 0,1.00,16,24lew, 0,24,LE,1, 6 ),
|
||||
#endif
|
||||
#if (HAS_ASAP)
|
||||
#define asap_ICount asap_icount
|
||||
CPU0(ASAP, asap, 1, 0,1.00,32,32ledw, 0,32,LE,4, 12 ),
|
||||
@@ -595,6 +639,9 @@ const struct cpu_interface cpuintrf[] =
|
||||
#if (HAS_ARM)
|
||||
CPU0(ARM, arm, 2, 0,1.00,32,26ledw, 0,26,LE,4, 4 ),
|
||||
#endif
|
||||
#if (HAS_ARM7)
|
||||
CPU0(ARM7, arm7, 5, 0,1.00,32,32ledw, 0,32,LE,2, 4 ),
|
||||
#endif
|
||||
#if (HAS_SH2)
|
||||
CPU4(SH2, sh2, 16, 0,1.00,32,32bedw, 0,32,BE,2, 2 ),
|
||||
#endif
|
||||
@@ -626,6 +673,22 @@ const struct cpu_interface cpuintrf[] =
|
||||
#if (HAS_E132XS)
|
||||
CPU0(E132XS, e132xs, 1,0,1.00, 32, 32bedw, 0,32,BE,2, 6 ),
|
||||
#endif
|
||||
#if (HAS_I960)
|
||||
#define i960_ICount i960_icount
|
||||
CPU0(I960, i960, 4, 0,1.00,32,32ledw, 0,32,LE,4,12 ),
|
||||
#endif
|
||||
#if (HAS_MB86233)
|
||||
#define mb86233_ICount mb86233_icount
|
||||
CPU0(MB86233, mb86233, 0, 0,1.00,32,32ledw, 0,32,LE,4, 4 ),
|
||||
#endif
|
||||
#if (HAS_MB86235)
|
||||
#define mb86235_ICount mb86235_icount
|
||||
CPU0(MB86235, mb86235, 0, 0,1.00,32,32ledw, 0,32,LE,8, 8 ),
|
||||
#endif
|
||||
#if (HAS_ADSP21062)
|
||||
#define sharc_ICount sharc_icount
|
||||
CPU0(ADSP21062, sharc, 3, 0,1.00,32,32ledw, 0,32,LE,4, 8 ),
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
@@ -1169,6 +1232,32 @@ void cpunum_write_byte(int cpunum, offs_t address, data8_t data)
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------
|
||||
Read/write a run of bytes
|
||||
(as cpunum_read_byte/
|
||||
cpunum_write_byte on each,
|
||||
one context switch)
|
||||
--------------------------*/
|
||||
|
||||
void cpunum_read_bytes(int cpunum, offs_t address, UINT8 *data, UINT32 count)
|
||||
{
|
||||
VERIFY_CPUNUM_VOID(cpunum_read_bytes);
|
||||
cpuintrf_push_context(cpunum);
|
||||
while (count--)
|
||||
*data++ = (*cpu[cpunum].intf.memory_read)(address++);
|
||||
cpuintrf_pop_context();
|
||||
}
|
||||
|
||||
void cpunum_write_bytes(int cpunum, offs_t address, const UINT8 *data, UINT32 count)
|
||||
{
|
||||
VERIFY_CPUNUM_VOID(cpunum_write_bytes);
|
||||
cpuintrf_push_context(cpunum);
|
||||
while (count--)
|
||||
(*cpu[cpunum].intf.memory_write)(address++, *data++);
|
||||
cpuintrf_pop_context();
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------
|
||||
Get context pointer
|
||||
--------------------------*/
|
||||
|
||||
@@ -127,6 +127,9 @@ enum
|
||||
#if (HAS_I8X41)
|
||||
CPU_I8X41,
|
||||
#endif
|
||||
#if (HAS_I8051)
|
||||
CPU_I8051,
|
||||
#endif
|
||||
#if (HAS_M6800)
|
||||
CPU_M6800,
|
||||
#endif
|
||||
@@ -250,9 +253,21 @@ enum
|
||||
#if (HAS_ADSP2115)
|
||||
CPU_ADSP2115,
|
||||
#endif
|
||||
#if (HAS_ADSP2181)
|
||||
CPU_ADSP2181,
|
||||
#endif
|
||||
#if (HAS_PSXCPU)
|
||||
CPU_PSXCPU,
|
||||
#endif
|
||||
#if (HAS_H83002)
|
||||
CPU_H83002,
|
||||
#endif
|
||||
#if (HAS_MN10200)
|
||||
CPU_MN10200,
|
||||
#endif
|
||||
#if (HAS_M37702)
|
||||
CPU_M37702,
|
||||
#endif
|
||||
#if (HAS_ASAP)
|
||||
CPU_ASAP,
|
||||
#endif
|
||||
@@ -281,6 +296,9 @@ enum
|
||||
#if (HAS_ARM)
|
||||
CPU_ARM,
|
||||
#endif
|
||||
#if (HAS_ARM7)
|
||||
CPU_ARM7,
|
||||
#endif
|
||||
#if (HAS_SH2)
|
||||
CPU_SH2,
|
||||
#endif
|
||||
@@ -311,6 +329,18 @@ enum
|
||||
#if (HAS_E132XS)
|
||||
CPU_E132XS,
|
||||
#endif
|
||||
#if (HAS_I960)
|
||||
CPU_I960,
|
||||
#endif
|
||||
#if (HAS_MB86233)
|
||||
CPU_MB86233,
|
||||
#endif
|
||||
#if (HAS_MB86235)
|
||||
CPU_MB86235,
|
||||
#endif
|
||||
#if (HAS_ADSP21062)
|
||||
CPU_ADSP21062,
|
||||
#endif
|
||||
|
||||
CPU_COUNT
|
||||
};
|
||||
@@ -590,6 +620,10 @@ data8_t cpunum_read_byte(int cpunum, offs_t address);
|
||||
/* write a byte from another CPU's memory space */
|
||||
void cpunum_write_byte(int cpunum, offs_t address, data8_t data);
|
||||
|
||||
/* read/write 'count' consecutive bytes of another CPU's memory space (one context switch) */
|
||||
void cpunum_read_bytes(int cpunum, offs_t address, UINT8 *data, UINT32 count);
|
||||
void cpunum_write_bytes(int cpunum, offs_t address, const UINT8 *data, UINT32 count);
|
||||
|
||||
/* return a pointer to the saved context of a given CPU, or NULL if the
|
||||
context is active (and contained within the CPU core */
|
||||
void *cpunum_get_context_ptr(int cpunum);
|
||||
|
||||
+540
-102
@@ -121,7 +121,7 @@ const struct GameDriver *test_drivers[] =
|
||||
DRIVER( ponpokov ) /* (c) 1982 Sigma Ent. Inc. + Venture Line license */
|
||||
DRIVER( lizwiz ) /* (c) 1985 Techstar + "Sunn presents" */
|
||||
DRIVER( theglobp ) /* (c) 1983 Epos Corporation */
|
||||
DRIVER( beastf ) /* (c) 1984 Epos Corporation */
|
||||
DRIVER( beastfp ) /* (c) 1984 Epos Corporation */
|
||||
DRIVER( acitya ) /* (c) 1983 Epos Corporation */
|
||||
DRIVER( bwcasino ) /* (c) 1983 Epos Coropration */
|
||||
DRIVER( dremshpr ) /* (c) 1982 Sanritsu */
|
||||
@@ -158,7 +158,10 @@ const struct GameDriver *test_drivers[] =
|
||||
DRIVER( theglob2 ) /* (c) 1983 */
|
||||
DRIVER( theglob3 ) /* (c) 1983 */
|
||||
DRIVER( igmo ) /* (c) 1984 */
|
||||
DRIVER( dealer ) /* (c) 198? */
|
||||
DRIVER( dealer ) /* (c) 1984 */
|
||||
DRIVER( revngr84 ) /* (c) 1984 */
|
||||
DRIVER( revenger ) /* (c) 1984 */
|
||||
DRIVER( beastf ) /* (c) 1984 */
|
||||
|
||||
/* "Galaxian hardware" games */
|
||||
DRIVER( galaxian ) /* (c) Namco */
|
||||
@@ -2050,24 +2053,51 @@ V-V TP-027
|
||||
DRIVER( makaimuc ) /* 9/1985 (c) 1985 */
|
||||
DRIVER( makaimug ) /* 9/1985 (c) 1985 */
|
||||
DRIVER( diamond ) /* (c) 1989 KH Video (NOT A CAPCOM GAME but runs on GnG hardware) */
|
||||
DRIVER( gngknight ) /* Hack */
|
||||
DRIVER( gngknighta ) /* Hack */
|
||||
DRIVER( gngknightb ) /* Hack */
|
||||
DRIVER( gngknightc ) /* Hack */
|
||||
DRIVER( gngknightt ) /* Hack */
|
||||
DRIVER( gngenh ) /* Hack */
|
||||
DRIVER( gngaenh ) /* Hack */
|
||||
DRIVER( gngbenh ) /* Hack */
|
||||
DRIVER( gngcenh ) /* Hack */
|
||||
DRIVER( gngtenh ) /* Hack */
|
||||
DRIVER( makaimurenh ) /* Hack */
|
||||
DRIVER( makaimurbenh ) /* Hack */
|
||||
DRIVER( makaimurcenh ) /* Hack */
|
||||
DRIVER( makaimurgenh ) /* Hack */
|
||||
DRIVER( gngmaiden ) /* Hack */
|
||||
DRIVER( gngmaidenenh ) /* Hack */
|
||||
DRIVER( gngmaidena ) /* Hack */
|
||||
DRIVER( gngmaidenaenh ) /* Hack */
|
||||
DRIVER( gngmaidenb ) /* Hack */
|
||||
DRIVER( gngmaidenbenh ) /* Hack */
|
||||
DRIVER( gngmaidenc ) /* Hack */
|
||||
DRIVER( gngmaidencenh ) /* Hack */
|
||||
DRIVER( gngmaident ) /* Hack */
|
||||
DRIVER( makknight ) /* Hack */
|
||||
DRIVER( makknightb ) /* Hack */
|
||||
DRIVER( makknightc ) /* Hack */
|
||||
DRIVER( makknightg ) /* Hack */
|
||||
DRIVER( gngmaidentenh ) /* Hack */
|
||||
DRIVER( gngknight ) /* Hack */
|
||||
DRIVER( gngknightenh ) /* Hack */
|
||||
DRIVER( gngknighta ) /* Hack */
|
||||
DRIVER( gngknightaenh ) /* Hack */
|
||||
DRIVER( gngknightb ) /* Hack */
|
||||
DRIVER( gngknightbenh ) /* Hack */
|
||||
DRIVER( gngknightc ) /* Hack */
|
||||
DRIVER( gngknightcenh ) /* Hack */
|
||||
DRIVER( gngknightt ) /* Hack */
|
||||
DRIVER( gngknighttenh ) /* Hack */
|
||||
DRIVER( makmaiden ) /* Hack */
|
||||
DRIVER( makmaidenenh ) /* Hack */
|
||||
DRIVER( makmaidenb ) /* Hack */
|
||||
DRIVER( makmaidenbenh ) /* Hack */
|
||||
DRIVER( makmaidenc ) /* Hack */
|
||||
DRIVER( makmaidencenh ) /* Hack */
|
||||
DRIVER( makmaideng ) /* Hack */
|
||||
DRIVER( makmaidengenh ) /* Hack */
|
||||
DRIVER( makknight ) /* Hack */
|
||||
DRIVER( makknightenh ) /* Hack */
|
||||
DRIVER( makknightb ) /* Hack */
|
||||
DRIVER( makknightbenh ) /* Hack */
|
||||
DRIVER( makknightc ) /* Hack */
|
||||
DRIVER( makknightcenh ) /* Hack */
|
||||
DRIVER( makknightg ) /* Hack */
|
||||
DRIVER( makknightgenh ) /* Hack */
|
||||
DRIVER( gunsmoke ) /* 11/1985 (c) 1985 (World) */
|
||||
DRIVER( gunsmoku ) /* 11/1985 (c) 1985 + Romstar (US) */
|
||||
DRIVER( gunsmoka ) /* 11/1985 (c) 1985 (US) */
|
||||
@@ -2138,6 +2168,12 @@ V-V TP-027
|
||||
DRIVER( ghouls ) /* 12/1988 (c) 1988 (World) */
|
||||
DRIVER( ghoulsu ) /* 12/1988 (c) 1988 (US) */
|
||||
DRIVER( daimakai ) /* 12/1988 (c) 1988 (Japan) */
|
||||
DRIVER( ghoulsmaiden ) /* Hack */
|
||||
DRIVER( ghoulsknight ) /* Hack */
|
||||
DRIVER( ghoulsumaiden ) /* Hack */
|
||||
DRIVER( ghoulsuknight ) /* Hack */
|
||||
DRIVER( daimakaimaiden ) /* Hack */
|
||||
DRIVER( daimakaiknight ) /* Hack */
|
||||
DRIVER( strider ) /* 3/1989 (c) 1989 (not explicitly stated but should be US) */
|
||||
DRIVER( stridrua ) /* 3/1989 (c) 1989 (not explicitly stated but should be US) */
|
||||
DRIVER( striderj ) /* 3/1989 (c) 1989 */
|
||||
@@ -2418,6 +2454,7 @@ V-V TP-027
|
||||
DRIVER( spf2xj ) /* Capcom, Super Puzzle Fighter II X (Japan 960531) */
|
||||
DRIVER( spf2ta ) /* Capcom, Super Puzzle Fighter II Turbo (Asia 960529) */
|
||||
DRIVER( spf2th ) /* Capcom, Super Puzzle Fighter II Turbo (Hispanic 960531) */
|
||||
DRIVER( spf2xpri ) /* hack, Super Puzzle Fighter 2 X' (X Prime rebalance of Euro 960529) */
|
||||
DRIVER( megaman2 ) /* Capcom, Mega Man 2: The Power Fighters (USA 960708) */
|
||||
DRIVER( megaman2a ) /* Capcom, Mega Man 2: The Power Fighters (Asia 960708) */
|
||||
DRIVER( rockman2j ) /* Capcom, Rockman 2: The Power Fighters (Japan 960708) */
|
||||
@@ -2494,6 +2531,7 @@ V-V TP-027
|
||||
DRIVER( sfz3jr2 ) /* Capcom, Street Fighter Zero 3 (Japan 980629) */
|
||||
DRIVER( sfz3a ) /* Capcom, Street Fighter Zero 3 (Asia 980904) */
|
||||
DRIVER( sfz3ar1 ) /* Capcom, Street Fighter Zero 3 (Asia 980701) */
|
||||
DRIVER( sfz3mix ) /* hack, Street Fighter Zero 3 Mix v0.32 (CPS2Turbo, Zero800) */
|
||||
DRIVER( jyangoku ) /* Capcom, Jyangokushi: Haoh no Saihai (Japan 990527) */
|
||||
DRIVER( hsf2 ) /* Capcom, Hyper Street Fighter II: The Anniversary Edition (USA 040202) */
|
||||
DRIVER( hsf2a ) /* Capcom, Hyper Street Fighter II: The Anniversary Edition (Asia 040202) */
|
||||
@@ -2574,100 +2612,278 @@ V-V TP-027
|
||||
DRIVER( hsf2d ) /* bootleg, Hyper Street Fighter II: The Anniversary Edition (Asia 040202 Phoenix Edition) (bootleg) */
|
||||
#endif
|
||||
/* Capcom CPS3 games */
|
||||
/* 10/1996 Warzard */
|
||||
/* 2/1997 Street Fighter III - New Generation */
|
||||
/* ???? Jojo's Bizarre Adventure */
|
||||
/* ???? Street Fighter 3: Second Impact ~giant attack~ */
|
||||
/* ???? Street Fighter 3: Third Strike ~fight to the finish~ */
|
||||
DRIVER( redearth )
|
||||
DRIVER( warzard )
|
||||
DRIVER( redearthn )
|
||||
DRIVER( redearthr1 )
|
||||
DRIVER( warzardr1 )
|
||||
DRIVER( redearthnr1 )
|
||||
DRIVER( sfiii )
|
||||
DRIVER( sfiiiu )
|
||||
DRIVER( sfiiia )
|
||||
DRIVER( sfiiij )
|
||||
DRIVER( sfiiih )
|
||||
DRIVER( sfiiin )
|
||||
DRIVER( sfiiina )
|
||||
DRIVER( sfiii2 )
|
||||
DRIVER( sfiii2j )
|
||||
DRIVER( sfiii2h )
|
||||
DRIVER( sfiii2a )
|
||||
DRIVER( sfiii2n )
|
||||
DRIVER( jojo )
|
||||
DRIVER( jojou )
|
||||
DRIVER( jojoa )
|
||||
DRIVER( jojoj )
|
||||
DRIVER( jojon )
|
||||
DRIVER( jojor1 )
|
||||
DRIVER( jojour1 )
|
||||
DRIVER( jojoar1 )
|
||||
DRIVER( jojojr1 )
|
||||
DRIVER( jojonr1 )
|
||||
DRIVER( jojor2 )
|
||||
DRIVER( jojour2 )
|
||||
DRIVER( jojoar2 )
|
||||
DRIVER( jojojr2 )
|
||||
DRIVER( jojonr2 )
|
||||
DRIVER( sfiii3 )
|
||||
DRIVER( sfiii3u )
|
||||
DRIVER( sfiii3j )
|
||||
DRIVER( sfiii3n )
|
||||
DRIVER( sfiii3na )
|
||||
DRIVER( sfiii3r1 )
|
||||
DRIVER( sfiii3ur1 )
|
||||
DRIVER( sfiii3jr1 )
|
||||
DRIVER( sfiii3nr1 )
|
||||
DRIVER( sfiii3nar1 )
|
||||
DRIVER( jojoba )
|
||||
DRIVER( jojoban )
|
||||
DRIVER( jojobar1 )
|
||||
DRIVER( jojobajr1 )
|
||||
DRIVER( jojobanr1 )
|
||||
DRIVER( jojobaner1 )
|
||||
DRIVER( jojobar2 )
|
||||
DRIVER( jojobajr2 )
|
||||
DRIVER( jojobanr2 )
|
||||
DRIVER( jojobaner2 )
|
||||
DRIVER( sfiii4n )
|
||||
DRIVER( sfiii3ws ) /* hack, Street Fighter III 3rd Strike: Fight for the Future (Widescreen 20220908) */
|
||||
|
||||
/* Capcom ZN1 */
|
||||
DRIVER( ts2 ) /* Battle Arena Toshinden 2 (USA 951124) */
|
||||
DRIVER( ts2j ) /* Battle Arena Toshinden 2 (JAPAN 951124) */
|
||||
DRIVER( starglad ) /* Star Gladiator (USA 960627) */
|
||||
DRIVER( sfex ) /* Street Fighter EX (ASIA 961219) */
|
||||
DRIVER( sfexj ) /* Street Fighter EX (JAPAN 961130) */
|
||||
DRIVER( glpracr ) /* Gallop Racer (JAPAN Ver 9.01.12) */
|
||||
DRIVER( sfexp ) /* Street Fighter EX Plus (USA 970311) */
|
||||
DRIVER( sfexpj ) /* Street Fighter EX Plus (JAPAN 970311) */
|
||||
DRIVER( rvschool ) /* Rival Schools (ASIA 971117) */
|
||||
DRIVER( jgakuen ) /* Justice Gakuen (JAPAN 971117) */
|
||||
DRIVER( tgmj ) /* Tetris The Grand Master (JAPAN 980710) */
|
||||
/* Capcom ZN-1 */
|
||||
DRIVER( ts2 ) /* Battle Arena Toshinden 2 (Europe 951124) */
|
||||
DRIVER( ts2u ) /* Battle Arena Toshinden 2 (USA 951124) */
|
||||
DRIVER( ts2ua ) /* Battle Arena Toshinden 2 (USA 951124, 32Mb mask ROMs) */
|
||||
DRIVER( ts2j ) /* Battle Arena Toshinden 2 (Japan 951124) */
|
||||
DRIVER( ts2ja ) /* Battle Arena Toshinden 2 (Japan 951124, 32Mb mask ROMs) */
|
||||
DRIVER( starglad ) /* Star Gladiator Episode I: Final Crusade (USA 960627) */
|
||||
DRIVER( stargladj ) /* Star Gladiator Episode I: Final Crusade (Japan 960627) */
|
||||
DRIVER( glpracr ) /* Gallop Racer (English Ver 10.17.K) */
|
||||
DRIVER( glpracrj ) /* Gallop Racer (Japanese Ver 9.01.12) */
|
||||
DRIVER( sfex ) /* Street Fighter EX (Europe 961219) */
|
||||
DRIVER( sfexu ) /* Street Fighter EX (USA 961219) */
|
||||
DRIVER( sfexa ) /* Street Fighter EX (Asia 961219) */
|
||||
DRIVER( sfexj ) /* Street Fighter EX (Japan 961130) */
|
||||
DRIVER( sfexp ) /* Street Fighter EX Plus (USA 970407) */
|
||||
DRIVER( sfexpu1 ) /* Street Fighter EX Plus (USA 970311) */
|
||||
DRIVER( sfexpj ) /* Street Fighter EX Plus (Japan 970407) */
|
||||
|
||||
/* Capcom ZN2 */
|
||||
DRIVER( sfex2 ) /* Street Fighter EX 2 (JAPAN 980312) */
|
||||
DRIVER( sg2j ) /* Star Gladiator 2 (JAPAN 980316) */
|
||||
DRIVER( techromn ) /* Tech Romancer (USA 980914) */
|
||||
DRIVER( kikaioh ) /* Kikaioh (JAPAN 980914) */
|
||||
DRIVER( sfex2p ) /* Street Fighter EX 2 Plus (JAPAN 990611) */
|
||||
DRIVER( strider2 ) /* Strider 2 (USA 991213) */
|
||||
DRIVER( stridr2a ) /* Strider 2 (ASIA 991213) */
|
||||
DRIVER( shiryu2 ) /* Strider Hiryu 2 (JAPAN 991213) */
|
||||
/* Rival Schools 2 */
|
||||
/* Capcom ZN-2 */
|
||||
DRIVER( sfexpj1 ) /* Street Fighter EX Plus (Japan 970311) */
|
||||
DRIVER( rvschool ) /* Rival Schools: United By Fate (Europe 971117) */
|
||||
DRIVER( rvschoolu ) /* Rival Schools: United By Fate (USA 971117) */
|
||||
DRIVER( rvschoola ) /* Rival Schools: United By Fate (Asia 971117) */
|
||||
DRIVER( jgakuen ) /* Shiritsu Justice Gakuen: Legion of Heroes (Japan 971216) */
|
||||
DRIVER( jgakuen1 ) /* Shiritsu Justice Gakuen: Legion of Heroes (Japan 971117) */
|
||||
DRIVER( sfex2 ) /* Street Fighter EX2 (Europe 980312) */
|
||||
DRIVER( sfex2u ) /* Street Fighter EX2 (USA 980526) */
|
||||
DRIVER( sfex2u1 ) /* Street Fighter EX2 (USA 980312) */
|
||||
DRIVER( sfex2a ) /* Street Fighter EX2 (Asia 980312) */
|
||||
DRIVER( sfex2h ) /* Street Fighter EX2 (Hispanic 980312) */
|
||||
DRIVER( sfex2j ) /* Street Fighter EX2 (Japan 980312) */
|
||||
DRIVER( plsmaswd ) /* Plasma Sword: Nightmare of Bilstein (USA 980316) */
|
||||
DRIVER( plsmaswda ) /* Plasma Sword: Nightmare of Bilstein (Asia 980316) */
|
||||
DRIVER( stargld2 ) /* Star Gladiator 2: Nightmare of Bilstein (Japan 980316) */
|
||||
DRIVER( tgmj ) /* Tetris: The Grand Master (Japan 980710) */
|
||||
DRIVER( techromn ) /* Tech Romancer (Europe 980914) */
|
||||
DRIVER( techromnu ) /* Tech Romancer (USA 980914) */
|
||||
DRIVER( techromna ) /* Tech Romancer (Asia 980914) */
|
||||
DRIVER( kikaioh ) /* Choukou Senki Kikaioh (Japan 980914) */
|
||||
DRIVER( sfex2p ) /* Street Fighter EX2 Plus (Europe 990611) */
|
||||
DRIVER( sfex2pu ) /* Street Fighter EX2 Plus (USA 990611) */
|
||||
DRIVER( sfex2pa ) /* Street Fighter EX2 Plus (Asia 990611) */
|
||||
DRIVER( sfex2ph ) /* Street Fighter EX2 Plus (Hispanic 990611) */
|
||||
DRIVER( sfex2pj ) /* Street Fighter EX2 Plus (Japan 990611) */
|
||||
DRIVER( strider2 ) /* Strider 2 (Europe 991213) */
|
||||
DRIVER( strider2u ) /* Strider 2 (USA 991213) */
|
||||
DRIVER( strider2a ) /* Strider 2 (Asia 991213) */
|
||||
DRIVER( shiryu2 ) /* Strider Hiryu 2 (Japan 991213) */
|
||||
|
||||
/* Tecmo ZN1 */
|
||||
DRIVER( glpracr2 ) /* Gallop Racer 2 (USA) */
|
||||
DRIVER( glprac2j ) /* Gallop Racer 2 (JAPAN) */
|
||||
DRIVER( glprac2l ) /* Gallop Racer 2 Link HW (JAPAN) */
|
||||
DRIVER( doapp ) /* Dead Or Alive ++ (JAPAN) */
|
||||
DRIVER( tondemo ) /* Tondemo Crisis (JAPAN) */
|
||||
/* Tecmo TPS (ZN1) */
|
||||
DRIVER( glpracr2 ) /* Gallop Racer 2 (Export) */
|
||||
DRIVER( glpracr2j ) /* Gallop Racer 2 (Japan) */
|
||||
DRIVER( glpracr2l ) /* Gallop Racer 2 Link HW (Japan) */
|
||||
DRIVER( doapp ) /* Dead Or Alive ++ (Japan/USA/Export) */
|
||||
DRIVER( doappk ) /* Dead Or Alive ++ (Korea) */
|
||||
DRIVER( cbaj ) /* Cool Boarders Arcade Jam (Export) */
|
||||
DRIVER( cbajbl ) /* Cool Boarders Arcade Jam (Export bootleg) */
|
||||
DRIVER( shngmtkb ) /* Shanghai Matekibuyuu (Japan) */
|
||||
DRIVER( tondemo ) /* Tondemo Crisis (Japan) */
|
||||
DRIVER( glpracr3 ) /* Gallop Racer 3 (Export) */
|
||||
DRIVER( glpracr3j ) /* Gallop Racer 3 (Japan) */
|
||||
DRIVER( flamegun ) /* Flame Gunner (Export) */
|
||||
DRIVER( flamegunj ) /* Flame Gunner (Japan) */
|
||||
DRIVER( lpadv ) /* Logic Pro Adventure (Japan) */
|
||||
DRIVER( tblkkuzu ) /* The Block Kuzushi (Japan) */
|
||||
DRIVER( 1on1gov ) /* 1 on 1 Government (Japan) */
|
||||
DRIVER( twcupmil ) /* Tecmo World Cup Millennium (Japan) */
|
||||
DRIVER( mfjump ) /* Monster Farm Jump (Japan) */
|
||||
|
||||
/* PS Arcade 95 */
|
||||
DRIVER( brvblade ) /* Brave Blade */
|
||||
DRIVER( beastrzr ) /* Beastorizer */
|
||||
/* Eighting / Raizing (COH-1002E) */
|
||||
DRIVER( beastrzr ) /* Beastorizer (USA, Sep 22 1997) */
|
||||
DRIVER( beastrzra ) /* Beastorizer (USA, Jun 21 1997) */
|
||||
DRIVER( beastrzrb ) /* Beastorizer (USA bootleg) */
|
||||
DRIVER( bldyroar ) /* Bloody Roar (Japan, Jun 21 1997) */
|
||||
DRIVER( bldyror2 ) /* Bloody Roar 2 (World) */
|
||||
DRIVER( bldyror2u ) /* Bloody Roar 2 (USA) */
|
||||
DRIVER( bldyror2a ) /* Bloody Roar 2 (Asia) */
|
||||
DRIVER( bldyror2j ) /* Bloody Roar 2 (Japan) */
|
||||
DRIVER( brvblade ) /* Brave Blade (World) */
|
||||
DRIVER( brvbladeu ) /* Brave Blade (USA) */
|
||||
DRIVER( brvbladea ) /* Brave Blade (Asia) */
|
||||
DRIVER( brvbladej ) /* Brave Blade (Japan) */
|
||||
|
||||
/* Atari PSX */
|
||||
DRIVER( primrag2 ) /* Primal Rage 2 */
|
||||
DRIVER( primrag2 ) /* Primal Rage II (Test Version 0.36a) */
|
||||
|
||||
/* Acclaim PSX */
|
||||
DRIVER( nbajamex ) /* NBA Jam Extreme */
|
||||
DRIVER( jdredd ) /* Judge Dredd (Rev C) */
|
||||
DRIVER( jdreddb ) /* Judge Dredd (Rev B) */
|
||||
DRIVER( jdredd ) /* Judge Dredd (Rev C Dec. 17 1997) */
|
||||
DRIVER( jdreddb ) /* Judge Dredd (Rev B Nov. 26 1997) */
|
||||
DRIVER( nbajamex ) /* NBA Jam Extreme (ver. 1.10I) */
|
||||
DRIVER( nbajamexa ) /* NBA Jam Extreme (ver. 1.04) */
|
||||
|
||||
/* Video System ZN1 */
|
||||
DRIVER( sncwgltd ) /* Sonic Wings Limited (JAPAN) */
|
||||
DRIVER( aerofgts ) /* Aero Fighters Special (USA) */
|
||||
DRIVER( aerofgtst ) /* Aero Fighters Special (Taiwan) */
|
||||
DRIVER( sncwgltd ) /* Sonic Wings Limited (Japan) */
|
||||
|
||||
/* Taito FX1a */
|
||||
DRIVER( psyforce ) /* Psychic Force (JAPAN) */
|
||||
DRIVER( sfchamp ) /* Super Football Champ (JAPAN) */
|
||||
DRIVER( mgcldate ) /* Magical Date (JAPAN) */
|
||||
DRIVER( mgcldtea ) /* Magical Date (JAPAN) */
|
||||
/* Atlus ZN1 */
|
||||
DRIVER( hvnsgate ) /* Heaven's Gate */
|
||||
|
||||
/* Taito FX1b */
|
||||
DRIVER( raystorm ) /* Ray Storm (JAPAN) */
|
||||
DRIVER( ftimpcta ) /* Fighter's Impact Ace (JAPAN) */
|
||||
DRIVER( gdarius ) /* G-Darius (JAPAN) */
|
||||
DRIVER( gdarius2 ) /* G-Darius Ver.2 (JAPAN) */
|
||||
DRIVER( beastrzb ) /* Beastorizer (bootleg)*/
|
||||
/* Taito FX-1A */
|
||||
DRIVER( sfchamp ) /* Super Football Champ (Ver 2.5O) */
|
||||
DRIVER( sfchampo ) /* Super Football Champ (Ver 2.4O) */
|
||||
DRIVER( sfchampu ) /* Super Football Champ (Ver 2.4A) */
|
||||
DRIVER( sfchampj ) /* Super Football Champ (Ver 2.4J) */
|
||||
DRIVER( psyforce ) /* Psychic Force (Ver 2.4O) */
|
||||
DRIVER( psyforcej ) /* Psychic Force (Ver 2.4J) */
|
||||
DRIVER( psyforcex ) /* Psychic Force EX (Ver 2.0J) */
|
||||
DRIVER( mgcldtex ) /* Magical Date EX (Ver 2.01J) */
|
||||
DRIVER( mgcldate ) /* Magical Date (Ver 2.02J) */
|
||||
|
||||
/* Taito FX-1B */
|
||||
DRIVER( raystorm ) /* RayStorm (Ver 2.06A) */
|
||||
DRIVER( raystormo ) /* RayStorm (Ver 2.05O) */
|
||||
DRIVER( raystormu ) /* RayStorm (Ver 2.05A) */
|
||||
DRIVER( raystormj ) /* RayStorm (Ver 2.05J) */
|
||||
DRIVER( ftimpcta ) /* Fighters' Impact A (Ver 2.00J) */
|
||||
DRIVER( ftimpact ) /* Fighters' Impact (Ver 2.02O) */
|
||||
DRIVER( ftimpactu ) /* Fighters' Impact (Ver 2.02A) */
|
||||
DRIVER( ftimpactj ) /* Fighters' Impact (Ver 2.02J) */
|
||||
DRIVER( gdarius2 ) /* G-Darius Ver.2 (Ver 2.03J) */
|
||||
DRIVER( gdarius ) /* G-Darius (Ver 2.02O) */
|
||||
DRIVER( gdariusu ) /* G-Darius (Ver 2.02A) */
|
||||
DRIVER( gdariusj ) /* G-Darius (Ver 2.01J) */
|
||||
|
||||
/* Namco System 11 */
|
||||
DRIVER( tekken ) /* Tekken (TE4/VER.C) */
|
||||
DRIVER( tekkena ) /* Tekken (TE2/VER.B) */
|
||||
DRIVER( tekkenb ) /* Tekken (TE1/VER.B) */
|
||||
DRIVER( tekken2 ) /* Tekken 2 Ver.B (TES3/VER.B) */
|
||||
DRIVER( tekken2a ) /* Tekken 2 Ver.B (TES2/VER.B) */
|
||||
DRIVER( tekken2b ) /* Tekken 2 (TES2/VER.A) */
|
||||
DRIVER( souledge ) /* Soul Edge Ver. II (SO4/VER.C) */
|
||||
DRIVER( souledga ) /* Soul Edge (SO3/VER.A) */
|
||||
DRIVER( souledgb ) /* Soul Edge (SO1/VER.A) */
|
||||
DRIVER( dunkmnia ) /* Dunk Mania (DM1/VER.C) */
|
||||
DRIVER( xevi3dg ) /* Xevious 3D/G (XV31/VER.A) */
|
||||
DRIVER( primglex ) /* Prime Goal EX (PG1/VER.A) */
|
||||
DRIVER( danceyes ) /* Dancing Eyes (DC1/VER.A) */
|
||||
DRIVER( starswep ) /* Star Sweep (STP1/VER.A) */
|
||||
DRIVER( myangel3 ) /* Kosodate Quiz My Angel 3 (KQT1/VER.A) */
|
||||
DRIVER( tekken ) /* Tekken (World, TE2/VER.C) */
|
||||
DRIVER( tekkenac ) /* Tekken (Asia, TE4/VER.C) */
|
||||
DRIVER( tekkenb ) /* Tekken (World, TE2/VER.B) */
|
||||
DRIVER( tekkenjb ) /* Tekken (Japan, TE1/VER.B) */
|
||||
DRIVER( tekken2 ) /* Tekken 2 Ver.B (World, TES2/VER.D) */
|
||||
DRIVER( tekken2b ) /* Tekken 2 Ver.B (World, TES2/VER.B) */
|
||||
DRIVER( tekken2ud ) /* Tekken 2 Ver.B (US, TES3/VER.D) */
|
||||
DRIVER( tekken2ub ) /* Tekken 2 Ver.B (US, TES3/VER.B) */
|
||||
DRIVER( tekken2jc ) /* Tekken 2 Ver.B (Japan, TES1/VER.C) */
|
||||
DRIVER( tekken2jb ) /* Tekken 2 Ver.B (Japan, TES1/VER.B) */
|
||||
DRIVER( tekken2a ) /* Tekken 2 (World, TES2/VER.A) */
|
||||
DRIVER( tekken2ua ) /* Tekken 2 (US, TES3/VER.A) */
|
||||
DRIVER( souledge ) /* Soul Edge Ver. II (Asia, SO4/VER.C) */
|
||||
DRIVER( souledgeuc ) /* Soul Edge Ver. II (US, SO3/VER.C) */
|
||||
DRIVER( souledgea ) /* Soul Edge (World, SO2/VER.A) */
|
||||
DRIVER( souledgeua ) /* Soul Edge (US, SO3/VER.A) */
|
||||
DRIVER( souledgeja ) /* Soul Edge (Japan, SO1/VER.A) */
|
||||
DRIVER( dunkmnia ) /* Dunk Mania (World, DM2/VER.C) */
|
||||
DRIVER( dunkmniajc ) /* Dunk Mania (Japan, DM1/VER.C) */
|
||||
DRIVER( xevi3dg ) /* Xevious 3D/G (World, XV32/VER.B) */
|
||||
DRIVER( xevi3dga ) /* Xevious 3D/G (World, XV32/VER.A) */
|
||||
DRIVER( xevi3dgj ) /* Xevious 3D/G (Japan, XV31/VER.A) */
|
||||
DRIVER( primglex ) /* Prime Goal EX (Japan, PG1/VER.A) */
|
||||
DRIVER( danceyes ) /* Dancing Eyes (World, DC2/VER.B) */
|
||||
DRIVER( danceyesu ) /* Dancing Eyes (US, DC3/VER.C) */
|
||||
DRIVER( danceyesj ) /* Dancing Eyes (Japan, DC1/VER.A) */
|
||||
DRIVER( starswep ) /* Star Sweep (World, STP2/VER.A) */
|
||||
DRIVER( starswepj ) /* Star Sweep (Japan, STP1/VER.A) */
|
||||
DRIVER( myangel3 ) /* Kosodate Quiz My Angel 3 (Japan, KQT1/VER.A) */
|
||||
DRIVER( pocketrc ) /* Pocket Racer (Japan, PKR1/VER.B) */
|
||||
DRIVER( ptblank2a ) /* Point Blank 2 (World, GNB2/VER.A) */
|
||||
DRIVER( ptblank2b ) /* Point Blank 2 (World, GNB2/VER.A alt) */
|
||||
DRIVER( ptblank2c ) /* Point Blank 2 (World, unknown version) */
|
||||
DRIVER( ptblank2ua ) /* Point Blank 2 (US, GNB3/VER.A) */
|
||||
DRIVER( gunbarla ) /* Gunbarl (Japan, GNB1/VER.A) */
|
||||
|
||||
/* Namco System 12 */
|
||||
DRIVER( tekken3 ) /* Tekken 3 (TET1/VER.E) */
|
||||
DRIVER( soulclbr ) /* Soul Calibur (SOC1/VER.A) */
|
||||
DRIVER( ehrgeiz ) /* Ehrgeiz (EG3/VER.A) */
|
||||
DRIVER( mdhorse ) /* Derby Quiz My Dream Horse (MDH1/VER.A) */
|
||||
DRIVER( fgtlayer ) /* Fighting Layer (FTL1/VER.A) */
|
||||
DRIVER( pacapp ) /* Paca Paca Passion (PPP1/VERA) */
|
||||
DRIVER( sws99 ) /* Super World Stadium '99 (SS91/VER.A) */
|
||||
DRIVER( tekkentt ) /* Tekken Tag Tournament (TEG3/VER.B) */
|
||||
DRIVER( mrdrillr ) /* Mr Driller (DRI1/VER.A) */
|
||||
DRIVER( aquarush ) /* Aqua Rush (AQ1/VER.A) */
|
||||
DRIVER( golgo13 ) /* Golgo 13 (GLG1/VER.A) */
|
||||
DRIVER( tekken3 ) /* Tekken 3 (World, TET2/VER.E1) */
|
||||
DRIVER( tekken3a ) /* Tekken 3 (World, TET2/VER.A) */
|
||||
DRIVER( tekken3b ) /* Tekken 3 (World, TET2/VER.B) */
|
||||
DRIVER( tekken3c ) /* Tekken 3 (World, TET2/VER.C) */
|
||||
DRIVER( tekken3d ) /* Tekken 3 (World, TET2/VER.D) */
|
||||
DRIVER( tekken3ua ) /* Tekken 3 (US, TET3/VER.A) */
|
||||
DRIVER( tekken3ud ) /* Tekken 3 (US, TET3/VER.D) */
|
||||
DRIVER( tekken3ja ) /* Tekken 3 (Japan, TET1/VER.A) */
|
||||
DRIVER( tekken3jd ) /* Tekken 3 (Japan, TET1/VER.D) */
|
||||
DRIVER( tekken3je1 ) /* Tekken 3 (Japan, TET1/VER.E1) */
|
||||
DRIVER( lbgrande ) /* Libero Grande (World, LG2/VER.A) */
|
||||
DRIVER( toukon3 ) /* Shin Nihon Pro Wrestling Toukon Retsuden 3 Arcade Edition (Japan, TR1/VER.A) */
|
||||
DRIVER( soulclbr ) /* Soul Calibur (World, SOC12/VER.A2) */
|
||||
DRIVER( soulclbrab ) /* Soul Calibur (Asia, SOC14/VER.B) */
|
||||
DRIVER( soulclbrac ) /* Soul Calibur (Asia, SOC14/VER.C) */
|
||||
DRIVER( soulclbrub ) /* Soul Calibur (US, SOC13/VER.B) */
|
||||
DRIVER( soulclbruc ) /* Soul Calibur (US, SOC13/VER.C) */
|
||||
DRIVER( soulclbrja2 ) /* Soul Calibur (Japan, SOC11/VER.A2) */
|
||||
DRIVER( soulclbrjb ) /* Soul Calibur (Japan, SOC11/VER.B) */
|
||||
DRIVER( soulclbrjc ) /* Soul Calibur (Japan, SOC11/VER.C) */
|
||||
DRIVER( ehrgeiz ) /* Ehrgeiz (World, EG2/VER.A) */
|
||||
DRIVER( ehrgeizua ) /* Ehrgeiz (US, EG3/VER.A) */
|
||||
DRIVER( ehrgeizja ) /* Ehrgeiz (Japan, EG1/VER.A) */
|
||||
DRIVER( sws98 ) /* Super World Stadium '98 (Japan, SS81/VER.A) */
|
||||
DRIVER( mdhorse ) /* Derby Quiz My Dream Horse (Japan, MDH1/VER.A2) */
|
||||
DRIVER( tenkomor ) /* Tenkomori Shooting (World, TKM2/VER.A1) */
|
||||
DRIVER( tenkomorja1 ) /* Tenkomori Shooting (Japan, TKM1/VER.A1) */
|
||||
DRIVER( fgtlayer ) /* Fighting Layer (Asia, FTL3/VER.A) */
|
||||
DRIVER( fgtlayerja ) /* Fighting Layer (Japan, FTL0/VER.A) */
|
||||
DRIVER( pacapp ) /* Paca Paca Passion (Japan, PPP1/VER.A2) */
|
||||
DRIVER( ptblank2 ) /* Point Blank 2 (World, GNB5/VER.A) */
|
||||
DRIVER( gunbarl ) /* Gunbarl (Japan, GNB4/VER.A) */
|
||||
DRIVER( sws99 ) /* Super World Stadium '99 (Japan, SS91/VER.A3) */
|
||||
DRIVER( tektagt ) /* Tekken Tag Tournament (World, TEG2/VER.C1) */
|
||||
DRIVER( tektagtc1a ) /* Tekken Tag Tournament (World, TEG2/VER.C1, set 2) */
|
||||
DRIVER( tektagtub ) /* Tekken Tag Tournament (US, TEG3/VER.B) */
|
||||
DRIVER( tektagtuc1 ) /* Tekken Tag Tournament (US, TEG3/VER.C1) */
|
||||
DRIVER( tektagtja3 ) /* Tekken Tag Tournament (Japan, TEG1/VER.A3) */
|
||||
DRIVER( tektagtjb ) /* Tekken Tag Tournament (Japan, TEG1/VER.B) */
|
||||
DRIVER( tektagtjc1 ) /* Tekken Tag Tournament (Japan, TEG1/VER.C1) */
|
||||
DRIVER( ghlpanic ) /* Ghoul Panic (World, OB2/VER.A) */
|
||||
DRIVER( ohbakyuun ) /* Oh! Bakyuuun (Japan, OB1/VER.A) */
|
||||
DRIVER( pacapp2 ) /* Paca Paca Passion 2 (Japan, PKS1/VER.A) */
|
||||
DRIVER( mrdrillr ) /* Mr. Driller (US, DRI3/VER.A2) */
|
||||
DRIVER( mrdrillrja2 ) /* Mr. Driller (Japan, DRI1/VER.A2) */
|
||||
DRIVER( kaiunqz ) /* Kaiun Quiz (Japan, KW1/VER.A) */
|
||||
DRIVER( pacappsp ) /* Paca Paca Passion Special (Japan, PSP1/VER.A) */
|
||||
DRIVER( aquarush ) /* Aqua Rush (Japan, AQ1/VER.A1) */
|
||||
DRIVER( golgo13 ) /* Golgo 13 (Japan, GLG1/VER.A) */
|
||||
DRIVER( sws2000 ) /* Super World Stadium 2000 (Japan, SS01/VER.A) */
|
||||
DRIVER( kartduel ) /* Kart Duel (World, KTD2/VER.A) */
|
||||
DRIVER( kartduelja ) /* Kart Duel (Japan, KTD1/VER.A) */
|
||||
DRIVER( g13knd ) /* Golgo 13 Kiseki no Dandou (Japan, GLS1/VER.A) */
|
||||
|
||||
/* Namco System 10 */
|
||||
DRIVER( mrdrilr2 ) /* Mr Driller 2 */
|
||||
@@ -2907,9 +3123,9 @@ V-V TP-027
|
||||
DRIVER( sscandal ) /* 834-5755 (c) 1985 Coreland / Sega (S1) */
|
||||
DRIVER( myherok ) /* 834-5755 (c) 1985 Coreland / Sega (S1) */
|
||||
DRIVER( shtngmst ) /* 834-5719/5720 (c) 1985 (S2) */
|
||||
DRIVER( chplft ) /* 834-5795 (c) 1985, (c) 1982 Dan Gorlin (S2) */
|
||||
DRIVER( chplftb ) /* 834-5795 (c) 1985, (c) 1982 Dan Gorlin (S2) */
|
||||
DRIVER( chplftbl ) /* bootleg (S2) */
|
||||
DRIVER( choplift ) /* 834-5795 (c) 1985, (c) 1982 Dan Gorlin (S2) */
|
||||
DRIVER( chopliftu ) /* 834-5795 (c) 1985, (c) 1982 Dan Gorlin (S2) */
|
||||
DRIVER( chopliftbl ) /* bootleg (S2) */
|
||||
DRIVER( 4dwarrio ) /* 834-5918 (c) 1985 Coreland / Sega (S1) */
|
||||
DRIVER( brain ) /* (c) 1986 Coreland / Sega (S2?) */
|
||||
DRIVER( raflesia ) /* 834-5753 (c) 1985 Coreland / Sega (S1) */
|
||||
@@ -3162,6 +3378,8 @@ Sep.1994 Quiz Ghost Hunter
|
||||
DRIVER( harddunj ) /* (c) 1994 (Japan) */
|
||||
DRIVER( titlef ) /* (c) 1992 */
|
||||
DRIVER( scross ) /* (c) 1992 (World) */
|
||||
DRIVER( scrossa ) /* (c) 1992 (World, linkable) */
|
||||
DRIVER( scrossu ) /* (c) 1992 (US) */
|
||||
|
||||
/* Sega ST-V games */
|
||||
DRIVER( astrass )
|
||||
@@ -3353,12 +3571,16 @@ BOMULEUL CHAJARA SEGA ST-V 1997/04/11
|
||||
/* Sega MegaPlay */
|
||||
DRIVER( mp_sonic ) /* 01 */
|
||||
DRIVER( mp_gaxe2 ) /* 02 */
|
||||
DRIVER( mp_gslam ) /* 03 */
|
||||
DRIVER( mp_sor2 ) /* 03 */
|
||||
DRIVER( mp_twc ) /* 04 */
|
||||
DRIVER( mp_soni2 ) /* 05 */
|
||||
DRIVER( mp_bio ) /* 06 */
|
||||
DRIVER( mp_shnb3 ) /* 07 */
|
||||
DRIVER( mp_col3 ) /* 10 */
|
||||
DRIVER( mp_gunhe ) /* 10 */
|
||||
DRIVER( mp_mazin ) /* 11 */
|
||||
DRIVER( mp_col3 ) /* ?? */
|
||||
DRIVER( mp_addams )
|
||||
|
||||
/* Data East "Burger Time hardware" games */
|
||||
DRIVER( lnc ) /* (c) 1981 */
|
||||
@@ -4825,13 +5047,17 @@ BOMULEUL CHAJARA SEGA ST-V 1997/04/11
|
||||
|
||||
/* Midway / Atari Voodoo based Hardware (Seattle, Flagstaff) */
|
||||
DRIVER ( wg3dh ) /* (c) 1996 Atari Games */
|
||||
DRIVER ( wg3dhfe ) /* (c) 1996 Atari Games */
|
||||
DRIVER ( mace ) /* (c) 1996 Atari Games */
|
||||
DRIVER ( macea ) /* (c) 1997 Atari Games */
|
||||
DRIVER ( sfrush ) /* (c) 1996 Atari Games */
|
||||
DRIVER ( sfrushrk ) /* (c) 1997 Atari Games */
|
||||
DRIVER ( calspeed ) /* (c) 1996 Atari Games */
|
||||
DRIVER ( carnevil ) /* (c) 1998 Midway Games */
|
||||
DRIVER ( biofreak ) /* (c) 1997 Midway Games */
|
||||
DRIVER ( blitz ) /* (c) 1997 Midway Games */
|
||||
DRIVER ( blitz99 ) /* (c) 1998 Midway Games */
|
||||
DRIVER ( blitz99a ) /* (c) 1998 Midway Games */
|
||||
DRIVER ( blitz2k ) /* (c) 1999 Midway Games */
|
||||
|
||||
/* Cinematronics raster games */
|
||||
@@ -4931,7 +5157,52 @@ BOMULEUL CHAJARA SEGA ST-V 1997/04/11
|
||||
DRIVER( sengokmj ) /* (c) 1991 Sigma */
|
||||
|
||||
|
||||
DRIVER( raiden2 )
|
||||
DRIVER( raiden2 ) /* Raiden II (US, set 1) */
|
||||
DRIVER( raiden2g ) /* Raiden II (Germany) */
|
||||
DRIVER( raiden2gb ) /* Raiden II (Great Britain) */
|
||||
DRIVER( raiden2hk ) /* Raiden II (Hong Kong) */
|
||||
DRIVER( raiden2j ) /* Raiden II (Japan) */
|
||||
DRIVER( raiden2sw ) /* Raiden II (Switzerland) */
|
||||
DRIVER( raiden2u ) /* Raiden II (US, set 2) */
|
||||
DRIVER( raiden2f ) /* Raiden II (France) */
|
||||
DRIVER( raiden2nl ) /* Raiden II (Holland) */
|
||||
DRIVER( raiden2es ) /* Raiden II (Spain) */
|
||||
DRIVER( raiden2i ) /* Raiden II (Italy) */
|
||||
DRIVER( raiden2au ) /* Raiden II (Australia) */
|
||||
DRIVER( raiden2e ) /* Raiden II (easier, Korea) */
|
||||
DRIVER( raiden2eub ) /* Raiden II (easier, US set 3) */
|
||||
DRIVER( raiden2eua ) /* Raiden II (easier, US set 1) */
|
||||
DRIVER( raiden2eg ) /* Raiden II (easier, Germany) */
|
||||
DRIVER( raiden2eup ) /* Raiden II (easier, US, prototype? 11-16) */
|
||||
DRIVER( raiden2ea ) /* Raiden II (easier, Japan) */
|
||||
DRIVER( raiden2eu ) /* Raiden II (easier, US set 2) */
|
||||
DRIVER( raiden2k ) /* Raiden II (harder, Korea) */
|
||||
DRIVER( raiden2dx ) /* Raiden II (harder, Raiden DX hardware, Korea) */
|
||||
DRIVER( raidendx ) /* Raiden DX (UK) */
|
||||
DRIVER( raidendxg ) /* Raiden DX (Germany) */
|
||||
DRIVER( raidendxpt ) /* Raiden DX (Portugal) */
|
||||
DRIVER( raidendxa1 ) /* Raiden DX (Hong Kong, set 1) */
|
||||
DRIVER( raidendxa2 ) /* Raiden DX (Hong Kong, set 2) */
|
||||
DRIVER( raidendxk ) /* Raiden DX (Korea) */
|
||||
DRIVER( raidendxu ) /* Raiden DX (US) */
|
||||
DRIVER( raidendxnl ) /* Raiden DX (Holland) */
|
||||
DRIVER( raidendxj ) /* Raiden DX (Japan, set 1) */
|
||||
DRIVER( raidendxja ) /* Raiden DX (Japan, set 2) */
|
||||
DRIVER( raidendxch ) /* Raiden DX (China) */
|
||||
DRIVER( zeroteam ) /* Zero Team USA (US) */
|
||||
DRIVER( zeroteama ) /* Zero Team (Japan?, earlier?, set 1) */
|
||||
DRIVER( zeroteamb ) /* Zero Team (Japan?, later batteryless) */
|
||||
DRIVER( zeroteamc ) /* Zero Team (Taiwan) */
|
||||
DRIVER( zeroteamd ) /* Zero Team (Korea) */
|
||||
DRIVER( zeroteame ) /* Zero Team (Japan?, earlier?, set 2) */
|
||||
DRIVER( zeroteams ) /* Zero Team Selection */
|
||||
DRIVER( zeroteamsr ) /* Zero Team Suicide Revival Kit */
|
||||
DRIVER( r2dx_v33 ) /* Raiden II New / Raiden DX (newer V33 PCB) (Raiden DX EEPROM) */
|
||||
DRIVER( r2dx_v33_r2 ) /* Raiden II New / Raiden DX (newer V33 PCB) (Raiden II EEPROM) */
|
||||
DRIVER( nzeroteam ) /* New Zero Team (V33 SYSTEM TYPE_B hardware) */
|
||||
DRIVER( nzeroteama ) /* New Zero Team (V33 SYSTEM TYPE_B hardware, Zhongguo Shantou Yihuang license) */
|
||||
DRIVER( nzeroteamb ) /* New Zero Team (V33 SYSTEM TYPE_B hardware, Haoyunlai Trading Company license) */
|
||||
DRIVER( zerotm2k ) /* Zero Team 2000 */
|
||||
|
||||
/* Seibu STI System games:
|
||||
Viper: Phase 1 (c) 1995
|
||||
@@ -5035,20 +5306,26 @@ BOMULEUL CHAJARA SEGA ST-V 1997/04/11
|
||||
DRIVER( cybattlr ) /* (c) 1993 */
|
||||
DRIVER( peekaboo ) /* (c) 1993 */
|
||||
|
||||
/* Jaleco Mega System 1 games */
|
||||
DRIVER( hayaosi1 ) /* (c) 1994 */
|
||||
/* Jaleco Mega System 32 games */
|
||||
DRIVER( hayaosi2 ) /* (c) 1994 */
|
||||
DRIVER( hayaosi3 ) /* (c) 1994 */
|
||||
DRIVER( hayaosi3a ) /* (c) 1994 */
|
||||
DRIVER( bbbxing ) /* (c) 1994 */
|
||||
DRIVER( 47pie2 ) /* (c) 1994 */
|
||||
DRIVER( 47pie2o ) /* (c) 1994 */
|
||||
DRIVER( suchie2 ) /* (c) 1994 */
|
||||
DRIVER( suchie2o ) /* (c) 1994 */
|
||||
DRIVER( desertwr ) /* (c) 1995 */
|
||||
DRIVER( gametngk ) /* (c) 1995 */
|
||||
DRIVER( tetrisp ) /* (c) 1995 Jaleco / BPS */
|
||||
DRIVER( p47aces ) /* (c) 1995 */
|
||||
DRIVER( p47acesa ) /* (c) 1995 */
|
||||
DRIVER( akiss ) /* (c) 1995 */
|
||||
DRIVER( akissa ) /* (c) 1995 */
|
||||
DRIVER( gratia ) /* (c) 1996 */
|
||||
DRIVER( gratiaa ) /* (c) 1996 */
|
||||
DRIVER( kirarast ) /* (c) 1996 */
|
||||
DRIVER( kirarasta ) /* (c) 1996 */
|
||||
DRIVER( tp2m32 ) /* (c) 1997 */
|
||||
DRIVER( wpksocv2 ) /* (c) 1996 */
|
||||
DRIVER( f1superb ) /* (c) 1994 */
|
||||
|
||||
/* Video System Co. games */
|
||||
@@ -5656,13 +5933,76 @@ Other Sun games
|
||||
DRIVER( kov ) /* (c) 1999 */
|
||||
DRIVER( kovplus ) /* (c) 1999 */
|
||||
DRIVER( kov115 ) /* (c) 1999 */
|
||||
DRIVER( kovsh ) /* (c) 1999 */
|
||||
DRIVER( photoy2k ) /* (c) 1999 */
|
||||
DRIVER( puzlstar ) /* (c) 1999 */
|
||||
DRIVER( puzzli2 ) /* (c) 1999 */
|
||||
DRIVER( puzzli2s ) /* (c) 2001 */
|
||||
DRIVER( py2k2 ) /* (c) 2001 */
|
||||
DRIVER( ddp2 ) /* (c) 2001 */
|
||||
DRIVER( ddp2 ) /* (c) 2001 IGS */
|
||||
DRIVER( ddp2101 ) /* (c) 2001 IGS */
|
||||
DRIVER( ddp2100 ) /* (c) 2001 IGS */
|
||||
DRIVER( ddp2hk ) /* (c) 2001 IGS */
|
||||
DRIVER( ddp2101hk ) /* (c) 2001 IGS */
|
||||
DRIVER( ddp2100hk ) /* (c) 2001 IGS */
|
||||
DRIVER( ddp2k ) /* (c) 2001 IGS */
|
||||
DRIVER( ddp2101k ) /* (c) 2001 IGS */
|
||||
DRIVER( ddp2100k ) /* (c) 2001 IGS */
|
||||
DRIVER( ddp2j ) /* (c) 2001 IGS */
|
||||
DRIVER( ddp2101j ) /* (c) 2001 IGS */
|
||||
DRIVER( ddp2100j ) /* (c) 2001 IGS */
|
||||
DRIVER( ddp2t ) /* (c) 2001 IGS */
|
||||
DRIVER( ddp2101t ) /* (c) 2001 IGS */
|
||||
DRIVER( ddp2100t ) /* (c) 2001 IGS */
|
||||
DRIVER( ddp2c ) /* (c) 2001 IGS */
|
||||
DRIVER( ddp2101c ) /* (c) 2001 IGS */
|
||||
DRIVER( ddp2100c ) /* (c) 2001 IGS */
|
||||
DRIVER( kov2 ) /* (c) 2000 IGS */
|
||||
DRIVER( kov2106 ) /* (c) 2000 IGS */
|
||||
DRIVER( kov2104 ) /* (c) 2000 IGS */
|
||||
DRIVER( kov2103 ) /* (c) 2000 IGS */
|
||||
DRIVER( kov21022 ) /* (c) 2000 IGS */
|
||||
DRIVER( kov2102 ) /* (c) 2000 IGS */
|
||||
DRIVER( kov2101 ) /* (c) 2000 IGS */
|
||||
DRIVER( kov2100 ) /* (c) 2000 IGS */
|
||||
DRIVER( kov2p ) /* (c) 2001 IGS */
|
||||
DRIVER( kov2p204 ) /* (c) 2001 IGS */
|
||||
DRIVER( kov2p203 ) /* (c) 2001 IGS */
|
||||
DRIVER( kov2p202 ) /* (c) 2001 IGS */
|
||||
DRIVER( kov2p200 ) /* (c) 2001 IGS */
|
||||
DRIVER( martmast ) /* (c) 2001 IGS */
|
||||
DRIVER( martmast104c ) /* (c) 2001 IGS */
|
||||
DRIVER( martmast103c ) /* (c) 2001 IGS */
|
||||
DRIVER( martmast102c ) /* (c) 2001 IGS */
|
||||
DRIVER( dw2001 ) /* (c) 2001 IGS */
|
||||
DRIVER( dwpc ) /* (c) 2001 IGS */
|
||||
DRIVER( dwpc101j ) /* (c) 2001 IGS */
|
||||
DRIVER( dmnfrnt ) /* (c) 2002 IGS */
|
||||
DRIVER( dmnfrnt103 ) /* (c) 2002 IGS */
|
||||
DRIVER( dmnfrnt102 ) /* (c) 2002 IGS */
|
||||
DRIVER( dmnfrntpcb ) /* (c) 2002 IGS */
|
||||
DRIVER( theglad ) /* (c) 2003 IGS */
|
||||
DRIVER( theglad104 ) /* (c) 2003 IGS */
|
||||
DRIVER( theglad101 ) /* (c) 2003 IGS */
|
||||
DRIVER( theglad100 ) /* (c) 2003 IGS */
|
||||
DRIVER( thegladpcb ) /* (c) 2003 IGS (Alta/AMI license) */
|
||||
DRIVER( thegladpcba ) /* (c) 2003 IGS (Alta/AMI license) */
|
||||
DRIVER( svg ) /* (c) 2005 IGS / Idea Factory */
|
||||
DRIVER( svghk ) /* (c) 2005 IGS / Idea Factory */
|
||||
DRIVER( svgtw ) /* (c) 2005 IGS / Idea Factory */
|
||||
DRIVER( svgpcb ) /* (c) 2005 IGS / Idea Factory (AMI license) */
|
||||
DRIVER( killbldp ) /* (c) 2005 IGS */
|
||||
DRIVER( happy6 ) /* (c) 2004 IGS */
|
||||
DRIVER( happy6101 ) /* (c) 2004 IGS */
|
||||
DRIVER( happy6100hk ) /* (c) 2004 IGS */
|
||||
DRIVER( happy6100cn ) /* (c) 2004 IGS */
|
||||
DRIVER( kovsh ) /* (c) 1999 IGS */
|
||||
DRIVER( kovsh103 ) /* (c) 1999 IGS */
|
||||
DRIVER( kovsh102 ) /* (c) 1999 IGS */
|
||||
DRIVER( kovsh101 ) /* (c) 1999 IGS */
|
||||
DRIVER( kovsh100 ) /* (c) 1999 IGS */
|
||||
DRIVER( photoy2k ) /* (c) 1999 IGS */
|
||||
DRIVER( photoy2k104 ) /* (c) 1999 IGS */
|
||||
DRIVER( photoy2k103j ) /* (c) 1999 IGS */
|
||||
DRIVER( photoy2k102j ) /* (c) 1999 IGS */
|
||||
|
||||
/* RamTek games */
|
||||
DRIVER( hitme ) /* [1976 Ramtek] */
|
||||
@@ -5704,7 +6044,13 @@ Other Sun games
|
||||
/* Rare games */
|
||||
DRIVER( btoads ) /* (c) 1994 Rare */
|
||||
DRIVER( kinst ) /* (c) 1994 Rare */
|
||||
DRIVER( kinst2 ) /* (c) 1994 Rare */
|
||||
DRIVER( kinst14 ) /* (c) 1994 Rare */
|
||||
DRIVER( kinst13 ) /* (c) 1994 Rare */
|
||||
DRIVER( kinstp ) /* (c) 1994 Rare */
|
||||
DRIVER( kinst2 ) /* (c) 1996 Rare */
|
||||
DRIVER( kinst213 ) /* (c) 1996 Rare */
|
||||
DRIVER( kinst211 ) /* (c) 1996 Rare */
|
||||
DRIVER( kinst210 ) /* (c) 1996 Rare */
|
||||
|
||||
/* Nihon System games */
|
||||
DRIVER( gigasb )
|
||||
@@ -6155,7 +6501,99 @@ Other Sun games
|
||||
|
||||
/* Sega Model 1 Hardware */
|
||||
DRIVER( vr ) /* (c) 1992 Sega */
|
||||
DRIVER( vformula ) /* (c) 1993 Sega */
|
||||
DRIVER( vf ) /* (c) 1993 Sega */
|
||||
DRIVER( swa ) /* (c) 1994 Sega */
|
||||
DRIVER( swaj )
|
||||
DRIVER( wingwar ) /* (c) 1994 Sega */
|
||||
DRIVER( wingwaru )
|
||||
DRIVER( wingwarj )
|
||||
DRIVER( wingwar360 )
|
||||
DRIVER( netmerc ) /* (c) 1993 Sega */
|
||||
DRIVER( vf2 ) /* (c) 1994 Sega, Model 2A */
|
||||
DRIVER( vf2b )
|
||||
DRIVER( vf2a )
|
||||
DRIVER( vf2o )
|
||||
DRIVER( vcop2 ) /* (c) 1995 Sega, Model 2A */
|
||||
DRIVER( motoraid ) /* (c) 1997 Sega, Model 2A */
|
||||
DRIVER( motoraiddx )
|
||||
DRIVER( skytargt ) /* (c) 1995 Sega, Model 2A */
|
||||
DRIVER( airwlkrs ) /* (c) 1997 Data East, Model 2A */
|
||||
DRIVER( manxtt ) /* (c) 1995 Sega, Model 2A */
|
||||
DRIVER( manxttc )
|
||||
DRIVER( manxttdx )
|
||||
DRIVER( hpyagu98 ) /* (c) 1998 Deniam, Model 2A */
|
||||
DRIVER( srallyc ) /* (c) 1995 Sega, Model 2A */
|
||||
DRIVER( srallycb )
|
||||
DRIVER( srallycc )
|
||||
DRIVER( srallycdx )
|
||||
DRIVER( srallycdxa )
|
||||
DRIVER( vcop ) /* (c) 1994 Sega, original Model 2 */
|
||||
DRIVER( vcopa )
|
||||
DRIVER( desert ) /* 1994 Sega / Martin Marietta - original Model 2 */
|
||||
DRIVER( daytona ) /* (c) 1994 Sega, original Model 2 */
|
||||
DRIVER( daytonase )
|
||||
DRIVER( daytona93 ) /* (c) 1993 Sega */
|
||||
DRIVER( daytonas )
|
||||
DRIVER( daytonat )
|
||||
DRIVER( daytonata )
|
||||
DRIVER( daytonam )
|
||||
DRIVER( daytonagtx )
|
||||
DRIVER( vstriker ) /* (c) 1994 Sega, Model 2B */
|
||||
DRIVER( vstrikero )
|
||||
DRIVER( gunblade ) /* (c) 1995 Sega, Model 2B */
|
||||
DRIVER( rchase2 ) /* (c) 1994 Sega, Model 2B */
|
||||
DRIVER( rchase2a )
|
||||
DRIVER( doa ) /* (c) 1996 Tecmo, Model 2B */
|
||||
DRIVER( doab ) /* (c) 1996 Tecmo, Model 2B */
|
||||
DRIVER( doaa ) /* (c) 1996 Tecmo, Model 2A */
|
||||
DRIVER( doaab )
|
||||
DRIVER( doaae )
|
||||
DRIVER( zerogun ) /* (c) 1997 Psikyo, Model 2B */
|
||||
DRIVER( zerogunj ) /* (c) 1997 Psikyo, Model 2B */
|
||||
DRIVER( zeroguna ) /* (c) 1997 Psikyo, Model 2A */
|
||||
DRIVER( zerogunaj )
|
||||
DRIVER( fvipers ) /* 1995 Sega - Model 2B */
|
||||
DRIVER( fvipersb )
|
||||
DRIVER( fvipersa )
|
||||
DRIVER( von ) /* 1995 Sega - Model 2B */
|
||||
DRIVER( vonu )
|
||||
DRIVER( vonj )
|
||||
DRIVER( schamp ) /* 1996 Sega - Model 2B */
|
||||
DRIVER( sfight )
|
||||
DRIVER( lastbrnx ) /* 1996 Sega - Model 2B */
|
||||
DRIVER( lastbrnxu )
|
||||
DRIVER( lastbrnxj )
|
||||
DRIVER( dynamcop ) /* 1998 Sega - Model 2A / 2B */
|
||||
DRIVER( dyndeka2 )
|
||||
DRIVER( dynamcopb )
|
||||
DRIVER( dynamcopc ) /* Model 2C */
|
||||
DRIVER( dyndeka2b )
|
||||
DRIVER( dynabb ) /* 1996 Sega - Model 2B */
|
||||
DRIVER( dynabb97 ) /* 1997 Sega - Model 2B */
|
||||
DRIVER( indy500 ) /* 1995 Sega - Model 2B */
|
||||
DRIVER( indy500d )
|
||||
DRIVER( indy500to )
|
||||
DRIVER( sgt24h ) /* 1996 Jaleco - Model 2B */
|
||||
DRIVER( stcc ) /* 1996 Sega - Model 2C */
|
||||
DRIVER( stccb )
|
||||
DRIVER( stcca )
|
||||
DRIVER( stcco )
|
||||
DRIVER( waverunr ) /* 1996 Sega - Model 2C */
|
||||
DRIVER( skisuprg ) /* 1996 Sega - Model 2C */
|
||||
DRIVER( bel ) /* 1997 Sega / EPL - Model 2C */
|
||||
DRIVER( hotd ) /* 1997 Sega - Model 2C */
|
||||
DRIVER( hotdo )
|
||||
DRIVER( segawski ) /* 1997 Sega - Model 2C */
|
||||
DRIVER( topskatr ) /* 1997 Sega - Model 2C */
|
||||
DRIVER( topskatru )
|
||||
DRIVER( topskatruo )
|
||||
DRIVER( topskatrj )
|
||||
DRIVER( overrev ) /* Model 2C */
|
||||
DRIVER( overrevb ) /* Model 2B */
|
||||
DRIVER( overrevba )
|
||||
DRIVER( pltkids ) /* (c) 1998 Psikyo, Model 2B */
|
||||
DRIVER( pltkidsa ) /* (c) 1998 Psikyo, Model 2A */
|
||||
|
||||
/* Oriental Soft */
|
||||
DRIVER( 1945kiii ) /* (c) 2000 Oriental */
|
||||
|
||||
+21
-6
@@ -8,6 +8,7 @@ Preliminary driver by:
|
||||
***************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "state.h"
|
||||
#include "vidhrdw/generic.h"
|
||||
#include "cpu/konami/konami.h" /* for the callback and the firq irq definition */
|
||||
#include "vidhrdw/konamiic.h"
|
||||
@@ -434,26 +435,33 @@ ROM_END
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
static void aliens_banking( int lines )
|
||||
static int aliens_rombank = 0x10; /* CPU ROM bank lines, kept for save states */
|
||||
|
||||
static void aliens_rombank_set(void)
|
||||
{
|
||||
unsigned char *RAM = memory_region(REGION_CPU1);
|
||||
int lines = aliens_rombank;
|
||||
int offs = 0x18000;
|
||||
|
||||
|
||||
if (lines & 0x10) offs -= 0x8000;
|
||||
|
||||
offs += (lines & 0x0f)*0x2000;
|
||||
cpu_setbank( 1, &RAM[offs] );
|
||||
}
|
||||
|
||||
static void aliens_banking( int lines )
|
||||
{
|
||||
aliens_rombank = lines;
|
||||
aliens_rombank_set();
|
||||
}
|
||||
|
||||
static MACHINE_INIT( aliens )
|
||||
{
|
||||
unsigned char *RAM = memory_region(REGION_CPU1);
|
||||
|
||||
konami_cpu_setlines_callback = aliens_banking;
|
||||
|
||||
/* init the default bank */
|
||||
cpu_setbank( 1, &RAM[0x10000] );
|
||||
/* init the default bank (0x10000) */
|
||||
aliens_rombank = 0x10;
|
||||
aliens_rombank_set();
|
||||
}
|
||||
|
||||
|
||||
@@ -462,6 +470,13 @@ static DRIVER_INIT( aliens )
|
||||
{
|
||||
konami_rom_deinterleave_2(REGION_GFX1);
|
||||
konami_rom_deinterleave_2(REGION_GFX2);
|
||||
|
||||
/* Save the ROM bank and the work RAM / palette switch, and map the
|
||||
saved bank again after loading, so a loaded save state runs the
|
||||
right code */
|
||||
state_save_register_int("aliens", 0, "rombank", &aliens_rombank);
|
||||
state_save_register_int("aliens", 0, "palette_selected", &palette_selected);
|
||||
state_save_register_func_postload(aliens_rombank_set);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+36
-36
@@ -199,16 +199,15 @@ INPUT_PORTS_START( brkthru )
|
||||
PORT_DIPSETTING( 0x03, "3" )
|
||||
PORT_DIPSETTING( 0x01, "5" )
|
||||
PORT_BITX(0, 0x00, IPT_DIPSWITCH_SETTING | IPF_CHEAT, "99", IP_KEY_NONE, IP_JOY_NONE )
|
||||
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Bonus_Life ) )
|
||||
PORT_DIPSETTING( 0x00, "20000 Points Only" )
|
||||
PORT_DIPSETTING( 0x04, "10000/20000 Points" )
|
||||
PORT_DIPSETTING( 0x0c, "20000/30000 Points" )
|
||||
PORT_DIPSETTING( 0x08, "20000/40000 Points" )
|
||||
PORT_DIPNAME( 0x10, 0x10, "Allow Continue" )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( No ) )
|
||||
PORT_DIPSETTING( 0x10, DEF_STR( Yes ) )
|
||||
PORT_BIT_IMPULSE( 0x20, IP_ACTIVE_LOW, IPT_COIN1, 2 )
|
||||
PORT_BIT_IMPULSE( 0x20, IP_ACTIVE_LOW, IPT_COIN1, 2 ) /* Manual says Pitcure Flip=On, Normal=Off */
|
||||
PORT_BIT_IMPULSE( 0x40, IP_ACTIVE_LOW, IPT_COIN2, 2 )
|
||||
PORT_BIT_IMPULSE( 0x80, IP_ACTIVE_LOW, IPT_SERVICE1, 2 )
|
||||
|
||||
@@ -223,17 +222,18 @@ INPUT_PORTS_START( brkthru )
|
||||
PORT_DIPSETTING( 0x0c, DEF_STR( 1C_1C ) )
|
||||
PORT_DIPSETTING( 0x08, DEF_STR( 1C_2C ) )
|
||||
PORT_DIPSETTING( 0x04, DEF_STR( 1C_3C ) )
|
||||
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0xc0, 0x00, DEF_STR( Cabinet ) )
|
||||
PORT_DIPSETTING( 0x00, "Upright 1 Player" )
|
||||
PORT_DIPSETTING( 0x40, "Upright 2 Players" )
|
||||
/* PORT_DIPSETTING( 0x80, DEF_STR( Cocktail ) ) */ /* "Cocktail 1 Player" - IMPOSSIBLE !*/
|
||||
PORT_DIPSETTING( 0xc0, DEF_STR( Cocktail ) ) /* "Cocktail 2 Players"*/
|
||||
PORT_DIPNAME( 0x10, 0x10, "Enemy Vehicles" )
|
||||
PORT_DIPSETTING( 0x10, "Slow" )
|
||||
PORT_DIPSETTING( 0x00, "Fast" )
|
||||
PORT_DIPNAME( 0x20, 0x20, "Enemy Bullets" )
|
||||
PORT_DIPSETTING( 0x20, "Slow" )
|
||||
PORT_DIPSETTING( 0x00, "Fast" )
|
||||
PORT_DIPNAME( 0x40, 0x00, "Control Panel" )
|
||||
PORT_DIPSETTING( 0x40, DEF_STR( Upright ) ) /* 1 Player */
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) ) /* 2 Players */
|
||||
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Cabinet ) )
|
||||
PORT_DIPSETTING( 0x80, DEF_STR( Upright ) )
|
||||
PORT_DIPSETTING( 0xc0, DEF_STR( Cocktail ) )
|
||||
INPUT_PORTS_END
|
||||
|
||||
INPUT_PORTS_START( brkthruj )
|
||||
@@ -263,14 +263,13 @@ INPUT_PORTS_START( brkthruj )
|
||||
PORT_DIPSETTING( 0x03, "3" )
|
||||
PORT_DIPSETTING( 0x01, "5" )
|
||||
PORT_BITX(0, 0x00, IPT_DIPSWITCH_SETTING | IPF_CHEAT, "99", IP_KEY_NONE, IP_JOY_NONE )
|
||||
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Bonus_Life ) )
|
||||
PORT_DIPSETTING( 0x00, "20000 Points Only" )
|
||||
PORT_DIPSETTING( 0x04, "10000/20000 Points" )
|
||||
PORT_DIPSETTING( 0x0c, "20000/30000 Points" )
|
||||
PORT_DIPSETTING( 0x08, "20000/40000 Points" )
|
||||
PORT_SERVICE( 0x10, IP_ACTIVE_LOW )
|
||||
PORT_BIT_IMPULSE( 0x20, IP_ACTIVE_LOW, IPT_COIN1, 2 )
|
||||
PORT_BIT_IMPULSE( 0x20, IP_ACTIVE_LOW, IPT_COIN1, 2 ) /* Manual says Pitcure Flip=On, Normal=Off */
|
||||
PORT_BIT_IMPULSE( 0x40, IP_ACTIVE_LOW, IPT_COIN2, 2 )
|
||||
PORT_BIT_IMPULSE( 0x80, IP_ACTIVE_LOW, IPT_SERVICE1, 2 )
|
||||
|
||||
@@ -285,17 +284,18 @@ INPUT_PORTS_START( brkthruj )
|
||||
PORT_DIPSETTING( 0x0c, DEF_STR( 1C_1C ) )
|
||||
PORT_DIPSETTING( 0x08, DEF_STR( 1C_2C ) )
|
||||
PORT_DIPSETTING( 0x04, DEF_STR( 1C_3C ) )
|
||||
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0xc0, 0x00, DEF_STR( Cabinet ) )
|
||||
PORT_DIPSETTING( 0x00, "Upright 1 Player" )
|
||||
PORT_DIPSETTING( 0x40, "Upright 2 Players" )
|
||||
/* PORT_DIPSETTING( 0x80, DEF_STR( Cocktail ) ) */ /* "Cocktail 1 Player" - IMPOSSIBLE !*/
|
||||
PORT_DIPSETTING( 0xc0, DEF_STR( Cocktail ) ) /* "Cocktail 2 Players"*/
|
||||
PORT_DIPNAME( 0x10, 0x10, "Enemy Vehicles" )
|
||||
PORT_DIPSETTING( 0x10, "Slow" )
|
||||
PORT_DIPSETTING( 0x00, "Fast" )
|
||||
PORT_DIPNAME( 0x20, 0x20, "Enemy Bullets" )
|
||||
PORT_DIPSETTING( 0x20, "Slow" )
|
||||
PORT_DIPSETTING( 0x00, "Fast" )
|
||||
PORT_DIPNAME( 0x40, 0x00, "Control Panel" )
|
||||
PORT_DIPSETTING( 0x40, DEF_STR( Upright ) ) /* 1 Player */
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) ) /* 2 Players */
|
||||
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Cabinet ) )
|
||||
PORT_DIPSETTING( 0x80, DEF_STR( Upright ) )
|
||||
PORT_DIPSETTING( 0xc0, DEF_STR( Cocktail ) )
|
||||
INPUT_PORTS_END
|
||||
|
||||
INPUT_PORTS_START( darwin )
|
||||
|
||||
+306
-8
@@ -13,6 +13,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "state.h"
|
||||
#include "vidhrdw/generic.h"
|
||||
#include "machine/eeprom.h"
|
||||
#include "ost_samples.h"
|
||||
@@ -231,20 +232,48 @@ static WRITE16_HANDLER( qsound_sharedram2_w )
|
||||
qsound_sharedram2[offset] = data;
|
||||
}
|
||||
|
||||
/* the QSound Z80 shared RAM, for drivers that watch the sound commands */
|
||||
data8_t *cps_qsound_sharedram1(void)
|
||||
{
|
||||
return qsound_sharedram1;
|
||||
}
|
||||
|
||||
data8_t *cps_qsound_sharedram2(void)
|
||||
{
|
||||
return qsound_sharedram2;
|
||||
}
|
||||
|
||||
static int qsound_bank; /* Z80 bank, kept for save states */
|
||||
|
||||
static void qsound_banksw_set(void)
|
||||
{
|
||||
unsigned char *RAM = memory_region(REGION_CPU2);
|
||||
int bankaddress=0x10000+(qsound_bank*0x4000);
|
||||
if (bankaddress >= memory_region_length(REGION_CPU2))
|
||||
{
|
||||
log_cb(RETRO_LOG_DEBUG, LOGPRE "WARNING: Q sound bank overflow (%02x)\n", qsound_bank);
|
||||
bankaddress=0x10000;
|
||||
}
|
||||
cpu_setbank(1, &RAM[bankaddress]);
|
||||
}
|
||||
|
||||
static WRITE_HANDLER( qsound_banksw_w )
|
||||
{
|
||||
/*
|
||||
Z80 bank register for music note data. It's odd that it isn't encrypted
|
||||
though.
|
||||
*/
|
||||
unsigned char *RAM = memory_region(REGION_CPU2);
|
||||
int bankaddress=0x10000+((data&0x0f)*0x4000);
|
||||
if (bankaddress >= memory_region_length(REGION_CPU2))
|
||||
{
|
||||
log_cb(RETRO_LOG_DEBUG, LOGPRE "WARNING: Q sound bank overflow (%02x)\n", data);
|
||||
bankaddress=0x10000;
|
||||
}
|
||||
cpu_setbank(1, &RAM[bankaddress]);
|
||||
qsound_bank = data & 0x0f;
|
||||
qsound_banksw_set();
|
||||
}
|
||||
|
||||
/* Save the Z80 bank of the QSound games: after loading a save state the
|
||||
music code runs from the right bank again. */
|
||||
void cps_qsound_state_register(void)
|
||||
{
|
||||
qsound_bank = 0;
|
||||
state_save_register_int("qsound_z80", 0, "bank", &qsound_bank);
|
||||
state_save_register_func_postload(qsound_banksw_set);
|
||||
}
|
||||
|
||||
|
||||
@@ -4264,6 +4293,265 @@ ROM_START( daimakai )
|
||||
ROM_CONTINUE( 0x10000, 0x08000 )
|
||||
ROM_END
|
||||
|
||||
// Ghouls'n Ghosts - Artoria Edition hacks (GoodLuckTrying)
|
||||
ROM_START( ghoulsmaiden )
|
||||
ROM_REGION( CODE_SIZE, REGION_CPU1, 0 )
|
||||
ROM_LOAD16_BYTE( "dme_29maiden.10h", 0x00000, 0x20000, CRC(62bc0f9f) SHA1(cd715aa5ccad61bc2c038d32594843377d2ea8ab) )
|
||||
ROM_LOAD16_BYTE( "dme_30maiden.10j", 0x00001, 0x20000, CRC(3d770ee1) SHA1(a5f913923c078187b26783ef0baae3aed7361e66) )
|
||||
ROM_LOAD16_BYTE( "dme_27maiden.9h", 0x40000, 0x20000, CRC(717dfa2f) SHA1(64a0397e9203cdf0e92d07adef6de94a7ee3fd47) )
|
||||
ROM_LOAD16_BYTE( "dme_28maiden.9j", 0x40001, 0x20000, CRC(00136f06) SHA1(430d469717c3535a06d74d1df23c5fa348a87793) )
|
||||
ROM_LOAD16_WORD( "dm-17maiden.7j", 0x80000, 0x80000, CRC(f96c3f5d) SHA1(2be095270f3afe827306ef19df4ac3a3bfaeab35) )
|
||||
|
||||
ROM_REGION( 0x300000, REGION_GFX1, 0 )
|
||||
ROMX_LOAD( "dm-05maiden.3a", 0x000000, 0x80000, CRC(089d3e31) SHA1(e9f9406fc16686a98e1372bc09e7c51456315a66), ROM_GROUPWORD | ROM_SKIP(6) )
|
||||
ROMX_LOAD( "dm-07maiden.3f", 0x000002, 0x80000, CRC(b7b0567c) SHA1(f3d74ebd9daa4bdc7e91080f02f801e2ac9dd40d), ROM_GROUPWORD | ROM_SKIP(6) )
|
||||
ROMX_LOAD( "dm-06maiden.3c", 0x000004, 0x80000, CRC(92ca0ba1) SHA1(a5dd14e8cb0cb4c7f4ebad07cfc36abf148fcf78), ROM_GROUPWORD | ROM_SKIP(6) )
|
||||
ROMX_LOAD( "dm-08maiden.3g", 0x000006, 0x80000, CRC(0f39afc8) SHA1(44d499fd38e2e9155a843ab834bee4e91ced4375), ROM_GROUPWORD | ROM_SKIP(6) )
|
||||
ROMX_LOAD( "09maiden.4a", 0x200000, 0x10000, CRC(e99f777e) SHA1(015549b7745e7a1c26ae50450e5a3ff0116c64eb), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "18maiden.7a", 0x200001, 0x10000, CRC(9798c4be) SHA1(601a2122e774b5142d152d9666cbec0a512c0fae), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "13maiden.4e", 0x200002, 0x10000, CRC(d731677a) SHA1(53138a653737556023e384fb075c971ca0640235), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "22maiden.7e", 0x200003, 0x10000, CRC(e9282194) SHA1(47d635673d894725cb343b2753e2be632bcb23cd), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "11maiden.4c", 0x200004, 0x10000, CRC(f94717d0) SHA1(dc0e13727d0a2b4111f9fa64ca272986de822196), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "20maiden.7c", 0x200005, 0x10000, CRC(d2605c04) SHA1(e6e5343d1f3737a0cdd815c8045acc81f1e6587e), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "15maiden.4g", 0x200006, 0x10000, CRC(ad8a53ec) SHA1(48a763d5ab320a1b3ce9f8ec5319a6a854f34fca), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "24maiden.7g", 0x200007, 0x10000, CRC(ae66ab27) SHA1(3eb22952e3b6843e13d05f14b3ccaf7c504c7aeb), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "10maiden.4b", 0x280000, 0x10000, CRC(afce74dd) SHA1(a13d7a7e11f900d6f5a7273ca93e30f1e0a385b1), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "19maiden.7b", 0x280001, 0x10000, CRC(0b4e155f) SHA1(268188162286e12af63653d5f700263f6f3b70d4), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "14maiden.4f", 0x280002, 0x10000, CRC(5bc8e886) SHA1(17b727169c68b0ed3574bc321db4fbfd4d2f9266), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "23maiden.7f", 0x280003, 0x10000, CRC(095a6785) SHA1(659530f934c1f33067e9af71503b92da88315018), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "12maiden.4d", 0x280004, 0x10000, CRC(c8a5b7e9) SHA1(35b2f96994338816b29e1f65127f81d949a3a775), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "21maiden.7d", 0x280005, 0x10000, CRC(7d2f39f4) SHA1(6156385421104fef4e7b02bb1aba04f13aadb750), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "16maiden.4h", 0x280006, 0x10000, CRC(2913fa9b) SHA1(c37e526f5c647091cc45fa045f1e8049ec71483a), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "25maiden.7h", 0x280007, 0x10000, CRC(35d1b525) SHA1(e10226e6a34c827a44908384c37a0f9aaa74c934), ROM_SKIP(7) )
|
||||
|
||||
ROM_REGION( 0x18000, REGION_CPU2, 0 )
|
||||
ROM_LOAD( "26.10a", 0x00000, 0x08000, CRC(3692f6e5) SHA1(61b8438d60a39b4cf5062dff0a53228e8a4e4b5f) )
|
||||
ROM_CONTINUE( 0x10000, 0x08000 )
|
||||
|
||||
ROM_REGION( 0x8000, REGION_GFX2, 0 )
|
||||
ROM_COPY( REGION_GFX1, 0x000000, 0x000000, 0x8000 ) /* stars */
|
||||
ROM_END
|
||||
|
||||
ROM_START( ghoulsknight )
|
||||
ROM_REGION( CODE_SIZE, REGION_CPU1, 0 )
|
||||
ROM_LOAD16_BYTE( "dme_29knight.10h", 0x00000, 0x20000, CRC(a26366a2) SHA1(5fcbb7b594814d5dd074f17c61d2ef72467b89fc) )
|
||||
ROM_LOAD16_BYTE( "dme_30knight.10j", 0x00001, 0x20000, CRC(906bfbd9) SHA1(003d5cffd8ef23f349158136c0b6e34c93f4abbd) )
|
||||
ROM_LOAD16_BYTE( "dme_27knight.9h", 0x40000, 0x20000, CRC(0f80f588) SHA1(b0def403185ccbf0c373a868afcfe757e7b7caf8) )
|
||||
ROM_LOAD16_BYTE( "dme_28knight.9j", 0x40001, 0x20000, CRC(448bf481) SHA1(804a2e8a22153135c16a6388f69150049bd9c651) )
|
||||
ROM_LOAD16_WORD( "dm-17knight.7j", 0x80000, 0x80000, CRC(e856d9b6) SHA1(10a49dbba04c90c1676ad63a093c3b6f10345134) )
|
||||
|
||||
ROM_REGION( 0x300000, REGION_GFX1, 0 )
|
||||
ROMX_LOAD( "dm-05knight.3a", 0x000000, 0x80000, CRC(68381793) SHA1(1d82de2a42cac3a25faf3ffa04292303d08fcbc5), ROM_GROUPWORD | ROM_SKIP(6) )
|
||||
ROMX_LOAD( "dm-07knight.3f", 0x000002, 0x80000, CRC(fe68674d) SHA1(648645333767270fe859f275a1cacc816e0f05fe), ROM_GROUPWORD | ROM_SKIP(6) )
|
||||
ROMX_LOAD( "dm-06knight.3c", 0x000004, 0x80000, CRC(c0e27e48) SHA1(6a8f67c6ac4d2e720475fe6ec9160fd5b6de7916), ROM_GROUPWORD | ROM_SKIP(6) )
|
||||
ROMX_LOAD( "dm-08knight.3g", 0x000006, 0x80000, CRC(7be8f80a) SHA1(7b6c1f423fcf0dfeb2f2fd705b2aeed8345c4a5e), ROM_GROUPWORD | ROM_SKIP(6) )
|
||||
ROMX_LOAD( "09knight.4a", 0x200000, 0x10000, CRC(a726123a) SHA1(b9b5133ac838d98aa2eb0098ce6dc95e1ed36e19), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "18knight.7a", 0x200001, 0x10000, CRC(379d3bee) SHA1(8c65e0443cf7ff7695b103bc67d7288e156a613a), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "13knight.4e", 0x200002, 0x10000, CRC(eedbdd71) SHA1(603855bf2e046543bc6cab4708b1fde01c5593e0), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "22knight.7e", 0x200003, 0x10000, CRC(96a4311f) SHA1(02faedaffef031c0c446f1ec27d3de286094f0b3), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "11knight.4c", 0x200004, 0x10000, CRC(af590ecd) SHA1(38b1398600aa16b0adaa89813169977d2565cc9a), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "20knight.7c", 0x200005, 0x10000, CRC(00bdeef0) SHA1(6a2aa247a1bc2d467e4f1ae2c3f6b937d13310b0), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "15knight.4g", 0x200006, 0x10000, CRC(d409bf40) SHA1(a9d79df80e97391118c74571eed55cdb1a89da00), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "24knight.7g", 0x200007, 0x10000, CRC(fc91ec7c) SHA1(4d099e4fa67daab094997a217b3381340955e0ab), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "10knight.4b", 0x280000, 0x10000, CRC(08043aa8) SHA1(41dcf3219d1895489ef1db67226420f50264f9cc), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "19knight.7b", 0x280001, 0x10000, CRC(daca4bc1) SHA1(8566fff3073e2323eeb7e4b265e18808fb92e1a5), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "14knight.4f", 0x280002, 0x10000, CRC(0d7d3de4) SHA1(618025aaf21b622ad7beaff286bea01313015628), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "23knight.7f", 0x280003, 0x10000, CRC(53622c1c) SHA1(3546fa048823922d01d50fdbc9a717738c535eb6), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "12knight.4d", 0x280004, 0x10000, CRC(95efe854) SHA1(03bcdd7bf25637e1ab7166985093d14111699dc5), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "21knight.7d", 0x280005, 0x10000, CRC(5fd971cf) SHA1(dc2fb8e909cd4a5de1d637b750d383ad34480d2e), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "16knight.4h", 0x280006, 0x10000, CRC(5c63b626) SHA1(069b6efaac107abdf762db1edd025ec4d607bac2), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "25knight.7h", 0x280007, 0x10000, CRC(2556bc0e) SHA1(4f62a23bd7e43c6b00ef744de618d9b44e7d76f6), ROM_SKIP(7) )
|
||||
|
||||
ROM_REGION( 0x18000, REGION_CPU2, 0 )
|
||||
ROM_LOAD( "26.10a", 0x00000, 0x08000, CRC(3692f6e5) SHA1(61b8438d60a39b4cf5062dff0a53228e8a4e4b5f) )
|
||||
ROM_CONTINUE( 0x10000, 0x08000 )
|
||||
|
||||
ROM_REGION( 0x8000, REGION_GFX2, 0 )
|
||||
ROM_COPY( REGION_GFX1, 0x000000, 0x000000, 0x8000 ) /* stars */
|
||||
ROM_END
|
||||
|
||||
ROM_START( ghoulsumaiden )
|
||||
ROM_REGION( CODE_SIZE, REGION_CPU1, 0 )
|
||||
ROM_LOAD16_BYTE( "dmu_29maiden.10h", 0x00000, 0x20000, CRC(7ac6c63e) SHA1(669087b80001ea86181a889d7f1fc712ad94215a) )
|
||||
ROM_LOAD16_BYTE( "dmu_30maiden.10j", 0x00001, 0x20000, CRC(0a3d58f0) SHA1(89727371eed9188da622e9858cd90eea0a28cc97) )
|
||||
ROM_LOAD16_BYTE( "dmu_27maiden.9h", 0x40000, 0x20000, CRC(db966113) SHA1(0c0af55ba5ad550aa2f9548431cbc349d68a91be) )
|
||||
ROM_LOAD16_BYTE( "dmu_28maiden.9j", 0x40001, 0x20000, CRC(d6594f60) SHA1(54edb2db45974ccfad1c61697f50032342584556) )
|
||||
ROM_LOAD16_WORD( "dm-17maiden.7j", 0x80000, 0x80000, CRC(f96c3f5d) SHA1(2be095270f3afe827306ef19df4ac3a3bfaeab35) )
|
||||
|
||||
ROM_REGION( 0x300000, REGION_GFX1, 0 )
|
||||
ROMX_LOAD( "dm-05maiden.3a", 0x000000, 0x80000, CRC(089d3e31) SHA1(e9f9406fc16686a98e1372bc09e7c51456315a66), ROM_GROUPWORD | ROM_SKIP(6) )
|
||||
ROMX_LOAD( "dm-07maiden.3f", 0x000002, 0x80000, CRC(b7b0567c) SHA1(f3d74ebd9daa4bdc7e91080f02f801e2ac9dd40d), ROM_GROUPWORD | ROM_SKIP(6) )
|
||||
ROMX_LOAD( "dm-06maiden.3c", 0x000004, 0x80000, CRC(92ca0ba1) SHA1(a5dd14e8cb0cb4c7f4ebad07cfc36abf148fcf78), ROM_GROUPWORD | ROM_SKIP(6) )
|
||||
ROMX_LOAD( "dm-08maiden.3g", 0x000006, 0x80000, CRC(0f39afc8) SHA1(44d499fd38e2e9155a843ab834bee4e91ced4375), ROM_GROUPWORD | ROM_SKIP(6) )
|
||||
ROMX_LOAD( "09maiden.4a", 0x200000, 0x10000, CRC(e99f777e) SHA1(015549b7745e7a1c26ae50450e5a3ff0116c64eb), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "18maiden.7a", 0x200001, 0x10000, CRC(9798c4be) SHA1(601a2122e774b5142d152d9666cbec0a512c0fae), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "13maiden.4e", 0x200002, 0x10000, CRC(d731677a) SHA1(53138a653737556023e384fb075c971ca0640235), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "22maiden.7e", 0x200003, 0x10000, CRC(e9282194) SHA1(47d635673d894725cb343b2753e2be632bcb23cd), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "11maiden.4c", 0x200004, 0x10000, CRC(f94717d0) SHA1(dc0e13727d0a2b4111f9fa64ca272986de822196), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "20maiden.7c", 0x200005, 0x10000, CRC(d2605c04) SHA1(e6e5343d1f3737a0cdd815c8045acc81f1e6587e), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "15maiden.4g", 0x200006, 0x10000, CRC(ad8a53ec) SHA1(48a763d5ab320a1b3ce9f8ec5319a6a854f34fca), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "24maiden.7g", 0x200007, 0x10000, CRC(ae66ab27) SHA1(3eb22952e3b6843e13d05f14b3ccaf7c504c7aeb), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "10maiden.4b", 0x280000, 0x10000, CRC(afce74dd) SHA1(a13d7a7e11f900d6f5a7273ca93e30f1e0a385b1), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "19maiden.7b", 0x280001, 0x10000, CRC(0b4e155f) SHA1(268188162286e12af63653d5f700263f6f3b70d4), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "14maiden.4f", 0x280002, 0x10000, CRC(5bc8e886) SHA1(17b727169c68b0ed3574bc321db4fbfd4d2f9266), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "23maiden.7f", 0x280003, 0x10000, CRC(095a6785) SHA1(659530f934c1f33067e9af71503b92da88315018), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "12maiden.4d", 0x280004, 0x10000, CRC(c8a5b7e9) SHA1(35b2f96994338816b29e1f65127f81d949a3a775), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "21maiden.7d", 0x280005, 0x10000, CRC(7d2f39f4) SHA1(6156385421104fef4e7b02bb1aba04f13aadb750), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "16maiden.4h", 0x280006, 0x10000, CRC(2913fa9b) SHA1(c37e526f5c647091cc45fa045f1e8049ec71483a), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "25maiden.7h", 0x280007, 0x10000, CRC(35d1b525) SHA1(e10226e6a34c827a44908384c37a0f9aaa74c934), ROM_SKIP(7) )
|
||||
|
||||
ROM_REGION( 0x18000, REGION_CPU2, 0 )
|
||||
ROM_LOAD( "26.10a", 0x00000, 0x08000, CRC(3692f6e5) SHA1(61b8438d60a39b4cf5062dff0a53228e8a4e4b5f) )
|
||||
ROM_CONTINUE( 0x10000, 0x08000 )
|
||||
|
||||
ROM_REGION( 0x8000, REGION_GFX2, 0 )
|
||||
ROM_COPY( REGION_GFX1, 0x000000, 0x000000, 0x8000 ) /* stars */
|
||||
ROM_END
|
||||
|
||||
ROM_START( ghoulsuknight )
|
||||
ROM_REGION( CODE_SIZE, REGION_CPU1, 0 )
|
||||
ROM_LOAD16_BYTE( "dmu_29knight.10h", 0x00000, 0x20000, CRC(6b315490) SHA1(6b3ccff317295a772ea5c15ae3a2cb3ec16ba398) )
|
||||
ROM_LOAD16_BYTE( "dmu_30knight.10j", 0x00001, 0x20000, CRC(e3209d51) SHA1(e573a2649b83d9d57ccab60977a5a3e233c1733a) )
|
||||
ROM_LOAD16_BYTE( "dmu_27knight.9h", 0x40000, 0x20000, CRC(0cc89606) SHA1(87903a4f5e00b48573f2e3e5b12f4d202e485f7c) )
|
||||
ROM_LOAD16_BYTE( "dmu_28knight.9j", 0x40001, 0x20000, CRC(a263bde6) SHA1(5912b748a6f2949453634d50b5bdaaa567eaa1c3) )
|
||||
ROM_LOAD16_WORD( "dm-17knight.7j", 0x80000, 0x80000, CRC(e856d9b6) SHA1(10a49dbba04c90c1676ad63a093c3b6f10345134) )
|
||||
|
||||
ROM_REGION( 0x300000, REGION_GFX1, 0 )
|
||||
ROMX_LOAD( "dm-05knight.3a", 0x000000, 0x80000, CRC(68381793) SHA1(1d82de2a42cac3a25faf3ffa04292303d08fcbc5), ROM_GROUPWORD | ROM_SKIP(6) )
|
||||
ROMX_LOAD( "dm-07knight.3f", 0x000002, 0x80000, CRC(fe68674d) SHA1(648645333767270fe859f275a1cacc816e0f05fe), ROM_GROUPWORD | ROM_SKIP(6) )
|
||||
ROMX_LOAD( "dm-06knight.3c", 0x000004, 0x80000, CRC(c0e27e48) SHA1(6a8f67c6ac4d2e720475fe6ec9160fd5b6de7916), ROM_GROUPWORD | ROM_SKIP(6) )
|
||||
ROMX_LOAD( "dm-08knight.3g", 0x000006, 0x80000, CRC(7be8f80a) SHA1(7b6c1f423fcf0dfeb2f2fd705b2aeed8345c4a5e), ROM_GROUPWORD | ROM_SKIP(6) )
|
||||
ROMX_LOAD( "09knight.4a", 0x200000, 0x10000, CRC(a726123a) SHA1(b9b5133ac838d98aa2eb0098ce6dc95e1ed36e19), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "18knight.7a", 0x200001, 0x10000, CRC(379d3bee) SHA1(8c65e0443cf7ff7695b103bc67d7288e156a613a), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "13knight.4e", 0x200002, 0x10000, CRC(eedbdd71) SHA1(603855bf2e046543bc6cab4708b1fde01c5593e0), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "22knight.7e", 0x200003, 0x10000, CRC(96a4311f) SHA1(02faedaffef031c0c446f1ec27d3de286094f0b3), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "11knight.4c", 0x200004, 0x10000, CRC(af590ecd) SHA1(38b1398600aa16b0adaa89813169977d2565cc9a), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "20knight.7c", 0x200005, 0x10000, CRC(00bdeef0) SHA1(6a2aa247a1bc2d467e4f1ae2c3f6b937d13310b0), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "15knight.4g", 0x200006, 0x10000, CRC(d409bf40) SHA1(a9d79df80e97391118c74571eed55cdb1a89da00), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "24knight.7g", 0x200007, 0x10000, CRC(fc91ec7c) SHA1(4d099e4fa67daab094997a217b3381340955e0ab), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "10knight.4b", 0x280000, 0x10000, CRC(08043aa8) SHA1(41dcf3219d1895489ef1db67226420f50264f9cc), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "19knight.7b", 0x280001, 0x10000, CRC(daca4bc1) SHA1(8566fff3073e2323eeb7e4b265e18808fb92e1a5), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "14knight.4f", 0x280002, 0x10000, CRC(0d7d3de4) SHA1(618025aaf21b622ad7beaff286bea01313015628), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "23knight.7f", 0x280003, 0x10000, CRC(53622c1c) SHA1(3546fa048823922d01d50fdbc9a717738c535eb6), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "12knight.4d", 0x280004, 0x10000, CRC(95efe854) SHA1(03bcdd7bf25637e1ab7166985093d14111699dc5), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "21knight.7d", 0x280005, 0x10000, CRC(5fd971cf) SHA1(dc2fb8e909cd4a5de1d637b750d383ad34480d2e), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "16knight.4h", 0x280006, 0x10000, CRC(5c63b626) SHA1(069b6efaac107abdf762db1edd025ec4d607bac2), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "25knight.7h", 0x280007, 0x10000, CRC(2556bc0e) SHA1(4f62a23bd7e43c6b00ef744de618d9b44e7d76f6), ROM_SKIP(7) )
|
||||
|
||||
ROM_REGION( 0x18000, REGION_CPU2, 0 )
|
||||
ROM_LOAD( "26.10a", 0x00000, 0x08000, CRC(3692f6e5) SHA1(61b8438d60a39b4cf5062dff0a53228e8a4e4b5f) )
|
||||
ROM_CONTINUE( 0x10000, 0x08000 )
|
||||
|
||||
ROM_REGION( 0x8000, REGION_GFX2, 0 )
|
||||
ROM_COPY( REGION_GFX1, 0x000000, 0x000000, 0x8000 ) /* stars */
|
||||
ROM_END
|
||||
|
||||
ROM_START( daimakaimaiden )
|
||||
ROM_REGION( CODE_SIZE, REGION_CPU1, 0 )
|
||||
ROM_LOAD16_BYTE( "dmj_38maiden.12f", 0x00000, 0x20000, CRC(7f436646) SHA1(dd60f7757418e0b682c3d14ab1f077668aa328f6) )
|
||||
ROM_LOAD16_BYTE( "dmj_39maiden.12h", 0x00001, 0x20000, CRC(ebc72dee) SHA1(f82157fdacfe6496398b8702cb4e97a3bcb750c5) )
|
||||
ROM_LOAD16_BYTE( "dmj_40maiden.13f", 0x40000, 0x20000, CRC(a8371817) SHA1(56f2be6fba857d026da3a0d4e801edd0e6e53d10) )
|
||||
ROM_LOAD16_BYTE( "dmj_41maiden.13h", 0x40001, 0x20000, CRC(cd7de9bb) SHA1(77dcf1128ae8fd2c5ef3ff9800f69aa875c56436) )
|
||||
ROM_LOAD16_BYTE( "dm_33maiden.10f", 0x80000, 0x20000, CRC(0e47e3b3) SHA1(3e0b12607f5745c5b4a789e68307cfd08da1ac18) )
|
||||
ROM_LOAD16_BYTE( "dm_34maiden.10h", 0x80001, 0x20000, CRC(d9675957) SHA1(43fd195995ec311bde79f6a17c47e938baaae545) )
|
||||
ROM_LOAD16_BYTE( "dm_35maiden.11f", 0xc0000, 0x20000, CRC(c04b85c8) SHA1(f8659624bb9d418d02f63f43478d3b53cfe18718) )
|
||||
ROM_LOAD16_BYTE( "dm_36maiden.11h", 0xc0001, 0x20000, CRC(89be83de) SHA1(6dfd1380304a85dee7cac4d0b2cfd7625b9020bf) )
|
||||
|
||||
ROM_REGION( 0x300000, REGION_GFX1, 0 )
|
||||
ROMX_LOAD( "dm_02maiden.4b", 0x000000, 0x20000, CRC(e195234d) SHA1(e83fe906577ff9a55c6222b148ae616eee71f9bd), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_01maiden.4a", 0x000001, 0x20000, CRC(bf40447c) SHA1(129f989307618346d4d0f048cf0975fcd9ac85ba), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_10maiden.9b", 0x000002, 0x20000, CRC(64506deb) SHA1(81795caef6c183c26597e69f0ca4dc2f46a97a9b), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_09maiden.9a", 0x000003, 0x20000, CRC(6db846bf) SHA1(3031a7a754cc8a45265663d5d13c588ed1a2e3e4), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_18maiden.5e", 0x000004, 0x20000, CRC(3d707890) SHA1(1fb13ac4f4d458c1d8429cb18b3cb0c755582c8f), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_17maiden.5c", 0x000005, 0x20000, CRC(25adb6e2) SHA1(e57207799427f9372052a886be92aadd1521f9b2), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_30maiden.8h", 0x000006, 0x20000, CRC(29bb7d32) SHA1(fbf501e9674e64528846c1b4bdf1c50350e2163e), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_29maiden.8f", 0x000007, 0x20000, CRC(d99c38e0) SHA1(0d1a2a391a63eb723a07cec051daadaba8bd93b2), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_04maiden.5b", 0x100000, 0x20000, CRC(a4f4f8f0) SHA1(edca0f61b40a18afe279f7007c233064130cfb4f), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_03maiden.5a", 0x100001, 0x20000, CRC(b1033e62) SHA1(547fc281dd9e7a74ac86c3692508c7bde9b6167b), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_12maiden.10b", 0x100002, 0x20000, CRC(10fdd76a) SHA1(aee774d6323292799dff7a30ef9559c92fe5507a), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_11maiden.10a", 0x100003, 0x20000, CRC(9040cb04) SHA1(b32e9056fc20a5162868eade10f3ef5efc167a28), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_20maiden.7e", 0x100004, 0x20000, CRC(281d0b3e) SHA1(70e1813de184ad0ec164145b7b843b5e387494e3), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_19maiden.7c", 0x100005, 0x20000, CRC(2623b52f) SHA1(fc4200924452bfbff687934782398ed345dc0aa0), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_32maiden.9h", 0x100006, 0x20000, CRC(99692344) SHA1(67dc70618568b7c0adcb00a612aaf5501f6c8c0f), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_31maiden.9f", 0x100007, 0x20000, CRC(54acb729) SHA1(d1fca43db36253fd19db4337c49272a6cadff597), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_06maiden.7b", 0x200000, 0x10000, CRC(e99f777e) SHA1(015549b7745e7a1c26ae50450e5a3ff0116c64eb), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_05maiden.7a", 0x200001, 0x10000, CRC(9798c4be) SHA1(601a2122e774b5142d152d9666cbec0a512c0fae), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_14maiden.11b", 0x200002, 0x10000, CRC(d731677a) SHA1(53138a653737556023e384fb075c971ca0640235), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_13maiden.11a", 0x200003, 0x10000, CRC(e9282194) SHA1(47d635673d894725cb343b2753e2be632bcb23cd), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_22maiden.8e", 0x200004, 0x10000, CRC(f94717d0) SHA1(dc0e13727d0a2b4111f9fa64ca272986de822196), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_21maiden.8c", 0x200005, 0x10000, CRC(d2605c04) SHA1(e6e5343d1f3737a0cdd815c8045acc81f1e6587e), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_26maiden.10e", 0x200006, 0x10000, CRC(ad8a53ec) SHA1(48a763d5ab320a1b3ce9f8ec5319a6a854f34fca), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_25maiden.10c", 0x200007, 0x10000, CRC(ae66ab27) SHA1(3eb22952e3b6843e13d05f14b3ccaf7c504c7aeb), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_08maiden.8b", 0x280000, 0x10000, CRC(afce74dd) SHA1(a13d7a7e11f900d6f5a7273ca93e30f1e0a385b1), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_07maiden.8a", 0x280001, 0x10000, CRC(0b4e155f) SHA1(268188162286e12af63653d5f700263f6f3b70d4), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_16maiden.12b", 0x280002, 0x10000, CRC(5bc8e886) SHA1(17b727169c68b0ed3574bc321db4fbfd4d2f9266), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_15maiden.12a", 0x280003, 0x10000, CRC(095a6785) SHA1(659530f934c1f33067e9af71503b92da88315018), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_24maiden.9e", 0x280004, 0x10000, CRC(c8a5b7e9) SHA1(35b2f96994338816b29e1f65127f81d949a3a775), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_23maiden.9c", 0x280005, 0x10000, CRC(7d2f39f4) SHA1(6156385421104fef4e7b02bb1aba04f13aadb750), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_28maiden.11e", 0x280006, 0x10000, CRC(2913fa9b) SHA1(c37e526f5c647091cc45fa045f1e8049ec71483a), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_27maiden.11c", 0x280007, 0x10000, CRC(35d1b525) SHA1(e10226e6a34c827a44908384c37a0f9aaa74c934), ROM_SKIP(7) )
|
||||
|
||||
ROM_REGION( 0x18000, REGION_CPU2, 0 )
|
||||
ROM_LOAD( "37.13c", 0x00000, 0x08000, CRC(3692f6e5) SHA1(61b8438d60a39b4cf5062dff0a53228e8a4e4b5f) )
|
||||
ROM_CONTINUE( 0x10000, 0x08000 )
|
||||
|
||||
ROM_REGION( 0x8000, REGION_GFX2, 0 )
|
||||
ROM_COPY( REGION_GFX1, 0x000000, 0x000000, 0x8000 ) /* stars */
|
||||
ROM_END
|
||||
|
||||
ROM_START( daimakaiknight )
|
||||
ROM_REGION( CODE_SIZE, REGION_CPU1, 0 )
|
||||
ROM_LOAD16_BYTE( "dmj_38knight.12f", 0x00000, 0x20000, CRC(3098aca7) SHA1(ac1f175deffd486eab177f0c6c3992802c24dd49) )
|
||||
ROM_LOAD16_BYTE( "dmj_39knight.12h", 0x00001, 0x20000, CRC(222d253b) SHA1(7c26d6a0fe204a83dfc9cba6db7ed2635a7b9f7b) )
|
||||
ROM_LOAD16_BYTE( "dmj_40knight.13f", 0x40000, 0x20000, CRC(1050f528) SHA1(c09ddd0f63e093ad1e6c50782db4ffa21114c6e1) )
|
||||
ROM_LOAD16_BYTE( "dmj_41knight.13h", 0x40001, 0x20000, CRC(bff07623) SHA1(2f8d6980ae5a3f798fd3296185f14fb59b8a472a) )
|
||||
ROM_LOAD16_BYTE( "dm_33knight.10f", 0x80000, 0x20000, CRC(37619c8a) SHA1(39782b4285fbf103b2a820d745dc56ae1a1e9def) )
|
||||
ROM_LOAD16_BYTE( "dm_34knight.10h", 0x80001, 0x20000, CRC(f92dc399) SHA1(eb92ba0d28e22c6f3c6f16396017ed45c4932487) )
|
||||
ROM_LOAD16_BYTE( "dm_35knight.11f", 0xc0000, 0x20000, CRC(c04b85c8) SHA1(f8659624bb9d418d02f63f43478d3b53cfe18718) )
|
||||
ROM_LOAD16_BYTE( "dm_36knight.11h", 0xc0001, 0x20000, CRC(89be83de) SHA1(6dfd1380304a85dee7cac4d0b2cfd7625b9020bf) )
|
||||
|
||||
ROM_REGION( 0x300000, REGION_GFX1, 0 )
|
||||
ROMX_LOAD( "dm_02knight.4b", 0x000000, 0x20000, CRC(27bd1d69) SHA1(464ba1ec2ccb7997a9bcce6a024b3f4f62cbbb6d), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_01knight.4a", 0x000001, 0x20000, CRC(e8ba76ec) SHA1(9c285eb2377155973aa2d06cec86c116e8db8c28), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_10knight.9b", 0x000002, 0x20000, CRC(44d222eb) SHA1(874da73471bf67aa59aefd03ccbb41b5a3ad26e9), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_09knight.9a", 0x000003, 0x20000, CRC(5561f7df) SHA1(27aac04774b098fb97847cac0ebe7bdaa7583c65), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_18knight.5e", 0x000004, 0x20000, CRC(a65e9f34) SHA1(6f4f293189bf487dc3b32539b7698da523eba7b0), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_17knight.5c", 0x000005, 0x20000, CRC(3f84db19) SHA1(d33389b29d09bc711bed91769ca588795908b313), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_30knight.8h", 0x000006, 0x20000, CRC(500840f2) SHA1(85efda21fd449a68d8daec435dd2da301b9dd738), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_29knight.8f", 0x000007, 0x20000, CRC(bafb92de) SHA1(0d221a7004f197a95081be728ee0a54316d9b406), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_04knight.5b", 0x100000, 0x20000, CRC(a4f4f8f0) SHA1(edca0f61b40a18afe279f7007c233064130cfb4f), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_03knight.5a", 0x100001, 0x20000, CRC(b1033e62) SHA1(547fc281dd9e7a74ac86c3692508c7bde9b6167b), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_12knight.10b", 0x100002, 0x20000, CRC(10fdd76a) SHA1(aee774d6323292799dff7a30ef9559c92fe5507a), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_11knight.10a", 0x100003, 0x20000, CRC(9040cb04) SHA1(b32e9056fc20a5162868eade10f3ef5efc167a28), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_20knight.7e", 0x100004, 0x20000, CRC(281d0b3e) SHA1(70e1813de184ad0ec164145b7b843b5e387494e3), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_19knight.7c", 0x100005, 0x20000, CRC(2623b52f) SHA1(fc4200924452bfbff687934782398ed345dc0aa0), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_32knight.9h", 0x100006, 0x20000, CRC(99692344) SHA1(67dc70618568b7c0adcb00a612aaf5501f6c8c0f), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_31knight.9f", 0x100007, 0x20000, CRC(54acb729) SHA1(d1fca43db36253fd19db4337c49272a6cadff597), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_06knight.7b", 0x200000, 0x10000, CRC(a726123a) SHA1(b9b5133ac838d98aa2eb0098ce6dc95e1ed36e19), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_05knight.7a", 0x200001, 0x10000, CRC(379d3bee) SHA1(8c65e0443cf7ff7695b103bc67d7288e156a613a), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_14knight.11b", 0x200002, 0x10000, CRC(eedbdd71) SHA1(603855bf2e046543bc6cab4708b1fde01c5593e0), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_13knight.11a", 0x200003, 0x10000, CRC(96a4311f) SHA1(02faedaffef031c0c446f1ec27d3de286094f0b3), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_22knight.8e", 0x200004, 0x10000, CRC(af590ecd) SHA1(38b1398600aa16b0adaa89813169977d2565cc9a), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_21knight.8c", 0x200005, 0x10000, CRC(00bdeef0) SHA1(6a2aa247a1bc2d467e4f1ae2c3f6b937d13310b0), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_26knight.10e", 0x200006, 0x10000, CRC(d409bf40) SHA1(a9d79df80e97391118c74571eed55cdb1a89da00), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_25knight.10c", 0x200007, 0x10000, CRC(fc91ec7c) SHA1(4d099e4fa67daab094997a217b3381340955e0ab), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_08knight.8b", 0x280000, 0x10000, CRC(08043aa8) SHA1(41dcf3219d1895489ef1db67226420f50264f9cc), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_07knight.8a", 0x280001, 0x10000, CRC(daca4bc1) SHA1(8566fff3073e2323eeb7e4b265e18808fb92e1a5), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_16knight.12b", 0x280002, 0x10000, CRC(0d7d3de4) SHA1(618025aaf21b622ad7beaff286bea01313015628), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_15knight.12a", 0x280003, 0x10000, CRC(53622c1c) SHA1(3546fa048823922d01d50fdbc9a717738c535eb6), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_24knight.9e", 0x280004, 0x10000, CRC(95efe854) SHA1(03bcdd7bf25637e1ab7166985093d14111699dc5), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_23knight.9c", 0x280005, 0x10000, CRC(5fd971cf) SHA1(dc2fb8e909cd4a5de1d637b750d383ad34480d2e), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_28knight.11e", 0x280006, 0x10000, CRC(5c63b626) SHA1(069b6efaac107abdf762db1edd025ec4d607bac2), ROM_SKIP(7) )
|
||||
ROMX_LOAD( "dm_27knight.11c", 0x280007, 0x10000, CRC(2556bc0e) SHA1(4f62a23bd7e43c6b00ef744de618d9b44e7d76f6), ROM_SKIP(7) )
|
||||
|
||||
ROM_REGION( 0x18000, REGION_CPU2, 0 )
|
||||
ROM_LOAD( "37.13c", 0x00000, 0x08000, CRC(3692f6e5) SHA1(61b8438d60a39b4cf5062dff0a53228e8a4e4b5f) )
|
||||
ROM_CONTINUE( 0x10000, 0x08000 )
|
||||
|
||||
ROM_REGION( 0x8000, REGION_GFX2, 0 )
|
||||
ROM_COPY( REGION_GFX1, 0x000000, 0x000000, 0x8000 ) /* stars */
|
||||
ROM_END
|
||||
|
||||
ROM_START( strider )
|
||||
ROM_REGION( CODE_SIZE, REGION_CPU1, 0 ) /* 68000 code */
|
||||
ROM_LOAD16_BYTE( "strider.30", 0x00000, 0x20000, CRC(da997474) SHA1(3e4ac98f9a6967d61899281b31c7de779723397b) )
|
||||
@@ -7804,24 +8092,28 @@ static DRIVER_INIT( wof )
|
||||
{
|
||||
wof_decode();
|
||||
init_cps1();
|
||||
cps_qsound_state_register();
|
||||
}
|
||||
|
||||
static DRIVER_INIT( dino )
|
||||
{
|
||||
dino_decode();
|
||||
init_cps1();
|
||||
cps_qsound_state_register();
|
||||
}
|
||||
|
||||
static DRIVER_INIT( punisher )
|
||||
{
|
||||
punisher_decode();
|
||||
init_cps1();
|
||||
cps_qsound_state_register();
|
||||
}
|
||||
|
||||
static DRIVER_INIT( slammast )
|
||||
{
|
||||
slammast_decode();
|
||||
init_cps1();
|
||||
cps_qsound_state_register();
|
||||
}
|
||||
|
||||
static DRIVER_INIT( pang3 )
|
||||
@@ -7854,6 +8146,12 @@ GAME( 1988, lostwrld, forgottn, forgottn, forgottn, cps1, ROT0, "
|
||||
GAME( 1988, ghouls, 0, cps1, ghouls, cps1, ROT0, "Capcom", "Ghouls'n Ghosts (World)" ) /* Wed.26.10.1988 in the ROMS*/
|
||||
GAME( 1988, ghoulsu, ghouls, cps1, ghoulsu, cps1, ROT0, "Capcom", "Ghouls'n Ghosts (US)" ) /* Wed.26.10.1988 in the ROMS*/
|
||||
GAME( 1988, daimakai, ghouls, cps1_12mhz, daimakai, cps1, ROT0, "Capcom", "Dai Makai-Mura (Japan)" ) /* Wed.26.10.1988 in the ROMS*/
|
||||
GAME( 2026, ghoulsmaiden, ghouls, cps1, ghouls, cps1, ROT0, "hack (GoodLuckTrying)", "Ghouls'n Ghosts - Maiden Artoria Edition (World)" )
|
||||
GAME( 2026, ghoulsknight, ghouls, cps1, ghouls, cps1, ROT0, "hack (GoodLuckTrying)", "Ghouls'n Ghosts - Knight Artoria Edition (World)" )
|
||||
GAME( 2026, ghoulsumaiden, ghoulsu, cps1, ghoulsu, cps1, ROT0, "hack (GoodLuckTrying)", "Ghouls'n Ghosts - Maiden Artoria Edition (USA)" )
|
||||
GAME( 2026, ghoulsuknight, ghoulsu, cps1, ghoulsu, cps1, ROT0, "hack (GoodLuckTrying)", "Ghouls'n Ghosts - Knight Artoria Edition (USA)" )
|
||||
GAME( 2026, daimakaimaiden, ghouls, cps1_12mhz, daimakai, cps1, ROT0, "hack (GoodLuckTrying)", "Daimakaimura - Maiden Artoria Edition (Japan)" )
|
||||
GAME( 2026, daimakaiknight, ghouls, cps1_12mhz, daimakai, cps1, ROT0, "hack (GoodLuckTrying)", "Daimakaimura - Knight Artoria Edition (Japan)" )
|
||||
GAME( 1989, strider, 0, cps1, strider, cps1, ROT0, "Capcom", "Strider (US set 1)" )
|
||||
GAME( 1989, stridrua, strider, cps1, stridrua, cps1, ROT0, "Capcom", "Strider (US set 2)" )
|
||||
GAME( 1989, striderj, strider, cps1_12mhz, strider, cps1, ROT0, "Capcom", "Strider Hiryu (Japan set 1)" )
|
||||
|
||||
@@ -97,6 +97,7 @@
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "bootstrap.h"
|
||||
#include "inptport.h"
|
||||
#include "state.h"
|
||||
|
||||
#include "cps1.h" /* External CPS1 definitions */
|
||||
|
||||
@@ -514,6 +515,65 @@ INPUT_PORTS_START( cps2_2p6b )
|
||||
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
INPUT_PORTS_END
|
||||
|
||||
/* Street Fighter Zero 3 Mix: cps2_2p6b, plus the aspect ratio DIP switch of FBNeo */
|
||||
INPUT_PORTS_START( sfz3mix )
|
||||
PORT_START /* IN0 (0x00) */
|
||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START /* IN1 (0x10) */
|
||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON4 | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON5 | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON6 | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON4 | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START /* IN2 (0x20) */
|
||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_SPECIAL ) /* EEPROM bit */
|
||||
PORT_BITX(0x0002, IP_ACTIVE_LOW, IPT_SERVICE, DEF_STR( Service_Mode ), KEYCODE_F2, IP_JOY_NONE )
|
||||
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_SERVICE1 )
|
||||
PORT_BIT( 0x00f8, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 )
|
||||
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_START2 )
|
||||
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_COIN1 )
|
||||
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_COIN2 )
|
||||
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON6 | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START /* fake DIP switch: display aspect ratio, see VIDEO_UPDATE( cps2turbo ) */
|
||||
PORT_DIPNAME( 0x03, 0x00, "Aspect Ratio" )
|
||||
PORT_DIPSETTING( 0x00, "16:9" )
|
||||
PORT_DIPSETTING( 0x01, "4:3" )
|
||||
PORT_DIPSETTING( 0x02, "112:81" )
|
||||
INPUT_PORTS_END
|
||||
|
||||
INPUT_PORTS_START( cps2_2p6bt )
|
||||
PORT_START /* IN0 (0x00) */
|
||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_PLAYER1 )
|
||||
@@ -1136,6 +1196,391 @@ static MACHINE_DRIVER_START( cps2 )
|
||||
MDRV_SOUND_ADD(QSOUND, qsound_interface)
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* CPS2Turbo
|
||||
*
|
||||
* The extended CPS2 that Zero800 made for his Street Fighter Zero 3 Mix
|
||||
* hack (https://sfz3mix.github.io/), from his MAME 0.261 driver
|
||||
* (cps2turbo.cpp) and the FBNeo one:
|
||||
* - 68000 and Z80 at twice the CPS2 clock
|
||||
* - 416x234 display, 16:9
|
||||
* - 6MB of program ROM space, so the CPS2 object output moves from
|
||||
* 0x400000 to 0x665000
|
||||
* - 64MB of sprite ROM: bit 12 of the sprite Y selects the upper half
|
||||
* (cps1_vidhrdw.c)
|
||||
* - 16MB of QSound samples (qsound.c)
|
||||
* - optional music samples: the hacked Z80 program leaves the number of
|
||||
* the tune in its shared RAM, and a sample replaces the QSound music
|
||||
*
|
||||
*************************************/
|
||||
|
||||
/* the object output, also seen at 0xfffff0 like in current MAME */
|
||||
static READ16_HANDLER( cps2turbo_output_mirror_r )
|
||||
{
|
||||
return cps2_output[offset];
|
||||
}
|
||||
|
||||
static WRITE16_HANDLER( cps2turbo_output_mirror_w )
|
||||
{
|
||||
COMBINE_DATA(&cps2_output[offset]);
|
||||
}
|
||||
|
||||
/* sample n is the left channel of tune n, sample 0x40+n the right one */
|
||||
static const char *sfz3mix_sample_names[] =
|
||||
{
|
||||
"*sfz3mix",
|
||||
"empty",
|
||||
"L01",
|
||||
"L02",
|
||||
"L03",
|
||||
"L04",
|
||||
"L05",
|
||||
"L06",
|
||||
"L07",
|
||||
"L08",
|
||||
"L09",
|
||||
"L0A",
|
||||
"L0B",
|
||||
"L0C",
|
||||
"L0D",
|
||||
"L0E",
|
||||
"L0F",
|
||||
"L10",
|
||||
"L11",
|
||||
"L12",
|
||||
"L13",
|
||||
"L14",
|
||||
"L15",
|
||||
"L16",
|
||||
"L17",
|
||||
"L18",
|
||||
"L19",
|
||||
"L1A",
|
||||
"L1B",
|
||||
"L1C",
|
||||
"L1D",
|
||||
"L1E",
|
||||
"L1F",
|
||||
"L20",
|
||||
"L21",
|
||||
"L22",
|
||||
"L23",
|
||||
"L24",
|
||||
"L25",
|
||||
"L26",
|
||||
"L27",
|
||||
"L28",
|
||||
"L29",
|
||||
"L2A",
|
||||
"L2B",
|
||||
"L2C",
|
||||
"L2D",
|
||||
"L2E",
|
||||
"L2F",
|
||||
"L30",
|
||||
"L31",
|
||||
"L32",
|
||||
"L33",
|
||||
"L34",
|
||||
"L35",
|
||||
"L36",
|
||||
"L37",
|
||||
"L38",
|
||||
"L39",
|
||||
"L3A",
|
||||
"L3B",
|
||||
"L3C",
|
||||
"L3D",
|
||||
"L3E",
|
||||
"L3F",
|
||||
"empty",
|
||||
"R01",
|
||||
"R02",
|
||||
"R03",
|
||||
"R04",
|
||||
"R05",
|
||||
"R06",
|
||||
"R07",
|
||||
"R08",
|
||||
"R09",
|
||||
"R0A",
|
||||
"R0B",
|
||||
"R0C",
|
||||
"R0D",
|
||||
"R0E",
|
||||
"R0F",
|
||||
"R10",
|
||||
"R11",
|
||||
"R12",
|
||||
"R13",
|
||||
"R14",
|
||||
"R15",
|
||||
"R16",
|
||||
"R17",
|
||||
"R18",
|
||||
"R19",
|
||||
"R1A",
|
||||
"R1B",
|
||||
"R1C",
|
||||
"R1D",
|
||||
"R1E",
|
||||
"R1F",
|
||||
"R20",
|
||||
"R21",
|
||||
"R22",
|
||||
"R23",
|
||||
"R24",
|
||||
"R25",
|
||||
"R26",
|
||||
"R27",
|
||||
"R28",
|
||||
"R29",
|
||||
"R2A",
|
||||
"R2B",
|
||||
"R2C",
|
||||
"R2D",
|
||||
"R2E",
|
||||
"R2F",
|
||||
"R30",
|
||||
"R31",
|
||||
"R32",
|
||||
"R33",
|
||||
"R34",
|
||||
"R35",
|
||||
"R36",
|
||||
"R37",
|
||||
"R38",
|
||||
"R39",
|
||||
"R3A",
|
||||
"R3B",
|
||||
"R3C",
|
||||
"R3D",
|
||||
"R3E",
|
||||
"R3F",
|
||||
0 /* end of array */
|
||||
};
|
||||
|
||||
static struct Samplesinterface sfz3mix_samples_interface =
|
||||
{
|
||||
2, /* left, right */
|
||||
10, /* the samples are mixed at 1/10 of the QSound */
|
||||
sfz3mix_sample_names
|
||||
};
|
||||
|
||||
#define SFZ3MIX_SAMPLE_RIGHT 0x40
|
||||
|
||||
static int cps2turbo_tune; /* tune played by the samples, 0 = none (saved in the states) */
|
||||
|
||||
static void cps2turbo_music_stop(void)
|
||||
{
|
||||
sample_stop(0);
|
||||
sample_stop(1);
|
||||
cps2turbo_tune = 0;
|
||||
}
|
||||
|
||||
/* returns whether the sample of that side is there and plays */
|
||||
static int cps2turbo_music_start(int side, int tune)
|
||||
{
|
||||
sample_stop(side);
|
||||
sample_start(side, side ? SFZ3MIX_SAMPLE_RIGHT + tune : tune, 1);
|
||||
if (!sample_playing(side))
|
||||
{
|
||||
sample_stop(side);
|
||||
return 0;
|
||||
}
|
||||
if (side)
|
||||
sample_set_stereo_volume(1, 0, 255);
|
||||
else
|
||||
sample_set_stereo_volume(0, 255, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* the 68000 side of the QSound shared RAM: watch the Z80 for the music */
|
||||
static WRITE16_HANDLER( cps2turbo_qsound_sharedram1_w )
|
||||
{
|
||||
data8_t *ram1, *ram2;
|
||||
|
||||
if (!ACCESSING_LSB)
|
||||
return;
|
||||
|
||||
ram1 = cps_qsound_sharedram1();
|
||||
ram2 = cps_qsound_sharedram2();
|
||||
data &= 0xff;
|
||||
|
||||
/* stop the samples */
|
||||
if (offset == 0x001 && data == 0x00 && ram1[0x00] == 0xff)
|
||||
cps2turbo_music_stop();
|
||||
|
||||
/* last byte of a sound command */
|
||||
if (offset == 0xffe)
|
||||
{
|
||||
if (ram1[0x80] == 0x77)
|
||||
{
|
||||
/* the Z80 stops the music */
|
||||
cps2turbo_music_stop();
|
||||
ram2[0x27] = 0xc9; /* QSound music volume back on */
|
||||
ram1[0x80] = 0xff;
|
||||
ram1[0x81] = 0xff;
|
||||
}
|
||||
else if (ram1[0x81] > 0x00 && ram1[0x81] < 0x40)
|
||||
{
|
||||
/* the Z80 starts a tune: play its sample instead, if there is one */
|
||||
int tune = ram1[0x81];
|
||||
|
||||
ram1[0x80] = 0xff;
|
||||
ram1[0x81] = 0xff;
|
||||
cps2turbo_tune = 0;
|
||||
if (cps2turbo_music_start(0, tune))
|
||||
{
|
||||
ram2[0x27] = 0x00; /* QSound music volume off */
|
||||
cps2turbo_tune = tune;
|
||||
}
|
||||
if (cps2turbo_music_start(1, tune))
|
||||
{
|
||||
ram2[0x27] = 0x00;
|
||||
cps2turbo_tune = tune;
|
||||
}
|
||||
}
|
||||
else if (ram2[0x27] == 0x00 && !sample_playing(0))
|
||||
{
|
||||
/* after a state load: no QSound music and no sample */
|
||||
cps2turbo_music_stop();
|
||||
ram2[0x27] = 0xc9;
|
||||
ram1[0x80] = 0xff;
|
||||
ram1[0x81] = 0xff;
|
||||
}
|
||||
else if (ram2[0x27] != 0x00 && sample_playing(0))
|
||||
{
|
||||
/* after a state load: QSound music and a sample */
|
||||
cps2turbo_music_stop();
|
||||
ram2[0x27] = 0xc9;
|
||||
ram1[0x80] = 0xff;
|
||||
ram1[0x81] = 0xff;
|
||||
}
|
||||
else if (data == 0x55)
|
||||
{
|
||||
/* boot */
|
||||
cps2turbo_music_stop();
|
||||
}
|
||||
}
|
||||
|
||||
ram1[offset] = data;
|
||||
}
|
||||
|
||||
static MEMORY_READ16_START( cps2turbo_readmem )
|
||||
{ 0x000000, 0x5fffff, MRA16_ROM }, /* 68000 ROM */
|
||||
{ 0x618000, 0x619fff, qsound_sharedram1_r }, /* Q RAM */
|
||||
{ 0x660000, 0x663fff, MRA16_RAM }, /* Extra RAM, as on the other CPS2 games */
|
||||
{ 0x664000, 0x664001, MRA16_RAM }, /* Unknown */
|
||||
{ 0x665000, 0x66500b, MRA16_RAM }, /* CPS2 object output (0x400000 on CPS2) */
|
||||
{ 0x708000, 0x709fff, cps2_objram2_r }, /* Object RAM */
|
||||
{ 0x70a000, 0x70bfff, cps2_objram2_r }, /* mirror */
|
||||
{ 0x70c000, 0x70dfff, cps2_objram2_r }, /* mirror */
|
||||
{ 0x70e000, 0x70ffff, cps2_objram2_r }, /* mirror */
|
||||
{ 0x800100, 0x8001ff, cps1_output_r }, /* Output ports mirror (sfa) */
|
||||
{ 0x804000, 0x804001, input_port_0_word_r }, /* IN0 */
|
||||
{ 0x804010, 0x804011, input_port_1_word_r }, /* IN1 */
|
||||
{ 0x804020, 0x804021, cps2_eeprom_port_r }, /* IN2 + EEPROM */
|
||||
{ 0x804030, 0x804031, cps2_qsound_volume_r }, /* Master volume */
|
||||
{ 0x8040b0, 0x8040b3, kludge_r }, /* unknown */
|
||||
{ 0x804100, 0x8041ff, cps1_output_r }, /* CPS1 Output ports */
|
||||
{ 0x900000, 0x92ffff, MRA16_RAM }, /* Video RAM */
|
||||
{ 0xfffff0, 0xfffffb, cps2turbo_output_mirror_r }, /* CPS2 object output */
|
||||
{ 0xff0000, 0xffffff, MRA16_RAM }, /* RAM */
|
||||
MEMORY_END
|
||||
|
||||
static MEMORY_WRITE16_START( cps2turbo_writemem )
|
||||
{ 0x000000, 0x5fffff, MWA16_ROM }, /* ROM */
|
||||
{ 0x618000, 0x619fff, cps2turbo_qsound_sharedram1_w }, /* Q RAM + music samples */
|
||||
{ 0x660000, 0x663fff, MWA16_RAM }, /* Extra RAM */
|
||||
{ 0x664000, 0x664001, MWA16_RAM }, /* Unknown */
|
||||
{ 0x665000, 0x66500b, MWA16_RAM, &cps2_output, &cps2_output_size }, /* CPS2 object output */
|
||||
{ 0x700000, 0x701fff, cps2_objram1_w, &cps2_objram1 }, /* Object RAM, no game seems to use it directly */
|
||||
{ 0x708000, 0x709fff, cps2_objram2_w, &cps2_objram2 }, /* Object RAM */
|
||||
{ 0x70a000, 0x70bfff, cps2_objram2_w }, /* mirror */
|
||||
{ 0x70c000, 0x70dfff, cps2_objram2_w }, /* mirror */
|
||||
{ 0x70e000, 0x70ffff, cps2_objram2_w }, /* mirror */
|
||||
{ 0x800100, 0x8001ff, cps1_output_w }, /* Output ports mirror (sfa) */
|
||||
{ 0x804040, 0x804041, cps2_eeprom_port_w }, /* EEPROM */
|
||||
{ 0x8040a0, 0x8040a1, MWA16_NOP }, /* Unknown (reset once on startup) */
|
||||
{ 0x8040e0, 0x8040e1, cps2_objram_bank_w }, /* bit 0 = Object ram bank swap */
|
||||
{ 0x804100, 0x8041ff, cps1_output_w, &cps1_output, &cps1_output_size }, /* Output ports */
|
||||
{ 0x900000, 0x92ffff, cps1_gfxram_w, &cps1_gfxram, &cps1_gfxram_size },
|
||||
{ 0xfffff0, 0xfffffb, cps2turbo_output_mirror_w }, /* CPS2 object output */
|
||||
{ 0xff0000, 0xffffff, MWA16_RAM }, /* RAM */
|
||||
MEMORY_END
|
||||
|
||||
/* the aspect ratio DIP switch is for the display only, the game doesn't read it */
|
||||
static VIDEO_UPDATE( cps2turbo )
|
||||
{
|
||||
static const int aspect[4][2] = { { 16, 9 }, { 4, 3 }, { 112, 81 }, { 16, 9 } };
|
||||
int dip = readinputport(3) & 0x03;
|
||||
|
||||
set_display_aspect_ratio(aspect[dip][0], aspect[dip][1]);
|
||||
video_update_cps1(bitmap, cliprect);
|
||||
}
|
||||
|
||||
static MACHINE_DRIVER_START( cps2turbo )
|
||||
|
||||
/* basic machine hardware */
|
||||
MDRV_CPU_ADD(M68000, 23600000) /* 32MHz, slowed down like the CPS2 16MHz (11.8MHz) */
|
||||
MDRV_CPU_CONFIG(cps2_encryption)
|
||||
MDRV_CPU_MEMORY(cps2turbo_readmem,cps2turbo_writemem)
|
||||
MDRV_CPU_VBLANK_INT(cps2_interrupt,262) /* 262 ??? interrupts per frame*/
|
||||
|
||||
MDRV_CPU_ADD(Z80, 16000000)
|
||||
MDRV_CPU_MEMORY(qsound_readmem,qsound_writemem)
|
||||
MDRV_CPU_PERIODIC_INT(irq0_line_hold,251)
|
||||
|
||||
MDRV_FRAMES_PER_SECOND(59.633333)
|
||||
MDRV_VBLANK_DURATION(0)
|
||||
|
||||
MDRV_NVRAM_HANDLER(cps2)
|
||||
|
||||
/* video hardware */
|
||||
MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER | VIDEO_NEEDS_6BITS_PER_GUN | VIDEO_UPDATE_BEFORE_VBLANK)
|
||||
MDRV_SCREEN_SIZE(64*8, 32*8)
|
||||
MDRV_VISIBLE_AREA(6*8, (64-6)*8-1, 12, 12+234-1 ) /* 416x234 */
|
||||
MDRV_ASPECT_RATIO(16,9)
|
||||
MDRV_GFXDECODE(gfxdecodeinfo)
|
||||
MDRV_PALETTE_LENGTH(4096)
|
||||
|
||||
MDRV_VIDEO_START(cps2turbo)
|
||||
MDRV_VIDEO_EOF(cps1)
|
||||
MDRV_VIDEO_UPDATE(cps2turbo)
|
||||
|
||||
/* sound hardware */
|
||||
MDRV_SOUND_ATTRIBUTES(SOUND_SUPPORTS_STEREO)
|
||||
MDRV_SOUND_ADD(QSOUND, qsound_interface)
|
||||
MDRV_SOUND_ADD(SAMPLES, sfz3mix_samples_interface)
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
/* the samples aren't in the states: start again the tune of the state */
|
||||
static void cps2turbo_music_postload(void)
|
||||
{
|
||||
int tune = cps2turbo_tune;
|
||||
|
||||
cps2turbo_music_stop();
|
||||
if (tune)
|
||||
{
|
||||
int playing = cps2turbo_music_start(0, tune);
|
||||
|
||||
playing |= cps2turbo_music_start(1, tune);
|
||||
if (playing)
|
||||
cps2turbo_tune = tune;
|
||||
}
|
||||
}
|
||||
|
||||
static DRIVER_INIT( cps2turbo )
|
||||
{
|
||||
init_my_cps2();
|
||||
|
||||
cps2turbo_tune = 0;
|
||||
state_save_register_int("cps2turbo", 0, "tune", &cps2turbo_tune);
|
||||
state_save_register_func_postload(cps2turbo_music_postload);
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* ROM definitions
|
||||
@@ -7439,6 +7884,27 @@ ROM_START( sfz3ar1 )
|
||||
ROM_LOAD( "sfz3a.key", 0x000000, 0x000014, CRC(09045d61) SHA1(0cfeb0b53973fff08b673a10b1f7e6e3b46aa214) )
|
||||
ROM_END
|
||||
|
||||
/* Street Fighter Zero 3 Mix v0.32 - hack of Street Fighter Zero 3 by Zero800, on his CPS2Turbo hardware.
|
||||
https://sfz3mix.github.io/ - ROM names follow the FBNeo set. Only the first 4MB of the program are used.
|
||||
The optional music samples (samples/sfz3mix.zip, L01.wav ... R3F.wav) come from the site too. */
|
||||
ROM_START( sfz3mix )
|
||||
ROM_REGION( 0x600000, REGION_CPU1, 0 ) /* 68000 code */
|
||||
ROM_LOAD16_WORD( "sz3mx.03", 0x000000, 0x600000, CRC(7a968da6) SHA1(5656ff21d6b23f8eab21e9d7e222461ceefed69e) )
|
||||
|
||||
ROM_REGION( 0x4000000, REGION_GFX1, 0 )
|
||||
ROM_LOAD( "sz3mx.13m", 0x0000000, 0x2000000, CRC(5389b651) SHA1(6032a925a0f37773fb26a1800d568dde0ea3082e) )
|
||||
ROM_LOAD( "sz3mx.21m", 0x2000000, 0x2000000, CRC(914c7031) SHA1(7b7ce04e563ef23f6f9454f268a968b9114ac729) )
|
||||
|
||||
ROM_REGION( 0x80000, REGION_CPU2, 0 ) /* 64k for the audio CPU (+banks) */
|
||||
ROM_LOAD( "sz3mx.01", 0x00000, 0x80000, CRC(52f98a5c) SHA1(5e1251b85d0bfb707b3e519aeb3a716893191a20) )
|
||||
|
||||
ROM_REGION( 0x1000000, REGION_SOUND1, 0 ) /* QSound samples */
|
||||
ROM_LOAD( "sz3mx.11m", 0x000000, 0x1000000, CRC(395edce2) SHA1(0f6a4be84ed1e1a13319a480b41c1f35b36f35fc) )
|
||||
|
||||
ROM_REGION( 0x20, REGION_USER5, 0 )
|
||||
ROM_LOAD( "phoenix.key", 0x000000, 0x000014, CRC(2cf772b0) SHA1(eff33c65a4f3862c231f9e4d6fefa7b34398dbf2) )
|
||||
ROM_END
|
||||
|
||||
ROM_START( sfa3h )
|
||||
ROM_REGION( CODE_SIZE, REGION_CPU1, 0 ) /* 68000 code */
|
||||
ROM_LOAD16_WORD_SWAP( "sz3h.03c", 0x000000, 0x80000, CRC(b3b563a3) SHA1(27863508fedeb5d85e78b8d64361f0000d00e0a5) )
|
||||
@@ -7791,6 +8257,34 @@ ROM_START( spf2th )
|
||||
ROM_LOAD( "spf2th.key", 0x000000, 0x000014, CRC(292db449) SHA1(e0b82bd471ceadcee1e52ff5a4a8835d53a84a66) )
|
||||
ROM_END
|
||||
|
||||
/* Super Puzzle Fighter 2 X' (X Prime) - fan rebalance hack by Kaito Sinclaire, based on the Euro set (spf2t).
|
||||
Recreates the X' balance changes from Super Puzzle Fighter II HD Remix.
|
||||
https://github.com/KScl/puzzle-fighter-x-prime - ROM names follow the Fightcade set. */
|
||||
ROM_START( spf2xpri )
|
||||
ROM_REGION(CODE_SIZE, REGION_CPU1, 0 ) /* 68000 code */
|
||||
ROM_LOAD16_WORD_SWAP( "pzfxp.03", 0x000000, 0x80000, CRC(f205a7da) SHA1(3fa4b7ecc54d239061148781ecdc469f975122af) )
|
||||
ROM_LOAD16_WORD_SWAP( "pzfxp.04", 0x080000, 0x80000, CRC(4177aadd) SHA1(c218d2446f3fc348a952a8b7a75dace864fed0f9) )
|
||||
|
||||
ROM_REGION( 0xC00000, REGION_GFX1, 0 )
|
||||
ROM_FILL( 0x000000, 0x800000, 0x00 )
|
||||
ROM_LOAD64_WORD( "pzfxp.14m", 0x800000, 0x100000, CRC(930b0ec7) SHA1(60b786dca5a943010b0273a5f6d084453a3bd121) )
|
||||
ROM_LOAD64_WORD( "pzfxp.16m", 0x800002, 0x100000, CRC(769377ad) SHA1(eb86026999ab01e74a975d03305d637899615bf4) )
|
||||
ROM_LOAD64_WORD( "pzfxp.18m", 0x800004, 0x100000, CRC(5a79233f) SHA1(31ca4744be2d7860351dc56fbb3e03e0ddf35b09) )
|
||||
ROM_LOAD64_WORD( "pzfxp.20m", 0x800006, 0x100000, CRC(42cfc9e2) SHA1(04cadb017163732f5ba022733d0cb442ce3cada3) )
|
||||
|
||||
ROM_REGION(QSOUND_SIZE, REGION_CPU2, 0 ) /* 64k for the audio CPU (+banks) */
|
||||
ROM_LOAD( "pzf.01", 0x00000, 0x08000, CRC(600fb2a3) SHA1(1fab1c2a23bf6ad8309d29ddbbc29435a8aeea13) )
|
||||
ROM_CONTINUE( 0x10000, 0x18000 )
|
||||
ROM_LOAD( "pzf.02", 0x28000, 0x20000, CRC(496076e0) SHA1(1ee4e135140afd0e8e03231e570cd77d140f6367) )
|
||||
|
||||
ROM_REGION( 0x400000, REGION_SOUND1, 0 ) /* QSound samples */
|
||||
ROM_LOAD16_WORD_SWAP( "pzf.11m", 0x000000, 0x200000, CRC(78442743) SHA1(b61190bb586871de6d54af580e3e1d9cc0de0acb) )
|
||||
ROM_LOAD16_WORD_SWAP( "pzf.12m", 0x200000, 0x200000, CRC(399d2c7b) SHA1(e849dea97b8d16540415c0d9bbc4f9f4eb755ec4) )
|
||||
|
||||
ROM_REGION( 0x20, REGION_USER5, 0 )
|
||||
ROM_LOAD( "spf2t.key", 0x000000, 0x000014, CRC(4c4dc7e3) SHA1(db4f257f6006b2f3cfa7cc70917228d639324513) )
|
||||
ROM_END
|
||||
|
||||
ROM_START( ssf2 )
|
||||
ROM_REGION( CODE_SIZE, REGION_CPU1, 0 ) /* 68000 code */
|
||||
ROM_LOAD16_WORD_SWAP( "ssfe-03b", 0x000000, 0x80000, CRC(af654792) SHA1(a8e84154a639c036413f1423aaf2312a5affa55a) )
|
||||
@@ -11849,6 +12343,7 @@ GAME( 1996, spf2tu, spf2t, cps2, cps2_2p2b, my_cps2, ROT0, "Ca
|
||||
GAME( 1996, spf2xj, spf2t, cps2, cps2_2p2b, my_cps2, ROT0, "Capcom", "Super Puzzle Fighter II X (Japan 960531)")
|
||||
GAME( 1996, spf2ta, spf2t, cps2, cps2_2p2b, my_cps2, ROT0, "Capcom", "Super Puzzle Fighter II Turbo (Asia 960529)")
|
||||
GAME( 1996, spf2th, spf2t, cps2, cps2_2p2b, my_cps2, ROT0, "Capcom", "Super Puzzle Fighter II Turbo (Hispanic 960531)")
|
||||
GAME( 2021, spf2xpri, spf2t, cps2, cps2_2p2b, my_cps2, ROT0, "hack", "Super Puzzle Fighter 2 X'")
|
||||
GAME( 1996, megaman2, 0, cps2, cps2_2p3b, my_cps2, ROT0, "Capcom", "Mega Man 2: The Power Fighters (USA 960708)")
|
||||
GAME( 1996, megaman2a, megaman2, cps2, cps2_2p3b, my_cps2, ROT0, "Capcom", "Mega Man 2: The Power Fighters (Asia 960708)")
|
||||
GAME( 1996, rockman2j, megaman2, cps2, cps2_2p3b, my_cps2, ROT0, "Capcom", "Rockman 2: The Power Fighters (Japan 960708)")
|
||||
@@ -11925,6 +12420,7 @@ GAME( 1998, sfz3jr1, sfa3, cps2, cps2_2p6b, my_cps2, ROT0, "Ca
|
||||
GAME( 1998, sfz3jr2, sfa3, cps2, cps2_2p6b, my_cps2, ROT0, "Capcom", "Street Fighter Zero 3 (Japan 980629)")
|
||||
GAME( 1998, sfz3a, sfa3, cps2, cps2_2p6b, my_cps2, ROT0, "Capcom", "Street Fighter Zero 3 (Asia 980904)")
|
||||
GAME( 1998, sfz3ar1, sfa3, cps2, cps2_2p6b, my_cps2, ROT0, "Capcom", "Street Fighter Zero 3 (Asia 980701)")
|
||||
GAME( 2026, sfz3mix, sfa3, cps2turbo, sfz3mix, cps2turbo, ROT0, "hack", "Street Fighter Zero 3 Mix v0.32 (CPS2Turbo)")
|
||||
GAME( 1999, jyangoku, 0, cps2, cps2_1p2b, my_cps2, ROT0, "Capcom", "Jyangokushi: Haoh no Saihai (Japan 990527)")
|
||||
GAMEC( 2004, hsf2, 0, cps2, cps2_2p6b, my_cps2, ROT0, "Capcom", "Hyper Street Fighter II: The Anniversary Edition (USA 040202)", &sf2_ctrl, NULL )
|
||||
GAMEC( 2004, hsf2a, hsf2, cps2, cps2_2p6b, my_cps2, ROT0, "Capcom", "Hyper Street Fighter II: The Anniversary Edition (Asia 040202)", &sf2_ctrl, NULL )
|
||||
|
||||
+2746
File diff suppressed because it is too large.
Load diff
+386
-303
@@ -25,6 +25,8 @@
|
||||
between the two palettes. This effect is not emulated, but since both
|
||||
halfs of the palette are identical, this is not an issue. See $039c.
|
||||
The other games have a different color test, not using the busy loop.
|
||||
- dealer/beastf/revngr84: "PSG registers not OK" in service mode thru
|
||||
sound menu, internal ay8910 not right? (same in current MAME)
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
@@ -32,41 +34,7 @@
|
||||
#include "vidhrdw/generic.h"
|
||||
#include "machine/8255ppi.h"
|
||||
#include "epos.h"
|
||||
|
||||
|
||||
static int counter = 0;
|
||||
|
||||
MACHINE_INIT( dealer );
|
||||
|
||||
WRITE_HANDLER( dealer_decrypt_rom )
|
||||
{
|
||||
unsigned char *RAM = memory_region(REGION_CPU1);
|
||||
|
||||
if (offset & 0x04)
|
||||
{
|
||||
counter = counter + 1;
|
||||
if (counter < 0)
|
||||
counter = 0x0F;
|
||||
}
|
||||
else
|
||||
{
|
||||
counter = (counter - 1) & 0x0F;
|
||||
}
|
||||
|
||||
/* log_cb(RETRO_LOG_DEBUG, LOGPRE "PC %08x: ctr=%04x\n",activecpu_get_pc(),counter);*/
|
||||
|
||||
switch(counter)
|
||||
{
|
||||
|
||||
case 0x00: cpu_setbank(1, &RAM[0x10000]); break;
|
||||
case 0x01: cpu_setbank(1, &RAM[0x20000]); break;
|
||||
case 0x02: cpu_setbank(1, &RAM[0x30000]); break;
|
||||
case 0x03: cpu_setbank(1, &RAM[0x40000]); break;
|
||||
default:
|
||||
log_cb(RETRO_LOG_DEBUG, LOGPRE "Invalid counter = %02X\n",counter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#include "state.h"
|
||||
|
||||
|
||||
/*************************************
|
||||
@@ -88,17 +56,6 @@ static MEMORY_WRITE_START( writemem )
|
||||
MEMORY_END
|
||||
|
||||
|
||||
static MEMORY_READ_START( dealer_readmem )
|
||||
{ 0x0000, 0x6fff, MRA_BANK1 },
|
||||
{ 0x7000, 0xffff, MRA_RAM },
|
||||
MEMORY_END
|
||||
|
||||
static MEMORY_WRITE_START( dealer_writemem )
|
||||
{ 0x0000, 0x6fff, MWA_ROM },
|
||||
{ 0x7000, 0x7fff, MWA_RAM },
|
||||
{ 0x8000, 0xffff, epos_videoram_w, &videoram, &videoram_size },
|
||||
MEMORY_END
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Main CPU port handlers
|
||||
@@ -121,28 +78,6 @@ static PORT_WRITE_START( writeport )
|
||||
PORT_END
|
||||
|
||||
|
||||
static PORT_READ_START( dealer_readport )
|
||||
{ 0x10, 0x13, ppi8255_0_r },
|
||||
{ 0x38, 0x38, input_port_0_r },
|
||||
PORT_END
|
||||
|
||||
static PORT_WRITE_START( dealer_writeport )
|
||||
{ 0x10, 0x13, ppi8255_0_w },
|
||||
{ 0x20, 0x24, dealer_decrypt_rom },
|
||||
/* { 0x40, 0x40, watchdog_reset_w },*/
|
||||
PORT_END
|
||||
|
||||
static ppi8255_interface ppi8255_intf =
|
||||
{
|
||||
1, /* 1 chip */
|
||||
{ input_port_2_r }, /* Port A read */
|
||||
{ NULL }, /* Port B read */
|
||||
{ NULL }, /* Port C read */
|
||||
{ NULL }, /* Port A write */
|
||||
{ NULL }, /* Port B write */
|
||||
{ NULL }, /* Port C write */
|
||||
};
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Port definitions
|
||||
@@ -352,55 +287,6 @@ INPUT_PORTS_START( igmo )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
INPUT_PORTS_START( dealer )
|
||||
PORT_START /* IN0 */
|
||||
PORT_DIPNAME( 0x01, 0x00, DEF_STR( Demo_Sounds ) )
|
||||
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Free_Play ) )
|
||||
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unused ) )
|
||||
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unused ) )
|
||||
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unused ) )
|
||||
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unused ) )
|
||||
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Cabinet ) )
|
||||
PORT_DIPSETTING( 0x40, DEF_STR( Upright ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) )
|
||||
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Flip_Screen ) )
|
||||
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
|
||||
PORT_START /* IN1 */
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
|
||||
PORT_START /* IN2 */
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) /*cancel*/
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) /*draw*/
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) /*stand*/
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON4 )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON5 ) /*play*/
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON6 )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON7 ) /*coin in*/
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON8 )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Sound interfaces
|
||||
@@ -444,7 +330,7 @@ static MACHINE_DRIVER_START( epos )
|
||||
MDRV_PALETTE_LENGTH(32)
|
||||
|
||||
MDRV_PALETTE_INIT(epos)
|
||||
MDRV_VIDEO_START(generic_bitmapped)
|
||||
MDRV_VIDEO_START(epos)
|
||||
MDRV_VIDEO_UPDATE(epos)
|
||||
|
||||
/* sound hardware */
|
||||
@@ -452,32 +338,6 @@ static MACHINE_DRIVER_START( epos )
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
|
||||
static MACHINE_DRIVER_START( dealer )
|
||||
/* basic machine hardware */
|
||||
MDRV_CPU_ADD(Z80, 11000000/4) /* 2.75 MHz (see notes) */
|
||||
MDRV_CPU_MEMORY(dealer_readmem,dealer_writemem)
|
||||
MDRV_CPU_PORTS(dealer_readport,dealer_writeport)
|
||||
MDRV_CPU_VBLANK_INT(irq0_line_hold,1)
|
||||
|
||||
MDRV_FRAMES_PER_SECOND(60)
|
||||
MDRV_VBLANK_DURATION(DEFAULT_REAL_60HZ_VBLANK_DURATION)
|
||||
|
||||
/* video hardware */
|
||||
MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
|
||||
MDRV_SCREEN_SIZE(272, 241)
|
||||
MDRV_VISIBLE_AREA(0, 271, 0, 235)
|
||||
MDRV_PALETTE_LENGTH(32)
|
||||
|
||||
MDRV_PALETTE_INIT(epos)
|
||||
MDRV_VIDEO_START(generic_bitmapped)
|
||||
MDRV_VIDEO_UPDATE(epos)
|
||||
MDRV_MACHINE_INIT(dealer)
|
||||
|
||||
/* sound hardware */
|
||||
MDRV_SOUND_ADD(AY8910, ay8912_interface)
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* ROM definitions
|
||||
@@ -612,180 +472,400 @@ ROM_START( igmo )
|
||||
ROM_END
|
||||
|
||||
|
||||
ROM_START( dealer )
|
||||
ROM_REGION( 0x50000, REGION_CPU1, 0 )
|
||||
ROM_LOAD( "u1.bin", 0x0000, 0x2000, CRC(e06f3563) SHA1(0d58cd1f2e1ca89adb9c64d7dd520bb1f2d50f1a) )
|
||||
ROM_LOAD( "u2.bin", 0x2000, 0x2000, CRC(726bbbd6) SHA1(3538f3d655899c2a0f984c43fb7545ea4be1b231) )
|
||||
ROM_LOAD( "u3.bin", 0x4000, 0x2000, CRC(ab721455) SHA1(a477da0590e0431172baae972e765473e19dcbff) )
|
||||
ROM_LOAD( "u4.bin", 0x6000, 0x2000, BAD_DUMP CRC(ddb903e4) SHA1(4c06a2048b1c6989c363b110a17c33180025b9c8) )
|
||||
/*************************************
|
||||
*
|
||||
* Epos Tristar 9000 (from current MAME)
|
||||
*
|
||||
* - the program ROMs are encrypted: a counter changed by writes to
|
||||
* ports 0x20-0x24 selects one of four decryption keys for 0x0000-0x5fff
|
||||
* - 0x6000-0x6fff is one half of U04, selected by the PPI port C (bit 0);
|
||||
* U04 is kept at 0x16000 in the region, as 0x7000-0x7fff is RAM here
|
||||
* - the palette is in RAM (ports 0x00-0x0f), there is no color PROM
|
||||
* - 0x7000-0x7fff is battery backed, with a default image per game
|
||||
* - the inputs are two groups selected by the PPI port C (bits 5-6),
|
||||
* read on the PPI port A; the DIP switches are read on the AY8910 port A
|
||||
* - the AY8910 port B selects the DIP switches (bit 6) and flips the
|
||||
* screen (bit 7)
|
||||
*
|
||||
*************************************/
|
||||
|
||||
ROM_REGION( 0x0020, REGION_PROMS, 0 )
|
||||
ROM_LOAD( "82s123.u66", 0x0000, 0x0020, NO_DUMP ) /* missing */
|
||||
static int tristar9000_counter;
|
||||
static int tristar9000_rombank;
|
||||
static int tristar9000_input_mux;
|
||||
static int tristar9000_ay_porta_mux;
|
||||
static int tristar9000_flip;
|
||||
static int tristar9000_portc; /* last value written to the PPI port C */
|
||||
|
||||
static void tristar9000_set_banks(void)
|
||||
{
|
||||
data8_t *rom = memory_region(REGION_CPU1);
|
||||
|
||||
cpu_setbank(1, &rom[0x10000 * tristar9000_counter]);
|
||||
cpu_setbank(2, &rom[0x16000 + 0x1000 * tristar9000_rombank]);
|
||||
}
|
||||
|
||||
static WRITE_HANDLER( tristar9000_decrypt_rom_w )
|
||||
{
|
||||
if (offset & 0x04)
|
||||
tristar9000_counter = (tristar9000_counter + 1) & 0x03;
|
||||
else
|
||||
tristar9000_counter = (tristar9000_counter - 1) & 0x03;
|
||||
|
||||
tristar9000_set_banks();
|
||||
}
|
||||
|
||||
static READ_HANDLER( tristar9000_ppi_porta_r )
|
||||
{
|
||||
data8_t data = 0xff;
|
||||
|
||||
if (!(tristar9000_input_mux & 1))
|
||||
data &= readinputport(2);
|
||||
|
||||
if (!(tristar9000_input_mux & 2))
|
||||
data &= readinputport(3);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
ROMs U01-U03 are checked with the same code in a loop.
|
||||
There's a separate ROM check for banked U04 at 30F3.
|
||||
*/
|
||||
static WRITE_HANDLER( tristar9000_ppi_portc_w )
|
||||
{
|
||||
tristar9000_portc = data;
|
||||
tristar9000_rombank = data & 0x01;
|
||||
tristar9000_input_mux = (data >> 5) & 3;
|
||||
tristar9000_set_banks();
|
||||
}
|
||||
|
||||
static READ_HANDLER( tristar9000_ay_porta_r )
|
||||
{
|
||||
return tristar9000_ay_porta_mux ? 0xff : readinputport(0);
|
||||
}
|
||||
|
||||
static WRITE_HANDLER( tristar9000_ay_portb_w )
|
||||
{
|
||||
/* bit 7: flip screen */
|
||||
tristar9000_flip = (data >> 7) & 1;
|
||||
epos_set_flipscreen(tristar9000_flip);
|
||||
|
||||
/* bit 6: AY8910 port A multiplexer */
|
||||
tristar9000_ay_porta_mux = (data >> 6) & 1;
|
||||
}
|
||||
|
||||
static ppi8255_interface tristar9000_ppi8255_intf =
|
||||
{
|
||||
1, /* 1 chip */
|
||||
{ tristar9000_ppi_porta_r }, /* Port A read */
|
||||
{ NULL }, /* Port B read */
|
||||
{ NULL }, /* Port C read */
|
||||
{ NULL }, /* Port A write */
|
||||
{ NULL }, /* Port B write */
|
||||
{ tristar9000_ppi_portc_w }, /* Port C write */
|
||||
};
|
||||
|
||||
static MEMORY_READ_START( tristar9000_readmem )
|
||||
{ 0x0000, 0x5fff, MRA_BANK1 },
|
||||
{ 0x6000, 0x6fff, MRA_BANK2 },
|
||||
{ 0x7000, 0xffff, MRA_RAM },
|
||||
MEMORY_END
|
||||
|
||||
static MEMORY_WRITE_START( tristar9000_writemem )
|
||||
{ 0x0000, 0x6fff, MWA_ROM },
|
||||
{ 0x7000, 0x7fff, MWA_RAM, &generic_nvram, &generic_nvram_size },
|
||||
{ 0x8000, 0xffff, epos_videoram_w, &videoram, &videoram_size },
|
||||
MEMORY_END
|
||||
|
||||
static PORT_READ_START( tristar9000_readport )
|
||||
{ 0x10, 0x13, ppi8255_0_r },
|
||||
{ 0x38, 0x38, AY8910_read_port_0_r },
|
||||
PORT_END
|
||||
|
||||
static PORT_WRITE_START( tristar9000_writeport )
|
||||
{ 0x00, 0x0f, epos_palette_w },
|
||||
{ 0x10, 0x13, ppi8255_0_w },
|
||||
{ 0x20, 0x24, tristar9000_decrypt_rom_w },
|
||||
{ 0x34, 0x34, AY8910_write_port_0_w },
|
||||
{ 0x3c, 0x3c, AY8910_control_port_0_w },
|
||||
{ 0x40, 0x40, watchdog_reset_w },
|
||||
PORT_END
|
||||
|
||||
|
||||
INPUT_PORTS_START( dealer )
|
||||
PORT_START /* DSW, read on the AY8910 port A */
|
||||
PORT_DIPNAME( 0x01, 0x00, DEF_STR( Demo_Sounds ) )
|
||||
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Free_Play ) )
|
||||
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unused ) )
|
||||
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unused ) )
|
||||
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unused ) )
|
||||
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unused ) )
|
||||
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Cabinet ) )
|
||||
PORT_DIPSETTING( 0x40, DEF_STR( Upright ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) )
|
||||
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Flip_Screen ) )
|
||||
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
|
||||
PORT_START /* SYSTEM (not connected) */
|
||||
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
|
||||
PORT_START /* INPUTS, PPI port A, group 1 */
|
||||
PORT_BITX(0x01, IP_ACTIVE_LOW, IPT_BUTTON1, "Hold 1", IP_KEY_DEFAULT, IP_JOY_DEFAULT )
|
||||
PORT_BITX(0x02, IP_ACTIVE_LOW, IPT_BUTTON2, "Hold 2", IP_KEY_DEFAULT, IP_JOY_DEFAULT )
|
||||
PORT_BITX(0x04, IP_ACTIVE_LOW, IPT_BUTTON3, "Hold 3", IP_KEY_DEFAULT, IP_JOY_DEFAULT )
|
||||
PORT_BITX(0x08, IP_ACTIVE_LOW, IPT_BUTTON4, "Hold 4", IP_KEY_DEFAULT, IP_JOY_DEFAULT )
|
||||
PORT_BITX(0x10, IP_ACTIVE_LOW, IPT_BUTTON5, "Hold 5", IP_KEY_DEFAULT, IP_JOY_DEFAULT )
|
||||
PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
|
||||
PORT_START /* INPUTS2, PPI port A, group 2 */
|
||||
PORT_BITX(0x01, IP_ACTIVE_LOW, IPT_BUTTON6, "Cancel", IP_KEY_DEFAULT, IP_JOY_DEFAULT )
|
||||
PORT_BITX(0x02, IP_ACTIVE_LOW, IPT_BUTTON7, "Draw", IP_KEY_DEFAULT, IP_JOY_DEFAULT )
|
||||
PORT_BITX(0x04, IP_ACTIVE_LOW, IPT_BUTTON8, "Stand", IP_KEY_DEFAULT, IP_JOY_DEFAULT )
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BITX(0x10, IP_ACTIVE_LOW, IPT_START1, "Play", IP_KEY_DEFAULT, IP_JOY_DEFAULT )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 )
|
||||
PORT_BITX(0x80, IP_ACTIVE_LOW, IPT_SERVICE, DEF_STR( Service_Mode ), KEYCODE_F2, IP_JOY_NONE )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
INPUT_PORTS_START( beastf )
|
||||
PORT_START /* DSW, read on the AY8910 port A */
|
||||
PORT_DIPNAME( 0x01, 0x00, DEF_STR( Demo_Sounds ) )
|
||||
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Free_Play ) )
|
||||
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unused ) )
|
||||
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unused ) )
|
||||
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unused ) )
|
||||
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unused ) )
|
||||
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Cabinet ) )
|
||||
PORT_DIPSETTING( 0x40, DEF_STR( Upright ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) )
|
||||
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Flip_Screen ) )
|
||||
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
|
||||
PORT_START /* SYSTEM (not connected) */
|
||||
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
|
||||
PORT_START /* INPUTS, PPI port A, group 1 */
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_4WAY )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_4WAY )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_4WAY )
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_4WAY )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 )
|
||||
|
||||
PORT_START /* INPUTS2, PPI port A, group 2 */
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_4WAY | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_4WAY | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_4WAY | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_4WAY | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 )
|
||||
PORT_BITX(0x80, IP_ACTIVE_LOW, IPT_SERVICE, DEF_STR( Service_Mode ), KEYCODE_F2, IP_JOY_NONE )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
static struct AY8910interface tristar9000_ay8910_interface =
|
||||
{
|
||||
1, /* 1 chip */
|
||||
22118400/32, /* 0.6912 MHz (measured) */
|
||||
{ 50 },
|
||||
{ tristar9000_ay_porta_r },
|
||||
{ 0 },
|
||||
{ 0 },
|
||||
{ tristar9000_ay_portb_w }
|
||||
};
|
||||
|
||||
|
||||
/* the battery backed RAM starts with the game's default image */
|
||||
static NVRAM_HANDLER( tristar9000 )
|
||||
{
|
||||
if (read_or_write)
|
||||
mame_fwrite(file, generic_nvram, generic_nvram_size);
|
||||
else if (file)
|
||||
mame_fread(file, generic_nvram, generic_nvram_size);
|
||||
else if (memory_region(REGION_USER1))
|
||||
memcpy(generic_nvram, memory_region(REGION_USER1), generic_nvram_size);
|
||||
else
|
||||
memset(generic_nvram, 0, generic_nvram_size);
|
||||
}
|
||||
|
||||
static MACHINE_INIT( tristar9000 )
|
||||
{
|
||||
ppi8255_init(&tristar9000_ppi8255_intf);
|
||||
|
||||
tristar9000_counter = 0;
|
||||
tristar9000_rombank = 0;
|
||||
tristar9000_input_mux = 3;
|
||||
tristar9000_ay_porta_mux = 0;
|
||||
tristar9000_flip = 0;
|
||||
tristar9000_portc = 0;
|
||||
epos_set_flipscreen(0);
|
||||
tristar9000_set_banks();
|
||||
}
|
||||
|
||||
static void tristar9000_postload(void)
|
||||
{
|
||||
/* the PPI is not in the save states: restore its port C latch (all the
|
||||
port C bits are outputs on this board), which also sets the banks */
|
||||
ppi8255_w(0, 2, tristar9000_portc);
|
||||
tristar9000_set_banks();
|
||||
epos_set_flipscreen(tristar9000_flip);
|
||||
}
|
||||
|
||||
static MACHINE_DRIVER_START( tristar9000 )
|
||||
|
||||
/* basic machine hardware */
|
||||
MDRV_CPU_ADD(Z80, 22118400/8) /* 2.7648 MHz (measured) */
|
||||
MDRV_CPU_MEMORY(tristar9000_readmem,tristar9000_writemem)
|
||||
MDRV_CPU_PORTS(tristar9000_readport,tristar9000_writeport)
|
||||
MDRV_CPU_VBLANK_INT(irq0_line_hold,1)
|
||||
|
||||
MDRV_FRAMES_PER_SECOND(60)
|
||||
MDRV_VBLANK_DURATION(DEFAULT_REAL_60HZ_VBLANK_DURATION)
|
||||
|
||||
MDRV_MACHINE_INIT(tristar9000)
|
||||
MDRV_NVRAM_HANDLER(tristar9000)
|
||||
|
||||
/* video hardware */
|
||||
MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
|
||||
MDRV_SCREEN_SIZE(272, 241)
|
||||
MDRV_VISIBLE_AREA(0, 271, 0, 235)
|
||||
MDRV_PALETTE_LENGTH(32) /* RAM based palette, no PROM */
|
||||
|
||||
MDRV_VIDEO_START(epos)
|
||||
MDRV_VIDEO_UPDATE(epos)
|
||||
|
||||
/* sound hardware */
|
||||
MDRV_SOUND_ADD(AY8910, tristar9000_ay8910_interface)
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
|
||||
ROM_START( dealer )
|
||||
ROM_REGION( 0x40000, REGION_CPU1, 0 )
|
||||
ROM_LOAD( "u1.bin", 0x0000, 0x2000, CRC(e06f3563) SHA1(0d58cd1f2e1ca89adb9c64d7dd520bb1f2d50f1a) )
|
||||
ROM_LOAD( "u2.bin", 0x2000, 0x2000, CRC(726bbbd6) SHA1(3538f3d655899c2a0f984c43fb7545ea4be1b231) )
|
||||
ROM_LOAD( "u3.bin", 0x4000, 0x2000, CRC(ab721455) SHA1(a477da0590e0431172baae972e765473e19dcbff) )
|
||||
ROM_LOAD( "u4.bin", 0x6000, 0x2000, CRC(ddb903e4) SHA1(4c06a2048b1c6989c363b110a17c33180025b9c8) )
|
||||
|
||||
ROM_REGION( 0x1000, REGION_USER1, 0 ) /* default NVRAM */
|
||||
ROM_LOAD( "dealer.nv", 0, 0x1000, CRC(a6f88459) SHA1(1deda2a71433c97fe3e5cb39defc285f4fa9c9b8) )
|
||||
ROM_END
|
||||
|
||||
MACHINE_INIT( dealer )
|
||||
{
|
||||
cpu_setbank(1, memory_region(REGION_CPU1) + 0x10000);
|
||||
/*
|
||||
Revenger '84 (newer) - EPOS TRISTAR 9000
|
||||
*/
|
||||
ROM_START( revngr84 )
|
||||
ROM_REGION( 0x40000, REGION_CPU1, 0 )
|
||||
ROM_LOAD( "u_1__revenger__r06254__=c=_epos_corp.m5l2764k.u1", 0x0000, 0x2000, CRC(308f231f) SHA1(cf06695601bd0387e4fcb64d9b34143323e98b07) ) /* labeled as "U 1 // REVENGER // R06254 // (C) EPOS CORP" (hand written R06254 over R06124) */
|
||||
ROM_LOAD( "u_2__revenger__r06254__=c=_epos_corp.m5l2764k.u2", 0x2000, 0x2000, CRC(e80bbfb4) SHA1(9302beaef8bbb7376b6a20e9ee5adbcf60d66dd8) ) /* labeled as "U 2 // REVENGER // R06254 // (C) EPOS CORP" (hand written R06254 over R06124) */
|
||||
ROM_LOAD( "u_3__revenger__r06254__=c=_epos_corp.m5l2764k.u3", 0x4000, 0x2000, CRC(d9270929) SHA1(a95034b5387a40e02f04bdfa79e1d8e65dad30fe) ) /* labeled as "U 3 // REVENGER // R06254 // (C) EPOS CORP" (hand written R06254 over R06124) */
|
||||
ROM_LOAD( "u_4__revenger__r06254__=c=_epos_corp.m5l2764k.u4", 0x6000, 0x2000, CRC(d6e6cfa8) SHA1(f10131bb2e9d088c7b6d6a5d5520073d78ad69cc) ) /* labeled as "U 4 // REVENGER // R06254 // (C) EPOS CORP" (hand written R06254 over R06124) */
|
||||
|
||||
ppi8255_init(&ppi8255_intf);
|
||||
}
|
||||
ROM_REGION( 0x0020, REGION_PROMS, 0 )
|
||||
ROM_LOAD( "dm74s288n.u60", 0x0000, 0x0020, CRC(be2b0641) SHA1(26982903b6d942af8e0a526412d8e01978d76420) ) /* unknown purpose */
|
||||
|
||||
DRIVER_INIT( dealer )
|
||||
ROM_REGION( 0x1000, REGION_USER1, 0 ) /* default NVRAM */
|
||||
ROM_LOAD( "revngr84.nv", 0, 0x1000, CRC(a4417770) SHA1(92eded82db0810e7818d2f52a0497032f390fcc1) )
|
||||
ROM_END
|
||||
|
||||
/*
|
||||
Revenger '84 (older) - EPOS TRISTAR 9000
|
||||
*/
|
||||
ROM_START( revenger )
|
||||
ROM_REGION( 0x40000, REGION_CPU1, 0 )
|
||||
ROM_LOAD( "r06124.u1", 0x0000, 0x2000, BAD_DUMP CRC(fad1a2a5) SHA1(a31052c91fe67e2e90441abc40b6483f921ecfe3) )
|
||||
ROM_LOAD( "r06124.u2", 0x2000, 0x2000, BAD_DUMP CRC(a8e0ee7b) SHA1(f6f78e8ce40eab07de461b364876c1eb4a78d96e) )
|
||||
ROM_LOAD( "r06124.u3", 0x4000, 0x2000, BAD_DUMP CRC(cca414a5) SHA1(1c9dd3ff63d57e9452e63083cdbd7f5d693bb686) )
|
||||
ROM_LOAD( "r06124.u4", 0x6000, 0x2000, BAD_DUMP CRC(0b81c303) SHA1(9022d18dec11312eb4bb471c22b563f5f897b4f7) )
|
||||
|
||||
ROM_REGION( 0x0020, REGION_PROMS, 0 )
|
||||
ROM_LOAD( "dm74s288n.u60", 0x0000, 0x0020, CRC(be2b0641) SHA1(26982903b6d942af8e0a526412d8e01978d76420) ) /* unknown purpose */
|
||||
|
||||
ROM_REGION( 0x1000, REGION_USER1, 0 ) /* default NVRAM */
|
||||
ROM_LOAD( "revngr84.nv", 0, 0x1000, CRC(a4417770) SHA1(92eded82db0810e7818d2f52a0497032f390fcc1) )
|
||||
ROM_END
|
||||
|
||||
/*
|
||||
Beastie Feastie - EPOS TRISTAR 9000
|
||||
*/
|
||||
ROM_START( beastf )
|
||||
ROM_REGION( 0x40000, REGION_CPU1, 0 )
|
||||
ROM_LOAD( "u_1__beastie__feastie__b09084.m5l2764k.u1", 0x0000, 0x2000, CRC(820d4019) SHA1(e953aaeeb626776dd86c521066b553d054ae4422) ) /* labeled as "U 1 // BEASTIE // FEASTIE // B09084" */
|
||||
ROM_LOAD( "u_2__beastie__feastie__b09084.m5l2764k.u2", 0x2000, 0x2000, CRC(967405d8) SHA1(dd763be909e6966521b01ee878df9cef865c3b30) ) /* labeled as "U 2 // BEASTIE // FEASTIE // B09084" */
|
||||
ROM_LOAD( "u_3__beastie__feastie__b09084.m5l2764k.u3", 0x4000, 0x2000, CRC(3edb5381) SHA1(14c236045e6df7a475c32222652860689d4f68ce) ) /* labeled as "U 3 // BEASTIE // FEASTIE // B09084" */
|
||||
ROM_LOAD( "u_4__beastie__feastie__b09084.m5l2764k.u4", 0x6000, 0x2000, CRC(c8cd9640) SHA1(72da881b903ead873cc3f4df27646d1ffdd63c1c) ) /* labeled as "U 4 // BEASTIE // FEASTIE // B09084" */
|
||||
|
||||
ROM_REGION( 0x1000, REGION_USER1, 0 ) /* default NVRAM */
|
||||
ROM_LOAD( "beastf.nv", 0, 0x1000, CRC(98017b09) SHA1(0e2b2071bb47fc179d5bc36ef9431a9d2727d36a) )
|
||||
ROM_END
|
||||
|
||||
|
||||
static DRIVER_INIT( tristar9000 )
|
||||
{
|
||||
unsigned char *ROM = memory_region(REGION_CPU1);
|
||||
data8_t *rom = memory_region(REGION_CPU1);
|
||||
int A;
|
||||
int oldbyte,newbyte;
|
||||
|
||||
/* Key 0 */
|
||||
for (A = 0; A < 0x8000; A++)
|
||||
rom[A] = BITSWAP8(rom[A] ^ 0xbd, 2,6,4,0,5,7,1,3);
|
||||
|
||||
/* Key 1 */
|
||||
for (A = 0;A < 0x7000;A++)
|
||||
{
|
||||
oldbyte = ROM[A];
|
||||
|
||||
newbyte = 0;
|
||||
newbyte += ((oldbyte & 0x01 ) ^ 0x01) * 0x10;
|
||||
newbyte += ((oldbyte & 0x02 ) ^ 0x00) * 0x01;
|
||||
newbyte += ((oldbyte & 0x04 ) ^ 0x04) * 0x20;
|
||||
newbyte += ((oldbyte & 0x08 ) ^ 0x08) / 0x08;
|
||||
newbyte += ((oldbyte & 0x10 ) ^ 0x10) * 0x02;
|
||||
newbyte += ((oldbyte & 0x20 ) ^ 0x20) / 0x04;
|
||||
newbyte += ((oldbyte & 0x40 ) ^ 0x00) * 0x01;
|
||||
newbyte += ((oldbyte & 0x80 ) ^ 0x80) / 0x20;
|
||||
|
||||
ROM[A + 0x10000] = newbyte;
|
||||
}
|
||||
for (A = 0; A < 0x8000; A++)
|
||||
rom[A + 0x10000] = BITSWAP8(rom[A], 7,5,4,6,3,2,1,0);
|
||||
|
||||
/* Key 2 */
|
||||
for (A = 0;A < 0x7000;A++)
|
||||
{
|
||||
oldbyte = ROM[A+0x10000];
|
||||
|
||||
newbyte = 0;
|
||||
newbyte += ((oldbyte & 0x01 ) ^ 0x00) * 0x01;
|
||||
newbyte += ((oldbyte & 0x02 ) ^ 0x00) * 0x01;
|
||||
newbyte += ((oldbyte & 0x04 ) ^ 0x00) * 0x01;
|
||||
newbyte += ((oldbyte & 0x08 ) ^ 0x00) * 0x01;
|
||||
newbyte += ((oldbyte & 0x10 ) ^ 0x00) * 0x02;
|
||||
newbyte += ((oldbyte & 0x20 ) ^ 0x00) * 0x02;
|
||||
newbyte += ((oldbyte & 0x40 ) ^ 0x00) / 0x04;
|
||||
newbyte += ((oldbyte & 0x80 ) ^ 0x00) * 0x01;
|
||||
|
||||
ROM[A + 0x20000 ] = newbyte;
|
||||
}
|
||||
for (A = 0; A < 0x8000; A++)
|
||||
rom[A + 0x20000] = BITSWAP8(rom[A] ^ 1, 7,6,5,4,3,0,2,1);
|
||||
|
||||
/* Key 3 */
|
||||
for (A = 0;A < 0x7000;A++)
|
||||
{
|
||||
oldbyte = ROM[A+0x10000];
|
||||
for (A = 0; A < 0x8000; A++)
|
||||
rom[A + 0x30000] = BITSWAP8(rom[A] ^ 1, 7,5,4,6,3,0,2,1);
|
||||
|
||||
newbyte = 0;
|
||||
newbyte += ((oldbyte & 0x01 ) ^ 0x01) * 0x04;
|
||||
newbyte += ((oldbyte & 0x02 ) ^ 0x00) / 0x02;
|
||||
newbyte += ((oldbyte & 0x04 ) ^ 0x00) / 0x02;
|
||||
newbyte += ((oldbyte & 0x08 ) ^ 0x00) * 0x01;
|
||||
newbyte += ((oldbyte & 0x10 ) ^ 0x00) * 0x01;
|
||||
newbyte += ((oldbyte & 0x20 ) ^ 0x00) * 0x01;
|
||||
newbyte += ((oldbyte & 0x40 ) ^ 0x00) * 0x01;
|
||||
newbyte += ((oldbyte & 0x80 ) ^ 0x00) * 0x01;
|
||||
/* U04 (key 0) for the 0x6000-0x6fff bank. 0x7000-0x7fff is RAM, which
|
||||
uses the region at that address, so its 2nd half can't stay there.
|
||||
Only 0x0000-0x5fff of the key 1-3 copies is used. */
|
||||
memcpy(&rom[0x16000], &rom[0x6000], 0x2000);
|
||||
|
||||
ROM[A + 0x30000 ] = newbyte;
|
||||
}
|
||||
|
||||
/* Key 4 */
|
||||
for (A = 0;A < 0x7000;A++)
|
||||
{
|
||||
|
||||
/* there is not enough data to determine the last key.
|
||||
the code in question is this:
|
||||
|
||||
55 = 32 ld (793e),a
|
||||
2f59 5c 3e
|
||||
2f5a 79 78
|
||||
|
||||
2f5b 55 32 ld (79xx),a
|
||||
2f5c f7 53 or D2 or F3
|
||||
2f5d 79 78
|
||||
|
||||
2f5e 55 32 ld (79xx),a
|
||||
2f5f cd 1B 56 77 9A BB F6
|
||||
79 78
|
||||
It writes data to be read later.
|
||||
I don't know the lsb of the writes. I do know:
|
||||
if 2f5c = 53 then 2f5f = 9A or BB or F6
|
||||
d2 1B 77 BB
|
||||
f3 1B 56 9A
|
||||
|
||||
Someone will have to check the code to see what it's looking for.
|
||||
As usual I've had to make some assumptions so I can't guarantee 100% accuracy
|
||||
Dave
|
||||
*/
|
||||
|
||||
oldbyte = ROM[A+0x10000];
|
||||
|
||||
newbyte = 0;
|
||||
#if 1
|
||||
/*53:9a*/
|
||||
newbyte += ((oldbyte & 0x01 ) ^ 0x01) * 0x04;
|
||||
newbyte += ((oldbyte & 0x02 ) ^ 0x00) / 0x02;
|
||||
newbyte += ((oldbyte & 0x04 ) ^ 0x00) / 0x02;
|
||||
newbyte += ((oldbyte & 0x08 ) ^ 0x00) * 0x01;
|
||||
newbyte += ((oldbyte & 0x10 ) ^ 0x10) * 0x08;
|
||||
newbyte += ((oldbyte & 0x20 ) ^ 0x00) * 0x02;
|
||||
newbyte += ((oldbyte & 0x40 ) ^ 0x00) / 0x04;
|
||||
newbyte += ((oldbyte & 0x80 ) ^ 0x80) / 0x04;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*53:bb*/
|
||||
newbyte += ((oldbyte & 0x01 ) ^ 0x01) * 0x04;
|
||||
newbyte += ((oldbyte & 0x02 ) ^ 0x02) * 0x10;
|
||||
newbyte += ((oldbyte & 0x04 ) ^ 0x00) / 0x02;
|
||||
newbyte += ((oldbyte & 0x08 ) ^ 0x00) * 0x01;
|
||||
newbyte += ((oldbyte & 0x10 ) ^ 0x10) * 0x08;
|
||||
newbyte += ((oldbyte & 0x20 ) ^ 0x00) * 0x02;
|
||||
newbyte += ((oldbyte & 0x40 ) ^ 0x00) / 0x04;
|
||||
newbyte += ((oldbyte & 0x80 ) ^ 0x00) / 0x80;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*f3:9a*/
|
||||
newbyte += ((oldbyte & 0x01 ) ^ 0x01) * 0x04;
|
||||
newbyte += ((oldbyte & 0x02 ) ^ 0x00) / 0x02;
|
||||
newbyte += ((oldbyte & 0x04 ) ^ 0x00) / 0x02;
|
||||
newbyte += ((oldbyte & 0x08 ) ^ 0x00) * 0x01;
|
||||
newbyte += ((oldbyte & 0x10 ) ^ 0x00) * 0x02;
|
||||
newbyte += ((oldbyte & 0x20 ) ^ 0x00) * 0x02;
|
||||
newbyte += ((oldbyte & 0x40 ) ^ 0x00) / 0x04;
|
||||
newbyte += ((oldbyte & 0x80 ) ^ 0x00) * 0x01;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*f3:1b*/
|
||||
newbyte += ((oldbyte & 0x01 ) ^ 0x01) * 0x04;
|
||||
newbyte += ((oldbyte & 0x02 ) ^ 0x00) * 0x40;
|
||||
newbyte += ((oldbyte & 0x04 ) ^ 0x00) / 0x02;
|
||||
newbyte += ((oldbyte & 0x08 ) ^ 0x00) * 0x01;
|
||||
newbyte += ((oldbyte & 0x10 ) ^ 0x00) * 0x02;
|
||||
newbyte += ((oldbyte & 0x20 ) ^ 0x00) * 0x02;
|
||||
newbyte += ((oldbyte & 0x40 ) ^ 0x00) / 0x04;
|
||||
newbyte += ((oldbyte & 0x80 ) ^ 0x00) / 0x80;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*d2:1b*/
|
||||
newbyte += ((oldbyte & 0x01 ) ^ 0x01) * 0x04;
|
||||
newbyte += ((oldbyte & 0x02 ) ^ 0x00) * 0x40;
|
||||
newbyte += ((oldbyte & 0x04 ) ^ 0x00) / 0x02;
|
||||
newbyte += ((oldbyte & 0x08 ) ^ 0x00) * 0x01;
|
||||
newbyte += ((oldbyte & 0x10 ) ^ 0x10) / 0x10;
|
||||
newbyte += ((oldbyte & 0x20 ) ^ 0x00) * 0x02;
|
||||
newbyte += ((oldbyte & 0x40 ) ^ 0x00) / 0x04;
|
||||
newbyte += ((oldbyte & 0x80 ) ^ 0x80) / 0x04;
|
||||
#endif
|
||||
|
||||
ROM[A + 0x40000 ] = newbyte;
|
||||
}
|
||||
state_save_register_int("tristar9000", 0, "counter", &tristar9000_counter);
|
||||
state_save_register_int("tristar9000", 0, "rombank", &tristar9000_rombank);
|
||||
state_save_register_int("tristar9000", 0, "input_mux", &tristar9000_input_mux);
|
||||
state_save_register_int("tristar9000", 0, "ay_porta_mux", &tristar9000_ay_porta_mux);
|
||||
state_save_register_int("tristar9000", 0, "flip", &tristar9000_flip);
|
||||
state_save_register_int("tristar9000", 0, "portc", &tristar9000_portc);
|
||||
state_save_register_func_postload(tristar9000_postload);
|
||||
}
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Game drivers
|
||||
@@ -803,6 +883,9 @@ GAME ( 1983, theglob2, suprglob, epos, suprglob, 0, ROT270, "Epos Corporation
|
||||
GAME ( 1983, theglob3, suprglob, epos, suprglob, 0, ROT270, "Epos Corporation", "The Glob (set 3)" )
|
||||
GAME ( 1984, igmo, 0, epos, igmo, 0, ROT270, "Epos Corporation", "IGMO" )
|
||||
|
||||
/* Epos Tristar 9000 */
|
||||
/* Epos Tristar 9000 */
|
||||
|
||||
GAMEX( 19??, dealer, 0, dealer, dealer, dealer, ROT270, "Epos Corporation", "The Dealer", GAME_NOT_WORKING)
|
||||
GAME ( 1984, dealer, 0, tristar9000, dealer, tristar9000, ROT270, "Epos Corporation", "The Dealer" )
|
||||
GAME ( 1984, revngr84, 0, tristar9000, beastf, tristar9000, ROT270, "Epos Corporation", "Revenger '84 (newer)" )
|
||||
GAMEX( 1984, revenger, revngr84, tristar9000, beastf, tristar9000, ROT270, "Epos Corporation", "Revenger '84 (older)", GAME_NOT_WORKING ) /* bad dump */
|
||||
GAME ( 1984, beastf, suprglob, tristar9000, beastf, tristar9000, ROT270, "Epos Corporation", "Beastie Feastie" )
|
||||
+1341
-1341
File diff suppressed because it is too large.
Load diff
+424
-35
@@ -20,6 +20,7 @@
|
||||
#include "machine/midwayic.h"
|
||||
#include "sndhrdw/dcs.h"
|
||||
#include "kinst.h"
|
||||
#include "state.h"
|
||||
|
||||
|
||||
/* constants */
|
||||
@@ -33,6 +34,10 @@ static data32_t *kinst_speedup;
|
||||
|
||||
static const UINT8 *control_map;
|
||||
|
||||
/* the end of the IRQ 0 pulse, with its time left for the save states */
|
||||
static void *irq0_timer;
|
||||
static double irq0_timer_left;
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
@@ -41,6 +46,36 @@ static const UINT8 *control_map;
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static void irq0_stop(int param);
|
||||
|
||||
static void kinst_presave(void)
|
||||
{
|
||||
irq0_timer_left = timer_timeleft(irq0_timer);
|
||||
}
|
||||
|
||||
|
||||
/* after a load: the displayed buffer, from the VRAM control register, and
|
||||
the end of the IRQ 0 pulse where it was. (A wait of the speedup is not
|
||||
saved: after a load the CPU runs the delay loop again, and waits again.) */
|
||||
static void kinst_postload(void)
|
||||
{
|
||||
kinst_set_video_base(&rambase1[((kinst_control[0] & 4) ? 0x58000 : 0x30000) / 4]);
|
||||
timer_adjust(irq0_timer, (irq0_timer_left < TIME_NEVER / 2) ? irq0_timer_left : TIME_NEVER, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
static void kinst_register_state(void)
|
||||
{
|
||||
irq0_timer = timer_alloc(irq0_stop);
|
||||
|
||||
/* the control registers ($80-$ff) are not RAM of the memory map */
|
||||
state_save_register_UINT32("kinst", 0, "control", kinst_control, 0x80 / 4);
|
||||
state_save_register_double("kinst", 0, "irq0_timer_left", &irq0_timer_left, 1);
|
||||
state_save_register_func_presave(kinst_presave);
|
||||
state_save_register_func_postload(kinst_postload);
|
||||
}
|
||||
|
||||
|
||||
static MACHINE_INIT( kinst )
|
||||
{
|
||||
cpu_setbank(1, rambase1 + 0x1000/4);
|
||||
@@ -49,6 +84,9 @@ static MACHINE_INIT( kinst )
|
||||
cpu_setbank(4, rambase2 + 0x90000/4);
|
||||
|
||||
ide_controller_reset(0);
|
||||
|
||||
/* set a safe base location for video */
|
||||
kinst_set_video_base(&rambase1[0x30000/4]);
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +106,7 @@ static void irq0_stop(int param)
|
||||
static INTERRUPT_GEN( irq0_start )
|
||||
{
|
||||
cpu_set_irq_line(0, 0, ASSERT_LINE);
|
||||
timer_set(TIME_IN_USEC(50), 0, irq0_stop);
|
||||
timer_adjust(irq0_timer, TIME_IN_USEC(50), 0, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -167,8 +205,8 @@ static WRITE32_HANDLER( kinst_control_w )
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0: /* $80 - VRAM buffer control?? */
|
||||
kinst_buffer_vram(&rambase1[0x30000/4]);
|
||||
case 0: /* $80 - VRAM control: bit 2 selects the displayed buffer (current MAME) */
|
||||
kinst_set_video_base(&rambase1[((kinst_control[offset] & 4) ? 0x58000 : 0x30000) / 4]);
|
||||
break;
|
||||
|
||||
case 1: /* $88 - sound reset */
|
||||
@@ -199,10 +237,49 @@ static void end_spin(int param)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Speedups. Every version has the same two waiting loops, at different addresses.
|
||||
|
||||
1) A delay on the CP0 Count register:
|
||||
v1 = [delay]
|
||||
loop: k0 = Count; k1 = [start]; k0 -= k1; if (k0 < v1) goto loop
|
||||
When the loop reads [start] we skip the remaining wait.
|
||||
The PC is the instruction after the read.
|
||||
|
||||
2) The waits for an interrupt, polling the CP0 Cause register, for example VBLANK:
|
||||
loop: v0 = Cause; if (!(v0 & 0x400)) goto loop
|
||||
The MIPS3 core recognises these loops and skips their passes exactly
|
||||
(mips3_set_cause_poll_skip), counters included.
|
||||
|
||||
On top of that the MIPS3 core reads and writes main RAM directly (fast RAM).
|
||||
The addresses come from each version's code, as loaded from the hard disk.
|
||||
*/
|
||||
struct kinst_speedup_info
|
||||
{
|
||||
const char * name;
|
||||
offs_t pc;
|
||||
offs_t address;
|
||||
};
|
||||
|
||||
static const struct kinst_speedup_info kinst_speedups[] =
|
||||
{
|
||||
{ "kinst", 0x88029f98, 0x8808f5d4 }, /* v1.5d */
|
||||
{ "kinst14", 0x88029890, 0x8808f5bc }, /* v1.4 */
|
||||
{ "kinst13", 0x88029880, 0x8808f5bc }, /* v1.3 */
|
||||
{ "kinstp", 0x88029010, 0x8808f5bc }, /* proto v4.7 */
|
||||
{ "kinst2", 0x8802c2d0, 0x887ff544 }, /* v1.4 */
|
||||
{ "kinst213", 0x8802c2d0, 0x887ff544 }, /* v1.3 */
|
||||
{ "kinst211", 0x8802bef4, 0x887ff544 }, /* v1.1 */
|
||||
{ "kinst210", 0x8802bb80, 0x887ff544 }, /* v1.0 */
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static offs_t kinst_speedup_pc;
|
||||
|
||||
|
||||
static READ32_HANDLER( kinst_speedup_r )
|
||||
{
|
||||
if (activecpu_get_pc() == 0x88029890 || /* KI */
|
||||
activecpu_get_pc() == 0x8802c2d0 /* KI2 */)
|
||||
if (activecpu_get_pc() == kinst_speedup_pc)
|
||||
{
|
||||
UINT32 r3 = activecpu_get_reg(MIPS3_R3);
|
||||
UINT32 r26 = activecpu_get_reg(MIPS3_R26) - *kinst_speedup;
|
||||
@@ -216,6 +293,59 @@ static READ32_HANDLER( kinst_speedup_r )
|
||||
}
|
||||
|
||||
|
||||
#define KINST_ROM_WAIT 128 /* cycles per data read from the boot EPROM */
|
||||
|
||||
static void kinst_install_speedup(void)
|
||||
{
|
||||
const struct kinst_speedup_info *info;
|
||||
|
||||
for (info = kinst_speedups; info->name; info++)
|
||||
if (!strcmp(Machine->gamedrv->name, info->name))
|
||||
break;
|
||||
if (!info->name)
|
||||
return;
|
||||
|
||||
/* the Count delay loop */
|
||||
kinst_speedup_pc = info->pc;
|
||||
kinst_speedup = install_mem_read32_handler(0, info->address, info->address + 3, kinst_speedup_r);
|
||||
|
||||
/* the loops waiting for an interrupt in Cause (VBLANK, IRQ 0, and the others) are
|
||||
skipped exactly by the MIPS3 core; the input port at $a0 can be read inside them */
|
||||
mips3_set_cause_poll_skip(1);
|
||||
mips3_add_poll_read(0xb00000a0, 0xb00000a3);
|
||||
|
||||
/* main RAM through a direct pointer, except the word watched by the delay speedup; */
|
||||
/* (the regions are tried in order, so the busiest come first) */
|
||||
mips3_add_fastram(0x80000000, 0x8007ffff, 0, rambase1);
|
||||
mips3_add_fastram(0x88000000, info->address - 1, 0, rambase2);
|
||||
mips3_add_fastram(info->address + 4, 0x887fffff, 0, (UINT8 *)rambase2 + (info->address + 4 - 0x88000000));
|
||||
mips3_add_fastram(0xa0000000, 0xa007ffff, 0, rambase1);
|
||||
/* the low RAM windows (banks 4 and 1): the drawing code reads its tables there */
|
||||
mips3_add_fastram(0x00000000, 0x00000fff, 0, rambase2 + 0x90000/4);
|
||||
mips3_add_fastram(0x00001000, 0x0007ffff, 0, rambase1 + 0x1000/4);
|
||||
/* the boot ROM, read only: the game calls its routines (and they can be recompiled) */
|
||||
/* data reads from the boot EPROM have wait states (128 cycles, as FBNeo): */
|
||||
/* the boot (blue screen) then takes about 7 seconds instead of 1, and the */
|
||||
/* DCS has time to start the attract mode music, which was missing */
|
||||
mips3_add_fastram_wait(0x9fc00000, 0x9fc7ffff, 1, rombase, KINST_ROM_WAIT);
|
||||
mips3_add_fastram_wait(0xbfc00000, 0xbfc7ffff, 1, rombase, KINST_ROM_WAIT);
|
||||
|
||||
/* DCS sound: the boot code's NOP delay loops skipped exactly, and the */
|
||||
/* banked sound ROM read through a pointer */
|
||||
adsp2100_set_nop_loop_skip(1);
|
||||
dcs_fast_rombank_init();
|
||||
|
||||
/* recompiler (core option; only on the hosts that support it) */
|
||||
if (options.mips_dynarec)
|
||||
mips3_set_jit(1);
|
||||
if (options.adsp_dynarec)
|
||||
{
|
||||
adsp2100_set_jit(1);
|
||||
/* the banked sound ROM (dcs_rombank_data_r): reads with no side effects */
|
||||
adsp2100_jit_pure_read(0x2000, 0x2fff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
@@ -306,7 +436,7 @@ INPUT_PORTS_START( kinst )
|
||||
PORT_START
|
||||
PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNUSED ) /* verify */
|
||||
|
||||
PORT_START
|
||||
PORT_START /* DSW (dip switches as in current MAME) */
|
||||
PORT_DIPNAME( 0x0003, 0x0003, "Blood Level" )
|
||||
PORT_DIPSETTING( 0x0003, "High")
|
||||
PORT_DIPSETTING( 0x0002, "Medium")
|
||||
@@ -321,32 +451,142 @@ INPUT_PORTS_START( kinst )
|
||||
PORT_DIPNAME( 0x0010, 0x0010, "Display Warning" )
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( Off ))
|
||||
PORT_DIPSETTING( 0x0010, DEF_STR( On ))
|
||||
PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ))
|
||||
PORT_DIPSETTING( 0x0020, DEF_STR( Off ))
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( On ))
|
||||
PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ))
|
||||
PORT_DIPNAME( 0x0020, 0x0020, "Blood" )
|
||||
PORT_DIPSETTING( 0x0020, "Red" )
|
||||
PORT_DIPSETTING( 0x0000, "White" )
|
||||
PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unused ))
|
||||
PORT_DIPSETTING( 0x0040, DEF_STR( Off ))
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( On ))
|
||||
PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ))
|
||||
PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unused ))
|
||||
PORT_DIPSETTING( 0x0080, DEF_STR( Off ))
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( On ))
|
||||
PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ))
|
||||
PORT_DIPSETTING( 0x0100, DEF_STR( Off ))
|
||||
PORT_DIPNAME( 0x0100, 0x0100, "Coinage Source" )
|
||||
PORT_DIPSETTING( 0x0100, "Dipswitch" )
|
||||
PORT_DIPSETTING( 0x0000, "Disk" )
|
||||
PORT_DIPNAME( 0x3e00, 0x3e00, DEF_STR( Coinage ))
|
||||
PORT_DIPSETTING( 0x3e00, "USA-1" )
|
||||
PORT_DIPSETTING( 0x3c00, "USA-2" )
|
||||
PORT_DIPSETTING( 0x3a00, "USA-3" )
|
||||
PORT_DIPSETTING( 0x3800, "USA-4" )
|
||||
PORT_DIPSETTING( 0x3400, "USA-9" )
|
||||
PORT_DIPSETTING( 0x3200, "USA-10" )
|
||||
PORT_DIPSETTING( 0x3600, "USA-ECA" )
|
||||
PORT_DIPSETTING( 0x3000, "USA-Free Play" )
|
||||
PORT_DIPSETTING( 0x2e00, "German-1" )
|
||||
PORT_DIPSETTING( 0x2c00, "German-2" )
|
||||
PORT_DIPSETTING( 0x2a00, "German-3" )
|
||||
PORT_DIPSETTING( 0x2800, "German-4" )
|
||||
PORT_DIPSETTING( 0x2600, "German-ECA" )
|
||||
PORT_DIPSETTING( 0x2000, "German-Free Play" )
|
||||
PORT_DIPSETTING( 0x1e00, "French-1" )
|
||||
PORT_DIPSETTING( 0x1c00, "French-2" )
|
||||
PORT_DIPSETTING( 0x1a00, "French-3" )
|
||||
PORT_DIPSETTING( 0x1800, "French-4" )
|
||||
PORT_DIPSETTING( 0x1600, "French-ECA" )
|
||||
PORT_DIPSETTING( 0x1000, "French-Free Play" )
|
||||
PORT_DIPNAME( 0x4000, 0x4000, "Coin Counters" )
|
||||
PORT_DIPSETTING( 0x4000, "1" )
|
||||
PORT_DIPSETTING( 0x0000, "2" )
|
||||
PORT_DIPNAME( 0x8000, 0x8000, "Test Switch" )
|
||||
PORT_DIPSETTING( 0x8000, DEF_STR( Off ))
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( On ))
|
||||
PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ))
|
||||
PORT_DIPSETTING( 0x0200, DEF_STR( Off ))
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
INPUT_PORTS_START( kinst2 )
|
||||
PORT_START
|
||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON4 | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON5 | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON6 | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_PLAYER1 )
|
||||
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_START1 )
|
||||
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_COIN1 )
|
||||
PORT_BITX(0x1000, IP_ACTIVE_LOW, IPT_SERVICE, DEF_STR( Service_Mode ), KEYCODE_F2, IP_JOY_NONE )
|
||||
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_COIN3 )
|
||||
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_COIN4 )
|
||||
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_SPECIAL ) /* door */
|
||||
|
||||
PORT_START
|
||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON3 | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON4 | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON5 | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON6 | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_PLAYER2 )
|
||||
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_START2 )
|
||||
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_COIN2 )
|
||||
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_TILT )
|
||||
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_SERVICE1 )
|
||||
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_SPECIAL ) /* bill */
|
||||
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* coin door */
|
||||
|
||||
PORT_START
|
||||
PORT_BIT( 0x0003, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
PORT_BITX(0x0004, IP_ACTIVE_LOW, 0, "Volume Up", KEYCODE_EQUALS, IP_JOY_NONE )
|
||||
PORT_BITX(0x0008, IP_ACTIVE_LOW, 0, "Volume Down", KEYCODE_MINUS, IP_JOY_NONE )
|
||||
PORT_BIT( 0xfff0, IP_ACTIVE_LOW, IPT_UNKNOWN )
|
||||
|
||||
PORT_START
|
||||
PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNUSED ) /* verify */
|
||||
|
||||
PORT_START /* DSW (dip switches as in current MAME) */
|
||||
PORT_DIPNAME( 0x0003, 0x0003, "Blood Level" )
|
||||
PORT_DIPSETTING( 0x0003, "High")
|
||||
PORT_DIPSETTING( 0x0002, "Medium")
|
||||
PORT_DIPSETTING( 0x0001, "Low")
|
||||
PORT_DIPSETTING( 0x0000, "None")
|
||||
PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Demo_Sounds ))
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( Off ))
|
||||
PORT_DIPSETTING( 0x0004, DEF_STR( On ))
|
||||
PORT_DIPNAME( 0x0008, 0x0008, "Finishing Moves" )
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( Off ))
|
||||
PORT_DIPSETTING( 0x0008, DEF_STR( On ))
|
||||
PORT_DIPNAME( 0x0010, 0x0010, "Display Warning" )
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( Off ))
|
||||
PORT_DIPSETTING( 0x0010, DEF_STR( On ))
|
||||
PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unused ))
|
||||
PORT_DIPSETTING( 0x0020, DEF_STR( Off ))
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( On ))
|
||||
PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ))
|
||||
PORT_DIPSETTING( 0x0400, DEF_STR( Off ))
|
||||
PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unused ))
|
||||
PORT_DIPSETTING( 0x0040, DEF_STR( Off ))
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( On ))
|
||||
PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ))
|
||||
PORT_DIPSETTING( 0x0800, DEF_STR( Off ))
|
||||
PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unused ))
|
||||
PORT_DIPSETTING( 0x0080, DEF_STR( Off ))
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( On ))
|
||||
PORT_DIPNAME( 0x3000, 0x3000, "Country" )
|
||||
PORT_DIPSETTING( 0x3000, "USA" )
|
||||
PORT_DIPSETTING( 0x2000, "Germany" )
|
||||
PORT_DIPSETTING( 0x1000, "France" )
|
||||
/* PORT_DIPSETTING( 0x0000, "USA" )*/
|
||||
PORT_DIPNAME( 0x0100, 0x0100, "Coinage Source" )
|
||||
PORT_DIPSETTING( 0x0100, "Dipswitch" )
|
||||
PORT_DIPSETTING( 0x0000, "Disk" )
|
||||
PORT_DIPNAME( 0x3e00, 0x3e00, DEF_STR( Coinage ))
|
||||
PORT_DIPSETTING( 0x3e00, "USA-1" )
|
||||
PORT_DIPSETTING( 0x3c00, "USA-2" )
|
||||
PORT_DIPSETTING( 0x3a00, "USA-3" )
|
||||
PORT_DIPSETTING( 0x3800, "USA-4" )
|
||||
PORT_DIPSETTING( 0x3400, "USA-9" )
|
||||
PORT_DIPSETTING( 0x3200, "USA-10" )
|
||||
PORT_DIPSETTING( 0x3600, "USA-ECA" )
|
||||
PORT_DIPSETTING( 0x3000, "USA-Free Play" )
|
||||
PORT_DIPSETTING( 0x2e00, "German-1" )
|
||||
PORT_DIPSETTING( 0x2c00, "German-2" )
|
||||
PORT_DIPSETTING( 0x2a00, "German-3" )
|
||||
PORT_DIPSETTING( 0x2800, "German-4" )
|
||||
PORT_DIPSETTING( 0x2600, "German-ECA" )
|
||||
PORT_DIPSETTING( 0x2000, "German-Free Play" )
|
||||
PORT_DIPSETTING( 0x1e00, "French-1" )
|
||||
PORT_DIPSETTING( 0x1c00, "French-2" )
|
||||
PORT_DIPSETTING( 0x1a00, "French-3" )
|
||||
PORT_DIPSETTING( 0x1800, "French-4" )
|
||||
PORT_DIPSETTING( 0x1600, "French-ECA" )
|
||||
PORT_DIPSETTING( 0x1000, "French-Free Play" )
|
||||
PORT_DIPNAME( 0x4000, 0x4000, "Coin Counters" )
|
||||
PORT_DIPSETTING( 0x4000, "1" )
|
||||
PORT_DIPSETTING( 0x0000, "2" )
|
||||
@@ -378,13 +618,13 @@ MACHINE_DRIVER_START( kinst )
|
||||
MDRV_CPU_MEMORY(main_readmem,main_writemem)
|
||||
MDRV_CPU_VBLANK_INT(irq0_start,1)
|
||||
|
||||
MDRV_FRAMES_PER_SECOND(60)
|
||||
MDRV_FRAMES_PER_SECOND(MASTER_CLOCK / 8.0 / (406 * 261)) /* 58.98 Hz, as in current MAME */
|
||||
MDRV_VBLANK_DURATION(DEFAULT_REAL_60HZ_VBLANK_DURATION)
|
||||
|
||||
MDRV_MACHINE_INIT(kinst)
|
||||
|
||||
/* video hardware */
|
||||
MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER | VIDEO_UPDATE_BEFORE_VBLANK)
|
||||
MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER | VIDEO_RGB_DIRECT | VIDEO_UPDATE_BEFORE_VBLANK)
|
||||
MDRV_SCREEN_SIZE(320, 240)
|
||||
MDRV_VISIBLE_AREA(0, 319, 0, 239)
|
||||
MDRV_PALETTE_LENGTH(32768)
|
||||
@@ -406,7 +646,10 @@ MACHINE_DRIVER_END
|
||||
*************************************/
|
||||
|
||||
ROM_START( kinst )
|
||||
ROM_REGION( 0x80000, REGION_CPU1, 0 ) /* dummy region for R3000 */
|
||||
ROM_REGION( 0x80000, REGION_CPU1, 0 ) /* dummy region for R4600 */
|
||||
|
||||
ROM_REGION32_LE( 0x80000, REGION_USER1, 0 ) /* 512k for R4600 code */
|
||||
ROM_LOAD( "ki-l15d.u98", 0x00000, 0x80000, CRC(7b65ca3d) SHA1(607394d4ba1713f38c2cb5159303cace9cde991e) )
|
||||
|
||||
ROM_REGION( ADSP2100_SIZE + 0x800000, REGION_CPU2, 0 ) /* ADSP-2105 data */
|
||||
ROM_LOAD( "u10-l1", ADSP2100_SIZE + 0x000000, 0x80000, CRC(b6cc155f) SHA1(810d455df8f385d76143e9d7d048f2b555ff8bf0) )
|
||||
@@ -418,18 +661,84 @@ ROM_START( kinst )
|
||||
ROM_LOAD( "u35-l1", ADSP2100_SIZE + 0x600000, 0x80000, CRC(0aaef4fc) SHA1(48c4c954ac9db648f28ad64f9845e19ec432eec3) )
|
||||
ROM_LOAD( "u36-l1", ADSP2100_SIZE + 0x700000, 0x80000, CRC(0577bb60) SHA1(cc78070cc41701e9a91fde5cfbdc7e1e83354854) )
|
||||
|
||||
ROM_REGION( 0x600000, REGION_SOUND1, 0 )
|
||||
|
||||
DISK_REGION( REGION_DISKS )
|
||||
DISK_IMAGE( "kinst", 0, SHA1(81d833236e994528d1482979261401b198d1ca53) ) /* current MAME CHD (v5); also accepts the older v3 one */
|
||||
ROM_END
|
||||
|
||||
|
||||
ROM_START( kinst14 )
|
||||
ROM_REGION( 0x80000, REGION_CPU1, 0 ) /* dummy region for R4600 */
|
||||
|
||||
ROM_REGION32_LE( 0x80000, REGION_USER1, 0 ) /* 512k for R4600 code */
|
||||
ROM_LOAD( "u98-l14", 0x00000, 0x80000, CRC(afedb75f) SHA1(07254f20707377f7195e64675eb6458e663c1a9a) )
|
||||
ROM_LOAD( "ki-l14.u98", 0x00000, 0x80000, CRC(afedb75f) SHA1(07254f20707377f7195e64675eb6458e663c1a9a) )
|
||||
|
||||
ROM_REGION( ADSP2100_SIZE + 0x800000, REGION_CPU2, 0 ) /* ADSP-2105 data */
|
||||
ROM_LOAD( "u10-l1", ADSP2100_SIZE + 0x000000, 0x80000, CRC(b6cc155f) SHA1(810d455df8f385d76143e9d7d048f2b555ff8bf0) )
|
||||
ROM_LOAD( "u11-l1", ADSP2100_SIZE + 0x100000, 0x80000, CRC(0b5e05df) SHA1(0595909cb667c38ac7c8c7bd0646b28899e27777) )
|
||||
ROM_LOAD( "u12-l1", ADSP2100_SIZE + 0x200000, 0x80000, CRC(d05ce6ad) SHA1(7a8ee405c118fd176b66353fa7bfab888cc63cd2) )
|
||||
ROM_LOAD( "u13-l1", ADSP2100_SIZE + 0x300000, 0x80000, CRC(7d0954ea) SHA1(ea4d1f153eb284f1bcfc5295fbce316bba6083f4) )
|
||||
ROM_LOAD( "u33-l1", ADSP2100_SIZE + 0x400000, 0x80000, CRC(8bbe4f0c) SHA1(b22e365bc8d58a80eaac226be14b4bb8d9a04844) )
|
||||
ROM_LOAD( "u34-l1", ADSP2100_SIZE + 0x500000, 0x80000, CRC(b2e73603) SHA1(ee439f5162a2b3379d3f802328017bb3c68547d2) )
|
||||
ROM_LOAD( "u35-l1", ADSP2100_SIZE + 0x600000, 0x80000, CRC(0aaef4fc) SHA1(48c4c954ac9db648f28ad64f9845e19ec432eec3) )
|
||||
ROM_LOAD( "u36-l1", ADSP2100_SIZE + 0x700000, 0x80000, CRC(0577bb60) SHA1(cc78070cc41701e9a91fde5cfbdc7e1e83354854) )
|
||||
|
||||
ROM_REGION( 0x600000, REGION_SOUND1, 0 )
|
||||
|
||||
DISK_REGION( REGION_DISKS )
|
||||
DISK_IMAGE( "kinst.chd", 0, MD5(6d4c2f152c9a18ab3a9b05b8804306a8) SHA1(a37a2c5e52ea936a715210d237874dd573bb002f) )
|
||||
DISK_IMAGE( "kinst", 0, SHA1(81d833236e994528d1482979261401b198d1ca53) ) /* current MAME CHD (v5); also accepts the older v3 one */
|
||||
ROM_END
|
||||
|
||||
|
||||
ROM_START( kinst13 )
|
||||
ROM_REGION( 0x80000, REGION_CPU1, 0 ) /* dummy region for R4600 */
|
||||
|
||||
ROM_REGION32_LE( 0x80000, REGION_USER1, 0 ) /* 512k for R4600 code */
|
||||
ROM_LOAD( "ki-l13.u98", 0x00000, 0x80000, CRC(65f7ea31) SHA1(7f21620a512549db6821a0b4fa53681a767b7974) )
|
||||
|
||||
ROM_REGION( ADSP2100_SIZE + 0x800000, REGION_CPU2, 0 ) /* ADSP-2105 data */
|
||||
ROM_LOAD( "u10-l1", ADSP2100_SIZE + 0x000000, 0x80000, CRC(b6cc155f) SHA1(810d455df8f385d76143e9d7d048f2b555ff8bf0) )
|
||||
ROM_LOAD( "u11-l1", ADSP2100_SIZE + 0x100000, 0x80000, CRC(0b5e05df) SHA1(0595909cb667c38ac7c8c7bd0646b28899e27777) )
|
||||
ROM_LOAD( "u12-l1", ADSP2100_SIZE + 0x200000, 0x80000, CRC(d05ce6ad) SHA1(7a8ee405c118fd176b66353fa7bfab888cc63cd2) )
|
||||
ROM_LOAD( "u13-l1", ADSP2100_SIZE + 0x300000, 0x80000, CRC(7d0954ea) SHA1(ea4d1f153eb284f1bcfc5295fbce316bba6083f4) )
|
||||
ROM_LOAD( "u33-l1", ADSP2100_SIZE + 0x400000, 0x80000, CRC(8bbe4f0c) SHA1(b22e365bc8d58a80eaac226be14b4bb8d9a04844) )
|
||||
ROM_LOAD( "u34-l1", ADSP2100_SIZE + 0x500000, 0x80000, CRC(b2e73603) SHA1(ee439f5162a2b3379d3f802328017bb3c68547d2) )
|
||||
ROM_LOAD( "u35-l1", ADSP2100_SIZE + 0x600000, 0x80000, CRC(0aaef4fc) SHA1(48c4c954ac9db648f28ad64f9845e19ec432eec3) )
|
||||
ROM_LOAD( "u36-l1", ADSP2100_SIZE + 0x700000, 0x80000, CRC(0577bb60) SHA1(cc78070cc41701e9a91fde5cfbdc7e1e83354854) )
|
||||
|
||||
ROM_REGION( 0x600000, REGION_SOUND1, 0 )
|
||||
|
||||
DISK_REGION( REGION_DISKS )
|
||||
DISK_IMAGE( "kinst", 0, SHA1(81d833236e994528d1482979261401b198d1ca53) ) /* current MAME CHD (v5); also accepts the older v3 one */
|
||||
ROM_END
|
||||
|
||||
|
||||
ROM_START( kinstp )
|
||||
ROM_REGION( 0x80000, REGION_CPU1, 0 ) /* dummy region for R4600 */
|
||||
|
||||
ROM_REGION32_LE( 0x80000, REGION_USER1, 0 ) /* 512k for R4600 code */
|
||||
ROM_LOAD( "ki-p47.u98", 0x00000, 0x80000, CRC(05e67bcb) SHA1(501e69b3026394f69229a6e9866c1037502b86bb) )
|
||||
|
||||
ROM_REGION( ADSP2100_SIZE + 0x800000, REGION_CPU2, 0 ) /* ADSP-2105 data */
|
||||
ROM_LOAD( "u10-l1", ADSP2100_SIZE + 0x000000, 0x80000, CRC(b6cc155f) SHA1(810d455df8f385d76143e9d7d048f2b555ff8bf0) )
|
||||
ROM_LOAD( "u11-l1", ADSP2100_SIZE + 0x100000, 0x80000, CRC(0b5e05df) SHA1(0595909cb667c38ac7c8c7bd0646b28899e27777) )
|
||||
ROM_LOAD( "u12-l1", ADSP2100_SIZE + 0x200000, 0x80000, CRC(d05ce6ad) SHA1(7a8ee405c118fd176b66353fa7bfab888cc63cd2) )
|
||||
ROM_LOAD( "u13-l1", ADSP2100_SIZE + 0x300000, 0x80000, CRC(7d0954ea) SHA1(ea4d1f153eb284f1bcfc5295fbce316bba6083f4) )
|
||||
ROM_LOAD( "u33-l1", ADSP2100_SIZE + 0x400000, 0x80000, CRC(8bbe4f0c) SHA1(b22e365bc8d58a80eaac226be14b4bb8d9a04844) )
|
||||
ROM_LOAD( "u34-l1", ADSP2100_SIZE + 0x500000, 0x80000, CRC(b2e73603) SHA1(ee439f5162a2b3379d3f802328017bb3c68547d2) )
|
||||
ROM_LOAD( "u35-l1", ADSP2100_SIZE + 0x600000, 0x80000, CRC(0aaef4fc) SHA1(48c4c954ac9db648f28ad64f9845e19ec432eec3) )
|
||||
ROM_LOAD( "u36-l1", ADSP2100_SIZE + 0x700000, 0x80000, CRC(0577bb60) SHA1(cc78070cc41701e9a91fde5cfbdc7e1e83354854) )
|
||||
|
||||
ROM_REGION( 0x600000, REGION_SOUND1, 0 )
|
||||
|
||||
DISK_REGION( REGION_DISKS )
|
||||
DISK_IMAGE( "kinst", 0, SHA1(81d833236e994528d1482979261401b198d1ca53) ) /* current MAME CHD (v5); also accepts the older v3 one */
|
||||
ROM_END
|
||||
|
||||
|
||||
ROM_START( kinst2 )
|
||||
ROM_REGION( 0x80000, REGION_CPU1, 0 ) /* dummy region for R3000 */
|
||||
ROM_REGION( 0x80000, REGION_CPU1, 0 ) /* dummy region for R4600 */
|
||||
|
||||
ROM_REGION32_LE( 0x80000, REGION_USER1, 0 ) /* 512k for R4600 code */
|
||||
ROM_LOAD( "ki2-l14.u98", 0x00000, 0x80000, CRC(27d0285e) SHA1(aa7a2a9d72a47dd0ea2ee7b2776b79288060b179) )
|
||||
@@ -444,11 +753,81 @@ ROM_START( kinst2 )
|
||||
ROM_LOAD( "ki2_l1.u35", ADSP2100_SIZE + 0x600000, 0x80000, CRC(7245ce69) SHA1(24a3ff009c8a7f5a0bfcb198b8dcb5df365770d3) )
|
||||
ROM_LOAD( "ki2_l1.u36", ADSP2100_SIZE + 0x700000, 0x80000, CRC(8920acbb) SHA1(0fca72c40067034939b984b4bf32972a5a6c26af) )
|
||||
|
||||
ROM_REGION( 0x600000, REGION_SOUND1, 0 )
|
||||
|
||||
DISK_REGION( REGION_DISKS )
|
||||
DISK_IMAGE( "kinst2.chd", 0, MD5(2563b089b316f2c8636d78af661ac656) SHA1(ab0242233d2eaf9d907abe246a54e09a8a2561a5) )
|
||||
DISK_IMAGE( "kinst2", 0, SHA1(e7c9291b4648eae0012ea0cc230731ed4987d1d5) ) /* current MAME CHD (v5); also accepts the older v3 one */
|
||||
ROM_END
|
||||
|
||||
|
||||
ROM_START( kinst213 )
|
||||
ROM_REGION( 0x80000, REGION_CPU1, 0 ) /* dummy region for R4600 */
|
||||
|
||||
ROM_REGION32_LE( 0x80000, REGION_USER1, 0 ) /* 512k for R4600 code */
|
||||
ROM_LOAD( "ki2-l13.u98", 0x00000, 0x80000, CRC(25ebde3b) SHA1(771d150fb4de0a2ceb279954b9545458e93e2405) )
|
||||
|
||||
ROM_REGION( ADSP2100_SIZE + 0x800000, REGION_CPU2, 0 ) /* ADSP-2105 data */
|
||||
ROM_LOAD( "ki2_l1.u10", ADSP2100_SIZE + 0x000000, 0x80000, CRC(fdf6ed51) SHA1(acfc9460cd5df01403b7f00b2f68c2a8734ad6d3) )
|
||||
ROM_LOAD( "ki2_l1.u11", ADSP2100_SIZE + 0x100000, 0x80000, CRC(f9e70024) SHA1(fe7fc78f1c60b15f2bbdc4c455f55cdf30f48ed4) )
|
||||
ROM_LOAD( "ki2_l1.u12", ADSP2100_SIZE + 0x200000, 0x80000, CRC(2994c199) SHA1(9997a83432cb720f65b40a8af46f31a5d0d16d8e) )
|
||||
ROM_LOAD( "ki2_l1.u13", ADSP2100_SIZE + 0x300000, 0x80000, CRC(3fe6327b) SHA1(7ff164fc2f079d039921594be92208973d43aa03) )
|
||||
ROM_LOAD( "ki2_l1.u33", ADSP2100_SIZE + 0x400000, 0x80000, CRC(6f4dcdcf) SHA1(0ab6dbfb76e9fa2db072e287864ad1f9d514dd9b) )
|
||||
ROM_LOAD( "ki2_l1.u34", ADSP2100_SIZE + 0x500000, 0x80000, CRC(5db48206) SHA1(48456a7b6592c40bc9c664dcd2ee2cfd91942811) )
|
||||
ROM_LOAD( "ki2_l1.u35", ADSP2100_SIZE + 0x600000, 0x80000, CRC(7245ce69) SHA1(24a3ff009c8a7f5a0bfcb198b8dcb5df365770d3) )
|
||||
ROM_LOAD( "ki2_l1.u36", ADSP2100_SIZE + 0x700000, 0x80000, CRC(8920acbb) SHA1(0fca72c40067034939b984b4bf32972a5a6c26af) )
|
||||
|
||||
ROM_REGION( 0x600000, REGION_SOUND1, 0 )
|
||||
|
||||
DISK_REGION( REGION_DISKS )
|
||||
DISK_IMAGE( "kinst2", 0, SHA1(e7c9291b4648eae0012ea0cc230731ed4987d1d5) ) /* current MAME CHD (v5); also accepts the older v3 one */
|
||||
ROM_END
|
||||
|
||||
|
||||
ROM_START( kinst211 )
|
||||
ROM_REGION( 0x80000, REGION_CPU1, 0 ) /* dummy region for R4600 */
|
||||
|
||||
ROM_REGION32_LE( 0x80000, REGION_USER1, 0 ) /* 512k for R4600 code */
|
||||
ROM_LOAD( "ki2-l11.u98", 0x00000, 0x80000, CRC(0cb8de1e) SHA1(fe447f4b1d29b524f57c5ba1890652ef6afff88a) )
|
||||
|
||||
ROM_REGION( ADSP2100_SIZE + 0x800000, REGION_CPU2, 0 ) /* ADSP-2105 data */
|
||||
ROM_LOAD( "ki2_l1.u10", ADSP2100_SIZE + 0x000000, 0x80000, CRC(fdf6ed51) SHA1(acfc9460cd5df01403b7f00b2f68c2a8734ad6d3) )
|
||||
ROM_LOAD( "ki2_l1.u11", ADSP2100_SIZE + 0x100000, 0x80000, CRC(f9e70024) SHA1(fe7fc78f1c60b15f2bbdc4c455f55cdf30f48ed4) )
|
||||
ROM_LOAD( "ki2_l1.u12", ADSP2100_SIZE + 0x200000, 0x80000, CRC(2994c199) SHA1(9997a83432cb720f65b40a8af46f31a5d0d16d8e) )
|
||||
ROM_LOAD( "ki2_l1.u13", ADSP2100_SIZE + 0x300000, 0x80000, CRC(3fe6327b) SHA1(7ff164fc2f079d039921594be92208973d43aa03) )
|
||||
ROM_LOAD( "ki2_l1.u33", ADSP2100_SIZE + 0x400000, 0x80000, CRC(6f4dcdcf) SHA1(0ab6dbfb76e9fa2db072e287864ad1f9d514dd9b) )
|
||||
ROM_LOAD( "ki2_l1.u34", ADSP2100_SIZE + 0x500000, 0x80000, CRC(5db48206) SHA1(48456a7b6592c40bc9c664dcd2ee2cfd91942811) )
|
||||
ROM_LOAD( "ki2_l1.u35", ADSP2100_SIZE + 0x600000, 0x80000, CRC(7245ce69) SHA1(24a3ff009c8a7f5a0bfcb198b8dcb5df365770d3) )
|
||||
ROM_LOAD( "ki2_l1.u36", ADSP2100_SIZE + 0x700000, 0x80000, CRC(8920acbb) SHA1(0fca72c40067034939b984b4bf32972a5a6c26af) )
|
||||
|
||||
ROM_REGION( 0x600000, REGION_SOUND1, 0 )
|
||||
|
||||
DISK_REGION( REGION_DISKS )
|
||||
DISK_IMAGE( "kinst2", 0, SHA1(e7c9291b4648eae0012ea0cc230731ed4987d1d5) ) /* current MAME CHD (v5); also accepts the older v3 one */
|
||||
ROM_END
|
||||
|
||||
|
||||
ROM_START( kinst210 )
|
||||
ROM_REGION( 0x80000, REGION_CPU1, 0 ) /* dummy region for R4600 */
|
||||
|
||||
ROM_REGION32_LE( 0x80000, REGION_USER1, 0 ) /* 512k for R4600 code */
|
||||
ROM_LOAD( "ki2-l10.u98", 0x00000, 0x80000, CRC(b17b4b3d) SHA1(756629cd1b51ae50f2b9818765dd3d277c3019b3) )
|
||||
|
||||
ROM_REGION( ADSP2100_SIZE + 0x800000, REGION_CPU2, 0 ) /* ADSP-2105 data */
|
||||
ROM_LOAD( "ki2_l1.u10", ADSP2100_SIZE + 0x000000, 0x80000, CRC(fdf6ed51) SHA1(acfc9460cd5df01403b7f00b2f68c2a8734ad6d3) )
|
||||
ROM_LOAD( "ki2_l1.u11", ADSP2100_SIZE + 0x100000, 0x80000, CRC(f9e70024) SHA1(fe7fc78f1c60b15f2bbdc4c455f55cdf30f48ed4) )
|
||||
ROM_LOAD( "ki2_l1.u12", ADSP2100_SIZE + 0x200000, 0x80000, CRC(2994c199) SHA1(9997a83432cb720f65b40a8af46f31a5d0d16d8e) )
|
||||
ROM_LOAD( "ki2_l1.u13", ADSP2100_SIZE + 0x300000, 0x80000, CRC(3fe6327b) SHA1(7ff164fc2f079d039921594be92208973d43aa03) )
|
||||
ROM_LOAD( "ki2_l1.u33", ADSP2100_SIZE + 0x400000, 0x80000, CRC(6f4dcdcf) SHA1(0ab6dbfb76e9fa2db072e287864ad1f9d514dd9b) )
|
||||
ROM_LOAD( "ki2_l1.u34", ADSP2100_SIZE + 0x500000, 0x80000, CRC(5db48206) SHA1(48456a7b6592c40bc9c664dcd2ee2cfd91942811) )
|
||||
ROM_LOAD( "ki2_l1.u35", ADSP2100_SIZE + 0x600000, 0x80000, CRC(7245ce69) SHA1(24a3ff009c8a7f5a0bfcb198b8dcb5df365770d3) )
|
||||
ROM_LOAD( "ki2_l1.u36", ADSP2100_SIZE + 0x700000, 0x80000, CRC(8920acbb) SHA1(0fca72c40067034939b984b4bf32972a5a6c26af) )
|
||||
|
||||
ROM_REGION( 0x600000, REGION_SOUND1, 0 )
|
||||
|
||||
DISK_REGION( REGION_DISKS )
|
||||
DISK_IMAGE( "kinst2", 0, SHA1(e7c9291b4648eae0012ea0cc230731ed4987d1d5) ) /* current MAME CHD (v5); also accepts the older v3 one */
|
||||
ROM_END
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
@@ -484,10 +863,12 @@ static DRIVER_INIT( kinst )
|
||||
features[31*2+1] = 0x20;
|
||||
|
||||
/* optimize one of the non-standard loops */
|
||||
kinst_speedup = install_mem_read32_handler(0, 0x8808f5bc, 0x8808f5bf, kinst_speedup_r);
|
||||
kinst_install_speedup();
|
||||
|
||||
/* set the fastest DRC options */
|
||||
mips3drc_set_options(0, MIPS3DRC_FASTEST_OPTIONS);
|
||||
|
||||
kinst_register_state();
|
||||
}
|
||||
|
||||
|
||||
@@ -526,10 +907,12 @@ static DRIVER_INIT( kinst2 )
|
||||
features[14*2+1] = 0x41;
|
||||
|
||||
/* optimize one of the non-standard loops */
|
||||
kinst_speedup = install_mem_read32_handler(0, 0x887ff544, 0x887ff547, kinst_speedup_r);
|
||||
kinst_install_speedup();
|
||||
|
||||
/* set the fastest DRC options */
|
||||
mips3drc_set_options(0, MIPS3DRC_FASTEST_OPTIONS);
|
||||
|
||||
kinst_register_state();
|
||||
}
|
||||
|
||||
|
||||
@@ -540,5 +923,11 @@ static DRIVER_INIT( kinst2 )
|
||||
*
|
||||
*************************************/
|
||||
|
||||
GAME( 1994, kinst, 0, kinst, kinst, kinst, ROT0, "Rare", "Killer Instinct (v1.0)" )
|
||||
GAME( 1994, kinst2, 0, kinst, kinst, kinst2, ROT0, "Rare", "Killer Instinct 2 (v2.1)" )
|
||||
GAME( 1994, kinst, 0, kinst, kinst, kinst, ROT0, "Rare / Nintendo (Midway license)", "Killer Instinct (v1.5d)" )
|
||||
GAME( 1994, kinst14, kinst, kinst, kinst, kinst, ROT0, "Rare / Nintendo (Midway license)", "Killer Instinct (v1.4)" )
|
||||
GAME( 1994, kinst13, kinst, kinst, kinst, kinst, ROT0, "Rare / Nintendo (Midway license)", "Killer Instinct (v1.3)" )
|
||||
GAME( 1994, kinstp, kinst, kinst, kinst, kinst, ROT0, "Rare / Nintendo (Midway license)", "Killer Instinct (proto v4.7)" )
|
||||
GAME( 1996, kinst2, 0, kinst, kinst2, kinst2, ROT0, "Rare / Nintendo (Midway license)", "Killer Instinct 2 (v1.4)" )
|
||||
GAME( 1996, kinst213, kinst2, kinst, kinst2, kinst2, ROT0, "Rare / Nintendo (Midway license)", "Killer Instinct 2 (v1.3)" )
|
||||
GAME( 1996, kinst211, kinst2, kinst, kinst2, kinst2, ROT0, "Rare / Nintendo (Midway license)", "Killer Instinct 2 (v1.1)" )
|
||||
GAME( 1996, kinst210, kinst2, kinst, kinst2, kinst2, ROT0, "Rare / Nintendo (Midway license)", "Killer Instinct 2 (v1.0)" )
|
||||
+1
-1
@@ -1221,7 +1221,7 @@ static struct GfxDecodeInfo gfxdecodeinfo[] =
|
||||
|
||||
static struct GfxDecodeInfo spyhunt_gfxdecodeinfo[] =
|
||||
{
|
||||
{ REGION_GFX1, 0, &spyhunt_charlayout, 1*16, 1 },
|
||||
{ REGION_GFX1, 0, &spyhunt_charlayout, 3*16, 1 },
|
||||
{ REGION_GFX2, 0, &mcr_sprite_layout, 0*16, 4 },
|
||||
{ REGION_GFX3, 0, &spyhunt_alphalayout, 4*16, 1 },
|
||||
{ -1 } /* end of array */
|
||||
|
||||
+1358
-407
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+3898
-1867
File diff suppressed because it is too large.
Load diff
+1417
-589
File diff suppressed because it is too large.
Load diff
+2442
-202
File diff suppressed because it is too large.
Load diff
+93
-16
@@ -181,6 +181,7 @@ Dave Widel
|
||||
#include "vidhrdw/generic.h"
|
||||
#include "pacman.h"
|
||||
#include "cpu/s2650/s2650.h"
|
||||
#include "state.h"
|
||||
|
||||
|
||||
static UINT8 speedcheat = 0; /* a well known hack allows to make Pac Man run at four times */
|
||||
@@ -491,15 +492,37 @@ static READ_HANDLER( alibaba_mystery_1_r )
|
||||
}
|
||||
|
||||
|
||||
/* The mystery item clock (from current MAME): a write to 0x5080 starts or
|
||||
stops it (d0) and shows it (d1). Running, it advances every 64 frames,
|
||||
and the mystery item lights up when it reaches 24. */
|
||||
int alibaba_mystery_control, alibaba_mystery_clock;
|
||||
static int alibaba_mystery_prescaler;
|
||||
|
||||
static READ_HANDLER( alibaba_mystery_2_r )
|
||||
{
|
||||
static int mystery = 0;
|
||||
/* The single bit return value determines when the mystery is lit up. */
|
||||
return (alibaba_mystery_clock >= 24) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* The single bit return value determines when the mystery is lit up.*/
|
||||
/* This is certainly wrong*/
|
||||
static WRITE_HANDLER( alibaba_mystery_w )
|
||||
{
|
||||
/* d0: start/stop clock */
|
||||
if ((alibaba_mystery_control ^ data) & 1)
|
||||
alibaba_mystery_prescaler = alibaba_mystery_clock = 0;
|
||||
|
||||
mystery++;
|
||||
return (mystery >> 10) & 1;
|
||||
/* d1: show clock */
|
||||
alibaba_mystery_control = data;
|
||||
}
|
||||
|
||||
static INTERRUPT_GEN( alibaba_interrupt )
|
||||
{
|
||||
/* increment the clock every 64 frames (about 1.05 s) */
|
||||
alibaba_mystery_prescaler = (alibaba_mystery_prescaler + 1) & 0x3f;
|
||||
|
||||
if (alibaba_mystery_prescaler == 0 && (alibaba_mystery_control & 1))
|
||||
alibaba_mystery_clock = (alibaba_mystery_clock + 1) & 0x1f;
|
||||
|
||||
irq0_line_hold();
|
||||
}
|
||||
|
||||
|
||||
@@ -845,6 +868,7 @@ static MEMORY_WRITE_START( alibaba_writemem )
|
||||
{ 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 */
|
||||
{ 0x5080, 0x50bf, alibaba_mystery_w },
|
||||
{ 0x50c0, 0x50c0, pengo_sound_enable_w },
|
||||
{ 0x50c1, 0x50c1, pacman_flipscreen_w },
|
||||
{ 0x50c2, 0x50c2, interrupt_enable_w },
|
||||
@@ -2624,6 +2648,33 @@ static struct GfxDecodeInfo gfxdecodeinfo[] =
|
||||
};
|
||||
|
||||
|
||||
static struct GfxLayout alibaba_clocklayout =
|
||||
{
|
||||
24,16, /* 24*16 characters */
|
||||
RGN_FRAC(1,2),
|
||||
2,
|
||||
{ RGN_FRAC(1,2), RGN_FRAC(0,2) },
|
||||
{
|
||||
16*8+7, 16*8+6, 16*8+5, 16*8+4, 16*8+3, 16*8+2, 16*8+1, 16*8+0,
|
||||
8*8+7, 8*8+6, 8*8+5, 8*8+4, 8*8+3, 8*8+2, 8*8+1, 8*8+0,
|
||||
0*8+7, 0*8+6, 0*8+5, 0*8+4, 0*8+3, 0*8+2, 0*8+1, 0*8+0
|
||||
},
|
||||
{
|
||||
256+0*8, 256+1*8, 256+2*8, 256+3*8, 256+4*8, 256+5*8, 256+6*8, 256+7*8,
|
||||
0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8
|
||||
},
|
||||
32*16 /* every char takes 64 bytes */
|
||||
};
|
||||
|
||||
static struct GfxDecodeInfo alibaba_gfxdecodeinfo[] =
|
||||
{
|
||||
{ REGION_GFX1, 0x0000, &tilelayout, 0, 128 },
|
||||
{ REGION_GFX1, 0x1000, &spritelayout, 0, 128 },
|
||||
{ REGION_GFX2, 0x0000, &alibaba_clocklayout, 0, 128 },
|
||||
{ -1 } /* end of array */
|
||||
};
|
||||
|
||||
|
||||
static struct GfxDecodeInfo s2650games_gfxdecodeinfo[] =
|
||||
{
|
||||
{ REGION_GFX1, 0x0000, &tilelayout, 0, 128 },
|
||||
@@ -2830,9 +2881,13 @@ static MACHINE_DRIVER_START( alibaba )
|
||||
|
||||
MDRV_CPU_MODIFY("main")
|
||||
MDRV_CPU_MEMORY(alibaba_readmem,alibaba_writemem)
|
||||
MDRV_CPU_VBLANK_INT(irq0_line_hold,1)
|
||||
MDRV_CPU_VBLANK_INT(alibaba_interrupt,1)
|
||||
|
||||
MDRV_MACHINE_INIT(NULL)
|
||||
|
||||
/* video hardware */
|
||||
MDRV_GFXDECODE(alibaba_gfxdecodeinfo)
|
||||
MDRV_VIDEO_UPDATE(alibaba)
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
static MACHINE_DRIVER_START( piranha )
|
||||
@@ -3900,7 +3955,7 @@ ROM_START( theglobp )
|
||||
ROM_END
|
||||
|
||||
|
||||
ROM_START( beastf )
|
||||
ROM_START( beastfp )
|
||||
ROM_REGION( 0x20000, REGION_CPU1, 0 ) /* 64k for code */
|
||||
ROM_LOAD( "bf-u2.bin", 0x0000, 0x2000, CRC(3afc517b) SHA1(5b74bca9e9cd4d8bcf94a340f8f0e53fe1dcfc1d) )
|
||||
ROM_LOAD( "bf-u3.bin", 0x2000, 0x2000, CRC(8dbd76d0) SHA1(058c01e87ad583eb99d5043a821e6c68f1b30267) )
|
||||
@@ -3996,9 +4051,9 @@ ROM_START( alibaba )
|
||||
ROM_LOAD( "82s126.1m", 0x0000, 0x0100, CRC(a9cc86bf) SHA1(bbcec0570aeceb582ff8238a4bc8546a23430081) )
|
||||
ROM_LOAD( "82s126.3m", 0x0100, 0x0100, CRC(77245b66) SHA1(0c4d0bee858b97632411c440bea6948a74759746) ) /* timing - not used */
|
||||
|
||||
/* unknown, used for the mystery items ? */
|
||||
ROM_REGION( 0x1000, REGION_USER1, 0 )
|
||||
ROM_LOAD( "ab7.bin", 0x0000, 0x0800, CRC(52294ef5) SHA1(1d76e16c95cb2873d898a4151a902113fccafe1c) )
|
||||
ROM_REGION( 0x1000, REGION_GFX2, 0 ) /* mystery item clock */
|
||||
ROM_LOAD( "ab7.bin", 0x0000, 0x0800, CRC(52294ef5) SHA1(1d76e16c95cb2873d898a4151a902113fccafe1c) ) /* 7.p6 dumped as 0x1000 - 1st and 2nd half identical */
|
||||
ROM_RELOAD( 0x0800, 0x0800 )
|
||||
ROM_END
|
||||
|
||||
ROM_START( alibabab )
|
||||
@@ -4024,9 +4079,9 @@ ROM_START( alibabab )
|
||||
ROM_LOAD( "82s126.1m", 0x0000, 0x0100, CRC(a9cc86bf) SHA1(bbcec0570aeceb582ff8238a4bc8546a23430081) )
|
||||
ROM_LOAD( "82s126.3m", 0x0100, 0x0100, CRC(77245b66) SHA1(0c4d0bee858b97632411c440bea6948a74759746) ) /* timing - not used */
|
||||
|
||||
/* unknown, used for the mystery items ? */
|
||||
ROM_REGION( 0x1000, REGION_USER1, 0 )
|
||||
ROM_LOAD( "ab7.bin", 0x0000, 0x0800, CRC(52294ef5) SHA1(1d76e16c95cb2873d898a4151a902113fccafe1c) )
|
||||
ROM_REGION( 0x1000, REGION_GFX2, 0 ) /* mystery item clock */
|
||||
ROM_LOAD( "ab7.bin", 0x0000, 0x0800, CRC(52294ef5) SHA1(1d76e16c95cb2873d898a4151a902113fccafe1c) ) /* 7.p6 dumped as 0x1000 - 1st and 2nd half identical */
|
||||
ROM_RELOAD( 0x0800, 0x0800 )
|
||||
ROM_END
|
||||
|
||||
ROM_START( jumpshot )
|
||||
@@ -4490,6 +4545,28 @@ static void eyes_decode(unsigned char *data)
|
||||
}
|
||||
}
|
||||
|
||||
static DRIVER_INIT( alibaba )
|
||||
{
|
||||
data8_t *rom = memory_region(REGION_GFX2);
|
||||
int len = memory_region_length(REGION_GFX2);
|
||||
int i;
|
||||
|
||||
/* reorder the clock graphics a bit to make them work with gfxdecode */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if ((i & 0x3f) < 0x18)
|
||||
{
|
||||
rom[i] = rom[i + 8];
|
||||
rom[i + 8] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
alibaba_mystery_control = alibaba_mystery_clock = alibaba_mystery_prescaler = 0;
|
||||
state_save_register_int("alibaba", 0, "mystery_control", &alibaba_mystery_control);
|
||||
state_save_register_int("alibaba", 0, "mystery_clock", &alibaba_mystery_clock);
|
||||
state_save_register_int("alibaba", 0, "mystery_prescaler", &alibaba_mystery_prescaler);
|
||||
}
|
||||
|
||||
static DRIVER_INIT( eyes )
|
||||
{
|
||||
int i;
|
||||
@@ -4617,14 +4694,14 @@ GAME( 1983, gorkans, mrtnt, pacman, mrtnt, 0, ROT90, "Techst
|
||||
GAMEX(1983, eggor, 0, pacman, mrtnt, eyes, ROT90, "Telko", "Eggor", GAME_WRONG_COLORS | GAME_IMPERFECT_SOUND )
|
||||
GAME( 1985, lizwiz, 0, pacman, lizwiz, 0, ROT90, "Techstar (Sunn license)", "Lizard Wizard" )
|
||||
GAME( 1983, theglobp, suprglob, theglobp, theglobp, 0, ROT90, "Epos Corporation", "The Glob (Pac-Man hardware)" )
|
||||
GAME( 1984, beastf, suprglob, theglobp, theglobp, 0, ROT90, "Epos Corporation", "Beastie Feastie" )
|
||||
GAME( 1984, beastfp, suprglob, theglobp, theglobp, 0, ROT90, "Epos Corporation", "Beastie Feastie (Pac-Man conversion)" )
|
||||
GAME( 1983, bwcasino, 0, acitya, bwcasino, 0, ROT90, "Epos Corporation", "Boardwalk Casino" )
|
||||
GAME( 1982, dremshpr, 0, dremshpr, dremshpr, 0, ROT270, "Sanritsu", "Dream Shopper" )
|
||||
GAME( 1983, acitya, bwcasino, acitya, acitya, 0, ROT90, "Epos Corporation", "Atlantic City Action" )
|
||||
GAME( 1983, vanvan, 0, vanvan, vanvan, 0, ROT270, "Sanritsu", "Van-Van Car" )
|
||||
GAME( 1983, vanvank, vanvan, vanvan, vanvank, 0, ROT270, "Karateco", "Van-Van Car (Karateco)" )
|
||||
GAMEX(1982, alibaba, 0, alibaba, alibaba, 0, ROT90, "Sega", "Ali Baba and 40 Thieves", GAME_UNEMULATED_PROTECTION )
|
||||
GAMEX(1982, alibabab, alibaba, alibaba, alibaba, 0, ROT90, "bootleg", "Mustafa and 40 Thieves (bootleg)", GAME_UNEMULATED_PROTECTION )
|
||||
GAME( 1982, alibaba, 0, alibaba, alibaba, alibaba, ROT90, "Sega", "Ali Baba and 40 Thieves" )
|
||||
GAME( 1982, alibabab, alibaba, alibaba, alibaba, alibaba, ROT90, "bootleg", "Mustafa and 40 Thieves (bootleg)" )
|
||||
GAME( 1985, jumpshot, 0, pacman, jumpshot, jumpshot, ROT90, "Bally Midway", "Jump Shot" )
|
||||
GAME( 1985, shootbul, 0, pacman, shootbul, jumpshot, ROT90, "Bally Midway", "Shoot the Bull" )
|
||||
GAME( 1986, bigbucks, 0, bigbucks, bigbucks, 0, ROT90, "Dynasoft Inc.", "Big Bucks" )
|
||||
|
||||
+2311
-169
File diff suppressed because it is too large.
Load diff
+4493
-239
File diff suppressed because it is too large.
Load diff
+634
-162
File diff suppressed because it is too large.
Load diff
+269
-6
@@ -247,6 +247,12 @@ extern UINT16 scanbase;
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
/* Mega Play: H-INT/V-INT are cleared by the 68000 interrupt acknowledge
|
||||
(see genesis_irq_ack_callback) instead of timing out; also selects the
|
||||
corrected HBLANK status bit in vidhrdw/segac2_vidhrdw.c */
|
||||
int genesis_vdp_iack;
|
||||
void segac2_vdp_set_vblank(void);
|
||||
|
||||
/* call this whenever the interrupt state has changed */
|
||||
static void update_interrupts(void)
|
||||
{
|
||||
@@ -254,8 +260,20 @@ static void update_interrupts(void)
|
||||
|
||||
/* determine which interrupt is active */
|
||||
if (ym3438_int) level = 2;
|
||||
if (scanline_int) level = 4;
|
||||
if (vblank_int) level = 6;
|
||||
if (genesis_vdp_iack)
|
||||
{
|
||||
/* Mega Play: a pending H-INT/V-INT only drives the line while it is
|
||||
enabled in VDP register 0/1, as on the real 315-5313 (Mazin Wars masks
|
||||
H-INT this way while its V-INT handler borrows a5/a6, which its H-INT
|
||||
handler jumps through) */
|
||||
if (scanline_int && (segac2_vdp_regs[0] & 0x10)) level = 4;
|
||||
if (vblank_int && (segac2_vdp_regs[1] & 0x20)) level = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scanline_int) level = 4;
|
||||
if (vblank_int) level = 6;
|
||||
}
|
||||
|
||||
/* either set or clear the appropriate lines */
|
||||
if (level)
|
||||
@@ -282,7 +300,9 @@ static void vdp_reload_counter(int scanline)
|
||||
{
|
||||
scanline_int = 1;
|
||||
update_interrupts();
|
||||
timer_set(cpu_getscanlinetime(scanline + 1), 0, vdp_int4_off);
|
||||
/* with IACK emulation the line stays asserted until the 68000 takes it */
|
||||
if (!genesis_vdp_iack)
|
||||
timer_set(cpu_getscanlinetime(scanline + 1), 0, vdp_int4_off);
|
||||
}
|
||||
|
||||
/* advance to the next scanline */
|
||||
@@ -307,8 +327,38 @@ static void vdp_int6_off(int param)
|
||||
|
||||
|
||||
/* interrupt callback to generate the VBLANK interrupt */
|
||||
/* Mega Play: V-INT raised shortly after the VBLANK status bit */
|
||||
static void genesis_vint_delayed(int param)
|
||||
{
|
||||
/* the pending flag is always set; update_interrupts() gates it with R1 */
|
||||
vblank_int = 1;
|
||||
update_interrupts();
|
||||
}
|
||||
|
||||
/* called by the VDP after a write to R0/R1 (Mega Play only) */
|
||||
void segac2_vdp_irq_update(void)
|
||||
{
|
||||
if (genesis_vdp_iack)
|
||||
update_interrupts();
|
||||
}
|
||||
|
||||
static INTERRUPT_GEN( vblank_interrupt )
|
||||
{
|
||||
/* with IACK emulation V-INT stays pending until the 68000 takes it, so it
|
||||
is not lost while an H-INT handler has the interrupts masked; as on the
|
||||
real 315-5313 it only drives the 68000 while enabled in VDP register 1 */
|
||||
if (genesis_vdp_iack)
|
||||
{
|
||||
/* the VBLANK status bit rises first and V-INT follows about 788 master
|
||||
clocks later (~112 68000 cycles): code polling the status bit gets to
|
||||
see VBLANK before the interrupt takes over. Mazin Wars depends on it:
|
||||
its V-INT handler outlasts the blanking period, so without the gap its
|
||||
main loop never sees VBLANK and hangs in a fade loop after coin-up. */
|
||||
segac2_vdp_set_vblank();
|
||||
timer_set(TIME_IN_USEC(788.0 * 1000000.0 / 53693100.0), 0, genesis_vint_delayed);
|
||||
return;
|
||||
}
|
||||
|
||||
/* generate the interrupt */
|
||||
vblank_int = 1;
|
||||
update_interrupts();
|
||||
@@ -354,6 +404,8 @@ static MACHINE_INIT( segac2 )
|
||||
|
||||
static MACHINE_INIT( genesis )
|
||||
{
|
||||
genesis_vdp_iack = 0;
|
||||
|
||||
/* the following ensures that the Z80 begins without running away from 0 */
|
||||
/* 0x76 is just a forced 'halt' as soon as the CPU is initially run */
|
||||
genesis_z80_ram[0] = 0x76;
|
||||
@@ -380,6 +432,36 @@ static MACHINE_INIT( megatech )
|
||||
machine_init_genesis();
|
||||
}
|
||||
|
||||
/* On the real 315-5313 VDP the H-INT (level 4) and V-INT (level 6) pending
|
||||
flags are cleared when the 68000 acknowledges the interrupt.
|
||||
The old timed pulses break games that use H-INT on every line:
|
||||
- IRQ4 held for a whole scanline re-enters a short H-INT handler over and
|
||||
over and the main program starves;
|
||||
- IRQ6 dropped after 22 pixels is lost when the H-INT handler of line 223
|
||||
still has the interrupts masked, so the game never sees V-INT again.
|
||||
Gunstar Heroes hits both (68000 stuck at $FFEE04, its H-INT handler in RAM). */
|
||||
static int genesis_irq_ack_callback(int irqline)
|
||||
{
|
||||
int level = 0;
|
||||
|
||||
if (irqline == 4)
|
||||
scanline_int = 0;
|
||||
else if (irqline == 6)
|
||||
vblank_int = 0;
|
||||
|
||||
if (ym3438_int) level = 2;
|
||||
if (scanline_int && (segac2_vdp_regs[0] & 0x10)) level = 4;
|
||||
if (vblank_int && (segac2_vdp_regs[1] & 0x20)) level = 6;
|
||||
|
||||
/* drop the line now (an immediate clear cannot re-enter the CPU core),
|
||||
then re-assert whatever is still pending */
|
||||
activecpu_set_irq_line(7, INTERNAL_CLEAR_LINE);
|
||||
if (level)
|
||||
cpu_set_irq_line(0, level, ASSERT_LINE);
|
||||
|
||||
return MC68000_INT_ACK_AUTOVECTOR;
|
||||
}
|
||||
|
||||
static MACHINE_INIT( megaplay )
|
||||
{
|
||||
/* unsigned char* ram = memory_region(REGION_CPU3); */
|
||||
@@ -390,6 +472,10 @@ static MACHINE_INIT( megaplay )
|
||||
cpu_setbank(3, &genesis_68k_ram[0]);
|
||||
|
||||
machine_init_genesis();
|
||||
|
||||
genesis_vdp_iack = 1;
|
||||
scanline_int = vblank_int = 0;
|
||||
cpu_set_irq_callback(0, genesis_irq_ack_callback);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@@ -1606,7 +1692,12 @@ READ16_HANDLER ( megaplay_genesis_io_r )
|
||||
return_value = readinputport(1) & (genesis_io_ram[4]^0xff);
|
||||
else
|
||||
{
|
||||
return_value = readinputport(2) & (genesis_io_ram[4]^0xff);
|
||||
/* the pad's Start line is driven by the BIOS (bit 4 of $6203,
|
||||
active low), not by the Start button: the BIOS reads the button
|
||||
on its own port and passes it on only when the game may start
|
||||
(Mazin Wars expects exactly this). Same as current MAME. */
|
||||
return_value = (readinputport(2) & ~0x20 & 0xff) | ((bios_bank & 0x10) ? 0x20 : 0x00);
|
||||
return_value &= (genesis_io_ram[4]^0xff);
|
||||
return_value |= readinputport(1) & 0x03;
|
||||
}
|
||||
return_value = (genesis_io_ram[offset] & 0x80) | return_value;
|
||||
@@ -1619,7 +1710,9 @@ READ16_HANDLER ( megaplay_genesis_io_r )
|
||||
return_value = readinputport(3) & (genesis_io_ram[5]^0xff);
|
||||
else
|
||||
{
|
||||
return_value = readinputport(4) & (genesis_io_ram[5]^0xff);
|
||||
/* P2 Start from the BIOS too (bit 5 of $6203) */
|
||||
return_value = (readinputport(4) & ~0x20 & 0xff) | ((bios_bank & 0x20) ? 0x20 : 0x00);
|
||||
return_value &= (genesis_io_ram[5]^0xff);
|
||||
return_value |= readinputport(3) & 0x03;
|
||||
}
|
||||
return_value = (genesis_io_ram[offset] & 0x80) | return_value;
|
||||
@@ -4239,6 +4332,97 @@ INPUT_PORTS_START ( mp_shnb3 )
|
||||
PORT_DIPSETTING( 0x0c, "Normal" )
|
||||
INPUT_PORTS_END
|
||||
|
||||
INPUT_PORTS_START ( mp_gunhe )
|
||||
GENESIS_PORTS
|
||||
MEGAPLAY_TEST
|
||||
MEGAPLAY_COIN
|
||||
MEGAPLAY_DSWA
|
||||
MEGAPLAY_DSWB
|
||||
|
||||
PORT_START
|
||||
/* DSW C (per game settings) */
|
||||
PORT_DIPNAME( 0x03, 0x01, "Initial Players" )
|
||||
PORT_DIPSETTING( 0x00, "4" )
|
||||
PORT_DIPSETTING( 0x01, "3" )
|
||||
PORT_DIPSETTING( 0x02, "2" )
|
||||
PORT_DIPSETTING( 0x03, "1" )
|
||||
|
||||
PORT_DIPNAME( 0xc, 0x0c, DEF_STR ( Difficulty ) )
|
||||
PORT_DIPSETTING( 0x00, "Expert" )
|
||||
PORT_DIPSETTING( 0x04, "Hard" )
|
||||
PORT_DIPSETTING( 0x08, "Easy" )
|
||||
PORT_DIPSETTING( 0x0c, "Normal" )
|
||||
INPUT_PORTS_END
|
||||
|
||||
INPUT_PORTS_START ( mp_gslam )
|
||||
GENESIS_PORTS
|
||||
MEGAPLAY_TEST
|
||||
MEGAPLAY_COIN
|
||||
MEGAPLAY_DSWA
|
||||
MEGAPLAY_DSWB
|
||||
|
||||
PORT_START
|
||||
/* DSW C (per game settings) */
|
||||
PORT_DIPNAME( 0x07, 0x04, "Game Time" )
|
||||
PORT_DIPSETTING( 0x07, "1:30" )
|
||||
PORT_DIPSETTING( 0x06, "2:00" )
|
||||
PORT_DIPSETTING( 0x05, "2:30" )
|
||||
PORT_DIPSETTING( 0x04, "3:00" )
|
||||
PORT_DIPSETTING( 0x03, "3:30" )
|
||||
PORT_DIPSETTING( 0x02, "4:00" )
|
||||
PORT_DIPSETTING( 0x01, "4:30" )
|
||||
PORT_DIPSETTING( 0x00, "5:00" )
|
||||
|
||||
PORT_DIPNAME( 0x08, 0x08, "2P-Play Continue" )
|
||||
PORT_DIPSETTING( 0x00, "1 Credit" )
|
||||
PORT_DIPSETTING( 0x08, "2 Credits" )
|
||||
INPUT_PORTS_END
|
||||
|
||||
INPUT_PORTS_START ( mp_mazin )
|
||||
GENESIS_PORTS
|
||||
MEGAPLAY_TEST
|
||||
MEGAPLAY_COIN
|
||||
MEGAPLAY_DSWA
|
||||
MEGAPLAY_DSWB
|
||||
|
||||
PORT_START
|
||||
/* DSW C (per game settings) */
|
||||
PORT_DIPNAME( 0x03, 0x01, "Initial Player" )
|
||||
PORT_DIPSETTING( 0x02, "1" )
|
||||
PORT_DIPSETTING( 0x03, "2" )
|
||||
PORT_DIPSETTING( 0x01, "3" )
|
||||
PORT_DIPSETTING( 0x00, "4" )
|
||||
|
||||
PORT_DIPNAME( 0x04, 0x04, DEF_STR ( Difficulty ) )
|
||||
PORT_DIPSETTING( 0x04, "Normal" )
|
||||
PORT_DIPSETTING( 0x00, "Hard" )
|
||||
|
||||
PORT_DIPNAME( 0x08, 0x08, "Title" )
|
||||
PORT_DIPSETTING( 0x08, "EUROPE" )
|
||||
PORT_DIPSETTING( 0x00, "U.S.A" )
|
||||
INPUT_PORTS_END
|
||||
|
||||
INPUT_PORTS_START ( mp_addams )
|
||||
GENESIS_PORTS
|
||||
MEGAPLAY_TEST
|
||||
MEGAPLAY_COIN
|
||||
MEGAPLAY_DSWA
|
||||
MEGAPLAY_DSWB
|
||||
|
||||
PORT_START
|
||||
/* DSW C (per game settings) */
|
||||
PORT_DIPNAME( 0x03, 0x03, "1UP Every" )
|
||||
PORT_DIPSETTING( 0x03, "3 Pickups" )
|
||||
PORT_DIPSETTING( 0x02, "2 Pickups" )
|
||||
PORT_DIPSETTING( 0x01, "1 Pickup" )
|
||||
|
||||
PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Lives ) )
|
||||
PORT_DIPSETTING( 0x0c, "3" )
|
||||
PORT_DIPSETTING( 0x08, "5" )
|
||||
PORT_DIPSETTING( 0x04, "7" )
|
||||
PORT_DIPSETTING( 0x00, "99" )
|
||||
INPUT_PORTS_END
|
||||
|
||||
INPUT_PORTS_START( aladbl )
|
||||
PORT_START /* Joypad 1 (3 button + start) NOT READ DIRECTLY */
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY | IPF_PLAYER1)
|
||||
@@ -4852,6 +5036,7 @@ static MACHINE_DRIVER_START( megaplay )
|
||||
/* MDRV_CPU_PROGRAM_MAP(megaplay_genesis_readmem, genesis_writemem) */
|
||||
|
||||
MDRV_VIDEO_START(megaplay)
|
||||
MDRV_VIDEO_EOF(segac2) /* VBLANK tracking: without it there are no mid-screen partial updates */
|
||||
MDRV_VIDEO_UPDATE(megaplay)
|
||||
MDRV_MACHINE_INIT(megaplay)
|
||||
|
||||
@@ -4862,6 +5047,23 @@ static MACHINE_DRIVER_START( megaplay )
|
||||
MDRV_CPU_VBLANK_INT(megatech_irq, 262)
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
/* The BIOS keeps its credits, bookkeeping and each slot's 256-byte game
|
||||
area (high scores) in battery-backed RAM at Z80 0x6800-0x77ff. */
|
||||
static NVRAM_HANDLER( megaplay )
|
||||
{
|
||||
if (read_or_write)
|
||||
mame_fwrite(file, ic3_ram, 0x1000);
|
||||
else if (file)
|
||||
mame_fread(file, ic3_ram, 0x1000);
|
||||
else
|
||||
memset(ic3_ram, 0, 0x1000);
|
||||
}
|
||||
|
||||
static MACHINE_DRIVER_START( megaplay_nvram )
|
||||
MDRV_IMPORT_FROM(megaplay)
|
||||
MDRV_NVRAM_HANDLER(megaplay)
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
/******************************************************************************
|
||||
Rom Definitions
|
||||
*******************************************************************************
|
||||
@@ -5912,6 +6114,63 @@ ROM_START( mp_sor2 ) /* Streets of Rage 2 */
|
||||
MEGAPLAY_BIOS
|
||||
ROM_END
|
||||
|
||||
ROM_START( mp_gunhe ) /* Gunstar Heroes */
|
||||
ROM_REGION( 0x400000, REGION_CPU1, 0 )
|
||||
ROM_LOAD16_WORD_SWAP( "mpr-16390.ic1", 0x000000, 0x100000, CRC(d963a748) SHA1(adf231c5180a9307fd6675fe77fffd4c5bfa3d6a) )
|
||||
/* Game Instruction rom copied to 0x300000 - 0x310000 (odd / even bytes equal) */
|
||||
|
||||
ROM_REGION( 0x10000, REGION_CPU2, 0 ) /* z80 */
|
||||
|
||||
ROM_REGION( 0x8000, REGION_USER1, 0 ) /* Game Instructions */
|
||||
ROM_LOAD( "epr-15175-10.ic2", 0x000000, 0x08000, CRC(e4f08233) SHA1(b7e0ad3f6ae1c56df6ec76375842050f08afcbef) )
|
||||
|
||||
ROM_REGION( 0x28000, REGION_CPU3, 0 ) /* Bios */
|
||||
MEGAPLAY_BIOS
|
||||
ROM_END
|
||||
|
||||
ROM_START( mp_gslam ) /* Grand Slam */
|
||||
ROM_REGION( 0x400000, REGION_CPU1, 0 )
|
||||
ROM_LOAD16_BYTE( "epr-15181.ic2", 0x000000, 0x040000, CRC(642437c1) SHA1(cbf88e196c04b6d886bf9642b69bf165045510fe) )
|
||||
ROM_LOAD16_BYTE( "epr-15180.ic1", 0x000001, 0x040000, CRC(73bb48f1) SHA1(981b64f834d5618599352f5fad683bf232390ba3) )
|
||||
/* Game Instruction rom copied to 0x300000 - 0x310000 (odd / even bytes equal) */
|
||||
|
||||
ROM_REGION( 0x10000, REGION_CPU2, 0 ) /* z80 */
|
||||
|
||||
ROM_REGION( 0x8000, REGION_USER1, 0 ) /* Game Instructions */
|
||||
ROM_LOAD( "epr-15175-03.ic3", 0x000000, 0x08000, CRC(70ea1aec) SHA1(0d9d82a1f8aa51d02707f7b343e7cfb6591efccd) )
|
||||
|
||||
ROM_REGION( 0x28000, REGION_CPU3, 0 ) /* Bios */
|
||||
MEGAPLAY_BIOS
|
||||
ROM_END
|
||||
|
||||
ROM_START( mp_mazin ) /* Mazin Wars */
|
||||
ROM_REGION( 0x400000, REGION_CPU1, 0 )
|
||||
ROM_LOAD16_WORD_SWAP( "mpr-16460.ic1", 0x000000, 0x100000, CRC(e9635a83) SHA1(ab3afa11656f0ae3a50c957dce012fb15d3992e0) )
|
||||
/* Game Instruction rom copied to 0x300000 - 0x310000 (odd / even bytes equal) */
|
||||
|
||||
ROM_REGION( 0x10000, REGION_CPU2, 0 ) /* z80 */
|
||||
|
||||
ROM_REGION( 0x8000, REGION_USER1, 0 ) /* Game Instructions */
|
||||
ROM_LOAD( "epr-15175-11.ic2", 0x000000, 0x08000, CRC(bb651120) SHA1(81cb736f2732373e260dde162249c1d29a3489c3) )
|
||||
|
||||
ROM_REGION( 0x28000, REGION_CPU3, 0 ) /* Bios */
|
||||
MEGAPLAY_BIOS
|
||||
ROM_END
|
||||
|
||||
ROM_START( mp_addams ) /* The Addams Family ARCADE (homebrew conversion of the Mega Drive game) */
|
||||
ROM_REGION( 0x400000, REGION_CPU1, 0 )
|
||||
ROM_LOAD16_WORD_SWAP( "epr-26013.ic1", 0x000000, 0x200000, CRC(87ecace1) SHA1(d6529b4b692a9515ccf6722f26c011660154ae7a) )
|
||||
/* Game Instruction rom copied to 0x300000 - 0x310000 (odd / even bytes equal) */
|
||||
|
||||
ROM_REGION( 0x10000, REGION_CPU2, 0 ) /* z80 */
|
||||
|
||||
ROM_REGION( 0x8000, REGION_USER1, 0 ) /* Game Instructions */
|
||||
ROM_LOAD( "epr-15175-20.ic2", 0x000000, 0x08000, CRC(dcfde4e7) SHA1(3f5a1b4de94fad4ccd404b95a53fdb2e1c4773e6) )
|
||||
|
||||
ROM_REGION( 0x28000, REGION_CPU3, 0 ) /* Bios */
|
||||
MEGAPLAY_BIOS
|
||||
ROM_END
|
||||
|
||||
ROM_START( mp_twc ) /* Tecmo World Cup */
|
||||
ROM_REGION( 0x400000, REGION_CPU1, 0 )
|
||||
ROM_LOAD16_BYTE( "ep15183.ic2", 0x000000, 0x040000, CRC(8b79b861) SHA1(c72af72840513b82f2562409eccdf13b031bf3c0) )
|
||||
@@ -6771,9 +7030,13 @@ static DRIVER_INIT (megaplay)
|
||||
/* -- */ GAMEBX(1993, megaplay, 0, megaplay, megaplay, megaplay, megaplay, ROT0, "Sega", "MegaPlay: BIOS", NOT_A_DRIVER, &generic_ctrl, NULL )
|
||||
/* 01 */ GAMEB( 1993, mp_sonic, megaplay, megaplay, megaplay, mp_sonic, megaplay, ROT0, "Sega", "Sonic The Hedgehog", &megaplay_ctrl, NULL )
|
||||
/* 02 */ GAMEB( 1993, mp_gaxe2, megaplay, megaplay, megaplay, mp_gaxe2, megaplay, ROT0, "Sega", "Golden Axe II", &megaplay_ctrl, NULL )
|
||||
/* 03 */ GAMEB( 1993, mp_gslam, megaplay, megaplay, megaplay, mp_gslam, megaplay, ROT0, "Sega", "Grand Slam", &megaplay_ctrl, NULL )
|
||||
/* 03 */ GAMEB( 1993, mp_sor2, megaplay, megaplay, megaplay, mp_sor2, megaplay, ROT0, "Sega", "Streets Of Rage II", &megaplay_ctrl, NULL )
|
||||
/* 04 */ GAMEB( 1993, mp_twc, megaplay, megaplay, megaplay, mp_twc, megaplay, ROT0, "Sega", "Tecmo World Cup", &megaplay_ctrl, NULL )
|
||||
/* 05 */ GAMEB( 1993, mp_soni2, megaplay, megaplay, megaplay, mp_soni2, megaplay, ROT0, "Sega", "Sonic The Hedgehog 2", &megaplay_ctrl, NULL )
|
||||
/* 06 */ GAMEB( 1993, mp_bio, megaplay, megaplay, megaplay, mp_bio, megaplay, ROT0, "Sega", "Bio-Hazard Battle", &megaplay_ctrl, NULL )
|
||||
/* 07 */ GAMEB( 1993, mp_shnb3, megaplay, megaplay, megaplay, mp_shnb3, megaplay, ROT0, "Sega", "Shinobi III", &megaplay_ctrl, NULL )
|
||||
/* 10 */ GAMEB( 1993, mp_col3, megaplay, megaplay, megaplay, megaplay, megaplay, ROT0, "Sega", "Columns III", &megaplay_ctrl, NULL )
|
||||
/* 10 */ GAMEB( 1993, mp_gunhe, megaplay, megaplay, megaplay, mp_gunhe, megaplay, ROT0, "Sega", "Gunstar Heroes", &megaplay_ctrl, NULL )
|
||||
/* 11 */ GAMEB( 1993, mp_mazin, megaplay, megaplay, megaplay, mp_mazin, megaplay, ROT0, "Sega", "Mazin Wars / Mazin Saga", &megaplay_ctrl, NULL )
|
||||
/* ?? */ GAMEB( 1993, mp_col3, megaplay, megaplay, megaplay, megaplay, megaplay, ROT0, "Sega", "Columns III", &megaplay_ctrl, NULL )
|
||||
/* -- */ GAMEB( 2026, mp_addams, megaplay, megaplay, megaplay_nvram, mp_addams, megaplay, ROT0, "hack", "The Addams Family ARCADE (Mega Play)", &megaplay_ctrl, NULL )
|
||||
+67
-27
@@ -1736,7 +1736,8 @@ INPUT_PORTS_START( f1lap )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SPECIAL ) /* EEPROM data*/
|
||||
|
||||
PORT_START /* 0xc00000 - port 1 */
|
||||
PORT_BITX(0x01, IP_ACTIVE_LOW, IPT_BUTTON1, "Gear Up", IP_KEY_DEFAULT, IP_JOY_DEFAULT )
|
||||
@@ -3415,33 +3416,67 @@ ROM_START( harddunj )
|
||||
ROM_LOAD("mp16507.2", 0x200000, 0x200000, CRC(31e068d3) SHA1(9ac88b15af441fb3b31ce759c565b60a09039571) )
|
||||
ROM_END
|
||||
|
||||
/* Stadium Cross: the sets and ROM names of current MAME. The old 2MB graphics
|
||||
and PCM dumps were the 1MB ROMs twice; ROM_RELOAD keeps that layout */
|
||||
#define SCROSS_COMMON_ROMS \
|
||||
ROM_REGION( 0x080000, REGION_CPU2, 0 ) /* sound CPU */ \
|
||||
ROM_LOAD_x4( "epr-15192.ic31", 0x000000, 0x20000, CRC(7524290b) SHA1(ee58be2c0c4293ee19622b96ca493f4ce4da0038) ) \
|
||||
ROM_REGION( 0x400000, REGION_GFX1, 0 ) /* tiles */ \
|
||||
ROM_LOAD16_BYTE( "mpr-15020.ic3", 0x000000, 0x100000, CRC(de47006a) SHA1(dbef7b9ff8c39992b8596d38985e65c627d6fa79) ) \
|
||||
ROM_RELOAD( 0x200000, 0x100000 ) \
|
||||
ROM_LOAD16_BYTE( "mpr-15021.ic11", 0x000001, 0x100000, CRC(3677db02) SHA1(7aeeb85f1632253fcdc8f7881512066e97837e5e) ) \
|
||||
ROM_RELOAD( 0x200001, 0x100000 ) \
|
||||
ROM_REGION32_BE( 0x1000000, REGION_GFX2, 0 ) /* sprites */ \
|
||||
ROM_LOAD64_WORD( "mpr-15022.ic14", 0x000000, 0x100000, CRC(baee6fd5) SHA1(ddf022c61f0805af45a84c65eb5d01006c153c07) ) \
|
||||
ROM_RELOAD( 0x400000, 0x100000 ) \
|
||||
ROM_LOAD64_WORD( "mpr-15024.ic15", 0x000002, 0x100000, CRC(b9f339e2) SHA1(4b9a392459132a19d62928ef3939e1f2356e3994) ) \
|
||||
ROM_RELOAD( 0x400002, 0x100000 ) \
|
||||
ROM_LOAD64_WORD( "mpr-15026.ic10", 0x000004, 0x100000, CRC(b72e8df6) SHA1(a7a87f79814b022985121e163c7f88244c50e427) ) \
|
||||
ROM_RELOAD( 0x400004, 0x100000 ) \
|
||||
ROM_LOAD64_WORD( "mpr-15028.ic38", 0x000006, 0x100000, CRC(183f6eb0) SHA1(5a2172d5afd696af361ff9f8a92f5911e05c578d) ) \
|
||||
ROM_RELOAD( 0x400006, 0x100000 ) \
|
||||
ROM_LOAD64_WORD( "mpr-15023.ic22", 0x800000, 0x100000, CRC(230735ed) SHA1(36075504e27b8a32d63fa3b8abd7037d17440ebf) ) \
|
||||
ROM_RELOAD( 0xc00000, 0x100000 ) \
|
||||
ROM_LOAD64_WORD( "mpr-15025.ic23", 0x800002, 0x100000, CRC(da4315cb) SHA1(3910c5654e34b17851d6d93615e3404b3b397fea) ) \
|
||||
ROM_RELOAD( 0xc00002, 0x100000 ) \
|
||||
ROM_LOAD64_WORD( "mpr-15027.ic18", 0x800004, 0x100000, CRC(b765efb8) SHA1(61f3865f92b36ca4b3cd20c0716a7121755eea73) ) \
|
||||
ROM_RELOAD( 0xc00004, 0x100000 ) \
|
||||
ROM_LOAD64_WORD( "mpr-15029.ic41", 0x800006, 0x100000, CRC(cf8e3b2b) SHA1(c158810d9d82b10a753bc739d1f56572042dac0b) ) \
|
||||
ROM_RELOAD( 0xc00006, 0x100000 ) \
|
||||
ROM_REGION( 0x400000, REGION_SOUND1, 0 ) /* Sega PCM sound data */ \
|
||||
ROM_LOAD( "mpr-15031.ic1", 0x000000, 0x100000, CRC(6af139dc) SHA1(2378c2ad0c52c114eb93206a6fbee723c038d030) ) \
|
||||
ROM_RELOAD( 0x100000, 0x100000 ) \
|
||||
ROM_LOAD( "mpr-15032.ic2", 0x200000, 0x100000, CRC(915d6096) SHA1(e1f670949b1254f5a3c3131993ca9b3baa4d9f6b) ) \
|
||||
ROM_RELOAD( 0x300000, 0x100000 ) \
|
||||
ROM_REGION( 0x20000, REGION_USER1, 0 ) /* comms board */ \
|
||||
ROM_LOAD( "epr-15033.ic17", 0x00000, 0x20000, CRC(dc19ac00) SHA1(16bbb5af034e5419673e637be30283b73ab7b290) )
|
||||
|
||||
ROM_START( scross )
|
||||
ROM_REGION( 0x200000, REGION_CPU1, 0 ) /* v60 code + data */
|
||||
ROM_LOAD32_WORD_x2( "epr15093.bin", 0x000000, 0x040000, CRC(2adc7a4b) SHA1(dca71f00d94898c0758394704d819e13482bf120) )
|
||||
ROM_LOAD32_WORD_x2( "epr15094.bin", 0x000002, 0x040000, CRC(bbb0ae73) SHA1(0d8837706405f301adf8fa85c8d4813d7600af98) )
|
||||
ROM_LOAD32_WORD( "epr15018.bin", 0x100000, 0x080000, CRC(3a98385e) SHA1(8088d337655030c28e290da4bbf44cb647dab66c) )
|
||||
ROM_LOAD32_WORD( "epr15019.bin", 0x100002, 0x080000, CRC(8bf4ac83) SHA1(e594d9d9b42d0765ed8a20a40b7dd92b75124d34) )
|
||||
ROM_LOAD32_WORD_x2( "epr-15093.ic37", 0x000000, 0x040000, CRC(2adc7a4b) SHA1(dca71f00d94898c0758394704d819e13482bf120) )
|
||||
ROM_LOAD32_WORD_x2( "epr-15094.ic40", 0x000002, 0x040000, CRC(bbb0ae73) SHA1(0d8837706405f301adf8fa85c8d4813d7600af98) )
|
||||
ROM_LOAD32_WORD( "mpr-15018.ic36", 0x100000, 0x080000, CRC(3a98385e) SHA1(8088d337655030c28e290da4bbf44cb647dab66c) )
|
||||
ROM_LOAD32_WORD( "mpr-15019.ic39", 0x100002, 0x080000, CRC(8bf4ac83) SHA1(e594d9d9b42d0765ed8a20a40b7dd92b75124d34) )
|
||||
SCROSS_COMMON_ROMS
|
||||
ROM_END
|
||||
|
||||
ROM_REGION( 0x080000, REGION_CPU2, 0 ) /* sound CPU */
|
||||
ROM_LOAD_x4( "epr15192.bin", 0x000000, 0x20000, CRC(7524290b) SHA1(ee58be2c0c4293ee19622b96ca493f4ce4da0038) )
|
||||
ROM_START( scrossa )
|
||||
ROM_REGION( 0x200000, REGION_CPU1, 0 ) /* v60 code + data */
|
||||
/* 37/40 were missing labels */
|
||||
ROM_LOAD32_WORD_x2( "ic37", 0x000000, 0x040000, CRC(240a7655) SHA1(7cfdce002fb4783e8c1debf206922d88647c106e) )
|
||||
ROM_LOAD32_WORD_x2( "ic40", 0x000002, 0x040000, CRC(3a073060) SHA1(c92c8d8921d94d85c8484c103cbf9cd6ad651333) )
|
||||
ROM_LOAD32_WORD( "mpr-15018.ic36", 0x100000, 0x080000, CRC(3a98385e) SHA1(8088d337655030c28e290da4bbf44cb647dab66c) )
|
||||
ROM_LOAD32_WORD( "mpr-15019.ic39", 0x100002, 0x080000, CRC(8bf4ac83) SHA1(e594d9d9b42d0765ed8a20a40b7dd92b75124d34) )
|
||||
SCROSS_COMMON_ROMS
|
||||
ROM_END
|
||||
|
||||
ROM_REGION( 0x400000, REGION_GFX1, 0 ) /* tiles */
|
||||
ROM_LOAD16_BYTE( "epr15020.bin", 0x000000, 0x200000, CRC(65afea2f) SHA1(ad573727398bfac8e94f321be84b60e5690bfba6) )
|
||||
ROM_LOAD16_BYTE( "epr15021.bin", 0x000001, 0x200000, CRC(27bc6969) SHA1(d6bb446becb2d36b73bca5055357a43b837afc0a) )
|
||||
|
||||
ROM_REGION32_BE( 0x1000000, REGION_GFX2, 0 ) /* sprites */
|
||||
ROM_LOAD64_WORD( "epr15022.bin", 0x000000, 0x200000, CRC(09ca9608) SHA1(cbd0138c1c7811d42b051fed6a7e3526cc4e457f) )
|
||||
ROM_LOAD64_WORD( "epr15024.bin", 0x000002, 0x200000, CRC(0dc920eb) SHA1(d24d637aa0dcd3bae779ef7e12663df81667dbf7) )
|
||||
ROM_LOAD64_WORD( "epr15026.bin", 0x000004, 0x200000, CRC(67637c37) SHA1(7c250e7e9dd5c07da4fa35bacdfcecd5e8fa4ec7) )
|
||||
ROM_LOAD64_WORD( "epr15028.bin", 0x000006, 0x200000, CRC(9929abdc) SHA1(34b6624ddd3a0aedec0a2b433643a37f745ec66d) )
|
||||
ROM_LOAD64_WORD( "epr15023.bin", 0x800000, 0x200000, CRC(0e42a2bb) SHA1(503214caf5fa9a2324b61e04f378fd1a790322df) )
|
||||
ROM_LOAD64_WORD( "epr15025.bin", 0x800002, 0x200000, CRC(0c677fc6) SHA1(fc2207008417072e7ee91f722797d827e150ce2d) )
|
||||
ROM_LOAD64_WORD( "epr15027.bin", 0x800004, 0x200000, CRC(d6d077f9) SHA1(928cefae9ae58239fbffb1dcee282c6ac1e661fe) )
|
||||
ROM_LOAD64_WORD( "epr15029.bin", 0x800006, 0x200000, CRC(707af749) SHA1(fae5325c983df3cf198878220ad88d47339ac512) )
|
||||
|
||||
ROM_REGION( 0x400000, REGION_SOUND1, 0 ) /* Sega PCM sound data */
|
||||
ROM_LOAD("epr15031.bin", 0x000000, 0x200000, CRC(663a7fd2) SHA1(b4393a687225b075db21960d19a6ddd7a9d7d086) )
|
||||
ROM_LOAD("epr15032.bin", 0x200000, 0x200000, CRC(cb709f3d) SHA1(3962c8b5907d1f8f611f58ddac693cc47364a79c) )
|
||||
ROM_START( scrossu )
|
||||
ROM_REGION( 0x200000, REGION_CPU1, 0 ) /* v60 code + data */
|
||||
ROM_LOAD32_WORD_x2( "epr-15091.ic37", 0x000000, 0x040000, CRC(2c572293) SHA1(6377a6eb6084f7332ce6eeaaf0c37200da792d0c) )
|
||||
ROM_LOAD32_WORD_x2( "epr-15092.ic40", 0x000002, 0x040000, CRC(6e3e175a) SHA1(feaca0720646e2a4b78b376e99dc86788adb98e7) )
|
||||
ROM_LOAD32_WORD( "mpr-15018.ic36", 0x100000, 0x080000, CRC(3a98385e) SHA1(8088d337655030c28e290da4bbf44cb647dab66c) )
|
||||
ROM_LOAD32_WORD( "mpr-15019.ic39", 0x100002, 0x080000, CRC(8bf4ac83) SHA1(e594d9d9b42d0765ed8a20a40b7dd92b75124d34) )
|
||||
SCROSS_COMMON_ROMS
|
||||
ROM_END
|
||||
|
||||
ROM_START( titlef )
|
||||
@@ -3538,7 +3573,7 @@ static READ16_HANDLER( dual_pcb_masterslave )
|
||||
return 0; /* 0/1 master/slave */
|
||||
}
|
||||
|
||||
static DRIVER_INIT ( f1sl )
|
||||
static DRIVER_INIT ( f1lap )
|
||||
{
|
||||
install_io_analog();
|
||||
|
||||
@@ -3547,6 +3582,8 @@ static DRIVER_INIT ( f1sl )
|
||||
install_mem_write16_handler(0, 0x800000, 0x800fff, dual_pcb_comms_w);
|
||||
install_mem_read16_handler (0, 0x801000, 0x801003, dual_pcb_masterslave);
|
||||
system32_prot_vblank = f1lap_fd1149_vblank;
|
||||
|
||||
f1lap_kludge = true;
|
||||
}
|
||||
|
||||
static DRIVER_INIT ( arf )
|
||||
@@ -3675,6 +3712,7 @@ static DRIVER_INIT( titlef )
|
||||
{
|
||||
install_port_write_handler(1, 0xb0, 0xbf, scross_bank_w);
|
||||
titlef_kludge = true;
|
||||
opaquey_hack = true;
|
||||
}
|
||||
|
||||
static DRIVER_INIT( scross )
|
||||
@@ -3703,8 +3741,8 @@ GAMEX(1994, jpark, 0, system32, jpark, jpark, ROT0, "Sega",
|
||||
GAMEX(1994, svf, 0, system32, svf, 0, ROT0, "Sega", "Super Visual Football - European Sega Cup", GAME_IMPERFECT_GRAPHICS )
|
||||
GAMEX(1994, svs, svf, system32, svf, 0, ROT0, "Sega", "Super Visual Soccer - Sega Cup (US)", GAME_IMPERFECT_GRAPHICS )
|
||||
GAMEX(1994, jleague, svf, system32, svf, jleague, ROT0, "Sega", "The J.League 1994 (Japan)", GAME_IMPERFECT_GRAPHICS )
|
||||
GAMEX(1993, f1lap, 0, system32, f1lap, f1sl, ROT0, "Sega", "F1 Super Lap (World)", GAME_IMPERFECT_GRAPHICS )
|
||||
GAMEX(1993, f1lapj, f1lap, system32, f1lap, f1sl, ROT0, "Sega", "F1 Super Lap (Japan)", GAME_IMPERFECT_GRAPHICS )
|
||||
GAMEX(1993, f1lap, 0, system32, f1lap, f1lap, ROT0, "Sega", "F1 Super Lap (World)", GAME_IMPERFECT_GRAPHICS )
|
||||
GAMEX(1993, f1lapj, f1lap, system32, f1lap, f1lap, ROT0, "Sega", "F1 Super Lap (Japan)", GAME_IMPERFECT_GRAPHICS )
|
||||
GAMEX(1993, darkedge, 0, system32, darkedge, darkedge, ROT0, "Sega", "Dark Edge", GAME_IMPERFECT_GRAPHICS )
|
||||
GAMEX(1994, dbzvrvs, 0, system32, system32, dbzvrvs, ROT0, "Sega / Banpresto", "Dragon Ball Z V.R.V.S.", GAME_IMPERFECT_GRAPHICS )
|
||||
GAMEX(1995, slipstrm, 0, system32, slipstrm, slipstrm, ROT0, "Capcom", "Slipstream (Brazil)", GAME_IMPERFECT_GRAPHICS )
|
||||
@@ -3715,4 +3753,6 @@ GAMEX(1992, orunners, 0, multi32, orunners, 0, ROT0, "Sega",
|
||||
GAMEX(1994, harddunk, 0, multi32, harddunk, 0, ROT0, "Sega", "Hard Dunk (World)", GAME_IMPERFECT_GRAPHICS )
|
||||
GAMEX(1994, harddunj, harddunk, multi32, harddunk, 0, ROT0, "Sega", "Hard Dunk (Japan)", GAME_IMPERFECT_GRAPHICS )
|
||||
GAMEX(1992, scross, 0, multi32, scross, scross, ROT0, "Sega", "Stadium Cross (World)", GAME_IMPERFECT_GRAPHICS )
|
||||
GAMEX(1992, scrossa, scross, multi32, scross, scross, ROT0, "Sega", "Stadium Cross (World, linkable)", GAME_IMPERFECT_GRAPHICS )
|
||||
GAMEX(1992, scrossu, scross, multi32, scross, scross, ROT0, "Sega", "Stadium Cross (US)", GAME_IMPERFECT_GRAPHICS )
|
||||
GAMEX(1992, titlef, 0, multi32, titlef, titlef, ROT0, "Sega", "Title Fight (World)", GAME_IMPERFECT_GRAPHICS )
|
||||
+18
-3
@@ -9,6 +9,7 @@ [email protected]
|
||||
***************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "state.h"
|
||||
#include "vidhrdw/generic.h"
|
||||
#include "cpu/konami/konami.h" /* for the callback and the firq irq definition */
|
||||
#include "cpu/z80/z80.h"
|
||||
@@ -29,6 +30,7 @@ READ_HANDLER( simpsons_speedup1_r );
|
||||
READ_HANDLER( simpsons_speedup2_r );
|
||||
MACHINE_INIT( simpsons );
|
||||
NVRAM_HANDLER( simpsons );
|
||||
void simpsons_state_register(void);
|
||||
extern int simpsons_firq_enabled;
|
||||
|
||||
/***************************************************************************
|
||||
@@ -72,15 +74,22 @@ static MEMORY_WRITE_START( writemem )
|
||||
{ 0x8000, 0xffff, MWA_ROM },
|
||||
MEMORY_END
|
||||
|
||||
static WRITE_HANDLER( z80_bankswitch_w )
|
||||
int simpsons_z80_bank = 2; /* sound CPU bank register, kept for save states */
|
||||
|
||||
static void z80_bank_set(void)
|
||||
{
|
||||
unsigned char *RAM = memory_region(REGION_CPU2);
|
||||
|
||||
offset = 0x10000 + ( ( ( data & 7 ) - 2 ) * 0x4000 );
|
||||
int offset = 0x10000 + ( ( ( simpsons_z80_bank & 7 ) - 2 ) * 0x4000 );
|
||||
|
||||
cpu_setbank( 2, &RAM[ offset ] );
|
||||
}
|
||||
|
||||
static WRITE_HANDLER( z80_bankswitch_w )
|
||||
{
|
||||
simpsons_z80_bank = data;
|
||||
z80_bank_set();
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int nmi_enabled;
|
||||
|
||||
@@ -468,6 +477,12 @@ static DRIVER_INIT( simpsons )
|
||||
{
|
||||
konami_rom_deinterleave_2(REGION_GFX1);
|
||||
konami_rom_deinterleave_4(REGION_GFX2);
|
||||
|
||||
/* Save the bank selections so a loaded save state runs the right code */
|
||||
simpsons_z80_bank = 2;
|
||||
state_save_register_int("simpsons_z80", 0, "bank", &simpsons_z80_bank);
|
||||
state_save_register_func_postload(z80_bank_set);
|
||||
simpsons_state_register();
|
||||
}
|
||||
|
||||
GAME( 1991, simpsons, 0, simpsons, simpsons, simpsons, ROT0, "Konami", "The Simpsons (4 Players)" )
|
||||
|
||||
Loaded 100 of 289 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user