|
|

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