From 564a0680659e469c49498ea819147897b34446ed Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Thu, 12 Mar 2020 13:10:53 +0100 Subject: First stab at the ks0164 core, plus a xavix fix (nw) --- src/devices/cpu/ks0164/ks0164.cpp | 683 ++++++++++++++++++++++++++++++++++++- src/devices/cpu/ks0164/ks0164.h | 40 ++- src/devices/cpu/ks0164/ks0164d.cpp | 71 ++-- src/devices/cpu/ks0164/ks0164d.h | 2 + src/devices/cpu/xavix2/xavix2.h | 6 +- src/mame/drivers/dgpix.cpp | 35 +- 6 files changed, 784 insertions(+), 53 deletions(-) diff --git a/src/devices/cpu/ks0164/ks0164.cpp b/src/devices/cpu/ks0164/ks0164.cpp index 538fd8b13ed..83739ac5f19 100644 --- a/src/devices/cpu/ks0164/ks0164.cpp +++ b/src/devices/cpu/ks0164/ks0164.cpp @@ -10,6 +10,11 @@ DEFINE_DEVICE_TYPE(KS0164, ks0164_device, "ks0164", "Samsung KS0164 audio processor") +const u16 ks0164_device::imask[16] = { + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + ks0164_device::ks0164_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : cpu_device(mconfig, KS0164, tag, owner, clock) , m_program_config("program", ENDIANNESS_BIG, 16, 16) @@ -18,18 +23,36 @@ ks0164_device::ks0164_device(const machine_config &mconfig, const char *tag, dev void ks0164_device::device_start() { - state_add(STATE_GENPC, "GENPC", m_pc).callexport().noshow(); - state_add(STATE_GENPCBASE, "CURPC", m_pc).callexport().noshow(); + m_program = &space(AS_PROGRAM); + m_program_cache = m_program->cache<1, 0, ENDIANNESS_BIG>(); + + state_add(STATE_GENPC, "GENPC", m_r[R_PC]).callexport().noshow(); + state_add(STATE_GENPCBASE, "CURPC", m_r[R_PC]).callexport().noshow(); + state_add(STATE_GENSP, "GENSP", m_r[R_SP]).noshow(); + state_add(STATE_GENFLAGS, "GENFLAGS", m_r[R_PSW]).callimport().formatstr("%8s").noshow(); + state_add(KS0164_PC, "PC", m_r[R_PC]).callimport(); + state_add(KS0164_PSW, "PSW", m_r[R_PSW]).callimport(); + + state_add(KS0164_SP, "SP", m_r[R_SP]); + + state_add(KS0164_R0, "R0", m_r[0]); + state_add(KS0164_R1, "R1", m_r[1]); + state_add(KS0164_R2, "R2", m_r[2]); + state_add(KS0164_R3, "R3", m_r[3]); + + save_item(NAME(m_r)); - save_item(NAME(m_pc)); set_icountptr(m_icount); - m_pc = 0; + m_irq = 0x10000; + memset(m_r, 0, sizeof(m_r)); } void ks0164_device::device_reset() { - m_pc = 0x780; + m_irq = 1; + memset(m_r, 0, sizeof(m_r)); + m_r[R_PSW] = F_I; } uint32_t ks0164_device::execute_min_cycles() const noexcept @@ -39,16 +62,20 @@ uint32_t ks0164_device::execute_min_cycles() const noexcept uint32_t ks0164_device::execute_max_cycles() const noexcept { - return 1; + return 5; } uint32_t ks0164_device::execute_input_lines() const noexcept { - return 0; + return 16; } void ks0164_device::execute_set_input(int inputnum, int state) { + if(state) + m_irq |= 1 << inputnum; + else + m_irq &= ~(1 << inputnum); } device_memory_interface::space_config_vector ks0164_device::memory_space_config() const @@ -65,10 +92,648 @@ std::unique_ptr ks0164_device::create_disassembler() void ks0164_device::state_string_export(const device_state_entry &entry, std::string &str) const { + switch(entry.index()) { + case STATE_GENFLAGS: + str = util::string_format("%c %c%c%c%c %x", + m_r[R_PSW] & F_I ? 'I' : '-', + m_r[R_PSW] & F_V ? 'V' : '-', + m_r[R_PSW] & F_C ? 'C' : '-', + m_r[R_PSW] & F_N ? 'N' : '-', + m_r[R_PSW] & F_Z ? 'Z' : '-', + m_r[R_PSW] & 0xf); + break; + } +} + +void ks0164_device::handle_irq() +{ + u16 mask = m_irq & imask[m_r[R_PSW] & 15]; + if(mask) { + int index; + for(index = 0; !(mask & (1 << index)); index ++); + if(index) { + // Normal irq (not reset), save pc and psw + if(m_r[R_PSW] & F_I) + return; + m_program->write_word(m_r[R_SP] - 2, m_r[R_PC]); + m_program->write_word(m_r[R_SP] - 4, m_r[R_PSW]); + m_r[R_SP] -= 4; + m_icount -= 2; + } else + m_irq &= 0xfffe; + + m_r[R_PSW] = (m_r[R_PSW] & 0xfff0) | (index ? index - 1 : 0); + m_r[R_PC] = m_program_cache->read_word(index*2); + m_icount --; + if(index) + standard_irq_callback(0); + } +} + +u16 ks0164_device::snz(u16 r) +{ + u16 f = 0; + if(!r) + f |= F_Z; + if(r & 0x8000) + f |= F_N; + m_r[R_PSW] = (m_r[R_PSW] & ~F_MASK) | f; + return r; +} + +void ks0164_device::do_alu(u16 opcode, u16 v2) +{ + int r = (opcode >> 8) & 7; + switch((opcode >> 11) & 7) { + case 0: { // add + u16 v1 = m_r[r]; + u16 res = v1 + v2; + u16 f = 0; + if(!res) + f |= F_Z; + if(res & 0x8000) + f |= F_N; + if(((v1 & v2) | ((~res) & (v1 | v2))) & 0x8000) + f |= F_C; + if(((v1 ^ res) & (v2 ^ res)) & 0x8000) + f |= F_V; + m_r[r] = res; + m_r[R_PSW] = (m_r[R_PSW] & ~F_MASK) | f; + break; + } + case 1: { // sub + u16 v1 = m_r[r]; + u16 res = v1 - v2; + u16 f = 0; + if(!res) + f |= F_Z; + if(res & 0x8000) + f |= F_N; + if(((v2 & res) | ((~v1) & (v2 | res))) & 0x8000) + f |= F_C; + if(((v1 ^ v2) & (v1 ^ res)) & 0x8000) + f |= F_V; + m_r[r] = res; + m_r[R_PSW] = (m_r[R_PSW] & ~F_MASK) | f; + break; + } + case 2: { // cmp + u16 v1 = m_r[r]; + u16 res = v1 - v2; + u16 f = 0; + if(!res) + f |= F_Z; + if(res & 0x8000) + f |= F_N; + if(((v2 & res) | ((~v1) & (v2 | res))) & 0x8000) + f |= F_C; + if(((v1 ^ v2) & (v1 ^ res)) & 0x8000) + f |= F_V; + m_r[R_PSW] = (m_r[R_PSW] & ~F_MASK) | f; + break; + } + case 3: // and + m_r[r] = snz(m_r[r] & v2); + break; + case 4: // or + m_r[r] = snz(m_r[r] | v2); + break; + case 5: // xor + m_r[r] = snz(m_r[r] ^ v2); + break; + case 6: // set + m_r[r] = v2; + break; + case 7: { // mul + u32 res; + if(opcode & 0x0080) + res = s16(m_r[r]) * s16(v2); + else + res = u16(m_r[r]) * u16(v2); + + u16 f = 0; + if(!res) + f |= F_Z; + if(res & 0x8000) + f |= F_N; + if(res & 0xffff0000) + f |= F_C; + if(res >= 0x00008000 && res < 0xffff8000) + f |= F_V; + m_r[r] = res; + m_r[R_PSW] = (m_r[R_PSW] & ~F_MASK) | f; + break; + } + } +} + +void ks0164_device::unk(u16 opcode) +{ + logerror("Unknown opcode %04x at address %04x\n", opcode, m_r[R_PC]-2); } void ks0164_device::execute_run() { - debugger_instruction_hook(m_pc); - m_icount = 0; + while(m_icount > 0) { + if(m_irq) + handle_irq(); + debugger_instruction_hook(m_r[R_PC]); + u16 opcode = m_program_cache->read_word(m_r[R_PC]); + m_r[R_PC] += 2; + + // First switch level on bits 15-14 and 2-0 + switch(((opcode >> 11) & 0x18) | (opcode & 0x7)) { + + case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: { + // Conditional branches + // 00cc ccoo oooo oooo + bool cond; + switch((opcode >> 10) & 0xf) { + case 0x0: cond = !(m_r[R_PSW] & F_Z); break; + case 0x1: cond = m_r[R_PSW] & F_Z ; break; + case 0x2: cond = !(m_r[R_PSW] & F_C); break; + case 0x3: cond = m_r[R_PSW] & F_C ; break; + case 0x4: cond = !(m_r[R_PSW] & F_N); break; + case 0x5: cond = m_r[R_PSW] & F_N ; break; + case 0x6: cond = !(m_r[R_PSW] & F_V); break; + case 0x7: cond = m_r[R_PSW] & F_V ; break; + case 0x8: cond = false; break; + case 0x9: cond = !(m_r[R_PSW] & F_Z) && !(m_r[R_PSW] & F_C); break; + case 0xa: cond = (m_r[R_PSW] & F_Z) || (m_r[R_PSW] & F_C); break; + case 0xb: cond = (!(m_r[R_PSW] & F_Z) && (m_r[R_PSW] & F_N) && (m_r[R_PSW] & F_V)) || (!(m_r[R_PSW] & F_Z) && !(m_r[R_PSW] & F_V) && !(m_r[R_PSW] & F_N)); break; + case 0xc: cond = (m_r[R_PSW] & F_Z) || ((m_r[R_PSW] & F_N) && !(m_r[R_PSW] & F_V)) || ((m_r[R_PSW] & F_V) && !(m_r[R_PSW] & F_N)); break; + case 0xd: cond = ((m_r[R_PSW] & F_N) && (m_r[R_PSW] & F_V)) || (!(m_r[R_PSW] & F_V) && !(m_r[R_PSW] & F_N)); break; + case 0xe: cond = ((m_r[R_PSW] & F_N) && !(m_r[R_PSW] & F_V)) || ((m_r[R_PSW] & F_V) && !(m_r[R_PSW] & F_N)); break; + case 0xf: cond = true; break; + } + if(cond) { + if(opcode & 0x200) + m_r[R_PC] += opcode | 0xfc00; + else + m_r[R_PC] += opcode & 0x3ff; + } + break; + } + + case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: { + // ALU functions with 8-bit immediate + // 01ff frrr iiii iiii + + do_alu(opcode, s8(opcode)); + break; + } + + case 0x14: { + // ALU functions with other register + // 10ff frrr Ssss w100 + u16 rv = m_r[(opcode >> 4) & 7]; + u16 v = opcode & 0x0004 ? rv : opcode & 0x0080 ? s8(rv) : u8(rv); + + do_alu(opcode, v); + break; + } + + case 0x15: { + // ALU functions with immediate + // 10ff frrr S... w101 + u16 rv = m_program_cache->read_word(m_r[R_PC]); + m_r[R_PC] += 2; + u16 v = opcode & 0x0004 ? rv : opcode & 0x0080 ? s8(rv) : u8(rv); + + do_alu(opcode, v); + break; + } + + case 0x16: { + // ALU functions from memory indexed + // 10ff frrr Ssss w110 + u16 a = m_r[(opcode >> 4) & 7]; + u16 v = opcode & 0x0004 ? m_program->read_word(a) : opcode & 0x0080 ? s8(m_program->read_byte(a)) : u8(m_program->read_byte(a)); + m_icount -= 2; + + do_alu(opcode, v); + break; + } + + case 0x17: { + // ALU functions from memory indexed and offset + // 10ff frrr Ssss w111 + u16 a = m_r[(opcode >> 4) & 7] + m_program_cache->read_word(m_r[R_PC]); + m_r[R_PC] += 2; + u16 v = opcode & 0x0004 ? m_program->read_word(a) : opcode & 0x0080 ? s8(m_program->read_byte(a)) : u8(m_program->read_byte(a)); + m_icount -= 2; + + do_alu(opcode, v); + break; + } + + case 0x18: { + switch((opcode >> 12) & 3) { + case 0: { + // Data move with pre/post incrementation + // 1100 arrr bsss c000 + + int r1 = (opcode >> 8) & 7; + int r2 = (opcode >> 4) & 7; + switch(bitswap<3>(opcode, 11, 7, 3)) { + case 1: m_program->write_word(m_r[r1], m_r[r2]); m_r[r1] += 2; break; + case 4: m_r[r1] -= 2; m_program->write_word(m_r[r1], m_r[r2]); break; + default: unk(opcode); break; + } + m_icount --; + break; + } + + case 1: { + // Min/max with immediate + // 1101 Mrrr Ssss 1000 + u16 v1 = m_r[(opcode >> 4) & 7]; + u16 v2 = m_program_cache->read_word(m_r[R_PC]); + m_r[R_PC] += 2; + u16 res; + switch(bitswap<2>(opcode, 11, 7)) { + case 0: res = v1 > v2 ? v1 : v2; break; + case 1: res = s16(v1) > s16(v2) ? v1 : v2; break; + case 2: res = v1 < v2 ? v1 : v2; break; + case 3: res = s16(v1) < s16(v2) ? v1 : v2; break; + } + m_r[(opcode >> 8) & 7] = res; + break; + } + + case 2: { + // Bit test in register + // 1110 .rrr bbbb .000 + if(m_r[(opcode >> 8) & 7] & (1 << ((opcode >> 4) & 0xf))) + m_r[R_PSW] &= ~F_Z; + else + m_r[R_PSW] |= F_Z; + break; + } + + case 3: { + unk(opcode); + break; + } + } + break; + } + + case 0x19: { + switch((opcode >> 12) & 3) { + case 0: { + // Push all registers + // 1100 .... .... .001 + + m_program->write_word(m_r[R_SP] - 2, m_r[0]); + m_program->write_word(m_r[R_SP] - 4, m_r[1]); + m_program->write_word(m_r[R_SP] - 6, m_r[2]); + m_program->write_word(m_r[R_SP] - 8, m_r[3]); + m_r[R_SP] -= 8; + break; + } + + case 1: { + // Absolute jump + // 1101 .... .... .001 + m_r[R_PC] = m_program->read_word(m_r[R_PC]); + break; + } + + case 2: { + // Bit set in register + // 1110 .rrr bbbb .001 + m_r[(opcode >> 8) & 7] |= 1 << ((opcode >> 4) & 0xf); + break; + } + + case 3: { + unk(opcode); + break; + } + } + break; + } + + case 0x1a: { + switch((opcode >> 12) & 3) { + case 0: { + // Data move with pre/post incrementation + // 1100 arrr bsss c010 + + int r1 = (opcode >> 8) & 7; + int r2 = (opcode >> 4) & 7; + switch(bitswap<3>(opcode, 11, 7, 3)) { + case 1: m_r[r1] = m_program->read_word(m_r[r2]); m_r[r2] += 2; break; + default: unk(opcode); break; + } + m_icount --; + break; + } + + case 1: { + // Absolute subroutine call + // 1101 .... .... .010 + + u16 a = m_program->read_word(m_r[R_PC]); + m_program->write_word(m_r[R_SP] - 2, m_r[R_PC] + 2); + m_r[R_SP] -= 2; + m_r[R_PC] = a; + m_icount -= 2; + break; + } + + case 2: { + // Bit test from memory indexed + // 1110 .rrr bbbb w010 + + u16 a = m_r[(opcode >> 8) & 7]; + u16 v = opcode & 0x0008 ? m_program->read_word(a) : m_program->read_byte(a); + if(v & (1 << ((opcode >> 4) & 0xf))) + m_r[R_PSW] &= ~F_Z; + else + m_r[R_PSW] |= F_Z; + m_icount -= 2; + break; + } + + case 3: { + unk(opcode); + break; + } + } + break; + } + + case 0x1b: { + switch((opcode >> 12) & 3) { + case 0: { + // Push all registers + // 1100 .... .... .011 + + m_r[0] = m_program->read_word(m_r[R_SP] + 6); + m_r[1] = m_program->read_word(m_r[R_SP] + 4); + m_r[2] = m_program->read_word(m_r[R_SP] + 2); + m_r[3] = m_program->read_word(m_r[R_SP] + 0); + m_r[R_SP] += 8; + break; + } + + case 1: { + // Return from subroutine + // 1101 .... .... .011 + + m_r[R_PC] = m_program->read_word(m_r[R_SP]); + m_r[R_SP] += 2; + m_icount --; + break; + } + + case 2: { + // Bit test from memory indexed and offset + // 1110 .rrr bbbb w011 + + u16 a = m_r[(opcode >> 8) & 7] + m_program_cache->read_word(m_r[R_PC]); + m_r[R_PC] += 2; + u16 v = opcode & 0x0008 ? m_program->read_word(a) : m_program->read_byte(a); + if(v & (1 << ((opcode >> 4) & 0xf))) + m_r[R_PSW] &= ~F_Z; + else + m_r[R_PSW] |= F_Z; + m_icount -= 2; + break; + } + + case 3: { + unk(opcode); + break; + } + } + break; + } + + case 0x1c: { + switch((opcode >> 12) & 3) { + case 0: { + // Unsigned shifts + // 1100 drrr nnnn .100 + + int r = (opcode >> 8) & 7; + int shift = (opcode >> 4) & 0xf; + u16 v1 = m_r[r]; + u16 res; + + if(!shift) { + m_r[R_PSW] = (m_r[R_PSW] & ~F_MASK) | (v1 ? v1 & 0x8000 ? F_N : 0 : F_Z); + res = v1; + } else if(opcode & 0x0800) { + res = v1 >> shift; + u16 f = res ? 0 : F_Z; + if(v1 & (1 << (shift - 1))) + f |= F_C; + m_r[R_PSW] = (m_r[R_PSW] & ~F_MASK) | f; + } else { + res = v1 << shift; + u16 f = res ? res & 0x8000 ? F_N : 0 : F_Z; + if(v1 & (1 << (16-shift))) + f |= F_C; + m_r[R_PSW] = (m_r[R_PSW] & ~F_MASK) | f; + } + m_r[r] = res; + break; + } + + case 1: { + // Return from interrupt + // 1101 .... .... .100 + + m_r[R_PSW] = m_program->read_word(m_r[R_SP] + 0); + m_r[R_PC] = m_program->read_word(m_r[R_SP] + 2); + m_r[R_SP] += 4; + m_icount -= 2; + break; + } + + case 2: { + // Bit clear in register + // 1110 .rrr bbbb .001 + m_r[(opcode >> 8) & 7] &= ~(1 << ((opcode >> 4) & 0xf)); + break; + } + + case 3: { + // Decrement and branch + int r = (opcode >> 8) & 7; + u16 a = m_program_cache->read_word(m_r[R_PC]); + m_r[R_PC] += 2; + + m_r[r] --; + if(m_r[r] != 0xffff) + m_r[R_PC] = a; + break; + } + } + break; + } + + case 0x1d: { + switch((opcode >> 12) & 3) { + case 0: { + // Signed shifts + // 1100 drrr nnnn .101 + + int r = (opcode >> 8) & 7; + int shift = (opcode >> 4) & 0xf; + u16 v1 = m_r[r]; + u16 res; + + if(!shift) { + m_r[R_PSW] = (m_r[R_PSW] & ~F_MASK) | (v1 ? v1 & 0x8000 ? F_N : 0 : F_Z); + res = v1; + } else if(opcode & 0x0800) { + res = s16(v1) >> shift; + u16 f = res ? res & 0x8000 ? F_N : 0 : F_Z; + if(v1 & (1 << (shift - 1))) + f |= F_C; + m_r[R_PSW] = (m_r[R_PSW] & ~F_MASK) | f; + } else { + res = v1 << shift; + u16 f = res ? res & 0x8000 ? F_N : 0 : F_Z; + if(v1 & (1 << (16-shift))) + f |= F_C; + m_r[R_PSW] = (m_r[R_PSW] & ~F_MASK) | f; + } + m_r[r] = res; + break; + } + + case 1: { + // Neg/not + // 1101 .rrr Ssss .101 + + u16 v = m_r[(opcode >> 4) & 7]; + if(opcode & 0x0080) + v = -s16(v); + else + v = ~v; + m_r[R_PSW] = (m_r[R_PSW] & ~F_MASK) | (v ? v & 0x8000 ? F_N : 0 : F_Z); + break; + } + + case 2: { + unk(opcode); + break; + } + + case 3: { + // Compare with immediate and branch if equal + // 1111 .rrr .... .101 + + u16 v = m_program_cache->read_word(m_r[R_PC]); + u16 a = m_program_cache->read_word(m_r[R_PC] + 2); + m_r[R_PC] += 4; + + do_alu((opcode & 0x07ff) | 0x1000, v); + if(m_r[R_PSW] & F_Z) + m_r[R_PC] = a; + break; + } + } + break; + } + + case 0x1e: { + switch((opcode >> 12) & 3) { + case 0: { + unk(opcode); + break; + } + + case 1: { + unk(opcode); + break; + } + + case 2: { + // Write memory indexed + // 1110 .rrr .sss w110 + u16 a = m_r[(opcode >> 8) & 7]; + if(opcode & 0x0008) + m_program->write_word(a, m_r[(opcode >> 4) & 7]); + else + m_program->write_byte(a, m_r[(opcode >> 4) & 7]); + break; + } + + case 3: { + unk(opcode); + break; + } + } + break; + } + + case 0x1f: { + switch((opcode >> 12) & 3) { + case 0: { + // Rotate through carry + // 1100 drrr nnnn .111 + + int r = (opcode >> 8) & 7; + int shift = (opcode >> 4) & 0xf; + u32 v1 = m_r[r] | (m_r[R_PSW] & F_C ? 0x10000 : 0); + u16 res; + + if(!shift) { + m_r[R_PSW] = (m_r[R_PSW] & ~(F_N|F_Z|F_V)) | (v1 & 0xffff ? v1 & 0x8000 ? F_N : 0 : F_Z); + res = v1; + } else if(opcode & 0x0800) { + res = (v1 >> shift) | (v1 << (17-shift)); + u16 f = res ? res & 0x8000 ? F_N : 0 : F_Z; + if(v1 & (1 << (shift - 1))) + f |= F_C; + m_r[R_PSW] = (m_r[R_PSW] & ~F_MASK) | f; + } else { + res = (v1 << shift) | (v1 >> (17-shift)); + u16 f = res ? res & 0x8000 ? F_N : 0 : F_Z; + if(v1 & (1 << (16-shift))) + f |= F_C; + m_r[R_PSW] = (m_r[R_PSW] & ~F_MASK) | f; + } + m_r[r] = res; + break; + } + + case 1: { + unk(opcode); + break; + } + + case 2: { + // Write memory indexed and offset + // 1110 .rrr .sss w111 + u16 a = m_r[(opcode >> 8) & 7] + m_program_cache->read_word(m_r[R_PC]); + m_r[R_PC] += 2; + if(opcode & 0x0008) + m_program->write_word(a, m_r[(opcode >> 4) & 7]); + else + m_program->write_byte(a, m_r[(opcode >> 4) & 7]); + break; + } + + case 3: { + unk(opcode); + break; + } + } + break; + } + + default: + unk(opcode); + break; + } + + m_r[R_ZERO] = 0; + } } diff --git a/src/devices/cpu/ks0164/ks0164.h b/src/devices/cpu/ks0164/ks0164.h index 5041b8270e5..12bcdde987f 100644 --- a/src/devices/cpu/ks0164/ks0164.h +++ b/src/devices/cpu/ks0164/ks0164.h @@ -14,8 +14,29 @@ public: ks0164_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: + enum { + R_SP = 4, + R_PSW = 5, + R_PC = 6, + R_ZERO = 7 + }; + + enum { + F_MASK = 0xf0, + + F_Z = 0x10, + F_C = 0x20, + F_N = 0x40, + F_V = 0x80, + + F_I = 0x8000 + }; + + static const u16 imask[16]; + int m_icount; - u32 m_pc; + u16 m_r[8]; + u32 m_irq; virtual void device_start() override; virtual void device_reset() override; @@ -29,6 +50,23 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; const address_space_config m_program_config; + address_space *m_program; + memory_access_cache<1, 0, ENDIANNESS_BIG> *m_program_cache; + + void handle_irq(); + u16 snz(u16 r); + void do_alu(u16 opcode, u16 v); + void unk(u16 opcode); +}; + +enum { + KS0164_R0, + KS0164_R1, + KS0164_R2, + KS0164_R3, + KS0164_SP, + KS0164_PSW, + KS0164_PC, }; DECLARE_DEVICE_TYPE(KS0164, ks0164_device) diff --git a/src/devices/cpu/ks0164/ks0164d.cpp b/src/devices/cpu/ks0164/ks0164d.cpp index 5aeb65caec4..dfdb4e79ce7 100644 --- a/src/devices/cpu/ks0164/ks0164d.cpp +++ b/src/devices/cpu/ks0164/ks0164d.cpp @@ -20,6 +20,11 @@ s32 ks0164_disassembler::off10(u32 opcode) return opcode & 0x200 ? opcode | 0xfffffc00 : opcode & 0x3ff; } +std::string ks0164_disassembler::imm8(s8 dt) +{ + return dt < 0 ? util::string_format("-%x", -dt) : util::string_format("%x", dt); +} + std::string ks0164_disassembler::off16(s16 dt) { return dt < 0 ? util::string_format(" - %x", -dt) : dt ? util::string_format(" + %x", dt) : ""; @@ -35,7 +40,7 @@ const ks0164_disassembler::instruction ks0164_disassembler::instructions[] { { 0x1400, 0xfc00, [](P) -> u32 { util::stream_format(stream, "bmi %04x", (pc + 2 + off10(opcode)) & 0xffff); return 2; } }, { 0x1800, 0xfc00, [](P) -> u32 { util::stream_format(stream, "bvc %04x", (pc + 2 + off10(opcode)) & 0xffff); return 2; } }, { 0x1c00, 0xfc00, [](P) -> u32 { util::stream_format(stream, "bvs %04x", (pc + 2 + off10(opcode)) & 0xffff); return 2; } }, - { 0x2000, 0xfc00, [](P) -> u32 { util::stream_format(stream, "b?8 %04x", (pc + 2 + off10(opcode)) & 0xffff); return 2; } }, + { 0x2000, 0xfc00, [](P) -> u32 { util::stream_format(stream, "bnv %04x", (pc + 2 + off10(opcode)) & 0xffff); return 2; } }, { 0x2400, 0xfc00, [](P) -> u32 { util::stream_format(stream, "bgtu %04x", (pc + 2 + off10(opcode)) & 0xffff); return 2; } }, { 0x2800, 0xfc00, [](P) -> u32 { util::stream_format(stream, "bleu %04x", (pc + 2 + off10(opcode)) & 0xffff); return 2; } }, { 0x2c00, 0xfc00, [](P) -> u32 { util::stream_format(stream, "bgts %04x", (pc + 2 + off10(opcode)) & 0xffff); return 2; } }, @@ -44,14 +49,14 @@ const ks0164_disassembler::instruction ks0164_disassembler::instructions[] { { 0x3800, 0xfc00, [](P) -> u32 { util::stream_format(stream, "blts %04x", (pc + 2 + off10(opcode)) & 0xffff); return 2; } }, { 0x3c00, 0xfc00, [](P) -> u32 { util::stream_format(stream, "bra %04x", (pc + 2 + off10(opcode)) & 0xffff); return 2; } }, - { 0x4000, 0xf800, [](P) -> u32 { util::stream_format(stream, "%s += %02x", regs[(opcode >> 8) & 7], opcode & 0xff); return 2; } }, - { 0x4800, 0xf800, [](P) -> u32 { util::stream_format(stream, "%s -= %02x", regs[(opcode >> 8) & 7], opcode & 0xff); return 2; } }, - { 0x5000, 0xf800, [](P) -> u32 { util::stream_format(stream, "cmp %s, %02x", regs[(opcode >> 8) & 7], opcode & 0xff); return 2; } }, - { 0x5800, 0xf800, [](P) -> u32 { util::stream_format(stream, "%s &= %02x", regs[(opcode >> 8) & 7], opcode & 0xff); return 2; } }, - { 0x6000, 0xf800, [](P) -> u32 { util::stream_format(stream, "%s |= %02x", regs[(opcode >> 8) & 7], opcode & 0xff); return 2; } }, - { 0x6800, 0xf800, [](P) -> u32 { util::stream_format(stream, "%s ?5 %02x", regs[(opcode >> 8) & 7], opcode & 0xff); return 2; } }, - { 0x7000, 0xf800, [](P) -> u32 { util::stream_format(stream, "%s = %02x", regs[(opcode >> 8) & 7], opcode & 0xff); return 2; } }, - { 0x7800, 0xf800, [](P) -> u32 { util::stream_format(stream, "%s *= %02x", regs[(opcode >> 8) & 7], opcode & 0xff); return 2; } }, + { 0x4000, 0xf800, [](P) -> u32 { util::stream_format(stream, "%s += %s", regs[(opcode >> 8) & 7], imm8(opcode)); return 2; } }, + { 0x4800, 0xf800, [](P) -> u32 { util::stream_format(stream, "%s -= %s", regs[(opcode >> 8) & 7], imm8(opcode)); return 2; } }, + { 0x5000, 0xf800, [](P) -> u32 { util::stream_format(stream, "cmp %s, %s", regs[(opcode >> 8) & 7], imm8(opcode)); return 2; } }, + { 0x5800, 0xf800, [](P) -> u32 { util::stream_format(stream, "%s &= %s", regs[(opcode >> 8) & 7], imm8(opcode)); return 2; } }, + { 0x6000, 0xf800, [](P) -> u32 { util::stream_format(stream, "%s |= %s", regs[(opcode >> 8) & 7], imm8(opcode)); return 2; } }, + { 0x6800, 0xf800, [](P) -> u32 { util::stream_format(stream, "%s ^= %s", regs[(opcode >> 8) & 7], imm8(opcode)); return 2; } }, + { 0x7000, 0xf800, [](P) -> u32 { util::stream_format(stream, "%s = %s", regs[(opcode >> 8) & 7], imm8(opcode)); return 2; } }, + { 0x7800, 0xf800, [](P) -> u32 { util::stream_format(stream, "%s *= %s", regs[(opcode >> 8) & 7], imm8(opcode)); return 2; } }, { 0x8004, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s += %s.bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, { 0x8084, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s += %s.bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, @@ -68,9 +73,9 @@ const ks0164_disassembler::instruction ks0164_disassembler::instructions[] { { 0xa004, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s |= %s.bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, { 0xa084, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s |= %s.bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, { 0xa00c, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s |= %s", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, - { 0xa804, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s ?5 %s.bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, - { 0xa884, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s ?5 %s.bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, - { 0xa80c, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s ?5 %s", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, + { 0xa804, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s ^= %s.bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, + { 0xa884, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s ^= %s.bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, + { 0xa80c, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s ^= %s", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, { 0xb004, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s = %s.bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, { 0xb084, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s = %s.bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, { 0xb00c, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s = %s", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, @@ -88,8 +93,8 @@ const ks0164_disassembler::instruction ks0164_disassembler::instructions[] { { 0x987d, 0xf8ff, [](P) -> u32 { u16 imm = opcodes.r16(pc+2); util::stream_format(stream, "%s &= %04x", regs[(opcode >> 8) & 7], imm); return 4; } }, { 0xa075, 0xf8ff, [](P) -> u32 { u16 imm = opcodes.r16(pc+2); util::stream_format(stream, "%s |= %02x", regs[(opcode >> 8) & 7], imm); return 4; } }, { 0xa07d, 0xf8ff, [](P) -> u32 { u16 imm = opcodes.r16(pc+2); util::stream_format(stream, "%s |= %04x", regs[(opcode >> 8) & 7], imm); return 4; } }, - { 0xa875, 0xf8ff, [](P) -> u32 { u16 imm = opcodes.r16(pc+2); util::stream_format(stream, "%s ?5 %02x", regs[(opcode >> 8) & 7], imm); return 4; } }, - { 0xa87d, 0xf8ff, [](P) -> u32 { u16 imm = opcodes.r16(pc+2); util::stream_format(stream, "%s ?5 %04x", regs[(opcode >> 8) & 7], imm); return 4; } }, + { 0xa875, 0xf8ff, [](P) -> u32 { u16 imm = opcodes.r16(pc+2); util::stream_format(stream, "%s ^= %02x", regs[(opcode >> 8) & 7], imm); return 4; } }, + { 0xa87d, 0xf8ff, [](P) -> u32 { u16 imm = opcodes.r16(pc+2); util::stream_format(stream, "%s ^= %04x", regs[(opcode >> 8) & 7], imm); return 4; } }, { 0xb075, 0xf8ff, [](P) -> u32 { u16 imm = opcodes.r16(pc+2); util::stream_format(stream, "%s = %02x", regs[(opcode >> 8) & 7], imm); return 4; } }, { 0xb07d, 0xf8ff, [](P) -> u32 { u16 imm = opcodes.r16(pc+2); util::stream_format(stream, "%s = %04x", regs[(opcode >> 8) & 7], imm); return 4; } }, { 0xb875, 0xf8ff, [](P) -> u32 { u16 imm = opcodes.r16(pc+2); util::stream_format(stream, "%s *u= %02x", regs[(opcode >> 8) & 7], imm); return 4; } }, @@ -111,9 +116,9 @@ const ks0164_disassembler::instruction ks0164_disassembler::instructions[] { { 0xa006, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s |= (%s).bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, { 0xa086, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s |= (%s).bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, { 0xa00e, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s |= (%s).w", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, - { 0xa806, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s ?5 (%s).bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, - { 0xa886, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s ?5 (%s).bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, - { 0xa80e, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s ?5 (%s).w", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, + { 0xa806, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s ^= (%s).bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, + { 0xa886, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s ^= (%s).bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, + { 0xa80e, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s ^= (%s).w", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, { 0xb006, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s = (%s).bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, { 0xb086, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s = (%s).bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, { 0xb00e, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s = (%s).w", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, @@ -136,9 +141,9 @@ const ks0164_disassembler::instruction ks0164_disassembler::instructions[] { { 0xa077, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s |= (%04x).bu", regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } }, { 0xa0f7, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s |= (%04x).bs", regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } }, { 0xa07f, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s |= (%04x).w", regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } }, - { 0xa877, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s ?5 (%04x).bu", regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } }, - { 0xa8f7, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s ?5 (%04x).bs", regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } }, - { 0xa87f, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s ?5 (%04x).w", regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } }, + { 0xa877, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s ^= (%04x).bu", regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } }, + { 0xa8f7, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s ^= (%04x).bs", regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } }, + { 0xa87f, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s ^= (%04x).w", regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } }, { 0xb077, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s = (%04x).bu", regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } }, { 0xb0f7, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s = (%04x).bs", regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } }, { 0xb07f, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s = (%04x).w", regs[(opcode >> 8) & 7], opcodes.r16(pc+2)); return 4; } }, @@ -161,9 +166,9 @@ const ks0164_disassembler::instruction ks0164_disassembler::instructions[] { { 0xa007, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s |= (%s%s).bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } }, { 0xa087, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s |= (%s%s).bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } }, { 0xa00f, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s |= (%s%s).w", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } }, - { 0xa807, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s ?5 (%s%s).bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } }, - { 0xa887, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s ?5 (%s%s).bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } }, - { 0xa80f, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s ?5 (%s%s).w", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } }, + { 0xa807, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s ^= (%s%s).bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } }, + { 0xa887, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s ^= (%s%s).bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } }, + { 0xa80f, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s ^= (%s%s).w", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } }, { 0xb007, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s = (%s%s).bu", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } }, { 0xb087, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s = (%s%s).bs", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } }, { 0xb00f, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s = (%s%s).w", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], off16(opcodes.r16(pc+2))); return 4; } }, @@ -188,9 +193,9 @@ const ks0164_disassembler::instruction ks0164_disassembler::instructions[] { { 0xd088, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s = maxs(%s, %04x)", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], opcodes.r16(pc+2)); return 4; } }, { 0xd888, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s = mins(%s, %04x)", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], opcodes.r16(pc+2)); return 4; } }, { 0xd001, 0xffff, [](P) -> u32 { util::stream_format(stream, "jmp %04x", opcodes.r16(pc+2)); return 4; } }, - { 0xd002, 0xffff, [](P) -> u32 { util::stream_format(stream, "jsr %04x", opcodes.r16(pc+2)); return 4; } }, - { 0xd003, 0xffff, [](P) -> u32 { util::stream_format(stream, "rts"); return 2; } }, - { 0xd004, 0xffff, [](P) -> u32 { util::stream_format(stream, "rti"); return 2; } }, + { 0xd002, 0xffff, [](P) -> u32 { util::stream_format(stream, "jsr %04x", opcodes.r16(pc+2)); return 4 | STEP_OVER; } }, + { 0xd003, 0xffff, [](P) -> u32 { util::stream_format(stream, "rts"); return 2 | STEP_OUT; } }, + { 0xd004, 0xffff, [](P) -> u32 { util::stream_format(stream, "rti"); return 2 | STEP_OUT; } }, { 0xd005, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s = ~%s", regs[(opcode >> 8) & 7], regs[(opcode >> 8) & 7]); return 2; } }, { 0xd085, 0xf8ff, [](P) -> u32 { util::stream_format(stream, "%s = -%s", regs[(opcode >> 8) & 7], regs[(opcode >> 8) & 7]); return 2; } }, @@ -225,16 +230,6 @@ offs_t ks0164_disassembler::disassemble(std::ostream &stream, offs_t pc, const d for(u32 i=0;; i++) if((opcode & instructions[i].mask) == instructions[i].value) - return instructions[i].cb(stream, opcode, opcodes, pc); - - abort(); - -#if 0 - } else if((opcode & 0xf80f) == 0xc800) // c808? - util::stream_format(stream, "store.w -(%s), %s", regs[(opcode >> 4) & 7], regs[(opcode >> 7) & 7]); - - else if( (opcode & 0xf88f) == 0xc00a) - util::stream_format(stream, "load.w %s, (%s)+ ?2", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); - -#endif + return instructions[i].cb(stream, opcode, opcodes, pc) | SUPPORTED; + return 0; } diff --git a/src/devices/cpu/ks0164/ks0164d.h b/src/devices/cpu/ks0164/ks0164d.h index 4383fbd7388..7f817ab8ba3 100644 --- a/src/devices/cpu/ks0164/ks0164d.h +++ b/src/devices/cpu/ks0164/ks0164d.h @@ -1,3 +1,4 @@ + // license:BSD-3-Clause // copyright-holders:Olivier Galibert, David Carne @@ -28,6 +29,7 @@ private: static const char *const regs[8]; static s32 off10(u32 opcode); + static std::string imm8(s8 dt); static std::string off16(s16 dt); }; diff --git a/src/devices/cpu/xavix2/xavix2.h b/src/devices/cpu/xavix2/xavix2.h index 8c6153441ed..099b7e4a27e 100644 --- a/src/devices/cpu/xavix2/xavix2.h +++ b/src/devices/cpu/xavix2/xavix2.h @@ -117,7 +117,7 @@ protected: return v1; } else if(shift < 32) { u32 r = v1 << shift; - u32 f = v1 ? v1 & 0x80000000 ? F_N : 0 : F_Z; + u32 f = r ? r & 0x80000000 ? F_N : 0 : F_Z; if(v1 & (1 << (32-shift))) f |= F_C; m_hr[4] = (m_hr[4] & ~F_MASK) | f; @@ -137,7 +137,7 @@ protected: return v1; } else if(shift < 32) { u32 r = v1 >> shift; - u32 f = v1 ? 0 : F_Z; + u32 f = r ? 0 : F_Z; if(v1 & (1 << (shift - 1))) f |= F_C; m_hr[4] = (m_hr[4] & ~F_MASK) | f; @@ -157,7 +157,7 @@ protected: return v1; } else if(shift < 32) { u32 r = static_cast(v1) >> shift; - u32 f = v1 ? v1 & 0x80000000 ? F_N : 0 : F_Z; + u32 f = r ? r & 0x80000000 ? F_N : 0 : F_Z; if(v1 & (1 << (shift - 1))) f |= F_C; m_hr[4] = (m_hr[4] & ~F_MASK) | f; diff --git a/src/mame/drivers/dgpix.cpp b/src/mame/drivers/dgpix.cpp index 4b4ff59f6cd..5214a49169a 100644 --- a/src/mame/drivers/dgpix.cpp +++ b/src/mame/drivers/dgpix.cpp @@ -167,7 +167,9 @@ public: m_flash(*this, "flash"), m_maincpu(*this, "maincpu"), m_soundcpu(*this, "soundcpu"), - m_vblank(*this, "VBLANK") + m_vblank(*this, "VBLANK"), + m_sndrom(*this, "soundcpu"), + m_sndrombank(*this, "sndrombank") { } void dgpix(machine_config &config); @@ -190,6 +192,8 @@ private: required_device m_maincpu; required_device m_soundcpu; required_ioport m_vblank; + required_region_ptr m_sndrom; + required_memory_bank m_sndrombank; std::unique_ptr m_vram; int m_vbuffer; @@ -197,6 +201,8 @@ private: int m_old_vbuf; u32 m_flash_cmd; s32 m_first_offset; + u16 m_sndrombank_val; + u16 m_sndrombank_mask; u32 flash_r(offs_t offset); void flash_w(offs_t offset, u32 data, u32 mem_mask = ~0); @@ -210,8 +216,21 @@ private: void mem_map(address_map &map); void io_map(address_map &map); void snd_map(address_map &map); + u16 snd_rom_bank_r(); + void snd_rom_bank_w(offs_t, u16 data, u16 mem_mask); }; +u16 dgpix_state::snd_rom_bank_r() +{ + return m_sndrombank->entry(); +} + +void dgpix_state::snd_rom_bank_w(offs_t, u16 data, u16 mem_mask) +{ + COMBINE_DATA(&m_sndrombank_val); + logerror("bank4000 = %04x\n", m_sndrombank_val); + m_sndrombank->set_entry(m_sndrombank_val & m_sndrombank_mask); +} u32 dgpix_state::flash_r(offs_t offset) { @@ -348,7 +367,11 @@ void dgpix_state::io_map(address_map &map) void dgpix_state::snd_map(address_map &map) { - map(0x0000, 0x7fff).rom(); + map(0x0000, 0x3fff).rom(); + map(0x0020, 0x007f).unmaprw(); + map(0x0062, 0x0063).rw(FUNC(dgpix_state::snd_rom_bank_r), FUNC(dgpix_state::snd_rom_bank_w)); + map(0x4000, 0x7fff).bankr("sndrombank"); + map(0xe000, 0xffff).ram(); } static INPUT_PORTS_START( dgpix ) @@ -415,6 +438,11 @@ void dgpix_state::machine_start() save_item(NAME(m_flash_cmd)); save_item(NAME(m_first_offset)); save_item(NAME(m_old_vbuf)); + save_item(NAME(m_sndrombank_val)); + + m_sndrombank->configure_entries(0, m_sndrom.bytes()/0x4000, m_sndrom, 0x4000); + m_sndrombank->set_entry(0); + m_sndrombank_mask = m_sndrom.bytes()/0x4000 - 1; } void dgpix_state::machine_reset() @@ -423,6 +451,9 @@ void dgpix_state::machine_reset() m_flash_cmd = 0; m_first_offset = -1; m_old_vbuf = 3; + + m_sndrombank_val = 0; + m_sndrombank->set_entry(0); } -- cgit v1.2.3