WIP add GBA system

This commit is contained in:
Natt Akuma 2024-01-10 11:17:36 +07:00
parent 892ee12d91
commit f3705fb435
22 changed files with 748 additions and 49 deletions

View file

@ -64,13 +64,15 @@ const char** DivPlatformGB::getRegisterSheet() {
void DivPlatformGB::acquire(short** buf, size_t len) {
for (size_t i=0; i<len; i++) {
if (!writes.empty()) {
QueuedWrite& w=writes.front();
GB_apu_write(gb,w.addr,w.val);
writes.pop();
}
for (int j=0; j<(1<<(outDepth-6)); j++) {
if (!writes.empty()) {
QueuedWrite& w=writes.front();
GB_apu_write(gb,w.addr,w.val);
writes.pop();
}
GB_advance_cycles(gb,16);
GB_advance_cycles(gb,16);
}
buf[0][i]=gb->apu_output.final_sample.left;
buf[1][i]=gb->apu_output.final_sample.right;
@ -81,17 +83,41 @@ void DivPlatformGB::acquire(short** buf, size_t len) {
}
void DivPlatformGB::updateWave() {
rWrite(0x1a,0);
for (int i=0; i<16; i++) {
int nibble1=ws.output[((i<<1)+antiClickWavePos)&31];
int nibble2=ws.output[((1+(i<<1))+antiClickWavePos)&31];
if (invertWave) {
nibble1^=15;
nibble2^=15;
if (doubleWave) {
rWrite(0x1a,0x40); // select 1 -> write to bank 0
for (int i=0; i<16; i++) {
int nibble1=ws.output[((i<<1)+antiClickWavePos)&63];
int nibble2=ws.output[((1+(i<<1))+antiClickWavePos)&63];
if (invertWave) {
nibble1^=15;
nibble2^=15;
}
rWrite(0x30+i,(nibble1<<4)|nibble2);
}
rWrite(0x30+i,(nibble1<<4)|nibble2);
rWrite(0x1a,0); // select 0 -> write to bank 1
for (int i=0; i<16; i++) {
int nibble1=ws.output[((32+(i<<1))+antiClickWavePos)&63];
int nibble2=ws.output[((33+(i<<1))+antiClickWavePos)&63];
if (invertWave) {
nibble1^=15;
nibble2^=15;
}
rWrite(0x30+i,(nibble1<<4)|nibble2);
}
antiClickWavePos&=63;
} else {
rWrite(0x1a,extendWave?0x40:0);
for (int i=0; i<16; i++) {
int nibble1=ws.output[((i<<1)+antiClickWavePos)&31];
int nibble2=ws.output[((1+(i<<1))+antiClickWavePos)&31];
if (invertWave) {
nibble1^=15;
nibble2^=15;
}
rWrite(0x30+i,(nibble1<<4)|nibble2);
}
antiClickWavePos&=31;
}
antiClickWavePos&=31;
}
static unsigned char chanMuteMask[4]={
@ -112,6 +138,13 @@ static unsigned char gbVolMap[16]={
0x20, 0x20, 0x20, 0x20
};
static unsigned char gbVolMapEx[16]={
0x00, 0x00, 0x00, 0x00,
0x60, 0x60, 0x60, 0x60,
0x40, 0x40, 0x40, 0x40,
0xa0, 0xa0, 0x20, 0x20
};
static unsigned char noiseTable[256]={
0,
0xf7, 0xf6, 0xf5, 0xf4,
@ -156,7 +189,7 @@ void DivPlatformGB::tick(bool sysTick) {
if (chan[i].outVol<0) chan[i].outVol=0;
if (i==2) {
rWrite(16+i*5+2,gbVolMap[chan[i].outVol]);
rWrite(16+i*5+2,(extendWave?gbVolMapEx:gbVolMap)[chan[i].outVol]);
chan[i].soundLen=64;
} else {
chan[i].envLen=0;
@ -188,7 +221,7 @@ void DivPlatformGB::tick(bool sysTick) {
rWrite(16+i*5+1,((chan[i].duty&3)<<6)|(63-(chan[i].soundLen&63)));
} else if (!chan[i].softEnv) {
if (parent->song.waveDutyIsVol) {
rWrite(16+i*5+2,gbVolMap[(chan[i].std.duty.val&3)<<2]);
rWrite(16+i*5+2,(extendWave?gbVolMapEx:gbVolMap)[(chan[i].std.duty.val&3)<<2]);
}
}
}
@ -301,8 +334,8 @@ void DivPlatformGB::tick(bool sysTick) {
if (chan[i].keyOn) {
if (i==2) { // wave
rWrite(16+i*5,0x00);
rWrite(16+i*5,0x80);
rWrite(16+i*5+2,gbVolMap[chan[i].outVol]);
rWrite(16+i*5,doubleWave?0xa0:0x80);
rWrite(16+i*5+2,(extendWave?gbVolMapEx:gbVolMap)[chan[i].outVol]);
} else {
rWrite(16+i*5+1,((chan[i].duty&3)<<6)|(63-(chan[i].soundLen&63)));
rWrite(16+i*5+2,((chan[i].envVol<<4))|(chan[i].envLen&7)|((chan[i].envDir&1)<<3));
@ -379,11 +412,16 @@ int DivPlatformGB::dispatch(DivCommand c) {
chan[c.chan].softEnv=ins->gb.softEnv;
chan[c.chan].macroInit(ins);
if (c.chan==2) {
doubleWave=extendWave&&ins->gb.doubleWave;
if (chan[c.chan].wave<0) {
chan[c.chan].wave=0;
ws.changeWave1(chan[c.chan].wave);
}
ws.init(ins,32,15,chan[c.chan].insChanged);
ws.init(ins,doubleWave?64:32,15,chan[c.chan].insChanged);
if (doubleWave!=lastDoubleWave) {
ws.changeWave1(chan[c.chan].wave);
lastDoubleWave=doubleWave;
}
}
if ((chan[c.chan].insChanged || ins->gb.alwaysInit) && !chan[c.chan].softEnv) {
if (!chan[c.chan].soManyHacksToMakeItDefleCompatible && c.chan!=2) {
@ -447,7 +485,7 @@ int DivPlatformGB::dispatch(DivCommand c) {
chan[c.chan].vol=c.value;
chan[c.chan].outVol=c.value;
if (c.chan==2) {
rWrite(16+c.chan*5+2,gbVolMap[chan[c.chan].outVol]);
rWrite(16+c.chan*5+2,(extendWave?gbVolMapEx:gbVolMap)[chan[c.chan].outVol]);
}
if (!chan[c.chan].softEnv) {
chan[c.chan].envVol=chan[c.chan].vol;
@ -619,6 +657,8 @@ void DivPlatformGB::reset() {
antiClickPeriodCount=0;
antiClickWavePos=0;
doubleWave=false;
lastDoubleWave=false;
}
int DivPlatformGB::getPortaFloor(int ch) {
@ -665,6 +705,8 @@ void DivPlatformGB::poke(std::vector<DivRegWrite>& wlist) {
void DivPlatformGB::setFlags(const DivConfig& flags) {
antiClickEnabled=!flags.getBool("noAntiClick",false);
extendWave=flags.getBool("extendWave",false);
outDepth=flags.getInt("dacDepth",9);
switch (flags.getInt("chipType",0)) {
case 0:
model=GB_MODEL_DMG_B;
@ -676,7 +718,7 @@ void DivPlatformGB::setFlags(const DivConfig& flags) {
model=GB_MODEL_CGB_E;
break;
case 3:
model=GB_MODEL_AGB;
model=extendWave?GB_MODEL_AGB_NATIVE:GB_MODEL_AGB;
break;
}
invertWave=flags.getBool("invertWave",true);
@ -684,7 +726,7 @@ void DivPlatformGB::setFlags(const DivConfig& flags) {
chipClock=4194304;
CHECK_CUSTOM_CLOCK;
rate=chipClock/16;
rate=chipClock>>(outDepth-2);
for (int i=0; i<4; i++) {
oscBuf[i]->rate=rate;
}