NES: fix a little accuracy problem

This commit is contained in:
tildearrow 2025-03-07 02:31:38 -05:00
parent 54d1998c70
commit 86fb92595a
2 changed files with 28 additions and 2 deletions

View file

@ -211,7 +211,11 @@ enum apu_mode { APU_60HZ, APU_48HZ };
square.sweep.negate = value & 0x08 square.sweep.negate = value & 0x08
#define square_reg2(square)\ #define square_reg2(square)\
/* timer (low 8 bits) */\ /* timer (low 8 bits) */\
square.timer = (square.timer & 0x0700) | value square.timer = (square.timer & 0x0700) | value;\
if (!square.firstTime) {\
square.frequency=1;\
square.firstTime=1;\
}
#define square_reg3(square,length_clocked)\ #define square_reg3(square,length_clocked)\
/* length counter */\ /* length counter */\
/*\ /*\
@ -232,7 +236,11 @@ enum apu_mode { APU_60HZ, APU_48HZ };
/*The correct behaviour is to reset the duty cycle sequencers but not the clock dividers*/\ /*The correct behaviour is to reset the duty cycle sequencers but not the clock dividers*/\
/*square.frequency = 1;*/\ /*square.frequency = 1;*/\
/* sequencer */\ /* sequencer */\
square.sequencer = 0 square.sequencer = 0;\
if (!square.firstTime) {\
square.frequency=1;\
square.firstTime=1;\
}
#define init_nla_table(p, t)\ #define init_nla_table(p, t)\
{\ {\
WORD i;\ WORD i;\
@ -328,6 +336,8 @@ typedef struct _apuSquare {
DBWORD timer; DBWORD timer;
/* ogni quanti cicli devo generare un output */ /* ogni quanti cicli devo generare un output */
WORD frequency; WORD frequency;
/* optimization */
BYTE firstTime;
/* duty */ /* duty */
BYTE duty; BYTE duty;
/* envelope */ /* envelope */
@ -354,6 +364,8 @@ typedef struct _apuTriangle {
_length_counter length; _length_counter length;
/* sequencer */ /* sequencer */
BYTE sequencer; BYTE sequencer;
/* optimization */
BYTE firstTime;
/* output */ /* output */
SWORD output; SWORD output;
} _apuTriangle; } _apuTriangle;
@ -374,6 +386,8 @@ typedef struct _apuNoise {
_length_counter length; _length_counter length;
/* sequencer */ /* sequencer */
BYTE sequencer; BYTE sequencer;
/* optimization */
BYTE firstTime;
/* output */ /* output */
SWORD output; SWORD output;
} _apuNoise; } _apuNoise;

View file

@ -105,6 +105,10 @@ INLINE static void apu_wr_reg(struct NESAPU* a, int ts, WORD address, BYTE value
if (address == 0x400A) { if (address == 0x400A) {
/* timer (low 8 bits) */ /* timer (low 8 bits) */
a->TR.timer = (a->TR.timer & 0x0700) | value; a->TR.timer = (a->TR.timer & 0x0700) | value;
if (!a->TR.firstTime) {
a->TR.firstTime=1;
a->TR.frequency=1;
}
return; return;
} }
if (address == 0x400B) { if (address == 0x400B) {
@ -127,6 +131,10 @@ INLINE static void apu_wr_reg(struct NESAPU* a, int ts, WORD address, BYTE value
* automaticamente l'halt flag del triangle. * automaticamente l'halt flag del triangle.
*/ */
a->TR.linear.halt = TRUE; a->TR.linear.halt = TRUE;
if (!a->TR.firstTime) {
a->TR.firstTime=1;
a->TR.frequency=1;
}
return; return;
} }
return; return;
@ -143,6 +151,10 @@ INLINE static void apu_wr_reg(struct NESAPU* a, int ts, WORD address, BYTE value
if (address == 0x400E) { if (address == 0x400E) {
a->NS.mode = value & 0x80; a->NS.mode = value & 0x80;
a->NS.timer = value & 0x0F; a->NS.timer = value & 0x0F;
if (!a->NS.firstTime) {
a->NS.firstTime=1;
a->NS.frequency=1;
}
return; return;
} }
if (address == 0x400F) { if (address == 0x400F) {