XaviX - preliminary wheel input for rad_mtrk (#4232)

* groundwork for monster truck wheel (nw)

* more groundwork (nw)

* more prep (nw)

* more prep (nw)

* (nw)

* preliminary wheel input for rad_mtrk
This commit is contained in:
David Haywood 2018-11-03 04:08:45 +00:00 committed by R. Belmont
parent 21f836ccf8
commit 9eba8c36fa
6 changed files with 287 additions and 12 deletions

View File

@ -3445,6 +3445,8 @@ files {
MAME_DIR .. "src/mame/machine/xavix.cpp",
MAME_DIR .. "src/mame/audio/xavix.cpp",
MAME_DIR .. "src/mame/includes/xavix.h",
MAME_DIR .. "src/mame/machine/xavix_mtrk_wheel.cpp",
MAME_DIR .. "src/mame/machine/xavix_mtrk_wheel.h",
}
createMESSProjects(_target, _subtarget, "ultimachine")

View File

@ -400,8 +400,9 @@ void xavix_state::xavix_lowbus_map(address_map &map)
map(0x7a02, 0x7a02).rw(FUNC(xavix_state::io0_direction_r), FUNC(xavix_state::io0_direction_w));
map(0x7a03, 0x7a03).rw(FUNC(xavix_state::io1_direction_r), FUNC(xavix_state::io1_direction_w));
// Interrupt control registers
map(0x7a80, 0x7a80).w(FUNC(xavix_state::xavix_7a80_w)); // still IO? ADC related?
// IO Event Interrupt control
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).w(FUNC(xavix_state::adc_7b00_w)); // rad_snow (not often, why?)
@ -414,7 +415,7 @@ void xavix_state::xavix_lowbus_map(address_map &map)
map(0x7b81, 0x7b81).rw(FUNC(xavix_state::adc_7b81_r), FUNC(xavix_state::adc_7b81_w)); // written (often, m_trck, analog related?)
// Sleep control
//map(7b82, 7b83)
//map(0x7b82, 0x7b83)
// Timer control
map(0x7c00, 0x7c00).rw(FUNC(xavix_state::timer_status_r), FUNC(xavix_state::timer_control_w));
@ -529,6 +530,12 @@ INPUT_PORTS_END
*/
CUSTOM_INPUT_MEMBER( xavix_mtrk_state::mtrk_wheel_r )
{
return m_wheel->read_direction();
}
static INPUT_PORTS_START( rad_mtrk )
PORT_INCLUDE(xavix)
@ -538,6 +545,8 @@ static INPUT_PORTS_START( rad_mtrk )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Throttle Low")
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Reverse / Back")
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(DEVICE_SELF, xavix_mtrk_state,mtrk_wheel_r, (void *)0)
PORT_MODIFY("IN1")
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Horn")
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_POWER_OFF ) PORT_NAME("Power Switch") // pressing this will turn the game off.
@ -869,6 +878,21 @@ MACHINE_CONFIG_START(xavix_state::xavix2000_i2c_24c02)
MACHINE_CONFIG_END
MACHINE_CONFIG_START(xavix_mtrk_state::xavix_mtrk)
xavix(config);
XAVIX_MTRK_WHEEL(config, m_wheel, 0);
m_wheel->event_out_cb().set(FUNC(xavix_state::ioevent_trg08));
MACHINE_CONFIG_END
MACHINE_CONFIG_START(xavix_mtrk_state::xavix_mtrkp)
xavix_mtrk(config);
MCFG_SCREEN_MODIFY("screen")
MCFG_SCREEN_REFRESH_RATE(50)
MACHINE_CONFIG_END
DEVICE_IMAGE_LOAD_MEMBER( xavix_ekara_state, ekara_cart )
{
@ -1043,8 +1067,8 @@ CONS( 2006, namcons2, 0, 0, xavix_i2c_24lc04, namcons2, xavix_state,
CONS( 2000, rad_ping, 0, 0, xavix, rad_ping, xavix_state, init_xavix, "Radica / SSD Company LTD / Simmer Technology", "Play TV Ping Pong", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND ) // "Simmer Technology" is also known as "Hummer Technology Co., Ltd"
CONS( 2003, rad_mtrk, 0, 0, xavix, rad_mtrk, xavix_state, init_xavix, "Radica / SSD Company LTD", "Play TV Monster Truck (NTSC)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND )
CONS( 2003, rad_mtrkp, rad_mtrk, 0, xavixp, rad_mtrkp,xavix_state, init_xavix, "Radica / SSD Company LTD", "ConnecTV Monster Truck (PAL)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND )
CONS( 2003, rad_mtrk, 0, 0, xavix_mtrk, rad_mtrk, xavix_mtrk_state, init_xavix, "Radica / SSD Company LTD", "Play TV Monster Truck (NTSC)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND )
CONS( 2003, rad_mtrkp, rad_mtrk, 0, xavix_mtrkp, rad_mtrkp,xavix_mtrk_state, init_xavix, "Radica / SSD Company LTD", "ConnecTV Monster Truck (PAL)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND )
CONS( 200?, rad_box, 0, 0, xavix, rad_box, xavix_state, init_xavix, "Radica / SSD Company LTD", "Play TV Boxin' (NTSC)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND)
CONS( 200?, rad_boxp, rad_box, 0, xavixp, rad_boxp, xavix_state, init_xavix, "Radica / SSD Company LTD", "ConnecTV Boxin' (PAL)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND)

View File

@ -14,6 +14,7 @@
#include "bus/generic/slot.h"
#include "bus/generic/carts.h"
#include "machine/xavix_mtrk_wheel.h"
class xavix_state : public driver_device
{
@ -61,6 +62,11 @@ public:
DECLARE_CUSTOM_INPUT_MEMBER(rad_rh_in1_08_r);
DECLARE_WRITE_LINE_MEMBER(ioevent_trg01);
DECLARE_WRITE_LINE_MEMBER(ioevent_trg02);
DECLARE_WRITE_LINE_MEMBER(ioevent_trg04);
DECLARE_WRITE_LINE_MEMBER(ioevent_trg08);
private:
// screen updates
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
@ -94,7 +100,14 @@ void superxavix_lowbus_map(address_map &map);
DECLARE_WRITE8_MEMBER(extintrf_7901_w);
DECLARE_WRITE8_MEMBER(extintrf_7902_w);
DECLARE_WRITE8_MEMBER(xavix_7a80_w);
DECLARE_READ8_MEMBER(ioevent_enable_r);
DECLARE_WRITE8_MEMBER(ioevent_enable_w);
DECLARE_READ8_MEMBER(ioevent_irqstate_r);
DECLARE_WRITE8_MEMBER(ioevent_irqack_w);
uint8_t m_ioevent_enable;
uint8_t m_ioevent_active;
void process_ioevent(uint8_t bits);
DECLARE_WRITE8_MEMBER(adc_7b00_w);
DECLARE_READ8_MEMBER(adc_7b80_r);
DECLARE_WRITE8_MEMBER(adc_7b80_w);
@ -316,6 +329,23 @@ void superxavix_lowbus_map(address_map &map);
optional_device<i2cmem_device> m_i2cmem;
};
class xavix_mtrk_state : public xavix_state
{
public:
xavix_mtrk_state(const machine_config &mconfig, device_type type, const char *tag)
: xavix_state(mconfig, type, tag),
m_wheel(*this, "wheel")
{ }
void xavix_mtrk(machine_config &config);
void xavix_mtrkp(machine_config &config);
CUSTOM_INPUT_MEMBER( mtrk_wheel_r );
protected:
required_device<xavix_mtrk_wheel_device> m_wheel;
};
class xavix_ekara_state : public xavix_state
{
public:

View File

@ -129,11 +129,95 @@ WRITE8_MEMBER(xavix_state::extintrf_7902_w)
LOG("%s: extintrf_7902_w %02x\n", machine().describe_context(), data);
}
WRITE8_MEMBER(xavix_state::xavix_7a80_w)
READ8_MEMBER(xavix_state::ioevent_enable_r)
{
LOG("%s: xavix_7a80_w %02x\n", machine().describe_context(), data);
LOG("%s: ioevent_enable_r\n", machine().describe_context());
return m_ioevent_enable;
}
WRITE8_MEMBER(xavix_state::ioevent_enable_w)
{
LOG("%s: ioevent_enable_w %02x\n", machine().describe_context(), data);
m_ioevent_enable = data;
}
void xavix_state::process_ioevent(uint8_t bits)
{
if (m_ioevent_enable & bits)
{
m_ioevent_active |= bits;
if (m_ioevent_active & 0x0f)
{
m_irqsource |= 0x08;
}
update_irqs();
}
}
WRITE_LINE_MEMBER(xavix_state::ioevent_trg01)
{
process_ioevent(0x01);
}
WRITE_LINE_MEMBER(xavix_state::ioevent_trg02)
{
process_ioevent(0x02);
}
WRITE_LINE_MEMBER(xavix_state::ioevent_trg04)
{
process_ioevent(0x04);
}
WRITE_LINE_MEMBER(xavix_state::ioevent_trg08)
{
process_ioevent(0x08);
}
READ8_MEMBER(xavix_state::ioevent_irqstate_r)
{
LOG("%s: ioevent_irqstate_r\n", machine().describe_context());
return m_ioevent_active;
}
WRITE8_MEMBER(xavix_state::ioevent_irqack_w)
{
LOG("%s: ioevent_irqack_w %02x\n", machine().describe_context(), data);
if (data & 0x01)
{
m_ioevent_active &= ~0x01;
}
if (data & 0x02)
{
m_ioevent_active &= ~0x02;
}
if (data & 0x04)
{
m_ioevent_active &= ~0x04;
}
if (data & 0x08)
{
m_ioevent_active &= ~0x08;
}
if (!(m_ioevent_active & 0x0f))
{
m_irqsource &= ~0x08;
}
update_irqs();
}
WRITE8_MEMBER(xavix_state::adc_7b00_w)
{
LOG("%s: adc_7b00_w %02x\n", machine().describe_context(), data);
@ -564,15 +648,16 @@ READ8_MEMBER(xavix_state::irq_source_r)
{
/* the 2nd IRQ routine (regular IRQ) reads here before deciding what to do
the following bits have been seen to be checked (active low?)
the following bits have been seen to be checked (active high)
monster truck does most extensive checking
0x80 - Sound Irq
0x40 - Picture / Arena Irq?
0x40 - Picture / Arena Irq? (including raster interrupt)
0x20 - DMA Irq (most routines check this as first priority, and ignore other requests if it is set?)
0x10 - Timer / Counter IRQ
0x08 - IO Irq (ADC? - used for analog control on Monster Truck) (uses 7a80 top bit to determine direction, and 7a81 0x08 as an output, presumably to clock)
0x04 - ADC IRQ - loads/stores 7b81
0x08 - IO Event Irq (uses 7a00 top bit to determine direction, enabled with 0x08 on 7a80, IRQ acked / cleared with 0x08 written to 7a81, 4 possible sources with different bits in 7a80 / 7a81 ? )
(this is the type of interrupt where the irq frequency adds a counter which determines analog value)
0x04 - ADC Conversion IRQ - loads/stores 7b81 (to ack interrupt)
*/
LOG("%s: irq_source_r\n", machine().describe_context());
@ -651,6 +736,9 @@ void xavix_state::machine_reset()
m_irqsource = 0x00;
m_timer_control = 0x00;
m_ioevent_enable = 0x00;
m_ioevent_active = 0x00;
}
typedef device_delegate<uint8_t(int which, int half)> xavix_interrupt_vector_delegate;

View File

@ -0,0 +1,91 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
#include "emu.h"
#include "machine/xavix_mtrk_wheel.h"
DEFINE_DEVICE_TYPE(XAVIX_MTRK_WHEEL, xavix_mtrk_wheel_device, "xavix_mtrk_wheel", "XaviX / Radica Monster Truck Steering Wheel")
xavix_mtrk_wheel_device::xavix_mtrk_wheel_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, XAVIX_MTRK_WHEEL, tag, owner, clock),
m_event_out_cb(*this),
m_in(*this, "WHEEL")
{
}
TIMER_CALLBACK_MEMBER(xavix_mtrk_wheel_device::event_timer)
{
m_event_out_cb(1);
m_is_running = 0;
check_wheel();
}
void xavix_mtrk_wheel_device::check_wheel()
{
uint8_t wheelval = m_in->read();
if (wheelval == 0x80)
{
m_event_timer->adjust(attotime::never, 0);
m_direction = 0;
m_is_running = 0;
}
else if (wheelval > 0x80)
{
wheelval = wheelval - 0x80;
m_direction = 1;
// TODO: set frequency based on value
m_event_timer->adjust(attotime::from_hz(20), 0);
m_is_running = 1;
}
else
{
wheelval = 0x7f - wheelval;
m_direction = 0;
// TODO: set frequency based on value
m_event_timer->adjust(attotime::from_hz(20), 0);
m_is_running = 1;
}
}
INPUT_CHANGED_MEMBER( xavix_mtrk_wheel_device::changed )
{
// this could happen while the timer is still active, which could end up cancelling it in flight
// should probably calculate adjustment based on current expiry?
// instead I'm just making sure the timer isn't running right now
//printf("wheel changed to %02x\n", m_in->read());
if (!m_is_running)
{
check_wheel();
}
}
static INPUT_PORTS_START( wheel )
PORT_START("WHEEL")
PORT_BIT( 0xff, 0x80, IPT_PADDLE ) PORT_MINMAX(0x20,0xe0) PORT_SENSITIVITY(100) PORT_KEYDELTA(4) PORT_CENTERDELTA(20) PORT_CHANGED_MEMBER(DEVICE_SELF, xavix_mtrk_wheel_device, changed, nullptr)
INPUT_PORTS_END
ioport_constructor xavix_mtrk_wheel_device::device_input_ports() const
{
return INPUT_PORTS_NAME(wheel);
}
void xavix_mtrk_wheel_device::device_start()
{
m_event_out_cb.resolve_safe();
m_event_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(xavix_mtrk_wheel_device::event_timer), this));
}
void xavix_mtrk_wheel_device::device_reset()
{
m_direction = 0;
m_event_timer->adjust(attotime::never, 0);
m_is_running = 0;
}
int xavix_mtrk_wheel_device::read_direction()
{
return m_direction;
}

View File

@ -0,0 +1,40 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
#ifndef MAME_MACHINE_XAVIX_MTRK_WHEEL_H
#define MAME_MACHINE_XAVIX_MTRK_WHEEL_H
#pragma once
#include "machine/timer.h"
DECLARE_DEVICE_TYPE(XAVIX_MTRK_WHEEL, xavix_mtrk_wheel_device)
class xavix_mtrk_wheel_device : public device_t
{
public:
// construction/destruction
xavix_mtrk_wheel_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
auto event_out_cb() { return m_event_out_cb.bind(); }
int read_direction();
DECLARE_INPUT_CHANGED_MEMBER( changed );
protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual ioport_constructor device_input_ports() const override;
private:
devcb_write_line m_event_out_cb;
required_ioport m_in;
TIMER_CALLBACK_MEMBER(event_timer);
emu_timer *m_event_timer;
int m_direction;
void check_wheel();
int m_is_running;
};
#endif // MAME_MACHINE_XAVIX_MTRK_WHEEL_H