|
|

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