|
|

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