设为首页收藏本站

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

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

  [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?
+ y: a3 x2 |4 v5 v. p- w6 S/ _. FPS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。" V/ M' g3 d! _5 @" h
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~1 k9 H6 |3 w- q; x8 z4 q
这里有相应的模拟器源码,就当送给大侠了~~
( {3 E; Y1 C" u9 z( Ahttp://kenkao.qupan.com/5096520.html
回复

使用道具 举报

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表   ?8 O+ K$ V; T0 D1 A% I0 B
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。  @8 ]8 r" R1 Z/ w
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
; h. {5 L; A6 X2 B0 H, H这里有相应的模拟器源码,就当送给大侠 ...
2 ]- u8 i( Q* t
聲音部分(Audoi Process Unit = APU):
: X+ H( u' u; c.\NES\APU.cpp
+ B  J" L: c& \1 a5 I0 h+ [7 z# F' _+ h.\NES\APU.h
- O/ P; Q3 X# ~2 A5 [: v
, {$ [0 i. @2 n! e
$ c, u. L5 [3 j, U$ Z影像處理部份(Picture Processing Unit = PPU):
2 k' d. }4 g0 D.\NES\PPU.cpp
! y' o& o* t1 a0 B* t0 F* d.\NES\PPU.h/ P9 ?3 Z& o0 A5 z
$ Q( a, q9 p) B* o9 x9 B
如果原碼用C跟ASM混搭也不錯
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。5 Z8 Q% K4 E3 q+ U8 D% s$ E9 y
感激不尽~~
回复

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
9 }6 j, U7 r1 G# C: M(由于很多专用术语和算法机理都不明白,所以看不大懂……)' b& a$ S9 _; o- W( K+ X; a
//////////////////////////////////////////////////////////////////////////% ^* w5 e) z# S6 V' o9 Y
//                                                                      //+ R7 |' s8 g7 v0 M
//      NES APU core                                                    //; O6 A' O, ?9 c' q, p
//                                                           Norix      //- K  ~; z" X9 i2 T* x" @
//                                               written     2002/06/27 //3 q$ }1 w+ S! O2 s# f7 ?0 ~
//                                               last modify ----/--/-- //$ s0 `# i5 g" a
/////////////////////////////////////////////////////////////////////////// ^, t6 `9 ?# W+ j2 [
#include "DebugOut.h"; [+ q7 m6 L0 ]; K: n1 G
#include "App.h"
: P* I% `4 U5 |2 X' O  G6 U#include "Config.h"
3 l) }9 |! R! I0 l
1 l' K5 M+ X7 e: H#include "nes.h"$ X: x* a2 x. ?% v. Z
#include "mmu.h"' f; F3 x) Y- G+ x& H4 ^- U
#include "cpu.h"% W' E) f  X/ P# V
#include "ppu.h"' i1 }9 S# x  S& I! I/ |9 F9 F
#include "rom.h"" t% j3 v0 ]8 X
#include "apu.h"1 L6 H) `% I. d( l, p
# x3 |) @7 y9 E
// Volume adjust( `- b7 J) k: x! @0 z+ t
// Internal sounds
7 H2 H* |: X" A- z# K5 i8 t#define        RECTANGLE_VOL        (0x0F0)
$ i4 ~1 i4 v" J6 ]0 A4 I#define        TRIANGLE_VOL        (0x130)
  G: z; j& `9 ?$ ~5 x# T- ?#define        NOISE_VOL        (0x0C0)
5 j& L; ^! P7 d- V9 O#define        DPCM_VOL        (0x0F0): D& q6 j& i" m# u8 n! d
// Extra sounds5 D8 E7 N  L  n0 d) e7 P5 K1 Q; M
#define        VRC6_VOL        (0x0F0)' }4 z1 Y* z4 ~5 i: L; _7 [" J9 @+ f
#define        VRC7_VOL        (0x130)
6 ~/ h. H. B. I; g/ F7 T#define        FDS_VOL                (0x0F0)
: ^4 n* U' k! Y! N9 N; e#define        MMC5_VOL        (0x0F0)3 G0 \' ], y- h5 N' R9 n
#define        N106_VOL        (0x088)
0 M. T. |8 U, U$ Y& z0 S5 W#define        FME7_VOL        (0x130)
6 l; e8 b; b) h4 z1 ^( [6 K4 n" ^- L6 x
APU::APU( NES* parent )
, I$ \3 v6 z8 _{
9 q0 z: y8 ?: N3 i        exsound_select = 0;' ]1 Q2 M9 H5 k0 g: }. Q+ c

  K1 g7 t$ ?9 _        nes = parent;
+ o! q0 I3 _. {3 s/ o, P* k        internal.SetParent( parent );" }- v; k; \2 @; |* Y' d  G

3 F0 M/ s/ m; l* `8 e( w        last_data = last_diff = 0;  i; Q, v4 c! w2 S" N
: e- N( _9 \) d$ a! I$ l
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
+ J; i5 ?( X8 l' O. b% l* S* Y( W
8 E( K: B! f# f: B: }5 E$ A8 t        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );6 b$ B, o8 K  ?4 }2 L
        ZEROMEMORY( &queue, sizeof(queue) );
. }( U+ H6 Z" {, u9 F' R        ZEROMEMORY( &exqueue, sizeof(exqueue) );9 Y( Z, k- R4 n4 |9 N' p
9 a! U  D5 f" K/ k& y* {" l
        for( INT i = 0; i < 16; i++ ) {
& \' }! N/ E4 q- ?6 ?- S" u# Y                m_bMute = TRUE;, ]. s4 s0 V; W. N: Y
        }2 a# H# L; `! L! P' d) a
}" y) T% c" p' t" w9 {1 y/ G+ {

$ G5 y! j4 x) P; n: @2 BAPU::~APU()* h& I# ^) l, ?7 T) i
{
: h  x, ?9 ?3 S6 _% h, O/ t4 |}
" e6 H  B- z9 v* G: ~. v8 y) Z( z( u: v0 N9 I& r
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
. T7 ^. D4 _9 f8 N6 R0 H2 z7 Z{1 E/ p* k$ U  }2 K" v( I2 ?. O
        queue.data[queue.wrptr].time = writetime;
9 c' A- O9 p. L; r8 N        queue.data[queue.wrptr].addr = addr;: K% A/ }5 a0 {& F$ y5 l
        queue.data[queue.wrptr].data = data;
* [# ^" O9 P& b& c; t6 [        queue.wrptr++;
; N6 u: ^3 y' s: Q        queue.wrptr&=QUEUE_LENGTH-1;: R: h; u; O6 O! m0 m; g& K
        if( queue.wrptr == queue.rdptr ) {
$ [7 N, t) [) d9 _                DEBUGOUT( "queue overflow.\n" );
$ S5 |1 ]" \) }; n        }
$ H' K7 B1 y; v: x4 \8 U}
) c+ H! t4 u% |# n* k' L
5 w+ A/ s; N5 x" w$ [5 b2 KBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )! x4 _: h7 k! U2 S$ ^7 b
{5 I5 E  e* Z7 j! R
        if( queue.wrptr == queue.rdptr ) {* y7 s0 ~& ^. @) \$ [! X  \
                return        FALSE;/ m; s$ C8 e8 [( W
        }
$ v$ c% k* d1 V/ l7 B$ H        if( queue.data[queue.rdptr].time <= writetime ) {
4 K) ~' g+ M7 M- q8 v                ret = queue.data[queue.rdptr];% @2 O6 u7 ]! G$ z" A
                queue.rdptr++;
5 v! W$ F# j) H" \                queue.rdptr&=QUEUE_LENGTH-1;
  z- p0 h) ~( G/ v! E! c! {2 V                return        TRUE;
2 f7 ?2 `. i5 t6 J  G' E3 R        }% ]% q3 F5 r3 @2 c5 r5 E
        return        FALSE;8 f3 h% y9 V- f6 l1 f* j* J) z
}
: d' K$ A0 _2 [, j2 |
+ F: B  N! T& l% k# `$ {  m- ivoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
/ x! ~1 K8 O( \+ p{* F1 c  l! J( g& P5 D
        exqueue.data[exqueue.wrptr].time = writetime;
* v8 ?  j: x! V* O8 @        exqueue.data[exqueue.wrptr].addr = addr;0 s. M$ K7 v% ~
        exqueue.data[exqueue.wrptr].data = data;
' `  Y" |  b( a/ e8 y+ Z* `        exqueue.wrptr++;
  x3 S5 f! l7 ?2 H/ X8 Y4 U        exqueue.wrptr&=QUEUE_LENGTH-1;1 n6 f8 R; V, f1 m" O6 N
        if( exqueue.wrptr == exqueue.rdptr ) {6 p" B. A! Z; h# c0 l3 U2 f( o
                DEBUGOUT( "exqueue overflow.\n" );
$ u1 \6 D' v9 q% q. j/ I* ~        }
) }% b7 n/ Y# R" l& n, @, [}- ?, t* _  E2 \5 D
# w) _' d( K: n3 M( l5 d
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )" O1 [" ~4 w8 E
{
) w7 i0 p0 G" x9 n+ d: n        if( exqueue.wrptr == exqueue.rdptr ) {
$ E! F: p7 B1 f- g                return        FALSE;
: c  b( D; y2 G7 a/ r5 }# A# t8 z        }3 d1 g( A- [9 Z9 ^
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {& r5 C0 {8 ~6 T: Y" W5 h4 L
                ret = exqueue.data[exqueue.rdptr];
# f, b: @0 L* p  L* G; `$ g' V                exqueue.rdptr++;8 J/ b2 O, W0 ]0 C6 i
                exqueue.rdptr&=QUEUE_LENGTH-1;* S* E: N+ k/ P0 p, A  t  r" d7 N- }8 `
                return        TRUE;3 J. `5 D# o9 x( ]. H: |, {4 e
        }
9 k6 ^: G8 g1 \  {/ \        return        FALSE;" Y% H& G& n& b  v, p
}
9 f  Y6 w! i2 S: B7 L3 ]8 `7 T: M& v( |2 Q
void        APU::QueueClear()
7 G" x) a" L! }{- I. w* P8 P( @5 `  s. S0 n, a% N
        ZEROMEMORY( &queue, sizeof(queue) );
" }% ~. U9 \9 W        ZEROMEMORY( &exqueue, sizeof(exqueue) );
1 b- f% |5 D" p$ P+ I+ |$ E7 U}
# g, v8 G0 N  L, I+ O) K; L9 ^( X! m' I" W; c2 ]
void        APU::QueueFlush()
9 _8 ^8 D+ F% S- a{) U1 g7 K! `4 F( z
        while( queue.wrptr != queue.rdptr ) {: _$ @& E) }6 t( A2 U, N9 L; y
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );! r, [- _. y; [8 S/ W
                queue.rdptr++;
9 ^$ H2 v& F. [! T/ x                queue.rdptr&=QUEUE_LENGTH-1;# \6 j. Y% w: e" K$ L# g& v! ]. u$ v% I
        }4 V7 E" U+ M# `+ H9 r' P+ @1 {

3 \2 x5 q3 z& h* J' N3 E% ]' w5 R        while( exqueue.wrptr != exqueue.rdptr ) {6 D0 X0 w7 M/ U1 P1 b
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
" G1 p! V) z/ v8 ]' m- {" d                exqueue.rdptr++;
+ r* K# ~- X/ J2 _* Y2 q% c/ B/ f                exqueue.rdptr&=QUEUE_LENGTH-1;
) ^, {& s: w1 d( h        }
; t) ?) P# y3 C1 e- X}
+ \8 q' A$ L! O! v1 e3 I: j& A: ?9 h4 B# q! N3 l& x% C
void        APU::SoundSetup()
, H0 }& J/ E3 p, q  c8 U{
* ]( {0 l5 A9 }- U6 P6 @; \        FLOAT        fClock = nes->nescfg->CpuClock;, m2 Y: V- y/ r! O8 u$ q0 B6 e
        INT        nRate = (INT)Config.sound.nRate;' D; w0 k1 U/ u+ ~7 t0 E9 ?
        internal.Setup( fClock, nRate );5 M% K. A9 {9 `% q8 m4 D
        vrc6.Setup( fClock, nRate );
* G( p. ^5 R, C2 ~        vrc7.Setup( fClock, nRate );
- ~% D. Z7 ?/ W, F& C7 d        mmc5.Setup( fClock, nRate );2 I* z( j, Q! H, l
        fds.Setup ( fClock, nRate );
3 X( Z( r! ?- x% ]  O6 a        n106.Setup( fClock, nRate );
9 M, p( w- i9 l1 x7 M/ m4 V& e1 r8 {/ ^        fme7.Setup( fClock, nRate );
6 k- G/ b7 S* C! b+ S' }' ?; V}  o& R2 ~6 w5 n0 V$ F6 C5 O, v
- G2 \; ?) n& A% h) s/ S! J2 l+ m
void        APU::Reset()& \  h5 J, S6 G" {+ p5 G
{
- R! E+ N, W$ X: }) c        ZEROMEMORY( &queue, sizeof(queue) );3 b# t0 {# m2 ?
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
/ F% U8 j+ Q' l( b( b- `! M# s( l9 C7 R) g" `
        elapsed_time = 0;8 m+ ~6 o2 A# g9 ?

# o8 ?* K: J! Z. g5 d        FLOAT        fClock = nes->nescfg->CpuClock;
* H4 R; N# _0 B+ U3 o        INT        nRate = (INT)Config.sound.nRate;" ?: j# Z, _! c' d) j
        internal.Reset( fClock, nRate );' x+ h  o; t! }; e9 c' h
        vrc6.Reset( fClock, nRate );! L+ h: E9 i* c! |
        vrc7.Reset( fClock, nRate );( S3 j- F( U$ @2 K7 _, E
        mmc5.Reset( fClock, nRate );
9 }  C& |' e0 y) l+ I        fds.Reset ( fClock, nRate );) E7 i7 _8 C; @
        n106.Reset( fClock, nRate );# x+ p* W  Z: P+ r
        fme7.Reset( fClock, nRate );
' o$ I2 }1 l- I6 y+ z. E, T5 h& J4 z0 B% F( n! {+ v0 Y
        SoundSetup();
' q' u; C) Q) K. k) w}
- O: |& Q  H  e3 \9 [1 t0 `: |" B: F) Q$ q0 x9 @- Q
void        APU::SelectExSound( BYTE data )6 D) G. Q# G! X  R# Q
{2 i4 l& [/ f$ P5 p) h& U6 T
        exsound_select = data;
6 |" R- v+ m# L. b' z9 S/ a! L}
3 m. `! V( L. V( G) A8 n1 Q* q! {. M( B+ j. `1 w4 L5 ]
BYTE        APU::Read( WORD addr )8 D) A0 D. p% a# m# O/ Z. u: e
{4 H' b$ N. w1 t. b
        return        internal.SyncRead( addr );
& y7 q2 o, K6 O- z( V: ~}. `3 L5 x  ^0 H/ ?

. C0 U6 C7 l- avoid        APU::Write( WORD addr, BYTE data )
6 |( Y: t' E4 Q9 g9 a- L! O+ x! F0 q: \{
9 E  M( \: @8 d" @0 T- e. ~. ~        // $4018偼VirtuaNES屌桳億乕僩
1 L2 ^% `! E, G( V& Q9 l+ l! _; H        if( addr >= 0x4000 && addr <= 0x401F ) {
8 j5 ?, ^. N# F0 X& t, Z                internal.SyncWrite( addr, data );1 Z' z9 G6 C- v5 k' [
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
9 B- L( C- `: O& `7 T5 a        }! O! A' ?% @8 Z" c/ R# h" a5 N* W
}- f2 x& P5 W' K7 L" {
; G' T( r/ n- _% n
BYTE        APU::ExRead( WORD addr )6 v' D% o& O, l# L/ v
{
( m: v( w7 w; P7 U' {) h3 iBYTE        data = 0;
( o8 ~2 [8 x0 r3 F; ]$ v8 ]# v: [' L- F" H- Z9 u# W
        if( exsound_select & 0x10 ) {
1 v+ k  h3 e2 E$ J/ p7 m4 y                if( addr == 0x4800 ) {2 i& V) b4 ^$ i0 {! q& c
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
3 G. _9 d  D5 B5 w, \                }
9 Q4 _8 z' L7 Y) o        }
. i% X+ j+ J* p: r+ N8 G        if( exsound_select & 0x04 ) {# r) W6 Q& p6 [! i/ h! p( _- J
                if( addr >= 0x4040 && addr < 0x4100 ) {
4 X9 k2 F/ F9 {8 u                        data = fds.SyncRead( addr );
, B$ q  t5 z7 c5 c" a& @                }: S' J- j. k" N! [5 n
        }
" F+ I: |  F$ S! v$ N& I        if( exsound_select & 0x08 ) {( u% C1 J' n+ k4 d0 G
                if( addr >= 0x5000 && addr <= 0x5015 ) {0 X) [5 S( E: c6 p$ l
                        data = mmc5.SyncRead( addr );. \) N1 q! b" u! \$ s, x
                }% y+ t8 r, g1 r2 O+ D. g2 M, c
        }3 u5 h' ^! |! o: n% f) C

" j" r# I! b0 U        return        data;
. ]3 B6 F+ d. s7 Q; K5 N6 L}& B) y- {# V6 e% J1 ~6 l
. e/ V) F9 ^% a6 ?4 }% {& {. k
void        APU::ExWrite( WORD addr, BYTE data ): d/ l/ p/ C. B- v' x- M
{
# S5 ^( J( _  w! U        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );3 Q; l4 A9 z5 P4 `8 y/ e( Q
  R! a* L2 n* W
        if( exsound_select & 0x04 ) {: F' \0 d" c9 }+ P* l
                if( addr >= 0x4040 && addr < 0x4100 ) {4 h/ i3 H6 _6 |; j. n( A# K
                        fds.SyncWrite( addr, data );
' l7 J# j0 j/ x: Q: F                }% }( q2 b; {: D
        }6 B; p% C1 ~7 ]* l5 g0 T" ~% O
8 Y0 p# E4 |; Q+ G& E; S
        if( exsound_select & 0x08 ) {" a- n7 F& \- t2 Q/ M/ M
                if( addr >= 0x5000 && addr <= 0x5015 ) {& h2 a# c+ g; n4 ?& {0 j% S
                        mmc5.SyncWrite( addr, data );3 a2 G  O. r5 E9 v$ m4 g: `
                }
4 B: f& j! W2 c( q" y        }2 c) T7 l5 j& N- U9 o
}7 |5 ^* Y5 l7 _5 V6 s& @. n
8 Q5 V! i  Y+ e$ Z3 l
void        APU::Sync()5 U- e; i9 _" S( {/ r
{
- o7 ]* L4 w  N5 @2 }7 p5 q( j. \& q}
4 }: X( A6 h  S- M; U7 b& w8 }4 A& T. |/ R/ I& J/ V1 K
void        APU::SyncDPCM( INT cycles )& m# v4 e5 a2 L! ^* A
{
+ L( l6 J; G5 p5 S+ N        internal.Sync( cycles );; a# H7 L0 P- o6 T

5 V6 y4 @8 ?, `; _, L9 P        if( exsound_select & 0x04 ) {
. H: Z( e) T$ w0 D: w* a                fds.Sync( cycles );
5 A. v: y  l& ]        }
6 {1 y( n6 O" X2 k5 u9 l, e        if( exsound_select & 0x08 ) {
5 _+ ]5 N; a$ u- [/ r                mmc5.Sync( cycles );5 z% Z1 P9 t& b* q0 k' {) |2 t
        }2 Z6 J3 g, S9 C5 k& `$ |1 a
}6 E: R, v. [6 w! j7 _: E4 J
+ S+ x7 |# R! r4 o' B& U& J8 S' m
void        APU::WriteProcess( WORD addr, BYTE data )" L0 G3 f9 D4 i  a" @
{
+ u" U0 O: P$ p6 u        // $4018偼VirtuaNES屌桳億乕僩2 |( t3 V3 o" H# N
        if( addr >= 0x4000 && addr <= 0x401F ) {$ V, I7 T. j1 y
                internal.Write( addr, data );
% y( ~; n6 M" M. I" E' V        }
- o* H+ U3 e4 s7 ~+ H}
9 s7 P. h0 ?2 Z% K% u: i3 l& P. |, d9 R
void        APU::WriteExProcess( WORD addr, BYTE data )
! d, S3 Y* P, x1 N; r8 }( e( k" ]$ w{0 D9 e! C  w8 i7 \/ x
        if( exsound_select & 0x01 ) {/ m6 w/ e2 d1 `1 N
                vrc6.Write( addr, data );
2 }5 T$ v# B- A$ ?* n        }, D8 K% X' ^0 e" P& r
        if( exsound_select & 0x02 ) {, ]3 E) A1 r* {, l+ V( p4 [
                vrc7.Write( addr, data );1 }* G: s$ U9 X. V
        }
1 I8 Q7 U' P5 b2 r1 {- O9 ^" z        if( exsound_select & 0x04 ) {1 J: u4 T6 L4 Z* g8 \! ^5 G+ S
                fds.Write( addr, data );/ E1 {4 C) A, e7 _
        }
( q- k6 e; W) i+ r" m, F        if( exsound_select & 0x08 ) {# ~/ m  x( l4 y4 Z4 ~% h0 w' m  q
                mmc5.Write( addr, data );
4 ?) b, J+ M  b/ i7 Q        }+ }# ~6 ?6 @) d5 x' {# o
        if( exsound_select & 0x10 ) {% f8 B% I  c7 u
                if( addr == 0x0000 ) {
/ ?! s7 I) y+ ~2 y# D: u+ T' Z                        BYTE        dummy = n106.Read( addr );% ~# g4 D  D$ [8 X( t0 @0 W( M
                } else {5 y2 q1 e* z6 |/ j) w1 O- b
                        n106.Write( addr, data );& s3 `2 I" h& v& _# _
                }0 k% a1 c  e, D5 I* N: w$ U
        }
2 f4 `- D! R" p2 Z/ {3 ~, l        if( exsound_select & 0x20 ) {
3 |; U) Z( E$ a                fme7.Write( addr, data );; X2 W% b9 w. ~/ v+ O! R% b$ D7 c
        }7 y( a* Y! Y) t  M- k
}
7 q/ L, q0 [8 S& S1 y1 T7 F; R$ r- n
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
: X1 S1 R: [6 b" I3 X$ _5 N8 {{, N* c2 l* G% v. ~$ A& f
INT        nBits = Config.sound.nBits;5 [9 B" D( C& t' c( q
DWORD        dwLength = dwSize / (nBits/8);
' S: }$ ?8 }" s  TINT        output;+ A  F& v( c8 I" \+ t$ D" R  a$ J$ X; U
QUEUEDATA q;
  [2 H% p; I! {$ m7 y( HDWORD        writetime;2 n' Y( n1 \- A7 r+ u, C8 a
, b) b) _3 P: Y& E
LPSHORT        pSoundBuf = m_SoundBuffer;/ J/ Q1 V; \# G8 E
INT        nCcount = 0;
5 Y. A- d0 I' |1 }$ f7 X, v; X/ e% y0 ]9 R
INT        nFilterType = Config.sound.nFilterType;. M/ j+ y* K! P0 ~8 s
0 ?4 e1 J7 Q, ^7 d" N! j& P. M
        if( !Config.sound.bEnable ) {
) t7 s% D* p9 }4 ^4 u                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
( k; J9 M) T  [+ b                return;
6 B$ \' H! X! V0 n  K4 a1 O( D        }
! m$ L& N: X  s+ L( U/ ?" H$ c3 |3 m+ S  J4 W8 X! }" [
        // Volume setup+ V. _% J; Q! s* R) v# F  R. Z
        //  0:Master
" c+ n: x  ]! {2 e1 V3 G        //  1:Rectangle 1
3 ?8 K! J1 I2 t5 X; X2 b& |7 l        //  2:Rectangle 2; ]* {7 o; Y4 w) ]; y& }0 m2 M( a
        //  3:Triangle. j, }) C2 s  p
        //  4:Noise
. a! _/ B5 u/ a" K- Q$ V( D        //  5:DPCM
& m+ z6 B2 f4 r% t        //  6:VRC6! U! o# @0 U, C. P; A- `6 ?% u8 S
        //  7:VRC7
' ?# g+ o. C- T9 n        //  8:FDS1 t+ J5 B6 z( g; K; Z" B
        //  9:MMC5
% x$ M: S1 Q) ^" e! Y& v( a2 d% k        // 10:N106
$ M$ }! u8 \& s6 X" C" ?        // 11:FME7' K) q+ X2 {) h! r) f
        INT        vol[24];
; m0 D9 n, I$ s+ P# W) ]" L        BOOL*        bMute = m_bMute;
! E# c8 t! \* E# e- k        SHORT*        nVolume = Config.sound.nVolume;
/ j' U, n& X0 I% n' A5 g
! Y  T1 t8 @3 O6 @. [        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
( I3 j0 K7 g1 U$ {1 P/ s1 g9 a; y5 [  |3 p8 z. u
        // Internal
* I- P+ N/ L+ d, n        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
$ a/ L- g6 D% ?6 k        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;3 E3 i8 s$ U! |: m6 {
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
7 Y% s: _7 G7 ~8 N        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
- [3 _; d+ T0 F3 E        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;) K) W! L. F' N

$ H/ Q! O7 F  l* S- n; R6 ^0 J        // VRC6
8 d8 k- w2 m0 @) I1 l        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;/ ~$ F- f( B$ E- |# U! t! M
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;, R# |2 O- R3 O$ m# L. a' Y0 h
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
0 K( A7 f) L/ S8 P0 U8 o; \
. G5 @- U% k( B" O) ?' b! t        // VRC7
' [$ T7 }8 v1 O        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
% O4 M% u  n* @9 _  E
+ t; o9 b: w' O0 x        // FDS1 X/ k. B2 T8 |' p9 s$ c
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;6 a% ~7 e5 g8 U! q8 l

; e( N# h5 s, {# v* {        // MMC5
! @# s6 n" [' B- b        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
6 v5 H6 T+ M3 ~' `$ {$ x        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;" i5 i% i& o0 a7 J
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;  L2 c( a5 a3 Q3 j+ i) ?
$ ?# ^! ~& i, c/ I- i
        // N106) q+ d0 h( k, X* L8 r4 S
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' a/ U: V& m1 U# l" e  M/ V' q
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
3 P9 L! R! }) n7 ?        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;4 n) F+ n' \$ v
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- l$ p5 p+ O- {% ^+ F7 D4 {, J
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;% Q2 p% I2 g! m1 S9 f* c+ j
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
; c, P5 g5 f+ ^. A5 a$ t        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' o6 l1 n! G2 q% @, Y. X) I  \
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;/ t; R* {" I- A. q5 ?
9 ?5 {. W0 O# P' y* s
        // FME7; J' \6 D/ B% N( M2 X
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
0 f0 Z0 M; S/ S( |4 j5 L        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
4 X) |, P2 M2 j6 Y- O6 `        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;  k' }+ i7 z( v0 \6 k7 H

- r' W8 x2 T# i5 e8 U! M  a//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
* w$ M, W' F6 d0 j3 l8 z* a        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
+ [" w0 w5 H) N
) X0 d& |  G3 ]4 N4 r# {        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
( ]. \2 D- m$ h! W        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
3 J- s% a  F$ `8 Q                QueueFlush();
; p) z) @% c- m        }% @: B' o( u2 F2 h4 j* [) Y
% B# s; E8 Q# U9 r8 a" N
        while( dwLength-- ) {# b. v/ p7 i" ]' H; B6 ~
                writetime = (DWORD)elapsed_time;
9 j4 \8 r4 O! Q, _) M0 y& n
2 W# [3 I2 o) b: N8 t" C                while( GetQueue( writetime, q ) ) {
* M. X0 M0 c1 A  |9 g                        WriteProcess( q.addr, q.data );
6 V6 Z8 `, W7 q, E/ e                }
8 N: N1 W- ^- g. l) W( e# e
. @* G1 J+ k3 [6 F                while( GetExQueue( writetime, q ) ) {
0 C5 T  b9 V0 k$ u: s' `1 G5 a7 ?                        WriteExProcess( q.addr, q.data );
1 p5 l- H$ S( |$ l- P' A3 m- ?3 u7 e                }
2 p$ z# B9 o* m4 V9 q4 N7 u2 H6 Z" |
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7. ]7 p0 j  O5 z/ C! j; j
                output = 0;
% @3 j$ F5 w( Q0 R1 F9 Q3 C                output += internal.Process( 0 )*vol[0];: \* U# b$ S& F/ w# h+ W% S
                output += internal.Process( 1 )*vol[1];
' ^5 ^. z0 |# d5 E* Y6 G                output += internal.Process( 2 )*vol[2];8 R9 L" H! t3 E, O3 ^' }( Q
                output += internal.Process( 3 )*vol[3];
# {% q% }# J' z/ K                output += internal.Process( 4 )*vol[4];
( j$ |# _8 F3 b& C1 s# K  R, m+ r! Y! |% [/ R1 ?( ]. a# H
                if( exsound_select & 0x01 ) {6 f6 Z9 h7 Y2 r) A6 ]
                        output += vrc6.Process( 0 )*vol[5];) p9 R; o$ N: I! U$ K
                        output += vrc6.Process( 1 )*vol[6];! Y' T$ M/ u4 }# R/ p/ n; q
                        output += vrc6.Process( 2 )*vol[7];
( s/ S2 p7 F) b4 `& E                }
4 E, g8 o0 i. m6 U/ D                if( exsound_select & 0x02 ) {8 M  @0 q2 g/ ^7 R7 ?" H& d
                        output += vrc7.Process( 0 )*vol[8];: J! Q: _9 Z/ u
                }: w& M8 |- n# |& q; l% ^( Z
                if( exsound_select & 0x04 ) {. y  F4 s! u6 ^3 q! x1 S& k  A
                        output += fds.Process( 0 )*vol[9];: @: y  R) n, U4 \
                }
7 d8 n' o# G# g2 v                if( exsound_select & 0x08 ) {
0 }3 ]% c( }  R                        output += mmc5.Process( 0 )*vol[10];
0 v& F- \# {$ r+ J8 M- \                        output += mmc5.Process( 1 )*vol[11];
3 N- Q& j% e1 J9 R! F                        output += mmc5.Process( 2 )*vol[12];: j: k9 m* b6 O- C! W- I3 N1 I  a; f8 n
                }
, x+ @8 n6 N; b                if( exsound_select & 0x10 ) {
: U/ @8 `  B/ p/ l0 n- g# X                        output += n106.Process( 0 )*vol[13];$ j; e- x  ~4 @9 H
                        output += n106.Process( 1 )*vol[14];
3 x* j/ y* H$ N7 O+ ]                        output += n106.Process( 2 )*vol[15];
, D6 e7 L3 s7 x0 ~' k- a- \. ~: S                        output += n106.Process( 3 )*vol[16];
0 ]/ h; x6 N2 d& [. {                        output += n106.Process( 4 )*vol[17];* s& w! D& K7 Z1 Z- m4 c
                        output += n106.Process( 5 )*vol[18];8 R9 _/ {" S, K/ g+ g0 h/ ]
                        output += n106.Process( 6 )*vol[19];) J" w  M) J! ~2 G# l
                        output += n106.Process( 7 )*vol[20];  k# o8 e. D* _' N, ?0 M1 Z( _# p% ^
                }
# n. b7 n! i: j- z0 [                if( exsound_select & 0x20 ) {
/ h. U& T+ n; V0 ?+ B: }                        fme7.Process( 3 );        // Envelope & Noise* ?) _9 r3 F9 t6 U
                        output += fme7.Process( 0 )*vol[21];
' w4 J' O. a4 G1 O; K) ~- w3 u                        output += fme7.Process( 1 )*vol[22];5 [9 x+ M+ ^& Y
                        output += fme7.Process( 2 )*vol[23];/ W9 L9 I  T+ r6 @( h) k
                }( y' {; G/ b7 g, v0 x  ]4 t

5 U4 Q5 n  m& U( r+ [                output >>= 8;
) T1 F/ ~- w* F( Y: R3 M) ?* r5 a. t% |9 U
                if( nFilterType == 1 ) {6 E1 c; e2 l: ?/ S+ \/ P
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
* ]  }' \( {) o' L                        output = (lowpass_filter[0]+output)/2;
2 ?. X, e/ r1 Z! o; z- v- r                        lowpass_filter[0] = output;
4 s- |6 j# b2 a6 k  l                } else if( nFilterType == 2 ) {" }. d+ h6 w4 Y9 T9 ~; f
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)/ _. p" u# u! m
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;( p0 M# `6 J, w# }
                        lowpass_filter[1] = lowpass_filter[0];
1 p, p- Z! F+ f3 I% p                        lowpass_filter[0] = output;
! H* F1 s$ U0 K2 \8 A9 o                } else if( nFilterType == 3 ) {
. e- L0 ]9 n( D                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
4 P; ]. K  w- L1 e. E                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;' @- H8 I7 x. z, k2 g0 J( Y" y
                        lowpass_filter[2] = lowpass_filter[1];9 Y, ?( V$ }3 x' l: p, i3 |
                        lowpass_filter[1] = lowpass_filter[0];
: }* r4 d+ q5 P0 j! z                        lowpass_filter[0] = output;$ S2 ?* M# t7 L! @8 S9 h) G
                } else if( nFilterType == 4 ) {
6 ^1 S% B; g' \8 S3 I/ ~; l/ c/ {                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
) f! Q  U; u; t                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
3 J- u+ i+ @7 `! d3 g1 l8 R                        lowpass_filter[1] = lowpass_filter[0];
, t% y8 i' m6 I, Q% u1 b5 P, `. T                        lowpass_filter[0] = output;
& }0 J: E; \1 J. @7 ~4 X                }7 i8 |, Z+ X7 B9 k; o/ U4 c: n
# \$ t" i& ]3 u; W/ M
#if        04 w0 P6 Y) J) t3 ^# W
                // DC惉暘偺僇僢僩) j$ M; H3 e! D
                {8 h! ^) R; T' b9 o* N3 a1 M
                static double ave = 0.0, max=0.0, min=0.0;
8 s  L. D# Z; B5 E- k1 z                double delta;
- O$ N& U; S# O2 N1 X& ]7 R2 c                delta = (max-min)/32768.0;
, P: e4 c' _7 B2 g1 Z) s! H                max -= delta;0 b) C6 q2 k, w3 p+ O1 @
                min += delta;
; o4 S# W5 O8 }# f, [) M                if( output > max ) max = output;
( J8 G0 W( I# _! W: k, K' V( D                if( output < min ) min = output;
7 ~, w2 x& L$ t; c% O% i" p; E                ave -= ave/1024.0;
+ w. V8 M; y1 l- |                ave += (max+min)/2048.0;
& p; I: {$ r( s5 r, ~                output -= (INT)ave;
- R0 s5 A4 S. w/ j3 J/ \  T) n3 S                }
* u& s: ?8 e) w9 C#endif2 _3 v( ~' m9 Q9 A5 ]
#if        1! k( J0 `$ V& H) i
                // DC惉暘偺僇僢僩(HPF TEST)
& R& `6 I9 R5 b9 C! `. G                {
6 s+ \" y' U3 ~$ |//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);  I7 Z8 y" U* Z# [: b
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
& r6 G( J% P% ~) @9 s6 n0 s! ?                double        cutoff = cutofftemp/(double)Config.sound.nRate;
! ?+ c8 h/ ^# a6 n8 k8 @* y6 J                static        double        tmp = 0.0;1 ~# E8 j/ z/ u$ v( x$ `
                double        in, out;
. p2 G# n1 D+ ]$ |: m1 R& B4 P3 W) D0 ?% i7 J6 d4 P" G( [
                in = (double)output;/ d, A  E) M; _; j3 v) X  A9 C! F
                out = (in - tmp);
# N" B/ |0 ^) n; q6 s                tmp = tmp + cutoff * out;
) @0 v! i% D8 c# Y' B9 q! p* _" B" \
! W# u  @- ]0 T1 w  I' z( t                output = (INT)out;  f7 _- y+ Y2 j, @0 E: L/ E& y8 u
                }
# U& u! b# i( Y" b  c/ W! X) _#endif
" I( y! f2 L3 }1 B7 B6 u#if        0# @4 z1 _5 j& ^
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
5 C! l: O$ P: J0 ~1 ~                {
9 ^  _4 H9 I5 T  G, V) X                INT        diff = abs(output-last_data);
+ z( i0 q& ?. e                if( diff > 0x4000 ) {: B+ H; X5 j* r% x' a
                        output /= 4;
8 \5 [2 |8 O7 h4 t1 E& [3 _1 u                } else : A, [- e8 x% v  B
                if( diff > 0x3000 ) {
; t0 w) ~1 D$ p* j; b7 T                        output /= 3;
& }" ~* x- h  o                } else6 R1 |1 O7 t3 V* e) C2 I
                if( diff > 0x2000 ) {
0 c$ z# F4 s2 a! Q" o. e$ m+ R                        output /= 2;
7 o( }8 L# E3 @; ?                }
$ j! |$ l" D$ @4 k  `                last_data = output;+ d! ~! _+ s5 m! V6 m2 U3 a
                }
8 i% l, _* @  u; J9 N8 u. y" O#endif
5 e$ N% w9 c% w7 V                // Limit
! J4 Q" `0 v" M) `                if( output > 0x7FFF ) {; S& `. {% h. K- C) K
                        output = 0x7FFF;
) b1 k. b; F7 |: ?3 y/ D                } else if( output < -0x8000 ) {, I1 D6 |7 f: e( O7 \& E! W
                        output = -0x8000;
3 `6 e$ M* V/ T" w9 S                }+ Y+ B$ E6 b( @: f7 z% t* K
1 h2 @1 \# e$ n
                if( nBits != 8 ) {4 K* M9 b8 \* S3 q
                        *(SHORT*)lpBuffer = (SHORT)output;4 D5 s. C* ]" w* l: Q4 w
                        lpBuffer += sizeof(SHORT);' i: N3 N* S2 N5 X4 @; j
                } else {! m: V1 ?0 H1 P9 U, f
                        *lpBuffer++ = (output>>8)^0x80;
+ F+ x& o5 E0 v7 P                }
, y6 ^5 A7 ?# Q+ e; }% ]
5 d; R- }+ p/ r  ^. D7 j+ S                if( nCcount < 0x0100 )
0 v: D' V; g4 p! B% l                        pSoundBuf[nCcount++] = (SHORT)output;) @& T: D8 K; F1 _; f! I" Q
+ r+ O" h$ h/ n: ]; P
//                elapsedtime += cycle_rate;9 f+ \0 A+ I9 u7 c+ K7 E: ~
                elapsed_time += cycle_rate;
/ o( w+ ?7 }. k2 s5 R        }* n0 h( s9 k: i4 D. C
# Q4 S! R1 `% L" Q1 D; o& ^
#if        1" ~$ Y8 f5 q7 P7 F9 ]3 M
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
4 a0 h) ~4 p2 I' T3 u                elapsed_time = nes->cpu->GetTotalCycles();' w2 s( s. R9 `8 X
        }' W' I, T+ T! \' l! Y$ s
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
6 J7 F( ]- k3 C2 e0 Z                elapsed_time = nes->cpu->GetTotalCycles();5 M, R$ n- u; C# D5 |5 I
        }7 }" ]) X0 }: b  S
#else8 P; o) B  L* f( r+ r
        elapsed_time = nes->cpu->GetTotalCycles();
; M! K( v! k3 r3 s#endif
2 I% r  f( ~4 p3 s, n( K: i" M}
, e; s8 S0 Z; C/ L; P: x, G+ z1 Z
: A) R* ^/ S! X* P, ?7 b// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
( l9 b9 h3 C- m4 I1 W- gINT        APU::GetChannelFrequency( INT no )
3 K: V1 E7 ]1 Z, c0 C* [0 B{4 a, a. V' R7 X8 A6 A
        if( !m_bMute[0] )
- ?0 c1 l2 \9 b4 m                return        0;2 |4 H: E7 K3 a4 m

) J, p: t. R- q4 t3 h        // Internal
3 q5 {: L& v! e2 r) D        if( no < 5 ) {, N& b  c) a- `. S
                return        m_bMute[no+1]?internal.GetFreq( no ):0;( @' M% L9 R5 m( G
        }
, k1 x: t0 N' H6 U        // VRC6/ d' ~' _4 S# E6 L: S# r! H" W
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {5 v7 M2 f# k3 Y$ _! s6 ]4 t
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
! K2 V: r, g! F3 ~7 e  H2 g$ B/ V        }) z' r' a8 P  J
        // FDS
9 p, j* q* ^- k: X- Q6 j        if( (exsound_select & 0x04) && no == 0x300 ) {8 z8 U! s- S% T! K9 ?% ~1 P; k
                return        m_bMute[6]?fds.GetFreq( 0 ):0;$ A) k/ y' L4 ^" H: C6 b
        }# ?: [7 e5 `4 j# `0 [% V5 W: h6 M
        // MMC5  n  E/ p: g) H" K$ V1 m5 p
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
1 I, |" t; K( i' |) O7 C                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
/ w' S/ a  h: H) G- n# ?. |        }
1 P* l6 Q, }% k; }- l/ S! v' l        // N106
6 \) b/ o  r  Q; I1 s        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {( R8 H) ~( m* A' ^! Z
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
7 z- [: c4 l5 i: A        }) U: o7 P( F& _& X; x* Y1 \  W
        // FME7
, P, p; e& p; Q% t        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {- `; n' @. x: d6 A4 i
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
. T' @( v$ t( B; J) b+ F        }
. ]# l7 n1 \  X" G; o- j, [8 |$ n        // VRC7
0 u( R; g6 W* U4 G        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {. n1 I# x; G6 |4 G+ Q% t; Z  c
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
& U% p# Q, I4 W* H8 F" [        }: u/ O7 C" m1 e. P5 P, L. ^/ |
        return        0;1 s) R9 u; C$ D3 l: V) ~. q! v
}% I5 v  o* l  C7 x8 p

' V. u8 S3 `  [$ x! i5 s// State Save/Load
8 ]0 N2 u4 B* j1 L) S/ b" c8 _void        APU::SaveState( LPBYTE p )5 C+ x, v9 o0 P. B
{6 c5 P4 y  y8 ?/ h  X  n( _/ u  U
#ifdef        _DEBUG
2 X1 n, a) W" l; O5 TLPBYTE        pold = p;
& m6 w9 _# a( P9 E#endif2 b+ f! _  g. f: Z# Z7 n, Z
9 U# @/ K  I9 B1 Z& E
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞) I6 M4 ~; Y- O/ a7 a" _
        QueueFlush();# e* G0 T$ u* K* p$ j0 s7 a

/ l) q: l. I% l6 I# M8 r        internal.SaveState( p );0 H" M, O# G% g+ b$ e$ l  ~8 Q8 J  N
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding5 B: j4 l( v, u+ |8 u
0 z6 I8 x1 r5 Z0 H
        // VRC6( u3 A4 n2 h& k4 \% n4 b' V6 C# F; _
        if( exsound_select & 0x01 ) {7 ~& v! d; G4 I: x
                vrc6.SaveState( p );
: }6 D* s4 J. {( u7 B6 N                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
0 ^6 p  _' T8 I" `. T( j4 _        }
: W# z+ q& ]. t& W        // VRC7 (not support)% |( P3 I5 ^! Q, a0 u  e
        if( exsound_select & 0x02 ) {; B5 i3 N5 _: @1 g3 l; N
                vrc7.SaveState( p );
! o, b* j/ A1 h& Y- B                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding+ W- K: [$ x7 U' v' G
        }
! ?3 `( N; ?8 B8 G$ T7 h8 z) Y0 P        // FDS
+ C. X5 V$ S- }4 a4 n4 o        if( exsound_select & 0x04 ) {
- |' o+ z+ i* |                fds.SaveState( p );5 i, W/ `+ C/ S" Z
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
$ T. R/ G+ d. l* o( E        }+ W( o/ k0 L' C4 d* S3 G+ z; u. z) V
        // MMC5
  z, p# g6 N: S1 W        if( exsound_select & 0x08 ) {, M" F) `. ?3 o5 o* k" ]& _
                mmc5.SaveState( p );
9 I, n7 P2 V' R) O5 J6 z* V                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
* g( m! _4 I. y2 F# t        }
, S8 Q8 X& b* T4 U4 d( }. F( [        // N106/ h! V7 L+ c- G4 u0 G" g
        if( exsound_select & 0x10 ) {
  z( g3 Q9 y( O" ]/ z7 h                n106.SaveState( p );  k3 {% e! j/ j0 Y1 a: h
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
6 ^5 i+ y; w; E5 ^        }+ L4 @1 d' I* n
        // FME7
& \& a! M1 o$ c. G8 M, I' m        if( exsound_select & 0x20 ) {7 G' c: c# y- i* V6 _
                fme7.SaveState( p );: b7 v& p6 Z) F: }5 K1 m4 n
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding7 g. G0 P4 f3 w- ^' ?! p
        }: x. H- D2 q8 l/ p7 O5 ]& a
. u' L$ v  u) }, C
#ifdef        _DEBUG* Q8 ^6 L4 \0 }! R- N$ W, D
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
* |& D, Q  Q, n5 `#endif
- O/ Y5 M' R) W: m}
+ q8 _6 q1 c5 `! W$ B
$ b4 O# {" d5 ?, a- H0 q( Cvoid        APU::LoadState( LPBYTE p )
+ p, D8 g  |; y. L- t{
1 Y: P9 t$ D' P% X) ], D        // 帪娫幉傪摨婜偝偣傞堊偵徚偡2 c4 A2 t/ m# i7 v$ Y! Z
        QueueClear();
- W& \! `) Q: t6 i1 F
* H# t6 o: D0 R  w& \" Y        internal.LoadState( p );( n6 m: `! ~1 b4 f. k( R$ a
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding7 W4 i4 W4 Y( [
9 E+ {" E. J$ K- v- k
        // VRC6) |9 p6 r! s2 {' D/ g
        if( exsound_select & 0x01 ) {8 E& p+ q- a6 Y: u0 k
                vrc6.LoadState( p );
! L' }$ L/ ?: I                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding3 \8 t/ u7 m5 z, u+ `6 j
        }6 |9 {6 U7 N. \! X' C/ ]" M
        // VRC7 (not support)5 Y9 ^5 s$ `  R+ W
        if( exsound_select & 0x02 ) {
, N+ R4 d  i1 X# L, g                vrc7.LoadState( p );. P& s7 O0 J# E& R% f$ u
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
2 I: e  ~  Z: s# {, |4 \        }+ I. J- t5 g" `& I
        // FDS
! l! g' {8 X7 ]5 X! O        if( exsound_select & 0x04 ) {& ~! R6 @  ~" D2 e# X; L1 z8 _# ~& l
                fds.LoadState( p );
+ r& h  S1 z6 U  r* s1 R& m                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding/ v2 `. f8 Y5 F% I- c% F1 }$ R/ M
        }
+ Z; h0 U6 B% o1 e: v# v        // MMC51 Y% e4 t) t2 @
        if( exsound_select & 0x08 ) {; @7 G, z# W7 g+ J( L) V( R4 g) A
                mmc5.LoadState( p );
# S' K5 J3 e( K9 q( B( c2 Y: T: ~                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding/ ~& r  m# P' P" i! u1 l7 }/ {5 V' [
        }0 \" X* _, ~* g
        // N106
# J, J; I1 K( d3 Y$ q        if( exsound_select & 0x10 ) {
& P& {: }% }- e# H* j                n106.LoadState( p );
2 c. ^5 G8 Q/ e                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding% d' A$ W! _" k3 c% U3 [
        }
0 ?+ m& I( c' O& Q3 l        // FME76 \9 f: K+ h9 Q2 O: M
        if( exsound_select & 0x20 ) {2 \) x& r9 v8 ^( U
                fme7.LoadState( p );% ?0 K& J& D- g, K# R, c
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
- O& ]# ]3 g( b- s' p* R+ y        }
0 L5 Y1 q& S' @$ ]}
回复

使用道具 举报

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
: L5 T" `4 ]5 d; G: j可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。/ T$ G9 L. N: a; u5 A. M
感激不尽~~

5 X( N9 Q0 F1 P恩 我對模擬器不是很有研究,
8 C6 T1 g  f2 z( \" ]雖然要了解源碼內容,可能不是很困難,; L; N# h) [& L' F9 A: c
不過還是要花時間,個人目前蠻忙碌的。
( l, x" R% U  i) P$ K+ d: G2 T* x# t6 l' I7 s
給你一個朋友的MSN,你可以跟他討論看看,6 C. z5 K: Q+ |) B* O$ G% W* G/ d
他本身是程式設計師,也對FC模擬器很有興趣。
1 L, b" A0 {  X7 `5 ]+ [
8 ^6 @5 |+ p( i( qMSN我就PM到你的信箱了。; T% v$ G& I% @: U4 y* {( Z
* J+ ^  X3 O9 \. q  \7 n
希望你能有所得。
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

签到天数: 82 天

[LV.6]常住居民II

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

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表
. j+ w8 ]% g" H呵…… 谢过团长大人~~

8 L  O- l) V5 g5 B) H. i" M9 d
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
; X" [5 u0 a0 i& h9 Q, y1 N5 i- t团长的朋友都是神,那团长就是神的boss。

+ X3 g/ a# f* ], z  _! q  {哈 不敢當,我只是個平凡人,) o' Q3 y5 X. L6 M/ }
要吃飯喝水,光吸空氣是不會飽的。。。。 :)
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙% R) f  z* u/ R! b% V. f  T5 b
ZYH
( |5 M3 U1 m9 _) g1 s4 fQQ:414734306
- X6 S  o; E( U5 |! @0 k! {* GMail:zyh-01@126.com1 }6 ^) G% s5 I1 ]
/ T7 G* V! c, g, M$ o3 k
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 5 N% r$ s- W5 C8 {( c# ~9 k
再次对团长大人和悠悠哥的无私帮助表示感谢~~
7 n' L! P0 t7 l* b# }, i) A& ~
不客氣  ^_^
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-8-5 09:35

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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