XaviX - refactoring, Gururin World promoted to working (#4775)

* code shuffle (nw)

* refactoring (nw)

* make it actually possible to control epo_guru.  note, chase scenes seem to run in slow motion, while the timer runs at normal speed, making them impossible, need to fix that before promoting.

* (nw)

* 4 bits either way works better in practice

* promoted to WORKING
---
Gururin World (Japan) [David Haywood, Sean Riddle, Peter Wilhelmsen. ShouTime]

* tidy (nw)
This commit is contained in:
David Haywood 2019-03-20 14:36:04 +00:00 committed by R. Belmont
parent 7bffc048be
commit dbb071d328
8 changed files with 480 additions and 217 deletions

View File

@ -3546,6 +3546,10 @@ files {
MAME_DIR .. "src/mame/machine/xavix_io.h",
MAME_DIR .. "src/mame/machine/xavix_adc.cpp",
MAME_DIR .. "src/mame/machine/xavix_adc.h",
MAME_DIR .. "src/mame/machine/xavix_anport.h",
MAME_DIR .. "src/mame/machine/xavix_anport.cpp",
MAME_DIR .. "src/mame/machine/xavix_math.h",
MAME_DIR .. "src/mame/machine/xavix_math.cpp",
MAME_DIR .. "src/mame/machine/xavix2002_io.cpp",
MAME_DIR .. "src/mame/machine/xavix2002_io.h",
MAME_DIR .. "src/mame/drivers/xavix2.cpp",

View File

@ -371,11 +371,11 @@ void xavix_state::xavix_lowbus_map(address_map &map)
map(0x7a80, 0x7a80).rw(FUNC(xavix_state::ioevent_enable_r), FUNC(xavix_state::ioevent_enable_w));
map(0x7a81, 0x7a81).rw(FUNC(xavix_state::ioevent_irqstate_r), FUNC(xavix_state::ioevent_irqack_w));
// Mouse?
map(0x7b00, 0x7b00).rw(FUNC(xavix_state::mouse_7b00_r), FUNC(xavix_state::mouse_7b00_w));
map(0x7b01, 0x7b01).rw(FUNC(xavix_state::mouse_7b01_r), FUNC(xavix_state::mouse_7b01_w));
map(0x7b10, 0x7b10).rw(FUNC(xavix_state::mouse_7b10_r), FUNC(xavix_state::mouse_7b10_w));
map(0x7b11, 0x7b11).rw(FUNC(xavix_state::mouse_7b11_r), FUNC(xavix_state::mouse_7b11_w));
// Mouse / Trackball?
map(0x7b00, 0x7b00).rw("anport", FUNC(xavix_anport_device::mouse_7b00_r), FUNC(xavix_anport_device::mouse_7b00_w));
map(0x7b01, 0x7b01).rw("anport", FUNC(xavix_anport_device::mouse_7b01_r), FUNC(xavix_anport_device::mouse_7b01_w));
map(0x7b10, 0x7b10).rw("anport", FUNC(xavix_anport_device::mouse_7b10_r), FUNC(xavix_anport_device::mouse_7b10_w));
map(0x7b11, 0x7b11).rw("anport", FUNC(xavix_anport_device::mouse_7b11_r), FUNC(xavix_anport_device::mouse_7b11_w));
// Lightgun / pen 2 control
//map(0x7b18, 0x7b1b)
@ -394,11 +394,11 @@ void xavix_state::xavix_lowbus_map(address_map &map)
map(0x7c03, 0x7c03).r(FUNC(xavix_state::timer_curval_r));
// Barrel Shifter registers
map(0x7ff0, 0x7ff1).rw(FUNC(xavix_state::barrel_r), FUNC(xavix_state::barrel_w));
map(0x7ff0, 0x7ff1).rw("math", FUNC(xavix_math_device::barrel_r), FUNC(xavix_math_device::barrel_w));
// Multiply / Divide registers
map(0x7ff2, 0x7ff4).rw(FUNC(xavix_state::mult_param_r), FUNC(xavix_state::mult_param_w));
map(0x7ff5, 0x7ff6).rw(FUNC(xavix_state::mult_r), FUNC(xavix_state::mult_w));
map(0x7ff2, 0x7ff4).rw("math", FUNC(xavix_math_device::mult_param_r), FUNC(xavix_math_device::mult_param_w));
map(0x7ff5, 0x7ff6).rw("math", FUNC(xavix_math_device::mult_r), FUNC(xavix_math_device::mult_w));
// CPU Vector registers
map(0x7ff9, 0x7ff9).w(FUNC(xavix_state::vector_enable_w)); // enables / disables the custom vectors
@ -1100,6 +1100,47 @@ static INPUT_PORTS_START( epo_epp )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
INPUT_PORTS_END
// there is also a rumble output, likely mapped to one of the port bits
static INPUT_PORTS_START( epo_guru )
PORT_INCLUDE(xavix)
PORT_MODIFY("IN0")
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON1 )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) // used in the 'from behind' game at least
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
PORT_MODIFY("MOUSE1X")
// PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_SENSITIVITY(6) PORT_KEYDELTA(16) PORT_PLAYER(1) PORT_MINMAX(0x44,0xbc)
PORT_BIT( 0x1f, 0x10, IPT_AD_STICK_X ) PORT_SENSITIVITY(6) PORT_KEYDELTA(16) PORT_PLAYER(1) // PORT_MINMAX(0x44,0xbc)
/*
(0x20 is subtracted from value returned in read handler)
main game
00 still
01 - 3c right
3d - 78 left - 78 is a nice slow left but invalid for the sub game
79 - 7f right
80 - 87 left
88 - c3 right
c4 - ff left
sub game (break-out)
00 still
01 - 3f right
40 - 7f left
80 still
81 - bf right
c0 - ff left
so valid range seems to be c4-ff (left), 00 (still), 01-3c (right) even if this means the slowest speed going left is faster than the slowest speed going right
maybe actual range is 5 bits either way?
4 bits either way seems to work best in practice
*/
INPUT_PORTS_END
static INPUT_PORTS_START( epo_efdx )
PORT_INCLUDE(xavix_i2c)
@ -1211,6 +1252,14 @@ void xavix_state::xavix(machine_config &config)
m_adc->read_6_callback().set(FUNC(xavix_state::adc6_r));
m_adc->read_7_callback().set(FUNC(xavix_state::adc7_r));
XAVIX_ANPORT(config, m_anport, 0);
m_anport->read_0_callback().set(FUNC(xavix_state::anport0_r));
m_anport->read_1_callback().set(FUNC(xavix_state::anport1_r));
m_anport->read_2_callback().set(FUNC(xavix_state::anport2_r));
m_anport->read_3_callback().set(FUNC(xavix_state::anport3_r));
XAVIX_MATH(config, m_math, 0);
/* video hardware */
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60);
@ -1239,6 +1288,14 @@ void xavix_state::xavix(machine_config &config)
m_sound->add_route(1, "rspeaker", 1.0);
}
void xavix_guru_state::xavix_guru(machine_config &config)
{
xavix_nv(config);
m_anport->read_2_callback().set(FUNC(xavix_guru_state::guru_anport2_r));
}
void xavix_i2c_state::xavix_i2c_24lc02(machine_config &config)
{
xavix(config);
@ -1262,6 +1319,16 @@ void xavix_i2c_state::xavix_i2c_24lc04(machine_config &config)
I2CMEM(config, "i2cmem", 0).set_page_size(16).set_data_size(0x200); // 24LC04 on Nostalgia games, 24C04 on others
}
void xavix_i2c_ltv_tam_state::xavix_i2c_24lc04_tam(machine_config &config)
{
xavix_i2c_24lc04(config);
m_anport->read_0_callback().set(FUNC(xavix_i2c_ltv_tam_state::tam_anport0_r));
m_anport->read_1_callback().set(FUNC(xavix_i2c_ltv_tam_state::tam_anport1_r));
m_anport->read_2_callback().set(FUNC(xavix_i2c_ltv_tam_state::tam_anport2_r));
m_anport->read_3_callback().set(FUNC(xavix_i2c_ltv_tam_state::tam_anport3_r));
}
void xavix_i2c_state::xavix_i2c_24c08(machine_config &config)
{
xavix(config);
@ -1345,6 +1412,16 @@ void xavix_state::xavix2000_nv(machine_config &config)
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
}
void xavix_2000_nv_sdb_state::xavix2000_nv_sdb(machine_config &config)
{
xavix2000_nv(config);
m_anport->read_0_callback().set(FUNC(xavix_2000_nv_sdb_state::sdb_anport0_r));
m_anport->read_1_callback().set(FUNC(xavix_2000_nv_sdb_state::sdb_anport1_r));
m_anport->read_2_callback().set(FUNC(xavix_2000_nv_sdb_state::sdb_anport2_r));
m_anport->read_3_callback().set(FUNC(xavix_2000_nv_sdb_state::sdb_anport3_r));
}
void xavix_i2c_state::xavix2000_i2c_24c04(machine_config &config)
{
xavix2000(config);
@ -1451,7 +1528,7 @@ void xavix_cart_state::xavix_cart_popira(machine_config &config)
// see code at 028060, using table from 00eb6d for conversion
READ8_MEMBER(xavix_popira2_cart_state::popira2_adc0_r)
{
uint8_t p2 = ioport("P2")->read() & 0x03;
uint8_t p2 = m_p2->read() & 0x03;
switch (p2)
{
case 0x00: return 0xa0;
@ -1465,7 +1542,7 @@ READ8_MEMBER(xavix_popira2_cart_state::popira2_adc0_r)
READ8_MEMBER(xavix_popira2_cart_state::popira2_adc1_r)
{
uint8_t p2 = (ioport("P2")->read() >> 2) & 0x03;
uint8_t p2 = (m_p2->read() >> 2) & 0x03;
switch (p2)
{
case 0x00: return 0xa0;
@ -1868,7 +1945,7 @@ CONS( 2006, epo_epp3, 0, 0, xavix, epo_epp, xavix_state,
CONS( 200?, epo_efdx, 0, 0, xavix_i2c_24c08, epo_efdx, xavix_i2c_state, init_epo_efdx, "Epoch / SSD Company LTD", "Excite Fishing DX (Japan)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND )
CONS( 2005, epo_guru, 0, 0, xavix, xavix, xavix_state, init_xavix, "Epoch / SSD Company LTD", "Gururin World (Japan)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND )
CONS( 2005, epo_guru, 0, 0, xavix_guru, epo_guru, xavix_guru_state, init_xavix, "Epoch / SSD Company LTD", "Gururin World (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
CONS( 2002, epo_dmon, 0, 0, xavix_i2c_24c02, xavix_i2c,xavix_i2c_state, init_xavix, "Epoch / SSD Company LTD", "Doraemon Wakuwaku Kuukihou (Japan)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) // full / proper title?
@ -1909,7 +1986,7 @@ CONS( 2003, evio, 0, 0, xavix_nv, evio, xavix_state,
// Lets!TVプレイ 超にんきスポット!ころがしほーだい たまごっちりぞーと (Let's! TV Play Chou Ninki Spot! Korogashi-Houdai Tamagotchi Resort) (only on the Japanese list? http://test.shinsedai.co.jp/english/products/Applied/list.html ) This also allows you to use an IR reciever to import a Tamagotchi from compatible games
CONS( 2006, ltv_tam, 0, 0, xavix_i2c_24lc04, ltv_tam,xavix_i2c_ltv_tam_state, init_xavix, "Bandai / SSD Company LTD", "Let's! TV Play Chou Ninki Spot! Korogashi-Houdai Tamagotchi Resort (Japan)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND )
CONS( 2006, ltv_tam, 0, 0, xavix_i2c_24lc04_tam, ltv_tam,xavix_i2c_ltv_tam_state, init_xavix, "Bandai / SSD Company LTD", "Let's! TV Play Chou Ninki Spot! Korogashi-Houdai Tamagotchi Resort (Japan)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND )
/* SuperXaviX(?) (XaviX 2000 type CPU) hardware titles (2nd XaviX generation?)
@ -1959,7 +2036,7 @@ ROM_START( ban_onep )
ROM_END
CONS( 2002, epo_ebox, 0, 0, xavix2000_nv, epo_epp, xavix_state, init_xavix, "Epoch / SSD Company LTD", "Excite Boxing (Japan)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND ) // doesn't use XaviX2000 extra opcodes, but had that type of CPU
CONS( 2004, epo_sdb, 0, 0, xavix2000_nv, epo_sdb, xavix_state, init_xavix, "Epoch / SSD Company LTD", "Super Dash Ball (Japan)", MACHINE_IMPERFECT_SOUND )
CONS( 2004, epo_sdb, 0, 0, xavix2000_nv_sdb, epo_sdb, xavix_2000_nv_sdb_state, init_xavix, "Epoch / SSD Company LTD", "Super Dash Ball (Japan)", MACHINE_IMPERFECT_SOUND )
CONS( 2005, ttv_sw, 0, 0, xavix2000_i2c_24c02, ttv_lotr, xavix_i2c_lotr_state, init_xavix, "Tiger / SSD Company LTD", "Star Wars Saga Edition - Lightsaber Battle Game", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND )
CONS( 2005, ttv_lotr, 0, 0, xavix2000_i2c_24c02, ttv_lotr, xavix_i2c_lotr_state, init_xavix, "Tiger / SSD Company LTD", "Lord Of The Rings - Warrior of Middle-Earth", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND )

View File

@ -21,6 +21,8 @@
#include "machine/xavix2002_io.h"
#include "machine/xavix_io.h"
#include "machine/xavix_adc.h"
#include "machine/xavix_anport.h"
#include "machine/xavix_math.h"
class xavix_sound_device : public device_t, public device_sound_interface
{
@ -103,6 +105,8 @@ public:
m_gfxdecode(*this, "gfxdecode"),
m_sound(*this, "xavix_sound"),
m_adc(*this, "adc"),
m_anport(*this, "anport"),
m_math(*this, "math"),
m_xavix2002io(*this, "xavix2002io")
{ }
@ -277,16 +281,6 @@ private:
uint8_t m_ioevent_active;
void process_ioevent(uint8_t bits);
DECLARE_READ8_MEMBER(mouse_7b00_r);
DECLARE_READ8_MEMBER(mouse_7b01_r);
DECLARE_READ8_MEMBER(mouse_7b10_r);
DECLARE_READ8_MEMBER(mouse_7b11_r);
DECLARE_WRITE8_MEMBER(mouse_7b00_w);
DECLARE_WRITE8_MEMBER(mouse_7b01_w);
DECLARE_WRITE8_MEMBER(mouse_7b10_w);
DECLARE_WRITE8_MEMBER(mouse_7b11_w);
DECLARE_WRITE8_MEMBER(slotreg_7810_w);
DECLARE_WRITE8_MEMBER(rom_dmatrg_w);
@ -458,15 +452,6 @@ private:
return 0xff;
}
DECLARE_READ8_MEMBER(mult_r);
DECLARE_WRITE8_MEMBER(mult_w);
DECLARE_READ8_MEMBER(mult_param_r);
DECLARE_WRITE8_MEMBER(mult_param_w);
uint8_t m_barrel_params[2];
DECLARE_READ8_MEMBER(barrel_r);
DECLARE_WRITE8_MEMBER(barrel_w);
DECLARE_READ8_MEMBER(adc0_r) { return m_an_in[0]->read(); };
DECLARE_READ8_MEMBER(adc1_r) { return m_an_in[1]->read(); };
@ -477,6 +462,11 @@ private:
DECLARE_READ8_MEMBER(adc6_r) { return m_an_in[6]->read(); };
DECLARE_READ8_MEMBER(adc7_r) { return m_an_in[7]->read(); };
DECLARE_READ8_MEMBER(anport0_r) { logerror("%s: unhandled anport0_r\n", machine().describe_context()); return 0xff; };
DECLARE_READ8_MEMBER(anport1_r) { logerror("%s: unhandled anport1_r\n", machine().describe_context()); return 0xff; };
DECLARE_READ8_MEMBER(anport2_r) { logerror("%s: unhandled anport2_r\n", machine().describe_context()); return 0xff; };
DECLARE_READ8_MEMBER(anport3_r) { logerror("%s: unhandled anport3_r\n", machine().describe_context()); return 0xff; };
void update_irqs();
uint8_t m_irqsource;
@ -486,9 +476,6 @@ private:
uint8_t m_irq_vector_lo_data;
uint8_t m_irq_vector_hi_data;
uint8_t m_multparams[3];
uint8_t m_multresults[2];
uint8_t m_spritefragment_dmaparam1[2];
uint8_t m_spritefragment_dmaparam2[2];
@ -576,6 +563,8 @@ private:
protected:
required_device<xavix_adc_device> m_adc;
required_device<xavix_anport_device> m_anport;
required_device<xavix_math_device> m_math;
optional_device<xavix2002_io_device> m_xavix2002io;
uint8_t m_extbusctrl[3];
@ -591,6 +580,42 @@ protected:
DECLARE_WRITE8_MEMBER(extended_extbus_reg2_w);
};
class xavix_guru_state : public xavix_state
{
public:
xavix_guru_state(const machine_config &mconfig, device_type type, const char *tag)
: xavix_state(mconfig, type, tag)
{ }
void xavix_guru(machine_config &config);
protected:
private:
DECLARE_READ8_MEMBER(guru_anport2_r) { uint8_t ret = m_mouse1x->read()-0x10; return ret; }
};
class xavix_2000_nv_sdb_state : public xavix_state
{
public:
xavix_2000_nv_sdb_state(const machine_config &mconfig, device_type type, const char *tag)
: xavix_state(mconfig, type, tag)
{ }
void xavix2000_nv_sdb(machine_config &config);
protected:
private:
DECLARE_READ8_MEMBER(sdb_anport0_r) { return m_mouse0x->read()^0x7f; }
DECLARE_READ8_MEMBER(sdb_anport1_r) { return m_mouse0y->read()^0x7f; }
DECLARE_READ8_MEMBER(sdb_anport2_r) { return m_mouse1x->read()^0x7f; }
DECLARE_READ8_MEMBER(sdb_anport3_r) { return m_mouse1y->read()^0x7f; }
};
class xavix_i2c_state : public xavix_state
{
public:
@ -637,8 +662,16 @@ public:
: xavix_i2c_state(mconfig, type, tag)
{ }
void xavix_i2c_24lc04_tam(machine_config &config);
private:
virtual void write_io1(uint8_t data, uint8_t direction) override;
private:
DECLARE_READ8_MEMBER(tam_anport0_r) { return m_mouse0x->read()^0x7f; }
DECLARE_READ8_MEMBER(tam_anport1_r) { return m_mouse0y->read()^0x7f; }
DECLARE_READ8_MEMBER(tam_anport2_r) { return m_mouse1x->read()^0x7f; }
DECLARE_READ8_MEMBER(tam_anport3_r) { return m_mouse1y->read()^0x7f; }
};
@ -918,7 +951,8 @@ class xavix_popira2_cart_state : public xavix_cart_state
{
public:
xavix_popira2_cart_state(const machine_config &mconfig, device_type type, const char *tag)
: xavix_cart_state(mconfig,type,tag)
: xavix_cart_state(mconfig,type,tag),
m_p2(*this, "P2")
{ }
void xavix_cart_popira2(machine_config &config);
@ -931,6 +965,8 @@ protected:
private:
DECLARE_READ8_MEMBER(popira2_adc0_r);
DECLARE_READ8_MEMBER(popira2_adc1_r);
required_ioport m_p2;
};

View File

@ -245,70 +245,6 @@ WRITE8_MEMBER(xavix_state::ioevent_irqack_w)
update_irqs();
}
READ8_MEMBER(xavix_state::mouse_7b00_r)
{
if (m_mouse0x)
{
uint8_t retval = m_mouse0x->read();
return retval ^ 0x7f;
}
return 0x00;
}
READ8_MEMBER(xavix_state::mouse_7b01_r)
{
if (m_mouse0y)
{
uint8_t retval = m_mouse0y->read();
return retval ^ 0x7f;
}
return 0x00;
}
READ8_MEMBER(xavix_state::mouse_7b10_r)
{
if (m_mouse1x)
{
uint8_t retval = m_mouse1x->read();
return retval ^ 0x7f;
}
return 0x00;
}
READ8_MEMBER(xavix_state::mouse_7b11_r)
{
if (m_mouse1y)
{
uint8_t retval = m_mouse1y->read();
return retval ^ 0x7f;
}
return 0x00;
}
WRITE8_MEMBER(xavix_state::mouse_7b00_w)
{
LOG("%s: mouse_7b00_w %02x\n", machine().describe_context(), data);
}
WRITE8_MEMBER(xavix_state::mouse_7b01_w)
{
LOG("%s: mouse_7b01_w %02x\n", machine().describe_context(), data);
}
WRITE8_MEMBER(xavix_state::mouse_7b10_w)
{
LOG("%s: mouse_7b10_w %02x\n", machine().describe_context(), data);
}
WRITE8_MEMBER(xavix_state::mouse_7b11_w)
{
LOG("%s: mouse_7b11_w %02x\n", machine().describe_context(), data);
}
WRITE8_MEMBER(xavix_state::slotreg_7810_w)
@ -869,116 +805,6 @@ TIMER_CALLBACK_MEMBER(xavix_state::freq_timer_done)
//m_freq_timer->adjust(attotime::from_usec(50000));
}
// epo_guru uses this for ground movement in 3d stages (and other places)
READ8_MEMBER(xavix_state::barrel_r)
{
if (offset == 0)
{
// or upper bits of result?
logerror("%s: reading shift trigger?!\n", machine().describe_context());
return 0x00;
}
else
{
uint8_t retdata = m_barrel_params[1];
logerror("%s: reading shift results/data %02x\n", machine().describe_context(), retdata);
return retdata;
}
}
WRITE8_MEMBER(xavix_state::barrel_w)
{
m_barrel_params[offset] = data;
if (offset == 0)
{
int shift_data = m_barrel_params[1];
int shift_amount = data & 0x0f;
int shift_param = (data & 0xf0)>>4;
// this can't be right, shift amount would allow us to shift 16 places this way, this is an 8-bit register, uneless it can shift in and out of a private register?
if (shift_param & 0x8)
{
m_barrel_params[1] = shift_data >> shift_amount;
}
else
{
m_barrel_params[1] = shift_data << shift_amount;
}
// offset 0 = trigger
logerror("%s: shifting value %02x by %01x with params %01x\n", machine().describe_context(), shift_data, shift_amount, shift_param);
}
}
READ8_MEMBER(xavix_state::mult_r)
{
return m_multresults[offset];
}
WRITE8_MEMBER(xavix_state::mult_w)
{
// rad_madf writes here to set the base value which the multiplication result gets added to
m_multresults[offset] = data;
}
READ8_MEMBER(xavix_state::mult_param_r)
{
return m_multparams[offset];
}
WRITE8_MEMBER(xavix_state::mult_param_w)
{
COMBINE_DATA(&m_multparams[offset]);
// there are NOPs after one of the writes, so presumably the operation is write triggerd and not intstant
// see test code at 0184a4 in monster truck
// offset0 is control
// mm-- --Ss
// mm = mode, S = sign for param1, s = sign for param2
// modes 00 = multiply (regular?) 11 = add to previous 01 / 10 unknown (maybe subtract?)
if (offset == 2)
{
// assume 0 is upper bits, might be 'mode' instead, check
int signmode = (m_multparams[0] & 0x3f);
uint16_t result = 0;
// rad_madf uses this mode (add to previous result)
if ((m_multparams[0] & 0xc0) == 0xc0)
{
const int param1 = signmode & 0x2 ? (int8_t)m_multparams[1] : (uint8_t)m_multparams[1];
const int param2 = signmode & 0x1 ? (int8_t)m_multparams[2] : (uint8_t)m_multparams[2];
result = param1 * param2;
uint16_t oldresult = (m_multresults[1] << 8) | m_multresults[0];
result = oldresult + result;
}
else if ((m_multparams[0] & 0xc0) == 0x00)
{
const int param1 = signmode & 0x2 ? (int8_t)m_multparams[1] : (uint8_t)m_multparams[1];
const int param2 = signmode & 0x1 ? (int8_t)m_multparams[2] : (uint8_t)m_multparams[2];
result = param1 * param2;
}
else
{
popmessage("unknown multiplier mode %02x", m_multparams[0] & 0xc0);
}
m_multresults[1] = (result >> 8) & 0xff;
m_multresults[0] = result & 0xff;
}
}
READ8_MEMBER(xavix_state::irq_source_r)
{
@ -1051,8 +877,6 @@ void xavix_state::machine_start()
save_item(NAME(m_nmi_vector_hi_data));
save_item(NAME(m_irq_vector_lo_data));
save_item(NAME(m_irq_vector_hi_data));
save_item(NAME(m_multparams));
save_item(NAME(m_multresults));
save_item(NAME(m_spritefragment_dmaparam1));
save_item(NAME(m_spritefragment_dmaparam2));
save_item(NAME(m_tmap1_regs));
@ -1069,7 +893,6 @@ void xavix_state::machine_start()
save_item(NAME(m_sndtimer));
save_item(NAME(m_timer_baseval));
save_item(NAME(m_spritereg));
save_item(NAME(m_barrel_params));
save_item(NAME(m_sx_extended_extbus));
}
@ -1110,8 +933,6 @@ void xavix_state::machine_reset()
m_sndtimer[i] = 0x00;
}
std::fill(std::begin(m_multparams), std::end(m_multparams), 0x00);
std::fill(std::begin(m_multresults), std::end(m_multresults), 0x00);
std::fill(std::begin(m_spritefragment_dmaparam1), std::end(m_spritefragment_dmaparam1), 0x00);
std::fill(std::begin(m_tmap1_regs), std::end(m_tmap1_regs), 0x00);
std::fill(std::begin(m_tmap2_regs), std::end(m_tmap2_regs), 0x00);
@ -1146,8 +967,6 @@ void xavix_state::machine_reset()
m_extbusctrl[1] = 0x00;
m_extbusctrl[2] = 0x00;
m_barrel_params[0] = 0x00;
m_barrel_params[1] = 0x00;
// SuperXaviX

View File

@ -0,0 +1,81 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
// are these still part of the ADC? if so merge into xavix_adc.cpp
#include "emu.h"
#include "xavix_anport.h"
#define VERBOSE 0
#include "logmacro.h"
DEFINE_DEVICE_TYPE(XAVIX_ANPORT, xavix_anport_device, "xavix_anport", "XaviX Analog ports")
xavix_anport_device::xavix_anport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, XAVIX_ANPORT, tag, owner, clock)
, m_in0_cb(*this)
, m_in1_cb(*this)
, m_in2_cb(*this)
, m_in3_cb(*this)
{
}
void xavix_anport_device::device_start()
{
m_in0_cb.resolve_safe(0xff);
m_in1_cb.resolve_safe(0xff);
m_in2_cb.resolve_safe(0xff);
m_in3_cb.resolve_safe(0xff);
}
void xavix_anport_device::device_reset()
{
}
READ8_MEMBER(xavix_anport_device::mouse_7b00_r)
{
LOG("%s: mouse_7b00_r\n", machine().describe_context());
return m_in0_cb();
}
READ8_MEMBER(xavix_anport_device::mouse_7b01_r)
{
LOG("%s: mouse_7b01_r\n", machine().describe_context());
return m_in1_cb();
}
READ8_MEMBER(xavix_anport_device::mouse_7b10_r)
{
LOG("%s: mouse_7b10_r\n", machine().describe_context());
return m_in2_cb();
}
READ8_MEMBER(xavix_anport_device::mouse_7b11_r)
{
LOG("%s: mouse_7b11_r\n", machine().describe_context());
return m_in3_cb();
}
WRITE8_MEMBER(xavix_anport_device::mouse_7b00_w)
{
LOG("%s: mouse_7b00_w %02x\n", machine().describe_context(), data);
}
WRITE8_MEMBER(xavix_anport_device::mouse_7b01_w)
{
LOG("%s: mouse_7b01_w %02x\n", machine().describe_context(), data);
}
WRITE8_MEMBER(xavix_anport_device::mouse_7b10_w)
{
LOG("%s: mouse_7b10_w %02x\n", machine().describe_context(), data);
}
WRITE8_MEMBER(xavix_anport_device::mouse_7b11_w)
{
LOG("%s: mouse_7b11_w %02x\n", machine().describe_context(), data);
}

View File

@ -0,0 +1,41 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
#ifndef MAME_MACHINE_XAVIX_ANPORT_H
#define MAME_MACHINE_XAVIX_ANPORT_H
class xavix_anport_device : public device_t
{
public:
xavix_anport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
auto read_0_callback() { return m_in0_cb.bind(); }
auto read_1_callback() { return m_in1_cb.bind(); }
auto read_2_callback() { return m_in2_cb.bind(); }
auto read_3_callback() { return m_in3_cb.bind(); }
DECLARE_READ8_MEMBER(mouse_7b00_r);
DECLARE_READ8_MEMBER(mouse_7b01_r);
DECLARE_READ8_MEMBER(mouse_7b10_r);
DECLARE_READ8_MEMBER(mouse_7b11_r);
DECLARE_WRITE8_MEMBER(mouse_7b00_w);
DECLARE_WRITE8_MEMBER(mouse_7b01_w);
DECLARE_WRITE8_MEMBER(mouse_7b10_w);
DECLARE_WRITE8_MEMBER(mouse_7b11_w);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
private:
devcb_read8 m_in0_cb;
devcb_read8 m_in1_cb;
devcb_read8 m_in2_cb;
devcb_read8 m_in3_cb;
};
DECLARE_DEVICE_TYPE(XAVIX_ANPORT, xavix_anport_device)
#endif // MAME_MACHINE_XAVIX_ANPORT_H

View File

@ -0,0 +1,171 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
#include "emu.h"
#include "xavix_math.h"
#define VERBOSE 0
#include "logmacro.h"
DEFINE_DEVICE_TYPE(XAVIX_MATH, xavix_math_device, "xavix_math", "XaviX Math Unit")
xavix_math_device::xavix_math_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, XAVIX_MATH, tag, owner, clock)
{
}
void xavix_math_device::device_start()
{
save_item(NAME(m_barrel_params));
save_item(NAME(m_multparams));
save_item(NAME(m_multresults));
}
void xavix_math_device::device_reset()
{
m_barrel_params[0] = 0x00;
m_barrel_params[1] = 0x00;
std::fill(std::begin(m_multparams), std::end(m_multparams), 0x00);
std::fill(std::begin(m_multresults), std::end(m_multresults), 0x00);
}
// epo_guru uses this for ground movement in 3d stages (and other places)
READ8_MEMBER(xavix_math_device::barrel_r)
{
if (offset == 0)
{
// or upper bits of result?
LOG("%s: reading shift trigger?!\n", machine().describe_context());
return 0x00;
}
else
{
uint8_t retdata = m_barrel_params[1];
LOG("%s: reading shift results/data %02x\n", machine().describe_context(), retdata);
return retdata;
}
}
// epo_guru 3d stages still flicker a lot with this, but it seems unrelated to the calculations here, possibly a raster timing issue
// the pickup animations however don't seem to play, which indicates this could still be wrong.
WRITE8_MEMBER(xavix_math_device::barrel_w)
{
LOG("%s: barrel_w %02x\n", machine().describe_context(), data);
m_barrel_params[offset] = data;
// offset 0 = trigger
if (offset == 0)
{
int shift_data = m_barrel_params[1];
int shift_amount = data & 0x0f;
int shift_param = (data & 0xf0) >> 4;
if (shift_param == 0x00) // just a shift? (definitely right for 'hammer throw'
{
// used in epo_guru for 'hammer throw', 'pre-title screen', 'mini game select', '3d chase game (floor scroll, pickups, misc)', 'toilet roll mini game (when you make an error)'
if (shift_amount & 0x08)
{
m_barrel_params[1] = (shift_data >> (shift_amount & 0x7));
}
else
{
m_barrel_params[1] = (shift_data << (shift_amount & 0x7));
}
}
else if (shift_param == 0x8) // rotate? (should it rotate through a carry bit of some kind?)
{
// used in epo_guru for '3d chase game' (unsure of actual purpose in it)
switch (shift_amount)
{
case 0x0: m_barrel_params[1] = shift_data; break;
case 0x1: m_barrel_params[1] = (shift_data << 1) | ((shift_data >> 7) & 0x01); break;
case 0x2: m_barrel_params[1] = (shift_data << 2) | ((shift_data >> 6) & 0x03); break;
case 0x3: m_barrel_params[1] = (shift_data << 3) | ((shift_data >> 5) & 0x07); break;
case 0x4: m_barrel_params[1] = (shift_data << 4) | ((shift_data >> 4) & 0x0f); break;
case 0x5: m_barrel_params[1] = (shift_data << 5) | ((shift_data >> 3) & 0x1f); break;
case 0x6: m_barrel_params[1] = (shift_data << 6) | ((shift_data >> 2) & 0x2f); break;
case 0x7: m_barrel_params[1] = (shift_data << 7) | ((shift_data >> 1) & 0x3f); break;
case 0x8: m_barrel_params[1] = shift_data; break;
case 0x9: m_barrel_params[1] = (shift_data >> 1) | ((shift_data & 0x01) << 7); break;
case 0xa: m_barrel_params[1] = (shift_data >> 2) | ((shift_data & 0x03) << 6); break;
case 0xb: m_barrel_params[1] = (shift_data >> 3) | ((shift_data & 0x07) << 5); break;
case 0xc: m_barrel_params[1] = (shift_data >> 4) | ((shift_data & 0x0f) << 4); break;
case 0xd: m_barrel_params[1] = (shift_data >> 5) | ((shift_data & 0x1f) << 3); break;
case 0xe: m_barrel_params[1] = (shift_data >> 6) | ((shift_data & 0x2f) << 2); break;
case 0xf: m_barrel_params[1] = (shift_data >> 7) | ((shift_data & 0x3f) << 1); break;
}
}
}
}
READ8_MEMBER(xavix_math_device::mult_r)
{
return m_multresults[offset];
}
WRITE8_MEMBER(xavix_math_device::mult_w)
{
// rad_madf writes here to set the base value which the multiplication result gets added to
m_multresults[offset] = data;
}
READ8_MEMBER(xavix_math_device::mult_param_r)
{
return m_multparams[offset];
}
WRITE8_MEMBER(xavix_math_device::mult_param_w)
{
COMBINE_DATA(&m_multparams[offset]);
// there are NOPs after one of the writes, so presumably the operation is write triggerd and not intstant
// see test code at 0184a4 in monster truck
// offset0 is control
// mm-- --Ss
// mm = mode, S = sign for param1, s = sign for param2
// modes 00 = multiply (regular?) 11 = add to previous 01 / 10 unknown (maybe subtract?)
if (offset == 2)
{
// assume 0 is upper bits, might be 'mode' instead, check
int signmode = (m_multparams[0] & 0x3f);
uint16_t result = 0;
// rad_madf uses this mode (add to previous result)
if ((m_multparams[0] & 0xc0) == 0xc0)
{
const int param1 = signmode & 0x2 ? (int8_t)m_multparams[1] : (uint8_t)m_multparams[1];
const int param2 = signmode & 0x1 ? (int8_t)m_multparams[2] : (uint8_t)m_multparams[2];
result = param1 * param2;
uint16_t oldresult = (m_multresults[1] << 8) | m_multresults[0];
result = oldresult + result;
}
else if ((m_multparams[0] & 0xc0) == 0x00)
{
const int param1 = signmode & 0x2 ? (int8_t)m_multparams[1] : (uint8_t)m_multparams[1];
const int param2 = signmode & 0x1 ? (int8_t)m_multparams[2] : (uint8_t)m_multparams[2];
result = param1 * param2;
}
else
{
popmessage("unknown multiplier mode %02x", m_multparams[0] & 0xc0);
}
m_multresults[1] = (result >> 8) & 0xff;
m_multresults[0] = result & 0xff;
}
}

View File

@ -0,0 +1,34 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
#ifndef MAME_MACHINE_XAVIX_MATH_H
#define MAME_MACHINE_XAVIX_MATH_H
class xavix_math_device : public device_t
{
public:
xavix_math_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
DECLARE_READ8_MEMBER(mult_r);
DECLARE_WRITE8_MEMBER(mult_w);
DECLARE_READ8_MEMBER(mult_param_r);
DECLARE_WRITE8_MEMBER(mult_param_w);
DECLARE_READ8_MEMBER(barrel_r);
DECLARE_WRITE8_MEMBER(barrel_w);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
private:
uint8_t m_barrel_params[2];
uint8_t m_multparams[3];
uint8_t m_multresults[2];
};
DECLARE_DEVICE_TYPE(XAVIX_MATH, xavix_math_device)
#endif // MAME_MACHINE_XAVIX_MATH_H