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