|
|

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