|
|

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