mirror of https://github.com/mgba-emu/mgba.git
GB Audio: Fix serializing sweep time
This commit is contained in:
parent
717ede4b94
commit
7652fe9f7a
1
CHANGES
1
CHANGES
|
@ -10,6 +10,7 @@ Emulation fixes:
|
|||
- ARM: Fix STR storing PC after address calculation
|
||||
- GB: Partially fix timing for skipped BIOS
|
||||
- GB Audio: Fix initial sweep state
|
||||
- GB Audio: Fix serializing sweep time
|
||||
- GB MBC: Fix MBC1 mode changing behavior
|
||||
- GB Video: Fix state after skipping BIOS (fixes mgba.io/i/1715 and mgba.io/i/1716)
|
||||
- GBA: Fix timing advancing too quickly in rare cases
|
||||
|
|
|
@ -59,7 +59,9 @@ mLOG_DECLARE_CATEGORY(GB_STATE);
|
|||
* | bits 21 - 31: Reserved
|
||||
* | 0x0004C - 0x0004F: Next frame
|
||||
* | 0x00050 - 0x00053: Next channel 3 fade
|
||||
* | 0x00054 - 0x00057: Reserved
|
||||
* | 0x00054 - 0x00057: Sweep state
|
||||
* | bits 0 - 2: Timesteps
|
||||
* | bits 3 - 31: Reserved
|
||||
* | 0x00058 - 0x0005B: Next event
|
||||
* 0x0005C - 0x0006B: Audio channel 2 state
|
||||
* | 0x0005C - 0x0005F: Envelepe timing
|
||||
|
@ -87,22 +89,23 @@ mLOG_DECLARE_CATEGORY(GB_STATE);
|
|||
* | bits 0 - 3: Current volume
|
||||
* | bits 4 - 5: Is dead?
|
||||
* | bit 6: Is high?
|
||||
* | bit 7: Reserved
|
||||
* | 0x000A5: Channel 2 envelope state
|
||||
* | bits 0 - 3: Current volume
|
||||
* | bits 4 - 5: Is dead?
|
||||
* | bit 6: Is high?
|
||||
* | bits 7: Reserved
|
||||
* | bit 7: Reserved
|
||||
* | 0x000A6: Channel 4 envelope state
|
||||
* | bits 0 - 3: Current volume
|
||||
* | bits 4 - 5: Is dead?
|
||||
* | bit 6: Is high?
|
||||
* | bits 7: Reserved
|
||||
* | bits 6 - 7: Current frame (continued)
|
||||
* | 0x000A7: Miscellaneous audio flags
|
||||
* | bits 0 - 3: Current frame
|
||||
* | bit 4: Is channel 1 sweep enabled?
|
||||
* | bit 5: Has channel 1 sweep occurred?
|
||||
* | bit 6: Is channel 3's memory readable?
|
||||
* | bit 7: Reserved
|
||||
* | bit 0: Current frame (continuation)
|
||||
* | bit 1: Is channel 1 sweep enabled?
|
||||
* | bit 2: Has channel 1 sweep occurred?
|
||||
* | bit 3: Is channel 3's memory readable?
|
||||
* | bit 4: Skip frame
|
||||
* | bits 5 - 7: Reserved
|
||||
* | 0x000A8 - 0x000AB: Left capacitor charge
|
||||
* | 0x000AC - 0x000AF: Right capacitor charge
|
||||
* | 0x000B0 - 0x000B3: Next sample
|
||||
|
@ -203,12 +206,16 @@ DECL_BITS(GBSerializedAudioEnvelope, Length, 0, 7);
|
|||
DECL_BITS(GBSerializedAudioEnvelope, NextStep, 7, 3);
|
||||
DECL_BITS(GBSerializedAudioEnvelope, Frequency, 10, 11);
|
||||
|
||||
|
||||
DECL_BITFIELD(GBSerializedAudioSweep, uint32_t);
|
||||
DECL_BITS(GBSerializedAudioSweep, Time, 0, 3);
|
||||
|
||||
struct GBSerializedPSGState {
|
||||
struct {
|
||||
GBSerializedAudioEnvelope envelope;
|
||||
int32_t nextFrame;
|
||||
int32_t nextCh3Fade;
|
||||
int32_t reserved;
|
||||
GBSerializedAudioSweep sweep;
|
||||
uint32_t nextEvent;
|
||||
} ch1;
|
||||
struct {
|
||||
|
|
|
@ -41,7 +41,10 @@ mLOG_DECLARE_CATEGORY(GBA_STATE);
|
|||
* | bits 10 - 20: Shadow frequency register
|
||||
* | bits 21 - 31: Reserved
|
||||
* | 0x00134 - 0x00137: Next frame
|
||||
* | 0x00138 - 0x0013F: Reserved
|
||||
* | 0x00138 - 0x0013B: Next channel 3 fade
|
||||
* | 0x0013C - 0x0013F: Sweep state
|
||||
* | bits 0 - 2: Timesteps
|
||||
* | bits 3 - 7: Reserved
|
||||
* | 0x00140 - 0x00143: Next event
|
||||
* 0x00144 - 0x00153: Audio channel 2 state
|
||||
* | 0x00144 - 0x00147: Envelepe timing
|
||||
|
@ -75,21 +78,23 @@ mLOG_DECLARE_CATEGORY(GBA_STATE);
|
|||
* | bits 0 - 3: Current volume
|
||||
* | bits 4 - 5: Is dead?
|
||||
* | bit 6: Is high?
|
||||
* | bit 7: Reserved
|
||||
* | 0x001DD - 0x001DD: Channel 2 envelope state
|
||||
* | bits 0 - 3: Current volume
|
||||
* | bits 4 - 5: Is dead?
|
||||
* | bit 6: Is high?
|
||||
* | bits 7: Reserved
|
||||
* | bit 7: Reserved
|
||||
* | 0x001DE - 0x001DE: Channel 4 envelope state
|
||||
* | bits 0 - 3: Current volume
|
||||
* | bits 4 - 5: Is dead?
|
||||
* | bit 6: Is high?
|
||||
* | bits 7: Reserved
|
||||
* | bits 6 - 7: Current frame (continued)
|
||||
* | 0x001DF - 0x001DF: Miscellaneous audio flags
|
||||
* | bits 0 - 3: Current frame
|
||||
* | bit 4: Is channel 1 sweep enabled?
|
||||
* | bit 5: Has channel 1 sweep occurred?
|
||||
* | bits 6 - 7: Reserved
|
||||
* | bit 0: Current frame (continuation)
|
||||
* | bit 1: Is channel 1 sweep enabled?
|
||||
* | bit 2: Has channel 1 sweep occurred?
|
||||
* | bit 3: Is channel 3's memory readable?
|
||||
* | bit 4: Skip frame
|
||||
* | bits 5 - 7: Reserved
|
||||
* 0x001E0 - 0x001FF: Video miscellaneous state
|
||||
* | 0x001E0 - 0x001E3: Next event
|
||||
* | 0x001E4 - 0x001F7: Reserved
|
||||
|
|
|
@ -964,6 +964,7 @@ static void _updateChannel4(struct mTiming* timing, void* user, uint32_t cyclesL
|
|||
|
||||
void GBAudioPSGSerialize(const struct GBAudio* audio, struct GBSerializedPSGState* state, uint32_t* flagsOut) {
|
||||
uint32_t flags = 0;
|
||||
uint32_t sweep = 0;
|
||||
uint32_t ch1Flags = 0;
|
||||
uint32_t ch2Flags = 0;
|
||||
uint32_t ch4Flags = 0;
|
||||
|
@ -980,7 +981,9 @@ void GBAudioPSGSerialize(const struct GBAudio* audio, struct GBSerializedPSGStat
|
|||
ch1Flags = GBSerializedAudioEnvelopeSetLength(ch1Flags, audio->ch1.control.length);
|
||||
ch1Flags = GBSerializedAudioEnvelopeSetNextStep(ch1Flags, audio->ch1.envelope.nextStep);
|
||||
ch1Flags = GBSerializedAudioEnvelopeSetFrequency(ch1Flags, audio->ch1.sweep.realFrequency);
|
||||
sweep = GBSerializedAudioSweepSetTime(sweep, audio->ch1.sweep.time & 7);
|
||||
STORE_32LE(ch1Flags, 0, &state->ch1.envelope);
|
||||
STORE_32LE(sweep, 0, &state->ch1.sweep);
|
||||
STORE_32LE(audio->ch1Event.when - mTimingCurrentTime(audio->timing), 0, &state->ch1.nextEvent);
|
||||
|
||||
flags = GBSerializedAudioFlagsSetCh2Volume(flags, audio->ch2.envelope.currentVolume);
|
||||
|
@ -1011,6 +1014,7 @@ void GBAudioPSGSerialize(const struct GBAudio* audio, struct GBSerializedPSGStat
|
|||
|
||||
void GBAudioPSGDeserialize(struct GBAudio* audio, const struct GBSerializedPSGState* state, const uint32_t* flagsIn) {
|
||||
uint32_t flags;
|
||||
uint32_t sweep;
|
||||
uint32_t ch1Flags = 0;
|
||||
uint32_t ch2Flags = 0;
|
||||
uint32_t ch4Flags = 0;
|
||||
|
@ -1032,11 +1036,16 @@ void GBAudioPSGDeserialize(struct GBAudio* audio, const struct GBSerializedPSGSt
|
|||
audio->skipFrame = GBSerializedAudioFlagsGetSkipFrame(flags);
|
||||
|
||||
LOAD_32LE(ch1Flags, 0, &state->ch1.envelope);
|
||||
LOAD_32LE(sweep, 0, &state->ch1.sweep);
|
||||
audio->ch1.envelope.currentVolume = GBSerializedAudioFlagsGetCh1Volume(flags);
|
||||
audio->ch1.envelope.dead = GBSerializedAudioFlagsGetCh1Dead(flags);
|
||||
audio->ch1.control.hi = GBSerializedAudioFlagsGetCh1Hi(flags);
|
||||
audio->ch1.sweep.enable = GBSerializedAudioFlagsGetCh1SweepEnabled(flags);
|
||||
audio->ch1.sweep.occurred = GBSerializedAudioFlagsGetCh1SweepOccurred(flags);
|
||||
audio->ch1.sweep.time = GBSerializedAudioSweepGetTime(sweep);
|
||||
if (!audio->ch1.sweep.time) {
|
||||
audio->ch1.sweep.time = 8;
|
||||
}
|
||||
audio->ch1.control.length = GBSerializedAudioEnvelopeGetLength(ch1Flags);
|
||||
audio->ch1.envelope.nextStep = GBSerializedAudioEnvelopeGetNextStep(ch1Flags);
|
||||
audio->ch1.sweep.realFrequency = GBSerializedAudioEnvelopeGetFrequency(ch1Flags);
|
||||
|
|
Loading…
Reference in New Issue