|
|

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