|
|

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