EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
0 E( H1 i1 r! ^5 H: M9 i楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
0 a& D! G: T( X这里有相应的模拟器源码,就当送给大侠了~~
4 \, @" S' s7 Z* B( b/ w5 _+ zhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 4 k" t2 q/ _- @4 v0 I
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。4 m- u8 [: b* c- P
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~6 h9 J4 b. d# K7 z' Y
这里有相应的模拟器源码,就当送给大侠 ...
: d' `) }4 N, g0 E, s
聲音部分(Audoi Process Unit = APU):- s/ N5 H, f4 @8 ]
.\NES\APU.cpp$ U/ M  a5 M# ?
.\NES\APU.h' f" I  F1 h! ?) M
, x' `, b# A2 o: |

, E( P) B- ^: R3 T影像處理部份(Picture Processing Unit = PPU):. Z# a! J/ v; k, U) o* `8 j
.\NES\PPU.cpp$ u( s2 Y3 m: I& p& e5 x0 [
.\NES\PPU.h& N; \4 N2 |$ M

" ?% H1 R. F. z+ [* z3 a1 Q# i; b: P如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:! a' t2 w7 @! w! h" F6 B+ {
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
) {1 X6 @- x2 b: w$ q//////////////////////////////////////////////////////////////////////////- |5 R% F1 S) m. f' \" j1 @
//                                                                      /// S1 h) x7 c/ w9 Y
//      NES APU core                                                    //% {  {8 E5 V* L* D. g' X  h/ |# ~
//                                                           Norix      //
& L' R5 ~$ q% e# |6 J//                                               written     2002/06/27 //
3 {+ ?* j, ?/ H) s! S! N; V' F2 m//                                               last modify ----/--/-- //
0 x# `  Y8 u. X0 e//////////////////////////////////////////////////////////////////////////
0 f/ {) S/ n  U3 k+ p, P#include "DebugOut.h"" T3 c0 z* m, d; e! u  K, Y7 e' U
#include "App.h"
- t; a$ @8 {3 d. ]#include "Config.h"
7 H; ?% f! k% s3 j
- w: c" S" \1 i1 d6 B#include "nes.h"9 J: _/ y5 M- ~! y% z( Y4 J
#include "mmu.h". T4 |5 X6 [9 ^; a2 T
#include "cpu.h"
3 q& m. l: l7 A) O3 u/ Z#include "ppu.h") t( E# o+ C4 B- e! V! x
#include "rom.h"
8 ^7 |& a- I# z6 F4 {#include "apu.h"- K* \4 n& }  K: v9 M- q
6 G) ?$ e4 `5 ~0 b% x7 M! _
// Volume adjust& M9 ]( }+ E7 e4 C# u
// Internal sounds
! Y  G3 X- C! _5 V#define        RECTANGLE_VOL        (0x0F0)& m2 ~. Z! m9 P7 `, o; o* @
#define        TRIANGLE_VOL        (0x130)
# Q, }# W# i$ j  n1 n/ f9 `2 s3 x#define        NOISE_VOL        (0x0C0), M* T5 G. L; t2 m
#define        DPCM_VOL        (0x0F0). Y' l# P7 B3 E2 X( }4 u# d
// Extra sounds9 j* H8 P- r# X( D
#define        VRC6_VOL        (0x0F0)  q+ U8 Y* w* K# R5 t. _7 g/ r
#define        VRC7_VOL        (0x130): F4 a5 A9 J$ A! ~0 ^8 }# d
#define        FDS_VOL                (0x0F0)2 f/ [# v& Y% M  f% c( s
#define        MMC5_VOL        (0x0F0)
/ }) h. x+ z) \+ p! Q" e#define        N106_VOL        (0x088)
% ^8 L* l( W; L9 @4 k#define        FME7_VOL        (0x130)- z, M8 X* d& t  v- F" t) {* Q

% C1 l) Z. q+ Q3 Q4 w8 nAPU::APU( NES* parent )
# L$ v  s% x, [{
3 Y! {. v6 U( ^+ H- o        exsound_select = 0;0 f- P' ^2 h5 u2 R& ]

" F; S4 x3 `8 O8 I4 C/ B        nes = parent;; v: p4 g+ E) k6 X2 l3 f8 y$ D
        internal.SetParent( parent );! a* e, ?" f4 I8 x/ q  d3 [

2 A! A* S7 v1 G: \5 n        last_data = last_diff = 0;+ s" ?' o# @  M# F% e

' J2 h6 ~( f7 h& S  K6 p* f        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );0 U  P+ W4 D0 ~: z

2 x$ m3 M- t9 f  C" {        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
9 d) ?' Y& H3 K0 ?4 G        ZEROMEMORY( &queue, sizeof(queue) );
2 p0 k. ?1 d2 _4 [4 v3 ]        ZEROMEMORY( &exqueue, sizeof(exqueue) );% T! K2 W* p3 H  m
: R3 u7 b0 `3 R$ H2 O
        for( INT i = 0; i < 16; i++ ) {
- V1 J. j! v5 r; U$ N/ x: X                m_bMute = TRUE;
7 p8 z* h" w, R; R5 y3 e- O        }
( Q( y8 D& b% g% a) H}
5 l- E) ^$ y' d2 F
2 k2 U+ t% \# z) g; uAPU::~APU()
: o, l3 p6 x! U6 B; }{
# f, w' E* w2 ^) M1 q8 ^( L, _}" J8 _' d0 u+ H; V& ^2 ^5 j  Y4 x" Q

* x( H# V0 C! P- I  ]8 `/ {: V: Yvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )) @. i- H3 K9 _( r/ D
{9 w8 ?8 e: V9 O* i8 B2 P
        queue.data[queue.wrptr].time = writetime;
0 e* A% V1 e& k8 C' C        queue.data[queue.wrptr].addr = addr;
) v! T- i& G" Z4 q8 p3 Y6 c        queue.data[queue.wrptr].data = data;
) c$ H/ Z. U$ P! m7 M1 p. s        queue.wrptr++;
$ A; _. g, h  `& x* E        queue.wrptr&=QUEUE_LENGTH-1;
+ }$ z  ]6 _) ]        if( queue.wrptr == queue.rdptr ) {" ~( x( ?5 d% z' h: s
                DEBUGOUT( "queue overflow.\n" );
4 J, r. G- l1 r) k        }
6 X5 P& k% I5 r- l9 y9 o}! k! g+ Z3 i7 a. g7 _
# r8 W' X5 X9 o) i4 i1 c
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )$ a; p; Z0 ~( p, i
{
$ X9 F* y2 p5 p        if( queue.wrptr == queue.rdptr ) {- o2 D  e* E/ m; Z) E
                return        FALSE;
; ]+ H" v, v  [5 O/ h' h4 n' Q        }
) ?7 s' ]" }# w8 j/ ^        if( queue.data[queue.rdptr].time <= writetime ) {
$ ~/ c& {9 k  b! ?- ?7 _                ret = queue.data[queue.rdptr];' Z2 H5 a/ K6 U' G
                queue.rdptr++;" w" N2 p# C& d5 H- \& X5 b
                queue.rdptr&=QUEUE_LENGTH-1;. z0 E" v% n& M: M1 R) H$ _
                return        TRUE;
( k3 I' [, s8 L) {. M        }
/ l. z# S" X  W6 C! O        return        FALSE;! I$ i2 b1 @: k4 j
}8 R( s; }6 \+ I% \" c
3 D9 b% _1 l! t9 x
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )& j4 Z. E* I* ^% c
{4 f7 x0 p# ~0 {- J
        exqueue.data[exqueue.wrptr].time = writetime;% O' a. Q( p  ^+ W
        exqueue.data[exqueue.wrptr].addr = addr;% j# B2 m" t2 a; I: `
        exqueue.data[exqueue.wrptr].data = data;
! i4 J5 I7 G0 K  J6 x; Z6 v4 Y5 Y        exqueue.wrptr++;
. C* S& `$ [& ]  e$ c' _5 c        exqueue.wrptr&=QUEUE_LENGTH-1;
. K: m/ `! c5 ~! |9 s        if( exqueue.wrptr == exqueue.rdptr ) {
7 @! d) g7 _* K* S9 L                DEBUGOUT( "exqueue overflow.\n" );
+ k! }' f+ V6 u; T' D        }2 n3 \% G* A, f% o) `( W
}" l- e1 F( B' E0 N7 v

$ }' k: I6 H3 x! U7 L  s. @BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )/ ?! o* l" d& G3 s- r
{
* l3 H9 m+ T/ G' f. E2 E9 Q        if( exqueue.wrptr == exqueue.rdptr ) {, Q( B5 \4 p( v
                return        FALSE;
; A$ r& y* P/ k2 t        }
( B. D1 V  W% P8 }% S        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
4 C1 P  D; X/ v5 n. V* I                ret = exqueue.data[exqueue.rdptr];
, I% ]' W$ P7 T3 v0 I                exqueue.rdptr++;) z: j7 o- s) X- s  m
                exqueue.rdptr&=QUEUE_LENGTH-1;4 T. d% o/ e( D. F$ B, J
                return        TRUE;9 K2 r0 ~/ V# F! Y0 F% g
        }6 K) _  |/ P; N2 R+ a
        return        FALSE;& R7 n, s! I. f5 G7 c  m8 C
}
( A6 l/ O/ o8 x
$ A: F" D2 Z6 n# d( F. A: Nvoid        APU::QueueClear()" }8 v, {: L1 \; {# z! ]2 _; c
{
- a1 y3 i9 ]' Y+ S, D        ZEROMEMORY( &queue, sizeof(queue) );! T/ I' M  l9 ?! O/ S6 P. e
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
) H7 z2 r. G& k- Z* S+ R6 x}. F% S0 o8 U0 |4 r

) s0 S2 Y3 j4 s8 N4 A2 nvoid        APU::QueueFlush()
" v/ V( |$ R% W: L! U{- \7 A4 s* G4 `& Y; l; s$ E; O  y
        while( queue.wrptr != queue.rdptr ) {; Q& _" X- _5 Y4 X2 W: W
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );6 R; X  h  T* p2 Q- U) q6 p6 ^/ t2 M1 f
                queue.rdptr++;6 x/ O" ]+ f, u7 j% q
                queue.rdptr&=QUEUE_LENGTH-1;3 T" A: k9 g+ S, a; G& M
        }9 _( Y/ R) L4 ~1 ^7 G: n* N4 k

% Q. m  j5 ]0 [; h3 l. U. a0 G6 O  a        while( exqueue.wrptr != exqueue.rdptr ) {( `5 m5 F0 v4 X( i) H* B
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
* @: c# B$ n8 X8 I9 j                exqueue.rdptr++;
4 `+ I! S0 U% N1 C; B9 x                exqueue.rdptr&=QUEUE_LENGTH-1;
/ z6 y( `$ a3 _5 L) n6 l, N: H        }+ A5 [# a* e3 e0 u
}2 @& e8 `% {3 W! ]" y# D5 G

: c9 |* T9 A, X; v1 Jvoid        APU::SoundSetup()0 I. L) D: k6 m- p& C6 l" h. |% O1 B
{
/ A9 Z3 r2 ^- t& N. p        FLOAT        fClock = nes->nescfg->CpuClock;
5 I( c, V% Z# _7 M+ C6 b        INT        nRate = (INT)Config.sound.nRate;5 S2 u" n9 B: D" N
        internal.Setup( fClock, nRate );- P+ R  A7 H4 d' o* d  P
        vrc6.Setup( fClock, nRate );1 L% |/ p* S% ^3 I
        vrc7.Setup( fClock, nRate );+ i5 l  a* \3 Y/ Q; U/ k' a
        mmc5.Setup( fClock, nRate );
) \; p; P5 k( ]& q6 S8 Q        fds.Setup ( fClock, nRate );
+ f& I1 i/ p# F% k# P        n106.Setup( fClock, nRate );3 O2 S* {/ L  z9 R
        fme7.Setup( fClock, nRate );
( D/ j" J2 C8 F- B' l) ^4 y& B}
" G0 \7 t- S! t1 f
7 F$ J" n6 C- [- B- ~% H: A0 svoid        APU::Reset()
/ G. K+ w' w! T" j7 _( s{3 u  J; E% d- t% `6 B) K) L
        ZEROMEMORY( &queue, sizeof(queue) );
* f0 v5 P5 H, K5 w8 i% f        ZEROMEMORY( &exqueue, sizeof(exqueue) );! |; [1 L4 Y9 q5 r" Q5 N+ ~
6 _, ]" G5 ]; z, D
        elapsed_time = 0;
2 I  |$ l* Z+ X& K7 M) r" U; S) P# o  y+ Z( O  T
        FLOAT        fClock = nes->nescfg->CpuClock;
6 Z4 i$ L* j# X  f3 f0 w# _        INT        nRate = (INT)Config.sound.nRate;
; o' c9 K1 c9 P, P7 L: A        internal.Reset( fClock, nRate );! n- L2 _4 ^9 E
        vrc6.Reset( fClock, nRate );- u& \1 d# g8 p
        vrc7.Reset( fClock, nRate );( I9 [- k# m6 s# r7 A& r) g, g
        mmc5.Reset( fClock, nRate );/ @$ U3 r6 _2 V, I) D+ C
        fds.Reset ( fClock, nRate );
1 S- L% i4 W4 p! }5 |        n106.Reset( fClock, nRate );: s3 V5 r7 ^6 H3 n
        fme7.Reset( fClock, nRate );5 c6 i. G2 \7 ]4 L
( O. f0 x! r" C& {. s1 ~. m
        SoundSetup();
: {# t1 M4 f% A6 [' \}6 p$ H3 Y1 n) o8 I9 n1 @

, J$ b+ f" w; ~! Z( Z9 E. c% I( Pvoid        APU::SelectExSound( BYTE data )/ X" Q+ G/ m6 y0 E: P
{4 I5 K: Q4 C2 p
        exsound_select = data;
9 p4 J5 V: p* J- m}# l% ?1 r9 k! ]: A3 V# y
* C- ?3 H! x) P% V  E8 W9 v5 X4 i
BYTE        APU::Read( WORD addr )
% X7 }! Z0 S/ s: u/ ?{5 Y; @* E+ W3 M3 c
        return        internal.SyncRead( addr );
/ X2 D7 M; V+ o' _8 D9 J}: T1 q  S6 s# s& p

% {) m- l/ p9 J( lvoid        APU::Write( WORD addr, BYTE data )
# m6 @# ?* Y$ @3 I/ _, a3 [& H{
$ a$ z7 E( J) O        // $4018偼VirtuaNES屌桳億乕僩
' ~, S! F4 `, O        if( addr >= 0x4000 && addr <= 0x401F ) {, ~" f8 g( k% E8 @' W
                internal.SyncWrite( addr, data );; H# i8 q& l5 S- s4 r  |
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );1 X' V5 ~3 B3 z2 J
        }8 E+ I0 V$ u2 v: R1 A  b
}
, X  N6 ~. w8 {! N: P# v8 l6 Z5 W2 N' Y2 K7 r; _
BYTE        APU::ExRead( WORD addr )5 ]  i/ j2 d1 X! _( b
{  P% t2 Z! z  H. b& Y
BYTE        data = 0;, f4 ]# T- {& D/ |$ ]  j5 s- S
0 N3 S: Z, r3 }3 o# i& o$ D( q5 \
        if( exsound_select & 0x10 ) {" I3 e- @; U# X7 _$ \% ]
                if( addr == 0x4800 ) {
- x9 W! S9 U2 ]6 B5 a8 p                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );0 k4 R. b, S5 b, e  ~. ]+ |8 `
                }4 e3 O4 }4 U/ P, H% ]4 J
        }# u9 i, u% Z4 O1 U( u) r
        if( exsound_select & 0x04 ) {
1 t3 _3 R. \, O1 v                if( addr >= 0x4040 && addr < 0x4100 ) {
5 y% U) _9 e! c- _) ~5 c7 Z3 \                        data = fds.SyncRead( addr );& t& L/ v1 \8 ~6 T5 k+ w: S; i0 A
                }
$ q. ]1 F: s) t, [( z0 C, f        }4 w9 y4 V5 `* ~1 _4 c
        if( exsound_select & 0x08 ) {
" m  z+ {3 `5 |  T+ C( m2 @                if( addr >= 0x5000 && addr <= 0x5015 ) {
, u5 }+ F# }, N                        data = mmc5.SyncRead( addr );
+ \# k  q2 E  Y0 \* s0 v( |                }
" J, K( J" Z" s9 z! u6 z+ k        }
2 [4 |0 L* L0 J+ c  l
3 Z# E5 V3 o! B) J' L+ L        return        data;8 p9 C  M0 z  k1 P
}# |" I& ]9 J& l. r

4 Y. e4 c! \4 T. r& K' avoid        APU::ExWrite( WORD addr, BYTE data )8 l# s6 i# U8 e* c: b, b! o* R
{
, b- t; ?" B+ t! y: s- O        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
4 L" [; y$ P- \; H8 }; \: V9 ^% Q* ~
        if( exsound_select & 0x04 ) {
6 p$ h( [4 C8 S! c9 G% ~                if( addr >= 0x4040 && addr < 0x4100 ) {2 F! U, h% |8 y5 t
                        fds.SyncWrite( addr, data );
- A" g$ a: u6 k/ g( |                }
; {, F( z( Z% E1 B        }
8 ]9 @8 \3 ~1 I1 X8 j8 K* a1 _3 i' R+ t7 J3 V5 r1 p! H* |% [/ s+ x/ U
        if( exsound_select & 0x08 ) {
2 [$ L( i! V6 d7 e                if( addr >= 0x5000 && addr <= 0x5015 ) {! K- b+ j! b+ q8 f: E
                        mmc5.SyncWrite( addr, data );
! X9 {" D* j7 ~* G- y( |  p# P/ Q                }
' k9 U9 c1 C" l' J, a+ q1 J        }3 r3 W2 t2 m0 _+ r2 S7 l, u
}
3 u: e8 f3 s1 V, E" a& }) p2 Q3 W, {- h/ o) F* D0 r" P
void        APU::Sync()9 ?, e- w7 _6 W; Y
{
2 P( p/ z8 p6 g; `$ a}* y  R& B# o* w, V/ l6 w$ E; e) f
4 {6 G6 M5 J8 E* ]* D
void        APU::SyncDPCM( INT cycles )& I8 r: f0 \: r! W6 _. t6 S8 r2 ?
{
, K; y& y7 k, d+ j" T2 \        internal.Sync( cycles );& Z, ^% v( L  M7 [
9 y4 {4 @- O4 q
        if( exsound_select & 0x04 ) {. X- x, z+ J  e: v4 b, S
                fds.Sync( cycles );
- |7 \6 A% w9 R+ h% m. U8 B& \        }! U2 o7 M, e3 _$ D. m/ J
        if( exsound_select & 0x08 ) {
, J4 g6 H& q; z4 }                mmc5.Sync( cycles );
! @+ h4 o* j3 g6 o% a7 t+ g8 ~* c        }
& y- P- d, b1 O/ @! v! Q2 [}1 W8 V$ W0 e) x, a" z
( n  q: j/ d. o& |
void        APU::WriteProcess( WORD addr, BYTE data ); Z1 Y$ o  b6 a( B5 Y( l" A* A
{3 B) h; Q# T$ m3 |) B
        // $4018偼VirtuaNES屌桳億乕僩
# s* w/ q) y9 @. r1 B        if( addr >= 0x4000 && addr <= 0x401F ) {
3 z4 ]' t% k6 t0 s/ h( R( V. K1 C                internal.Write( addr, data );
- y- x$ Z0 u/ w( S  R* v8 T        }
0 S+ H( a3 C4 c" J5 d4 G}9 F; G7 T0 K8 \- s  m

' E' {- U" x7 Q! F& u# Qvoid        APU::WriteExProcess( WORD addr, BYTE data )
/ r( P1 r' d# m6 x; j% @{
# S" |, Y: R: V0 J4 y        if( exsound_select & 0x01 ) {
3 I/ z4 s2 u, \$ K                vrc6.Write( addr, data );) _2 o2 u0 p% G& a. h  A5 t9 F
        }" v4 \! K& f4 S' g" \% H
        if( exsound_select & 0x02 ) {
! i% J: e% z2 D! Y: Q% I: m                vrc7.Write( addr, data );" ^' u/ N  Z$ C4 Y2 V$ M
        }+ ]4 T  f, u+ ^7 f; Y5 e' _
        if( exsound_select & 0x04 ) {
1 X% W2 ]) V. B$ N) W0 n# z1 s; X" T                fds.Write( addr, data );
! i" j9 q- E2 ?% R9 A0 V8 E        }  b1 R; I3 m/ T, [% W; \. ]$ _/ ~
        if( exsound_select & 0x08 ) {
% f7 {! t% w1 g& w1 W* X4 d                mmc5.Write( addr, data );
. A2 h# \7 f8 d2 u        }1 e; d( c) d! m! N
        if( exsound_select & 0x10 ) {2 P( @" g  u- ^5 p
                if( addr == 0x0000 ) {1 b2 B3 d1 k! i- _8 k9 h9 L
                        BYTE        dummy = n106.Read( addr );9 n, i  u! l' D! ]$ |3 z0 Q
                } else {/ r6 w5 R) i$ k
                        n106.Write( addr, data );
7 Q& |+ _" k$ r5 k6 k1 b                }
! x; ~" c$ _1 t$ Z3 h4 u& Z$ g        }
! k9 J0 G, [7 q/ k        if( exsound_select & 0x20 ) {9 k4 U0 p- D$ B$ N
                fme7.Write( addr, data );' j/ C# f5 K# N, J0 ~2 h8 Q# w
        }. D+ [" f' D  e5 \7 U5 i4 D
}
0 ^. ^' ?* T( j1 v9 {
. [4 s! ~* V3 u! L4 d' P& fvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )+ R* f3 l1 g  ~
{, |- F0 ?0 l2 ?" t6 E; D% v: Y
INT        nBits = Config.sound.nBits;  W; d7 t, o8 C, Z+ y; y& y* R% N& e
DWORD        dwLength = dwSize / (nBits/8);
4 A4 Q0 S" l8 d  v$ F6 qINT        output;
! F9 u+ B7 P1 r/ s- iQUEUEDATA q;) ^, h. t: f( w9 h2 w( z
DWORD        writetime;
- J% l& i0 m3 _* C& {7 f# `5 m, E, N
LPSHORT        pSoundBuf = m_SoundBuffer;- ]! b2 R: c2 V- z* V2 E" f
INT        nCcount = 0;3 D; b9 E  f% S6 Z( r7 d/ v

0 j& V) N0 W9 m) b! EINT        nFilterType = Config.sound.nFilterType;
% b* c  E4 c% x# r
& j5 r. T, L: `; S; y; H+ K        if( !Config.sound.bEnable ) {5 _- L$ f- N- d3 N. [: }
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
' c; S( e; N, U; u( B                return;
( z" K6 `0 e' U% j' E) S- a. k        }; c7 A; D9 v3 z# F# t: L2 e
% |/ p+ h0 a1 Y; s3 {
        // Volume setup9 @2 |# d! H5 M+ {2 G& f5 t) c4 Z
        //  0:Master; H6 X3 r  c$ H6 a. i6 c
        //  1:Rectangle 1
! G# {; P; r+ Y' w0 v$ r1 t        //  2:Rectangle 2
; U+ Z$ L% H$ g! Q' y" M        //  3:Triangle
. |' D( I3 I% q- M        //  4:Noise/ {. H" c* f+ c" _
        //  5:DPCM, X5 q1 Z" j  x* O9 x
        //  6:VRC6; \- z" C& m5 [0 x
        //  7:VRC7
# B0 ~# N' e0 O- o) M4 K3 W        //  8:FDS
. |1 `% @" y) g6 n6 n0 E$ Q4 s        //  9:MMC5
6 y3 |# ~. K5 m, i6 U        // 10:N106
. w6 z" f( B1 _) d/ f3 Z        // 11:FME7
8 Q( Z1 R8 |$ L, M        INT        vol[24];- ~0 s) V+ v" k& g! ^& ]
        BOOL*        bMute = m_bMute;
% ~1 }# r* S, C. f+ ]        SHORT*        nVolume = Config.sound.nVolume;
* r- y8 O- i1 C4 A/ s2 G$ I1 ^  N# U+ Z. i# E
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
. H9 H( K" n0 Y) f) |7 ^9 ^  n' v2 D* Y# o
        // Internal7 X; P* s- v5 z0 a$ {0 }
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;: c# z5 J& j/ m* ~9 V( K; s
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
0 T* J/ u! W4 M  c" p' }% C        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
2 s7 s& l: \+ O: r# T# }# ?        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;( u( c+ K! f7 V$ ^& w
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
7 \; o" D/ b# }0 B5 [, e, `9 V# p3 k
        // VRC6, y% z1 i- _: q% j" m0 K9 C8 g
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
0 Z9 N  q  y+ q+ R: m' r8 |$ A        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
1 X- L) I+ n4 a9 B: J6 G        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
+ f& F- y4 d8 @1 A" A4 d) c8 j
- ]# ~4 [, o7 s" x' }, p1 R9 d        // VRC7
% w( r. k* a% z  F        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
. h7 _% @# o& Y( ?3 |- H
5 R. p- O# j/ d- O2 Q" u* ^4 g        // FDS( D' P' o' n+ Y0 m) V: q( L0 L* v
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;0 D. b' s* q# L& ]
. s4 F$ B4 q  o, x6 f" {" c
        // MMC5
/ o5 R" ^' o6 q) L        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;0 }: d+ t  F- O/ m9 k/ y
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
; l: w7 A* n. N# V& o: z+ j$ Q) g        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;0 Y4 R4 x) V: a6 D, Y: C6 w/ f( f. F

9 J( s9 B* G4 ~. C        // N1064 G6 P2 A5 v/ W* {
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
( p& G& t1 a# i, }        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
4 m! c% r0 N4 j! |- a6 ]7 e        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;" U/ ?% ?2 E+ k% e! c2 K* F# D
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;4 z% A) H% D" L& O$ O: m7 x
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
$ A( A5 `% _! c$ ]- T) n) c- B+ b        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;( U' T) L1 Y+ x" x/ X! `' w4 |$ I
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ E, t  E6 n/ {. ]/ p; z: {        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: F9 \5 C+ a4 Q3 J9 g, Z: ~$ H0 r. v
        // FME7
' p2 y! {9 s" Z! R% @; e! ?        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;* R3 S$ K! ]! I# A1 B: l& S
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;7 t# t4 o4 N& e! E8 e% R- Z$ C
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
7 p) e  ]+ ^& P- n# k& x; ?: q! L* }1 w4 X9 ]$ Z0 y
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;) u: c( u2 q! m2 N4 u8 c
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;8 G2 r2 O1 y+ Q6 E( o
( P1 f% ~- Q7 K
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟+ |& |/ W; R: B
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {8 M) _) N6 d! N1 [( j: G0 d7 `
                QueueFlush();. N* s  i. U. s+ `2 _( q
        }
) I2 \% @* }# q- h4 |+ U9 p
2 i- ~5 b# c% v, H, h$ Z% p/ c/ E        while( dwLength-- ) {
: }( J9 B( a! _& q  r( s                writetime = (DWORD)elapsed_time;
3 \  \0 s# ~; n- u1 S* M+ j
- |  `* p& ]9 j5 V0 S' i                while( GetQueue( writetime, q ) ) {
. _! d0 n5 Q( k! Z! e/ s                        WriteProcess( q.addr, q.data );4 F+ N% t/ N% f& g0 s
                }
! i1 U$ z/ w! O4 j0 o
6 H# ^- D( M6 W- ?8 A9 _                while( GetExQueue( writetime, q ) ) {
( ^* P3 T- o# g  |( ]) Q8 a                        WriteExProcess( q.addr, q.data );
- c8 s+ _* M) s                }
$ ^7 Q' m& \) r) F' o+ g6 e
% E- S% R- V, C                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME78 {5 }" T" U6 o, B9 k
                output = 0;
7 W" |5 a4 V  h. X) U                output += internal.Process( 0 )*vol[0];
0 J( M2 m  {' Z9 O: ]" \' O                output += internal.Process( 1 )*vol[1];# r( u. m  D" k0 c8 ^4 `: a
                output += internal.Process( 2 )*vol[2];- U/ ~- d8 `& ~6 c- \  H( R* w1 }
                output += internal.Process( 3 )*vol[3];" N8 _$ R2 ]6 D# L4 x& m+ q
                output += internal.Process( 4 )*vol[4];* W$ V7 c  y2 N( ^
3 s# i: G( ~  g, ^
                if( exsound_select & 0x01 ) {
/ B' H; u$ n; o1 y( M# D                        output += vrc6.Process( 0 )*vol[5];9 l2 ]6 C5 n& X1 r+ G
                        output += vrc6.Process( 1 )*vol[6];" K2 X- z# d3 ~" M
                        output += vrc6.Process( 2 )*vol[7];
, o9 y- S' a* u! d# ]                }6 x+ ?) i. H! ^' O, c& X; v
                if( exsound_select & 0x02 ) {
9 o& r+ X/ O& ~6 [- B                        output += vrc7.Process( 0 )*vol[8];( r4 O/ ?- i2 y
                }
" x- X* n" t& T9 a. g5 F, \: r                if( exsound_select & 0x04 ) {
: s$ S, C3 C3 ]! C- @. S" |% q7 g0 f                        output += fds.Process( 0 )*vol[9];0 U) R4 _% b) z1 L3 M+ D
                }
2 j* G# S% O$ `- i                if( exsound_select & 0x08 ) {
/ l# o  E' j) `9 h& ]* j9 q                        output += mmc5.Process( 0 )*vol[10];$ A0 M4 v; K$ ]# n
                        output += mmc5.Process( 1 )*vol[11];5 _( _' r1 ?" ^9 b
                        output += mmc5.Process( 2 )*vol[12];  O4 m. E6 E: B) F
                }
( x) C  v! K5 u# q4 p3 U& j, b                if( exsound_select & 0x10 ) {
3 ?* @9 p9 o+ i& i, \- c8 B                        output += n106.Process( 0 )*vol[13];  V) ^& w! Y0 G9 s
                        output += n106.Process( 1 )*vol[14];, H9 S8 [% i( _" S5 g& r- {
                        output += n106.Process( 2 )*vol[15];( E/ I( U+ ]$ l& _7 C" ~6 x6 S* c
                        output += n106.Process( 3 )*vol[16];2 \$ H0 O% j( n+ P$ g3 y4 {
                        output += n106.Process( 4 )*vol[17];" O9 O! f6 k  K* Q  I; N
                        output += n106.Process( 5 )*vol[18];
5 _6 J* a2 i  `* k5 g5 l" v( G5 k                        output += n106.Process( 6 )*vol[19];
0 y7 V# O2 F5 w* V$ ^3 M4 v5 X                        output += n106.Process( 7 )*vol[20];
. a4 q3 B+ z1 G" y; ]                }
7 ^9 Z& j  o* [- L- |: n% m                if( exsound_select & 0x20 ) {
. n6 Y3 I# U. S( i) \4 s. G4 p                        fme7.Process( 3 );        // Envelope & Noise
& {% ~/ n/ j. r4 F6 J( {* u                        output += fme7.Process( 0 )*vol[21];
2 A' B6 i6 l$ s) v- ~                        output += fme7.Process( 1 )*vol[22];8 e% Z0 L. `9 `6 ]4 y& ?( C. Z6 L
                        output += fme7.Process( 2 )*vol[23];7 d" ]9 j2 W7 J/ D6 y
                }
6 }. H% u0 x( K: c- Q4 V6 L; ]' E; `" ?  q. d0 [
                output >>= 8;
2 M' s1 M! X1 K
3 J$ @: j  P% g# x, J                if( nFilterType == 1 ) {& Y5 }! f8 r2 s. z' R2 P* D" Z$ p
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)) _. `% X& _, m+ z0 e! h
                        output = (lowpass_filter[0]+output)/2;: r, m- r3 a( r& ?+ M. z1 o7 @
                        lowpass_filter[0] = output;+ ]' z8 {+ v2 J3 }
                } else if( nFilterType == 2 ) {' ^" x8 x6 d0 X/ L7 O5 a
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1); a3 u2 m! }1 j7 t
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;  ^% t9 U3 h- `9 }! ~! t- r; t' A6 x
                        lowpass_filter[1] = lowpass_filter[0];9 w& ~, F% ]  I4 h! M4 f
                        lowpass_filter[0] = output;( E& ~3 _; q9 j5 G/ B) W6 P* I
                } else if( nFilterType == 3 ) {
% n% [. T% `6 d; J                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
3 e, t) w1 `% `( y5 ~5 p/ G                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;) L0 a  f/ L9 C
                        lowpass_filter[2] = lowpass_filter[1];
& n" t& ^6 ]2 \1 @5 ^                        lowpass_filter[1] = lowpass_filter[0];- {8 N/ v/ @+ b6 Q
                        lowpass_filter[0] = output;
7 B2 t/ w) ?# Z5 l/ u% ~; {                } else if( nFilterType == 4 ) {0 q$ q4 x7 Y( F% l, X( v  k2 K
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)) j/ G4 L. A, p0 X1 `
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;* X& U/ m% H9 F3 G; }( f
                        lowpass_filter[1] = lowpass_filter[0];; A+ Y# c* A) p/ X0 h- ], f
                        lowpass_filter[0] = output;; g% d& x4 k! O' p5 s
                }
# @, C; E$ u+ L, R, `/ z" w& Y8 b. J) z
#if        0
# @- s6 N( t* T& u. `+ t                // DC惉暘偺僇僢僩' }2 }3 b/ k$ b  }
                {
0 l( u: C" T0 ?9 E, |                static double ave = 0.0, max=0.0, min=0.0;9 U7 Z; }  j7 j7 [
                double delta;
* S- v- O: j) M$ R. B                delta = (max-min)/32768.0;. R7 `/ q4 s5 W  ~
                max -= delta;
/ x0 F- y# p$ M( e/ E                min += delta;
, Q  Y$ o$ }, P& i$ y                if( output > max ) max = output;
4 q& E& l: {9 M9 r: G                if( output < min ) min = output;# y$ _$ ?* u/ P& J
                ave -= ave/1024.0;
1 W$ D3 K2 r4 X9 E                ave += (max+min)/2048.0;
+ }6 p% z- Z5 x6 j! `" ]6 }" c                output -= (INT)ave;& l+ \7 {( c& I& `: b# x; M
                }3 N! n4 V! g" n, c  C  R
#endif8 O# I# i. I) t& a$ w; N
#if        1; D6 R4 M: C  i1 a. r$ i% T
                // DC惉暘偺僇僢僩(HPF TEST)
' l" P8 |7 W; K% [' m2 |                {
4 a: P5 d; T- I$ i  L7 \. v. _; c//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
) s/ }5 s) n5 \                static        double        cutofftemp = (2.0*3.141592653579*40.0);
6 Y% ~; b1 Z' R6 ?; T                double        cutoff = cutofftemp/(double)Config.sound.nRate;1 t; a9 ^# ~  d/ f% j% _& @: B$ j
                static        double        tmp = 0.0;
8 K8 h3 I/ F) O9 j4 {" @. u                double        in, out;
0 p5 y' T8 \6 Z* g* |# d5 r; w. L* U5 X$ [% T
                in = (double)output;
% H7 L  [- H/ ?3 }: K2 h                out = (in - tmp);' ~. Q7 i/ _0 p7 @+ h/ u! g
                tmp = tmp + cutoff * out;% k0 I8 M# h5 ]
" N; X& f! A5 x# i, Z" b
                output = (INT)out;/ M# J$ U3 H: @
                }) U# M) N9 A4 X9 k3 A7 j8 o6 {
#endif
% ?. c6 E! N1 _! K2 G; `#if        0
& O* X! d- ]9 q5 M                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
) K$ z* p# I" r* l  F% w                {& ^& T1 D8 N+ D
                INT        diff = abs(output-last_data);
" c4 A; P) A/ H9 b0 c" S7 \                if( diff > 0x4000 ) {1 w' ]3 Z& z8 x1 P$ b7 {
                        output /= 4;
1 j3 K; ^3 V; \$ z; u                } else 6 D, s3 _& U+ d4 y7 v9 x" P# u& N
                if( diff > 0x3000 ) {' ^+ j1 g* T- I- x) f, M* g! n
                        output /= 3;2 h4 r. c7 {6 r& o1 a3 O9 p1 q5 J
                } else" i2 C6 i, g7 Z1 c' n
                if( diff > 0x2000 ) {3 {0 c: N. v" H* o+ C) c0 }
                        output /= 2;, M3 I9 H* k9 z' l/ t% ]
                }
- y2 X9 p: ]: r8 G                last_data = output;9 e7 ^& c" w# ^6 Z
                }
, n* y3 C- ^% C0 E, d#endif
" N5 x, I1 `7 u3 r1 D                // Limit/ f; _" E9 |. \: c9 \: K
                if( output > 0x7FFF ) {$ b" m3 L# g: o. E+ J7 w' |
                        output = 0x7FFF;
0 O& i- _' m) S' X2 X' v8 O: A                } else if( output < -0x8000 ) {3 `& J& n) m$ s6 K4 k9 C
                        output = -0x8000;6 x( H) y2 U. Y6 x
                }. a) u/ E$ n% x7 |' T$ ]

/ \' }" T$ W: I- F: v1 S" }                if( nBits != 8 ) {
. ]# }$ B8 w. A& \: G                        *(SHORT*)lpBuffer = (SHORT)output;% e& c. Y$ B+ u# p& q7 x
                        lpBuffer += sizeof(SHORT);
. S, @- I+ Y* n& V. M  `                } else {. X. m5 M5 p$ b$ w2 A9 q5 Q+ V
                        *lpBuffer++ = (output>>8)^0x80;
+ {. [: [8 c0 P% G# A% X                }
+ J! V0 L" N9 _
2 N1 m- q2 w& _' i                if( nCcount < 0x0100 )8 ^- Y) s' u' T) t. H+ {
                        pSoundBuf[nCcount++] = (SHORT)output;+ R: I7 A2 W* L' ^

" `6 Q- Q/ |! U8 q//                elapsedtime += cycle_rate;
1 }' l2 S" N7 V8 n- s1 {" _                elapsed_time += cycle_rate;
: _" H; `4 k2 s) ~7 X        }
/ }: |( q9 S: F5 |0 W6 X+ i/ |7 x$ E  m
#if        18 |9 X8 r& r) p
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
! O: D+ |. J7 `* q0 c/ Z- k4 J                elapsed_time = nes->cpu->GetTotalCycles();+ [6 a3 s$ ^' _1 ~
        }4 d, ^/ R8 F6 i2 i
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {; L6 i1 N2 i7 L9 `$ `1 A
                elapsed_time = nes->cpu->GetTotalCycles();
& V4 x2 M0 Q5 v/ ^9 C        }
7 {2 s% I, ]! z+ T! Z* F. a: m#else
5 {1 c# W& p' d5 W6 _# T        elapsed_time = nes->cpu->GetTotalCycles();0 q7 |  j) N8 t" S9 Q, f3 l
#endif
$ X) Z/ a4 R: f3 A+ Y6 _! u}/ m" a2 p* {7 s7 d$ f6 a, x2 [: b
- S( M4 b# t8 W
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)+ r: x$ u* v# C' v. t% T$ B! o
INT        APU::GetChannelFrequency( INT no )# f: A9 a# y+ y! c5 J
{+ ?" q) |; _) g/ A0 I6 h7 P
        if( !m_bMute[0] )
/ C" G3 Q3 \( \5 G% m1 X                return        0;
, d( m, ?8 M+ W3 w
6 \3 g7 z5 m/ r% P        // Internal
3 T2 U' X  C3 ^( `( r5 t        if( no < 5 ) {
, r; n2 Q* m' Z' l                return        m_bMute[no+1]?internal.GetFreq( no ):0;! U! ?) {% K7 T, l0 U) y7 `$ X4 ?
        }6 R5 O0 n* r9 [% ~( v. K# y; \+ n
        // VRC6! v& V" @  J0 r. K$ x' z  b- F
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {: P* S- q+ R0 D. n3 V
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;& v. E/ l2 B6 A( e
        }5 m4 U6 B$ _  |0 B9 j) n
        // FDS0 b' A% \0 L5 k3 e# k/ f6 H9 Y
        if( (exsound_select & 0x04) && no == 0x300 ) {3 v: C! {6 W0 O. N+ r
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
0 ?. F4 }$ B/ p        }
5 y3 Z) h* D! O3 ]( }; _        // MMC5
2 e9 s' V1 z0 A9 Z) f. s* N$ B" }2 b        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {  h4 e8 C) x, H
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
0 U: S( _( v% G2 X9 U6 {        }
1 h+ \, n  Z/ O0 _        // N106
* N) A; m1 A& J0 d7 x        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
5 ?) u/ T7 [  T9 ~                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;* y: `, g6 C: _( }6 l; s/ K
        }: u. Q6 m" I$ u& k/ H$ v! K- }
        // FME7
' r/ y0 P1 C+ q  o, G3 M  q        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
( b  }& n1 }0 H4 A, v+ @                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
, v& t. B: J5 b0 B9 V        }( f1 I' w8 _3 R5 {, M. S) u$ k
        // VRC7+ p3 v" K- g, b
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
" G; P# }+ E7 n- Z; Z9 C                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
' r/ ~8 \7 {3 s9 {& ^( {$ M        }
& C' g& W' O# y0 c8 F6 o        return        0;
0 R* O5 ?8 l7 f( ~9 H- J% N/ ]6 _}
5 [4 `6 ~. U0 ?7 o6 h( s8 X: M8 q* o9 }8 k" ]: Y( |5 y5 t; d: ]8 v* ?
// State Save/Load
& H; M+ F$ e' ]& t8 D- vvoid        APU::SaveState( LPBYTE p )
$ O5 K) e" B. r! u% ?9 v{
( `2 \# B9 D7 f; i! @) d#ifdef        _DEBUG1 v9 j( N# k; ?% z4 i8 \: G$ _
LPBYTE        pold = p;
4 e2 S' @( ]2 B1 S6 k/ H" j* D#endif
: L; v! B' P% e( |  n! _
$ |% E, e9 [9 A0 ]+ O        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
8 g3 w& {% y  {& F, X$ Z        QueueFlush();# B& X" G7 p  _( R$ K
  D! d0 S( @% [4 B
        internal.SaveState( p );
; ?5 E9 Z* [' h5 m4 F        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding/ l- U/ W6 H. J. b+ W

; W2 X1 n: |5 C6 r" Z) O, e        // VRC6
6 v; @2 ?0 P7 @7 n3 E( }0 ?$ L* a. l        if( exsound_select & 0x01 ) {9 ]& N  C, B* p" [! x' X4 F
                vrc6.SaveState( p );
, J7 \2 N, s/ M, w% S                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
/ `0 E6 s" L, e" Q7 \        }9 ~( \" J- h4 |0 }2 o9 Z; j  ]+ e
        // VRC7 (not support)5 C- |" ^3 I8 h1 K& ]  \
        if( exsound_select & 0x02 ) {
3 h; J. }. ^, f/ z+ K& |& x                vrc7.SaveState( p );
5 P6 L# Y8 y+ ~! v+ v' T                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
2 \4 \6 t4 P* _# U' w8 R        }* v, G/ @: V* H$ p
        // FDS
: D0 s4 n9 S, D3 L" Z1 }  ]; ]7 w        if( exsound_select & 0x04 ) {, G. f& R9 _! y6 ?, x  i
                fds.SaveState( p );& G$ A- s1 _2 \* @; _: c
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
# v$ Y* [" q9 g3 H5 }  z0 {3 Z        }- p- G* R4 _) p8 ~7 p( B7 E* p6 u
        // MMC5
" u9 Z+ |. F' p. o        if( exsound_select & 0x08 ) {5 K% V* [: j& s4 S: b4 h
                mmc5.SaveState( p );
; Q4 ^( V) R( d8 C6 o                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
( E3 G3 Y, T: \+ A$ S        }
/ }8 k& Y0 J6 m0 \6 L) ~        // N1062 n6 T, h% a1 C+ R1 K
        if( exsound_select & 0x10 ) {
: t( N: I& @$ B$ o0 H) @                n106.SaveState( p );
& s, f. ~2 r3 \6 `' f# y                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding: e3 o; c4 ?- M# w% v
        }$ [/ |8 |7 u* Z, H
        // FME7+ S  r* f9 q+ A/ P  M) Q
        if( exsound_select & 0x20 ) {6 |) X  y. |' g
                fme7.SaveState( p );) u$ f- W) _( P0 w7 w2 Y2 W; H0 F7 _
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
+ \/ G8 s+ a4 V5 I. P& A4 B        }2 J$ r' ~1 ^8 o' Y6 S# g
/ P& ]5 _6 f" w: Z, c3 n8 t  C# F
#ifdef        _DEBUG
. {; g$ Y, Z1 Q1 G0 q% X% b8 m. CDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
% ], H1 f0 C8 v: w" n$ {5 A( ]8 W#endif
/ [' V' F+ K4 o- k. M. |8 s+ j}& O! I4 d1 F; G5 n0 H% w( ~, `

  [4 G/ ]. p9 J) T5 h, U; F* x, x* dvoid        APU::LoadState( LPBYTE p )
& _8 f) S0 o: ]; c{
0 B6 I4 K- X# @( @; ?! H: v. J        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
9 g) Q* l& @/ Y6 F  @  E& g3 j        QueueClear();$ e6 C& n  ~& @( D3 y8 X# s
! O: u  J$ L' J3 K2 N' [# L
        internal.LoadState( p );3 `4 h# ^+ i" |" u1 k
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
: ?4 c% O; _& u- Y. r5 u/ m# l  v9 Y; u' J) k
        // VRC6
( Y4 F6 u1 Y7 r" n9 L" P4 m4 D  S        if( exsound_select & 0x01 ) {- h* o1 Y. U% w9 A
                vrc6.LoadState( p );/ Y$ \* y* o( E( D) A; H
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding* i2 `8 D* U4 Y3 W+ X+ t
        }
! i8 o8 y! Z( ?$ f! j* i  q        // VRC7 (not support)
6 r7 `% z9 m$ q4 d/ U        if( exsound_select & 0x02 ) {9 D: R; j! N2 ]1 r- M
                vrc7.LoadState( p );/ ]; r$ ]! P& ?& U4 }; }) l
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
/ E$ J3 a' U; n" @; @3 m/ u4 h        }/ F$ N1 }0 h+ k/ N& p4 @% q
        // FDS) ~3 l( w6 ~. n3 C& Z$ G
        if( exsound_select & 0x04 ) {+ u! n" v1 l( x5 ~+ ]6 P7 S' @- i1 O
                fds.LoadState( p );% |7 A5 b/ ]8 {7 u1 ]
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
" d4 {, `. o/ E" e& V2 l) R        }
0 e& N- ^; _3 v# [0 y        // MMC5) b' L/ S; }' F' Y) ?% E& t9 \
        if( exsound_select & 0x08 ) {* Z+ p& a# W+ Y/ t+ f
                mmc5.LoadState( p );
, G! j6 b. e3 S+ P                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
3 t: H: z' M# `3 _+ F  F        }
  [& \) H3 J" r1 z" W+ H        // N1069 s4 |. D9 d+ E: A$ V( Z
        if( exsound_select & 0x10 ) {2 m# u9 T( |9 H) m* d, A
                n106.LoadState( p );
" P# P3 D0 ]5 \- L                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
8 K6 h2 }1 o- L; S! a  x3 Q2 X        }
) Y8 @, ?2 R' X7 }        // FME7
1 v  V: D2 F' n8 j! h- s1 V, [8 L2 W2 l        if( exsound_select & 0x20 ) {: K' H( j8 H) C1 ]
                fme7.LoadState( p );: q( J( n" f- W5 Z# c3 ]
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
* B. ~" T" y- ]. X0 z        }
6 a1 i4 [5 {5 |: ^+ f) F}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 ; g* ^5 ~2 g! M6 ^
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
8 Y. ]: n3 S, B. F4 \感激不尽~~
& O" L( D% t' G# \' r
恩 我對模擬器不是很有研究,
. i+ F% t4 }: B雖然要了解源碼內容,可能不是很困難,
8 e$ q; z- w: n% W4 W$ f0 ?, K  F不過還是要花時間,個人目前蠻忙碌的。/ n+ j6 y2 }4 }, S% z) f8 I0 |
- y2 Z  ^3 e6 k2 J/ A( Q
給你一個朋友的MSN,你可以跟他討論看看,6 O1 \: p* F5 h* H% F+ V# b
他本身是程式設計師,也對FC模擬器很有興趣。) {, ]2 i3 [6 B% V+ v

3 ?* p* q. X% a% }- ?4 Y. ^MSN我就PM到你的信箱了。
0 _, @+ b+ R5 y' x: r
3 T  I9 @8 {- P: C+ g希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 3 y6 Y9 g4 t% O" C0 N
呵…… 谢过团长大人~~

) M' W6 W0 }" P+ f8 N* j+ U( ^' Y' |8 @2 p: ]! I/ }; r" I
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
; J) u4 D7 ]; N2 e团长的朋友都是神,那团长就是神的boss。
: ]  V/ O6 ?) ?+ s; m# `, h7 a
哈 不敢當,我只是個平凡人,
4 ?% d6 {9 l; J! n* k要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙2 `/ J8 }5 F: e+ Y; s( _
ZYH) Y, C" ^* U1 y  V
QQ:414734306
- X# X4 r7 S; V) F5 f& IMail:zyh-01@126.com
8 e' K  O- A: b# v) o( }% }: F9 B* S; o2 p7 O6 `
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 9 V4 ]4 |. d+ s7 J3 H/ _8 P
再次对团长大人和悠悠哥的无私帮助表示感谢~~
$ N5 X+ W  N6 Y% w5 r  c8 T
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-5 11:56 , Processed in 1.083984 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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