EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。- Y0 C# _6 ]3 f& H' Y
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
4 f* p# I' |6 d' |0 s6 Q$ d$ n: `3 B6 {这里有相应的模拟器源码,就当送给大侠了~~' N; q! c2 q1 j# p% q) o
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
$ s; m6 @( W. I2 ]$ M能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
2 `8 j8 h3 o+ i' v' }* V楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~6 Z/ ]& j* U' v9 W# n8 I- Q/ ~
这里有相应的模拟器源码,就当送给大侠 ...
0 |1 t1 W2 V, i0 p* [0 ?
聲音部分(Audoi Process Unit = APU):  I2 p8 H% q/ y/ J. s2 I6 p
.\NES\APU.cpp. y; P: l+ X" [3 V2 J  A
.\NES\APU.h
! T) y6 N+ q- d: d1 K5 h. o2 F! z/ {+ V

! q1 S: @! K$ C" Q影像處理部份(Picture Processing Unit = PPU):1 J$ ~5 W; F9 F/ b' G0 U& ^
.\NES\PPU.cpp. L2 H7 d1 o7 r" X3 t8 C9 F1 `
.\NES\PPU.h
7 X9 u& V- b' l
) C8 ]1 `. H$ p2 e4 k/ z( L如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:. a$ S6 D0 o) {* G8 x4 L7 ]- l
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
1 E* A9 r8 q- P0 i- p! v. g//////////////////////////////////////////////////////////////////////////* A% W( J* b0 q' Q4 |
//                                                                      //
6 I  j) I2 b7 d2 P9 J//      NES APU core                                                    //& ?8 l9 c# J: j6 M& a0 n
//                                                           Norix      //
  ?( {" w) P7 H) O5 U6 K//                                               written     2002/06/27 //
4 O5 z3 E9 t1 j! ~' h  W+ i' s1 l# [//                                               last modify ----/--/-- //
7 d) U% H1 m& M0 g, ~$ }; e//////////////////////////////////////////////////////////////////////////
( o7 f4 w+ v% X% o8 |#include "DebugOut.h"
$ G4 R* c/ j  y. D4 K$ j$ _#include "App.h". _. V! U6 V( B. A
#include "Config.h"
% r+ F6 F& R5 O( n
2 V' d# I: c6 H2 d1 F- V#include "nes.h"
& o6 [$ V7 v. b& l8 m* k#include "mmu.h"1 F8 e4 G1 Y  c% @& g! u
#include "cpu.h"9 T; Y; m: c( {7 b1 G
#include "ppu.h"7 U# i( y8 i5 y! S+ G
#include "rom.h", V6 M7 P9 s) l
#include "apu.h": }. \( S) @3 b: o  o
$ g' }6 f$ Q/ s! G
// Volume adjust+ L( r8 y' a, k  m6 M9 v- S* \. @
// Internal sounds5 [+ B+ v( t/ _- g
#define        RECTANGLE_VOL        (0x0F0)
5 @8 L1 c' l) Q5 U" Q5 S# n, A#define        TRIANGLE_VOL        (0x130)
% z3 V/ e) u; A% t#define        NOISE_VOL        (0x0C0)4 i$ x* E5 ?& D
#define        DPCM_VOL        (0x0F0)
! v' T# J9 F+ n9 T4 B5 m/ P& B% P// Extra sounds
' f' d+ K! I% q#define        VRC6_VOL        (0x0F0)0 J' X* J, \; Z  a2 v6 T
#define        VRC7_VOL        (0x130)
$ v$ L( _1 f$ c% b6 E5 r#define        FDS_VOL                (0x0F0)
4 l( M) u; |- b: i/ K9 T#define        MMC5_VOL        (0x0F0)# q# j* o6 M/ [$ Y( R5 d5 M
#define        N106_VOL        (0x088)  ?8 J( J& u' t. Q$ D
#define        FME7_VOL        (0x130)
0 H6 W" \4 }* b/ P' h$ t2 N1 Y( J- L6 r+ b1 Z) O1 _5 {" R& B
APU::APU( NES* parent )
; D0 U; H# p3 T2 Z4 A{9 T( v4 V; ~; @. N5 }. l
        exsound_select = 0;% [, Z% o: ?) O! d5 n6 W- j
3 V2 ]: Q# U9 g; Y: ?
        nes = parent;, S/ C) H- v- @
        internal.SetParent( parent );. x& c5 m& a2 @: W6 O8 k0 g6 n2 x

3 X* u4 U2 s  v5 d7 a) u, `# S        last_data = last_diff = 0;+ i4 t' x( ~/ q0 q% D

) z6 W+ f& H4 \# R& |        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
1 n+ o8 Q- w5 b6 X" E* M; A  ?9 \
( M3 p8 P( r) i- i        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
; d3 G8 B  _. Q1 i4 G        ZEROMEMORY( &queue, sizeof(queue) );7 c! F% |5 [+ @& Q3 Y
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
1 ^" |/ s- B" h( a8 \! s7 N5 N3 N! d
        for( INT i = 0; i < 16; i++ ) {0 g3 K) m* d( K' q% ?
                m_bMute = TRUE;
1 `8 ^# C7 V( Z  {' f( G        }  h- o1 W0 ^2 m4 s- j7 A/ Q7 _
}4 ~: t- M9 n3 @8 }8 S

: c1 u$ m* S7 G5 p: XAPU::~APU()( X6 i8 H  u8 ?9 m: r6 z4 s, |
{# C8 z& ?; m0 H! [
}6 t% c4 D; b  ^- h/ x

( m' i! ]% K# L$ V4 cvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
. ?& H. x: H% u) ~3 |6 d{
, _' V5 _4 `( m- Y        queue.data[queue.wrptr].time = writetime;9 e- W) D# U$ p. ~
        queue.data[queue.wrptr].addr = addr;. F+ J. w6 h( o4 f( b
        queue.data[queue.wrptr].data = data;1 @' K' h9 [. K. m; w: F/ r. U
        queue.wrptr++;
  Q0 s* J: f" b5 `& L' `* j        queue.wrptr&=QUEUE_LENGTH-1;
# G$ A, D8 `9 G5 \+ I        if( queue.wrptr == queue.rdptr ) {
) M' l( I& q2 e% A- P& |+ V" v$ H                DEBUGOUT( "queue overflow.\n" );
! c# X% z9 W2 }% C        }
3 c7 J& P! j+ K! f( Q}% J' [$ r5 y& U) q
0 I" N3 V$ d% A! B3 c
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
8 T" |+ j' D" K% x{
: x4 r& A/ k9 J        if( queue.wrptr == queue.rdptr ) {
$ d( S3 J& k0 c$ w# L  ~! A                return        FALSE;
# }: e# U$ y, \0 ^, y        }! C5 I$ f& Z4 u# {' F
        if( queue.data[queue.rdptr].time <= writetime ) {
7 e( e( A: h" w" a6 I% m5 t+ J. U                ret = queue.data[queue.rdptr];
# r3 r, T* d5 [* [                queue.rdptr++;
4 l5 j& ~7 s. L                queue.rdptr&=QUEUE_LENGTH-1;
' z1 C% _6 K& A# W: g% J* _/ m9 P                return        TRUE;
  I" G3 V% k  j0 M, n6 {2 W        }4 K5 j' K3 L: V; {
        return        FALSE;& p  R2 J% I7 ^! d# y$ p: H8 Q
}
9 R) b$ ]4 E* t4 W( [" ]4 L
$ f' p( O7 V) u9 b& Jvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )# p5 z4 |# M7 C3 v$ J
{$ P2 k$ r% Y& ]1 M# A& n
        exqueue.data[exqueue.wrptr].time = writetime;/ f8 w' p4 V4 X4 ?4 \
        exqueue.data[exqueue.wrptr].addr = addr;
( o, Y" X; [- ~: o, I4 x$ X        exqueue.data[exqueue.wrptr].data = data;
$ g; }! _/ h; e        exqueue.wrptr++;
9 K  T$ {% n# y& \3 `        exqueue.wrptr&=QUEUE_LENGTH-1;
9 L1 L( e& p' j+ U8 ^        if( exqueue.wrptr == exqueue.rdptr ) {
$ P  K5 k2 R: L. t' I; k# F! ]                DEBUGOUT( "exqueue overflow.\n" );/ w7 k, D) ^# S4 a) R
        }
' J( ]- Q; K: W+ ^, }/ R}
6 D" p8 o6 i* e& w3 M3 q
  m$ p! @9 o1 e! a& Q& ^/ qBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
* @/ N) ]' N3 y7 U{7 V1 H1 P1 G, ]9 I9 `  W
        if( exqueue.wrptr == exqueue.rdptr ) {
4 D5 t( R$ y$ N6 _# K, g                return        FALSE;
1 G+ ~/ M0 k2 b' w( D, N: O$ K        }: ]+ l7 U0 {0 g
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
2 A( z% ?+ W0 P. T8 ?                ret = exqueue.data[exqueue.rdptr];9 L- L' G- Q: S7 w1 e: l2 {! q
                exqueue.rdptr++;
; B' {# h& b" @* u% _                exqueue.rdptr&=QUEUE_LENGTH-1;
: o2 K( Z3 C' O5 a% x, E                return        TRUE;* W8 m# m2 V7 Q. J$ x/ ?
        }6 [2 v  K2 U/ K; F
        return        FALSE;8 y# F1 w# y5 V: p! z. \3 l9 S
}
; A6 D* f& X2 O# A
/ H7 w( p& A$ \, T0 ~. L5 g* ~$ n6 Nvoid        APU::QueueClear()) a7 U8 r' N2 w+ `2 I: \4 P* q
{8 [7 L; [3 L- L% r5 G1 M7 k2 ?5 x, S+ ~
        ZEROMEMORY( &queue, sizeof(queue) );
# f' Y9 B- ~9 h- U+ l" P" U: J        ZEROMEMORY( &exqueue, sizeof(exqueue) );8 C: ~2 k% ]8 H7 i- \- ?
}
2 D! x( d! r0 A) B; o9 X0 U' w. o( y/ ~
void        APU::QueueFlush()
$ f- B5 y; ]" _; t{' Q0 m. a( t6 R4 f+ _/ v7 X  A
        while( queue.wrptr != queue.rdptr ) {6 X3 C8 W+ @# R6 u4 V' v* F% h
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );5 E/ J0 h: X$ V! M# X
                queue.rdptr++;
) D0 m" |* s0 R, B4 e                queue.rdptr&=QUEUE_LENGTH-1;
. T. W& F+ T1 M8 l. e: J6 d) ^        }* x( x7 {+ p: V% m

  m! a; s2 C. d# K$ E( J        while( exqueue.wrptr != exqueue.rdptr ) {
* ?+ d% ^9 j" |- c) Y" m- J                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );1 V* z$ [* P$ T6 p
                exqueue.rdptr++;5 r3 L* B3 t- k4 ^7 y
                exqueue.rdptr&=QUEUE_LENGTH-1;
: @. h; v8 Q) V! a3 n, N        }% w( _7 _; o1 H) Z9 Y: T  T
}
2 L; Z  K8 w0 Y. U! v& e( t6 w% G9 e2 i9 v
void        APU::SoundSetup()7 i9 R: \* n1 S; K! k
{, b  I  n  X1 N- i; O7 ~
        FLOAT        fClock = nes->nescfg->CpuClock;  h3 @% h) N- ?) p
        INT        nRate = (INT)Config.sound.nRate;3 _+ b8 K, o* t7 S
        internal.Setup( fClock, nRate );
- u! M) E8 M* H3 Z$ y" L# e        vrc6.Setup( fClock, nRate );, U9 D& z) |) a0 Z1 p
        vrc7.Setup( fClock, nRate );
7 b5 D+ k8 e8 u4 C+ G        mmc5.Setup( fClock, nRate );
6 H; v3 Y4 e9 y  P8 p; L        fds.Setup ( fClock, nRate );
6 D( v+ ?% u4 x  U        n106.Setup( fClock, nRate );
( _( m& A4 }4 K7 |        fme7.Setup( fClock, nRate );
" f. _) b5 t( H1 X}
" |7 y# ]3 L9 s1 b
4 w( H+ @7 b( B5 [8 K7 w/ w; wvoid        APU::Reset()
3 |, i; \5 ]6 B{
* f* `3 ?1 K% ^        ZEROMEMORY( &queue, sizeof(queue) );
5 Q# _: z0 C2 T& L+ u/ k. E        ZEROMEMORY( &exqueue, sizeof(exqueue) );
& P! m! y  L, D/ C$ z% ?) z2 U
$ m1 I; r7 O" {; ]( @        elapsed_time = 0;
$ U4 I* c  B( A" m6 H; t- s& V7 C& v$ j% q* O) ]- h* Y# P
        FLOAT        fClock = nes->nescfg->CpuClock;8 ]  {5 Q+ A6 l% g& v
        INT        nRate = (INT)Config.sound.nRate;; K- i5 S6 r% q& f9 f8 b0 L
        internal.Reset( fClock, nRate );. A6 T# E: n  n& G4 I3 }1 ~
        vrc6.Reset( fClock, nRate );, w2 Q+ R6 N3 F' m" P
        vrc7.Reset( fClock, nRate );
, n/ C$ Q7 Q4 K- w/ W) @& L        mmc5.Reset( fClock, nRate );
  q" A( p0 q& b+ \6 Y+ x7 x        fds.Reset ( fClock, nRate );
3 |& X" _: L: h( V, p        n106.Reset( fClock, nRate );; x! a' ?" J4 w6 c: J: \  m2 W+ x
        fme7.Reset( fClock, nRate );$ h$ W( [9 g0 `4 D$ J5 o

3 L- g3 I7 _0 p# t3 [5 G        SoundSetup();
/ t6 T: H8 P) l4 a/ Q+ s: }0 V) B}3 Q; }% Z5 Z% W. O8 o- K- R
) O' Z+ ?: G( E, J7 b, A' k
void        APU::SelectExSound( BYTE data )
  ^6 t$ u& c  W5 G& x% l/ H3 z{0 q; C0 u2 U* \& y' F3 j" m
        exsound_select = data;4 \, w9 ?: Y: s3 p* q) L! l
}
( ~/ K# l" }! `0 L8 `- W5 C8 V" C0 ]0 t6 H$ G" l( H3 X' u
BYTE        APU::Read( WORD addr )
: @( z, G* ~# j& j+ V{( a2 [! B+ Y: M- d' l: o
        return        internal.SyncRead( addr );, T$ z8 d% P' T4 e8 J
}. f4 R& I; s, L: B% ^

- P$ @$ I  _5 bvoid        APU::Write( WORD addr, BYTE data ): i$ v' `+ x6 `+ W
{( z: Y3 C1 }' C+ ]8 v3 C
        // $4018偼VirtuaNES屌桳億乕僩
3 ^! U4 q- t& ~0 @: B1 c) _( O        if( addr >= 0x4000 && addr <= 0x401F ) {
5 I+ l8 j& m3 Y. ~                internal.SyncWrite( addr, data );
$ y8 y" }# \* g& E7 A& J6 C                SetQueue( nes->cpu->GetTotalCycles(), addr, data );+ V9 ^  r; l1 K
        }( ~5 j" T2 n" `6 V# u
}
. X# J- o; |$ s
+ d/ D' L9 T  i; |BYTE        APU::ExRead( WORD addr )( e/ _0 k# H8 f. x3 }6 Z4 H
{: h  r  l  {8 A9 ~8 Z
BYTE        data = 0;
, w# L7 X- ~4 ~6 Z( P% t" u( A7 b5 q$ o
        if( exsound_select & 0x10 ) {3 a8 w8 R$ W8 h
                if( addr == 0x4800 ) {" U) H% D' Q0 i1 @! E
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );/ A+ e9 u0 j% z0 g, f
                }& }3 P; y/ L3 l0 D: ]) m
        }
4 p' z' p( X8 K' H' F+ G" I  z. t        if( exsound_select & 0x04 ) {
! I2 k  T1 v- z- _. g2 D                if( addr >= 0x4040 && addr < 0x4100 ) {
& [# n" E! _, R# B# I                        data = fds.SyncRead( addr );
+ o2 b7 m7 W8 M3 i  A6 f& s" F                }* m0 V- g% }3 z
        }2 q$ n% K1 m7 k4 g3 ]
        if( exsound_select & 0x08 ) {* i+ h; B* j# ^
                if( addr >= 0x5000 && addr <= 0x5015 ) {: m! }& N' u3 u- T% Z: t" X$ j; P
                        data = mmc5.SyncRead( addr );# P, d  k9 B+ N0 z' _
                }
2 K. K: q/ r* M" i        }5 W* Y# y: V# U1 A0 _: [% t

' [, \9 a4 J% d5 N& t/ \        return        data;
. O$ v/ j" y3 V8 E, K5 U}
2 c1 x1 p  z; F$ m% T5 G2 \
* h& ~( q7 T# ]) {void        APU::ExWrite( WORD addr, BYTE data )8 N6 P' h; S& c6 y5 c# d4 @& s
{
  s) `, w/ T* \# f. s" b% @        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
5 d0 M. Q: L! N# k" z
# [1 K, c, T# j( O        if( exsound_select & 0x04 ) {
4 x! F; V' t+ l0 |                if( addr >= 0x4040 && addr < 0x4100 ) {3 Z/ X  C! f' i; B$ q; I9 Z' M$ u
                        fds.SyncWrite( addr, data );
3 g! _/ ?# [2 D3 \8 C                }
* s9 M, y' q" _- Q. W7 e        }
% S! p! f- C# N$ A4 x
1 }. S6 h& r7 Z: u* _  K5 V        if( exsound_select & 0x08 ) {
" j0 Y) ]3 i! Q' ?                if( addr >= 0x5000 && addr <= 0x5015 ) {
$ Y2 L$ p, X8 e  H# L/ M2 {' B8 y                        mmc5.SyncWrite( addr, data );
. q3 K; G! E% P8 n; e4 ^" P: _% ~* w3 x                }( k/ d# x0 A0 u" x) p8 J( [! a& L
        }
: A2 q$ ~: ]$ E4 H9 g" E}
( }3 q* L6 {% N0 O; g" C. a% r+ G
void        APU::Sync()3 O% o: ^/ C/ n" i: t% W- M/ s4 N2 G
{8 l6 j, n1 R8 p+ K& Z
}$ V8 R8 h/ J( K0 S) s3 R' a% K4 e
% \5 P8 e- s1 p. t
void        APU::SyncDPCM( INT cycles )) U, o% o  i: e4 d# V
{3 ]0 k) c( n4 G; I3 D
        internal.Sync( cycles );+ r: ~0 s* j' Z: c7 K+ H7 m" O( @
0 `5 r! Y$ \; {
        if( exsound_select & 0x04 ) {
. w0 q4 w( ?' \; D; s, O2 f                fds.Sync( cycles );
( k0 x  q& ~+ k9 u        }
/ Y  @% \3 a* w' A/ |9 E$ Z; i        if( exsound_select & 0x08 ) {& F3 a" x; L. M2 z' V& j
                mmc5.Sync( cycles );
& B/ _4 I3 ^/ k5 O6 Y; K2 Z* n        }( J3 V& d, m/ o9 e% |! K1 K
}; _, O5 ?" |# Z6 x: z$ G

2 G  k8 F" [, p, q( p0 E0 Mvoid        APU::WriteProcess( WORD addr, BYTE data )3 L$ C3 E& w3 n2 Q5 h$ c4 u
{1 f: D8 E7 g# @1 E% S! Q
        // $4018偼VirtuaNES屌桳億乕僩, c! S# I  U/ A# N. [- \
        if( addr >= 0x4000 && addr <= 0x401F ) {
; y% O5 o4 Z2 F                internal.Write( addr, data );
3 `: Y% O* c7 w2 m        }2 A" e$ @5 V& w9 C9 ?% S
}
4 p* w1 X* Q" f! @3 j4 i% J) A* u' w; \% Q2 f/ ]
void        APU::WriteExProcess( WORD addr, BYTE data )  i. x5 u" \5 D
{0 @4 N: E1 T. k4 J4 W7 l$ I
        if( exsound_select & 0x01 ) {
7 x4 u% L7 i9 S; Q+ ]! _                vrc6.Write( addr, data );' g0 G5 O6 v  D" q$ j( U) Z
        }# U1 T8 z0 d+ G- @
        if( exsound_select & 0x02 ) {
9 Q: I9 q) i1 A0 {4 y                vrc7.Write( addr, data );
: B. K  m# a3 d9 H; `        }& z  D, P" H, ]; B
        if( exsound_select & 0x04 ) {7 L8 Q: t* y8 I# C! ?9 J
                fds.Write( addr, data );  p% r  x4 U& A) E) z
        }
+ j% S5 ^- l& _+ s        if( exsound_select & 0x08 ) {
; o3 X3 m6 W% U* F5 ]                mmc5.Write( addr, data );
/ k) D' m" p0 ^( N% A2 {        }
1 `. F  A# S9 Z/ r9 h# o# X        if( exsound_select & 0x10 ) {7 B6 `. l& b9 ?, X6 H- ]
                if( addr == 0x0000 ) {, O( T( P, I8 |; F9 J8 S; @
                        BYTE        dummy = n106.Read( addr );4 t" W7 C3 L/ u$ d; O& A( z
                } else {
8 j. f3 B% b7 C, L+ M, ^4 H1 w                        n106.Write( addr, data );
+ w6 R3 n" V0 |5 R                }  k1 d. N' Z. L3 J8 ^
        }
: _$ G% @/ a! |* g5 {        if( exsound_select & 0x20 ) {  ^5 d, `: {" i5 a( O
                fme7.Write( addr, data );, B) N; s8 i, O& I
        }
! _5 q# G2 u+ M: N3 \6 O" c% ^}1 a  D  u6 T3 [3 N% U

" T. ]2 t6 T9 W, p0 G& [void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )# k0 X$ _, H& _  `; ~" a: L+ C6 K
{) \. T, t% ^- v7 @8 O1 P4 q0 |
INT        nBits = Config.sound.nBits;
3 ]" @% J) L/ E" aDWORD        dwLength = dwSize / (nBits/8);
& }! Q- e% e0 a2 B1 BINT        output;+ d1 z, m8 u- y( i6 G0 g$ n1 A; G
QUEUEDATA q;0 d  a7 B5 v7 I, j
DWORD        writetime;
3 O$ A2 x! j/ r; B, W# U
; `  i7 l6 J1 W" x8 N% p3 {; f+ mLPSHORT        pSoundBuf = m_SoundBuffer;: Z" x' r0 ~. g1 Y
INT        nCcount = 0;
' m1 S* r: o- p" o; v4 \- g! G9 z3 D! ~" ^% J
INT        nFilterType = Config.sound.nFilterType;; y5 c0 ?$ r# @* @! O' \
; R' n! x$ i7 {5 d
        if( !Config.sound.bEnable ) {
3 [) n& [. v1 x7 Q. b  f6 n                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );% }9 I; o9 i7 F/ {& g
                return;
3 G8 g- E) J( w8 z4 N        }
) ]5 T5 [8 w! x* M: h6 S: v
8 ?5 l$ A; X( v        // Volume setup0 O' H9 H9 h3 G
        //  0:Master
1 k1 x) [  ^& ]# e  X; i        //  1:Rectangle 1' n+ @/ }# Y: h: o! M# ^
        //  2:Rectangle 2
* R8 Q9 o$ U; r% @% y8 k' q, V8 m        //  3:Triangle
1 ]: O& J8 b" V( O( X        //  4:Noise! _# }! X2 U2 @1 L$ C. L
        //  5:DPCM3 Q3 A2 u" e  O
        //  6:VRC60 J. K" V/ J+ B2 }( V% A' D
        //  7:VRC7
, }3 b+ u  r1 X6 A3 h3 C* Z$ h        //  8:FDS
1 Q8 G; K4 [; [* X7 U        //  9:MMC5
3 F( R5 R3 m/ y4 h( g! o2 v        // 10:N1065 [! G  W- b1 `2 n4 _
        // 11:FME7
7 H" f% p+ B: j; U. H! B        INT        vol[24];
2 V) S, u0 d* s6 F$ B5 d        BOOL*        bMute = m_bMute;
" `% X, v6 E0 p0 \* a3 p        SHORT*        nVolume = Config.sound.nVolume;3 |3 F3 g9 B& h

- W8 b: V2 D7 N6 R& o- @: p        INT        nMasterVolume = bMute[0]?nVolume[0]:0;4 C; Z6 p0 a7 J7 }% U) D
/ r  s3 D, L$ ?8 S* W4 R2 Y) l
        // Internal- r" l& k. [/ e: U" j
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;5 `0 M- l/ K+ g; X
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;% R$ {6 o% p) w, ^* W& J- {
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;% _: s7 ~* B* J" B
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
2 W3 Q8 a" o" G+ ^4 F( M        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;2 M2 X9 E% S( G% h4 @

0 W* F$ {& M- N) |$ E2 n        // VRC69 b/ y* X4 `+ U# n
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
/ t- s( d7 b. p0 u* ~% I- A        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;( P9 F9 [- A" `# T
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;7 B1 B# F* ]  ?. `# D0 r: R& f8 d
) x2 m  R) G+ c
        // VRC7. h3 A% J1 C" U( f9 j$ z
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
& \. V8 r: [0 _1 e# ~$ Z" m
$ U  H5 P% u1 Q' `; @0 U; `        // FDS1 k% X" l$ h! V
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
( D3 a1 [  I/ e2 Z. d2 d- i* E' H
9 ?4 }& b  {, R1 d7 i        // MMC5/ W5 m9 {8 @( i2 K1 V  }/ d2 y3 `
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;% C, s4 a, w8 ~
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;0 N* {7 B, L2 I
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;/ k% m$ h1 I- V8 F
, T8 ?% d+ \+ D6 `) [
        // N1062 v3 y6 b) ^6 \% m7 L% w9 S! q/ {
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
5 i& W( n8 Y( Y5 j        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
' o2 _, T% N, ~+ _& u        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: c8 s8 ]6 T5 o        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
) n  l/ \7 j: h$ V: B0 S. L        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;7 t& ~: m4 o; n$ D/ ?
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;0 `5 x7 R2 T/ f' H8 |
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, p7 h- J, C- A        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
1 {" d" y$ P3 b8 u! |$ J: M5 ], l& P0 B$ D
( H5 z4 H+ _! Z1 n5 |$ D- ^% V        // FME7
1 ~4 `# C# _+ G        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;3 @% V# J. h  u) b% ^3 c
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;; N* }3 B# Z/ ?7 ?
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;( l, N' i9 g4 U6 O5 A3 p7 U5 B8 F

/ H( G# w& O( S* B" ~: c% K( P//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;. K* ^3 A' r/ x' x
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
: u* y* x( E  B. t# Q
- G. @2 V* k% a* T        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
6 j6 B4 X3 Q2 b1 b: o# E. s' A        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
' A. w8 k' v. |" o  p                QueueFlush();
2 E9 r* H1 h+ }# H7 S( G  K        }
" y# m/ A8 ?. \, m, _' q, W, u  r  ]8 w! O/ E5 f. h
        while( dwLength-- ) {
: ]. e/ e% L; ?, U                writetime = (DWORD)elapsed_time;# h7 O+ k+ N9 P/ y

# n( Y# H1 l7 G" K                while( GetQueue( writetime, q ) ) {
! T1 d% k' V( f0 Z; ^+ N                        WriteProcess( q.addr, q.data );* G8 u$ a* m$ T1 b; r3 K
                }4 \/ O8 C4 Z" Y! ]* u0 F2 T

+ f  q$ M: T: x- Z                while( GetExQueue( writetime, q ) ) {8 O" R5 W0 A+ Z$ t  [1 G
                        WriteExProcess( q.addr, q.data );
# x# P2 P% T7 `/ }" D# A( @+ Y9 L4 i                }+ m6 v7 A# a; s. k) H* \: G6 i
1 u2 ^* [  J! |
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
8 \9 y! f* ~1 ]: g' b2 a  j! k                output = 0;
& q& n/ Q1 Y! }- c: ^' |- a# w# s2 m                output += internal.Process( 0 )*vol[0];
# h/ @7 P+ ]/ X. r                output += internal.Process( 1 )*vol[1];
' I0 C' W  D9 K  d5 R6 w+ o                output += internal.Process( 2 )*vol[2];
7 u, y* s! u8 ~4 f" N8 p" e                output += internal.Process( 3 )*vol[3];
  Y7 w2 C3 A! s) R5 v                output += internal.Process( 4 )*vol[4];3 N) z  @+ c; L# k' `

- r0 e& f( n* y. v! v$ T/ v                if( exsound_select & 0x01 ) {
( p* \) k# T4 X- t                        output += vrc6.Process( 0 )*vol[5];
6 A# U8 N. x9 o& v% F9 \; Q                        output += vrc6.Process( 1 )*vol[6];4 v9 U3 u$ P2 |; W
                        output += vrc6.Process( 2 )*vol[7];, S& A$ V" X5 E  I# i3 z0 v
                }
/ U; v+ E; j3 P                if( exsound_select & 0x02 ) {
$ k( n4 o7 P4 n: e                        output += vrc7.Process( 0 )*vol[8];
0 v6 Q8 [+ [& n3 X9 ?, I* I                }
* Z/ a5 M' ?/ _* M: r. n2 p                if( exsound_select & 0x04 ) {$ [4 K1 q# N6 V) Z5 A) `  v- b8 J9 S0 K) j
                        output += fds.Process( 0 )*vol[9];) p, W" |% e3 J% d
                }3 p1 h$ G8 [. S5 Z
                if( exsound_select & 0x08 ) {
: E: H/ ^9 S* a" X                        output += mmc5.Process( 0 )*vol[10];
5 F7 M: O- V: i2 ?; {# a8 q                        output += mmc5.Process( 1 )*vol[11];& |- B: t( u- L' \) @
                        output += mmc5.Process( 2 )*vol[12];
% b6 q7 z# L$ S4 u2 ^% D                }) K! i7 j- Y# `7 C/ I$ O3 G
                if( exsound_select & 0x10 ) {9 ], d/ h1 j% O: t( P
                        output += n106.Process( 0 )*vol[13];" X3 q/ X/ }. B
                        output += n106.Process( 1 )*vol[14];
/ r5 a  t) b+ ?) |8 P; k2 ?                        output += n106.Process( 2 )*vol[15];  X3 f1 S, G  Y  e" R- C; b, X
                        output += n106.Process( 3 )*vol[16];* u2 ^' k- R& U  `, e
                        output += n106.Process( 4 )*vol[17];
, Z( ]* m/ m' \. Z3 X: ~) Z                        output += n106.Process( 5 )*vol[18];, x; ?. W: r$ T; Y7 r/ `
                        output += n106.Process( 6 )*vol[19];
  X7 |1 a6 ?  C. z  e6 w9 U                        output += n106.Process( 7 )*vol[20];* s6 c$ f9 I' l+ \& N3 J! h
                }4 H0 \/ R: ~0 g$ s( x
                if( exsound_select & 0x20 ) {/ \/ z: U, u& T9 s
                        fme7.Process( 3 );        // Envelope & Noise& w/ Q9 U6 u9 P- }! A; F+ t( h
                        output += fme7.Process( 0 )*vol[21];
$ D& k$ o) e4 m                        output += fme7.Process( 1 )*vol[22];) ^' f7 ?! S' Y* p6 p$ _
                        output += fme7.Process( 2 )*vol[23];
: w. \2 g5 q7 j) N7 D* `                }2 [5 |$ t8 P7 k: q( F
0 ]& J/ ]3 ^$ H! k" u# q6 z5 R
                output >>= 8;
9 V& u. [. o3 S. u" B  t
1 M- ]3 D1 C. a- |4 Z6 @$ L                if( nFilterType == 1 ) {( m2 z1 x% E' f
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)9 v% _3 C$ Y! n3 I& j, H
                        output = (lowpass_filter[0]+output)/2;
& w( L( h* K* T8 M* I. g                        lowpass_filter[0] = output;! N. S5 Y2 ?+ V4 }: k3 ~( M& b
                } else if( nFilterType == 2 ) {
! |2 p2 t: e( ?7 f! v9 X4 N3 ~, N                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)& R- w, [' @3 E3 T5 T. A
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
8 @3 w1 b: B$ u# r* N9 K- P$ a                        lowpass_filter[1] = lowpass_filter[0];
+ p( d+ A! j2 g. r- G7 I  b                        lowpass_filter[0] = output;
( v  ?5 X" |! [% E                } else if( nFilterType == 3 ) {
, C% [) Z3 P* }9 B" H6 B                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
9 ~2 g% I. B& D$ @4 e                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
& c7 V0 C, N+ X( |2 b6 s                        lowpass_filter[2] = lowpass_filter[1];
( t) x1 B( y& w& R                        lowpass_filter[1] = lowpass_filter[0];- z. P, G' ]/ B9 H8 W
                        lowpass_filter[0] = output;( `+ Y' O4 T5 y( R' G" q5 U
                } else if( nFilterType == 4 ) {0 n' ]$ o# u# M( w+ a# d  _6 u
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
( J' w  s) Z" o. T                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
( \6 @* a; t, P4 S6 T                        lowpass_filter[1] = lowpass_filter[0];/ D* H/ }1 |7 H4 w/ e7 t) a
                        lowpass_filter[0] = output;
# `% a: A5 S' P# K' b3 Y                }2 U0 O1 i1 k! d. d7 a# |

: w$ a) g& n, N#if        0$ q! U2 O! M6 p& ^" Z; P
                // DC惉暘偺僇僢僩) Z$ a, G' o. D; s* w9 H. ?
                {8 e; `2 L( ~) r) \2 Q+ b
                static double ave = 0.0, max=0.0, min=0.0;& h# {. [# E1 u6 j2 Y
                double delta;
# j1 L/ e, x5 L                delta = (max-min)/32768.0;$ y1 Y+ G* Y7 b9 ~5 `
                max -= delta;
( K) H4 M  m' w" a                min += delta;
  L# Q1 e) y% v0 J                if( output > max ) max = output;
7 ]3 D# ^" n3 k" b5 ?6 [3 b9 J                if( output < min ) min = output;
+ W# f: X8 E* ]                ave -= ave/1024.0;$ T$ s- ?1 h+ q/ P* i
                ave += (max+min)/2048.0;
% F" H0 @3 ~; w% U- g/ M                output -= (INT)ave;
$ @: J; R$ d% J8 ~2 C) L                }
& U+ L! C4 R8 ^+ ~  n$ B#endif  Y2 v2 l; Y, x* E
#if        1
; i- Q% }1 e" K, p. w0 G                // DC惉暘偺僇僢僩(HPF TEST)
0 t( ?+ S3 B8 `' ?. O& Z                {
/ h/ w! T; f! P//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);% R0 S! p$ ~; t* k7 B! x6 o" g
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
# G& ?: }: g' E) G- h( G                double        cutoff = cutofftemp/(double)Config.sound.nRate;
+ o5 M9 `; ]* S/ \                static        double        tmp = 0.0;
+ Q' ~. R1 }' O. ]0 U                double        in, out;3 t6 w/ t9 [& S1 O9 P4 k- o

& K& q1 a) Z" y/ H% ]6 N  d$ [/ W6 b- h                in = (double)output;' o% N: F; O* h0 z
                out = (in - tmp);, E& u, }5 j  X# b
                tmp = tmp + cutoff * out;4 ^! ~8 I& h' h5 ~$ b) a4 h5 D4 Y
& f8 `" ]5 h" K$ k* V
                output = (INT)out;
0 K  L7 s; {$ p' T, z7 G                }7 X3 B2 r- b' z( M( K% ]
#endif
" Q0 L, F7 W; `2 U  H# [#if        0
  _7 `. N, r* s. u2 U, l" t                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST); R3 y$ @2 S! |8 r( z  K
                {
5 U7 \% h/ S4 q& g                INT        diff = abs(output-last_data);2 [) D9 }( ]9 v7 p4 y1 S0 Q
                if( diff > 0x4000 ) {4 S7 ^4 l5 B5 ?" {! L! N9 |# T
                        output /= 4;+ T1 R7 \) x3 T) Q' ^
                } else 5 H2 d4 ~6 x8 J9 F* F" \4 U! I' Z) Z& l
                if( diff > 0x3000 ) {
, B# C$ E1 B- }# i' C. p5 C6 X( c                        output /= 3;
. q6 P# E' @5 @, F                } else7 ]' s1 E. c3 x+ e1 C; s9 K7 w3 T
                if( diff > 0x2000 ) {# U$ g/ p) e5 V; {( d6 `( s5 P
                        output /= 2;
# ^" T: D9 d, U8 }                }
: ~) Y7 a( M2 a$ e; ^) m                last_data = output;
, E4 ~6 H1 S/ d# S$ y8 X                }
+ b, V) P$ J4 z! @3 g8 ]7 i6 E#endif
( s: O# c: o8 V                // Limit4 j1 O' q+ i1 a1 `  G* P
                if( output > 0x7FFF ) {& A0 @% @4 D8 o- Z" z
                        output = 0x7FFF;+ A% X% M# t/ X2 Y
                } else if( output < -0x8000 ) {& r' V; s( ?: i) U: D
                        output = -0x8000;
7 a5 A- {* E$ e! [; Q                }
6 f7 s9 {6 f$ T& |
8 _& e0 a, I/ E: C8 H5 T! `                if( nBits != 8 ) {( i5 T7 T8 G$ x8 v( L
                        *(SHORT*)lpBuffer = (SHORT)output;5 L  f, y0 r+ j* o- J
                        lpBuffer += sizeof(SHORT);
+ k% Y2 u7 R8 G4 V5 ]                } else {
; g5 f0 f0 I2 @; j8 F                        *lpBuffer++ = (output>>8)^0x80;8 {- M( q% w4 ~. ]! p5 g9 q& y1 m
                }
4 g5 t8 x$ f6 m5 y8 ?: r
  [4 j$ l+ z; E                if( nCcount < 0x0100 ), |; o: u: w$ i
                        pSoundBuf[nCcount++] = (SHORT)output;
6 c6 b; ~9 d: P$ s! I6 c
& r9 M' ~3 @6 T% l2 p+ F9 _- V//                elapsedtime += cycle_rate;
! Q, j( J  e2 [6 W! L$ F2 l7 K                elapsed_time += cycle_rate;
9 Z/ D) }  g6 I& |' v2 z" q        }- z! h7 O3 T+ F

9 o; y1 o; ?# X: j4 g0 v#if        1: @  _1 N3 _! E& r9 C4 m7 U
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {# V. H0 J% [' n9 X* z8 o
                elapsed_time = nes->cpu->GetTotalCycles();# L1 W- w3 I0 [$ ~) `0 f9 x& ~5 @
        }; S' {0 v5 U2 ]  E7 r3 S' A8 _
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {& o" V) I3 ^$ A! K& q( `, O+ s) E- l
                elapsed_time = nes->cpu->GetTotalCycles();& }# i3 ?3 E$ J4 `+ B" e) h4 x
        }
  z1 z# I# s2 }! b# s( R- ?#else
2 a6 \, l! j: J  s, m        elapsed_time = nes->cpu->GetTotalCycles();
+ K" g# Q( u8 G. @" L#endif  E9 w' ~) P5 m. I$ W: p
}
) G0 J  D4 V& {+ A8 K! x  ?+ }* a1 O& x7 g& K) `/ O
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)) S1 x6 N2 e* }8 }. f8 m, e
INT        APU::GetChannelFrequency( INT no )* d" }& G4 }8 L2 A
{
9 S9 W/ ?+ y* Y        if( !m_bMute[0] )" _% a! f/ q: z6 e6 M& @
                return        0;
& ^- S/ ?% `2 ]; u6 D2 g! N: t
6 n5 \3 I, B5 s0 c. J* n( Z0 j        // Internal6 E# \2 r. h& A0 t2 q2 k$ x
        if( no < 5 ) {3 b* L/ O  {- t, O- r
                return        m_bMute[no+1]?internal.GetFreq( no ):0;0 [" \% I8 r9 I0 E. ]) S
        }8 |# A% O1 s2 a5 G8 _+ o9 o
        // VRC6
8 a) c+ h5 I( `& F: K% |        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {( w8 ^$ x% I* m" A$ H3 ~4 b
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;" s1 l3 L8 D. d% q3 H! B! N: _, l
        }
4 ^( S* O4 \0 K* y: X1 w        // FDS
( T9 Q; I# _! W/ n/ Y! U        if( (exsound_select & 0x04) && no == 0x300 ) {# ]5 t  z$ K% `' i! k* b
                return        m_bMute[6]?fds.GetFreq( 0 ):0;$ S% J+ j; t+ {: t
        }
- T$ `% X/ S  \/ @: G1 f        // MMC5
) c7 z' ^  j  X. j        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
. V1 K, K% W$ |7 Y                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;/ M0 Z) c$ E' g# s& B1 ?
        }
/ Q6 s2 S" R+ I6 }. U$ P        // N106
# O) Z1 r/ N% N0 a2 a        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
1 G9 ~/ ]8 h, ?! l+ }4 s                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;* q5 e& W) S! b7 U2 E3 h
        }
% O0 w+ h1 F, V$ V2 ?9 }* ?        // FME7. g3 r  Y- }" ^3 h4 `" g5 U4 q) s
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
; `) v2 t" N) @                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;9 J, n. l& W8 M( L8 X
        }
( p% v* {' O% ^        // VRC7
! a+ z/ i5 e. x5 ^. X  f        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
# @+ P9 \- D$ s* n6 D. J2 n                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;& A0 L' ~1 [; g! J3 _3 d( J" P6 I1 w
        }
6 O2 e" K1 {9 O( y: E        return        0;
7 b7 ~$ ], h% m- t}
9 m! y  h1 _; E, G$ w
% g( ?1 M- R4 L+ ]8 J3 F  Z. \8 n6 w// State Save/Load
# U/ o1 J6 V  g1 Q0 d+ mvoid        APU::SaveState( LPBYTE p )5 g+ ]& b7 q* m0 Y7 \
{
9 O5 H. J% I# y#ifdef        _DEBUG. R8 x5 E0 _+ S5 J; P2 m& y% F( U
LPBYTE        pold = p;
, _3 H( u$ Y" b, J( G3 w/ s- T! S3 j#endif
* Z* I1 }8 `) ?5 ^; s5 Z
/ d- @! e7 v5 t& Z8 X* q1 Z0 E        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞9 |4 v. G, C( z) j( z# s4 H! d2 Y
        QueueFlush();6 W' S# h# i: q& m. C
8 P4 s! {  D. B3 f- H; H: n
        internal.SaveState( p );
8 T9 J# b0 I6 c7 F% \8 i        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
3 Q5 D& Q; R- O# x3 s& Y
" }# e* ]7 E: r8 f9 p, l* n# T        // VRC6
% i& n/ z  Y( a( J% |' \        if( exsound_select & 0x01 ) {3 _1 f+ S. H0 h" Z
                vrc6.SaveState( p );
9 U% ^- H2 M/ D1 e1 H. S                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding4 K, M! j$ G2 N3 A) k% Z& T* ~
        }
6 x$ P6 [5 I& _- p/ f5 R+ e        // VRC7 (not support)
) w  `0 \  [% A9 h# X3 }        if( exsound_select & 0x02 ) {+ `' p- {* y6 y( D4 M
                vrc7.SaveState( p );
! R5 |5 T; y5 \/ U" l# ?                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding2 V, T+ g- t( a# F* g, g
        }
9 v6 m" F+ j# ?  i- M% y) a! W. s- U& W. c        // FDS
( c2 O5 g! Z4 h/ f% @        if( exsound_select & 0x04 ) {
6 g% l: j- d8 y* r                fds.SaveState( p );
" I1 Y1 V) y  h8 p5 P# m5 L+ Z                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding- w3 e. L' O9 p4 K( J9 e3 _, u( J
        }2 M% O8 X# Y) c! V. M
        // MMC5
" K6 |5 r+ D/ o7 i# m% m+ p        if( exsound_select & 0x08 ) {. S  w* b& W7 s1 ]- R
                mmc5.SaveState( p );6 V+ V9 {' C  \4 N$ ~& y7 Y, k
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding: x+ F1 K7 X7 \  }/ H; m7 T
        }; b! i# q  p* x7 d! E( X
        // N1065 m& P: I4 |; Z; K
        if( exsound_select & 0x10 ) {
; N! c) l/ A; |) s% r/ d6 K$ [2 a                n106.SaveState( p );
; i- |3 K; x% d/ d' ^/ Q  q                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
) G6 z6 a0 Y3 \/ Z2 G: \        }" g/ _+ k% |! Q1 _- I
        // FME7
. y! ~' u& e4 ]) s        if( exsound_select & 0x20 ) {
; x8 G- P; m3 W; Q                fme7.SaveState( p );+ a$ h% ^3 I: V" z' T
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
/ m& M; F* d8 x4 W3 G$ L        }
( H# f. [- Y5 s* @) p8 N
, z' y4 }5 S. X# _. a#ifdef        _DEBUG* _: J& M7 \1 l9 x0 t. a
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
; Y! I* H) O- c#endif
9 m4 a( Z$ W9 p1 u  `}& E. s" s, R) T" w* x, \8 N4 s" ~
. S" j  G3 v, O3 r# B3 ]# a
void        APU::LoadState( LPBYTE p )" x! A6 R: y$ t6 c. I1 T' P
{
5 d% f5 S. i+ e6 X  F6 t6 ?4 b4 I( Z        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
% h3 U) ~- A+ D! U8 v$ I        QueueClear();
( C9 p% G, z, C! l- E1 y+ {1 a3 i+ O5 f  l8 f
        internal.LoadState( p );
% D4 h+ x$ y8 R/ Z! y$ m3 J        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
/ @5 a4 I" L7 q. C) l9 u; f2 b- c% }4 }1 D6 X. F. p! }5 y- Y
        // VRC6# F2 q" t) Z9 Z" i/ l! y$ L: b. t
        if( exsound_select & 0x01 ) {
4 u5 Q) _- K" Q% ~5 ^+ R                vrc6.LoadState( p );
. E1 G" ]) `1 _0 I  _                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
* b# ?) D% T( w5 R        }2 {) k/ {  M7 C7 }. x/ F4 F5 P2 [
        // VRC7 (not support)9 n( V" o1 V8 A& ^8 B7 I6 q
        if( exsound_select & 0x02 ) {
1 Z, [7 U6 `. n1 u. h0 x                vrc7.LoadState( p );
6 J/ ]& a! d9 L$ m* A                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding1 [2 k' e. V; |8 ]+ t
        }- a* Y3 I% K1 d# q# {
        // FDS' [: X0 B* o, [3 B$ w
        if( exsound_select & 0x04 ) {
" P0 ^+ I, y4 v/ p5 c8 o                fds.LoadState( p );
1 G. [3 S: M- f7 U                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
! n1 l  R* {# E        }9 x/ L9 p1 c% G, E9 L
        // MMC5. g5 _: s# {! U% v# F' d7 `* m) e; V
        if( exsound_select & 0x08 ) {  U9 Z/ a6 O1 K. W3 V) e. F/ {
                mmc5.LoadState( p );' e1 u, T+ o& ?& {
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
$ M# }8 x  g! C0 j5 X0 r* P        }& q& z- I% ]- z5 y
        // N1066 G, M& j7 F3 M8 U
        if( exsound_select & 0x10 ) {6 U6 H9 T0 E5 j: |2 N6 c
                n106.LoadState( p );! h; n6 o( |8 }
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding* D% r* T' u  ?" s
        }- }% {' i% E7 a
        // FME75 \# t- K) m$ W5 f
        if( exsound_select & 0x20 ) {' I' |( v4 x; I% F
                fme7.LoadState( p );8 d; h$ S5 \2 K; C6 W' }
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
4 |2 W' s$ B8 m' v/ C        }! Z9 K* e) _8 w3 P( F
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
2 n4 l" Q6 u3 N9 k- h+ P可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。) ^) U& E8 Z9 ~/ c1 _
感激不尽~~
  C  r8 Q1 r) H  N6 L) \
恩 我對模擬器不是很有研究,
* ~  u: i: X- o) [雖然要了解源碼內容,可能不是很困難,( _/ [' m; u) o3 w
不過還是要花時間,個人目前蠻忙碌的。
  y$ E6 ?/ e* j; M6 C) `" Y! O; o, k
給你一個朋友的MSN,你可以跟他討論看看,
& N. d! |; M. S/ t4 g. t他本身是程式設計師,也對FC模擬器很有興趣。# S' X% j: P$ p6 F4 d0 B3 Q- q: {

7 M9 i5 v, a5 A" Y& AMSN我就PM到你的信箱了。
- F* o1 k, j' r6 w/ s( v& d2 x) ?) V
1 T6 G, M  v2 \. @( E2 T! ?希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
9 [+ j2 i: O1 I呵…… 谢过团长大人~~
# Z! c9 [2 @! B2 A
2 b+ m+ m" v( P3 k) o  |  ?1 m
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
! r% ^0 |' o) C- w+ O团长的朋友都是神,那团长就是神的boss。
! S% j( g5 j4 B; I
哈 不敢當,我只是個平凡人,* ~8 p! e9 F5 s$ y% `/ @1 x$ A: e- O
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙, L) v: E5 L; c, @. I
ZYH
) U0 h4 D- k5 T0 a; \& k- UQQ:4147343066 Y* M1 e% W% p- l
Mail:zyh-01@126.com
+ ], g* S) v) o: u
4 [9 u1 ?; k' A3 ^他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 - e% @& L5 ^& v# n! N1 F6 X9 d
再次对团长大人和悠悠哥的无私帮助表示感谢~~

3 `5 o' K% @/ L0 ^% q不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-15 17:34 , Processed in 1.088867 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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