mirror of https://github.com/bsnes-emu/bsnes.git
98 lines
1.9 KiB
C++
98 lines
1.9 KiB
C++
#ifdef APU_CPP
|
|
|
|
void APU::Wave::run() {
|
|
if(period && --period == 0) {
|
|
period = 1 * (2048 - frequency);
|
|
pattern_sample = pattern[++pattern_offset];
|
|
}
|
|
|
|
uint4 sample = pattern_sample >> volume_shift;
|
|
if(enable == false) sample = 0;
|
|
|
|
output = sample;
|
|
}
|
|
|
|
void APU::Wave::clock_length() {
|
|
if(enable && counter) {
|
|
if(++length == 0) enable = false;
|
|
}
|
|
}
|
|
|
|
void APU::Wave::write(unsigned r, uint8 data) {
|
|
if(r == 0) { //$ff1a NR30
|
|
dac_enable = data & 0x80;
|
|
if(dac_enable == false) enable = false;
|
|
}
|
|
|
|
if(r == 1) { //$ff1b NR31
|
|
length = data;
|
|
}
|
|
|
|
if(r == 2) { //$ff1c NR32
|
|
switch((data >> 5) & 3) {
|
|
case 0: volume_shift = 4; break; // 0%
|
|
case 1: volume_shift = 0; break; //100%
|
|
case 2: volume_shift = 1; break; // 50%
|
|
case 3: volume_shift = 2; break; // 25%
|
|
}
|
|
}
|
|
|
|
if(r == 3) { //$ff1d NR33
|
|
frequency = (frequency & 0x0700) | data;
|
|
}
|
|
|
|
if(r == 4) { //$ff1e NR34
|
|
bool initialize = data & 0x80;
|
|
counter = data & 0x40;
|
|
frequency = ((data & 7) << 8) | (frequency & 0x00ff);
|
|
|
|
if(initialize) {
|
|
enable = dac_enable;
|
|
period = 1 * (2048 - frequency);
|
|
pattern_offset = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void APU::Wave::write_pattern(unsigned p, uint8 data) {
|
|
p <<= 1;
|
|
pattern[p + 0] = (data >> 4) & 15;
|
|
pattern[p + 1] = (data >> 0) & 15;
|
|
}
|
|
|
|
void APU::Wave::power() {
|
|
enable = 0;
|
|
|
|
dac_enable = 0;
|
|
volume_shift = 0;
|
|
frequency = 0;
|
|
counter = 0;
|
|
|
|
random_lfsr r;
|
|
for(auto& n : pattern) n = r() & 15;
|
|
|
|
output = 0;
|
|
length = 0;
|
|
period = 0;
|
|
pattern_offset = 0;
|
|
pattern_sample = 0;
|
|
}
|
|
|
|
void APU::Wave::serialize(serializer& s) {
|
|
s.integer(enable);
|
|
|
|
s.integer(dac_enable);
|
|
s.integer(volume_shift);
|
|
s.integer(frequency);
|
|
s.integer(counter);
|
|
s.array(pattern);
|
|
|
|
s.integer(output);
|
|
s.integer(length);
|
|
s.integer(period);
|
|
s.integer(pattern_offset);
|
|
s.integer(pattern_sample);
|
|
}
|
|
|
|
#endif
|