mirror of
https://github.com/holub/mame
synced 2025-10-06 09:00:04 +03:00
Merge pull request #1112 from ajrhacker/spicrtc
Hook up Seibu CRTC to SPI System
This commit is contained in:
commit
5d18d1170f
@ -3279,8 +3279,6 @@ files {
|
|||||||
MAME_DIR .. "src/mame/drivers/r2dx_v33.cpp",
|
MAME_DIR .. "src/mame/drivers/r2dx_v33.cpp",
|
||||||
MAME_DIR .. "src/mame/drivers/seibuspi.cpp",
|
MAME_DIR .. "src/mame/drivers/seibuspi.cpp",
|
||||||
MAME_DIR .. "src/mame/includes/seibuspi.h",
|
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/video/seibuspi.cpp",
|
||||||
MAME_DIR .. "src/mame/drivers/sengokmj.cpp",
|
MAME_DIR .. "src/mame/drivers/sengokmj.cpp",
|
||||||
MAME_DIR .. "src/mame/drivers/stfight.cpp",
|
MAME_DIR .. "src/mame/drivers/stfight.cpp",
|
||||||
@ -3295,8 +3293,8 @@ files {
|
|||||||
MAME_DIR .. "src/mame/video/wiz.cpp",
|
MAME_DIR .. "src/mame/video/wiz.cpp",
|
||||||
MAME_DIR .. "src/mame/machine/seicop.cpp",
|
MAME_DIR .. "src/mame/machine/seicop.cpp",
|
||||||
MAME_DIR .. "src/mame/machine/seicop.h",
|
MAME_DIR .. "src/mame/machine/seicop.h",
|
||||||
MAME_DIR .. "src/mame/machine/spisprit.cpp",
|
MAME_DIR .. "src/mame/machine/seibuspi.cpp",
|
||||||
MAME_DIR .. "src/mame/machine/spisprit.h",
|
MAME_DIR .. "src/mame/machine/seibuspi.h",
|
||||||
MAME_DIR .. "src/mame/audio/seibu.cpp",
|
MAME_DIR .. "src/mame/audio/seibu.cpp",
|
||||||
MAME_DIR .. "src/mame/audio/seibu.h",
|
MAME_DIR .. "src/mame/audio/seibu.h",
|
||||||
MAME_DIR .. "src/mame/video/seibu_crtc.cpp",
|
MAME_DIR .. "src/mame/video/seibu_crtc.cpp",
|
||||||
|
@ -196,8 +196,8 @@ static ADDRESS_MAP_START( feversoc_map, AS_PROGRAM, 32, feversoc_state )
|
|||||||
AM_RANGE(0x06000004, 0x06000007) AM_WRITENOP //???
|
AM_RANGE(0x06000004, 0x06000007) AM_WRITENOP //???
|
||||||
AM_RANGE(0x06000008, 0x0600000b) AM_READ(in0_r)
|
AM_RANGE(0x06000008, 0x0600000b) AM_READ(in0_r)
|
||||||
AM_RANGE(0x0600000c, 0x0600000f) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0x00ff0000)
|
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(0x06010000, 0x0601007f) AM_DEVREADWRITE("obj", seibu_encrypted_sprite_device, read, write) AM_RAM
|
||||||
AM_RANGE(0x06010060, 0x06010063) AM_WRITENOP
|
AM_RANGE(0x06010060, 0x06010063) AM_WRITENOP // sprite buffering
|
||||||
AM_RANGE(0x06018000, 0x06019fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
|
AM_RANGE(0x06018000, 0x06019fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
|
||||||
ADDRESS_MAP_END
|
ADDRESS_MAP_END
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ static ADDRESS_MAP_START( legionna_map, AS_PROGRAM, 16, legionna_state )
|
|||||||
AM_RANGE(0x000000, 0x07ffff) AM_ROM
|
AM_RANGE(0x000000, 0x07ffff) AM_ROM
|
||||||
AM_RANGE(0x100000, 0x1003ff) AM_RAM
|
AM_RANGE(0x100000, 0x1003ff) AM_RAM
|
||||||
AM_RANGE(0x100470, 0x100471) AM_WRITENOP // toggles 0x2000 / 0x0000, tile bank on some games
|
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(0x100680, 0x100681) AM_WRITENOP // irq ack?
|
||||||
AM_RANGE(0x100700, 0x10071f) AM_READWRITE(sound_comms_r,sound_comms_w)
|
AM_RANGE(0x100700, 0x10071f) AM_READWRITE(sound_comms_r,sound_comms_w)
|
||||||
AM_RANGE(0x100740, 0x100741) AM_READ_PORT("DSW1")
|
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(0x000000, 0x07ffff) AM_ROM
|
||||||
AM_RANGE(0x100000, 0x1003ff) AM_RAM
|
AM_RANGE(0x100000, 0x1003ff) AM_RAM
|
||||||
AM_RANGE(0x100470, 0x100471) AM_WRITE(denjinmk_setgfxbank)
|
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(0x100680, 0x100681) AM_WRITENOP // irq ack?
|
||||||
AM_RANGE(0x100700, 0x10071f) AM_READWRITE(sound_comms_r,sound_comms_w)
|
AM_RANGE(0x100700, 0x10071f) AM_READWRITE(sound_comms_r,sound_comms_w)
|
||||||
AM_RANGE(0x100740, 0x100741) AM_READ_PORT("DSW1")
|
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(0x000000, 0x0fffff) AM_ROM
|
||||||
AM_RANGE(0x100000, 0x1003ff) AM_RAM
|
AM_RANGE(0x100000, 0x1003ff) AM_RAM
|
||||||
AM_RANGE(0x100470, 0x100471) AM_WRITE(denjinmk_setgfxbank)
|
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(0x100680, 0x100681) AM_WRITENOP // irq ack?
|
||||||
AM_RANGE(0x100700, 0x10071f) AM_READWRITE(denjinmk_sound_comms_r,sound_comms_w)
|
AM_RANGE(0x100700, 0x10071f) AM_READWRITE(denjinmk_sound_comms_r,sound_comms_w)
|
||||||
AM_RANGE(0x100740, 0x100741) AM_READ_PORT("DSW1")
|
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(0x000000, 0x0fffff) AM_ROM
|
||||||
AM_RANGE(0x100000, 0x1003ff) AM_RAM
|
AM_RANGE(0x100000, 0x1003ff) AM_RAM
|
||||||
AM_RANGE(0x100480, 0x100487) AM_WRITE(grainbow_layer_config_w) // probably a COP feature
|
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(0x100680, 0x100681) AM_WRITENOP // irq ack?
|
||||||
AM_RANGE(0x100700, 0x10071f) AM_READWRITE(sound_comms_r,sound_comms_w)
|
AM_RANGE(0x100700, 0x10071f) AM_READWRITE(sound_comms_r,sound_comms_w)
|
||||||
AM_RANGE(0x100740, 0x100741) AM_READ_PORT("DSW1")
|
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_IMPORT_FROM( legionna_cop_mem )
|
||||||
AM_RANGE(0x000000, 0x0fffff) AM_ROM
|
AM_RANGE(0x000000, 0x0fffff) AM_ROM
|
||||||
AM_RANGE(0x100000, 0x1003ff) AM_RAM
|
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(0x100680, 0x100681) AM_WRITENOP // irq ack?
|
||||||
AM_RANGE(0x100700, 0x10071f) AM_READWRITE(sound_comms_r,sound_comms_w)
|
AM_RANGE(0x100700, 0x10071f) AM_READWRITE(sound_comms_r,sound_comms_w)
|
||||||
AM_RANGE(0x100740, 0x100741) AM_READ_PORT("DSW1")
|
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_IMPORT_FROM( legionna_cop_mem )
|
||||||
AM_RANGE(0x000000, 0x0fffff) AM_ROM
|
AM_RANGE(0x000000, 0x0fffff) AM_ROM
|
||||||
AM_RANGE(0x100000, 0x1003ff) AM_RAM
|
AM_RANGE(0x100000, 0x1003ff) AM_RAM
|
||||||
AM_RANGE(0x100600, 0x10060f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)//?
|
AM_RANGE(0x100600, 0x10067f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read_xor, write_xor)
|
||||||
AM_RANGE(0x100640, 0x10067f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
|
|
||||||
AM_RANGE(0x100680, 0x100681) AM_WRITENOP // irq ack?
|
AM_RANGE(0x100680, 0x100681) AM_WRITENOP // irq ack?
|
||||||
AM_RANGE(0x100700, 0x100701) AM_READ_PORT("DSW1")
|
AM_RANGE(0x100700, 0x100701) AM_READ_PORT("DSW1")
|
||||||
AM_RANGE(0x100704, 0x100705) AM_READ_PORT("PLAYERS12")
|
AM_RANGE(0x100704, 0x100705) AM_READ_PORT("PLAYERS12")
|
||||||
|
@ -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(0x00434, 0x00435) AM_READ(r2dx_sin_r)
|
||||||
AM_RANGE(0x00436, 0x00437) AM_READ(r2dx_cos_r)
|
AM_RANGE(0x00436, 0x00437) AM_READ(r2dx_cos_r)
|
||||||
|
|
||||||
AM_RANGE(0x00600, 0x0064f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
|
AM_RANGE(0x00600, 0x0063f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
|
||||||
// AM_RANGE(0x00650, 0x0068f) AM_RAM //???
|
//AM_RANGE(0x00640, 0x006bf) AM_DEVREADWRITE("obj", seibu_encrypted_sprite_device, read, write)
|
||||||
|
AM_RANGE(0x0068e, 0x0068f) AM_WRITENOP // sprite buffering
|
||||||
AM_RANGE(0x0068e, 0x0068f) AM_WRITENOP // maybe a watchdog?
|
|
||||||
AM_RANGE(0x006b0, 0x006b1) AM_WRITE(mcu_prog_w) // could be encryption key uploads just like raiden2.c ?
|
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(0x006b2, 0x006b3) AM_WRITE(mcu_prog_w2)
|
||||||
// AM_RANGE(0x006b4, 0x006b5) AM_WRITENOP
|
// 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(0x00434, 0x00435) AM_READ(r2dx_sin_r)
|
||||||
AM_RANGE(0x00436, 0x00437) AM_READ(r2dx_cos_r)
|
AM_RANGE(0x00436, 0x00437) AM_READ(r2dx_cos_r)
|
||||||
|
|
||||||
AM_RANGE(0x00600, 0x0064f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
|
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 // synch for the MCU?
|
AM_RANGE(0x0068e, 0x0068f) AM_WRITENOP // sprite buffering
|
||||||
AM_RANGE(0x006b0, 0x006b1) AM_WRITE(mcu_prog_w)
|
AM_RANGE(0x006b0, 0x006b1) AM_WRITE(mcu_prog_w)
|
||||||
AM_RANGE(0x006b2, 0x006b3) AM_WRITE(mcu_prog_w2)
|
AM_RANGE(0x006b2, 0x006b3) AM_WRITE(mcu_prog_w2)
|
||||||
// AM_RANGE(0x006b4, 0x006b5) AM_WRITENOP
|
// AM_RANGE(0x006b4, 0x006b5) AM_WRITENOP
|
||||||
|
@ -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(0x005b2, 0x005b3) AM_DEVREAD("raiden2cop", raiden2cop_device, cop_dist_r)
|
||||||
AM_RANGE(0x005b4, 0x005b5) AM_DEVREAD("raiden2cop", raiden2cop_device, cop_angle_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, 0x0063f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
|
||||||
AM_RANGE(0x00600, 0x0064f) AM_DEVREADWRITE("crtc", seibu_crtc_device, read, write)
|
//AM_RANGE(0x00640, 0x006bf) AM_DEVREADWRITE("obj", seibu_encrypted_sprite_device, read, write)
|
||||||
// AM_RANGE(0x0061c, 0x0061d) AM_WRITE(tilemap_enable_w)
|
|
||||||
// AM_RANGE(0x00620, 0x0062b) AM_WRITE(tile_scroll_w)
|
|
||||||
AM_RANGE(0x006a0, 0x006a3) AM_WRITE(sprcpt_val_1_w)
|
AM_RANGE(0x006a0, 0x006a3) AM_WRITE(sprcpt_val_1_w)
|
||||||
AM_RANGE(0x006a4, 0x006a7) AM_WRITE(sprcpt_data_3_w)
|
AM_RANGE(0x006a4, 0x006a7) AM_WRITE(sprcpt_data_3_w)
|
||||||
AM_RANGE(0x006a8, 0x006ab) AM_WRITE(sprcpt_data_4_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 )
|
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(0x00470, 0x00471) AM_READWRITE(cop_tile_bank_2_r,raidendx_cop_bank_2_w)
|
||||||
AM_RANGE(0x004d0, 0x004d7) AM_RAM //???
|
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_RANGE(0x006ca, 0x006cb) AM_WRITENOP
|
||||||
AM_IMPORT_FROM( raiden2_mem )
|
AM_IMPORT_FROM( raiden2_mem )
|
||||||
ADDRESS_MAP_END
|
ADDRESS_MAP_END
|
||||||
|
@ -855,7 +855,7 @@ Notes:
|
|||||||
#include "sound/ymf271.h"
|
#include "sound/ymf271.h"
|
||||||
#include "sound/ymz280b.h"
|
#include "sound/ymz280b.h"
|
||||||
#include "machine/seibuspi.h"
|
#include "machine/seibuspi.h"
|
||||||
#include "machine/spisprit.h"
|
#include "video/seibu_crtc.h"
|
||||||
#include "includes/seibuspi.h"
|
#include "includes/seibuspi.h"
|
||||||
|
|
||||||
// default values written to CRTC (note: SYS386F does not have this chip)
|
// 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 )
|
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(0x00000400, 0x0000043f) AM_DEVREADWRITE16("crtc", seibu_crtc_device, read, write, 0xffffffff)
|
||||||
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(0x00000480, 0x00000483) AM_WRITE(tilemap_dma_start_w)
|
AM_RANGE(0x00000480, 0x00000483) AM_WRITE(tilemap_dma_start_w)
|
||||||
AM_RANGE(0x00000484, 0x00000487) AM_WRITE(palette_dma_start_w)
|
AM_RANGE(0x00000484, 0x00000487) AM_WRITE(palette_dma_start_w)
|
||||||
AM_RANGE(0x00000490, 0x00000493) AM_WRITE(video_dma_length_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
|
ADDRESS_MAP_END
|
||||||
|
|
||||||
static ADDRESS_MAP_START( sei252_map, AS_PROGRAM, 32, seibuspi_state )
|
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(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(0x00000524, 0x00000527) AM_WRITENOP // SEI252 sprite decryption key, see machine/spisprit.c
|
||||||
AM_RANGE(0x00000528, 0x0000052b) AM_WRITENOP // SEI252 sprite decryption unknown
|
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
|
ADDRESS_MAP_END
|
||||||
|
|
||||||
static ADDRESS_MAP_START( rise_map, AS_PROGRAM, 32, seibuspi_state )
|
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(0x0000054c, 0x0000054f) AM_WRITENOP // RISE10/11 sprite decryption key, see machine/seibuspi.c
|
||||||
AM_RANGE(0x00000560, 0x00000563) AM_WRITE16(sprite_dma_start_w, 0xffff0000)
|
AM_RANGE(0x00000560, 0x00000563) AM_WRITE16(sprite_dma_start_w, 0xffff0000)
|
||||||
ADDRESS_MAP_END
|
ADDRESS_MAP_END
|
||||||
@ -1809,28 +1808,12 @@ void seibuspi_state::init_spi_common()
|
|||||||
|
|
||||||
void seibuspi_state::init_sei252()
|
void seibuspi_state::init_sei252()
|
||||||
{
|
{
|
||||||
seibuspi_text_decrypt(memregion("gfx1")->base());
|
text_decrypt(memregion("gfx1")->base());
|
||||||
seibuspi_bg_decrypt(memregion("gfx2")->base(), memregion("gfx2")->bytes());
|
bg_decrypt(memregion("gfx2")->base(), memregion("gfx2")->bytes());
|
||||||
seibuspi_sprite_decrypt(memregion("gfx3")->base(), 0x400000);
|
seibuspi_sprite_decrypt(memregion("gfx3")->base(), 0x400000);
|
||||||
init_spi_common();
|
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()
|
void seibuspi_state::machine_start()
|
||||||
{
|
{
|
||||||
@ -1886,6 +1869,12 @@ static MACHINE_CONFIG_START( spi, seibuspi_state )
|
|||||||
|
|
||||||
MCFG_PALETTE_ADD_INIT_BLACK("palette", 6144)
|
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 */
|
/* sound hardware */
|
||||||
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
|
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_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 */
|
/* sound hardware */
|
||||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||||
|
|
||||||
@ -2109,13 +2104,21 @@ DRIVER_INIT_MEMBER(seibuspi_state,rdft)
|
|||||||
DRIVER_INIT_MEMBER(seibuspi_state,rdft2)
|
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));
|
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)
|
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));
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ public:
|
|||||||
m_maincpu(*this, "maincpu"),
|
m_maincpu(*this, "maincpu"),
|
||||||
m_audiocpu(*this, "audiocpu"),
|
m_audiocpu(*this, "audiocpu"),
|
||||||
m_mainram(*this, "mainram"),
|
m_mainram(*this, "mainram"),
|
||||||
m_scrollram(*this, "scrollram"),
|
|
||||||
m_z80_rom(*this, "audiocpu"),
|
m_z80_rom(*this, "audiocpu"),
|
||||||
m_eeprom(*this, "eeprom"),
|
m_eeprom(*this, "eeprom"),
|
||||||
m_soundflash1(*this, "soundflash1"),
|
m_soundflash1(*this, "soundflash1"),
|
||||||
@ -35,7 +34,6 @@ public:
|
|||||||
required_device<cpu_device> m_maincpu;
|
required_device<cpu_device> m_maincpu;
|
||||||
optional_device<cpu_device> m_audiocpu;
|
optional_device<cpu_device> m_audiocpu;
|
||||||
required_shared_ptr<UINT32> m_mainram;
|
required_shared_ptr<UINT32> m_mainram;
|
||||||
optional_shared_ptr<UINT32> m_scrollram;
|
|
||||||
optional_memory_region m_z80_rom;
|
optional_memory_region m_z80_rom;
|
||||||
optional_device<eeprom_serial_93cxx_device> m_eeprom;
|
optional_device<eeprom_serial_93cxx_device> m_eeprom;
|
||||||
optional_device<intel_e28f008sa_device> m_soundflash1;
|
optional_device<intel_e28f008sa_device> m_soundflash1;
|
||||||
@ -57,9 +55,10 @@ public:
|
|||||||
tilemap_t *m_fore_layer;
|
tilemap_t *m_fore_layer;
|
||||||
UINT32 m_video_dma_length;
|
UINT32 m_video_dma_length;
|
||||||
UINT32 m_video_dma_address;
|
UINT32 m_video_dma_address;
|
||||||
UINT32 m_layer_enable;
|
UINT16 m_layer_enable;
|
||||||
UINT32 m_layer_bank;
|
UINT16 m_layer_bank;
|
||||||
UINT8 m_rf2_layer_bank;
|
UINT8 m_rf2_layer_bank;
|
||||||
|
UINT16 m_scrollram[6];
|
||||||
int m_rowscroll_enable;
|
int m_rowscroll_enable;
|
||||||
int m_midl_layer_offset;
|
int m_midl_layer_offset;
|
||||||
int m_fore_layer_offset;
|
int m_fore_layer_offset;
|
||||||
@ -78,10 +77,11 @@ public:
|
|||||||
UINT8 m_alpha_table[0x2000];
|
UINT8 m_alpha_table[0x2000];
|
||||||
int m_sprite_bpp;
|
int m_sprite_bpp;
|
||||||
|
|
||||||
DECLARE_READ32_MEMBER(spi_layer_bank_r);
|
DECLARE_WRITE16_MEMBER(tile_decrypt_key_w);
|
||||||
DECLARE_WRITE32_MEMBER(spi_layer_bank_w);
|
DECLARE_WRITE16_MEMBER(spi_layer_bank_w);
|
||||||
DECLARE_WRITE32_MEMBER(spi_layer_enable_w);
|
DECLARE_WRITE16_MEMBER(spi_layer_enable_w);
|
||||||
DECLARE_WRITE8_MEMBER(rf2_layer_bank_w);
|
DECLARE_WRITE8_MEMBER(rf2_layer_bank_w);
|
||||||
|
DECLARE_WRITE16_MEMBER(scroll_w);
|
||||||
DECLARE_WRITE32_MEMBER(tilemap_dma_start_w);
|
DECLARE_WRITE32_MEMBER(tilemap_dma_start_w);
|
||||||
DECLARE_WRITE32_MEMBER(palette_dma_start_w);
|
DECLARE_WRITE32_MEMBER(palette_dma_start_w);
|
||||||
DECLARE_WRITE16_MEMBER(sprite_dma_start_w);
|
DECLARE_WRITE16_MEMBER(sprite_dma_start_w);
|
||||||
@ -140,8 +140,6 @@ public:
|
|||||||
void register_video_state();
|
void register_video_state();
|
||||||
void init_spi_common();
|
void init_spi_common();
|
||||||
void init_sei252();
|
void init_sei252();
|
||||||
void init_rise10();
|
|
||||||
void init_rise11();
|
|
||||||
DECLARE_DRIVER_INIT(batlball);
|
DECLARE_DRIVER_INIT(batlball);
|
||||||
DECLARE_DRIVER_INIT(senkyu);
|
DECLARE_DRIVER_INIT(senkyu);
|
||||||
DECLARE_DRIVER_INIT(viprp1);
|
DECLARE_DRIVER_INIT(viprp1);
|
||||||
@ -152,4 +150,13 @@ public:
|
|||||||
DECLARE_DRIVER_INIT(rdft2);
|
DECLARE_DRIVER_INIT(rdft2);
|
||||||
DECLARE_DRIVER_INIT(ejanhs);
|
DECLARE_DRIVER_INIT(ejanhs);
|
||||||
DECLARE_DRIVER_INIT(sys386f);
|
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);
|
||||||
};
|
};
|
||||||
|
@ -4,28 +4,6 @@
|
|||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "machine/seibuspi.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
|
// add two numbers generating carry from one bit to the next only if
|
||||||
// the corresponding bit in carry_mask is 1
|
// the corresponding bit in carry_mask is 1
|
||||||
static UINT32 partial_carry_sum(UINT32 add1,UINT32 add2,UINT32 carry_mask,int bits)
|
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);
|
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);
|
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)
|
#if 0
|
||||||
{
|
key tables: table[n] is the column of bit n
|
||||||
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);
|
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;
|
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;
|
/* first of all, permutate 16 of the 48 bits */
|
||||||
rom[(i*3) + 1] = (w >> 8) & 0xff;
|
bs = bitswap[key_table[addr & 0xff]&0xf];
|
||||||
rom[(i*3) + 2] = w & 0xff;
|
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)
|
|
||||||
|
// 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++)
|
||||||
{
|
{
|
||||||
int i,j;
|
plane5 |= (BIT(s1, 2*j+1) << j);
|
||||||
for(j=0; j<size; j+=0xc0000)
|
plane4 |= (BIT(s1, 2*j+0) << j);
|
||||||
{
|
plane3 |= (BIT(s2, 4*j+3) << j);
|
||||||
for(i=0; i<0x40000; i++)
|
plane2 |= (BIT(s2, 4*j+2) << j);
|
||||||
{
|
plane1 |= (BIT(s2, 4*j+1) << j);
|
||||||
UINT32 w;
|
plane0 |= (BIT(s2, 4*j+0) << j);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************************
|
src[2*i+0*rom_size+0] = plane5;
|
||||||
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 00000000 & 0000FFFF
|
src[2*i+0*rom_size+1] = plane4;
|
||||||
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 0000DF5B & 0000FFFF
|
src[2*i+1*rom_size+0] = plane3;
|
||||||
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 000078CF & 0000FFFF
|
src[2*i+1*rom_size+1] = plane2;
|
||||||
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 00001377 & 0000FFFF
|
src[2*i+2*rom_size+0] = plane1;
|
||||||
cpu #0 (PC=0033B2EB): unmapped program memory dword write to 00000414 = 00002538 & 0000FFFF
|
src[2*i+2*rom_size+1] = plane0;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,18 +1,12 @@
|
|||||||
// license:BSD-3-Clause
|
// license:BSD-3-Clause
|
||||||
// copyright-holders:Ville Linde, Nicola Salmoria
|
// 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_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_sprite_decrypt(UINT8 *src, int romsize);
|
||||||
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_rise10_sprite_decrypt(UINT8 *rom, 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_rfjet(UINT8 *rom, int romsize);
|
||||||
void seibuspi_rise11_sprite_decrypt_feversoc(UINT8 *rom, int romsize);
|
void seibuspi_rise11_sprite_decrypt_feversoc(UINT8 *rom, int romsize);
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
// license:BSD-3-Clause
|
|
||||||
// copyright-holders:Ville Linde, Nicola Salmoria
|
|
||||||
|
|
||||||
void seibuspi_sprite_decrypt(UINT8 *src, int romsize);
|
|
@ -54,6 +54,13 @@ preliminary memory map:
|
|||||||
[0x38]: Tilemap Screen 3 base scroll X
|
[0x38]: Tilemap Screen 3 base scroll X
|
||||||
[0x3a]: Tilemap Screen 3 base scroll Y
|
[0x3a]: Tilemap Screen 3 base scroll Y
|
||||||
[0x3e]: OBJ Y base
|
[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
|
0C0030: 01C2 01FF **** **** 00C0 01FF 0034 003F
|
||||||
0C0040: 0000 A8A8 0006 1830 0009 **** **** ****
|
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
|
0C0000: 000F 0013 009F 00BF 00FA 000F 00FA 00FF
|
||||||
0C0010: 0076 0006 0000 0002 0000 0000 0000 0000
|
0C0010: 0076 0006 0000 0002 0000 0000 0000 0000
|
||||||
0C0020: 0000 0000 0000 0000 0000 0000 0040 01FF
|
0C0020: 0000 0000 0000 0000 0000 0000 0040 01FF
|
||||||
0C0030: 0040 01FF 0040 01FF 0040 01FF 0034 003F
|
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)
|
*D-Con (320 x 224 -> 0 - 224 v res)
|
||||||
0C0000: 000F 0013 009F 00BF 00FA 000F 00FA 00FF
|
0C0000: 000F 0013 009F 00BF 00FA 000F 00FA 00FF
|
||||||
@ -193,7 +200,6 @@ List of default vregs (title screen):
|
|||||||
00000414: related to decryption
|
00000414: related to decryption
|
||||||
00000418: fg layer bank, rowscroll enable, ...
|
00000418: fg layer bank, rowscroll enable, ...
|
||||||
0000041C-0000043F: same as other chips (layer enable, scrollregs, base)
|
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>;
|
const device_type SEIBU_CRTC = &device_creator<seibu_crtc_device>;
|
||||||
|
|
||||||
static ADDRESS_MAP_START( seibu_crtc_vregs, AS_0, 16, 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(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(0x0020, 0x002b) AM_WRITE(layer_scroll_w)
|
||||||
AM_RANGE(0x002c, 0x003b) AM_WRITE(layer_scroll_base_w)
|
AM_RANGE(0x002c, 0x003b) AM_WRITE(layer_scroll_base_w)
|
||||||
AM_RANGE(0x0000, 0x004f) AM_RAM // debug
|
AM_RANGE(0x0000, 0x004f) AM_RAM // debug
|
||||||
ADDRESS_MAP_END
|
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)
|
WRITE16_MEMBER( seibu_crtc_device::layer_en_w)
|
||||||
{
|
{
|
||||||
if (!m_layer_en_cb.isnull())
|
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);
|
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)
|
WRITE16_MEMBER( seibu_crtc_device::reg_1a_w)
|
||||||
{
|
{
|
||||||
|
COMBINE_DATA(&m_reg_1a);
|
||||||
if (!m_reg_1a_cb.isnull())
|
if (!m_reg_1a_cb.isnull())
|
||||||
m_reg_1a_cb(offset,data,mem_mask);
|
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_t(mconfig, SEIBU_CRTC, "Seibu CRT Controller", tag, owner, clock, "seibu_crtc", __FILE__),
|
||||||
device_memory_interface(mconfig, *this),
|
device_memory_interface(mconfig, *this),
|
||||||
device_video_interface(mconfig, *this),
|
device_video_interface(mconfig, *this),
|
||||||
|
m_decrypt_key_cb(*this),
|
||||||
m_layer_en_cb(*this),
|
m_layer_en_cb(*this),
|
||||||
m_layer_scroll_cb(*this),
|
m_layer_scroll_cb(*this),
|
||||||
m_reg_1a_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()
|
void seibu_crtc_device::device_start()
|
||||||
{
|
{
|
||||||
|
m_decrypt_key_cb.resolve();
|
||||||
m_layer_en_cb.resolve();
|
m_layer_en_cb.resolve();
|
||||||
m_layer_scroll_cb.resolve();
|
m_layer_scroll_cb.resolve();
|
||||||
m_reg_1a_cb.resolve();
|
m_reg_1a_cb.resolve();
|
||||||
m_layer_scroll_base_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()
|
void seibu_crtc_device::device_reset()
|
||||||
{
|
{
|
||||||
|
m_reg_1a = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
// INTERFACE CONFIGURATION MACROS
|
// 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) \
|
#define MCFG_SEIBU_CRTC_LAYER_EN_CB(_devcb) \
|
||||||
devcb = &seibu_crtc_device::set_layer_en_callback(*device, DEVCB_##_devcb);
|
devcb = &seibu_crtc_device::set_layer_en_callback(*device, DEVCB_##_devcb);
|
||||||
|
|
||||||
@ -43,6 +46,7 @@ public:
|
|||||||
// construction/destruction
|
// construction/destruction
|
||||||
seibu_crtc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
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_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_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); }
|
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 );
|
||||||
DECLARE_READ16_MEMBER( read_alt );
|
DECLARE_READ16_MEMBER( read_alt );
|
||||||
DECLARE_READ16_MEMBER( read_xor );
|
DECLARE_READ16_MEMBER( read_xor );
|
||||||
|
DECLARE_WRITE16_MEMBER(decrypt_key_w);
|
||||||
DECLARE_WRITE16_MEMBER(layer_en_w);
|
DECLARE_WRITE16_MEMBER(layer_en_w);
|
||||||
|
DECLARE_READ16_MEMBER(reg_1a_r);
|
||||||
DECLARE_WRITE16_MEMBER(reg_1a_w);
|
DECLARE_WRITE16_MEMBER(reg_1a_w);
|
||||||
DECLARE_WRITE16_MEMBER(layer_scroll_w);
|
DECLARE_WRITE16_MEMBER(layer_scroll_w);
|
||||||
DECLARE_WRITE16_MEMBER(layer_scroll_base_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;
|
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
devcb_write16 m_decrypt_key_cb;
|
||||||
devcb_write16 m_layer_en_cb;
|
devcb_write16 m_layer_en_cb;
|
||||||
devcb_write16 m_layer_scroll_cb;
|
devcb_write16 m_layer_scroll_cb;
|
||||||
devcb_write16 m_reg_1a_cb;
|
devcb_write16 m_reg_1a_cb;
|
||||||
@ -75,6 +82,8 @@ private:
|
|||||||
const address_space_config m_space_config;
|
const address_space_config m_space_config;
|
||||||
inline UINT16 read_word(offs_t address);
|
inline UINT16 read_word(offs_t address);
|
||||||
inline void write_word(offs_t address, UINT16 data);
|
inline void write_word(offs_t address, UINT16 data);
|
||||||
|
|
||||||
|
UINT16 m_reg_1a;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,6 +10,142 @@
|
|||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "includes/seibuspi.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_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_back_layer_d14 = m_rf2_layer_bank << 14 & 0x4000;
|
||||||
m_midl_layer_d14 = m_rf2_layer_bank << 13 & 0x4000;
|
m_midl_layer_d14 = m_rf2_layer_bank << 13 & 0x4000;
|
||||||
m_fore_layer_d14 = m_rf2_layer_bank << 12 & 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
|
||||||
{
|
|
||||||
// r000f000 0010100a 00000000 00000000
|
|
||||||
// r: rowscroll enable
|
// r: rowscroll enable
|
||||||
// f: fore layer d13
|
// f: fore layer d13
|
||||||
// a: ? (0 in ejanhs and rdft22kc, 1 in all other games)
|
// 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);
|
COMBINE_DATA(&m_layer_bank);
|
||||||
|
|
||||||
m_rowscroll_enable = m_layer_bank >> 31 & 1;
|
m_rowscroll_enable = m_layer_bank >> 15 & 1;
|
||||||
set_layer_offsets();
|
set_layer_offsets();
|
||||||
|
|
||||||
if ((prev ^ m_layer_bank) & 0x08000000)
|
if ((prev ^ m_layer_bank) & 0x0800)
|
||||||
m_fore_layer->mark_all_dirty();
|
m_fore_layer->mark_all_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,9 +210,9 @@ WRITE8_MEMBER(seibuspi_state::rf2_layer_bank_w)
|
|||||||
m_fore_layer->mark_all_dirty();
|
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
|
// s: sprite layer
|
||||||
// t: text layer
|
// t: text layer
|
||||||
// f: fore layer
|
// f: fore layer
|
||||||
@ -88,6 +221,11 @@ WRITE32_MEMBER(seibuspi_state::spi_layer_enable_w)
|
|||||||
COMBINE_DATA(&m_layer_enable);
|
COMBINE_DATA(&m_layer_enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(seibuspi_state::scroll_w)
|
||||||
|
{
|
||||||
|
COMBINE_DATA(&m_scrollram[offset]);
|
||||||
|
}
|
||||||
|
|
||||||
WRITE32_MEMBER(seibuspi_state::video_dma_length_w)
|
WRITE32_MEMBER(seibuspi_state::video_dma_length_w)
|
||||||
{
|
{
|
||||||
COMBINE_DATA(&m_video_dma_length);
|
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)
|
if (m_layer_enable & 1)
|
||||||
bitmap.fill(0, cliprect);
|
bitmap.fill(0, cliprect);
|
||||||
else
|
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);
|
draw_sprites(bitmap, cliprect, screen.priority(), 0);
|
||||||
|
|
||||||
// if fore layer is enabled, draw priority 0 sprites behind back layer
|
// if fore layer is enabled, draw priority 0 sprites behind back layer
|
||||||
if ((m_layer_enable & 0x15) == 0)
|
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 fore layer is enabled, draw priority 1 sprites behind middle layer
|
||||||
if (~m_layer_enable & 4)
|
if (~m_layer_enable & 4)
|
||||||
draw_sprites(bitmap, cliprect, screen.priority(), 1);
|
draw_sprites(bitmap, cliprect, screen.priority(), 1);
|
||||||
|
|
||||||
if (~m_layer_enable & 2)
|
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 fore layer is disabled, draw priority 1 sprites above middle layer
|
||||||
if (m_layer_enable & 4)
|
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);
|
draw_sprites(bitmap, cliprect, screen.priority(), 2);
|
||||||
|
|
||||||
if (~m_layer_enable & 4)
|
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);
|
draw_sprites(bitmap, cliprect, screen.priority(), 3);
|
||||||
|
|
||||||
@ -587,6 +725,12 @@ void seibuspi_state::video_start()
|
|||||||
m_layer_bank = 0;
|
m_layer_bank = 0;
|
||||||
m_rf2_layer_bank = 0;
|
m_rf2_layer_bank = 0;
|
||||||
m_rowscroll_enable = 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();
|
set_layer_offsets();
|
||||||
|
|
||||||
UINT32 region_length = memregion("gfx2")->bytes();
|
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_layer_bank));
|
||||||
save_item(NAME(m_rf2_layer_bank));
|
save_item(NAME(m_rf2_layer_bank));
|
||||||
save_item(NAME(m_rowscroll_enable));
|
save_item(NAME(m_rowscroll_enable));
|
||||||
|
save_item(NAME(m_scrollram));
|
||||||
|
|
||||||
save_item(NAME(m_midl_layer_offset));
|
save_item(NAME(m_midl_layer_offset));
|
||||||
save_item(NAME(m_fore_layer_offset));
|
save_item(NAME(m_fore_layer_offset));
|
||||||
|
Loading…
Reference in New Issue
Block a user