From 3439fa5bf41eb9a8f71e73938ff209804e54eb84 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Mon, 30 Sep 2013 01:23:58 -0700 Subject: [PATCH] Start audio --- src/gba/gba-audio.c | 72 ++++++++++++++++++++++++ src/gba/gba-audio.h | 132 ++++++++++++++++++++++++++++++++++++++++++++ src/gba/gba-io.c | 77 ++++++++++++++++++++++++++ src/gba/gba.c | 3 + src/gba/gba.h | 2 + 5 files changed, 286 insertions(+) create mode 100644 src/gba/gba-audio.c create mode 100644 src/gba/gba-audio.h diff --git a/src/gba/gba-audio.c b/src/gba/gba-audio.c new file mode 100644 index 000000000..e2a46164c --- /dev/null +++ b/src/gba/gba-audio.c @@ -0,0 +1,72 @@ +#include "gba-audio.h" + +#include "gba.h" + +void GBAAudioInit(struct GBAAudio* audio) { + (void)(audio); +} + +void GBAAudioDeinit(struct GBAAudio* audio) { + (void)(audio); +} + +void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value) { + audio->ch1.sweep.packed = value; +} + +void GBAAudioWriteSOUND1CNT_HI(struct GBAAudio* audio, uint16_t value) { + audio->ch1.wave.packed = value; +} + +void GBAAudioWriteSOUND1CNT_X(struct GBAAudio* audio, uint16_t value) { + audio->ch1.control.packed = value; +} + +void GBAAudioWriteSOUND2CNT_LO(struct GBAAudio* audio, uint16_t value) { + audio->ch2.wave.packed = value; +} + +void GBAAudioWriteSOUND2CNT_HI(struct GBAAudio* audio, uint16_t value) { + audio->ch2.control.packed = value; +} + +void GBAAudioWriteSOUND3CNT_LO(struct GBAAudio* audio, uint16_t value) { + audio->ch3.bank.packed = value; +} + +void GBAAudioWriteSOUND3CNT_HI(struct GBAAudio* audio, uint16_t value) { + audio->ch3.wave.packed = value; +} + +void GBAAudioWriteSOUND3CNT_X(struct GBAAudio* audio, uint16_t value) { + audio->ch3.control.packed = value; +} + +void GBAAudioWriteSOUND4CNT_LO(struct GBAAudio* audio, uint16_t value) { + audio->ch4.wave.packed = value; +} + +void GBAAudioWriteSOUND4CNT_HI(struct GBAAudio* audio, uint16_t value) { + audio->ch4.control.packed = value; +} + +void GBAAudioWriteSOUNDCNT_LO(struct GBAAudio* audio, uint16_t value) { + GBALog(audio->p, GBA_LOG_STUB, "Audio unimplemented"); +} + +void GBAAudioWriteSOUNDCNT_HI(struct GBAAudio* audio, uint16_t value) { + GBALog(audio->p, GBA_LOG_STUB, "Audio unimplemented"); +} + +void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value) { + GBALog(audio->p, GBA_LOG_STUB, "Audio unimplemented"); +} + +void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value) { + GBALog(audio->p, GBA_LOG_STUB, "Audio unimplemented"); +} + +void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value) { + GBALog(audio->p, GBA_LOG_STUB, "Audio unimplemented"); +} + diff --git a/src/gba/gba-audio.h b/src/gba/gba-audio.h new file mode 100644 index 000000000..fccb21b26 --- /dev/null +++ b/src/gba/gba-audio.h @@ -0,0 +1,132 @@ +#ifndef GBA_AUDIO_H +#define GBA_AUDIO_H + +#include + +union GBAAudioWave { + struct { + unsigned length : 6; + unsigned duty : 2; + unsigned stepTime : 3; + unsigned direction : 1; + unsigned initialVolume : 4; + }; + uint16_t packed; +}; + +union GBAAudioSquareControl { + struct { + unsigned frequency : 11; + unsigned : 3; + unsigned stop : 1; + unsigned restart : 1; + }; + uint16_t packed; +}; + +struct GBAAudioChannel1 { + union GBAAudioSquareSweep { + struct { + unsigned shift : 3; + unsigned direction : 1; + unsigned time : 3; + unsigned : 9; + }; + uint16_t packed; + } sweep; + + union GBAAudioWave wave; + union GBAAudioSquareControl control; +}; + +struct GBAAudioChannel2 { + union GBAAudioWave wave; + union GBAAudioSquareControl control; +}; + +struct GBAAudioChannel3 { + union { + struct { + unsigned : 5; + unsigned size : 1; + unsigned bank : 1; + unsigned disable : 1; + unsigned : 7; + }; + uint16_t packed; + } bank; + + union { + struct { + unsigned length : 8; + unsigned : 5; + unsigned volume : 3; + unsigned disable : 1; + unsigned : 7; + }; + uint16_t packed; + } wave; + + union { + struct { + unsigned rate : 11; + unsigned : 3; + unsigned stop : 1; + unsigned restart : 1; + }; + uint16_t packed; + } control; +}; + +struct GBAAudioChannel4 { + union GBAAudioWave wave; + union { + struct { + unsigned ratio : 3; + unsigned power : 1; + unsigned frequency : 4; + unsigned : 6; + unsigned stop : 1; + unsigned restart : 1; + }; + uint16_t packed; + } control; +}; + +struct GBAAudioFIFO { + +}; + +struct GBAAudio { + struct GBA* p; + + struct GBAAudioChannel1 ch1; + struct GBAAudioChannel2 ch2; + struct GBAAudioChannel3 ch3; + struct GBAAudioChannel4 ch4; + + struct GBAAudioFIFO chA; + struct GBAAudioFIFO chB; +}; + +void GBAAudioInit(struct GBAAudio* audio); +void GBAAudioDeinit(struct GBAAudio* audio); + +void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value); +void GBAAudioWriteSOUND1CNT_HI(struct GBAAudio* audio, uint16_t value); +void GBAAudioWriteSOUND1CNT_X(struct GBAAudio* audio, uint16_t value); +void GBAAudioWriteSOUND2CNT_LO(struct GBAAudio* audio, uint16_t value); +void GBAAudioWriteSOUND2CNT_HI(struct GBAAudio* audio, uint16_t value); +void GBAAudioWriteSOUND3CNT_LO(struct GBAAudio* audio, uint16_t value); +void GBAAudioWriteSOUND3CNT_HI(struct GBAAudio* audio, uint16_t value); +void GBAAudioWriteSOUND3CNT_X(struct GBAAudio* audio, uint16_t value); +void GBAAudioWriteSOUND4CNT_LO(struct GBAAudio* audio, uint16_t value); +void GBAAudioWriteSOUND4CNT_HI(struct GBAAudio* audio, uint16_t value); +void GBAAudioWriteSOUNDCNT_LO(struct GBAAudio* audio, uint16_t value); +void GBAAudioWriteSOUNDCNT_HI(struct GBAAudio* audio, uint16_t value); +void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value); + +void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value); +void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value); + +#endif diff --git a/src/gba/gba-io.c b/src/gba/gba-io.c index 34275718a..524814745 100644 --- a/src/gba/gba-io.c +++ b/src/gba/gba-io.c @@ -17,6 +17,65 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) { GBAVideoWriteDISPSTAT(&gba->video, value); break; + // Audio + case REG_SOUND1CNT_LO: + GBAAudioWriteSOUND1CNT_LO(&gba->audio, value); + break; + case REG_SOUND1CNT_HI: + GBAAudioWriteSOUND1CNT_HI(&gba->audio, value); + break; + case REG_SOUND1CNT_X: + GBAAudioWriteSOUND1CNT_X(&gba->audio, value); + break; + case REG_SOUND2CNT_LO: + GBAAudioWriteSOUND2CNT_LO(&gba->audio, value); + break; + case REG_SOUND2CNT_HI: + GBAAudioWriteSOUND2CNT_HI(&gba->audio, value); + break; + case REG_SOUND3CNT_LO: + GBAAudioWriteSOUND3CNT_LO(&gba->audio, value); + break; + case REG_SOUND3CNT_HI: + GBAAudioWriteSOUND3CNT_HI(&gba->audio, value); + break; + case REG_SOUND3CNT_X: + GBAAudioWriteSOUND3CNT_X(&gba->audio, value); + break; + case REG_SOUND4CNT_LO: + GBAAudioWriteSOUND4CNT_LO(&gba->audio, value); + break; + case REG_SOUND4CNT_HI: + GBAAudioWriteSOUND4CNT_HI(&gba->audio, value); + break; + case REG_SOUNDCNT_LO: + GBAAudioWriteSOUNDCNT_LO(&gba->audio, value); + break; + case REG_SOUNDCNT_HI: + GBAAudioWriteSOUNDCNT_HI(&gba->audio, value); + break; + case REG_SOUNDCNT_X: + GBAAudioWriteSOUNDCNT_X(&gba->audio, value); + break; + + case REG_WAVE_RAM0_LO: + case REG_WAVE_RAM1_LO: + case REG_WAVE_RAM2_LO: + case REG_WAVE_RAM3_LO: + case REG_FIFO_A_LO: + case REG_FIFO_B_LO: + GBAIOWrite32(gba, address, (gba->memory.io[(address >> 1) + 1] << 16) | value); + break; + + case REG_WAVE_RAM0_HI: + case REG_WAVE_RAM1_HI: + case REG_WAVE_RAM2_HI: + case REG_WAVE_RAM3_HI: + case REG_FIFO_A_HI: + case REG_FIFO_B_HI: + GBAIOWrite32(gba, address - 2, gba->memory.io[(address >> 1) - 1] | (value << 16)); + break; + // DMA case REG_DMA0SAD_LO: case REG_DMA0DAD_LO: @@ -137,6 +196,24 @@ void GBAIOWrite8(struct GBA* gba, uint32_t address, uint8_t value) { void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) { switch (address) { + case REG_WAVE_RAM0_LO: + GBAAudioWriteWaveRAM(&gba->audio, 0, value); + break; + case REG_WAVE_RAM1_LO: + GBAAudioWriteWaveRAM(&gba->audio, 1, value); + break; + case REG_WAVE_RAM2_LO: + GBAAudioWriteWaveRAM(&gba->audio, 2, value); + break; + case REG_WAVE_RAM3_LO: + GBAAudioWriteWaveRAM(&gba->audio, 3, value); + break; + case REG_FIFO_A_LO: + GBAAudioWriteFIFO(&gba->audio, 0, value); + break; + case REG_FIFO_B_LO: + GBAAudioWriteFIFO(&gba->audio, 1, value); + break; case REG_DMA0SAD_LO: GBAMemoryWriteDMASAD(&gba->memory, 0, value); break; diff --git a/src/gba/gba.c b/src/gba/gba.c index ebcbf30d9..aaadcfa7d 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -40,6 +40,9 @@ void GBAInit(struct GBA* gba) { gba->video.p = gba; GBAVideoInit(&gba->video); + gba->audio.p = gba; + GBAAudioInit(&gba->audio); + GBAIOInit(gba); memset(gba->timers, 0, sizeof(gba->timers)); diff --git a/src/gba/gba.h b/src/gba/gba.h index 14e81de50..9cdf3fb5e 100644 --- a/src/gba/gba.h +++ b/src/gba/gba.h @@ -5,6 +5,7 @@ #include "gba-memory.h" #include "gba-video.h" +#include "gba-audio.h" enum GBAIRQ { IRQ_VBLANK = 0x0, @@ -61,6 +62,7 @@ struct GBA { struct GBABoard board; struct GBAMemory memory; struct GBAVideo video; + struct GBAAudio audio; struct ARMDebugger* debugger;