Fully working World Rally driver

This commit is contained in:
Manuel Abadia 2008-05-12 09:04:04 +00:00
parent 90f263f8a3
commit 8034359e0e
3 changed files with 190 additions and 217 deletions

View File

@ -2,13 +2,9 @@
World Rally (c) 1993 Gaelco (Designed & Developed by Zigurat. Produced by Gaelco) World Rally (c) 1993 Gaelco (Designed & Developed by Zigurat. Produced by Gaelco)
Preliminary driver by Manuel Abadia <manu@teleline.es> Driver by Manuel Abadia, Mike Coates, Nicola Salmoria and Miguel Andel Horna
Encyption tables provided by Mike Coates who connected a fluke to the PCB. Thanks to GAELCO SA for the DS5002FP code and information about the encryption
Nicola Salmoria made the decode function based on that info.
Current decryption is incomplete
The DS5002FP has 32KB undumped gameplay code making the game unplayable :(
Main PCB components: Main PCB components:
==================== ====================
@ -18,7 +14,7 @@ CPUs related:
* 1xDS5002FP @ D12 (Dallas security processor @ 12 MHz) * 1xDS5002FP @ D12 (Dallas security processor @ 12 MHz)
* 1xHM62256ALFP-8T (32KB NVSRAM) @ C11 (encrypted DS5002FP program code) * 1xHM62256ALFP-8T (32KB NVSRAM) @ C11 (encrypted DS5002FP program code)
* 1xLithium cell * 1xLithium cell
* 2xMS6264A-20NC (32KB SRAM) @ D14 & D15 (shared memory between M68000 & DS5002FP) * 2xMS6264A-20NC (16KB SRAM) @ D14 & D15 (shared memory between M68000 & DS5002FP)
* 4x74LS157 (Quad 2 input multiplexer) @ F14, F15, F16 & F17 (used to select M68000 or DS5002FP address bus) * 4x74LS157 (Quad 2 input multiplexer) @ F14, F15, F16 & F17 (used to select M68000 or DS5002FP address bus)
* 4x74LS245 (Octal bus transceiver) @ C14, C15, C16 & C17 (used to store shared RAM data) * 4x74LS245 (Octal bus transceiver) @ C14, C15, C16 & C17 (used to store shared RAM data)
* 2x74LS373 (Octal tristate latch) @ D16 & D17 (used by DS5002FP to access data from shared RAM) * 2x74LS373 (Octal tristate latch) @ D16 & D17 (used by DS5002FP to access data from shared RAM)
@ -26,7 +22,7 @@ CPUs related:
* 1xOSC24MHz @ B20 * 1xOSC24MHz @ B20
* 2xM27C4001 @ C22 & C23 (M68000 program ROMs) * 2xM27C4001 @ C22 & C23 (M68000 program ROMs)
* 1xPAL20L8 @ B23 (handles 1st level M68000 memory map) * 1xPAL20L8 @ B23 (handles 1st level M68000 memory map)
0 -> DTACK (M68000 data ack) 0 -> DTACK M68000 data ack
1 -> SELACT 1 -> SELACT
2 -> Input/sound (see below) 2 -> Input/sound (see below)
3 -> ACTEXT 3 -> ACTEXT
@ -54,7 +50,17 @@ CPUs related:
5 -> flip screen 5 -> flip screen
6 -> ENA/D? 6 -> ENA/D?
7 -> CKA/D? 7 -> CKA/D?
* 1x16AS @ B15
0 -> OE
1 -> XSRL Shared RAM @ D14
2 -> XSRH Shared RAM @ D15
3 -> SAD Shared Access with DS5002FP
4 -> SRE Shared Access with M68000
5 -> TRANS
6 -> XLD
7 -> XHI
Sound related: Sound related:
============== ==============
* 1xOKIM6295 @ C6 * 1xOKIM6295 @ C6
@ -78,6 +84,7 @@ Palette related:
#include "driver.h" #include "driver.h"
#include "cpu/m68000/m68000.h" #include "cpu/m68000/m68000.h"
#include "cpu/ds5002fp/ds5002fp.h"
#include "sound/okim6295.h" #include "sound/okim6295.h"
/* from video/wrally.c */ /* from video/wrally.c */
@ -91,37 +98,48 @@ VIDEO_UPDATE( wrally );
/* from machine/wrally.c */ /* from machine/wrally.c */
DRIVER_INIT( wrally ); DRIVER_INIT( wrally );
MACHINE_RESET( wrally );
READ32_HANDLER( wrally_external_ram_iaddr );
WRITE16_HANDLER( OKIM6295_bankswitch_w ); WRITE16_HANDLER( OKIM6295_bankswitch_w );
WRITE16_HANDLER( wrally_coin_counter_w ); WRITE16_HANDLER( wrally_coin_counter_w );
WRITE16_HANDLER( wrally_coin_lockout_w ); WRITE16_HANDLER( wrally_coin_lockout_w );
static ADDRESS_MAP_START( wrally_readmem, ADDRESS_SPACE_PROGRAM, 16 )
static WRITE16_HANDLER( unknown_w ) AM_RANGE(0x000000, 0x0fffff) AM_ROM /* ROM */
{ AM_RANGE(0x100000, 0x103fff) AM_READWRITE(SMH_RAM, wrally_vram_w) AM_BASE(&wrally_videoram) /* encrypted Video RAM */
popmessage("write %04x to %04x", data, offset*2 + 0x6a); AM_RANGE(0x108000, 0x108007) AM_RAM AM_BASE(&wrally_vregs) /* Video Registers */
} AM_RANGE(0x10800c, 0x10800d) AM_WRITE(SMH_NOP) /* CLR INT Video */
AM_RANGE(0x200000, 0x203fff) AM_READWRITE(SMH_RAM, paletteram16_xxxxBBBBRRRRGGGG_word_w) AM_BASE(&paletteram16) /* Palette */
static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 16 ) AM_RANGE(0x440000, 0x440fff) AM_RAM AM_BASE(&wrally_spriteram) /* Sprite RAM */
AM_RANGE(0x000000, 0x0fffff) AM_ROM AM_RANGE(0x700000, 0x700001) AM_READ(input_port_0_word_r) /* DSW #1 & #2 */
AM_RANGE(0x100000, 0x103fff) AM_RAM_WRITE(wrally_vram_w) AM_BASE(&wrally_videoram) /* encrypted Video RAM */ AM_RANGE(0x700002, 0x700003) AM_READ(input_port_1_word_r) /* INPUT 1P & 2P, COINSW, STARTSW */
AM_RANGE(0x108000, 0x108007) AM_RAM AM_BASE(&wrally_vregs) /* Video Registers */ AM_RANGE(0x700004, 0x700005) AM_READ(input_port_2_word_r) /* Wheel */
AM_RANGE(0x10800c, 0x10800d) AM_WRITE(SMH_NOP) /* CLR INT Video */ AM_RANGE(0x700008, 0x700009) AM_READ(input_port_3_word_r) /* TESTSW & SERVICESW */
AM_RANGE(0x200000, 0x203fff) AM_RAM_WRITE(paletteram16_xxxxBBBBRRRRGGGG_word_w) AM_BASE(&paletteram16)/* Palette */ AM_RANGE(0x70000c, 0x70000d) AM_WRITE(OKIM6295_bankswitch_w) /* OKI6295 bankswitch */
AM_RANGE(0x440000, 0x440fff) AM_RAM AM_BASE(&wrally_spriteram) /* Sprite RAM */ AM_RANGE(0x70000e, 0x70000f) AM_READWRITE(OKIM6295_status_0_lsb_r, OKIM6295_data_0_lsb_w) /* OKI6295 status/data register */
AM_RANGE(0x700000, 0x700001) AM_READ(input_port_0_word_r) /* DSW #1 & #2 */ AM_RANGE(0x70000a, 0x70001b) AM_WRITE(wrally_coin_lockout_w) /* Coin lockouts */
AM_RANGE(0x700002, 0x700003) AM_READ(input_port_1_word_r) /* INPUT 1P & 2P, COINSW, STARTSW */ AM_RANGE(0x70002a, 0x70003b) AM_WRITE(wrally_coin_counter_w) /* Coin counters */
AM_RANGE(0x700004, 0x700005) AM_READ(input_port_2_word_r) /* Wheel */ AM_RANGE(0x70004a, 0x70004b) AM_WRITE(SMH_NOP) /* sound muting */
AM_RANGE(0x700008, 0x700009) AM_READ(input_port_3_word_r) /* TESTSW & SERVICESW */ AM_RANGE(0x70005a, 0x70005b) AM_WRITE(SMH_NOP) /* flip screen */
AM_RANGE(0x70000c, 0x70000d) AM_WRITE(OKIM6295_bankswitch_w) /* OKI6295 bankswitch */ AM_RANGE(0x70006a, 0x70007b) AM_WRITE(SMH_NOP) /* ??? */
AM_RANGE(0x70000e, 0x70000f) AM_READWRITE(OKIM6295_status_0_lsb_r,OKIM6295_data_0_lsb_w)/* OKI6295 status register */ AM_RANGE(0xfec000, 0xfeffff) AM_RAM AM_SHARE(1) /* Work RAM (shared with DS5002FP) */
AM_RANGE(0x70000a, 0x70001b) AM_WRITE(wrally_coin_lockout_w) /* Coin lockouts */
AM_RANGE(0x70002a, 0x70003b) AM_WRITE(wrally_coin_counter_w) /* Coin counters */
AM_RANGE(0x70004a, 0x70004b) AM_WRITE(SMH_NOP) /* sound muting */
AM_RANGE(0x70005a, 0x70005b) AM_WRITE(SMH_NOP) /* flip screen */
AM_RANGE(0x70006a, 0x70007b) AM_WRITE(unknown_w) /* ??? */
AM_RANGE(0xfe0000, 0xfeffff) AM_RAM /* Work RAM (partially shared with DS5002FP) */
ADDRESS_MAP_END ADDRESS_MAP_END
static ADDRESS_MAP_START( dallas_rom, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x7fff) AM_ROM /* Code in NVRAM */
ADDRESS_MAP_END
static ADDRESS_MAP_START( dallas_ram, ADDRESS_SPACE_DATA, 8 )
AM_RANGE(0x0000, 0xffff) AM_RAM AM_SHARE(1) AM_MASK(0x3fff) /* Shared RAM with the main CPU */
ADDRESS_MAP_END
/* DS5002FP configuration */
static const ds5002fp_config dallas_config =
{
0x88, /* bootstrap loader MCON register */
0x00, /* bootstrap loader RPCTL register */
0x80 /* bootstrap loader CRC register */
};
static INPUT_PORTS_START( wrally ) static INPUT_PORTS_START( wrally )
PORT_START /* DSW #1 & #2 */ PORT_START /* DSW #1 & #2 */
@ -174,21 +192,21 @@ PORT_START /* INPUTS, COINSW & STARTSW */
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1)
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1) PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1)
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1) PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1)
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2) PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2) PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2) PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2) PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_START1 ) PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_START2 ) PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_START2 )
PORT_START /* Wheel control? */ PORT_START /* Wheel control? */
PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* not implemented yet */ PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* not implemented */
PORT_START /* INPUTS, TEST & SERVICE */ PORT_START /* INPUTS, TEST & SERVICE */
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_SERVICE1 )
@ -196,8 +214,6 @@ PORT_START /* INPUTS, TEST & SERVICE */
PORT_BIT( 0xfffc, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0xfffc, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END INPUT_PORTS_END
static const gfx_layout wrally_tilelayout16 = static const gfx_layout wrally_tilelayout16 =
{ {
16,16, /* 16x16 tiles */ 16,16, /* 16x16 tiles */
@ -216,21 +232,27 @@ static GFXDECODE_START( wrally )
GFXDECODE_END GFXDECODE_END
static MACHINE_DRIVER_START( wrally ) static MACHINE_DRIVER_START( wrally )
/* basic machine hardware */ /* basic machine hardware */
MDRV_CPU_ADD(M68000,XTAL_24MHz/2) /* verified on pcb */ MDRV_CPU_ADD(M68000,XTAL_24MHz/2) /* verified on pcb */
MDRV_CPU_PROGRAM_MAP(main_map,0) MDRV_CPU_PROGRAM_MAP(wrally_readmem, 0)
MDRV_CPU_VBLANK_INT("main", irq6_line_hold) MDRV_CPU_VBLANK_INT("main", irq6_line_hold)
MDRV_CPU_ADD(DS5002FP, XTAL_24MHz/2) /* verified on pcb */
MDRV_CPU_CONFIG(dallas_config)
MDRV_CPU_PROGRAM_MAP(dallas_rom, 0)
MDRV_CPU_DATA_MAP(dallas_ram, 0)
MDRV_INTERLEAVE(640) /* heavy sync */
MDRV_MACHINE_RESET(wrally)
/* video hardware */ /* video hardware */
MDRV_SCREEN_ADD("main", RASTER) MDRV_SCREEN_ADD("main", RASTER)
MDRV_SCREEN_REFRESH_RATE(60) MDRV_SCREEN_REFRESH_RATE(60)
MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
MDRV_SCREEN_SIZE(64*16, 32*16) MDRV_SCREEN_SIZE(64*16, 32*16)
MDRV_SCREEN_VISIBLE_AREA(0, 64*16-1, 0, 32*16-1) MDRV_SCREEN_VISIBLE_AREA(8, 24*16-8-1, 16, 16*16-8-1)
// MDRV_SCREEN_VISIBLE_AREA(0, 320-1, 16, 256-1)
MDRV_GFXDECODE(wrally) MDRV_GFXDECODE(wrally)
MDRV_PALETTE_LENGTH(1024*8) MDRV_PALETTE_LENGTH(1024*8)
@ -241,7 +263,7 @@ static MACHINE_DRIVER_START( wrally )
/* sound hardware */ /* sound hardware */
MDRV_SPEAKER_STANDARD_MONO("mono") MDRV_SPEAKER_STANDARD_MONO("mono")
MDRV_SOUND_ADD(OKIM6295, XTAL_1MHz) /* verified on pcb */ MDRV_SOUND_ADD(OKIM6295, XTAL_1MHz) /* verified on pcb */
MDRV_SOUND_CONFIG(okim6295_interface_region_1_pin7high) /* verified on pcb */ MDRV_SOUND_CONFIG(okim6295_interface_region_1_pin7high) /* verified on pcb */
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MACHINE_DRIVER_END MACHINE_DRIVER_END
@ -251,6 +273,9 @@ ROM_START( wrally )
ROM_REGION( 0x100000, REGION_CPU1, 0 ) /* 68000 code */ ROM_REGION( 0x100000, REGION_CPU1, 0 ) /* 68000 code */
ROM_LOAD16_BYTE( "worldr17.c23", 0x000000, 0x080000, CRC(050f5629) SHA1(74fc2cd5114f3bc4b2429f1d8d7eeb1658f9f179) ) ROM_LOAD16_BYTE( "worldr17.c23", 0x000000, 0x080000, CRC(050f5629) SHA1(74fc2cd5114f3bc4b2429f1d8d7eeb1658f9f179) )
ROM_LOAD16_BYTE( "worldr16.c22", 0x000001, 0x080000, CRC(9e0d126c) SHA1(369360b7ec2c3497af3bf62b4eba24c3d9f94675) ) ROM_LOAD16_BYTE( "worldr16.c22", 0x000001, 0x080000, CRC(9e0d126c) SHA1(369360b7ec2c3497af3bf62b4eba24c3d9f94675) )
ROM_REGION( 0x10000, REGION_CPU2, 0 ) /* DS5002FP code */
ROM_LOAD( "wrdallas.bin", 0x00000, 0x8000, CRC(547d1768) SHA1(c58d1edd072d796be0663fb265f4739ec006b688) )
ROM_REGION( 0x200000, REGION_GFX1, ROMREGION_DISPOSE ) ROM_REGION( 0x200000, REGION_GFX1, ROMREGION_DISPOSE )
ROM_LOAD16_BYTE( "worldr21.i13", 0x000000, 0x080000, CRC(b7fddb12) SHA1(619a75daac8cbba7e85c97ca19733e2196d66d5c) ) ROM_LOAD16_BYTE( "worldr21.i13", 0x000000, 0x080000, CRC(b7fddb12) SHA1(619a75daac8cbba7e85c97ca19733e2196d66d5c) )
@ -276,6 +301,9 @@ ROM_START( wrallya )
ROM_REGION( 0x100000, REGION_CPU1, 0 ) /* 68000 code */ ROM_REGION( 0x100000, REGION_CPU1, 0 ) /* 68000 code */
ROM_LOAD16_BYTE( "c23.bin", 0x000000, 0x080000, CRC(8b7d93c3) SHA1(ce4163eebc5d4a0c1266d650523b1ffc702d1b87) ) ROM_LOAD16_BYTE( "c23.bin", 0x000000, 0x080000, CRC(8b7d93c3) SHA1(ce4163eebc5d4a0c1266d650523b1ffc702d1b87) )
ROM_LOAD16_BYTE( "c22.bin", 0x000001, 0x080000, CRC(56da43b6) SHA1(02db8f969ed5e7f5e5356c45c0312faf5f000335) ) ROM_LOAD16_BYTE( "c22.bin", 0x000001, 0x080000, CRC(56da43b6) SHA1(02db8f969ed5e7f5e5356c45c0312faf5f000335) )
ROM_REGION( 0x10000, REGION_CPU2, 0 ) /* DS5002FP code */
ROM_LOAD( "wrdallas.bin", 0x00000, 0x8000, CRC(547d1768) SHA1(c58d1edd072d796be0663fb265f4739ec006b688) )
ROM_REGION( 0x200000, REGION_GFX1, ROMREGION_DISPOSE ) ROM_REGION( 0x200000, REGION_GFX1, ROMREGION_DISPOSE )
ROM_LOAD16_BYTE( "worldr21.i13", 0x000000, 0x080000, CRC(b7fddb12) SHA1(619a75daac8cbba7e85c97ca19733e2196d66d5c) ) ROM_LOAD16_BYTE( "worldr21.i13", 0x000000, 0x080000, CRC(b7fddb12) SHA1(619a75daac8cbba7e85c97ca19733e2196d66d5c) )
@ -304,6 +332,9 @@ ROM_START( wrallyb ) /* Board Marked 930217 */
ROM_REGION( 0x100000, REGION_CPU1, 0 ) /* 68000 code */ ROM_REGION( 0x100000, REGION_CPU1, 0 ) /* 68000 code */
ROM_LOAD16_BYTE( "rally.c23", 0x000000, 0x080000, CRC(366595ad) SHA1(e16341ed9eacf9b729c28184268150ea9b62f185) ) ROM_LOAD16_BYTE( "rally.c23", 0x000000, 0x080000, CRC(366595ad) SHA1(e16341ed9eacf9b729c28184268150ea9b62f185) )
ROM_LOAD16_BYTE( "rally.c22", 0x000001, 0x080000, CRC(0ad4ec6f) SHA1(991557cf25fe960b1c586e990e6019befe5a11d0) ) ROM_LOAD16_BYTE( "rally.c22", 0x000001, 0x080000, CRC(0ad4ec6f) SHA1(991557cf25fe960b1c586e990e6019befe5a11d0) )
ROM_REGION( 0x10000, REGION_CPU2, 0 ) /* DS5002FP code */
ROM_LOAD( "wrdallas.bin", 0x00000, 0x8000, CRC(547d1768) SHA1(c58d1edd072d796be0663fb265f4739ec006b688) )
ROM_REGION( 0x400000, REGION_GFX1, ROMREGION_DISPOSE ) ROM_REGION( 0x400000, REGION_GFX1, ROMREGION_DISPOSE )
ROM_LOAD( "rally h-12.h12", 0x000000, 0x200000, CRC(38a44370) SHA1(cb427aa337232ae3a8effab3804d3d1d85d1f40b) ) ROM_LOAD( "rally h-12.h12", 0x000000, 0x200000, CRC(38a44370) SHA1(cb427aa337232ae3a8effab3804d3d1d85d1f40b) )
@ -321,6 +352,6 @@ ROM_START( wrallyb ) /* Board Marked 930217 */
ROM_END ROM_END
GAME( 1993, wrally, 0, wrally, wrally, wrally, ROT0, "Gaelco", "World Rally (set 1)", GAME_NOT_WORKING ) GAME( 1993, wrally, 0, wrally, wrally, wrally, ROT0, "Gaelco", "World Rally (set 1)", 0 )
GAME( 1993, wrallya, wrally, wrally, wrally, wrally, ROT0, "Gaelco", "World Rally (set 2)", GAME_NOT_WORKING ) GAME( 1993, wrallya, wrally, wrally, wrally, wrally, ROT0, "Gaelco", "World Rally (set 2)", 0 )
GAME( 1993, wrallyb, wrally, wrally, wrally, wrally, ROT0, "Gaelco", "World Rally (set 3 - 930217)", GAME_NOT_WORKING ) GAME( 1993, wrallyb, wrally, wrally, wrally, wrally, ROT0, "Gaelco", "World Rally (set 3 - 930217)", 0 )

View File

@ -8,106 +8,12 @@
***************************************************************************/ ***************************************************************************/
#include "driver.h" #include "driver.h"
#include "cpu/ds5002fp/ds5002fp.h"
#include "gaelcrpt.h"
UINT16 *wrally_encr_table[2]; /* from video/wrally.c */
extern UINT16 *wrally_videoram;
/*************************************************************************** extern tilemap *wrally_pant[2];
World Rally Video RAM encryption
***************************************************************************/
static int subxor1(int data,int res)
{
res ^= 0x0002;
if (BIT(data,0) ^ !BIT(data,5))
{
res ^= 0x0800;
if (BIT(data,2) ^ BIT(data,3)) res ^= 0x0001;
if (BIT(data,6) && !BIT(data,11) && BIT(data,5)) res ^= 0x0001;
}
return res;
}
static int subxor2(int data,int res)
{
res ^= 0x0020;
if (BIT(data,8) ^ !BIT(data,5))
{
res ^= 0x0008;
if (BIT(data,4) ^ BIT(data,3)) res ^= 0x0100;
if (BIT(data,6) && !BIT(data,11) && BIT(data,5)) res ^= 0x0100;
}
return res;
}
static int wrally_decode_vram(int data)
{
int res = 0;
res = BITSWAP16(data,5,7,9,12,2,14,13,15,3,6,8,11,4,10,0,1);
res ^= 0x0062;
if (BIT(data,9)) res ^= 0x5004;
if ( BIT(data,5) ^ (!BIT(data,9) && BIT(data,7))) res ^= 0x0200;
if (!BIT(data,5) ^ (!BIT(data,9) && BIT(data,12))) res ^= 0x0400;
if (BIT(data,3) ^ BIT(data,6)) res ^= 0x0101;
if (BIT(data,3) ^ BIT(data,5))
{
res ^= 0x0808;
if (BIT(data,2) ^ BIT(data,3)) res ^= 0x0001;
if (BIT(data,4) ^ BIT(data,3)) res ^= 0x0100;
}
if ((BIT(data,9) && !BIT(data,10)) || BIT(data,5))
{
res ^= 0x0010;
if (!BIT(data,11)) res ^= 0x0141;
if (BIT(data,6) && !BIT(data,11))
{
res ^= 0x0888;
if (!BIT(data,2)) res ^= 0x0001;
if (!BIT(data,4)) res ^= 0x0100;
}
}
if (BIT(data,9) && !BIT(data,10))
{
res ^= 0x8600;
if (!BIT(data,14)) res = subxor1(data,res);
if (!BIT(data,5)) res = subxor2(data,res);
if (BIT(data,6) && !BIT(data,11))
{
if (BIT(data,0) && !BIT(data,5)) res ^= 0x0001;
if (BIT(data,8) && !BIT(data,5)) res ^= 0x0100;
}
}
if (BIT(data,5) ^ BIT(data,14))
{
if ( BIT(data,14)) res = subxor1(data,res);
if (!BIT(data,9) && BIT(data,12)) res = subxor1(data,res);
}
if (BIT(data,5) ^ !BIT(data,13))
{
if ( BIT(data,5)) res = subxor2(data,res);
if ( BIT(data,9) && BIT(data,10)) res = subxor2(data,res);
if (!BIT(data,9) && !BIT(data,7)) res = subxor2(data,res);
}
return res;
}
/*************************************************************************** /***************************************************************************
@ -115,6 +21,15 @@ static int wrally_decode_vram(int data)
***************************************************************************/ ***************************************************************************/
WRITE16_HANDLER( wrally_vram_w )
{
data = gaelco_decrypt(offset, data, 0x1f, 0x522a);
COMBINE_DATA(&wrally_videoram[offset]);
tilemap_mark_tile_dirty(wrally_pant[(offset & 0x1fff) >> 12], ((offset << 1) & 0x1fff) >> 2);
}
WRITE16_HANDLER( OKIM6295_bankswitch_w ) WRITE16_HANDLER( OKIM6295_bankswitch_w )
{ {
UINT8 *RAM = memory_region(REGION_SOUND1); UINT8 *RAM = memory_region(REGION_SOUND1);
@ -134,21 +49,24 @@ WRITE16_HANDLER( wrally_coin_lockout_w )
coin_lockout_w( (offset >> 3) & 0x01, ~data & 0x01); coin_lockout_w( (offset >> 3) & 0x01, ~data & 0x01);
} }
/* Converts memory offsets to the format expected by the Dallas */
READ32_HANDLER( wrally_external_ram_iaddr )
{
return offset ^= 0x0001;
}
/*************************************************************************** /***************************************************************************
World Rally init machine World Rally init/reset machine
***************************************************************************/ ***************************************************************************/
DRIVER_INIT( wrally ) DRIVER_INIT( wrally )
{ {
int i; }
/* recreate encryption tables on start up */ MACHINE_RESET( wrally )
wrally_encr_table[0] = (UINT16 *)auto_malloc(0x10000*2); {
wrally_encr_table[1] = (UINT16 *)auto_malloc(0x10000*2); /* sets the function to convert addresses for shared memory with the dallas */
for (i = 0; i < 0x10000; i++){ ds5002fp_set_ebram_iaddr_callback(wrally_external_ram_iaddr);
wrally_encr_table[0][i] = wrally_decode_vram(i);
wrally_encr_table[1][i] = wrally_decode_vram(i);
}
} }

View File

@ -12,10 +12,7 @@ UINT16 *wrally_spriteram;
UINT16 *wrally_vregs; UINT16 *wrally_vregs;
UINT16 *wrally_videoram; UINT16 *wrally_videoram;
static tilemap *pant[2]; tilemap *wrally_pant[2];
/* from machine/wrally.c */
extern UINT16 *wrally_encr_table[2];
/*************************************************************************** /***************************************************************************
@ -33,19 +30,23 @@ extern UINT16 *wrally_encr_table[2];
-----+-FEDCBA98-76543210-+-------------------------- -----+-FEDCBA98-76543210-+--------------------------
0 | --xxxxxx xxxxxxxx | code 0 | --xxxxxx xxxxxxxx | code
0 | xx------ -------- | not used? 0 | xx------ -------- | not used?
1 | xxxxxxxx xxxxxxxx | unknown 1 | -------- ---xxxxx | color
1 | -------- --x----- | priority
preliminary 1 | -------- -x------ | flip y
1 | -------- x------- | flip x
1 | ---xxxxx -------- | data used to handle collisions, speed, etc
1 | xxx----- -------- | not used?
*/ */
static TILE_GET_INFO( get_tile_info_wrally_screen0 ) static TILE_GET_INFO( get_tile_info_wrally_screen0 )
{ {
int data = wrally_videoram[tile_index << 1]; int data = wrally_videoram[tile_index << 1];
int data2 = wrally_videoram[(tile_index << 1) + 1]; int data2 = wrally_videoram[(tile_index << 1) + 1];
int code = data & 0x3fff; int code = data & 0x3fff;
SET_TILE_INFO(0, code, data2 & 0x1f, TILE_FLIPXY((data2 >> 5) & 0x00)); tileinfo->category = (data2 >> 5) & 0x01;
SET_TILE_INFO(0, code, data2 & 0x1f, TILE_FLIPYX((data2 >> 6) & 0x03));
} }
static TILE_GET_INFO( get_tile_info_wrally_screen1 ) static TILE_GET_INFO( get_tile_info_wrally_screen1 )
@ -53,24 +54,12 @@ static TILE_GET_INFO( get_tile_info_wrally_screen1 )
int data = wrally_videoram[(0x2000/2) + (tile_index << 1)]; int data = wrally_videoram[(0x2000/2) + (tile_index << 1)];
int data2 = wrally_videoram[(0x2000/2) + (tile_index << 1) + 1]; int data2 = wrally_videoram[(0x2000/2) + (tile_index << 1) + 1];
int code = data & 0x3fff; int code = data & 0x3fff;
tileinfo->category = (data2 >> 5) & 0x01;
SET_TILE_INFO(0, code, data2 & 0x1f, TILE_FLIPXY((data2 >> 5) & 0x00)); SET_TILE_INFO(0, code, data2 & 0x1f, TILE_FLIPYX((data2 >> 6) & 0x03));
} }
/***************************************************************************
Memory Handlers
***************************************************************************/
WRITE16_HANDLER( wrally_vram_w )
{
wrally_videoram[offset] = wrally_encr_table[offset & 0x01][data];
tilemap_mark_tile_dirty(pant[(offset & 0x1fff) >> 12], ((offset << 1) & 0x1fff) >> 2);
}
/*************************************************************************** /***************************************************************************
Start/Stop the video hardware emulation. Start/Stop the video hardware emulation.
@ -79,11 +68,11 @@ WRITE16_HANDLER( wrally_vram_w )
VIDEO_START( wrally ) VIDEO_START( wrally )
{ {
pant[0] = tilemap_create(get_tile_info_wrally_screen0,tilemap_scan_rows,16,16,64,32); wrally_pant[0] = tilemap_create(get_tile_info_wrally_screen0,tilemap_scan_rows,16,16,64,32);
pant[1] = tilemap_create(get_tile_info_wrally_screen1,tilemap_scan_rows,16,16,64,32); wrally_pant[1] = tilemap_create(get_tile_info_wrally_screen1,tilemap_scan_rows,16,16,64,32);
tilemap_set_transparent_pen(pant[0],0); tilemap_set_transparent_pen(wrally_pant[0],0);
tilemap_set_transparent_pen(pant[1],0); tilemap_set_transparent_pen(wrally_pant[1],0);
} }
@ -106,44 +95,73 @@ VIDEO_START( wrally )
1 | xxxxxxxx xxxxxxxx | unknown 1 | xxxxxxxx xxxxxxxx | unknown
2 | ------xx xxxxxxxx | x position 2 | ------xx xxxxxxxx | x position
2 | --xxxx-- -------- | sprite color (low 4 bits) 2 | --xxxx-- -------- | sprite color (low 4 bits)
2 | xx------ -------- | unknown 2 | -x------ -------- | shadows/highlights (see below)
2 | x------- -------- | not used?
3 | --xxxxxx xxxxxxxx | sprite code 3 | --xxxxxx xxxxxxxx | sprite code
3 | xx------ -------- | not used? 3 | xx------ -------- | not used?
preliminary For shadows/highlights, the tile color below the sprite will be set using a
palette (from the 8 available) based on the gfx pen of the sprite. Only pens
in the range 0x8-0xf are used.
*/ */
static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect) static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, int priority)
{ {
int i, x, y, ex, ey; int i, px, py;
const gfx_element *gfx = machine->gfx[0]; const gfx_element *gfx = machine->gfx[0];
static const int x_offset[2] = {0x0,0x2}; for (i = 6/2; i < (0x1000 - 6)/2; i += 4) {
static const int y_offset[2] = {0x0,0x1};
for (i = 3; i < (0x1000 - 6)/2; i += 4){
int sx = wrally_spriteram[i+2] & 0x03ff; int sx = wrally_spriteram[i+2] & 0x03ff;
int sy = (240 - (wrally_spriteram[i] & 0x00ff)) & 0x00ff; int sy = (240 - (wrally_spriteram[i] & 0x00ff)) & 0x00ff;
int number = wrally_spriteram[i+3] & 0x3fff; int number = wrally_spriteram[i+3] & 0x3fff;
int color = ((wrally_spriteram[i+2] & 0xfc00) >> 10); int color = (wrally_spriteram[i+2] & 0x7c00) >> 10;
int attr = (wrally_spriteram[i] & 0xfe00) >> 9; int attr = (wrally_spriteram[i] & 0xfe00) >> 9;
int xflip = attr & 0x20; int xflip = attr & 0x20;
int yflip = attr & 0x40; int yflip = attr & 0x40;
int spr_size = 1; int color_effect = (color & 0x10) >> 4;
int high_priority = number >= 0x3700;
color = color & 0x0f;
if (high_priority != priority) continue;
if (!color_effect) {
drawgfx(bitmap,gfx,number,
0x20 + color,xflip,yflip,
sx - 0x0f,sy,
cliprect,TRANSPARENCY_PEN,0);
} else {
/* get a pointer to the current sprite's gfx data */
UINT8 *gfx_src = gfx->gfxdata + (number % gfx->total_elements)*gfx->char_modulo;
color = (color & 0x0f); for (py = 0; py < gfx->height; py++){
/* get a pointer to the current line in the screen bitmap */
int ypos = ((sy + py) & 0xff);
UINT16 *srcy = BITMAP_ADDR16(bitmap, ypos, 0);
for (y = 0; y < spr_size; y++){ int gfx_py = yflip ? (gfx->height - 1 - py) : py;
for (x = 0; x < spr_size; x++){
ex = xflip ? (spr_size-1-x) : x; if ((ypos < cliprect->min_y) || (ypos > cliprect->max_y)) continue;
ey = yflip ? (spr_size-1-y) : y;
drawgfx(bitmap,gfx,number + x_offset[ex] + y_offset[ey], for (px = 0; px < gfx->width; px++){
0x20 + color,xflip,yflip, /* get current pixel */
sx-0x0f+x*16,sy+y*16, int xpos = (((sx + px) & 0x3ff) - 0x0f) & 0x3ff;
cliprect,TRANSPARENCY_PEN,0); UINT16 *pixel = srcy + xpos;
int src_color = *pixel;
int gfx_px = xflip ? (gfx->width - 1 - px) : px;
/* get asociated pen for the current sprite pixel */
int gfx_pen = gfx_src[gfx->line_modulo*gfx_py + gfx_px];
/* pens 8..15 are used to select a palette */
if ((gfx_pen < 8) || (gfx_pen >= 16)) continue;
if ((xpos < cliprect->min_x) || (xpos > cliprect->max_x)) continue;
/* modify the color of the tile */
*pixel = src_color + (gfx_pen-8)*1024;
}
} }
} }
} }
@ -156,17 +174,23 @@ static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const recta
***************************************************************************/ ***************************************************************************/
VIDEO_UPDATE( wrally ) VIDEO_UPDATE( wrally )
{ {
/* set scroll registers */ /* set scroll registers */
tilemap_set_scrolly(pant[0], 0, wrally_vregs[0]); tilemap_set_scrolly(wrally_pant[0], 0, wrally_vregs[0]);
tilemap_set_scrollx(pant[0], 0, wrally_vregs[1]); tilemap_set_scrollx(wrally_pant[0], 0, wrally_vregs[1]+4);
tilemap_set_scrolly(pant[1], 0, wrally_vregs[2]); tilemap_set_scrolly(wrally_pant[1], 0, wrally_vregs[2]);
tilemap_set_scrollx(pant[1], 0, wrally_vregs[3]); tilemap_set_scrollx(wrally_pant[1], 0, wrally_vregs[3]);
fillbitmap( bitmap, 0, cliprect ); /* draw tilemaps + sprites */
tilemap_draw(bitmap,cliprect,wrally_pant[1],TILEMAP_DRAW_OPAQUE,0);
tilemap_draw(bitmap,cliprect,wrally_pant[0],TILEMAP_DRAW_CATEGORY(0),0);
tilemap_draw(bitmap,cliprect,pant[1],0,0); draw_sprites(screen->machine,bitmap,cliprect,0);
tilemap_draw(bitmap,cliprect,pant[0],0,0);
draw_sprites(screen->machine, bitmap,cliprect); tilemap_draw(bitmap,cliprect,wrally_pant[1],TILEMAP_DRAW_CATEGORY(1),0);
tilemap_draw(bitmap,cliprect,wrally_pant[0],TILEMAP_DRAW_CATEGORY(1),0);
draw_sprites(screen->machine,bitmap,cliprect,1);
return 0; return 0;
} }