|
|

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