|
|

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