summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/bus/megadrive/md_carts.cpp1
-rw-r--r--src/devices/bus/megadrive/md_slot.cpp1
-rw-r--r--src/devices/bus/megadrive/md_slot.h1
-rw-r--r--src/devices/bus/megadrive/rom.cpp23
-rw-r--r--src/devices/bus/megadrive/rom.h13
-rw-r--r--src/devices/cpu/adsp2100/2100ops.hxx8
-rw-r--r--src/devices/cpu/adsp2100/adsp2100.cpp4
-rw-r--r--src/devices/cpu/adsp2100/adsp2100.h5
-rw-r--r--src/devices/cpu/sparc/mb86901.cpp216
-rw-r--r--src/devices/cpu/sparc/sparc.h36
-rw-r--r--src/devices/cpu/sparc/sparcdefs.h34
-rw-r--r--src/devices/machine/8530scc.cpp162
-rw-r--r--src/devices/machine/8530scc.h3
-rw-r--r--src/devices/video/zeus2.cpp1311
-rw-r--r--src/devices/video/zeus2.h286
-rw-r--r--src/mame/audio/dcs.cpp59
-rw-r--r--src/mame/audio/dcs.h4
-rw-r--r--src/mame/drivers/atlantis.cpp358
-rw-r--r--src/mame/drivers/midzeus.cpp14
-rw-r--r--src/mame/drivers/pc9801.cpp2
-rw-r--r--src/mame/drivers/poker72.cpp113
-rw-r--r--src/mame/drivers/sun4.cpp334
-rw-r--r--src/mame/includes/midzeus.h2
-rw-r--r--src/mame/includes/midzeus2.h5
-rw-r--r--src/mame/layout/dlair.lay102
25 files changed, 2545 insertions, 552 deletions
diff --git a/src/devices/bus/megadrive/md_carts.cpp b/src/devices/bus/megadrive/md_carts.cpp
index 4c9f1b9b2e0..5a8e1902d09 100644
--- a/src/devices/bus/megadrive/md_carts.cpp
+++ b/src/devices/bus/megadrive/md_carts.cpp
@@ -55,6 +55,7 @@ SLOT_INTERFACE_START(md_cart)
SLOT_INTERFACE_INTERNAL("rom_lion3", MD_ROM_LION3)
SLOT_INTERFACE_INTERNAL("rom_mcpir", MD_ROM_MCPIR)
SLOT_INTERFACE_INTERNAL("rom_mjlov", MD_ROM_MJLOV)
+ SLOT_INTERFACE_INTERNAL("rom_cjmjclub", MD_ROM_CJMJCLUB)
SLOT_INTERFACE_INTERNAL("rom_pokea", MD_ROM_POKEA)
SLOT_INTERFACE_INTERNAL("rom_pokestad", MD_ROM_POKESTAD)
SLOT_INTERFACE_INTERNAL("rom_realtec", MD_ROM_REALTEC)
diff --git a/src/devices/bus/megadrive/md_slot.cpp b/src/devices/bus/megadrive/md_slot.cpp
index 61e847eb6e9..55d80f8b64d 100644
--- a/src/devices/bus/megadrive/md_slot.cpp
+++ b/src/devices/bus/megadrive/md_slot.cpp
@@ -270,6 +270,7 @@ static const md_slot slot_list[] =
{ LIONK3, "rom_lion3" },
{ MC_PIRATE, "rom_mcpir" },
{ MJLOVER, "rom_mjlov" },
+ { CJMJCLUB, "rom_cjmjclub" },
{ POKEMONA, "rom_pokea" },
{ REALTEC, "rom_realtec" },
{ REDCL_EN, "rom_redcl" },
diff --git a/src/devices/bus/megadrive/md_slot.h b/src/devices/bus/megadrive/md_slot.h
index a033daec607..b6cb59147d5 100644
--- a/src/devices/bus/megadrive/md_slot.h
+++ b/src/devices/bus/megadrive/md_slot.h
@@ -61,6 +61,7 @@ enum
LIONK3, /* Lion King 3, Super Donkey Kong 99, Super King Kong 99 */
MC_PIRATE, /* Super 19 in 1, Super 15 in 1, 12 in 1 and a few more multicarts */
MJLOVER, /* Mahjong Lover */
+ CJMJCLUB, /* Super Mahjong Club */
POKEMONA, /* Pocket Monster Alt Protection */
REALTEC, /* Whac a Critter/Mallet legend, Defend the Earth, Funnyworld/Ballonboy */
REDCLIFF, /* Romance of the Three Kingdoms - Battle of Red Cliffs, already decoded from .mdx format */
diff --git a/src/devices/bus/megadrive/rom.cpp b/src/devices/bus/megadrive/rom.cpp
index 16b12561c8a..ed17cfff044 100644
--- a/src/devices/bus/megadrive/rom.cpp
+++ b/src/devices/bus/megadrive/rom.cpp
@@ -41,6 +41,7 @@ const device_type MD_ROM_SMB2 = &device_creator<md_rom_smb2_device>;
const device_type MD_ROM_SBUBL = &device_creator<md_rom_sbubl_device>;
const device_type MD_ROM_RX3 = &device_creator<md_rom_rx3_device>;
const device_type MD_ROM_MJLOV = &device_creator<md_rom_mjlov_device>;
+const device_type MD_ROM_CJMJCLUB = &device_creator<md_rom_cjmjclub_device>;
const device_type MD_ROM_KOF98 = &device_creator<md_rom_kof98_device>;
const device_type MD_ROM_KOF99 = &device_creator<md_rom_kof99_device>;
const device_type MD_ROM_SOULB = &device_creator<md_rom_soulb_device>;
@@ -141,6 +142,11 @@ md_rom_mjlov_device::md_rom_mjlov_device(const machine_config &mconfig, const ch
{
}
+md_rom_cjmjclub_device::md_rom_cjmjclub_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : md_std_rom_device(mconfig, MD_ROM_CJMJCLUB, "MD Chaoji Majiang Club / Super Mahjong Club", tag, owner, clock, "md_rom_cjmjclub", __FILE__)
+{
+}
+
md_rom_kof98_device::md_rom_kof98_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: md_std_rom_device(mconfig, MD_ROM_KOF98, "MD KOF 98", tag, owner, clock, "md_rom_kof98", __FILE__)
{
@@ -917,6 +923,23 @@ READ16_MEMBER(md_rom_mjlov_device::read)
/*-------------------------------------------------
+ CHAOJI MAJIANG CLUB
+ -------------------------------------------------*/
+
+READ16_MEMBER(md_rom_cjmjclub_device::read)
+{
+ if (offset == 0x400000/2) return 0x9000;
+ if (offset == 0x400002/2) return 0xd300;
+
+ // non-protection accesses
+ if (offset < 0x400000/2)
+ return m_rom[MD_ADDR(offset)];
+ else
+ return 0xffff;
+}
+
+
+/*-------------------------------------------------
SUPER BUBBLE BOBBLE MD
-------------------------------------------------*/
diff --git a/src/devices/bus/megadrive/rom.h b/src/devices/bus/megadrive/rom.h
index dcb1536f974..3bafead4346 100644
--- a/src/devices/bus/megadrive/rom.h
+++ b/src/devices/bus/megadrive/rom.h
@@ -263,6 +263,18 @@ public:
virtual DECLARE_READ16_MEMBER(read) override;
};
+// ======================> md_rom_cjmjclub_device
+
+class md_rom_cjmjclub_device : public md_std_rom_device
+{
+public:
+ // construction/destruction
+ md_rom_cjmjclub_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // reading and writing
+ virtual DECLARE_READ16_MEMBER(read) override;
+};
+
// ======================> md_rom_pokea_device
class md_rom_pokea_device : public md_std_rom_device
@@ -585,6 +597,7 @@ extern const device_type MD_ROM_LION2;
extern const device_type MD_ROM_LION3;
extern const device_type MD_ROM_MCPIR;
extern const device_type MD_ROM_MJLOV;
+extern const device_type MD_ROM_CJMJCLUB;
extern const device_type MD_ROM_POKEA;
extern const device_type MD_ROM_POKESTAD;
extern const device_type MD_ROM_REALTEC;
diff --git a/src/devices/cpu/adsp2100/2100ops.hxx b/src/devices/cpu/adsp2100/2100ops.hxx
index 31cae1ae59b..c52767bd9cf 100644
--- a/src/devices/cpu/adsp2100/2100ops.hxx
+++ b/src/devices/cpu/adsp2100/2100ops.hxx
@@ -380,7 +380,11 @@ void adsp21xx_device::write_reg1(int regnum, INT32 val)
break;
case 3:
- logerror("ADSP %04x: Writing to an invalid register!\n", m_ppc);
+ // Check for DMOVLAY instruction callback
+ if (regnum == 0xf && !m_dmovlay_cb.isnull())
+ m_dmovlay_cb(val & 0x3fff);
+ else
+ logerror("ADSP %04x: Writing to an invalid register! RGP=01 RegCode=%1X Val=%04X\n", m_ppc, regnum, val);
break;
}
}
@@ -505,7 +509,7 @@ INT32 adsp21xx_device::read_reg3(int regnum)
case 0x08: if (!m_sport_rx_cb.isnull()) return m_sport_rx_cb(0); else return 0;
case 0x0a: if (!m_sport_rx_cb.isnull()) return m_sport_rx_cb(1); else return 0;
case 0x0f: return pc_stack_pop_val();
- default: logerror("ADSP %04x: Reading from an invalid register!\n", m_ppc); return 0;
+ default: logerror("ADSP %04x: Reading from an invalid register! RGP=b11 RegCode=%1X\n", m_ppc, regnum); return 0;
}
}
diff --git a/src/devices/cpu/adsp2100/adsp2100.cpp b/src/devices/cpu/adsp2100/adsp2100.cpp
index 868303fde40..dd9bdb4209d 100644
--- a/src/devices/cpu/adsp2100/adsp2100.cpp
+++ b/src/devices/cpu/adsp2100/adsp2100.cpp
@@ -157,7 +157,8 @@ adsp21xx_device::adsp21xx_device(const machine_config &mconfig, device_type type
(m_chip_type >= CHIP_TYPE_ADSP2101) ? 0x3f : 0x0f),
m_sport_rx_cb(*this),
m_sport_tx_cb(*this),
- m_timer_fired_cb(*this)
+ m_timer_fired_cb(*this),
+ m_dmovlay_cb(*this)
{
// initialize remaining state
memset(&m_core, 0, sizeof(m_core));
@@ -405,6 +406,7 @@ void adsp21xx_device::device_start()
m_sport_rx_cb.resolve();
m_sport_tx_cb.resolve();
m_timer_fired_cb.resolve();
+ m_dmovlay_cb.resolve();
// get our address spaces
m_program = &space(AS_PROGRAM);
diff --git a/src/devices/cpu/adsp2100/adsp2100.h b/src/devices/cpu/adsp2100/adsp2100.h
index f2393f986d2..282a340e040 100644
--- a/src/devices/cpu/adsp2100/adsp2100.h
+++ b/src/devices/cpu/adsp2100/adsp2100.h
@@ -192,6 +192,9 @@ enum
#define MCFG_ADSP21XX_TIMER_FIRED_CB(_devcb) \
devcb = &adsp21xx_device::set_timer_fired_callback(*device, DEVCB_##_devcb);
+#define MCFG_ADSP21XX_DMOVLAY_CB(_devcb) \
+ devcb = &adsp21xx_device::set_dmovlay_callback(*device, DEVCB_##_devcb);
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -220,6 +223,7 @@ public:
template<class _Object> static devcb_base &set_sport_rx_callback(device_t &device, _Object object) { return downcast<adsp21xx_device &>(device).m_sport_rx_cb.set_callback(object); }
template<class _Object> static devcb_base &set_sport_tx_callback(device_t &device, _Object object) { return downcast<adsp21xx_device &>(device).m_sport_tx_cb.set_callback(object); }
template<class _Object> static devcb_base &set_timer_fired_callback(device_t &device, _Object object) { return downcast<adsp21xx_device &>(device).m_timer_fired_cb.set_callback(object); }
+ template<class _Object> static devcb_base &set_dmovlay_callback(device_t &device, _Object object) { return downcast<adsp21xx_device &>(device).m_dmovlay_cb.set_callback(object); }
// public interfaces
void load_boot_data(UINT8 *srcdata, UINT32 *dstdata);
@@ -459,6 +463,7 @@ protected:
devcb_read32 m_sport_rx_cb; // callback for serial receive
devcb_write32 m_sport_tx_cb; // callback for serial transmit
devcb_write_line m_timer_fired_cb; // callback for timer fired
+ devcb_write_line m_dmovlay_cb; // callback for DMOVLAY instruction
// debugging
#if ADSP_TRACK_HOTSPOTS
diff --git a/src/devices/cpu/sparc/mb86901.cpp b/src/devices/cpu/sparc/mb86901.cpp
index 82bde76b7c2..382aa865522 100644
--- a/src/devices/cpu/sparc/mb86901.cpp
+++ b/src/devices/cpu/sparc/mb86901.cpp
@@ -165,6 +165,12 @@ void mb86901_device::device_stop()
void mb86901_device::device_reset()
{
+ m_queued_tt = 0;
+ m_queued_priority = 0;
+ m_asi = 0;
+ MAE = false;
+ HOLD_BUS = false;
+
PC = 0;
nPC = 4;
memset(m_r, 0, sizeof(UINT32) * 120);
@@ -699,7 +705,7 @@ bool mb86901_device::execute_group2(UINT32 op)
bool v = ((arg1 & 0x80000000) == (arg2 & 0x80000000) && (arg2 & 0x80000000) != (result & 0x80000000)) || ((arg1 & 3) != 0) || ((arg2 & 3) != 0);
if (v)
{
- queue_trap(sparc_tag_overflow);
+ trap(SPARC_TAG_OVERFLOW);
}
else
{
@@ -716,7 +722,7 @@ bool mb86901_device::execute_group2(UINT32 op)
bool v = ((arg1 & 0x80000000) == (arg2 & 0x80000000) && (arg2 & 0x80000000) != (result & 0x80000000)) || ((arg1 & 3) != 0) || ((arg2 & 3) != 0);
if (v)
{
- queue_trap(sparc_tag_overflow);
+ trap(SPARC_TAG_OVERFLOW);
}
else
{
@@ -795,7 +801,7 @@ bool mb86901_device::execute_group2(UINT32 op)
case 41: // rd psr
if (IS_USER)
{
- queue_trap(sparc_privileged_instruction);
+ trap(SPARC_PRIVILEGED_INSTRUCTION);
}
else
{
@@ -805,7 +811,7 @@ bool mb86901_device::execute_group2(UINT32 op)
case 42: // rd wim
if (IS_USER)
{
- queue_trap(sparc_privileged_instruction);
+ trap(SPARC_PRIVILEGED_INSTRUCTION);
}
else
{
@@ -815,7 +821,7 @@ bool mb86901_device::execute_group2(UINT32 op)
case 43: // rd tbr
if (IS_USER)
{
- queue_trap(sparc_privileged_instruction);
+ trap(SPARC_PRIVILEGED_INSTRUCTION);
}
else
{
@@ -837,14 +843,14 @@ bool mb86901_device::execute_group2(UINT32 op)
case 49: // wr psr
if (IS_USER)
{
- queue_trap(sparc_privileged_instruction);
+ trap(SPARC_PRIVILEGED_INSTRUCTION);
}
else
{
UINT32 new_psr = (arg1 ^ arg2) & ~PSR_ZERO_MASK;
if ((new_psr & PSR_CWP_MASK) >= WINDOW_COUNT)
{
- queue_trap(sparc_illegal_instruction);
+ trap(SPARC_ILLEGAL_INSTRUCTION);
}
else
{
@@ -856,7 +862,7 @@ bool mb86901_device::execute_group2(UINT32 op)
case 50: // wr wim
if (IS_USER)
{
- queue_trap(sparc_privileged_instruction);
+ trap(SPARC_PRIVILEGED_INSTRUCTION);
}
else
{
@@ -866,7 +872,7 @@ bool mb86901_device::execute_group2(UINT32 op)
case 51: // wr tbr
if (IS_USER)
{
- queue_trap(sparc_privileged_instruction);
+ trap(SPARC_PRIVILEGED_INSTRUCTION);
}
else
{
@@ -876,13 +882,13 @@ bool mb86901_device::execute_group2(UINT32 op)
case 52: // FPop1
if (FPU_DISABLED)
{
- queue_trap(sparc_floating_point_disabled);
+ trap(SPARC_FLOATING_POINT_DISABLED);
}
break;
case 53: // FPop2
if (FPU_DISABLED)
{
- queue_trap(sparc_floating_point_disabled);
+ trap(SPARC_FLOATING_POINT_DISABLED);
}
break;
case 56: // jmpl
@@ -891,7 +897,7 @@ bool mb86901_device::execute_group2(UINT32 op)
m_icount--;
if (addr & 3)
{
- queue_trap(sparc_mem_address_not_aligned);
+ trap(SPARC_MEM_ADDRESS_NOT_ALIGNED);
}
else
{
@@ -909,11 +915,11 @@ bool mb86901_device::execute_group2(UINT32 op)
{
if (IS_USER)
{
- queue_trap(sparc_privileged_instruction);
+ trap(SPARC_PRIVILEGED_INSTRUCTION);
}
else
{
- queue_trap(sparc_illegal_instruction);
+ trap(SPARC_ILLEGAL_INSTRUCTION);
}
break;
}
@@ -921,17 +927,17 @@ bool mb86901_device::execute_group2(UINT32 op)
{
if (IS_USER)
{
- queue_trap(sparc_reset, sparc_privileged_instruction);
+ trap(SPARC_RESET, SPARC_PRIVILEGED_INSTRUCTION);
break;
}
else if (m_wim & (1 << new_cwp))
{
- queue_trap(sparc_reset, sparc_window_underflow);
+ trap(SPARC_RESET, SPARC_WINDOW_UNDERFLOW);
break;
}
else if (ADDRESS & 3)
{
- queue_trap(sparc_reset, sparc_mem_address_not_aligned);
+ trap(SPARC_RESET, SPARC_MEM_ADDRESS_NOT_ALIGNED);
break;
}
}
@@ -963,7 +969,7 @@ bool mb86901_device::execute_group2(UINT32 op)
UINT8 new_cwp = ((m_cwp + WINDOW_COUNT) - 1) % WINDOW_COUNT;
if (m_wim & (1 << new_cwp))
{
- queue_trap(sparc_window_overflow);
+ trap(SPARC_WINDOW_OVERFLOW);
}
else
{
@@ -976,7 +982,7 @@ bool mb86901_device::execute_group2(UINT32 op)
UINT8 new_cwp = (m_cwp + 1) % WINDOW_COUNT;
if (m_wim & (1 << new_cwp))
{
- queue_trap(sparc_window_overflow);
+ trap(SPARC_WINDOW_UNDERFLOW);
}
else
{
@@ -985,7 +991,7 @@ bool mb86901_device::execute_group2(UINT32 op)
break;
}
default:
- queue_trap(sparc_illegal_instruction);
+ trap(SPARC_ILLEGAL_INSTRUCTION);
break;
}
@@ -1014,17 +1020,17 @@ bool mb86901_device::check_main_traps(UINT32 op, bool privileged, UINT32 alignme
bool trap_queued = false;
if (privileged && !m_s)
{
- queue_trap(sparc_privileged_instruction);
+ trap(SPARC_PRIVILEGED_INSTRUCTION);
trap_queued = true;
}
if (alignment & ADDRESS)
{
- queue_trap(sparc_mem_address_not_aligned);
+ trap(SPARC_MEM_ADDRESS_NOT_ALIGNED);
trap_queued = true;
}
if ((registeralign & RD) || (noimmediate && USEIMM))
{
- queue_trap(sparc_illegal_instruction);
+ trap(SPARC_ILLEGAL_INSTRUCTION);
trap_queued = true;
}
return trap_queued;
@@ -1051,21 +1057,44 @@ void mb86901_device::execute_group3(UINT32 op)
switch (OP3)
{
case 0: // ld
+ {
check_main_traps(op, false, 3, 0, false);
- SET_RDREG(read_word(m_data_asi, ADDRESS));
+ UINT32 result = read_word(m_data_asi, ADDRESS);
+ if (MAE || HOLD_BUS)
+ break;
+ SET_RDREG(result);
break;
+ }
case 1: // ldub
- SET_RDREG(read_byte(m_data_asi, ADDRESS));
+ {
+ UINT32 result = read_byte(m_data_asi, ADDRESS);
+ if (MAE || HOLD_BUS)
+ break;
+ SET_RDREG(result);
break;
+ }
case 2: // lduh
+ {
check_main_traps(op, false, 1, 0, false);
- SET_RDREG(read_half(m_data_asi, ADDRESS));
+ UINT32 result = read_half(m_data_asi, ADDRESS);
+ if (MAE || HOLD_BUS)
+ break;
+ SET_RDREG(result);
break;
+ }
case 3: // ldd
+ {
check_main_traps(op, false, 7, 1, false);
- SET_RDREG(read_word(m_data_asi, ADDRESS));
- REG(RD+1) = read_word(m_data_asi, ADDRESS+4);
+ UINT32 result = read_word(m_data_asi, ADDRESS);
+ if (MAE || HOLD_BUS)
+ break;
+ SET_RDREG(result);
+ result = read_word(m_data_asi, ADDRESS+4);
+ if (MAE || HOLD_BUS)
+ break;
+ REG(RD+1) = result;
break;
+ }
case 4: // st
check_main_traps(op, false, 3, 0, false);
write_word(m_data_asi, ADDRESS, RDREG);
@@ -1080,38 +1109,78 @@ void mb86901_device::execute_group3(UINT32 op)
case 7: // std
check_main_traps(op, false, 7, 1, false);
write_word(m_data_asi, ADDRESS, RDREG);
+ if (MAE || HOLD_BUS)
+ break;
write_word(m_data_asi, ADDRESS, REG(RD+1));
break;
case 9: // ldsb
- SET_RDREG(read_signed_byte(m_data_asi, ADDRESS));
+ {
+ UINT32 result = read_signed_byte(m_data_asi, ADDRESS);
+ if (MAE || HOLD_BUS)
+ break;
+ SET_RDREG(result);
break;
+ }
case 10: // lsdh
+ {
check_main_traps(op, false, 1, 0, false);
- SET_RDREG(read_signed_half(m_data_asi, ADDRESS));
+ UINT32 result = read_signed_half(m_data_asi, ADDRESS);
+ if (MAE || HOLD_BUS)
+ break;
+ SET_RDREG(result);
break;
+ }
case 13: // ldstub
- SET_RDREG(read_byte(m_data_asi, ADDRESS));
+ {
+ UINT32 result = read_byte(m_data_asi, ADDRESS);
+ if (MAE || HOLD_BUS)
+ break;
+ SET_RDREG(result);
write_byte(m_data_asi, ADDRESS, 0xff);
break;
+ }
case 15: // swap, SPARCv8
break;
case 16: // lda
+ {
check_main_traps(op, true, 3, 0, true);
- SET_RDREG(read_word(ASI, ADDRESS));
+ UINT32 result = read_word(ASI, ADDRESS);
+ if (MAE || HOLD_BUS)
+ break;
+ SET_RDREG(result);
break;
+ }
case 17: // lduba
+ {
check_main_traps(op, true, 0, 0, true);
- SET_RDREG(read_byte(ASI, ADDRESS));
+ UINT32 result = read_byte(ASI, ADDRESS);
+ if (MAE || HOLD_BUS)
+ break;
+ SET_RDREG(result);
break;
+ }
case 18: // lduha
+ {
check_main_traps(op, true, 1, 0, true);
- SET_RDREG(read_half(ASI, ADDRESS));
+ UINT32 result = read_half(ASI, ADDRESS);
+ if (MAE || HOLD_BUS)
+ break;
+ SET_RDREG(result);
break;
+ }
case 19: // ldda
+ {
check_main_traps(op, true, 7, 1, true);
- SET_RDREG(read_word(ASI, ADDRESS));
- REG(RD+1) = read_word(ASI, ADDRESS+4);
+ UINT32 result = read_word(ASI, ADDRESS);
+ if (MAE || HOLD_BUS)
+ break;
+ SET_RDREG(result);
+ result = read_word(ASI, ADDRESS+4);
+ if (MAE || HOLD_BUS)
+ break;
+ REG(RD+1) = result;
break;
+ }
case 20: // sta
check_main_traps(op, true, 3, 0, true);
write_word(ASI, ADDRESS, RDREG);
@@ -1127,36 +1196,67 @@ void mb86901_device::execute_group3(UINT32 op)
case 23: // stda
check_main_traps(op, true, 7, 1, true);
write_word(ASI, ADDRESS, RDREG);
+ if (MAE || HOLD_BUS)
+ break;
write_word(ASI, ADDRESS+4, REG(RD+1));
break;
case 25: // ldsba
+ {
check_main_traps(op, true, 0, 0, true);
- SET_RDREG(read_signed_byte(ASI, ADDRESS));
+ UINT32 result = read_signed_byte(ASI, ADDRESS);
+ if (MAE || HOLD_BUS)
+ break;
+ SET_RDREG(result);
break;
+ }
case 26: // ldsha
+ {
check_main_traps(op, true, 1, 0, true);
- SET_RDREG(read_signed_half(ASI, ADDRESS));
+ UINT32 result = read_signed_half(ASI, ADDRESS);
+ if (MAE || HOLD_BUS)
+ break;
+ SET_RDREG(result);
break;
+ }
case 29: // ldstuba
+ {
check_main_traps(op, true, 0, 0, true);
- SET_RDREG(read_byte(ASI, ADDRESS));
+ UINT32 result = read_byte(ASI, ADDRESS);
+ if (MAE || HOLD_BUS)
+ break;
+ SET_RDREG(result);
write_byte(ASI, ADDRESS, 0xff);
break;
+ }
case 31: // swapa, SPARCv8
break;
case 32: // ld fpr
+ if (FPU_DISABLED)
+ trap(SPARC_FLOATING_POINT_DISABLED);
break;
case 33: // ld fsr
+ if (FPU_DISABLED)
+ trap(SPARC_FLOATING_POINT_DISABLED);
break;
case 35: // ldd fpr
+ if (FPU_DISABLED)
+ trap(SPARC_FLOATING_POINT_DISABLED);
break;
case 36: // st fpr
+ if (FPU_DISABLED)
+ trap(SPARC_FLOATING_POINT_DISABLED);
break;
case 37: // st fsr
+ if (FPU_DISABLED)
+ trap(SPARC_FLOATING_POINT_DISABLED);
break;
case 38: // std fq, SPARCv8
+ if (FPU_DISABLED)
+ trap(SPARC_FLOATING_POINT_DISABLED);
break;
case 39: // std fpr
+ if (FPU_DISABLED)
+ trap(SPARC_FLOATING_POINT_DISABLED);
break;
case 40: // ld cpr, SPARCv8
break;
@@ -1174,7 +1274,10 @@ void mb86901_device::execute_group3(UINT32 op)
break;
}
- m_icount -= ldst_cycles[OP3];
+ if (MAE || HOLD_BUS)
+ m_icount--;
+ else
+ m_icount -= ldst_cycles[OP3];
}
@@ -1253,7 +1356,7 @@ bool mb86901_device::execute_ticc(UINT32 op)
{
UINT32 arg2 = USEIMM ? SIMM7 : RS2REG;
UINT8 tt = 128 + ((RS1REG + arg2) & 0x7f);
- queue_trap(sparc_trap_instruction, tt);
+ trap(SPARC_TRAP_INSTRUCTION, tt);
m_icount -= 3;
return false;
}
@@ -1263,24 +1366,32 @@ bool mb86901_device::execute_ticc(UINT32 op)
//-------------------------------------------------
-// queue_trap - flag an incoming trap of a given
+// trap - flag an incoming trap of a given
// type
//-------------------------------------------------
-void mb86901_device::queue_trap(UINT8 type, UINT8 tt_override)
+void mb86901_device::trap(UINT8 type, UINT8 tt_override)
{
- if (type == sparc_reset)
+ if (type == SPARC_RESET)
{
m_queued_priority = m_trap_priorities[0];
m_queued_tt = tt_override;
}
else
{
- if (type == sparc_trap_instruction)
+ if (type == SPARC_TRAP_INSTRUCTION)
{
type = tt_override;
}
+ if (type >= SPARC_INT1 && type <= SPARC_INT14)
+ {
+ if (!ET)
+ return;
+ int irl = (type - SPARC_INT1) + 1;
+ if (irl <= PIL)
+ return;
+ }
if (m_trap_priorities[type] < m_queued_priority)
{
m_queued_priority = m_trap_priorities[type];
@@ -1302,6 +1413,7 @@ bool mb86901_device::invoke_queued_traps()
if (m_queued_priority > 0)
{
m_queued_priority = 0;
+ m_queued_tt = 0;
m_et = false;
m_ps = m_s;
@@ -1336,8 +1448,20 @@ void mb86901_device::execute_run()
while (m_icount > 0)
{
+ bool trap_was_queued = invoke_queued_traps();
+ if (trap_was_queued)
+ {
+ m_icount -= 4;
+ continue;
+ }
+
debugger_instruction_hook(this, m_pc);
+ if (HOLD_BUS)
+ {
+ m_icount--;
+ continue;
+ }
UINT32 op = GET_OPCODE;
bool update_npc = true;
@@ -1390,7 +1514,7 @@ void mb86901_device::execute_run()
REG(0) = 0;
bool trap_taken = invoke_queued_traps();
- if (!trap_taken && update_npc)
+ if (!trap_taken && update_npc && !HOLD_BUS)
{
PC = nPC;
nPC = PC + 4;
diff --git a/src/devices/cpu/sparc/sparc.h b/src/devices/cpu/sparc/sparc.h
index 0c23bdbe29c..324d46137a9 100644
--- a/src/devices/cpu/sparc/sparc.h
+++ b/src/devices/cpu/sparc/sparc.h
@@ -9,6 +9,34 @@
#ifndef __SPARC_H__
#define __SPARC_H__
+#define SPARC_RESET 0
+#define SPARC_INSTRUCTION_ACCESS_EXCEPTION 1
+#define SPARC_ILLEGAL_INSTRUCTION 2
+#define SPARC_PRIVILEGED_INSTRUCTION 3
+#define SPARC_FLOATING_POINT_DISABLED 4
+#define SPARC_WINDOW_OVERFLOW 5
+#define SPARC_WINDOW_UNDERFLOW 6
+#define SPARC_MEM_ADDRESS_NOT_ALIGNED 7
+#define SPARC_FLOATING_POINT_EXCEPTION 8
+#define SPARC_DATA_ACCESS_EXCEPTION 9
+#define SPARC_TAG_OVERFLOW 10
+#define SPARC_INT1 17
+#define SPARC_INT2 18
+#define SPARC_INT3 19
+#define SPARC_INT4 20
+#define SPARC_INT5 21
+#define SPARC_INT6 22
+#define SPARC_INT7 23
+#define SPARC_INT8 24
+#define SPARC_INT9 25
+#define SPARC_INT10 26
+#define SPARC_INT11 27
+#define SPARC_INT12 28
+#define SPARC_INT13 29
+#define SPARC_INT14 30
+#define SPARC_INT15 31
+#define SPARC_TRAP_INSTRUCTION 128
+
class mb86901_device : public cpu_device
{
public:
@@ -40,8 +68,12 @@ public:
UINT8 get_asi() { return m_asi; }
UINT32 pc() { return m_pc; }
+ void trap(UINT8 type, UINT8 tt_override = 0);
+ void set_mae() { m_mae = true; }
+ void hold_bus() { m_hold_bus = true; }
+ void release_bus() { m_hold_bus = false; }
+
protected:
- void queue_trap(UINT8 type, UINT8 tt_override = 0);
bool invoke_queued_traps();
bool check_main_traps(UINT32 op, bool privileged, UINT32 alignment, UINT8 registeralign, bool noimmediate);
@@ -103,6 +135,8 @@ protected:
UINT8 m_trap_priorities[256];
UINT8 m_queued_tt;
UINT8 m_queued_priority;
+ bool m_mae;
+ bool m_hold_bus;
int m_icount;
// debugger helpers
diff --git a/src/devices/cpu/sparc/sparcdefs.h b/src/devices/cpu/sparc/sparcdefs.h
index dbc50fd4e00..185845c1d4f 100644
--- a/src/devices/cpu/sparc/sparcdefs.h
+++ b/src/devices/cpu/sparc/sparcdefs.h
@@ -114,35 +114,9 @@
#define Y m_y
-enum sparc_trap_type
-{
- sparc_reset = 0,
- sparc_instruction_access_exception = 1,
- sparc_illegal_instruction = 2,
- sparc_privileged_instruction = 3,
- sparc_floating_point_disabled = 4,
- sparc_window_overflow = 5,
- sparc_window_underflow = 6,
- sparc_mem_address_not_aligned = 7,
- sparc_floating_point_exception = 8,
- sparc_data_access_exception = 9,
- sparc_tag_overflow = 10,
- sparc_int1 = 17,
- sparc_int2 = 18,
- sparc_int3 = 19,
- sparc_int4 = 20,
- sparc_int5 = 21,
- sparc_int6 = 22,
- sparc_int7 = 23,
- sparc_int8 = 24,
- sparc_int9 = 25,
- sparc_int10 = 26,
- sparc_int11 = 27,
- sparc_int12 = 28,
- sparc_int13 = 29,
- sparc_int14 = 30,
- sparc_int15 = 31,
- sparc_trap_instruction = 128
-};
+#define ET m_et
+#define PIL m_pil
+#define MAE m_mae
+#define HOLD_BUS m_hold_bus
#endif // __MB86901_DEFS_H__ \ No newline at end of file
diff --git a/src/devices/machine/8530scc.cpp b/src/devices/machine/8530scc.cpp
index c618fd57004..25484798b36 100644
--- a/src/devices/machine/8530scc.cpp
+++ b/src/devices/machine/8530scc.cpp
@@ -447,7 +447,7 @@ void scc8530_t::set_reg_a(int reg, UINT8 data)
/*-------------------------------------------------
- scc8530_set_reg_a
+ scc8530_set_reg_b
-------------------------------------------------*/
void scc8530_t::set_reg_b(int reg, UINT8 data)
@@ -457,46 +457,41 @@ void scc8530_t::set_reg_b(int reg, UINT8 data)
-/*-------------------------------------------------
- scc8530_r
--------------------------------------------------*/
+//-------------------------------------------------
+// reg_r - read handler, trampolines into normal
+// getter
+//-------------------------------------------------
-READ8_MEMBER( scc8530_t::reg_r)
+READ8_MEMBER(scc8530_t::reg_r)
{
- UINT8 result = 0;
+ return read_reg(offset & 3);
+}
- offset %= 4;
+
+//-------------------------------------------------
+// read_reg - reads either the control or data
+// port for either SCC channel.
+//-------------------------------------------------
+
+UINT8 scc8530_t::read_reg(int offset)
+{
switch(offset)
{
- case 0:
- /* Channel B (Printer Port) Control */
- if (mode == 1)
- mode = 0;
- else
- reg = 0;
-
- result = getbreg();
- break;
+ case 0: /* Channel B (Printer Port) Control */
+ case 1: /* Channel A (Modem Port) Control */
- case 1:
- /* Channel A (Modem Port) Control */
if (mode == 1)
mode = 0;
else
reg = 0;
- result = getareg();
- break;
-
- case 2:
- /* Channel B (Printer Port) Data */
- result = channel[1].rxData;
+ result = (offset == 0) ? getbreg(); : getareg()
break;
- case 3:
- /* Channel A (Modem Port) Data */
- result = channel[0].rxData;
+ case 2: /* Channel B (Printer Port) Data */
+ case 3:/* Channel A (Modem Port) Data */
+ result = channel[offset == 2 ? 1 : 0].rxData;
break;
}
return result;
@@ -504,116 +499,85 @@ READ8_MEMBER( scc8530_t::reg_r)
-/*-------------------------------------------------
- scc8530_w
--------------------------------------------------*/
+//-------------------------------------------------
+// reg_w - write handler, trampolines into normal
+// setter
+//-------------------------------------------------
WRITE8_MEMBER( scc8530_t::reg_w )
{
- Chan *pChan;
+ write_reg(offset & 3, data);
+}
+
- offset &= 3;
+
+//-------------------------------------------------
+// write_reg - writes either the control or data
+// port for either SCC channel.
+//-------------------------------------------------
+
+void scc8530_t::write_reg(int offset, UINT8 data)
+{
+ offset & 3;
// printf(" mode %d data %x offset %d \n", mode, data, offset);
+ Chan *pChan;
switch(offset)
{
- case 0:
- /* Channel B (Printer Port) Control */
- if (mode == 0)
- {
- if((data & 0xf0) == 0) // not a reset command
- {
- mode = 1;
- reg = data & 0x0f;
-// putbreg(data & 0xf0);
- }
- else if (data == 0x10)
- {
- pChan = &channel[1];
- // clear ext. interrupts
- pChan->extIRQPending = 0;
- pChan->baudIRQPending = 0;
- updateirqs();
- }
- }
- else
- {
- mode = 0;
- putreg(1, data);
- }
- break;
-
- case 1:
- /* Channel A (Modem Port) Control */
+ case 0: /* Channel B (Printer Port) Control */
+ case 1: /* Channel A (Modem Port) Control */
+ {
+ int chan = ((offset == 2) ? 1 : 0);
if (mode == 0)
{
if((data & 0xf0) == 0) // not a reset command
{
mode = 1;
reg = data & 0x0f;
-// putareg(data & 0xf0);
+// putbreg(data & 0xf0);
}
else if (data == 0x10)
{
- pChan = &channel[0];
// clear ext. interrupts
- pChan->extIRQPending = 0;
- pChan->baudIRQPending = 0;
+ channel[chan].extIRQPending = 0;
+ channel[chan].baudIRQPending = 0;
updateirqs();
}
}
else
{
mode = 0;
- putreg(0, data);
+ putreg(chan, data);
}
break;
+ }
- case 2:
- /* Channel B (Printer Port) Data */
- pChan = &channel[1];
-
- if (pChan->txEnable)
- {
- pChan->txData = data;
- // local loopback?
- if (pChan->reg_val[14] & 0x10)
- {
- pChan->rxData = data;
- pChan->reg_val[0] |= 0x01; // Rx character available
- }
- pChan->reg_val[1] |= 0x01; // All sent
- pChan->reg_val[0] |= 0x04; // Tx empty
- pChan->txUnderrun = 1;
- pChan->txIRQPending = 1;
- updateirqs();
- }
- break;
-
- case 3:
- /* Channel A (Modem Port) Data */
- pChan = &channel[0];
-
- if (pChan->txEnable)
+ case 2: /* Channel B (Printer Port) Data */
+ case 3: /* Channel A (Modem Port) Data */
+ {
+ int chan = ((offset == 2) ? 1 : 0);
+ if (channel[chan].txEnable)
{
- pChan->txData = data;
+ channel[chan].txData = data;
// local loopback?
- if (pChan->reg_val[14] & 0x10)
+ if (channel[chan].reg_val[14] & 0x10)
{
- pChan->rxData = data;
- pChan->reg_val[0] |= 0x01; // Rx character available
+ channel[chan].rxData = data;
+ channel[chan].reg_val[0] |= 0x01; // Rx character available
}
- pChan->reg_val[1] |= 0x01; // All sent
- pChan->reg_val[0] |= 0x04; // Tx empty
- pChan->txUnderrun = 1;
- pChan->txIRQPending = 1;
+ channel[chan].reg_val[1] |= 0x01; // All sent
+ channel[chan].reg_val[0] |= 0x04; // Tx empty
+ channel[chan].txUnderrun = 1;
+ channel[chan].txIRQPending = 1;
updateirqs();
}
break;
+ }
}
}
+
/*
AppleTalk check:
diff --git a/src/devices/machine/8530scc.h b/src/devices/machine/8530scc.h
index 2e6e703ceb8..b711f7cdabe 100644
--- a/src/devices/machine/8530scc.h
+++ b/src/devices/machine/8530scc.h
@@ -43,6 +43,9 @@ public:
DECLARE_READ8_MEMBER(reg_r);
DECLARE_WRITE8_MEMBER(reg_w);
+ void write_reg(int offset, UINT8 data);
+ UINT8 read_reg(int offset);
+
protected:
virtual void device_start() override;
virtual void device_reset() override;
diff --git a/src/devices/video/zeus2.cpp b/src/devices/video/zeus2.cpp
new file mode 100644
index 00000000000..02e9b9d9e52
--- /dev/null
+++ b/src/devices/video/zeus2.cpp
@@ -0,0 +1,1311 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles
+/*************************************************************************
+
+ Midway Zeus2 Video
+
+**************************************************************************/
+#include "zeus2.h"
+
+#define LOG_REGS 0
+
+/*************************************
+* Constructor
+*************************************/
+zeus2_renderer::zeus2_renderer(zeus2_device *state)
+ : poly_manager<float, zeus2_poly_extra_data, 4, 10000>(state->machine())
+ , m_state(state)
+{
+}
+
+const device_type ZEUS2 = &device_creator<zeus2_device>;
+
+zeus2_device::zeus2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, ZEUS2, "Midway Zeus2", tag, owner, clock, "zeus2", __FILE__),
+ m_vblank(*this), m_irq(*this)
+{
+}
+
+/*************************************
+* Display interrupt generation
+*************************************/
+
+TIMER_CALLBACK_MEMBER(zeus2_device::display_irq_off)
+{
+ m_vblank(CLEAR_LINE);
+
+ //attotime vblank_period = m_screen->time_until_pos(m_zeusbase[0x37] & 0xffff);
+
+ ///* if zero, adjust to next frame, otherwise we may get stuck in an infinite loop */
+ //if (vblank_period == attotime::zero)
+ // vblank_period = m_screen->frame_period();
+ //vblank_timer->adjust(vblank_period);
+ vblank_timer->adjust(m_screen->time_until_vblank_start());
+ //machine().scheduler().timer_set(attotime::from_hz(30000000), timer_expired_delegate(FUNC(zeus2_device::display_irq), this));
+}
+
+TIMER_CALLBACK_MEMBER(zeus2_device::display_irq)
+{
+ m_vblank(ASSERT_LINE);
+ /* set a timer for the next off state */
+ //machine().scheduler().timer_set(m_screen->time_until_pos(0), timer_expired_delegate(FUNC(zeus2_device::display_irq_off), this), 0, this);
+ machine().scheduler().timer_set(m_screen->time_until_vblank_end(), timer_expired_delegate(FUNC(zeus2_device::display_irq_off), this), 0, this);
+ //machine().scheduler().timer_set(attotime::from_hz(30000000), timer_expired_delegate(FUNC(zeus2_device::display_irq_off), this));
+}
+
+TIMER_CALLBACK_MEMBER(zeus2_device::int_timer_callback)
+{
+ //m_maincpu->set_input_line(2, ASSERT_LINE);
+ m_irq(ASSERT_LINE);
+}
+
+/*************************************
+ * Video startup
+ *************************************/
+
+
+void zeus2_device::device_start()
+{
+
+ /* allocate memory for "wave" RAM */
+ waveram[0] = auto_alloc_array(machine(), UINT32, WAVERAM0_WIDTH * WAVERAM0_HEIGHT * 8/4);
+ waveram[1] = auto_alloc_array(machine(), UINT32, WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 12/4);
+
+ /* initialize polygon engine */
+ poly = auto_alloc(machine(), zeus2_renderer(this));
+
+ //m_screen = machine().first_screen();
+ m_screen = downcast<screen_device *>(machine().device("screen"));
+ m_vblank.resolve_safe();
+ m_irq.resolve_safe();
+
+ /* we need to cleanup on exit */
+ //machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(zeus2_device::exit_handler2), this));
+
+ int_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(zeus2_device::int_timer_callback), this));
+ vblank_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(zeus2_device::display_irq), this));
+
+ /* save states */
+ save_pointer(NAME(waveram[0]), WAVERAM0_WIDTH * WAVERAM0_HEIGHT * 8 / sizeof(waveram[0][0]));
+ save_pointer(NAME(waveram[1]), WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 12 / sizeof(waveram[1][0]));
+ save_pointer(NAME(m_zeusbase), sizeof(m_zeusbase[0])*0x80);
+ save_item(NAME(zeus_fifo));
+ save_item(NAME(zeus_fifo_words));
+ save_item(NAME(zeus_cliprect.min_x));
+ save_item(NAME(zeus_cliprect.max_x));
+ save_item(NAME(zeus_cliprect.min_y));
+ save_item(NAME(zeus_cliprect.max_y));
+ save_item(NAME(zeus_matrix));
+ save_item(NAME(zeus_point));
+ save_item(NAME(zeus_texbase));
+ save_item(NAME(m_fill_color));
+ save_item(NAME(m_fill_depth));
+}
+
+void zeus2_device::device_reset()
+{
+ memset(m_zeusbase, 0, sizeof(m_zeusbase));
+ zbase = 2.0f;
+ m_yScale = 0;
+ yoffs = 0;
+ texel_width = 256;
+ zeus_renderbase = waveram[1];
+ zeus_fifo_words = 0;
+ m_fill_color = 0;
+ m_fill_depth = 0;
+}
+
+void zeus2_device::device_stop()
+{
+#if DUMP_WAVE_RAM
+ FILE *f = fopen("waveram.dmp", "w");
+ int i;
+
+ for (i = 0; i < WAVERAM0_WIDTH * WAVERAM0_HEIGHT; i++)
+ {
+ if (i % 4 == 0) fprintf(f, "%03X%03X: ", i / WAVERAM0_WIDTH, i % WAVERAM0_WIDTH);
+ fprintf(f, " %08X %08X ",
+ WAVERAM_READ32(waveram[0], i*2+0),
+ WAVERAM_READ32(waveram[0], i*2+1));
+ if (i % 4 == 3) fprintf(f, "\n");
+ }
+ fclose(f);
+#endif
+
+#if TRACK_REG_USAGE
+{
+ reg_info *info;
+ int regnum;
+
+ for (regnum = 0; regnum < 0x80; regnum++)
+ {
+ printf("Register %02X\n", regnum);
+ if (regread_count[regnum] == 0)
+ printf("\tNever read\n");
+ else
+ printf("\tRead %d times\n", regread_count[regnum]);
+
+ if (regwrite_count[regnum] == 0)
+ printf("\tNever written\n");
+ else
+ {
+ printf("\tWritten %d times\n", regwrite_count[regnum]);
+ for (info = regdata[regnum]; info != nullptr; info = info->next)
+ printf("\t%08X\n", info->value);
+ }
+ }
+
+ for (regnum = 0; regnum < 0x100; regnum++)
+ if (subregwrite_count[regnum] != 0)
+ {
+ printf("Sub-Register %02X (%d writes)\n", regnum, subregwrite_count[regnum]);
+ for (info = subregdata[regnum]; info != nullptr; info = info->next)
+ printf("\t%08X\n", info->value);
+ }
+}
+#endif
+
+}
+
+
+
+/*************************************
+ *
+ * Video update
+ *
+ *************************************/
+
+UINT32 zeus2_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ int x, y;
+
+ poly->wait();
+
+if (machine().input().code_pressed(KEYCODE_UP)) { zbase += 1.0f; popmessage("Zbase = %f", (double) zbase); }
+if (machine().input().code_pressed(KEYCODE_DOWN)) { zbase -= 1.0f; popmessage("Zbase = %f", (double) zbase); }
+
+ /* normal update case */
+ if (!machine().input().code_pressed(KEYCODE_W))
+ {
+ const void *base = waveram1_ptr_from_expanded_addr(m_zeusbase[0x38] >> m_yScale);
+ int xoffs = screen.visible_area().min_x;
+ for (y = cliprect.min_y; y <= cliprect.max_y; y++)
+ {
+ UINT32 *dest = &bitmap.pix32(y);
+ UINT32 bufY = y >> m_yScale;
+ UINT32 bufOffsX = (m_yScale && (y & 1)) ? 0x200 : 0;
+ for (x = cliprect.min_x; x <= cliprect.max_x; x++) {
+ UINT32 bufX = x - xoffs + bufOffsX;
+ dest[x] = WAVERAM_READPIX(base, bufY, bufX);
+ //dest[x] = WAVERAM_READPIX(base, y, x - xoffs);
+ }
+ }
+ }
+
+ /* waveram drawing case */
+ else
+ {
+ const UINT64 *base;
+
+ if (machine().input().code_pressed(KEYCODE_DOWN)) yoffs += machine().input().code_pressed(KEYCODE_LSHIFT) ? 0x40 : 1;
+ if (machine().input().code_pressed(KEYCODE_UP)) yoffs -= machine().input().code_pressed(KEYCODE_LSHIFT) ? 0x40 : 1;
+ if (machine().input().code_pressed(KEYCODE_LEFT) && texel_width > 4) { texel_width >>= 1; while (machine().input().code_pressed(KEYCODE_LEFT)) ; }
+ if (machine().input().code_pressed(KEYCODE_RIGHT) && texel_width < 512) { texel_width <<= 1; while (machine().input().code_pressed(KEYCODE_RIGHT)) ; }
+
+ if (yoffs < 0) yoffs = 0;
+ if (0)
+ base = (const UINT64 *)waveram0_ptr_from_expanded_addr(yoffs << 16);
+ else
+ base = (const UINT64 *)waveram1_ptr_from_expanded_addr(yoffs << 16);
+
+ int xoffs = screen.visible_area().min_x;
+ for (y = cliprect.min_y; y <= cliprect.max_y; y++)
+ {
+ UINT32 *dest = &bitmap.pix32(y);
+ for (x = cliprect.min_x; x <= cliprect.max_x; x++)
+ {
+ if (0) {
+ UINT8 tex = get_texel_8bit(base, y, x, texel_width);
+ dest[x] = (tex << 16) | (tex << 8) | tex;
+ }
+ else {
+ dest[x] = WAVERAM_READPIX(base, y, x - xoffs);
+ }
+ }
+ }
+ popmessage("offs = %06X", yoffs);
+ }
+
+ return 0;
+}
+
+
+
+/*************************************
+ *
+ * Core read handler
+ *
+ *************************************/
+
+READ32_MEMBER( zeus2_device::zeus2_r )
+{
+ int logit = (offset != 0x00 && offset != 0x01 &&
+ offset != 0x48 && offset != 0x49 &&
+ offset != 0x54 && offset != 0x58 && offset != 0x59 && offset != 0x5a);
+ logit &= LOG_REGS;
+ UINT32 result = m_zeusbase[offset];
+#if TRACK_REG_USAGE
+ regread_count[offset]++;
+#endif
+
+ switch (offset)
+ {
+ case 0x00:
+ result = 0x20;
+ break;
+
+ case 0x01:
+ /* bit $000C0070 are tested in a loop until 0 */
+ /* bits $00080000 is tested in a loop until 0 */
+ /* bit $00000004 is tested for toggling; probably VBLANK */
+ result = 0x00;
+ if (m_screen->vblank())
+ result |= 0x04;
+ break;
+
+ case 0x07:
+ /* this is needed to pass the self-test in thegrid */
+ result = 0x10451998;
+ break;
+
+ case 0x54:
+ /* both upper 16 bits and lower 16 bits seem to be used as vertical counters */
+ result = (m_screen->vpos() << 16) | m_screen->vpos();
+ break;
+ }
+
+ if (logit)
+ logerror("%08X:zeus2_r(%02X) = %08X\n", machine().device("maincpu")->safe_pc(), offset, result);
+
+ return result;
+}
+
+
+
+/*************************************
+ *
+ * Core write handler
+ *
+ *************************************/
+
+WRITE32_MEMBER( zeus2_device::zeus2_w )
+{
+ int logit = (offset != 0x08 &&
+ (offset != 0x20 || data != 0) &&
+ offset != 0x40 && offset != 0x41 && offset != 0x48 && offset != 0x49 && offset != 0x4e &&
+ offset != 0x50 && offset != 0x51 && offset != 0x57 && offset != 0x58 && offset != 0x59 && offset != 0x5a && offset != 0x5e);
+ logit &= LOG_REGS;
+ if (logit)
+ logerror("%08X:zeus2_w", machine().device("maincpu")->safe_pc());
+ zeus2_register32_w(offset, data, logit);
+}
+
+
+
+/*************************************
+ *
+ * Handle register writes
+ *
+ *************************************/
+
+void zeus2_device::zeus2_register32_w(offs_t offset, UINT32 data, int logit)
+{
+ UINT32 oldval = m_zeusbase[offset];
+
+#if TRACK_REG_USAGE
+regwrite_count[offset]++;
+if (regdata_count[offset] < 256)
+{
+ reg_info **tailptr;
+
+ for (tailptr = &regdata[offset]; *tailptr != nullptr; tailptr = &(*tailptr)->next)
+ if ((*tailptr)->value == data)
+ break;
+ if (*tailptr == nullptr)
+ {
+ *tailptr = alloc_or_die(reg_info);
+ (*tailptr)->next = nullptr;
+ (*tailptr)->value = data;
+ regdata_count[offset]++;
+ }
+}
+#endif
+
+ /* writes to register $CC need to force a partial update */
+// if ((offset & ~1) == 0xcc)
+// m_screen->update_partial(m_screen->vpos());
+
+ /* always write to low word? */
+ m_zeusbase[offset] = data;
+
+ /* log appropriately */
+ if (logit)
+ logerror("(%02X) = %08X\n", offset, data);
+
+ /* handle the update */
+ zeus2_register_update(offset, oldval, logit);
+}
+
+
+
+/*************************************
+ *
+ * Update state after a register write
+ *
+ *************************************/
+
+void zeus2_device::zeus2_register_update(offs_t offset, UINT32 oldval, int logit)
+{
+ /* handle the writes; only trigger on low accesses */
+ switch (offset)
+ {
+ case 0x08:
+ zeus_fifo[zeus_fifo_words++] = m_zeusbase[0x08];
+ if (zeus2_fifo_process(zeus_fifo, zeus_fifo_words))
+ zeus_fifo_words = 0;
+
+ /* set the interrupt signal to indicate we can handle more */
+ int_timer->adjust(attotime::from_nsec(500));
+ break;
+
+ case 0x20:
+ /* toggles between two values based on the page:
+
+ Page # m_zeusbase[0x20] m_zeusbase[0x38]
+ ------ -------------- --------------
+ 0 $04000190 $00000000
+ 1 $04000000 $01900000
+ */
+ zeus2_pointer_write(m_zeusbase[0x20] >> 24, m_zeusbase[0x20]);
+ break;
+
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0x36:
+ case 0x37:
+ m_screen->update_partial(m_screen->vpos());
+ {
+ // Just a guess. Atlantis startup has two scanlines per physical ram row
+ if ((m_zeusbase[0x30] & 0xfff) <= 0x100)
+ m_yScale = 1;
+ else
+ m_yScale = 0;
+ int vtotal = (m_zeusbase[0x37] & 0xffff) << m_yScale;
+ int htotal = (m_zeusbase[0x34] >> 16);
+
+ rectangle visarea((m_zeusbase[0x33] >> 16), htotal - 1, 0, (m_zeusbase[0x35] & 0xffff)<< m_yScale);
+ if (htotal > 0 && vtotal > 0 && visarea.min_x < visarea.max_x && visarea.max_y < vtotal)
+ {
+ m_screen->configure(htotal, vtotal, visarea, HZ_TO_ATTOSECONDS((double)ZEUS2_VIDEO_CLOCK / 4.0 / (htotal * vtotal)));
+ zeus_cliprect = visarea;
+ zeus_cliprect.max_x -= zeus_cliprect.min_x;
+ zeus_cliprect.min_x = 0;
+ // Startup vblank timer
+ vblank_timer->adjust(attotime::from_usec(100));
+ }
+ }
+ break;
+
+ case 0x38:
+ {
+ UINT32 temp = m_zeusbase[0x38];
+ m_zeusbase[0x38] = oldval;
+ m_screen->update_partial(m_screen->vpos());
+ log_fifo = machine().input().code_pressed(KEYCODE_L);
+ //log_fifo = 1;
+ m_zeusbase[0x38] = temp;
+ }
+ break;
+
+ case 0x40:
+ /* in direct mode it latches values */
+ if ((m_zeusbase[0x4e] & 0x20) && m_zeusbase[0x40] == 0x00820000)
+ {
+ const void *src = waveram0_ptr_from_expanded_addr(m_zeusbase[0x41]);
+ m_zeusbase[0x48] = WAVERAM_READ32(src, 0);
+ m_zeusbase[0x49] = WAVERAM_READ32(src, 1);
+
+ if (m_zeusbase[0x4e] & 0x40)
+ {
+ m_zeusbase[0x41]++;
+ m_zeusbase[0x41] += (m_zeusbase[0x41] & 0x400) << 6;
+ m_zeusbase[0x41] &= ~0xfc00;
+ }
+ }
+ break;
+ case 0x41:
+ /* this is the address, except in read mode, where it latches values */
+ if (m_zeusbase[0x4e] & 0x10)
+ {
+ const void *src = waveram0_ptr_from_expanded_addr(oldval);
+ m_zeusbase[0x41] = oldval;
+ m_zeusbase[0x48] = WAVERAM_READ32(src, 0);
+ m_zeusbase[0x49] = WAVERAM_READ32(src, 1);
+
+ if (m_zeusbase[0x4e] & 0x40)
+ {
+ m_zeusbase[0x41]++;
+ m_zeusbase[0x41] += (m_zeusbase[0x41] & 0x400) << 6;
+ m_zeusbase[0x41] &= ~0xfc00;
+ }
+ } else {
+ // mwskinsa (atlantis) writes 0xffffffff and expects 0x1fff03ff to be read back
+ m_zeusbase[0x41] &= 0x1fff03ff;
+ }
+ break;
+
+ case 0x48:
+ case 0x49:
+ /* if we're in write mode, process it */
+ if (m_zeusbase[0x40] == 0x00890000)
+ {
+ /*
+ m_zeusbase[0x4e]:
+ bit 0-1: which register triggers write through
+ bit 3: enable write through via these registers
+ bit 4: seems to be set during reads, when 0x41 is used for latching
+ bit 6: enable autoincrement on write through
+ */
+ if ((m_zeusbase[0x4e] & 0x08) && (offset & 3) == (m_zeusbase[0x4e] & 3))
+ {
+ void *dest = waveram0_ptr_from_expanded_addr(m_zeusbase[0x41]);
+ WAVERAM_WRITE32(dest, 0, m_zeusbase[0x48]);
+ WAVERAM_WRITE32(dest, 1, m_zeusbase[0x49]);
+
+ if (m_zeusbase[0x4e] & 0x40)
+ {
+ m_zeusbase[0x41]++;
+ m_zeusbase[0x41] += (m_zeusbase[0x41] & 0x400) << 6;
+ m_zeusbase[0x41] &= ~0xfc00;
+ }
+ }
+ }
+
+ /* make sure we log anything else */
+ else if (logit)
+ logerror("\t[40]=%08X [4E]=%08X\n", m_zeusbase[0x40], m_zeusbase[0x4e]);
+ break;
+
+ case 0x50:
+ if (m_zeusbase[0x50] == 0x00510000) {
+ // SGRAM Special Mode Register Write
+ if (m_zeusbase[0x51] & 0x00400000) {
+ // SGRAM Mask Register
+ if ((m_zeusbase[0x58] & m_zeusbase[0x59] & m_zeusbase[0x5a]) != 0xffffffff)
+ logerror("zeus2_register_update: Warning! Mask Register not equal to 0xffffffff\n");
+ }
+ if (m_zeusbase[0x51] & 0x00200000) {
+ // SGRAM Color Register
+ m_fill_color = m_zeusbase[0x58];
+ m_fill_depth = m_zeusbase[0x5a] & 0xffff;
+ if (m_zeusbase[0x58] != m_zeusbase[0x59])
+ logerror("zeus2_register_update: Warning! Different fill colors are set.\n");
+ }
+ }
+ else if (1 && (m_zeusbase[0x50] & 0x00080000) && (m_zeusbase[0x50] & 0xffff)) {
+ // Fast fill
+ // Unknown what the exact bit fields are, this is a just a guess
+ // Atlantis: 0x00983FFF => clear entire frame buffer, 0x00981FFF => clear one frame
+ // crusnexo: 0x007831FF => clear one frame
+ // thegrid: 0x008831FF => clear one frame
+ //UINT32 lastRow = (((m_zeusbase[0x50] >> 8) & 0xff) << 3) | 0x7;
+ UINT32 lastRow = (((m_zeusbase[0x50] >> 8) & 0xff) << 3) | 0x3;
+ UINT32 lastCol = (((m_zeusbase[0x50] >> 0) & 0xff) << 2) | 0x3;
+ // Not sure how to select
+ //void *base = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]);
+ void *base = (m_zeusbase[0x50] & 0x800000) ? waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]) : zeus_renderbase;
+ for (int y = 0; y <= lastRow; y++)
+ for (int x = 0; x <= lastCol; x++) {
+ WAVERAM_WRITEPIX(base, y, x, m_fill_color);
+ WAVERAM_WRITEDEPTH(base, y, x, m_fill_depth);
+ }
+ //waveram_plot_depth(y, x, m_fill_color, m_fill_depth);
+ }
+ else if ((m_zeusbase[0x5e] >> 16) != 0xF208) {
+ /* If 0x5e==0xf20a0000 (atlantis) or 0xf20d0000 (the grid) then process the read/write now */
+ /*
+ m_zeusbase[0x5e]:
+ bit 0-1: which register triggers write through
+ bit 3: enable write through via these registers
+ bit 4: seems to be set during reads, when 0x51 is used for latching
+ bit 5: unknown, currently used to specify ordering, but this is suspect
+ bit 6: enable autoincrement on write through
+ */
+ if (m_zeusbase[0x50] == 0x00890000)
+ {
+ void *dest = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]);
+ WAVERAM_WRITE32(dest, 0, m_zeusbase[0x58]);
+ if (m_zeusbase[0x5e] & 0x20)
+ WAVERAM_WRITE32(dest, 1, m_zeusbase[0x5a]);
+ else
+ {
+ WAVERAM_WRITE32(dest, 1, m_zeusbase[0x59]);
+ WAVERAM_WRITE32(dest, 2, m_zeusbase[0x5a]);
+ }
+
+ if (m_zeusbase[0x5e] & 0x40)
+ {
+ m_zeusbase[0x51]++;
+ m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7;
+ m_zeusbase[0x51] &= ~0xfe00;
+ }
+ }
+ else if (m_zeusbase[0x50] == 0x00720000) {
+ /* Do the read */
+ const void *src = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]);
+ m_zeusbase[0x58] = WAVERAM_READ32(src, 0);
+ m_zeusbase[0x59] = WAVERAM_READ32(src, 1);
+ m_zeusbase[0x5a] = WAVERAM_READ32(src, 2);
+
+ if (m_zeusbase[0x5e] & 0x40)
+ {
+ m_zeusbase[0x51]++;
+ m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7;
+ m_zeusbase[0x51] &= ~0xfe00;
+ }
+ }
+ }
+ break;
+ case 0x51:
+
+ /* in this mode, crusnexo expects the reads to immediately latch */
+ //if ((m_zeusbase[0x50] == 0x00a20000) || (m_zeusbase[0x50] == 0x00720000))
+ if (m_zeusbase[0x50] == 0x00a20000)
+ oldval = m_zeusbase[0x51];
+
+ /* this is the address, except in read mode, where it latches values */
+ if ((m_zeusbase[0x5e] & 0x10) || (m_zeusbase[0x50] == 0x00a20000))
+ {
+ const void *src = waveram1_ptr_from_expanded_addr(oldval);
+ m_zeusbase[0x51] = oldval;
+ m_zeusbase[0x58] = WAVERAM_READ32(src, 0);
+ m_zeusbase[0x59] = WAVERAM_READ32(src, 1);
+ m_zeusbase[0x5a] = WAVERAM_READ32(src, 2);
+
+ if (m_zeusbase[0x5e] & 0x40)
+ {
+ m_zeusbase[0x51]++;
+ m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7;
+ m_zeusbase[0x51] &= ~0xfe00;
+ }
+ }
+ break;
+
+ case 0x57:
+ /* thegrid uses this to write either left or right halves of pixels */
+ if (m_zeusbase[0x50] == 0x00e90000)
+ {
+ void *dest = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]);
+ if (m_zeusbase[0x57] & 1)
+ WAVERAM_WRITE32(dest, 0, m_zeusbase[0x58]);
+ if (m_zeusbase[0x57] & 4)
+ WAVERAM_WRITE32(dest, 1, m_zeusbase[0x59]);
+ }
+
+ /* make sure we log anything else */
+ else if (logit)
+ logerror("\t[50]=%08X [5E]=%08X\n", m_zeusbase[0x50], m_zeusbase[0x5e]);
+ break;
+
+ case 0x58:
+ case 0x59:
+ case 0x5a:
+ /* if we're in write mode, process it */
+ if (m_zeusbase[0x50] == 0x00890000)
+ {
+ /*
+ m_zeusbase[0x5e]:
+ bit 0-1: which register triggers write through
+ bit 3: enable write through via these registers
+ bit 4: seems to be set during reads, when 0x51 is used for latching
+ bit 5: unknown, currently used to specify ordering, but this is suspect
+ bit 6: enable autoincrement on write through
+ */
+ if ((m_zeusbase[0x5e] & 0x08) && (offset & 3) == (m_zeusbase[0x5e] & 3))
+ {
+ void *dest = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]);
+ WAVERAM_WRITE32(dest, 0, m_zeusbase[0x58]);
+ if (m_zeusbase[0x5e] & 0x20)
+ WAVERAM_WRITE32(dest, 1, m_zeusbase[0x5a]);
+ else
+ {
+ WAVERAM_WRITE32(dest, 1, m_zeusbase[0x59]);
+ WAVERAM_WRITE32(dest, 2, m_zeusbase[0x5a]);
+ }
+
+ if (m_zeusbase[0x5e] & 0x40)
+ {
+ m_zeusbase[0x51]++;
+ m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7;
+ m_zeusbase[0x51] &= ~0xfe00;
+ }
+ }
+ }
+
+ /* make sure we log anything else */
+ else if (logit)
+ logerror("\t[50]=%08X [5E]=%08X\n", m_zeusbase[0x50], m_zeusbase[0x5e]);
+ break;
+ }
+}
+
+
+
+/*************************************
+ *
+ * Process the FIFO
+ *
+ *************************************/
+
+void zeus2_device::zeus2_pointer_write(UINT8 which, UINT32 value)
+{
+#if TRACK_REG_USAGE
+subregwrite_count[which]++;
+if (subregdata_count[which] < 256)
+{
+ reg_info **tailptr;
+
+ for (tailptr = &subregdata[which]; *tailptr != nullptr; tailptr = &(*tailptr)->next)
+ if ((*tailptr)->value == value)
+ break;
+ if (*tailptr == nullptr)
+ {
+ *tailptr = alloc_or_die(reg_info);
+ (*tailptr)->next = nullptr;
+ (*tailptr)->value = value;
+ subregdata_count[which]++;
+ }
+}
+#endif
+
+ switch (which)
+ {
+ case 0x04:
+ zeus_renderbase = waveram1_ptr_from_expanded_addr(value << 16);
+ break;
+
+ case 0x05:
+ zeus_texbase = value % (WAVERAM0_HEIGHT * WAVERAM0_WIDTH);
+ break;
+
+ case 0x40:
+ zeus_unknown_40 = value & 0xffffff;
+ zeus_quad_size = (zeus_unknown_40 == 0) ? 10 : 14;
+ break;
+
+#if 0
+ case 0x0c:
+ case 0x0d:
+ // These seem to have something to do with blending.
+ // There are fairly unique 0x0C,0x0D pairs for various things:
+ // Car reflection on initial screen: 0x40, 0x00
+ // Additively-blended "flares": 0xFA, 0xFF
+ // Car windshields (and drivers, apparently): 0x82, 0x7D
+ // Other minor things: 0xA4, 0x100
+ break;
+#endif
+ }
+}
+
+/*************************************
+ * Process the FIFO
+ *************************************/
+
+int zeus2_device::zeus2_fifo_process(const UINT32 *data, int numwords)
+{
+ int dataoffs = 0;
+
+ /* handle logging */
+ switch (data[0] >> 24)
+ {
+ // 0x00: write 32-bit value to low registers
+ case 0x00:
+ // Ignore the all zeros commmand
+ if (((data[0] >> 16) & 0x7f) == 0x0)
+ return TRUE;
+ // Drop through to 0x05 command
+ /* 0x05: write 32-bit value to low registers */
+ case 0x05:
+ if (numwords < 2)
+ return FALSE;
+ if (log_fifo)
+ log_fifo_command(data, numwords, " -- reg32");
+ if (((data[0] >> 16) & 0x7f) != 0x08)
+ zeus2_register32_w((data[0] >> 16) & 0x7f, data[1], log_fifo);
+ break;
+
+ /* 0x08: set matrix and point (thegrid) */
+ case 0x08:
+ if (numwords < 14)
+ return FALSE;
+ dataoffs = 1;
+
+ /* 0x07: set matrix and point (crusnexo) */
+ case 0x07:
+ if (numwords < 13)
+ return FALSE;
+
+ /* extract the matrix from the raw data */
+ zeus_matrix[0][0] = tms3203x_device::fp_to_float(data[dataoffs + 1]);
+ zeus_matrix[0][1] = tms3203x_device::fp_to_float(data[dataoffs + 2]);
+ zeus_matrix[0][2] = tms3203x_device::fp_to_float(data[dataoffs + 3]);
+ zeus_matrix[1][0] = tms3203x_device::fp_to_float(data[dataoffs + 4]);
+ zeus_matrix[1][1] = tms3203x_device::fp_to_float(data[dataoffs + 5]);
+ zeus_matrix[1][2] = tms3203x_device::fp_to_float(data[dataoffs + 6]);
+ zeus_matrix[2][0] = tms3203x_device::fp_to_float(data[dataoffs + 7]);
+ zeus_matrix[2][1] = tms3203x_device::fp_to_float(data[dataoffs + 8]);
+ zeus_matrix[2][2] = tms3203x_device::fp_to_float(data[dataoffs + 9]);
+
+ /* extract the translation point from the raw data */
+ zeus_point[0] = tms3203x_device::fp_to_float(data[dataoffs + 10]);
+ zeus_point[1] = tms3203x_device::fp_to_float(data[dataoffs + 11]);
+ zeus_point[2] = tms3203x_device::fp_to_float(data[dataoffs + 12]);
+
+ if (log_fifo)
+ {
+ log_fifo_command(data, numwords, "\n");
+ logerror("\t\tmatrix ( %8.2f %8.2f %8.2f ) ( %8.2f %8.2f %8.2f ) ( %8.2f %8.2f %8.2f )\n\t\tvector %8.2f %8.2f %8.5f\n",
+ (double) zeus_matrix[0][0], (double) zeus_matrix[0][1], (double) zeus_matrix[0][2],
+ (double) zeus_matrix[1][0], (double) zeus_matrix[1][1], (double) zeus_matrix[1][2],
+ (double) zeus_matrix[2][0], (double) zeus_matrix[2][1], (double) zeus_matrix[2][2],
+ (double) zeus_point[0],
+ (double) zeus_point[1],
+ (double) zeus_point[2]);
+ }
+ break;
+
+ // 0x14: ?? atlantis
+ /* 0x15: set point only (thegrid) */
+ /* 0x16: set point only (crusnexo) */
+ case 0x14:
+ case 0x15:
+ case 0x16:
+ if (numwords < 4)
+ return FALSE;
+
+ /* extract the translation point from the raw data */
+ zeus_point[0] = tms3203x_device::fp_to_float(data[1]);
+ zeus_point[1] = tms3203x_device::fp_to_float(data[2]);
+ zeus_point[2] = tms3203x_device::fp_to_float(data[3]);
+
+ if (log_fifo)
+ {
+ log_fifo_command(data, numwords, "\n");
+ logerror("\t\tvector %8.2f %8.2f %8.5f\n",
+ (double) zeus_point[0],
+ (double) zeus_point[1],
+ (double) zeus_point[2]);
+ }
+ break;
+
+ /* 0x1c: */
+ case 0x1c:
+ if (numwords < 4)
+ return FALSE;
+ if (log_fifo)
+ {
+ log_fifo_command(data, numwords, " -- unknown control + hack clear screen\n");
+ logerror("\t\tvector %8.2f %8.2f %8.5f\n",
+ (double) tms3203x_device::fp_to_float(data[1]),
+ (double) tms3203x_device::fp_to_float(data[2]),
+ (double) tms3203x_device::fp_to_float(data[3]));
+
+ /* extract the translation point from the raw data */
+ zeus_point2[0] = tms3203x_device::fp_to_float(data[1]);
+ zeus_point2[1] = tms3203x_device::fp_to_float(data[2]);
+ zeus_point2[2] = tms3203x_device::fp_to_float(data[3]);
+ }
+ {
+ /* not right -- just a hack */
+ if (0) {
+ int x, y;
+ for (y = zeus_cliprect.min_y; y <= zeus_cliprect.max_y; y++)
+ for (x = zeus_cliprect.min_x; x <= zeus_cliprect.max_x; x++)
+ waveram_plot_depth(y, x, 0, 0x7fff);
+ }
+ }
+ break;
+
+ /* 0x23: render model in waveram (thegrid) */
+ /* 0x24: render model in waveram (crusnexo) */
+ // 0x17: ??? (atlantis)
+ case 0x17:
+ case 0x23:
+ case 0x24:
+ if (numwords < 2)
+ return FALSE;
+ if (log_fifo)
+ log_fifo_command(data, numwords, "");
+ //zeus2_draw_model(data[1], data[0] & 0xffff, log_fifo);
+ zeus2_draw_model(data[1], data[0] & 0x3fff, log_fifo);
+ break;
+
+ // 0x2d; ??? (atlantis)
+ case 0x2d:
+ if (numwords < 2)
+ return FALSE;
+ if (log_fifo)
+ log_fifo_command(data, numwords, "\n");
+ //zeus2_draw_model(data[1], data[0] & 0xff, log_fifo);
+ break;
+
+ /* 0x31: sync pipeline? (thegrid) */
+ /* 0x32: sync pipeline? (crusnexo) */
+ // 0x25 ?? (atlantis)
+ case 0x25:
+ case 0x31:
+ case 0x32:
+ if (log_fifo)
+ log_fifo_command(data, numwords, "\n");
+ zeus_quad_size = 10;
+ break;
+
+ /* 0x38: direct render quad (crusnexo) */
+ // 0x38: ?? (atlantis)
+ case 0x38:
+ if (numwords < 12)
+ return FALSE;
+ if (log_fifo)
+ log_fifo_command(data, numwords, "\n");
+ break;
+
+ /* 0x40: ???? */
+ case 0x40:
+ if (log_fifo)
+ log_fifo_command(data, numwords, "\n");
+ break;
+
+ default:
+ if (data[0] != 0x2c0)
+ {
+ printf("Unknown command %08X\n", data[0]);
+ if (log_fifo)
+ log_fifo_command(data, numwords, "\n");
+ }
+ break;
+ }
+ return TRUE;
+}
+
+/*************************************
+ * Draw a model in waveram
+ *************************************/
+
+void zeus2_device::zeus2_draw_model(UINT32 baseaddr, UINT16 count, int logit)
+{
+ UINT32 databuffer[32];
+ int databufcount = 0;
+ int model_done = FALSE;
+ UINT32 texoffs = 0;
+ int quadsize = zeus_quad_size;
+
+ if (logit)
+ logerror(" -- model @ %08X, len %04X\n", baseaddr, count);
+
+ if (count > 0x1000)
+ fatalerror("Extreme count\n");
+
+ while (baseaddr != 0 && !model_done)
+ {
+ const void *base = waveram0_ptr_from_expanded_addr(baseaddr);
+ int curoffs;
+
+ /* reset the objdata address */
+ baseaddr = 0;
+
+ /* loop until we run out of data */
+ for (curoffs = 0; curoffs <= count; curoffs++)
+ {
+ int countneeded = 2;
+ UINT8 cmd;
+
+ /* accumulate 2 words of data */
+ databuffer[databufcount++] = WAVERAM_READ32(base, curoffs * 2 + 0);
+ databuffer[databufcount++] = WAVERAM_READ32(base, curoffs * 2 + 1);
+
+ /* if this is enough, process the command */
+ cmd = databuffer[0] >> 24;
+ if (cmd == 0x38)
+ countneeded = quadsize;
+ if (databufcount == countneeded)
+ {
+ /* handle logging of the command */
+ if (logit)
+ {
+ int offs;
+ logerror("\t");
+ for (offs = 0; offs < databufcount; offs++)
+ logerror("%08X ", databuffer[offs]);
+ logerror("-- ");
+ }
+
+ /* handle the command */
+ switch (cmd)
+ {
+ case 0x21: /* thegrid */
+ case 0x22: /* crusnexo */
+ if (((databuffer[0] >> 16) & 0xff) == 0x9b)
+ {
+ texoffs = databuffer[1];
+ if (logit)
+ logerror("texture offset\n");
+ }
+ else if (logit)
+ logerror("unknown offset\n");
+ break;
+
+ case 0x31: /* thegrid */
+ if (logit)
+ logerror("sync?\n");
+ break;
+
+ case 0x35: /* thegrid */
+ case 0x36: /* crusnexo */
+ if (logit)
+ logerror("reg32");
+ zeus2_register32_w((databuffer[0] >> 16) & 0x7f, databuffer[1], logit);
+ break;
+
+ case 0x38: /* crusnexo/thegrid */
+ poly->zeus2_draw_quad(databuffer, texoffs, logit);
+ break;
+
+ default:
+ if (quadsize == 10)
+ {
+ logerror("Correcting quad size\n");
+ quadsize = 14;
+ }
+ if (logit)
+ logerror("unknown model data\n");
+ break;
+ }
+
+ /* reset the count */
+ databufcount = 0;
+ }
+ }
+ }
+}
+
+/*************************************
+ * Draw a quad
+ *************************************/
+void zeus2_renderer::zeus2_draw_quad(const UINT32 *databuffer, UINT32 texoffs, int logit)
+{
+ z2_poly_vertex clipvert[8];
+ z2_poly_vertex vert[4];
+ // float uscale, vscale;
+ float maxy, maxx;
+ // int val1, val2, texwshift;
+ int numverts;
+ int i;
+ // INT16 normal[3];
+ // INT32 rotnormal[3];
+ int texmode = texoffs & 0xffff;
+
+ if (logit)
+ m_state->logerror("quad\n");
+
+ if (machine().input().code_pressed(KEYCODE_Q) && (texoffs & 0xffff) == 0x119) return;
+ if (machine().input().code_pressed(KEYCODE_E) && (texoffs & 0xffff) == 0x01d) return;
+ if (machine().input().code_pressed(KEYCODE_R) && (texoffs & 0xffff) == 0x11d) return;
+ if (machine().input().code_pressed(KEYCODE_T) && (texoffs & 0xffff) == 0x05d) return;
+ if (machine().input().code_pressed(KEYCODE_Y) && (texoffs & 0xffff) == 0x0dd) return;
+ //if (machine().input().code_pressed(KEYCODE_U) && (texoffs & 0xffff) == 0x119) return;
+ //if (machine().input().code_pressed(KEYCODE_I) && (texoffs & 0xffff) == 0x119) return;
+ //if (machine().input().code_pressed(KEYCODE_O) && (texoffs & 0xffff) == 0x119) return;
+ //if (machine().input().code_pressed(KEYCODE_L) && (texoffs & 0x100)) return;
+
+ /*
+ 0 38800000
+ 1 x2 | x1
+ 2 v1 | u1
+ 3 y2 | y1
+ 4 v2 | u2
+ 5 z2 | z1
+ 6 v3 | u3
+ 7 v4 | u4
+ 8 ???
+ 9 x4 | x3
+ 10 y4 | y3
+ 11 z4 | z3
+
+ In memory:
+ +0 = ???
+ +1 = set via $05410000/value
+ +2 = x1
+ +3 = y1
+ +4 = z1
+ +5 = x2
+ +6 = y2
+ +7 = z2
+ +8 = x3
+ +9 = y3
+ +10= z3
+ +11= x4
+ +12= y4
+ +13= z4
+ +14= uv1
+ +15= uv2
+ +16= uv3
+ +17= uv4
+ +18= set via $05200000/$05000000 | (value << 10) (uvoffset?)
+ +19= ???
+
+
+ 38810000 00000000 00C7|FF38 FF5E|FF5E 15400154 11400114 00000000 00000000 FF38|00C7 00A3|00A3 -- quad
+ xxxx|xxxx yyyy|yyyy xxxx|xxxx yyyy|yyyy
+ */
+
+ /* extract raw x,y,z */
+ vert[0].x = (INT16)databuffer[2];
+ vert[0].y = (INT16)databuffer[3];
+ vert[0].p[0] = (INT16)databuffer[6];
+ vert[0].p[1] = (databuffer[1] >> 2) & 0xff;
+ vert[0].p[2] = (databuffer[1] >> 18) & 0xff;
+
+ vert[1].x = (INT16)(databuffer[2] >> 16);
+ vert[1].y = (INT16)(databuffer[3] >> 16);
+ vert[1].p[0] = (INT16)(databuffer[6] >> 16);
+ vert[1].p[1] = (databuffer[4] >> 2) & 0xff;
+ vert[1].p[2] = (databuffer[4] >> 12) & 0xff;
+
+ vert[2].x = (INT16)databuffer[8];
+ vert[2].y = (INT16)databuffer[9];
+ vert[2].p[0] = (INT16)databuffer[7];
+ vert[2].p[1] = (databuffer[4] >> 22) & 0xff;
+ vert[2].p[2] = (databuffer[5] >> 2) & 0xff;
+
+ vert[3].x = (INT16)(databuffer[8] >> 16);
+ vert[3].y = (INT16)(databuffer[9] >> 16);
+ vert[3].p[0] = (INT16)(databuffer[7] >> 16);
+ vert[3].p[1] = (databuffer[5] >> 12) & 0xff;
+ vert[3].p[2] = (databuffer[5] >> 22) & 0xff;
+
+ /*
+ vert[0].x = (INT16)databuffer[1];
+ vert[0].y = (INT16)databuffer[3];
+ vert[0].p[0] = (INT16)databuffer[5];
+ vert[0].p[1] = (UINT16)databuffer[2];
+ vert[0].p[2] = (UINT16)(databuffer[2] >> 16);
+
+ vert[1].x = (INT16)(databuffer[1] >> 16);
+ vert[1].y = (INT16)(databuffer[3] >> 16);
+ vert[1].p[0] = (INT16)(databuffer[5] >> 16);
+ vert[1].p[1] = (UINT16)databuffer[4];
+ vert[1].p[2] = (UINT16)(databuffer[4] >> 16);
+
+ vert[2].x = (INT16)databuffer[9];
+ vert[2].y = (INT16)databuffer[10];
+ vert[2].p[0] = (INT16)databuffer[11];
+ vert[2].p[1] = (UINT16)databuffer[6];
+ vert[2].p[2] = (UINT16)(databuffer[6] >> 16);
+
+ vert[3].x = (INT16)(databuffer[9] >> 16);
+ vert[3].y = (INT16)(databuffer[10] >> 16);
+ vert[3].p[0] = (INT16)(databuffer[11] >> 16);
+ vert[3].p[1] = (UINT16)databuffer[7];
+ vert[3].p[2] = (UINT16)(databuffer[7] >> 16);
+ */
+ for (i = 0; i < 4; i++)
+ {
+ float x = vert[i].x;
+ float y = vert[i].y;
+ float z = vert[i].p[0];
+
+ vert[i].x = x * m_state->zeus_matrix[0][0] + y * m_state->zeus_matrix[0][1] + z * m_state->zeus_matrix[0][2] + m_state->zeus_point[0];
+ vert[i].y = x * m_state->zeus_matrix[1][0] + y * m_state->zeus_matrix[1][1] + z * m_state->zeus_matrix[1][2] + m_state->zeus_point[1];
+ vert[i].p[0] = x * m_state->zeus_matrix[2][0] + y * m_state->zeus_matrix[2][1] + z * m_state->zeus_matrix[2][2] + m_state->zeus_point[2];
+ vert[i].p[0] += m_state->zbase;
+ vert[i].p[2] += texoffs >> 16;
+ vert[i].p[1] *= 256.0f;
+ vert[i].p[2] *= 256.0f;
+
+ if (logit)
+ {
+ m_state->logerror("\t\t(%f,%f,%f) (%02X,%02X)\n",
+ (double)vert[i].x, (double)vert[i].y, (double)vert[i].p[0],
+ (int)(vert[i].p[1] / 256.0f), (int)(vert[i].p[2] / 256.0f));
+ }
+ }
+
+ numverts = this->zclip_if_less(4, &vert[0], &clipvert[0], 4, 1.0f / 512.0f / 4.0f);
+ if (numverts < 3)
+ return;
+
+ maxx = maxy = -1000.0f;
+ for (i = 0; i < numverts; i++)
+ {
+ // 412.0f here works for crusnexo
+ float ooz = 512.0f / clipvert[i].p[0];
+
+ // ooz *= 1.0f / (512.0f * 512.0f);
+
+ clipvert[i].x *= ooz;
+ clipvert[i].y *= ooz;
+ clipvert[i].x += 256.5f;
+ clipvert[i].y += 200.5f;
+ clipvert[i].p[0] *= 65536.0f * 16.0f;
+
+ maxx = MAX(maxx, clipvert[i].x);
+ maxy = MAX(maxy, clipvert[i].y);
+ if (logit)
+ m_state->logerror("\t\t\tTranslated=(%f,%f)\n", (double)clipvert[i].x, (double)clipvert[i].y);
+ }
+ for (i = 0; i < numverts; i++)
+ {
+ if (clipvert[i].x == maxx)
+ clipvert[i].x += 0.0005f;
+ if (clipvert[i].y == maxy)
+ clipvert[i].y += 0.0005f;
+ }
+
+ zeus2_poly_extra_data& extra = this->object_data_alloc();
+ switch (texmode)
+ {
+ case 0x01d: /* crusnexo: RHS of score bar */
+ case 0x05d: /* crusnexo: background, road */
+ case 0x0dd: /* crusnexo: license plate letters */
+ case 0x11d: /* crusnexo: LHS of score bar */
+ case 0x15d: /* crusnexo */
+ case 0x85d: /* crusnexo */
+ case 0x95d: /* crusnexo */
+ case 0xc1d: /* crusnexo */
+ case 0xc5d: /* crusnexo */
+ extra.texwidth = 256;
+ break;
+
+ case 0x059: /* crusnexo */
+ case 0x0d9: /* crusnexo */
+ case 0x119: /* crusnexo: license plates */
+ case 0x159: /* crusnexo */
+ extra.texwidth = 128;
+ break;
+
+ case 0x055: /* crusnexo */
+ case 0x155: /* crusnexo */
+ extra.texwidth = 64;
+ break;
+
+ case 0x000: // thegrid guess
+ case 0x120: // thegrid guess
+ extra.texwidth = 32;
+ break;
+
+ default:
+ {
+ static UINT8 hits[0x10000];
+ if (!hits[(texoffs & 0xffff)])
+ {
+ hits[(texoffs & 0xffff)] = 1;
+ printf("format = %04X\n", (texoffs & 0xffff));
+ }
+ break;
+ }
+ }
+
+ extra.solidcolor = 0;//m_zeusbase[0x00] & 0x7fff;
+ extra.zoffset = 0;//m_zeusbase[0x7e] >> 16;
+ extra.alpha = 0;//m_zeusbase[0x4e];
+ extra.transcolor = 0x100;//((databuffer[1] >> 16) & 1) ? 0 : 0x100;
+ extra.texbase = WAVERAM_BLOCK0_EXT(m_state->zeus_texbase);
+ extra.palbase = m_state->waveram0_ptr_from_expanded_addr(m_state->m_zeusbase[0x41]);
+
+ // Note: Before being converted to the "poly.h" interface, this used to call the polylgcy function
+ // poly_render_quad_fan. The behavior seems to be the same as it once was after a few short
+ // tests, but the (numverts == 5) statement below may actually be a quad fan instead of a 5-sided
+ // polygon.
+ if (numverts == 3)
+ render_triangle(m_state->zeus_cliprect, render_delegate(FUNC(zeus2_renderer::render_poly_8bit), this), 4, clipvert[0], clipvert[1], clipvert[2]);
+ else if (numverts == 4)
+ render_polygon<4>(m_state->zeus_cliprect, render_delegate(FUNC(zeus2_renderer::render_poly_8bit), this), 4, clipvert);
+ else if (numverts == 5)
+ render_polygon<5>(m_state->zeus_cliprect, render_delegate(FUNC(zeus2_renderer::render_poly_8bit), this), 4, clipvert);
+}
+
+
+
+/*************************************
+* Rasterizers
+*************************************/
+
+void zeus2_renderer::render_poly_8bit(INT32 scanline, const extent_t& extent, const zeus2_poly_extra_data& object, int threadid)
+{
+ INT32 curz = extent.param[0].start;
+ INT32 curu = extent.param[1].start;
+ INT32 curv = extent.param[2].start;
+ // INT32 curi = extent.param[3].start;
+ INT32 dzdx = extent.param[0].dpdx;
+ INT32 dudx = extent.param[1].dpdx;
+ INT32 dvdx = extent.param[2].dpdx;
+ // INT32 didx = extent.param[3].dpdx;
+ const void *texbase = object.texbase;
+ const void *palbase = object.palbase;
+ UINT16 transcolor = object.transcolor;
+ int texwidth = object.texwidth;
+ int x;
+
+ for (x = extent.startx; x < extent.stopx; x++)
+ {
+ UINT16 *depthptr = WAVERAM_PTRDEPTH(m_state->zeus_renderbase, scanline, x);
+ INT32 depth = (curz >> 16) + object.zoffset;
+ //if (depth > 0x7fff) depth = 0x7fff;
+ if (depth > 0xffff) depth = 0xffff;
+ if (depth >= 0 && depth <= *depthptr)
+ {
+ int u0 = (curu >> 8);// & (texwidth - 1);
+ int v0 = (curv >> 8);// & 255;
+ int u1 = (u0 + 1);
+ int v1 = (v0 + 1);
+ UINT8 texel0 = m_state->get_texel_8bit(texbase, v0, u0, texwidth);
+ UINT8 texel1 = m_state->get_texel_8bit(texbase, v0, u1, texwidth);
+ UINT8 texel2 = m_state->get_texel_8bit(texbase, v1, u0, texwidth);
+ UINT8 texel3 = m_state->get_texel_8bit(texbase, v1, u1, texwidth);
+ if (texel0 != transcolor)
+ {
+ UINT32 color0 = WAVERAM_READ16(palbase, texel0);
+ UINT32 color1 = WAVERAM_READ16(palbase, texel1);
+ UINT32 color2 = WAVERAM_READ16(palbase, texel2);
+ UINT32 color3 = WAVERAM_READ16(palbase, texel3);
+ color0 = ((color0 & 0x7c00) << 9) | ((color0 & 0x3e0) << 6) | ((color0 & 0x1f) << 3);
+ color1 = ((color1 & 0x7c00) << 9) | ((color1 & 0x3e0) << 6) | ((color1 & 0x1f) << 3);
+ color2 = ((color2 & 0x7c00) << 9) | ((color2 & 0x3e0) << 6) | ((color2 & 0x1f) << 3);
+ color3 = ((color3 & 0x7c00) << 9) | ((color3 & 0x3e0) << 6) | ((color3 & 0x1f) << 3);
+ rgb_t filtered = rgbaint_t::bilinear_filter(color0, color1, color2, color3, curu, curv);
+ WAVERAM_WRITEPIX(m_state->zeus_renderbase, scanline, x, filtered);
+ *depthptr = depth;
+ }
+ }
+
+ curz += dzdx;
+ curu += dudx;
+ curv += dvdx;
+ // curi += didx;
+ }
+}
+
+/*************************************
+ * Debugging tools
+ *************************************/
+
+void zeus2_device::log_fifo_command(const UINT32 *data, int numwords, const char *suffix)
+{
+ int wordnum;
+ std::string errorStr;
+ logerror("Zeus cmd %02X :", data[0] >> 24);
+ for (wordnum = 0; wordnum < numwords; wordnum++)
+ logerror(" %08X", data[wordnum]);
+ logerror("%s", suffix);
+}
diff --git a/src/devices/video/zeus2.h b/src/devices/video/zeus2.h
new file mode 100644
index 00000000000..cc147654e71
--- /dev/null
+++ b/src/devices/video/zeus2.h
@@ -0,0 +1,286 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles
+/*************************************************************************
+
+ Midway Zeus2 Video
+
+**************************************************************************/
+#ifndef __ZEUS2_H__
+#define __ZEUS2_H__
+
+#include "emu.h"
+#include "video/poly.h"
+#include "video/rgbutil.h"
+#include "cpu/tms32031/tms32031.h"
+
+#pragma once
+
+/*************************************
+* Constants
+*************************************/
+#define ZEUS2_VIDEO_CLOCK XTAL_66_6667MHz
+
+#define DUMP_WAVE_RAM 0
+#define TRACK_REG_USAGE 0
+
+#define WAVERAM0_WIDTH 1024
+#define WAVERAM0_HEIGHT 2048
+
+#define WAVERAM1_WIDTH 512
+#define WAVERAM1_HEIGHT 1024
+
+/*************************************
+* Type definitions
+*************************************/
+
+struct zeus2_poly_extra_data
+{
+ const void * palbase;
+ const void * texbase;
+ UINT16 solidcolor;
+ INT16 zoffset;
+ UINT16 transcolor;
+ UINT16 texwidth;
+ UINT16 color;
+ UINT32 alpha;
+};
+
+/*************************************
+* Macros
+*************************************/
+
+#define WAVERAM_BLOCK0(blocknum) ((void *)((UINT8 *)waveram[0] + 8 * (blocknum)))
+#define WAVERAM_BLOCK1(blocknum) ((void *)((UINT8 *)waveram[1] + 12 * (blocknum)))
+#define WAVERAM_BLOCK0_EXT(blocknum) ((void *)((UINT8 *)m_state->waveram[0] + 8 * (blocknum)))
+#define WAVERAM_BLOCK1_EXT(blocknum) ((void *)((UINT8 *)m_state->waveram[1] + 12 * (blocknum)))
+
+#define WAVERAM_PTR8(base, bytenum) ((UINT8 *)(base) + BYTE4_XOR_LE(bytenum))
+#define WAVERAM_READ8(base, bytenum) (*WAVERAM_PTR8(base, bytenum))
+#define WAVERAM_WRITE8(base, bytenum, data) do { *WAVERAM_PTR8(base, bytenum) = (data); } while (0)
+
+#define WAVERAM_PTR16(base, wordnum) ((UINT16 *)(base) + BYTE_XOR_LE(wordnum))
+#define WAVERAM_READ16(base, wordnum) (*WAVERAM_PTR16(base, wordnum))
+#define WAVERAM_WRITE16(base, wordnum, data) do { *WAVERAM_PTR16(base, wordnum) = (data); } while (0)
+
+#define WAVERAM_PTR32(base, dwordnum) ((UINT32 *)(base) + (dwordnum))
+#define WAVERAM_READ32(base, dwordnum) (*WAVERAM_PTR32(base, dwordnum))
+#define WAVERAM_WRITE32(base, dwordnum, data) do { *WAVERAM_PTR32(base, dwordnum) = (data); } while (0)
+
+#define PIXYX_TO_DWORDNUM(y, x) (((((y) & 0x1ff) << 8) | (((x) & 0x1fe) >> 1)) * 3 + ((x) & 1))
+#define DEPTHYX_TO_DWORDNUM(y, x) (PIXYX_TO_DWORDNUM(y, (x) & ~1) + 2)
+
+#define WAVERAM_PTRPIX(base, y, x) WAVERAM_PTR32(base, PIXYX_TO_DWORDNUM(y, x))
+#define WAVERAM_READPIX(base, y, x) (*WAVERAM_PTRPIX(base, y, x))
+#define WAVERAM_WRITEPIX(base, y, x, color) do { *WAVERAM_PTRPIX(base, y, x) = (color); } while (0)
+
+#define WAVERAM_PTRDEPTH(base, y, x) WAVERAM_PTR16(base, DEPTHYX_TO_DWORDNUM(y, x) * 2 + (x & 1))
+#define WAVERAM_READDEPTH(base, y, x) (*WAVERAM_PTRDEPTH(base, y, x))
+#define WAVERAM_WRITEDEPTH(base, y, x, color) do { *WAVERAM_PTRDEPTH(base, y, x) = (color); } while (0)
+
+/*************************************
+* Polygon renderer
+*************************************/
+class zeus2_device;
+
+class zeus2_renderer : public poly_manager<float, zeus2_poly_extra_data, 4, 10000>
+{
+public:
+ zeus2_renderer(zeus2_device *state);
+
+ void render_poly_8bit(INT32 scanline, const extent_t& extent, const zeus2_poly_extra_data& object, int threadid);
+
+ void zeus2_draw_quad(const UINT32 *databuffer, UINT32 texoffs, int logit);
+
+private:
+ zeus2_device* m_state;
+};
+typedef zeus2_renderer::vertex_t z2_poly_vertex;
+typedef zeus2_renderer::extent_t z2_poly_extent;
+
+/*************************************
+* Zeus2 Video Device
+*************************************/
+#define MCFG_ZEUS2_VBLANK_CB(_devcb) \
+ devcb = &zeus2_device::set_vblank_callback(*device, DEVCB_##_devcb);
+
+#define MCFG_ZEUS2_IRQ_CB(_devcb) \
+ devcb = &zeus2_device::set_irq_callback(*device, DEVCB_##_devcb);
+
+class zeus2_device : public device_t
+{
+public:
+ zeus2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ screen_device *m_screen; /* the screen we are acting on */
+
+ UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+ DECLARE_READ32_MEMBER( zeus2_r );
+ DECLARE_WRITE32_MEMBER( zeus2_w );
+ TIMER_CALLBACK_MEMBER(display_irq_off);
+ TIMER_CALLBACK_MEMBER(display_irq);
+
+ template<class _Object> static devcb_base &set_vblank_callback(device_t &device, _Object object) { return downcast<zeus2_device &>(device).m_vblank.set_callback(object); }
+ template<class _Object> static devcb_base &set_irq_callback(device_t &device, _Object object) { return downcast<zeus2_device &>(device).m_irq.set_callback(object); }
+ devcb_write_line m_vblank;
+ devcb_write_line m_irq;
+
+ UINT32 m_zeusbase[0x80];
+
+ zeus2_renderer* poly;
+
+ void *zeus_renderbase;
+ rectangle zeus_cliprect;
+
+ float zeus_matrix[3][3];
+ float zeus_point[3];
+ float zeus_point2[3];
+ UINT32 zeus_texbase;
+ UINT32 zeus_unknown_40;
+ int zeus_quad_size;
+
+ UINT32 *waveram[2];
+ emu_timer *int_timer;
+ emu_timer *vblank_timer;
+ int m_yScale;
+ int yoffs;
+ int texel_width;
+ float zbase;
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_stop() override;
+
+private:
+ TIMER_CALLBACK_MEMBER(int_timer_callback);
+ void zeus2_register32_w(offs_t offset, UINT32 data, int logit);
+ void zeus2_register_update(offs_t offset, UINT32 oldval, int logit);
+ int zeus2_fifo_process(const UINT32 *data, int numwords);
+ void zeus2_pointer_write(UINT8 which, UINT32 value);
+ void zeus2_draw_model(UINT32 baseaddr, UINT16 count, int logit);
+ void log_fifo_command(const UINT32 *data, int numwords, const char *suffix);
+
+ /*************************************
+ * Member variables
+ *************************************/
+
+
+ UINT8 log_fifo;
+
+ UINT32 zeus_fifo[20];
+ UINT8 zeus_fifo_words;
+
+ UINT32 m_fill_color;
+ UINT16 m_fill_depth;
+
+#if TRACK_REG_USAGE
+ struct reg_info
+ {
+ struct reg_info *next;
+ UINT32 value;
+ };
+
+ reg_info *regdata[0x80];
+ int regdata_count[0x80];
+ int regread_count[0x80];
+ int regwrite_count[0x80];
+ reg_info *subregdata[0x100];
+ int subregdata_count[0x80];
+ int subregwrite_count[0x100];
+#endif
+public:
+ /*************************************
+ * Inlines for block addressing
+ *************************************/
+
+ inline void *waveram0_ptr_from_expanded_addr(UINT32 addr)
+ {
+ UINT32 blocknum = (addr % WAVERAM0_WIDTH) + ((addr >> 16) % WAVERAM0_HEIGHT) * WAVERAM0_WIDTH;
+ return WAVERAM_BLOCK0(blocknum);
+ }
+
+ inline void *waveram1_ptr_from_expanded_addr(UINT32 addr)
+ {
+ UINT32 blocknum = (addr % WAVERAM1_WIDTH) + ((addr >> 16) % WAVERAM1_HEIGHT) * WAVERAM1_WIDTH;
+ return WAVERAM_BLOCK1(blocknum);
+ }
+
+#ifdef UNUSED_FUNCTION
+ inline void *waveram0_ptr_from_texture_addr(UINT32 addr, int width)
+ {
+ UINT32 blocknum = ((addr & ~1) * width) / 8;
+ return WAVERAM_BLOCK0(blocknum);
+ }
+#endif
+
+ /*************************************
+ * Inlines for rendering
+ *************************************/
+
+#ifdef UNUSED_FUNCTION
+ inline void WAVERAM_plot(int y, int x, UINT32 color)
+ {
+ if (zeus_cliprect.contains(x, y))
+ WAVERAM_WRITEPIX(zeus_renderbase, y, x, color);
+ }
+#endif
+
+ inline void waveram_plot_depth(int y, int x, UINT32 color, UINT16 depth)
+ {
+ if (zeus_cliprect.contains(x, y))
+ {
+ WAVERAM_WRITEPIX(zeus_renderbase, y, x, color);
+ WAVERAM_WRITEDEPTH(zeus_renderbase, y, x, depth);
+ }
+ }
+
+#ifdef UNUSED_FUNCTION
+ inline void waveram_plot_check_depth(int y, int x, UINT32 color, UINT16 depth)
+ {
+ if (zeus_cliprect.contains(x, y))
+ {
+ UINT16 *depthptr = WAVERAM_PTRDEPTH(zeus_renderbase, y, x);
+ if (depth <= *depthptr)
+ {
+ WAVERAM_WRITEPIX(zeus_renderbase, y, x, color);
+ *depthptr = depth;
+ }
+ }
+ }
+#endif
+
+#ifdef UNUSED_FUNCTION
+ inline void waveram_plot_check_depth_nowrite(int y, int x, UINT32 color, UINT16 depth)
+ {
+ if (zeus_cliprect.contains(x, y))
+ {
+ UINT16 *depthptr = WAVERAM_PTRDEPTH(zeus_renderbase, y, x);
+ if (depth <= *depthptr)
+ WAVERAM_WRITEPIX(zeus_renderbase, y, x, color);
+ }
+ }
+#endif
+ /*************************************
+ * Inlines for texel accesses
+ *************************************/
+ inline UINT8 get_texel_8bit(const void *base, int y, int x, int width)
+ {
+ UINT32 byteoffs = (y / 2) * (width * 2) + ((x / 4) << 3) + ((y & 1) << 2) + (x & 3);
+ return WAVERAM_READ8(base, byteoffs);
+ }
+
+#ifdef UNUSED_FUNCTION
+ inline UINT8 get_texel_4bit(const void *base, int y, int x, int width)
+ {
+ UINT32 byteoffs = (y / 2) * (width * 2) + ((x / 8) << 3) + ((y & 1) << 2) + ((x / 2) & 3);
+ return (WAVERAM_READ8(base, byteoffs) >> (4 * (x & 1))) & 0x0f;
+ }
+#endif
+
+};
+
+// device type definition
+extern const device_type ZEUS2;
+
+#endif
diff --git a/src/mame/audio/dcs.cpp b/src/mame/audio/dcs.cpp
index 75972ebf0cf..009722f77bb 100644
--- a/src/mame/audio/dcs.cpp
+++ b/src/mame/audio/dcs.cpp
@@ -557,6 +557,7 @@ MACHINE_CONFIG_FRAGMENT( dcs2_audio_denver )
MCFG_CPU_ADD("denver", ADSP2181, XTAL_33_333MHz)
MCFG_ADSP21XX_SPORT_TX_CB(WRITE32(dcs_audio_device, sound_tx_callback)) /* callback for serial transmit */
MCFG_ADSP21XX_TIMER_FIRED_CB(WRITELINE(dcs_audio_device,timer_enable_callback)) /* callback for timer fired */
+ MCFG_ADSP21XX_DMOVLAY_CB(WRITE32(dcs_audio_device, dmovlay_callback)) // callback for adsp 2181 dmovlay instruction
MCFG_CPU_PROGRAM_MAP(denver_program_map)
MCFG_CPU_DATA_MAP(denver_data_map)
MCFG_CPU_IO_MAP(denver_io_map)
@@ -688,6 +689,8 @@ TIMER_CALLBACK_MEMBER( dcs_audio_device::dcs_reset )
/* rev 4: reset the Denver ASIC */
case 4:
+ m_dmovlay_val = 0;
+ dmovlay_remap_memory();
denver_reset();
break;
}
@@ -752,6 +755,7 @@ void dcs_audio_device::dcs_register_state()
save_item(NAME(m_control_regs));
save_item(NAME(m_sounddata_bank));
+ save_item(NAME(m_dmovlay_val));
save_item(NAME(m_auto_ack));
save_item(NAME(m_latch_control));
@@ -786,6 +790,9 @@ void dcs_audio_device::dcs_register_state()
if (m_rev == 2)
machine().save().register_postload(save_prepost_delegate(FUNC(dcs_audio_device::sdrc_remap_memory), this));
+
+ if (m_rev == 4)
+ machine().save().register_postload(save_prepost_delegate(FUNC(dcs_audio_device::dmovlay_remap_memory), this));
}
@@ -958,8 +965,12 @@ void dcs2_audio_device::device_start()
/* supports both RAM and ROM variants */
if (m_dram_in_mb != 0)
{
- m_sounddata = auto_alloc_array(machine(), UINT16, m_dram_in_mb << (20-1));
- save_pointer(NAME(m_sounddata), m_dram_in_mb << (20-1));
+ UINT32 ramSize = m_dram_in_mb << (20 - 1);
+ // Add one extra bank for internal ram in ADSP 2181
+ if (m_rev == 4)
+ ramSize += soundbank_words;
+ m_sounddata = auto_alloc_array(machine(), UINT16, ramSize);
+ save_pointer(NAME(m_sounddata), ramSize);
m_sounddata_words = (m_dram_in_mb << 20) / 2;
}
else
@@ -973,6 +984,7 @@ void dcs2_audio_device::device_start()
m_data_bank->configure_entries(0, m_sounddata_banks, m_sounddata, soundbank_words*2);
}
+
/* allocate memory for the SRAM */
m_sram = auto_alloc_array(machine(), UINT16, 0x8000*4/2);
@@ -1330,7 +1342,7 @@ WRITE16_MEMBER( dcs_audio_device::dsio_w )
/* offset 2 controls RAM pages */
case 2:
dsio.reg[2] = data;
- m_data_bank->set_entry(DSIO_DM_PG % m_sounddata_banks);
+ dmovlay_remap_memory();
break;
}
}
@@ -1388,7 +1400,7 @@ WRITE16_MEMBER( dcs_audio_device::denver_w )
m_dmadac[chan] = subdevice<dmadac_sound_device>(buffer);
}
dmadac_enable(&m_dmadac[0], m_channels, enable);
- if (m_channels < 6)
+ if (m_channels <= 6)
dmadac_enable(&m_dmadac[m_channels], 6 - m_channels, FALSE);
recompute_sample_rate();
}
@@ -1399,7 +1411,6 @@ WRITE16_MEMBER( dcs_audio_device::denver_w )
dsio.reg[2] = data;
m_data_bank->set_entry(DENV_DM_PG % m_sounddata_banks);
break;
-
/* offset 3 controls FIFO reset */
case 3:
if (!m_fifo_reset_w.isnull())
@@ -1460,6 +1471,32 @@ READ32_MEMBER( dcs_audio_device::dsio_idma_data_r )
return result;
}
+void dcs_audio_device::dmovlay_remap_memory()
+{
+ // Switch banks
+ // Internal ram is bank 0
+ int bankSel;
+ if (m_dmovlay_val == 0) {
+ bankSel = 0;
+ m_data_bank->set_entry(bankSel);
+ } else {
+ bankSel = 1 + (DSIO_DM_PG % m_sounddata_banks);
+ m_data_bank->set_entry(bankSel);
+ }
+ if (LOG_DCS_IO)
+ logerror("%s dmovlay_remap_memory: Switching data ram location bankSel = %i\n", machine().describe_context(), bankSel);
+}
+
+WRITE32_MEMBER(dcs_audio_device::dmovlay_callback)
+{
+ // Do some checking first
+ if (data < 0 || data > 1) {
+ logerror("dmovlay_callback: Error! dmovlay called with value = %X\n", data);
+ } else {
+ m_dmovlay_val = data;
+ dmovlay_remap_memory();
+ }
+}
/***************************************************************************
@@ -1872,10 +1909,10 @@ WRITE16_MEMBER(dcs_audio_device:: adsp_control_w )
switch (offset)
{
case SYSCONTROL_REG:
- /* bit 9 forces a reset */
- if (data & 0x0200)
+ /* bit 9 forces a reset (not on 2181) */
+ if ((data & 0x0200) && !(m_rev == 3 || m_rev == 4))
{
- logerror("%04X:Rebooting DCS due to SYSCONTROL write\n", space.device().safe_pc());
+ logerror("%04X:Rebooting DCS due to SYSCONTROL write = %04X\n", space.device().safe_pc(), data);
m_cpu->set_input_line(INPUT_LINE_RESET, PULSE_LINE);
dcs_boot();
m_control_regs[SYSCONTROL_REG] = 0;
@@ -1950,9 +1987,7 @@ TIMER_DEVICE_CALLBACK_MEMBER( dcs_audio_device::dcs_irq )
{
int count = m_size / (2*(m_incs ? m_incs : 1));
// sf2049se was having overflow issues with fixed size of 0x400 buffer (m_size==0xb40, count=0x5a0).
- //INT16 buffer[0x400];
- std::unique_ptr<INT16[]> buffer;
- buffer = std::make_unique<INT16[]>(count);
+ INT16 buffer[0x800];
int i;
for (i = 0; i < count; i++)
@@ -1962,7 +1997,7 @@ TIMER_DEVICE_CALLBACK_MEMBER( dcs_audio_device::dcs_irq )
}
if (m_channels)
- dmadac_transfer(&m_dmadac[0], m_channels, 1, m_channels, count / m_channels, buffer.get());
+ dmadac_transfer(&m_dmadac[0], m_channels, 1, m_channels, count / m_channels, buffer);
}
/* check for wrapping */
diff --git a/src/mame/audio/dcs.h b/src/mame/audio/dcs.h
index 3d30e946604..5b84b994126 100644
--- a/src/mame/audio/dcs.h
+++ b/src/mame/audio/dcs.h
@@ -47,6 +47,8 @@ public:
DECLARE_WRITE32_MEMBER( dsio_idma_addr_w );
DECLARE_WRITE32_MEMBER( dsio_idma_data_w );
DECLARE_READ32_MEMBER( dsio_idma_data_r );
+ void dmovlay_remap_memory();
+ WRITE32_MEMBER(dmovlay_callback);
// non public
void dcs_boot();
@@ -202,6 +204,8 @@ protected:
UINT32 *m_internal_program_ram;
UINT32 *m_external_program_ram;
+ int m_dmovlay_val;
+
sdrc_state m_sdrc;
dsio_state m_dsio;
hle_transfer_state m_transfer;
diff --git a/src/mame/drivers/atlantis.cpp b/src/mame/drivers/atlantis.cpp
index 65102eee960..802704b8e43 100644
--- a/src/mame/drivers/atlantis.cpp
+++ b/src/mame/drivers/atlantis.cpp
@@ -43,8 +43,7 @@
#include "machine/vrc4373.h"
#include "machine/pci9050.h"
#include "machine/pci-ide.h"
-#include "includes/midzeus.h"
-#include "includes/midzeus2.h"
+#include "video/zeus2.h"
#include "machine/nvram.h"
#include "coreutil.h"
@@ -62,19 +61,22 @@
// These need more verification
#define IOASIC_IRQ_SHIFT 0
+#define GALILEO_IRQ_SHIFT 1
+#define ZEUS_IRQ_SHIFT 2
#define PARALLEL_IRQ_SHIFT 3
#define UART0_SHIFT 4
#define UART1_SHIFT 5
-#define ZEUS_IRQ_SHIFT 2
#define VBLANK_IRQ_SHIFT 7
-#define GALILEO_IRQ_SHIFT 0
/* static interrupts */
#define GALILEO_IRQ_NUM MIPS3_IRQ0
+#define VBLANK_IRQ_NUM MIPS3_IRQ3
#define IDE_IRQ_NUM MIPS3_IRQ4
-#define LOG_RTC (1)
-#define LOG_ZEUS (0)
+#define LOG_RTC (0)
+#define LOG_RED (0)
+#define LOG_PORT (0)
+#define LOG_IRQ (0)
class atlantis_state : public driver_device
{
@@ -83,6 +85,8 @@ public:
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_screen(*this, "screen"),
+ m_palette(*this, "palette"),
+ m_zeus(*this, "zeus2"),
m_dcs(*this, "dcs"),
m_ioasic(*this, "ioasic"),
m_uart0(*this, "uart0"),
@@ -95,14 +99,14 @@ public:
UINT32 screen_update_mwskins(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
required_device<mips3_device> m_maincpu;
required_device<screen_device> m_screen;
- //required_device<dcs2_audio_dsio_device> m_dcs;
- //required_device<dcs2_audio_denver_device> m_dcs;
+ optional_device<palette_device> m_palette;
+ required_device<zeus2_device> m_zeus;
required_device<dcs_audio_device> m_dcs;
required_device<midway_ioasic_device> m_ioasic;
required_device<ns16550_device> m_uart0;
required_device<ns16550_device> m_uart1;
required_device<nvram_device> m_rtc;
- UINT8 m_rtc_data[0x800];
+ UINT8 m_rtc_data[0x8000];
UINT32 m_last_offset;
READ8_MEMBER(cmos_r);
@@ -110,6 +114,7 @@ public:
DECLARE_WRITE32_MEMBER(cmos_protect_w);
DECLARE_READ32_MEMBER(cmos_protect_r);
UINT32 m_cmos_write_enabled;
+ UINT32 m_serial_count;
DECLARE_READ32_MEMBER(status_leds_r);
DECLARE_WRITE32_MEMBER(status_leds_w);
@@ -118,15 +123,6 @@ public:
DECLARE_WRITE32_MEMBER(asic_fifo_w);
DECLARE_WRITE32_MEMBER(dcs3_fifo_full_w);
- DECLARE_WRITE32_MEMBER(zeus_w);
- DECLARE_READ32_MEMBER(zeus_r);
- UINT32 m_zeus_data[0x80];
-
- READ8_MEMBER (red_r);
- WRITE8_MEMBER(red_w);
- UINT8 m_red_data[0x1000];
- int m_red_count;
-
READ32_MEMBER (green_r);
WRITE32_MEMBER(green_w);
READ8_MEMBER (blue_r);
@@ -142,6 +138,8 @@ public:
UINT8 board_ctrl[CTRL_SIZE];
void update_asic_irq();
+ DECLARE_WRITE_LINE_MEMBER(vblank_irq);
+ DECLARE_WRITE_LINE_MEMBER(zeus_irq);
DECLARE_WRITE_LINE_MEMBER(ide_irq);
DECLARE_WRITE_LINE_MEMBER(ioasic_irq);
@@ -154,37 +152,6 @@ public:
UINT32 m_port_ctrl_reg[0x8];
};
-READ8_MEMBER (atlantis_state::red_r)
-{
- UINT8 data = m_red_data[offset];
- logerror("%06X: red_r %08x = %02x\n", machine().device("maincpu")->safe_pc(), offset, data);
- m_last_offset = offset | 0x10000;
- return data;
-}
-
-WRITE8_MEMBER(atlantis_state::red_w)
-{
- COMBINE_DATA(&m_red_data[offset]);
-
- switch (offset) {
- case 0:
- // User I/O 0 = Allow write to red[0]. Serial Write Enable?
- if (m_user_io_state & 0x1) {
- // Data written is shifted by 1 bit each time. Maybe a serial line output?
- if (m_red_count == 0)
- logerror("%06X: red_w start serial %08x = %02x\n", machine().device("maincpu")->safe_pc(), offset, data);
- m_red_count++;
- if (m_red_count == 8)
- m_red_count = 0;
- break;
- } // Fall through to default if not enabled
- default:
- logerror("%06X: red_w %08x = %02x\n", machine().device("maincpu")->safe_pc(), offset, data);
- break;
- }
- m_last_offset = offset | 0x10000;
-}
-
READ32_MEMBER(atlantis_state::green_r)
{
// If not 0x80 cpu writes to 00e80000 = 0
@@ -222,10 +189,12 @@ READ32_MEMBER(atlantis_state::board_ctrl_r)
if (1 && m_screen->vblank())
data |= 0x80;
if (m_last_offset != (newOffset | 0x40000))
- logerror("%s:board_ctrl_r read from CTRL_STATUS offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
+ if (LOG_IRQ)
+ logerror("%s:board_ctrl_r read from CTRL_STATUS offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
break;
default:
- logerror("%s:board_ctrl_r read from offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
+ if (LOG_IRQ)
+ logerror("%s:board_ctrl_r read from offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
break;
}
m_last_offset = newOffset | 0x40000;
@@ -251,66 +220,70 @@ WRITE32_MEMBER(atlantis_state::board_ctrl_w)
m_dcs->reset_w(CLEAR_LINE);
}
}
- logerror("%s:board_ctrl_w write to CTRL_POWER0 offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
+ if (LOG_IRQ)
+ logerror("%s:board_ctrl_w write to CTRL_POWER0 offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
break;
case CTRL_POWER1:
- // 0x1 VBlank clear?
+ // 0x1 VBlank clear?
if (changeData & 0x1) {
if ((data & 0x0001) == 0) {
+ //UINT32 status_bit = (1 << VBLANK_IRQ_SHIFT);
+ UINT32 status_bit = (1 << 7);
+ board_ctrl[CTRL_CAUSE] &= ~status_bit;
+ board_ctrl[CTRL_STATUS] &= ~status_bit;
+ update_asic_irq();
}
else {
}
}
- logerror("%s:board_ctrl_w write to CTRL_POWER1 offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
+ if (LOG_IRQ)
+ logerror("%s:board_ctrl_w write to CTRL_POWER1 offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
break;
case CTRL_GLOBAL_EN:
// Zero bit will clear cause
board_ctrl[CTRL_CAUSE] &= data;
update_asic_irq();
- logerror("%s:board_ctrl_w write to CTRL_GLOBAL_EN offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
+ if (LOG_IRQ)
+ logerror("%s:board_ctrl_w write to CTRL_GLOBAL_EN offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
break;
default:
- logerror("%s:board_ctrl_w write to offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
+ if (LOG_IRQ)
+ logerror("%s:board_ctrl_w write to offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
break;
}
}
-WRITE32_MEMBER(atlantis_state::asic_fifo_w)
-{
- m_ioasic->fifo_w(data);
-}
-
READ8_MEMBER(atlantis_state::cmos_r)
{
UINT8 result = m_rtc_data[offset];
switch (offset) {
- case 0x7F9:
- case 0x7FA:
- case 0x7FB:
- case 0x7FC:
- case 0x7FD:
- case 0x7FE:
- case 0x7FF:
- if ((m_rtc_data[0x7F8] & 0x40)==0) {
+ case 0x7FF9:
+ case 0x7FFA:
+ case 0x7FFB:
+ case 0x7FFC:
+ case 0x7FFD:
+ case 0x7FFE:
+ case 0x7FFF:
+ if ((m_rtc_data[0x7FF8] & 0x40)==0) {
system_time systime;
// get the current date/time from the core
machine().current_datetime(systime);
- m_rtc_data[0x7F9] = dec_2_bcd(systime.local_time.second);
- m_rtc_data[0x7FA] = dec_2_bcd(systime.local_time.minute);
- m_rtc_data[0x7FB] = dec_2_bcd(systime.local_time.hour);
-
- m_rtc_data[0x7FC] = dec_2_bcd((systime.local_time.weekday != 0) ? systime.local_time.weekday : 7);
- m_rtc_data[0x7FD] = dec_2_bcd(systime.local_time.mday);
- m_rtc_data[0x7FE] = dec_2_bcd(systime.local_time.month + 1);
- m_rtc_data[0x7FF] = dec_2_bcd(systime.local_time.year - 1900); // Epoch is 1900
+ m_rtc_data[0x7FF9] = dec_2_bcd(systime.local_time.second);
+ m_rtc_data[0x7FFA] = dec_2_bcd(systime.local_time.minute);
+ m_rtc_data[0x7FFB] = dec_2_bcd(systime.local_time.hour);
+
+ m_rtc_data[0x7FFC] = dec_2_bcd((systime.local_time.weekday != 0) ? systime.local_time.weekday : 7);
+ m_rtc_data[0x7FFD] = dec_2_bcd(systime.local_time.mday);
+ m_rtc_data[0x7FFE] = dec_2_bcd(systime.local_time.month + 1);
+ m_rtc_data[0x7FFF] = dec_2_bcd(systime.local_time.year - 1900); // Epoch is 1900
result = m_rtc_data[offset];
}
break;
default:
if (LOG_RTC)
- logerror("%s:RTC read from offset %04X = %08X m_rtc_data[0x7F8] %02X\n", machine().describe_context(), offset, result, m_rtc_data[0x7F8]);
+ logerror("%s:RTC read from offset %04X = %08X m_rtc_data[0x7FF8] %02X\n", machine().describe_context(), offset, result, m_rtc_data[0x7FF8]);
break;
}
return result;
@@ -319,23 +292,31 @@ READ8_MEMBER(atlantis_state::cmos_r)
WRITE8_MEMBER(atlantis_state::cmos_w)
{
system_time systime;
-
- if (m_cmos_write_enabled) {
+ // User I/O 0 = Allow write to cmos[0]. Serial Write Enable?
+ if (offset == 0 && (m_user_io_state & 0x1)) {
+ // Data written is shifted by 1 bit each time. Maybe a serial line output?
+ if (LOG_RTC && m_serial_count == 0)
+ logerror("%06X: cmos_w[0] start serial %08x = %02x\n", machine().device("maincpu")->safe_pc(), offset, data);
+ m_serial_count++;
+ if (m_serial_count == 8)
+ m_serial_count = 0;
+ }
+ else if (m_cmos_write_enabled) {
COMBINE_DATA(&m_rtc_data[offset]);
m_cmos_write_enabled = FALSE;
switch (offset) {
- case 0x7F8: // M48T02 time
+ case 0x7FF8: // M48T02 time
if (data & 0x40) {
// get the current date/time from the core
machine().current_datetime(systime);
- m_rtc_data[0x7F9] = dec_2_bcd(systime.local_time.second);
- m_rtc_data[0x7FA] = dec_2_bcd(systime.local_time.minute);
- m_rtc_data[0x7FB] = dec_2_bcd(systime.local_time.hour);
-
- m_rtc_data[0x7FC] = dec_2_bcd((systime.local_time.weekday != 0) ? systime.local_time.weekday : 7);
- m_rtc_data[0x7FD] = dec_2_bcd(systime.local_time.mday);
- m_rtc_data[0x7FE] = dec_2_bcd(systime.local_time.month + 1);
- m_rtc_data[0x7FF] = dec_2_bcd(systime.local_time.year - 1900); // Epoch is 1900
+ m_rtc_data[0x7FF9] = dec_2_bcd(systime.local_time.second);
+ m_rtc_data[0x7FFA] = dec_2_bcd(systime.local_time.minute);
+ m_rtc_data[0x7FFB] = dec_2_bcd(systime.local_time.hour);
+
+ m_rtc_data[0x7FFC] = dec_2_bcd((systime.local_time.weekday != 0) ? systime.local_time.weekday : 7);
+ m_rtc_data[0x7FFD] = dec_2_bcd(systime.local_time.mday);
+ m_rtc_data[0x7FFE] = dec_2_bcd(systime.local_time.month + 1);
+ m_rtc_data[0x7FFF] = dec_2_bcd(systime.local_time.year - 1900); // Epoch is 1900
}
if (LOG_RTC)
logerror("%s:RTC write to offset %04X = %08X & %08X\n", machine().describe_context(), offset, data, mem_mask);
@@ -396,40 +377,14 @@ WRITE32_MEMBER(atlantis_state::status_leds_w)
}
}
-READ32_MEMBER(atlantis_state::zeus_r)
-{
- UINT32 result = m_zeus_data[offset];
- switch (offset) {
- case 0x1:
- /* bit $000C0070 are tested in a loop until 0 */
- /* bits $00080000 is tested in a loop until 0 */
- /* bit $00000004 is tested for toggling; probably VBLANK */
- // zeus is reset if 0x80 is read
- //if (m_screen->vblank())
- m_zeus_data[offset] = (m_zeus_data[offset] + 1) & 0xf;
- break;
- case 0x41:
- // CPU resets map2, writes 0xffffffff here, and then expects this read
- result &= 0x1fff03ff;
- break;
- }
- if (LOG_ZEUS)
- logerror("%s:zeus_r read from offset %04X = %08X & %08X\n", machine().describe_context(), offset, result, mem_mask);
- return result;
-}
-
-WRITE32_MEMBER(atlantis_state::zeus_w)
+READ32_MEMBER(atlantis_state::cmos_protect_r)
{
- COMBINE_DATA(&m_zeus_data[offset]);
- if (LOG_ZEUS)
- logerror("%s:zeus_w write to offset %04X = %08X & %08X\n", machine().describe_context(), offset, data, mem_mask);
- m_last_offset = offset | 0x30000;
+ return m_cmos_write_enabled;
}
-
-READ32_MEMBER(atlantis_state::cmos_protect_r)
+WRITE32_MEMBER(atlantis_state::asic_fifo_w)
{
- return m_cmos_write_enabled;
+ m_ioasic->fifo_w(data);
}
WRITE32_MEMBER(atlantis_state::dcs3_fifo_full_w)
@@ -496,12 +451,48 @@ WRITE_LINE_MEMBER(atlantis_state::uart1_irq_callback)
}
/*************************************
+* Video interrupts
+*************************************/
+WRITE_LINE_MEMBER(atlantis_state::vblank_irq)
+{
+ //logerror("%s: atlantis_state::vblank state = %i\n", machine().describe_context(), state);
+ if (1) {
+ if (state) {
+ board_ctrl[CTRL_STATUS] |= (1 << VBLANK_IRQ_SHIFT);
+ update_asic_irq();
+ }
+ else {
+ board_ctrl[CTRL_STATUS] &= ~(1 << VBLANK_IRQ_SHIFT);
+ board_ctrl[CTRL_CAUSE] &= ~(1 << VBLANK_IRQ_SHIFT);
+ update_asic_irq();
+ }
+ } else {
+ m_maincpu->set_input_line(VBLANK_IRQ_NUM, state);
+ }
+}
+
+WRITE_LINE_MEMBER(atlantis_state::zeus_irq)
+{
+ //logerror("%s: atlantis_state::zeus_irq state = %i\n", machine().describe_context(), state);
+ if (state) {
+ board_ctrl[CTRL_STATUS] |= (1 << ZEUS_IRQ_SHIFT);
+ update_asic_irq();
+ }
+ else {
+ board_ctrl[CTRL_STATUS] &= ~(1 << ZEUS_IRQ_SHIFT);
+ board_ctrl[CTRL_CAUSE] &= ~(1 << ZEUS_IRQ_SHIFT);
+ update_asic_irq();
+ }
+}
+
+/*************************************
* IDE interrupts
*************************************/
WRITE_LINE_MEMBER(atlantis_state::ide_irq)
{
m_maincpu->set_input_line(IDE_IRQ_NUM, state);
- logerror("%s: atlantis_state::ide_irq state = %i\n", machine().describe_context(), state);
+ if (LOG_IRQ)
+ logerror("%s: atlantis_state::ide_irq state = %i\n", machine().describe_context(), state);
}
/*************************************
@@ -509,7 +500,8 @@ WRITE_LINE_MEMBER(atlantis_state::ide_irq)
*************************************/
WRITE_LINE_MEMBER(atlantis_state::ioasic_irq)
{
- logerror("%s: atlantis_state::ioasic_irq state = %i\n", machine().describe_context(), state);
+ if (LOG_IRQ)
+ logerror("%s: atlantis_state::ioasic_irq state = %i\n", machine().describe_context(), state);
if (state) {
board_ctrl[CTRL_STATUS] |= (1 << IOASIC_IRQ_SHIFT);
update_asic_irq();
@@ -535,13 +527,13 @@ void atlantis_state::update_asic_irq()
if (irqBits && !currState) {
m_maincpu->set_input_line(MIPS3_IRQ0 + irqIndex, ASSERT_LINE);
m_irq_state |= (1 << irqIndex);
- if (1)
+ if (LOG_IRQ)
logerror("atlantis_state::update_asic_irq Asserting IRQ(%d) CAUSE = %02X\n", irqIndex, board_ctrl[CTRL_CAUSE]);
}
else if (!(causeBits) && currState) {
m_maincpu->set_input_line(MIPS3_IRQ0 + irqIndex, CLEAR_LINE);
m_irq_state &= ~(1 << irqIndex);
- if (1)
+ if (LOG_IRQ)
logerror("atlantis_state::update_asic_irq Clearing IRQ(%d) CAUSE = %02X\n", irqIndex, board_ctrl[CTRL_CAUSE]);
}
}
@@ -553,7 +545,8 @@ READ32_MEMBER(atlantis_state::port_ctrl_r)
{
UINT32 newOffset = offset >> 17;
UINT32 result = m_port_ctrl_reg[newOffset];
- logerror("%s: port_ctrl_r newOffset = %02X data = %08X\n", machine().describe_context(), newOffset, result);
+ if (LOG_PORT)
+ logerror("%s: port_ctrl_r newOffset = %02X data = %08X\n", machine().describe_context(), newOffset, result);
return result;
}
@@ -562,22 +555,24 @@ WRITE32_MEMBER(atlantis_state::port_ctrl_w)
UINT32 newOffset = offset >> 17;
COMBINE_DATA(&m_port_ctrl_reg[newOffset]);
- switch (newOffset) {
- //case 1:
- // m_port_ctrl_reg[newOffset] = 0;
- // if (!(data & 0x8))
- // m_port_ctrl_reg[newOffset] = 0*3; // Row 0
- // else if (!(data & 0x10))
- // m_port_ctrl_reg[newOffset] = 1*3; // Row 1
- // else if (!(data & 0x20))
- // m_port_ctrl_reg[newOffset] = 2*3; // Row 2
- // else if (!(data & 0x40))
- // m_port_ctrl_reg[newOffset] = 3*3; // Row 3
- // logerror("%s: port_ctrl_w Keypad Row Sel = %04X data = %08X\n", machine().describe_context(), m_port_ctrl_reg[newOffset], data);
- // break;
- default:
- logerror("%s: port_ctrl_w write to offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
- break;
+ //switch (newOffset) {
+ if (newOffset == 1) {
+ UINT32 bits = ioport("KEYPAD")->read();
+ m_port_ctrl_reg[2] = 0;
+ if (!(data & 0x8))
+ m_port_ctrl_reg[2] = bits & 7; // Row 0
+ else if (!(data & 0x10))
+ m_port_ctrl_reg[2] = (bits >> 4) & 7; // Row 1
+ else if (!(data & 0x20))
+ m_port_ctrl_reg[2] = (bits >> 8) & 7; // Row 2
+ else if (!(data & 0x40))
+ m_port_ctrl_reg[2] = (bits >> 12) & 7; // Row 3
+ if (LOG_PORT)
+ logerror("%s: port_ctrl_w Keypad Row Sel = %04X bits = %08X\n", machine().describe_context(), data, bits);
+ }
+ else {
+ if (LOG_PORT)
+ logerror("%s: port_ctrl_w write to offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
}
}
@@ -625,24 +620,17 @@ void atlantis_state::machine_reset()
m_dcs->reset_w(0);
m_user_io_state = 0;
m_cmos_write_enabled = FALSE;
- memset(m_zeus_data, 0, sizeof(m_zeus_data));
- m_red_count = 0;
+ m_serial_count = 0;
m_irq_state = 0;
memset(board_ctrl, 0, sizeof(board_ctrl));
memset(m_port_ctrl_reg, 0, sizeof(m_port_ctrl_reg));
}
-
-
/*************************************
- *
- * Main CPU memory handlers
- *
+ * Address Maps
*************************************/
-
static ADDRESS_MAP_START( map0, AS_PROGRAM, 32, atlantis_state )
- AM_RANGE(0x00000000, 0x00000fff) AM_READWRITE8(red_r, red_w, 0xff)
- AM_RANGE(0x0001e000, 0x0001ffff) AM_READWRITE8(cmos_r, cmos_w, 0xff)
+ AM_RANGE(0x00000000, 0x0001ffff) AM_READWRITE8(cmos_r, cmos_w, 0xff)
AM_RANGE(0x00100000, 0x0010001f) AM_DEVREADWRITE8("uart0", ns16550_device, ins8250_r, ins8250_w, 0xff) // Serial UART0 (TL16C552 CS0)
AM_RANGE(0x00180000, 0x0018001f) AM_DEVREADWRITE8("uart1", ns16550_device, ins8250_r, ins8250_w, 0xff) // Serial UART1 (TL16C552 CS1)
//AM_RANGE(0x00200000, 0x0020001f) // Parallel UART (TL16C552 CS2)
@@ -666,21 +654,20 @@ static ADDRESS_MAP_START( map1, AS_PROGRAM, 32, atlantis_state )
AM_RANGE(0x00000000, 0x0000003f) AM_DEVREADWRITE("ioasic", midway_ioasic_device, read, write)
// asic_fifo_w
// dcs3_fifo_full_w
- //AM_RANGE(0x00200000, 0x00200003)
+ AM_RANGE(0x00200000, 0x00200003) AM_WRITE(dcs3_fifo_full_w)
AM_RANGE(0x00400000, 0x00400003) AM_DEVWRITE("dcs", dcs_audio_device, dsio_idma_addr_w)
AM_RANGE(0x00600000, 0x00600003) AM_DEVREADWRITE("dcs", dcs_audio_device, dsio_idma_data_r, dsio_idma_data_w)
- //AM_RANGE(0x00800000, 0x00800003) AM_WRITE(dcs3_fifo_full_w)
- //AM_RANGE(0x00800000, 0x00800003) AM_WRITE(asic_fifo_w)
- //AM_RANGE(0x00800000, 0x00a00003) AM_READWRITE(port_ctrl_r, port_ctrl_w)
+ AM_RANGE(0x00800000, 0x00900003) AM_READWRITE(port_ctrl_r, port_ctrl_w)
//AM_RANGE(0x00800000, 0x00800003) // Written once = 0000fff8
//AM_RANGE(0x00880000, 0x00880003) // Initial write 0000fff0, follow by sequence ffef, ffdf, ffbf, fff7. Row Select?
//AM_RANGE(0x00900000, 0x00900003) // Read once before each sequence write to 0x00880000. Code checks bits 0,1,2. Keypad?
//AM_RANGE(0x00980000, 0x00980003) // Read / Write. Bytes written 0x8f, 0xcf. Code if read 0x1 then read 00a00000. POTs?
//AM_RANGE(0x00a00000, 0x00a00003)
- ADDRESS_MAP_END
+ AM_RANGE(0x00980000, 0x00980003) AM_NOP // AM_WRITE(asic_fifo_w)
+ADDRESS_MAP_END
static ADDRESS_MAP_START(map2, AS_PROGRAM, 32, atlantis_state)
- AM_RANGE(0x00000000, 0x000001ff) AM_READWRITE(zeus_r, zeus_w)
+ AM_RANGE(0x00000000, 0x000001ff) AM_DEVREADWRITE("zeus2", zeus2_device, zeus2_r, zeus2_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( map3, AS_PROGRAM, 32, atlantis_state )
@@ -696,26 +683,26 @@ ADDRESS_MAP_END
static INPUT_PORTS_START( mwskins )
PORT_START("DIPS")
PORT_DIPNAME(0x0003, 0x0003, "Boot Mode")
- PORT_DIPSETTING(0x0003, "Normal Boot")
+ PORT_DIPSETTING(0x0003, "Run Game")
PORT_DIPSETTING(0x0002, "Boot EEPROM Based Self Test")
PORT_DIPSETTING(0x0001, "Boot Disk Based Self Test")
PORT_DIPSETTING(0x0000, "Run Factory Tests")
- PORT_DIPNAME(0x0004, 0x0004, "Unknown0004")
- PORT_DIPSETTING(0x0004, DEF_STR(Off))
- PORT_DIPSETTING(0x0000, DEF_STR(On))
- PORT_DIPNAME(0x0008, 0x0008, "Unknown0008")
+ PORT_DIPNAME(0x0004, 0x0004, "Boot Message")
+ PORT_DIPSETTING(0x0004, "Quiet")
+ PORT_DIPSETTING(0x0000, "Squawk During Boot")
+ PORT_DIPNAME(0x0008, 0x0008, "Reserved")
PORT_DIPSETTING(0x0008, DEF_STR(Off))
PORT_DIPSETTING(0x0000, DEF_STR(On))
- PORT_DIPNAME(0x0010, 0x0010, "Unknown0010")
+ PORT_DIPNAME(0x0010, 0x0010, "Reserved")
PORT_DIPSETTING(0x0010, DEF_STR(Off))
PORT_DIPSETTING(0x0000, DEF_STR(On))
- PORT_DIPNAME(0x0020, 0x0020, "Unknown0020")
+ PORT_DIPNAME(0x0020, 0x0020, "Reserved")
PORT_DIPSETTING(0x0020, DEF_STR(Off))
PORT_DIPSETTING(0x0000, DEF_STR(On))
- PORT_DIPNAME(0x0040, 0x0040, "Unknown0040")
+ PORT_DIPNAME(0x0040, 0x0040, "Reserved")
PORT_DIPSETTING(0x0040, DEF_STR(Off))
PORT_DIPSETTING(0x0000, DEF_STR(On))
- PORT_DIPNAME(0x0080, 0x0080, "Unknown0080")
+ PORT_DIPNAME(0x0080, 0x0080, "Reserved")
PORT_DIPSETTING(0x0080, DEF_STR(Off))
PORT_DIPSETTING(0x0000, DEF_STR(On))
PORT_DIPNAME(0x0100, 0x0100, "Unknown0100")
@@ -783,18 +770,18 @@ static INPUT_PORTS_START( mwskins )
PORT_BIT(0xffff, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("KEYPAD")
- PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD) /* keypad 3 */
- PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD) /* keypad 1 */
- PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD) /* keypad 2 */
- PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD) /* keypad 6 */
- PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD) /* keypad 4 */
- PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD) /* keypad 5 */
- PORT_BIT(0x0100, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD) /* keypad 9 */
- PORT_BIT(0x0200, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD) /* keypad 7 */
- PORT_BIT(0x0400, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD) /* keypad 8 */
- PORT_BIT(0x1000, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad #") PORT_CODE(KEYCODE_PLUS_PAD) /* keypad # */
- PORT_BIT(0x2000, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad *") PORT_CODE(KEYCODE_MINUS_PAD) /* keypad * */
- PORT_BIT(0x4000, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 0") PORT_CODE(KEYCODE_0_PAD) /* keypad 0 */
+ PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD) /* keypad 1 */
+ PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD) /* keypad 2 */
+ PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD) /* keypad 3 */
+ PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD) /* keypad 4 */
+ PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD) /* keypad 5 */
+ PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD) /* keypad 6 */
+ PORT_BIT(0x0100, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD) /* keypad 7 */
+ PORT_BIT(0x0200, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD) /* keypad 8 */
+ PORT_BIT(0x0400, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD) /* keypad 9 */
+ PORT_BIT(0x1000, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad *") PORT_CODE(KEYCODE_MINUS_PAD) /* keypad - */
+ PORT_BIT(0x2000, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 0") PORT_CODE(KEYCODE_0_PAD) /* keypad 0 */
+ PORT_BIT(0x4000, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad #") PORT_CODE(KEYCODE_PLUS_PAD) /* keypad + */
INPUT_PORTS_END
@@ -830,21 +817,18 @@ static MACHINE_CONFIG_START( mwskins, atlantis_state )
MCFG_IDE_PCI_IRQ_HANDLER(DEVWRITELINE(":", atlantis_state, ide_irq))
/* video hardware */
- MCFG_SCREEN_ADD("screen", RASTER)
- MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK)
- MCFG_SCREEN_REFRESH_RATE(60)
- MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)
- MCFG_SCREEN_SIZE(320, 240)
- MCFG_SCREEN_VISIBLE_AREA(0, 319, 0, 239)
- MCFG_SCREEN_UPDATE_DRIVER(atlantis_state, screen_update_mwskins)
- MCFG_SCREEN_PALETTE("palette")
+ MCFG_DEVICE_ADD("zeus2", ZEUS2, ZEUS2_VIDEO_CLOCK)
+ MCFG_ZEUS2_IRQ_CB(WRITELINE(atlantis_state, zeus_irq))
+ MCFG_ZEUS2_VBLANK_CB(WRITELINE(atlantis_state, vblank_irq))
- MCFG_PALETTE_ADD_BBBBBGGGGGRRRRR("palette")
+ MCFG_SCREEN_ADD("screen", RASTER)
+ MCFG_SCREEN_RAW_PARAMS(ZEUS2_VIDEO_CLOCK / 8, 529, 0, 400, 278, 0, 256)
+ MCFG_SCREEN_UPDATE_DEVICE("zeus2", zeus2_device, screen_update)
/* sound hardware */
//MCFG_DEVICE_ADD("dcs", DCS2_AUDIO_DSIO, 0)
MCFG_DEVICE_ADD("dcs", DCS2_AUDIO_DENVER, 0)
- MCFG_DCS2_AUDIO_DRAM_IN_MB(8)
+ MCFG_DCS2_AUDIO_DRAM_IN_MB(4)
MCFG_DCS2_AUDIO_POLLING_OFFSET(0) /* no place to hook :-( */
MCFG_DEVICE_ADD("ioasic", MIDWAY_IOASIC, 0)
diff --git a/src/mame/drivers/midzeus.cpp b/src/mame/drivers/midzeus.cpp
index 816dc219648..a8eb9a68f72 100644
--- a/src/mame/drivers/midzeus.cpp
+++ b/src/mame/drivers/midzeus.cpp
@@ -37,6 +37,7 @@ The Grid v1.2 10/18/2000
#include "machine/nvram.h"
#include "crusnexo.lh"
+#include "video/zeus2.h"
#define CPU_CLOCK XTAL_60MHz
@@ -114,6 +115,10 @@ INTERRUPT_GEN_MEMBER(midzeus_state::display_irq)
machine().scheduler().timer_set(attotime::from_hz(30000000), timer_expired_delegate(FUNC(midzeus_state::display_irq_off),this));
}
+WRITE_LINE_MEMBER(midzeus2_state::zeus_irq)
+{
+ m_maincpu->set_input_line(2, ASSERT_LINE);
+}
/*************************************
@@ -575,7 +580,7 @@ static ADDRESS_MAP_START( zeus2_map, AS_PROGRAM, 32, midzeus2_state )
AM_RANGE(0x000000, 0x03ffff) AM_RAM AM_SHARE("ram_base")
AM_RANGE(0x400000, 0x43ffff) AM_RAM
AM_RANGE(0x808000, 0x80807f) AM_READWRITE(tms32031_control_r, tms32031_control_w) AM_SHARE("tms32031_ctl")
- AM_RANGE(0x880000, 0x88007f) AM_READWRITE(zeus2_r, zeus2_w) AM_SHARE("zeusbase")
+ AM_RANGE(0x880000, 0x88007f) AM_DEVREADWRITE("zeus2", zeus2_device, zeus2_r, zeus2_w)
AM_RANGE(0x8a0000, 0x8a003f) AM_READWRITE(linkram_r, linkram_w) AM_SHARE("linkram")
AM_RANGE(0x8d0000, 0x8d000a) AM_READWRITE(bitlatches_r, bitlatches_w)
AM_RANGE(0x900000, 0x91ffff) AM_READWRITE(zpram_r, zpram_w) AM_SHARE("nvram") AM_MIRROR(0x020000)
@@ -1134,7 +1139,7 @@ static MACHINE_CONFIG_START( midzeus2, midzeus2_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", TMS32032, CPU_CLOCK)
MCFG_CPU_PROGRAM_MAP(zeus2_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", midzeus2_state, display_irq)
+ MCFG_CPU_VBLANK_INT_DRIVER("screen", midzeus2_state, display_irq)
MCFG_MACHINE_START_OVERRIDE(midzeus2_state,midzeus)
MCFG_MACHINE_RESET_OVERRIDE(midzeus2_state,midzeus)
@@ -1143,9 +1148,10 @@ static MACHINE_CONFIG_START( midzeus2, midzeus2_state )
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_RAW_PARAMS(MIDZEUS_VIDEO_CLOCK/4, 666, 0, 512, 438, 0, 400)
- MCFG_SCREEN_UPDATE_DRIVER(midzeus2_state, screen_update_midzeus2)
+ MCFG_SCREEN_UPDATE_DEVICE("zeus2", zeus2_device, screen_update)
- MCFG_VIDEO_START_OVERRIDE(midzeus2_state,midzeus2)
+ MCFG_DEVICE_ADD("zeus2", ZEUS2, ZEUS2_VIDEO_CLOCK)
+ MCFG_ZEUS2_IRQ_CB(WRITELINE(midzeus2_state, zeus_irq))
/* sound hardware */
MCFG_DEVICE_ADD("dcs", DCS2_AUDIO_2104, 0)
diff --git a/src/mame/drivers/pc9801.cpp b/src/mame/drivers/pc9801.cpp
index 6fa412a978c..846f87cb95e 100644
--- a/src/mame/drivers/pc9801.cpp
+++ b/src/mame/drivers/pc9801.cpp
@@ -3185,6 +3185,8 @@ static MACHINE_CONFIG_FRAGMENT( pc9801_ide )
MCFG_ATA_INTERFACE_IRQ_HANDLER(WRITELINE(pc9801_state, ide1_irq_w))
MCFG_ATA_INTERFACE_ADD("ide2", pc9801_atapi_devices, "pc9801_cd", nullptr, false)
MCFG_ATA_INTERFACE_IRQ_HANDLER(WRITELINE(pc9801_state, ide2_irq_w))
+
+ MCFG_SOFTWARE_LIST_ADD("cd_list","pc98_cd")
MACHINE_CONFIG_END
static MACHINE_CONFIG_FRAGMENT( pc9801_common )
diff --git a/src/mame/drivers/poker72.cpp b/src/mame/drivers/poker72.cpp
index 4867465e902..2d88b84b5b4 100644
--- a/src/mame/drivers/poker72.cpp
+++ b/src/mame/drivers/poker72.cpp
@@ -1,16 +1,22 @@
// license:BSD-3-Clause
-// copyright-holders:David Haywood
-/*
- Unknown game, dump was marked 'slot 72 - poker'
+// copyright-holders:David Haywood, Robbbert
+/************************************************************************************************
+ Poker Monarch
GFX roms contain
'Extrema Systems International Ltd'
as well as a logo for the company.
- There are also 'Lucky Boy' graphics in various places, which might be the title.
+ There are also 'Lucky Boy' graphics in various places.
+ * Turn on all the dips of SW1
+ * Restart game
+ * If it says ERROR OF RAM GAME STOP, press F2
+ * When you get a blank blue screen Press Alt+2
+ * This gives a setup screen. Press F2 to see cards and logo (and it beeps)
+ * Depending on settings of SW1, you can get other cards, or other test screens.
-*/
+*************************************************************************************************/
#include "emu.h"
#include "cpu/z80/z80.h"
@@ -89,17 +95,15 @@ WRITE8_MEMBER(poker72_state::poker72_paletteram_w)
WRITE8_MEMBER(poker72_state::output_w)
{
- UINT8 *ROM = memregion("maincpu")->base();
-
printf("%02x\n",data);
/* if((data & 0xc) == 0xc)
- membank("bank1")->set_base(&ROM[0x10000]);
+ membank("bank1")->set_entry(2);
else*/
if(data & 8)
- membank("bank1")->set_base(&ROM[0x08000]);
+ membank("bank1")->set_entry(1);
else
- membank("bank1")->set_base(&ROM[0x00000]);
+ membank("bank1")->set_entry(0);
}
WRITE8_MEMBER(poker72_state::tile_bank_w)
@@ -108,17 +112,17 @@ WRITE8_MEMBER(poker72_state::tile_bank_w)
}
static ADDRESS_MAP_START( poker72_map, AS_PROGRAM, 8, poker72_state )
- AM_RANGE(0x0000, 0xbfff) AM_ROMBANK("bank1")
+ AM_RANGE(0x0000, 0x7fff) AM_ROMBANK("bank1")
AM_RANGE(0xc000, 0xdfff) AM_RAM //work ram
AM_RANGE(0xe000, 0xefff) AM_RAM AM_SHARE("vram")
AM_RANGE(0xf000, 0xfbff) AM_RAM_WRITE(poker72_paletteram_w) AM_SHARE("pal")
AM_RANGE(0xfc00, 0xfdff) AM_RAM //???
- AM_RANGE(0xfe08, 0xfe08) AM_READ_PORT("IN0")
+ AM_RANGE(0xfe08, 0xfe08) AM_READ_PORT("SW1")
AM_RANGE(0xfe09, 0xfe09) AM_READ_PORT("IN1")
AM_RANGE(0xfe0a, 0xfe0a) AM_READ_PORT("IN2")
- AM_RANGE(0xfe0c, 0xfe0c) AM_READ_PORT("IN3")
- AM_RANGE(0xfe0d, 0xfe0d) AM_READ_PORT("IN4")
- AM_RANGE(0xfe0e, 0xfe0e) AM_READ_PORT("IN5")
+ AM_RANGE(0xfe0c, 0xfe0c) AM_READ_PORT("SW4")
+ AM_RANGE(0xfe0d, 0xfe0d) AM_READ_PORT("SW5")
+ AM_RANGE(0xfe0e, 0xfe0e) AM_READ_PORT("SW6")
AM_RANGE(0xfe17, 0xfe17) AM_READNOP //irq ack
AM_RANGE(0xfe20, 0xfe20) AM_WRITE(output_w) //output, irq enable?
@@ -142,8 +146,8 @@ ADDRESS_MAP_END
static INPUT_PORTS_START( poker72 )
- PORT_START("IN0")
- PORT_DIPNAME( 0x01, 0x00, "IN0" )
+ PORT_START("SW1")
+ PORT_DIPNAME( 0x01, 0x00, "SW1" )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x01, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) )
@@ -169,28 +173,28 @@ static INPUT_PORTS_START( poker72 )
PORT_DIPSETTING( 0x80, DEF_STR( On ) )
PORT_START("IN1")
- PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_POKER_HOLD1 )
- PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_POKER_HOLD2 )
- PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_POKER_HOLD3 )
- PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_POKER_HOLD4 )
- PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_POKER_HOLD5 )
- PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("M. Bet")
- PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_COIN1 )
- PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Black")
+ PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_POKER_HOLD1 ) // Z
+ PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_POKER_HOLD2 ) // X
+ PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_POKER_HOLD3 ) // C
+ PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_POKER_HOLD4 ) // V
+ PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_POKER_HOLD5 ) // B
+ PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("M. Bet")
+ PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_COIN1 )
+ PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Black")
PORT_START("IN2")
- PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Red")
- PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP )
- PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE )
- PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL )
- PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_GAMBLE_BET )
- PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_COIN2 )
- PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_SERVICE1 )
- PORT_SERVICE( 0x0080, IP_ACTIVE_LOW )
-
- PORT_START("IN3")
- PORT_DIPNAME( 0x01, 0x00, "IN3" )
+ PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Red")
+ PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_GAMBLE_D_UP )
+ PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_GAMBLE_TAKE )
+ PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_GAMBLE_DEAL ) // '2'
+ PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_GAMBLE_BET ) // M
+ PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_COIN2 )
+ PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_SERVICE1 ) // '9'
+ PORT_SERVICE( 0x0080, IP_ACTIVE_HIGH ) // F2
+
+ PORT_START("SW4")
+ PORT_DIPNAME( 0x01, 0x00, "SW4" )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x01, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) )
@@ -214,8 +218,8 @@ static INPUT_PORTS_START( poker72 )
PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x80, DEF_STR( On ) )
- PORT_START("IN4")
- PORT_DIPNAME( 0x01, 0x00, "IN4" )
+ PORT_START("SW5")
+ PORT_DIPNAME( 0x01, 0x00, "SW5" )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x01, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) )
@@ -239,8 +243,8 @@ static INPUT_PORTS_START( poker72 )
PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x80, DEF_STR( On ) )
- PORT_START("IN5")
- PORT_DIPNAME( 0x01, 0x00, "IN5" )
+ PORT_START("SW6")
+ PORT_DIPNAME( 0x01, 0x00, "SW6" )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x01, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) )
@@ -266,8 +270,8 @@ static INPUT_PORTS_START( poker72 )
PORT_DIPSETTING( 0x80, DEF_STR( On ) )
- PORT_START("DSW0")
- PORT_DIPNAME( 0x01, 0x00, "DSW0" )
+ PORT_START("SW2")
+ PORT_DIPNAME( 0x01, 0x00, "SW2" )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x01, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) )
@@ -292,8 +296,8 @@ static INPUT_PORTS_START( poker72 )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x80, DEF_STR( On ) )
- PORT_START("DSW1")
- PORT_DIPNAME( 0x01, 0x00, "DSW1" )
+ PORT_START("SW3")
+ PORT_DIPNAME( 0x01, 0x00, "SW3" )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x01, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) )
@@ -354,9 +358,7 @@ PALETTE_INIT_MEMBER(poker72_state, poker72)
void poker72_state::machine_reset()
{
- UINT8 *ROM = memregion("maincpu")->base();
-
- membank("bank1")->set_base(&ROM[0]);
+ membank("bank1")->set_entry(0);
}
static MACHINE_CONFIG_START( poker72, poker72_state )
@@ -384,15 +386,15 @@ static MACHINE_CONFIG_START( poker72, poker72_state )
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("ay", AY8910, 8000000/8) /* ? Mhz */
- MCFG_AY8910_PORT_A_READ_CB(IOPORT("DSW0"))
- MCFG_AY8910_PORT_B_READ_CB(IOPORT("DSW1"))
+ MCFG_AY8910_PORT_A_READ_CB(IOPORT("SW2"))
+ MCFG_AY8910_PORT_B_READ_CB(IOPORT("SW3"))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
MACHINE_CONFIG_END
ROM_START( poker72 )
- ROM_REGION( 0x20000, "maincpu", 0 )
+ ROM_REGION( 0x20000, "roms", 0 )
ROM_LOAD( "27010.bin", 0x00000, 0x20000, CRC(62447341) SHA1(e442c1f834a5dd2ab6ab3bdd316dfa86f2ca6647) )
ROM_REGION( 0x1000, "89c51", 0 )
@@ -407,9 +409,14 @@ ROM_END
DRIVER_INIT_MEMBER(poker72_state,poker72)
{
- UINT8 *rom = memregion("maincpu")->base();
+ UINT8 *rom = memregion("roms")->base();
+
+ // configure and intialize bank 1
+ membank("bank1")->configure_entries(0, 4, memregion("roms")->base(), 0x8000);
+ membank("bank1")->set_entry(0);
- rom[0x4a9] = 0x28;
+ //rom[0x4a9] = 0x28;
+ rom[0x4aa] = 0x00;
}
-GAME( 1995, poker72, 0, poker72, poker72, poker72_state, poker72, ROT0, "Extrema Systems International Ltd.", "Poker Monarch (v2.50)", MACHINE_NOT_WORKING ) // actually unknown, was marked 'slot 72 poker' Manufacturers logo and 'Lucky Boy' gfx in rom..
+GAME( 1995, poker72, 0, poker72, poker72, poker72_state, poker72, ROT0, "Extrema Systems International Ltd.", "Poker Monarch (v2.50)", MACHINE_NOT_WORKING )
diff --git a/src/mame/drivers/sun4.cpp b/src/mame/drivers/sun4.cpp
index e89fa616231..ceae4a5e568 100644
--- a/src/mame/drivers/sun4.cpp
+++ b/src/mame/drivers/sun4.cpp
@@ -387,6 +387,8 @@
#include "emu.h"
#include "cpu/sparc/sparc.h"
+#include "machine/z80scc.h"
+#include "bus/rs232/rs232.h"
#define ENA_NOTBOOT 0x80
#define ENA_SDVMA 0x20
@@ -394,6 +396,22 @@
#define ENA_RESET 0x04
#define ENA_DIAG 0x01
+#define SCC1_TAG "kbdmouse"
+#define SCC2_TAG "uart"
+#define RS232A_TAG "rs232a"
+#define RS232B_TAG "rs232b"
+
+#define ASI_SYSTEM_SPACE 2
+#define ASI_SEGMENT_MAP 3
+#define ASI_PAGE_MAP 4
+#define ASI_USER_INSN 8
+#define ASI_SUPER_INSN 9
+#define ASI_USER_DATA 10
+#define ASI_SUPER_DATA 11
+#define ASI_FLUSH_SEGMENT 12
+#define ASI_FLUSH_PAGE 13
+#define ASI_FLUSH_CONTEXT 14
+
class sun4_state : public driver_device
{
public:
@@ -401,7 +419,10 @@ public:
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_rom(*this, "user1")
+ , m_kbdmouse(*this, SCC1_TAG)
+ , m_uart(*this, SCC2_TAG)
, m_rom_ptr(nullptr)
+ , m_context(0)
, m_system_enable(0)
{
}
@@ -416,39 +437,172 @@ protected:
required_device<mb86901_device> m_maincpu;
required_memory_region m_rom;
+ required_device<z80scc_device> m_kbdmouse;
+ required_device<z80scc_device> m_uart;
+
+ UINT32 read_supervisor_data(UINT32 vaddr, UINT32 mem_mask);
+ void write_supervisor_data(UINT32 vaddr, UINT32 data, UINT32 mem_mask);
+
UINT32 *m_rom_ptr;
UINT32 m_context;
+ UINT16 m_segmap[8][4096];
+ UINT32 m_pagemap[8192];
UINT32 m_system_enable;
};
+#define SEGMENT(vaddr) m_segmap[m_context & 7][((vaddr) >> 18) & 0xfff]
+#define PAGE(vaddr) m_pagemap[((m_segmap[m_context & 7][((vaddr) >> 18) & 0xfff] & 0x7f) << 6) | (((vaddr) >> 12) & 0x3f)]
+#define PADDR(vaddr) (((PAGE(vaddr) << 12) & 0x0ffff000) | ((vaddr) & 0xfff))
+
+UINT32 sun4_state::read_supervisor_data(UINT32 vaddr, UINT32 mem_mask)
+{
+ UINT32 page = PAGE(vaddr);
+ bool v = (page & 0x80000000) ? true : false;
+ bool w = (page & 0x40000000) ? true : false;
+ bool s = (page & 0x20000000) ? true : false;
+ bool x = (page & 0x10000000) ? true : false;
+ int t = (page & 0x0c000000) >> 26;
+ bool a = (page & 0x02000000) ? true : false;
+ bool m = (page & 0x01000000) ? true : false;
+ char mode[4] = { 'M', 'S', '0', '1' };
+
+ logerror("supervisor data read: vaddr %08x, paddr %08x, context %d, segment entry %02x, page entry %08x, %c%c%c%c%c%c%c\n", vaddr, PADDR(vaddr), m_context, SEGMENT(vaddr), PAGE(vaddr)
+ , v ? 'V' : 'v', w ? 'W' : 'w', s ? 'S' : 's', x ? 'X' : 'x', mode[t], a ? 'A' : 'a', m ? 'M' : 'm');
+ return 0;
+}
+
+void sun4_state::write_supervisor_data(UINT32 vaddr, UINT32 data, UINT32 mem_mask)
+{
+ UINT32 page = PAGE(vaddr);
+ bool v = (page & 0x80000000) ? true : false;
+ bool w = (page & 0x40000000) ? true : false;
+ bool s = (page & 0x20000000) ? true : false;
+ bool x = (page & 0x10000000) ? true : false;
+ int t = (page & 0x0c000000) >> 26;
+ bool a = (page & 0x02000000) ? true : false;
+ bool m = (page & 0x01000000) ? true : false;
+ char mode[4] = { 'M', 'S', '0', '1' };
+
+ logerror("supervisor data write: vaddr %08x, paddr %08x, data %08x, mem_mask %08x, context %d, segment entry %02x, page entry %08x, %c%c%c%c%c%c%c\n", vaddr, PADDR(vaddr), data, mem_mask,
+ m_context, SEGMENT(vaddr), PAGE(vaddr), v ? 'V' : 'v', w ? 'W' : 'w', s ? 'S' : 's', x ? 'X' : 'x', mode[t], a ? 'A' : 'a', m ? 'M' : 'm');
+}
+
READ32_MEMBER( sun4_state::sun4_mmu_r )
{
UINT8 asi = m_maincpu->get_asi();
- if (asi == 2 && !space.debugger_access())
+ if (!space.debugger_access())
{
- switch (offset >> 26)
+ switch(asi)
{
- case 3: // context reg
- return m_context;
-
- case 4: // system enable reg
- return m_system_enable;
-
- case 6: // bus error register
- return 0;
-
- case 8: // (d-)cache tags
- logerror("sun4: read dcache tags @ %x, PC = %x\n", offset, m_maincpu->pc());
- return 0xffffffff;
+ case ASI_SYSTEM_SPACE:
+ switch (offset >> 26)
+ {
+ case 3: // context reg
+ logerror("sun4: read context register %08x (& %08x) asi 2, offset %x, PC = %x\n", m_context << 24, mem_mask, offset << 2, m_maincpu->pc());
+ return m_context << 24;
+
+ case 4: // system enable reg
+ logerror("sun4: read system enable register %08x (& %08x) asi 2, offset %x, PC = %x\n", m_system_enable << 24, mem_mask, offset << 2, m_maincpu->pc());
+ return m_system_enable << 24;
+
+ case 8: // (d-)cache tags
+ logerror("sun4: read dcache tags %08x (& %08x) asi 2, offset %x, PC = %x\n", 0xffffffff, mem_mask, offset << 2, m_maincpu->pc());
+ return 0xffffffff;
+
+ case 9: // (d-)cache data
+ logerror("sun4: read dcache data %08x (& %08x) asi 2, offset %x, PC = %x\n", 0xffffffff, mem_mask, offset << 2, m_maincpu->pc());
+ return 0xffffffff;
+
+ case 15: // Type 1 space passthrough
+ switch ((offset >> 22) & 15)
+ {
+ case 0: // keyboard/mouse
+ switch (offset & 1)
+ {
+ case 0:
+ {
+ UINT32 ret = 0;
+ if (mem_mask & 0xffff0000)
+ ret |= m_kbdmouse->cb_r(space, 0) << 24;
+ if (mem_mask & 0x0000ffff)
+ ret |= m_kbdmouse->db_r(space, 0) << 8;
+ return ret;
+ }
+ case 1:
+ {
+ UINT32 ret = 0;
+ if (mem_mask & 0xffff0000)
+ ret |= m_kbdmouse->ca_r(space, 0) << 24;
+ if (mem_mask & 0x0000ffff)
+ ret |= m_kbdmouse->da_r(space, 0) << 8;
+ return ret;
+ }
+ }
+ break;
+ case 1: // serial ports
+ switch (offset & 1)
+ {
+ case 0:
+ {
+ UINT32 ret = 0;
+ if (mem_mask & 0xffff0000)
+ ret |= m_uart->cb_r(space, 0) << 24;
+ if (mem_mask & 0x0000ffff)
+ ret |= m_uart->db_r(space, 0) << 8;
+ return ret;
+ }
+ case 1:
+ {
+ UINT32 ret = 0;
+ if (mem_mask & 0xffff0000)
+ ret |= m_uart->ca_r(space, 0) << 24;
+ if (mem_mask & 0x0000ffff)
+ ret |= m_uart->da_r(space, 0) << 8;
+ return ret;
+ }
+ }
+ break;
+
+ default:
+ logerror("sun4: read unknown type 1 space at address %x (& %08x) asi 2, offset %x, PC = %x\n", offset << 2, mem_mask, offset << 2, m_maincpu->pc());
+ }
+ break;
+
+ case 0: // IDPROM - TODO: SPARCstation-1 does not have an ID prom and a timeout should occur.
+ default:
+ logerror("sun4: read unknown register (& %08x) asi 2, offset %x, PC = %x\n", mem_mask, offset << 2, m_maincpu->pc());
+ return 0;
+ }
+ break;
+
+ case ASI_SEGMENT_MAP:
+ {
+ logerror("sun4: read m_segmap[%d][(%08x >> 18) & 0xfff = %03x] = %08x << 24 & %08x\n", m_context & 7, offset << 2, (offset >> 16) & 0xfff, SEGMENT(offset << 2), mem_mask);
+ UINT32 result = SEGMENT(offset << 2);
+ while (!(mem_mask & 1))
+ {
+ mem_mask >>= 1;
+ result <<= 1;
+ }
+ return result;
+ }
+
+ case ASI_PAGE_MAP: // page map
+ {
+ logerror("sun4: read m_pagemap[(m_segmap[%d][(%08x >> 18) & 0xfff = %03x] = %08x << 6) | ((%08x >> 12) & 0x3f)]] = %08x & %08x\n", m_context & 7, offset << 2, (offset >> 16) & 0xfff, SEGMENT(offset << 2), offset << 2, PAGE(offset << 2), mem_mask);
+ return PAGE(offset << 2);
+ }
+
+ case ASI_SUPER_INSN: // supervisor instruction space
+ return m_rom_ptr[offset & 0x1ffff]; // wrong, but works for now
+
+ case ASI_SUPER_DATA:
+ return read_supervisor_data(offset << 2, mem_mask);
- case 9: // (d-)cache data
- logerror("sun4: read dcache data @ %x, PC = %x\n", offset, m_maincpu->pc());
- return 0xffffffff;
-
- case 0: // IDPROM - TODO: SPARCstation-1 does not have an ID prom and a timeout should occur.
default:
- return 0;
+ logerror("sun4: read (& %08x) asi %d byte offset %x, PC = %x\n", mem_mask, asi, offset << 2, m_maincpu->pc());
+ break;
}
}
@@ -456,10 +610,6 @@ READ32_MEMBER( sun4_state::sun4_mmu_r )
{
return m_rom_ptr[offset & 0x1ffff];
}
- else if (asi < 8 || asi > 11)
- {
- logerror("sun4: read asi %d byte offset %x, PC = %x\n", asi, offset << 2, m_maincpu->pc());
- }
return 0;
}
@@ -468,34 +618,107 @@ WRITE32_MEMBER( sun4_state::sun4_mmu_w )
{
UINT8 asi = m_maincpu->get_asi();
- if (asi == 2)
+ switch (asi)
{
- switch (offset >> 26)
+ case 2:
+ switch (offset >> 26)
+ {
+ case 3: // context reg
+ logerror("sun4: %08x (& %08x) asi 2 to context register, offset %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc());
+ m_context = (UINT8)(data >> 24) & 7;
+ return;
+
+ case 4: // system enable reg
+ logerror("sun4: write %08x (& %08x) asi 2 to system enable register, offset %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc());
+ m_system_enable = (UINT8)data;
+ return;
+
+ case 8: // cache tags
+ logerror("sun4: write %08x (& %08x) asi 2 to cache tags @ %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc());
+ return;
+
+ case 9: // cache data
+ logerror("sun4: write %08x (& %08x) asi 2 to cache data @ %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc());
+ return;
+
+ case 15: // Type 1 space passthrough
+ switch ((offset >> 22) & 15)
+ {
+ case 0: // keyboard/mouse
+ switch (offset & 1)
+ {
+ case 0:
+ if (mem_mask & 0xffff0000)
+ m_kbdmouse->cb_w(space, 0, data >> 24);
+ if (mem_mask & 0x0000ffff)
+ m_kbdmouse->db_w(space, 0, data >> 24);
+ break;
+ case 1:
+ if (mem_mask & 0xffff0000)
+ m_kbdmouse->ca_w(space, 0, data >> 24);
+ if (mem_mask & 0x0000ffff)
+ m_kbdmouse->da_w(space, 0, data >> 24);
+ break;
+ }
+ break;
+ case 1: // serial ports
+ switch (offset & 1)
+ {
+ case 0:
+ if (mem_mask & 0xffff0000)
+ m_uart->cb_w(space, 0, data >> 24);
+ if (mem_mask & 0x0000ffff)
+ m_uart->db_w(space, 0, data >> 24);
+ break;
+ case 1:
+ if (mem_mask & 0xffff0000)
+ m_uart->ca_w(space, 0, data >> 24);
+ if (mem_mask & 0x0000ffff)
+ m_uart->da_w(space, 0, data >> 24);
+ break;
+ }
+ break;
+ default:
+ logerror("sun4: write unknown type 1 space %08x (& %08x) asi 2, offset %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc());
+ }
+ break;
+
+ case 0: // IDPROM
+ default:
+ logerror("sun4: write %08x (& %08x) asi 2 to unknown register, offset %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc());
+ return;
+ }
+ break;
+
+ case 3: // segment map
+ offset <<= 2;
+ while (!(mem_mask & 1))
+ {
+ mem_mask >>= 1;
+ data >>= 1;
+ }
+ SEGMENT(offset) = data;
+ //m_segmap[m_context & 7][(offset >> 18) & 0xfff] &= ~(mem_mask >> 16);
+ //m_segmap[m_context & 7][(offset >> 18) & 0xfff] |= (data >> 16) & (mem_mask >> 16);
+ logerror("sun4: write m_segmap[%d][(%08x >> 18) & 0xfff = %03x] = %08x & %08x\n", m_context & 7, offset << 2, (offset >> 16) & 0xfff, data, mem_mask);
+ break;
+
+ case ASI_PAGE_MAP: // page map
{
- case 3: // context reg
- m_context = (UINT8)data;
- return;
-
- case 4: // system enable reg
- m_system_enable = (UINT8)data;
- return;
-
- case 8: // cache tags
- logerror("sun4: %08x to cache tags @ %x, PC = %x\n", data, offset, m_maincpu->pc());
- return;
+ logerror("sun4: write m_pagemap[(m_segmap[%d][(%08x >> 18) & 0xfff = %03x] = %08x << 6) | ((%08x >> 12) & 0x3f)]] = %08x & %08x\n", m_context & 7, offset << 2,
+ (offset >> 16) & 0xfff, SEGMENT(offset << 2), offset << 2, data, mem_mask);
+ COMBINE_DATA(&PAGE(offset << 2));
+ PAGE(offset << 2) &= 0xff00ffff;
+ break;
+ }
- case 9: // cache data
- logerror("sun4: %08x to cache data @ %x, PC = %x\n", data, offset, m_maincpu->pc());
- return;
+ case ASI_SUPER_DATA:
+ write_supervisor_data(offset << 2, data, mem_mask);
+ break;
- case 0: // IDPROM
- default:
- return;
- }
- }
- else if (asi < 8 || asi > 11)
- {
- logerror("sun4: %08x to asi %d byte offset %x, PC = %x\n", data, asi, offset << 2, m_maincpu->pc());
+ default:
+ logerror("sun4: write %08x (& %08x) to asi %d byte offset %x, PC = %x\n", data, mem_mask, asi, offset << 2, m_maincpu->pc());
+ break;
}
}
@@ -521,6 +744,21 @@ static MACHINE_CONFIG_START( sun4, sun4_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", MB86901, 16670000)
MCFG_DEVICE_ADDRESS_MAP(AS_PROGRAM, sun4_mem)
+
+ MCFG_SCC8530_ADD(SCC1_TAG, XTAL_4_9152MHz, 0, 0, 0, 0)
+ MCFG_SCC8530_ADD(SCC2_TAG, XTAL_4_9152MHz, 0, 0, 0, 0)
+ MCFG_Z80SCC_OUT_TXDA_CB(DEVWRITELINE(RS232A_TAG, rs232_port_device, write_txd))
+ MCFG_Z80SCC_OUT_TXDB_CB(DEVWRITELINE(RS232B_TAG, rs232_port_device, write_txd))
+
+ MCFG_RS232_PORT_ADD(RS232A_TAG, default_rs232_devices, nullptr)
+ MCFG_RS232_RXD_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, rxa_w))
+ MCFG_RS232_DCD_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, dcda_w))
+ MCFG_RS232_CTS_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, ctsa_w))
+
+ MCFG_RS232_PORT_ADD(RS232B_TAG, default_rs232_devices, nullptr)
+ MCFG_RS232_RXD_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, rxb_w))
+ MCFG_RS232_DCD_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, dcdb_w))
+ MCFG_RS232_CTS_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, ctsb_w))
MACHINE_CONFIG_END
/*
diff --git a/src/mame/includes/midzeus.h b/src/mame/includes/midzeus.h
index 7530b0b68f2..7a38879e142 100644
--- a/src/mame/includes/midzeus.h
+++ b/src/mame/includes/midzeus.h
@@ -29,7 +29,7 @@ public:
required_shared_ptr<UINT32> m_ram_base;
optional_shared_ptr<UINT32> m_linkram;
required_shared_ptr<UINT32> m_tms32031_control;
- required_shared_ptr<UINT32> m_zeusbase;
+ optional_shared_ptr<UINT32> m_zeusbase;
optional_device<timekeeper_device> m_m48t35;
required_device<cpu_device> m_maincpu;
required_device<screen_device> m_screen;
diff --git a/src/mame/includes/midzeus2.h b/src/mame/includes/midzeus2.h
index ff876ae1b94..2a3801a117f 100644
--- a/src/mame/includes/midzeus2.h
+++ b/src/mame/includes/midzeus2.h
@@ -5,13 +5,16 @@
Driver for Midway Zeus games
**************************************************************************/
+#include "video/zeus2.h"
class midzeus2_state : public midzeus_state
{
public:
midzeus2_state(const machine_config &mconfig, device_type type, const char *tag)
- : midzeus_state(mconfig, type, tag) { }
+ : midzeus_state(mconfig, type, tag), m_zeus(*this, "zeus2") { }
+ required_device<zeus2_device> m_zeus;
+ DECLARE_WRITE_LINE_MEMBER(zeus_irq);
DECLARE_VIDEO_START(midzeus2);
UINT32 screen_update_midzeus2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_READ32_MEMBER( zeus2_r );
diff --git a/src/mame/layout/dlair.lay b/src/mame/layout/dlair.lay
index 7b94c1f89cc..51c7096adbd 100644
--- a/src/mame/layout/dlair.lay
+++ b/src/mame/layout/dlair.lay
@@ -1,83 +1,51 @@
<?xml version="1.0"?>
<mamelayout version="2">
- <element name="digit" defstate="10">
- <led7seg>
- <color red="1.0" green="0.3" blue="0.0" />
- </led7seg>
- </element>
-
- <view name="Simple LEDs">
- <screen index="0">
- <bounds left="0" top="0" right="4" bottom="3" />
- </screen>
-
-
- <bezel name="digit0" element="digit">
- <bounds x="1.4" y="-1.5" width="0.2" height="0.3" />
- </bezel>
-
- <bezel name="digit1" element="digit">
- <bounds x="1.6" y="-1.5" width="0.2" height="0.3" />
- </bezel>
-
- <bezel name="digit2" element="digit">
- <bounds x="1.8" y="-1.5" width="0.2" height="0.3" />
- </bezel>
- <bezel name="digit3" element="digit">
- <bounds x="2.0" y="-1.5" width="0.2" height="0.3" />
- </bezel>
+<!-- define elements -->
- <bezel name="digit4" element="digit">
- <bounds x="2.2" y="-1.5" width="0.2" height="0.3" />
- </bezel>
-
- <bezel name="digit5" element="digit">
- <bounds x="2.4" y="-1.5" width="0.2" height="0.3" />
- </bezel>
-
-
- <bezel name="digit6" element="digit">
- <bounds x="1.9" y="-1.2" width="0.2" height="0.3" />
- </bezel>
-
-
- <bezel name="digit8" element="digit">
- <bounds x="1.4" y="-0.9" width="0.2" height="0.3" />
- </bezel>
+ <element name="digit" defstate="0">
+ <led7seg><color red="1.0" green="0.1" blue="0.15" /></led7seg>
+ </element>
- <bezel name="digit9" element="digit">
- <bounds x="1.6" y="-0.9" width="0.2" height="0.3" />
- </bezel>
+ <element name="text_p1"><text string="PLAYER 1 SCORE"><color red="0.9" green="0.8" blue="0.05" /></text></element>
+ <element name="text_p2"><text string="PLAYER 2 SCORE"><color red="0.9" green="0.8" blue="0.05" /></text></element>
+ <element name="text_lives"><text string="LIVES" align="1"><color red="0.9" green="0.8" blue="0.05" /></text></element>
+ <element name="text_credits"><text string="CREDITS" align="1"><color red="0.9" green="0.8" blue="0.05" /></text></element>
- <bezel name="digit10" element="digit">
- <bounds x="1.8" y="-0.9" width="0.2" height="0.3" />
- </bezel>
- <bezel name="digit11" element="digit">
- <bounds x="2.0" y="-0.9" width="0.2" height="0.3" />
- </bezel>
+<!-- build screen -->
- <bezel name="digit12" element="digit">
- <bounds x="2.2" y="-0.9" width="0.2" height="0.3" />
- </bezel>
+ <view name="Internal Layout">
+ <bounds x="0" y="0" width="4950" height="3000" />
+ <screen index="0">
+ <bounds x="0" y="0" width="4000" height="3000" />
+ </screen>
- <bezel name="digit13" element="digit">
- <bounds x="2.4" y="-0.9" width="0.2" height="0.3" />
- </bezel>
+ <bezel element="text_p1"><bounds x="4086" y="280" width="788" height="85" /></bezel>
+ <bezel name="digit0" element="digit"><bounds x="4086" y="380" width="118" height="165" /></bezel>
+ <bezel name="digit1" element="digit"><bounds x="4220" y="380" width="118" height="165" /></bezel>
+ <bezel name="digit2" element="digit"><bounds x="4354" y="380" width="118" height="165" /></bezel>
+ <bezel name="digit3" element="digit"><bounds x="4488" y="380" width="118" height="165" /></bezel>
+ <bezel name="digit4" element="digit"><bounds x="4622" y="380" width="118" height="165" /></bezel>
+ <bezel name="digit5" element="digit"><bounds x="4756" y="380" width="118" height="165" /></bezel>
+ <bezel element="text_lives"><bounds x="4580" y="639" width="400" height="85" /></bezel>
+ <bezel name="digit6" element="digit"><bounds x="4419" y="599" width="118" height="165" /></bezel>
- <bezel name="digit7" element="digit">
- <bounds x="1.9" y="-0.6" width="0.2" height="0.3" />
- </bezel>
+ <bezel element="text_p2"><bounds x="4086" y="783" width="788" height="85" /></bezel>
+ <bezel name="digit8" element="digit"><bounds x="4086" y="883" width="118" height="165" /></bezel>
+ <bezel name="digit9" element="digit"><bounds x="4220" y="883" width="118" height="165" /></bezel>
+ <bezel name="digit10" element="digit"><bounds x="4354" y="883" width="118" height="165" /></bezel>
+ <bezel name="digit11" element="digit"><bounds x="4488" y="883" width="118" height="165" /></bezel>
+ <bezel name="digit12" element="digit"><bounds x="4622" y="883" width="118" height="165" /></bezel>
+ <bezel name="digit13" element="digit"><bounds x="4756" y="883" width="118" height="165" /></bezel>
+ <bezel element="text_lives"><bounds x="4580" y="1144" width="400" height="85" /></bezel>
+ <bezel name="digit7" element="digit"><bounds x="4419" y="1104" width="118" height="165" /></bezel>
- <bezel name="digit14" element="digit">
- <bounds x="1.7" y="-0.3" width="0.2" height="0.3" />
- </bezel>
+ <bezel element="text_credits"><bounds x="4580" y="1413" width="400" height="85" /></bezel>
+ <bezel name="digit14" element="digit"><bounds x="4285" y="1383" width="118" height="165" /></bezel>
+ <bezel name="digit15" element="digit"><bounds x="4419" y="1383" width="118" height="165" /></bezel>
- <bezel name="digit15" element="digit">
- <bounds x="1.9" y="-0.3" width="0.2" height="0.3" />
- </bezel>
</view>
</mamelayout>