|
|

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