EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?% T! _4 }' i5 }7 S8 Z& T: t  {7 ]1 n
PS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
  g1 ?* L7 U' `+ c3 W; P楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~; h4 g4 F0 D1 N4 K/ ^! N
这里有相应的模拟器源码,就当送给大侠了~~
! y0 T9 B' ~) P) E5 k6 Whttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 ; O/ l! o# S0 A' g+ ]
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。0 q3 o# v$ p" ^3 i+ _
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
$ b9 Y* o9 L: @这里有相应的模拟器源码,就当送给大侠 ...
  C$ M4 i# X, `
聲音部分(Audoi Process Unit = APU):- R: h$ p7 j& Q/ E4 z
.\NES\APU.cpp
- H6 c2 i& m) e0 Q% K/ A.\NES\APU.h
; _5 w( N" L' c5 R8 h3 U3 y! ~, @% }1 o5 y0 J
! y* U( G9 {6 R  w6 ~
影像處理部份(Picture Processing Unit = PPU):0 o$ A# G, S3 J, r" i  m" O
.\NES\PPU.cpp, }6 k. L" p# U8 @$ ~' S& W( x" j
.\NES\PPU.h
" N( T/ t# z0 |) h! C* Q* e, A$ Q+ m8 G+ q/ d2 d  [; r4 a, j; v
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
( @2 [. ~% ~- f* |4 x" c2 w+ e" I感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
, F/ r2 E: {# Y  G$ c5 E& d(由于很多专用术语和算法机理都不明白,所以看不大懂……)
2 l7 O! C. v2 k//////////////////////////////////////////////////////////////////////////0 A- P% T! S9 G8 a7 |) w6 w2 C8 }
//                                                                      //
/ P. j* ?9 f6 N# H//      NES APU core                                                    //+ ~% |7 J+ C2 r& H  ^
//                                                           Norix      //
3 S) D1 k( y3 b8 p0 H7 L//                                               written     2002/06/27 //" s5 \: e2 d; P$ h1 B
//                                               last modify ----/--/-- //$ n( N8 `- T! K% t: a. \
//////////////////////////////////////////////////////////////////////////
: ^/ d' Y8 H- o% {' f+ Q% W/ a1 G#include "DebugOut.h"" w3 i  ]* ~3 V; S
#include "App.h"
1 A, m4 _6 C* B9 [4 ]- H9 K#include "Config.h"6 K! V" ~  y/ e9 k# `5 q# l4 D

8 `6 X6 j6 {0 n! J1 ~( O( w& M#include "nes.h"
7 J2 V3 |) B1 z+ b" M& L! Z# m#include "mmu.h"5 c* [" c" g, l$ q' h# ^+ G
#include "cpu.h"# D% t8 t  @. f9 ]. {  }  \
#include "ppu.h"" p/ }( C2 S- z2 Y
#include "rom.h"
6 w" ]0 g* j! M  Y: q! f1 t9 r: A#include "apu.h"6 |, K! f$ V" z2 b

4 c, w5 k7 ~( O) p// Volume adjust1 Q( ~7 ]! I, P; G8 C2 V
// Internal sounds
4 U$ X4 ^9 s( U% K! M, _  [! U#define        RECTANGLE_VOL        (0x0F0)0 ~+ J0 `2 o: s' V) C/ I+ t
#define        TRIANGLE_VOL        (0x130)
/ L/ V) D2 N+ \8 Z7 G& L#define        NOISE_VOL        (0x0C0)- ?4 R3 I5 {9 p8 K9 C7 d
#define        DPCM_VOL        (0x0F0)) d2 {0 Y$ I" F7 s
// Extra sounds2 J% I) k3 _+ j
#define        VRC6_VOL        (0x0F0)' u7 Q; k& d2 v1 ]
#define        VRC7_VOL        (0x130)
; Q3 ~" m, U& u" z5 p% t#define        FDS_VOL                (0x0F0)
% n0 q6 W, \3 f8 }$ _7 z% X& b#define        MMC5_VOL        (0x0F0)3 B: c9 s5 h- d/ X( j, V8 _! o& P
#define        N106_VOL        (0x088)8 H9 R7 r- L, x, ^9 i# h; r
#define        FME7_VOL        (0x130)
0 z$ p4 r& l$ `* F; l6 R4 ]9 x2 D4 A4 [# z
APU::APU( NES* parent )
" G1 M; Q) V2 A. n1 R' \{" y9 U+ o4 r, R" \  p  y. n
        exsound_select = 0;
5 v4 n3 j( z8 W" q( n  |: W, d9 E( ]* }
        nes = parent;2 P! C- K* U" Y
        internal.SetParent( parent );' s( x/ {4 q% L

9 a* a" J4 N) h% ]5 d        last_data = last_diff = 0;+ k3 A9 e+ d9 \2 ~0 s" m, L9 {
* `% ?7 ~  a$ x- r  }! y
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );% z0 D& j/ n; U+ ]  g/ Z* ~; ]

. z" Z( L) z9 Y0 f3 \% U        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
# F" C+ V# Z9 u  T7 G  a        ZEROMEMORY( &queue, sizeof(queue) );, V. \: V. \0 f0 x
        ZEROMEMORY( &exqueue, sizeof(exqueue) );- X4 V. Y3 ^0 P7 @

4 T9 F& l! G% V  {1 N        for( INT i = 0; i < 16; i++ ) {
* L& |0 ~2 X* N; [                m_bMute = TRUE;
/ w* s  P- g  @3 C0 c( U" M8 C        }$ X/ d9 ?  e  A4 o3 e9 Y
}0 }  o+ u; s# x1 Q5 H
4 d* n/ W) O# q- w; D
APU::~APU()+ ^; ~- X7 z6 J' C8 f
{3 N% r& y+ }- h: }8 }
}
0 ~8 X- N# D/ i4 ^* \
  \7 e& J) G. d$ Uvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
. w4 ~  B0 n- _4 A{% D9 x1 e; w+ P
        queue.data[queue.wrptr].time = writetime;
! z* ]$ u' Y! ^' n) T7 R7 j) u        queue.data[queue.wrptr].addr = addr;
+ ~. ~$ T% u7 X1 E1 ?9 A/ z6 C        queue.data[queue.wrptr].data = data;( R+ Z; K: {) x* c5 ]. ?. G; t
        queue.wrptr++;% B* _3 w* c6 B9 e5 c
        queue.wrptr&=QUEUE_LENGTH-1;
! Q! N, N( N. E; o4 x7 T0 }  |6 F        if( queue.wrptr == queue.rdptr ) {" p$ u7 d5 @, Z
                DEBUGOUT( "queue overflow.\n" );
% d. `% V# N8 n- |0 ~( [        }
  ~1 {. \0 S4 S6 Y9 K, l8 y}
& ]' s! A9 z1 _6 I! A5 I: E0 m: r" G; E! d$ l* b
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
; T$ m- n: l; u3 @4 H: e% G{: ~  Q2 j  d/ N9 k2 @% ?
        if( queue.wrptr == queue.rdptr ) {6 u# M  P- G  W3 g! _8 }( ?# u( n
                return        FALSE;
0 y$ M, H3 |' Z1 x4 |        }3 G$ D- S! X5 _) J3 l' c
        if( queue.data[queue.rdptr].time <= writetime ) {3 z! H4 a3 X8 H7 [) D0 r
                ret = queue.data[queue.rdptr];; Y7 T; f: P: i6 o2 L4 \$ ]" |
                queue.rdptr++;
6 P, u+ |+ j2 {4 r                queue.rdptr&=QUEUE_LENGTH-1;: X" A# [; P1 ~) z# X: @; y! d# g
                return        TRUE;
3 J2 |/ _1 T( ~( e6 i: Q5 P        }( H# C% y. d) w4 O2 `
        return        FALSE;7 Z. j0 k9 n$ w- A) Q
}
" \3 Y  s* O' o7 P# |' |$ T8 y, U! B1 g
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )+ Q/ k, B; W' e( a' q8 @% i4 o
{+ r9 Z& T7 Q7 T/ w$ T8 ^
        exqueue.data[exqueue.wrptr].time = writetime;& \9 _) O1 L# k7 N5 R
        exqueue.data[exqueue.wrptr].addr = addr;7 O  [) S' {( H" E
        exqueue.data[exqueue.wrptr].data = data;; Y; a+ Z, ~. `7 ^- i1 D+ E% _
        exqueue.wrptr++;# v9 M! Z! }: T4 r$ n- D
        exqueue.wrptr&=QUEUE_LENGTH-1;  V6 r( o8 }" x, p+ c# b# ~
        if( exqueue.wrptr == exqueue.rdptr ) {
5 e- Q! e, N, y, t2 t9 {% s( r- P5 u* Z                DEBUGOUT( "exqueue overflow.\n" );' ?$ E  g1 I2 Z7 A& b; q
        }/ I6 e0 z! @8 e+ O5 V
}2 |5 f0 w4 S; e% q' f! r1 T2 `/ e
9 F8 F0 M* N; T: H/ ~& [4 A
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )9 O: h5 B. t( y- w
{9 V. [0 u0 ?$ ~1 }! D6 {/ L+ g& Q
        if( exqueue.wrptr == exqueue.rdptr ) {
$ T! S; e$ ]& x% l1 @                return        FALSE;
* x: F/ J9 t. |2 ~, k( u5 {; e9 N        }- z( S; P! G8 y3 t0 h
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {( e- {3 L3 C' |0 j! u: @
                ret = exqueue.data[exqueue.rdptr];/ U& ?. I& A) q( w6 i
                exqueue.rdptr++;
, l3 l: M0 U6 F" E3 p; E  y                exqueue.rdptr&=QUEUE_LENGTH-1;
4 n  ~& V8 p. ]0 l                return        TRUE;
1 T3 E% w& {3 N& F( B        }
4 U! e' ^# d! ~; O7 d        return        FALSE;. `9 a/ n0 y# l& @/ `; u% G& D, Y/ E
}
$ N; R% u) [7 D. Z1 d/ _% b% h1 o' `7 l
void        APU::QueueClear()
9 F3 n2 n% n% q9 \5 C/ r4 p: n{
- h$ Y2 C* w4 g. D; z        ZEROMEMORY( &queue, sizeof(queue) );
! |7 n) E/ G) t        ZEROMEMORY( &exqueue, sizeof(exqueue) );8 P# C$ _, V  T6 y
}
6 a9 z* U. o; R6 v& |' ?, u. \7 K" x# g/ j' G7 N
void        APU::QueueFlush()& @3 [! l- R  z4 Z9 E4 r. G
{
! P0 L0 r( J8 E+ C3 C9 ^# a        while( queue.wrptr != queue.rdptr ) {
' I7 W# }5 C# q                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
& c# {- T' m, b; z                queue.rdptr++;6 x, Q: S2 s6 o# n- d' T% {
                queue.rdptr&=QUEUE_LENGTH-1;
2 V- E7 k' B- [& ]  q        }1 I; ]0 h* T4 @: [2 b
; {& E* F' I! K& M
        while( exqueue.wrptr != exqueue.rdptr ) {" H; b0 j; k( c. h, G4 V
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );7 p* I% ^- t/ @. {
                exqueue.rdptr++;
7 ]3 z9 N9 @. Q( k                exqueue.rdptr&=QUEUE_LENGTH-1;
6 |. i) J1 Q; j: {: D- y. U        }
6 m8 i5 @& o9 R' a}
; t+ E5 n) ^; ~( c- J1 n1 c
2 u( M# X, m4 ~+ U5 C" o' }! Dvoid        APU::SoundSetup(): S. |+ |4 T  T, R. C
{4 L! p$ @. v& d. e
        FLOAT        fClock = nes->nescfg->CpuClock;! J+ o  D9 b0 L# ~7 {
        INT        nRate = (INT)Config.sound.nRate;
9 B9 j+ d5 V0 R        internal.Setup( fClock, nRate );& }: |6 s. v  W! H9 J! `# y
        vrc6.Setup( fClock, nRate );
+ j+ r% ]; i3 P" f$ D: g4 `        vrc7.Setup( fClock, nRate );
8 q5 B0 K$ w# q; U        mmc5.Setup( fClock, nRate );
6 p( P/ E9 o  {) `% Z8 j        fds.Setup ( fClock, nRate );
5 Z! z) A, v' q% {0 r5 E6 w        n106.Setup( fClock, nRate );7 U2 r9 ~  K) m' g  P
        fme7.Setup( fClock, nRate );% ~! U7 _) G, G. H! o9 K
}, e6 g1 M; {$ `; A8 T( h
4 e% ~, H; O, }% a1 N9 H  I$ S
void        APU::Reset()4 r1 Z  B# D/ ~8 j0 U! T
{
) t) f( k  U) S/ I1 t( Z8 g: S        ZEROMEMORY( &queue, sizeof(queue) );! j+ e4 t* t6 y. t  H
        ZEROMEMORY( &exqueue, sizeof(exqueue) );2 L7 D& T$ O1 D# m
3 e4 }( R; c8 c. P3 M7 B
        elapsed_time = 0;
$ I: D! ^/ G- j& C) p* A! z+ Q& o8 n# [6 P# N
        FLOAT        fClock = nes->nescfg->CpuClock;
7 U8 \! a) u0 y" W/ ?5 U        INT        nRate = (INT)Config.sound.nRate;
! K/ C+ U& L$ [5 p: g9 m        internal.Reset( fClock, nRate );. I& b. R/ S8 W! k: J9 d
        vrc6.Reset( fClock, nRate );5 B. [$ x$ b' B" w
        vrc7.Reset( fClock, nRate );/ [- R9 N6 f; @8 f9 X4 h  v5 e
        mmc5.Reset( fClock, nRate );! [6 Y8 ~) |$ t/ h, h
        fds.Reset ( fClock, nRate );- b: }4 V' w- w: ?; G
        n106.Reset( fClock, nRate );9 {2 F6 w! y6 p) i; Q7 U- A
        fme7.Reset( fClock, nRate );
* Q* {! u  f7 C+ I
5 G& c' C! ~" n5 U" w        SoundSetup();7 C) n5 D7 n8 F" T, x+ \, I
}
3 v6 V1 y+ L+ D/ r0 q
5 N) k0 g3 g' G5 }8 B2 e; E/ [7 Qvoid        APU::SelectExSound( BYTE data ). Q- f, r2 x! q' ^
{
. s' @/ M6 y8 |# _        exsound_select = data;
4 D" j& d0 ?2 n$ M- {}0 v. E6 O# Z& l( O5 l

1 f8 e# N9 W# ]/ P3 s& j, d4 z% Y! rBYTE        APU::Read( WORD addr )
* V+ O; z. v+ K8 O7 x3 Z5 V0 z+ l{1 U, s' Y9 U% S
        return        internal.SyncRead( addr );9 k; t# L& z! }1 x8 I" I$ z* ^% g5 A
}3 H: j* m3 m/ \% N% q; p
: W$ `& S/ g( E& [, i$ M0 J
void        APU::Write( WORD addr, BYTE data )
% s. N- n  H( ^2 M' S& B, K{
6 |; }5 C* X/ O0 ]# a        // $4018偼VirtuaNES屌桳億乕僩* y' t* h+ Y: M9 N* P' J8 w
        if( addr >= 0x4000 && addr <= 0x401F ) {
' r$ ~7 G  I" F' M                internal.SyncWrite( addr, data );
/ Y+ D- c$ \9 A# h' _. @4 S                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
, X# M( r' s- P0 x5 U        }
! X' U5 @/ E: z* l* B}( W8 Q3 c, y! x# E' l

: B! @# A3 B8 N- {6 j+ ]$ xBYTE        APU::ExRead( WORD addr )2 z" L' [0 e, e/ w6 n, X0 H
{
3 `6 i1 H0 U4 x8 K& |" ?BYTE        data = 0;
$ S* c6 \4 U1 V* |1 {
3 P8 i0 z9 x. A4 W        if( exsound_select & 0x10 ) {1 S, V% v5 S8 F( }: T" U
                if( addr == 0x4800 ) {
( H. Z& [  C( X  l; ~                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
, i# @3 i6 D2 U& t                }; `5 L' o  c9 Y+ e1 j, N
        }
/ V2 {: |  r9 K& ]  p        if( exsound_select & 0x04 ) {
* N" |" x  P" O% Y2 v                if( addr >= 0x4040 && addr < 0x4100 ) {/ `1 C  h, m3 I
                        data = fds.SyncRead( addr );9 n; `) t' e+ m% k
                }
7 c4 Y# }5 k! m2 @' H! ^& j8 t8 S        }
  b9 j  ~$ s1 c+ C# d        if( exsound_select & 0x08 ) {
" q8 N- l: Q. K& a9 L! h6 f                if( addr >= 0x5000 && addr <= 0x5015 ) {( X) g8 p$ m' K! U8 K
                        data = mmc5.SyncRead( addr );
) W6 J2 P6 Q' ^$ b4 ~! {                }
! p5 H; q' ]9 B. L        }$ S+ H) S& T0 a8 U' ]9 Q' @

% g+ Z3 b/ D/ h' r- ~" Z        return        data;
, o6 h( m8 f! \  i}  n" X7 z  ^& {: o- f1 B! q' {7 [

# b, ]) E3 ^6 y  S! Wvoid        APU::ExWrite( WORD addr, BYTE data )/ g. C/ r- h3 B  S9 X% c
{! Q3 V6 p4 ?" n- W
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
1 k. W* w# k! i1 C; Q0 G2 h9 L$ X- k7 i( U2 a
        if( exsound_select & 0x04 ) {, x+ c6 ^9 a  B
                if( addr >= 0x4040 && addr < 0x4100 ) {$ i% R* }0 T1 W0 \
                        fds.SyncWrite( addr, data );
& J# }  u) N+ H1 h                }
1 X& ?; |# z6 N        }( `6 Y9 L0 M; k5 n

% M# q) u7 @& F3 O2 j9 ?        if( exsound_select & 0x08 ) {
0 H8 X/ R& J0 P0 L                if( addr >= 0x5000 && addr <= 0x5015 ) {  {3 Y: q* j/ I
                        mmc5.SyncWrite( addr, data );% k7 W( T8 f1 p+ T
                }; F4 V2 e0 P% @* C! O; m
        }  @/ C4 }, O" @1 B
}5 t. E2 n" Z1 Q. F
. z0 `/ u% h; R: N% J
void        APU::Sync()
# ?. |9 B+ l" W+ t3 b. Q{
% }0 b4 d# h2 C- Z( [" x}
0 T. V/ X- U- q/ ^. {# e  d  t* l1 w  i
void        APU::SyncDPCM( INT cycles )3 E- e; Q  |5 {
{
/ S: N0 }; l& `' r5 |' \        internal.Sync( cycles );
; N6 T* \: ?: K8 o9 a/ i7 F. z1 I
        if( exsound_select & 0x04 ) {
6 G! F, f! S; r1 W( q1 f5 b, a# O  q3 F, h                fds.Sync( cycles );) M1 h( s) q4 @# ^
        }
4 I: N  T$ }0 T        if( exsound_select & 0x08 ) {# a3 _; \+ R7 I+ R7 E
                mmc5.Sync( cycles );
3 q3 Y3 @6 |4 G0 M        }( c8 v# y  u. Q; |0 f' ]
}2 K- E( c2 \. F, u, x) O' ^
& s4 [$ ?& T9 ?! R2 j: a
void        APU::WriteProcess( WORD addr, BYTE data )
8 r0 Z9 M! f. I! X{% d! k3 L! \& G8 \5 f& ]# V
        // $4018偼VirtuaNES屌桳億乕僩
; B# V( h# y* T" V( A# Y% h! J: a        if( addr >= 0x4000 && addr <= 0x401F ) {
1 B# ?4 {7 I- u3 p! I+ w                internal.Write( addr, data );
; f) {- d- Z; G8 e0 N. W+ A. \        }3 D6 w9 A0 A1 b$ K" f
}; l( \; a+ k- t* r- g: S

+ L( ?# W( X- f! ?6 p, f5 @/ Qvoid        APU::WriteExProcess( WORD addr, BYTE data ), J$ v5 F' P5 {! r8 J" y
{
. J, G; o4 H: @" _        if( exsound_select & 0x01 ) {  `/ F: A- n. Q/ [9 e  \( x3 c
                vrc6.Write( addr, data );# ~/ ]* q, v. b+ d0 f! }
        }& `& P% ?4 f8 W1 H
        if( exsound_select & 0x02 ) {6 [$ A( o; T4 |! [
                vrc7.Write( addr, data );  X6 p2 e. z. Y8 J& [$ R
        }! z0 w' d+ c# Q; E
        if( exsound_select & 0x04 ) {
) v+ ?' L- T6 _0 t9 `1 b                fds.Write( addr, data );+ J$ R+ V* n( B$ L/ Y. l* Q: V1 Q
        }2 K0 F/ z! u0 f  O- w6 h) V- q
        if( exsound_select & 0x08 ) {/ v" \5 D2 u; a; P8 m
                mmc5.Write( addr, data );
, E# E' k+ l7 s; G# s& d7 F/ c3 j        }0 o8 v6 e) g0 n9 S, v2 X
        if( exsound_select & 0x10 ) {
' L  q1 h8 k4 a9 n                if( addr == 0x0000 ) {
6 D& j1 N; y8 c* Z7 M                        BYTE        dummy = n106.Read( addr );
( C! l8 ?: V8 I                } else {: b1 @2 ^! u/ r5 M8 E9 z7 Q
                        n106.Write( addr, data );
% ?: K& Y' e; }8 k4 `; `                }
8 [* \: M) t$ u1 u        }) `* u0 e# ?, m. ?% d
        if( exsound_select & 0x20 ) {
4 U: t, l9 K" V& _) b0 @: _$ ?                fme7.Write( addr, data );
% q0 E* p& z+ f, A8 r        }
  y4 J* @/ p5 M6 p}
, }# n, E* [, P1 z) w7 o! F+ V
; M2 D0 s4 G7 t- q9 m% B: U9 [void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )' c$ [1 f/ |5 v9 w- W  j* T- K
{$ L2 l: x$ O; Q7 J$ g/ v
INT        nBits = Config.sound.nBits;+ w% O" P; T' g: q; q
DWORD        dwLength = dwSize / (nBits/8);& r4 w0 C* s/ J  W
INT        output;; v: L5 I, |1 K! ^1 a7 e: e5 H
QUEUEDATA q;
+ x- m8 q3 V; N: \+ ^7 R0 NDWORD        writetime;' ]3 s  O; P( q/ f: N# H- M' t& s
* L( z, J% Q( [, v
LPSHORT        pSoundBuf = m_SoundBuffer;' l2 ?2 k9 F. }* E" y
INT        nCcount = 0;5 \+ z! a4 L) x) K+ K2 |  C! H
3 n  T) F! {4 v1 Q0 T# ?$ T7 e: H3 B
INT        nFilterType = Config.sound.nFilterType;5 b  T& G2 G5 R9 y: M( H5 M
" n3 ^) L0 U! i0 J
        if( !Config.sound.bEnable ) {6 a2 z% J0 f. y6 Y2 @7 n2 S
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
" r2 G' U3 [* I$ y+ j- }7 v                return;
! f# [" U6 G% H0 x6 B7 I8 a        }
! ]  V# c  k! b6 w# [+ _' ~7 G4 v! _* E2 B3 m- k
        // Volume setup: B2 q, T! P2 j+ \8 D& r
        //  0:Master1 v3 V8 o% Q" Q1 B
        //  1:Rectangle 1
/ F* e3 D8 d8 H        //  2:Rectangle 2
& r; t  Z0 @( u' Y6 D# b* h        //  3:Triangle. V$ w) ^) u4 P+ k6 H
        //  4:Noise$ h- j- D; R9 ~" }, J# u4 a
        //  5:DPCM9 D. v+ b  m% O1 ]( J2 K) O: y% L
        //  6:VRC6/ v; H' ]- K9 ]) e7 O
        //  7:VRC7( I; [, c  B- S& ?. Q! |
        //  8:FDS  |' I! }8 `4 v! \# s% _! H
        //  9:MMC57 s  \+ t4 {; s# \1 M8 `
        // 10:N106+ `" k$ E, C! K' c! @9 f- l0 [
        // 11:FME79 o) g% R: r7 ~5 @9 X+ P$ \, v9 G1 x1 A5 L; h
        INT        vol[24];& c5 R& S( x+ w' l
        BOOL*        bMute = m_bMute;9 q  @) r, J/ z, J
        SHORT*        nVolume = Config.sound.nVolume;  g) ]9 i( n5 W$ |% I
5 h6 \+ `2 {2 y9 J' Y* P! g
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
' l+ d" f6 `; ]' W8 ^9 f
3 N" ~" p$ N# y- U- D3 d        // Internal+ E1 {2 u4 q9 d; s* I5 y$ ^. Q
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
; N: }$ w2 }. Q; g7 S8 n        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;3 I- t+ m2 a6 N3 B# `
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
6 T, n2 x' F( ?( u. g; U. r0 A        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
  W  r$ R7 g8 g3 S$ A% T        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
7 L; }! {+ ~0 y4 Y: J) d
- E, {" q# i! \$ L        // VRC68 Z! p+ r* m2 ?+ H0 F% `
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
* F, S- G! t( a        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
" X5 A# k1 M- w/ ]* g* y7 B! x        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;6 ~0 n( k9 V! a, ?8 C9 Z. S
. e! t: y/ |" {& [! o
        // VRC7
! \8 g8 H, F4 N, H        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;5 u. E1 h, |) [1 O
5 E3 \5 d1 A6 S4 m
        // FDS; L  h2 ]( M+ K! Q2 x; p+ \- N
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;& m7 e. n8 e2 l' z
' o2 Y2 ~, N6 ]9 v. v
        // MMC5
- W* N6 R3 f! O        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;9 k$ m7 X; ^9 t& i
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
! Z& q8 O; x# U; f6 T' f5 z        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
/ b8 c; g/ {% n  l. O4 S+ [2 P
$ _/ g* U- n3 b+ r& P+ F6 C% }! _5 R; R        // N106& w, u. W, \' r; `3 h* u
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;6 ?6 x+ }) _5 `. r/ N+ }" l7 ~
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
5 {) {$ o: r& o+ ]" i        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
# Z, z7 R+ p! `8 O+ Q1 f0 B2 Z        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 r( D$ Y  Y, L  b! d        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;, X9 A) s; W2 o1 o7 x  E
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
  e9 {3 _0 _0 K4 h& L        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
  i2 P; @% T: Y        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
8 f" d, D" U# q) d( S0 n2 [* o7 z9 Z8 R  D& s6 y2 {
        // FME7
! n4 U3 p1 G% @2 n        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;3 w0 ?( o! Z# `' [
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;+ w' c: G( N' e' f: w( y5 w  j
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
/ C% |9 ?2 @/ {6 F5 ^/ W, u! d1 ]3 D8 f( G& {' g
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;7 d4 O% W/ z6 V9 K0 n
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;$ h( M6 N# d6 ?" S/ }% @/ ^' n# H

2 Q; C- }3 f/ D2 s        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟; a+ R$ H' _# {
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
. b6 w0 n+ }/ R                QueueFlush();
/ K7 f: J# `8 T' S, _        }0 L6 t7 Q9 Q  d

9 D6 h3 ?$ _1 ?        while( dwLength-- ) {
+ S# [' p5 A8 |2 k* z. @9 N( i                writetime = (DWORD)elapsed_time;' _% j, K/ b3 D* r

' @% }; K  \+ z9 }* z( M                while( GetQueue( writetime, q ) ) {
: k( }# ^, J. \9 a                        WriteProcess( q.addr, q.data );! [1 j% ~3 N- t8 f" O
                }
/ V/ \! _! a8 p8 f6 H: D4 y; w
, w( s2 y( U: X( a3 \  P                while( GetExQueue( writetime, q ) ) {
) r  _( \3 ?$ H. c0 t                        WriteExProcess( q.addr, q.data );
& u% y4 I3 F& [% P7 v- e                }+ E, {3 o0 `/ C$ F- A/ ?) A* C: V* E

5 n9 H% y4 F8 W1 v* _1 q& O                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7% s$ X3 X1 }# V) U' ]
                output = 0;$ B4 G( U& u' i+ h1 ~
                output += internal.Process( 0 )*vol[0];' V# W2 e' r# G
                output += internal.Process( 1 )*vol[1];
! p! J" _4 i4 r6 ?, \8 B4 D                output += internal.Process( 2 )*vol[2];
* S2 G2 g( b' {/ c6 B* N                output += internal.Process( 3 )*vol[3];8 n( k3 F9 Y1 D6 G/ ~
                output += internal.Process( 4 )*vol[4];
+ ]4 Z: p8 n# j2 H" y- C, r* T
. b4 m! d; T* `7 g/ J) p                if( exsound_select & 0x01 ) {
- l! J9 U' n1 H7 [! @" l                        output += vrc6.Process( 0 )*vol[5];. h6 L7 a3 Q  k7 Q
                        output += vrc6.Process( 1 )*vol[6];2 \3 C$ K' z, l) ~# {8 R
                        output += vrc6.Process( 2 )*vol[7];) k$ A9 y& e% }  {# ^* J
                }! i/ C$ _1 d/ h4 i
                if( exsound_select & 0x02 ) {5 W8 [- c( N* \$ Q, j/ ]
                        output += vrc7.Process( 0 )*vol[8];4 X- K. y5 x. z, {
                }$ q+ M0 U3 g2 m2 b  q' _& H
                if( exsound_select & 0x04 ) {/ R! E/ \" s$ b
                        output += fds.Process( 0 )*vol[9];2 g- ~6 x' J9 C1 X7 ~9 i
                }* [' B& A+ P) H5 n' K* K0 w" j
                if( exsound_select & 0x08 ) {
8 |0 g. H& H' N" Y. }                        output += mmc5.Process( 0 )*vol[10];
; ^. f# J1 n( k+ m+ W; x                        output += mmc5.Process( 1 )*vol[11];
9 {. a  C/ {2 g) I. z* @; K5 \                        output += mmc5.Process( 2 )*vol[12];
  I8 K& x9 v, M                }: z/ H) a8 h' B) T! e
                if( exsound_select & 0x10 ) {: _( v' G" p4 o3 \2 H
                        output += n106.Process( 0 )*vol[13];3 p- s) u/ l- ?5 e
                        output += n106.Process( 1 )*vol[14];% x3 o% E. ~9 q% n4 K" E" @
                        output += n106.Process( 2 )*vol[15];
+ c- B3 Q& |6 I8 V4 Y6 I                        output += n106.Process( 3 )*vol[16];
% U' E8 k3 b. a4 Y( H                        output += n106.Process( 4 )*vol[17];
0 B, m0 ^% L$ J, ?7 c) d                        output += n106.Process( 5 )*vol[18];
1 K$ R1 w( |6 J                        output += n106.Process( 6 )*vol[19];
- Z$ H0 p2 `5 I' B5 ~                        output += n106.Process( 7 )*vol[20];
7 x" B" L' E$ ~                }
9 f! `$ _/ T3 |, V                if( exsound_select & 0x20 ) {6 W# d' P# j9 ~
                        fme7.Process( 3 );        // Envelope & Noise
9 K; o7 V% K9 \, z  Q                        output += fme7.Process( 0 )*vol[21];
8 g7 u5 c3 B; p* c' G" e; r5 S9 K                        output += fme7.Process( 1 )*vol[22];( u3 C% E  G& f4 v
                        output += fme7.Process( 2 )*vol[23];2 B  v$ r: G, F& P- `0 a' K
                }/ Q! E8 O1 |: B  H( @+ y* G
% k4 n+ X5 q& \( G
                output >>= 8;6 l' T# O4 }, A- Z& {" H

4 }% e3 @" J7 ]& _+ y                if( nFilterType == 1 ) {
- K3 p9 V+ Y) g: ^9 I                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
5 H1 l9 d3 ]/ R; G. P                        output = (lowpass_filter[0]+output)/2;: s4 b; v6 }% @( E% `
                        lowpass_filter[0] = output;
. R; ?. |5 T( I! O7 q  H8 t2 f                } else if( nFilterType == 2 ) {: ~# G4 K" G: @5 P( b" w" i  D. Y
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
  {( R/ @9 c# i, l6 C7 }                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;- A* F5 t$ i  T2 V: o' q& E4 F
                        lowpass_filter[1] = lowpass_filter[0];* S4 n; J3 v1 ?
                        lowpass_filter[0] = output;
+ l5 Q  A, W) l1 j' Y8 W                } else if( nFilterType == 3 ) {& N) B" E- B( ], [% ~8 J, }: ^
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
! m1 H/ y0 \+ y- {                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
! c& ]4 O! \: G' J8 w                        lowpass_filter[2] = lowpass_filter[1];
( t4 S9 F) W6 u9 e                        lowpass_filter[1] = lowpass_filter[0];
/ q! k* w# W1 p: {                        lowpass_filter[0] = output;" i8 b' x, V% u# f
                } else if( nFilterType == 4 ) {3 G5 Q! H: L6 O5 H( d
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)* e$ y; ~7 [" G3 `
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;& `& S2 X/ K  [" R
                        lowpass_filter[1] = lowpass_filter[0];5 H+ M" d6 I2 |* V
                        lowpass_filter[0] = output;
! v: G* N+ Z# i! j5 ?, p                }
* t/ o% a& d0 H- F% W' r6 W( n) ^3 J0 F: F5 B6 k# e, ?
#if        0
' H! j+ f6 c, I/ W( p; V0 g( X' d                // DC惉暘偺僇僢僩1 s  o( t  Y* \7 U9 v% b
                {
+ k( z' f5 O; G+ n' v9 D+ A; L                static double ave = 0.0, max=0.0, min=0.0;' l+ q% L. i  R2 Z4 P' Z  T
                double delta;" ]2 F8 d- d5 x, K. t3 r
                delta = (max-min)/32768.0;6 U; o' p. P' O; J( t
                max -= delta;( K  e% s( ]3 X& m
                min += delta;, y* X8 D/ v! ?
                if( output > max ) max = output;5 V4 d" V- v# ]
                if( output < min ) min = output;
) D, {/ [% O7 ]2 }4 ~3 y2 Q3 V                ave -= ave/1024.0;) F, M( w3 h; _6 U
                ave += (max+min)/2048.0;
! i0 f  R  m" x* X: @( B                output -= (INT)ave;" }) E# J' x3 w0 m: R, ~5 p
                }
4 h8 O6 i9 ?8 j4 ]; p6 L#endif" i$ o9 u4 j3 Q9 d* Y, K
#if        1  ]  R2 {1 i5 S& K# Y& p
                // DC惉暘偺僇僢僩(HPF TEST)
0 Z& B3 ~# _, S. Q4 v$ ~/ L& G                {
9 v  }; `1 V% }, x* }: `//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
! b* |6 w$ c8 Y8 v4 e                static        double        cutofftemp = (2.0*3.141592653579*40.0);
# J& i4 r5 Q2 m( F5 o/ `2 m                double        cutoff = cutofftemp/(double)Config.sound.nRate;, `( P' r( p- U
                static        double        tmp = 0.0;1 ]# w! t! H3 ~5 q" g& G5 b  W( ~
                double        in, out;
$ [2 W9 R6 C" D- a  T* w$ L
  E5 [" ]  l9 k9 }; C6 w                in = (double)output;8 {3 ~' H2 O# a" ^5 J( b& r
                out = (in - tmp);/ V9 ]6 B% W7 g* p2 L
                tmp = tmp + cutoff * out;% N/ D  s6 p2 o0 }  B8 L

9 f/ l* Q/ P* H6 [* O8 B8 y  |; \                output = (INT)out;
2 j, _1 S3 r1 b; V0 w5 p                }
8 ^7 X5 o; p/ ?5 q9 }#endif
0 K8 g5 L# B  A#if        0/ a, [) t& V3 d( S
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST), d* \* C- c4 {1 |3 g
                {
2 a: q9 Q. a, l+ }' y                INT        diff = abs(output-last_data);
6 z' f* O3 [9 P                if( diff > 0x4000 ) {1 F3 L6 S5 ?5 c) I% k
                        output /= 4;
. X$ |/ D, R) a- ~                } else , W" O) \. Q! S1 U" T' t' c. r
                if( diff > 0x3000 ) {
! o2 T$ V! T# u  R                        output /= 3;
* m/ S9 G! h4 b$ t6 L) ?                } else, Y0 A& \% G! |; S, d
                if( diff > 0x2000 ) {
" D+ M2 I5 ?2 j- X+ N                        output /= 2;1 e: {7 e5 q2 g: U$ Q- e0 ~1 c
                }
  j0 o  r# A+ ]* k( h' o                last_data = output;, I0 q8 z3 b$ w. W- k6 ?5 \: z7 [
                }- }- U0 u6 _- m* h  i4 b# @
#endif3 ^. r% [* G& O3 P7 N" Y* s4 k. r0 ]
                // Limit
3 S& ?# T! w) G4 i                if( output > 0x7FFF ) {
5 w0 ?8 b5 j4 o/ V1 j2 l                        output = 0x7FFF;5 Q, h% p/ p/ r
                } else if( output < -0x8000 ) {
& I1 w5 k+ r6 d3 u6 z( @                        output = -0x8000;/ g/ ]' U+ {* H) g( u0 L
                }! I2 Z% ^2 A" V' P3 _- Q) o

/ D  y' i1 G4 H, z9 ~, Z                if( nBits != 8 ) {
: m9 V) e% v' M# @! E5 T* E( S                        *(SHORT*)lpBuffer = (SHORT)output;0 j2 R: _* N0 A& K8 G! t' @, _7 A5 M
                        lpBuffer += sizeof(SHORT);
; x- l+ Q& j- g! ?% c  r                } else {! `5 t1 f" Y2 c, r2 ]& r
                        *lpBuffer++ = (output>>8)^0x80;
$ H+ J$ N' u- F2 ?                }" q2 r9 p- ]1 G' h
3 i3 e2 l$ ?# \/ ]$ p2 y& a
                if( nCcount < 0x0100 )
1 y& @% a0 S3 }' i% Y& h                        pSoundBuf[nCcount++] = (SHORT)output;( P9 Y$ R0 A" d
* A/ H, ]0 N9 \0 \7 q, s% h
//                elapsedtime += cycle_rate;/ V5 q$ p% g5 w# C/ v
                elapsed_time += cycle_rate;
: i6 N2 j2 t! H, S        }
/ [$ R0 q7 R# u9 H5 k- R) C- e; a0 K1 B1 Q# U# ^/ u: Z
#if        1
  P9 k$ Z. d0 x: A) R8 d        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {  y6 t) K( B/ {" v
                elapsed_time = nes->cpu->GetTotalCycles();4 f0 q& R9 V. k( u; d
        }
  }( \2 d1 {6 [" G* F0 S' e        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {9 m2 E* T' `' i0 f: L
                elapsed_time = nes->cpu->GetTotalCycles();7 f3 E& |3 f8 K. e; E' p
        }7 Z- n  w8 }7 o. @5 L/ M) f1 z/ ?
#else+ F! K8 c' O3 a0 U. R5 j% P+ ]
        elapsed_time = nes->cpu->GetTotalCycles();  G8 f3 l9 b0 Q: b
#endif4 Z  J+ @& {# L$ V! Y/ a
}
4 L# w# A. [+ b' ?( p8 x( E0 Z* n& M! _6 Y
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)% }3 u* z+ ~6 W
INT        APU::GetChannelFrequency( INT no )
2 e8 `. {/ X  \8 g, Y+ j: W2 ]{! h; C3 r6 ]0 k
        if( !m_bMute[0] )
4 j9 C3 H# O0 `# S, R6 X                return        0;7 F" C! ^/ E9 ]- M" Z

% g8 @( \4 D/ {" L7 J" I        // Internal
, w! r1 u. T! P        if( no < 5 ) {# D& F2 Z8 z7 j7 k0 o& q7 e' M/ N& H
                return        m_bMute[no+1]?internal.GetFreq( no ):0;" \* l; o( g; {5 l. c' d" n
        }
! k4 U+ N: Q6 m, J8 D  h" [        // VRC69 U2 ?7 ]$ A- |: D7 ]
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {; b' f( n; Q( B
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
2 r) \6 ^6 D& G5 d; V( f( ]        }
6 y4 x9 m* r$ i3 L        // FDS: S7 S' o% N+ h# U- u! Y
        if( (exsound_select & 0x04) && no == 0x300 ) {0 t  c( N0 }; U- N
                return        m_bMute[6]?fds.GetFreq( 0 ):0;. J& f9 D' R$ L% a+ Y/ ]) G
        }2 q+ e# P# K* _
        // MMC5
4 Y0 R! w0 y! T" }7 k        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {3 _  T- N2 A, T- ~& \
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
5 S% I/ c* U9 ?& G6 S4 _3 e        }. A9 z$ I( W, Y( S2 N# P
        // N106
1 |% ^) B- l; q: T) G' `0 v) B        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {) ~, A3 u, [" r* T/ `
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;! W% B2 [( |# h' C+ E  T% ?
        }
/ v  m! z9 O' O1 w: [# M        // FME7
% g5 u4 t2 C/ _7 I  J" \        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {3 l. h% J! f$ [) \- e, r
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;9 q9 b2 E/ q; ~
        }4 I. d* Q- r# h2 p2 i  @
        // VRC7
( a! Y% d$ ^1 x5 c' `6 B* J        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {! q1 M3 N# K" j
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;8 G5 q+ z" [: V1 Y/ N
        }# ?; ~# a9 j4 A# q4 x  A
        return        0;$ n. D! L+ t3 I0 C5 j: m/ m& k& F
}
1 ]7 S0 z$ @# V% m: {, z- l3 y
0 D' @  g; Q4 ~// State Save/Load
, B, {$ X; I! [. W, R% fvoid        APU::SaveState( LPBYTE p )
6 ^" B9 l6 w4 \8 ~- t# W* y{9 ~8 C2 K. Y9 ?  t3 o& D% r
#ifdef        _DEBUG
. G. ]8 F+ m- `. _% \$ ~LPBYTE        pold = p;- ^! S" ]' I& D: C- N7 L
#endif
7 c0 i" i- V7 P: s! H; N7 O4 k
$ w% Y2 ^( M, v5 w        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞( [# r9 ~8 }+ }* v2 E9 w3 P3 g
        QueueFlush();: F9 s0 k4 M9 `! R2 J0 p- _9 Z( [) [

' i- N3 E  x9 o0 E/ s7 W  ~2 ?/ a/ G        internal.SaveState( p );. P' p) p. I2 B  {7 X6 \
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
, o3 e( }4 c* m( u0 N  T; B. O+ g' L' H* u* c
        // VRC6
& R9 [& x" D7 X* N" ~2 j        if( exsound_select & 0x01 ) {
* N& H9 W7 M( Z  N7 A. F                vrc6.SaveState( p );) e$ X6 k; r3 e
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding  J* b" y" k- N
        }0 I- ^: s! x7 E9 k' S8 l
        // VRC7 (not support)
, b2 @& y, G2 ^        if( exsound_select & 0x02 ) {6 n& W% Q- s3 k; a* V
                vrc7.SaveState( p );1 S. v( Y7 u4 i, x% I
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
  }0 ]+ g% `8 \6 d. ]        }$ ^( {$ W, [* b/ U6 l
        // FDS
& M1 v0 r" d' U3 d: K2 z        if( exsound_select & 0x04 ) {+ _- q- ^6 h! e+ D
                fds.SaveState( p );0 @5 c9 |) U7 h% v
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding! @4 w# D% z+ @! b8 |* W4 B
        }
( t1 V( e- e) r- L; N5 X) d        // MMC53 l& M5 O& w3 \% b2 @1 n: v' F
        if( exsound_select & 0x08 ) {
) o+ E9 N( x, u+ P1 G5 A) F                mmc5.SaveState( p );
9 I( [8 D; i8 X* S4 q                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
5 ~3 v& ^& `2 H( |! Y4 A; ~1 {. e        }
4 a  D3 u( G7 L" Z5 t        // N106
+ `7 l4 q7 w) d- k4 ~        if( exsound_select & 0x10 ) {
! [2 r; y- \# i( B9 k3 M* V1 K                n106.SaveState( p );
, p& Q2 E. D, C6 P                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding) w3 d4 ~9 p0 `2 V+ x% p& s
        }
! N- E8 M+ \; J        // FME7( `5 |3 n& L9 A3 S( y: U
        if( exsound_select & 0x20 ) {
/ R' `- o6 v1 n) k- [6 m; K                fme7.SaveState( p );
: w& p5 s  c, W* g$ X9 K                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
, c$ S5 R* q7 R: i        }
& E" ]5 r2 Y9 B) y# w5 X5 N' z/ H" i1 C3 S0 n8 d
#ifdef        _DEBUG) A/ k) F3 u2 F# C; o
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );4 p* V  e  I) ]
#endif3 G/ A$ B9 M4 m9 R6 Y
}7 |# J6 U, p0 R- @
; m" R4 ?. V- i2 G
void        APU::LoadState( LPBYTE p )
" `( _  H' W0 ^3 O{$ _$ u/ {5 x+ \2 Y( ~8 c
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
& d( ^+ r# A+ w: |7 ]; z* \        QueueClear();
. Z6 j  B* }( O2 D! K# V9 k0 m" `# P3 P0 ~( V7 J) ]/ u
        internal.LoadState( p );
2 Y/ ^% Q% [1 B2 q1 ^. f        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding& C& ~# ~( ?: ^! q3 Y

6 ^; n6 ?) v- J% A" O1 @        // VRC6
* ~% c% r7 g% ?! s9 }, g        if( exsound_select & 0x01 ) {1 K' \1 i+ Y$ y, Y
                vrc6.LoadState( p );' V3 E. V" _/ C8 ~
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
0 R9 B5 t) @+ W- U        }/ D1 \- z& M- J* B, K( ]# Y1 j" T
        // VRC7 (not support)6 q+ R: ^. K4 F# H7 n
        if( exsound_select & 0x02 ) {
6 u, l  `+ L! M) ^# s1 }. K                vrc7.LoadState( p );
8 C3 ~. z* a1 v$ N                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding( Y( j+ X! Z/ C$ Q! p6 _
        }# L2 `% F1 c$ S* V
        // FDS$ p1 b* v5 K; F
        if( exsound_select & 0x04 ) {
0 Q! j7 o& g4 K* R9 L0 W: `                fds.LoadState( p );
5 J! Y* R+ J8 @3 ?5 J                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding  `. e! \% ?- ~8 J0 k; G
        }4 B, r# d; f: ~
        // MMC5
/ H& S7 U6 v- I/ M% c        if( exsound_select & 0x08 ) {! _; P3 J, b4 r+ o5 S8 s+ ?; y
                mmc5.LoadState( p );
# c  ?6 J5 a; z5 M4 y                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding. A2 k) k, v: B4 {* b- u
        }
+ k- ?2 m! K  h        // N106# [1 R7 k8 D3 r7 {. o* g: X& g
        if( exsound_select & 0x10 ) {- v6 [. t% G) h6 |7 M
                n106.LoadState( p );
% W6 ?( C; D( n, Y6 _) @! f/ N* ~                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding2 s# X% {% w9 r  R9 G
        }
) x' H, I6 v1 D, R4 v% I) f' B        // FME7' H* P6 ^0 u8 A& j, x
        if( exsound_select & 0x20 ) {
* B2 m) P& I: {' W5 ]                fme7.LoadState( p );
# h6 F" r/ I( C  W' C. c                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding5 D4 o3 W3 m/ G3 X0 m% O) V' ]$ n
        }
# A6 a. M. K$ A  f}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
: a& Y& b# v, F- ^可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
8 e9 `; i# z5 @# W, [2 M6 K( N6 c) n感激不尽~~
" `7 @6 V8 g9 q0 {
恩 我對模擬器不是很有研究,
: B0 p  H) k# P7 Y" ?雖然要了解源碼內容,可能不是很困難,9 e9 Y9 D) S4 p- ~, A
不過還是要花時間,個人目前蠻忙碌的。0 Z: u7 E9 t$ @

- S/ X, b, H5 |1 I2 w給你一個朋友的MSN,你可以跟他討論看看,
6 M( `+ {0 u; Y他本身是程式設計師,也對FC模擬器很有興趣。
" m- Y: g$ Q; O' `/ h
: T& N$ Z% Y& S+ l: J7 {" }! KMSN我就PM到你的信箱了。
9 L/ F! k& i% o- ~: x1 j; [
; [3 q; A  P& \# f希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
: b& A/ ~- ]0 T. ]# I( w  q; V, F呵…… 谢过团长大人~~
& k+ t+ c3 P! g1 j- u$ [

! e- ]# W8 A$ ?哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
8 [! P2 G# h2 A0 U0 c团长的朋友都是神,那团长就是神的boss。
; D  [' V& G: T# L( ~, i: [
哈 不敢當,我只是個平凡人,
7 _) j0 }& J& N- O/ m要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
8 D) N7 Y1 g+ ^. n" h* a) @! fZYH
: N" g& n. y  m7 H3 oQQ:4147343067 M" _% C- @  q+ K' A. D
Mail:zyh-01@126.com
  U8 b% W& g# t: ~( g1 K9 X; ?
; I7 D' I. ?9 a4 u他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
: T. K$ s  V+ h% O* E5 K6 Y再次对团长大人和悠悠哥的无私帮助表示感谢~~
1 c+ q" v" k0 c# Q, a0 ]
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-9-17 11:39 , Processed in 1.124024 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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