EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?- Z, @1 H) \0 e3 `1 t1 z/ L
PS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。2 H. P' o4 }: j4 q6 i, k. r
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
- b! ]( p7 W7 L# {/ ^2 K这里有相应的模拟器源码,就当送给大侠了~~
1 K$ }+ [* C5 F+ [4 ghttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 ( a  Q& S/ b& X; M. [% o
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
8 }$ y" O; d; O楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~8 i4 A8 O7 U( |- u9 @% w
这里有相应的模拟器源码,就当送给大侠 ...
) N, ]. v) Z, j
聲音部分(Audoi Process Unit = APU):
) z- K/ H. f9 {/ ?0 j+ M% R.\NES\APU.cpp$ O% i! R( @3 r: O" @5 n2 Z( Y
.\NES\APU.h
1 A. m) l  h- f: e/ X
+ e+ s7 M7 c: L0 \. ]3 Y7 R- \
, M! Q2 X0 r0 Z/ N3 `$ l影像處理部份(Picture Processing Unit = PPU):
" `7 v+ `: N" r' h! z% |.\NES\PPU.cpp
4 {* `+ W' r! ~$ M) ~  N! [# L.\NES\PPU.h4 j" R3 q5 ]8 }' I; C  `

$ _# O, J$ w5 E0 j- V- B$ b如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:2 _; \2 M$ Y' Z
(由于很多专用术语和算法机理都不明白,所以看不大懂……)4 N6 ^7 ~: `# j9 v3 g0 M- f- c
/////////////////////////////////////////////////////////////////////////// h/ W- W3 u* p" ^( j5 a
//                                                                      //
6 Q$ ?1 i8 A% Q" O. g# X9 i//      NES APU core                                                    //
4 \4 M: A* F' W+ Q* E//                                                           Norix      //
- z) W# T! R4 x. V//                                               written     2002/06/27 //* W& q: E- [5 h8 \. h$ L. H# u* u
//                                               last modify ----/--/-- //1 k4 L# d& r+ @/ E; d, ?' @" w! E
//////////////////////////////////////////////////////////////////////////
6 Z; [3 Q" [) i" ]- _0 O/ F+ e#include "DebugOut.h"
! ]9 F( q  c! g; p#include "App.h"9 A" b: x5 C2 T% r' g
#include "Config.h"
- p9 ?  k6 l; p% U4 |0 [0 t; B# m3 @7 m
#include "nes.h"( c. w' v0 N3 s; c2 i0 u; g
#include "mmu.h"8 B- B; u& S9 c+ P9 B1 n5 }- F
#include "cpu.h"
: X5 p; t; M+ p1 ]1 }# ]1 c3 D* m#include "ppu.h"
9 [# v; L& u: W) C" h#include "rom.h"/ B. |# }9 U' B( _6 X
#include "apu.h"
+ P" \% N: |0 O! z9 J2 b0 o
+ ?8 ~- h# h( y" b) N8 T// Volume adjust
9 P3 R) W- T: W8 a& B6 P// Internal sounds6 N$ k( c- O% q' e/ a8 ~- P
#define        RECTANGLE_VOL        (0x0F0), Y; r7 n9 U- z6 v9 Q* z
#define        TRIANGLE_VOL        (0x130)
' B4 l& C: }) u0 A! T2 D7 w8 x% R#define        NOISE_VOL        (0x0C0)3 V' b$ U/ l7 o2 P2 ^
#define        DPCM_VOL        (0x0F0)
: {+ D+ X3 w# v$ p6 m// Extra sounds
) O. I7 y4 z0 x" k#define        VRC6_VOL        (0x0F0)
" Q" Q& Y$ o3 H- L8 D#define        VRC7_VOL        (0x130)2 t  @) i0 b  P
#define        FDS_VOL                (0x0F0)8 G. s, U( {/ t
#define        MMC5_VOL        (0x0F0)
" O" N& d0 v0 ^: u6 x7 A#define        N106_VOL        (0x088)$ t/ ]1 m( v# d/ h
#define        FME7_VOL        (0x130)) D, J- z( h( {. I! l
- I0 k: ~% a9 a; H& ?3 T
APU::APU( NES* parent )& L# C' o! n0 d, ^$ ]8 ?
{
2 C/ m/ `* _* W$ Z8 G3 R, z        exsound_select = 0;
* {: W6 ^) g/ H: D
. O1 \2 m# b# D4 W4 A+ m" ?        nes = parent;
' I0 Y- O: R1 |! P2 V. P        internal.SetParent( parent );
  Q1 D. x6 @$ g3 E" ]
1 S5 {& j( @) w! G* s& E        last_data = last_diff = 0;* f/ _% A5 V0 x

- T3 i7 ?1 K' Y9 F) P        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );  j2 Q8 f" F+ ]& H2 E, j  l

% a: I& ?( V8 j, d        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );* Q! L# [2 F: D! d
        ZEROMEMORY( &queue, sizeof(queue) );7 V* Y% [* G0 @3 V4 f. l) @  y" a
        ZEROMEMORY( &exqueue, sizeof(exqueue) );' A% Q8 y9 w5 \. g
2 F* Z# P2 \$ c. l4 _- H0 R
        for( INT i = 0; i < 16; i++ ) {
" }3 r' ]1 w3 @, `' R0 R  i                m_bMute = TRUE;- U( R  \& J) h7 i1 M
        }6 y+ O$ E$ M& v+ i5 `* O/ ~* y  V
}
" l, m0 A* ^+ f& D: d8 p  y- q" E9 O2 Y9 A$ z$ d: n
APU::~APU()
+ L; u1 H/ c" u( M: D- Z. @) P{+ f( H  @2 s/ j8 v2 x  Y
}
7 E7 z: c" G8 A/ n+ A; ^5 F
9 G& ]4 T" M5 c9 U; c7 ^3 ]) Gvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )& M/ G  n8 u4 v2 o
{' X' {- @' O, F2 Q$ A, E* X
        queue.data[queue.wrptr].time = writetime;
9 `( Z/ }% R+ F. A        queue.data[queue.wrptr].addr = addr;! c2 y8 E5 v/ L; F& @$ \8 x/ S
        queue.data[queue.wrptr].data = data;" z; H6 S) {! T6 z8 C
        queue.wrptr++;
/ p/ J, [/ J/ v  n' `  n1 Y; b        queue.wrptr&=QUEUE_LENGTH-1;
  i- T( |  R3 F0 G! T        if( queue.wrptr == queue.rdptr ) {) F: o9 U" h$ e  @, F/ ?$ G1 O
                DEBUGOUT( "queue overflow.\n" );( m, E5 E* C: Y# U- E
        }
3 ~8 N# N$ a/ |- D- C6 L}- ?4 k) m5 Q, _" J0 W5 `
4 }; Z# g. t+ B5 j5 n& j& U
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )# O; z' Q& @& k; A2 N
{2 I# `! S+ ]/ H/ [) J  z
        if( queue.wrptr == queue.rdptr ) {- Q) q' A% z2 c
                return        FALSE;
# @7 r) H8 x3 \; x5 Z' \9 r8 }  s        }) }2 P  g3 T" v6 [1 q3 X9 i
        if( queue.data[queue.rdptr].time <= writetime ) {
" |+ `) g+ {0 G! ~3 s                ret = queue.data[queue.rdptr];& p. v, G( L" Q! n6 i
                queue.rdptr++;
" y: ^. N' z1 h& c( P% O6 X                queue.rdptr&=QUEUE_LENGTH-1;7 K; w8 z$ A# n6 s
                return        TRUE;$ X; K* X. S0 @, c1 i1 v
        }8 ?; I' Z& |. K6 I" W2 G: e6 w% b
        return        FALSE;
. z' H# Z9 `9 s# n, S. ~( u}
1 V2 e/ [" g5 O0 M% z+ I( p6 v, H: W
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
. c) X9 A$ y6 {6 _. _{
% }7 U. Z! l. z  Z3 }8 E0 I* j/ P        exqueue.data[exqueue.wrptr].time = writetime;
% A5 a7 s0 k/ s! x        exqueue.data[exqueue.wrptr].addr = addr;& u! c1 {( P+ e8 Q  O+ w9 Y( c
        exqueue.data[exqueue.wrptr].data = data;
% [; m, Y$ h5 H        exqueue.wrptr++;0 d) h# G, ?/ t, ^8 H5 v& `
        exqueue.wrptr&=QUEUE_LENGTH-1;
5 f  }7 E' u1 t2 e& y        if( exqueue.wrptr == exqueue.rdptr ) {  Y) x% R2 \5 f( {$ e
                DEBUGOUT( "exqueue overflow.\n" );
6 H3 M! n) y' t' c# h        }) t  z7 u' a* \, ]" B6 }
}$ c% c2 S" \3 R" P8 @8 W
2 e  [! R# I& R: [5 x
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
; A) H' J; W5 Y- a1 Z6 q0 C{
3 N  h$ c9 Z9 a# \# Q        if( exqueue.wrptr == exqueue.rdptr ) {
* t( H) |2 w) G0 ^  ]) T                return        FALSE;
" |5 R, W" X3 x* m; T( O( h* o        }
# k! @7 c! F" s( b        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
8 j/ S( N" T1 d* ?                ret = exqueue.data[exqueue.rdptr];! P' J  B8 E7 Q$ J! ?3 c
                exqueue.rdptr++;) l2 p9 x/ t5 d0 A( J! d
                exqueue.rdptr&=QUEUE_LENGTH-1;: G) [  ?9 y" U
                return        TRUE;
' V! z" y; B3 w, @  W/ x        }
, i% ]6 D" R& L5 M2 l6 `" ~        return        FALSE;
6 l: ?" ^& I! N}
2 z% \/ C5 I. x4 o( n) M' d4 B
8 j$ p6 r% v7 ?. Avoid        APU::QueueClear(), ?0 h6 A! \% |% l9 O" g, ]
{! z# K3 {( {( G4 b4 {( m
        ZEROMEMORY( &queue, sizeof(queue) );, V2 z7 J  U/ z- o3 F1 w# u
        ZEROMEMORY( &exqueue, sizeof(exqueue) );4 }4 @4 m0 u4 l/ ?* ^
}
7 Q0 G) a* B) q( Z. Z  ?/ [* s5 o" G+ F5 ?9 W, j& Y! g
void        APU::QueueFlush()& o- z$ ^- Y5 o* e& T- T- _4 D
{
8 f; x' I6 F: C& Q        while( queue.wrptr != queue.rdptr ) {
+ W5 i8 D) A9 w' u. [                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );# j( R7 Q; O3 f+ [- E
                queue.rdptr++;7 a7 X! g# n6 k4 l
                queue.rdptr&=QUEUE_LENGTH-1;3 c( R8 U' N- U
        }
0 I2 j: a9 J) w& G: F: f# ?; G! k
        while( exqueue.wrptr != exqueue.rdptr ) {
% U. e6 ]) w1 W1 S" K                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );' ]7 |1 q! R% Q. T
                exqueue.rdptr++;& t: G* z+ L# M' E. E, c
                exqueue.rdptr&=QUEUE_LENGTH-1;# f" R& r. _  n$ q
        }
, _4 [$ K" S1 P# ?# ^}
4 T0 `3 q9 P6 o. q4 g. E
; ?* S  _- K: F* kvoid        APU::SoundSetup()
0 A8 i4 e8 @, M% e( T2 f{
/ p( C6 i& S; I, C5 [5 F0 n        FLOAT        fClock = nes->nescfg->CpuClock;: y- s+ }7 Y3 g2 z0 R, y1 P7 ^# T0 {
        INT        nRate = (INT)Config.sound.nRate;
9 ~0 ]6 ]/ w4 K4 i" m& T8 c        internal.Setup( fClock, nRate );
* N/ w  C5 K5 G1 ?3 }. ^. {        vrc6.Setup( fClock, nRate );% `+ D6 s! X' ]/ t; z2 S7 P! ~( s
        vrc7.Setup( fClock, nRate );5 w& y4 y1 p! u# k* y6 B8 O- F- ^' I
        mmc5.Setup( fClock, nRate );& T3 a$ q. f, L( R8 G& U* X
        fds.Setup ( fClock, nRate );* y1 |4 _6 b2 i2 o
        n106.Setup( fClock, nRate );
. W: j% w. \4 S- x5 c0 X        fme7.Setup( fClock, nRate );1 U# @/ k  H9 k- m5 P% O
}
6 \1 Q: T4 s$ q4 v; \) u  E! d3 l7 @2 N. B2 E
void        APU::Reset()0 k7 ^0 n& [, J
{3 m& p. d2 Z* X* k
        ZEROMEMORY( &queue, sizeof(queue) );
1 n, R9 A  W5 F( ?2 c        ZEROMEMORY( &exqueue, sizeof(exqueue) );3 B! |% t; f) J4 L4 `: n

  `; t( [; @% {' _; J5 T$ [        elapsed_time = 0;
6 _4 \; Y. H1 P( o, g" ^# x6 ~+ Y2 ?2 t2 z+ |  |
        FLOAT        fClock = nes->nescfg->CpuClock;
8 |1 a% I4 X2 x- I7 H        INT        nRate = (INT)Config.sound.nRate;
3 f. f0 j& z" O# K! i1 T        internal.Reset( fClock, nRate );* y1 U; ]& S7 F, G1 p
        vrc6.Reset( fClock, nRate );
) J* [+ T  f3 i& @  o3 \& Y( a        vrc7.Reset( fClock, nRate );
& X9 F' N  e% O7 M* K, F8 g        mmc5.Reset( fClock, nRate );
- A1 M, j; [  D0 E( ^        fds.Reset ( fClock, nRate );
. k. N5 g( r) O3 g( s! s; Z        n106.Reset( fClock, nRate );1 m$ n8 L6 _# C' Z
        fme7.Reset( fClock, nRate );
+ V3 _- D6 B( E4 ^6 ~" a2 k
0 t# t& ~2 @/ w        SoundSetup();- r# G4 E  ~# Y( h7 f/ R
}
) w7 U" y. c" F4 F& O$ R. u
8 F6 G6 |7 P+ ?void        APU::SelectExSound( BYTE data )
. t# ~* L8 [  H{
* a0 O: r- a0 _9 A5 f1 v7 F        exsound_select = data;' ~: \; ^- i; G$ d2 K8 p
}% q8 E9 |' i9 j; a2 K
7 K0 X/ e8 s$ Y+ v9 u  M0 `' \1 {
BYTE        APU::Read( WORD addr )6 O. N% p' n7 U9 k/ v' O
{
8 d- ~) ~) \' q5 b% K) D        return        internal.SyncRead( addr );
$ B$ e2 J+ n# ^: g( A& p0 |  M- y}
2 j  Z! k  m. a
5 a; V3 e; t4 I, `2 b+ I' s, Bvoid        APU::Write( WORD addr, BYTE data )! Z# D/ N" M7 A! r3 D
{7 k0 \/ j3 e* [4 h
        // $4018偼VirtuaNES屌桳億乕僩
# ]) N$ h7 p/ w5 R7 o$ m  b        if( addr >= 0x4000 && addr <= 0x401F ) {
5 g* V, C( \/ H( q* h+ I                internal.SyncWrite( addr, data );8 c3 |0 A+ [  |; M
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );; z3 w# B7 r4 O; r3 M; g* I
        }
! }# \, s" W1 I+ U}- ]5 n4 r! H3 g9 G! ?0 R/ E1 s
  o$ {* A% o2 C) g% ?- J
BYTE        APU::ExRead( WORD addr )0 v) M; C- h7 v, l2 o
{( t: |& z/ }0 l- `9 |3 |5 \) O- _
BYTE        data = 0;
7 v; _0 ^2 Y; \3 t- F
# j. u2 h7 y+ N  ]8 A$ Y9 T        if( exsound_select & 0x10 ) {
& x# i9 P* O- i; _' h+ D                if( addr == 0x4800 ) {
: B. p! E* q/ o9 S/ {8 e+ \5 x                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
2 p9 m" b- {5 K, E7 x5 W9 u" `                }9 r. u) T' g0 Q2 e! y- l) p
        }
# v  h" K, ?6 Y- \# W        if( exsound_select & 0x04 ) {
6 v2 t% X% V: M( b                if( addr >= 0x4040 && addr < 0x4100 ) {
$ S& U1 \+ p* g                        data = fds.SyncRead( addr );/ p0 k  s4 y2 L- `/ w
                }& Q' V" R0 o5 Y$ j) G! Z4 E; U2 @
        }
% o5 R; L( T( X: G        if( exsound_select & 0x08 ) {
- S: j( i/ \; D6 v1 Z& n0 n: |                if( addr >= 0x5000 && addr <= 0x5015 ) {
& `: {+ D! v; n. ~9 o( ~                        data = mmc5.SyncRead( addr );; Q8 s/ t- @9 T) Z. f6 d/ Z
                }
" e& Q% z3 D4 D# \6 J% y- S        }, ^7 G" h6 z! i8 ]& V
& n8 \% W  f" W: k1 S
        return        data;
( J( q* N+ }; V6 O6 g}0 m; o, r  C* k$ ?

, h! r) E+ B7 ?! A. h3 g" evoid        APU::ExWrite( WORD addr, BYTE data )* i9 a0 q6 |8 n, j
{/ g* }0 D4 J8 o( ~+ ^# q- q
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );! e2 k* A' i. y; n6 Y+ p* s! b( z

7 L7 E+ ]1 R: A- O/ a        if( exsound_select & 0x04 ) {
% ]5 ~9 f9 i7 U8 Q/ w6 x5 q# f                if( addr >= 0x4040 && addr < 0x4100 ) {
. F; y  n; Z* k( H9 }7 b" L                        fds.SyncWrite( addr, data );9 g1 U: G7 ?$ [7 j% J
                }3 p5 t4 L: @" N0 \% c
        }
4 t% n; ^) E# J# d$ @2 d# S
. N5 a& C6 ^5 M8 ^        if( exsound_select & 0x08 ) {
' i' Q- k; o  u# C& E( T- \                if( addr >= 0x5000 && addr <= 0x5015 ) {( Z9 n: x: z7 \2 P: }& V7 I
                        mmc5.SyncWrite( addr, data );8 g( h; f3 J  M# v) o# ~
                }! o- T# ~2 G, Y# J8 ]3 m
        }
0 X, n* L5 B- D. [4 n}1 {* j0 `: S+ K

/ k+ c, t: d2 q& dvoid        APU::Sync()# J+ s8 I. _, y% V7 Y
{  R- P/ Q9 W# [; I' G, ^3 W+ J
}
/ S; K* J( ~( z) e) j# b- x2 U; V- _7 W6 X  R. P2 [( P- n. M: C: O
void        APU::SyncDPCM( INT cycles )& l3 C; z" m, d! B
{
! g  z5 q! m" h( e5 C        internal.Sync( cycles );
5 r* w+ R; Y/ w) I& q
$ `) w) e9 P3 y- |        if( exsound_select & 0x04 ) {2 @& E1 D2 c3 J" ~  V1 D
                fds.Sync( cycles );. d6 f8 x$ w, O' d) h6 p& M, \' D
        }
& _: z8 a8 ^2 M" l- Z) V3 L+ l        if( exsound_select & 0x08 ) {# Y3 Q. C9 [) I
                mmc5.Sync( cycles );
+ i4 k. v/ r( ?        }
9 m/ x. o# I- r* F5 n}
0 e6 |# J! ]! z! H# Q" x( I& f: P% N1 U& A8 R
void        APU::WriteProcess( WORD addr, BYTE data )- d1 p$ [* _" A
{
# B% O' O& P$ _) Q6 b        // $4018偼VirtuaNES屌桳億乕僩% @' P2 W4 y( Z- t* Y6 L% u
        if( addr >= 0x4000 && addr <= 0x401F ) {
( w* e! ?, T3 }( ^                internal.Write( addr, data );
; C& W# M) x# v/ x6 K/ H! Q! q  [        }
' R7 n. v+ V. N5 i}7 N& g6 ~+ |6 S( G

( E/ e5 d* i3 f" Hvoid        APU::WriteExProcess( WORD addr, BYTE data )0 `4 @; |- M* v1 X. v% {, R4 t
{
5 O# b& I2 z9 S9 O* ?7 x# x        if( exsound_select & 0x01 ) {1 v2 ]( M2 V$ @$ P
                vrc6.Write( addr, data );/ E" u% A5 B! [9 J
        }0 g9 z% P( s2 P! w9 ]: v' V1 Y
        if( exsound_select & 0x02 ) {! i( i- }9 L  z& u. k7 v8 D* z
                vrc7.Write( addr, data );+ H% K9 r5 J1 h) K* A& ~( r1 M8 ~2 M
        }0 ~: p4 X/ q5 `, |  m) H
        if( exsound_select & 0x04 ) {
7 B3 ?( Q3 ]: a8 n4 {                fds.Write( addr, data );, H' y( Q- n( s5 T- x% ]- Q2 ^
        }! T/ N+ J  `+ ~, u
        if( exsound_select & 0x08 ) {5 g! v. c: Y: p$ @* [9 |
                mmc5.Write( addr, data );) v0 q/ {1 K3 K6 `/ t% n! G
        }$ ], Z1 [# e1 d0 s$ A) @" x1 Q
        if( exsound_select & 0x10 ) {1 Y* N9 A6 H0 l
                if( addr == 0x0000 ) {* ~5 n; m: E5 J( ]7 d
                        BYTE        dummy = n106.Read( addr );
; X/ ?: ]$ ~  I* S- H                } else {7 G' L: Y6 M# S4 x
                        n106.Write( addr, data );  t2 Q% }7 R2 z# b5 H6 `8 Q
                }7 @4 d; \; @0 ~
        }
; u3 b, ^5 p% V        if( exsound_select & 0x20 ) {
9 b0 k8 o$ J3 v' Y                fme7.Write( addr, data );5 u4 M0 u  l" m2 c/ L! W1 G
        }  A( C6 o1 e& y9 n
}
" B% f# J4 D; h; Z0 S/ D2 {; G! Y- o' k8 o; }
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )0 K7 a: G$ K( }0 S6 @4 g# a
{8 i9 C( P" h6 P5 W$ ^0 v  i8 q
INT        nBits = Config.sound.nBits;
; w2 W2 r# k: r, W0 KDWORD        dwLength = dwSize / (nBits/8);7 e5 B; e5 E, f  b& F
INT        output;; \1 W1 G# A" w% A! |; {% z7 T
QUEUEDATA q;: c# r+ G) ^, k2 a/ [* Q
DWORD        writetime;. K6 A) S( G" F- s3 ~
9 \5 z0 d( I8 S$ K! E% v/ G; G  }
LPSHORT        pSoundBuf = m_SoundBuffer;
# K; [) `) i7 I8 {INT        nCcount = 0;7 \' E6 [3 P3 P, L, r  |

/ D8 @1 h! a1 `% W% ^INT        nFilterType = Config.sound.nFilterType;
' }8 c' V8 x- A6 C3 Q8 j5 L3 |% t% ^" B! X- ^3 [+ V
        if( !Config.sound.bEnable ) {) H9 `0 \: Z- h; G* V. V
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
* d) D& ^2 Q" x                return;9 K4 p1 c" ^! w- F; p' e* h
        }
' I2 |  V5 }! a0 Q* y
$ z2 T6 f' j8 @! P' l# a% ~% c        // Volume setup6 m$ |& n' i7 T
        //  0:Master% }5 V9 u8 G$ W: m3 v- p( A: `
        //  1:Rectangle 1" f/ x8 X: j! Z1 Z
        //  2:Rectangle 2" H/ X" n5 q# V4 [6 x4 Y  w- T
        //  3:Triangle
/ p+ \# w( }& ~- L* u! g        //  4:Noise
4 p# V1 A1 ^- I3 a6 `        //  5:DPCM/ V1 |6 O# V. Q: H) j$ ?9 h, M* @
        //  6:VRC66 i3 i1 O$ d7 I% m! ?, Q. i
        //  7:VRC7
. B; r; F" ?1 d3 L, Q3 T0 u6 _        //  8:FDS
, Y( L4 S. A  F        //  9:MMC5+ s! T" L) [9 m' t( t# T
        // 10:N106+ ?7 y. I5 x; D
        // 11:FME7* N7 H2 X4 P/ X5 s6 u
        INT        vol[24];" U) p$ w8 r" }: v& I0 _2 B' q
        BOOL*        bMute = m_bMute;
. H  v& `* w2 g/ P) F4 I; b        SHORT*        nVolume = Config.sound.nVolume;/ Q9 Q4 x: w9 u3 u; T

9 B: ^& Q9 s1 \, T$ \        INT        nMasterVolume = bMute[0]?nVolume[0]:0;  F. n6 ^/ m  g; m! a: @2 Z

3 n7 O8 n5 p5 u0 m        // Internal
* b, r3 u. w# l        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
9 A/ `& d4 M# n. E( b5 U' J        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;- w% `3 t: l# `- _
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;1 Z% M" A) l+ V( ^2 |
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
% N. j, l. U4 `" G3 [        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
, v+ V7 m3 l) C, ~( u. Z, T& ?- @" g; n. U6 p& u: K$ f0 v
        // VRC6
1 u( y. ?- B! s8 Y: [  z0 }        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;2 y) h, A$ w4 d8 \! S7 l/ o
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
% x& v3 l" S) _  a* x5 [0 p        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
' `" [; g2 L2 R/ v& t- f. Y- c  v
        // VRC7
" I# d2 X3 S, O# j: F        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
3 w5 e2 K1 |- r6 Q
7 ~6 w9 H9 Y& m: [& z        // FDS
& ]$ m; i4 w8 X; F! E        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;( D% _; }' N* `" B# ?- Q1 C

3 U1 K7 i, Q4 A8 }2 ?        // MMC5, H0 T. I6 ?4 _6 a5 t4 N1 R
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
( f0 ?! T8 t2 ?* M# D0 G; P( O        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;' u8 m" b/ _. h. {3 u  ]; T6 I
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
& i) C. F& n& j" z2 g3 ^5 Y5 M7 s+ s6 K8 h) a" v
        // N106
' v6 m3 e" x# v, ?' t" n. h        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; a3 X, \" L" f) G: K
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- k9 e5 n0 ~" T5 R6 U9 M0 D        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
; u( D# M: Q- r! S* O* `        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ P! F7 a; c( \$ Y. }        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;" O5 D7 B! l+ ~: b5 [0 L. @
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;0 h7 n" y: o6 g
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: h1 t; Q; ]' p        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- |! @' |, w/ N
7 W( K* |2 S. G
        // FME7
2 |: F0 v$ ^. h9 G& S$ ]        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
8 e: w$ ~6 E1 s: [        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;5 R/ h4 ^, V6 h9 C4 ?
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
* N7 \$ a4 e* z6 E3 ]8 H% \5 s' ^1 s3 O  m
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;  I, l& _+ u8 {6 \! [
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
( D5 d0 c) ~0 ?/ u
3 H8 }$ [9 r  s        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟5 |6 X) u2 E* Z
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {" @5 _- C- J  y8 ]( Q
                QueueFlush();9 f- C0 J  ?* c9 x$ m
        }
) @) N4 \% k6 o$ L7 M( X
2 j& u9 C; r" E8 @- X6 ^5 ]        while( dwLength-- ) {' r! g  W0 B; Y/ e7 [- x
                writetime = (DWORD)elapsed_time;& v' P0 m4 o' p' V
8 F4 M6 ]( G2 k5 h
                while( GetQueue( writetime, q ) ) {' F8 [1 j% W  q
                        WriteProcess( q.addr, q.data );
# z; ]5 J0 G% ~2 k                }3 U9 c! X; A) R; c, \* H3 s
: x# n- z( ]" q) s6 z. i
                while( GetExQueue( writetime, q ) ) {( [) {3 R  m+ E3 l
                        WriteExProcess( q.addr, q.data );$ {$ p* X; p, l, I
                }+ i: }$ ^7 ?1 n; {$ h1 S/ G
% j/ N! o9 r' p4 M2 r
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
. R: ]& T; ?) O" T; ~: L* d                output = 0;. g# ?' E: e/ Q
                output += internal.Process( 0 )*vol[0];, }( j$ e: K/ g# W: k9 h
                output += internal.Process( 1 )*vol[1];
' }. ~7 T0 I% p6 b                output += internal.Process( 2 )*vol[2];+ o) w& r; j, M  E7 h
                output += internal.Process( 3 )*vol[3];. l1 d2 \7 I- v) P  j& f
                output += internal.Process( 4 )*vol[4];6 f! w* R- ?0 R3 g, |& q

6 c) j# }( U" ^# ]! b. `) c6 R                if( exsound_select & 0x01 ) {0 H# j7 q% n) t
                        output += vrc6.Process( 0 )*vol[5];0 @& _7 y) `# A% _
                        output += vrc6.Process( 1 )*vol[6];- ?6 [" ^! \; ^$ F
                        output += vrc6.Process( 2 )*vol[7];- |" o( R5 K# z: v, `
                }
7 @5 C! K& ^" c# Q: }: R) s                if( exsound_select & 0x02 ) {$ `$ k$ E$ I. X8 ^3 B+ ~# z
                        output += vrc7.Process( 0 )*vol[8];! i* j/ d& N) q+ s: q
                }. T6 V6 Y$ |% P6 L+ {0 |3 U
                if( exsound_select & 0x04 ) {
+ Q6 w5 c$ f4 v1 D                        output += fds.Process( 0 )*vol[9];
; ^" |& a5 _* m' n0 x) G2 C                }
# D) O" d2 ^! O2 V! E& S: Y4 w                if( exsound_select & 0x08 ) {9 H" M2 @) N+ f; A7 F1 S
                        output += mmc5.Process( 0 )*vol[10];6 [5 k8 y5 V, {( h- ^
                        output += mmc5.Process( 1 )*vol[11];
7 N6 x4 y* l- p" [2 f9 f  g                        output += mmc5.Process( 2 )*vol[12];, |# m4 v/ {' D0 r( `0 [
                }
( c* g2 T* ^3 p9 `( J8 {# }# Y                if( exsound_select & 0x10 ) {/ h3 v6 D8 F5 }$ t% {5 e5 f% R
                        output += n106.Process( 0 )*vol[13];
: c* S+ |4 c/ e7 r; W/ J* Y+ T* U) j                        output += n106.Process( 1 )*vol[14];
' @8 ?% b( `, z( C                        output += n106.Process( 2 )*vol[15];  N9 y  |5 J0 {
                        output += n106.Process( 3 )*vol[16];
3 w8 f5 i& ?: e) n                        output += n106.Process( 4 )*vol[17];$ ?( {6 v" N5 N% _) _: b6 c
                        output += n106.Process( 5 )*vol[18];2 Q( b, G( o& k: F4 a7 ^! ^% u9 ]
                        output += n106.Process( 6 )*vol[19];
* s. y1 O( [% p                        output += n106.Process( 7 )*vol[20];
* F0 d  Q7 N; L$ v/ d                }
6 i& @. U% ^3 s2 V, d$ f- l                if( exsound_select & 0x20 ) {; @. m1 G9 P7 D1 e3 L, w+ S, C( [3 m
                        fme7.Process( 3 );        // Envelope & Noise) [: E* u3 G+ S. U* C
                        output += fme7.Process( 0 )*vol[21];' m5 T5 e8 N8 s
                        output += fme7.Process( 1 )*vol[22];
- w5 X* k7 a  F4 X  r                        output += fme7.Process( 2 )*vol[23];
6 r. t" n. U, j8 o                }+ m# E) S. b2 F8 n" u

0 P* |( J5 B  e4 N                output >>= 8;6 H, [8 R5 B3 e' {
1 L0 t& B6 \. }* t8 o& n) h
                if( nFilterType == 1 ) {
/ I, s/ `* T, D5 X9 K                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)0 d/ _7 T+ f2 N+ D# Q7 E: ^
                        output = (lowpass_filter[0]+output)/2;
; d8 u& c% ^. a3 N( B% S                        lowpass_filter[0] = output;! F+ u& Q$ ^/ c7 N
                } else if( nFilterType == 2 ) {
8 p" i8 C' v* g( o+ F                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
7 C- l- t! x4 k5 K$ B                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;/ `6 y$ C: b/ f1 T4 K
                        lowpass_filter[1] = lowpass_filter[0];
, c: t8 n; N% j  d: V, {; ]                        lowpass_filter[0] = output;4 L) W/ k4 Y; U3 A
                } else if( nFilterType == 3 ) {
- a; G( X' V+ e$ g# o, v$ x                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
8 ?" o7 V& E3 L6 u" n9 C8 Z                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
! N. u6 Y- o/ V, B                        lowpass_filter[2] = lowpass_filter[1];
  _$ ^% |: G" h* A8 x                        lowpass_filter[1] = lowpass_filter[0];* h$ g" B' B% d* G* r/ e
                        lowpass_filter[0] = output;2 Y9 e- G# k4 C! ~, V
                } else if( nFilterType == 4 ) {* B1 c+ f* L! N% W3 ~5 D
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3); J- e/ b# {8 X0 r' A. s7 q. Y
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
* d. p! X6 a0 f/ T) ]% `( z! N                        lowpass_filter[1] = lowpass_filter[0];/ f+ K0 A  G' y/ C; o* X- H
                        lowpass_filter[0] = output;
7 G- R$ E: r, e- v2 l# h* F, W+ z                }! |9 S" _0 [3 Z6 e* {$ T

! J/ L1 n- Z% f#if        0: A% Q" K) Q: X3 B# I! w9 B; |
                // DC惉暘偺僇僢僩
$ r- O, a! X; ^+ ^5 Z                {0 i4 r; E  p' @$ P
                static double ave = 0.0, max=0.0, min=0.0;
; a- y# i! }' N& k6 K                double delta;$ D: P; e2 f. z8 I5 [5 I
                delta = (max-min)/32768.0;
9 u7 N5 A. f2 V+ f                max -= delta;
5 n. {6 q4 V; A+ H$ g                min += delta;& P- r: b7 }; N
                if( output > max ) max = output;
0 L7 k: C% x# E) j; Q' n                if( output < min ) min = output;% m4 {- \* j5 }  z+ F
                ave -= ave/1024.0;; s( [6 {. b' |
                ave += (max+min)/2048.0;  j/ N& o& g* m3 I* w3 Y
                output -= (INT)ave;. M5 h1 Q$ ?+ I* g. Z
                }
$ i  ?/ Q" p0 G9 V( g#endif
% ~3 O, a, i0 z6 L#if        14 G8 X' [4 f6 A; @$ B& t% _2 q
                // DC惉暘偺僇僢僩(HPF TEST)
/ m# `$ T, v  ^; B! H& I+ D" S8 n+ X                {& D& B. R# y% k- j$ T$ }
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);) _; s  M9 l" ?9 _  ]+ n
                static        double        cutofftemp = (2.0*3.141592653579*40.0);+ N4 L  X* ?& b" K9 U* ^
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
, m2 b" N  m6 [+ |* j$ k                static        double        tmp = 0.0;4 m) s! p/ ~3 Y  Y9 k8 _: b# v3 N
                double        in, out;
# `( H9 p2 `" P6 a) Q7 z( M, t  R. n' ^) q8 J
                in = (double)output;
& Y* B5 t& I) \  A7 |                out = (in - tmp);8 i9 b# r7 I( B7 D! E9 ?7 W/ g
                tmp = tmp + cutoff * out;
7 I" g! W- t8 ~. \* [' [
. o1 ]8 D7 r1 n' [" c; E                output = (INT)out;) x$ V' D6 w0 E8 M7 H. W/ t
                }
+ Q- V, ]; r3 E- ?" |#endif% b8 M& n& L$ X( e' A7 v9 N0 \* ?
#if        0( l& N8 X. F% l% R4 }8 P
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
! a; X) L; e. K3 X7 i                {
& Y- Z' L2 o% ^# B5 z, d                INT        diff = abs(output-last_data);3 L2 ?' q$ D' ?! B2 _8 c  \! M! Q, G8 O9 f
                if( diff > 0x4000 ) {8 {$ j' D+ |* V0 I; G; N; w& x
                        output /= 4;
; j/ g# @7 h" R# R2 E4 U                } else
7 M' e3 P+ H, u1 V                if( diff > 0x3000 ) {/ P  ^, e8 l+ D9 q! |; p: P% J  x0 e
                        output /= 3;
) A0 T! U8 A4 A# G                } else: F, M8 Y- n4 {/ O+ a
                if( diff > 0x2000 ) {3 Q. ~1 I. Y% n5 {/ @& P/ b! }2 B
                        output /= 2;; A  S0 U- E* h/ [
                }
, @6 T& O  z* \6 o9 `8 {                last_data = output;. B8 q% n4 v4 j/ [0 U  z' i( L
                }+ [$ ~5 r* Y8 Y
#endif: O. M+ w2 |! P  e7 h$ w( h9 M5 L
                // Limit( h( \, I! e2 N8 |6 }; h
                if( output > 0x7FFF ) {
- u2 M2 L& }( j6 H8 e                        output = 0x7FFF;+ S& k7 V2 \" W
                } else if( output < -0x8000 ) {. Z1 R! t8 _; a0 U7 x2 ~- l; Y1 s! T
                        output = -0x8000;: ~8 \; d# d+ Q/ B7 U. m
                }0 B& M- i7 B& _  e3 E! |
  G9 q* x( T7 J  s) r
                if( nBits != 8 ) {
' B5 `$ z5 g0 N; H: P) |) D) e: M: V; E                        *(SHORT*)lpBuffer = (SHORT)output;
. m& t% b1 M" D$ X3 D                        lpBuffer += sizeof(SHORT);
+ K, W2 {' L+ f; l8 S4 e/ H# @                } else {- m& U/ @. }2 u4 T: i" w3 Q5 _! H
                        *lpBuffer++ = (output>>8)^0x80;
& j& H9 L4 q! F' v# i                }" Q/ Q. ^. z" ^* ]

& i' y6 m$ ]: @5 y2 F, B4 ~8 ?                if( nCcount < 0x0100 )+ q& R  G$ W- B- \% o  `
                        pSoundBuf[nCcount++] = (SHORT)output;
: U  c# z" y. l/ ~8 A3 z
# c$ O: \1 h8 s2 p. i6 v0 x//                elapsedtime += cycle_rate;& g6 K! q9 l1 h6 R$ j
                elapsed_time += cycle_rate;
* \4 r6 g0 e2 R5 F' b. i5 z        }0 J1 O. G1 {0 s5 N/ G
& m+ x* e- S+ ~1 e3 ?) ?( O
#if        1
- ^& ?( U$ g$ L$ x        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
( A8 j/ D5 [8 E) e2 s7 b                elapsed_time = nes->cpu->GetTotalCycles();$ s# A  [- q7 G, ^# ^, O
        }! q/ H3 z$ ~/ c* @
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
9 f& e' e( m! v* S/ ]1 u5 y9 {5 c$ U                elapsed_time = nes->cpu->GetTotalCycles();
( Q  y; X7 {1 p9 U) C        }
) `2 T4 B6 m! D5 s: `. ~. m#else
4 S' o& e, E* G- ^        elapsed_time = nes->cpu->GetTotalCycles();
/ ?9 Z5 T) G9 L+ F$ z' I#endif
$ X# J' C  D! F8 f! s# x% e}3 X9 S+ V% W" a2 C/ v6 W0 m8 P

; |3 u6 n/ u7 x. u3 L9 K" ]4 m// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)' Y+ B# K" K% Y6 v
INT        APU::GetChannelFrequency( INT no )
& p) H, H5 ]" u- |) ~# O" A" n{
$ p" ~4 g" |- l        if( !m_bMute[0] )4 A9 A( g, U- N9 T/ ?& U
                return        0;6 p+ I8 n7 }: ?
5 t! X, D3 z; U* F$ R7 a1 |2 _8 ~
        // Internal
5 s: z- ]" U4 n        if( no < 5 ) {3 r9 `* E& Q- l, B+ H/ l0 V
                return        m_bMute[no+1]?internal.GetFreq( no ):0;. [! d# F% K8 S; \
        }
. e9 \& f/ r$ [! T. s$ G        // VRC6
7 a# ^$ C. q  E  C% h; a% @5 P        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
) ~! h& Z" _- S. k, l, z$ e                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;0 a4 \/ _$ ^, n
        }
4 l4 {+ V  V: `4 |" O        // FDS- N7 @; |% G/ _1 H# w1 x
        if( (exsound_select & 0x04) && no == 0x300 ) {
( e8 _6 z$ w9 m+ f& U# ?                return        m_bMute[6]?fds.GetFreq( 0 ):0;
" S2 }! v4 G9 `1 G/ Q        }0 A: p2 G) Y( Q3 A9 Z4 ~7 S" }( ^
        // MMC5
$ I5 A+ n3 H1 l2 f, ]# _        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
' \  b+ c: Y1 B+ P6 F8 @                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
) S' C( Y& f$ {  |/ h8 d- }( |2 U/ K4 @        }! v* o2 p3 w; S, s3 `$ \; @4 q
        // N106
8 j+ B$ S9 o: C! m7 s+ i        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
0 w" D. \. L4 a1 N# T. }( ~% B                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;0 x3 p* \( F+ f) ?' f
        }
3 ]0 B3 q: y8 X6 s7 |" S        // FME78 P  }% F1 }, [! n2 i
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {& A; J; o$ z( A0 S1 X& V! Y+ ]
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;+ L6 N3 Y  I# M# g' R. V
        }! i! H. n% `2 O% g8 s, {
        // VRC7
1 x+ E: Y4 T6 S, H1 h! L        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {* }5 P/ ~: V8 {. j1 ~- ]* D
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;( V" e; k+ U+ o$ J$ K
        }
% [$ K5 b. Y: o; T) G        return        0;3 ~& U8 A) h7 P& ?
}
7 r8 f% `  U' [) V" w1 G; H
1 p6 z, D( w9 y. M/ L) i// State Save/Load7 _" J4 ^5 V  k$ k: W( j7 _* u" S
void        APU::SaveState( LPBYTE p )
- ~1 r4 e' @  O) z- j{
( n( ~1 s+ x0 I5 G- a* c& h#ifdef        _DEBUG
# [6 v9 {. ?+ X, q6 m$ t/ YLPBYTE        pold = p;
. _' u: j0 L4 l3 I# R. t% U#endif8 v+ T; Y" z, b+ V% |5 }1 Z
; e$ g* Z: ^3 \/ @2 v* e' Y) A
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
; W/ l5 {: V+ g1 P        QueueFlush();
" a8 m" _) A" c! Q$ q$ _: I
: Z* A7 h+ f' F- d9 c        internal.SaveState( p );" k; A/ u3 x- Y& L3 ~7 ^4 i7 b1 I
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding# l( e  k) ]6 f( ?
9 ^$ g9 u0 t2 w) M
        // VRC6
* q: q& J0 K, E# z8 ]        if( exsound_select & 0x01 ) {
4 \4 ~4 t, g( c# p% ^% i' r                vrc6.SaveState( p );! {9 X1 c7 p) ~! F9 m/ M
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
- O0 E/ w- K( i- G9 `, G+ x# L* c) e( N        }8 _. v. y+ _9 y) [
        // VRC7 (not support)6 Z4 P4 A/ W) H; _( G$ X
        if( exsound_select & 0x02 ) {
% b0 g0 i# e5 U7 D. y                vrc7.SaveState( p );- u$ B* Q5 _$ |
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding) P# k6 B9 ~- }( ^+ F5 m+ g
        }
3 ]  n0 i+ X- P0 A% ^$ u& g        // FDS
) Z3 d, `) v) M: D9 H4 p& B        if( exsound_select & 0x04 ) {$ w2 D) T& h; u" q
                fds.SaveState( p );, W2 c5 e2 E( n1 Z8 I' `; ?/ X
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding9 x8 ~8 D& y0 m( [0 r( q$ C
        }
5 }4 |7 s! ^. J9 G$ i- t$ x4 F        // MMC5: f6 a( H- @/ A" c6 K8 C
        if( exsound_select & 0x08 ) {/ s" o- I* }: n% [. S
                mmc5.SaveState( p );0 }* C4 e! d& Z  d8 r& ~
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding  G/ L# y. b. E
        }- j# d. I& G; V) B3 G, B3 T% H
        // N106
& ?' q* F; Q$ `        if( exsound_select & 0x10 ) {
: l8 p* L& S7 p2 N- X                n106.SaveState( p );1 s& x. h1 C" ^' l! T: W
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
+ c4 n2 I3 z7 c  g2 ]$ u# Y        }
# f. _+ o: G  b4 [* W! V! X! z8 `        // FME7) X  x! W; E% d4 w. v
        if( exsound_select & 0x20 ) {0 e+ @4 G9 ^4 G) K7 N
                fme7.SaveState( p );. E$ U9 n$ ]. y6 {7 w8 J% r
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding/ P6 P. N- [# ?2 g; I
        }
: B9 e* t' P9 k' K8 x4 J7 S; o0 _1 \6 o$ S9 C! w
#ifdef        _DEBUG8 v2 W* I4 _6 g6 A1 w
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );" v- g4 q' [6 r' D
#endif& s8 @( T! z0 I. r+ M1 B, `/ U
}
' ~5 r' n' L8 o+ B6 ~  J( G9 N8 Q& _2 `
void        APU::LoadState( LPBYTE p )1 C1 o' H8 y" P" d
{0 w$ V- [% t! Y& K& G  l0 B
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
- [( e4 M( H; Q2 E2 U# z3 j( H        QueueClear();& r) @  f8 Z. R' a" O

& M' G- e4 e, O' V0 u        internal.LoadState( p );4 U9 A- K) d6 o0 F: B9 o4 v7 E/ q, V+ }
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding! [2 ?* g  |2 ~
3 i, d8 g) o; W9 y; R, X( E
        // VRC6( f% g4 E" n: [. A0 F  d5 M( U, c
        if( exsound_select & 0x01 ) {* A" ]0 N( N, b4 {2 n/ ^% {$ {8 ^
                vrc6.LoadState( p );
! K. |9 c+ G5 w6 p( n* t) c                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
! V) ~  D/ p. H7 r6 F" }9 M) `0 {- u( y. V        }) Y% D) g4 P) q0 ^$ j
        // VRC7 (not support)
) ]1 `$ J& G4 s6 y6 e# l        if( exsound_select & 0x02 ) {
2 _) a; X% m# H6 v) }, x4 R' `                vrc7.LoadState( p );  y5 x" R0 m. q- z* F
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding1 B  S$ Y6 I1 y5 m0 ]- g( z1 ~
        }- Z% \5 W& g% w
        // FDS
3 C4 C' p& L8 Y5 ~) V/ b2 L6 j+ K        if( exsound_select & 0x04 ) {
( W! a9 @$ e! [. h% Y                fds.LoadState( p );
( Z2 z* y. ~1 Y4 Z* h  B                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding8 ?6 R; v7 N" {; d
        }
* u8 f( ]1 p4 z1 S6 _        // MMC5
5 w4 M+ ]2 G( p7 {$ [        if( exsound_select & 0x08 ) {
% I' {$ R6 K. b9 W* o- y/ S6 S6 X                mmc5.LoadState( p );$ a+ d3 w# J* r4 M/ H# o
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
+ l/ P5 @4 `" [5 a: {9 V2 @        }
& s% O) t; _* R2 n" H( I$ i. N' w        // N1060 X2 }& ~2 \1 r- r
        if( exsound_select & 0x10 ) {( Z( F% l0 S: |6 K- G9 B
                n106.LoadState( p );
6 F7 N4 \3 N' |5 W  J$ L                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding5 p+ W3 H8 A3 t% Q7 t6 M
        }" j& J  P8 ]1 M- ^
        // FME7# [" j4 W5 ?" i+ `2 G
        if( exsound_select & 0x20 ) {
0 M4 K3 s4 v; e                fme7.LoadState( p );
2 A( ?2 _  T$ M" l5 @                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding# R3 @5 i4 [: a
        }
% ^8 H! {( k" E" \  b) V" t) g}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
4 k3 y2 ~$ _( |8 D; @, E! [可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
1 Z7 s, R$ x& A+ Q. \6 N, z# e感激不尽~~
8 ~5 M% F0 ?0 C, p
恩 我對模擬器不是很有研究,
7 t7 t' s0 J; W: ^雖然要了解源碼內容,可能不是很困難,8 u* m* X  l" u8 u8 T
不過還是要花時間,個人目前蠻忙碌的。2 c) J! _0 w- D- w

1 G0 d; L. p( X: _給你一個朋友的MSN,你可以跟他討論看看,
/ C- V# U1 S, v5 {" U3 f他本身是程式設計師,也對FC模擬器很有興趣。8 r. J7 ?8 R. v# O* o
- [* B) S/ p6 s; s* P4 @
MSN我就PM到你的信箱了。
) w7 N0 v: }5 {4 b5 l9 w
. |% F" ^3 L0 \: j5 @7 w+ y希望你能有所得。

该用户从未签到

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

签到天数: 80 天

[LV.6]常住居民II

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

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表 9 q" A1 i. L8 {( @8 F; \9 p6 J4 L
呵…… 谢过团长大人~~

8 q1 q( h: v8 ?; ?
1 c& A0 G' Y7 g; Z6 ~5 L- R' \哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 " J1 r$ x9 ^+ P* e: o  T5 \' Q
团长的朋友都是神,那团长就是神的boss。
7 u0 \# E1 r- [6 J+ t( v; z; }
哈 不敢當,我只是個平凡人,& z: F5 g1 K( H, p- M
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙* H0 e& |. U( ?7 w/ h+ h
ZYH; r9 o0 s0 @( D0 X2 k) b! D# C8 z
QQ:414734306
0 P" j" K. ~9 A; NMail:zyh-01@126.com8 h7 n9 s7 D6 Z% j
3 \' _9 T1 @6 T* p! A5 `, b" Y
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 * P  j9 J6 N& L" t9 P, ]7 X( C
再次对团长大人和悠悠哥的无私帮助表示感谢~~
5 Q6 d- Z: P4 @! W
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-2-9 20:22 , Processed in 1.090820 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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