EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。6 `& x7 J4 K4 k
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~6 s( v: x' F8 `$ b! y% y! L7 m: l
这里有相应的模拟器源码,就当送给大侠了~~
9 R' A) E8 Y2 I) S$ Nhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 ; D& a/ D6 h& f! n1 A. F4 `
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。* g; E9 y! T3 U4 K
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
9 |& L2 R# k( x  N8 M: s这里有相应的模拟器源码,就当送给大侠 ...

8 u* G8 F( T+ B+ \9 P5 S聲音部分(Audoi Process Unit = APU):5 W  x" Z( t, r' A+ e  u9 Q
.\NES\APU.cpp) ?) p5 k9 }  v
.\NES\APU.h
( e& |/ l- g3 U* p- G$ I  Z5 X
, I; Q- s- ]+ V$ g/ z0 {6 y8 m) W/ v
影像處理部份(Picture Processing Unit = PPU):; ~" [: T; E# s/ R3 h7 k
.\NES\PPU.cpp8 u. h* G6 q- X- E
.\NES\PPU.h
8 d: o+ K5 C6 \) M7 c
- B/ ~* i1 p% z# c, u7 g如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
6 @0 D1 O+ K& S/ }: X& N8 G+ r2 L感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
9 }% ?+ a1 l0 n5 d/ I(由于很多专用术语和算法机理都不明白,所以看不大懂……)0 d! {3 G7 ^" K0 O/ A" t1 e
//////////////////////////////////////////////////////////////////////////
0 T/ K6 |# s8 ^2 j//                                                                      //9 i& o& A/ D; G0 x
//      NES APU core                                                    //4 e1 J) m" W- @) z3 f5 t+ m! u/ {" i' d
//                                                           Norix      //
6 ?% s% n; U; O0 z0 d3 o//                                               written     2002/06/27 //$ m8 F- B' Y& t1 w/ k+ l5 k
//                                               last modify ----/--/-- //
; x/ w( |. _0 N* t+ A6 n/////////////////////////////////////////////////////////////////////////// b. A; w( l' u  W
#include "DebugOut.h") ^% w2 }; p% S$ I) j, x; m* \
#include "App.h"" F! o- a/ X) J  x
#include "Config.h"
; |* a; ^3 ]  |) {+ {1 B7 Q
: c0 f) w3 [- W" Y4 Q#include "nes.h"5 @  a6 A* g1 b9 Z# R$ G
#include "mmu.h", Z2 G. N2 U0 d0 O% \
#include "cpu.h"3 E- y8 A* Q5 C) H
#include "ppu.h"% ^/ Z# Q: D/ ~6 t
#include "rom.h"
8 s  h2 @! G6 k( z6 b#include "apu.h"
8 c3 P# B1 s- Q8 \# ~4 B: X& W* V5 |. _7 L* v6 v( \
// Volume adjust
4 L2 [$ [5 `/ m/ U' Y// Internal sounds
% G: M' y$ v( a; L; m3 y4 a#define        RECTANGLE_VOL        (0x0F0)' e+ S% m; ?* w( V7 [8 @
#define        TRIANGLE_VOL        (0x130)' [' k( X6 T6 C& O) K5 _" K6 {% I
#define        NOISE_VOL        (0x0C0)
& ~' i- b6 M/ j( b. r, O$ q#define        DPCM_VOL        (0x0F0)
) T+ L2 Z" c+ D$ x// Extra sounds
: \+ \+ M" e4 g( j0 {4 _# e* L  T#define        VRC6_VOL        (0x0F0)% Y1 t# g7 X7 `
#define        VRC7_VOL        (0x130)
" ]; ^9 d: U  M0 E4 {#define        FDS_VOL                (0x0F0)+ r0 U% r6 ]& y6 B4 E- J6 m
#define        MMC5_VOL        (0x0F0)7 F# j" v- Q& g  K: J
#define        N106_VOL        (0x088)
+ |/ L/ j& q% ]( K0 A( l#define        FME7_VOL        (0x130)
' U3 J- v% Y/ g5 ~. f9 M4 r7 P* Y# w+ Y5 I( z
APU::APU( NES* parent )
1 I% u- A3 Y* l0 M. g{
) H" d; K! z. m        exsound_select = 0;/ z; w- ?5 @5 H# y+ y6 k6 z2 W
, ^+ }- F$ l% g/ f5 R- O3 c: q. _
        nes = parent;
/ g+ o6 p: P0 _  I; p7 w        internal.SetParent( parent );
& y4 G) i# y1 H) A7 T+ R2 q3 I2 C1 Y/ Y6 C! u
        last_data = last_diff = 0;* a& i2 ]1 U% c% {" f
  H  @" [# `- Y! ?/ S* n# u/ K3 S
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );4 Q& h' \# D- ^
; G! t& S8 \$ ^6 H
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
% |( Q* u# w3 Q9 C5 [7 i        ZEROMEMORY( &queue, sizeof(queue) );
* ]$ D4 s9 r8 G- c% p/ N: k& N        ZEROMEMORY( &exqueue, sizeof(exqueue) );
: @# h  `; N- G3 j
7 D1 n$ Z% X! [        for( INT i = 0; i < 16; i++ ) {- N4 F4 k. L* [" I
                m_bMute = TRUE;
, w- s& B( j8 k        }
3 g1 N  V8 y0 x2 `9 `}* R7 E% y# _3 D& e  k1 l8 W
7 z4 w) E5 y' U, \' ^
APU::~APU()" A) W* p/ P4 o% t8 g; f1 |
{
; o- W0 F2 p, Z+ M}
; ?% M' u4 D# z5 q2 _
, m5 l; |% ?/ [3 s2 V) ]; X" Vvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )* r; |, X/ u3 _1 _! b
{
5 Z5 \* K5 l8 S, C5 _        queue.data[queue.wrptr].time = writetime;
8 h7 }" ]1 R+ m8 |) J& M        queue.data[queue.wrptr].addr = addr;
+ `  M# e% h( B9 x4 w' P9 c        queue.data[queue.wrptr].data = data;
. s2 q' m+ N! [9 Q' n5 i8 {% r        queue.wrptr++;
: {/ @- Q. {; W$ i# e+ ]        queue.wrptr&=QUEUE_LENGTH-1;
. I+ k2 d) p: ^$ b        if( queue.wrptr == queue.rdptr ) {
9 ]6 V5 T' Q- Y6 U. o$ M                DEBUGOUT( "queue overflow.\n" );
, `  \3 U) m2 l$ ?% d        }
% O+ T& }" E, ?- u( H}0 C  C, a/ f2 T$ v# R' _% x5 I$ V" \* F

2 ~& a$ C, E; y4 y$ ?BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
5 [; L$ @, G5 L# ]{6 |7 e; y- a2 s8 ?  i+ }
        if( queue.wrptr == queue.rdptr ) {! p% R: D: |, b! E# S2 x
                return        FALSE;' t3 {- a* d$ {/ @" Q1 `( g- _
        }
! s, `9 Z2 N$ F" K: ~8 s1 e+ k8 F        if( queue.data[queue.rdptr].time <= writetime ) {
# c2 n9 Y7 G' d4 h                ret = queue.data[queue.rdptr];
5 A; |8 w1 Y2 b, I  h" l' ^7 e                queue.rdptr++;. E+ @5 v- v( Z3 Z: v( s: C! l" K4 e
                queue.rdptr&=QUEUE_LENGTH-1;
# }) ~# r% Y. ~' d% H/ ]: F7 l' T                return        TRUE;4 F+ ]: t& G0 i: {
        }
$ s- N' u. r/ O) z9 D        return        FALSE;
3 v3 k( Q3 M8 ?, e* ~3 H4 T}
0 Q7 ^! l9 W  o! j$ z
) i) u# e  D+ i- }9 @1 y# hvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )5 f5 m+ O+ M/ L! [- m3 c! e
{
* ^1 c. z7 N* ?; a  z        exqueue.data[exqueue.wrptr].time = writetime;
- [( _) G2 L6 U        exqueue.data[exqueue.wrptr].addr = addr;
- `, v: t. ~: h9 N5 N2 o" c        exqueue.data[exqueue.wrptr].data = data;* p7 ^6 N& G$ ^. l7 r# e* @* @
        exqueue.wrptr++;% |" ^* ]! E, g- Z0 H1 Q* E7 |
        exqueue.wrptr&=QUEUE_LENGTH-1;
& S; b8 H" z+ p1 l/ l% e        if( exqueue.wrptr == exqueue.rdptr ) {2 h' v0 Y6 G" j& ]4 V' T5 G
                DEBUGOUT( "exqueue overflow.\n" );# }2 t6 e& V7 d
        }
) k" A8 b, V+ v0 t1 V# \! _}
  u# s3 u: {2 D& v  w8 t
7 {* r+ E- j' UBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
/ F) L: T! l+ w! A6 t{
7 o9 ~# o* t( b) s! O3 n        if( exqueue.wrptr == exqueue.rdptr ) {
' |/ {+ I' w5 k& a, I                return        FALSE;  m1 v- J. A4 Z  Q, x- x' {
        }
8 M! n  e" c, F  Q( @0 K& G        if( exqueue.data[exqueue.rdptr].time <= writetime ) {2 z: x' {0 F8 ~4 p8 A
                ret = exqueue.data[exqueue.rdptr];
% b9 q5 c7 F5 o: k( D% b                exqueue.rdptr++;
3 [4 k0 g' Z( w7 F8 L                exqueue.rdptr&=QUEUE_LENGTH-1;) c4 S1 Q, m% p8 o
                return        TRUE;' Z2 y9 m+ k  a; F/ @" ?4 Q
        }+ {. N5 r0 F. \
        return        FALSE;5 T( g& o- ?4 W* t, U
}- y) R1 y. s7 B; X3 t! G; C2 V" Z

) @' Q3 a* K2 e; mvoid        APU::QueueClear()8 p" B: U# h$ L% p0 g
{
$ Z7 ]( y( s1 V) M) T4 V/ L4 f        ZEROMEMORY( &queue, sizeof(queue) );) x+ K' I, d$ t3 o* E* H
        ZEROMEMORY( &exqueue, sizeof(exqueue) );& P; z, _5 Z! }" R: @
}! g) \+ I  b- u
( v9 n* N) B* {4 n6 q
void        APU::QueueFlush()7 F  o* v- F" t8 d
{
# t8 m0 O" ]6 ^        while( queue.wrptr != queue.rdptr ) {3 ?, P3 q+ Q" a2 _8 S  m! Z
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
( y0 s0 H/ `# q3 P$ S                queue.rdptr++;
: a% F+ ^  I3 R4 L6 M* {6 S                queue.rdptr&=QUEUE_LENGTH-1;1 Q# Z( n% Q& E4 L
        }
6 k  V' Y$ @- \  I* U
8 c, A, X  p! u+ y        while( exqueue.wrptr != exqueue.rdptr ) {
4 F1 i& X* n' \7 H5 b                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
1 m# U- [8 Z& k' R3 U                exqueue.rdptr++;6 p4 q8 d7 H3 c4 e' n" y1 |, D
                exqueue.rdptr&=QUEUE_LENGTH-1;% [( m% k; l  M. n
        }
* o4 ]+ j9 i: d1 H9 A}
/ K/ G0 V; d% T2 b7 b0 V- ]2 U1 ]) `3 J: g% e
void        APU::SoundSetup()% V, P- }  V( J( s
{
" g$ L0 P( p& a) k        FLOAT        fClock = nes->nescfg->CpuClock;
3 r$ O& j2 q8 ?" K) {, Z        INT        nRate = (INT)Config.sound.nRate;
$ H" p, a. K) O# \3 J. S& J% M        internal.Setup( fClock, nRate );! x$ a! Y2 c! A* u7 p: G8 E  Q
        vrc6.Setup( fClock, nRate );0 H6 [# c, ?2 [: X
        vrc7.Setup( fClock, nRate );/ s; b' ^* a; C8 [) I
        mmc5.Setup( fClock, nRate );- R* L5 P( o4 a& B
        fds.Setup ( fClock, nRate );
: e5 @) q( O5 K7 Y8 y        n106.Setup( fClock, nRate );
  b7 a; }9 N5 L. h, U/ ~        fme7.Setup( fClock, nRate );
/ S; K- c1 b& j( X}
* [: k) G4 A* ?% {% M( z% X- a1 P1 q. P5 e$ Z. G
void        APU::Reset()
( T" b0 ~# i; K{6 B9 e2 j" P# a! C
        ZEROMEMORY( &queue, sizeof(queue) );* a0 ?! U& U) n1 a7 g& V4 d
        ZEROMEMORY( &exqueue, sizeof(exqueue) );9 `  P* h' F2 U$ X$ k
! z+ p. h; c; q# I8 g2 ~! S
        elapsed_time = 0;
- L: {5 `: P, y0 E! A/ p/ j6 A& X
+ G  C% j  o% X- I; m2 ?  y' E        FLOAT        fClock = nes->nescfg->CpuClock;
5 H. j4 b& l9 h9 E0 t: W        INT        nRate = (INT)Config.sound.nRate;
( l/ i$ Q2 k/ t: v        internal.Reset( fClock, nRate );
, y2 w/ y! z& l" V        vrc6.Reset( fClock, nRate );
- e; ~. U; A! R2 Q7 k* I1 h( P8 v        vrc7.Reset( fClock, nRate );: S' x& s- w3 U
        mmc5.Reset( fClock, nRate );
# {5 x. @1 f0 Q$ _' M7 d        fds.Reset ( fClock, nRate );6 h3 U+ T* I& N7 ^( N! m
        n106.Reset( fClock, nRate );
2 v% k  R  N2 f7 T1 n: M        fme7.Reset( fClock, nRate );
4 P) X; e5 w# @4 s7 t
2 |7 Y! R9 g6 U        SoundSetup();
( g$ v3 m; ?2 D) Z& Z& t+ F$ _, N8 s}# |8 Q& T. u7 l
# e- Y% `2 b" e. Z* [1 X+ A' R
void        APU::SelectExSound( BYTE data ); Y, D4 @9 \  `0 \* d  z3 j6 T; m
{8 j; i  v8 C0 i8 ]' s' R5 R- r
        exsound_select = data;: Q& v& F: m% `2 t/ K
}
6 _& l4 u, Q6 D, E1 D2 x
' p3 G6 r8 Y  o& K7 G$ a  XBYTE        APU::Read( WORD addr )7 g0 _. h( j$ s
{8 v9 x" C7 O  {' C- @3 p; m1 l0 X
        return        internal.SyncRead( addr );
  |+ n3 `" b1 W3 G}5 I! X& A# C+ g6 n# H3 @
& ]; H6 T% V7 G6 d$ F6 x
void        APU::Write( WORD addr, BYTE data )
: r- t: p$ K1 \8 S( c{/ r( k  x% {* `
        // $4018偼VirtuaNES屌桳億乕僩
* H! P  O. m7 f" f! h4 ^9 s        if( addr >= 0x4000 && addr <= 0x401F ) {
- z8 N) I2 v# k" U                internal.SyncWrite( addr, data );
! C' ^: N! ~1 f1 S0 \  D. P7 W$ M                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
# |  p+ L' {4 I" p        }! h5 V9 {8 i( u# d* s/ Z
}: [$ ^4 l* }# n$ Z

# H; G' }* H+ m; a# {' L! eBYTE        APU::ExRead( WORD addr )
. \* ^" c% A* Q7 @& y6 Z{
* K$ R; S* _3 m1 g  D, cBYTE        data = 0;' H6 W# Z  B; Y3 \; \( b* `
* c, w4 m/ d1 z; d
        if( exsound_select & 0x10 ) {
5 ~3 J1 H) R1 U7 n  O0 W- y  g7 n                if( addr == 0x4800 ) {
0 Q; M8 e1 N) L% ^                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );2 q  T& W/ t$ [" `, i
                }
1 b8 b9 a8 ]4 I3 K/ |        }
% _: D2 d8 t% l& W: b2 u        if( exsound_select & 0x04 ) {8 B+ L7 f: j9 m
                if( addr >= 0x4040 && addr < 0x4100 ) {, O/ ^" w* [; v, D% v  @3 B$ W! E. x
                        data = fds.SyncRead( addr );
( V! J$ p/ ]9 j6 d( M                }4 ]. ^+ P8 _: n- @
        }
! U% G, \7 {" |  f        if( exsound_select & 0x08 ) {
8 ^! Z2 ~( G) }, C+ a                if( addr >= 0x5000 && addr <= 0x5015 ) {
  _' @- ?6 s/ J$ `) \                        data = mmc5.SyncRead( addr );
; z; h: k, a! Y( h7 \                }
' |& c5 U( F9 }2 K2 S        }$ s! ]! L6 I3 r0 ?- R1 @9 A
$ y; Y) C' o6 |4 h
        return        data;
  J* _% X! ?% @}
, n/ m6 N' Y) q  J  {9 J4 r( D: n# p4 w& {5 P9 P- @* f
void        APU::ExWrite( WORD addr, BYTE data )* u. o- v! T8 J/ O* g
{3 L( P+ W$ V- X2 W  ?# a
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );1 [2 z; a+ I7 ^8 y! T1 T5 X! ^4 I  {

/ U% E/ L) P7 o& v+ |        if( exsound_select & 0x04 ) {1 a* B* |( G1 z+ o* V1 K0 L6 r
                if( addr >= 0x4040 && addr < 0x4100 ) {$ Q! l6 Z( u3 h$ Y3 D
                        fds.SyncWrite( addr, data );
8 p7 Z/ X8 X; }% Y$ a+ p1 L                }; f9 N* J2 O& r. k
        }
7 b2 v+ F% I1 T  i0 P( p# M- K1 @1 R8 J4 {1 j6 ?7 ?* [2 E# _
        if( exsound_select & 0x08 ) {/ c0 D7 v2 S, ^& o' i' v. E
                if( addr >= 0x5000 && addr <= 0x5015 ) {
  W+ `6 p: C+ e2 r8 e0 D# T1 N# U                        mmc5.SyncWrite( addr, data );% o' J1 u  U1 H
                }" J5 {7 E3 ~: x8 V' I" H$ s
        }
. q! p1 F4 \2 {# A8 L( f0 F}" T; W" E3 g0 X* ~& L& ~* X7 @4 Y
6 d* U* ?* n+ m' c. j1 F+ \* U7 z5 ?
void        APU::Sync()9 ]9 w) c) M, H
{) B, Q! b9 ^! P3 `- D
}
- n$ A+ y, A+ B3 G. [! E
  d. C+ C; X! h! L( \void        APU::SyncDPCM( INT cycles )
8 I# m7 e% I& P0 D. m# q5 n{
) Q; _0 i* h* E7 b- K; _! Q        internal.Sync( cycles );- O$ e) }( h$ @- I0 Q
  H( @' \9 t# M4 X! w
        if( exsound_select & 0x04 ) {
# @- p# S; `/ l                fds.Sync( cycles );
! J# }9 T8 ]1 n* B% |( `9 t* V        }4 c& T2 V, Z# a% Q3 e2 `
        if( exsound_select & 0x08 ) {
! y) O/ U# F# o0 e0 [7 T! C                mmc5.Sync( cycles );
5 E& Q' |9 j# f7 C# Y4 T' N        }
* h" h3 ?. e# Z8 b+ r: N}
; h8 }  w% @6 K5 ?! g' E& i2 }' y: s0 S2 r
void        APU::WriteProcess( WORD addr, BYTE data )
2 Y) M0 X5 Z) K) u{
9 o0 }$ P, t' H8 K2 X        // $4018偼VirtuaNES屌桳億乕僩+ W2 ]0 s0 G  K+ g/ U# G
        if( addr >= 0x4000 && addr <= 0x401F ) {
4 X+ b1 Z! X. k0 e# s                internal.Write( addr, data );
1 X+ n5 H( ^& T2 J; y. G0 j. B) I# O        }7 F1 \7 f* W( |, z4 R; b& u
}
8 @$ y6 L8 L; b2 {1 n% j: u( g/ V+ s9 \# c3 ~- I) ^6 k# f
void        APU::WriteExProcess( WORD addr, BYTE data )* [9 \- v$ I8 I
{
" l6 o0 o5 i$ L7 q6 y  O) K  s& w, x, Z        if( exsound_select & 0x01 ) {, K3 O( s9 S( b. d0 [  d/ |; h
                vrc6.Write( addr, data );" A5 C8 z  M5 [: w$ v; B; [
        }
+ d1 `8 p+ }) q        if( exsound_select & 0x02 ) {# e- \2 l/ S. M. Y2 P6 y
                vrc7.Write( addr, data );
  c( I# w4 k* g! F        }
6 {7 n! N! F8 L+ S1 ^/ I        if( exsound_select & 0x04 ) {
+ k! L) ?9 ]: C( P" s* s                fds.Write( addr, data );
: }/ z" M. K2 P# u        }# \% ?5 V" V6 [+ ]" e
        if( exsound_select & 0x08 ) {
4 f  H6 @8 m, Q3 b, H) c                mmc5.Write( addr, data );4 h0 ~; W' m+ G: [( R
        }
: G+ K0 K% {0 Q! z# {0 \, B        if( exsound_select & 0x10 ) {
2 j7 ^/ I0 y4 z6 [2 _8 ?                if( addr == 0x0000 ) {8 {( @8 W; ~% i4 [
                        BYTE        dummy = n106.Read( addr );& T! c  f3 t, v$ R
                } else {0 W0 O* j1 x1 K1 [. d4 A
                        n106.Write( addr, data );" H9 P; a& O' u
                }
* z- J2 u7 m( |9 E        }! ?* n/ Y/ e0 B4 s. t
        if( exsound_select & 0x20 ) {* U$ ^, }- Q2 L3 @4 m2 P( p
                fme7.Write( addr, data );
: D) B% X! |4 M        }
5 ]! {3 u4 g/ w/ F" m}
; b+ i, ?- I2 h* `- O5 i5 H" g; q; A% \# D) X' y4 {- {% M
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
3 [# o& i" ~4 E4 T$ l{6 {) B4 t( V& {
INT        nBits = Config.sound.nBits;8 A! |' C9 z6 u) }- E- ?: c! @2 |
DWORD        dwLength = dwSize / (nBits/8);
0 Q& U8 o. \6 ?+ ]2 z1 wINT        output;
$ T5 `0 L+ x7 H( ^QUEUEDATA q;8 ^2 y% M# U  a" L+ n" `$ c
DWORD        writetime;1 [/ G- @, K! `+ |
; ]+ c8 ?) F1 r( U  Y
LPSHORT        pSoundBuf = m_SoundBuffer;
+ ]/ J3 @# I7 F' o6 q- o" C4 L2 o4 lINT        nCcount = 0;& J( V+ Z2 {6 ^! M

+ b, s; Z# V! ~- q  }1 g" _- \7 y  O3 UINT        nFilterType = Config.sound.nFilterType;" F$ W2 w  b, X3 f3 `8 W% c9 I

  A& N6 L! Z' E0 t: p        if( !Config.sound.bEnable ) {
4 ?# |& V) J. \2 \* M- J8 F                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
+ `2 F$ N9 i% }9 Y2 O) f9 c                return;
8 t& ~! ]0 T7 `. D        }
; _- T+ J, F7 m
& y% G" T7 {! I/ Y1 ]& q        // Volume setup0 D' G5 e/ \' u8 n: f
        //  0:Master
$ Z& x# s+ j, l* i; L4 V9 l        //  1:Rectangle 1: X$ s+ W: Y; t2 S; q/ a
        //  2:Rectangle 2
1 [7 [6 d6 n" Z( n7 `; `. z1 S        //  3:Triangle
; z* D, y& x) c: [        //  4:Noise8 ]1 s( ^7 J: A! U; o
        //  5:DPCM
* {" o! X! ^5 c5 p/ a' i3 }. t  W        //  6:VRC6
) @* n7 \/ s( z6 A2 ~: ]9 t        //  7:VRC76 }* y2 a+ w% S: f" h4 p
        //  8:FDS
6 z: x% Q, I1 {2 T9 E        //  9:MMC54 Y8 ]- `- O; n! v# t0 I
        // 10:N106
' v- e7 t2 }3 f: s. Y        // 11:FME76 g& L7 Z; N( n2 J
        INT        vol[24];
7 p) V. z! \  y+ ~# z5 l  g        BOOL*        bMute = m_bMute;( H% Q: i8 |# \/ ~5 x. R5 s+ X- w/ V
        SHORT*        nVolume = Config.sound.nVolume;
! P# x: x# K* }) n0 K5 _: Y# ?+ B) }% k1 `6 x4 Y: x& \2 Q
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
' E. `& {2 p9 b) P$ D" l. @+ o8 s8 e* _! f: L' ?( v9 T- |
        // Internal0 T4 \1 [  s9 O3 M8 K& \4 g
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;0 ^& r/ x9 q- g
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
: k7 [1 M6 o) g# u        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
  O" V, y; k% b/ l        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;$ A! m0 k4 \+ }$ T' ~2 P
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;% M; X" [/ b3 w; q( X

+ e8 \  f; [. R& H        // VRC6
' t1 l) g1 T& B% P- z) p7 ?        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;1 J3 T: j$ V" I& y* V
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;( H6 G7 _( J* Y, C5 O* m8 S1 g' |
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
  H/ |0 r  z) o7 u: Z
( x! H$ I9 B: r1 ]/ I  g3 k        // VRC7
, ^' c2 v4 W' x. V        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
, E, ?+ e: h% M; c+ t+ K! g9 s( n
7 r6 E1 x8 R% L# R1 Y6 u5 g        // FDS
+ |5 d3 F+ I0 H+ X3 `3 Y' u" m        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;- E0 c9 G- `$ G8 H% R
7 u0 o( K/ w: J7 C2 n
        // MMC5% T$ L1 _# C# f( p
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
6 d& o% Y6 \6 \4 }& {        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;% n3 {& h2 p8 y9 N
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
: u4 ]: Y9 S- H  _% l# ]4 f
) I, T/ g1 F& U. j8 O        // N106) m; i1 U1 N0 H- {8 F" c
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" C2 K- b$ f' z; S3 N        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;! \) |& `; r- N& r& }) ?
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 H, O. z- n) B; `, g: r
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;% I: m) W* u0 O3 f, Y0 I
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
( M$ J! v1 `) M. }2 ~* J( f        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
# r5 H3 x1 x5 \% e        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;* _; T& F5 x& o5 s! d1 j1 I% {
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;0 v/ A* b+ }' D+ ]& m5 c7 @# r
5 x& e4 L  J, _" t, ]8 ]0 M% s9 H/ p( u
        // FME76 o; z8 ]$ ?1 G* }& M; V( T
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;5 {0 [1 d& K. j, D8 P
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;0 i$ B0 a$ l9 T0 a
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
, r3 t! Y" N, x# W8 s
: q+ [4 `7 Q% ^' L8 F) y  G9 Q//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
' t& d# m& Q' m        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;: U3 R+ f! {0 P- K. ^" V7 V0 S
0 G1 ^& k" [0 R/ x1 P% ^/ d& Y
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
( X% a3 f9 G( [        if( elapsed_time > nes->cpu->GetTotalCycles() ) {3 V& }& [' y, I: Q% Y* r
                QueueFlush();0 J. M6 \3 F8 ~- }4 D, b
        }$ D/ x4 f+ I6 a! ]) }' ^" G

$ R7 w" n3 a! A6 m8 E4 }        while( dwLength-- ) {
* d( O( X7 i" m- y6 V                writetime = (DWORD)elapsed_time;: R! ?$ F  q9 t- n4 l& S2 _" i/ I" N
4 n3 b4 u1 [, w& h- P' q1 ?4 \
                while( GetQueue( writetime, q ) ) {1 n0 w8 V# X1 S& u3 U. [9 z
                        WriteProcess( q.addr, q.data );, T4 E; G4 n; i  R& z1 P
                }, c: @5 B9 {, q6 R
0 S, \( a6 y7 U! i; X. T6 \
                while( GetExQueue( writetime, q ) ) {
1 z- M% ?6 q; C5 t8 t0 R                        WriteExProcess( q.addr, q.data );
+ @. A% Q6 \# V; f' M  E; d+ p                }
2 T4 R% V& l1 x: k/ T2 |) F$ F5 ?8 M; X3 d$ W5 b* a4 L- V
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
8 r, U9 s, j+ K, N5 K/ w6 U  W. Q3 _  E                output = 0;
' |9 k6 W1 I8 d                output += internal.Process( 0 )*vol[0];, ^- E0 Y; X6 \: O0 |8 ^, E; z
                output += internal.Process( 1 )*vol[1];
: m, p, L+ A( t9 [4 p                output += internal.Process( 2 )*vol[2];5 S. j8 ^, D. k# j4 {" f
                output += internal.Process( 3 )*vol[3];  M& z" M3 \( m- Q
                output += internal.Process( 4 )*vol[4];
! {% g2 ^% v/ X  v2 F7 ?: r' u
2 B7 `! X( O: X  w# H  n                if( exsound_select & 0x01 ) {
+ E8 z6 @2 c  V1 ]' A, ]6 A. V                        output += vrc6.Process( 0 )*vol[5];
5 \0 b6 s' [8 h4 f5 Z8 b                        output += vrc6.Process( 1 )*vol[6];' d' t& ^! y4 a5 \6 Y5 d  n0 ]
                        output += vrc6.Process( 2 )*vol[7];
: u+ Q9 o! c  L# |                }
$ L1 K  z( j" N  x                if( exsound_select & 0x02 ) {
1 U( j8 b. ^, x                        output += vrc7.Process( 0 )*vol[8];
! @+ o3 P/ t( z9 z                }
9 V* p: U0 \3 T$ N                if( exsound_select & 0x04 ) {2 X, r2 r2 W% B4 L) O
                        output += fds.Process( 0 )*vol[9];" i+ g# Q7 e1 O0 O7 B7 F2 o
                }, r% j  S- U9 M, h3 Q9 R) T8 ^
                if( exsound_select & 0x08 ) {
3 `$ v: e- i: T+ c                        output += mmc5.Process( 0 )*vol[10];
) o2 B# Z* G& `9 O! h) B                        output += mmc5.Process( 1 )*vol[11];. p4 ]  w8 \: K# K9 _2 |
                        output += mmc5.Process( 2 )*vol[12];
/ N+ Y  V% o7 l8 {8 K% U                }5 s2 V  d( m/ x5 N  ~) [
                if( exsound_select & 0x10 ) {0 I/ N+ H* p( ?4 j7 F0 a
                        output += n106.Process( 0 )*vol[13];
4 L6 o, [1 ~% h3 l8 z$ p                        output += n106.Process( 1 )*vol[14];, Y( V9 v2 A% J/ `- j4 u( U
                        output += n106.Process( 2 )*vol[15];
( s# l8 [$ _' t# w0 a                        output += n106.Process( 3 )*vol[16];
1 ]* I+ m5 {6 X, }+ X" q8 B                        output += n106.Process( 4 )*vol[17];( y8 |& x9 g# l6 T
                        output += n106.Process( 5 )*vol[18];
* d- p  r4 j/ v2 W1 B- I, G7 p                        output += n106.Process( 6 )*vol[19];- _, H7 ^' t( y, U0 m- P( a
                        output += n106.Process( 7 )*vol[20];
$ V- t+ t2 v% p) T5 e( i- D4 r* B                }
  Y2 K, e. |& z/ R  a                if( exsound_select & 0x20 ) {
# B- K+ @. h( m* S1 M* d. \                        fme7.Process( 3 );        // Envelope & Noise
7 f$ q& ~  O/ I" P: h9 a+ c                        output += fme7.Process( 0 )*vol[21];" }" R. _4 H! M: x: W, _3 H, G
                        output += fme7.Process( 1 )*vol[22];
- x1 C4 m0 b' _9 a" I$ c, ^                        output += fme7.Process( 2 )*vol[23];( U" g  C, C. G, N  n8 H( n( u
                }% T4 |  c  H6 B

0 o+ K! l# _5 Z1 ?0 C: J+ _) w                output >>= 8;
  f8 n/ t# j& A& N& O  M& F: h) W! t/ E4 g
                if( nFilterType == 1 ) {7 v( V  c8 Z. z5 k6 N
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
/ p7 N8 d* ~' _% J! _* l9 k; X                        output = (lowpass_filter[0]+output)/2;' D& E7 k! Q0 f; ^; M! u
                        lowpass_filter[0] = output;& }/ A5 F/ q" y& n& r! J  n
                } else if( nFilterType == 2 ) {- h9 A7 {7 g" q  q; n! r% N
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
  `7 z, i6 o0 ~- C  s- g3 _                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
) G2 j) \* u3 p* P                        lowpass_filter[1] = lowpass_filter[0];( ^+ \3 D; h; T. v
                        lowpass_filter[0] = output;7 Z9 T, j0 K* ?! q4 o$ G8 ?+ ~" }
                } else if( nFilterType == 3 ) {$ r+ a: i1 \. ?. b$ `
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)$ W2 K$ Q6 H1 T8 F" w* h% r4 |
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
2 x1 v+ k+ q  l, p$ h                        lowpass_filter[2] = lowpass_filter[1];' M6 S* b/ _! b3 S) P# h
                        lowpass_filter[1] = lowpass_filter[0];. a: g2 s' ?2 @( K+ j) v
                        lowpass_filter[0] = output;
# q0 `4 m% J* S- q                } else if( nFilterType == 4 ) {
$ `5 u8 V+ R, J& p1 L2 a                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)$ T# I- F- q3 o9 I0 N) D
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
; w  c9 d' x/ i7 B                        lowpass_filter[1] = lowpass_filter[0];  M  O# N( r. v8 r2 c1 l/ Y+ ^
                        lowpass_filter[0] = output;
2 }: M- d) N* i% s* D9 x/ Y: F2 [# s. M                }
, P' X( z; g5 u9 c$ T4 d3 X0 t+ V  U# v
#if        0
  \# ~$ l- L4 Y' ?+ F* q2 ]                // DC惉暘偺僇僢僩
# [% N8 O# W0 C9 w$ A% {: l+ I: ^9 m2 u                {! @2 C$ }8 G9 e% k5 Y3 I
                static double ave = 0.0, max=0.0, min=0.0;
& Q' `- \5 R7 }% F                double delta;+ m/ P4 X* {+ s" P
                delta = (max-min)/32768.0;2 X4 `" E' j! }4 K
                max -= delta;2 x9 n% P2 E/ z, z" M6 j
                min += delta;
9 v2 ]# ?1 F; k  m* L" t                if( output > max ) max = output;4 f% o7 L# f/ b: o/ H
                if( output < min ) min = output;4 _" x" J2 G/ B* p  R& T# \) ^
                ave -= ave/1024.0;
8 {7 D0 l) K7 S2 W  u                ave += (max+min)/2048.0;; i$ c, L& e) o# w; \' F
                output -= (INT)ave;$ {  }% S1 J# W1 @# p  w
                }8 e; _1 h) ~3 a5 `; X7 r" P) @8 B9 u
#endif4 l4 U8 U# n0 z* C( @' |0 x
#if        1" z& |8 Y" U; T/ ~0 ~
                // DC惉暘偺僇僢僩(HPF TEST)( D# S9 R" ^' F. F2 Q
                {
5 j- g+ f0 k# L3 v. j- X//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);5 f, }, o$ Z2 Q2 k5 i) `! |
                static        double        cutofftemp = (2.0*3.141592653579*40.0);) p. d$ C( B4 z- R0 i) X7 x
                double        cutoff = cutofftemp/(double)Config.sound.nRate;- k+ C* e. x6 V! t' h0 n6 \
                static        double        tmp = 0.0;
0 \7 v3 \) L6 p                double        in, out;
, I, `8 Z- Z4 k. m2 {/ A5 [' ]7 ^9 F
                in = (double)output;
) ]9 o) a4 a" w. m) d2 g9 O/ k+ e                out = (in - tmp);
7 v2 T1 x% u" ^: H9 h* ]                tmp = tmp + cutoff * out;* K2 j% ]. P0 O  {/ r
* |5 N' a: ^7 F  `. w" w
                output = (INT)out;$ Q3 I4 C+ }6 |
                }
$ q0 Z/ Q- W$ ?' F. ^#endif
/ a9 u+ m! y3 H5 V3 P" a: k9 r#if        0. L7 r+ B9 A- n: D! ~1 m% V8 U' S
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)1 x4 _0 x3 H. S7 z. H5 X- H4 ?% `
                {
$ w# l& y7 x, o+ b. t                INT        diff = abs(output-last_data);4 ^5 U: k2 h# O. ~7 i0 V
                if( diff > 0x4000 ) {
2 N& n; p' ^! R. Q                        output /= 4;( D9 N7 K3 Y# g( {
                } else 1 _5 G4 ^6 z0 A% R; ~- e7 v: S& {
                if( diff > 0x3000 ) {
! x1 ~! a$ k6 \0 I% Y* G% ~, w                        output /= 3;
, x' k4 j$ y: m1 ?" Y                } else
# Q) c  T3 ]; l) N& c$ @6 u                if( diff > 0x2000 ) {
' @4 p) b9 [8 M% g8 E1 ^4 _                        output /= 2;
( f: I: t( t5 H; f2 V( q4 H: N9 {                }) s! @4 i. E( U, x& V' O. Y
                last_data = output;
# A" L. u" s( j; n) p                }
$ K: \6 z$ o, w5 C/ U' u#endif
! L! B) ]2 Q& f# i: o2 I' D                // Limit! @( [3 f4 ~8 @1 L" x# |
                if( output > 0x7FFF ) {
, D% n; l! K% K' m4 A3 f+ r: m  _                        output = 0x7FFF;
' v5 X% k7 G; B0 S1 q4 V6 P- o                } else if( output < -0x8000 ) {9 t3 f4 o. s3 d# M
                        output = -0x8000;* u$ b, S4 _5 P
                }5 ?5 o! X% h( O/ M- a

% X6 c( H7 Q: D3 a! F: `8 x9 b7 g                if( nBits != 8 ) {
! H# U: x' u* k! k1 b! S5 L                        *(SHORT*)lpBuffer = (SHORT)output;
' j" d4 B" X4 @: f! t% }                        lpBuffer += sizeof(SHORT);
: L( ?6 Y3 R* ]7 e! L( T                } else {/ @* r$ B5 w/ j2 b- T, N; M
                        *lpBuffer++ = (output>>8)^0x80;3 K; T7 ^* i+ _( h$ M" N% k0 ?
                }
/ ^+ ~2 y" z8 S, F+ O2 B( H4 |! ?7 z- O. w+ A5 N3 F2 J7 e* c
                if( nCcount < 0x0100 )& _! i: f/ A& F1 R: s$ B
                        pSoundBuf[nCcount++] = (SHORT)output;- |) O) I' t& |9 [  [. U

( @# y+ k4 W& i. f3 R//                elapsedtime += cycle_rate;& K6 [. F! D/ X$ Z$ _4 r
                elapsed_time += cycle_rate;
# c5 i8 u$ E. [; o5 s- G: ^  i0 t        }& Q. S3 e' ?! `' H

+ a) p* Z+ T: Z# k8 v% N#if        1
5 ~0 `+ ^, z; U0 F# k        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {/ U# C1 r" R: ]- G. c5 V
                elapsed_time = nes->cpu->GetTotalCycles();
5 X! q# ]1 g0 S6 {3 b        }3 L( r3 ^& u. n& f) u
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {+ X. `3 Y' j7 ~# \  y
                elapsed_time = nes->cpu->GetTotalCycles();
6 ]. _8 g7 p0 X- G3 ^, o- O: l        }7 R4 J2 ?& B; |2 y  F
#else) E. }* `! h/ d( c; R) Y3 g
        elapsed_time = nes->cpu->GetTotalCycles();# z* e8 Y1 H/ d1 A
#endif2 p$ ^1 s) j3 o6 {# h6 j% g
}  [* c  N( g& b9 v* b
; I  y% y+ L! p6 e4 a
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)  D; h/ d5 f! l
INT        APU::GetChannelFrequency( INT no )& z4 ?/ K8 ?& [2 O
{
( a  F1 r5 t% O- U7 Y2 F* [        if( !m_bMute[0] ). O5 ~' r/ x; p% ?& X
                return        0;8 [+ m; n/ L1 k* e
( S) @1 D% b7 v; @+ y
        // Internal* A9 U9 k9 M+ v" Q
        if( no < 5 ) {, N3 w- ^' M9 m, X* o$ n4 b$ Q
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
7 N7 p4 e! E% P" Z# u' ~  Z        }- d3 @, }) D6 }7 ?5 A1 L
        // VRC6
# S! [2 Q6 q5 h$ @2 U* `- V8 D        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {' {$ a; u  d6 A
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
' Y$ F, z% d1 C: ?4 [% U) u5 J- K/ M" o        }$ M" F& R+ b% N; F/ @
        // FDS
9 g' @# u; D( k; z        if( (exsound_select & 0x04) && no == 0x300 ) {% M/ p' e& }2 k2 y. R( X3 {* x
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
2 }1 @, y: R$ e6 L1 h: \  \# n        }6 `5 f$ K7 Y, z1 M
        // MMC56 U  R  k: x& C* f/ y/ }# M
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
0 L9 q( j0 l7 l9 W/ W9 ]                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;3 U7 `  ~# l1 _0 C2 |" y3 t
        }2 o% i4 l9 A/ I; @
        // N1065 t8 _1 t4 ?3 h8 N3 F: U
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {! s* u% b) r1 @
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;0 m: O2 h0 Z8 z/ p! m! [9 D  d
        }2 [5 G8 g; l9 h& R, @' ]" w
        // FME71 _( O+ e( w: Z) X0 d. K
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {6 s) P' e1 y7 x/ C9 K+ `7 L
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
# c( z! V- q  j3 c. }2 `$ P4 D        }6 C" X- M1 h6 |9 D
        // VRC7
& J7 j  `0 B& }/ C! B* w        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
- R4 V* `& @% n6 m                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;- X. O/ u) P. }  P8 ~" ~+ W
        }# P. V" ^$ H" j& ?+ ]+ h- W
        return        0;
0 e# W: P! e6 b7 y9 a# I}
$ }6 j% [+ c# o' ^) R
  X6 ^  F) C6 M" _, p& E// State Save/Load
1 F5 L4 h6 i9 R3 n# ?4 qvoid        APU::SaveState( LPBYTE p )2 _, x: T" j; g
{
6 V+ A6 m9 N/ v9 w#ifdef        _DEBUG8 M# @9 ]( O  X& h5 M- Y, {, B' Y
LPBYTE        pold = p;
1 B( E% h1 f) }) d4 C#endif
9 V! j2 k2 q: B8 b
* Z% x* Z9 L( b! Z        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
; h! d' O4 w: B        QueueFlush();8 Q0 c3 W3 r& M% h+ R8 Y" g

1 g% Z* ~* L: ]; [$ ?# u2 j1 v        internal.SaveState( p );. X  m5 l7 X3 A3 c+ T7 H
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding/ r2 r5 Q* B# N6 ^: j# ?
: T" I9 o+ W0 R1 X. Q6 F% E" ~# t
        // VRC61 u! Z! W8 T' @
        if( exsound_select & 0x01 ) {
3 ?# F! ?0 k% W% D3 i* w: r, p3 I                vrc6.SaveState( p );
4 f' \! r1 E0 C+ F                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding  S+ m/ e0 F) X
        }9 q4 ?* }& {7 b$ B, J( f7 W
        // VRC7 (not support)% q- n1 h+ H4 X2 N" P; p
        if( exsound_select & 0x02 ) {0 A  ]/ P3 Q! i  K4 z
                vrc7.SaveState( p );0 O( x2 D$ s# H* P
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
7 ?9 D+ E/ ^  g        }) X, B9 [2 g# `, O& R8 E
        // FDS
/ I' Q& \7 H$ J/ e- S/ ~7 m        if( exsound_select & 0x04 ) {4 v1 l0 D) N+ w, z1 f9 z
                fds.SaveState( p );. x. m2 i5 d4 R8 N
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding# [% ]2 ?2 b" U" j4 J+ F, f
        }
: Y5 i% s1 v$ t, {$ a        // MMC5% c- T1 e# j% @# G+ z+ I+ {8 w5 U
        if( exsound_select & 0x08 ) {
1 C4 X5 ^" C! |% p6 h                mmc5.SaveState( p );3 {) |: q! Z7 e& r
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding/ _1 ?2 _4 b) R6 [$ w' g
        }
+ N  m0 H3 M' L& Q$ e; m2 ~        // N106
* v) r/ K! _: [0 ^( j        if( exsound_select & 0x10 ) {
- }, v/ H  N- }+ B                n106.SaveState( p );
. P; _; h6 N+ q% i; r# e5 o- L- X                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding8 @4 q" K5 d  o1 @( l" g9 u6 z$ J
        }
1 b0 P8 X+ P4 }; d5 k& g% D        // FME7  [! c8 n/ I4 L( B
        if( exsound_select & 0x20 ) {
/ Y( d& w! x  {! `/ t0 r                fme7.SaveState( p );
, b( o2 k' e+ x                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
; a8 W' B- R& ^3 A; ]0 N9 ^        }3 E9 ?/ }/ `" \
. h; H/ E7 Z) B) n7 D: w) d  [( v
#ifdef        _DEBUG' a3 J# ]) S( e( A( ~
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );3 Q, r7 `9 I5 p4 Z/ s
#endif2 |( n' c4 l1 L- v1 Z
}9 ^& f! G$ o/ t) h: U

. o$ e4 _, J$ xvoid        APU::LoadState( LPBYTE p )
  T6 V+ Z1 H2 h$ F{
/ h7 B; C, I' W2 v. p9 j, X        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
  E- T& p) Z0 Y, q: H" v        QueueClear();" L4 y* h; p/ t2 P0 ^0 D9 T! H
. M: y# J( k1 x3 z( z
        internal.LoadState( p );
6 q( {) m, f% c! ^! V; j$ H        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding/ R; e* a4 M! v* Y

) ^( D# R/ t! P, y8 A; E; Y        // VRC6
3 T6 ]. T" [' M6 F5 }) S        if( exsound_select & 0x01 ) {% |' A: Z: T# y; l* @0 a. f
                vrc6.LoadState( p );$ ~: K" b4 J/ j. f) k- I) ?( z
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
1 P  b( L& P3 c/ c' G+ s5 U        }
' M0 u* C7 U/ [$ Z        // VRC7 (not support)
3 @) h0 P# L; S4 e7 F: H, {/ b; Y        if( exsound_select & 0x02 ) {, n- w  _7 H+ x
                vrc7.LoadState( p );
+ `, m' V  D- V9 m                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding" [' \+ E, I/ a" P
        }- F* U# y& J; y9 p: ?, v, W- {
        // FDS* u$ G  k, |* w) e$ c( J% C
        if( exsound_select & 0x04 ) {
! H1 L8 P8 u' J( \8 L9 y                fds.LoadState( p );
8 I( v) \/ L/ v8 |9 C. z0 ^                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding% F7 e7 ~. G+ O# o; C( k$ j# H, X8 x
        }
# {+ {% a2 ]4 q4 I: V. G. c        // MMC5" @/ w& Y/ z' P6 y( h
        if( exsound_select & 0x08 ) {
$ e7 a& Q1 ^* S! [0 R- ?                mmc5.LoadState( p );
2 F$ Z( e4 B2 G" t; g                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding* C6 A% J) f* |( p
        }
, i6 z' L2 w7 Y( l% V# U0 W        // N1066 T& |2 K# Y5 Q2 k- {9 Q
        if( exsound_select & 0x10 ) {/ n7 d: g. V. K& j) k
                n106.LoadState( p );2 l; s2 E8 E) T1 h
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding4 i7 M3 S" ^2 U' n7 E  y% o, Z* ~
        }
* }1 L* O8 t: M2 ~! ^8 u9 ~        // FME79 |6 |+ ^: F1 ]6 {* R7 U% p. `
        if( exsound_select & 0x20 ) {
4 M, J, }# p; r! }% u3 I* @                fme7.LoadState( p );3 }4 k  V, \' `; L1 j/ A
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
  j0 y, G# f5 ]% e, U2 t' Q* w- Q        }
$ O3 a: ^' R5 r0 B}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 % p1 t3 p1 A  C, ]/ U; c8 _
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。/ K) `$ }1 ~/ `' b& a0 b4 M
感激不尽~~
+ m/ P/ W( p; w
恩 我對模擬器不是很有研究,0 I1 Q- i8 n$ p2 o4 t4 R0 m
雖然要了解源碼內容,可能不是很困難,5 `" Q& E/ [+ l' A* e
不過還是要花時間,個人目前蠻忙碌的。
) T! X& r0 K" {% A4 i) @4 }) o5 ~; b* j6 M( q9 {; ]  ^
給你一個朋友的MSN,你可以跟他討論看看,- e1 O) \& a2 P2 W1 w$ e9 e2 |
他本身是程式設計師,也對FC模擬器很有興趣。
# i2 D9 z0 c" m: @- o5 q+ A) ]! {9 |2 k& p6 {
MSN我就PM到你的信箱了。4 u% r& r, K7 Z& N' {: ]: k1 t1 E% Z( g

% S7 l/ {! J2 W- `: b$ i8 Y* {0 e, y希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
) a3 p' `6 x& |. a  y: K呵…… 谢过团长大人~~

/ `  n+ V+ v  ~! x8 C- O
  x  ~" y/ j/ ]0 |) i9 S哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
% D) R# W- l1 D: ~0 V团长的朋友都是神,那团长就是神的boss。

% b% f' x" E- r哈 不敢當,我只是個平凡人,
  I3 Y4 G2 B9 E( n7 V要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
' \: l( x& E& m& h# e; `ZYH
8 U, `) M4 _, W1 ?QQ:414734306
6 J9 f, x* u: K$ I+ f6 ^Mail:zyh-01@126.com' C" H$ Y1 q' M7 ?

/ J  A( e& n& P5 j  H1 Y( s他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 . G2 m. l' k. n- S
再次对团长大人和悠悠哥的无私帮助表示感谢~~
# b4 T% b8 R9 W
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-6 04:55 , Processed in 1.066406 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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