EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?
3 r) g" U+ A3 E. ^- y5 R/ LPS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。8 S# y; n# Z- @
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~4 b2 f( }8 C& N6 I4 r: Z" m* x1 h! ]
这里有相应的模拟器源码,就当送给大侠了~~1 N( w& v+ r3 A* q
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
# |% x; x9 s) j5 `  ?6 _能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
$ E' a& J/ T6 W) R2 o& y: \楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
* |7 ~9 g' p8 E, i5 u$ Z这里有相应的模拟器源码,就当送给大侠 ...
) T7 E9 S. E& \# A$ x. q+ t# S
聲音部分(Audoi Process Unit = APU):
7 e6 i( N# B- _: ?' c.\NES\APU.cpp
: P6 Q# v7 S! }8 T.\NES\APU.h) p) q) {# Z0 b+ k' m
% E6 A2 l% c* I# B) ?2 z
1 C7 q1 a7 {6 B, q  `
影像處理部份(Picture Processing Unit = PPU):. i6 ~: n% }5 M0 i
.\NES\PPU.cpp2 \  c+ S* ?: }( `" F' D
.\NES\PPU.h5 G* H+ _8 ~9 \
: G# H$ f; \+ d+ @
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
3 \5 t$ l$ j5 d. \(由于很多专用术语和算法机理都不明白,所以看不大懂……)0 U8 k. H6 I, P$ a
//////////////////////////////////////////////////////////////////////////+ J8 W, \2 s; Q1 r0 |' l' C) K
//                                                                      //* r8 g$ H$ N9 Q  ^! h- M$ y; J
//      NES APU core                                                    /// ^/ r8 o/ K, s4 ~
//                                                           Norix      //; Z2 U+ H! b& s
//                                               written     2002/06/27 //. t8 _, p' i) c4 Z( C% S
//                                               last modify ----/--/-- //
5 j. q4 \& g: F! u# c$ _( k, L//////////////////////////////////////////////////////////////////////////
2 t$ U* O' Z" C6 C0 w7 e# F9 v1 ~#include "DebugOut.h"3 j) `2 V" i+ Q( M# P: h
#include "App.h"( [* [2 J/ {3 f$ K/ O8 F
#include "Config.h"( t8 h2 ?. j- q' l$ E3 c3 X" @0 `
2 e4 P- A5 e- W! o% x. V6 q
#include "nes.h"
4 s; I' R4 \7 ?* A* j#include "mmu.h") q: ^7 [6 }5 {: x3 X- Z8 J
#include "cpu.h"
  U8 z' o5 r/ q0 i6 X  u9 F# p#include "ppu.h"4 ^3 p& T  G* k5 f6 f
#include "rom.h"
) G& _! p% ^$ |- d& X0 x#include "apu.h") a  D' t8 L' Z7 h" e6 j% z
+ }$ e' Q8 l3 q* }
// Volume adjust" l, ~5 u% L9 N) K! @
// Internal sounds. @1 b- r9 M: `, O
#define        RECTANGLE_VOL        (0x0F0)
7 v% ]" r0 B5 Y#define        TRIANGLE_VOL        (0x130)  h1 ]( M9 Y% S
#define        NOISE_VOL        (0x0C0)& H3 k% a: D+ N9 Y
#define        DPCM_VOL        (0x0F0)) Z+ u3 C/ B- m3 ~8 {* a& e( A- `
// Extra sounds
2 C; {5 v1 p4 g' u#define        VRC6_VOL        (0x0F0)0 |0 [( J* v- K1 i5 A
#define        VRC7_VOL        (0x130)
6 \! o! k, }1 B1 m#define        FDS_VOL                (0x0F0)+ t* ^4 ]! P( U
#define        MMC5_VOL        (0x0F0)) D6 W8 m% m8 W  g% h# j
#define        N106_VOL        (0x088)8 _. H: L6 y2 e  X( ~2 S/ }9 J2 r
#define        FME7_VOL        (0x130)
3 ]6 W# v1 A- M; p# d6 R( y4 P/ a9 L
APU::APU( NES* parent )
  H& k. E8 D2 D; h  \9 I{2 @9 i0 j1 m+ ]5 _* _7 `5 t
        exsound_select = 0;
+ ^$ t. x8 W$ A% p: U/ e4 O5 U7 K$ m
        nes = parent;
1 |, i1 s9 Z3 d" I( g  ^        internal.SetParent( parent );
8 S: J1 p3 i& n0 `  n% [
1 ~. v% `* T+ d        last_data = last_diff = 0;2 `3 @) ~, g0 l3 _) D4 `& W

& x6 e$ f- t  D+ I( @# ?        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
% u, N/ d4 b1 K
4 I$ H' g( J+ }9 n. B, F3 v7 W; v+ U        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );+ j$ U9 B, i0 A* E5 ^& T
        ZEROMEMORY( &queue, sizeof(queue) );
" {7 u8 [( i2 r& D- f6 c        ZEROMEMORY( &exqueue, sizeof(exqueue) );0 Q; ^- K& L  _# }4 X

1 p1 x  O2 A7 }4 @- G3 z: `        for( INT i = 0; i < 16; i++ ) {8 G2 Z3 R, M& {0 Z7 |% M* P
                m_bMute = TRUE;
' H9 j7 f. u& h( \' m4 F* L        }+ i9 N0 }) r( h3 t+ f7 n! l
}( m+ V! [$ V4 ^

# _9 }" _/ ~) p, Z, \' J) u0 o9 I* KAPU::~APU()2 L, @  J5 J5 [/ \, X: C
{6 b# @: W( c- ]' G- `; I0 o/ a2 j0 R
}
8 }; S2 f& R' R
  B- q# o* i  Bvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )7 a& Z: A: R; }! a7 t6 C
{
- x0 Q. t( I  n  k, x        queue.data[queue.wrptr].time = writetime;5 U0 \5 E6 R0 C1 ]2 F' P, ^/ q% H, @
        queue.data[queue.wrptr].addr = addr;% b1 N: p7 z& K
        queue.data[queue.wrptr].data = data;
1 ^$ N6 f2 |+ g0 G5 N# R% ?/ z        queue.wrptr++;* P6 z  x, z0 a: k. w! C
        queue.wrptr&=QUEUE_LENGTH-1;
& W) j- _8 o/ U" B8 _2 A" T        if( queue.wrptr == queue.rdptr ) {
4 ^8 n) w+ \7 h, O* P                DEBUGOUT( "queue overflow.\n" );
( R& H6 i5 q, ~( N. G        }
  ~/ X6 u0 a% L3 k' F( u}
3 p2 n* U% S$ g5 w' u% Z; K- a
4 a8 \2 Y* y; d4 g, L& @BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )$ K; i5 T/ a8 l
{
1 ~% l" ]2 n1 m" t        if( queue.wrptr == queue.rdptr ) {
( h1 h3 R8 N. T5 g: Z4 Q                return        FALSE;$ V4 i! r7 J5 v! y, t% V
        }
' r1 t5 i! U4 W; L! s& @        if( queue.data[queue.rdptr].time <= writetime ) {0 {& \9 q* {" u$ L# _/ G; d
                ret = queue.data[queue.rdptr];
: A' f# I( j% [5 U                queue.rdptr++;! D  X( M5 R* W% ]
                queue.rdptr&=QUEUE_LENGTH-1;: n4 m+ c/ ^6 _3 K
                return        TRUE;, m( @. \+ t' s& s! d! P/ h
        }
& J" Y2 |3 v% s/ ~$ y; |- b6 z+ Z9 U        return        FALSE;
, n) n# d+ [9 h8 p5 i& l}1 b/ L; D9 O' d' j5 c- {
; K3 b1 `, Y( a. y6 A* x* I; u- E% m$ b; }
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
" U3 |+ C! j2 d% r6 {{
% L) z$ d* _0 X        exqueue.data[exqueue.wrptr].time = writetime;- K5 i4 c: x. s$ D. H# @) I
        exqueue.data[exqueue.wrptr].addr = addr;
* h) y; I' ?3 d- o9 D0 e( @        exqueue.data[exqueue.wrptr].data = data;
1 @- H$ L3 \* R        exqueue.wrptr++;
. W/ `+ x3 j# ?: l- j. G- p        exqueue.wrptr&=QUEUE_LENGTH-1;
0 v" X0 F6 m; g0 n( g        if( exqueue.wrptr == exqueue.rdptr ) {! F  _4 q" `1 w$ q
                DEBUGOUT( "exqueue overflow.\n" );
8 n, o1 @4 D* X        }3 G' `1 z( b$ X( w" D' C7 C7 n2 n9 j
}; ^$ c& Y; f2 Y4 Y
- e9 G1 V( ~4 ]4 V" ?5 o% F3 ?
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret ): |+ M0 S% f8 P; Y& S% v4 Y' G" o
{" u0 e7 |# m$ J) \- L7 P7 S; @
        if( exqueue.wrptr == exqueue.rdptr ) {
6 Q; n/ D( T0 y# F7 f  [" z                return        FALSE;" W0 w8 c/ f  m& S: x3 @
        }; ^6 }1 r7 m. r/ Z
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {# Z) H5 F+ U/ [; {. Y: K
                ret = exqueue.data[exqueue.rdptr];, Q: K, I3 L. M" U
                exqueue.rdptr++;3 s/ ~4 O  N+ K: v7 t: @
                exqueue.rdptr&=QUEUE_LENGTH-1;* n5 r! [1 y( P7 S' O+ A/ v
                return        TRUE;
: P; o9 J" H& E# h        }6 x6 A, Y( T0 S* E( q1 N
        return        FALSE;6 j7 U* P" g) f" t; J* o
}, s+ j3 M3 C" b. I# H$ ]3 \5 B) {
7 N. J8 C7 u# c3 d: }
void        APU::QueueClear()
7 g+ z! U" s3 M{
3 ^5 {; w* F1 }/ f+ h- q! i        ZEROMEMORY( &queue, sizeof(queue) );
0 a  D4 r! A/ J1 _, m) q# Z0 s) G        ZEROMEMORY( &exqueue, sizeof(exqueue) );
# Y4 ^( X( u5 E7 t; a9 ^& ~6 G}+ K- E5 N: g8 N. E) a# h4 c

. ]+ B  e; V1 q1 |1 `# lvoid        APU::QueueFlush()
# l* u! z: H7 Q  y7 M$ R6 y{9 ^% l1 c- ^4 c
        while( queue.wrptr != queue.rdptr ) {
- F( o- N9 W' S/ |. i, ]9 Y                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );% r* j- B5 g8 s6 u& m
                queue.rdptr++;3 }1 R  [) D/ K' @3 z" ~0 `  T9 g
                queue.rdptr&=QUEUE_LENGTH-1;
/ b. t+ @& w3 _5 W        }
* q( j5 e3 s' G" h# f# I
* \- B" H! ]' n0 V: j9 I        while( exqueue.wrptr != exqueue.rdptr ) {
" M+ Q. ]2 F# L. k* t                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );! K! F& r, U; u6 O+ y) z
                exqueue.rdptr++;
& A# [; B9 ]& n  t. b4 @  e                exqueue.rdptr&=QUEUE_LENGTH-1;! N: D5 y7 y5 y! C
        }  h4 H( Y1 {+ I) w7 \! {0 R
}
4 d1 t7 B7 e4 C) X& Z& }" \' L
/ p, k, f; ]; U1 k1 Gvoid        APU::SoundSetup()9 ?% d' T; u8 o
{" \/ v8 u( a& ^
        FLOAT        fClock = nes->nescfg->CpuClock;9 d2 n) x" s8 [9 Q" f' o7 o5 a
        INT        nRate = (INT)Config.sound.nRate;
  i' Z# c' N! L" s        internal.Setup( fClock, nRate );
; A2 h$ g/ D2 K* \" L" L, K( i4 ]        vrc6.Setup( fClock, nRate );# c1 x* N7 ?, o, \4 H- x, i, K
        vrc7.Setup( fClock, nRate );+ K7 S% M) D6 b% Q, d1 w# p
        mmc5.Setup( fClock, nRate );/ L% ^7 c( d  K' b' ^% z+ [" w
        fds.Setup ( fClock, nRate );" P7 q  H# l7 L" S
        n106.Setup( fClock, nRate );
9 _% a+ D$ ^* d5 T0 T8 o# q! q        fme7.Setup( fClock, nRate );+ w/ n  b) w0 t. J5 ^4 `
}+ f5 N; x% J4 K2 Q( T3 d5 K! r! J

& M& I6 F5 M6 A! m+ ?void        APU::Reset()
; D7 m* I; R2 M$ X, o( ]2 t{
5 s4 f, X/ h+ P& ?6 @        ZEROMEMORY( &queue, sizeof(queue) );6 h* y1 E/ r, s; C4 g
        ZEROMEMORY( &exqueue, sizeof(exqueue) );; j/ z; }. v8 z4 u2 ^: F$ U1 b  U
; V2 ~9 }6 w" j) J! M: I7 H' i
        elapsed_time = 0;& j0 T* I8 P$ @; j7 l1 ^

- y* V; B4 l. `. ^+ z4 v8 ]/ E        FLOAT        fClock = nes->nescfg->CpuClock;! o- a1 \& H5 N0 h1 {- q6 R: [
        INT        nRate = (INT)Config.sound.nRate;
  J# _+ _' C) [( z" l        internal.Reset( fClock, nRate );  I1 y4 q7 o6 k2 d3 W0 z6 Z0 A( n# b
        vrc6.Reset( fClock, nRate );
+ q/ }  b! ^' @% ]) X: ]5 {        vrc7.Reset( fClock, nRate );
5 H7 M. B# e, V0 @# b; d        mmc5.Reset( fClock, nRate );
9 e7 Z7 T. U+ [- [        fds.Reset ( fClock, nRate );" _3 h* u6 ~1 z9 _! {$ l* u5 p1 ]! e
        n106.Reset( fClock, nRate );# f7 f7 h6 I* ]( M. ?
        fme7.Reset( fClock, nRate );0 M1 d* ~6 E8 i5 y+ I: W4 v
# {6 _7 r; s& ?  g* P
        SoundSetup();7 H  o1 A6 E$ I7 u* h  ?  }
}9 X- K& b- z  z, X  o+ S
7 E7 O4 F0 g/ e% v$ I8 O+ S
void        APU::SelectExSound( BYTE data )
- G/ U+ c8 f* h% H+ Y9 C" r& @{$ ^) Q* J, b0 S( O
        exsound_select = data;
0 _7 o, A$ q* K  ]: T9 B& a: F4 \}
) ]6 a2 |( `1 A( g: K# T; l0 n0 I! [) N$ S% Q+ N& m. g
BYTE        APU::Read( WORD addr )
3 v& o' \! `' A  M{
7 x, \: @4 A1 R$ M6 l: n0 o        return        internal.SyncRead( addr );6 S! z& G( X+ F- Y9 b3 I$ d
}0 |4 I9 R7 |, h& h
7 T. g9 u% K. S9 ^4 ~6 M
void        APU::Write( WORD addr, BYTE data )
1 F5 m! M8 c' z) R! Z{7 k5 a; g: `8 h' v- O: r5 E
        // $4018偼VirtuaNES屌桳億乕僩
9 ?4 R! [% R# u. l        if( addr >= 0x4000 && addr <= 0x401F ) {
$ @5 M" o# ]$ b% p* ?                internal.SyncWrite( addr, data );! z  A: U, h! O! d3 q) g7 \
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
: h/ N' x4 }( G- R        }+ I" x' d# z; ^
}
1 k1 t. F/ `  Y2 T  V  D& p5 ~6 D
; N, h8 J: Y0 D4 E4 |  TBYTE        APU::ExRead( WORD addr )' F2 F; f- i  h- k  i# }, r
{
$ f/ [% o; \; t0 D. z2 ?* eBYTE        data = 0;
; }0 P, b5 P, D) s7 u
5 O  b# D- }/ n2 o        if( exsound_select & 0x10 ) {
: p8 n8 z" J# h( X, `                if( addr == 0x4800 ) {
! N- Z) f- ?* p8 g' ~+ M% S! c" p                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
+ V% S; m$ Z* ^: k" R                }+ g# \5 _, y; i
        }
2 ]3 G  b# ^( ^        if( exsound_select & 0x04 ) {
" A6 q# \* `! c1 q                if( addr >= 0x4040 && addr < 0x4100 ) {
% Z% }5 N. d2 |5 K0 g0 T. V/ X( g                        data = fds.SyncRead( addr );" q- g5 q3 }( ?# [1 i
                }. E' M% O+ }( |
        }
7 @  C: Z7 k8 L8 j        if( exsound_select & 0x08 ) {
8 Q8 i+ C: l0 m, Y9 u+ v6 L                if( addr >= 0x5000 && addr <= 0x5015 ) {! D7 L/ e6 b, _% ^0 ?! ^
                        data = mmc5.SyncRead( addr );
2 C) f4 t4 I8 m& R                }
) @' @0 ^) R/ U/ ^& h& g6 q        }# @9 _! ]! ?! O: _
8 |: R, W2 C% g0 S( u+ O
        return        data;- \4 `, S' n. K- n% e
}' t" w! x8 j$ R

% d$ w5 h4 T! \; Evoid        APU::ExWrite( WORD addr, BYTE data )
) K7 _/ I8 M; A7 F7 j{4 [0 |6 _0 i+ `( }
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
1 f& o6 q+ P: W# V
# ^& T2 @) F/ ~) C# V        if( exsound_select & 0x04 ) {
) @" z, v, Y  t                if( addr >= 0x4040 && addr < 0x4100 ) {
1 j' M4 u0 {# F5 m                        fds.SyncWrite( addr, data );
6 n0 `# H+ N' Z9 o* g: i0 Q- i                }
4 |" P- A7 i1 K! C3 ]        }" i3 Q! J9 q8 S& b5 \
8 `! ?$ C! c4 H5 p5 h5 I
        if( exsound_select & 0x08 ) {
, I+ ~3 k" z, I/ I) n0 N                if( addr >= 0x5000 && addr <= 0x5015 ) {1 X8 i6 N' i& h: e2 r; d9 q# F9 v2 A
                        mmc5.SyncWrite( addr, data );' L- `( q% |0 C5 u3 p9 a* `  m
                }; x* S* S% f3 D5 y1 H  y) I7 i
        }% F  O- y/ w+ Q7 S5 Q. e( o
}
7 P  H- H! ?" a$ w9 @" e% _6 f  ]
/ n8 F% v8 n% a: G& v5 b8 w# n+ Jvoid        APU::Sync()9 \* {4 c' d( @- _' @
{5 Q' l0 n5 ]7 C/ d" L$ _
}
! A* Y6 }8 m5 z7 {
  q* R8 i# z; ovoid        APU::SyncDPCM( INT cycles )
% }  U& b# }6 L- c{
9 M0 g$ x/ W# E" u6 O        internal.Sync( cycles );
5 K$ f, J& @% }" n9 Q+ S, v6 l) _+ h# b
        if( exsound_select & 0x04 ) {
* E+ O7 M( V( k                fds.Sync( cycles );
" B: w0 |9 G- U3 s2 E3 _        }$ d4 [8 T3 {0 X" @, C" d4 |* m
        if( exsound_select & 0x08 ) {
5 O0 i3 ~4 y+ k; g( g                mmc5.Sync( cycles );9 p' ]0 B6 ^3 H! Z! Z5 t4 G& a
        }
& ]3 z2 W; ~& a) W: c! e: B1 J& u}( }; @; Z2 a, }6 [# s& K9 Y

5 e4 s1 S* @7 l- u6 C. u8 H1 _8 Jvoid        APU::WriteProcess( WORD addr, BYTE data )
# N4 m3 |4 G* q9 K9 {' k8 b- O+ Z{
' f/ D1 n* i5 R4 D  F" q        // $4018偼VirtuaNES屌桳億乕僩! N3 v; J. y: O! [: Y) V3 P
        if( addr >= 0x4000 && addr <= 0x401F ) {
# }, n! _. O+ M  V8 m' b1 {" V                internal.Write( addr, data );
4 @  e6 Y* ~; @        }3 B+ O+ [6 v! x3 ]8 c: ~  J+ b
}
8 y: L5 M0 C; w4 s! L  O; s7 _( b- o
void        APU::WriteExProcess( WORD addr, BYTE data )
) ^+ ?2 r6 L- V! I{
  Z: `( |. @# @2 c' C        if( exsound_select & 0x01 ) {
$ p" F' ~9 Z5 L; V                vrc6.Write( addr, data );9 f, }3 d% X8 z
        }4 k' r) D5 D" a
        if( exsound_select & 0x02 ) {
' x8 W" v! V4 |1 u* i5 E4 `0 T                vrc7.Write( addr, data );+ ]0 b+ e( q' I
        }
/ H7 q9 Q6 S4 V5 f$ N% b. I! o        if( exsound_select & 0x04 ) {
# m  [1 d2 D; U' e; z' I                fds.Write( addr, data );" ^9 P, A, e1 X% P6 F4 T( Y
        }
( U1 a- u( y' V& |        if( exsound_select & 0x08 ) {
! ]5 D9 e- J2 J                mmc5.Write( addr, data );( O: T. f( C' y! X8 t: X; i* L' T
        }5 p$ ^' c0 E0 n9 f) d
        if( exsound_select & 0x10 ) {
  O) k$ Z9 X5 q7 x                if( addr == 0x0000 ) {
$ l7 w3 J* ~. w0 R                        BYTE        dummy = n106.Read( addr );: ~1 O  p3 L6 t7 {
                } else {" k5 p3 f& Z7 h  c0 f$ t5 [( x
                        n106.Write( addr, data );
( C0 h, b2 F- v. s' t9 C                }
1 A0 |- L# z6 o4 ^6 {        }
  ~  q$ B8 O- {3 b8 O+ g6 e        if( exsound_select & 0x20 ) {: }' h/ _% s' X8 T, W- Y3 g
                fme7.Write( addr, data );& M- a- {/ B, }$ w5 w
        }" W4 z! B% d: S- Q  b
}7 f7 P& x9 T1 j- {

/ }2 i5 C% [# M# z& H4 Z, Lvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
; S4 b% I; [8 p  p) _( d{
6 w+ X+ `2 z! \8 i/ B! dINT        nBits = Config.sound.nBits;
6 ]7 ~% f4 n+ e, [DWORD        dwLength = dwSize / (nBits/8);7 V. E8 c5 J5 B4 w( d8 ]! E
INT        output;4 w7 f( r( o' \+ z
QUEUEDATA q;* ~0 J! \5 G) d8 g& a
DWORD        writetime;
& E1 |4 C% m9 [' |
  U: J& H0 {1 N. O. yLPSHORT        pSoundBuf = m_SoundBuffer;$ ~! i& {" l. ]  S" _" g
INT        nCcount = 0;
- M! x0 N2 W6 r  m* V4 k
1 b( A& u1 J' f" {1 W. rINT        nFilterType = Config.sound.nFilterType;
/ N( k" l2 G( g4 u* a! r6 G. K* j1 V7 [8 D! ]
        if( !Config.sound.bEnable ) {
0 u% l" ^" x  e0 s: T( B                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
& T/ z: M( ]" ]2 o; r" S                return;
7 R1 E5 _0 X# Z6 n6 u        }
7 z, x/ k9 i# N+ o4 w
; _7 k* M  c3 t! k. Z3 ^6 t1 G8 E        // Volume setup/ U$ z' u6 {+ o$ c0 V. |) ~
        //  0:Master
7 v) b8 U7 K: |& B( j& c        //  1:Rectangle 1+ s$ H7 E% p/ D. ]
        //  2:Rectangle 20 F. B: G2 r1 j% I" U: Q
        //  3:Triangle
  I5 ?$ x" z; ^0 N, @        //  4:Noise
" Z; j1 ^) Z! o        //  5:DPCM. L3 N3 P2 \/ J3 K/ g) C
        //  6:VRC6
" J% Y1 h- {& ], n# I+ K3 M        //  7:VRC7
. @, e8 i2 I) Z        //  8:FDS* _* m' p% S3 \: L, b6 O& t* U
        //  9:MMC5: f8 l3 b0 b2 }. d$ h  ~9 Z
        // 10:N1066 }& X6 _- e1 G  Z
        // 11:FME7
& D0 l# X+ R* q% m% H: e        INT        vol[24];
6 \2 g. T# _4 B+ Z        BOOL*        bMute = m_bMute;
, }" Y) _8 n8 q4 k: f        SHORT*        nVolume = Config.sound.nVolume;5 |1 {; u3 W9 I
/ w1 A$ f1 m4 E
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
0 j: E% [3 w+ e/ B! l. a( @" Z" f) s, w5 d9 h/ M+ X
        // Internal& C# G; m) U) ?
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;4 [% k% j4 y; [$ B9 e1 s3 }5 M- q% }) ]3 x
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;- M9 c  J: N8 E! Z7 s  v6 G
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;4 }- i' H0 s' Y2 [9 c# H' B9 l
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;' t* w+ ?3 @' T) i: l2 C
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;7 l4 V0 D& i" {  x. k
/ @; b: T! D& S  Y! x0 N
        // VRC6
$ E# C# D' W2 j+ P" S        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;) z: |% b( v, k1 ^) q3 e
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
8 A4 v0 |% U) V- J4 }, A        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
6 m1 [; p- M% g; k- d9 w
7 M6 u/ y* L; Y  v        // VRC7- m5 I: a: a  j# g; z' ~3 c
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
4 z* R4 s+ K; h: W  u# t' B& ?& c
" C; s/ N- X- U% s( \        // FDS
3 R* l" \! k1 y9 V: O2 }        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
/ R; x# s# n  u) X9 |7 H( P, B: Q1 M
        // MMC5
5 x- U$ B/ S6 `3 u: [: K- z        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
/ z! C1 f( H6 n8 \" B' H        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;, I" {; _) N# f2 j' b9 T
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;$ s" H/ n% u" X( p% z
8 r; c/ m" C. s6 j. }$ M
        // N1063 L$ P2 ]# ]  C) x/ W  `4 ~' a
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
3 l. _+ I7 i# {1 |  L        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" J) W& a& D! b( r2 ^/ _& w( ^3 S        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
/ j! ?1 [- y! u5 E% T8 _        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; |1 V2 v, A5 L# |' G/ A8 c& |
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
* W) B) T* b9 p# ~7 o        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- Q3 \7 j8 ?* A- b/ z        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
3 n1 n4 p- `5 R3 ]        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
  b* ?( c+ i1 j* k- X/ {# M9 \* ?* C& e7 c8 o. Y& |4 s8 d" P
        // FME7
* Q& A; b' k5 V) S( B        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;  y& V9 n, d) r, @
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
% p& g! f' S* [6 m( m9 h7 ?) T        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;% O: n. `% b5 S
# Z$ x2 }! X$ g0 b0 X6 J! }6 D# s
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;+ ]; d. W4 Z  O
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
- u1 y5 {. c/ B' K9 Q0 G0 F- k, p* A$ e
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
7 ?9 D2 U' y5 \! K        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
. M6 p. f& D* s& V5 H6 r0 o                QueueFlush();
8 }5 O2 N4 k6 _) @: [2 q* o! ~( y        }
% }: [1 y# c% J  w( G1 d# k1 U3 m( ?4 Z  U6 F
        while( dwLength-- ) {
5 o7 f- ~1 D" }' F) R9 t                writetime = (DWORD)elapsed_time;. @0 ^) q  c' C  q

! f( o$ R3 z# L- x- s$ ?! j6 J" r                while( GetQueue( writetime, q ) ) {
$ p# m5 {# ^) o: ?/ M$ k) y7 ^! B                        WriteProcess( q.addr, q.data );8 w# l  Y" u; c! C
                }
$ W1 p3 k: `1 K1 r! t( B( `, V& S5 a0 ?  [2 X! ^
                while( GetExQueue( writetime, q ) ) {! z) T# @' R, }' a+ G5 j
                        WriteExProcess( q.addr, q.data );
7 t* v2 y* \3 g# h" I                }3 J- s" z4 p* i; B

1 n' \/ Z( S3 l* x, o0 D1 p+ S  F                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
+ j6 g% c, z( q& Y, o1 x* C' p                output = 0;9 R4 _4 C/ c2 J+ w" e# o
                output += internal.Process( 0 )*vol[0];
; v# {6 g* U5 b7 l                output += internal.Process( 1 )*vol[1];
" z# _" w: N7 L5 a" @                output += internal.Process( 2 )*vol[2];3 [! t9 n, n3 ]7 P
                output += internal.Process( 3 )*vol[3];
! Z2 J% G. `4 _. W8 f                output += internal.Process( 4 )*vol[4];
7 ?4 y2 j# C. \5 h; ^; ]3 ^) d; i! N: F  H  H3 k* M
                if( exsound_select & 0x01 ) {
; m* m. v1 I8 ~9 b8 `' E6 U; v                        output += vrc6.Process( 0 )*vol[5];  S  s% @0 O, L( j6 i/ i1 A
                        output += vrc6.Process( 1 )*vol[6];
$ {( f" f% T  S                        output += vrc6.Process( 2 )*vol[7];) {$ l, N! e2 S9 U* i) _9 z
                }) M7 k  F9 d% c, S2 h' m+ T
                if( exsound_select & 0x02 ) {
; |4 _2 J2 q4 Z. ]6 w9 @1 V0 a                        output += vrc7.Process( 0 )*vol[8];
7 j. \, F4 z# V; W  ]                }; p$ ^& e2 p2 x
                if( exsound_select & 0x04 ) {
6 W# V; @$ Y+ [: N$ p                        output += fds.Process( 0 )*vol[9];! `# }- @$ B7 w4 L. O; R  Z  k- F
                }
) q! l  C7 [3 M% U9 t8 p6 j( q                if( exsound_select & 0x08 ) {
: a- a7 ]/ X  ~( _& C2 ?                        output += mmc5.Process( 0 )*vol[10];
4 ?. B) O$ ~/ d+ x  J! Z                        output += mmc5.Process( 1 )*vol[11];  n. t# `. f+ I5 U  C4 p
                        output += mmc5.Process( 2 )*vol[12];: M, A# B$ k1 j! m) ~7 B
                }
/ X2 G0 D* \1 |7 ~                if( exsound_select & 0x10 ) {2 i0 C" f& H9 A5 _- C. c( z
                        output += n106.Process( 0 )*vol[13];6 ]" O4 M0 t4 U0 A. Z8 y
                        output += n106.Process( 1 )*vol[14];9 S9 I& \  k6 q. a( B
                        output += n106.Process( 2 )*vol[15];* d6 J( c$ @+ G2 R
                        output += n106.Process( 3 )*vol[16];
2 l4 l9 E- S8 m. y& E+ [3 Z                        output += n106.Process( 4 )*vol[17];
+ n  ~7 H, j) H8 D( ]                        output += n106.Process( 5 )*vol[18];
# {5 O6 T1 p2 D2 Y. f) J2 W2 w8 b                        output += n106.Process( 6 )*vol[19];5 R6 [/ `( k& E: A' _# Y
                        output += n106.Process( 7 )*vol[20];9 b$ w" L$ v' q9 L/ N5 @
                }
1 O7 s: O$ X. l8 M                if( exsound_select & 0x20 ) {! V* E+ z+ B& I; k0 a
                        fme7.Process( 3 );        // Envelope & Noise
& }* K( H9 b5 x$ G9 _! X                        output += fme7.Process( 0 )*vol[21];
3 V: k: T% i+ u. L6 E6 C                        output += fme7.Process( 1 )*vol[22];! e+ m  ?5 Q) `
                        output += fme7.Process( 2 )*vol[23];
: O2 G; I! c* P  ?                }
; v5 [) ~' R+ ]% S8 q0 a! H( b. e# H8 Q9 e- T$ [! z7 v" k
                output >>= 8;
6 Q' j. @' y7 c) r3 P# l/ j6 J+ k% i' |2 E; e# v& d% U
                if( nFilterType == 1 ) {
8 [7 u9 J4 J5 L' t# _# l                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)! H2 M. r2 o7 i
                        output = (lowpass_filter[0]+output)/2;4 g% I! L5 {$ l: j4 L5 {& }
                        lowpass_filter[0] = output;
0 w0 _$ h: [0 v  I1 o3 B/ r                } else if( nFilterType == 2 ) {- ]7 k9 O+ R: C' a' u- ]
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)1 g0 d5 D6 W7 A& B; X$ {
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;1 ]. i7 \) s& P
                        lowpass_filter[1] = lowpass_filter[0];7 Y% \2 ~5 n" @, [
                        lowpass_filter[0] = output;9 h# L$ l8 t4 G  |$ }
                } else if( nFilterType == 3 ) {' N5 M: ?6 P8 e( A4 H% Q) z  ~
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
1 A) a; R' r" a( J# t                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;# f6 a. o5 n) y4 `! f" U
                        lowpass_filter[2] = lowpass_filter[1];
% @1 S/ F+ w$ }* X                        lowpass_filter[1] = lowpass_filter[0];
; I. H& M; v9 G# b; ^" {% t1 t                        lowpass_filter[0] = output;" k4 K* V$ A" i$ R( b8 L' k/ w
                } else if( nFilterType == 4 ) {' T1 z0 {! m9 w: x0 C0 M
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)$ V; v% f2 ]4 L6 d) F) z
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
7 [. e4 @; Y6 R6 t                        lowpass_filter[1] = lowpass_filter[0];7 H9 t: G) U8 {7 q: U
                        lowpass_filter[0] = output;4 y" R* F- L6 u0 a
                }
: r6 Q4 Q- E: S4 ?: {' f  ]% w
1 Q' k( D: S/ @* \#if        0& q/ {/ S7 q5 ]/ d3 b, u/ P! f5 y
                // DC惉暘偺僇僢僩
9 E/ i' i& [! R: Z) V5 R- R' s  m8 ?                {
# ]+ F0 B# H2 `                static double ave = 0.0, max=0.0, min=0.0;
! K6 u. W$ I' ]2 S                double delta;
( Q6 P+ l- `8 Q                delta = (max-min)/32768.0;
  j6 d0 D( b- J( q- G0 A                max -= delta;
5 u* a; J5 b& ^  @8 I0 v                min += delta;
' S) K/ N( |3 i! r) `                if( output > max ) max = output;' y* W' c( n4 O/ S, O( b
                if( output < min ) min = output;8 l& k1 C/ j/ g9 R3 i
                ave -= ave/1024.0;
: j. u* T$ h6 b* J/ j. X/ T; i                ave += (max+min)/2048.0;
# }$ p, t! c. A1 R                output -= (INT)ave;8 @: U; G- A* E% d7 L: T
                }
. b1 Z, K  r) a5 l2 O#endif
( o, u! y, @& H% a% i  X; g3 M#if        1
6 I. _# C$ j0 q: b                // DC惉暘偺僇僢僩(HPF TEST)* o# a7 V; K% _8 ?& f% |
                {" y3 V; ~0 c3 Y# {- }
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);' h2 r2 V' O# J
                static        double        cutofftemp = (2.0*3.141592653579*40.0);4 f% @7 _5 i+ s' h- b; U( K
                double        cutoff = cutofftemp/(double)Config.sound.nRate;. y2 P; P  a/ I  ?' Z
                static        double        tmp = 0.0;
! `# y: ~$ o& C& Y                double        in, out;. _8 a& r: W* l- f- _3 e3 o) u& J

' r% y9 r) C/ ^; N. G, N4 N                in = (double)output;
5 f1 B3 t5 c4 k9 p9 D9 z2 \                out = (in - tmp);
) Y/ ~9 l1 b2 y                tmp = tmp + cutoff * out;* Q5 X7 @" ], F/ _

# b: j; w4 A7 V' m/ Y6 R  Q, n3 Q% J/ G                output = (INT)out;  w/ K8 I" r. K2 \! W, o
                }: b' q4 E4 j2 p
#endif
2 u/ ^5 ~& I/ k" G& \8 e#if        0; m: i/ p. c- X' [: _
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
3 H! X8 t: C$ k+ \9 i                {
0 ^+ _3 v$ B' g7 r5 Y1 b                INT        diff = abs(output-last_data);
  b/ H5 B9 ^% [2 q                if( diff > 0x4000 ) {
# Q, z/ w/ g6 ~                        output /= 4;) u) f% {, b- a4 j
                } else
! e" S" F( _6 s# J                if( diff > 0x3000 ) {7 x% U  q& b: x. d4 L6 A6 y
                        output /= 3;
7 s' [% ?  K! I                } else
& W% l$ z$ Z  o2 `# D                if( diff > 0x2000 ) {; a; y( n% h4 ^& q* O' K+ d- _) a3 g% L
                        output /= 2;
& p5 h1 [" l1 y( g5 X" E                }# ?% H9 o% \7 R& e
                last_data = output;7 ]9 A  |  m2 `* C: [
                }' V) F5 m0 i) r4 s) U% P
#endif; W% \9 i& r/ J. _, ?
                // Limit
2 w5 s0 o+ W, d- c1 T3 ]  v% f                if( output > 0x7FFF ) {
$ R6 m7 D: e' C1 |+ u* E1 p                        output = 0x7FFF;" c+ ?' ?' Z+ G' v" G' q
                } else if( output < -0x8000 ) {6 y5 w1 M) Y& E' E/ A: D/ e5 L
                        output = -0x8000;
8 D" O: y6 ]8 V& D  {& X                }6 G8 K. _, y; L5 P  s
- z9 o. z6 _9 Z' e1 w' q
                if( nBits != 8 ) {& ~+ L" B: h2 @" c- e/ j4 a) f
                        *(SHORT*)lpBuffer = (SHORT)output;4 b. D) k. B5 t9 W& D9 C2 ?0 I
                        lpBuffer += sizeof(SHORT);
7 D$ f% L, h: d) H( n$ K: Z( {- }                } else {
$ [4 S( s4 E1 ?                        *lpBuffer++ = (output>>8)^0x80;2 s8 B+ ?, ~3 _, J4 q/ l$ d' p6 q# Q
                }5 l. o3 Q' Q$ B" k1 C9 R& d# ?
# I5 D8 ], R: }4 ^2 z
                if( nCcount < 0x0100 )/ I5 |9 j6 ]+ k
                        pSoundBuf[nCcount++] = (SHORT)output;# ~& w5 c9 B# Q
9 `. v  {+ [8 n- X
//                elapsedtime += cycle_rate;
6 y5 B7 G& u+ g2 [- K4 E; G% ~) T                elapsed_time += cycle_rate;. V9 r; L+ y2 U  v
        }. F9 o6 r5 ?1 u+ c4 ]  t
& B- k/ Q: \6 B
#if        1
9 C$ @9 ~' b3 L/ x5 Y3 A. @& _        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {: Q* A& h3 d# C, ^
                elapsed_time = nes->cpu->GetTotalCycles();
8 X8 P: ^- A5 A/ a1 P* Y        }
4 H; ^) G$ q( Y* d. Z        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {% ?, i1 I" {. y. Q9 U' D
                elapsed_time = nes->cpu->GetTotalCycles();
# S& J8 d( [' p/ X8 V9 X. L% E- p        }
& Y$ I8 r) V% p, |#else0 E- ]3 ]) _) f
        elapsed_time = nes->cpu->GetTotalCycles();4 o" n: I$ K4 [9 m
#endif
8 Y+ o* c" [  c  \8 i}
% O# Y/ }- Z& B& A8 F( P- T( y8 R8 C) d7 ?+ S- f2 J* U
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)& x& `6 h0 `! F+ Y. E+ X' ~
INT        APU::GetChannelFrequency( INT no )8 P; Y0 [/ m) [8 v7 D* t
{: C$ Q+ }! z! X* t5 r8 b
        if( !m_bMute[0] )* N& b- W! @4 R; R7 H
                return        0;
  ]5 m+ W( @( x8 @: o5 |
' x0 F8 j5 K8 ?$ P- ]2 K6 N: D        // Internal
! N6 U: \/ p( P+ V9 l        if( no < 5 ) {  Z4 z  x3 Z5 f
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
! i5 b4 b. U" k" X9 j        }
2 U9 l6 U0 ]. W  }; y! Q        // VRC6
9 @* ^& I  f) h6 s        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
: _" ~+ R1 R/ H3 u                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
, I- b6 x; H2 w6 E        }
# C, P+ o& w$ _8 C- ]3 U        // FDS  K9 y- U+ @0 d7 a7 a) T
        if( (exsound_select & 0x04) && no == 0x300 ) {! r/ H/ t- Y$ ?& E. f6 ]
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
4 z, A8 v1 |# t, H8 z5 x. l        }
6 a/ E; V3 I9 W8 O        // MMC5
- {' \, S/ I' Q. I# J        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {" T+ u* v) {, p0 V4 Y3 P
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
1 H' U3 l4 p$ e, ^: L( z        }
! O' m1 q, t3 P0 X1 R3 p* I3 r2 B        // N106+ }8 h  o, i1 R7 R' N3 K* W3 g
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
. h$ ^" r+ g" E" K! [. L                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;. B  P% M6 b: p9 U  T
        }! g* O7 z8 d# N/ V: C/ f
        // FME7
  S2 a% Q8 M; J8 G        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {9 v. p5 ~, k+ b/ @- |! w, y: z  `) Y
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;7 m4 a3 J7 |- e0 u+ A# _& B5 V- w5 G
        }
4 C  O; {  z' B8 b: M        // VRC70 d% T5 T6 U' N
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {# o$ a; j: Y4 `3 q/ ^, m
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
0 F! m  _7 t/ ~6 a        }
6 ^* ~7 d) d& {& W/ d" g        return        0;
3 U9 n: R& Q& g}9 l2 d) d* e) e  h9 @5 ]

& l- s" I9 d! D$ o% u8 X// State Save/Load5 _) }- U) `; A0 v
void        APU::SaveState( LPBYTE p ). X% I2 V. K& r2 ~0 I6 T/ J: M; t+ ]
{) b8 g5 V. T8 I) u
#ifdef        _DEBUG
; r; D4 }) ?2 h& t* N- r; w  c; mLPBYTE        pold = p;3 K4 i3 t1 P0 ~9 U. g, S+ Q6 g2 K" s
#endif# o/ B- ^6 j. ]1 i

7 k3 N2 ]7 y0 e& j- r4 X        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
! K- H0 w7 F+ X        QueueFlush();9 Y9 Y. O" ]4 F/ i7 R/ H
4 c( s' g1 [/ A+ M( z
        internal.SaveState( p );
) B6 x- ~( E, r7 r3 t        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding4 f6 n% F3 X8 P6 f4 q

2 C2 n4 t) u0 z. @( q+ L4 r        // VRC6# E/ C) ~  h, `+ `0 E. r0 z0 ?, |
        if( exsound_select & 0x01 ) {
, i2 E7 a4 c4 g$ E- }0 A                vrc6.SaveState( p );
7 W& E4 T$ C+ B& f; g                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding$ _7 u& A8 \! T
        }* N- h" F1 u- J& g+ n* |2 t! @
        // VRC7 (not support)( q; }" @0 a5 |' S( M
        if( exsound_select & 0x02 ) {
9 ^( h* r+ l; N9 z3 E                vrc7.SaveState( p );
- i- m5 r7 E5 W3 @) a                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
- X' R9 u9 O* N! [% L& F        }& O3 }! e, K( I- l
        // FDS
' @, v+ `$ P* @- }        if( exsound_select & 0x04 ) {% Z' R  p# N, z1 M& @) B
                fds.SaveState( p );3 w6 x4 q% V% t, _3 `, L+ n
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding/ A* n; y5 b, |" J: ?, M. t, O
        }
5 W  A4 o  W+ w- |& `( n! o3 T        // MMC5% e9 @# _$ X: d5 l
        if( exsound_select & 0x08 ) {; Y- R" W. ~: J, U' B
                mmc5.SaveState( p );
$ r: t  g8 M/ L# E6 y$ Z# A                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
" a+ I) A8 J  R' \: J# R        }  J: n  {" @4 v" @
        // N106
) ^# \8 r( d0 [; O' g2 I        if( exsound_select & 0x10 ) {+ `3 ~$ x- @$ Z( c5 O) U4 `
                n106.SaveState( p );
' D* Z1 R5 k+ ]( v) G3 O                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
% v% ?  x; b- |' {" e( C        }" b* E4 P; u, F* @; v
        // FME7
2 |/ i) U! j- q; O+ s        if( exsound_select & 0x20 ) {  o! N0 c  I' e3 o, x
                fme7.SaveState( p );
) P% d' W- `* g& ~: }                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding; u1 Z, ]' ^( R" p9 P8 J" f2 K
        }
. y& F0 I. G1 k) G% e) S8 i$ d" {) b* P7 U) ~9 M  s
#ifdef        _DEBUG
; t7 v% @  R1 `$ v: aDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
# |$ J4 ?6 d% ^$ K: w" t0 F& ~5 k* h#endif# q9 I5 h; K9 C* Q0 J: c' E
}! s% `7 ]: ~+ @3 t  U

1 A8 X+ s9 _  @7 @# D$ j* z3 e' s0 ]void        APU::LoadState( LPBYTE p )
1 a" K& A9 P3 W  V$ [" R, n1 o+ c' R{
' L" v- h6 }- M2 j        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
5 }& z" q5 Z) T) k5 u        QueueClear();
- D! ]3 w' Q% i3 U
$ r' n& L. V* A: `- V- M        internal.LoadState( p );/ [" q( p7 ]. \& d4 \5 Y  X
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding5 j5 }/ w1 g  j
: ]2 s; j3 k9 q! v" p% ?! {
        // VRC65 R) {+ E* \) Y: Y& c; O- c( Z
        if( exsound_select & 0x01 ) {
: W8 I, R% \9 i                vrc6.LoadState( p );% u4 h3 }0 K" u1 L
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
1 b$ J4 f" O* k$ |        }
$ M5 f2 @: t% A5 `/ C5 S        // VRC7 (not support)2 [) B# M/ s8 m5 s
        if( exsound_select & 0x02 ) {
% k. h! H) Q* J1 e$ [" q9 I, C0 @% p5 R                vrc7.LoadState( p );* H  k2 l2 }+ Y. G4 k
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
: t- {' g3 X( @        }
! {1 `/ V6 t; ?        // FDS
; |: u7 e* J+ H0 L/ R4 V6 T% E        if( exsound_select & 0x04 ) {
3 X/ ^3 j9 h, U8 G9 G" p                fds.LoadState( p );
/ k, q- y: z/ a) ]7 X; n7 P                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding$ F& x0 y8 O. h2 X
        }
, I9 U0 C: l+ a1 X, I( G1 o        // MMC5% V) n$ T. H7 X& @  ~* d
        if( exsound_select & 0x08 ) {
* I7 M+ Z6 ^5 D+ k1 O8 W4 F; N                mmc5.LoadState( p );8 R. K( e( y8 Z8 e2 E: p
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
( l% g! n+ \" _3 u3 ^) |- d5 T7 R; l        }4 \  K2 a4 [, P9 n! H% y
        // N1066 _1 S. Y5 A" t( s
        if( exsound_select & 0x10 ) {. f/ V3 }' f% V# P6 n9 b4 C
                n106.LoadState( p );
2 z' R5 @2 R* B6 {8 G1 C                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding) y/ c3 w$ n, h' ?0 I- j
        }
5 O0 x9 h+ q4 L) w( T        // FME7
2 ]0 J( Y) A/ N( ^: Z        if( exsound_select & 0x20 ) {- U, B6 Q& r7 a
                fme7.LoadState( p );
7 q5 Q6 N2 p9 a7 b# Z) n2 c                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
  E+ }8 ?+ F5 U  v4 O' j( S        }
4 D; p  l! p3 x}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
% t. k+ q) R# L, i, R3 O5 X( ?可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
! l. a0 U" [. ?! M. v感激不尽~~

0 q) B: _2 t" v) e* L恩 我對模擬器不是很有研究,
' l0 j& u6 A" d+ u雖然要了解源碼內容,可能不是很困難,0 Z0 K. W9 u1 t7 k
不過還是要花時間,個人目前蠻忙碌的。: E4 r3 K; e, a1 n0 n* s9 y
& C5 T0 _, O2 Z- M( r2 U% x4 Q* t0 m
給你一個朋友的MSN,你可以跟他討論看看,8 s4 O& D' g; Z9 H  u7 _8 k4 |2 g
他本身是程式設計師,也對FC模擬器很有興趣。
, q% B, l# K5 k& C. t9 ?; f& T
' ~( @' f; R( N9 G- [MSN我就PM到你的信箱了。
  [# \, h7 t1 J* V8 s' |+ N! h* F0 I  B+ M9 |. U, h: C* t
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 1 v9 [) t, K6 l' R2 h# _: g
呵…… 谢过团长大人~~
) p, a, s2 d2 y7 V, a% X
3 T  J2 T+ X1 P; w( j
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
& n3 Z: }8 r# E, T团长的朋友都是神,那团长就是神的boss。
- j# q( z' P0 ?8 j; `* J4 A
哈 不敢當,我只是個平凡人,
7 W! h! F# u9 E: V+ |- c6 O要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙% v) Q1 s( K( S3 E
ZYH5 e( _4 ^1 k* r4 e* d& O9 u( a
QQ:414734306
" {8 o! M; p4 M: S) m6 YMail:zyh-01@126.com' `; O& L2 V/ [, ?1 K" T+ c

) g6 O2 ~1 c4 d9 E  U. C. `" Y& u他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
2 U2 H: h* t! y再次对团长大人和悠悠哥的无私帮助表示感谢~~
' I6 {! X. O& k5 {* \
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-2-4 08:48 , Processed in 1.095703 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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