|
|

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