|
|

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