|
|

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