|
|

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