|
|

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