|
|

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