stfight.c - Hooked up ADPCM/coin control MCU. Changed YM2203 clocks to 1.5MHz for cshooter and 4.5MHz for empcity/stfight (see notes) [Phil Bennett]

This commit is contained in:
Phil Bennett 2013-09-04 13:36:56 +00:00
parent bbab936a11
commit ff8db40368
3 changed files with 213 additions and 270 deletions

View File

@ -71,6 +71,11 @@ are not accessed by the CPUs.
Text video RAM is situated at $D000-$D7FF.
The 68705 MCU handles the two coin inputs and drives the MSM5205 ADPCM chip.
It also appears to serve as a simple protection device. During initialization,
the main Z80 writes a special ADPCM code to the MCU and then spins in a loop.
The MCU reponds by asserting the Z80's /NMI line, and thus the init process
continues. The protection ADPCM code varies between versions of each game.
3) MAIN CPU MEMORY MAP.
@ -113,8 +118,11 @@ $C204 R dipswitch #2 hard value (negative logic)
$C205 R read to determine coin circuit check status
$C500 W play fm number
$C600 W play voice number
$C700 W ?coin mechanism control?
$C804 W ?watchdog?
$C700 W coin mechanism control
$C804 W coin counters
- b4 Unknown
- b1 Coin counter 2
- b0 Coin counter 1
$C806 W ???
$C807 W current sprite bank h/w register
- bank = b2,b0
@ -151,12 +159,16 @@ $C000 W YM2203 #1 address register
$C001 W YM2203 #1 data register
$C800 W YM2203 #2 address register
$C801 W YM2203 #2 data register
$E800 W ??
$D000 R ADPCM code port (unused)
$D800 W MSM5205 control (unused)
$E800 W Debug port? (mirrors FM code)
$F000 R FM Voice number to play
- b7 set for valid data latched
- b6-b0 voice number
$F800-$FFFF RW RAM
empcity contains an NMI routine which appears to control an MSM5205.
However, it does not work properly. The NMI routine is not present in stfight.
5) COLOR RAM
@ -218,15 +230,16 @@ conventional RAM. See the memory map for sprite data format.
****************************************************************************
TODO:
- MCU is identical between Empire City and Cross Shooter, it's ADPCM and
perhaps coinage related too.
- palette is incorporated - fix!!!
- handle transparency in text layer properly (how?)
- second bank of sf02 is this used? (probably NOT)
DONE? (check on real board)
- sound (fm)
- sound (adpcm)
- stfight/empcity YM2203s should be clocked at 1.5MHz but this results in
the sound and music being 1/3 of the pitch they should be. The game never
writes the YM2203s' divider registers yet other games (e.g. Lock-On)
suggest the default values are correct. What *is* going on here?
- Each version of empcity/stfight has a different protection code stored in the
MCU (at $1D2) so each 68705 will need to be dumped.
We currently use hacked versions of the empcityu MCU for each different set.
*****************************************************************************/
@ -242,16 +255,17 @@ static ADDRESS_MAP_START( cpu1_map, AS_PROGRAM, 8, stfight_state )
AM_RANGE(0x8000, 0xbfff) AM_ROMBANK("bank1") /* sf02.bin */
AM_RANGE(0xc000, 0xc0ff) AM_RAM AM_SHARE("paletteram")
AM_RANGE(0xc100, 0xc1ff) AM_RAM AM_SHARE("paletteram2")
AM_RANGE(0xc200, 0xc200) AM_READ_PORT("P1") /* IN1 */
AM_RANGE(0xc201, 0xc201) AM_READ_PORT("P2") /* IN2 */
AM_RANGE(0xc202, 0xc202) AM_READ_PORT("START") /* IN3 */
AM_RANGE(0xc200, 0xc200) AM_READ_PORT("P1")
AM_RANGE(0xc201, 0xc201) AM_READ_PORT("P2")
AM_RANGE(0xc202, 0xc202) AM_READ_PORT("START")
AM_RANGE(0xc203, 0xc203) AM_READ_PORT("DSW0")
AM_RANGE(0xc204, 0xc204) AM_READ_PORT("DSW1")
AM_RANGE(0xc205, 0xc205) AM_READ(stfight_coin_r) /* coin mech */
AM_RANGE(0xc500, 0xc500) AM_WRITE(stfight_fm_w) /* play fm sound */
AM_RANGE(0xc600, 0xc600) AM_WRITE(stfight_adpcm_control_w) /* voice control */
AM_RANGE(0xc700, 0xc700) AM_WRITE(stfight_coin_w) /* coin mech */
AM_RANGE(0xc804, 0xc806) AM_WRITENOP /* TBD */
AM_RANGE(0xc205, 0xc205) AM_READ(stfight_coin_r)
AM_RANGE(0xc500, 0xc500) AM_WRITE(stfight_fm_w)
AM_RANGE(0xc600, 0xc600) AM_WRITE(stfight_mcu_w)
AM_RANGE(0xc700, 0xc700) AM_WRITE(stfight_coin_w)
AM_RANGE(0xc804, 0xc804) AM_WRITE(stfight_io_w)
AM_RANGE(0xc806, 0xc806) AM_WRITENOP /* TBD */
AM_RANGE(0xc807, 0xc807) AM_WRITE(stfight_sprite_bank_w)
AM_RANGE(0xd000, 0xd3ff) AM_RAM_WRITE(stfight_text_char_w) AM_SHARE("text_char_ram")
AM_RANGE(0xd400, 0xd7ff) AM_RAM_WRITE(stfight_text_attr_w) AM_SHARE("text_attr_ram")
@ -261,9 +275,6 @@ static ADDRESS_MAP_START( cpu1_map, AS_PROGRAM, 8, stfight_state )
ADDRESS_MAP_END
static ADDRESS_MAP_START( cshooter_cpu1_map, AS_PROGRAM, 8, stfight_state )
/* wants 0xff at PC=0x9a otherwise it won't boot, MCU related? */
AM_RANGE(0x0007, 0x0007) AM_READ(cshooter_mcu_unk1_r)
AM_RANGE(0xc500, 0xc500) AM_WRITE(cshooter_fm_w) /* play fm sound */
AM_RANGE(0xc801, 0xc801) AM_WRITE(stfight_bank_w)
AM_RANGE(0xd000, 0xd7ff) AM_RAM_WRITE(cshooter_text_w) AM_SHARE("tx_vram")
AM_RANGE(0xe000, 0xfdff) AM_RAM
@ -275,19 +286,21 @@ static ADDRESS_MAP_START( cpu2_map, AS_PROGRAM, 8, stfight_state )
AM_RANGE(0x0000, 0x7fff) AM_ROM
AM_RANGE(0xc000, 0xc001) AM_DEVREADWRITE("ym1", ym2203_device, read, write)
AM_RANGE(0xc800, 0xc801) AM_DEVREADWRITE("ym2", ym2203_device, read, write)
AM_RANGE(0xe800, 0xe800) AM_WRITE(stfight_fm_w)
AM_RANGE(0xd000, 0xd000) AM_READNOP
AM_RANGE(0xd800, 0xd800) AM_WRITENOP
AM_RANGE(0xe800, 0xe800) AM_WRITENOP
AM_RANGE(0xf000, 0xf000) AM_READ(stfight_fm_r)
AM_RANGE(0xf800, 0xffff) AM_RAM
ADDRESS_MAP_END
static ADDRESS_MAP_START( cshooter_mcu_map, AS_PROGRAM, 8, stfight_state )
static ADDRESS_MAP_START( mcu_map, AS_PROGRAM, 8, stfight_state )
ADDRESS_MAP_GLOBAL_MASK(0x7ff)
AM_RANGE(0x0000, 0x0000) AM_READWRITE(cshooter_68705_port_a_r,cshooter_68705_port_a_w)
AM_RANGE(0x0001, 0x0001) AM_READWRITE(cshooter_68705_port_b_r,cshooter_68705_port_b_w)
AM_RANGE(0x0002, 0x0002) AM_READWRITE(cshooter_68705_port_c_r,cshooter_68705_port_c_w)
AM_RANGE(0x0004, 0x0004) AM_WRITE(cshooter_68705_ddr_a_w)
AM_RANGE(0x0005, 0x0005) AM_WRITE(cshooter_68705_ddr_b_w)
AM_RANGE(0x0006, 0x0006) AM_WRITE(cshooter_68705_ddr_c_w)
AM_RANGE(0x0000, 0x0000) AM_READWRITE(stfight_68705_port_a_r,stfight_68705_port_a_w)
AM_RANGE(0x0001, 0x0001) AM_READWRITE(stfight_68705_port_b_r,stfight_68705_port_b_w)
AM_RANGE(0x0002, 0x0002) AM_READWRITE(stfight_68705_port_c_r,stfight_68705_port_c_w)
AM_RANGE(0x0004, 0x0004) AM_WRITE(stfight_68705_ddr_a_w)
AM_RANGE(0x0005, 0x0005) AM_WRITE(stfight_68705_ddr_b_w)
AM_RANGE(0x0006, 0x0006) AM_WRITE(stfight_68705_ddr_c_w)
AM_RANGE(0x0010, 0x007f) AM_RAM
AM_RANGE(0x0080, 0x07ff) AM_ROM
ADDRESS_MAP_END
@ -368,8 +381,8 @@ static INPUT_PORTS_START( stfight )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START("COIN") /* COIN MECH */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(1)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_IMPULSE(1)
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
INPUT_PORTS_END
static INPUT_PORTS_START( cshooter )
@ -519,8 +532,8 @@ GFXDECODE_END
static const msm5205_interface msm5205_config =
{
DEVCB_DRIVER_LINE_MEMBER(stfight_state,stfight_adpcm_int), /* interrupt function */
MSM5205_S48_4B /* 8KHz */
DEVCB_DRIVER_LINE_MEMBER(stfight_state, stfight_adpcm_int), // Interrupt function
MSM5205_S48_4B // 8KHz, 4-bit
};
static MACHINE_CONFIG_START( stfight, stfight_state )
@ -535,7 +548,7 @@ static MACHINE_CONFIG_START( stfight, stfight_state )
MCFG_CPU_PERIODIC_INT_DRIVER(stfight_state, irq0_line_hold, 120)
MCFG_CPU_ADD("mcu", M68705, 6000000) /* 6 MHz? */
MCFG_CPU_PROGRAM_MAP(cshooter_mcu_map)
MCFG_CPU_PROGRAM_MAP(mcu_map)
MCFG_QUANTUM_TIME(attotime::from_hz(600))
@ -555,29 +568,30 @@ static MACHINE_CONFIG_START( stfight, stfight_state )
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("ym1", YM2203, 3000000)
// HACK! These should be clocked at 1.5Mhz (see TODO list)
MCFG_SOUND_ADD("ym1", YM2203, 4500000)
MCFG_SOUND_ROUTE(0, "mono", 0.15)
MCFG_SOUND_ROUTE(1, "mono", 0.15)
MCFG_SOUND_ROUTE(2, "mono", 0.15)
MCFG_SOUND_ROUTE(3, "mono", 0.10)
MCFG_SOUND_ADD("ym2", YM2203, 3000000)
MCFG_SOUND_ADD("ym2", YM2203, 4500000)
MCFG_SOUND_ROUTE(0, "mono", 0.15)
MCFG_SOUND_ROUTE(1, "mono", 0.15)
MCFG_SOUND_ROUTE(2, "mono", 0.15)
MCFG_SOUND_ROUTE(3, "mono", 0.10)
MCFG_SOUND_ADD("msm", MSM5205, 384000)
MCFG_SOUND_ADD("msm", MSM5205, XTAL_384kHz)
MCFG_SOUND_CONFIG(msm5205_config)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( cshooter, stfight )
MCFG_CPU_REPLACE("maincpu", Z80, 6000000) /* 6 MHz */
MCFG_CPU_REPLACE("maincpu", Z80, 6000000)
MCFG_CPU_PROGRAM_MAP(cshooter_cpu1_map)
MCFG_CPU_VBLANK_INT_DRIVER("screen", stfight_state, stfight_vb_interrupt)
MCFG_CPU_REPLACE("audiocpu", Z80, 6000000) /* 6 MHz */
MCFG_CPU_REPLACE("audiocpu", Z80, 6000000)
MCFG_CPU_PROGRAM_MAP(cpu2_map)
MCFG_CPU_PERIODIC_INT_DRIVER(stfight_state, irq0_line_hold, 120)
@ -588,6 +602,12 @@ static MACHINE_CONFIG_DERIVED( cshooter, stfight )
MCFG_GFXDECODE(cshooter)
MCFG_VIDEO_START_OVERRIDE(stfight_state,cshooter)
MCFG_SOUND_MODIFY("ym1")
MCFG_SOUND_CLOCK(1500000)
MCFG_SOUND_MODIFY("ym2")
MCFG_SOUND_CLOCK(1500000)
MACHINE_CONFIG_END
/***************************************************************************
@ -596,6 +616,7 @@ MACHINE_CONFIG_END
***************************************************************************/
// Is this a bootleg? The MCU protection check at $00A7 has been disabled
ROM_START( empcity )
ROM_REGION( 2*0x18000, "maincpu", 0 ) /* 96k for code + 96k for decrypted opcodes */
ROM_LOAD( "ec_01.rom", 0x00000, 0x8000, CRC(fe01d9b1) SHA1(c4b62d1b7e3a062f6a7a75f49cce5712f9016f98) )
@ -604,9 +625,8 @@ ROM_START( empcity )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* 64k for the second CPU */
ROM_LOAD( "ec_04.rom", 0x0000, 0x8000, CRC(aa3e7d1e) SHA1(da350384d55f011253d19ce17fc327cd2604257f) )
// not hooked up yet, what's it for, coinage?
ROM_REGION( 0x0800, "mcu", 0 )
ROM_LOAD( "empirecity_68705.bin", 0x0000, 0x0800, CRC(182f7616) SHA1(38b4f23a559ae13f8ca1b974407a2a40fc52879f) )
ROM_LOAD( "empcityu_68705.3j", 0x0000, 0x0800, CRC(182f7616) SHA1(38b4f23a559ae13f8ca1b974407a2a40fc52879f) )
ROM_REGION( 0x02000, "gfx1", 0 ) /* character data */
ROM_LOAD( "sf17.bin", 0x0000, 0x2000, CRC(1b3706b5) SHA1(61f069329a7a836523ffc8cce915b0d0129fd896) )
@ -647,7 +667,7 @@ ROM_START( empcity )
ROM_LOAD( "82s129.066", 0x0600, 0x0100, CRC(51e8832f) SHA1(ed8c00559e7a02bb8c11861d747c8c64c01b7437) )
ROM_LOAD( "82s129.015", 0x0700, 0x0100, CRC(0eaf5158) SHA1(bafd4108708f66cd7b280e47152b108f3e254fc9) ) /* timing? (not used) */
ROM_REGION( 0x08000, "adpcm", 0 ) /* adpcm voice data */
ROM_REGION( 0x08000, "adpcm", 0 ) /* ADPCM voice data */
ROM_LOAD( "sf04.bin", 0x00000, 0x8000, CRC(1b8d0c07) SHA1(c163ccd2b7ed6c84facc075eb1564ca399f3ba17) )
ROM_END
@ -660,9 +680,8 @@ ROM_START( empcityu )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* 64k for the second CPU */
ROM_LOAD( "ec_04.rom", 0x0000, 0x8000, CRC(aa3e7d1e) SHA1(da350384d55f011253d19ce17fc327cd2604257f) )
// not hooked up yet, what's it for, coinage?
ROM_REGION( 0x0800, "mcu", 0 )
ROM_LOAD( "empirecity_68705.bin", 0x0000, 0x0800, CRC(182f7616) SHA1(38b4f23a559ae13f8ca1b974407a2a40fc52879f) )
ROM_LOAD( "empcityu_68705.3j", 0x0000, 0x0800, CRC(182f7616) SHA1(38b4f23a559ae13f8ca1b974407a2a40fc52879f) )
ROM_REGION( 0x02000, "gfx1", 0 ) /* character data */
ROM_LOAD( "vid.2p", 0x0000, 0x2000, CRC(15593793) SHA1(ac9ca8a0aa0ce3810f45aa41e74d4946ecced245) )
@ -703,7 +722,7 @@ ROM_START( empcityu )
ROM_LOAD( "82s129.066", 0x0600, 0x0100, CRC(51e8832f) SHA1(ed8c00559e7a02bb8c11861d747c8c64c01b7437) )
ROM_LOAD( "82s129.015", 0x0700, 0x0100, CRC(0eaf5158) SHA1(bafd4108708f66cd7b280e47152b108f3e254fc9) ) /* timing? (not used) */
ROM_REGION( 0x08000, "adpcm", 0 ) /* adpcm voice data */
ROM_REGION( 0x08000, "adpcm", 0 ) /* ADPCM voice data */
ROM_LOAD( "sf04.bin", 0x00000, 0x8000, CRC(1b8d0c07) SHA1(c163ccd2b7ed6c84facc075eb1564ca399f3ba17) )
ROM_REGION( 0x020, "user1", 0 )
@ -718,9 +737,8 @@ ROM_START( empcityj )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* 64k for the second CPU */
ROM_LOAD( "ec_04.rom", 0x0000, 0x8000, CRC(aa3e7d1e) SHA1(da350384d55f011253d19ce17fc327cd2604257f) )
// not hooked up yet, what's it for, coinage?
ROM_REGION( 0x0800, "mcu", 0 )
ROM_LOAD( "empirecity_68705.bin", 0x0000, 0x0800, CRC(182f7616) SHA1(38b4f23a559ae13f8ca1b974407a2a40fc52879f) )
ROM_LOAD( "empcityj_68705.3j", 0x0000, 0x0800, BAD_DUMP CRC(19bdb0a9) SHA1(6baba9a46d64ae8349c7e9713419141f76a7af96) )
ROM_REGION( 0x02000, "gfx1", 0 ) /* character data */
ROM_LOAD( "sf17.bin", 0x0000, 0x2000, CRC(1b3706b5) SHA1(61f069329a7a836523ffc8cce915b0d0129fd896) )
@ -761,7 +779,7 @@ ROM_START( empcityj )
ROM_LOAD( "82s129.066", 0x0600, 0x0100, CRC(51e8832f) SHA1(ed8c00559e7a02bb8c11861d747c8c64c01b7437) )
ROM_LOAD( "82s129.015", 0x0700, 0x0100, CRC(0eaf5158) SHA1(bafd4108708f66cd7b280e47152b108f3e254fc9) ) /* timing? (not used) */
ROM_REGION( 0x08000, "adpcm", 0 ) /* adpcm voice data */
ROM_REGION( 0x08000, "adpcm", 0 ) /* ADPCM voice data */
ROM_LOAD( "sf04.bin", 0x00000, 0x8000, CRC(1b8d0c07) SHA1(c163ccd2b7ed6c84facc075eb1564ca399f3ba17) )
ROM_END
@ -773,9 +791,8 @@ ROM_START( stfight )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* 64k for the second CPU */
ROM_LOAD( "sf03.bin", 0x0000, 0x8000, CRC(6a8cb7a6) SHA1(dc123cc48d3623752b78e7c23dd8d2f5adf84f92) )
// not hooked up yet, what's it for, coinage?
ROM_REGION( 0x0800, "mcu", 0 )
ROM_LOAD( "empirecity_68705.bin", 0x0000, 0x0800, CRC(182f7616) SHA1(38b4f23a559ae13f8ca1b974407a2a40fc52879f) )
ROM_LOAD( "stfight_68705.3j", 0x0000, 0x0800, BAD_DUMP CRC(f4cc50d6) SHA1(2ff62a349b74fa965b5d19615e52b867c04988dc) )
ROM_REGION( 0x02000, "gfx1", 0 ) /* character data */
ROM_LOAD( "sf17.bin", 0x0000, 0x2000, CRC(1b3706b5) SHA1(61f069329a7a836523ffc8cce915b0d0129fd896) )
@ -816,7 +833,7 @@ ROM_START( stfight )
ROM_LOAD( "82s129.066", 0x0600, 0x0100, CRC(51e8832f) SHA1(ed8c00559e7a02bb8c11861d747c8c64c01b7437) )
ROM_LOAD( "82s129.015", 0x0700, 0x0100, CRC(0eaf5158) SHA1(bafd4108708f66cd7b280e47152b108f3e254fc9) ) /* timing? (not used) */
ROM_REGION( 0x08000, "adpcm", 0 ) /* adpcm voice data */
ROM_REGION( 0x08000, "adpcm", 0 ) /* ADPCM voice data */
ROM_LOAD( "sf04.bin", 0x00000, 0x8000, CRC(1b8d0c07) SHA1(c163ccd2b7ed6c84facc075eb1564ca399f3ba17) )
ROM_END
@ -830,9 +847,8 @@ ROM_START( stfighta )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* 64k for the second CPU */
ROM_LOAD( "sf03.bin", 0x0000, 0x8000, CRC(6a8cb7a6) SHA1(dc123cc48d3623752b78e7c23dd8d2f5adf84f92) )
// not hooked up yet, what's it for, coinage?
ROM_REGION( 0x0800, "mcu", 0 )
ROM_LOAD( "empirecity_68705.bin", 0x0000, 0x0800, CRC(182f7616) SHA1(38b4f23a559ae13f8ca1b974407a2a40fc52879f) )
ROM_LOAD( "stfight_68705.3j", 0x0000, 0x0800, BAD_DUMP CRC(f4cc50d6) SHA1(2ff62a349b74fa965b5d19615e52b867c04988dc) )
ROM_REGION( 0x02000, "gfx1", 0 ) /* character data */
ROM_LOAD( "sf17.bin", 0x0000, 0x2000, CRC(1b3706b5) SHA1(61f069329a7a836523ffc8cce915b0d0129fd896) )
@ -873,7 +889,7 @@ ROM_START( stfighta )
ROM_LOAD( "82s129.066", 0x0600, 0x0100, CRC(51e8832f) SHA1(ed8c00559e7a02bb8c11861d747c8c64c01b7437) )
ROM_LOAD( "82s129.015", 0x0700, 0x0100, CRC(0eaf5158) SHA1(bafd4108708f66cd7b280e47152b108f3e254fc9) ) /* timing? (not used) */
ROM_REGION( 0x08000, "adpcm", 0 ) /* adpcm voice data */
ROM_REGION( 0x08000, "adpcm", 0 ) /* ADPCM voice data */
ROM_LOAD( "sf04.bin", 0x00000, 0x8000, CRC(1b8d0c07) SHA1(c163ccd2b7ed6c84facc075eb1564ca399f3ba17) )
ROM_END
@ -885,9 +901,8 @@ ROM_START( empcityi ) // very similar to above set
ROM_REGION( 0x10000, "audiocpu", 0 ) /* 64k for the second CPU */
ROM_LOAD( "sf03.bin", 0x0000, 0x8000, CRC(6a8cb7a6) SHA1(dc123cc48d3623752b78e7c23dd8d2f5adf84f92) )
// not hooked up yet, what's it for, coinage?
ROM_REGION( 0x0800, "mcu", 0 )
ROM_LOAD( "empirecity_68705.bin", 0x0000, 0x0800, CRC(182f7616) SHA1(38b4f23a559ae13f8ca1b974407a2a40fc52879f) )
ROM_LOAD( "empcityi_68705.3j", 0x0000, 0x0800, BAD_DUMP CRC(b1817d44) SHA1(395aad763eb054514f658a14c12b92c1b90c02ce) )
ROM_REGION( 0x02000, "gfx1", 0 ) /* character data */
ROM_LOAD( "sf17.bin", 0x0000, 0x2000, CRC(1b3706b5) SHA1(61f069329a7a836523ffc8cce915b0d0129fd896) )
@ -928,7 +943,7 @@ ROM_START( empcityi ) // very similar to above set
ROM_LOAD( "82s129.066", 0x0600, 0x0100, CRC(51e8832f) SHA1(ed8c00559e7a02bb8c11861d747c8c64c01b7437) )
ROM_LOAD( "82s129.015", 0x0700, 0x0100, CRC(0eaf5158) SHA1(bafd4108708f66cd7b280e47152b108f3e254fc9) ) /* timing? (not used) */
ROM_REGION( 0x08000, "adpcm", 0 ) /* adpcm voice data */
ROM_REGION( 0x08000, "adpcm", 0 ) /* ADPCM voice data */
ROM_LOAD( "sf04.bin", 0x00000, 0x8000, CRC(1b8d0c07) SHA1(c163ccd2b7ed6c84facc075eb1564ca399f3ba17) )
ROM_END
@ -993,7 +1008,6 @@ ROM_START( cshooter )
ROM_REGION( 0x10000, "audiocpu", 0 ) // Sub/Sound CPU
ROM_LOAD( "r4.5c", 0x00000, 0x08000, CRC(84fed017) SHA1(9a564c9379eb48569cfba48562889277991864d8) )
// not hooked up yet (Taito version has this instead of encryption!
ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "crshooter.3j", 0x0000, 0x0800, CRC(aae61ce7) SHA1(bb2b9887ec73a5b82604b9b64c533c2242d20d0f) )
@ -1013,7 +1027,7 @@ ROM_START( cshooter )
ROM_REGION( 0x10000, "gfx6", ROMREGION_ERASEFF ) /* background map data */
ROM_REGION( 0x08000, "adpcm", ROMREGION_ERASEFF ) /* adpcm voice data */
ROM_REGION( 0x08000, "adpcm", ROMREGION_ERASEFF ) /* ADPCM voice data */
ROM_REGION( 0x820, "proms", 0 )
ROM_LOAD( "63s281.16a", 0x0000, 0x0100, CRC(0b8b914b) SHA1(8cf4910b846de79661cc187887171ed8ebfd6719) ) // clut
@ -1022,11 +1036,12 @@ ROM_START( cshooter )
ROM_LOAD( "82s123.7a", 0x0800, 0x0020, CRC(93e2d292) SHA1(af8edd0cfe85f28ede9604cfaf4516d54e5277c9) ) // sprite color related? (not used)
ROM_END
GAME( 1986, empcity, 0, stfight, stfight, stfight_state, empcity, ROT0, "Seibu Kaihatsu", "Empire City: 1931 (bootleg?)", 0 )
GAME( 1986, empcityu, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu (Taito / Romstar license)", "Empire City: 1931 (US)", 0 ) // different title logo
GAME( 1986, empcityj, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu (Taito license)", "Empire City: 1931 (Japan)", 0 )
GAME( 1986, empcityi, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu (Eurobed license)", "Empire City: 1931 (Italy)", 0 )
GAME( 1986, stfight, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu (Tuning license)", "Street Fight (Germany)", 0 )
GAME( 1986, stfighta, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu", "Street Fight (bootleg?)", 0 )
/* Cross Shooter runs on a slightly modified version of Empire City, with M68705 MCU, a different text tilemap and gfx blobs (see also airraid.c) */
// Note: Marked GAME_IMPERFECT_SOUND due to YM2203 clock issue
GAME( 1986, empcity, 0, stfight, stfight, stfight_state, empcity, ROT0, "Seibu Kaihatsu", "Empire City: 1931 (bootleg?)", GAME_IMPERFECT_SOUND )
GAME( 1986, empcityu, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu (Taito / Romstar license)", "Empire City: 1931 (US)", GAME_IMPERFECT_SOUND ) // different title logo
GAME( 1986, empcityj, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu (Taito license)", "Empire City: 1931 (Japan)", GAME_IMPERFECT_SOUND )
GAME( 1986, empcityi, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu (Eurobed license)", "Empire City: 1931 (Italy)", GAME_IMPERFECT_SOUND )
GAME( 1986, stfight, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu (Tuning license)", "Street Fight (Germany)", GAME_IMPERFECT_SOUND )
GAME( 1986, stfighta, empcity, stfight, stfight, stfight_state, stfight, ROT0, "Seibu Kaihatsu", "Street Fight (bootleg?)", GAME_IMPERFECT_SOUND )
/* Cross Shooter runs on a slightly modified PCB, with a different text tilemap and gfx blobs (see also airraid.c) */
GAME( 1987, cshooter, 0, cshooter,cshooter, stfight_state, cshooter,ROT270,"Seibu Kaihatsu (Taito license)", "Cross Shooter (not encrypted)", GAME_NOT_WORKING )

View File

@ -27,42 +27,52 @@ public:
required_shared_ptr<UINT8> m_sprite_ram;
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
optional_device<cpu_device> m_mcu;
required_device<cpu_device> m_mcu;
required_device<msm5205_device> m_msm;
UINT8 *m_decrypt;
int m_adpcm_data_offs;
int m_adpcm_data_end;
int m_toggle;
UINT8 m_fm_data;
int m_coin_mech_latch[2];
int m_coin_mech_query_active;
int m_coin_mech_query;
UINT8 m_cpu_to_mcu_data;
UINT8 m_cpu_to_mcu_empty;
UINT16 m_adpcm_data_offs;
UINT8 m_adpcm_nibble;
UINT8 m_adpcm_reset;
UINT8 m_coin_state;
tilemap_t *m_fg_tilemap;
tilemap_t *m_bg_tilemap;
tilemap_t *m_tx_tilemap;
int m_sprite_base;
DECLARE_WRITE_LINE_MEMBER(stfight_adpcm_int);
DECLARE_DRIVER_INIT(stfight);
DECLARE_DRIVER_INIT(empcity);
DECLARE_DRIVER_INIT(cshooter);
DECLARE_WRITE8_MEMBER(stfight_io_w);
DECLARE_READ8_MEMBER(stfight_coin_r);
DECLARE_WRITE8_MEMBER(stfight_coin_w);
DECLARE_WRITE8_MEMBER(stfight_e800_w);
DECLARE_WRITE8_MEMBER(stfight_fm_w);
DECLARE_WRITE8_MEMBER(cshooter_fm_w);
DECLARE_READ8_MEMBER(stfight_fm_r);
DECLARE_WRITE8_MEMBER(stfight_mcu_w);
DECLARE_WRITE8_MEMBER(stfight_bank_w);
DECLARE_WRITE8_MEMBER(stfight_text_char_w);
DECLARE_WRITE8_MEMBER(stfight_text_attr_w);
DECLARE_WRITE8_MEMBER(stfight_sprite_bank_w);
DECLARE_WRITE8_MEMBER(stfight_vh_latch_w);
DECLARE_WRITE8_MEMBER(cshooter_text_w);
DECLARE_DRIVER_INIT(stfight);
DECLARE_DRIVER_INIT(empcity);
DECLARE_DRIVER_INIT(cshooter);
DECLARE_WRITE8_MEMBER(cshooter_text_w);
DECLARE_READ8_MEMBER(stfight_fm_r);
TILEMAP_MAPPER_MEMBER(fg_scan);
TILE_GET_INFO_MEMBER(get_fg_tile_info);
TILEMAP_MAPPER_MEMBER(bg_scan);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
TILE_GET_INFO_MEMBER(get_tx_tile_info);
TILE_GET_INFO_MEMBER(get_cshooter_tx_tile_info);
DECLARE_READ8_MEMBER(cshooter_mcu_unk1_r);
DECLARE_VIDEO_START(stfight);
DECLARE_VIDEO_START(cshooter);
virtual void machine_reset();
@ -70,27 +80,24 @@ public:
UINT32 screen_update_stfight(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
UINT32 screen_update_cshooter(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(stfight_vb_interrupt);
DECLARE_WRITE8_MEMBER(stfight_adpcm_control_w);
void set_pens();
void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void cshooter_draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(stfight_adpcm_int);
/*
MCU specifics
*/
DECLARE_READ8_MEMBER(cshooter_68705_port_a_r);
DECLARE_READ8_MEMBER(cshooter_68705_port_b_r);
DECLARE_READ8_MEMBER(cshooter_68705_port_c_r);
DECLARE_WRITE8_MEMBER(cshooter_68705_port_a_w);
DECLARE_WRITE8_MEMBER(cshooter_68705_port_b_w);
DECLARE_WRITE8_MEMBER(cshooter_68705_port_c_w);
DECLARE_READ8_MEMBER(stfight_68705_port_a_r);
DECLARE_READ8_MEMBER(stfight_68705_port_b_r);
DECLARE_READ8_MEMBER(stfight_68705_port_c_r);
DECLARE_WRITE8_MEMBER(stfight_68705_port_a_w);
DECLARE_WRITE8_MEMBER(stfight_68705_port_b_w);
DECLARE_WRITE8_MEMBER(stfight_68705_port_c_w);
DECLARE_WRITE8_MEMBER(cshooter_68705_ddr_a_w);
DECLARE_WRITE8_MEMBER(cshooter_68705_ddr_b_w);
DECLARE_WRITE8_MEMBER(cshooter_68705_ddr_c_w);
DECLARE_WRITE8_MEMBER(cshooter_mcu_w);
DECLARE_WRITE8_MEMBER(stfight_68705_ddr_a_w);
DECLARE_WRITE8_MEMBER(stfight_68705_ddr_b_w);
DECLARE_WRITE8_MEMBER(stfight_68705_ddr_c_w);
UINT8 m_portA_out, m_portA_in;
UINT8 m_portB_out, m_portB_in;

View File

@ -12,7 +12,6 @@
#include "sound/msm5205.h"
#include "includes/stfight.h"
// this prototype will move to the driver
@ -40,12 +39,11 @@ DRIVER_INIT_MEMBER(stfight_state,empcity)
{
address_space &space = m_maincpu->space(AS_PROGRAM);
UINT8 *rom = memregion("maincpu")->base();
int A;
m_decrypt = auto_alloc_array(machine(), UINT8, 0x8000);
space.set_decrypted_region(0x0000, 0x7fff, m_decrypt);
for (A = 0;A < 0x8000;A++)
for (UINT32 A = 0; A < 0x8000; ++A)
{
UINT8 src = rom[A];
@ -70,38 +68,25 @@ DRIVER_INIT_MEMBER(stfight_state,empcity)
DRIVER_INIT_MEMBER(stfight_state,stfight)
{
DRIVER_INIT_CALL(empcity);
/* patch out a tight loop during startup - is the code waiting */
/* for NMI to wake it up? */
m_decrypt[0xb1] = 0x00;
m_decrypt[0xb2] = 0x00;
m_decrypt[0xb3] = 0x00;
m_decrypt[0xb4] = 0x00;
m_decrypt[0xb5] = 0x00;
}
DRIVER_INIT_MEMBER(stfight_state,cshooter)
{
UINT8 *rom = memregion("maincpu")->base();
/* patch out initial coin mech check for now */
rom[0x5068] = 0xc9; /* ret z -> ret*/
}
void stfight_state::machine_reset()
{
address_space &space = m_maincpu->space(AS_PROGRAM);
m_adpcm_data_offs = m_adpcm_data_end = 0;
m_toggle = 0;
m_fm_data = 0;
m_coin_mech_latch[0] = 0x02;
m_coin_mech_latch[1] = 0x01;
m_adpcm_reset = 1;
m_cpu_to_mcu_empty = 1;
m_coin_mech_query_active = 0;
m_coin_mech_query = 0;
// Coin signals are active low
m_coin_state = 3;
// initialise rom bank
stfight_bank_w(space, 0, 0 );
// initialise ROM bank
stfight_bank_w(m_maincpu->space(AS_PROGRAM), 0, 0);
}
// It's entirely possible that this bank is never switched out
@ -119,7 +104,7 @@ WRITE8_MEMBER(stfight_state::stfight_bank_w)
if(data & 0x04)
bank_num |= 0x4000;
membank("bank1")->set_base(&ROM2[bank_num] );
membank("bank1")->set_base(&ROM2[bank_num]);
}
/*
@ -150,235 +135,171 @@ INTERRUPT_GEN_MEMBER(stfight_state::stfight_vb_interrupt)
* Hardware handlers
*/
WRITE8_MEMBER(stfight_state::stfight_io_w)
{
// TODO: What is bit 4?
coin_counter_w(machine(), 0, data & 1);
coin_counter_w(machine(), 1, data & 2);
}
READ8_MEMBER(stfight_state::stfight_coin_r)
{
int coin_mech_data;
int i;
// Was the coin mech queried by software?
if( m_coin_mech_query_active )
{
m_coin_mech_query_active = 0;
return( (~m_coin_mech_query) & 0x03 );
}
/*
* Is this really necessary?
* - we can control impulse length so that the port is
* never strobed twice within the impulse period
* since it's read by the 30Hz interrupt ISR
*/
coin_mech_data = ioport("COIN")->read();
for( i=0; i<2; i++ )
{
/* Only valid on signal edge */
if( ( coin_mech_data & (1<<i) ) != m_coin_mech_latch[i] )
m_coin_mech_latch[i] = coin_mech_data & (1<<i);
else
coin_mech_data |= coin_mech_data & (1<<i);
}
return( coin_mech_data );
return m_coin_state;
}
WRITE8_MEMBER(stfight_state::stfight_coin_w)
{
// interrogate coin mech
m_coin_mech_query_active = 1;
m_coin_mech_query = data;
}
// Acknowledge coin signals (active low)
if (!BIT(data, 0))
m_coin_state |= 1;
READ8_MEMBER(stfight_state::cshooter_mcu_unk1_r)
{
return 0xff; // hack so it boots
if (!BIT(data, 1))
m_coin_state |= 2;
}
/*
* Machine hardware for MSM5205 ADPCM sound control
*/
static const int sampleLimits[] =
{
0x0000, // machine gun fire?
0x1000, // player getting shot
0x2C00, // player shooting
0x3C00, // girl screaming
0x5400, // girl getting shot
0x7200, // (end of samples)
0x7200,
0x7200,
0x7200
};
WRITE_LINE_MEMBER(stfight_state::stfight_adpcm_int)
{
UINT8 *SAMPLES = memregion("adpcm")->base();
int adpcm_data = SAMPLES[m_adpcm_data_offs & 0x7fff];
static int m_vck2 = 0;
// finished playing sample?
if( m_adpcm_data_offs == m_adpcm_data_end )
{
m_msm->reset_w(1);
return;
}
// Falling edge triggered interrupt at half the rate of /VCK?
if (m_vck2)
m_mcu->set_input_line(0, HOLD_LINE);
if( m_toggle == 0 )
{
m_msm->data_w((adpcm_data >> 4) & 0x0f);
}
else
m_vck2 ^= 1;
if (!m_adpcm_reset)
{
const UINT8 *samples = memregion("adpcm")->base();
UINT8 adpcm_data = samples[m_adpcm_data_offs & 0x7fff];
if (m_adpcm_nibble == 0)
adpcm_data >>= 4;
else
++m_adpcm_data_offs;
m_msm->data_w(adpcm_data & 0x0f);
m_adpcm_data_offs++;
m_adpcm_nibble ^= 1;
}
m_toggle ^= 1;
}
WRITE8_MEMBER(stfight_state::stfight_adpcm_control_w)
{
if( data < 0x08 )
{
m_adpcm_data_offs = sampleLimits[data];
m_adpcm_data_end = sampleLimits[data+1];
}
m_mcu->set_input_line(0, HOLD_LINE);
m_from_main = data;
m_main_sent = 1;
// m_maincpu->set_input_line(INPUT_LINE_NMI,PULSE_LINE);
m_msm->reset_w(BIT(data, 3));
}
WRITE8_MEMBER(stfight_state::stfight_e800_w)
{
}
/*
* Machine hardware for YM2303 fm sound control
* Machine hardware for YM2303 FM sound control
*/
WRITE8_MEMBER(stfight_state::stfight_fm_w)
{
// the sound cpu ignores any fm data without bit 7 set, it's very likely to be xor'ed and both CPUs can write to it.
m_fm_data = 0x80 ^ data;
}
WRITE8_MEMBER(stfight_state::cshooter_fm_w)
{
m_fm_data = data;
// The sound cpu ignores any FM data without bit 7 set
m_fm_data = 0x80 | data;
}
READ8_MEMBER(stfight_state::stfight_fm_r)
{
int data = m_fm_data;
UINT8 data = m_fm_data;
//m_fm_data &= 0x7f;
// Acknowledge the command
m_fm_data &= ~0x80;
return( data );
return data;
}
/*
* Cross Shooter MCU communications
*
* TODO: everything, especially MCU to main comms (tied with coinage ports?)
* MCU communications
*/
WRITE8_MEMBER(stfight_state::cshooter_68705_ddr_a_w)
WRITE8_MEMBER(stfight_state::stfight_mcu_w)
{
m_cpu_to_mcu_data = data;
m_cpu_to_mcu_empty = 0;
}
WRITE8_MEMBER(stfight_state::stfight_68705_ddr_a_w)
{
m_ddrA = data;
}
WRITE8_MEMBER(stfight_state::cshooter_68705_ddr_b_w)
WRITE8_MEMBER(stfight_state::stfight_68705_ddr_b_w)
{
m_ddrB = data;
}
WRITE8_MEMBER(stfight_state::cshooter_68705_ddr_c_w)
WRITE8_MEMBER(stfight_state::stfight_68705_ddr_c_w)
{
m_ddrC = data;
}
WRITE8_MEMBER(stfight_state::cshooter_mcu_w)
{
m_mcu->set_input_line(0, HOLD_LINE);
m_from_main = data;
m_main_sent = 1;
}
READ8_MEMBER(stfight_state::cshooter_68705_port_a_r)
READ8_MEMBER(stfight_state::stfight_68705_port_a_r)
{
m_portA_in = m_cpu_to_mcu_data;
return (m_portA_out & m_ddrA) | (m_portA_in & ~m_ddrA);
}
WRITE8_MEMBER(stfight_state::cshooter_68705_port_a_w)
WRITE8_MEMBER(stfight_state::stfight_68705_port_a_w)
{
// ADPCM start offset goes there
// TODO: where's end offset?
m_adpcm_data_offs = data << 8;
m_portA_out = data;
}
READ8_MEMBER(stfight_state::cshooter_68705_port_b_r)
READ8_MEMBER(stfight_state::stfight_68705_port_b_r)
{
m_portB_in = (ioport("COIN")->read() << 6) | (m_cpu_to_mcu_empty << 4) | m_cpu_to_mcu_data;
return (m_portB_out & m_ddrB) | (m_portB_in & ~m_ddrB);
}
WRITE8_MEMBER(stfight_state::cshooter_68705_port_b_w)
WRITE8_MEMBER(stfight_state::stfight_68705_port_b_w)
{
if ((m_ddrB & 0x01) && (data & 0x01) && (~m_portB_out & 0x01))
if ((m_ddrB & 0x20) && (~data & 0x20))
{
printf("bit 0\n");
}
if ((m_ddrB & 0x02) && (data & 0x02) && (~m_portB_out & 0x02))
{
printf("bit 1\n");
}
if ((m_ddrB & 0x04) && (data & 0x04) && (~m_portB_out & 0x04))
{
printf("bit 2\n");
}
if ((m_ddrB & 0x08) && (data & 0x08) && (~m_portB_out & 0x08))
{
printf("bit 3\n");
}
if ((m_ddrB & 0x10) && (data & 0x10) && (~m_portB_out & 0x10))
{
printf("bit 4\n");
}
if ((m_ddrB & 0x20) && (data & 0x20) && (~m_portB_out & 0x20))
{
//printf("bit 5\n");
m_portB_in = m_from_main;
if (m_main_sent)
{
//m_mcu->set_input_line(0, CLEAR_LINE);
}
m_main_sent = 0;
}
if ((m_ddrB & 0x40) && (data & 0x40) && (~m_portB_out & 0x40))
{
printf("bit 6\n");
}
if ((m_ddrB & 0x80) && (data & 0x80) && (~m_portB_out & 0x80))
{
printf("bit 7\n");
// Acknowledge Z80 command
m_cpu_to_mcu_empty = 1;
}
m_portB_out = data;
}
READ8_MEMBER(stfight_state::cshooter_68705_port_c_r)
READ8_MEMBER(stfight_state::stfight_68705_port_c_r)
{
return (m_portC_out & m_ddrC) | (m_portC_in & ~m_ddrC);
}
WRITE8_MEMBER(stfight_state::cshooter_68705_port_c_w)
WRITE8_MEMBER(stfight_state::stfight_68705_port_c_w)
{
// Signal a valid coin on the falling edge
if ((m_ddrC & 0x01) && (m_portC_out & 0x01) && !(data & 0x01))
{
m_coin_state &= ~1;
}
if ((m_ddrC & 0x02) && (m_portC_out & 0x02) && !(data & 0x02))
{
m_coin_state &= ~2;
}
if (m_ddrC & 0x04)
{
if (data & 0x04)
{
m_adpcm_reset = 1;
m_adpcm_nibble = 0;
m_msm->reset_w(1);
}
else
{
m_adpcm_reset = 0;
m_msm->reset_w(0);
}
}
if (m_ddrC & 0x08)
m_maincpu->set_input_line(INPUT_LINE_NMI, data & 0x08 ? CLEAR_LINE : ASSERT_LINE);
m_portC_out = data;
}