|
|

楼主 |
发表于 2009-11-8 14:47:50
|
显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
& p Z3 e+ g( B' v1 _* q( P(由于很多专用术语和算法机理都不明白,所以看不大懂……)- ?) {. g2 k# j
//////////////////////////////////////////////////////////////////////////
5 i7 Y1 a) q+ A: Q# l// //) X" |8 o" X- U5 x* D
// NES APU core //
L" u8 Z# n( a// Norix //
U$ M r! ~$ {5 g. M, V2 {// written 2002/06/27 //
# E: }& c5 L4 ]9 T7 p// last modify ----/--/-- /// O, D! g0 K( A6 J8 m- |
//////////////////////////////////////////////////////////////////////////
7 p7 I& A# f2 t" f) z#include "DebugOut.h"; J; r) W8 o" t8 T# c R% o. T$ N
#include "App.h"
6 F. t' ? @# }0 T8 B' L#include "Config.h"9 c! \! M7 d& Q8 E
* m- H6 }' ^2 G- D, l$ D! f
#include "nes.h"
2 j q% ]/ p& S0 {$ h% _5 h/ ~2 @#include "mmu.h"
( }" A) t% L E( Q#include "cpu.h") b* F/ K1 @" O$ f
#include "ppu.h"
% O9 E% {; H0 B" K#include "rom.h"' p( |" O( h% ~- Z
#include "apu.h"$ ~6 C4 s0 {9 a, S! ~2 i3 |
1 R, T$ `9 R$ P1 O3 {5 i0 j
// Volume adjust
B4 F7 W/ P# V3 U// Internal sounds0 \# ?6 D1 o" H' {/ R+ h
#define RECTANGLE_VOL (0x0F0)
6 }3 i# s& E$ r4 @2 P9 R#define TRIANGLE_VOL (0x130)% Z" m3 v( a$ U
#define NOISE_VOL (0x0C0)5 N2 \! L3 m6 |, h* h% y
#define DPCM_VOL (0x0F0)
5 l' d8 ^. y" j1 i// Extra sounds5 _5 l# r+ o" k6 j7 k& w+ n6 ~7 m
#define VRC6_VOL (0x0F0)6 `! n( H3 g/ i# W" h
#define VRC7_VOL (0x130)( i( j, E! N+ E$ [, Y
#define FDS_VOL (0x0F0)3 o% \6 A" O$ f. i1 ~ c5 C
#define MMC5_VOL (0x0F0)
, l6 w+ @; ~; W#define N106_VOL (0x088)5 |% t/ z4 g6 E5 W& k, c( m* ~( g
#define FME7_VOL (0x130); L/ ^) q6 N* p
* X2 c# o4 j8 hAPU::APU( NES* parent )
. D }4 d4 y$ e, b" `{' _% h0 g/ v7 V7 G* w
exsound_select = 0;
, e# p2 B5 Q8 k& p9 E% i% H) L ]5 w2 M* u; @' ?
nes = parent;
2 o1 g1 R5 r8 B+ C% u& O ^ internal.SetParent( parent );8 ?* \) M! H# `
5 Q7 ^- Y' v1 H# } last_data = last_diff = 0;# u) A4 R( e" |) |2 `
2 _8 D6 {2 U/ ~4 i) V ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
% B; W' J: l# s7 b
2 u0 m' B2 J: Z; H! a% ?6 [/ J$ k; s ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );4 @% `! B; ?3 Y0 z& b. [; b
ZEROMEMORY( &queue, sizeof(queue) );$ A) U2 \4 ^- u7 [7 U) s8 D
ZEROMEMORY( &exqueue, sizeof(exqueue) );" n! P' A+ e! y* X' F( m0 _$ `
) r+ G. w0 z6 r- _# \
for( INT i = 0; i < 16; i++ ) {; r' j( t1 k% d! Y/ A
m_bMute = TRUE;( X& l e' R" p% ]% u, Q9 I. h
}
P. ^; D% m) Q9 S3 ]# W}+ l C" S: |% J7 u
' A0 j" w3 u; hAPU::~APU()8 X& T! H; k, o' w! E7 I3 X3 ]% ?
{
9 N) a$ X! |/ [6 _}3 N6 K& `7 q+ A( X! D
# {: r; C+ v3 v R" Fvoid APU::SetQueue( INT writetime, WORD addr, BYTE data )) j0 g3 {. d% h5 i. S5 h
{6 O" `6 w& z0 S5 W5 l7 B
queue.data[queue.wrptr].time = writetime;! E% _( i- `/ C3 [: ?
queue.data[queue.wrptr].addr = addr;
) x7 p" ^$ O- [% }& v% t- h queue.data[queue.wrptr].data = data;
; l- X/ F9 r8 }8 R queue.wrptr++;
- x6 z: I: y. R+ \ queue.wrptr&=QUEUE_LENGTH-1;/ S9 s, ~) ?- _! U0 y5 ^
if( queue.wrptr == queue.rdptr ) {
; V! g8 z. H! B4 J) M DEBUGOUT( "queue overflow.\n" );* R- A/ M0 J3 U) O* G; |* d
}* d# n$ G T3 F, s6 C6 m& R
}
5 Q! a/ K/ u* `
3 b/ p( n L3 P4 X! eBOOL APU::GetQueue( INT writetime, QUEUEDATA& ret )
* S& x$ h7 t" H% W{
4 Z4 J* {1 O* w3 A( q if( queue.wrptr == queue.rdptr ) {: b, j6 X) x1 d
return FALSE;
t: j7 G, t1 T* S/ Y' I }
1 x7 n7 N' X8 m, l# M3 Q8 f if( queue.data[queue.rdptr].time <= writetime ) {% p2 `$ y/ D+ a( ?- g
ret = queue.data[queue.rdptr];
) h+ c+ P* a0 ^- g queue.rdptr++;
! X/ L& b# ~3 G7 P5 h5 l7 b3 o2 d7 O9 M queue.rdptr&=QUEUE_LENGTH-1;
. h$ W8 z2 K4 e r# P; \ return TRUE;$ |6 |4 Q7 O# M9 W. M' J2 Q
}
5 ?4 h" S' b0 ? U+ c" t" B8 w return FALSE;
" b5 ?" H' E- Y7 B) c}+ a6 ?4 z3 Z! s8 L) }
{$ L& c* S& f Q" e; wvoid APU::SetExQueue( INT writetime, WORD addr, BYTE data )8 n8 |3 |. K' M/ ]2 g" p p
{( d/ `+ G1 t4 ]
exqueue.data[exqueue.wrptr].time = writetime;: |; G: Q* d& v0 i( y! A
exqueue.data[exqueue.wrptr].addr = addr;7 Z2 d8 Z% t; i( d$ ?5 ~3 [" `8 ?$ V. I
exqueue.data[exqueue.wrptr].data = data;: p$ k/ o4 q- H7 O
exqueue.wrptr++;
' d: }3 ^8 H6 k& A- c( K _ exqueue.wrptr&=QUEUE_LENGTH-1;
; @# W/ {0 c L if( exqueue.wrptr == exqueue.rdptr ) {
3 y! Y: O5 C/ z* o: B DEBUGOUT( "exqueue overflow.\n" );
9 z- ?0 C0 X3 N1 a+ U' v7 I }2 D. M [$ q5 G" W; D
}
% P6 W: J" z+ E. h) Y* D' |5 b% ?- Y4 k
BOOL APU::GetExQueue( INT writetime, QUEUEDATA& ret )
0 \% q0 z& T) S/ ~2 P8 s{
5 j4 A! ` J, h+ g if( exqueue.wrptr == exqueue.rdptr ) {
( E2 w, X, d; d/ C" q. `+ O return FALSE;
5 f! x3 k7 B: |- \ }, }1 i7 U" ^6 |/ U
if( exqueue.data[exqueue.rdptr].time <= writetime ) {
. j/ b. c# C7 }) J. F7 y ret = exqueue.data[exqueue.rdptr];, e, f. r3 w8 [" H0 A- j; c
exqueue.rdptr++;# |8 W r* z, s
exqueue.rdptr&=QUEUE_LENGTH-1;4 c* @* D1 @; \! b7 w: ]! p3 A
return TRUE; u2 l; C* m+ u: z4 C# w
}
# ]/ i) [& e! a1 K* c& m( k return FALSE;
. Z7 b; b+ ~) i}- D. H' Q; S( M, \9 A! G8 s" d
. l4 ], T4 C: `- A" s
void APU::QueueClear()
h( Y- g2 k, V, P g# n# G{
( b+ M0 S2 M8 H& _3 j ZEROMEMORY( &queue, sizeof(queue) );, E/ R9 X) N, X) z3 y! Z
ZEROMEMORY( &exqueue, sizeof(exqueue) );
7 |# Z) K4 N" K& _2 H- T$ e}% {$ T1 s# D" V4 j# ^
4 ~ }2 t( Y% C, `
void APU::QueueFlush()
+ _: p: l2 u$ l8 n1 _2 `" t) N{
( `$ _& I% e4 W# ?; h" r while( queue.wrptr != queue.rdptr ) {
9 N# T2 A% R9 J0 z8 d8 T WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
5 r: {# @- `9 K0 f& ]) P queue.rdptr++;
! ~5 W0 r9 G3 v/ I8 Y* I# I( `0 o queue.rdptr&=QUEUE_LENGTH-1;9 C0 m) S, B4 K# u, P2 M
} M# m8 G" Q8 j/ N6 q! X3 @2 K
. t- | ]9 M/ a while( exqueue.wrptr != exqueue.rdptr ) {
$ M+ m( H: a0 ]4 _5 n5 T' Q: O- ] WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );( w1 V0 @$ X6 L3 b" g
exqueue.rdptr++;3 m5 T6 Y3 v) [1 k9 l
exqueue.rdptr&=QUEUE_LENGTH-1;
' ~- r7 ?# k8 R6 [* c/ ], B }
- E& L* l- e9 e$ V7 _. u) b& S}" b) U$ y" L1 w& ? ?8 z2 f/ X) Z
. Y r2 l0 _0 Q) Qvoid APU::SoundSetup()6 T" [5 j0 y2 p
{
+ Y# Y) \% ?) C: Y# h FLOAT fClock = nes->nescfg->CpuClock;
. s7 N* o, Y8 C1 x2 k INT nRate = (INT)Config.sound.nRate;
' x, U3 H- L% k$ |- Z3 Q1 Q internal.Setup( fClock, nRate );
2 D W+ a; R! T3 }5 e& Y x vrc6.Setup( fClock, nRate );
/ d3 ^) \. C# q vrc7.Setup( fClock, nRate );
5 h+ N$ L+ z$ u mmc5.Setup( fClock, nRate );
. A9 f2 {1 U' s. i fds.Setup ( fClock, nRate );. i: e! F+ y1 e0 s
n106.Setup( fClock, nRate );( g7 @) ?& R7 q+ D+ n, O# a$ e' z& i
fme7.Setup( fClock, nRate ); _" [6 N) f5 e
}: o! R! Z |/ z6 Q! U0 U
" K( L" ~9 t. a8 Z8 S; W. a3 fvoid APU::Reset()" T* @) }1 \! V+ e9 m
{: c! @9 m! u* L. K; G. f
ZEROMEMORY( &queue, sizeof(queue) );
4 u8 U( ^6 I" } ZEROMEMORY( &exqueue, sizeof(exqueue) );
0 | ?; T Y5 _( O
n X- Z2 w9 O3 c elapsed_time = 0;. i) |% i4 R5 {, D! a& `" T r( t4 B
- u* l4 A& A$ s: T6 x# D' A, L FLOAT fClock = nes->nescfg->CpuClock;
* z2 f' b# k- s6 F9 F7 Z INT nRate = (INT)Config.sound.nRate;
' A3 [: W1 @, Q internal.Reset( fClock, nRate );# Z% y2 N( @8 F" `+ r2 k! _/ D
vrc6.Reset( fClock, nRate );
8 D' S$ ~5 G+ x3 j1 J+ ^ vrc7.Reset( fClock, nRate );$ S6 I3 {/ D8 ^+ Y
mmc5.Reset( fClock, nRate );' b1 }3 W8 {, y# R
fds.Reset ( fClock, nRate );
5 q2 s+ m% A# Z* q1 Q k% T n106.Reset( fClock, nRate );$ i5 q$ @3 J' P/ o1 l: V
fme7.Reset( fClock, nRate );" g2 g0 j2 c' y8 c7 r
7 r; F# _ ^: L8 B! ] SoundSetup(); \- x: E) Z( x2 _8 x/ Y- c
}
, G2 ~6 a! `. Q* |; c, q5 Z8 s' w5 A. T% X, |! C5 Z& `9 N
void APU::SelectExSound( BYTE data )
4 P& J; U2 S0 i7 v# p{4 Y0 w8 G* ^/ e0 h$ D
exsound_select = data;# a# m* e+ i# P3 g+ V$ j
}( S G6 n; B; m( C9 ?1 o
@" V& {! v9 m) P: T
BYTE APU::Read( WORD addr )8 Q+ |% J% [7 L7 O; ^' c
{
- X4 J* q: I* X' r return internal.SyncRead( addr );2 ]' M! Q3 l) [9 d. R9 ~8 X4 Y
}6 g# S4 u& j4 U, P# n
/ q7 P" S- U' B' ]void APU::Write( WORD addr, BYTE data )
4 _# i. q% _* ]8 t{' T" k: f9 r* ~' o( u
// $4018偼VirtuaNES屌桳億乕僩4 |7 M" J: \% D& R0 o3 V
if( addr >= 0x4000 && addr <= 0x401F ) {
; o* i6 p1 o9 O internal.SyncWrite( addr, data );& h& H1 ^: q3 m& I
SetQueue( nes->cpu->GetTotalCycles(), addr, data );7 `0 D( u/ n' }; P- S+ P
}& p3 \' c& @% Q6 |
}) T+ q I) L0 W9 v H
7 N) f, ` j: K0 w, U( LBYTE APU::ExRead( WORD addr )
. `' K3 [7 _1 c- w3 g$ F{
- F5 b2 V! ] \) ^7 tBYTE data = 0; `% q* Z6 r. i$ [1 r4 m) S
+ v2 R# c8 m F9 M
if( exsound_select & 0x10 ) {
- I/ ^# Q& S* b* e if( addr == 0x4800 ) {: i" m4 D, S# {5 d. d
SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
5 A# U) X0 R, n w/ x }
: {% z" |5 r' |* M, L( A }; S5 d; ?6 R# F& U6 ]3 J$ @
if( exsound_select & 0x04 ) {' \7 b9 r1 a0 X2 X5 x1 e0 ?
if( addr >= 0x4040 && addr < 0x4100 ) {: j8 ]: Q2 Z8 w8 }0 d
data = fds.SyncRead( addr );
) V/ U p" k7 s9 M- i2 I }
% \* S2 D G4 @% P# s; u: x }
( y2 x* J# o! s& ^ if( exsound_select & 0x08 ) {
9 f1 r0 o% u$ R8 w7 r8 i if( addr >= 0x5000 && addr <= 0x5015 ) {4 r; ^% v" Z9 e' v$ S2 B* o+ l O
data = mmc5.SyncRead( addr );
% w4 X4 i" s# V0 O" c$ A( ?# m5 c }: D' M2 J2 i' n, \, ]) n
}# e3 B7 v6 H4 {, j2 ~* |, X2 W
: Z; s9 A; t. x% {8 Q9 ?0 V
return data;
' \( ]4 p; v5 m& g}
7 q# z% _/ d! A$ `4 X
% f) B9 d1 E+ g3 b% b6 ^' |void APU::ExWrite( WORD addr, BYTE data )
4 c+ S: s7 f% [7 I{6 n8 }+ V' `% r
SetExQueue( nes->cpu->GetTotalCycles(), addr, data );9 K6 u$ e# ^& Y6 Z9 h) X
/ u6 s7 ~& v4 O: S6 c' N if( exsound_select & 0x04 ) {
) \* a- ?7 m, ]9 j% Y& z5 C if( addr >= 0x4040 && addr < 0x4100 ) {$ c: F3 m# T+ K' v
fds.SyncWrite( addr, data );7 T. E2 O! {9 \) s4 k" g
}: ?1 H- I. A; z1 c1 T
}3 v' P& J. I; g8 A G
S; s' M* F7 f% |( N, b if( exsound_select & 0x08 ) {
# R$ n- W% g h/ W if( addr >= 0x5000 && addr <= 0x5015 ) {# u$ |* C/ f, s# a3 ]* @
mmc5.SyncWrite( addr, data );5 L& }0 k3 A7 t4 T/ ?
}8 \& e' D: {4 ?! ^) ~1 V. d
}0 j& d+ i+ y. u& {/ I" M+ U
}
+ S3 d% J$ S( ?" r/ U9 m
. I5 d% N+ X$ l" u9 V% C9 w' p& l3 k! zvoid APU::Sync()
9 c4 U/ z) c3 @0 m0 u+ B& k{4 G" }! k* Z+ s- H" n
}2 Z& f/ v/ n) Z4 ^7 J1 x
! V: R8 f4 v( L5 u) Q& b/ U
void APU::SyncDPCM( INT cycles )2 S$ w n$ l% S4 p7 T4 o4 A
{
+ B6 h/ _: T, I; J1 \: G internal.Sync( cycles );0 j7 }: v k' \3 J7 [4 N3 A8 M
% c' u" H2 b# I& w7 H if( exsound_select & 0x04 ) {
/ T. T* L/ }' R" h3 x; b fds.Sync( cycles );9 U5 A& A9 X* m) g
}2 i- Y+ N6 C$ }6 J2 s$ ]2 |$ T) X; ^
if( exsound_select & 0x08 ) {
' g, J: W; r% y7 m2 e mmc5.Sync( cycles );9 D2 U3 k( C) y, T3 e( E
}6 o9 ?0 @/ u' p
}
/ ? x3 K$ ?( m* ?& r% V: h+ @; v) K R4 a. o \
void APU::WriteProcess( WORD addr, BYTE data )
% h/ l! B7 E# `4 D, {{# |0 x, `5 a+ I9 e9 I
// $4018偼VirtuaNES屌桳億乕僩
% ? r+ h G: u3 n, ~ if( addr >= 0x4000 && addr <= 0x401F ) {
2 W' e; \$ ~- k, I1 b) J0 p& e' R internal.Write( addr, data );* t& \+ x' M8 B3 p+ u- q
}
: h+ j( K6 `$ E: E1 G}1 u9 S: U" j! e' C& X
1 C1 t/ {3 W8 x' @void APU::WriteExProcess( WORD addr, BYTE data )
b* g/ W0 i6 {( B7 w" X$ w{1 l9 u$ Q) w! v) S/ G
if( exsound_select & 0x01 ) {, T1 f* W* o& `7 d
vrc6.Write( addr, data );
2 S w. j9 X) l2 f% T6 _! \" m }
& F- b/ |0 h A" B' `% [% D: u+ U if( exsound_select & 0x02 ) {( \% P7 A& t k3 F9 S, i
vrc7.Write( addr, data );
, p5 M. i$ N3 u+ h# l" Z7 n }1 O. Q' Q o) o6 t
if( exsound_select & 0x04 ) {: e2 K) F' n5 F& V
fds.Write( addr, data );$ F4 P8 k1 [+ a) H4 [; @1 ?
}! P7 `5 ~, M* f( J; Y
if( exsound_select & 0x08 ) {
9 s( j% D t, G mmc5.Write( addr, data );
; g( _4 D7 g8 L4 [( I8 T; ~ }
K8 W2 r8 `- `% a- _' n if( exsound_select & 0x10 ) {+ T' a% y0 Z/ A: l: m- x/ n* ]
if( addr == 0x0000 ) {2 h: O, p( k# G6 z+ B5 G K2 Q# E
BYTE dummy = n106.Read( addr );
9 `7 x: n" I: e } else {- `8 |+ x9 i5 Y3 z% i6 p% ~9 h
n106.Write( addr, data );
) e6 L4 \ Z. [3 O }
" X& C7 O- ~" I$ D. ?& e }/ _3 P% N) Q4 a- [3 Z
if( exsound_select & 0x20 ) {1 [5 s- |& j, i' Z6 `. K( _
fme7.Write( addr, data );
' ^* y- i, B+ e2 Q* D: k) e# W& q- W }
5 ~) i- ?+ g1 P& H$ M( e% {! [: ^}
7 N7 x3 i, A/ n* l! {; C! L& ]7 _8 s. Q+ V9 W
void APU::Process( LPBYTE lpBuffer, DWORD dwSize )6 D" i! | z* h
{
( m( @2 x* E& H9 ]' ~INT nBits = Config.sound.nBits; n) v3 r) v: A0 l6 O4 z
DWORD dwLength = dwSize / (nBits/8);% w H; b7 I- H- x2 l1 B
INT output;0 w G. {! r' ]$ y, _/ N- M) V
QUEUEDATA q;
% D- z4 k( r. Z6 P4 tDWORD writetime;
4 Y0 Q. X3 u1 [+ G/ X6 j7 w; B) Q8 j+ k1 N& |* Z9 G9 `
LPSHORT pSoundBuf = m_SoundBuffer;/ {9 x- B Y5 Y
INT nCcount = 0;
. f$ N0 k/ F& K' l$ L6 F" |
@7 J4 Y0 C( Z/ TINT nFilterType = Config.sound.nFilterType;
& N% ]" g$ p0 s/ c
: l4 p4 \, R5 S& v; `$ {" v( @ if( !Config.sound.bEnable ) {7 J: W5 |; v$ l( w+ ?& |: }
::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );! ^" B& u/ g4 x# R
return;2 C7 N& c# k5 @2 ?+ t V
}
/ d$ V8 ~. D8 r$ F, F( @. K* @. \6 D
// Volume setup
' p2 q5 {* ?# \3 i$ n% s }7 r // 0:Master5 e4 T3 x P. f' L0 ]) O
// 1:Rectangle 1
4 Z9 c" s; V+ I" h // 2:Rectangle 2% m' c, [) X g
// 3:Triangle6 ~+ T4 O! ]% k. ^
// 4:Noise
2 X% I5 ]$ ^7 D* [7 v$ \& ]- h // 5:DPCM
# D' U* R8 @1 z# n, [. }* C // 6:VRC6# I3 ?& r M+ H- @* V2 N
// 7:VRC7
9 f' h/ A: N3 z+ T: s0 [* ?: p // 8:FDS
8 R2 ?# S! u; x% L' } // 9:MMC5- _9 @) a h! l! ?. } ^
// 10:N106
8 q" H1 s0 E" U$ x1 d+ Y: i2 ~5 t // 11:FME73 s" g9 J! n( w
INT vol[24];
4 z* r9 l0 r' m2 j! v BOOL* bMute = m_bMute;
+ ]9 r, \" m0 y, `, x SHORT* nVolume = Config.sound.nVolume;& M+ h! w% l8 v1 h, A
3 c+ K2 F: k* l& r6 P) R
INT nMasterVolume = bMute[0]?nVolume[0]:0;
; n8 ]' C0 ?" s% O
2 h& K( m5 F9 {' x) I // Internal6 F: o0 @. \( j' o
vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
, Z$ _0 a4 [6 B5 y vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
+ X5 Q, Q. ]6 m% b vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;: |( g1 Q/ o2 F
vol[ 3] = bMute[4]?(NOISE_VOL *nVolume[4]*nMasterVolume)/(100*100):0;
4 B% f2 ^4 E2 S) w& K6 Q. V G vol[ 4] = bMute[5]?(DPCM_VOL *nVolume[5]*nMasterVolume)/(100*100):0;
' J% D# A- ~/ |( ^5 \8 s; l- `( ?) \1 F$ I( C
// VRC6
: Y' Y r9 n& I- {8 Q vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
6 n6 W. _- w1 |' L- x6 v vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
( c' P& a* m( B: }) |5 Q vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;% u9 w: t0 H" k
+ X1 Z0 |2 ]$ i2 J* t* ]$ [ // VRC7 K0 O' z0 H% L/ b/ u/ `
vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
; I# p9 a/ {2 T P9 l5 v9 `3 Q! s$ I; K3 T" d w3 @6 w& M2 y2 W# K, t
// FDS- H9 J0 |5 p6 o5 a6 L$ F) I) j+ H
vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
& U, C) ]3 f5 S# h0 T1 a5 t- K5 N; v1 m3 Z# N5 k
// MMC5
( G: O8 j; }# @/ A5 F- c9 X4 u8 z vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;+ O" L# |( {/ b6 c/ \ n3 F
vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;/ D/ h7 a( |" n1 v
vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
9 E5 X) v, Y: |' k1 A5 ~& V+ h$ B0 ]: Z: |3 z7 A0 c+ l p; y
// N106- y4 ~8 n% b* ~1 f
vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, `- e2 ^/ l5 Z% O, {1 } vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;& f! }. b/ a/ O2 c! P7 C$ G
vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' P, q' u9 m* y9 ?2 ^5 ~1 K" p
vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;* H, Y% m7 [/ p! W7 {
vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;/ T* M1 [4 ^6 P: D2 B
vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
8 I- a* o; m' f: G vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 z1 x$ a. a$ L* ]) b. S$ M vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- Q8 y$ B$ Z1 M4 ~, Y" v# V7 @, @' M; O& O/ x7 f( Y
// FME7
) U3 H" T( w1 R! B( I" l1 ] vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;" u& l& ^5 Y2 m8 u2 D5 u
vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
9 i7 f3 {9 H" y9 T3 V vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;" w- Y/ L @* S
$ L: y; S, x* d' c$ I// double cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;% Q& q: J# N7 O% Z& Y2 k
double cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
% }& d4 o; f; \6 \- \& F$ e0 w6 z6 g1 k0 Y3 F* C: q
// CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟. G! j% |( A/ N3 a% Y* y
if( elapsed_time > nes->cpu->GetTotalCycles() ) {
8 S4 G' a, F! j b: k6 A QueueFlush();
9 p# [0 m! j5 |& L- ^9 g }
2 n' }- ^' J) J$ a" l+ h
* c8 m/ Q6 j. i, Y: d% \; } while( dwLength-- ) { Z0 Z! B- P0 N. F& ]% w2 _- h. n# Q
writetime = (DWORD)elapsed_time;
; Q1 L8 {! V/ X( j9 g: r7 u1 Z+ f
while( GetQueue( writetime, q ) ) {$ g2 f' u1 [$ j7 C0 \: p+ e
WriteProcess( q.addr, q.data );
/ Z& O# G l3 E: N8 W }3 b- O' S) x5 i' V& J. b
\ N9 P; E' ]3 V4 ]% ?& Z8 |8 K0 u while( GetExQueue( writetime, q ) ) {
$ p- [6 ?& J" I; Z9 w+ x5 e WriteExProcess( q.addr, q.data );
0 ?# }( K5 q: ~" t4 ^ }+ U% v8 ?) f8 }: T- e' M! k
5 q% U4 ^+ v& h4 ^' O // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7' i) }3 J7 j( B: n* e. P
output = 0;
: {3 T. r, R& M! W& e output += internal.Process( 0 )*vol[0];* O' `& m# b6 b/ |3 k' Y3 q
output += internal.Process( 1 )*vol[1];# ^% A; t6 v; H5 J4 o
output += internal.Process( 2 )*vol[2];
' J X0 o; T6 u* o$ N5 A$ e9 q output += internal.Process( 3 )*vol[3];2 |1 P; E" g# A9 Y ^2 _
output += internal.Process( 4 )*vol[4];4 H3 k5 E9 c6 ?
1 n1 d% @- Q g; g2 H if( exsound_select & 0x01 ) {
5 N8 _3 d/ a5 N$ b+ N, k, ]& O output += vrc6.Process( 0 )*vol[5];7 o5 ?7 \/ M2 ^/ F
output += vrc6.Process( 1 )*vol[6];
$ \4 Q6 M: D' j8 u9 e+ w output += vrc6.Process( 2 )*vol[7];
, ]0 h. ^# G- I: r }
( l" P# Y9 z; }; w! F7 B if( exsound_select & 0x02 ) {/ u* }# v9 G& _8 |7 ^1 X& |
output += vrc7.Process( 0 )*vol[8];
1 k8 O* G9 q( O6 Y( q }
s! U$ E* m# |5 G if( exsound_select & 0x04 ) {- h% v3 g% Q+ m( S2 {6 @
output += fds.Process( 0 )*vol[9];+ g; Q: B) W9 i- a+ X5 @
}/ B, h4 B9 p& U+ a. ~3 A5 I
if( exsound_select & 0x08 ) {
& C- b/ ?- ^; z output += mmc5.Process( 0 )*vol[10];
0 @% i' `8 V# p2 S- q output += mmc5.Process( 1 )*vol[11];
& _! S% e" d4 [6 q output += mmc5.Process( 2 )*vol[12];
* F4 Z# J& I3 A! Q$ ` }
$ c( A2 F Y+ A8 e- B if( exsound_select & 0x10 ) {
# b0 R' z9 n6 I4 j; \( o output += n106.Process( 0 )*vol[13];
0 x0 G+ a; R" F" | output += n106.Process( 1 )*vol[14];
3 X+ ?: z2 @) Y% g output += n106.Process( 2 )*vol[15];
- D8 k- K |& G output += n106.Process( 3 )*vol[16];$ B4 [8 `& N5 n" [$ Z1 u; M
output += n106.Process( 4 )*vol[17];
' d4 h. D- ?* {1 r, R* @/ f3 D& m& S output += n106.Process( 5 )*vol[18];
, l0 @$ P1 ]5 Q( x i9 x2 W; ~ output += n106.Process( 6 )*vol[19];
G* m0 g$ o) |; Q I! L output += n106.Process( 7 )*vol[20];# u% s! A5 M0 }( N
}
" |& T; B- R# s7 N+ [ if( exsound_select & 0x20 ) {
6 g/ w( r$ O) q( z- O* ~ fme7.Process( 3 ); // Envelope & Noise" h% M& p: _# ?2 m' U
output += fme7.Process( 0 )*vol[21];6 r5 l3 B7 @0 q* r5 s" r
output += fme7.Process( 1 )*vol[22];' X* j7 o/ ~4 r
output += fme7.Process( 2 )*vol[23];$ ^6 Z" O. b4 t6 f/ ~* Z( c
}
' Y3 x( L& x P; L) G4 G |8 U$ w% D' _* \. L; k. u' f
output >>= 8;
4 E1 A" ]* n$ C) Q! g4 G$ W/ W' R! t7 \& f& r' l/ p* S. I. H
if( nFilterType == 1 ) {( \( @; {' u$ a, B) Q- {# }
//儘乕僷僗僼傿儖僞乕TYPE 1(Simple)/ j+ A% ~1 o: A$ X% k, V
output = (lowpass_filter[0]+output)/2;! a2 m% n0 \! }& Q+ f3 d, K
lowpass_filter[0] = output;
, Y8 n! a# E: F9 }& p( u) { } else if( nFilterType == 2 ) {- F7 x" p4 }* A$ {; V8 r
//儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1) O; Y5 P& |5 F. W$ `* Y1 G
output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;8 e( A1 T' I& q
lowpass_filter[1] = lowpass_filter[0];! A% ?- q W3 U4 i: |- I: k
lowpass_filter[0] = output;
/ }" G! u' r% X$ v6 b( i } else if( nFilterType == 3 ) {
' g4 t( p2 @# g' q) C //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
8 ?+ B: u6 M* O; ?2 m output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
B7 j, U- k/ Z5 A+ @: t9 g& h8 _ lowpass_filter[2] = lowpass_filter[1];
- p, \! |$ G0 z$ W" |$ L: @/ C lowpass_filter[1] = lowpass_filter[0];3 |8 S9 ^4 N* C' k+ @0 j
lowpass_filter[0] = output;
: p( {4 u0 p+ K8 M8 o% S } else if( nFilterType == 4 ) {
' \3 ?+ w; T* u+ A; s& N //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
6 o0 n9 ^# t; c3 j6 W output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
# |; G3 V* [ ?- R* ]; g! _" E& Q7 v- L lowpass_filter[1] = lowpass_filter[0];$ U. h* Z3 y& |7 I. M C8 b7 Z7 n
lowpass_filter[0] = output;
( {1 M% K9 ~; { }* t! B* C1 @* ]3 n/ s
. G; i+ j6 K7 B
#if 0* |5 l+ L5 B$ s. O2 j# a- k. [' o
// DC惉暘偺僇僢僩
( k$ E d3 g0 ?" }' o {& e3 w& O1 m3 c3 s$ |
static double ave = 0.0, max=0.0, min=0.0;4 g/ c% _, f) W) X$ M F5 f* e
double delta;
' C9 z8 J9 v; h2 H% @" E7 R% R delta = (max-min)/32768.0;: h$ O! r. h! G3 O4 |
max -= delta;) p5 K) G1 x/ ^
min += delta;9 f" F/ ^" h7 u: O
if( output > max ) max = output;
$ T9 C3 z/ a$ @! R1 y if( output < min ) min = output;
$ T, }# u- E) S) i7 S% T ave -= ave/1024.0;& y1 g( D; g4 c
ave += (max+min)/2048.0;8 _5 t# ~: d G) m' O
output -= (INT)ave;, P4 U, a3 A/ ~0 T4 L. _3 Z* c$ V- b4 z7 i
}0 q3 Q6 s5 e7 R$ C# U
#endif
$ N' E6 \3 g0 H; J" j; W9 f#if 1
7 D6 _9 r( _/ f( ~ // DC惉暘偺僇僢僩(HPF TEST)
: B* j: Q0 @+ P0 W {* G- L- k5 g0 e) j3 A5 A# s
// static double cutoff = (2.0*3.141592653579*40.0/44100.0);# H& q( }4 m' S) \# b& o; d: [
static double cutofftemp = (2.0*3.141592653579*40.0);) h1 x0 N5 l7 |' Y v/ q) R
double cutoff = cutofftemp/(double)Config.sound.nRate;
2 @% S9 I- s* z, r static double tmp = 0.0;
- j8 l! k( |' F; B$ | double in, out;# H! @, A3 q: f9 O6 R
8 e8 X2 ]# k) K
in = (double)output;# k* C6 F* T6 f2 C% Y9 m
out = (in - tmp);
9 y7 k. d% Y1 d% P( [ J( }/ w tmp = tmp + cutoff * out;" M; b( l2 Z, a* O
1 M y& n0 ^' D output = (INT)out;4 f8 [# I( f# o( r
}, j5 G+ M; c* p7 b0 W
#endif
' P5 r! i1 P2 u9 }+ w$ j6 B* o5 M#if 0
6 S% F# }6 D' [ Z // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)# s; q# K1 y8 J5 {" c3 ?2 i9 G
{+ @2 U# u! K. n, T; Q1 s0 U" u
INT diff = abs(output-last_data);5 T1 L4 G0 K. t) @' T% j
if( diff > 0x4000 ) {
" n8 U4 Z' m& {6 Q9 X/ ?7 L output /= 4;
. k) E% r) I8 h3 F h } else
* F& ^8 m. v3 K- `) @) u$ ~ if( diff > 0x3000 ) {
: R3 V% m/ Y: |2 A! R* _2 a output /= 3;
. J: t1 g6 r7 o5 {+ @ } else4 x! I: Q1 g0 b% p( _, e
if( diff > 0x2000 ) {4 U2 h4 \- h. `8 ~) R
output /= 2;% a. W) M' V. E3 g- F7 K/ B
}: ]/ A% A( B: Q! |2 V
last_data = output;, e# G: Q% K3 A0 p5 l9 w2 G. ?
}
9 l9 x* D/ j7 [$ d- Z4 c. V, z) W#endif+ L+ V7 x8 V/ p6 u6 O/ d- Z
// Limit
" U" n5 |2 }5 _1 ]2 I: ] if( output > 0x7FFF ) {
0 s: N/ W% L) u, V7 K6 c9 ^8 H output = 0x7FFF;/ ~9 Z) C' R5 ~5 Y
} else if( output < -0x8000 ) {
3 \ {9 a u+ p- Q. N1 X8 K3 b output = -0x8000;
* Q, k" C- c# u: S! L4 K" a/ F. H1 j }! D7 X8 }9 j: B! M! \" |
2 U0 _, @, }) X' ~
if( nBits != 8 ) {
1 F* |! w, b8 p *(SHORT*)lpBuffer = (SHORT)output;
4 |# V- r* ~% L& w% M lpBuffer += sizeof(SHORT);! ^9 f- w+ D) W
} else {3 J7 l& P! u0 e3 s! J! P
*lpBuffer++ = (output>>8)^0x80;( v7 C' z0 A+ i( \; m
}7 A& Y! v5 l! H& o, U" Q4 D: P% C
7 \$ r" X/ V7 x) }
if( nCcount < 0x0100 )
; P; t2 y9 `9 A, ?+ P2 f, k pSoundBuf[nCcount++] = (SHORT)output;) d! V1 M9 u8 Q2 }5 `" s
% g4 E1 Q& D# I( F# t, p! f7 }// elapsedtime += cycle_rate;3 R; O3 ^+ \0 @3 O0 \4 R7 r
elapsed_time += cycle_rate;1 ^- G" C o* {+ }
}# ?2 m3 z9 \+ R* h# _, c# R
: q7 `/ j" }4 P; V y6 _4 x#if 12 S1 t( Q3 n! j! a: |" S, H# Z* J
if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
+ [5 ?; F$ o3 ]" U% b elapsed_time = nes->cpu->GetTotalCycles();
7 n6 c- g: l8 X4 h/ W* T' Z }
; n( R5 Y5 f3 Z) ~/ _8 x$ A' y if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {7 e* S( {3 _* ^. T6 r
elapsed_time = nes->cpu->GetTotalCycles();. y: c& g$ Y) J
}
7 B1 J( Y$ [$ y) F#else
/ s% L2 m8 O* j% x' \0 F& ^6 {$ T elapsed_time = nes->cpu->GetTotalCycles();4 B5 E8 P V8 [0 M( R* e7 y
#endif
4 c9 ]3 L( v2 N; U4 T- ^& u}4 x! d9 V$ d( O: _- Y8 S r
, q9 u1 x7 y# }6 k n2 w
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
) b9 ]$ i4 F0 J2 R) _$ xINT APU::GetChannelFrequency( INT no )" S) W' p5 L9 `0 C1 I
{8 d. N, H$ N }* s0 e
if( !m_bMute[0] )
; X. R) {% v |! S return 0;( Z" }0 n* e C/ M. I3 j. Y
9 p/ l2 Q7 I# C& P+ F3 t/ `8 I" v
// Internal
7 x* k# x2 v& `. u) t$ f# A if( no < 5 ) {# ]% K" Y( r, H% r
return m_bMute[no+1]?internal.GetFreq( no ):0;2 u3 _9 N6 Z! ?# y: o$ M
}% C# e b1 V3 v1 X% N; @% J
// VRC65 [) z3 U" a1 ^4 f& j7 F: c
if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {9 l2 p/ A6 h1 Z" S3 @& A9 \ Z
return m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;7 ]/ z/ K: j2 j2 o& J% M& L* B
}
. P' Y! [* R) P5 ~5 C3 |" v) P // FDS9 q6 t! a5 _1 y
if( (exsound_select & 0x04) && no == 0x300 ) {6 s$ C; s6 @/ }5 m3 O# d6 ?$ {9 R
return m_bMute[6]?fds.GetFreq( 0 ):0;
( r4 m! J% S: P. {! ~6 e }
* x& Y- l r5 h. M$ J/ v4 } // MMC5
- Y" U% [5 o' c- b4 c$ S if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
7 c6 S4 V% `* T. u2 O return m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
0 r1 N. _1 D# z# K" G* W }! d- P8 T) g/ b7 \8 q* D" p
// N106
- {1 V2 \ r1 Z1 [) { V4 _# W. T if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
+ m; ]! u; s4 h/ } H5 I6 h return m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;1 ^$ c6 {$ a! t2 C% R2 }/ _: }
}
. @8 V% x# u) H& Z& E8 G // FME7
( j8 y9 M: w# I' _' q# k/ |( j if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {0 a# x, k- i5 V" u7 O2 j9 g0 V
return m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
& l8 J) P6 w4 K }, [6 A, a+ x" B. [! m; F3 s
// VRC7 \6 G8 P1 W$ N o: |3 k, |, W D
if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {5 ^' I5 j) d1 W3 r. r4 y" W1 x
return m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
+ w5 s/ ?& |0 ^* d0 D4 f7 Q }
9 k: C5 w# s/ ?; @% Y4 e return 0;% k) `' E |! A; i6 ~$ z+ z j
}+ Z4 ~4 q6 Z& J$ ?) v) u) z" ?
, ]% |. s$ X( R" x* E
// State Save/Load3 }( i5 f* [4 A8 x; {( t6 z. [
void APU::SaveState( LPBYTE p )8 n' s/ }' E+ o( v
{# ?& z* s& I9 H& f j$ L8 l. I/ R
#ifdef _DEBUG
- _# g& G) p3 j7 b8 g G0 PLPBYTE pold = p;
9 M# K6 L9 F9 `$ n$ ], ?#endif
! [+ c! y. L @$ ]& N: J7 L; i. B7 z6 G/ W0 ?- ^- n
// 帪娫幉傪摨婜偝偣傞堊Flush偡傞8 i5 o( ^9 _. h! H9 w
QueueFlush();
( ~( I' I+ Y7 N; J9 z& B; r
3 a' p. Y+ y# y internal.SaveState( p );) m3 v1 S. C% E/ q
p += (internal.GetStateSize()+15)&(~0x0F); // Padding" B, m$ |. o' X" j) }
: f& |* s3 H, x$ l8 Q // VRC6
4 ^' V* J) [2 _# v if( exsound_select & 0x01 ) {' P/ D5 |8 ]6 T4 g/ K( E
vrc6.SaveState( p );( |2 W7 g* a& a* R: L4 T1 g8 B
p += (vrc6.GetStateSize()+15)&(~0x0F); // Padding4 ^; F, B6 G. ?4 l/ f
}
9 \' R5 D# M( o) |# f // VRC7 (not support)
( r1 u L# S4 x" E/ n' k- i if( exsound_select & 0x02 ) {- Z3 B- J8 P- m( B+ f. {
vrc7.SaveState( p );- v3 B5 J k6 f, Q$ s
p += (vrc7.GetStateSize()+15)&(~0x0F); // Padding1 E# B6 V9 x% V9 {- C' ^, F" L
}
+ N! D7 R* l1 p9 R$ B/ P9 ~+ i // FDS
: ?+ c3 S3 u3 o \, g if( exsound_select & 0x04 ) {3 E6 @$ u; [( b$ h* X7 |7 b
fds.SaveState( p );+ T# M$ q! J6 x2 D: [
p += (fds.GetStateSize()+15)&(~0x0F); // Padding; s) ~8 [+ v; v, i5 w8 D: j9 H' Y
}( |8 d# E, z/ e k
// MMC5+ ?3 y6 |* G9 G/ r* ^
if( exsound_select & 0x08 ) {
9 L1 C* O' s0 b* J9 _+ p/ j0 l mmc5.SaveState( p );1 o i- V" m2 P+ J, ~
p += (mmc5.GetStateSize()+15)&(~0x0F); // Padding2 `/ W* N/ I, u, h1 }3 z( e+ k
}
. Y {4 v. Y9 a1 d( q // N106
; I! |2 ?4 f c& e if( exsound_select & 0x10 ) {, q7 Z4 L! g; x1 m# V8 T
n106.SaveState( p );
: V9 C, G j6 _. U* ~+ i! K2 } p += (n106.GetStateSize()+15)&(~0x0F); // Padding# I" x1 E9 a6 Y" y+ P
}
; ?- w% C/ e- a& ]% ` // FME7
) ^5 g$ g' d U n! f if( exsound_select & 0x20 ) {) M3 [, e$ r5 i+ K
fme7.SaveState( p );
! C! V/ Z- l1 F8 E0 j- \ p += (fme7.GetStateSize()+15)&(~0x0F); // Padding
! Z# ]' [& H! F8 E }4 v5 F8 Y, i1 o) O
. b7 b7 G% \; ^
#ifdef _DEBUG( R0 Z4 l& l- b6 X
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );! u* ^5 N; [' R) Y
#endif
2 _3 Z* }3 C2 x+ z! o}
- Z2 a; m7 r& x, l) r' {6 y! y9 _, {6 }4 g
void APU::LoadState( LPBYTE p )* w, z [% `: U0 |4 A
{
* u" a y4 d* t) u9 y // 帪娫幉傪摨婜偝偣傞堊偵徚偡* g& i z# r$ P- X: b% D+ o
QueueClear();
1 z" l9 C" o1 ^9 K' ^, e
; E" M" A- H- B/ n' V5 T( X2 R internal.LoadState( p );/ ]4 D+ H/ x' }
p += (internal.GetStateSize()+15)&(~0x0F); // Padding& j+ |" b, d% v; V
7 a. }6 V1 \1 a! y* ^; t: e // VRC64 ?+ c, L/ T# }6 h% v& W/ }: x
if( exsound_select & 0x01 ) {
- u1 C/ Z, F+ T3 I3 E vrc6.LoadState( p );' t* _2 m3 F' N$ Z
p += (vrc6.GetStateSize()+15)&(~0x0F); // Padding
* j; p' s }9 j0 R+ ^ }
4 l+ T& X. _# n8 U" y |; R f // VRC7 (not support); V8 G# k# O. A3 W$ r' F. Y
if( exsound_select & 0x02 ) {, c! }' V( `) K+ Q
vrc7.LoadState( p );$ ~& Q1 w7 R% k4 y
p += (vrc7.GetStateSize()+15)&(~0x0F); // Padding: m. k- v4 i8 Y4 M/ ?- t
}$ O7 W* X1 q3 ]# U4 M' X' g
// FDS
' x) L2 s& G1 |$ X if( exsound_select & 0x04 ) {
( Q0 B$ G+ ^0 l2 ~ fds.LoadState( p );
" q5 J; M+ n/ Y, I- S9 t' F' k% U1 A p += (fds.GetStateSize()+15)&(~0x0F); // Padding
* C+ y# ]2 [# @' j } c; `5 N- |7 z; d
// MMC53 m0 F0 }) `7 S3 t
if( exsound_select & 0x08 ) {
5 G3 A e9 E0 [: I mmc5.LoadState( p );3 f# S0 k5 `; z3 h) q. j
p += (mmc5.GetStateSize()+15)&(~0x0F); // Padding+ ?6 E. c% J8 G
}
* k7 B8 J! }$ d& q7 Z+ D" v // N106
& \/ z( Q" ^' y- r7 k& ? if( exsound_select & 0x10 ) {. A- T4 l% O9 u' Z
n106.LoadState( p );
# a( }' I8 y/ z% p3 p2 S p += (n106.GetStateSize()+15)&(~0x0F); // Padding1 F/ t% \% D, z `* X L* @" ^
}
* z. e) A! _; S# `) h // FME7+ A! [" @1 v& M. Y
if( exsound_select & 0x20 ) {
, [! F* Q4 i' C7 T* X fme7.LoadState( p );
; @7 z. M' X! f3 O8 s( J# K1 E p += (fme7.GetStateSize()+15)&(~0x0F); // Padding1 T! T% E; f$ e6 ^& w
}
& z( v9 v! f8 p1 s( N) ^} |
|