mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-02-24 07:02:27 +01:00
byuu says: Changelog: - fixed I/O register reads; perfect score on endrift's I/O tests now - fixed mouse capture clipping on Windows [Cydrak] - several hours of code maintenance work done on the SFC core All higan/sfc files should now use the auto fn() -> ret; syntax. Haven't converted all unsigned->uint yet. Also, probably won't do sfc/alt as that's mostly just speed hack stuff. Errata: - forgot auto& instead of just auto on SuperFamicom::Video::draw_cursor, which makes Super Scope / Justifier crash. Will be fixed in the next WIP.
96 lines
2.0 KiB
C++
96 lines
2.0 KiB
C++
void APU::Wave::run() {
|
|
if(period && --period == 0) {
|
|
period = 1 * (2048 - frequency);
|
|
patternsample = pattern[patternbank * 16 + patternaddr++];
|
|
if(patternaddr == 0) patternbank ^= mode;
|
|
}
|
|
|
|
output = patternsample;
|
|
static unsigned multiplier[] = {0, 4, 2, 1, 3, 3, 3, 3};
|
|
output = (output * multiplier[volume]) / 4;
|
|
if(enable == false) output = 0;
|
|
}
|
|
|
|
void APU::Wave::clocklength() {
|
|
if(enable && counter) {
|
|
if(++length == 0) enable = false;
|
|
}
|
|
}
|
|
|
|
uint8 APU::Wave::read(unsigned addr) const {
|
|
switch(addr) {
|
|
case 0: return (mode << 5) | (bank << 6) | (dacenable << 7);
|
|
case 1: return 0;
|
|
case 2: return (volume << 5);
|
|
case 3: return 0;
|
|
case 4: return (counter << 6);
|
|
}
|
|
}
|
|
|
|
void APU::Wave::write(unsigned addr, uint8 byte) {
|
|
switch(addr) {
|
|
case 0: //NR30
|
|
mode = byte >> 5;
|
|
bank = byte >> 6;
|
|
dacenable = byte >> 7;
|
|
if(dacenable == false) enable = false;
|
|
break;
|
|
|
|
case 1: //NR31
|
|
length = byte >> 0;
|
|
break;
|
|
|
|
case 2: //NR32
|
|
volume = byte >> 5;
|
|
break;
|
|
|
|
case 3: //NR33
|
|
frequency = (frequency & 0xff00) | (byte << 0);
|
|
break;
|
|
|
|
case 4: //NR34
|
|
frequency = (frequency & 0x00ff) | (byte << 8);
|
|
counter = byte >> 6;
|
|
initialize = byte >> 7;
|
|
|
|
if(initialize) {
|
|
enable = dacenable;
|
|
period = 1 * (2048 - frequency);
|
|
patternaddr = 0;
|
|
patternbank = mode ? (uint1)0 : bank;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
uint8 APU::Wave::readram(unsigned addr) const {
|
|
uint8 byte = 0;
|
|
byte |= pattern[addr * 2 + 0] << 0;
|
|
byte |= pattern[addr * 2 + 1] << 4;
|
|
return byte;
|
|
}
|
|
|
|
void APU::Wave::writeram(unsigned addr, uint8 byte) {
|
|
pattern[addr * 2 + 0] = byte >> 0;
|
|
pattern[addr * 2 + 1] = byte >> 4;
|
|
}
|
|
|
|
void APU::Wave::power() {
|
|
mode = 0;
|
|
bank = 0;
|
|
dacenable = 0;
|
|
length = 0;
|
|
volume = 0;
|
|
frequency = 0;
|
|
counter = 0;
|
|
initialize = 0;
|
|
for(auto& sample : pattern) sample = 0;
|
|
enable = 0;
|
|
output = 0;
|
|
patternaddr = 0;
|
|
patternbank = 0;
|
|
patternsample = 0;
|
|
period = 0;
|
|
}
|