|
|

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