EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
* V  a! D7 U4 ?: X1 p# O楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
3 }  I, g1 T) }' K9 t  `1 X这里有相应的模拟器源码,就当送给大侠了~~
" H. D( j1 Z& E4 b  {8 ihttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
- \, J" G6 X" ?4 _1 T能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。" ]# e1 |5 E$ T
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
% A, a" B9 X; U这里有相应的模拟器源码,就当送给大侠 ...
- ^2 J) V) ^) W+ g
聲音部分(Audoi Process Unit = APU):% }3 [, ]* p+ G$ p5 Z
.\NES\APU.cpp
8 A, v( o; M: _4 x: X$ E9 a! s( Y1 Q.\NES\APU.h
! f$ y" `- a& l$ _) Y$ y' _, `
2 x/ v2 g$ g) q! O" B* J9 w9 c( h0 {) p. W' e/ c
影像處理部份(Picture Processing Unit = PPU):
3 V  N# n3 ?; K# z. d/ i.\NES\PPU.cpp. o' p0 ~0 m0 I& C4 b; }9 }
.\NES\PPU.h* V! a8 I  `3 I( ^- A7 R
. S: w) s/ u1 C3 U6 [$ t! r% X
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
1 L' }3 E6 L& m1 M+ `$ T4 y; V感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:4 d/ T3 z6 z  ?4 l1 [, Z
(由于很多专用术语和算法机理都不明白,所以看不大懂……)1 e& ]" ~( N2 S/ J! s* K
//////////////////////////////////////////////////////////////////////////
$ b& e# z, ^- B4 M6 S8 Y+ g//                                                                      //
3 g2 ]! R% b& P//      NES APU core                                                    //
/ u$ _- a1 r/ w- s4 ]7 U//                                                           Norix      //. O" a# e/ q; _( y, m9 |3 A
//                                               written     2002/06/27 //! q9 I. c  p: R/ e1 k
//                                               last modify ----/--/-- //7 `/ `7 ^& X8 m" o0 a
/////////////////////////////////////////////////////////////////////////// Q+ R3 V, \  j" x# r6 G8 @. i
#include "DebugOut.h"
  _/ r* l3 }( U" g. q& p#include "App.h"6 A+ R8 e) W' B# s# z- v. y9 p
#include "Config.h"
1 Y9 Z3 O6 k. I1 j: ?. s+ I$ C) L( }$ E, g
#include "nes.h"8 {3 [$ z+ W3 e- l' [
#include "mmu.h"& a  _. f% b9 e8 H8 ]
#include "cpu.h"' z4 |5 ^1 h5 u; g; ^' Q
#include "ppu.h"( t: f( v8 }& X: b+ w# H* t; q
#include "rom.h"3 g1 e% ~' P" @) h3 l
#include "apu.h"% w+ u  e) F  m9 H; [1 Y) m

8 a6 ?$ T# z& |, h// Volume adjust+ R! M( g) [' h& D% ^
// Internal sounds
- ]6 J2 O$ z- P: C#define        RECTANGLE_VOL        (0x0F0)
3 x/ n% y2 u. a8 b8 l0 s, h#define        TRIANGLE_VOL        (0x130)
! u3 s. b8 s7 J& Y8 c#define        NOISE_VOL        (0x0C0)
, v1 z% v; Q4 l2 t! X#define        DPCM_VOL        (0x0F0)% c" K8 u' z& Y- D' e, u! U! f' k
// Extra sounds1 L2 N6 R9 {) ~# r
#define        VRC6_VOL        (0x0F0)+ K6 G1 Z. b' z( Z: o* J- p
#define        VRC7_VOL        (0x130)0 q. a" Z+ b& d: |6 Z) u7 i
#define        FDS_VOL                (0x0F0)8 f6 p' \4 k3 }$ X1 L
#define        MMC5_VOL        (0x0F0)/ }7 [' G( y1 z/ ?4 n( H8 W
#define        N106_VOL        (0x088)
  B! o3 |* c; F/ K& W#define        FME7_VOL        (0x130)- N+ ]' h6 \, s3 U: L
! {6 ?; V% ^# C4 d6 \3 @
APU::APU( NES* parent )
. n7 _/ w% n/ ]% A{# l7 _0 m4 _) w" p. a2 ?! Y7 F" O+ t9 A
        exsound_select = 0;6 _7 @7 P' K+ V7 Y/ d
# P* C. q9 a6 P3 b2 L% K3 W! ]
        nes = parent;
% i' y4 c& w  c& p! L( w        internal.SetParent( parent );
5 d" F% o1 ?" D
4 D$ `* L) G; H0 X        last_data = last_diff = 0;& ~3 c8 }: e. }8 }  u$ l# d( w1 X
7 {  ]2 \5 N7 k" q5 ^9 A6 O& u
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
" O  o+ z% ]5 [/ n  ~
' ?$ M' b3 Q' V/ l  R        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );3 b3 A3 ~7 J! k
        ZEROMEMORY( &queue, sizeof(queue) );
" T% N; C3 T4 u5 a* e% s        ZEROMEMORY( &exqueue, sizeof(exqueue) );
1 J9 `% o1 b9 b
7 |+ L( \/ h+ q: b7 C! @        for( INT i = 0; i < 16; i++ ) {# v* N$ x5 }& q( Q2 E  N' \1 M
                m_bMute = TRUE;0 d% {' N9 k+ ^: r# d( R
        }
. \8 r( s' a' S6 _$ b2 j! [# E% ]}
4 P1 |- `. w: |7 q9 ?  t) k8 b. l, {# w; I' P2 R1 E
APU::~APU()
8 X3 V9 p8 J# S9 ?: T! A$ P{
6 I' c+ I4 t8 R/ K: t) P! D/ B}* F; s3 X/ ~7 a% n- _

5 r5 z/ j9 i; S# evoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
; c" J" X+ `: n1 j% r{" b* X9 B7 p$ i; z1 ~' U" A
        queue.data[queue.wrptr].time = writetime;
# x. d, W, H4 `* G        queue.data[queue.wrptr].addr = addr;
+ L$ I9 m  a" y& ^4 i- l" f! W        queue.data[queue.wrptr].data = data;
3 U* b3 R$ V( f( F        queue.wrptr++;4 t* N5 k/ N: n1 z. \8 |) t! E0 m
        queue.wrptr&=QUEUE_LENGTH-1;- k  X% @- u) Y; B/ g0 G. o7 c
        if( queue.wrptr == queue.rdptr ) {5 a) z. }% n/ H
                DEBUGOUT( "queue overflow.\n" );
* c! X6 [2 F9 b) Q/ _. ^        }
7 C. T  @7 e3 A( X1 n}  S& j4 ?2 R9 P  i) Q# b7 U. q" R

3 J1 Z6 i; E! u. DBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret ); n4 ]& U) m* Z
{. t4 @+ s0 r; \7 b
        if( queue.wrptr == queue.rdptr ) {0 G/ W" b+ L! L7 C4 k
                return        FALSE;4 g. G5 g7 s/ E: {
        }0 q# q% ]$ X' r; X
        if( queue.data[queue.rdptr].time <= writetime ) {
; N7 F: F# ~* b6 x0 ~, ~% l) ]+ ^                ret = queue.data[queue.rdptr];3 n/ K$ H( o6 i0 a( M
                queue.rdptr++;
) w: A! j1 D4 O$ q% q                queue.rdptr&=QUEUE_LENGTH-1;
# k4 {% X2 w1 p                return        TRUE;
. O& q$ w) ^8 P1 \        }
; L# H/ \. f! o" l        return        FALSE;
. y3 M# @1 d( @$ d}
9 b! X1 l: C1 a9 r7 x( K- z
) Z6 Q2 y" g5 R$ U5 s8 h, o/ P4 kvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )$ z5 y7 i1 Y( I
{
2 g" d9 _  x' N. K% f8 V        exqueue.data[exqueue.wrptr].time = writetime;2 z7 x; y. P/ t3 m1 j/ t9 Z  h4 F' |/ x: M
        exqueue.data[exqueue.wrptr].addr = addr;
8 h- N/ h; {$ g5 g        exqueue.data[exqueue.wrptr].data = data;
" M6 |% s3 N, M+ h        exqueue.wrptr++;8 `& u; O( O5 \) L: c6 Y
        exqueue.wrptr&=QUEUE_LENGTH-1;! z# Q5 e! n) c7 v
        if( exqueue.wrptr == exqueue.rdptr ) {" T. D5 R$ P7 m# V: F
                DEBUGOUT( "exqueue overflow.\n" );
3 I) k$ z0 u! @- z, ]        }0 B9 a" X! f6 r5 V1 p
}! O7 P1 R+ W1 z" ]

, I6 H/ c$ X: Q# B" @5 NBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
: w) L" \4 ^+ I. X( B: V! S{
" w/ d' S. V% r6 i, e1 q2 U5 B( x        if( exqueue.wrptr == exqueue.rdptr ) {
1 X3 r) X. T! @& f. ~) n, e4 O                return        FALSE;
$ t2 h: D* Q% s2 v        }: X, T. V- A! K. Q
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {8 R( n; Y6 n9 n, e8 D1 K
                ret = exqueue.data[exqueue.rdptr];
4 M% z" n( S) E2 E/ n9 F) f! d- [                exqueue.rdptr++;
6 h; [4 [. E5 q. x5 {" ~# i                exqueue.rdptr&=QUEUE_LENGTH-1;
, M5 t+ G; t) y) D0 U                return        TRUE;4 q3 g$ D+ O( j$ c! J# k. _  p
        }* P1 Q9 T3 h+ o: ^4 Y. L' b
        return        FALSE;0 \: w0 |7 i5 \8 W, u1 v- Y
}9 D4 K: g! L# \! ]% I/ _, R' k
$ x; u, q4 D6 r8 Z( F
void        APU::QueueClear()" w& Z8 O$ }$ e5 `3 A5 i, O
{
- \" I  L- ~* P7 x' Q4 Y/ q        ZEROMEMORY( &queue, sizeof(queue) );! x  `) u- s- M+ L* {9 C; d
        ZEROMEMORY( &exqueue, sizeof(exqueue) );* t8 z( z3 E% ^. Q' |5 [
}0 V' x6 t5 ?" n5 m; y
2 Q. T9 v: X; s0 q) V
void        APU::QueueFlush()/ z) s6 t9 t" n% E+ d7 d
{3 `8 E5 y; c& [: r
        while( queue.wrptr != queue.rdptr ) {: b# v+ ]6 F: V/ }9 v! a
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
5 ?' o% W# P+ ]. I7 p9 m) J                queue.rdptr++;8 c/ l5 v" r6 ^8 z$ Q& N2 b0 b
                queue.rdptr&=QUEUE_LENGTH-1;7 E2 \+ I: W7 {5 c' k" c: t- x+ P
        }
1 o) q/ c7 G1 o9 ?. ]0 I& G. M/ U: L+ b( b- l+ E+ _! k
        while( exqueue.wrptr != exqueue.rdptr ) {. o; R! r% F: p# U  l1 g
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );. F" `/ x! O( j
                exqueue.rdptr++;
0 X; y) R# _- m4 ^9 [* R* \: D                exqueue.rdptr&=QUEUE_LENGTH-1;9 l  X  m$ f7 V, L' I
        }# o6 ~) n- L3 x0 c; E, R
}
. G7 l  R$ y) {( e& q- l4 `  H
/ z9 q2 D/ J  C" Pvoid        APU::SoundSetup()! A" Q7 z0 z  g9 y% T. t
{
4 @$ z' D0 ~' l* z' }' }4 y        FLOAT        fClock = nes->nescfg->CpuClock;. u* F0 u  y, a( X, @
        INT        nRate = (INT)Config.sound.nRate;
) a+ p/ R, E8 X9 O: Z, n! K) o$ s        internal.Setup( fClock, nRate );4 ^* O3 C1 X) D/ c# \
        vrc6.Setup( fClock, nRate );2 N& X! i, n3 ]# j% ]5 d( @* ?9 l
        vrc7.Setup( fClock, nRate );
0 U0 Q* |: B" K! I3 f) ^        mmc5.Setup( fClock, nRate );8 G4 a! }2 p$ F6 t
        fds.Setup ( fClock, nRate );
8 K5 X8 O% q) c        n106.Setup( fClock, nRate );. ]+ y% j$ ^# s+ P8 N: W
        fme7.Setup( fClock, nRate );
, e4 `$ ^& z- k3 I9 v: k- \, ?}. S6 o( q7 F: \% g
1 u/ x) b9 N. c
void        APU::Reset()
- I9 `8 W) b3 D8 {: \; d# z{
4 N# H5 y1 D4 {' W9 Y2 {' c4 a        ZEROMEMORY( &queue, sizeof(queue) );
  F1 m* p9 T( q        ZEROMEMORY( &exqueue, sizeof(exqueue) );. U% S9 ^8 [7 ]& y8 T

: G! T& G2 z  C$ Q6 A        elapsed_time = 0;
! B7 t" R& E' ~1 u5 S- ~' T# G9 ~# n- c' i
        FLOAT        fClock = nes->nescfg->CpuClock;
" b, x- @4 A! @' v. E! n# h        INT        nRate = (INT)Config.sound.nRate;
$ O% u. p; q9 q" G" Q3 G        internal.Reset( fClock, nRate );
, l1 g# Z% E1 j4 e3 u        vrc6.Reset( fClock, nRate );% D: [- W+ u' ~
        vrc7.Reset( fClock, nRate );3 L% X5 X$ y2 g. y- M3 M
        mmc5.Reset( fClock, nRate );
9 z- k6 P- D" T9 @. Q# K- X  I        fds.Reset ( fClock, nRate );$ |/ ^+ S  R5 x2 T9 t5 T+ b
        n106.Reset( fClock, nRate );9 J( G; |. Z; `( v
        fme7.Reset( fClock, nRate );
. S5 [. J3 u8 [5 Y0 v& z, `
4 g# n9 j" D$ r+ s+ u# |        SoundSetup();5 S; e0 i7 P. _3 }
}. n) R! ~) r7 ]- N$ s( i

9 Z9 V" M$ |( c8 @7 `void        APU::SelectExSound( BYTE data )
1 f" Q$ _2 U# E, I8 `. c% v) e{" r5 o/ E3 L2 ?/ b) \, H# l9 T
        exsound_select = data;
  z' K3 m# A* x) M% L}
6 D% M. L4 V1 J/ y! A& D1 W$ r% m' ~7 x" K+ u3 C; j
BYTE        APU::Read( WORD addr )
0 n4 y& O6 w' s" P7 I{
- i5 w6 ?" J( |! m: v, |: l: ~! i        return        internal.SyncRead( addr );6 Q$ L; Q5 Y; g- h, K* B
}. e* h' m' @6 B8 v: ?* z& Z: r* t

1 A% }. Q# f6 Nvoid        APU::Write( WORD addr, BYTE data )8 w- @9 G  X6 w0 h" W* N% D
{3 F7 l# {) g7 {' H; n" [
        // $4018偼VirtuaNES屌桳億乕僩. K) ~1 x0 @& |+ w6 v
        if( addr >= 0x4000 && addr <= 0x401F ) {4 ^3 I- L$ h* A
                internal.SyncWrite( addr, data );: M" Z! b0 V  i7 U9 T
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
3 J6 k" Z& `! T2 J( k# T1 L        }1 H4 ]+ @. _8 X3 c* z  U/ x
}) e0 a" i  m: D$ i6 C( ]
2 e: F7 Q9 p: f  n% y  m7 q0 H( F
BYTE        APU::ExRead( WORD addr )3 T% a9 F, M/ c$ z* x# T, T: x
{
# q  p) r- ]( m! i) ?. \1 k. xBYTE        data = 0;
' b9 ~& y7 B: R  z  C: O) q- e1 }% u; J6 U. H% i7 H
        if( exsound_select & 0x10 ) {
4 W, |) g7 b* i6 r& p/ F; r                if( addr == 0x4800 ) {
0 y& n/ j; Y  t1 V                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
3 M! C* z" u. Z' D                }
( T+ m# [& U$ B. I        }+ m8 L: |% U* {1 G6 I: Y
        if( exsound_select & 0x04 ) {* C! n. ^9 E* ^0 O& P
                if( addr >= 0x4040 && addr < 0x4100 ) {( c* ]3 L; V, I% b
                        data = fds.SyncRead( addr );
$ X+ B$ _6 \6 H. d% W; b                }
1 R0 j3 E! m. _4 F. l; {        }$ {  L5 d+ D4 a5 X
        if( exsound_select & 0x08 ) {
# k/ V6 O$ m: Z6 j# u                if( addr >= 0x5000 && addr <= 0x5015 ) {7 ~: `5 b4 F, W: j( [
                        data = mmc5.SyncRead( addr );
$ u: b! F! c' q- @                }
0 d& R2 ^# |( p! _        }+ v" `8 O$ E' l7 u- ~% C/ N, ?
) a7 y% `1 Z$ v& e- l! X# s* t. V
        return        data;' W% v: m: X& W& C: {
}
6 w$ E# M& ^0 a: [0 V, {( m, G' q7 m+ j9 T3 ]! f
void        APU::ExWrite( WORD addr, BYTE data )
9 Y4 I' K- n5 N: y+ u: p{; C3 q- R7 ~7 `' c3 }
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
3 V) L2 v  s& v% f3 E/ f3 c3 S5 i% D6 p
        if( exsound_select & 0x04 ) {1 Z# P' |; Y/ A4 g7 _$ s- y9 v
                if( addr >= 0x4040 && addr < 0x4100 ) {3 R2 ^* u& i- G2 h. i
                        fds.SyncWrite( addr, data );5 c/ G( u8 C9 l# S" w
                }
6 Q4 n0 r& a% G( F1 R# A3 t" t        }
( U/ p2 d7 M! f
& t5 I' r* V5 @, r5 S* ~        if( exsound_select & 0x08 ) {: H: {6 x1 U9 u' O/ q: j3 v
                if( addr >= 0x5000 && addr <= 0x5015 ) {
0 t1 \2 d* D; C                        mmc5.SyncWrite( addr, data );% D/ A; V! _, M. ^4 a+ l) V
                }" t3 T; v. W3 k" j( L+ w
        }+ t$ L  v" u7 @. o
}: r2 S$ e$ R5 z; V' g: Z

3 H& n4 }: n- _& Avoid        APU::Sync()
7 U2 M- T# B' a. D4 a0 D; |{
: }6 p# k# q* N" z}' e8 R- Y# H  m- A: r: F

( Z5 V" p' }& e. t% l( C1 kvoid        APU::SyncDPCM( INT cycles ); }3 h# T+ M4 c4 Z+ p
{( V" _# n  P7 i% N
        internal.Sync( cycles );
. |9 E! q7 B6 [/ N% |6 }: i
- X1 Z% n1 ~1 [. l; b        if( exsound_select & 0x04 ) {& F  B5 w/ ]. c$ K+ B4 o* x4 o
                fds.Sync( cycles );
0 B0 F# z& d) a, u5 H& L) r        }3 O+ ~# U4 I% x1 U
        if( exsound_select & 0x08 ) {2 X. t) V0 e, w" M6 j0 x4 o
                mmc5.Sync( cycles );7 n/ B2 ^; d- G. q- Z2 S
        }$ p) s3 Q+ \# O& T. [
}
/ a2 R% o; ?) Z' E* q  z( f1 M
; E$ U+ ~% `( X& F7 R7 ~0 Bvoid        APU::WriteProcess( WORD addr, BYTE data )9 Y! X0 n+ L, E, q. d
{
# V& j( Y7 W1 W" w        // $4018偼VirtuaNES屌桳億乕僩; s# l, {$ s3 Y! H9 W7 D+ D* X1 M( S
        if( addr >= 0x4000 && addr <= 0x401F ) {. H. u, z+ A% f$ |, L' Z7 A& v  P
                internal.Write( addr, data );! L6 j! y8 I  Y; ?* l( x
        }
* ]5 b8 l& `4 _7 Y& O}& j4 K: E+ I$ y4 I

8 C- s/ x/ d( {/ M* p, Jvoid        APU::WriteExProcess( WORD addr, BYTE data )
! K7 M1 k# ?- s{( p9 T" k( F- [: l
        if( exsound_select & 0x01 ) {
- I/ @$ N2 M  @. v7 f                vrc6.Write( addr, data );: u6 a" q: x) V$ X+ b, G
        }
" o/ J$ V! g5 `/ s; k        if( exsound_select & 0x02 ) {0 M6 ~  K9 K3 S6 T+ _- A
                vrc7.Write( addr, data );* [$ P0 V+ F0 S0 q) A" l* W; C# V
        }3 h+ `. Q% N+ r( y3 P: w
        if( exsound_select & 0x04 ) {
2 O' \, I) O/ D7 ]2 ~                fds.Write( addr, data );% z; a' g- V- h; p+ [
        }
( Y0 c+ a  M, [1 h        if( exsound_select & 0x08 ) {
1 G# ]/ q" ?: o+ E& T7 H. e. [                mmc5.Write( addr, data );8 A, w9 e9 t8 b( {
        }
: K/ }. \2 l7 L) A; x( N        if( exsound_select & 0x10 ) {& u6 a& v: K5 m4 h3 D* J, V' c' d
                if( addr == 0x0000 ) {
/ @* o' c. V+ |4 [: q                        BYTE        dummy = n106.Read( addr );
/ i# N4 [8 d3 {: `/ l% U( s                } else {
) W6 a0 j, ^3 k9 @6 F                        n106.Write( addr, data );
: ]+ J; t/ e: A  s  Q: [                }0 ]% G: C) l0 h: h( B3 L
        }$ P1 R; a& [; F5 o) ~
        if( exsound_select & 0x20 ) {; ?7 x+ b3 J& j7 M7 x
                fme7.Write( addr, data );
1 r% F2 |" }2 N1 r  m- I! N  N        }
! k1 J' v: `5 Q# I) F( }2 {}
) E! f+ g" D" P
0 |# _! ^- L) h# q+ n6 B1 xvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
% i+ B5 g# F# H( V+ t( _{$ ?8 ~/ k: q4 ?
INT        nBits = Config.sound.nBits;$ P. ~- y+ \. [0 Y8 h
DWORD        dwLength = dwSize / (nBits/8);
4 r! ^* p2 I1 j$ v2 F* mINT        output;4 n' ^& x5 r( V4 Q1 d
QUEUEDATA q;
" S; C/ h  @# x! `0 D# n5 X% @DWORD        writetime;
* a0 b+ m7 d2 c4 y7 |' w" C0 m
/ d9 c( o) ^% y5 K! l, d/ @LPSHORT        pSoundBuf = m_SoundBuffer;& `  t! c' p6 I$ t
INT        nCcount = 0;# \" C' H% @: b2 v& e* x: `! c3 [
* J4 N5 p, e: D2 h1 X) k0 V
INT        nFilterType = Config.sound.nFilterType;% \) z  p1 s. u3 I2 @" g* E* V

3 H( ^# z- T: X1 I$ T/ \6 Q; d        if( !Config.sound.bEnable ) {+ ]1 A  j. n* }
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );; U( k' U, b" W0 J
                return;
6 H0 M& y, F8 {5 E" q/ i        }
. s8 V" s+ N& l5 t' H7 R% l" }
1 o' n2 l" d, `3 n# {' v, N        // Volume setup
3 a$ L. h6 Q5 m) n+ R        //  0:Master9 D6 Y# u) W) n% _8 B) h: q8 h6 d+ A
        //  1:Rectangle 19 L) G! N+ P- a( o
        //  2:Rectangle 2% r, d$ h5 \5 Z9 [
        //  3:Triangle
# s  ^+ y6 N! t8 {9 \        //  4:Noise
8 U! h: t, X( n% ?. t        //  5:DPCM
: c  ]6 E3 u* ^4 e; l        //  6:VRC6
) V( e# l% a8 X$ n6 s        //  7:VRC7
9 N1 E+ f- k" @2 G5 |9 Z        //  8:FDS' T' A2 n! Y7 P- S* R4 I; Y
        //  9:MMC5
& q3 `8 |" r; w+ X9 v! @' M        // 10:N106% a; v: G1 y( _# Z, H% _+ ?8 \
        // 11:FME7/ z- V  W: }4 ?/ g* l8 p2 G
        INT        vol[24];) w) a5 a3 [5 ?2 U( @
        BOOL*        bMute = m_bMute;( U* u4 H* F# z& N9 F( E
        SHORT*        nVolume = Config.sound.nVolume;8 B, O) H2 O; {- o4 v% C7 C

/ g! O% U8 m- H5 y( ~# q" N        INT        nMasterVolume = bMute[0]?nVolume[0]:0;: F$ s1 G" Z. T' J- d

% k* X+ ~8 h2 ?- @  m        // Internal
5 i! [: z; r* ?3 }        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;4 |; x2 d5 V* I. Y
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;* ~4 J9 b( Z8 j1 q) k/ D
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
; B+ m& k; T8 z+ o8 T% {0 s        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;7 b& x8 f7 @1 s, J. E' |) x
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;6 C! X1 ?, @6 p4 E7 O4 V; x
2 Z! p6 ^/ i6 r- Y/ n: o
        // VRC6
2 ~& o. N: Q& _% t7 s8 k        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
: l3 W7 Q! u; b' G" ]        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;$ F0 q# O+ N7 `5 {* B/ U$ r4 ~
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;' q) q! J7 M  w/ P

/ y, ?( o# f) |        // VRC7
  D. x: I: X) y$ U$ ?: W/ n        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;6 `8 D6 R- @9 J) ?
6 e: L# W5 n7 J# b) h
        // FDS
" N8 c' v4 N$ Z# m6 a        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
: Y- @, d* d+ i3 N# b- k* g
, q' X2 f: _& V( a* {        // MMC52 g2 A0 ]! }5 I% g; i1 e7 [
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
+ J9 I  E, k2 t" o0 f9 j# f" r        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
' |! o* P; u8 O1 K$ @; f        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
! p8 i* h, Z$ r8 n* S4 ^) o, G9 H2 C( b9 B) k, \0 D# |2 i
        // N106
( N: [$ a: [" ?" O' V! A        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
4 W4 E, K& T" J- ]$ Y1 `        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 a5 k0 |5 o- T$ L- X" h        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;# k* a0 f% l' J
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
' |+ l1 T7 a( E/ F        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; B6 |* H) c, V+ g- v: H) q
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;  ^1 l" [3 Q2 e! B2 W; Q
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, P6 s: N+ r1 ]! }        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;3 y3 z" p& P9 O5 d. |
5 `; [& a, K, n0 T( E( W3 a9 f
        // FME7
' r% A6 Z" x& V# C! Y6 [        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;& Q( [6 F. u0 t# m8 y. s( n- V
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
& \2 p1 T& y8 t7 g# h        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;! E/ e3 e8 k( b" b4 s' B) C+ u

1 x6 N. r- q& W, S! K& W. t! Z; t//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;2 z' Z6 a+ R) R; C
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
- S3 P( P( x7 K$ K8 S# k( c3 n
# K! z2 I0 A$ c- c' F. U        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟" b8 V# n* L* _0 p
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {; Y" ?4 `/ g3 k8 p4 {. n) w
                QueueFlush();) U1 j8 ^0 `9 X9 g# U5 g% y$ m) T2 r
        }; i) L+ P+ G$ m2 t4 ]

8 S4 P" C' g& h, \        while( dwLength-- ) {! h. K2 e: W  T3 M' E
                writetime = (DWORD)elapsed_time;
( n0 r) r& V+ _8 V% s* F, a  X) C" M& P/ a3 D
                while( GetQueue( writetime, q ) ) {& T, W* x" Q  b, \% l( m0 u
                        WriteProcess( q.addr, q.data );
* w( D" }5 F9 ~3 ~. H                }
' I  f+ R9 J+ a  B4 w" S- ], ]3 L/ t! s/ G
                while( GetExQueue( writetime, q ) ) {
. O" Z; y' R! q: [+ n                        WriteExProcess( q.addr, q.data );
/ U) \2 Z' h: @6 P1 f                }' [" z: v. q' C3 U" [& `
  u- s. K) Y' J  G9 h4 {! ]
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
2 d/ u' B5 b8 g8 c6 N4 }+ u% X, @- D                output = 0;6 \4 y- p/ `* t3 ?4 Z3 m$ T
                output += internal.Process( 0 )*vol[0];1 G2 I* L( ~' z+ _5 M4 C  A5 A$ _
                output += internal.Process( 1 )*vol[1];6 a9 R' M" P4 k( |' x1 J3 `
                output += internal.Process( 2 )*vol[2];
% D; }3 W% X: n  V* \( ]+ h  z                output += internal.Process( 3 )*vol[3];
; t' o* o: `. R                output += internal.Process( 4 )*vol[4];
( o9 ?' i( `0 W% e* h; n$ ]( a. v% ?' w2 ]; ^
                if( exsound_select & 0x01 ) {& j' J& T3 _! }' q
                        output += vrc6.Process( 0 )*vol[5];8 B8 K& Q3 ?5 n( m. `( ^
                        output += vrc6.Process( 1 )*vol[6];
/ n7 g1 C3 o& c4 v1 A; t- ?                        output += vrc6.Process( 2 )*vol[7];8 t" y' R+ H! A$ Z
                }3 J5 t7 _, X8 V4 ]( Y5 y3 j# b2 B: D
                if( exsound_select & 0x02 ) {& L3 h& h2 b5 C9 X# Y: L
                        output += vrc7.Process( 0 )*vol[8];
' w$ j0 g' X6 p; @                }
/ B( x3 T* o1 r5 w                if( exsound_select & 0x04 ) {
; X4 {& M. ?# n                        output += fds.Process( 0 )*vol[9];" L& }9 M3 p) k" L! u
                }' s: k9 L3 m- S
                if( exsound_select & 0x08 ) {
- Z7 q" x, h6 B) ?                        output += mmc5.Process( 0 )*vol[10];
& f3 j) \4 [- o3 F; W+ N8 W                        output += mmc5.Process( 1 )*vol[11];$ g* H! r5 g; f0 g& }8 |
                        output += mmc5.Process( 2 )*vol[12];  R& C5 L. c4 I% L. \- j
                }# R' O5 B) e  d" j+ `$ K
                if( exsound_select & 0x10 ) {0 @, @, [9 o6 R* ~' s& _, h
                        output += n106.Process( 0 )*vol[13];
. ^( S9 t3 ]1 V1 F                        output += n106.Process( 1 )*vol[14];
( O5 r( `% s; j) |, V                        output += n106.Process( 2 )*vol[15];- \% i0 a' S5 k+ F
                        output += n106.Process( 3 )*vol[16];
: w$ O3 v# p! R- Z; G                        output += n106.Process( 4 )*vol[17];! ^+ U7 i* }& w$ x+ b
                        output += n106.Process( 5 )*vol[18];
( R7 C! w2 R) S& z* n* ]                        output += n106.Process( 6 )*vol[19];
. z6 f" x$ M2 g. Q$ B6 G1 {                        output += n106.Process( 7 )*vol[20];4 a3 R  Z1 N7 J
                }
1 N/ V# u* c* _) T) ~+ f/ Z                if( exsound_select & 0x20 ) {8 ]% f7 Q8 Y4 a- ]0 J. Y  A
                        fme7.Process( 3 );        // Envelope & Noise
7 a# ~( A! M& {: b, o8 L                        output += fme7.Process( 0 )*vol[21];3 ~$ c5 u7 w  X9 J4 {3 v+ w
                        output += fme7.Process( 1 )*vol[22];  I$ i; B- R! ?; }2 A; r
                        output += fme7.Process( 2 )*vol[23];
. C3 S  }( q0 Q. V                }
. C/ @- \: y1 G1 F. _' j: k% R$ A: B3 p6 B
                output >>= 8;
3 ]7 E. F+ Z/ J, O1 I8 t2 [
" c5 n. s6 G  R' c- @! m                if( nFilterType == 1 ) {8 k5 B$ G$ K- l+ [0 `
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)" \+ Q( A/ l3 ?0 v. I1 e0 _* z
                        output = (lowpass_filter[0]+output)/2;
; e7 G  L5 ], {! R% ~4 _4 y* L                        lowpass_filter[0] = output;: M9 n% s4 z' s: S( X+ X
                } else if( nFilterType == 2 ) {) H: J6 b) F4 E# _) y/ K) B) F
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1). }- g  e% ?+ g$ f
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
* a6 n' f! l$ H                        lowpass_filter[1] = lowpass_filter[0];% E( r% Z4 P3 x3 |5 @' W
                        lowpass_filter[0] = output;8 o' x$ S4 @: V" h* e0 \* w( H
                } else if( nFilterType == 3 ) {
2 y. r8 {& I+ h' V                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
* X' ^6 H0 h( j* e# k/ z                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
- H5 ?& ~1 K" H; O                        lowpass_filter[2] = lowpass_filter[1];" n1 D1 x3 P1 k- y7 D- q
                        lowpass_filter[1] = lowpass_filter[0];
! R' a% S$ e) J0 R6 ^0 t) F                        lowpass_filter[0] = output;
! m$ S* r" s1 B% X* ^                } else if( nFilterType == 4 ) {0 _/ i$ b0 E2 U
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)0 S# s. N; M9 s% v
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
; ?4 D" [$ u9 w4 {3 J  n9 f                        lowpass_filter[1] = lowpass_filter[0];
8 Y: v6 D6 L' C0 U( t- p! O, k7 W# }                        lowpass_filter[0] = output;" R  m5 p, H& k4 ^2 x
                }6 K: d% y  x, K+ T; w) v* I
1 X) E  z: _* r" W6 Q
#if        0$ u5 O2 v, A+ b& y
                // DC惉暘偺僇僢僩6 s8 f9 g1 t( U: u
                {
5 D) H6 P6 X- _5 z: K9 V7 M' ~                static double ave = 0.0, max=0.0, min=0.0;
$ l# \5 Q0 k. b2 L8 t# c                double delta;' {" a: l" q1 B* F. \
                delta = (max-min)/32768.0;3 c+ {% _! _( N% M
                max -= delta;& |& G& l* Q2 I. v
                min += delta;
, d9 w# U% A) _8 l2 g                if( output > max ) max = output;
* `- f! |& ~3 W                if( output < min ) min = output;9 @) ]* \7 c+ n! N6 ]
                ave -= ave/1024.0;/ e4 S/ M- _7 j+ d4 D5 d- G# t# M# `4 {
                ave += (max+min)/2048.0;6 k- b3 b% [- t; |0 v7 w+ k
                output -= (INT)ave;1 R9 j. I$ d6 q' P2 [7 B
                }: G+ l, ]. O4 D) x" L  W  [1 g
#endif0 U' a) b& C$ S5 F8 R5 Z/ A& q" `
#if        17 ], X: v1 J: d/ c% l
                // DC惉暘偺僇僢僩(HPF TEST)
" \# S7 D( p( ^8 r  ~8 y                {
( q  c- f0 a# A0 _//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);. [% q& |6 U/ j0 U$ j* K
                static        double        cutofftemp = (2.0*3.141592653579*40.0);! Y  m! Y  O1 w7 p$ l1 f7 H. s
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
' r  X6 h1 B4 o3 C" [) ~) R  N3 O" p                static        double        tmp = 0.0;
- I& [) }( I7 s                double        in, out;1 E6 e8 K5 b+ d

9 R# d# y3 c$ O  M( m" Z                in = (double)output;
% W: f$ \# O" |                out = (in - tmp);- v; {7 j9 B: S
                tmp = tmp + cutoff * out;: ]5 A+ j$ @7 `5 E8 {0 i

, M6 l& r0 Q) a. Y5 o                output = (INT)out;# Z4 `" p: o% a; Y' ?; ]0 r0 C
                }! ?3 w8 ?' l: s6 m' k( v. V' l
#endif
; X/ D1 D. U0 }+ K4 v1 z) e#if        0
: f7 [' @! ^% v6 I5 F                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)* Y! E2 Y# ~& P- t1 E- i4 E
                {
2 K) Q( A% n7 H* z& I                INT        diff = abs(output-last_data);
% a& H( v3 Q0 [1 |                if( diff > 0x4000 ) {
8 f1 }( ^4 m! V8 r" ?                        output /= 4;" D3 u: W7 W1 m! h3 v0 Z+ U
                } else 0 h% K! ]' Q3 v3 G/ Z0 E5 P
                if( diff > 0x3000 ) {0 X0 H, T$ A' L- A( T/ X" [
                        output /= 3;1 `1 m$ D2 w% S4 J: x7 ^
                } else
" h/ K0 N; n4 ]+ U+ e                if( diff > 0x2000 ) {
, d* t; p  `' i$ T" t# K                        output /= 2;
5 Z( h; E) W* l, g                }
" C' n; {9 m! ^1 G( v                last_data = output;. g( J, r1 g$ R6 B( Y
                }; V9 Z, M9 f! h, F' H7 r
#endif
1 Z! L' ~  F* u, l                // Limit
0 i, J0 u$ {( s0 C                if( output > 0x7FFF ) {4 o, l, I5 `1 X: b9 _% j* ?
                        output = 0x7FFF;
6 C, U# `. _: k! y. }* ?: x                } else if( output < -0x8000 ) {
) _" x! K4 j1 u, v                        output = -0x8000;
* o) h/ v8 t) X                }
" A9 U# e7 g7 o  E0 ^7 N- E* B, t' }
& F1 i# R9 @: Q3 q: s                if( nBits != 8 ) {$ i1 n( C8 v6 r; C; i
                        *(SHORT*)lpBuffer = (SHORT)output;
! a  ?' O* }$ y; f8 ~9 n. \                        lpBuffer += sizeof(SHORT);2 J; C; {6 ]- g5 ~) q! G4 Z: |& _: @, L
                } else {5 w4 S5 W3 w0 M. L+ ]% t' i+ b+ p# N
                        *lpBuffer++ = (output>>8)^0x80;) z! y$ d) G: O  l# m
                }% M4 k6 t8 T6 L6 R" q( ~8 z

$ S( S' E+ W! M% Q) C                if( nCcount < 0x0100 )
2 v' T( e. [  P) j( N+ B# I                        pSoundBuf[nCcount++] = (SHORT)output;
: ^* `( g# ]' L/ a4 U+ A2 p: L5 @
7 w3 _6 B# u$ p0 H: O2 I) V( j//                elapsedtime += cycle_rate;9 U+ o' b  z& Q4 [( i
                elapsed_time += cycle_rate;$ f. M2 i# t; f
        }9 q1 E7 u8 k! s8 G* `& O

! G; h: t/ \4 a- `) N#if        1" }5 @3 J1 I6 `
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
9 `7 U9 m8 ^' c                elapsed_time = nes->cpu->GetTotalCycles();
$ W! g" l' m6 b# h! C* V6 `' B        }
' a0 J( i0 g+ x$ f        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
4 m5 M/ H1 g. C/ z- r9 I! z9 |                elapsed_time = nes->cpu->GetTotalCycles();
  M1 w4 [3 w$ L        }
: ^: D4 w1 B3 H! |: o" r& R#else  a4 e4 w1 Z$ A" Q& T
        elapsed_time = nes->cpu->GetTotalCycles();6 T" g+ |8 a/ l: @9 f# {
#endif
1 H8 ~2 u' C. y2 R( h- S}
9 n: v5 Z" c/ C' q6 L% J( g
+ M$ F& i% I. ~; o# ~9 t; _// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
& J& @9 Z6 x9 c" g1 e/ xINT        APU::GetChannelFrequency( INT no )
$ s: m5 g/ K7 U: f  _" ?{, t/ X5 k1 n+ b
        if( !m_bMute[0] )
4 z" Y& b: W, d! @6 P! l4 ]                return        0;2 ^' a/ [* @' {6 o

( x' j! ^8 b( L        // Internal# S/ ]/ g* y5 k9 `; {' Q: B' \0 ?
        if( no < 5 ) {6 c& G3 q3 F) h) v$ Y$ k$ y0 Q
                return        m_bMute[no+1]?internal.GetFreq( no ):0;- S' i) E3 ~% k* E0 _9 {
        }; @9 U; Y1 g. x( r( s
        // VRC6' \9 F: \  g, e! ?% _/ K  h$ w
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {. @* ^3 x  \) l7 c0 C0 y) F' z
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;0 o$ x0 R( v% S* j; }: q
        }
7 @" g% F; [3 p0 \# B        // FDS
" U$ }5 \7 O7 [6 }0 A- G- t        if( (exsound_select & 0x04) && no == 0x300 ) {
. n5 p4 Y" p: F8 v                return        m_bMute[6]?fds.GetFreq( 0 ):0;
+ l  M# F2 O( K) x        }
: Q6 w: v- z5 e( l! c8 e        // MMC54 ^) p1 A: L( m! F  Q/ _. H  p* J
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {# f# a" r, u  P
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
3 N1 ~" Y9 r% |/ j9 G        }
3 W! V4 s3 O# Y+ b2 T: P  v: ~        // N106; t2 `, s2 i9 M3 |& G
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
! _$ z8 ^* \, f+ g7 b                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;: F% b7 u6 P' }% A
        }
3 u/ L7 ~( ?, j/ `        // FME7% w9 U" r, P# [8 {7 T) R" n2 L
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {+ N5 @8 Z% A: x+ ~0 y$ Y( `- s: i
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;! d; Z' k; R6 v1 I/ W# ~$ G
        }" V6 Q1 W, l- S( C0 ?- N
        // VRC79 C+ g2 m. ^% ~7 R0 w
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {% \8 F% L1 X$ o: |6 S5 n5 C% c/ {4 A
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;$ X7 n- V% ^( {) R( g5 U/ N+ T  C
        }) `# `9 {3 D7 `
        return        0;7 @$ v- Y. u  p) T
}# d5 o8 P) R: z1 k( C

! E' G4 ]4 X3 X% z& ^// State Save/Load4 _- ^. K9 z$ t( x* @% u8 ~
void        APU::SaveState( LPBYTE p )
7 C0 A, t- Q) }/ `{% j& C) a8 Y  Q8 l, s3 x
#ifdef        _DEBUG
. o. D) @' C2 Y% R, QLPBYTE        pold = p;3 \5 l) ~. z- Z! J1 X2 a9 _3 h
#endif6 a3 k3 H  @8 v( z
2 R& E$ G' h$ _  N. r6 I
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
) R( ]( D$ {2 e" p# z$ z        QueueFlush();/ ^/ @' ?9 O( Z) L- e- `# o7 k

9 f% O; v5 w( S' d        internal.SaveState( p );
/ E2 E4 e" e" z7 C: n1 D) T; b( j        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding3 r0 h* h7 Y! d) Z- K. c0 E

0 e2 x4 M/ U+ k7 A        // VRC6
8 f- S0 \1 b; M1 A: R' X        if( exsound_select & 0x01 ) {9 M6 Z3 J+ |: [; H
                vrc6.SaveState( p );+ N/ U; k% S; t: P
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
8 e5 j" n& S6 q4 Z$ @: w        }
4 h0 W, h$ i+ v+ Z  Q/ I        // VRC7 (not support)
0 Z5 [+ z1 R. m/ ?        if( exsound_select & 0x02 ) {
5 e$ ~* U5 {2 E4 N. h1 N                vrc7.SaveState( p );( a; P# L" z/ W1 A- a9 o: o
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding2 m" W' H& F  T
        }5 B" E8 }& A# c2 ^  K$ ?: u8 K
        // FDS- i1 O% h8 e& O3 p
        if( exsound_select & 0x04 ) {
: z0 H! Z/ @* ]9 m                fds.SaveState( p );" M4 b, S) e* e5 ]* n: n9 I
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding: z3 t; r  b, t0 W) o* L
        }5 c. [" p# x$ v2 o3 [
        // MMC5- |6 [8 W2 r! [4 b9 `3 m
        if( exsound_select & 0x08 ) {* Y5 j/ d# v4 J$ }3 ]" f9 W
                mmc5.SaveState( p );
+ p6 a4 g  |* u% \3 h( P                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding, \% V! U3 B% c6 P
        }7 |# r: t8 a( ~* p2 i) J2 y
        // N1067 N) [  \8 }7 Q/ r0 C8 Y
        if( exsound_select & 0x10 ) {+ }$ a, r* l. t" r& E8 ^
                n106.SaveState( p );. {6 r' Y" {& g' ?
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding- y! H0 [8 \6 M; ~! D. `8 L5 e7 Q
        }1 x  G+ }+ U% P2 b/ S" U( o4 E
        // FME75 y% h+ ]& j) B- z  i( B
        if( exsound_select & 0x20 ) {1 `5 G5 \" V; K8 b# ~2 b* Y( ^
                fme7.SaveState( p );
, k  ^+ N; ]2 @/ l9 u                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding* e' ]0 J  H3 R, D0 a8 c
        }2 h  G$ o0 k6 k' O6 v) u3 Y. n9 g

4 u; M. Z( Z3 s7 @, S* @#ifdef        _DEBUG
1 Y" g5 A. W. ]# jDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );$ V1 d, H' A+ i3 h0 Z
#endif
! m4 k- [, t. U) k( w% J+ O7 z}
/ @' I$ r9 j/ ]6 R: M& o8 C3 B4 N/ f( Q' u7 y. `, H
void        APU::LoadState( LPBYTE p )
4 ~+ P- B9 o4 @{
: P. s: @0 u  E  a# J        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
; H1 @$ O- w. P- g( g2 ~        QueueClear();
" u6 w, a) e9 [+ g& T2 B4 U. v  s' O! u( d
        internal.LoadState( p );& j; ]9 V; p8 n
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
- J/ m0 l" j) J/ P0 q( U9 S1 E7 Y& h2 q- Y
        // VRC6/ @3 Q4 U! I1 g6 [* C1 j
        if( exsound_select & 0x01 ) {
2 H. G: A- R) j! S5 e+ M. R                vrc6.LoadState( p );
3 n- s- b' w' b+ [9 _% B/ l. A. a                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
' u) h$ ~- b/ M        }
+ R9 R. A- A* C: }        // VRC7 (not support)1 l3 b0 N% `( C  [1 y4 _& N: t/ P; g9 k
        if( exsound_select & 0x02 ) {
( i" z: }. a0 d( d$ i  U                vrc7.LoadState( p );! j( j$ h" ^2 @1 S1 ?% b
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
. _& o4 c8 A! Z1 c7 e  y  p0 ~        }$ h/ i/ t+ G4 ?% R6 l$ E7 W
        // FDS
$ H% s) E; V7 U) D# N: \        if( exsound_select & 0x04 ) {" j( B' E( F# x$ i# j- f
                fds.LoadState( p );
- n/ a9 e: }6 L8 d% J                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
2 n* G/ o/ A& V. V$ C+ C6 R        }
$ Q3 j! e: F# f/ d        // MMC52 {8 @& h, }: ^$ N
        if( exsound_select & 0x08 ) {+ f  n" J) i& B, @/ U2 m8 W
                mmc5.LoadState( p );
- }, ^) z( E3 u4 U" Q' F                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding; X- Y; R# Z. |
        }
) o. Y0 {9 ?% Y, [0 W        // N106; y5 t2 `6 I$ A6 U: l5 f
        if( exsound_select & 0x10 ) {
  @% z, ]8 F6 b) M# }                n106.LoadState( p );; P& D, T0 k$ I4 O; d. ^
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
6 Q5 K' C; `( |  g$ Q        }9 _* k  {8 A. F% b; S4 @
        // FME7" z3 P8 R; ^; d" o9 X8 h5 ^% [. K# r' ^
        if( exsound_select & 0x20 ) {" W9 H5 H! F% i
                fme7.LoadState( p );3 g& \6 p9 F( o$ f, B
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
) n6 c4 M1 X6 p1 \6 p$ y, R$ y        }7 n- ?) E1 @+ D( W/ V
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
6 S4 B6 Z4 G: F: A9 s可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。3 B6 ^. f8 j/ A2 ]6 M
感激不尽~~

* }5 X6 f+ q2 w/ w恩 我對模擬器不是很有研究,
2 I$ l: h1 q9 A3 x4 W2 t雖然要了解源碼內容,可能不是很困難,
, E7 Q8 H7 t6 Y+ T6 a+ g不過還是要花時間,個人目前蠻忙碌的。& c# N7 U+ l( D1 K
) t, P( D% Z5 ^* s
給你一個朋友的MSN,你可以跟他討論看看,
& r9 `% n4 }. Q( r/ R# o) h他本身是程式設計師,也對FC模擬器很有興趣。* {" Q/ c& U1 T4 {- r6 S

. U+ c3 H$ H! ?+ U  D% \) o/ ?/ OMSN我就PM到你的信箱了。# @* G- _( _; F# t

2 @8 M$ V" Z! F6 b6 f; ~+ d! T9 w( ^希望你能有所得。

该用户从未签到

 楼主| 发表于 2009-11-9 13:23:59 | 显示全部楼层
呵…… 谢过团长大人~~

签到天数: 80 天

[LV.6]常住居民II

发表于 2009-11-9 16:02:29 | 显示全部楼层
团长的朋友都是神,那团长就是神的boss。

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表 1 d" @( w( a4 A; k
呵…… 谢过团长大人~~
! h8 r/ u6 }+ d, |% X: E& \" i
# G; I+ k6 D, _% V. |: E
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 7 ?4 j$ m" q: K* z  E
团长的朋友都是神,那团长就是神的boss。
) F* m. {$ j4 T# X3 \
哈 不敢當,我只是個平凡人,. v7 R4 N8 c$ P' O/ Q
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙$ [) N- u( }' [. h- [6 d
ZYH! u3 U3 l/ x. H0 k, `" z, |% O) ?+ ^4 ]
QQ:414734306
% q3 g# K7 W, d: f5 {7 W( JMail:zyh-01@126.com. k* r$ e6 p% v. @

. y9 h& z0 b6 r) T他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
) @  V* h4 u( P; r再次对团长大人和悠悠哥的无私帮助表示感谢~~

1 I. }" P+ T" N: w3 b6 X& N4 i2 a不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-15 03:54 , Processed in 1.080078 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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