|
|

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