summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices
diff options
context:
space:
mode:
author 987123879113 <63495610+987123879113@users.noreply.github.com>2023-09-30 17:45:47 +0900
committer GitHub <noreply@github.com>2023-09-30 10:45:47 +0200
commit6f3e2c6b56f9f7ec07e27157bc0d3673b6f21abb (patch)
tree49750bf9dddf156769065580920615bc61bc69d5 /src/devices
parentfdfe65ce18ecfdf54547f7be7302a89b330cf083 (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.cpp48
-rw-r--r--src/devices/cpu/ks0164/ks0164d.cpp17
-rw-r--r--src/devices/sound/ks0164.cpp34
-rw-r--r--src/devices/sound/ks0164.h2
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);