|
|

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