|
|

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