设为首页收藏本站

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

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

  [复制链接]

该用户从未签到

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

该用户从未签到

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

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。: c3 y3 k0 K, X2 M* r
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~: I( c! n. ^4 }; ^% L
这里有相应的模拟器源码,就当送给大侠了~~
/ t" T# [' f0 r+ R) r, y; I) Uhttp://kenkao.qupan.com/5096520.html
回复

使用道具 举报

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
& {3 K$ _7 m/ c- Y- g能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
& Z5 ]$ m- N6 Q8 b& r楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~4 r$ t0 {6 }0 p% e0 o
这里有相应的模拟器源码,就当送给大侠 ...

. z( b& @( u/ V, ^* s聲音部分(Audoi Process Unit = APU):
; y6 q. b5 O4 f. J/ e7 t$ S+ O.\NES\APU.cpp
+ c7 a; q9 l$ X/ k  `1 f.\NES\APU.h; _4 q! \. ~, V, v/ W& U5 j
+ @, d  @- B. o' {1 h& g. r! _

: a+ Y& q# p4 r2 o4 `影像處理部份(Picture Processing Unit = PPU):0 f8 j7 Z6 M  O. c
.\NES\PPU.cpp6 O3 M) E) \. H+ V0 n$ M; l# ?+ h
.\NES\PPU.h3 t" v$ `3 W, z8 h* a+ ~& h

0 R- O& H7 |/ w& d如果原碼用C跟ASM混搭也不錯
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
, o2 U( r6 c* [) T2 m(由于很多专用术语和算法机理都不明白,所以看不大懂……)
: _5 ~, ?. o9 F/ N/ s# B: n8 F//////////////////////////////////////////////////////////////////////////: Z& b) `0 z7 {- v5 _; d
//                                                                      //+ m! s  _% e$ b" i1 l& z6 E* E
//      NES APU core                                                    //" y$ Q9 S9 A: _( R
//                                                           Norix      //
7 k; S! @  y5 X' ~7 x0 N//                                               written     2002/06/27 //2 j$ t8 R5 T0 _' I
//                                               last modify ----/--/-- //
( W. t1 e* s7 F9 j, O. L7 r2 P//////////////////////////////////////////////////////////////////////////0 Z( Y+ U0 G( ^0 ]
#include "DebugOut.h"
9 a. a) O( F* C#include "App.h"
/ {4 @- o0 o* G( j+ K+ R* C#include "Config.h"
" {$ C$ O6 ~) e/ X: L+ q, _
5 z$ E" b' S+ M1 c5 ^6 b#include "nes.h"8 ~. v3 ?& u4 K! Z7 ]! i$ O
#include "mmu.h"
" i; j9 h- M2 I8 E* }: U- k: M7 G#include "cpu.h", \. p! o* n1 Z- Q
#include "ppu.h"+ I6 R+ F! w" Z. m& r9 E) W# n; o
#include "rom.h"
( O2 _/ J7 _: B+ Q% K" k, Y- C4 m( O#include "apu.h"
0 p! q; u4 r9 B4 B* f5 ]( L' n" f* J" K9 Z9 n$ Y
// Volume adjust  }- V: q( T! F0 g5 q1 C
// Internal sounds
, D9 [# `* O4 v#define        RECTANGLE_VOL        (0x0F0)' o1 z1 O) A6 t$ R. |2 e* d
#define        TRIANGLE_VOL        (0x130)
' Q3 I; k! W/ J2 W  ]/ K& K#define        NOISE_VOL        (0x0C0)
' X9 C, Y- V3 G3 L: h$ W#define        DPCM_VOL        (0x0F0)
9 K+ w* k# n/ m) b// Extra sounds0 d( l" `, P4 I4 ~, H) }
#define        VRC6_VOL        (0x0F0)% j. r$ I0 }" y( _
#define        VRC7_VOL        (0x130)
- r. i: H& M' x; u2 W" J#define        FDS_VOL                (0x0F0)
/ Q& G4 y6 D0 O6 H8 N#define        MMC5_VOL        (0x0F0)
2 W* V& e# i/ ?) \% g( q#define        N106_VOL        (0x088)
" s: c1 w7 w# S+ u- k( A9 n#define        FME7_VOL        (0x130)
: L" E; Y2 L% `
" m4 [) W* G# r- I0 \% `/ NAPU::APU( NES* parent )
3 R  u$ x6 D; |{
" `* D+ o/ t' e        exsound_select = 0;
) U: k" A3 c: O1 {) c3 g4 j, A4 |8 v5 k' o3 L6 C- Y
        nes = parent;* x- w" b+ n  W- x" C5 R7 G
        internal.SetParent( parent );
6 e0 y; T! N% f" N3 C/ Q
) m. w7 U0 ?5 u0 s+ ]7 |5 @* T% \' P        last_data = last_diff = 0;
) F$ O# t& L: C3 a  S! l
$ W7 ?3 `7 r! e/ `8 u/ v" f        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
# B1 B8 l* m, J; M( @# f7 O6 X% Y/ D- E
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );' u( I1 n6 h4 P- J. Q/ j) w
        ZEROMEMORY( &queue, sizeof(queue) );
1 h0 ~. M) @. O0 y8 u4 W8 ?        ZEROMEMORY( &exqueue, sizeof(exqueue) );: O! p5 p( i7 [  G# `/ s/ K. D
9 b$ e. i; ?. ^* T+ c
        for( INT i = 0; i < 16; i++ ) {
2 A+ w+ V' N* s! P6 i                m_bMute = TRUE;
" T. V. W  F7 e        }
) ^) ^9 t( q5 O- K6 q3 T8 N6 \+ k}4 l" R2 n  P+ Q* m: p% i

) W4 `3 R0 [2 g  yAPU::~APU()6 Y6 z3 A9 [4 m% W
{
) ~* N6 g. v$ `}0 i, D1 ^7 M8 k3 h& S8 i1 T

0 Y. }5 V" ]* Ovoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
) G3 B' k+ t' d; K7 Q{% H6 |! T2 h) Y6 N6 G
        queue.data[queue.wrptr].time = writetime;
! }9 p! m% V) q9 U+ K5 F4 W        queue.data[queue.wrptr].addr = addr;4 E8 Y; [# y. }. G5 j
        queue.data[queue.wrptr].data = data;8 a" [1 V( t- S5 \+ H0 j
        queue.wrptr++;
) T. G0 y+ z$ [& ]3 h        queue.wrptr&=QUEUE_LENGTH-1;
$ \1 `1 g" }' m8 W/ Q& j$ X( d6 ]* c        if( queue.wrptr == queue.rdptr ) {: P$ ]. |* _; B! m5 w: D8 I
                DEBUGOUT( "queue overflow.\n" );
7 M2 t! ^- `6 Y; T! ?7 a        }
( |' e. O0 b+ L2 C1 I}
  t' C7 \2 N% Z' C2 J% \" B( C
! ?/ t  M! M# B6 r  B* `BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
" m5 u: Q+ ~7 i3 t3 u{
* D- v- D  ?0 F* ]' ^        if( queue.wrptr == queue.rdptr ) {
& p' M0 I4 r8 T  p: l* ]" v                return        FALSE;- _( Y; m& ]: Q6 A+ ?2 V
        }3 m- L6 \$ }5 m9 m9 Q0 B9 F
        if( queue.data[queue.rdptr].time <= writetime ) {9 W8 l" c5 w8 `7 L  |
                ret = queue.data[queue.rdptr];: E5 ~, ?1 _$ [% [* U! P
                queue.rdptr++;; q/ V8 d( F& t1 I2 Q
                queue.rdptr&=QUEUE_LENGTH-1;
7 i5 t# B# B8 Q! N4 }                return        TRUE;4 m6 D' L6 i, P  ?
        }
: R9 m% _$ l& L; u" w2 x2 ^        return        FALSE;% m; S% Z: j8 [4 w# ], O
}
  k8 X; l) u6 _2 L$ v
, B6 X+ z9 b" ^# r' i7 xvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )" \4 n: V) l# q5 v
{8 T. v6 ^* z) V
        exqueue.data[exqueue.wrptr].time = writetime;* q5 L0 K5 C$ N' @$ F0 l
        exqueue.data[exqueue.wrptr].addr = addr;3 L, U9 N* p! K! h% Q
        exqueue.data[exqueue.wrptr].data = data;
& c3 P& w  f; y$ T+ {5 w        exqueue.wrptr++;7 B; e# x; c' L; A9 W7 {
        exqueue.wrptr&=QUEUE_LENGTH-1;
' @% B% N/ w8 E; ?- w* L5 _6 l        if( exqueue.wrptr == exqueue.rdptr ) {
* r3 I2 l7 g2 t/ |1 b                DEBUGOUT( "exqueue overflow.\n" );5 N+ }5 D* b8 a$ _% I5 s: p
        }
5 M( Q! ?5 H* A9 `+ e" Z0 z}  A' ~3 ~8 _- S
* ~. Q  ]' w' r4 `
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
0 L( N4 k4 A' Z9 c5 ~: P/ A{4 b6 |% {$ M- F
        if( exqueue.wrptr == exqueue.rdptr ) {
4 m3 _0 m0 ^4 O6 g7 O, S                return        FALSE;
: k& |. v' h4 y) A0 C        }; |( _( l5 i- a# V
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {/ H" t' M7 {# v
                ret = exqueue.data[exqueue.rdptr];
* k7 M* Z3 e; V4 B6 s                exqueue.rdptr++;, p* m; k; h/ [& a6 ~; C
                exqueue.rdptr&=QUEUE_LENGTH-1;/ U2 t! R( W1 c* q* u7 t
                return        TRUE;7 C; W! I+ i* G5 i. N
        }0 l( [1 W* O* g( y4 U: _. V1 P
        return        FALSE;8 ^3 F( Y4 D+ T7 d
}
. u1 @9 C6 }, l8 o6 U$ K- N
" c6 n- P8 }/ g  v; M  }void        APU::QueueClear()
/ L9 f7 D+ L7 p& P  D{
0 K8 ~  L' @' H$ f( v  D        ZEROMEMORY( &queue, sizeof(queue) );
+ B- ]+ q; n, w, B* T' b        ZEROMEMORY( &exqueue, sizeof(exqueue) );0 p4 F& \5 k7 ~, V
}
; e0 d0 F6 w! L+ W# X( w0 @
1 ^% F- f( q- S0 b3 Vvoid        APU::QueueFlush()$ Q: v' O4 s+ ^
{  m# o5 B0 c+ q) W1 `7 m
        while( queue.wrptr != queue.rdptr ) {
9 }7 v9 u% C  N                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );# n3 U: l# |! Q$ {, F  F
                queue.rdptr++;
1 d- v! d$ T; E                queue.rdptr&=QUEUE_LENGTH-1;5 k: {) B& C1 Q. X
        }
8 u: h" I$ D3 t9 K) s! p" K
9 _$ e; d: M# o# e7 k4 r3 D" `8 K        while( exqueue.wrptr != exqueue.rdptr ) {
; T& I3 r. W7 b- ?( o' l8 ^                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
9 \3 s; b* C7 q4 k                exqueue.rdptr++;
3 v! a( _4 `/ p3 ?9 S                exqueue.rdptr&=QUEUE_LENGTH-1;7 K+ d0 D7 F. Q! h" G! [5 A
        }* a0 L9 c3 E/ I. q
}
: U; b% X1 z& _- b- W0 l4 D) n+ ]! O* z% @4 P2 O% O0 r
void        APU::SoundSetup()& s( I" X1 A2 u% @' S
{
! E8 v/ ^# Z/ e& ~4 K3 |) o        FLOAT        fClock = nes->nescfg->CpuClock;/ _) p$ S( K+ \' z
        INT        nRate = (INT)Config.sound.nRate;
3 Y8 V, @; Q# H0 b+ _4 J( M        internal.Setup( fClock, nRate );+ u" a0 P' l4 T  s
        vrc6.Setup( fClock, nRate );* C5 M4 A5 b& q  w3 L
        vrc7.Setup( fClock, nRate );
% f5 I9 D- a9 R: D: d        mmc5.Setup( fClock, nRate );
1 {0 H7 \! R( ?1 x, O6 V        fds.Setup ( fClock, nRate );
; J* M6 a& Q0 l% _6 ]! E        n106.Setup( fClock, nRate );: S( E8 ~' d- h- G1 ~9 d  E% M
        fme7.Setup( fClock, nRate );7 H5 C2 [4 ^9 \4 R9 z
}
0 L! a7 {5 x, r, n) Z
/ }0 h8 r/ P! o3 x. O7 Z7 Lvoid        APU::Reset()
5 j: i1 ]4 P' n2 A{2 x) d1 T, I5 b' _: S# M7 G- u7 G* a
        ZEROMEMORY( &queue, sizeof(queue) );6 g! H0 @8 B& J8 s. `
        ZEROMEMORY( &exqueue, sizeof(exqueue) );$ Y6 G' ^7 r) t! Y5 ^# I

$ b" S: }4 c% o0 n& H; o        elapsed_time = 0;7 s8 v* G4 @# d/ }
# G6 D2 Z- r& I& u: b' y% X
        FLOAT        fClock = nes->nescfg->CpuClock;/ v$ c9 D! @+ E( c5 A
        INT        nRate = (INT)Config.sound.nRate;
' [' o* q3 I, E2 Z        internal.Reset( fClock, nRate );
" d$ N; F' W3 R6 o        vrc6.Reset( fClock, nRate );
4 G. U4 O& p- Q4 h4 }        vrc7.Reset( fClock, nRate );' t. H- N6 a! I' a# ?& W! m0 Y
        mmc5.Reset( fClock, nRate );
) ~: ^7 t/ v& D- N        fds.Reset ( fClock, nRate );6 C3 |! Y0 |0 ?) k' k$ {
        n106.Reset( fClock, nRate );& e3 I; ]7 W( G% @
        fme7.Reset( fClock, nRate );
6 d( X6 }1 b, i; S$ U8 p* ~
" G6 o) X* W7 h        SoundSetup();9 f' E" S$ ?2 f. D
}
3 K! |$ {: e; A* D  M# L& W& l7 \/ V+ y8 {* g
void        APU::SelectExSound( BYTE data )
& n5 u- V2 B  i7 l. t* r: V{0 K  V% A/ h% }0 D
        exsound_select = data;
  j  Z* C2 P& ]}, f9 o) }( C& L* x4 m! n. c! S5 W7 q
' g5 G" I3 R. r6 B9 T6 R, ^- t
BYTE        APU::Read( WORD addr ): }8 |6 Z' @' ]- b
{
1 C/ ?3 y& l$ Q) Q; t        return        internal.SyncRead( addr );
7 n" [* L1 d- E. g$ u( i}! O# f" U/ L5 |9 F

, O" l* W  M  E5 Yvoid        APU::Write( WORD addr, BYTE data )
8 W5 g$ b  s. N{
) ^- v; {7 i$ y+ v# r% N# M        // $4018偼VirtuaNES屌桳億乕僩" ^& g6 c7 T) W0 B5 K# ]
        if( addr >= 0x4000 && addr <= 0x401F ) {
) u# Z: Y+ i6 J* O' U  G. Q                internal.SyncWrite( addr, data );
4 s( a4 K( l  v( {! _  G, Y" O                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
. f8 R2 Y) T2 R" b; `2 H, o# |' S        }! M2 R+ p# F- N. J" ~1 J: o
}
2 _4 _' p/ c  p& d0 P# x% z0 f; L7 l% y) Q6 R
BYTE        APU::ExRead( WORD addr )6 `( C8 P  x' `6 [6 @
{) W& m5 c3 H; j4 W6 R% V
BYTE        data = 0;5 ]# c7 W" f6 ], P2 h  w
0 H3 S" |( e0 j/ B5 M
        if( exsound_select & 0x10 ) {
7 X0 U# w5 |8 p/ l6 j3 H4 Z8 ?                if( addr == 0x4800 ) {
. B$ G  S' K% l7 G                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
$ D/ x- ?9 _7 e, _( X) I6 s                }
* O  v" b9 e4 t9 _        }+ G/ ?! \) i5 s% X( L. {9 w
        if( exsound_select & 0x04 ) {# C* Y" r2 t) b6 ^
                if( addr >= 0x4040 && addr < 0x4100 ) {
1 N/ z' u( o, C( h" n/ D) r                        data = fds.SyncRead( addr );) C9 ^$ s/ T5 y! k# K
                }
! g1 w& @4 P; h/ @        }3 R1 b6 J- }3 R9 ~1 G" S
        if( exsound_select & 0x08 ) {! n" u" S- W3 S* Q1 X
                if( addr >= 0x5000 && addr <= 0x5015 ) {
' b. i% S, g* {6 L3 ~- S0 D                        data = mmc5.SyncRead( addr );( B6 U- F/ e& N+ g0 y, d2 E" P- Y/ o
                }7 \, ^: n4 D5 z4 a
        }
, W  H# [* g5 _8 k2 ?' Z- b0 g) m+ y! c
        return        data;
& i0 U' A* [* r, q- Y}
6 H; r4 P& {0 N, e) m. u$ O$ t# E3 d) E% q
void        APU::ExWrite( WORD addr, BYTE data )9 I$ p$ U# l6 l( P. h9 O8 c
{/ f9 C9 u) G/ Y9 U5 T# X
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
6 Q, O( I" O6 E% e6 }# a* Q
' D$ w( }% I0 ^) O7 Z% L        if( exsound_select & 0x04 ) {1 e1 f6 |9 C5 T& w7 Q- }
                if( addr >= 0x4040 && addr < 0x4100 ) {0 w9 r3 Q2 L; T
                        fds.SyncWrite( addr, data );4 J0 e3 L3 w* ^5 N2 a' {  t
                }& S3 J- w+ K  `
        }7 X. z3 H+ H: A; e& V" Q, o
  R' u% z$ R' j5 v; p+ ?
        if( exsound_select & 0x08 ) {( n1 `+ ]- K# o5 D$ [0 [- _
                if( addr >= 0x5000 && addr <= 0x5015 ) {! G+ ~) I0 l1 n  M* [& S
                        mmc5.SyncWrite( addr, data );: M: S; m) H7 T2 w% h% C9 Q
                }
4 A5 ^4 x+ b- k& m) ?: H. P/ q: }        }- G5 x) E& r/ j; x- k  B+ y: E, l
}3 o* ?+ G, Z* e* ~, d* R
$ @+ j. b! @* A. T  `! `0 \3 K
void        APU::Sync()+ k+ I) ~' v. [) z4 j' J
{
7 W9 B2 g* V0 X; W5 O' m, \}
. m+ X+ N. R, s
+ U; E9 K8 f: |8 y% L3 k4 vvoid        APU::SyncDPCM( INT cycles )8 w& _" @% }7 N8 I( `: Q
{4 }/ i+ @7 s3 @  W2 P/ Q
        internal.Sync( cycles );5 o( n& ?, }" H. F0 ]3 f" ?. ?4 s
9 j9 w; g( c* ?' V* K/ T4 J. |
        if( exsound_select & 0x04 ) {' }  \; Z* w6 y7 e
                fds.Sync( cycles );9 H6 P( Y" v) a3 y8 L6 V' d
        }
& L- b( W3 F% y: ]8 a& h        if( exsound_select & 0x08 ) {, u* W2 q0 s; C) o. O
                mmc5.Sync( cycles );2 e' U* b3 k9 F% p$ E8 A& ^
        }+ x( A  ]: d  }6 q7 g. l
}
% {7 ]8 S+ U% J" n8 |+ E+ S
. E& j# r7 t  q  Svoid        APU::WriteProcess( WORD addr, BYTE data )
1 ^2 [( C8 \+ r/ ^/ e) W7 H( g! s{
6 G  {5 y  L! q  s6 |1 o! S# I' x  q6 P        // $4018偼VirtuaNES屌桳億乕僩+ t" M- T" g" H" K3 n
        if( addr >= 0x4000 && addr <= 0x401F ) {$ P) M3 ?4 ^# E3 q. _1 _$ ?
                internal.Write( addr, data );
4 n3 x8 q, j$ }& H; ^$ N& u        }" O8 h& h- f: j8 D% l1 B
}
* d$ J+ e, a: n
3 q  I& {) e- U* A- b9 z( ?void        APU::WriteExProcess( WORD addr, BYTE data )9 R/ J* n0 n, w1 {
{' f; P- `, _2 ]/ J
        if( exsound_select & 0x01 ) {
, J/ Z2 G& H1 i: I, h+ |( v( I                vrc6.Write( addr, data );# ?4 E0 _4 b. Q" _( m1 A; {3 \( Y0 g8 h
        }. y" a4 B1 N, @0 g4 i7 Y
        if( exsound_select & 0x02 ) {; X# f% r5 C9 A
                vrc7.Write( addr, data );
" o4 b% J( S! c* Q) D0 M        }
* h, z1 _) N- `& f! V        if( exsound_select & 0x04 ) {
# P5 @' p% N( t, m4 T4 G* q                fds.Write( addr, data );( H6 d( D0 ?! o2 `; y1 G7 Z
        }6 l7 a7 j+ w: o, |
        if( exsound_select & 0x08 ) {
; }! X. k+ z7 e) L  T7 a                mmc5.Write( addr, data );- ?6 O! t& i8 f1 {: g
        }, _: A$ @1 \4 a
        if( exsound_select & 0x10 ) {
2 l% T! p- U3 }! p                if( addr == 0x0000 ) {
! i" l; V; a6 t) K/ N3 b4 }                        BYTE        dummy = n106.Read( addr );
( Q+ D. N! b% w" p                } else {+ V: a8 E2 I4 Y, u# g
                        n106.Write( addr, data );5 }+ x0 c1 }5 E6 _' y7 h. V- q
                }1 ]. v. P, Y0 }2 D
        }* S/ @2 u' t2 j( x( ?
        if( exsound_select & 0x20 ) {
, @) [9 i  D+ I; X2 W: c+ H3 R                fme7.Write( addr, data );. X1 c1 V& b( G8 Z
        }
4 V# i0 t4 s  g* w}
  O% e  x8 Q# f/ ?* M9 }$ G" {) [) F+ p
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
& i& x3 n$ @, y8 t{# x- B/ i$ q8 ~) S0 d3 A4 M
INT        nBits = Config.sound.nBits;
" L* r  ~  |, B1 m/ vDWORD        dwLength = dwSize / (nBits/8);( w* X6 ^1 q: p2 h. J, x5 Q7 N: Z
INT        output;, C5 @! Z2 i2 `" d# }8 ?
QUEUEDATA q;) x* P4 I$ R' H, R% H
DWORD        writetime;9 B/ Z% b8 h$ g3 Z' m4 I4 F

/ m! a+ ^# ]" Z: ]& ILPSHORT        pSoundBuf = m_SoundBuffer;
3 g3 b) v$ p' W7 }$ \0 C% rINT        nCcount = 0;' F1 V5 c! _/ x3 c0 W5 L

  M+ L! J% u: O0 W4 DINT        nFilterType = Config.sound.nFilterType;( O8 w: Z2 y$ m- F  r2 s, |2 L5 R

( v- m8 a) B9 Q% j, ~8 K$ ~/ s  k        if( !Config.sound.bEnable ) {+ ]0 W2 j  f& s4 I8 N
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );- ]0 X& l6 L) [0 Q
                return;
8 S4 e- |4 A- ^! l' ?+ y        }
/ T# e% D8 y1 t' R0 Y( r! Y' f7 Z1 ~% I+ }
        // Volume setup
' j# s2 ?& P/ }0 O' q0 s+ W        //  0:Master, ?1 O! K5 J0 r5 q& a; x
        //  1:Rectangle 1
7 P  P) s) E: {. F4 G        //  2:Rectangle 2
! j& {4 f) X3 g1 @$ E! ^& `        //  3:Triangle
* v$ B7 N) k9 x        //  4:Noise
: {6 S: n# l, k$ H9 n0 `: a        //  5:DPCM
: t, q9 a# L. u. H        //  6:VRC6; z+ z" l0 [, P
        //  7:VRC7
1 B% _$ u( z& b" Q* c- r) V( W5 j        //  8:FDS" e: Y- w; X4 s# n
        //  9:MMC5% y0 k: {( [; v; r% _
        // 10:N1063 A! w3 C, f- t8 L% e! W
        // 11:FME7
- K& B, L+ C) d+ ?# M2 a' }0 v        INT        vol[24];
4 \! Z, ?9 R1 u2 z- x7 W        BOOL*        bMute = m_bMute;+ H. a+ ^" u& W- h& P
        SHORT*        nVolume = Config.sound.nVolume;
0 N  Z+ E$ `, m) T; c. Y/ y6 u( s
5 A' {& _9 C; w  c- |3 c        INT        nMasterVolume = bMute[0]?nVolume[0]:0;9 P$ j2 D7 F! o( A( T3 F. n
" s: _6 |7 S  I- S
        // Internal
' j/ x) U* s  a( a7 r( e        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;+ z1 B4 V3 p+ ~1 A
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
5 F/ C, C4 K" i3 i        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;/ c1 k6 a3 |# v
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;7 n; V) {, r% L
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;% [, B% L' z5 r) o% [
1 b5 ]" C# W& L8 e
        // VRC64 ?' v- N8 p. [9 K/ ^
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
7 q8 m5 L$ q% l; ]( J        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;3 X5 z& e* |8 A5 Y) S" a4 w6 r
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;8 h2 j; i/ ?, ]9 L! J. Y2 B) M( R

. N% H1 M0 e$ g; ?6 W& o0 c        // VRC7
  K' P, U! V1 t  P! n1 X        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;/ w5 p0 P! |# g- o0 k3 m5 x- R9 h

8 F+ o- s7 a* _3 ~8 x        // FDS% M) w9 W) I4 R0 Q' G+ }3 d
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
0 O7 B. S( A4 C3 V+ M3 I7 ~: G
& d8 |( O4 [8 o  N( r0 R        // MMC5
: j* V! N& Q0 k' B5 q        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
6 ~# G1 |9 p( N, y1 H" d3 S        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
6 B/ }' `" K) u        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;! s( S8 V7 ]4 ^: ?0 t1 q7 S+ Z. y

* E! Z- n. P9 @4 L        // N106
" X. }3 ]' S8 g1 m8 R        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ D1 ]. d7 C! D. r
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" n2 ~" t/ k" x        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;7 t* n0 r) A8 a8 N! @: |* Q& ^
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
; \: l- i8 {/ C4 |0 I        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. Y/ K6 K! @6 N8 `: c3 \# t& ?0 w        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;% x6 ?6 K5 o- d* V( E7 Y) M) e
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
# O! o* b3 Y. W* W        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
% _2 @, Y$ ]5 c7 T# [' A: s  |. |$ j2 F0 h# m. l. R
        // FME7
9 }3 \* N; o9 V7 \        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
5 e- E, O+ f3 C% x. X8 y        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
/ T: |- A" k0 W        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;( z0 b* \4 c8 w. C/ e
9 I6 ?1 u1 k& h" t
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;. h& d5 g& t' `4 U) t1 l
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
$ C9 I3 M6 s" ]+ m
/ \  G' t  ]2 |5 q+ b+ s4 T        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟9 I# V: {( R) o; T: b' u$ Y
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
/ [% A$ i2 t2 v1 p                QueueFlush();, S& W, o3 {. ^( V. Y9 e- j  Z
        }: @/ v# y1 f6 T1 ~$ W

+ v: m/ ]- b* x+ q- r$ W5 `. r        while( dwLength-- ) {
/ y3 ?, K! \) Z% _& ^                writetime = (DWORD)elapsed_time;- ]; k6 r8 u; H! ^" O  N/ s/ N
6 t3 s9 d: o/ \7 e3 b0 ?* n% r
                while( GetQueue( writetime, q ) ) {' @) q" z" F& B% b, j: Z
                        WriteProcess( q.addr, q.data );& R; U% O4 L5 k8 B
                }. M! T+ b7 N  }3 _$ h5 i6 P5 g8 x
4 N& w5 X: X; B
                while( GetExQueue( writetime, q ) ) {
( i3 P+ z4 B3 ]                        WriteExProcess( q.addr, q.data );# X  }- t( r7 c: d7 l
                }- [$ U% f( J# L
+ N" r( D& ?6 K  T% A0 T
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
! s- {) P; W, V: {# @                output = 0;$ y. Y/ Q) S8 s+ h
                output += internal.Process( 0 )*vol[0];
' {* X# h* |; v2 T                output += internal.Process( 1 )*vol[1];) D1 U0 b1 g- W8 e, V
                output += internal.Process( 2 )*vol[2];& m- [  x  b: r0 L+ D4 E
                output += internal.Process( 3 )*vol[3];
2 d" W5 n. m6 C5 u( y3 X$ L+ T                output += internal.Process( 4 )*vol[4];
2 L2 P1 X0 I2 f2 h! M* J7 ?) Q1 Z# l! L4 x
                if( exsound_select & 0x01 ) {! I0 |% `* f8 q
                        output += vrc6.Process( 0 )*vol[5];# T* u, s/ i' W2 O
                        output += vrc6.Process( 1 )*vol[6];0 _3 ~6 E' J9 J7 m" x" l3 v# @
                        output += vrc6.Process( 2 )*vol[7];
( c, }; H7 l, d) B9 H; Q9 ~; T                }
* U4 M. S) v$ f                if( exsound_select & 0x02 ) {& A8 n- t2 w3 i
                        output += vrc7.Process( 0 )*vol[8];! D5 I$ b9 g4 d+ R' E
                }
1 r. {+ s7 f! r! \                if( exsound_select & 0x04 ) {5 e9 S/ Q0 g% X) L/ L* W" C  }
                        output += fds.Process( 0 )*vol[9];
: i, H+ L' n" P. }                }  k' @0 [( ^) k( Q9 @) E. C9 ^
                if( exsound_select & 0x08 ) {7 l. b$ P6 n# }$ s7 U* N
                        output += mmc5.Process( 0 )*vol[10];
0 P" @4 h! Y6 F: G! d* X                        output += mmc5.Process( 1 )*vol[11];% L2 U2 @4 x3 D$ ^- e- F
                        output += mmc5.Process( 2 )*vol[12];
3 W6 i% R& {! [+ T# N6 l$ C- U- ]                }3 l2 E* `3 \' `4 ^- I0 B2 l$ B
                if( exsound_select & 0x10 ) {' V5 V7 i+ n. s2 p; z- F
                        output += n106.Process( 0 )*vol[13];9 [0 e7 O. ^7 B
                        output += n106.Process( 1 )*vol[14];
& i1 T+ p. S+ e: r7 {* q( C, I                        output += n106.Process( 2 )*vol[15];
. Y  V3 _- Y; j0 v                        output += n106.Process( 3 )*vol[16];
% R4 s+ u' a1 d% W6 v                        output += n106.Process( 4 )*vol[17];
1 H+ d& S! O5 m9 v7 _                        output += n106.Process( 5 )*vol[18];
" d! o+ k: n6 P9 w& ?                        output += n106.Process( 6 )*vol[19];: \1 u8 x2 I7 \# y+ F$ G( T  V
                        output += n106.Process( 7 )*vol[20];, b  k; h) h4 [0 q5 c
                }
1 b4 D3 V$ h, m- F: A0 S6 h                if( exsound_select & 0x20 ) {) E- W* T; w- n
                        fme7.Process( 3 );        // Envelope & Noise  g/ n* D, i8 t1 r! Y9 h
                        output += fme7.Process( 0 )*vol[21];
6 A0 O  B5 B6 e0 Z! c9 x, o6 b                        output += fme7.Process( 1 )*vol[22];
0 r- i- L9 b& [/ v% @                        output += fme7.Process( 2 )*vol[23];
$ J) ?! Z9 J2 P6 l                }' o1 t8 A, I3 q  Q3 S. ~3 ?

8 d" L2 }& _: Q" Z0 E                output >>= 8;9 D% B4 R# K$ `9 }! \9 J" O) i

9 L( O# y9 E, i" k                if( nFilterType == 1 ) {
" k$ ?$ v8 x/ K( |                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)- L+ Q( y* \( j" i/ X
                        output = (lowpass_filter[0]+output)/2;
! S6 V- Q+ T' K+ _                        lowpass_filter[0] = output;' S3 |5 k4 c" B; @# c
                } else if( nFilterType == 2 ) {! I1 W: ]/ P/ w0 S
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1), E2 W% P$ \: D" u0 D* a3 @
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
5 [/ F/ l4 d3 U  C$ t& T) V                        lowpass_filter[1] = lowpass_filter[0];
9 @. b- S0 S6 i' z0 R                        lowpass_filter[0] = output;
( `+ Q3 w" y! M, D2 `; c. U                } else if( nFilterType == 3 ) {
1 B; _) ^! {( }9 X  \2 y8 l& Y                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
7 J3 w5 l; `) i7 C                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;  K3 W  R  p! a7 E  l, C# Q
                        lowpass_filter[2] = lowpass_filter[1];- [7 Q8 A* X0 }
                        lowpass_filter[1] = lowpass_filter[0];
9 ?/ k# l: r. k$ B/ a                        lowpass_filter[0] = output;
( V/ d4 P$ W: z2 ]. d5 A                } else if( nFilterType == 4 ) {
6 x: a1 u/ u& c- L  m1 h0 b                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
" B9 P  W7 q; B+ n                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
. r9 y9 j) {: `, _                        lowpass_filter[1] = lowpass_filter[0];1 |. U! B$ k. C- g* s0 ]
                        lowpass_filter[0] = output;! a* L  E+ l" ^! W" c  u8 y
                }$ _. C2 _* ?% u# Y* p7 H4 F
* Z5 a( c" z+ F" C( ^7 q: Z& |
#if        0
6 f0 K+ m2 p. g                // DC惉暘偺僇僢僩
& t# U" v  S; Q( }                {
4 ?3 R5 [0 J0 T9 B% Q                static double ave = 0.0, max=0.0, min=0.0;
! r8 R- `9 N3 P                double delta;
! o( p1 f2 O4 i3 Y4 w4 _                delta = (max-min)/32768.0;
" {8 E1 W) K0 S9 l* E/ }1 X                max -= delta;
4 S; o5 p% Z4 T( E% Z                min += delta;' Y/ |  ]2 E( C( v! L2 h! C$ \
                if( output > max ) max = output;  k# c3 X& J$ y& b- `0 Q7 K
                if( output < min ) min = output;! L7 Z  L) E6 n6 h
                ave -= ave/1024.0;
% k* X8 O% w  W5 ]                ave += (max+min)/2048.0;# ]) ^# E- t0 D1 ~* I/ M9 ~$ q) W
                output -= (INT)ave;
9 L1 l; N! V, _1 C, |# [                }7 P) r1 f5 {# Q# e- W
#endif
4 U0 T5 l" i8 K" n! z& @' Y8 X#if        1
% q: h2 Y- ^  W% |                // DC惉暘偺僇僢僩(HPF TEST)
$ I% B& d( J0 c2 a3 ~                {
+ h+ f/ G) A3 e/ h) B# K5 c//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
- b$ S  v" d% x3 m" K; T4 {1 E( m                static        double        cutofftemp = (2.0*3.141592653579*40.0);  b7 G8 H( e/ _9 R
                double        cutoff = cutofftemp/(double)Config.sound.nRate;$ n5 p: ^5 E  x  ]# j: k6 z- i/ S
                static        double        tmp = 0.0;
0 n2 y) g% b( D4 ~* ?- @                double        in, out;( c; B4 E/ a4 H: J! c( u
+ T" w. ]; k+ m3 ]
                in = (double)output;
! q7 ~- n* u- @8 s' s  R                out = (in - tmp);1 P4 m8 g5 f! x# [* z( N% T3 [; }
                tmp = tmp + cutoff * out;
$ q- ^8 Z: T3 q1 w5 S0 ^. ?0 }+ Z+ P/ W2 c
                output = (INT)out;% J9 L$ h1 X9 p
                }
. P- C& ?) b/ j  P; u/ P#endif1 g, D! ]4 m; J" }; |( {, v2 D
#if        0
1 V1 H7 c/ Y7 E( X, B                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)! \0 t2 Z& M7 [
                {
, [0 T* |- w1 m' a: q                INT        diff = abs(output-last_data);# _: Z; [. y( d
                if( diff > 0x4000 ) {$ r( v/ V# p) J% F! I3 N
                        output /= 4;9 z' r. Y3 s  N7 V4 {+ z
                } else
0 a$ N; G+ G5 y                if( diff > 0x3000 ) {
/ w) F* ~* p) u1 O* I* Y9 K                        output /= 3;7 g7 A8 T( I5 n) }5 ?; @" S
                } else) E. g2 A2 K- h
                if( diff > 0x2000 ) {
: W% ^2 ^6 m' s  T/ N( P% c& ~% a9 x1 U                        output /= 2;: T+ _! \& y' q1 M7 D/ G
                }
* |; z4 m) I4 z1 L) Z# ^                last_data = output;/ a, ]% m7 r( C, e
                }
  R3 `: V; E0 W" V; k#endif
: p2 D" ^4 K( r7 ]* x9 L( F                // Limit& U) k7 y( g9 Z  ?% `6 h9 r: U/ V( p
                if( output > 0x7FFF ) {
2 H9 G1 e: f( k/ [: {3 w                        output = 0x7FFF;. m1 |0 Z! E: x  [% p' c
                } else if( output < -0x8000 ) {2 y3 q' p8 R+ {" o0 j
                        output = -0x8000;
4 T6 `0 k6 s  [- i$ ^3 r% u                }6 M3 U% r6 W3 a- {
6 U4 r, x* b' Z) ~9 t; b
                if( nBits != 8 ) {0 ^- P! e7 u0 r  ~1 V
                        *(SHORT*)lpBuffer = (SHORT)output;
- ]/ S) V0 e& u5 ~& [) d7 Z                        lpBuffer += sizeof(SHORT);  i1 E& v" Y, P# P& _7 T1 V
                } else {" D7 j$ |3 @. j- \- e+ `3 T/ u# b( c1 Q
                        *lpBuffer++ = (output>>8)^0x80;; D* E. M0 Y3 A1 v( h
                }! Q+ Z  q% z3 ]* g/ C
# R  |  P: s+ W8 [6 v% ^! E$ P& ]; @
                if( nCcount < 0x0100 )
, `" \4 g; j: q# ^                        pSoundBuf[nCcount++] = (SHORT)output;$ B* j0 N) I9 [& Q: q  c

* x' O% {! M/ e/ x8 i! H//                elapsedtime += cycle_rate;% D* x7 ^8 D( i& y: j( L
                elapsed_time += cycle_rate;
  \; l* o2 W1 ~6 K. v        }
+ l! n. w2 S8 l+ y! W. b% V- ?9 q7 R3 V: a" y- y  _3 X' `) o
#if        19 t* j6 X2 r. z# N5 s
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {- o% K. ^, b# V: c* b4 [1 x3 L
                elapsed_time = nes->cpu->GetTotalCycles();
) Q; n  |1 n6 y* m5 l1 {+ Z9 j3 I        }- q( v  K5 N* E$ X8 y& s" s' c1 n
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {: v% w# H# j- k! h+ p
                elapsed_time = nes->cpu->GetTotalCycles();, e0 A: E2 Q, s3 y
        }
" ~" P5 H' f  a; s( R& x#else2 l/ L' ^! T! f
        elapsed_time = nes->cpu->GetTotalCycles();: N) a* @  L7 D) g4 e6 H2 |
#endif
7 K7 o# O/ t/ c( {}1 i6 ?  w. J, K7 P9 d1 s

  L1 e* q; w" {  u/ n// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
2 ~; F7 d% F: S3 zINT        APU::GetChannelFrequency( INT no )
) e3 d  M5 J! t% }1 K{' o( i: |8 y9 p* {8 }( c- I
        if( !m_bMute[0] )
! J; R5 O  A/ q* e1 `2 B6 V; ~                return        0;
1 }! _( f" j+ _7 ?' Q
% T- r8 U0 ~- A' T        // Internal* u$ C4 U& @' B$ K  W
        if( no < 5 ) {- i4 v) w! [1 I1 U9 Q# j
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
4 c7 c  h+ a9 ~6 i6 z5 [        }
9 K+ |0 n/ c% _: w8 r        // VRC6* B8 [" j+ C0 {2 l
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
- z3 }. j' b% Y, m0 O: Q. |                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;; ]; ]; Q  f/ J& X
        }
3 l/ g9 t* h9 X7 H        // FDS
! e0 z- L3 O. {8 E& g        if( (exsound_select & 0x04) && no == 0x300 ) {
6 w! Y$ d/ G/ O                return        m_bMute[6]?fds.GetFreq( 0 ):0;' k& x3 A9 e( G2 }: Y
        }
" R' B6 W5 A) _9 v: U: V) Q4 f        // MMC5
" k/ I% K+ u* l" a+ h3 U        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {' c5 o4 G$ A$ s9 Y2 {6 `( k3 ~
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
, p2 w3 l+ g3 M        }6 N7 l: t7 K$ Q; P1 G' c4 k
        // N106
1 y, I- c6 A. `0 a2 h4 K. m        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
" M( {  K6 R. d" U+ @/ Z                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
& U9 F: b& Y/ G& p& u        }
) @( J: Y- D; T0 G) c        // FME70 @# C6 |7 q+ e* O
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {6 w( ]$ j$ E, k6 F( r
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;! e0 ^) d5 d# F
        }
' ?& D4 N/ ?8 u0 B        // VRC7$ `% m- F% L6 u* ]; T% k8 T! J9 a$ A& v
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {5 N% `+ x$ V4 e( E+ }
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
! ]" k) D* Q: r$ J        }
  \0 Q: [% [/ l4 m& [        return        0;
3 t. M# D  L2 G; j, `1 M8 n}
. O* _4 k/ U+ d# Z0 l# C( b. g5 v% R4 w* K# R
// State Save/Load0 x' M4 Y6 B. ?1 j, p
void        APU::SaveState( LPBYTE p )
- B1 N) @! e8 _0 o6 ?6 O# P{& R+ z) R; }0 g' p6 \
#ifdef        _DEBUG8 |+ p2 Y- T/ b6 S
LPBYTE        pold = p;
$ [: x9 U! n. p#endif
2 U1 J! O) \  V& g2 k9 S! Z7 V5 _" x$ Y+ G# Z3 G) p
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞& a; d' p- W* O! p( `& N7 k
        QueueFlush();) ~  @3 n1 i, r3 U
2 T3 n) {& z8 ?0 _
        internal.SaveState( p );6 C3 q: _5 U5 Q+ `, {
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
+ ^. d$ s; g1 v  N/ U7 K' g. D0 M4 Z6 Q5 j! a
        // VRC64 c5 _0 z: X) Y6 n7 k1 O" P% v
        if( exsound_select & 0x01 ) {( ?2 U& h) z0 U8 x3 u4 O
                vrc6.SaveState( p );9 n% U  p: U4 G- Q9 f* a! |& w8 `
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding# q( q" }" _6 G, `# E' \
        }
) o1 A* c9 F* w        // VRC7 (not support)& M4 N# x: a# B
        if( exsound_select & 0x02 ) {
. K) i$ W" q4 T( Z5 `0 N  i6 c+ c                vrc7.SaveState( p );
( c" Y" v. l) u3 P# m6 v& F2 F) n                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding) |7 \# _5 t/ i" K
        }8 L* X+ }' o) T% b2 u
        // FDS! q2 D5 E* }$ r, b5 V7 ~
        if( exsound_select & 0x04 ) {
4 j  y0 e0 @: d                fds.SaveState( p );
3 \6 N: [$ O+ a                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding; ~$ `) N7 f+ n8 ^
        }! a7 O$ Z6 n. }1 }) b! y5 z
        // MMC5
4 d6 Z4 G3 l1 y2 j9 P; K        if( exsound_select & 0x08 ) {
+ h1 N$ x/ J& v* P                mmc5.SaveState( p );
) C1 A, g! k5 A- r/ t, |" l                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding+ D  G9 h, F% Q( X1 X
        }
: g3 I* d' |2 V1 ~' M        // N106
  Q' `' W% X& J; h+ D% Z        if( exsound_select & 0x10 ) {
6 o% L6 D% D0 P) e% }                n106.SaveState( p );" v% \/ Z" Y6 V  @; T8 _# H
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
% Y2 q1 m/ h9 P) Q' _        }5 z) Q; _8 R, ^; [/ f
        // FME7
# ~2 M% J. W! M2 ^        if( exsound_select & 0x20 ) {
/ f. A+ \6 k" v1 E6 c( H                fme7.SaveState( p );
( A9 q3 Q6 T0 i8 s9 Y/ d                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
+ k9 N' K/ X7 v6 [" ?: ]4 `( J- Q4 @        }
5 O" E8 S5 ^1 U3 Q/ s+ O' l
, D7 K0 x6 \+ l9 K3 W' t" ^/ Y#ifdef        _DEBUG
" _0 C9 C( g0 D3 V8 y- @8 ~  H7 c7 j4 E! YDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
* K" T/ g+ q: u; M2 _$ ?. ~#endif- F( g. Q( J( o( Z. m3 M
}
' d) h1 c. O, C0 |' Y7 T& V9 a+ l" p% Q) b
void        APU::LoadState( LPBYTE p )
3 i: J  W! H7 _1 M$ V{/ B. j0 X4 b4 w8 F0 T1 }
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
7 m0 X1 B0 k) S        QueueClear();
. k, p. h, o5 x+ p) w. D' @# }9 X
        internal.LoadState( p );
2 {! Y) Y+ H' ?        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding0 U' {& m( L1 M

, E! v: [+ D% @        // VRC6  y. K  D5 U, G; u) O8 C
        if( exsound_select & 0x01 ) {( \0 R6 o. ?; S9 c: A9 @8 C. D
                vrc6.LoadState( p );
; e9 q. c9 X2 @/ V                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
+ |. e. A2 C. N/ y- w0 U/ D' w        }0 {0 ^% t9 V( ~9 {; X: T6 {
        // VRC7 (not support): m  `# {: A9 m2 Z
        if( exsound_select & 0x02 ) {% E6 y1 @/ t! z- t( d
                vrc7.LoadState( p );5 u3 l+ \) q* J6 l- E0 y% B5 o
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding4 H1 j  d1 }# y/ t8 W1 X3 [  w
        }
3 e% g- c2 @% B4 g        // FDS- ^0 F: Q# ]) w2 H6 u3 L) v; Y0 Q2 `6 S
        if( exsound_select & 0x04 ) {1 {( R  c- _$ D" |3 c( e& U5 J$ D
                fds.LoadState( p );
  R& c) F- j( D5 z- n                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
) T% m' P0 C" A6 r4 Z; t; q        }
, Z8 u  t6 }+ g2 |0 J  [1 S        // MMC51 V/ P/ R) }4 k3 ]
        if( exsound_select & 0x08 ) {
. {8 d/ n, x# J! H9 T( Z                mmc5.LoadState( p );
$ Q# x) h2 P3 \6 [2 D                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding; V; `0 D# i1 _* v
        }
- ~7 i1 f; m3 {, ~6 H: C+ N. J4 {5 C        // N106
. Z' v1 \% d* e" Z        if( exsound_select & 0x10 ) {
3 `4 a& I2 L6 G                n106.LoadState( p );# ?! ?1 w( R+ J
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
+ k( g) U  W3 ?7 c        }" s" g; b6 F$ D" k
        // FME7
4 L5 T) G, D$ ^9 @$ V) C        if( exsound_select & 0x20 ) {% L+ p- U1 w* U. C1 P
                fme7.LoadState( p );
; W2 I3 X- a+ c6 n0 _* H                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
/ t8 E: k* e8 f& J9 l        }: C! v  ?3 j0 J* @6 |$ @6 f6 J5 ^4 D
}
回复

使用道具 举报

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 # r5 G$ X" g! y: T# u: }
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。: ?+ s1 c& d% T; d4 \" ]: c3 s2 S
感激不尽~~
) x% i* u( ?& x* L6 \8 ~
恩 我對模擬器不是很有研究,
, L- o( ~& {5 E4 F4 P雖然要了解源碼內容,可能不是很困難,
* a; z2 I  c/ Q. X* e不過還是要花時間,個人目前蠻忙碌的。# s  E6 G8 f- k! v* P/ {8 t
/ m2 z% A1 A' n- ~) {
給你一個朋友的MSN,你可以跟他討論看看,, |- V! t! ~4 o) I! N7 ]3 D
他本身是程式設計師,也對FC模擬器很有興趣。3 O0 Q, u% X) d" b7 O' X/ s$ M' g$ d6 y$ y
# y  g( Q$ ?. d9 E3 a* H: l& E5 m% \
MSN我就PM到你的信箱了。8 |7 l/ r6 P6 ?! X/ L4 T
6 l( P" q, f" y9 o% o& b; c  \
希望你能有所得。
回复

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-9 13:23:59 | 显示全部楼层
呵…… 谢过团长大人~~
回复

使用道具 举报

签到天数: 82 天

[LV.6]常住居民II

发表于 2009-11-9 16:02:29 | 显示全部楼层
团长的朋友都是神,那团长就是神的boss。
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表
& m# ~' c, ?$ n5 k0 M& C呵…… 谢过团长大人~~

9 N/ J! a. y! i5 v# m2 D9 t! w, \' K! [  W! ~+ P( x
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
/ ^/ R2 |+ t) U9 y% b( i团长的朋友都是神,那团长就是神的boss。

# z) X) j+ C( e" ^  g' X哈 不敢當,我只是個平凡人,& ?6 g/ v* w" |+ L5 |
要吃飯喝水,光吸空氣是不會飽的。。。。 :)
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
8 W3 I- L: n" k( ~4 mZYH, s7 @  m, |0 P& s9 }
QQ:4147343063 s  [9 @0 y0 J" k% o
Mail:zyh-01@126.com
- M- ^$ K+ ?( {4 L) g& r4 F: D& K- {' h( h
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 ! ]( I" T! n: Z2 _( S
再次对团长大人和悠悠哥的无私帮助表示感谢~~
" w: p! j5 i* u
不客氣  ^_^
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-6-26 04:35

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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