diff options
| author | 2023-09-30 17:45:47 +0900 | |
|---|---|---|
| committer | 2023-09-30 10:45:47 +0200 | |
| commit | 6f3e2c6b56f9f7ec07e27157bc0d3673b6f21abb (patch) | |
| tree | 49750bf9dddf156769065580920615bc61bc69d5 /src/devices | |
| parent | fdfe65ce18ecfdf54547f7be7302a89b330cf083 (diff) | |
dgpix: Use intelfsh + improvements to sound emulation (#11582)
* sound/ks0164: Attempt to fix audio looping issues
* cpu/ks0164: swap bges and bles (fixes sound effects), fix some disasm issues, document a new opcode
* misc/dgpix: Refactor to use intelfsh, add controls for btplay2k and letsdnce, add sound banking for BMkey PCB
Diffstat (limited to 'src/devices')
| -rw-r--r-- | src/devices/cpu/ks0164/ks0164.cpp | 48 | ||||
| -rw-r--r-- | src/devices/cpu/ks0164/ks0164d.cpp | 17 | ||||
| -rw-r--r-- | src/devices/sound/ks0164.cpp | 34 | ||||
| -rw-r--r-- | src/devices/sound/ks0164.h | 2 |
4 files changed, 80 insertions, 21 deletions
diff --git a/src/devices/cpu/ks0164/ks0164.cpp b/src/devices/cpu/ks0164/ks0164.cpp index b66080ba06b..194823474d0 100644 --- a/src/devices/cpu/ks0164/ks0164.cpp +++ b/src/devices/cpu/ks0164/ks0164.cpp @@ -253,8 +253,8 @@ void ks0164_cpu_device::execute_run() 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 0xc: 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 0xd: 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 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: default: cond = true; break; } @@ -462,7 +462,7 @@ void ks0164_cpu_device::execute_run() case 0x1b: { switch((opcode >> 12) & 3) { case 0: { - // Push all registers + // Pop all registers // 1100 .... .... .011 m_r[0] = m_program.read_word(m_r[R_SP] + 6); @@ -550,7 +550,7 @@ void ks0164_cpu_device::execute_run() case 2: { // Bit clear in register - // 1110 .rrr bbbb .001 + // 1110 .rrr bbbb .100 if(m_r[(opcode >> 8) & 7] & (1 << ((opcode >> 4) & 0xf))) { m_r[(opcode >> 8) & 7] &= ~(1 << ((opcode >> 4) & 0xf)); m_r[R_PSW] &= ~F_Z; @@ -561,6 +561,7 @@ void ks0164_cpu_device::execute_run() case 3: { // Decrement and branch + // 1111 .rrr .... .100 int r = (opcode >> 8) & 7; u16 a = m_program_cache.read_word(m_r[R_PC]); m_r[R_PC] += 2; @@ -643,7 +644,44 @@ void ks0164_cpu_device::execute_run() case 0x1e: { switch((opcode >> 12) & 3) { case 0: { - unk(opcode); + // Rotate without carry? + // 1100 drrr nnnn .110 + /* + From btplay2k flash.u22: + Surrounding code gives some context to usage here? + opcode is sandwiched between other shift/rotate commands + 6E2C: 7010 r0 = 10 + 6E2E: 8817 0001 r0 -= (r1 + 1).bu + 6E32: 0406 beq 6e3a + 6E34: CA1C r2 >>= 1 + 6E36: F004 6E34 dbra r0, 6e34 + ... + 6E52: B017 0001 r0 = (r1 + 1).bu + 6E56: CA1E ?ca1e + 6E58: F004 6E56 dbra r0, 6e56 + */ + + 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) | (v1 << (16 - 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) | (v1 >> (16 - 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; } diff --git a/src/devices/cpu/ks0164/ks0164d.cpp b/src/devices/cpu/ks0164/ks0164d.cpp index 21e60bd97f7..192dc7d1221 100644 --- a/src/devices/cpu/ks0164/ks0164d.cpp +++ b/src/devices/cpu/ks0164/ks0164d.cpp @@ -39,8 +39,8 @@ const ks0164_disassembler::instruction ks0164_disassembler::instructions[] { { 0x2400, 0xfc00, [](P) -> u32 { util::stream_format(stream, "bgtu %04x", (pc + 2 + util::sext(opcode, 10)) & 0xffff); return 2 | STEP_COND; } }, { 0x2800, 0xfc00, [](P) -> u32 { util::stream_format(stream, "bleu %04x", (pc + 2 + util::sext(opcode, 10)) & 0xffff); return 2 | STEP_COND; } }, { 0x2c00, 0xfc00, [](P) -> u32 { util::stream_format(stream, "bgts %04x", (pc + 2 + util::sext(opcode, 10)) & 0xffff); return 2 | STEP_COND; } }, - { 0x3000, 0xfc00, [](P) -> u32 { util::stream_format(stream, "bles %04x", (pc + 2 + util::sext(opcode, 10)) & 0xffff); return 2 | STEP_COND; } }, - { 0x3400, 0xfc00, [](P) -> u32 { util::stream_format(stream, "bges %04x", (pc + 2 + util::sext(opcode, 10)) & 0xffff); return 2 | STEP_COND; } }, + { 0x3000, 0xfc00, [](P) -> u32 { util::stream_format(stream, "bges %04x", (pc + 2 + util::sext(opcode, 10)) & 0xffff); return 2 | STEP_COND; } }, + { 0x3400, 0xfc00, [](P) -> u32 { util::stream_format(stream, "bles %04x", (pc + 2 + util::sext(opcode, 10)) & 0xffff); return 2 | STEP_COND; } }, { 0x3800, 0xfc00, [](P) -> u32 { util::stream_format(stream, "blts %04x", (pc + 2 + util::sext(opcode, 10)) & 0xffff); return 2 | STEP_COND; } }, { 0x3c00, 0xfc00, [](P) -> u32 { util::stream_format(stream, "bra %04x", (pc + 2 + util::sext(opcode, 10)) & 0xffff); return 2; } }, @@ -177,11 +177,14 @@ const ks0164_disassembler::instruction ks0164_disassembler::instructions[] { { 0xc008, 0xf88f, [](P) -> u32 { util::stream_format(stream, "(%s)+.w = %s", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, { 0xc00a, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s = (%s)+.w", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7]); return 2; } }, - { 0xc00c, 0xf80f, [](P) -> u32 { util::stream_format(stream, "%s <<= %x", regs[(opcode >> 8) & 7], (opcode >> 4) & 0xf); return 2; } }, - { 0xc80c, 0xf80f, [](P) -> u32 { util::stream_format(stream, "%s >>= %x", regs[(opcode >> 8) & 7], (opcode >> 4) & 0xf); return 2; } }, - { 0xc80d, 0xf80f, [](P) -> u32 { util::stream_format(stream, "%s >>s= %x", regs[(opcode >> 8) & 7], (opcode >> 4) & 0xf); return 2; } }, - { 0xc00f, 0xf80f, [](P) -> u32 { util::stream_format(stream, "%s <<c= %x", regs[(opcode >> 8) & 7], (opcode >> 4) & 0xf); return 2; } }, - { 0xc80f, 0xf80f, [](P) -> u32 { util::stream_format(stream, "%s >>c= %x", regs[(opcode >> 8) & 7], (opcode >> 4) & 0xf); return 2; } }, + { 0xc004, 0xf807, [](P) -> u32 { util::stream_format(stream, "%s <<= %x", regs[(opcode >> 8) & 7], (opcode >> 4) & 0xf); return 2; } }, // are these with bit 3 set really all the same? + { 0xc804, 0xf807, [](P) -> u32 { util::stream_format(stream, "%s >>= %x", regs[(opcode >> 8) & 7], (opcode >> 4) & 0xf); return 2; } }, + { 0xc005, 0xf807, [](P) -> u32 { util::stream_format(stream, "%s >>s= %x", regs[(opcode >> 8) & 7], (opcode >> 4) & 0xf); return 2; } }, + { 0xc805, 0xf807, [](P) -> u32 { util::stream_format(stream, "%s >>s= %x", regs[(opcode >> 8) & 7], (opcode >> 4) & 0xf); return 2; } }, + { 0xc006, 0xf807, [](P) -> u32 { util::stream_format(stream, "%s <<<= %x", regs[(opcode >> 8) & 7], (opcode >> 4) & 0xf); return 2; } }, + { 0xc806, 0xf807, [](P) -> u32 { util::stream_format(stream, "%s >>>= %x", regs[(opcode >> 8) & 7], (opcode >> 4) & 0xf); return 2; } }, + { 0xc007, 0xf807, [](P) -> u32 { util::stream_format(stream, "%s <<c= %x", regs[(opcode >> 8) & 7], (opcode >> 4) & 0xf); return 2; } }, + { 0xc807, 0xf807, [](P) -> u32 { util::stream_format(stream, "%s >>c= %x", regs[(opcode >> 8) & 7], (opcode >> 4) & 0xf); return 2; } }, { 0xd008, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s = maxu(%s, %04x)", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], opcodes.r16(pc+2)); return 4; } }, { 0xd808, 0xf88f, [](P) -> u32 { util::stream_format(stream, "%s = minu(%s, %04x)", regs[(opcode >> 8) & 7], regs[(opcode >> 4) & 7], opcodes.r16(pc+2)); return 4; } }, diff --git a/src/devices/sound/ks0164.cpp b/src/devices/sound/ks0164.cpp index 42cd4775726..6fe7e6d25bc 100644 --- a/src/devices/sound/ks0164.cpp +++ b/src/devices/sound/ks0164.cpp @@ -54,7 +54,8 @@ ks0164_device::ks0164_device(const machine_config &mconfig, const char *tag, dev m_midi_tx(*this), m_mem_region(*this, DEVICE_SELF), m_cpu(*this, "cpu"), - m_mem_config("mem", ENDIANNESS_BIG, 16, 23) + m_mem_config("mem", ENDIANNESS_BIG, 16, 23), + m_notif_rom_space() { } @@ -89,6 +90,16 @@ void ks0164_device::device_start() space().install_rom(0, rend, ((1 << 23) - 1) ^ rmask, m_mem_region->base()); } + m_notif_rom_space = space().add_change_notifier([this] (read_or_write mode) { + // HACK: If something external changes the ROM space after initial load then reset the CPU because the program code also changed (used by BMkey ROM PCBs) + for(int voice = 0; voice < 0x20; voice++) { + // Disable all voices + m_sregs[voice][0] &= ~1; + } + + m_cpu->pulse_input_line(INPUT_LINE_RESET, attotime::zero); + }); + m_stream = stream_alloc(0, 2, clock()/3/2/2/32); space().cache(m_mem_cache); m_timer = timer_alloc(FUNC(ks0164_device::irq_timer_tick), this); @@ -308,7 +319,7 @@ void ks0164_device::bank2_select_w(offs_t, u16 data, u16 mem_mask) u16 ks0164_device::voice_r(offs_t offset) { m_stream->update(); - logerror("voice read %02x.%02x -> %04x (%04x)\n", m_voice_select & 0x1f, offset, m_sregs[m_voice_select & 0x1f][offset], m_cpu->pc()); + // logerror("voice read %02x.%02x -> %04x (%04x)\n", m_voice_select & 0x1f, offset, m_sregs[m_voice_select & 0x1f][offset], m_cpu->pc()); return m_sregs[m_voice_select & 0x1f][offset]; } @@ -321,13 +332,14 @@ void ks0164_device::voice_w(offs_t offset, u16 data, u16 mem_mask) if(m_cpu->pc() < 0x5f94 || m_cpu->pc() > 0x5fc0) logerror("voice %02x.%02x = %04x @ %04x (%04x)\n", m_voice_select & 0x1f, offset, m_sregs[m_voice_select & 0x1f][offset], mem_mask, m_cpu->pc()); if(offset == 0 && (data & 1) && !(old & 1)) - logerror("keyon %02x mode=%04x (%s %c %c %c) cur=%02x%04x.%04x loop=%02x%04x.%04x end=%02x%04x.%04x pitch=%02x.%03x 10=%02x/%02x:%02x/%02x 14=%03x/%03x:%03x/%03x 18=%04x/%04x c=%04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n", + logerror("keyon %02x mode=%04x (%s %c %c %c %c) cur=%02x%04x.%04x loop=%02x%04x.%04x end=%02x%04x.%04x pitch=%02x.%03x 10=%02x/%02x:%02x/%02x 14=%03x/%03x:%03x/%03x 18=%04x/%04x c=%04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n", m_voice_select, m_sregs[m_voice_select & 0x1f][0x00], - m_sregs[m_voice_select & 0x1f][0x00] & 0x8000 ? " 8" : "16", - m_sregs[m_voice_select & 0x1f][0x00] & 0x0400 ? 'c' : 'l', + m_sregs[m_voice_select & 0x1f][0x00] & 0x8000 ? " 8" : "16", // 8-bit/16-bit samples + m_sregs[m_voice_select & 0x1f][0x00] & 0x0400 ? 'c' : 'l', // compressed/linear samples + m_sregs[m_voice_select & 0x1f][0x00] & 0x0010 ? 'r' : '-', // loop m_sregs[m_voice_select & 0x1f][0x00] & 0x0008 ? '3' : '-', m_sregs[m_voice_select & 0x1f][0x00] & 0x0004 ? '2' : '-', @@ -423,7 +435,7 @@ u8 ks0164_device::voice_select_r() void ks0164_device::voice_select_w(u8 data) { m_voice_select = data; - logerror("voice_select = %02x (%04x)\n", m_voice_select, m_cpu->pc()); + // logerror("voice_select = %02x (%04x)\n", m_voice_select, m_cpu->pc()); } void ks0164_device::cpu_map(address_map &map) @@ -492,9 +504,13 @@ void ks0164_device::sound_stream_update(sound_stream &stream, std::vector<read_s current += step; u64 end = (u64(regs[0xd]) << 32) | (u64(regs[0xe]) << 16) | regs[0xf]; if(current >= end) { - // Is there a loop enabled flag? - u64 loop = (u64(regs[9]) << 32) | (regs[0xa] << 16) | regs[0xb]; - current = current - end + loop; + // guessed, 1d26 in btplay2k flash.u22 seems to check this flag for something similar to looping but no games use it + if (regs[0] & 0x10) { + u64 loop = (u64(regs[9]) << 32) | (regs[0xa] << 16) | regs[0xb]; + current = current - end + loop; + } else { + regs[0] = ~1; + } } regs[1] = current >> 32; regs[2] = current >> 16; diff --git a/src/devices/sound/ks0164.h b/src/devices/sound/ks0164.h index 3f4a1f30cb7..ae7680c91c9 100644 --- a/src/devices/sound/ks0164.h +++ b/src/devices/sound/ks0164.h @@ -74,6 +74,8 @@ private: u8 m_irqen_76, m_irqen_77; bool m_timer_interrupt; + util::notifier_subscription m_notif_rom_space; + void cpu_map(address_map &map); u16 vec_r(offs_t offset, u16 mem_mask); |
