|
|

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