|
|

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