|
|

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