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);
|
||||
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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue