|
|

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