|
|

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