|
|

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