|
|

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