|
|

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