EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?1 G" I% h3 o( K' V6 O% \
PS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。! x' G3 e. B- u8 l" H
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
1 n2 r+ b8 \3 Y  \; f" ~这里有相应的模拟器源码,就当送给大侠了~~, h( [9 W  H1 ^/ m2 m8 E. Y; R
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 6 x% m( t' f0 p; Y; e6 w$ U6 I  l
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。5 g1 L/ u2 d* a1 n
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
+ z5 ^1 o  O+ k1 q- s这里有相应的模拟器源码,就当送给大侠 ...
2 Q/ @& X; R: k9 X9 j! Z9 {
聲音部分(Audoi Process Unit = APU):
+ p7 v: ~) ]  c$ O/ q5 w5 l3 v. r.\NES\APU.cpp+ `9 W' c1 S" r
.\NES\APU.h0 A$ g8 N9 U) ]: S7 J

4 Q- D8 H# j$ |- p" h& W( J
- J! Y6 Q" @7 g1 @; o影像處理部份(Picture Processing Unit = PPU):
+ X( I8 T( f/ b  G) Z.\NES\PPU.cpp
: s$ n! D7 G7 m.\NES\PPU.h
% ~' W3 X4 c2 R( d# `3 @
: D1 F* {8 v  Q9 U; U如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
$ Q" a1 [# q9 {- T( }3 o6 L感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:3 q4 N8 Q* ^* G, G3 z
(由于很多专用术语和算法机理都不明白,所以看不大懂……)1 T5 s& _  f$ S2 `+ G/ G
//////////////////////////////////////////////////////////////////////////* e6 |, m* L. c8 u6 ?
//                                                                      //
7 k5 c+ n2 B; z: }6 E//      NES APU core                                                    //
  [9 M5 ^$ H8 O" j//                                                           Norix      //% J! k- y# G: g8 L5 w8 R- B+ u
//                                               written     2002/06/27 //9 Q) U' p7 \4 S) i- A
//                                               last modify ----/--/-- //) J$ @8 B+ t3 a6 L$ y
//////////////////////////////////////////////////////////////////////////
6 C( K2 a1 u, C# n5 a8 }+ _: _#include "DebugOut.h", w3 l  {% D/ o; i" k$ L- U
#include "App.h"
; j% P% s( {! _7 g#include "Config.h"
. S; d4 O9 G" J- ]
1 |# T5 G" c8 A% e4 e; @( I# \#include "nes.h"
* J) S8 a9 F) x0 `# }3 d#include "mmu.h"
0 G; R9 l& l6 ?% l/ q#include "cpu.h"
' ^% {4 F! \/ G/ o2 o# I# \  z#include "ppu.h"# c  G- R! |# e( ]- a
#include "rom.h"
0 U; a% N2 O; G, @4 X7 K! V6 ^#include "apu.h"
; _$ @! z1 N3 V8 P7 u3 j( q9 U& [, n
// Volume adjust3 H$ |$ h6 {/ b0 v  _: t
// Internal sounds
) \" \  i& t* i  i% O6 D#define        RECTANGLE_VOL        (0x0F0)! Q( V: ]4 l. j5 S
#define        TRIANGLE_VOL        (0x130)# i" ^4 v5 ^1 F* X9 T, }3 e* h
#define        NOISE_VOL        (0x0C0)0 y: F" T/ N& n1 e/ V/ @: W6 N- ?  G
#define        DPCM_VOL        (0x0F0), ?7 c' a% r1 o6 \( Q" R8 d
// Extra sounds
' l. Z/ z; o# t8 ]#define        VRC6_VOL        (0x0F0)/ t1 V+ C# r  C, ~6 p
#define        VRC7_VOL        (0x130)
; `3 r) P0 z* z- p4 J#define        FDS_VOL                (0x0F0)2 X, t, P' w6 i
#define        MMC5_VOL        (0x0F0): y1 D' K2 G! x! P, A4 l; C
#define        N106_VOL        (0x088)
  U3 ^* R( v8 }9 V; \$ h: W#define        FME7_VOL        (0x130)! H  G3 j$ z2 M

( C& K* H' C% ^# H3 H$ N% ?APU::APU( NES* parent )
- a/ }8 l$ s+ d6 [{+ ?! K2 ~0 D  w  i4 I
        exsound_select = 0;
, w3 c3 t/ o- u: w( U: [4 A* _
        nes = parent;
2 [. R; V* @  s: R; e  N+ R1 d        internal.SetParent( parent );/ v2 |3 {. B$ m+ V# D# O
! i6 u, M' e; X* ]
        last_data = last_diff = 0;
( i) ^5 k% F9 U
' U' v7 P, D9 `5 e( d8 T+ ~4 _        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
& S+ D8 g7 c# i- ], i8 P9 p& c
& M6 k2 K! C8 c! {        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
! ]) y- f& D0 U2 {7 k) \1 D6 B; ~        ZEROMEMORY( &queue, sizeof(queue) );( m( O8 m; N7 \% {, z) Q  B
        ZEROMEMORY( &exqueue, sizeof(exqueue) );0 }0 T! C" s: ]$ |- a* X* h
' A- ?) G' g% w8 H' j
        for( INT i = 0; i < 16; i++ ) {/ h: H# l# G- p% R+ M
                m_bMute = TRUE;
7 M* t: `! \  `5 h        }
& y7 V, d& G6 H}, R9 T2 s9 i2 A: R% t: F, Q% S

4 V# Z; _- P% y& n1 W  _APU::~APU()( W( u  x+ w! O  r1 w4 s, ]) F
{& O. M) X/ p- |  T9 m
}( V' s- R- V9 e7 {* l
9 D  K* x( G* a
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )- t: j0 z# R0 r: I+ B
{& H8 _4 f4 e2 [4 @% \7 \& h) P
        queue.data[queue.wrptr].time = writetime;& t7 b1 T2 [. s: E0 b) ^* I) t
        queue.data[queue.wrptr].addr = addr;( F9 l- [1 q) v
        queue.data[queue.wrptr].data = data;: ^1 C+ O( |' q  H+ D- |( C
        queue.wrptr++;
5 }' y) x: e8 @& u: ^        queue.wrptr&=QUEUE_LENGTH-1;
' ]! P; c, ^4 b# X/ W        if( queue.wrptr == queue.rdptr ) {
" T, Z4 Q  M2 W# G                DEBUGOUT( "queue overflow.\n" );
( c) C' r: U7 H1 r5 _, J  j" |        }! _/ n2 g6 }0 l: C' N; P0 l
}
9 [8 b% E% ?" e3 M' J, g! R2 w5 Q4 ^9 r& m% r
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )7 d) ?$ U7 T4 T# w
{
& ?7 _, V& S' U4 c; E        if( queue.wrptr == queue.rdptr ) {
# l# x+ m& z) w% C1 X                return        FALSE;
! L1 o: F7 U- m. K7 {        }
5 k0 E3 a0 w- p. R( R9 i- f: b        if( queue.data[queue.rdptr].time <= writetime ) {+ W/ w- i; u; r; Y' r+ {  g5 |2 b$ R
                ret = queue.data[queue.rdptr];
# k# u2 R. ^0 U+ `! g                queue.rdptr++;
( m7 [" E6 U0 Z0 j/ F! L3 S                queue.rdptr&=QUEUE_LENGTH-1;
6 [9 U) `1 d5 m: N; u8 Y                return        TRUE;
$ C. q$ D/ J& X/ u! l9 l        }
  x" h5 q0 O, `- t2 a! k6 Z        return        FALSE;
+ ?# O1 c; \/ j; r1 W! ^}
  ]. d4 i; j& ^' S: u9 F
% Z8 m4 T# Q7 \1 L8 wvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )3 p- F2 F0 H" k5 j( J0 w& J/ G
{
2 w- S$ H/ }9 g$ A        exqueue.data[exqueue.wrptr].time = writetime;# b& P! B! j: I# A3 j1 C
        exqueue.data[exqueue.wrptr].addr = addr;4 K. \4 n! [. N9 q# C' S
        exqueue.data[exqueue.wrptr].data = data;
3 h; `" c. Q# W& e  b9 _. |/ g% e        exqueue.wrptr++;
, y/ X  F- ?8 v        exqueue.wrptr&=QUEUE_LENGTH-1;
) W: Q2 b" E% V        if( exqueue.wrptr == exqueue.rdptr ) {2 r1 h+ ^  k) d0 P8 E" g
                DEBUGOUT( "exqueue overflow.\n" );
* d9 B( t  M, w1 d        }! a( M9 l6 y  G& M% G
}. `* _/ R, |: h( F' X: U- A( Q

. V6 A/ ~; ~5 YBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
: G* \+ z# y# Y! b9 m{
0 B3 B- b2 s0 q) x6 h        if( exqueue.wrptr == exqueue.rdptr ) {" `% Z9 W+ R+ S! m
                return        FALSE;
2 p6 X$ q, V" g/ i* w, T/ H8 V* Y        }
1 ]  R: t9 j. O. ]4 C        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
. z5 e' o% ^, i4 ~2 y+ b* E/ d                ret = exqueue.data[exqueue.rdptr];( |8 F$ g5 n0 d, {4 @: B
                exqueue.rdptr++;' @8 n  k& P; m' ^8 v, K- k3 ?5 }
                exqueue.rdptr&=QUEUE_LENGTH-1;
# C5 i% u7 ?8 q                return        TRUE;
* q) Y! y7 c: Q4 G7 p0 o) X        }
) s* y# s# z( X, q0 y* l. o' `' w        return        FALSE;
; w4 S! D2 r4 k7 L$ l) x2 D" d}
3 @* U  a1 e7 A: ^% W6 J2 I/ d, z& P* [. Z
void        APU::QueueClear()
7 ~1 [/ I7 b* o# i, r{% M; p* ^8 E$ J2 k
        ZEROMEMORY( &queue, sizeof(queue) );
2 I; b! a) S: l/ n, U; M; y        ZEROMEMORY( &exqueue, sizeof(exqueue) );2 a  c' z0 x6 {& K' t# Z
}+ `" }+ A% B1 |8 z5 b

" T! n9 l) L1 ~8 Z. n7 l0 @void        APU::QueueFlush(). W9 y! o. [- R7 u5 C9 b: p
{
4 z7 t; @$ Q4 p% k1 y" _        while( queue.wrptr != queue.rdptr ) {
5 N9 ~- z8 M/ q& Y+ z: `; s                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );7 [9 l6 w4 L- @' k
                queue.rdptr++;
8 }# W) v0 `2 ^* N' h% G                queue.rdptr&=QUEUE_LENGTH-1;
0 V- K# z- Z+ Y7 m9 W% M- G" G5 r+ c5 o        }
. Z* V' U/ ~3 [9 d
6 `$ b2 t1 W% a7 a8 i7 ~        while( exqueue.wrptr != exqueue.rdptr ) {
+ X2 h9 z: p5 E: S" I' W                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );7 T: g  q7 b3 t. g* S6 n* B
                exqueue.rdptr++;
" p. f! s# I+ Q2 ~* O. R9 H) c                exqueue.rdptr&=QUEUE_LENGTH-1;
# S- D# b1 k- v0 U) s8 H) G  t! d        }
# {( E  F0 r  U" X" B}
5 }# Z* h2 f7 T) S. S+ P8 f$ j2 |( c! g- q9 P9 p% F3 |, @
void        APU::SoundSetup()! D8 _6 b. `) T* J
{" Z3 Z- ^; d9 N& |
        FLOAT        fClock = nes->nescfg->CpuClock;
" p* D5 O. C' U        INT        nRate = (INT)Config.sound.nRate;
. H! c7 P( K! L2 w8 _        internal.Setup( fClock, nRate );; n& n5 s* p0 Q, q5 o
        vrc6.Setup( fClock, nRate );5 z) ?* s7 F7 w' n
        vrc7.Setup( fClock, nRate );+ h, X, m& o" l. r
        mmc5.Setup( fClock, nRate );
& ?4 f8 B3 O& u        fds.Setup ( fClock, nRate );. |6 J9 p$ R5 {5 @) }& R. F
        n106.Setup( fClock, nRate );) N4 N) f0 }, g& c
        fme7.Setup( fClock, nRate );% c7 C) s* J: \) m1 O9 G. v* S
}  T5 T, j3 g  n
* d* h5 |$ p; V( ]+ n0 Z+ K" v9 p
void        APU::Reset()
5 P' W: i7 W, O9 q  c1 Q8 G{
, b8 x4 w* B2 E* U( H/ s/ X  X7 s        ZEROMEMORY( &queue, sizeof(queue) );
: y! o) E8 X& q# c        ZEROMEMORY( &exqueue, sizeof(exqueue) );- ?3 W' K0 x  o8 f$ K' ?
+ P! Q+ J2 w* Q6 }# M) S; B, [, v
        elapsed_time = 0;
; p) ^6 I! N2 s2 b8 Y- h2 w4 z! l! A- o( y$ Q+ G
        FLOAT        fClock = nes->nescfg->CpuClock;
9 ^, m& L# m7 W; @, z) ?        INT        nRate = (INT)Config.sound.nRate;
/ x  ?) i1 t) r        internal.Reset( fClock, nRate );
$ h4 ?1 k; ?8 W        vrc6.Reset( fClock, nRate );. o3 }) p0 v. O% v
        vrc7.Reset( fClock, nRate );+ t  I: T! Y* I% ?; Z
        mmc5.Reset( fClock, nRate );
4 {9 F( S* p1 C7 l8 J8 @; K& x        fds.Reset ( fClock, nRate );" v* T  h1 I. @& r3 \
        n106.Reset( fClock, nRate );
/ T& }$ f/ g7 X        fme7.Reset( fClock, nRate );
4 g0 a4 q' {* v9 ], O4 [7 J' {
! y# F  L) I/ S' E" P6 H. `        SoundSetup();
( `- M( [; n+ A7 q7 w& W}2 Q& j# K% `& h6 o9 b2 S
9 P, ~' b$ O7 L) s- B% g3 `
void        APU::SelectExSound( BYTE data )
% [8 {2 R/ R! W& m, s! ~) Z{, G/ M; w) S& H1 u" t) [
        exsound_select = data;" v; s" _  c% {" h9 G/ u
}
% ]4 J, c8 [- t4 t( w( `- Y1 X: X9 D
BYTE        APU::Read( WORD addr )
& c8 r7 N+ t3 t" E2 j{" H1 O+ M/ @$ N0 G0 x- }' j
        return        internal.SyncRead( addr );, _. ~) P, |/ N0 e( O* c1 R
}2 Y7 H4 J$ @7 {" l- j0 N* r
+ S" ~5 t, D5 X* R5 Y
void        APU::Write( WORD addr, BYTE data )
2 M3 d: ?6 Y  @9 }{1 Y. [9 H8 d- G' W- \1 a9 p7 ~
        // $4018偼VirtuaNES屌桳億乕僩
. L8 @5 u% l2 H( i/ u! J0 ^4 r        if( addr >= 0x4000 && addr <= 0x401F ) {' t( P$ ]! t" S% l7 a' ?( |
                internal.SyncWrite( addr, data );
9 W! ~8 ?  U; P- [1 Q+ t                SetQueue( nes->cpu->GetTotalCycles(), addr, data );% o5 d+ }* E+ \. y5 ~8 f, g. z* ?' d
        }, R% h; l7 M- r$ P
}5 o  X1 y- K6 I3 a& y2 W/ p; K
  V- r" N4 u; o6 f; c0 `/ {
BYTE        APU::ExRead( WORD addr )
# r2 m( A2 _: t3 d- [{
0 \0 z" b8 _' G. HBYTE        data = 0;2 M2 o5 V' E- q+ t. H
8 s7 h  v/ x7 t% A! d' \
        if( exsound_select & 0x10 ) {
) M4 ]; V7 g' ~" I                if( addr == 0x4800 ) {! O  x+ U& `( o$ c+ z4 Y1 N
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
  o, |& n; M3 p+ a0 d, B' j                }3 @  k( }- c" f# ?  T
        }. l) @3 h- q( S4 q
        if( exsound_select & 0x04 ) {+ m9 F: \2 M* E7 ]" x" Y
                if( addr >= 0x4040 && addr < 0x4100 ) {; P, Z1 s" |9 \# u  Z& a. Q
                        data = fds.SyncRead( addr );
! I" V' K; z4 d- r1 H                }, M. r( S! M( ]' B1 e2 C# X9 G5 d
        }
' Y: a9 r3 s4 m$ ?        if( exsound_select & 0x08 ) {: ^  E( t( _  N( ^% p
                if( addr >= 0x5000 && addr <= 0x5015 ) {+ C5 q/ S0 E& ?$ C4 v; F
                        data = mmc5.SyncRead( addr );4 |& d4 u" k8 X% b
                }4 `- l" W; J7 J! a/ a) h6 \% P9 G
        }
8 Q  W2 C9 S5 {4 ^5 ~& w
0 G( f% o! y3 J/ e: P' E" M        return        data;& o' f$ Y, Z9 p6 O' q- b
}; D0 p7 {% c+ Q9 N

8 T0 l1 y4 j7 D/ s( V" v* Cvoid        APU::ExWrite( WORD addr, BYTE data ): e% C1 _+ P) V
{
7 W" B2 k3 {! m( k) {7 R3 ~        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );* O0 _9 `4 l  h# `# A; G

1 F( a, f( e) r: s) b        if( exsound_select & 0x04 ) {
+ p1 d; i+ |/ {3 d1 I                if( addr >= 0x4040 && addr < 0x4100 ) {' o3 a" n$ Z6 o
                        fds.SyncWrite( addr, data );
9 M6 h; z) q) z& T6 L                }  @" J/ \4 K8 z# g' r4 O8 G
        }  U$ N: K9 ^% C' F; o6 Y5 r
- |8 [; @. l+ T# N: d& w
        if( exsound_select & 0x08 ) {! G& {9 ^3 m! q* E
                if( addr >= 0x5000 && addr <= 0x5015 ) {; A) K' K* d2 O5 p4 q# y
                        mmc5.SyncWrite( addr, data );5 `0 K5 d0 }) v
                }: ?, z$ t* \) H/ v
        }
7 \6 n7 Q  V% h}' j- t: U4 D# a% K; R
# ?/ _$ U  |- f5 x
void        APU::Sync()5 z6 j; i+ i% e: P3 J+ n0 l
{
! P# g0 `( T$ L! L, y- d}1 U7 o% s9 o: b: G
* p# s# C0 M, P: K; m$ O3 e4 v
void        APU::SyncDPCM( INT cycles )( {% H" \' {1 p  V8 o
{& I8 B- M. d5 f1 s5 K
        internal.Sync( cycles );% H  i. F3 j1 G7 z, P0 `6 L+ S7 X
' \9 Q7 Y1 u7 @
        if( exsound_select & 0x04 ) {
  c# {6 n0 V6 ~" o7 `                fds.Sync( cycles );
: `5 x% ?6 N) y! g; b8 _: ?; {        }+ M. i5 \& W9 S9 S6 W$ c* U; j* s
        if( exsound_select & 0x08 ) {
- P' W- t  ]  T: f9 @                mmc5.Sync( cycles );
0 C; t9 }! X8 o1 I! U        }* D) }. Z* c5 t7 ]) Z/ y
}
, I4 a( ?3 A& J& d% ]
3 l3 U, u$ k7 E4 ?+ @void        APU::WriteProcess( WORD addr, BYTE data )
% I( |' N- n- i/ R7 c. W{" }" o. z5 `6 c
        // $4018偼VirtuaNES屌桳億乕僩
* W) e7 \( a" x; a. {. E        if( addr >= 0x4000 && addr <= 0x401F ) {
+ X" Y: n, `' h. ^. _                internal.Write( addr, data );3 R7 K, [, V: R* n4 ?* B
        }6 v& P# l0 t& W$ F2 u* w: M
}
( X) T! L8 V2 }: _
( ?% i4 Q0 ^# S& V# @! kvoid        APU::WriteExProcess( WORD addr, BYTE data )
4 N% N# [) Z6 u/ a* `9 d9 D{+ x7 ?  w7 j  T) c/ J
        if( exsound_select & 0x01 ) {! ~( W; T- T) I5 `" n1 h
                vrc6.Write( addr, data );
4 C. \- f  _& K  j* L        }2 j: d# h3 D# x" R1 V9 H/ d5 h
        if( exsound_select & 0x02 ) {
6 T# ]5 M& r/ s% e                vrc7.Write( addr, data );6 l6 N: T7 X* ?/ [" L2 r, c7 U
        }
- {1 Y& C# r8 X3 \6 Y5 J2 y        if( exsound_select & 0x04 ) {8 W! q* y+ C' d8 k) r. F# I  [
                fds.Write( addr, data );
2 x  @8 w4 c/ s% ?, w        }
5 d1 O9 L4 x% ~! t7 {# K" A        if( exsound_select & 0x08 ) {
7 {! z! ~! X# n4 |% x/ p4 f, I5 _+ |                mmc5.Write( addr, data );
' Z- M; \9 u( p; Y. R- \; ?( Z        }
4 H7 s8 ^* k$ X( ~: \+ ~        if( exsound_select & 0x10 ) {7 R# F1 L7 t% ~% v+ H# z
                if( addr == 0x0000 ) {
; i) q! f! o* W: n                        BYTE        dummy = n106.Read( addr );: g& K) k, q( X$ n
                } else {
0 Q: s9 ?8 }. j* g( g                        n106.Write( addr, data );
% C# q$ }8 L; \1 C7 r; g                }
6 B0 j8 C6 y2 r0 N$ D        }
) Y) ]! M* Z' ^, Y' ]1 I        if( exsound_select & 0x20 ) {
; v1 s, X' k$ @( [                fme7.Write( addr, data );2 I/ F7 t1 G9 l, Y; E7 s- z/ G* x: Y
        }% q7 M/ m$ P  h; ^
}
+ f" N, y# o6 |8 v- z8 N4 z4 r/ y! h6 L1 m5 L! l8 Y  u% I
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )$ T/ O/ U, g  w' H& t, w
{6 J' K/ L9 y" e! g
INT        nBits = Config.sound.nBits;
5 A, ?! d8 E, e/ M+ Y; RDWORD        dwLength = dwSize / (nBits/8);, x2 B' }7 R. n, |5 d7 K* e
INT        output;8 P3 q2 N7 I6 I$ M/ P' H
QUEUEDATA q;; n! Q2 h. c! n- ~1 k  G
DWORD        writetime;
2 |- F4 c8 U5 N7 d3 x
' d/ e" ]" t4 F+ ULPSHORT        pSoundBuf = m_SoundBuffer;; v& ^" L. F+ V9 R6 s" D
INT        nCcount = 0;: m1 V( J2 k) ]0 z
7 `7 J( n) B! g
INT        nFilterType = Config.sound.nFilterType;
5 ]% q! B, t1 c5 U% ~# r' O; \/ I* c
7 O3 N- E7 V! H- f6 }        if( !Config.sound.bEnable ) {
& O. R7 s3 x& z1 v0 \7 d  R2 F                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );2 A, w, l. d: ~5 X2 n: t
                return;
* t2 @2 ]2 V# p8 i3 `; Y! R        }( F8 M6 m+ I4 ]+ D! _) k
2 K7 x) E0 E+ B- Q9 f6 J& `/ X
        // Volume setup
. X2 J, n" q+ n0 g' Y! Q* R        //  0:Master
; H1 r1 H' `( r) Q4 p        //  1:Rectangle 1
" g( f" {8 s; S$ J- D        //  2:Rectangle 2" s; u" U" P8 e( ~6 R
        //  3:Triangle0 C: U2 Y7 N' z: H1 ]
        //  4:Noise. ^6 O. G  z( F- h
        //  5:DPCM" @# |) k8 [, V5 m1 a( r
        //  6:VRC6
/ H2 \4 d$ s; b$ I$ n2 i6 c- _        //  7:VRC79 ^" }0 D" I9 L( m+ _
        //  8:FDS& i7 e' G- B" {  s5 g* `
        //  9:MMC5
3 }* j) |; }( m        // 10:N106
: J" `0 S" Q2 Q0 k+ p        // 11:FME7, [5 M# U2 F/ ]3 ^& S
        INT        vol[24];
- }8 W  l" G+ I8 _5 I$ p        BOOL*        bMute = m_bMute;6 N1 K3 g& i) g; g
        SHORT*        nVolume = Config.sound.nVolume;0 f1 b( T, u1 O' H% d: g/ Q

* }1 k( R4 _0 @" \; A2 f        INT        nMasterVolume = bMute[0]?nVolume[0]:0;) n: r, S' s$ B8 K- n2 ]; d, g

" K% _! n% ?2 j7 e0 r% _$ {, K  W        // Internal" n) z- G* e8 _
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
, x" N# }' d0 x4 `. Z        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;- s* c; [' U4 o, T' Y/ Y% F
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
8 T: A+ ^! M$ [        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;6 @4 J5 z- b* m# U7 M! d2 y. Z
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
/ O% ~5 }4 d  m. ?4 D
' Y% a3 u( U$ U  M/ V% `" e' i        // VRC6
/ S$ C9 \; S9 F4 |. C% p; q        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;- H, ^) \9 M  d# J' y& ]% ?
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
' y# {/ p9 X7 k1 W8 V        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
5 R+ X$ c7 `! l; \: ]0 |; ?0 @/ h& p2 j3 p
        // VRC7
5 @: P2 Q& {% {        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
  j' X9 @) \1 H/ L( V9 B, g, O! S0 S3 {( z5 B( r* S* h( R
        // FDS8 G4 A, m7 `0 i5 X% K* r" P2 i
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
" a7 d7 w1 y; b& {! ~$ ]0 K) T9 j
, `. X+ T/ G: y4 O2 U        // MMC55 R+ u( Z% }8 W7 P$ i; F5 L8 i, P: x1 n
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
* k7 t0 A' }7 B5 m: R        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;  k# \2 i7 [+ {$ v# m* p* a4 B
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;: X% m; v) C; k8 s9 W/ L
/ @' M9 b! d) Z2 K& h/ U
        // N1060 c/ A8 d$ n; |# H& Q6 r
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 B" G- E4 ^; e        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
$ m. v) l' E) A/ b* Z" O7 L* m        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 v8 J8 K5 S0 u% E        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
* s7 {$ i9 T! w9 \  U/ c6 e        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;. z" [, T  k, P
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- M( h% k* P  E
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;6 e  U' n7 X# {0 c# p' |) S- x
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;4 k& F: o: ]8 }9 g. A; I

, e6 ]* ?" L5 C8 e9 h        // FME7
; m. R, d) o+ J& l* ~, r        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
8 @2 e6 R+ I: f" I' g- k* `        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;# K3 n& J3 Q1 K- ?0 V$ {
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
# ?( O1 o; A/ m& B+ z5 b+ _9 v% k. v
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;! q: w+ G8 d- A2 Z
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
+ I" X* {4 j2 E- y# Q7 C( m9 D% E! L+ d5 m& k
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
  f+ e+ q( y' |1 D! F- v- n% z9 G        if( elapsed_time > nes->cpu->GetTotalCycles() ) {! n: S5 ^. v- V5 `3 ?5 E/ \0 j7 v
                QueueFlush();" O5 @9 o' Q# k# e9 g" G7 N
        }
) W) {3 ~$ I; D) y# c7 W/ d/ R) O7 [9 O( B  e, y0 T  m% w4 t" K! g# J* `
        while( dwLength-- ) {4 W; S4 ?+ M/ p( ]/ z( ~! U1 u
                writetime = (DWORD)elapsed_time;1 g# I2 [* d: z6 K. f

) O, |, H1 L, Q                while( GetQueue( writetime, q ) ) {
* ?1 m" M& V3 A# m) P% V                        WriteProcess( q.addr, q.data );
% O( c& b  x2 z' }$ ~                }
% j( l. B# Z, R* y6 P+ ~2 E6 r  F5 ?1 w
                while( GetExQueue( writetime, q ) ) {
3 H7 h7 [# R) |2 f/ Y( O  z                        WriteExProcess( q.addr, q.data );6 `& |3 I& q  S0 G# b
                }: x  C9 E) s7 B

2 J) T+ m6 G  \7 ^8 t& }                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7+ X. T/ ?) \  d. v8 ?1 M/ @
                output = 0;9 F" Q" S' L4 P" Y  p8 p
                output += internal.Process( 0 )*vol[0];
4 |' b% C/ M- [8 T7 V9 ~8 h  d                output += internal.Process( 1 )*vol[1];% u3 j( u( \+ y3 t
                output += internal.Process( 2 )*vol[2];  ?3 F/ H  ^8 Z$ c
                output += internal.Process( 3 )*vol[3];5 F' T; U; Y& v
                output += internal.Process( 4 )*vol[4];1 r# B$ ]2 K+ Z  F- R! w( g7 ]
: ]9 h4 J5 K4 U7 [* ?0 [& p
                if( exsound_select & 0x01 ) {/ Z$ k0 s  }, {. @
                        output += vrc6.Process( 0 )*vol[5];, j. o! I! {2 o8 z7 P. \! B
                        output += vrc6.Process( 1 )*vol[6];% L; x8 p9 e* X4 K
                        output += vrc6.Process( 2 )*vol[7];
& J5 W: x- e. j* n, A9 {3 _" K! N2 j                }: v2 M, X! T+ @, Q) O$ m9 ^
                if( exsound_select & 0x02 ) {2 z- {! l% n" ^; e& T9 M
                        output += vrc7.Process( 0 )*vol[8];
6 W; n$ f. m1 ~7 P4 Q) [                }
4 o  s  q2 L! L) o" r/ R' ~, y" ]                if( exsound_select & 0x04 ) {. }( N. U+ X) Y1 J6 @
                        output += fds.Process( 0 )*vol[9];
/ V+ W( Y7 @5 `9 A                }- o* Y3 C& V) U' Q$ u
                if( exsound_select & 0x08 ) {9 F0 n9 r' b2 h  |$ h: F# _
                        output += mmc5.Process( 0 )*vol[10];* L6 q1 g$ a$ ]2 a8 \
                        output += mmc5.Process( 1 )*vol[11];
5 J4 P- Q* Y& ?$ A                        output += mmc5.Process( 2 )*vol[12];
4 k+ p% Y6 z9 U$ z3 \; p! X                }
9 S; n" i+ G# k" _9 U5 s, Y                if( exsound_select & 0x10 ) {
$ ]5 [' w6 j' H                        output += n106.Process( 0 )*vol[13];
: f! F6 j5 p9 Q, |6 w# L                        output += n106.Process( 1 )*vol[14];% W" v; y# l( A* m: a
                        output += n106.Process( 2 )*vol[15];/ U& q6 y6 a) z% R$ Y  O% a
                        output += n106.Process( 3 )*vol[16];( z1 w* E: ?4 S0 t' u
                        output += n106.Process( 4 )*vol[17];
9 M, ]" Y/ @+ k4 W                        output += n106.Process( 5 )*vol[18];
: S- w. o2 B. J3 B2 z4 T! q                        output += n106.Process( 6 )*vol[19];
+ q: S8 D0 M" k# W  e; V- H( u                        output += n106.Process( 7 )*vol[20];0 G5 W! T. `( e4 y: f3 E
                }
& v$ q1 N3 f" @* m                if( exsound_select & 0x20 ) {: M  ~, B$ j  Z% \
                        fme7.Process( 3 );        // Envelope & Noise: f# _# n( f2 J  W% x# ?
                        output += fme7.Process( 0 )*vol[21];7 `) f, p. P- r: V  I
                        output += fme7.Process( 1 )*vol[22];# A0 m6 }. n# N* R
                        output += fme7.Process( 2 )*vol[23];$ B  V, k: ?) T& v
                }
9 e$ h! U5 d. k+ S4 K- f: H$ \" i2 ~6 H+ l+ U- D6 N
                output >>= 8;
# |- k5 A9 o5 x# N  C2 [7 K: ?8 R7 W
                if( nFilterType == 1 ) {
8 B# R' G  A# e/ z$ B0 J5 Z4 P                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
2 v! i* p' G( c% d                        output = (lowpass_filter[0]+output)/2;
& C* G! g6 E+ [1 E& i3 ~                        lowpass_filter[0] = output;7 e: s" b* ~% B" f' \
                } else if( nFilterType == 2 ) {
1 X' x  B3 o! s, y* M- d  e8 o/ ]                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
: `7 T( l  V: m3 ^% L% n                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
4 K) U2 T% j; A. v                        lowpass_filter[1] = lowpass_filter[0];% m* E4 j* G& p8 E7 T
                        lowpass_filter[0] = output;7 S" @, q" Y. H9 y  }
                } else if( nFilterType == 3 ) {
7 ?# N3 l( w/ d/ y                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)" r7 w- E, e; n% @9 c+ u3 w
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
  ^2 U0 }* ~. n$ n- r                        lowpass_filter[2] = lowpass_filter[1];
5 P4 R' E, G/ R  M. P                        lowpass_filter[1] = lowpass_filter[0];" r. w! f0 x8 u" B' h
                        lowpass_filter[0] = output;9 G8 `6 S# ^% \, q0 s) e
                } else if( nFilterType == 4 ) {
5 e. A& [" ?6 t                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)9 n4 Q7 z: i4 ^0 N
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;& V7 z, m4 N! G9 H4 e7 e8 J3 a
                        lowpass_filter[1] = lowpass_filter[0];" Q4 p: m. _4 B$ s$ d4 K8 L
                        lowpass_filter[0] = output;2 I: M. C, A9 C* r
                }  q7 z0 d( N; f: X' X! Q

3 C6 j) Y6 F. w8 [& T: t6 k9 k#if        0
, E7 Y6 O( k: S# @                // DC惉暘偺僇僢僩: q2 F8 B8 {  i8 `( d  M, v
                {
6 j, `1 o2 {# ]) K! B                static double ave = 0.0, max=0.0, min=0.0;& D3 N6 }5 ]- U/ @8 C9 A
                double delta;% x" c* q5 H6 t( v$ ^3 k  c% x9 u
                delta = (max-min)/32768.0;
$ n2 L( p4 {' x% r) j, O" \/ U                max -= delta;, D0 a7 u& `& X( i  x
                min += delta;% p. N$ N+ v6 z1 @
                if( output > max ) max = output;
3 e: m- p: i* o                if( output < min ) min = output;
6 F# L/ @9 K6 u6 h' N3 R6 G. p                ave -= ave/1024.0;+ r! |" E8 J, _+ \$ \  S
                ave += (max+min)/2048.0;
8 ^- F0 T  J" M. Q5 \                output -= (INT)ave;$ I. U# p0 \& L
                }
2 D$ B" P$ p7 C! C  N8 B2 I0 C#endif
# G# P1 H6 T' s( d9 o0 ~; t* {#if        1
+ }/ @6 a7 g/ k7 q7 V5 I! \                // DC惉暘偺僇僢僩(HPF TEST)
* ^7 U! O: g- v8 N                {
0 `% O& J0 Q2 t1 S4 E; f( r//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
3 F6 X; _% K/ N; C' b2 b: m                static        double        cutofftemp = (2.0*3.141592653579*40.0);0 D" {! }7 t; A# s% Z% k
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
# z# Z3 n8 A0 Z) `" T4 h) G+ K                static        double        tmp = 0.0;3 _/ R4 h( J* x- |% Y- o3 S
                double        in, out;
  ]2 b! C  ]5 U3 ?% ~8 a
( Z& `+ q2 ~5 f3 b0 j) G4 K                in = (double)output;) P9 Y: O8 K+ }& \1 j* N7 ]" {
                out = (in - tmp);  A( K& V8 E; Y; x
                tmp = tmp + cutoff * out;7 B- Z6 h0 N+ ^
8 |2 }! F- v; C4 d& O
                output = (INT)out;
2 f5 P/ M: P% T1 ~4 h8 n& \0 n& R2 T                }
4 ?6 Y+ r8 V! X. B& B, z* W  ]#endif& f/ t6 Z! w' K- t
#if        0, g, C. S$ d' D- o4 ^
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
" d2 @) g) {6 y( b  i7 X* i  \5 z5 F                {: y" ^! c9 ~4 e9 }
                INT        diff = abs(output-last_data);+ v+ ?7 @" L1 m
                if( diff > 0x4000 ) {- o2 N3 G! p+ G* e* a" s
                        output /= 4;) L! q0 W# E7 g
                } else 9 j) l" N6 \. j9 P
                if( diff > 0x3000 ) {
, o; M7 [2 F3 |/ Y9 u+ P                        output /= 3;
7 B( o2 @8 J7 f: p6 `$ F- u) C. |                } else- i8 S2 T. s; b& p2 t
                if( diff > 0x2000 ) {% j+ Y& I) D$ A* [' B; C9 P3 e1 f
                        output /= 2;
/ m; u0 R- I. M3 Z                }; r: z. o2 \) x0 K% H' C
                last_data = output;: D9 K& Q5 h7 i( {! @
                }/ D  e/ e2 A9 z5 S: x  w$ ?8 ~- k
#endif/ C, u" b$ R  X$ D( p8 I! q8 h# C2 P
                // Limit
9 A" l7 v0 a5 J4 ?1 {2 p                if( output > 0x7FFF ) {  d& j1 n. z, n0 L: v- {: X" ]  Q
                        output = 0x7FFF;
: d) w5 P0 L4 w0 y                } else if( output < -0x8000 ) {
7 |2 Q0 W% C; ^/ d' C                        output = -0x8000;
/ e& {. h$ d* W* q$ M( \- l& k+ e! W                }
. F# o6 Y2 {$ x7 C: a
' E7 ]8 t. q6 [" C# h' c                if( nBits != 8 ) {8 E. D$ h5 ]% X6 I; r
                        *(SHORT*)lpBuffer = (SHORT)output;
8 g$ n# V: M" J/ @4 x                        lpBuffer += sizeof(SHORT);  G9 O0 h9 C9 d* U
                } else {6 J! }: [2 a) m% m) t  o
                        *lpBuffer++ = (output>>8)^0x80;0 E/ E' B/ ~" S9 `7 y8 Y; c; v
                }+ z' y& b  g) R! P: {

/ g5 Q; E" Z8 O" h" W                if( nCcount < 0x0100 )$ K5 ?) c& u/ q3 z, G, ?
                        pSoundBuf[nCcount++] = (SHORT)output;
0 |* E% b) }! o, ^- m
3 A# |+ |! I9 G0 }# W: x//                elapsedtime += cycle_rate;
; n7 k7 t9 F. a# I                elapsed_time += cycle_rate;, h3 t, |1 J8 W. F3 H6 V3 @8 e
        }
; q) c6 Q& m: T! o
, X3 n( O4 C8 z7 K( z# l#if        1
1 _; w) n5 ?, r5 c2 {7 j        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
3 a. s- H3 w: f7 u( i0 k! H! q                elapsed_time = nes->cpu->GetTotalCycles();
8 Z' |, q2 k4 {4 |* j        }6 O. \8 Z0 F1 H
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {) W. d4 o1 w8 R. a$ Q; ?
                elapsed_time = nes->cpu->GetTotalCycles();
+ s9 K# \7 B: \0 x- `: H. t7 v* b        }) F% K$ Y$ w: ?! [6 ~
#else; Y/ @6 h- E6 q  ~# H9 d7 ]* Q" j
        elapsed_time = nes->cpu->GetTotalCycles();; w1 J7 v9 d% n2 i6 l: _, a
#endif
* A* r; K( d; e# A) y4 i}/ i$ S, C; ?2 J4 \/ m0 m% m
" A  r3 l0 O  ?; V) t& d" t
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)' e9 w4 I) }0 \$ U: h3 \( z
INT        APU::GetChannelFrequency( INT no ), A) w/ t0 F$ M1 {1 i
{
* b" B+ e; [& @1 ?        if( !m_bMute[0] )
) Z( f( ]" b5 ?4 W                return        0;
) S; `& T% Q$ ?1 W3 }3 }$ O  `# s( E9 ?; G; @9 s
        // Internal  U( w+ L, l, g( ?0 E
        if( no < 5 ) {+ M1 {2 ~$ ^$ d, i. B
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
+ ]& O. g5 N( E) }) X. _        }2 M$ v$ S* K& L9 e
        // VRC6! `( i! _9 f  X3 k. U* c( s
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
, X" `. f4 ~! t/ C+ S0 i2 M9 `  I5 {                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;, x9 m, p: q3 h4 M0 t/ Z1 i
        }
- [; a% u$ Z( K. {+ B6 {$ ^9 ?        // FDS( Z& C# [5 o/ g; G. |  ]
        if( (exsound_select & 0x04) && no == 0x300 ) {. i& H8 F* `4 I, N- C+ m0 [& j
                return        m_bMute[6]?fds.GetFreq( 0 ):0;) Z* W; a( E2 C* k7 E1 q
        }8 b$ |9 X0 F% f; m
        // MMC5+ ?' T, s1 [0 Y/ B# g1 |
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {! s! ]8 }9 G5 B1 P' o  u3 {+ a7 B
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
% W. i+ e8 z7 T2 e# x        }$ `9 Y) A" X! B# R0 z* C7 Z
        // N106
9 q* X  H. y- I3 m; c        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
' Z3 h) u+ w( [! B                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
, O$ x. q3 W# y6 k$ T4 C        }; U; \# P- j; [0 Y3 Y: b/ ~
        // FME79 V4 S) Q$ L2 P% K& K7 J$ E6 Z
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
" b. s) K+ C1 K1 {% c% h                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
, W7 ?% O; c8 e7 @6 E4 `4 [/ M        }
, M$ Z: Y- q, T. b) t9 p        // VRC7
( Q) Q# ^5 P) C$ ?) w        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
% j( R' s2 t; C- j0 M% ~: H                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;0 m  b8 |% J3 l2 f$ J; A4 |
        }1 i/ Y  T/ ]5 Q
        return        0;- I2 p- e; u* X  y
}
( V! O0 ]8 |9 A2 w4 U6 w
3 N/ r6 {6 K' [/ D$ P% s1 s( b; ^// State Save/Load* d! B" W0 P, R- P: z) K; m9 ~9 {. |
void        APU::SaveState( LPBYTE p )
1 l8 I7 v# X/ s9 A{% L5 H' A: q2 w. i0 j, R7 F
#ifdef        _DEBUG
" C8 Y: B8 D4 \' B& D( pLPBYTE        pold = p;
! S( t' G( v- e' I8 Q' t7 x6 ?#endif
, O. r9 C3 H' ^" R8 O6 a* k. e% @5 x/ {
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
7 K* O* L( `0 \3 S4 f1 |        QueueFlush();2 Q& T: S6 Q& b) g( t
4 `) Y4 p2 R8 R' w
        internal.SaveState( p );
* n2 I1 W! e' Z  j# f1 x1 ]        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
" {- z7 o. Z  d) X) [1 ^0 x* z1 d/ W* A
        // VRC6
+ o: {2 }6 ^0 L& g4 H; o  T        if( exsound_select & 0x01 ) {
6 a, n* M9 y. y2 _' f7 w' U1 h" s                vrc6.SaveState( p );1 n& q$ k4 I. J, x+ v
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding  d- \) r! j( s) g1 ^! Q
        }
0 c$ n! L* L) o: ~. W$ y        // VRC7 (not support); s, l& _4 Y& m) n
        if( exsound_select & 0x02 ) {- `0 x) ?7 `! ~: ?% _3 U
                vrc7.SaveState( p );
  Q2 s" U& C6 T. n1 L$ K                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding+ e9 R% N) x5 j- F
        }
4 ]( o9 b2 k' t9 k' y# ~: d& t        // FDS; G2 {( q# E: i. s# [
        if( exsound_select & 0x04 ) {' k$ t7 s; w1 u/ F
                fds.SaveState( p );- U$ q; r2 y5 P9 h* B
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding; `( e4 o! Z6 Z# H8 l# z
        }
! x1 S0 q# v0 o* H+ Q- O4 Z, p        // MMC5" q% t4 X& D& F
        if( exsound_select & 0x08 ) {
& A& o. }" l1 g6 Z3 p                mmc5.SaveState( p );
, M4 s# S: G) r8 O, v7 i4 r* J. _                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding% ~5 d% q7 T" \* a8 |9 K
        }
/ W7 u7 Y" |$ r# j; B6 F        // N1062 ^. A2 x3 V( f* L
        if( exsound_select & 0x10 ) {: `, R5 M5 i) k! \9 \6 S! k, @5 k
                n106.SaveState( p );$ w( |, p, U9 F2 R3 g: d+ Y- Z# F) c
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding1 b* r0 W0 Q& k7 b, z
        }' w3 w0 J  k. v6 j
        // FME7
7 G# ?+ K4 A8 i0 O        if( exsound_select & 0x20 ) {  c, _& b7 d3 h& i; f5 w
                fme7.SaveState( p );5 Q. Z6 G) H# ~7 F6 R% B
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
: I9 z4 Y' g& ~' r0 ~* m6 V        }7 m; q# @  s0 L- Z

) p# p& H: W; \5 i#ifdef        _DEBUG2 s  n# U) g7 M7 u
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );' p0 y3 ~* H$ n- O' A
#endif+ G( t2 s( Y8 L8 W  k' y" o
}
9 ?$ M1 X+ _2 Q7 R- o0 S" Q
/ G/ x% S/ |; P( {1 U' J/ vvoid        APU::LoadState( LPBYTE p )% M6 I+ D3 ^8 q
{
+ N8 O. _% F8 O& Y' d        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
/ w9 E0 p0 Z7 k7 z' U5 s8 A        QueueClear();  p4 R+ c( e+ y$ H
# Q" ^$ X: L! p. z0 G: J
        internal.LoadState( p );
. T* q6 g, O! I! l- z" ?        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding  Y+ d& x) n. V- \" l9 s5 d
# p! J1 i/ I* h$ ^& j+ N$ g. v% f$ B# R
        // VRC62 ~/ v2 A; l9 ^) E- e1 h2 ?
        if( exsound_select & 0x01 ) {1 Z% N4 F7 \6 {% p
                vrc6.LoadState( p );
. [3 [6 |/ W9 m' }                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding9 T- m8 p+ N( M' G. M9 C  d( e, i: D6 @
        }
3 s6 m9 ~0 s: \6 M9 }* b        // VRC7 (not support)) E9 R8 R! O$ ~1 _
        if( exsound_select & 0x02 ) {' f8 T8 j. n, `  E# O. O2 y0 v
                vrc7.LoadState( p );( N* N4 L( m& p- `$ A
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding( o. d7 p$ [4 J+ |" K( z: i% V
        }/ r+ s+ D% A0 S+ W1 m
        // FDS4 g7 M: e" q* o3 ]' D' g+ I
        if( exsound_select & 0x04 ) {, h1 w5 X7 C  F0 H: O- q+ I# `
                fds.LoadState( p );" a3 K( o. E& G# G
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
) E; \) n* L! r0 X( k; G) \        }
" v0 P1 r$ y, g7 L        // MMC5
' B' m) Y  k- D        if( exsound_select & 0x08 ) {6 [) B" z7 K' O, R
                mmc5.LoadState( p );) s1 v: y  e7 [- p
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
6 N; J5 V0 s6 [& Y        }
: @. t. I% b; h        // N106: N# Q( v, U4 f& s4 P1 y
        if( exsound_select & 0x10 ) {
; L( h8 `- n- A& X                n106.LoadState( p );0 V! G6 _* Y2 ^* F1 B5 I3 n
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
: x3 w3 N$ m7 k: l% J0 w        }7 I7 `" N9 y& ~( U* f9 ?2 J
        // FME77 ?( N4 b0 H; @; G9 b! ^( T, r
        if( exsound_select & 0x20 ) {) r$ l' @& i+ ~9 Y
                fme7.LoadState( p );' _! f) \/ V. m. M* j/ u
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
2 c- \; c# r; d4 G: ?3 R9 P9 F$ Y" {        }
5 o( h5 V1 n( u0 u$ Q3 X: \}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
6 M$ O( w+ e1 f& d% I! U# Q可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
! d  F3 T) A6 y感激不尽~~

0 T- {- ]" l) @* ~3 J0 Q& y8 y. ?恩 我對模擬器不是很有研究,
  S' q  d9 I$ v2 v7 c; E雖然要了解源碼內容,可能不是很困難,7 h1 i& M4 [# |4 l& L, i! @/ n/ V
不過還是要花時間,個人目前蠻忙碌的。
; Y* {( E8 M/ j$ w. ]+ ~! T) X' q; J
給你一個朋友的MSN,你可以跟他討論看看,
5 J- R3 H* v  k  Z' V他本身是程式設計師,也對FC模擬器很有興趣。
+ Z& q9 H: F" X1 B; {0 Z  z/ Z  V+ `5 j7 Z
MSN我就PM到你的信箱了。. l/ `4 c6 g6 ?1 q9 s- K& I
6 M; `: T- C: c. p4 y/ I1 a8 i
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 * E4 K; l, k0 o6 b+ \- p
呵…… 谢过团长大人~~
* X" G. t' v9 ^0 s9 n6 S
) A5 F- S4 E6 ~4 }2 k9 n
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
% h: v# x, j1 |团长的朋友都是神,那团长就是神的boss。

% J2 B0 _5 u+ K* k哈 不敢當,我只是個平凡人,5 w4 x9 W+ U' u7 d; `: Z; F/ v# l
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙  I  b/ ~+ d' _1 L
ZYH
9 i* b2 ^* X5 l9 TQQ:414734306$ f4 Z" N- c' B) e
Mail:zyh-01@126.com- X) a: z% v, ]  X

' x& q3 j0 D- R他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 1 f% U/ T& p  [
再次对团长大人和悠悠哥的无私帮助表示感谢~~

0 ^  G* u* C" q不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-21 14:02 , Processed in 1.093750 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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