|
|

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