设为首页收藏本站

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

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

  [复制链接]

该用户从未签到

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

该用户从未签到

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

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
  x  L$ {$ T, O. V; ]( F楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
6 h( Y( F( g' d$ {5 `  Y4 y这里有相应的模拟器源码,就当送给大侠了~~: F! V" d8 A* @+ |1 G# s! u) ~4 o
http://kenkao.qupan.com/5096520.html
回复

使用道具 举报

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
6 ~/ h* x( J9 _1 a. H+ b能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。: W' }. R& Z8 y2 h, `+ b0 z1 b
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
' N$ @  T( B% r2 d/ ]这里有相应的模拟器源码,就当送给大侠 ...
2 ~* u, o& f  H
聲音部分(Audoi Process Unit = APU):& ?& T9 l0 |) \( g- A7 M
.\NES\APU.cpp
6 R1 E4 U( r7 d  [+ }6 K1 ]0 D.\NES\APU.h
; d2 v$ j. Y) s# ~+ T+ J$ p0 ~5 Q# u, y& b' W

5 O/ o# q  d" R! Q. @& y* }影像處理部份(Picture Processing Unit = PPU):
, `7 H) |( ]' b# d+ M.\NES\PPU.cpp+ Q; y* j, b$ N4 U7 r
.\NES\PPU.h
" C3 M6 z. h# ?8 M% E  n9 y* p
) x6 D! @; t2 k& G5 Q# Q+ X+ H) K5 Y. ^如果原碼用C跟ASM混搭也不錯
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
! I) v$ f4 o. q7 h+ C- ~感激不尽~~
回复

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:6 G- W% i; U) x% t0 r$ ?, Q
(由于很多专用术语和算法机理都不明白,所以看不大懂……). {9 J* \5 n  H, E; U5 k5 @
//////////////////////////////////////////////////////////////////////////
0 y1 {' m) J' r' V4 N$ v& ]//                                                                      //+ K4 q; l7 }6 n! C9 y
//      NES APU core                                                    //( G  M" ^& a; {6 |  w
//                                                           Norix      //6 d" c: e: F' L3 S) V
//                                               written     2002/06/27 //
4 A# U( T8 h, `1 W6 G, Y& p//                                               last modify ----/--/-- //5 S, P8 |& V' s( K
//////////////////////////////////////////////////////////////////////////2 y/ r; B3 s& T6 Z9 C( g3 v
#include "DebugOut.h"
8 c# w9 X* [) u2 c0 r7 j+ W* r# t( u#include "App.h"
7 p% r: j) b5 f7 R; I/ h, ^& s#include "Config.h"( Q1 n9 o. L7 i1 o  I4 y" S
" r2 t# F# g' d; q) m) j& D
#include "nes.h"
& t# [; A4 t7 V#include "mmu.h"- s7 `% k7 t& u1 w2 m  k
#include "cpu.h"& T4 i) h7 s2 ?0 A7 a! J) X+ L
#include "ppu.h"$ {% g) f4 R+ O1 U/ L* u
#include "rom.h"
/ m1 X# Y; T( Z8 p  T. I% J#include "apu.h"! e4 C( `- y+ X0 ^# K

8 r. h$ Y" H* i9 J// Volume adjust
0 e- l3 V2 q; _8 p, m# t, u// Internal sounds
0 O& P9 [; K/ T+ V$ `#define        RECTANGLE_VOL        (0x0F0)
" s. Y: z) g3 H#define        TRIANGLE_VOL        (0x130)0 T1 ~# {% T$ }2 |* P: g+ Z
#define        NOISE_VOL        (0x0C0)) T5 L5 w3 h  i# U1 o) J; M9 B9 L3 I
#define        DPCM_VOL        (0x0F0)
" q: ^3 a; c7 e' J. Y// Extra sounds
# S; ]6 x0 K+ _#define        VRC6_VOL        (0x0F0)/ h; L0 n+ }3 f$ K$ p; F
#define        VRC7_VOL        (0x130)" ^5 X2 i9 w( |+ ?" Q
#define        FDS_VOL                (0x0F0)) {/ A  K6 b% Q$ K* B
#define        MMC5_VOL        (0x0F0)
/ i0 u+ o2 V* m4 o#define        N106_VOL        (0x088)
6 ]8 D" Q) A4 n  E3 E0 t+ }2 f+ a! ~#define        FME7_VOL        (0x130)
4 L, W8 x. h. o$ Y+ \& o4 ?& Z1 `# `' j3 V+ Z
APU::APU( NES* parent )+ l' b" |! j- d1 z% W: a
{
  }  w) J5 u+ [4 j/ V, O        exsound_select = 0;+ `" I7 m4 x  g  M, E5 E$ Z5 D% R
2 }  W4 F- m" j: ?1 ]
        nes = parent;& [) x) Y. H1 Y% v
        internal.SetParent( parent );
" T( b5 B& ?6 m3 d0 h- f( w  L2 m
, `5 Z' w5 i) H& w        last_data = last_diff = 0;, @% ~6 N+ ~9 Z! R5 `

0 X- h$ s* E4 `- @        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
$ |- q6 K8 k* N
5 {  M$ k* n# H" X- s! I) x& g        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
5 B* W& W9 s! v        ZEROMEMORY( &queue, sizeof(queue) );
! m6 b7 h3 n( ^6 t3 l        ZEROMEMORY( &exqueue, sizeof(exqueue) );
* ]9 ^! W: _9 Y5 U8 _# f) M& x) M
. Z$ H+ @. D5 d- P, ^        for( INT i = 0; i < 16; i++ ) {
, G* Z' |, \4 D' ^1 _4 W; j9 e. V                m_bMute = TRUE;: W& z3 A" j! I: Q4 m$ X- e# H
        }
% K" S) g& R5 S2 Q$ y1 e}' ^. e& L& H) H* W

6 C; F6 c+ P6 \- t% @APU::~APU(): D7 r$ d1 M4 A; ?* s" s5 m1 H: ?
{# V5 S0 M1 J' ~6 f
}
. d; b9 T. W- i1 x9 a. |$ R! Q3 u
& H3 H  x1 F) P6 D3 g5 Cvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
5 I+ W# B) A( w  M1 Q" R# W/ z9 q# d{% G  G3 b3 ^$ F# Z5 o
        queue.data[queue.wrptr].time = writetime;( I/ G0 x& i( c' n- j
        queue.data[queue.wrptr].addr = addr;; j7 o6 a' f6 ^5 O
        queue.data[queue.wrptr].data = data;
1 p9 t7 y- u3 z+ m$ T, r8 ^% S2 L        queue.wrptr++;2 b9 u2 r; G& b6 L) X( w
        queue.wrptr&=QUEUE_LENGTH-1;# K6 {% R( M0 O4 H: g7 }* V
        if( queue.wrptr == queue.rdptr ) {
* {6 w: a: X$ Q3 L+ ?                DEBUGOUT( "queue overflow.\n" );3 {  a# l9 A- p
        }1 c2 O. ]) t; e  ]
}
+ B( f4 p( k; z8 {- I$ a; D- d2 D  @- y* q+ T/ H* U; \
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
3 n4 G' m6 |3 g$ x6 b{- W8 }$ O8 L+ Z& i7 E
        if( queue.wrptr == queue.rdptr ) {6 c$ x2 O6 E. c1 H) E
                return        FALSE;4 P. g  t1 s  L( |
        }, l# t! U6 f: ?- Y, v6 C8 L% ~
        if( queue.data[queue.rdptr].time <= writetime ) {0 g4 p6 |* M" N) B
                ret = queue.data[queue.rdptr];
9 B5 b; i- e) t6 I7 N  y6 [# t                queue.rdptr++;
" u1 T9 e, F1 c* _- s0 m3 x0 X% M                queue.rdptr&=QUEUE_LENGTH-1;  w' l  I2 }/ o7 h6 a2 x" y
                return        TRUE;3 |7 S  U& q( e3 U
        }
; Q% [/ t+ |. w4 F2 l; y/ z        return        FALSE;1 o; |: ~2 O# r" }4 T$ p. J3 X
}& o1 k+ o9 @5 @4 l' L% ?( Y3 Z

) C# B1 Y$ {! z3 ^! r0 b/ j4 uvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
6 w) d" S* w# }+ D* e{2 _: q2 S1 x7 S' @% D/ I! I
        exqueue.data[exqueue.wrptr].time = writetime;
6 \: v+ w5 E. n" ?; W' M" \        exqueue.data[exqueue.wrptr].addr = addr;  h' m* U7 ~6 u* h$ q; A9 J; y0 q& B
        exqueue.data[exqueue.wrptr].data = data;8 `/ \0 X, ]' M$ q
        exqueue.wrptr++;
. ?1 c& ^" b) J& S        exqueue.wrptr&=QUEUE_LENGTH-1;8 ~9 q0 O/ Z% I3 R- k' M
        if( exqueue.wrptr == exqueue.rdptr ) {
/ c6 O0 \6 h; S0 N* q) S$ `                DEBUGOUT( "exqueue overflow.\n" );# m; U/ {$ g) ?1 {4 t5 D
        }
5 Z+ A( p) H6 {( [& N, D}
  w$ F6 w$ v2 B) y; Z8 Q( d" q9 b& d+ @2 c
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
7 R8 i* _% a/ t; j{
* w! _4 h; M, y) E7 a        if( exqueue.wrptr == exqueue.rdptr ) {
9 ^  E5 s* U; C  [1 a5 I$ T' K                return        FALSE;
: z( O7 n/ B( G        }
. x2 ~  K! G  B5 X( d/ Q6 s1 p        if( exqueue.data[exqueue.rdptr].time <= writetime ) {" W; R, a! S+ O  E. y" Z
                ret = exqueue.data[exqueue.rdptr];6 _" i$ `1 g1 f6 [
                exqueue.rdptr++;
- f; T' n- k9 i5 g4 W. {4 g                exqueue.rdptr&=QUEUE_LENGTH-1;
3 e& R6 G( [0 B( j5 S& b                return        TRUE;
& m7 c- I4 ]& z4 r        }+ G* s3 T! I' p/ M  J/ m
        return        FALSE;% U' B$ O# P% O9 C+ ^7 d
}
3 o+ g6 v1 n; f$ g4 X0 T4 X2 h1 i, P, ?3 z1 J" {' j' F7 B
void        APU::QueueClear(); j9 @$ ?; b) J& n% ^' d% t
{
% L2 |' |" P) N5 U) o# v, M        ZEROMEMORY( &queue, sizeof(queue) );
) I; i* p2 X8 n0 Z  [# Z* V        ZEROMEMORY( &exqueue, sizeof(exqueue) );& x) ^! V* r, M" Q" R
}; H6 Q9 f: Q$ L$ X: c; \
" v3 w2 S& k+ D  C5 M3 C
void        APU::QueueFlush()
* ]) F, }% R8 c9 x3 R{$ @, o! j# h8 j2 j4 K
        while( queue.wrptr != queue.rdptr ) {7 Z/ Y3 \6 y' f+ Z3 C
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
: ~4 p) I, m* J( }                queue.rdptr++;
3 m  ^! y, R& f- f$ [7 X$ N                queue.rdptr&=QUEUE_LENGTH-1;
1 v& r% Z/ Z" U# \        }# p/ g" ]9 ]2 q# `
; |0 B, }% `8 Z4 N" h* j
        while( exqueue.wrptr != exqueue.rdptr ) {* Z$ q- M9 I' _
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );: }6 }* q9 O$ L; `
                exqueue.rdptr++;# V# n" ~, T* k, a* _
                exqueue.rdptr&=QUEUE_LENGTH-1;( d( k, r: {( u" ?
        }
/ l- _9 }4 l5 u! u8 Q7 m# N9 h5 q}4 Q% v9 ~& L% D9 {. C

2 i* i6 W( E7 m: e# ^$ cvoid        APU::SoundSetup()
' K+ I/ |8 \& u4 j1 _  S{; }/ z; B7 h3 X  i" m% I9 W
        FLOAT        fClock = nes->nescfg->CpuClock;4 N/ J1 F* U( T* m# Z. W! Q
        INT        nRate = (INT)Config.sound.nRate;
/ {# q; z3 r: i- u: P        internal.Setup( fClock, nRate );
% |' }/ w4 \" f$ c2 h) K% B        vrc6.Setup( fClock, nRate );+ A; b+ q9 h4 }# R6 W# K
        vrc7.Setup( fClock, nRate );8 Z& m) g9 a, q& q1 Y- m# ^+ s
        mmc5.Setup( fClock, nRate );# W+ n: `2 n7 E
        fds.Setup ( fClock, nRate );
# O2 }( d" L' l+ q3 X        n106.Setup( fClock, nRate );
9 T& u4 t  S/ M6 @# F. w        fme7.Setup( fClock, nRate );
! n7 b: N( E1 \# o/ ?}1 i) a1 L5 h1 W
) J' W: c0 l. _  [& T- }' m. g
void        APU::Reset()
! x( Q4 G& L$ k+ J0 U0 D& Y7 q6 k. X& m. e, N{
0 y5 y, f* v2 R/ U/ u        ZEROMEMORY( &queue, sizeof(queue) );2 t3 L5 Z4 E. s6 l7 B+ E, J6 w; k" {8 ^
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
1 [$ K" D- _- J& U4 {
; y/ M  Y: K" c4 U* O, b+ W% b! g        elapsed_time = 0;
' C6 ~( b& k9 {- T: Y4 q
6 ~: D. Z& g1 W# i4 i5 G3 ?& h$ @        FLOAT        fClock = nes->nescfg->CpuClock;- B% n/ P2 p6 M/ R( l+ y% i
        INT        nRate = (INT)Config.sound.nRate;* ~$ J3 p. y! i
        internal.Reset( fClock, nRate );
/ K9 {2 p3 Y4 R, t8 q, c        vrc6.Reset( fClock, nRate );7 H" p7 u4 }1 c# W
        vrc7.Reset( fClock, nRate );
5 u) p& L2 q0 ?        mmc5.Reset( fClock, nRate );
# {% @, G5 D+ ]7 `$ X9 P9 j        fds.Reset ( fClock, nRate );
" F, N, \& o0 U/ C        n106.Reset( fClock, nRate );9 {" N& V% m! _  |$ Q. C
        fme7.Reset( fClock, nRate );
. x8 ?( x; D- u+ H1 a) E! ^  f& j1 H5 e
        SoundSetup();
5 n3 [! f" z8 m$ j}1 E+ y  C3 M+ f1 w) X1 i

4 c! T- R5 |6 o" Pvoid        APU::SelectExSound( BYTE data )/ P, \8 T! U& N9 d" d
{
- x0 \& k3 O2 G* Y# z1 ^5 `, s0 ~        exsound_select = data;
4 n0 p+ w: N4 _7 J}
- K6 ?2 u) {: V9 j$ b1 p0 u
# {9 }+ z) m7 @# R+ W" Z; D4 XBYTE        APU::Read( WORD addr )4 z$ Q; J1 l4 R0 {; c# R# o
{$ V# @2 G! z* y- I: M
        return        internal.SyncRead( addr );4 M* I) n' ]$ f0 C! y! p! J
}; B2 S) t. l" B( U( q4 Y

5 F  I4 K$ X3 e# \4 Nvoid        APU::Write( WORD addr, BYTE data )2 k) Y* t7 y" m4 O
{) S" G' d: R9 |3 _& V) h
        // $4018偼VirtuaNES屌桳億乕僩  d2 w: t5 [" {8 O
        if( addr >= 0x4000 && addr <= 0x401F ) {+ q% E6 |7 S) |; m' I1 T$ @
                internal.SyncWrite( addr, data );4 A* F; P- ]8 G5 v0 f
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
! ?/ v+ ?2 X% X% C) ]. v        }- o* i( N* ^& B3 E6 l* M/ b
}
9 u( r( p  q* ^9 a  p; u# ^+ x" A, F" [: H8 z1 ~& R" O
BYTE        APU::ExRead( WORD addr )) K: R) W/ j* n: A* b
{
6 A$ }# `) o& I4 z) XBYTE        data = 0;
+ t/ @0 }/ q+ t
$ |6 d% s  a3 }1 Z/ B3 t        if( exsound_select & 0x10 ) {
3 f) r5 I/ V- Y                if( addr == 0x4800 ) {
/ W: q8 D- Z3 A7 Y) a5 q+ o2 u                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
. c. ]' [/ q% P; J                }  W# K; k0 }% V8 }1 a& r+ P
        }8 ^- f7 r3 v% @- P( L- G  k
        if( exsound_select & 0x04 ) {
. m: P& [; X/ X& E/ ]7 R+ Q7 m3 ^                if( addr >= 0x4040 && addr < 0x4100 ) {, U) I% x# k% n1 J3 F" \' ?
                        data = fds.SyncRead( addr );7 c2 M! T* B& E! n
                }
8 a- K, `/ ?' n/ D9 f% s$ M5 ~, \: A! n        }# V. v  r5 N1 @' |& F
        if( exsound_select & 0x08 ) {# f7 v6 f7 b: k; T+ Z
                if( addr >= 0x5000 && addr <= 0x5015 ) {
5 ^8 T+ d  q5 J3 G' R  p. q                        data = mmc5.SyncRead( addr );) S5 g6 q, I& I& z2 ^6 `! S6 w: D
                }( z4 d( E) s6 ]0 H' Q
        }
1 P% ~6 ]& o. H% C, r
" h& B% k7 K# _& s3 ^        return        data;
$ L( W2 Z4 w' e9 r2 d/ i  s' z- b}( @9 B% }/ x  d

* N8 E- p) p1 X+ \) a7 K' a& avoid        APU::ExWrite( WORD addr, BYTE data ), T8 @/ D' r  q. C. |
{: J- Z% H; H" W9 `: }
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );+ v- W5 X- Y- B2 j* M8 ?, C* ]
" u9 V. W- B' G$ Y- G! K( x( ^: l
        if( exsound_select & 0x04 ) {! l+ A, k1 {7 ]0 ^! n0 I
                if( addr >= 0x4040 && addr < 0x4100 ) {
; n1 h2 Y) L- e- y& X                        fds.SyncWrite( addr, data );
) j* Y( S. N0 ?7 O! w% k                }
4 f3 m8 ^; E" N2 Y' S  k9 @        }" y, m- w& e$ X( e& J! B' f. g
' E; }$ }; z3 ~
        if( exsound_select & 0x08 ) {
" r7 }) h* Q# U; s' q                if( addr >= 0x5000 && addr <= 0x5015 ) {
) w4 j$ |3 u. x; [                        mmc5.SyncWrite( addr, data );
5 E' u5 h( v  ]' u! Z                }
5 d% I2 Y  Y+ X! I        }
2 J) Z6 c& L: d% w: O: f4 a' l! f& |}
) G6 A" k! b' T- L" x5 t$ ]  K
" W6 v; u' ]" u2 f8 a9 v* Nvoid        APU::Sync()0 z  _7 z+ g5 k! I$ Z8 A: O
{
! E/ F! H+ o* Z# w; [8 u}
" W5 T- C. V4 V% o7 a- Q3 L: u' Q. h7 z, j- S% N5 A# N: C
void        APU::SyncDPCM( INT cycles )
$ a7 T# G" ~3 K4 {+ c# h{5 T$ n: x( @. {* u" c
        internal.Sync( cycles );
' {4 l* f3 q, m! l9 }5 M
5 n4 h; N2 y4 n        if( exsound_select & 0x04 ) {9 A% x" ?7 P7 }8 n! c' W/ B
                fds.Sync( cycles );
% ?3 e8 K& W8 l$ T, W8 r        }% f) W1 _' k% w, w) ^
        if( exsound_select & 0x08 ) {1 n3 Q( ~5 b3 \3 C/ m/ D' @8 y
                mmc5.Sync( cycles );
/ w0 X0 f7 ~9 `6 a! S        }
7 |: x0 Z9 F* S}
6 ~0 k6 D; L4 \) `
7 G0 d1 {- `8 v' Wvoid        APU::WriteProcess( WORD addr, BYTE data )
- g( ], g  C( A& {3 C0 L{% f" H$ ~9 ^0 b- r% r
        // $4018偼VirtuaNES屌桳億乕僩
# C1 X* w6 r  a. b/ w; i        if( addr >= 0x4000 && addr <= 0x401F ) {5 C' [6 t5 U9 ~3 |. y
                internal.Write( addr, data );
( z  G7 |( P) _$ l$ l# ?        }$ V' q) M* R3 ^& N
}
! K' [' D( N( X9 V
6 v, j0 j- P& W2 O" B% hvoid        APU::WriteExProcess( WORD addr, BYTE data )
1 d5 L% ^4 x9 ~; v{
- o( _" d# ^' Y5 T8 y  y" C# ^        if( exsound_select & 0x01 ) {% R  F8 z, K7 |' w
                vrc6.Write( addr, data );4 [, t1 }7 [; H0 E1 c- w
        }& ?0 w2 }, N; ]" _
        if( exsound_select & 0x02 ) {. B" j/ H, N1 t8 ]- _/ x
                vrc7.Write( addr, data );- z2 Y8 r4 M7 k$ h* h% w6 t+ L
        }
6 L& m  C8 S3 r5 ^5 y* ~        if( exsound_select & 0x04 ) {
8 B( R. w$ K3 v$ d8 J( `                fds.Write( addr, data );& V8 G! |# m' b# o+ j
        }
- p, v9 g* g7 y+ M' Z3 N  [8 h9 d        if( exsound_select & 0x08 ) {- h+ ^. d& X2 J9 h, ^4 Q' s
                mmc5.Write( addr, data );+ a% w6 o( j4 N" T
        }
6 h# s, ^4 E+ K; F0 o5 t/ L" N        if( exsound_select & 0x10 ) {. x( h- C" J) [& [. n
                if( addr == 0x0000 ) {) j2 Z  c6 T/ P6 @
                        BYTE        dummy = n106.Read( addr );9 T5 T. \/ y& A# T. d6 M# }7 U8 |4 [
                } else {- S9 x/ l' W3 _5 i2 g9 W, x) _/ A
                        n106.Write( addr, data );+ t: E8 G3 k- I* }" {2 U/ V
                }( ]  |) N4 p# @; E: M
        }2 B) S, X: m8 u3 B; [
        if( exsound_select & 0x20 ) {
) q6 T* U7 H. E1 i1 d* ~; S                fme7.Write( addr, data );  P4 s2 a  G) ~& t4 j
        }
# O% D( U) k3 O+ L" h2 o# m# j}) ]5 `4 W6 x% k( \

9 f) I% `  v& |6 o8 p! |void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
' E+ D5 l' _8 [3 N* {6 `{
& y& S; i. l: P5 O" ?6 FINT        nBits = Config.sound.nBits;; X$ D2 l9 Y' I, T9 k
DWORD        dwLength = dwSize / (nBits/8);
$ N8 u- D9 v5 r1 }1 {+ [+ f5 q# CINT        output;
- w. Y7 m' F9 B0 PQUEUEDATA q;
7 r1 _9 U4 D( D+ T5 D/ N- ZDWORD        writetime;  H; \9 i( @: [
. t5 ]" K0 b' V! K  L9 u
LPSHORT        pSoundBuf = m_SoundBuffer;
% H, Q$ }' ^% |6 GINT        nCcount = 0;2 a/ k/ t: X8 s
) _7 I: W' x2 A$ Y, k
INT        nFilterType = Config.sound.nFilterType;
% `2 \. b9 x" J: ~0 N# q
; h1 I, b6 W6 [2 h        if( !Config.sound.bEnable ) {) D% [1 @6 i5 i: O
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );! C6 m4 T, O# o0 u% e
                return;
! E7 G/ `# {9 Z1 ]% r. K" h9 }        }
) w4 x2 M/ @( E& I% m. T
1 P( G) K9 R1 K  A/ U( E  K1 ?        // Volume setup  _  b, \3 M6 U* W) B; m0 Y4 r
        //  0:Master: [/ ~' r" V$ d9 t& p
        //  1:Rectangle 1, T/ r+ N' |& S/ V
        //  2:Rectangle 2
* v4 P& ~- `! |5 b* O        //  3:Triangle
' z% x$ |* a% Q. W6 _0 M        //  4:Noise
, }5 e9 w: i3 H' s* }        //  5:DPCM0 c# b( r8 t. M% r/ N
        //  6:VRC6
9 K( M* O' a4 j        //  7:VRC7
* I: h7 G$ ]/ t+ f        //  8:FDS3 ~8 i8 O  u; W7 E
        //  9:MMC5
& D6 m7 B/ F. x8 c* O        // 10:N106
7 d# M* j3 t2 C+ h* Q6 T        // 11:FME7+ B) _1 M, A, Q4 f9 |+ G7 K# P; S
        INT        vol[24];
  t/ A5 Q# b& ]: g# C3 C" y1 m  @        BOOL*        bMute = m_bMute;# H- e% Q. U7 U
        SHORT*        nVolume = Config.sound.nVolume;
4 q; K( A! v0 U) H5 \( ?! W* u- L7 K( ?* C
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;' P% x$ b. b% F" @) \
5 F2 q9 k1 I  k0 i
        // Internal
9 Q& X( [( e( v* v5 u        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;5 `* L* t& f' O3 X
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;# U. u" |6 x7 {: O) y# Z
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
+ Z! X8 q  f# L        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
+ a. x6 }% T& a4 d# Y2 i; m        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;. ~* ]: ^2 x# U# ~4 N$ f( ~
7 C. m+ G7 K" B( j. A; d
        // VRC6  ?# Z! `3 O' i8 q  Q1 v% v
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
6 [! X/ R) h8 S/ _: l7 I        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
, y  v. U, f; ^% a" o; r        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
+ Z4 }% X  W$ C+ A( Z& n: \& K; c: x7 ^- ~6 _& f
        // VRC7+ a; N0 ?+ d- ?; J3 O( z$ r
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;' p. W& P' o7 [* r" r2 ]2 j
' f$ X" U7 m& o" t9 N; n0 @
        // FDS0 M- A& `5 g' z+ H9 z
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;: k4 f% b5 G- ]% M8 A4 w$ B) ~

' a% W; Y. {1 T9 ]        // MMC5. r/ m( U- U8 L$ i
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;5 B! w/ X8 C& Y+ {
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
* G6 ^" @2 P! z; ]& q( {) O5 @; c        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
7 T7 B# g* R: d5 H4 r: k
) X1 e9 l0 R, v' I0 o0 @        // N106
, m/ q! k, f2 m' g/ B7 K3 J3 U        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ C* S4 e" A* S' `# c/ R        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
; ?% ^& E4 W" W- x: ^; |7 j        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. ]! F) r* g" w2 y        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
2 w- |' C  f7 y' X1 D! l8 P        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
( t# G% ?7 k# X" R+ d6 K+ V( N- X        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ D6 J4 R0 S: i+ r* t' b
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: ^/ h: T5 O/ ]6 u$ A1 n" m        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- X) }- a9 z- K
8 S3 j  @5 l7 }  D) y0 c1 j
        // FME74 i4 {9 `: X" \* g% ~" z
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;. a* ?$ [1 W' {! W$ G
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;: w9 }6 x' l$ y$ F! G
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;5 y" t# e, V( @1 B% P/ X, }

: q) V" o# j/ `0 O//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;) k, n1 V2 }6 o8 d( p5 i
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;& I6 U; |, ~8 k+ A/ z

+ {' [# h: {  e( J7 v        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
1 A& S, o$ `) B& S8 y, \: T        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
& Y; G: X/ R0 V1 H9 q4 ^                QueueFlush();3 t  b0 b  [0 c) w: I- n8 q8 l
        }
  v, ^7 ]3 u9 x3 C  i% y& |" T. H: n0 c* d$ d% R
        while( dwLength-- ) {
/ }: P: r/ Y* q4 d- |$ |6 k                writetime = (DWORD)elapsed_time;. z" t! c5 X8 c$ q! |  W( l
8 F* S: K. E' U4 D( f; ~
                while( GetQueue( writetime, q ) ) {7 [1 X- M+ o% P, _2 S
                        WriteProcess( q.addr, q.data );! p1 l$ c1 Q, [( ]9 n
                }$ _, T9 ]4 n# h/ i& y$ s7 t

3 x4 F8 u( N! i+ a                while( GetExQueue( writetime, q ) ) {
# b1 ]0 b- V7 s( I0 T                        WriteExProcess( q.addr, q.data );
' c/ M+ s% m4 P' o+ c* |                }
# M% ?4 O, D' f/ W1 v6 w3 I( @. ?5 s4 k7 i2 ^
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
9 u, {( q6 p% v8 J1 }% P                output = 0;
6 c/ X4 M/ Y. R                output += internal.Process( 0 )*vol[0];
  c; V4 [3 q! g! R$ R( g                output += internal.Process( 1 )*vol[1];
0 x: ?7 l% L8 u+ M$ Q# S$ L                output += internal.Process( 2 )*vol[2];
5 C  G2 u7 u- W$ ]                output += internal.Process( 3 )*vol[3];
* w$ ~' u2 Z% u5 e7 G  K* l. f                output += internal.Process( 4 )*vol[4];
4 J5 F2 r3 r* n4 x8 N
1 G+ h2 ~4 Q5 B, c* \* `                if( exsound_select & 0x01 ) {! {! g' ~8 x$ S" W7 ?) f
                        output += vrc6.Process( 0 )*vol[5];, V9 ^/ U* F8 x+ b* @, k
                        output += vrc6.Process( 1 )*vol[6];  c* ]6 ^/ m; w0 V, }% x/ q! U
                        output += vrc6.Process( 2 )*vol[7];
, V3 P4 O) D/ l: q, Z                }
0 b) L- {! T# e0 A4 P/ g3 ?1 Z( g                if( exsound_select & 0x02 ) {- n+ e6 [/ R/ w) C- [
                        output += vrc7.Process( 0 )*vol[8];
8 s9 H5 l0 O  E" R5 P" J0 L9 z                }( k3 [% z+ \: \
                if( exsound_select & 0x04 ) {+ J8 Z% \6 Y2 Z+ m
                        output += fds.Process( 0 )*vol[9];$ C& a5 n# b7 X5 x" c
                }' }5 V6 C. Z6 A0 H8 K% x  }$ I
                if( exsound_select & 0x08 ) {
6 A( _1 ?2 P7 h: I5 H" @$ Z                        output += mmc5.Process( 0 )*vol[10];
+ V; `5 F8 Q& d! `8 X; I" b                        output += mmc5.Process( 1 )*vol[11];5 F: f7 m, l- K9 l- I9 G
                        output += mmc5.Process( 2 )*vol[12];6 O2 u: C5 R1 m7 [  A" R- P
                }( U" P$ ^* j8 J. c1 k2 U  c& @; ~
                if( exsound_select & 0x10 ) {2 W4 R0 l7 G' M3 L. ^
                        output += n106.Process( 0 )*vol[13];
4 E& `& [/ X' |/ k                        output += n106.Process( 1 )*vol[14];2 t. k- x6 A( F6 j. F
                        output += n106.Process( 2 )*vol[15];1 s! \4 c; n3 j! ^
                        output += n106.Process( 3 )*vol[16];
' U" [. L+ A; u% K; r' Y8 W  W. b                        output += n106.Process( 4 )*vol[17];
- y, A4 n$ s3 |$ V                        output += n106.Process( 5 )*vol[18];
1 a6 ?1 G; S: A: E                        output += n106.Process( 6 )*vol[19];$ [. p( c) I* m3 j
                        output += n106.Process( 7 )*vol[20];
* q4 `& O% ?% |3 l! @+ i2 C" H                }
# M0 M' ?+ n; S( [1 b! Z& g                if( exsound_select & 0x20 ) {; q, @( G2 C. J) [- Q4 S& A
                        fme7.Process( 3 );        // Envelope & Noise& m1 Z! W" c# y/ J! e
                        output += fme7.Process( 0 )*vol[21];$ n7 I: B' [9 H+ g3 c! n
                        output += fme7.Process( 1 )*vol[22];8 s7 a( ]5 X: w8 f8 U; ~' J
                        output += fme7.Process( 2 )*vol[23];
2 i- x0 e. e' }9 w; J+ B: V                }' `5 Y) j% K6 V. N% @! [1 n3 n

% i5 D. _2 p+ ]% \                output >>= 8;
7 ~) Y( p# g% o1 F# y  K3 l6 l
% P2 }4 F- {/ J4 L1 p& ]                if( nFilterType == 1 ) {( g; Z. l! F5 r: C; Y
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)8 Q  @! T9 A! e! G2 J' w
                        output = (lowpass_filter[0]+output)/2;& @. M( x  N2 Z7 t) s
                        lowpass_filter[0] = output;
1 k0 V! Y* |8 S; l                } else if( nFilterType == 2 ) {
5 @3 ^; L9 j3 L' d/ C                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
9 @9 R# p1 Z/ v; Z# t1 N; {9 J                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;# _) f9 W# x3 d, E
                        lowpass_filter[1] = lowpass_filter[0];
3 ^# A% {4 M3 T1 P- T( j9 _% ^                        lowpass_filter[0] = output;
# Q& x- V8 i# r" M* }                } else if( nFilterType == 3 ) {
- }6 E* D# @  b6 e4 L( S                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)! m5 Z! c3 e" i- F# `
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;0 ^* d/ t, {$ W; }: I  I
                        lowpass_filter[2] = lowpass_filter[1];: H3 ~7 F$ G' L% L' m" q
                        lowpass_filter[1] = lowpass_filter[0];
" y: C* H" \2 X$ m                        lowpass_filter[0] = output;
2 Q: _" [) g: d- U: i7 U                } else if( nFilterType == 4 ) {5 @0 a% F, j2 Z3 u
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
$ e. }% ^# P' b% K# l1 [                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;$ R) X( K, E3 I7 i6 N4 L
                        lowpass_filter[1] = lowpass_filter[0];
2 M6 g- u% l: K8 \" T                        lowpass_filter[0] = output;% i7 o/ a4 d' I  U* O6 J
                }2 s$ X5 N/ o" t! }3 N8 V
: J3 b3 O4 x9 D. v( m7 h4 z3 K
#if        0! F4 u& R$ X- Z! o: \* e' _! j
                // DC惉暘偺僇僢僩
- q2 S% U  V; N                {- x3 Q) i2 ~' H
                static double ave = 0.0, max=0.0, min=0.0;
* F$ X5 T( `1 m! o8 l8 ?# k; d% f# I) X* O+ }                double delta;
2 a5 N- _$ F5 {8 c9 \                delta = (max-min)/32768.0;
" O+ P) C  v* U4 ^8 ~4 W, a8 T                max -= delta;; u6 E" b9 P( G
                min += delta;: |3 ?  I7 v* f
                if( output > max ) max = output;
* V0 k$ B, ~! L                if( output < min ) min = output;4 I1 O: M5 g( N+ e
                ave -= ave/1024.0;$ Q7 z) C* n2 m) L2 q( a/ a
                ave += (max+min)/2048.0;. c' ^" k6 K$ {: `4 }( y: `
                output -= (INT)ave;
. W1 m0 Q) k% `, t$ `1 ^4 E                }
0 `* T( q8 W  Y' V0 B#endif* E) w) X4 G/ A2 Q
#if        1/ @/ s+ K' I2 ]7 w2 p
                // DC惉暘偺僇僢僩(HPF TEST): t0 B, M* I: ]( L
                {9 S/ G. d+ T' K9 \- E+ I: d+ U
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);9 d. [! m' r8 B
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
9 ]# F) l0 w& Y9 U7 k                double        cutoff = cutofftemp/(double)Config.sound.nRate;" J- t  S6 q/ t4 ~! y. r: ?0 c/ P
                static        double        tmp = 0.0;( \. v- A/ ~6 C1 R* E
                double        in, out;  p# W, t+ M2 T0 d) \
; T$ I/ d0 i& M
                in = (double)output;: l3 z1 \/ g) g4 E: `
                out = (in - tmp);3 [! Y; i; |6 U$ V5 _
                tmp = tmp + cutoff * out;, r" s' e0 c' C/ H4 a3 U
, A: F& k' b% F
                output = (INT)out;6 A' m) m" \5 ~0 i. h4 P
                }6 P0 s1 t0 y, A' m  J3 d) `
#endif' d$ E; _1 r! {
#if        0/ ?' E6 x( h7 c
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)* q" Q8 ]) t7 a- O: ?3 w! d
                {( L0 F/ E; e  F5 ]/ L
                INT        diff = abs(output-last_data);5 s0 q% z; \. N2 G( S7 j. x, f
                if( diff > 0x4000 ) {
$ i( l. K$ ~# _8 q7 y1 i; l                        output /= 4;/ B4 ^8 W* r; \) m
                } else
1 {* U* Y- N2 r2 Z0 a. l: U                if( diff > 0x3000 ) {
0 W' ]1 p! b2 S# q# K3 ~                        output /= 3;
/ R9 ]9 |* Z5 x5 Z                } else
) P  y$ V& }0 J. E& }                if( diff > 0x2000 ) {  b8 c; v, y7 D6 K
                        output /= 2;
- `. u5 D0 B8 g$ e                }
% z4 k* w7 c( _& h5 @7 _) M+ _$ ^                last_data = output;% K/ r9 h+ w5 k0 l0 w
                }( {* o6 v- k( U3 G9 N
#endif
3 D1 k4 H" E* \, v! r9 Z6 U                // Limit
2 {3 O+ S- }" T! X                if( output > 0x7FFF ) {7 b5 C* Q0 C( c" m$ Z6 g4 N! J3 F2 o
                        output = 0x7FFF;
8 Z# C+ p: o6 A9 N$ X, e/ z                } else if( output < -0x8000 ) {) n4 K3 c8 L4 ]% ?& n; H
                        output = -0x8000;6 z& X! V" t1 a
                }
9 _$ Q& U. I) x7 l2 c  Y: [2 A, s! i
1 W- `5 u8 f2 Q" G                if( nBits != 8 ) {
' m8 i2 b+ f' x% N6 A, {& Q1 D                        *(SHORT*)lpBuffer = (SHORT)output;$ |& H- z  l, H, F0 u1 }9 @) E3 o
                        lpBuffer += sizeof(SHORT);& N0 X" f  n. c
                } else {0 y: s* h, x8 A; W+ V. n
                        *lpBuffer++ = (output>>8)^0x80;$ j$ C, {1 C5 ?, R8 p  p
                }
# s& ~% d' U- s. \( r( @/ G% |  ]
                if( nCcount < 0x0100 )
/ ?& O( E! G' p                        pSoundBuf[nCcount++] = (SHORT)output;
* D. B: S% S' `- a! f& R+ `0 K2 G& z
( X9 m" ?9 ^& X4 s0 G//                elapsedtime += cycle_rate;
! f8 I& K) q  N) q                elapsed_time += cycle_rate;9 g! v6 s( o, u1 T, `3 t
        }
+ D, b" B' i7 |, O3 D+ x; ?- T
1 [: C3 m+ ?* i6 l# _% \1 H  D2 `#if        1
; {! v" W% ^# P( O        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
/ K( K& D1 ~9 I+ {                elapsed_time = nes->cpu->GetTotalCycles();- F1 }* H5 B. E$ p' c1 w9 W
        }
. Y5 D3 [  }: e        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
: {9 I5 f) V+ ?) D2 @                elapsed_time = nes->cpu->GetTotalCycles();
" E/ a) U0 {, @* H9 N        }
2 |3 I( `8 b4 x- v, s7 x! _#else
2 S. T8 r( a# G' O- T  i" _        elapsed_time = nes->cpu->GetTotalCycles();2 `  e* _8 u" K( ?; j1 V$ @" s
#endif
" y7 a& h+ Y: Z& P$ U9 d- j}5 V  m5 h) [4 I7 K) K
  ?% l# o  {% K. D! [' k
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
1 B1 K3 h: u# `& u$ P0 N: `; \INT        APU::GetChannelFrequency( INT no )( f9 K: S! `  ~: C2 C0 X' q* v
{
, e. K9 i7 ^7 ^# P        if( !m_bMute[0] )
! B1 W  k' D: d                return        0;  W* j- K9 t  p4 i7 ~3 l) h* \/ L

0 a" f" r8 f2 L+ X- ?$ n! B        // Internal; N3 Y2 Y0 z7 [% e0 _' f9 \
        if( no < 5 ) {
  ]5 D, S1 D( B) t5 ^" W6 k                return        m_bMute[no+1]?internal.GetFreq( no ):0;
, v  @9 }% ~" Y7 }9 B# u. m; A        }# _, k0 }' c1 [
        // VRC6
, k/ P& ?: V8 z. ~* \& @* }        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {  C8 O' k( B! S' ~" C) h+ G& q
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;* }6 c0 ^1 ~$ J2 K# Y4 n/ h. w, O
        }
' R, F, x# B( H1 X" L, ~, C2 c; S        // FDS$ a8 d$ B/ w  E) N0 C7 r
        if( (exsound_select & 0x04) && no == 0x300 ) {& I. o7 p7 k) ^' L2 k# d
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
& q2 h* `) f3 U        }
5 L, U- j0 x! J, j        // MMC5) G/ j  ?3 Q1 X3 y/ H
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {$ z, ]: k0 j! R. L" M! C$ v* j4 n
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;' H, Q+ L* A0 I6 q
        }9 }4 t6 `8 S; ?. n6 ]7 Z  X0 k, O: Y
        // N106
1 E7 \- N0 [1 l) G: x        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
2 X) x  ]3 |, n                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;* j: p$ `" P) \, Z7 E! V
        }
# c" w& r6 y: l. G3 \' c( y9 L+ S        // FME7
( I5 ]+ }% Y: m/ |- g! {4 _        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
' o+ ^# ^- l% ~- z1 [) ?# o                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;3 i( `) a' e. q1 s: |$ k8 G. m
        }
- \4 F+ y( I) E! d        // VRC7
! a, |1 B. B( r" r6 A: {        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
0 H1 V0 w/ Y9 T1 q                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
3 ]2 Q$ Z/ c! w! ~( f        }% U; }( L: i: y4 Q
        return        0;; c* u  M! y* P
}
% a* }' @, u# |$ r8 V
. C3 z: ^/ ]7 b8 W// State Save/Load3 ?. U: l  e# h% K) A
void        APU::SaveState( LPBYTE p )
$ r' H& u, N2 l; g" m% i4 ~{: b4 q1 `0 H  `; l" c3 g
#ifdef        _DEBUG8 t6 M( I2 [; q, W! K, w
LPBYTE        pold = p;
$ D$ }' G* V) w, K#endif7 R) H. n8 ^; M
* m* }* f" A7 V0 z( M4 A
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
* E$ r% C  s; h/ s4 w        QueueFlush();
( L2 i8 T8 }( O; {
) |& f8 E6 D% y9 O" s/ P, F        internal.SaveState( p );
' P6 Q4 \5 [" l" a. `        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding1 f2 [; w3 O. d/ F9 z

% F8 k0 _- Y7 h9 e' b        // VRC6
0 b; W" C, K/ t        if( exsound_select & 0x01 ) {# K/ I6 z- I1 ]" V, u( m
                vrc6.SaveState( p );% B$ }, A" W7 O. X
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
! ]) l% @9 k6 T4 K# f7 ~        }
) [& Q/ \( ?% _& M9 a        // VRC7 (not support)
  x0 a' ?* ~5 n        if( exsound_select & 0x02 ) {/ S4 _: Z+ @3 J6 Z) Y* I* c2 k7 c
                vrc7.SaveState( p );1 z# d0 @6 q% l( N6 b. W; i
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
6 M. X, j# C% f. W9 U3 q' D        }
0 m! w( a: `5 {1 E. Q        // FDS) _1 u" Y% }; s
        if( exsound_select & 0x04 ) {, G1 s# f& J  d
                fds.SaveState( p );
  x% H4 C) u1 G2 ]                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
- [& o( e7 H, t9 O% G. j$ w+ i        }
( r, e* v- X; P5 s: n        // MMC5& S& T/ _6 e- K0 P$ g5 t# L- m3 n
        if( exsound_select & 0x08 ) {
2 v# g9 U+ N) w; Y5 y                mmc5.SaveState( p );3 t0 B7 f& `  Z$ E/ W2 B
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
/ p: P. d8 U. V( z# r8 f# R( |$ [        }
$ _' ]5 m2 ~6 {2 x        // N1066 N8 S/ \3 b# s0 t/ M
        if( exsound_select & 0x10 ) {  K' E! j+ |: F. T/ V
                n106.SaveState( p );
. [. {( E+ u9 E, C7 V6 m9 I                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
8 d6 r1 p3 Q, a$ E* Y+ Q' T        }
( L7 L" `) L5 Z0 ]' [        // FME7
( t  ^9 k+ q/ A# C* B" U        if( exsound_select & 0x20 ) {& @$ u/ Q$ ^+ z  u6 d
                fme7.SaveState( p );
5 O! l& E* j! T                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding/ U$ Y4 o* r) m+ A  v
        }
& V6 ?* T& w) {- m* w
/ Q- b, c' y2 j: I1 ]#ifdef        _DEBUG" j% {% S0 j. y+ y; O/ `2 v
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );) r8 U' X# D5 M
#endif
" w( D" K1 b* {* F# `; G4 [}# |& s7 E2 p' p- c8 b

6 b  d5 O# a" O6 ^4 F, l, E( ivoid        APU::LoadState( LPBYTE p ), \; B% U) n3 n; ~. `
{7 H5 L3 o, G+ ~- n& U
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
! j) n+ t' H, R9 t        QueueClear();
- l, u, n* {7 K4 Y0 Q3 k
" h9 P4 p  s9 b" y1 x        internal.LoadState( p );! k) I( p$ E5 m- k4 T6 a
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding4 \' f9 b3 ?7 n* ^

9 L; P. m2 ^& K* h/ J" p* o        // VRC66 [" g" w% m: |
        if( exsound_select & 0x01 ) {
; H  G0 a- s8 ^# j0 p( Q* ~                vrc6.LoadState( p );
: p$ b+ K) l) ^: d) Y                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
) N6 k, U' x6 i! P( u4 ~! v5 G6 r        }! C9 _; R% S5 t
        // VRC7 (not support)8 R! L! |* }9 g6 W1 y0 v% t) `7 V
        if( exsound_select & 0x02 ) {
" g) W, u' m' A                vrc7.LoadState( p );
  Y  \) K: ?8 u                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
: J: w% X* Q' X/ I( ?/ J        }! r# l2 X; |9 \6 s
        // FDS2 u. G" [. h- {0 @+ C% u. J
        if( exsound_select & 0x04 ) {% P/ b  b* z9 m' D
                fds.LoadState( p );
: \% x  ~! V( M: q+ G. }; q+ b                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
4 k2 ?9 ?1 ~; V" g3 x, {9 b: |        }6 b! g0 R* \4 T) h/ G
        // MMC5) H/ M8 `8 t6 S. Y* I
        if( exsound_select & 0x08 ) {
! U( [7 Z2 a* m6 [; G6 l5 J                mmc5.LoadState( p );+ M( r3 Q  T( H# f. n+ C2 x
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding, O5 @2 b3 M; e9 C7 n8 L
        }: V- p8 M# `& V0 x' p+ A
        // N106# M8 v9 a* k( {1 N" [( S8 _
        if( exsound_select & 0x10 ) {
$ F0 u+ S0 X% A* d                n106.LoadState( p );! d% w0 H% j  C' L" D3 ^+ [- D
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding; T- M0 b* _4 Q
        }
0 u; D! h* C5 e! u        // FME7% s* ]% c6 m# s! z; |* y
        if( exsound_select & 0x20 ) {
7 k! q5 a& y* z/ E                fme7.LoadState( p );
; p8 ?4 n" T9 P, r1 C( ~                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
4 u' |$ l4 f$ R9 s( G0 l        }
$ `$ `1 O; I: d% c4 m+ D  ^}
回复

使用道具 举报

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
; [, H) D8 }  B, x" E' U0 y可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。- c8 Y% W' T( `; A
感激不尽~~
( @! d# s4 L- b* V; e. y7 P7 k
恩 我對模擬器不是很有研究,. m+ P1 l. o& X- ], e
雖然要了解源碼內容,可能不是很困難,
$ ]- P# e9 L& c9 d不過還是要花時間,個人目前蠻忙碌的。6 W7 b  U' G- n, Z$ Y+ a' Q7 ]6 p1 S

  ?( R, I& U: J& U" X% R給你一個朋友的MSN,你可以跟他討論看看,
2 [1 Y# {0 x9 R4 a0 u/ r( W3 U他本身是程式設計師,也對FC模擬器很有興趣。
  ~* k3 D6 `' p+ E' B" \* ~9 h) {, P( l5 n5 i: C5 J
MSN我就PM到你的信箱了。4 ~# P, v' I/ f, S0 ]

# P' Q1 i7 X: S, u4 u. h希望你能有所得。
回复

使用道具 举报

该用户从未签到

 楼主| 发表于 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 发表 7 H% X; B5 h3 M+ y& I( R
呵…… 谢过团长大人~~

+ g1 n* T4 V/ p( j( m( |. J- v" ]$ ]) N- R7 e+ j- q( |# g
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 * a; ~. p% g* `- \
团长的朋友都是神,那团长就是神的boss。

, W8 ?: o& @8 u% J+ z/ k8 n5 f! b9 Q哈 不敢當,我只是個平凡人,
. L1 E8 [- {/ Q) k( b* v$ D要吃飯喝水,光吸空氣是不會飽的。。。。 :)
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
+ `1 m- d  a+ a+ E  k, [ZYH
+ A( K$ `6 ?- z1 m% G' m3 DQQ:414734306
- N4 d2 D1 j0 y" F" \3 [4 fMail:zyh-01@126.com0 [+ e* f# G  ~- \- J+ F. V

6 g) ]1 }0 [' N- y; L* z他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
0 F/ W5 O5 r7 g! q- z再次对团长大人和悠悠哥的无私帮助表示感谢~~

1 `( B9 W/ n. v8 l- n: G不客氣  ^_^
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-4-6 17:02

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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