|
|

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