|
|

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