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