airbustr: add kaneko_hit device

This commit is contained in:
hap 2022-09-09 13:59:40 +02:00
parent ad4f0c9bf7
commit 7c1801658a
6 changed files with 128 additions and 150 deletions

View File

@ -49,8 +49,8 @@ protected:
attotime m_sensordelay;
bool m_disable_leds;
u8 m_led_data = 0;
u8 m_mux = 0;
u8 m_led_data;
u8 m_mux;
};

View File

@ -34,9 +34,9 @@ private:
void update_lcd();
int m_strobe = 0;
u8 m_digit_idx = 0;
u8 m_digit_data[4] = { 0, 0, 0, 0 };
int m_strobe;
u8 m_digit_idx;
u8 m_digit_data[4];
};

View File

@ -42,8 +42,8 @@ private:
void lcd_palette(palette_device &palette) const;
HD44780_PIXEL_UPDATE(lcd_pixel_update);
u8 m_latch = 0;
u8 m_ctrl = 0;
u8 m_latch;
u8 m_ctrl;
};

View File

@ -1,6 +1,5 @@
// license:BSD-3-Clause
// copyright-holders: Luca Elia
/***************************************************************************
Air Buster
@ -86,10 +85,6 @@ f150<- index of table of routines at 2907
----------------
Interesting routines (sub CPU)
-------------------------------
@ -154,13 +149,6 @@ f14c scroll regs high bits
----------------
Interesting routines (sound CPU)
-------------------------------
@ -179,12 +167,11 @@ c760 ROM bank
To Do
-----
- Is the sub CPU / sound CPU communication status port (0e) correct ?
- Main CPU: port 01 ? boot sub/sound CPU?
- Is the sub CPU / sound CPU communication status port (0x0e) correct ?
- Main CPU: port 0x01 ? boot sub/sound CPU?
- Sub CPU: port 0x38 ? irq ack?
- incomplete DSWs
- Spriteram low 0x300 bytes (priority?)
- Hook up KANEKO CALC1 chip for the original sets
*/
/*
@ -228,7 +215,6 @@ Code at 505: waits for bit 1 to go low, writes command, waits for bit
#include "cpu/z80/z80.h"
#include "machine/gen_latch.h"
#include "machine/timer.h"
#include "machine/watchdog.h"
#include "sound/okim6295.h"
#include "sound/ymopn.h"
@ -265,10 +251,10 @@ public:
, m_slave(*this, "slave")
, m_audiocpu(*this, "audiocpu")
, m_pandora(*this, "pandora")
, m_calc1(*this, "calc1")
, m_gfxdecode(*this, "gfxdecode")
, m_screen(*this, "screen")
, m_palette(*this, "palette")
, m_watchdog(*this, "watchdog")
, m_soundlatch(*this, "soundlatch%u", 1)
{
}
@ -276,8 +262,6 @@ public:
void airbustr(machine_config &config);
void airbustrb(machine_config &config);
void init_airbustr();
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
@ -304,13 +288,14 @@ private:
required_device<cpu_device> m_slave;
required_device<cpu_device> m_audiocpu;
required_device<kaneko_pandora_device> m_pandora;
optional_device<kaneko_hit_device> m_calc1;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
required_device<watchdog_timer_device> m_watchdog;
required_device_array<generic_latch_8_device, 2> m_soundlatch;
uint8_t devram_r(address_space &space, offs_t offset);
void calc1_w(offs_t offset, uint8_t data);
uint8_t calc1_r(offs_t offset);
void master_nmi_trigger_w(uint8_t data);
void master_bankswitch_w(uint8_t data);
void slave_bankswitch_w(uint8_t data);
@ -325,16 +310,18 @@ private:
DECLARE_WRITE_LINE_MEMBER(screen_vblank);
INTERRUPT_GEN_MEMBER(slave_interrupt);
TIMER_DEVICE_CALLBACK_MEMBER(scanline);
void master_io_map(address_map &map);
void master_map(address_map &map);
void slave_io_map(address_map &map);
void master_prot_map(address_map &map);
void master_io_map(address_map &map);
void slave_map(address_map &map);
void sound_io_map(address_map &map);
void slave_io_map(address_map &map);
void sound_map(address_map &map);
void sound_io_map(address_map &map);
};
// video
// Video
/**************************************************************************
@ -364,7 +351,6 @@ private:
**************************************************************************/
/* Scroll Registers
Port:
@ -444,40 +430,25 @@ WRITE_LINE_MEMBER(airbustr_state::screen_vblank)
}
// machine
// Machine
// Read / Write Handlers
uint8_t airbustr_state::devram_r(address_space &space, offs_t offset)
void airbustr_state::calc1_w(offs_t offset, uint8_t data)
{
// this is a custom implementation of the Kaneko CALC1 chip. TODO: hook up the generic implementation in kaneko_hit.cpp
switch (offset)
{
/* Reading efe0 probably resets a watchdog mechanism
that would reset the main CPU. We avoid this and patch
the ROM instead (main CPU has to be reset once at startup) */
case 0xfe0:
return m_watchdog->reset_r(space);
offset += 0x1fe0;
m_devram[offset] = data;
/* Reading a word at eff2 probably yields the product
of the words written to eff0 and eff2 */
case 0xff2:
case 0xff3:
{
int x = (m_devram[0xff0] + m_devram[0xff1] * 256) * (m_devram[0xff2] + m_devram[0xff3] * 256);
if (offset == 0xff2)
return (x & 0x00ff) >> 0;
else
return (x & 0xff00) >> 8;
}
// CALC1 chip is 16-bit
uint16_t data16 = m_devram[offset | 1] << 8 | m_devram[offset & ~1];
m_calc1->kaneko_hit_w((offset & 0x1f) / 2, data16);
}
/* Reading eff4, F0 times must yield at most 80-1 consecutive
equal values */
case 0xff4:
return machine().rand();
default:
return m_devram[offset];
}
uint8_t airbustr_state::calc1_r(offs_t offset)
{
// CALC1 chip is 16-bit
uint16_t ret = m_calc1->kaneko_hit_r(offset / 2);
return (offset & 1) ? (ret >> 8) : (ret & 0xff);
}
void airbustr_state::master_nmi_trigger_w(uint8_t data)
@ -537,17 +508,25 @@ void airbustr_state::coin_counter_w(uint8_t data)
machine().bookkeeping().coin_lockout_w(1, ~data & 8);
}
// Memory Maps
void airbustr_state::master_map(address_map &map)
{
map(0x0000, 0x7fff).rom();
map(0x8000, 0xbfff).bankr(m_masterbank);
map(0xc000, 0xcfff).rw(m_pandora, FUNC(kaneko_pandora_device::spriteram_r), FUNC(kaneko_pandora_device::spriteram_w));
map(0xd000, 0xdfff).ram();
map(0xe000, 0xefff).ram().share(m_devram); // shared with protection device
map(0xe000, 0xefff).ram().share(m_devram); // shared with protection device (see below)
map(0xf000, 0xffff).ram().share("master_slave");
}
void airbustr_state::master_prot_map(address_map &map)
{
master_map(map);
map(0xefe0, 0xeff5).rw(FUNC(airbustr_state::calc1_r), FUNC(airbustr_state::calc1_w));
}
void airbustr_state::master_io_map(address_map &map)
{
map.global_mask(0xff);
@ -600,7 +579,8 @@ void airbustr_state::sound_io_map(address_map &map)
map(0x06, 0x06).r(m_soundlatch[0], FUNC(generic_latch_8_device::read)).w(m_soundlatch[1], FUNC(generic_latch_8_device::write));
}
/* Input Ports */
// Input Ports
static INPUT_PORTS_START( airbustr )
PORT_START("P1")
@ -631,7 +611,7 @@ static INPUT_PORTS_START( airbustr )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // used
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // used
PORT_START("DSW1")
PORT_DIPUNUSED_DIPLOC( 0x01, IP_ACTIVE_LOW, "SW1:1" )
@ -640,9 +620,9 @@ static INPUT_PORTS_START( airbustr )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_SERVICE_DIPLOC( 0x04, IP_ACTIVE_LOW, "SW1:3" )
PORT_DIPNAME( 0x08, 0x08, "Coin Mode" ) PORT_DIPLOCATION("SW1:4")
PORT_DIPSETTING( 0x08, "Mode 1" ) // routine at 0x056d: 11 21 12 16 (bit 3 active)
PORT_DIPSETTING( 0x00, "Mode 2" ) // 11 21 13 14 (bit 3 not active)
PORT_DIPNAME( 0x30, 0x30, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:5,6")
PORT_DIPSETTING( 0x08, "Mode 1" ) // routine at 0x056d: 11 21 12 16 (bit 3 active)
PORT_DIPSETTING( 0x00, "Mode 2" ) // 11 21 13 14 (bit 3 not active)
PORT_DIPNAME( 0x30, 0x30, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:5,6")
PORT_DIPSETTING( 0x20, DEF_STR( 2C_1C ) ) PORT_CONDITION("DSW1", 0x08, NOTEQUALS, 0x00)
PORT_DIPSETTING( 0x30, DEF_STR( 1C_1C ) ) PORT_CONDITION("DSW1", 0x08, NOTEQUALS, 0x00)
PORT_DIPSETTING( 0x10, DEF_STR( 1C_2C ) ) PORT_CONDITION("DSW1", 0x08, NOTEQUALS, 0x00)
@ -651,7 +631,7 @@ static INPUT_PORTS_START( airbustr )
PORT_DIPSETTING( 0x30, DEF_STR( 1C_1C ) ) PORT_CONDITION("DSW1", 0x08, EQUALS, 0x00)
PORT_DIPSETTING( 0x10, DEF_STR( 1C_3C ) ) PORT_CONDITION("DSW1", 0x08, EQUALS, 0x00)
PORT_DIPSETTING( 0x00, DEF_STR( 1C_4C ) ) PORT_CONDITION("DSW1", 0x08, EQUALS, 0x00)
PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:7,8")
PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:7,8")
PORT_DIPSETTING( 0x80, DEF_STR( 2C_1C ) ) PORT_CONDITION("DSW1", 0x08, NOTEQUALS, 0x00)
PORT_DIPSETTING( 0xc0, DEF_STR( 1C_1C ) ) PORT_CONDITION("DSW1", 0x08, NOTEQUALS, 0x00)
PORT_DIPSETTING( 0x40, DEF_STR( 1C_2C ) ) PORT_CONDITION("DSW1", 0x08, NOTEQUALS, 0x00)
@ -699,6 +679,7 @@ static INPUT_PORTS_START( airbustrj )
PORT_DIPSETTING( 0x80, DEF_STR( 1C_2C ) )
INPUT_PORTS_END
// Graphics Decode Information
static GFXDECODE_START( gfx_airbustr )
@ -728,6 +709,7 @@ INTERRUPT_GEN_MEMBER(airbustr_state::slave_interrupt)
device.execute().set_input_line_and_vector(0, HOLD_LINE, 0xfd); // Z80
}
// Machine Initialization
void airbustr_state::machine_start()
@ -750,17 +732,18 @@ void airbustr_state::machine_reset()
m_highbits = 0;
}
// Machine Driver
void airbustr_state::airbustr(machine_config &config)
void airbustr_state::airbustrb(machine_config &config)
{
// basic machine hardware
Z80(config, m_master, XTAL(12'000'000) / 2); // verified on PCB
Z80(config, m_master, XTAL(12'000'000) / 2); // verified on PCB
m_master->set_addrmap(AS_PROGRAM, &airbustr_state::master_map);
m_master->set_addrmap(AS_IO, &airbustr_state::master_io_map);
TIMER(config, "scantimer").configure_scanline(FUNC(airbustr_state::scanline), "screen", 0, 1);
Z80(config, m_slave, XTAL(12'000'000) / 2); // verified on PCB
Z80(config, m_slave, XTAL(12'000'000) / 2); // verified on PCB
m_slave->set_addrmap(AS_PROGRAM, &airbustr_state::slave_map);
m_slave->set_addrmap(AS_IO, &airbustr_state::slave_io_map);
m_slave->set_vblank_int("screen", FUNC(airbustr_state::slave_interrupt)); // nmi signal from master CPU
@ -769,10 +752,8 @@ void airbustr_state::airbustr(machine_config &config)
m_audiocpu->set_addrmap(AS_PROGRAM, &airbustr_state::sound_map);
m_audiocpu->set_addrmap(AS_IO, &airbustr_state::sound_io_map);
config.set_maximum_quantum(attotime::from_hz(6000)); // Palette RAM is filled by sub CPU with data supplied by main CPU
// Maybe a high value is safer in order to avoid glitches
WATCHDOG_TIMER(config, m_watchdog).set_time(attotime::from_seconds(3)); // a guess, and certainly wrong
// palette RAM is filled by sub CPU with data supplied by main CPU, maybe a high value is safer in order to avoid glitches
config.set_maximum_quantum(attotime::from_hz(6000));
// video hardware
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
@ -799,7 +780,7 @@ void airbustr_state::airbustr(machine_config &config)
GENERIC_LATCH_8(config, m_soundlatch[1]);
ym2203_device &ymsnd(YM2203(config, "ymsnd", XTAL(12'000'000) / 4)); // verified on PCB
ym2203_device &ymsnd(YM2203(config, "ymsnd", XTAL(12'000'000) / 4)); // verified on PCB
ymsnd.port_a_read_callback().set_ioport("DSW1");
ymsnd.port_b_read_callback().set_ioport("DSW2");
ymsnd.irq_handler().set_inputline(m_audiocpu, INPUT_LINE_IRQ0);
@ -808,13 +789,17 @@ void airbustr_state::airbustr(machine_config &config)
ymsnd.add_route(2, "mono", 0.25);
ymsnd.add_route(3, "mono", 0.50);
OKIM6295(config, "oki", XTAL(12'000'000)/4, okim6295_device::PIN7_LOW).add_route(ALL_OUTPUTS, "mono", 0.80); // verified on PCB
OKIM6295(config, "oki", XTAL(12'000'000)/4, okim6295_device::PIN7_LOW).add_route(ALL_OUTPUTS, "mono", 0.80); // verified on PCB
}
void airbustr_state::airbustrb(machine_config &config)
void airbustr_state::airbustr(machine_config &config)
{
airbustr(config);
m_watchdog->set_time(attotime::from_seconds(0)); // no protection device or watchdog
airbustrb(config);
m_master->set_addrmap(AS_PROGRAM, &airbustr_state::master_prot_map);
KANEKO_HIT(config, m_calc1).set_type(0);
WATCHDOG_TIMER(config, "watchdog").set_time(attotime::from_seconds(3)); // a guess, and certainly wrong
}
@ -907,18 +892,11 @@ ROM_START( airbustrb )
ROM_LOAD( "3.bin", 0x20000, 0x20000, CRC(58cd19e2) SHA1(479f22241bf29f7af67d9679fc6c20f10004fdd8) )
ROM_END
// Driver Initialization
void airbustr_state::init_airbustr()
{
m_master->space(AS_PROGRAM).install_read_handler(0xe000, 0xefff, read8m_delegate(*this, FUNC(airbustr_state::devram_r))); // protection device lives here
}
} // anonymous namespace
// Game Drivers
GAME( 1990, airbustr, 0, airbustr, airbustr, airbustr_state, init_airbustr, ROT0, "Kaneko (Namco license)", "Air Buster: Trouble Specialty Raid Unit (World)", MACHINE_SUPPORTS_SAVE ) // 891220
GAME( 1990, airbustrj, airbustr, airbustr, airbustrj, airbustr_state, init_airbustr, ROT0, "Kaneko (Namco license)", "Air Buster: Trouble Specialty Raid Unit (Japan)", MACHINE_SUPPORTS_SAVE ) // 891229
GAME( 1990, airbustrb, airbustr, airbustrb, airbustrj, airbustr_state, empty_init, ROT0, "bootleg", "Air Buster: Trouble Specialty Raid Unit (bootleg)", MACHINE_SUPPORTS_SAVE ) // based on Japan set (891229)
GAME( 1990, airbustr, 0, airbustr, airbustr, airbustr_state, empty_init, ROT0, "Kaneko (Namco license)", "Air Buster: Trouble Specialty Raid Unit (World)", MACHINE_SUPPORTS_SAVE ) // 891220
GAME( 1990, airbustrj, airbustr, airbustr, airbustrj, airbustr_state, empty_init, ROT0, "Kaneko (Namco license)", "Air Buster: Trouble Specialty Raid Unit (Japan)", MACHINE_SUPPORTS_SAVE ) // 891229
GAME( 1990, airbustrb, airbustr, airbustrb, airbustrj, airbustr_state, empty_init, ROT0, "bootleg", "Air Buster: Trouble Specialty Raid Unit (bootleg)", MACHINE_SUPPORTS_SAVE ) // based on Japan set (891229)

View File

@ -418,7 +418,6 @@ uint32_t expro02_state::screen_update_zipzap(screen_device &screen, bitmap_ind16
*************************************/
static INPUT_PORTS_START( expro02 ) // TODO: at least for the 1994 version of New Fantasia running on the 940630 SWA and SWB should be inverted
PORT_START("DSW1")
PORT_DIPNAME( 0x0003, 0x0003, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SWA:1,2")
PORT_DIPSETTING( 0x0002, DEF_STR( Easy ) )
@ -731,11 +730,11 @@ void expro02_state::expro02_map(address_map &map)
map(0x900000, 0x900000).w(FUNC(expro02_state::oki_bankswitch_w));
map(0xa00000, 0xa00001).nopw(); /* ??? */
map(0xc80000, 0xc8ffff).ram();
map(0xe00000, 0xe00015).rw("calc1_mcu", FUNC(kaneko_hit_device::kaneko_hit_r), FUNC(kaneko_hit_device::kaneko_hit_w));
map(0xe00000, 0xe00015).rw("calc1", FUNC(kaneko_hit_device::kaneko_hit_r), FUNC(kaneko_hit_device::kaneko_hit_w));
}
// bigger ROM space, OKI commands moved, no CALC mcu
// bigger ROM space, OKI commands moved, no CALC1 chip
void expro02_state::fantasia_map(address_map &map)
{
expro02_video_base_map(map);
@ -922,8 +921,6 @@ void expro02_state::expro02(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &expro02_state::expro02_map);
TIMER(config, "scantimer").configure_scanline(FUNC(expro02_state::scanline), "screen", 0, 1);
/* CALC01 MCU @ 16Mhz (unknown type, simulated) */
/* video hardware */
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60);
@ -947,7 +944,7 @@ void expro02_state::expro02(machine_config &config)
m_kaneko_spr->set_palette(m_palette);
m_kaneko_spr->set_color_base(0x100);
KANEKO_HIT(config, "calc1_mcu").set_type(0);
KANEKO_HIT(config, "calc1").set_type(0);
/* arm watchdog */
WATCHDOG_TIMER(config, "watchdog").set_time(attotime::from_seconds(3)); /* a guess, and certainly wrong */
@ -968,7 +965,7 @@ void expro02_state::comad(machine_config &config)
/* basic machine hardware */
m_maincpu->set_addrmap(AS_PROGRAM, &expro02_state::fantasia_map);
config.device_remove("calc1_mcu");
config.device_remove("calc1");
// these values might not be correct, behavior differs from original boards
m_view2->set_invert_flip(1);

View File

@ -1,38 +1,43 @@
// license:BSD-3-Clause
// copyright-holders:Luca Elia, David Haywood,Stephane Humbert
// copyright-holders:Luca Elia, David Haywood, Stephane Humbert
/* Kaneko 'Calc' hitbox collision / protection
It is thought that this is done by the 'CALC1' 'TOYBOX' and 'CALC3' protection chips found on the various boards
however we have 3 implementations, and they don't quite pair up with the chips at the moment, this might be
because our implementations are wrong / incomplete, or in some cases the newer chips are backwards compatible.
It is thought that this is done by the 'CALC1' 'TOYBOX' and 'CALC3' protection chips found on the various boards
however we have 3 implementations, and they don't quite pair up with the chips at the moment, this might be
because our implementations are wrong / incomplete, or in some cases the newer chips are backwards compatible.
galpanica - CALC1 - type 0
sandscrp - CALC1 - type 0 ( only uses Random Number? )
bonkadv - TOYBOX - type 0 ( only uses Random Number, XY Overlap Collision bit and register '0x02' )
gtmr - TOYBOX - type 1 ( only uses Random Number )
gtmr2 - TOYBOX - type 1 ( only uses Random Number )
bloodwar - TOYBOX - type 1
shogwarr - CALC3 - type 1
brapboys - CALC3 - type 2
airbustr - CALC1 - type 0
expro02 - CALC1 - type 0
galpanica - CALC1 - type 0
sandscrp - CALC1 - type 0 ( only uses Random Number? )
bonkadv - TOYBOX - type 0 ( only uses Random Number, XY Overlap Collision bit and register '0x02' )
gtmr - TOYBOX - type 1 ( only uses Random Number )
gtmr2 - TOYBOX - type 1 ( only uses Random Number )
bloodwar - TOYBOX - type 1
shogwarr - CALC3 - type 1
brapboys - CALC3 - type 2
note: shogwarr won't work with our brapboys implementation despite them being the same PCB and same MCU, this
suggests that at least one of the implementations is wrong
note: shogwarr won't work with our brapboys implementation despite them being the same PCB and same CALC chip,
this suggests that at least one of the implementations is wrong
suprnova.c also has a similar device, the implementation hasn't been fully compared
suprnova.cpp also has a similar device, the implementation hasn't been fully compared
CALC1 is a 40 pin DIP ULA with no internal ROM
CALC1 is a 40 pin DIP ULA with no internal ROM
TODO:
- change to 3 devices, it's not like m_hittype can be changed on the fly
- is watchdog used by any driver? if not, watchdog device can be moved to here
*/
#include "emu.h"
#include "kaneko_hit.h"
DEFINE_DEVICE_TYPE(KANEKO_HIT, kaneko_hit_device, "kaneko_hit", "Kaneko CALC Hitbox")
kaneko_hit_device::kaneko_hit_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, KANEKO_HIT, tag, owner, clock),
m_watchdog(*this, "^watchdog")
kaneko_hit_device::kaneko_hit_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, KANEKO_HIT, tag, owner, clock),
m_watchdog(*this, "^watchdog")
{
m_hittype = -1;
memset(&m_hit, 0, sizeof m_hit);
@ -132,11 +137,14 @@ void kaneko_hit_device::kaneko_hit_w(offs_t offset, uint16_t data, uint16_t mem_
}
}
/*********************************************************************
TYPE 0
galpanica
sandscrp
bonkadv
* airbustr
* expro02
* galpanica
* sandscrp
* bonkadv
*********************************************************************/
uint16_t kaneko_hit_device::kaneko_hit_type0_r(offs_t offset)
@ -220,8 +228,8 @@ void kaneko_hit_device::kaneko_hit_type0_w(offs_t offset, uint16_t data, uint16_
/*********************************************************************
TYPE 1
shogwarr
bloorwar
* shogwarr
* bloorwar
*********************************************************************/
uint16_t kaneko_hit_device::kaneko_hit_type1_r(offs_t offset)
@ -230,7 +238,6 @@ uint16_t kaneko_hit_device::kaneko_hit_type1_r(offs_t offset)
uint16_t data = 0;
int16_t x_coll, y_coll;
x_coll = calc_compute_x(hit);
y_coll = calc_compute_y(hit);
@ -354,10 +361,9 @@ int16_t kaneko_hit_device::calc_compute_y(calc1_hit_t &hit)
/*********************************************************************
TYPE 2
brapboys
* brapboys
*********************************************************************/
void kaneko_hit_device::kaneko_hit_type2_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
calc3_hit_t &hit3 = m_hit3;
@ -369,54 +375,54 @@ void kaneko_hit_device::kaneko_hit_type2_w(offs_t offset, uint16_t data, uint16_
// p is position, s is size
case 0x00:
case 0x28:
hit3.x1po = data; break;
hit3.x1po = data; break;
case 0x04:
case 0x2c:
hit3.x1so = data; break;
hit3.x1so = data; break;
case 0x08:
case 0x30:
hit3.y1po = data; break;
hit3.y1po = data; break;
case 0x0c:
case 0x34:
hit3.y1so = data; break;
hit3.y1so = data; break;
case 0x10:
case 0x58:
hit3.x2po = data; break;
hit3.x2po = data; break;
case 0x14:
case 0x5c:
hit3.x2so = data; break;
hit3.x2so = data; break;
case 0x18:
case 0x60:
hit3.y2po = data; break;
hit3.y2po = data; break;
case 0x1c:
case 0x64:
hit3.y2so = data; break;
hit3.y2so = data; break;
case 0x38:
case 0x50:
hit3.z1po = data; break;
hit3.z1po = data; break;
case 0x3c:
case 0x54:
hit3.z1so = data; break;
hit3.z1so = data; break;
case 0x20:
case 0x68:
hit3.z2po = data; break;
hit3.z2po = data; break;
case 0x24:
case 0x6c:
hit3.z2so = data; break;
hit3.z2so = data; break;
case 0x70:
hit3.mode=data;break;
hit3.mode = data; break;
default:
logerror("%s warning - write unmapped hit address %06x [ %06x] = %06x\n",machine().describe_context(),offset<<1, idx, data);
@ -477,7 +483,7 @@ uint16_t kaneko_hit_device::kaneko_hit_type2_r(offs_t offset)
return 0;
}
//calculate simple intersection of two segments
// calculate simple intersection of two segments
int kaneko_hit_device::type2_calc_compute(int x1, int w1, int x2, int w2)
{
@ -485,21 +491,21 @@ int kaneko_hit_device::type2_calc_compute(int x1, int w1, int x2, int w2)
if(x2>=x1 && x2+w2<=(x1+w1))
{
//x2 inside x1
// x2 inside x1
dist=w2;
}
else
{
if(x1>=x2 && x1+w1<=(x2+w2))
{
//x1 inside x2
// x1 inside x2
dist=w1;
}
else
{
if(x2<x1)
{
//swap
// swap
int tmp=x1;
x1=x2;
x2=tmp;
@ -513,7 +519,7 @@ int kaneko_hit_device::type2_calc_compute(int x1, int w1, int x2, int w2)
return dist;
}
//calc segment coordinates
// calc segment coordinates
void kaneko_hit_device::type2_calc_org(int mode, int x0, int s0, int* x1, int* s1)
{
@ -524,12 +530,12 @@ void kaneko_hit_device::type2_calc_org(int mode, int x0, int s0, int* x1, int*
case 2: *x1=x0-s0; *s1=s0; break;
case 3: *x1=x0-s0; *s1=2*s0; break;
}
//x1 is the left most coord, s1 = width
// x1 is the left most coord, s1 = width
}
void kaneko_hit_device::type2_recalc_collisions(calc3_hit_t &hit3)
{
//calculate positions and sizes
// calculate positions and sizes
int mode=hit3.mode;
@ -543,17 +549,14 @@ void kaneko_hit_device::type2_recalc_collisions(calc3_hit_t &hit3)
type2_calc_org((mode>>10)&3, hit3.y2po, hit3.y2so, &hit3.y2p, &hit3.y2s);
type2_calc_org((mode>>12)&3, hit3.z2po, hit3.z2so, &hit3.z2p, &hit3.z2s);
hit3.x1tox2=abs(hit3.x2po-hit3.x1po);
hit3.y1toy2=abs(hit3.y2po-hit3.y1po);
hit3.z1toz2=abs(hit3.z2po-hit3.z1po);
hit3.x_coll = type2_calc_compute(hit3.x1p, hit3.x1s, hit3.x2p, hit3.x2s);
hit3.y_coll = type2_calc_compute(hit3.y1p, hit3.y1s, hit3.y2p, hit3.y2s);
hit3.z_coll = type2_calc_compute(hit3.z1p, hit3.z1s, hit3.z2p, hit3.z2s);
// 4th nibble: Y Absolute Collision -> possible values = 9,8,4,3,2
if (hit3.y1p > hit3.y2p) hit3.flags |= 0x2000;
else if (hit3.y1p == hit3.y2p) hit3.flags |= 0x4000;