|
|

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