summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author David Haywood <mamehaze@gmail.com>2018-11-03 22:42:53 +0000
committer ajrhacker <ajrhacker@users.noreply.github.com>2018-11-03 18:42:53 -0400
commit84e9644c4fe34e20c854a587ea584adc5f04102b (patch)
tree9e7dd8a8cbbc0389b871b4dd056df73267412f39
parentc8572d9508ea5f6d13c001c20f08e1ded66a11a1 (diff)
XaviX - fix opcode access in upper banks (needed for rad_fb) + basic input mapping to push things along (#4237)
* some cleanups, opcode access fix (nw) * start looking at the football * rad_fb inputs (nw) * slight video refactor (nw) * (nw)
-rw-r--r--scripts/target/mame/mess.lua2
-rw-r--r--src/mame/drivers/xavix.cpp108
-rw-r--r--src/mame/includes/xavix.h34
-rw-r--r--src/mame/machine/xavix.cpp16
-rw-r--r--src/mame/machine/xavix_madfb_ball.cpp87
-rw-r--r--src/mame/machine/xavix_madfb_ball.h39
-rw-r--r--src/mame/video/xavix.cpp115
7 files changed, 276 insertions, 125 deletions
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index 90ee5a7ed3e..584f6ceae15 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -3447,6 +3447,8 @@ files {
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",
+ MAME_DIR .. "src/mame/machine/xavix_madfb_ball.cpp",
+ MAME_DIR .. "src/mame/machine/xavix_madfb_ball.h",
}
createMESSProjects(_target, _subtarget, "ultimachine")
diff --git a/src/mame/drivers/xavix.cpp b/src/mame/drivers/xavix.cpp
index 6dc9e52df28..4f059ba5ca9 100644
--- a/src/mame/drivers/xavix.cpp
+++ b/src/mame/drivers/xavix.cpp
@@ -209,30 +209,6 @@
// NTSC clock for regular XaviX?
#define MAIN_CLOCK XTAL(21'477'272)
-READ8_MEMBER(xavix_state::main_r)
-{
- if (offset & 0x8000)
- {
- return m_rgn[(offset) & (m_rgnlen - 1)];
- }
- else
- {
- return m_lowbus->read8(space, offset & 0x7fff);
- }
-}
-
-WRITE8_MEMBER(xavix_state::main_w)
-{
- if (offset & 0x8000)
- {
- logerror("write to ROM area?\n");
- }
- else
- {
- m_lowbus->write8(space, offset & 0x7fff, data);
- }
-}
-
/* rad_madf has callf #$8f3f21 in various places, and expects to jump to code in ROM, it is unclear how things map in this case, as presumably
the CPU 0 page memory and stack are still at 0 but ROM must be in the 3xxx range (game hasn't got far enough to call this yet to help either)
@@ -259,7 +235,8 @@ WRITE8_MEMBER(xavix_state::main_w)
*/
-READ8_MEMBER(xavix_state::main2_r)
+
+READ8_MEMBER(xavix_state::opcodes_000000_r)
{
if (offset & 0x8000)
{
@@ -267,35 +244,21 @@ READ8_MEMBER(xavix_state::main2_r)
}
else
{
- if ((offset & 0xffff) >= 0x200)
- {
- return m_rgn[(offset) & (m_rgnlen - 1)];
- }
- else
- return m_lowbus->read8(space, offset & 0x7fff);
+ return m_lowbus->read8(space, offset & 0x7fff);
}
}
-WRITE8_MEMBER(xavix_state::main2_w)
+READ8_MEMBER(xavix_state::opcodes_800000_r)
{
- if (offset & 0x8000)
- {
- logerror("write to ROM area?\n");
- }
- else
- {
- if ((offset & 0xffff) >= 0x200)
- logerror("write to ROM area?\n");
- else
- m_lowbus->write8(space, offset & 0x7fff, data);
- }
+ // rad_fb, rad_madf confirm that for >0x800000 the CPU only sees ROM when executing opcodes
+ return m_rgn[(offset) & (m_rgnlen - 1)];
}
// this is only used for opcode / oprand reads, data memory addressing is handled in core, doing the opcode / oprand addressing in core causes disassembly issues when running from lowbus space (ram, interrupts on most games)
void xavix_state::xavix_map(address_map &map)
{
- map(0x000000, 0x7fffff).rw(FUNC(xavix_state::main_r), FUNC(xavix_state::main_w));
- map(0x800000, 0xffffff).rw(FUNC(xavix_state::main2_r), FUNC(xavix_state::main2_w));
+ map(0x000000, 0x7fffff).r(FUNC(xavix_state::opcodes_000000_r));
+ map(0x800000, 0xffffff).r(FUNC(xavix_state::opcodes_800000_r));
}
// this is used by data reads / writes after some processing in the core to decide if data reads can see lowbus, zeropage, stack, bank registers etc. and only falls through to here on a true external bus access
@@ -316,8 +279,8 @@ void xavix_state::xavix_lowbus_map(address_map &map)
map(0x6000, 0x67ff).ram().share("fragment_sprite");
// Palette RAM
- map(0x6800, 0x68ff).ram().share("palram_sh");
- map(0x6900, 0x69ff).ram().share("palram_l");
+ map(0x6800, 0x68ff).ram().w(FUNC(xavix_state::palram_sh_w)).share("palram_sh");
+ map(0x6900, 0x69ff).ram().w(FUNC(xavix_state::palram_l_w)).share("palram_l");
// Segment RAM
map(0x6a00, 0x6a1f).ram().share("segment_regs"); // test mode, pass flag 0x20
@@ -342,8 +305,8 @@ void xavix_state::xavix_lowbus_map(address_map &map)
map(0x6fea, 0x6fea).rw(FUNC(xavix_state::arena_control_r), FUNC(xavix_state::arena_control_w));
// Colour Mixing / Enabling Registers
- map(0x6ff0, 0x6ff0).ram().share("colmix_sh"); // a single colour (for effects?) not bgpen
- map(0x6ff1, 0x6ff1).ram().share("colmix_l");
+ map(0x6ff0, 0x6ff0).ram().w(FUNC(xavix_state::colmix_sh_w)).share("colmix_sh"); // effect colour?
+ map(0x6ff1, 0x6ff1).ram().w(FUNC(xavix_state::colmix_l_w)).share("colmix_l");
map(0x6ff2, 0x6ff2).ram().w(FUNC(xavix_state::colmix_6ff2_w)).share("colmix_ctrl"); // set to 07 after clearing above things in interrupt 0
// Display Control Register / Status Flags
@@ -421,6 +384,7 @@ void xavix_state::xavix_lowbus_map(address_map &map)
map(0x7c00, 0x7c00).rw(FUNC(xavix_state::timer_status_r), FUNC(xavix_state::timer_control_w));
map(0x7c01, 0x7c01).rw(FUNC(xavix_state::timer_baseval_r), FUNC(xavix_state::timer_baseval_w)); // r/w tested
map(0x7c02, 0x7c02).rw(FUNC(xavix_state::timer_freq_r), FUNC(xavix_state::timer_freq_w));
+ map(0x7c03, 0x7c03).r(FUNC(xavix_state::timer_curval_r));
// Barrel Shifter registers
// map(0x7ff0, 0x7ff1)
@@ -444,8 +408,8 @@ void xavix_state::superxavix_lowbus_map(address_map &map)
xavix_lowbus_map(map);
// bitmap layer palette
- map(0x6c00, 0x6cff).ram().share("bmp_palram_sh");
- map(0x6d00, 0x6dff).ram().share("bmp_palram_l");
+ map(0x6c00, 0x6cff).ram().w(FUNC(xavix_state::bmp_palram_sh_w)).share("bmp_palram_sh");
+ map(0x6d00, 0x6dff).ram().w(FUNC(xavix_state::bmp_palram_l_w)).share("bmp_palram_l");
map(0x6fb0, 0x6fc7).ram().share("bmp_base");
}
@@ -720,6 +684,21 @@ static INPUT_PORTS_START( ttv_mx )
INPUT_PORTS_END
+static INPUT_PORTS_START( rad_fb )
+ PORT_INCLUDE(xavix)
+
+ PORT_MODIFY("IN0")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(1)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2)
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
+
+ PORT_MODIFY("IN1")
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_POWER_OFF ) PORT_NAME("Power Switch") // pressing this will turn the game off.
+INPUT_PORTS_END
+
CUSTOM_INPUT_MEMBER( xavix_state::rad_rh_in1_08_r )
{
// it's unclear what rad_rh wants here
@@ -819,7 +798,7 @@ MACHINE_CONFIG_START(xavix_state::xavix)
MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_xavix)
- MCFG_PALETTE_ADD("palette", 256 + 1)
+ MCFG_PALETTE_ADD("palette", 256)
/* sound hardware */
SPEAKER(config, "mono").front_center();
@@ -861,7 +840,7 @@ MACHINE_CONFIG_START(xavix_state::xavix2000)
MCFG_XAVIX_VECTOR_CALLBACK(xavix_state, get_vectors)
MCFG_DEVICE_REMOVE("palette")
- MCFG_PALETTE_ADD("palette", 512+1)
+ MCFG_PALETTE_ADD("palette", 512)
MACHINE_CONFIG_END
@@ -893,6 +872,13 @@ MACHINE_CONFIG_START(xavix_mtrk_state::xavix_mtrkp)
MCFG_SCREEN_REFRESH_RATE(50)
MACHINE_CONFIG_END
+MACHINE_CONFIG_START(xavix_madfb_state::xavix_madfb)
+ xavix(config);
+
+ XAVIX_MADFB_BALL(config, m_ball, 0);
+ m_ball->event_out_cb().set(FUNC(xavix_state::ioevent_trg01));
+
+MACHINE_CONFIG_END
DEVICE_IMAGE_LOAD_MEMBER( xavix_ekara_state, ekara_cart )
{
@@ -907,7 +893,6 @@ DEVICE_IMAGE_LOAD_MEMBER( xavix_ekara_state, ekara_cart )
return image_init_result::PASS;
}
-
MACHINE_CONFIG_START(xavix_ekara_state::xavix_ekara)
xavix(config);
@@ -921,10 +906,6 @@ MACHINE_CONFIG_START(xavix_ekara_state::xavix_ekara)
MACHINE_CONFIG_END
-
-
-
-
void xavix_state::init_xavix()
{
m_rgnlen = memregion("bios")->bytes();
@@ -1055,7 +1036,7 @@ ROM_START( has_wamg )
ROM_LOAD( "minigolf.bin", 0x000000, 0x400000, CRC(35cee2ad) SHA1(c7344e8ba336bc329638485ea571cd731ebf7649) )
ROM_END
-/* Standalone TV Games */
+/* XaviX hardware titles */
CONS( 2006, taitons1, 0, 0, xavix_i2c_24lc04, namcons2, xavix_state, init_xavix, "Bandai / SSD Company LTD / Taito", "Let's! TV Play Classic - Taito Nostalgia 1", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND )
@@ -1085,9 +1066,9 @@ CONS( 2001, rad_bassp, rad_bass, 0, xavixp, rad_bassp,xavix_state, init_xavix
CONS( 2001, rad_snow, 0, 0, xavix, rad_snow, xavix_state, init_xavix, "Radica / SSD Company LTD", "Play TV Snowboarder (Blue) (NTSC)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND)
CONS( 2001, rad_snowp, rad_snow, 0, xavixp, rad_snowp,xavix_state, init_xavix, "Radica / SSD Company LTD", "ConnecTV Snowboarder (Blue) (PAL)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND)
-CONS( 2003, rad_madf, 0, 0, xavix, xavix, xavix_state, init_xavix, "Radica / SSD Company LTD", "EA Sports Madden Football (NTSC)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND) // no Play TV branding, USA only release?
+CONS( 2003, rad_madf, 0, 0, xavix_madfb, rad_fb, xavix_madfb_state, init_xavix, "Radica / SSD Company LTD", "EA Sports Madden Football (NTSC)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND) // no Play TV branding, USA only release?
-CONS( 200?, rad_fb, 0, 0, xavix, xavix, xavix_state, init_xavix, "Radica / SSD Company LTD", "Play TV Football (NTSC)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND) // USA only release? doesn't change logo for PAL
+CONS( 200?, rad_fb, 0, 0, xavix_madfb, rad_fb, xavix_madfb_state, init_xavix, "Radica / SSD Company LTD", "Play TV Football (NTSC)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND) // USA only release? doesn't change logo for PAL.
CONS( 200?, rad_rh, 0, 0, xavix, rad_rh, xavix_state, init_xavix, "Radioa / Fisher-Price / SSD Company LTD", "Play TV Rescue Heroes", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND)
@@ -1097,6 +1078,8 @@ CONS( 200?, has_wamg, 0, 0, xavix, xavix, xavix_state, init_xavix
CONS( 200?, ekara, 0, 0, xavix_ekara, ekara, xavix_ekara_state, init_xavix, "Takara / Hasbro / SSD Company LTD", "e-kara (US?)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND|MACHINE_IS_BIOS_ROOT)
+/* SuperXaviX hardware titles */
+
/* The 'XaviXPORT' isn't a real console, more of a TV adapter, all the actual hardware (CPU including video hw, sound hw) is in the cartridges and controllers
and can vary between games, see notes at top of driver.
*/
@@ -1106,9 +1089,6 @@ ROM_START( xavtenni )
ROM_LOAD( "xavixtennis.bin", 0x000000, 0x800000, CRC(23a1d918) SHA1(2241c59e8ea8328013e55952ebf9060ea0a4675b) )
ROM_END
-/* Tiger games have extended opcodes too */
-
-
ROM_START( ttv_sw )
ROM_REGION( 0x800000, "bios", ROMREGION_ERASE00 )
ROM_LOAD( "jedi.bin", 0x000000, 0x800000, CRC(51cae5fd) SHA1(1ed8d556f31b4182259ca8c766d60c824d8d9744) )
diff --git a/src/mame/includes/xavix.h b/src/mame/includes/xavix.h
index e1bda42a84f..efdf05003c0 100644
--- a/src/mame/includes/xavix.h
+++ b/src/mame/includes/xavix.h
@@ -15,6 +15,7 @@
#include "bus/generic/carts.h"
#include "machine/xavix_mtrk_wheel.h"
+#include "machine/xavix_madfb_ball.h"
class xavix_state : public driver_device
{
@@ -86,12 +87,8 @@ void superxavix_lowbus_map(address_map &map);
virtual void video_start() override;
- DECLARE_READ8_MEMBER(main_r);
- DECLARE_WRITE8_MEMBER(main_w);
- DECLARE_READ8_MEMBER(main2_r);
- DECLARE_WRITE8_MEMBER(main2_w);
- DECLARE_READ8_MEMBER(main3_r);
- DECLARE_WRITE8_MEMBER(main3_w);
+ DECLARE_READ8_MEMBER(opcodes_000000_r);
+ DECLARE_READ8_MEMBER(opcodes_800000_r);
DECLARE_READ8_MEMBER(extbus_r) { return m_rgn[(offset) & (m_rgnlen - 1)]; }
DECLARE_WRITE8_MEMBER(extbus_w) { logerror("write to external bus %06x %02x\n", offset, data); }
@@ -201,11 +198,19 @@ void superxavix_lowbus_map(address_map &map);
DECLARE_WRITE8_MEMBER(timer_baseval_w);
DECLARE_READ8_MEMBER(timer_freq_r);
DECLARE_WRITE8_MEMBER(timer_freq_w);
+ DECLARE_READ8_MEMBER(timer_curval_r);
uint8_t m_timer_control;
uint8_t m_timer_freq;
TIMER_CALLBACK_MEMBER(freq_timer_done);
emu_timer *m_freq_timer;
+ DECLARE_WRITE8_MEMBER(palram_sh_w);
+ DECLARE_WRITE8_MEMBER(palram_l_w);
+ DECLARE_WRITE8_MEMBER(colmix_sh_w);
+ DECLARE_WRITE8_MEMBER(colmix_l_w);
+ DECLARE_WRITE8_MEMBER(bmp_palram_sh_w);
+ DECLARE_WRITE8_MEMBER(bmp_palram_l_w);
+
DECLARE_WRITE8_MEMBER(tmap1_regs_w);
DECLARE_WRITE8_MEMBER(tmap2_regs_w);
@@ -300,7 +305,7 @@ void superxavix_lowbus_map(address_map &map);
required_device<gfxdecode_device> m_gfxdecode;
- void handle_palette(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, uint8_t* ramsh, uint8_t* raml, int size, int basecol);
+ void update_pen(int pen, uint8_t shval, uint8_t lval);
double hue2rgb(double p, double q, double t);
void draw_tile_line(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int tile, int bpp, int xpos, int ypos, int drawheight, int drawwidth, int flipx, int flipy, int pal, int zval, int line);
void draw_tilemap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int which);
@@ -346,6 +351,21 @@ protected:
required_device<xavix_mtrk_wheel_device> m_wheel;
};
+class xavix_madfb_state : public xavix_state
+{
+public:
+ xavix_madfb_state(const machine_config &mconfig, device_type type, const char *tag)
+ : xavix_state(mconfig, type, tag),
+ m_ball(*this, "ball")
+ { }
+
+ void xavix_madfb(machine_config &config);
+
+protected:
+ required_device<xavix_madfb_ball_device> m_ball;
+};
+
+
class xavix_ekara_state : public xavix_state
{
public:
diff --git a/src/mame/machine/xavix.cpp b/src/mame/machine/xavix.cpp
index 965ef554c59..e39fa03df05 100644
--- a/src/mame/machine/xavix.cpp
+++ b/src/mame/machine/xavix.cpp
@@ -268,7 +268,15 @@ INTERRUPT_GEN_MEMBER(xavix_state::interrupt)
}
+WRITE8_MEMBER(xavix_state::colmix_sh_w)
+{
+ m_colmix_sh[offset] = data;
+}
+WRITE8_MEMBER(xavix_state::colmix_l_w)
+{
+ m_colmix_l[offset] = data;
+}
WRITE8_MEMBER(xavix_state::colmix_6ff2_w)
{
@@ -532,6 +540,14 @@ READ8_MEMBER(xavix_state::timer_freq_r)
return m_timer_freq;
}
+READ8_MEMBER(xavix_state::timer_curval_r)
+{
+ // TODO implement properly with timers etc. as rad_fb / rad_madfb rely on these values to calculate throw strength!
+ LOG("%s: timer_curval_r\n", machine().describe_context());
+ return machine().rand();
+}
+
+
WRITE8_MEMBER(xavix_state::timer_freq_w)
{
// 4-bit prescale
diff --git a/src/mame/machine/xavix_madfb_ball.cpp b/src/mame/machine/xavix_madfb_ball.cpp
new file mode 100644
index 00000000000..11c419dab51
--- /dev/null
+++ b/src/mame/machine/xavix_madfb_ball.cpp
@@ -0,0 +1,87 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood
+
+/*
+ Motion Football simulation for XaviX based games
+ EA Sports Madden Football
+ Play TV Football
+
+ seems to register a pulse when you move it, and another when it stops moving
+ game uses current timer register (without interrupt) to measure time between pulses
+ to get 'throw' value
+
+ need to verify with code and work out how best to handle this
+*/
+
+#include "emu.h"
+#include "machine/xavix_madfb_ball.h"
+
+DEFINE_DEVICE_TYPE(XAVIX_MADFB_BALL, xavix_madfb_ball_device, "xavix_madfb_ball", "XaviX / Radica Football Ball")
+
+xavix_madfb_ball_device::xavix_madfb_ball_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, XAVIX_MADFB_BALL, tag, owner, clock),
+ m_event_out_cb(*this),
+ m_in(*this, "BALL")
+{
+}
+
+TIMER_CALLBACK_MEMBER(xavix_madfb_ball_device::event_timer)
+{
+ m_event_out_cb(1);
+ m_is_running = 0;
+ check_ball();
+}
+
+void xavix_madfb_ball_device::check_ball()
+{
+ uint8_t ballval = m_in->read();
+
+ if (ballval == 0x00)
+ {
+ m_event_timer->adjust(attotime::never, 0);
+ m_is_running = 0;
+ }
+ else
+ {
+ // TODO: set frequency based on value
+ m_event_timer->adjust(attotime::from_hz(800), 0);
+ m_is_running = 1;
+ }
+}
+
+INPUT_CHANGED_MEMBER( xavix_madfb_ball_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("ball changed to %02x\n", m_in->read());
+ if (!m_is_running)
+ {
+ check_ball();
+ }
+}
+
+
+static INPUT_PORTS_START( ball )
+ PORT_START("BALL")
+ PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(100) PORT_KEYDELTA(20) PORT_CHANGED_MEMBER(DEVICE_SELF, xavix_madfb_ball_device, changed, nullptr)
+INPUT_PORTS_END
+
+
+ioport_constructor xavix_madfb_ball_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(ball);
+}
+
+
+void xavix_madfb_ball_device::device_start()
+{
+ m_event_out_cb.resolve_safe();
+ m_event_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(xavix_madfb_ball_device::event_timer), this));
+}
+
+void xavix_madfb_ball_device::device_reset()
+{
+ m_event_timer->adjust(attotime::never, 0);
+ m_is_running = 0;
+}
diff --git a/src/mame/machine/xavix_madfb_ball.h b/src/mame/machine/xavix_madfb_ball.h
new file mode 100644
index 00000000000..6ee5d266fb0
--- /dev/null
+++ b/src/mame/machine/xavix_madfb_ball.h
@@ -0,0 +1,39 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood
+
+#ifndef MAME_MACHINE_XAVIX_MADFB_BALL_H
+#define MAME_MACHINE_XAVIX_MADFB_BALL_H
+
+#pragma once
+
+#include "machine/timer.h"
+
+DECLARE_DEVICE_TYPE(XAVIX_MADFB_BALL, xavix_madfb_ball_device)
+
+
+class xavix_madfb_ball_device : public device_t
+{
+public:
+ // construction/destruction
+ xavix_madfb_ball_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;
+ void check_ball();
+ int m_is_running;
+};
+
+#endif // MAME_MACHINE_XAVIX_MADFB_BALL_H
diff --git a/src/mame/video/xavix.cpp b/src/mame/video/xavix.cpp
index 7730560db9f..cbc9e9f9daf 100644
--- a/src/mame/video/xavix.cpp
+++ b/src/mame/video/xavix.cpp
@@ -57,6 +57,31 @@ void xavix_state::video_start()
}
+WRITE8_MEMBER(xavix_state::palram_sh_w)
+{
+ m_palram_sh[offset] = data;
+ update_pen(offset, m_palram_sh[offset], m_palram_l[offset]);
+}
+
+WRITE8_MEMBER(xavix_state::palram_l_w)
+{
+ m_palram_l[offset] = data;
+ update_pen(offset, m_palram_sh[offset], m_palram_l[offset]);
+}
+
+WRITE8_MEMBER(xavix_state::bmp_palram_sh_w)
+{
+ m_bmp_palram_sh[offset] = data;
+ update_pen(offset+256, m_bmp_palram_sh[offset], m_bmp_palram_l[offset]);
+}
+
+WRITE8_MEMBER(xavix_state::bmp_palram_l_w)
+{
+ m_bmp_palram_l[offset] = data;
+ update_pen(offset+256, m_bmp_palram_sh[offset], m_bmp_palram_l[offset]);
+}
+
+
double xavix_state::hue2rgb(double p, double q, double t)
{
if (t < 0) t += 1;
@@ -67,62 +92,56 @@ double xavix_state::hue2rgb(double p, double q, double t)
return p;
}
-void xavix_state::handle_palette(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, uint8_t* ramsh, uint8_t* raml, int size, int basecol)
+void xavix_state::update_pen(int pen, uint8_t shval, uint8_t lval)
{
- // not verified
- int offs = 0;
- for (int index = 0; index < size; index++)
- {
- uint16_t dat;
- dat = ramsh[offs];
- dat |= raml[offs] << 8;
+ uint16_t dat;
+ dat = shval;
+ dat |= lval << 8;
- offs++;
+ int l_raw = (dat & 0x1f00) >> 8;
+ int s_raw = (dat & 0x00e0) >> 5;
+ int h_raw = (dat & 0x001f) >> 0;
- int l_raw = (dat & 0x1f00) >> 8;
- int s_raw = (dat & 0x00e0) >> 5;
- int h_raw = (dat & 0x001f) >> 0;
+ //if (h_raw > 24)
+ // LOG("hraw >24 (%02x)\n", h_raw);
- //if (h_raw > 24)
- // LOG("hraw >24 (%02x)\n", h_raw);
+ //if (l_raw > 24)
+ // LOG("lraw >24 (%02x)\n", l_raw);
- //if (l_raw > 24)
- // LOG("lraw >24 (%02x)\n", l_raw);
+ //if (s_raw > 7)
+ // LOG("s_raw >5 (%02x)\n", s_raw);
- //if (s_raw > 7)
- // LOG("s_raw >5 (%02x)\n", s_raw);
+ double l = (double)l_raw / 24.0f; // ekara and drgqst go up to 23 during fades, expect that to be brightest
+ l = l * (std::atan(1)*2); // does not appear to be a linear curve
+ l = std::sin(l);
- double l = (double)l_raw / 24.0f; // ekara and drgqst go up to 23 during fades, expect that to be brightest
- l = l * (std::atan(1)*2); // does not appear to be a linear curve
- l = std::sin(l);
+ double s = (double)s_raw / 7.0f;
+ s = s * (std::atan(1)*2); // does not appear to be a linear curve
+ s = std::sin(s);
- double s = (double)s_raw / 7.0f;
- s = s * (std::atan(1)*2); // does not appear to be a linear curve
- s = std::sin(s);
+ double h = (double)h_raw / 24.0f; // hue values 24-31 render as transparent
- double h = (double)h_raw / 24.0f; // hue values 24-31 render as transparent
+ double r, g, b;
- double r, g, b;
+ if (s == 0) {
+ r = g = b = l; // greyscale
+ }
+ else {
+ double q = l < 0.5f ? l * (1 + s) : l + s - l * s;
+ double p = 2 * l - q;
+ r = hue2rgb(p, q, h + 1 / 3.0f);
+ g = hue2rgb(p, q, h);
+ b = hue2rgb(p, q, h - 1 / 3.0f);
+ }
- if (s == 0) {
- r = g = b = l; // greyscale
- }
- else {
- double q = l < 0.5f ? l * (1 + s) : l + s - l * s;
- double p = 2 * l - q;
- r = hue2rgb(p, q, h + 1 / 3.0f);
- g = hue2rgb(p, q, h);
- b = hue2rgb(p, q, h - 1 / 3.0f);
- }
+ int r_real = r * 255.0f;
+ int g_real = g * 255.0f;
+ int b_real = b * 255.0f;
- int r_real = r * 255.0f;
- int g_real = g * 255.0f;
- int b_real = b * 255.0f;
+ m_palette->set_pen_color(pen, r_real, g_real, b_real);
+}
- m_palette->set_pen_color(basecol+index, r_real, g_real, b_real);
- }
-}
void xavix_state::draw_tilemap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int which)
{
@@ -671,18 +690,6 @@ void xavix_state::draw_tile_line(screen_device &screen, bitmap_ind16 &bitmap, co
uint32_t xavix_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
- handle_palette(screen, bitmap, cliprect, m_palram_sh, m_palram_l, 256, 0);
-
- if (m_bmp_palram_sh)
- {
- handle_palette(screen, bitmap, cliprect, m_bmp_palram_sh, m_bmp_palram_l, 256, 256);
- handle_palette(screen, bitmap, cliprect, m_colmix_sh, m_colmix_l, 1, 512);
- }
- else
- {
- handle_palette(screen, bitmap, cliprect, m_colmix_sh, m_colmix_l, 1, 256);
- }
-
// not sure what you end up with if you fall through all layers as transparent, so far no issues noticed
bitmap.fill(m_palette->black_pen(), cliprect);
m_zbuffer.fill(0, cliprect);