|
|

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