|
|

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