Example #1
0
void PCE_PSG::SetRegister(const unsigned int id, const uint32 value)
{
 const int ch = (id >> 8) & 0xF;

 switch(id & 0xF0FF)
 {
  default: break;

  case PSG_GSREG_SELECT:
	select = value & 0x07;
	break;

  case PSG_GSREG_GBALANCE:
	globalbalance = value & 0xFF;
	break;

  case PSG_GSREG_LFOFREQ:
	lfofreq = value & 0xFF;
	break;

  case PSG_GSREG_LFOCTRL:
	lfoctrl = value & 0x83;
        RecalcFreqCache(0);
        RecalcUOFunc(0);
        RecalcFreqCache(1);
        RecalcUOFunc(1);
	break;

  case PSG_GSREG_CH0_FREQ:
	channel[ch].frequency = value & 0xFFF;
	RecalcFreqCache(ch);
	RecalcUOFunc(ch);
	break;

  case PSG_GSREG_CH0_CTRL:
	channel[ch].control = value & 0xFF;
	RecalcFreqCache(ch);
	RecalcUOFunc(ch);
	break;

  case PSG_GSREG_CH0_BALANCE:
	channel[ch].balance = value & 0xFF;
	break;

  case PSG_GSREG_CH0_WINDEX:
	channel[ch].waveform_index = value & 0x1F;
	break;

  case PSG_GSREG_CH0_SCACHE:
	channel[ch].dda = value & 0x1F;
	break;

  case PSG_GSREG_CH0_NCTRL:
	channel[ch].noisectrl = value & 0xFF;
        RecalcNoiseFreqCache(ch);
        RecalcUOFunc(ch);
	break;

  case PSG_GSREG_CH0_LFSR:
	channel[ch].lfsr = value & 0x7FFF;
	break;
 }
}
Example #2
0
void PCEFast_PSG::Write(int32 timestamp, uint8 A, uint8 V)
{	
    A &= 0x0F;

    if(A == 0x00)
    {
     select = (V & 0x07);
     return;
    }

    Update(timestamp);

    psg_channel *ch = &channel[select];

    //if(A == 0x01 || select == 5)
    // printf("Write Ch: %d %04x %02x, %d\n", select, A, V, timestamp);

    switch(A)
    {
	default: break;

        case 0x01: /* Global sound balance */
            globalbalance = V;
	    vol_pending = true;
            break;

        case 0x02: /* Channel frequency (LSB) */
	    if(select > 5) return; // no more than 6 channels, silly game.

            ch->frequency = (ch->frequency & 0x0F00) | V;
	    RecalcFreqCache(select);
	    RecalcUOFunc(select);
            break;

        case 0x03: /* Channel frequency (MSB) */
	    if(select > 5) return; // no more than 6 channels, silly game.

            ch->frequency = (ch->frequency & 0x00FF) | ((V & 0x0F) << 8);
	    RecalcFreqCache(select);
	    RecalcUOFunc(select);
            break;

        case 0x04: /* Channel enable, DDA, volume */
	    if(select > 5) return; // no more than 6 channels, silly game.

            if((ch->control & 0x40) && !(V & 0x40))
	    {
	     ch->waveform_index = 0;
             ch->dda = ch->waveform[ch->waveform_index];
	     ch->counter = ch->freq_cache;
	    }

	    if(!(ch->control & 0x80) && (V & 0x80)) 
	    {
	     if(!(V & 0x40))
	     {
	      ch->waveform_index = (ch->waveform_index + 1) & 0x1F;
	      ch->dda = ch->waveform[ch->waveform_index];
	     }
	    }

            ch->control = V;
	    RecalcFreqCache(select);
	    RecalcUOFunc(select);

	    vol_pending = true;
            break;

        case 0x05: /* Channel balance */
	    if(select > 5) return; // no more than 6 channels, silly game.
            ch->balance = V;

	    vol_pending = true;
            break;

        case 0x06: /* Channel waveform data */
            if(select > 5) return; // no more than 6 channels, silly game.
            V &= 0x1F;

            if(!(ch->control & 0x40))
	    {
	     ch->samp_accum -= ch->waveform[ch->waveform_index];
             ch->waveform[ch->waveform_index] = V;
	     ch->samp_accum += ch->waveform[ch->waveform_index];
	    }

            if((ch->control & 0xC0) == 0x00)
             ch->waveform_index = ((ch->waveform_index + 1) & 0x1F);

	    if(ch->control & 0x80)
	    {
	     // According to my tests(on SuperGrafx), writing to this channel
	     // will update the waveform value cache/latch regardless of DDA mode being enabled.
             ch->dda = V;
	    }
            break;

        case 0x07: /* Noise enable and frequency */
	    if(select > 5) return; // no more than 6 channels, silly game.
            if(select >= 4)
	    {
	     ch->noisectrl = V;
	     RecalcNoiseFreqCache(select);
	     RecalcUOFunc(select);
	    }
            break;

        case 0x08: /* LFO frequency */
            lfofreq = V & 0xFF;
	    //printf("LFO Freq: %02x\n", V);
            break;

        case 0x09: /* LFO trigger and control */
	    //printf("LFO Ctrl: %02x\n", V);
	    if(V & 0x80)
	    {
	     channel[1].waveform_index = 0;
	     channel[1].dda = channel[1].waveform[channel[1].waveform_index];
	     channel[1].counter = channel[1].freq_cache;
	    }
            lfoctrl = V;
	    RecalcFreqCache(0);
	    RecalcUOFunc(0);
	    RecalcFreqCache(1);
	    RecalcUOFunc(1);
            break;
    }
}