|

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