diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mame/drivers/xavix.cpp | 34 | ||||
-rw-r--r-- | src/mame/includes/xavix.h | 32 | ||||
-rw-r--r-- | src/mame/machine/xavix.cpp | 100 | ||||
-rw-r--r-- | src/mame/machine/xavix_mtrk_wheel.cpp | 91 | ||||
-rw-r--r-- | src/mame/machine/xavix_mtrk_wheel.h | 40 |
5 files changed, 285 insertions, 12 deletions
diff --git a/src/mame/drivers/xavix.cpp b/src/mame/drivers/xavix.cpp index 40e4cea5d18..6dc9e52df28 100644 --- a/src/mame/drivers/xavix.cpp +++ b/src/mame/drivers/xavix.cpp @@ -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) diff --git a/src/mame/includes/xavix.h b/src/mame/includes/xavix.h index 6f3a08152ff..e1bda42a84f 100644 --- a/src/mame/includes/xavix.h +++ b/src/mame/includes/xavix.h @@ -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: diff --git a/src/mame/machine/xavix.cpp b/src/mame/machine/xavix.cpp index 4704fd2ca5f..965ef554c59 100644 --- a/src/mame/machine/xavix.cpp +++ b/src/mame/machine/xavix.cpp @@ -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: 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: xavix_7a80_w %02x\n", machine().describe_context(), data); + 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; diff --git a/src/mame/machine/xavix_mtrk_wheel.cpp b/src/mame/machine/xavix_mtrk_wheel.cpp new file mode 100644 index 00000000000..5b4793d5e76 --- /dev/null +++ b/src/mame/machine/xavix_mtrk_wheel.cpp @@ -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; +} diff --git a/src/mame/machine/xavix_mtrk_wheel.h b/src/mame/machine/xavix_mtrk_wheel.h new file mode 100644 index 00000000000..593fdf4808d --- /dev/null +++ b/src/mame/machine/xavix_mtrk_wheel.h @@ -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 |