|
|

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