|
|

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