EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。( |$ Y! P8 v3 A# s8 R7 U; c- }! F
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~0 M6 B5 \: v4 m0 ?, Y0 o5 o9 y
这里有相应的模拟器源码,就当送给大侠了~~/ h8 `2 T2 s/ J5 t: L
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
: q7 H  s' j/ M' P能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
' ]5 W2 G8 R; A1 H. Z: |% I+ m楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
- `' V+ V. h; I& ]: B5 j这里有相应的模拟器源码,就当送给大侠 ...
! R; L4 K3 A/ ]- l
聲音部分(Audoi Process Unit = APU):- f$ l' c2 r/ e* T) `9 F9 F) h) M
.\NES\APU.cpp
5 V( y) Z& I, j" Z.\NES\APU.h6 n4 n3 \, g+ P' U! _

, i+ N4 u  ]/ P6 u, L5 q& C
) Y) d6 v" ]1 S5 k) V% K影像處理部份(Picture Processing Unit = PPU):6 g0 {" S& v$ J: c
.\NES\PPU.cpp6 U1 y- f- j  i% |9 l
.\NES\PPU.h9 Z, N  P8 E# @% V; k' O

  y6 b) A# {7 {/ k+ K8 K如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。* Q" U* ^  l& x' t' T) r
感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
4 B& X- Y& }0 D) [' T5 ~(由于很多专用术语和算法机理都不明白,所以看不大懂……)5 j5 G5 c7 u, T( C- ^  @
//////////////////////////////////////////////////////////////////////////* U- u/ y( Y3 l: c  [
//                                                                      /// x( i/ J2 E' @) M/ K* @6 c* B
//      NES APU core                                                    //+ C( n7 a+ V* m* d% i
//                                                           Norix      //# Y( j/ l* x9 Z- |% c1 z
//                                               written     2002/06/27 //
. _" v. J# a0 s8 L2 {7 C//                                               last modify ----/--/-- //. H* u" [; t+ J
//////////////////////////////////////////////////////////////////////////
" u) P3 T1 _' s+ N( N#include "DebugOut.h"
. m7 E, c& J0 G" W4 O" x5 ]) w#include "App.h"/ Q! }* }4 }4 i) N, U
#include "Config.h"; c$ I7 r- C" q) a4 D1 I  u
6 a$ N  t9 A: p
#include "nes.h"# e8 k% T  j8 d: T6 G3 O  _! u5 \4 |7 J
#include "mmu.h"
) O8 b, l6 q6 P6 c  F5 ]) }  s#include "cpu.h"
6 H7 |/ V! R3 k1 r0 K#include "ppu.h"
% r+ y3 T) x: X; ^, d#include "rom.h"
) L% A) H( O) X% S2 E  w: T8 q#include "apu.h"* V: Q$ V( r" p- ]  ]
3 b6 Q  T9 T+ c# m: @+ h, F* n
// Volume adjust4 r* ]- P  t: ?, B1 o
// Internal sounds& N" J' a% b* p, L( R
#define        RECTANGLE_VOL        (0x0F0)
2 m+ W; K- X/ |. g! u#define        TRIANGLE_VOL        (0x130)
: v  B: c# w; ]* i7 t#define        NOISE_VOL        (0x0C0)
$ A6 h2 h9 ~; u# w; W- O9 K: c#define        DPCM_VOL        (0x0F0)
% l+ N6 V* v, A- \// Extra sounds
% Y1 T. G! ]( ^# u+ P#define        VRC6_VOL        (0x0F0); e6 `9 R' _* e
#define        VRC7_VOL        (0x130)- q0 T, j$ n. t! c8 H
#define        FDS_VOL                (0x0F0)
3 B7 D) {. f# f$ \2 G* X5 _#define        MMC5_VOL        (0x0F0)) e* u8 d! P$ U+ s+ S8 O2 L
#define        N106_VOL        (0x088). D0 J" G. w7 F6 D+ ?/ k
#define        FME7_VOL        (0x130)! r8 I" [8 n. ?* i0 L. z: G: ^
9 u2 {! m0 k4 _7 w& Z3 d
APU::APU( NES* parent )
7 Y  I/ k' {. j8 d* L- H{
9 e. K( a9 T3 ]4 R        exsound_select = 0;
9 ^: T! D8 X5 ?! I4 T! _( A; a- I% f  F6 s" @7 Y
        nes = parent;' e* n, T# r+ b9 q
        internal.SetParent( parent );
3 |' [0 J0 B5 o  Q- Q  J
' P) I& i" T) N" Q. r. m* W1 j$ {        last_data = last_diff = 0;
- c  d4 g5 W1 I9 K5 M5 G5 F
8 {; h- S- R) y9 N3 U        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
# {" b# I" R) ^! V8 j: j* m; R6 w/ z# b
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );0 `1 W$ `, [9 _0 ?+ x
        ZEROMEMORY( &queue, sizeof(queue) );
% x# A1 {4 Z4 |, g7 `7 y        ZEROMEMORY( &exqueue, sizeof(exqueue) );
7 K" c, Z% G6 L6 B9 g& ?9 f7 ^! l7 W# o5 u$ [8 N( A' M7 F& t! p
        for( INT i = 0; i < 16; i++ ) {% @4 V7 w, T: p) k4 \9 ~* G- d
                m_bMute = TRUE;
: j- \+ I1 R0 I8 F% q        }/ |( v( Y0 W) ^, d: H: v& `
}
! p. D* a; ~2 s% e% P( Q6 `+ b. n5 I9 s
APU::~APU()
8 M; N! e5 U" ^$ ~" Q{. ^, B0 f. _$ D2 @0 o- ~
}
* r7 H$ A1 |) h4 J% f2 W7 \) E2 `; W7 o6 |# R& q" v& E$ d2 s
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
1 W1 t( n+ c. C7 e( O/ S" v{
6 n# S! m" J# V/ h+ V        queue.data[queue.wrptr].time = writetime;
% Q5 I1 ]3 d) F& K        queue.data[queue.wrptr].addr = addr;1 |) V1 a" d+ r# f! T, g' R. |' e
        queue.data[queue.wrptr].data = data;) ?4 ]5 p# _1 y+ N. R
        queue.wrptr++;: _8 ?4 `: g, C, d9 F
        queue.wrptr&=QUEUE_LENGTH-1;' }" ~! L3 v/ z1 E
        if( queue.wrptr == queue.rdptr ) {
! `7 r4 r) z  i- [) U/ b/ X3 [                DEBUGOUT( "queue overflow.\n" );
7 A: C5 c6 K6 }+ o        }
; z$ [- u: h6 [! ?6 r, O, I5 q) h2 C}
+ D* _# O! a+ o  S
" m% j; n0 z, R# a1 r5 pBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
: y1 f$ N/ J" L! |- X! R- S9 H{( {/ a' o  |! m; e6 ?# ?% I
        if( queue.wrptr == queue.rdptr ) {7 h# r; a( V3 w% m
                return        FALSE;
* H3 P: f5 b* J' \9 Q  q        }
/ t0 T7 B* Y3 |! h        if( queue.data[queue.rdptr].time <= writetime ) {
, W+ Z" }4 N2 Z$ w4 b                ret = queue.data[queue.rdptr];& j. L! Z: q6 \0 E
                queue.rdptr++;- r" n; V" V; H7 f: s* }3 ]
                queue.rdptr&=QUEUE_LENGTH-1;- q4 m5 ^  A; F: _6 s
                return        TRUE;
: k) }% A8 E& j* u, x        }2 t2 @- M7 d$ p2 Y7 j$ Z" p# N% w
        return        FALSE;, r/ M% w: `7 [& v. F& ?
}" ]0 L0 \* I; o2 ^
7 N& Q" o/ N2 x$ h3 E0 K* A5 t5 Y$ N
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
& y: j$ h0 ?3 K1 @{3 ]! `, ~% e2 I2 H
        exqueue.data[exqueue.wrptr].time = writetime;6 Y8 M9 S7 A, K3 E$ D) V$ l: l' l- ^
        exqueue.data[exqueue.wrptr].addr = addr;5 z7 J  e; U/ o: ~# f) f( l
        exqueue.data[exqueue.wrptr].data = data;
' V; Z& H/ p# m* p        exqueue.wrptr++;
( V! v- S. R1 ^* H; g, T        exqueue.wrptr&=QUEUE_LENGTH-1;' C+ r7 e5 j$ T+ Q" s* V: B5 z% Q2 L' u
        if( exqueue.wrptr == exqueue.rdptr ) {
  q: z; Z% H0 e; s% {                DEBUGOUT( "exqueue overflow.\n" );3 n, p8 w1 c  O: p2 {( V5 l8 s2 q! u
        }+ u8 @" N- z! l, M& o) K
}0 W  ^( l( M; G

% R, N3 U1 o0 H% O) _BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )0 Y1 P" W& L& E. p/ I2 m
{
/ X1 Q6 A2 F' M$ h0 k8 H- o; M        if( exqueue.wrptr == exqueue.rdptr ) {" B; t! P+ c  Q
                return        FALSE;
! U  h8 m- C& J( V+ I7 |        }
$ T6 p- {6 w/ [        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
7 x# V1 ~$ o/ \# B' o4 [                ret = exqueue.data[exqueue.rdptr];
) B" ~8 P( ~, ?2 a/ r& j                exqueue.rdptr++;
- \5 e; B9 J: N7 J                exqueue.rdptr&=QUEUE_LENGTH-1;, F* K/ j; a2 l/ R
                return        TRUE;5 H6 E" a, m, b2 p( Z
        }
3 v1 c, ^6 x3 [        return        FALSE;
, ~  {* _' z9 i' J! h0 b' y}
' V" H  A0 a; q5 x0 L! T8 A5 E# x3 Z8 p. b3 c
void        APU::QueueClear()! Z; @+ ?! l8 R6 t
{* {9 @4 z+ z, S( D5 q% l6 @
        ZEROMEMORY( &queue, sizeof(queue) );- ^* x; |& n: a$ |
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
. T& N) h7 k* f1 K: b}
9 J: z; ?: b- o; B6 `
8 n: Z4 O- y- f, p9 r3 ]void        APU::QueueFlush()
+ y3 D1 c8 _+ H3 E$ C1 `{; L" \5 U. P0 h' G$ U1 N" k
        while( queue.wrptr != queue.rdptr ) {# ^6 u- F, b4 L/ ~* W
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );/ _: `9 S6 `  o6 V5 `% o
                queue.rdptr++;/ f& k' U; O  Z3 G7 {
                queue.rdptr&=QUEUE_LENGTH-1;1 f0 r( b' m; n: h
        }
. \4 ^  r7 M$ e: e8 Q
+ ^. d* ^3 W/ ?3 B2 F        while( exqueue.wrptr != exqueue.rdptr ) {) s! n, c7 _1 P: L1 M2 e
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
8 g/ d* r1 j& H                exqueue.rdptr++;4 |( |/ M) k3 K, F  G) e
                exqueue.rdptr&=QUEUE_LENGTH-1;  d; w$ M: J( F, \, {8 Y# g& P2 J$ G0 c
        }4 ?: [' v. A0 A7 X, t3 `* ~
}
3 q$ y, e- x: ]1 y5 B. k/ g8 e2 _! J0 O8 h6 D4 f/ K
void        APU::SoundSetup()
7 n2 k0 a8 `) @+ o. v{
+ V; K6 b! ?2 S+ P9 V        FLOAT        fClock = nes->nescfg->CpuClock;
  i$ d9 _! I/ b        INT        nRate = (INT)Config.sound.nRate;7 Q( ~0 Q* B8 T% w8 g1 K- K# Y
        internal.Setup( fClock, nRate );
  I) m' q: E  Z+ D/ q        vrc6.Setup( fClock, nRate );
5 W& J7 k4 `1 U+ ?* O" x5 ^. P        vrc7.Setup( fClock, nRate );
9 U+ t  i0 z, g3 z6 U% r% R* X        mmc5.Setup( fClock, nRate );- e& @; M# Y1 t4 b% D
        fds.Setup ( fClock, nRate );
" Z. H2 y% k% K, [        n106.Setup( fClock, nRate );
$ W! x/ G5 a) ~6 @  l+ Z! h        fme7.Setup( fClock, nRate );
& I/ z5 v+ {' @0 n. s7 h1 F  U  J, e}
9 m. K7 h4 _3 q+ M; p- A
6 r# Y+ b4 v/ {5 g/ K$ i! Tvoid        APU::Reset()' \6 A+ \% _  S3 e8 I9 c# \
{
" c, g7 w: v. g. X& R* v        ZEROMEMORY( &queue, sizeof(queue) );' ]8 N2 z* Y" I: D3 v
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
' }' y- t/ u+ }. e4 {5 i& N. Q" s2 _9 p: \- ~) G0 f& C
        elapsed_time = 0;
1 E0 V; S0 X9 B( i1 X( s. a) f3 T4 C  R
        FLOAT        fClock = nes->nescfg->CpuClock;
. g9 ?$ ]* h/ Z# A        INT        nRate = (INT)Config.sound.nRate;, d% k4 C& e( g' A/ d- l
        internal.Reset( fClock, nRate );: O7 q* D; l/ J
        vrc6.Reset( fClock, nRate );- P  c: u  f* y, V
        vrc7.Reset( fClock, nRate );- v" s) U) P% I# D0 ?( E  Q
        mmc5.Reset( fClock, nRate );* _6 `+ n$ i/ _9 B4 H# L/ e
        fds.Reset ( fClock, nRate );+ u! z/ ]" S: X  V  y
        n106.Reset( fClock, nRate );  w0 g' M$ e# S+ M+ y: E' f
        fme7.Reset( fClock, nRate );; q+ I0 z% k/ ]+ D0 v; U4 j% h) r
% ?  d5 }% U2 }) H" _
        SoundSetup();1 {2 r% E- ~- d% L' N
}' Q4 }# J$ g$ h! Z& u/ ?
' ?6 ]$ u6 T( x$ p% c6 k% o1 }! _
void        APU::SelectExSound( BYTE data )
% e# E* A. W8 r: J3 I! ?{8 s, ~6 K0 W1 ^2 ?
        exsound_select = data;
# I$ [1 }" ]) L$ u. w0 [: A}
! P7 q( l4 I8 H3 B% a9 ?! C8 u0 d8 _2 j$ Z& @1 S. ]( l
BYTE        APU::Read( WORD addr )
8 @' Z- s7 A4 g. L, S{
$ Z% k& p7 g% e* e3 [' ?$ r- }. R        return        internal.SyncRead( addr );
8 V. T9 D% \+ B0 i2 _: g0 q}$ z! z4 _+ \+ S5 M: }5 X

! e  z/ l/ ]- U" ]1 M8 ~+ k$ xvoid        APU::Write( WORD addr, BYTE data )0 g& ~$ Y& k7 ?& M  k3 D7 |
{% x1 b, A7 g* l- t
        // $4018偼VirtuaNES屌桳億乕僩
! V# ?) R* L4 I1 n  t* `        if( addr >= 0x4000 && addr <= 0x401F ) {; q3 c+ @6 S1 C" G9 W8 i) K% B
                internal.SyncWrite( addr, data );2 D0 ~% [; F3 e" B- k& P, E
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
! P1 b6 O6 N  v! G! B+ |3 g8 Y( B        }, V2 p( [; O) `7 y: y1 ^% S
}
. k, v/ P9 z6 _* `. t  N( ?# s. y4 g' g2 x( R! Q
BYTE        APU::ExRead( WORD addr )- P. |2 I. Z3 m7 E. I4 |/ ]4 n$ S+ `# C  @
{; U3 b* U4 c$ p( R! t2 r# T
BYTE        data = 0;
8 q$ C0 V1 B6 ?# ], F
4 z; V8 q' d' K2 m! ~! z        if( exsound_select & 0x10 ) {
% X9 c% f2 l  x                if( addr == 0x4800 ) {2 q5 E* H: a1 S& x! @7 u
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );5 w( k: G" S0 x# ^: z+ |
                }1 T- q! k9 s& ?: }3 B
        }- v9 s0 |# p9 n9 I- d
        if( exsound_select & 0x04 ) {
" V' j. U! Z# m2 x: d                if( addr >= 0x4040 && addr < 0x4100 ) {
: H1 s$ X" s  E- N( Q: C                        data = fds.SyncRead( addr );) S) f5 `9 |3 K  x
                }
8 G7 ?" S+ q" R, C$ m. @+ B+ b        }- p- r! L0 I; G% h
        if( exsound_select & 0x08 ) {
5 [' S- Q+ G. u2 J/ M( Y9 P                if( addr >= 0x5000 && addr <= 0x5015 ) {( K# K6 \1 j" z$ P- N2 C
                        data = mmc5.SyncRead( addr );
- @7 ~- e! e  q- y' f2 h2 `                }6 D( O! ]( T5 E7 i4 k
        }- N1 {' E8 X$ @8 P5 F% b

$ ]. [/ {+ q6 K, a        return        data;
* g( n% c( O- s}/ t* S8 v! ^. m+ b$ N& U
" [5 f* M" L8 y% M' I0 ]
void        APU::ExWrite( WORD addr, BYTE data )/ \& ?6 A0 {) e( `: y+ Q
{
. R0 @  I* b& ?" E/ g' x4 P        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );6 ]4 M4 q- m2 k1 i

# F  x" p; X4 ?        if( exsound_select & 0x04 ) {6 J; U! W2 @- P+ {+ R* v
                if( addr >= 0x4040 && addr < 0x4100 ) {! P8 R' q# N( |" o! O- t
                        fds.SyncWrite( addr, data );
9 |3 C# ]+ Z1 G) b                }
& s( F. g! ^1 {. q9 J        }: t& e0 W- i+ \9 K) ~6 }7 r+ C
* m1 ~' f# z, ~* K5 L
        if( exsound_select & 0x08 ) {: |& z, V& T" \) C
                if( addr >= 0x5000 && addr <= 0x5015 ) {
, ?; q/ ~8 T3 |/ m% K                        mmc5.SyncWrite( addr, data );+ t; N, V  ]1 \) V
                }7 l; J+ j( \/ x7 E6 u5 g% y
        }6 k/ \% h3 d* s- }
}: B$ Z% k9 c0 Z) x5 T
6 r# L6 u9 q& e/ R! p
void        APU::Sync()# C: ^  @- z$ k3 Z# r0 Y5 f
{
' ~" `, g. k1 R* T: l2 \}+ c+ y: a8 m( t) @( U6 w# a

+ o) s: c7 n. Y; O* [- {void        APU::SyncDPCM( INT cycles )! j) L4 _4 Y. x
{6 s  q) ~* p7 t3 \0 }! A  l
        internal.Sync( cycles );6 b. Z, v0 [9 @$ G( p

( S1 n! w+ Z& G4 {4 e        if( exsound_select & 0x04 ) {. Y, I- `0 ~4 S- L1 a+ [
                fds.Sync( cycles );, U. Q6 m2 m8 c) G1 E" t" H* C
        }, s4 k+ l  B' W# v0 K
        if( exsound_select & 0x08 ) {
9 b9 D0 Y4 q: ~: @. Y; h) ]                mmc5.Sync( cycles );, u. t1 v/ Y/ X
        }5 W/ e( b( K- ~
}
; V" c) h- Z. H2 t6 f8 [9 e$ S2 S2 u2 [* ~
void        APU::WriteProcess( WORD addr, BYTE data ). z' K) r# E; A4 x6 i
{; t* T& M( |3 U$ S# m# V% Y
        // $4018偼VirtuaNES屌桳億乕僩
- V* M/ t. {" O' w! O/ [4 f        if( addr >= 0x4000 && addr <= 0x401F ) {
* X2 U% f+ P" ^0 O8 p6 L" j                internal.Write( addr, data );
9 @& S# g% S4 g2 h7 `# G        }
4 K$ _; r/ X, i/ `}5 k0 X. d. J9 Z4 `- Z

- `, U  P, g) h. o. Y. qvoid        APU::WriteExProcess( WORD addr, BYTE data )
3 F, J" R6 j. R6 E  d! G, q& t3 R% m{
7 {7 ^$ |1 n2 j        if( exsound_select & 0x01 ) {; {4 [4 A1 D. B1 Z
                vrc6.Write( addr, data );
# ]! X5 @* e/ M        }9 M3 t; v$ x& n# k( a# x. H, j
        if( exsound_select & 0x02 ) {, m* m' _! N# H7 b2 p
                vrc7.Write( addr, data );$ k9 B" F4 V+ ^) O' }7 y0 A
        }
) t2 F* t3 \6 i: R2 ?" x( {        if( exsound_select & 0x04 ) {
, f! X% ]0 N3 m8 o4 G* h                fds.Write( addr, data );
8 Z( [+ Q- z/ P8 Z3 A5 u        }7 S9 ^9 l  V% Z& ?
        if( exsound_select & 0x08 ) {/ }2 ]6 |5 b" ]0 n0 N: N" n
                mmc5.Write( addr, data );
2 G0 r9 f' j6 @& o* c        }
- E- [$ A" y) X# h        if( exsound_select & 0x10 ) {
: R; r( K7 X# w) t& S  J                if( addr == 0x0000 ) {
0 h2 A! S5 c; k( c! ~1 s                        BYTE        dummy = n106.Read( addr );
2 _: a1 H: B! d4 K# {; z% J                } else {
' Z! N7 Z5 w  e, J- p% M                        n106.Write( addr, data );
" g8 s2 t, v0 K3 \+ g" j- B                }
0 Y" ^0 V/ e1 d! m* g$ F        }3 G/ g( F5 l5 d( y" M' m9 ]7 X9 Q
        if( exsound_select & 0x20 ) {8 I- [3 H# X# c% [. J: G" g
                fme7.Write( addr, data );3 H# }+ p+ ?' X
        }
1 x' D, [7 o! [+ O' h. i4 z% P}
0 k: X2 d& e" B  s2 c
$ I2 V+ n' L/ e# H0 avoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
$ Q" L/ x* [$ F; K0 [% w& P6 V3 ]! L. z{' \1 Z- b9 z$ D$ \( Z: P7 E
INT        nBits = Config.sound.nBits;1 V$ M9 l0 m- O2 Q8 m: A* K
DWORD        dwLength = dwSize / (nBits/8);) r1 j6 L- H8 e  Z% w9 X
INT        output;
. i- F; u4 F& o" i% s. JQUEUEDATA q;
$ n: a4 ~( A- M1 A) K/ mDWORD        writetime;
  \8 ~' |9 }; b) d  O. W2 A8 M; I- a2 r+ S  C8 Z7 S- _: k
LPSHORT        pSoundBuf = m_SoundBuffer;, @' s! h" ~+ D# J, P
INT        nCcount = 0;
, s& {0 z8 o( ?5 j6 [
' B3 y9 R; f. L/ Q0 rINT        nFilterType = Config.sound.nFilterType;# M8 f+ e7 I; P# |1 I# ]$ R

3 W, m! w* f" K        if( !Config.sound.bEnable ) {4 Y8 Z0 \6 F5 v- j9 M: Y3 G
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
  F6 w" V6 V% T: J* j                return;
; a% E1 B% [- f! e- q4 S        }
: W) F1 D7 r4 F9 a
* h* u! N7 C( _        // Volume setup$ {! }/ e& p1 c7 E
        //  0:Master
+ \  R+ {# C$ w+ ~        //  1:Rectangle 1
6 ^- V. z' h) w; P5 |        //  2:Rectangle 2
# W8 j0 r3 L6 e3 J0 K" v        //  3:Triangle' ]# }4 p: F# Z9 }2 E4 d
        //  4:Noise
% z4 p% P' H( P5 `8 K        //  5:DPCM
6 v; ~" m4 D% _) F) ?2 N        //  6:VRC6! F0 m" D3 T3 J$ y! D. X
        //  7:VRC72 r: h/ Q. U  a  _0 y! H
        //  8:FDS
$ y/ S; M2 U4 J  k        //  9:MMC5
* O* {$ p5 ~% K/ u& ^        // 10:N106, v# I9 r; b9 T. \7 ^8 s9 P& {
        // 11:FME7+ [7 {; I5 e, i- I9 L2 s+ A6 I( o
        INT        vol[24];  ?: k3 Y$ x. g% M- \3 U& P: i
        BOOL*        bMute = m_bMute;' [: X+ b  ^: \3 j. y) f  ~5 p' v
        SHORT*        nVolume = Config.sound.nVolume;) j3 I! z# p1 x/ \. L
, \, `* I& q" y
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
, w; k# k) T/ s) W- U, S( v  R+ E9 u2 u/ w9 W, y
        // Internal0 _" I8 R: R5 `6 ?7 j7 k) \
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
' w1 k* t2 E& x& X3 b  e( ]        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
3 s- |. g- j. I3 E5 I        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;1 R6 ?7 q5 Z) Z7 n- e: r) e
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
% ~* u) U% u: W3 |6 {3 g2 y        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;, g; o- o8 I: k' x0 P4 v4 h

. N+ j% B( }6 V( g0 k: l        // VRC6
" S# C& H9 y& ?; k9 a        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
8 {  k/ z5 H( `$ P. m  I( H$ U" F  W        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;1 ]- o6 Q1 f9 r. X4 ]) I( F* U
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
- ?7 Y. |" [. j
6 e$ }  q2 P/ B/ l' |5 l        // VRC78 U2 k- c* ?1 G3 \3 v! J* p1 s, V
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
9 J: I) J& Z, E- {8 Q7 Z% t9 \" a, R9 b
        // FDS
; b" P8 q9 j6 I9 C$ a; Q        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;7 M) l# T4 }. _$ x8 B# l6 n

( |6 q+ x! O! q3 O# v        // MMC5
( y, G2 @$ t. s+ A' w( e* N/ Q: }& N        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;  r" n0 X9 I% U% e5 o
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
( s+ H* a% ~/ `. R        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;! }& y: O2 U- L# p' V4 @

3 j$ K/ N7 ]* _8 z( P        // N1066 u4 j7 C% x- }- A9 L4 S$ c1 ^% V! a
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
# \$ P/ l; |* e" {3 e5 }4 X" C        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' }0 l$ L2 J- z8 Q4 O6 j7 J  r
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;, T' [1 c6 R8 i$ A3 I# B( M1 O: h0 U7 u
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;, a! b/ F1 a# ~2 f' J- h
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
4 U- O1 @& U  e& D/ T$ o        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
# L: |: ^, D9 W2 U6 f7 f2 p        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' `! Y) O  B. l& L0 A2 }6 m+ k
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;( x1 n" ^: J8 d+ V7 q

/ |$ U+ P- ?2 s, J; k- p8 E        // FME7+ o# `: H8 f  J' G; D
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;% }2 p5 k. [8 E. n  z# G9 n' F
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
7 {& K# h# {8 }: O* @, M        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;" `! }4 J# v6 S) |
/ y4 `! |! ^; D
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
! c/ p$ d: `2 L. Y& D* u        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
- q3 O8 j3 ^! _0 x: T% P
6 i; ^  Q- k. b9 O' i        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
" ^) l9 ~) S/ ~6 s8 |9 c        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
( |6 I: I; {8 q, P, k: R! W                QueueFlush();
  ~8 C3 o4 k" y7 ^$ C        }0 o9 l4 f# j  U" I$ v

# f$ o+ I& F1 Y6 ^% e( W  h        while( dwLength-- ) {% w7 r. G( U' Q! ]% J0 o
                writetime = (DWORD)elapsed_time;  H2 d' b2 T1 C. F

" Q' h( U. B7 E% }/ V* Z                while( GetQueue( writetime, q ) ) {
7 @/ o1 ~( d& N/ y, ?0 X, p$ f" G                        WriteProcess( q.addr, q.data );; E# |* L- X8 i0 \
                }9 n. m# R/ ^& B- y
6 M. o: R+ d+ ~- c
                while( GetExQueue( writetime, q ) ) {3 p- u% A2 ^% `* Z
                        WriteExProcess( q.addr, q.data );- }% T. F6 |  R9 T8 l; u
                }0 W/ a* n# f7 L! M* P. s
" B4 r: f/ P3 a) ^: D4 f4 ?
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
/ e0 [0 d/ O- {3 {. k) ^  |# ^                output = 0;" o! V. K- B$ K7 I
                output += internal.Process( 0 )*vol[0];
2 s& f- ^1 u1 j2 y                output += internal.Process( 1 )*vol[1];. A; Y$ t2 C0 F, o
                output += internal.Process( 2 )*vol[2];
$ a7 j4 z5 R. G$ ~* |! h6 f! A                output += internal.Process( 3 )*vol[3];
( H- V( S" z7 g+ g; L( _                output += internal.Process( 4 )*vol[4];7 a( y  z. Y, [0 k  D. u0 _9 W1 c

: a0 }  Y# l1 h4 i, x                if( exsound_select & 0x01 ) {
3 V4 t7 V. y5 Y8 K" o5 q" a5 _" V                        output += vrc6.Process( 0 )*vol[5];9 [# w2 m) `/ P- f4 L" z
                        output += vrc6.Process( 1 )*vol[6];
+ ]/ p, @% s5 D  g0 v* V# b( G% N                        output += vrc6.Process( 2 )*vol[7];
8 a) I, V% G& z5 P# P                }0 o+ z6 K/ v: J% L  K
                if( exsound_select & 0x02 ) {
6 ]; c1 D1 k: l; T- x, H0 I4 x                        output += vrc7.Process( 0 )*vol[8];
* W8 x( j9 b5 w7 k1 C                }  L' O0 r$ W% d' W% X
                if( exsound_select & 0x04 ) {8 ?4 H: m/ U: O. M% _# ]3 F
                        output += fds.Process( 0 )*vol[9];% V8 l. P) @: `' D2 i0 n. B+ r
                }( C* H9 `# D# ^, @6 N( E% p
                if( exsound_select & 0x08 ) {
; f  E. J$ s3 j" n. P! j3 h' G                        output += mmc5.Process( 0 )*vol[10];
3 E) W$ u6 ~4 M4 R( B" r/ y                        output += mmc5.Process( 1 )*vol[11];
- r# I% J. w/ o7 K3 H6 ~3 n                        output += mmc5.Process( 2 )*vol[12];% a; x% m2 i: ?" s2 ]- E
                }
; x0 e* l+ F- o; W% h  a  D, J                if( exsound_select & 0x10 ) {
( o3 f% M1 P; V& d                        output += n106.Process( 0 )*vol[13];
/ r* X( }$ A/ G! X3 p* r1 l                        output += n106.Process( 1 )*vol[14];
- W/ i+ y' v( w                        output += n106.Process( 2 )*vol[15];: s1 R$ R1 K3 K6 J; C6 H
                        output += n106.Process( 3 )*vol[16];( z8 `' i! o3 o" l' b. x
                        output += n106.Process( 4 )*vol[17];6 U( q- O( W/ d5 ^) n& G+ S  w
                        output += n106.Process( 5 )*vol[18];2 C, i9 V. L5 O! _" ?( e# c
                        output += n106.Process( 6 )*vol[19];# A: A& M& X9 g+ B" y
                        output += n106.Process( 7 )*vol[20];5 ^3 y* B/ z1 O4 r, {
                }
7 e: U# @  I/ Z) [8 k" n                if( exsound_select & 0x20 ) {
  O$ z( ?! R  h/ i3 W                        fme7.Process( 3 );        // Envelope & Noise* ~8 i7 M3 {( ~
                        output += fme7.Process( 0 )*vol[21];
% b4 L9 ?8 }5 f                        output += fme7.Process( 1 )*vol[22];
- A" ?1 O7 d; R) q$ T                        output += fme7.Process( 2 )*vol[23];
7 M4 f+ B' `/ h4 V8 p9 w- H2 [7 k                }
; R4 p5 \" b2 w* U
4 d$ t- Z1 C! s& b* V1 O. e9 P                output >>= 8;6 k1 E% B) ], B$ ]

1 `6 m2 F* b( u                if( nFilterType == 1 ) {: ^4 `  P  k+ e0 ~
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
- L4 p+ q9 x* e% Y                        output = (lowpass_filter[0]+output)/2;
1 I; m9 G$ X) G0 g- b2 P, a& P9 }                        lowpass_filter[0] = output;
/ i7 P) ]. d5 s3 h- O0 i                } else if( nFilterType == 2 ) {5 K) _$ q8 Y" K) N9 Y# Y* s* h
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)0 m4 [( v9 J  p0 n0 @- ]
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
! x$ W+ P. r8 O4 m- s" F0 l! S: w                        lowpass_filter[1] = lowpass_filter[0];0 p. q. Q  `( G$ C
                        lowpass_filter[0] = output;: R( X7 T8 s8 {2 x* U. o
                } else if( nFilterType == 3 ) {6 {& M: Y/ x/ b
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)+ u+ L- z& y; G& G6 Y+ |# B
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;% R) |' t8 g3 G$ E8 O
                        lowpass_filter[2] = lowpass_filter[1];$ W& H) u' e# G, Q
                        lowpass_filter[1] = lowpass_filter[0];
7 V( V1 S5 A* V! l: q. T  [5 h: p                        lowpass_filter[0] = output;0 |! A7 ?7 ^. d7 J+ ^
                } else if( nFilterType == 4 ) {: s! A: Q0 L3 I& N: s1 X
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
' y9 h: ~6 Q! }$ {5 N                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
+ R) g8 \1 ]8 R                        lowpass_filter[1] = lowpass_filter[0];
! R! v, F1 h4 z5 T- f                        lowpass_filter[0] = output;
( B. y9 N. `4 q& @' S/ h5 j/ K                }' S+ R2 Y) O; v9 N

/ W# Y, e- @1 F! M9 Z#if        0
/ H8 P3 h- B$ k( r+ g" \                // DC惉暘偺僇僢僩1 J8 d* H: k; i5 M  b1 N
                {: p" I6 a( t7 \, b( p
                static double ave = 0.0, max=0.0, min=0.0;
( [. |+ v* y) _: v) V                double delta;9 V% e5 @0 c5 ^
                delta = (max-min)/32768.0;" G. @( ]) H9 K1 c. V+ \  f$ Q" W
                max -= delta;( M6 S+ `  ]8 F1 P5 X; O
                min += delta;0 N  Y  N$ q6 {+ V  M* K+ h/ E
                if( output > max ) max = output;0 F1 E) Z7 F1 ?+ K- i
                if( output < min ) min = output;
2 }6 H9 z" H; W, A3 J                ave -= ave/1024.0;
9 r: ~) v. S- T: ^, e# R                ave += (max+min)/2048.0;& `! N" _! C9 b; i3 z8 ]
                output -= (INT)ave;
+ Z9 T; i* a/ V1 H3 m* n                }) z& U+ u' f* `: P/ c' d& X  J2 w
#endif
$ O. N+ R' a# [" a#if        12 P7 P; ^* J1 @$ }1 a. [$ r
                // DC惉暘偺僇僢僩(HPF TEST)
& |9 E6 K5 Q$ I/ Q, v" C2 f                {, y$ A; |+ A7 ?& ^/ A, S5 T% r
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
1 S9 M4 d! x2 h7 {! d                static        double        cutofftemp = (2.0*3.141592653579*40.0);
; w  n6 Q" I% {0 }2 Z, o! y                double        cutoff = cutofftemp/(double)Config.sound.nRate;' g7 j0 W) m6 S( U* f( Q; b
                static        double        tmp = 0.0;+ S% F/ u3 [) i
                double        in, out;. d( \& e, ~) D" G) \

) V" d* k8 F! m+ x' U% |" c' w) @3 u                in = (double)output;& Q1 o% I4 Q- D6 Y- z
                out = (in - tmp);
/ e6 h( v6 y% n: f                tmp = tmp + cutoff * out;; Y; p1 I; Q3 e( Z1 J) B
1 H2 o& n6 U* A# D/ C1 |3 M1 {
                output = (INT)out;6 a1 X$ N) A  L/ U6 X
                }
5 \+ b1 y$ Z) V" K! @+ T2 O#endif
- I& |- r( t+ g! i" a#if        0
! F$ g- s6 ~" y$ v9 g                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)) y9 D1 Y8 O/ l$ M8 H4 }* b
                {
, Y. P' l6 a+ o                INT        diff = abs(output-last_data);
6 M1 U- X& T. C                if( diff > 0x4000 ) {
# V* J) r3 F! o5 y" M$ \" C- A                        output /= 4;
" {! g/ o2 x% t; c  ~) z                } else
+ N5 Y9 U9 K6 k  ]5 _                if( diff > 0x3000 ) {
% B# ?. }) l3 ?+ s                        output /= 3;
- U1 K' i3 _$ A5 N                } else
4 X: Y; B) F; D- F; x; M& _                if( diff > 0x2000 ) {
7 v" e; P4 M9 d: u6 L                        output /= 2;
$ z( `8 K, d- S) ~9 Z3 D8 R1 `                }
% H8 v% v  G; V$ [" Y. T7 X                last_data = output;
2 w  a+ X( }9 ?6 Y8 o                }
2 Y' V4 D9 G- h#endif( z* n" N! y. a3 }. O, J
                // Limit
4 f% W- }+ C0 Z+ @                if( output > 0x7FFF ) {
. [, Y# ]7 l  Z9 j" V: g* |                        output = 0x7FFF;* {- w  B! z1 u- L9 Q7 w& T  d
                } else if( output < -0x8000 ) {" h2 @9 ]$ x* B4 I3 ]
                        output = -0x8000;: D2 `1 F+ J* c
                }
8 w8 D) z# v+ f* S0 U, n
1 I, h6 I6 I- K1 q7 b8 O- E                if( nBits != 8 ) {
6 L1 _( W. v. _9 D/ B4 ~& H# [0 K; N! t                        *(SHORT*)lpBuffer = (SHORT)output;$ _$ _, r: }/ J7 i8 T
                        lpBuffer += sizeof(SHORT);0 T& Q# s8 B1 h- d* W. V1 s
                } else {9 k1 ^/ X" W; v
                        *lpBuffer++ = (output>>8)^0x80;
% e$ p+ e: w  G; i8 P                }
) p1 u& P0 k# h  u' G4 w( D0 H
                if( nCcount < 0x0100 )
) m" ^" t5 X) P+ _% d' |, e& }                        pSoundBuf[nCcount++] = (SHORT)output;
2 a: I' w3 n% ~) x6 J
7 w+ M0 q4 v7 M' x; m/ a//                elapsedtime += cycle_rate;
1 }& ^5 Z$ {$ a                elapsed_time += cycle_rate;9 ]3 ]% t( l0 S/ J+ j6 o
        }
! ?/ X3 r6 ~  _# n9 U/ `8 h  p/ I1 w
#if        17 o) e! L  M2 B4 M0 f* e" J1 i' j
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {# H; ?* ^! p0 s' S) f% S6 |
                elapsed_time = nes->cpu->GetTotalCycles();# P, Z' K; @9 x1 H4 ]( Z' U& V% Q
        }
  G* P& P$ j; e! e: ]' b        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
0 O: v' A0 K! E. f$ E6 s                elapsed_time = nes->cpu->GetTotalCycles();! V% h4 v$ ]* ?0 K* t
        }3 D# Q. n* D. Y& ]5 W/ B  s
#else
+ d4 s  l2 m% A/ b        elapsed_time = nes->cpu->GetTotalCycles();
2 {& x: P2 z1 ~0 w" i4 k$ s5 o#endif
7 X% E  X8 _3 {6 H( D, [6 t}% i( f$ u4 z2 O( p

8 S' m7 c) c& d  ]8 D) \// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
8 ~7 N1 Y% Q+ W% wINT        APU::GetChannelFrequency( INT no )
! f$ W# q8 J) N8 E3 _{
+ J7 a! c: r% V" L. H        if( !m_bMute[0] )
# I* `: Q, n9 R0 ?& _8 t8 C                return        0;  k, ]3 }" A, R: P9 z; C3 l1 q, x3 @
8 |9 _: Q# t" \0 A
        // Internal  b( [$ t; ?1 _7 ~$ M% G
        if( no < 5 ) {9 y4 R. ~' B8 R% n4 `7 u
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
: Z/ v+ l) {; W' U( J8 j        }
, t$ C% W  X5 K        // VRC6
6 W3 l  n0 e! u1 p        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {$ @" f9 }( s' j" D- c
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;; y6 y- s7 P/ U' N. N4 _3 [
        }' Z! C; x; q6 z8 k6 X) |6 s
        // FDS4 f! Q, X+ q* J  D2 O3 [7 R3 m4 w' v
        if( (exsound_select & 0x04) && no == 0x300 ) {
0 A& j0 v! d7 r4 r! I9 Q0 s: d                return        m_bMute[6]?fds.GetFreq( 0 ):0;
6 g) o9 K) u/ Z; W7 ?7 R4 w  p+ L: P        }3 s; C) l' K$ z
        // MMC5
7 Z9 v  B# f0 g! [; Z& g' h% Q        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {% C- u% l  z: n1 K$ P
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;0 _& b& a- S4 ^8 [% P! U
        }
. p3 ]4 ?2 [% u. b0 u        // N106. h- ]& Z5 l* l9 v& g/ M
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {; |6 p/ b( I/ N3 J. z
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
. Q. p, U) X' K8 @        }
; Z% o, m+ D# s/ D' E        // FME7- u6 F6 ^7 l2 k
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {( c: V$ K4 G' v
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
! T& t: K: ~! e4 |1 {( N        }
. y+ K, ~! V- b3 y0 r        // VRC7
. S1 w+ q5 @* F7 z  j# u" U        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
3 R* {1 L" r. K# m                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;! V' y, v' |! ?! i# _3 G( H" q
        }% ~7 M& p7 V+ ?0 f% Y" W
        return        0;
" X0 h3 W  C* k9 T2 t7 q9 ~- [( n}
1 C; u+ M: B; r0 D6 Y+ o. G
7 q/ `" X( s( P  A  u! k// State Save/Load$ A5 B4 N( ^' R2 M$ I/ i1 b, b
void        APU::SaveState( LPBYTE p )- J6 ^" T8 P- O/ \
{6 L, Q9 S% y6 i$ v( [# h
#ifdef        _DEBUG
% o' t; s8 o' X. Y( ]LPBYTE        pold = p;0 T# \% X- R! N5 a: f
#endif1 r/ M1 @' S. ?- T8 ?6 E- w# N
( ^' g2 S5 c. H
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
9 a  E; Y& F6 l# Z, F5 w        QueueFlush();$ }; G+ P8 k0 ]1 m! M+ ^8 @6 r
8 N% a% o; T9 w' d6 |0 e1 g
        internal.SaveState( p );4 u" H" y$ ^* p1 B" }9 j
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
) x+ w2 o. X! t
9 n3 H; `* j. S+ g6 g0 v+ D7 i        // VRC6' P' h" E1 z; \4 d6 Q+ t
        if( exsound_select & 0x01 ) {0 q1 y) p/ D( M& c6 [3 x
                vrc6.SaveState( p );
4 [: H; p3 I% x; @1 ?  g. w1 z) s                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding! b1 y  k" M, ?& ~
        }2 ?" a* B. j4 ~& q, O$ B: ^
        // VRC7 (not support)) Y/ b% S  k- c6 Y: w9 r
        if( exsound_select & 0x02 ) {+ O9 _! O% f' T# ?1 c& F: c
                vrc7.SaveState( p );
  S5 Z3 B# X7 e/ V& w5 O" ?) ^                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
& D  A- V/ }) R, q' Z0 E# Y        }# ?5 r6 r2 H4 i3 d* B: O
        // FDS
" p  \# c, r9 [( ?3 ~# W1 R        if( exsound_select & 0x04 ) {! L& Q. c& F7 z7 T; B- M
                fds.SaveState( p );5 O* F4 @2 c6 p9 }" s* Y
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding& H/ e5 H0 [- n( j8 i
        }4 [4 L5 E$ Z! T! ~0 _0 b4 `
        // MMC5
: L; r5 x' q* H- l2 ~  x! P        if( exsound_select & 0x08 ) {
- D$ w* c6 X  M+ o) ^+ O                mmc5.SaveState( p );3 H+ R6 ^# R& t; C4 C
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding% p/ R5 J4 [! w$ N3 Y3 H2 j6 c
        }/ F* @7 w4 W; d' O( F
        // N106. x+ J' N3 e% U9 J; X" `+ p* K
        if( exsound_select & 0x10 ) {
6 z; r2 ?& Z( t8 W0 b                n106.SaveState( p );! l$ H1 }5 ^8 |. ?3 p; B, `
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
: k1 d, u3 A! o# {  |        }$ h1 g% `- B% d. N5 B
        // FME7
4 o: `, i) ~  z0 }. A        if( exsound_select & 0x20 ) {
- ?) H& a. P8 c: ]/ e' i- U                fme7.SaveState( p );
: ^8 M' Z* M. p. m                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
% {( U' {" d/ J% K7 A& `        }
/ u6 b/ X7 Y& M4 E& ^: Y7 y/ e! J/ S& q  j* `+ e( T, g
#ifdef        _DEBUG3 m" M! m! A' ^; k
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
; n  u1 d  \5 q" ]#endif7 `$ D, V! n8 j9 U- I* O
}& {, Y8 o/ e- f! F' Q& C
4 [) i# H' L% q
void        APU::LoadState( LPBYTE p )
) T/ g  K9 Y3 S% u. Q- [2 _{
6 Z; l# ~' y) M5 d        // 帪娫幉傪摨婜偝偣傞堊偵徚偡( K+ [; r8 i& e% \
        QueueClear();' b8 ]. A+ A( J, @2 U

2 s! D# E9 s- ^1 A9 W        internal.LoadState( p );0 \7 G0 Z8 J& i$ [
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
7 f4 H, g" z1 t3 z. P8 k
5 [% n7 n$ a- G% F, p        // VRC6
2 `" o5 a- G3 k6 P        if( exsound_select & 0x01 ) {
1 P5 I7 ]- m/ R                vrc6.LoadState( p );
' S1 D+ C4 b& X9 ^) H) o  j                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
' u- e& X, l' }( `        }. I. w+ M- O  b5 _
        // VRC7 (not support)4 c9 [+ `- Z' }/ u
        if( exsound_select & 0x02 ) {
3 R( B- O# m  m* G                vrc7.LoadState( p );' K9 T1 U5 t2 g
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding) f7 i; E6 t& n1 _
        }
9 W6 V3 y2 L+ @        // FDS- W6 x1 _, S# w% `6 c- I% g
        if( exsound_select & 0x04 ) {
3 s/ B  o+ T& ]4 X. y& \                fds.LoadState( p );
0 i$ Q: |$ {2 N# O2 ^. h1 l                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
4 L+ V/ \. Q) [' N+ ]5 \        }! b$ a2 U7 B- h3 `9 M0 ?/ |. ~, z
        // MMC5- w1 b) n. t; ~) w
        if( exsound_select & 0x08 ) {$ _" w0 {# x" d; L& G
                mmc5.LoadState( p );
: A. E6 [$ ?9 i: b, U8 R- f. v                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding& D3 ?4 x6 x; ~! b
        }
7 b. @5 I& o7 m' _+ I) D        // N1063 G! c; z% V+ @8 s" B# l* {% E
        if( exsound_select & 0x10 ) {
. c% V$ z7 ^# _2 }, h                n106.LoadState( p );/ `# z8 Q1 v- z2 y+ ]
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
0 Z' S3 L  N. _" P        }
% p# I! U! l2 p0 ?0 }# ]2 {        // FME7' j  k) d3 \6 Z1 E
        if( exsound_select & 0x20 ) {
+ s5 f" f9 U  J                fme7.LoadState( p );
( f+ v, {: \2 X2 {: e, p' W+ B                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding5 O: e( G; L# |0 u( {- y& q
        }
3 E; u( h5 q0 c: a3 M* z6 P8 m}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 2 c* N; j& k+ l1 ]- J+ ]& _
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。1 A2 O8 `& B9 g: f
感激不尽~~

, |4 ^% T" }2 O3 `2 R9 Q恩 我對模擬器不是很有研究,' r, ^6 W9 L! I* r- i  g7 h6 C$ C
雖然要了解源碼內容,可能不是很困難,
) o$ r, f* L$ Y* t: e不過還是要花時間,個人目前蠻忙碌的。8 n2 a$ O8 q/ l9 |- V% A) G+ c$ N, }

+ |0 d0 ^2 ]4 Z% ?: v給你一個朋友的MSN,你可以跟他討論看看,
! W8 s4 j  w% ]4 G) M1 O2 a他本身是程式設計師,也對FC模擬器很有興趣。
& o; N) R$ @( _6 C8 j
2 D( {! w) p, v" LMSN我就PM到你的信箱了。- I" T  ~: X5 A% H" r
/ K2 @. J1 k4 m1 B
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
5 {  ]2 Q0 \- }$ \  X, ^4 O呵…… 谢过团长大人~~
1 ]! }8 ~& @6 P" y8 x4 `. T$ J
# @& g2 N+ G1 \* H& x( |) z7 g- a
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
1 f9 ^6 \% n4 l9 F3 P* \6 `7 s0 ~团长的朋友都是神,那团长就是神的boss。

3 |# u0 x* H' C: c$ X哈 不敢當,我只是個平凡人,! Q+ e$ D9 x) _! Q
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙3 j4 f4 K9 [0 ?' M& b/ d$ Y! v
ZYH( ]) A3 [: C, \
QQ:414734306
* d8 Z1 Y, }- G! H9 MMail:zyh-01@126.com
! G/ o: }7 Y; O+ b- i
" ^4 W2 }& x* n/ ]- h3 d他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 3 M* A$ E$ F8 t6 Z0 ]. ]
再次对团长大人和悠悠哥的无私帮助表示感谢~~
. I3 @8 g6 Y* h
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-9 09:37 , Processed in 1.081055 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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