EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。* h9 E: m, f: \
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~. S1 k; B1 |3 i$ w
这里有相应的模拟器源码,就当送给大侠了~~( B& N3 U% i4 P" E& ?- r
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
$ V! c9 \7 `" A0 a能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
: E: X* I; e) n  Y, x楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
- p9 G/ W0 g0 X9 c3 Q$ b这里有相应的模拟器源码,就当送给大侠 ...
. o5 c. D: g5 g# q
聲音部分(Audoi Process Unit = APU):- f, ~" N! n* G+ V& A
.\NES\APU.cpp
( h8 \; Y! J, c/ r.\NES\APU.h
3 M8 z) V( g+ i3 \9 `$ k8 n9 k2 o) U

; A- F' m  H( k" @影像處理部份(Picture Processing Unit = PPU):1 E5 z6 e. I& Q! ?2 y. _/ Z9 y
.\NES\PPU.cpp, s& \# ~, M+ [8 `
.\NES\PPU.h
/ u# Y, ^2 f, w# C+ H! q( A! p
- S9 K* K$ T" k! h7 n如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
5 e+ `9 W+ m; ]8 P7 W感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:2 `5 z( y4 W0 i
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
0 M3 D2 e. Y: M  ]0 C//////////////////////////////////////////////////////////////////////////! q# i: B6 _0 ]1 U3 s
//                                                                      //
" p! A4 u6 z5 ^' T- h/ Z//      NES APU core                                                    //
2 {9 I2 {7 m- T9 Z2 V//                                                           Norix      //
: T+ `- O0 b# N//                                               written     2002/06/27 //5 E0 `( g/ G0 X9 p4 z/ T, l  g
//                                               last modify ----/--/-- //- q* m  I. {& J4 u- B
//////////////////////////////////////////////////////////////////////////
  O; E4 ~) {# x* H#include "DebugOut.h"7 k, D& \' u' o# Q" c) b7 ]* W
#include "App.h"
! ?8 _! U7 n+ n+ K$ w& b#include "Config.h"0 K( ?. Q7 {5 [% r, X5 V

* F# d! @4 N( T: h/ K; k: E1 q0 v) L7 [#include "nes.h"
0 s- g. h* i+ q' j4 q#include "mmu.h"
7 m" y3 y% I9 B#include "cpu.h"
( X- f8 Y  I/ Q: _1 b+ b) m#include "ppu.h") G& f5 W3 ~. |% Q* w
#include "rom.h"+ b- g& U. X! ?
#include "apu.h"9 V, U- n6 z1 L6 j" ?2 Y8 |) l' ~
8 j: x: z% _& q2 W- l5 j
// Volume adjust/ y. X# y3 j4 Z
// Internal sounds
: X) m# [$ l% q( d# f. t. c#define        RECTANGLE_VOL        (0x0F0)
" ?1 i2 A* P5 j#define        TRIANGLE_VOL        (0x130)
1 ?8 O: ^8 J: M& G#define        NOISE_VOL        (0x0C0), ?/ M- _: _9 r7 ^
#define        DPCM_VOL        (0x0F0)  l; _) Q; L1 V' D
// Extra sounds; C& R% M) ?. j6 a' A
#define        VRC6_VOL        (0x0F0)9 q. B: h) P6 a0 O
#define        VRC7_VOL        (0x130)+ q8 B  Z7 d5 ^! \/ I  x0 x, t0 L
#define        FDS_VOL                (0x0F0), R# ?8 h# @$ P/ L9 A, i
#define        MMC5_VOL        (0x0F0)* d3 h1 u1 l8 a7 z1 F  d
#define        N106_VOL        (0x088)# z, s8 b) t# Q* X
#define        FME7_VOL        (0x130): S) e7 |, l6 C0 \

  g  R! o: X+ L0 U* Z1 [APU::APU( NES* parent )
4 K. }7 F0 l7 x7 X/ G  c{
! p- |* w' y+ H        exsound_select = 0;
5 s! J( ]6 E1 n% {) U+ Y3 w0 h# N4 `2 n( Q1 s
        nes = parent;' |0 C+ S6 G+ }2 N0 _
        internal.SetParent( parent );
$ y- z3 f* h2 u6 [1 U1 l0 t0 i. U' }7 I8 D
        last_data = last_diff = 0;( V3 X" D: \; V) p

2 r( g7 g0 h3 J        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );3 B% I8 I2 O% n# x/ H, v7 R

! S) \  }+ v. W# M        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
* s, d9 R$ R6 {        ZEROMEMORY( &queue, sizeof(queue) );
" T6 S5 r& [" ?9 V        ZEROMEMORY( &exqueue, sizeof(exqueue) );
! Z4 X; d: P* o2 ]7 l5 n5 B+ D+ x5 r2 _0 {* x; R' \  J( O6 O
        for( INT i = 0; i < 16; i++ ) {
, I% ]5 U- t" x* D" x* M/ z/ A                m_bMute = TRUE;
9 r, ~. x7 C8 C  ^; P3 ?; O        }: S4 d" u# W9 Y. M
}
; V6 A) S. e1 v. Z! g4 b2 `. E: C  g5 T" _. l5 H. ], i
APU::~APU()* L5 G) d% Q/ T) k3 L- b
{
! z4 e9 a6 D" v; P. m2 [; E7 L! s}1 r7 c; ?* e0 ^& S9 u/ P5 q
/ g" `, h; E& f5 u% J: ~% w$ t- c5 Q2 t
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
1 \, T2 R( G' ~7 f{% ]1 B/ i7 U2 Y6 G0 l5 H/ C
        queue.data[queue.wrptr].time = writetime;
0 Y& N2 {: a0 _( i# }        queue.data[queue.wrptr].addr = addr;
( g6 t5 y+ o5 T3 D$ U0 d        queue.data[queue.wrptr].data = data;. r3 ?5 E  M$ {% _, f: E/ e
        queue.wrptr++;
9 t4 Y8 d8 y* s: t8 Y        queue.wrptr&=QUEUE_LENGTH-1;
) Z* t! M0 `$ i+ V        if( queue.wrptr == queue.rdptr ) {& S; I' \1 s4 W* ~: r
                DEBUGOUT( "queue overflow.\n" );8 L: l/ @" {3 ~) N
        }3 W% N; }; `1 O/ O0 \
}' f* p1 [+ {" B" S; o: h
, @* m! {* V$ _
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )) `# y+ N2 v( Z8 s' u+ e6 A" g
{
- e  i$ f9 c5 ^* d4 |- v: T        if( queue.wrptr == queue.rdptr ) {" G) _9 Q) Z4 F& `7 K, T' H# x
                return        FALSE;
' H+ Z4 F' }! V! V; ~, a3 M        }
% ^" `% d/ Y# B# V3 m1 V        if( queue.data[queue.rdptr].time <= writetime ) {
* b* M: h& }, I7 m+ t! s3 m6 S8 F8 w                ret = queue.data[queue.rdptr];3 g0 L6 g  H. C6 O8 J
                queue.rdptr++;7 c4 y7 M/ a& q9 }
                queue.rdptr&=QUEUE_LENGTH-1;7 F# h* }8 [  V3 f8 S0 s/ t
                return        TRUE;
7 |7 T4 x: g4 `- Q# A6 x7 x        }
2 z( l( D$ g) ^. m        return        FALSE;
/ j7 Q6 I7 g6 m+ \}
! v2 G. H- X+ ~: O8 J- l. [2 m  q* ^8 E6 `1 S/ Z2 g! o6 O' `: i
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )  ~% R3 U+ P" a
{
  X3 E3 f# n; z4 s9 V" P5 l7 E        exqueue.data[exqueue.wrptr].time = writetime;
4 s1 K1 o, e6 a4 f3 D% c. H( k        exqueue.data[exqueue.wrptr].addr = addr;
* }$ ?+ R- \+ f6 P6 f        exqueue.data[exqueue.wrptr].data = data;
' \8 {+ ?" D2 e        exqueue.wrptr++;
' X4 O* d! s  |        exqueue.wrptr&=QUEUE_LENGTH-1;* x/ c6 m5 N1 F- v. W6 @' P
        if( exqueue.wrptr == exqueue.rdptr ) {% q2 d; E- ?0 T" X, p* `0 Q( I
                DEBUGOUT( "exqueue overflow.\n" );
  A/ f% C2 }+ ]+ e+ T        }
8 Y5 W' |4 j* J}
* ]* ]5 M9 W% m4 J, v0 {& d6 `" P) E3 b% C9 U# s/ q
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
1 ]0 @; y% e4 E8 n& ]/ l  h0 Y{2 J" c9 e  v: `4 b0 U6 F: a, ?
        if( exqueue.wrptr == exqueue.rdptr ) {" S$ u1 K% ~/ ]4 {% y9 P0 p
                return        FALSE;
. m" \. j9 b& A; U+ X6 Y        }2 ^# g" G) y% e! [9 D
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {* Y3 N6 P* n  V; m
                ret = exqueue.data[exqueue.rdptr];* q& _/ M( z1 B0 Y, L& H4 B% [9 c
                exqueue.rdptr++;
! y3 e& S( V3 `2 J: I# q: v; J1 b                exqueue.rdptr&=QUEUE_LENGTH-1;5 D5 \3 q$ z* S+ g
                return        TRUE;
: E, N9 Q% v) j4 o0 `# h1 Q        }
( w5 P3 b  _0 \; t8 ]) Z        return        FALSE;
: j2 [# A9 h8 y}' M& P& ~/ a  s& E) M

1 @" i1 O3 d- Z' E" Q9 d) wvoid        APU::QueueClear()4 n- V1 |8 S+ Q( E" _
{
, r! Z7 t0 x2 f; h, H        ZEROMEMORY( &queue, sizeof(queue) );2 c* g/ N7 x5 o1 _' E0 r! H% @1 F
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
3 _: Q. ?! B6 ?5 [9 C2 \}+ v4 x1 T) }! E9 e8 i7 m# e; a6 F5 J7 M

, w- p1 {5 l/ e. d+ a% }% Mvoid        APU::QueueFlush()
0 |4 J* [  J- |! r1 T" v. v0 \, N{
- O5 i9 G6 g, J3 }! r2 ]9 }3 y5 X        while( queue.wrptr != queue.rdptr ) {) Q7 y5 L$ ]9 M, a
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
" |" ?1 h% c( A3 \; w                queue.rdptr++;
1 `* o: F. J+ Q4 E* B" Z                queue.rdptr&=QUEUE_LENGTH-1;3 m4 ?3 B0 v# F# h0 n
        }
$ S: A  |( f* a: i
- i5 m8 ~  E5 q/ z+ v+ |        while( exqueue.wrptr != exqueue.rdptr ) {
# }# e  X( ~5 {! B, Z                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
; X6 T  v$ O4 }* d! t9 G                exqueue.rdptr++;& V- q% w8 a9 ?/ ^" C
                exqueue.rdptr&=QUEUE_LENGTH-1;+ K3 L7 h3 @! ?% w2 n0 G
        }
5 y5 O( x6 j5 |# y}# \( m# h7 j- g% T

& f( X& X% d/ H5 Mvoid        APU::SoundSetup()
8 _* n# I3 Z- i" `- B: D& Y{
2 i# Q1 g7 Y+ d5 Z- n        FLOAT        fClock = nes->nescfg->CpuClock;; X& O% i6 x- h6 k- s/ U0 D4 ^
        INT        nRate = (INT)Config.sound.nRate;
, ~) B  c# |" i; U        internal.Setup( fClock, nRate );9 p" ?" L2 K8 C2 r
        vrc6.Setup( fClock, nRate );
, C* h$ x. L: e6 c5 B        vrc7.Setup( fClock, nRate );
6 M9 N$ g3 {( w7 L! ?        mmc5.Setup( fClock, nRate );# f& [0 s7 o! f2 d
        fds.Setup ( fClock, nRate );3 {/ h; y' [. Q. k' Z
        n106.Setup( fClock, nRate );! A1 K) s, u) h/ }/ a0 \0 r
        fme7.Setup( fClock, nRate );. m9 p4 c) T8 m8 K( ]/ w/ e1 a+ V% C4 B
}. g$ ]2 Y9 ]9 V

) ^- ~% _0 d4 x$ h$ l, K( _void        APU::Reset()
. ?+ E9 ^' X5 C" ~) s{4 E# i, u! M  V6 d
        ZEROMEMORY( &queue, sizeof(queue) );  ]& R5 Q* p" Z  U
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
# |* v& V4 Z4 e  X
$ m6 U3 t7 T5 N3 w" _: C        elapsed_time = 0;7 i) _4 |( D) N! J8 m" ]* d

6 c4 \. G! j4 B% _# @$ e4 k        FLOAT        fClock = nes->nescfg->CpuClock;
4 W" C( ~1 {" F$ o        INT        nRate = (INT)Config.sound.nRate;( \6 ~/ n$ e% M; Q' v
        internal.Reset( fClock, nRate );
) m! P+ W, H1 O, D3 Z. w" s        vrc6.Reset( fClock, nRate );
2 M; K) K: H4 s! r0 f2 I        vrc7.Reset( fClock, nRate );8 f$ f1 M$ f5 P
        mmc5.Reset( fClock, nRate );
( F. M1 d0 J- b" @        fds.Reset ( fClock, nRate );5 v) o) r5 p1 _4 u
        n106.Reset( fClock, nRate );
* p# M; v8 b% f) a        fme7.Reset( fClock, nRate );
) d( Q/ i1 F# M, B9 g+ K+ C7 r
' u5 U8 [, A! D! O        SoundSetup();
, Y) c" r9 o7 j+ B}5 j; A. K! t! X7 U
, t9 C5 w6 c" I  B1 x+ [
void        APU::SelectExSound( BYTE data )
3 h% N  W6 ]- w$ E+ `{( s& l  S% V' E* B# Y
        exsound_select = data;& q5 ?: Q) A1 Y! P' W" C
}8 b2 @" {" x/ W; w) @

7 q& h6 }5 l; |, r2 y: m/ Z: dBYTE        APU::Read( WORD addr )3 @2 w) N* H- r. F1 y& A/ L- |9 h
{
, h. X8 i, t  i7 m; n9 B: {6 G0 X        return        internal.SyncRead( addr );! O: |* E# I: {: `) ]/ B
}
: y: _5 z( a' {  M; m( i0 I  V- m( C9 D3 p
void        APU::Write( WORD addr, BYTE data )+ N# H& J' n- a, j; I
{" ?" s( I; ^7 W7 B& X
        // $4018偼VirtuaNES屌桳億乕僩7 ?+ X6 ?. R5 Y2 E' T
        if( addr >= 0x4000 && addr <= 0x401F ) {0 w- I0 V) h) L
                internal.SyncWrite( addr, data );
) ]' U6 j/ Z" K0 _$ O" Y                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
- a4 u5 I: q7 l% a        }% a$ `& \  ?! ^  m; A
}/ W0 [- b0 S! {( E
, F- {( c$ M+ j! \& H* o8 V
BYTE        APU::ExRead( WORD addr )
5 @' Z3 d8 }* b{
2 A9 @7 k. ?' B* X/ `! GBYTE        data = 0;- Y/ Q  I- H" o, O9 i7 T

7 }/ S+ a) O$ @: z  e        if( exsound_select & 0x10 ) {5 l: K1 W4 c+ L; G2 z/ d$ _
                if( addr == 0x4800 ) {! z: ^; Y% |  J. V
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
. f( u; z' i/ U$ s                }8 M& N4 D5 L: @/ K- x" U7 I
        }0 P$ E5 h' j5 l- z1 L
        if( exsound_select & 0x04 ) {+ M* T4 x. z- y+ d  h0 d6 S# G/ b
                if( addr >= 0x4040 && addr < 0x4100 ) {
. v! ~1 M0 D4 d/ T                        data = fds.SyncRead( addr );
3 I+ i/ W0 f+ L% ~( S$ N; Q                }
$ F8 q# a- G  P% W( d        }, R5 }" G: T$ p4 w3 R/ Q
        if( exsound_select & 0x08 ) {# {  G; {7 O  O
                if( addr >= 0x5000 && addr <= 0x5015 ) {
/ s  [; e  U3 m9 r3 K2 X                        data = mmc5.SyncRead( addr );, K, D/ p0 M3 m0 O( a; _
                }
/ C% e) |* P7 B' d        }8 o+ F; k3 F) N5 [# C. r. `

5 \) l3 Y- M. C        return        data;5 A  g% h: t# o+ N
}
" O- m1 E! H- {1 g; W8 b+ y* E" Q& A5 w
3 D- q8 U0 ^0 D- ^void        APU::ExWrite( WORD addr, BYTE data )& g& p6 M9 S6 _5 n; C
{0 f5 H' G2 y3 K9 O- [# o
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );& h8 L2 B0 n& w' G

7 k! R. L6 R8 M& r0 Z( T        if( exsound_select & 0x04 ) {; Z4 ~3 }6 u6 R. j2 M; {2 X
                if( addr >= 0x4040 && addr < 0x4100 ) {
% }) r6 ?  L: u. h                        fds.SyncWrite( addr, data );# O: d& }( ]- D9 \) n
                }
6 B. f0 M  K0 Y, W7 a        }$ @- L4 ^+ B7 h% _

& W* h! z+ c' V        if( exsound_select & 0x08 ) {
2 _! v3 v- K$ ~1 f                if( addr >= 0x5000 && addr <= 0x5015 ) {, B: E7 [4 Y# N# G8 H
                        mmc5.SyncWrite( addr, data );6 k( R( R+ B$ N0 d- T) z( x3 e0 t
                }
: y- X; o7 x! e0 N+ H/ x# [        }" O% I. b3 }) n% r: T! W
}
$ y4 |) v$ j$ o) F' C4 B8 F! o3 C0 c. K
void        APU::Sync()6 o, x3 j; X2 i+ z3 @- Y4 r5 D9 d
{" e& D3 ~! i1 q# @/ }  X
}, b, l* ?1 |- g2 S& E$ i

% x/ j  d- w( X7 F1 d7 _' Mvoid        APU::SyncDPCM( INT cycles ): w+ Z, a! Q5 [& N6 t: _
{+ a3 Q, N% O1 A$ Z  `1 Y, W5 d
        internal.Sync( cycles );+ r  U7 G& ~. U
+ s- l" H' I4 N+ I' _( z5 k
        if( exsound_select & 0x04 ) {$ u3 Y- H- |3 T0 P9 a' n$ X
                fds.Sync( cycles );
. V# B0 k& B& @        }; S0 U  O- A: u- h7 ?
        if( exsound_select & 0x08 ) {. ~9 I& b% l: E4 I3 D( V6 @
                mmc5.Sync( cycles );7 J7 |1 ?9 B5 `0 I9 c) R/ X4 c
        }9 Q) ?: `6 |" U' L  _1 m4 e% d7 U8 ^
}
2 K4 \* N, o, t5 B5 R4 ]/ h  [. C5 T# a
void        APU::WriteProcess( WORD addr, BYTE data )' u+ `4 x7 s, J  ^
{
6 |/ o5 h1 c1 o  L  x& M4 `7 n4 a2 ~        // $4018偼VirtuaNES屌桳億乕僩
% t9 b0 f1 b' Y; c        if( addr >= 0x4000 && addr <= 0x401F ) {- o. T* j8 e- E, n) g  ^
                internal.Write( addr, data );9 s# I# T# V8 D  r( O  T9 n
        }
7 @  r1 a* E1 W) ?8 k}+ T$ \$ m0 m/ h; O

& ]1 S% r" l, }! _( |void        APU::WriteExProcess( WORD addr, BYTE data )) K" B4 D: R: f+ [
{
, O0 \; V- a% X' z' @$ Q        if( exsound_select & 0x01 ) {
  b# V, M$ S* J3 l5 U( X                vrc6.Write( addr, data );
  L# b/ t& ?* q' C2 p! d5 K/ o9 \        }
0 v6 q) r: I. k: Z9 T        if( exsound_select & 0x02 ) {
- g( Y' B2 M  s                vrc7.Write( addr, data );
' a4 U  D9 H8 C( F        }( d7 r2 b- u/ O- i" e: A
        if( exsound_select & 0x04 ) {
. @8 m" h5 F4 Z/ ?9 J) h  T5 j* J                fds.Write( addr, data );
! u8 ?7 G9 k9 J6 ?- K" f        }
& _" a6 Z( _$ P* M. N        if( exsound_select & 0x08 ) {" `# S" N9 ]& X9 B6 E3 ~
                mmc5.Write( addr, data );  F1 \! ^- C0 k  ]1 r2 u
        }2 b- K. Z& g' b1 s9 y. Q! J
        if( exsound_select & 0x10 ) {
/ G# {% ]4 c1 R! x                if( addr == 0x0000 ) {
  `& Q. B. k( o- @5 s                        BYTE        dummy = n106.Read( addr );
" z. f/ I$ }/ f" L                } else {
+ r* @- J" s' q, z  E                        n106.Write( addr, data );
0 E: S! ?! {; h( j# n) d                }3 `% ^3 Z3 V6 u
        }
" P7 i8 K! o- C9 i9 y# r6 ~        if( exsound_select & 0x20 ) {7 y9 F% B; `1 z! ^4 C
                fme7.Write( addr, data );$ g! F& b2 z) y' ?. W7 Z. `: i
        }
# y0 V( y% F1 T) U/ D5 L}, }; f! S  u3 A+ \+ V/ ]8 x8 }

5 W' y7 A. `2 v# n5 L- U: |void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )2 B: ]2 x4 r  ?" ~# f- F5 n! Z
{
$ K( i, z9 `% g: e& ?" n: W3 G0 QINT        nBits = Config.sound.nBits;  M5 P% ^! i) Q: s' U% |7 g
DWORD        dwLength = dwSize / (nBits/8);  n, {: b* S# R( }
INT        output;
# i& i+ @1 V" F* f0 `QUEUEDATA q;
* p) G( X) ]- O) KDWORD        writetime;
$ U# ]$ L4 E  B& z" U* A. O1 _
; j) L: ]) ?, [; YLPSHORT        pSoundBuf = m_SoundBuffer;
7 x6 }" r% U, v% l* A8 r% A, ^* b; l1 lINT        nCcount = 0;" m9 k* [' T& t1 Y5 l5 L" ?

" f: v' |* _  R0 v- d4 TINT        nFilterType = Config.sound.nFilterType;
  M; e4 L- Q" y3 ^, w( i
0 Q0 g: J8 T  ^* q        if( !Config.sound.bEnable ) {
0 j* W( s4 r7 O; [. Y  D                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );: J) S# D( [! l3 S; [
                return;( I1 R$ l3 }+ ^, s; U8 F  g' q
        }
9 S3 r0 k2 p0 h
- z/ m0 t7 P  F2 L9 n( s2 j4 Y        // Volume setup
% L* N' z! w3 h" n9 `5 w        //  0:Master
) P' m' s" P4 H) `        //  1:Rectangle 1
( q6 o, U2 D" u  t4 n- g        //  2:Rectangle 2
$ I/ y7 X8 h& Z) V! T6 N        //  3:Triangle5 W$ J& U  q' G2 _9 J- E4 g' H0 H
        //  4:Noise
1 \! z0 Y3 A# u* M# |5 _        //  5:DPCM
8 l( |( d6 \& N5 h; _. g5 {        //  6:VRC6
7 c0 L2 G. i( ?1 r* C        //  7:VRC7
6 Z, r% {& l1 i9 ?. m) s        //  8:FDS
, \$ V" W6 F# ]% V& t        //  9:MMC57 i$ |" k& j; M' o3 v2 J# F) ^6 a" `
        // 10:N106
# U. I! |2 D$ E6 a/ h1 {        // 11:FME7
: ?) i% N5 L* J- X        INT        vol[24];
7 S& W  q4 m( y+ z5 N        BOOL*        bMute = m_bMute;3 V7 i; ?3 L- ~; _  ?
        SHORT*        nVolume = Config.sound.nVolume;! C  l4 X# |6 \: M- f) A

  w' @0 M( a# ?: G        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
9 v( n! |* U( N$ d/ u. v! k3 r$ [! P
        // Internal
' p- c  l, _- x" u. o        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
. p* p6 [7 m2 _6 G3 x        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;6 @4 @" l4 t  z6 Z" A+ e
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;) M. X6 {; w( T
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;- Z; B/ V4 K, V* h0 V- p4 Q
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
; b3 W' ]0 X0 E$ i$ l- M2 j& @% ]4 z7 @) w" O' Z9 _
        // VRC62 _0 ^# w- L9 P/ u6 n* n
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
3 H- k5 f1 O1 y        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
! v7 }  q6 }0 D% Z+ n6 u        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
! y$ I. ?) s$ w3 t& n* Q! p) u/ {; X. G4 D9 j* H3 M! s
        // VRC76 C9 Z$ n' T+ D
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
" j) R) n& F, s* j' r% G2 J# J( M. U! l- k  v
        // FDS
0 X/ I6 Y" w' P/ u' |- z$ p        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
* {6 A/ F% \1 A, J3 y% e
! u, ~+ Y, c& Q! U8 p# v        // MMC5+ }/ u- A: k: W3 h3 c) w: B
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
" e: d7 l& d5 x$ m4 ]7 r* c        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;/ \4 S% `6 ^+ S  w' n$ Y/ R2 c
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
. U# D9 Y1 p) l7 c0 j. M
+ r! e/ u/ I! P* F+ v        // N106% m- ?5 M1 D( W1 t6 w& z
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
8 S) [' {# [9 S5 `% \) F        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;( A1 {: `9 Z. c+ T+ e
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" l6 |! t/ f' x' x9 ~* O  d: E        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;2 g6 {, C8 E7 s4 u
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- N6 u7 i+ U5 }        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: g* Z0 D3 a* N. I5 p4 x) X# L        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;& U; b9 B7 f* ?5 ~# W
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;( g, Y& j! |* @! z* U7 q+ E9 z

# g* R7 Z7 w5 M% q4 c* }        // FME7
* \9 s' O$ B5 I        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
% Z0 i, l. X# n3 ]$ P; G! x& |( D        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;! q6 b& A, l* R
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;' k. {. b! A0 Q7 E- p& K+ j2 |1 t
0 ^2 G7 B& F. k
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
- {' E6 p* d, s0 J/ J        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;( }( Y3 o# q" P  N: q. a
+ I5 p, Q6 B/ [4 Q
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟& O4 |/ X$ x; m4 k6 g9 x
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {2 X5 N- W/ K+ V2 Z8 ^# {
                QueueFlush();
$ l6 c% x4 N9 R, d! p$ H+ Z2 H        }) W1 a8 v) D: a$ v" c
9 Z* T! H* n# R' P/ G8 x8 c
        while( dwLength-- ) {8 i$ b9 }7 @3 `( e& z
                writetime = (DWORD)elapsed_time;5 ]- q- P. f) q; d( O1 I6 @
" i4 T1 p4 j9 C# ]/ y) x
                while( GetQueue( writetime, q ) ) {
& \; c, ]3 F/ P; ?" I                        WriteProcess( q.addr, q.data );
$ `6 U) b. L' H                }
  D& D8 P; }, y+ a+ M' g6 N, D+ e, Z
, t2 Q7 ~+ c, l( P$ ?                while( GetExQueue( writetime, q ) ) {7 q: E1 c# r& u  _) N: `
                        WriteExProcess( q.addr, q.data );
* J6 E8 r& ~% Q5 h. v) C/ R5 G                }
1 C9 j+ W. X! B/ B! L/ y) J
5 K- L) n+ V& x+ U! ?                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7/ i, ]) F6 ~3 Q6 J9 ?2 A, D+ o6 C7 w
                output = 0;+ I; q  j2 W* c
                output += internal.Process( 0 )*vol[0];
# e5 ~/ ]7 ?6 X                output += internal.Process( 1 )*vol[1];+ K1 Z1 @0 Y3 A0 F  P; o
                output += internal.Process( 2 )*vol[2];
5 Q: z1 a( U) P" M  x9 f5 I9 ]                output += internal.Process( 3 )*vol[3];
: P2 e4 b8 F: @4 [                output += internal.Process( 4 )*vol[4];
3 o/ T# s) ]! W2 [0 f. e5 _  I/ X' ?- t( ?9 ~
                if( exsound_select & 0x01 ) {$ T5 M0 r# @1 i& x
                        output += vrc6.Process( 0 )*vol[5];
0 e; a5 M" X5 r% u; @1 a4 Y                        output += vrc6.Process( 1 )*vol[6];
8 m& K" x" z* a1 R( a: S/ K                        output += vrc6.Process( 2 )*vol[7];
( ~. R4 J1 E3 a, S+ e: I0 ^                }
# B0 K7 _0 u5 s( Y0 t5 E. l                if( exsound_select & 0x02 ) {
$ y2 p$ O% R; V                        output += vrc7.Process( 0 )*vol[8];
2 \% q( ?  V0 H0 Y9 J7 ~                }1 Z9 q- ^0 ^) o, i% R3 n
                if( exsound_select & 0x04 ) {
% @8 u3 [7 v* s                        output += fds.Process( 0 )*vol[9];
$ M: S# X4 O3 c$ j6 X5 g: z                }  ~$ b; a6 g* A0 z* |0 w
                if( exsound_select & 0x08 ) {
9 E2 s3 h6 }' |$ V3 i+ J9 C                        output += mmc5.Process( 0 )*vol[10];3 q# \* U, @2 n
                        output += mmc5.Process( 1 )*vol[11];/ g5 C7 a$ e4 O
                        output += mmc5.Process( 2 )*vol[12];1 R9 F3 x" i3 D( a
                }
/ k& ?* t8 P! T7 i& M                if( exsound_select & 0x10 ) {' d5 e7 r7 _8 M5 ]/ @2 ~+ N9 V
                        output += n106.Process( 0 )*vol[13];
/ C' A5 E5 O% |" S                        output += n106.Process( 1 )*vol[14];
" i2 Y/ _/ }6 h- }8 n$ o4 p' |2 V                        output += n106.Process( 2 )*vol[15];3 N( [/ B1 H" d2 K1 q& j
                        output += n106.Process( 3 )*vol[16];
  g: r# h; f9 E; u' f5 g                        output += n106.Process( 4 )*vol[17];
) z* [; A& K, R) \$ T                        output += n106.Process( 5 )*vol[18];3 T) S* _# O/ D
                        output += n106.Process( 6 )*vol[19];; O+ ~0 D( f& m: z: v$ ]$ M- E
                        output += n106.Process( 7 )*vol[20];9 `0 D6 y* V. L& X- }4 n
                }; A+ K0 k8 w: v6 N8 @' Q! T4 K
                if( exsound_select & 0x20 ) {" Q; s- t% v, t! c- s9 m
                        fme7.Process( 3 );        // Envelope & Noise" H! U0 B! g: T
                        output += fme7.Process( 0 )*vol[21];* D, @% M5 z( {9 d
                        output += fme7.Process( 1 )*vol[22];! D" x  y1 D. k4 I8 N" Y$ A) n
                        output += fme7.Process( 2 )*vol[23];# b# F/ P- `' w/ h1 d' m
                }
8 M' C6 e9 @# k- G" [4 [4 h1 L8 Q/ ?' N
                output >>= 8;: B# G* p  ~0 h/ w, |' A* X

9 J& N! q8 u2 X# q. o; p                if( nFilterType == 1 ) {
4 [& ^0 D0 ~2 C6 R. V  y$ v, @                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
3 ?. [% [! ^0 ]4 {, S# a                        output = (lowpass_filter[0]+output)/2;( X* w$ Z( v9 }& L6 _8 q
                        lowpass_filter[0] = output;5 t9 k) r( l3 w) ~0 l  `' H% B
                } else if( nFilterType == 2 ) {2 ^8 C' |& C3 z3 @
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)2 J$ Q2 j6 b9 t; n7 Q. k
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
1 S$ ?/ ~* M6 y" M8 r9 M: F7 }  c                        lowpass_filter[1] = lowpass_filter[0];7 t' E. y9 Q* Q  G# v" o2 W
                        lowpass_filter[0] = output;% r( m  @+ C% @/ [+ W2 D
                } else if( nFilterType == 3 ) {
1 J8 b; ^) b& p8 B, S8 ^                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
  I2 n! x2 W5 Z9 N                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;. v0 k1 `2 [0 E9 [/ Z" l
                        lowpass_filter[2] = lowpass_filter[1];8 G* a9 X. P1 a8 Y0 I2 m
                        lowpass_filter[1] = lowpass_filter[0];* H1 D2 [' p; T: b6 g/ Y. z! w* k
                        lowpass_filter[0] = output;
( l: I/ l% R+ l                } else if( nFilterType == 4 ) {
: r- X4 V* W: {5 Q2 ]                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)/ {6 J/ _4 `( L2 ?
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
, ^+ n$ z4 a  j9 d( [  R! P                        lowpass_filter[1] = lowpass_filter[0];. X7 h$ N2 ~- T( E1 x
                        lowpass_filter[0] = output;% ~4 O1 @- {1 |$ D9 ~
                }
% L2 {8 z! p6 n+ \0 x
) h  a: w4 _$ e$ K/ D; \0 w#if        03 p. D/ }* ], Y% z- Q
                // DC惉暘偺僇僢僩
( Z% o+ g, I/ `) m- Q                {
2 l5 U, W& ^3 u" ?1 |8 l+ z                static double ave = 0.0, max=0.0, min=0.0;
8 `* K7 j" W+ y% ^+ o/ n5 n                double delta;
" v* I+ J4 n; _4 F( B5 [                delta = (max-min)/32768.0;
: ^: y$ g9 _, w                max -= delta;7 `% w6 A* T1 p& ^# A/ ^# }
                min += delta;+ [/ r, S/ u7 o6 Z
                if( output > max ) max = output;( u4 }3 |* [) ]9 e/ V3 F1 y7 S# g
                if( output < min ) min = output;) v2 q! G  v, M! X4 a' v
                ave -= ave/1024.0;
8 ^+ ?+ v, Q% n, l5 {1 H                ave += (max+min)/2048.0;
, r- f" R3 }: b" ~. P* M) Z0 Z. f1 g                output -= (INT)ave;+ C+ R. B7 D( G
                }
3 a0 v+ ?3 t; N7 J. z$ ^. }+ m3 j#endif
! K% X$ H( H% I% B6 P#if        10 G% q, Q& p8 j2 J
                // DC惉暘偺僇僢僩(HPF TEST)
2 L' |% Z4 `9 ^; S$ J                {  n8 q5 x' n7 i7 r
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
0 ], E$ z7 m* O4 f/ _                static        double        cutofftemp = (2.0*3.141592653579*40.0);' N7 U- i$ h3 y+ T
                double        cutoff = cutofftemp/(double)Config.sound.nRate;3 [, s* e4 u3 h/ F% h, I; r# F" j3 N
                static        double        tmp = 0.0;" ~; L' w2 p2 R9 L
                double        in, out;
1 x) u: z) R( Q8 q9 L" Z9 l7 ^' \# e5 \4 M! k5 y
                in = (double)output;' j& I$ @8 O+ {9 z7 d
                out = (in - tmp);: h3 K0 i: M  U9 }
                tmp = tmp + cutoff * out;
2 v. J8 G; i) B- Z# {% ]5 K# T9 w! h, f0 Y
7 I- S0 v) {! n2 ]. x5 n                output = (INT)out;
" P- R1 z2 a& @+ A# S  p                }& G& ^# E; v2 I# B7 j6 @9 g* m
#endif
! a: Z- R$ {4 U4 N; {6 V#if        0
$ Y3 J& Q  a+ {                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
) j0 R5 I! t* B5 ^; Q/ w0 R% ], l  `                {
( f" ?0 F/ F* T1 Z& }2 Y0 o& s                INT        diff = abs(output-last_data);% D! R6 Q; \" ^# @) N" Q
                if( diff > 0x4000 ) {2 F& v0 X, Y$ \. b" V
                        output /= 4;, \$ e1 N7 B2 Q3 ~0 K  h9 P% y: V
                } else 1 H' G- N) b  f
                if( diff > 0x3000 ) {
' S0 t+ f! o3 c2 f8 P; U/ C                        output /= 3;( E: j4 ~1 x1 ^5 _1 z2 }8 ?/ |7 D3 ^
                } else
9 s  b1 V- w9 u* Y  b9 B7 s! g5 K                if( diff > 0x2000 ) {
( Q$ n2 |5 a+ |" d2 L                        output /= 2;
' h" o+ i& V: ^- X8 P7 v                }
' q8 F4 q0 L5 D/ J) g                last_data = output;
" q  [, E+ p+ m* G/ }: Y/ K                }( @; x6 f$ S7 X" U) o6 r
#endif
  D9 e1 K3 D& ^7 ~                // Limit
+ q1 P9 ]! m1 }4 t1 ~; `                if( output > 0x7FFF ) {2 ~3 \; }- O  r8 `" m' \
                        output = 0x7FFF;
" q8 |! d* o1 n' V% G3 z                } else if( output < -0x8000 ) {2 @; b9 j  t* z' n& y  {  h
                        output = -0x8000;3 y  k& V& }2 X% u
                }
, E- n' Q/ a" @9 |, D
) w( K1 _, p9 A: v. A                if( nBits != 8 ) {3 \2 F9 [, x6 [. A0 h" Q4 ]$ `
                        *(SHORT*)lpBuffer = (SHORT)output;
, v. F& s* A$ A/ H0 s* F                        lpBuffer += sizeof(SHORT);+ q& L# _9 M$ M/ ~  j7 U' T4 S
                } else {
: G7 i6 K( h; ?* p2 `" N                        *lpBuffer++ = (output>>8)^0x80;  o/ n+ F* v# Z
                }
; ?* }7 v2 J8 e/ P- N- K. b7 Z/ [0 e6 u1 ?+ j/ z2 u
                if( nCcount < 0x0100 )) F. J/ ?$ k! S" Q) j9 n; a
                        pSoundBuf[nCcount++] = (SHORT)output;3 [$ S9 T( u- ~, M" ~* G
# X9 N+ J8 Z9 n! ?  j  u# S' r
//                elapsedtime += cycle_rate;
& k0 C2 s7 s0 }$ ?6 f! |7 x                elapsed_time += cycle_rate;
0 V9 o5 J/ F8 o9 m( U& n# W; l        }
: O! {0 M! t+ ]( M# h4 [# r
/ `$ a% y) l, V. t9 x& D#if        1
2 ]5 j& u5 w* L9 H( c        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
$ t; h6 H3 E1 W1 e                elapsed_time = nes->cpu->GetTotalCycles();
, K. k2 H" B6 j- V3 I4 f6 D        }
4 x% I$ D4 p8 e" o3 s& [" N        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {) K7 S9 ], g. Q* j4 i
                elapsed_time = nes->cpu->GetTotalCycles();# t$ q; q* I  j- A: q4 n. ~
        }
$ `, [  F2 t+ O: i2 u4 o* e+ X#else( F$ O0 v+ T7 u. V% o
        elapsed_time = nes->cpu->GetTotalCycles();
" s+ K. h6 i+ m#endif
+ g2 W9 U; }& B9 C1 y, a; M}
' t7 e0 U; u- k
+ H; x$ {8 P; Y! F9 A3 p// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
" L! b, A; W% q; NINT        APU::GetChannelFrequency( INT no )
' L8 I/ o/ w1 p# r- G{: h3 u* N* V* V! P) V
        if( !m_bMute[0] )% c: C, X+ R, U2 e2 ?; Q* C
                return        0;
- S3 h. M* a  {, @" [" F# o0 s8 H* s* k! I/ j9 x! W" d
        // Internal
6 q( B0 \5 ^  i3 l        if( no < 5 ) {
% ?; L0 [& H# Y6 Z& r* c                return        m_bMute[no+1]?internal.GetFreq( no ):0;
" \7 a: B9 x1 t4 \2 k1 B  S        }
2 w# I7 m4 s9 j5 B        // VRC6
% |9 [" g8 K2 X3 l2 q6 Q1 C& x- [        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {1 B' i3 W' Q9 g; s6 ~* ]# Q7 F4 |+ ^4 [
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
' ?) a* h3 L+ F; M, q" Q& s+ J        }
1 \0 n# O4 e* [! c' b5 E: E        // FDS7 L5 g5 V8 |) n
        if( (exsound_select & 0x04) && no == 0x300 ) {) e8 T  G4 J& v  E+ w& s3 a2 e
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
% X# q, [' {4 J9 I( C        }% f" d" O/ B, j! z& n' a, c( J- J9 Q
        // MMC5! ^5 H) r/ J: M
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {8 c! X7 j9 e" c2 E
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;; H4 `3 i5 I% I& y
        }3 J/ b& B3 T- q: Z4 f+ F
        // N106! Q. r# f$ x( _
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
+ k2 @+ ^* V# i+ q! i                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;8 R" a: I$ K6 A4 i- V" B: O
        }2 E9 C. U9 n- U
        // FME7( Q5 M  H) l0 b/ o/ T" |. s: H
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
* n! o" m5 x8 R) J2 N. O( M" p                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
8 v2 }" t4 `0 Z# c; A/ T        }: \: G8 Z% `- J6 c
        // VRC7, x! C$ G4 Q6 S; v
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
+ }' r$ {! X2 T' Z' v/ K                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;9 ?% C+ k; \$ R
        }
! w6 F7 N. U. t+ d4 v; [        return        0;
3 z0 J( `. h, o& c$ r. d! |}# N$ u% P3 D. E4 D
/ D& x+ r# U; d
// State Save/Load& N. n+ `+ j% p2 i6 y* W
void        APU::SaveState( LPBYTE p )+ ?6 a5 r6 ]( p, r8 K: N8 U- [
{8 u' a! ]8 y) S
#ifdef        _DEBUG
  E- {# l1 R5 h" n- p1 f) kLPBYTE        pold = p;
& y# a0 Q7 J7 x7 B6 {1 O' ?#endif* U3 A2 f/ `  L

5 n& @  x+ f" R+ z" n6 e        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞4 N2 w  Q: m6 t+ k" k0 X
        QueueFlush();
# T2 J! n7 _4 Y8 M7 g& d( l3 h- L& _1 F1 Y# |5 P
        internal.SaveState( p );6 q: _7 O7 r0 B
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
% Z: n% O9 o, |* E- O  y$ Q) Q0 M# z# X+ I
        // VRC6
( @7 t6 ~- i' s' g/ R& n        if( exsound_select & 0x01 ) {8 c6 {* E9 H* z/ L/ \7 @0 w4 }4 v
                vrc6.SaveState( p );+ U$ h+ y7 K* n) _! N/ B% h9 W/ Y
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding* {7 h4 O+ V) s
        }/ \3 C; g# y" F* {, `, n2 L3 ?
        // VRC7 (not support)
4 b( z/ V% _  g& Z        if( exsound_select & 0x02 ) {- }1 i9 e# ?% |) R
                vrc7.SaveState( p );
3 d% O  g. a* t$ o                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
3 F. F0 L# Q' I2 l# K$ c        }
! J( o: l) ]3 m: j- \        // FDS' P6 a# S4 X! @$ J) T
        if( exsound_select & 0x04 ) {+ \# l+ ~  h6 q
                fds.SaveState( p );) q* J0 u' `+ p5 w. m8 S  ^
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding; {4 I, [0 ]$ R: c4 W; g
        }
+ j/ k8 V$ u$ W2 h        // MMC5+ p) h5 E2 e# A) H
        if( exsound_select & 0x08 ) {
  U$ a- @1 v/ r0 L' j8 z( m                mmc5.SaveState( p );5 |7 Z  {' R6 m4 Z6 T
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding& e/ Z6 G  I, ]% a" l. i
        }
% \' K& K+ ~+ Z7 ~2 u% n5 D        // N1063 e  u3 k  _4 N8 K1 Z# b
        if( exsound_select & 0x10 ) {# o5 G  `* [/ U0 p
                n106.SaveState( p );
! e8 g) r/ \% k& i, K; ]                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding% j+ |2 d2 d* B( e* G
        }
% |6 {$ w0 w, ]        // FME7  _8 Y& V6 I0 g- ]) W, U1 Q/ i' K4 ?
        if( exsound_select & 0x20 ) {6 f# ?$ o  E% b
                fme7.SaveState( p );
  Q8 [# y; Y% i: I: x                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
9 I5 [6 h1 s; X5 F% m1 y        }
- Q* L' s4 P5 h. N# _* X
: {) T  Z/ A# r1 f7 ^0 S& Q#ifdef        _DEBUG
& W$ E0 b/ L8 b+ i, F& ]DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
  U% P6 [0 r1 w1 F! h% r) k#endif
8 G8 g+ |6 Y0 E) v  X  H3 C}
& F- F& _. p% D6 I& G8 Z8 Y1 _5 @  Q% c. T$ v" S- w
void        APU::LoadState( LPBYTE p )% f' A( M( H- Y* q: W% O1 c3 }
{8 t4 ]+ I+ h% G6 G( [
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡9 M: k: Z* E8 M+ {3 H+ ^! ^/ M4 n
        QueueClear();6 i, {1 Q  X3 P0 j  H

; t$ T4 ]" M6 p: Y        internal.LoadState( p );
7 _1 ^7 i7 S" H7 q) X* `        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
$ s* Q* f8 q( _3 G: B
' D' j3 m  c9 _6 N        // VRC6
$ F% Z3 g! B0 ~        if( exsound_select & 0x01 ) {
2 e8 t) u) d9 x, l6 S$ o( I                vrc6.LoadState( p );& z2 P# u- Z+ i5 I- @
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding2 q  M3 m0 D+ L) h
        }3 z# E3 O- y# T1 @6 Z
        // VRC7 (not support)
+ B3 s4 c9 |+ f4 L        if( exsound_select & 0x02 ) {, i, q5 m  k; g5 L4 j2 G
                vrc7.LoadState( p );* W& F# H, y4 j9 e: d
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding5 h5 P9 Y- b5 ^/ R! X; q$ Z, w
        }
3 \: P6 ?( X0 C        // FDS9 d% m" `) i; P( G) n- l7 B
        if( exsound_select & 0x04 ) {& z* t% q# d' o9 r! G( |# \5 b$ y0 |. \7 Y
                fds.LoadState( p );# D: I& X3 e: }9 v7 C* x) a
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
% l' O9 g& q+ @& h$ j  [# E& V) S        }, Z. A% m% R6 P8 N" z- Y, `' J
        // MMC51 M7 S7 {: O- t( A) d
        if( exsound_select & 0x08 ) {2 V# c5 z  `$ J* \. @: u
                mmc5.LoadState( p );
! m  M- T0 Q$ r: c: m; a  X                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
! L7 n. H* W5 O7 A8 o; H' T& v        }
! g) h( W& r) i+ `9 {1 W. f        // N106
, V: H; N2 x$ n' d# f  L% G        if( exsound_select & 0x10 ) {+ s. F4 K1 f9 F' d3 Q$ h
                n106.LoadState( p );2 K# a: L+ [: T: r/ G
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
  U/ @: _  Y: ?2 s# t0 p        }( `; M8 X3 X! @  r5 h2 C, B0 @
        // FME7
" `  D( m- D% m        if( exsound_select & 0x20 ) {
9 ^* ~8 Z  b! w                fme7.LoadState( p );" z/ O6 Q, ]4 y2 I
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding+ R7 O3 d8 F8 R" ]; }
        }' b; e, j2 O* a* r9 o- \7 w: ?9 L' A
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 1 d: B, a6 N: o* `( {9 S. ^3 B
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
2 ^" i6 M+ {$ V0 `5 S感激不尽~~

0 Q+ }( N2 }9 c8 ?  ^恩 我對模擬器不是很有研究,& |0 U# u, e0 |! G1 |; z7 u
雖然要了解源碼內容,可能不是很困難,
& Z% K4 U2 p0 u5 _9 @7 ]' D8 d2 Q7 P不過還是要花時間,個人目前蠻忙碌的。
; \% I/ y7 [1 Q+ K- f  E% }
3 d  o( l' k$ H* J/ a' V! T給你一個朋友的MSN,你可以跟他討論看看,* f4 c" l$ w" {* Y8 t& K1 ]  i
他本身是程式設計師,也對FC模擬器很有興趣。
* u! Z7 p- n; F9 I3 M+ h% N$ O' s% s
MSN我就PM到你的信箱了。
' K2 B5 F: k2 z9 [* p, P1 `, R  N% ~( M5 [' G- a
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 % F& z4 L6 G2 X8 F3 \
呵…… 谢过团长大人~~

. S* e. E( M  g6 G6 y1 G
& x, r' P- F( U  p- Q0 C哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 $ ?) T/ J" P9 ^8 h( V4 J5 B2 d
团长的朋友都是神,那团长就是神的boss。

3 H5 H/ s. [! R, z& b" ^哈 不敢當,我只是個平凡人,
1 ^6 V# L4 W* A要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
1 \: }  d3 e9 i) b  D8 {/ [ZYH
) M1 x1 r* F- B- ~QQ:414734306
8 a: |4 B. B! @8 RMail:zyh-01@126.com
# D' N" i  N8 k. y! K4 K
7 P! c0 E7 D- X4 z8 f他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
+ x+ \/ V6 o" H再次对团长大人和悠悠哥的无私帮助表示感谢~~

% ~' y  A2 M7 V不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-2-6 15:08 , Processed in 1.078125 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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