Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
akatsuki105 committed Apr 13, 2021
1 parent 608a9a6 commit dd6e43e
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 26 deletions.
82 changes: 56 additions & 26 deletions pkg/gba/apu.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ import (
var waveSamples byte
var wavePosition byte

var waveRAM [0x20]byte

func isWaveRAM(addr uint32) bool {
return addr >= 0x04000090 && addr <= 0x0400009f
}

const (
CPU_FREQ_HZ = 16777216
SND_FREQUENCY = 32768
Expand All @@ -22,10 +28,6 @@ const (
SAMPLE_TIME float64 = 1.0 / 32768
)

const (
CH_LEN = 1 << 14
)

const (
PSG_MAX = 0x7f
PSG_MIN = -0x80
Expand Down Expand Up @@ -96,9 +98,6 @@ func (g *GBA) squareSample(ch int) int8 {
if !util.Bit(cntx, ch) {
return 0
}
if !(ch == 0 || ch == 1) {
return 0
}

toneAddr := uint32(ram.SOUND1CNT_H)
if ch == 1 {
Expand Down Expand Up @@ -138,8 +137,8 @@ func (g *GBA) squareSample(ch int) int8 {
if g.apu.chans[0].sweepTime >= sweepInterval {
g.apu.chans[0].sweepTime -= sweepInterval
sweepShift := byte(g._getRAM(ram.SOUND1CNT_L) & 0b111)
if sweepShift > 0 {
disp := uint32(freqHz >> sweepShift)
if sweepShift != 0 {
disp := freqHz >> sweepShift
if !util.Bit(g._getRAM(ram.SOUND1CNT_L), 3) {
freqHz += disp
} else {
Expand Down Expand Up @@ -200,9 +199,15 @@ func (g *GBA) squareSample(ch int) int8 {
}

if g.apu.chans[ch].phase {
return int8((float64(envelope) / 15) * PSG_MAX)
return int8(float64(envelope) * PSG_MAX / 15)
}
return int8((float64(envelope) / 15) * PSG_MIN)
return int8(float64(envelope) * PSG_MIN / 15)
}

func (g *GBA) enableSoundChan(ch int) {
cntx := byte(g._getRAM(ram.SOUNDCNT_X))
cntx = cntx | (1 << ch)
g._setRAM8(ram.SOUNDCNT_X, cntx)
}

func (g *GBA) disableSoundChan(ch int) {
Expand Down Expand Up @@ -231,7 +236,7 @@ func (g *GBA) waveSample() int8 {
cycleSamples := SND_FREQUENCY / frequency

// Length reached check (if so, just disable the channel and return silence)
if util.Bit(cntx, 14) {
if util.Bit(uint16(g._getRAM(ram.SOUND3CNT_X)), 14) {
g.apu.chans[2].lengthTime += SAMPLE_TIME
if g.apu.chans[2].lengthTime >= length {
g.disableSoundChan(2)
Expand Down Expand Up @@ -278,21 +283,20 @@ func (g *GBA) waveSample() int8 {
}

func (g *GBA) noiseSample() int8 {
cntx := g._getRAM(ram.SOUNDCNT_X)
if !util.Bit(cntx, 3) {
if !util.Bit(g._getRAM(ram.SOUNDCNT_X), 3) {
return 0
}

cnth := g._getRAM(ram.SOUND4CNT_H)
cnth := g._getRAM(ram.SOUND4CNT_H) // ctrl

// Actual frequency in Hertz
freqDiv, freqRsh := float64(cnth&0x7), float64((cnth>>4)&0xf)
if freqDiv == 0 {
freqDiv = 2
freqDiv = 1 / 2
}
frequency := (524288 * freqDiv) / math.Pow(2, freqRsh+1)
frequency := (524288 / freqDiv) / math.Pow(2, freqRsh+1)

cntl := g._getRAM(ram.SOUND4CNT_L)
cntl := g._getRAM(ram.SOUND4CNT_L) // env
// Full length of the generated wave (if enabled) in seconds
soundLen := cntl & 0x3f
length := (64 - float64(soundLen)) / 256
Expand Down Expand Up @@ -385,11 +389,11 @@ var stream []byte

func (g *GBA) soundMix() {
for i := 0; i < len(sndBuffer); i += 4 {
stream[i+0] = byte(sndBuffer[sndCurPlay&BUFF_SAMPLES_MSK] << 6)
stream[i+1] = byte(sndBuffer[sndCurPlay&BUFF_SAMPLES_MSK]>>8) << 6
snd := sndBuffer[sndCurPlay&BUFF_SAMPLES_MSK] << 6
stream[i+0], stream[i+1] = byte(snd), byte(snd>>8)
sndCurPlay++
stream[i+2] = byte(sndBuffer[sndCurPlay&BUFF_SAMPLES_MSK] << 6)
stream[i+3] = byte(sndBuffer[sndCurPlay&BUFF_SAMPLES_MSK]>>8) << 6
snd = sndBuffer[sndCurPlay&BUFF_SAMPLES_MSK] << 6
stream[i+2], stream[i+3] = byte(snd), byte(snd>>8)
sndCurPlay++
}

Expand All @@ -410,7 +414,7 @@ func (g *GBA) fifoACopy() {

for i := uint32(0); i < 4; i++ {
fifoA[fifoALen] = int8(g._getRAM(ram.FIFO_A + i))
i++
fifoALen++
}
}
func (g *GBA) fifoBCopy() {
Expand All @@ -421,7 +425,7 @@ func (g *GBA) fifoBCopy() {

for i := uint32(0); i < 4; i++ {
fifoB[fifoBLen] = int8(g._getRAM(ram.FIFO_B + i))
i++
fifoBLen++
}
}

Expand Down Expand Up @@ -478,7 +482,7 @@ func (g *GBA) soundClock(cycles uint32) {

sampPcmL, sampPcmR := int16(0), int16(0)

cnth := uint16(g._getRAM(ram.SOUNDCNT_H))
cnth := uint16(g._getRAM(ram.SOUNDCNT_H)) // snd_pcm_vol
sampCh4, sampCh5 := (int16(fifoASamp)<<1)>>^(cnth&4), (int16(fifoBSamp)<<1)>>^(cnth&8)

// Left
Expand All @@ -501,7 +505,7 @@ func (g *GBA) soundClock(cycles uint32) {
sampCh := [4]int16{int16(g.squareSample(0)), int16(g.squareSample(1)), int16(g.waveSample()), int16(g.noiseSample())}
sampPsgL, sampPsgR := int32(0), int32(0)

cntl := uint16(g._getRAM(ram.SOUNDCNT_L))
cntl := uint16(g._getRAM(ram.SOUNDCNT_L)) // snd_psg_vol
for i := 0; i < 4; i++ {
if util.Bit(cntl, 12+i) {
sampPsgL = int32(g.clip(sampPsgL + int32(sampCh[i])))
Expand All @@ -527,3 +531,29 @@ func (g *GBA) soundClock(cycles uint32) {
sndCycles -= SAMP_CYCLES
}
}

func (g *GBA) resetSoundChan(ch int, enable bool) {
if enable {
g.apu.chans[ch] = &SoundChan{
phase: false,
samples: 0,
lengthTime: 0,
sweepTime: 0,
envTime: 0,
}

if ch == 2 {
g.waveReset()
}

if ch == 3 {
if util.Bit(g._getRAM(ram.SOUND4CNT_H), 3) {
g.apu.chans[3].lfsr = 0x007f
} else {
g.apu.chans[3].lfsr = 0x7fff
}
}

g.enableSoundChan(ch)
}
}
8 changes: 8 additions & 0 deletions pkg/gba/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ func (g *GBA) _getRAM(addr uint32) uint32 {
switch {
case gpu.IsIO(addr):
return util.LE32(g.GPU.IO[(addr - 0x0400_0000):])
case isWaveRAM(addr):
bank := (g._getRAM(ram.SOUND3CNT_L) >> 2) & 0x10
idx := (bank ^ 0x10) | (addr & 0xf)
return util.LE32(waveRAM[idx:])
case isDMA0IO(addr):
return g.dma[0].get(addr - 0x0400_00b0)
case isDMA1IO(addr):
Expand Down Expand Up @@ -96,6 +100,10 @@ func (g *GBA) _setRAM8(addr uint32, b byte) {
switch {
case gpu.IsIO(addr):
g.GPU.IO[addr-0x0400_0000] = b
case isWaveRAM(addr):
bank := (g._getRAM(ram.SOUND3CNT_L) >> 2) & 0x10
idx := (bank ^ 0x10) | (addr & 0xf)
waveRAM[idx] = b
case isDMA0IO(addr):
if g.dma[0].set(addr-0x0400_00b0, b) {
g.dmaTransfer(dmaImmediate)
Expand Down

0 comments on commit dd6e43e

Please sign in to comment.