|
|

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