mirror of https://github.com/mgba-emu/mgba.git
Start audio
This commit is contained in:
parent
25885e1e82
commit
3439fa5bf4
|
@ -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");
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
#ifndef GBA_AUDIO_H
|
||||||
|
#define GBA_AUDIO_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
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
|
|
@ -17,6 +17,65 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
|
||||||
GBAVideoWriteDISPSTAT(&gba->video, value);
|
GBAVideoWriteDISPSTAT(&gba->video, value);
|
||||||
break;
|
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
|
// DMA
|
||||||
case REG_DMA0SAD_LO:
|
case REG_DMA0SAD_LO:
|
||||||
case REG_DMA0DAD_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) {
|
void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) {
|
||||||
switch (address) {
|
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:
|
case REG_DMA0SAD_LO:
|
||||||
GBAMemoryWriteDMASAD(&gba->memory, 0, value);
|
GBAMemoryWriteDMASAD(&gba->memory, 0, value);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -40,6 +40,9 @@ void GBAInit(struct GBA* gba) {
|
||||||
gba->video.p = gba;
|
gba->video.p = gba;
|
||||||
GBAVideoInit(&gba->video);
|
GBAVideoInit(&gba->video);
|
||||||
|
|
||||||
|
gba->audio.p = gba;
|
||||||
|
GBAAudioInit(&gba->audio);
|
||||||
|
|
||||||
GBAIOInit(gba);
|
GBAIOInit(gba);
|
||||||
|
|
||||||
memset(gba->timers, 0, sizeof(gba->timers));
|
memset(gba->timers, 0, sizeof(gba->timers));
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "gba-memory.h"
|
#include "gba-memory.h"
|
||||||
#include "gba-video.h"
|
#include "gba-video.h"
|
||||||
|
#include "gba-audio.h"
|
||||||
|
|
||||||
enum GBAIRQ {
|
enum GBAIRQ {
|
||||||
IRQ_VBLANK = 0x0,
|
IRQ_VBLANK = 0x0,
|
||||||
|
@ -61,6 +62,7 @@ struct GBA {
|
||||||
struct GBABoard board;
|
struct GBABoard board;
|
||||||
struct GBAMemory memory;
|
struct GBAMemory memory;
|
||||||
struct GBAVideo video;
|
struct GBAVideo video;
|
||||||
|
struct GBAAudio audio;
|
||||||
|
|
||||||
struct ARMDebugger* debugger;
|
struct ARMDebugger* debugger;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue