|

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