|
|

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