Merge branch 'master' into S11tamrit

This commit is contained in:
system11b 2015-07-03 18:13:01 +01:00
commit c58cdf09a3
52 changed files with 4787 additions and 2251 deletions

View File

@ -3692,7 +3692,7 @@ Beyond that last category are the roms waiting to be classified.
<part name="cart" interface="snes_cart">
<feature name="slot" value="lorom" />
<dataarea name="rom" size="1048576">
<rom name="spellcraft (usa) (proto).sfc" size="1048576" crc="3daea8a1" sha1="fe4dcca5c3cb2e721f4dbf971cc06fe10f78e629" offset="0x000000" />
<rom name="spellcraft (usa) (proto).sfc" size="1048576" crc="47e900bf" sha1="67107c028eb23b830c9fdfc4136c416d793dd98f" offset="0x000000" />
</dataarea>
</part>
</software>

50
nl_examples/vs_cs.c Normal file
View File

@ -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()

View File

@ -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",

View File

@ -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"

View File

@ -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,

View File

@ -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();

View File

@ -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

View File

@ -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:

73
src/emu/cpu/rsp/vldst.h Normal file
View File

@ -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);
}
}

View File

@ -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
}
}

View File

@ -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();
};

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}
/******************************************

View File

@ -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()

View File

@ -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()

View File

@ -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")

View File

@ -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_ */

View File

@ -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
};

View File

@ -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);
}

View File

@ -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;

View File

@ -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)

View File

@ -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<pstring> m_stack;
source_t::list_t m_sources;
plist_t<pstring> m_lib;
void connect_terminals(core_terminal_t &in, core_terminal_t &out);

View File

@ -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
/*

View File

@ -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
{

View File

@ -147,7 +147,7 @@ template <unsigned m_N, unsigned _storage_N>
ATTR_COLD void matrix_solver_direct_t<m_N, _storage_N>::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++)
{

View File

@ -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; j<groups[i].size(); j++)
{
netlist().log("Net %" SIZETFMT ": %s", j, groups[i][j]->name().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++)
{

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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()

View File

@ -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 )

View File

@ -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<cpu_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 Descriptors 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)

View File

@ -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) )

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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)

View File

@ -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);
}

View File

@ -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 )

View File

@ -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<cpu_device> m_maincpu;
@ -48,101 +48,110 @@ public:
optional_device<deco104_device> m_deco104;
optional_device<decobsmt_device> m_decobsmt;
optional_device<buffered_spriteram32_device> m_spriteram;
optional_device<decospr_device> m_sprgen;
optional_device<decospr_device> m_sprgen1;
optional_device<decospr_device> m_sprgen2;
optional_device<deco_zoomspr_device> m_sprgenzoom;
optional_device<eeprom_serial_93cxx_device> m_eeprom;
optional_device<okim6295_device> m_oki1;
optional_device<okim6295_device> m_oki2;
required_device<deco16ic_device> m_deco_tilegen1;
required_device<deco16ic_device> m_deco_tilegen2;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
required_shared_ptr<UINT32> m_ram;
// we use the pointers below to store a 32-bit copy..
required_shared_ptr<UINT32> m_pf1_rowscroll32;
required_shared_ptr<UINT32> m_pf2_rowscroll32;
required_shared_ptr<UINT32> m_pf3_rowscroll32;
required_shared_ptr<UINT32> m_pf4_rowscroll32;
optional_shared_ptr<UINT32> m_ace_ram;
optional_device<decospr_device> m_sprgen;
optional_device<decospr_device> m_sprgen1;
optional_device<decospr_device> m_sprgen2;
optional_device<deco_zoomspr_device> m_sprgenzoom;
optional_device<eeprom_serial_93cxx_device> m_eeprom;
optional_device<okim6295_device> m_oki1;
optional_device<okim6295_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<deco16ic_device> m_deco_tilegen1;
required_device<deco16ic_device> m_deco_tilegen2;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
required_shared_ptr<UINT32> m_generic_paletteram_32;
optional_shared_ptr<UINT32> 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<UINT32> m_dragngun_sprite_layout_0_ram;
required_shared_ptr<UINT32> m_dragngun_sprite_layout_1_ram;
required_shared_ptr<UINT32> m_dragngun_sprite_lookup_0_ram;
required_shared_ptr<UINT32> m_dragngun_sprite_lookup_1_ram;
required_shared_ptr<UINT32> m_sprite_layout_0_ram;
required_shared_ptr<UINT32> m_sprite_layout_1_ram;
required_shared_ptr<UINT32> m_sprite_lookup_0_ram;
required_shared_ptr<UINT32> 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;
};

View File

@ -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);

View File

@ -1587,6 +1587,9 @@ hbf9sp
fsa1gt
fsa1st
// Microsoft
xbox
// NASCOM Microcomputers
nascom1 // 1978 Nascom 1
nascom2 // 1979 Nascom 2

View File

@ -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 );
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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

View File

@ -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<fd1797_t> m_fd1797;
required_device<floppy_image_device> m_floppy0;
required_device<floppy_image_device> m_floppy1;
optional_device<m20_8086_device> m_apb;
required_shared_ptr<UINT16> m_p_videoram;
required_device<palette_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

224
src/mess/drivers/xbox.c Normal file
View File

@ -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<cpu_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 )

119
src/mess/machine/m20_8086.c Normal file
View File

@ -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::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_device>("ram")->pointer();
m_8086->space(AS_PROGRAM).install_readwrite_bank(0x00000, machine().device<ram_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;
}
}

View File

@ -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<cpu_device> m_8086;
protected:
void device_start();
void device_reset();
private:
required_device<cpu_device> m_maincpu;
required_device<pic8259_device> m_pic;
bool m_8086_halt;
int m_nvi, m_vi;
};
extern const device_type M20_8086;
#endif /* M20_8086_H_ */

View File

@ -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<UINT8 *>(HeapAlloc(GetProcessHeap(), 0, size));
if (block == NULL)
return NULL;
UINT8 *const result = reinterpret_cast<UINT8 *>(reinterpret_cast<FPTR>(block + sizeof(size_t) + MAX_ALIGNMENT) & ~(FPTR(MAX_ALIGNMENT) - 1));
// store the size and return and pointer to the data afterward
*reinterpret_cast<size_t *>(result) = size;
return reinterpret_cast<UINT8 *>(result) + sizeof(size_t);
*reinterpret_cast<size_t *>(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<UINT8 *>(page_base) + rounded_size - size);
UINT8 *const block = GUARD_ALIGN_START ? reinterpret_cast<UINT8 *>(page_base) : (reinterpret_cast<UINT8 *>(page_base) + rounded_size - size);
UINT8 *const result = reinterpret_cast<UINT8 *>(reinterpret_cast<FPTR>(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<size_t *>(result) = size | 0x80000000;
return reinterpret_cast<UINT8 *>(result) + sizeof(size_t);
*reinterpret_cast<size_t *>(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<size_t *>(ptr)[-1];
UINT8 const offset = *(reinterpret_cast<UINT8 *>(ptr) - 1);
UINT8 *const block = reinterpret_cast<UINT8 *>(ptr) - offset;
size_t const size = *reinterpret_cast<size_t *>(block);
// if no guard page, just free the pointer
if ((size & 0x80000000) == 0)
HeapFree(GetProcessHeap(), 0, reinterpret_cast<UINT8 *>(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<ULONG_PTR>(ptr) - sizeof(size_t)) & ~(PAGE_SIZE - 1);
// large items need more care
ULONG_PTR const page_base = reinterpret_cast<ULONG_PTR>(block) & ~(PAGE_SIZE - 1);
VirtualFree(reinterpret_cast<void *>(page_base - PAGE_SIZE), 0, MEM_RELEASE);
}
#endif