|
|

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