From b72b5bf0e6d6357da305cd39142d09cda2f04bc9 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 23 Sep 2022 20:15:20 -0500 Subject: [PATCH] A Y P C M --- src/engine/platform/ay.cpp | 92 +++++++++++++++++++++++---------- src/engine/platform/ay.h | 2 + src/engine/platform/ay8930.cpp | 94 +++++++++++++++++++++++----------- src/engine/platform/ay8930.h | 2 + 4 files changed, 133 insertions(+), 57 deletions(-) diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index 851ef46b4..9526e591d 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -81,16 +81,39 @@ const char** DivPlatformAY8910::getRegisterSheet() { return intellivision?regCheatSheetAY8914:regCheatSheetAY; } -void DivPlatformAY8910::acquire(short* bufL, short* bufR, size_t start, size_t len) { - if (ayBufLen +#include + +int main(int argc, char** argv) { + for (int i=0; i<256; i++) { + if ((i&15)==0) printf("\n "); + printf(" %d,",(int)round(pow((double)i/255.0,0.36)*15.0)); } - // TODO: try to fit this into the actual loop - // PCM part +} +*/ + +const unsigned char dacLogTableAY[256]={ + 0, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 +}; + +void DivPlatformAY8910::runDAC() { for (int i=0; i<3; i++) { if (chan[i].psgMode.dac && chan[i].dac.sample!=-1) { chan[i].dac.period+=chan[i].dac.rate; @@ -105,9 +128,8 @@ void DivPlatformAY8910::acquire(short* bufL, short* bufR, size_t start, size_t l end=true; break; } - // Partially - unsigned char dacData=(((unsigned char)s->data8[chan[i].dac.pos]^0x80)>>4); - chan[i].dac.out=MAX(0,MIN(15,(dacData*chan[i].outVol)/15)); + unsigned char dacData=dacLogTableAY[(unsigned char)s->data8[chan[i].dac.pos]^0x80]; + chan[i].dac.out=MAX(0,dacData-(15-chan[i].outVol)); if (prevOut!=chan[i].dac.out) { prevOut=chan[i].dac.out; changed=true; @@ -130,7 +152,9 @@ void DivPlatformAY8910::acquire(short* bufL, short* bufR, size_t start, size_t l } } } +} +void DivPlatformAY8910::checkWrites() { while (!writes.empty()) { QueuedWrite w=writes.front(); if (intellivision) { @@ -143,8 +167,22 @@ void DivPlatformAY8910::acquire(short* bufL, short* bufR, size_t start, size_t l regPool[w.addr&0x0f]=w.val; writes.pop(); } +} + +void DivPlatformAY8910::acquire(short* bufL, short* bufR, size_t start, size_t len) { + if (ayBufLensound_stream_update(ayBuf,1); bufL[i+start]=ayBuf[0][0]; bufR[i+start]=bufL[i+start]; @@ -154,22 +192,22 @@ void DivPlatformAY8910::acquire(short* bufL, short* bufR, size_t start, size_t l oscBuf[2]->data[oscBuf[2]->needle++]=sunsoftVolTable[31-((ay->lastIndx>>10)&31)]>>3; } } else { - ay->sound_stream_update(ayBuf,len); - if (stereo) { - for (size_t i=0; i>8); - bufR[i+start]=((ayBuf[0][i]*stereoSep)>>8)+ayBuf[1][i]+ayBuf[2][i]; - } - } else { - for (size_t i=0; isound_stream_update(ayBuf,1); + if (stereo) { + bufL[i+start]=ayBuf[0][0]+ayBuf[1][0]+((ayBuf[2][0]*stereoSep)>>8); + bufR[i+start]=((ayBuf[0][0]*stereoSep)>>8)+ayBuf[1][0]+ayBuf[2][0]; + } else { + bufL[i+start]=ayBuf[0][0]+ayBuf[1][0]+ayBuf[2][0]; bufR[i+start]=bufL[i+start]; } - } - for (int ch=0; ch<3; ch++) { - for (size_t i=0; idata[oscBuf[ch]->needle++]=ayBuf[ch][i]<<2; - } + + oscBuf[0]->data[oscBuf[0]->needle++]=ayBuf[0][0]<<2; + oscBuf[1]->data[oscBuf[1]->needle++]=ayBuf[1][0]<<2; + oscBuf[2]->data[oscBuf[2]->needle++]=ayBuf[2][0]<<2; } } } @@ -291,7 +329,7 @@ void DivPlatformAY8910::tick(bool sysTick) { off=8363.0/(double)s->centerRate; } } - chan[i].dac.rate=((double)chipClock*4096.0)/(double)(MAX(1,off*chan[i].freq)); + chan[i].dac.rate=((double)rate*16.0)/(double)(MAX(1,off*chan[i].freq)); if (dumpWrites) addWrite(0xffff0001+(i<<8),chan[i].dac.rate); } if (chan[i].freq>4095) chan[i].freq=4095; diff --git a/src/engine/platform/ay.h b/src/engine/platform/ay.h index 4f77281de..ec9a14fe5 100644 --- a/src/engine/platform/ay.h +++ b/src/engine/platform/ay.h @@ -145,6 +145,8 @@ class DivPlatformAY8910: public DivDispatch { short* ayBuf[3]; size_t ayBufLen; + void runDAC(); + void checkWrites(); void updateOutSel(bool immediate=false); friend void putDispatchChip(void*,int); diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index fbc9b3275..b6c59452f 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -77,22 +77,45 @@ const char** DivPlatformAY8930::getRegisterSheet() { return regCheatSheetAY8930; } -void DivPlatformAY8930::acquire(short* bufL, short* bufR, size_t start, size_t len) { - if (ayBufLen +#include + +int main(int argc, char** argv) { + for (int i=0; i<256; i++) { + if ((i&15)==0) printf("\n "); + printf(" %d,",(int)round(pow((double)i/255.0,0.3)*31.0)); } - // TODO: try to fit this into the actual loop - // PCM part - for (int i=0; i<3; i++) { +} +*/ + +const unsigned char dacLogTableAY8930[256]={ + 0, 6, 7, 8, 9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, + 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, + 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31 +}; + +void DivPlatformAY8930::runDAC() { + for (int i=0; i<3; i++) { if (chan[i].psgMode.dac && chan[i].dac.sample!=-1) { chan[i].dac.period+=chan[i].dac.rate; bool end=false; bool changed=false; - int prev_out = chan[i].dac.out; + int prevOut=chan[i].dac.out; while (chan[i].dac.period>rate && !end) { DivSample* s=parent->getSample(chan[i].dac.sample); if (s->samples<=0) { @@ -101,11 +124,10 @@ void DivPlatformAY8930::acquire(short* bufL, short* bufR, size_t start, size_t l end=true; break; } - // Partially - unsigned char dacData=(((unsigned char)s->data8[chan[i].dac.pos]^0x80)>>3); - chan[i].dac.out=MAX(0,MIN(31,(dacData*chan[i].outVol)/31)); - if (prev_out!=chan[i].dac.out) { - prev_out=chan[i].dac.out; + unsigned char dacData=dacLogTableAY8930[(unsigned char)s->data8[chan[i].dac.pos]^0x80]; + chan[i].dac.out=MAX(0,dacData-(31-chan[i].outVol)); + if (prevOut!=chan[i].dac.out) { + prevOut=chan[i].dac.out; changed=true; } chan[i].dac.pos++; @@ -126,7 +148,9 @@ void DivPlatformAY8930::acquire(short* bufL, short* bufR, size_t start, size_t l } } } +} +void DivPlatformAY8930::checkWrites() { while (!writes.empty()) { QueuedWrite w=writes.front(); ay->address_w(w.addr); @@ -138,23 +162,33 @@ void DivPlatformAY8930::acquire(short* bufL, short* bufR, size_t start, size_t l } writes.pop(); } - ay->sound_stream_update(ayBuf,len); - if (stereo) { - for (size_t i=0; i>8); - bufR[i+start]=((ayBuf[0][i]*stereoSep)>>8)+ayBuf[1][i]+ayBuf[2][i]; - } - } else { - for (size_t i=0; idata[oscBuf[ch]->needle++]=ayBuf[ch][i]<<2; + for (size_t i=0; isound_stream_update(ayBuf,1); + if (stereo) { + bufL[i+start]=ayBuf[0][0]+ayBuf[1][0]+((ayBuf[2][0]*stereoSep)>>8); + bufR[i+start]=((ayBuf[0][0]*stereoSep)>>8)+ayBuf[1][0]+ayBuf[2][0]; + } else { + bufL[i+start]=ayBuf[0][0]+ayBuf[1][0]+ayBuf[2][0]; + bufR[i+start]=bufL[i+start]; } + + oscBuf[0]->data[oscBuf[0]->needle++]=ayBuf[0][0]<<2; + oscBuf[1]->data[oscBuf[1]->needle++]=ayBuf[1][0]<<2; + oscBuf[2]->data[oscBuf[2]->needle++]=ayBuf[2][0]<<2; } } @@ -294,7 +328,7 @@ void DivPlatformAY8930::tick(bool sysTick) { off=8363.0/(double)s->centerRate; } } - chan[i].dac.rate=((double)chipClock*16384.0)/(double)(MAX(1,off*chan[i].freq)); + chan[i].dac.rate=((double)chipClock*4.0)/(double)(MAX(1,off*chan[i].freq)); if (dumpWrites) addWrite(0xffff0001+(i<<8),chan[i].dac.rate); } if (chan[i].freq>65535) chan[i].freq=65535; diff --git a/src/engine/platform/ay8930.h b/src/engine/platform/ay8930.h index c1a50e7a5..441e82148 100644 --- a/src/engine/platform/ay8930.h +++ b/src/engine/platform/ay8930.h @@ -148,6 +148,8 @@ class DivPlatformAY8930: public DivDispatch { short* ayBuf[3]; size_t ayBufLen; + void runDAC(); + void checkWrites(); void updateOutSel(bool immediate=false); void immWrite(unsigned char a, unsigned char v);