summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/cps3.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/cps3.c')
-rw-r--r--src/mame/drivers/cps3.c3286
1 files changed, 3286 insertions, 0 deletions
diff --git a/src/mame/drivers/cps3.c b/src/mame/drivers/cps3.c
new file mode 100644
index 00000000000..7a04db588c9
--- /dev/null
+++ b/src/mame/drivers/cps3.c
@@ -0,0 +1,3286 @@
+/*
+
+CPS3 Driver (preliminary)
+
+Decryption by Andreas Naive
+
+Driver by David Haywood
+ with help from Tomasz Slanina and ElSemi
+
+Sound emulation by Philip Bennett
+
+SCSI code by ElSemi
+
+ToDo: (in order or priority?)
+
+There are currently a bunch of hacks in here to workaround the way the encryption works on the actual
+PCB. It seems that the SH2 DMA should bypass the encryption, returning values directly stored in the
+BIOS and/or flashROMs. Without modification to the CPU core this isn't possible. The hacks currently
+in the driver allow the Flash commands to be sent correctly from the BIOS rom (they're stored
+unencrypted) and allow the Flash type and Rom checksums to pass, needed for the flash routines.
+
+The SCSI / CD Rom controller code here is limited, it's designed for the needs of CPS3 only, we should
+fix MAME's generic implementation and use that.
+
+Street Fighter 3 2nd Impact uses flipped tilemaps during flashing, emulate this.
+
+Figure out proper IRQ10 generation:
+ If we generate on DMA operations only then Warzard is OK, otherwise it hangs during attract
+ HOWEVER, SFIII2 sometimes has messed up character profiles unless we also generate it periodicly.
+ I think the corrupt background on some of the lighning effects may be realted to this + the DMA
+ status flags.
+
+Alpha Blending Effects
+ These are actually palette manipulation effects, not true blending. How the values are used is
+ not currently 100% understood, however it seems good enough for Warzard etc. at the moment.
+
+Linezoom
+ Is it used anywhere??
+
+Palette DMA effects
+ Verify them, they might not be 100% accurate at the moment
+
+Verify Full Screen Zoom on real hardware
+ Which is which, x & y registers, how far can it zoom etc.
+
+Verify CRT registers
+ Only SFIII2 changes them, for widescreen mode. What other modes are possible?
+
+Sprite positioning glitches
+ Some sprites are still in the wrong places, seems the placement of zooming sprites is imperfect
+ eg. warzard intro + cutscenes leave the left most 16 pixels uncovered because the sprite is positioned incorrectly,
+ the same occurs in the sf games. doesn't look like the origin is correct when zooming in all cases.
+
+Gaps in Sprite Zooming
+ probably cause by use of drawgfx instead of processing as a single large sprite, but could also be due to the
+ positioning of each part of the sprite.
+
+---
+
+Capcom CP SYSTEM III Hardware Overview
+Capcom, 1996-1999
+
+From late 1996 to 1999 Capcom developed another hardware platform to rival the CPS2 System and called
+it CP SYSTEM III. Only 6 games were produced....
+
+Game Date S/W Rev CD Part# Label Cart Part#
+----------------------------------------------------------------------------------------------------------------
+JoJo no Kimyouna Bouken / JoJo's Venture 1998 98/12/02 CAP-JJK000 CAP-JJK-140 JJK98c00F
+ 99/01/08 CAP-JJK-160
+ 99/01/28 **
+JoJo no Kimyouna Bouken Miraie no Isan
+/ JoJo's Bizarre Adventure Heritage for the Future 1999 99/09/13 CAP-JJM000 CAP-JJM-110 JJM99900F
+ 99/09/27 **
+
+Street Fighter III New Generation 1997 97/02/04 CAP-SF3000 CAP-SF3-3 SF397200F
+
+Street Fighter III 2nd Impact Giant Attack 1997 97/09/30 CAP-3GA000 CAP-3GA-1 3GA97a00F
+
+Street Fighter III 3rd Strike Fight for the Future 1999 99/05/12 CAP-33S000 CAP-33S-1 33S99400F
+ 99/06/08 CAP-33S-2
+
+Warzard / Red Earth 1996 96/11/21 CAP-WZD000 CAP-WZD-5 WZD96a00F
+
+** NOT DUMPED but known to exist
+
+The Game Region / No CD Flags / Development flags etc. are controlled by a byte in the bios roms. The CDs
+contain revisions of the game code and are independant of the region.
+
+The CP SYSTEM III comprises a main board with several custom ASICs, custom 72-pin SIMMs for program
+and graphics storage (the same SIMMs are also used in some CPS2 titles), SCSI CDROM and CDROM disc,
+and a plug-in security cart containing a boot ROM, an NVRAM and another custom ASIC containing vital
+decryption information held by a [suicide] battery.
+
+Not much is known about the actual CPU used in this system due to the extensive use of encryption,
+and the volatile nature of the security information. There appears to be a custom Hitachi SH-2
+CPU on the mainboard and there has been confirmed to be one in the cart. Tests were done by decrypting
+the BIOS and code and running it on the PCB. It is known that neither of these CPU's will run standard
+(i.e. unencrypted) SH2 code.
+
+The security cart is thought to work like this.... the flashROM in the cart contains a program BIOS which is
+decrypted by the CPU in the cart (the CPU has built-in decryption) then executed by that CPU to boot the BIOS
+code. Even though the code in the flashROM is encrypted, the cart can run it even if it is dead/suicided because
+it has been discovered that the BIOS contains a hidden security menu allowing the cart to be loaded with the
+security data. This proves the cart runs the BIOS even if it is dead. The special security menu is not
+normally available but is likely accessed with a special key/button combination which is unknown ATM.
+The cart contains a FM1208S NVRAM which appears to either be unused or holds game settings. Because the CPU
+in the cart is always powered by a battery, it has stealth capability that allows it to continually monitor
+the situation. If the custom CPU detects any tampering (generally things such as voltage fluctuation or
+voltage dropping or even removal of the cart with the power on), it immediately erases the SRAM inside the
+CPU (and thus the key) which effectively kills the security cart dead. This also suggests that the custom
+Capcom CPU contains some additional internal code to initiate the boot process which is battery-backed
+as well. It is known (from decapping it) that the CPU in the security cart does contain an amount of static
+RAM for data storage and a SH2 core.
+
+The main board uses the familiar Capcom SIMM modules to hold the data from the CDROM so that the life of
+the CD drive is maximized. The SIMMs don't contain RAM, but instead TSOP48 surface mounted flashROMs
+that can be updated with different games on bootup using a built-in software updating system.
+The SIMMs that hold the program code are located in positions 1 & 2 and are 64MBit.
+The SIMMs that hold the graphics are located in positions 3, 4, 5, 6 & 7 and are 128MBit.
+The data in the SIMMs is not decrypted, it is merely taken directly from the CDROM and shuffled slightly
+then programmed to the flashROMs. The SIMMs hold the entire contents of the CDROM.
+
+To swap games requires the security cart for the game, it's CDROM disc and the correctly populated type
+and number of SIMMs on the main board.
+On first power-up after switching the cart and CD, you're presented with a screen asking if you want to
+re-program the SIMMs with the new game. Pressing player 1 button 2 cancels it. Pressing player 1 button 1
+allows it to proceed whereby you wait about 25 minutes then the game boots up almost immediately. On
+subsequent power-ups, the game boots immediately.
+If the CDROM is not present in the drive on a normal bootup, a message tells you to insert the CDROM.
+Then you press button 1 to continue and the game boots immediately.
+Note that not all of the SIMMs are populated on the PCB for each game. Some games have more, some less,
+depending on game requirements, so flash times can vary per game. See the table below for details.
+
+ |----------- Required SIMM Locations & Types -----------|
+Game 1 2 3 4 5 6 7
+--------------------------------------------------------------------------------------------------------------
+JoJo's Venture 64MBit 64MBit 128MBit 128MBit 32MBit - -
+JoJo's Bizarre Adventure 64MBit 64MBit 128MBit 128MBit 128MBit - -
+Street Fighter III New Generation 64MBit - 128MBit 128MBit 32MBit* - -
+Street Fighter III 2nd Impact Giant Attack 64MBit 64MBit 128MBit 128MBit 128MBit - -
+Street Fighter III 3rd Strike Fight for the Future 64MBit 64MBit 128MBit 128MBit 128MBit 128MBit -
+Warzard / Red Earth 64MBit - 128MBit 128MBit 32MBit* - -
+
+ Notes:
+ - denotes not populated
+ * 32MBit SIMMs have only 2 FlashROMs populated on them.
+ 128MBit SIMMs can also be used.
+ No game uses a SIMM at 7
+ See main board diagram below for SIMM locations.
+
+Due to the built-in upgradability of the hardware, and the higher frame-rates the hardware seems to have,
+it appears Capcom had big plans for this system and possibly intended to create many games on it, as they
+did with CPS2. Unfortunately for Capcom, CP SYSTEM III was an absolute flop in the arcades so those plans
+were cancelled. Possible reasons include...
+- The games were essentially just 2D, and already there were many 3D games coming out onto the market that
+ interested operators more than this.
+- The cost of the system was quite expensive when compared to other games on the market.
+- It is rumoured that the system was difficult to program for developers.
+- These PCBs were not popular with operators because the security carts are extremely static-sensitive and most
+ of them failed due to the decryption information being zapped by simple handling of the PCBs or by touching
+ the security cart edge connector underneath the PCB while the security cart was plugged in, or by power
+ fluctuations while flashing the SIMMs. You will know if your cart has been zapped because on bootup, you get
+ a screen full of garbage coloured pixels instead of the game booting up, or just a black or single-coloured
+ screen. You should also not touch the inside of the security cart because it will be immediately zapped
+ when you touch it! The PCB can detect the presence of the security cart and if it is removed on a working game,
+ the game will freeze immediately and it will also erase the security cart battery-backed data.
+
+
+PCB Layouts
+-----------
+
+CAPCOM
+CP SYSTEMIII
+95682A-4 (older rev 95682A-3)
+ |----------------------------------------------------------------------|
+ |= J1 HM514260 |------------| | | | | | |
+ | |CAPCOM | | | | | | |
+ |= J2 TA8201 TC5118160 |DL-2729 PPU | | | | | | |
+ | |(QFP304) | | | | | | |
+|--| VOL TC5118160 | | | | | | | |
+| LM833N | | S S S S S |
+| LM833N TC5118160 |------------| I I I I I |
+| TDA1306T |--------| M M M M M |
+| TC5118160 60MHz |CAPCOM | M M M M M |-|
+| 42.9545MHz |DL-3329 | 7 6 5 4 3 | |
+| LM385 |SSU | | | | | | | |
+|J KM681002 |--------| | | | | | | |
+|A KM681002 62256 |-------| | | | | | | |
+|M |DL3529 | | | | | | | |
+|M MC44200FU |GLL2 | | | | | | | |
+|A 3.6864MHz |-------| CN6| |
+| | | | |
+| |--------| |-| | | | |
+| |CAPCOM | | | |-------| | | | |
+| TD62064 |DL-2929 | | | |CAPCOM | | | | |
+| |IOU | | | |DL-3429| | | | |
+| TD62064 |--------| | | |GLL1 | S S | |
+|--| *HA16103FPJ | | |-------| I I |-|
+ | | |CN5 M M |
+ | | | |-------| M M |
+ |-| 93C46 | | |CAPCOM | 2 1 |
+ | | PS2501 | | |DL-2829| | | |-----||
+ | |CN1 | | |CCU | | | |AMD ||
+ | | PS2501 | | |-------| | | |33C93||
+ |-| |-| | | |-----||
+ | SW1 HM514260 | | |
+ |----------------------------------------------------------------------|
+Notes:
+ TA8201 - Toshiba TA8201 18W BTL x 2-Channel Audio Power Amplifier
+ PS2501 - NEC PS2501 High Isolation Voltage Single Transistor Type Multi Photocoupler (DIP16)
+ TDA1306T - Philips TDA1306T Noise Shaping Filter DAC (SOIC24). The clock (on pin 12) measures
+ 14.3181667MHz (42.9545/3)
+ MC44200FU - Motorola MC44200FU Triple 8-bit Video DAC (QFP44)
+ LM833N - ST Microelectronics LM833N Low Noise Audio Dual Op-Amp (DIP8)
+ TD62064 - Toshiba TD62064AP NPN 50V 1.5A Quad Darlington Driver (DIP16)
+ HA16103FPJ - Hitachi HA16103FPJ Watchdog Timer (SOIC20)
+ *Note this IC is not populated on the rev -4 board
+ 93C46 - National Semiconductor NM93C46A 128bytes x8 Serial EEPROM (SOIC8)
+ Note this IC is covered by a plastic housing on the PCB. The chip is just a normal
+ (unsecured) EEPROM so why it was covered is not known.
+ LM385 - National Semiconductor LM385 Adjustable Micropower Voltage Reference Diode (SOIC8)
+ 33C93 - AMD 33C93A-16 SCSI Controller (PLCC44)
+ KM681002 - Samsung Electronics KM681002 128k x8 SRAM (SOJ32)
+ 62256 - 8k x8 SRAM (SOJ28)
+ HM514260 - Hitachi HM514260CJ7 1M x16 DRAM (SOJ42)
+ TC5118160 - Toshiba TC5118160BJ-60 256k x16 DRAM (SOJ42)
+ SW1 - Push-button Test Switch
+ VOL - Master Volume Potentiometer
+ J1/J2 - Optional RCA Left/Right Audio Out Connectors
+ CN1 - 34-Pin Capcom Kick Button Harness Connector
+ CN5 - Security Cartridge Slot
+ CN6 - 4-Pin Power Connector and 50-pin SCSI Data Cable Connector
+ CDROM Drive is a CR504-KCM 4X SCSI drive manufactured By Panasonic / Matsushita
+ SIMM 1-2 - 72-Pin SIMM Connector, holds single sided SIMMs containing 4x Fujitsu 29F016A
+ surface mounted TSOP48 FlashROMs
+ SIMM 3-7 - 72-Pin SIMM Connector, holds double sided SIMMs containing 8x Fujitsu 29F016A
+ surface mounted TSOP48 FlashROMs
+
+ SIMM Layout -
+ |----------------------------------------------------|
+ | |
+ | |-------| |-------| |-------| |-------| |
+ | |Flash_A| |Flash_B| |Flash_C| |Flash_D| |
+ | |-------| |-------| |-------| |-------| |
+ |- |
+ |-------------------------/\------------------------|
+ Notes:
+ For SIMMs 1-2, Flash_A & Flash_C and regular pinout (Fujitsu 29F016A-90PFTN)
+ Flash_B & Flash_D are reverse pinout (Fujitsu 29F016A-90PFTR)
+ and are mounted upside down also so that pin1 lines up with
+ the normal pinout of FlashROMs A & C.
+ For SIMMs 3-7, the 8 FlashROMs are populated on both sides using a similar layout.
+
+ Capcom Custom ASICs -
+ DL-2729 PPU SD10-505 (QFP304). Decapping reveals this is the main graphics chip.
+ DL-2829 CCU SD07-1514 (QFP208). Decapping reveals this to be a custom Toshiba ASIC.
+ DL-2929 IOU SD08-1513 (QFP208). This is the I/O controller.
+ DL-3329 SSU SD04-1536 (QFP144). This is might be the main CPU. It appears to be a SH2
+ variant with built-in encryption. It is clocked at
+ 21.47725MHz (42.9545/2)
+ DL-3429 GLL1 SD06-1537 (QFP144). Unknown, possibly a DMA or bus controller.
+ DL-3529 GLL2 SD11-1755 (QFP80). This might be the sound chip (it has 32k SRAM connected to it).
+
+
+Connector Pinouts
+-----------------
+
+ JAMMA Connector Extra Button Connector
+ --------------- ----------------------
+ PART SIDE SOLDER SIDE TOP BOTTOM
+ ---------------------------- --------------------------
+ GND 01 A GND GND 01 02 GND
+ GND 02 B GND +5V 03 04 +5V
+ +5V 03 C +5V +12V 05 06 +12V
+ +5V 04 D +5V 07 08
+ NC 05 E NC Player 2 Button 4 09 10
+ +12V 06 F +12V 11 12
+ 07 H 13 14
+ Coin Counter 1 08 J NC Player 1 Button 4 15 16
+ Coin Lockout 09 K Coin Lockout Player 1 Button 5 17 18
+ Speaker (+) 10 L Speaker (-) Player 1 Button 6 19 20
+ NC 11 M NC Player 2 Button 5 21 22
+ Video Red 12 N Video Green Player 2 Button 6 23 24
+ Video Blue 13 P Video Composite Sync 25 26
+ Video Ground 14 R Service Switch 27 28
+ Test 15 S NC Volume Down 29 30 Volume UP
+ Coin A 16 T Coin B GND 31 32 GND
+ Player 1 Start 17 U Player 2 Start GND 33 34 GND
+ Player 1 Up 18 V Player 2 Up
+ Player 1 Down 19 W Player 2 Down
+ Player 1 Left 20 X Player 2 Left
+ Player 1 Right 21 Y Player 2 Right
+ Player 1 Button 1 22 Z Player 2 Button 1
+ Player 1 Button 2 23 a Player 2 Button 2
+ Player 1 Button 3 24 b Player 2 Button 3
+ NC 25 c NC
+ NC 26 d NC
+ GND 27 e GND
+ GND 28 f GND
+
+
+Security Cartridge PCB Layout
+-----------------------------
+
+CAPCOM 95682B-3 TORNADE
+|------------------------------------------------|
+| BATTERY |
+| |-------| |
+| |CAPCOM | 29F400 |
+| |DL-3229| *28F400 |
+| |SCU | *FM1208S|
+| 74HC00 |-------| |
+| 6.25MHz 74F00 |
+|---| |-| |------|
+ | | | |
+ |-----| |-----------------------------|
+Notes:
+ 74F00 - 74F00 Quad 2-Input NAND Gate (SOIC14)
+ 74HC00 - Philips 74HC00N Quad 2-Input NAND Gate (DIP14)
+ 29F400 - Fujitsu 29F400TA-90PFTN 512k x8 FlashROM (TSOP48)
+ Custom ASIC - CAPCOM DL-3229 SCU (QFP144). Decapping reveals this is a Hitachi HD6417099 SH2 variant
+ with built-in encryption, clocked at 6.250MHz
+ FM1208S - RAMTRON FM1208S 4k (512bytes x8) Nonvolatile Ferroelectric RAM (SOIC24)
+ 28F400 - 28F400 SOP44 FlashROM (not populated)
+ * - These components located on the other side of the PCB
+ The battery powers the CPU only. A small board containing some transistors is wired to the 74HC00
+ to switch the CPU from battery power to main power to increase the life of the battery.
+
+*/
+
+#include "driver.h"
+#include "cdrom.h"
+#include "cpu/sh2/sh2.h"
+#include "machine/intelfsh.h"
+#include "includes/cps3.h"
+#include "machine/wd33c93.h"
+
+/* load extracted cd content? */
+#define LOAD_CD_CONTENT 1
+#define DEBUG_PRINTF 0
+
+#ifdef LSB_FIRST
+ #define DMA_XOR(a) ((a) ^ 1)
+#else
+ #define DMA_XOR(a) ((a) ^ 2)
+#endif
+
+static int cps3_use_fastboot;
+
+static UINT32* decrypted_bios;
+static UINT32* decrypted_gamerom;
+static UINT32 cram_gfxflash_bank;
+static UINT32* cps3_nops;
+
+static UINT32* tilemap20_regs_base;
+static UINT32* tilemap30_regs_base;
+static UINT32* tilemap40_regs_base;
+static UINT32* tilemap50_regs_base;
+
+static UINT32* cps3_0xc0000000_ram;
+static UINT32* cps3_0xc0000000_ram_decrypted;
+
+static UINT32* cps3_char_ram;
+
+static UINT32* cps3_spriteram;
+static UINT32* cps3_eeprom;
+static UINT32* cps3_fullscreenzoom;
+
+UINT32 cps3_ss_pal_base = 0;
+static UINT32* cps3_colourram;
+static UINT32 cps3_unk_vidregs[0x20/4];
+UINT32 cps3_ss_bank_base = 0;
+
+static UINT32 cps3_screenwidth;
+//cdrom_file* cps3_cd;
+
+static UINT32* cps3_mame_colours;//[0x20000]; // actual values to write to 32-bit bitmap
+
+static mame_bitmap *renderbuffer_bitmap;
+static rectangle renderbuffer_clip;
+
+
+#define CPS3_TRANSPARENCY_NONE 0
+#define CPS3_TRANSPARENCY_PEN 1
+#define CPS3_TRANSPARENCY_PEN_INDEX 2
+#define CPS3_TRANSPARENCY_PEN_INDEX_BLEND 3
+
+INLINE void cps3_drawgfxzoom( mame_bitmap *dest_bmp,const gfx_element *gfx,
+ unsigned int code,unsigned int color,int flipx,int flipy,int sx,int sy,
+ const rectangle *clip,int transparency,int transparent_color,
+ int scalex, int scaley,mame_bitmap *pri_buffer,UINT32 pri_mask)
+{
+ rectangle myclip;
+
+// UINT8 al;
+
+// al = (pdrawgfx_shadow_lowpri) ? 0 : 0x80;
+
+ if (!scalex || !scaley) return;
+
+// todo: reimplement this optimization!!
+// if (scalex == 0x10000 && scaley == 0x10000)
+// {
+// common_drawgfx(dest_bmp,gfx,code,color,flipx,flipy,sx,sy,clip,transparency,transparent_color,pri_buffer,pri_mask);
+// return;
+// }
+
+ /*
+ scalex and scaley are 16.16 fixed point numbers
+ 1<<15 : shrink to 50%
+ 1<<16 : uniform scale
+ 1<<17 : double to 200%
+ */
+
+
+ /* force clip to bitmap boundary */
+ if(clip)
+ {
+ myclip.min_x = clip->min_x;
+ myclip.max_x = clip->max_x;
+ myclip.min_y = clip->min_y;
+ myclip.max_y = clip->max_y;
+
+ if (myclip.min_x < 0) myclip.min_x = 0;
+ if (myclip.max_x >= dest_bmp->width) myclip.max_x = dest_bmp->width-1;
+ if (myclip.min_y < 0) myclip.min_y = 0;
+ if (myclip.max_y >= dest_bmp->height) myclip.max_y = dest_bmp->height-1;
+
+ clip=&myclip;
+ }
+
+
+ /* 32-bit ONLY */
+ {
+ if( gfx )
+ {
+// const pen_t *pal = &gfx->colortable[gfx->color_granularity * (color % gfx->total_colors)];
+ UINT32 palbase = (gfx->color_granularity * color) & 0x1ffff;
+ const pen_t *pal = &cps3_mame_colours[palbase];
+ UINT8 *source_base = gfx->gfxdata + (code % gfx->total_elements) * gfx->char_modulo;
+
+ int sprite_screen_height = (scaley*gfx->height+0x8000)>>16;
+ int sprite_screen_width = (scalex*gfx->width+0x8000)>>16;
+
+ if (sprite_screen_width && sprite_screen_height)
+ {
+ /* compute sprite increment per screen pixel */
+ int dx = (gfx->width<<16)/sprite_screen_width;
+ int dy = (gfx->height<<16)/sprite_screen_height;
+
+ int ex = sx+sprite_screen_width;
+ int ey = sy+sprite_screen_height;
+
+ int x_index_base;
+ int y_index;
+
+ if( flipx )
+ {
+ x_index_base = (sprite_screen_width-1)*dx;
+ dx = -dx;
+ }
+ else
+ {
+ x_index_base = 0;
+ }
+
+ if( flipy )
+ {
+ y_index = (sprite_screen_height-1)*dy;
+ dy = -dy;
+ }
+ else
+ {
+ y_index = 0;
+ }
+
+ if( clip )
+ {
+ if( sx < clip->min_x)
+ { /* clip left */
+ int pixels = clip->min_x-sx;
+ sx += pixels;
+ x_index_base += pixels*dx;
+ }
+ if( sy < clip->min_y )
+ { /* clip top */
+ int pixels = clip->min_y-sy;
+ sy += pixels;
+ y_index += pixels*dy;
+ }
+ if( ex > clip->max_x+1 )
+ { /* clip right */
+ int pixels = ex-clip->max_x-1;
+ ex -= pixels;
+ }
+ if( ey > clip->max_y+1 )
+ { /* clip bottom */
+ int pixels = ey-clip->max_y-1;
+ ey -= pixels;
+ }
+ }
+
+ if( ex>sx )
+ { /* skip if inner loop doesn't draw anything */
+ int y;
+
+ /* case 0: TRANSPARENCY_NONE */
+ if (transparency == CPS3_TRANSPARENCY_NONE)
+ {
+ {
+ for( y=sy; y<ey; y++ )
+ {
+ UINT8 *source = source_base + (y_index>>16) * gfx->line_modulo;
+ UINT32 *dest = BITMAP_ADDR32(dest_bmp, y, 0);
+
+ int x, x_index = x_index_base;
+ for( x=sx; x<ex; x++ )
+ {
+ dest[x] = pal[source[x_index>>16]];
+ x_index += dx;
+ }
+
+ y_index += dy;
+ }
+ }
+ }
+ else if (transparency == CPS3_TRANSPARENCY_PEN)
+ {
+ {
+ for( y=sy; y<ey; y++ )
+ {
+ UINT8 *source = source_base + (y_index>>16) * gfx->line_modulo;
+ UINT32 *dest = BITMAP_ADDR32(dest_bmp, y, 0);
+
+ int x, x_index = x_index_base;
+ for( x=sx; x<ex; x++ )
+ {
+ int c = source[x_index>>16];
+ if( c != transparent_color ) dest[x] = pal[c];
+ x_index += dx;
+ }
+
+ y_index += dy;
+ }
+ }
+ }
+ else if (transparency == CPS3_TRANSPARENCY_PEN_INDEX)
+ {
+ {
+ for( y=sy; y<ey; y++ )
+ {
+ UINT8 *source = source_base + (y_index>>16) * gfx->line_modulo;
+ UINT32 *dest = BITMAP_ADDR32(dest_bmp, y, 0);
+
+ int x, x_index = x_index_base;
+ for( x=sx; x<ex; x++ )
+ {
+ int c = source[x_index>>16];
+ if( c != transparent_color ) dest[x] = c | palbase;
+ x_index += dx;
+ }
+
+ y_index += dy;
+ }
+ }
+ }
+ else if (transparency == CPS3_TRANSPARENCY_PEN_INDEX_BLEND)
+ {
+ {
+ for( y=sy; y<ey; y++ )
+ {
+ UINT8 *source = source_base + (y_index>>16) * gfx->line_modulo;
+ UINT32 *dest = BITMAP_ADDR32(dest_bmp, y, 0);
+
+ int x, x_index = x_index_base;
+ for( x=sx; x<ex; x++ )
+ {
+ int c = source[x_index>>16];
+ if( c != transparent_color )
+ {
+ /* blending isn't 100% understood */
+ if (gfx->color_granularity == 64)
+ {
+ // OK for sfiii2 spotlight
+ if (c&0x01) dest[x] |= 0x2000;
+ if (c&0x02) dest[x] |= 0x4000;
+ if (c&0x04) dest[x] |= 0x8000;
+ if (c&0x08) dest[x] |= 0x10000;
+ if (c&0xf0) dest[x] |= mame_rand(Machine); // ?? not used?
+ }
+ else
+ {
+ // OK for jojo intro, and warzard swords, and various shadows in sf games
+ if (c&0x01) dest[x] |= 0x8000;
+ if (color&0x100) dest[x]|=0x10000;
+ }
+ }
+
+
+ x_index += dx;
+ }
+
+ y_index += dy;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+static offs_t cps3_opbase_handler(offs_t address);
+
+/* Encryption */
+
+static UINT32 cps3_key1, cps3_key2, cps3_isSpecial;
+
+static UINT16 rotate_left(UINT16 value, int n)
+{
+ int aux = value>>(16-n);
+ return ((value<<n)|aux)%0x10000;
+}
+
+static UINT16 rotxor(UINT16 val, UINT16 xor)
+{
+ UINT16 res;
+
+ res = val + rotate_left(val,2);
+
+ res = rotate_left(res,4) ^ (res & (val ^ xor));
+
+ return res;
+}
+
+static UINT32 cps3_mask(UINT32 address, UINT32 key1, UINT32 key2)
+{
+ UINT16 val;
+
+ address ^= key1;
+
+ val = (address & 0xffff) ^ 0xffff;
+
+ val = rotxor(val, key2 & 0xffff);
+
+ val ^= (address >> 16) ^ 0xffff;
+
+ val = rotxor(val, key2 >> 16);
+
+ val ^= (address & 0xffff) ^ (key2 & 0xffff);
+
+ return val | (val << 16);
+}
+
+struct game_keys2
+{
+ const char *name; /* game driver name */
+ const UINT32 keys[2];
+ int isSpecial;
+};
+
+static const struct game_keys2 keys_table2[] =
+{
+ // name key1 key2
+ { "jojo", { 0x02203ee3, 0x01301972 },0 },
+ { "jojon", { 0x02203ee3, 0x01301972 },0 },
+ { "jojoalt", { 0x02203ee3, 0x01301972 },0 },
+ { "jojoaltn", { 0x02203ee3, 0x01301972 },0 },
+ { "jojoba", { 0x23323ee3, 0x03021972 },0 },
+ { "jojoban", { 0x23323ee3, 0x03021972 },0 },
+ { "jojobane", { 0x23323ee3, 0x03021972 },0 },
+ { "sfiii", { 0xb5fe053e, 0xfc03925a },0 },
+ { "sfiiiu", { 0xb5fe053e, 0xfc03925a },0 },
+ { "sfiiin", { 0xb5fe053e, 0xfc03925a },0 },
+ { "sfiii2", { 0x00000000, 0x00000000 },1 },
+ { "sfiii2u", { 0x00000000, 0x00000000 },1 },
+ { "sfiii2n", { 0x00000000, 0x00000000 },1 },
+ { "sfiii3", { 0xa55432b4, 0x0c129981 },0 },
+ { "sfiii3n", { 0xa55432b4, 0x0c129981 },0 },
+ { "sfiii3a", { 0xa55432b4, 0x0c129981 },0 },
+ { "sfiii3an", { 0xa55432b4, 0x0c129981 },0 },
+ { "warzard", { 0x9e300ab1, 0xa175b82c },0 },
+ { "redearth", { 0x9e300ab1, 0xa175b82c },0 },
+ { 0 } // end of table
+};
+
+static void cps3_decrypt_bios(void)
+{
+ int i;
+ UINT32 *coderegion = (UINT32*)memory_region(REGION_USER1);
+
+ decrypted_bios = (UINT32*)memory_region(REGION_USER1);
+
+ for (i=0;i<0x80000;i+=4)
+ {
+ UINT32 dword = coderegion[i/4];
+ UINT32 xormask = cps3_mask(i, cps3_key1, cps3_key2);
+
+ /* a bit of a hack, don't decrypt the FLASH commands which are transfered by SH2 DMA */
+ if (((i<0x1ff00) || (i>0x1ff6b)) && (i<0x20000) )
+ {
+ decrypted_bios[i/4] = dword ^ xormask;
+ }
+ else
+ {
+ decrypted_bios[i/4] = dword;
+ }
+ }
+#if 0
+ /* Dump to file */
+ {
+ FILE *fp;
+ const char *gamename = Machine->gamedrv->name;
+ char filename[256];
+ sprintf(filename, "%s_bios.dump", gamename);
+
+ fp=fopen(filename, "w+b");
+ if (fp)
+ {
+ fwrite(decrypted_bios, 0x080000, 1, fp);
+ fclose(fp);
+ }
+ }
+#endif
+}
+
+
+
+
+static DRIVER_INIT( cps3crpt )
+{
+ const char *gamename = machine->gamedrv->name;
+ const struct game_keys2 *k = &keys_table2[0];
+ int i;
+
+ cps3_key1 = -1;
+ cps3_key2 = -1;
+ cps3_isSpecial = -1;
+
+ while (k->name)
+ {
+ if (strcmp(k->name, gamename) == 0)
+ {
+ // we have a proper key set the global variables to it (so that we can decrypt code in ram etc.)
+ cps3_key1 = k->keys[0];
+ cps3_key2 = k->keys[1];
+ cps3_isSpecial = k->isSpecial;
+ break;
+ }
+ ++k;
+ }
+
+ cps3_decrypt_bios();
+ decrypted_gamerom = auto_malloc(0x1000000);
+
+ /* just some NOPs for the game to execute if it crashes and starts executing unmapped addresses
+ - this prevents MAME from crashing */
+ cps3_nops = auto_malloc(0x4);
+ cps3_nops[0] = 0x00090009;
+
+
+ cps3_0xc0000000_ram_decrypted = auto_malloc(0x400);
+ memory_set_opbase_handler(0, cps3_opbase_handler);
+
+ // flash roms
+
+ for (i=0;i<48;i++)
+ intelflash_init( i, FLASH_FUJITSU_29F016A, NULL );
+
+ cps3_eeprom = auto_malloc(0x400);
+
+
+
+}
+
+/* GFX decodes */
+
+
+static const gfx_layout cps3_tiles16x16_layout =
+{
+ 16,16,
+ 0x8000,
+ 8,
+ { 0,1,2,3,4,5,6,7 },
+ { 3*8,2*8,1*8,0*8,7*8,6*8,5*8,4*8,
+ 11*8,10*8,9*8,8*8,15*8,14*8,13*8,12*8 },
+ { 0*128,1*128,2*128,3*128,4*128,5*128,6*128,7*128,8*128,9*128,10*128,11*128,12*128,13*128,14*128,15*128},
+ 8*256
+};
+
+
+
+static const gfx_layout cps3_tiles8x8_layout =
+{
+ 8,8,
+ 0x400,
+ 4,
+ { /*8,9,10,11,*/ 0,1,2,3 },
+ { 20,16,4,0,52,48,36,32 },
+
+ { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64 },
+ 64*8
+};
+
+static UINT32* cps3_ss_ram;
+static UINT8* cps3_ss_ram_dirty;
+static int cps3_ss_ram_is_dirty;
+
+static UINT8* cps3_char_ram_dirty;
+static int cps3_char_ram_is_dirty;
+
+static void cps3_set_mame_colours( int colournum, UINT16 data, UINT32 fadeval )
+{
+ int r,g,b;
+ UINT16* dst = (UINT16*)cps3_colourram;
+
+
+ r = (data >> 0) & 0x1f;
+ g = (data >> 5) & 0x1f;
+ b = (data >> 10) & 0x1f;
+
+ /* is this 100% correct? */
+ if (fadeval!=0)
+ {
+ int fade;
+ //printf("fadeval %08x\n",fadeval);
+
+ fade = (fadeval & 0x3f000000)>>24;
+ r = (r*fade)>>5;
+ if (r>0x1f) r = 0x1f;
+
+ fade = (fadeval & 0x003f0000)>>16;
+ g = (g*fade)>>5;
+ if (g>0x1f) g = 0x1f;
+
+ fade = (fadeval & 0x0000003f)>>0;
+ b = (b*fade)>>5;
+ if (b>0x1f) b = 0x1f;
+
+ data = (r <<0) | (g << 5) | (b << 10);
+ }
+
+ dst[colournum] = data;
+
+ cps3_mame_colours[colournum] = (r << (16+3)) | (g << (8+3)) | (b << (0+3));
+
+ if (colournum<0x10000) palette_set_color(Machine,colournum,cps3_mame_colours[colournum]/* MAKE_RGB(r<<3,g<<3,b<<3)*/);//cps3_mame_colours[colournum]);
+}
+
+#ifdef UNUSED_FUNCTION
+static void decode_ssram(void)
+{
+ if (cps3_ss_ram_dirty)
+ {
+ int i;
+ for (i=0;i<0x400;i++)
+ {
+ if (cps3_ss_ram_dirty[i])
+ {
+ decodechar(Machine->gfx[0], i, (UINT8*)cps3_ss_ram, &cps3_tiles8x8_layout);
+ cps3_ss_ram_dirty[i] = 0;
+ }
+ }
+
+ cps3_ss_ram_is_dirty = 0;
+ }
+
+ return;
+}
+
+static void decode_charram(void)
+{
+ if (cps3_char_ram_is_dirty)
+ {
+ int i;
+ for (i=0;i<0x8000;i++)
+ {
+ if (cps3_char_ram_dirty[i])
+ {
+ decodechar(Machine->gfx[1], i, (UINT8*)cps3_char_ram, &cps3_tiles16x16_layout);
+ cps3_char_ram_dirty[i] = 0;
+ }
+ }
+
+ cps3_char_ram_is_dirty = 0;
+ }
+
+ return;
+}
+#endif
+
+static VIDEO_START(cps3)
+{
+ cps3_ss_ram = auto_malloc(0x10000);
+ cps3_ss_ram_dirty = auto_malloc(0x400);
+ cps3_ss_ram_is_dirty = 1;
+ memset(cps3_ss_ram, 0x00, 0x10000);
+ memset(cps3_ss_ram_dirty, 1, 0x400);
+ state_save_register_global_pointer(cps3_ss_ram, 0x10000/4);
+
+ cps3_char_ram = auto_malloc(0x800000);
+ cps3_char_ram_dirty = auto_malloc(0x800000/256);
+ cps3_char_ram_is_dirty = 1;
+ memset(cps3_char_ram, 0x00, 0x800000);
+ memset(cps3_char_ram_dirty, 1, 0x8000);
+ state_save_register_global_pointer(cps3_char_ram, 0x800000 /4);
+
+ /* create the char set (gfx will then be updated dynamically from RAM) */
+ machine->gfx[0] = allocgfx(&cps3_tiles8x8_layout);
+ machine->gfx[0]->total_colors = machine->drv->total_colors / 16;
+
+ //decode_ssram();
+
+ /* create the char set (gfx will then be updated dynamically from RAM) */
+ machine->gfx[1] = allocgfx(&cps3_tiles16x16_layout);
+ machine->gfx[1]->total_colors = machine->drv->total_colors / 64;
+ machine->gfx[1]->color_granularity=64;
+
+ //decode_charram();
+
+ cps3_mame_colours = auto_malloc(0x80000);
+ memset(cps3_mame_colours, 0x00, 0x80000);
+
+ cps3_screenwidth = 384;
+
+ // the renderbuffer can be twice the size of the screen, this allows us to handle framebuffer zoom values
+ // between 0x00 and 0x80 (0x40 is normal, 0x80 would be 'view twice as much', 0x20 is 'view half as much')
+ renderbuffer_bitmap = auto_bitmap_alloc(512*2,224*2,machine->screen[0].format);
+
+ renderbuffer_clip.min_x = 0;
+ renderbuffer_clip.max_x = cps3_screenwidth-1;
+ renderbuffer_clip.min_y = 0;
+ renderbuffer_clip.max_y = 224-1;
+
+ fillbitmap(renderbuffer_bitmap,0x3f,&renderbuffer_clip);
+
+}
+
+// the 0x400 bit in the tilemap regs is "draw it upside-down" (bios tilemap during flashing, otherwise capcom logo is flipped)
+
+static void cps3_draw_tilemapsprite_line(int tmnum, int drawline, mame_bitmap *bitmap, const rectangle *cliprect )
+{
+ UINT32* tmapregs[4] = { tilemap20_regs_base, tilemap30_regs_base, tilemap40_regs_base, tilemap50_regs_base };
+ UINT32* regs;
+ int line;
+ int scrolly;
+ if (tmnum>3)
+ {
+ printf("cps3_draw_tilemapsprite_line Illegal tilemap number %d\n",tmnum);
+ return;
+ }
+ regs = tmapregs[tmnum];
+
+ scrolly = ((regs[0]&0x0000ffff)>>0)+4;
+ line = drawline+scrolly;
+ line&=0x3ff;
+
+
+ if (!(regs[1]&0x00008000)) return;
+
+ {
+ UINT32 mapbase = (regs[2]&0x007f0000)>>16;
+ UINT32 linebase= (regs[2]&0x7f000000)>>24;
+ int linescroll_enable = (regs[1]&0x00004000);
+
+ int scrollx;
+ int x;
+ int tileline = (line/16)+1;
+ int tilesubline = line % 16;
+ rectangle clip;
+
+ mapbase = mapbase << 10;
+ linebase = linebase << 10;
+
+ if (!linescroll_enable)
+ {
+ scrollx = (regs[0]&0xffff0000)>>16;
+ }
+ else
+ {
+ // printf("linebase %08x\n", linebase);
+
+ scrollx = (regs[0]&0xffff0000)>>16;
+ scrollx+= (cps3_spriteram[linebase+((line+16-4)&0x3ff)]>>16)&0x3ff;
+
+ }
+
+// zoombase = (layerregs[1]&0xffff0000)>>16;
+
+ drawline&=0x3ff;
+
+ if (drawline>cliprect->max_y+4) return;
+
+ clip.min_x = cliprect->min_x;
+ clip.max_x = cliprect->max_x;
+ clip.min_y = drawline;
+ clip.max_y = drawline;
+
+ for (x=0;x<(cliprect->max_x/16)+2;x++)
+ {
+
+ UINT32 dat;
+ int tileno;
+ int colour;
+ int bpp;
+ int xflip,yflip;
+
+ dat = cps3_spriteram[mapbase+((tileline&63)*64)+((x+scrollx/16)&63)];
+ tileno = (dat & 0xffff0000)>>17;
+ colour = (dat & 0x000001ff)>>0;
+ bpp = (dat & 0x0000200)>>9;
+ yflip = (dat & 0x00000800)>>11;
+ xflip = (dat & 0x00001000)>>12;
+
+ if (!bpp) Machine->gfx[1]->color_granularity=256;
+ else Machine->gfx[1]->color_granularity=64;
+
+ if (cps3_char_ram_dirty[tileno])
+ {
+ decodechar(Machine->gfx[1], tileno, (UINT8*)cps3_char_ram, &cps3_tiles16x16_layout);
+ cps3_char_ram_dirty[tileno] = 0;
+ }
+ cps3_drawgfxzoom(bitmap, Machine->gfx[1],tileno,colour,xflip,yflip,(x*16)-scrollx%16,drawline-tilesubline,&clip,CPS3_TRANSPARENCY_PEN_INDEX,0, 0x10000, 0x10000, NULL, 0);
+
+ }
+ }
+}
+
+static VIDEO_UPDATE(cps3)
+{
+ int y,x, count;
+// int offset;
+
+ int bg_drawn[4] = { 0, 0, 0, 0 };
+
+ UINT32 fullscreenzoomx, fullscreenzoomy;
+ UINT32 fszx, fszy;
+
+// decode_ssram();
+// decode_charram();
+
+ /* registers are normally 002a006f 01ef01c6
+ widescreen mode = 00230076 026501c6
+ only SFIII2 uses widescreen, I don't know exactly which register controls it */
+ if (((cps3_fullscreenzoom[1]&0xffff0000)>>16)==0x0265)
+ {
+ if (cps3_screenwidth!=496)
+ {
+ screen_state *state = &machine->screen[0];
+ rectangle visarea = state->visarea;
+ cps3_screenwidth = 496;
+ visarea.min_x = 0; visarea.max_x = 496-1;
+ visarea.min_y = 0; visarea.max_y = 224-1;
+ video_screen_configure(0, 496, 224, &visarea, state->refresh );
+ }
+ }
+ else
+ {
+ if (cps3_screenwidth!=384)
+ {
+ screen_state *state = &machine->screen[0];
+ rectangle visarea = state->visarea;
+ cps3_screenwidth = 384;
+ visarea.min_x = 0; visarea.max_x = 384-1;
+ visarea.min_y = 0; visarea.max_y = 224-1;
+ video_screen_configure(0, 384, 224, &visarea, state->refresh );
+ }
+ }
+
+ fullscreenzoomx = cps3_fullscreenzoom[3] & 0x000000ff;
+ fullscreenzoomy = cps3_fullscreenzoom[3] & 0x000000ff;
+ /* clamp at 0x80, I don't know if this is accurate */
+ if (fullscreenzoomx>0x80) fullscreenzoomx = 0x80;
+ if (fullscreenzoomy>0x80) fullscreenzoomy = 0x80;
+
+ fszx = (fullscreenzoomx<<16)/0x40;
+ fszy = (fullscreenzoomy<<16)/0x40;
+
+ renderbuffer_clip.min_x = 0;
+ renderbuffer_clip.max_x = ((cps3_screenwidth*fszx)>>16)-1;
+ renderbuffer_clip.min_y = 0;
+ renderbuffer_clip.max_y = ((224*fszx)>>16)-1;
+
+ fillbitmap(renderbuffer_bitmap,0,&renderbuffer_clip);
+
+ /* Sprites */
+ {
+ int i;
+
+ //printf("Spritelist start:\n");
+ for (i=0x00000/4;i<0x2000/4;i+=4)
+ {
+ int xpos = (cps3_spriteram[i+1]&0x03ff0000)>>16;
+ int ypos = cps3_spriteram[i+1]&0x000003ff;
+ int j;
+ int gscroll = (cps3_spriteram[i+0]&0x70000000)>>28;
+ UINT8 length = (cps3_spriteram[i+0]&0x00ff0000)>>16; // how many entries in the sprite table
+ UINT32 start = (cps3_spriteram[i+0]&0x00007ff0)>>4;
+
+ int whichbpp = (cps3_spriteram[i+2]&0x40000000)>>30; // not 100% sure if this is right, jojo title / characters
+ int whichpal = (cps3_spriteram[i+2]&0x20000000)>>29;
+ int global_xflip = (cps3_spriteram[i+2]&0x10000000)>>28;
+ int global_yflip = (cps3_spriteram[i+2]&0x08000000)>>27;
+ int global_alpha = (cps3_spriteram[i+2]&0x04000000)>>26; // alpha / shadow? set on sfiii2 shadows, and big black image in jojo intro
+ int global_bpp = (cps3_spriteram[i+2]&0x02000000)>>25;
+ int global_pal = (cps3_spriteram[i+2]&0x01ff0000)>>16;
+
+ int gscrollx = (cps3_unk_vidregs[gscroll]&0x03ff0000)>>16;
+ int gscrolly = (cps3_unk_vidregs[gscroll]&0x000003ff)>>0;
+ start = (start * 0x100) >> 2;
+
+ if ((cps3_spriteram[i+0]&0xf0000000) == 0x80000000)
+ break;
+
+ for (j=0;j<(length)*4;j+=4)
+ {
+
+ UINT32 value1 = (cps3_spriteram[start+j+0]);
+ UINT32 value2 = (cps3_spriteram[start+j+1]);
+ UINT32 value3 = (cps3_spriteram[start+j+2]);
+
+
+ //UINT8* srcdata = (UINT8*)cps3_char_ram;
+ //UINT32 sourceoffset = (value1 >>14)&0x7fffff;
+ int count;
+
+ UINT32 tileno = (value1&0xfffe0000)>>17;
+
+ int xpos2 = (value2 & 0x03ff0000)>>16;
+ int ypos2 = (value2 & 0x000003ff)>>0;
+ int flipx = (value1 & 0x00001000)>>12;
+ int flipy = (value1 & 0x00000800)>>11;
+ int alpha = (value1 & 0x00000400)>>10; //? this one is used for alpha effects on warzard
+ int bpp = (value1 & 0x00000200)>>9;
+ int pal = (value1 & 0x000001ff);
+
+
+ /* these are the sizes to actually draw */
+ int ysizedraw2 = ((value3 & 0x7f000000)>>24);
+ int xsizedraw2 = ((value3 & 0x007f0000)>>16);
+ int xx,yy;
+
+ int tilestable[4] = { 8,1,2,4 };
+ int ysize2 = ((value3 & 0x0000000c)>>2);
+ int xsize2 = ((value3 & 0x00000003)>>0);
+ UINT32 xinc,yinc;
+
+ if (ysize2==0)
+ {
+ // printf("invalid sprite ysize of 0 tiles\n");
+ continue;
+ }
+
+ if (xsize2==0) // xsize of 0 tiles seems to be a special command to draw tilemaps
+ {
+ int tilemapnum = ((value3 & 0x00000030)>>4);
+ int startline;// = value2 & 0x3ff;
+ int endline;
+ int height = (value3 & 0x7f000000)>>24;
+ int uu;
+ UINT32* tmapregs[4] = { tilemap20_regs_base, tilemap30_regs_base, tilemap40_regs_base, tilemap50_regs_base };
+ UINT32* regs;
+ regs = tmapregs[tilemapnum];
+ endline = value2;
+ startline = endline - height;
+
+ startline &=0x3ff;
+ endline &=0x3ff;
+
+ //printf("tilemap draw %01x %02x %02x %02x\n",tilemapnum, value2, height, regs[0]&0x000003ff );
+
+ //printf("tilemap draw %01x %d %d\n",tilemapnum, startline, endline );
+
+
+ /* Urgh, the startline / endline seem to be direct screen co-ordinates regardless of fullscreen zoom
+ which probably means the fullscreen zoom is applied when rendering everything, not aftewards */
+ //for (uu=startline;uu<endline+1;uu++)
+
+ if (bg_drawn[tilemapnum]==0)
+ {
+ for (uu=0;uu<1023;uu++)
+ {
+ cps3_draw_tilemapsprite_line( tilemapnum, uu, renderbuffer_bitmap, &renderbuffer_clip );
+ }
+ }
+ bg_drawn[tilemapnum] = 1;
+ }
+ else
+ {
+ ysize2 = tilestable[ysize2];
+ xsize2 = tilestable[xsize2];
+
+ xinc = ((xsizedraw2+1)<<16) / ((xsize2*0x10));
+ yinc = ((ysizedraw2+1)<<16) / ((ysize2*0x10));
+
+ xsize2-=1;
+ ysize2-=1;
+
+ flipx ^= global_xflip;
+ flipy ^= global_yflip;
+
+ if (!flipx) xpos2+=((xsizedraw2+1)/2);
+ else xpos2-=((xsizedraw2+1)/2);
+
+ ypos2+=((ysizedraw2+1)/2);
+
+ if (!flipx) xpos2-= (xsize2+1)*((16*xinc)>>16);
+ else xpos2+= (xsize2)*((16*xinc)>>16);
+
+ if (flipy) ypos2-= ysize2*((16*yinc)>>16);
+
+ {
+ count = 0;
+ for (xx=0;xx<xsize2+1;xx++)
+ {
+ int current_xpos;
+
+ if (!flipx) current_xpos = (xpos+xpos2+xx* ((16*xinc)>>16) );
+ else current_xpos = (xpos+xpos2-xx*((16*xinc)>>16));
+ //current_xpos += rand()&0x3ff;
+ current_xpos += gscrollx;
+ current_xpos += 1;
+ current_xpos &=0x3ff;
+ if (current_xpos&0x200) current_xpos-=0x400;
+
+ for (yy=0;yy<ysize2+1;yy++)
+ {
+ int current_ypos;
+ int actualpal;
+
+ if (flipy) current_ypos = (ypos+ypos2+yy*((16*yinc)>>16));
+ else current_ypos = (ypos+ypos2-yy*((16*yinc)>>16));
+
+ current_ypos += gscrolly;
+ current_ypos = 0x3ff-current_ypos;
+ current_ypos -= 17;
+ current_ypos &=0x3ff;
+
+ if (current_ypos&0x200) current_ypos-=0x400;
+
+ //if ( (whichbpp) && (cpu_getcurrentframe() & 1)) continue;
+
+ /* use the palette value from the main list or the sublists? */
+ if (whichpal)
+ {
+ actualpal = global_pal;
+ }
+ else
+ {
+ actualpal = pal;
+ }
+
+ /* use the bpp value from the main list or the sublists? */
+ if (whichbpp)
+ {
+ if (!global_bpp) machine->gfx[1]->color_granularity=256;
+ else machine->gfx[1]->color_granularity=64;
+ }
+ else
+ {
+ if (!bpp) machine->gfx[1]->color_granularity=256;
+ else machine->gfx[1]->color_granularity=64;
+ }
+
+ {
+ int realtileno = tileno+count;
+
+ if (cps3_char_ram_dirty[realtileno])
+ {
+ decodechar(machine->gfx[1], realtileno, (UINT8*)cps3_char_ram, &cps3_tiles16x16_layout);
+ cps3_char_ram_dirty[realtileno] = 0;
+ }
+
+ if (global_alpha || alpha)
+ {
+ cps3_drawgfxzoom(renderbuffer_bitmap, machine->gfx[1],realtileno,actualpal,0^flipx,0^flipy,current_xpos,current_ypos,&renderbuffer_clip,CPS3_TRANSPARENCY_PEN_INDEX_BLEND,0,xinc,yinc, NULL, 0);
+ }
+ else
+ {
+ cps3_drawgfxzoom(renderbuffer_bitmap, machine->gfx[1],realtileno,actualpal,0^flipx,0^flipy,current_xpos,current_ypos,&renderbuffer_clip,CPS3_TRANSPARENCY_PEN_INDEX,0,xinc,yinc, NULL, 0);
+ }
+ count++;
+ }
+ }
+ }
+ }
+ // */
+
+ // printf("cell %08x %08x %08x\n",value1, value2, value3);
+ }
+ }
+ }
+ }
+
+ /* copy render bitmap with zoom */
+ {
+ UINT32 renderx,rendery;
+ UINT32 srcx, srcy;
+ UINT32* srcbitmap;
+ UINT32* dstbitmap;
+
+
+ srcy=0;
+ for (rendery=0;rendery<224;rendery++)
+ {
+ dstbitmap = BITMAP_ADDR32(bitmap, rendery, 0);
+ srcbitmap = BITMAP_ADDR32(renderbuffer_bitmap, srcy>>16, 0);
+ srcx=0;
+
+ for (renderx=0;renderx<cps3_screenwidth;renderx++)
+ {
+ dstbitmap[renderx] = cps3_mame_colours[srcbitmap[srcx>>16]&0x1ffff];
+ srcx += fszx;
+ }
+
+ srcy += fszy;
+ }
+ }
+
+ /* Draw the text layer */
+ /* Copy the first 0x800 colours to be used for fg layer rendering */
+// for (offset=0;offset<0x200;offset++)
+// {
+// int palreadbase = (cps3_ss_pal_base << 9);
+// palette_set_color(machine,offset,cps3_mame_colours[palreadbase+offset]);
+// }
+
+ // fg layer
+ {
+ // bank select? (sfiii2 intro)
+ if (cps3_ss_bank_base & 0x01000000) count = 0x000;
+ else count = 0x800;
+
+ for (y=0;y<32;y++)
+ {
+ for (x=0;x<64;x++)
+ {
+ UINT32 data = cps3_ss_ram[count]; // +0x800 = 2nd bank, used on sfiii2 intro..
+ UINT32 tile = (data >> 16) & 0x1ff;
+ int pal = (data&0x003f) >> 1;
+ int flipx = (data & 0x0080) >> 7;
+ int flipy = (data & 0x0040) >> 6;
+ pal += cps3_ss_pal_base << 5;
+ tile+=0x200;
+
+
+ if (cps3_ss_ram_dirty[tile])
+ {
+ decodechar(machine->gfx[0], tile, (UINT8*)cps3_ss_ram, &cps3_tiles8x8_layout);
+ cps3_ss_ram_dirty[tile] = 0;
+ }
+
+ cps3_drawgfxzoom(bitmap, machine->gfx[0],tile,pal,flipx,flipy,x*8,y*8,cliprect,CPS3_TRANSPARENCY_PEN,0,0x10000,0x10000,NULL,0);
+ count++;
+ }
+ }
+ }
+ return 0;
+}
+
+static READ32_HANDLER( cps3_ssram_r )
+{
+ if (offset>0x8000/4)
+ return LITTLE_ENDIANIZE_INT32(cps3_ss_ram[offset]);
+ else
+ return cps3_ss_ram[offset];
+}
+
+static WRITE32_HANDLER( cps3_ssram_w )
+{
+ if (offset>0x8000/4)
+ {
+ // we only want to endian-flip the character data, the tilemap info is fine
+ data = LITTLE_ENDIANIZE_INT32(data);
+ mem_mask = LITTLE_ENDIANIZE_INT32(mem_mask);
+
+ cps3_ss_ram_dirty[offset/16] = 1;
+ cps3_ss_ram_is_dirty = 1;
+ }
+
+ COMBINE_DATA(&cps3_ss_ram[offset]);
+}
+
+static WRITE32_HANDLER( cps3_0xc0000000_ram_w )
+{
+ COMBINE_DATA( &cps3_0xc0000000_ram[offset] );
+ // store a decrypted copy
+ cps3_0xc0000000_ram_decrypted[offset] = cps3_0xc0000000_ram[offset]^cps3_mask(offset*4+0xc0000000, cps3_key1, cps3_key2);
+}
+
+
+
+static offs_t cps3_opbase_handler(offs_t address)
+{
+// if(DEBUG_PRINTF) printf("address %04x\n",address);
+
+ /* BIOS ROM */
+ if (address < 0x80000)
+ {
+ opcode_base = opcode_arg_base = memory_region(REGION_USER1);
+ return ~0;
+ }
+ /* RAM */
+ else if (address >= 0x06000000 && address <= 0x06ffffff)
+ {
+ opcode_base = (UINT8*)decrypted_gamerom-0x06000000;
+ opcode_arg_base = (UINT8*)decrypted_gamerom-0x06000000;
+
+ if (cps3_isSpecial) opcode_arg_base = (UINT8*) memory_region(REGION_USER4)-0x06000000;
+
+
+ return ~0;
+ }
+ else if (address >= 0xc0000000 && address <= 0xc00003ff)
+ {
+// opcode_base = (void*)cps3_0xc0000000_ram_decrypted;
+ opcode_base = (UINT8*)cps3_0xc0000000_ram_decrypted-0xc0000000;
+ opcode_arg_base = (UINT8*)cps3_0xc0000000_ram-0xc0000000;
+ return ~0;
+ }
+
+ /* anything else falls through to NOPs */
+ opcode_base = (UINT8*)cps3_nops-address;
+ opcode_arg_base = (UINT8*)cps3_nops-address;
+ return ~0;
+}
+
+static UINT32 cram_bank = 0;
+
+static WRITE32_HANDLER( cram_bank_w )
+{
+ if (ACCESSING_LSB)
+ {
+ // this seems to be related to accesses to the 0x04100000 region
+ if (cram_bank != data)
+ {
+ cram_bank = data;
+ //if(data&0xfffffff0)
+ //bank_w 00000000, ffff0000
+ //bank_w 00000001, ffff0000
+ //bank_w 00000002, ffff0000
+ //bank_w 00000003, ffff0000
+ //bank_w 00000004, ffff0000
+ //bank_w 00000005, ffff0000
+ //bank_w 00000006, ffff0000
+ //bank_w 00000007, ffff0000
+ // during CHARACTER RAM test..
+ if(DEBUG_PRINTF) printf("bank_w %08x, %08x\n",data,mem_mask);
+
+ }
+ }
+ else
+ {
+ if(DEBUG_PRINTF) printf("bank_w LSB32 %08x, %08x\n",data,mem_mask);
+
+ }
+}
+
+static READ32_HANDLER( cram_data_r )
+{
+ UINT32 fulloffset = (((cram_bank&0x7)*0x100000)/4) + offset;
+
+ return LITTLE_ENDIANIZE_INT32(cps3_char_ram[fulloffset]);
+}
+
+static WRITE32_HANDLER( cram_data_w )
+{
+ UINT32 fulloffset = (((cram_bank&0x7)*0x100000)/4) + offset;
+ mem_mask = LITTLE_ENDIANIZE_INT32(mem_mask);
+ data = LITTLE_ENDIANIZE_INT32(data);
+ COMBINE_DATA(&cps3_char_ram[fulloffset]);
+ cps3_char_ram_dirty[fulloffset/0x40] = 1;
+ cps3_char_ram_is_dirty = 1;
+}
+
+/* FLASH ROM ACCESS */
+
+static READ32_HANDLER( cps3_gfxflash_r )
+{
+ UINT32 result = 0;
+ int flash1 = 8;
+ int flash2 = 9;
+ if (cram_gfxflash_bank&1) offset += 0x200000/4;
+
+ flash1 += cram_gfxflash_bank&0x3e;
+ flash2 += cram_gfxflash_bank&0x3e;
+
+ if(DEBUG_PRINTF) printf("gfxflash_r\n");
+
+ if (!(mem_mask & 0xff000000)) // GFX Flash 1
+ {
+ logerror("read GFX flash chip %d addr %02x\n", flash1-8, (offset<<1));
+ result |= intelflash_read(flash1, (offset<<1) ) << 24;
+ }
+ if (!(mem_mask & 0x00ff0000)) // GFX Flash 2
+ {
+ logerror("read GFX flash chip %d addr %02x\n", flash2-8, (offset<<1));
+ result |= intelflash_read(flash2, (offset<<1) ) << 16;
+ }
+ if (!(mem_mask & 0x0000ff00)) // GFX Flash 1
+ {
+ logerror("read GFX flash chip %d addr %02x\n", flash1-8, (offset<<1)+1);
+ result |= intelflash_read(flash1, (offset<<1)+0x1 ) << 8;
+ }
+ if (!(mem_mask & 0x000000ff)) // GFX Flash 2
+ {
+ logerror("read GFX flash chip %d addr %02x\n", flash2-8, (offset<<1)+1);
+ result |= intelflash_read(flash2, (offset<<1)+0x1 ) << 0;
+ }
+
+ //printf("read GFX flash chips addr %02x returning %08x mem_mask %08x crambank %08x gfxbank %08x\n", offset*2, result,mem_mask, cram_bank, cram_gfxflash_bank );
+
+ return result;
+}
+
+static WRITE32_HANDLER( cps3_gfxflash_w )
+{
+ int command;
+ int flash1 = 8;
+ int flash2 = 9;
+ if (cram_gfxflash_bank&1) offset += 0x200000/4;
+
+ flash1 += cram_gfxflash_bank&0x3e;
+ flash2 += cram_gfxflash_bank&0x3e;
+
+
+// if(DEBUG_PRINTF) printf("cps3_gfxflash_w %08x %08x %08x\n", offset *2, data, mem_mask);
+
+
+ if (!(mem_mask & 0xff000000)) // GFX Flash 1
+ {
+ command = (data >> 24) & 0xff;
+ logerror("write to GFX flash chip %d addr %02x cmd %02x\n", flash1-8, (offset<<1), command);
+ intelflash_write(flash1, (offset<<1), command);
+ }
+ if (!(mem_mask & 0x00ff0000)) // GFX Flash 2
+ {
+ command = (data >> 16) & 0xff;
+ logerror("write to GFX flash chip %d addr %02x cmd %02x\n", flash2-8, (offset<<1), command);
+ intelflash_write(flash2, (offset<<1), command);
+ }
+ if (!(mem_mask & 0x0000ff00)) // GFX Flash 1
+ {
+ command = (data >> 8) & 0xff;
+ logerror("write to GFX flash chip %d addr %02x cmd %02x\n", flash1-8, (offset<<1)+1, command);
+ intelflash_write(flash1, (offset<<1)+0x1, command);
+ }
+ if (!(mem_mask & 0x000000ff)) // GFX Flash 2
+ {
+ command = (data >> 0) & 0xff;
+ //if ( ((offset<<1)+1) != 0x555) printf("write to GFX flash chip %d addr %02x cmd %02x\n", flash1-8, (offset<<1)+1, command);
+ intelflash_write(flash2, (offset<<1)+0x1, command);
+ }
+
+ /* make a copy in the linear memory region we actually use for drawing etc. having it stored in interleaved flash roms isnt' very useful */
+ {
+ UINT32* romdata = (UINT32*)memory_region(REGION_USER5);
+ int real_offset = 0;
+ UINT32 newdata;
+ UINT8* ptr1 = intelflash_getmemptr(flash1);
+ UINT8* ptr2 = intelflash_getmemptr(flash2);
+
+ real_offset = ((cram_gfxflash_bank&0x3e) * 0x200000) + offset*4;
+
+ newdata =((ptr1[((offset*2)&0xfffffffe)+0]<<8) |
+ (ptr1[((offset*2)&0xfffffffe)+1]<<24) |
+ (ptr2[((offset*2)&0xfffffffe)+0]<<0) |
+ (ptr2[((offset*2)&0xfffffffe)+1]<<16));
+
+// printf("flashcrap %08x %08x %08x\n", offset *2, romdata[real_offset/4], newdata);
+ romdata[real_offset/4] = newdata;
+ }
+}
+
+
+
+static UINT32 cps3_flashmain_r(int base, UINT32 offset, UINT32 mem_mask)
+{
+ UINT32 result = 0;
+
+ if (!(mem_mask & 0xff000000)) // Flash 1
+ {
+// logerror("read flash chip %d addr %02x\n", base+0, offset*4 );
+ result |= (intelflash_read(base+0, offset)<<24);
+ }
+ if (!(mem_mask & 0x00ff0000)) // Flash 1
+ {
+// logerror("read flash chip %d addr %02x\n", base+1, offset*4 );
+ result |= (intelflash_read(base+1, offset)<<16);
+ }
+ if (!(mem_mask & 0x0000ff00)) // Flash 1
+ {
+// logerror("read flash chip %d addr %02x\n", base+2, offset*4 );
+ result |= (intelflash_read(base+2, offset)<<8);
+ }
+ if (!(mem_mask & 0x000000ff)) // Flash 1
+ {
+// logerror("read flash chip %d addr %02x\n", base+3, offset*4 );
+ result |= (intelflash_read(base+3, offset)<<0);
+ }
+
+// if (base==4) logerror("read flash chips addr %02x returning %08x\n", offset*4, result );
+
+ return result;
+}
+
+/* In certain situations (SH2 DMA?) the reads must bypass the encryption device,
+ this is used when checking the flash roms, and performing rom tests. Without
+ modification to the SH2 core this requires PC based hacks to work correctly */
+static UINT32 cps3_bios_test_hack;
+static UINT32 cps3_game_test_hack;
+
+struct cps3_test_hacks
+{
+ const char *name; /* game driver name */
+ const UINT32 bios_test_hack;
+ const UINT32 game_test_hack;
+};
+
+static const struct cps3_test_hacks testhack_table[] =
+{
+ // name mainram address code address
+ { "jojo", 0x0011c2c, 0x6172568 },
+ { "jojon", 0x0011c2c, 0x6172568 },
+ { "jojoalt", 0x0011c2c, 0x6172798 },
+ { "jojoaltn", 0x0011c2c, 0x6172798 },
+ { "jojoba", 0x0011c90, 0x61c45bc },
+ { "jojoban", 0x0011c90, 0x61c45bc },
+ { "jojobane", 0x0011c90, 0x61c45bc },
+ { "sfiii", 0x00166b4, 0x63cdff4 },
+ { "sfiiiu", 0x00166b4, 0x63cdff4 },
+ { "sfiiin", 0x00166b4, 0x63cdff4 },
+ { "sfiii2", 0, 0 },
+ { "sfiii2u", 0, 0 },
+ { "sfiii2n", 0, 0 },
+ { "sfiii3", 0x0011c44, 0x613a9fc },
+ { "sfiii3n", 0x0011c44, 0x613a9fc },
+ { "sfiii3a", 0x0011c44, 0x613ab48 },
+ { "sfiii3an", 0x0011c44, 0x613ab48 },
+ { "warzard", 0x0016530, 0x60105f0 },
+ { "redearth", 0x0016530, 0x60105f0 },
+ { 0 } // end of table
+};
+
+static DRIVER_INIT( cps3_testhacks )
+{
+ const char *gamename = machine->gamedrv->name;
+ const struct cps3_test_hacks *k = &testhack_table[0];
+
+ cps3_bios_test_hack = 0;
+ cps3_game_test_hack = 0;
+
+ while (k->name)
+ {
+ if (strcmp(k->name, gamename) == 0)
+ {
+ cps3_bios_test_hack = k->bios_test_hack;
+ cps3_game_test_hack = k->game_test_hack;
+ break;
+ }
+ ++k;
+ }
+ printf("testhacks %08x %08x\n",cps3_bios_test_hack,cps3_game_test_hack);
+}
+
+
+static READ32_HANDLER( cps3_flash1_r )
+{
+ UINT32 retvalue = cps3_flashmain_r(0, offset,mem_mask);
+
+ if (activecpu_get_pc()==cps3_bios_test_hack) return retvalue; // initial flash tests / bios tests
+ if (activecpu_get_pc()==cps3_game_test_hack) return retvalue; // test menu rom tests
+ if (cps3_isSpecial) return retvalue; // sfiii2.. (no encrypted data)
+
+ retvalue = retvalue ^ cps3_mask(0x6000000+offset*4, cps3_key1, cps3_key2);
+ return retvalue;
+}
+
+static READ32_HANDLER( cps3_flash2_r )
+{
+ UINT32 retvalue = cps3_flashmain_r(4, offset,mem_mask);
+
+ if (activecpu_get_pc()==cps3_bios_test_hack) return retvalue; // initial flash tests / bios tests
+ if (activecpu_get_pc()==cps3_game_test_hack) return retvalue; // test menu rom tests
+ if (cps3_isSpecial) return retvalue; // sfiii2.. (no encrypted data)
+
+ retvalue = retvalue ^ cps3_mask(0x6800000+offset*4, cps3_key1, cps3_key2);
+ return retvalue;
+}
+
+static void cps3_flashmain_w(int base, UINT32 offset, UINT32 data, UINT32 mem_mask)
+{
+ int command;
+ if (!(mem_mask & 0xff000000)) // Flash 1
+ {
+ command = (data >> 24) & 0xff;
+ logerror("write to flash chip %d addr %02x cmd %02x\n", base+0, offset, command);
+ intelflash_write(base+0, offset, command);
+ }
+ if (!(mem_mask & 0x00ff0000)) // Flash 2
+ {
+ command = (data >> 16) & 0xff;
+ logerror("write to flash chip %d addr %02x cmd %02x\n", base+1, offset, command);
+ intelflash_write(base+1, offset, command);
+ }
+ if (!(mem_mask & 0x0000ff00)) // Flash 2
+ {
+ command = (data >> 8) & 0xff;
+ logerror("write to flash chip %d addr %02x cmd %02x\n", base+2, offset, command);
+ intelflash_write(base+2, offset, command);
+ }
+ if (!(mem_mask & 0x000000ff)) // Flash 2
+ {
+ command = (data >> 0) & 0xff;
+ logerror("write to flash chip %d addr %02x cmd %02x\n", base+3, offset, command);
+ intelflash_write(base+3, offset, command);
+ }
+
+ /* copy data into regions to execute from */
+ {
+ UINT32* romdata = (UINT32*)memory_region(REGION_USER4);
+ UINT32* romdata2 = (UINT32*)decrypted_gamerom;
+ int real_offset = 0;
+ UINT32 newdata;
+ UINT8* ptr1 = intelflash_getmemptr(base+0);
+ UINT8* ptr2 = intelflash_getmemptr(base+1);
+ UINT8* ptr3 = intelflash_getmemptr(base+2);
+ UINT8* ptr4 = intelflash_getmemptr(base+3);
+
+ real_offset = offset * 4;
+
+ if (base==4)
+ {
+ romdata+=0x800000/4;
+ romdata2+=0x800000/4;
+ real_offset += 0x800000;
+ }
+
+ newdata = (ptr1[offset]<<24) |
+ (ptr2[offset]<<16) |
+ (ptr3[offset]<<8) |
+ (ptr4[offset]<<0);
+
+ //printf("%08x %08x %08x %08x %08x\n",offset, romdata2[offset], romdata[offset], newdata, newdata^cps3_mask(0x6000000+real_offset, cps3_key1, cps3_key2) );
+
+ romdata[offset] = newdata;
+ romdata2[offset] = newdata^cps3_mask(0x6000000+real_offset, cps3_key1, cps3_key2);
+ }
+
+
+
+/*
+ opcode_base = (UINT8*)decrypted_gamerom-0x06000000;
+ opcode_arg_base = (UINT8*)decrypted_gamerom-0x06000000;
+
+ if (cps3_isSpecial) opcode_arg_base = (UINT8*) memory_region(REGION_USER4)-0x06000000;
+*/
+
+}
+static WRITE32_HANDLER( cps3_flash1_w )
+{
+ cps3_flashmain_w(0, offset,data,mem_mask);
+}
+
+static WRITE32_HANDLER( cps3_flash2_w )
+{
+ cps3_flashmain_w(4, offset,data,mem_mask);
+}
+
+static WRITE32_HANDLER( cram_gfxflash_bank_w )
+{
+ if (ACCESSING_MSB32)
+ {
+ //printf("cram_gfxflash_bank_w MSB32 %08x\n",data);
+/*
+ SIMM 3 (Rom 30/31)
+ cram_gfxflash_bank_w MSB32 00020000 // first half of gfx 0 + 1
+ cram_gfxflash_bank_w MSB32 00030000 // 2nd half of gfx 0 + 1
+ cram_gfxflash_bank_w MSB32 00040000 // first half of gfx 2 + 3
+ cram_gfxflash_bank_w MSB32 00050000
+ cram_gfxflash_bank_w MSB32 00060000 // first half of gfx 4 + 5
+ cram_gfxflash_bank_w MSB32 00070000
+ cram_gfxflash_bank_w MSB32 00080000 // first half of gfx 6 + 7
+ cram_gfxflash_bank_w MSB32 00090000
+ SIMM 4 (Rom 40/41)
+ cram_gfxflash_bank_w MSB32 000a0000 // first half of gfx 8 + 9
+ cram_gfxflash_bank_w MSB32 000b0000
+ cram_gfxflash_bank_w MSB32 000c0000 // first half of gfx 10 + 11
+ cram_gfxflash_bank_w MSB32 000d0000
+ cram_gfxflash_bank_w MSB32 000e0000 // first half of gfx 12 + 13
+ cram_gfxflash_bank_w MSB32 000f0000
+ cram_gfxflash_bank_w MSB32 00100000 // first half of gfx 14 + 15
+ cram_gfxflash_bank_w MSB32 00110000
+ SIMM 5 (Rom 50/51)
+ cram_gfxflash_bank_w MSB32 00120000 // first half of gfx 16 + 17
+ cram_gfxflash_bank_w MSB32 00130000
+ cram_gfxflash_bank_w MSB32 00140000 // first half of gfx 18 + 19
+ cram_gfxflash_bank_w MSB32 00150000
+ cram_gfxflash_bank_w MSB32 00160000 // first half of gfx 20 + 21
+ cram_gfxflash_bank_w MSB32 00170000
+ cram_gfxflash_bank_w MSB32 00180000 // first half of gfx 22 + 23
+ cram_gfxflash_bank_w MSB32 00190000
+ SIMM 6 (Rom 60/61)
+ cram_gfxflash_bank_w MSB32 001a0000 // first half of gfx 24 + 25
+ cram_gfxflash_bank_w MSB32 001b0000
+ cram_gfxflash_bank_w MSB32 001c0000 // first half of gfx 26 + 27
+ cram_gfxflash_bank_w MSB32 001d0000
+ cram_gfxflash_bank_w MSB32 001e0000 // first half of gfx 28 + 29
+ cram_gfxflash_bank_w MSB32 001f0000
+ cram_gfxflash_bank_w MSB32 00200000 // first half of gfx 30 + 31
+ cram_gfxflash_bank_w MSB32 00210000
+ SIMM 7 (Rom 70/71) ** NOT USED (would follow on in sequence tho)
+
+ */
+ cram_gfxflash_bank = (data & 0xffff0000) >> 16;
+ cram_gfxflash_bank-= 0x0002;// as with sound access etc. first 4 meg is 'special' and skipped
+ }
+
+ if (ACCESSING_LSB32)
+ {
+ /* if(DEBUG_PRINTF)*/ printf("cram_gfxflash_bank_LSB_w LSB32 %08x\n",data);
+ }
+}
+
+static READ32_HANDLER( cps3_io1_r )
+{
+ return readinputport(0);
+}
+
+static READ32_HANDLER( cps3_io2_r )
+{
+ return readinputport(1);
+}
+
+// this seems to be dma active flags, and maybe vblank... not if it is anything else
+static READ32_HANDLER( cps3_vbl_r )
+{
+ return 0x00000000;
+}
+
+static READ32_HANDLER( cps3_unk_io_r )
+{
+ // warzard will crash before booting if you return anything here
+ return 0xffffffff;
+}
+
+static READ32_HANDLER( cps3_40C0000_r )
+{
+ return 0x00000000;
+}
+
+static READ32_HANDLER( cps3_40C0004_r )
+{
+ return 0x00000000;
+}
+
+/* EEPROM access is a little odd, I think it accesses eeprom through some kind of
+ additional interface, as these writes aren't normal for the type of eeprom we have */
+static UINT16 cps3_current_eeprom_read;
+
+static READ32_HANDLER( cps3_eeprom_r )
+{
+ int addr = offset*4;
+
+ if (addr>=0x100 && addr<=0x17f)
+ {
+ if (ACCESSING_MSB32) cps3_current_eeprom_read = (cps3_eeprom[offset-0x100/4] & 0xffff0000)>>16;
+ else cps3_current_eeprom_read = (cps3_eeprom[offset-0x100/4] & 0x0000ffff)>>0;
+ // read word to latch...
+ return 0x00000000;
+ }
+ else if (addr == 0x200)
+ {
+ // busy flag / read data..
+ if (ACCESSING_MSB32) return 0;
+ else
+ {
+ //if(DEBUG_PRINTF) printf("reading %04x from eeprom\n", cps3_current_eeprom_read);
+ return cps3_current_eeprom_read;
+ }
+ }
+ else
+ {
+ // if(DEBUG_PRINTF) printf("unk read eeprom addr %04x, mask %08x\n", addr, mem_mask);
+ return 0x00000000;
+ }
+ return 0x00000000;
+}
+
+static WRITE32_HANDLER( cps3_eeprom_w )
+{
+ int addr = offset*4;
+
+ if (addr>=0x080 && addr<=0x0ff)
+ {
+ offset -= 0x80/4;
+ COMBINE_DATA(&cps3_eeprom[offset]);
+ // write word to storage
+
+ }
+ else if (addr>=0x180 && addr<=0x1ff)
+ {
+ // always 00000000 ? incrememnt access?
+ }
+ else
+ {
+ // if(DEBUG_PRINTF) printf("unk write eeprom addr %04x, data %08x, mask %08x\n", addr, data, mem_mask);
+ }
+
+}
+
+static READ32_HANDLER( cps3_cdrom_r )
+{
+
+ UINT32 retval = 0;
+
+ if (ACCESSING_MSB32)
+ {
+ retval |= ((UINT16)wd33c93_r(0))<<16;
+ }
+
+ if (ACCESSING_LSB32)
+ {
+ retval |= (UINT16)wd33c93_r(1);
+ }
+
+ return retval;
+}
+
+static WRITE32_HANDLER( cps3_cdrom_w )
+{
+ if (ACCESSING_MSB32)
+ {
+ wd33c93_w(0,(data & 0x00ff0000)>>16);
+ }
+
+ if (ACCESSING_LSB32)
+ {
+ wd33c93_w(1,(data & 0x000000ff)>>0);
+ }
+}
+
+static WRITE32_HANDLER( cps3_ss_bank_base_w )
+{
+ // might be scroll registers or something else..
+ // used to display bank with 'insert coin' on during sfiii2 attract intro
+ COMBINE_DATA(&cps3_ss_bank_base);
+
+// printf("cps3_ss_bank_base_w %08x %08x\n", data, mem_mask);
+}
+
+static WRITE32_HANDLER( cps3_ss_pal_base_w )
+{
+ if(DEBUG_PRINTF) printf ("cps3_ss_pal_base_w %08x %08x\n", data, mem_mask);
+
+ if(ACCESSING_MSB32)
+ {
+ cps3_ss_pal_base = (data & 0x00ff0000)>>16;
+
+ if (data & 0xff000000) printf("cps3_ss_pal_base MSB32 upper bits used %04x \n", data);
+ }
+ else
+ {
+ // printf("cps3_ss_pal_base LSB32 used %04x \n", data);
+ }
+}
+
+static UINT32* tilemap20_regs_base;
+static UINT32* tilemap30_regs_base;
+static UINT32* tilemap40_regs_base;
+static UINT32* tilemap50_regs_base;
+
+//<ElSemi> +0 X +2 Y +4 unknown +6 enable (&0x8000) +8 low part tilemap base, high part linescroll base
+//<ElSemi> (a word each)
+
+static UINT32 paldma_source;
+static UINT32 paldma_realsource;
+static UINT32 paldma_dest;
+static UINT32 paldma_fade;
+static UINT32 paldma_other2;
+static UINT32 paldma_length;
+
+static WRITE32_HANDLER( cps3_palettedma_w )
+{
+ if (offset==0)
+ {
+ COMBINE_DATA(&paldma_source);
+ paldma_realsource = (paldma_source<<1)-0x400000;
+ }
+ else if (offset==1)
+ {
+ COMBINE_DATA(&paldma_dest);
+ }
+ else if (offset==2)
+ {
+ COMBINE_DATA(&paldma_fade);
+ }
+ else if (offset==3)
+ {
+ COMBINE_DATA(&paldma_other2);
+
+ if (ACCESSING_MSB32)
+ {
+ paldma_length = (data & 0xffff0000)>>16;
+ }
+ if (ACCESSING_LSB32)
+ {
+ if (data & 0x0002)
+ {
+ int i;
+ // if(DEBUG_PRINTF) printf("CPS3 pal dma start %08x (real: %08x) dest %08x fade %08x other2 %08x (length %04x)\n", paldma_source, paldma_realsource, paldma_dest, paldma_fade, paldma_other2, paldma_length);
+
+ for (i=0;i<paldma_length;i++)
+ {
+ UINT16* src = (UINT16*)memory_region(REGION_USER5);
+ UINT16 coldata = src[BYTE_XOR_BE(((paldma_realsource>>1)+i))];
+
+ //if (paldma_fade!=0) printf("%08x\n",paldma_fade);
+
+ cps3_set_mame_colours((paldma_dest+i)^1, coldata, paldma_fade);
+ }
+
+
+ cpunum_set_input_line(0,10, ASSERT_LINE);
+
+
+ }
+ }
+ }
+
+}
+
+static UINT32 chardma_source;
+static UINT32 chardma_other;
+
+//static UINT8* current_table;
+static UINT32 current_table_address = -1;
+
+int cps3_rle_length = 0;
+
+static int last_normal_byte = 0;
+
+
+static UINT32 process_byte( UINT8 real_byte, UINT32 destination, int max_length )
+{
+ UINT8* dest = (UINT8*)cps3_char_ram;
+
+ //printf("process byte for destination %08x\n", destination);
+
+ destination&=0x7fffff;
+
+ if (real_byte&0x40)
+ {
+ int tranfercount = 0;
+
+ //printf("Set RLE Mode\n");
+ cps3_rle_length = (real_byte&0x3f)+1;
+
+ //printf("RLE Operation (length %08x\n", cps3_rle_length );
+
+ while (cps3_rle_length)
+ {
+ dest[((destination+tranfercount)&0x7fffff)^3] = (last_normal_byte&0x3f);
+ cps3_char_ram_dirty[((destination+tranfercount)&0x7fffff)/0x100] = 1;
+ cps3_char_ram_is_dirty = 1;
+ //printf("RLE WRite Byte %08x, %02x\n", destination+tranfercount, real_byte);
+
+ tranfercount++;
+ cps3_rle_length--;
+ max_length--;
+
+ if ((destination+tranfercount) > 0x7fffff) return max_length;
+
+
+ // if (max_length==0) return max_length; // this is meant to abort the transfer if we exceed dest length,, not working
+ }
+ return tranfercount;
+ }
+ else
+ {
+ //printf("Write Normal Data\n");
+ dest[(destination&0x7fffff)^3] = real_byte;
+ last_normal_byte = real_byte;
+ cps3_char_ram_dirty[(destination&0x7fffff)/0x100] = 1;
+ cps3_char_ram_is_dirty = 1;
+ return 1;
+ }
+}
+
+static void cps3_do_char_dma( UINT32 real_source, UINT32 real_destination, UINT32 real_length )
+{
+ UINT8* sourcedata = (UINT8*)memory_region(REGION_USER5);
+ int length_remaining;
+
+ last_normal_byte = 0;
+ cps3_rle_length = 0;
+ length_remaining = real_length;
+ while (length_remaining)
+ {
+ UINT8 current_byte;
+
+ current_byte = sourcedata[DMA_XOR(real_source)];
+ real_source++;
+
+ if (current_byte & 0x80)
+ {
+ UINT8 real_byte;
+ UINT32 length_processed;
+ current_byte &= 0x7f;
+
+ real_byte = sourcedata[DMA_XOR((current_table_address+current_byte*2+0))];
+ //if (real_byte&0x80) return;
+ length_processed = process_byte( real_byte, real_destination, length_remaining );
+ length_remaining-=length_processed; // subtract the number of bytes the operation has taken
+ real_destination+=length_processed; // add it onto the destination
+ if (real_destination>0x7fffff) return;
+ if (length_remaining<=0) return; // if we've expired, exit
+
+ real_byte = sourcedata[DMA_XOR((current_table_address+current_byte*2+1))];
+ //if (real_byte&0x80) return;
+ length_processed = process_byte( real_byte, real_destination, length_remaining );
+ length_remaining-=length_processed; // subtract the number of bytes the operation has taken
+ real_destination+=length_processed; // add it onto the destination
+ if (real_destination>0x7fffff) return;
+ if (length_remaining<=0) return; // if we've expired, exit
+ }
+ else
+ {
+ UINT32 length_processed;
+ length_processed = process_byte( current_byte, real_destination, length_remaining );
+ length_remaining-=length_processed; // subtract the number of bytes the operation has taken
+ real_destination+=length_processed; // add it onto the destination
+ if (real_destination>0x7fffff) return;
+ if (length_remaining<=0) return; // if we've expired, exit
+ }
+
+// length_remaining--;
+ }
+}
+
+static unsigned short lastb;
+static unsigned short lastb2;
+static UINT32 ProcessByte8(UINT8 b,UINT32 dst_offset)
+{
+ UINT8* destRAM = (UINT8*)cps3_char_ram;
+ int l=0;
+
+ if(lastb==lastb2) //rle
+ {
+ int i;
+ int rle=(b+1)&0xff;
+
+ for(i=0;i<rle;++i)
+ {
+ destRAM[(dst_offset&0x7fffff)^3] = lastb;
+ cps3_char_ram_dirty[(dst_offset&0x7fffff)/0x100] = 1;
+ cps3_char_ram_is_dirty = 1;
+
+ dst_offset++;
+ ++l;
+ }
+ lastb2=0xffff;
+
+ return l;
+ }
+ else
+ {
+ lastb2=lastb;
+ lastb=b;
+ destRAM[(dst_offset&0x7fffff)^3] = b;
+ cps3_char_ram_dirty[(dst_offset&0x7fffff)/0x100] = 1;
+ cps3_char_ram_is_dirty = 1;
+ return 1;
+ }
+ }
+
+static void cps3_do_alt_char_dma( UINT32 src, UINT32 real_dest, UINT32 real_length )
+{
+ UINT8* px = (UINT8*)memory_region(REGION_USER5);
+ UINT32 start = real_dest;
+ UINT32 ds = real_dest;
+
+ lastb=0xfffe;
+ lastb2=0xffff;
+
+ while(1)
+ {
+ int i;
+ UINT8 ctrl=px[DMA_XOR(src)];
+ ++src;
+
+ for(i=0;i<8;++i)
+ {
+ UINT8 p=px[DMA_XOR(src)];
+
+ if(ctrl&0x80)
+ {
+ UINT8 real_byte;
+ p&=0x7f;
+ real_byte = px[DMA_XOR((current_table_address+p*2+0))];
+ ds+=ProcessByte8(real_byte,ds);
+ real_byte = px[DMA_XOR((current_table_address+p*2+1))];
+ ds+=ProcessByte8(real_byte,ds);
+ }
+ else
+ {
+ ds+=ProcessByte8(p,ds);
+ }
+ ++src;
+ ctrl<<=1;
+
+ if((ds-start)>=real_length)
+ return;
+ }
+ }
+}
+
+static void cps3_process_character_dma(UINT32 address)
+{
+ int i;
+
+ //printf("charDMA start:\n");
+
+ for (i=0;i<0x1000;i+=3)
+ {
+ UINT32 dat1 = LITTLE_ENDIANIZE_INT32(cps3_char_ram[i+0+(address)]);
+ UINT32 dat2 = LITTLE_ENDIANIZE_INT32(cps3_char_ram[i+1+(address)]);
+ UINT32 dat3 = LITTLE_ENDIANIZE_INT32(cps3_char_ram[i+2+(address)]);
+ UINT32 real_source = (dat3<<1)-0x400000;
+ UINT32 real_destination = dat2<<3;
+ UINT32 real_length = (((dat1&0x001fffff)+1)<<3);
+
+ /* 0x01000000 is the end of list marker, 0x13131313 is our default fill */
+ if ((dat1==0x01000000) || (dat1==0x13131313)) break;
+
+ //printf("%08x %08x %08x real_source %08x (rom %d offset %08x) real_destination %08x, real_length %08x\n", dat1, dat2, dat3, real_source, real_source/0x800000, real_source%0x800000, real_destination, real_length);
+
+ if ( (dat1&0x00e00000) ==0x00800000 )
+ {
+ /* Sets a table used by the decompression routines */
+ {
+ /* We should probably copy this, but a pointer to it is fine for our purposes as the data doesn't change */
+ current_table_address = real_source;
+ }
+ cpunum_set_input_line(0,10, ASSERT_LINE);
+ }
+ else if ( (dat1&0x00e00000) ==0x00400000 )
+ {
+ /* 6bpp DMA decompression
+ - this is used for the majority of sprites and backgrounds */
+ cps3_do_char_dma( real_source, real_destination, real_length );
+ cpunum_set_input_line(0,10, ASSERT_LINE);
+
+ }
+ else if ( (dat1&0x00e00000) ==0x00600000 )
+ {
+ /* 8bpp DMA decompression
+ - this is used on SFIII NG Sean's Stage ONLY */
+ cps3_do_alt_char_dma( real_source, real_destination, real_length);
+ cpunum_set_input_line(0,10, ASSERT_LINE);
+ }
+ else
+ {
+ printf("Unknown DMA List Command Type\n"); // warzard uses command 0, uncompressed? but for what?
+ }
+
+ }
+}
+
+static WRITE32_HANDLER( cps3_characterdma_w )
+{
+ if(DEBUG_PRINTF) printf("chardma_w %08x %08x %08x\n", offset, data, mem_mask);
+
+ if (offset==0)
+ {
+ //COMBINE_DATA(&chardma_source);
+ if (ACCESSING_LSB32)
+ {
+ chardma_source = data & 0x0000ffff;
+ }
+ if (ACCESSING_MSB32)
+ {
+ if(DEBUG_PRINTF) printf("chardma_w accessing MSB32 of offset 0");
+ }
+ }
+ else if (offset==1)
+ {
+ COMBINE_DATA(&chardma_other);
+
+ if (ACCESSING_MSB32)
+ {
+ if ((data>>16) & 0x0040)
+ {
+ UINT32 list_address;
+ list_address = (chardma_source | ((chardma_other&0x003f0000)));
+
+ //printf("chardma_w activated %08x %08x (address = cram %08x)\n", chardma_source, chardma_other, list_address*4 );
+ cps3_process_character_dma(list_address);
+ }
+ else
+ {
+ if(DEBUG_PRINTF) printf("chardma_w NOT activated %08x %08x\n", chardma_source, chardma_other );
+ }
+
+ if ((data>>16) & 0xff80)
+ if(DEBUG_PRINTF) printf("chardma_w unknown bits in activate command %08x %08x\n", chardma_source, chardma_other );
+ }
+ else
+ {
+ if(DEBUG_PRINTF) printf("chardma_w LSB32 write to activate command %08x %08x\n", chardma_source, chardma_other );
+ }
+ }
+}
+
+static WRITE32_HANDLER( cps3_irq10_ack_w )
+{
+ cpunum_set_input_line(0,10, CLEAR_LINE); return;
+}
+
+static WRITE32_HANDLER( cps3_irq12_ack_w )
+{
+ cpunum_set_input_line(0,12, CLEAR_LINE); return;
+}
+
+static WRITE32_HANDLER( cps3_unk_vidregs_w )
+{
+ COMBINE_DATA(&cps3_unk_vidregs[offset]);
+}
+
+static READ32_HANDLER( cps3_colourram_r )
+{
+ UINT16* src = (UINT16*)cps3_colourram;
+
+ return src[offset*2+1] | (src[offset*2+0]<<16);
+}
+
+static WRITE32_HANDLER( cps3_colourram_w )
+{
+// COMBINE_DATA(&cps3_colourram[offset]);
+
+ if (ACCESSING_MSB32)
+ {
+ cps3_set_mame_colours(offset*2, (data & 0xffff0000) >> 16, 0);
+ }
+
+ if (ACCESSING_LSB32)
+ {
+ cps3_set_mame_colours(offset*2+1, (data & 0x0000ffff) >> 0, 0);
+ }
+}
+
+static UINT32* cps3_mainram;
+
+/* there are more unknown writes, but you get the idea */
+static ADDRESS_MAP_START( cps3_map, ADDRESS_SPACE_PROGRAM, 32 )
+ AM_RANGE(0x00000000, 0x0007ffff) AM_ROM AM_REGION(REGION_USER1, 0) // Bios ROM
+ AM_RANGE(0x02000000, 0x0207ffff) AM_RAM AM_BASE(&cps3_mainram) // Main RAM
+
+ AM_RANGE(0x03000000, 0x030003ff) AM_RAM // 'FRAM' (SFIII memory test mode ONLY)
+
+// AM_RANGE(0x04000000, 0x0407dfff) AM_RAM AM_BASE(&cps3_spriteram)//AM_WRITE(MWA32_RAM) // Sprite RAM (jojoba tests this size)
+ AM_RANGE(0x04000000, 0x0407ffff) AM_RAM AM_BASE(&cps3_spriteram)//AM_WRITE(MWA32_RAM) // Sprite RAM
+
+ AM_RANGE(0x04080000, 0x040bffff) AM_RAM AM_READWRITE(cps3_colourram_r, cps3_colourram_w) AM_BASE(&cps3_colourram) // Colour RAM (jojoba tests this size) 0x20000 colours?!
+
+ // video registers of some kind probably
+ AM_RANGE(0x040C0000, 0x040C0003) AM_READ(cps3_40C0000_r)//?? every frame
+ AM_RANGE(0x040C0004, 0x040C0007) AM_READ(cps3_40C0004_r)//AM_READ(cps3_40C0004_r) // warzard reads this!
+// AM_RANGE(0x040C0008, 0x040C000b) AM_WRITE(MWA32_NOP)//??
+ AM_RANGE(0x040C000c, 0x040C000f) AM_READ(cps3_vbl_r)// AM_WRITE(MWA32_NOP)/
+
+ AM_RANGE(0x040C0000, 0x040C001f) AM_WRITE(cps3_unk_vidregs_w)
+ AM_RANGE(0x040C0020, 0x040C002b) AM_WRITE(MWA32_RAM) AM_BASE(&tilemap20_regs_base)
+ AM_RANGE(0x040C0030, 0x040C003b) AM_WRITE(MWA32_RAM) AM_BASE(&tilemap30_regs_base)
+ AM_RANGE(0x040C0040, 0x040C004b) AM_WRITE(MWA32_RAM) AM_BASE(&tilemap40_regs_base)
+ AM_RANGE(0x040C0050, 0x040C005b) AM_WRITE(MWA32_RAM) AM_BASE(&tilemap50_regs_base)
+
+ AM_RANGE(0x040C0060, 0x040C007f) AM_RAM AM_BASE(&cps3_fullscreenzoom)
+
+
+ AM_RANGE(0x040C0094, 0x040C009b) AM_WRITE(cps3_characterdma_w)
+
+
+ AM_RANGE(0x040C00a0, 0x040C00af) AM_WRITE(cps3_palettedma_w)
+
+
+ AM_RANGE(0x040C0084, 0x040C0087) AM_WRITE(cram_bank_w)
+ AM_RANGE(0x040C0088, 0x040C008b) AM_WRITE(cram_gfxflash_bank_w)
+
+ AM_RANGE(0x040e0000, 0x040e02ff) AM_READWRITE(cps3_sound_r, cps3_sound_w)
+
+ AM_RANGE(0x04100000, 0x041fffff) AM_READWRITE(cram_data_r, cram_data_w)
+ AM_RANGE(0x04200000, 0x043fffff) AM_READWRITE(cps3_gfxflash_r, cps3_gfxflash_w) // GFX Flash ROMS
+
+ AM_RANGE(0x05000000, 0x05000003) AM_READ( cps3_io1_r )
+ AM_RANGE(0x05000004, 0x05000007) AM_READ( cps3_io2_r )
+
+ AM_RANGE(0x05000008, 0x0500000b) AM_WRITE( MWA32_NOP ) // ?? every frame
+
+ AM_RANGE(0x05000a00, 0x05000a1f) AM_READ( cps3_unk_io_r ) // ?? every frame
+
+ AM_RANGE(0x05001000, 0x05001203) AM_READWRITE( cps3_eeprom_r, cps3_eeprom_w )
+
+ AM_RANGE(0x05040000, 0x0504ffff) AM_RAM AM_READWRITE(cps3_ssram_r,cps3_ssram_w) // 'SS' RAM (Score Screen) (text tilemap + toles)
+ //0x25050020
+ AM_RANGE(0x05050020, 0x05050023) AM_WRITE( cps3_ss_bank_base_w )
+ AM_RANGE(0x05050024, 0x05050027) AM_WRITE( cps3_ss_pal_base_w )
+
+ AM_RANGE(0x05100000, 0x05100003) AM_WRITE( cps3_irq12_ack_w )
+ AM_RANGE(0x05110000, 0x05110003) AM_WRITE( cps3_irq10_ack_w )
+
+ AM_RANGE(0x05140000, 0x05140003) AM_READWRITE( cps3_cdrom_r, cps3_cdrom_w )
+
+ AM_RANGE(0x06000000, 0x067fffff) AM_ROM AM_READWRITE( cps3_flash1_r, cps3_flash1_w ) /* Flash ROMs simm 1 */
+ AM_RANGE(0x06800000, 0x06ffffff) AM_ROM AM_READWRITE( cps3_flash2_r, cps3_flash2_w ) /* Flash ROMs simm 2 */
+
+ AM_RANGE(0xc0000000, 0xc00003ff) AM_RAM AM_WRITE( cps3_0xc0000000_ram_w ) AM_BASE(&cps3_0xc0000000_ram) /* Executes code from here */
+ADDRESS_MAP_END
+
+
+
+
+static INPUT_PORTS_START( cps3 )
+ PORT_START
+ PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
+ PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
+ PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1)
+ PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1)
+ PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
+ PORT_BIT( 0x00000020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
+ PORT_BIT( 0x00000040, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
+ PORT_BIT( 0x00000080, IP_ACTIVE_LOW, IPT_UNUSED ) // nothing here?
+ PORT_BIT( 0x00000100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
+ PORT_BIT( 0x00000200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
+ PORT_BIT( 0x00000400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
+ PORT_BIT( 0x00000800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
+ PORT_BIT( 0x00001000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
+ PORT_BIT( 0x00002000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
+ PORT_BIT( 0x00004000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
+ PORT_BIT( 0x00008000, IP_ACTIVE_LOW, IPT_UNUSED ) // nothing here?
+ PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_SERVICE1 )
+ PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME( DEF_STR( Service_Mode )) PORT_CODE(KEYCODE_F2)
+ PORT_BIT( 0x00fc0000, IP_ACTIVE_LOW, IPT_UNUSED ) // nothing here?
+ PORT_BIT( 0x01000000, IP_ACTIVE_LOW, IPT_COIN1 )
+ PORT_BIT( 0x02000000, IP_ACTIVE_LOW, IPT_COIN2 )
+ PORT_BIT( 0x04000000, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(2)
+ PORT_BIT( 0x08000000, IP_ACTIVE_LOW, IPT_UNUSED ) // nothing here?
+ PORT_BIT( 0x10000000, IP_ACTIVE_LOW, IPT_START1 )
+ PORT_BIT( 0x20000000, IP_ACTIVE_LOW, IPT_START2 )
+ PORT_BIT( 0xc0000000, IP_ACTIVE_LOW, IPT_UNUSED ) // nothing here?
+
+ PORT_START
+ PORT_BIT( 0x0001ffff, IP_ACTIVE_LOW, IPT_UNUSED ) // nothing here?
+ PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(1)
+ PORT_BIT( 0x00040000, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(1)
+ PORT_BIT( 0x00080000, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1)
+ PORT_BIT( 0x00100000, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2)
+ PORT_BIT( 0x00200000, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(2)
+ PORT_BIT( 0xffc00000, IP_ACTIVE_LOW, IPT_UNUSED ) // nothing here?
+INPUT_PORTS_END
+
+static INTERRUPT_GEN(cps3_vbl_interrupt)
+{
+ cpunum_set_input_line(0,12, ASSERT_LINE);
+}
+
+static INTERRUPT_GEN(cps3_other_interrupt)
+{
+ // this seems to need to be periodic (see the life bar portraits in sfiii2
+ // but also triggered on certain dma events (or warzard locks up in attract)
+ // what is the REAL source of IRQ10??
+ cpunum_set_input_line(0,10, ASSERT_LINE);
+}
+
+
+//static struct sh2_config sh2cp_conf_slave = { 1 };
+
+
+static struct CustomSound_interface custom_interface =
+{
+ cps3_sh_start
+};
+
+
+static emu_timer* fastboot_timer;
+
+static TIMER_CALLBACK( fastboot_timer_callback )
+{
+ UINT32 *rom = (UINT32*)decrypted_gamerom;//memory_region ( REGION_USER4 );
+ if (cps3_isSpecial) rom = (UINT32*)memory_region(REGION_USER4);
+
+// printf("fastboot callback %08x %08x", rom[0], rom[1]);
+ cpunum_set_reg(0,SH2_PC, rom[0]);
+ cpunum_set_reg(0,SH2_R15, rom[1]);
+ cpunum_set_reg(0,SH2_VBR, 0x6000000);
+}
+
+static SCSIConfigTable dev_table =
+{
+ 1, /* 1 SCSI device */
+ { { SCSI_ID_1, 0, SCSI_DEVICE_CDROM } } /* SCSI ID 2, using CD 0, and it's a CD-ROM */
+};
+
+static struct WD33C93interface scsi_intf =
+{
+ &dev_table, /* SCSI device table */
+ NULL /* command completion IRQ */
+};
+
+static MACHINE_RESET( cps3 )
+{
+ wd33c93_init(&scsi_intf);
+
+ if (cps3_use_fastboot)
+ {
+ fastboot_timer = timer_alloc(fastboot_timer_callback);
+ // printf("reset\n");
+ timer_adjust(fastboot_timer, attotime_zero, 0, attotime_zero);
+ }
+}
+
+#define MASTER_CLOCK 42954500
+
+
+
+static void precopy_to_flash(void)
+{
+ int i;
+ /* precopy program roms, ok, sfiii2 tests pass, others fail because of how the decryption affects testing */
+ for (i=0;i<0x800000;i+=4)
+ {
+ UINT32* romdata = (UINT32*)memory_region(REGION_USER4);
+ UINT32 data;
+ UINT8* ptr1 = intelflash_getmemptr(0);
+ UINT8* ptr2 = intelflash_getmemptr(1);
+ UINT8* ptr3 = intelflash_getmemptr(2);
+ UINT8* ptr4 = intelflash_getmemptr(3);
+
+ data = romdata[i/4];
+
+ ptr1[i/4] = (data & 0xff000000)>>24;
+ ptr2[i/4] = (data & 0x00ff0000)>>16;
+ ptr3[i/4] = (data & 0x0000ff00)>>8;
+ ptr4[i/4] = (data & 0x000000ff)>>0;
+ }
+
+ for (i=0;i<0x800000;i+=4)
+ {
+ UINT32* romdata = (UINT32*)memory_region(REGION_USER4);
+ UINT32 data;
+ UINT8* ptr1 = intelflash_getmemptr(4);
+ UINT8* ptr2 = intelflash_getmemptr(5);
+ UINT8* ptr3 = intelflash_getmemptr(6);
+ UINT8* ptr4 = intelflash_getmemptr(7);
+
+ data = romdata[(0x800000+i)/4];
+
+ ptr1[i/4] = (data & 0xff000000)>>24;
+ ptr2[i/4] = (data & 0x00ff0000)>>16;
+ ptr3[i/4] = (data & 0x0000ff00)>>8;
+ ptr4[i/4] = (data & 0x000000ff)>>0;
+ }
+
+ /* precopy gfx roms, good, tests pass */
+ {
+ UINT32 thebase;
+ int flashnum = 8;
+ UINT32* romdata = (UINT32*)memory_region(REGION_USER5);
+
+ for (thebase = 0;thebase < memory_region_length(REGION_USER5)/2; thebase+=0x200000)
+ {
+ // printf("flashnums %d. %d\n",flashnum, flashnum+1);
+
+ for (i=0;i<0x200000;i+=2)
+ {
+ UINT8* ptr1 = intelflash_getmemptr(flashnum);
+ UINT8* ptr2 = intelflash_getmemptr(flashnum+1);
+ UINT32 dat = romdata[(thebase+i)/2];
+
+ ptr1[BYTE_XOR_LE(i+1)] = (dat&0xff000000)>>24;
+ ptr2[BYTE_XOR_LE(i+1)] = (dat&0x00ff0000)>>16;
+
+ ptr1[BYTE_XOR_LE(i+0)] = (dat&0x0000ff00)>>8;
+ ptr2[BYTE_XOR_LE(i+0)] = (dat&0x000000ff)>>0;
+ }
+ flashnum+=2;
+ }
+ }
+}
+
+
+// make a copy in the regions we execute code / draw gfx from
+static void copy_from_nvram(void)
+{
+
+ int i;
+ /* copy + decrypt program roms which have been loaded from flashroms/nvram */
+ for (i=0;i<0x800000;i+=4)
+ {
+ UINT32* romdata = (UINT32*)memory_region(REGION_USER4);
+ UINT32* romdata2 = (UINT32*)decrypted_gamerom;
+ UINT32 data;
+ UINT8* ptr1 = intelflash_getmemptr(0);
+ UINT8* ptr2 = intelflash_getmemptr(1);
+ UINT8* ptr3 = intelflash_getmemptr(2);
+ UINT8* ptr4 = intelflash_getmemptr(3);
+
+ data = ((ptr1[i/4]<<24) | (ptr2[i/4]<<16) | (ptr3[i/4]<<8) | (ptr4[i/4]<<0));
+
+ // printf("%08x %08x %08x %08x\n",romdata[i/4],data, romdata2[i/4], data ^ cps3_mask(i+0x6000000, cps3_key1, cps3_key2));
+ romdata[i/4] = data;
+ romdata2[i/4] = data ^ cps3_mask(i+0x6000000, cps3_key1, cps3_key2);
+
+ }
+
+ for (i=0;i<0x800000;i+=4)
+ {
+ UINT32* romdata = (UINT32*)memory_region(REGION_USER4);
+ UINT32* romdata2 = (UINT32*)decrypted_gamerom;
+ UINT32 data;
+ UINT8* ptr1 = intelflash_getmemptr(4);
+ UINT8* ptr2 = intelflash_getmemptr(5);
+ UINT8* ptr3 = intelflash_getmemptr(6);
+ UINT8* ptr4 = intelflash_getmemptr(7);
+
+ romdata += 0x800000/4;
+ romdata2 += 0x800000/4;
+
+ data = ((ptr1[i/4]<<24) | (ptr2[i/4]<<16) | (ptr3[i/4]<<8) | (ptr4[i/4]<<0));
+
+ // printf("%08x %08x %08x %08x\n",romdata[i/4],data, romdata2[i/4], data ^ cps3_mask(i+0x6800000, cps3_key1, cps3_key2) );
+ romdata[i/4] = data;
+ romdata2[i/4] = data ^ cps3_mask(i+0x6800000, cps3_key1, cps3_key2);
+ }
+
+ /* copy gfx from loaded flashroms to user reigon 5, where it's used */
+ {
+ UINT32 thebase;
+ int flashnum = 8;
+ UINT32* romdata = (UINT32*)memory_region(REGION_USER5);
+ int countoffset = 0;
+
+ for (thebase = 0;thebase < memory_region_length(REGION_USER5)/2; thebase+=0x200000)
+ {
+ // printf("flashnums %d. %d\n",flashnum, flashnum+1);
+
+ for (i=0;i<0x200000;i+=2)
+ {
+ UINT8* ptr1 = intelflash_getmemptr(flashnum);
+ UINT8* ptr2 = intelflash_getmemptr(flashnum+1);
+ UINT32 dat = (ptr1[i+0]<<8) |
+ (ptr1[i+1]<<24) |
+ (ptr2[i+0]<<0) |
+ (ptr2[i+1]<<16);
+
+ //printf("%08x %08x\n",romdata[countoffset],dat);
+ romdata[countoffset] = dat;
+
+ countoffset++;
+ }
+ flashnum+=2;
+ }
+ }
+
+
+ /*
+ {
+ FILE *fp;
+ const char *gamename = Machine->gamedrv->name;
+ char filename[256];
+ sprintf(filename, "%s_bios.dump", gamename);
+
+ fp=fopen(filename, "w+b");
+ if (fp)
+ {
+ fwrite(rom, 0x080000, 1, fp);
+ fclose(fp);
+ }
+ }
+ */
+
+}
+
+static NVRAM_HANDLER( cps3 )
+{
+ int i;
+
+ if (read_or_write)
+ {
+ //printf("read_write\n");
+ mame_fwrite(file, cps3_eeprom, 0x400);
+ for (i=0;i<48;i++)
+ nvram_handler_intelflash( machine, i, file, read_or_write );
+ }
+ else if (file)
+ {
+ //printf("file\n");
+ mame_fread(file, cps3_eeprom, 0x400);
+ for (i=0;i<48;i++)
+ nvram_handler_intelflash( machine, i, file, read_or_write );
+
+ copy_from_nvram(); // copy data from flashroms back into user regions + decrypt into regions we execute/draw from.
+ }
+ else
+ {
+ //printf("nothing?\n");
+ precopy_to_flash(); // attempt to copy data from user regions into flash roms (incase this is a NOCD set)
+ copy_from_nvram(); // copy data from flashroms back into user regions + decrypt into regions we execute/draw from.
+ }
+
+
+}
+
+
+
+
+
+static MACHINE_DRIVER_START( cps3 )
+ /* basic machine hardware */
+ MDRV_CPU_ADD_TAG("main", SH2, 6250000*4) // external clock is 6.25 Mhz, it sets the intenral multiplier to 4x (this should probably be handled in the core..)
+ MDRV_CPU_PROGRAM_MAP(cps3_map,0)
+ MDRV_CPU_VBLANK_INT(cps3_vbl_interrupt,1)
+ MDRV_CPU_PERIODIC_INT(cps3_other_interrupt,80) /* ?source? */
+
+ MDRV_SCREEN_REFRESH_RATE(60)
+ MDRV_SCREEN_VBLANK_TIME(DEFAULT_REAL_60HZ_VBLANK_DURATION)
+
+
+ /* video hardware */
+ MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
+ MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
+ MDRV_SCREEN_SIZE(512*2, 224*2)
+ MDRV_SCREEN_VISIBLE_AREA(0, (384*1)-1, 0, 223/*511*/)
+
+ MDRV_MACHINE_RESET(cps3)
+ MDRV_NVRAM_HANDLER( cps3 )
+ MDRV_PALETTE_LENGTH(0x10000) // actually 0x20000 ...
+
+ MDRV_VIDEO_START(cps3)
+ MDRV_VIDEO_UPDATE(cps3)
+
+ /* sound hardware */
+ MDRV_SPEAKER_STANDARD_STEREO("left", "right")
+
+ MDRV_SOUND_ADD(CUSTOM, MASTER_CLOCK / 3)
+ MDRV_SOUND_CONFIG(custom_interface)
+ MDRV_SOUND_ROUTE(1, "left", 1.0)
+ MDRV_SOUND_ROUTE(0, "right", 1.0)
+MACHINE_DRIVER_END
+
+
+ROM_START( sfiii )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "sfiii_japan.29f400.u2", 0x000000, 0x080000, CRC(74205250) SHA1(c3e83ace7121d32da729162662ec6b5285a31211) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* Program Code Region */
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* GFX Region */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE_READONLY( "sf3000", 0, MD5(cdc5c5423bd8c053de7cdd927dc60da7) SHA1(cc72c9eb2096f4d51f2cf6df18f29fd79d05067c) )
+ROM_END
+
+ROM_START( sfiiiu )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "sfiii_usa.29f400.u2", 0x000000, 0x080000, CRC(fb172a8e) SHA1(48ebf59910f246835f7dc0c588da30f7a908072f) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* Program Code Region */
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* GFX Region */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE_READONLY( "sf3000", 0, MD5(cdc5c5423bd8c053de7cdd927dc60da7) SHA1(cc72c9eb2096f4d51f2cf6df18f29fd79d05067c) )
+ROM_END
+
+ROM_START( sfiii2 )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "sfiii2_japan.29f400.u2", 0x000000, 0x080000, CRC(faea0a3e) SHA1(a03cd63bcf52e4d57f7a598c8bc8e243694624ec) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* Program Code Region */
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* GFX Region */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE_READONLY( "3ga000", 0, MD5(941c7e8d0838db9880ea7bf169ad310d) SHA1(76e9fdef020c4b85a10aa8828a63e67c7dca22bd) )
+ROM_END
+
+ROM_START( sfiii2u )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "sfiii2_usa.29f400.u2", 0x000000, 0x080000, CRC(75dd72e0) SHA1(5a12d6ea6734df5de00ecee6f9ef470749d2f242) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* Program Code Region */
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* GFX Region */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE_READONLY( "3ga000", 0, MD5(941c7e8d0838db9880ea7bf169ad310d) SHA1(76e9fdef020c4b85a10aa8828a63e67c7dca22bd) )
+ROM_END
+
+ROM_START( sfiii3 )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "sfiii3_usa.29f400.u2", 0x000000, 0x080000, CRC(ecc545c1) SHA1(e39083820aae914fd8b80c9765129bedb745ceba) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* Program Code Region */
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* GFX Region */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE_READONLY( "33s000", 0, MD5(f159ad85cc94ced3ddb9ef5e92173a9f) SHA1(47c7ae0f2dc47c7d28bdf66d378a3aaba4c99c75) )
+ROM_END
+
+ROM_START( sfiii3a )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "sfiii3_usa.29f400.u2", 0x000000, 0x080000, CRC(ecc545c1) SHA1(e39083820aae914fd8b80c9765129bedb745ceba) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* Program Code Region */
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* GFX Region */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE_READONLY( "cap-33s-2", 0, SHA1(24e78b8c66fb1573ffd642ee51607f3b53ed40b7) MD5(cf63f3dbcc2653b95709133fe79c7225) )
+ROM_END
+
+ROM_START( redearth )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "warzard_euro.29f400.u2", 0x000000, 0x080000, CRC(02e0f336) SHA1(acc37e830dfeb9674f5a0fb24f4cc23217ae4ff5) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* Program Code Region */
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* GFX Region */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE_READONLY( "wzd000", 0, MD5(028ff12a4ce34118dd0091e87c8cdd08) SHA1(6d4e6b7fff4ff3f04e349479fa5a1cbe63e673b8) )
+ROM_END
+
+ROM_START( warzard )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "warzard_japan.29f400.u2", 0x000000, 0x080000, CRC(f8e2f0c6) SHA1(93d6a986f44c211fff014e55681eca4d2a2774d6) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* Program Code Region */
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* GFX Region */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE_READONLY( "wzd000", 0, MD5(028ff12a4ce34118dd0091e87c8cdd08) SHA1(6d4e6b7fff4ff3f04e349479fa5a1cbe63e673b8) )
+ROM_END
+
+
+ROM_START( jojo )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "jojo_japan.29f400.u2", 0x000000, 0x080000, CRC(02778f60) SHA1(a167f9ebe030592a0cdb0c6a3c75835c6a43be4c) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* Program Code Region */
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* GFX Region */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE_READONLY( "jjk000", 0, MD5(05440ecf90e836207a27a99c817a3328) SHA1(d5a11315ac21e573ffe78e63602ec2cb420f361f) )
+ROM_END
+
+ROM_START( jojoalt )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "jojo_japan.29f400.u2", 0x000000, 0x080000, CRC(02778f60) SHA1(a167f9ebe030592a0cdb0c6a3c75835c6a43be4c) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* Program Code Region */
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* GFX Region */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE_READONLY( "cap-jjk-160", 0, SHA1(74fb14d838d98c3e10baa08e6f7b2464d840dcf0) MD5(93cc16f11a88c8f5268cb96baebc0a13) )
+ROM_END
+
+ROM_START( jojoba )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "jojoba_japan.29f400.u2", 0x000000, 0x080000, CRC(3085478c) SHA1(055eab1fc42816f370a44b17fd7e87ffcb10e8b7) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* Program Code Region */
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* GFX Region */
+
+ DISK_REGION( REGION_DISKS )
+ DISK_IMAGE_READONLY( "jjm000", 0, MD5(bf6b90334bf1f6bd8dbfed737face2d6) SHA1(688520bb83ccbf4b31c3bfe26bd0cc8292a8c558) )
+ROM_END
+
+
+/* NO CD sets - use NO CD BIOS roms */
+
+ROM_START( sfiiin )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "sfiii_asia_nocd.29f400.u2", 0x000000, 0x080000, CRC(73e32463) SHA1(45d144e533e4b20cc5a744ca4f618e288430c601) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* cd content region */
+ ROM_LOAD( "10", 0x0000000, 0x800000, CRC(e896dc27) SHA1(47623820c64b72e69417afcafaacdd2c318cde1c) )
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* cd content region */
+ ROM_LOAD( "30", 0x0000000, 0x800000, CRC(98c2d07c) SHA1(604ce4a16170847c10bc233a47a47a119ce170f7) )
+ ROM_LOAD( "31", 0x0800000, 0x800000, CRC(7115a396) SHA1(b60a74259e3c223138e66e68a3f6457694a0c639) )
+ ROM_LOAD( "40", 0x1000000, 0x800000, CRC(839f0972) SHA1(844e43fcc157b7c774044408bfe918c49e174cdb) )
+ ROM_LOAD( "41", 0x1800000, 0x800000, CRC(8a8b252c) SHA1(9ead4028a212c689d7a25746fbd656dca6f938e8) )
+ ROM_LOAD( "50", 0x2000000, 0x400000, CRC(58933dc2) SHA1(1f1723be676a817237e96b6e20263b935c59daae) )
+ROM_END
+
+
+ROM_START( sfiii2n )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "sfiii2_asia_nocd.29f400.u2", 0x000000, 0x080000, CRC(fd297c0d) SHA1(4323deda2789f104b53f32a663196ec16de73215) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* cd content region */
+ ROM_LOAD( "10", 0x0000000, 0x800000, CRC(682b014a) SHA1(abd5785f4b7c89584d6d1cf6fb61a77d7224f81f) )
+ ROM_LOAD( "20", 0x0800000, 0x800000, CRC(38090460) SHA1(aaade89b8ccdc9154f97442ca35703ec538fe8be) )
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* cd content region */
+ ROM_LOAD( "30", 0x0000000, 0x800000, CRC(77c197c0) SHA1(944381161462e65de7ae63a656658f3fbe44727a) )
+ ROM_LOAD( "31", 0x0800000, 0x800000, CRC(7470a6f2) SHA1(850b2e20afe8a5a1f0d212d9abe002cb5cf14d22) )
+ ROM_LOAD( "40", 0x1000000, 0x800000, CRC(01a85ced) SHA1(802df3274d5f767636b2785606e0558f6d3b9f13) )
+ ROM_LOAD( "41", 0x1800000, 0x800000, CRC(fb346d74) SHA1(57570f101a170aa7e83e84e4b7cbdc63a11a486a) )
+ ROM_LOAD( "50", 0x2000000, 0x800000, CRC(32f79449) SHA1(44b1f2a640ab4abc23ff47e0edd87fbd0b345c06) )
+ ROM_LOAD( "51", 0x2800000, 0x800000, CRC(1102b8eb) SHA1(c7dd2ee3a3214c6ec47a03fe3e8c941775d57f76) )
+ROM_END
+
+
+ROM_START( sfiii3n )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "sfiii3_japan_nocd.29f400.u2", 0x000000, 0x080000, CRC(1edc6366) SHA1(60b4b9adeb030a33059d74fdf03873029e465b52) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* cd content region */
+ ROM_LOAD( "10", 0x0000000, 0x800000, CRC(77233d39) SHA1(59c3f890fdc33a7d8dc91e5f9c4e7b7019acfb00) )
+ ROM_LOAD( "20", 0x0800000, 0x800000, CRC(5ca8faba) SHA1(71c12638ae7fa38b362d68c3ccb4bb3ccd67f0e9) )
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* cd content region */
+ ROM_LOAD( "30", 0x0000000, 0x800000, CRC(b37cf960) SHA1(60310f95e4ecedee85846c08ccba71e286cda73b) )
+ ROM_LOAD( "31", 0x0800000, 0x800000, CRC(450ec982) SHA1(1cb3626b8479997c4f1b29c41c81cac038fac31b) )
+ ROM_LOAD( "40", 0x1000000, 0x800000, CRC(632c965f) SHA1(9a46b759f5dee35411fd6446c2457c084a6dfcd8) )
+ ROM_LOAD( "41", 0x1800000, 0x800000, CRC(7a4c5f33) SHA1(f33cdfe247c7caf9d3d394499712f72ca930705e) )
+ ROM_LOAD( "50", 0x2000000, 0x800000, CRC(8562358e) SHA1(8ed78f6b106659a3e4d94f38f8a354efcbdf3aa7) )
+ ROM_LOAD( "51", 0x2800000, 0x800000, CRC(7baf234b) SHA1(38feb45d6315d771de5f9ae965119cb25bae2a1e) )
+ ROM_LOAD( "60", 0x3000000, 0x800000, CRC(bc9487b7) SHA1(bc2cd2d3551cc20aa231bba425ff721570735eba) )
+ ROM_LOAD( "61", 0x3800000, 0x800000, CRC(b813a1b1) SHA1(16de0ee3dfd6bf33d07b0ff2e797ebe2cfe6589e) )
+ROM_END
+
+ROM_START( sfiii3an )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "sfiii3_japan_nocd.29f400.u2", 0x000000, 0x080000, CRC(1edc6366) SHA1(60b4b9adeb030a33059d74fdf03873029e465b52) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* cd content region */
+ ROM_LOAD( "10", 0x0000000, 0x800000, CRC(ba7f76b2) SHA1(6b396596dea009b34af17484919ae37eda53ec65) )
+ ROM_LOAD( "20", 0x0800000, 0x800000, CRC(5ca8faba) SHA1(71c12638ae7fa38b362d68c3ccb4bb3ccd67f0e9) )
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* cd content region */
+ ROM_LOAD( "30", 0x0000000, 0x800000, CRC(b37cf960) SHA1(60310f95e4ecedee85846c08ccba71e286cda73b) )
+ ROM_LOAD( "31", 0x0800000, 0x800000, CRC(450ec982) SHA1(1cb3626b8479997c4f1b29c41c81cac038fac31b) )
+ ROM_LOAD( "40", 0x1000000, 0x800000, CRC(632c965f) SHA1(9a46b759f5dee35411fd6446c2457c084a6dfcd8) )
+ ROM_LOAD( "41", 0x1800000, 0x800000, CRC(7a4c5f33) SHA1(f33cdfe247c7caf9d3d394499712f72ca930705e) )
+ ROM_LOAD( "50", 0x2000000, 0x800000, CRC(8562358e) SHA1(8ed78f6b106659a3e4d94f38f8a354efcbdf3aa7) )
+ ROM_LOAD( "51", 0x2800000, 0x800000, CRC(7baf234b) SHA1(38feb45d6315d771de5f9ae965119cb25bae2a1e) )
+ ROM_LOAD( "60", 0x3000000, 0x800000, CRC(bc9487b7) SHA1(bc2cd2d3551cc20aa231bba425ff721570735eba) )
+ ROM_LOAD( "61", 0x3800000, 0x800000, CRC(b813a1b1) SHA1(16de0ee3dfd6bf33d07b0ff2e797ebe2cfe6589e) )
+ROM_END
+
+ROM_START( jojon )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "jojo_asia_nocd.29f400.u2", 0x000000, 0x080000, CRC(05b4f953) SHA1(c746c7bb5359acc9adced817cb4870b1912eaefd) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* cd content region */
+ ROM_LOAD( "10", 0x0000000, 0x800000, CRC(e40dc123) SHA1(517e7006349b5a8fd6c30910362583f48d009355) )
+ ROM_LOAD( "20", 0x0800000, 0x800000, CRC(0571e37c) SHA1(1aa28ef6ea1b606a55d0766480b3ee156f0bca5a) )
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* cd content region */
+ ROM_LOAD( "30", 0x0000000, 0x800000, CRC(1d99181b) SHA1(25c216de16cefac2d5892039ad23d07848a457e6) )
+ ROM_LOAD( "31", 0x0800000, 0x800000, CRC(6889fbda) SHA1(53a51b993d319d81a604cdf70b224955eacb617e) )
+ ROM_LOAD( "40", 0x1000000, 0x800000, CRC(8069f9de) SHA1(7862ee104a2e9034910dd592687b40ebe75fa9ce) )
+ ROM_LOAD( "41", 0x1800000, 0x800000, CRC(9c426823) SHA1(1839dccc7943a44063e8cb2376cd566b24e8b797) )
+ ROM_LOAD( "50", 0x2000000, 0x400000, CRC(1c749cc7) SHA1(23df741360476d8035c68247e645278fbab53b59) )
+ROM_END
+
+ROM_START( jojoaltn )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "jojo_asia_nocd.29f400.u2", 0x000000, 0x080000, CRC(05b4f953) SHA1(c746c7bb5359acc9adced817cb4870b1912eaefd) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* cd content region */
+ ROM_LOAD( "10", 0x0000000, 0x800000, CRC(bc612872) SHA1(18930f2906176b54a9b8bec56f06dda3362eb418) )
+ ROM_LOAD( "20", 0x0800000, 0x800000, CRC(0e1daddf) SHA1(34bb4e0fb86258095a7b20f60174453195f3735a) )
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* cd content region */
+ ROM_LOAD( "30", 0x0000000, 0x800000, CRC(1d99181b) SHA1(25c216de16cefac2d5892039ad23d07848a457e6) )
+ ROM_LOAD( "31", 0x0800000, 0x800000, CRC(6889fbda) SHA1(53a51b993d319d81a604cdf70b224955eacb617e) )
+ ROM_LOAD( "40", 0x1000000, 0x800000, CRC(8069f9de) SHA1(7862ee104a2e9034910dd592687b40ebe75fa9ce) )
+ ROM_LOAD( "41", 0x1800000, 0x800000, CRC(9c426823) SHA1(1839dccc7943a44063e8cb2376cd566b24e8b797) )
+ ROM_LOAD( "50", 0x2000000, 0x400000, CRC(1c749cc7) SHA1(23df741360476d8035c68247e645278fbab53b59) )
+ROM_END
+
+ROM_START( jojoban )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "jojoba_japan_nocd.29f400.u2", 0x000000, 0x080000, CRC(4dab19f5) SHA1(ba07190e7662937fc267f07285c51e99a45c061e) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* cd content region */
+ ROM_LOAD( "10", 0x000000, 0x800000, CRC(6e2490f6) SHA1(75cbf1e39ad6362a21c937c827e492d927b7cf39) )
+ ROM_LOAD( "20", 0x800000, 0x800000, CRC(1293892b) SHA1(b1beafac1a9c4b6d0640658af8a3eb359e76eb25) )
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* cd content region */
+ ROM_LOAD( "30", 0x0000000, 0x800000, CRC(d25c5005) SHA1(93a19a14783d604bb42feffbe23eb370d11281e8) )
+ ROM_LOAD( "31", 0x0800000, 0x800000, CRC(51bb3dba) SHA1(39e95a05882909820b3efa6a3b457b8574012638) )
+ ROM_LOAD( "40", 0x1000000, 0x800000, CRC(94dc26d4) SHA1(5ae2815142972f322886eea4885baf2b82563ab1) )
+ ROM_LOAD( "41", 0x1800000, 0x800000, CRC(1c53ee62) SHA1(e096bf3cb6fbc3d45955787b8f3213abcd76d120) )
+ ROM_LOAD( "50", 0x2000000, 0x800000, CRC(36e416ed) SHA1(58d0e95cc13f39bc171165468ce72f4f17b8d8d6) )
+ ROM_LOAD( "51", 0x2800000, 0x800000, CRC(eedf19ca) SHA1(a7660bf9ff87911afb4f83b64456245059986830) )
+ROM_END
+
+ROM_START( jojobane )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "jojoba_euro_nocd.29f400.u2", 0x000000, 0x080000, CRC(1ee2d679) SHA1(9e129b454a376606b3f7e8aec64de425cf9c635c) )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* cd content region */
+ ROM_LOAD( "10", 0x000000, 0x800000, CRC(6e2490f6) SHA1(75cbf1e39ad6362a21c937c827e492d927b7cf39) )
+ ROM_LOAD( "20", 0x800000, 0x800000, CRC(1293892b) SHA1(b1beafac1a9c4b6d0640658af8a3eb359e76eb25) )
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* cd content region */
+ ROM_LOAD( "30", 0x0000000, 0x800000, CRC(d25c5005) SHA1(93a19a14783d604bb42feffbe23eb370d11281e8) )
+ ROM_LOAD( "31", 0x0800000, 0x800000, CRC(51bb3dba) SHA1(39e95a05882909820b3efa6a3b457b8574012638) )
+ ROM_LOAD( "40", 0x1000000, 0x800000, CRC(94dc26d4) SHA1(5ae2815142972f322886eea4885baf2b82563ab1) )
+ ROM_LOAD( "41", 0x1800000, 0x800000, CRC(1c53ee62) SHA1(e096bf3cb6fbc3d45955787b8f3213abcd76d120) )
+ ROM_LOAD( "50", 0x2000000, 0x800000, CRC(36e416ed) SHA1(58d0e95cc13f39bc171165468ce72f4f17b8d8d6) )
+ ROM_LOAD( "51", 0x2800000, 0x800000, CRC(eedf19ca) SHA1(a7660bf9ff87911afb4f83b64456245059986830) )
+ROM_END
+
+
+ROM_START( redeartn )
+ ROM_REGION32_BE( 0x080000, REGION_USER1, 0 ) /* bios region */
+ ROM_LOAD( "redearth_nocd.bios", 0x000000, 0x080000, NO_DUMP )
+
+ ROM_REGION32_BE( 0x800000*2, REGION_USER4, ROMREGION_ERASEFF ) /* cd content region */
+ ROM_LOAD( "10", 0x000000, 0x800000, CRC(68188016) SHA1(93aaac08cb5566c33aabc16457085b0a36048019) )
+ ROM_REGION16_BE( 0x800000*10, REGION_USER5, ROMREGION_ERASEFF ) /* cd content region */
+ ROM_LOAD( "30", 0x0000000, 0x800000, CRC(074cab4d) SHA1(4cb6cc9cce3b1a932b07058a5d723b3effa23fcf) )
+ ROM_LOAD( "31", 0x0800000, 0x800000, CRC(14e2cad4) SHA1(9958a4e315e4476e4791a6219b93495413c7b751) )
+ ROM_LOAD( "40", 0x1000000, 0x800000, CRC(72d98890) SHA1(f40926c52cb7a71b0ef0027a0ea38bbc7e8b31b0) )
+ ROM_LOAD( "41", 0x1800000, 0x800000, CRC(88ccb33c) SHA1(1e7af35d186d0b4e45b6c27458ddb9cfddd7c9bc) )
+ ROM_LOAD( "50", 0x2000000, 0x400000, CRC(2f5b44bd) SHA1(7ffdbed5b6899b7e31414a0828e04543d07435e4) )
+ROM_END
+
+/* Idle loop skipping speedups */
+static UINT32 cps3_speedup_ram_address;
+static UINT32 cps3_speedup_code_address;
+
+struct cps3_speedups
+{
+ const char *name; /* game driver name */
+ const UINT32 ram_address;
+ const UINT32 code_address;
+};
+
+static const struct cps3_speedups speedup_table[] =
+{
+ // name mainram address code address
+ { "jojo", 0x223c0, 0x600065c },
+ { "jojon", 0x223c0, 0x600065c },
+ { "jojoalt", 0x223d8, 0x600065c },
+ { "jojoaltn", 0x223d8, 0x600065c },
+ { "jojoba", 0x267dc, 0x600065c },
+ { "jojoban", 0x267dc, 0x600065c },
+ { "jojobane", 0x267dc, 0x600065c },
+ { "sfiii", 0x0cc6c, 0x6000884 },
+ { "sfiiiu", 0x0cc6c, 0x6000884 },
+ { "sfiiin", 0x0cc6c, 0x6000884 },
+ { "sfiii2", 0x0dfe4, 0x6000884 },
+ { "sfiii2u", 0x0dfe4, 0x6000884 },
+ { "sfiii2n", 0x0dfe4, 0x6000884 },
+ { "sfiii3", 0x0d794, 0x6000884 },
+ { "sfiii3n", 0x0d794, 0x6000884 },
+ { "sfiii3a", 0x0d794, 0x6000884 },
+ { "sfiii3an", 0x0d794, 0x6000884 },
+ { "warzard", 0x2136c, 0x600194e },
+ { "redearth", 0x2136c, 0x600194e },
+ { 0 } // end of table
+};
+
+static READ32_HANDLER(cps3_speedup_r)
+{
+// printf("speedup read %08x %d\n",activecpu_get_pc(), cpu_getexecutingcpu());
+ if (cpu_getexecutingcpu()>=0) // prevent cheat search crash..
+ if (activecpu_get_pc()==cps3_speedup_code_address) {cpu_spinuntil_int();return cps3_mainram[cps3_speedup_ram_address/4];}
+
+ return cps3_mainram[cps3_speedup_ram_address/4];
+}
+
+static DRIVER_INIT( cps3_speedups )
+{
+ const char *gamename = machine->gamedrv->name;
+ const struct cps3_speedups *k = &speedup_table[0];
+
+ cps3_speedup_ram_address = 0;
+ cps3_speedup_code_address = 0;
+
+ while (k->name)
+ {
+ if (strcmp(k->name, gamename) == 0)
+ {
+ cps3_speedup_ram_address = k->ram_address;
+ cps3_speedup_code_address = k->code_address;
+ break;
+ }
+ ++k;
+ }
+
+ //printf("speedup %08x %08x\n",cps3_speedup_ram_address,cps3_speedup_code_address);
+
+ if (cps3_speedup_code_address!=0) memory_install_read32_handler(0, ADDRESS_SPACE_PROGRAM, cps3_speedup_ram_address+0x02000000, cps3_speedup_ram_address+0x02000003, 0, 0, cps3_speedup_r );
+}
+
+
+/* PLEASE leave the region / NOCD information here even once CD emulation is done, its useful for debugging */
+
+
+static DRIVER_INIT( jojo )
+{
+ // XXXXXX 0
+ // JAPAN 1
+ // ASIA 2
+ // EURO 3
+ // USA 4
+ // HISPANIC 5
+ // BRAZIL 6
+ // OCEANIA 7
+
+ // DEVELOPMENT VERSION add 0x70 mask!
+
+// UINT32 *rom = (UINT32*)memory_region ( REGION_USER1 );
+// rom[0x1fec8/4]^=0x00000001; // region hack (clear jpn)
+
+// rom[0x1fec8/4]^=0x00000004; // region
+// rom[0x1fec8/4]^=0x00000070; // DEV mode
+// rom[0x1fecc/4]^=0x01000000; // nocd
+
+ cps3_use_fastboot = 0;
+ driver_init_cps3crpt(machine);
+ driver_init_cps3_speedups(machine);
+ driver_init_cps3_testhacks(machine);
+
+
+}
+
+static DRIVER_INIT (jojoba)
+{
+ // XXXXXX 0
+ // JAPAN 1
+ // ASIA 2
+ // EURO 3
+ // USA 4
+ // HISPANIC 5
+ // BRAZIL 6
+ // OCEANIA 7
+
+ // DEVELOPMENT VERSION add 0x70 mask!
+
+// UINT32 *rom = (UINT32*)memory_region ( REGION_USER1 );
+// rom[0x1fec8/4]^=0x00000001; // region (clear jpn)
+// rom[0x1fec8/4]^=0x00000002; // region
+// rom[0x1fec8/4]^=0x00000070; // DEV mode
+// rom[0x1fecc/4]^=0x01000000; // nocd
+
+ driver_init_cps3crpt(machine);
+ driver_init_cps3_speedups(machine);
+ driver_init_cps3_testhacks(machine);
+
+ cps3_use_fastboot = 0;
+}
+
+
+static DRIVER_INIT( warzard )
+{
+ // JAPAN 1
+ // ASIA 2
+ // EURO 3
+ // USA 4
+ // HISPANIC 5
+ // BRAZIL 6
+ // OCEANIA 7
+ // ASIA NCD 8
+
+// UINT32 *rom = (UINT32*)memory_region ( REGION_USER1 );
+// rom[0x1fed8/4]^=0x00000001; // clear region to 0 (invalid)
+// rom[0x1fed8/4]^=0x00000008; // region 8 - ASIA NO CD - doesn't actually skip the CD test on startup,
+ // only during game, must be another flag somewhere too, and we don't have
+ // any actual NCD dumps to compare (or it expects SCSI to report there being
+ // no cd drive?)
+
+ driver_init_cps3crpt(machine);
+ driver_init_cps3_speedups(machine);
+ driver_init_cps3_testhacks(machine);
+
+ cps3_use_fastboot = 0; // required due to cd check, even with ASIA NO CD selected, not req. with CD emulation
+}
+
+
+static DRIVER_INIT( sfiii )
+{
+ // JAPAN 1
+ // ASIA NCD 2
+ // EURO 3
+ // USA 4
+ // HISPANIC 5
+ // BRAZIL 6
+ // OCEANIA 7
+ // ASIA 8
+
+ // bios rom also lists korea, but game rom does not.
+
+// UINT32 *rom = (UINT32*)memory_region ( REGION_USER1 );
+// rom[0x1fec8/4]^=0x00000001; // region (clear region)
+// rom[0x1fec8/4]^=0x00000008; // region
+// rom[0x1fecc/4]^=0x01000000; // nocd - this ONLY skips the cd check in the bios test menu is region is ASIA NCD, otherwise it will report NG, Asia was probably the only NCD region for this
+
+ cps3_use_fastboot = 0;
+
+ driver_init_cps3crpt(machine);
+ driver_init_cps3_speedups(machine);
+ driver_init_cps3_testhacks(machine);
+
+}
+
+static DRIVER_INIT( sfiii2 )
+{
+ // JAPAN 1
+ // ASIA NCD 2
+ // EURO 3
+ // USA 4
+ // HISPANIC 5
+ // BRAZIL 6
+ // OCEANIA 7
+ // ASIA 8
+
+// UINT32 *rom = (UINT32*)memory_region ( REGION_USER1 );
+// rom[0x1fec8/4]^=0x00000001; // region (clear region)
+// rom[0x1fec8/4]^=0x00000008; // region
+// rom[0x1fecc/4]^=0x01000000; // nocd - this ONLY skips the cd check in the bios test menu is region is ASIA NCD, otherwise it will report NG, Asia was probably the only NCD region for this
+
+ cps3_use_fastboot = 0; // not required
+
+ driver_init_cps3crpt(machine);
+ driver_init_cps3_speedups(machine);
+ driver_init_cps3_testhacks(machine);
+}
+
+
+static DRIVER_INIT( sfiii3 )
+{
+ // JAPAN 1
+ // ASIA 2
+ // EURO 3
+ // USA 4
+ // HISPANIC 5
+ // BRAZIL 6
+ // OCEANIA 7
+
+// UINT32 *rom = (UINT32*)memory_region ( REGION_USER1 );
+
+// rom[0x1fec8/4]^=0x00000004; // region (clear region)
+// rom[0x1fec8/4]^=0x00000001; // region
+// rom[0x1fecc/4]^=0x01000000; // nocd
+
+ driver_init_cps3crpt(machine);
+ driver_init_cps3_speedups(machine);
+ driver_init_cps3_testhacks(machine);
+
+ cps3_use_fastboot = 0;
+}
+
+/* todo: use BIOS for the bios roms, having clones only for CD / No CD */
+
+GAME( 1997, sfiii, 0, cps3, cps3, sfiii, ROT0, "Capcom", "Street Fighter III: New Generation (Japan, 970204)", GAME_IMPERFECT_GRAPHICS )
+GAME( 1997, sfiiiu, sfiii, cps3, cps3, sfiii, ROT0, "Capcom", "Street Fighter III: New Generation (USA, 970204)", GAME_IMPERFECT_GRAPHICS )
+
+GAME( 1997, sfiii2, 0, cps3, cps3, sfiii2, ROT0, "Capcom", "Street Fighter III 2nd Impact: Giant Attack (Japan, 970930)", GAME_IMPERFECT_GRAPHICS )
+GAME( 1997, sfiii2u, sfiii2, cps3, cps3, sfiii2, ROT0, "Capcom", "Street Fighter III 2nd Impact: Giant Attack (USA, 970930)", GAME_IMPERFECT_GRAPHICS )
+
+GAME( 1999, sfiii3, 0, cps3, cps3, sfiii3, ROT0, "Capcom", "Street Fighter III 3rd Strike: Fight for the Future (USA, 990512)", GAME_IMPERFECT_GRAPHICS )
+GAME( 1999, sfiii3a, sfiii3, cps3, cps3, sfiii3, ROT0, "Capcom", "Street Fighter III 3rd Strike: Fight for the Future (USA, 990608)", GAME_IMPERFECT_GRAPHICS )
+
+GAME( 1998, jojo, 0, cps3, cps3, jojo, ROT0, "Capcom", "JoJo's Venture / JoJo no Kimyouna Bouken (Japan, 981202)", GAME_IMPERFECT_GRAPHICS )
+GAME( 1998, jojoalt, jojo, cps3, cps3, jojo, ROT0, "Capcom", "JoJo's Venture / JoJo no Kimyouna Bouken (Japan, 990108)", GAME_IMPERFECT_GRAPHICS )
+
+GAME( 1999, jojoba, 0, cps3, cps3, jojoba, ROT0, "Capcom", "JoJo's Bizarre Adventure: Heritage for the Future / JoJo no Kimyouna Bouken: Miraie no Isan (Japan, 990913)", GAME_IMPERFECT_GRAPHICS )
+
+GAME( 1996, redearth,0, cps3, cps3, warzard, ROT0, "Capcom", "Red Earth (Euro, 961121)", GAME_IMPERFECT_GRAPHICS )
+GAME( 1996, warzard, redearth, cps3, cps3, warzard, ROT0, "Capcom", "Warzard (Japan, 961121)", GAME_IMPERFECT_GRAPHICS )
+
+/* NO-CD sets */
+
+GAME( 1997, sfiiin, sfiii, cps3, cps3, sfiii, ROT0, "Capcom", "Street Fighter III: New Generation (Asia, 970204, NO CD)", GAME_IMPERFECT_GRAPHICS )
+
+GAME( 1997, sfiii2n, sfiii2, cps3, cps3, sfiii2, ROT0, "Capcom", "Street Fighter III 2nd Impact: Giant Attack (Asia, 970930, NO CD)", GAME_IMPERFECT_GRAPHICS )
+
+GAME( 1999, sfiii3n, sfiii3, cps3, cps3, sfiii3, ROT0, "Capcom", "Street Fighter III 3rd Strike: Fight for the Future (Japan, 990512, NO CD)", GAME_IMPERFECT_GRAPHICS )
+GAME( 1999, sfiii3an,sfiii3, cps3, cps3, sfiii3, ROT0, "Capcom", "Street Fighter III 3rd Strike: Fight for the Future (Japan, 990608, NO CD)", GAME_IMPERFECT_GRAPHICS )
+
+GAME( 1998, jojon, jojo, cps3, cps3, jojo, ROT0, "Capcom", "JoJo's Venture / JoJo no Kimyouna Bouken (Asia, 981202, NO CD)", GAME_IMPERFECT_GRAPHICS )
+GAME( 1998, jojoaltn,jojo, cps3, cps3, jojo, ROT0, "Capcom", "JoJo's Venture / JoJo no Kimyouna Bouken (Asia, 990108, NO CD)", GAME_IMPERFECT_GRAPHICS )
+
+GAME( 1999, jojoban, jojoba, cps3, cps3, jojoba, ROT0, "Capcom", "JoJo's Bizarre Adventure: Heritage for the Future / JoJo no Kimyouna Bouken: Miraie no Isan (Japan, 990913, NO CD)", GAME_IMPERFECT_GRAPHICS )
+GAME( 1999, jojobane,jojoba, cps3, cps3, jojoba, ROT0, "Capcom", "JoJo's Bizarre Adventure: Heritage for the Future / JoJo no Kimyouna Bouken: Miraie no Isan (Euro, 990913, NO CD)", GAME_IMPERFECT_GRAPHICS )
+
+// We don't have any actual warzard / red earth no cd bios sets, but keep this here anyway
+GAME( 1996, redeartn,redearth, cps3, cps3, warzard,ROT0, "Capcom", "Red Earth (961121, NO CD)", GAME_NOT_WORKING )