|
|

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