|
|

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