|
|

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