|
|

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