|
|

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