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;
|
break;
|
||||||
|
|
||||||
case 0x5F870>>1: /* BKCOL */
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
86
core/vsu.c
86
core/vsu.c
|
@ -50,7 +50,7 @@ static uint8_t vsuCheckFreqMod(VB *sim) {
|
||||||
return
|
return
|
||||||
sim->vsu.freqmod.enb &&
|
sim->vsu.freqmod.enb &&
|
||||||
sim->vsu.freqmod.interval != 0 && (
|
sim->vsu.freqmod.interval != 0 && (
|
||||||
!sim->vsu.freqmod.modmask || (
|
sim->vsu.freqmod.modmask != 2 || (
|
||||||
sim->vsu.freqmod.func == 1 &&
|
sim->vsu.freqmod.func == 1 &&
|
||||||
sim->vsu.freqmod.rep
|
sim->vsu.freqmod.rep
|
||||||
)
|
)
|
||||||
|
@ -62,6 +62,12 @@ static uint8_t vsuCheckFreqMod(VB *sim) {
|
||||||
static void vsuNextFreqMod(VB *sim, Channel *chan) {
|
static void vsuNextFreqMod(VB *sim, Channel *chan) {
|
||||||
int32_t next;
|
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 */
|
/* Sweep */
|
||||||
if (sim->vsu.freqmod.func == 0) {
|
if (sim->vsu.freqmod.func == 0) {
|
||||||
next = chan->freq.current >> sim->vsu.freqmod.shift;
|
next = chan->freq.current >> sim->vsu.freqmod.shift;
|
||||||
|
@ -76,35 +82,31 @@ static void vsuNextFreqMod(VB *sim, Channel *chan) {
|
||||||
|
|
||||||
/* Modulation */
|
/* Modulation */
|
||||||
else {
|
else {
|
||||||
|
|
||||||
/* Compute the modulated value */
|
|
||||||
next = (int32_t) chan->freq.written +
|
next = (int32_t) chan->freq.written +
|
||||||
sim->vsu.modulation[sim->vsu.freqmod.sample];
|
sim->vsu.modulation[sim->vsu.freqmod.sample];
|
||||||
if (next < 0)
|
if (next < 0)
|
||||||
next = 0;
|
next = 0;
|
||||||
if (next > 2047)
|
if (next > 2047)
|
||||||
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 */
|
/* Configure state */
|
||||||
sim->vsu.freqmod.next = next;
|
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 */
|
/* Process one channel */
|
||||||
static void vsuEmulateChannel(VB *sim, Channel *chan) {
|
static void vsuEmulateChannel(VB *sim, Channel *chan) {
|
||||||
uint32_t bit; /* Pseudorandom bit */
|
|
||||||
|
|
||||||
/* Automatic shutoff */
|
/* Automatic shutoff */
|
||||||
if (chan->int_.auto_ && chan->int_.clocks == 0) {
|
if (chan->int_.auto_ && chan->int_.clocks == 0) {
|
||||||
|
@ -124,12 +126,7 @@ static void vsuEmulateChannel(VB *sim, Channel *chan) {
|
||||||
/* Noise */
|
/* Noise */
|
||||||
else {
|
else {
|
||||||
chan->clocks = 40 * (2048 - (uint32_t) chan->freq.current);
|
chan->clocks = 40 * (2048 - (uint32_t) chan->freq.current);
|
||||||
bit = ((
|
vsuNextNoise(sim);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -147,13 +144,37 @@ static void vsuEmulateChannel(VB *sim, Channel *chan) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Frequency modification */
|
/* Frequency modification */
|
||||||
if (chan->freqmod && sim->vsu.freqmod.clocks == 0) {
|
if (chan == &sim->vsu.channels[4] && sim->vsu.freqmod.clocks == 0) {
|
||||||
chan->freq.current = sim->vsu.freqmod.next;
|
|
||||||
vsuNextFreqMod(sim, chan);
|
/* Apply previously computed frequency modification */
|
||||||
|
if (chan->freqmod)
|
||||||
|
chan->freq.current = sim->vsu.freqmod.next;
|
||||||
|
|
||||||
|
/* Channel itself is disabled */
|
||||||
if (!chan->int_.enb)
|
if (!chan->int_.enb)
|
||||||
return;
|
return;
|
||||||
sim->vsu.freqmod.clocks = (uint32_t) sim->vsu.freqmod.interval *
|
|
||||||
(sim->vsu.freqmod.clk == 0 ? 19200 : 153600);
|
/* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -194,8 +215,10 @@ static void vsuWriteEV0(VB *sim, int index, uint8_t value) {
|
||||||
chan->env.interval = value & 7;
|
chan->env.interval = value & 7;
|
||||||
chan->env.value = value >> 4 & 15;
|
chan->env.value = value >> 4 & 15;
|
||||||
chan->env.reload = chan->env.value;
|
chan->env.reload = chan->env.value;
|
||||||
if (index == 4)
|
if (index == 4) {
|
||||||
|
chan->freqmod = vsuCheckFreqMod(sim);
|
||||||
vsuNextFreqMod(sim, chan);
|
vsuNextFreqMod(sim, chan);
|
||||||
|
}
|
||||||
|
|
||||||
/* Configure state */
|
/* Configure state */
|
||||||
chan->env.clocks = 307220 * ((uint32_t) chan->env.interval + 1);
|
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 */
|
case 5: /* Channel 6 */
|
||||||
sim->vsu.noise.tap = value >> 4 & 7;
|
sim->vsu.noise.tap = value >> 4 & 7;
|
||||||
sim->vsu.noise.register_ = 0x0000;
|
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);
|
chan->clocks = 4 * (2048 - (uint32_t) chan->freq.current);
|
||||||
} else {
|
} else {
|
||||||
sim->vsu.noise.register_ = 0x0000;
|
sim->vsu.noise.register_ = 0x0000;
|
||||||
|
vsuNextNoise(sim);
|
||||||
chan->clocks = 40 * (2048 - (uint32_t) chan->freq.current);
|
chan->clocks = 40 * (2048 - (uint32_t) chan->freq.current);
|
||||||
}
|
}
|
||||||
if (index == 4) {
|
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.clk == 0 ? 19200 : 153600);
|
||||||
sim->vsu.freqmod.modmask = 0;
|
sim->vsu.freqmod.modmask = 0;
|
||||||
sim->vsu.freqmod.sample = 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)
|
if (clocks < sim->vsu.freqmod.clocks)
|
||||||
sim->vsu.freqmod.clocks = clocks;
|
sim->vsu.freqmod.clocks = clocks;
|
||||||
sim->vsu.channels[4].freqmod = vsuCheckFreqMod(sim);
|
sim->vsu.channels[4].freqmod = vsuCheckFreqMod(sim);
|
||||||
|
vsuNextFreqMod(sim, &sim->vsu.channels[4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue