@@ 1,11 1,14 @@
#include "pd_api.h"
#include "uxn.h"
+#include "devices/apu.h"
#include "devices/ppu.h"
+#define POLYPHONY 4
#define BOOT_ROM_FILENAME "boot.rom"
static PlaydateAPI *pd = NULL;
-
+static SoundSource *apu_sources[POLYPHONY];
+static Apu apu[POLYPHONY];
Uxn u;
Ppu ppu;
@@ 102,6 105,27 @@ screen_deo(Uint8 *d, Uint8 port)
}
}
+void
+audio_deo(Uint8 *d, Uint8 port){
+ /* TODO
+ Apu *c = &apu[d - devaudio0];
+ if(!w) {
+ if(b0 == 0x2) {
+ d->dat[0x2] = 0x0;
+ poke16(d->dat, 0x2, c->i); }
+ else if(b0 == 0x4)
+ d->dat[0x4] = apu_get_vu(c);
+ } else if(b0 == 0xf) {
+ c->len = PEEK16(d->dat, 0xa);
+ c->addr = PEEK16(d->dat, 0xc);
+ c->volume[0] = d->dat[0xe] >> 4;
+ c->volume[1] = d->dat[0xe] & 0xf;
+ c->repeat = !(d->dat[0xf] & 0x80);
+ apu_start(c, PEEK16(d->dat, 0x8), d->dat[0xf] & 0x7f);
+ }
+ */
+}
+
static Uint8
emu_dei(Uxn *u, Uint8 addr)
{
@@ 121,6 145,7 @@ emu_deo(Uxn *u, Uint8 addr, Uint8 v)
switch(d) {
case 0x10: console_deo(&u->dev[d], p); break;
case 0x20: screen_deo(&u->dev[d], p); break;
+ case 0x30: audio_deo(&u->dev[d], p); break;
}
}
@@ 137,6 162,24 @@ emu_start(Uxn *u, char *filename)
return 1;
}
+static int
+audio_callback(void *context, int16_t *left, int16_t *right, int len)
+{
+ return apu_render((Apu *)context, u.ram, left, right, len);
+}
+
+static int
+apu_init(void)
+{
+ int i;
+ SoundChannel *ch = pd->sound->getDefaultChannel();
+ for(i = 0; i < POLYPHONY; ++i)
+ apu_sources[i] = pd->sound->channel->addCallbackSource(ch, audio_callback, &apu[i], 1);
+ pd->sound->channel->setVolume(ch, 1.0);
+ pd->sound->channel->setPan(ch, 0.0);
+ return 1;
+}
+
/* Lua */
static int
@@ 224,8 267,11 @@ eventHandler(PlaydateAPI *playdate, PDSystemEvent event, uint32_t arg)
pd->display->setScale(1);
pd->graphics->clear(kColorBlack);
memset(&ppu, 0, sizeof(ppu));
+ memset(&apu, 0, sizeof(apu));
+ if(!apu_init())
+ return emu_error("APU", "Start failed.");
if(!ppu_init(&ppu, (uint32_t *)pd->graphics->getFrame()))
- return emu_error("Screen", "Start failed.");
+ return emu_error("PPU", "Start failed.");
if(!emu_start(&u, BOOT_ROM_FILENAME))
return emu_error("Emulator", "Start failed.");
} else if(event == kEventInitLua) {