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