|
|

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