|
|

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