EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?6 e6 P1 {( k! J4 F1 f0 g* n; s* i
PS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。. z7 H) k9 }" V1 {: N' T* i7 X
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~1 A$ y" S0 O- B: i$ T
这里有相应的模拟器源码,就当送给大侠了~~
/ j: N+ c+ O3 _+ b( Z( Ghttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 + }$ [9 G* J5 Q& {; a% d3 G
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。9 W' ]+ ^: Q4 `: j+ `4 E4 j, o
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
% m" ^, f' I0 x; G这里有相应的模拟器源码,就当送给大侠 ...

+ u9 a# x+ e3 S聲音部分(Audoi Process Unit = APU):3 p6 W, c3 J8 g7 [
.\NES\APU.cpp
9 u( W% d) x& x.\NES\APU.h
- K1 w6 M# o3 E0 e- J7 w% u
5 ?5 Y4 w5 ^4 _! X, f
* G" z5 R. ~0 f$ y' ^+ _+ }影像處理部份(Picture Processing Unit = PPU):
! l& v# _! ^. @; U7 D3 R8 M.\NES\PPU.cpp6 o0 C* [, l7 c6 E7 s! W
.\NES\PPU.h
) [% F8 B4 ~- k% g1 M
2 Q5 m. o4 ~$ b# q$ @$ U1 A- p6 ^4 P如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:) W- [5 a+ x' ~
(由于很多专用术语和算法机理都不明白,所以看不大懂……)) y# N+ _: e& p* o, f0 v
//////////////////////////////////////////////////////////////////////////8 A' ~! f! N, V
//                                                                      //! B0 ]' i; t* y' j- }9 k, m
//      NES APU core                                                    //8 B  {# F/ i4 E" y, n# @  u- _& B
//                                                           Norix      //0 H0 Z0 f  C) Y& ?5 D/ X" a; Y, x
//                                               written     2002/06/27 //
8 i/ j- W  |+ c) n8 T, m//                                               last modify ----/--/-- //
& E2 T# r2 U. `3 h" {6 J//////////////////////////////////////////////////////////////////////////
: q7 L7 i1 G8 l8 T0 X( i8 V- X#include "DebugOut.h"
- h; D) f. P" c4 {4 V#include "App.h"- F( t. ?. @. \* i  |
#include "Config.h"
' q+ V' J- n  T/ y6 o) Y
4 s! v- I  o$ A' B' D' S#include "nes.h"
( e9 \5 l! u8 V# F/ G2 C1 v% E#include "mmu.h"* n" G* |) n0 b+ f, I0 G
#include "cpu.h"
( X2 a/ G; u% [; P9 G. X#include "ppu.h"$ k8 i- B) e! g& I% ?/ [2 B8 U
#include "rom.h"
' L* N% h8 f6 U$ G#include "apu.h"
( y4 u' W" z9 |1 d% x! i
- g4 d* @; w$ |: M0 Q$ h// Volume adjust) L/ Y) y6 U3 f/ H, |) j( e
// Internal sounds
8 d4 K8 ?7 c2 F+ s" y! u! @0 `#define        RECTANGLE_VOL        (0x0F0)& k9 U+ t0 N* x2 ?4 s1 i
#define        TRIANGLE_VOL        (0x130)8 s% P; ?) d9 b6 c( i
#define        NOISE_VOL        (0x0C0)( h, M& J# ^1 r' S' Z3 T
#define        DPCM_VOL        (0x0F0). S) ]0 c$ D( l8 _9 C
// Extra sounds
/ S& U3 ]8 m1 X0 z% s" _8 Z  p+ Z#define        VRC6_VOL        (0x0F0)" ^8 |7 D. Q! D& `: x. o
#define        VRC7_VOL        (0x130)# d0 x: Y3 \  i
#define        FDS_VOL                (0x0F0)$ F' @4 Z0 Q+ M! p
#define        MMC5_VOL        (0x0F0)
9 P0 q3 b6 x6 [9 y/ j4 o#define        N106_VOL        (0x088)
7 j8 n* }8 W' J3 o; X#define        FME7_VOL        (0x130)
6 _' ~- y5 H. j0 q9 }9 z' S  L& ~. h: h0 X5 X
APU::APU( NES* parent )  X- _5 o) }& h: W3 @+ ^4 i7 {8 s
{3 w, O9 R, a! W# e# U, i7 I. V
        exsound_select = 0;/ J5 M  o; @  v$ s1 G& U
& L4 W/ [7 j2 K: `) T. R, K
        nes = parent;
/ j  f1 s6 x2 Q3 F- {        internal.SetParent( parent );0 P$ l! u0 I; G0 ?+ o; c
. d! @/ ?7 ]+ f; Q/ E: J
        last_data = last_diff = 0;
9 i) e) N, n6 D3 C% `' [% @! N( p2 b' p
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );- i# |! i' v8 `/ b$ G% P/ Y" y/ o
' J, P# n& x) y- t
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );; P# h$ v( V. U: F" D! o
        ZEROMEMORY( &queue, sizeof(queue) );
$ T6 A0 g) ]# G# Q$ s& N        ZEROMEMORY( &exqueue, sizeof(exqueue) );
. u: A4 o2 ]: M, W& S7 |) D- z' w+ T9 R; |6 Y3 l& U. W( z: Q1 L% _
        for( INT i = 0; i < 16; i++ ) {
+ [/ T( f0 Y! v  k: ^+ M0 t* Z                m_bMute = TRUE;5 O! q; \! L, x
        }
# ?+ e& m' o# d}
2 f# t/ ?; S8 D+ [- G) A: u  ]( }  x
APU::~APU()9 m" Q: t; O! |! c
{/ w& V% d! n. ^( p5 g0 g+ E& p7 N
}" O; L  H6 N6 d: R/ }/ D3 G0 @2 X
. O7 S/ ]  X. d4 l
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
3 t' A, Y8 f, s) z# m$ i1 E{) T" q3 f8 e4 T
        queue.data[queue.wrptr].time = writetime;: @, z$ y/ h7 d$ w3 J8 l
        queue.data[queue.wrptr].addr = addr;8 ]9 K0 v! m% M3 [  M
        queue.data[queue.wrptr].data = data;
8 S0 C0 Z/ C7 N% c4 q        queue.wrptr++;7 G, J; {5 e1 O; F$ f
        queue.wrptr&=QUEUE_LENGTH-1;
: V$ m% w/ t" J. Y% G        if( queue.wrptr == queue.rdptr ) {
; I( N" a" K9 \# ~1 O                DEBUGOUT( "queue overflow.\n" );9 _+ r; P! y2 a) \+ `
        }
# {3 M7 u" _5 G0 G5 l9 s' X$ m}
# j/ d% }3 I) @4 w- d! ]: Y; f- @6 V( }  B0 A
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )6 Y7 h  r( B2 T: o  J
{# m# m- W$ b& `' G3 S
        if( queue.wrptr == queue.rdptr ) {
4 B& b/ |$ d  `' s9 G                return        FALSE;7 k& g3 B; m5 I* g+ _
        }+ k" I) |0 G7 c
        if( queue.data[queue.rdptr].time <= writetime ) {: Y' \, |: B+ P1 j0 t' H" u
                ret = queue.data[queue.rdptr];
6 a8 Y% j" ]7 r, @. K                queue.rdptr++;/ V/ j$ F. l7 g
                queue.rdptr&=QUEUE_LENGTH-1;8 y+ r7 o' w" X) D5 Q, e
                return        TRUE;
& ?! I8 X7 J" R2 {% g        }) y0 ]& B  P0 G+ f7 x
        return        FALSE;
4 c: n' M# V4 l}+ F! v! l; g! Z# w: g
( v  W  t' {$ i( v) ?, q6 U
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
; W5 ?8 v7 g; J5 i: t4 J{
+ j* }: x" `4 W% N5 [/ g* C        exqueue.data[exqueue.wrptr].time = writetime;
! X6 Q* f5 c0 H6 _8 F9 `" z$ q        exqueue.data[exqueue.wrptr].addr = addr;& a) J* ]& O6 e( Y; B6 R3 k
        exqueue.data[exqueue.wrptr].data = data;
: ^7 T7 R' V. w/ `$ M        exqueue.wrptr++;
  D- d1 `) }) ?. T6 p        exqueue.wrptr&=QUEUE_LENGTH-1;4 }! G0 w& Z/ d4 r
        if( exqueue.wrptr == exqueue.rdptr ) {& C5 `+ T5 r8 R  O+ b0 o
                DEBUGOUT( "exqueue overflow.\n" );
1 T! c7 P/ E3 y) Y        }) \6 ~' P" |+ S" g& V$ G
}
2 k7 r) `  [( N' x; ^+ ~9 F2 v* E# R0 _' N) i$ `. n9 h
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret ). Q/ A: b2 i4 X; R
{. g; U+ e$ F: u" F/ Q. }- W
        if( exqueue.wrptr == exqueue.rdptr ) {
8 N" u3 o0 W0 I" j1 E* b  }                return        FALSE;: H) z& j' J- S3 e
        }3 _4 R- ^" }0 P
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {5 h. f: d" G9 @/ Q: Q
                ret = exqueue.data[exqueue.rdptr];" \! J+ i4 h$ z4 A9 o+ L
                exqueue.rdptr++;
2 v& n; ]6 @# E# V" O$ F' m                exqueue.rdptr&=QUEUE_LENGTH-1;
' S2 Q" N# y7 }# U( L8 g                return        TRUE;
; ^7 h& i; c: h; J        }, z& L/ f* _0 X3 u- B, K/ \' a
        return        FALSE;5 X3 u$ h( A/ D5 y2 _1 u
}5 E0 C- H, e, z9 }" K" Y( v1 Y

& d- a! J3 U4 tvoid        APU::QueueClear()
$ Z$ G0 X/ g' A4 V{
/ Q% N2 s- m; o* H! u% P# t; m        ZEROMEMORY( &queue, sizeof(queue) );2 y2 p9 b( G, [/ N
        ZEROMEMORY( &exqueue, sizeof(exqueue) );. e6 s0 r: z; @" P3 F8 [
}
' q$ S$ w9 b: a
3 k% [5 s+ T: w2 ]  `9 yvoid        APU::QueueFlush()  T2 E! Z+ P% ^! @3 r- F# y
{8 y, Y  j  V; O$ G$ r  b+ H
        while( queue.wrptr != queue.rdptr ) {+ C$ M  @9 j, q2 @2 S: t" U2 K
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );) k: x# K8 J5 z% Z' W1 X" g
                queue.rdptr++;
: I. T) B6 U, o& N5 r  k6 w+ E                queue.rdptr&=QUEUE_LENGTH-1;
- L2 ^. r. y+ D( m1 {) f6 P& Z! |        }
6 F0 k" B0 j. o7 q5 r7 i0 @
8 p. m1 s- [1 [; G# \$ N1 \  W: V        while( exqueue.wrptr != exqueue.rdptr ) {
5 O4 D+ q2 H4 o- ^- w# v                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );2 c4 f+ Q; y+ u7 V: E8 u
                exqueue.rdptr++;
+ V& ~8 P& u2 d3 G9 b, F. j4 l4 _7 @                exqueue.rdptr&=QUEUE_LENGTH-1;
2 i7 B( U$ l3 P1 `: y( I+ b1 H        }' N  \3 m4 D5 ~+ L$ j$ ?7 p6 j
}
7 D9 h2 V# l; L0 q# Y$ z8 t$ F$ {, n
void        APU::SoundSetup()
  d  T6 r2 {- o{
' l5 J% S: Q; T4 S% T4 F        FLOAT        fClock = nes->nescfg->CpuClock;
9 G- X+ y" _/ w% {+ {6 s( o: t        INT        nRate = (INT)Config.sound.nRate;
2 d$ J: P6 h/ k# @# q" e& v        internal.Setup( fClock, nRate );
" B6 c  L* E2 K# z        vrc6.Setup( fClock, nRate );
% {1 ^8 F/ j: ~/ R- S; o        vrc7.Setup( fClock, nRate );
9 T# H; q; y9 f  x        mmc5.Setup( fClock, nRate );/ H0 G8 n$ c/ T' S5 S9 {# D6 I
        fds.Setup ( fClock, nRate );
' y: {/ ^$ T2 i. l' S        n106.Setup( fClock, nRate );
0 T1 f& s: c" n        fme7.Setup( fClock, nRate );5 M- r  U3 |% _
}
8 q# r; k1 F; @  g; a* |% }; G6 Y3 l! |. c' ?6 R% L1 {
void        APU::Reset()" |7 T0 F6 z; l8 v
{; U( W2 R. A" l& B
        ZEROMEMORY( &queue, sizeof(queue) );8 {; i9 d7 P3 l
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
7 L0 u  V: j8 Y0 Z& ?9 X
- S5 e) K. t6 X        elapsed_time = 0;/ @8 n% L" D& f8 S

/ f6 \* C2 _& _- T        FLOAT        fClock = nes->nescfg->CpuClock;7 F6 Q/ Q% ]) @3 ?: U: w
        INT        nRate = (INT)Config.sound.nRate;# H! D/ ?3 h3 D9 d9 b; x
        internal.Reset( fClock, nRate );7 J, P- X5 v& g. t
        vrc6.Reset( fClock, nRate );
: u$ R+ V! {/ l5 {3 O        vrc7.Reset( fClock, nRate );
4 E3 v" E. h3 o' t# l: _        mmc5.Reset( fClock, nRate );
- O/ j8 l9 L! F9 \) [) b, }        fds.Reset ( fClock, nRate );
- Q- E" U1 s/ z5 K        n106.Reset( fClock, nRate );2 U( p% H. w' `: L
        fme7.Reset( fClock, nRate );6 b" H) G7 _1 H+ M+ i5 d, c
/ Y# w# s, v$ I# V  m' G' r
        SoundSetup();  ^) d9 X3 k& `" q  H
}
9 x- h: l  Q1 h" ~1 p; y
/ r% ~  \4 C9 yvoid        APU::SelectExSound( BYTE data )3 l8 o5 F0 u) R1 o3 R" b
{
; i4 I8 W: F7 R        exsound_select = data;- C" @/ J4 D, Y, }, c
}& q8 q( w2 Y* [& a  k0 V2 G- H

$ y( A4 \6 t# S! o7 l- LBYTE        APU::Read( WORD addr )
8 P; B* Z- A/ A0 i( j7 c{
' H' l. J6 L4 Q6 x( p        return        internal.SyncRead( addr );- G+ L5 I7 y* @) I: A' H( f
}
) O3 F8 f" f  v! W9 z! |1 }5 n' ~0 V; ?1 C9 s2 i& k
void        APU::Write( WORD addr, BYTE data )
8 i  v7 A2 a+ |& |" n1 U4 ]{
- E6 w( `0 i# |. W) S        // $4018偼VirtuaNES屌桳億乕僩# B3 V) E! r9 b+ N; A0 w& _* @- W
        if( addr >= 0x4000 && addr <= 0x401F ) {
+ H# h5 ]3 Z$ Z# C/ K                internal.SyncWrite( addr, data );. \0 m  o4 k$ {/ t
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );8 o, x$ L2 [, D
        }
8 [/ ^1 z& }1 t1 L& \}* w! j  L, k9 j/ P2 f$ B

* H4 w: s6 j( G4 j$ f, _BYTE        APU::ExRead( WORD addr ): N4 ]" H) R- t$ _9 S  Y
{
3 S0 O8 H4 R" u& Z) UBYTE        data = 0;
0 x9 a, t/ H- b6 ~) u! h( K, @" m6 s" R$ R% k% L1 P
        if( exsound_select & 0x10 ) {
% Z8 ?# i3 z) ^( H8 s; W' C3 u                if( addr == 0x4800 ) {
* d+ w4 Q/ N7 y4 E3 Z                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );! U* J: ^# r; x% S5 g; Y
                }
- M" E' ~- ]: k! M9 R: X( \5 O        }
% h* m# p) i& F- V/ V        if( exsound_select & 0x04 ) {
, S2 s. x) V( M# @2 y                if( addr >= 0x4040 && addr < 0x4100 ) {
5 [# n# U) f+ m( |  ~                        data = fds.SyncRead( addr );
6 \7 w, }* A( f$ z( d5 W- t                }
8 _; \+ d* o+ M7 R) [        }
: ^; J* i/ G1 C( J        if( exsound_select & 0x08 ) {
  o* n& Y) ]* R  r* h: T                if( addr >= 0x5000 && addr <= 0x5015 ) {4 P4 A5 w, T% p6 D3 v
                        data = mmc5.SyncRead( addr );
( h! h( d, R- _$ M                }: t6 K/ i5 _$ H4 y# X
        }
% v! \( g3 i/ y0 U8 O. r3 \# W# R
        return        data;
6 s% s, ~1 ^, T) |0 _6 O% V}
' v" `' w, g$ J0 S" d
/ V+ o- l' {1 x5 avoid        APU::ExWrite( WORD addr, BYTE data )+ a4 B+ t) e- z4 b  i+ X) E- Z2 ~$ _
{% F9 p( i  A! l$ s/ _
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );. D& T  d6 Q" L% D6 s

: }: D6 W) d* }5 p  j        if( exsound_select & 0x04 ) {' t" \4 V$ g  S6 N  L. w
                if( addr >= 0x4040 && addr < 0x4100 ) {
- Z& }+ E6 f' S# A$ K                        fds.SyncWrite( addr, data );
$ J7 Q7 @3 G$ ~' ^1 ?# x0 n                }
- Q/ s3 K  f7 g- I        }
3 p. w6 C4 P: n& i) B7 n
& Y/ _6 p$ |9 v  Z1 T2 U5 ^6 }        if( exsound_select & 0x08 ) {8 T) d/ N" g/ l/ W& _) \; }) F
                if( addr >= 0x5000 && addr <= 0x5015 ) {
' X3 {, f9 f* r6 N6 \                        mmc5.SyncWrite( addr, data );
' J: `& n/ ]" w6 ]$ a7 z                }
, C" [# h. x  v. m: X        }
: ]2 W# P+ K* W}
( A8 R" m0 n- ]( Z; P& ]' ]1 [. P6 o( c  D, p& `5 D
void        APU::Sync()
! I* H8 Z' E- P{6 I) l. c# ~: A- [1 b$ J8 I
}
/ B; W7 V- K% l9 o+ P4 k- O  y, D2 g3 d0 T4 r/ B6 `2 M% y
void        APU::SyncDPCM( INT cycles )
5 h& X4 ]- a* v3 E9 S0 B9 ]{
5 V' H' s/ x- d0 L, F, {        internal.Sync( cycles );
4 f8 a6 k" x' ]5 i* K, N
. Q/ y3 |2 b2 \4 }: M+ @        if( exsound_select & 0x04 ) {
' e6 I+ f1 S4 T  r' K' ]$ ?                fds.Sync( cycles );6 T6 Z$ @0 [! t' r4 T8 j
        }
! s, {6 ]. Z) i& ~) i" D  T& M* B- v        if( exsound_select & 0x08 ) {  m3 k8 A9 @; ~! }  W
                mmc5.Sync( cycles );' c$ r( q7 r* R% h
        }$ s3 V1 c8 ]! d7 A" x! }, t
}
* I3 l" \$ C& P# j8 |6 U! E8 }! w) {8 T4 E4 ^. r3 R- }4 u% }; L
void        APU::WriteProcess( WORD addr, BYTE data )) B2 W- |6 ?' v' b1 v9 I% p- S- P
{) I' U4 q  {  A; p- R# E* ^$ `
        // $4018偼VirtuaNES屌桳億乕僩
4 x& x% I$ g9 L6 `        if( addr >= 0x4000 && addr <= 0x401F ) {3 Y" H1 C( L( {( A4 p3 Q
                internal.Write( addr, data );; t8 O# l& e+ s$ o+ n
        }
6 g# ]% A) i) m7 ]+ r; t3 O}  L  q3 X4 H6 T, g

' O4 r5 [5 f9 R+ m- [# W" Y+ ovoid        APU::WriteExProcess( WORD addr, BYTE data )( a7 p' I8 _; T: w
{# c2 i* P; e0 v% {1 {% Y
        if( exsound_select & 0x01 ) {
* x( T- }. T: a- p                vrc6.Write( addr, data );
. [) |8 |7 W, Y0 K* Z6 J# O        }# n+ o" J# q# d% ?# M
        if( exsound_select & 0x02 ) {
! F4 F- `  D' l1 `! b% b3 O7 W1 }                vrc7.Write( addr, data );
9 H5 E7 P6 V6 q5 E. P        }5 N+ H. J" F" _2 W2 v- n6 q
        if( exsound_select & 0x04 ) {
' t8 I; a- o! g5 {. }6 e" Q                fds.Write( addr, data );
6 }) U& f) l* [. _& [        }8 d$ Y; o2 p5 U' w, e+ \
        if( exsound_select & 0x08 ) {- t& w: W3 `: r; _
                mmc5.Write( addr, data );& Y/ ^1 X: E7 u$ m
        }
: h6 t- E4 N% }% f7 n; W        if( exsound_select & 0x10 ) {
" F/ [( b" |9 y2 h' W- B                if( addr == 0x0000 ) {# y/ o% b% N" V1 D, a8 f4 a
                        BYTE        dummy = n106.Read( addr );1 l$ q  L$ Y. b# ?' w
                } else {
- m$ z+ g: N/ m9 ?5 q* V' U/ D# m                        n106.Write( addr, data );& C, g! s8 H% i0 q& h4 G+ }
                }
( O" M: }) r2 S7 e# }/ P        }8 J& t) R( G, O. N( t8 F+ ]7 G
        if( exsound_select & 0x20 ) {
; r" t$ d1 J/ q2 K; g7 r( Q. j                fme7.Write( addr, data );
- s" W& l4 M! A6 q, @        }; D0 l* f% I. R
}* M8 f8 K9 b# f" s  d+ h3 B
8 R5 N% s+ H/ B- T7 I
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
" l% x7 T' s4 o! L0 \{
6 _+ H! i7 S, tINT        nBits = Config.sound.nBits;% C0 G4 ~5 v3 ^- [$ p
DWORD        dwLength = dwSize / (nBits/8);+ r( u' a, w% k- E3 X* j: c
INT        output;
, x8 J8 r- v6 o1 VQUEUEDATA q;
* @6 o. B: U% r' u: j) wDWORD        writetime;. ~0 I, \# G# O0 b' J4 A* Q' k

" b4 y; a' ^8 J3 F  w0 F4 L9 JLPSHORT        pSoundBuf = m_SoundBuffer;" o8 Y4 L# H8 V) P
INT        nCcount = 0;
  y7 g5 E3 C2 G6 `, A% A
$ X8 U2 e9 i, N, vINT        nFilterType = Config.sound.nFilterType;
. p% Z  k: K! e8 D  `. \& x5 q9 s, \
        if( !Config.sound.bEnable ) {2 r4 k7 p6 E; }
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
  u$ w1 \6 K% `1 U                return;
" ~1 j: ?# m4 W0 M4 y! T        }
  ]3 b$ q4 V& F; A6 L% }3 L8 X( x! a, E
  t& N1 _9 w- }2 B. @/ P: O% M        // Volume setup" `8 H. F+ |6 x8 m. x* b* P! P
        //  0:Master! b% F% _  c+ l. g! `9 e* B2 `$ L
        //  1:Rectangle 1, ?: [" e. Y+ F% D+ A
        //  2:Rectangle 2
, O. C+ H' T) ~( o        //  3:Triangle5 {: `* D9 \6 }% ]
        //  4:Noise
4 I+ M: l, {" J$ v/ a3 |1 R        //  5:DPCM9 k$ t- N' p5 ?! t2 ~9 W& X) A$ H
        //  6:VRC6
0 I' ]  }9 E+ ]$ Z, C, X        //  7:VRC7; T4 Q, u  ^6 p+ R
        //  8:FDS' _. I" j; h$ G, L( O% d; [$ q
        //  9:MMC51 d( ?# _' K: l
        // 10:N106
0 B+ j! e. I0 B+ F' Y1 B        // 11:FME7  q. F! w7 T. N1 W5 U7 {
        INT        vol[24];
$ Q  T: g9 l# |8 S8 b        BOOL*        bMute = m_bMute;* M# p& J/ U2 y' h" h
        SHORT*        nVolume = Config.sound.nVolume;
/ m' r1 ^% K9 b0 c$ ^( ^8 ~- {: C# [
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
6 @, a/ Q" F) A2 {( q9 n
1 H/ b+ p4 f" ?        // Internal
7 b/ H% q  _, n, h. u        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
; F- P+ X2 F- S, B        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;! t( g4 [: i$ Z7 f1 ~
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;5 ?7 `) A0 m  J$ ?* d+ ]/ O
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;; i% T% i2 S) _
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
9 t* D( g  t2 P* P: R# E, i8 f4 f) u! l) q! }
        // VRC6; \8 W, Q# h+ a6 H* ^
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
( a# [* K# P3 M* {        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;& F- y; \2 [4 G  m! C
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
6 O7 b  y2 b' [5 c6 a0 F# k3 c" J9 s% O3 C# Q
        // VRC7
+ P% d8 [0 }$ {! f) @7 Z3 B        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;, B/ M9 U5 `: P) q

  j( P/ ?, s' w+ K        // FDS3 L% H7 Y" k) {& r2 h6 g3 Z
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;$ ]( B4 P" e4 C. P/ C
  ^/ j) e$ r, z4 S; p: f7 @0 ^
        // MMC5- `3 r; E( K9 r. z/ P" q- v
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;' p" v+ B) S- t4 x1 M% N6 x
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
, K! g# w; f9 }8 @) p        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
$ K' D' x. P1 A) X! m3 _  N5 z  M$ }) j# Z: p3 g  Q4 ^5 M
        // N106
: m  N  T7 a- G6 e- r% g2 Q        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;. G8 w: w' n/ K- K7 o
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 g7 O8 i7 p" n4 e
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, V" N6 Q5 b3 y/ s        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
5 u8 s: I2 G! u" r" b% s: C        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;3 T6 J& M4 K5 G4 \) j! t% `
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' W/ D! H$ M  r; Y
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 }( [' T: \2 D: C/ V7 l4 g# G        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
% |* [  T1 W6 r, ~1 j. @# w/ V) d2 S  v( K9 \; K
        // FME7
( x6 X( O1 p$ G: m        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;/ }  @4 a. D- G
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
% r3 E$ U. r( x, M7 C; x( c4 u        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;' p3 V8 o4 U& D: B6 I+ V
8 m" Z% j, G% |
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
! F* Y# q2 A6 V9 y        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
# F% s# [8 j+ C3 r, k, J  Q0 p
$ D5 M  R4 _: G) D  r. y        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
$ p% L9 c$ G2 L/ C! _( f        if( elapsed_time > nes->cpu->GetTotalCycles() ) {6 f6 R  ~0 p+ o2 k5 K
                QueueFlush();
0 b' U+ o% v7 d% R8 X( V        }# K  V4 u+ {& d0 Z% e' P

* J% G7 F5 ]+ Q, X- t+ G9 f" J2 @        while( dwLength-- ) {
8 x+ A6 N2 C# k4 D: ]) `( z, }                writetime = (DWORD)elapsed_time;; z& O2 }5 l9 J8 S) U" q
" `: A  M6 q$ j  s) t
                while( GetQueue( writetime, q ) ) {
& a3 m% P& |( u" _: w                        WriteProcess( q.addr, q.data );2 B5 ?+ @" e; [
                }4 R2 N* c6 ], l& W
/ |* o/ @9 O7 b
                while( GetExQueue( writetime, q ) ) {7 c4 R3 }( k% c! B# _4 p* s9 b' Y
                        WriteExProcess( q.addr, q.data );+ H' ~' k! `( M
                }
+ V# y/ B% B8 c' [8 P6 ?- @; J
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7- B8 j( ^3 P6 ^% W
                output = 0;& a# s! o) D! N: L' a7 T7 G
                output += internal.Process( 0 )*vol[0];
- U9 _7 ^7 n; f! S  l5 X4 |                output += internal.Process( 1 )*vol[1];1 j9 V( u0 Z: N2 x3 L. t
                output += internal.Process( 2 )*vol[2];
4 N, Y! f2 N1 w0 r                output += internal.Process( 3 )*vol[3];
4 m# J9 J& W$ B, R- I% k                output += internal.Process( 4 )*vol[4];
7 Q9 k! a8 U* q% W
# @; f  W7 N- A# t. E- j$ G( H, `                if( exsound_select & 0x01 ) {9 z' y+ C* }0 |- R
                        output += vrc6.Process( 0 )*vol[5];8 n- x$ C9 Q: ^% P
                        output += vrc6.Process( 1 )*vol[6];
5 Y9 o# ^5 G( F0 G  f/ }2 a                        output += vrc6.Process( 2 )*vol[7];4 Q7 |  b8 r' n6 W- B
                }
" V/ T- y; ?/ W' _' \3 r# |+ I                if( exsound_select & 0x02 ) {5 H) ]8 d! H) C8 m7 R- q/ X
                        output += vrc7.Process( 0 )*vol[8];
$ f  D( B# a* z) @( P" D                }
, q) |$ n4 @7 ~7 b; s5 W# g                if( exsound_select & 0x04 ) {
$ B, h4 E. ~+ Y- V                        output += fds.Process( 0 )*vol[9];
6 P' Q/ E* i% G+ D                }& _1 {& r/ C: f6 Z& d6 P1 b! J
                if( exsound_select & 0x08 ) {
5 s( Y3 T2 E( ?  d                        output += mmc5.Process( 0 )*vol[10];
' i& y5 {  N" U) w) g2 g                        output += mmc5.Process( 1 )*vol[11];
9 r5 M) F% I6 K                        output += mmc5.Process( 2 )*vol[12];( m7 q3 d8 _& M2 P3 i9 p' X+ R
                }
& B1 i) q" l% A$ i  h8 V: \1 |* T) e                if( exsound_select & 0x10 ) {
& C, t+ `& W! V& }$ U- X5 U1 s                        output += n106.Process( 0 )*vol[13];# E  v* T+ {5 p6 p! e
                        output += n106.Process( 1 )*vol[14];- {' l' \( h' y5 ^$ c7 Z' B$ d0 u
                        output += n106.Process( 2 )*vol[15];
1 }( I- V# {, x                        output += n106.Process( 3 )*vol[16];
2 m4 _: v$ o4 G) s' v                        output += n106.Process( 4 )*vol[17];4 ^5 y% H: ?# r
                        output += n106.Process( 5 )*vol[18];3 W! |! |+ u( O4 [9 T
                        output += n106.Process( 6 )*vol[19];" ?( X8 z. `  N$ d/ R  j
                        output += n106.Process( 7 )*vol[20];
" d! [0 t% @' K; C$ M3 r; ~                }# K. K9 ]: X+ g- T6 [
                if( exsound_select & 0x20 ) {
; n( O7 W$ M7 \, }                        fme7.Process( 3 );        // Envelope & Noise( u+ X  v& t3 x& N* u9 ?
                        output += fme7.Process( 0 )*vol[21];' x* F$ Z( ^" {5 C
                        output += fme7.Process( 1 )*vol[22];$ m. n( R! Q( C2 ^
                        output += fme7.Process( 2 )*vol[23];
1 ?3 Y: m8 g; z8 n/ x% w                }$ R, l$ j' L) c( {5 V8 ?

' Q* ]0 d( y+ m2 Q. U; E8 e                output >>= 8;8 ]$ w' m' W7 Y$ M

" o, n( ]; S; z" n                if( nFilterType == 1 ) {
5 k% Z6 `& q$ {8 N6 Q( Y" p                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple). j5 x% K# Y* l5 D+ B1 c5 D! C
                        output = (lowpass_filter[0]+output)/2;0 A3 P* E! ]8 B; V% W! k; Y
                        lowpass_filter[0] = output;
5 M& f; m8 S1 d8 K( I, ~7 v7 x                } else if( nFilterType == 2 ) {
+ L3 F- S3 y$ O: l* l# B                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
9 v3 `! x1 e+ x2 X# L                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;5 |3 J( O0 n4 x- b5 [: ^
                        lowpass_filter[1] = lowpass_filter[0];
# p7 T' L0 ^( c/ Y/ S3 P                        lowpass_filter[0] = output;
' X( Q# ^- t/ s& u/ i* B                } else if( nFilterType == 3 ) {8 d9 d) n4 C* s. O* |% q
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
7 `) r$ M; Q% y* X/ ^7 A, c1 x  k                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
( j8 O0 z& E6 d) N                        lowpass_filter[2] = lowpass_filter[1];8 G  x/ U: Q- k& }
                        lowpass_filter[1] = lowpass_filter[0];3 G1 g9 w8 a. h9 N7 ~8 ~
                        lowpass_filter[0] = output;4 K8 |. Y) S0 \* S* Z
                } else if( nFilterType == 4 ) {
6 v/ d8 W+ n+ [, m+ i                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
2 Y, y( B2 y: I. @* J                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
- W8 @, z: U8 W3 E                        lowpass_filter[1] = lowpass_filter[0];1 N# r# X2 k+ Z* P8 [
                        lowpass_filter[0] = output;
; [9 t" ?2 J2 h' h) [& w2 Y                }2 S0 a% ~$ Q* M3 y& l) J) O0 U' ~

! N) G9 B! l) M4 r" @- h0 N#if        0
( Z& w' b3 O+ A9 p; [% X, X                // DC惉暘偺僇僢僩
# K2 Y3 T7 Q$ ^4 [% }                {
1 Z# F1 b! m/ B% l! U- d+ v1 `1 Q3 ?1 |  i                static double ave = 0.0, max=0.0, min=0.0;
% j! X# X; ], q& O0 e                double delta;
% d: ?; y0 n+ ~) |6 D4 s                delta = (max-min)/32768.0;4 C% b6 s; T* {/ Q% j+ N9 ^+ p
                max -= delta;$ D' C$ z* B+ d9 O8 `
                min += delta;
: q  t: ^/ }) ]7 d9 x                if( output > max ) max = output;6 V2 }- n$ B  }% c3 m
                if( output < min ) min = output;
7 X: R( n) ~2 A                ave -= ave/1024.0;
6 `0 U9 \" `) g! L& i4 Q3 @8 g                ave += (max+min)/2048.0;! I2 u3 H, l# |$ {2 S
                output -= (INT)ave;: P: a  L* _& F2 Z; T$ B. F
                }
' U6 q7 X7 o+ d0 g3 T) L& Y. @#endif
7 q) j& J. W9 ^4 N0 g& ^/ n( {#if        14 J$ @7 ^2 `3 r6 O: ~4 ~" D( {
                // DC惉暘偺僇僢僩(HPF TEST)4 F8 }* q  I. I) |  K
                {
7 x/ X7 v  X6 E% r) T//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
2 U/ b! h4 N0 w1 ^9 w6 T& G                static        double        cutofftemp = (2.0*3.141592653579*40.0);0 A0 z5 f1 D7 y1 A- m
                double        cutoff = cutofftemp/(double)Config.sound.nRate;+ O) `" Y& t; m7 X' y
                static        double        tmp = 0.0;
* ?: f' `6 v. ?1 Z3 K# H                double        in, out;
- u6 p& W6 O3 d  D  w' O) B
7 X( R0 ~* C% e" Z& ]$ ^# k3 J                in = (double)output;; R/ A' i% m  e8 X0 q1 }
                out = (in - tmp);4 O1 w: n3 j6 Q2 i
                tmp = tmp + cutoff * out;
! `' K/ I4 O$ H7 }2 `% Q
% {0 j0 _  }8 N7 n+ ~                output = (INT)out;
6 R9 K3 G% |4 N, P                }  i" o7 ~# q  r" m/ j
#endif
; y4 O9 p% c! X: c* _+ a3 z#if        07 U# k( @. ?  W: |; \6 @- m
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)3 |" V$ m  O( g+ f8 o8 ~0 Z
                {6 b6 z) C3 X% Q# M0 m4 h
                INT        diff = abs(output-last_data);) x. b8 T" D5 A
                if( diff > 0x4000 ) {
, V3 X4 f# C1 A- R, o; n                        output /= 4;; \2 x. w' W. ^+ W7 k. q
                } else 2 V) ~9 q! t, ?  ]2 a7 i
                if( diff > 0x3000 ) {
+ R0 g, Z9 l5 f9 }9 m7 u0 }# }                        output /= 3;5 k% _8 u/ P. j
                } else: _  y+ G' \! I: a/ Q( U
                if( diff > 0x2000 ) {
! Q9 T7 f. k+ ]; \1 [6 Z' G                        output /= 2;
& M1 R7 a( G; H4 K* h7 y9 K. A% M                }  J" I  A1 j, @  k
                last_data = output;
/ `+ B4 _4 A# q1 L& n; L                }
( W1 ^+ Q# Q$ v8 {" `: R#endif# |9 y5 E* w/ x6 m, O
                // Limit
) y' w- x/ q, s5 J8 t" H. h                if( output > 0x7FFF ) {
7 V) |1 U+ t9 F! ~6 a                        output = 0x7FFF;& h: K$ c% [- O7 ~
                } else if( output < -0x8000 ) {3 F8 S6 `0 G, Z5 b+ ~
                        output = -0x8000;
6 ]0 s4 j1 e) Z0 o1 X                }
. q& M, |) q) o# W6 ~) |: P3 g, F' l
                if( nBits != 8 ) {, q' @+ J# b/ \* X" x6 ]' v2 j
                        *(SHORT*)lpBuffer = (SHORT)output;# F+ |4 C4 U' {% K. X  e& g; w
                        lpBuffer += sizeof(SHORT);
4 }8 I& {- E: d6 B) F4 E5 `* N                } else {
) U9 `# {7 Z: a9 T                        *lpBuffer++ = (output>>8)^0x80;* i; R. o) N3 x! n; l" }
                }& c# g7 f; s& q- _( A* V7 D
* R& l; y6 A3 B; h! l- j1 i5 ?
                if( nCcount < 0x0100 )
6 x5 P: V- a" g, s                        pSoundBuf[nCcount++] = (SHORT)output;
6 Y  L* F" k9 R% Y. |6 l& V5 ~, m) c( I& m4 M5 A9 I2 g5 a$ V# r
//                elapsedtime += cycle_rate;
5 e+ a. B# \" L: H/ K5 a                elapsed_time += cycle_rate;
5 j  P5 Q$ v3 D( x+ T& M        }
, w# Z4 a( s, O! I' a9 B8 i
$ N2 m9 e4 Q3 Q& K, h9 I" O9 _7 A#if        1- O$ e: w# y3 W& f3 F7 j7 u
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {; L6 U# @2 @; z6 F
                elapsed_time = nes->cpu->GetTotalCycles();, u9 Y- G7 h# [9 a# X9 A% q
        }
% F2 @! U' r7 G4 h( }        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {1 \* p0 Q/ m& O$ n7 {
                elapsed_time = nes->cpu->GetTotalCycles();
3 }6 a1 f7 R7 c' ?9 m        }; {8 K6 o! J. Y* a! E
#else
1 r% J3 D/ J- u5 x  @        elapsed_time = nes->cpu->GetTotalCycles();
4 j& q* H7 T, q2 C5 ?, |4 h#endif0 U1 R  z; t1 @- D% v/ [' ^
}5 f$ X7 F; [( W/ ~' c- t; r

3 v% j8 {" t, \  a7 |& x// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
% U# S/ S: L+ ^$ GINT        APU::GetChannelFrequency( INT no )
# `$ G4 n$ I0 S8 [( e$ @8 K3 T{
+ R  Q5 R7 K0 k1 R        if( !m_bMute[0] )
4 f0 {. D1 r$ A7 b' ]5 ^0 Q                return        0;
, g6 J3 H% @) d. T3 g  y: {
$ @0 R9 o' a; d3 G1 L        // Internal: m! U- y7 m! i. V0 d+ z
        if( no < 5 ) {
% R+ p: f& w% ?/ y* Q3 R: O" s( q; M                return        m_bMute[no+1]?internal.GetFreq( no ):0;2 ~3 e: c# [1 O, n% r! A- |
        }
0 s0 K2 d- P4 r$ k9 |' _        // VRC67 S$ x6 j+ g: l9 {% v3 Z4 m9 Z
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
" m' U% W2 X* E/ W/ t                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;( K. ]& P$ w9 d* y6 d
        }
0 @/ x# y: K" o; t        // FDS
. k' n8 h/ E$ y2 \4 g9 S- T        if( (exsound_select & 0x04) && no == 0x300 ) {
2 D' t& c' s9 h- y                return        m_bMute[6]?fds.GetFreq( 0 ):0;
: X& x5 y- y" V4 E' }        }$ H( b1 M* u! j( h
        // MMC5
' y( n, `. H( g        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
, |2 d' w4 G& K                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;, w' a2 Y$ N; X1 t
        }/ H+ u( o& s1 O& g4 s
        // N106
+ `; q- P' V  o1 [' L( ^" A        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {# c' T9 J  t6 b* l: M3 M( u
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
9 S5 p  l' }& E* D4 u# ~' ]        }  S$ X+ _) F8 L6 d3 S3 d. y- R& s
        // FME7+ v" ]' S, Q3 t3 |: u! `% `
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {, H5 g2 H7 A6 t% ?$ R# Q+ J$ y% R2 e3 D# }
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
! w7 e6 l. S7 f        }
* F* O5 f5 v+ d' k        // VRC7
& y% S* b& h7 P' k6 u) u' |        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {  t5 M; |3 _% X3 t& F: R# G# U& }
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
7 `* f: a* v* S& D% N, _        }- C; i3 s' s3 F7 I
        return        0;
4 \3 `" R! R9 b( ~. s6 G$ v: w3 f% ?}/ }2 `9 x/ Y7 W8 U; Z- V% }
" \) I9 g! k9 v2 w( j
// State Save/Load$ C. W* Q( K2 p
void        APU::SaveState( LPBYTE p )
% |4 {9 P1 c& x' U8 U" p+ \3 `& q{3 J" z$ L+ o. m
#ifdef        _DEBUG
' H  F% B+ W- u0 _/ w( hLPBYTE        pold = p;
0 Z: S9 c! t! z' i9 B#endif. A, n9 C: T# x" ?* O

2 e( }4 t, N+ [        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
- g; e5 p0 \4 I9 l        QueueFlush();
4 |+ g+ Q: p# {4 {, B
, a) Y* P; _2 W" ~        internal.SaveState( p );
+ a& U4 ]* r) _! Q, C% e        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding7 N" e& a9 T0 x/ G7 Q: N

9 f* k2 O9 y, p1 F! w        // VRC6
$ X! c6 h3 v/ l9 h; E        if( exsound_select & 0x01 ) {5 w8 H6 d; I0 {- ~8 H* h
                vrc6.SaveState( p );; X+ k" W) o; a( U5 i& u. D2 x8 J
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding- j( ^3 G6 o5 z+ U1 r
        }5 \; t# Z* n/ Z8 E2 G, E, C. `: a
        // VRC7 (not support)
. a/ k# ]8 r. M3 i# n2 \9 T' G        if( exsound_select & 0x02 ) {* x9 ~; T4 T9 o% H. g8 t
                vrc7.SaveState( p );
4 f& T$ ]7 f. a+ z                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding4 i, l5 f+ `+ N8 m1 d
        }4 L4 p+ w, c: w
        // FDS/ F% D4 t5 g# g% V0 i9 e* N
        if( exsound_select & 0x04 ) {; p: g( x$ P: Q" Q) w$ h- y
                fds.SaveState( p );
) \8 }0 E. Z6 u                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
  Q! T0 V/ G( @1 T" \        }# J+ N, D: ~* `# C7 K9 o
        // MMC5
# @8 Y' N0 j0 \        if( exsound_select & 0x08 ) {+ p: y1 {0 G" n, e- c' H( i, `" s
                mmc5.SaveState( p );
( v* J8 X9 }- f8 U3 j1 T                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
6 u5 l9 y7 B& F0 c% n# o0 |        }% V8 c' ~; \- Q+ ~( B$ Z  X
        // N106
' y6 n4 \' m8 q# Y# G- B        if( exsound_select & 0x10 ) {- Q0 i- M, I; y$ U
                n106.SaveState( p );
' f! H* U8 w) N. q+ {- d& w                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
9 b" K1 `2 f  S$ N5 I/ T" B% c+ W        }6 u% n7 X' @& A$ h, b& [
        // FME7
0 n. u3 E( `0 f( ~9 }9 b        if( exsound_select & 0x20 ) {
, c& l- N' B2 S+ p0 j                fme7.SaveState( p );+ ?+ U  m1 I0 y0 Q( U: e
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding' P1 W5 d/ N) v9 H3 M8 l
        }8 a# V5 z, [% g
( W/ v5 T9 c/ ~: b& H. o
#ifdef        _DEBUG3 W- Z; e7 `! ?! f# o, D6 |; H
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
. t' l; Y0 ?9 o8 C#endif
( T3 G/ a* l5 o* c}5 }( I3 x! N" {) f
* n* p1 l! C- l
void        APU::LoadState( LPBYTE p )
7 ~  j% O. h% s  |! ]. k! o+ v{' @& Y8 `( q" H2 l8 y9 b$ e! |% ~
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
2 n+ {! B& `0 |- }9 `6 g9 f9 k5 Q( B        QueueClear();9 c# F2 o- n' H. e; d5 G

+ }2 q% d& N; T, w; S        internal.LoadState( p );
; R; p  ~$ _7 z( ^+ w        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
1 Z7 y* i" X$ c8 J) S& |+ x: h0 @4 O
        // VRC68 {! {  R: I+ w: J8 [% a
        if( exsound_select & 0x01 ) {
  V- }$ G% |2 H/ p, r; P9 C                vrc6.LoadState( p );
5 }+ u& Z3 y/ |                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
) E. @1 {% w8 A7 x        }6 N0 E4 J6 z: T) \" J0 j: N
        // VRC7 (not support); t7 X3 v8 d$ x8 a/ L" e- d" f
        if( exsound_select & 0x02 ) {6 a8 c8 ?1 F" A4 u+ E, s
                vrc7.LoadState( p );, l. P% M- n1 N0 y. @' ~
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
3 s/ Y0 y6 i( L        }: c$ Z, {2 z- b7 K# I  _
        // FDS: s3 n1 L% n7 a  o
        if( exsound_select & 0x04 ) {0 K) b( q$ S1 ]% b3 I' ?
                fds.LoadState( p );: }1 M4 l9 \1 q2 N/ l0 \4 N
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
* z; r2 |" d: a/ e. }4 X        }
6 Z) {0 u; i' s* X3 K" c# L4 G        // MMC5+ b! s' v5 \: ~, I# K
        if( exsound_select & 0x08 ) {7 f( M  g9 `" i; A4 F( p
                mmc5.LoadState( p );5 M: C2 U; D' A; r' R* U, x
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding; r& D; y: m+ v; n5 j0 y) O
        }  t7 y' A# d3 \; M4 k- J4 l
        // N1069 {) l7 u8 n+ ~. f1 [
        if( exsound_select & 0x10 ) {
% g$ c: j( Q7 N  L/ c' X4 o                n106.LoadState( p );
  }& J$ B! Y& p1 @$ d                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding! _; X; U2 W5 ~$ B2 l
        }
7 M* c+ C5 ?  C, T4 W, V# x- _        // FME7
3 y& e& `# r" }% `        if( exsound_select & 0x20 ) {$ l+ N+ q8 U  d
                fme7.LoadState( p );
  R1 l% w: e1 A5 t                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding, O8 w# J$ d# {9 R5 V" n
        }% e3 p4 w% ]: }9 l) u, o/ k  g
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 9 i  n7 X! ~7 j1 R
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。1 x( s  Q6 k( e2 Z! X! a7 P
感激不尽~~
1 ^; B& V5 |3 m5 e/ ~4 i1 o
恩 我對模擬器不是很有研究,
$ G" a9 l4 q% w6 D& F8 [雖然要了解源碼內容,可能不是很困難,3 r. {8 L% i/ }1 _/ L, c
不過還是要花時間,個人目前蠻忙碌的。
! h, h+ i+ v7 Q2 t$ ]8 |4 s3 c, S9 R
給你一個朋友的MSN,你可以跟他討論看看,
2 m! Z& N5 h& r' v8 V- a他本身是程式設計師,也對FC模擬器很有興趣。
, B& j  l( j3 [, l" g3 @6 r# n- g" S) R6 I
MSN我就PM到你的信箱了。% Z1 n8 h6 g. B/ i% J* o8 _

; T3 Z. I0 Q, y9 S5 P6 ^: G, @' 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 发表 ! x. j% C$ J  H- X+ J1 h
呵…… 谢过团长大人~~

0 Q, o5 U" t& D1 B
! r- ?: l6 @* R; J3 E, e哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 # b6 j* O. L) c& S- r& w
团长的朋友都是神,那团长就是神的boss。

! O  c9 F5 O( U6 b+ E哈 不敢當,我只是個平凡人,
- C3 v7 d- |1 U+ A要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
. f( ~4 C8 J, a; hZYH& L2 [' R2 `, D4 j" c% P& A
QQ:414734306. ^, A% c& \8 ~2 o% p- C6 x
Mail:zyh-01@126.com9 E; G7 Q: G/ T0 S1 o. H

$ A& ?5 x) w; S/ S他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
' p' ]7 [8 t& H8 }* [; }5 K. G% i6 [再次对团长大人和悠悠哥的无私帮助表示感谢~~
) C# P/ f0 P: H7 Y( y8 h
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-25 00:53 , Processed in 1.107422 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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