|
|

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