From 5f2cfd4854f0ecd7308360ca79e0e88977afd720 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 11 Aug 2023 23:58:44 -0500 Subject: [PATCH] AY: don't use bit arrays issue #649 --- src/engine/platform/ay.cpp | 44 ++++++++++++++++++-------------- src/engine/platform/ay.h | 26 ++++++++----------- src/engine/platform/ay8930.cpp | 46 ++++++++++++++++++++-------------- src/engine/platform/ay8930.h | 26 ++++++++----------- src/gui/debug.cpp | 27 -------------------- 5 files changed, 74 insertions(+), 95 deletions(-) diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index 5d9a5593..9a171176 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -115,7 +115,7 @@ const unsigned char dacLogTableAY[256]={ void DivPlatformAY8910::runDAC() { for (int i=0; i<3; i++) { - if (chan[i].active && chan[i].curPSGMode.dac && chan[i].dac.sample!=-1) { + if (chan[i].active && (chan[i].curPSGMode.val&8) && chan[i].dac.sample!=-1) { chan[i].dac.period+=chan[i].dac.rate; bool end=false; bool changed=false; @@ -243,7 +243,7 @@ void DivPlatformAY8910::tick(bool sysTick) { if (chan[i].std.vol.had) { chan[i].outVol=MIN(15,chan[i].std.vol.val)-(15-(chan[i].vol&15)); if (chan[i].outVol<0) chan[i].outVol=0; - if (!chan[i].nextPSGMode.dac) { + if (!(chan[i].nextPSGMode.val&8)) { if (isMuted[i]) { rWrite(0x08+i,0); } else if (intellivision && (chan[i].nextPSGMode.getEnvelope())) { @@ -265,7 +265,7 @@ void DivPlatformAY8910::tick(bool sysTick) { rWrite(0x06,31-chan[i].std.duty.val); } if (chan[i].std.wave.had) { - if (!chan[i].nextPSGMode.dac) { + if (!(chan[i].nextPSGMode.val&8)) { chan[i].nextPSGMode.val=(chan[i].std.wave.val+1)&7; if (chan[i].active) { chan[i].curPSGMode.val=chan[i].nextPSGMode.val; @@ -290,7 +290,7 @@ void DivPlatformAY8910::tick(bool sysTick) { } if (chan[i].std.phaseReset.had) { if (chan[i].std.phaseReset.val==1) { - if (chan[i].nextPSGMode.dac) { + if (chan[i].nextPSGMode.val&8) { if (dumpWrites) addWrite(0xffff0002+(i<<8),0); if (chan[i].dac.sample<0 || chan[i].dac.sample>=parent->song.sampleLen) { if (dumpWrites) { @@ -340,7 +340,7 @@ void DivPlatformAY8910::tick(bool sysTick) { if (chan[i].keyOn) { //rWrite(16+i*5+1,((chan[i].duty&3)<<6)|(63-(ins->gb.soundLen&63))); //rWrite(16+i*5+2,((chan[i].vol<<4))|(ins->gb.envLen&7)|((ins->gb.envDir&1)<<3)); - if (!chan[i].nextPSGMode.dac) { + if (!(chan[i].nextPSGMode.val&8)) { chan[i].curPSGMode.val=chan[i].nextPSGMode.val; } } @@ -396,11 +396,11 @@ int DivPlatformAY8910::dispatch(DivCommand c) { case DIV_CMD_NOTE_ON: { DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AY); if (!parent->song.disableSampleMacro && (ins->type==DIV_INS_AMIGA || ins->amiga.useSample)) { - chan[c.chan].nextPSGMode.dac=true; + chan[c.chan].nextPSGMode.val|=8; } else if (chan[c.chan].dac.furnaceDAC) { - chan[c.chan].nextPSGMode.dac=false; + chan[c.chan].nextPSGMode.val&=~8; } - if (chan[c.chan].nextPSGMode.dac) { + if (chan[c.chan].nextPSGMode.val&8) { if (skipRegisterWrites) break; if (!parent->song.disableSampleMacro && (ins->type==DIV_INS_AMIGA || ins->amiga.useSample)) { if (c.value!=DIV_NOTE_NULL) { @@ -452,7 +452,8 @@ int DivPlatformAY8910::dispatch(DivCommand c) { } chan[c.chan].dac.furnaceDAC=false; } - chan[c.chan].curPSGMode.dac=chan[c.chan].nextPSGMode.dac; + chan[c.chan].curPSGMode.val&=~8; + chan[c.chan].curPSGMode.val|=chan[c.chan].nextPSGMode.val&8; break; } if (c.value!=DIV_NOTE_NULL) { @@ -466,7 +467,7 @@ int DivPlatformAY8910::dispatch(DivCommand c) { if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) { chan[c.chan].outVol=chan[c.chan].vol; } - if (!chan[c.chan].nextPSGMode.dac) { + if (!(chan[c.chan].nextPSGMode.val&8)) { if (isMuted[c.chan]) { rWrite(0x08+c.chan,0); } else if (intellivision && (chan[c.chan].nextPSGMode.getEnvelope())) { @@ -480,7 +481,7 @@ int DivPlatformAY8910::dispatch(DivCommand c) { case DIV_CMD_NOTE_OFF: chan[c.chan].dac.sample=-1; if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0); - chan[c.chan].nextPSGMode.dac=false; + chan[c.chan].nextPSGMode.val&=~8; chan[c.chan].keyOff=true; chan[c.chan].active=false; chan[c.chan].macroInit(NULL); @@ -494,7 +495,7 @@ int DivPlatformAY8910::dispatch(DivCommand c) { if (!chan[c.chan].std.vol.has) { chan[c.chan].outVol=c.value; } - if (!chan[c.chan].nextPSGMode.dac) { + if (!(chan[c.chan].nextPSGMode.val&8)) { if (isMuted[c.chan]) { rWrite(0x08+c.chan,0); } else { @@ -553,7 +554,7 @@ int DivPlatformAY8910::dispatch(DivCommand c) { break; } case DIV_CMD_STD_NOISE_MODE: - if (!chan[c.chan].nextPSGMode.dac) { + if (!(chan[c.chan].nextPSGMode.val&8)) { if (c.value<16) { chan[c.chan].nextPSGMode.val=(c.value+1)&7; if (chan[c.chan].active) { @@ -578,11 +579,11 @@ int DivPlatformAY8910::dispatch(DivCommand c) { ayEnvMode=c.value>>4; rWrite(0x0d,ayEnvMode); if (c.value&15) { - chan[c.chan].nextPSGMode.envelope|=1; + chan[c.chan].nextPSGMode.val|=4; } else { - chan[c.chan].nextPSGMode.envelope&=~1; + chan[c.chan].nextPSGMode.val&=~4; } - if (!chan[c.chan].nextPSGMode.dac && chan[c.chan].active) { + if (!(chan[c.chan].nextPSGMode.val&8) && chan[c.chan].active) { chan[c.chan].curPSGMode.val=chan[c.chan].nextPSGMode.val; } if (isMuted[c.chan]) { @@ -628,9 +629,14 @@ int DivPlatformAY8910::dispatch(DivCommand c) { immWrite(14+(c.value?1:0),(c.value?portBVal:portAVal)); break; case DIV_CMD_SAMPLE_MODE: - chan[c.chan].nextPSGMode.dac=(c.value>0)?1:0; + if (c.value>0) { + chan[c.chan].nextPSGMode.val|=8; + } else { + chan[c.chan].nextPSGMode.val&=~8; + } if (chan[c.chan].active) { - chan[c.chan].curPSGMode.dac=chan[c.chan].nextPSGMode.dac; + chan[c.chan].curPSGMode.val&=~8; + chan[c.chan].curPSGMode.val|=chan[c.chan].nextPSGMode.val&8; } break; case DIV_CMD_SAMPLE_BANK: @@ -673,7 +679,7 @@ void DivPlatformAY8910::muteChannel(int ch, bool mute) { isMuted[ch]=mute; if (isMuted[ch]) { rWrite(0x08+ch,0); - } else if (chan[ch].active && chan[ch].nextPSGMode.dac) { + } else if (chan[ch].active && (chan[ch].nextPSGMode.val&8)) { rWrite(0x08+ch,chan[ch].dac.out); } else { if (intellivision && (chan[ch].nextPSGMode.getEnvelope()) && chan[ch].active) { diff --git a/src/engine/platform/ay.h b/src/engine/platform/ay.h index 999db1e5..2948f3b8 100644 --- a/src/engine/platform/ay.h +++ b/src/engine/platform/ay.h @@ -31,29 +31,25 @@ class DivPlatformAY8910: public DivDispatch { inline unsigned char regRemap(unsigned char reg) { return intellivision?AY8914RegRemap[reg&0x0f]:reg&0x0f; } struct Channel: public SharedChannel { struct PSGMode { - union { - struct { - unsigned char tone: 1; - unsigned char noise: 1; - unsigned char envelope: 1; - unsigned char dac: 1; - }; - unsigned char val=1; - }; + // bit 3: DAC + // bit 2: envelope + // bit 1: noise + // bit 0: tone + unsigned char val; unsigned char getTone() { - return dac?0:(tone<<0); + return (val&8)?0:(val&1); } unsigned char getNoise() { - return dac?0:(noise<<1); + return (val&8)?0:(val&2); } unsigned char getEnvelope() { - return dac?0:(envelope<<2); + return (val&8)?0:(val&4); } - PSGMode(unsigned char v=0): + PSGMode(unsigned char v=1): val(v) {} }; PSGMode curPSGMode; @@ -61,7 +57,7 @@ class DivPlatformAY8910: public DivDispatch { struct DAC { int sample, rate, period, pos, out; - unsigned char furnaceDAC: 1; + bool furnaceDAC; DAC(): sample(-1), @@ -69,7 +65,7 @@ class DivPlatformAY8910: public DivDispatch { period(0), pos(0), out(0), - furnaceDAC(0) {} + furnaceDAC(false) {} } dac; unsigned char autoEnvNum, autoEnvDen; diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index 10421942..a337a2a3 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -111,7 +111,7 @@ const unsigned char dacLogTableAY8930[256]={ void DivPlatformAY8930::runDAC() { for (int i=0; i<3; i++) { - if (chan[i].active && chan[i].curPSGMode.dac && chan[i].dac.sample!=-1) { + if (chan[i].active && (chan[i].curPSGMode.val&8) && chan[i].dac.sample!=-1) { chan[i].dac.period+=chan[i].dac.rate; bool end=false; bool changed=false; @@ -235,7 +235,7 @@ void DivPlatformAY8930::tick(bool sysTick) { if (chan[i].std.vol.had) { chan[i].outVol=MIN(31,chan[i].std.vol.val)-(31-(chan[i].vol&31)); if (chan[i].outVol<0) chan[i].outVol=0; - if (!chan[i].nextPSGMode.dac) { + if (!(chan[i].nextPSGMode.val&8)) { if (isMuted[i]) { rWrite(0x08+i,0); } else { @@ -255,7 +255,7 @@ void DivPlatformAY8930::tick(bool sysTick) { rWrite(0x06,chan[i].std.duty.val); } if (chan[i].std.wave.had) { - if (!chan[i].nextPSGMode.dac) { + if (!(chan[i].nextPSGMode.val&8)) { chan[i].nextPSGMode.val=(chan[i].std.wave.val+1)&7; if (chan[i].active) { chan[i].curPSGMode.val=chan[i].nextPSGMode.val; @@ -278,7 +278,7 @@ void DivPlatformAY8930::tick(bool sysTick) { } if (chan[i].std.phaseReset.had) { if (chan[i].std.phaseReset.val==1) { - if (chan[i].nextPSGMode.dac) { + if (chan[i].nextPSGMode.val&8) { if (dumpWrites) addWrite(0xffff0002+(i<<8),0); if (chan[i].dac.sample<0 || chan[i].dac.sample>=parent->song.sampleLen) { if (dumpWrites) { @@ -337,7 +337,7 @@ void DivPlatformAY8930::tick(bool sysTick) { if (chan[i].freq<0) chan[i].freq=0; if (chan[i].freq>65535) chan[i].freq=65535; if (chan[i].keyOn) { - if (!chan[i].nextPSGMode.dac) { + if (!(chan[i].nextPSGMode.val&8)) { chan[i].curPSGMode.val=chan[i].nextPSGMode.val; } if (chan[i].insChanged) { @@ -397,11 +397,11 @@ int DivPlatformAY8930::dispatch(DivCommand c) { case DIV_CMD_NOTE_ON: { DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AY8930); if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) { - chan[c.chan].nextPSGMode.dac=true; + chan[c.chan].nextPSGMode.val|=8; } else if (chan[c.chan].dac.furnaceDAC) { - chan[c.chan].nextPSGMode.dac=false; + chan[c.chan].nextPSGMode.val&=~8; } - if (chan[c.chan].nextPSGMode.dac) { + if (chan[c.chan].nextPSGMode.val&8) { if (skipRegisterWrites) break; if (ins->type==DIV_INS_AMIGA || ins->amiga.useSample) { if (c.value!=DIV_NOTE_NULL) { @@ -453,7 +453,8 @@ int DivPlatformAY8930::dispatch(DivCommand c) { } chan[c.chan].dac.furnaceDAC=false; } - chan[c.chan].curPSGMode.dac=chan[c.chan].nextPSGMode.dac; + chan[c.chan].curPSGMode.val&=~8; + chan[c.chan].curPSGMode.val|=chan[c.chan].nextPSGMode.val&8; break; } if (c.value!=DIV_NOTE_NULL) { @@ -467,7 +468,7 @@ int DivPlatformAY8930::dispatch(DivCommand c) { if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) { chan[c.chan].outVol=chan[c.chan].vol; } - if (!chan[c.chan].nextPSGMode.dac) { + if (!(chan[c.chan].nextPSGMode.val&8)) { if (isMuted[c.chan]) { rWrite(0x08+c.chan,0); } else { @@ -479,7 +480,7 @@ int DivPlatformAY8930::dispatch(DivCommand c) { case DIV_CMD_NOTE_OFF: chan[c.chan].dac.sample=-1; if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0); - chan[c.chan].nextPSGMode.dac=false; + chan[c.chan].nextPSGMode.val&=~8; chan[c.chan].keyOff=true; chan[c.chan].active=false; chan[c.chan].macroInit(NULL); @@ -493,7 +494,7 @@ int DivPlatformAY8930::dispatch(DivCommand c) { if (!chan[c.chan].std.vol.has) { chan[c.chan].outVol=c.value; } - if (!chan[c.chan].nextPSGMode.dac) { + if (!(chan[c.chan].nextPSGMode.val&8)) { if (isMuted[c.chan]) { rWrite(0x08+c.chan,0); } else { @@ -548,7 +549,7 @@ int DivPlatformAY8930::dispatch(DivCommand c) { } case DIV_CMD_STD_NOISE_MODE: if (c.value<0x10) { - if (!chan[c.chan].nextPSGMode.dac) { + if (!(chan[c.chan].nextPSGMode.val&8)) { chan[c.chan].nextPSGMode.val=(c.value+1)&7; if (chan[c.chan].active) { chan[c.chan].curPSGMode.val=chan[c.chan].nextPSGMode.val; @@ -571,11 +572,11 @@ int DivPlatformAY8930::dispatch(DivCommand c) { chan[c.chan].envelope.mode=c.value>>4; rWrite(regMode[c.chan],chan[c.chan].envelope.mode); if (c.value&15) { - chan[c.chan].nextPSGMode.envelope|=1; + chan[c.chan].nextPSGMode.val|=4; } else { - chan[c.chan].nextPSGMode.envelope&=~1; + chan[c.chan].nextPSGMode.val&=~4; } - if (!chan[c.chan].nextPSGMode.dac && chan[c.chan].active) { + if (!(chan[c.chan].nextPSGMode.val&8) && chan[c.chan].active) { chan[c.chan].curPSGMode.val=chan[c.chan].nextPSGMode.val; } if (isMuted[c.chan]) { @@ -630,8 +631,15 @@ int DivPlatformAY8930::dispatch(DivCommand c) { immWrite(14+(c.value?1:0),(c.value?portBVal:portAVal)); break; case DIV_CMD_SAMPLE_MODE: - chan[c.chan].nextPSGMode.dac=(c.value>0)?1:0; - chan[c.chan].curPSGMode.dac=chan[c.chan].nextPSGMode.dac; + if (c.value>0) { + chan[c.chan].nextPSGMode.val|=8; + } else { + chan[c.chan].nextPSGMode.val&=~8; + } + if (chan[c.chan].active) { + chan[c.chan].curPSGMode.val&=~8; + chan[c.chan].curPSGMode.val|=chan[c.chan].nextPSGMode.val&8; + } break; case DIV_CMD_SAMPLE_BANK: sampleBank=c.value; @@ -672,7 +680,7 @@ void DivPlatformAY8930::muteChannel(int ch, bool mute) { if (isMuted[ch]) { rWrite(0x08+ch,0); } else if (chan[ch].active) { - if (chan[ch].nextPSGMode.dac) { + if (chan[ch].nextPSGMode.val&8) { rWrite(0x08+ch,chan[ch].dac.out&31); } else { rWrite(0x08+ch,(chan[ch].outVol&31)|((chan[ch].nextPSGMode.getEnvelope())<<3)); diff --git a/src/engine/platform/ay8930.h b/src/engine/platform/ay8930.h index 113aed91..0ff69ad4 100644 --- a/src/engine/platform/ay8930.h +++ b/src/engine/platform/ay8930.h @@ -39,29 +39,25 @@ class DivPlatformAY8930: public DivDispatch { } envelope; struct PSGMode { - union { - struct { - unsigned char tone: 1; - unsigned char noise: 1; - unsigned char envelope: 1; - unsigned char dac: 1; - }; - unsigned char val=1; - }; + // bit 3: DAC + // bit 2: envelope + // bit 1: noise + // bit 0: tone + unsigned char val; unsigned char getTone() { - return dac?0:(tone<<0); + return (val&8)?0:(val&1); } unsigned char getNoise() { - return dac?0:(noise<<1); + return (val&8)?0:(val&2); } unsigned char getEnvelope() { - return dac?0:(envelope<<2); + return (val&8)?0:(val&4); } - PSGMode(unsigned char v=0): + PSGMode(unsigned char v=1): val(v) {} }; PSGMode curPSGMode; @@ -69,7 +65,7 @@ class DivPlatformAY8930: public DivDispatch { struct DAC { int sample, rate, period, pos, out; - unsigned char furnaceDAC: 1; + bool furnaceDAC; DAC(): sample(-1), @@ -77,7 +73,7 @@ class DivPlatformAY8930: public DivDispatch { period(0), pos(0), out(0), - furnaceDAC(0) {} + furnaceDAC(false) {} } dac; unsigned char autoEnvNum, autoEnvDen, duty; diff --git a/src/gui/debug.cpp b/src/gui/debug.cpp index d2b2f44a..8723ce4e 100644 --- a/src/gui/debug.cpp +++ b/src/gui/debug.cpp @@ -761,17 +761,6 @@ void putDispatchChan(void* data, int chanNum, int type) { DivPlatformAY8910::Channel* ch=(DivPlatformAY8910::Channel*)data; ImGui::Text("> AY-3-8910"); COMMON_CHAN_DEBUG; - ImGui::Text("* psgMode:"); - ImGui::Text(" * curr:"); - ImGui::Text(" - tone: %d",ch->curPSGMode.tone); - ImGui::Text(" - noise: %d",ch->curPSGMode.noise); - ImGui::Text(" - envelope: %d",ch->curPSGMode.envelope); - ImGui::Text(" - dac: %d",ch->curPSGMode.dac); - ImGui::Text(" * next:"); - ImGui::Text(" - tone: %d",ch->nextPSGMode.tone); - ImGui::Text(" - noise: %d",ch->nextPSGMode.noise); - ImGui::Text(" - envelope: %d",ch->nextPSGMode.envelope); - ImGui::Text(" - dac: %d",ch->nextPSGMode.dac); ImGui::Text("* DAC:"); ImGui::Text(" - sample: %d",ch->dac.sample); ImGui::Text(" - rate: %d",ch->dac.rate); @@ -789,22 +778,6 @@ void putDispatchChan(void* data, int chanNum, int type) { ImGui::Text("> AY8930"); COMMON_CHAN_DEBUG; ImGui::Text("- duty: %d",ch->duty); - ImGui::Text("* envelope:"); - ImGui::Text(" - mode: %d",ch->envelope.mode); - ImGui::Text(" - period: %d",ch->envelope.period); - ImGui::Text(" * slide: %d",ch->envelope.slide); - ImGui::Text(" - low: %d",ch->envelope.slideLow); - ImGui::Text("* psgMode:"); - ImGui::Text(" * curr:"); - ImGui::Text(" - tone: %d",ch->curPSGMode.tone); - ImGui::Text(" - noise: %d",ch->curPSGMode.noise); - ImGui::Text(" - envelope: %d",ch->curPSGMode.envelope); - ImGui::Text(" - dac: %d",ch->curPSGMode.dac); - ImGui::Text(" * next:"); - ImGui::Text(" - tone: %d",ch->nextPSGMode.tone); - ImGui::Text(" - noise: %d",ch->nextPSGMode.noise); - ImGui::Text(" - envelope: %d",ch->nextPSGMode.envelope); - ImGui::Text(" - dac: %d",ch->nextPSGMode.dac); ImGui::Text("* DAC:"); ImGui::Text(" - sample: %d",ch->dac.sample); ImGui::Text(" - rate: %d",ch->dac.rate);