|
|

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