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