|
|

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