|

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