|
|

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