设为首页收藏本站

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

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

  [复制链接]

该用户从未签到

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

该用户从未签到

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

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
+ y  b4 y6 B+ V8 S楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
9 G( J, Y4 z1 y/ T这里有相应的模拟器源码,就当送给大侠了~~
& [  Y8 j/ O, I( ghttp://kenkao.qupan.com/5096520.html
回复

使用道具 举报

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 6 z) y7 A- q# _4 T( r! ]
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
/ X! w7 E% d, \3 _3 Z* L楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~! [+ N0 U* }1 G, Z1 H! g
这里有相应的模拟器源码,就当送给大侠 ...

. A& w* O: U- ]' u5 @聲音部分(Audoi Process Unit = APU):
, [3 K4 H/ F( c.\NES\APU.cpp
- @& b# k2 G3 a0 o. p# Z: [/ }.\NES\APU.h
, K' _& l0 Z1 ^
  e, z, c, L$ S! c
- Y: N+ u" O6 e! Z影像處理部份(Picture Processing Unit = PPU):
/ {' n" B8 g  c6 Q9 v# a.\NES\PPU.cpp+ ?& Z0 p1 ?$ q5 S' G3 `$ q
.\NES\PPU.h4 I* R, j6 G* c# D9 X' M! i# }

4 O; W9 v* u8 A4 e如果原碼用C跟ASM混搭也不錯
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
) n$ {, s% s! N, O+ v& B' {(由于很多专用术语和算法机理都不明白,所以看不大懂……)
" w4 e$ x- g9 S/ Z; m1 b//////////////////////////////////////////////////////////////////////////) U# f6 e9 J& b; q, ?0 F$ ~. r4 z
//                                                                      //
* U& p( ?. }: k: E7 o//      NES APU core                                                    //5 U6 ^  A; p% R( g
//                                                           Norix      //. Q( I6 o9 L  q& j
//                                               written     2002/06/27 //
9 P6 G( G9 m# x6 T" t//                                               last modify ----/--/-- //
8 N* }0 b3 C3 y& H0 R5 m# t//////////////////////////////////////////////////////////////////////////3 b& y+ K! {0 L2 d2 q$ R+ J  \
#include "DebugOut.h"% G7 a) @* \, L: U/ o/ B
#include "App.h"
0 B2 l* R# m7 c7 [#include "Config.h". J+ [$ a4 E4 D/ z7 v2 W

3 N, B+ ?! r" g! d2 g#include "nes.h"
+ W  T  a7 u+ L4 w#include "mmu.h"$ t1 C; w& \! D" S( K* p) I& n- K
#include "cpu.h"
( ?$ V' s0 Z% s) K8 _8 y: w#include "ppu.h"
, r/ f1 p, t2 g' |#include "rom.h"4 t8 p% X- x5 {! v: Z( M9 u
#include "apu.h"
8 I- p! U2 t; v) G, z% `
2 a& @6 c0 [+ L// Volume adjust
/ `& m- o" p1 ?# L: l9 I// Internal sounds4 \6 Q4 E- n) e& m
#define        RECTANGLE_VOL        (0x0F0)
; I. x) m( w3 ?. v#define        TRIANGLE_VOL        (0x130)
3 [- g3 y7 S; {#define        NOISE_VOL        (0x0C0)% i& K) n) M0 S; \+ _  h) J
#define        DPCM_VOL        (0x0F0)9 z6 D/ y2 d* {6 i& D% K, D
// Extra sounds1 `" H( R! m  q
#define        VRC6_VOL        (0x0F0)$ c! r9 J, c" [
#define        VRC7_VOL        (0x130)9 ^0 w0 C: F5 G8 S2 L1 P+ V- a, j
#define        FDS_VOL                (0x0F0)0 f" _& p5 u2 u& I3 B( Z
#define        MMC5_VOL        (0x0F0)  I8 V" V# A$ l, A5 `  O1 q
#define        N106_VOL        (0x088)
$ w1 o5 s5 l& F% H: E6 e- ~#define        FME7_VOL        (0x130)1 |$ S6 U- r2 W' l
# T: [* |( [  a1 k4 ^" W
APU::APU( NES* parent )# y6 q0 _. J$ Y/ Y5 g+ K0 O
{
2 y3 K% e" }, ], Z; C        exsound_select = 0;
: O6 b! K# j1 s" r6 Y+ X! y- B8 h* m+ s& v. q/ N+ L. u
        nes = parent;7 ~# _1 T& w& c% j1 Z( \5 N8 u
        internal.SetParent( parent );
  v. G) L% \0 C0 `, x/ c! R2 x, w1 t8 L, ]# `: m
        last_data = last_diff = 0;
+ O% V: p: m* l0 H1 r
4 _7 B6 W; A# p        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
7 V# M# M" |. e6 E" i% o7 E, O* f. n. a7 K. z
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );$ d9 z% O7 D# h  N# C/ b0 _6 l
        ZEROMEMORY( &queue, sizeof(queue) );
& ~* y5 D' i. N0 D. _        ZEROMEMORY( &exqueue, sizeof(exqueue) );
, T" \$ T' |4 d9 _: X3 @
1 t% [' Y4 k, I: Y2 O4 j9 D        for( INT i = 0; i < 16; i++ ) {" G7 l* E: p, ?, L
                m_bMute = TRUE;
/ i& g+ q/ L  n1 A; r        }
0 `; R5 o$ H7 y3 a1 T2 u}
- \; `! f: K$ i3 B
1 x( \6 {1 ?7 [7 [1 y5 JAPU::~APU()
7 X! C7 G6 W2 |- a# J. G3 Z% i{/ f) f5 p' [2 e0 z  k' \6 n
}
$ R  T6 g8 `' B* v: d/ f  ?
; B6 e9 I0 Q' L) Z) m! N5 D6 jvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
7 L; X6 F# _5 {; T* f{8 ^9 d3 `) \& f# i: l. Q& Q
        queue.data[queue.wrptr].time = writetime;
1 ~' S; Y) [4 {1 m        queue.data[queue.wrptr].addr = addr;; e* h; u9 ]: b; Q4 y
        queue.data[queue.wrptr].data = data;; t/ V2 G2 ~: S6 U0 {# T9 E
        queue.wrptr++;! Y; v0 s( T# t# _, O. e2 ?0 x
        queue.wrptr&=QUEUE_LENGTH-1;
9 c, O& F# }% d0 |+ X! r, ~        if( queue.wrptr == queue.rdptr ) {
" C# v7 \: g+ I) B, h5 y                DEBUGOUT( "queue overflow.\n" );
' P  @0 G; ?' n( `  }- j! j  |        }
& M5 t. d: R" k! P$ H}/ Q8 y: j* M$ Q3 r6 K# R$ h6 \3 A% \
8 `' a9 v4 o6 h/ |3 l9 o
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )$ k+ B6 N$ K2 P# h- l6 {
{
" _0 B9 p8 U+ }6 V1 b* q9 s7 ?8 m# C+ J        if( queue.wrptr == queue.rdptr ) {
, O) G( v" S# T                return        FALSE;
2 E; Z! I9 |4 f2 ]0 b: {0 r        }
2 Z' I# J" L/ `! e        if( queue.data[queue.rdptr].time <= writetime ) {) O: W5 P' ^3 V5 x
                ret = queue.data[queue.rdptr];1 M0 W( A) f: L; g" f$ S) @
                queue.rdptr++;2 ~# b, {! p3 u
                queue.rdptr&=QUEUE_LENGTH-1;" a" n* h4 _- j3 C' {+ P9 I" A
                return        TRUE;
$ @4 A3 K6 ^2 f, D        }
. h9 P  {9 ?& l- J        return        FALSE;
0 c8 ]  A! _. Y' }0 {}1 \; _: g/ n: h$ n1 B, z

, J; p, X" N: c6 M% B, gvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )3 ?8 e( o) R* g" J' n, m
{9 g1 Q, k0 W( g3 f3 h
        exqueue.data[exqueue.wrptr].time = writetime;
, W* Q' N  @5 D, O: p: o( u        exqueue.data[exqueue.wrptr].addr = addr;
3 u. J: h' m3 S& W4 V; h( f        exqueue.data[exqueue.wrptr].data = data;% v7 v3 [' z' W. ^, J
        exqueue.wrptr++;
/ C% q' u4 r" V        exqueue.wrptr&=QUEUE_LENGTH-1;( k) q' }8 M0 G) @! [: R$ {
        if( exqueue.wrptr == exqueue.rdptr ) {5 ]4 H( O( o" P1 T* H) C8 t
                DEBUGOUT( "exqueue overflow.\n" );# `8 O+ h) W  D
        }9 J. |1 I! K8 P4 U
}
$ c, R  G. J+ g3 j" N3 F. ?" B( Z- J- K) e' ~' q
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret ); n" I: F0 g* z/ y. X6 r
{; p: ]1 Z( p" B
        if( exqueue.wrptr == exqueue.rdptr ) {/ C0 [, R- u& Y4 t5 F
                return        FALSE;+ Q" l- f8 t8 X
        }
3 J4 P* X' D5 U% K( Q+ i" N% d        if( exqueue.data[exqueue.rdptr].time <= writetime ) {" `+ D/ E) ~6 U
                ret = exqueue.data[exqueue.rdptr];/ C# O4 T7 _. H
                exqueue.rdptr++;
$ k, N) S" G$ M7 J" N                exqueue.rdptr&=QUEUE_LENGTH-1;
9 E; ]5 t1 V; W- }, m1 D  C                return        TRUE;4 m# D8 I6 Q8 j. g2 }3 C
        }
2 ~1 M. |' T: k. x3 I! I6 [0 O        return        FALSE;: H4 S. F' n* y: ~
}
. W3 _/ D: q% ^  F# e/ P# D
# m1 m+ _8 ~) U  c  H; ?void        APU::QueueClear()7 S  C) V, z! N2 T) v& I9 Q' [
{1 A" @3 C/ W) H9 s0 r
        ZEROMEMORY( &queue, sizeof(queue) );
! p- B0 H& x# u        ZEROMEMORY( &exqueue, sizeof(exqueue) );
3 |0 u% r7 i0 ^. n}
- C" v  [# y2 p
  P4 S; P! o+ T. ?void        APU::QueueFlush()
: O% r: l8 E3 \3 ?{
! P" C  N' j, S/ _5 {        while( queue.wrptr != queue.rdptr ) {
% G1 a4 ^# i- _* y2 V                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
$ Z- ~. c3 e, Z6 @- `6 b4 E! K                queue.rdptr++;( t: \2 F& ]+ Z, u/ J+ g, p: r4 {
                queue.rdptr&=QUEUE_LENGTH-1;
8 Q4 Y, |- L, ]! C0 D        }: z  t3 [' U& T9 `0 u- w4 ]6 J0 P8 B
' Z2 {9 N' D$ I
        while( exqueue.wrptr != exqueue.rdptr ) {; H# k" h' I; G% O; d
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
7 b; Q" @+ s. B  j+ w2 C9 ]                exqueue.rdptr++;
: C: z" {( e4 j7 Y                exqueue.rdptr&=QUEUE_LENGTH-1;1 v+ ^; k: Z, g1 v1 m5 B; y
        }1 P$ O: H: _5 n( T6 q
}/ @/ W4 o# y9 G( x  f4 e

- u; a: |$ E; i' s( x. i: m; kvoid        APU::SoundSetup()0 O& U" X; i5 m* G! l  W8 |: L" F
{- m7 b! x( r4 z9 k+ f9 M/ q- v
        FLOAT        fClock = nes->nescfg->CpuClock;
! t& _" A8 H& e        INT        nRate = (INT)Config.sound.nRate;
  `# ?. g- |! {, l        internal.Setup( fClock, nRate );
) I# t2 B" ~- K2 w5 T( `        vrc6.Setup( fClock, nRate );; z; c- o& v, `1 k/ G: C# M6 M
        vrc7.Setup( fClock, nRate );
0 Q( Y! x( [# f8 d2 h, V        mmc5.Setup( fClock, nRate );
* b( A. g1 ?6 X3 F" q        fds.Setup ( fClock, nRate );) S  s, E* r6 j, A
        n106.Setup( fClock, nRate );: l* K3 n7 k# p+ m* \0 x  t" Z
        fme7.Setup( fClock, nRate );0 |; @  @. m, H0 i
}* C) s1 r7 u  L
. b! h# B, M* j( ~# ?  T0 O  W
void        APU::Reset()
- M! }0 D5 O- F; [4 O* G5 H. `{
$ F5 t1 S9 L7 o( n: ^( ?4 t7 s; ]        ZEROMEMORY( &queue, sizeof(queue) );# e2 n# k3 g1 N5 f( _4 L
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
* \# O/ V- [& V* x5 t6 \. ?& P$ E4 J/ B/ `; z
        elapsed_time = 0;' @) j7 q; ~; f  m2 `* a& a6 ~  C

4 U* [) k. M+ K! E$ k        FLOAT        fClock = nes->nescfg->CpuClock;( b$ L1 |, ?/ E  J, X' ]! X
        INT        nRate = (INT)Config.sound.nRate;- n; C. w$ K; N7 L" {; F' A+ C; ?) b" d
        internal.Reset( fClock, nRate );
+ d! H% m/ G$ a% Y8 k% c% Y        vrc6.Reset( fClock, nRate );8 k: w; L: b0 f( K; Z2 a
        vrc7.Reset( fClock, nRate );  [7 r% c8 _0 w. p( `9 ]* W
        mmc5.Reset( fClock, nRate );/ C. u6 W: ^1 N' {# ^1 F
        fds.Reset ( fClock, nRate );+ a6 M3 u; U' f" C  C; s9 B6 n
        n106.Reset( fClock, nRate );
2 H& n, g) @+ E$ r. w* ^        fme7.Reset( fClock, nRate );
9 b$ b* q' L! f( A% ^7 n2 a6 f6 z8 b  n$ p& V# u. j; E
        SoundSetup();
; ?% ?8 R! a, _# r% a}
; |* Q2 i5 |: w% ?; A7 k  _' }
void        APU::SelectExSound( BYTE data )& Y- ~7 u5 j- h7 [" f8 h
{. P7 w7 M  S6 p  H8 r
        exsound_select = data;
. w) L$ \( g2 ~5 P+ {# q}
( I4 O4 m" D; I  }2 C/ q# i/ J& f% H$ g) y% h$ j2 t6 e) o
BYTE        APU::Read( WORD addr )
5 N" G" j% X9 }: O) c/ t/ D{
% g& p* U; Z! G. _/ w& f4 i6 \        return        internal.SyncRead( addr );
% x) D0 I! J  z+ u1 j/ D}, `6 b0 T, ~6 f1 ^6 a: G
4 s: `3 V! }; {+ z, J
void        APU::Write( WORD addr, BYTE data )
( W8 o0 Q9 `# G% ]5 B0 f8 {* ^{* @* k" I/ k. j
        // $4018偼VirtuaNES屌桳億乕僩
; ~9 c2 v2 ^/ e1 [9 B+ F        if( addr >= 0x4000 && addr <= 0x401F ) {
& V# {2 b# e; F# ]. ]% p% M                internal.SyncWrite( addr, data );7 P9 i0 p( P# _1 W
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );2 F* u1 q5 N: h$ M( @' H
        }( T  T% g. B, P& _; J% [  \3 v% S
}3 y6 S% T' _) A- {1 P5 C$ q( m/ p6 _

8 z( }' r5 K& b& bBYTE        APU::ExRead( WORD addr )
. B5 p, e& t) o; i: K7 b1 |{
; P& t' u/ |( B$ o' lBYTE        data = 0;/ ~5 q3 m% o9 n+ e! u& J% R

: U, v; Y2 i: N4 M+ Z1 G0 f- J" X2 p        if( exsound_select & 0x10 ) {
+ Y* \5 c$ l, x4 M                if( addr == 0x4800 ) {% H; G  c( p' C: F) \
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
! x; b7 F3 w7 P& |                }# @- U, |, M: q- M
        }/ |2 C( S+ c4 P' f6 U% D% L/ w1 t
        if( exsound_select & 0x04 ) {
1 v* s4 R2 p9 p$ ^! o9 I) P3 C3 U! Y                if( addr >= 0x4040 && addr < 0x4100 ) {
3 Y% Q- h3 @" W$ N9 e; u* p& d, C                        data = fds.SyncRead( addr );9 B0 s+ S3 x! w( T) _, t) J, {1 O
                }
0 q, [; a! W7 H/ J- `  A5 Z5 V; G1 U        }% U. f7 j, V' x! b8 G! a% l
        if( exsound_select & 0x08 ) {
! X" J& A" m8 V, U$ e9 H( ]# Y                if( addr >= 0x5000 && addr <= 0x5015 ) {8 H5 o) f3 q. A6 p, k1 |# ^
                        data = mmc5.SyncRead( addr );& w3 E+ ^/ w0 ]
                }
2 _. u* \5 _' g. N+ H        }
9 ^; k( k! t& d/ Y- P2 ]
& N2 H" t1 W, ~* K: c6 T( v1 Y        return        data;0 `2 r0 _2 v. z* v
}( V4 k# f* w& G& M
- g8 P8 i" o  w
void        APU::ExWrite( WORD addr, BYTE data )
. A; z+ k1 n0 \0 [9 r1 B1 l$ u8 _{* D5 J5 s7 q9 J  m3 j& I2 O/ M
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );3 O1 [9 l% I2 q; X; O8 h: }
( {6 C) @+ {3 O9 b  H, q
        if( exsound_select & 0x04 ) {
# ?9 s' K& R7 @7 Q8 P. c                if( addr >= 0x4040 && addr < 0x4100 ) {
* V& i; e. W* ]( t: ]! _                        fds.SyncWrite( addr, data );
0 j9 I# N" S4 H                }$ v+ j1 u" }! m0 b( q+ g
        }
7 Q" }: [" Z) ^0 O# ]4 E" m* u* E! m9 W+ a4 k, E% d
        if( exsound_select & 0x08 ) {
' }  b' U: {) R  W2 W4 P; w                if( addr >= 0x5000 && addr <= 0x5015 ) {
; \) `4 @+ P7 s# U8 R                        mmc5.SyncWrite( addr, data );; U* f  u) c% l; |: y/ [& ~
                }! l  i4 a! Z- f9 B) |- I( x
        }: }; {% [. H6 C2 `- p* }
}( H1 Z4 i8 v( C
8 @/ ?/ ^+ D; c# C) t; M
void        APU::Sync()2 ^1 o7 j/ v: f2 `
{
3 q6 d8 S7 t' D& c# E( ~}/ W! c+ w. _: a0 ]3 e5 Z, N. o
0 F  A, F. D( b9 t" ~* L' ]8 W
void        APU::SyncDPCM( INT cycles )& h9 ]/ Y0 L% c: C; N- C: M, Z
{7 [! O* S+ _, F8 o% ]
        internal.Sync( cycles );
7 u  O  C% S) y
4 n% s" W" x, {% H/ T1 W        if( exsound_select & 0x04 ) {
1 k% f5 |, R+ |8 s0 m# v1 V2 C; G                fds.Sync( cycles );' j4 ?) [- {+ a1 a' N& E; G
        }/ l  Y) B9 ?$ ?$ ?; F
        if( exsound_select & 0x08 ) {
$ P+ ?5 }3 Y: y                mmc5.Sync( cycles );! \" l5 c4 T( o6 S7 H9 I) q
        }
, t8 [. U; s; U# Q' ~, N1 ?}- y. l1 H" ~4 Q# O: z( T' j) }
# O- F0 L' n7 j/ c
void        APU::WriteProcess( WORD addr, BYTE data )( M' U) u. y2 Y" n0 `1 L
{
* F" Y1 ?3 ^9 \$ `4 K6 Q        // $4018偼VirtuaNES屌桳億乕僩
# g9 T! ~5 h5 T7 [" {4 h  j9 j$ z        if( addr >= 0x4000 && addr <= 0x401F ) {
) M4 K! D; x* G% s! X1 n" G                internal.Write( addr, data );
$ D( @& P, O8 O        }
- v4 E$ @7 L9 |}
( I9 H4 L' s* Z6 ~+ k% j+ H# `8 y) R0 ?, e4 f
void        APU::WriteExProcess( WORD addr, BYTE data )
! W5 S7 S& Q3 m0 `8 M8 D" m{- c. \3 f: V% O3 U! O% _
        if( exsound_select & 0x01 ) {
; {) R4 z9 u& S: R1 [: O# \! `3 ~8 ?                vrc6.Write( addr, data );$ q/ z9 P# V8 J7 R5 s
        }
, R+ S. J1 `7 h$ r3 P0 Y        if( exsound_select & 0x02 ) {
/ M) ^2 y5 ~, H( q                vrc7.Write( addr, data );
6 z8 h5 V- R6 s. b8 U- ]. O        }% _# Z) L, t- X% s# l5 k! ]: p3 `
        if( exsound_select & 0x04 ) {
& l; S/ A$ c/ {9 m( s  R) Z                fds.Write( addr, data );5 w9 E5 a! D8 f" [9 ~. z, S, G( w
        }
8 s0 W, a- V9 o' X        if( exsound_select & 0x08 ) {' n1 K0 r4 C' K  R" p, E8 H
                mmc5.Write( addr, data );
0 }0 }& z/ w$ o- u; R9 ^        }/ z1 @* {  A! ^% Z5 w
        if( exsound_select & 0x10 ) {
; @. p, G3 h$ X9 H( a: o: x                if( addr == 0x0000 ) {
3 P4 x8 |! H, L0 k' g( m                        BYTE        dummy = n106.Read( addr );4 K- G$ A. n: w. F- S9 ~
                } else {
) c4 B) [8 ^! {3 \                        n106.Write( addr, data );! @4 B: v, T' C, T( A2 p/ _& |& n
                }0 q$ C* ^  m+ O$ r1 R, `# G! g
        }& Q6 A& R' H" Q3 I& h
        if( exsound_select & 0x20 ) {
& R! q# ^: _2 i! x( f                fme7.Write( addr, data );
: A  {3 i5 G5 O$ G' t8 x        }5 p0 @$ S5 X' `+ C' j; F- j
}7 C5 |* b4 p: I) d5 }

) Q, P9 \5 H* D' tvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
3 {- I  P$ u2 `5 d+ \{
  l/ S2 \9 \( U) P, g  G3 DINT        nBits = Config.sound.nBits;: @8 A2 ~  d# R1 D7 G
DWORD        dwLength = dwSize / (nBits/8);4 b# ?9 b* a' Q7 W5 e; m  ?( Z0 F
INT        output;7 M+ I- a( f" _! d9 r
QUEUEDATA q;9 U( b: [8 l" i8 `. \
DWORD        writetime;+ R: U; U; D& g$ l+ T4 f: H
. r' \) x, z: h; M
LPSHORT        pSoundBuf = m_SoundBuffer;1 D0 j, C5 `& h* V5 R# k' x
INT        nCcount = 0;: x+ r5 A# y; T; s; p

' s6 I% @6 n& s% n4 f' r) mINT        nFilterType = Config.sound.nFilterType;5 y/ o; v; _+ q$ E# K5 C
# V( Y: b! P+ L* |7 ~
        if( !Config.sound.bEnable ) {
% n& @% G) I9 t$ y' g- f                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );5 D3 c9 f1 k" r' h7 K/ f4 G( u
                return;
3 H: Y' ?. m% H( ]- q% ?+ ^        }
% U; o5 r4 S. c. v- r3 j( s
! B( j& X3 G& A" X2 K8 b        // Volume setup. x! |. }$ u( ^: P
        //  0:Master3 ?2 x8 F3 n% b7 q+ i1 T' ?& ?6 E
        //  1:Rectangle 14 L5 g! a, i- Y3 ~& }
        //  2:Rectangle 20 S5 F( j/ t/ Y: ?6 @/ o2 U( n7 O
        //  3:Triangle
/ S  _0 d# E$ i4 I2 V' u6 a0 Y9 n        //  4:Noise
  B& S' D2 v; l' m) G0 M  w8 c        //  5:DPCM
" E& u8 r( x2 R1 X( M% k        //  6:VRC63 M0 B5 U3 i2 @; }9 S7 _% W: [
        //  7:VRC7
+ M8 ~8 i3 c# f" D$ `        //  8:FDS& i3 `3 j" t' O
        //  9:MMC5! N# U$ H" S  t- t6 R5 e
        // 10:N106
2 U! T" ?% x8 G7 f0 L! f        // 11:FME7% r% m/ R/ `6 H7 |
        INT        vol[24];
1 k* g) r6 u7 v2 I, S* ?2 Y1 h, G# a        BOOL*        bMute = m_bMute;7 d" m! n% @0 ]) i9 T  V
        SHORT*        nVolume = Config.sound.nVolume;
/ K+ V( S  s+ }% K. P7 S3 E4 l( U  P
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
# m2 F8 y' ?( s8 o; z- j. E0 I7 ~: X2 O3 Y' D9 J- x! x$ ^* S" y. \
        // Internal$ {, k( \- \  a/ g; i. @
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;5 Z$ V5 P' q2 L) u
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
& {% z! o0 y: L2 P        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;8 g) i7 ?$ ^" `
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;2 K4 [% `) r' \% s3 h
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
' Y3 R. z3 e  s# m
6 @/ g) M+ E# \' Y, ?6 D6 w        // VRC6' Q0 h& ?+ m5 ]: D; K! B
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
! q" {/ }; y& _4 R$ g' R        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
, y2 |2 E: C9 a  r2 y6 ]* ]0 H8 s) J        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
2 F7 A+ O/ L0 Q
- d, i) e1 S' i# W* }3 U        // VRC7) o6 l1 i5 H4 Z3 }/ K/ b) Y
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
  q2 M( M  e4 l( V% E* }% G3 k
        // FDS3 V8 B: c$ z# I( r# O. T$ f
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
! f. z1 z) T. E5 _" T
8 z" \; b9 g1 x7 m- d; j* @+ D  ^        // MMC5) h" w. d5 D. I0 }" {! x
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;/ a9 j/ n/ l) Z/ E) A; ~& A# a
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;' O- Y! T: y/ `% C
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
4 B9 s8 N3 m5 I( `
! o$ Z0 j  j5 {+ a. m+ x        // N106
% _0 D6 r3 k% o  J$ F- T        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
) \3 }: H& V& n5 Y        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 n9 L2 T5 o9 ]1 q7 m        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; z  G% N# r  o3 u3 }( E0 u4 S
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
3 |4 s' }7 n% ~" y" L1 H/ k* J6 X' f        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- Q4 _  R! X( u3 w# d        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' M; K8 g% Y/ U8 C9 _4 Z" ~
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: F4 m/ w9 p! v4 d        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;! k  |: N% `/ [9 Z$ B  b7 c* M

4 R3 q1 \7 ?, a4 D/ C1 u5 w4 {* O        // FME76 X3 W2 P* T6 ^# p
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;& n& h, F+ E& y; @8 ~/ q
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
1 I9 W5 D+ H: b  H* b        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
) L" e0 n/ O5 A- U# j; N+ V, d. ~  a2 c7 g6 ?
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
8 R/ [! Q- p! H% v' \3 k        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;! ^& m' S0 w. ^& F- E: D

3 w4 y( ?4 B' N" z( t3 Z        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
3 F5 l5 X6 R3 x        if( elapsed_time > nes->cpu->GetTotalCycles() ) {# ?# ?# g8 O9 W- j
                QueueFlush();0 m1 y/ U& v5 W+ W, ?; {% i
        }
" S* `2 I: D/ @! Y
- v! U: H3 W$ V; k3 |7 w        while( dwLength-- ) {. a2 c! H2 ^7 y- G; L$ F# k9 c
                writetime = (DWORD)elapsed_time;
: c% Q! X) `& s$ q
1 N1 H5 F, l1 {                while( GetQueue( writetime, q ) ) {; A6 H0 V1 T$ `2 ^2 ?
                        WriteProcess( q.addr, q.data );% p; X4 D- S# @3 Z
                }, Y& c, k2 y: Y, R! s
7 k0 L3 C" i  x# I: j" l+ q
                while( GetExQueue( writetime, q ) ) {
5 r: u5 J2 r$ a& d                        WriteExProcess( q.addr, q.data );
: t. s2 u6 n! Q                }
- P0 U' g+ {1 `5 g3 m# j5 E. ?4 L% q# w9 h- ?
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7; Y- L: G' B  O  |7 K6 Q- q- u/ ?0 P) D
                output = 0;
; n* e( x$ V+ T1 X7 R. E6 q                output += internal.Process( 0 )*vol[0];
3 |  A. A, V: E9 P' @+ c9 @                output += internal.Process( 1 )*vol[1];5 V$ y$ L9 R2 l4 W
                output += internal.Process( 2 )*vol[2];- g, g2 N" ~( j
                output += internal.Process( 3 )*vol[3];, b" U) Z+ I4 \6 _
                output += internal.Process( 4 )*vol[4];) O- {7 g# B' w- p0 S

9 y! O: t5 x# M2 [5 W                if( exsound_select & 0x01 ) {
# Y0 n( e/ K5 I6 X& d2 d5 l                        output += vrc6.Process( 0 )*vol[5];8 Q6 x! D/ H$ L1 c/ W% _
                        output += vrc6.Process( 1 )*vol[6];
8 A0 }% p* [  q# e                        output += vrc6.Process( 2 )*vol[7];
# {8 C& P8 h& @9 D" R' V                }
& A3 V0 _8 b1 }# \5 F$ o0 {                if( exsound_select & 0x02 ) {
& |2 \* o  e) U4 x" H3 `9 M; ?- M7 D                        output += vrc7.Process( 0 )*vol[8];
; r( ^3 s* j6 _7 ?. u1 R                }" q# W: `$ ]9 l. q4 a2 m) R
                if( exsound_select & 0x04 ) {% l  W9 J/ T3 ]7 |4 p/ u
                        output += fds.Process( 0 )*vol[9];1 T' t/ p2 c3 x, o5 I' ?  Q9 K; |
                }0 m5 C3 X/ |* \/ B# l
                if( exsound_select & 0x08 ) {+ C4 ]! t2 F) x/ V
                        output += mmc5.Process( 0 )*vol[10];8 Q, B& \7 H, k1 k: l" B( a
                        output += mmc5.Process( 1 )*vol[11];
; @) Z! L( X2 t( ^                        output += mmc5.Process( 2 )*vol[12];
4 ]' A+ |: R( g                }
3 |2 O, k' A: K& P; d3 q                if( exsound_select & 0x10 ) {% P6 V) T1 h) B  Q4 z
                        output += n106.Process( 0 )*vol[13];" S0 y+ ^- H( x( ]2 s! `4 \
                        output += n106.Process( 1 )*vol[14];
- M+ S  c- x2 [% z                        output += n106.Process( 2 )*vol[15];9 D- f/ y# G% `% [
                        output += n106.Process( 3 )*vol[16];! N/ X3 N+ k4 W# H' k
                        output += n106.Process( 4 )*vol[17];4 \: U$ h& f& E; J/ L3 p" d
                        output += n106.Process( 5 )*vol[18];
  y6 J7 d2 `0 B# Y- l                        output += n106.Process( 6 )*vol[19];; G* K4 @" H9 o( w2 `
                        output += n106.Process( 7 )*vol[20];
) n5 T+ m, b$ n6 D+ u                }5 ~0 e; R- n) L1 K# C
                if( exsound_select & 0x20 ) {! b4 u/ @9 T3 {
                        fme7.Process( 3 );        // Envelope & Noise
( R2 x: Y2 p9 \& T                        output += fme7.Process( 0 )*vol[21];
" s- v& P  A3 r                        output += fme7.Process( 1 )*vol[22];0 E: w% {8 b# z  V
                        output += fme7.Process( 2 )*vol[23];$ X" T( n! z$ l8 |$ `
                }6 [- Z3 R8 P4 X6 b1 C' @! H4 y

. P' t9 F6 c5 q                output >>= 8;
7 m3 M/ S7 I0 J1 W' a" X
9 Y* E! F. l9 x0 p( B                if( nFilterType == 1 ) {
, n' s8 N( G5 k# ?                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)$ ]8 E) ]) B# @" O
                        output = (lowpass_filter[0]+output)/2;
( t+ |' i: O2 x                        lowpass_filter[0] = output;
+ a3 {9 z1 H- A( @: G& ]" q! H                } else if( nFilterType == 2 ) {' L# a, c( H% s! h+ O' A0 X$ j
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
8 d, @; ]' l% u: n                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
! V3 S/ M2 R5 b. Q1 |                        lowpass_filter[1] = lowpass_filter[0];
7 ^! o. O9 P, w2 y( g                        lowpass_filter[0] = output;
/ F: f& U8 a; {$ I8 x/ E, h                } else if( nFilterType == 3 ) {; z* w) U% N% _  a, B
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
8 n3 `4 f8 W6 x! _                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;  j, b5 h! V- y1 X5 V3 K/ y! c$ S
                        lowpass_filter[2] = lowpass_filter[1];
9 K  h1 M0 L0 O% R) G, C; c& n                        lowpass_filter[1] = lowpass_filter[0];8 U( ~' B0 O! j5 j  {; s) [
                        lowpass_filter[0] = output;
1 ^5 v% N3 P" Y                } else if( nFilterType == 4 ) {
# ~; ^7 U9 P( ~$ B                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)- z+ l% w+ d! k) x
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
6 i; g7 f$ E" n; h2 C$ r; F                        lowpass_filter[1] = lowpass_filter[0];$ y. G# M  R  s& K5 D
                        lowpass_filter[0] = output;
+ K- I2 c. o4 ?7 i; G                }
" w) M- u) c' X, Z& `$ F: S, S+ E1 \$ C3 g5 r2 I
#if        0
0 G& ]1 x+ P$ x1 j2 P1 T# k' m                // DC惉暘偺僇僢僩: c/ Q9 a2 s1 A7 Y
                {( ^$ R) D0 Z3 s  J1 o& R
                static double ave = 0.0, max=0.0, min=0.0;
4 w' `# q0 f6 d4 c( `6 Q& o  N2 n3 U( s                double delta;5 {6 l9 L' S* r
                delta = (max-min)/32768.0;' t6 `! W5 O) [( o  f
                max -= delta;2 ]4 J. m1 n( `  h
                min += delta;% z/ L) e( V4 [2 h3 J- o: a
                if( output > max ) max = output;
4 u% Z2 n. d* c( W( M: n, V, d8 ^                if( output < min ) min = output;
& t, a, |1 y: N4 ~/ i                ave -= ave/1024.0;7 F# W1 w' j! H, d4 d5 t  W" ~& s( `
                ave += (max+min)/2048.0;
. _# W- V) ^1 B7 ~$ W0 U                output -= (INT)ave;
. s; k9 h; O3 c* `8 X                }
$ P" ^% k% r3 |( {#endif
. X6 R6 X- C" V3 m3 s" L#if        1
: H9 I4 _+ F! ~1 V& y9 ^' t                // DC惉暘偺僇僢僩(HPF TEST)
9 ~* |; }" N& N7 E# i- l                {
- v  \' U( N: H  M/ y//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);5 O5 K1 U2 C/ m7 Z& i* `/ X
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
2 h  E8 n- d9 H/ g/ h! R. `: _8 |                double        cutoff = cutofftemp/(double)Config.sound.nRate;
$ n+ J$ B; K7 U3 V                static        double        tmp = 0.0;
3 |( D" B( V; b                double        in, out;
- c8 ~3 e0 _9 S' Z0 ^& r
- b! i" R. O7 U1 y/ [                in = (double)output;  Y/ i/ c& |6 L. P) z
                out = (in - tmp);
% J% m' H3 b3 N: ?                tmp = tmp + cutoff * out;
6 W1 b# i5 y) t) L; T$ {$ m
9 t# L2 t  h7 \3 j- v* W                output = (INT)out;$ Y  X" h0 b. X  A, c; L
                }+ Q* w5 J" ]4 H
#endif; L8 u4 y( D- R# p
#if        0& s2 ^! L, d* J9 I
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
/ _% b3 L( P7 I+ y0 v7 Y                {) f- Z% d: X; k  e2 q# B. H
                INT        diff = abs(output-last_data);8 x' V# ?# s/ v% m3 s0 c* J) x6 k
                if( diff > 0x4000 ) {
8 T8 Q' Z+ N4 p8 c                        output /= 4;
& |8 t' g1 j; v' o6 l7 w/ _/ W                } else 3 X$ N+ }+ X( t3 V, G8 s
                if( diff > 0x3000 ) {
5 `' N% P5 I; H1 r# Y                        output /= 3;/ W( {) q0 ^- N' w
                } else. }3 x: y/ S2 k0 R; D7 w
                if( diff > 0x2000 ) {! \( X* l! T4 c+ H- J. R$ s$ M, O
                        output /= 2;
) i3 |  @, [  j) ^                }# Q2 L% e2 b! U2 m- A
                last_data = output;: @( p* f3 V- V
                }; u4 P/ k6 F0 X4 M7 [
#endif/ F0 k2 D% T$ u- n9 J% ]
                // Limit
( k+ L% b) Y8 W0 n: r                if( output > 0x7FFF ) {& _" m$ d! t4 N! n4 n8 E0 u1 _
                        output = 0x7FFF;# V6 T( o/ v" k; H9 Q  \  I
                } else if( output < -0x8000 ) {
/ P3 P+ h; r$ y$ \9 q  P1 _6 i" j                        output = -0x8000;
3 @6 a% t4 C5 _( l8 y9 I% w. n( }                }
$ X. ]$ o/ H/ v/ }6 S/ M  B/ v& C9 f( H$ R
                if( nBits != 8 ) {$ {9 k2 Q- t4 u
                        *(SHORT*)lpBuffer = (SHORT)output;
  l! g; z: J& ^( I                        lpBuffer += sizeof(SHORT);
: Z: Z; Y$ g* P5 G                } else {3 d( x- k  j1 m# n; S% B
                        *lpBuffer++ = (output>>8)^0x80;
# l9 `3 }' r2 {8 b& F                }
4 x1 b" D9 `) x8 l+ n
8 W0 R* W8 ^8 m8 o4 K- O                if( nCcount < 0x0100 )" S0 r0 ?. Y3 @: q
                        pSoundBuf[nCcount++] = (SHORT)output;
. n2 b2 U2 W. U; I% @  h
2 }! Q5 |- z; ]0 I//                elapsedtime += cycle_rate;
( T. V" a  O! V3 k# @) z                elapsed_time += cycle_rate;* Y( T3 C9 l1 d4 K9 M5 D7 |
        }, ^; [) b) v) E! m2 C) P8 n
/ h% A) h: W3 [! u. j' t9 w" K3 G
#if        15 \- c, `+ U3 V+ ^! A
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {4 V' q1 ^- g6 J4 Z, a4 w) f5 G2 [
                elapsed_time = nes->cpu->GetTotalCycles();( P& I% k, g, u) W- a* [
        }2 a& ]* w# W" z7 ]* Z
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {2 J! R3 Y/ i$ u8 c, J: @
                elapsed_time = nes->cpu->GetTotalCycles();1 p) H) s+ }, x$ F" y
        }
7 i0 [# {/ L% C0 y#else
. _' ~* X6 a3 v' [# b        elapsed_time = nes->cpu->GetTotalCycles();
- k9 X! Q. C) `+ a# z#endif
7 i: d& t6 i) m  _}9 l2 G. V* u" @) D/ n

9 H4 ~9 _1 l/ |( R/ B% y1 @0 x// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡). U3 u+ n; m7 ^& a. |. e
INT        APU::GetChannelFrequency( INT no )
( O+ H7 E0 w, b' d{9 c- r3 i) E2 e8 a  u. p& \
        if( !m_bMute[0] )/ [/ [- r7 o  j: D
                return        0;
) U7 H% q: N) D( a4 N( u7 |9 U. O7 D+ H
        // Internal
+ G' T1 Z$ X* A& q        if( no < 5 ) {
" R- [* u; s3 \" B& z; [4 U                return        m_bMute[no+1]?internal.GetFreq( no ):0;
* T8 ]4 e, I# n        }1 Z' ^3 Y( x1 Z- b5 _0 A
        // VRC60 }* u: ^0 F" e* g
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {- o6 Q1 X- ]* G8 r! v+ A5 ?
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
; \5 S$ Y. M9 {        }+ v) b. P$ k: o+ |) G! B" V
        // FDS
* T  X+ t) c8 x. V        if( (exsound_select & 0x04) && no == 0x300 ) {
3 [* H3 z, v9 C5 [                return        m_bMute[6]?fds.GetFreq( 0 ):0;1 H% _& `: c0 P
        }' ]  S$ o/ r# x7 S" \: y
        // MMC5
0 r7 P0 w% q. u! D9 f6 G$ M3 U' [5 {        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {4 p6 [4 X9 x& f8 z1 b4 j$ i. p
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;! Y, K+ Z! ^' [- J9 B
        }7 C2 m; @7 g# X& a% s7 I, r$ c
        // N106
' e# ^  [  J6 j. O: O: K, a        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {& p/ {- P: y, V( y5 G( _( G0 Q
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;# g" m! Z! Q/ ~/ M
        }% h. S5 _0 Z0 \/ E* w/ |
        // FME7+ m6 l+ [3 r# B( F) T& A1 ~
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
8 H5 H. n% O+ z, G& |( w                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;+ o1 ^/ i2 d1 R! W! V
        }$ t, a( N- o9 q' j9 I
        // VRC78 x8 a3 l& \( t# ~+ \. a6 o
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {9 U6 ~5 u+ t# \9 B: s$ J5 h
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
/ E* L' s, y' e- h3 P        }
* F0 @$ p" u/ ]+ h" _8 M4 o" T1 C        return        0;2 {. b, _- Y- V: w
}
, P- ~8 r& r  R+ P
( v6 j' T6 l- M3 _// State Save/Load
4 r1 u' Y$ m' \% P- [! Jvoid        APU::SaveState( LPBYTE p )# n: ], K$ Z1 `
{4 P3 W8 ^% j: W5 P* @
#ifdef        _DEBUG8 W, J. N2 v0 P* \9 G3 j0 E" w
LPBYTE        pold = p;
1 G  T8 U: s9 [  b( _#endif" Y/ a: H0 \7 m: G  [

3 z! o- ?4 F  i: ?' {5 W! L8 _        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞  K( C6 o& R, u/ F5 T. v) E4 B
        QueueFlush();
" u' C) _) p5 R! t0 B5 P2 P
9 ~6 A  W  X- \: v: n* i- ~) M& l        internal.SaveState( p );3 o6 L# h- r0 E7 M7 U
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
4 b  X0 [+ S5 u9 T0 V5 ~
" y( k+ T+ T4 G* Q# x5 V( L        // VRC6
0 n- M, ^( J/ X/ [3 H/ c( U        if( exsound_select & 0x01 ) {! [! N) |1 w& x2 t( f- H3 G$ \
                vrc6.SaveState( p );& k8 W( _$ o  Z1 I7 x
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding1 ~0 L; |+ G( d# D' X
        }
* V7 w. I6 _( o; W- `        // VRC7 (not support)
& C8 [3 `6 A6 I& _# T        if( exsound_select & 0x02 ) {
4 g) a! N7 J6 j+ ]8 \                vrc7.SaveState( p );
. Q, z% s, h/ h9 q; t# }4 N                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
0 A8 x( a) k0 m) Z        }7 c& @$ I6 t2 O6 }1 @
        // FDS
0 E7 u( a1 P5 J! _: t" ~        if( exsound_select & 0x04 ) {3 A7 w3 `" @$ b; X, N
                fds.SaveState( p );
6 {7 w$ y/ C" ~& T+ z                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding  a( S$ a% N: E9 @5 r. o
        }# R7 y0 S  N6 v# o* [- ~
        // MMC5
. s* Q. w/ F/ [) G" r' r$ w3 y        if( exsound_select & 0x08 ) {
& w; k) {8 O. k* r! [4 G) \                mmc5.SaveState( p );, u4 _- R. K+ }3 \3 @
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding* z, n, _* B' a. l/ J  ^1 B
        }3 z4 |+ T0 |" ~, U/ s) }5 s
        // N106$ a6 n5 K/ X" \) @1 ~
        if( exsound_select & 0x10 ) {4 c6 T7 d! g' t& L
                n106.SaveState( p );: C9 K  ^0 [/ Z) M
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
9 D" X: m+ _- ?, r. i. ~# O4 r        }3 c) {: q' Y+ B' C/ f1 s. \* W
        // FME7( w) L1 j% Z6 }, o- k' q
        if( exsound_select & 0x20 ) {1 u$ ^) p) p+ R! I8 I7 s2 u; y, s
                fme7.SaveState( p );- O+ V4 g5 ?! d6 l1 j6 d: q" h
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
! g1 g( J( f% m: S4 b        }. g$ ]8 {4 ]$ C/ l7 n+ ?3 Q
( w  I* ^+ i" X
#ifdef        _DEBUG
  E1 o/ K4 N7 _0 U, oDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );; E0 X7 K/ d" B- M0 J
#endif" {; ]% T2 H2 _* R
}% r. v1 m7 B5 {3 O) J: E; J; S

. K2 x$ c- s, d0 Q$ C8 D# j0 evoid        APU::LoadState( LPBYTE p )
$ A! K1 R. f  u1 H& C. _{* n- T7 z* G& J3 K6 |" j( S
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
4 U" w3 F6 H/ Z& t4 Q% k& G: S        QueueClear();
" Y. V2 \+ V. _( C3 n  K" E+ U  n; G4 `. V1 G0 ]( T, m, P
        internal.LoadState( p );
2 p) w2 E( g' m% F; V$ \; B. P0 W  v        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding2 h5 O# T8 M8 I! J, \5 g" \, y: }. d* V
2 h+ m. l1 Y3 M$ |! T0 @
        // VRC6
. {5 X5 H" w# E4 ~  E% T        if( exsound_select & 0x01 ) {" ]  n* v$ X# D3 ^8 Q* g
                vrc6.LoadState( p );
7 X$ H4 j8 u! E( I) w$ J% }                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
+ i1 i! K' E: h        }
* f+ p" ~  v9 ?0 C        // VRC7 (not support)
# Q- j7 z# }$ _0 X: z/ n& [        if( exsound_select & 0x02 ) {- {: v3 D8 j8 ]* |. U4 ~& M
                vrc7.LoadState( p );2 Y; a9 t' n, S) E$ S
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
! S* v3 n% v& e3 ]" i8 l/ b        }
8 M1 \" N6 }( ?; [( }  K        // FDS5 h# F% H9 V) e
        if( exsound_select & 0x04 ) {
+ w5 }: J3 }# [* f# f: o  m                fds.LoadState( p );
0 s/ i4 ^1 x8 _5 S0 ?- N* u$ f0 r8 i                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding+ v  V! [" x6 G, @# }$ D
        }6 u4 O: q# k  G! S- Q
        // MMC5/ b& v, m% j$ t; V1 ^
        if( exsound_select & 0x08 ) {
5 @5 w6 M2 t5 ^0 s6 d                mmc5.LoadState( p );0 p7 ~' c1 I; Y2 E; W
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
, d- }. b9 r' f6 y        }
3 }; L1 k6 w" @, Z2 W- k1 G        // N106$ ~" T, p  y2 m4 h/ L  `# _  x9 S
        if( exsound_select & 0x10 ) {
( |& c8 ]  g/ R/ t: L                n106.LoadState( p );" e2 E1 E; ~4 p5 t
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding* J- u# f* O0 Q' K; @; o( Q
        }
' A5 m8 r1 J( D8 V        // FME7  h* p: @$ B( l0 f# l* a# p  u& K7 c
        if( exsound_select & 0x20 ) {
8 k$ @' g: B+ Z4 r, \! Z5 ]6 g* z; v/ b6 F                fme7.LoadState( p );# z* R/ L* n9 }+ t. q" E- P( R
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding& L' Z7 J& q# V  q; H
        }; R! c# h* T& X* A8 ?
}
回复

使用道具 举报

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 ; V+ \& [3 J) ?: _# i6 D/ P
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。0 Z( p; P$ d& P8 F5 F4 u
感激不尽~~
; M: G4 v. p$ w
恩 我對模擬器不是很有研究,
( S8 x2 b3 R. H1 j雖然要了解源碼內容,可能不是很困難,# e3 Y! A+ Q' L
不過還是要花時間,個人目前蠻忙碌的。
. q& K$ i1 t. U& Y3 s
  _8 A1 o+ z' j$ N" H; y! X/ {1 }$ Z* a給你一個朋友的MSN,你可以跟他討論看看,) R, y. ?8 h, ^) e. `
他本身是程式設計師,也對FC模擬器很有興趣。
0 A, P2 [! i  B( A+ h: F) A# S: Z( F6 x  ~8 b
MSN我就PM到你的信箱了。! P$ o( j9 K1 \1 {  \7 L' M5 X
0 @% L0 A& I. C5 J% Q# V1 F5 O) \
希望你能有所得。
回复

使用道具 举报

该用户从未签到

 楼主| 发表于 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 发表 ) w1 P- r% ~+ m5 a7 [% p
呵…… 谢过团长大人~~

3 B- U2 \2 o8 A4 ~0 ]5 u6 o; W' t! b$ g: f: y# U9 \
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 , F, {1 ^% T) a3 z/ G
团长的朋友都是神,那团长就是神的boss。

( Q8 k$ r+ Y- \+ v7 G& Y+ ?; ^) G) z' W哈 不敢當,我只是個平凡人,7 X, ~6 a4 @3 M: H. q) F: F# W  G
要吃飯喝水,光吸空氣是不會飽的。。。。 :)
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
9 U  r0 p# w; g5 T. y4 X1 a5 dZYH! g( h5 }/ B8 l# ]# \
QQ:414734306- b" v8 z" C, Z+ N5 B, G  D7 C
Mail:zyh-01@126.com
% S* I. L1 _1 v* c$ m( n; T1 U' v; d2 g! `1 R5 _/ X
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 + s) S+ v3 P' H4 m% Z
再次对团长大人和悠悠哥的无私帮助表示感谢~~
; Y+ j- |. N7 H/ g6 T3 g
不客氣  ^_^
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-7-16 06:40

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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