|
|

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