|
|

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