|
|

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