|
|

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