|

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