|
|

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