|
|

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