EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?+ M. _, c# t0 Z! L. C" s
PS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
7 E4 m1 X0 i; ^1 z+ Y- [4 W0 u楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
4 p3 S4 m, b3 W" \这里有相应的模拟器源码,就当送给大侠了~~: ]6 b9 Y) z: L5 k/ a! t. R+ q% \
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
: |! |; f; o4 P能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。  g6 [8 n' W1 N9 R3 A
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
: g5 Q/ P9 B# D" @这里有相应的模拟器源码,就当送给大侠 ...

; H/ \3 w) g' c7 f, Y: h聲音部分(Audoi Process Unit = APU):
" R9 V; ?- Y8 k0 C.\NES\APU.cpp
2 U* ]4 V- ~* Q0 ^# d) f; m.\NES\APU.h
# D  @0 S+ W$ W! i4 ]5 e
* |6 x  a' l4 n- c. b' e/ t9 n7 c: }( C/ S) i. j7 d$ h5 s" e
影像處理部份(Picture Processing Unit = PPU):: E( p3 R$ n4 g1 V8 q
.\NES\PPU.cpp  K2 v( |" H- h6 m* m
.\NES\PPU.h
* y1 h6 K$ N) a6 P& T
# F8 w6 b$ A6 K! R' P! \- a如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
5 |1 \1 \9 t: R- f5 `2 y5 k(由于很多专用术语和算法机理都不明白,所以看不大懂……)6 [' ], b5 v* Q3 U+ ~9 x1 F; P) x. D# O
//////////////////////////////////////////////////////////////////////////; M9 ?9 A+ j5 `$ m
//                                                                      //' Z& b2 P- A5 `! K, b- }
//      NES APU core                                                    //
9 I( E7 A* }9 Z( a//                                                           Norix      //
. F' ^% C8 W) I! P4 [0 o8 c//                                               written     2002/06/27 //( j. e# r# N* ]( d
//                                               last modify ----/--/-- //; N0 j0 J3 W! P9 m3 z5 p. F: s
//////////////////////////////////////////////////////////////////////////
* T" J0 x6 y, R# g' M% D#include "DebugOut.h"
: S  [5 J% F3 y, [#include "App.h"$ @. Q" e/ H. C
#include "Config.h"' x" `# d0 ?7 n& S8 A

4 i+ {/ l- b# z9 m+ o#include "nes.h"  _1 t+ \1 _5 s
#include "mmu.h"3 r1 v: B- x0 v$ D) z: M' e8 T7 z- n
#include "cpu.h", I& g5 i" V- {" w* S) U! t0 A5 n
#include "ppu.h"
3 m9 \3 l! h& ?9 e: T7 ~#include "rom.h"4 d+ y- B+ F& c" V; z6 Z
#include "apu.h". T" R9 `$ ?, @/ }% q! I

) j2 n3 U& A+ i% \// Volume adjust
& L4 _, Y9 u( h. A// Internal sounds
! k& f  ]. i, |: \3 J( C0 {# h#define        RECTANGLE_VOL        (0x0F0)
* z; @" x( Y3 R, _; k" m#define        TRIANGLE_VOL        (0x130)
! C- x7 O6 U3 {, e2 c5 [! k0 k4 t#define        NOISE_VOL        (0x0C0)
  K2 _# C; Q7 m#define        DPCM_VOL        (0x0F0)0 ?) \) V1 Q  q, p% e6 b' U$ m
// Extra sounds
- u3 P4 D& A" ~#define        VRC6_VOL        (0x0F0)
+ V  e3 w' f3 c) B6 ]0 X% b5 x#define        VRC7_VOL        (0x130)5 d9 M6 }/ O7 G' H
#define        FDS_VOL                (0x0F0)
5 `" G' G+ I* h  R, f#define        MMC5_VOL        (0x0F0)
) w% F+ ^$ ^7 n6 E* c1 V#define        N106_VOL        (0x088); `4 A+ L: ]: f! Q6 q2 U) q
#define        FME7_VOL        (0x130)
' G" O) q5 Y5 V" _9 ]' V. [% {" s6 H' p$ X
APU::APU( NES* parent )
" K. {, |- ]7 j6 \/ z' |{! N/ Z) ?2 S& q/ ~
        exsound_select = 0;
8 s/ j7 A6 a7 U2 `; h; ]8 O; \  @" `& ]2 U) W
        nes = parent;1 P+ r/ _1 s& x/ S( u
        internal.SetParent( parent );- [5 a0 F) z3 V8 }1 f: ]* v$ d) p

* ~/ Z7 m- _. _: n; ?. A5 Y  k$ J        last_data = last_diff = 0;; ]% a  b) @4 y
5 b5 ^" O+ m; g7 }; {. _  [% \
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
2 z2 j  o- N2 E/ t. J- v. C* e- G$ l' `* M
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
3 Q' m8 _( q  H2 i        ZEROMEMORY( &queue, sizeof(queue) );
- y- B1 ~, A1 t1 |6 W5 Q# V) Z& v        ZEROMEMORY( &exqueue, sizeof(exqueue) );
$ y- k/ c# k9 `- J
" S2 J) ~3 S. O4 E1 a0 C1 t& a+ v        for( INT i = 0; i < 16; i++ ) {
  j7 {# }9 Y8 t( d                m_bMute = TRUE;. {* O3 V2 @3 l% f5 S  P7 {
        }  W3 V+ O9 r# ]* n/ z& S
}
/ X6 X5 O3 t3 b0 M- @
" I5 t% H9 t( H- N4 FAPU::~APU()2 r* o$ l$ z2 j; s0 B
{
6 d  ]9 l- X0 |}
6 k) K- `: y, W2 P
" I* \( F. [" L$ H8 J& C% `. Kvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )6 m7 D# V( o/ ^2 Y- G
{
7 l3 L" _) f) N* f& Q% Q2 M        queue.data[queue.wrptr].time = writetime;
! y& B+ V" Z6 S$ f! q9 d! C8 C5 V        queue.data[queue.wrptr].addr = addr;
4 f* U/ W# @# ^        queue.data[queue.wrptr].data = data;
- J. ~# |# g6 b, d3 ]        queue.wrptr++;
* Q2 F1 Z) J- H/ }9 [        queue.wrptr&=QUEUE_LENGTH-1;) ]4 Z6 L5 j  e% I, r3 ^
        if( queue.wrptr == queue.rdptr ) {
! |6 K3 M$ e" x" J$ x! C- z5 F                DEBUGOUT( "queue overflow.\n" );+ X0 p) l5 \9 n* c6 O3 Q
        }* J9 h. _+ a' y# V% Z$ Z
}( `: F$ y, K% p) F' D4 G8 c& W
) J  Z% B" ?1 y) i. B6 K0 w
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )8 \' |; A0 M" r. q4 Z
{
% c* Y- K- k6 Q        if( queue.wrptr == queue.rdptr ) {9 y0 h! U) w! f1 g! D
                return        FALSE;
6 v4 s( J; Q" |7 q. g. G7 b& c        }/ E% ~1 q! h# \
        if( queue.data[queue.rdptr].time <= writetime ) {4 s7 g+ O) F/ e0 S& }
                ret = queue.data[queue.rdptr];
4 S: \$ S: C: Z8 H# u9 t. B                queue.rdptr++;" G+ l5 q3 D8 X8 M; p) M3 H
                queue.rdptr&=QUEUE_LENGTH-1;
( p; a. H& c% {6 ]+ z9 I* b                return        TRUE;. X6 H' A& i; ]: u
        }
; `4 y1 }1 e% s% J+ j6 Q% ~. Z9 Q7 c( h        return        FALSE;! t6 z: a" N6 C. o: B
}& V# E1 b: V9 B. a% _& N
1 E% n# E9 v2 ]3 l4 C% H
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
6 _3 H+ P2 w0 z+ |{  O2 J( M1 I7 Z
        exqueue.data[exqueue.wrptr].time = writetime;
8 H* ]0 V+ X1 q& t! t9 z6 L! e        exqueue.data[exqueue.wrptr].addr = addr;
$ \4 P/ H  ]) k" k        exqueue.data[exqueue.wrptr].data = data;$ }( u3 i/ C1 p, r* k
        exqueue.wrptr++;
1 |, S1 S0 |& F% D* |# a        exqueue.wrptr&=QUEUE_LENGTH-1;  k& O/ @5 b8 q0 i( P5 a
        if( exqueue.wrptr == exqueue.rdptr ) {
0 I6 T$ r9 ~$ x4 z                DEBUGOUT( "exqueue overflow.\n" );4 a# e1 p$ ?" U- x2 i. [  O
        }0 P: x0 N5 [6 v
}2 _$ z0 U4 K2 O6 t* r
1 n# i# p- J' S9 ?. I) p, Q: ^6 A/ C
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
2 o' p( _2 T8 H) U{% g+ Z6 q: c& n9 Q
        if( exqueue.wrptr == exqueue.rdptr ) {& l/ q/ r. j' ^( S# r6 R7 @
                return        FALSE;
3 ]$ c* k7 i+ J0 K. y& m        }
! }7 Q% x2 R9 g        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
- H% K  Z, _. ~5 R; Q' \                ret = exqueue.data[exqueue.rdptr];
4 i. e; i6 o8 u" ?5 V1 b' C2 h                exqueue.rdptr++;
4 N( e, D# w5 D7 Z0 ]                exqueue.rdptr&=QUEUE_LENGTH-1;
6 r: N7 y! c9 w3 V8 T% q' l                return        TRUE;$ `' N5 W2 B; i1 Q6 C& z0 C$ w
        }
, {; R# ~; ]! h        return        FALSE;$ R) G+ c4 n. f; F. I! Y
}
3 d9 G' Y1 |0 ]) s) R# V' n# D& o
$ w" b+ L$ Y  |' }1 o# |void        APU::QueueClear()0 o5 M  O. @! T" \
{
3 y) c5 y$ w, _  N" P9 }. z; n8 H        ZEROMEMORY( &queue, sizeof(queue) );* p! W5 @+ y  N1 C$ R5 l
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
  K  `( b# {5 i, t$ {7 l}( K$ R  ?5 s' S# X: @
! b0 o7 [3 M) z, r) x$ `; x
void        APU::QueueFlush()# M3 J0 ^1 U4 M' j2 I
{$ k# b+ e6 l' ]/ h' x( v
        while( queue.wrptr != queue.rdptr ) {
0 g7 z; b4 U0 K' E& V                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
% \% F0 V2 I2 o1 L9 j1 `                queue.rdptr++;
7 q  G; x: T( t5 N5 ]( d6 c                queue.rdptr&=QUEUE_LENGTH-1;
) v% ?2 ]/ q& V* a# W$ O( k4 r        }6 N: `  O$ d* x5 H* B# ^+ D- n5 f. V

- S2 ?9 s1 k5 K5 V        while( exqueue.wrptr != exqueue.rdptr ) {& W7 e9 K& d, R9 C
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
! K3 l5 N/ ]: \/ q1 {                exqueue.rdptr++;
; P5 B4 N! F5 ?. c1 i, l! A9 k                exqueue.rdptr&=QUEUE_LENGTH-1;
, J2 ]- b+ L% G& C! H. q' [        }1 G* D9 {: Q  P
}+ g2 q: z, k* C6 I" L1 f
- w6 X3 @. z8 ^+ w
void        APU::SoundSetup()$ {7 ^# ~4 T! m4 Z& C
{+ B6 g: s; I2 H, _' _' H4 ~
        FLOAT        fClock = nes->nescfg->CpuClock;
0 o$ g$ ~! l# c. M        INT        nRate = (INT)Config.sound.nRate;" a2 L& f1 F# v" e! U
        internal.Setup( fClock, nRate );+ i$ M# }" V: L2 R* X
        vrc6.Setup( fClock, nRate );* s' ?' m1 a& X
        vrc7.Setup( fClock, nRate );% ^9 L# J4 b1 F& W+ t  U2 g
        mmc5.Setup( fClock, nRate );6 s: G5 H& x2 L
        fds.Setup ( fClock, nRate );0 `3 l; y% D% @0 A' |* K! S; T
        n106.Setup( fClock, nRate );, u5 X6 Q4 E& y* d+ R( Z. X0 d$ P* ?
        fme7.Setup( fClock, nRate );
: h" q6 p1 X" s}
9 Z( x5 x# @% c' |, I# I
3 H. ]& |) e' k7 |. d  mvoid        APU::Reset()
2 Z5 @! @6 g5 {{8 ]' i: r0 |! k5 e, l7 F9 L
        ZEROMEMORY( &queue, sizeof(queue) );: \9 z0 `- x5 M1 E; H$ h4 p
        ZEROMEMORY( &exqueue, sizeof(exqueue) );! I) ]- p( E/ h' o5 \! U9 c" {
7 W7 D  Z, d* G0 `! M
        elapsed_time = 0;0 U1 K7 v4 d$ e% X4 M6 y

5 m3 W) G; r0 F3 a        FLOAT        fClock = nes->nescfg->CpuClock;, F( e; d' Y+ p" p: P2 X
        INT        nRate = (INT)Config.sound.nRate;9 o9 Y6 f; w* p8 A
        internal.Reset( fClock, nRate );
2 o/ @( q. o. n2 o6 q/ c* A        vrc6.Reset( fClock, nRate );$ H9 U, ^' H  f4 d, F
        vrc7.Reset( fClock, nRate );6 M0 t; m- {% w
        mmc5.Reset( fClock, nRate );/ z6 ]1 G: Q! e( z) ~
        fds.Reset ( fClock, nRate );
8 ]+ E; Z* N7 E4 i. h        n106.Reset( fClock, nRate );' \% _: q: |8 d3 q: `
        fme7.Reset( fClock, nRate );/ ]* P% W8 W: |0 R" U$ h3 S. h

  I; f" Y& v' e        SoundSetup();
; X0 t$ J+ d+ u! ], V4 `$ m}
1 k& u& s: F+ J" l, M: H1 t0 O
! z: m; F# c; D% ^void        APU::SelectExSound( BYTE data )
/ M6 c5 g1 t# b" J0 |: E{2 [- e: P8 n% f- Q; j* E
        exsound_select = data;3 M. d. A6 u3 P: J
}$ V/ d. U% J! c. a

6 r6 j& R' F9 M: SBYTE        APU::Read( WORD addr )
$ e* k! u* u- h$ @{
; }7 p6 A8 ?7 s7 g2 G- ~        return        internal.SyncRead( addr );2 l& a6 j* @* N$ B- V) [$ j9 r/ p
}$ Q0 d; @: M" X

1 K0 g' D. o3 C3 c& ]6 H% Mvoid        APU::Write( WORD addr, BYTE data )& Z) L. U, W; i3 `* G& C' M
{
6 d# l; I, D# ?. ]4 J        // $4018偼VirtuaNES屌桳億乕僩0 Z7 ?4 o' L  B% L1 y+ ^( B7 R  ^
        if( addr >= 0x4000 && addr <= 0x401F ) {1 G" C$ |% F  @
                internal.SyncWrite( addr, data );
3 N0 T8 [) [4 M9 n                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
  M/ y( {# m8 E( U        }+ E7 U* f! O& K, {9 N
}
6 n  |" z) W( X. ]
9 B8 g: n2 K7 |7 j4 u" z0 l9 aBYTE        APU::ExRead( WORD addr )
$ W& E6 O# Q, b- ^# e5 I" S. t{
# @; N9 Q  z! ^5 m6 |$ G& hBYTE        data = 0;
7 O: n: L, R9 G, x. l5 ^
7 Q0 x$ V6 }3 I5 J; @( a        if( exsound_select & 0x10 ) {
  Y. ~8 B# p# M                if( addr == 0x4800 ) {
' W- R. t2 Q3 ~* G# ~                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
: U) T8 {4 a7 ^/ Z                }: [) j+ D' J( ^& I- j1 E4 y
        }
, y0 c- Z3 ]7 m+ P        if( exsound_select & 0x04 ) {9 T3 ]% j! L5 e
                if( addr >= 0x4040 && addr < 0x4100 ) {" `/ K/ f& l4 H3 S! x
                        data = fds.SyncRead( addr );
! n/ U0 g" l- K. Z9 [, n% Q3 n                }
) x4 M- L; A: T$ i        }
7 q  m4 r9 C6 G* S: I  T        if( exsound_select & 0x08 ) {
. O" [! K4 V1 q& I" y3 S( l                if( addr >= 0x5000 && addr <= 0x5015 ) {8 @  F! h$ J6 d+ S7 y2 Z
                        data = mmc5.SyncRead( addr );# y3 B+ m( C- ^1 ?( L6 P+ l
                }" F% O4 `( s& Y/ m4 ]
        }" ?2 l1 J$ V0 I5 A3 r- {" V, ?
$ ^, }$ [4 ^) n
        return        data;/ g# |" ^) ^( m5 G0 o2 }2 a- g
}
2 s- R3 {2 R& \; J) t
1 X( t, Y/ Z; B- L! Qvoid        APU::ExWrite( WORD addr, BYTE data )
& Z+ I+ H4 W* Z; \{8 k& r) X2 T8 B  @& k
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
% ?) ?( I* z  a$ g: M% V9 F$ M$ m, P$ {4 [( T
        if( exsound_select & 0x04 ) {$ `7 F5 m* R0 _4 p1 x
                if( addr >= 0x4040 && addr < 0x4100 ) {
. e2 P  }. W) ?+ z* c- j$ q                        fds.SyncWrite( addr, data );( ?9 p( z( I" s! _3 L
                }3 _, J: @' p; G8 a/ t, Z+ b
        }
+ }; e+ P  }) {" ], `3 {$ R& k: H- {' e- `, k' d( N
        if( exsound_select & 0x08 ) {
5 r; g' \- q; F% G. C: c* \* c, Y                if( addr >= 0x5000 && addr <= 0x5015 ) {, H1 Q# q" s6 R* Q6 q
                        mmc5.SyncWrite( addr, data );( l. W0 O: }4 u; S3 J
                }' |' ]  z- R0 E0 Y) ^9 r+ Z( @
        }
! M& Q/ E+ A5 D6 k( e7 |& j}
2 P) R! R( ~' I8 m( s* W4 G! Y  |  U6 e3 g& o
void        APU::Sync()
' a- `* X" W6 Y& W{
% A7 s5 i; @, Y  O}
. R. j" B' @9 t2 Z9 ?' L" d  @2 u/ p& t4 q4 K" F
void        APU::SyncDPCM( INT cycles )6 ]% J: x2 V) M5 l  ]0 d+ a( m( \: a& X
{: T  b: P9 _( M: i. ~8 v' H4 q2 O
        internal.Sync( cycles );
: @  z, {( g* d, j' g2 j/ w& G' C, Y: P1 {  O/ [1 U
        if( exsound_select & 0x04 ) {
& t; X! I7 q2 R* I& g0 s                fds.Sync( cycles );
1 `$ U) e8 U) o' ^1 X        }! e' K3 h: F; K) y4 e+ m3 J
        if( exsound_select & 0x08 ) {& [4 y4 {( S  E' W
                mmc5.Sync( cycles );
2 a9 x. X- p: g2 H        }
; s! V2 H$ e1 D1 J$ w}4 H6 j/ b, ~' ^* Q7 k

7 [6 V2 {/ j7 }- i) H8 b9 Kvoid        APU::WriteProcess( WORD addr, BYTE data )
  H) B3 h3 O% e: s* h9 m8 S$ U7 u* G{6 n$ l2 @9 m# \
        // $4018偼VirtuaNES屌桳億乕僩" g* k( L1 u+ y7 }# Q; a2 E% ]
        if( addr >= 0x4000 && addr <= 0x401F ) {
6 u6 I& F& D  @5 T3 n                internal.Write( addr, data );
; W3 ?( W! K) B        }
, h3 R- n/ E) R6 f}
7 w- N0 e# _. q% q$ j3 J3 G/ Q( h
; D, |6 c; x% zvoid        APU::WriteExProcess( WORD addr, BYTE data )
- S, K# Z* k* j{6 Z2 G- g, m3 E6 e
        if( exsound_select & 0x01 ) {: h! }8 q, o8 t; p1 z$ E
                vrc6.Write( addr, data );. c% L* P% L1 R
        }
. C7 v; g" @, K- o, e8 |" T% }        if( exsound_select & 0x02 ) {
3 R/ `8 a  e0 h, B                vrc7.Write( addr, data );
' ~) ?; p+ g( S6 U* p# W& G  w        }9 V# G8 j2 E" N0 j( x4 A' E
        if( exsound_select & 0x04 ) {
' E4 }! @/ n/ J3 J0 O                fds.Write( addr, data );
! e. H# ~6 `5 [* e- g        }' \# k( I7 m3 k! X" w
        if( exsound_select & 0x08 ) {  W6 T' \8 d& l
                mmc5.Write( addr, data );
, b0 A0 H& {2 i$ `        }& B9 x3 Z1 `/ d" F; c6 I" ]
        if( exsound_select & 0x10 ) {
8 t/ ~9 B! e4 F$ G" e4 Y7 U- u                if( addr == 0x0000 ) {% W+ h( K# |: L3 l8 I; F
                        BYTE        dummy = n106.Read( addr );
) t: i4 w6 E9 u3 s! u                } else {5 v! [- l2 M4 a/ ~9 r  u
                        n106.Write( addr, data );0 c9 w7 `( x' {* W1 n5 ^
                }
, Y6 f4 s& Z+ Y. N7 p7 b% [        }) B' U$ I7 \# m5 k- w1 r5 D
        if( exsound_select & 0x20 ) {
# x8 {$ ?- N" @                fme7.Write( addr, data );, K0 M& w6 K" P* |
        }0 I, F0 N1 x- Z- C% Q6 U
}
: H2 r" H% G2 f$ d! p! s& G% a7 j" \3 a9 F6 d: x: R. `+ I
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
8 v! j; X" L9 U{
$ F' T1 Q% K4 ^' A, F6 uINT        nBits = Config.sound.nBits;- O8 ]& Q6 T+ p" m6 c. ?( R
DWORD        dwLength = dwSize / (nBits/8);
- @  ^9 H" S8 e* iINT        output;  e: _* ^" r# q( T  K' k3 O" ?' b
QUEUEDATA q;9 I. l: I" p, g5 [8 ^0 y5 [
DWORD        writetime;
+ s2 Y9 N4 `  V1 |$ I# X9 u
% j; Z% C$ L) }) VLPSHORT        pSoundBuf = m_SoundBuffer;
2 ~' o% J! H  ?( G) s* d# c4 yINT        nCcount = 0;/ Y" [) r( j% f. x

6 d, U% R8 m2 t( m7 qINT        nFilterType = Config.sound.nFilterType;
: o' @2 ]) B4 ^7 j( j* j, e& q. G/ n( g
        if( !Config.sound.bEnable ) {
  L1 F6 {$ k: k; X                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );8 n/ c" {" @2 N6 W1 S5 }8 J
                return;
8 \5 l' i5 G4 k) d        }
$ L2 r, N3 A- b0 A6 L" [( L! l( X2 t# K. j% o3 y: X
        // Volume setup( n6 I( T8 p; y( |4 }* N% F. z5 I
        //  0:Master
  \. g/ t+ T8 x  Z        //  1:Rectangle 1
# q; D5 @) R0 @# Q2 g3 W7 y% h        //  2:Rectangle 2( s) e" J( r4 j& Q5 |: t" Z% m
        //  3:Triangle
  A$ V5 |7 H: V4 w. }        //  4:Noise9 o- T; X3 E* L2 j* q  p& |
        //  5:DPCM5 l8 ], `  K/ J. M9 y6 @
        //  6:VRC6
6 L+ ~9 Y/ ^' h) m0 N, {        //  7:VRC76 O+ w% `4 E$ O: |& i
        //  8:FDS
- J0 X+ x4 I) j9 ]        //  9:MMC5: p+ A5 Q1 m6 b" I* ]$ L& i0 K7 o9 A0 s
        // 10:N106/ c  y: V! m$ u5 D. [+ k
        // 11:FME7
$ t: G1 I) V# E' V        INT        vol[24];' [. Z9 g! n6 f- I( @3 L* f/ G6 Z9 v
        BOOL*        bMute = m_bMute;
% @! l) Y7 ?' A4 A$ r, z        SHORT*        nVolume = Config.sound.nVolume;
6 `( M1 C2 Z' W/ I5 ~
/ o" R' M* j' Y5 ~, z        INT        nMasterVolume = bMute[0]?nVolume[0]:0;& ]1 Q9 y: T: }2 \

; R. x! K7 B& `        // Internal
; [$ X. n. E5 n+ r9 j3 W, S        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
' s0 y! ^" ^! J% P        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
( ?6 O( q" e/ `! }9 K8 D5 z; {        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
; w. x7 P8 T& i, _" o7 K$ `8 j        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
' o; h2 `3 l6 W3 u: ?        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
  E. \4 a+ S$ h9 j4 G; c  T5 I8 O# S* p; X( ]$ X  i$ n6 J3 B0 \
        // VRC64 F5 K+ c: o: A
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;. ^# m. D1 X8 @4 f" L
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
- d; C0 b. d/ h        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
- d  k$ P( e! c# j8 q8 q8 D3 t! ?) ]8 o! e2 p/ `+ L
        // VRC7+ o8 d& S4 Z- Q$ G0 ~- ^/ Z
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
. d: I8 o* d& P$ I& _* \. _  Z4 x% t$ e% Q& }
        // FDS
; y! R) E6 m/ Z3 N        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
% E! x( V. R- d! O3 A
. {9 j$ C. g, y- c/ ?  w7 t        // MMC5
3 F! C  q: h2 m  d) e2 L9 a/ `& P        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;$ ~4 {9 y9 X9 B2 U4 V
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
/ H; F9 b. u5 y        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;& v% i; `, d! K7 b) g

! `; h% {' F  ^! }! r. q0 J7 D; s        // N106
( K' T# H) S$ p* ~        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
* f- i: B. {1 v7 N8 [5 h! i        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
( T* K1 }% I9 u: c6 ?! \4 z        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ u5 g6 {  T% ]5 S: ^5 ]
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;. x  Z6 v0 k! X' |: H3 r8 d2 Q* z% b
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;3 U( r( t2 I  v3 O4 o
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
( p2 S% k/ a6 X# d        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
% X7 G  r* ]$ b        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
$ b- `( {- Z+ u$ d1 G! e9 g; [" F% Z9 f
        // FME7* p8 ]3 N$ q/ v% ~4 k/ {9 s- k" Q
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
! P1 E6 c$ O5 `/ e& u7 V; h        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
( y0 a/ ]' V; b7 g- ~: M' }1 l        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
% b% z! k. ^7 Z. l0 o9 f" Z9 {5 v7 m# ?5 G
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;: T" B8 y/ P8 V6 ~6 e# |- a7 K9 A
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;  @! v  B8 c2 g: U$ M4 E+ k

: F& m0 H# h) @# O- Y$ {        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
$ ^0 O% _2 g) N) c. d4 W8 K        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
; O- ~( l" K2 S7 \/ v' U                QueueFlush();9 |' H( w" p; y5 q4 E4 z8 P
        }
8 U  V9 [+ @5 l& G
' f( z: f. A. E2 Q% w: x- X3 ^        while( dwLength-- ) {
0 G/ G2 i( M( q% z* l                writetime = (DWORD)elapsed_time;
/ O0 H0 M9 N! V! y8 ]. X# I+ t' @( C8 C# u" k
                while( GetQueue( writetime, q ) ) {
) P) e8 v; H3 _6 D! s; q/ R" B" S                        WriteProcess( q.addr, q.data );
/ G2 q9 C0 |+ r2 r9 M0 A7 \                }
/ V0 [0 d5 Y. F! b7 w0 a+ I: i1 O7 p2 V" U  [* o
                while( GetExQueue( writetime, q ) ) {
, t; y+ X+ T: C& U                        WriteExProcess( q.addr, q.data );, [4 n* L2 f9 e( d
                }
$ f0 f4 h: r" I0 Q8 K: ?5 w1 u% C3 e: g9 u6 s
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
) S: m  g4 G  E' S& R                output = 0;7 d) @1 o$ `- K2 g5 a) P
                output += internal.Process( 0 )*vol[0];& w8 T5 b  g1 O- a0 u9 \6 v1 s" y
                output += internal.Process( 1 )*vol[1];  N) `) a* u  w1 J6 _# A
                output += internal.Process( 2 )*vol[2];
5 i$ U, d# f  q# R- g3 _                output += internal.Process( 3 )*vol[3];
9 u; i$ n0 B: E! x' D) ~1 X3 c                output += internal.Process( 4 )*vol[4];5 u- t/ }/ k- G& l  B; ?# N
/ {3 L4 Y4 i0 C* T+ A
                if( exsound_select & 0x01 ) {3 L* o2 }# w! K; ?
                        output += vrc6.Process( 0 )*vol[5];
! K0 h9 [) p- I( C/ w! P                        output += vrc6.Process( 1 )*vol[6];
7 e7 Y& E7 C* A3 C; N                        output += vrc6.Process( 2 )*vol[7];! {" ^* h9 F$ q4 r& m1 x+ t
                }- O' T/ Y% i. G* ?. K
                if( exsound_select & 0x02 ) {7 E- l% o% @( L4 A4 H. S' l- N
                        output += vrc7.Process( 0 )*vol[8];
& ?+ i! j  q6 Q/ v+ P                }- x* o0 n+ H% K
                if( exsound_select & 0x04 ) {: t( ]6 t( w; O7 J3 m# O- Q
                        output += fds.Process( 0 )*vol[9];
, O; i! g* `! B* ^/ z                }
. v  O# p- H. b7 |                if( exsound_select & 0x08 ) {+ L/ B( I" X+ M: C& |/ m
                        output += mmc5.Process( 0 )*vol[10];5 w' p  \0 G% b  b
                        output += mmc5.Process( 1 )*vol[11];
$ h8 Y+ m. E# W7 z3 V                        output += mmc5.Process( 2 )*vol[12];
2 E  o3 U" _& f& J                }/ p9 C2 R- }1 J3 _& b5 V+ o
                if( exsound_select & 0x10 ) {
1 w, S1 a7 q& R                        output += n106.Process( 0 )*vol[13];
% I- m4 B* ~0 f                        output += n106.Process( 1 )*vol[14];
. y+ h! r) [3 P  h                        output += n106.Process( 2 )*vol[15];+ v9 }! j8 U9 o0 d. g
                        output += n106.Process( 3 )*vol[16];
5 y+ q/ w# I7 F* n$ U  c! H! Y                        output += n106.Process( 4 )*vol[17];. j$ s% F5 v! E
                        output += n106.Process( 5 )*vol[18];2 ~' u- ?! M; ]* E. M* S+ u
                        output += n106.Process( 6 )*vol[19];, c" |& C' r7 P1 q9 d
                        output += n106.Process( 7 )*vol[20];6 p. O! Q5 K3 N7 Z- {5 H
                }
& q- I+ q% R6 R; }                if( exsound_select & 0x20 ) {
1 d, [# X* Z% v* Q' H# N1 m                        fme7.Process( 3 );        // Envelope & Noise
3 ^) v; M/ I2 C% N                        output += fme7.Process( 0 )*vol[21];6 c3 a8 g: m5 `
                        output += fme7.Process( 1 )*vol[22];
0 r2 K4 c0 `1 s0 ^% p5 |" z  ]                        output += fme7.Process( 2 )*vol[23];
6 ?" ]; @2 E' q4 b, n                }% M2 Q: ]$ x' p. x) F0 ]; z
7 ~6 S7 s3 A7 z# P
                output >>= 8;+ C8 V5 S& g) o7 d7 O2 g
8 R7 r. c! Y" d3 r; f5 A# K* ~( z7 ^
                if( nFilterType == 1 ) {* m* S: `3 |+ Z" v' |( |3 k
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)+ X" o& U! v( o2 N' w! e: Z
                        output = (lowpass_filter[0]+output)/2;0 y& r; o$ O! D( X' B& d  L
                        lowpass_filter[0] = output;
- \  ^6 \' H! ^3 h# l% _2 n4 ~                } else if( nFilterType == 2 ) {$ {; j+ M# J& C6 ]! m6 A
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
" F; ~/ g5 u- p- t3 ?                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
6 ?! Y3 O3 I1 o! B4 S2 m: I1 L                        lowpass_filter[1] = lowpass_filter[0];5 n3 z; z0 G0 x' p5 K0 Y
                        lowpass_filter[0] = output;
5 r% I- ]) E. y" P3 l                } else if( nFilterType == 3 ) {2 Z% Q9 C4 F  a5 c" l  Y  y) D. d/ K
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
* S7 R$ P3 t3 z6 s& }                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;3 k* P6 G& w8 g0 a7 i$ e* H
                        lowpass_filter[2] = lowpass_filter[1];/ {' m' |  l" P7 N
                        lowpass_filter[1] = lowpass_filter[0];: l0 `% A) R% A1 W- `4 z1 Y
                        lowpass_filter[0] = output;
$ R: ~( C4 C+ K$ q8 n6 \! j                } else if( nFilterType == 4 ) {) q& \) j( D# J% E  L* e! P
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3); |8 B1 r; N1 m3 w. a9 }
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
- q8 L% A* z8 s% L                        lowpass_filter[1] = lowpass_filter[0];+ m8 j' W, t- y7 z1 W& W/ c' y, h
                        lowpass_filter[0] = output;" i" s' |. P, s' t7 _# r
                }
7 O9 J) u' M  n" c  t3 R+ n$ c6 a3 O, ]5 E
#if        0
! U- w! d( V" S+ J                // DC惉暘偺僇僢僩
  W6 ~* J' q5 i$ a4 ^& e                {3 B2 [# m: g- D, E& m# f7 j: f
                static double ave = 0.0, max=0.0, min=0.0;$ ?4 e( t! m% Z+ N) i5 ?0 \6 L( u" I
                double delta;
) D8 L4 l# s; A) k  a- J                delta = (max-min)/32768.0;
+ D+ a9 P+ c, |8 k. [7 M2 W' p  D                max -= delta;) ], R, \6 ?% l
                min += delta;
" x% X; v, C0 T5 X9 G4 `. I+ r                if( output > max ) max = output;9 B" X0 r) G& [* k0 d
                if( output < min ) min = output;
1 {! n0 c( m1 ]4 o" F; o                ave -= ave/1024.0;8 V! j9 g" y% \* t2 e3 t
                ave += (max+min)/2048.0;
) V, W; i; L. [. x$ W                output -= (INT)ave;
5 T! |/ o3 h$ w- J! \                }, \, ^7 ~$ L" q0 m- o+ v
#endif
$ W7 u+ M, s6 F7 r! M#if        1
6 b& N$ ?3 w  y$ ]1 X4 y3 L( X& d                // DC惉暘偺僇僢僩(HPF TEST)
! P7 U% g9 e9 a* Z& E! ^% v) d* M6 R                {
) J. x' v3 }2 ^' v. D% s//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
6 \5 i4 ~/ i8 t' u: b, O3 E  m4 e7 |                static        double        cutofftemp = (2.0*3.141592653579*40.0);4 j& a/ z) b+ t8 G8 y; @+ x
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
2 P' V! W9 d5 K* y( q                static        double        tmp = 0.0;9 p& E* v" Y" }6 G
                double        in, out;: j0 }5 U5 L2 U1 n# c

2 e4 Q& N% X$ S* H7 B                in = (double)output;
" c6 Z9 {9 f  a9 s$ k                out = (in - tmp);
# y- n$ w2 O1 L6 ^3 N2 Z( a/ Z                tmp = tmp + cutoff * out;) A$ M; v/ t, I( H0 {! x; q
* H. Q. c  E1 B% O; t) l3 p, G2 }
                output = (INT)out;
/ B8 u# [6 a% K  u" |                }3 Q: R, H& y" Z) K' A
#endif) L) M1 S  R4 k5 e7 z, A! x/ c
#if        07 n/ d2 n8 A1 }9 c. m
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
6 b2 O% o. ^) K5 b2 Q0 }                {
2 b4 v5 a  s% j2 @- Q: u                INT        diff = abs(output-last_data);4 O; l8 m6 }, }  v( A
                if( diff > 0x4000 ) {: q' b! g, M; q5 x; E
                        output /= 4;  y, ?: j4 \- ^8 I
                } else
9 V9 j8 e3 h& Z* H                if( diff > 0x3000 ) {
9 ~# S6 @: Z9 T+ [+ \, a9 F5 m                        output /= 3;
9 d1 g, i" P& \  G5 h* |2 ]) ]7 [                } else
5 L# l' q: {% ?/ p; |                if( diff > 0x2000 ) {! \5 S& j# R3 ~3 L
                        output /= 2;
0 j( R" s; j/ c+ C- w/ f% x                }
7 n( I; R& P2 S! z; v                last_data = output;6 W; v* x) W0 g) r0 R( i
                }  f$ h9 c. X$ j
#endif
, x6 u  m: l- f                // Limit) H9 `- }6 d: }5 w  P$ b" P% ^
                if( output > 0x7FFF ) {
- H" ~8 ?, H; Z: R: J' ]5 C1 L6 e                        output = 0x7FFF;
. ^5 `% y2 Y7 e" I                } else if( output < -0x8000 ) {1 ?8 p* v/ x( u9 `3 I2 W: [
                        output = -0x8000;" k8 x& ^( E3 j
                }$ g+ \! C) o1 o$ L
, `5 c1 Z% \( \1 p8 D/ Q) K& U7 Q
                if( nBits != 8 ) {
8 \8 B) K" X! Y' r- g                        *(SHORT*)lpBuffer = (SHORT)output;
$ M  f4 v- u) v2 n9 z* p                        lpBuffer += sizeof(SHORT);  z' s$ J% P& E- d5 b3 ]+ ?( K
                } else {
9 h+ I" M: `0 c3 c7 i                        *lpBuffer++ = (output>>8)^0x80;
7 a; d$ g6 e9 c: d* f                }# N# b8 J. v5 Y7 i! w6 F

; G" ^$ ]9 B7 ~: j: t& i                if( nCcount < 0x0100 )
( |: K0 D8 _2 N# j' d8 `3 v" d7 ~                        pSoundBuf[nCcount++] = (SHORT)output;% y5 R8 I$ C: J% z# \" g1 Z
3 f% |, Y; a+ i- E/ Q
//                elapsedtime += cycle_rate;; R" J6 a2 B0 @6 L2 x, v. T# D* G  x
                elapsed_time += cycle_rate;9 a9 d+ U5 A3 D  ^+ D) z
        }
! w, W0 X& h+ J9 Q' Q% l: G& Y$ k( Z- M# E9 d3 F$ x
#if        1; ^" q+ j; e- C4 S& }3 [8 A' ~
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {, v% F4 u: i, s3 F7 u6 n; i
                elapsed_time = nes->cpu->GetTotalCycles();
; A7 v' o& F+ r6 P( V0 |        }6 T4 F) w. q! j* Z" U
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
" f& b: n  O; [0 c  ]- }# h                elapsed_time = nes->cpu->GetTotalCycles();
. q/ }# J- f: h0 w        }# s* [* \% W+ m' T: ^6 @" Z
#else
, a5 ?, X* W; Q$ @2 {* |        elapsed_time = nes->cpu->GetTotalCycles();
) I% i- I; @- l5 t2 [$ K/ y#endif
. j$ w4 {0 C1 k; N+ w0 U% o, _}, ?) V& p0 u  s) I0 \

. z& g0 n3 G; _( K$ }// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
/ T1 |$ v5 e% g/ OINT        APU::GetChannelFrequency( INT no )" [3 S' ^# X& `
{
4 ]5 a8 \; S4 Y' D        if( !m_bMute[0] )( ~  l& J! v" J  v
                return        0;
3 |- W/ e. T4 m9 T
! f) U4 W# X3 `+ a- k6 v        // Internal* G  `% N3 b9 G; F/ M+ o
        if( no < 5 ) {0 ^9 m: t; g9 m* K3 _9 b' \
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
- y1 B) g( I( S, Z8 N/ m. q7 K, f6 k        }9 L9 Z# t, d2 u1 O
        // VRC6' w* I5 o8 W, v' e( M# a
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {) O8 l& U( _3 w/ d! q
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
8 _/ \* t4 `7 M1 B" Y* C- {7 p* V        }/ _- s/ \) ~/ D5 I) _- A& G+ w
        // FDS
. g1 U" `/ j& d. r- N8 w        if( (exsound_select & 0x04) && no == 0x300 ) {: K2 P3 q1 Z) e  O1 j- ?8 F
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
6 Z: x* S3 b. _1 v, _. S        }" l) p7 j; {9 m
        // MMC56 Y& @3 N, U. v1 d3 z8 H; e
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {  B. w; `6 K  X* @: L
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
- ?4 i$ r4 p4 v# _  ]6 X, a  y/ l        }
3 h1 J- Y4 a; k4 O7 x; U0 F        // N106
- l. |9 M, I3 X( j& }0 ~        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
1 |  T3 M/ L+ E# p' Z  p, o                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;! T' M4 h3 S" L6 l1 C. j9 z. v! y: w
        }
) a, H$ t7 y2 P# a5 C        // FME7
' j: t/ e, _, B1 ^9 a# b& p; Y  Q        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {: G$ c  b( Y5 U+ i& r: I8 c
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
0 t" T9 _! r: c! i; F6 S5 |4 j3 u        }
+ v/ d5 z# b. b5 e* o        // VRC7! p0 b* }# J8 v) a; u1 X: |
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {5 \! z/ _1 _$ {& z4 K
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;% j" O- E- b8 a# V1 _
        }  Z: L* i: Q- `& l9 C! H3 S! y+ Q" v
        return        0;
4 ^6 l: j% R* A( H% h$ }8 Q; y}$ ^6 |3 M5 I1 R
- b3 w' o0 }" V& }0 N- j' n
// State Save/Load
7 r8 U1 `4 @/ m/ {% Bvoid        APU::SaveState( LPBYTE p )1 f( v! [, y" Z% m7 B" @. z  c
{$ F" l0 M: S& P7 \$ ~( s0 g
#ifdef        _DEBUG
# E# D( }. K( D% `LPBYTE        pold = p;
# \% a$ B5 @6 L- J4 p#endif4 M: e/ x/ M; f8 L( Y
- Z+ K# P5 `) n9 @' k
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞2 u4 |: ]& a8 ^1 s
        QueueFlush();5 r1 r+ q2 Q( l/ I; `$ l1 u$ x

8 R. X, E" H& D* V        internal.SaveState( p );
. _  v" R/ h# k1 G3 e- @        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding# s4 N0 d9 V( @1 W! [

9 u+ K7 e  s* E- W& N        // VRC67 c( _! w% Z, B# _( n" ?6 v
        if( exsound_select & 0x01 ) {9 C6 C' W; m5 J! D1 g+ Q
                vrc6.SaveState( p );' V; V0 p8 s1 [$ I
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding: W9 i1 Y( t2 k4 x% r7 o; F% F
        }( E( \) s7 O+ I7 P
        // VRC7 (not support)
6 T0 z" j: {* Y  e; ]' f        if( exsound_select & 0x02 ) {- |* w/ O1 n$ m$ T8 g# s
                vrc7.SaveState( p );# a% c6 E* G& u
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding! H3 Z# u# f7 J* A
        }
0 u% y. q9 }  I  R* e: e$ w3 b9 L        // FDS4 i# e% J$ W( K* j5 w6 D
        if( exsound_select & 0x04 ) {7 h3 p& Y& U( H% X0 s: F
                fds.SaveState( p );
$ Z+ I0 N6 l2 d# s                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
$ H9 Y; Y+ |8 x1 l. v! v$ N7 A        }
* K9 K& Z0 S# K        // MMC51 t' r: j1 A- ^, R7 r' ~7 \) {# e
        if( exsound_select & 0x08 ) {7 d- C$ K2 Q* L/ u' b9 e& q; g: |
                mmc5.SaveState( p );
2 c1 U5 `% l. i) l, x                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
! x; V: \/ p% b$ \0 ^4 Z        }2 u3 y/ l; q- g: i# O
        // N106. S. D' j- T. `9 b. N
        if( exsound_select & 0x10 ) {) z* A0 ]; g& u( ?/ R1 S6 r7 \
                n106.SaveState( p );
7 t& ~6 [% Q) \* R) P                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding, u$ V: `! \0 J3 S" `1 R  x
        }
& _5 f# O2 J1 t( @) W        // FME7
6 k: I, G) @7 l        if( exsound_select & 0x20 ) {: Y9 k$ L* H0 L0 F3 ^( ~
                fme7.SaveState( p );
6 q& i# q- _8 q$ A) Z                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding: q( R& n5 W) U" f$ [
        }
/ Y5 d0 ^5 A+ X7 y; F7 H& G& L
, |. s6 S; f7 M* j* J#ifdef        _DEBUG. e( a2 X  P1 @: ]
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
, Y* ^3 m8 _1 \& b#endif
6 B5 ^% e! X& P( q+ A4 L3 i; {! d" r}
9 J& E* P0 S" u
# B2 D2 G. _% I1 s4 avoid        APU::LoadState( LPBYTE p )8 C% [7 [' u6 c% w
{+ ]6 w8 o+ _9 H" F3 ]( I8 a
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
  n1 I/ s" W( s- u) O        QueueClear();
* v& G' y7 F& C# h% R/ W
9 K! a# Q$ d- a& c- Q        internal.LoadState( p );3 N+ \3 A6 ?3 B5 E3 d
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding: G3 R% F% E. a& H
; Y# B9 R' G9 a6 }8 T
        // VRC6, M# L9 E9 z! L5 P
        if( exsound_select & 0x01 ) {
, P, d% ~; R0 m  d2 {                vrc6.LoadState( p );% p- b7 C2 O5 n7 D# Q, c  I/ P
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding) G/ X  H7 b0 `" E# h/ r
        }
6 F  j) N/ {( r: h        // VRC7 (not support)
# G% X, X: y7 f        if( exsound_select & 0x02 ) {" Q+ u: |0 E3 q% g* ^
                vrc7.LoadState( p );
2 M8 V7 s) a8 P/ N! ~                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding1 ^4 N. Q; U. \, ^
        }
( @# c7 r8 H: s5 h4 _5 y        // FDS
% c. o- d$ l+ k1 G3 ~: X        if( exsound_select & 0x04 ) {
0 P% w) H3 S2 u5 S3 \$ \# j. H! n                fds.LoadState( p );# M' ?, L4 o+ X# B  ]
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
; g7 K! X3 X, M% q" W. t        }! |6 j0 `6 s( c
        // MMC5
( y( A* r) [, v        if( exsound_select & 0x08 ) {, H, w8 e, t& \& l- A5 V, I1 c
                mmc5.LoadState( p );
" y1 C2 g+ F+ C8 O                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
# a$ C* [6 n' U# ^! A+ e) J; P        }% h. e' ^8 m* ^1 E
        // N106
6 l' W% ]  I4 i8 g% Z' h9 i        if( exsound_select & 0x10 ) {
9 i- R2 v- r7 X! s9 s( g. J# y                n106.LoadState( p );
4 v( `8 M+ h3 a5 f/ ~* ?2 f( T                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
- h, R$ N. u; z# d' \. F        }/ u: p( `( `" [/ h! i
        // FME7
  v. h; Y. u9 ^( m. o9 W# ?        if( exsound_select & 0x20 ) {  b/ ?$ [5 X2 h) }
                fme7.LoadState( p );
) J3 h" b. t; q4 I6 Y, C                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
- K" z% x% N- D& t6 s8 a        }
9 n. j4 T. _1 Z0 r7 s+ e}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 , s  e; M8 h* Y; _! e# K
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。; ~( Z; {; q: s2 G5 E3 v
感激不尽~~
6 O, ^+ w9 _  b& l* |
恩 我對模擬器不是很有研究,
0 E' T4 u- h' b7 H$ l雖然要了解源碼內容,可能不是很困難,
0 Y# H! l' X; `不過還是要花時間,個人目前蠻忙碌的。
. A( q5 r- N. k3 e; y& H) m, T7 E# [; d
給你一個朋友的MSN,你可以跟他討論看看,
+ \6 K: Y2 }0 f, \7 j2 ]" l, x# k他本身是程式設計師,也對FC模擬器很有興趣。
' z/ c  q  K0 @- R) G
) b; t. N3 n8 B* o- o7 D/ t9 eMSN我就PM到你的信箱了。% D" z6 V) |1 l& m9 w6 t
, X) I& Q# B# u- w% }
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 2 e9 B5 y$ f" e; u
呵…… 谢过团长大人~~

* V4 ]/ a+ q# D
! q0 Z' l& E. M' }6 N哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 ! N, i6 l& d% u5 V& N
团长的朋友都是神,那团长就是神的boss。
! r! e$ ?+ I! }1 W: y) x
哈 不敢當,我只是個平凡人,
+ _) N, r. g# V4 @" F# K要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
- X0 p$ q- I! u3 ]ZYH/ ^4 h9 f; {% c% ]1 j
QQ:4147343065 v8 s! j) U- Y+ w  m
Mail:zyh-01@126.com
; a: \+ ?/ `  m
! R: s$ ?: H3 x& ]他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
0 M9 ~' ~3 U' ?' j9 W- a- V再次对团长大人和悠悠哥的无私帮助表示感谢~~
" ?$ A% N2 t4 g
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-2 23:16 , Processed in 1.090821 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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