|

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