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