|
|

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