Fix BKCOL debug writes, more VSU edge cases
This commit is contained in:
parent
c62dd833a3
commit
185362e6cd
|
@ -546,7 +546,7 @@ static void vipWriteIO(
|
|||
break;
|
||||
|
||||
case 0x5F870>>1: /* BKCOL */
|
||||
sim->vip.bkcol = (sim->vip.bkcol & mask) | (value & 3 * ~mask);
|
||||
sim->vip.bkcol = (sim->vip.bkcol & mask) | (value & 3 & ~mask);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
78
core/vsu.c
78
core/vsu.c
|
@ -50,7 +50,7 @@ static uint8_t vsuCheckFreqMod(VB *sim) {
|
|||
return
|
||||
sim->vsu.freqmod.enb &&
|
||||
sim->vsu.freqmod.interval != 0 && (
|
||||
!sim->vsu.freqmod.modmask || (
|
||||
sim->vsu.freqmod.modmask != 2 || (
|
||||
sim->vsu.freqmod.func == 1 &&
|
||||
sim->vsu.freqmod.rep
|
||||
)
|
||||
|
@ -62,6 +62,12 @@ static uint8_t vsuCheckFreqMod(VB *sim) {
|
|||
static void vsuNextFreqMod(VB *sim, Channel *chan) {
|
||||
int32_t next;
|
||||
|
||||
/* Modulation mask control */
|
||||
if (sim->vsu.freqmod.modmask == 1 && sim->vsu.freqmod.func == 1) {
|
||||
sim->vsu.freqmod.modmask = 2;
|
||||
chan->freqmod = vsuCheckFreqMod(sim);
|
||||
}
|
||||
|
||||
/* Sweep */
|
||||
if (sim->vsu.freqmod.func == 0) {
|
||||
next = chan->freq.current >> sim->vsu.freqmod.shift;
|
||||
|
@ -76,35 +82,31 @@ static void vsuNextFreqMod(VB *sim, Channel *chan) {
|
|||
|
||||
/* Modulation */
|
||||
else {
|
||||
|
||||
/* Compute the modulated value */
|
||||
next = (int32_t) chan->freq.written +
|
||||
sim->vsu.modulation[sim->vsu.freqmod.sample];
|
||||
if (next < 0)
|
||||
next = 0;
|
||||
if (next > 2047)
|
||||
next = 2047;
|
||||
|
||||
/* Not the final modulation sample */
|
||||
if (sim->vsu.freqmod.sample != 31)
|
||||
sim->vsu.freqmod.sample++;
|
||||
|
||||
/* Last modulation sample processed */
|
||||
else {
|
||||
sim->vsu.freqmod.modmask = 1;
|
||||
if (sim->vsu.freqmod.rep)
|
||||
sim->vsu.freqmod.sample = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Configure state */
|
||||
if (chan->freqmod)
|
||||
sim->vsu.freqmod.next = next;
|
||||
}
|
||||
|
||||
/* Advance the noise channel's shift register */
|
||||
static void vsuNextNoise(VB *sim) {
|
||||
uint32_t bit = ((
|
||||
sim->vsu.noise.register_ >> NOISE_TAPS[sim->vsu.noise.tap] ^
|
||||
sim->vsu.noise.register_ >> 7
|
||||
) & 1) ^ 1;
|
||||
sim->vsu.noise.register_ = bit |
|
||||
(sim->vsu.noise.register_ << 1 & 0x7FFE);
|
||||
}
|
||||
|
||||
/* Process one channel */
|
||||
static void vsuEmulateChannel(VB *sim, Channel *chan) {
|
||||
uint32_t bit; /* Pseudorandom bit */
|
||||
|
||||
/* Automatic shutoff */
|
||||
if (chan->int_.auto_ && chan->int_.clocks == 0) {
|
||||
|
@ -124,12 +126,7 @@ static void vsuEmulateChannel(VB *sim, Channel *chan) {
|
|||
/* Noise */
|
||||
else {
|
||||
chan->clocks = 40 * (2048 - (uint32_t) chan->freq.current);
|
||||
bit = ((
|
||||
sim->vsu.noise.register_ >> NOISE_TAPS[sim->vsu.noise.tap]^
|
||||
sim->vsu.noise.register_ >> 7
|
||||
) & 1) ^ 1;
|
||||
sim->vsu.noise.register_ = bit |
|
||||
(sim->vsu.noise.register_ << 1 & 0x7FFE);
|
||||
vsuNextNoise(sim);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -147,15 +144,39 @@ static void vsuEmulateChannel(VB *sim, Channel *chan) {
|
|||
}
|
||||
|
||||
/* Frequency modification */
|
||||
if (chan->freqmod && sim->vsu.freqmod.clocks == 0) {
|
||||
if (chan == &sim->vsu.channels[4] && sim->vsu.freqmod.clocks == 0) {
|
||||
|
||||
/* Apply previously computed frequency modification */
|
||||
if (chan->freqmod)
|
||||
chan->freq.current = sim->vsu.freqmod.next;
|
||||
vsuNextFreqMod(sim, chan);
|
||||
|
||||
/* Channel itself is disabled */
|
||||
if (!chan->int_.enb)
|
||||
return;
|
||||
|
||||
/* Frequency modifications are enabled */
|
||||
if (chan->freqmod) {
|
||||
|
||||
/* Not the final modulation sample */
|
||||
if (sim->vsu.freqmod.sample != 31)
|
||||
sim->vsu.freqmod.sample++;
|
||||
|
||||
/* Last modulation sample processed */
|
||||
else {
|
||||
sim->vsu.freqmod.modmask = 1;
|
||||
if (sim->vsu.freqmod.rep)
|
||||
sim->vsu.freqmod.sample = 0;
|
||||
}
|
||||
|
||||
/* Schedule next modification */
|
||||
sim->vsu.freqmod.clocks = (uint32_t) sim->vsu.freqmod.interval *
|
||||
(sim->vsu.freqmod.clk == 0 ? 19200 : 153600);
|
||||
}
|
||||
|
||||
/* Always process and validate next frequency value */
|
||||
vsuNextFreqMod(sim, chan);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Produce output for a channel */
|
||||
|
@ -194,8 +215,10 @@ static void vsuWriteEV0(VB *sim, int index, uint8_t value) {
|
|||
chan->env.interval = value & 7;
|
||||
chan->env.value = value >> 4 & 15;
|
||||
chan->env.reload = chan->env.value;
|
||||
if (index == 4)
|
||||
if (index == 4) {
|
||||
chan->freqmod = vsuCheckFreqMod(sim);
|
||||
vsuNextFreqMod(sim, chan);
|
||||
}
|
||||
|
||||
/* Configure state */
|
||||
chan->env.clocks = 307220 * ((uint32_t) chan->env.interval + 1);
|
||||
|
@ -223,6 +246,7 @@ static void vsuWriteEV1(VB *sim, int index, uint8_t value) {
|
|||
case 5: /* Channel 6 */
|
||||
sim->vsu.noise.tap = value >> 4 & 7;
|
||||
sim->vsu.noise.register_ = 0x0000;
|
||||
vsuNextNoise(sim);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -265,6 +289,7 @@ static void vsuWriteINT(VB *sim, int index, uint8_t value) {
|
|||
chan->clocks = 4 * (2048 - (uint32_t) chan->freq.current);
|
||||
} else {
|
||||
sim->vsu.noise.register_ = 0x0000;
|
||||
vsuNextNoise(sim);
|
||||
chan->clocks = 40 * (2048 - (uint32_t) chan->freq.current);
|
||||
}
|
||||
if (index == 4) {
|
||||
|
@ -272,6 +297,8 @@ static void vsuWriteINT(VB *sim, int index, uint8_t value) {
|
|||
(sim->vsu.freqmod.clk == 0 ? 19200 : 153600);
|
||||
sim->vsu.freqmod.modmask = 0;
|
||||
sim->vsu.freqmod.sample = 0;
|
||||
chan->freqmod = vsuCheckFreqMod(sim);
|
||||
vsuNextFreqMod(sim, chan);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -304,6 +331,7 @@ static void vsuWriteSWP(VB *sim, uint8_t value) {
|
|||
if (clocks < sim->vsu.freqmod.clocks)
|
||||
sim->vsu.freqmod.clocks = clocks;
|
||||
sim->vsu.channels[4].freqmod = vsuCheckFreqMod(sim);
|
||||
vsuNextFreqMod(sim, &sim->vsu.channels[4]);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue