EMU618社区

 找回密码
 立即注册
搜索
查看: 1920|回复: 14

[求助] 【模拟器代码问题】模拟器如何通过代码控制Rom的背景音乐

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?$ g/ K/ X) d' K. G
PS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

发表于 2009-11-2 22:57:37 | 显示全部楼层
看了下VirtualNes的源码,是APU那部分,全称应该是Audio Process Unit

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
$ u7 ~3 h4 Y! o/ C& C5 `* n楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~) @2 [4 ^: ]/ l
这里有相应的模拟器源码,就当送给大侠了~~& J5 R7 }- C+ \2 [, O
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 % L0 ?0 b$ ]+ s0 A
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。  c( w- c, x: x- z* A
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
: Y& D6 p  O/ X: _这里有相应的模拟器源码,就当送给大侠 ...
- Z) u6 Z' R, e- C5 c
聲音部分(Audoi Process Unit = APU):7 s% i; B. K5 C" l! u( ^
.\NES\APU.cpp5 e& E& i6 B* `9 P
.\NES\APU.h
* D( r2 q& m7 K! R* }- Q& \/ T5 z0 B# X# H$ b0 T! h1 ]
6 d' x/ A* Z8 z4 B
影像處理部份(Picture Processing Unit = PPU):) ]9 ]% F! K  t; d
.\NES\PPU.cpp  |, s6 f0 t- e* A* ^
.\NES\PPU.h$ ~" r' Q* N/ ]
/ Y. ~  u# o* r; d
如果原碼用C跟ASM混搭也不錯

该用户从未签到

发表于 2009-11-8 13:03:26 | 显示全部楼层
楼上是高手 哈哈

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。9 Q+ v) n. d& s* m4 X7 S
感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:/ |+ \+ E- w- x( R  f/ s
(由于很多专用术语和算法机理都不明白,所以看不大懂……). O9 u) I! c. F# G/ W: B0 m
//////////////////////////////////////////////////////////////////////////
7 `4 s: B/ J0 l9 |- ?7 B( L/ D) i//                                                                      //
5 A& t. x  l" o//      NES APU core                                                    //
$ n, e$ I! F9 ~# P+ Z) ]7 }: ~//                                                           Norix      //9 v4 t/ @% ~; k5 [' l
//                                               written     2002/06/27 //
. Q+ C5 s' ~, v2 R7 t" e. o/ i//                                               last modify ----/--/-- //
. I, ^* s/ a* L0 f. A4 t/ r/////////////////////////////////////////////////////////////////////////// q! D- X6 C( E8 M- b' u
#include "DebugOut.h"4 J# N7 _5 V5 F8 V; S
#include "App.h"! m& ~8 [( g# _" S  h" c
#include "Config.h"
% J8 I2 {5 e- @
/ }! A( S$ G* d* A0 n5 O3 p/ s#include "nes.h"% `/ d6 p/ j9 U
#include "mmu.h"
. k, S: p' s6 V4 e( h: i, \#include "cpu.h"
& ?5 {: ]6 w$ y* g  ~+ w; I#include "ppu.h"
" \' D% i$ D2 j" ^6 j! E#include "rom.h"/ l/ Q& y+ c7 b4 I
#include "apu.h"" V5 D  ^9 [' n' k, a) ?) |* a5 p

! b' C0 M" P( p1 w! b// Volume adjust9 v5 a+ P6 _% d7 Q
// Internal sounds
7 _5 ?: [. N/ i! O& z#define        RECTANGLE_VOL        (0x0F0)
) t. _/ c5 R1 q3 `+ N#define        TRIANGLE_VOL        (0x130)! i1 m+ X/ Z$ R1 X# Y! p5 z7 a
#define        NOISE_VOL        (0x0C0)7 z8 W9 S, _! P- G
#define        DPCM_VOL        (0x0F0)8 V; d0 S) q& _
// Extra sounds
8 M+ }$ S) U: P6 b* c#define        VRC6_VOL        (0x0F0)8 G& Y$ L* b; R- V- d8 }' W) ]
#define        VRC7_VOL        (0x130)
+ J6 u! {+ ?( ^/ F0 O+ _) n#define        FDS_VOL                (0x0F0)
3 d% H3 n9 k# g0 T#define        MMC5_VOL        (0x0F0)
4 x; q% M9 c$ n* c( U#define        N106_VOL        (0x088)
! c0 b  H% r+ j" A$ o/ @+ d3 U#define        FME7_VOL        (0x130)
$ J8 t. O0 ^, s4 j/ v0 m
/ @. ?! D7 r2 t* X) \APU::APU( NES* parent )2 s2 V" A- t( I# h0 C* n
{6 R# k" @8 `& r, G  @$ S$ J/ b% X0 s
        exsound_select = 0;' k' j% Q; H3 n0 n8 s
0 s- M- `3 J9 o/ \
        nes = parent;: S: l% I& K3 k9 s' V) @* @4 J
        internal.SetParent( parent );
7 t  [( s/ O9 L. a: n, ?2 f  q
$ u! r1 U5 b# }9 [. q$ a        last_data = last_diff = 0;! R1 B! M+ U! B

7 r0 y' h2 Y3 L, R) F        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
+ d; h7 r% M( Y; T1 w3 z: T& @
$ P: d( j3 s4 z6 L        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );' r' v. q# f7 u# M5 G" x
        ZEROMEMORY( &queue, sizeof(queue) );
' y* q: w  G/ t: p        ZEROMEMORY( &exqueue, sizeof(exqueue) );; L5 z2 h1 _* M0 v. a6 x% d
$ x( y) \' G' s% U5 z; F
        for( INT i = 0; i < 16; i++ ) {( m: k1 d9 Y- v5 w: p
                m_bMute = TRUE;6 S: z4 E  j* C& Z+ E* s
        }
: }  z: [  U0 _  d3 M& P. z1 ^}
9 m2 p0 \. W: S" q8 s0 v3 z* E
! P; F" d* k* j8 G0 HAPU::~APU()0 ?2 z% k0 p9 k
{
  x$ P% X1 ]2 Y. @0 T8 `}- O3 F/ K! B$ _3 @' a/ b5 T4 @; f
8 _/ N/ ~5 A% l' e+ R
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )( W4 d5 U+ I  u+ t
{- V' a/ @4 f1 k0 C
        queue.data[queue.wrptr].time = writetime;
4 ^# y$ Y& H; _# k        queue.data[queue.wrptr].addr = addr;& }" q: g; @, P9 [1 D
        queue.data[queue.wrptr].data = data;6 q$ F( k+ y. c% H( d8 C8 d
        queue.wrptr++;7 u$ [1 n9 P$ j8 d  O
        queue.wrptr&=QUEUE_LENGTH-1;: x: a9 m/ q% U8 \5 ^. \4 H
        if( queue.wrptr == queue.rdptr ) {! X6 h$ v- i' H1 b/ l; F) H3 W
                DEBUGOUT( "queue overflow.\n" );) j" |2 g+ K6 I3 \" z
        }5 z$ v8 r/ K( ]) ]
}! I( G+ L) x2 ~2 e& I* z$ m8 u
" x8 x0 Z1 n, |5 H% i# Z
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )# a; Z# I! n5 t1 z3 |
{- m/ X+ @5 L( k* L
        if( queue.wrptr == queue.rdptr ) {0 I; g( S; S8 I) R
                return        FALSE;
7 e! P5 r  m- ~, I        }
5 Z9 I, R; J3 I  k3 R, Q: Y  ]        if( queue.data[queue.rdptr].time <= writetime ) {- r6 x7 w. h- f) R) V3 L' H0 q6 j
                ret = queue.data[queue.rdptr];& x+ ]) M. U. j8 \! Z7 S3 K% H1 J  v
                queue.rdptr++;6 M# S7 x3 R9 W+ @$ q9 l9 P
                queue.rdptr&=QUEUE_LENGTH-1;( V7 C* B8 \: r2 o7 m$ E% e7 ~  X
                return        TRUE;
2 q+ d& y6 p! _4 Z0 v: I        }/ q& x1 i/ I; F0 z/ J% K
        return        FALSE;
) T% e; d! L/ b0 M( |* |}
- n- t. V1 `2 B/ G% g
- ^- B9 z( I/ A7 _2 Hvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
2 Q9 V" C" j7 a4 Z4 g( D8 E5 D; l; ^6 p{
- F5 |& s! W) M7 l        exqueue.data[exqueue.wrptr].time = writetime;
& m) y7 T, h' X% c% w+ k0 j        exqueue.data[exqueue.wrptr].addr = addr;
3 {* J1 _* B2 T        exqueue.data[exqueue.wrptr].data = data;
) M! i3 G+ b7 V        exqueue.wrptr++;
1 W3 S: U, G1 |. g7 {: S5 @        exqueue.wrptr&=QUEUE_LENGTH-1;
$ ^* E4 ~, [5 L: Y' E; H: V6 b        if( exqueue.wrptr == exqueue.rdptr ) {
4 R, B% }5 _+ p: C' w) D# x6 m                DEBUGOUT( "exqueue overflow.\n" );. V! v& P9 _: e* S6 I. E$ h
        }
/ Y7 y. e& O9 \' w}
  H% ]) A! I8 G8 v' }4 K
6 d, s/ o7 a1 c  [6 p1 XBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret ), w/ B/ }5 o3 i6 Y6 Q( q& P8 d
{
. {3 U9 ]/ a  `& a        if( exqueue.wrptr == exqueue.rdptr ) {
  d6 y: O" C1 Z- k5 A' S( w# s9 d; ~/ u- _                return        FALSE;. g( b( I+ q* _1 {+ O
        }
* S! O. D. R% S* C+ M: N        if( exqueue.data[exqueue.rdptr].time <= writetime ) {0 z* c) o0 O8 d& q7 _8 U$ {% M
                ret = exqueue.data[exqueue.rdptr];2 C, K  h6 [  D; Q" P2 F0 t9 ^! F
                exqueue.rdptr++;4 N+ s; f  O* F' p' C8 m8 m
                exqueue.rdptr&=QUEUE_LENGTH-1;
( Z) A1 u: a( s                return        TRUE;
! ]2 l* T3 q3 @6 X9 S3 o" _* l' P        }
; J7 c# O5 x0 A$ O4 h# }3 J1 f        return        FALSE;5 T6 Z) k3 b2 E/ L* f* P" d
}$ L' H4 U: C. I+ D5 _, r' _
% Z: [6 o: s6 A9 w5 q0 w
void        APU::QueueClear(), o0 H& I# u5 o2 r7 K2 e
{. h( k7 c/ {7 y0 M
        ZEROMEMORY( &queue, sizeof(queue) );
! M0 K/ U# w! J" H2 V        ZEROMEMORY( &exqueue, sizeof(exqueue) );9 i- s# _  u8 A/ \- A
}
4 F6 H+ P$ _- q
! Y9 P4 q  K# }( E- L1 X! e+ K0 lvoid        APU::QueueFlush()
. ~0 b6 p5 J" e: n$ `, H{
, ~) t) `$ H: p" ~        while( queue.wrptr != queue.rdptr ) {
* M% n) T. O( r. m                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
8 D& \& V4 V6 R: J                queue.rdptr++;
7 T" `0 w9 n& Y4 o                queue.rdptr&=QUEUE_LENGTH-1;
  ]/ I9 X  Q9 g4 M  i% w        }) [7 ?0 V/ d6 e- M- m
3 d& i# M1 v. P0 ?
        while( exqueue.wrptr != exqueue.rdptr ) {& \+ M( X( L  h/ s/ A1 \& {
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );) P5 x( ?7 K# @$ [: h# [+ y
                exqueue.rdptr++;& b/ z4 Z8 g2 g; W3 V6 J/ u0 Q/ s
                exqueue.rdptr&=QUEUE_LENGTH-1;- d  t4 c6 b, p+ ~4 M
        }
: [1 l% u/ X  P; i/ x/ n}
* D  q" S5 g5 B3 L. R+ F, G" h3 a1 l7 F
void        APU::SoundSetup()
4 X' x  ?/ \/ l1 Y/ V{  X/ L4 n8 F0 Y: y1 N/ {
        FLOAT        fClock = nes->nescfg->CpuClock;  m& `( f  J& q" W: Y. l
        INT        nRate = (INT)Config.sound.nRate;
3 `/ G  y1 k, u! j        internal.Setup( fClock, nRate );
& @' r) y1 ?1 _0 H. w! D: v& }        vrc6.Setup( fClock, nRate );
4 A) j* X( c: u2 e; Y' S' Y        vrc7.Setup( fClock, nRate );
. P* W7 f# v& {5 q0 O        mmc5.Setup( fClock, nRate );
$ G3 n7 A* C% b8 M8 p( {# t        fds.Setup ( fClock, nRate );
, X8 f6 r# P* R& Q5 |6 c0 q$ j; B        n106.Setup( fClock, nRate );7 u, I2 c1 M% {
        fme7.Setup( fClock, nRate );, \; o  y0 D5 }
}
$ Z6 h9 j. Z/ J* d  L1 p7 B: b; J- O( E- y
void        APU::Reset()3 y$ s' ~( \7 I4 P. z8 D7 i9 D' t4 e
{# o. d) S8 M+ E2 N2 \: |3 f
        ZEROMEMORY( &queue, sizeof(queue) );, a/ ?2 c2 U$ V9 L2 \
        ZEROMEMORY( &exqueue, sizeof(exqueue) );) G* T: y1 _* o4 Y' F, z9 u

1 n. l" G% X( v. `; {& O) t/ e, y        elapsed_time = 0;
2 j: H% F9 f9 R4 |" A- p1 K6 N
! d$ s4 w& E* n( h' T8 m" y" m, G: G        FLOAT        fClock = nes->nescfg->CpuClock;
8 _3 Y" O3 }' I5 t5 J        INT        nRate = (INT)Config.sound.nRate;
; X7 h* x& i* @: M4 n. ?& S7 p        internal.Reset( fClock, nRate );
' _  j& {0 m* d% K2 T/ J, A        vrc6.Reset( fClock, nRate );
* d8 K/ m: H  i0 ~' P4 _8 r        vrc7.Reset( fClock, nRate );. E9 b; W$ d9 o5 i9 f! q% r7 P# x
        mmc5.Reset( fClock, nRate );
9 K2 {' J" ]6 x% |6 l5 r        fds.Reset ( fClock, nRate );* H9 S: H1 I6 [
        n106.Reset( fClock, nRate );
3 U$ y$ ^: q) r& ^3 z% r  S        fme7.Reset( fClock, nRate );% N9 G. N# y9 d
# b* U8 K7 D$ b$ S% d) A
        SoundSetup();+ z$ Q; u! G9 ]) ~1 `, _, p
}
( V8 U' w) q( z6 C, f5 C/ F& A( Z. t, c  o0 Y" K8 e; P! C
void        APU::SelectExSound( BYTE data )
& `' U8 o  B7 y3 m{
% w4 V, C+ ], u8 O$ W) z  ?        exsound_select = data;3 [& a; w/ A6 r
}+ j/ _* S/ ^9 x* a. G

" O3 Q' E5 p# p' H/ l5 [* QBYTE        APU::Read( WORD addr )1 ^- }6 J  \, c! G$ M7 Z
{
) c( [. T/ K  g5 e1 l. O" ~) H        return        internal.SyncRead( addr );
% r! s- O, z5 u& g, s4 U8 s}  u1 b: _1 z9 L, _. F5 K

# s" H* L- n4 S; [8 R$ k0 U8 i: gvoid        APU::Write( WORD addr, BYTE data )
  n9 b" K0 o3 n3 _2 i: ^{
/ J' Z- {2 M4 p        // $4018偼VirtuaNES屌桳億乕僩
$ l5 O0 `3 E& c' a6 |, x        if( addr >= 0x4000 && addr <= 0x401F ) {) [* C0 n4 N* s( V
                internal.SyncWrite( addr, data );5 ]; z% W: m/ i. {7 D4 J
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
3 l2 L) ]4 @5 h7 \* C! a' J        }) s+ @: b6 T3 F! {# x! ~
}9 n$ t5 Q, r! x: v- F  i7 U

) y/ I" @# @( z0 L1 \1 tBYTE        APU::ExRead( WORD addr )
. C# D2 x, \; F4 O2 |1 j{
$ j6 p% [- p% V! t- ~! xBYTE        data = 0;
! W+ Q" Q" @; @% N" w8 U( A1 @/ T. V: U- v
        if( exsound_select & 0x10 ) {
( z& [/ T. K% \/ q* Z3 z                if( addr == 0x4800 ) {
3 ]# o2 U0 _; C0 ~                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
4 I1 B" n4 I; M                }1 \4 Z* i5 e& [9 C0 f6 f
        }
- m4 i( b" @* ]6 u        if( exsound_select & 0x04 ) {& H4 T$ J! v/ r, I* s2 ?+ F
                if( addr >= 0x4040 && addr < 0x4100 ) {# o+ q6 S( K: M/ i( z' z$ ^4 f
                        data = fds.SyncRead( addr );
4 S5 H: v; t. P/ j" o* B! Q( j- ?                }
6 i5 P0 o. b; ]$ _        }
' w- r* }! J) y; E2 K1 L& L! A5 C" q        if( exsound_select & 0x08 ) {
0 f5 h5 V6 m% x& ?/ ]+ C& C                if( addr >= 0x5000 && addr <= 0x5015 ) {
, c* ~& w) Z% q# O                        data = mmc5.SyncRead( addr );
; d: _6 m2 {# U3 y/ O/ r- Y                }+ H* s% \! d3 H, @* L! P4 Y; E
        }' e  O- c5 S. g% I' |: ]7 M
& j$ ~' {$ h* C* k; |
        return        data;
: C: E7 ^  ]7 t; v  k. u}
- L3 H5 t8 j5 {+ `2 U' y4 Q- I  k+ a/ ?+ @2 A, ?2 z
void        APU::ExWrite( WORD addr, BYTE data )
9 {- P9 O5 J/ x! \# A{
- r! S# |% [2 I4 {4 m        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
1 d+ K* O# X( ~( [3 O
, S' ?: T. o1 F' `        if( exsound_select & 0x04 ) {* C; e+ y! X$ K! v8 W; W. n2 ~1 k
                if( addr >= 0x4040 && addr < 0x4100 ) {
) z6 }7 d& D2 A3 F                        fds.SyncWrite( addr, data );
9 ?& G+ a" \! O  C                }8 g' q' R' N3 N0 f4 X7 B
        }4 C( a* l9 |+ k# ]" X
, s, ?1 q7 [9 X& z# z- f
        if( exsound_select & 0x08 ) {
) b2 X- b9 A9 a8 j, G% \                if( addr >= 0x5000 && addr <= 0x5015 ) {
% a& @( a. L8 M4 C8 L1 n( A                        mmc5.SyncWrite( addr, data );
* e' q0 o  c. P" I, b8 M1 S                }
2 Q) _5 Z# ?. c) l0 n/ f+ [' y        }! l: _0 X+ w. Y& n" D) m
}" j$ z. W$ f$ ^# u8 l# ~9 r( a
0 x  G+ g4 s( g* ]5 z: m& ?/ @
void        APU::Sync()0 I1 g/ y- d+ q# `4 t
{" q# O" \" ?  s7 ?0 ^" |& q* ^" E
}  O: B4 p8 ]; }- j9 e

7 [0 E, t7 H( d# B# y4 uvoid        APU::SyncDPCM( INT cycles )1 W' F7 B+ W) o, w8 j8 |1 I
{" q5 R4 m8 B+ ?' v
        internal.Sync( cycles );
7 w! H0 q# T! L- C7 b. T, k1 i0 D& _+ s; k& C
        if( exsound_select & 0x04 ) {
/ ^( c' l8 S3 h9 g                fds.Sync( cycles );4 p# M, v; s# V, [
        }
- h- V/ G. y% z- H2 s0 H2 K3 ~- D        if( exsound_select & 0x08 ) {1 F$ T5 E" v$ o1 b" y, y
                mmc5.Sync( cycles );
9 i- ^. S0 g' F% l4 C3 k        }! a0 D# f$ W- r8 ?. U' O- s8 L
}! ]- c0 ]( p! l9 J

' Y$ n0 g- |! u7 Ivoid        APU::WriteProcess( WORD addr, BYTE data )7 G, i0 B% ^4 r5 R9 S7 h
{
; q) e1 i- L/ L        // $4018偼VirtuaNES屌桳億乕僩
: {! G3 k7 z2 [# ~# V8 n2 V0 }        if( addr >= 0x4000 && addr <= 0x401F ) {! D/ n4 h: o/ i* ~
                internal.Write( addr, data );
" n# I, e6 u3 |, k        }
! m$ V, L" f1 K. s}, b6 M9 b0 c& M' m" m7 K: {5 h2 Z( C

5 h7 q- x. s/ x( k& t- ^1 qvoid        APU::WriteExProcess( WORD addr, BYTE data )
& @+ Y' h; w; a$ q& e{& H5 S* ~( x, @$ [: u, j4 p9 A" q5 z
        if( exsound_select & 0x01 ) {
* i1 s  y2 l' W+ N                vrc6.Write( addr, data );
, d1 E: P- f- I# b& E) e( _$ L        }
5 }2 L, M# S# m6 ^& y4 M9 j5 P        if( exsound_select & 0x02 ) {. T! L1 h2 ?* V$ d
                vrc7.Write( addr, data );- P. A* P8 L2 O9 a7 F1 S
        }
4 r3 r, q9 R( B: U- I# v        if( exsound_select & 0x04 ) {
; D! _) Q7 p: P! Y. M                fds.Write( addr, data );% o0 d# N/ L' x3 X  v: f' \1 g
        }
' V0 D, s0 `; b- z. \+ C- ]* q        if( exsound_select & 0x08 ) {% C6 o# I7 v( @$ E
                mmc5.Write( addr, data );1 r; y# S! B! w2 k1 J: u; w  z
        }! s" r7 l+ X  d9 }# c* H+ s+ U
        if( exsound_select & 0x10 ) {) W  `  m  G* `( e& t7 p
                if( addr == 0x0000 ) {
. x6 `6 r% |2 d" i5 K- j                        BYTE        dummy = n106.Read( addr );
/ W- Y9 m2 |8 ?0 `8 O                } else {. |  l' ^  G% k: t) T2 D
                        n106.Write( addr, data );  q/ g. h* p4 L. \; n; f) i
                }
$ E! X8 @5 D( a& H. L        }" u: X( C' v% _/ B, y
        if( exsound_select & 0x20 ) {5 l- J8 }: ~0 Q% n% s: ]
                fme7.Write( addr, data );6 J* n( b0 I/ b4 Y: S% p) _
        }
$ e( o8 t: K) m5 e}2 N; d  r7 j* p# a

1 R. [0 g0 P8 L# [/ |  O* jvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
- X4 v! _- x8 H( l# }# h+ J. z/ Z{- `" h7 V" `1 r* ^
INT        nBits = Config.sound.nBits;& ?! Y! @$ B3 M4 l+ r6 I; |
DWORD        dwLength = dwSize / (nBits/8);
2 o+ D( S& l- E6 @) N0 pINT        output;/ D/ j+ C& [+ e& T3 l
QUEUEDATA q;
$ n1 [5 u, M. _$ b7 u9 V( ^# x7 t& ADWORD        writetime;
  J: o) T( E! R. C% V2 n7 G$ C$ A. k1 e
LPSHORT        pSoundBuf = m_SoundBuffer;
1 o5 E" t# ~3 T1 ~* X& P5 m) [+ _& _INT        nCcount = 0;' I3 t) M) i, \/ o1 B- `
* h4 P7 m6 M: ?- q8 X8 P/ Z1 U
INT        nFilterType = Config.sound.nFilterType;
$ x+ `2 f5 q' ?9 T' F+ i" u/ d& _* F- w0 {, p
        if( !Config.sound.bEnable ) {
8 ^+ l, u0 P0 U  X" H                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );* }( [: l- }5 ^, |& h/ Z) e5 \
                return;$ ~. i3 [0 ~  |6 D
        }4 u, I# n; C7 d

5 P( w; ~3 a. ]5 k: p6 `        // Volume setup
# R/ i( n" w& G        //  0:Master. Z2 r. O" M  u8 e! R* T
        //  1:Rectangle 1* q8 P' d: I2 Y
        //  2:Rectangle 2/ T2 v* D; r2 A0 f' U
        //  3:Triangle
+ P" u) i0 s: V# w        //  4:Noise
0 E6 X5 L9 K) u, z1 B  C1 r+ i        //  5:DPCM# K' t7 j0 k, \0 G! V' O, \: O7 `; M
        //  6:VRC6
9 H. k$ F* a, x5 t7 p4 `( t. D3 K        //  7:VRC70 Q; }4 f8 W; t
        //  8:FDS
+ ?! H6 Q% z; j        //  9:MMC5
+ o. y5 q' D% F( g" L        // 10:N106. {" E  G2 X% V. A$ l3 c
        // 11:FME7
! _9 d1 I$ B3 {+ r! |/ A6 t        INT        vol[24];
$ G: I* {6 `% \        BOOL*        bMute = m_bMute;
, z- o( ?3 y. h' G  T( i( S( g, c        SHORT*        nVolume = Config.sound.nVolume;
* \* M1 ]7 L1 D' J4 J7 A2 B, I# u, b5 }* D6 \' D$ Z7 q
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;. D# g4 x$ a+ y1 {( K$ c& a
# O( U* Z$ t& ~* E
        // Internal/ j5 H6 d. P- p& @+ ?/ V
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;2 K( |! [* o2 z6 D
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;1 D$ S1 n% w2 Q7 j6 L8 K! ~7 m
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;2 n" _# B7 D1 q0 [+ \
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;" E& d8 i; j6 |( f4 y# v% N
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;  U# |8 @$ n( V0 e1 ^# @, p6 m

* F" Y8 a; U9 y        // VRC6( S6 x* [) u, |
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
( u4 S$ S: K1 W' i, J        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
4 b6 n% S# a; q. w        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
6 [1 _0 L& w( l" R0 f+ E
: O& C2 T: r+ r0 P# N        // VRC7
7 \  R6 O8 P4 l2 s. K/ P        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
' K! Z7 Z/ n5 x1 K7 c
  [) E' E0 w) X        // FDS  p% Q9 A( k5 Y: |
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
+ t( _' G- u. }
3 L. }0 @1 T5 p- Q" G  D; E        // MMC5
! N' H+ k; Q9 J# ~& w- |1 f+ B7 C( s        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
: _2 `% _+ L' w- [9 y0 O& M0 P        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;) T7 \$ O: V2 _; p: H5 M* R
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;  D$ |  E1 A. ]2 V' h3 ^) r0 U
$ _6 J; ^: O! n
        // N106! B& j+ f8 h8 N! ]. Z
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
$ l: ?! H4 K$ h. \. [3 q2 r0 x5 m        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& P. W3 ^+ I# m9 O/ w1 a8 o5 A        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
6 N) K" L1 q( z1 L: L& O        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, w" {4 |, S- c# p7 x        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; K; f7 r4 Q. f+ |7 A% @
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;/ M, m, a" C, I' D: ~
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
1 d- R7 s3 [# h; w        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' c) O$ g1 ]9 B+ S

% w: _: ]1 w# U8 U8 B; ?        // FME7& P: k0 s* \4 M2 R
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;+ q& m# g* \  n5 s9 N
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
, i% c! a$ _+ A        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
; R! A# I% N9 I0 ~1 U' f) |/ z7 ^$ X8 M* f" t
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
. @5 E! v( n- \4 F* d        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;  I4 N( q5 D* C
3 E8 g) Q) G0 n( ]
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟7 e- g& o% e) R0 c
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
$ P; @" a% z0 b( x. t2 A4 y                QueueFlush();+ [4 b3 ~4 d5 w3 F
        }& R8 Q5 U' U" z) l

( a7 F. G+ z. M. p: k0 }/ `        while( dwLength-- ) {
5 G: U5 b& I: ^$ d                writetime = (DWORD)elapsed_time;
  o$ S5 Z7 B  }' L2 O8 q  K2 [; [7 l. V* i0 a
                while( GetQueue( writetime, q ) ) {
8 D9 R- r' M+ {/ D+ k. o  F  P) b                        WriteProcess( q.addr, q.data );) y2 `  w" E1 A' s# v7 G+ U
                }+ [- j9 k/ O5 p! {7 b" R

- r& \3 G' ?9 d, ], ~                while( GetExQueue( writetime, q ) ) {2 r$ G" n/ ]( F
                        WriteExProcess( q.addr, q.data );- q& [& O) ~7 g  y5 [$ e: I/ V% S
                }
. E# j  o) }8 Q& j: L' E( F2 a
: H) W5 c; t( c3 ~, y                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7; j* T1 a* x1 s; l
                output = 0;3 c) q: b& b" X
                output += internal.Process( 0 )*vol[0];
" p7 {. t3 p; {/ s                output += internal.Process( 1 )*vol[1];* T" h/ r; k$ B: g3 X8 K7 q
                output += internal.Process( 2 )*vol[2];
7 r: `1 M0 _% H( v/ `/ s$ L/ x                output += internal.Process( 3 )*vol[3];
$ I$ a; u6 \3 y) V4 j$ `) V                output += internal.Process( 4 )*vol[4];
4 U; W1 N1 b* v7 ]) I/ h% _* |9 ~! n3 p4 w/ H4 }/ n* d
                if( exsound_select & 0x01 ) {
: Z4 ?" r$ a) t; M. I2 c3 G                        output += vrc6.Process( 0 )*vol[5];
( X6 f, a2 q) J& e9 J* n# H  g. T                        output += vrc6.Process( 1 )*vol[6];" {0 ?6 W# }9 X. j2 d
                        output += vrc6.Process( 2 )*vol[7];
3 w! Y9 _3 X. ]                }
1 O9 V$ X* @2 Q- M# q; K6 Q6 y                if( exsound_select & 0x02 ) {. L' t) [( h1 v& b# |; q, y& j
                        output += vrc7.Process( 0 )*vol[8];
- {& _/ p. f3 S) b7 F                }
( F7 A; k# o9 D                if( exsound_select & 0x04 ) {4 ]$ n0 Z& L2 {. c
                        output += fds.Process( 0 )*vol[9];
& c9 x+ n# H0 v& o& i+ Z8 J2 P  @                }3 \0 X9 W1 ]2 r( B
                if( exsound_select & 0x08 ) {
& {$ f- k. {$ O5 e- i                        output += mmc5.Process( 0 )*vol[10];1 `, l( v- K% K2 a
                        output += mmc5.Process( 1 )*vol[11];/ J4 y3 m* p. b
                        output += mmc5.Process( 2 )*vol[12];* G- t0 F2 n, v
                }$ `3 h' u% U: e3 N# h
                if( exsound_select & 0x10 ) {
1 }5 z" y6 h( Z7 y) {                        output += n106.Process( 0 )*vol[13];
; @5 n7 Y1 W0 B2 h: |                        output += n106.Process( 1 )*vol[14];0 Y. A( }% r  U6 _( B2 u
                        output += n106.Process( 2 )*vol[15];
, ~; _2 [, f2 K" K3 w5 R7 u- E                        output += n106.Process( 3 )*vol[16];
3 k0 v' l( ]& O- ~2 ]3 Y                        output += n106.Process( 4 )*vol[17];+ ]3 t( ~. z8 E; \
                        output += n106.Process( 5 )*vol[18];  _" Y( r# m: o3 P# H, {# @- ~
                        output += n106.Process( 6 )*vol[19];$ m2 q  d5 Y5 W1 [! e" n
                        output += n106.Process( 7 )*vol[20];5 z+ W/ H6 ~" l! D1 Q1 g9 y
                }' k! M6 K/ [* R, S5 s
                if( exsound_select & 0x20 ) {
$ v5 ?/ r& Z' P5 l                        fme7.Process( 3 );        // Envelope & Noise
9 m# j4 T% C- W( j                        output += fme7.Process( 0 )*vol[21];) N' H5 ]9 G) k5 S% s6 b! U
                        output += fme7.Process( 1 )*vol[22];1 c8 R: R( j% L' m$ y* P+ `+ \4 G
                        output += fme7.Process( 2 )*vol[23];7 x" Y2 J+ i- B: H8 n; P
                }
3 M/ b4 `& x+ s  D4 ]1 T2 H* U( {$ ]3 f9 a" f3 ]% T, m& n
                output >>= 8;
0 F& q$ a4 R6 z' A6 v( e! p+ u% ?# A8 S0 u
                if( nFilterType == 1 ) {* X8 M7 p& Z  N2 C1 q- V
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
; w! x" D2 ^; W) V: H! [                        output = (lowpass_filter[0]+output)/2;& G! z# m4 K9 X/ d# i" V; B
                        lowpass_filter[0] = output;, a0 x$ h3 f1 E/ W; \8 q7 e5 C7 s
                } else if( nFilterType == 2 ) {
0 q& T! E6 a. s" ^# P                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
" j/ C3 }$ w8 l: p% m3 I                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
$ e3 T* x: Z% ~: A; \                        lowpass_filter[1] = lowpass_filter[0];
+ Y' Q, J% b2 R7 v  a                        lowpass_filter[0] = output;
- q9 N+ M$ ^+ B+ a7 s                } else if( nFilterType == 3 ) {: S. Z; I  {" y0 C! G1 o: w
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
4 z* _5 t# R7 N& w7 C                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
2 t2 F! [9 z1 W4 l                        lowpass_filter[2] = lowpass_filter[1];7 [! W  Z8 j; }' r  w0 C+ w
                        lowpass_filter[1] = lowpass_filter[0];
, N3 M1 i6 `& p* u3 X                        lowpass_filter[0] = output;
2 n0 e6 i! ]& N( [. B9 x                } else if( nFilterType == 4 ) {6 \  ^/ U0 o  }4 l
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)% r; }$ O' y- C% e  w$ Q
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;% e, X" H7 n0 B( p& E
                        lowpass_filter[1] = lowpass_filter[0];" C- G  n+ B4 h0 j$ r/ ?
                        lowpass_filter[0] = output;* ?$ Y/ I0 ], ?5 y" T- _+ Y" ~
                }
2 o9 c! E/ ~9 A; r0 u; R# `4 ?
% M% z$ N2 u! J% |7 o8 k) Q#if        0
6 S" z+ @, ~7 a) d$ p                // DC惉暘偺僇僢僩
7 n7 d& t$ g6 D                {" ^. Y7 f: d8 @+ \) `2 b/ L2 _
                static double ave = 0.0, max=0.0, min=0.0;
' f: t: Z, m4 p2 ?& f6 Q                double delta;
3 P, T9 P! _7 e- t# o                delta = (max-min)/32768.0;3 k- G# B8 {  m
                max -= delta;
0 q! P( e& {7 p, J4 j( N* h                min += delta;
) U- u# Q4 a, ]                if( output > max ) max = output;. Q+ G5 O& P2 \1 h
                if( output < min ) min = output;
( }9 g% F% e, i' t. I7 c                ave -= ave/1024.0;$ I! \1 V  r0 ~: l# A& H! i. F
                ave += (max+min)/2048.0;
  O# E! m* A9 H3 g( d                output -= (INT)ave;) v# r, K! m$ o/ @* Q$ d6 n
                }
# x+ F1 s. S& Y5 a- W( n#endif
3 p8 l2 c* w" n3 h# g#if        1
5 C) u  \7 a  c3 l1 i7 N9 z) z. l                // DC惉暘偺僇僢僩(HPF TEST)* z: n$ ?! P  A  z1 s6 J& K; P3 k  u
                {1 c( O1 ?- K2 C( a
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
: N. ?8 q- D2 V& B! Q                static        double        cutofftemp = (2.0*3.141592653579*40.0);
* |7 r- ]! Y  o0 y! M                double        cutoff = cutofftemp/(double)Config.sound.nRate;; W0 k/ {1 h. Z
                static        double        tmp = 0.0;8 B+ c! j" O- y% o
                double        in, out;' a$ I$ n6 n2 f1 I' t/ J# x4 ^1 I

' Z5 y  F% w, Q8 S- l! Z! v                in = (double)output;5 R3 k1 Z3 V! @' X
                out = (in - tmp);
! J6 d/ ~8 ]0 Q2 M                tmp = tmp + cutoff * out;
7 c# @* M+ G" ^  R' H  J5 r/ d
/ k$ Z! W: D1 D                output = (INT)out;
" k' x5 T; t$ V% J  ?  l                }/ {0 V1 w# Q. H, q
#endif  x. q, ^. P1 ~# c: q
#if        0
/ }" Y) A; I2 F: L4 q1 N5 g8 O' L. p$ M2 ~                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)- S7 k' r' j) o. {$ O
                {
5 I! B- x( a& l                INT        diff = abs(output-last_data);" A9 x3 p* U2 j, g' B6 {/ w$ B
                if( diff > 0x4000 ) {
2 F" J. Y. X" t2 T  w# Q! r                        output /= 4;4 g; i7 N, y) ^6 \
                } else
5 K1 [& x. m  j# y  J" z! x, V7 q                if( diff > 0x3000 ) {7 T; p; }% S& ]* E3 e- X9 k* ?
                        output /= 3;% u& B. B1 ]+ l4 v2 Y- T+ y# ]1 `) \
                } else/ y9 e& T8 l* f
                if( diff > 0x2000 ) {
* r9 C4 W" k" B- X0 W                        output /= 2;
  ]# @& @( j' |. M% _4 h) r                }
  R' m  C& B8 l+ J9 |5 W. |4 o                last_data = output;
8 b9 T9 T. |( Z; ]; W- T- h                }
. t: {7 p2 N( ^8 ]# s: Q#endif$ B; G$ B. x9 ?% q
                // Limit- F: F+ f! M( R1 i/ ?0 O8 F
                if( output > 0x7FFF ) {
' v4 l- l* y/ b& O                        output = 0x7FFF;% ?4 R% H0 {, }
                } else if( output < -0x8000 ) {$ `- h4 k7 e: l) ^& |; a- [
                        output = -0x8000;
# m5 C! A, E( t( p) X                }
1 r- O& j9 a( X# o/ t' l+ h* w: x) I" ^* ?6 q9 s- r
                if( nBits != 8 ) {- R# G+ [# O/ Q7 I
                        *(SHORT*)lpBuffer = (SHORT)output;
+ |# e# {( i* o6 u! f4 a1 C                        lpBuffer += sizeof(SHORT);
# \* @1 j$ ^6 ~                } else {9 {3 I* ~1 |, T. U: s: q
                        *lpBuffer++ = (output>>8)^0x80;
' ?% O! g" {9 W) T6 s6 n4 i                }
( J, X- n( H. _4 ^$ y4 A2 V( N: p8 v" y2 ~
                if( nCcount < 0x0100 ); R* k  ]2 G6 w8 Y7 ^8 ]& o
                        pSoundBuf[nCcount++] = (SHORT)output;$ W) h6 j# a1 h% w( n2 Q% C% }
! C( }/ m) z0 z3 w. U, b
//                elapsedtime += cycle_rate;7 W5 i* R. i  t# b& ~. t* c: o
                elapsed_time += cycle_rate;
* J% R3 V; m) i        }9 m/ |+ b, O4 P& w5 T# U

! t4 [- {3 K% F: x#if        1
# [3 ], q/ L9 g" _6 B+ x$ n        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
2 q/ S) `" g# F+ ~/ x                elapsed_time = nes->cpu->GetTotalCycles();
! M: k8 p3 l  H        }
7 C6 P7 p" U% O; J  @6 z        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
3 x  r/ t0 X* B, S' V                elapsed_time = nes->cpu->GetTotalCycles();
5 i0 v* c) [) e! O, i" p        }
) I& ^2 q9 B- D) p% _) L# C#else
$ Z2 i2 b6 A7 o* R9 z% X) {; L        elapsed_time = nes->cpu->GetTotalCycles();) X! e- I( w( [8 D
#endif
9 ~8 b) K! O; Y$ @) l2 e0 {}5 D, G$ [* j+ Q" I: p1 z7 g6 q

6 z( a0 _4 Y, V9 t" u5 R// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
  c3 b% }# e+ j  n+ J3 t3 rINT        APU::GetChannelFrequency( INT no )! H" {# ^) B2 Z2 R* q
{
: D7 v# Q5 Y- u. X        if( !m_bMute[0] )' ^5 g# W/ c' y+ y3 t0 D
                return        0;: J# X0 P9 }; Y# [; m: _  x# d
9 e7 ]0 F5 S6 B2 v, _/ H
        // Internal
6 }  h) v/ _- M9 \' k, c* ^        if( no < 5 ) {7 Q- k9 d. W# o/ B
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
# [; `; ]. H$ h' o. P        }- f# J& X9 n' M- p
        // VRC6
- X1 H, `' W/ ]3 @! A. T" ?        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {9 M8 q! S9 y% f( O: J3 m
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
, R& d( w% {6 J6 t; G. M8 R2 @        }
& Z' G- X! {6 e- _! k* K        // FDS
* i2 Z0 G: P4 s$ l        if( (exsound_select & 0x04) && no == 0x300 ) {- R2 g% E2 Y4 j" h, ]
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
2 M0 L7 L' ~1 t$ c        }
& J0 g7 }/ o. D) \; @0 L6 S        // MMC5
4 x1 |% Y9 g: b6 x; Y/ e        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {) C9 ?* m) m4 x. O( u
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
. g8 h* X, H, g        }
9 M3 R5 A6 z3 |        // N106) s; H! W; q" E" I
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
# e* d- {& {/ O9 t) |7 U* S! X                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
+ h5 v. [% [6 t& O  X0 q+ z/ q        }3 _% M2 }/ j8 D& T* k) [& j
        // FME7( F5 B) d. g" J
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
) P. Q0 a5 p  t( u. k% n. a4 G  R                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;+ ~% R3 z3 A  U' X2 z
        }$ h) S' M% t- n" P8 z  g" E/ [2 j
        // VRC7. u7 y/ \2 H+ A7 U7 ?( R
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {$ Z. E/ c. y8 u7 ^2 d9 |+ j9 @
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;& b$ E8 V8 ?+ Y/ M, y
        }# f5 n0 o( s0 b; b: \7 I
        return        0;" G' ^/ l  ^! d0 i# s7 ?
}7 J# U: z8 q6 B' a! V

: @/ O% ^7 L/ U8 b  K" Z// State Save/Load
6 S* `* `8 _/ A7 tvoid        APU::SaveState( LPBYTE p )) Z- W. Y7 B1 m
{
& i" n4 ^- e# N4 E$ X3 N* p#ifdef        _DEBUG1 ]9 o# r. j# ^4 z* s0 R' X7 n+ F
LPBYTE        pold = p;6 U9 f  l; v- ~- D
#endif% p: H8 L( M- `  K4 E: a
$ i0 `( w3 `' i2 G% w  ]. Q' r
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞6 ?4 R0 e& J3 G' I* O* X
        QueueFlush();1 E* F8 ]  m: ?
# ?1 ^& V1 a) o
        internal.SaveState( p );  |, x4 a7 r0 U/ O' e! J% f
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
* B7 u1 _! Z8 U( C0 K' B. e2 m0 f) t
        // VRC64 C5 x: O% U8 x; q, I7 o& a
        if( exsound_select & 0x01 ) {
. m1 h8 M  H( a                vrc6.SaveState( p );
: ]$ y: }6 {* B9 u2 S" v9 s; X5 v1 r                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
& S) Y4 j. ?1 l& B        }
" J1 R4 o& `. M% \1 t- N, P        // VRC7 (not support)
5 J" z  ^# C3 T  t/ n        if( exsound_select & 0x02 ) {1 X: Z& F" e: x) ^% u1 X5 @" N
                vrc7.SaveState( p );
0 o" Y4 D2 V/ F& ~- T7 J                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
. e9 P5 O7 h0 A5 P& `" W        }$ q% o- P, d7 I7 @# i+ l
        // FDS: ]" c' h3 H0 o( t% V8 `" V
        if( exsound_select & 0x04 ) {
" R1 Z9 G; E: S                fds.SaveState( p );
/ u5 g+ b- I+ g/ F! _                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
, @/ ]6 _, ^6 R- m9 |. A        }
7 v0 j( g0 X0 q+ W* N, ?6 k        // MMC5
) p! Q" L2 A# m( ]        if( exsound_select & 0x08 ) {
' A/ ^" e9 i7 Y+ B0 e) K                mmc5.SaveState( p );% `' u( _: o' M
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
7 t) |: J1 g, d! E# t: r        }
7 h! F" |# X( h1 H6 s        // N106
4 [4 }# h% @, S6 l2 M! I8 R        if( exsound_select & 0x10 ) {: m4 ]. ^7 Y  x
                n106.SaveState( p );
( J& R/ f, b" G- x' Y0 {                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
, l" D) N. \; g3 b- `6 l. H  U        }
) _; b+ H* ?9 P6 h! E        // FME7
8 |+ A) S2 K6 \. V: G% b        if( exsound_select & 0x20 ) {
8 ^; g" J1 t9 x& ^: c) V+ U0 s                fme7.SaveState( p );3 h; z4 j8 q& K
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
1 N! m( D) R. b  G1 M7 r: b4 x        }
3 d) L- f, w* y0 K2 L4 [) ~2 K
) m9 q) R4 U& o& _# H3 V#ifdef        _DEBUG, Z9 y8 ?2 z7 P. l/ \
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
. \8 r' ]9 [+ ?0 t# N7 O- _* e#endif
* J& Q% s9 q/ Z9 y$ r6 H3 F}
2 Q/ m, H& I; z2 b7 Q4 W$ a% C5 _
void        APU::LoadState( LPBYTE p )+ r, Q8 O, r2 c0 y4 j  C& V
{  a5 N! `" I* W4 B9 x3 L: k& p
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
$ s, F% G% G! D. k& ]        QueueClear();
7 S" g6 S2 @: V' w% X* g8 H5 U/ _# N7 Z
        internal.LoadState( p );) O, Y1 l: t" Y! R# T1 \
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
) \2 k5 Y2 ]* l; l7 y% G+ O7 X6 h% L
        // VRC6$ \0 i# z; z% w! G
        if( exsound_select & 0x01 ) {
1 r. X3 D- |! d: a2 X9 T                vrc6.LoadState( p );
/ e1 E1 J) a# j& E" a+ F  `                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
' \  k0 L0 X0 W5 \4 U* A        }
/ U  H( `) y/ @) v4 x        // VRC7 (not support)2 l4 t5 \9 T0 k- F: e" y$ r+ |
        if( exsound_select & 0x02 ) {
5 }1 v" L5 q* G" O( N0 b5 H                vrc7.LoadState( p );
7 M$ n* j8 r( r8 K  a                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
  d0 L" d& F8 R7 w% @& i0 |        }4 b2 b# |2 F# k# B5 o6 X$ W
        // FDS. G1 h: X# Z' u. s/ X
        if( exsound_select & 0x04 ) {
, L4 w2 G# v9 Z% T, X                fds.LoadState( p );" l" Y8 u2 z+ Y" e
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
& P* s' l- h) z; D! U2 R& E        }
0 y, y2 Y' k1 Z9 q8 Y        // MMC5
8 H$ ]* S4 D& C; J9 Z8 m        if( exsound_select & 0x08 ) {) _% I8 I. o/ V
                mmc5.LoadState( p );. \' y+ b; {! r4 j% q
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
" r+ |& P! T6 C/ `  L8 _5 E0 A$ D        }
: \* M4 _% T) W3 v* u" K0 {        // N106: G* l6 I1 u0 {+ g/ k3 A
        if( exsound_select & 0x10 ) {
* Y9 M& f2 W4 v* a/ s# j) y                n106.LoadState( p );+ |0 q* x( m6 ]/ o9 ~* i& |
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
% ?0 g" b7 ]2 J6 W        }9 G. g& e- x& Q. X2 [0 O
        // FME7
/ y3 G& p3 s" d4 |' s2 h        if( exsound_select & 0x20 ) {8 T4 S8 H( P% d/ |1 y
                fme7.LoadState( p );! I1 e0 M8 D8 i) t* g
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding/ ]& K9 p- _/ s* [! ~0 @3 V
        }9 A1 ~* X; Y0 e& L# I
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
/ ^0 H# w( V$ D" D& u可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
8 s/ v5 a3 M, c+ e( t  q; w( E感激不尽~~
: f! B3 ~0 G, C' p6 [4 Y
恩 我對模擬器不是很有研究,
4 N1 B3 ^% X# Y* e0 q雖然要了解源碼內容,可能不是很困難,
) S5 p0 v! ?+ Q5 z不過還是要花時間,個人目前蠻忙碌的。
% u$ g+ C9 [0 s* p" D, k* q& O+ g1 _# K. D5 `2 a9 r3 D* G
給你一個朋友的MSN,你可以跟他討論看看,
: z' a# t0 h9 R8 i) Q5 R# ?) @他本身是程式設計師,也對FC模擬器很有興趣。* q4 @$ c$ E  t( K: B" X9 K  n: W! S

! A" l: u8 `, J# s0 f7 g% ?  x3 j  DMSN我就PM到你的信箱了。
5 q: L, _1 @6 {! l% n6 U+ Y$ B* y7 R* c$ h9 _+ W0 q
希望你能有所得。

该用户从未签到

 楼主| 发表于 2009-11-9 13:23:59 | 显示全部楼层
呵…… 谢过团长大人~~

签到天数: 80 天

[LV.6]常住居民II

发表于 2009-11-9 16:02:29 | 显示全部楼层
团长的朋友都是神,那团长就是神的boss。

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表
$ ]- j5 X6 a7 O7 q& }, f' f呵…… 谢过团长大人~~

; c$ e3 }% Y7 _  i* z& J
& R- V" ?6 d) D! S# l哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
4 ^% a  R7 {7 Z9 b3 x; c团长的朋友都是神,那团长就是神的boss。

$ x1 p5 K/ U- i哈 不敢當,我只是個平凡人,' l2 D: v) D1 L
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
* {; F8 F; I1 s+ G5 l  [" M( k) eZYH
3 K- d- U  c& M) Y& [6 ?QQ:4147343068 W- c+ b/ _1 H9 p3 T& ]
Mail:zyh-01@126.com
) E6 X4 Z7 s) l* q) u2 b
% d6 v6 Z$ b# t9 Q他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

 楼主| 发表于 2009-11-27 09:48:23 | 显示全部楼层
再次对团长大人和悠悠哥的无私帮助表示感谢~~

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 9 x) Y+ ^0 a* C% [( g& D
再次对团长大人和悠悠哥的无私帮助表示感谢~~

2 B' K) y* Q" @# b& N! v; T不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|国治模拟精品屋 ( 沪ICP备15012945号-1 )

GMT+8, 2026-2-8 13:42 , Processed in 1.072266 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表