|
|

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