|
|

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