Aid VSU performance
This commit is contained in:
		
							parent
							
								
									e97b52e944
								
							
						
					
					
						commit
						bc864644f7
					
				| 
						 | 
					@ -64,7 +64,9 @@ typedef struct {
 | 
				
			||||||
    } wave;
 | 
					    } wave;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Other state */
 | 
					    /* Other state */
 | 
				
			||||||
    uint32_t clocks; /* Clocks until next sample */
 | 
					    uint32_t clocks;  /* Clocks until next wave or noise sample */
 | 
				
			||||||
 | 
					    uint8_t  freqmod; /* Frequency modifications are active */
 | 
				
			||||||
 | 
					    uint32_t until;   /* Clocks until channel component update */
 | 
				
			||||||
} Channel;
 | 
					} Channel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Simulation state */
 | 
					/* Simulation state */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										105
									
								
								core/vsu.c
								
								
								
								
							
							
						
						
									
										105
									
								
								core/vsu.c
								
								
								
								
							| 
						 | 
					@ -74,49 +74,8 @@ static void vsuNextFreqMod(VB *sim, Channel *chan) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Process one channel */
 | 
					/* Process one channel */
 | 
				
			||||||
static void vsuEmulateChannel(VB *sim, int index, uint32_t clocks) {
 | 
					static void vsuEmulateChannel(VB *sim, Channel *chan, uint32_t clocks) {
 | 
				
			||||||
    uint32_t bit; /* Pseudorandom bit */
 | 
					    uint32_t bit; /* Pseudorandom bit */
 | 
				
			||||||
    Channel *chan;    /* Channel handle */
 | 
					 | 
				
			||||||
    int      freqmod; /* Frequency modifications enabled */
 | 
					 | 
				
			||||||
    uint32_t until;   /* Clocks to process sub-channel components */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Select channel */
 | 
					 | 
				
			||||||
    chan = &sim->vsu.channels[index];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Channel is disabled */
 | 
					 | 
				
			||||||
    if (!chan->int_.enb)
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Frequency modifications are active */
 | 
					 | 
				
			||||||
    freqmod =
 | 
					 | 
				
			||||||
        index == 4           &&        /* Channel 5 */
 | 
					 | 
				
			||||||
        sim->vsu.freqmod.enb &&        /* Modifications enabled */
 | 
					 | 
				
			||||||
        sim->vsu.freqmod.interval != 0 /* Modifications valid */
 | 
					 | 
				
			||||||
    ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Process all clocks */
 | 
					 | 
				
			||||||
    do {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* Clocks until next state change */
 | 
					 | 
				
			||||||
        until = clocks;
 | 
					 | 
				
			||||||
        if (chan->clocks < until)
 | 
					 | 
				
			||||||
            until = chan->clocks;
 | 
					 | 
				
			||||||
        if (chan->env.enb && chan->env.clocks < until)
 | 
					 | 
				
			||||||
            until = chan->env.clocks;
 | 
					 | 
				
			||||||
        if (chan->int_.auto_ && chan->int_.clocks < until)
 | 
					 | 
				
			||||||
            until = chan->int_.clocks;
 | 
					 | 
				
			||||||
        if (freqmod && sim->vsu.freqmod.clocks < until)
 | 
					 | 
				
			||||||
            until = sim->vsu.freqmod.clocks;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* Manage clocks */
 | 
					 | 
				
			||||||
        clocks       -= until;
 | 
					 | 
				
			||||||
        chan->clocks -= until;
 | 
					 | 
				
			||||||
        if (chan->env.enb)
 | 
					 | 
				
			||||||
            chan->env.clocks -= until;
 | 
					 | 
				
			||||||
        if (chan->int_.auto_)
 | 
					 | 
				
			||||||
            chan->int_.clocks -= until;
 | 
					 | 
				
			||||||
        if (freqmod)
 | 
					 | 
				
			||||||
            sim->vsu.freqmod.clocks -= until;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Automatic shutoff */
 | 
					    /* Automatic shutoff */
 | 
				
			||||||
    if (chan->int_.auto_ && chan->int_.clocks == 0) {
 | 
					    if (chan->int_.auto_ && chan->int_.clocks == 0) {
 | 
				
			||||||
| 
						 | 
					@ -124,11 +83,11 @@ static void vsuEmulateChannel(VB *sim, int index, uint32_t clocks) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Next sample */
 | 
					    /* Next input sample */
 | 
				
			||||||
    if (chan->clocks == 0) {
 | 
					    if (chan->clocks == 0) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Wave */
 | 
					        /* Wave */
 | 
				
			||||||
            if (index != 5) {
 | 
					        if (chan != &sim->vsu.channels[5]) {
 | 
				
			||||||
            chan->clocks =  4 * (2048 - (uint32_t) chan->freq.current);
 | 
					            chan->clocks =  4 * (2048 - (uint32_t) chan->freq.current);
 | 
				
			||||||
            chan->wave.sample = (chan->wave.sample + 1) & 31;
 | 
					            chan->wave.sample = (chan->wave.sample + 1) & 31;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -158,7 +117,7 @@ static void vsuEmulateChannel(VB *sim, int index, uint32_t clocks) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Frequency modification */
 | 
					    /* Frequency modification */
 | 
				
			||||||
        if (freqmod && sim->vsu.freqmod.clocks == 0) {
 | 
					    if (chan->freqmod && sim->vsu.freqmod.clocks == 0) {
 | 
				
			||||||
        chan->freq.current = sim->vsu.freqmod.next;
 | 
					        chan->freq.current = sim->vsu.freqmod.next;
 | 
				
			||||||
        vsuNextFreqMod(sim, chan);
 | 
					        vsuNextFreqMod(sim, chan);
 | 
				
			||||||
        if (!chan->int_.enb)
 | 
					        if (!chan->int_.enb)
 | 
				
			||||||
| 
						 | 
					@ -167,8 +126,6 @@ static void vsuEmulateChannel(VB *sim, int index, uint32_t clocks) {
 | 
				
			||||||
            (sim->vsu.freqmod.clk == 0 ? 19200 : 153600);
 | 
					            (sim->vsu.freqmod.clk == 0 ? 19200 : 153600);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    } while (clocks != 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Produce output for a channel */
 | 
					/* Produce output for a channel */
 | 
				
			||||||
| 
						 | 
					@ -230,6 +187,8 @@ static void vsuWriteEV1(VB *sim, int index, uint8_t value) {
 | 
				
			||||||
            sim->vsu.freqmod.func = value >> 4 & 1;
 | 
					            sim->vsu.freqmod.func = value >> 4 & 1;
 | 
				
			||||||
            sim->vsu.freqmod.rep  = value >> 5 & 1;
 | 
					            sim->vsu.freqmod.rep  = value >> 5 & 1;
 | 
				
			||||||
            vsuNextFreqMod(sim, chan);
 | 
					            vsuNextFreqMod(sim, chan);
 | 
				
			||||||
 | 
					            chan->freqmod =
 | 
				
			||||||
 | 
					                sim->vsu.freqmod.enb && sim->vsu.freqmod.interval != 0;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        case 5: /* Channel 6 */
 | 
					        case 5: /* Channel 6 */
 | 
				
			||||||
| 
						 | 
					@ -313,6 +272,8 @@ static void vsuWriteSWP(VB *sim, uint8_t value) {
 | 
				
			||||||
        (sim->vsu.freqmod.clk == 0 ? 19200 : 153600);
 | 
					        (sim->vsu.freqmod.clk == 0 ? 19200 : 153600);
 | 
				
			||||||
    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 =
 | 
				
			||||||
 | 
					        sim->vsu.freqmod.enb && sim->vsu.freqmod.interval != 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -321,6 +282,8 @@ static void vsuWriteSWP(VB *sim, uint8_t value) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Process component */
 | 
					/* Process component */
 | 
				
			||||||
static void vsuEmulate(VB *sim, uint32_t clocks) {
 | 
					static void vsuEmulate(VB *sim, uint32_t clocks) {
 | 
				
			||||||
 | 
					    Channel *chan;      /* Input channel */
 | 
				
			||||||
 | 
					    uint32_t chantil;   /* Clocks until next channel state update */
 | 
				
			||||||
    float    i0;        /* Current analog input sample */
 | 
					    float    i0;        /* Current analog input sample */
 | 
				
			||||||
    float    o0;        /* Current analog output sample */
 | 
					    float    o0;        /* Current analog output sample */
 | 
				
			||||||
    uint16_t output[2]; /* Digital output samples */
 | 
					    uint16_t output[2]; /* Digital output samples */
 | 
				
			||||||
| 
						 | 
					@ -340,8 +303,50 @@ static void vsuEmulate(VB *sim, uint32_t clocks) {
 | 
				
			||||||
        sim->vsu.clocks -= until;
 | 
					        sim->vsu.clocks -= until;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Process all channels */
 | 
					        /* Process all channels */
 | 
				
			||||||
        for (x = 0; x < 6; x++)
 | 
					        for (x = 0; x < 6; x++) {
 | 
				
			||||||
            vsuEmulateChannel(sim, x, until);
 | 
					            chan    = &sim->vsu.channels[x];
 | 
				
			||||||
 | 
					            chantil = until;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Process all clocks */
 | 
				
			||||||
 | 
					            while (chan->int_.enb && chantil != 0) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                /* Determine when the next state change will occur */
 | 
				
			||||||
 | 
					                if (chan->until == 0) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    /* Clocks until next state change */
 | 
				
			||||||
 | 
					                    chan->until = chan->clocks;
 | 
				
			||||||
 | 
					                    if (chan->env.enb && chan->env.clocks < chan->until)
 | 
				
			||||||
 | 
					                        chan->until = chan->env.clocks;
 | 
				
			||||||
 | 
					                    if (chan->int_.auto_ && chan->int_.clocks < chan->until)
 | 
				
			||||||
 | 
					                        chan->until = chan->int_.clocks;
 | 
				
			||||||
 | 
					                    if (chan->freqmod && sim->vsu.freqmod.clocks < chan->until)
 | 
				
			||||||
 | 
					                        chan->until = sim->vsu.freqmod.clocks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    /* Manage clocks */
 | 
				
			||||||
 | 
					                    chan->clocks -= chan->until;
 | 
				
			||||||
 | 
					                    if (chan->env.enb)
 | 
				
			||||||
 | 
					                        chan->env.clocks -= chan->until;
 | 
				
			||||||
 | 
					                    if (chan->int_.auto_)
 | 
				
			||||||
 | 
					                        chan->int_.clocks -= chan->until;
 | 
				
			||||||
 | 
					                    if (chan->freqmod)
 | 
				
			||||||
 | 
					                        sim->vsu.freqmod.clocks -= chan->until;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                /* Manage clocks */
 | 
				
			||||||
 | 
					                if (chan->until > chantil) {
 | 
				
			||||||
 | 
					                    chan->until -= chantil;
 | 
				
			||||||
 | 
					                    chantil      = 0;
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    chantil     -= chan->until;
 | 
				
			||||||
 | 
					                    chan->until  = 0;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                /* Update channel state */
 | 
				
			||||||
 | 
					                if (chan->until == 0)
 | 
				
			||||||
 | 
					                    vsuEmulateChannel(sim, chan, chan->until);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Wait for the current sample to finish */
 | 
					        /* Wait for the current sample to finish */
 | 
				
			||||||
        if (sim->vsu.clocks != 0)
 | 
					        if (sim->vsu.clocks != 0)
 | 
				
			||||||
| 
						 | 
					@ -416,6 +421,8 @@ static void vsuReset(VB *sim) {
 | 
				
			||||||
    for (x = 0; x < 6; x++) {
 | 
					    for (x = 0; x < 6; x++) {
 | 
				
			||||||
        chan = &sim->vsu.channels[x];
 | 
					        chan = &sim->vsu.channels[x];
 | 
				
			||||||
        chan->clocks        = 0;
 | 
					        chan->clocks        = 0;
 | 
				
			||||||
 | 
					        chan->freqmod       = 0;
 | 
				
			||||||
 | 
					        chan->until         = 0;
 | 
				
			||||||
        chan->env.clocks    = 0;
 | 
					        chan->env.clocks    = 0;
 | 
				
			||||||
        chan->env.enb       = 0;
 | 
					        chan->env.enb       = 0;
 | 
				
			||||||
        chan->env.dir       = 0;
 | 
					        chan->env.dir       = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue