Merge pull request #1112 from ajrhacker/spicrtc

Hook up Seibu CRTC to SPI System
This commit is contained in:
R. Belmont 2016-07-17 21:37:53 -04:00 committed by GitHub
commit 5d18d1170f
14 changed files with 504 additions and 496 deletions

View File

@ -3279,8 +3279,6 @@ files {
MAME_DIR .. "src/mame/drivers/r2dx_v33.cpp",
MAME_DIR .. "src/mame/drivers/seibuspi.cpp",
MAME_DIR .. "src/mame/includes/seibuspi.h",
MAME_DIR .. "src/mame/machine/seibuspi.cpp",
MAME_DIR .. "src/mame/machine/seibuspi.h",
MAME_DIR .. "src/mame/video/seibuspi.cpp",
MAME_DIR .. "src/mame/drivers/sengokmj.cpp",
MAME_DIR .. "src/mame/drivers/stfight.cpp",
@ -3295,8 +3293,8 @@ files {
MAME_DIR .. "src/mame/video/wiz.cpp",
MAME_DIR .. "src/mame/machine/seicop.cpp",
MAME_DIR .. "src/mame/machine/seicop.h",
MAME_DIR .. "src/mame/machine/spisprit.cpp",
MAME_DIR .. "src/mame/machine/spisprit.h",
MAME_DIR .. "src/mame/machine/seibuspi.cpp",
MAME_DIR .. "src/mame/machine/seibuspi.h",
MAME_DIR .. "src/mame/audio/seibu.cpp",
MAME_DIR .. "src/mame/audio/seibu.h",
MAME_DIR .. "src/mame/video/seibu_crtc.cpp",

View File

@ -196,8 +196,8 @@ static ADDRESS_MAP_START( feversoc_map, AS_PROGRAM, 32, feversoc_state )
AM_RANGE(0x06000004, 0x06000007) AM_WRITENOP //???
AM_RANGE(0x06000008, 0x0600000b) AM_READ(in0_r)
AM_RANGE(0x0600000c, 0x0600000f) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0x00ff0000)
// AM_RANGE(0x06010000, 0x06017fff) AM_RAM //contains RISE11 keys and other related stuff.
AM_RANGE(0x06010060, 0x06010063) AM_WRITENOP
//AM_RANGE(0x06010000, 0x0601007f) AM_DEVREADWRITE("obj", seibu_encrypted_sprite_device, read, write) AM_RAM
AM_RANGE(0x06010060, 0x06010063) AM_WRITENOP // sprite buffering
AM_RANGE(0x06018000, 0x06019fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
ADDRESS_MAP_END

View File

@ -189,7 +189,7 @@ static ADDRESS_MAP_START( legionna_map, AS_PROGRAM, 16, legionna_state )
AM_RANGE(0x000000, 0x07ffff) AM_ROM
AM_RANGE(0x100000, 0x1003ff) AM_RAM
AM_RANGE(0x100470, 0x100471) AM_WRITENOP // toggles 0x2000 / 0x0000, tile bank on some games
AM_RANGE(0x100600, 0x10063f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
AM_RANGE(0x100600, 0x10064f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
AM_RANGE(0x100680, 0x100681) AM_WRITENOP // irq ack?
AM_RANGE(0x100700, 0x10071f) AM_READWRITE(sound_comms_r,sound_comms_w)
AM_RANGE(0x100740, 0x100741) AM_READ_PORT("DSW1")
@ -233,7 +233,7 @@ static ADDRESS_MAP_START( godzilla_map, AS_PROGRAM, 16, legionna_state )
AM_RANGE(0x000000, 0x07ffff) AM_ROM
AM_RANGE(0x100000, 0x1003ff) AM_RAM
AM_RANGE(0x100470, 0x100471) AM_WRITE(denjinmk_setgfxbank)
AM_RANGE(0x100600, 0x10063f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
AM_RANGE(0x100600, 0x10064f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
AM_RANGE(0x100680, 0x100681) AM_WRITENOP // irq ack?
AM_RANGE(0x100700, 0x10071f) AM_READWRITE(sound_comms_r,sound_comms_w)
AM_RANGE(0x100740, 0x100741) AM_READ_PORT("DSW1")
@ -260,7 +260,7 @@ static ADDRESS_MAP_START( denjinmk_map, AS_PROGRAM, 16, legionna_state )
AM_RANGE(0x000000, 0x0fffff) AM_ROM
AM_RANGE(0x100000, 0x1003ff) AM_RAM
AM_RANGE(0x100470, 0x100471) AM_WRITE(denjinmk_setgfxbank)
AM_RANGE(0x100600, 0x10063f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
AM_RANGE(0x100600, 0x10064f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
AM_RANGE(0x100680, 0x100681) AM_WRITENOP // irq ack?
AM_RANGE(0x100700, 0x10071f) AM_READWRITE(denjinmk_sound_comms_r,sound_comms_w)
AM_RANGE(0x100740, 0x100741) AM_READ_PORT("DSW1")
@ -286,7 +286,7 @@ static ADDRESS_MAP_START( grainbow_map, AS_PROGRAM, 16, legionna_state )
AM_RANGE(0x000000, 0x0fffff) AM_ROM
AM_RANGE(0x100000, 0x1003ff) AM_RAM
AM_RANGE(0x100480, 0x100487) AM_WRITE(grainbow_layer_config_w) // probably a COP feature
AM_RANGE(0x100600, 0x10063f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
AM_RANGE(0x100600, 0x10064f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
AM_RANGE(0x100680, 0x100681) AM_WRITENOP // irq ack?
AM_RANGE(0x100700, 0x10071f) AM_READWRITE(sound_comms_r,sound_comms_w)
AM_RANGE(0x100740, 0x100741) AM_READ_PORT("DSW1")
@ -310,7 +310,7 @@ static ADDRESS_MAP_START( cupsoc_mem, AS_PROGRAM, 16, legionna_state )
AM_IMPORT_FROM( legionna_cop_mem )
AM_RANGE(0x000000, 0x0fffff) AM_ROM
AM_RANGE(0x100000, 0x1003ff) AM_RAM
AM_RANGE(0x100600, 0x10063f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
AM_RANGE(0x100600, 0x10064f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
AM_RANGE(0x100680, 0x100681) AM_WRITENOP // irq ack?
AM_RANGE(0x100700, 0x10071f) AM_READWRITE(sound_comms_r,sound_comms_w)
AM_RANGE(0x100740, 0x100741) AM_READ_PORT("DSW1")
@ -337,8 +337,7 @@ static ADDRESS_MAP_START( cupsocs_mem, AS_PROGRAM, 16, legionna_state )
AM_IMPORT_FROM( legionna_cop_mem )
AM_RANGE(0x000000, 0x0fffff) AM_ROM
AM_RANGE(0x100000, 0x1003ff) AM_RAM
AM_RANGE(0x100600, 0x10060f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)//?
AM_RANGE(0x100640, 0x10067f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
AM_RANGE(0x100600, 0x10067f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read_xor, write_xor)
AM_RANGE(0x100680, 0x100681) AM_WRITENOP // irq ack?
AM_RANGE(0x100700, 0x100701) AM_READ_PORT("DSW1")
AM_RANGE(0x100704, 0x100705) AM_READ_PORT("PLAYERS12")

View File

@ -389,10 +389,9 @@ static ADDRESS_MAP_START( rdx_v33_map, AS_PROGRAM, 16, r2dx_v33_state )
AM_RANGE(0x00434, 0x00435) AM_READ(r2dx_sin_r)
AM_RANGE(0x00436, 0x00437) AM_READ(r2dx_cos_r)
AM_RANGE(0x00600, 0x0064f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
// AM_RANGE(0x00650, 0x0068f) AM_RAM //???
AM_RANGE(0x0068e, 0x0068f) AM_WRITENOP // maybe a watchdog?
AM_RANGE(0x00600, 0x0063f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
//AM_RANGE(0x00640, 0x006bf) AM_DEVREADWRITE("obj", seibu_encrypted_sprite_device, read, write)
AM_RANGE(0x0068e, 0x0068f) AM_WRITENOP // sprite buffering
AM_RANGE(0x006b0, 0x006b1) AM_WRITE(mcu_prog_w) // could be encryption key uploads just like raiden2.c ?
AM_RANGE(0x006b2, 0x006b3) AM_WRITE(mcu_prog_w2)
// AM_RANGE(0x006b4, 0x006b5) AM_WRITENOP
@ -458,9 +457,9 @@ static ADDRESS_MAP_START( nzeroteam_base_map, AS_PROGRAM, 16, r2dx_v33_state )
AM_RANGE(0x00434, 0x00435) AM_READ(r2dx_sin_r)
AM_RANGE(0x00436, 0x00437) AM_READ(r2dx_cos_r)
AM_RANGE(0x00600, 0x0064f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
AM_RANGE(0x0068e, 0x0068f) AM_WRITENOP // synch for the MCU?
AM_RANGE(0x00600, 0x0063f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
//AM_RANGE(0x00640, 0x006bf) AM_DEVREADWRITE("obj", seibu_encrypted_sprite_device, read, write)
AM_RANGE(0x0068e, 0x0068f) AM_WRITENOP // sprite buffering
AM_RANGE(0x006b0, 0x006b1) AM_WRITE(mcu_prog_w)
AM_RANGE(0x006b2, 0x006b3) AM_WRITE(mcu_prog_w2)
// AM_RANGE(0x006b4, 0x006b5) AM_WRITENOP

View File

@ -932,10 +932,8 @@ static ADDRESS_MAP_START( raiden2_cop_mem, AS_PROGRAM, 16, raiden2_state )
AM_RANGE(0x005b2, 0x005b3) AM_DEVREAD("raiden2cop", raiden2cop_device, cop_dist_r)
AM_RANGE(0x005b4, 0x005b5) AM_DEVREAD("raiden2cop", raiden2cop_device, cop_angle_r)
/* I think all this block is part of the video chip */
AM_RANGE(0x00600, 0x0064f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
// AM_RANGE(0x0061c, 0x0061d) AM_WRITE(tilemap_enable_w)
// AM_RANGE(0x00620, 0x0062b) AM_WRITE(tile_scroll_w)
AM_RANGE(0x00600, 0x0063f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
//AM_RANGE(0x00640, 0x006bf) AM_DEVREADWRITE("obj", seibu_encrypted_sprite_device, read, write)
AM_RANGE(0x006a0, 0x006a3) AM_WRITE(sprcpt_val_1_w)
AM_RANGE(0x006a4, 0x006a7) AM_WRITE(sprcpt_data_3_w)
AM_RANGE(0x006a8, 0x006ab) AM_WRITE(sprcpt_data_4_w)
@ -996,7 +994,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( raidendx_mem, AS_PROGRAM, 16, raiden2_state )
AM_RANGE(0x00470, 0x00471) AM_READWRITE(cop_tile_bank_2_r,raidendx_cop_bank_2_w)
AM_RANGE(0x004d0, 0x004d7) AM_RAM //???
AM_RANGE(0x00600, 0x0064f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read_alt, write_alt)
AM_RANGE(0x00600, 0x0063f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read_alt, write_alt)
// AM_RANGE(0x006ca, 0x006cb) AM_WRITENOP
AM_IMPORT_FROM( raiden2_mem )
ADDRESS_MAP_END

View File

@ -855,7 +855,7 @@ Notes:
#include "sound/ymf271.h"
#include "sound/ymz280b.h"
#include "machine/seibuspi.h"
#include "machine/spisprit.h"
#include "video/seibu_crtc.h"
#include "includes/seibuspi.h"
// default values written to CRTC (note: SYS386F does not have this chip)
@ -969,10 +969,7 @@ WRITE32_MEMBER(seibuspi_state::ejsakura_input_select_w)
static ADDRESS_MAP_START( base_map, AS_PROGRAM, 32, seibuspi_state )
AM_RANGE(0x00000414, 0x00000417) AM_WRITENOP // bg gfx decryption key, see machine/seibuspi.c
AM_RANGE(0x00000418, 0x0000041b) AM_READWRITE(spi_layer_bank_r, spi_layer_bank_w)
AM_RANGE(0x0000041c, 0x0000041f) AM_WRITE(spi_layer_enable_w) // seibu crtc
AM_RANGE(0x00000420, 0x0000042b) AM_RAM AM_SHARE("scrollram") // seibu crtc
AM_RANGE(0x00000400, 0x0000043f) AM_DEVREADWRITE16("crtc", seibu_crtc_device, read, write, 0xffffffff)
AM_RANGE(0x00000480, 0x00000483) AM_WRITE(tilemap_dma_start_w)
AM_RANGE(0x00000484, 0x00000487) AM_WRITE(palette_dma_start_w)
AM_RANGE(0x00000490, 0x00000493) AM_WRITE(video_dma_length_w)
@ -988,6 +985,7 @@ static ADDRESS_MAP_START( base_map, AS_PROGRAM, 32, seibuspi_state )
ADDRESS_MAP_END
static ADDRESS_MAP_START( sei252_map, AS_PROGRAM, 32, seibuspi_state )
//AM_RANGE(0x00000500, 0x0000057f) AM_DEVREADWRITE16("obj", sei252_device, read_xor, write_xor, 0xffffffff)
AM_RANGE(0x0000050c, 0x0000050f) AM_WRITE16(sprite_dma_start_w, 0xffff0000)
AM_RANGE(0x00000524, 0x00000527) AM_WRITENOP // SEI252 sprite decryption key, see machine/spisprit.c
AM_RANGE(0x00000528, 0x0000052b) AM_WRITENOP // SEI252 sprite decryption unknown
@ -997,6 +995,7 @@ static ADDRESS_MAP_START( sei252_map, AS_PROGRAM, 32, seibuspi_state )
ADDRESS_MAP_END
static ADDRESS_MAP_START( rise_map, AS_PROGRAM, 32, seibuspi_state )
//AM_RANGE(0x00000500, 0x0000057f) AM_DEVREADWRITE16("obj", seibu_encrypted_sprite_device, read, write, 0xffffffff)
AM_RANGE(0x0000054c, 0x0000054f) AM_WRITENOP // RISE10/11 sprite decryption key, see machine/seibuspi.c
AM_RANGE(0x00000560, 0x00000563) AM_WRITE16(sprite_dma_start_w, 0xffff0000)
ADDRESS_MAP_END
@ -1809,28 +1808,12 @@ void seibuspi_state::init_spi_common()
void seibuspi_state::init_sei252()
{
seibuspi_text_decrypt(memregion("gfx1")->base());
seibuspi_bg_decrypt(memregion("gfx2")->base(), memregion("gfx2")->bytes());
text_decrypt(memregion("gfx1")->base());
bg_decrypt(memregion("gfx2")->base(), memregion("gfx2")->bytes());
seibuspi_sprite_decrypt(memregion("gfx3")->base(), 0x400000);
init_spi_common();
}
void seibuspi_state::init_rise10()
{
seibuspi_rise10_text_decrypt(memregion("gfx1")->base());
seibuspi_rise10_bg_decrypt(memregion("gfx2")->base(), memregion("gfx2")->bytes());
seibuspi_rise10_sprite_decrypt(memregion("gfx3")->base(), 0x600000);
init_spi_common();
}
void seibuspi_state::init_rise11()
{
seibuspi_rise11_text_decrypt(memregion("gfx1")->base());
seibuspi_rise11_bg_decrypt(memregion("gfx2")->base(), memregion("gfx2")->bytes());
seibuspi_rise11_sprite_decrypt_rfjet(memregion("gfx3")->base(), 0x800000);
init_spi_common();
}
void seibuspi_state::machine_start()
{
@ -1886,6 +1869,12 @@ static MACHINE_CONFIG_START( spi, seibuspi_state )
MCFG_PALETTE_ADD_INIT_BLACK("palette", 6144)
MCFG_DEVICE_ADD("crtc", SEIBU_CRTC, 0)
MCFG_SEIBU_CRTC_DECRYPT_KEY_CB(WRITE16(seibuspi_state, tile_decrypt_key_w))
MCFG_SEIBU_CRTC_LAYER_EN_CB(WRITE16(seibuspi_state, spi_layer_enable_w))
MCFG_SEIBU_CRTC_REG_1A_CB(WRITE16(seibuspi_state, spi_layer_bank_w))
MCFG_SEIBU_CRTC_LAYER_SCROLL_CB(WRITE16(seibuspi_state, scroll_w))
/* sound hardware */
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
@ -1996,6 +1985,12 @@ static MACHINE_CONFIG_START( sys386i, seibuspi_state )
MCFG_PALETTE_ADD_INIT_BLACK("palette", 6144)
MCFG_DEVICE_ADD("crtc", SEIBU_CRTC, 0)
MCFG_SEIBU_CRTC_DECRYPT_KEY_CB(WRITE16(seibuspi_state, tile_decrypt_key_w))
MCFG_SEIBU_CRTC_LAYER_EN_CB(WRITE16(seibuspi_state, spi_layer_enable_w))
MCFG_SEIBU_CRTC_REG_1A_CB(WRITE16(seibuspi_state, spi_layer_bank_w))
MCFG_SEIBU_CRTC_LAYER_SCROLL_CB(WRITE16(seibuspi_state, scroll_w))
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
@ -2109,13 +2104,21 @@ DRIVER_INIT_MEMBER(seibuspi_state,rdft)
DRIVER_INIT_MEMBER(seibuspi_state,rdft2)
{
if (ENABLE_SPEEDUP_HACKS) m_maincpu->space(AS_PROGRAM).install_read_handler(0x00282ac, 0x00282af, read32_delegate(FUNC(seibuspi_state::rf2_speedup_r),this));
init_rise10();
rdft2_text_decrypt(memregion("gfx1")->base());
rdft2_bg_decrypt(memregion("gfx2")->base(), memregion("gfx2")->bytes());
seibuspi_rise10_sprite_decrypt(memregion("gfx3")->base(), 0x600000);
init_spi_common();
}
DRIVER_INIT_MEMBER(seibuspi_state,rfjet)
{
if (ENABLE_SPEEDUP_HACKS) m_maincpu->space(AS_PROGRAM).install_read_handler(0x002894c, 0x002894f, read32_delegate(FUNC(seibuspi_state::rfjet_speedup_r),this));
init_rise11();
rfjet_text_decrypt(memregion("gfx1")->base());
rfjet_bg_decrypt(memregion("gfx2")->base(), memregion("gfx2")->bytes());
seibuspi_rise11_sprite_decrypt_rfjet(memregion("gfx3")->base(), 0x800000);
init_spi_common();
}

View File

@ -19,7 +19,6 @@ public:
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_mainram(*this, "mainram"),
m_scrollram(*this, "scrollram"),
m_z80_rom(*this, "audiocpu"),
m_eeprom(*this, "eeprom"),
m_soundflash1(*this, "soundflash1"),
@ -35,7 +34,6 @@ public:
required_device<cpu_device> m_maincpu;
optional_device<cpu_device> m_audiocpu;
required_shared_ptr<UINT32> m_mainram;
optional_shared_ptr<UINT32> m_scrollram;
optional_memory_region m_z80_rom;
optional_device<eeprom_serial_93cxx_device> m_eeprom;
optional_device<intel_e28f008sa_device> m_soundflash1;
@ -57,9 +55,10 @@ public:
tilemap_t *m_fore_layer;
UINT32 m_video_dma_length;
UINT32 m_video_dma_address;
UINT32 m_layer_enable;
UINT32 m_layer_bank;
UINT16 m_layer_enable;
UINT16 m_layer_bank;
UINT8 m_rf2_layer_bank;
UINT16 m_scrollram[6];
int m_rowscroll_enable;
int m_midl_layer_offset;
int m_fore_layer_offset;
@ -78,10 +77,11 @@ public:
UINT8 m_alpha_table[0x2000];
int m_sprite_bpp;
DECLARE_READ32_MEMBER(spi_layer_bank_r);
DECLARE_WRITE32_MEMBER(spi_layer_bank_w);
DECLARE_WRITE32_MEMBER(spi_layer_enable_w);
DECLARE_WRITE16_MEMBER(tile_decrypt_key_w);
DECLARE_WRITE16_MEMBER(spi_layer_bank_w);
DECLARE_WRITE16_MEMBER(spi_layer_enable_w);
DECLARE_WRITE8_MEMBER(rf2_layer_bank_w);
DECLARE_WRITE16_MEMBER(scroll_w);
DECLARE_WRITE32_MEMBER(tilemap_dma_start_w);
DECLARE_WRITE32_MEMBER(palette_dma_start_w);
DECLARE_WRITE16_MEMBER(sprite_dma_start_w);
@ -140,8 +140,6 @@ public:
void register_video_state();
void init_spi_common();
void init_sei252();
void init_rise10();
void init_rise11();
DECLARE_DRIVER_INIT(batlball);
DECLARE_DRIVER_INIT(senkyu);
DECLARE_DRIVER_INIT(viprp1);
@ -152,4 +150,13 @@ public:
DECLARE_DRIVER_INIT(rdft2);
DECLARE_DRIVER_INIT(ejanhs);
DECLARE_DRIVER_INIT(sys386f);
void text_decrypt(UINT8 *rom);
void bg_decrypt(UINT8 *rom, int size);
void rdft2_text_decrypt(UINT8 *rom);
void rdft2_bg_decrypt(UINT8 *rom, int size);
void rfjet_text_decrypt(UINT8 *rom);
void rfjet_bg_decrypt(UINT8 *rom, int size);
};

View File

@ -4,28 +4,6 @@
#include "emu.h"
#include "machine/seibuspi.h"
/**************************************************************************
Tile encryption
---------------
The tile graphics encryption uses the same algorithm in all games, with
different keys for the SPI, RISE10 and RISE11 custom chips.
- Take 24 bits of gfx data (used to decrypt 4 pixels at 6 bpp) and perform
a bit permutation on them (the permutation is the same in all games).
- Take the low 12 bits of the tile code and add a 24-bit number (KEY1) to it.
- Add the two 24-bit numbers resulting from the above steps, but with a
catch: while performing the sum, some bits generate carry as usual, other
bits don't, depending on a 24-bit key (KEY2). Note that the carry generated
by bit 23 (if enabled) wraps around to bit 0.
- XOR the result with a 24-bit number (KEY3).
The decryption is actually programmable; the games write the key to the
custom IC on startup!! (writes to 000414)
**************************************************************************/
// add two numbers generating carry from one bit to the next only if
// the corresponding bit in carry_mask is 1
static UINT32 partial_carry_sum(UINT32 add1,UINT32 add2,UINT32 carry_mask,int bits)
@ -59,7 +37,7 @@ UINT32 partial_carry_sum32(UINT32 add1,UINT32 add2,UINT32 carry_mask)
return partial_carry_sum(add1,add2,carry_mask,32);
}
static UINT32 partial_carry_sum24(UINT32 add1,UINT32 add2,UINT32 carry_mask)
UINT32 partial_carry_sum24(UINT32 add1,UINT32 add2,UINT32 carry_mask)
{
return partial_carry_sum(add1,add2,carry_mask,24);
}
@ -71,116 +49,259 @@ static UINT32 partial_carry_sum16(UINT32 add1,UINT32 add2,UINT32 carry_mask)
static UINT32 decrypt_tile(UINT32 val, int tileno, UINT32 key1, UINT32 key2, UINT32 key3)
{
val = BITSWAP24(val, 18,19,9,5, 10,17,16,20, 21,22,6,11, 15,14,4,23, 0,1,7,8, 13,12,3,2);
#if 0
key tables: table[n] is the column of bit n
cpu #0 (PC=0033C2F5): unmapped program memory dword write to 00000530 = 0000xxxx & FFFFFFFF (256 times, see key_table[])
return partial_carry_sum24( val, tileno + key1, key2 ) ^ key3;
cpu #0 (PC=0033C315): unmapped program memory dword write to 00000524 = 843A0000 & FFFFFFFF
cpu #0 (PC=0033C315): unmapped program memory dword write to 00000524 = 3A590000 & FFFFFFFF
cpu #0 (PC=0033C315): unmapped program memory dword write to 00000524 = C8E20000 & FFFFFFFF
cpu #0 (PC=0033C315): unmapped program memory dword write to 00000524 = 28D40000 & FFFFFFFF
cpu #0 (PC=0033C315): unmapped program memory dword write to 00000524 = 9F840000 & FFFFFFFF
cpu #0 (PC=0033C315): unmapped program memory dword write to 00000524 = 9CAC0000 & FFFFFFFF
#endif
/*
This is the main key as written by the game.
There are 256 values; the one to use is key_table[(address >> 8) & 0xff].
Bits 0-3 select the permutation on 16 bits of the source data.
Bits 4-14 are added to the source data, with partial carry.
Bit 15 is still unknown.
*/
static const UINT16 key_table[256]=
{
0x3ad7,0x54b1,0x2d41,0x8ca0,0xa69b,0x9018,0x9db9,0x6559,
0xe9a7,0xb087,0x8a5e,0x821c,0xaafc,0x2ae7,0x557b,0xcd80,
0xcfee,0x653e,0x9b31,0x7ab5,0x8b2a,0xbda8,0x707a,0x3c83,
0xcbb7,0x7157,0x8226,0x5c4a,0x8bf2,0x6397,0x13e2,0x3102,
0x8093,0x44cd,0x5f2d,0x7639,0xa7a4,0x9974,0x5263,0x8318,
0xb78c,0xa120,0xafb4,0x615f,0x6e0b,0x1d7d,0x8c29,0x4466,
0x3f35,0x794e,0xaea6,0x601c,0xe478,0xcf6e,0x4ee3,0xa009,
0x4b99,0x51d3,0x3474,0x3e4d,0xe5b7,0x9088,0xb5c0,0xba9f,
0x5646,0xa0af,0x970b,0xb14f,0x8216,0x2386,0x496d,0x9245,
0x7e4c,0xad5f,0x89d9,0xb801,0xdf64,0x8ca8,0xe019,0xde9b,
0x6836,0x70e2,0x7dcd,0x7ac1,0x98ef,0x71aa,0x7d6f,0x70bd,
0x9e14,0x75b6,0x8153,0xab6c,0x1f85,0x79cd,0xb2a1,0x934a,
0x6f74,0x37d7,0xa05a,0x6563,0x1972,0x2dcd,0x7e59,0x6a60,
0x5163,0x84c4,0xc451,0x8d80,0x4287,0x57e8,0xacc9,0x539d,
0xbe71,0xdb7c,0x9424,0xb224,0xcc0f,0xe3dd,0xb79c,0x461e,
0x96a9,0x4c7c,0x5443,0x6b2b,0x3cdc,0xbee8,0x2602,0x3282,
0x7f9c,0x59c3,0xc69a,0x39f4,0x5138,0xb7ca,0x6ca7,0x62e7,
0xc455,0x56cf,0x8a9a,0x695c,0x5af2,0xdebf,0x4dbb,0xdaec,
0xb564,0xc89c,0x7d2d,0x6dc3,0xa15a,0x6584,0xb8ea,0xb7ac,
0x88d8,0xc5aa,0x98c5,0xc506,0xc13c,0x7f59,0xab65,0x8fc8,
0x3a3c,0xd5f6,0x554d,0x5682,0x8ce7,0x40fc,0x8fd7,0x535c,
0x6aa0,0x52fe,0x8834,0x5316,0x6c27,0x80a9,0x9e6f,0x2c08,
0x4092,0xc7c1,0xc468,0x9520,0xbc4d,0xb621,0x3cdb,0xdce8,
0x481f,0xd0bd,0x3a57,0x807e,0x3025,0x5aa0,0x5e49,0xa29b,
0xd2d6,0x7bee,0x97f0,0xe28e,0x2fff,0x48e4,0x6367,0x933f,
0x57c5,0x28d4,0x68a0,0xd22e,0x39a6,0x9d2b,0x7a64,0x7e72,
0x5379,0xe86c,0x7554,0x8fbb,0xc06a,0x9533,0x7eec,0x4d52,
0xa800,0x5d35,0xa47d,0xe515,0x8d19,0x703b,0x5a2e,0x627c,
0x7cea,0x1b2c,0x5a05,0x8598,0x9e00,0xcf01,0x62d9,0x7a10,
0x1f42,0x87ce,0x575d,0x6e23,0x86ef,0x93c2,0x3d1a,0x89aa,
0xe199,0xba1d,0x1b72,0x4513,0x5131,0xc23c,0xba9f,0xa069,
0xfbfb,0xda92,0x42b2,0x3a48,0xdb96,0x5fad,0xba96,0xc6eb,
};
#if 0
{ // table[15] NOT USED!
0,0,0,1,1,1,1,0,1,1,1,1,1,0,0,1,1,0,1,0,1,1,0,0,1,0,1,0,1,0,0,0,
1,0,0,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,1,0,1,1,0,1,0,0,0,0,1,1,1,1,
0,1,1,1,1,0,0,1,0,1,1,1,1,1,1,1,0,0,0,0,1,0,0,0,1,0,1,1,0,0,1,1,
0,0,1,0,0,0,0,0,0,1,1,1,0,0,1,0,1,1,1,1,1,1,1,0,1,0,0,0,0,1,0,0,
0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,1,1,0,0,1,0,1,1,1,1,1,1,1,0,1,1,
0,1,0,0,1,0,1,0,0,0,1,0,0,1,1,0,0,1,1,1,1,1,0,1,0,1,0,1,0,0,0,1,
1,0,1,1,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,1,1,0,0,1,0,1,1,1,0,0,0,
0,0,0,1,1,1,0,0,0,1,0,0,1,1,0,1,1,1,0,0,0,1,1,1,1,1,0,0,1,0,1,1,
},
#endif
static const UINT8 bitswap[16][16] =
{
{ 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, },
{ 7, 6, 5,14, 0,15, 4, 3, 2, 8, 9,10,11,12,13, 1, },
{ 9,15,14,13,12, 0, 1, 2,10, 8, 7, 6, 5, 4, 3,11, },
{ 5, 4, 3, 2, 9,14,13,12,11, 6, 7, 8, 1,15, 0,10, },
{ 12,11, 0, 7, 8, 5, 6,15,10,13,14, 1, 2, 3, 4, 9, },
{ 14, 0, 1, 2, 3, 9, 8, 7,15, 5, 6,13,12,11,10, 4, },
{ 13,12,11,10, 2, 7, 8, 9, 0,14,15, 3, 4, 5, 6, 1, },
{ 2, 9,10,11,12, 7, 6, 5,14, 3, 4, 0,15, 1, 8,13, },
{ 8, 7, 4, 3, 2,13,12,11, 0, 9,10,14,15, 6, 5, 1, },
{ 3, 2,10,11,12, 5,14, 0, 1, 4,15, 6, 7, 8, 9,13, },
{ 2,10, 6, 5, 4,14,13,12,11, 1, 0,15, 9, 8, 7, 3, },
{ 12,11, 8, 1,15, 3, 2, 9,10,13,14, 4, 5, 6, 7, 0, },
{ 8, 7, 0,11,12, 5, 6,15,14, 9,10, 1, 2, 3, 4,13, },
{ 3, 2, 1, 0,14, 9, 8, 7, 6, 4,15,13,12,11,10, 5, },
{ 2,10,11,12,13, 7, 8, 9,15, 1, 0, 3, 4, 5, 6,14, },
{ 12,11,10, 9, 2, 7, 6, 5, 4,13,14, 0,15, 1, 8, 3, },
};
static int key(int table,int addr)
{
int xorbit = 8 + ((table & 0xc) >> 2);
return BIT(key_table[addr & 0xff] >> 4,table) ^ BIT(addr,xorbit);
}
static void decrypt_text(UINT8 *rom, UINT32 key1, UINT32 key2, UINT32 key3)
void seibuspi_sprite_decrypt(UINT8 *src, int rom_size)
{
int i;
for(i=0; i<0x10000; i++)
for(i = 0; i < rom_size/2; i++)
{
UINT32 w;
int j;
int addr = i>>8;
int y1,y2,y3;
int s1,s2;
int add1,add2;
int plane0,plane1,plane2,plane3,plane4,plane5;
const UINT8 *bs;
w = (rom[(i*3) + 0] << 16) | (rom[(i*3) + 1] << 8) | (rom[(i*3) +2]);
y1 = src[2*i+0*rom_size+0] + (src[2*i+0*rom_size+1] << 8);
y2 = src[2*i+1*rom_size+0] + (src[2*i+1*rom_size+1] << 8);
y3 = src[2*i+2*rom_size+0] + (src[2*i+2*rom_size+1] << 8);
w = decrypt_tile(w, i >> 4, key1, key2, key3);
rom[(i*3) + 0] = (w >> 16) & 0xff;
rom[(i*3) + 1] = (w >> 8) & 0xff;
rom[(i*3) + 2] = w & 0xff;
}
}
/* first of all, permutate 16 of the 48 bits */
bs = bitswap[key_table[addr & 0xff]&0xf];
y3 = BITSWAP16(y3, bs[0],bs[1],bs[2],bs[3],bs[4],bs[5],bs[6],bs[7],
bs[8],bs[9],bs[10],bs[11],bs[12],bs[13],bs[14],bs[15]);
static void decrypt_bg(UINT8 *rom, int size, UINT32 key1, UINT32 key2, UINT32 key3)
{
int i,j;
for(j=0; j<size; j+=0xc0000)
{
for(i=0; i<0x40000; i++)
// planes 4 & 5, interleaved
s1 = (BIT(y1, 4) << 0) |
(BIT(y3, 7) << 1) |
(BIT(y3, 6) << 2) |
(BIT(y2,12) << 3) |
(BIT(y2, 3) << 4) |
(BIT(y1,10) << 5) |
(BIT(y1, 1) << 6) |
(BIT(y3,14) << 7) |
(BIT(y3, 2) << 8) |
(BIT(y2, 9) << 9) |
(BIT(y2, 0) << 10) |
(BIT(y1, 7) << 11) |
(BIT(y3,12) << 12) |
(BIT(y2,15) << 13) |
(BIT(y2, 6) << 14) |
(BIT(y1,13) << 15);
add1 = (BIT(addr,11) << 0) |
(BIT(addr,10) << 1) |
(key(10,addr) << 2) |
(key( 5,addr) << 3) |
(key( 4,addr) << 4) |
(BIT(addr,11) << 5) |
(BIT(addr,11) << 6) |
(key( 7,addr) << 7) |
(key( 6,addr) << 8) |
(key( 1,addr) << 9) |
(key( 0,addr) << 10) |
(BIT(addr,11) << 11) |
(key( 9,addr) << 12) |
(key( 8,addr) << 13) |
(key( 3,addr) << 14) |
(key( 2,addr) << 15);
// planes 0-3, interleaved
s2 = (BIT(y1, 5) << 0) |
(BIT(y3, 0) << 1) |
(BIT(y3, 5) << 2) |
(BIT(y2,13) << 3) |
(BIT(y2, 4) << 4) |
(BIT(y1,11) << 5) |
(BIT(y1, 2) << 6) |
(BIT(y3, 9) << 7) |
(BIT(y3, 3) << 8) |
(BIT(y2, 8) << 9) |
(BIT(y1,15) << 10) |
(BIT(y1, 6) << 11) |
(BIT(y3,11) << 12) |
(BIT(y2,14) << 13) |
(BIT(y2, 5) << 14) |
(BIT(y1,12) << 15) |
(BIT(y1, 3) << 16) |
(BIT(y3, 8) << 17) |
(BIT(y3,15) << 18) |
(BIT(y2,11) << 19) |
(BIT(y2, 2) << 20) |
(BIT(y1, 9) << 21) |
(BIT(y1, 0) << 22) |
(BIT(y3,10) << 23) |
(BIT(y3, 1) << 24) |
(BIT(y2,10) << 25) |
(BIT(y2, 1) << 26) |
(BIT(y1, 8) << 27) |
(BIT(y3,13) << 28) |
(BIT(y3, 4) << 29) |
(BIT(y2, 7) << 30) |
(BIT(y1,14) << 31);
add2 = (key( 0,addr) << 0) |
(key( 1,addr) << 1) |
(key( 2,addr) << 2) |
(key( 3,addr) << 3) |
(key( 4,addr) << 4) |
(key( 5,addr) << 5) |
(key( 6,addr) << 6) |
(key( 7,addr) << 7) |
(key( 8,addr) << 8) |
(key( 9,addr) << 9) |
(key(10,addr) << 10) |
(BIT(addr,10) << 11) |
(BIT(addr,11) << 12) |
(BIT(addr,11) << 13) |
(BIT(addr,11) << 14) |
(BIT(addr,11) << 15) |
(BIT(addr,11) << 16) |
(key( 7,addr) << 17) |
(BIT(addr,11) << 18) |
(key( 6,addr) << 19) |
(BIT(addr,11) << 20) |
(key( 5,addr) << 21) |
(BIT(addr,11) << 22) |
(key( 4,addr) << 23) |
(BIT(addr,10) << 24) |
(key( 3,addr) << 25) |
(key(10,addr) << 26) |
(key( 2,addr) << 27) |
(key( 9,addr) << 28) |
(key( 1,addr) << 29) |
(key( 8,addr) << 30) |
(key( 0,addr) << 31);
s1 = partial_carry_sum( s1, add1, 0x3a59, 16 ) ^ 0x843a;
s2 = partial_carry_sum( s2, add2, 0x28d49cac, 32 ) ^ 0xc8e29f84;
// reorder the bits in the order MAME expects to decode the graphics
plane0 = plane1 = plane2 = plane3 = plane4 = plane5 = 0;
for (j = 0;j < 8;j++)
{
UINT32 w;
w = (rom[j + (i*3) + 0] << 16) | (rom[j + (i*3) + 1] << 8) | (rom[j + (i*3) + 2]);
w = decrypt_tile(w, i >> 6, key1, key2, key3);
rom[j + (i*3) + 0] = (w >> 16) & 0xff;
rom[j + (i*3) + 1] = (w >> 8) & 0xff;
rom[j + (i*3) + 2] = w & 0xff;
plane5 |= (BIT(s1, 2*j+1) << j);
plane4 |= (BIT(s1, 2*j+0) << j);
plane3 |= (BIT(s2, 4*j+3) << j);
plane2 |= (BIT(s2, 4*j+2) << j);
plane1 |= (BIT(s2, 4*j+1) << j);
plane0 |= (BIT(s2, 4*j+0) << j);
}
src[2*i+0*rom_size+0] = plane5;
src[2*i+0*rom_size+1] = plane4;
src[2*i+1*rom_size+0] = plane3;
src[2*i+1*rom_size+1] = plane2;
src[2*i+2*rom_size+0] = plane1;
src[2*i+2*rom_size+1] = plane0;
}
}
/******************************************************************************************
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 00000000 & 0000FFFF
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 0000DF5B & 0000FFFF
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 000078CF & 0000FFFF
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 00001377 & 0000FFFF
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 00002538 & 0000FFFF
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 00004535 & 0000FFFF
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 06DC0000 & FFFF0000
******************************************************************************************/
void seibuspi_text_decrypt(UINT8 *rom)
{
decrypt_text( rom, 0x5a3845, 0x77cf5b, 0x1378df);
}
void seibuspi_bg_decrypt(UINT8 *rom, int size)
{
decrypt_bg( rom, size, 0x5a3845, 0x77cf5b, 0x1378df);
}
/******************************************************************************************
cpu #0 (PC=002A097D): unmapped program memory dword write to 00000414 = 00000001 & 0000FFFF
cpu #0 (PC=002A097D): unmapped program memory dword write to 00000414 = 0000DCF8 & 0000FFFF
cpu #0 (PC=002A097D): unmapped program memory dword write to 00000414 = 00007AE2 & 0000FFFF
cpu #0 (PC=002A097D): unmapped program memory dword write to 00000414 = 0000154D & 0000FFFF
cpu #0 (PC=002A097D): unmapped program memory dword write to 00000414 = 00001731 & 0000FFFF
cpu #0 (PC=002A097D): unmapped program memory dword write to 00000414 = 0000466B & 0000FFFF
cpu #0 (PC=002A097D): unmapped program memory dword write to 00000414 = 3EDC0000 & FFFF0000
******************************************************************************************/
/* RISE10 (Raiden Fighters 2) */
void seibuspi_rise10_text_decrypt(UINT8 *rom)
{
decrypt_text( rom, 0x823146, 0x4de2f8, 0x157adc);
}
void seibuspi_rise10_bg_decrypt(UINT8 *rom, int size)
{
decrypt_bg( rom, size, 0x823146, 0x4de2f8, 0x157adc);
}
/******************************************************************************************
cpu #0 (PC=002C40F9): unmapped program memory dword write to 00000414 = 00000001 & 0000FFFF
cpu #0 (PC=002C40F9): unmapped program memory dword write to 00000414 = 00006630 & 0000FFFF
cpu #0 (PC=002C40F9): unmapped program memory dword write to 00000414 = 0000B685 & 0000FFFF
cpu #0 (PC=002C40F9): unmapped program memory dword write to 00000414 = 0000CCFE & 0000FFFF
cpu #0 (PC=002C40F9): unmapped program memory dword write to 00000414 = 000032A7 & 0000FFFF
cpu #0 (PC=002C40F9): unmapped program memory dword write to 00000414 = 0000547C & 0000FFFF
cpu #0 (PC=002C40F9): unmapped program memory dword write to 00000414 = 3EDC0000 & FFFF0000
******************************************************************************************/
/* RISE11 (Raiden Fighters Jet) */
void seibuspi_rise11_text_decrypt(UINT8 *rom)
{
decrypt_text( rom, 0xaea754, 0xfe8530, 0xccb666);
}
void seibuspi_rise11_bg_decrypt(UINT8 *rom, int size)
{
decrypt_bg( rom, size, 0xaea754, 0xfe8530, 0xccb666);
}

View File

@ -1,18 +1,12 @@
// license:BSD-3-Clause
// copyright-holders:Ville Linde, Nicola Salmoria
// TODO: modernize code (spisprit.c too)
// TODO: modernize code
UINT32 partial_carry_sum32(UINT32 add1,UINT32 add2,UINT32 carry_mask);
UINT32 partial_carry_sum24(UINT32 add1,UINT32 add2,UINT32 carry_mask);
void seibuspi_text_decrypt(UINT8 *rom);
void seibuspi_bg_decrypt(UINT8 *rom, int size);
void seibuspi_rise10_text_decrypt(UINT8 *rom);
void seibuspi_rise10_bg_decrypt(UINT8 *rom, int size);
void seibuspi_sprite_decrypt(UINT8 *src, int romsize);
void seibuspi_rise10_sprite_decrypt(UINT8 *rom, int romsize);
void seibuspi_rise11_text_decrypt(UINT8 *rom);
void seibuspi_rise11_bg_decrypt(UINT8 *rom, int size);
void seibuspi_rise11_sprite_decrypt_rfjet(UINT8 *rom, int romsize);
void seibuspi_rise11_sprite_decrypt_feversoc(UINT8 *rom, int romsize);

View File

@ -1,286 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Ville Linde, Nicola Salmoria
#if 0
key tables: table[n] is the column of bit n
cpu #0 (PC=0033C2F5): unmapped program memory dword write to 00000530 = 0000xxxx & FFFFFFFF (256 times, see key_table[])
cpu #0 (PC=0033C315): unmapped program memory dword write to 00000524 = 843A0000 & FFFFFFFF
cpu #0 (PC=0033C315): unmapped program memory dword write to 00000524 = 3A590000 & FFFFFFFF
cpu #0 (PC=0033C315): unmapped program memory dword write to 00000524 = C8E20000 & FFFFFFFF
cpu #0 (PC=0033C315): unmapped program memory dword write to 00000524 = 28D40000 & FFFFFFFF
cpu #0 (PC=0033C315): unmapped program memory dword write to 00000524 = 9F840000 & FFFFFFFF
cpu #0 (PC=0033C315): unmapped program memory dword write to 00000524 = 9CAC0000 & FFFFFFFF
#endif
#include "emu.h"
#include "includes/seibuspi.h"
// add two numbers generating carry from one bit to the next only if
// the corresponding bit in carry_mask is 1
static int partial_carry_sum(int add1,int add2,int carry_mask,int bits)
{
int i,res,carry;
res = 0;
carry = 0;
for (i = 0;i < bits;i++)
{
int bit = BIT(add1,i) + BIT(add2,i) + carry;
res += (bit & 1) << i;
// generate carry only if the corresponding bit in carry_mask is 1
if (BIT(carry_mask,i))
carry = bit >> 1;
else
carry = 0;
}
// wrap around carry from top bit to bit 0
if (carry)
res ^=1;
return res;
}
/*
This is the main key as written by the game.
There are 256 values; the one to use is key_table[(address >> 8) & 0xff].
Bits 0-3 select the permutation on 16 bits of the source data.
Bits 4-14 are added to the source data, with partial carry.
Bit 15 is still unknown.
*/
static const UINT16 key_table[256]=
{
0x3ad7,0x54b1,0x2d41,0x8ca0,0xa69b,0x9018,0x9db9,0x6559,
0xe9a7,0xb087,0x8a5e,0x821c,0xaafc,0x2ae7,0x557b,0xcd80,
0xcfee,0x653e,0x9b31,0x7ab5,0x8b2a,0xbda8,0x707a,0x3c83,
0xcbb7,0x7157,0x8226,0x5c4a,0x8bf2,0x6397,0x13e2,0x3102,
0x8093,0x44cd,0x5f2d,0x7639,0xa7a4,0x9974,0x5263,0x8318,
0xb78c,0xa120,0xafb4,0x615f,0x6e0b,0x1d7d,0x8c29,0x4466,
0x3f35,0x794e,0xaea6,0x601c,0xe478,0xcf6e,0x4ee3,0xa009,
0x4b99,0x51d3,0x3474,0x3e4d,0xe5b7,0x9088,0xb5c0,0xba9f,
0x5646,0xa0af,0x970b,0xb14f,0x8216,0x2386,0x496d,0x9245,
0x7e4c,0xad5f,0x89d9,0xb801,0xdf64,0x8ca8,0xe019,0xde9b,
0x6836,0x70e2,0x7dcd,0x7ac1,0x98ef,0x71aa,0x7d6f,0x70bd,
0x9e14,0x75b6,0x8153,0xab6c,0x1f85,0x79cd,0xb2a1,0x934a,
0x6f74,0x37d7,0xa05a,0x6563,0x1972,0x2dcd,0x7e59,0x6a60,
0x5163,0x84c4,0xc451,0x8d80,0x4287,0x57e8,0xacc9,0x539d,
0xbe71,0xdb7c,0x9424,0xb224,0xcc0f,0xe3dd,0xb79c,0x461e,
0x96a9,0x4c7c,0x5443,0x6b2b,0x3cdc,0xbee8,0x2602,0x3282,
0x7f9c,0x59c3,0xc69a,0x39f4,0x5138,0xb7ca,0x6ca7,0x62e7,
0xc455,0x56cf,0x8a9a,0x695c,0x5af2,0xdebf,0x4dbb,0xdaec,
0xb564,0xc89c,0x7d2d,0x6dc3,0xa15a,0x6584,0xb8ea,0xb7ac,
0x88d8,0xc5aa,0x98c5,0xc506,0xc13c,0x7f59,0xab65,0x8fc8,
0x3a3c,0xd5f6,0x554d,0x5682,0x8ce7,0x40fc,0x8fd7,0x535c,
0x6aa0,0x52fe,0x8834,0x5316,0x6c27,0x80a9,0x9e6f,0x2c08,
0x4092,0xc7c1,0xc468,0x9520,0xbc4d,0xb621,0x3cdb,0xdce8,
0x481f,0xd0bd,0x3a57,0x807e,0x3025,0x5aa0,0x5e49,0xa29b,
0xd2d6,0x7bee,0x97f0,0xe28e,0x2fff,0x48e4,0x6367,0x933f,
0x57c5,0x28d4,0x68a0,0xd22e,0x39a6,0x9d2b,0x7a64,0x7e72,
0x5379,0xe86c,0x7554,0x8fbb,0xc06a,0x9533,0x7eec,0x4d52,
0xa800,0x5d35,0xa47d,0xe515,0x8d19,0x703b,0x5a2e,0x627c,
0x7cea,0x1b2c,0x5a05,0x8598,0x9e00,0xcf01,0x62d9,0x7a10,
0x1f42,0x87ce,0x575d,0x6e23,0x86ef,0x93c2,0x3d1a,0x89aa,
0xe199,0xba1d,0x1b72,0x4513,0x5131,0xc23c,0xba9f,0xa069,
0xfbfb,0xda92,0x42b2,0x3a48,0xdb96,0x5fad,0xba96,0xc6eb,
};
#if 0
{ // table[15] NOT USED!
0,0,0,1,1,1,1,0,1,1,1,1,1,0,0,1,1,0,1,0,1,1,0,0,1,0,1,0,1,0,0,0,
1,0,0,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,1,0,1,1,0,1,0,0,0,0,1,1,1,1,
0,1,1,1,1,0,0,1,0,1,1,1,1,1,1,1,0,0,0,0,1,0,0,0,1,0,1,1,0,0,1,1,
0,0,1,0,0,0,0,0,0,1,1,1,0,0,1,0,1,1,1,1,1,1,1,0,1,0,0,0,0,1,0,0,
0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,1,1,0,0,1,0,1,1,1,1,1,1,1,0,1,1,
0,1,0,0,1,0,1,0,0,0,1,0,0,1,1,0,0,1,1,1,1,1,0,1,0,1,0,1,0,0,0,1,
1,0,1,1,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,1,1,0,0,1,0,1,1,1,0,0,0,
0,0,0,1,1,1,0,0,0,1,0,0,1,1,0,1,1,1,0,0,0,1,1,1,1,1,0,0,1,0,1,1,
},
#endif
static const UINT8 bitswap[16][16] =
{
{ 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, },
{ 7, 6, 5,14, 0,15, 4, 3, 2, 8, 9,10,11,12,13, 1, },
{ 9,15,14,13,12, 0, 1, 2,10, 8, 7, 6, 5, 4, 3,11, },
{ 5, 4, 3, 2, 9,14,13,12,11, 6, 7, 8, 1,15, 0,10, },
{ 12,11, 0, 7, 8, 5, 6,15,10,13,14, 1, 2, 3, 4, 9, },
{ 14, 0, 1, 2, 3, 9, 8, 7,15, 5, 6,13,12,11,10, 4, },
{ 13,12,11,10, 2, 7, 8, 9, 0,14,15, 3, 4, 5, 6, 1, },
{ 2, 9,10,11,12, 7, 6, 5,14, 3, 4, 0,15, 1, 8,13, },
{ 8, 7, 4, 3, 2,13,12,11, 0, 9,10,14,15, 6, 5, 1, },
{ 3, 2,10,11,12, 5,14, 0, 1, 4,15, 6, 7, 8, 9,13, },
{ 2,10, 6, 5, 4,14,13,12,11, 1, 0,15, 9, 8, 7, 3, },
{ 12,11, 8, 1,15, 3, 2, 9,10,13,14, 4, 5, 6, 7, 0, },
{ 8, 7, 0,11,12, 5, 6,15,14, 9,10, 1, 2, 3, 4,13, },
{ 3, 2, 1, 0,14, 9, 8, 7, 6, 4,15,13,12,11,10, 5, },
{ 2,10,11,12,13, 7, 8, 9,15, 1, 0, 3, 4, 5, 6,14, },
{ 12,11,10, 9, 2, 7, 6, 5, 4,13,14, 0,15, 1, 8, 3, },
};
static int key(int table,int addr)
{
int xorbit = 8 + ((table & 0xc) >> 2);
return BIT(key_table[addr & 0xff] >> 4,table) ^ BIT(addr,xorbit);
}
void seibuspi_sprite_decrypt(UINT8 *src, int rom_size)
{
int i;
for(i = 0; i < rom_size/2; i++)
{
int j;
int addr = i>>8;
int y1,y2,y3;
int s1,s2;
int add1,add2;
int plane0,plane1,plane2,plane3,plane4,plane5;
const UINT8 *bs;
y1 = src[2*i+0*rom_size+0] + (src[2*i+0*rom_size+1] << 8);
y2 = src[2*i+1*rom_size+0] + (src[2*i+1*rom_size+1] << 8);
y3 = src[2*i+2*rom_size+0] + (src[2*i+2*rom_size+1] << 8);
/* first of all, permutate 16 of the 48 bits */
bs = bitswap[key_table[addr & 0xff]&0xf];
y3 = BITSWAP16(y3, bs[0],bs[1],bs[2],bs[3],bs[4],bs[5],bs[6],bs[7],
bs[8],bs[9],bs[10],bs[11],bs[12],bs[13],bs[14],bs[15]);
// planes 4 & 5, interleaved
s1 = (BIT(y1, 4) << 0) |
(BIT(y3, 7) << 1) |
(BIT(y3, 6) << 2) |
(BIT(y2,12) << 3) |
(BIT(y2, 3) << 4) |
(BIT(y1,10) << 5) |
(BIT(y1, 1) << 6) |
(BIT(y3,14) << 7) |
(BIT(y3, 2) << 8) |
(BIT(y2, 9) << 9) |
(BIT(y2, 0) << 10) |
(BIT(y1, 7) << 11) |
(BIT(y3,12) << 12) |
(BIT(y2,15) << 13) |
(BIT(y2, 6) << 14) |
(BIT(y1,13) << 15);
add1 = (BIT(addr,11) << 0) |
(BIT(addr,10) << 1) |
(key(10,addr) << 2) |
(key( 5,addr) << 3) |
(key( 4,addr) << 4) |
(BIT(addr,11) << 5) |
(BIT(addr,11) << 6) |
(key( 7,addr) << 7) |
(key( 6,addr) << 8) |
(key( 1,addr) << 9) |
(key( 0,addr) << 10) |
(BIT(addr,11) << 11) |
(key( 9,addr) << 12) |
(key( 8,addr) << 13) |
(key( 3,addr) << 14) |
(key( 2,addr) << 15);
// planes 0-3, interleaved
s2 = (BIT(y1, 5) << 0) |
(BIT(y3, 0) << 1) |
(BIT(y3, 5) << 2) |
(BIT(y2,13) << 3) |
(BIT(y2, 4) << 4) |
(BIT(y1,11) << 5) |
(BIT(y1, 2) << 6) |
(BIT(y3, 9) << 7) |
(BIT(y3, 3) << 8) |
(BIT(y2, 8) << 9) |
(BIT(y1,15) << 10) |
(BIT(y1, 6) << 11) |
(BIT(y3,11) << 12) |
(BIT(y2,14) << 13) |
(BIT(y2, 5) << 14) |
(BIT(y1,12) << 15) |
(BIT(y1, 3) << 16) |
(BIT(y3, 8) << 17) |
(BIT(y3,15) << 18) |
(BIT(y2,11) << 19) |
(BIT(y2, 2) << 20) |
(BIT(y1, 9) << 21) |
(BIT(y1, 0) << 22) |
(BIT(y3,10) << 23) |
(BIT(y3, 1) << 24) |
(BIT(y2,10) << 25) |
(BIT(y2, 1) << 26) |
(BIT(y1, 8) << 27) |
(BIT(y3,13) << 28) |
(BIT(y3, 4) << 29) |
(BIT(y2, 7) << 30) |
(BIT(y1,14) << 31);
add2 = (key( 0,addr) << 0) |
(key( 1,addr) << 1) |
(key( 2,addr) << 2) |
(key( 3,addr) << 3) |
(key( 4,addr) << 4) |
(key( 5,addr) << 5) |
(key( 6,addr) << 6) |
(key( 7,addr) << 7) |
(key( 8,addr) << 8) |
(key( 9,addr) << 9) |
(key(10,addr) << 10) |
(BIT(addr,10) << 11) |
(BIT(addr,11) << 12) |
(BIT(addr,11) << 13) |
(BIT(addr,11) << 14) |
(BIT(addr,11) << 15) |
(BIT(addr,11) << 16) |
(key( 7,addr) << 17) |
(BIT(addr,11) << 18) |
(key( 6,addr) << 19) |
(BIT(addr,11) << 20) |
(key( 5,addr) << 21) |
(BIT(addr,11) << 22) |
(key( 4,addr) << 23) |
(BIT(addr,10) << 24) |
(key( 3,addr) << 25) |
(key(10,addr) << 26) |
(key( 2,addr) << 27) |
(key( 9,addr) << 28) |
(key( 1,addr) << 29) |
(key( 8,addr) << 30) |
(key( 0,addr) << 31);
s1 = partial_carry_sum( s1, add1, 0x3a59, 16 ) ^ 0x843a;
s2 = partial_carry_sum( s2, add2, 0x28d49cac, 32 ) ^ 0xc8e29f84;
// reorder the bits in the order MAME expects to decode the graphics
plane0 = plane1 = plane2 = plane3 = plane4 = plane5 = 0;
for (j = 0;j < 8;j++)
{
plane5 |= (BIT(s1, 2*j+1) << j);
plane4 |= (BIT(s1, 2*j+0) << j);
plane3 |= (BIT(s2, 4*j+3) << j);
plane2 |= (BIT(s2, 4*j+2) << j);
plane1 |= (BIT(s2, 4*j+1) << j);
plane0 |= (BIT(s2, 4*j+0) << j);
}
src[2*i+0*rom_size+0] = plane5;
src[2*i+0*rom_size+1] = plane4;
src[2*i+1*rom_size+0] = plane3;
src[2*i+1*rom_size+1] = plane2;
src[2*i+2*rom_size+0] = plane1;
src[2*i+2*rom_size+1] = plane0;
}
}

View File

@ -1,4 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Ville Linde, Nicola Salmoria
void seibuspi_sprite_decrypt(UINT8 *src, int romsize);

View File

@ -54,6 +54,13 @@ preliminary memory map:
[0x38]: Tilemap Screen 3 base scroll X
[0x3a]: Tilemap Screen 3 base scroll Y
[0x3e]: OBJ Y base
[0x40]: Semaphore for 0x4e register
In later games using the SEI251, SEI252 and RISE sprite chips, registers
0x40 through 0x4e appear to be either nonexistent or overridden. The aberrant
mapping of these registers in some games is not unusual for Seibu customs,
but it should be noted that SD Gundam Psycho Salamander relegates the
initialization of these registers to a separate routine.
===========================================================================================
@ -125,12 +132,12 @@ List of default vregs (title screen):
0C0030: 01C2 01FF **** **** 00C0 01FF 0034 003F
0C0040: 0000 A8A8 0006 1830 0009 **** **** ****
*SD Gundam Psycho Salamander no Kyoui (320 x 224 -> 0 - 224 v res)
*SD Gundam Psycho Salamander no Kyoui (init routines at $4b56 and $13fc; 320 x 224 -> 0 - 224 v res)
0C0000: 000F 0013 009F 00BF 00FA 000F 00FA 00FF
0C0010: 0076 0006 0000 0002 0000 0000 0000 0000
0C0020: 0000 0000 0000 0000 0000 0000 0040 01FF
0C0030: 0040 01FF 0040 01FF 0040 01FF 0034 003F
0C0040: 0000 A8A8 0003 1C37 0009 0000 0000 0000
0C0040: **** A8A8 0003 1C37 0009 **** **** ****
*D-Con (320 x 224 -> 0 - 224 v res)
0C0000: 000F 0013 009F 00BF 00FA 000F 00FA 00FF
@ -193,7 +200,6 @@ List of default vregs (title screen):
00000414: related to decryption
00000418: fg layer bank, rowscroll enable, ...
0000041C-0000043F: same as other chips (layer enable, scrollregs, base)
00000440-0000044F: unused, not written to at all
***************************************************************************/
@ -210,13 +216,20 @@ List of default vregs (title screen):
const device_type SEIBU_CRTC = &device_creator<seibu_crtc_device>;
static ADDRESS_MAP_START( seibu_crtc_vregs, AS_0, 16, seibu_crtc_device )
AM_RANGE(0x0014, 0x0015) AM_WRITE(decrypt_key_w)
AM_RANGE(0x001a, 0x001b) AM_READWRITE(reg_1a_r, reg_1a_w)
AM_RANGE(0x001c, 0x001d) AM_WRITE(layer_en_w)
AM_RANGE(0x001a, 0x001b) AM_WRITE(reg_1a_w)
AM_RANGE(0x0020, 0x002b) AM_WRITE(layer_scroll_w)
AM_RANGE(0x002c, 0x003b) AM_WRITE(layer_scroll_base_w)
AM_RANGE(0x0000, 0x004f) AM_RAM // debug
ADDRESS_MAP_END
WRITE16_MEMBER(seibu_crtc_device::decrypt_key_w)
{
if (!m_decrypt_key_cb.isnull())
m_decrypt_key_cb(0, data, mem_mask);
}
WRITE16_MEMBER( seibu_crtc_device::layer_en_w)
{
if (!m_layer_en_cb.isnull())
@ -229,8 +242,15 @@ WRITE16_MEMBER( seibu_crtc_device::layer_scroll_w)
m_layer_scroll_cb(offset,data,mem_mask);
}
READ16_MEMBER(seibu_crtc_device::reg_1a_r)
{
// SPI needs read/write access to this
return m_reg_1a;
}
WRITE16_MEMBER( seibu_crtc_device::reg_1a_w)
{
COMBINE_DATA(&m_reg_1a);
if (!m_reg_1a_cb.isnull())
m_reg_1a_cb(offset,data,mem_mask);
}
@ -253,6 +273,7 @@ seibu_crtc_device::seibu_crtc_device(const machine_config &mconfig, const char *
: device_t(mconfig, SEIBU_CRTC, "Seibu CRT Controller", tag, owner, clock, "seibu_crtc", __FILE__),
device_memory_interface(mconfig, *this),
device_video_interface(mconfig, *this),
m_decrypt_key_cb(*this),
m_layer_en_cb(*this),
m_layer_scroll_cb(*this),
m_reg_1a_cb(*this),
@ -277,10 +298,13 @@ void seibu_crtc_device::device_validity_check(validity_checker &valid) const
void seibu_crtc_device::device_start()
{
m_decrypt_key_cb.resolve();
m_layer_en_cb.resolve();
m_layer_scroll_cb.resolve();
m_reg_1a_cb.resolve();
m_layer_scroll_base_cb.resolve();
save_item(NAME(m_reg_1a));
}
@ -290,6 +314,7 @@ void seibu_crtc_device::device_start()
void seibu_crtc_device::device_reset()
{
m_reg_1a = 0;
}
//-------------------------------------------------

View File

@ -16,6 +16,9 @@
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
#define MCFG_SEIBU_CRTC_DECRYPT_KEY_CB(_devcb) \
devcb = &seibu_crtc_device::set_decrypt_key_callback(*device, DEVCB_##_devcb);
#define MCFG_SEIBU_CRTC_LAYER_EN_CB(_devcb) \
devcb = &seibu_crtc_device::set_layer_en_callback(*device, DEVCB_##_devcb);
@ -43,6 +46,7 @@ public:
// construction/destruction
seibu_crtc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
template<class _Object> static devcb_base &set_decrypt_key_callback(device_t &device, _Object object) { return downcast<seibu_crtc_device &>(device).m_decrypt_key_cb.set_callback(object); }
template<class _Object> static devcb_base &set_layer_en_callback(device_t &device, _Object object) { return downcast<seibu_crtc_device &>(device).m_layer_en_cb.set_callback(object); }
template<class _Object> static devcb_base &set_layer_scroll_callback(device_t &device, _Object object) { return downcast<seibu_crtc_device &>(device).m_layer_scroll_cb.set_callback(object); }
template<class _Object> static devcb_base &set_reg_1a_callback(device_t &device, _Object object) { return downcast<seibu_crtc_device &>(device).m_reg_1a_cb.set_callback(object); }
@ -55,7 +59,9 @@ public:
DECLARE_READ16_MEMBER( read );
DECLARE_READ16_MEMBER( read_alt );
DECLARE_READ16_MEMBER( read_xor );
DECLARE_WRITE16_MEMBER(decrypt_key_w);
DECLARE_WRITE16_MEMBER(layer_en_w);
DECLARE_READ16_MEMBER(reg_1a_r);
DECLARE_WRITE16_MEMBER(reg_1a_w);
DECLARE_WRITE16_MEMBER(layer_scroll_w);
DECLARE_WRITE16_MEMBER(layer_scroll_base_w);
@ -68,6 +74,7 @@ protected:
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const override;
private:
devcb_write16 m_decrypt_key_cb;
devcb_write16 m_layer_en_cb;
devcb_write16 m_layer_scroll_cb;
devcb_write16 m_reg_1a_cb;
@ -75,6 +82,8 @@ private:
const address_space_config m_space_config;
inline UINT16 read_word(offs_t address);
inline void write_word(offs_t address, UINT16 data);
UINT16 m_reg_1a;
};

View File

@ -10,6 +10,142 @@
#include "emu.h"
#include "includes/seibuspi.h"
#include "machine/seibuspi.h"
/**************************************************************************
Tile encryption
---------------
The tile graphics encryption uses the same algorithm in all games. This is
similar to, but simpler than, that used by the SEI252, RISE10 and RISE11
custom chips.
- Take 24 bits of gfx data (used to decrypt 4 pixels at 6 bpp) and perform
a bit permutation on them (the permutation is the same in all games).
- Take the low 12 bits of the tile code and add a 24-bit number (KEY1) to it.
- Add the two 24-bit numbers resulting from the above steps, but with a
catch: while performing the sum, some bits generate carry as usual, other
bits don't, depending on a 24-bit key (KEY2). Note that the carry generated
by bit 23 (if enabled) wraps around to bit 0.
- XOR the result with a 24-bit number (KEY3).
The decryption is actually programmable; the games write the key to the
custom CRTC on startup!! (writes to 000414)
**************************************************************************/
static UINT32 decrypt_tile(UINT32 val, int tileno, UINT32 key1, UINT32 key2, UINT32 key3)
{
val = BITSWAP24(val, 18,19,9,5, 10,17,16,20, 21,22,6,11, 15,14,4,23, 0,1,7,8, 13,12,3,2);
return partial_carry_sum24( val, tileno + key1, key2 ) ^ key3;
}
static void decrypt_text(UINT8 *rom, UINT32 key1, UINT32 key2, UINT32 key3)
{
int i;
for(i=0; i<0x10000; i++)
{
UINT32 w;
w = (rom[(i*3) + 0] << 16) | (rom[(i*3) + 1] << 8) | (rom[(i*3) +2]);
w = decrypt_tile(w, i >> 4, key1, key2, key3);
rom[(i*3) + 0] = (w >> 16) & 0xff;
rom[(i*3) + 1] = (w >> 8) & 0xff;
rom[(i*3) + 2] = w & 0xff;
}
}
static void decrypt_bg(UINT8 *rom, int size, UINT32 key1, UINT32 key2, UINT32 key3)
{
int i,j;
for(j=0; j<size; j+=0xc0000)
{
for(i=0; i<0x40000; i++)
{
UINT32 w;
w = (rom[j + (i*3) + 0] << 16) | (rom[j + (i*3) + 1] << 8) | (rom[j + (i*3) + 2]);
w = decrypt_tile(w, i >> 6, key1, key2, key3);
rom[j + (i*3) + 0] = (w >> 16) & 0xff;
rom[j + (i*3) + 1] = (w >> 8) & 0xff;
rom[j + (i*3) + 2] = w & 0xff;
}
}
}
/******************************************************************************************
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 00000000 & 0000FFFF
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 0000DF5B & 0000FFFF
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 000078CF & 0000FFFF
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 00001377 & 0000FFFF
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 00002538 & 0000FFFF
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 00004535 & 0000FFFF
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 06DC0000 & FFFF0000
******************************************************************************************/
void seibuspi_state::text_decrypt(UINT8 *rom)
{
decrypt_text( rom, 0x5a3845, 0x77cf5b, 0x1378df);
}
void seibuspi_state::bg_decrypt(UINT8 *rom, int size)
{
decrypt_bg( rom, size, 0x5a3845, 0x77cf5b, 0x1378df);
}
/******************************************************************************************
cpu #0 (PC=002A097D): unmapped program memory dword write to 00000414 = 00000001 & 0000FFFF
cpu #0 (PC=002A097D): unmapped program memory dword write to 00000414 = 0000DCF8 & 0000FFFF
cpu #0 (PC=002A097D): unmapped program memory dword write to 00000414 = 00007AE2 & 0000FFFF
cpu #0 (PC=002A097D): unmapped program memory dword write to 00000414 = 0000154D & 0000FFFF
cpu #0 (PC=002A097D): unmapped program memory dword write to 00000414 = 00001731 & 0000FFFF
cpu #0 (PC=002A097D): unmapped program memory dword write to 00000414 = 0000466B & 0000FFFF
cpu #0 (PC=002A097D): unmapped program memory dword write to 00000414 = 3EDC0000 & FFFF0000
******************************************************************************************/
void seibuspi_state::rdft2_text_decrypt(UINT8 *rom)
{
decrypt_text( rom, 0x823146, 0x4de2f8, 0x157adc);
}
void seibuspi_state::rdft2_bg_decrypt(UINT8 *rom, int size)
{
decrypt_bg( rom, size, 0x823146, 0x4de2f8, 0x157adc);
}
/******************************************************************************************
cpu #0 (PC=002C40F9): unmapped program memory dword write to 00000414 = 00000001 & 0000FFFF
cpu #0 (PC=002C40F9): unmapped program memory dword write to 00000414 = 00006630 & 0000FFFF
cpu #0 (PC=002C40F9): unmapped program memory dword write to 00000414 = 0000B685 & 0000FFFF
cpu #0 (PC=002C40F9): unmapped program memory dword write to 00000414 = 0000CCFE & 0000FFFF
cpu #0 (PC=002C40F9): unmapped program memory dword write to 00000414 = 000032A7 & 0000FFFF
cpu #0 (PC=002C40F9): unmapped program memory dword write to 00000414 = 0000547C & 0000FFFF
cpu #0 (PC=002C40F9): unmapped program memory dword write to 00000414 = 3EDC0000 & FFFF0000
******************************************************************************************/
void seibuspi_state::rfjet_text_decrypt(UINT8 *rom)
{
decrypt_text( rom, 0xaea754, 0xfe8530, 0xccb666);
}
void seibuspi_state::rfjet_bg_decrypt(UINT8 *rom, int size)
{
decrypt_bg( rom, size, 0xaea754, 0xfe8530, 0xccb666);
}
WRITE16_MEMBER(seibuspi_state::tile_decrypt_key_w)
{
if (data != 0 && data != 1)
logerror("Decryption key: %04X\n", data);
}
/*****************************************************************************/
@ -29,30 +165,27 @@ void seibuspi_state::set_layer_offsets()
m_text_layer_offset = 0x3000 / 4 / 2;
}
m_fore_layer_d13 = m_layer_bank >> 14 & 0x2000;
m_fore_layer_d13 = m_layer_bank << 2 & 0x2000;
m_back_layer_d14 = m_rf2_layer_bank << 14 & 0x4000;
m_midl_layer_d14 = m_rf2_layer_bank << 13 & 0x4000;
m_fore_layer_d14 = m_rf2_layer_bank << 12 & 0x4000;
}
READ32_MEMBER(seibuspi_state::spi_layer_bank_r)
WRITE16_MEMBER(seibuspi_state::spi_layer_bank_w)
{
return m_layer_bank;
}
//logerror("Writing %04X to layer register\n", data);
WRITE32_MEMBER(seibuspi_state::spi_layer_bank_w)
{
// r000f000 0010100a 00000000 00000000
// r000f000 0010100a
// r: rowscroll enable
// f: fore layer d13
// a: ? (0 in ejanhs and rdft22kc, 1 in all other games)
UINT32 prev = m_layer_bank;
UINT16 prev = m_layer_bank;
COMBINE_DATA(&m_layer_bank);
m_rowscroll_enable = m_layer_bank >> 31 & 1;
m_rowscroll_enable = m_layer_bank >> 15 & 1;
set_layer_offsets();
if ((prev ^ m_layer_bank) & 0x08000000)
if ((prev ^ m_layer_bank) & 0x0800)
m_fore_layer->mark_all_dirty();
}
@ -77,9 +210,9 @@ WRITE8_MEMBER(seibuspi_state::rf2_layer_bank_w)
m_fore_layer->mark_all_dirty();
}
WRITE32_MEMBER(seibuspi_state::spi_layer_enable_w)
WRITE16_MEMBER(seibuspi_state::spi_layer_enable_w)
{
// 00000000 00000000 00000000 000stfmb (0=on, 1=off)
// 00000000 000stfmb (0=on, 1=off)
// s: sprite layer
// t: text layer
// f: fore layer
@ -88,6 +221,11 @@ WRITE32_MEMBER(seibuspi_state::spi_layer_enable_w)
COMBINE_DATA(&m_layer_enable);
}
WRITE16_MEMBER(seibuspi_state::scroll_w)
{
COMBINE_DATA(&m_scrollram[offset]);
}
WRITE32_MEMBER(seibuspi_state::video_dma_length_w)
{
COMBINE_DATA(&m_video_dma_length);
@ -480,20 +618,20 @@ UINT32 seibuspi_state::screen_update_spi(screen_device &screen, bitmap_rgb32 &bi
if (m_layer_enable & 1)
bitmap.fill(0, cliprect);
else
combine_tilemap(bitmap, cliprect, m_back_layer, m_scrollram[0] & 0xffff, (m_scrollram[0] >> 16) & 0xffff, 1, back_rowscroll);
combine_tilemap(bitmap, cliprect, m_back_layer, m_scrollram[0], m_scrollram[1], 1, back_rowscroll);
draw_sprites(bitmap, cliprect, screen.priority(), 0);
// if fore layer is enabled, draw priority 0 sprites behind back layer
if ((m_layer_enable & 0x15) == 0)
combine_tilemap(bitmap, cliprect, m_back_layer, m_scrollram[0] & 0xffff, (m_scrollram[0] >> 16) & 0xffff, 0, back_rowscroll);
combine_tilemap(bitmap, cliprect, m_back_layer, m_scrollram[0], m_scrollram[1], 0, back_rowscroll);
// if fore layer is enabled, draw priority 1 sprites behind middle layer
if (~m_layer_enable & 4)
draw_sprites(bitmap, cliprect, screen.priority(), 1);
if (~m_layer_enable & 2)
combine_tilemap(bitmap, cliprect, m_midl_layer, m_scrollram[1] & 0xffff, (m_scrollram[1] >> 16) & 0xffff, 0, midl_rowscroll);
combine_tilemap(bitmap, cliprect, m_midl_layer, m_scrollram[2], m_scrollram[3], 0, midl_rowscroll);
// if fore layer is disabled, draw priority 1 sprites above middle layer
if (m_layer_enable & 4)
@ -502,7 +640,7 @@ UINT32 seibuspi_state::screen_update_spi(screen_device &screen, bitmap_rgb32 &bi
draw_sprites(bitmap, cliprect, screen.priority(), 2);
if (~m_layer_enable & 4)
combine_tilemap(bitmap, cliprect, m_fore_layer, m_scrollram[2] & 0xffff, (m_scrollram[2] >> 16) & 0xffff, 0, fore_rowscroll);
combine_tilemap(bitmap, cliprect, m_fore_layer, m_scrollram[4], m_scrollram[5], 0, fore_rowscroll);
draw_sprites(bitmap, cliprect, screen.priority(), 3);
@ -587,6 +725,12 @@ void seibuspi_state::video_start()
m_layer_bank = 0;
m_rf2_layer_bank = 0;
m_rowscroll_enable = 0;
m_scrollram[0] = 0;
m_scrollram[1] = 0;
m_scrollram[2] = 0;
m_scrollram[3] = 0;
m_scrollram[4] = 0;
m_scrollram[5] = 0;
set_layer_offsets();
UINT32 region_length = memregion("gfx2")->bytes();
@ -682,6 +826,7 @@ void seibuspi_state::register_video_state()
save_item(NAME(m_layer_bank));
save_item(NAME(m_rf2_layer_bank));
save_item(NAME(m_rowscroll_enable));
save_item(NAME(m_scrollram));
save_item(NAME(m_midl_layer_offset));
save_item(NAME(m_fore_layer_offset));