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