|
|

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