|
|

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