|
|

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