|
|

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