|

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