|
|

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