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