summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author David Haywood <hazemamewip@hotmail.com>2018-04-17 03:34:42 +0100
committer R. Belmont <rb6502@users.noreply.github.com>2018-04-16 22:34:42 -0400
commit261bcfa3cdc15e409ae34be1ba637f8319743353 (patch)
tree62c51414b7de4fb5a115a4ca3271db7cc516fd27
parent753934d6e5a4c73ddbe184632517e4a42cdeffd8 (diff)
XaviX - current checkpoint, tidying, reorganization etc. (+ general TV game work) (#3450)
* xavix - tidy ups, reorganization, current notes etc. * didn't mean to push a copy (nw) * shift some common code around for palette handling (nw) * lean less heavily on memory system (nw) * revert 'shift some common code around for palette handling (nw)' to be revisited later. * add missed include guards (nw) * new machines marked as NOT WORKING Skannerz TV [Sean RIddle, Peter Wilhelmsen] This will need the communication protocol with the barcode scanner unit reverse engeering (the scanner unit has it's own MCU that isn't dumped and for which we have no method of dumping) this also probably means it will need improvements to the general vii.cpp handling of interrupts and serial ports (which Cricket needs too)
-rw-r--r--scripts/target/mame/mess.lua26
-rw-r--r--src/devices/cpu/m6502/oxavix.lst24
-rw-r--r--src/devices/cpu/m6502/xavix.cpp110
-rw-r--r--src/devices/cpu/m6502/xavix.h13
-rw-r--r--src/mame/drivers/vii.cpp114
-rw-r--r--src/mame/drivers/xavix.cpp1576
-rw-r--r--src/mame/includes/xavix.h266
-rw-r--r--src/mame/machine/xavix.cpp637
-rw-r--r--src/mame/mame.lst1
-rw-r--r--src/mame/video/xavix.cpp730
10 files changed, 1965 insertions, 1532 deletions
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index ebf6ee13acd..48f9c605c5b 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -1130,6 +1130,7 @@ function linkProjects_mame_mess(_target, _subtarget)
"toshiba",
"trainer",
"trs",
+ "tvgames",
"ultimachine",
"ultratec",
"unicard",
@@ -3314,6 +3315,22 @@ files {
MAME_DIR .. "src/mame/drivers/vis.cpp",
}
+createMESSProjects(_target, _subtarget, "tvgames")
+files {
+ MAME_DIR .. "src/mame/drivers/rad_eu3a14.cpp",
+ MAME_DIR .. "src/mame/drivers/rad_eu3a05.cpp",
+ MAME_DIR .. "src/mame/audio/rad_eu3a05.cpp",
+ MAME_DIR .. "src/mame/audio/rad_eu3a05.h",
+ MAME_DIR .. "src/mame/machine/rad_eu3a05gpio.cpp",
+ MAME_DIR .. "src/mame/machine/rad_eu3a05gpio.h",
+ MAME_DIR .. "src/mame/drivers/tvgame.cpp",
+ MAME_DIR .. "src/mame/drivers/vii.cpp",
+ MAME_DIR .. "src/mame/drivers/xavix.cpp",
+ MAME_DIR .. "src/mame/video/xavix.cpp",
+ MAME_DIR .. "src/mame/machine/xavix.cpp",
+ MAME_DIR .. "src/mame/includes/xavix.h",
+}
+
createMESSProjects(_target, _subtarget, "ultimachine")
files {
MAME_DIR .. "src/mame/drivers/rambo.cpp",
@@ -3662,12 +3679,6 @@ files {
MAME_DIR .. "src/mame/drivers/pv9234.cpp",
MAME_DIR .. "src/mame/drivers/qtsbc.cpp",
MAME_DIR .. "src/mame/drivers/rd100.cpp",
- MAME_DIR .. "src/mame/drivers/rad_eu3a14.cpp",
- MAME_DIR .. "src/mame/drivers/rad_eu3a05.cpp",
- MAME_DIR .. "src/mame/audio/rad_eu3a05.cpp",
- MAME_DIR .. "src/mame/audio/rad_eu3a05.h",
- MAME_DIR .. "src/mame/machine/rad_eu3a05gpio.cpp",
- MAME_DIR .. "src/mame/machine/rad_eu3a05gpio.h",
MAME_DIR .. "src/mame/drivers/rvoice.cpp",
MAME_DIR .. "src/mame/drivers/sacstate.cpp",
MAME_DIR .. "src/mame/drivers/sartorius.cpp",
@@ -3695,12 +3706,10 @@ files {
MAME_DIR .. "src/mame/drivers/tsispch.cpp",
MAME_DIR .. "src/mame/includes/tsispch.h",
MAME_DIR .. "src/mame/drivers/tti.cpp",
- MAME_DIR .. "src/mame/drivers/tvgame.cpp",
MAME_DIR .. "src/mame/drivers/unistar.cpp",
MAME_DIR .. "src/mame/drivers/v6809.cpp",
MAME_DIR .. "src/mame/drivers/vector4.cpp",
MAME_DIR .. "src/mame/drivers/vectrix.cpp",
- MAME_DIR .. "src/mame/drivers/vii.cpp",
MAME_DIR .. "src/mame/drivers/vp60.cpp",
MAME_DIR .. "src/mame/drivers/vp122.cpp",
MAME_DIR .. "src/mame/drivers/vp415.cpp",
@@ -3709,7 +3718,6 @@ files {
MAME_DIR .. "src/mame/drivers/wyse.cpp",
MAME_DIR .. "src/mame/drivers/xor100.cpp",
MAME_DIR .. "src/mame/includes/xor100.h",
- MAME_DIR .. "src/mame/drivers/xavix.cpp",
MAME_DIR .. "src/mame/drivers/zms8085.cpp",
MAME_DIR .. "src/mame/drivers/zorba.cpp",
MAME_DIR .. "src/mame/includes/zorba.h",
diff --git a/src/devices/cpu/m6502/oxavix.lst b/src/devices/cpu/m6502/oxavix.lst
index 34e5b66309b..8ea1c7f0acc 100644
--- a/src/devices/cpu/m6502/oxavix.lst
+++ b/src/devices/cpu/m6502/oxavix.lst
@@ -4,9 +4,9 @@
callf_xa3
read(SP);
- if (PC & 0x8000) // if top bit of PC isn't set we're in the non-banked RAM area, don't store farbank?
+ if (PC & 0x8000) // if top bit of PC isn't set we're in the non-banked RAM area, don't store codebank?
{
- write(SP, m_farbank);
+ write(SP, get_codebank());
dec_SP();
}
TMP2 = read_pc();
@@ -18,7 +18,7 @@ callf_xa3
dec_SP();
TMP = set_h(TMP, read_pc());
PC = TMP;
- m_farbank=TMP2;
+ set_codebank(TMP2);
prefetch();
retf_imp
@@ -28,28 +28,24 @@ retf_imp
PC = read(SP);
inc_SP();
PC = set_h(PC, read(SP));
- if (PC & 0x8000) // if top bit of PC is set then we're jumping back to a banked ROM area, so get farbank? (see 0fdae in rad_ping)
+ if (PC & 0x8000) // if top bit of PC is set then we're jumping back to a banked ROM area, so get codebank? (see 0fdae in rad_ping)
{
inc_SP();
TMP2 = read(SP);
- m_farbank = TMP2;
- }
- else
- {
- // namcons2: because apparently 0x0300ea isn't correctly mirroring 0x0000ea despite logic in xavix.cpp looking correct?
- m_farbank = 0;
+ set_codebank(TMP2);
}
read_pc();
prefetch();
brk_xav_imp
+ // there is code in soem games to indicate this doesn't always push the far bank to the stack..
// The 6502 bug when a nmi occurs in a brk is reproduced (case !irq_taken && nmi_state)
if(irq_taken) {
read_pc_noinc();
} else {
read_pc();
}
- write(SP, m_farbank); // maybe
+ write(SP, get_codebank()); // maybe
dec_SP();
write(SP, PC >> 8);
dec_SP();
@@ -62,13 +58,11 @@ brk_xav_imp
{
PC = read_arg(0xfffa);
PC = set_h(PC, read_arg(0xfffb));
- m_farbank = 0;
}
else
{
PC = m_vector_callback(0,1);
PC = set_h(PC, m_vector_callback(0,0));
- m_farbank = 0;
}
nmi_state = false;
@@ -78,13 +72,11 @@ brk_xav_imp
{
PC = read_arg(0xfffe);
PC = set_h(PC, read_arg(0xffff));
- m_farbank = 0;
}
else
{
PC = m_vector_callback(1,1);
PC = set_h(PC, m_vector_callback(1,0));
- m_farbank = 0;
}
if(irq_taken)
@@ -106,5 +98,5 @@ rti_xav_imp
PC = set_h(PC, read(SP));
inc_SP();
TMP2 = read(SP);
- m_farbank = TMP2;
+ set_codebank(TMP2);
prefetch();
diff --git a/src/devices/cpu/m6502/xavix.cpp b/src/devices/cpu/m6502/xavix.cpp
index 2a01e8ee390..e3f00edbccb 100644
--- a/src/devices/cpu/m6502/xavix.cpp
+++ b/src/devices/cpu/m6502/xavix.cpp
@@ -5,7 +5,16 @@
xavix.c
6502 with custom opcodes
- integrated gfx / sound / coprocessor?
+ integrated gfx / sound
+
+ special notes
+
+ 0x0000-0x7fff seems to be a 'low bus' area, it is always the same regardless
+ of banking
+ 0x8000-0xffff is a banked area with individual code and data banks
+ 0x00ff contains the DATA bank, set manually in code
+ 0x00fe appears to be the current CODE bank, set with either the
+ custom opcodes, or manually (if running from lowbus only?)
***************************************************************************/
@@ -34,7 +43,7 @@ std::unique_ptr<util::disasm_interface> xavix_device::create_disassembler()
offs_t xavix_device::pc_to_external(u16 pc)
{
- return adr_with_bank(pc);
+ return adr_with_codebank(pc);
}
void xavix_device::device_start()
@@ -52,7 +61,8 @@ void xavix_device::device_start()
void xavix_device::device_reset()
{
- m_farbank = 0;
+ set_codebank(0);
+ set_databank(0);
m6502_device::device_reset();
}
@@ -64,40 +74,48 @@ xavix_device::mi_xavix_normal::mi_xavix_normal(xavix_device *_base)
uint8_t xavix_device::mi_xavix_normal::read(uint16_t adr)
{
- if (adr < 0x8000)
- return program->read_byte(adr);
- else
- {
- uint8_t data_bank = program->read_byte(0xff);
- return program->read_byte((data_bank << 16) | adr);
- }
+ if (adr == 0xfe)
+ return base->m_codebank;
+ else if (adr == 0xff)
+ return base->m_databank;
+
+ return program->read_byte((base->get_databank() << 16) | adr);
}
uint8_t xavix_device::mi_xavix_normal::read_sync(uint16_t adr)
{
- if (adr < 0x8000)
- return sdirect->read_byte(adr);
- else
- return sdirect->read_byte(base->adr_with_bank(adr));
+ if (adr == 0xfe)
+ return base->m_codebank;
+ else if (adr == 0xff)
+ return base->m_databank;
+
+ return sdirect->read_byte(base->adr_with_codebank(adr));
}
uint8_t xavix_device::mi_xavix_normal::read_arg(uint16_t adr)
{
- if (adr < 0x8000)
- return direct->read_byte(adr);
- else
- return direct->read_byte(base->adr_with_bank(adr));
+ if (adr == 0xfe)
+ return base->m_codebank;
+ else if (adr == 0xff)
+ return base->m_databank;
+
+ return direct->read_byte(base->adr_with_codebank(adr));
}
void xavix_device::mi_xavix_normal::write(uint16_t adr, uint8_t val)
{
- if (adr < 0x8000)
- program->write_byte(adr, val);
- else
+ if (adr == 0xfe)
{
- uint8_t data_bank = program->read_byte(0xff);
- program->write_byte((data_bank << 16) | adr, val);
+ base->m_codebank = val;
+ return;
}
+ else if (adr == 0xff)
+ {
+ base->m_databank = val;
+ return;
+ }
+
+ program->write_byte((base->get_databank() << 16) | adr, val);
}
xavix_device::mi_xavix_nd::mi_xavix_nd(xavix_device *_base) : mi_xavix_normal(_base)
@@ -106,19 +124,49 @@ xavix_device::mi_xavix_nd::mi_xavix_nd(xavix_device *_base) : mi_xavix_normal(_b
uint8_t xavix_device::mi_xavix_nd::read_sync(uint16_t adr)
{
- if (adr < 0x8000)
- return sprogram->read_byte(adr);
- else
- return sprogram->read_byte(base->adr_with_bank(adr));
+ if (adr == 0xfe)
+ return base->m_codebank;
+ else if (adr == 0xff)
+ return base->m_databank;
+
+ return sprogram->read_byte(base->adr_with_codebank(adr));
}
uint8_t xavix_device::mi_xavix_nd::read_arg(uint16_t adr)
{
- if (adr < 0x8000)
- return program->read_byte(adr);
- else
- return program->read_byte(base->adr_with_bank(adr));
+ if (adr == 0xfe)
+ return base->m_codebank;
+ else if (adr == 0xff)
+ return base->m_databank;
+
+ return program->read_byte(base->adr_with_codebank(adr));
+}
+
+inline void xavix_device::set_codebank(uint8_t bank)
+{
+// space().write_byte(0xfe, bank);
+ m_codebank = bank;
+}
+
+inline uint8_t xavix_device::get_codebank()
+{
+// return space().read_byte(0xfe);
+ return m_codebank;
}
+inline void xavix_device::set_databank(uint8_t bank)
+{
+// space().write_byte(0xff, bank);
+ m_databank = bank;
+}
+
+inline uint8_t xavix_device::get_databank()
+{
+// return space().read_byte(0xff);
+ return m_databank;
+}
+
+
+
#include "cpu/m6502/xavix.hxx"
diff --git a/src/devices/cpu/m6502/xavix.h b/src/devices/cpu/m6502/xavix.h
index 3e55428bb8b..ea9c4785f53 100644
--- a/src/devices/cpu/m6502/xavix.h
+++ b/src/devices/cpu/m6502/xavix.h
@@ -61,13 +61,11 @@ protected:
virtual uint8_t read_arg(uint16_t adr) override;
};
- uint8_t m_farbank;
+ uint8_t m_databank;
+ uint8_t m_codebank;
uint32_t XPC;
- uint8_t farbank_r() { return m_farbank; }
- void farbank_w(uint8_t data) { m_farbank = data; }
-
- uint32_t adr_with_bank(uint16_t adr) { return adr | (m_farbank << 16); }
+ uint32_t adr_with_codebank(uint16_t adr) { return adr | (get_codebank() << 16); }
virtual void device_start() override;
virtual void device_reset() override;
@@ -76,6 +74,11 @@ protected:
private:
xavix_interrupt_vector_delegate m_vector_callback;
+ void set_codebank(uint8_t bank);
+ uint8_t get_codebank();
+ void set_databank(uint8_t bank);
+ uint8_t get_databank();
+
};
DECLARE_DEVICE_TYPE(XAVIX, xavix_device)
diff --git a/src/mame/drivers/vii.cpp b/src/mame/drivers/vii.cpp
index 069d1ab76ef..8e47af0fb1a 100644
--- a/src/mame/drivers/vii.cpp
+++ b/src/mame/drivers/vii.cpp
@@ -1127,6 +1127,106 @@ static INPUT_PORTS_START( rad_skatp )
PORT_BIT( 0xffff, IP_ACTIVE_HIGH, IPT_CUSTOM )
INPUT_PORTS_END
+static INPUT_PORTS_START( rad_sktv )
+ /* how does the Scanner connect? probably some serial port with comms protocol, not IO ports?
+ internal test mode shows 'uart' ports (which currently fail)
+
+ To access internal test hold DOWN and BUTTON1 together on startup until a coloured screen appears.
+ To cycle through the tests again hold DOWN and press BUTTON1 */
+
+ PORT_START("P1")
+ PORT_DIPNAME( 0x0001, 0x0001, "IN0" )
+ PORT_DIPSETTING( 0x0001, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0002, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
+ PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
+ PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )
+ PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0020, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0040, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
+ PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON1 )
+ PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON2 )
+ PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0400, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0800, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x1000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x2000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x8000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+
+ PORT_START("P2")
+ PORT_DIPNAME( 0x0001, 0x0001, "IN1" )
+ PORT_DIPSETTING( 0x0001, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0002, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0004, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0008, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0010, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0020, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0040, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0080, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0100, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0200, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0400, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x0800, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x1000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x2000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x8000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+
+ PORT_START("P3") // PAL/NTSC flag
+ PORT_BIT( 0xffff, IP_ACTIVE_HIGH, IPT_CUSTOM ) // NTSC
+ //PORT_BIT( 0xffff, IP_ACTIVE_PAL, IPT_CUSTOM ) // PAL
+INPUT_PORTS_END
+
/* hold 'Console Down' while powering up to get the test menu, including input tests
the ball (Wired) and bat (IR) are read some other way as they don't seem to appear in the ports. */
static INPUT_PORTS_START( rad_crik )
@@ -1475,6 +1575,17 @@ ROM_START( rad_skatp ) // rom was dumped from the NTSC version, but region comes
ROM_LOAD16_WORD_SWAP( "skateboarder.bin", 0x000000, 0x400000, CRC(08b9ab91) SHA1(6665edc4740804956136c68065890925a144626b) )
ROM_END
+ROM_START( rad_sktv )
+ ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASEFF )
+ ROM_LOAD16_WORD_SWAP( "skannerztv.bin", 0x000000, 0x200000, CRC(e92278e3) SHA1(eb6bee5e661128d83784960dfff50379c36bfaeb) )
+
+ /* The external scanner MCU is a Winbond from 2000: SA5641
+ the scanner plays sound effects when scanning, without being connected to the main unit, so a way to dump / emulate
+ this MCU is also needed for complete emulation
+
+ TODO: find details on MCU so that we know capacity etc. */
+ROM_END
+
ROM_START( rad_crik ) // only released in EU?
ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASEFF )
ROM_LOAD16_WORD_SWAP( "cricket.bin", 0x000000, 0x200000, CRC(6fa0aaa9) SHA1(210d2d4f542181f59127ce2f516d0408dc6de7a8) )
@@ -1613,6 +1724,9 @@ CONS( 2006, rad_skatp, rad_skat,0, spg2xx_basep,rad_skatp,spg2xx_game_sta
CONS( 2006, rad_crik, 0, 0, spg2xx_basep,rad_crik, spg2xx_game_state, rad_crik, "Radica", "Connectv Cricket (PAL)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING ) // Version 3.00 20/03/06 is listed in INTERNAL TEST
+CONS( 2007, rad_sktv, 0, 0, spg2xx_base, rad_sktv, spg2xx_game_state, rad_skat, "Radica", "Skannerz TV", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
+
+
// might not fit here. First 0x8000 bytes are blank (not too uncommon for these) then rest of rom looks like it's probably encrypted at least
CONS( 2009, zone40, 0, 0, spg2xx_base, wirels60, spg2xx_game_state, wirels60, "Jungle Soft / Ultimate Products (HK) Ltd", "Zone 40", MACHINE_NO_SOUND | MACHINE_NOT_WORKING )
// might not fit here, NAND dump, has internal bootstrap at least, see above.
diff --git a/src/mame/drivers/xavix.cpp b/src/mame/drivers/xavix.cpp
index 32636dca736..451b9cecca9 100644
--- a/src/mame/drivers/xavix.cpp
+++ b/src/mame/drivers/xavix.cpp
@@ -203,1455 +203,165 @@
***************************************************************************/
-
#include "emu.h"
-#include "cpu/m6502/xavix.h"
-#include "machine/timer.h"
-#include "screen.h"
-#include "speaker.h"
+#include "includes/xavix.h"
// not confirmed for all games
#define MAIN_CLOCK XTAL(21'477'272)
-class xavix_state : public driver_device
-{
-public:
- xavix_state(const machine_config &mconfig, device_type type, const char *tag)
- : driver_device(mconfig, type, tag),
- m_maincpu(*this, "maincpu"),
- m_mainram(*this, "mainram"),
- m_spr_attr0(*this, "spr_attr0"),
- m_spr_attr1(*this, "spr_attr1"),
- m_spr_ypos(*this, "spr_ypos"),
- m_spr_xpos(*this, "spr_xpos"),
- m_spr_addr_lo(*this, "spr_addr_lo"),
- m_spr_addr_md(*this, "spr_addr_md"),
- m_spr_addr_hi(*this, "spr_addr_hi"),
- m_palram1(*this, "palram1"),
- m_palram2(*this, "palram2"),
- m_spr_attra(*this, "spr_attra"),
- m_palette(*this, "palette"),
- m_in0(*this, "IN0"),
- m_in1(*this, "IN1"),
- m_region(*this, "REGION"),
- m_gfxdecode(*this, "gfxdecode"),
- m_alt_addressing(0)
- { }
-
- // devices
- required_device<cpu_device> m_maincpu;
-
- // screen updates
- uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
-
- void xavix(machine_config &config);
- void xavixp(machine_config &config);
-
- DECLARE_WRITE8_MEMBER(xavix_7900_w);
-
- DECLARE_WRITE8_MEMBER(dma_trigger_w);
- DECLARE_WRITE8_MEMBER(rom_dmasrc_lo_w);
- DECLARE_WRITE8_MEMBER(rom_dmasrc_md_w);
- DECLARE_WRITE8_MEMBER(rom_dmasrc_hi_w);
- DECLARE_WRITE8_MEMBER(rom_dmadst_lo_w);
- DECLARE_WRITE8_MEMBER(rom_dmadst_hi_w);
- DECLARE_WRITE8_MEMBER(rom_dmalen_lo_w);
- DECLARE_WRITE8_MEMBER(rom_dmalen_hi_w);
- DECLARE_READ8_MEMBER(dma_trigger_r);
-
- DECLARE_WRITE8_MEMBER(vid_dma_params_1_w);
- DECLARE_WRITE8_MEMBER(vid_dma_params_2_w);
- DECLARE_WRITE8_MEMBER(vid_dma_trigger_w);
- DECLARE_READ8_MEMBER(vid_dma_trigger_r);
-
- DECLARE_READ8_MEMBER(xavix_io_0_r);
- DECLARE_READ8_MEMBER(xavix_io_1_r);
-
- DECLARE_WRITE8_MEMBER(irq_enable_w);
- DECLARE_WRITE8_MEMBER(irq_vector0_lo_w);
- DECLARE_WRITE8_MEMBER(irq_vector0_hi_w);
- DECLARE_WRITE8_MEMBER(irq_vector1_lo_w);
- DECLARE_WRITE8_MEMBER(irq_vector1_hi_w);
-
- DECLARE_READ8_MEMBER(irq_source_r);
- DECLARE_WRITE8_MEMBER(irq_source_w);
-
- DECLARE_READ8_MEMBER(xavix_6ff0_r);
- DECLARE_WRITE8_MEMBER(xavix_6ff0_w);
-
- DECLARE_READ8_MEMBER(xavix_6ff8_r);
- DECLARE_WRITE8_MEMBER(xavix_6ff8_w);
-
- DECLARE_READ8_MEMBER(xavix_75f0_r);
- DECLARE_WRITE8_MEMBER(xavix_75f0_w);
-
- DECLARE_READ8_MEMBER(xavix_75f1_r);
- DECLARE_WRITE8_MEMBER(xavix_75f1_w);
-
- DECLARE_READ8_MEMBER(xavix_75f4_r);
- DECLARE_READ8_MEMBER(xavix_75f5_r);
- DECLARE_READ8_MEMBER(xavix_75f6_r);
- DECLARE_WRITE8_MEMBER(xavix_75f6_w);
-
- DECLARE_WRITE8_MEMBER(xavix_75f7_w);
-
- DECLARE_READ8_MEMBER(xavix_75f8_r);
- DECLARE_WRITE8_MEMBER(xavix_75f8_w);
-
- DECLARE_READ8_MEMBER(xavix_75f9_r);
- DECLARE_WRITE8_MEMBER(xavix_75f9_w);
-
- DECLARE_READ8_MEMBER(xavix_75fa_r);
- DECLARE_WRITE8_MEMBER(xavix_75fa_w);
- DECLARE_READ8_MEMBER(xavix_75fb_r);
- DECLARE_WRITE8_MEMBER(xavix_75fb_w);
- DECLARE_READ8_MEMBER(xavix_75fc_r);
- DECLARE_WRITE8_MEMBER(xavix_75fc_w);
- DECLARE_READ8_MEMBER(xavix_75fd_r);
- DECLARE_WRITE8_MEMBER(xavix_75fd_w);
-
- DECLARE_WRITE8_MEMBER(xavix_75fe_w);
- DECLARE_WRITE8_MEMBER(xavix_75ff_w);
-
- DECLARE_WRITE8_MEMBER(xavix_6fc0_w);
- DECLARE_WRITE8_MEMBER(tmap1_regs_w);
- DECLARE_WRITE8_MEMBER(xavix_6fd8_w);
- DECLARE_WRITE8_MEMBER(tmap2_regs_w);
- DECLARE_READ8_MEMBER(tmap2_regs_r);
-
- DECLARE_READ8_MEMBER(pal_ntsc_r);
-
- DECLARE_READ8_MEMBER(xavix_4000_r);
-
- DECLARE_READ8_MEMBER(mult_r);
- DECLARE_WRITE8_MEMBER(mult_param_w);
-
- INTERRUPT_GEN_MEMBER(interrupt);
- TIMER_DEVICE_CALLBACK_MEMBER(scanline_cb);
-
- DECLARE_DRIVER_INIT(xavix);
- DECLARE_DRIVER_INIT(taitons1);
- DECLARE_DRIVER_INIT(rad_box);
-
- void xavix_map(address_map &map);
-protected:
- // driver_device overrides
- virtual void machine_start() override;
- virtual void machine_reset() override;
-
- virtual void video_start() override;
-
-private:
- uint8_t m_rom_dmasrc_lo_data;
- uint8_t m_rom_dmasrc_md_data;
- uint8_t m_rom_dmasrc_hi_data;
-
- uint8_t m_rom_dmadst_lo_data;
- uint8_t m_rom_dmadst_hi_data;
-
- uint8_t m_rom_dmalen_lo_data;
- uint8_t m_rom_dmalen_hi_data;
-
- uint8_t m_irq_enable_data;
- uint8_t m_irq_vector0_lo_data;
- uint8_t m_irq_vector0_hi_data;
- uint8_t m_irq_vector1_lo_data;
- uint8_t m_irq_vector1_hi_data;
-
- uint8_t m_multparams[3];
- uint8_t m_multresults[2];
-
- uint8_t m_vid_dma_param1[2];
- uint8_t m_vid_dma_param2[2];
-
- uint8_t m_tmap1_regs[8];
- uint8_t m_tmap2_regs[8];
-
- uint8_t m_6ff0;
- uint8_t m_6ff8;
-
- uint8_t m_75f0;
- uint8_t m_75f1;
-
- uint8_t m_75f6;
- uint8_t m_75f8;
- uint8_t m_75fa;
- uint8_t m_75fb;
- uint8_t m_75fc;
- uint8_t m_75fd;
-
- uint8_t get_vectors(int which, int half);
-
- required_shared_ptr<uint8_t> m_mainram;
-
- required_shared_ptr<uint8_t> m_spr_attr0;
- required_shared_ptr<uint8_t> m_spr_attr1;
- required_shared_ptr<uint8_t> m_spr_ypos;
- required_shared_ptr<uint8_t> m_spr_xpos;
-
- required_shared_ptr<uint8_t> m_spr_addr_lo;
- required_shared_ptr<uint8_t> m_spr_addr_md;
- required_shared_ptr<uint8_t> m_spr_addr_hi;
-
- required_shared_ptr<uint8_t> m_palram1;
- required_shared_ptr<uint8_t> m_palram2;
-
- required_shared_ptr<uint8_t> m_spr_attra;
-
- required_device<palette_device> m_palette;
-
- required_ioport m_in0;
- required_ioport m_in1;
- required_ioport m_region;
-
- required_device<gfxdecode_device> m_gfxdecode;
-
- void handle_palette(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- double hue2rgb(double p, double q, double t);
- void draw_tile(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 opaque);
- void draw_tilemap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int which);
- void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
-
- int m_rgnlen;
- uint8_t* m_rgn;
-
- // variables used by rendering
- int m_tmp_dataaddress;
- int m_tmp_databit;
- void set_data_address(int address, int bit);
- uint8_t get_next_bit();
- uint8_t get_next_byte();
-
- int get_current_address_byte();
-
- int m_alt_addressing;
-};
-
-void xavix_state::set_data_address(int address, int bit)
-{
- m_tmp_dataaddress = address;
- m_tmp_databit = bit;
-}
-
-uint8_t xavix_state::get_next_bit()
+READ8_MEMBER(xavix_state::main_r)
{
- uint8_t bit = m_rgn[m_tmp_dataaddress & (m_rgnlen - 1)];
- bit = bit >> m_tmp_databit;
- bit &= 1;
-
- m_tmp_databit++;
-
- if (m_tmp_databit == 8)
+ if (offset & 0x8000)
{
- m_tmp_databit = 0;
- m_tmp_dataaddress++;
+ return m_rgn[(offset) & (m_rgnlen - 1)];
}
-
- return bit;
-}
-
-uint8_t xavix_state::get_next_byte()
-{
- uint8_t dat = 0;
- for (int i = 0; i < 8; i++)
- {
- dat |= (get_next_bit() << i);
- }
- return dat;
-}
-
-int xavix_state::get_current_address_byte()
-{
- return m_tmp_dataaddress;
-}
-
-
-void xavix_state::video_start()
-{
-}
-
-
-double xavix_state::hue2rgb(double p, double q, double t)
-{
- if (t < 0) t += 1;
- if (t > 1) t -= 1;
- if (t < 1 / 6.0f) return p + (q - p) * 6 * t;
- if (t < 1 / 2.0f) return q;
- if (t < 2 / 3.0f) return p + (q - p) * (2 / 3.0f - t) * 6;
- return p;
-}
-
-
-void xavix_state::handle_palette(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- // not verified
- int offs = 0;
- for (int index = 0; index < 256; index++)
- {
- uint16_t dat = m_palram1[offs];
- dat |= m_palram2[offs]<<8;
- offs++;
-
- int l_raw = (dat & 0x1f00) >> 8;
- int sl_raw =(dat & 0x00e0) >> 5;
- int h_raw = (dat & 0x001f) >> 0;
-
- //if (h_raw > 24)
- // logerror("hraw >24 (%02x)\n", h_raw);
-
- //if (l_raw > 17)
- // logerror("lraw >17 (%02x)\n", l_raw);
-
- //if (sl_raw > 7)
- // logerror("sl_raw >5 (%02x)\n", sl_raw);
-
- double l = (double)l_raw / 17.0f;
- double s = (double)sl_raw / 7.0f;
- double h = (double)h_raw / 24.0f;
-
- 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);
- }
-
- int r_real = r * 255.0f;
- int g_real = g * 255.0f;
- int b_real = b * 255.0f;
-
- m_palette->set_pen_color(index, r_real, g_real, b_real);
-
- }
-}
-
-void xavix_state::draw_tilemap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int which)
-{
- int alt_tileaddressing = 0;
- int alt_tileaddressing2 = 0;
-
- int ydimension = 0;
- int xdimension = 0;
- int ytilesize = 0;
- int xtilesize = 0;
- int offset_multiplier = 0;
- int opaque = 0;
-
- uint8_t* tileregs;
- address_space& mainspace = m_maincpu->space(AS_PROGRAM);
-
- if (which == 0)
- {
- tileregs = m_tmap1_regs;
- opaque = 1;
- }
- else
- {
- tileregs = m_tmap2_regs;
- opaque = 0;
- }
-
- switch (tileregs[0x3] & 0x30)
- {
- case 0x00:
- ydimension = 32;
- xdimension = 32;
- ytilesize = 8;
- xtilesize = 8;
- break;
-
- case 0x10:
- ydimension = 32;
- xdimension = 16;
- ytilesize = 8;
- xtilesize = 16;
- break;
-
- case 0x20: // guess
- ydimension = 16;
- xdimension = 32;
- ytilesize = 16;
- xtilesize = 8;
- break;
-
- case 0x30:
- ydimension = 16;
- xdimension = 16;
- ytilesize = 16;
- xtilesize = 16;
- break;
- }
-
- offset_multiplier = (ytilesize * xtilesize)/8;
-
- if (tileregs[0x7] & 0x10)
- alt_tileaddressing = 1;
else
- alt_tileaddressing = 0;
-
- if (tileregs[0x7] & 0x02)
- alt_tileaddressing2 = 1;
-
- static int hackx = 1;
-
- if (machine().input().code_pressed_once(KEYCODE_Q))
- {
- hackx--;
- printf("%02x\n", hackx);
- }
-
- if (machine().input().code_pressed_once(KEYCODE_W))
- {
- hackx++;
- printf("%02x\n", hackx);
- }
-
- if (tileregs[0x7] & 0x80)
- {
- //printf("draw tilemap %d, regs base0 %02x base1 %02x base2 %02x tilesize,bpp %02x scrollx %02x scrolly %02x pal %02x mode %02x\n", which, tileregs[0x0], tileregs[0x1], tileregs[0x2], tileregs[0x3], tileregs[0x4], tileregs[0x5], tileregs[0x6], tileregs[0x7]);
-
- // there's a tilemap register to specify base in main ram, although in the monster truck test mode it points to an unmapped region
- // and expected a fixed layout, we handle that in the memory map at the moment
- int count;
-
- count = 0;// ;
- for (int y = 0; y < ydimension; y++)
- {
- for (int x = 0; x < xdimension; x++)
- {
- int bpp, pal, scrolly, scrollx;
- int tile = 0;
- int extraattr = 0;
-
- // the register being 0 probably isn't the condition here
- if (tileregs[0x0] != 0x00) tile |= mainspace.read_byte((tileregs[0x0] << 8) + count);
- if (tileregs[0x1] != 0x00) tile |= mainspace.read_byte((tileregs[0x1] << 8) + count) << 8;
-
- // at the very least boxing leaves unwanted bits set in ram after changing between mode 0x8a and 0x82, expecting them to not be used
- if (tileregs[0x7] & 0x08)
- extraattr = mainspace.read_byte((tileregs[0x2] << 8) + count);
-
- count++;
-
- bpp = (tileregs[0x3] & 0x0e) >> 1;
- bpp++;
- pal = (tileregs[0x6] & 0xf0) >> 4;
- scrolly = tileregs[0x5];
- scrollx = tileregs[0x4];
-
- int basereg;
- int flipx = 0;
- int flipy = 0;
- int gfxbase;
-
- // tile 0 is always skipped, doesn't even point to valid data packets in alt mode
- // this is consistent with the top layer too
- // should we draw as solid in solid layer?
- if (tile == 0)
- continue;
-
- const int debug_packets = 0;
- int test = 0;
-
- if (!alt_tileaddressing)
- {
- if (!alt_tileaddressing2)
- {
- basereg = 0;
- gfxbase = (m_spr_attra[(basereg * 2) + 1] << 16) | (m_spr_attra[(basereg * 2)] << 8);
-
- tile = tile * (offset_multiplier * bpp);
- tile += gfxbase;
- }
- else
- {
- tile = tile * 8;
- basereg = (tile & 0x70000) >> 16;
- tile &= 0xffff;
- gfxbase = (m_spr_attra[(basereg * 2) + 1] << 16) | (m_spr_attra[(basereg * 2)] << 8);
- tile += gfxbase;
-
- if (tileregs[0x7] & 0x08)
- {
- // make use of the extraattr stuff?
- pal = (extraattr & 0xf0)>>4;
- // low bits are priority?
- }
- }
- }
- else
- {
- if (debug_packets) printf("for tile %04x (at %d %d): ", tile, (((x * 16) + scrollx) & 0xff), (((y * 16) + scrolly) & 0xff));
-
-
- basereg = (tile & 0xf000) >> 12;
- tile &= 0x0fff;
- gfxbase = (m_spr_attra[(basereg * 2) + 1] << 16) | (m_spr_attra[(basereg * 2)] << 8);
-
- tile += gfxbase;
- set_data_address(tile, 0);
-
- // there seems to be a packet stored before the tile?!
- // the offset used for flipped sprites seems to specifically be changed so that it picks up an extra byte which presumably triggers the flipping
- uint8_t byte1 = 0;
- int done = 0;
- int skip = 0;
-
- do
- {
- byte1 = get_next_byte();
-
- if (debug_packets) printf(" %02x, ", byte1);
-
- if (skip == 1)
- {
- skip = 0;
- //test = 1;
- }
- else if ((byte1 & 0x0f) == 0x01)
- {
- // used
- }
- else if ((byte1 & 0x0f) == 0x03)
- {
- // causes next byte to be skipped??
- skip = 1;
- }
- else if ((byte1 & 0x0f) == 0x05)
- {
- // the upper bits are often 0x00, 0x10, 0x20, 0x30, why?
- flipx = 1;
- }
- else if ((byte1 & 0x0f) == 0x06) // there must be other finish conditions too because sometimes this fails..
- {
- // tile data will follow after this, always?
- pal = (byte1 & 0xf0) >> 4;
- done = 1;
- }
- else if ((byte1 & 0x0f) == 0x07)
- {
- // causes next byte to be skipped??
- skip = 1;
- }
- else if ((byte1 & 0x0f) == 0x09)
- {
- // used
- }
- else if ((byte1 & 0x0f) == 0x0a)
- {
- // not seen
- }
- else if ((byte1 & 0x0f) == 0x0b)
- {
- // used
- }
- else if ((byte1 & 0x0f) == 0x0c)
- {
- // not seen
- }
- else if ((byte1 & 0x0f) == 0x0d)
- {
- // used
- }
- else if ((byte1 & 0x0f) == 0x0e)
- {
- // not seen
- }
- else if ((byte1 & 0x0f) == 0x0f)
- {
- // used
- }
-
- } while (done == 0);
- if (debug_packets) printf("\n");
- tile = get_current_address_byte();
- }
-
- if (test == 1) pal = machine().rand() & 0xf;
-
-
- draw_tile(screen, bitmap, cliprect, tile, bpp, (x * xtilesize) + scrollx, ((y * ytilesize) - 16) - scrolly, ytilesize, xtilesize, flipx, flipy, pal, opaque);
- draw_tile(screen, bitmap, cliprect, tile, bpp, (x * xtilesize) + scrollx, (((y * ytilesize) - 16) - scrolly) + 256, ytilesize, xtilesize, flipx, flipy, pal, opaque); // wrap-y
- draw_tile(screen, bitmap, cliprect, tile, bpp, ((x * xtilesize) + scrollx) - 256, ((y * ytilesize) - 16) - scrolly, ytilesize, xtilesize, flipx, flipy, pal, opaque); // wrap-x
- draw_tile(screen, bitmap, cliprect, tile, bpp, ((x * xtilesize) + scrollx) - 256, (((y * ytilesize) - 16) - scrolly) + 256, ytilesize, xtilesize, flipx, flipy, pal, opaque); // wrap-y and x
- }
- }
- }
-}
-
-void xavix_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- //logerror("frame\n");
- // priority doesn't seem to be based on list order, there are bad sprite-sprite priorities with either forward or reverse
-
- for (int i = 0xff; i >= 0; i--)
- {
- /* attribute 0 bits
- pppp bbb- p = palette, b = bpp
-
- attribute 1 bits
- ---- ss-f s = size, f = flipx
- */
-
- int ypos = m_spr_ypos[i];
- int xpos = m_spr_xpos[i];
- int tile = (m_spr_addr_hi[i] << 16) | (m_spr_addr_md[i] << 8) | m_spr_addr_lo[i];
- int attr0 = m_spr_attr0[i];
- int attr1 = m_spr_attr1[i];
-
- int pal = (attr0 & 0xf0) >> 4;
- int flipx = (attr1 & 0x01);
-
- int drawheight = 16;
- int drawwidth = 16;
-
- tile &= (m_rgnlen - 1);
-
- // taito nostalgia 1 also seems to use a different addressing, is it selectable or is the chip different?
- // taito nost attr1 is 84 / 80 / 88 / 8c for the various elements of the xavix logo. monster truck uses ec / fc / dc / 4c / 5c / 6c (final 6 sprites ingame are 00 00 f0 f0 f0 f0, radar?)
-
- if ((attr1 & 0x0c) == 0x0c)
- {
- drawheight = 16;
- drawwidth = 16;
- if (m_alt_addressing == 1)
- tile = tile * 128;
- else if (m_alt_addressing == 2)
- tile = tile * 8;
- }
- else if ((attr1 & 0x0c) == 0x08)
- {
- drawheight = 16;
- drawwidth = 8;
- xpos += 4;
- if (m_alt_addressing == 1)
- tile = tile * 64;
- else if (m_alt_addressing == 2)
- tile = tile * 8;
- }
- else if ((attr1 & 0x0c) == 0x04)
- {
- drawheight = 8;
- drawwidth = 16;
- ypos -= 4;
- if (m_alt_addressing == 1)
- tile = tile * 64;
- else if (m_alt_addressing == 2)
- tile = tile * 8;
- }
- else if ((attr1 & 0x0c) == 0x00)
- {
- drawheight = 8;
- drawwidth = 8;
- xpos += 4;
- ypos -= 4;
- if (m_alt_addressing == 1)
- tile = tile * 32;
- else if (m_alt_addressing == 2)
- tile = tile * 8;
- }
-
- if (m_alt_addressing != 0)
- {
- int basereg = (tile & 0xf0000) >> 16;
- tile &= 0xffff;
- int gfxbase = (m_spr_attra[(basereg * 2) + 1] << 16) | (m_spr_attra[(basereg * 2)] << 8);
- tile+= gfxbase;
- }
-
- ypos = 0x100 - ypos;
-
- xpos -= 136;
- ypos -= 152;
-
- xpos &= 0xff;
- ypos &= 0xff;
-
- if (ypos >= 192)
- ypos -= 256;
-
- int bpp = 1;
-
- bpp = (attr0 & 0x0e) >> 1;
- bpp += 1;
-
- draw_tile(screen, bitmap, cliprect, tile, bpp, xpos, ypos, drawheight, drawwidth, flipx, 0, pal, 0);
- draw_tile(screen, bitmap, cliprect, tile, bpp, xpos - 256, ypos, drawheight, drawwidth, flipx, 0, pal, 0); // wrap-x
- draw_tile(screen, bitmap, cliprect, tile, bpp, xpos, ypos - 256, drawheight, drawwidth, flipx, 0, pal, 0); // wrap-y
- draw_tile(screen, bitmap, cliprect, tile, bpp, xpos - 256, ypos - 256, drawheight, drawwidth, flipx, 0, pal, 0); // wrap-x,y
-
- /*
- if ((m_spr_ypos[i] != 0x81) && (m_spr_ypos[i] != 0x80) && (m_spr_ypos[i] != 0x00))
- {
- logerror("sprite with enable? %02x attr0 %02x attr1 %02x attr3 %02x attr5 %02x attr6 %02x attr7 %02x\n", m_spr_ypos[i], m_spr_attr0[i], m_spr_attr1[i], m_spr_xpos[i], m_spr_addr_lo[i], m_spr_addr_md[i], m_spr_addr_hi[i] );
- }
- */
- }
-}
-
-void xavix_state::draw_tile(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 opaque)
-{
- // set the address here so we can increment in bits in the draw function
- set_data_address(tile, 0);
-
- for (int y = 0; y < drawheight; y++)
- {
- int row;
- if (flipy)
- {
- row = ypos + (drawheight-1) - y;
- }
- else
- {
- row = ypos + y;
- }
-
- for (int x = 0; x < drawwidth; x++)
- {
-
- int col;
-
- if (flipx)
- {
- col = xpos + (drawwidth-1) - x;
- }
- else
- {
- col = xpos + x;
- }
-
- uint8_t dat = 0;
-
- for (int i = 0; i < bpp; i++)
- {
- dat |= (get_next_bit() << i);
- }
-
- if ((row >= cliprect.min_y && row <= cliprect.max_y) && (col >= cliprect.min_x && col <= cliprect.max_x))
- {
- uint16_t* rowptr;
-
- rowptr = &bitmap.pix16(row);
-
- if (opaque)
- {
- rowptr[col] = (dat + (pal << 4)) & 0xff;
- }
- else
- {
- if (dat)
- rowptr[col] = (dat + (pal << 4)) & 0xff;
- }
- }
- }
- }
-}
-
-uint32_t xavix_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- handle_palette(screen, bitmap, cliprect);
-
- bitmap.fill(0, cliprect);
-
- draw_tilemap(screen,bitmap,cliprect,0);
- draw_sprites(screen,bitmap,cliprect);
- draw_tilemap(screen,bitmap,cliprect,1);
-
- return 0;
-}
-
-
-WRITE8_MEMBER(xavix_state::dma_trigger_w)
-{
- if (data & 0x01) // namcons2 writes 0x81, most of the time things write 0x01
- {
- logerror("%s: dma_trigger_w (do DMA?) %02x\n", machine().describe_context(), data);
-
- uint32_t source = (m_rom_dmasrc_hi_data << 16) | (m_rom_dmasrc_md_data << 8) | m_rom_dmasrc_lo_data;
- uint16_t dest = (m_rom_dmadst_hi_data << 8) | m_rom_dmadst_lo_data;
- uint16_t len = (m_rom_dmalen_hi_data << 8) | m_rom_dmalen_lo_data;
-
- source &= m_rgnlen - 1;
- logerror(" (possible DMA op SRC %08x DST %04x LEN %04x)\n", source, dest, len);
-
- address_space& destspace = m_maincpu->space(AS_PROGRAM);
-
- for (int i = 0; i < len; i++)
- {
- uint8_t dat = m_rgn[(source + i) & (m_rgnlen - 1)];
- destspace.write_byte(dest + i, dat);
- }
- }
- else // the interrupt routine writes 0x80 to the trigger, maybe 'clear IRQ?'
- {
- logerror("%s: dma_trigger_w (unknown) %02x\n", machine().describe_context(), data);
- }
-}
-
-WRITE8_MEMBER(xavix_state::rom_dmasrc_lo_w)
-{
- logerror("%s: rom_dmasrc_lo_w %02x\n", machine().describe_context(), data);
- m_rom_dmasrc_lo_data = data;
-}
-
-WRITE8_MEMBER(xavix_state::rom_dmasrc_md_w)
-{
- logerror("%s: rom_dmasrc_md_w %02x\n", machine().describe_context(), data);
- m_rom_dmasrc_md_data = data;
-}
-
-WRITE8_MEMBER(xavix_state::rom_dmasrc_hi_w)
-{
- logerror("%s: rom_dmasrc_hi_w %02x\n", machine().describe_context(), data);
- m_rom_dmasrc_hi_data = data;
- // this would mean Taito Nostalgia relies on mirroring tho, as it has the high bits set... so could just be wrong
- logerror(" (DMA ROM source of %02x%02x%02x)\n", m_rom_dmasrc_hi_data, m_rom_dmasrc_md_data, m_rom_dmasrc_lo_data);
-}
-
-WRITE8_MEMBER(xavix_state::rom_dmadst_lo_w)
-{
- logerror("%s: rom_dmadst_lo_w %02x\n", machine().describe_context(), data);
- m_rom_dmadst_lo_data = data;
-}
-
-WRITE8_MEMBER(xavix_state::rom_dmadst_hi_w)
-{
- logerror("%s: rom_dmadst_hi_w %02x\n", machine().describe_context(), data);
- m_rom_dmadst_hi_data = data;
-
- logerror(" (DMA dest of %02x%02x)\n", m_rom_dmadst_hi_data, m_rom_dmadst_lo_data);
-}
-
-WRITE8_MEMBER(xavix_state::rom_dmalen_lo_w)
-{
- logerror("%s: rom_dmalen_lo_w %02x\n", machine().describe_context(), data);
- m_rom_dmalen_lo_data = data;
-}
-
-WRITE8_MEMBER(xavix_state::rom_dmalen_hi_w)
-{
- logerror("%s: rom_dmalen_hi_w %02x\n", machine().describe_context(), data);
- m_rom_dmalen_hi_data = data;
-
- logerror(" (DMA len of %02x%02x)\n", m_rom_dmalen_hi_data, m_rom_dmalen_lo_data);
-}
-
-READ8_MEMBER(xavix_state::dma_trigger_r)
-{
- logerror("%s: dma_trigger_r (operation status?)\n", machine().describe_context());
- return 0x00;
-}
-
-
-
-WRITE8_MEMBER(xavix_state::irq_enable_w)
-{
- logerror("%s: irq_enable_w %02x\n", machine().describe_context(), data);
- m_irq_enable_data = data;
-}
-
-WRITE8_MEMBER(xavix_state::irq_vector0_lo_w)
-{
- logerror("%s: irq_vector0_lo_w %02x\n", machine().describe_context(), data);
- m_irq_vector0_lo_data = data;
-}
-
-WRITE8_MEMBER(xavix_state::irq_vector0_hi_w)
-{
- logerror("%s: irq_vector0_hi_w %02x\n", machine().describe_context(), data);
- m_irq_vector0_hi_data = data;
-}
-
-WRITE8_MEMBER(xavix_state::irq_vector1_lo_w)
-{
- logerror("%s: irq_vector1_lo_w %02x\n", machine().describe_context(), data);
- m_irq_vector1_lo_data = data;
-}
-
-WRITE8_MEMBER(xavix_state::irq_vector1_hi_w)
-{
- logerror("%s: irq_vector1_hi_w %02x\n", machine().describe_context(), data);
- m_irq_vector1_hi_data = data;
-}
-
-
-WRITE8_MEMBER(xavix_state::xavix_7900_w)
-{
- logerror("%s: xavix_7900_w %02x (---FIRST WRITE ON STARTUP---)\n", machine().describe_context(), data);
-}
-
-
-
-TIMER_DEVICE_CALLBACK_MEMBER(xavix_state::scanline_cb)
-{
-/*
- int scanline = param;
-
- if (scanline == 200)
- {
- if (m_irq_enable_data != 0)
- m_maincpu->set_input_line(INPUT_LINE_IRQ0,HOLD_LINE);
- }
-*/
-}
-
-INTERRUPT_GEN_MEMBER(xavix_state::interrupt)
-{
- // if (m_irq_enable_data != 0)
- // m_maincpu->set_input_line(INPUT_LINE_IRQ0,HOLD_LINE);
-
- // this logic is clearly VERY wrong
-
- if (m_irq_enable_data != 0)
- {
- if (m_6ff8)
- m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
- }
-}
-
-
-
-READ8_MEMBER(xavix_state::xavix_6ff0_r)
-{
- //logerror("%s: xavix_6ff0_r\n", machine().describe_context());
- return m_6ff0;
-}
-
-WRITE8_MEMBER(xavix_state::xavix_6ff0_w)
-{
- // expected to return data written
- m_6ff0 = data;
- //logerror("%s: xavix_6ff0_w %02x\n", machine().describe_context(), data);
-}
-
-READ8_MEMBER(xavix_state::xavix_6ff8_r)
-{
- //logerror("%s: xavix_6ff8_r\n", machine().describe_context());
- return m_6ff8;
-}
-
-WRITE8_MEMBER(xavix_state::xavix_6ff8_w)
-{
- // I think this is something to do with IRQ ack / enable
- m_6ff8 = data;
- logerror("%s: xavix_6ff8_w %02x\n", machine().describe_context(), data);
-}
-
-READ8_MEMBER(xavix_state::xavix_75f0_r)
-{
- logerror("%s: xavix_75f0_r\n", machine().describe_context());
- return m_75f0;
-}
-
-WRITE8_MEMBER(xavix_state::xavix_75f0_w)
-{
- // expected to return data written
- m_75f0 = data;
- logerror("%s: xavix_75f0_w %02x\n", machine().describe_context(), data);
-}
-
-READ8_MEMBER(xavix_state::xavix_75f1_r)
-{
- logerror("%s: xavix_75f1_r\n", machine().describe_context());
- return m_75f1;
-}
-
-WRITE8_MEMBER(xavix_state::xavix_75f1_w)
-{
- // expected to return data written
- m_75f1 = data;
- logerror("%s: xavix_75f1_w %02x\n", machine().describe_context(), data);
-}
-
-READ8_MEMBER(xavix_state::xavix_75f6_r)
-{
- logerror("%s: xavix_75f6_w\n", machine().describe_context());
- return m_75f6;
-}
-
-WRITE8_MEMBER(xavix_state::xavix_75f6_w)
-{
- // expected to return data written
- m_75f6 = data;
- logerror("%s: xavix_75f6_w %02x\n", machine().describe_context(), data);
-}
-
-READ8_MEMBER(xavix_state::xavix_75fa_r)
-{
- logerror("%s: xavix_75fa_w\n", machine().describe_context());
- return m_75fa;
-}
-
-WRITE8_MEMBER(xavix_state::xavix_75fa_w)
-{
- // expected to return data written
- m_75fa = data;
- logerror("%s: xavix_75fa_w %02x\n", machine().describe_context(), data);
-}
-
-READ8_MEMBER(xavix_state::xavix_75fb_r)
-{
- logerror("%s: xavix_75fb_w\n", machine().describe_context());
- return m_75fb;
-}
-
-WRITE8_MEMBER(xavix_state::xavix_75fb_w)
-{
- // expected to return data written
- m_75fb = data;
- logerror("%s: xavix_75fb_w %02x\n", machine().describe_context(), data);
-}
-
-READ8_MEMBER(xavix_state::xavix_75fc_r)
-{
- logerror("%s: xavix_75fc_w\n", machine().describe_context());
- return m_75fc;
-}
-
-WRITE8_MEMBER(xavix_state::xavix_75fc_w)
-{
- // expected to return data written
- m_75fc = data;
- logerror("%s: xavix_75fc_w %02x\n", machine().describe_context(), data);
-}
-
-READ8_MEMBER(xavix_state::xavix_75fd_r)
-{
- logerror("%s: xavix_75fd_w\n", machine().describe_context());
- return m_75fd;
-}
-
-WRITE8_MEMBER(xavix_state::xavix_75fd_w)
-{
- // expected to return data written
- m_75fd = data;
- logerror("%s: xavix_75fd_w %02x\n", machine().describe_context(), data);
-}
-
-
-
-
-
-WRITE8_MEMBER(xavix_state::xavix_75f7_w)
-{
- logerror("%s: xavix_75f7_w %02x\n", machine().describe_context(), data);
-}
-
-READ8_MEMBER(xavix_state::xavix_75f8_r)
-{
- logerror("%s: xavix_75f8_r\n", machine().describe_context());
- return m_75f8;
-}
-
-WRITE8_MEMBER(xavix_state::xavix_75f8_w)
-{
- // expected to return data written
- m_75f8 = data;
- logerror("%s: xavix_75f8_w %02x\n", machine().describe_context(), data);
-}
-
-WRITE8_MEMBER(xavix_state::xavix_75f9_w)
-{
- logerror("%s: xavix_75f9_w %02x\n", machine().describe_context(), data);
-}
-
-WRITE8_MEMBER(xavix_state::xavix_75fe_w)
-{
- logerror("%s: xavix_75fe_w %02x\n", machine().describe_context(), data);
-}
-
-WRITE8_MEMBER(xavix_state::xavix_75ff_w)
-{
- logerror("%s: xavix_75ff_w %02x\n", machine().describe_context(), data);
-}
-
-READ8_MEMBER(xavix_state::xavix_75f9_r)
-{
- logerror("%s: xavix_75f9_r\n", machine().describe_context());
- return 0x00;
-}
-
-READ8_MEMBER(xavix_state::xavix_io_0_r)
-{
- return m_in0->read();
-}
-
-READ8_MEMBER(xavix_state::xavix_io_1_r)
-{
- return m_in1->read();
-}
-
-READ8_MEMBER(xavix_state::xavix_75f4_r)
-{
- // used with 75f0
- return 0xff;
-}
-
-READ8_MEMBER(xavix_state::xavix_75f5_r)
-{
- // used with 75f1
- return 0xff;
-}
-
-READ8_MEMBER(xavix_state::mult_r)
-{
- return m_multresults[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
-
- if (offset == 2)
{
- // assume 0 is upper bits, might be 'mode' instead, check
- uint16_t param1 = (m_multparams[0]<<8) | (m_multparams[1]);
- uint8_t param2 = (m_multparams[2]);
-
- uint16_t result = param1*param2;
-
- m_multresults[1] = (result>>8)&0xff;
- m_multresults[0] = result&0xff;
+ return m_lowbus->read8(space, offset&0x7fff);
}
}
-WRITE8_MEMBER(xavix_state::vid_dma_params_1_w)
-{
- m_vid_dma_param1[offset] = data;
-}
-
-WRITE8_MEMBER(xavix_state::vid_dma_params_2_w)
+WRITE8_MEMBER(xavix_state::main_w)
{
- m_vid_dma_param2[offset] = data;
-}
-
-WRITE8_MEMBER(xavix_state::vid_dma_trigger_w)
-{
- uint16_t len = data & 0x07;
- uint16_t src = (m_vid_dma_param1[1]<<8) | m_vid_dma_param1[0];
- uint16_t dst = (m_vid_dma_param2[0]<<8);
- dst += 0x6000;
-
- uint8_t unk = m_vid_dma_param2[1];
-
- logerror("%s: vid_dma_trigger_w with trg %02x size %04x src %04x dest %04x unk (%02x)\n", machine().describe_context(), data & 0xf8, len,src,dst,unk);
-
- if (unk)
- {
- fatalerror("m_vid_dma_param2[1] != 0x00 (is %02x)\n", m_vid_dma_param2[1]);
- }
-
- if (len == 0x00)
- {
- len = 0x08;
- logerror(" (length was 0x0, assuming 0x8)\n");
- }
-
- len = len << 8;
-
- address_space& dmaspace = m_maincpu->space(AS_PROGRAM);
-
- if (data & 0x40)
+ if (offset & 0x8000)
{
- for (int i = 0; i < len; i++)
- {
- uint8_t dat = dmaspace.read_byte(src + i);
- dmaspace.write_byte(dst + i, dat);
- }
- }
-}
-
-READ8_MEMBER(xavix_state::vid_dma_trigger_r)
-{
- // expects bit 0x40 to clear in most cases
- return 0x00;
-}
-
-READ8_MEMBER(xavix_state::pal_ntsc_r)
-{
- // only seen 0x10 checked in code
- // in monster truck the tile base address gets set based on this, there are 2 copies of the test screen in rom, one for pal, one for ntsc, see 1854c
- // likewise card night has entirely different tilesets for each region title
- return m_region->read();
-}
-
-WRITE8_MEMBER(xavix_state::xavix_6fc0_w) // also related to tilemap 1?
-{
- logerror("%s: xavix_6fc0_w data %02x\n", machine().describe_context(), data);
-}
-
-WRITE8_MEMBER(xavix_state::tmap1_regs_w)
-{
- /*
- 0x0 pointer to address where tile data is
- it gets set to 0x40 in monster truck test mode, which is outside of ram but test mode requires a fixed 'column scan' layout
- so that might be special
-
- 0x1 pointer to middle tile bits (if needed, depends on mode) (usually straight after the ram needed for above)
-
- 0x2 pointer to tile highest tile bits (if needed, depends on mode) (usually straight after the ram needed for above)
-
- 0x3 --tt bbb- - = ? tt = tile/tilemap size b = bpp (0x36 xavix logo, 0x3c title screen, 0x36 course select)
-
- 0x4 and 0x5 are scroll
-
- 0x6 pppp ---- p = palette - = ? (0x02 xavix logo, 0x01 course select)
-
- 0x7 could be mode (16x16, 8x8 etc.)
- 0x00 is disabled?
- 0x80 means 16x16 tiles
- 0x81 might be 8x8 tiles
- 0x93 course / mode select bg / ingame (weird addressing?)
-
-
- */
-
- /*
- 6aff base registers
- -- ingame
-
- ae 80
- 02 80
- 02 90
- 02 a0
- 02 b0
- 02 c0
- 02 d0
- 02 e0
-
- 02 00
- 04 80
- 04 90
- 04 a0
- 04 b0
- 04 c0
- 04 d0
- 04 e0
-
- -- menu
- af 80
- 27 80
- 27 90
- 27 a0
- 27 b0
- 27 c0
- 27 d0
- 27 e0
-
- 27 00
- 00 80
- 00 90
- 00 a0
- 00 b0
- 00 c0
- 00 d0
- 00 e0
- */
-
-
- if ((offset != 0x4) && (offset != 0x5))
- {
- logerror("%s: tmap1_regs_w offset %02x data %02x\n", machine().describe_context(), offset, data);
- }
-
- COMBINE_DATA(&m_tmap1_regs[offset]);
-}
-
-WRITE8_MEMBER(xavix_state::xavix_6fd8_w) // also related to tilemap 2?
-{
- // possibly just a mirror of tmap2_regs_w, at least it writes 0x04 here which would be the correct
- // base address to otherwise write at tmap2_regs_w offset 0
-// tmap2_regs_w(space,offset,data);
-
- logerror("%s: xavix_6fd8_w data %02x\n", machine().describe_context(), data);
-}
-
-WRITE8_MEMBER(xavix_state::tmap2_regs_w)
-{
- // same as above but for 2nd tilemap
- if ((offset != 0x4) && (offset != 0x5))
- {
- //logerror("%s: tmap2_regs_w offset %02x data %02x\n", machine().describe_context(), offset, data);
- }
-
- COMBINE_DATA(&m_tmap2_regs[offset]);
-}
-
-READ8_MEMBER(xavix_state::tmap2_regs_r)
-{
- // does this return the same data or a status?
-
- logerror("%s: tmap2_regs_r offset %02x\n", offset, machine().describe_context());
- return m_tmap2_regs[offset];
-}
-
-READ8_MEMBER(xavix_state::xavix_4000_r)
-{
- if (offset < 0x100)
- {
- return ((offset>>4) | (offset<<4));
+ logerror("write to ROM area?\n");
}
else
{
- return 0x00;
+ m_lowbus->write8(space, offset & 0x7fff, data);
}
}
-READ8_MEMBER(xavix_state::irq_source_r)
-{
- /* the 2nd IRQ routine (regular IRQ, not NMI?) reads here before deciding what to do
-
- the following bits have been seen to be checked (active low?)
-
- 0x40 - Monster Truck - stuff with 6ffb 6fd6 and 6ff8
- 0x20 - most games (but not Monster Truck) - DMA related?
- 0x10 - card night + monster truck - 7c00 related? (increases 16-bit counter in ram stores 0xc1 at 7c00)
- 0x08 - several games - Input related (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 - Monster Truck - loads/stores 7b81
- */
- logerror("%s: irq_source_r\n", machine().describe_context());
- return 0xff;
-}
+// DATA reads from 0x8000-0xffff are banked by byte 0xff of 'ram' (this is handled in the CPU core)
-WRITE8_MEMBER(xavix_state::irq_source_w)
+void xavix_state::xavix_map(address_map &map)
{
- logerror("%s: irq_source_w %02x\n", machine().describe_context(), data);
- // cleared on startup in monster truck, no purpose?
+ map(0x000000, 0xffffff).rw(this, FUNC(xavix_state::main_r), FUNC(xavix_state::main_w));
}
-
-// DATA reads from 0x8000-0xffff are banked by byte 0xff of 'ram' (this is handled in the CPU core)
-
-void xavix_state::xavix_map(address_map &map)
+void xavix_state::xavix_lowbus_map(address_map &map)
{
- map(0x000000, 0x0001ff).ram();
- map(0x000200, 0x003fff).ram().share("mainram");
+ map(0x0000, 0x01ff).ram();
+ map(0x0200, 0x3fff).ram().share("mainram");
// this might not be a real area, the tilemap base register gets set to 0x40 in monster truck service mode, and expects a fixed layout.
// As that would point at this address maybe said layout is being read from here, or maybe it's just a magic tilemap register value that doesn't read address space at all.
- map(0x004000, 0x0041ff).r(this, FUNC(xavix_state::xavix_4000_r));
+ map(0x4000, 0x41ff).r(this, FUNC(xavix_state::xavix_4000_r));
// 6xxx ranges are the video hardware
- // appears to be 256 sprites (shares will be renamed once their purpose is known)
- map(0x006000, 0x0060ff).ram().share("spr_attr0");
- map(0x006100, 0x0061ff).ram().share("spr_attr1");
- map(0x006200, 0x0062ff).ram().share("spr_ypos"); // cleared to 0x80 by both games, maybe enable registers?
- map(0x006300, 0x0063ff).ram().share("spr_xpos");
- map(0x006400, 0x0064ff).ram(); // 6400 range gets populated in some cases, but it seems to be more like work ram, data doesn't matter and must be ignored?
- map(0x006500, 0x0065ff).ram().share("spr_addr_lo");
- map(0x006600, 0x0066ff).ram().share("spr_addr_md");
- map(0x006700, 0x0067ff).ram().share("spr_addr_hi");
- map(0x006800, 0x0068ff).ram().share("palram1"); // written with 6900
- map(0x006900, 0x0069ff).ram().share("palram2"); // startup (taitons1)
- map(0x006a00, 0x006a1f).ram().share("spr_attra"); // test mode, pass flag 0x20
-
-
- map(0x006fc0, 0x006fc0).w(this, FUNC(xavix_state::xavix_6fc0_w)); // startup (maybe this is a mirror of tmap1_regs_w)
-
- map(0x006fc8, 0x006fcf).w(this, FUNC(xavix_state::tmap1_regs_w)); // video registers
-
- map(0x006fd0, 0x006fd7).rw(this, FUNC(xavix_state::tmap2_regs_r), FUNC(xavix_state::tmap2_regs_w));
- map(0x006fd8, 0x006fd8).w(this, FUNC(xavix_state::xavix_6fd8_w)); // startup (mirror of tmap2_regs_w?)
-
- map(0x006fe0, 0x006fe0).rw(this, FUNC(xavix_state::vid_dma_trigger_r), FUNC(xavix_state::vid_dma_trigger_w)); // after writing to 6fe1/6fe2 and 6fe5/6fe6 rad_mtrk writes 0x43/0x44 here then polls on 0x40 (see function call at c273) write values are hardcoded, similar code at 18401
- map(0x006fe1, 0x006fe2).w(this, FUNC(xavix_state::vid_dma_params_1_w));
- map(0x006fe5, 0x006fe6).w(this, FUNC(xavix_state::vid_dma_params_2_w));
+ // appears to be 256 sprites
+ map(0x6000, 0x60ff).ram().share("spr_attr0");
+ map(0x6100, 0x61ff).ram().share("spr_attr1");
+ map(0x6200, 0x62ff).ram().share("spr_ypos"); // cleared to 0x80 by both games, maybe enable registers?
+ map(0x6300, 0x63ff).ram().share("spr_xpos");
+ map(0x6400, 0x64ff).ram(); // 6400 range gets populated in some cases, but it seems to be more like work ram, data doesn't matter and must be ignored?
+ map(0x6500, 0x65ff).ram().share("spr_addr_lo");
+ map(0x6600, 0x66ff).ram().share("spr_addr_md");
+ map(0x6700, 0x67ff).ram().share("spr_addr_hi");
+ map(0x6800, 0x68ff).ram().share("palram1"); // written with 6900
+ map(0x6900, 0x69ff).ram().share("palram2"); // startup (taitons1)
+ map(0x6a00, 0x6a1f).ram().share("spr_attra"); // test mode, pass flag 0x20
+
+ map(0x6fc0, 0x6fc0).w(this, FUNC(xavix_state::xavix_6fc0_w)); // startup (maybe this is a mirror of tmap1_regs_w)
+
+ map(0x6fc8, 0x6fcf).w(this, FUNC(xavix_state::tmap1_regs_w)); // video registers
+
+ map(0x6fd0, 0x6fd7).rw(this, FUNC(xavix_state::tmap2_regs_r), FUNC(xavix_state::tmap2_regs_w));
+ map(0x6fd8, 0x6fd8).w(this, FUNC(xavix_state::xavix_6fd8_w)); // startup (mirror of tmap2_regs_w?)
+
+ map(0x6fe0, 0x6fe0).rw(this, FUNC(xavix_state::vid_dma_trigger_r), FUNC(xavix_state::vid_dma_trigger_w)); // after writing to 6fe1/6fe2 and 6fe5/6fe6 rad_mtrk writes 0x43/0x44 here then polls on 0x40 (see function call at c273) write values are hardcoded, similar code at 18401
+ map(0x6fe1, 0x6fe2).w(this, FUNC(xavix_state::vid_dma_params_1_w));
+ map(0x6fe5, 0x6fe6).w(this, FUNC(xavix_state::vid_dma_params_2_w));
// function in rad_mtrk at 0184b7 uses this
- map(0x006fe8, 0x006fe8).ram(); // r/w tested
- map(0x006fe9, 0x006fe9).ram(); // r/w tested
- //AM_RANGE(0x006fea, 0x006fea) AM_WRITENOP
+ map(0x6fe8, 0x6fe8).rw(this, FUNC(xavix_state::xavix_6fe8_r), FUNC(xavix_state::xavix_6fe8_w)); // r/w tested
+ map(0x6fe9, 0x6fe9).rw(this, FUNC(xavix_state::xavix_6fe9_r), FUNC(xavix_state::xavix_6fe9_w)); // r/w tested
+ map(0x6fea, 0x6fea).w(this, FUNC(xavix_state::xavix_6fea_w));
- map(0x006ff0, 0x006ff0).rw(this, FUNC(xavix_state::xavix_6ff0_r), FUNC(xavix_state::xavix_6ff0_w)); // r/w tested
- //AM_RANGE(0x006ff1, 0x006ff1) AM_WRITENOP // startup - cleared in interrupt 0
- //AM_RANGE(0x006ff2, 0x006ff2) AM_WRITENOP // set to 07 after clearing above things in interrupt 0
+ map(0x6ff0, 0x6ff0).rw(this, FUNC(xavix_state::xavix_6ff0_r), FUNC(xavix_state::xavix_6ff0_w)); // r/w tested
+ map(0x6ff1, 0x6ff1).w(this, FUNC(xavix_state::xavix_6ff1_w)); // startup - cleared in interrupt 0
+ map(0x6ff2, 0x6ff2).w(this, FUNC(xavix_state::xavix_6ff2_w)); // set to 07 after clearing above things in interrupt 0
- map(0x006ff8, 0x006ff8).rw(this, FUNC(xavix_state::xavix_6ff8_r), FUNC(xavix_state::xavix_6ff8_w)); // always seems to be a read/store or read/modify/store
- map(0x006ff9, 0x006ff9).r(this, FUNC(xavix_state::pal_ntsc_r));
+ map(0x6ff8, 0x6ff8).rw(this, FUNC(xavix_state::xavix_6ff8_r), FUNC(xavix_state::xavix_6ff8_w)); // always seems to be a read/store or read/modify/store
+ map(0x6ff9, 0x6ff9).r(this, FUNC(xavix_state::pal_ntsc_r));
+ map(0x6ffa, 0x6ffa).w(this, FUNC(xavix_state::xavix_6ffa_w));
+ map(0x6ffb, 0x6ffb).w(this, FUNC(xavix_state::xavix_6ffb_w)); // increases / decreases when you jump in snowboard, maybe raster irq pos or part of a clipping window?
// 7xxx ranges system controller?
-
- map(0x0075f0, 0x0075f0).rw(this, FUNC(xavix_state::xavix_75f0_r), FUNC(xavix_state::xavix_75f0_w)); // r/w tested read/written 8 times in a row
- map(0x0075f1, 0x0075f1).rw(this, FUNC(xavix_state::xavix_75f1_r), FUNC(xavix_state::xavix_75f1_w)); // r/w tested read/written 8 times in a row
- map(0x0075f3, 0x0075f3).ram();
- map(0x0075f4, 0x0075f4).r(this, FUNC(xavix_state::xavix_75f4_r)); // related to 75f0 (read after writing there - rad_mtrk)
- map(0x0075f5, 0x0075f5).r(this, FUNC(xavix_state::xavix_75f5_r)); // related to 75f1 (read after writing there - rad_mtrk)
+ map(0x75f0, 0x75f0).rw(this, FUNC(xavix_state::xavix_75f0_r), FUNC(xavix_state::xavix_75f0_w)); // r/w tested read/written 8 times in a row
+ map(0x75f1, 0x75f1).rw(this, FUNC(xavix_state::xavix_75f1_r), FUNC(xavix_state::xavix_75f1_w)); // r/w tested read/written 8 times in a row
+ map(0x75f3, 0x75f3).ram();
+ map(0x75f4, 0x75f4).r(this, FUNC(xavix_state::xavix_75f4_r)); // related to 75f0 (read after writing there - rad_mtrk)
+ map(0x75f5, 0x75f5).r(this, FUNC(xavix_state::xavix_75f5_r)); // related to 75f1 (read after writing there - rad_mtrk)
// taitons1 after 75f7/75f8
- map(0x0075f6, 0x0075f6).rw(this, FUNC(xavix_state::xavix_75f6_r), FUNC(xavix_state::xavix_75f6_w)); // r/w tested
+ map(0x75f6, 0x75f6).rw(this, FUNC(xavix_state::xavix_75f6_r), FUNC(xavix_state::xavix_75f6_w)); // r/w tested
// taitons1 written as a pair
- map(0x0075f7, 0x0075f7).w(this, FUNC(xavix_state::xavix_75f7_w));
- map(0x0075f8, 0x0075f8).rw(this, FUNC(xavix_state::xavix_75f8_r), FUNC(xavix_state::xavix_75f8_w)); // r/w tested
+ map(0x75f7, 0x75f7).w(this, FUNC(xavix_state::xavix_75f7_w));
+ map(0x75f8, 0x75f8).rw(this, FUNC(xavix_state::xavix_75f8_r), FUNC(xavix_state::xavix_75f8_w)); // r/w tested
// taitons1 written after 75f6, then read
- map(0x0075f9, 0x0075f9).rw(this, FUNC(xavix_state::xavix_75f9_r), FUNC(xavix_state::xavix_75f9_w));
+ map(0x75f9, 0x75f9).rw(this, FUNC(xavix_state::xavix_75f9_r), FUNC(xavix_state::xavix_75f9_w));
// at another time
- map(0x0075fa, 0x0075fa).rw(this, FUNC(xavix_state::xavix_75fa_r), FUNC(xavix_state::xavix_75fa_w)); // r/w tested
- map(0x0075fb, 0x0075fb).rw(this, FUNC(xavix_state::xavix_75fb_r), FUNC(xavix_state::xavix_75fb_w)); // r/w tested
- map(0x0075fc, 0x0075fc).rw(this, FUNC(xavix_state::xavix_75fc_r), FUNC(xavix_state::xavix_75fc_w)); // r/w tested
- map(0x0075fd, 0x0075fd).rw(this, FUNC(xavix_state::xavix_75fd_r), FUNC(xavix_state::xavix_75fd_w)); // r/w tested
- map(0x0075fe, 0x0075fe).w(this, FUNC(xavix_state::xavix_75fe_w));
+ map(0x75fa, 0x75fa).rw(this, FUNC(xavix_state::xavix_75fa_r), FUNC(xavix_state::xavix_75fa_w)); // r/w tested
+ map(0x75fb, 0x75fb).rw(this, FUNC(xavix_state::xavix_75fb_r), FUNC(xavix_state::xavix_75fb_w)); // r/w tested
+ map(0x75fc, 0x75fc).rw(this, FUNC(xavix_state::xavix_75fc_r), FUNC(xavix_state::xavix_75fc_w)); // r/w tested
+ map(0x75fd, 0x75fd).rw(this, FUNC(xavix_state::xavix_75fd_r), FUNC(xavix_state::xavix_75fd_w)); // r/w tested
+ map(0x75fe, 0x75fe).w(this, FUNC(xavix_state::xavix_75fe_w));
// taitons1 written other 75xx operations
- map(0x0075ff, 0x0075ff).w(this, FUNC(xavix_state::xavix_75ff_w));
+ map(0x75ff, 0x75ff).w(this, FUNC(xavix_state::xavix_75ff_w));
- //AM_RANGE(0x007810, 0x007810) AM_WRITENOP // startup
+ map(0x7810, 0x7810).w(this, FUNC(xavix_state::xavix_7810_w)); // startup
- //AM_RANGE(0x007900, 0x007900) AM_WRITE(xavix_7900_w) // startup
- //AM_RANGE(0x007902, 0x007902) AM_WRITENOP // startup
+ map(0x7900, 0x7900).w(this, FUNC(xavix_state::xavix_7900_w));
+ map(0x7901, 0x7901).w(this, FUNC(xavix_state::xavix_7901_w));
+ map(0x7902, 0x7902).w(this, FUNC(xavix_state::xavix_7902_w));
// DMA trigger for below (written after the others) waits on status of bit 1 in a loop
- map(0x007980, 0x007980).rw(this, FUNC(xavix_state::dma_trigger_r), FUNC(xavix_state::dma_trigger_w));
+ map(0x7980, 0x7980).rw(this, FUNC(xavix_state::dma_trigger_r), FUNC(xavix_state::dma_trigger_w));
// DMA source
- map(0x007981, 0x007981).w(this, FUNC(xavix_state::rom_dmasrc_lo_w));
- map(0x007982, 0x007982).w(this, FUNC(xavix_state::rom_dmasrc_md_w));
- map(0x007983, 0x007983).w(this, FUNC(xavix_state::rom_dmasrc_hi_w));
+ map(0x7981, 0x7981).w(this, FUNC(xavix_state::rom_dmasrc_lo_w));
+ map(0x7982, 0x7982).w(this, FUNC(xavix_state::rom_dmasrc_md_w));
+ map(0x7983, 0x7983).w(this, FUNC(xavix_state::rom_dmasrc_hi_w));
// DMA dest
- map(0x007984, 0x007984).w(this, FUNC(xavix_state::rom_dmadst_lo_w));
- map(0x007985, 0x007985).w(this, FUNC(xavix_state::rom_dmadst_hi_w));
+ map(0x7984, 0x7984).w(this, FUNC(xavix_state::rom_dmadst_lo_w));
+ map(0x7985, 0x7985).w(this, FUNC(xavix_state::rom_dmadst_hi_w));
// DMA length
- map(0x007986, 0x007986).w(this, FUNC(xavix_state::rom_dmalen_lo_w));
- map(0x007987, 0x007987).w(this, FUNC(xavix_state::rom_dmalen_hi_w));
+ map(0x7986, 0x7986).w(this, FUNC(xavix_state::rom_dmalen_lo_w));
+ map(0x7987, 0x7987).w(this, FUNC(xavix_state::rom_dmalen_hi_w));
// GPIO stuff
- map(0x007a00, 0x007a00).r(this, FUNC(xavix_state::xavix_io_0_r));
- map(0x007a01, 0x007a01).r(this, FUNC(xavix_state::xavix_io_1_r)); //AM_WRITENOP // startup (taitons1)
- //AM_RANGE(0x007a02, 0x007a02) AM_WRITENOP // startup, gets set to 20, 7a00 is then also written with 20
- //AM_RANGE(0x007a03, 0x007a03) AM_READNOP AM_WRITENOP // startup (gets set to 84 which is the same as the bits checked on 7a01, possible port direction register?)
+ map(0x7a00, 0x7a00).rw(this, FUNC(xavix_state::xavix_io_0_r),FUNC(xavix_state::xavix_7a00_w));
+ map(0x7a01, 0x7a01).rw(this, FUNC(xavix_state::xavix_io_1_r),FUNC(xavix_state::xavix_7a01_w)); // startup (taitons1)
+ map(0x7a02, 0x7a02).rw(this, FUNC(xavix_state::xavix_7a02_r),FUNC(xavix_state::xavix_7a02_w)); // startup, gets set to 20, 7a00 is then also written with 20
+ map(0x7a03, 0x7a03).rw(this, FUNC(xavix_state::xavix_7a03_r),FUNC(xavix_state::xavix_7a03_w)); // startup (gets set to 84 which is the same as the bits checked on 7a01, possible port direction register?)
+
+ map(0x7a80, 0x7a80).w(this, FUNC(xavix_state::xavix_7a80_w)); // still IO? ADC related?
- //AM_RANGE(0x007a80, 0x007a80) AM_WRITENOP
+ map(0x7b00, 0x7b00).w(this, FUNC(xavix_state::xavix_7b00_w)); // rad_snow (not often)
- //AM_RANGE(0x007b80, 0x007b80) AM_READNOP
- //AM_RANGE(0x007b81, 0x007b81) AM_WRITENOP // every frame?
- //AM_RANGE(0x007b82, 0x007b82) AM_WRITENOP
+ map(0x7b80, 0x7b80).rw(this, FUNC(xavix_state::xavix_7b80_r), FUNC(xavix_state::xavix_7b80_w)); // rad_snow (not often)
+ map(0x7b81, 0x7b81).w(this, FUNC(xavix_state::xavix_7b81_w)); // written (often, m_trck, analog related?)
- //AM_RANGE(0x007c01, 0x007c01) AM_RAM // r/w tested
- //AM_RANGE(0x007c02, 0x007c02) AM_WRITENOP // once
+ map(0x7c00, 0x7c00).w(this, FUNC(xavix_state::xavix_7c00_w));
+ map(0x7c01, 0x7c01).rw(this, FUNC(xavix_state::xavix_7c01_r), FUNC(xavix_state::xavix_7c01_w)); // r/w tested
+ map(0x7c02, 0x7c02).w(this, FUNC(xavix_state::xavix_7c02_w));
// this is a multiplication chip
- map(0x007ff2, 0x007ff4).w(this, FUNC(xavix_state::mult_param_w));
- map(0x007ff5, 0x007ff6).r(this, FUNC(xavix_state::mult_r));
+ map(0x7ff2, 0x7ff4).w(this, FUNC(xavix_state::mult_param_w));
+ map(0x7ff5, 0x7ff6).rw(this, FUNC(xavix_state::mult_r), FUNC(xavix_state::mult_w));
// maybe irq enable, written after below
- map(0x007ff9, 0x007ff9).w(this, FUNC(xavix_state::irq_enable_w)); // interrupt related, but probalby not a simple 'enable' otherwise interrupts happen before we're ready for them.
+ map(0x7ff9, 0x7ff9).w(this, FUNC(xavix_state::irq_enable_w)); // interrupt related, but probalby not a simple 'enable' otherwise interrupts happen before we're ready for them.
// an IRQ vector (nmi?)
- map(0x007ffa, 0x007ffa).w(this, FUNC(xavix_state::irq_vector0_lo_w));
- map(0x007ffb, 0x007ffb).w(this, FUNC(xavix_state::irq_vector0_hi_w));
+ map(0x7ffa, 0x7ffa).w(this, FUNC(xavix_state::irq_vector0_lo_w));
+ map(0x7ffb, 0x7ffb).w(this, FUNC(xavix_state::irq_vector0_hi_w));
- map(0x007ffc, 0x007ffc).rw(this, FUNC(xavix_state::irq_source_r), FUNC(xavix_state::irq_source_w));
+ map(0x7ffc, 0x7ffc).rw(this, FUNC(xavix_state::irq_source_r), FUNC(xavix_state::irq_source_w));
// an IRQ vector (irq?)
- map(0x007ffe, 0x007ffe).w(this, FUNC(xavix_state::irq_vector1_lo_w));
- map(0x007fff, 0x007fff).w(this, FUNC(xavix_state::irq_vector1_hi_w));
-
-// rom is installed in init due to different rom sizes and mirroring required
-// AM_RANGE(0x008000, 0x7fffff) AM_ROM AM_REGION("bios", 0x008000) AM_MIRROR(0x800000) // rad_mtrk relies on rom mirroring
+ map(0x7ffe, 0x7ffe).w(this, FUNC(xavix_state::irq_vector1_lo_w));
+ map(0x7fff, 0x7fff).w(this, FUNC(xavix_state::irq_vector1_hi_w));
}
static INPUT_PORTS_START( xavix )
@@ -1731,7 +441,6 @@ INPUT_PORTS_END
*/
-
static INPUT_PORTS_START( rad_mtrk )
PORT_INCLUDE(xavix)
@@ -1867,8 +576,6 @@ static const gfx_layout char16layout8bpp =
16*16*8
};
-
-
static GFXDECODE_START( xavix )
GFXDECODE_ENTRY( "bios", 0, charlayout, 0, 16 )
GFXDECODE_ENTRY( "bios", 0, char16layout, 0, 16 )
@@ -1877,82 +584,6 @@ static GFXDECODE_START( xavix )
GFXDECODE_END
-void xavix_state::machine_start()
-{
-}
-
-void xavix_state::machine_reset()
-{
- m_rom_dmasrc_lo_data = 0;
- m_rom_dmasrc_md_data = 0;
- m_rom_dmasrc_hi_data = 0;
-
- m_rom_dmadst_lo_data = 0;
- m_rom_dmadst_hi_data = 0;
-
- m_rom_dmalen_lo_data = 0;
- m_rom_dmalen_hi_data = 0;
-
- m_irq_enable_data = 0;
- m_irq_vector0_lo_data = 0;
- m_irq_vector0_hi_data = 0;
- m_irq_vector1_lo_data = 0;
- m_irq_vector1_hi_data = 0;
-
- m_6ff0 = 0;
- m_6ff8 = 0;
-
- m_75f0 = 0;
- m_75f1 = 0;
-
- m_75f6 = 0;
- m_75f8 = 0;
- m_75fa = 0;
- m_75fb = 0;
- m_75fc = 0;
- m_75fd = 0;
-
- for (int i = 0; i < 3; i++)
- m_multparams[i] = 0;
-
- for (int i = 0; i < 2; i++)
- m_multresults[i] = 0;
-
- for (int i = 0; i < 2; i++)
- {
- m_vid_dma_param1[i] = 0;
- m_vid_dma_param2[i] = 0;
- }
-
- for (int i = 0; i < 8; i++)
- {
- m_tmap1_regs[i] = 0;
- m_tmap2_regs[i] = 0;
- }
-}
-
-typedef device_delegate<uint8_t (int which, int half)> xavix_interrupt_vector_delegate;
-
-uint8_t xavix_state::get_vectors(int which, int half)
-{
-// logerror("get_vectors %d %d\n", which, half);
-
- if (which == 0) // irq?
- {
- if (half == 0)
- return m_irq_vector0_hi_data;
- else
- return m_irq_vector0_lo_data;
- }
- else
- {
- if (half == 0)
- return m_irq_vector1_hi_data;
- else
- return m_irq_vector1_lo_data;
- }
-}
-
MACHINE_CONFIG_START(xavix_state::xavix)
/* basic machine hardware */
@@ -1964,6 +595,13 @@ MACHINE_CONFIG_START(xavix_state::xavix)
MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", xavix_state, scanline_cb, "screen", 0, 1)
+ MCFG_DEVICE_ADD("lowbus", ADDRESS_MAP_BANK, 0)
+ MCFG_DEVICE_PROGRAM_MAP(xavix_lowbus_map)
+ MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE)
+ MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8)
+ MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(24)
+ MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000)
+
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
@@ -1991,14 +629,10 @@ MACHINE_CONFIG_START(xavix_state::xavixp)
MCFG_SCREEN_REFRESH_RATE(50)
MACHINE_CONFIG_END
-DRIVER_INIT_MEMBER(xavix_state,xavix)
+DRIVER_INIT_MEMBER(xavix_state, xavix)
{
- m_rgnlen = memregion("bios")->bytes();
+ m_rgnlen = memregion("bios")->bytes();
m_rgn = memregion("bios")->base();
-
- // mirror the rom across the space
- address_space &space = m_maincpu->space(AS_PROGRAM);
- space.install_rom(0x8000, m_rgnlen, ((~(m_rgnlen-1))<<1)&0xffffff, m_rgn+0x8000);
}
DRIVER_INIT_MEMBER(xavix_state, taitons1)
diff --git a/src/mame/includes/xavix.h b/src/mame/includes/xavix.h
new file mode 100644
index 00000000000..c755f9bbb48
--- /dev/null
+++ b/src/mame/includes/xavix.h
@@ -0,0 +1,266 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood
+#ifndef MAME_INCLUDES_XAVIX_H
+#define MAME_INCLUDES_XAVIX_H
+
+#include "cpu/m6502/xavix.h"
+#include "machine/timer.h"
+#include "screen.h"
+#include "speaker.h"
+#include "machine/bankdev.h"
+
+
+class xavix_state : public driver_device
+{
+public:
+ xavix_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu"),
+ m_mainram(*this, "mainram"),
+ m_spr_attr0(*this, "spr_attr0"),
+ m_spr_attr1(*this, "spr_attr1"),
+ m_spr_ypos(*this, "spr_ypos"),
+ m_spr_xpos(*this, "spr_xpos"),
+ m_spr_addr_lo(*this, "spr_addr_lo"),
+ m_spr_addr_md(*this, "spr_addr_md"),
+ m_spr_addr_hi(*this, "spr_addr_hi"),
+ m_palram1(*this, "palram1"),
+ m_palram2(*this, "palram2"),
+ m_spr_attra(*this, "spr_attra"),
+ m_palette(*this, "palette"),
+ m_in0(*this, "IN0"),
+ m_in1(*this, "IN1"),
+ m_region(*this, "REGION"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_alt_addressing(0),
+ m_lowbus(*this, "lowbus")
+ { }
+
+ // screen updates
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+
+ void xavix(machine_config &config);
+ void xavixp(machine_config &config);
+
+ void xavix_map(address_map &map);
+ void xavix_lowbus_map(address_map &map);
+
+ INTERRUPT_GEN_MEMBER(interrupt);
+ TIMER_DEVICE_CALLBACK_MEMBER(scanline_cb);
+
+ DECLARE_DRIVER_INIT(xavix);
+ DECLARE_DRIVER_INIT(taitons1);
+ DECLARE_DRIVER_INIT(rad_box);
+
+protected:
+ // driver_device overrides
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+
+ virtual void video_start() override;
+
+private:
+
+ DECLARE_READ8_MEMBER(main_r);
+ DECLARE_WRITE8_MEMBER(main_w);
+
+ DECLARE_WRITE8_MEMBER(xavix_7900_w);
+ DECLARE_WRITE8_MEMBER(xavix_7901_w);
+ DECLARE_WRITE8_MEMBER(xavix_7902_w);
+
+ DECLARE_WRITE8_MEMBER(xavix_7a80_w);
+ DECLARE_WRITE8_MEMBER(xavix_7b00_w);
+ DECLARE_READ8_MEMBER(xavix_7b80_r);
+ DECLARE_WRITE8_MEMBER(xavix_7b80_w);
+ DECLARE_WRITE8_MEMBER(xavix_7b81_w);
+
+ DECLARE_WRITE8_MEMBER(xavix_7810_w);
+
+ DECLARE_WRITE8_MEMBER(dma_trigger_w);
+ DECLARE_WRITE8_MEMBER(rom_dmasrc_lo_w);
+ DECLARE_WRITE8_MEMBER(rom_dmasrc_md_w);
+ DECLARE_WRITE8_MEMBER(rom_dmasrc_hi_w);
+ DECLARE_WRITE8_MEMBER(rom_dmadst_lo_w);
+ DECLARE_WRITE8_MEMBER(rom_dmadst_hi_w);
+ DECLARE_WRITE8_MEMBER(rom_dmalen_lo_w);
+ DECLARE_WRITE8_MEMBER(rom_dmalen_hi_w);
+ DECLARE_READ8_MEMBER(dma_trigger_r);
+
+ DECLARE_WRITE8_MEMBER(vid_dma_params_1_w);
+ DECLARE_WRITE8_MEMBER(vid_dma_params_2_w);
+ DECLARE_WRITE8_MEMBER(vid_dma_trigger_w);
+ DECLARE_READ8_MEMBER(vid_dma_trigger_r);
+
+ DECLARE_READ8_MEMBER(xavix_io_0_r);
+ DECLARE_READ8_MEMBER(xavix_io_1_r);
+ DECLARE_READ8_MEMBER(xavix_7a02_r);
+ DECLARE_READ8_MEMBER(xavix_7a03_r);
+
+ DECLARE_WRITE8_MEMBER(xavix_7a00_w);
+ DECLARE_WRITE8_MEMBER(xavix_7a01_w);
+ DECLARE_WRITE8_MEMBER(xavix_7a02_w);
+ DECLARE_WRITE8_MEMBER(xavix_7a03_w);
+
+ DECLARE_WRITE8_MEMBER(irq_enable_w);
+ DECLARE_WRITE8_MEMBER(irq_vector0_lo_w);
+ DECLARE_WRITE8_MEMBER(irq_vector0_hi_w);
+ DECLARE_WRITE8_MEMBER(irq_vector1_lo_w);
+ DECLARE_WRITE8_MEMBER(irq_vector1_hi_w);
+
+ DECLARE_READ8_MEMBER(irq_source_r);
+ DECLARE_WRITE8_MEMBER(irq_source_w);
+
+ DECLARE_READ8_MEMBER(xavix_6fe8_r);
+ DECLARE_WRITE8_MEMBER(xavix_6fe8_w);
+ DECLARE_READ8_MEMBER(xavix_6fe9_r);
+ DECLARE_WRITE8_MEMBER(xavix_6fe9_w);
+ DECLARE_WRITE8_MEMBER(xavix_6fea_w);
+
+ DECLARE_READ8_MEMBER(xavix_6ff0_r);
+ DECLARE_WRITE8_MEMBER(xavix_6ff0_w);
+
+ DECLARE_WRITE8_MEMBER(xavix_6ff1_w);
+ DECLARE_WRITE8_MEMBER(xavix_6ff2_w);
+
+ DECLARE_READ8_MEMBER(xavix_6ff8_r);
+ DECLARE_WRITE8_MEMBER(xavix_6ff8_w);
+
+ DECLARE_WRITE8_MEMBER(xavix_6ffa_w);
+ DECLARE_WRITE8_MEMBER(xavix_6ffb_w);
+
+ DECLARE_READ8_MEMBER(xavix_75f0_r);
+ DECLARE_WRITE8_MEMBER(xavix_75f0_w);
+
+ DECLARE_READ8_MEMBER(xavix_75f1_r);
+ DECLARE_WRITE8_MEMBER(xavix_75f1_w);
+
+ DECLARE_READ8_MEMBER(xavix_75f4_r);
+ DECLARE_READ8_MEMBER(xavix_75f5_r);
+ DECLARE_READ8_MEMBER(xavix_75f6_r);
+ DECLARE_WRITE8_MEMBER(xavix_75f6_w);
+
+ DECLARE_WRITE8_MEMBER(xavix_75f7_w);
+
+ DECLARE_READ8_MEMBER(xavix_75f8_r);
+ DECLARE_WRITE8_MEMBER(xavix_75f8_w);
+
+ DECLARE_READ8_MEMBER(xavix_75f9_r);
+ DECLARE_WRITE8_MEMBER(xavix_75f9_w);
+
+ DECLARE_READ8_MEMBER(xavix_75fa_r);
+ DECLARE_WRITE8_MEMBER(xavix_75fa_w);
+ DECLARE_READ8_MEMBER(xavix_75fb_r);
+ DECLARE_WRITE8_MEMBER(xavix_75fb_w);
+ DECLARE_READ8_MEMBER(xavix_75fc_r);
+ DECLARE_WRITE8_MEMBER(xavix_75fc_w);
+ DECLARE_READ8_MEMBER(xavix_75fd_r);
+ DECLARE_WRITE8_MEMBER(xavix_75fd_w);
+
+ DECLARE_WRITE8_MEMBER(xavix_75fe_w);
+ DECLARE_WRITE8_MEMBER(xavix_75ff_w);
+
+ DECLARE_WRITE8_MEMBER(xavix_7c00_w);
+ DECLARE_READ8_MEMBER(xavix_7c01_r);
+ DECLARE_WRITE8_MEMBER(xavix_7c01_w);
+ DECLARE_WRITE8_MEMBER(xavix_7c02_w);
+
+ DECLARE_WRITE8_MEMBER(xavix_6fc0_w);
+ DECLARE_WRITE8_MEMBER(tmap1_regs_w);
+ DECLARE_WRITE8_MEMBER(xavix_6fd8_w);
+ DECLARE_WRITE8_MEMBER(tmap2_regs_w);
+ DECLARE_READ8_MEMBER(tmap2_regs_r);
+
+ DECLARE_READ8_MEMBER(pal_ntsc_r);
+
+ DECLARE_READ8_MEMBER(xavix_4000_r);
+
+ DECLARE_READ8_MEMBER(mult_r);
+ DECLARE_WRITE8_MEMBER(mult_w);
+ DECLARE_WRITE8_MEMBER(mult_param_w);
+
+ required_device<cpu_device> m_maincpu;
+
+ uint8_t m_rom_dmasrc_lo_data;
+ uint8_t m_rom_dmasrc_md_data;
+ uint8_t m_rom_dmasrc_hi_data;
+
+ uint8_t m_rom_dmadst_lo_data;
+ uint8_t m_rom_dmadst_hi_data;
+
+ uint8_t m_rom_dmalen_lo_data;
+ uint8_t m_rom_dmalen_hi_data;
+
+ uint8_t m_irq_enable_data;
+ uint8_t m_irq_vector0_lo_data;
+ uint8_t m_irq_vector0_hi_data;
+ uint8_t m_irq_vector1_lo_data;
+ uint8_t m_irq_vector1_hi_data;
+
+ uint8_t m_multparams[3];
+ uint8_t m_multresults[2];
+
+ uint8_t m_vid_dma_param1[2];
+ uint8_t m_vid_dma_param2[2];
+
+ uint8_t m_tmap1_regs[8];
+ uint8_t m_tmap2_regs[8];
+
+ uint8_t m_6fe8;
+ uint8_t m_6fe9;
+
+ uint8_t m_6ff0;
+ uint8_t m_6ff8;
+
+ uint8_t m_75fx[0x10];
+
+ uint8_t m_7c01;
+
+ uint8_t get_vectors(int which, int half);
+
+ required_shared_ptr<uint8_t> m_mainram;
+
+ required_shared_ptr<uint8_t> m_spr_attr0;
+ required_shared_ptr<uint8_t> m_spr_attr1;
+ required_shared_ptr<uint8_t> m_spr_ypos;
+ required_shared_ptr<uint8_t> m_spr_xpos;
+
+ required_shared_ptr<uint8_t> m_spr_addr_lo;
+ required_shared_ptr<uint8_t> m_spr_addr_md;
+ required_shared_ptr<uint8_t> m_spr_addr_hi;
+
+ required_shared_ptr<uint8_t> m_palram1;
+ required_shared_ptr<uint8_t> m_palram2;
+
+ required_shared_ptr<uint8_t> m_spr_attra;
+
+ required_device<palette_device> m_palette;
+
+ required_ioport m_in0;
+ required_ioport m_in1;
+ required_ioport m_region;
+
+ required_device<gfxdecode_device> m_gfxdecode;
+
+ void handle_palette(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ double hue2rgb(double p, double q, double t);
+ void draw_tile(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 opaque);
+ void draw_tilemap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int which);
+ void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+
+ int m_rgnlen;
+ uint8_t* m_rgn;
+
+ // variables used by rendering
+ int m_tmp_dataaddress;
+ int m_tmp_databit;
+ void set_data_address(int address, int bit);
+ uint8_t get_next_bit();
+ uint8_t get_next_byte();
+
+ int get_current_address_byte();
+
+ int m_alt_addressing;
+ required_device<address_map_bank_device> m_lowbus;
+};
+
+#endif // MAME_INCLUDES_XAVIX_H
diff --git a/src/mame/machine/xavix.cpp b/src/mame/machine/xavix.cpp
new file mode 100644
index 00000000000..ff02466b516
--- /dev/null
+++ b/src/mame/machine/xavix.cpp
@@ -0,0 +1,637 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood
+
+#include "emu.h"
+#include "includes/xavix.h"
+
+// general DMA fro ROM, not Video DMA
+WRITE8_MEMBER(xavix_state::dma_trigger_w)
+{
+ if (data & 0x01) // namcons2 writes 0x81, most of the time things write 0x01
+ {
+ logerror("%s: dma_trigger_w (do DMA?) %02x\n", machine().describe_context(), data);
+
+ uint32_t source = (m_rom_dmasrc_hi_data << 16) | (m_rom_dmasrc_md_data << 8) | m_rom_dmasrc_lo_data;
+ uint16_t dest = (m_rom_dmadst_hi_data << 8) | m_rom_dmadst_lo_data;
+ uint16_t len = (m_rom_dmalen_hi_data << 8) | m_rom_dmalen_lo_data;
+
+ source &= m_rgnlen - 1;
+ logerror(" (possible DMA op SRC %08x DST %04x LEN %04x)\n", source, dest, len);
+
+ address_space& destspace = m_maincpu->space(AS_PROGRAM);
+
+ for (int i = 0; i < len; i++)
+ {
+ uint8_t dat = m_rgn[(source + i) & (m_rgnlen - 1)];
+ destspace.write_byte(dest + i, dat);
+ }
+ }
+ else // the interrupt routine writes 0x80 to the trigger, maybe 'clear IRQ?'
+ {
+ logerror("%s: dma_trigger_w (unknown) %02x\n", machine().describe_context(), data);
+ }
+}
+
+WRITE8_MEMBER(xavix_state::rom_dmasrc_lo_w)
+{
+ logerror("%s: rom_dmasrc_lo_w %02x\n", machine().describe_context(), data);
+ m_rom_dmasrc_lo_data = data;
+}
+
+WRITE8_MEMBER(xavix_state::rom_dmasrc_md_w)
+{
+ logerror("%s: rom_dmasrc_md_w %02x\n", machine().describe_context(), data);
+ m_rom_dmasrc_md_data = data;
+}
+
+WRITE8_MEMBER(xavix_state::rom_dmasrc_hi_w)
+{
+ logerror("%s: rom_dmasrc_hi_w %02x\n", machine().describe_context(), data);
+ m_rom_dmasrc_hi_data = data;
+ // this would mean Taito Nostalgia relies on mirroring tho, as it has the high bits set... so could just be wrong
+ logerror(" (DMA ROM source of %02x%02x%02x)\n", m_rom_dmasrc_hi_data, m_rom_dmasrc_md_data, m_rom_dmasrc_lo_data);
+}
+
+WRITE8_MEMBER(xavix_state::rom_dmadst_lo_w)
+{
+ logerror("%s: rom_dmadst_lo_w %02x\n", machine().describe_context(), data);
+ m_rom_dmadst_lo_data = data;
+}
+
+WRITE8_MEMBER(xavix_state::rom_dmadst_hi_w)
+{
+ logerror("%s: rom_dmadst_hi_w %02x\n", machine().describe_context(), data);
+ m_rom_dmadst_hi_data = data;
+
+ logerror(" (DMA dest of %02x%02x)\n", m_rom_dmadst_hi_data, m_rom_dmadst_lo_data);
+}
+
+WRITE8_MEMBER(xavix_state::rom_dmalen_lo_w)
+{
+ logerror("%s: rom_dmalen_lo_w %02x\n", machine().describe_context(), data);
+ m_rom_dmalen_lo_data = data;
+}
+
+WRITE8_MEMBER(xavix_state::rom_dmalen_hi_w)
+{
+ logerror("%s: rom_dmalen_hi_w %02x\n", machine().describe_context(), data);
+ m_rom_dmalen_hi_data = data;
+
+ logerror(" (DMA len of %02x%02x)\n", m_rom_dmalen_hi_data, m_rom_dmalen_lo_data);
+}
+
+READ8_MEMBER(xavix_state::dma_trigger_r)
+{
+ logerror("%s: dma_trigger_r (operation status?)\n", machine().describe_context());
+ return 0x00;
+}
+
+
+
+WRITE8_MEMBER(xavix_state::irq_enable_w)
+{
+ logerror("%s: irq_enable_w %02x\n", machine().describe_context(), data);
+ m_irq_enable_data = data;
+}
+
+WRITE8_MEMBER(xavix_state::irq_vector0_lo_w)
+{
+ logerror("%s: irq_vector0_lo_w %02x\n", machine().describe_context(), data);
+ m_irq_vector0_lo_data = data;
+}
+
+WRITE8_MEMBER(xavix_state::irq_vector0_hi_w)
+{
+ logerror("%s: irq_vector0_hi_w %02x\n", machine().describe_context(), data);
+ m_irq_vector0_hi_data = data;
+}
+
+WRITE8_MEMBER(xavix_state::irq_vector1_lo_w)
+{
+ logerror("%s: irq_vector1_lo_w %02x\n", machine().describe_context(), data);
+ m_irq_vector1_lo_data = data;
+}
+
+WRITE8_MEMBER(xavix_state::irq_vector1_hi_w)
+{
+ logerror("%s: irq_vector1_hi_w %02x\n", machine().describe_context(), data);
+ m_irq_vector1_hi_data = data;
+}
+
+
+WRITE8_MEMBER(xavix_state::xavix_7900_w)
+{
+ logerror("%s: xavix_7900_w %02x (---FIRST WRITE ON STARTUP---)\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_7901_w)
+{
+ logerror("%s: xavix_7901_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_7902_w)
+{
+ logerror("%s: xavix_7902_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_7a80_w)
+{
+ logerror("%s: xavix_7a80_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_7b00_w)
+{
+ logerror("%s: xavix_7b00_w %02x\n", machine().describe_context(), data);
+}
+
+READ8_MEMBER(xavix_state::xavix_7b80_r)
+{
+ logerror("%s: xavix_7b80_r\n", machine().describe_context());
+ return 0xff;
+}
+
+WRITE8_MEMBER(xavix_state::xavix_7b80_w)
+{
+ logerror("%s: xavix_7b80_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_7b81_w)
+{
+ logerror("%s: xavix_7b81_w %02x\n", machine().describe_context(), data);
+}
+
+
+WRITE8_MEMBER(xavix_state::xavix_7810_w)
+{
+ logerror("%s: xavix_7810_w %02x\n", machine().describe_context(), data);
+}
+
+
+TIMER_DEVICE_CALLBACK_MEMBER(xavix_state::scanline_cb)
+{
+/*
+ int scanline = param;
+
+ if (scanline == 200)
+ {
+ if (m_irq_enable_data != 0)
+ m_maincpu->set_input_line(INPUT_LINE_IRQ0,HOLD_LINE);
+ }
+*/
+}
+
+INTERRUPT_GEN_MEMBER(xavix_state::interrupt)
+{
+ // if (m_irq_enable_data != 0)
+ // m_maincpu->set_input_line(INPUT_LINE_IRQ0,HOLD_LINE);
+
+ // this logic is clearly VERY wrong
+
+ if (m_irq_enable_data != 0)
+ {
+ if (m_6ff8)
+ m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
+ }
+}
+
+
+
+READ8_MEMBER(xavix_state::xavix_6ff0_r)
+{
+ //logerror("%s: xavix_6ff0_r\n", machine().describe_context());
+ return m_6ff0;
+}
+
+WRITE8_MEMBER(xavix_state::xavix_6ff0_w)
+{
+ // expected to return data written
+ m_6ff0 = data;
+ //logerror("%s: xavix_6ff0_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_6ff1_w)
+{
+ logerror("%s: xavix_6ff1_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_6ff2_w)
+{
+ logerror("%s: xavix_6ff2_w %02x\n", machine().describe_context(), data);
+}
+
+
+READ8_MEMBER(xavix_state::xavix_6ff8_r)
+{
+ //logerror("%s: xavix_6ff8_r\n", machine().describe_context());
+ return m_6ff8;
+}
+
+WRITE8_MEMBER(xavix_state::xavix_6ff8_w)
+{
+ // I think this is something to do with IRQ ack / enable
+ m_6ff8 = data;
+ logerror("%s: xavix_6ff8_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_6ffa_w)
+{
+ logerror("%s: xavix_6ffa_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_6ffb_w)
+{
+ logerror("%s: xavix_6ffb_w %02x\n", machine().describe_context(), data);
+}
+
+READ8_MEMBER(xavix_state::xavix_75f0_r)
+{
+ logerror("%s: xavix_75f0_r\n", machine().describe_context());
+ return m_75fx[0];
+}
+
+READ8_MEMBER(xavix_state::xavix_75f1_r)
+{
+ logerror("%s: xavix_75f1_r\n", machine().describe_context());
+ return m_75fx[1];
+}
+
+READ8_MEMBER(xavix_state::xavix_75f6_r)
+{
+ logerror("%s: xavix_75f6_r\n", machine().describe_context());
+ return m_75fx[6];
+}
+
+READ8_MEMBER(xavix_state::xavix_75f8_r)
+{
+ logerror("%s: xavix_75f8_r\n", machine().describe_context());
+ return m_75fx[8];
+}
+
+READ8_MEMBER(xavix_state::xavix_75f9_r)
+{
+ logerror("%s: xavix_75f9_r\n", machine().describe_context());
+ return 0x00;
+}
+
+READ8_MEMBER(xavix_state::xavix_75fa_r)
+{
+ logerror("%s: xavix_75fa_r\n", machine().describe_context());
+ return m_75fx[10];
+}
+
+READ8_MEMBER(xavix_state::xavix_75fb_r)
+{
+ logerror("%s: xavix_75fb_r\n", machine().describe_context());
+ return m_75fx[11];
+}
+
+READ8_MEMBER(xavix_state::xavix_75fc_r)
+{
+ logerror("%s: xavix_75fc_r\n", machine().describe_context());
+ return m_75fx[12];
+}
+
+READ8_MEMBER(xavix_state::xavix_75fd_r)
+{
+ logerror("%s: xavix_75fd_r\n", machine().describe_context());
+ return m_75fx[13];
+}
+
+
+
+
+WRITE8_MEMBER(xavix_state::xavix_75f0_w)
+{
+ // expected to return data written
+ m_75fx[0] = data;
+ logerror("%s: xavix_75f0_w %02x\n", machine().describe_context(), data);
+}
+
+
+WRITE8_MEMBER(xavix_state::xavix_75f1_w)
+{
+ // expected to return data written
+ m_75fx[1] = data;
+ logerror("%s: xavix_75f1_w %02x\n", machine().describe_context(), data);
+}
+
+
+WRITE8_MEMBER(xavix_state::xavix_75f6_w)
+{
+ // expected to return data written
+ m_75fx[6] = data;
+ logerror("%s: xavix_75f6_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_75f7_w)
+{
+ m_75fx[7] = data;
+ logerror("%s: xavix_75f7_w %02x\n", machine().describe_context(), data);
+}
+
+
+WRITE8_MEMBER(xavix_state::xavix_75f8_w)
+{
+ // expected to return data written
+ m_75fx[8] = data;
+ logerror("%s: xavix_75f8_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_75f9_w)
+{
+ m_75fx[9] = data;
+ logerror("%s: xavix_75f9_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_75fa_w)
+{
+ // expected to return data written
+ m_75fx[10] = data;
+ logerror("%s: xavix_75fa_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_75fb_w)
+{
+ // expected to return data written
+ m_75fx[11] = data;
+ logerror("%s: xavix_75fb_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_75fc_w)
+{
+ // expected to return data written
+ m_75fx[12] = data;
+ logerror("%s: xavix_75fc_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_75fd_w)
+{
+ // expected to return data written
+ m_75fx[13] = data;
+ logerror("%s: xavix_75fd_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_75fe_w)
+{
+ m_75fx[14] = data;
+ logerror("%s: xavix_75fe_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_75ff_w)
+{
+ m_75fx[15] = data;
+ logerror("%s: xavix_75ff_w %02x\n", machine().describe_context(), data);
+}
+
+READ8_MEMBER(xavix_state::xavix_io_0_r)
+{
+ return m_in0->read();
+}
+
+READ8_MEMBER(xavix_state::xavix_io_1_r)
+{
+ /*
+ int pc = m_maincpu->state_int(M6502_PC);
+
+ if (pc == 0x3acc) return 0x08;
+ if (pc == 0x3ae0) return 0x08;
+ if (pc == 0xfcb0) return 0xff;
+
+ logerror("%04x: in1 read\n", pc);
+ */
+ return m_in1->read();
+}
+
+READ8_MEMBER(xavix_state::xavix_7a02_r)
+{
+ return 0xff;
+}
+
+READ8_MEMBER(xavix_state::xavix_7a03_r)
+{
+ return 0xff;
+}
+
+
+WRITE8_MEMBER(xavix_state::xavix_7a00_w)
+{
+ logerror("%s: xavix_7a00_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_7a01_w)
+{
+ logerror("%s: xavix_7a01_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_7a02_w)
+{
+ logerror("%s: xavix_7a02_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_7a03_w)
+{
+ logerror("%s: xavix_7a03_w %02x\n", machine().describe_context(), data);
+}
+
+READ8_MEMBER(xavix_state::xavix_6fe8_r)
+{
+ logerror("%s: xavix_6fe8_r\n", machine().describe_context());
+ return m_6fe8;
+}
+
+WRITE8_MEMBER(xavix_state::xavix_6fe8_w)
+{
+ // expected to return data written
+ m_6fe8 = data;
+ logerror("%s: xavix_6fe8_w %02x\n", machine().describe_context(), data);
+}
+
+READ8_MEMBER(xavix_state::xavix_6fe9_r)
+{
+ logerror("%s: xavix_6fe9_r\n", machine().describe_context());
+ return m_6fe9;
+}
+
+WRITE8_MEMBER(xavix_state::xavix_6fe9_w)
+{
+ // expected to return data written
+ m_6fe9 = data;
+ logerror("%s: xavix_6fe9_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_6fea_w)
+{
+ logerror("%s: xavix_6fea_w %02x\n", machine().describe_context(), data);
+}
+
+
+READ8_MEMBER(xavix_state::xavix_7c01_r)
+{
+ logerror("%s: xavix_7c01_r\n", machine().describe_context());
+ return m_7c01;
+}
+
+WRITE8_MEMBER(xavix_state::xavix_7c00_w)
+{
+ logerror("%s: xavix_7c00_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_7c01_w)
+{
+ // expected to return data written
+ m_7c01 = data;
+ logerror("%s: xavix_7c01_w %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_7c02_w)
+{
+ logerror("%s: xavix_7c02_w %02x\n", machine().describe_context(), data);
+}
+
+READ8_MEMBER(xavix_state::xavix_75f4_r)
+{
+ // used with 75f0
+ return 0xff;
+}
+
+READ8_MEMBER(xavix_state::xavix_75f5_r)
+{
+ // used with 75f1
+ return 0xff;
+}
+
+READ8_MEMBER(xavix_state::mult_r)
+{
+ return m_multresults[offset];
+}
+
+WRITE8_MEMBER(xavix_state::mult_w)
+{
+ // rad_fb writes here, why would you write to the results registers?
+ logerror("%s: mult_w (write to multiply RESULT registers, why?) reg: %d %02x\n", machine().describe_context(), offset, data);
+ m_multresults[offset] = data;
+}
+
+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
+
+ if (offset == 2)
+ {
+ // assume 0 is upper bits, might be 'mode' instead, check
+ uint16_t param1 = (m_multparams[0]<<8) | (m_multparams[1]);
+ uint8_t param2 = (m_multparams[2]);
+
+ uint16_t result = param1*param2;
+
+ m_multresults[1] = (result>>8)&0xff;
+ m_multresults[0] = result&0xff;
+ }
+}
+
+
+READ8_MEMBER(xavix_state::irq_source_r)
+{
+ /* the 2nd IRQ routine (regular IRQ, not NMI?) reads here before deciding what to do
+
+ the following bits have been seen to be checked (active low?)
+
+ 0x40 - Monster Truck - stuff with 6ffb 6fd6 and 6ff8
+ 0x20 - most games (but not Monster Truck) - DMA related?
+ 0x10 - card night + monster truck - 7c00 related? (increases 16-bit counter in ram stores 0xc1 at 7c00)
+ 0x08 - several games - Input related (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 - Monster Truck - loads/stores 7b81
+ */
+ logerror("%s: irq_source_r\n", machine().describe_context());
+ return 0xff;
+}
+
+WRITE8_MEMBER(xavix_state::irq_source_w)
+{
+ logerror("%s: irq_source_w %02x\n", machine().describe_context(), data);
+ // cleared on startup in monster truck, no purpose?
+}
+
+
+void xavix_state::machine_start()
+{
+
+}
+
+void xavix_state::machine_reset()
+{
+ m_rom_dmasrc_lo_data = 0;
+ m_rom_dmasrc_md_data = 0;
+ m_rom_dmasrc_hi_data = 0;
+
+ m_rom_dmadst_lo_data = 0;
+ m_rom_dmadst_hi_data = 0;
+
+ m_rom_dmalen_lo_data = 0;
+ m_rom_dmalen_hi_data = 0;
+
+ m_irq_enable_data = 0;
+ m_irq_vector0_lo_data = 0;
+ m_irq_vector0_hi_data = 0;
+ m_irq_vector1_lo_data = 0;
+ m_irq_vector1_hi_data = 0;
+
+ m_6ff0 = 0;
+ m_6ff8 = 0;
+
+ m_75fx[0] = 0;
+ m_75fx[1] = 0;
+
+ m_75fx[6] = 0;
+ m_75fx[8] = 0;
+ m_75fx[10] = 0;
+ m_75fx[11] = 0;
+ m_75fx[12] = 0;
+ m_75fx[13] = 0;
+
+ for (int i = 0; i < 3; i++)
+ m_multparams[i] = 0;
+
+ for (int i = 0; i < 2; i++)
+ m_multresults[i] = 0;
+
+ for (int i = 0; i < 2; i++)
+ {
+ m_vid_dma_param1[i] = 0;
+ m_vid_dma_param2[i] = 0;
+ }
+
+ for (int i = 0; i < 8; i++)
+ {
+ m_tmap1_regs[i] = 0;
+ m_tmap2_regs[i] = 0;
+ }
+
+ m_lowbus->set_bank(0);
+}
+
+typedef device_delegate<uint8_t (int which, int half)> xavix_interrupt_vector_delegate;
+
+uint8_t xavix_state::get_vectors(int which, int half)
+{
+// logerror("get_vectors %d %d\n", which, half);
+
+ if (which == 0) // irq?
+ {
+ if (half == 0)
+ return m_irq_vector0_hi_data;
+ else
+ return m_irq_vector0_lo_data;
+ }
+ else
+ {
+ if (half == 0)
+ return m_irq_vector1_hi_data;
+ else
+ return m_irq_vector1_lo_data;
+ }
+}
+
+
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index c48f2b57d77..9f812260462 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -37987,6 +37987,7 @@ zone40 // Zone 40
zone60 // Zone 60
rad_skat //
rad_skatp //
+rad_sktv //
rad_crik //
@source:vsmilepro.cpp
diff --git a/src/mame/video/xavix.cpp b/src/mame/video/xavix.cpp
new file mode 100644
index 00000000000..6c576f8eb8d
--- /dev/null
+++ b/src/mame/video/xavix.cpp
@@ -0,0 +1,730 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood
+
+#include "emu.h"
+#include "includes/xavix.h"
+
+inline void xavix_state::set_data_address(int address, int bit)
+{
+ m_tmp_dataaddress = address;
+ m_tmp_databit = bit;
+}
+
+inline uint8_t xavix_state::get_next_bit()
+{
+ uint8_t bit = m_rgn[m_tmp_dataaddress & (m_rgnlen - 1)];
+ bit = bit >> m_tmp_databit;
+ bit &= 1;
+
+ m_tmp_databit++;
+
+ if (m_tmp_databit == 8)
+ {
+ m_tmp_databit = 0;
+ m_tmp_dataaddress++;
+ }
+
+ return bit;
+}
+
+inline uint8_t xavix_state::get_next_byte()
+{
+ uint8_t dat = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ dat |= (get_next_bit() << i);
+ }
+ return dat;
+}
+
+inline int xavix_state::get_current_address_byte()
+{
+ return m_tmp_dataaddress;
+}
+
+
+void xavix_state::video_start()
+{
+}
+
+
+double xavix_state::hue2rgb(double p, double q, double t)
+{
+ if (t < 0) t += 1;
+ if (t > 1) t -= 1;
+ if (t < 1 / 6.0f) return p + (q - p) * 6 * t;
+ if (t < 1 / 2.0f) return q;
+ if (t < 2 / 3.0f) return p + (q - p) * (2 / 3.0f - t) * 6;
+ return p;
+}
+
+
+void xavix_state::handle_palette(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ // not verified
+ int offs = 0;
+ for (int index = 0; index < 256; index++)
+ {
+ uint16_t dat = m_palram1[offs];
+ dat |= m_palram2[offs]<<8;
+ offs++;
+
+ int l_raw = (dat & 0x1f00) >> 8;
+ int sl_raw =(dat & 0x00e0) >> 5;
+ int h_raw = (dat & 0x001f) >> 0;
+
+ //if (h_raw > 24)
+ // logerror("hraw >24 (%02x)\n", h_raw);
+
+ //if (l_raw > 17)
+ // logerror("lraw >17 (%02x)\n", l_raw);
+
+ //if (sl_raw > 7)
+ // logerror("sl_raw >5 (%02x)\n", sl_raw);
+
+ double l = (double)l_raw / 17.0f;
+ double s = (double)sl_raw / 7.0f;
+ double h = (double)h_raw / 24.0f;
+
+ 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);
+ }
+
+ int r_real = r * 255.0f;
+ int g_real = g * 255.0f;
+ int b_real = b * 255.0f;
+
+ m_palette->set_pen_color(index, r_real, g_real, b_real);
+
+ }
+}
+
+void xavix_state::draw_tilemap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int which)
+{
+ int alt_tileaddressing = 0;
+ int alt_tileaddressing2 = 0;
+
+ int ydimension = 0;
+ int xdimension = 0;
+ int ytilesize = 0;
+ int xtilesize = 0;
+ int offset_multiplier = 0;
+ int opaque = 0;
+
+ uint8_t* tileregs;
+ address_space& mainspace = m_maincpu->space(AS_PROGRAM);
+
+ if (which == 0)
+ {
+ tileregs = m_tmap1_regs;
+ opaque = 1;
+ }
+ else
+ {
+ tileregs = m_tmap2_regs;
+ opaque = 0;
+ }
+
+ switch (tileregs[0x3] & 0x30)
+ {
+ case 0x00:
+ ydimension = 32;
+ xdimension = 32;
+ ytilesize = 8;
+ xtilesize = 8;
+ break;
+
+ case 0x10:
+ ydimension = 32;
+ xdimension = 16;
+ ytilesize = 8;
+ xtilesize = 16;
+ break;
+
+ case 0x20: // guess
+ ydimension = 16;
+ xdimension = 32;
+ ytilesize = 16;
+ xtilesize = 8;
+ break;
+
+ case 0x30:
+ ydimension = 16;
+ xdimension = 16;
+ ytilesize = 16;
+ xtilesize = 16;
+ break;
+ }
+
+ offset_multiplier = (ytilesize * xtilesize)/8;
+
+ if (tileregs[0x7] & 0x10)
+ alt_tileaddressing = 1;
+ else
+ alt_tileaddressing = 0;
+
+ if (tileregs[0x7] & 0x02)
+ alt_tileaddressing2 = 1;
+
+ static int hackx = 1;
+
+ if (machine().input().code_pressed_once(KEYCODE_Q))
+ {
+ hackx--;
+ logerror("%02x\n", hackx);
+ }
+
+ if (machine().input().code_pressed_once(KEYCODE_W))
+ {
+ hackx++;
+ logerror("%02x\n", hackx);
+ }
+
+ if (tileregs[0x7] & 0x80)
+ {
+ //logerror("draw tilemap %d, regs base0 %02x base1 %02x base2 %02x tilesize,bpp %02x scrollx %02x scrolly %02x pal %02x mode %02x\n", which, tileregs[0x0], tileregs[0x1], tileregs[0x2], tileregs[0x3], tileregs[0x4], tileregs[0x5], tileregs[0x6], tileregs[0x7]);
+
+ // there's a tilemap register to specify base in main ram, although in the monster truck test mode it points to an unmapped region
+ // and expected a fixed layout, we handle that in the memory map at the moment
+ int count;
+
+ count = 0;// ;
+ for (int y = 0; y < ydimension; y++)
+ {
+ for (int x = 0; x < xdimension; x++)
+ {
+ int bpp, pal, scrolly, scrollx;
+ int tile = 0;
+ int extraattr = 0;
+
+ // the register being 0 probably isn't the condition here
+ if (tileregs[0x0] != 0x00) tile |= mainspace.read_byte((tileregs[0x0] << 8) + count);
+ if (tileregs[0x1] != 0x00) tile |= mainspace.read_byte((tileregs[0x1] << 8) + count) << 8;
+
+ // at the very least boxing leaves unwanted bits set in ram after changing between mode 0x8a and 0x82, expecting them to not be used
+ if (tileregs[0x7] & 0x08)
+ extraattr = mainspace.read_byte((tileregs[0x2] << 8) + count);
+
+ count++;
+
+ bpp = (tileregs[0x3] & 0x0e) >> 1;
+ bpp++;
+ pal = (tileregs[0x6] & 0xf0) >> 4;
+ scrolly = tileregs[0x5];
+ scrollx = tileregs[0x4];
+
+ int basereg;
+ int flipx = 0;
+ int flipy = 0;
+ int gfxbase;
+
+ // tile 0 is always skipped, doesn't even point to valid data packets in alt mode
+ // this is consistent with the top layer too
+ // should we draw as solid in solid layer?
+ if (tile == 0)
+ continue;
+
+ const int debug_packets = 0;
+ int test = 0;
+
+ if (!alt_tileaddressing)
+ {
+ if (!alt_tileaddressing2)
+ {
+ basereg = 0;
+ gfxbase = (m_spr_attra[(basereg * 2) + 1] << 16) | (m_spr_attra[(basereg * 2)] << 8);
+
+ tile = tile * (offset_multiplier * bpp);
+ tile += gfxbase;
+ }
+ else
+ {
+ tile = tile * 8;
+ basereg = (tile & 0x70000) >> 16;
+ tile &= 0xffff;
+ gfxbase = (m_spr_attra[(basereg * 2) + 1] << 16) | (m_spr_attra[(basereg * 2)] << 8);
+ tile += gfxbase;
+
+ if (tileregs[0x7] & 0x08)
+ {
+ // make use of the extraattr stuff?
+ pal = (extraattr & 0xf0)>>4;
+ // low bits are priority?
+ }
+ }
+ }
+ else
+ {
+ if (debug_packets) logerror("for tile %04x (at %d %d): ", tile, (((x * 16) + scrollx) & 0xff), (((y * 16) + scrolly) & 0xff));
+
+
+ basereg = (tile & 0xf000) >> 12;
+ tile &= 0x0fff;
+ gfxbase = (m_spr_attra[(basereg * 2) + 1] << 16) | (m_spr_attra[(basereg * 2)] << 8);
+
+ tile += gfxbase;
+ set_data_address(tile, 0);
+
+ // there seems to be a packet stored before the tile?!
+ // the offset used for flipped sprites seems to specifically be changed so that it picks up an extra byte which presumably triggers the flipping
+ uint8_t byte1 = 0;
+ int done = 0;
+ int skip = 0;
+
+ do
+ {
+ byte1 = get_next_byte();
+
+ if (debug_packets) logerror(" %02x, ", byte1);
+
+ if (skip == 1)
+ {
+ skip = 0;
+ //test = 1;
+ }
+ else if ((byte1 & 0x0f) == 0x01)
+ {
+ // used
+ }
+ else if ((byte1 & 0x0f) == 0x03)
+ {
+ // causes next byte to be skipped??
+ skip = 1;
+ }
+ else if ((byte1 & 0x0f) == 0x05)
+ {
+ // the upper bits are often 0x00, 0x10, 0x20, 0x30, why?
+ flipx = 1;
+ }
+ else if ((byte1 & 0x0f) == 0x06) // there must be other finish conditions too because sometimes this fails..
+ {
+ // tile data will follow after this, always?
+ pal = (byte1 & 0xf0) >> 4;
+ done = 1;
+ }
+ else if ((byte1 & 0x0f) == 0x07)
+ {
+ // causes next byte to be skipped??
+ skip = 1;
+ }
+ else if ((byte1 & 0x0f) == 0x09)
+ {
+ // used
+ }
+ else if ((byte1 & 0x0f) == 0x0a)
+ {
+ // not seen
+ }
+ else if ((byte1 & 0x0f) == 0x0b)
+ {
+ // used
+ }
+ else if ((byte1 & 0x0f) == 0x0c)
+ {
+ // not seen
+ }
+ else if ((byte1 & 0x0f) == 0x0d)
+ {
+ // used
+ }
+ else if ((byte1 & 0x0f) == 0x0e)
+ {
+ // not seen
+ }
+ else if ((byte1 & 0x0f) == 0x0f)
+ {
+ // used
+ }
+
+ } while (done == 0);
+ if (debug_packets) logerror("\n");
+ tile = get_current_address_byte();
+ }
+
+ if (test == 1) pal = machine().rand() & 0xf;
+
+
+ draw_tile(screen, bitmap, cliprect, tile, bpp, (x * xtilesize) + scrollx, ((y * ytilesize) - 16) - scrolly, ytilesize, xtilesize, flipx, flipy, pal, opaque);
+ draw_tile(screen, bitmap, cliprect, tile, bpp, (x * xtilesize) + scrollx, (((y * ytilesize) - 16) - scrolly) + 256, ytilesize, xtilesize, flipx, flipy, pal, opaque); // wrap-y
+ draw_tile(screen, bitmap, cliprect, tile, bpp, ((x * xtilesize) + scrollx) - 256, ((y * ytilesize) - 16) - scrolly, ytilesize, xtilesize, flipx, flipy, pal, opaque); // wrap-x
+ draw_tile(screen, bitmap, cliprect, tile, bpp, ((x * xtilesize) + scrollx) - 256, (((y * ytilesize) - 16) - scrolly) + 256, ytilesize, xtilesize, flipx, flipy, pal, opaque); // wrap-y and x
+ }
+ }
+ }
+}
+
+void xavix_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ //logerror("frame\n");
+ // priority doesn't seem to be based on list order, there are bad sprite-sprite priorities with either forward or reverse
+
+ for (int i = 0xff; i >= 0; i--)
+ {
+ /* attribute 0 bits
+ pppp bbb- p = palette, b = bpp
+
+ attribute 1 bits
+ ---- ss-f s = size, f = flipx
+ */
+
+ int ypos = m_spr_ypos[i];
+ int xpos = m_spr_xpos[i];
+ int tile = (m_spr_addr_hi[i] << 16) | (m_spr_addr_md[i] << 8) | m_spr_addr_lo[i];
+ int attr0 = m_spr_attr0[i];
+ int attr1 = m_spr_attr1[i];
+
+ int pal = (attr0 & 0xf0) >> 4;
+ int flipx = (attr1 & 0x01);
+
+ int drawheight = 16;
+ int drawwidth = 16;
+
+ tile &= (m_rgnlen - 1);
+
+ // taito nostalgia 1 also seems to use a different addressing, is it selectable or is the chip different?
+ // taito nost attr1 is 84 / 80 / 88 / 8c for the various elements of the xavix logo. monster truck uses ec / fc / dc / 4c / 5c / 6c (final 6 sprites ingame are 00 00 f0 f0 f0 f0, radar?)
+
+ if ((attr1 & 0x0c) == 0x0c)
+ {
+ drawheight = 16;
+ drawwidth = 16;
+ if (m_alt_addressing == 1)
+ tile = tile * 128;
+ else if (m_alt_addressing == 2)
+ tile = tile * 8;
+ }
+ else if ((attr1 & 0x0c) == 0x08)
+ {
+ drawheight = 16;
+ drawwidth = 8;
+ xpos += 4;
+ if (m_alt_addressing == 1)
+ tile = tile * 64;
+ else if (m_alt_addressing == 2)
+ tile = tile * 8;
+ }
+ else if ((attr1 & 0x0c) == 0x04)
+ {
+ drawheight = 8;
+ drawwidth = 16;
+ ypos -= 4;
+ if (m_alt_addressing == 1)
+ tile = tile * 64;
+ else if (m_alt_addressing == 2)
+ tile = tile * 8;
+ }
+ else if ((attr1 & 0x0c) == 0x00)
+ {
+ drawheight = 8;
+ drawwidth = 8;
+ xpos += 4;
+ ypos -= 4;
+ if (m_alt_addressing == 1)
+ tile = tile * 32;
+ else if (m_alt_addressing == 2)
+ tile = tile * 8;
+ }
+
+ if (m_alt_addressing != 0)
+ {
+ int basereg = (tile & 0xf0000) >> 16;
+ tile &= 0xffff;
+ int gfxbase = (m_spr_attra[(basereg * 2) + 1] << 16) | (m_spr_attra[(basereg * 2)] << 8);
+ tile+= gfxbase;
+ }
+
+ ypos = 0x100 - ypos;
+
+ xpos -= 136;
+ ypos -= 152;
+
+ xpos &= 0xff;
+ ypos &= 0xff;
+
+ if (ypos >= 192)
+ ypos -= 256;
+
+ int bpp = 1;
+
+ bpp = (attr0 & 0x0e) >> 1;
+ bpp += 1;
+
+ draw_tile(screen, bitmap, cliprect, tile, bpp, xpos, ypos, drawheight, drawwidth, flipx, 0, pal, 0);
+ draw_tile(screen, bitmap, cliprect, tile, bpp, xpos - 256, ypos, drawheight, drawwidth, flipx, 0, pal, 0); // wrap-x
+ draw_tile(screen, bitmap, cliprect, tile, bpp, xpos, ypos - 256, drawheight, drawwidth, flipx, 0, pal, 0); // wrap-y
+ draw_tile(screen, bitmap, cliprect, tile, bpp, xpos - 256, ypos - 256, drawheight, drawwidth, flipx, 0, pal, 0); // wrap-x,y
+
+ /*
+ if ((m_spr_ypos[i] != 0x81) && (m_spr_ypos[i] != 0x80) && (m_spr_ypos[i] != 0x00))
+ {
+ logerror("sprite with enable? %02x attr0 %02x attr1 %02x attr3 %02x attr5 %02x attr6 %02x attr7 %02x\n", m_spr_ypos[i], m_spr_attr0[i], m_spr_attr1[i], m_spr_xpos[i], m_spr_addr_lo[i], m_spr_addr_md[i], m_spr_addr_hi[i] );
+ }
+ */
+ }
+}
+
+void xavix_state::draw_tile(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 opaque)
+{
+ // set the address here so we can increment in bits in the draw function
+ set_data_address(tile, 0);
+
+ for (int y = 0; y < drawheight; y++)
+ {
+ int row;
+ if (flipy)
+ {
+ row = ypos + (drawheight-1) - y;
+ }
+ else
+ {
+ row = ypos + y;
+ }
+
+ for (int x = 0; x < drawwidth; x++)
+ {
+
+ int col;
+
+ if (flipx)
+ {
+ col = xpos + (drawwidth-1) - x;
+ }
+ else
+ {
+ col = xpos + x;
+ }
+
+ uint8_t dat = 0;
+
+ for (int i = 0; i < bpp; i++)
+ {
+ dat |= (get_next_bit() << i);
+ }
+
+ if ((row >= cliprect.min_y && row <= cliprect.max_y) && (col >= cliprect.min_x && col <= cliprect.max_x))
+ {
+ uint16_t* rowptr;
+
+ rowptr = &bitmap.pix16(row);
+
+ if (opaque)
+ {
+ rowptr[col] = (dat + (pal << 4)) & 0xff;
+ }
+ else
+ {
+ if (dat)
+ rowptr[col] = (dat + (pal << 4)) & 0xff;
+ }
+ }
+ }
+ }
+}
+
+uint32_t xavix_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ handle_palette(screen, bitmap, cliprect);
+
+ bitmap.fill(0, cliprect);
+
+ draw_tilemap(screen,bitmap,cliprect,0);
+ draw_sprites(screen,bitmap,cliprect);
+ draw_tilemap(screen,bitmap,cliprect,1);
+
+ //popmessage("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", m_75fx[0],m_75fx[1],m_75fx[2],m_75fx[3],m_75fx[4],m_75fx[5],m_75fx[6],m_75fx[7],m_75fx[8],m_75fx[9],m_75fx[10],m_75fx[11],m_75fx[12],m_75fx[13],m_75fx[14],m_75fx[15]);
+
+ return 0;
+}
+
+
+WRITE8_MEMBER(xavix_state::vid_dma_params_1_w)
+{
+ m_vid_dma_param1[offset] = data;
+}
+
+WRITE8_MEMBER(xavix_state::vid_dma_params_2_w)
+{
+ m_vid_dma_param2[offset] = data;
+}
+
+WRITE8_MEMBER(xavix_state::vid_dma_trigger_w)
+{
+ uint16_t len = data & 0x07;
+ uint16_t src = (m_vid_dma_param1[1]<<8) | m_vid_dma_param1[0];
+ uint16_t dst = (m_vid_dma_param2[0]<<8);
+ dst += 0x6000;
+
+ uint8_t unk = m_vid_dma_param2[1];
+
+ logerror("%s: vid_dma_trigger_w with trg %02x size %04x src %04x dest %04x unk (%02x)\n", machine().describe_context(), data & 0xf8, len,src,dst,unk);
+
+ if (unk)
+ {
+ fatalerror("m_vid_dma_param2[1] != 0x00 (is %02x)\n", m_vid_dma_param2[1]);
+ }
+
+ if (len == 0x00)
+ {
+ len = 0x08;
+ logerror(" (length was 0x0, assuming 0x8)\n");
+ }
+
+ len = len << 8;
+
+ address_space& dmaspace = m_maincpu->space(AS_PROGRAM);
+
+ if (data & 0x40)
+ {
+ for (int i = 0; i < len; i++)
+ {
+ uint8_t dat = dmaspace.read_byte(src + i);
+ dmaspace.write_byte(dst + i, dat);
+ }
+ }
+}
+
+READ8_MEMBER(xavix_state::vid_dma_trigger_r)
+{
+ // expects bit 0x40 to clear in most cases
+ return 0x00;
+}
+
+READ8_MEMBER(xavix_state::pal_ntsc_r)
+{
+ // only seen 0x10 checked in code
+ // in monster truck the tile base address gets set based on this, there are 2 copies of the test screen in rom, one for pal, one for ntsc, see 1854c
+ // likewise card night has entirely different tilesets for each region title
+ return m_region->read();
+}
+
+WRITE8_MEMBER(xavix_state::xavix_6fc0_w) // also related to tilemap 1?
+{
+ logerror("%s: xavix_6fc0_w data %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::tmap1_regs_w)
+{
+ /*
+ 0x0 pointer to address where tile data is
+ it gets set to 0x40 in monster truck test mode, which is outside of ram but test mode requires a fixed 'column scan' layout
+ so that might be special
+
+ 0x1 pointer to middle tile bits (if needed, depends on mode) (usually straight after the ram needed for above)
+
+ 0x2 pointer to tile highest tile bits (if needed, depends on mode) (usually straight after the ram needed for above)
+
+ 0x3 --tt bbb- - = ? tt = tile/tilemap size b = bpp (0x36 xavix logo, 0x3c title screen, 0x36 course select)
+
+ 0x4 and 0x5 are scroll
+
+ 0x6 pppp ---- p = palette - = ? (0x02 xavix logo, 0x01 course select)
+
+ 0x7 could be mode (16x16, 8x8 etc.)
+ 0x00 is disabled?
+ 0x80 means 16x16 tiles
+ 0x81 might be 8x8 tiles
+ 0x93 course / mode select bg / ingame (weird addressing?)
+
+
+ */
+
+ /*
+ 6aff base registers
+ -- ingame
+
+ ae 80
+ 02 80
+ 02 90
+ 02 a0
+ 02 b0
+ 02 c0
+ 02 d0
+ 02 e0
+
+ 02 00
+ 04 80
+ 04 90
+ 04 a0
+ 04 b0
+ 04 c0
+ 04 d0
+ 04 e0
+
+ -- menu
+ af 80
+ 27 80
+ 27 90
+ 27 a0
+ 27 b0
+ 27 c0
+ 27 d0
+ 27 e0
+
+ 27 00
+ 00 80
+ 00 90
+ 00 a0
+ 00 b0
+ 00 c0
+ 00 d0
+ 00 e0
+ */
+
+
+ if ((offset != 0x4) && (offset != 0x5))
+ {
+ logerror("%s: tmap1_regs_w offset %02x data %02x\n", machine().describe_context(), offset, data);
+ }
+
+ COMBINE_DATA(&m_tmap1_regs[offset]);
+}
+
+WRITE8_MEMBER(xavix_state::xavix_6fd8_w) // also related to tilemap 2?
+{
+ // possibly just a mirror of tmap2_regs_w, at least it writes 0x04 here which would be the correct
+ // base address to otherwise write at tmap2_regs_w offset 0
+// tmap2_regs_w(space,offset,data);
+
+ logerror("%s: xavix_6fd8_w data %02x\n", machine().describe_context(), data);
+}
+
+WRITE8_MEMBER(xavix_state::tmap2_regs_w)
+{
+ // same as above but for 2nd tilemap
+ if ((offset != 0x4) && (offset != 0x5))
+ {
+ //logerror("%s: tmap2_regs_w offset %02x data %02x\n", machine().describe_context(), offset, data);
+ }
+
+ COMBINE_DATA(&m_tmap2_regs[offset]);
+}
+
+READ8_MEMBER(xavix_state::tmap2_regs_r)
+{
+ // does this return the same data or a status?
+
+ logerror("%s: tmap2_regs_r offset %02x\n", offset, machine().describe_context());
+ return m_tmap2_regs[offset];
+}
+
+READ8_MEMBER(xavix_state::xavix_4000_r)
+{
+ if (offset < 0x100)
+ {
+ return ((offset>>4) | (offset<<4));
+ }
+ else
+ {
+ return 0x00;
+ }
+}
+