|
|

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