EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。& A/ ~9 o2 |' U3 `$ s  E
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~7 k7 c' v& b3 m6 U! s
这里有相应的模拟器源码,就当送给大侠了~~) z0 H3 A$ ]% G% w7 a
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 , K  M+ x8 Y' P
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
4 b0 ?% Q, v) |* e# t" Q% ~楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~. o; `  ~/ Q( E+ T8 T1 v  w# N! |8 e
这里有相应的模拟器源码,就当送给大侠 ...

; |9 K6 c: M% {+ n) W聲音部分(Audoi Process Unit = APU):
. G% ~: B$ g8 P.\NES\APU.cpp4 Q$ h) H; t5 }8 B. @
.\NES\APU.h
9 ^) z8 E- [: O3 }& f* n. z' s" [3 s( k3 P7 i, y
& W2 ~9 n9 m0 [" F1 E5 s
影像處理部份(Picture Processing Unit = PPU):0 m0 t( p4 j* Z
.\NES\PPU.cpp
0 H8 \9 i. [8 H" C) a+ S.\NES\PPU.h
. c4 N/ K. C$ P; x: D, r! {7 z/ Z, I9 m! h3 \2 o9 x( F1 t, Z
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
/ H5 Z( V: j. X0 l2 T(由于很多专用术语和算法机理都不明白,所以看不大懂……)
) C: Y9 S& x, _7 v//////////////////////////////////////////////////////////////////////////7 u5 Z4 B( C  |1 S
//                                                                      //9 l4 ^- x4 ?4 w( o3 a3 [
//      NES APU core                                                    //. e& N6 [4 a8 z" V& a! m0 X
//                                                           Norix      //2 t; O  |8 t& o6 D
//                                               written     2002/06/27 //# U$ k" G+ i: |0 w1 g1 @
//                                               last modify ----/--/-- //
0 p6 j) f* U. R9 Y//////////////////////////////////////////////////////////////////////////. }" z4 b4 @, U& S- u3 b& ~) V2 c% i
#include "DebugOut.h"1 V; ?5 z: [6 B2 [. X$ g0 S
#include "App.h"6 `8 G. ^, d6 f6 B  k% x) x: N
#include "Config.h"
7 f  w/ l: f% g
) j- Q9 c* J; Q#include "nes.h"$ a/ C+ x5 x6 F# E5 e& W
#include "mmu.h"
$ G9 n! t* d7 t* t#include "cpu.h"
! s6 O3 R" C+ Z% P9 N4 w$ G#include "ppu.h"
6 b) g8 ]0 R) ^& W& |  }+ _#include "rom.h"$ Y$ y7 B2 P1 L* q4 A# O: ]
#include "apu.h"2 [0 ?$ O7 D0 D& N0 r) H7 [6 ]6 A

3 n  B7 {2 M* p' N// Volume adjust! `( C# e$ A& a# L$ H# R: p- \/ h
// Internal sounds
( J. E* A/ n* ?$ R8 m' t" b/ T. s' \#define        RECTANGLE_VOL        (0x0F0)( l9 Q5 c9 V' p- i0 _
#define        TRIANGLE_VOL        (0x130)
* N; n  q* f6 n/ _#define        NOISE_VOL        (0x0C0)- J( [: u- z2 s* ]9 z
#define        DPCM_VOL        (0x0F0)
8 n8 d' d$ b8 u7 a& B+ l// Extra sounds! R; i7 ]0 r' |1 P; h  w+ W* x% Z
#define        VRC6_VOL        (0x0F0)
; x2 v$ `/ N) x* E1 D, K#define        VRC7_VOL        (0x130)9 j: `* }3 z$ z$ s
#define        FDS_VOL                (0x0F0): \  p0 ^" D% n, X) U! g) s% Y4 P. P8 ^
#define        MMC5_VOL        (0x0F0)
9 p2 g; w+ t; R/ \: @#define        N106_VOL        (0x088)
2 R! L+ ]" Y4 ^7 f5 @3 T  R$ s" A#define        FME7_VOL        (0x130)
" ~8 w; a, E+ Y
& x: C, Z( v8 M& M* `- }2 Y$ C5 ZAPU::APU( NES* parent )' [- Q+ _% F. q! H% t3 q
{
' A+ |6 \' H9 q3 ?2 ?& A- c! V0 B        exsound_select = 0;
& H. t" `% V6 x$ d* j# i8 }* y, k  p$ ^' E
        nes = parent;
5 s) W  D' ]: l8 S& h( M        internal.SetParent( parent );5 H$ h' k4 Y. u

" [7 M2 I$ U4 t, `3 I0 Q+ @        last_data = last_diff = 0;
% A8 ~& P  O6 v8 t( Y7 I; r4 S+ O1 h
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );  k7 J" @2 k: C2 k" Z

. ?% a  n5 ^$ A- b" h        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
+ q. A, P, v2 w+ p        ZEROMEMORY( &queue, sizeof(queue) );
. a8 @7 }6 `2 X. `' ~% F- i% C        ZEROMEMORY( &exqueue, sizeof(exqueue) );( C1 G2 Q7 r( t
* H6 L! ]4 m7 j( o$ n
        for( INT i = 0; i < 16; i++ ) {. y3 {8 G. D; S0 ?9 h* j! e# ?
                m_bMute = TRUE;
( J, q9 m0 }( V0 |        }4 S1 L: F7 _4 o$ z+ B$ I, t
}! Z7 B0 d+ q& M5 J! m

4 X3 |5 h# j0 Y  B" TAPU::~APU()
6 ^( c5 Y" N7 G  v{
. E! _5 g3 X2 t. z" m* _6 n}2 N1 V2 Y' x" ~4 H

" ~; t5 L' z0 s# Ivoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )7 I* \! p* J: A& L1 p$ t
{2 Z8 `8 j! ]% `) r3 Y
        queue.data[queue.wrptr].time = writetime;  }! ^" a: b6 g- h+ W0 O2 K
        queue.data[queue.wrptr].addr = addr;3 k7 Y) ^& A6 O3 l
        queue.data[queue.wrptr].data = data;
; L1 T' ~; G7 ^0 w0 T/ K8 r        queue.wrptr++;- ^9 C1 I" G! p" |! Z
        queue.wrptr&=QUEUE_LENGTH-1;7 C( F) ]/ E* ^( |+ R1 \& [- e& Z
        if( queue.wrptr == queue.rdptr ) {
. `7 T, X) ^! I                DEBUGOUT( "queue overflow.\n" );
& f7 ~$ k7 ~* o+ z* b2 E0 _# f. {        }3 Z; V: U6 q6 X
}
! Z8 A7 b, n0 y7 K  T1 C: e, s& B  S( O. }. T
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )1 b  [. c1 B/ b* `& A: _
{
0 g" S, `: i7 k/ m        if( queue.wrptr == queue.rdptr ) {
! m/ j* v  [2 p5 V                return        FALSE;1 y8 T6 w6 m! q% P
        }7 |: o8 e( R7 E, W+ z+ |
        if( queue.data[queue.rdptr].time <= writetime ) {
' ~# k0 ~' S2 O& A                ret = queue.data[queue.rdptr];% w$ t, O5 d' Q
                queue.rdptr++;2 q% B7 |) E. Z& C+ X' m# ~3 c' X
                queue.rdptr&=QUEUE_LENGTH-1;
/ k5 V+ o' ]0 X+ }                return        TRUE;! G% n# v' M0 I, _" ?  }. ~
        }
9 o5 X/ I2 r; _2 \+ B        return        FALSE;$ N: w0 D( \" ^
}
% [6 N7 j8 Z  w( ~4 B2 H
$ T5 Y1 ~( p4 Xvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
9 i' Q8 R  K( ~3 |! e5 O4 r{7 c. a9 P5 P: T5 p% L
        exqueue.data[exqueue.wrptr].time = writetime;0 {" r3 _. |* S- {$ T9 u
        exqueue.data[exqueue.wrptr].addr = addr;* j$ F6 B2 D5 g/ ^+ y3 u1 o
        exqueue.data[exqueue.wrptr].data = data;- D$ d" ?& j, x9 Q  O
        exqueue.wrptr++;) q6 E: P6 O2 r; a+ j* i. R
        exqueue.wrptr&=QUEUE_LENGTH-1;" W) L4 E% C' _4 f3 M2 V
        if( exqueue.wrptr == exqueue.rdptr ) {
8 Z' D/ B4 U( q! m& k                DEBUGOUT( "exqueue overflow.\n" );: m' Z1 L9 a7 p  W; i
        }
# H1 M$ [  k- T. {# m}
5 E$ [5 v/ R8 e0 U$ ]& g2 E2 Z4 N
% v0 U& N, L' {BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
0 Y1 ~+ b. R& w1 O! S$ k8 e{( y. z: a) O% }- \2 F2 h
        if( exqueue.wrptr == exqueue.rdptr ) {/ f4 `5 x" ?: s2 A. a7 ~3 I6 G
                return        FALSE;" S* P$ y$ N. ^6 R) e: N6 a: D
        }% t) J- V* b" z. t' N* V1 l  f
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {# m# M$ ~; H& H, h0 i
                ret = exqueue.data[exqueue.rdptr];
. f/ }/ Z" x+ Q. J8 H                exqueue.rdptr++;9 u5 f% _2 G9 V0 h1 @. x
                exqueue.rdptr&=QUEUE_LENGTH-1;! S8 j8 Z8 L8 P. s% x+ _
                return        TRUE;
% V- X1 _& P0 P! j6 J6 Z        }8 k0 W7 h# b5 C+ j- U  Y5 i
        return        FALSE;
* O9 I" j! g* r$ d0 w( n: N}4 m4 N$ z! ^! D$ f

9 k- l1 c/ Q7 Z# f: E0 Xvoid        APU::QueueClear()8 A! W) E6 }& \( p2 F8 i8 \
{; H/ H: d' Y1 x2 c! v/ d
        ZEROMEMORY( &queue, sizeof(queue) );
1 }7 ]; M; H- [, r6 ^* Z6 b        ZEROMEMORY( &exqueue, sizeof(exqueue) );$ q2 q) K0 Z( K$ [, [" s
}
+ ^3 {6 R* q. n2 m9 \
; ?* z1 v& J& m# A" I% X! ?. J+ ]void        APU::QueueFlush()
% H! r' `$ W( x2 J9 P{/ t# ?# c4 C4 V6 J* ~& o6 [% U
        while( queue.wrptr != queue.rdptr ) {- ?9 ?* }+ n/ n: F1 X2 M2 u8 b
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
# U, z; P/ J. \0 \1 S" j/ {                queue.rdptr++;
9 Y, o. k  @$ Q; M7 V4 m                queue.rdptr&=QUEUE_LENGTH-1;( ]' L) y% w# ~
        }
  u9 F# o% C# J! \
( f! o8 |' G4 b$ f2 r  ^        while( exqueue.wrptr != exqueue.rdptr ) {
3 _+ x2 W: V9 X% d' A                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );, T) U- M) v' a. S" Q" {
                exqueue.rdptr++;
5 h' f( j1 p& G6 g& G5 Q, t% x                exqueue.rdptr&=QUEUE_LENGTH-1;# |2 D1 Q( l+ i7 f; q; ^. N3 m, z' j
        }
4 [3 D- h3 p2 J# h}
4 N/ O9 T4 q( Z- P5 c3 F, w; N5 q
6 I& W, F# A) s' @5 Z) Z( S5 w! avoid        APU::SoundSetup()
6 R3 ]$ z0 X3 I6 M{
8 a1 H1 u. K+ v  i# _# y( x        FLOAT        fClock = nes->nescfg->CpuClock;
8 Q8 _' [, G- A3 R, ?        INT        nRate = (INT)Config.sound.nRate;
3 W: g- V; z: D8 p. {' R        internal.Setup( fClock, nRate );
: {% ?- o+ d7 }8 W        vrc6.Setup( fClock, nRate );7 t5 n% E! S% D
        vrc7.Setup( fClock, nRate );
, [9 ^) [% Y* O. s* k        mmc5.Setup( fClock, nRate );
' D1 }6 J4 _) P" |        fds.Setup ( fClock, nRate );5 E, y, A# `3 v
        n106.Setup( fClock, nRate );% a& V: c0 r1 M4 D
        fme7.Setup( fClock, nRate );2 h# w+ T% e6 o+ K
}
; M2 b) i# S! G% h7 c
' f9 c  Z' k. S* _# z# j; T/ k3 v3 Dvoid        APU::Reset()
0 S! N; f' A8 {{+ S6 |" B8 \& b8 m. G6 A
        ZEROMEMORY( &queue, sizeof(queue) );
$ K! P- ?. `: I4 @/ w        ZEROMEMORY( &exqueue, sizeof(exqueue) );3 ~! j7 g. o; A  r4 p
2 p4 {/ a4 D+ z+ y6 u
        elapsed_time = 0;4 H. J# @2 i% v9 R5 }

# m/ m: p5 q8 x+ H4 z        FLOAT        fClock = nes->nescfg->CpuClock;
" h- ?3 o# C$ T$ d  U$ y        INT        nRate = (INT)Config.sound.nRate;2 `% c. A. w7 X; H: v9 l) S* f
        internal.Reset( fClock, nRate );+ P  K, W, J( s/ b; e' V2 ~
        vrc6.Reset( fClock, nRate );
' k2 W7 L7 I( A! z" x) I        vrc7.Reset( fClock, nRate );/ t' S" v" o- ~5 n
        mmc5.Reset( fClock, nRate );7 B1 |! Z* v/ K7 F
        fds.Reset ( fClock, nRate );4 \1 U; s) M0 o+ X$ t# O1 D/ q
        n106.Reset( fClock, nRate );
$ _7 t7 {2 M. B% [1 z- v" e  F( _        fme7.Reset( fClock, nRate );& j$ B  q( s" _  O: F. [( p# h- f. ^  y- r

8 @0 m/ v  i! A  a        SoundSetup();: ?2 @9 Z, w1 I* _
}
5 S" ^) p8 m) S' k3 D! z& k, C
( W& h+ Y" `- }5 C6 ]. a1 yvoid        APU::SelectExSound( BYTE data )7 l- o) Q- k0 n" ^+ Y3 j# q, n! h4 V
{
( V; i- s& C1 X; V, M        exsound_select = data;
; {* m0 s% {0 I}) p  D7 \( V7 F) `8 N

5 o, l0 Z0 x6 {! ?) p8 m* C, uBYTE        APU::Read( WORD addr )
5 g! w0 T- V6 Z; [# i  x{
+ H0 o! k2 A* y" m0 w) M        return        internal.SyncRead( addr );
3 y( w5 |- y% I4 J) R}
- z) p9 x: n( b
! s9 X9 B0 O* J) W- F# Z+ Ovoid        APU::Write( WORD addr, BYTE data )# l4 i5 T$ }: t7 H% I* m' h
{
7 P: B* d9 B" F/ H; `0 V" v9 O+ n        // $4018偼VirtuaNES屌桳億乕僩
* H) A8 e& l* O" i7 Q  r        if( addr >= 0x4000 && addr <= 0x401F ) {
2 s( o, K& C. o. V  ^! {( g                internal.SyncWrite( addr, data );
6 u, ^0 y! i! h% w( c" r                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
4 u+ ^( D" k0 k7 z% C8 F        }) i" p' f$ N" P8 I& z" O
}+ {2 v, }* }  y+ \: L- ]
+ `7 m8 t; V3 e  |% |
BYTE        APU::ExRead( WORD addr )+ c# d. l( {# l9 K' G! y$ w
{# y4 ~5 p& l' M7 c- y! ^; q5 R
BYTE        data = 0;3 l7 |( m& U7 v8 R

: M* f' p" N0 b# l* j# y2 Y- A        if( exsound_select & 0x10 ) {
- S; H. s+ {, z  i                if( addr == 0x4800 ) {
  ?! I6 [6 {6 q- L4 N2 n  l0 u                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
0 F% T0 l" B$ Y# ?0 ], N* Y2 q                }4 l1 \% y* }: q6 S- q
        }
4 B3 ?2 m  p. M        if( exsound_select & 0x04 ) {& e! q; M7 G3 f. o- l' U
                if( addr >= 0x4040 && addr < 0x4100 ) {
) i4 [: S: D* |) X0 m( Z8 E, N                        data = fds.SyncRead( addr );7 `: K9 {# Y4 f3 C; [
                }
) c& h; _5 V3 t        }
) {% i2 ^# Y" N+ ~2 w8 w4 w! z        if( exsound_select & 0x08 ) {" o2 o- q" M* H) K1 q' C
                if( addr >= 0x5000 && addr <= 0x5015 ) {; p1 R: {9 A; m8 y
                        data = mmc5.SyncRead( addr );
) B( v( z0 _1 a                }
9 m" w. B% V! o  D6 D        }$ K1 c2 |: {& q$ C! B8 k' l
3 y, m: ]* n) b) C9 r
        return        data;2 p1 e7 @$ _4 ~1 ]) K
}3 t2 C. @+ x3 c0 U1 v& t4 R; r

5 g! t. t) a9 v4 Dvoid        APU::ExWrite( WORD addr, BYTE data )
8 s, V! \0 o$ p% `1 _2 m{
: N& e$ }$ Y2 c# V3 v: U, Y- n$ o        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
+ ?& e. K# [; g8 j( F+ F0 _: c2 ]- S4 X7 x0 Y% Y5 m
        if( exsound_select & 0x04 ) {
8 y' M& M8 I) m                if( addr >= 0x4040 && addr < 0x4100 ) {
2 m3 r4 B; @) W" A- o7 e                        fds.SyncWrite( addr, data );
' _7 b2 R$ S' h1 y                }
! Z; `, s. s& Q/ w1 a        }
( M2 U# m9 A3 Y( T
0 \! U' p. ?5 ]8 q- C3 Z        if( exsound_select & 0x08 ) {
$ _1 y3 ?- G$ a; F7 K                if( addr >= 0x5000 && addr <= 0x5015 ) {. Z8 _8 n' Q8 c1 x2 T+ R
                        mmc5.SyncWrite( addr, data );3 {! ^4 `# [2 o* _9 C* f+ r: e0 n7 M
                }
9 W  Y8 |8 V1 x6 g        }
( e3 N$ N8 p7 e& S/ D2 ]}
( ?! J% l8 E8 `5 B; n" N( M! @
/ ?0 W1 p/ \- K; l$ E, ovoid        APU::Sync()7 B4 Y) N0 m$ @2 ^
{, l, H/ ^; Z; p) |8 X) C
}
0 g+ k- O( D! q% C- }+ O
' B% H; H0 w" D: pvoid        APU::SyncDPCM( INT cycles )
* x" ]: u( r# m$ l2 O{# i2 i" i+ x) B9 u# L' ]- c2 q
        internal.Sync( cycles );
/ [& Y+ s  a/ x  W- F3 A
" D* D$ K1 s7 w# y% ?' r( m        if( exsound_select & 0x04 ) {0 K" U& W. B& H" ]6 Q
                fds.Sync( cycles );
0 u9 K( X3 \8 ^7 M        }8 m+ s+ f) A" D' h4 E! ?+ W
        if( exsound_select & 0x08 ) {, G6 i1 p: O1 V5 s5 S0 l# z. O8 Q
                mmc5.Sync( cycles );
7 s- P8 d  ~, I' a; m" j! `: e        }
" ^/ f7 l. @, v% U, m}
% o$ o: {' D8 b3 t2 Z
3 l+ o: h+ ~; ~+ @- x1 a5 Lvoid        APU::WriteProcess( WORD addr, BYTE data )  }% s( h9 Y  m* \4 c0 e
{5 D1 b- I" ]7 v4 m9 [
        // $4018偼VirtuaNES屌桳億乕僩* E7 w8 `1 \8 {/ s. [& c
        if( addr >= 0x4000 && addr <= 0x401F ) {! t" n5 Q4 y- H" a4 }
                internal.Write( addr, data );
+ N: g( z: p9 D( I  X        }1 L* G1 R' e; k# k/ g" [: b2 H
}0 H% o2 u# ~4 A" ~
: g! a5 h  R$ @6 d
void        APU::WriteExProcess( WORD addr, BYTE data )
6 S9 D5 s7 Y. ^2 G' u  Z7 V6 D{
7 s* \6 |: f7 g9 d  X) [        if( exsound_select & 0x01 ) {! P1 U% i; F  J  _2 W* P! q
                vrc6.Write( addr, data );
* E9 {0 M( F! S7 A        }
2 O4 j8 n2 i+ X        if( exsound_select & 0x02 ) {
3 ?: H: J7 r# u7 ^+ b. m+ P                vrc7.Write( addr, data );
' z4 ]4 s1 @8 O! V0 ~1 z        }
$ i' |5 X4 n# `2 W3 e        if( exsound_select & 0x04 ) {3 x2 I' ]* i  m( W2 x$ [
                fds.Write( addr, data );1 O; c( d4 P- E3 `! Y
        }2 ]7 f4 ]1 [) w
        if( exsound_select & 0x08 ) {8 B" X9 p. Y/ c" {. r, q" D
                mmc5.Write( addr, data );; K' U6 Q6 ~7 j
        }9 T: N- ^4 c9 p* q/ w& E
        if( exsound_select & 0x10 ) {7 K4 b3 J0 n3 j9 U0 d; r
                if( addr == 0x0000 ) {* m. U$ Y; L& ]4 M
                        BYTE        dummy = n106.Read( addr );! b- R/ u& D" k0 \
                } else {) f$ F2 `$ }: k4 J  p
                        n106.Write( addr, data );
6 l& y3 j0 D- I9 j" T3 \7 v; X' n                }
* U' X- `1 ~! {) v4 v# G: A4 u/ I3 w        }
+ t8 j  ]4 t! s4 Q- A' W        if( exsound_select & 0x20 ) {! @$ U+ ]" ]2 d) ]6 S+ x# t; H
                fme7.Write( addr, data );
4 ~) |, O9 o/ I& v# ~! T, f+ v        }% @6 H% k6 T/ l
}) A% ^, L) s9 w  V1 M8 @" s

) C  x: m$ o$ H  h" Evoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )& ]/ {4 N' D" q" C
{
+ U* |6 R+ A! t0 I" s$ KINT        nBits = Config.sound.nBits;
- ~! g% ]. r4 x5 T" }, {' O3 z9 p# RDWORD        dwLength = dwSize / (nBits/8);' \) z& C! }/ h' h- t+ ~
INT        output;
$ Q6 ~$ g) [/ DQUEUEDATA q;: o5 i* ^6 S* b- K
DWORD        writetime;& h! `" j# D! h- u* k
7 d7 \% s* m' A' O9 l; b+ Y
LPSHORT        pSoundBuf = m_SoundBuffer;
$ R" [: |& P4 a0 v9 }6 o5 HINT        nCcount = 0;
3 N6 a$ F# ~( O" O$ L) V  ~
& f' {; R+ _$ v0 G# Q$ w/ f/ e. e, HINT        nFilterType = Config.sound.nFilterType;
+ h' f, ]3 \* J2 S7 ]0 Q2 y6 M$ u7 B3 h
' W+ V1 l0 r4 _: Z$ c$ E        if( !Config.sound.bEnable ) {
/ j7 C8 X* r: e# x# p2 L                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
, a' h. B# l( Y+ s                return;
* m3 M8 ]% i* N        }
. {# [( E- P0 m+ v
) m, h& s# P- Y% l3 f        // Volume setup
5 Z* D9 d+ t. H! U7 H/ @        //  0:Master0 J  X/ ^& J1 ~, t) o. A6 p; X
        //  1:Rectangle 1) S0 b5 p- A: J( L" w9 m
        //  2:Rectangle 2. [3 d+ h4 D7 M" _: X
        //  3:Triangle
  v2 q# ?% \- e* ?        //  4:Noise3 N: c, ^1 W2 z3 T4 W2 _3 L% b
        //  5:DPCM, A4 b: \( |$ Z! E0 R# X. T$ w
        //  6:VRC6: q$ U: I9 K8 A  p7 X5 v
        //  7:VRC7
# T2 x7 J# z- W' B) Q  \        //  8:FDS- V; }. h9 F/ X4 W! {) b
        //  9:MMC51 X; Y3 s) j* t& w
        // 10:N106
6 x7 T1 O* o) j: Q7 O/ o* {        // 11:FME78 ?: H+ R% T* x/ H' B
        INT        vol[24];; G- G- ~5 k" W+ v8 O" d4 W6 b
        BOOL*        bMute = m_bMute;% b( A( f/ X4 N4 \+ b( k4 x
        SHORT*        nVolume = Config.sound.nVolume;
) |9 y& S6 s9 n4 @) |( q' w1 I1 r3 W7 z. G4 Q0 }7 f
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
) u. Z0 _# F7 X
: A& P& F: s  c  _6 ]+ Z# V2 K( s        // Internal
' p% E0 C0 p; Q+ T1 E$ z        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;6 v1 u- k+ e7 e4 }  k4 l  [
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
" P; T- _) J# v$ r2 r" E        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
$ d0 t: `8 Y. B/ a! u% d2 b, Y        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
3 H, ^8 b! z5 J' @/ I8 B7 e        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;2 _+ R1 ?8 \" D$ w
2 ?9 h+ @8 i3 v2 ~
        // VRC6  m! {5 h9 I1 z1 e+ o2 O9 B
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;/ M& \# B* V8 Q5 J' Y& }
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;8 h  t' L- N# p' X1 V
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;6 _9 M* J, V) {: |0 ^
% S% C3 Q, w* o7 n' o
        // VRC7) V7 H, |$ K4 X! m; o, ?1 {& y
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
8 h$ i: W% ?9 ?( Y2 K8 M6 ^9 _: E+ W4 v& Z6 f
        // FDS
0 Q, X. x' V) c, g  O: ?. k( q        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
) P( o7 G6 g, @2 W4 J) D; h  o( j$ N5 y7 P
        // MMC5; x; a$ J4 \1 `5 U6 Y5 J2 [& m
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
. `1 b  y. \% f        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
0 n) l: A/ X8 Y/ u" U1 t        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;! P2 ~" W9 O, y: @& ^/ _
# N; ?' C' q$ c# X
        // N1066 b0 s+ \; U: r" _1 e+ t& T
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;. w$ y( O4 _: _& T# p
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;% G: l! X; L5 U" H4 L
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" Z+ P$ k8 A: C$ L" m        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
  }' S7 s& B5 k& y        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 E2 [  h" _8 f6 m4 \        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
3 e3 i# A: s' a) f        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;) M5 J( M9 ?' d0 G2 M4 G1 q8 T
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
) |' c0 I% r7 ?1 ~- D9 h/ b0 u! o* p4 b- O/ A. X
        // FME7
  C4 W0 ]# \# g0 R3 e6 y        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
9 M( p" U+ g: _" _+ W/ g+ Q        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
6 ?( C- x% [. o% G9 W        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;6 q" D' ?. ?( s) r8 B/ X

7 m- O9 e: H% ]9 D& ?! K, O) R4 d//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;" i8 ]; Q( c7 s9 [4 o' X
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
7 ?9 Y$ F% N# @7 r5 l
, j- U2 n& x, [        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
9 l, t. ~2 ]' P+ O        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
5 O4 b1 Q* W% P* N9 r$ d$ L. K% T                QueueFlush();% C$ |+ o- u9 p8 g
        }
6 \, c' Q$ }& J3 Q" g7 p/ p4 o/ e1 E' `: T/ o1 Y" \
        while( dwLength-- ) {
  c& D( L! j5 T% ?                writetime = (DWORD)elapsed_time;. z4 z- G6 V. G6 P' D: m# v+ B
) o" K3 U" m. `8 t
                while( GetQueue( writetime, q ) ) {9 o8 _9 w. K' _% \- H; m. W& c
                        WriteProcess( q.addr, q.data );7 @+ _* t9 B! f& _
                }
$ C9 v1 G( T3 y: k  r: T( S+ d( R0 [
! S$ Q7 N4 i% A6 d5 \+ _$ R2 t+ L                while( GetExQueue( writetime, q ) ) {
7 C$ [& Y* D# ]/ e3 f' X" d                        WriteExProcess( q.addr, q.data );8 {' M! E/ e9 R- u/ y
                }
8 T6 A/ z3 C2 S. `6 Y& b6 l5 Q' p3 t# [
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7$ D% k  A2 {2 Y8 T
                output = 0;! I7 j, P% ?/ b/ I4 \
                output += internal.Process( 0 )*vol[0];: l; t; v9 a0 x
                output += internal.Process( 1 )*vol[1];1 H, u& E. A. M2 M0 H
                output += internal.Process( 2 )*vol[2];2 S1 M2 q/ h8 ]8 r' l7 j
                output += internal.Process( 3 )*vol[3];- c3 }% X* c( ]/ o! L- y
                output += internal.Process( 4 )*vol[4];
2 p# X5 B2 U. R% a0 P- U3 r" o% d8 Z& j8 P: W
                if( exsound_select & 0x01 ) {; @- ^3 v* D) [/ Q  K2 K1 P
                        output += vrc6.Process( 0 )*vol[5];
1 D% _4 ]1 n: q  f                        output += vrc6.Process( 1 )*vol[6];  v6 @. j8 P, H0 L& m) n
                        output += vrc6.Process( 2 )*vol[7];" x/ M) V# t3 I* O) n! ~8 }
                }
2 p0 F, N- t; p5 ]2 R( L3 |1 T3 N/ j                if( exsound_select & 0x02 ) {
, h4 ~: R  c- Y& Z) [( ~! L. L                        output += vrc7.Process( 0 )*vol[8];8 [1 Y3 ?: y( ?
                }
$ y$ D# Y3 [! z0 u, o                if( exsound_select & 0x04 ) {
% G' u6 [+ E  _- H- |' H, v                        output += fds.Process( 0 )*vol[9];
" `- g/ P6 M2 \8 d4 q                }2 h) m6 I& y* S8 m" M% H. A9 L2 q+ {- k
                if( exsound_select & 0x08 ) {
; T6 V, D. r  C* A. i. }' s' R0 F                        output += mmc5.Process( 0 )*vol[10];. B. x& w& S* ^8 a9 m. [
                        output += mmc5.Process( 1 )*vol[11];
/ U0 z& Z+ V1 X& B7 M/ }                        output += mmc5.Process( 2 )*vol[12];; t' O: L" B3 q, z8 v7 O
                }  P% J. p8 }: g6 c
                if( exsound_select & 0x10 ) {  Q# U% U* ^# k# G3 c1 L& `
                        output += n106.Process( 0 )*vol[13];
  T7 Q4 g. ^( X  I$ m- n0 Q  t                        output += n106.Process( 1 )*vol[14];8 y* R" g7 |7 @& E: {
                        output += n106.Process( 2 )*vol[15];
3 H6 v: n  q( w1 O  C0 R! L1 w' a                        output += n106.Process( 3 )*vol[16];
4 q5 T+ }. @% ?2 A* J                        output += n106.Process( 4 )*vol[17];/ N" F, W2 R) H/ o; E
                        output += n106.Process( 5 )*vol[18];
5 S! |, ?7 ~5 m8 h9 ?                        output += n106.Process( 6 )*vol[19];
1 g! B$ L, {6 n' V; @                        output += n106.Process( 7 )*vol[20];
9 [7 Z+ p' B$ W7 c" z" T                }
* d& |. e4 C" ^' e) ^0 [' O                if( exsound_select & 0x20 ) {0 a/ S  M% [+ I
                        fme7.Process( 3 );        // Envelope & Noise/ M+ C" A; u: [4 i
                        output += fme7.Process( 0 )*vol[21];. p% j0 O0 O  ]8 d
                        output += fme7.Process( 1 )*vol[22];
. L( e6 Z, {7 j& M4 g5 q* u! w( I                        output += fme7.Process( 2 )*vol[23];
+ X0 V3 R5 B# D2 a3 E                }
+ v) @# V5 H1 v- l2 d+ C$ S: k$ W3 _; k  C8 @" }4 H
                output >>= 8;
1 Y. y/ Y! V( {6 b! w1 q1 O# W! V0 e
                if( nFilterType == 1 ) {3 i2 v: n+ R- D# Z8 O" o6 `
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
9 G# Y$ P8 l* g  U; f2 Y2 g                        output = (lowpass_filter[0]+output)/2;# k* V# ?9 `- t6 \  Q
                        lowpass_filter[0] = output;
2 [/ {3 n6 ?( s                } else if( nFilterType == 2 ) {
& h2 w, n6 T* ^2 l2 P4 [                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
# W2 p7 x8 _1 J+ \% q. E                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;5 E! E1 n# l6 r  M% i: L% `
                        lowpass_filter[1] = lowpass_filter[0];. B$ o% `2 k: c/ c1 r
                        lowpass_filter[0] = output;
& d6 z+ @7 S6 H) @                } else if( nFilterType == 3 ) {! C$ x  F9 _% `6 I  t' W% t
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
: ~! u2 U- Y1 n0 }7 n                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
8 V1 s' y0 \; o9 U9 b                        lowpass_filter[2] = lowpass_filter[1];
) a4 @; ^* a, P8 U. v                        lowpass_filter[1] = lowpass_filter[0];0 A0 X6 @& Y; t6 f
                        lowpass_filter[0] = output;# l$ J; A) n! @  q7 g& y9 K
                } else if( nFilterType == 4 ) {; Y, p, f& L& G  x1 d5 |/ W
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
& X8 S# N& f3 v                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
( I8 A/ Z" K" X- m' e' u  X/ w' Q                        lowpass_filter[1] = lowpass_filter[0];
" W/ A% |; A/ x  z$ @7 ~                        lowpass_filter[0] = output;
5 W( g, G- j3 @                }
5 U( f' H# T2 }0 }* G/ h
6 h( C& P: \' X- R#if        0
/ ^8 H! s/ f+ O7 T0 r( B                // DC惉暘偺僇僢僩5 Q/ T9 x, t$ e; g
                {' ]3 _, i% N4 Y
                static double ave = 0.0, max=0.0, min=0.0;  j7 P; O; Q6 T! b
                double delta;
2 @2 c# F* n1 Q7 b                delta = (max-min)/32768.0;) r% n5 C- V  K- w4 q
                max -= delta;/ m9 W3 {- H) g8 [" |
                min += delta;
5 f- u7 h, o1 S" d7 Z                if( output > max ) max = output;, C! j% Z# s' V
                if( output < min ) min = output;
1 {7 h. G# b8 y$ `4 p                ave -= ave/1024.0;3 d, }4 W( ]  [/ H. ~+ Z) [5 ~. T
                ave += (max+min)/2048.0;! L( o' S; ]( U2 K
                output -= (INT)ave;" \7 S) z% {! j3 C; Y- i
                }' n& P" b3 F( h9 X5 L4 y& P- U3 I
#endif
: u$ r% n* j6 z#if        1+ J8 {* Z/ g) }; @
                // DC惉暘偺僇僢僩(HPF TEST)
: G6 S" J, X0 r2 ?! P                {' ?5 r; `; B; I) ]  y! ~$ I
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);4 X$ |+ P; R  j& I
                static        double        cutofftemp = (2.0*3.141592653579*40.0);, a" C$ w# I9 [) g+ z1 g
                double        cutoff = cutofftemp/(double)Config.sound.nRate;) _3 K7 L% H, D$ @6 |1 U. d' p
                static        double        tmp = 0.0;
7 C  C4 Z, w, J4 l                double        in, out;
4 h* {- V  l( [6 A* T/ l. a/ ~* Z, H8 }6 g# {& Q$ F5 q
                in = (double)output;. V' N& A# E! k0 F: L" Z# ]
                out = (in - tmp);8 v3 V8 g  q5 A, E3 i  g' F
                tmp = tmp + cutoff * out;
" X" p5 H1 W" F
+ Z0 z3 i' p0 \. Q. ^- z. `                output = (INT)out;
# {2 U9 Z/ s0 r5 y8 Q0 x                }
) D  q% U* o& Q* e- |9 I$ M#endif
6 k  ~" Y1 I$ V) g#if        0
" N+ u) t2 K  C                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)6 W% @% d) V& u
                {; a4 F9 \7 e, e
                INT        diff = abs(output-last_data);, ?0 S& E! E( m
                if( diff > 0x4000 ) {
" ]3 a  D( }- J1 s: A1 l                        output /= 4;
9 o9 w$ M. h  C* s% A8 f! g                } else % @( K* s7 U& O" {
                if( diff > 0x3000 ) {
* J: S: U4 p  X. X( `                        output /= 3;$ @) b) p6 Y. t7 Q
                } else  V4 D5 {7 i) `0 q- C% t, l
                if( diff > 0x2000 ) {
+ M6 J" T5 I$ W' b' q# V                        output /= 2;
& K- o8 G' {# N$ x' s9 T                }! }  E4 P  P# V& _3 Y
                last_data = output;
2 A6 O& g. B4 ?2 F9 C2 Z                }
; t4 B- {+ l7 l) W#endif
5 e! Z5 E- {1 y, Q& T: Y3 A3 P                // Limit
- ?1 d& Q& i2 \                if( output > 0x7FFF ) {
8 i* D+ y; x! |# G                        output = 0x7FFF;
! _& l" p! F; U                } else if( output < -0x8000 ) {/ X1 i( N+ ^4 X5 R9 A; j2 N
                        output = -0x8000;* T7 g: P7 H2 p
                }* s1 s* @# t4 E8 w9 G
, c; _% @. e" r: J
                if( nBits != 8 ) {
: y1 s+ F0 [4 F; S                        *(SHORT*)lpBuffer = (SHORT)output;
. n) a1 V! Z3 K! @. o3 G0 F' c$ M8 r                        lpBuffer += sizeof(SHORT);
' e8 H- z/ F; M  F                } else {) T6 B. {( A, u, q1 u7 B
                        *lpBuffer++ = (output>>8)^0x80;
9 X. F& q) |/ \- R! Y; }0 ~                }& I4 g1 o& @) R) A4 j$ F6 L

. C% T1 X. ^& D5 Q# _0 ^4 r                if( nCcount < 0x0100 )# Y+ }$ R; L8 [7 d
                        pSoundBuf[nCcount++] = (SHORT)output;; N8 A, M2 o7 N4 x

6 V  K- u5 `  O+ d5 x//                elapsedtime += cycle_rate;, F6 \0 m" H" I$ W7 {$ R, A( O
                elapsed_time += cycle_rate;; P- Q) D" h1 e! n7 |
        }0 u3 m" s9 d- E; t8 g
6 p/ t! Q; f& M0 z& y5 e$ \
#if        1  n8 F( _" n6 x* T. a+ _6 v2 }
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {4 F' D6 K  i$ f. n# z. T8 K
                elapsed_time = nes->cpu->GetTotalCycles();% j: I& ^- w( ]& H) q+ A. ^
        }
* X4 J3 q$ @2 `9 A; I        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {) ^  l# K. w$ U7 E
                elapsed_time = nes->cpu->GetTotalCycles();
3 ~: J! ^' g; e5 ?! J) M        }
0 i4 m* X+ ~" M& B/ B#else3 |8 ^5 [* L  k) E
        elapsed_time = nes->cpu->GetTotalCycles();: z# X* }8 z/ {: m+ Z0 T; F. V: y) h1 \
#endif1 Z' z4 }6 y$ j4 G2 u4 o& R+ q2 I
}% w# L, t- i1 a, S5 B
) Q6 x% o: `3 v' J! D% N! ?
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)8 E1 q2 j* H7 t+ C9 _
INT        APU::GetChannelFrequency( INT no )
6 O2 L/ y; Z2 I, i( d& u{
, I* c  |9 F. B( [& Y4 m        if( !m_bMute[0] )9 a+ x; o7 b1 C0 w& O2 N5 E, Y1 h
                return        0;
' b1 O6 p& [/ q) A8 p
+ f0 b1 c4 D8 ~& B+ C        // Internal
- \; S8 t3 u7 v6 x        if( no < 5 ) {
; M. _1 H5 `! o! q8 }                return        m_bMute[no+1]?internal.GetFreq( no ):0;
5 x2 d, b5 a5 p( T& w        }7 Q$ o% A/ I' a" U
        // VRC6
& v# c, A, S6 b        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {2 G+ @) n6 j9 D# N
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;+ p* g8 Y: x/ u- U' C5 c; A1 U
        }
/ u+ I, q# t) c  ?9 p) s3 R4 F        // FDS
" k6 H  W, l  `1 a* x: J! O1 B% O) t        if( (exsound_select & 0x04) && no == 0x300 ) {
7 P2 R, o' u7 y/ w0 c                return        m_bMute[6]?fds.GetFreq( 0 ):0;; ]! Z$ C( _3 E( s6 X
        }
4 R" v9 G1 ^7 ?. L8 K" d        // MMC5
* i1 h/ `7 Q: Z+ R) R* y6 o6 t        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
" o8 i6 I. A- [( v$ h- K$ D& P: }                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;0 {" S  g2 _+ }# g  Y7 k
        }! E& `' A" h8 _( z
        // N106
2 Z5 M2 I2 n! P! r        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
5 u0 N3 q/ L0 Z, @. L                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
- S, p9 P) s( `        }6 Z8 }6 H5 i6 x2 V( b
        // FME7; G$ Y* b* C0 A8 o4 m" N1 s
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
; B, X" Z3 h+ ^: ^3 _                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
3 Q/ c( J$ y, C5 _5 N        }* W7 @, Q( f, O# L
        // VRC7: M; j" W9 K* |/ ?$ M* J
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {5 M- l4 V/ K& d0 n  G% {
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;) [* c2 I# d7 W. q
        }+ X& V$ Y6 i* {+ U' Y9 S
        return        0;* _9 k7 K- X! r% u
}
5 ]4 y1 P! e1 y8 L6 |1 R! v3 }1 w( W0 i2 {4 X
// State Save/Load5 S! E- L4 ^! w6 x( _, O
void        APU::SaveState( LPBYTE p )
: p% B; [; G0 N1 m{% ^0 i; [" I# ^0 Y! h; M# s
#ifdef        _DEBUG
# B/ o' k3 [/ h% K) VLPBYTE        pold = p;
# F/ F( J/ T+ E. _+ K: S#endif
! l8 m7 ~" I. k" d5 f
' n( B& t7 s. {" ^0 H        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
% U* [2 {, [0 l$ ^; a6 ?; \3 b" f        QueueFlush();
, [8 S4 ]* R! v: ?$ l8 S6 q# K5 C( k) `
        internal.SaveState( p );
" k0 X1 A% n' f, }- w        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding3 \% S; F' f1 I' ~! o; N# v
. K0 [- I( D) G
        // VRC6) H6 a% }! q9 L8 m& M% R
        if( exsound_select & 0x01 ) {1 w- @: b+ M% `9 x0 m
                vrc6.SaveState( p );
' A+ [2 `& j5 j. D  m0 L; K                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
3 S$ V3 z! e7 j( @- \9 [0 P        }5 n, `: R6 M. H/ N: E  s( q
        // VRC7 (not support)2 g( ?4 b* L; _) T8 L& F
        if( exsound_select & 0x02 ) {1 F' ]- f. Y4 h9 P" @# N; A
                vrc7.SaveState( p );
- Z& ]# N  }: y4 H# \                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding/ n) [& }$ |; a" ?% V& {- [; H. Z
        }
/ {% S$ [! d# ]# S        // FDS
' _# g* |5 g) H/ V- M; c        if( exsound_select & 0x04 ) {; S* N6 B( S! m' R6 ]3 v  R
                fds.SaveState( p );
' d; ], r' i: w7 ?' B                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding. \* ~# l" h5 z; }6 z/ q) N
        }
; |; n) ^. F: W4 V        // MMC5& g+ P1 }' V# }" \' `6 X
        if( exsound_select & 0x08 ) {
7 p7 s3 T. A, X7 j                mmc5.SaveState( p );
( ^/ g  O, H! X                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding' D1 p2 Y1 T* s( k; Y* g: Z$ B
        }
* ?' S8 Q8 y9 k        // N106
" r1 Q4 P6 D2 c7 {        if( exsound_select & 0x10 ) {6 J2 _/ w0 \' _' |) B( r7 \) |: x
                n106.SaveState( p );
, ?/ y/ {9 N* b$ x& V                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
( ^4 e7 ^) o# z' m% r1 u/ N        }
; J! h2 |; L  t2 s+ I( l        // FME76 d6 u3 L, Z! `1 B
        if( exsound_select & 0x20 ) {; s6 q  m2 `% ~
                fme7.SaveState( p );' F2 c/ V/ v7 f' x; z8 K
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
6 s/ S- a/ ~1 \" U0 d6 D" Q8 |) p% j0 S        }
( D: Q" e3 r1 A& p+ n2 n
" ^  N5 w( v5 B+ ?; \3 k* |! Q#ifdef        _DEBUG; g: G" b# L+ I
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
1 y9 u6 v0 _' }8 M! |#endif2 T( x$ L( f! i; Q
}
9 ~/ d1 z0 e& y, X# r9 [$ g# w) G! l+ w8 K+ p" r( s
void        APU::LoadState( LPBYTE p )3 R4 c2 B6 N9 t; E, P! j: x" \+ U
{& H2 x* d( e3 A9 G  X  J
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
6 ^' W$ o$ p, P& J        QueueClear();9 I4 Y5 J, X) Z, m4 H$ X
6 {& |: s9 v5 h' I' ?
        internal.LoadState( p );! q8 h) J; D0 g0 ^  r1 N! W
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding4 _$ l: F1 w$ z5 R5 C( {* f

; _9 P+ }7 @/ z, l5 [& i4 B2 `        // VRC6
, m# c& V: q  @        if( exsound_select & 0x01 ) {6 B$ C! a( y& g9 r0 Z) I
                vrc6.LoadState( p );
# V- k* k% a+ Z, W9 e5 e8 W) m0 z' j( W                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
7 g' e$ y0 _3 ^3 Y        }
* B: k/ r  r: Q9 j: l1 t        // VRC7 (not support)$ \# G6 q( I% [; H+ K, v1 m
        if( exsound_select & 0x02 ) {6 G0 _' e' U+ ~; `) h# M" W
                vrc7.LoadState( p );, B# o! C% G# Z% H6 G1 ~
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
' J, Z6 P# I. [# R% y. u4 a        }
# i3 A0 m% ]! C6 ?: r' h  z$ W4 y        // FDS
8 ]) w( _" d! t! Y2 I        if( exsound_select & 0x04 ) {
& Q& y& V# _4 v) ^4 s                fds.LoadState( p );6 V6 e* Z& q. L: D# }) N2 n
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
0 h: b9 Z# c: a6 x: g2 z        }
1 c: r7 X& f# n( v& L        // MMC5
# K. X' A2 c. D! q        if( exsound_select & 0x08 ) {
0 B7 {  N  z7 C1 g' j4 E5 b                mmc5.LoadState( p );
5 v- _0 c+ E# q$ O                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding9 Q/ {4 D: K  A3 R8 _3 S; O7 E
        }+ y6 Q% `& }3 ?6 e- B, b
        // N106& |6 P6 s+ \; j# e% @. S
        if( exsound_select & 0x10 ) {
: Y  X3 ^& S' k& T) I7 m1 e7 A                n106.LoadState( p );
$ R  e! i0 |3 `3 h' ]; y4 Y4 X                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
: B0 _) i, u$ N# }7 G        }
! B/ |- L5 [, H% r        // FME7. g7 D9 E* X$ D. w9 p# e
        if( exsound_select & 0x20 ) {
8 R( J+ P- ?$ F* C; ^  b* B                fme7.LoadState( p );
  {' Y1 [8 r) ~5 o                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
# A$ c' B2 n: s7 Y) ~% l        }
' e' J- I( x$ a" E}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
' L, G) g8 n1 _9 U可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
# Q8 }* e) B1 t0 W$ r+ K感激不尽~~

' k( y- B# Z8 k# W! J恩 我對模擬器不是很有研究,
: S9 M2 q5 @8 E1 o4 `雖然要了解源碼內容,可能不是很困難,* F0 S, g, d3 }1 j2 X- E
不過還是要花時間,個人目前蠻忙碌的。
% H0 [+ O& f7 `. P3 I( Z/ t- g# P( t- g6 R
給你一個朋友的MSN,你可以跟他討論看看,! U  q, s7 q" T: j* i! f
他本身是程式設計師,也對FC模擬器很有興趣。
+ w  k' p: F  N, j) n- A
+ H; G; @4 [. ?/ `& c; {: PMSN我就PM到你的信箱了。& q+ r# C. d% e

6 D8 `  m% Z' H$ J: ]6 S希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 7 K+ Z0 w' b! l! g
呵…… 谢过团长大人~~
0 P: k; a! `' {
- d- Q" g. M! x, u
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 * Z; W6 ?" r  D- {, s# Z
团长的朋友都是神,那团长就是神的boss。

# c2 p8 T9 y" X2 w+ n; c  z  F, \哈 不敢當,我只是個平凡人,: ]0 H& r8 f2 A) u4 s
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙6 p  V, R) a* K$ J( ]; U
ZYH
+ k* p+ k% N! t9 H2 w5 T# r( ]# pQQ:414734306; j6 Y8 g4 D+ C$ T& v
Mail:zyh-01@126.com  g5 u$ P: L+ |+ r. R4 m

2 @& A* C3 O+ b! K# j. h: f; H他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 ) [/ J0 @5 b& L" M, I
再次对团长大人和悠悠哥的无私帮助表示感谢~~

( ]) O. o+ c" d" t7 P% g4 t. y不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-29 04:43 , Processed in 1.087891 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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