|
|

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