Skip to content

Commit

Permalink
fix: DMA sound bug
Browse files Browse the repository at this point in the history
  • Loading branch information
akatsuki105 committed May 14, 2021
1 parent be767aa commit ef72fbf
Show file tree
Hide file tree
Showing 15 changed files with 95 additions and 229 deletions.
19 changes: 5 additions & 14 deletions pkg/gba/apu.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@ import (

const (
CPU_FREQ_HZ = 16777216
SND_FREQUENCY = 32768
SND_FREQUENCY = 32768 // sample rate
SND_SAMPLES = 512
SAMP_CYCLES = (CPU_FREQ_HZ / SND_FREQUENCY)
BUFF_SAMPLES = ((SND_SAMPLES) * 16 * 2)
BUFF_SAMPLES_MSK = ((BUFF_SAMPLES) - 1)
SAMPLE_TIME float64 = 1.0 / SND_FREQUENCY
SAMPLE_RATE = SND_FREQUENCY
STREAM_LEN = 2184 // 2 * 2 * sampleRate * (1/60)
STREAM_LEN = (2 * 2 * SND_FREQUENCY / 60) - (2*2*SND_FREQUENCY/60)%4
)

const (
Expand Down Expand Up @@ -48,10 +47,6 @@ type SoundChan struct {
samples, lengthTime, sweepTime, envTime float64
}

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

func isResetSoundChan(addr uint32) bool {
_, ok := resetSoundChanMap[addr]
return ok
Expand All @@ -64,7 +59,7 @@ func (g *GBA) resetSoundChan(addr uint32, b byte) {
func newAPU() *APU {
stream = make([]byte, STREAM_LEN)

context, err := oto.NewContext(SAMPLE_RATE, 2, 2, STREAM_LEN)
context, err := oto.NewContext(SND_FREQUENCY, 2, 2, STREAM_LEN)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -410,11 +405,7 @@ func soundMix() {

// Avoid desync between the Play cursor and the Write cursor
delta := (int32(sndCurWrite-sndCurPlay) >> 8) - (int32(sndCurWrite-sndCurPlay)>>8)%2
if delta >= 0 {
sndCurPlay += uint32(delta)
} else {
sndCurPlay -= uint32(-delta)
}
sndCurPlay = util.AddInt32(sndCurPlay, delta)
}

var (
Expand Down Expand Up @@ -497,7 +488,7 @@ func (g *GBA) soundClock(cycles uint32) {
sampPcmL, sampPcmR := int16(0), int16(0)

cnth := uint16(g._getRAM(ram.SOUNDCNT_H)) // snd_pcm_vol
volADiv, volBDiv := int16((cnth>>2)&0b1), int16((cnth>>3)&0b1)
volADiv, volBDiv := int16((cnth>>2)&0b1)^1, int16((cnth>>3)&0b1)^1
sampCh4, sampCh5 := (int16(fifoASamp)<<1)>>volADiv, (int16(fifoBSamp)<<1)>>volBDiv

// Left
Expand Down
9 changes: 3 additions & 6 deletions pkg/gba/arm.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,13 @@ func (g *GBA) armSWI(inst uint32) {
}

func (g *GBA) armB(inst uint32) {
nn := int32(inst)
nn = (nn << 8) >> 6
nn := (int32(inst) << 8) >> 6
g.R[15] = util.AddInt32(g.inst.loc+8, nn)
g.pipelining()
}

func (g *GBA) armBL(inst uint32) {
nn := int32(inst)
nn = (nn << 8) >> 6
nn := (int32(inst) << 8) >> 6
g.R[14] = g.inst.loc + 4
g.R[15] = util.AddInt32(g.inst.loc+8, nn)
g.pipelining()
Expand Down Expand Up @@ -835,8 +833,7 @@ func (g *GBA) armLDRSH(inst uint32) {

func (g *GBA) armSTRH(inst uint32) {
ofs := (((inst >> 8) & 0b1111) << 4) | (inst & 0b1111) // immediate
if !util.Bit(inst, 22) {
// register
if !util.Bit(inst, 22) { // register
rm := inst & 0b1111
ofs = g.R[rm]
}
Expand Down
5 changes: 1 addition & 4 deletions pkg/gba/arm_shift.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,7 @@ func (g *GBA) armASR(val uint32, is uint32, carryMut bool, imm bool) uint32 {

func (g *GBA) armROR(val uint32, is uint32, carryMut bool, imm bool) uint32 {
if is == 0 && imm {
c := uint32(0)
if g.GetCPSRFlag(flagC) {
c = 1
}
c := g.Carry()
g.SetCPSRFlag(flagC, util.Bit(val, 0))
return util.ROR(((val & ^(uint32(1))) | c), 1)
}
Expand Down
17 changes: 7 additions & 10 deletions pkg/gba/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package gba

import (
"fmt"
"magia/pkg/gpu"
"magia/pkg/ram"
"magia/pkg/util"
"os"
Expand Down Expand Up @@ -53,24 +54,24 @@ func (g *GBA) breakpoint() {

func (g *GBA) thumbInst(inst uint16) {
if inst != 0 {
fmt.Printf("Thumb pc, inst, cycle: 0x%04x, 0x%02x, %d:%d\n", g.inst.loc, inst, g.line, g.cycle)
fmt.Printf("Thumb pc, inst, cycle: 0x%04x, 0x%02x, %d:%d\n", g.inst.loc, inst, g.GPU.IO[gpu.VCOUNT], g.cycle)
}
}

func (g *GBA) armInst(inst uint32) {
if inst != 0 {
fmt.Printf("ARM pc, inst, cycle: 0x%04x, 0x%04x, %d:%d\n", g.inst.loc, inst, g.line, g.cycle)
fmt.Printf("ARM pc, inst, cycle: 0x%04x, 0x%04x, %d:%d\n", g.inst.loc, inst, g.GPU.IO[gpu.VCOUNT], g.cycle)
}
}

func (g *GBA) printInst(inst uint32) {
if inst != 0 {
t := g.GetCPSRFlag(flagT)
if t {
fmt.Printf("Thumb pc, inst, cycle: 0x%04x, 0x%02x, %d:%d\n", g.inst.loc, inst, g.line, g.cycle)
fmt.Printf("Thumb pc, inst, cycle: 0x%04x, 0x%02x, %d:%d\n", g.inst.loc, inst, g.GPU.IO[gpu.VCOUNT], g.cycle)
return
}
fmt.Printf("ARM pc, inst, cycle: 0x%04x, 0x%04x, %d:%d\n", g.inst.loc, inst, g.line, g.cycle)
fmt.Printf("ARM pc, inst, cycle: 0x%04x, 0x%04x, %d:%d\n", g.inst.loc, inst, g.GPU.IO[gpu.VCOUNT], g.cycle)
}
}

Expand Down Expand Up @@ -221,12 +222,8 @@ func (g *GBA) outputCPUSet() string {
}
}

func (g *GBA) printPC() {
fmt.Printf(" PC: %04x\n", g.pipe.inst[0].loc)
}
func (g *GBA) PC() uint32 {
return g.inst.loc
}
func (g *GBA) printPC() { fmt.Printf(" PC: %04x\n", g.pipe.inst[0].loc) }
func (g *GBA) PC() uint32 { return g.inst.loc }

func (g *GBA) printIRQRegister() {
str := ` IME: %d IE: %02x IF: %02x
Expand Down
25 changes: 5 additions & 20 deletions pkg/gba/debug_decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,11 @@ func armDecodeBranch(pc, inst uint32) string {
case util.Bit(inst, 24):
nn := int32(inst)
nn = (nn << 8) >> 6
if nn >= 0 {
return fmt.Sprintf("bl 0x%08x", pc+8+uint32(nn))
} else {
return fmt.Sprintf("bl 0x%08x", pc+8-uint32(-nn))
}
return fmt.Sprintf("bl 0x%08x", util.AddInt32(pc+8, nn))
default:
nn := int32(inst)
nn = (nn << 8) >> 6
if nn >= 0 {
return fmt.Sprintf("b 0x%08x", pc+8+uint32(nn))
} else {
return fmt.Sprintf("b 0x%08x", pc+8-uint32(-nn))
}
return fmt.Sprintf("b 0x%08x", util.AddInt32(pc+8, nn))
}
}

Expand Down Expand Up @@ -218,7 +210,7 @@ func armDecodeMPY(inst uint32) string {
rd, rn, rs, rm := inst>>16&0b1111, inst>>12&0b1111, inst>>8&0b1111, inst&0b1111
return fmt.Sprintf("mla r%d,r%d,r%d,r%d", rd, rm, rs, rn)
case 0b0010:
return fmt.Sprintf("UMAAL is unsupported")
return "UMAAL is unsupported"
case 0b0100:
rdHi, rdLo, rs, rm := inst>>16&0b1111, inst>>12&0b1111, inst>>8&0b1111, inst&0b1111
return fmt.Sprintf("umull r%d,r%d,r%d,r%d", rdLo, rdHi, rm, rs)
Expand Down Expand Up @@ -248,15 +240,8 @@ func armDecodeALU(inst uint32) string {
is := (inst >> 7) & 0b11111
rm := inst & 0b1111

shift := "lsl"
switch shiftType := (inst >> 5) & 0b11; shiftType {
case lsr:
shift = "lsr"
case asr:
shift = "asr"
case ror:
shift = "ror"
}
shiftType := (inst >> 5) & 0b11
shift := [4]string{"lsl", "lsr", "asr", "ror"}[shiftType]

isRegister := (inst>>4)&0b1 > 0
if isRegister {
Expand Down
8 changes: 2 additions & 6 deletions pkg/gba/debug_gpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,8 @@ import (
"magia/pkg/ram"
)

func (g *GBA) printBGMap(bg int) {
g.GPU.PrintBGMap(bg)
}
func (g *GBA) printPalette() {
g.GPU.PrintPalette()
}
func (g *GBA) printBGMap(bg int) { g.GPU.PrintBGMap(bg) }
func (g *GBA) printPalette() { g.GPU.PrintPalette() }
func (g *GBA) printLCD() {
str := ` dispcnt: 0x%04x dispstat: 0x%04x LY: %d
`
Expand Down
8 changes: 4 additions & 4 deletions pkg/gba/dma.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ func (g *GBA) dmaTransfer(t dmaTiming) {
for ch.count > 0 {
switch size {
case 16:
g.setRAM16(ch.dst, uint16(g.getRAM16(ch.src, true)), true)
g._setRAM(ch.dst, g._getRAM(ch.src), 2)
case 32:
g.setRAM32(ch.dst, g.getRAM32(ch.src, true), true)
g._setRAM(ch.dst, g._getRAM(ch.src), 4)
}

ch.dst, ch.src = uint32(int64(ch.dst)+dstInc), uint32(int64(ch.src)+srcInc)
Expand Down Expand Up @@ -141,8 +141,8 @@ func (g *GBA) dmaTransferFifo(ch int) {
// 32bit × 4 = 4 words
cnt := g.dma[ch].cnt()
for i := 0; i < 4; i++ {
val := g.getRAM32(g.dma[ch].src, true)
g.setRAM32(g.dma[ch].dst, val, true)
val := g._getRAM(g.dma[ch].src)
g._setRAM(g.dma[ch].dst, val, 4)

if ch == 1 {
g.fifoACopy(val)
Expand Down
23 changes: 10 additions & 13 deletions pkg/gba/gba.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ type GBA struct {
inst Inst
cycle int
Frame uint
line int
halt bool
pipe Pipe
timers Timers
Expand Down Expand Up @@ -173,7 +172,7 @@ func (g *GBA) exception(addr uint32, mode Mode) {

// Update GBA by 1 frame
func (g *GBA) Update() {
g.line, g.GPU.IO[gpu.VCOUNT] = 0, 0
g.GPU.IO[gpu.VCOUNT] = 0

// line 0~159
for y := 0; y < 160; y++ {
Expand Down Expand Up @@ -207,6 +206,13 @@ func (g *GBA) Update() {

func (g *GBA) scanline() {
dispstat := uint16(g._getRAM(ram.DISPSTAT))
vCount, lyc := g.GPU.IO[gpu.VCOUNT], byte(g._getRAM(ram.DISPSTAT+1))
if vCount == lyc {
if util.Bit(dispstat, 5) {
g.triggerIRQ(irqVCount)
}
}

g.exec(1006)

// HBlank
Expand All @@ -222,20 +228,11 @@ func (g *GBA) scanline() {
g.soundClock(1232)
g.GPU.SetHBlank(false)

vCount, lyc := g.GPU.IncrementVCount(), byte(g._getRAM(ram.DISPSTAT+1))
if vCount == lyc {
if util.Bit(dispstat, 5) {
g.triggerIRQ(irqVCount)
}
}

g.line++
g.GPU.IO[gpu.VCOUNT]++ // increment vcount
}

// Draw GBA screen by 1 frame
func (g *GBA) Draw() *image.RGBA {
return g.GPU.Draw()
}
func (g *GBA) Draw() *image.RGBA { return g.GPU.Draw() }

func (g *GBA) checkIRQ() {
cond1 := !g.GetCPSRFlag(flagI)
Expand Down
5 changes: 2 additions & 3 deletions pkg/gba/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,12 @@ func (g *GBA) _setRAM(addr uint32, val uint32, width int) {
}
case addr == ram.SOUNDCNT_H:
for i := uint32(0); i < uint32(width); i++ {
g.RAM.Set8(addr+i, byte(val>>(8*i)))
g.RAM.IO[ram.IOOffset(addr+i)] = byte(val >> (8 * i))
}
if util.Bit(val, 11) {
fifoA = [32]int8{}
fifoALen = 0
}
if util.Bit(val, 15) {
fifoB = [32]int8{}
fifoBLen = 0
}
case addr == ram.SOUNDCNT_X:
Expand All @@ -133,6 +131,7 @@ func (g *GBA) _setRAM(addr uint32, val uint32, width int) {
for i := uint32(0x4000060); i <= 0x4000081; i++ {
g.RAM.IO[ram.IOOffset(i)] = 0
}
g.RAM.IO[ram.IOOffset(addr)] = 0
}
case g.in(addr, ram.WAVE_RAM, ram.WAVE_RAM+0xf): // wave ram
for i := uint32(0); i < uint32(width); i++ {
Expand Down
24 changes: 5 additions & 19 deletions pkg/gba/thumb.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,7 @@ func (g *GBA) thumbShift(inst uint16) {
case 2:
g.R[rd] = g.armASR(g.R[rs], is, true, true)
}

g.SetCPSRFlag(flagZ, g.R[rd] == 0)
g.SetCPSRFlag(flagN, util.Bit(g.R[rd], 31))
g.armLogicSet(uint32(rd), true, g.R[rd], false)
}

func (g *GBA) thumbAddSub(inst uint16) {
Expand Down Expand Up @@ -211,22 +209,12 @@ func (g *GBA) thumbALU(inst uint16) {
}
}

func (g *GBA) thumbHiRegisterBXOperand(r uint16) uint32 {
if r == 15 {
return g.inst.loc + 4
}
return g.R[r]
}

func (g *GBA) thumbHiRegisterBX(inst uint16) {
rs, rd := (inst>>3)&0b111, inst&0b111
rs, rd := (inst>>3)&0b1111, inst&0b111
if util.Bit(inst, 7) {
rd += 8
}
if util.Bit(inst, 6) {
rs += 8
}
rsval, rdval := g.thumbHiRegisterBXOperand(rs), g.thumbHiRegisterBXOperand(rd)
rsval, rdval := g.R[rs], g.R[rd]

opcode := (inst >> 8) & 0b11
switch opcode {
Expand Down Expand Up @@ -457,15 +445,13 @@ func (g *GBA) thumbSWI(inst uint16) {
}

func (g *GBA) thumbB(inst uint16) {
nn := int32(inst)
nn = (nn << 21) >> 20
nn := (int32(inst) << 21) >> 20
g.R[15] = util.AddInt32(g.inst.loc+4, nn)
g.pipelining()
}

func (g *GBA) thumbLinkBranch1(inst uint16) {
nn := int32(inst)
nn = (nn << 21) >> 9
nn := (int32(inst) << 21) >> 9
g.R[14] = g.inst.loc + 4
g.R[14] = util.AddInt32(g.R[14], nn)
}
Expand Down
Loading

0 comments on commit ef72fbf

Please sign in to comment.