|
|

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