|
|

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