EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。/ P' n2 u# s- M) U  }
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~4 r9 W* i7 y% D' x+ m" [: q3 M
这里有相应的模拟器源码,就当送给大侠了~~
, C; E3 ~8 Q' I( v& V* Jhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
& I7 q" g* B; n6 u3 s能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
0 @; N; D% t: q: Q5 h/ r8 Z' g0 L楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~$ Y7 \3 H4 L( x6 l4 L7 Q# `8 H% p
这里有相应的模拟器源码,就当送给大侠 ...
; T0 q: C* [& ]  E5 J' j1 F$ U
聲音部分(Audoi Process Unit = APU):7 r. B+ }  q4 B
.\NES\APU.cpp& h1 U" B- K8 S
.\NES\APU.h
; X1 A. }: R1 t! Y
& K- r$ ]! K+ b! l1 G
2 J. G# ]& D7 L" r& D影像處理部份(Picture Processing Unit = PPU):
5 m- t4 w/ M( v3 E.\NES\PPU.cpp
2 d) d) D6 n) k7 |3 Z5 L- b.\NES\PPU.h, D2 @5 D1 U4 P3 @

7 O  W: g% y! f9 ?如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:# h, R3 u# B! X
(由于很多专用术语和算法机理都不明白,所以看不大懂……)' t) b6 }4 L% z8 ?3 }9 n9 P
//////////////////////////////////////////////////////////////////////////; [' a6 `, D2 ]( G; G
//                                                                      //
; ~9 {$ ~' a' e5 w//      NES APU core                                                    //0 D; u% S# }6 s' c6 I- R7 m
//                                                           Norix      //% u) I3 M  @# N( y7 n. L' E+ P+ X
//                                               written     2002/06/27 //8 K* I8 `& n5 H  P
//                                               last modify ----/--/-- //
' i( V& W- y1 s9 Q" |, V* q# {' x6 Z//////////////////////////////////////////////////////////////////////////! B" n5 v  b1 {! @5 v. q
#include "DebugOut.h"/ s4 k) Z) n$ ?2 K$ ^
#include "App.h"
( @; I' l0 k( X& [#include "Config.h"1 K& d  K6 m! b5 [: y% s; j5 M

5 w9 z6 [8 L& g6 y3 _6 u$ |* F#include "nes.h"* ^8 Q3 T' Y/ _1 ]$ x
#include "mmu.h"( B( c) N1 Q& w# S
#include "cpu.h"3 ~' Q2 s& c" M3 K( r
#include "ppu.h"
4 x* s# ?; _$ j  v- t#include "rom.h"
+ Y6 @# a, i) w+ ~#include "apu.h"
5 _5 O1 j/ Z2 D
- }# z3 T( X# c9 {9 z# f// Volume adjust
" a" Z9 b3 ^! s# N4 G// Internal sounds: D! D' t. i* l+ q" I
#define        RECTANGLE_VOL        (0x0F0)# x, E- {+ B$ Y
#define        TRIANGLE_VOL        (0x130)
. d8 q% l8 l7 b, s7 Z* y#define        NOISE_VOL        (0x0C0)
* x4 C' Y% S$ N1 S8 j#define        DPCM_VOL        (0x0F0); }6 M& P+ s0 V1 n' _
// Extra sounds7 }9 x: R, c" L! l! }
#define        VRC6_VOL        (0x0F0)
7 t/ B( q6 Z3 c) s; {#define        VRC7_VOL        (0x130); G# N6 W9 v& W$ K# e+ H, P
#define        FDS_VOL                (0x0F0)# N0 ^# c- _2 ^( s
#define        MMC5_VOL        (0x0F0)! O$ w5 I1 u% f- \* o. w: h9 h
#define        N106_VOL        (0x088); [) u" {! `. Q
#define        FME7_VOL        (0x130)
/ F" C* _4 |) c* X% Y* i+ O
; w: j! P; U4 u, I) G7 ?+ A0 _: pAPU::APU( NES* parent )  i! g& k$ r; r& r  F( H
{4 G) A, D8 r6 m8 f" y; W, `
        exsound_select = 0;' f2 f+ _# d  x* d" x, X8 ?
% R2 D0 t+ w2 n! [' Z9 C8 p' F
        nes = parent;+ \3 d6 x8 `/ ^8 J
        internal.SetParent( parent );1 [+ Y/ l  ?: \* ]

+ C1 X: b( o+ E- L        last_data = last_diff = 0;
; f- p* g/ P/ d8 V4 {6 z+ Q
$ {6 }+ |! [0 H        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
* Z! T% T* O3 _2 C1 w- I' ~  ~8 D$ L$ g. e" A# v; ]
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );/ d* _$ r3 {6 M5 u% G2 I7 l
        ZEROMEMORY( &queue, sizeof(queue) );
9 N$ m7 S) D, q, z4 R- |        ZEROMEMORY( &exqueue, sizeof(exqueue) );
" R/ ?* q; ~$ s" V5 V% O$ v! [) Q6 ?! T
        for( INT i = 0; i < 16; i++ ) {; U( a" s; j4 B; {& U2 }) p3 n
                m_bMute = TRUE;5 k* [) d/ O$ S9 L: v
        }
) Y' q9 C! ]5 y. A# u: P$ n8 j}/ {3 L4 T1 p: O2 d
3 T( K: R, P2 @+ Q$ z! D5 @
APU::~APU()" F# D0 D! a* m5 ]2 H+ k  r7 x
{
! W* i! C. C0 A}1 W  {- @* f. r, }- r
: l! s" E, t* p% k3 r* h, D) R
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )+ e* ?/ e* C1 U  `
{1 J* E! R5 |4 C" U$ ^4 {
        queue.data[queue.wrptr].time = writetime;
8 G2 V- B  F; [+ c  s- B/ z3 Y        queue.data[queue.wrptr].addr = addr;
6 r" N2 H$ y& m5 b: h9 T/ Q        queue.data[queue.wrptr].data = data;
/ Y3 m5 D* }! @- G        queue.wrptr++;8 ?: n+ @# R- p3 u# s
        queue.wrptr&=QUEUE_LENGTH-1;5 T2 g* B3 W' G$ H
        if( queue.wrptr == queue.rdptr ) {
( q$ v# n( r( D5 v; _                DEBUGOUT( "queue overflow.\n" );
* {' L; `* X  v* E4 }        }
7 j8 ^6 ~; v5 J% v7 P3 C6 t}
4 d1 L7 O; t4 w6 N; r
' p# A+ z; W* P1 UBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
1 C8 U5 T% O# D# w2 k, j7 h* [$ z, ^{
* O2 z0 b  O7 o' z- }$ Q% P1 [        if( queue.wrptr == queue.rdptr ) {: I- u9 d1 E! r9 \! A
                return        FALSE;
% {4 i2 S& T$ g9 L( l3 W3 {! H        }
, b" u. J; m, u/ q( O. V) Q        if( queue.data[queue.rdptr].time <= writetime ) {
" E8 A7 J3 w! S                ret = queue.data[queue.rdptr];' R. `) X3 q* i4 O4 ]
                queue.rdptr++;# u0 B, `# n8 h" B2 J
                queue.rdptr&=QUEUE_LENGTH-1;
& i% P0 L1 I/ g                return        TRUE;
  r/ n! F( ]  O" O: [: p        }
/ W7 g$ n% N9 k7 p: r' F. D( r' q! L        return        FALSE;
2 _, q2 W- X" z; U3 a. G  ^}
$ v% o# F/ z) \8 f" j3 S# a
, e7 Q% W. c! c4 g; avoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
! `4 {* F" {2 y0 ~. Y{: V& ~% |" U; E/ [5 L
        exqueue.data[exqueue.wrptr].time = writetime;
3 V' O, e0 Z& Y! m( {4 Y0 }        exqueue.data[exqueue.wrptr].addr = addr;
, T6 l" v6 i) y8 v0 ]) X        exqueue.data[exqueue.wrptr].data = data;
; N, M5 W$ t2 X. y2 f4 W2 y        exqueue.wrptr++;2 M& I* ~% p% L+ J( s1 w7 _0 y
        exqueue.wrptr&=QUEUE_LENGTH-1;
! c8 t, N& @# X: J* V5 a; d        if( exqueue.wrptr == exqueue.rdptr ) {
( S* O3 H- Y: h; j( g, H, o6 x$ U- i' {8 f                DEBUGOUT( "exqueue overflow.\n" );
: G, h2 u8 W- z! Z. t5 w% P        }# X! v$ `/ d& `" e# |4 M1 g1 n
}5 U" ]. ]0 L$ X8 e0 c5 y
* l5 r7 m/ I. L; F
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
" y7 p7 z+ J, g+ `/ E6 Z+ p{
+ Q  j' B2 U' i) M/ U        if( exqueue.wrptr == exqueue.rdptr ) {/ v' c" A0 [9 {8 ]6 n1 K
                return        FALSE;$ V4 N& h3 i, ~, L+ J
        }
0 L5 q4 j! j# Z+ x* @& B        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
4 d9 n( Y$ Q/ j4 z& E8 t; a, H                ret = exqueue.data[exqueue.rdptr];
  ]7 D; u7 J6 L1 _( I. f                exqueue.rdptr++;& j) }; {0 Z! r0 k
                exqueue.rdptr&=QUEUE_LENGTH-1;/ M6 W3 @0 @6 I/ o' B8 \, X
                return        TRUE;: d1 k  l; S8 i( ]
        }! ^; e8 u2 A; _, s- }- i' b
        return        FALSE;
4 e' o9 v6 S# S) b) t4 K1 e}
" O& W; f! o. G$ s. ?# N
1 H/ b2 I3 m$ \2 Xvoid        APU::QueueClear()9 s1 b7 J" k* R4 ~/ e4 }# m
{
" |! q+ Q1 l' I7 v        ZEROMEMORY( &queue, sizeof(queue) );
% n5 z( x2 ?3 t- _' G) @* z        ZEROMEMORY( &exqueue, sizeof(exqueue) );
# c- X+ g: N; e  ~. [1 ]5 W* Z2 Q* h}6 H& n2 v+ i- p8 e! K6 q$ W/ c

% C- P0 Q7 s, Ivoid        APU::QueueFlush()' e& `2 Z5 k6 _) Y
{
( W& N5 Q) a! }! m' `+ X' V        while( queue.wrptr != queue.rdptr ) {
/ t$ m+ ?9 p0 c  I( T1 M                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
3 x  @; R# Q$ {) T: A% e' h6 s                queue.rdptr++;. p( q* t% i) R9 ~
                queue.rdptr&=QUEUE_LENGTH-1;
! Q# @$ o% W2 H: ?        }' |. A# n) ?% m0 O7 S
2 }3 \8 E: @" e1 j% J' L
        while( exqueue.wrptr != exqueue.rdptr ) {
7 }0 f" W6 @5 q$ A                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );" o, d, U- ~9 P0 Q8 h- S
                exqueue.rdptr++;
- G' _4 o+ K% ~# L  e" a3 x9 n                exqueue.rdptr&=QUEUE_LENGTH-1;
! |. f& I1 N2 J+ C1 X        }
& P0 f+ [# s& V* z1 [# Z}
% k2 p- A! M/ E
) C9 O1 H" F* Y' {" ovoid        APU::SoundSetup()9 x0 U- b4 e4 |! e3 h
{
9 G! ~7 E4 L+ n* e1 c1 }        FLOAT        fClock = nes->nescfg->CpuClock;
5 f; C7 p% @- f8 {- l8 K9 i        INT        nRate = (INT)Config.sound.nRate;9 m2 A3 m* l: h: B, T% U
        internal.Setup( fClock, nRate );; \0 p+ c) o/ F
        vrc6.Setup( fClock, nRate );
7 h6 l3 ]9 u) E& P- v/ O3 g% m) \        vrc7.Setup( fClock, nRate );/ V6 O4 I! ]' f/ u
        mmc5.Setup( fClock, nRate );6 u' G# U% `- T; H9 A' k; w1 ?2 D/ ]
        fds.Setup ( fClock, nRate );) ?3 V1 C, a# B( Y
        n106.Setup( fClock, nRate );* [0 k5 R8 j! v( }5 P' S. o- M9 w2 a
        fme7.Setup( fClock, nRate );+ ]* X1 r/ Z7 s/ j
}
+ O5 B% d. G; F) ]9 q
/ t' F3 J, X/ z: K1 b1 a  S" hvoid        APU::Reset()
  S2 Y" f; W$ G3 f4 G{! H/ Q) I7 y  [( c$ F% P4 B
        ZEROMEMORY( &queue, sizeof(queue) );" S" K* m, d1 r( @
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
& ]# |' w2 U; L& d% H% M# L
  K: y9 l5 t8 I6 X" c( s9 G0 |- M        elapsed_time = 0;
% y. Y, w" e4 A' U/ Y2 S" J! ?
0 m# D$ l( r1 Q4 C; T- k        FLOAT        fClock = nes->nescfg->CpuClock;
% V* W% z: [5 _5 u) e1 w        INT        nRate = (INT)Config.sound.nRate;6 V2 d; T( Q, Z. b* X
        internal.Reset( fClock, nRate );
3 p/ |; U9 b, t8 j3 |5 X! }9 s        vrc6.Reset( fClock, nRate );4 \* S+ X1 d) ]
        vrc7.Reset( fClock, nRate );. I+ r! }2 j& i8 B  b; l: a% i3 a
        mmc5.Reset( fClock, nRate );" \2 S4 V9 v1 |" {
        fds.Reset ( fClock, nRate );. S$ X! Q* e: L& H, S" Y: k
        n106.Reset( fClock, nRate );
9 c) x' y9 v* \, K5 ]        fme7.Reset( fClock, nRate );
! @7 ~1 C; c* d, r, z
8 H! c# {: f$ c0 }, p  s! I5 N5 M        SoundSetup();9 h+ T* |5 ~' Z& @0 Z& m
}3 e* N. B' L$ B' O+ g: Y, V8 f8 x# Y- }
+ W( B2 z. l3 E
void        APU::SelectExSound( BYTE data )0 ]5 X9 I) |5 S1 p
{
0 d+ W0 ^0 ^, e6 d, m6 Z0 n4 x        exsound_select = data;
% h+ t  A0 t/ @' d3 j8 U  b) Z}
$ J' `5 e6 m' j: U6 M2 L8 s4 u) W; [+ {
BYTE        APU::Read( WORD addr )
+ t/ F7 W& X4 I" A{
% y* }9 l$ Q, \) z8 c# ~% B! O        return        internal.SyncRead( addr );
; {: l3 ~" G4 N}
, T& L( E7 M' d5 g  i$ X( f( j7 _9 X% i9 N" M
void        APU::Write( WORD addr, BYTE data ); R! A" M6 h( }9 ?  M& G
{
# k2 ~+ z( v$ ~        // $4018偼VirtuaNES屌桳億乕僩
% f8 m  I1 D2 B        if( addr >= 0x4000 && addr <= 0x401F ) {
0 m- w5 n2 P* i8 t6 i                internal.SyncWrite( addr, data );+ [+ A2 a" f3 G2 {
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
8 C- w9 l& M, V- K, b4 Z        }) F% C- P' P: g0 F
}
# R$ ]; S  Y1 J& ~- |& D0 ?: u1 i, S3 O1 J
BYTE        APU::ExRead( WORD addr )
8 F, c4 R9 |4 @$ |* U{
& q0 I9 n3 Q# k8 H! i; tBYTE        data = 0;
( f, j& ^  s) ]. M! b0 a* D: d9 D! c6 R9 ^; O
        if( exsound_select & 0x10 ) {
" Y) }3 O6 Q; m3 \) |                if( addr == 0x4800 ) {# P8 X' I8 B* S
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
! T0 ~/ O. g+ T) [& C. v                }5 m7 o' J% s. M$ t# k( Q' K
        }
$ |$ K9 B) j. B( v( P' H' r        if( exsound_select & 0x04 ) {
  \6 o% u) c! S$ ]5 q                if( addr >= 0x4040 && addr < 0x4100 ) {5 z+ P7 b- s; W. z. {) ?; p
                        data = fds.SyncRead( addr );  g9 |6 f" y& T# N  p, a8 o& q
                }
$ l3 ^( q- x# `' i0 f        }
' N, o. Q) p/ T, S        if( exsound_select & 0x08 ) {
# S- d1 j$ O1 r4 i0 @                if( addr >= 0x5000 && addr <= 0x5015 ) {
) ^6 }, |$ b3 S3 x+ i( ~                        data = mmc5.SyncRead( addr );# N) c) V  T+ ]' Q* o  u& `
                }
* V# R. N1 o' ]5 k8 L% O. x, }7 {        }
* E6 q& W) O$ j$ Z" f! z0 o: G% _
( I! J* {8 h! J* G        return        data;
8 W- S5 R1 @: @: K/ p2 {0 Y}
! Y% P9 c9 p1 R; [! k& n- A, P4 U) z/ C$ K  V1 m: X" a) ?
void        APU::ExWrite( WORD addr, BYTE data )
. D- _: r4 ~9 o2 t' h, W{$ Z1 X5 v9 f) X
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );- a! N: P# M7 ?5 w. }
; E& C; a% C- O. Q2 L
        if( exsound_select & 0x04 ) {
" Z0 x; F$ y+ K% \& Z. {                if( addr >= 0x4040 && addr < 0x4100 ) {1 g( O( N* l3 u/ b
                        fds.SyncWrite( addr, data );
2 J- X3 B) a  `/ k; W7 F* v# G                }
& c7 T; \5 u6 ^. |        }
# s9 Y+ m4 S! I/ I- s) R5 D3 d9 ?; r, r
        if( exsound_select & 0x08 ) {9 h6 i: o' B. w1 o
                if( addr >= 0x5000 && addr <= 0x5015 ) {
' t  I9 V. R6 n                        mmc5.SyncWrite( addr, data );
( _' ^5 |7 {- f8 b                }
& F5 |2 N( O* V" {# Y3 Y8 d7 ^        }/ r/ o; j0 U; M0 l: c5 e* P
}
6 M9 X! v$ e1 d& G% f* d. {) |
0 G* z+ c1 \5 S, Y, s" lvoid        APU::Sync()5 B  M; F# n6 l" r9 W# b
{
- U' a" g+ T) v/ s9 [}( I, k3 ~$ l) P1 r  @! H7 m

" r, m! v! ]& W. G7 bvoid        APU::SyncDPCM( INT cycles )/ E( a) p& b& v; W  T2 w
{: a- Y2 d8 X8 {9 l) e* M
        internal.Sync( cycles );
6 T. h6 D% J  V7 a
* ^; ?: |1 |8 r7 g        if( exsound_select & 0x04 ) {9 G$ y( \8 q$ f" U& m
                fds.Sync( cycles );
9 x; `! v. v/ k# o! g        }; H9 s& j1 o; u& m& m
        if( exsound_select & 0x08 ) {
" Z0 E! `2 z! M5 {" w  F3 T% g                mmc5.Sync( cycles );% Z# h/ R% J" G3 W$ h
        }
' d; D+ z- c* ?& L}
; X) ?0 ]4 ^2 |; \. r& Q  E  I- B8 j5 s+ x5 j
void        APU::WriteProcess( WORD addr, BYTE data )* ]0 M6 C$ [; w. I1 D, x
{; A3 f3 D% S6 K. Y6 h3 D9 X
        // $4018偼VirtuaNES屌桳億乕僩
! D8 d% `+ t: k7 B0 p/ o* R- H        if( addr >= 0x4000 && addr <= 0x401F ) {
, k( ]2 f4 X3 x' X* ]                internal.Write( addr, data );' E0 j- i* B$ O  ^: q1 T
        }/ m, [! y1 Q4 p4 o/ A( Z8 G2 ~; g9 g
}
) x+ w8 r$ C4 t% F& Z6 z# {* B8 ~9 l& M5 i" Q. ?0 P7 p0 K9 \, a% J3 D
void        APU::WriteExProcess( WORD addr, BYTE data )
; ]/ {6 U0 D/ b* ]{! K+ z# K9 p$ H$ a
        if( exsound_select & 0x01 ) {
6 J# B1 q4 z1 b5 y1 ^% }                vrc6.Write( addr, data );
1 A4 j5 g1 w" _        }
; l. l6 U5 K5 s        if( exsound_select & 0x02 ) {
1 ]( q3 a- m: s8 X, l  t7 Z                vrc7.Write( addr, data );
' F$ |; I4 L6 p# N& X9 q        }& J" z* x& i; ~$ x) v
        if( exsound_select & 0x04 ) {1 Q( o' y) O9 u+ H4 Z7 O
                fds.Write( addr, data );
  o" C5 b5 X/ U- q6 b) ]- S$ W        }5 h, Y# O5 a+ u" r0 d& s( B
        if( exsound_select & 0x08 ) {! _; z* v6 }- D  b& l+ A  z( {
                mmc5.Write( addr, data );: b0 b# I/ \& Z6 f; {
        }$ e, P; \2 ?! I7 S% Z- ]+ P; Z3 b
        if( exsound_select & 0x10 ) {
" ~6 _0 C8 G5 Z/ E! u- Q; z' k                if( addr == 0x0000 ) {
* P! A$ c  B" p! |3 F7 F+ E                        BYTE        dummy = n106.Read( addr );# @: v, k  R  E0 r
                } else {+ q8 ~9 L) x# ^: Z0 \
                        n106.Write( addr, data );1 O' M/ J! g. a
                }
; K6 s5 F7 ^% z, l( P* m# n        }2 \( k% N! @: N+ H- `8 P
        if( exsound_select & 0x20 ) {& S; y. l' k" I6 z- k6 E3 f1 t
                fme7.Write( addr, data );
) |$ w/ g# k! ]        }. k' K, b" z0 o; h. @
}
; O1 f# T, `8 h# p) s) o, m, `# `& p4 f& K1 O
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )7 j+ s  A3 r9 Z
{
( G+ I5 R) u) `3 D  LINT        nBits = Config.sound.nBits;: e3 ^; E+ t  ]* n, K
DWORD        dwLength = dwSize / (nBits/8);
* ^9 X% Z$ f/ t5 a' XINT        output;
* N) ]: K. N' UQUEUEDATA q;
* p: S" I) {  G0 L/ pDWORD        writetime;, N. p8 Z" N8 Q

4 d6 W- N4 Z) D' E( LLPSHORT        pSoundBuf = m_SoundBuffer;+ X) v( M5 U% n
INT        nCcount = 0;
; J% X  l7 b# O6 d( c! @; A+ V, K% Y' i  g' S7 {. {
INT        nFilterType = Config.sound.nFilterType;
+ c7 T% r  V' V; z" L; V. P% \( L: E0 g% [- ^
        if( !Config.sound.bEnable ) {0 B2 ~& L; g* j' H$ e
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );  p. B  T7 s+ D. q
                return;. N5 H6 V0 p% N" v, J6 o
        }
+ f  z/ P. G; G/ W# L* ^" r' B/ R- m9 f; B
        // Volume setup
# L+ Q1 }4 U2 Y! w' x        //  0:Master1 e# j" q9 N0 U/ w6 J2 Z
        //  1:Rectangle 1
7 A/ N- j8 s, }5 G( u# \        //  2:Rectangle 2
: A, y% A- d- S6 |+ R        //  3:Triangle
( c7 T1 X9 g2 X        //  4:Noise1 A! I. {* K1 T& y8 x0 K
        //  5:DPCM# D+ F4 c4 [7 n1 R/ P
        //  6:VRC6
# i; `* \( U  `        //  7:VRC7
% L# h3 x0 C  `        //  8:FDS
* S2 m+ y1 j  x5 t# _        //  9:MMC5
2 \! `; l( l9 R- O# T        // 10:N106
9 y( T( ~4 a& ]' _) e; M  `        // 11:FME7  h8 D2 I- ]8 C' W" }# `& h" t
        INT        vol[24];
0 |1 j2 p6 x! Q/ [        BOOL*        bMute = m_bMute;
* ]6 d. \+ t1 O. V        SHORT*        nVolume = Config.sound.nVolume;
3 D2 N$ M- H, P) P1 H6 _& k/ _# {7 K
5 W$ K. s# n$ ]7 m& Z' `4 I  u        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
* D  ]$ K( s/ U8 |- O# E& X9 m
" {3 t/ f$ {+ n) x/ D        // Internal4 p& [. S" i2 c% L# ?" X& }/ R% W
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
% R9 J! l& w6 _  w        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
: |* g2 {  b! _' w& C        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;+ ]- B4 m+ Y, j, [
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
: Z2 {- B  B) F+ ~0 Z        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;- V4 l: g3 |6 b7 w' w: B0 Q
) B& c- ]4 t0 c2 C- M
        // VRC6. {2 G% F* k/ J' c) B0 x; I
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;* Z: f& g: h) Z. \& Y8 x
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
$ z1 y0 O; e( D$ S, f2 d& A. K8 e        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;9 b5 @3 L% F$ ]7 G$ G" b5 V
' l) ?* m$ z, m5 X7 ^
        // VRC7
4 g9 a1 y: m. s7 _  \5 q        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;1 U  C: b5 V' H/ v" V
! w6 Z6 K8 e" ?6 B( O* Y0 l
        // FDS. Q; `+ T( W; v1 y4 P
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;4 a; _( B! y; c$ ^. @' K* q: ?

' q, @" {* w- _# k/ d( P0 Z        // MMC5
% F5 |/ s" b1 i) o$ w8 }8 W: \        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
* {% L6 A9 T, H. j        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
: b3 f0 A/ W% N6 D        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
% e$ {3 v" y2 _) V
; [) ?$ J5 e+ H( p8 s        // N106' S8 X8 L5 R5 a0 R% @% O8 S6 P
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;( }* g& t8 Z6 a' c4 {
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
/ W& i3 p" l; T. O- @1 Z; q) `. j        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
3 A3 l4 M" V1 }, V+ d7 c        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;5 F9 R9 P: e( U& D- p' I
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: L6 q; w/ d* q' N$ q' o        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 b9 r2 r+ O+ T4 e6 `2 Y$ M6 N
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
* w  J& P1 ~; c) M2 j) q5 z        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;) e8 k6 C9 m& y5 j5 }9 O6 m4 H5 @
+ w  P5 Z! a6 o5 `
        // FME7
! \' v" |. c6 |( Z1 X- b% }' m        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
7 Y1 I* J; U7 K* k- o7 j        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;+ T8 {7 }+ K& Q( |
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;& I9 m  W9 P( l+ W) U. m0 ]- Y  P: Q

2 _( M/ t- F  N+ B4 o1 H//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;7 o$ Q* o0 h- b, f! n( W6 p
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;7 {1 `" k5 l- H. I) A) C

' [& P, K! b) F: p        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
' a. J0 V) _+ m        if( elapsed_time > nes->cpu->GetTotalCycles() ) {: D8 i2 j6 s  T  _7 f
                QueueFlush();- r1 P3 z( K' L; b0 d# M
        }
% _" S8 w. f$ S% ^$ f9 C) p1 Z
4 N. z1 T/ m; b1 T: Z        while( dwLength-- ) {0 s- `/ t# }) q$ o9 b' L' A
                writetime = (DWORD)elapsed_time;8 I/ q( g8 H/ x' z& r9 {

" o  O& d4 d$ F8 }! d( x                while( GetQueue( writetime, q ) ) {+ f/ F4 p% Y! Y) J# q6 u4 c
                        WriteProcess( q.addr, q.data );
+ d( X0 s5 G  V" V8 ]8 E4 X) F" I                }
7 A2 Q2 f0 w7 D8 J. n  j4 o8 l* Z) F- Z- N+ [
                while( GetExQueue( writetime, q ) ) {
8 x- V! ?% Q& q8 D: Y- J  E  d* _                        WriteExProcess( q.addr, q.data );
# x  ~/ B2 w/ ^  H0 y' l) u                }( @6 X9 d. ?2 L5 M# `9 E, V9 O

  H+ \: g2 R# E2 m" P" q" M                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
5 Y0 k9 c) a7 }( n5 G  ?. U                output = 0;
+ y9 Y/ A& K" x( [                output += internal.Process( 0 )*vol[0];
( m" H) A' R7 _7 [7 q) `6 v                output += internal.Process( 1 )*vol[1];
8 a$ N. y- ^5 F3 H1 X                output += internal.Process( 2 )*vol[2];
. l$ y8 x, S: ?# F1 {0 F. O% i                output += internal.Process( 3 )*vol[3];
8 D. `6 X% e1 I& K                output += internal.Process( 4 )*vol[4];
: v) H4 c- D: ^/ q5 K
  ^1 n+ Z: r6 O* U$ Q. C                if( exsound_select & 0x01 ) {
. E# @: r  ~. H                        output += vrc6.Process( 0 )*vol[5];6 g6 n6 K2 z& i2 M8 l: e/ {4 A
                        output += vrc6.Process( 1 )*vol[6];8 C4 s3 E9 V! M% ?7 r  ]+ V
                        output += vrc6.Process( 2 )*vol[7];6 I) I/ e7 M: p+ c
                }  m2 i: G: g: o" u- R
                if( exsound_select & 0x02 ) {
/ Y# P  G- }- a- K                        output += vrc7.Process( 0 )*vol[8];4 Y- |2 \( @8 _) w, j- o9 F
                }
  i7 a+ `2 s& f( ^1 v1 x" S: H                if( exsound_select & 0x04 ) {
0 Q& M& m& r2 j. K- m  g; d. T                        output += fds.Process( 0 )*vol[9];
3 F# d! i) o3 X                }
; P" K  E" a  Y  K$ B$ Y# M1 G, o6 o) S: m                if( exsound_select & 0x08 ) {
0 c8 H" _  b5 |, D3 U                        output += mmc5.Process( 0 )*vol[10];
1 |) M/ M. v7 J$ g! x0 s                        output += mmc5.Process( 1 )*vol[11];' u- W) Z2 O' S) J8 w( C, u) }
                        output += mmc5.Process( 2 )*vol[12];6 Z- t" n, Q' `5 p( }2 W1 @
                }( V. c/ \5 O. [4 n
                if( exsound_select & 0x10 ) {4 q* ~% ?( Q! w# [& f: g
                        output += n106.Process( 0 )*vol[13];
1 B3 G% S# {( f                        output += n106.Process( 1 )*vol[14];$ P7 L: M/ c% u! F6 f
                        output += n106.Process( 2 )*vol[15];
5 @+ E% r) A2 O                        output += n106.Process( 3 )*vol[16];
0 Q9 B5 B; [4 `! {1 {- ]                        output += n106.Process( 4 )*vol[17];
9 h+ [% R/ O/ m. u8 c                        output += n106.Process( 5 )*vol[18];
# @8 v; _0 R: x% s; J$ b) H& b) _                        output += n106.Process( 6 )*vol[19];9 Z- `  G/ z# x+ G; i  ]
                        output += n106.Process( 7 )*vol[20];0 T* e- H, V, M
                }
3 R% `8 c( ~7 K8 v9 D3 o                if( exsound_select & 0x20 ) {
, B* H/ T5 s) j  X& h5 T/ b% w                        fme7.Process( 3 );        // Envelope & Noise
& a7 C# {$ V4 I' h7 Y. e                        output += fme7.Process( 0 )*vol[21];
! s3 K* s: @3 M$ A& x* h, G: K                        output += fme7.Process( 1 )*vol[22];
: q; z0 \6 K6 v+ S( x$ [. A                        output += fme7.Process( 2 )*vol[23];, @- L: S7 W+ ]  X; g
                }# x! k# g: I( i$ \% O2 K: \

2 N# R$ A+ H) p                output >>= 8;
( {) H- C% p( Y) }/ h$ E5 P! p- P$ Z% Q7 ]7 e& x- }" r! D
                if( nFilterType == 1 ) {3 o, \/ z( g9 l
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
: y" W: y8 B7 J, f6 R( P                        output = (lowpass_filter[0]+output)/2;; K& o! U6 k5 y
                        lowpass_filter[0] = output;9 y/ ^; E- M1 e; ?
                } else if( nFilterType == 2 ) {! |! p% {0 w) v* ^
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
3 o2 j+ S0 j- U5 w% d% J1 l: Y                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;3 A* z6 Y: ^% `, X
                        lowpass_filter[1] = lowpass_filter[0];9 J# {3 h0 n4 |" g4 [5 Z
                        lowpass_filter[0] = output;
( r) S, V- |# M& }9 d                } else if( nFilterType == 3 ) {& W5 K# E  [; w, e" @1 T
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)7 y* ?  ^7 {9 r9 _! \/ O- {
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;+ t! v2 D* q! A- y. g. U
                        lowpass_filter[2] = lowpass_filter[1];
2 c9 ^, c' V( A3 Q, ~0 V; y4 B                        lowpass_filter[1] = lowpass_filter[0];; c8 \* q6 s- M; `8 |
                        lowpass_filter[0] = output;/ [' Z) [5 R0 L! E4 T
                } else if( nFilterType == 4 ) {
3 W$ E$ z) u& x6 Y3 ?+ j4 v                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
: R/ |& K2 E, T" l                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;. {3 n& w: q6 m' g% C$ \9 I
                        lowpass_filter[1] = lowpass_filter[0];- s7 [  i4 @) F: W) w% J+ v, F
                        lowpass_filter[0] = output;
8 z; C$ M! [0 x. A. ]* f                }4 w5 R: z) u5 q3 w+ l

2 O4 L- Z( {; a( R: G* L# ^#if        08 |3 o, {2 S7 J4 j: N  D
                // DC惉暘偺僇僢僩
: m3 X& ]# Y2 }: e                {6 x' Y" D+ c' }2 Y  ~: f8 O" O
                static double ave = 0.0, max=0.0, min=0.0;9 {  g7 o( W7 n- G
                double delta;
0 s" t: |; J8 O; J                delta = (max-min)/32768.0;
+ ^, B  Z1 G  |, `                max -= delta;
: Y5 ~+ T4 U' U$ o/ `                min += delta;, T2 z) D4 Y( m7 B7 b& ?
                if( output > max ) max = output;
9 i6 C3 G" o2 Q) f3 S                if( output < min ) min = output;5 T2 ^0 @4 H4 t+ Q
                ave -= ave/1024.0;% Y5 B5 f7 F5 `& ]7 s/ L
                ave += (max+min)/2048.0;
" ]: q$ N% z+ \3 _& r                output -= (INT)ave;0 F  f! ^( w& X' Z* s
                }' x+ h8 J! ?6 E2 Y, L
#endif  A# p) W7 S8 x" k2 d
#if        1
. e2 t! R/ E! E4 N2 e                // DC惉暘偺僇僢僩(HPF TEST)$ p1 A/ C" ~( R" m" P2 ?
                {. B7 v+ K, g0 E' a+ j; Q9 B
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
! U1 B& |/ _8 H! p, p( j) a# z                static        double        cutofftemp = (2.0*3.141592653579*40.0);
* Z7 L. b8 F8 H3 x8 J                double        cutoff = cutofftemp/(double)Config.sound.nRate;
/ x" W0 F6 ^. v6 q3 S3 W                static        double        tmp = 0.0;
' s* l, e( I0 ?( k                double        in, out;
% \% h7 U0 I* {/ v) W. e; ]2 [7 K; N  |% H0 J, x* g1 y
                in = (double)output;6 q( M+ J1 o# Y& {" a
                out = (in - tmp);4 J4 L# U- L5 F6 V! j* ^9 ]
                tmp = tmp + cutoff * out;" i* m( T: V' X) f

5 `& c% S2 m+ t2 h" [: M. j+ Y                output = (INT)out;
2 p! f6 O9 @/ @3 x! w8 s                }
8 m$ {- T  D* k# f- g( s#endif
# x3 Q- ?8 l/ U7 r#if        0" U6 Q7 }) B! {* U5 ]+ Z- r
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
5 |4 N; y% W2 L3 z                {) R8 z6 {1 e3 \! ^# R" w- q3 L
                INT        diff = abs(output-last_data);7 w# J$ |' ?3 G* u4 h2 G8 J4 H
                if( diff > 0x4000 ) {
. o" X; O; M( L8 @( K1 u                        output /= 4;
4 z+ X! [+ d$ d& d9 M) S, f                } else " p5 V' {# E( @, x# p8 l; }
                if( diff > 0x3000 ) {, D* t: u7 x* [- c
                        output /= 3;1 ~/ E% t# z0 L2 m7 P6 Y& A1 t
                } else1 s" F2 R: Z9 H9 k" z
                if( diff > 0x2000 ) {) t/ s; n; T& ~3 L$ k0 F* F8 K3 ?7 B
                        output /= 2;
' Q+ o) {# ^, I2 F                }8 T8 V' \7 _8 W
                last_data = output;
4 F8 V5 a5 W3 m" C0 W! Y8 h4 G# z1 X                }
7 s- V& x/ j2 Y5 R" K: H. u#endif
% k" T' K: w& d                // Limit. ]) H+ ^0 |" s8 K" p1 i! @$ _
                if( output > 0x7FFF ) {
  w4 D) T: S3 u6 g( r9 z                        output = 0x7FFF;" C& H$ o7 }& D8 O
                } else if( output < -0x8000 ) {$ H* k' H" I$ n- z6 z
                        output = -0x8000;
' N/ E, [& \& [7 F7 W                }8 J+ S6 L: j! N4 d  W5 b

8 F8 t" u5 A, o" t                if( nBits != 8 ) {
3 {4 X2 A% E- T; w9 ?/ O. P0 F                        *(SHORT*)lpBuffer = (SHORT)output;7 f4 i8 m3 t; a! _5 X
                        lpBuffer += sizeof(SHORT);4 E5 q. ~' N( k* d
                } else {
+ ]" C& m7 k% X" [% A' ]2 r1 f                        *lpBuffer++ = (output>>8)^0x80;, `5 S( p6 C0 D
                }
* H2 P1 k6 ^: w/ o! ~7 z* G
8 C3 V& w5 u% Z                if( nCcount < 0x0100 )! }4 p* i1 t. M; }, j
                        pSoundBuf[nCcount++] = (SHORT)output;
6 a1 E! H1 z# ]& D6 C% t3 Z4 D. C" `$ m. P. |
//                elapsedtime += cycle_rate;4 \' T( g' ^/ z7 A7 C5 B4 f
                elapsed_time += cycle_rate;# d* X+ x9 x/ Z
        }
8 l1 f1 p5 u* |+ `# j8 H5 p* I" j  E, M
% d1 M: o7 t$ `2 l- c#if        1
6 M% W5 g8 K5 k6 K4 A        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
9 D6 {- a: j( u                elapsed_time = nes->cpu->GetTotalCycles();$ j6 f, ?0 P$ W) G" s
        }9 X9 y6 M/ q0 `5 V+ N# h
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {4 Y4 T& d7 l7 A& U0 Y3 ^5 y# |) p
                elapsed_time = nes->cpu->GetTotalCycles();
, ?/ X0 z; E9 r" T# Z        }4 t6 ?! U) A- V7 O4 \) E
#else
3 Z1 ~* H& _/ z. [: l0 ^1 Y- \% i        elapsed_time = nes->cpu->GetTotalCycles();/ u* J" O* b7 f) U$ T  [
#endif
1 `* W: E7 B8 ~' s& I$ F}4 R6 F5 O' K/ V2 o9 v+ X
. D4 v) V5 ^# p4 m% E, E' O$ h$ Z" t
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)8 `2 ]6 ^9 }/ O5 Z! g+ e  s
INT        APU::GetChannelFrequency( INT no )3 j8 }, L5 w: A8 t# a8 ?
{+ U7 b/ Q4 \5 c5 U& s
        if( !m_bMute[0] )
) [9 j2 s* S# @8 H3 B9 O6 T, S                return        0;; j) T# w& p# o
( V* e/ E$ r+ W
        // Internal$ N$ M  {; ?* c3 ]+ U
        if( no < 5 ) {1 z4 u- P$ l$ H  R- x- Q8 J) F
                return        m_bMute[no+1]?internal.GetFreq( no ):0;) _1 B. t5 X: g1 i6 d, v
        }
* e$ G& t% b' ]& G4 V7 x        // VRC6
7 ?9 Z$ G4 U$ e& z& i8 ]        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {6 ?. I2 b. r4 ?5 r- ]
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;4 R5 `  ]4 [* q. w% R
        }
5 ^8 k( n! x0 J% }( S# q3 p        // FDS
, ?; X. I: m% |: }8 A! Y8 [( f        if( (exsound_select & 0x04) && no == 0x300 ) {; ?  {+ X+ w; r2 ?( m
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
% s6 O8 F3 w4 b' m+ l) V, o1 m5 e        }1 V+ m$ W7 ]0 t! a7 I/ r
        // MMC5
6 M5 O6 _5 ^! ~5 N: {9 e) Y1 h        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {* k7 k8 T* x& N, [  e
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;5 q8 c/ W) m# m* g* F7 H5 U
        }' t3 V8 c) J5 ~3 n
        // N1062 \$ S; V+ h1 [4 R0 h
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {( m) E" U. L! Z% F+ h# p! e
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;1 d$ V1 N, y6 X  B0 \# r# x
        }
4 u# W4 D. f4 b6 M: B  `' B        // FME7
/ N/ }: J% S" {) ]% t0 S        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
0 k2 B' d$ ~3 B7 T# m) V' U                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
; t) O3 v9 H! {) ]# k+ B" k        }% F4 E7 K9 o( X8 r
        // VRC7
( K! ~) G9 f. ]        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {& ]0 {( h  Z' `- V
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;% |9 ~% S7 c0 l# B, @# }
        }; |- c5 G4 ^( M; m: O$ Y
        return        0;& K* y9 ~  U! `: @- V
}
% P8 f0 y: P+ C! F" S5 t" |& }  b6 S
9 _5 L$ X. x* o1 x0 H6 W// State Save/Load4 x& ~" c; d; T; J6 o- k
void        APU::SaveState( LPBYTE p )
' ?/ I# `3 n* s3 ?+ G{# N' Q6 r0 J/ P, W6 s
#ifdef        _DEBUG
( h! r9 n2 |( P& H+ @LPBYTE        pold = p;# q6 n. U& l* j8 [' [
#endif
6 n; [1 L& g" G, z0 g# ^/ [5 p9 |$ T3 d5 g0 o6 S9 M/ B/ Z
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
5 N+ Y5 R- k+ ]8 y% n+ |        QueueFlush();4 U: n, p0 V$ D' u) `
. ?+ I0 N0 {1 O& {) Q$ {
        internal.SaveState( p );
" C6 P" {# f  ?/ ?; z4 K        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
, R! Q8 d: ?3 h6 T) o. L( e
  C" \" S. X6 s# _, U        // VRC68 @5 g9 q/ Q; ?' d2 Z5 }
        if( exsound_select & 0x01 ) {; o( t4 Y& t0 J1 `  b
                vrc6.SaveState( p );# H" Z7 w" f4 V7 R$ E" }
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
0 H. T- ~3 B- j        }9 c) X1 i- m: |8 s+ V
        // VRC7 (not support): c! S. B: F* v3 x5 R
        if( exsound_select & 0x02 ) {* p2 X$ g6 G& x; W& Z& ^6 Q
                vrc7.SaveState( p );1 R5 C  m) m! w# y
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding0 i) p0 }# t# N
        }& d" r7 o) R- n; U; F+ Y
        // FDS: U0 W$ B# D( r# e) s. L
        if( exsound_select & 0x04 ) {
+ y0 H+ @# o% _% s$ ]                fds.SaveState( p );
3 R' D: Q2 U1 M) M8 [; [                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
6 I9 k' \1 R2 N8 `) I        }
1 S/ E* r0 D: i3 K+ S& n        // MMC5% b" z# L. m" P5 e; h5 T# e- S
        if( exsound_select & 0x08 ) {
4 I/ Q0 I1 W2 T+ ]$ G9 ?                mmc5.SaveState( p );' D& d% K: [5 j- _( [
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
( C7 X, Y% }  T6 h        }1 m1 z: L0 g5 X: C. S) N
        // N106
$ q  b/ Q, j" E0 w) W! o4 v5 P' z* ^- ?4 N        if( exsound_select & 0x10 ) {
2 A6 D* q$ i/ [: r7 R                n106.SaveState( p );, b& k/ i7 B9 y2 ^9 h
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding7 u% e, l* F) O* J% ]0 M& P
        }
8 S/ X3 z* ~3 ~  I        // FME7. f$ U. i# G6 z) c* q9 g. E8 y
        if( exsound_select & 0x20 ) {' a- l1 ]! A" H+ W. J( {( h: v
                fme7.SaveState( p );
" L; s, A' a/ b! O# z& ?. O                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
0 R3 m2 U5 V9 |7 E6 i+ r( N) B+ V        }2 h+ _* j- S/ I& s7 C0 W$ G7 S( }5 t

( t8 ^% _2 i# h* h! U5 J7 ?' p0 d#ifdef        _DEBUG# n/ L! ?4 U9 K. {- i1 q2 _# S
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );4 N# C/ h4 ]* D, c: f
#endif% U# U) J( |1 }( ~, P3 ?/ p$ [
}' p+ S! [" q* Q$ n" K
! z' O+ `" d( d  ]" b7 D$ o
void        APU::LoadState( LPBYTE p )
0 ~! o, Y. N3 }* }{
. ?8 N& P5 \3 C        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
/ C7 _: h7 S. t: A        QueueClear();9 p' g( Z) k5 C8 Y! b

7 i8 [( ?% s1 k# u# S        internal.LoadState( p );( x9 v. P1 Q+ a5 y& D& \7 q
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
" Q2 d, k  x2 a2 I; y+ D- X' e' B4 m
        // VRC6- G& }$ G8 X+ \7 h+ J5 G
        if( exsound_select & 0x01 ) {
  @" A, \7 Y) n8 w1 c3 ~1 k& c  N( `                vrc6.LoadState( p );
8 h3 L/ f- K2 e: l/ {7 S' H- ^  x                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding9 t. E* y; F8 d' A
        }
* l' |3 u9 U9 t( h$ G# J1 a        // VRC7 (not support)8 z2 ]- M" w# [5 J& |
        if( exsound_select & 0x02 ) {
4 e* [$ x- C$ g* U) {2 [3 b9 e7 M                vrc7.LoadState( p );: M3 e' `8 o( R$ ^' C8 ^8 g- L+ v
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding( c( B1 _! X6 a2 n! x, s
        }. |( y9 v9 f, N1 G+ Z: ^0 z: i' |
        // FDS8 t6 u' M4 h' Q1 X5 i  b7 R! Z
        if( exsound_select & 0x04 ) {
9 o: I2 P! m5 J  q- w) M                fds.LoadState( p );. s2 C$ B. O/ L) ]: M
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
7 s. k- z6 S' x9 a2 R        }
& T6 q. w( w# A* ~0 \        // MMC5
+ k$ h  q# w/ D2 Y; ^4 q8 X; J% R        if( exsound_select & 0x08 ) {
" n1 Z" H$ T/ g5 n, w4 v                mmc5.LoadState( p );- J: g6 w1 A- O1 ?+ c3 ^+ P
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding$ p( c3 E3 }0 g5 a: o$ }
        }6 }- j  O5 d) ^2 s' L/ H' h
        // N106- ?6 W% ?* V' d2 d/ R" L8 u; G2 s% Q9 Q
        if( exsound_select & 0x10 ) {0 `7 S; }  x5 {
                n106.LoadState( p );
0 g4 Z  P/ c' A1 [5 R" o                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
/ H$ V7 F4 q5 A" C) o        }" b- ]; j' c' t( {/ k% a  d
        // FME77 _4 R$ Q" S2 S- O# o
        if( exsound_select & 0x20 ) {2 S2 E! s1 Z# L  L+ b" p: y9 @7 N
                fme7.LoadState( p );
$ X3 J+ \5 l2 i; D                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding# `/ {3 N! G# r: L
        }& K- Z7 _& n. c1 H+ x
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 / [0 w. i' X; i! l8 ~$ n& h( j3 @
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
8 {* E, \8 I0 I* v, V0 f% X- J感激不尽~~
3 K* v, ^/ G, l6 j
恩 我對模擬器不是很有研究,
! G0 b) b2 n! J+ {9 u0 [雖然要了解源碼內容,可能不是很困難,
0 v0 s$ A, @6 G- w6 e+ _: H不過還是要花時間,個人目前蠻忙碌的。
! W, B& C" J5 i( S' x1 s' Y3 z
: K( n' y; ]7 V% ~3 U2 U) Y4 Q. E給你一個朋友的MSN,你可以跟他討論看看,- y: Z; h0 |+ a
他本身是程式設計師,也對FC模擬器很有興趣。
2 j- t2 |$ m! N# p0 E5 ?1 ^  X* Y* W; k4 [
MSN我就PM到你的信箱了。
( z4 s  W' g6 m: r; H( H1 a% a4 w/ F1 s, b
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 4 T( q) T( l6 B8 a
呵…… 谢过团长大人~~
1 i4 C: U& ?$ j3 q; D; J

8 i, g' J& J! L  Z( z哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 : Z/ ^8 e% c0 F2 h6 ]# w
团长的朋友都是神,那团长就是神的boss。
3 z, {  b6 j5 i, n) z0 X4 h
哈 不敢當,我只是個平凡人,
/ X0 s8 P$ x, l# y. R要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙0 A3 m, O( r) @
ZYH
/ Q: K. \8 z9 v8 Y: K5 ?& o# |QQ:414734306* S7 l6 J! z& _: M( E
Mail:zyh-01@126.com# t3 U# h1 M& d! P3 r# t/ [
' k. C6 D0 d0 X
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 4 e9 U' Y' ^# m$ n9 s: ?
再次对团长大人和悠悠哥的无私帮助表示感谢~~

% G: y' w, A& ?" w2 V+ J. |3 P) X, Y& ]不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-28 14:28 , Processed in 1.082032 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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