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