|
|

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