|
|

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