diff --git a/src/engine/platform/sound/nes/apu.h b/src/engine/platform/sound/nes/apu.h index 1fe6e9ac3..7213b30c0 100644 --- a/src/engine/platform/sound/nes/apu.h +++ b/src/engine/platform/sound/nes/apu.h @@ -211,7 +211,11 @@ enum apu_mode { APU_60HZ, APU_48HZ }; square.sweep.negate = value & 0x08 #define square_reg2(square)\ /* 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)\ /* 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*/\ /*square.frequency = 1;*/\ /* sequencer */\ - square.sequencer = 0 + square.sequencer = 0;\ + if (!square.firstTime) {\ + square.frequency=1;\ + square.firstTime=1;\ + } #define init_nla_table(p, t)\ {\ WORD i;\ @@ -328,6 +336,8 @@ typedef struct _apuSquare { DBWORD timer; /* ogni quanti cicli devo generare un output */ WORD frequency; + /* optimization */ + BYTE firstTime; /* duty */ BYTE duty; /* envelope */ @@ -354,6 +364,8 @@ typedef struct _apuTriangle { _length_counter length; /* sequencer */ BYTE sequencer; + /* optimization */ + BYTE firstTime; /* output */ SWORD output; } _apuTriangle; @@ -374,6 +386,8 @@ typedef struct _apuNoise { _length_counter length; /* sequencer */ BYTE sequencer; + /* optimization */ + BYTE firstTime; /* output */ SWORD output; } _apuNoise; diff --git a/src/engine/platform/sound/nes/cpu_inline.h b/src/engine/platform/sound/nes/cpu_inline.h index 018b96160..dfde3277c 100644 --- a/src/engine/platform/sound/nes/cpu_inline.h +++ b/src/engine/platform/sound/nes/cpu_inline.h @@ -105,6 +105,10 @@ INLINE static void apu_wr_reg(struct NESAPU* a, int ts, WORD address, BYTE value if (address == 0x400A) { /* timer (low 8 bits) */ a->TR.timer = (a->TR.timer & 0x0700) | value; + if (!a->TR.firstTime) { + a->TR.firstTime=1; + a->TR.frequency=1; + } return; } 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. */ a->TR.linear.halt = TRUE; + if (!a->TR.firstTime) { + a->TR.firstTime=1; + a->TR.frequency=1; + } return; } return; @@ -143,6 +151,10 @@ INLINE static void apu_wr_reg(struct NESAPU* a, int ts, WORD address, BYTE value if (address == 0x400E) { a->NS.mode = value & 0x80; a->NS.timer = value & 0x0F; + if (!a->NS.firstTime) { + a->NS.firstTime=1; + a->NS.frequency=1; + } return; } if (address == 0x400F) {