mirror of https://github.com/bsnes-emu/bsnes.git
249 lines
6.3 KiB
C++
249 lines
6.3 KiB
C++
auto APU::portRead(uint16 addr) -> uint8 {
|
|
//SDMA_SRC
|
|
if(addr == 0x004a) return dma.s.source.bits( 0, 7);
|
|
if(addr == 0x004b) return dma.s.source.bits( 8,15);
|
|
if(addr == 0x004c) return dma.s.source.bits(16,19);
|
|
|
|
//SDMA_LEN
|
|
if(addr == 0x004e) return dma.s.length.bits( 0, 7);
|
|
if(addr == 0x004f) return dma.s.length.bits( 8,15);
|
|
if(addr == 0x0050) return dma.s.length.bits(16,19);
|
|
|
|
//SDMA_CTRL
|
|
if(addr == 0x0052) return (
|
|
dma.r.rate << 0
|
|
| dma.r.unknown << 2
|
|
| dma.r.loop << 3
|
|
| dma.r.target << 4
|
|
| dma.r.direction << 6
|
|
| dma.r.enable << 7
|
|
);
|
|
|
|
//SND_HYPER_CTRL
|
|
if(addr == 0x006a) return (
|
|
channel5.r.volume << 0
|
|
| channel5.r.scale << 2
|
|
| channel5.r.speed << 4
|
|
| channel5.r.enable << 7
|
|
);
|
|
|
|
//SND_HYPER_CHAN_CTRL
|
|
if(addr == 0x006b) return (
|
|
channel5.r.unknown << 0
|
|
| channel5.r.leftEnable << 5
|
|
| channel5.r.rightEnable << 6
|
|
);
|
|
|
|
//SND_CH1_PITCH
|
|
if(addr == 0x0080) return channel1.r.pitch.bits(0, 7);
|
|
if(addr == 0x0081) return channel1.r.pitch.bits(8,11);
|
|
|
|
//SND_CH2_PITCH
|
|
if(addr == 0x0082) return channel2.r.pitch.bits(0, 7);
|
|
if(addr == 0x0083) return channel2.r.pitch.bits(8,11);
|
|
|
|
//SND_CH3_PITCH
|
|
if(addr == 0x0084) return channel3.r.pitch.bits(0, 7);
|
|
if(addr == 0x0085) return channel3.r.pitch.bits(8,11);
|
|
|
|
//SND_CH4_PITCH
|
|
if(addr == 0x0086) return channel4.r.pitch.bits(0, 7);
|
|
if(addr == 0x0087) return channel4.r.pitch.bits(8,11);
|
|
|
|
//SND_CH1_VOL
|
|
if(addr == 0x0088) return (
|
|
channel1.r.volumeRight << 0
|
|
| channel1.r.volumeLeft << 4
|
|
);
|
|
|
|
//SND_CH2_VOL
|
|
if(addr == 0x0089) return (
|
|
channel2.r.volumeRight << 0
|
|
| channel2.r.volumeLeft << 4
|
|
);
|
|
|
|
//SND_CH3_VOL
|
|
if(addr == 0x008a) return (
|
|
channel3.r.volumeRight << 0
|
|
| channel3.r.volumeLeft << 4
|
|
);
|
|
|
|
//SND_CH4_VOL
|
|
if(addr == 0x008b) return (
|
|
channel4.r.volumeRight << 0
|
|
| channel4.r.volumeLeft << 4
|
|
);
|
|
|
|
//SND_SWEEP_VALUE
|
|
if(addr == 0x008c) return channel3.r.sweepValue;
|
|
|
|
//SND_SWEEP_TIME
|
|
if(addr == 0x008d) return channel3.r.sweepTime;
|
|
|
|
//SND_NOISE
|
|
//(noiseReset [bit 3] always reads as zero)
|
|
if(addr == 0x008e) return (
|
|
channel4.r.noiseMode << 0
|
|
| channel4.r.noiseUpdate << 4
|
|
);
|
|
|
|
//SND_WAVE_BASE
|
|
if(addr == 0x008f) return r.waveBase;
|
|
|
|
//SND_CTRL
|
|
if(addr == 0x0090) return (
|
|
channel1.r.enable << 0
|
|
| channel2.r.enable << 1
|
|
| channel3.r.enable << 2
|
|
| channel4.r.enable << 3
|
|
| channel2.r.voice << 5
|
|
| channel3.r.sweep << 6
|
|
| channel4.r.noise << 7
|
|
);
|
|
|
|
//SND_OUTPUT
|
|
if(addr == 0x0091) return (
|
|
r.speakerEnable << 0
|
|
| r.speakerShift << 1
|
|
| r.headphoneEnable << 3
|
|
| 1 << 7 //headphone connected
|
|
);
|
|
|
|
//SND_RANDOM
|
|
if(addr == 0x0092) return channel4.s.noiseLFSR.bits(0, 7);
|
|
if(addr == 0x0093) return channel4.s.noiseLFSR.bits(8,14);
|
|
|
|
//SND_VOICE_CTRL
|
|
if(addr == 0x0094) return (
|
|
channel2.r.voiceEnableRight << 0
|
|
| channel2.r.voiceEnableLeft << 2
|
|
);
|
|
|
|
//SND_HYPERVOICE
|
|
if(addr == 0x0095) return channel5.s.data;
|
|
|
|
return 0x00;
|
|
}
|
|
|
|
auto APU::portWrite(uint16 addr, uint8 data) -> void {
|
|
//SDMA_SRC
|
|
if(addr == 0x004a) dma.r.source.bits( 0, 7) = data.bits(0,7);
|
|
if(addr == 0x004b) dma.r.source.bits( 8,15) = data.bits(0,7);
|
|
if(addr == 0x004c) dma.r.source.bits(16,19) = data.bits(0,3);
|
|
|
|
//SDMA_LEN
|
|
if(addr == 0x004e) dma.r.length.bits( 0, 7) = data.bits(0,7);
|
|
if(addr == 0x004f) dma.r.length.bits( 8,15) = data.bits(0,7);
|
|
if(addr == 0x0050) dma.r.length.bits(16,19) = data.bits(0,3);
|
|
|
|
//SDMA_CTRL
|
|
if(addr == 0x0052) {
|
|
bool trigger = !dma.r.enable && data.bit(7);
|
|
dma.r.rate = data.bits(0,1);
|
|
dma.r.unknown = data.bit (2);
|
|
dma.r.loop = data.bit (3);
|
|
dma.r.target = data.bit (4);
|
|
dma.r.direction = data.bit (6);
|
|
dma.r.enable = data.bit (7);
|
|
if(trigger) {
|
|
dma.s.source = dma.r.source;
|
|
dma.s.length = dma.r.length;
|
|
}
|
|
}
|
|
|
|
//SND_HYPER_CTRL
|
|
if(addr == 0x006a) {
|
|
channel5.r.volume = data.bits(0,1);
|
|
channel5.r.scale = data.bits(2,3);
|
|
channel5.r.speed = data.bits(4,6);
|
|
channel5.r.enable = data.bit (7);
|
|
}
|
|
|
|
//SND_HYPER_CHAN_CTRL
|
|
if(addr == 0x006b) {
|
|
channel5.r.unknown = data.bits(0,3);
|
|
channel5.r.leftEnable = data.bit (5);
|
|
channel5.r.rightEnable = data.bit (6);
|
|
}
|
|
|
|
//SND_CH1_PITCH
|
|
if(addr == 0x0080) channel1.r.pitch.bits(0, 7) = data.bits(0,7);
|
|
if(addr == 0x0081) channel1.r.pitch.bits(8,11) = data.bits(0,3);
|
|
|
|
//SND_CH2_PITCH
|
|
if(addr == 0x0082) channel2.r.pitch.bits(0, 7) = data.bits(0,7);
|
|
if(addr == 0x0083) channel2.r.pitch.bits(8,11) = data.bits(0,3);
|
|
|
|
//SND_CH3_PITCH
|
|
if(addr == 0x0084) channel3.r.pitch.bits(0, 7) = data.bits(0,7);
|
|
if(addr == 0x0085) channel3.r.pitch.bits(8,11) = data.bits(0,3);
|
|
|
|
//SND_CH4_PITCH
|
|
if(addr == 0x0086) channel4.r.pitch.bits(0, 7) = data.bits(0,7);
|
|
if(addr == 0x0087) channel4.r.pitch.bits(8,11) = data.bits(0,3);
|
|
|
|
//SND_CH1_VOL
|
|
if(addr == 0x0088) {
|
|
channel1.r.volumeRight = data.bits(0,3);
|
|
channel1.r.volumeLeft = data.bits(4,7);
|
|
}
|
|
|
|
//SND_CH2_VOL
|
|
if(addr == 0x0089) {
|
|
channel2.r.volumeRight = data.bits(0,3);
|
|
channel2.r.volumeLeft = data.bits(4,7);
|
|
}
|
|
|
|
//SND_CH3_VOL
|
|
if(addr == 0x008a) {
|
|
channel3.r.volumeRight = data.bits(0,3);
|
|
channel3.r.volumeLeft = data.bits(4,7);
|
|
}
|
|
|
|
//SND_CH4_VOL
|
|
if(addr == 0x008b) {
|
|
channel4.r.volumeRight = data.bits(0,3);
|
|
channel4.r.volumeLeft = data.bits(4,7);
|
|
}
|
|
|
|
//SND_SWEEP_VALUE
|
|
if(addr == 0x008c) channel3.r.sweepValue = data;
|
|
|
|
//SND_SWEEP_TIME
|
|
if(addr == 0x008d) channel3.r.sweepTime = data.bits(0,4);
|
|
|
|
//SND_NOISE
|
|
if(addr == 0x008e) {
|
|
channel4.r.noiseMode = data.bits(0,2);
|
|
channel4.r.noiseReset = data.bit (3);
|
|
channel4.r.noiseUpdate = data.bit (4);
|
|
}
|
|
|
|
//SND_WAVE_BASE
|
|
if(addr == 0x008f) r.waveBase = data;
|
|
|
|
//SND_CTRL
|
|
if(addr == 0x0090) {
|
|
channel1.r.enable = data.bit(0);
|
|
channel2.r.enable = data.bit(1);
|
|
channel3.r.enable = data.bit(2);
|
|
channel4.r.enable = data.bit(3);
|
|
channel2.r.voice = data.bit(5);
|
|
channel3.r.sweep = data.bit(6);
|
|
channel4.r.noise = data.bit(7);
|
|
}
|
|
|
|
//SND_OUTPUT
|
|
if(addr == 0x0091) {
|
|
r.speakerEnable = data.bit (0);
|
|
r.speakerShift = data.bits(1,2);
|
|
r.headphoneEnable = data.bit (3);
|
|
}
|
|
|
|
//SND_VOICE_CTRL
|
|
if(addr == 0x0094) {
|
|
channel2.r.voiceEnableRight = data.bits(0,1);
|
|
channel2.r.voiceEnableLeft = data.bits(2,3);
|
|
}
|
|
}
|