|
|

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