|
|

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