summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/swp30.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound/swp30.cpp')
-rw-r--r--src/devices/sound/swp30.cpp368
1 files changed, 312 insertions, 56 deletions
diff --git a/src/devices/sound/swp30.cpp b/src/devices/sound/swp30.cpp
index e1107329d2e..69d17c85ea7 100644
--- a/src/devices/sound/swp30.cpp
+++ b/src/devices/sound/swp30.cpp
@@ -33,13 +33,53 @@
#if 0
// 929a6: 00 2e 30 32 33 34 35 36 37 3a 3c
+// 3fb80: list of reverb times as text, 4chars/entry
+
+// 84268: 7c 76 77 78
+// 80 79 7a 7b
+// 84 7e 7d 7f
+// 88 81 82 83
+// 8c 85 86 87
+// 91 89 8a 8b
+
+
void f_62fcc(e0, r0, e1, r1l, er5) // 8 (11/12) 1 6 84268
{
+ // 929b1
+ // 00 00 00 00 00 00
+ // 38 3c 40 43 49 3b
+ // 46 4a 4e 51 55 43
+ // 3e 3f 41 43 48 3c
+ // 4b 51 59 5c 00 4e
+
+ // 92560
+ // 00 01 12 1c 23 28 2d 30 34 37 39 3c 3e 40 42 43
+ // 45 46 48 49 4a 4c 4d 4e 4f 50 51 52 53 54 54 55
+ // 56 57 58 58 59 5a 5a 5b 5c 5c 5d 5d 5e 5e 5f 60
+ // 60 61 61 63 66 68 69 6b 6d 6e 70 71 72 75 77 79
+ // 7b 7c 7e 7f 81 82
+
l8 = 929b1 + 6*e1;
r6 = r1l == 6 ? 0x15 : r1l == 4 ? 0xd : r1l == 3 ? 0x9 : e1;
- f_64a34(0x01, 01, t929a6[e0].b << 8, 0x40, 0, er5 + 2*r6); // 0101 3700 40 0 84292
+ f_64a34(0x01, 01, t929a6[e0].b << 8, 0x40, 0, er5 + 2*r6); // 0101 3700 40 0 84292 - writes 1ff2/1ff1
+ pr0 = r0;
+ for(r3h=0; r3h<6; r3h++) {
+ r0l = *l8++;
+ if(r0l) {
+ r6 = clamp(r0l + l92560[pr0] - 0x38, 0, 0xff);
+ r6, e6 = l925a6[r6].l; // 13d2 5368
+ } else
+ r6, e6 = 0, 0;
+
+ }
+ er0 = *er5.w++;
+ g214ca4[0x10 + er0].w = e6;
+ lc = &g214ca4[0x20 + er0].w
+ er0 = float(r6);
}
+// 80914 = convert unsigned short to float
+
void write_regs(r0b, er1) // 728c0, r0=3, er1=84292
{
if(!g214c98)
@@ -102,15 +142,35 @@ void swp30_device::device_start()
void swp30_device::device_reset()
{
+ m_keyon_mask = 0;
+ m_active_mask = 0;
+
memset(m_pre_size, 0, sizeof(m_pre_size));
memset(m_post_size, 0, sizeof(m_post_size));
memset(m_address, 0, sizeof(m_address));
+
+ memset(m_sample_pos, 0, sizeof(m_sample_pos));
+ memset(m_sample_history, 0, sizeof(m_sample_history));
+
memset(m_volume, 0, sizeof(m_volume));
memset(m_freq, 0, sizeof(m_freq));
memset(m_pan, 0, sizeof(m_pan));
-
- m_keyon_mask = 0;
- m_active_mask = 0;
+ memset(m_lpf_cutoff, 0, sizeof(m_lpf_cutoff));
+ memset(m_lpf_reso, 0, sizeof(m_lpf_reso));
+ memset(m_hpf_cutoff, 0, sizeof(m_hpf_cutoff));
+ memset(m_eq_filter, 0, sizeof(m_eq_filter));
+
+ memset(m_variation_delay, 0, sizeof(m_variation_delay));
+ memset(m_variation_fb_level, 0, sizeof(m_variation_fb_level));
+ memset(m_variation_final_level, 0, sizeof(m_variation_final_level));
+ memset(m_variation_high_damp, 0, sizeof(m_variation_high_damp));
+ memset(m_variation_inv_high_damp, 0, sizeof(m_variation_inv_high_damp));
+
+ memset(m_insertion_delay, 0, sizeof(m_insertion_delay));
+ memset(m_insertion_fb_level, 0, sizeof(m_insertion_fb_level));
+ memset(m_insertion_final_level, 0, sizeof(m_insertion_final_level));
+ memset(m_insertion_high_damp, 0, sizeof(m_insertion_high_damp));
+ memset(m_insertion_inv_high_damp, 0, sizeof(m_insertion_inv_high_damp));
}
void swp30_device::rom_bank_updated()
@@ -121,17 +181,75 @@ void swp30_device::rom_bank_updated()
void swp30_device::map(address_map &map)
{
map(0x0000, 0x1fff).rw(FUNC(swp30_device::snd_r), FUNC(swp30_device::snd_w));
+ map(0x0000, 0x0001).select(0x1f80).rw(FUNC(swp30_device::lpf_cutoff_r), FUNC(swp30_device::lpf_cutoff_w));
+ map(0x0004, 0x0005).select(0x1f80).rw(FUNC(swp30_device::hpf_cutoff_r), FUNC(swp30_device::hpf_cutoff_w));
+ map(0x0008, 0x0009).select(0x1f80).rw(FUNC(swp30_device::lpf_reso_r), FUNC(swp30_device::lpf_reso_w));
map(0x0012, 0x0013).select(0x1f80).rw(FUNC(swp30_device::volume_r), FUNC(swp30_device::volume_w));
map(0x0022, 0x0023).select(0x1f80).rw(FUNC(swp30_device::freq_r), FUNC(swp30_device::freq_w));
map(0x0024, 0x0027).select(0x1f80).rw(FUNC(swp30_device::pre_size_r), FUNC(swp30_device::pre_size_w));
map(0x0028, 0x002b).select(0x1f80).rw(FUNC(swp30_device::post_size_r), FUNC(swp30_device::post_size_w));
map(0x002c, 0x002f).select(0x1f80).rw(FUNC(swp30_device::address_r), FUNC(swp30_device::address_w));
+ map(0x0040, 0x0041).select(0x1f80).rw(&swp30_device::eq_filter_r<0, 0>, "swp30_device::eq_filter_r<0, 0>", &swp30_device::eq_filter_w<0, 0>, "swp30_device::eq_filter_w<0, 0>");
+ map(0x0044, 0x0045).select(0x1f80).rw(&swp30_device::eq_filter_r<0, 1>, "swp30_device::eq_filter_r<0, 1>", &swp30_device::eq_filter_w<0, 1>, "swp30_device::eq_filter_w<0, 1>");
+ map(0x0048, 0x0049).select(0x1f80).rw(&swp30_device::eq_filter_r<0, 2>, "swp30_device::eq_filter_r<0, 2>", &swp30_device::eq_filter_w<0, 2>, "swp30_device::eq_filter_w<0, 2>");
+ map(0x004c, 0x004d).select(0x1f80).rw(&swp30_device::eq_filter_r<1, 0>, "swp30_device::eq_filter_r<1, 0>", &swp30_device::eq_filter_w<1, 0>, "swp30_device::eq_filter_w<1, 0>");
+ map(0x0050, 0x0051).select(0x1f80).rw(&swp30_device::eq_filter_r<1, 1>, "swp30_device::eq_filter_r<1, 1>", &swp30_device::eq_filter_w<1, 1>, "swp30_device::eq_filter_w<1, 1>");
+ map(0x0054, 0x0055).select(0x1f80).rw(&swp30_device::eq_filter_r<1, 2>, "swp30_device::eq_filter_r<1, 2>", &swp30_device::eq_filter_w<1, 2>, "swp30_device::eq_filter_w<1, 2>");
map(0x0064, 0x0065).select(0x1f80).rw(FUNC(swp30_device::pan_r), FUNC(swp30_device::pan_w));
map(0x031c, 0x031d). rw(FUNC(swp30_device::keyon_mask_r<3>), FUNC(swp30_device::keyon_mask_w<3>));
map(0x031e, 0x031f). rw(FUNC(swp30_device::keyon_mask_r<2>), FUNC(swp30_device::keyon_mask_w<2>));
map(0x039c, 0x039d). rw(FUNC(swp30_device::keyon_mask_r<1>), FUNC(swp30_device::keyon_mask_w<1>));
map(0x039e, 0x039f). rw(FUNC(swp30_device::keyon_mask_r<0>), FUNC(swp30_device::keyon_mask_w<0>));
map(0x041c, 0x041d). rw(FUNC(swp30_device::keyon_r), FUNC(swp30_device::keyon_w));
+
+ map(0x1060, 0x1061). rw(&swp30_device::insertion_delay_r<0, 0>, "swp30_device::insertion_delay_r<0, 0>", &swp30_device::insertion_delay_w<0, 0>, "swp30_device::insertion_delay_w<0, 0>");
+ map(0x1062, 0x1063). rw(&swp30_device::insertion_delay_r<0, 1>, "swp30_device::insertion_delay_r<0, 1>", &swp30_device::insertion_delay_w<0, 1>, "swp30_device::insertion_delay_w<0, 1>");
+ map(0x10e0, 0x10e1). rw(&swp30_device::insertion_delay_r<0, 2>, "swp30_device::insertion_delay_r<0, 2>", &swp30_device::insertion_delay_w<0, 2>, "swp30_device::insertion_delay_w<0, 2>");
+ map(0x10e2, 0x10e3). rw(&swp30_device::insertion_delay_r<0, 3>, "swp30_device::insertion_delay_r<0, 3>", &swp30_device::insertion_delay_w<0, 3>, "swp30_device::insertion_delay_w<0, 3>");
+ map(0x1152, 0x1153). rw(&swp30_device::insertion_inv_high_damp_r<0, 0>, "swp30_device::insertion_inv_high_damp_r<0, 0>", &swp30_device::insertion_inv_high_damp_w<0, 0>, "swp30_device::insertion_inv_high_damp_w<0, 0>");
+ map(0x1156, 0x1157). rw(&swp30_device::insertion_high_damp_r<0, 0>, "swp30_device::insertion_high_damp_r<0, 0>", &swp30_device::insertion_high_damp_w<0, 0>, "swp30_device::insertion_high_damp_w<0, 0>");
+ map(0x11ca, 0x11cb). rw(&swp30_device::insertion_inv_high_damp_r<0, 1>, "swp30_device::insertion_inv_high_damp_r<0, 1>", &swp30_device::insertion_inv_high_damp_w<0, 1>, "swp30_device::insertion_inv_high_damp_w<0, 1>");
+ map(0x11ce, 0x11cf). rw(&swp30_device::insertion_high_damp_r<0, 1>, "swp30_device::insertion_high_damp_r<0, 1>", &swp30_device::insertion_high_damp_w<0, 1>, "swp30_device::insertion_high_damp_w<0, 1>");
+ map(0x1242, 0x1243). rw(&swp30_device::insertion_fb_level_r<0, 0>, "swp30_device::insertion_fb_level_r<0, 0>", &swp30_device::insertion_fb_level_w<0, 0>, "swp30_device::insertion_fb_level_w<0, 0>");
+ map(0x1246, 0x1247). rw(&swp30_device::insertion_fb_level_r<0, 1>, "swp30_device::insertion_fb_level_r<0, 1>", &swp30_device::insertion_fb_level_w<0, 1>, "swp30_device::insertion_fb_level_w<0, 1>");
+ map(0x124e, 0x124f). rw(&swp30_device::insertion_fb_level_r<0, 2>, "swp30_device::insertion_fb_level_r<0, 2>", &swp30_device::insertion_fb_level_w<0, 2>, "swp30_device::insertion_fb_level_w<0, 2>");
+ map(0x12d6, 0x12d7). rw(&swp30_device::insertion_final_level_r<0, 0>, "swp30_device::insertion_final_level_r<0, 0>", &swp30_device::insertion_final_level_w<0, 0>, "swp30_device::insertion_final_level_w<0, 0>");
+ map(0x1342, 0x1343). rw(&swp30_device::insertion_final_level_r<0, 1>, "swp30_device::insertion_final_level_r<0, 1>", &swp30_device::insertion_final_level_w<0, 1>, "swp30_device::insertion_final_level_w<0, 1>");
+ map(0x1346, 0x1347). rw(&swp30_device::insertion_final_level_r<0, 2>, "swp30_device::insertion_final_level_r<0, 2>", &swp30_device::insertion_final_level_w<0, 2>, "swp30_device::insertion_final_level_w<0, 2>");
+ map(0x134a, 0x134b). rw(&swp30_device::insertion_final_level_r<0, 3>, "swp30_device::insertion_final_level_r<0, 3>", &swp30_device::insertion_final_level_w<0, 3>, "swp30_device::insertion_final_level_w<0, 3>");
+
+ map(0x1460, 0x1461). rw(&swp30_device::insertion_delay_r<1, 0>, "swp30_device::insertion_delay_r<1, 0>", &swp30_device::insertion_delay_w<1, 0>, "swp30_device::insertion_delay_w<1, 0>");
+ map(0x1462, 0x1463). rw(&swp30_device::insertion_delay_r<1, 1>, "swp30_device::insertion_delay_r<1, 1>", &swp30_device::insertion_delay_w<1, 1>, "swp30_device::insertion_delay_w<1, 1>");
+ map(0x14e0, 0x14e1). rw(&swp30_device::insertion_delay_r<1, 2>, "swp30_device::insertion_delay_r<1, 2>", &swp30_device::insertion_delay_w<1, 2>, "swp30_device::insertion_delay_w<1, 2>");
+ map(0x14e2, 0x14e3). rw(&swp30_device::insertion_delay_r<1, 3>, "swp30_device::insertion_delay_r<1, 3>", &swp30_device::insertion_delay_w<1, 3>, "swp30_device::insertion_delay_w<1, 3>");
+ map(0x1552, 0x1553). rw(&swp30_device::insertion_inv_high_damp_r<1, 0>, "swp30_device::insertion_inv_high_damp_r<1, 0>", &swp30_device::insertion_inv_high_damp_w<1, 0>, "swp30_device::insertion_inv_high_damp_w<1, 0>");
+ map(0x1556, 0x1557). rw(&swp30_device::insertion_high_damp_r<1, 0>, "swp30_device::insertion_high_damp_r<1, 0>", &swp30_device::insertion_high_damp_w<1, 0>, "swp30_device::insertion_high_damp_w<1, 0>");
+ map(0x15ca, 0x15cb). rw(&swp30_device::insertion_inv_high_damp_r<1, 1>, "swp30_device::insertion_inv_high_damp_r<1, 1>", &swp30_device::insertion_inv_high_damp_w<1, 1>, "swp30_device::insertion_inv_high_damp_w<1, 1>");
+ map(0x15ce, 0x15cf). rw(&swp30_device::insertion_high_damp_r<1, 1>, "swp30_device::insertion_high_damp_r<1, 1>", &swp30_device::insertion_high_damp_w<1, 1>, "swp30_device::insertion_high_damp_w<1, 1>");
+ map(0x1642, 0x1643). rw(&swp30_device::insertion_fb_level_r<1, 0>, "swp30_device::insertion_fb_level_r<1, 0>", &swp30_device::insertion_fb_level_w<1, 0>, "swp30_device::insertion_fb_level_w<1, 0>");
+ map(0x1646, 0x1647). rw(&swp30_device::insertion_fb_level_r<1, 1>, "swp30_device::insertion_fb_level_r<1, 1>", &swp30_device::insertion_fb_level_w<1, 1>, "swp30_device::insertion_fb_level_w<1, 1>");
+ map(0x164e, 0x164f). rw(&swp30_device::insertion_fb_level_r<1, 2>, "swp30_device::insertion_fb_level_r<1, 2>", &swp30_device::insertion_fb_level_w<1, 2>, "swp30_device::insertion_fb_level_w<1, 2>");
+ map(0x16d6, 0x16d7). rw(&swp30_device::insertion_final_level_r<1, 0>, "swp30_device::insertion_final_level_r<1, 0>", &swp30_device::insertion_final_level_w<1, 0>, "swp30_device::insertion_final_level_w<1, 0>");
+ map(0x1742, 0x1743). rw(&swp30_device::insertion_final_level_r<1, 1>, "swp30_device::insertion_final_level_r<1, 1>", &swp30_device::insertion_final_level_w<1, 1>, "swp30_device::insertion_final_level_w<1, 1>");
+ map(0x1746, 0x1747). rw(&swp30_device::insertion_final_level_r<1, 2>, "swp30_device::insertion_final_level_r<1, 2>", &swp30_device::insertion_final_level_w<1, 2>, "swp30_device::insertion_final_level_w<1, 2>");
+ map(0x174a, 0x174b). rw(&swp30_device::insertion_final_level_r<1, 3>, "swp30_device::insertion_final_level_r<1, 3>", &swp30_device::insertion_final_level_w<1, 3>, "swp30_device::insertion_final_level_w<1, 3>");
+
+ map(0x18e0, 0x18e1). rw(FUNC(swp30_device::variation_delay_r<0>), FUNC(swp30_device::variation_delay_w<0>));
+ map(0x1960, 0x1961). rw(FUNC(swp30_device::variation_delay_r<1>), FUNC(swp30_device::variation_delay_w<1>));
+ map(0x19e0, 0x19e1). rw(FUNC(swp30_device::variation_delay_r<2>), FUNC(swp30_device::variation_delay_w<2>));
+ map(0x1ae0, 0x1ae1). rw(FUNC(swp30_device::variation_delay_r<3>), FUNC(swp30_device::variation_delay_w<3>));
+ map(0x1bd6, 0x1bd7). rw(FUNC(swp30_device::variation_inv_high_damp_r<0>), FUNC(swp30_device::variation_inv_high_damp_w<0>));
+ map(0x1c46, 0x1c47). rw(FUNC(swp30_device::variation_high_damp_r<0>), FUNC(swp30_device::variation_high_damp_w<0>));
+ map(0x1c52, 0x1c53). rw(FUNC(swp30_device::variation_inv_high_damp_r<1>), FUNC(swp30_device::variation_inv_high_damp_w<1>));
+ map(0x1cc2, 0x1cc3). rw(FUNC(swp30_device::variation_high_damp_r<1>), FUNC(swp30_device::variation_high_damp_w<1>));
+ map(0x1cce, 0x1ccf). rw(FUNC(swp30_device::variation_fb_level_r<0>), FUNC(swp30_device::variation_fb_level_w<0>));
+ map(0x1cd2, 0x1cd3). rw(FUNC(swp30_device::variation_fb_level_r<1>), FUNC(swp30_device::variation_fb_level_w<1>));
+ map(0x1d46, 0x1d47). rw(FUNC(swp30_device::variation_fb_level_r<2>), FUNC(swp30_device::variation_fb_level_w<2>));
+ map(0x1f4a, 0x1f4b). rw(FUNC(swp30_device::variation_final_level_r<0>), FUNC(swp30_device::variation_final_level_w<0>));
+ map(0x1f52, 0x1f53). rw(FUNC(swp30_device::variation_final_level_r<1>), FUNC(swp30_device::variation_final_level_w<1>));
+ map(0x1f56, 0x1f57). rw(FUNC(swp30_device::variation_final_level_r<2>), FUNC(swp30_device::variation_final_level_w<2>));
+ map(0x1fc6, 0x1fc7). rw(FUNC(swp30_device::variation_final_level_r<3>), FUNC(swp30_device::variation_final_level_w<3>));
+
}
@@ -150,22 +268,77 @@ u16 swp30_device::keyon_r()
return 0;
}
+static int ncount = 0;
void swp30_device::keyon_w(u16)
{
m_stream->update();
- static int count = 0;
for(int i=0; i<64; i++) {
u64 mask = u64(1) << i;
if((m_keyon_mask & mask) && !(m_active_mask & mask) && !(m_volume[i] & 0x8000)) {
m_sample_pos[i] = -s32(m_pre_size[i] << 8);
- logerror("sample count %3d %02x %08x %08x %08x vol %04x pan %04x\n", count, i, m_pre_size[i], m_post_size[i], m_address[i], m_volume[i], m_pan[i]);
+ logerror("sample count %3d %02x %08x %08x %08x vol %04x pan %04x\n", ncount, i, m_pre_size[i], m_post_size[i], m_address[i], m_volume[i], m_pan[i]);
m_active_mask |= mask;
- count++;
+ ncount++;
}
}
m_keyon_mask = 0;
}
+u16 swp30_device::lpf_cutoff_r(offs_t offset)
+{
+ return m_lpf_cutoff[offset >> 6];
+}
+
+void swp30_device::lpf_cutoff_w(offs_t offset, u16 data)
+{
+ m_stream->update();
+ u8 chan = offset >> 6;
+ if(m_lpf_cutoff[chan] != data)
+ logerror("chan %02x lpf cutoff %04x\n", chan, data);
+ m_lpf_cutoff[chan] = data;
+}
+
+u16 swp30_device::hpf_cutoff_r(offs_t offset)
+{
+ return m_hpf_cutoff[offset >> 6];
+}
+
+void swp30_device::hpf_cutoff_w(offs_t offset, u16 data)
+{
+ m_stream->update();
+ u8 chan = offset >> 6;
+ if(m_hpf_cutoff[chan] != data)
+ logerror("chan %02x hpf cutoff %04x\n", chan, data);
+ m_hpf_cutoff[chan] = data;
+}
+
+u16 swp30_device::lpf_reso_r(offs_t offset)
+{
+ return m_lpf_reso[offset >> 6];
+}
+
+void swp30_device::lpf_reso_w(offs_t offset, u16 data)
+{
+ m_stream->update();
+ u8 chan = offset >> 6;
+ if(m_lpf_reso[chan] != data)
+ logerror("chan %02x lpf resonance %04x\n", chan, data);
+ m_lpf_reso[chan] = data;
+}
+
+template<int filter, int coef> u16 swp30_device::eq_filter_r(offs_t offset)
+{
+ return m_eq_filter[offset >> 6][filter][coef];
+}
+
+template<int filter, int coef> void swp30_device::eq_filter_w(offs_t offset, u16 data)
+{
+ m_stream->update();
+ logerror("chan %02x eq filter %s coef %d: %04x (%f)\n", offset >> 6, filter, coef, data, s16(data)/8192.0);
+ m_eq_filter[offset >> 6][filter][coef] = data;
+}
+
+
u16 swp30_device::volume_r(offs_t offset)
{
int chan = offset >> 6;
@@ -270,6 +443,119 @@ void swp30_device::address_w(offs_t offset, u16 data)
m_address[chan] = (m_address[chan] & 0x0000ffff) | (data << 16);
}
+template<int id> void swp30_device::variation_delay_w(u16 data)
+{
+ m_variation_delay[id] = data;
+ logerror("variation delay %d: %04x (%fms)\n", id, data, data/44.100);
+}
+
+template<int id> u16 swp30_device::variation_delay_r()
+{
+ return m_variation_delay[id];
+}
+
+template<int id> void swp30_device::variation_fb_level_w(u16 data)
+{
+ m_variation_fb_level[id] = data;
+ logerror("variation feedback level %d: %04x (%+f)\n", id, data, s16(data)/500.0);
+}
+
+template<int id> u16 swp30_device::variation_fb_level_r()
+{
+ return m_variation_fb_level[id];
+}
+
+template<int id> void swp30_device::variation_final_level_w(u16 data)
+{
+ m_variation_final_level[id] = data;
+ logerror("variation final level %s %s: %04x (%f)\n", id & 1 ? "wet" : "dry", id & 2 ? "left" : "right", data, data/16383.0);
+}
+
+template<int id> u16 swp30_device::variation_final_level_r()
+{
+ return m_variation_final_level[id];
+}
+
+template<int id> void swp30_device::variation_high_damp_w(u16 data)
+{
+ m_variation_high_damp[id] = data;
+ logerror("variation high damp %d: %04x (%f)\n", id, data, 0.1+double(data-0x2000)/0x2000*0.9);
+}
+
+template<int id> u16 swp30_device::variation_high_damp_r()
+{
+ return m_variation_high_damp[id];
+}
+
+template<int id> void swp30_device::variation_inv_high_damp_w(u16 data)
+{
+ m_variation_inv_high_damp[id] = data;
+ logerror("variation inverse high damp %d: %04x (%f)\n", id, data, 0.1+double(0x2000-data)/0x2000*0.9);
+}
+
+template<int id> u16 swp30_device::variation_inv_high_damp_r()
+{
+ return m_variation_inv_high_damp[id];
+}
+
+
+template<int ins, int id> void swp30_device::insertion_delay_w(u16 data)
+{
+ m_insertion_delay[ins][id] = data;
+ logerror("insertion %d delay %d: %04x (%fms)\n", ins, id, data, data/44.100);
+}
+
+template<int ins, int id> u16 swp30_device::insertion_delay_r()
+{
+ return m_insertion_delay[ins][id];
+}
+
+template<int ins, int id> void swp30_device::insertion_fb_level_w(u16 data)
+{
+ m_insertion_fb_level[ins][id] = data;
+ logerror("insertion %d feedback level %d: %04x (%+f)\n", ins, id, data, s16(data)/500.0);
+}
+
+template<int ins, int id> u16 swp30_device::insertion_fb_level_r()
+{
+ return m_insertion_fb_level[ins][id];
+}
+
+template<int ins, int id> void swp30_device::insertion_final_level_w(u16 data)
+{
+ m_insertion_final_level[ins][id] = data;
+ logerror("insertion %d final level %s %s: %04x (%f)\n", ins, id & 1 ? "wet" : "dry", id & 2 ? "left" : "right", data, data/8191.0);
+}
+
+template<int ins, int id> u16 swp30_device::insertion_final_level_r()
+{
+ return m_insertion_final_level[ins][id];
+}
+
+template<int ins, int id> void swp30_device::insertion_high_damp_w(u16 data)
+{
+ m_insertion_high_damp[ins][id] = data;
+ logerror("insertion %d high damp %d: %04x (%f)\n", ins, id, data, 0.1+double(data-0x4000)/0x4000*0.9);
+}
+
+template<int ins, int id> u16 swp30_device::insertion_high_damp_r()
+{
+ return m_insertion_high_damp[ins][id];
+}
+
+template<int ins, int id> void swp30_device::insertion_inv_high_damp_w(u16 data)
+{
+ m_insertion_inv_high_damp[ins][id] = data;
+ logerror("insertion %s inverse high damp %d: %04x (%f)\n", ins, id, data, 0.1+double(0x4000-data)/0x4000*0.9);
+}
+
+template<int ins, int id> u16 swp30_device::insertion_inv_high_damp_r()
+{
+ return m_insertion_inv_high_damp[ins][id];
+}
+
+
+
static u16 rr[0x40*0x40];
u16 swp30_device::snd_r(offs_t offset)
@@ -297,6 +583,8 @@ void swp30_device::snd_w(offs_t offset, u16 data)
return;
}
rr[offset] = data;
+ if(offset == 0x4e)
+ return;
int chan = (offset >> 6) & 0x3f;
int slot = offset & 0x3f;
std::string preg = "-";
@@ -305,48 +593,6 @@ void swp30_device::snd_w(offs_t offset, u16 data)
logerror("snd_w [%04x %04x - %-4s] %02x.%02x, %04x\n", offset, offset*2, preg, chan, slot, data);
}
-/*
-[:swp30] sample 00 46a86f [3] -5848 0180 00ff 3e06
-[:swp30] sample 01 4a2a69 [1] -5789 0400 001b 0122
-[:swp30] sample 02 42a89b [3] -4110 0100 00ff 0a3a
-[:swp30] sample 03 46ce62 [3] -6727 0380 00ff 3e06
-[:swp30] sample 08 427193 [3] -4190 0540 00ff 0a3a
-#[:swp30] sample 09 94ba25 [0] -11267 0000 0026 0830
-[:swp30] sample 0b 41b5c1 [3] +617 fe80 003c 0a3a
-#[:swp30] sample 20 455235 [3] +19583 0580 002f 3e06
-#[:swp30] sample 24 4117b1 [3] +18465 fa80 0034 0a3a
-#[:swp30] sample 2a 41f4bf [3] +19969 ff40 0039 0a3a
-[:swp30] sample 2d 467938 [3] +7441 ff40 00ff 3e06
-[:swp30] sample 30 435fd3 [3] -5882 fdc0 0039 0a3a
-[:swp30] sample 33 431a0a [3] +1960 0340 0043 0a3a
-#[:swp30] sample 36 94ba25 [0] -2174 0000 0047 081c
-[:swp30] sample 39 42e187 [3] +4221 ffc0 00ff 0a3a
-[:swp30] sample 3a 46f798 [3] +2522 0000 00ff 3e06
-
-[:swp30] sample id 1226729 085f 0402
-
-[:swp30] sample 00 46a86f [3] -5847 00c0 00ff 3e06
-[:swp30] sample 01 4a2a69 [1] -5788 3010 001b 0122
-[:swp30] sample 02 42a89b [3] -4109 00c0 00ff 0a3a
-[:swp30] sample 03 46ce62 [3] -6726 0000 00ff 3e06
-[:swp30] sample 08 427193 [3] -4189 03c0 00ff 0a3a
-#[:swp30] sample 09 94ba25 [0] -11267 0000 0026 0830
-[:swp30] sample 0b 41b5c1 [3] +618 0180 003c 0a3a
-#[:swp30] sample 20 455235 [3] +19583 0580 002f 3e06
-#[:swp30] sample 24 4117b1 [3] +18465 fa80 0034 0a3a
-#[:swp30] sample 2a 41f4bf [3] +19970 fe40 0039 0a3a
-[:swp30] sample 2d 467938 [3] +7442 ff00 00ff 3e06
-[:swp30] sample 30 435fd3 [3] -5882 fdc0 0039 0a3a
-[:swp30] sample 33 431a0a [3] +1961 0040 0043 0a3a
-#[:swp30] sample 36 94ba25 [0] -2173 0000 0047 081c
-[:swp30] sample 39 42e187 [3] +4222 02c0 00ff 0a3a
-[:swp30] sample 3a 46f798 [3] +2523 ff80 00ff 3e06
-
-[:swp30] sample id 1226730 0ea3 2e06
-*/
-
- //static int sid = 0;
-
void swp30_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
// Loop first on the samples and not on the channels otherwise
@@ -428,12 +674,23 @@ void swp30_device::sound_stream_update(sound_stream &stream, stream_sample_t **i
}
// Third, filter the sample
+ // - missing lpf_cutoff, lpf_reso, hpf_cutoff
+
+ // - eq lowpass
+ s32 samp1 = (samp * m_eq_filter[channel][0][2] + m_sample_history[channel][0][0] * m_eq_filter[channel][0][1] + m_sample_history[channel][0][1] * m_eq_filter[channel][0][0]) >> 13;
+ m_sample_history[channel][0][1] = m_sample_history[channel][0][0];
+ m_sample_history[channel][0][0] = samp;
- // - no idea what's needed there
+ // - eq highpass
+ s32 samp2 = (samp1 * m_eq_filter[channel][1][2] + m_sample_history[channel][1][0] * m_eq_filter[channel][1][1] + m_sample_history[channel][1][1] * m_eq_filter[channel][1][0]) >> 13;
+ m_sample_history[channel][1][1] = m_sample_history[channel][1][0];
+ m_sample_history[channel][1][0] = samp1;
- // Fourth, volume and pan, clamp the attenuation at -96dB
- s32 sampl = samp * m_linear_attenuation[std::min(0xff, (m_volume[channel] & 0x00) + (m_pan[channel] >> 8))];
- s32 sampr = samp * m_linear_attenuation[std::min(0xff, (m_volume[channel] & 0x00) + (m_pan[channel] & 0xff))];
+ // - anything else?
+
+ // Fourth, volume (disabled) and pan, clamp the attenuation at -96dB
+ s32 sampl = samp2 * m_linear_attenuation[std::min(0xff, (m_volume[channel] & 0x00) + (m_pan[channel] >> 8))];
+ s32 sampr = samp2 * m_linear_attenuation[std::min(0xff, (m_volume[channel] & 0x00) + (m_pan[channel] & 0xff))];
// Fifth, add to the accumulators
acc_left += sampl;
@@ -443,6 +700,8 @@ void swp30_device::sound_stream_update(sound_stream &stream, stream_sample_t **i
}
// Samples are 16 bits, there are up to 64 of them, and the accumulators are fixed-point signed 48.16
+ // Global EQ is missing
+
acc_left >>= (16+6);
if(acc_left < -0x8000)
acc_left = -0x8000;
@@ -456,8 +715,5 @@ void swp30_device::sound_stream_update(sound_stream &stream, stream_sample_t **i
else if(acc_right > 0x7fff)
acc_right = 0x7fff;
outputs[1][sample] = acc_right;
-
- // logerror("sample id %8d %04x %04x %016x [%08x]\n", sid, acc_right & 0xffff, acc_left & 0xffff, m_active_mask, m_address[4]);
- // sid++;
}
}