diff --git a/hash/snes.xml b/hash/snes.xml
index cc6faa06efa..e6cb40cff2b 100644
--- a/hash/snes.xml
+++ b/hash/snes.xml
@@ -3692,7 +3692,7 @@ Beyond that last category are the roms waiting to be classified.
-
+
diff --git a/nl_examples/vs_cs.c b/nl_examples/vs_cs.c
new file mode 100644
index 00000000000..4e6bb9615fe
--- /dev/null
+++ b/nl_examples/vs_cs.c
@@ -0,0 +1,50 @@
+/*
+ * vs_cs.c
+ *
+ * Voltage and current source test
+ *
+ */
+
+#include "netlist/devices/net_lib.h"
+
+NETLIST_START(rc)
+
+ /*
+ * delay circuit
+ *
+ */
+
+ /* Standard stuff */
+
+ SOLVER(Solver, 48000)
+ PARAM(Solver.ACCURACY, 1e-6)
+ CLOCK(clk, 20000)
+
+ /* Voltage source. Inner resistance will make clock visible */
+
+ RES(R1, 1000)
+ VS(VS1, 1)
+ NET_C(R1.1, clk)
+ NET_C(R1.2, VS1.P)
+ NET_C(GND, VS1.N)
+
+ /* Current source. Current flows from "+" to "-", thus for a source we
+ * need negative current
+ */
+
+ RES(R2, 1000)
+ RES(R3, 1000)
+ CS(CS1, -0.001)
+ NET_C(CS1.P, R2.1)
+ NET_C(R2.2, R3.1)
+ NET_C(GND, CS1.N, R3.2)
+
+ CAP(C1, CAP_U(1))
+ NET_C(C1.1, R3.1)
+ NET_C(C1.2, R3.2)
+
+
+ LOG(tt, VS1.P)
+ LOG(tx, R2.2)
+
+NETLIST_END()
diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua
index 1c49acd213e..63cc4f920f8 100644
--- a/scripts/target/mame/arcade.lua
+++ b/scripts/target/mame/arcade.lua
@@ -2584,7 +2584,6 @@ files {
MAME_DIR .. "src/mame/machine/n64.c",
MAME_DIR .. "src/mame/video/n64.c",
MAME_DIR .. "src/mame/video/rdpblend.c",
- MAME_DIR .. "src/mame/video/rdpspn16.c",
MAME_DIR .. "src/mame/video/rdptpipe.c",
MAME_DIR .. "src/mame/drivers/hanaawas.c",
MAME_DIR .. "src/mame/video/hanaawas.c",
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index 93b845d4329..223700a25b5 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -755,6 +755,7 @@ function linkProjects_mame_mess(_target, _subtarget)
"memotech",
"mgu",
"microkey",
+ "microsoft",
"mit",
"mits",
"mitsubishi",
@@ -940,7 +941,6 @@ files {
MAME_DIR .. "src/mame/video/n64.c",
MAME_DIR .. "src/mame/video/rdpblend.c",
MAME_DIR .. "src/mame/video/rdptpipe.c",
- MAME_DIR .. "src/mame/video/rdpspn16.c",
MAME_DIR .. "src/mame/machine/megadriv.c",
MAME_DIR .. "src/mame/drivers/naomi.c",
MAME_DIR .. "src/mame/machine/awboard.c",
@@ -1751,6 +1751,11 @@ files {
MAME_DIR .. "src/mess/video/primo.c",
}
+createMESSProjects(_target, _subtarget, "microsoft")
+files {
+ MAME_DIR .. "src/mess/drivers/xbox.c",
+}
+
createMESSProjects(_target, _subtarget, "mit")
files {
MAME_DIR .. "src/mess/drivers/tx0.c",
@@ -1892,6 +1897,7 @@ createMESSProjects(_target, _subtarget, "olivetti")
files {
MAME_DIR .. "src/mess/drivers/m20.c",
MAME_DIR .. "src/mess/machine/m20_kbd.c",
+ MAME_DIR .. "src/mess/machine/m20_8086.c",
MAME_DIR .. "src/mess/drivers/m24.c",
MAME_DIR .. "src/mess/machine/m24_kbd.c",
MAME_DIR .. "src/mess/machine/m24_z8000.c"
diff --git a/src/emu/cpu/hmcs40/hmcs40d.c b/src/emu/cpu/hmcs40/hmcs40d.c
index 4ab55866d5d..8bd9ce4e043 100644
--- a/src/emu/cpu/hmcs40/hmcs40d.c
+++ b/src/emu/cpu/hmcs40/hmcs40d.c
@@ -82,7 +82,7 @@ static const UINT32 s_flags[] =
};
// next program counter in sequence (relative)
-static const INT16 s_next_pc[0x40] =
+static const INT8 s_next_pc[0x40] =
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32+0x40,
diff --git a/src/emu/cpu/rsp/rsp.h b/src/emu/cpu/rsp/rsp.h
index fce4635a359..6bc588c2f01 100644
--- a/src/emu/cpu/rsp/rsp.h
+++ b/src/emu/cpu/rsp/rsp.h
@@ -163,6 +163,8 @@ public:
void ccfunc_sp_set_status_cb();
void ccfunc_unimplemented();
+ UINT8* get_dmem() { return m_dmem8; }
+
protected:
// device-level overrides
virtual void device_start();
diff --git a/src/emu/cpu/rsp/rspcp2.c b/src/emu/cpu/rsp/rspcp2.c
index df55952ab4c..0d00e635d69 100644
--- a/src/emu/cpu/rsp/rspcp2.c
+++ b/src/emu/cpu/rsp/rspcp2.c
@@ -178,10 +178,58 @@ const rsp_cop2::vec_helpers_t rsp_cop2::m_vec_helpers = {
{ 0x0d0e, 0x030c, 0x0102, 0x0700, 0x0506, 0x0b04, 0x090a, 0x0f08 },
{ 0x0c0d, 0x0203, 0x0001, 0x0607, 0x0405, 0x0c0b, 0x0809, 0x0e0f },
{ 0x030c, 0x0102, 0x0700, 0x0506, 0x0b04, 0x090a, 0x0f08, 0x0d0e }
+ },
+ { // qr_lut
+ { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff },
+ { 0xff00, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff },
+ { 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff },
+ { 0x0000, 0xff00, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff },
+
+ { 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff},
+ { 0x0000, 0x0000, 0xff00, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff },
+ { 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff },
+ { 0x0000, 0x0000, 0x0000, 0xff00, 0xffff, 0xffff, 0xffff, 0xffff },
+
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0xff00, 0xffff, 0xffff, 0xffff },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff00, 0xffff, 0xffff },
+
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff00, 0xffff },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff },
+ { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff00 }
+ },
+ { // bdls_lut - mask to denote which part of the vector to load/store.
+ { 0x00ff, 0x0000, 0x0000, 0x0000 }, // B
+ { 0xffff, 0x0000, 0x0000, 0x0000 }, // S
+ { 0xffff, 0xffff, 0x0000, 0x0000 }, // L
+ { 0xffff, 0xffff, 0xffff, 0xffff } // D
}
};
#ifndef __SSSE3__
+// TODO: Highly optimized. More of a stopgap measure.
+static inline rsp_vec_t sse2_pshufb(rsp_vec_t v, const UINT16 *keys)
+{
+ UINT8 dest[16];
+ UINT8 temp[16];
+
+ _mm_storeu_si128((rsp_vec_t *) temp, v);
+
+ for (UINT32 j = 0; j < 8; j++)
+ {
+ UINT16 key = keys[j];
+ UINT8 key_hi = key >> 8;
+ UINT8 key_lo = key >> 0;
+
+ dest[(j << 1) + 1] = key_hi == 0x80 ? 0x00 : temp[key_hi];
+ dest[(j << 1) + 0] = key_lo == 0x80 ? 0x00 : temp[key_lo];
+ }
+
+ return _mm_loadu_si128((rsp_vec_t *) dest);
+}
+
rsp_vec_t rsp_cop2::vec_load_and_shuffle_operand(const UINT16* src, UINT32 element)
{
if (element >= 8) // element => 0w ... 7w
@@ -234,6 +282,292 @@ rsp_vec_t rsp_cop2::vec_load_and_shuffle_operand(const UINT16* src, UINT32 eleme
return _mm_shuffle_epi8(operand, key);
}
#endif
+//
+// SSSE3+ accelerated loads for group I. Byteswap big-endian to 2-byte
+// little-endian vector. Start at vector element offset, discarding any
+// wraparound as necessary.
+//
+// TODO: Reverse-engineer what happens when loads to vector elements must
+// wraparound. Do we just discard the data, as below, or does the
+// data effectively get rotated around the edge of the vector?
+//
+void rsp_cop2::vec_load_group1(UINT32 addr, UINT32 element, UINT16 *regp, rsp_vec_t reg, rsp_vec_t dqm)
+{
+ UINT32 offset = addr & 0x7;
+ UINT32 ror = offset - element;
+
+ // Always load in 8-byte chunks to emulate wraparound.
+ rsp_vec_t data;
+ if (offset) {
+ UINT32 aligned_addr_lo = addr & ~0x7;
+ UINT32 aligned_addr_hi = (aligned_addr_lo + 8) & 0xFFF;
+
+ data = _mm_loadl_epi64((rsp_vec_t *) (m_rsp.get_dmem() + aligned_addr_lo));
+ rsp_vec_t temp = _mm_loadl_epi64((rsp_vec_t *) (m_rsp.get_dmem() + aligned_addr_hi));
+ data = _mm_unpacklo_epi64(data, temp);
+ }
+ else
+ {
+ data = _mm_loadl_epi64((rsp_vec_t *) (m_rsp.get_dmem() + addr));
+ }
+
+ // Shift the DQM up to the point where we mux in the data.
+#ifndef __SSSE3__
+ dqm = sse2_pshufb(dqm, m_vec_helpers.sll_b2l_keys[element]);
+#else
+ rsp_vec_t ekey = _mm_load_si128((rsp_vec_t *) (m_vec_helpers.sll_b2l_keys[element]));
+ dqm = _mm_shuffle_epi8(dqm, ekey);
+#endif
+
+ // Align the data to the DQM so we can mask it in.
+#ifndef __SSSE3__
+ data = sse2_pshufb(data, m_vec_helpers.ror_b2l_keys[ror & 0xF]);
+#else
+ ekey = _mm_load_si128((rsp_vec_t *) (m_vec_helpers.ror_b2l_keys[ror & 0xF]));
+ data = _mm_shuffle_epi8(data, ekey);
+#endif
+
+ // Mask and mux in the data.
+#ifdef __SSE4_1__
+ reg = _mm_blendv_epi8(reg, data, dqm);
+#else
+ data = _mm_and_si128(dqm, data);
+ reg = _mm_andnot_si128(dqm, reg);
+ reg = _mm_or_si128(data, reg);
+#endif
+
+ _mm_store_si128((rsp_vec_t *) regp, reg);
+}
+
+//
+// SSSE3+ accelerated loads for group II.
+//
+// TODO: Reverse-engineer what happens when loads to vector elements must
+// wraparound. Do we just discard the data, as below, or does the
+// data effectively get rotated around the edge of the vector?
+//
+// TODO: Reverse-engineer what happens when element != 0.
+//
+void rsp_cop2::vec_load_group2(UINT32 addr, UINT32 element, UINT16 *regp, rsp_vec_t reg, rsp_vec_t dqm, rsp_mem_request_type request_type) {
+ UINT32 offset = addr & 0x7;
+ rsp_vec_t data;
+
+ // Always load in 8-byte chunks to emulate wraparound.
+ if (offset) {
+ UINT32 aligned_addr_lo = addr & ~0x7;
+ UINT32 aligned_addr_hi = (aligned_addr_lo + 8) & 0xFFF;
+ UINT64 datalow, datahigh;
+
+ memcpy(&datalow, m_rsp.get_dmem() + aligned_addr_lo, sizeof(datalow));
+ memcpy(&datahigh, m_rsp.get_dmem() + aligned_addr_hi, sizeof(datahigh));
+
+ // TODO: Test for endian issues?
+ datahigh >>= ((8 - offset) << 3);
+ datalow <<= (offset << 3);
+ datalow = datahigh | datalow;
+
+ data = _mm_loadl_epi64((rsp_vec_t *) &datalow);
+ }
+ else
+ {
+ data = _mm_loadl_epi64((rsp_vec_t *) (m_rsp.get_dmem() + addr));
+ }
+
+ // "Unpack" the data.
+ data = _mm_unpacklo_epi8(_mm_setzero_si128(), data);
+
+ if (request_type != RSP_MEM_REQUEST_PACK)
+ {
+ data = _mm_srli_epi16(data, 1);
+ }
+
+ _mm_store_si128((rsp_vec_t *) regp, data);
+}
+
+//
+// SSSE3+ accelerated loads for group IV. Byteswap big-endian to 2-byte
+// little-endian vector. Stop loading at quadword boundaries.
+//
+// TODO: Reverse-engineer what happens when loads from vector elements
+// must wraparound (i.e., the address offset is small, starting
+// element is large).
+//
+void rsp_cop2::vec_load_group4(UINT32 addr, UINT32 element, UINT16 *regp, rsp_vec_t reg, rsp_vec_t dqm, rsp_mem_request_type request_type)
+{
+ UINT32 aligned_addr = addr & 0xFF0;
+ UINT32 offset = addr & 0xF;
+
+ rsp_vec_t data = _mm_load_si128((rsp_vec_t *) (m_rsp.get_dmem() + aligned_addr));
+
+ UINT32 ror;
+ if (request_type == RSP_MEM_REQUEST_QUAD)
+ {
+ ror = 16 - element + offset;
+ }
+ else
+ {
+ // TODO: How is this adjusted for LRV when e != 0?
+ dqm = _mm_cmpeq_epi8(_mm_setzero_si128(), dqm);
+ ror = 16 - offset;
+ }
+
+#ifndef __SSSE3__
+ data = sse2_pshufb(data, m_vec_helpers.ror_b2l_keys[ror & 0xF]);
+ dqm = sse2_pshufb(dqm, m_vec_helpers.ror_b2l_keys[ror & 0xF]);
+#else
+ rsp_vec_t dkey = _mm_load_si128((rsp_vec_t *) (m_vec_helpers.ror_b2l_keys[ror & 0xF]));
+ data = _mm_shuffle_epi8(data, dkey);
+ dqm = _mm_shuffle_epi8(dqm, dkey);
+#endif
+
+ // Mask and mux in the data.
+#ifdef __SSE4_1__
+ data = _mm_blendv_epi8(reg, data, dqm);
+#else
+ data = _mm_and_si128(dqm, data);
+ reg = _mm_andnot_si128(dqm, reg);
+ data = _mm_or_si128(data, reg);
+#endif
+
+ _mm_store_si128((rsp_vec_t *) regp, data);
+}
+
+//
+// SSE3+ accelerated stores for group I. Byteswap 2-byte little-endian
+// vector back to big-endian. Start at vector element offset, wrapping
+// around the edge of the vector as necessary.
+//
+// TODO: Reverse-engineer what happens when stores from vector elements
+// must wraparound. Do we just stop storing the data, or do we
+// continue storing from the front of the vector, as below?
+//
+void rsp_cop2::vec_store_group1(UINT32 addr, UINT32 element, UINT16 *regp, rsp_vec_t reg, rsp_vec_t dqm)
+{
+ UINT32 offset = addr & 0x7;
+ UINT32 ror = element - offset;
+
+ // Shift the DQM up to the point where we mux in the data.
+#ifndef __SSSE3__
+ dqm = sse2_pshufb(dqm, m_vec_helpers.sll_l2b_keys[offset]);
+#else
+ __m182i ekey = _mm_load_si128((rsp_vec_t *) (m_vec_helpers.sll_l2b_keys[offset]));
+ dqm = _mm_shuffle_epi8(dqm, ekey);
+#endif
+
+ // Rotate the reg to align with the DQM.
+#ifndef __SSSE3__
+ reg = sse2_pshufb(reg, m_vec_helpers.ror_l2b_keys[ror & 0xF]);
+#else
+ ekey = _mm_load_si128((rsp_vec_t *) (m_vec_helpers.ror_l2b_keys[ror & 0xF]));
+ reg = _mm_shuffle_epi8(reg, ekey);
+#endif
+
+ // Always load in 8-byte chunks to emulate wraparound.
+ rsp_vec_t data;
+ if (offset)
+ {
+ UINT32 aligned_addr_lo = addr & ~0x7;
+ UINT32 aligned_addr_hi = (aligned_addr_lo + 8) & 0xFFF;
+
+ data = _mm_loadl_epi64((rsp_vec_t *) (m_rsp.get_dmem() + aligned_addr_lo));
+ rsp_vec_t temp = _mm_loadl_epi64((rsp_vec_t *) (m_rsp.get_dmem() + aligned_addr_hi));
+ data = _mm_unpacklo_epi64(data, temp);
+
+ // Mask and mux in the data.
+#ifdef __SSE4_1__
+ data = _mm_blendv_epi8(data, reg, dqm);
+#else
+ data = _mm_andnot_si128(dqm, data);
+ reg = _mm_and_si128(dqm, reg);
+ data = _mm_or_si128(data, reg);
+#endif
+
+ _mm_storel_epi64((rsp_vec_t *) (m_rsp.get_dmem() + aligned_addr_lo), data);
+
+ data = _mm_srli_si128(data, 8);
+ _mm_storel_epi64((rsp_vec_t *) (m_rsp.get_dmem() + aligned_addr_hi), data);
+ }
+ else
+ {
+ data = _mm_loadl_epi64((rsp_vec_t *) (m_rsp.get_dmem() + addr));
+
+ // Mask and mux in the data.
+#ifdef __SSE4_1__
+ data = _mm_blendv_epi8(data, reg, dqm);
+#else
+ data = _mm_andnot_si128(dqm, data);
+ reg = _mm_and_si128(dqm, reg);
+ data = _mm_or_si128(data, reg);
+#endif
+
+ _mm_storel_epi64((rsp_vec_t *) (m_rsp.get_dmem() + addr), data);
+ }
+}
+
+//
+// SSE3+ accelerated stores for group II. Byteswap 2-byte little-endian
+// vector back to big-endian. Start at vector element offset, wrapping
+// around the edge of the vector as necessary.
+//
+// TODO: Reverse-engineer what happens when stores from vector elements
+// must wraparound. Do we just stop storing the data, or do we
+// continue storing from the front of the vector, as below?
+//
+// TODO: Reverse-engineer what happens when element != 0.
+//
+void rsp_cop2::vec_store_group2(UINT32 addr, UINT32 element, UINT16 *regp, rsp_vec_t reg, rsp_vec_t dqm, rsp_mem_request_type request_type) {
+ // "Pack" the data.
+ if (request_type != RSP_MEM_REQUEST_PACK)
+ {
+ reg = _mm_slli_epi16(reg, 1);
+ }
+
+ reg = _mm_srai_epi16(reg, 8);
+ reg = _mm_packs_epi16(reg, reg);
+
+ // TODO: Always store in 8-byte chunks to emulate wraparound.
+ _mm_storel_epi64((rsp_vec_t *) (m_rsp.get_dmem() + addr), reg);
+}
+
+//
+// SSE3+ accelerated stores for group IV. Byteswap 2-byte little-endian
+// vector back to big-endian. Stop storing at quadword boundaries.
+//
+void rsp_cop2::vec_store_group4(UINT32 addr, UINT32 element, UINT16 *regp, rsp_vec_t reg, rsp_vec_t dqm, rsp_mem_request_type request_type) {
+ UINT32 aligned_addr = addr & 0xFF0;
+ UINT32 offset = addr & 0xF;
+ UINT32 rol = offset;
+
+ rsp_vec_t data = _mm_load_si128((rsp_vec_t *) (m_rsp.get_dmem() + aligned_addr));
+
+ if (request_type == RSP_MEM_REQUEST_QUAD)
+ {
+ rol -= element;
+ }
+ else
+ {
+ // TODO: How is this adjusted for SRV when e != 0?
+ dqm = _mm_cmpeq_epi8(_mm_setzero_si128(), dqm);
+ }
+
+#ifndef __SSSE3__
+ reg = sse2_pshufb(reg, m_vec_helpers.rol_l2b_keys[rol & 0xF]);
+#else
+ rsp_vec_t ekey = _mm_load_si128((rsp_vec_t *) (m_vec_helpers.rol_l2b_keys[rol & 0xF]));
+ reg = _mm_shuffle_epi8(reg, ekey);
+#endif
+
+ // Mask and mux out the data, write.
+#ifdef __SSE4_1__
+ data = _mm_blendv_epi8(data, reg, dqm);
+#else
+ reg = _mm_and_si128(dqm, reg);
+ data = _mm_andnot_si128(dqm, data);
+ data = _mm_or_si128(data, reg);
+#endif
+
+ _mm_store_si128((rsp_vec_t *) (m_rsp.get_dmem() + aligned_addr), data);
+}
#endif
extern offs_t rsp_dasm_one(char *buffer, offs_t pc, UINT32 op);
@@ -498,14 +832,16 @@ void rsp_cop2::state_string_export(const int index, std::string &str)
void rsp_cop2::handle_lwc2(UINT32 op)
{
+ int base = (op >> 21) & 0x1f;
+#if !USE_SIMD
int i, end;
UINT32 ea;
int dest = (op >> 16) & 0x1f;
- int base = (op >> 21) & 0x1f;
int index = (op >> 7) & 0xf;
int offset = (op & 0x7f);
if (offset & 0x40)
offset |= 0xffffffc0;
+#endif
switch ((op >> 11) & 0x1f)
{
@@ -518,8 +854,12 @@ void rsp_cop2::handle_lwc2(UINT32 op)
//
// Load 1 byte to vector byte index
+#if USE_SIMD
+ vec_lbdlsv_sbdlsv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + offset : offset;
VREG_B(dest, index) = m_rsp.READ8(ea);
+#endif
break;
}
case 0x01: /* LSV */
@@ -531,6 +871,9 @@ void rsp_cop2::handle_lwc2(UINT32 op)
//
// Loads 2 bytes starting from vector byte index
+#if USE_SIMD
+ vec_lbdlsv_sbdlsv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 2) : (offset * 2);
end = index + 2;
@@ -540,6 +883,7 @@ void rsp_cop2::handle_lwc2(UINT32 op)
VREG_B(dest, i) = m_rsp.READ8(ea);
ea++;
}
+#endif
break;
}
case 0x02: /* LLV */
@@ -551,6 +895,9 @@ void rsp_cop2::handle_lwc2(UINT32 op)
//
// Loads 4 bytes starting from vector byte index
+#if USE_SIMD
+ vec_lbdlsv_sbdlsv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 4) : (offset * 4);
end = index + 4;
@@ -560,6 +907,7 @@ void rsp_cop2::handle_lwc2(UINT32 op)
VREG_B(dest, i) = m_rsp.READ8(ea);
ea++;
}
+#endif
break;
}
case 0x03: /* LDV */
@@ -571,6 +919,9 @@ void rsp_cop2::handle_lwc2(UINT32 op)
//
// Loads 8 bytes starting from vector byte index
+#if USE_SIMD
+ vec_lbdlsv_sbdlsv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 8) : (offset * 8);
end = index + 8;
@@ -580,6 +931,7 @@ void rsp_cop2::handle_lwc2(UINT32 op)
VREG_B(dest, i) = m_rsp.READ8(ea);
ea++;
}
+#endif
break;
}
case 0x04: /* LQV */
@@ -591,6 +943,9 @@ void rsp_cop2::handle_lwc2(UINT32 op)
//
// Loads up to 16 bytes starting from vector byte index
+#if USE_SIMD
+ vec_lqrv_sqrv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 16) : (offset * 16);
end = index + (16 - (ea & 0xf));
@@ -601,6 +956,7 @@ void rsp_cop2::handle_lwc2(UINT32 op)
VREG_B(dest, i) = m_rsp.READ8(ea);
ea++;
}
+#endif
break;
}
case 0x05: /* LRV */
@@ -612,6 +968,9 @@ void rsp_cop2::handle_lwc2(UINT32 op)
//
// Stores up to 16 bytes starting from right side until 16-byte boundary
+#if USE_SIMD
+ vec_lqrv_sqrv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 16) : (offset * 16);
index = 16 - ((ea & 0xf) - index);
@@ -623,6 +982,7 @@ void rsp_cop2::handle_lwc2(UINT32 op)
VREG_B(dest, i) = m_rsp.READ8(ea);
ea++;
}
+#endif
break;
}
case 0x06: /* LPV */
@@ -634,12 +994,16 @@ void rsp_cop2::handle_lwc2(UINT32 op)
//
// Loads a byte as the upper 8 bits of each element
+#if USE_SIMD
+ vec_lfhpuv_sfhpuv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 8) : (offset * 8);
for (i=0; i < 8; i++)
{
VREG_S(dest, i) = m_rsp.READ8(ea + (((16-index) + i) & 0xf)) << 8;
}
+#endif
break;
}
case 0x07: /* LUV */
@@ -651,12 +1015,16 @@ void rsp_cop2::handle_lwc2(UINT32 op)
//
// Loads a byte as the bits 14-7 of each element
+#if USE_SIMD
+ vec_lfhpuv_sfhpuv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 8) : (offset * 8);
for (i=0; i < 8; i++)
{
VREG_S(dest, i) = m_rsp.READ8(ea + (((16-index) + i) & 0xf)) << 7;
}
+#endif
break;
}
case 0x08: /* LHV */
@@ -668,12 +1036,16 @@ void rsp_cop2::handle_lwc2(UINT32 op)
//
// Loads a byte as the bits 14-7 of each element, with 2-byte stride
+#if USE_SIMD
+ vec_lfhpuv_sfhpuv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 16) : (offset * 16);
for (i=0; i < 8; i++)
{
VREG_S(dest, i) = m_rsp.READ8(ea + (((16-index) + (i<<1)) & 0xf)) << 7;
}
+#endif
break;
}
case 0x09: /* LFV */
@@ -685,6 +1057,9 @@ void rsp_cop2::handle_lwc2(UINT32 op)
//
// Loads a byte as the bits 14-7 of upper or lower quad, with 4-byte stride
+#if USE_SIMD
+ vec_lfhpuv_sfhpuv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 16) : (offset * 16);
// not sure what happens if 16-byte boundary is crossed...
@@ -696,6 +1071,7 @@ void rsp_cop2::handle_lwc2(UINT32 op)
VREG_S(dest, i) = m_rsp.READ8(ea) << 7;
ea += 4;
}
+#endif
break;
}
case 0x0a: /* LWV */
@@ -708,6 +1084,8 @@ void rsp_cop2::handle_lwc2(UINT32 op)
// Loads the full 128-bit vector starting from vector byte index and wrapping to index 0
// after byte index 15
+#if USE_SIMD
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 16) : (offset * 16);
end = (16 - index) + 16;
@@ -717,6 +1095,7 @@ void rsp_cop2::handle_lwc2(UINT32 op)
VREG_B(dest, i & 0xf) = m_rsp.READ8(ea);
ea += 4;
}
+#endif
break;
}
case 0x0b: /* LTV */
@@ -730,6 +1109,8 @@ void rsp_cop2::handle_lwc2(UINT32 op)
// FIXME: has a small problem with odd indices
+#if USE_SIMD
+#else
int element;
int vs = dest;
int ve = dest + 8;
@@ -751,6 +1132,7 @@ void rsp_cop2::handle_lwc2(UINT32 op)
ea += 2;
}
+#endif
break;
}
@@ -769,15 +1151,17 @@ void rsp_cop2::handle_lwc2(UINT32 op)
void rsp_cop2::handle_swc2(UINT32 op)
{
+ int base = (op >> 21) & 0x1f;
+#if !USE_SIMD
int i, end;
int eaoffset;
UINT32 ea;
int dest = (op >> 16) & 0x1f;
- int base = (op >> 21) & 0x1f;
int index = (op >> 7) & 0xf;
int offset = (op & 0x7f);
if (offset & 0x40)
offset |= 0xffffffc0;
+#endif
switch ((op >> 11) & 0x1f)
{
@@ -790,8 +1174,12 @@ void rsp_cop2::handle_swc2(UINT32 op)
//
// Stores 1 byte from vector byte index
+#if USE_SIMD
+ vec_lbdlsv_sbdlsv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + offset : offset;
m_rsp.WRITE8(ea, VREG_B(dest, index));
+#endif
break;
}
case 0x01: /* SSV */
@@ -803,6 +1191,9 @@ void rsp_cop2::handle_swc2(UINT32 op)
//
// Stores 2 bytes starting from vector byte index
+#if USE_SIMD
+ vec_lbdlsv_sbdlsv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 2) : (offset * 2);
end = index + 2;
@@ -812,6 +1203,7 @@ void rsp_cop2::handle_swc2(UINT32 op)
m_rsp.WRITE8(ea, VREG_B(dest, i));
ea++;
}
+#endif
break;
}
case 0x02: /* SLV */
@@ -823,6 +1215,9 @@ void rsp_cop2::handle_swc2(UINT32 op)
//
// Stores 4 bytes starting from vector byte index
+#if USE_SIMD
+ vec_lbdlsv_sbdlsv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 4) : (offset * 4);
end = index + 4;
@@ -832,6 +1227,7 @@ void rsp_cop2::handle_swc2(UINT32 op)
m_rsp.WRITE8(ea, VREG_B(dest, i));
ea++;
}
+#endif
break;
}
case 0x03: /* SDV */
@@ -843,6 +1239,9 @@ void rsp_cop2::handle_swc2(UINT32 op)
//
// Stores 8 bytes starting from vector byte index
+#if USE_SIMD
+ vec_lbdlsv_sbdlsv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 8) : (offset * 8);
end = index + 8;
@@ -852,6 +1251,7 @@ void rsp_cop2::handle_swc2(UINT32 op)
m_rsp.WRITE8(ea, VREG_B(dest, i));
ea++;
}
+#endif
break;
}
case 0x04: /* SQV */
@@ -863,6 +1263,9 @@ void rsp_cop2::handle_swc2(UINT32 op)
//
// Stores up to 16 bytes starting from vector byte index until 16-byte boundary
+#if USE_SIMD
+ vec_lqrv_sqrv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 16) : (offset * 16);
end = index + (16 - (ea & 0xf));
@@ -872,6 +1275,7 @@ void rsp_cop2::handle_swc2(UINT32 op)
m_rsp.WRITE8(ea, VREG_B(dest, i & 0xf));
ea++;
}
+#endif
break;
}
case 0x05: /* SRV */
@@ -883,6 +1287,9 @@ void rsp_cop2::handle_swc2(UINT32 op)
//
// Stores up to 16 bytes starting from right side until 16-byte boundary
+#if USE_SIMD
+ vec_lqrv_sqrv(op, m_rsp.m_rsp_state->r[base]);
+#else
int o;
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 16) : (offset * 16);
@@ -895,6 +1302,7 @@ void rsp_cop2::handle_swc2(UINT32 op)
m_rsp.WRITE8(ea, VREG_B(dest, ((i + o) & 0xf)));
ea++;
}
+#endif
break;
}
case 0x06: /* SPV */
@@ -906,6 +1314,9 @@ void rsp_cop2::handle_swc2(UINT32 op)
//
// Stores upper 8 bits of each element
+#if USE_SIMD
+ vec_lfhpuv_sfhpuv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 8) : (offset * 8);
end = index + 8;
@@ -921,6 +1332,7 @@ void rsp_cop2::handle_swc2(UINT32 op)
}
ea++;
}
+#endif
break;
}
case 0x07: /* SUV */
@@ -932,6 +1344,9 @@ void rsp_cop2::handle_swc2(UINT32 op)
//
// Stores bits 14-7 of each element
+#if USE_SIMD
+ vec_lfhpuv_sfhpuv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 8) : (offset * 8);
end = index + 8;
@@ -947,6 +1362,7 @@ void rsp_cop2::handle_swc2(UINT32 op)
}
ea++;
}
+#endif
break;
}
case 0x08: /* SHV */
@@ -958,6 +1374,9 @@ void rsp_cop2::handle_swc2(UINT32 op)
//
// Stores bits 14-7 of each element, with 2-byte stride
+#if USE_SIMD
+ vec_lfhpuv_sfhpuv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 16) : (offset * 16);
for (i=0; i < 8; i++)
@@ -968,6 +1387,7 @@ void rsp_cop2::handle_swc2(UINT32 op)
m_rsp.WRITE8(ea, d);
ea += 2;
}
+#endif
break;
}
case 0x09: /* SFV */
@@ -981,6 +1401,9 @@ void rsp_cop2::handle_swc2(UINT32 op)
// FIXME: only works for index 0 and index 8
+#if USE_SIMD
+ vec_lfhpuv_sfhpuv(op, m_rsp.m_rsp_state->r[base]);
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 16) : (offset * 16);
eaoffset = ea & 0xf;
@@ -993,6 +1416,7 @@ void rsp_cop2::handle_swc2(UINT32 op)
m_rsp.WRITE8(ea + (eaoffset & 0xf), VREG_S(dest, i) >> 7);
eaoffset += 4;
}
+#endif
break;
}
case 0x0a: /* SWV */
@@ -1005,6 +1429,8 @@ void rsp_cop2::handle_swc2(UINT32 op)
// Stores the full 128-bit vector starting from vector byte index and wrapping to index 0
// after byte index 15
+#if USE_SIMD
+#else
ea = (base) ? m_rsp.m_rsp_state->r[base] + (offset * 16) : (offset * 16);
eaoffset = ea & 0xf;
@@ -1017,6 +1443,7 @@ void rsp_cop2::handle_swc2(UINT32 op)
m_rsp.WRITE8(ea + (eaoffset & 0xf), VREG_B(dest, i & 0xf));
eaoffset++;
}
+#endif
break;
}
case 0x0b: /* STV */
@@ -1028,6 +1455,8 @@ void rsp_cop2::handle_swc2(UINT32 op)
//
// Stores one element from maximum of 8 vectors, while incrementing element index
+#if USE_SIMD
+#else
int element;
int vs = dest;
int ve = dest + 8;
@@ -1047,6 +1476,7 @@ void rsp_cop2::handle_swc2(UINT32 op)
eaoffset += 2;
element++;
}
+#endif
break;
}
@@ -1981,16 +2411,21 @@ void rsp_cop2::handle_vector_ops(UINT32 op)
// Stores high, middle or low slice of accumulator to destination vector
#if USE_SIMD
+ UINT16 *acc = m_acc.s;
switch (EL)
{
case 8:
+ m_v[VDREG].v = read_acc_hi(acc);
break;
case 9:
+ m_v[VDREG].v = read_acc_mid(acc);
break;
case 10:
+ m_v[VDREG].v = read_acc_lo(acc);
break;
default:
+ m_v[VDREG].v = _mm_setzero_si128();
break;
}
#else
diff --git a/src/emu/cpu/rsp/rspcp2.h b/src/emu/cpu/rsp/rspcp2.h
index 2e09cd587f4..6f14d110a68 100644
--- a/src/emu/cpu/rsp/rspcp2.h
+++ b/src/emu/cpu/rsp/rspcp2.h
@@ -199,6 +199,23 @@ protected:
RSP_ACC_HI = 0,
};
+ enum rsp_mem_request_type {
+ RSP_MEM_REQUEST_NONE,
+ RSP_MEM_REQUEST_INT_MEM,
+ RSP_MEM_REQUEST_VECTOR,
+ RSP_MEM_REQUEST_FOURTH,
+ RSP_MEM_REQUEST_HALF,
+ RSP_MEM_REQUEST_PACK,
+ RSP_MEM_REQUEST_QUAD,
+ RSP_MEM_REQUEST_REST,
+ RSP_MEM_REQUEST_UPACK
+ };
+
+ union aligned_rsp_1vect_t {
+ rsp_vec_t __align;
+ UINT16 s[8];
+ };
+
union aligned_rsp_2vect_t {
rsp_vec_t __align[2];
UINT16 s[16];
@@ -209,6 +226,7 @@ protected:
UINT16 s[24];
};
+ aligned_rsp_1vect_t m_vdqm;
aligned_rsp_2vect_t m_flags[3];
aligned_rsp_3vect_t m_acc;
UINT32 m_dp_flag;
@@ -225,11 +243,16 @@ protected:
const UINT16 ror_b2l_keys[16][8];
const UINT16 rol_l2b_keys[16][8];
const UINT16 ror_l2b_keys[16][8];
+ const UINT16 qr_lut[16][8];
+ const UINT16 bdls_lut[4][4];
} vec_helpers_t;
static const vec_helpers_t m_vec_helpers;
rsp_vec_t vec_load_and_shuffle_operand(const UINT16* src, UINT32 element);
+ static inline UINT32 sign_extend_6(INT32 i) {
+ return ((i << (32 - 7)) >> (32 - 7)) & 0xfff;
+ }
static inline rsp_vec_t vec_load_unshuffled_operand(const UINT16* src)
{
return _mm_load_si128((rsp_vec_t*) src);
@@ -319,11 +342,11 @@ protected:
}
void vec_load_group1(UINT32 addr, UINT32 element, UINT16* regp, rsp_vec_t reg, rsp_vec_t dqm);
- void vec_load_group2(UINT32 addr, UINT32 element, UINT16* regp, rsp_vec_t reg, rsp_vec_t dqm);
- void vec_load_group4(UINT32 addr, UINT32 element, UINT16* regp, rsp_vec_t reg, rsp_vec_t dqm);
+ void vec_load_group2(UINT32 addr, UINT32 element, UINT16* regp, rsp_vec_t reg, rsp_vec_t dqm, rsp_mem_request_type request_type);
+ void vec_load_group4(UINT32 addr, UINT32 element, UINT16* regp, rsp_vec_t reg, rsp_vec_t dqm, rsp_mem_request_type request_type);
void vec_store_group1(UINT32 addr, UINT32 element, UINT16* regp, rsp_vec_t reg, rsp_vec_t dqm);
- void vec_store_group2(UINT32 addr, UINT32 element, UINT16* regp, rsp_vec_t reg, rsp_vec_t dqm);
- void vec_store_group4(UINT32 addr, UINT32 element, UINT16* regp, rsp_vec_t reg, rsp_vec_t dqm);
+ void vec_store_group2(UINT32 addr, UINT32 element, UINT16* regp, rsp_vec_t reg, rsp_vec_t dqm, rsp_mem_request_type request_type);
+ void vec_store_group4(UINT32 addr, UINT32 element, UINT16* regp, rsp_vec_t reg, rsp_vec_t dqm, rsp_mem_request_type request_type);
#include "clamp.h"
#include "vabs.h"
@@ -349,6 +372,7 @@ protected:
#include "vsub.h"
#include "vsubc.h"
#include "vxor.h"
+#include "vldst.h"
#endif
private:
diff --git a/src/emu/cpu/rsp/vldst.h b/src/emu/cpu/rsp/vldst.h
new file mode 100644
index 00000000000..80e95dd57fc
--- /dev/null
+++ b/src/emu/cpu/rsp/vldst.h
@@ -0,0 +1,73 @@
+// license:BSD-3-Clause
+// copyright-holders:Tyler J. Stachecki,Ryan Holtz
+
+// LBV, LDV, LLV, LSV, SBV, SDV, SLV, SSV
+inline void vec_lbdlsv_sbdlsv(UINT32 iw, UINT32 rs)
+{
+ rs &= 0xfff;
+
+ const UINT32 shift_and_idx = (iw >> 11) & 0x3;
+ rsp_vec_t dqm = _mm_loadl_epi64((rsp_vec_t *) (m_vec_helpers.bdls_lut[shift_and_idx]));
+
+ const UINT32 addr = rs + (sign_extend_6(iw) << shift_and_idx);
+ const UINT32 element = (iw >> 21) & 0xf;
+ UINT16* regp = m_v[(iw >> 16) & 0x1f].s;
+
+ if (iw >> 29 & 0x1)
+ {
+ vec_store_group1(addr, element, regp, vec_load_unshuffled_operand(regp), dqm);
+ }
+ else
+ {
+ vec_load_group1(addr, element, regp, vec_load_unshuffled_operand(regp), dqm);
+ }
+}
+
+// LPV, LUV, SPV, SUV
+inline void vec_lfhpuv_sfhpuv(UINT32 iw, UINT32 rs)
+{
+ static const enum rsp_mem_request_type fhpu_type_lut[4] = {
+ RSP_MEM_REQUEST_PACK,
+ RSP_MEM_REQUEST_UPACK,
+ RSP_MEM_REQUEST_HALF,
+ RSP_MEM_REQUEST_FOURTH
+ };
+
+ rs &= 0xfff;
+
+ const UINT32 addr = rs + (sign_extend_6(iw) << 3);
+ const UINT32 element = (iw >> 21) & 0xf;
+ UINT16* regp = m_v[(iw >> 16) & 0x1f].s;
+
+ rsp_mem_request_type request_type = fhpu_type_lut[((iw >> 11) & 0x1f) - 6];
+ if ((iw >> 29) && 0x1)
+ {
+ vec_store_group2(addr, element, regp, vec_load_unshuffled_operand(regp), _mm_setzero_si128(), request_type);
+ }
+ else
+ {
+ vec_load_group2(addr, element, regp, vec_load_unshuffled_operand(regp), _mm_setzero_si128(), request_type);
+ }
+}
+
+// LQV, LRV, SQV, SRV
+inline void vec_lqrv_sqrv(UINT32 iw, UINT32 rs)
+{
+ rs &= 0xfff;
+
+ const UINT32 addr = rs + (sign_extend_6(iw) << 4);
+ const UINT32 element = (iw >> 21) & 0xf;
+ UINT16* regp = m_v[(iw >> 16) & 0x1f].s;
+
+ memcpy(m_vdqm.s, m_vec_helpers.qr_lut[addr & 0xf], sizeof(m_vdqm.s));
+
+ rsp_mem_request_type request_type = (iw >> 11 & 0x1) ? RSP_MEM_REQUEST_REST : RSP_MEM_REQUEST_QUAD;
+ if ((iw >> 29) & 0x1)
+ {
+ vec_store_group4(addr, element, regp, vec_load_unshuffled_operand(regp), vec_load_unshuffled_operand(m_vdqm.s), request_type);
+ }
+ else
+ {
+ vec_load_group4(addr, element, regp, vec_load_unshuffled_operand(regp), vec_load_unshuffled_operand(m_vdqm.s), request_type);
+ }
+}
diff --git a/src/emu/cpu/sm510/sm510.c b/src/emu/cpu/sm510/sm510.c
index 5a5c364376d..c91f152fa77 100644
--- a/src/emu/cpu/sm510/sm510.c
+++ b/src/emu/cpu/sm510/sm510.c
@@ -6,6 +6,9 @@
References:
- 1990 Sharp Microcomputers Data Book
+
+ TODO:
+ - proper support for LFSR program counter in debugger
*/
@@ -44,23 +47,6 @@ sm510_device::sm510_device(const machine_config &mconfig, const char *tag, devic
// disasm
-void sm510_base_device::state_string_export(const device_state_entry &entry, std::string &str)
-{
- #if 0
- switch (entry.index())
- {
- case STATE_GENFLAGS:
- strprintf(str, "%c%c",
- m_c ? 'C':'c',
- m_s ? 'S':'s'
- );
- break;
-
- default: break;
- }
- #endif
-}
-
offs_t sm510_base_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
{
extern CPU_DISASSEMBLE(sm510);
@@ -98,6 +84,8 @@ void sm510_base_device::device_start()
m_acc = 0;
m_bl = 0;
m_bm = 0;
+ m_c = 0;
+ m_skip = false;
// register for savestates
save_item(NAME(m_stack));
@@ -109,6 +97,8 @@ void sm510_base_device::device_start()
save_item(NAME(m_acc));
save_item(NAME(m_bl));
save_item(NAME(m_bm));
+ save_item(NAME(m_c));
+ save_item(NAME(m_skip));
// register state for debugger
state_add(SM510_PC, "PC", m_pc).formatstr("%04X");
@@ -117,7 +107,7 @@ void sm510_base_device::device_start()
state_add(SM510_BM, "BM", m_bm).formatstr("%01X");
state_add(STATE_GENPC, "curpc", m_pc).formatstr("%04X").noshow();
- state_add(STATE_GENFLAGS, "GENFLAGS", m_pc).formatstr("%2s").noshow();
+ state_add(STATE_GENFLAGS, "GENFLAGS", m_c).formatstr("%1s").noshow();
m_icountptr = &m_icount;
}
@@ -130,19 +120,35 @@ void sm510_base_device::device_start()
void sm510_base_device::device_reset()
{
+ m_skip = false;
+ m_op = m_prev_op = 0;
+ do_branch(3, 7, 0);
+ m_prev_pc = m_pc;
}
-
-
-
//-------------------------------------------------
// execute
//-------------------------------------------------
inline void sm510_base_device::increment_pc()
{
+ // PL(program counter low 6 bits) is a simple LFSR: newbit = (bit0==bit1)
+ // PU,PM(high bits) specify page, PL specifies steps within page
+ int feed = ((m_pc >> 1 ^ m_pc) & 1) ? 0 : 0x20;
+ m_pc = feed | (m_pc >> 1 & 0x1f) | (m_pc & ~0x3f);
+}
+
+void sm510_base_device::get_opcode_param()
+{
+ // LBL, TL, TML opcodes are 2 bytes
+ if (m_op == 0x5f || (m_op & 0xf0) == 0x70)
+ {
+ m_icount--;
+ m_param = m_program->read_byte(m_pc);
+ increment_pc();
+ }
}
void sm510_base_device::execute_run()
@@ -157,12 +163,88 @@ void sm510_base_device::execute_run()
debugger_instruction_hook(this, m_pc);
m_icount--;
m_op = m_program->read_byte(m_pc);
- //m_param = fetch_opcode_param();
-
-
increment_pc();
+ get_opcode_param();
- // handle opcode
+ // handle opcode if it's not skipped
+ if (m_skip)
+ {
+ m_skip = false;
+ m_op = 0; // fake nop
+ }
+ else //execute_one();
+ switch (m_op & 0xf0)
+ {
+ case 0x20: op_lax(); break;
+ case 0x30: op_adx(); break;
+ case 0x40: op_lb(); break;
+
+ case 0x80: case 0x90: case 0xa0: case 0xb0:
+ op_t(); break;
+ case 0xc0: case 0xd0: case 0xe0: case 0xf0:
+ op_tm(); break;
+
+ default:
+ switch (m_op & 0xfc)
+ {
+ case 0x04: op_rm(); break;
+ case 0x0c: op_sm(); break;
+ case 0x10: op_exc(); break;
+ case 0x14: op_exci(); break;
+ case 0x18: op_lda(); break;
+ case 0x1c: op_excd(); break;
+ case 0x54: op_tmi(); break;
+ case 0x70: case 0x74: case 0x78: op_tl(); break;
+ case 0x7c: op_tml(); break;
+
+ default:
+ switch (m_op)
+ {
+ case 0x00: op_skip(); break;
+ case 0x01: op_atbp(); break;
+ case 0x02: op_sbm(); break;
+ case 0x03: op_atpl(); break;
+ case 0x08: op_add(); break;
+ case 0x09: op_add11(); break;
+ case 0x0a: op_coma(); break;
+ case 0x0b: op_exbla(); break;
+
+ case 0x51: op_tb(); break;
+ case 0x52: op_tc(); break;
+ case 0x53: op_tam(); break;
+ case 0x58: op_tis(); break;
+ case 0x59: op_atl(); break;
+ case 0x5a: op_ta0(); break;
+ case 0x5b: op_tabl(); break;
+ case 0x5d: op_cend(); break;
+ case 0x5e: op_tal(); break;
+ case 0x5f: op_lbl(); break;
+
+ case 0x60: op_atfc(); break;
+ case 0x61: op_atr(); break;
+ case 0x62: op_wr(); break;
+ case 0x63: op_ws(); break;
+ case 0x64: op_incb(); break;
+ case 0x65: op_idiv(); break;
+ case 0x66: op_rc(); break;
+ case 0x67: op_sc(); break;
+ case 0x68: op_tf1(); break;
+ case 0x69: op_tf4(); break;
+ case 0x6a: op_kta(); break;
+ case 0x6b: op_rot(); break;
+ case 0x6c: op_decb(); break;
+ case 0x6d: op_bdc(); break;
+ case 0x6e: op_rtn0(); break;
+ case 0x6f: op_rtn1(); break;
+
+ default: op_illegal(); break;
+ }
+ break; // 0xff
+
+ }
+ break; // 0xfc
+
+ } // big switch
}
}
diff --git a/src/emu/cpu/sm510/sm510.h b/src/emu/cpu/sm510/sm510.h
index 34042b093c4..379bc13c314 100644
--- a/src/emu/cpu/sm510/sm510.h
+++ b/src/emu/cpu/sm510/sm510.h
@@ -42,6 +42,8 @@ protected:
virtual void device_reset();
// device_execute_interface overrides
+ virtual UINT64 execute_clocks_to_cycles(UINT64 clocks) const { return (clocks + 2 - 1) / 2; } // default 2 cycles per machine cycle
+ virtual UINT64 execute_cycles_to_clocks(UINT64 cycles) const { return (cycles * 2); } // "
virtual UINT32 execute_min_cycles() const { return 1; }
virtual UINT32 execute_max_cycles() const { return 2; }
virtual UINT32 execute_input_lines() const { return 1; }
@@ -55,7 +57,6 @@ protected:
virtual UINT32 disasm_min_opcode_bytes() const { return 1; }
virtual UINT32 disasm_max_opcode_bytes() const { return 2; }
virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
- void state_string_export(const device_state_entry &entry, std::string &str);
address_space_config m_program_config;
address_space_config m_data_config;
@@ -79,19 +80,79 @@ protected:
UINT8 m_acc;
UINT8 m_bl;
UINT8 m_bm;
+ UINT8 m_c;
+ bool m_skip;
// i/o handlers
//..
// misc internal helpers
void increment_pc();
+ virtual void get_opcode_param();
UINT8 ram_r();
void ram_w(UINT8 data);
void pop_stack();
void push_stack();
+ void do_branch(UINT8 pu, UINT8 pm, UINT8 pl);
+ UINT8 bitmask(UINT8 param);
// opcode handlers
+ void op_lb();
+ void op_lbl();
+ void op_sbm();
+ void op_exbla();
+ void op_incb();
+ void op_decb();
+
+ void op_atpl();
+ void op_rtn0();
+ void op_rtn1();
+ void op_tl();
+ void op_tml();
+ void op_tm();
+ void op_t();
+
+ void op_exc();
+ void op_bdc();
+ void op_exci();
+ void op_excd();
+ void op_lda();
+ void op_lax();
+ void op_wr();
+ void op_ws();
+
+ void op_kta();
+ void op_atbp();
+ void op_atl();
+ void op_atfc();
+ void op_atr();
+
+ void op_add();
+ void op_add11();
+ void op_adx();
+ void op_coma();
+ void op_rot();
+ void op_rc();
+ void op_sc();
+
+ void op_tb();
+ void op_tc();
+ void op_tam();
+ void op_tmi();
+ void op_ta0();
+ void op_tabl();
+ void op_tis();
+ void op_tal();
+ void op_tf1();
+ void op_tf4();
+
+ void op_rm();
+ void op_sm();
+ void op_skip();
+ void op_cend();
+ void op_idiv();
+
void op_illegal();
};
diff --git a/src/emu/cpu/sm510/sm510d.c b/src/emu/cpu/sm510/sm510d.c
index f90bb4f06f0..dffd5e1530c 100644
--- a/src/emu/cpu/sm510/sm510d.c
+++ b/src/emu/cpu/sm510/sm510d.c
@@ -11,12 +11,134 @@
#include "sm510.h"
+enum e_mnemonics
+{
+ mILL,
+ mLB, mLBL, mSBM, mEXBLA, mINCB, mDECB,
+ mATPL, mRTN0, mRTN1, mTL, mTML, mTM, mT,
+ mEXC, mBDC, mEXCI, mEXCD, mLDA, mLAX, mWR, mWS,
+ mKTA, mATBP, mATL, mATFC, mATR,
+ mADD, mADD11, mADX, mCOMA, mROT, mRC, mSC,
+ mTB, mTC, mTAM, mTMI, mTA0, mTABL, mTIS, mTAL, mTF1, mTF4,
+ mRM, mSM, mSKIP, mCEND, mIDIV
+};
+
+static const char *const s_mnemonics[] =
+{
+ "?",
+ "LB", "LBL", "SBM", "EXBLA", "INCB", "DECB",
+ "ATPL", "RTN0", "RTN1", "TL", "TML", "TM", "T",
+ "EXC", "BDC", "EXCI", "EXCD", "LDA", "LAX", "WR", "WS",
+ "KTA", "ATBP", "ATL", "ATFC", "ATR",
+ "ADD", "ADD11", "ADX", "COMA", "ROT", "RC", "SC",
+ "TB", "TC", "TAM", "TMI", "TA0", "TABL", "TIS", "TAL", "TF1", "TF4",
+ "RM", "SM", "SKIP", "CEND", "IDIV"
+};
+
+// number of bits per opcode parameter, 8 or larger means 2-byte opcode
+static const UINT8 s_bits[] =
+{
+ 0,
+ 4, 8, 0, 0, 0, 0,
+ 0, 0, 0, 4+8, 2+8, 6, 6,
+ 2, 0, 2, 2, 2, 4, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 0,
+ 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,
+ 2, 2, 0, 0, 0
+};
+
+#define _OVER DASMFLAG_STEP_OVER
+#define _OUT DASMFLAG_STEP_OUT
+
+static const UINT32 s_flags[] =
+{
+ 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, _OUT, _OUT, 0, _OVER, _OVER, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, _OVER, 0
+};
+
+// next program counter in sequence (relative)
+static const INT8 s_next_pc[0x40] =
+{
+ 32, -1 /* rollback */, -1, 30, 30, -3, -3, 28, 28, -5, -5, 26, 26, -7, -7, 24,
+ 24, -9, -9, 22, 22, -11, -11, 20, 20, -13, -13, 18, 18, -15, -15, 16,
+ 16, -17, -17, 14, 14, -19, -19, 12, 12, -21, -21, 10, 10, -23, -23, 8,
+ 8, -25, -25, 6, 6, -27, -27, 4, 4, -29, -29, 2, 2, -31, -31, 0 /* gets stuck here */
+};
+
+
+static const UINT8 sm510_mnemonic[0x100] =
+{
+/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+ mSKIP, mATBP, mSBM, mATPL, mRM, mRM, mRM, mRM, mADD, mADD11,mCOMA, mEXBLA,mSM, mSM, mSM, mSM, // 0
+ mEXC, mEXC, mEXC, mEXC, mEXCI, mEXCI, mEXCI, mEXCI, mLDA, mLDA, mLDA, mLDA, mEXCD, mEXCD, mEXCD, mEXCD, // 1
+ mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, // 2
+ mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, // 3 - note: $3A has synonym DC(decimal correct)
+
+ mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, // 4
+ 0, mTB, mTC, mTAM, mTMI, mTMI, mTMI, mTMI, mTIS, mATL, mTA0, mTABL, 0, mCEND, mTAL, mLBL, // 5
+ mATFC, mATR, mWR, mWS, mINCB, mIDIV, mRC, mSC, mTF1, mTF4, mKTA, mROT, mDECB, mBDC, mRTN0, mRTN1, // 6
+ mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTL, mTML, mTML, mTML, mTML, // 7
+
+ mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, // 8
+ mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, // 9
+ mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, // A
+ mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, mT, // B
+
+ mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, // C
+ mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, // D
+ mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, // E
+ mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM // F
+};
+
CPU_DISASSEMBLE(sm510)
{
- //int pos = 0;
- //UINT8 op = oprom[pos++];
- return 1 | DASMFLAG_SUPPORTED;
+ // get raw opcode
+ UINT8 op = oprom[0];
+ UINT8 instr = sm510_mnemonic[op];
+ int len = 1;
+ int bits = s_bits[instr];
+ UINT8 mask = op & ((1 << (bits & 7)) - 1);
+ UINT16 param = mask;
+ if (bits >= 8)
+ {
+ // note: disasm view shows correct parameter, but raw view does not
+ // note2: oprom array negative index access is intentional
+ param = oprom[s_next_pc[pc & 0x3f]];
+ len++;
+ }
+
+ // disassemble it
+ char *dst = buffer;
+ dst += sprintf(dst, "%-6s ", s_mnemonics[instr]);
+ if (bits > 0)
+ {
+ if (bits <= 4)
+ {
+ if (param < 10)
+ dst += sprintf(dst, "%d", param);
+ else
+ dst += sprintf(dst, "$%X", param);
+ }
+ else if (bits <= 8)
+ {
+ dst += sprintf(dst, "$%02X", param);
+ }
+ else
+ {
+ UINT16 address = (param << 4 & 0xc00) | (mask << 6 & 0x3c0) | (param & 0x03f);
+ dst += sprintf(dst, "$%03X", address);
+ }
+ }
+
+ return len | s_flags[instr] | DASMFLAG_SUPPORTED;
}
diff --git a/src/emu/cpu/sm510/sm510op.inc b/src/emu/cpu/sm510/sm510op.inc
index f8e6aa40645..b9583694849 100644
--- a/src/emu/cpu/sm510/sm510op.inc
+++ b/src/emu/cpu/sm510/sm510op.inc
@@ -7,13 +7,15 @@
inline UINT8 sm510_base_device::ram_r()
{
- UINT8 address = (m_bm << 4 | m_bl) & m_datamask;
+ int bmh = (m_prev_op == 0x02) ? (1 << (m_datawidth-1)) : 0; // from SBM
+ UINT8 address = (bmh | m_bm << 4 | m_bl) & m_datamask;
return m_data->read_byte(address) & 0xf;
}
inline void sm510_base_device::ram_w(UINT8 data)
{
- UINT8 address = (m_bm << 4 | m_bl) & m_datamask;
+ int bmh = (m_prev_op == 0x02) ? (1 << (m_datawidth-1)) : 0; // from SBM
+ UINT8 address = (bmh | m_bm << 4 | m_bl) & m_datamask;
m_data->write_byte(address, data & 0xf);
}
@@ -31,10 +33,357 @@ void sm510_base_device::push_stack()
m_stack[0] = m_pc;
}
+inline void sm510_base_device::do_branch(UINT8 pu, UINT8 pm, UINT8 pl)
+{
+ // set new PC(Pu/Pm/Pl)
+ m_pc = ((pu << 10 & 0xc00) | (pm << 6 & 0x3c0) | (pl & 0x03f)) & m_prgmask;
+}
+
+inline UINT8 sm510_base_device::bitmask(UINT8 param)
+{
+ // bitmask from immediate opcode param
+ return 1 << (param & 3);
+}
+
// instruction set
+// RAM address instructions
+
+void sm510_base_device::op_lb()
+{
+ // LB x: load BM/BL with 4-bit immediate value (partial)
+ op_illegal();
+}
+
+void sm510_base_device::op_lbl()
+{
+ // LBL xy: load BM/BL with 8-bit immediate value
+ m_bl = m_param & 0xf;
+ m_bm = (m_param & m_datamask) >> 4;
+}
+
+void sm510_base_device::op_sbm()
+{
+ // SBM: set BM high bit for next opcode - handled in ram_r/w
+ assert(m_op == 0x02);
+}
+
+void sm510_base_device::op_exbla()
+{
+ // EXBLA: exchange BL with ACC
+ UINT8 a = m_acc;
+ m_acc = m_bl;
+ m_bl = a;
+}
+
+void sm510_base_device::op_incb()
+{
+ // INCB: increment BL, skip next on overflow
+ m_bl = (m_bl + 1) & 0xf;
+ m_skip = (m_bl == 0);
+}
+
+void sm510_base_device::op_decb()
+{
+ // DECB: decrement BL, skip next on overflow
+ m_bl = (m_bl - 1) & 0xf;
+ m_skip = (m_bl == 0xf);
+}
+
+
+// ROM address instructions
+
+void sm510_base_device::op_atpl()
+{
+ // ATPL: load Pl(PC low bits) with ACC
+ m_pc = (m_pc & ~0xf) | m_acc;
+}
+
+void sm510_base_device::op_rtn0()
+{
+ // RTN0: return from subroutine
+ pop_stack();
+}
+
+void sm510_base_device::op_rtn1()
+{
+ // RTN1: return from subroutine, skip next
+ op_rtn0();
+ m_skip = true;
+}
+
+void sm510_base_device::op_t()
+{
+ // T xy: jump(transfer) within current page
+ m_pc = (m_pc & ~0x3f) | (m_op & 0x3f);
+}
+
+void sm510_base_device::op_tl()
+{
+ // TL xyz: long jump
+ do_branch(m_param >> 6 & 3, m_op & 0xf, m_param & 0x3f);
+}
+
+void sm510_base_device::op_tml()
+{
+ // TML xyz: long call
+ push_stack();
+ do_branch(m_param >> 6 & 3, m_op & 3, m_param & 0x3f);
+}
+
+void sm510_base_device::op_tm()
+{
+ // TM x: indirect subroutine call, pointers(IDX) are in page 0
+ m_icount--;
+ push_stack();
+ UINT8 idx = m_program->read_byte(m_op & 0x3f);
+ do_branch(idx >> 6 & 3, 4, idx & 0x3f);
+}
+
+
+
+// Data transfer instructions
+
+void sm510_base_device::op_exc()
+{
+ // EXC x: exchange ACC with RAM, xor BM with x
+ UINT8 a = m_acc;
+ m_acc = ram_r();
+ ram_w(a);
+ m_bm ^= (m_op & 3);
+}
+
+void sm510_base_device::op_bdc()
+{
+ // BDC: x
+ op_illegal();
+}
+
+void sm510_base_device::op_exci()
+{
+ // EXCI x: EXC x, INCB
+ op_exc();
+ op_incb();
+}
+
+void sm510_base_device::op_excd()
+{
+ // EXCD x: EXC x, DECB
+ op_exc();
+ op_decb();
+}
+
+void sm510_base_device::op_lda()
+{
+ // LDA x: load ACC with RAM, xor BM with x
+ m_acc = ram_r();
+ m_bm ^= (m_op & 3);
+}
+
+void sm510_base_device::op_lax()
+{
+ // LAX x: load ACC with immediate value, skip any next LAX
+ if ((m_op & ~0xf) != (m_prev_op & ~0xf))
+ m_acc = m_op & 0xf;
+}
+
+void sm510_base_device::op_wr()
+{
+ // WR: shift 0 into W
+ op_illegal();
+}
+
+void sm510_base_device::op_ws()
+{
+ // WR: shift 1 into W
+ op_illegal();
+}
+
+
+// I/O instructions
+
+void sm510_base_device::op_kta()
+{
+ // KTA: input K to ACC
+ op_illegal();
+}
+
+void sm510_base_device::op_atbp()
+{
+ // ATBP: output ACC to BP
+ op_illegal();
+}
+
+void sm510_base_device::op_atl()
+{
+ // ATL: input L to ACC
+ op_illegal();
+}
+
+void sm510_base_device::op_atfc()
+{
+ // ATFC: input Y to ACC
+ op_illegal();
+}
+
+void sm510_base_device::op_atr()
+{
+ // ATR: output ACC to R
+ op_illegal();
+}
+
+
+// Arithmetic instructions
+
+void sm510_base_device::op_add()
+{
+ // ADD: add RAM to ACC
+ m_acc = (m_acc + ram_r()) & 0xf;
+}
+
+void sm510_base_device::op_add11()
+{
+ // ADD11: add RAM and carry to ACC and carry, skip next on carry
+ m_acc += ram_r() + m_c;
+ m_c = m_acc >> 4 & 1;
+ m_skip = (m_c == 1);
+ m_acc &= 0xf;
+}
+
+void sm510_base_device::op_adx()
+{
+ // ADX x: add immediate value to ACC, skip next on carry
+ m_acc += (m_op & 0xf);
+ m_skip = ((m_acc & 0x10) != 0);
+ m_acc &= 0xf;
+}
+
+void sm510_base_device::op_coma()
+{
+ // COMA: complement ACC
+ m_acc ^= 0xf;
+}
+
+void sm510_base_device::op_rot()
+{
+ // ROT: rotate ACC right through carry
+ UINT8 c = m_acc & 1;
+ m_acc = m_acc >> 1 | m_c << 3;
+ m_c = c;
+}
+
+void sm510_base_device::op_rc()
+{
+ // RC: reset carry
+ m_c = 0;
+}
+
+void sm510_base_device::op_sc()
+{
+ // SC: set carry
+ m_c = 1;
+}
+
+
+// Test instructions
+
+void sm510_base_device::op_tb()
+{
+ // TB: x
+ op_illegal();
+}
+
+void sm510_base_device::op_tc()
+{
+ // TC: skip next if no carry
+ m_skip = !m_c;
+}
+
+void sm510_base_device::op_tam()
+{
+ // TAM: skip next if ACC equals RAM
+ m_skip = (m_acc == ram_r());
+}
+
+void sm510_base_device::op_tmi()
+{
+ // TMI x: skip next if RAM bit is set
+ m_skip = ((ram_r() & bitmask(m_op)) != 0);
+}
+
+void sm510_base_device::op_ta0()
+{
+ // TA0: skip next if ACC is clear
+ m_skip = !m_acc;
+}
+
+void sm510_base_device::op_tabl()
+{
+ // TABL: skip next of ACC equals BL
+ m_skip = (m_acc == m_bl);
+}
+
+void sm510_base_device::op_tis()
+{
+ // TIS: x
+ op_illegal();
+}
+
+void sm510_base_device::op_tal()
+{
+ // TAL: x
+ op_illegal();
+}
+
+void sm510_base_device::op_tf1()
+{
+ // TF1: x
+ op_illegal();
+}
+
+void sm510_base_device::op_tf4()
+{
+ // TF4: x
+ op_illegal();
+}
+
+
+// Bit manipulation instructions
+
+void sm510_base_device::op_rm()
+{
+ // RM x: reset RAM bit
+ ram_w(ram_r() & ~bitmask(m_op));
+}
+
+void sm510_base_device::op_sm()
+{
+ // SM x: set RAM bit
+ ram_w(ram_r() | bitmask(m_op));
+}
+
+
+// Special instructions
+
+void sm510_base_device::op_skip()
+{
+ // SKIP: no operation
+}
+
+void sm510_base_device::op_cend()
+{
+ // CEND: stop clock
+ op_illegal();
+}
+
+void sm510_base_device::op_idiv()
+{
+ // IDIV: reset divider
+ op_illegal();
+}
+
void sm510_base_device::op_illegal()
{
logerror("%s unknown opcode $%03X at $%04X\n", tag(), m_op, m_prev_pc);
diff --git a/src/emu/cpu/z8000/z8000ops.inc b/src/emu/cpu/z8000/z8000ops.inc
index 511a0034887..c9d0b365783 100644
--- a/src/emu/cpu/z8000/z8000ops.inc
+++ b/src/emu/cpu/z8000/z8000ops.inc
@@ -4515,13 +4515,14 @@ void z8002_device::Z76_ssN0_dddd_addr()
GET_DST(OP0,NIB3);
GET_SRC(OP0,NIB2);
GET_ADDR_RAW(OP1);
+ UINT16 temp = RW(src); // store src in case dst == src
if (segmented_mode()) {
RL(dst) = addr;
}
else {
RW(dst) = addr;
}
- add_to_addr_reg(dst, RW(src));
+ add_to_addr_reg(dst, temp);
}
/******************************************
diff --git a/src/emu/netlist/analog/nld_twoterm.c b/src/emu/netlist/analog/nld_twoterm.c
index d0199c9671a..64e9ef042ba 100644
--- a/src/emu/netlist/analog/nld_twoterm.c
+++ b/src/emu/netlist/analog/nld_twoterm.c
@@ -281,4 +281,56 @@ NETLIB_UPDATE_TERMINALS(D)
set(m_D.G(), 0.0, m_D.Ieq());
}
+// ----------------------------------------------------------------------------------------
+// nld_VS
+// ----------------------------------------------------------------------------------------
+
+NETLIB_START(VS)
+{
+ NETLIB_NAME(twoterm)::start();
+
+ register_param("R", m_R, 0.1);
+ register_param("V", m_V, 0.0);
+
+ register_terminal("P", m_P);
+ register_terminal("N", m_N);
+}
+
+NETLIB_RESET(VS)
+{
+ NETLIB_NAME(twoterm)::reset();
+ this->set(1.0 / m_R, m_V, 0.0);
+}
+
+NETLIB_UPDATE(VS)
+{
+ NETLIB_NAME(twoterm)::update();
+}
+
+// ----------------------------------------------------------------------------------------
+// nld_CS
+// ----------------------------------------------------------------------------------------
+
+NETLIB_START(CS)
+{
+ NETLIB_NAME(twoterm)::start();
+
+ register_param("I", m_I, 1.0);
+
+ register_terminal("P", m_P);
+ register_terminal("N", m_N);
+}
+
+NETLIB_RESET(CS)
+{
+ NETLIB_NAME(twoterm)::reset();
+ printf("m_I %f\n", m_I.Value());
+ this->set(0.0, 0.0, m_I);
+}
+
+NETLIB_UPDATE(CS)
+{
+ NETLIB_NAME(twoterm)::update();
+}
+
NETLIB_NAMESPACE_DEVICES_END()
diff --git a/src/emu/netlist/analog/nld_twoterm.h b/src/emu/netlist/analog/nld_twoterm.h
index 6ef9361b22d..9969c65830e 100644
--- a/src/emu/netlist/analog/nld_twoterm.h
+++ b/src/emu/netlist/analog/nld_twoterm.h
@@ -40,28 +40,36 @@
// ----------------------------------------------------------------------------------------
#define RES(_name, _R) \
- NET_REGISTER_DEV(R, _name) \
+ NET_REGISTER_DEV(R, _name) \
NETDEV_PARAMI(_name, R, _R)
-#define POT(_name, _R) \
- NET_REGISTER_DEV(POT, _name) \
+#define POT(_name, _R) \
+ NET_REGISTER_DEV(POT, _name) \
NETDEV_PARAMI(_name, R, _R)
/* Does not have pin 3 connected */
-#define POT2(_name, _R) \
- NET_REGISTER_DEV(POT2, _name) \
+#define POT2(_name, _R) \
+ NET_REGISTER_DEV(POT2, _name) \
NETDEV_PARAMI(_name, R, _R)
#define CAP(_name, _C) \
- NET_REGISTER_DEV(C, _name) \
+ NET_REGISTER_DEV(C, _name) \
NETDEV_PARAMI(_name, C, _C)
/* Generic Diode */
-#define DIODE(_name, _model) \
- NET_REGISTER_DEV(D, _name) \
+#define DIODE(_name, _model) \
+ NET_REGISTER_DEV(D, _name) \
NETDEV_PARAMI(_name, model, _model)
+#define VS(_name, _V) \
+ NET_REGISTER_DEV(VS, _name) \
+ NETDEV_PARAMI(_name, V, _V)
+
+#define CS(_name, _I) \
+ NET_REGISTER_DEV(CS, _name) \
+ NETDEV_PARAMI(_name, I, _I)
+
// ----------------------------------------------------------------------------------------
// Generic macros
// ----------------------------------------------------------------------------------------
@@ -290,6 +298,43 @@ protected:
generic_diode m_D;
};
+// ----------------------------------------------------------------------------------------
+// nld_VS - Voltage source
+//
+// netlist voltage source must have inner resistance
+// ----------------------------------------------------------------------------------------
+
+class NETLIB_NAME(VS) : public NETLIB_NAME(twoterm)
+{
+public:
+ ATTR_COLD NETLIB_NAME(VS)() : NETLIB_NAME(twoterm)(VS) { }
+
+protected:
+ virtual void start();
+ virtual void reset();
+ ATTR_HOT void update();
+
+ param_double_t m_R;
+ param_double_t m_V;
+};
+
+// ----------------------------------------------------------------------------------------
+// nld_CS - Current source
+// ----------------------------------------------------------------------------------------
+
+class NETLIB_NAME(CS) : public NETLIB_NAME(twoterm)
+{
+public:
+ ATTR_COLD NETLIB_NAME(CS)() : NETLIB_NAME(twoterm)(CS) { }
+
+protected:
+ virtual void start();
+ virtual void reset();
+ ATTR_HOT void update();
+
+ param_double_t m_I;
+};
+
NETLIB_NAMESPACE_DEVICES_END()
diff --git a/src/emu/netlist/devices/net_lib.c b/src/emu/netlist/devices/net_lib.c
index 5335a34505c..534ef33d782 100644
--- a/src/emu/netlist/devices/net_lib.c
+++ b/src/emu/netlist/devices/net_lib.c
@@ -14,26 +14,31 @@
NETLIST_START(diode_models)
NET_MODEL(".model 1N914 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)")
+ NET_MODEL(".model 1N4001 D(Is=14.11n N=1.984 Rs=33.89m Ikf=94.81 Xti=3 Eg=1.11 Cjo=25.89p M=.44 Vj=.3245 Fc=.5 Bv=75 Ibv=10u Tt=5.7u Iave=1 Vpk=50 mfg=GI type=silicon)")
NET_MODEL(".model 1N4148 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)")
+ NET_MODEL(".model 1S1588 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75)")
NET_MODEL(".model LedRed D(IS=93.2p RS=42M N=3.73 BV=4 IBV=10U CJO=2.97P VJ=.75 M=.333 TT=4.32U Iave=40m Vpk=4 type=LED)")
NET_MODEL(".model LedGreen D(IS=93.2p RS=42M N=4.61 BV=4 IBV=10U CJO=2.97P VJ=.75 M=.333 TT=4.32U Iave=40m Vpk=4 type=LED)")
NET_MODEL(".model LedBlue D(IS=93.2p RS=42M N=7.47 BV=5 IBV=10U CJO=2.97P VJ=.75 M=.333 TT=4.32U Iave=40m Vpk=5 type=LED)")
NET_MODEL(".model LedWhite D(Is=0.27n Rs=5.65 N=6.79 Cjo=42p Iave=30m Vpk=5 type=LED)")
- NET_MODEL(".model 1N4001 D(Is=14.11n N=1.984 Rs=33.89m Ikf=94.81 Xti=3 Eg=1.11 Cjo=25.89p M=.44 Vj=.3245 Fc=.5 Bv=75 Ibv=10u Tt=5.7u Iave=1 Vpk=50 mfg=GI type=silicon)")
+
NETLIST_END()
NETLIST_START(bjt_models)
- NET_MODEL(".model BC237B NPN(IS=1.8E-14 ISE=5.0E-14 ISC=1.72E-13 XTI=3 BF=400 BR=35.5 IKF=0.14 IKR=0.03 XTB=1.5 VAF=80 VAR=12.5 VJE=0.58 VJC=0.54 RE=0.6 RC=0.25 RB=0.56 CJE=13E-12 CJC=4E-12 XCJC=0.75 FC=0.5 NF=0.9955 NR=1.005 NE=1.46 NC=1.27 MJE=0.33 MJC=0.33 TF=0.64E-9 TR=50.72E-9 EG=1.11 KF=0 AF=1 VCEO=45V ICRATING=100M MFG=ZETEX)")
- NET_MODEL(".model BC556B PNP(IS=3.83E-14 NF=1.008 ISE=1.22E-14 NE=1.528 BF=344.4 IKF=0.08039 VAF=21.11 NR=1.005 ISC=2.85E-13 NC=1.28 BR=14.84 IKR=0.047 VAR=32.02 RB=1 IRB=1.00E-06 RBM=1 RE=0.6202 RC=0.5713 XTB=0 EG=1.11 XTI=3 CJE=1.23E-11 VJE=0.6106 MJE=0.378 TF=5.60E-10 XTF=3.414 VTF=5.23 ITF=0.1483 PTF=0 CJC=1.08E-11 VJC=0.1022 MJC=0.3563 XCJC=0.6288 TR=1.00E-32 CJS=0 VJS=0.75 MJS=0.333 FC=0.8027 Vceo=65 Icrating=100m mfg=Philips)")
NET_MODEL(".model 2SA1015 PNP(Is=295.1E-18 Xti=3 Eg=1.11 Vaf=100 Bf=110 Xtb=1.5 Br=10.45 Rc=15 Cjc=66.2p Mjc=1.054 Vjc=.75 Fc=.5 Cje=5p Mje=.3333 Vje=.75 Tr=10n Tf=1.661n VCEO=45V ICrating=150M MFG=Toshiba)")
NET_MODEL(".model 2SC1815 NPN(Is=2.04f Xti=3 Eg=1.11 Vaf=6 Bf=400 Ikf=20m Xtb=1.5 Br=3.377 Rc=1 Cjc=1p Mjc=.3333 Vjc=.75 Fc=.5 Cje=25p Mje=.3333 Vje=.75 Tr=450n Tf=20n Itf=0 Vtf=0 Xtf=0 VCEO=45V ICrating=150M MFG=Toshiba)")
+
NET_MODEL(".model 2N3643 NPN(IS=14.34E-15 ISE=14.34E-15 ISC=0 XTI=3 BF=255.9 BR=6.092 IKF=0.2847 IKR=0 XTB=1.5 VAF=74.03 VAR=28 VJE=0.65 VJC=0.65 RE=0.1 RC=1 RB=10 CJE=22.01E-12 CJC=7.306E-12 XCJC=0.75 FC=0.5 NF=1 NR=1 NE=1.307 NC=2 MJE=0.377 MJC=0.3416 TF=411.1E-12 TR=46.91E-9 ITF=0.6 VTF=1.7 XTF=3 EG=1.11 KF=0 AF=1 VCEO=30 ICRATING=500m MFG=NSC)")
NET_MODEL(".model 2N3645 PNP(IS=650.6E-18 ISE=54.81E-15 ISC=0 XTI=3 BF=231.7 BR=3.563 IKF=1.079 IKR=0 XTB=1.5 VAF=115.7 VAR=35 VJE=0.65 VJC=0.65 RE=0.15 RC=0.715 RB=10 CJE=19.82E-12 CJC=14.76E-12 XCJC=0.75 FC=0.5 NF=1 NR=1 NE=1.829 NC=2 MJE=0.3357 MJC=0.5383 TF=603.7E-12 TR=111.3E-9 ITF=0.65 VTF=5 XTF=1.7 EG=1.11 KF=0 AF=1 VCEO=60 ICRATING=500m MFG=NSC)")
// 3644 = 3645 Difference between 3644 and 3645 is voltage rating. 3644: VCBO=45, 3645: VCBO=60
NET_MODEL(".model 2N3644 PNP(IS=650.6E-18 ISE=54.81E-15 ISC=0 XTI=3 BF=231.7 BR=3.563 IKF=1.079 IKR=0 XTB=1.5 VAF=115.7 VAR=35 VJE=0.65 VJC=0.65 RE=0.15 RC=0.715 RB=10 CJE=19.82E-12 CJC=14.76E-12 XCJC=0.75 FC=0.5 NF=1 NR=1 NE=1.829 NC=2 MJE=0.3357 MJC=0.5383 TF=603.7E-12 TR=111.3E-9 ITF=0.65 VTF=5 XTF=1.7 EG=1.11 KF=0 AF=1 VCEO=60 ICRATING=500m MFG=NSC)")
- NET_MODEL(".model BC817-25 NPN(IS=9.198E-14 NF=1.003 ISE=4.468E-16 NE=1.65 BF=338.8 IKF=0.4913 VAF=107.9 NR=1.002 ISC=5.109E-15 NC=1.071 BR=29.48 IKR=0.193 VAR=25 RB=1 IRB=1000 RBM=1 RE=0.2126 RC=0.143 XTB=0 EG=1.11 XTI=3 CJE=3.825E-11 VJE=0.7004 MJE=0.364 TF=5.229E-10 XTF=219.7 VTF=3.502 ITF=7.257 PTF=0 CJC=1.27E-11 VJC=0.4431 MJC=0.3983 XCJC=0.4555 TR=7E-11 CJS=0 VJS=0.75 MJS=0.333 FC=0.905 Vceo=45 Icrating=500m mfg=Philips)")
// 2N5190 = BC817-25
NET_MODEL(".model 2N5190 NPN(IS=9.198E-14 NF=1.003 ISE=4.468E-16 NE=1.65 BF=338.8 IKF=0.4913 VAF=107.9 NR=1.002 ISC=5.109E-15 NC=1.071 BR=29.48 IKR=0.193 VAR=25 RB=1 IRB=1000 RBM=1 RE=0.2126 RC=0.143 XTB=0 EG=1.11 XTI=3 CJE=3.825E-11 VJE=0.7004 MJE=0.364 TF=5.229E-10 XTF=219.7 VTF=3.502 ITF=7.257 PTF=0 CJC=1.27E-11 VJC=0.4431 MJC=0.3983 XCJC=0.4555 TR=7E-11 CJS=0 VJS=0.75 MJS=0.333 FC=0.905 Vceo=45 Icrating=500m mfg=Philips)")
+ NET_MODEL(".model 2SC945 NPN(IS=3.577E-14 BF=2.382E+02 NF=1.01 VAF=1.206E+02 IKF=3.332E-01 ISE=3.038E-16 NE=1.205 BR=1.289E+01 NR=1.015 VAR=1.533E+01 IKR=2.037E-01 ISC=3.972E-14 NC=1.115 RB=3.680E+01 IRB=1.004E-04 RBM=1 RE=8.338E-01 RC=1.557E+00 CJE=1.877E-11 VJE=7.211E-01 MJE=3.486E-01 TF=4.149E-10 XTF=1.000E+02 VTF=9.956 ITF=5.118E-01 PTF=0 CJC=6.876p VJC=3.645E-01 MJC=3.074E-01 TR=5.145E-08 XTB=1.5 EG=1.11 XTI=3 FC=0.5 Vceo=50 Icrating=100m MFG=NEC)")
+
+ NET_MODEL(".model BC237B NPN(IS=1.8E-14 ISE=5.0E-14 ISC=1.72E-13 XTI=3 BF=400 BR=35.5 IKF=0.14 IKR=0.03 XTB=1.5 VAF=80 VAR=12.5 VJE=0.58 VJC=0.54 RE=0.6 RC=0.25 RB=0.56 CJE=13E-12 CJC=4E-12 XCJC=0.75 FC=0.5 NF=0.9955 NR=1.005 NE=1.46 NC=1.27 MJE=0.33 MJC=0.33 TF=0.64E-9 TR=50.72E-9 EG=1.11 KF=0 AF=1 VCEO=45V ICRATING=100M MFG=ZETEX)")
+ NET_MODEL(".model BC556B PNP(IS=3.83E-14 NF=1.008 ISE=1.22E-14 NE=1.528 BF=344.4 IKF=0.08039 VAF=21.11 NR=1.005 ISC=2.85E-13 NC=1.28 BR=14.84 IKR=0.047 VAR=32.02 RB=1 IRB=1.00E-06 RBM=1 RE=0.6202 RC=0.5713 XTB=0 EG=1.11 XTI=3 CJE=1.23E-11 VJE=0.6106 MJE=0.378 TF=5.60E-10 XTF=3.414 VTF=5.23 ITF=0.1483 PTF=0 CJC=1.08E-11 VJC=0.1022 MJC=0.3563 XCJC=0.6288 TR=1.00E-32 CJS=0 VJS=0.75 MJS=0.333 FC=0.8027 Vceo=65 Icrating=100m mfg=Philips)")
+ NET_MODEL(".model BC817-25 NPN(IS=9.198E-14 NF=1.003 ISE=4.468E-16 NE=1.65 BF=338.8 IKF=0.4913 VAF=107.9 NR=1.002 ISC=5.109E-15 NC=1.071 BR=29.48 IKR=0.193 VAR=25 RB=1 IRB=1000 RBM=1 RE=0.2126 RC=0.143 XTB=0 EG=1.11 XTI=3 CJE=3.825E-11 VJE=0.7004 MJE=0.364 TF=5.229E-10 XTF=219.7 VTF=3.502 ITF=7.257 PTF=0 CJC=1.27E-11 VJC=0.4431 MJC=0.3983 XCJC=0.4555 TR=7E-11 CJS=0 VJS=0.75 MJS=0.333 FC=0.905 Vceo=45 Icrating=500m mfg=Philips)")
NETLIST_END()
@@ -53,6 +58,8 @@ void initialize_factory(factory_list_t &factory)
ENTRY(VCVS, VCVS, "-")
ENTRY(VCCS, VCCS, "-")
ENTRY(CCCS, CCCS, "-")
+ ENTRY(VS, VS, "V")
+ ENTRY(CS, CS, "I")
ENTRY(dummy_input, DUMMY_INPUT, "-")
ENTRY(frontier, FRONTIER_DEV, "+I,G,Q") // not intended to be used directly
ENTRY(QBJT_EB, QBJT_EB, "model")
diff --git a/src/emu/netlist/devices/nld_system.h b/src/emu/netlist/devices/nld_system.h
index 736187468d7..93e536fc7b3 100644
--- a/src/emu/netlist/devices/nld_system.h
+++ b/src/emu/netlist/devices/nld_system.h
@@ -11,6 +11,7 @@
#include "../nl_setup.h"
#include "../nl_base.h"
+#include "../nl_factory.h"
#include "../analog/nld_twoterm.h"
// -----------------------------------------------------------------------------
@@ -417,6 +418,45 @@ private:
bool m_is_timestep;
};
+
+class factory_lib_entry_t : public base_factory_t
+{
+ P_PREVENT_COPYING(factory_lib_entry_t)
+public:
+
+ ATTR_COLD factory_lib_entry_t(setup_t &setup, const pstring &name, const pstring &classname,
+ const pstring &def_param)
+ : base_factory_t(name, classname, def_param), m_setup(setup) { }
+
+ class dummy : public device_t
+ {
+ public:
+ dummy(const pstring &dev_name) : device_t(), m_dev_name(dev_name) { }
+ protected:
+ virtual void init(netlist_t &anetlist, const pstring &aname)
+ {
+ anetlist.setup().namespace_push(aname);
+ anetlist.setup().include(m_dev_name);
+ anetlist.setup().namespace_pop();
+ }
+ void start() { }
+ void reset() { }
+ void update() { }
+
+ pstring m_dev_name;
+ };
+
+ ATTR_COLD device_t *Create()
+ {
+ device_t *r = palloc(dummy(this->name()));
+ return r;
+ }
+
+private:
+ setup_t &m_setup;
+};
+
+
NETLIB_NAMESPACE_DEVICES_END()
#endif /* NLD_SYSTEM_H_ */
diff --git a/src/emu/netlist/nl_base.h b/src/emu/netlist/nl_base.h
index 7f329d05003..fff7fedf204 100644
--- a/src/emu/netlist/nl_base.h
+++ b/src/emu/netlist/nl_base.h
@@ -389,6 +389,8 @@ namespace netlist
VCVS, // Voltage controlled voltage source
VCCS, // Voltage controlled current source
CCCS, // Current controlled current source
+ VS, // Voltage Source
+ CS, // Current Source
GND // GND device
};
diff --git a/src/emu/netlist/nl_parser.c b/src/emu/netlist/nl_parser.c
index 4b6f2f51bbd..cbd9be4ec5a 100644
--- a/src/emu/netlist/nl_parser.c
+++ b/src/emu/netlist/nl_parser.c
@@ -56,6 +56,7 @@ bool parser_t::parse(const char *buf, const pstring nlname)
m_tok_NET_MODEL = register_token("NET_MODEL");
m_tok_INCLUDE = register_token("INCLUDE");
m_tok_LOCAL_SOURCE = register_token("LOCAL_SOURCE");
+ m_tok_LOCAL_LIB_ENTRY = register_token("LOCAL_LIB_ENTRY");
m_tok_SUBMODEL = register_token("SUBMODEL");
m_tok_NETLIST_START = register_token("NETLIST_START");
m_tok_NETLIST_END = register_token("NETLIST_END");
@@ -63,6 +64,7 @@ bool parser_t::parse(const char *buf, const pstring nlname)
m_tok_TRUTHTABLE_END = register_token("TRUTHTABLE_END");
m_tok_TT_HEAD = register_token("TT_HEAD");
m_tok_TT_LINE = register_token("TT_LINE");
+ m_tok_TT_FAMILY = register_token("TT_FAMILY");
bool in_nl = false;
@@ -134,6 +136,11 @@ void parser_t::parse_netlist(ATTR_UNUSED const pstring &nlname)
net_local_source();
else if (token.is(m_tok_TRUTHTABLE_START))
net_truthtable_start();
+ else if (token.is(m_tok_LOCAL_LIB_ENTRY))
+ {
+ m_setup.register_lib_entry(get_identifier());
+ require_token(m_tok_param_right);
+ }
else if (token.is(m_tok_NETLIST_END))
{
netdev_netlist_end();
@@ -176,6 +183,12 @@ void parser_t::net_truthtable_start()
ttd->m_desc.add(get_string());
require_token(m_tok_param_right);
}
+ else if (token.is(m_tok_TT_FAMILY))
+ {
+ require_token(m_tok_param_left);
+ ttd->m_family = netlist::logic_family_desc_t::from_model(get_string());
+ require_token(m_tok_param_right);
+ }
else
{
require_token(token, m_tok_TRUTHTABLE_END);
@@ -307,55 +320,65 @@ void parser_t::netdev_param()
void parser_t::device(const pstring &dev_type)
{
- pstring devname;
- base_factory_t *f = m_setup.factory().factory_by_name(dev_type, m_setup);
- device_t *dev;
- pstring_list_t termlist = f->term_param_list();
- pstring_list_t def_params = f->def_params();
-
- std::size_t cnt;
-
- devname = get_identifier();
-
- dev = f->Create();
- m_setup.register_dev(dev, devname);
-
- NL_VERBOSE_OUT(("Parser: IC: %s\n", devname.cstr()));
-
- cnt = 0;
- while (cnt < def_params.size())
+ if (m_setup.is_library_item(dev_type))
{
- pstring paramfq = devname + "." + def_params[cnt];
+ pstring devname = get_identifier();
+ m_setup.namespace_push(devname);
+ m_setup.include(dev_type);
+ m_setup.namespace_pop();
+ require_token(m_tok_param_right);
+ }
+ else
+ {
+ base_factory_t *f = m_setup.factory().factory_by_name(dev_type, m_setup);
+ device_t *dev;
+ pstring_list_t termlist = f->term_param_list();
+ pstring_list_t def_params = f->def_params();
+
+ std::size_t cnt;
+
+ pstring devname = get_identifier();
+
+ dev = f->Create();
+ m_setup.register_dev(dev, devname);
+
+ NL_VERBOSE_OUT(("Parser: IC: %s\n", devname.cstr()));
+
+ cnt = 0;
+ while (cnt < def_params.size())
+ {
+ pstring paramfq = devname + "." + def_params[cnt];
+
+ NL_VERBOSE_OUT(("Defparam: %s\n", paramfq.cstr()));
+ require_token(m_tok_comma);
+ token_t tok = get_token();
+ if (tok.is_type(STRING))
+ {
+ m_setup.register_param(paramfq, tok.str());
+ }
+ else
+ {
+ nl_double val = eval_param(tok);
+ m_setup.register_param(paramfq, val);
+ }
+ cnt++;
+ }
- NL_VERBOSE_OUT(("Defparam: %s\n", paramfq.cstr()));
- require_token(m_tok_comma);
token_t tok = get_token();
- if (tok.is_type(STRING))
+ cnt = 0;
+ while (tok.is(m_tok_comma) && cnt < termlist.size())
{
- m_setup.register_param(paramfq, tok.str());
+ pstring output_name = get_identifier();
+
+ m_setup.register_link(devname + "." + termlist[cnt], output_name);
+
+ cnt++;
+ tok = get_token();
}
- else
- {
- nl_double val = eval_param(tok);
- m_setup.register_param(paramfq, val);
- }
- cnt++;
+ if (cnt != termlist.size())
+ m_setup.netlist().error("netlist: input count mismatch for %s - expected %" SIZETFMT " found %" SIZETFMT "\n", devname.cstr(), SIZET_PRINTF(termlist.size()), SIZET_PRINTF(cnt));
+ require_token(tok, m_tok_param_right);
}
-
- token_t tok = get_token();
- cnt = 0;
- while (tok.is(m_tok_comma) && cnt < termlist.size())
- {
- pstring output_name = get_identifier();
-
- m_setup.register_link(devname + "." + termlist[cnt], output_name);
-
- cnt++;
- tok = get_token();
- }
- if (cnt != termlist.size())
- m_setup.netlist().error("netlist: input count mismatch for %s - expected %" SIZETFMT " found %" SIZETFMT "\n", devname.cstr(), termlist.size(), cnt);
- require_token(tok, m_tok_param_right);
}
diff --git a/src/emu/netlist/nl_parser.h b/src/emu/netlist/nl_parser.h
index 885d62449fb..d1e50ad026a 100644
--- a/src/emu/netlist/nl_parser.h
+++ b/src/emu/netlist/nl_parser.h
@@ -59,10 +59,12 @@ namespace netlist
token_id_t m_tok_SUBMODEL;
token_id_t m_tok_INCLUDE;
token_id_t m_tok_LOCAL_SOURCE;
+ token_id_t m_tok_LOCAL_LIB_ENTRY;
token_id_t m_tok_TRUTHTABLE_START;
token_id_t m_tok_TRUTHTABLE_END;
token_id_t m_tok_TT_HEAD;
token_id_t m_tok_TT_LINE;
+ token_id_t m_tok_TT_FAMILY;
setup_t &m_setup;
diff --git a/src/emu/netlist/nl_setup.c b/src/emu/netlist/nl_setup.c
index b7ebc9ca5e8..5b5eb7ccfb1 100644
--- a/src/emu/netlist/nl_setup.c
+++ b/src/emu/netlist/nl_setup.c
@@ -102,12 +102,30 @@ device_t *setup_t::register_dev(device_t *dev, const pstring &name)
return dev;
}
+void setup_t::register_lib_entry(const pstring &name)
+{
+ if (m_lib.contains(name))
+ netlist().warning("Lib entry collection already contains %s. IGNORED", name.cstr());
+ else
+ m_lib.add(name);
+}
+
device_t *setup_t::register_dev(const pstring &classname, const pstring &name)
{
- device_t *dev = factory().new_device_by_classname(classname);
- if (dev == NULL)
- netlist().error("Class %s not found!\n", classname.cstr());
- return register_dev(dev, name);
+ if (m_lib.contains(classname))
+ {
+ namespace_push(name);
+ include(classname);
+ namespace_pop();
+ return NULL;
+ }
+ else
+ {
+ device_t *dev = factory().new_device_by_classname(classname);
+ if (dev == NULL)
+ netlist().error("Class %s not found!\n", classname.cstr());
+ return register_dev(dev, name);
+ }
}
void setup_t::remove_dev(const pstring &name)
diff --git a/src/emu/netlist/nl_setup.h b/src/emu/netlist/nl_setup.h
index 88bd0b1504a..1cfa5a75ece 100644
--- a/src/emu/netlist/nl_setup.h
+++ b/src/emu/netlist/nl_setup.h
@@ -49,23 +49,27 @@
#define NETLIST_NAME(_name) netlist ## _ ## _name
-#define NETLIST_EXTERNAL(_name) \
+#define NETLIST_EXTERNAL(_name) \
ATTR_COLD void NETLIST_NAME(_name)(netlist::setup_t &setup);
-#define NETLIST_START(_name) \
-ATTR_COLD void NETLIST_NAME(_name)(netlist::setup_t &setup) \
+#define NETLIST_START(_name) \
+ATTR_COLD void NETLIST_NAME(_name)(netlist::setup_t &setup) \
{
#define NETLIST_END() }
-#define LOCAL_SOURCE(_name) \
+#define LOCAL_SOURCE(_name) \
setup.register_source(palloc(netlist::source_proc_t(# _name, &NETLIST_NAME(_name))));
-#define INCLUDE(_name) \
+#define LOCAL_LIB_ENTRY(_name) \
+ LOCAL_SOURCE(_name) \
+ setup.register_lib_entry(# _name);
+
+#define INCLUDE(_name) \
setup.include(# _name);
-#define SUBMODEL(_model, _name) \
- setup.namespace_push(# _name); \
- NETLIST_NAME(_model)(setup); \
+#define SUBMODEL(_model, _name) \
+ setup.namespace_push(# _name); \
+ NETLIST_NAME(_model)(setup); \
setup.namespace_pop();
// ----------------------------------------------------------------------------------------
@@ -145,6 +149,8 @@ namespace netlist
device_t *register_dev(const pstring &classname, const pstring &name);
void remove_dev(const pstring &name);
+ void register_lib_entry(const pstring &name);
+
void register_model(const pstring &model);
void register_alias(const pstring &alias, const pstring &out);
void register_alias_nofqn(const pstring &alias, const pstring &out);
@@ -186,6 +192,8 @@ namespace netlist
factory_list_t &factory() { return *m_factory; }
const factory_list_t &factory() const { return *m_factory; }
+ bool is_library_item(const pstring &name) const { return m_lib.contains(name); }
+
/* not ideal, but needed for save_state */
tagmap_terminal_t m_terminals;
@@ -215,6 +223,7 @@ namespace netlist
pstack_t m_stack;
source_t::list_t m_sources;
+ plist_t m_lib;
void connect_terminals(core_terminal_t &in, core_terminal_t &out);
diff --git a/src/emu/netlist/plib/pconfig.h b/src/emu/netlist/plib/pconfig.h
index 4ff0a07602d..2bf1a2f26c5 100644
--- a/src/emu/netlist/plib/pconfig.h
+++ b/src/emu/netlist/plib/pconfig.h
@@ -48,6 +48,11 @@
#undef ATTR_COLD
#define ATTR_COLD
+static inline std::size_t SIZET_PRINTF(const std::size_t &v)
+{
+ return (unsigned) v;
+}
+
/* use MAME */
#if (USE_DELEGATE_TYPE == DELEGATE_TYPE_INTERNAL)
#define PHAS_PMF_INTERNAL 1
@@ -148,6 +153,11 @@ typedef int64_t INT64;
#endif
#endif
+static inline std::size_t SIZET_PRINTF(const std::size_t &v)
+{
+ return (unsigned) v;
+}
+
#endif
/*
diff --git a/src/emu/netlist/plib/pparser.c b/src/emu/netlist/plib/pparser.c
index a6e633f22bb..954b9048810 100644
--- a/src/emu/netlist/plib/pparser.c
+++ b/src/emu/netlist/plib/pparser.c
@@ -463,7 +463,7 @@ pstring ppreprocessor::process(const pstring &contents)
}
}
else
- error(pstring::sprintf("unknown directive on line %" SIZETFMT ": %s\n", i, line.cstr()));
+ error(pstring::sprintf("unknown directive on line %" SIZETFMT ": %s\n", SIZET_PRINTF(i), line.cstr()));
}
else
{
diff --git a/src/emu/netlist/solver/nld_ms_direct.h b/src/emu/netlist/solver/nld_ms_direct.h
index 6f63d51db15..f715b9d074d 100644
--- a/src/emu/netlist/solver/nld_ms_direct.h
+++ b/src/emu/netlist/solver/nld_ms_direct.h
@@ -147,7 +147,7 @@ template
ATTR_COLD void matrix_solver_direct_t::vsetup(analog_net_t::list_t &nets)
{
if (m_dim < nets.size())
- netlist().error("Dimension %d less than %" SIZETFMT, m_dim, nets.size());
+ netlist().error("Dimension %d less than %" SIZETFMT, m_dim, SIZET_PRINTF(nets.size()));
for (unsigned k = 0; k < N(); k++)
{
diff --git a/src/emu/netlist/solver/nld_solver.c b/src/emu/netlist/solver/nld_solver.c
index d1f080bd176..46391bef3e6 100644
--- a/src/emu/netlist/solver/nld_solver.c
+++ b/src/emu/netlist/solver/nld_solver.c
@@ -162,7 +162,7 @@ ATTR_COLD void matrix_solver_t::setup(analog_net_t::list_t &nets)
if (net_proxy_output == NULL)
{
net_proxy_output = palloc(analog_output_t);
- net_proxy_output->init_object(*this, this->name() + "." + pstring::sprintf("m%" SIZETFMT, m_inps.size()));
+ net_proxy_output->init_object(*this, this->name() + "." + pstring::sprintf("m%" SIZETFMT, SIZET_PRINTF(m_inps.size())));
m_inps.add(net_proxy_output);
net_proxy_output->m_proxied_net = &p->net().as_analog();
}
@@ -511,7 +511,7 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start()
}
// setup the solvers
- netlist().log("Found %d net groups in %" SIZETFMT " nets\n", cur_group + 1, netlist().m_nets.size());
+ netlist().log("Found %d net groups in %" SIZETFMT " nets\n", cur_group + 1, SIZET_PRINTF(netlist().m_nets.size()));
for (int i = 0; i <= cur_group; i++)
{
matrix_solver_t *ms;
@@ -576,19 +576,19 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start()
break;
}
- register_sub(pstring::sprintf("Solver_%" SIZETFMT,m_mat_solvers.size()), *ms);
+ register_sub(pstring::sprintf("Solver_%" SIZETFMT,SIZET_PRINTF(m_mat_solvers.size())), *ms);
ms->vsetup(groups[i]);
m_mat_solvers.add(ms);
netlist().log("Solver %s", ms->name().cstr());
- netlist().log(" # %d ==> %" SIZETFMT " nets", i, groups[i].size()); //, (*(*groups[i].first())->m_core_terms.first())->name().cstr());
+ netlist().log(" # %d ==> %" SIZETFMT " nets", i, SIZET_PRINTF(groups[i].size())); //, (*(*groups[i].first())->m_core_terms.first())->name().cstr());
netlist().log(" has %s elements", ms->is_dynamic() ? "dynamic" : "no dynamic");
netlist().log(" has %s elements", ms->is_timestep() ? "timestep" : "no timestep");
for (std::size_t j=0; jname().cstr());
+ netlist().log("Net %" SIZETFMT ": %s", SIZET_PRINTF(j), groups[i][j]->name().cstr());
net_t *n = groups[i][j];
for (std::size_t k = 0; k < n->m_core_terms.size(); k++)
{
diff --git a/src/emu/netlist/tools/nl_convert.c b/src/emu/netlist/tools/nl_convert.c
index 39fad2d7241..23e5c537b12 100644
--- a/src/emu/netlist/tools/nl_convert.c
+++ b/src/emu/netlist/tools/nl_convert.c
@@ -337,7 +337,7 @@ void nl_convert_spice_t::process_line(const pstring &line)
add_device(tname, xname);
for (std::size_t i=1; i < tt.size() - 1; i++)
{
- pstring term = pstring::sprintf("%s.%" SIZETFMT, xname.cstr(), i);
+ pstring term = pstring::sprintf("%s.%" SIZETFMT, xname.cstr(), SIZET_PRINTF(i));
add_term(tt[i], term);
}
break;
diff --git a/src/emu/video/vooddefs.h b/src/emu/video/vooddefs.h
index f20ed902896..bb320bf237e 100644
--- a/src/emu/video/vooddefs.h
+++ b/src/emu/video/vooddefs.h
@@ -26,6 +26,9 @@ enum
// Use old macro style or newer SSE2 optimized functions
#define USE_OLD_RASTER 0
+// Use old table lookup versus straight double divide
+#define USE_FAST_RECIP 1
+
/* maximum number of TMUs */
#define MAX_TMU 2
@@ -2196,11 +2199,8 @@ do
} \
while (0)
-/* use SSE on 64-bit implementations, where it can be assumed */
-#if (!defined(MAME_DEBUG) || defined(__OPTIMIZE__)) && (defined(__SSE2__) || defined(_MSC_VER)) && defined(PTR64)
-
// NB: This code should no longer be SSE2-specific now that it uses rgbaint_t, consider removing the #define and the #else case.
-INLINE UINT32 clampARGB(INT32 iterr, INT32 iterg, INT32 iterb, INT32 itera, UINT32 FBZCP)
+INLINE UINT32 ATTR_FORCE_INLINE clampARGB(INT32 iterr, INT32 iterg, INT32 iterb, INT32 itera, UINT32 FBZCP)
{
rgb_t result;
rgbaint_t colorint((INT32) (itera>>12), (INT32) (iterr>>12), (INT32) (iterg>>12), (INT32) (iterb>>12));
@@ -2228,61 +2228,6 @@ INLINE UINT32 clampARGB(INT32 iterr, INT32 iterg, INT32 iterb, INT32 itera, UINT
}
}
-#else
-
-INLINE UINT32 clampARGB(INT32 iterr, INT32 iterg, INT32 iterb, INT32 itera, UINT32 FBZCP)
-{
- rgb_union result;
- INT16 r, g, b, a;
- r = (INT16)(iterr >> 12);
- g = (INT16)(iterg >> 12);
- b = (INT16)(iterb >> 12);
- a = (INT16)(itera >> 12);
-
- if (FBZCP_RGBZW_CLAMP(FBZCP) == 0)
- {
- r &= 0xfff;
- result.rgb.r = r;
- if (r == 0xfff)
- result.rgb.r = 0;
- else if (r == 0x100)
- result.rgb.r = 0xff;
-
- g &= 0xfff;
- result.rgb.g = g;
- if (g == 0xfff)
- result.rgb.g = 0;
- else if (g == 0x100)
- result.rgb.g = 0xff;
-
- b &= 0xfff;
- result.rgb.b = b;
- if (b == 0xfff)
- result.rgb.b = 0;
- else if (b == 0x100)
- result.rgb.b = 0xff;
-
- a &= 0xfff;
- result.rgb.a = a;
- if (a == 0xfff)
- result.rgb.a = 0;
- else if (a == 0x100)
- result.rgb.a = 0xff;
- }
- else
- {
- result.rgb.r = (r < 0) ? 0 : (r > 0xff) ? 0xff : r;
- result.rgb.g = (g < 0) ? 0 : (g > 0xff) ? 0xff : g;
- result.rgb.b = (b < 0) ? 0 : (b > 0xff) ? 0xff : b;
- result.rgb.a = (a < 0) ? 0 : (a > 0xff) ? 0xff : a;
- }
- return result.u;
-}
-
-#endif
-
-
-
#define CLAMPED_Z(ITERZ, FBZCP, RESULT) \
do \
{ \
@@ -2399,7 +2344,7 @@ do
} \
while (0)
-INLINE bool chromaKeyTest(voodoo_state *v, stats_block *stats, UINT32 fbzModeReg, rgb_union color)
+INLINE bool ATTR_FORCE_INLINE chromaKeyTest(voodoo_state *v, stats_block *stats, UINT32 fbzModeReg, rgb_union color)
{
if (FBZMODE_ENABLE_CHROMAKEY(fbzModeReg))
{
@@ -2572,7 +2517,7 @@ do
} \
while (0)
-INLINE bool alphaTest(voodoo_state *v, stats_block *stats, UINT32 alphaModeReg, UINT8 alpha)
+INLINE bool ATTR_FORCE_INLINE alphaTest(voodoo_state *v, stats_block *stats, UINT32 alphaModeReg, UINT8 alpha)
{
if (ALPHAMODE_ALPHATEST(alphaModeReg))
{
@@ -2801,7 +2746,7 @@ do
} \
while (0)
-INLINE void alphaBlend(UINT32 FBZMODE, UINT32 ALPHAMODE, INT32 x, const UINT8 *dither, int dpix, UINT16 *depth, rgb_union preFog, rgb_union &color)
+INLINE void ATTR_FORCE_INLINE alphaBlend(UINT32 FBZMODE, UINT32 ALPHAMODE, INT32 x, const UINT8 *dither, int dpix, UINT16 *depth, rgb_union preFog, rgb_union &color)
{
if (ALPHAMODE_ALPHABLEND(ALPHAMODE))
{
@@ -3112,7 +3057,7 @@ do
} \
while (0)
-INLINE void applyFogging(voodoo_state *v, UINT32 fogModeReg, UINT32 fbzCpReg, INT32 x, const UINT8 *dither4, INT32 fogDepth, rgb_union &color, INT32 iterz, INT64 iterw, rgb_union iterargb)
+INLINE void ATTR_FORCE_INLINE applyFogging(voodoo_state *v, UINT32 fogModeReg, UINT32 fbzCpReg, INT32 x, const UINT8 *dither4, INT32 fogDepth, rgb_union &color, INT32 iterz, INT64 iterw, rgb_union iterargb)
{
if (FOGMODE_ENABLE_FOG(fogModeReg))
{
@@ -3251,17 +3196,21 @@ do
{ \
INT32 blendr, blendg, blendb, blenda; \
INT32 tr, tg, tb, ta; \
- INT32 oow, s, t, lod, ilod; \
+ INT32 s, t, lod, ilod; \
INT32 smax, tmax; \
UINT32 texbase; \
rgb_union c_local; \
- \
+ \
/* determine the S/T/LOD values for this texture */ \
if (TEXMODE_ENABLE_PERSPECTIVE(TEXMODE)) \
{ \
- oow = fast_reciplog((ITERW), &lod); \
- s = ((INT64)oow * (ITERS)) >> 29; \
- t = ((INT64)oow * (ITERT)) >> 29; \
+ if (USE_FAST_RECIP) { \
+ const INT32 oow = fast_reciplog((ITERW), &lod); \
+ s = ((INT64)oow * (ITERS)) >> 29; \
+ t = ((INT64)oow * (ITERT)) >> 29; \
+ } else { \
+ multi_reciplog(ITERS, ITERT, ITERW, lod, s, t); \
+ } \
lod += (LODBASE); \
} \
else \
@@ -3753,7 +3702,7 @@ do
} \
while (0)
-INLINE bool depthTest(UINT16 zaColorReg, stats_block *stats, INT32 destDepth, UINT32 fbzModeReg, INT32 biasdepth)
+INLINE bool ATTR_FORCE_INLINE depthTest(UINT16 zaColorReg, stats_block *stats, INT32 destDepth, UINT32 fbzModeReg, INT32 biasdepth)
{
/* handle depth buffer testing */
if (FBZMODE_ENABLE_DEPTHBUF(fbzModeReg))
@@ -4178,7 +4127,7 @@ do
} \
while (0)
-INLINE bool combineColor(voodoo_state *VV, stats_block *STATS, UINT32 FBZCOLORPATH, UINT32 FBZMODE, UINT32 ALPHAMODE,
+INLINE bool ATTR_FORCE_INLINE combineColor(voodoo_state *VV, stats_block *STATS, UINT32 FBZCOLORPATH, UINT32 FBZMODE, UINT32 ALPHAMODE,
rgb_union TEXELARGB, INT32 ITERZ, INT64 ITERW, rgb_union ITERARGB, rgb_union &color)
{
rgb_union c_other;
@@ -4621,7 +4570,39 @@ static void raster_##name(void *destbase, INT32 y, const poly_extent *extent, co
} \
}
-INLINE UINT32 genTexture(tmu_state *TT, INT32 x, const UINT8 *dither4, const UINT32 TEXMODE, rgb_t *LOOKUP, INT32 LODBASE, INT64 ITERS, INT64 ITERT, INT64 ITERW, INT32 &lod)
+// ******************************************************************************************************************************
+// Computes a log2 of a 16.32 value to 2 fractional bits of precision.
+// The return value is coded as a 24.8 value.
+// The maximum error using a 4 bit lookup from the mantissa is 0.0875, which is less than 1/2 lsb (0.125) for 2 bits of fraction.
+// ******************************************************************************************************************************
+INLINE INT32 ATTR_FORCE_INLINE new_log2(double &value)
+{
+ static const INT32 new_log2_table[16] = {0, 22, 44, 63, 82, 100, 118, 134, 150, 165, 179, 193, 207, 220, 232, 244};
+ UINT64 ival = *((UINT64 *)&value);
+ // We zero the result if negative so don't worry about the sign bit
+ INT32 exp = (ival>>52);
+ exp -= 1023+32;
+ exp <<= 8;
+ UINT32 addr = (UINT64)(ival>>48) & 0xf;
+ exp += new_log2_table[addr];
+ // Return 0 if negative
+ return (ival & ((UINT64)1<<63)) ? 0 : exp;
+}
+
+// Computes A/C and B/C and returns log2 of 1/C
+// A, B and C are 16.32 values. The results are 14.18.
+INLINE void ATTR_FORCE_INLINE multi_reciplog(INT64 valueA, INT64 valueB, INT64 valueC, INT32 &log, INT32 &resA, INT32 &resB)
+{
+ double recip = 1.0f/valueC;
+ double resAD = valueA * recip * ((INT64)1<<(47-29));
+ double resBD = valueB * recip * ((INT64)1<<(47-29));
+ log = new_log2(recip);
+ resA = resAD;
+ resB = resBD;
+}
+
+
+INLINE UINT32 ATTR_FORCE_INLINE genTexture(tmu_state *TT, INT32 x, const UINT8 *dither4, const UINT32 TEXMODE, rgb_t *LOOKUP, INT32 LODBASE, INT64 ITERS, INT64 ITERT, INT64 ITERW, INT32 &lod)
{
UINT32 result;
INT32 s, t, ilod;
@@ -4631,10 +4612,14 @@ INLINE UINT32 genTexture(tmu_state *TT, INT32 x, const UINT8 *dither4, const UIN
if (TEXMODE_ENABLE_PERSPECTIVE(TEXMODE))
{
INT32 wLog;
- const INT32 oow = fast_reciplog((ITERW), &wLog);
+ if (USE_FAST_RECIP) {
+ const INT32 oow = fast_reciplog((ITERW), &wLog);
+ s = ((INT64)oow * (ITERS)) >> 29;
+ t = ((INT64)oow * (ITERT)) >> 29;
+ } else {
+ multi_reciplog(ITERS, ITERT, ITERW, wLog, s, t);
+ }
lod += wLog;
- s = ((INT64)oow * (ITERS)) >> 29;
- t = ((INT64)oow * (ITERT)) >> 29;
}
else
{
@@ -4808,7 +4793,7 @@ INLINE UINT32 genTexture(tmu_state *TT, INT32 x, const UINT8 *dither4, const UIN
return result;
}
-INLINE UINT32 combineTexture(tmu_state *TT, const UINT32 TEXMODE, rgb_union c_local, rgb_union c_other, INT32 lod)
+INLINE UINT32 ATTR_FORCE_INLINE combineTexture(tmu_state *TT, const UINT32 TEXMODE, rgb_union c_local, rgb_union c_other, INT32 lod)
{
UINT32 result;
//INT32 blendr, blendg, blendb, blenda;
diff --git a/src/mame/audio/irem.c b/src/mame/audio/irem.c
index be8b2c2c8e8..06de09520d7 100644
--- a/src/mame/audio/irem.c
+++ b/src/mame/audio/irem.c
@@ -415,22 +415,8 @@ NETLIST_START(kidniki_interface)
PARAM(Solver.PARALLEL, 0)
#endif
- NET_MODEL(".model 2SC945 NPN(IS=3.577E-14 BF=2.382E+02 NF=1.01 VAF=1.206E+02 IKF=3.332E-01 ISE=3.038E-16 NE=1.205 BR=1.289E+01 NR=1.015 VAR=1.533E+01 IKR=2.037E-01 ISC=3.972E-14 NC=1.115 RB=3.680E+01 IRB=1.004E-04 RBM=1 RE=8.338E-01 RC=1.557E+00 CJE=1.877E-11 VJE=7.211E-01 MJE=3.486E-01 TF=4.149E-10 XTF=1.000E+02 VTF=9.956 ITF=5.118E-01 PTF=0 CJC=6.876p VJC=3.645E-01 MJC=3.074E-01 TR=5.145E-08 XTB=1.5 EG=1.11 XTI=3 FC=0.5 Vceo=50 Icrating=100m MFG=NEC)")
- // Equivalent to 1N914
- NET_MODEL(".model 1S1588 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75)")
-
LOCAL_SOURCE(kidniki_schematics)
- /*
- * Workaround: The simplified opamp model does not correctly
- * model the internals of the inputs.
- */
-
- ANALOG_INPUT(VWORKAROUND, 2.061)
- RES(RWORKAROUND, RES_K(27))
- NET_C(VWORKAROUND.Q, RWORKAROUND.1)
- NET_C(XU1.6, RWORKAROUND.2)
-
ANALOG_INPUT(I_V5, 5)
//ANALOG_INPUT(I_V0, 0)
ALIAS(I_V0.Q, GND)
@@ -481,16 +467,6 @@ NETLIST_START(kidniki_interface)
INCLUDE(kidniki_schematics)
- CAP(C26, CAP_U(1))
- RES(R25, 560)
- RES(R26, RES_K(47))
- CAP(C29, CAP_U(0.01))
-
- NET_C(RV1.2, C26.1)
- NET_C(C26.2, R25.1)
- NET_C(R25.2, R26.1, C29.1)
- NET_C(R26.2, C29.2, GND)
-
#if (USE_FRONTIERS)
OPTIMIZE_FRONTIER(C63.2, RES_K(27), RES_K(1))
OPTIMIZE_FRONTIER(R31.2, RES_K(5.1), 50)
diff --git a/src/mame/audio/nl_kidniki.c b/src/mame/audio/nl_kidniki.c
index 5a2f5604d1d..21a81e80ffb 100644
--- a/src/mame/audio/nl_kidniki.c
+++ b/src/mame/audio/nl_kidniki.c
@@ -9,45 +9,35 @@
#define USE_FIXED_STV 0
#endif
-NETLIST_EXTERNAL(LM324_DIP)
-NETLIST_EXTERNAL(LM358_DIP)
+/* ----------------------------------------------------------------------------
+ * Library section header START
+ * ---------------------------------------------------------------------------*/
#ifndef __PLIB_PREPROCESSOR__
-#define MC14584B_GATE(_name) \
+
+#define MC14584B_GATE(_name) \
NET_REGISTER_DEV_X(MC14584B_GATE, _name)
+
+#define MC14584B_DIP(_name) \
+ NET_REGISTER_DEV_X(MC14584B_DIP, _name)
+
+#define LM324_DIP(_name) \
+ NET_REGISTER_DEV_X(LM324_DIP, _name)
+
+#define LM358_DIP(_name) \
+ NET_REGISTER_DEV_X(LM358_DIP, _name)
+
+NETLIST_EXTERNAL(kidniki_lib)
+
#endif
-NETLIST_START(kidniki_lib)
- TRUTHTABLE_START(MC14584B_GATE, 1, 1, 0, "A,B")
- TT_HEAD(" A | Q ")
- TT_LINE(" 0 | 1 |100")
- TT_LINE(" 1 | 0 |100")
- TT_FAMILY(".model MC14584B FAMILY(IVL=2.1 IVH=2.7 OVL=0.05 OVH=4.95 ORL=10.0 ORH 10.0)")
- TRUTHTABLE_END()
-NETLIST_END()
+/* ----------------------------------------------------------------------------
+ * Library section header END
+ * ---------------------------------------------------------------------------*/
-NETLIST_START(MC14584B_DIP)
- MC14584B_GATE(s1)
- MC14584B_GATE(s2)
- MC14584B_GATE(s3)
- MC14584B_GATE(s4)
- MC14584B_GATE(s5)
- MC14584B_GATE(s6)
-
- ALIAS( 1, s1.A)
- ALIAS( 2, s1.Q)
- ALIAS( 3, s2.A)
- ALIAS( 4, s2.Q)
- ALIAS( 5, s3.A)
- ALIAS( 6, s3.Q)
-
- ALIAS( 8, s4.Q)
- ALIAS( 9, s4.A)
- ALIAS(10, s5.Q)
- ALIAS(11, s5.A)
- ALIAS(12, s6.Q)
- ALIAS(13, s6.A)
-NETLIST_END()
+/* ----------------------------------------------------------------------------
+ * Kidniki schematics
+ * ---------------------------------------------------------------------------*/
NETLIST_START(kidniki_schematics)
// EESCHEMA NETLIST VERSION 1.1 (SPICE FORMAT) CREATION DATE: SAT 06 JUN 2015 01:06:26 PM CEST
@@ -58,9 +48,18 @@ NETLIST_START(kidniki_schematics)
// .END
LOCAL_SOURCE(kidniki_lib)
-
INCLUDE(kidniki_lib)
+ /*
+ * Workaround: The simplified opamp model does not correctly
+ * model the internals of the inputs.
+ */
+
+ ANALOG_INPUT(VWORKAROUND, 2.061)
+ RES(RWORKAROUND, RES_K(27))
+ NET_C(VWORKAROUND.Q, RWORKAROUND.1)
+ NET_C(XU1.6, RWORKAROUND.2)
+
CAP(C200, CAP_N(100))
CAP(C28, CAP_U(1))
CAP(C31, CAP_N(470))
@@ -118,10 +117,12 @@ NETLIST_START(kidniki_schematics)
QBJT_EB(Q7, "2SC945")
QBJT_EB(Q9, "2SC945")
- SUBMODEL(LM324_DIP,XU1)
- SUBMODEL(LM358_DIP,XU2)
+ LM324_DIP(XU1)
+ LM358_DIP(XU2)
+ //SUBMODEL(LM324_DIP,XU1)
+ //SUBMODEL(LM358_DIP,XU2)
- SUBMODEL(MC14584B_DIP, XU3)
+ MC14584B_DIP(XU3)
RES(R100, RES_K(560))
RES(R101, RES_K(150))
@@ -309,8 +310,25 @@ NETLIST_START(kidniki_schematics)
NET_C(I_MSM3K0.Q, R200.2)
NET_C(I_MSM2K0.Q, R201.2)
NET_C(R200.1, R201.1, C200.1)
+
+ /* Amplifier stage */
+
+ CAP(C26, CAP_U(1))
+ RES(R25, 560)
+ RES(R26, RES_K(47))
+ CAP(C29, CAP_U(0.01))
+
+ NET_C(RV1.2, C26.1)
+ NET_C(C26.2, R25.1)
+ NET_C(R25.2, R26.1, C29.1)
+ NET_C(R26.2, C29.2, GND)
+
NETLIST_END()
+/* ----------------------------------------------------------------------------
+ * Library section body START
+ * ---------------------------------------------------------------------------*/
+
NETLIST_START(opamp)
/* Opamp model from
@@ -426,3 +444,41 @@ NETLIST_START(LM358_DIP)
ALIAS( 4, op1.GND)
ALIAS( 8, op1.VCC)
NETLIST_END()
+
+NETLIST_START(MC14584B_DIP)
+ MC14584B_GATE(s1)
+ MC14584B_GATE(s2)
+ MC14584B_GATE(s3)
+ MC14584B_GATE(s4)
+ MC14584B_GATE(s5)
+ MC14584B_GATE(s6)
+
+ ALIAS( 1, s1.A)
+ ALIAS( 2, s1.Q)
+ ALIAS( 3, s2.A)
+ ALIAS( 4, s2.Q)
+ ALIAS( 5, s3.A)
+ ALIAS( 6, s3.Q)
+
+ ALIAS( 8, s4.Q)
+ ALIAS( 9, s4.A)
+ ALIAS(10, s5.Q)
+ ALIAS(11, s5.A)
+ ALIAS(12, s6.Q)
+ ALIAS(13, s6.A)
+NETLIST_END()
+
+NETLIST_START(kidniki_lib)
+ TRUTHTABLE_START(MC14584B_GATE, 1, 1, 0, "")
+ TT_HEAD(" A | Q ")
+ TT_LINE(" 0 | 1 |100")
+ TT_LINE(" 1 | 0 |100")
+ TT_FAMILY(".model MC14584B FAMILY(IVL=2.1 IVH=2.7 OVL=0.05 OVH=4.95 ORL=10.0 ORH 10.0)")
+ TRUTHTABLE_END()
+
+ LOCAL_LIB_ENTRY(LM324_DIP)
+ LOCAL_LIB_ENTRY(LM358_DIP)
+ LOCAL_LIB_ENTRY(MC14584B_DIP)
+
+NETLIST_END()
+
diff --git a/src/mame/drivers/arkanoid.c b/src/mame/drivers/arkanoid.c
index e6b0fed2f33..64693872fea 100644
--- a/src/mame/drivers/arkanoid.c
+++ b/src/mame/drivers/arkanoid.c
@@ -1365,6 +1365,40 @@ MACHINE_CONFIG_END
/***************************************************************************/
/* ROMs */
+/* rom numbering, with guesses:
+ A75 01 = Z80 code 1/2 v1.0 Japan
+ A75 01-1 = Z80 code 1/2 v1.1 Japan and USA/Romstar
+ A75 02 = Z80 code 2/2 v1.0 Japan
+ A75 03 = GFX 1/3
+ A75 04 = GFX 2/3
+ A75 05 = GFX 3/3
+ A75 06 = MC68705P5 MCU code, v1.0 Japan and v1.0 USA/Romstar
+ A75 07 = PROM red
+ A75 08 = PROM green
+ A75 09 = PROM blue
+ A75 10 = Z80 code 2/2 v1.1 USA/Romstar
+ A75 11 = Z80 code 2/2 v1.2 Japan (paired with 01-1 v1.1 Japan)
+ (A75 12 through 17 are unknown, could be another two sets of z80 code plus mc68705p5)
+ A75 18 = Z80 code v2.0 2/2 USA/Romstar
+ A75 19 = Z80 code v2.0 1/2 USA/Romstar
+ A75 20 = MC68705P5 MCU code, v2.0 USA/Romstar
+ A75 21 = Z80 code v2.0 1/2 Japan
+ A75 22 = Z80 code v2.0 2/2 Japan
+ A75 23 = MC68705P5 MCU code, v2.0 Japan
+ A75 24 = Z80 code v2.1 1/2 Japan
+ A75 25 = Z80 code v2.1 2/2 Japan
+ A75 26 = MC68705P5 MCU code, v2.1 Japan
+ A75 27 = Z80 code 1/2 Tournament
+ A75 28 = Z80 code 2/2 Tournament
+ A75 29 = GFX 1/3 Tournament
+ A75 30 = GFX 2/3 Tournament
+ A75 31 = GFX 3/3 Tournament
+ A75 32 = MC68705P5 MCU code, Tournament
+ A75 33 = PROM red Tournament
+ A75 34 = PROM green Tournament
+ A75 35 = PROM blue Tournament
+ (one of the 21/22/23 or 24/25/26 sets is likely 'world'? or are these really two japan sets?)
+*/
ROM_START( arkanoid )
ROM_REGION( 0x10000, "maincpu", 0 )
@@ -1411,23 +1445,24 @@ ROM_START( arkanoidu )
ROM_LOAD( "a75-09.ic22", 0x0400, 0x0200, CRC(a7c6c277) SHA1(adaa003dcd981576ea1cc5f697d709b2d6b2ea29) ) /* blue component */
ROM_END
+/* Observed on a real TAITO J1100075A pcb (with K1100181A sticker), pcb is white painted, and has a "ROMSTAR(C) // All Rights Reserved // Serial No. // No 14128" sticker */
ROM_START( arkanoiduo )
- ROM_REGION( 0x10000, "maincpu", 0 )
- ROM_LOAD( "a75-01-1.ic17", 0x0000, 0x8000, CRC(5bcda3b0) SHA1(52cadd38b5f8e8856f007a9c602d6b508f30be65) )
- ROM_LOAD( "a75-10.ic16", 0x8000, 0x8000, CRC(a1769e15) SHA1(fbb45731246a098b29eb08de5d63074b496aaaba) )
+ ROM_REGION( 0x10000, "maincpu", 0 ) /* Silkscreen: "IC17 27256" and "IC16 27256" */
+ ROM_LOAD( "a75__01-1.ic17", 0x0000, 0x8000, CRC(5bcda3b0) SHA1(52cadd38b5f8e8856f007a9c602d6b508f30be65) )
+ ROM_LOAD( "a75__10.ic16", 0x8000, 0x8000, CRC(a1769e15) SHA1(fbb45731246a098b29eb08de5d63074b496aaaba) )
- ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
- ROM_LOAD( "a75-06.ic14", 0x0000, 0x0800, CRC(515d77b6) SHA1(a302937683d11f663abd56a2fd7c174374e4d7fb) ) // ok for this set
+ ROM_REGION( 0x0800, "mcu", 0 ) /* Silkscreen: "IC14 P5", 2k for the MC68705P5S protected microcontroller */
+ ROM_LOAD( "a75__06.ic14", 0x0000, 0x0800, BAD_DUMP CRC(515d77b6) SHA1(a302937683d11f663abd56a2fd7c174374e4d7fb) ) /* Possible bootleg code??, need to re-verify the real decapped/extracted data here */
- ROM_REGION( 0x18000, "gfx1", 0 )
- ROM_LOAD( "a75-03.ic64", 0x00000, 0x8000, CRC(038b74ba) SHA1(ac053cc4908b4075f918748b89570e07a0ba5116) )
- ROM_LOAD( "a75-04.ic63", 0x08000, 0x8000, CRC(71fae199) SHA1(5d253c46ccf4cd2976a5fb8b8713f0f345443d06) )
- ROM_LOAD( "a75-05.ic62", 0x10000, 0x8000, CRC(c76374e2) SHA1(7520dd48de20db60a2038f134dcaa454988e7874) )
+ ROM_REGION( 0x18000, "gfx1", 0 ) /* Silkscreen: "IC62 27128/256", "IC63 27128/256", "IC64 27128/256" */
+ ROM_LOAD( "a75__03.ic64", 0x00000, 0x8000, CRC(038b74ba) SHA1(ac053cc4908b4075f918748b89570e07a0ba5116) )
+ ROM_LOAD( "a75__04.ic63", 0x08000, 0x8000, CRC(71fae199) SHA1(5d253c46ccf4cd2976a5fb8b8713f0f345443d06) )
+ ROM_LOAD( "a75__05.ic62", 0x10000, 0x8000, CRC(c76374e2) SHA1(7520dd48de20db60a2038f134dcaa454988e7874) )
- ROM_REGION( 0x0600, "proms", 0 ) /* BPROMs are silkscreened as 7621, actual BPROMs used are MMI 6306-1N */
- ROM_LOAD( "a75-07.ic24", 0x0000, 0x0200, CRC(0af8b289) SHA1(6bc589e8a609b4cf450aebedc8ce02d5d45c970f) ) /* red component */
- ROM_LOAD( "a75-08.ic23", 0x0200, 0x0200, CRC(abb002fb) SHA1(c14f56b8ef103600862e7930709d293b0aa97a73) ) /* green component */
- ROM_LOAD( "a75-09.ic22", 0x0400, 0x0200, CRC(a7c6c277) SHA1(adaa003dcd981576ea1cc5f697d709b2d6b2ea29) ) /* blue component */
+ ROM_REGION( 0x0600, "proms", 0 ) /* Silkscreen: "IC22 7621", "IC23 7621", "IC24 7621", but the actual BPROMs used are either MMI 6306-1N or Fairchild MB7116E */
+ ROM_LOAD( "a75-07.ic24", 0x0000, 0x0200, CRC(0af8b289) SHA1(6bc589e8a609b4cf450aebedc8ce02d5d45c970f) ) /* Chip Silkscreen: "A75-07"; red component */
+ ROM_LOAD( "a75-08.ic23", 0x0200, 0x0200, CRC(abb002fb) SHA1(c14f56b8ef103600862e7930709d293b0aa97a73) ) /* Chip Silkscreen: "A75-08"; green component */
+ ROM_LOAD( "a75-09.ic22", 0x0400, 0x0200, CRC(a7c6c277) SHA1(adaa003dcd981576ea1cc5f697d709b2d6b2ea29) ) /* Chip Silkscreen: "A75-09"; blue component */
ROM_END
ROM_START( arkanoidj )
diff --git a/src/mame/drivers/chihiro.c b/src/mame/drivers/chihiro.c
index 1584247309c..3cd3c4c1e32 100644
--- a/src/mame/drivers/chihiro.c
+++ b/src/mame/drivers/chihiro.c
@@ -197,6 +197,9 @@ XBox Board
Notes:
* These parts located on the other side of the PCB
Some of the connectors are not used.
+ GAME1/2 - Connected to CN1 on Base Board. JST Part Number B12B-PHDSS
+ GAME3/4 - Connected to CN1 on Base Board. JST Part Number B12B-PHDSS
+ FRONT_PANEL - Connected to CN1 on Base Board. JST Part Number B10B-PHDSS
Base Board
@@ -378,6 +381,203 @@ Thanks to Alex, Mr Mudkips, and Philip Burke for this info.
//#define LOG_BASEBOARD
//#define USB_ENABLED
+struct OHCIEndpointDescriptor {
+ int mps; // MaximumPacketSize
+ int f; // Format
+ int k; // sKip
+ int s; // Speed
+ int d; // Direction
+ int en; // EndpointNumber
+ int fa; // FunctionAddress
+ UINT32 tailp; // TDQueueTailPointer
+ UINT32 headp; // TDQueueHeadPointer
+ UINT32 nexted; // NextED
+ int c; // toggleCarry
+ int h; // Halted
+ UINT32 word0;
+};
+
+struct OHCITransferDescriptor {
+ int cc; // ConditionCode
+ int ec; // ErrorCount
+ int t; // DataToggle
+ int di; // DelayInterrupt
+ int dp; // Direction/PID
+ int r; // bufferRounding
+ UINT32 cbp; // CurrentBufferPointer
+ UINT32 nexttd; // NextTD
+ UINT32 be; // BufferEnd
+ UINT32 word0;
+};
+
+struct OHCIIsochronousTransferDescriptor {
+ int cc; // ConditionCode
+ int fc; // FrameCount
+ int di; // DelayInterrupt
+ int sf; // StartingFrame
+ UINT32 bp0; // BufferPage0
+ UINT32 nexttd; // NextTD
+ UINT32 be; // BufferEnd
+ UINT32 offset[8]; // Offset/PacketStatusWord
+};
+
+enum OHCIRegisters {
+ HcRevision=0,
+ HcControl,
+ HcCommandStatus,
+ HcInterruptStatus,
+ HcInterruptEnable,
+ HcInterruptDisable,
+ HcHCCA,
+ HcPeriodCurrentED,
+ HcControlHeadED,
+ HcControlCurrentED,
+ HcBulkHeadED,
+ HcBulkCurrentED,
+ HcDoneHead,
+ HcFmInterval,
+ HcFmRemaining,
+ HcFmNumber,
+ HcPeriodicStart,
+ HcLSThreshold,
+ HcRhDescriptorA,
+ HcRhDescriptorB,
+ HcRhStatus,
+ HcRhPortStatus1
+};
+
+enum OHCIHostControllerFunctionalState {
+ UsbReset=0,
+ UsbResume,
+ UsbOperational,
+ UsbSuspend
+};
+
+enum OHCIInterrupt {
+ SchedulingOverrun=1,
+ WritebackDoneHead=2,
+ StartofFrame=4,
+ ResumeDetected=8,
+ UnrecoverableError=16,
+ FrameNumberOverflow=32,
+ RootHubStatusChange=64,
+ OwnershipChange=0x40000000,
+ MasterInterruptEnable=0x80000000
+};
+
+enum OHCICompletionCode {
+ NoError=0,
+ CRC,
+ BitStuffing,
+ DataToggleMismatch,
+ Stall,
+ DeviceNotResponding,
+ PIDCheckFailure,
+ UnexpectedPID,
+ DataOverrun,
+ DataUnderrun,
+ BufferOverrun=12,
+ BufferUnderrun,
+ NotAccessed=14
+};
+
+struct USBSetupPacket {
+ UINT8 bmRequestType;
+ UINT8 bRequest;
+ UINT16 wValue;
+ UINT16 wIndex;
+ UINT16 wLength;
+};
+
+struct USBStandardDeviceDscriptor {
+ UINT8 bLength;
+ UINT8 bDescriptorType;
+ UINT16 bcdUSB;
+ UINT8 bDeviceClass;
+ UINT8 bDeviceSubClass;
+ UINT8 bDeviceProtocol;
+ UINT8 bMaxPacketSize0;
+ UINT16 idVendor;
+ UINT16 idProduct;
+ UINT16 bcdDevice;
+ UINT8 iManufacturer;
+ UINT8 iProduct;
+ UINT8 iSerialNumber;
+ UINT8 bNumConfigurations;
+};
+
+struct USBStandardConfigurationDescriptor {
+ UINT8 bLength;
+ UINT8 bDescriptorType;
+ UINT16 wTotalLength;
+ UINT8 bNumInterfaces;
+ UINT8 bConfigurationValue;
+ UINT8 iConfiguration;
+ UINT8 bmAttributes;
+ UINT8 MaxPower;
+};
+
+struct USBStandardInterfaceDescriptor {
+ UINT8 bLength;
+ UINT8 bDescriptorType;
+ UINT8 bInterfaceNumber;
+ UINT8 bAlternateSetting;
+ UINT8 bNumEndpoints;
+ UINT8 bInterfaceClass;
+ UINT8 bInterfaceSubClass;
+ UINT8 bInterfaceProtocol;
+ UINT8 iInterface;
+};
+
+struct USBStandardEndpointDescriptor {
+ UINT8 bLength;
+ UINT8 bDescriptorType;
+ UINT8 bEndpointAddress;
+ UINT8 bmAttributes;
+ UINT16 wMaxPacketSize;
+ UINT8 bInterval;
+};
+
+enum USBPid {
+ SetupPid=0,
+ OutPid,
+ InPid
+};
+
+enum USBRequestCode {
+ GET_STATUS=0,
+ CLEAR_FEATURE=1,
+ SET_FEATURE=3,
+ SET_ADDRESS=5,
+ GET_DESCRIPTOR=6,
+ SET_DESCRIPTOR=7,
+ GET_CONFIGURATION=8,
+ SET_CONFIGURATION=9,
+ GET_INTERFACE=10,
+ SET_INTERFACE=11,
+ SYNCH_FRAME=12
+};
+
+enum USBDescriptorType {
+ DEVICE=1,
+ CONFIGURATION=2,
+ STRING=3,
+ INTERFACE=4,
+ ENDPOINT=5
+};
+
+class ohci_function_device {
+public:
+ ohci_function_device();
+ void execute_reset();
+ int execute_transfer(int address, int endpoint, int pid, UINT8 *buffer, int size);
+private:
+ int address;
+ int controldir;
+ int remain;
+ UINT8 *position;
+};
+
class chihiro_state : public driver_device
{
public:
@@ -411,9 +611,12 @@ public:
int smbus_pic16lc(int command, int rw, int data);
int smbus_cx25871(int command, int rw, int data);
int smbus_eeprom(int command, int rw, int data);
+ void usb_ohci_plug(int port, ohci_function_device *function);
void usb_ohci_interrupts();
void usb_ohci_read_endpoint_descriptor(UINT32 address);
+ void usb_ohci_writeback_endpoint_descriptor(UINT32 address);
void usb_ohci_read_transfer_descriptor(UINT32 address);
+ void usb_ohci_writeback_transfer_descriptor(UINT32 address);
void usb_ohci_read_isochronous_transfer_descriptor(UINT32 address);
void baseboard_ide_event(int type, UINT8 *read, UINT8 *write);
UINT8 *baseboard_ide_dimmboard(UINT32 lba);
@@ -476,46 +679,22 @@ public:
} ac97st;
struct ohci_state {
UINT32 hc_regs[255];
- int ports[4 + 1];
+ struct {
+ ohci_function_device *function;
+ int delay;
+ } ports[4 + 1];
emu_timer *timer;
int state;
UINT32 framenumber;
+ UINT32 nextinterupted;
+ UINT32 nextbulked;
+ int interruptbulkratio;
+ int writebackdonehadcounter;
address_space *space;
- struct {
- int mps; // MaximumPacketSize
- int f; // Format
- int k; // sKip
- int s; // Speed
- int d; // Direction
- int en; // EndpointNumber
- int fa; // FunctionAddress
- UINT32 tailp; // TDQueueTailPointer
- UINT32 headp; // TDQueueHeadPointer
- UINT32 nexted; // NextED
- int c; // toggleCarry
- int h; // Halted
- } endpoint_descriptor;
- struct {
- int cc; // ConditionCode
- int ec; // ErrorCount
- int t; // DataToggle
- int di; // DelayInterrupt
- int dp; // Direction/PID
- int r; // bufferRounding
- UINT32 cbp; // CurrentBufferPointer
- UINT32 nexttd; // NextTD
- UINT32 be; // BufferEnd
- } transfer_descriptor;
- struct {
- int cc; // ConditionCode
- int fc; // FrameCount
- int di; // DelayInterrupt
- int sf; // StartingFrame
- UINT32 bp0; // BufferPage0
- UINT32 nexttd; // NextTD
- UINT32 be; // BufferEnd
- UINT32 offset[8]; // Offset/PacketStatusWord
- } isochronous_transfer_descriptor;
+ UINT8 buffer[1024];
+ OHCIEndpointDescriptor endpoint_descriptor;
+ OHCITransferDescriptor transfer_descriptor;
+ OHCIIsochronousTransferDescriptor isochronous_transfer_descriptor;
} ohcist;
UINT8 pic16lc_buffer[0xff];
nv2a_renderer *nvidia_nv2a;
@@ -526,50 +705,6 @@ public:
int usbhack_index;
int usbhack_counter;
required_device m_maincpu;
-
- enum OHCIRegisters {
- HcRevision=0,
- HcControl,
- HcCommandStatus,
- HcInterruptStatus,
- HcInterruptEnable,
- HcInterruptDisable,
- HcHCCA,
- HcPeriodCurrentED,
- HcControlHeadED,
- HcControlCurrentED,
- HcBulkHeadED,
- HcBulkCurrentED,
- HcDoneHead,
- HcFmInterval,
- HcFmRemaining,
- HcFmNumber,
- HcPeriodicStart,
- HcLSThreshold,
- HcRhDescriptorA,
- HcRhDescriptorB,
- HcRhStatus,
- HcRhPortStatus0
- };
-
- enum OHCIHostControllerFunctionalState {
- UsbReset=0,
- UsbResume,
- UsbOperational,
- UsbSuspend
- };
-
- enum OHCIInterrupt {
- SchedulingOverrun=1,
- WritebackDoneHead=2,
- StartofFrame=4,
- ResumeDetected=8,
- UnrecoverableError=16,
- FrameNumberOverflow=32,
- RootHubStatusChange=64,
- OwnershipChange=0x40000000,
- MasterInterruptEnable=0x80000000
- };
};
/* jamtable instructions for Chihiro (different from console)
@@ -1280,14 +1415,18 @@ WRITE32_MEMBER(chihiro_state::usbctrl_w)
if (hcfs == UsbOperational) {
ohcist.timer->enable();
ohcist.timer->adjust(attotime::from_msec(1), 0, attotime::from_msec(1));
+ ohcist.writebackdonehadcounter = 7;
}
else
ohcist.timer->enable(false);
ohcist.state = hcfs;
+ ohcist.interruptbulkratio = (data & 3) + 1;
}
if (offset == HcCommandStatus) {
if (data & 1)
ohcist.hc_regs[HcControl] |= 3 << 6;
+ ohcist.hc_regs[HcCommandStatus] |= data;
+ return;
}
if (offset == HcInterruptStatus) {
ohcist.hc_regs[HcInterruptStatus] &= ~data;
@@ -1304,8 +1443,8 @@ WRITE32_MEMBER(chihiro_state::usbctrl_w)
usb_ohci_interrupts();
return;
}
- if (offset >= HcRhPortStatus0) {
- int port = offset - HcRhPortStatus0 + 1; // port 0 not used
+ if (offset >= HcRhPortStatus1) {
+ int port = offset - HcRhPortStatus1 + 1; // port 0 not used
// bit 0 ClearPortEnable: 1 clears PortEnableStatus
// bit 1 SetPortEnable: 1 sets PortEnableStatus
// bit 2 SetPortSuspend: 1 sets PortSuspendStatus
@@ -1313,8 +1452,9 @@ WRITE32_MEMBER(chihiro_state::usbctrl_w)
// bit 4 SetPortReset: 1 sets PortResetStatus
if (data & 0x10) {
ohcist.hc_regs[offset] |= 0x10;
+ ohcist.ports[port].function->execute_reset();
// after 10ms set PortResetStatusChange and clear PortResetStatus and set PortEnableStatus
- ohcist.ports[port] = 10;
+ ohcist.ports[port].delay = 10;
}
// bit 8 SetPortPower: 1 sets PortPowerStatus
// bit 9 ClearPortPower: 1 clears PortPowerStatus
@@ -1336,26 +1476,182 @@ TIMER_CALLBACK_MEMBER(chihiro_state::usb_ohci_timer)
{
UINT32 hcca;
int changed = 0;
+ int list = 1;
+ bool cont = false;
+ int pid, remain, mps;
+ hcca = ohcist.hc_regs[HcHCCA];
if (ohcist.state == UsbOperational) {
- ohcist.framenumber=(ohcist.framenumber+1) & 0xffff;
- hcca = ohcist.hc_regs[HcHCCA];
+ // increment frame number
+ ohcist.framenumber = (ohcist.framenumber + 1) & 0xffff;
ohcist.space->write_dword(hcca + 0x80, ohcist.framenumber);
ohcist.hc_regs[HcFmNumber] = ohcist.framenumber;
}
+ // port reset delay
for (int p = 1; p <= 4; p++) {
- if (ohcist.ports[p] > 0) {
- ohcist.ports[p]--;
- if (ohcist.ports[p] == 0) {
- ohcist.hc_regs[HcRhPortStatus0 + p - 1] = (ohcist.hc_regs[HcRhPortStatus0 + p - 1] & ~(1 << 4)) | (1 << 20) | (1 << 1);
+ if (ohcist.ports[p].delay > 0) {
+ ohcist.ports[p].delay--;
+ if (ohcist.ports[p].delay == 0) {
+ ohcist.hc_regs[HcRhPortStatus1 + p - 1] = (ohcist.hc_regs[HcRhPortStatus1 + p - 1] & ~(1 << 4)) | (1 << 20) | (1 << 1); // bit 1 PortEnableStatus
changed = 1;
}
}
}
if (ohcist.state == UsbOperational) {
+ while (list >= 0)
+ {
+ // select list, do transfer
+ if (list == 0) {
+ if (ohcist.hc_regs[HcControl] & (1 << 2)) {
+ // periodic
+ if (ohcist.hc_regs[HcControl] & (1 << 3)) {
+ // isochronous
+ }
+ }
+ list = -1;
+ }
+ if (list == 1) {
+ // control
+ if (ohcist.hc_regs[HcControl] & (1 << 4)) {
+ cont = true;
+ while (cont == true) {
+ // if current endpoint descriptor is not 0 use it, otherwise ...
+ if (ohcist.hc_regs[HcControlCurrentED] == 0) {
+ // ... check the filled bit ...
+ if (ohcist.hc_regs[HcCommandStatus] & (1 << 1)) {
+ // ... if 1 start processing from the head of the list
+ ohcist.hc_regs[HcControlCurrentED] = ohcist.hc_regs[HcControlHeadED];
+ ohcist.hc_regs[HcCommandStatus] &= ~(1 << 1);
+ // but if the list is empty, go to the next list
+ if (ohcist.hc_regs[HcControlCurrentED] == 0)
+ cont = false;
+ }
+ else
+ cont = false;
+ }
+ if (cont == true) {
+ // service endpoint descriptor
+ usb_ohci_read_endpoint_descriptor(ohcist.hc_regs[HcControlCurrentED]);
+ // only if it is not halted and not to be skipped
+ if (!(ohcist.endpoint_descriptor.h | ohcist.endpoint_descriptor.k)) {
+ // compare the Endpoint Descriptor’s TailPointer and NextTransferDescriptor fields.
+ if (ohcist.endpoint_descriptor.headp != ohcist.endpoint_descriptor.tailp) {
+ UINT32 a, b;
+ // service transfer descriptor
+ usb_ohci_read_transfer_descriptor(ohcist.endpoint_descriptor.headp);
+ // get pid
+ if (ohcist.endpoint_descriptor.d == 1)
+ pid=OutPid; // out
+ else if (ohcist.endpoint_descriptor.d == 2)
+ pid=InPid; // in
+ else {
+ pid = ohcist.transfer_descriptor.dp; // 0 setup 1 out 2 in
+ }
+ // determine how much data to transfer
+ // setup pid must be 8 bytes
+ a = ohcist.transfer_descriptor.be & 0xfff;
+ b = ohcist.transfer_descriptor.cbp & 0xfff;
+ if ((ohcist.transfer_descriptor.be ^ ohcist.transfer_descriptor.cbp) & 0xfffff000)
+ a |= 0x1000;
+ remain = a - b + 1;
+ if (pid == InPid) {
+ mps = ohcist.endpoint_descriptor.mps;
+ if (remain < mps)
+ mps = remain;
+ }
+ else {
+ mps = ohcist.endpoint_descriptor.mps;
+ }
+ if (ohcist.transfer_descriptor.cbp == 0)
+ mps = 0;
+ b = ohcist.transfer_descriptor.cbp;
+ // if sending ...
+ if (pid != InPid) {
+ // ... get mps bytes
+ for (int c = 0; c < mps; c++) {
+ ohcist.buffer[c] = ohcist.space->read_byte(b);
+ b++;
+ if ((b & 0xfff) == 0)
+ b = ohcist.transfer_descriptor.be & 0xfffff000;
+ }
+ }
+ // should check for time available
+ // execute transaction
+ mps=ohcist.ports[1].function->execute_transfer(ohcist.endpoint_descriptor.fa, ohcist.endpoint_descriptor.en, pid, ohcist.buffer, mps);
+ // if receiving ...
+ if (pid == InPid) {
+ // ... store mps bytes
+ for (int c = 0; c < mps; c++) {
+ ohcist.space->write_byte(b,ohcist.buffer[c]);
+ b++;
+ if ((b & 0xfff) == 0)
+ b = ohcist.transfer_descriptor.be & 0xfffff000;
+ }
+ }
+ // status writeback (CompletionCode field, DataToggleControl field, CurrentBufferPointer field, ErrorCount field)
+ ohcist.transfer_descriptor.cc = NoError;
+ ohcist.transfer_descriptor.t = (ohcist.transfer_descriptor.t ^ 1) | 2;
+ ohcist.transfer_descriptor.cbp = b;
+ ohcist.transfer_descriptor.ec = 0;
+ if ((remain == mps) || (mps == 0)) {
+ // retire transfer descriptor
+ a = ohcist.endpoint_descriptor.headp;
+ ohcist.endpoint_descriptor.headp = ohcist.transfer_descriptor.nexttd;
+ ohcist.transfer_descriptor.nexttd = ohcist.hc_regs[HcDoneHead];
+ ohcist.hc_regs[HcDoneHead] = a;
+ ohcist.endpoint_descriptor.c = ohcist.transfer_descriptor.t & 1;
+ if (ohcist.transfer_descriptor.di != 7) {
+ if (ohcist.transfer_descriptor.di < ohcist.writebackdonehadcounter)
+ ohcist.writebackdonehadcounter = ohcist.transfer_descriptor.di;
+ }
+ usb_ohci_writeback_transfer_descriptor(a);
+ usb_ohci_writeback_endpoint_descriptor(ohcist.hc_regs[HcControlCurrentED]);
+ } else {
+ usb_ohci_writeback_transfer_descriptor(ohcist.endpoint_descriptor.headp);
+ }
+ } else
+ ohcist.hc_regs[HcControlCurrentED] = ohcist.endpoint_descriptor.nexted;
+ } else
+ ohcist.hc_regs[HcControlCurrentED] = ohcist.endpoint_descriptor.nexted;
+ // one bulk every n control transfers
+ ohcist.interruptbulkratio--;
+ if (ohcist.interruptbulkratio <= 0) {
+ ohcist.interruptbulkratio = (ohcist.hc_regs[HcControl] & 3) + 1;
+ cont = false;
+ }
+ }
+ }
+ }
+ list = 2;
+ }
+ if (list == 2) {
+ // bulk
+ if (ohcist.hc_regs[HcControl] & (1 << 5)) {
+ ohcist.hc_regs[HcCommandStatus] &= ~(1 << 2);
+ if (ohcist.hc_regs[HcControlCurrentED] == 0)
+ list = 0;
+ else if (ohcist.hc_regs[HcControl] & (1 << 4))
+ list = 1;
+ else
+ list = 0;
+ }
+ }
+ }
if (ohcist.framenumber == 0)
ohcist.hc_regs[HcInterruptStatus] |= FrameNumberOverflow;
ohcist.hc_regs[HcInterruptStatus] |= StartofFrame;
+ if ((ohcist.writebackdonehadcounter != 0) && (ohcist.writebackdonehadcounter != 7))
+ ohcist.writebackdonehadcounter--;
+ if ((ohcist.writebackdonehadcounter == 0) && ((ohcist.hc_regs[HcInterruptStatus] & WritebackDoneHead) == 0)) {
+ UINT32 b = 0;
+
+ if ((ohcist.hc_regs[HcInterruptStatus] & ohcist.hc_regs[HcInterruptEnable]) != WritebackDoneHead)
+ b = 1;
+ ohcist.hc_regs[HcInterruptStatus] |= WritebackDoneHead;
+ ohcist.space->write_dword(hcca + 0x84, ohcist.hc_regs[HcDoneHead] | b);
+ ohcist.hc_regs[HcDoneHead] = 0;
+ ohcist.writebackdonehadcounter = 7;
+ }
}
if (changed != 0) {
ohcist.hc_regs[HcInterruptStatus] |= RootHubStatusChange;
@@ -1363,6 +1659,85 @@ TIMER_CALLBACK_MEMBER(chihiro_state::usb_ohci_timer)
usb_ohci_interrupts();
}
+void chihiro_state::usb_ohci_plug(int port, ohci_function_device *function)
+{
+ if ((port > 0) && (port <= 4)) {
+ ohcist.ports[port].function = function;
+ ohcist.hc_regs[HcRhPortStatus1+port-1] = 1;
+ }
+}
+
+static USBStandardDeviceDscriptor devdesc = {18,1,0x201,0xff,0x34,0x56,64,0x100,0x101,0x301,0,0,0,1};
+
+ohci_function_device::ohci_function_device()
+{
+ address = 0;
+ controldir = 0;
+ remain = 0;
+ position = NULL;
+}
+
+void ohci_function_device::execute_reset()
+{
+ address = 0;
+}
+
+int ohci_function_device::execute_transfer(int address, int endpoint, int pid, UINT8 *buffer, int size)
+{
+ if (endpoint == 0) {
+ if (pid == SetupPid) {
+ struct USBSetupPacket *p=(struct USBSetupPacket *)buffer;
+ // define direction
+ controldir = p->bmRequestType & 128;
+ // case !=0, in data stage and out status stage
+ // case ==0, out data stage and in status stage
+ position = NULL;
+ remain = p->wLength;
+ if ((p->bmRequestType & 0x60) == 0) {
+ switch (p->bRequest) {
+ case GET_DESCRIPTOR:
+ if ((p->wValue >> 8) == 1) { // device descriptor
+ //p->wValue & 255;
+ position = (UINT8 *)&devdesc;
+ remain = sizeof(devdesc);
+ }
+ break;
+ case SET_ADDRESS:
+ //p->wValue;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else if (pid == InPid) {
+ // case !=0, give data
+ // case ==0, nothing
+ if (size > remain)
+ size = remain;
+ if (controldir != 0) {
+ if (position != NULL)
+ memcpy(buffer, position, size);
+ position = position + size;
+ remain = remain - size;
+ }
+ }
+ else if (pid == OutPid) {
+ // case !=0, nothing
+ // case ==0, give data
+ if (size > remain)
+ size = remain;
+ if (controldir == 0) {
+ if (position != NULL)
+ memcpy(position, buffer, size);
+ position = position + size;
+ remain = remain - size;
+ }
+ }
+ }
+ return size;
+}
+
void chihiro_state::usb_ohci_interrupts()
{
if (((ohcist.hc_regs[HcInterruptStatus] & ohcist.hc_regs[HcInterruptEnable]) != 0) && ((ohcist.hc_regs[HcInterruptEnable] & MasterInterruptEnable) != 0))
@@ -1376,6 +1751,7 @@ void chihiro_state::usb_ohci_read_endpoint_descriptor(UINT32 address)
UINT32 w;
w = ohcist.space->read_dword(address);
+ ohcist.endpoint_descriptor.word0 = w;
ohcist.endpoint_descriptor.fa = w & 0x7f;
ohcist.endpoint_descriptor.en = (w >> 7) & 15;
ohcist.endpoint_descriptor.d = (w >> 11) & 3;
@@ -1391,13 +1767,25 @@ void chihiro_state::usb_ohci_read_endpoint_descriptor(UINT32 address)
ohcist.endpoint_descriptor.nexted = ohcist.space->read_dword(address + 12);
}
+void chihiro_state::usb_ohci_writeback_endpoint_descriptor(UINT32 address)
+{
+ UINT32 w;
+
+ w = ohcist.endpoint_descriptor.word0 & 0xf8000000;
+ w = w | (ohcist.endpoint_descriptor.mps << 16) | (ohcist.endpoint_descriptor.f << 15) | (ohcist.endpoint_descriptor.k << 14) | (ohcist.endpoint_descriptor.s << 13) | (ohcist.endpoint_descriptor.d << 11) | (ohcist.endpoint_descriptor.en << 7) | ohcist.endpoint_descriptor.fa;
+ ohcist.space->write_dword(address, w);
+ w = ohcist.endpoint_descriptor.headp | (ohcist.endpoint_descriptor.c << 1) | ohcist.endpoint_descriptor.h;
+ ohcist.space->write_dword(address + 8, w);
+}
+
void chihiro_state::usb_ohci_read_transfer_descriptor(UINT32 address)
{
UINT32 w;
w = ohcist.space->read_dword(address);
+ ohcist.transfer_descriptor.word0 = w;
ohcist.transfer_descriptor.cc = (w >> 28) & 15;
- ohcist.transfer_descriptor.ec= (w >> 16) & 3;
+ ohcist.transfer_descriptor.ec= (w >> 26) & 3;
ohcist.transfer_descriptor.t= (w >> 24) & 3;
ohcist.transfer_descriptor.di= (w >> 21) & 7;
ohcist.transfer_descriptor.dp= (w >> 19) & 3;
@@ -1407,6 +1795,17 @@ void chihiro_state::usb_ohci_read_transfer_descriptor(UINT32 address)
ohcist.transfer_descriptor.be = ohcist.space->read_dword(address + 12);
}
+void chihiro_state::usb_ohci_writeback_transfer_descriptor(UINT32 address)
+{
+ UINT32 w;
+
+ w = ohcist.transfer_descriptor.word0 & 0x0003ffff;
+ w = w | (ohcist.transfer_descriptor.cc << 28) | (ohcist.transfer_descriptor.ec << 26) | (ohcist.transfer_descriptor.t << 24) | (ohcist.transfer_descriptor.di << 21) | (ohcist.transfer_descriptor.dp << 19) | (ohcist.transfer_descriptor.r << 18);
+ ohcist.space->write_dword(address, w);
+ ohcist.space->write_dword(address + 4, ohcist.transfer_descriptor.cbp);
+ ohcist.space->write_dword(address + 8, ohcist.transfer_descriptor.nexttd);
+}
+
void chihiro_state::usb_ohci_read_isochronous_transfer_descriptor(UINT32 address)
{
UINT32 w;
@@ -1623,6 +2022,23 @@ TIMER_CALLBACK_MEMBER(chihiro_state::audio_apu_timer)
}
}
+static UINT32 hubintiasbridg_pci_r(device_t *busdevice, device_t *device, int function, int reg, UINT32 mem_mask)
+{
+#ifdef LOG_PCI
+ // logerror(" bus:0 function:%d register:%d mask:%08X\n",function,reg,mem_mask);
+#endif
+ if ((function == 0) && (reg == 8))
+ return 0xb4; // 0:1:0 revision id must be at least 0xb4, otherwise usb will require a hub
+ return 0;
+}
+
+static void hubintiasbridg_pci_w(device_t *busdevice, device_t *device, int function, int reg, UINT32 data, UINT32 mem_mask)
+{
+#ifdef LOG_PCI
+ if (reg >= 16) logerror(" bus:0 function:%d register:%d data:%08X mask:%08X\n", function, reg, data, mem_mask);
+#endif
+}
+
/*
* dummy for non connected devices
*/
@@ -2131,10 +2547,12 @@ void chihiro_state::machine_start()
ohcist.hc_regs[HcFmInterval] = 0x2edf;
ohcist.hc_regs[HcLSThreshold] = 0x628;
ohcist.hc_regs[HcRhDescriptorA] = 4;
- ohcist.hc_regs[HcRhPortStatus0] = 1; // test connect
+ ohcist.interruptbulkratio = 1;
+ ohcist.writebackdonehadcounter = 7;
ohcist.space = &m_maincpu->space();
ohcist.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(chihiro_state::usb_ohci_timer), this), (void *)"USB OHCI Timer");
ohcist.timer->enable(false);
+ usb_ohci_plug(1, new ohci_function_device()); // test connect
#endif
usbhack_index = -1;
for (int a = 1; a < 2; a++)
@@ -2175,7 +2593,7 @@ static MACHINE_CONFIG_START(chihiro_base, chihiro_state)
MCFG_PCI_BUS_LEGACY_ADD("pcibus", 0)
MCFG_PCI_BUS_LEGACY_DEVICE(0, "PCI Bridge Device - Host Bridge", dummy_pci_r, dummy_pci_w)
- MCFG_PCI_BUS_LEGACY_DEVICE(1, "HUB Interface - ISA Bridge", dummy_pci_r, dummy_pci_w)
+ MCFG_PCI_BUS_LEGACY_DEVICE(1, "HUB Interface - ISA Bridge", hubintiasbridg_pci_r, hubintiasbridg_pci_w)
MCFG_PCI_BUS_LEGACY_DEVICE(2, "OHCI USB Controller 1", dummy_pci_r, dummy_pci_w)
MCFG_PCI_BUS_LEGACY_DEVICE(3, "OHCI USB Controller 2", dummy_pci_r, dummy_pci_w)
MCFG_PCI_BUS_LEGACY_DEVICE(4, "MCP Networking Adapter", dummy_pci_r, dummy_pci_w)
diff --git a/src/mame/drivers/cps2.c b/src/mame/drivers/cps2.c
index 8e483dbb429..b66415be907 100644
--- a/src/mame/drivers/cps2.c
+++ b/src/mame/drivers/cps2.c
@@ -8755,8 +8755,8 @@ ROM_END
ROM_START( xmvsfur1 )
ROM_REGION( CODE_SIZE, "maincpu", 0 ) /* 68000 code */
- ROM_LOAD16_WORD_SWAP( "xvsu.03h", 0x000000, 0x80000, CRC(5481155a) SHA1(799a2488684cbead33206498d13261b79624a46e) )
- ROM_LOAD16_WORD_SWAP( "xvsu.04h", 0x080000, 0x80000, CRC(1e236388) SHA1(329c08103840fadbc4176785c4b24013a7a2b1bc) )
+ ROM_LOAD16_WORD_SWAP( "xvsu.03h", 0x000000, 0x80000, CRC(5481155a) SHA1(799a2488684cbead33206498d13261b79624a46e) ) /* also found as rev I */
+ ROM_LOAD16_WORD_SWAP( "xvsu.04h", 0x080000, 0x80000, CRC(1e236388) SHA1(329c08103840fadbc4176785c4b24013a7a2b1bc) ) /* also found as rev I */
ROM_LOAD16_WORD_SWAP( "xvs.05a", 0x100000, 0x80000, CRC(7db6025d) SHA1(2d74f48f83f45359bfaca28ab686625766af12ee) )
ROM_LOAD16_WORD_SWAP( "xvs.06a", 0x180000, 0x80000, CRC(e8e2c75c) SHA1(929408cb5d98e95cec75ea58e4701b0cbdbcd016) )
ROM_LOAD16_WORD_SWAP( "xvs.07", 0x200000, 0x80000, CRC(08f0abed) SHA1(ef16c376232dba63b0b9bc3aa0640f9001ccb68a) )
@@ -8788,8 +8788,8 @@ ROM_END
ROM_START( xmvsfur2 )
ROM_REGION( CODE_SIZE, "maincpu", 0 ) /* 68000 code */
- ROM_LOAD16_WORD_SWAP( "xvsu.03", 0x000000, 0x80000, CRC(bd8b152f) SHA1(6b029b7314ce2516c67e5a71508f86aa01d30ab8) )
- ROM_LOAD16_WORD_SWAP( "xvsu.04", 0x080000, 0x80000, CRC(7c7d1da3) SHA1(96dd1f83c8f8053177b91ad31c4c051b28dd0208) )
+ ROM_LOAD16_WORD_SWAP( "xvsu.03d", 0x000000, 0x80000, CRC(bd8b152f) SHA1(6b029b7314ce2516c67e5a71508f86aa01d30ab8) )
+ ROM_LOAD16_WORD_SWAP( "xvsu.04d", 0x080000, 0x80000, CRC(7c7d1da3) SHA1(96dd1f83c8f8053177b91ad31c4c051b28dd0208) )
ROM_LOAD16_WORD_SWAP( "xvs.05a", 0x100000, 0x80000, CRC(7db6025d) SHA1(2d74f48f83f45359bfaca28ab686625766af12ee) )
ROM_LOAD16_WORD_SWAP( "xvs.06a", 0x180000, 0x80000, CRC(e8e2c75c) SHA1(929408cb5d98e95cec75ea58e4701b0cbdbcd016) )
ROM_LOAD16_WORD_SWAP( "xvs.07", 0x200000, 0x80000, CRC(08f0abed) SHA1(ef16c376232dba63b0b9bc3aa0640f9001ccb68a) )
diff --git a/src/mame/drivers/deco32.c b/src/mame/drivers/deco32.c
index 220bf509cb1..90cbed76764 100644
--- a/src/mame/drivers/deco32.c
+++ b/src/mame/drivers/deco32.c
@@ -232,10 +232,8 @@ Notes:
#include "cpu/m6809/m6809.h"
#include "cpu/z80/z80.h"
#include "includes/decocrpt.h"
-#include "machine/eepromser.h"
#include "includes/deco32.h"
#include "sound/2151intf.h"
-#include "sound/okim6295.h"
/**********************************************************************************/
@@ -245,7 +243,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(deco32_state::interrupt_gen)
m_maincpu->set_input_line(ARM_IRQ_LINE, HOLD_LINE);
}
-READ32_MEMBER(deco32_state::deco32_irq_controller_r)
+READ32_MEMBER(deco32_state::irq_controller_r)
{
int vblank;
@@ -281,7 +279,7 @@ READ32_MEMBER(deco32_state::deco32_irq_controller_r)
return 0xffffffff;
}
-WRITE32_MEMBER(deco32_state::deco32_irq_controller_w)
+WRITE32_MEMBER(deco32_state::irq_controller_w)
{
int scanline;
@@ -305,7 +303,7 @@ WRITE32_MEMBER(deco32_state::deco32_irq_controller_w)
}
}
-WRITE32_MEMBER(deco32_state::deco32_sound_w)
+WRITE32_MEMBER(deco32_state::sound_w)
{
soundlatch_byte_w(space,0,data & 0xff);
m_audiocpu->set_input_line(0, HOLD_LINE);
@@ -317,7 +315,7 @@ void deco32_state::deco32_sound_cb( address_space &space, UINT16 data, UINT16 me
m_audiocpu->set_input_line(0, HOLD_LINE);
}
-READ32_MEMBER(deco32_state::deco32_71_r)
+READ32_MEMBER(deco32_state::_71_r)
{
/* Bit 0x80 goes high when sprite DMA is complete, and low
while it's in progress, we don't bother to emulate it */
@@ -349,7 +347,7 @@ WRITE32_MEMBER(deco32_state::fghthist_eeprom_w)
m_eeprom->di_write((data & 0x10) >> 4);
m_eeprom->cs_write((data & 0x40) ? ASSERT_LINE : CLEAR_LINE);
- deco32_pri_w(space,0,data&0x1,0xffffffff); /* Bit 0 - layer priority toggle */
+ pri_w(space,0,data&0x1,0xffffffff); /* Bit 0 - layer priority toggle */
}
else if (!ACCESSING_BITS_8_15)
{
@@ -359,13 +357,13 @@ WRITE32_MEMBER(deco32_state::fghthist_eeprom_w)
/**********************************************************************************/
-READ32_MEMBER(deco32_state::dragngun_service_r)
+READ32_MEMBER(dragngun_state::service_r)
{
// logerror("%08x:Read service\n",space.device().safe_pc());
return ioport("IN2")->read();
}
-READ32_MEMBER(deco32_state::lockload_gun_mirror_r)
+READ32_MEMBER(dragngun_state::lockload_gun_mirror_r)
{
//logerror("%08x:Read gun %d\n",space.device().safe_pc(),offset);
//return ((machine().rand()%0xffff)<<16) | machine().rand()%0xffff;
@@ -375,32 +373,32 @@ READ32_MEMBER(deco32_state::lockload_gun_mirror_r)
}
-READ32_MEMBER(dragngun_state::dragngun_lightgun_r)
+READ32_MEMBER(dragngun_state::lightgun_r)
{
/* Ports 0-3 are read, but seem unused */
- switch (m_dragngun_lightgun_port) {
+ switch (m_lightgun_port) {
case 4: return ioport("LIGHT0_X")->read();
case 5: return ioport("LIGHT1_X")->read();
case 6: return ioport("LIGHT0_Y")->read();
case 7: return ioport("LIGHT1_Y")->read();
}
-// logerror("Illegal lightgun port %d read \n",m_dragngun_lightgun_port);
+// logerror("Illegal lightgun port %d read \n",m_lightgun_port);
return 0;
}
-WRITE32_MEMBER(dragngun_state::dragngun_lightgun_w)
+WRITE32_MEMBER(dragngun_state::lightgun_w)
{
-// logerror("Lightgun port %d\n",m_dragngun_lightgun_port);
- m_dragngun_lightgun_port=offset;
+// logerror("Lightgun port %d\n",m_lightgun_port);
+ m_lightgun_port=offset;
}
-READ32_MEMBER(deco32_state::dragngun_eeprom_r)
+READ32_MEMBER(dragngun_state::eeprom_r)
{
return 0xfffffffe | m_eeprom->do_read();
}
-WRITE32_MEMBER(deco32_state::dragngun_eeprom_w)
+WRITE32_MEMBER(dragngun_state::eeprom_w)
{
if (ACCESSING_BITS_0_7) {
m_eeprom->clk_write((data & 0x2) ? ASSERT_LINE : CLEAR_LINE);
@@ -531,7 +529,7 @@ WRITE32_MEMBER(deco32_state::tattass_control_w)
}
/* Playfield control - Only written in full word memory accesses */
- deco32_pri_w(space,0,data&0x3,0xffffffff); /* Bit 0 - layer priority toggle, Bit 1 - BG2/3 Joint mode (8bpp) */
+ pri_w(space,0,data&0x3,0xffffffff); /* Bit 0 - layer priority toggle, Bit 1 - BG2/3 Joint mode (8bpp) */
/* Sound board reset control */
if (data&0x80)
@@ -585,7 +583,7 @@ WRITE32_MEMBER(deco32_state::nslasher_eeprom_w)
m_eeprom->di_write((data & 0x10) >> 4);
m_eeprom->cs_write((data & 0x40) ? ASSERT_LINE : CLEAR_LINE);
- deco32_pri_w(space,0,data&0x3,0xffffffff); /* Bit 0 - layer priority toggle, Bit 1 - BG2/3 Joint mode (8bpp) */
+ pri_w(space,0,data&0x3,0xffffffff); /* Bit 0 - layer priority toggle, Bit 1 - BG2/3 Joint mode (8bpp) */
}
}
@@ -594,81 +592,81 @@ WRITE32_MEMBER(deco32_state::nslasher_eeprom_w)
/**********************************************************************************/
-READ32_MEMBER(deco32_state::deco32_spriteram_r)
+READ32_MEMBER(deco32_state::spriteram_r)
{
return m_spriteram16[offset] ^ 0xffff0000;
}
-WRITE32_MEMBER(deco32_state::deco32_spriteram_w)
+WRITE32_MEMBER(deco32_state::spriteram_w)
{
data &= 0x0000ffff;
mem_mask &= 0x0000ffff;
COMBINE_DATA(&m_spriteram16[offset]);
}
-WRITE32_MEMBER(deco32_state::deco32_buffer_spriteram_w)
+WRITE32_MEMBER(deco32_state::buffer_spriteram_w)
{
memcpy(m_spriteram16_buffered, m_spriteram16, 0x1000);
}
-READ32_MEMBER(deco32_state::deco32_spriteram2_r)
+READ32_MEMBER(deco32_state::spriteram2_r)
{
return m_spriteram16_2[offset] ^ 0xffff0000;
}
-WRITE32_MEMBER(deco32_state::deco32_spriteram2_w)
+WRITE32_MEMBER(deco32_state::spriteram2_w)
{
data &= 0x0000ffff;
mem_mask &= 0x0000ffff;
COMBINE_DATA(&m_spriteram16_2[offset]);
}
-WRITE32_MEMBER(deco32_state::deco32_buffer_spriteram2_w)
+WRITE32_MEMBER(deco32_state::buffer_spriteram2_w)
{
memcpy(m_spriteram16_2_buffered, m_spriteram16_2, 0x1000);
}
// tattass tests these as 32-bit ram, even if only 16-bits are hooked up to the tilemap chip - does it mirror parts of the dword?
-WRITE32_MEMBER(deco32_state::deco32_pf1_rowscroll_w){ COMBINE_DATA(&m_pf1_rowscroll32[offset]); data &= 0x0000ffff; mem_mask &= 0x0000ffff; COMBINE_DATA(&m_pf1_rowscroll[offset]); }
-WRITE32_MEMBER(deco32_state::deco32_pf2_rowscroll_w){ COMBINE_DATA(&m_pf2_rowscroll32[offset]); data &= 0x0000ffff; mem_mask &= 0x0000ffff; COMBINE_DATA(&m_pf2_rowscroll[offset]); }
-WRITE32_MEMBER(deco32_state::deco32_pf3_rowscroll_w){ COMBINE_DATA(&m_pf3_rowscroll32[offset]); data &= 0x0000ffff; mem_mask &= 0x0000ffff; COMBINE_DATA(&m_pf3_rowscroll[offset]); }
-WRITE32_MEMBER(deco32_state::deco32_pf4_rowscroll_w){ COMBINE_DATA(&m_pf4_rowscroll32[offset]); data &= 0x0000ffff; mem_mask &= 0x0000ffff; COMBINE_DATA(&m_pf4_rowscroll[offset]); }
+WRITE32_MEMBER(deco32_state::pf1_rowscroll_w){ COMBINE_DATA(&m_pf1_rowscroll32[offset]); data &= 0x0000ffff; mem_mask &= 0x0000ffff; COMBINE_DATA(&m_pf1_rowscroll[offset]); }
+WRITE32_MEMBER(deco32_state::pf2_rowscroll_w){ COMBINE_DATA(&m_pf2_rowscroll32[offset]); data &= 0x0000ffff; mem_mask &= 0x0000ffff; COMBINE_DATA(&m_pf2_rowscroll[offset]); }
+WRITE32_MEMBER(deco32_state::pf3_rowscroll_w){ COMBINE_DATA(&m_pf3_rowscroll32[offset]); data &= 0x0000ffff; mem_mask &= 0x0000ffff; COMBINE_DATA(&m_pf3_rowscroll[offset]); }
+WRITE32_MEMBER(deco32_state::pf4_rowscroll_w){ COMBINE_DATA(&m_pf4_rowscroll32[offset]); data &= 0x0000ffff; mem_mask &= 0x0000ffff; COMBINE_DATA(&m_pf4_rowscroll[offset]); }
static ADDRESS_MAP_START( captaven_map, AS_PROGRAM, 32, deco32_state )
AM_RANGE(0x000000, 0x0fffff) AM_ROM
- AM_RANGE(0x100000, 0x100007) AM_READ(deco32_71_r)
- AM_RANGE(0x100000, 0x100003) AM_WRITE(deco32_buffer_spriteram_w)
+ AM_RANGE(0x100000, 0x100007) AM_READ(_71_r)
+ AM_RANGE(0x100000, 0x100003) AM_WRITE(buffer_spriteram_w)
AM_RANGE(0x108000, 0x108003) AM_WRITENOP /* ? */
- AM_RANGE(0x110000, 0x111fff) AM_READWRITE(deco32_spriteram_r, deco32_spriteram_w)
+ AM_RANGE(0x110000, 0x111fff) AM_READWRITE(spriteram_r, spriteram_w)
AM_RANGE(0x120000, 0x127fff) AM_RAM AM_SHARE("ram") /* Main RAM */
// AM_RANGE(0x128000, 0x128fff) AM_DEVREAD("ioprot", deco146_device,captaven_prot_r)
-// AM_RANGE(0x1280c8, 0x1280cb) AM_WRITE(deco32_sound_w)
+// AM_RANGE(0x1280c8, 0x1280cb) AM_WRITE(sound_w)
AM_RANGE(0x128000, 0x12ffff) AM_READWRITE16(dg_protection_region_0_146_r, dg_protection_region_0_146_w, 0x0000ffff)
- AM_RANGE(0x130000, 0x131fff) AM_RAM_WRITE(deco32_nonbuffered_palette_w) AM_SHARE("paletteram") /* Palette RAM */
- AM_RANGE(0x148000, 0x14800f) AM_READWRITE(deco32_irq_controller_r, deco32_irq_controller_w)
+ AM_RANGE(0x130000, 0x131fff) AM_RAM_WRITE(nonbuffered_palette_w) AM_SHARE("paletteram") /* Palette RAM */
+ AM_RANGE(0x148000, 0x14800f) AM_READWRITE(irq_controller_r, irq_controller_w)
AM_RANGE(0x160000, 0x167fff) AM_RAM /* Extra work RAM */
AM_RANGE(0x168000, 0x168003) AM_READ(captaven_soundcpu_r)
- AM_RANGE(0x178000, 0x178003) AM_WRITE(deco32_pri_w)
+ AM_RANGE(0x178000, 0x178003) AM_WRITE(pri_w)
AM_RANGE(0x180000, 0x18001f) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf_control_dword_r, pf_control_dword_w)
AM_RANGE(0x190000, 0x191fff) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf1_data_dword_r, pf1_data_dword_w)
AM_RANGE(0x192000, 0x193fff) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf1_data_dword_r, pf1_data_dword_w) /* Mirror address - bug in program code */
AM_RANGE(0x194000, 0x195fff) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf2_data_dword_r, pf2_data_dword_w)
- AM_RANGE(0x1a0000, 0x1a3fff) AM_RAM_WRITE(deco32_pf1_rowscroll_w) AM_SHARE("pf1_rowscroll32")
- AM_RANGE(0x1a4000, 0x1a5fff) AM_RAM_WRITE(deco32_pf2_rowscroll_w) AM_SHARE("pf2_rowscroll32")
+ AM_RANGE(0x1a0000, 0x1a3fff) AM_RAM_WRITE(pf1_rowscroll_w) AM_SHARE("pf1_rowscroll32")
+ AM_RANGE(0x1a4000, 0x1a5fff) AM_RAM_WRITE(pf2_rowscroll_w) AM_SHARE("pf2_rowscroll32")
AM_RANGE(0x1c0000, 0x1c001f) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf_control_dword_r, pf_control_dword_w)
AM_RANGE(0x1d0000, 0x1d1fff) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf1_data_dword_r, pf1_data_dword_w)
AM_RANGE(0x1d4000, 0x1d5fff) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf2_data_dword_r, pf2_data_dword_w) // unused
- AM_RANGE(0x1e0000, 0x1e3fff) AM_RAM_WRITE(deco32_pf3_rowscroll_w) AM_SHARE("pf3_rowscroll32")
- AM_RANGE(0x1e4000, 0x1e5fff) AM_RAM_WRITE(deco32_pf4_rowscroll_w) AM_SHARE("pf4_rowscroll32") // unused
+ AM_RANGE(0x1e0000, 0x1e3fff) AM_RAM_WRITE(pf3_rowscroll_w) AM_SHARE("pf3_rowscroll32")
+ AM_RANGE(0x1e4000, 0x1e5fff) AM_RAM_WRITE(pf4_rowscroll_w) AM_SHARE("pf4_rowscroll32") // unused
ADDRESS_MAP_END
@@ -708,31 +706,31 @@ WRITE32_MEMBER( deco32_state::fghthist_protection_region_0_146_w )
static ADDRESS_MAP_START( fghthist_map, AS_PROGRAM, 32, deco32_state )
-// AM_RANGE(0x000000, 0x001fff) AM_ROM AM_WRITE(deco32_pf1_data_w) // wtf??
+// AM_RANGE(0x000000, 0x001fff) AM_ROM AM_WRITE(pf1_data_w) // wtf??
AM_RANGE(0x000000, 0x0fffff) AM_ROM
AM_RANGE(0x100000, 0x11ffff) AM_RAM AM_SHARE("ram")
AM_RANGE(0x120020, 0x12002f) AM_READ(fghthist_control_r)
AM_RANGE(0x12002c, 0x12002f) AM_WRITE(fghthist_eeprom_w)
- AM_RANGE(0x1201fc, 0x1201ff) AM_WRITE(deco32_sound_w)
+ AM_RANGE(0x1201fc, 0x1201ff) AM_WRITE(sound_w)
AM_RANGE(0x140000, 0x140003) AM_WRITENOP /* VBL irq ack */
- AM_RANGE(0x168000, 0x169fff) AM_RAM_WRITE(deco32_buffered_palette_w) AM_SHARE("paletteram")
- AM_RANGE(0x16c008, 0x16c00b) AM_WRITE(deco32_palette_dma_w)
+ AM_RANGE(0x168000, 0x169fff) AM_RAM_WRITE(buffered_palette_w) AM_SHARE("paletteram")
+ AM_RANGE(0x16c008, 0x16c00b) AM_WRITE(palette_dma_w)
//
- AM_RANGE(0x178000, 0x179fff) AM_READWRITE(deco32_spriteram_r, deco32_spriteram_w)
- AM_RANGE(0x17c010, 0x17c013) AM_WRITE(deco32_buffer_spriteram_w)
+ AM_RANGE(0x178000, 0x179fff) AM_READWRITE(spriteram_r, spriteram_w)
+ AM_RANGE(0x17c010, 0x17c013) AM_WRITE(buffer_spriteram_w)
AM_RANGE(0x182000, 0x183fff) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf1_data_dword_r, pf1_data_dword_w)
AM_RANGE(0x184000, 0x185fff) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf2_data_dword_r, pf2_data_dword_w)
- AM_RANGE(0x192000, 0x193fff) AM_RAM_WRITE(deco32_pf1_rowscroll_w) AM_SHARE("pf1_rowscroll32")
- AM_RANGE(0x194000, 0x195fff) AM_RAM_WRITE(deco32_pf2_rowscroll_w) AM_SHARE("pf2_rowscroll32")
+ AM_RANGE(0x192000, 0x193fff) AM_RAM_WRITE(pf1_rowscroll_w) AM_SHARE("pf1_rowscroll32")
+ AM_RANGE(0x194000, 0x195fff) AM_RAM_WRITE(pf2_rowscroll_w) AM_SHARE("pf2_rowscroll32")
AM_RANGE(0x1a0000, 0x1a001f) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf_control_dword_r, pf_control_dword_w)
AM_RANGE(0x1c2000, 0x1c3fff) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf1_data_dword_r, pf1_data_dword_w)
AM_RANGE(0x1c4000, 0x1c5fff) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf2_data_dword_r, pf2_data_dword_w)
- AM_RANGE(0x1d2000, 0x1d3fff) AM_RAM_WRITE(deco32_pf3_rowscroll_w) AM_SHARE("pf3_rowscroll32")
- AM_RANGE(0x1d4000, 0x1d5fff) AM_RAM_WRITE(deco32_pf4_rowscroll_w) AM_SHARE("pf4_rowscroll32")
+ AM_RANGE(0x1d2000, 0x1d3fff) AM_RAM_WRITE(pf3_rowscroll_w) AM_SHARE("pf3_rowscroll32")
+ AM_RANGE(0x1d4000, 0x1d5fff) AM_RAM_WRITE(pf4_rowscroll_w) AM_SHARE("pf4_rowscroll32")
AM_RANGE(0x1e0000, 0x1e001f) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf_control_dword_r, pf_control_dword_w)
AM_RANGE(0x16c000, 0x16c01f) AM_READNOP
@@ -748,24 +746,24 @@ static ADDRESS_MAP_START( fghthsta_memmap, AS_PROGRAM, 32, deco32_state )
AM_RANGE(0x140000, 0x140003) AM_WRITENOP /* VBL irq ack */
AM_RANGE(0x150000, 0x150003) AM_WRITE(fghthist_eeprom_w) /* Volume port/Eprom */
- AM_RANGE(0x168000, 0x169fff) AM_RAM_WRITE(deco32_buffered_palette_w) AM_SHARE("paletteram")
- AM_RANGE(0x16c008, 0x16c00b) AM_WRITE(deco32_palette_dma_w)
+ AM_RANGE(0x168000, 0x169fff) AM_RAM_WRITE(buffered_palette_w) AM_SHARE("paletteram")
+ AM_RANGE(0x16c008, 0x16c00b) AM_WRITE(palette_dma_w)
AM_RANGE(0x16c010, 0x16c013) AM_READNOP
- AM_RANGE(0x178000, 0x179fff) AM_READWRITE(deco32_spriteram_r, deco32_spriteram_w)
- AM_RANGE(0x17c010, 0x17c013) AM_WRITE(deco32_buffer_spriteram_w)
+ AM_RANGE(0x178000, 0x179fff) AM_READWRITE(spriteram_r, spriteram_w)
+ AM_RANGE(0x17c010, 0x17c013) AM_WRITE(buffer_spriteram_w)
AM_RANGE(0x17c020, 0x17c023) AM_READNOP
AM_RANGE(0x182000, 0x183fff) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf1_data_dword_r, pf1_data_dword_w)
AM_RANGE(0x184000, 0x185fff) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf2_data_dword_r, pf2_data_dword_w)
- AM_RANGE(0x192000, 0x193fff) AM_RAM_WRITE(deco32_pf1_rowscroll_w) AM_SHARE("pf1_rowscroll32")
- AM_RANGE(0x194000, 0x195fff) AM_RAM_WRITE(deco32_pf2_rowscroll_w) AM_SHARE("pf2_rowscroll32")
+ AM_RANGE(0x192000, 0x193fff) AM_RAM_WRITE(pf1_rowscroll_w) AM_SHARE("pf1_rowscroll32")
+ AM_RANGE(0x194000, 0x195fff) AM_RAM_WRITE(pf2_rowscroll_w) AM_SHARE("pf2_rowscroll32")
AM_RANGE(0x1a0000, 0x1a001f) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf_control_dword_r, pf_control_dword_w)
AM_RANGE(0x1c2000, 0x1c3fff) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf1_data_dword_r, pf1_data_dword_w)
AM_RANGE(0x1c4000, 0x1c5fff) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf2_data_dword_r, pf2_data_dword_w)
- AM_RANGE(0x1d2000, 0x1d3fff) AM_RAM_WRITE(deco32_pf3_rowscroll_w) AM_SHARE("pf3_rowscroll32")
- AM_RANGE(0x1d4000, 0x1d5fff) AM_RAM_WRITE(deco32_pf4_rowscroll_w) AM_SHARE("pf4_rowscroll32")
+ AM_RANGE(0x1d2000, 0x1d3fff) AM_RAM_WRITE(pf3_rowscroll_w) AM_SHARE("pf3_rowscroll32")
+ AM_RANGE(0x1d4000, 0x1d5fff) AM_RAM_WRITE(pf4_rowscroll_w) AM_SHARE("pf4_rowscroll32")
AM_RANGE(0x1e0000, 0x1e001f) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf_control_dword_r, pf_control_dword_w)
AM_RANGE(0x200000, 0x207fff) AM_READWRITE(fghthist_protection_region_0_146_r, fghthist_protection_region_0_146_w) AM_SHARE("prot32ram") // only maps on 16-bits
@@ -790,7 +788,7 @@ WRITE16_MEMBER( deco32_state::dg_protection_region_0_146_w )
m_deco146->write_data( space, deco146_addr, data, mem_mask, cs );
}
-READ32_MEMBER( dragngun_state::dragngun_unk_video_r)
+READ32_MEMBER( dragngun_state::unk_video_r)
{
return machine().rand();
}
@@ -803,11 +801,11 @@ static ADDRESS_MAP_START( dragngun_map, AS_PROGRAM, 32, dragngun_state )
// AM_RANGE(0x0120000, 0x0120fff) AM_DEVREAD("ioprot", deco146_device, dragngun_prot_r)
AM_RANGE(0x0120000, 0x0127fff) AM_READWRITE16(dg_protection_region_0_146_r, dg_protection_region_0_146_w, 0x0000ffff)
-// AM_RANGE(0x01204c0, 0x01204c3) AM_WRITE(deco32_sound_w)
- AM_RANGE(0x0128000, 0x012800f) AM_READWRITE(deco32_irq_controller_r, deco32_irq_controller_w)
- AM_RANGE(0x0130000, 0x0131fff) AM_RAM_WRITE(deco32_buffered_palette_w) AM_SHARE("paletteram")
+// AM_RANGE(0x01204c0, 0x01204c3) AM_WRITE(sound_w)
+ AM_RANGE(0x0128000, 0x012800f) AM_READWRITE(irq_controller_r, irq_controller_w)
+ AM_RANGE(0x0130000, 0x0131fff) AM_RAM_WRITE(buffered_palette_w) AM_SHARE("paletteram")
AM_RANGE(0x0138000, 0x0138003) AM_NOP /* Palette dma complete in bit 0x8? ack? return 0 else tight loop */
- AM_RANGE(0x0138008, 0x013800b) AM_WRITE(deco32_palette_dma_w)
+ AM_RANGE(0x0138008, 0x013800b) AM_WRITE(palette_dma_w)
AM_RANGE(0x0170100, 0x0170103) AM_WRITENOP
AM_RANGE(0x0170038, 0x017003b) AM_WRITENOP
@@ -817,41 +815,41 @@ static ADDRESS_MAP_START( dragngun_map, AS_PROGRAM, 32, dragngun_state )
AM_RANGE(0x0180000, 0x018001f) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf_control_dword_r, pf_control_dword_w)
AM_RANGE(0x0190000, 0x0191fff) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf1_data_dword_r, pf1_data_dword_w)
AM_RANGE(0x0194000, 0x0195fff) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf2_data_dword_r, pf2_data_dword_w)
- AM_RANGE(0x01a0000, 0x01a3fff) AM_RAM_WRITE(deco32_pf1_rowscroll_w) AM_SHARE("pf1_rowscroll32")
- AM_RANGE(0x01a4000, 0x01a5fff) AM_RAM_WRITE(deco32_pf2_rowscroll_w) AM_SHARE("pf2_rowscroll32")
+ AM_RANGE(0x01a0000, 0x01a3fff) AM_RAM_WRITE(pf1_rowscroll_w) AM_SHARE("pf1_rowscroll32")
+ AM_RANGE(0x01a4000, 0x01a5fff) AM_RAM_WRITE(pf2_rowscroll_w) AM_SHARE("pf2_rowscroll32")
AM_RANGE(0x01c0000, 0x01c001f) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf_control_dword_r, pf_control_dword_w)
AM_RANGE(0x01d0000, 0x01d1fff) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf1_data_dword_r, pf1_data_dword_w)
AM_RANGE(0x01d4000, 0x01d5fff) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf2_data_dword_r, pf2_data_dword_w) // unused
- AM_RANGE(0x01e0000, 0x01e3fff) AM_RAM_WRITE(deco32_pf3_rowscroll_w) AM_SHARE("pf3_rowscroll32")
- AM_RANGE(0x01e4000, 0x01e5fff) AM_RAM_WRITE(deco32_pf4_rowscroll_w) AM_SHARE("pf4_rowscroll32") // unused
+ AM_RANGE(0x01e0000, 0x01e3fff) AM_RAM_WRITE(pf3_rowscroll_w) AM_SHARE("pf3_rowscroll32")
+ AM_RANGE(0x01e4000, 0x01e5fff) AM_RAM_WRITE(pf4_rowscroll_w) AM_SHARE("pf4_rowscroll32") // unused
AM_RANGE(0x0204800, 0x0204fff) AM_RAM // ace? 0x10 byte increments only // 13f ff stuff
- AM_RANGE(0x0208000, 0x0208fff) AM_RAM AM_SHARE("dragngun_lay0")
- AM_RANGE(0x020c000, 0x020cfff) AM_RAM AM_SHARE("dragngun_lay1")
- AM_RANGE(0x0210000, 0x0217fff) AM_RAM AM_SHARE("dragngun_look0")
- AM_RANGE(0x0218000, 0x021ffff) AM_RAM AM_SHARE("dragngun_look1")
+ AM_RANGE(0x0208000, 0x0208fff) AM_RAM AM_SHARE("lay0")
+ AM_RANGE(0x020c000, 0x020cfff) AM_RAM AM_SHARE("lay1")
+ AM_RANGE(0x0210000, 0x0217fff) AM_RAM AM_SHARE("look0")
+ AM_RANGE(0x0218000, 0x021ffff) AM_RAM AM_SHARE("look1")
AM_RANGE(0x0220000, 0x0221fff) AM_RAM AM_SHARE("spriteram") /* Main spriteram */
AM_RANGE(0x0228000, 0x02283ff) AM_RAM //0x10 byte increments only
- AM_RANGE(0x0230000, 0x0230003) AM_WRITE(dragngun_spriteram_dma_w)
+ AM_RANGE(0x0230000, 0x0230003) AM_WRITE(spriteram_dma_w)
AM_RANGE(0x0300000, 0x03fffff) AM_ROM
AM_RANGE(0x0400000, 0x0400003) AM_DEVREADWRITE8("oki3", okim6295_device, read, write, 0x000000ff)
AM_RANGE(0x0410000, 0x0410003) AM_WRITENOP /* Some kind of serial bit-stream - digital volume control? */
- AM_RANGE(0x0420000, 0x0420003) AM_READWRITE(dragngun_eeprom_r, dragngun_eeprom_w)
- AM_RANGE(0x0438000, 0x0438003) AM_READ(dragngun_lightgun_r)
- AM_RANGE(0x0430000, 0x043001f) AM_WRITE(dragngun_lightgun_w)
- AM_RANGE(0x0440000, 0x0440003) AM_READ(dragngun_service_r)
+ AM_RANGE(0x0420000, 0x0420003) AM_READWRITE(eeprom_r, eeprom_w)
+ AM_RANGE(0x0438000, 0x0438003) AM_READ(lightgun_r)
+ AM_RANGE(0x0430000, 0x043001f) AM_WRITE(lightgun_w)
+ AM_RANGE(0x0440000, 0x0440003) AM_READ(service_r)
- AM_RANGE(0x0500000, 0x0500003) AM_WRITE(dragngun_sprite_control_w)
+ AM_RANGE(0x0500000, 0x0500003) AM_WRITE(sprite_control_w)
// this is clearly the dvi video related area
- AM_RANGE(0x1000000, 0x1000007) AM_READ(dragngun_unk_video_r)
+ AM_RANGE(0x1000000, 0x1000007) AM_READ(unk_video_r)
AM_RANGE(0x1000100, 0x1007fff) AM_RAM
AM_RANGE(0x10b0000, 0x10b01ff) AM_RAM
AM_RANGE(0x1400000, 0x1ffffff) AM_ROM AM_REGION("dvi", 0x00000) // reads from here during boss battles when the videos should be displayed at the offsets where the DVI headers are
@@ -863,14 +861,14 @@ static ADDRESS_MAP_START( lockload_map, AS_PROGRAM, 32, dragngun_state )
AM_RANGE(0x000000, 0x0fffff) AM_ROM
AM_RANGE(0x100000, 0x11ffff) AM_RAM AM_SHARE("ram")
// AM_RANGE(0x120000, 0x120fff) AM_DEVREAD("ioprot", deco146_device, dragngun_prot_r)
-// AM_RANGE(0x1204c0, 0x1204c3) AM_WRITE(deco32_sound_w)
+// AM_RANGE(0x1204c0, 0x1204c3) AM_WRITE(sound_w)
AM_RANGE(0x120000, 0x127fff) AM_READWRITE16(dg_protection_region_0_146_r, dg_protection_region_0_146_w, 0x0000ffff)
- AM_RANGE(0x128000, 0x12800f) AM_READWRITE(deco32_irq_controller_r, deco32_irq_controller_w)
+ AM_RANGE(0x128000, 0x12800f) AM_READWRITE(irq_controller_r, irq_controller_w)
- AM_RANGE(0x130000, 0x131fff) AM_RAM_WRITE(deco32_buffered_palette_w) AM_SHARE("paletteram")
+ AM_RANGE(0x130000, 0x131fff) AM_RAM_WRITE(buffered_palette_w) AM_SHARE("paletteram")
AM_RANGE(0x138000, 0x138003) AM_READONLY AM_WRITENOP //palette dma complete in bit 0x8? ack? return 0 else tight loop
- AM_RANGE(0x138008, 0x13800b) AM_WRITE(deco32_palette_dma_w)
+ AM_RANGE(0x138008, 0x13800b) AM_WRITE(palette_dma_w)
AM_RANGE(0x170000, 0x170007) AM_READ(lockload_gun_mirror_r) /* Not on Dragongun */
AM_RANGE(0x178008, 0x17800f) AM_WRITENOP /* Gun read ACK's */
@@ -878,33 +876,33 @@ static ADDRESS_MAP_START( lockload_map, AS_PROGRAM, 32, dragngun_state )
AM_RANGE(0x180000, 0x18001f) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf_control_dword_r, pf_control_dword_w)
AM_RANGE(0x190000, 0x191fff) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf1_data_dword_r, pf1_data_dword_w)
AM_RANGE(0x194000, 0x195fff) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf2_data_dword_r, pf2_data_dword_w)
- AM_RANGE(0x1a0000, 0x1a3fff) AM_RAM_WRITE(deco32_pf1_rowscroll_w) AM_SHARE("pf1_rowscroll32")
- AM_RANGE(0x1a4000, 0x1a5fff) AM_RAM_WRITE(deco32_pf2_rowscroll_w) AM_SHARE("pf2_rowscroll32")
+ AM_RANGE(0x1a0000, 0x1a3fff) AM_RAM_WRITE(pf1_rowscroll_w) AM_SHARE("pf1_rowscroll32")
+ AM_RANGE(0x1a4000, 0x1a5fff) AM_RAM_WRITE(pf2_rowscroll_w) AM_SHARE("pf2_rowscroll32")
AM_RANGE(0x1c0000, 0x1c001f) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf_control_dword_r, pf_control_dword_w)
AM_RANGE(0x1d0000, 0x1d1fff) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf1_data_dword_r, pf1_data_dword_w)
AM_RANGE(0x1d4000, 0x1d5fff) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf2_data_dword_r, pf2_data_dword_w) // unused
- AM_RANGE(0x1e0000, 0x1e3fff) AM_RAM_WRITE(deco32_pf3_rowscroll_w) AM_SHARE("pf3_rowscroll32")
- AM_RANGE(0x1e4000, 0x1e5fff) AM_RAM_WRITE(deco32_pf4_rowscroll_w) AM_SHARE("pf4_rowscroll32") // unused
+ AM_RANGE(0x1e0000, 0x1e3fff) AM_RAM_WRITE(pf3_rowscroll_w) AM_SHARE("pf3_rowscroll32")
+ AM_RANGE(0x1e4000, 0x1e5fff) AM_RAM_WRITE(pf4_rowscroll_w) AM_SHARE("pf4_rowscroll32") // unused
AM_RANGE(0x204800, 0x204fff) AM_RAM //0x10 byte increments only
- AM_RANGE(0x208000, 0x208fff) AM_RAM AM_SHARE("dragngun_lay0")
- AM_RANGE(0x20c000, 0x20cfff) AM_RAM AM_SHARE("dragngun_lay1")
- AM_RANGE(0x210000, 0x217fff) AM_RAM AM_SHARE("dragngun_look0")
- AM_RANGE(0x218000, 0x21ffff) AM_RAM AM_SHARE("dragngun_look1")
+ AM_RANGE(0x208000, 0x208fff) AM_RAM AM_SHARE("lay0")
+ AM_RANGE(0x20c000, 0x20cfff) AM_RAM AM_SHARE("lay1")
+ AM_RANGE(0x210000, 0x217fff) AM_RAM AM_SHARE("look0")
+ AM_RANGE(0x218000, 0x21ffff) AM_RAM AM_SHARE("look1")
AM_RANGE(0x220000, 0x221fff) AM_RAM AM_SHARE("spriteram") /* Main spriteram */
AM_RANGE(0x228000, 0x2283ff) AM_RAM //0x10 byte increments only
- AM_RANGE(0x230000, 0x230003) AM_WRITE(dragngun_spriteram_dma_w)
+ AM_RANGE(0x230000, 0x230003) AM_WRITE(spriteram_dma_w)
AM_RANGE(0x300000, 0x3fffff) AM_ROM
// AM_RANGE(0x400000, 0x400003) AM_DEVREADWRITE8("oki3", okim6295_device, read, write, 0x000000ff)
- AM_RANGE(0x420000, 0x420003) AM_READWRITE(dragngun_eeprom_r, dragngun_eeprom_w)
-// AM_RANGE(0x430000, 0x43001f) AM_WRITE(dragngun_lightgun_w)
-// AM_RANGE(0x438000, 0x438003) AM_READ(dragngun_lightgun_r)
- AM_RANGE(0x440000, 0x440003) AM_READ(dragngun_service_r)
- AM_RANGE(0x500000, 0x500003) AM_WRITE(dragngun_sprite_control_w)
+ AM_RANGE(0x420000, 0x420003) AM_READWRITE(eeprom_r, eeprom_w)
+// AM_RANGE(0x430000, 0x43001f) AM_WRITE(lightgun_w)
+// AM_RANGE(0x438000, 0x438003) AM_READ(lightgun_r)
+ AM_RANGE(0x440000, 0x440003) AM_READ(service_r)
+ AM_RANGE(0x500000, 0x500003) AM_WRITE(sprite_control_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( tattass_map, AS_PROGRAM, 32, deco32_state )
@@ -918,38 +916,37 @@ static ADDRESS_MAP_START( tattass_map, AS_PROGRAM, 32, deco32_state )
AM_RANGE(0x150000, 0x150003) AM_WRITE(tattass_control_w) /* Volume port/Eprom/Priority */
AM_RANGE(0x162000, 0x162fff) AM_RAM /* 'Jack' RAM!? */
- AM_RANGE(0x163000, 0x16309f) AM_RAM_WRITE(deco32_ace_ram_w) AM_SHARE("ace_ram")
+ AM_RANGE(0x163000, 0x16309f) AM_RAM_WRITE(ace_ram_w) AM_SHARE("ace_ram")
AM_RANGE(0x164000, 0x164003) AM_WRITENOP /* Palette control BG2/3 ($1a constant) */
AM_RANGE(0x164004, 0x164007) AM_WRITENOP /* Palette control Obj1 ($6 constant) */
AM_RANGE(0x164008, 0x16400b) AM_WRITENOP /* Palette control Obj2 ($5 constant) */
AM_RANGE(0x16400c, 0x16400f) AM_WRITENOP
- AM_RANGE(0x168000, 0x169fff) AM_RAM_WRITE(deco32_buffered_palette_w) AM_SHARE("paletteram")
+ AM_RANGE(0x168000, 0x169fff) AM_RAM_WRITE(buffered_palette_w) AM_SHARE("paletteram")
AM_RANGE(0x16c000, 0x16c003) AM_WRITENOP
- AM_RANGE(0x16c008, 0x16c00b) AM_WRITE(deco32_palette_dma_w)
+ AM_RANGE(0x16c008, 0x16c00b) AM_WRITE(palette_dma_w)
- AM_RANGE(0x170000, 0x171fff) AM_READWRITE(deco32_spriteram_r, deco32_spriteram_w)
+ AM_RANGE(0x170000, 0x171fff) AM_READWRITE(spriteram_r, spriteram_w)
AM_RANGE(0x174000, 0x174003) AM_WRITENOP /* Sprite DMA mode (2) */
- AM_RANGE(0x174010, 0x174013) AM_WRITE(deco32_buffer_spriteram_w)
+ AM_RANGE(0x174010, 0x174013) AM_WRITE(buffer_spriteram_w)
AM_RANGE(0x174018, 0x17401b) AM_WRITENOP /* Sprite 'CPU' (unused) */
- AM_RANGE(0x178000, 0x179fff) AM_READWRITE(deco32_spriteram2_r, deco32_spriteram2_w)
+ AM_RANGE(0x178000, 0x179fff) AM_READWRITE(spriteram2_r, spriteram2_w)
AM_RANGE(0x17c000, 0x17c003) AM_WRITENOP /* Sprite DMA mode (2) */
- AM_RANGE(0x17c010, 0x17c013) AM_WRITE(deco32_buffer_spriteram2_w)
+ AM_RANGE(0x17c010, 0x17c013) AM_WRITE(buffer_spriteram2_w)
AM_RANGE(0x17c018, 0x17c01b) AM_WRITENOP /* Sprite 'CPU' (unused) */
AM_RANGE(0x182000, 0x183fff) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf1_data_dword_r, pf1_data_dword_w)
AM_RANGE(0x184000, 0x185fff) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf2_data_dword_r, pf2_data_dword_w)
- AM_RANGE(0x192000, 0x193fff) AM_RAM_WRITE(deco32_pf1_rowscroll_w) AM_SHARE("pf1_rowscroll32")
- AM_RANGE(0x194000, 0x195fff) AM_RAM_WRITE(deco32_pf2_rowscroll_w) AM_SHARE("pf2_rowscroll32")
+ AM_RANGE(0x192000, 0x193fff) AM_RAM_WRITE(pf1_rowscroll_w) AM_SHARE("pf1_rowscroll32")
+ AM_RANGE(0x194000, 0x195fff) AM_RAM_WRITE(pf2_rowscroll_w) AM_SHARE("pf2_rowscroll32")
AM_RANGE(0x1a0000, 0x1a001f) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf_control_dword_r, pf_control_dword_w)
AM_RANGE(0x1c2000, 0x1c3fff) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf1_data_dword_r, pf1_data_dword_w)
AM_RANGE(0x1c4000, 0x1c5fff) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf2_data_dword_r, pf2_data_dword_w)
- AM_RANGE(0x1d2000, 0x1d3fff) AM_RAM_WRITE(deco32_pf3_rowscroll_w) AM_SHARE("pf3_rowscroll32")
- AM_RANGE(0x1d4000, 0x1d5fff) AM_RAM_WRITE(deco32_pf4_rowscroll_w) AM_SHARE("pf4_rowscroll32")
+ AM_RANGE(0x1d2000, 0x1d3fff) AM_RAM_WRITE(pf3_rowscroll_w) AM_SHARE("pf3_rowscroll32")
+ AM_RANGE(0x1d4000, 0x1d5fff) AM_RAM_WRITE(pf4_rowscroll_w) AM_SHARE("pf4_rowscroll32")
AM_RANGE(0x1e0000, 0x1e001f) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf_control_dword_r, pf_control_dword_w)
-// AM_RANGE(0x200000, 0x200fff) AM_READWRITE(tattass_prot_r, tattass_prot_w) AM_SHARE("prot32ram")
AM_RANGE(0x200000, 0x207fff) AM_READWRITE16(nslasher_protection_region_0_104_r, nslasher_protection_region_0_104_w, 0xffff0000)
AM_RANGE(0x200000, 0x207fff) AM_READ16(nslasher_debug_r, 0x0000ffff)
ADDRESS_MAP_END
@@ -984,38 +981,37 @@ static ADDRESS_MAP_START( nslasher_map, AS_PROGRAM, 32, deco32_state )
AM_RANGE(0x140000, 0x140003) AM_WRITENOP /* Vblank ack */
AM_RANGE(0x150000, 0x150003) AM_WRITE(nslasher_eeprom_w) /* Volume port/Eprom/Priority */
- AM_RANGE(0x163000, 0x16309f) AM_RAM_WRITE(deco32_ace_ram_w) AM_SHARE("ace_ram") /* 'Ace' RAM!? */
+ AM_RANGE(0x163000, 0x16309f) AM_RAM_WRITE(ace_ram_w) AM_SHARE("ace_ram") /* 'Ace' RAM!? */
AM_RANGE(0x164000, 0x164003) AM_WRITENOP /* Palette control BG2/3 ($1a constant) */
AM_RANGE(0x164004, 0x164007) AM_WRITENOP /* Palette control Obj1 ($4 constant) */
AM_RANGE(0x164008, 0x16400b) AM_WRITENOP /* Palette control Obj2 ($6 constant) */
AM_RANGE(0x16400c, 0x16400f) AM_WRITENOP
- AM_RANGE(0x168000, 0x169fff) AM_RAM_WRITE(deco32_buffered_palette_w) AM_SHARE("paletteram")
+ AM_RANGE(0x168000, 0x169fff) AM_RAM_WRITE(buffered_palette_w) AM_SHARE("paletteram")
AM_RANGE(0x16c000, 0x16c003) AM_WRITENOP
- AM_RANGE(0x16c008, 0x16c00b) AM_WRITE(deco32_palette_dma_w)
+ AM_RANGE(0x16c008, 0x16c00b) AM_WRITE(palette_dma_w)
- AM_RANGE(0x170000, 0x171fff) AM_READWRITE(deco32_spriteram_r, deco32_spriteram_w)
+ AM_RANGE(0x170000, 0x171fff) AM_READWRITE(spriteram_r, spriteram_w)
AM_RANGE(0x174000, 0x174003) AM_WRITENOP /* Sprite DMA mode (2) */
- AM_RANGE(0x174010, 0x174013) AM_WRITE(deco32_buffer_spriteram_w)
+ AM_RANGE(0x174010, 0x174013) AM_WRITE(buffer_spriteram_w)
AM_RANGE(0x174018, 0x17401b) AM_WRITENOP /* Sprite 'CPU' (unused) */
- AM_RANGE(0x178000, 0x179fff) AM_READWRITE(deco32_spriteram2_r, deco32_spriteram2_w)
+ AM_RANGE(0x178000, 0x179fff) AM_READWRITE(spriteram2_r, spriteram2_w)
AM_RANGE(0x17c000, 0x17c003) AM_WRITENOP /* Sprite DMA mode (2) */
- AM_RANGE(0x17c010, 0x17c013) AM_WRITE(deco32_buffer_spriteram2_w)
+ AM_RANGE(0x17c010, 0x17c013) AM_WRITE(buffer_spriteram2_w)
AM_RANGE(0x17c018, 0x17c01b) AM_WRITENOP /* Sprite 'CPU' (unused) */
AM_RANGE(0x182000, 0x183fff) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf1_data_dword_r, pf1_data_dword_w)
AM_RANGE(0x184000, 0x185fff) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf2_data_dword_r, pf2_data_dword_w)
- AM_RANGE(0x192000, 0x193fff) AM_RAM_WRITE(deco32_pf1_rowscroll_w) AM_SHARE("pf1_rowscroll32")
- AM_RANGE(0x194000, 0x195fff) AM_RAM_WRITE(deco32_pf2_rowscroll_w) AM_SHARE("pf2_rowscroll32")
+ AM_RANGE(0x192000, 0x193fff) AM_RAM_WRITE(pf1_rowscroll_w) AM_SHARE("pf1_rowscroll32")
+ AM_RANGE(0x194000, 0x195fff) AM_RAM_WRITE(pf2_rowscroll_w) AM_SHARE("pf2_rowscroll32")
AM_RANGE(0x1a0000, 0x1a001f) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf_control_dword_r, pf_control_dword_w)
AM_RANGE(0x1c2000, 0x1c3fff) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf1_data_dword_r, pf1_data_dword_w)
AM_RANGE(0x1c4000, 0x1c5fff) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf2_data_dword_r, pf2_data_dword_w)
- AM_RANGE(0x1d2000, 0x1d3fff) AM_RAM_WRITE(deco32_pf3_rowscroll_w) AM_SHARE("pf3_rowscroll32")
- AM_RANGE(0x1d4000, 0x1d5fff) AM_RAM_WRITE(deco32_pf4_rowscroll_w) AM_SHARE("pf4_rowscroll32")
+ AM_RANGE(0x1d2000, 0x1d3fff) AM_RAM_WRITE(pf3_rowscroll_w) AM_SHARE("pf3_rowscroll32")
+ AM_RANGE(0x1d4000, 0x1d5fff) AM_RAM_WRITE(pf4_rowscroll_w) AM_SHARE("pf4_rowscroll32")
AM_RANGE(0x1e0000, 0x1e001f) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf_control_dword_r, pf_control_dword_w)
-// AM_RANGE(0x200000, 0x200fff) AM_READWRITE(nslasher_prot_r, nslasher_prot_w) AM_SHARE("prot32ram")
AM_RANGE(0x200000, 0x207fff) AM_READWRITE16(nslasher_protection_region_0_104_r, nslasher_protection_region_0_104_w, 0xffff0000)
AM_RANGE(0x200000, 0x207fff) AM_READ16(nslasher_debug_r, 0x0000ffff) // seems to be debug switches / code activated by this?
@@ -1694,7 +1690,6 @@ static MACHINE_CONFIG_START( captaven, deco32_state )
MCFG_SCREEN_SIZE(42*8, 32*8)
MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1)
MCFG_SCREEN_UPDATE_DRIVER(deco32_state, screen_update_captaven)
- MCFG_SCREEN_VBLANK_DRIVER(deco32_state, screen_eof_captaven)
MCFG_SCREEN_PALETTE("palette")
MCFG_GFXDECODE_ADD("gfxdecode", "palette", captaven)
@@ -1989,7 +1984,6 @@ static MACHINE_CONFIG_START( dragngun, dragngun_state )
MCFG_SCREEN_SIZE(42*8, 32*8)
MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1)
MCFG_SCREEN_UPDATE_DRIVER(dragngun_state, screen_update_dragngun)
- MCFG_SCREEN_VBLANK_DRIVER(dragngun_state, screen_eof_dragngun)
//MCFG_SCREEN_PALETTE("palette")
MCFG_BUFFERED_SPRITERAM32_ADD("spriteram")
@@ -2062,7 +2056,7 @@ static MACHINE_CONFIG_START( dragngun, dragngun_state )
MACHINE_CONFIG_END
-TIMER_DEVICE_CALLBACK_MEMBER(deco32_state::lockload_vbl_irq)
+TIMER_DEVICE_CALLBACK_MEMBER(dragngun_state::lockload_vbl_irq)
{
int scanline = param;
@@ -2085,7 +2079,7 @@ static MACHINE_CONFIG_START( lockload, dragngun_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", ARM, 28000000/4)
MCFG_CPU_PROGRAM_MAP(lockload_map)
- MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", deco32_state, lockload_vbl_irq, "screen", 0, 1)
+ MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", dragngun_state, lockload_vbl_irq, "screen", 0, 1)
MCFG_CPU_ADD("audiocpu", Z80, 32220000/8)
MCFG_CPU_PROGRAM_MAP(nslasher_sound)
@@ -2104,7 +2098,6 @@ static MACHINE_CONFIG_START( lockload, dragngun_state )
MCFG_SCREEN_SIZE(42*8, 32*8+22)
MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1)
MCFG_SCREEN_UPDATE_DRIVER(dragngun_state, screen_update_dragngun)
- MCFG_SCREEN_VBLANK_DRIVER(dragngun_state, screen_eof_dragngun)
MCFG_BUFFERED_SPRITERAM32_ADD("spriteram")
@@ -3650,10 +3643,15 @@ DRIVER_INIT_MEMBER(deco32_state,captaven)
{
deco56_decrypt_gfx(machine(), "gfx1");
deco56_decrypt_gfx(machine(), "gfx2");
+
+ save_item(NAME(m_raster_enable));
+ save_item(NAME(m_nslasher_sound_irq));
+ save_item(NAME(m_irq_source));
}
extern void process_dvi_data(UINT8* dvi_data, int offset, int regionsize);
-void dragngun_state::init_dragngun_common()
+
+void dragngun_state::dragngun_init_common()
{
const UINT8 *SRC_RAM = memregion("gfx1")->base();
UINT8 *DST_RAM = memregion("gfx2")->base();
@@ -3681,6 +3679,10 @@ void dragngun_state::init_dragngun_common()
}
#endif
+ save_item(NAME(m_lightgun_port));
+ save_item(NAME(m_raster_enable));
+ save_item(NAME(m_irq_source));
+
// there are DVI headers at 0x000000, 0x580000, 0x800000, 0xB10000, 0xB80000
// process_dvi_data(memregion("dvi")->base(),0x000000, 0x1000000);
// process_dvi_data(memregion("dvi")->base(),0x580000, 0x1000000);
@@ -3691,7 +3693,7 @@ void dragngun_state::init_dragngun_common()
DRIVER_INIT_MEMBER(dragngun_state,dragngun)
{
- init_dragngun_common();
+ dragngun_init_common();
UINT32 *ROM = (UINT32 *)memregion("maincpu")->base();
ROM[0x1b32c/4]=0xe1a00000; // bl $ee000: NOP test switch lock
@@ -3699,7 +3701,7 @@ DRIVER_INIT_MEMBER(dragngun_state,dragngun)
DRIVER_INIT_MEMBER(dragngun_state,dragngunj)
{
- init_dragngun_common();
+ dragngun_init_common();
UINT32 *ROM = (UINT32 *)memregion("maincpu")->base();
ROM[0x1a1b4/4]=0xe1a00000; // bl $ee000: NOP test switch lock
@@ -3723,6 +3725,10 @@ DRIVER_INIT_MEMBER(dragngun_state,lockload)
memcpy(RAM+0x300000,RAM+0x100000,0x100000);
memset(RAM+0x100000,0,0x100000);
+
+ save_item(NAME(m_raster_enable));
+ save_item(NAME(m_nslasher_sound_irq));
+ save_item(NAME(m_irq_source));
// ROM[0x3fe3c0/4]=0xe1a00000;// NOP test switch lock
// ROM[0x3fe3cc/4]=0xe1a00000;// NOP test switch lock
@@ -3746,6 +3752,14 @@ DRIVER_INIT_MEMBER(deco32_state,tattass)
deco56_decrypt_gfx(machine(), "gfx1"); /* 141 */
deco56_decrypt_gfx(machine(), "gfx2"); /* 141 */
+
+ save_item(NAME(m_tattass_eprom_bit));
+ save_item(NAME(m_lastClock));
+ save_item(NAME(m_buffer));
+ save_item(NAME(m_bufPtr));
+ save_item(NAME(m_pendingCommand));
+ save_item(NAME(m_readBitCount));
+ save_item(NAME(m_byteAddr));
}
DRIVER_INIT_MEMBER(deco32_state,nslasher)
@@ -3769,6 +3783,8 @@ DRIVER_INIT_MEMBER(deco32_state,nslasher)
deco156_decrypt(machine());
soundlatch_setclearedvalue(0xff);
+
+ save_item(NAME(m_nslasher_sound_irq));
/* The board for Night Slashers is very close to the Fighter's History and
Tattoo Assassins boards, but has an encrypted ARM cpu. */
@@ -3776,35 +3792,35 @@ DRIVER_INIT_MEMBER(deco32_state,nslasher)
/**********************************************************************************/
-GAME( 1991, captaven, 0, captaven, captaven, deco32_state, captaven, ROT0, "Data East Corporation", "Captain America and The Avengers (Asia Rev 1.4)", 0 )
-GAME( 1991, captavena, captaven, captaven, captaven, deco32_state, captaven, ROT0, "Data East Corporation", "Captain America and The Avengers (Asia Rev 1.0)", 0 )
-GAME( 1991, captavene, captaven, captaven, captaven, deco32_state, captaven, ROT0, "Data East Corporation", "Captain America and The Avengers (UK Rev 1.4)", 0 )
-GAME( 1991, captavenu, captaven, captaven, captaven, deco32_state, captaven, ROT0, "Data East Corporation", "Captain America and The Avengers (US Rev 1.9)", 0 )
-GAME( 1991, captavenuu, captaven, captaven, captaven, deco32_state, captaven, ROT0, "Data East Corporation", "Captain America and The Avengers (US Rev 1.6)", 0 )
-GAME( 1991, captavenua, captaven, captaven, captaven, deco32_state, captaven, ROT0, "Data East Corporation", "Captain America and The Avengers (US Rev 1.4)", 0 )
-GAME( 1991, captavenj, captaven, captaven, captaven, deco32_state, captaven, ROT0, "Data East Corporation", "Captain America and The Avengers (Japan Rev 0.2)", 0 )
+GAME( 1991, captaven, 0, captaven, captaven, deco32_state, captaven, ROT0, "Data East Corporation", "Captain America and The Avengers (Asia Rev 1.4)", GAME_SUPPORTS_SAVE )
+GAME( 1991, captavena, captaven, captaven, captaven, deco32_state, captaven, ROT0, "Data East Corporation", "Captain America and The Avengers (Asia Rev 1.0)", GAME_SUPPORTS_SAVE )
+GAME( 1991, captavene, captaven, captaven, captaven, deco32_state, captaven, ROT0, "Data East Corporation", "Captain America and The Avengers (UK Rev 1.4)", GAME_SUPPORTS_SAVE )
+GAME( 1991, captavenu, captaven, captaven, captaven, deco32_state, captaven, ROT0, "Data East Corporation", "Captain America and The Avengers (US Rev 1.9)", GAME_SUPPORTS_SAVE )
+GAME( 1991, captavenuu, captaven, captaven, captaven, deco32_state, captaven, ROT0, "Data East Corporation", "Captain America and The Avengers (US Rev 1.6)", GAME_SUPPORTS_SAVE )
+GAME( 1991, captavenua, captaven, captaven, captaven, deco32_state, captaven, ROT0, "Data East Corporation", "Captain America and The Avengers (US Rev 1.4)", GAME_SUPPORTS_SAVE )
+GAME( 1991, captavenj, captaven, captaven, captaven, deco32_state, captaven, ROT0, "Data East Corporation", "Captain America and The Avengers (Japan Rev 0.2)", GAME_SUPPORTS_SAVE )
-GAME( 1993, fghthist, 0, fghthist, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (World ver 43-07, DE-0380-2 PCB)", 0 )
-GAME( 1993, fghthistu, fghthist, fghthsta, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (US ver 42-06, DE-0395-1 PCB)", 0 )
-GAME( 1993, fghthistua, fghthist, fghthsta, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (US ver 42-05, DE-0395-1 PCB)", 0 )
-GAME( 1993, fghthistub, fghthist, fghthist, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (US ver 42-03, DE-0380-2 PCB)", 0 )
-GAME( 1993, fghthistj, fghthist, fghthsta, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (Japan ver 41-07, DE-0395-1 PCB)", 0 )
-GAME( 1993, fghthistja, fghthist, fghthist, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (Japan ver 41-05, DE-0380-2 PCB)", 0 )
-GAME( 1993, fghthistjb, fghthist, fghthist, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (Japan ver 41-04, DE-0380-1 PCB)", 0 )
+GAME( 1993, fghthist, 0, fghthist, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (World ver 43-07, DE-0380-2 PCB)", GAME_SUPPORTS_SAVE )
+GAME( 1993, fghthistu, fghthist, fghthsta, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (US ver 42-06, DE-0395-1 PCB)", GAME_SUPPORTS_SAVE )
+GAME( 1993, fghthistua, fghthist, fghthsta, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (US ver 42-05, DE-0395-1 PCB)", GAME_SUPPORTS_SAVE )
+GAME( 1993, fghthistub, fghthist, fghthist, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (US ver 42-03, DE-0380-2 PCB)", GAME_SUPPORTS_SAVE )
+GAME( 1993, fghthistj, fghthist, fghthsta, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (Japan ver 41-07, DE-0395-1 PCB)", GAME_SUPPORTS_SAVE )
+GAME( 1993, fghthistja, fghthist, fghthist, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (Japan ver 41-05, DE-0380-2 PCB)", GAME_SUPPORTS_SAVE )
+GAME( 1993, fghthistjb, fghthist, fghthist, fghthist, deco32_state, fghthist, ROT0, "Data East Corporation", "Fighter's History (Japan ver 41-04, DE-0380-1 PCB)", GAME_SUPPORTS_SAVE )
-GAME( 1994, nslasher, 0, nslasher, nslasher, deco32_state, nslasher, ROT0, "Data East Corporation", "Night Slashers (Korea Rev 1.3)", GAME_IMPERFECT_GRAPHICS )
-GAME( 1994, nslasherj, nslasher, nslasher, nslasher, deco32_state, nslasher, ROT0, "Data East Corporation", "Night Slashers (Japan Rev 1.2)", GAME_IMPERFECT_GRAPHICS )
-GAME( 1994, nslashers, nslasher, nslasher, nslasher, deco32_state, nslasher, ROT0, "Data East Corporation", "Night Slashers (Over Sea Rev 1.2)", GAME_IMPERFECT_GRAPHICS )
-GAME( 1994, nslasheru, nslasher, nslasheru,nslasher, deco32_state, nslasher, ROT0, "Data East Corporation", "Night Slashers (US Rev 1.2, HuC6280 Sound CPU)", GAME_IMPERFECT_GRAPHICS )
+GAME( 1994, nslasher, 0, nslasher, nslasher, deco32_state, nslasher, ROT0, "Data East Corporation", "Night Slashers (Korea Rev 1.3)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
+GAME( 1994, nslasherj, nslasher, nslasher, nslasher, deco32_state, nslasher, ROT0, "Data East Corporation", "Night Slashers (Japan Rev 1.2)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
+GAME( 1994, nslashers, nslasher, nslasher, nslasher, deco32_state, nslasher, ROT0, "Data East Corporation", "Night Slashers (Over Sea Rev 1.2)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
+GAME( 1994, nslasheru, nslasher, nslasheru,nslasher, deco32_state, nslasher, ROT0, "Data East Corporation", "Night Slashers (US Rev 1.2, HuC6280 Sound CPU)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
-GAME( 1994, tattass, 0, tattass, tattass, deco32_state, tattass, ROT0, "Data East Pinball", "Tattoo Assassins (US prototype)", GAME_IMPERFECT_GRAPHICS )
-GAME( 1994, tattassa, tattass, tattass, tattass, deco32_state, tattass, ROT0, "Data East Pinball", "Tattoo Assassins (Asia prototype)", GAME_IMPERFECT_GRAPHICS )
+GAME( 1994, tattass, 0, tattass, tattass, deco32_state, tattass, ROT0, "Data East Pinball", "Tattoo Assassins (US prototype)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
+GAME( 1994, tattassa, tattass, tattass, tattass, deco32_state, tattass, ROT0, "Data East Pinball", "Tattoo Assassins (Asia prototype)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
// Dragon Gun / Lock 'n' Loaded have very different sprite hardware
-GAME( 1993, dragngun, 0, dragngun, dragngun, dragngun_state, dragngun, ROT0, "Data East Corporation", "Dragon Gun (US)", GAME_IMPERFECT_GRAPHICS )
-GAME( 1993, dragngunj, dragngun, dragngun, dragngun, dragngun_state, dragngunj, ROT0, "Data East Corporation", "Dragon Gun (Japan)", GAME_IMPERFECT_GRAPHICS )
+GAME( 1993, dragngun, 0, dragngun, dragngun, dragngun_state, dragngun, ROT0, "Data East Corporation", "Dragon Gun (US)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
+GAME( 1993, dragngunj, dragngun, dragngun, dragngun, dragngun_state, dragngunj, ROT0, "Data East Corporation", "Dragon Gun (Japan)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
-GAME( 1994, lockload, 0, lockload, lockload, dragngun_state, lockload, ROT0, "Data East Corporation", "Locked 'n Loaded (World)", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND | GAME_NOT_WORKING )
-GAME( 1994, gunhard, lockload, lockload, lockload, dragngun_state, lockload, ROT0, "Data East Corporation", "Gun Hard (Japan)", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND | GAME_NOT_WORKING )
-GAME( 1994, lockloadu, lockload, lockloadu,lockload, dragngun_state, lockload, ROT0, "Data East Corporation", "Locked 'n Loaded (US, Dragon Gun conversion)", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND | GAME_NOT_WORKING ) // HuC6280 Sound CPU
+GAME( 1994, lockload, 0, lockload, lockload, dragngun_state, lockload, ROT0, "Data East Corporation", "Locked 'n Loaded (World)", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND | GAME_NOT_WORKING | GAME_SUPPORTS_SAVE )
+GAME( 1994, gunhard, lockload, lockload, lockload, dragngun_state, lockload, ROT0, "Data East Corporation", "Gun Hard (Japan)", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND | GAME_NOT_WORKING | GAME_SUPPORTS_SAVE )
+GAME( 1994, lockloadu, lockload, lockloadu,lockload, dragngun_state, lockload, ROT0, "Data East Corporation", "Locked 'n Loaded (US, Dragon Gun conversion)", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND | GAME_NOT_WORKING | GAME_SUPPORTS_SAVE ) // HuC6280 Sound CPU
diff --git a/src/mame/drivers/firebeat.c b/src/mame/drivers/firebeat.c
index 346691f8098..e58068c25f1 100644
--- a/src/mame/drivers/firebeat.c
+++ b/src/mame/drivers/firebeat.c
@@ -82,9 +82,9 @@
------------------------------------------------------------------
GQ972 GQ972 2000 Beatmania III
GQ972(?) ? 2001 Beatmania III Append 6th Mix
- GQ972(?) ? 2002 Beatmania III Append 7th Mix
+ GQ972(?) GCB07 2002 Beatmania III Append 7th Mix
GQ972(?) ? 2000 Beatmania III Append Core Remix
- GQ972(?) ? 2003 Beatmania III The Final
+ GQ972(?) GCC01 2003 Beatmania III The Final
GQ974 GQ974 2000 Keyboardmania
GQ974 GCA01 2000 Keyboardmania 2nd Mix
GQ974 GCA12 2001 Keyboardmania 3rd Mix
@@ -92,13 +92,13 @@
GQ977 GQ977 2000 Para Para Dancing
GQ977 GC977 2000 Para Para Paradise 1.1
GQ977 GQA11 2000 Para Para Paradise 1st Mix+
- GQA02(?) ? 2000 Pop'n Music 4
- ??? ? 2000 Pop'n Music 5
- ??? ? 2001 Pop'n Music 6
+ GQA02(?) GQ986 2000 Pop'n Music 4
+ ??? G?A04 2000 Pop'n Music 5
+ ??? GQA16 2001 Pop'n Music 6
GQA02 GCB00 2001 Pop'n Music 7
- ??? ? 2002 Pop'n Music 8
+ ??? GQB30 2002 Pop'n Music 8
??? ? 2000 Pop'n Music Animelo
- ??? ? 2001 Pop'n Music Animelo 2
+ ??? GEA02 2001 Pop'n Music Animelo 2
??? ? 2001 Pop'n Music Mickey Tunes
TODO:
@@ -144,13 +144,9 @@
#include "firebeat.lh"
-struct GCU_REGS
-{
- UINT32 *vram;
- UINT32 vram_read_address;
- UINT32 vram_write_fifo_address;
- UINT32 visible_area;
-};
+#define DUMP_VRAM 0
+#define PRINT_GCU 0
+
struct IBUTTON_SUBKEY
{
@@ -164,6 +160,717 @@ struct IBUTTON
IBUTTON_SUBKEY subkey[3];
};
+#define MCFG_FIREBEAT_GCU_CPU_TAG(_tag) \
+ firebeat_gcu_device::static_set_cpu_tag(*device, _tag);
+
+class firebeat_gcu_device : public device_t
+{
+public:
+ firebeat_gcu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ static void static_set_cpu_tag(device_t &device, const char *tag) { downcast(device).m_cputag = tag; }
+
+ int draw(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+
+ DECLARE_READ32_MEMBER(read);
+ DECLARE_WRITE32_MEMBER(write);
+
+ struct framebuffer
+ {
+ UINT32 base;
+ int width;
+ int height;
+ };
+
+protected:
+ virtual void device_start();
+ virtual void device_stop();
+ virtual void device_reset();
+
+private:
+ void execute_command(UINT32 *cmd);
+ void execute_display_list(UINT32 addr);
+ void draw_object(UINT32 *cmd);
+ void fill_rect(UINT32 *cmd);
+ void draw_character(UINT32 *cmd);
+ void fb_config(UINT32 *cmd);
+
+ UINT32 *m_vram;
+ UINT32 m_vram_read_addr;
+ UINT32 m_vram_fifo0_addr;
+ UINT32 m_vram_fifo1_addr;
+ UINT32 m_vram_fifo0_mode;
+ UINT32 m_vram_fifo1_mode;
+ UINT32 m_command_fifo0[4];
+ UINT32 m_command_fifo0_ptr;
+ UINT32 m_command_fifo1[4];
+ UINT32 m_command_fifo1_ptr;
+
+ const char* m_cputag;
+ device_t* m_cpu;
+
+ framebuffer m_frame[4];
+ UINT32 m_fb_origin_x;
+ UINT32 m_fb_origin_y;
+};
+
+const device_type FIREBEAT_GCU = &device_creator;
+
+firebeat_gcu_device::firebeat_gcu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, FIREBEAT_GCU, "FireBeat GCU", tag, owner, clock, "firebeat_gcu", __FILE__)
+{
+}
+
+READ32_MEMBER(firebeat_gcu_device::read)
+{
+ int reg = offset * 4;
+
+ // VRAM Read
+ if (reg >= 0x80 && reg < 0x100)
+ {
+ return m_vram[m_vram_read_addr + offset - 0x20];
+ }
+
+ switch (reg)
+ {
+ case 0x78: // GCU Status
+ /* ppd checks bits 0x0041 of the upper halfword on interrupt */
+ return 0xffff0005;
+
+ default:
+ break;
+ }
+
+ return 0xffffffff;
+}
+
+WRITE32_MEMBER(firebeat_gcu_device::write)
+{
+ int reg = offset * 4;
+
+ switch (reg)
+ {
+ case 0x10:
+ /* IRQ clear/enable; ppd writes bit off then on in response to interrupt */
+ /* it enables bits 0x41, but 0x01 seems to be the one it cares about */
+ if (ACCESSING_BITS_16_31 && (data & 0x00010000) == 0)
+ m_cpu->execute().set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);
+ if (ACCESSING_BITS_0_15)
+#if PRINT_GCU
+ printf("%s_w: %02X, %08X, %08X\n", basetag(), reg, data, mem_mask);
+#endif
+ break;
+
+ case 0x14: // ?
+ break;
+
+ case 0x18: // ?
+ break;
+
+ case 0x20: // Framebuffer 0 Origin(?)
+ break;
+
+ case 0x24: // Framebuffer 1 Origin(?)
+ break;
+
+ case 0x28: // Framebuffer 2 Origin(?)
+ break;
+
+ case 0x2c: // Framebuffer 3 Origin(?)
+ break;
+
+ case 0x30: // Framebuffer 0 Dimensions
+ if (ACCESSING_BITS_16_31)
+ m_frame[0].height = (data >> 16) & 0xffff;
+ if (ACCESSING_BITS_0_15)
+ m_frame[0].width = data & 0xffff;
+ break;
+
+ case 0x34: // Framebuffer 1 Dimensions
+ if (ACCESSING_BITS_16_31)
+ m_frame[1].height = (data >> 16) & 0xffff;
+ if (ACCESSING_BITS_0_15)
+ m_frame[1].width = data & 0xffff;
+ break;
+
+ case 0x38: // Framebuffer 2 Dimensions
+ if (ACCESSING_BITS_16_31)
+ m_frame[2].height = (data >> 16) & 0xffff;
+ if (ACCESSING_BITS_0_15)
+ m_frame[2].width = data & 0xffff;
+ break;
+
+ case 0x3c: // Framebuffer 3 Dimensions
+ if (ACCESSING_BITS_16_31)
+ m_frame[3].height = (data >> 16) & 0xffff;
+ if (ACCESSING_BITS_0_15)
+ m_frame[3].width = data & 0xffff;
+ break;
+
+ case 0x40: // Framebuffer 0 Base
+ m_frame[0].base = data;
+#if PRINT_GCU
+ printf("%s FB0 Base: %08X\n", basetag(), data);
+#endif
+ break;
+
+ case 0x44: // Framebuffer 1 Base
+ m_frame[1].base = data;
+#if PRINT_GCU
+ printf("%s FB1 Base: %08X\n", basetag(), data);
+#endif
+ break;
+
+ case 0x48: // Framebuffer 2 Base
+ m_frame[2].base = data;
+#if PRINT_GCU
+ printf("%s FB2 Base: %08X\n", basetag(), data);
+#endif
+ break;
+
+ case 0x4c: // Framebuffer 3 Base
+ m_frame[3].base = data;
+#if PRINT_GCU
+ printf("%s FB3 Base: %08X\n", basetag(), data);
+#endif
+ break;
+
+ case 0x5c: // VRAM Read Address
+ m_vram_read_addr = (data & 0xffffff) / 2;
+ break;
+
+ case 0x60: // VRAM Port 0 Write Address
+ m_vram_fifo0_addr = (data & 0xffffff) / 2;
+ break;
+
+ case 0x68: // VRAM Port 0/1 Mode
+ if (ACCESSING_BITS_16_31)
+ m_vram_fifo0_mode = data >> 16;
+ if (ACCESSING_BITS_0_15)
+ m_vram_fifo1_mode = data & 0xffff;
+ break;
+
+ case 0x70: // VRAM Port 0 Write FIFO
+ if (m_vram_fifo0_mode & 0x100)
+ {
+ // write to command fifo
+ m_command_fifo0[m_command_fifo0_ptr] = data;
+ m_command_fifo0_ptr++;
+
+ // execute when filled
+ if (m_command_fifo0_ptr >= 4)
+ {
+ //printf("GCU FIFO0 exec: %08X %08X %08X %08X\n", m_command_fifo0[0], m_command_fifo0[1], m_command_fifo0[2], m_command_fifo0[3]);
+ execute_command(m_command_fifo0);
+ m_command_fifo0_ptr = 0;
+ }
+ }
+ else
+ {
+ // write to VRAM fifo
+ m_vram[m_vram_fifo0_addr] = data;
+ m_vram_fifo0_addr++;
+ }
+ break;
+
+ case 0x64: // VRAM Port 1 Write Address
+ m_vram_fifo1_addr = (data & 0xffffff) / 2;
+ printf("GCU FIFO1 addr = %08X\n", data);
+ break;
+
+ case 0x74: // VRAM Port 1 Write FIFO
+ printf("GCU FIFO1 write = %08X\n", data);
+
+ if (m_vram_fifo1_mode & 0x100)
+ {
+ // write to command fifo
+ m_command_fifo1[m_command_fifo1_ptr] = data;
+ m_command_fifo1_ptr++;
+
+ // execute when filled
+ if (m_command_fifo1_ptr >= 4)
+ {
+ printf("GCU FIFO1 exec: %08X %08X %08X %08X\n", m_command_fifo1[0], m_command_fifo1[1], m_command_fifo1[2], m_command_fifo1[3]);
+ m_command_fifo1_ptr = 0;
+ }
+ }
+ else
+ {
+ // write to VRAM fifo
+ m_vram[m_vram_fifo1_addr] = data;
+ m_vram_fifo1_addr++;
+ }
+ break;
+
+ default:
+ //printf("%s_w: %02X, %08X, %08X\n", basetag(), reg, data, mem_mask);
+ break;
+ }
+}
+
+int firebeat_gcu_device::draw(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ UINT16 *vram16 = (UINT16*)m_vram;
+
+ int x = 0;
+ int y = 0;
+ int width = m_frame[0].width;
+ int height = m_frame[0].height;
+
+ if (width != 0 && height != 0)
+ {
+ rectangle visarea = screen.visible_area();
+ if ((visarea.max_x+1) != width || (visarea.max_y+1) != height)
+ {
+ visarea.max_x = width-1;
+ visarea.max_y = height-1;
+ screen.configure(width, height, visarea, screen.frame_period().attoseconds);
+ }
+ }
+
+ int fb_pitch = 1024;
+
+ for (int j=0; j < height; j++)
+ {
+ UINT16 *d = &bitmap.pix16(j, x);
+ int li = ((j+y) * fb_pitch) + x;
+ UINT32 fbaddr0 = m_frame[0].base + li;
+ UINT32 fbaddr1 = m_frame[1].base + li;
+// UINT32 fbaddr2 = m_frame[2].base + li;
+// UINT32 fbaddr3 = m_frame[3].base + li;
+
+ for (int i=0; i < width; i++)
+ {
+ UINT16 pix0 = vram16[fbaddr0 ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)];
+ UINT16 pix1 = vram16[fbaddr1 ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)];
+// UINT16 pix2 = vram16[fbaddr2 ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)];
+// UINT16 pix3 = vram16[fbaddr3 ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)];
+
+ if (pix0 & 0x8000)
+ {
+ d[i] = pix0 & 0x7fff;
+ }
+ else
+ {
+ d[i] = pix1 & 0x7fff;
+ }
+
+ fbaddr0++;
+ fbaddr1++;
+// fbaddr2++;
+// fbaddr3++;
+ }
+ }
+
+ return 0;
+}
+
+void firebeat_gcu_device::draw_object(UINT32 *cmd)
+{
+ // 0x00: xxx----- -------- -------- -------- command (5)
+ // 0x00: ---x---- -------- -------- -------- 0: absolute coordinates
+ // 1: relative coordinates from framebuffer origin
+ // 0x00: ----xx-- -------- -------- -------- ?
+ // 0x00: -------- xxxxxxxx xxxxxxxx xxxxxxxx object data address in vram
+
+ // 0x01: -------- -------- ------xx xxxxxxxx object x
+ // 0x01: -------- xxxxxxxx xxxxxx-- -------- object y
+ // 0x01: -----x-- -------- -------- -------- object x flip
+ // 0x01: ----x--- -------- -------- -------- object y flip
+ // 0x01: --xx---- -------- -------- -------- object alpha enable (different blend modes?)
+ // 0x01: -x------ -------- -------- -------- object transparency enable (?)
+
+ // 0x02: -------- -------- ------xx xxxxxxxx object width
+ // 0x02: -------- -----xxx xxxxxx-- -------- object x scale
+
+ // 0x03: -------- -------- ------xx xxxxxxxx object height
+ // 0x03: -------- -----xxx xxxxxx-- -------- object y scale
+
+ int x = cmd[1] & 0x3ff;
+ int y = (cmd[1] >> 10) & 0x3fff;
+ int width = (cmd[2] & 0x3ff) + 1;
+ int height = (cmd[3] & 0x3ff) + 1;
+ int xscale = (cmd[2] >> 10) & 0x1ff;
+ int yscale = (cmd[3] >> 10) & 0x1ff;
+ bool xflip = (cmd[1] & 0x04000000) ? true : false;
+ bool yflip = (cmd[1] & 0x08000000) ? true : false;
+ bool alpha_enable = (cmd[1] & 0x30000000) ? true : false;
+ bool trans_enable = (cmd[1] & 0x40000000) ? true : false;
+ UINT32 address = cmd[0] & 0xffffff;
+ int alpha_level = (cmd[2] >> 27) & 0x1f;
+ bool relative_coords = (cmd[0] & 0x10000000) ? true : false;
+
+ if (relative_coords)
+ {
+ x += m_fb_origin_x;
+ y += m_fb_origin_y;
+ }
+
+ UINT16 *vram16 = (UINT16*)m_vram;
+
+ if (xscale == 0 || yscale == 0)
+ {
+ return;
+ }
+
+#if PRINT_GCU
+ printf("%s Draw Object %08X, x %d, y %d, w %d, h %d [%08X %08X %08X %08X]\n", basetag(), address, x, y, width, height, cmd[0], cmd[1], cmd[2], cmd[3]);
+#endif
+
+ width = (((width * 65536) / xscale) * 64) / 65536;
+ height = (((height * 65536) / yscale) * 64) / 65536;
+
+ int fb_pitch = 1024;
+
+ int v = 0;
+ for (int j=0; j < height; j++)
+ {
+ int index;
+ int xinc;
+ UINT32 fbaddr = ((j+y) * fb_pitch) + x;
+
+ if (yflip)
+ {
+ index = address + ((height - 1 - (v >> 6)) * 1024);
+ }
+ else
+ {
+ index = address + ((v >> 6) * 1024);
+ }
+
+ if (xflip)
+ {
+ fbaddr += width;
+ xinc = -1;
+ }
+ else
+ {
+ xinc = 1;
+ }
+
+ int u = 0;
+ for (int i=0; i < width; i++)
+ {
+ UINT16 pix = vram16[((index + (u >> 6)) ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)) & 0xffffff];
+ bool draw = !trans_enable || (trans_enable && (pix & 0x8000));
+ if (alpha_enable)
+ {
+ if (draw)
+ {
+ if ((pix & 0x7fff) != 0)
+ {
+ UINT16 srcpix = vram16[fbaddr ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)];
+
+ UINT32 sr = (srcpix >> 10) & 0x1f;
+ UINT32 sg = (srcpix >> 5) & 0x1f;
+ UINT32 sb = (srcpix >> 0) & 0x1f;
+ UINT32 r = (pix >> 10) & 0x1f;
+ UINT32 g = (pix >> 5) & 0x1f;
+ UINT32 b = (pix >> 0) & 0x1f;
+
+ sr += (r * alpha_level) >> 4;
+ sg += (g * alpha_level) >> 4;
+ sb += (b * alpha_level) >> 4;
+
+ if (sr > 0x1f) sr = 0x1f;
+ if (sg > 0x1f) sg = 0x1f;
+ if (sb > 0x1f) sb = 0x1f;
+
+ vram16[fbaddr ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)] = (sr << 10) | (sg << 5) | sb | 0x8000;
+ }
+ }
+ }
+ else
+ {
+ if (draw)
+ {
+ vram16[fbaddr ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)] = pix | 0x8000;
+ }
+ }
+
+ fbaddr += xinc;
+ u += xscale;
+ }
+
+ v += yscale;
+ }
+}
+
+void firebeat_gcu_device::fill_rect(UINT32 *cmd)
+{
+ // 0x00: xxx----- -------- -------- -------- command (4)
+ // 0x00: ---x---- -------- -------- -------- 0: absolute coordinates
+ // 1: relative coordinates from framebuffer origin
+ // 0x00: ----xx-- -------- -------- -------- ?
+ // 0x00: -------- -------- ------xx xxxxxxxx width
+ // 0x00: -------- ----xxxx xxxxxx-- -------- height
+
+ // 0x01: -------- -------- ------xx xxxxxxxx x
+ // 0x01: -------- xxxxxxxx xxxxxx-- -------- y
+
+ // 0x02: xxxxxxxx xxxxxxxx -------- -------- fill pattern pixel 0
+ // 0x02: -------- -------- xxxxxxxx xxxxxxxx fill pattern pixel 1
+
+ // 0x03: xxxxxxxx xxxxxxxx -------- -------- fill pattern pixel 2
+ // 0x03: -------- -------- xxxxxxxx xxxxxxxx fill pattern pixel 3
+
+ int x = cmd[1] & 0x3ff;
+ int y = (cmd[1] >> 10) & 0x3fff;
+ int width = (cmd[0] & 0x3ff) + 1;
+ int height = ((cmd[0] >> 10) & 0x3ff) + 1;
+ bool relative_coords = (cmd[0] & 0x10000000) ? true : false;
+
+ if (relative_coords)
+ {
+ x += m_fb_origin_x;
+ y += m_fb_origin_y;
+ }
+
+ UINT16 color[4];
+ color[0] = (cmd[2] >> 16);
+ color[1] = (cmd[2] & 0xffff);
+ color[2] = (cmd[3] >> 16);
+ color[3] = (cmd[3] & 0xffff);
+
+#if PRINT_GCU
+ printf("%s Fill Rect x %d, y %d, w %d, h %d, %08X %08X [%08X %08X %08X %08X]\n", basetag(), x, y, width, height, cmd[2], cmd[3], cmd[0], cmd[1], cmd[2], cmd[3]);
+#endif
+
+ int x1 = x;
+ int x2 = x + width;
+ int y1 = y;
+ int y2 = y + height;
+
+ UINT16 *vram16 = (UINT16*)m_vram;
+
+ int fb_pitch = 1024;
+
+ for (int j=y1; j < y2; j++)
+ {
+ UINT32 fbaddr = j * fb_pitch;
+ for (int i=x1; i < x2; i++)
+ {
+ vram16[(fbaddr+i) ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)] = color[i&3];
+ }
+ }
+}
+
+void firebeat_gcu_device::draw_character(UINT32 *cmd)
+{
+ // 0x00: xxx----- -------- -------- -------- command (7)
+ // 0x00: ---x---- -------- -------- -------- 0: absolute coordinates
+ // 1: relative coordinates from framebuffer base (unverified, should be same as other operations)
+ // 0x00: -------- xxxxxxxx xxxxxxxx xxxxxxxx character data address in vram
+
+ // 0x01: -------- -------- ------xx xxxxxxxx character x
+ // 0x01: -------- ----xxxx xxxxxx-- -------- character y
+
+ // 0x02: xxxxxxxx xxxxxxxx -------- -------- color 0
+ // 0x02: -------- -------- xxxxxxxx xxxxxxxx color 1
+
+ // 0x03: xxxxxxxx xxxxxxxx -------- -------- color 2
+ // 0x03: -------- -------- xxxxxxxx xxxxxxxx color 3
+
+ int x = cmd[1] & 0x3ff;
+ int y = (cmd[1] >> 10) & 0x3ff;
+ UINT32 address = cmd[0] & 0xffffff;
+ UINT16 color[4];
+ bool relative_coords = (cmd[0] & 0x10000000) ? true : false;
+
+ if (relative_coords)
+ {
+ x += m_fb_origin_x;
+ y += m_fb_origin_y;
+ }
+
+ color[0] = cmd[2] >> 16;
+ color[1] = cmd[2] & 0xffff;
+ color[2] = cmd[3] >> 16;
+ color[3] = cmd[3] & 0xffff;
+
+#if PRINT_GCU
+ printf("%s Draw Char %08X, x %d, y %d\n", basetag(), address, x, y);
+#endif
+
+ UINT16 *vram16 = (UINT16*)m_vram;
+ int fb_pitch = 1024;
+
+ for (int j=0; j < 8; j++)
+ {
+ UINT32 fbaddr = (y+j) * fb_pitch;
+ UINT16 line = vram16[address ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)];
+
+ address += 4;
+
+ for (int i=0; i < 8; i++)
+ {
+ int p = (line >> ((7-i) * 2)) & 3;
+ vram16[(fbaddr+x+i) ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0)] = color[p] | 0x8000;
+ }
+ }
+}
+
+void firebeat_gcu_device::fb_config(UINT32 *cmd)
+{
+ // 0x00: xxx----- -------- -------- -------- command (3)
+
+ // 0x01: -------- -------- -------- -------- unused?
+
+ // 0x02: -------- -------- ------xx xxxxxxxx Framebuffer Origin X
+
+ // 0x03: -------- -------- --xxxxxx xxxxxxxx Framebuffer Origin Y
+
+#if PRINT_GCU
+ printf("%s FB Config %08X %08X %08X %08X\n", basetag(), cmd[0], cmd[1], cmd[2], cmd[3]);
+#endif
+
+ m_fb_origin_x = cmd[2] & 0x3ff;
+ m_fb_origin_y = cmd[3] & 0x3fff;
+}
+
+void firebeat_gcu_device::execute_display_list(UINT32 addr)
+{
+ bool end = false;
+
+ int counter = 0;
+
+#if PRINT_GCU
+ printf("%s Exec Display List %08X\n", basetag(), addr);
+#endif
+
+ addr /= 2;
+ while (!end && counter < 0x1000 && addr < (0x2000000/4))
+ {
+ UINT32 *cmd = &m_vram[addr];
+ addr += 4;
+
+ int command = (cmd[0] >> 29) & 0x7;
+
+ switch (command)
+ {
+ case 0: // NOP?
+ break;
+
+ case 1: // Execute display list
+ execute_display_list(cmd[0] & 0xffffff);
+ break;
+
+ case 2: // End of display list
+ end = true;
+ break;
+
+ case 3: // Framebuffer config
+ fb_config(cmd);
+ break;
+
+ case 4: // Fill rectangle
+ fill_rect(cmd);
+ break;
+
+ case 5: // Draw object
+ draw_object(cmd);
+ break;
+
+ case 7: // Draw 8x8 character (2 bits per pixel)
+ draw_character(cmd);
+ break;
+
+ default:
+ printf("GCU Unknown command %08X %08X %08X %08X\n", cmd[0], cmd[1], cmd[2], cmd[3]);
+ break;
+ }
+ counter++;
+ };
+}
+
+void firebeat_gcu_device::execute_command(UINT32* cmd)
+{
+ int command = (cmd[0] >> 29) & 0x7;
+
+#if PRINT_GCU
+ printf("%s Exec Command %08X, %08X, %08X, %08X\n", basetag(), cmd[0], cmd[1], cmd[2], cmd[3]);
+#endif
+
+ switch (command)
+ {
+ case 0: // NOP?
+ break;
+
+ case 1: // Execute display list
+ execute_display_list(cmd[0] & 0xffffff);
+ break;
+
+ case 2: // End of display list
+ break;
+
+ case 3: // Framebuffer config
+ fb_config(cmd);
+ break;
+
+ case 4: // Fill rectangle
+ fill_rect(cmd);
+ break;
+
+ case 5: // Draw object
+ draw_object(cmd);
+ break;
+
+ case 7: // Draw 8x8 character (2 bits per pixel)
+ draw_character(cmd);
+ break;
+
+ default:
+ printf("GCU Unknown command %08X %08X %08X %08X\n", cmd[0], cmd[1], cmd[2], cmd[3]);
+ break;
+ }
+}
+
+void firebeat_gcu_device::device_start()
+{
+ m_cpu = machine().device(m_cputag);
+
+ m_vram = auto_alloc_array(machine(), UINT32, 0x2000000/4);
+ memset(m_vram, 0, 0x2000000);
+}
+
+void firebeat_gcu_device::device_reset()
+{
+ m_vram_read_addr = 0;
+ m_command_fifo0_ptr = 0;
+ m_command_fifo1_ptr = 0;
+ m_vram_fifo0_addr = 0;
+ m_vram_fifo1_addr = 0;
+
+ for (int i=0; i < 4; i++)
+ {
+ m_frame[i].base = 0;
+ m_frame[i].width = 0;
+ m_frame[i].height = 0;
+ }
+}
+
+void firebeat_gcu_device::device_stop()
+{
+#if DUMP_VRAM
+ char filename[200];
+ sprintf(filename, "%s_vram.bin", basetag());
+ printf("dumping %s\n", filename);
+ FILE *file = fopen(filename, "wb");
+ int i;
+
+ for (i=0; i < 0x2000000/4; i++)
+ {
+ fputc((m_vram[i] >> 24) & 0xff, file);
+ fputc((m_vram[i] >> 16) & 0xff, file);
+ fputc((m_vram[i] >> 8) & 0xff, file);
+ fputc((m_vram[i] >> 0) & 0xff, file);
+ }
+
+ fclose(file);
+#endif
+}
+
+
+
class firebeat_state : public driver_device
@@ -180,7 +887,9 @@ public:
m_duart_com(*this, "duart_com"),
m_kbd0(*this, "kbd0"),
m_kbd1(*this, "kbd1"),
- m_ata(*this, "ata")
+ m_ata(*this, "ata"),
+ m_gcu0(*this, "gcu0"),
+ m_gcu1(*this, "gcu1")
{ }
required_device m_maincpu;
@@ -193,11 +902,12 @@ public:
optional_device m_kbd0;
optional_device m_kbd1;
required_device m_ata;
+ required_device m_gcu0;
+ required_device m_gcu1;
UINT8 m_extend_board_irq_enable;
UINT8 m_extend_board_irq_active;
// emu_timer *m_keyboard_timer;
- GCU_REGS m_gcu[2];
int m_tick;
int m_layer;
int m_cab_data_ptr;
@@ -218,10 +928,6 @@ public:
UINT32 screen_update_firebeat_0(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
UINT32 screen_update_firebeat_1(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(firebeat_interrupt);
- DECLARE_READ32_MEMBER(gcu0_r);
- DECLARE_WRITE32_MEMBER(gcu0_w);
- DECLARE_READ32_MEMBER(gcu1_r);
- DECLARE_WRITE32_MEMBER(gcu1_w);
DECLARE_READ32_MEMBER(input_r);
DECLARE_READ32_MEMBER(sensor_r );
DECLARE_READ32_MEMBER(flashram_r);
@@ -252,13 +958,6 @@ public:
DECLARE_WRITE32_MEMBER(ppc_spu_share_w);
DECLARE_READ16_MEMBER(spu_unk_r);
// TIMER_CALLBACK_MEMBER(keyboard_timer_callback);
- void gcu_draw_object(bitmap_ind16 &bitmap, const rectangle &cliprect, int chip, UINT32 *cmd);
- void gcu_fill_rect(bitmap_ind16 &bitmap, const rectangle &cliprect, UINT32 *cmd);
- void gcu_draw_character(bitmap_ind16 &bitmap, const rectangle &cliprect, int chip, UINT32 *cmd);
- void gcu_exec_display_list(bitmap_ind16 &bitmap, const rectangle &cliprect, int chip, UINT32 address);
- UINT32 update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int chip);
- UINT32 GCU_r(int chip, UINT32 offset, UINT32 mem_mask);
- void GCU_w(int chip, UINT32 offset, UINT32 data, UINT32 mem_mask);
void set_ibutton(UINT8 *data);
int ibutton_w(UINT8 data);
DECLARE_WRITE8_MEMBER(security_w);
@@ -277,566 +976,10 @@ public:
VIDEO_START_MEMBER(firebeat_state,firebeat)
{
- m_gcu[0].vram = auto_alloc_array(machine(), UINT32, 0x2000000/4);
- m_gcu[1].vram = auto_alloc_array(machine(), UINT32, 0x2000000/4);
- memset(m_gcu[0].vram, 0, 0x2000000);
- memset(m_gcu[1].vram, 0, 0x2000000);
}
-
-void firebeat_state::gcu_draw_object(bitmap_ind16 &bitmap, const rectangle &cliprect, int chip, UINT32 *cmd)
-{
- // 0x00: xxx----- -------- -------- -------- command type
- // 0x00: -------- xxxxxxxx xxxxxxxx xxxxxxxx object data address in vram
-
- // 0x01: -------- -------- ------xx xxxxxxxx object x
- // 0x01: -------- ----xxxx xxxxxx-- -------- object y
- // 0x01: -----x-- -------- -------- -------- object x flip
- // 0x01: ----x--- -------- -------- -------- object y flip
- // 0x01: ---x---- -------- -------- -------- object alpha enable (?)
-
- // 0x02: -------- -------- ------xx xxxxxxxx object width
- // 0x02: -------- -----xxx xxxxxx-- -------- object x scale
-
- // 0x03: -------- -------- ------xx xxxxxxxx object height
- // 0x03: -------- -----xxx xxxxxx-- -------- object y scale
-
- int x = cmd[1] & 0x3ff;
- int y = (cmd[1] >> 10) & 0x3ff;
- int width = (cmd[2] & 0x3ff) + 1;
- int height = (cmd[3] & 0x3ff) + 1;
- int xscale = (cmd[2] >> 10) & 0x1ff;
- int yscale = (cmd[3] >> 10) & 0x1ff;
- int xflip = (cmd[1] & 0x04000000) ? 1 : 0;
- int yflip = (cmd[1] & 0x08000000) ? 1 : 0;
- int alpha_enable = (cmd[1] & 0x10000000) ? 1 : 0;
- UINT32 address = cmd[0] & 0xffffff;
- int alpha_level = (cmd[2] >> 27) & 0x1f;
-
- int i, j;
- int u, v;
- UINT16 *vr = (UINT16*)m_gcu[chip].vram;
-
- if (xscale == 0 || yscale == 0)
- {
- xscale = 0x40;
- yscale = 0x40;
- return;
- }
-
- //if ((cmd[2] >> 24) != 0x84 && (cmd[2] >> 24) != 0x04 && (cmd[2] >> 24) != 0x00)
- // printf("Unknown value = %d, %d\n", (cmd[2] >> 27) & 0x1f, (cmd[2] >> 22) & 0x1f);
-
- width = (((width * 65536) / xscale) * 64) / 65536;
- height = (((height * 65536) / yscale) * 64) / 65536;
-
- if (y > cliprect.max_y || x > cliprect.max_x) {
- return;
- }
- if ((y+height) > cliprect.max_y) {
- height = cliprect.max_y - y;
- }
- if ((x+width) > cliprect.max_x) {
- width = cliprect.max_x - x;
- }
-
- v = 0;
- for (j=0; j < height; j++)
- {
- int xi;
- int index;
- UINT16 *d = &bitmap.pix16(j+y, x);
- //int index = address + ((v >> 6) * 1024);
-
- if (yflip)
- {
- index = address + ((height - 1 - (v >> 6)) * 1024);
- }
- else
- {
- index = address + ((v >> 6) * 1024);
- }
-
- if (xflip)
- {
- d += width;
- xi = -1;
- }
- else
- {
- xi = 1;
- }
-
- u = 0;
- for (i=0; i < width; i++)
- {
- UINT16 pix = vr[((index + (u >> 6)) ^ 1) & 0xffffff];
-
- if (alpha_enable)
- {
- if (pix & 0x8000)
- {
- if ((pix & 0x7fff) != 0)
- {
- //*d = pix & 0x7fff;
- UINT16 srcpix = *d;
- /*
- UINT32 r = pix & 0x7c00;
- UINT32 g = pix & 0x03e0;
- UINT32 b = pix & 0x001f;
-
- UINT32 sr = srcpix & 0x7c00;
- UINT32 sg = srcpix & 0x03e0;
- UINT32 sb = srcpix & 0x001f;
-
- sr += r;
- sg += g;
- sb += b;
- if (sr > 0x7c00) sr = 0x7c00;
- if (sg > 0x03e0) sg = 0x03e0;
- if (sb > 0x001f) sb = 0x001f;
-
- *d = sr | sg | sb;
- */
-
- UINT32 sr = (srcpix >> 10) & 0x1f;
- UINT32 sg = (srcpix >> 5) & 0x1f;
- UINT32 sb = (srcpix >> 0) & 0x1f;
- UINT32 r = (pix >> 10) & 0x1f;
- UINT32 g = (pix >> 5) & 0x1f;
- UINT32 b = (pix >> 0) & 0x1f;
-
- sr += (r * alpha_level) >> 4;
- sg += (g * alpha_level) >> 4;
- sb += (b * alpha_level) >> 4;
-
- if (sr > 0x1f) sr = 0x1f;
- if (sg > 0x1f) sg = 0x1f;
- if (sb > 0x1f) sb = 0x1f;
-
- *d = (sr << 10) | (sg << 5) | sb;
- }
- }
- }
- else
- {
- if (pix & 0x8000)
- {
- *d = pix & 0x7fff;
- }
- }
-
- if ((cmd[0] & 0x10000000) == 0)
- *d = 0x7fff;
-
- d += xi;
- u += xscale;
- }
-
- v += yscale;
- }
-}
-
-void firebeat_state::gcu_fill_rect(bitmap_ind16 &bitmap, const rectangle &cliprect, UINT32 *cmd)
-{
- int i, j;
- int x1, y1, x2, y2;
-
- int x = cmd[1] & 0x3ff;
- int y = (cmd[1] >> 10) & 0x3ff;
- int width = (cmd[0] & 0x3ff) + 1;
- int height = ((cmd[0] >> 10) & 0x3ff) + 1;
-
- UINT16 color[4];
-
- color[0] = (cmd[2] >> 16);
- color[1] = (cmd[2] >> 0);
- color[2] = (cmd[3] >> 16);
- color[3] = (cmd[3] >> 0);
-
- x1 = x;
- x2 = x + width;
- y1 = y;
- y2 = y + height;
-
- if ((color[0] & 0x8000) == 0 && (color[1] & 0x8000) == 0 && (color[2] & 0x8000) == 0 && (color[3] & 0x8000) == 0)
- {
- // optimization, nothing to fill
- return;
- }
-
- // clip
- if (x1 < cliprect.min_x) x1 = cliprect.min_x;
- if (y1 < cliprect.min_y) y1 = cliprect.min_y;
- if (x2 > cliprect.max_x) x2 = cliprect.max_x;
- if (y2 > cliprect.max_y) y2 = cliprect.max_y;
-
- for (j=y1; j < y2; j++)
- {
- UINT16 *d = &bitmap.pix16(j);
- for (i=x1; i < x2; i++)
- {
- if (color[i&3] & 0x8000)
- {
- d[i] = color[i&3] & 0x7fff;
- }
- }
- }
-}
-
-void firebeat_state::gcu_draw_character(bitmap_ind16 &bitmap, const rectangle &cliprect, int chip, UINT32 *cmd)
-{
- // 0x00: xxx----- -------- -------- -------- command type
- // 0x00: -------- xxxxxxxx xxxxxxxx xxxxxxxx character data address in vram
-
- // 0x01: -------- -------- ------xx xxxxxxxx character x
- // 0x01: -------- ----xxxx xxxxxx-- -------- character y
-
- // 0x02: xxxxxxxx xxxxxxxx -------- -------- color 0
- // 0x02: -------- -------- xxxxxxxx xxxxxxxx color 1
-
- // 0x03: xxxxxxxx xxxxxxxx -------- -------- color 2
- // 0x03: -------- -------- xxxxxxxx xxxxxxxx color 3
-
- int i, j;
- int x = cmd[1] & 0x3ff;
- int y = (cmd[1] >> 10) & 0x3ff;
- UINT32 address = cmd[0] & 0xffffff;
- UINT16 color[4];
-
- UINT16 *vr = (UINT16*)m_gcu[chip].vram;
-
- color[0] = (cmd[2] >> 16) & 0xffff;
- color[1] = (cmd[2] >> 0) & 0xffff;
- color[2] = (cmd[3] >> 16) & 0xffff;
- color[3] = (cmd[3] >> 0) & 0xffff;
-
-
- if (y > cliprect.max_y || x > cliprect.max_x) {
- return;
- }
-
-
- for (j=0; j < 8; j++)
- {
- UINT16 *d = &bitmap.pix16(y+j, x);
- UINT16 line = vr[address^1];
-
- address += 4;
-
- for (i=0; i < 8; i++)
- {
- int pix = (line >> ((7-i) * 2)) & 3;
- d[i] = color[pix];
- }
- }
-}
-
-void firebeat_state::gcu_exec_display_list(bitmap_ind16 &bitmap, const rectangle &cliprect, int chip, UINT32 address)
-{
- int counter = 0;
- int end = 0;
-
- int i = address / 4;
- if (i < 0) i = 0;
- while (!end && counter < 0x1000 && i < (0x2000000/4))
- {
- int command;
- UINT32 cmd[4];
- cmd[0] = m_gcu[chip].vram[i+0];
- cmd[1] = m_gcu[chip].vram[i+1];
- cmd[2] = m_gcu[chip].vram[i+2];
- cmd[3] = m_gcu[chip].vram[i+3];
-
- command = (cmd[0] >> 29) & 0x7;
-
- switch (command)
- {
- case 0x0: // ???
- {
- break;
- }
-
- case 0x1: // Branch
- {
- gcu_exec_display_list(bitmap, cliprect, chip, cmd[0] & 0xffffff);
- break;
- }
-
- case 0x2: // End of display list
- {
- end = 1;
- break;
- }
-
- case 0x3: // ???
- {
- break;
- }
-
- case 0x4: // Fill rectangle
- {
- gcu_fill_rect(bitmap, cliprect, cmd);
- break;
- }
-
- case 0x5: // Draw object
- {
- gcu_draw_object(bitmap, cliprect, chip, cmd);
- break;
- }
-
- case 0x7: // Draw 8x8 Character (2-bits per pixel)
- {
- gcu_draw_character(bitmap, cliprect, chip, cmd);
- break;
- }
-
- default:
- //printf("Unknown command %08X %08X %08X %08X at %08X\n", cmd[0], cmd[1], cmd[2], cmd[3], i*4);
- break;
- }
-
- i += 4;
- counter++;
- };
-}
-
-UINT32 firebeat_state::update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int chip)
-{
- bitmap.fill(0, cliprect);
-
- if ((core_strnicmp(machine().system().name, "popn", 4) == 0) || (core_strnicmp(machine().system().name, "bm3", 3) == 0))
- {
- gcu_exec_display_list( bitmap, cliprect, chip, 0x1f80000);
- }
- else
- {
- if (m_layer >= 2)
- {
- gcu_exec_display_list(bitmap, cliprect, chip, 0x8000);
- gcu_exec_display_list(bitmap, cliprect, chip, 0x0000);
- gcu_exec_display_list(bitmap, cliprect, chip, 0x10000);
- }
- else if (m_layer == 0)
- {
- gcu_exec_display_list(bitmap, cliprect, chip, 0x200000);
-
- //gcu_exec_display_list(bitmap, cliprect, chip, 0x186040);
- }
- else if (m_layer == 1)
- {
- gcu_exec_display_list(bitmap, cliprect, chip, 0x1d0800);
-
- gcu_exec_display_list(bitmap, cliprect, chip, 0x1a9440);
- }
- }
-
- m_tick++;
- if (m_tick >= 5)
- {
- m_tick = 0;
- if (machine().input().code_pressed(KEYCODE_0))
- {
- m_layer++;
- if (m_layer > 2)
- {
- m_layer = 0;
- }
- }
-
- /*
- if (machine().input().code_pressed_once(KEYCODE_9))
- {
- FILE *file = fopen("vram0.bin", "wb");
- int i;
-
- for (i=0; i < 0x2000000/4; i++)
- {
- fputc((m_gcu[0].vram[i] >> 24) & 0xff, file);
- fputc((m_gcu[0].vram[i] >> 16) & 0xff, file);
- fputc((m_gcu[0].vram[i] >> 8) & 0xff, file);
- fputc((m_gcu[0].vram[i] >> 0) & 0xff, file);
- }
-
- fclose(file);
- file = fopen("vram1.bin", "wb");
-
- for (i=0; i < 0x2000000/4; i++)
- {
- fputc((m_gcu[1].vram[i] >> 24) & 0xff, file);
- fputc((m_gcu[1].vram[i] >> 16) & 0xff, file);
- fputc((m_gcu[1].vram[i] >> 8) & 0xff, file);
- fputc((m_gcu[1].vram[i] >> 0) & 0xff, file);
- }
-
- fclose(file);
- }
- */
- }
-
- return 0;
-}
-
-UINT32 firebeat_state::screen_update_firebeat_0(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect){ return update_screen(screen, bitmap, cliprect, 0); }
-UINT32 firebeat_state::screen_update_firebeat_1(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect){ return update_screen(screen, bitmap, cliprect, 1); }
-
-UINT32 firebeat_state::GCU_r(int chip, UINT32 offset, UINT32 mem_mask)
-{
- int reg = offset * 4;
-
- /* VRAM Read */
- if (reg >= 0x80 && reg < 0x100)
- {
- return m_gcu[chip].vram[m_gcu[chip].vram_read_address + ((reg/4) - 0x20)];
- }
-
- switch(reg)
- {
- case 0x78: /* GCU Status */
- /* ppd checks bits 0x0041 of the upper halfword on interrupt */
- return 0xffff0005;
-
- default:
- break;
- }
-
- return 0xffffffff;
-}
-
-void firebeat_state::GCU_w(int chip, UINT32 offset, UINT32 data, UINT32 mem_mask)
-{
- int reg = offset * 4;
-
- if (reg != 0x70 && chip == 0)
- {
- //printf("%s:gcu%d_w: %08X, %08X, %08X at %08X\n", machine().describe_context(), chip, data, offset, mem_mask);
- //logerror("%s:gcu%d_w: %08X, %08X, %08X at %08X\n", cmachine->describe_context(), hip, data, offset, mem_mask);
- }
-
- switch(reg)
- {
- case 0x10: /* ??? */
- /* IRQ clear/enable; ppd writes bit off then on in response to interrupt */
- /* it enables bits 0x41, but 0x01 seems to be the one it cares about */
- if (ACCESSING_BITS_16_31 && (data & 0x0001) == 0)
- m_maincpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);
- break;
-
- case 0x30:
- //case 0x34:
- //case 0x38:
- //case 0x3c:
- {
- COMBINE_DATA( &m_gcu[chip].visible_area );
- if (ACCESSING_BITS_0_15)
- {
- screen_device_iterator iter(machine().root_device());
- screen_device *screen = iter.byindex(chip);
-
- if (screen != NULL)
- {
- rectangle visarea = screen->visible_area();
- int width, height;
-
- width = (m_gcu[chip].visible_area & 0xffff);
- height = (m_gcu[chip].visible_area >> 16) & 0xffff;
-
- visarea.max_x = width-1;
- visarea.max_y = height-1;
-
- screen->configure(visarea.max_x + 1, visarea.max_y + 1, visarea, screen->frame_period().attoseconds);
- }
- }
- break;
- }
-
- case 0x40: /* framebuffer config */
- // HACK: switch display lists at the right times for the ParaParaParadise games until we
- // do the video emulation properly
- if (core_strnicmp(machine().system().name, "pp", 2) == 0)
- {
- switch (data)
- {
- case 0x00080000: // post
- m_layer = 0;
- break;
-
- case 0x00008400: // startup tests
- if (m_layer != 2)
- {
- m_layer = 1;
- }
- break;
-
- case 0x00068400: // game & svc menu
- m_layer = 2;
- break;
- }
- }
- else if (core_strnicmp(machine().system().name, "kbm", 3) == 0)
- {
- switch (data)
- {
- case 0x00080000: // post
- m_layer = 0;
- break;
-
- case 0x0000c400: // game & svn menu
- m_layer = 2;
- break;
- }
- }
- break;
-
- //case 0x44: /* ??? */
- // break;
-
- case 0x5c: /* VRAM Read Address */
- m_gcu[chip].vram_read_address = (data & 0xffffff) / 2;
- break;
-
- case 0x60: /* VRAM FIFO Write Address */
- m_gcu[chip].vram_write_fifo_address = (data & 0xffffff) / 2;
-
- // printf("gcu%d_w: %08X, %08X, %08X\n", chip, data, offset, mem_mask);
- break;
-
- case 0x68: /* Unknown */
- {
- break;
- }
-
- case 0x70: /* VRAM FIFO Write */
- m_gcu[chip].vram[m_gcu[chip].vram_write_fifo_address] = data;
- m_gcu[chip].vram_write_fifo_address++;
- break;
-
- default:
- // printf("gcu%d_w: %08X, %08X, %08X\n", chip, data, offset, mem_mask);
- break;
- }
-}
-
-READ32_MEMBER(firebeat_state::gcu0_r)
-{
- return GCU_r(0, offset, mem_mask);
-}
-
-WRITE32_MEMBER(firebeat_state::gcu0_w)
-{
- GCU_w(0, offset, data, mem_mask);
-}
-
-READ32_MEMBER(firebeat_state::gcu1_r)
-{
- return GCU_r(1, offset, mem_mask);
-}
-
-WRITE32_MEMBER(firebeat_state::gcu1_w)
-{
- GCU_w(1, offset, data, mem_mask);
-}
+UINT32 firebeat_state::screen_update_firebeat_0(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect){ return m_gcu0->draw(screen, bitmap, cliprect); }
+UINT32 firebeat_state::screen_update_firebeat_1(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect){ return m_gcu1->draw(screen, bitmap, cliprect); }
/*****************************************************************************/
@@ -1508,8 +1651,8 @@ static ADDRESS_MAP_START( firebeat_map, AS_PROGRAM, 32, firebeat_state )
AM_RANGE(0x7dc00000, 0x7dc0000f) AM_DEVREADWRITE8("duart_com", pc16552_device, read, write, 0xffffffff)
AM_RANGE(0x7e000000, 0x7e00003f) AM_DEVREADWRITE8("rtc", rtc65271_device, rtc_r, rtc_w, 0xffffffff)
AM_RANGE(0x7e000100, 0x7e00013f) AM_DEVREADWRITE8("rtc", rtc65271_device, xram_r, xram_w, 0xffffffff)
- AM_RANGE(0x7e800000, 0x7e8000ff) AM_READWRITE(gcu0_r, gcu0_w)
- AM_RANGE(0x7e800100, 0x7e8001ff) AM_READWRITE(gcu1_r, gcu1_w)
+ AM_RANGE(0x7e800000, 0x7e8000ff) AM_DEVREADWRITE("gcu0", firebeat_gcu_device, read, write)
+ AM_RANGE(0x7e800100, 0x7e8001ff) AM_DEVREADWRITE("gcu1", firebeat_gcu_device, read, write)
AM_RANGE(0x7fe00000, 0x7fe0000f) AM_READWRITE(ata_command_r, ata_command_w)
AM_RANGE(0x7fe80000, 0x7fe8000f) AM_READWRITE(ata_control_r, ata_control_w)
AM_RANGE(0x7ff80000, 0x7fffffff) AM_ROM AM_REGION("user1", 0) /* System BIOS */
@@ -1724,6 +1867,12 @@ static MACHINE_CONFIG_START( firebeat, firebeat_state )
/* video hardware */
MCFG_PALETTE_ADD_RRRRRGGGGGBBBBB("palette")
+ MCFG_DEVICE_ADD("gcu0", FIREBEAT_GCU, 0)
+ MCFG_FIREBEAT_GCU_CPU_TAG("maincpu")
+
+ MCFG_DEVICE_ADD("gcu1", FIREBEAT_GCU, 0)
+ MCFG_FIREBEAT_GCU_CPU_TAG("maincpu")
+
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)
@@ -1778,6 +1927,12 @@ static MACHINE_CONFIG_START( firebeat2, firebeat_state )
/* video hardware */
MCFG_PALETTE_ADD_RRRRRGGGGGBBBBB("palette")
+ MCFG_DEVICE_ADD("gcu0", FIREBEAT_GCU, 0)
+ MCFG_FIREBEAT_GCU_CPU_TAG("maincpu")
+
+ MCFG_DEVICE_ADD("gcu1", FIREBEAT_GCU, 0)
+ MCFG_FIREBEAT_GCU_CPU_TAG("maincpu")
+
MCFG_SCREEN_ADD("lscreen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)
diff --git a/src/mame/drivers/gambl186.c b/src/mame/drivers/gambl186.c
index d626a9ae425..ba0d4ce90ba 100644
--- a/src/mame/drivers/gambl186.c
+++ b/src/mame/drivers/gambl186.c
@@ -86,13 +86,6 @@ void gambl186_state::machine_start()
membank("data_bank")->configure_entries(0, 4, memregion("data")->base(), 0x40000);
}
-static ADDRESS_MAP_START( gambl186_map, AS_PROGRAM, 16, gambl186_state )
- AM_RANGE(0x00000, 0x0ffff) AM_RAM AM_SHARE("nvram")
- AM_RANGE(0x40000, 0x7ffff) AM_ROMBANK("data_bank") // TODO: way bigger than this, banked?
- AM_RANGE(0xa0000, 0xbffff) AM_DEVREADWRITE8("vga", cirrus_gd5428_device, mem_r, mem_w, 0xffff)
- AM_RANGE(0xc0000, 0xfffff) AM_ROM AM_REGION("ipl",0)
-ADDRESS_MAP_END
-
static const UINT8 password[] = {5, 2, 0, 3, 0, 0, 2, 4, 5, 6, 0x16};
READ16_MEMBER(gambl186_state::comms_r)
@@ -364,6 +357,12 @@ WRITE16_MEMBER(gambl186_state::upd_w)
// m_upd7759->start_w(1);
}
+static ADDRESS_MAP_START( gambl186_map, AS_PROGRAM, 16, gambl186_state )
+ AM_RANGE(0x00000, 0x0ffff) AM_RAM AM_SHARE("nvram")
+ AM_RANGE(0x40000, 0x7ffff) AM_ROMBANK("data_bank")
+ AM_RANGE(0xa0000, 0xbffff) AM_DEVREADWRITE8("vga", cirrus_gd5428_device, mem_r, mem_w, 0xffff)
+ AM_RANGE(0xc0000, 0xfffff) AM_ROM AM_REGION("ipl",0)
+ADDRESS_MAP_END
static ADDRESS_MAP_START( gambl186_io, AS_IO, 16, gambl186_state )
AM_RANGE(0x03b0, 0x03bf) AM_DEVREADWRITE8("vga", cirrus_gd5428_device, port_03b0_r, port_03b0_w, 0xffff)
diff --git a/src/mame/drivers/suprloco.c b/src/mame/drivers/suprloco.c
index 2779544ffa9..7ac0c12c437 100644
--- a/src/mame/drivers/suprloco.c
+++ b/src/mame/drivers/suprloco.c
@@ -52,7 +52,8 @@ static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, suprloco_state )
ADDRESS_MAP_END
static ADDRESS_MAP_START( decrypted_opcodes_map, AS_DECRYPTED_OPCODES, 8, suprloco_state )
- AM_RANGE(0x0000, 0xbfff) AM_ROM AM_SHARE("decrypted_opcodes")
+ AM_RANGE(0x0000, 0x7fff) AM_ROM AM_SHARE("decrypted_opcodes")
+ AM_RANGE(0x8000, 0xbfff) AM_ROM AM_REGION("maincpu", 0x8000)
ADDRESS_MAP_END
static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, suprloco_state )
@@ -319,7 +320,7 @@ DRIVER_INIT_MEMBER(suprloco_state,suprloco)
};
/* decrypt program ROMs */
- sega_decode(memregion("maincpu")->base(), m_decrypted_opcodes, 0xc000, convtable);
+ sega_decode(memregion("maincpu")->base(), m_decrypted_opcodes, 0x8000, convtable);
}
diff --git a/src/mame/drivers/taitoair.c b/src/mame/drivers/taitoair.c
index e893b439f4c..55a61decafe 100644
--- a/src/mame/drivers/taitoair.c
+++ b/src/mame/drivers/taitoair.c
@@ -121,7 +121,6 @@ Stephh's notes (based on the game M68000 code and some tests) :
TODO (TC0080VCO issues shared with TaitoH driver)
----
- - Need to implement BG1 : sprite priority. Currently not clear how this works.
- Fix sprite coordinates.
- Improve zoom y coordinate.
@@ -147,9 +146,6 @@ controlling the sit-in-cabinet (deluxe mechanized version only).
The interface is similar to that used by Midnight Landing
and though undumped, the motor CPU program may be identical.
-[Offer dip-selectable kludge of the analogue stick inputs so that
-keyboard play is possible?]
-
Unknown control bits remain in the 0x140000 write.
@@ -169,8 +165,6 @@ emulation is complete.
Topland
-------
-Sprite/tile priority bad.
-
After demo game in attract, palette seems too dark for a while.
Palette corruption has occurred with areas not restored after a fade.
Don't know why. (Perhaps 68000 relies on feedback from co-processor
@@ -188,38 +182,18 @@ discarded. But the cpu waits for a bit to be zero... some
sort of frame flag or some "ready" message from the 3d h/w
perhaps? The two writes seem to take only two values.
-
-Ainferno
---------
-
-Sprite/tile priority bad.
-
-More unmapped 320C25 reads and writes. This could be some sort of
-I/O device?? The MCU program is longer than the Topland one.
-
-cpu #2 (PC=000000C3): unmapped memory word write to 00006808 = 00FD & FFFF
-cpu #2 (PC=000000C8): unmapped memory word write to 00006810 = FF38 & FFFF
-cpu #2 (PC=000005A0): unmapped memory word write to 00006836 = 804E & FFFF
-cpu #2 (PC=000005B2): unmapped memory word write to 00006830 = FFFF & FFFF
-cpu #2 (PC=000005B5): unmapped memory word write to 00006832 = FFFE & FFFF
-cpu #2 (PC=000005B8): unmapped memory word write to 00006834 = FBCA & FFFF
-cpu #2 (PC=000005B9): unmapped memory word read from 00006836 & FFFF
-cpu #2 (PC=000005CC): unmapped memory word write to 00006830 = FFFF & FFFF
-cpu #2 (PC=000005CF): unmapped memory word write to 00006832 = FFFE & FFFF
-cpu #2 (PC=000005D2): unmapped memory word write to 00006834 = FBCA & FFFF
-cpu #2 (PC=000005D3): unmapped memory word read from 00006836 & FFFF
-cpu #2 (PC=000005E6): unmapped memory word write to 00006830 = FFFF & FFFF
-cpu #2 (PC=000005E9): unmapped memory word write to 00006832 = FFFE & FFFF
-cpu #2 (PC=000005EC): unmapped memory word write to 00006834 = FC8F & FFFF
-cpu #2 (PC=000005ED): unmapped memory word read from 00006836 & FFFF
-cpu #2 (PC=00000600): unmapped memory word write to 00006830 = FFFF & FFFF
-cpu #2 (PC=00000603): unmapped memory word write to 00006832 = FFFE & FFFF
-cpu #2 (PC=00000606): unmapped memory word write to 00006834 = FC8F & FFFF
-cpu #2 (PC=00000607): unmapped memory word read from 00006836 & FFFF
-cpu #2 (PC=00000609): unmapped memory word read from 00006838 & FFFF
-cpu #2 (PC=0000060E): unmapped memory word read from 0000683A & FFFF
-
****************************************************************************/
+/*!
+ @todo - Framebuffer DMA requires palette switch to be selected dynamically, see at first stage Course Select in Top Landing.
+ My gut feeling is that 3d poly fill operation actually copies to internal buffer then a DMA op actually do the buffer-to-screen copy, including gradiation ROZ too;
+ - Air Inferno: missing landing monitor camera (blackened);
+ - Air Inferno: missing 3d HUD graphics;
+ - Air Inferno: Expert course has wrong 3d geometry;
+ - Air Inferno: Almost surely crashing during replay has missing smoke effect, looks quit odd atm.
+ - Top Landing: Night stages might have wrong priority for stars-above-sea;
+ - Input limiters / analog thresholds for both games;
+ - Special thanks to syq for being a cunt.
+ */
#include "emu.h"
#include "cpu/z80/z80.h"
@@ -370,6 +344,33 @@ WRITE8_MEMBER(taitoair_state::sound_bankswitch_w)
membank("z80bank")->set_entry(data & 3);
}
+/*!
+ @brief Framebuffer DMA control
+ @regs [0] x--- ---- ---- ---- copy framebuffer to the screen
+ [0] --x- ---- ---- ---- unknown, used on POST test
+ [0] 1001 1111 1111 1111 used by Air Inferno after erase op, erase -> copy?
+ [0] 0001 1111 1111 1111 erase op?
+ [1] xxxx xxxx xxxx xxxx fill value? 0xffff by Top Landing, 0x0000 Air Inferno
+ [2] (unused)
+ [3] both games uses 0xb7, most likely a register setting.
+*/
+WRITE16_MEMBER(taitoair_state::dma_regs_w)
+{
+ printf("%08x %04x\n",offset,data);
+
+ if(offset == 0 && ACCESSING_BITS_8_15)
+ {
+ if(data == 0x1fff)
+ {
+ fb_erase_op();
+ }
+ else if(data & 0x8000)
+ {
+ /*! @todo it also flushes current palette. */
+ fb_copy_op();
+ }
+ }
+}
/***********************************************************
MEMORY STRUCTURES
@@ -382,7 +383,7 @@ static ADDRESS_MAP_START( airsys_map, AS_PROGRAM, 16, taitoair_state )
AM_RANGE(0x180000, 0x187fff) AM_RAM_WRITE(airsys_gradram_w) AM_SHARE("gradram") /* "gradiation ram (0/1)" */
AM_RANGE(0x188000, 0x189fff) AM_MIRROR(0x2000) AM_RAM_WRITE(airsys_paletteram16_w) AM_SHARE("paletteram")
AM_RANGE(0x800000, 0x820fff) AM_DEVREADWRITE("tc0080vco", tc0080vco_device, word_r, word_w) /* tilemaps, sprites */
-// AM_RANGE(0x906000, 0x906007) AM_RAM // DMA?
+ AM_RANGE(0x906000, 0x906007) AM_WRITE(dma_regs_w) // DMA?
AM_RANGE(0x908000, 0x90ffff) AM_RAM AM_SHARE("line_ram") /* "line ram" */
AM_RANGE(0x910000, 0x91ffff) AM_RAM AM_SHARE("dsp_ram") /* "dsp common ram" (TMS320C25) */
AM_RANGE(0x980000, 0x98000f) AM_RAM AM_SHARE("tc0430grw") /* TC0430GRW roz transform coefficients */
@@ -478,6 +479,9 @@ WRITE16_MEMBER(taitoair_state::dsp_muldiv_c_1_w)
READ16_MEMBER(taitoair_state::dsp_muldiv_1_r)
{
+ if(m_dsp_muldiv_c_1 == 0)
+ return 0xffff; /**< @todo true value? */
+
return m_dsp_muldiv_a_1*m_dsp_muldiv_b_1/m_dsp_muldiv_c_1;
}
@@ -498,6 +502,9 @@ WRITE16_MEMBER(taitoair_state::dsp_muldiv_c_2_w)
READ16_MEMBER(taitoair_state::dsp_muldiv_2_r)
{
+ if(m_dsp_muldiv_c_2 == 0)
+ return 0xffff; /**< @todo true value? */
+
return m_dsp_muldiv_a_2*m_dsp_muldiv_b_2/m_dsp_muldiv_c_2;
}
@@ -585,10 +592,10 @@ static INPUT_PORTS_START( topland )
PORT_BIT( 0x00ff, 0x0000, IPT_AD_STICK_Z ) PORT_MINMAX(0x0080,0x007f) PORT_SENSITIVITY(30) PORT_KEYDELTA(40) PORT_PLAYER(1) PORT_REVERSE
PORT_START(STICK2_PORT_TAG)
- PORT_BIT( 0xffff, 0x0000, IPT_AD_STICK_X ) PORT_MINMAX(0xf800,0x07ff) PORT_SENSITIVITY(30) PORT_KEYDELTA(40) PORT_PLAYER(1)
+ PORT_BIT( 0x0fff, 0x0000, IPT_AD_STICK_X ) PORT_MINMAX(0x00800, 0x07ff) PORT_SENSITIVITY(100) PORT_KEYDELTA(20) PORT_PLAYER(1)
PORT_START(STICK3_PORT_TAG)
- PORT_BIT( 0xffff, 0x0000, IPT_AD_STICK_Y ) PORT_MINMAX(0xf800,0x07ff) PORT_SENSITIVITY(30) PORT_KEYDELTA(40) PORT_PLAYER(1)
+ PORT_BIT( 0x0fff, 0x0000, IPT_AD_STICK_Y ) PORT_MINMAX(0x00800, 0x07ff) PORT_SENSITIVITY(100) PORT_KEYDELTA(20) PORT_PLAYER(1)
INPUT_PORTS_END
static INPUT_PORTS_START( ainferno )
@@ -645,10 +652,10 @@ static INPUT_PORTS_START( ainferno )
PORT_BIT( 0x00ff, 0x0000, IPT_AD_STICK_Z ) PORT_MINMAX(0x0080,0x007f) PORT_SENSITIVITY(30) PORT_KEYDELTA(40) PORT_PLAYER(1) PORT_REVERSE
PORT_START(STICK2_PORT_TAG)
- PORT_BIT( 0xffff, 0x0000, IPT_AD_STICK_X ) PORT_MINMAX(0xf800,0x7ff) PORT_SENSITIVITY(30) PORT_KEYDELTA(40) PORT_PLAYER(1)
+ PORT_BIT( 0x0fff, 0x0000, IPT_AD_STICK_X ) PORT_MINMAX(0x00800, 0x07ff) PORT_SENSITIVITY(100) PORT_KEYDELTA(20) PORT_PLAYER(1)
PORT_START(STICK3_PORT_TAG)
- PORT_BIT( 0xffff, 0x0000, IPT_AD_STICK_Y ) PORT_MINMAX(0xf800,0x7ff) PORT_SENSITIVITY(30) PORT_KEYDELTA(40) PORT_PLAYER(1)
+ PORT_BIT( 0x0fff, 0x0000, IPT_AD_STICK_Y ) PORT_MINMAX(0x00800, 0x07ff) PORT_SENSITIVITY(100) PORT_KEYDELTA(20) PORT_PLAYER(1)
INPUT_PORTS_END
@@ -953,6 +960,6 @@ ROM_END
/* ( YEAR NAME PARENT MACHINE INPUT INIT MONITOR COMPANY FULLNAME */
-GAME( 1988, topland, 0, airsys, topland, driver_device, 0, ROT0, "Taito Corporation Japan", "Top Landing (World)", GAME_NOT_WORKING )
+GAME( 1988, topland, 0, airsys, topland, driver_device, 0, ROT0, "Taito Corporation Japan", "Top Landing (World)", GAME_IMPERFECT_GRAPHICS )
GAME( 1990, ainferno, 0, airsys, ainferno, driver_device, 0, ROT0, "Taito America Corporation", "Air Inferno (US)", GAME_NOT_WORKING )
GAME( 1990, ainfernoj,ainferno, airsys, ainferno, driver_device, 0, ROT0, "Taito Corporation Japan", "Air Inferno (Japan)", GAME_NOT_WORKING )
diff --git a/src/mame/includes/deco32.h b/src/mame/includes/deco32.h
index 0d5bf5dcc9e..a03efc5adce 100644
--- a/src/mame/includes/deco32.h
+++ b/src/mame/includes/deco32.h
@@ -21,12 +21,6 @@ public:
m_deco104(*this, "ioprot104"),
m_decobsmt(*this, "decobsmt"),
m_spriteram(*this, "spriteram"),
- m_ram(*this, "ram"),
- m_pf1_rowscroll32(*this, "pf1_rowscroll32"),
- m_pf2_rowscroll32(*this, "pf2_rowscroll32"),
- m_pf3_rowscroll32(*this, "pf3_rowscroll32"),
- m_pf4_rowscroll32(*this, "pf4_rowscroll32"),
- m_ace_ram(*this, "ace_ram"),
m_sprgen(*this, "spritegen"),
m_sprgen1(*this, "spritegen1"),
m_sprgen2(*this, "spritegen2"),
@@ -39,7 +33,13 @@ public:
m_gfxdecode(*this, "gfxdecode"),
m_screen(*this, "screen"),
m_palette(*this, "palette"),
- m_generic_paletteram_32(*this, "paletteram")
+ m_ram(*this, "ram"),
+ m_pf1_rowscroll32(*this, "pf1_rowscroll32"),
+ m_pf2_rowscroll32(*this, "pf2_rowscroll32"),
+ m_pf3_rowscroll32(*this, "pf3_rowscroll32"),
+ m_pf4_rowscroll32(*this, "pf4_rowscroll32"),
+ m_generic_paletteram_32(*this, "paletteram"),
+ m_ace_ram(*this, "ace_ram")
{ }
required_device m_maincpu;
@@ -48,101 +48,110 @@ public:
optional_device m_deco104;
optional_device m_decobsmt;
optional_device m_spriteram;
+ optional_device m_sprgen;
+ optional_device m_sprgen1;
+ optional_device m_sprgen2;
+ optional_device m_sprgenzoom;
+ optional_device m_eeprom;
+ optional_device m_oki1;
+ optional_device m_oki2;
+ required_device m_deco_tilegen1;
+ required_device m_deco_tilegen2;
+ required_device m_gfxdecode;
+ required_device m_screen;
+ required_device m_palette;
+
required_shared_ptr m_ram;
// we use the pointers below to store a 32-bit copy..
required_shared_ptr m_pf1_rowscroll32;
required_shared_ptr m_pf2_rowscroll32;
required_shared_ptr m_pf3_rowscroll32;
required_shared_ptr m_pf4_rowscroll32;
-
- optional_shared_ptr m_ace_ram;
- optional_device m_sprgen;
- optional_device m_sprgen1;
- optional_device m_sprgen2;
- optional_device m_sprgenzoom;
-
- optional_device m_eeprom;
- optional_device m_oki1;
- optional_device m_oki2;
-
- int m_raster_enable;
- timer_device *m_raster_irq_timer;
- UINT8 m_nslasher_sound_irq;
-
- int m_tattass_eprom_bit;
- int m_lastClock;
- char m_buffer[32];
- int m_bufPtr;
- int m_pendingCommand;
- int m_readBitCount;
- int m_byteAddr;
-
- int m_ace_ram_dirty;
- int m_has_ace_ram;
-
- UINT8 *m_dirty_palette;
-
- int m_pri;
- bitmap_ind16 *m_tilemap_alpha_bitmap;
-
-
- UINT16 m_spriteram16[0x1000];
- UINT16 m_spriteram16_buffered[0x1000];
- UINT16 m_spriteram16_2[0x1000];
- UINT16 m_spriteram16_2_buffered[0x1000];
- UINT16 m_pf1_rowscroll[0x1000];
- UINT16 m_pf2_rowscroll[0x1000];
- UINT16 m_pf3_rowscroll[0x1000];
- UINT16 m_pf4_rowscroll[0x1000];
-
- required_device m_deco_tilegen1;
- required_device m_deco_tilegen2;
-
- required_device m_gfxdecode;
- required_device m_screen;
- required_device m_palette;
required_shared_ptr m_generic_paletteram_32;
+ optional_shared_ptr m_ace_ram;
- UINT8 m_irq_source;
- DECLARE_WRITE_LINE_MEMBER(sound_irq_nslasher);
- DECLARE_READ32_MEMBER(deco32_irq_controller_r);
- DECLARE_WRITE32_MEMBER(deco32_irq_controller_w);
- DECLARE_WRITE32_MEMBER(deco32_sound_w);
- DECLARE_READ32_MEMBER(deco32_71_r);
+ int m_raster_enable; // captaven, dragongun and lockload
+ timer_device *m_raster_irq_timer; // captaven, dragongun and lockload
+ UINT8 m_nslasher_sound_irq; // nslasher and lockload
+ UINT8 m_irq_source; // captaven, dragongun and lockload
+ int m_tattass_eprom_bit; // tattass
+ int m_lastClock; // tattass
+ char m_buffer[32]; // tattass
+ int m_bufPtr; // tattass
+ int m_pendingCommand; // tattass
+ int m_readBitCount; // tattass
+ int m_byteAddr; // tattass
+ int m_ace_ram_dirty; // nslasher and tattass
+ int m_has_ace_ram; // all - config
+ UINT8 *m_dirty_palette; // all but captaven
+ int m_pri; // captaven, fghthist, nslasher and tattass
+ bitmap_ind16 *m_tilemap_alpha_bitmap; // nslasher
+ UINT16 m_spriteram16[0x1000]; // captaven, fghthist, nslasher and tattass
+ UINT16 m_spriteram16_buffered[0x1000]; // captaven, fghthist, nslasher and tattass
+ UINT16 m_spriteram16_2[0x1000]; //nslasher and tattass
+ UINT16 m_spriteram16_2_buffered[0x1000]; //nslasher and tattass
+ UINT16 m_pf1_rowscroll[0x1000]; // common
+ UINT16 m_pf2_rowscroll[0x1000]; // common
+ UINT16 m_pf3_rowscroll[0x1000]; // common
+ UINT16 m_pf4_rowscroll[0x1000]; // common
+
+ // common
+ DECLARE_WRITE32_MEMBER(pf1_rowscroll_w);
+ DECLARE_WRITE32_MEMBER(pf2_rowscroll_w);
+ DECLARE_WRITE32_MEMBER(pf3_rowscroll_w);
+ DECLARE_WRITE32_MEMBER(pf4_rowscroll_w);
+ DECLARE_WRITE8_MEMBER(sound_bankswitch_w);
+
+ // captaven
+ DECLARE_READ32_MEMBER(_71_r);
DECLARE_READ32_MEMBER(captaven_soundcpu_r);
+ DECLARE_WRITE32_MEMBER(nonbuffered_palette_w);
+
+ // fghthist
+ DECLARE_WRITE32_MEMBER(sound_w);
DECLARE_READ32_MEMBER(fghthist_control_r);
DECLARE_WRITE32_MEMBER(fghthist_eeprom_w);
- DECLARE_READ32_MEMBER(dragngun_service_r);
- DECLARE_READ32_MEMBER(lockload_gun_mirror_r);
- DECLARE_READ32_MEMBER(tattass_prot_r);
- DECLARE_WRITE32_MEMBER(tattass_prot_w);
- DECLARE_WRITE32_MEMBER(tattass_control_w);
- //DECLARE_READ32_MEMBER(nslasher_prot_r);
- DECLARE_READ16_MEMBER( nslasher_protection_region_0_104_r );
- DECLARE_WRITE16_MEMBER( nslasher_protection_region_0_104_w );
- DECLARE_READ16_MEMBER( nslasher_debug_r );
+ DECLARE_READ32_MEMBER(fghthist_protection_region_0_146_r);
+ DECLARE_WRITE32_MEMBER(fghthist_protection_region_0_146_w);
+ // nslasher
DECLARE_WRITE32_MEMBER(nslasher_eeprom_w);
- //DECLARE_WRITE32_MEMBER(nslasher_prot_w);
- DECLARE_READ32_MEMBER(deco32_spriteram_r);
- DECLARE_WRITE32_MEMBER(deco32_spriteram_w);
- DECLARE_WRITE32_MEMBER(deco32_buffer_spriteram_w);
- DECLARE_READ32_MEMBER(deco32_spriteram2_r);
- DECLARE_WRITE32_MEMBER(deco32_spriteram2_w);
- DECLARE_WRITE32_MEMBER(deco32_buffer_spriteram2_w);
- DECLARE_WRITE32_MEMBER(deco32_pf1_rowscroll_w);
- DECLARE_WRITE32_MEMBER(deco32_pf2_rowscroll_w);
- DECLARE_WRITE32_MEMBER(deco32_pf3_rowscroll_w);
- DECLARE_WRITE32_MEMBER(deco32_pf4_rowscroll_w);
+
+ // tattass
+ DECLARE_WRITE32_MEMBER(tattass_control_w);
+
+ // nslasher and lockload
+ DECLARE_WRITE_LINE_MEMBER(sound_irq_nslasher);
DECLARE_READ8_MEMBER(latch_r);
- DECLARE_WRITE32_MEMBER(deco32_pri_w);
- DECLARE_WRITE32_MEMBER(deco32_ace_ram_w);
- DECLARE_WRITE32_MEMBER(deco32_nonbuffered_palette_w);
- DECLARE_WRITE32_MEMBER(deco32_buffered_palette_w);
- DECLARE_WRITE32_MEMBER(deco32_palette_dma_w);
- DECLARE_READ32_MEMBER(dragngun_eeprom_r);
- DECLARE_WRITE32_MEMBER(dragngun_eeprom_w);
- DECLARE_WRITE8_MEMBER(sound_bankswitch_w);
+
+ // captaven, dragongun and lockload
+ DECLARE_READ32_MEMBER(irq_controller_r);
+ DECLARE_WRITE32_MEMBER(irq_controller_w);
+
+ // nslasher and tattass
+ DECLARE_READ16_MEMBER(nslasher_protection_region_0_104_r);
+ DECLARE_WRITE16_MEMBER(nslasher_protection_region_0_104_w);
+ DECLARE_READ16_MEMBER(nslasher_debug_r);
+ DECLARE_READ32_MEMBER(spriteram2_r);
+ DECLARE_WRITE32_MEMBER(spriteram2_w);
+ DECLARE_WRITE32_MEMBER(buffer_spriteram2_w);
+ DECLARE_WRITE32_MEMBER(ace_ram_w);
+
+ // captaven, fghthist, nslasher and tattass
+ DECLARE_READ32_MEMBER(spriteram_r);
+ DECLARE_WRITE32_MEMBER(spriteram_w);
+ DECLARE_WRITE32_MEMBER(buffer_spriteram_w);
+ DECLARE_WRITE32_MEMBER(pri_w);
+
+ // all but captaven
+ DECLARE_WRITE32_MEMBER(buffered_palette_w);
+ DECLARE_WRITE32_MEMBER(palette_dma_w);
+
+ // captaven, dragongun and lockload
+ DECLARE_READ16_MEMBER(dg_protection_region_0_146_r);
+ DECLARE_WRITE16_MEMBER(dg_protection_region_0_146_w);
+
+ virtual void video_start();
DECLARE_DRIVER_INIT(tattass);
DECLARE_DRIVER_INIT(nslasher);
DECLARE_DRIVER_INIT(captaven);
@@ -151,23 +160,19 @@ public:
DECLARE_VIDEO_START(captaven);
DECLARE_VIDEO_START(fghthist);
DECLARE_VIDEO_START(nslasher);
+
+ INTERRUPT_GEN_MEMBER(deco32_vbl_interrupt);
+ TIMER_DEVICE_CALLBACK_MEMBER(interrupt_gen);
+
UINT32 screen_update_captaven(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
UINT32 screen_update_fghthist(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
UINT32 screen_update_nslasher(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
- void screen_eof_captaven(screen_device &screen, bool state);
- INTERRUPT_GEN_MEMBER(deco32_vbl_interrupt);
- TIMER_DEVICE_CALLBACK_MEMBER(interrupt_gen);
- TIMER_DEVICE_CALLBACK_MEMBER(lockload_vbl_irq);
void updateAceRam();
void mixDualAlphaSprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, gfx_element *gfx0, gfx_element *gfx1, int mixAlphaTilemap);
UINT16 port_a_fghthist(int unused);
UINT16 port_b_fghthist(int unused);
UINT16 port_c_fghthist(int unused);
- READ32_MEMBER( fghthist_protection_region_0_146_r );
- WRITE32_MEMBER( fghthist_protection_region_0_146_w );
- READ16_MEMBER( dg_protection_region_0_146_r );
- WRITE16_MEMBER( dg_protection_region_0_146_w );
void deco32_sound_cb( address_space &space, UINT16 data, UINT16 mem_mask );
UINT16 port_b_nslasher(int unused);
@@ -186,37 +191,43 @@ class dragngun_state : public deco32_state
public:
dragngun_state(const machine_config &mconfig, device_type type, const char *tag)
: deco32_state(mconfig, type, tag),
- m_dragngun_sprite_layout_0_ram(*this, "dragngun_lay0"),
- m_dragngun_sprite_layout_1_ram(*this, "dragngun_lay1"),
- m_dragngun_sprite_lookup_0_ram(*this, "dragngun_look0"),
- m_dragngun_sprite_lookup_1_ram(*this, "dragngun_look1")
+ m_sprite_layout_0_ram(*this, "lay0"),
+ m_sprite_layout_1_ram(*this, "lay1"),
+ m_sprite_lookup_0_ram(*this, "look0"),
+ m_sprite_lookup_1_ram(*this, "look1")
{ }
- required_shared_ptr m_dragngun_sprite_layout_0_ram;
- required_shared_ptr m_dragngun_sprite_layout_1_ram;
- required_shared_ptr m_dragngun_sprite_lookup_0_ram;
- required_shared_ptr m_dragngun_sprite_lookup_1_ram;
+ required_shared_ptr m_sprite_layout_0_ram;
+ required_shared_ptr m_sprite_layout_1_ram;
+ required_shared_ptr m_sprite_lookup_0_ram;
+ required_shared_ptr m_sprite_lookup_1_ram;
- UINT32 m_dragngun_sprite_ctrl;
- int m_dragngun_lightgun_port;
- DECLARE_READ32_MEMBER(dragngun_lightgun_r);
- DECLARE_WRITE32_MEMBER(dragngun_lightgun_w);
- DECLARE_WRITE32_MEMBER(dragngun_sprite_control_w);
- DECLARE_WRITE32_MEMBER(dragngun_spriteram_dma_w);
+ UINT32 m_sprite_ctrl;
+ int m_lightgun_port;
+ bitmap_rgb32 m_temp_render_bitmap;
+
+ DECLARE_READ32_MEMBER(lightgun_r);
+ DECLARE_WRITE32_MEMBER(lightgun_w);
+ DECLARE_WRITE32_MEMBER(sprite_control_w);
+ DECLARE_WRITE32_MEMBER(spriteram_dma_w);
+ DECLARE_READ32_MEMBER(unk_video_r);
+ DECLARE_READ32_MEMBER(service_r);
+ DECLARE_READ32_MEMBER(eeprom_r);
+ DECLARE_WRITE32_MEMBER(eeprom_w);
+ DECLARE_READ32_MEMBER(lockload_gun_mirror_r);
+
+ virtual void video_start();
DECLARE_DRIVER_INIT(dragngun);
DECLARE_DRIVER_INIT(dragngunj);
DECLARE_DRIVER_INIT(lockload);
DECLARE_VIDEO_START(dragngun);
DECLARE_VIDEO_START(lockload);
+ void dragngun_init_common();
+
+ TIMER_DEVICE_CALLBACK_MEMBER(lockload_vbl_irq);
+
UINT32 screen_update_dragngun(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
- void init_dragngun_common();
- void screen_eof_dragngun(screen_device &screen, bool state);
- void dragngun_draw_sprites( bitmap_rgb32 &bitmap, const rectangle &cliprect, const UINT32 *spritedata);
- READ32_MEMBER( dragngun_unk_video_r );
DECO16IC_BANK_CB_MEMBER(bank_1_callback);
DECO16IC_BANK_CB_MEMBER(bank_2_callback);
-
- bitmap_rgb32 m_temp_render_bitmap;
-
};
diff --git a/src/mame/includes/taitoair.h b/src/mame/includes/taitoair.h
index b5536f6cfa9..356801eede6 100644
--- a/src/mame/includes/taitoair.h
+++ b/src/mame/includes/taitoair.h
@@ -119,6 +119,7 @@ public:
DECLARE_READ16_MEMBER(stick2_input_r);
DECLARE_WRITE8_MEMBER(sound_bankswitch_w);
DECLARE_WRITE16_MEMBER(dsp_flags_w);
+ DECLARE_WRITE16_MEMBER(dma_regs_w);
virtual void machine_start();
virtual void machine_reset();
@@ -126,7 +127,10 @@ public:
UINT32 screen_update_taitoair(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
int draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect );
int draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect, int start_offset );
-
+ void fb_copy_op(void);
+ void fb_fill_op(void);
+ void fb_erase_op(void);
+
void fill_slope( bitmap_ind16 &bitmap, const rectangle &cliprect, UINT16 header, INT32 x1, INT32 x2, INT32 sl1, INT32 sl2, INT32 y1, INT32 y2, INT32 *nx1, INT32 *nx2 );
void fill_poly( bitmap_ind16 &bitmap, const rectangle &cliprect, const struct taitoair_poly *q );
int projectEyeCoordToScreen(float* projectionMatrix,const int Res,INT16* eyePoint3d,int type);
diff --git a/src/mame/mess.lst b/src/mame/mess.lst
index dba48281b60..4d0d3b51e36 100644
--- a/src/mame/mess.lst
+++ b/src/mame/mess.lst
@@ -1587,6 +1587,9 @@ hbf9sp
fsa1gt
fsa1st
+// Microsoft
+xbox
+
// NASCOM Microcomputers
nascom1 // 1978 Nascom 1
nascom2 // 1979 Nascom 2
diff --git a/src/mame/video/deco32.c b/src/mame/video/deco32.c
index c739522ef5d..122285f9674 100644
--- a/src/mame/video/deco32.c
+++ b/src/mame/video/deco32.c
@@ -5,24 +5,24 @@
/******************************************************************************/
-WRITE32_MEMBER(deco32_state::deco32_pri_w)
+WRITE32_MEMBER(deco32_state::pri_w)
{
m_pri=data;
}
-WRITE32_MEMBER(dragngun_state::dragngun_sprite_control_w)
+WRITE32_MEMBER(dragngun_state::sprite_control_w)
{
- m_dragngun_sprite_ctrl=data;
+ m_sprite_ctrl=data;
}
-WRITE32_MEMBER(dragngun_state::dragngun_spriteram_dma_w)
+WRITE32_MEMBER(dragngun_state::spriteram_dma_w)
{
/* DMA spriteram to private sprite chip area, and clear cpu ram */
m_spriteram->copy();
memset(m_spriteram->live(),0,0x2000);
}
-WRITE32_MEMBER(deco32_state::deco32_ace_ram_w)
+WRITE32_MEMBER(deco32_state::ace_ram_w)
{
/* Some notes pieced together from Tattoo Assassins info:
@@ -98,7 +98,7 @@ void deco32_state::updateAceRam()
/* Later games have double buffered paletteram - the real palette ram is
only updated on a DMA call */
-WRITE32_MEMBER(deco32_state::deco32_nonbuffered_palette_w)
+WRITE32_MEMBER(deco32_state::nonbuffered_palette_w)
{
int r,g,b;
@@ -111,13 +111,13 @@ WRITE32_MEMBER(deco32_state::deco32_nonbuffered_palette_w)
m_palette->set_pen_color(offset,rgb_t(r,g,b));
}
-WRITE32_MEMBER(deco32_state::deco32_buffered_palette_w)
+WRITE32_MEMBER(deco32_state::buffered_palette_w)
{
COMBINE_DATA(&m_generic_paletteram_32[offset]);
m_dirty_palette[offset]=1;
}
-WRITE32_MEMBER(deco32_state::deco32_palette_dma_w)
+WRITE32_MEMBER(deco32_state::palette_dma_w)
{
const int m=m_palette->entries();
int r,g,b,i;
@@ -145,9 +145,22 @@ WRITE32_MEMBER(deco32_state::deco32_palette_dma_w)
/******************************************************************************/
+void deco32_state::video_start()
+{
+ save_item(NAME(m_pri));
+ save_item(NAME(m_spriteram16));
+ save_item(NAME(m_spriteram16_buffered));
+ save_item(NAME(m_pf1_rowscroll));
+ save_item(NAME(m_pf2_rowscroll));
+ save_item(NAME(m_pf3_rowscroll));
+ save_item(NAME(m_pf4_rowscroll));
+}
+
VIDEO_START_MEMBER(deco32_state,captaven)
{
m_has_ace_ram=0;
+
+ deco32_state::video_start();
}
VIDEO_START_MEMBER(deco32_state,fghthist)
@@ -155,30 +168,9 @@ VIDEO_START_MEMBER(deco32_state,fghthist)
m_dirty_palette = auto_alloc_array(machine(), UINT8, 4096);
m_sprgen->alloc_sprite_bitmap();
m_has_ace_ram=0;
-}
-
-VIDEO_START_MEMBER(dragngun_state,dragngun)
-{
- m_dirty_palette = auto_alloc_array(machine(), UINT8, 4096);
- m_screen->register_screen_bitmap(m_temp_render_bitmap);
-
- memset(m_dirty_palette,0,4096);
-
- save_item(NAME(m_dragngun_sprite_ctrl));
- m_has_ace_ram=0;
-
-
-}
-
-VIDEO_START_MEMBER(dragngun_state,lockload)
-{
- m_dirty_palette = auto_alloc_array(machine(), UINT8, 4096);
- m_screen->register_screen_bitmap(m_temp_render_bitmap);
-
- memset(m_dirty_palette,0,4096);
-
- save_item(NAME(m_dragngun_sprite_ctrl));
- m_has_ace_ram=0;
+
+ save_pointer(NAME(m_dirty_palette), 4096);
+ deco32_state::video_start();
}
VIDEO_START_MEMBER(deco32_state,nslasher)
@@ -191,26 +183,59 @@ VIDEO_START_MEMBER(deco32_state,nslasher)
m_sprgen1->alloc_sprite_bitmap();
m_sprgen2->alloc_sprite_bitmap();
memset(m_dirty_palette,0,4096);
- save_item(NAME(m_pri));
m_has_ace_ram=1;
+
+ save_pointer(NAME(m_dirty_palette), 4096);
+ save_item(NAME(m_ace_ram_dirty));
+ save_item(NAME(m_spriteram16_2));
+ save_item(NAME(m_spriteram16_2_buffered));
+
+ deco32_state::video_start();
}
+void dragngun_state::video_start()
+{
+ save_item(NAME(m_pf1_rowscroll));
+ save_item(NAME(m_pf2_rowscroll));
+ save_item(NAME(m_pf3_rowscroll));
+ save_item(NAME(m_pf4_rowscroll));
+}
+
+VIDEO_START_MEMBER(dragngun_state,dragngun)
+{
+ m_dirty_palette = auto_alloc_array(machine(), UINT8, 4096);
+ m_screen->register_screen_bitmap(m_temp_render_bitmap);
+
+ memset(m_dirty_palette,0,4096);
+
+ m_has_ace_ram=0;
+
+ save_item(NAME(m_sprite_ctrl));
+ save_pointer(NAME(m_dirty_palette), 4096);
+}
+
+VIDEO_START_MEMBER(dragngun_state,lockload)
+{
+ m_dirty_palette = auto_alloc_array(machine(), UINT8, 4096);
+ m_screen->register_screen_bitmap(m_temp_render_bitmap);
+
+ memset(m_dirty_palette,0,4096);
+
+ m_has_ace_ram=0;
+
+ save_item(NAME(m_sprite_ctrl));
+ save_pointer(NAME(m_dirty_palette), 4096);
+}
/******************************************************************************/
-void deco32_state::screen_eof_captaven(screen_device &screen, bool state)
-{
-}
-
-void dragngun_state::screen_eof_dragngun(screen_device &screen, bool state)
-{
-}
-
/******************************************************************************/
UINT32 deco32_state::screen_update_captaven(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
- machine().tilemap().set_flip_all(flip_screen() ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
+ address_space &space = machine().driver_data()->generic_space();
+ UINT16 flip = m_deco_tilegen1->pf_control_r(space, 0, 0xffff);
+ flip_screen_set(BIT(flip, 7));
screen.priority().fill(0, cliprect);
bitmap.fill(m_palette->pen(0x000), cliprect); // Palette index not confirmed
@@ -267,7 +292,7 @@ UINT32 dragngun_state::screen_update_dragngun(screen_device &screen, bitmap_rgb3
{
rectangle clip(cliprect.min_x, cliprect.max_x, 8, 247);
- m_sprgenzoom->dragngun_draw_sprites(bitmap,clip,m_spriteram->buffer(), m_dragngun_sprite_layout_0_ram, m_dragngun_sprite_layout_1_ram, m_dragngun_sprite_lookup_0_ram, m_dragngun_sprite_lookup_1_ram, m_dragngun_sprite_ctrl, screen.priority(), m_temp_render_bitmap );
+ m_sprgenzoom->dragngun_draw_sprites(bitmap,clip,m_spriteram->buffer(), m_sprite_layout_0_ram, m_sprite_layout_1_ram, m_sprite_lookup_0_ram, m_sprite_lookup_1_ram, m_sprite_ctrl, screen.priority(), m_temp_render_bitmap );
}
diff --git a/src/mame/video/n64.c b/src/mame/video/n64.c
index a60699568bb..8db89f35cec 100644
--- a/src/mame/video/n64.c
+++ b/src/mame/video/n64.c
@@ -3201,3 +3201,828 @@ UINT32 n64_state::screen_update_n64(screen_device &screen, bitmap_rgb32 &bitmap,
return 0;
}
+
+void n64_rdp::render_spans(INT32 start, INT32 end, INT32 tilenum, bool flip, extent_t* spans, bool rect, rdp_poly_state* object)
+{
+ const INT32 clipy1 = m_scissor.m_yh;
+ const INT32 clipy2 = m_scissor.m_yl;
+ INT32 offset = 0;
+
+ if (clipy2 <= 0)
+ {
+ return;
+ }
+
+ if (start < clipy1)
+ {
+ offset = clipy1 - start;
+ start = clipy1;
+ }
+ if (start >= clipy2)
+ {
+ offset = start - (clipy2 - 1);
+ start = clipy2 - 1;
+ }
+ if (end < clipy1)
+ {
+ end = clipy1;
+ }
+ if (end >= clipy2)
+ {
+ end = clipy2 - 1;
+ }
+
+ object->m_rdp = this;
+ memcpy(&object->m_misc_state, &m_misc_state, sizeof(misc_state_t));
+ memcpy(&object->m_other_modes, &m_other_modes, sizeof(other_modes_t));
+ memcpy(&object->m_span_base, &m_span_base, sizeof(span_base_t));
+ memcpy(&object->m_scissor, &m_scissor, sizeof(rectangle_t));
+ memcpy(&object->m_tiles, &m_tiles, 8 * sizeof(n64_tile_t));
+ object->tilenum = tilenum;
+ object->flip = flip;
+ object->m_fill_color = m_fill_color;
+ object->rect = rect;
+
+ switch(m_other_modes.cycle_type)
+ {
+ case CYCLE_TYPE_1:
+ render_triangle_custom(m_visarea, render_delegate(FUNC(n64_rdp::span_draw_1cycle), this), start, (end - start) + 1, spans + offset);
+ break;
+
+ case CYCLE_TYPE_2:
+ render_triangle_custom(m_visarea, render_delegate(FUNC(n64_rdp::span_draw_2cycle), this), start, (end - start) + 1, spans + offset);
+ break;
+
+ case CYCLE_TYPE_COPY:
+ render_triangle_custom(m_visarea, render_delegate(FUNC(n64_rdp::span_draw_copy), this), start, (end - start) + 1, spans + offset);
+ break;
+
+ case CYCLE_TYPE_FILL:
+ render_triangle_custom(m_visarea, render_delegate(FUNC(n64_rdp::span_draw_fill), this), start, (end - start) + 1, spans + offset);
+ break;
+ }
+ //wait();
+}
+
+void n64_rdp::rgbaz_clip(INT32 sr, INT32 sg, INT32 sb, INT32 sa, INT32* sz, rdp_span_aux* userdata)
+{
+ userdata->m_shade_color.set(sa, sr, sg, sb);
+ userdata->m_shade_color.clamp_and_clear(0xfffffe00);
+ UINT32 a = userdata->m_shade_color.get_a();
+ userdata->m_shade_alpha.set(a, a, a, a);
+
+ INT32 zanded = (*sz) & 0x60000;
+
+ zanded >>= 17;
+ switch(zanded)
+ {
+ case 0: *sz &= 0x3ffff; break;
+ case 1: *sz &= 0x3ffff; break;
+ case 2: *sz = 0x3ffff; break;
+ case 3: *sz = 0x3ffff; break;
+ }
+}
+
+void n64_rdp::rgbaz_correct_triangle(INT32 offx, INT32 offy, INT32* r, INT32* g, INT32* b, INT32* a, INT32* z, rdp_span_aux* userdata, const rdp_poly_state &object)
+{
+ if (userdata->m_current_pix_cvg == 8)
+ {
+ *r >>= 2;
+ *g >>= 2;
+ *b >>= 2;
+ *a >>= 2;
+ *z = (*z >> 3) & 0x7ffff;
+ }
+ else
+ {
+ INT32 summand_xr = offx * SIGN13(object.m_span_base.m_span_dr >> 14);
+ INT32 summand_yr = offy * SIGN13(object.m_span_base.m_span_drdy >> 14);
+ INT32 summand_xb = offx * SIGN13(object.m_span_base.m_span_db >> 14);
+ INT32 summand_yb = offy * SIGN13(object.m_span_base.m_span_dbdy >> 14);
+ INT32 summand_xg = offx * SIGN13(object.m_span_base.m_span_dg >> 14);
+ INT32 summand_yg = offy * SIGN13(object.m_span_base.m_span_dgdy >> 14);
+ INT32 summand_xa = offx * SIGN13(object.m_span_base.m_span_da >> 14);
+ INT32 summand_ya = offy * SIGN13(object.m_span_base.m_span_dady >> 14);
+
+ INT32 summand_xz = offx * SIGN22(object.m_span_base.m_span_dz >> 10);
+ INT32 summand_yz = offy * SIGN22(object.m_span_base.m_span_dzdy >> 10);
+
+ *r = ((*r << 2) + summand_xr + summand_yr) >> 4;
+ *g = ((*g << 2) + summand_xg + summand_yg) >> 4;
+ *b = ((*b << 2) + summand_xb + summand_yb) >> 4;
+ *a = ((*a << 2) + summand_xa + summand_ya) >> 4;
+ *z = (((*z << 2) + summand_xz + summand_yz) >> 5) & 0x7ffff;
+ }
+}
+
+inline void n64_rdp::write_pixel(UINT32 curpixel, color_t& color, rdp_span_aux* userdata, const rdp_poly_state &object)
+{
+ if (object.m_misc_state.m_fb_size == 2) // 16-bit framebuffer
+ {
+ const UINT32 fb = (object.m_misc_state.m_fb_address >> 1) + curpixel;
+
+ UINT16 finalcolor;
+ if (object.m_other_modes.color_on_cvg && !userdata->m_pre_wrap)
+ {
+ finalcolor = RREADIDX16(fb) & 0xfffe;
+ }
+ else
+ {
+ color.shr_imm(3);
+ finalcolor = (color.get_r() << 11) | (color.get_g() << 6) | (color.get_b() << 1);
+ }
+
+ switch (object.m_other_modes.cvg_dest)
+ {
+ case 0:
+ if (userdata->m_blend_enable)
+ {
+ UINT32 finalcvg = userdata->m_current_pix_cvg + userdata->m_current_mem_cvg;
+ if (finalcvg & 8)
+ {
+ finalcvg = 7;
+ }
+ RWRITEIDX16(fb, finalcolor | (finalcvg >> 2));
+ HWRITEADDR8(fb, finalcvg & 3);
+ }
+ else
+ {
+ const UINT32 finalcvg = (userdata->m_current_pix_cvg - 1) & 7;
+ RWRITEIDX16(fb, finalcolor | (finalcvg >> 2));
+ HWRITEADDR8(fb, finalcvg & 3);
+ }
+ break;
+ case 1:
+ {
+ const UINT32 finalcvg = (userdata->m_current_pix_cvg + userdata->m_current_mem_cvg) & 7;
+ RWRITEIDX16(fb, finalcolor | (finalcvg >> 2));
+ HWRITEADDR8(fb, finalcvg & 3);
+ break;
+ }
+ case 2:
+ RWRITEIDX16(fb, finalcolor | 1);
+ HWRITEADDR8(fb, 3);
+ break;
+ case 3:
+ RWRITEIDX16(fb, finalcolor | (userdata->m_current_mem_cvg >> 2));
+ HWRITEADDR8(fb, userdata->m_current_mem_cvg & 3);
+ break;
+ }
+ }
+ else // 32-bit framebuffer
+ {
+ const UINT32 fb = (object.m_misc_state.m_fb_address >> 2) + curpixel;
+
+ UINT32 finalcolor;
+ if (object.m_other_modes.color_on_cvg && !userdata->m_pre_wrap)
+ {
+ finalcolor = RREADIDX32(fb) & 0xffffff00;
+ }
+ else
+ {
+ finalcolor = (color.get_r() << 24) | (color.get_g() << 16) | (color.get_b() << 8);
+ }
+
+ switch (object.m_other_modes.cvg_dest)
+ {
+ case 0:
+ if (userdata->m_blend_enable)
+ {
+ UINT32 finalcvg = userdata->m_current_pix_cvg + userdata->m_current_mem_cvg;
+ if (finalcvg & 8)
+ {
+ finalcvg = 7;
+ }
+
+ RWRITEIDX32(fb, finalcolor | (finalcvg << 5));
+ }
+ else
+ {
+ RWRITEIDX32(fb, finalcolor | (((userdata->m_current_pix_cvg - 1) & 7) << 5));
+ }
+ break;
+ case 1:
+ RWRITEIDX32(fb, finalcolor | (((userdata->m_current_pix_cvg + userdata->m_current_mem_cvg) & 7) << 5));
+ break;
+ case 2:
+ RWRITEIDX32(fb, finalcolor | 0xE0);
+ break;
+ case 3:
+ RWRITEIDX32(fb, finalcolor | (userdata->m_current_mem_cvg << 5));
+ break;
+ }
+ }
+}
+
+inline void n64_rdp::read_pixel(UINT32 curpixel, rdp_span_aux* userdata, const rdp_poly_state &object)
+{
+ if (object.m_misc_state.m_fb_size == 2) // 16-bit framebuffer
+ {
+ const UINT16 fword = RREADIDX16((object.m_misc_state.m_fb_address >> 1) + curpixel);
+
+ userdata->m_memory_color.set(0, GETHICOL(fword), GETMEDCOL(fword), GETLOWCOL(fword));
+ if (object.m_other_modes.image_read_en)
+ {
+ UINT8 hbyte = HREADADDR8((object.m_misc_state.m_fb_address >> 1) + curpixel);
+ userdata->m_memory_color.set_a(userdata->m_current_mem_cvg << 5);
+ userdata->m_current_mem_cvg = ((fword & 1) << 2) | (hbyte & 3);
+ }
+ else
+ {
+ userdata->m_memory_color.set_a(0xff);
+ userdata->m_current_mem_cvg = 7;
+ }
+ }
+ else // 32-bit framebuffer
+ {
+ const UINT32 mem = RREADIDX32((object.m_misc_state.m_fb_address >> 2) + curpixel);
+ userdata->m_memory_color.set(0, (mem >> 24) & 0xff, (mem >> 16) & 0xff, (mem >> 8) & 0xff);
+ if (object.m_other_modes.image_read_en)
+ {
+ userdata->m_memory_color.set_a(mem & 0xff);
+ userdata->m_current_mem_cvg = (mem >> 5) & 7;
+ }
+ else
+ {
+ userdata->m_memory_color.set_a(0xff);
+ userdata->m_current_mem_cvg = 7;
+ }
+ }
+}
+
+inline void n64_rdp::copy_pixel(UINT32 curpixel, color_t& color, const rdp_poly_state &object)
+{
+ const UINT32 current_pix_cvg = color.get_a() ? 7 : 0;
+ const UINT8 r = color.get_r(); // Vectorize me
+ const UINT8 g = color.get_g();
+ const UINT8 b = color.get_b();
+ if (object.m_misc_state.m_fb_size == 2) // 16-bit framebuffer
+ {
+ RWRITEIDX16((object.m_misc_state.m_fb_address >> 1) + curpixel, ((r >> 3) << 11) | ((g >> 3) << 6) | ((b >> 3) << 1) | ((current_pix_cvg >> 2) & 1));
+ HWRITEADDR8((object.m_misc_state.m_fb_address >> 1) + curpixel, current_pix_cvg & 3);
+ }
+ else // 32-bit framebuffer
+ {
+ RWRITEIDX32((object.m_misc_state.m_fb_address >> 2) + curpixel, (r << 24) | (g << 16) | (b << 8) | (current_pix_cvg << 5));
+ }
+}
+
+inline void n64_rdp::fill_pixel(UINT32 curpixel, const rdp_poly_state &object)
+{
+ if (object.m_misc_state.m_fb_size == 2) // 16-bit framebuffer
+ {
+ UINT16 val;
+ if (curpixel & 1)
+ {
+ val = object.m_fill_color & 0xffff;
+ }
+ else
+ {
+ val = (object.m_fill_color >> 16) & 0xffff;
+ }
+ RWRITEIDX16((object.m_misc_state.m_fb_address >> 1) + curpixel, val);
+ HWRITEADDR8((object.m_misc_state.m_fb_address >> 1) + curpixel, ((val & 1) << 1) | (val & 1));
+ }
+ else // 32-bit framebuffer
+ {
+ RWRITEIDX32((object.m_misc_state.m_fb_address >> 2) + curpixel, object.m_fill_color);
+ HWRITEADDR8((object.m_misc_state.m_fb_address >> 1) + (curpixel << 1), (object.m_fill_color & 0x10000) ? 3 : 0);
+ HWRITEADDR8((object.m_misc_state.m_fb_address >> 1) + (curpixel << 1) + 1, (object.m_fill_color & 0x1) ? 3 : 0);
+ }
+}
+
+void n64_rdp::span_draw_1cycle(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, INT32 threadid)
+{
+ assert(object.m_misc_state.m_fb_size >= 2 && object.m_misc_state.m_fb_size < 4);
+
+ const INT32 clipx1 = object.m_scissor.m_xh;
+ const INT32 clipx2 = object.m_scissor.m_xl;
+ const INT32 tilenum = object.tilenum;
+ const bool flip = object.flip;
+
+ span_param_t r; r.w = extent.param[SPAN_R].start;
+ span_param_t g; g.w = extent.param[SPAN_G].start;
+ span_param_t b; b.w = extent.param[SPAN_B].start;
+ span_param_t a; a.w = extent.param[SPAN_A].start;
+ span_param_t z; z.w = extent.param[SPAN_Z].start;
+ span_param_t s; s.w = extent.param[SPAN_S].start;
+ span_param_t t; t.w = extent.param[SPAN_T].start;
+ span_param_t w; w.w = extent.param[SPAN_W].start;
+
+ const UINT32 zb = object.m_misc_state.m_zb_address >> 1;
+ const UINT32 zhb = object.m_misc_state.m_zb_address;
+
+#ifdef PTR64
+ assert(extent.userdata != (const void *)0xcccccccccccccccc);
+#else
+ assert(extent.userdata != (const void *)0xcccccccc);
+#endif
+ rdp_span_aux* userdata = (rdp_span_aux*)extent.userdata;
+
+ m_tex_pipe.calculate_clamp_diffs(tilenum, userdata, object);
+
+ const bool partialreject = (userdata->m_color_inputs.blender2b_a[0] == &userdata->m_inv_pixel_color && userdata->m_color_inputs.blender1b_a[0] == &userdata->m_pixel_color);
+ const INT32 sel0 = (userdata->m_color_inputs.blender2b_a[0] == &userdata->m_memory_color) ? 1 : 0;
+
+ INT32 drinc, dginc, dbinc, dainc;
+ INT32 dzinc, dzpix;
+ INT32 dsinc, dtinc, dwinc;
+ INT32 xinc;
+
+ if (!flip)
+ {
+ drinc = -object.m_span_base.m_span_dr;
+ dginc = -object.m_span_base.m_span_dg;
+ dbinc = -object.m_span_base.m_span_db;
+ dainc = -object.m_span_base.m_span_da;
+ dzinc = -object.m_span_base.m_span_dz;
+ dsinc = -object.m_span_base.m_span_ds;
+ dtinc = -object.m_span_base.m_span_dt;
+ dwinc = -object.m_span_base.m_span_dw;
+ xinc = -1;
+ }
+ else
+ {
+ drinc = object.m_span_base.m_span_dr;
+ dginc = object.m_span_base.m_span_dg;
+ dbinc = object.m_span_base.m_span_db;
+ dainc = object.m_span_base.m_span_da;
+ dzinc = object.m_span_base.m_span_dz;
+ dsinc = object.m_span_base.m_span_ds;
+ dtinc = object.m_span_base.m_span_dt;
+ dwinc = object.m_span_base.m_span_dw;
+ xinc = 1;
+ }
+
+ const INT32 fb_index = object.m_misc_state.m_fb_width * scanline;
+
+ const INT32 xstart = extent.startx;
+ const INT32 xend = userdata->m_unscissored_rx;
+ const INT32 xend_scissored = extent.stopx;
+
+ INT32 x = xend;
+
+ const INT32 length = flip ? (xstart - xend) : (xend - xstart);
+
+ if(object.m_other_modes.z_source_sel)
+ {
+ z.w = object.m_misc_state.m_primitive_z;
+ dzpix = object.m_misc_state.m_primitive_dz;
+ dzinc = 0;
+ }
+ else
+ {
+ dzpix = object.m_span_base.m_span_dzpix;
+ }
+
+ if (object.m_misc_state.m_fb_size < 2 || object.m_misc_state.m_fb_size > 4)
+ fatalerror("unsupported m_fb_size %d\n", object.m_misc_state.m_fb_size);
+
+ const INT32 blend_index = (object.m_other_modes.alpha_cvg_select ? 2 : 0) | ((object.m_other_modes.rgb_dither_sel < 3) ? 1 : 0);
+ const INT32 cycle0 = ((object.m_other_modes.sample_type & 1) << 1) | (object.m_other_modes.bi_lerp0 & 1);
+
+ INT32 sss = 0;
+ INT32 sst = 0;
+
+ if (object.m_other_modes.persp_tex_en)
+ {
+ tc_div(s.w >> 16, t.w >> 16, w.w >> 16, &sss, &sst);
+ }
+ else
+ {
+ tc_div_no_perspective(s.w >> 16, t.w >> 16, w.w >> 16, &sss, &sst);
+ }
+
+ userdata->m_start_span = true;
+ for (INT32 j = 0; j <= length; j++)
+ {
+ INT32 sr = r.w >> 14;
+ INT32 sg = g.w >> 14;
+ INT32 sb = b.w >> 14;
+ INT32 sa = a.w >> 14;
+ INT32 sz = (z.w >> 10) & 0x3fffff;
+ const bool valid_x = (flip) ? (x >= xend_scissored) : (x <= xend_scissored);
+
+ if (x >= clipx1 && x < clipx2 && valid_x)
+ {
+ UINT8 offx, offy;
+ lookup_cvmask_derivatives(userdata->m_cvg[x], &offx, &offy, userdata);
+
+ m_tex_pipe.lod_1cycle(&sss, &sst, s.w, t.w, w.w, dsinc, dtinc, dwinc, userdata, object);
+
+ rgbaz_correct_triangle(offx, offy, &sr, &sg, &sb, &sa, &sz, userdata, object);
+ rgbaz_clip(sr, sg, sb, sa, &sz, userdata);
+
+ ((m_tex_pipe).*(m_tex_pipe.m_cycle[cycle0]))(&userdata->m_texel0_color, &userdata->m_texel0_color, sss, sst, tilenum, 0, userdata, object);
+ UINT32 t0a = userdata->m_texel0_color.get_a();
+ userdata->m_texel0_alpha.set(t0a, t0a, t0a, t0a);
+
+ const UINT8 noise = rand() << 3; // Not accurate
+ userdata->m_noise_color.set(0, noise, noise, noise);
+
+ rgbaint_t rgbsub_a(*userdata->m_color_inputs.combiner_rgbsub_a[1]);
+ rgbaint_t rgbsub_b(*userdata->m_color_inputs.combiner_rgbsub_b[1]);
+ rgbaint_t rgbmul(*userdata->m_color_inputs.combiner_rgbmul[1]);
+ rgbaint_t rgbadd(*userdata->m_color_inputs.combiner_rgbadd[1]);
+
+ rgbsub_a.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_a[1]);
+ rgbsub_b.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_b[1]);
+ rgbmul.merge_alpha(*userdata->m_color_inputs.combiner_alphamul[1]);
+ rgbadd.merge_alpha(*userdata->m_color_inputs.combiner_alphaadd[1]);
+
+ rgbsub_a.sign_extend(0x180, 0xfffffe00);
+ rgbsub_b.sign_extend(0x180, 0xfffffe00);
+ rgbadd.sign_extend(0x180, 0xfffffe00);
+
+ rgbadd.shl_imm(8);
+ rgbsub_a.sub(rgbsub_b);
+ rgbsub_a.mul(rgbmul);
+ rgbsub_a.add(rgbadd);
+ rgbsub_a.add_imm(0x0080);
+ rgbsub_a.sra_imm(8);
+ rgbsub_a.clamp_and_clear(0xfffffe00);
+
+ userdata->m_pixel_color = rgbsub_a;
+
+ //Alpha coverage combiner
+ userdata->m_pixel_color.set_a(get_alpha_cvg(userdata->m_pixel_color.get_a(), userdata, object));
+
+ const UINT32 curpixel = fb_index + x;
+ const UINT32 zbcur = zb + curpixel;
+ const UINT32 zhbcur = zhb + curpixel;
+
+ read_pixel(curpixel, userdata, object);
+
+ if(z_compare(zbcur, zhbcur, sz, dzpix, userdata, object))
+ {
+ INT32 cdith = 0;
+ INT32 adith = 0;
+ get_dither_values(scanline, j, &cdith, &adith, object);
+
+ color_t blended_pixel;
+ bool rendered = ((&m_blender)->*(m_blender.blend1[(userdata->m_blend_enable << 2) | blend_index]))(blended_pixel, cdith, adith, partialreject, sel0, userdata, object);
+
+ if (rendered)
+ {
+ write_pixel(curpixel, blended_pixel, userdata, object);
+ if (object.m_other_modes.z_update_en)
+ {
+ z_store(object, zbcur, zhbcur, sz, userdata->m_dzpix_enc);
+ }
+ }
+ }
+
+ sss = userdata->m_precomp_s;
+ sst = userdata->m_precomp_t;
+ }
+
+ r.w += drinc;
+ g.w += dginc;
+ b.w += dbinc;
+ a.w += dainc;
+ s.w += dsinc;
+ t.w += dtinc;
+ w.w += dwinc;
+ z.w += dzinc;
+
+ x += xinc;
+ }
+}
+
+void n64_rdp::span_draw_2cycle(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, INT32 threadid)
+{
+ assert(object.m_misc_state.m_fb_size >= 2 && object.m_misc_state.m_fb_size < 4);
+
+ const INT32 clipx1 = object.m_scissor.m_xh;
+ const INT32 clipx2 = object.m_scissor.m_xl;
+ const INT32 tilenum = object.tilenum;
+ const bool flip = object.flip;
+
+ span_param_t r; r.w = extent.param[SPAN_R].start;
+ span_param_t g; g.w = extent.param[SPAN_G].start;
+ span_param_t b; b.w = extent.param[SPAN_B].start;
+ span_param_t a; a.w = extent.param[SPAN_A].start;
+ span_param_t z; z.w = extent.param[SPAN_Z].start;
+ span_param_t s; s.w = extent.param[SPAN_S].start;
+ span_param_t t; t.w = extent.param[SPAN_T].start;
+ span_param_t w; w.w = extent.param[SPAN_W].start;
+
+ const UINT32 zb = object.m_misc_state.m_zb_address >> 1;
+ const UINT32 zhb = object.m_misc_state.m_zb_address;
+
+ INT32 tile2 = (tilenum + 1) & 7;
+ INT32 tile1 = tilenum;
+ const UINT32 prim_tile = tilenum;
+
+ INT32 newtile1 = tile1;
+ INT32 news = 0;
+ INT32 newt = 0;
+
+#ifdef PTR64
+ assert(extent.userdata != (const void *)0xcccccccccccccccc);
+#else
+ assert(extent.userdata != (const void *)0xcccccccc);
+#endif
+ rdp_span_aux* userdata = (rdp_span_aux*)extent.userdata;
+
+ m_tex_pipe.calculate_clamp_diffs(tile1, userdata, object);
+
+ bool partialreject = (userdata->m_color_inputs.blender2b_a[1] == &userdata->m_inv_pixel_color && userdata->m_color_inputs.blender1b_a[1] == &userdata->m_pixel_color);
+ INT32 sel0 = (userdata->m_color_inputs.blender2b_a[0] == &userdata->m_memory_color) ? 1 : 0;
+ INT32 sel1 = (userdata->m_color_inputs.blender2b_a[1] == &userdata->m_memory_color) ? 1 : 0;
+
+ INT32 drinc, dginc, dbinc, dainc;
+ INT32 dzinc, dzpix;
+ INT32 dsinc, dtinc, dwinc;
+ INT32 xinc;
+
+ if (!flip)
+ {
+ drinc = -object.m_span_base.m_span_dr;
+ dginc = -object.m_span_base.m_span_dg;
+ dbinc = -object.m_span_base.m_span_db;
+ dainc = -object.m_span_base.m_span_da;
+ dzinc = -object.m_span_base.m_span_dz;
+ dsinc = -object.m_span_base.m_span_ds;
+ dtinc = -object.m_span_base.m_span_dt;
+ dwinc = -object.m_span_base.m_span_dw;
+ xinc = -1;
+ }
+ else
+ {
+ drinc = object.m_span_base.m_span_dr;
+ dginc = object.m_span_base.m_span_dg;
+ dbinc = object.m_span_base.m_span_db;
+ dainc = object.m_span_base.m_span_da;
+ dzinc = object.m_span_base.m_span_dz;
+ dsinc = object.m_span_base.m_span_ds;
+ dtinc = object.m_span_base.m_span_dt;
+ dwinc = object.m_span_base.m_span_dw;
+ xinc = 1;
+ }
+
+ const INT32 fb_index = object.m_misc_state.m_fb_width * scanline;
+
+ INT32 cdith = 0;
+ INT32 adith = 0;
+
+ const INT32 xstart = extent.startx;
+ const INT32 xend = userdata->m_unscissored_rx;
+ const INT32 xend_scissored = extent.stopx;
+
+ INT32 x = xend;
+
+ const INT32 length = flip ? (xstart - xend) : (xend - xstart);
+
+ if(object.m_other_modes.z_source_sel)
+ {
+ z.w = object.m_misc_state.m_primitive_z;
+ dzpix = object.m_misc_state.m_primitive_dz;
+ dzinc = 0;
+ }
+ else
+ {
+ dzpix = object.m_span_base.m_span_dzpix;
+ }
+
+ if (object.m_misc_state.m_fb_size < 2 || object.m_misc_state.m_fb_size > 4)
+ fatalerror("unsupported m_fb_size %d\n", object.m_misc_state.m_fb_size);
+
+ const INT32 blend_index = (object.m_other_modes.alpha_cvg_select ? 2 : 0) | ((object.m_other_modes.rgb_dither_sel < 3) ? 1 : 0);
+ const INT32 cycle0 = ((object.m_other_modes.sample_type & 1) << 1) | (object.m_other_modes.bi_lerp0 & 1);
+ const INT32 cycle1 = ((object.m_other_modes.sample_type & 1) << 1) | (object.m_other_modes.bi_lerp1 & 1);
+
+ INT32 sss = 0;
+ INT32 sst = 0;
+
+ if (object.m_other_modes.persp_tex_en)
+ {
+ tc_div(s.w >> 16, t.w >> 16, w.w >> 16, &sss, &sst);
+ }
+ else
+ {
+ tc_div_no_perspective(s.w >> 16, t.w >> 16, w.w >> 16, &sss, &sst);
+ }
+
+ userdata->m_start_span = true;
+ for (INT32 j = 0; j <= length; j++)
+ {
+ INT32 sr = r.w >> 14;
+ INT32 sg = g.w >> 14;
+ INT32 sb = b.w >> 14;
+ INT32 sa = a.w >> 14;
+ INT32 sz = (z.w >> 10) & 0x3fffff;
+ color_t c1;
+ color_t c2;
+
+ const bool valid_x = (flip) ? (x >= xend_scissored) : (x <= xend_scissored);
+
+ if (x >= clipx1 && x < clipx2 && valid_x)
+ {
+ const UINT32 compidx = m_compressed_cvmasks[userdata->m_cvg[x]];
+ userdata->m_current_pix_cvg = cvarray[compidx].cvg;
+ userdata->m_current_cvg_bit = cvarray[compidx].cvbit;
+ const UINT8 offx = cvarray[compidx].xoff;
+ const UINT8 offy = cvarray[compidx].yoff;
+ //lookup_cvmask_derivatives(userdata->m_cvg[x], &offx, &offy, userdata);
+
+ m_tex_pipe.lod_2cycle(&sss, &sst, s.w, t.w, w.w, dsinc, dtinc, dwinc, prim_tile, &tile1, &tile2, userdata, object);
+
+ news = userdata->m_precomp_s;
+ newt = userdata->m_precomp_t;
+ m_tex_pipe.lod_2cycle_limited(&news, &newt, s.w + dsinc, t.w + dtinc, w.w + dwinc, dsinc, dtinc, dwinc, prim_tile, &newtile1, object);
+
+ rgbaz_correct_triangle(offx, offy, &sr, &sg, &sb, &sa, &sz, userdata, object);
+ rgbaz_clip(sr, sg, sb, sa, &sz, userdata);
+
+ ((m_tex_pipe).*(m_tex_pipe.m_cycle[cycle0]))(&userdata->m_texel0_color, &userdata->m_texel0_color, sss, sst, tile1, 0, userdata, object);
+ ((m_tex_pipe).*(m_tex_pipe.m_cycle[cycle1]))(&userdata->m_texel1_color, &userdata->m_texel0_color, sss, sst, tile2, 1, userdata, object);
+ ((m_tex_pipe).*(m_tex_pipe.m_cycle[cycle1]))(&userdata->m_next_texel_color, &userdata->m_next_texel_color, sss, sst, tile2, 1, userdata, object);
+
+ UINT32 t0a = userdata->m_texel0_color.get_a();
+ UINT32 t1a = userdata->m_texel1_color.get_a();
+ UINT32 tna = userdata->m_next_texel_color.get_a();
+ userdata->m_texel0_alpha.set(t0a, t0a, t0a, t0a);
+ userdata->m_texel1_alpha.set(t1a, t1a, t1a, t1a);
+ userdata->m_next_texel_alpha.set(tna, tna, tna, tna);
+
+ const UINT8 noise = rand() << 3; // Not accurate
+ userdata->m_noise_color.set(0, noise, noise, noise);
+
+ rgbaint_t rgbsub_a(*userdata->m_color_inputs.combiner_rgbsub_a[0]);
+ rgbaint_t rgbsub_b(*userdata->m_color_inputs.combiner_rgbsub_b[0]);
+ rgbaint_t rgbmul(*userdata->m_color_inputs.combiner_rgbmul[0]);
+ rgbaint_t rgbadd(*userdata->m_color_inputs.combiner_rgbadd[0]);
+
+ rgbsub_a.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_a[0]);
+ rgbsub_b.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_b[0]);
+ rgbmul.merge_alpha(*userdata->m_color_inputs.combiner_alphamul[0]);
+ rgbadd.merge_alpha(*userdata->m_color_inputs.combiner_alphaadd[0]);
+
+ rgbsub_a.sign_extend(0x180, 0xfffffe00);
+ rgbsub_b.sign_extend(0x180, 0xfffffe00);
+ rgbadd.sign_extend(0x180, 0xfffffe00);
+
+ rgbadd.shl_imm(8);
+ rgbsub_a.sub(rgbsub_b);
+ rgbsub_a.mul(rgbmul);
+
+ rgbsub_a.add(rgbadd);
+ rgbsub_a.add_imm(0x0080);
+ rgbsub_a.sra_imm(8);
+ rgbsub_a.clamp_and_clear(0xfffffe00);
+
+ userdata->m_combined_color.set(rgbsub_a);
+ userdata->m_texel0_color.set(userdata->m_texel1_color);
+ userdata->m_texel1_color.set(userdata->m_next_texel_color);
+
+ UINT32 ca = userdata->m_combined_color.get_a();
+ userdata->m_combined_alpha.set(ca, ca, ca, ca);
+ userdata->m_texel0_alpha.set(userdata->m_texel1_alpha);
+ userdata->m_texel1_alpha.set(userdata->m_next_texel_alpha);
+
+ rgbsub_a.set(*userdata->m_color_inputs.combiner_rgbsub_a[1]);
+ rgbsub_b.set(*userdata->m_color_inputs.combiner_rgbsub_b[1]);
+ rgbmul.set(*userdata->m_color_inputs.combiner_rgbmul[1]);
+ rgbadd.set(*userdata->m_color_inputs.combiner_rgbadd[1]);
+
+ rgbsub_a.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_a[1]);
+ rgbsub_b.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_b[1]);
+ rgbmul.merge_alpha(*userdata->m_color_inputs.combiner_alphamul[1]);
+ rgbadd.merge_alpha(*userdata->m_color_inputs.combiner_alphaadd[1]);
+
+ rgbsub_a.sign_extend(0x180, 0xfffffe00);
+ rgbsub_b.sign_extend(0x180, 0xfffffe00);
+ rgbadd.sign_extend(0x180, 0xfffffe00);
+
+ rgbadd.shl_imm(8);
+ rgbsub_a.sub(rgbsub_b);
+ rgbsub_a.mul(rgbmul);
+ rgbsub_a.add(rgbadd);
+ rgbsub_a.add_imm(0x0080);
+ rgbsub_a.sra_imm(8);
+ rgbsub_a.clamp_and_clear(0xfffffe00);
+
+ userdata->m_pixel_color.set(rgbsub_a);
+
+ //Alpha coverage combiner
+ userdata->m_pixel_color.set_a(get_alpha_cvg(userdata->m_pixel_color.get_a(), userdata, object));
+
+ const UINT32 curpixel = fb_index + x;
+ const UINT32 zbcur = zb + curpixel;
+ const UINT32 zhbcur = zhb + curpixel;
+
+ read_pixel(curpixel, userdata, object);
+
+ if(z_compare(zbcur, zhbcur, sz, dzpix, userdata, object))
+ {
+ get_dither_values(scanline, j, &cdith, &adith, object);
+
+ color_t blended_pixel;
+ bool rendered = ((&m_blender)->*(m_blender.blend2[(userdata->m_blend_enable << 2) | blend_index]))(blended_pixel, cdith, adith, partialreject, sel0, sel1, userdata, object);
+
+ if (rendered)
+ {
+ write_pixel(curpixel, blended_pixel, userdata, object);
+ if (object.m_other_modes.z_update_en)
+ {
+ z_store(object, zbcur, zhbcur, sz, userdata->m_dzpix_enc);
+ }
+ }
+ }
+ sss = userdata->m_precomp_s;
+ sst = userdata->m_precomp_t;
+ }
+
+ r.w += drinc;
+ g.w += dginc;
+ b.w += dbinc;
+ a.w += dainc;
+ s.w += dsinc;
+ t.w += dtinc;
+ w.w += dwinc;
+ z.w += dzinc;
+
+ x += xinc;
+ }
+}
+
+void n64_rdp::span_draw_copy(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, INT32 threadid)
+{
+ const INT32 clipx1 = object.m_scissor.m_xh;
+ const INT32 clipx2 = object.m_scissor.m_xl;
+ const INT32 tilenum = object.tilenum;
+ const bool flip = object.flip;
+
+ rdp_span_aux* userdata = (rdp_span_aux*)extent.userdata;
+ const INT32 xstart = extent.startx;
+ const INT32 xend = userdata->m_unscissored_rx;
+ const INT32 xend_scissored = extent.stopx;
+ const INT32 xinc = flip ? 1 : -1;
+ const INT32 length = flip ? (xstart - xend) : (xend - xstart);
+
+ span_param_t s; s.w = extent.param[SPAN_S].start;
+ span_param_t t; t.w = extent.param[SPAN_T].start;
+
+ const INT32 ds = object.m_span_base.m_span_ds / 4;
+ const INT32 dt = object.m_span_base.m_span_dt / 4;
+ const INT32 dsinc = flip ? (ds) : -ds;
+ const INT32 dtinc = flip ? (dt) : -dt;
+
+ const INT32 fb_index = object.m_misc_state.m_fb_width * scanline;
+
+ INT32 x = xend;
+
+ for (INT32 j = 0; j <= length; j++)
+ {
+ const bool valid_x = (flip) ? (x >= xend_scissored) : (x <= xend_scissored);
+
+ if (x >= clipx1 && x < clipx2 && valid_x)
+ {
+ INT32 sss = s.h.h;
+ INT32 sst = t.h.h;
+ m_tex_pipe.copy(&userdata->m_texel0_color, sss, sst, tilenum, object, userdata);
+
+ UINT32 curpixel = fb_index + x;
+ if ((userdata->m_texel0_color.get_a() != 0) || (!object.m_other_modes.alpha_compare_en))
+ {
+ copy_pixel(curpixel, userdata->m_texel0_color, object);
+ }
+ }
+
+ s.w += dsinc;
+ t.w += dtinc;
+ x += xinc;
+ }
+}
+
+void n64_rdp::span_draw_fill(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, INT32 threadid)
+{
+ assert(object.m_misc_state.m_fb_size >= 2 && object.m_misc_state.m_fb_size < 4);
+
+ const bool flip = object.flip;
+
+ const INT32 clipx1 = object.m_scissor.m_xh;
+ const INT32 clipx2 = object.m_scissor.m_xl;
+
+ const INT32 xinc = flip ? 1 : -1;
+
+ const INT32 fb_index = object.m_misc_state.m_fb_width * scanline;
+
+ const INT32 xstart = extent.startx;
+ const INT32 xend_scissored = extent.stopx;
+
+ INT32 x = xend_scissored;
+
+ const INT32 length = flip ? (xstart - xend_scissored) : (xend_scissored - xstart);
+
+ for (INT32 j = 0; j <= length; j++)
+ {
+ if (x >= clipx1 && x < clipx2)
+ {
+ fill_pixel(fb_index + x, object);
+ }
+
+ x += xinc;
+ }
+}
diff --git a/src/mame/video/rdpspn16.c b/src/mame/video/rdpspn16.c
deleted file mode 100644
index dab36695736..00000000000
--- a/src/mame/video/rdpspn16.c
+++ /dev/null
@@ -1,844 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Ryan Holtz
-/******************************************************************************
-
-
- SGI/Nintendo Reality Display Processor span-drawing functions
- -------------------
-
- by MooglyGuy
- based on initial C code by Ville Linde
- contains additional improvements from angrylion, Ziggy, Gonetz and Orkin
-
-
-******************************************************************************/
-
-#include "emu.h"
-#include "includes/n64.h"
-#include "video/n64.h"
-#include "video/rgbutil.h"
-
-void n64_rdp::render_spans(INT32 start, INT32 end, INT32 tilenum, bool flip, extent_t* spans, bool rect, rdp_poly_state* object)
-{
- const INT32 clipy1 = m_scissor.m_yh;
- const INT32 clipy2 = m_scissor.m_yl;
- INT32 offset = 0;
-
- if (clipy2 <= 0)
- {
- return;
- }
-
- if (start < clipy1)
- {
- offset = clipy1 - start;
- start = clipy1;
- }
- if (start >= clipy2)
- {
- offset = start - (clipy2 - 1);
- start = clipy2 - 1;
- }
- if (end < clipy1)
- {
- end = clipy1;
- }
- if (end >= clipy2)
- {
- end = clipy2 - 1;
- }
-
- object->m_rdp = this;
- memcpy(&object->m_misc_state, &m_misc_state, sizeof(misc_state_t));
- memcpy(&object->m_other_modes, &m_other_modes, sizeof(other_modes_t));
- memcpy(&object->m_span_base, &m_span_base, sizeof(span_base_t));
- memcpy(&object->m_scissor, &m_scissor, sizeof(rectangle_t));
- memcpy(&object->m_tiles, &m_tiles, 8 * sizeof(n64_tile_t));
- object->tilenum = tilenum;
- object->flip = flip;
- object->m_fill_color = m_fill_color;
- object->rect = rect;
-
- switch(m_other_modes.cycle_type)
- {
- case CYCLE_TYPE_1:
- render_triangle_custom(m_visarea, render_delegate(FUNC(n64_rdp::span_draw_1cycle), this), start, (end - start) + 1, spans + offset);
- break;
-
- case CYCLE_TYPE_2:
- render_triangle_custom(m_visarea, render_delegate(FUNC(n64_rdp::span_draw_2cycle), this), start, (end - start) + 1, spans + offset);
- break;
-
- case CYCLE_TYPE_COPY:
- render_triangle_custom(m_visarea, render_delegate(FUNC(n64_rdp::span_draw_copy), this), start, (end - start) + 1, spans + offset);
- break;
-
- case CYCLE_TYPE_FILL:
- render_triangle_custom(m_visarea, render_delegate(FUNC(n64_rdp::span_draw_fill), this), start, (end - start) + 1, spans + offset);
- break;
- }
- //wait();
-}
-
-void n64_rdp::rgbaz_clip(INT32 sr, INT32 sg, INT32 sb, INT32 sa, INT32* sz, rdp_span_aux* userdata)
-{
- userdata->m_shade_color.set(sa, sr, sg, sb);
- userdata->m_shade_color.clamp_and_clear(0xfffffe00);
- UINT32 a = userdata->m_shade_color.get_a();
- userdata->m_shade_alpha.set(a, a, a, a);
-
- INT32 zanded = (*sz) & 0x60000;
-
- zanded >>= 17;
- switch(zanded)
- {
- case 0: *sz &= 0x3ffff; break;
- case 1: *sz &= 0x3ffff; break;
- case 2: *sz = 0x3ffff; break;
- case 3: *sz = 0x3ffff; break;
- }
-}
-
-void n64_rdp::rgbaz_correct_triangle(INT32 offx, INT32 offy, INT32* r, INT32* g, INT32* b, INT32* a, INT32* z, rdp_span_aux* userdata, const rdp_poly_state &object)
-{
- if (userdata->m_current_pix_cvg == 8)
- {
- *r >>= 2;
- *g >>= 2;
- *b >>= 2;
- *a >>= 2;
- *z = (*z >> 3) & 0x7ffff;
- }
- else
- {
- INT32 summand_xr = offx * SIGN13(object.m_span_base.m_span_dr >> 14);
- INT32 summand_yr = offy * SIGN13(object.m_span_base.m_span_drdy >> 14);
- INT32 summand_xb = offx * SIGN13(object.m_span_base.m_span_db >> 14);
- INT32 summand_yb = offy * SIGN13(object.m_span_base.m_span_dbdy >> 14);
- INT32 summand_xg = offx * SIGN13(object.m_span_base.m_span_dg >> 14);
- INT32 summand_yg = offy * SIGN13(object.m_span_base.m_span_dgdy >> 14);
- INT32 summand_xa = offx * SIGN13(object.m_span_base.m_span_da >> 14);
- INT32 summand_ya = offy * SIGN13(object.m_span_base.m_span_dady >> 14);
-
- INT32 summand_xz = offx * SIGN22(object.m_span_base.m_span_dz >> 10);
- INT32 summand_yz = offy * SIGN22(object.m_span_base.m_span_dzdy >> 10);
-
- *r = ((*r << 2) + summand_xr + summand_yr) >> 4;
- *g = ((*g << 2) + summand_xg + summand_yg) >> 4;
- *b = ((*b << 2) + summand_xb + summand_yb) >> 4;
- *a = ((*a << 2) + summand_xa + summand_ya) >> 4;
- *z = (((*z << 2) + summand_xz + summand_yz) >> 5) & 0x7ffff;
- }
-}
-
-inline void n64_rdp::write_pixel(UINT32 curpixel, color_t& color, rdp_span_aux* userdata, const rdp_poly_state &object)
-{
- if (object.m_misc_state.m_fb_size == 2) // 16-bit framebuffer
- {
- const UINT32 fb = (object.m_misc_state.m_fb_address >> 1) + curpixel;
-
- UINT16 finalcolor;
- if (object.m_other_modes.color_on_cvg && !userdata->m_pre_wrap)
- {
- finalcolor = RREADIDX16(fb) & 0xfffe;
- }
- else
- {
- color.shr_imm(3);
- finalcolor = (color.get_r() << 11) | (color.get_g() << 6) | (color.get_b() << 1);
- }
-
- switch (object.m_other_modes.cvg_dest)
- {
- case 0:
- if (userdata->m_blend_enable)
- {
- UINT32 finalcvg = userdata->m_current_pix_cvg + userdata->m_current_mem_cvg;
- if (finalcvg & 8)
- {
- finalcvg = 7;
- }
- RWRITEIDX16(fb, finalcolor | (finalcvg >> 2));
- HWRITEADDR8(fb, finalcvg & 3);
- }
- else
- {
- const UINT32 finalcvg = (userdata->m_current_pix_cvg - 1) & 7;
- RWRITEIDX16(fb, finalcolor | (finalcvg >> 2));
- HWRITEADDR8(fb, finalcvg & 3);
- }
- break;
- case 1:
- {
- const UINT32 finalcvg = (userdata->m_current_pix_cvg + userdata->m_current_mem_cvg) & 7;
- RWRITEIDX16(fb, finalcolor | (finalcvg >> 2));
- HWRITEADDR8(fb, finalcvg & 3);
- break;
- }
- case 2:
- RWRITEIDX16(fb, finalcolor | 1);
- HWRITEADDR8(fb, 3);
- break;
- case 3:
- RWRITEIDX16(fb, finalcolor | (userdata->m_current_mem_cvg >> 2));
- HWRITEADDR8(fb, userdata->m_current_mem_cvg & 3);
- break;
- }
- }
- else // 32-bit framebuffer
- {
- const UINT32 fb = (object.m_misc_state.m_fb_address >> 2) + curpixel;
-
- UINT32 finalcolor;
- if (object.m_other_modes.color_on_cvg && !userdata->m_pre_wrap)
- {
- finalcolor = RREADIDX32(fb) & 0xffffff00;
- }
- else
- {
- finalcolor = (color.get_r() << 24) | (color.get_g() << 16) | (color.get_b() << 8);
- }
-
- switch (object.m_other_modes.cvg_dest)
- {
- case 0:
- if (userdata->m_blend_enable)
- {
- UINT32 finalcvg = userdata->m_current_pix_cvg + userdata->m_current_mem_cvg;
- if (finalcvg & 8)
- {
- finalcvg = 7;
- }
-
- RWRITEIDX32(fb, finalcolor | (finalcvg << 5));
- }
- else
- {
- RWRITEIDX32(fb, finalcolor | (((userdata->m_current_pix_cvg - 1) & 7) << 5));
- }
- break;
- case 1:
- RWRITEIDX32(fb, finalcolor | (((userdata->m_current_pix_cvg + userdata->m_current_mem_cvg) & 7) << 5));
- break;
- case 2:
- RWRITEIDX32(fb, finalcolor | 0xE0);
- break;
- case 3:
- RWRITEIDX32(fb, finalcolor | (userdata->m_current_mem_cvg << 5));
- break;
- }
- }
-}
-
-inline void n64_rdp::read_pixel(UINT32 curpixel, rdp_span_aux* userdata, const rdp_poly_state &object)
-{
- if (object.m_misc_state.m_fb_size == 2) // 16-bit framebuffer
- {
- const UINT16 fword = RREADIDX16((object.m_misc_state.m_fb_address >> 1) + curpixel);
-
- userdata->m_memory_color.set(0, GETHICOL(fword), GETMEDCOL(fword), GETLOWCOL(fword));
- if (object.m_other_modes.image_read_en)
- {
- UINT8 hbyte = HREADADDR8((object.m_misc_state.m_fb_address >> 1) + curpixel);
- userdata->m_memory_color.set_a(userdata->m_current_mem_cvg << 5);
- userdata->m_current_mem_cvg = ((fword & 1) << 2) | (hbyte & 3);
- }
- else
- {
- userdata->m_memory_color.set_a(0xff);
- userdata->m_current_mem_cvg = 7;
- }
- }
- else // 32-bit framebuffer
- {
- const UINT32 mem = RREADIDX32((object.m_misc_state.m_fb_address >> 2) + curpixel);
- userdata->m_memory_color.set(0, (mem >> 24) & 0xff, (mem >> 16) & 0xff, (mem >> 8) & 0xff);
- if (object.m_other_modes.image_read_en)
- {
- userdata->m_memory_color.set_a(mem & 0xff);
- userdata->m_current_mem_cvg = (mem >> 5) & 7;
- }
- else
- {
- userdata->m_memory_color.set_a(0xff);
- userdata->m_current_mem_cvg = 7;
- }
- }
-}
-
-inline void n64_rdp::copy_pixel(UINT32 curpixel, color_t& color, const rdp_poly_state &object)
-{
- const UINT32 current_pix_cvg = color.get_a() ? 7 : 0;
- const UINT8 r = color.get_r(); // Vectorize me
- const UINT8 g = color.get_g();
- const UINT8 b = color.get_b();
- if (object.m_misc_state.m_fb_size == 2) // 16-bit framebuffer
- {
- RWRITEIDX16((object.m_misc_state.m_fb_address >> 1) + curpixel, ((r >> 3) << 11) | ((g >> 3) << 6) | ((b >> 3) << 1) | ((current_pix_cvg >> 2) & 1));
- HWRITEADDR8((object.m_misc_state.m_fb_address >> 1) + curpixel, current_pix_cvg & 3);
- }
- else // 32-bit framebuffer
- {
- RWRITEIDX32((object.m_misc_state.m_fb_address >> 2) + curpixel, (r << 24) | (g << 16) | (b << 8) | (current_pix_cvg << 5));
- }
-}
-
-inline void n64_rdp::fill_pixel(UINT32 curpixel, const rdp_poly_state &object)
-{
- if (object.m_misc_state.m_fb_size == 2) // 16-bit framebuffer
- {
- UINT16 val;
- if (curpixel & 1)
- {
- val = object.m_fill_color & 0xffff;
- }
- else
- {
- val = (object.m_fill_color >> 16) & 0xffff;
- }
- RWRITEIDX16((object.m_misc_state.m_fb_address >> 1) + curpixel, val);
- HWRITEADDR8((object.m_misc_state.m_fb_address >> 1) + curpixel, ((val & 1) << 1) | (val & 1));
- }
- else // 32-bit framebuffer
- {
- RWRITEIDX32((object.m_misc_state.m_fb_address >> 2) + curpixel, object.m_fill_color);
- HWRITEADDR8((object.m_misc_state.m_fb_address >> 1) + (curpixel << 1), (object.m_fill_color & 0x10000) ? 3 : 0);
- HWRITEADDR8((object.m_misc_state.m_fb_address >> 1) + (curpixel << 1) + 1, (object.m_fill_color & 0x1) ? 3 : 0);
- }
-}
-
-void n64_rdp::span_draw_1cycle(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, INT32 threadid)
-{
- assert(object.m_misc_state.m_fb_size >= 2 && object.m_misc_state.m_fb_size < 4);
-
- const INT32 clipx1 = object.m_scissor.m_xh;
- const INT32 clipx2 = object.m_scissor.m_xl;
- const INT32 tilenum = object.tilenum;
- const bool flip = object.flip;
-
- span_param_t r; r.w = extent.param[SPAN_R].start;
- span_param_t g; g.w = extent.param[SPAN_G].start;
- span_param_t b; b.w = extent.param[SPAN_B].start;
- span_param_t a; a.w = extent.param[SPAN_A].start;
- span_param_t z; z.w = extent.param[SPAN_Z].start;
- span_param_t s; s.w = extent.param[SPAN_S].start;
- span_param_t t; t.w = extent.param[SPAN_T].start;
- span_param_t w; w.w = extent.param[SPAN_W].start;
-
- const UINT32 zb = object.m_misc_state.m_zb_address >> 1;
- const UINT32 zhb = object.m_misc_state.m_zb_address;
-
-#ifdef PTR64
- assert(extent.userdata != (const void *)0xcccccccccccccccc);
-#else
- assert(extent.userdata != (const void *)0xcccccccc);
-#endif
- rdp_span_aux* userdata = (rdp_span_aux*)extent.userdata;
-
- m_tex_pipe.calculate_clamp_diffs(tilenum, userdata, object);
-
- const bool partialreject = (userdata->m_color_inputs.blender2b_a[0] == &userdata->m_inv_pixel_color && userdata->m_color_inputs.blender1b_a[0] == &userdata->m_pixel_color);
- const INT32 sel0 = (userdata->m_color_inputs.blender2b_a[0] == &userdata->m_memory_color) ? 1 : 0;
-
- INT32 drinc, dginc, dbinc, dainc;
- INT32 dzinc, dzpix;
- INT32 dsinc, dtinc, dwinc;
- INT32 xinc;
-
- if (!flip)
- {
- drinc = -object.m_span_base.m_span_dr;
- dginc = -object.m_span_base.m_span_dg;
- dbinc = -object.m_span_base.m_span_db;
- dainc = -object.m_span_base.m_span_da;
- dzinc = -object.m_span_base.m_span_dz;
- dsinc = -object.m_span_base.m_span_ds;
- dtinc = -object.m_span_base.m_span_dt;
- dwinc = -object.m_span_base.m_span_dw;
- xinc = -1;
- }
- else
- {
- drinc = object.m_span_base.m_span_dr;
- dginc = object.m_span_base.m_span_dg;
- dbinc = object.m_span_base.m_span_db;
- dainc = object.m_span_base.m_span_da;
- dzinc = object.m_span_base.m_span_dz;
- dsinc = object.m_span_base.m_span_ds;
- dtinc = object.m_span_base.m_span_dt;
- dwinc = object.m_span_base.m_span_dw;
- xinc = 1;
- }
-
- const INT32 fb_index = object.m_misc_state.m_fb_width * scanline;
-
- const INT32 xstart = extent.startx;
- const INT32 xend = userdata->m_unscissored_rx;
- const INT32 xend_scissored = extent.stopx;
-
- INT32 x = xend;
-
- const INT32 length = flip ? (xstart - xend) : (xend - xstart);
-
- if(object.m_other_modes.z_source_sel)
- {
- z.w = object.m_misc_state.m_primitive_z;
- dzpix = object.m_misc_state.m_primitive_dz;
- dzinc = 0;
- }
- else
- {
- dzpix = object.m_span_base.m_span_dzpix;
- }
-
- if (object.m_misc_state.m_fb_size < 2 || object.m_misc_state.m_fb_size > 4)
- fatalerror("unsupported m_fb_size %d\n", object.m_misc_state.m_fb_size);
-
- const INT32 blend_index = (object.m_other_modes.alpha_cvg_select ? 2 : 0) | ((object.m_other_modes.rgb_dither_sel < 3) ? 1 : 0);
- const INT32 cycle0 = ((object.m_other_modes.sample_type & 1) << 1) | (object.m_other_modes.bi_lerp0 & 1);
-
- INT32 sss = 0;
- INT32 sst = 0;
-
- if (object.m_other_modes.persp_tex_en)
- {
- tc_div(s.w >> 16, t.w >> 16, w.w >> 16, &sss, &sst);
- }
- else
- {
- tc_div_no_perspective(s.w >> 16, t.w >> 16, w.w >> 16, &sss, &sst);
- }
-
- userdata->m_start_span = true;
- for (INT32 j = 0; j <= length; j++)
- {
- INT32 sr = r.w >> 14;
- INT32 sg = g.w >> 14;
- INT32 sb = b.w >> 14;
- INT32 sa = a.w >> 14;
- INT32 sz = (z.w >> 10) & 0x3fffff;
- const bool valid_x = (flip) ? (x >= xend_scissored) : (x <= xend_scissored);
-
- if (x >= clipx1 && x < clipx2 && valid_x)
- {
- UINT8 offx, offy;
- lookup_cvmask_derivatives(userdata->m_cvg[x], &offx, &offy, userdata);
-
- m_tex_pipe.lod_1cycle(&sss, &sst, s.w, t.w, w.w, dsinc, dtinc, dwinc, userdata, object);
-
- rgbaz_correct_triangle(offx, offy, &sr, &sg, &sb, &sa, &sz, userdata, object);
- rgbaz_clip(sr, sg, sb, sa, &sz, userdata);
-
- ((m_tex_pipe).*(m_tex_pipe.m_cycle[cycle0]))(&userdata->m_texel0_color, &userdata->m_texel0_color, sss, sst, tilenum, 0, userdata, object);
- UINT32 t0a = userdata->m_texel0_color.get_a();
- userdata->m_texel0_alpha.set(t0a, t0a, t0a, t0a);
-
- const UINT8 noise = rand() << 3; // Not accurate
- userdata->m_noise_color.set(0, noise, noise, noise);
-
- rgbaint_t rgbsub_a(*userdata->m_color_inputs.combiner_rgbsub_a[1]);
- rgbaint_t rgbsub_b(*userdata->m_color_inputs.combiner_rgbsub_b[1]);
- rgbaint_t rgbmul(*userdata->m_color_inputs.combiner_rgbmul[1]);
- rgbaint_t rgbadd(*userdata->m_color_inputs.combiner_rgbadd[1]);
-
- rgbsub_a.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_a[1]);
- rgbsub_b.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_b[1]);
- rgbmul.merge_alpha(*userdata->m_color_inputs.combiner_alphamul[1]);
- rgbadd.merge_alpha(*userdata->m_color_inputs.combiner_alphaadd[1]);
-
- rgbsub_a.sign_extend(0x180, 0xfffffe00);
- rgbsub_b.sign_extend(0x180, 0xfffffe00);
- rgbadd.sign_extend(0x180, 0xfffffe00);
-
- rgbadd.shl_imm(8);
- rgbsub_a.sub(rgbsub_b);
- rgbsub_a.mul(rgbmul);
- rgbsub_a.add(rgbadd);
- rgbsub_a.add_imm(0x0080);
- rgbsub_a.sra_imm(8);
- rgbsub_a.clamp_and_clear(0xfffffe00);
-
- userdata->m_pixel_color = rgbsub_a;
-
- //Alpha coverage combiner
- userdata->m_pixel_color.set_a(get_alpha_cvg(userdata->m_pixel_color.get_a(), userdata, object));
-
- const UINT32 curpixel = fb_index + x;
- const UINT32 zbcur = zb + curpixel;
- const UINT32 zhbcur = zhb + curpixel;
-
- read_pixel(curpixel, userdata, object);
-
- if(z_compare(zbcur, zhbcur, sz, dzpix, userdata, object))
- {
- INT32 cdith = 0;
- INT32 adith = 0;
- get_dither_values(scanline, j, &cdith, &adith, object);
-
- color_t blended_pixel;
- bool rendered = ((&m_blender)->*(m_blender.blend1[(userdata->m_blend_enable << 2) | blend_index]))(blended_pixel, cdith, adith, partialreject, sel0, userdata, object);
-
- if (rendered)
- {
- write_pixel(curpixel, blended_pixel, userdata, object);
- if (object.m_other_modes.z_update_en)
- {
- z_store(object, zbcur, zhbcur, sz, userdata->m_dzpix_enc);
- }
- }
- }
-
- sss = userdata->m_precomp_s;
- sst = userdata->m_precomp_t;
- }
-
- r.w += drinc;
- g.w += dginc;
- b.w += dbinc;
- a.w += dainc;
- s.w += dsinc;
- t.w += dtinc;
- w.w += dwinc;
- z.w += dzinc;
-
- x += xinc;
- }
-}
-
-void n64_rdp::span_draw_2cycle(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, INT32 threadid)
-{
- assert(object.m_misc_state.m_fb_size >= 2 && object.m_misc_state.m_fb_size < 4);
-
- const INT32 clipx1 = object.m_scissor.m_xh;
- const INT32 clipx2 = object.m_scissor.m_xl;
- const INT32 tilenum = object.tilenum;
- const bool flip = object.flip;
-
- span_param_t r; r.w = extent.param[SPAN_R].start;
- span_param_t g; g.w = extent.param[SPAN_G].start;
- span_param_t b; b.w = extent.param[SPAN_B].start;
- span_param_t a; a.w = extent.param[SPAN_A].start;
- span_param_t z; z.w = extent.param[SPAN_Z].start;
- span_param_t s; s.w = extent.param[SPAN_S].start;
- span_param_t t; t.w = extent.param[SPAN_T].start;
- span_param_t w; w.w = extent.param[SPAN_W].start;
-
- const UINT32 zb = object.m_misc_state.m_zb_address >> 1;
- const UINT32 zhb = object.m_misc_state.m_zb_address;
-
- INT32 tile2 = (tilenum + 1) & 7;
- INT32 tile1 = tilenum;
- const UINT32 prim_tile = tilenum;
-
- INT32 newtile1 = tile1;
- INT32 news = 0;
- INT32 newt = 0;
-
-#ifdef PTR64
- assert(extent.userdata != (const void *)0xcccccccccccccccc);
-#else
- assert(extent.userdata != (const void *)0xcccccccc);
-#endif
- rdp_span_aux* userdata = (rdp_span_aux*)extent.userdata;
-
- m_tex_pipe.calculate_clamp_diffs(tile1, userdata, object);
-
- bool partialreject = (userdata->m_color_inputs.blender2b_a[1] == &userdata->m_inv_pixel_color && userdata->m_color_inputs.blender1b_a[1] == &userdata->m_pixel_color);
- INT32 sel0 = (userdata->m_color_inputs.blender2b_a[0] == &userdata->m_memory_color) ? 1 : 0;
- INT32 sel1 = (userdata->m_color_inputs.blender2b_a[1] == &userdata->m_memory_color) ? 1 : 0;
-
- INT32 drinc, dginc, dbinc, dainc;
- INT32 dzinc, dzpix;
- INT32 dsinc, dtinc, dwinc;
- INT32 xinc;
-
- if (!flip)
- {
- drinc = -object.m_span_base.m_span_dr;
- dginc = -object.m_span_base.m_span_dg;
- dbinc = -object.m_span_base.m_span_db;
- dainc = -object.m_span_base.m_span_da;
- dzinc = -object.m_span_base.m_span_dz;
- dsinc = -object.m_span_base.m_span_ds;
- dtinc = -object.m_span_base.m_span_dt;
- dwinc = -object.m_span_base.m_span_dw;
- xinc = -1;
- }
- else
- {
- drinc = object.m_span_base.m_span_dr;
- dginc = object.m_span_base.m_span_dg;
- dbinc = object.m_span_base.m_span_db;
- dainc = object.m_span_base.m_span_da;
- dzinc = object.m_span_base.m_span_dz;
- dsinc = object.m_span_base.m_span_ds;
- dtinc = object.m_span_base.m_span_dt;
- dwinc = object.m_span_base.m_span_dw;
- xinc = 1;
- }
-
- const INT32 fb_index = object.m_misc_state.m_fb_width * scanline;
-
- INT32 cdith = 0;
- INT32 adith = 0;
-
- const INT32 xstart = extent.startx;
- const INT32 xend = userdata->m_unscissored_rx;
- const INT32 xend_scissored = extent.stopx;
-
- INT32 x = xend;
-
- const INT32 length = flip ? (xstart - xend) : (xend - xstart);
-
- if(object.m_other_modes.z_source_sel)
- {
- z.w = object.m_misc_state.m_primitive_z;
- dzpix = object.m_misc_state.m_primitive_dz;
- dzinc = 0;
- }
- else
- {
- dzpix = object.m_span_base.m_span_dzpix;
- }
-
- if (object.m_misc_state.m_fb_size < 2 || object.m_misc_state.m_fb_size > 4)
- fatalerror("unsupported m_fb_size %d\n", object.m_misc_state.m_fb_size);
-
- const INT32 blend_index = (object.m_other_modes.alpha_cvg_select ? 2 : 0) | ((object.m_other_modes.rgb_dither_sel < 3) ? 1 : 0);
- const INT32 cycle0 = ((object.m_other_modes.sample_type & 1) << 1) | (object.m_other_modes.bi_lerp0 & 1);
- const INT32 cycle1 = ((object.m_other_modes.sample_type & 1) << 1) | (object.m_other_modes.bi_lerp1 & 1);
-
- INT32 sss = 0;
- INT32 sst = 0;
-
- if (object.m_other_modes.persp_tex_en)
- {
- tc_div(s.w >> 16, t.w >> 16, w.w >> 16, &sss, &sst);
- }
- else
- {
- tc_div_no_perspective(s.w >> 16, t.w >> 16, w.w >> 16, &sss, &sst);
- }
-
- userdata->m_start_span = true;
- for (INT32 j = 0; j <= length; j++)
- {
- INT32 sr = r.w >> 14;
- INT32 sg = g.w >> 14;
- INT32 sb = b.w >> 14;
- INT32 sa = a.w >> 14;
- INT32 sz = (z.w >> 10) & 0x3fffff;
- color_t c1;
- color_t c2;
-
- const bool valid_x = (flip) ? (x >= xend_scissored) : (x <= xend_scissored);
-
- if (x >= clipx1 && x < clipx2 && valid_x)
- {
- const UINT32 compidx = m_compressed_cvmasks[userdata->m_cvg[x]];
- userdata->m_current_pix_cvg = cvarray[compidx].cvg;
- userdata->m_current_cvg_bit = cvarray[compidx].cvbit;
- const UINT8 offx = cvarray[compidx].xoff;
- const UINT8 offy = cvarray[compidx].yoff;
- //lookup_cvmask_derivatives(userdata->m_cvg[x], &offx, &offy, userdata);
-
- m_tex_pipe.lod_2cycle(&sss, &sst, s.w, t.w, w.w, dsinc, dtinc, dwinc, prim_tile, &tile1, &tile2, userdata, object);
-
- news = userdata->m_precomp_s;
- newt = userdata->m_precomp_t;
- m_tex_pipe.lod_2cycle_limited(&news, &newt, s.w + dsinc, t.w + dtinc, w.w + dwinc, dsinc, dtinc, dwinc, prim_tile, &newtile1, object);
-
- rgbaz_correct_triangle(offx, offy, &sr, &sg, &sb, &sa, &sz, userdata, object);
- rgbaz_clip(sr, sg, sb, sa, &sz, userdata);
-
- ((m_tex_pipe).*(m_tex_pipe.m_cycle[cycle0]))(&userdata->m_texel0_color, &userdata->m_texel0_color, sss, sst, tile1, 0, userdata, object);
- ((m_tex_pipe).*(m_tex_pipe.m_cycle[cycle1]))(&userdata->m_texel1_color, &userdata->m_texel0_color, sss, sst, tile2, 1, userdata, object);
- ((m_tex_pipe).*(m_tex_pipe.m_cycle[cycle1]))(&userdata->m_next_texel_color, &userdata->m_next_texel_color, sss, sst, tile2, 1, userdata, object);
-
- UINT32 t0a = userdata->m_texel0_color.get_a();
- UINT32 t1a = userdata->m_texel1_color.get_a();
- UINT32 tna = userdata->m_next_texel_color.get_a();
- userdata->m_texel0_alpha.set(t0a, t0a, t0a, t0a);
- userdata->m_texel1_alpha.set(t1a, t1a, t1a, t1a);
- userdata->m_next_texel_alpha.set(tna, tna, tna, tna);
-
- const UINT8 noise = rand() << 3; // Not accurate
- userdata->m_noise_color.set(0, noise, noise, noise);
-
- rgbaint_t rgbsub_a(*userdata->m_color_inputs.combiner_rgbsub_a[0]);
- rgbaint_t rgbsub_b(*userdata->m_color_inputs.combiner_rgbsub_b[0]);
- rgbaint_t rgbmul(*userdata->m_color_inputs.combiner_rgbmul[0]);
- rgbaint_t rgbadd(*userdata->m_color_inputs.combiner_rgbadd[0]);
-
- rgbsub_a.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_a[0]);
- rgbsub_b.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_b[0]);
- rgbmul.merge_alpha(*userdata->m_color_inputs.combiner_alphamul[0]);
- rgbadd.merge_alpha(*userdata->m_color_inputs.combiner_alphaadd[0]);
-
- rgbsub_a.sign_extend(0x180, 0xfffffe00);
- rgbsub_b.sign_extend(0x180, 0xfffffe00);
- rgbadd.sign_extend(0x180, 0xfffffe00);
-
- rgbadd.shl_imm(8);
- rgbsub_a.sub(rgbsub_b);
- rgbsub_a.mul(rgbmul);
-
- rgbsub_a.add(rgbadd);
- rgbsub_a.add_imm(0x0080);
- rgbsub_a.sra_imm(8);
- rgbsub_a.clamp_and_clear(0xfffffe00);
-
- userdata->m_combined_color.set(rgbsub_a);
- userdata->m_texel0_color.set(userdata->m_texel1_color);
- userdata->m_texel1_color.set(userdata->m_next_texel_color);
-
- UINT32 ca = userdata->m_combined_color.get_a();
- userdata->m_combined_alpha.set(ca, ca, ca, ca);
- userdata->m_texel0_alpha.set(userdata->m_texel1_alpha);
- userdata->m_texel1_alpha.set(userdata->m_next_texel_alpha);
-
- rgbsub_a.set(*userdata->m_color_inputs.combiner_rgbsub_a[1]);
- rgbsub_b.set(*userdata->m_color_inputs.combiner_rgbsub_b[1]);
- rgbmul.set(*userdata->m_color_inputs.combiner_rgbmul[1]);
- rgbadd.set(*userdata->m_color_inputs.combiner_rgbadd[1]);
-
- rgbsub_a.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_a[1]);
- rgbsub_b.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_b[1]);
- rgbmul.merge_alpha(*userdata->m_color_inputs.combiner_alphamul[1]);
- rgbadd.merge_alpha(*userdata->m_color_inputs.combiner_alphaadd[1]);
-
- rgbsub_a.sign_extend(0x180, 0xfffffe00);
- rgbsub_b.sign_extend(0x180, 0xfffffe00);
- rgbadd.sign_extend(0x180, 0xfffffe00);
-
- rgbadd.shl_imm(8);
- rgbsub_a.sub(rgbsub_b);
- rgbsub_a.mul(rgbmul);
- rgbsub_a.add(rgbadd);
- rgbsub_a.add_imm(0x0080);
- rgbsub_a.sra_imm(8);
- rgbsub_a.clamp_and_clear(0xfffffe00);
-
- userdata->m_pixel_color.set(rgbsub_a);
-
- //Alpha coverage combiner
- userdata->m_pixel_color.set_a(get_alpha_cvg(userdata->m_pixel_color.get_a(), userdata, object));
-
- const UINT32 curpixel = fb_index + x;
- const UINT32 zbcur = zb + curpixel;
- const UINT32 zhbcur = zhb + curpixel;
-
- read_pixel(curpixel, userdata, object);
-
- if(z_compare(zbcur, zhbcur, sz, dzpix, userdata, object))
- {
- get_dither_values(scanline, j, &cdith, &adith, object);
-
- color_t blended_pixel;
- bool rendered = ((&m_blender)->*(m_blender.blend2[(userdata->m_blend_enable << 2) | blend_index]))(blended_pixel, cdith, adith, partialreject, sel0, sel1, userdata, object);
-
- if (rendered)
- {
- write_pixel(curpixel, blended_pixel, userdata, object);
- if (object.m_other_modes.z_update_en)
- {
- z_store(object, zbcur, zhbcur, sz, userdata->m_dzpix_enc);
- }
- }
- }
- sss = userdata->m_precomp_s;
- sst = userdata->m_precomp_t;
- }
-
- r.w += drinc;
- g.w += dginc;
- b.w += dbinc;
- a.w += dainc;
- s.w += dsinc;
- t.w += dtinc;
- w.w += dwinc;
- z.w += dzinc;
-
- x += xinc;
- }
-}
-
-void n64_rdp::span_draw_copy(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, INT32 threadid)
-{
- const INT32 clipx1 = object.m_scissor.m_xh;
- const INT32 clipx2 = object.m_scissor.m_xl;
- const INT32 tilenum = object.tilenum;
- const bool flip = object.flip;
-
- rdp_span_aux* userdata = (rdp_span_aux*)extent.userdata;
- const INT32 xstart = extent.startx;
- const INT32 xend = userdata->m_unscissored_rx;
- const INT32 xend_scissored = extent.stopx;
- const INT32 xinc = flip ? 1 : -1;
- const INT32 length = flip ? (xstart - xend) : (xend - xstart);
-
- span_param_t s; s.w = extent.param[SPAN_S].start;
- span_param_t t; t.w = extent.param[SPAN_T].start;
-
- const INT32 ds = object.m_span_base.m_span_ds / 4;
- const INT32 dt = object.m_span_base.m_span_dt / 4;
- const INT32 dsinc = flip ? (ds) : -ds;
- const INT32 dtinc = flip ? (dt) : -dt;
-
- const INT32 fb_index = object.m_misc_state.m_fb_width * scanline;
-
- INT32 x = xend;
-
- for (INT32 j = 0; j <= length; j++)
- {
- const bool valid_x = (flip) ? (x >= xend_scissored) : (x <= xend_scissored);
-
- if (x >= clipx1 && x < clipx2 && valid_x)
- {
- INT32 sss = s.h.h;
- INT32 sst = t.h.h;
- m_tex_pipe.copy(&userdata->m_texel0_color, sss, sst, tilenum, object, userdata);
-
- UINT32 curpixel = fb_index + x;
- if ((userdata->m_texel0_color.get_a() != 0) || (!object.m_other_modes.alpha_compare_en))
- {
- copy_pixel(curpixel, userdata->m_texel0_color, object);
- }
- }
-
- s.w += dsinc;
- t.w += dtinc;
- x += xinc;
- }
-}
-
-void n64_rdp::span_draw_fill(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, INT32 threadid)
-{
- assert(object.m_misc_state.m_fb_size >= 2 && object.m_misc_state.m_fb_size < 4);
-
- const bool flip = object.flip;
-
- const INT32 clipx1 = object.m_scissor.m_xh;
- const INT32 clipx2 = object.m_scissor.m_xl;
-
- const INT32 xinc = flip ? 1 : -1;
-
- const INT32 fb_index = object.m_misc_state.m_fb_width * scanline;
-
- const INT32 xstart = extent.startx;
- const INT32 xend_scissored = extent.stopx;
-
- INT32 x = xend_scissored;
-
- const INT32 length = flip ? (xstart - xend_scissored) : (xend_scissored - xstart);
-
- for (INT32 j = 0; j <= length; j++)
- {
- if (x >= clipx1 && x < clipx2)
- {
- fill_pixel(fb_index + x, object);
- }
-
- x += xinc;
- }
-}
diff --git a/src/mame/video/taitoair.c b/src/mame/video/taitoair.c
index fc231c09c69..16af0809cd7 100644
--- a/src/mame/video/taitoair.c
+++ b/src/mame/video/taitoair.c
@@ -259,24 +259,26 @@ void taitoair_state::fill_slope( bitmap_ind16 &bitmap, const rectangle &cliprect
if (xx2 > cliprect.max_x)
xx2 = cliprect.max_x;
- if(header & 0x4000 || machine().input().code_pressed(KEYCODE_Q))
+ if(header & 0x4000 && machine().input().code_pressed(KEYCODE_Q))
{
base_color = machine().rand() & 0x3fff;
grad_col = 0;
}
- else if(header & 0x40)
- {
- /* Non-terrain elements are colored with this. */
- base_color = (header & 0x3f) + 0x340;
- grad_col = 0;
- }
- else
+ else if(m_paletteram[(header & 0xff)+0x300] & 0x8000)
{
/* Terrain elements, with a gradient applied. */
/*! @todo it's unknown if gradient color applies by global screen Y coordinate or there's a calculation to somewhere ... */
base_color = ((header & 0x3f) * 0x80) + 0x2040;
+ if(header & 0x3fe0)
+ base_color = machine().rand() & 0x3fff;
grad_col = (y1 >> 3) & 0x3f;
}
+ else
+ {
+ /* Non-terrain elements are colored with this. */
+ base_color = (header & 0xff) + 0x300;
+ grad_col = 0;
+ }
while (xx1 <= xx2)
{
@@ -388,8 +390,84 @@ void taitoair_state::fill_poly( bitmap_ind16 &bitmap, const rectangle &cliprect,
dsp handlers
***************************************************************************/
-/*
- TODO: still don't know how this works. It calls three values (0x1fff-0x5fff-0xdfff), for two or three offsets.
+void taitoair_state::fb_copy_op()
+{
+ /*! @todo declare once */
+ rectangle cliprect;
+
+ /* printf("%04x -> %d\n",data,offset); */
+
+ cliprect.min_x = 0;
+ cliprect.min_y = 3*16;
+ cliprect.max_x = m_screen->width() - 1;
+ cliprect.max_y = m_screen->height() - 1;
+
+ /* clear screen fb */
+ m_framebuffer[1]->fill(0, cliprect);
+ /* copy buffer fb into screen fb (at this stage we are ready to draw) */
+ copybitmap_trans(*m_framebuffer[1], *m_framebuffer[0], 0, 0, 0, 0, cliprect, 0);
+ /* now clear buffer fb */
+ m_framebuffer[0]->fill(0, cliprect);
+}
+
+void taitoair_state::fb_erase_op()
+{
+ /*! @todo declare once */
+ rectangle cliprect;
+
+ /* printf("%04x -> %d\n",data,offset); */
+
+ cliprect.min_x = 0;
+ cliprect.min_y = 3*16;
+ cliprect.max_x = m_screen->width() - 1;
+ cliprect.max_y = m_screen->height() - 1;
+
+ m_framebuffer[0]->fill(0, cliprect);
+ //m_framebuffer[1]->fill(0, cliprect);
+}
+
+void taitoair_state::fb_fill_op()
+{
+ /*! @todo declare once */
+ rectangle cliprect;
+
+ /* printf("%04x -> %d\n",data,offset); */
+
+ cliprect.min_x = 0;
+ cliprect.min_y = 3*16;
+ cliprect.max_x = m_screen->width() - 1;
+ cliprect.max_y = m_screen->height() - 1;
+
+ if (m_line_ram[0x3fff])
+ {
+ int adr = 0x3fff;
+
+ while (adr >= 0 && m_line_ram[adr] && m_line_ram[adr] != 0x4000)
+ {
+ int pcount = 0;
+ m_q.header = m_line_ram[adr--];
+ while (pcount < TAITOAIR_POLY_MAX_PT && adr >= 1 && !(m_line_ram[adr] & 0xc000))
+ {
+ m_q.p[pcount].y = m_line_ram[adr--] + 3 * 16;
+ m_q.p[pcount].x = m_line_ram[adr--];
+ pcount++;
+ }
+ adr--;
+ m_q.pcount = pcount;
+ if (!(m_line_ram[adr] & 0x8000))
+ {
+ m_q.header |= 0x4000;
+ logerror("special poly at %04x\n", adr);
+ while(adr >= 0 && !(m_line_ram[adr] & 0xc000))
+ adr--;
+ }
+ fill_poly(*m_framebuffer[0], cliprect, &m_q);
+ }
+ }
+}
+
+/*!
+ @todo still don't know how this works. It calls three values (0x1fff-0x5fff-0xdfff), for two or three offsets.
In theory this should fit into framebuffer draw, display, clear and swap in some way.
*/
WRITE16_MEMBER(taitoair_state::dsp_flags_w)
@@ -407,43 +485,13 @@ WRITE16_MEMBER(taitoair_state::dsp_flags_w)
/* clear and copy operation if offset is 0x3001 */
if(offset == 1)
{
- /* clear screen fb */
- m_framebuffer[1]->fill(0, cliprect);
- /* copy buffer fb into screen fb (at this stage we are ready to draw) */
- copybitmap_trans(*m_framebuffer[1], *m_framebuffer[0], 0, 0, 0, 0, cliprect, 0);
- /* now clear buffer fb */
- m_framebuffer[0]->fill(0, cliprect);
+ fb_copy_op();
}
/* if offset 0x3001 OR 0x3002 we put data in the buffer fb */
if(offset)
{
- if (m_line_ram[0x3fff])
- {
- int adr = 0x3fff;
-
- while (adr >= 0 && m_line_ram[adr] && m_line_ram[adr] != 0x4000)
- {
- int pcount = 0;
- m_q.header = m_line_ram[adr--];
- while (pcount < TAITOAIR_POLY_MAX_PT && adr >= 1 && !(m_line_ram[adr] & 0xc000))
- {
- m_q.p[pcount].y = m_line_ram[adr--] + 3 * 16;
- m_q.p[pcount].x = m_line_ram[adr--];
- pcount++;
- }
- adr--;
- m_q.pcount = pcount;
- if (!(m_line_ram[adr] & 0x8000))
- {
- m_q.header |= 0x4000;
- logerror("special poly at %04x\n", adr);
- while(adr >= 0 && !(m_line_ram[adr] & 0xc000))
- adr--;
- }
- fill_poly(*m_framebuffer[0], cliprect, &m_q);
- }
- }
+ fb_fill_op();
}
}
}
@@ -505,13 +553,14 @@ UINT32 taitoair_state::screen_update_taitoair(screen_device &screen, bitmap_ind1
}
- m_tc0080vco->tilemap_draw(screen, bitmap, cliprect, 0, 0, 0);
copybitmap_trans(bitmap, *m_framebuffer[1], 0, 0, 0, 0, cliprect, 0);
+ m_tc0080vco->tilemap_draw(screen, bitmap, cliprect, 0, 0, 0);
+
sprite_ptr = draw_sprites(bitmap, cliprect);
-
- m_tc0080vco->tilemap_draw(screen, bitmap, cliprect, 1, 0, 0);
+
+ m_tc0080vco->tilemap_draw(screen, bitmap, cliprect, 1, 0, 0);
m_tc0080vco->tilemap_draw(screen, bitmap, cliprect, 2, 0, 0);
diff --git a/src/mess/drivers/hh_tms1k.c b/src/mess/drivers/hh_tms1k.c
index 8504f383829..ba2f16dbadb 100644
--- a/src/mess/drivers/hh_tms1k.c
+++ b/src/mess/drivers/hh_tms1k.c
@@ -24,6 +24,7 @@
@MP1221 TMS1100 1980, Entex Raise The Devil
*MP1296 TMS1100? 1982, Entex Black Knight
*MP1312 TMS1100 198?, Tandy/RadioShack Science Fair Microcomputer Trainer
+ *MP1359 TMS1100? 1985, Capsela CRC2000
@MP1525 TMS1170 1980, Coleco Head to Head Baseball
*MP1604 ? 1981, Hanzawa Twinvader III/Tandy Cosmic Fire Away 3000 (? note: VFD-capable)
@MP2105 TMS1370 1979, Gakken Poker
diff --git a/src/mess/drivers/m20.c b/src/mess/drivers/m20.c
index 652a1b77bbd..5dd4d00503e 100644
--- a/src/mess/drivers/m20.c
+++ b/src/mess/drivers/m20.c
@@ -47,8 +47,10 @@ E I1 Vectored interrupt error
#include "machine/pit8253.h"
#include "machine/pic8259.h"
#include "formats/m20_dsk.h"
+#include "formats/pc_dsk.h"
#include "machine/m20_kbd.h"
#include "bus/rs232/rs232.h"
+#include "machine/m20_8086.h"
class m20_state : public driver_device
{
@@ -64,6 +66,7 @@ public:
m_fd1797(*this, "fd1797"),
m_floppy0(*this, "fd1797:0:5dd"),
m_floppy1(*this, "fd1797:1:5dd"),
+ m_apb(*this, "apb"),
m_p_videoram(*this, "p_videoram"),
m_palette(*this, "palette")
{
@@ -78,6 +81,7 @@ public:
required_device m_fd1797;
required_device m_floppy0;
required_device m_floppy1;
+ optional_device m_apb;
required_shared_ptr m_p_videoram;
required_device m_palette;
@@ -92,6 +96,8 @@ public:
DECLARE_WRITE_LINE_MEMBER(tty_clock_tick_w);
DECLARE_WRITE_LINE_MEMBER(kbd_clock_tick_w);
DECLARE_WRITE_LINE_MEMBER(timer_tick_w);
+ DECLARE_WRITE_LINE_MEMBER(halt_apb_w);
+ DECLARE_WRITE_LINE_MEMBER(int_w);
private:
offs_t m_memsize;
@@ -226,7 +232,9 @@ WRITE_LINE_MEMBER( m20_state::timer_tick_w )
* 8253 is programmed in square wave mode, not rate
* generator mode.
*/
- m_maincpu->set_input_line(0, state ? HOLD_LINE /*ASSERT_LINE*/ : CLEAR_LINE);
+ if(m_apb)
+ m_apb->nvi_w(state);
+ m_maincpu->set_input_line(INPUT_LINE_IRQ0, state ? HOLD_LINE /*ASSERT_LINE*/ : CLEAR_LINE);
}
@@ -714,24 +722,9 @@ static ADDRESS_MAP_START(m20_io, AS_IO, 16, m20_state)
AM_RANGE(0x140, 0x143) AM_READWRITE(m20_i8259_r, m20_i8259_w)
+ AM_RANGE(0x3ffa, 0x3ffd) AM_DEVWRITE("apb", m20_8086_device, handshake_w)
ADDRESS_MAP_END
-#if 0
-static ADDRESS_MAP_START(m20_apb_mem, AS_PROGRAM, 16, m20_state)
- ADDRESS_MAP_UNMAP_HIGH
- AM_RANGE( 0x00000, 0x007ff ) AM_RAM
- AM_RANGE( 0xf0000, 0xf7fff ) AM_RAM //mirrored?
- AM_RANGE( 0xfc000, 0xfffff ) AM_ROM AM_REGION("apb_bios",0)
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START(m20_apb_io, AS_IO, 16, m20_state)
- ADDRESS_MAP_UNMAP_HIGH
- ADDRESS_MAP_GLOBAL_MASK(0xff) // may not be needed
- //0x4060 crtc address
- //0x4062 crtc data
-ADDRESS_MAP_END
-#endif
-
IRQ_CALLBACK_MEMBER(m20_state::m20_irq_callback)
{
if (! irqline)
@@ -740,6 +733,13 @@ IRQ_CALLBACK_MEMBER(m20_state::m20_irq_callback)
return m_i8259->acknowledge();
}
+WRITE_LINE_MEMBER(m20_state::int_w)
+{
+ if(m_apb && !m_apb->halted())
+ m_apb->vi_w(state);
+ m_maincpu->set_input_line(INPUT_LINE_IRQ1, state ? ASSERT_LINE : CLEAR_LINE);
+}
+
void m20_state::machine_start()
{
install_memory();
@@ -762,6 +762,8 @@ void m20_state::machine_reset()
memcpy(RAM, ROM, 8); // we need only the reset vector
m_maincpu->reset(); // reset the CPU to ensure it picks up the new vector
+ if(m_apb)
+ m_apb->m_8086->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
}
@@ -770,7 +772,8 @@ static SLOT_INTERFACE_START( m20_floppies )
SLOT_INTERFACE_END
FLOPPY_FORMATS_MEMBER( m20_state::floppy_formats )
- FLOPPY_M20_FORMAT
+ FLOPPY_M20_FORMAT,
+ FLOPPY_PC_FORMAT
FLOPPY_FORMATS_END
static SLOT_INTERFACE_START(keyboard)
@@ -790,13 +793,6 @@ static MACHINE_CONFIG_START( m20, m20_state )
MCFG_RAM_DEFAULT_VALUE(0)
MCFG_RAM_EXTRA_OPTIONS("128K,192K,224K,256K,384K,512K")
-#if 0
- MCFG_CPU_ADD("apb", I8086, MAIN_CLOCK)
- MCFG_CPU_PROGRAM_MAP(m20_apb_mem)
- MCFG_CPU_IO_MAP(m20_apb_io)
- MCFG_DEVICE_DISABLE()
-#endif
-
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
@@ -832,11 +828,13 @@ static MACHINE_CONFIG_START( m20, m20_state )
MCFG_PIT8253_CLK2(1230782)
MCFG_PIT8253_OUT2_HANDLER(WRITELINE(m20_state, timer_tick_w))
- MCFG_PIC8259_ADD("i8259", INPUTLINE("maincpu", 1), VCC, NULL)
+ MCFG_PIC8259_ADD("i8259", WRITELINE(m20_state, int_w), VCC, NULL)
MCFG_RS232_PORT_ADD("kbd", keyboard, "m20")
MCFG_RS232_RXD_HANDLER(DEVWRITELINE("i8251_1", i8251_device, write_rxd))
+ MCFG_DEVICE_ADD("apb", M20_8086, 0)
+
MCFG_SOFTWARE_LIST_ADD("flop_list","m20")
MACHINE_CONFIG_END
diff --git a/src/mess/drivers/xbox.c b/src/mess/drivers/xbox.c
new file mode 100644
index 00000000000..8b2ada377e8
--- /dev/null
+++ b/src/mess/drivers/xbox.c
@@ -0,0 +1,224 @@
+// license:BSD-3-Clause
+// copyright-holders:?
+/***************************************************************************
+
+ XBOX (c) 2001 Microsoft
+
+ Skeleton driver
+
+***************************************************************************/
+
+
+#include "emu.h"
+#include "cpu/i386/i386.h"
+//#include "machine/lpci.h"
+//#include "machine/pic8259.h"
+//#include "machine/pit8253.h"
+//#include "machine/idectrl.h"
+//#include "machine/idehd.h"
+//#include "machine/naomigd.h"
+//#include "video/poly.h"
+//#include "bitmap.h"
+//#include "debug/debugcon.h"
+//#include "debug/debugcmd.h"
+//#include "debug/debugcpu.h"
+//#include "includes/chihiro.h"
+
+
+#define CPU_DIV 64
+
+/*!
+ @todo - Inheritance with chihiro_state
+ */
+class xbox_state : public driver_device
+{
+public:
+ xbox_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu")
+ { }
+
+ // devices
+ required_device m_maincpu;
+
+ // screen updates
+ UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ DECLARE_PALETTE_INIT(xbox);
+protected:
+ // driver_device overrides
+ virtual void machine_start();
+ virtual void machine_reset();
+
+ virtual void video_start();
+};
+
+void xbox_state::video_start()
+{
+}
+
+UINT32 xbox_state::screen_update( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect )
+{
+ return 0;
+}
+
+static ADDRESS_MAP_START(xbox_map, AS_PROGRAM, 32, xbox_state)
+ AM_RANGE(0x00000000, 0x07ffffff) AM_RAM // 128 megabytes
+ AM_RANGE(0xf0000000, 0xf0ffffff) AM_RAM
+// AM_RANGE(0xfd000000, 0xfdffffff) AM_RAM AM_READWRITE(geforce_r, geforce_w)
+// AM_RANGE(0xfed00000, 0xfed003ff) AM_READWRITE(usbctrl_r, usbctrl_w)
+// AM_RANGE(0xfe800000, 0xfe85ffff) AM_READWRITE(audio_apu_r, audio_apu_w)
+// AM_RANGE(0xfec00000, 0xfec001ff) AM_READWRITE(audio_ac93_r, audio_ac93_w)
+ AM_RANGE(0xff000000, 0xff07ffff) AM_ROM AM_REGION("bios", 0) AM_MIRROR(0x00f80000)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(xbox_map_io, AS_IO, 32, xbox_state)
+// AM_RANGE(0x0020, 0x0023) AM_DEVREADWRITE8("pic8259_1", pic8259_device, read, write, 0xffffffff)
+// AM_RANGE(0x0040, 0x0043) AM_DEVREADWRITE8("pit8254", pit8254_device, read, write, 0xffffffff)
+// AM_RANGE(0x00a0, 0x00a3) AM_DEVREADWRITE8("pic8259_2", pic8259_device, read, write, 0xffffffff)
+// AM_RANGE(0x01f0, 0x01f7) AM_DEVREADWRITE("ide", bus_master_ide_controller_device, read_cs0, write_cs0)
+// AM_RANGE(0x0cf8, 0x0cff) AM_DEVREADWRITE("pcibus", pci_bus_legacy_device, read, write)
+// AM_RANGE(0x4000, 0x40ff) AM_READWRITE(mediaboard_r, mediaboard_w)
+// AM_RANGE(0x8000, 0x80ff) AM_READWRITE(dummy_r, dummy_w)
+// AM_RANGE(0xc000, 0xc0ff) AM_READWRITE(smbus_r, smbus_w)
+// AM_RANGE(0xff60, 0xff67) AM_DEVREADWRITE("ide", bus_master_ide_controller_device, bmdma_r, bmdma_w)
+ADDRESS_MAP_END
+
+static INPUT_PORTS_START( xbox )
+ /* dummy active high structure */
+ PORT_START("SYSA")
+ PORT_DIPNAME( 0x01, 0x00, "SYSA" )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x01, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x02, DEF_STR( On ) )
+ PORT_DIPNAME( 0x04, 0x00, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x04, DEF_STR( On ) )
+ PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x08, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x00, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x10, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x20, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x00, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x40, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( On ) )
+
+ /* dummy active low structure */
+ PORT_START("DSWA")
+ PORT_DIPNAME( 0x01, 0x01, "DSWA" )
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+INPUT_PORTS_END
+
+
+
+
+void xbox_state::machine_start()
+{
+}
+
+void xbox_state::machine_reset()
+{
+}
+
+
+PALETTE_INIT_MEMBER(xbox_state, xbox)
+{
+}
+
+static MACHINE_CONFIG_START( xbox, xbox_state )
+
+ /* basic machine hardware */
+ MCFG_CPU_ADD("maincpu", PENTIUM3, 733333333/CPU_DIV) /* Wrong! family 6 model 8 stepping 10 */
+ MCFG_CPU_PROGRAM_MAP(xbox_map)
+ MCFG_CPU_IO_MAP(xbox_map_io)
+// MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(chihiro_state, irq_callback)
+
+ /* video hardware */
+ MCFG_SCREEN_ADD("screen", RASTER)
+// MCFG_SCREEN_REFRESH_RATE(60)
+// MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
+ MCFG_SCREEN_UPDATE_DRIVER(xbox_state, screen_update)
+// MCFG_SCREEN_SIZE(32*8, 32*8)
+// MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 32*8-1)
+ MCFG_SCREEN_RAW_PARAMS(8000000/2, 442, 0, 320, 264, 0, 240) /* generic NTSC video timing, change accordingly */
+ MCFG_SCREEN_PALETTE("palette")
+
+ MCFG_PALETTE_ADD("palette", 8)
+ MCFG_PALETTE_INIT_OWNER(xbox_state, xbox)
+
+ /* sound hardware */
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+// MCFG_SOUND_ADD("aysnd", AY8910, MAIN_CLOCK/4)
+// MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.30)
+MACHINE_CONFIG_END
+
+
+/***************************************************************************
+
+ Machine driver(s)
+
+***************************************************************************/
+
+ROM_START( xbox )
+ ROM_REGION( 0x200, "mcpx", 0 )
+ ROM_LOAD( "mcpx_1_0.bin", 0, 0x200, CRC(f31429fc) SHA1(a9ecbf8896d10db81594923e485862aa3aac7b58) )
+ ROM_LOAD( "mcpx_1_1.bin", 0, 0x200, CRC(94ce376b) SHA1(6c875f17f773aaec51eb434068bb6c657c4343c0) )
+
+ ROM_REGION( 0x80000, "bios", 0)
+ ROM_LOAD( "xbox-5530.bin", 0x000000, 0x040000, CRC(9569c4d3) SHA1(40fa73277013be3168135e1768b09623a987ff63) )
+ ROM_LOAD( "xbox-5713.bin", 0x040000, 0x040000, CRC(58fd8173) SHA1(8b7ccc4648ccd78cdb7b65cfca09621eaf2d4238) )
+ ROM_COPY( "mcpx", 0, 0x7fe00, 0x200 )
+
+
+ ROM_REGION( 0x1000000, "tbp", 0 ) // To Be Processed, of course
+ ROM_LOAD( "3944_1024k.bin", 0x000000, 0x100000, CRC(32a9ecb6) SHA1(67054fc88bda94e33e86f1b19be60efec0724fb6) )
+ ROM_LOAD( "4034_1024k.bin", 0x000000, 0x100000, CRC(0d6fc88f) SHA1(ab676b712204fb1728bf89f9cd541a8f5a64ab97) )
+ ROM_LOAD( "4134_1024k.bin", 0x000000, 0x100000, CRC(49d8055a) SHA1(d46cef771a63dc8024fe36d7ab5b959087ac999f) )
+ ROM_LOAD( "4817_1024k.bin", 0x000000, 0x100000, CRC(3f30863a) SHA1(dc955bd4d3ca71e01214a49e5d0aba615270c03c) )
+ ROM_LOAD( "5101_256k.bin", 0x000000, 0x040000, CRC(e8a9224e) SHA1(5108e1025f48071c07a6823661d708c66dee97a9) )
+ ROM_LOAD( "5838_256k.bin", 0x000000, 0x040000, CRC(5be2413d) SHA1(b9489e883c650b5e5fe2f83a32237dbf74f0e9f1) )
+ROM_END
+// See src/emu/gamedrv.h for details
+// For a game:
+// GAME(YEAR,NAME,PARENT,MACHINE,INPUT,CLASS,INIT,MONITOR,COMPANY,FULLNAME,FLAGS)
+
+// For a console:
+// CONS(YEAR,NAME,PARENT,COMPAT,MACHINE,INPUT,CLASS,INIT,COMPANY,FULLNAME,FLAGS)
+
+// For a computer:
+// COMP(YEAR,NAME,PARENT,COMPAT,MACHINE,INPUT,CLASS,INIT,COMPANY,FULLNAME,FLAGS)
+
+// For a generic system:
+// SYST(YEAR,NAME,PARENT,COMPAT,MACHINE,INPUT,CLASS,INIT,COMPANY,FULLNAME,FLAGS)
+
+CONS( 2001, xbox, 0, 0, xbox, xbox, driver_device, 0, "Microsoft", "XBOX", GAME_IS_SKELETON )
diff --git a/src/mess/machine/m20_8086.c b/src/mess/machine/m20_8086.c
new file mode 100644
index 00000000000..5c817b17edf
--- /dev/null
+++ b/src/mess/machine/m20_8086.c
@@ -0,0 +1,119 @@
+// license:BSD-3-Clause
+// copyright-holders:Carl
+#include "m20_8086.h"
+#include "machine/ram.h"
+
+const device_type M20_8086 = &device_creator;
+
+m20_8086_device::m20_8086_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, M20_8086, "Olivetti M20 8086 Adapter", tag, owner, clock, "m20_8086", __FILE__),
+ m_8086(*this, "8086"),
+ m_maincpu(*this, ":maincpu"),
+ m_pic(*this, ":i8259"),
+ m_8086_halt(true)
+{
+}
+
+void m20_8086_device::device_start()
+{
+ UINT8* ram = machine().device("ram")->pointer();
+ m_8086->space(AS_PROGRAM).install_readwrite_bank(0x00000, machine().device("ram")->size() - 0x4001, "mainram");
+ membank("highram")->set_base(ram);
+ membank("mainram")->set_base(&ram[0x4000]);
+ membank("vram")->set_base(memshare(":p_videoram")->ptr());
+ membank("vram2")->set_base(memshare(":p_videoram")->ptr());
+}
+
+void m20_8086_device::device_reset()
+{
+ m_8086_halt = true;
+ m_nvi = m_vi = 0;
+ m_8086->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
+}
+
+ROM_START( m20_8086 )
+ ROM_REGION(0x4000, "8086", 0)
+ ROM_LOAD("apb-1086-2.0.bin", 0x0000, 0x4000, CRC(8c05be93) SHA1(2bb424afd874cc6562e9642780eaac2391308053))
+ROM_END
+
+
+const rom_entry *m20_8086_device::device_rom_region() const
+{
+ return ROM_NAME( m20_8086 );
+}
+
+static ADDRESS_MAP_START(i86_prog, AS_PROGRAM, 16, m20_8086_device)
+ AM_RANGE(0xe0000, 0xe3fff) AM_RAMBANK("vram2")
+ AM_RANGE(0xf0000, 0xf3fff) AM_RAMBANK("highram")
+ AM_RANGE(0xf4000, 0xf7fff) AM_RAMBANK("vram")
+ AM_RANGE(0xfc000, 0xfffff) AM_ROM AM_REGION("8086",0)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(i86_io, AS_IO, 16, m20_8086_device)
+ AM_RANGE(0x4000, 0x4fff) AM_READWRITE(z8000_io_r, z8000_io_w)
+ AM_RANGE(0x7ffa, 0x7ffd) AM_WRITE(handshake_w)
+ADDRESS_MAP_END
+
+static MACHINE_CONFIG_FRAGMENT( m20_8086 )
+ MCFG_CPU_ADD("8086", I8086, XTAL_24MHz/3)
+ MCFG_CPU_PROGRAM_MAP(i86_prog)
+ MCFG_CPU_IO_MAP(i86_io)
+ MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(m20_8086_device, int_cb)
+MACHINE_CONFIG_END
+
+machine_config_constructor m20_8086_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( m20_8086 );
+}
+
+READ16_MEMBER(m20_8086_device::z8000_io_r)
+{
+ return m_maincpu->space(AS_IO).read_word(offset << 1, mem_mask);
+}
+
+WRITE16_MEMBER(m20_8086_device::z8000_io_w)
+{
+ m_maincpu->space(AS_IO).write_word(offset << 1, data, mem_mask);
+}
+
+IRQ_CALLBACK_MEMBER(m20_8086_device::int_cb)
+{
+ if(m_nvi)
+ {
+ m_nvi = false;
+ m_8086->set_input_line(INPUT_LINE_IRQ0, m_vi ? ASSERT_LINE : CLEAR_LINE);
+ return 0xff;
+ }
+ else
+ return m_pic->acknowledge() << 1;
+}
+
+WRITE_LINE_MEMBER(m20_8086_device::nvi_w)
+{
+ m_nvi = state;
+ m_8086->set_input_line(INPUT_LINE_IRQ0, (state || m_vi) ? ASSERT_LINE : CLEAR_LINE);
+}
+
+WRITE_LINE_MEMBER(m20_8086_device::vi_w)
+{
+ m_vi = state;
+ m_8086->set_input_line(INPUT_LINE_IRQ0, (state || m_nvi) ? ASSERT_LINE : CLEAR_LINE);
+}
+
+WRITE16_MEMBER(m20_8086_device::handshake_w)
+{
+ if(!offset)
+ {
+ m_8086->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
+ m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
+ m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
+ m_8086_halt = true;
+ }
+ else
+ {
+ m_8086->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
+ m_8086->set_input_line(INPUT_LINE_RESET, PULSE_LINE);
+ m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
+ m_8086_halt = false;
+ }
+}
diff --git a/src/mess/machine/m20_8086.h b/src/mess/machine/m20_8086.h
new file mode 100644
index 00000000000..148ba808c0a
--- /dev/null
+++ b/src/mess/machine/m20_8086.h
@@ -0,0 +1,40 @@
+// license:BSD-3-Clause
+// copyright-holders:Carl
+#ifndef M20_8086_H_
+#define M20_8086_H_
+
+#include "emu.h"
+#include "cpu/i86/i86.h"
+#include "machine/pic8259.h"
+
+class m20_8086_device : public device_t
+{
+public:
+ m20_8086_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ virtual const rom_entry *device_rom_region() const;
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+ DECLARE_READ16_MEMBER(z8000_io_r);
+ DECLARE_WRITE16_MEMBER(z8000_io_w);
+ DECLARE_WRITE_LINE_MEMBER(vi_w);
+ DECLARE_WRITE_LINE_MEMBER(nvi_w);
+ DECLARE_WRITE16_MEMBER(handshake_w);
+ IRQ_CALLBACK_MEMBER(int_cb);
+ bool halted() { return m_8086_halt; }
+ required_device m_8086;
+
+protected:
+ void device_start();
+ void device_reset();
+
+private:
+ required_device m_maincpu;
+ required_device m_pic;
+ bool m_8086_halt;
+ int m_nvi, m_vi;
+};
+
+extern const device_type M20_8086;
+
+#endif /* M20_8086_H_ */
diff --git a/src/osd/modules/lib/osdlib_win32.c b/src/osd/modules/lib/osdlib_win32.c
index 846d7e859cd..85334fd8ddc 100644
--- a/src/osd/modules/lib/osdlib_win32.c
+++ b/src/osd/modules/lib/osdlib_win32.c
@@ -36,6 +36,16 @@
// align allocations to start or end of the page?
#define GUARD_ALIGN_START 0
+#if defined(__BIGGEST_ALIGNMENT__)
+#define MAX_ALIGNMENT __BIGGEST_ALIGNMENT__
+#elif defined(__AVX__)
+#define MAX_ALIGNMENT 32
+#elif defined(__SSE__) || defined(__x86_64__) || defined(_M_X64)
+#define MAX_ALIGNMENT 16
+#else
+#define MAX_ALIGNMENT sizeof(INT64)
+#endif
+
//============================================================
// GLOBAL VARIABLES
@@ -112,17 +122,22 @@ int osd_get_num_processors(void)
void *osd_malloc(size_t size)
{
#ifndef MALLOC_DEBUG
- return HeapAlloc(GetProcessHeap(), 0, size);
+ return malloc(size);
#else
- // add in space for the size
- size += sizeof(size_t);
+ // add in space for the size and offset
+ size += MAX_ALIGNMENT + sizeof(size_t) + 2;
+ size &= ~size_t(1);
// basic objects just come from the heap
- void *result = HeapAlloc(GetProcessHeap(), 0, size);
+ UINT8 *const block = reinterpret_cast(HeapAlloc(GetProcessHeap(), 0, size));
+ if (block == NULL)
+ return NULL;
+ UINT8 *const result = reinterpret_cast(reinterpret_cast(block + sizeof(size_t) + MAX_ALIGNMENT) & ~(FPTR(MAX_ALIGNMENT) - 1));
// store the size and return and pointer to the data afterward
- *reinterpret_cast(result) = size;
- return reinterpret_cast(result) + sizeof(size_t);
+ *reinterpret_cast(block) = size;
+ *(result - 1) = result - block;
+ return result;
#endif
}
@@ -134,13 +149,14 @@ void *osd_malloc(size_t size)
void *osd_malloc_array(size_t size)
{
#ifndef MALLOC_DEBUG
- return HeapAlloc(GetProcessHeap(), 0, size);
+ return malloc(size);
#else
- // add in space for the size
- size += sizeof(size_t);
+ // add in space for the size and offset
+ size += MAX_ALIGNMENT + sizeof(size_t) + 2;
+ size &= ~size_t(1);
// round the size up to a page boundary
- size_t rounded_size = ((size + sizeof(void *) + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
+ size_t const rounded_size = ((size + sizeof(void *) + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
// reserve that much memory, plus two guard pages
void *page_base = VirtualAlloc(NULL, rounded_size + 2 * PAGE_SIZE, MEM_RESERVE, PAGE_NOACCESS);
@@ -153,11 +169,13 @@ void *osd_malloc_array(size_t size)
return NULL;
// work backwards from the page base to get to the block base
- void *result = GUARD_ALIGN_START ? page_base : (reinterpret_cast(page_base) + rounded_size - size);
+ UINT8 *const block = GUARD_ALIGN_START ? reinterpret_cast(page_base) : (reinterpret_cast(page_base) + rounded_size - size);
+ UINT8 *const result = reinterpret_cast(reinterpret_cast(block + sizeof(size_t) + MAX_ALIGNMENT) & ~(FPTR(MAX_ALIGNMENT) - 1));
// store the size at the start with a flag indicating it has a guard page
- *reinterpret_cast(result) = size | 0x80000000;
- return reinterpret_cast(result) + sizeof(size_t);
+ *reinterpret_cast(block) = size | 1;
+ *(result - 1) = result - block;
+ return result;
#endif
}
@@ -169,18 +187,21 @@ void *osd_malloc_array(size_t size)
void osd_free(void *ptr)
{
#ifndef MALLOC_DEBUG
- HeapFree(GetProcessHeap(), 0, ptr);
+ free(ptr);
#else
- size_t size = reinterpret_cast(ptr)[-1];
+ UINT8 const offset = *(reinterpret_cast(ptr) - 1);
+ UINT8 *const block = reinterpret_cast(ptr) - offset;
+ size_t const size = *reinterpret_cast(block);
- // if no guard page, just free the pointer
- if ((size & 0x80000000) == 0)
- HeapFree(GetProcessHeap(), 0, reinterpret_cast(ptr) - sizeof(size_t));
-
- // large items need more care
+ if ((size & 0x1) == 0)
+ {
+ // if no guard page, just free the pointer
+ HeapFree(GetProcessHeap(), 0, block);
+ }
else
{
- ULONG_PTR page_base = (reinterpret_cast(ptr) - sizeof(size_t)) & ~(PAGE_SIZE - 1);
+ // large items need more care
+ ULONG_PTR const page_base = reinterpret_cast(block) & ~(PAGE_SIZE - 1);
VirtualFree(reinterpret_cast(page_base - PAGE_SIZE), 0, MEM_RELEASE);
}
#endif