|
|

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