|
|

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