mirror of
https://github.com/exoticorn/microw8.git
synced 2026-01-20 19:26:43 +01:00
implement custom base address for GES
This commit is contained in:
@@ -55,6 +55,7 @@ data 80 {
|
|||||||
include "../../platform/src/ges.cwa"
|
include "../../platform/src/ges.cwa"
|
||||||
|
|
||||||
import "env.pow" fn pow(f32, f32) -> f32;
|
import "env.pow" fn pow(f32, f32) -> f32;
|
||||||
|
import "env.exp" fn exp(f32) -> f32;
|
||||||
import "env.sin" fn sin(f32) -> f32;
|
import "env.sin" fn sin(f32) -> f32;
|
||||||
|
|
||||||
export fn snd(t: i32) -> f32 {
|
export fn snd(t: i32) -> f32 {
|
||||||
|
|||||||
Binary file not shown.
@@ -7,21 +7,22 @@ const GesChannelState.Size = 8;
|
|||||||
const GesState.Filter = GesChannelState.Size * 4;
|
const GesState.Filter = GesChannelState.Size * 4;
|
||||||
const GesState.Size = GesState.Filter + 8*4;
|
const GesState.Size = GesState.Filter + 8*4;
|
||||||
|
|
||||||
const GesStateOffset = 112;
|
const GesStateOffset = 32;
|
||||||
const GesBufferOffset = 112 + GesState.Size;
|
const GesBufferOffset = 32 + GesState.Size;
|
||||||
|
|
||||||
export fn gesSnd(t: i32) -> f32 {
|
export fn gesSnd(t: i32) -> f32 {
|
||||||
|
let baseAddr = 0!0x12c78;
|
||||||
if !(t & 127) {
|
if !(t & 127) {
|
||||||
let i: i32;
|
let i: i32;
|
||||||
loop clearLoop {
|
loop clearLoop {
|
||||||
i!GesBufferOffset = 0;
|
(baseAddr + i)!GesBufferOffset = 0;
|
||||||
branch_if (i := i + 4) < 128*8: clearLoop;
|
branch_if (i := i + 4) < 128*8: clearLoop;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ch: i32;
|
let ch: i32;
|
||||||
loop channelLoop {
|
loop channelLoop {
|
||||||
let lazy channelState = GesStateOffset + ch * GesChannelState.Size;
|
let lazy channelState = baseAddr + GesStateOffset + ch * GesChannelState.Size;
|
||||||
let lazy channelReg = 80 + ch * 6;
|
let lazy channelReg = baseAddr + ch * 6;
|
||||||
let envState = channelState?GesChannelState.EnvState;
|
let envState = channelState?GesChannelState.EnvState;
|
||||||
let envVol = i32.load16_u(channelState, GesChannelState.EnvVol);
|
let envVol = i32.load16_u(channelState, GesChannelState.EnvVol);
|
||||||
|
|
||||||
@@ -77,7 +78,7 @@ export fn gesSnd(t: i32) -> f32 {
|
|||||||
let saw2 = saw2 -
|
let saw2 = saw2 -
|
||||||
polyBlep((p - pulsePhase1) >> 16, invPhaseInc, -saw) -
|
polyBlep((p - pulsePhase1) >> 16, invPhaseInc, -saw) -
|
||||||
polyBlep((p - pulsePhase2) >> 16, invPhaseInc, saw);
|
polyBlep((p - pulsePhase2) >> 16, invPhaseInc, saw);
|
||||||
i!(GesBufferOffset + 128*4) = saw2;
|
(baseAddr + i)!(GesBufferOffset + 128*4) = saw2;
|
||||||
phase = phase + phaseInc;
|
phase = phase + phaseInc;
|
||||||
branch_if (i := i + 4) < 64*4: sawLoop;
|
branch_if (i := i + 4) < 64*4: sawLoop;
|
||||||
}
|
}
|
||||||
@@ -86,7 +87,7 @@ export fn gesSnd(t: i32) -> f32 {
|
|||||||
{
|
{
|
||||||
let pulsePhase = 32768 + pulseWidth * 128;
|
let pulsePhase = 32768 + pulseWidth * 128;
|
||||||
loop rectLoop {
|
loop rectLoop {
|
||||||
i!(GesBufferOffset + 128*4) = select((phase & 65535) < pulsePhase, -32768, 32767) -
|
(baseAddr + i)!(GesBufferOffset + 128*4) = select((phase & 65535) < pulsePhase, -32768, 32767) -
|
||||||
polyBlep(phase, invPhaseInc, -32767) -
|
polyBlep(phase, invPhaseInc, -32767) -
|
||||||
polyBlep(phase - pulsePhase, invPhaseInc, 32767);
|
polyBlep(phase - pulsePhase, invPhaseInc, 32767);
|
||||||
phase = phase + phaseInc;
|
phase = phase + phaseInc;
|
||||||
@@ -101,7 +102,7 @@ export fn gesSnd(t: i32) -> f32 {
|
|||||||
s = (s ^ (s >> 31));
|
s = (s ^ (s >> 31));
|
||||||
s = (s >> 8) * scale;
|
s = (s >> 8) * scale;
|
||||||
s = (s ^ (s >> 31));
|
s = (s ^ (s >> 31));
|
||||||
i!(GesBufferOffset + 128*4) = (s >> 15) - 32768;
|
(baseAddr + i)!(GesBufferOffset + 128*4) = (s >> 15) - 32768;
|
||||||
phase = phase + phaseInc;
|
phase = phase + phaseInc;
|
||||||
branch_if (i := i + 4) < 64*4: triLoop;
|
branch_if (i := i + 4) < 64*4: triLoop;
|
||||||
}
|
}
|
||||||
@@ -111,7 +112,7 @@ export fn gesSnd(t: i32) -> f32 {
|
|||||||
let inline pulse = ((phase >> 8) & 255) >= pulseWidth;
|
let inline pulse = ((phase >> 8) & 255) >= pulseWidth;
|
||||||
s = s * 0x6746ba73;
|
s = s * 0x6746ba73;
|
||||||
s = s ^ (s >> 15) * pulse;
|
s = s ^ (s >> 15) * pulse;
|
||||||
i!(GesBufferOffset + 128*4) = (s * 0x835776c7) >> 16;
|
(baseAddr + i)!(GesBufferOffset + 128*4) = (s * 0x835776c7) >> 16;
|
||||||
phase = phase + phaseInc;
|
phase = phase + phaseInc;
|
||||||
branch_if (i := i + 4) < 64*4: noiseLoop;
|
branch_if (i := i + 4) < 64*4: noiseLoop;
|
||||||
}
|
}
|
||||||
@@ -122,8 +123,8 @@ export fn gesSnd(t: i32) -> f32 {
|
|||||||
|
|
||||||
if ctrl & 32 {
|
if ctrl & 32 {
|
||||||
let lazy modSrc = (ch - 1) & 3;
|
let lazy modSrc = (ch - 1) & 3;
|
||||||
let inline channelState = GesStateOffset + modSrc * GesChannelState.Size;
|
let inline channelState = baseAddr + GesStateOffset + modSrc * GesChannelState.Size;
|
||||||
let inline channelReg = 80 + modSrc * 6;
|
let inline channelReg = baseAddr + modSrc * 6;
|
||||||
|
|
||||||
let inline note = i32.load16_u(channelReg, 2);
|
let inline note = i32.load16_u(channelReg, 2);
|
||||||
let inline freq = 440 as f32 * pow(2.0, (note - 69*256) as f32 / (12*256) as f32);
|
let inline freq = 440 as f32 * pow(2.0, (note - 69*256) as f32 / (12*256) as f32);
|
||||||
@@ -138,13 +139,13 @@ export fn gesSnd(t: i32) -> f32 {
|
|||||||
loop ringLoop {
|
loop ringLoop {
|
||||||
let s = phase << 16;
|
let s = phase << 16;
|
||||||
s = (s ^ (s >> 31));
|
s = (s ^ (s >> 31));
|
||||||
i!(GesBufferOffset + 128*4) = (i!(GesBufferOffset + 128*4) * ((s >> 15) - 32768)) >> 15;
|
(baseAddr + i)!(GesBufferOffset + 128*4) = ((baseAddr + i)!(GesBufferOffset + 128*4) * ((s >> 15) - 32768)) >> 15;
|
||||||
phase = phase + phaseInc;
|
phase = phase + phaseInc;
|
||||||
branch_if (i := i + 4) < 64*4: ringLoop;
|
branch_if (i := i + 4) < 64*4: ringLoop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let channelVol = ((ch >> 1)?0x68 >> ((ch & 1) * 4)) & 15;
|
let channelVol = ((baseAddr + (ch >> 1))?24 >> ((ch & 1) * 4)) & 15;
|
||||||
envVol = envVol * channelVol / 15;
|
envVol = envVol * channelVol / 15;
|
||||||
|
|
||||||
let leftVol = (select(ctrl & 16, 0x3d5b, 0x6a79) >> (ch * 4)) & 15;
|
let leftVol = (select(ctrl & 16, 0x3d5b, 0x6a79) >> (ch * 4)) & 15;
|
||||||
@@ -156,30 +157,30 @@ export fn gesSnd(t: i32) -> f32 {
|
|||||||
if filter < 2 {
|
if filter < 2 {
|
||||||
if filter {
|
if filter {
|
||||||
let f = (4096 as f32 - min(4096 as f32, 4096 as f32 * exp(freq * (-8.0 * 3.141 / 44100.0)))) as i32;
|
let f = (4096 as f32 - min(4096 as f32, 4096 as f32 * exp(freq * (-8.0 * 3.141 / 44100.0)))) as i32;
|
||||||
let low = (ch * 8)!(GesStateOffset + GesState.Filter);
|
let low = (baseAddr + ch * 8)!(GesStateOffset + GesState.Filter);
|
||||||
loop filterLoop {
|
loop filterLoop {
|
||||||
let in = (i!(GesBufferOffset + 128*4) * envVol) >> 18;
|
let in = ((baseAddr + i)!(GesBufferOffset + 128*4) * envVol) >> 18;
|
||||||
low = low + (((in - low) * f) >> 12);
|
low = low + (((in - low) * f) >> 12);
|
||||||
(i * 2)!GesBufferOffset = (i * 2)!GesBufferOffset + ((low * leftVol) >> 4);
|
(baseAddr + i * 2)!GesBufferOffset = (baseAddr + i * 2)!GesBufferOffset + ((low * leftVol) >> 4);
|
||||||
(i * 2)!(GesBufferOffset + 4) = (i * 2)!(GesBufferOffset + 4) + ((low * rightVol) >> 4);
|
(baseAddr + i * 2)!(GesBufferOffset + 4) = (baseAddr + i * 2)!(GesBufferOffset + 4) + ((low * rightVol) >> 4);
|
||||||
branch_if (i := i + 4) < 64*4: filterLoop;
|
branch_if (i := i + 4) < 64*4: filterLoop;
|
||||||
(ch * 8)!(GesStateOffset + GesState.Filter) = low;
|
(baseAddr + ch * 8)!(GesStateOffset + GesState.Filter) = low;
|
||||||
(ch * 8)!(GesStateOffset + GesState.Filter + 4) = 0;
|
(baseAddr + ch * 8)!(GesStateOffset + GesState.Filter + 4) = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
loop mixLoop {
|
loop mixLoop {
|
||||||
let sample = (i!(GesBufferOffset + 128*4) * envVol) >> 18;
|
let sample = ((baseAddr + i)!(GesBufferOffset + 128*4) * envVol) >> 18;
|
||||||
(i * 2)!GesBufferOffset = (i * 2)!GesBufferOffset + ((sample * leftVol) >> 4);
|
(baseAddr + i * 2)!GesBufferOffset = (baseAddr + i * 2)!GesBufferOffset + ((sample * leftVol) >> 4);
|
||||||
(i * 2)!(GesBufferOffset + 4) = (i * 2)!(GesBufferOffset + 4) + ((sample * rightVol) >> 4);
|
(baseAddr + i * 2)!(GesBufferOffset + 4) = (baseAddr + i * 2)!(GesBufferOffset + 4) + ((sample * rightVol) >> 4);
|
||||||
branch_if (i := i + 4) < 64*4: mixLoop;
|
branch_if (i := i + 4) < 64*4: mixLoop;
|
||||||
(ch * 8)!(GesStateOffset + GesState.Filter) = sample;
|
(baseAddr + ch * 8)!(GesStateOffset + GesState.Filter) = sample;
|
||||||
(ch * 8)!(GesStateOffset + GesState.Filter + 4) = 0;
|
(baseAddr + ch * 8)!(GesStateOffset + GesState.Filter + 4) = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
filter = filter - 2;
|
filter = filter - 2;
|
||||||
let ctrl = filter?0x6a;
|
let ctrl = (baseAddr + filter)?26;
|
||||||
let note = i32.load16_u(filter * 2, 0x6c);
|
let note = i32.load16_u(baseAddr + filter * 2, 28);
|
||||||
let inline freq = 440 as f32 * pow(2.0, (note - 69*256) as f32 / (12*256) as f32);
|
let inline freq = 440 as f32 * pow(2.0, (note - 69*256) as f32 / (12*256) as f32);
|
||||||
let F = (8192 as f32 * sin(min(0.25, freq / 44100 as f32) * 3.1415)) as i32;
|
let F = (8192 as f32 * sin(min(0.25, freq / 44100 as f32) * 3.1415)) as i32;
|
||||||
let Q = 8192 - (ctrl >> 4) * (7000/15);
|
let Q = 8192 - (ctrl >> 4) * (7000/15);
|
||||||
@@ -190,28 +191,28 @@ export fn gesSnd(t: i32) -> f32 {
|
|||||||
let low_out = ctrl & 1;
|
let low_out = ctrl & 1;
|
||||||
let high_out = (ctrl >> 1) & 1;
|
let high_out = (ctrl >> 1) & 1;
|
||||||
let band_out = (ctrl >> 2) & 1;
|
let band_out = (ctrl >> 2) & 1;
|
||||||
let low = (ch * 8)!(GesStateOffset + GesState.Filter);
|
let low = (baseAddr + ch * 8)!(GesStateOffset + GesState.Filter);
|
||||||
let band = (ch * 8)!(GesStateOffset + GesState.Filter + 4);
|
let band = (baseAddr + ch * 8)!(GesStateOffset + GesState.Filter + 4);
|
||||||
loop filterLoop {
|
loop filterLoop {
|
||||||
let in = (i!(GesBufferOffset + 128*4) * envVol) >> 18;
|
let in = ((baseAddr + i)!(GesBufferOffset + 128*4) * envVol) >> 18;
|
||||||
|
|
||||||
let high = in - low - ((band * Q) >> 12);
|
let high = in - low - ((band * Q) >> 12);
|
||||||
band = band + ((F * high) >> 12);
|
band = band + ((F * high) >> 12);
|
||||||
low = low + ((F * band) >> 12);
|
low = low + ((F * band) >> 12);
|
||||||
|
|
||||||
let sample = low * low_out + high * high_out + band * band_out;
|
let sample = low * low_out + high * high_out + band * band_out;
|
||||||
(i * 2)!GesBufferOffset = (i * 2)!GesBufferOffset + ((sample * leftVol) >> 4);
|
(baseAddr + i * 2)!GesBufferOffset = (baseAddr + i * 2)!GesBufferOffset + ((sample * leftVol) >> 4);
|
||||||
(i * 2)!(GesBufferOffset + 4) = (i * 2)!(GesBufferOffset + 4) + ((sample * rightVol) >> 4);
|
(baseAddr + i * 2)!(GesBufferOffset + 4) = (baseAddr + i * 2)!(GesBufferOffset + 4) + ((sample * rightVol) >> 4);
|
||||||
branch_if (i := i + 4) < 64*4: filterLoop;
|
branch_if (i := i + 4) < 64*4: filterLoop;
|
||||||
(ch * 8)!(GesStateOffset + GesState.Filter) = low;
|
(baseAddr + ch * 8)!(GesStateOffset + GesState.Filter) = low;
|
||||||
(ch * 8)!(GesStateOffset + GesState.Filter + 4) = band;
|
(baseAddr + ch * 8)!(GesStateOffset + GesState.Filter + 4) = band;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
branch_if (ch := ch + 1) < 4: channelLoop;
|
branch_if (ch := ch + 1) < 4: channelLoop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(((t & 127) * 4)!GesBufferOffset) as f32 / 32768 as f32
|
((baseAddr + (t & 127) * 4)!GesBufferOffset) as f32 / 32768 as f32
|
||||||
}
|
}
|
||||||
|
|
||||||
fn polyBlep(transientPhase: i32, invPhaseInc: f32, magnitude: i32) -> i32 {
|
fn polyBlep(transientPhase: i32, invPhaseInc: f32, magnitude: i32) -> i32 {
|
||||||
|
|||||||
@@ -576,6 +576,10 @@ data 80 {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data 0x12c78 {
|
||||||
|
i32(80)
|
||||||
|
}
|
||||||
|
|
||||||
data 0x13000+192*4 {
|
data 0x13000+192*4 {
|
||||||
i32(
|
i32(
|
||||||
0x2c1c1a,
|
0x2c1c1a,
|
||||||
|
|||||||
@@ -19,10 +19,13 @@ The memory has to be imported as `env` `memory` and has a maximum size of 256kb
|
|||||||
00040-00044: time since module start in ms
|
00040-00044: time since module start in ms
|
||||||
00044-0004c: gamepad state
|
00044-0004c: gamepad state
|
||||||
0004c-00050: reserved
|
0004c-00050: reserved
|
||||||
00050-00070: sound registers
|
00050-00070: sound data (synced to sound thread)
|
||||||
00070-00078: reserved
|
00070-00078: reserved
|
||||||
00078-12c78: frame buffer
|
00078-12c78: frame buffer
|
||||||
12c78-13000: reserved
|
12c78-12c7c: sound registers/work area base address (for sndGes function)
|
||||||
|
12c7c-12c80: reserved
|
||||||
|
12c80-12ca0: sound data (synced from sound thread)
|
||||||
|
12ca0-13000: reserved
|
||||||
13000-13400: palette
|
13000-13400: palette
|
||||||
13400-13c00: font
|
13400-13c00: font
|
||||||
13c00-14000: reserved
|
13c00-14000: reserved
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user