|
|

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