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