|
|

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