Amiga: more accurate emulation

https://www.youtube.com/watch?v=xyQlmsD7PAg&t=403s

thanks TakuikaNinja for the info!
This commit is contained in:
tildearrow 2023-03-09 03:37:14 -05:00
parent 8c706f71a9
commit 5069cf65e3
2 changed files with 23 additions and 1 deletions

View file

@ -23,6 +23,7 @@
#include <math.h>
#define AMIGA_DIVIDER 8
#define AMIGA_VPMASK 7
#define CHIP_DIVIDER 16
const char* regCheatSheetAmiga[]={
@ -81,6 +82,7 @@ void DivPlatformAmiga::acquire(short** buf, size_t len) {
outL=0;
outR=0;
for (int i=0; i<4; i++) {
chan[i].volPos=(chan[i].volPos+1)&AMIGA_VPMASK;
if (!chan[i].active) {
oscBuf[i]->data[oscBuf[i]->needle++]=0;
continue;
@ -125,7 +127,13 @@ void DivPlatformAmiga::acquire(short** buf, size_t len) {
}
}
if (!isMuted[i]) {
output=chan[i].audDat*chan[i].outVol;
if (chan[i].outVol>=64) {
output=chan[i].audDat<<6;
} else if (chan[i].outVol<=0) {
output=0;
} else {
output=chan[i].audDat*volTable[chan[i].outVol][chan[i].volPos];
}
if (i==0 || i==3) {
outL+=(output*sep1)>>7;
outR+=(output*sep2)>>7;
@ -467,6 +475,16 @@ int DivPlatformAmiga::init(DivEngine* p, int channels, int sugRate, const DivCon
oscBuf[i]=new DivDispatchOscBuffer;
isMuted[i]=false;
}
// Paula volume is implemented using PWM rather than a multiplication.
// source: https://www.youtube.com/watch?v=xyQlmsD7PAg
memset(volTable,0,64*64);
for (int i=0; i<64; i++) {
for (int j=0; j<64; j++) {
volTable[i][j/AMIGA_DIVIDER]+=(j<i)*(64/AMIGA_DIVIDER);
}
}
setFlags(flags);
reset();
return 6;

View file

@ -31,6 +31,7 @@ class DivPlatformAmiga: public DivDispatch {
unsigned int audPos;
int audSub;
signed char audDat;
unsigned char volPos;
int sample, wave;
int busClock;
bool useWave, setPos, useV, useP;
@ -42,6 +43,7 @@ class DivPlatformAmiga: public DivDispatch {
audPos(0),
audSub(0),
audDat(0),
volPos(0),
sample(-1),
wave(-1),
busClock(0),
@ -61,6 +63,8 @@ class DivPlatformAmiga: public DivDispatch {
int filtConst;
int filtConstOff, filtConstOn;
unsigned char volTable[64][64];
int sep1, sep2;
friend void putDispatchChip(void*,int);