|
|

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