EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。/ O9 I3 E) F; j- q/ @
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
) X  e) B5 m5 W( a0 a5 X" |这里有相应的模拟器源码,就当送给大侠了~~) ~, V  K6 A" B
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
) O8 F' d, ^( f# W# h. g能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。- k. V3 M; }; `  K* t! y8 F- z1 f
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
* S. }# |2 R9 F5 c6 ^这里有相应的模拟器源码,就当送给大侠 ...
# D5 o+ w. N7 J
聲音部分(Audoi Process Unit = APU):1 w1 O2 x" N# H8 U8 W( d3 {
.\NES\APU.cpp
/ m, w; {  s; q' k.\NES\APU.h, p- R$ D+ l  T0 J* l
' b2 Y# z+ F- b0 A0 R- H! d' f! ?

8 s; i0 S  O+ G" W' x影像處理部份(Picture Processing Unit = PPU):
/ B: K/ v. ^2 G0 X.\NES\PPU.cpp
1 S' W6 T+ g6 b.\NES\PPU.h* D; |* `9 a' Q
* N+ @8 G6 k& _/ a/ Z
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
' _: _, A' @* v- b(由于很多专用术语和算法机理都不明白,所以看不大懂……)
. D5 `5 n& a3 s# l" e  ^3 c//////////////////////////////////////////////////////////////////////////! y7 n' @+ s+ e. z' O$ l
//                                                                      //) X8 A9 X) a* C7 e& n/ w# ~1 s/ M, u& H
//      NES APU core                                                    //, m. T' X. F9 Y7 a1 d8 ^/ O
//                                                           Norix      //( c  z5 [5 ~, X# f& K
//                                               written     2002/06/27 //
# i2 ]! J2 j' @& d: S: W//                                               last modify ----/--/-- //
, D2 V( b7 C8 x0 A5 w//////////////////////////////////////////////////////////////////////////: s. ^5 D9 g' P7 X5 U7 L1 h( Z
#include "DebugOut.h"
" g0 w+ w/ x* `, @#include "App.h": V% R% T# x( q( m( s% Q0 I7 D0 ], W4 S
#include "Config.h"+ |3 v; x& m0 j- M
  D( x+ f" p! V8 h  V4 w
#include "nes.h"
4 A+ V5 ?+ _1 B8 i' T8 }#include "mmu.h"
+ D; k/ T- B5 }. h3 H#include "cpu.h"
/ E  D& m& b9 y% _$ r#include "ppu.h"
8 U6 c+ A. t2 h/ ^' p. Q#include "rom.h"
* r8 w" y, m# N#include "apu.h"( O$ H* F4 s4 m5 x  I- }) F  q

# ~5 |: r, f+ {; F' h" K) N// Volume adjust( {7 D2 |- X* d  |
// Internal sounds
( f. x; [6 m& Q  ]# \1 q#define        RECTANGLE_VOL        (0x0F0)
( [9 t5 Z2 c: Z2 Q. k6 W# Q#define        TRIANGLE_VOL        (0x130)' O1 d8 w6 w0 `4 ^
#define        NOISE_VOL        (0x0C0)
( d, p- P: Q$ `" o- z#define        DPCM_VOL        (0x0F0)
' `) b; K7 F: `8 _( s, m5 A4 P// Extra sounds* Z" C0 J5 _" `
#define        VRC6_VOL        (0x0F0)
/ J6 Q) g, [9 @9 O8 p, E7 C#define        VRC7_VOL        (0x130)
/ O% S% J7 M, X  H1 {0 d* g#define        FDS_VOL                (0x0F0)
6 ~; C, T( ?: v% u1 |3 _#define        MMC5_VOL        (0x0F0)& K4 {' _+ A! ]3 ~/ ?' P
#define        N106_VOL        (0x088)4 i. Q! Q/ h5 x; o( z  T
#define        FME7_VOL        (0x130)
+ Z2 Z" c( e/ h/ |! f) f% V
# X, {2 D3 x" N+ D: d! o0 ZAPU::APU( NES* parent )9 [- R! B: t5 \4 Y" A+ ]; d
{8 m! o+ O" Q/ ?+ A
        exsound_select = 0;
+ p1 m: s- U/ u" G5 J$ x( }/ B! A$ b. g8 V1 l& P1 |  f
        nes = parent;
' j$ k! b' \* V$ I8 J8 T9 j        internal.SetParent( parent );
9 T) G  ?: {  ^! K) A4 d4 o9 V( |/ ]1 p% w
        last_data = last_diff = 0;
* h8 z  n' S4 M$ A- Q( d- ~3 @2 g0 ^) h) D7 I/ U8 w
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
1 M/ R/ W! A. |" H3 B( \
* n. O: ^2 |7 {2 t- f- u: I& t7 z        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
0 d1 C. h$ a. A% j9 E" \        ZEROMEMORY( &queue, sizeof(queue) );
9 o0 \/ u7 M0 f& S        ZEROMEMORY( &exqueue, sizeof(exqueue) );
* O. ~; f" h9 [% v+ u' N6 i! z: ]( h, w, {! c+ ~
        for( INT i = 0; i < 16; i++ ) {" I4 U' y1 Q( [  ]4 F" _0 t
                m_bMute = TRUE;
' v7 d. w$ ~, w' e$ r% j; E        }
, G2 w- R/ ^6 [0 o; H}
1 ]( B1 `4 `( m9 E6 ~9 S8 G( t% e! x% U9 M, e7 x; ~' J) k8 h
APU::~APU()9 t3 o5 f# K! P1 @, T# J
{& N2 m2 S+ t+ V
}3 B7 e9 k5 n; n' E6 t! N

9 G) e: X2 \( c. ~) ^! jvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
8 _& f( C4 T- A! m2 P; G{9 I2 A4 U. R) n9 W5 t3 _
        queue.data[queue.wrptr].time = writetime;$ \) K! M# W* v# ?
        queue.data[queue.wrptr].addr = addr;/ L" I% @- @- j1 i
        queue.data[queue.wrptr].data = data;
4 `# \1 y% T8 q7 ?5 L4 j2 v* @        queue.wrptr++;6 M* S8 e5 e/ F2 D+ O- v1 s
        queue.wrptr&=QUEUE_LENGTH-1;0 ?9 y5 I6 X1 R; {6 V$ M' R/ N; u* y
        if( queue.wrptr == queue.rdptr ) {
4 S5 ~* o6 h' f2 V  k                DEBUGOUT( "queue overflow.\n" );4 K+ U2 ?7 y* f5 ^
        }+ O+ N: t1 O5 r3 F7 ?4 }2 v2 _5 N
}
* B" T3 u- s" M( Z6 B3 u7 d, Q5 K8 C2 O( L/ Q
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
2 l' K5 M- F* G{
5 X1 H' m3 S7 U% ^        if( queue.wrptr == queue.rdptr ) {/ h0 `9 w! t: j% R1 f( O0 M
                return        FALSE;
6 \) N8 ?  P) v# Z6 I$ ]$ |# t        }. k- N" n1 u+ L, A; C
        if( queue.data[queue.rdptr].time <= writetime ) {  ^! q5 N7 v8 H# R2 \/ K' j: ]
                ret = queue.data[queue.rdptr];, _6 P  x; J0 c) _
                queue.rdptr++;* `4 x5 T3 L9 c3 w
                queue.rdptr&=QUEUE_LENGTH-1;9 D) L8 |0 U8 X; E( N
                return        TRUE;$ \8 D0 B: J& z' f# M
        }2 j( o& B/ F0 w8 Z1 F1 o: e" R
        return        FALSE;
8 N+ d, w3 n3 R. n  V; d) _& {}
  d/ M1 @5 d. m2 Y
5 v( d/ a( c4 `void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
! f( }! y: i$ h/ _, ?  a, n{
% v8 T* K0 \1 o9 h3 m4 [8 g        exqueue.data[exqueue.wrptr].time = writetime;. R) q# l  u5 Z1 h2 X
        exqueue.data[exqueue.wrptr].addr = addr;
" \! h! X3 j# |& ~- l        exqueue.data[exqueue.wrptr].data = data;5 M. x4 W; K. N& f
        exqueue.wrptr++;
4 N. P' J9 g1 ]$ ?; m        exqueue.wrptr&=QUEUE_LENGTH-1;
& V0 Q- y3 g3 j) u4 ^6 c2 ?. p        if( exqueue.wrptr == exqueue.rdptr ) {
- h1 K6 H0 X# ~. Q0 H8 H) M6 g* e$ P, ]                DEBUGOUT( "exqueue overflow.\n" );2 t4 \* d8 h2 i; ~
        }
, ^$ Z$ i$ ~' \3 z}, ~6 z, m0 M) x" Y

/ J/ S1 R  G; L( P( }9 P" oBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )6 o8 l0 K6 Q7 R+ t$ h7 P
{! R4 p0 P1 w& m1 j
        if( exqueue.wrptr == exqueue.rdptr ) {3 E- V! y' E) G% [: `
                return        FALSE;7 B& Y8 y4 E% G' D7 t5 E+ ]5 E
        }% w8 o. q9 a, a5 f4 e, N# \
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
" _6 z0 e, @. x# P7 C% L+ t                ret = exqueue.data[exqueue.rdptr];
2 I+ ~3 u8 ]1 i8 ?4 B  D                exqueue.rdptr++;
+ w. r0 o, U) {0 I  f) Q8 t                exqueue.rdptr&=QUEUE_LENGTH-1;
9 c: Z7 @' S# A* r8 `" R; t; x                return        TRUE;  E0 A9 E. D1 |) Z3 }- i( u+ w9 i1 p
        }; y. q; U3 m! ^# u& M8 M$ E
        return        FALSE;2 i5 ~; a, x, T& ?+ j' T/ {
}
9 p% B% K. U2 G
- l) M6 {2 N2 e+ C- @void        APU::QueueClear()0 d2 \4 L, {+ g/ W
{
! @2 G: D3 r, p$ |" `        ZEROMEMORY( &queue, sizeof(queue) );
" r' n- A0 H2 c; D0 e# I- K# b: G        ZEROMEMORY( &exqueue, sizeof(exqueue) );
: Q  g" l) H3 t% m- k}
0 B6 Q) c, L. W" t" H
5 R9 q) R6 ~8 O: e, d  g/ wvoid        APU::QueueFlush()' H9 l6 S, e+ T' ]# K' Q3 Y1 }
{
; l$ ?' g9 f/ D6 V6 R5 a        while( queue.wrptr != queue.rdptr ) {: j6 _& [. g; g/ L2 k! O: Z6 i1 O+ M
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );( W8 Z- ^6 V/ x. i# a
                queue.rdptr++;% B% |9 b0 U- p  B- m( Q, h7 E5 t
                queue.rdptr&=QUEUE_LENGTH-1;
4 _* m7 `9 W1 e7 w. L6 ]9 W        }
3 ^: P- a5 z- Y& e/ W! I# L
# i) u- Q/ ~; S9 {2 ^; l        while( exqueue.wrptr != exqueue.rdptr ) {
  j3 U/ d' t* ^: f                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
+ ]. k8 \1 @: ^                exqueue.rdptr++;
3 y8 F0 h& N* L0 y( ?2 @5 w/ N                exqueue.rdptr&=QUEUE_LENGTH-1;- X5 o- Z3 L6 z6 N; M7 L3 Y
        }
0 f# L8 [3 o$ J+ F: J- P8 w0 N' ?}
6 D/ U: k$ x6 \6 e+ e' i: t3 [' H6 p; j6 |
void        APU::SoundSetup()
; {" j/ S, g- z{% J7 o: m; ~1 P6 l) k
        FLOAT        fClock = nes->nescfg->CpuClock;# U( b1 N* e* U" s  O
        INT        nRate = (INT)Config.sound.nRate;$ X9 }% p% \1 S5 f6 B( M8 B( n" Y
        internal.Setup( fClock, nRate );1 b. x, u( d  R5 j8 X4 I
        vrc6.Setup( fClock, nRate );% a% K- H0 N( s+ F) B
        vrc7.Setup( fClock, nRate );
5 a, E* W/ V4 v0 W1 Q        mmc5.Setup( fClock, nRate );
: a6 h1 n( {2 k9 J; U* \! `1 f) ~        fds.Setup ( fClock, nRate );; A( V  Q6 P2 ~' M  O7 s
        n106.Setup( fClock, nRate );; K) @  J9 l5 d; h* W. }
        fme7.Setup( fClock, nRate );9 q& A; `9 ~  Z" M, r/ z
}; p" d3 {% d# z' E# K
  g  |; W3 k2 [1 Z
void        APU::Reset()
1 U9 S; J5 L! e4 w. x{
+ T6 l" y! W+ x        ZEROMEMORY( &queue, sizeof(queue) );0 v; C" H! k6 ]
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
) K( I/ H" [! {1 L% Q$ w
4 \+ r' [0 Y2 z8 ?6 `! _1 G        elapsed_time = 0;
; u% y- M8 T& S) V( g1 r2 U, o* j$ {& @. Z& o/ a9 j; X: R0 j
        FLOAT        fClock = nes->nescfg->CpuClock;7 I5 g! Y' J4 K  f0 S! m- d; a  y
        INT        nRate = (INT)Config.sound.nRate;' Z$ a3 }# y2 _, R
        internal.Reset( fClock, nRate );
3 @, m3 X6 R! l2 @3 M; ]        vrc6.Reset( fClock, nRate );/ C/ ]  }/ }* x# u
        vrc7.Reset( fClock, nRate );2 s5 v# m  D. @. x
        mmc5.Reset( fClock, nRate );4 g( o' ]; d0 R" j1 @
        fds.Reset ( fClock, nRate );" d- e0 u$ z+ W4 Q
        n106.Reset( fClock, nRate );
: ~- B9 z* X+ m: I        fme7.Reset( fClock, nRate );
* w) W, G, I4 H0 m' V' W$ J4 g- @+ \5 S. }9 r* A1 L& i
        SoundSetup();8 y8 ?) v. N* M; e7 K3 i8 y; l
}
- e( f: t+ t$ r7 ]) T1 l
% u6 Z7 V7 g4 A1 `& J6 rvoid        APU::SelectExSound( BYTE data )
- l6 B5 x& w0 k{0 y" E, f; X# H4 C. j
        exsound_select = data;
( a, m, e% q4 |8 ~- L, o& m6 T}" d, J  D5 p. A( u

0 P, O: ?. M% x2 R) `/ CBYTE        APU::Read( WORD addr )' Z" |, y2 e+ ~5 K% Q
{
* `: a% d& L: b3 h  v$ `        return        internal.SyncRead( addr );
; _. i. J3 X' v( F7 d}
& ~! V2 B4 g' N% i# h8 }( Y* R  ]: F. c- Q/ E
void        APU::Write( WORD addr, BYTE data )- U  h* M, w: x. T% S) u# r. n
{
* m5 @. T0 t+ u& c  o3 s& L+ d* _        // $4018偼VirtuaNES屌桳億乕僩1 N% I( [+ |5 F' w9 S; m
        if( addr >= 0x4000 && addr <= 0x401F ) {9 ?. b! d) ^4 Z: z9 |  `; W/ |
                internal.SyncWrite( addr, data );
1 V7 b- \! o4 \' k                SetQueue( nes->cpu->GetTotalCycles(), addr, data );. T; c& X8 `# v  C; Z
        }! t' @! D8 F/ h) Q7 F% `
}8 X" g: k  ?% H3 @% t3 a

! n9 H; |" w5 E/ R0 s) ]5 u5 C; x9 GBYTE        APU::ExRead( WORD addr )
0 J, j1 K/ ]- i1 r{
# N4 M, N0 p: F/ }. YBYTE        data = 0;" R$ o/ [% _% {0 Y' k8 p

! M8 I7 x- p' q8 h8 Z        if( exsound_select & 0x10 ) {3 U$ O, i; d% m1 M5 M
                if( addr == 0x4800 ) {
" Z: \6 I2 J3 ~0 N: u                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
( L; q2 T3 t% H                }
2 q6 j9 _2 h- A! ~' I3 i2 o, b        }; n3 h9 U( |8 {
        if( exsound_select & 0x04 ) {5 Q' Q" ^8 Z3 b) [8 t
                if( addr >= 0x4040 && addr < 0x4100 ) {/ |4 a0 M% v4 Q/ [/ h# Q
                        data = fds.SyncRead( addr );# c8 N# p/ T  Y; L* u
                }
9 ~+ W/ [. s  l& D        }
# S3 A; F) j- @2 ?; Z. B        if( exsound_select & 0x08 ) {
. O, z* I7 j% ?$ ^                if( addr >= 0x5000 && addr <= 0x5015 ) {5 F- ]7 g6 O# b5 D5 n  e  J) I
                        data = mmc5.SyncRead( addr );
: Q( w& X) K- \6 g0 l* J" X                }
# U+ K8 W: c( ]0 S3 J2 X; \        }. S# ]: h! w( e& I  z' O2 w
, i; R; z+ ~. n1 l1 j
        return        data;
( [4 X8 L0 W5 r4 m}3 N+ Z0 V0 L: f; A

" T4 m. a1 Z& c9 G: C9 E4 n; ovoid        APU::ExWrite( WORD addr, BYTE data )* r/ Y3 R# `% L" {9 s
{" l- T8 w4 {& C4 a
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
8 K+ ^- g9 b. \3 ?) P  a3 y$ U9 ^7 V0 x+ r( v
        if( exsound_select & 0x04 ) {; `( r5 e9 k; _7 }! l( N
                if( addr >= 0x4040 && addr < 0x4100 ) {
4 g5 n( G6 G9 z4 Z8 ~& M5 G/ D                        fds.SyncWrite( addr, data );
+ Z* A( n8 R9 C  S                }
9 d- [* B* i/ W' Q        }6 |" u! C7 m2 g
" V: i/ k  G. _
        if( exsound_select & 0x08 ) {& D: i  x, L! I
                if( addr >= 0x5000 && addr <= 0x5015 ) {) e. \/ ]1 B$ ?6 U3 |; n/ v; p
                        mmc5.SyncWrite( addr, data );
# G) U9 q7 T: W* B                }$ w: G1 ~# g: V
        }% ]- B! `% \8 e# u: ~8 j
}
, J% w* F5 a* @! ?9 s1 O, F2 v0 {4 h4 R* H6 }7 n
void        APU::Sync(); d3 ^4 p% e# O
{1 a& K0 h& O" E. A
}
2 @: M8 U& n! L5 n# ~" b: Y. q: e7 Y  ?) U' m
void        APU::SyncDPCM( INT cycles )
# S- ]* `2 @! D7 B{6 ]- g3 S9 R% o
        internal.Sync( cycles );
4 L" {  D/ s$ V5 y
7 ]- q' Y( A, v! {        if( exsound_select & 0x04 ) {. |6 K3 J3 ]0 Y8 ]# y" o6 r
                fds.Sync( cycles );
# v, ^* W$ e) p# M/ G$ n1 V        }3 u( e( F  f! h. y7 \
        if( exsound_select & 0x08 ) {
! @& n$ W) x  \6 s' w3 ~5 [                mmc5.Sync( cycles );
' r( b3 ^. b5 y( u% b. B: x        }7 T) B, V+ \( w' Q  O: Q5 t) {
}
( E! N! }" |: @2 `6 v6 @: o- {# G5 n" _" c3 `0 }
void        APU::WriteProcess( WORD addr, BYTE data )
. J9 R" K' [% G  P; o7 m  Y{
& f( }3 C  t) }& |        // $4018偼VirtuaNES屌桳億乕僩7 O! P/ z5 N' Q4 f
        if( addr >= 0x4000 && addr <= 0x401F ) {
9 S1 f/ {* ~4 @4 Q! [                internal.Write( addr, data );
9 \0 z/ |& q0 V6 g        }
1 K7 g2 M/ a( O}
5 [, J+ b5 T* B8 ^8 d3 {' E
( d4 T8 M) C; H/ S  m; Evoid        APU::WriteExProcess( WORD addr, BYTE data )
. b9 n1 R; f+ s6 t2 [# M1 I{3 g9 {5 a2 o4 F( y  b
        if( exsound_select & 0x01 ) {( v5 W4 m0 l4 E. d6 r$ a5 u" f! c6 u
                vrc6.Write( addr, data );
1 N9 R  M3 S0 n% X        }2 `8 ?9 o& z, \  {
        if( exsound_select & 0x02 ) {* J* M0 v' y6 A9 x! ]/ Y4 D* ]9 O2 ?
                vrc7.Write( addr, data );3 N, T" k% Z5 m& @
        }
# v' v+ _- e  s7 P4 Q6 a        if( exsound_select & 0x04 ) {
7 |' P# z% r# A7 U  {. Y* S                fds.Write( addr, data );
& y) q% f" B7 R  O        }, U" X$ G6 |; c& l' ]' g
        if( exsound_select & 0x08 ) {
' e# b) F  h; T9 i- a                mmc5.Write( addr, data );
* l$ R! a. s5 ]7 Y& @( S        }9 |0 I+ ^8 b' T2 O; h
        if( exsound_select & 0x10 ) {
  z- D1 F  z' W' u& S1 n' w                if( addr == 0x0000 ) {
! ?8 r  Q9 K0 n5 |                        BYTE        dummy = n106.Read( addr );5 Z3 L; e8 w0 r
                } else {- Q. m( M) g2 g& m2 O+ W/ A
                        n106.Write( addr, data );  t# q  b3 ^* o8 Y' d
                }
0 ^- G7 r% m6 j) B: \5 ^0 K2 S0 V        }
% m3 g# V4 S0 A/ T        if( exsound_select & 0x20 ) {
$ }6 h( m* ^4 \8 s' r. J) q  t9 \                fme7.Write( addr, data );
& @- Q; |/ T: I/ h6 l        }$ `0 u; K6 w: }5 [; i; \
}
- C' i% |5 P/ I4 q
4 a: p6 p: n& @3 U2 l2 yvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )4 R! {" ^; h! i  k
{3 l" H+ e1 q* u  t% v3 o1 @
INT        nBits = Config.sound.nBits;
( W* q. j* r% qDWORD        dwLength = dwSize / (nBits/8);, h6 N8 V% m$ V( \1 q
INT        output;
& v0 h! z. q% m, E, ~+ {* m" pQUEUEDATA q;, f2 _* B% l; E, ^: i% }
DWORD        writetime;1 p0 f3 L0 i& ?- w; J2 ~
! a. T. A" z. J+ x0 B$ }0 a) b
LPSHORT        pSoundBuf = m_SoundBuffer;1 Q6 a+ b1 ~$ L7 F4 _- \9 {
INT        nCcount = 0;
. {/ _9 h% ?+ k$ i8 L7 t5 c9 [8 H
INT        nFilterType = Config.sound.nFilterType;
  b" H3 A/ ]8 i  ?. O& e8 e  i
  H  S, d; F1 u; Q4 r% J% r        if( !Config.sound.bEnable ) {
7 ]/ U# P# P2 d/ ]                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );# s6 [1 Q( z# K
                return;) g7 e! a4 E; I1 O! V! Q0 g: D0 o
        }
" p+ _: }! A7 z2 y2 x% s/ l3 x# ?$ v) }# m. i: M: |
        // Volume setup$ I! u7 y4 p0 f
        //  0:Master; a! H) g* M6 H: w1 t& I3 t) W$ j7 z
        //  1:Rectangle 1
9 r* \% c! d5 f) d$ W& o        //  2:Rectangle 2
  X$ y0 F7 }" u# S$ @, O8 D        //  3:Triangle# F) r8 ]; ~$ c4 `
        //  4:Noise! S: ?6 N! ?7 k$ u7 U# ^' F
        //  5:DPCM
* H2 a8 R( U4 O9 i( g) {        //  6:VRC6
( {. ^, s$ b! F' Z. M        //  7:VRC7; s0 f0 N9 x: n
        //  8:FDS4 Y+ E$ @6 ~/ x9 E  |
        //  9:MMC57 C( G' I( n5 x" C2 ~% t
        // 10:N106
# O( n2 y# C' k2 Z8 b- c2 S- A        // 11:FME7
( c: y; O, H* W0 \7 u$ t        INT        vol[24];
% E% t7 D# z* B; U        BOOL*        bMute = m_bMute;
5 ]3 O5 P( p7 w* G0 t- ^( _        SHORT*        nVolume = Config.sound.nVolume;+ U$ a0 q! J* a: |" t

% b  [! P. a1 l) g9 T, E3 i        INT        nMasterVolume = bMute[0]?nVolume[0]:0;* J; N4 U$ N+ [. [

6 K/ }" Z. n/ p% J8 x4 M% O! M        // Internal
0 Y/ S2 @: Z3 Y        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;) D$ f3 Y/ ?8 c$ }; J* G; H
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
: D; v5 k4 {  W# W$ Y( E+ ~/ `' ]        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;' S# h! Q& H" r# F3 ^. f# a
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;& I' I: g  b' F  Z" n8 P% c
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
5 M" X' S. I- Z: a
# e/ Q0 g+ i$ G        // VRC6  B+ B& d( b9 B: H: |# S# N/ l
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;5 L! l' P! A  ?9 C' j; A/ o
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;7 j7 e$ {" l& B
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;/ B- ?! r9 h# G& N. A3 H5 R

+ g6 W: [: t% e8 f- @9 R" s6 b        // VRC7; p4 Q2 ]5 L- `/ l+ E0 G, V
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;# r4 G' e0 c+ Y; ~7 g; e! v

7 `' I8 d* G' X  x. ^0 b9 l; F        // FDS
( i7 H; S' M0 X3 U        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;6 ^6 m2 U, M- l3 D! i) Y
. t# D5 f& ^; x7 z; [1 E
        // MMC52 S% W5 S: B4 d7 @6 A& q' F
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;* T" U; q: y# u' k8 g
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;% _7 L  d  u  c* f" Q# n6 E+ g* o
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
* U! v) ]5 e" n* I/ N6 B* h: J4 Q6 @9 ?$ D, H( q" T- h1 U1 O
        // N106
0 K: u4 m! k6 @0 N, g; D4 X' {        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- U; H% c( c; h3 T% t; E
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;) [8 P/ D) |& `; u: k
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
4 I# B# t" I* j  f8 s. G        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; a0 S2 [* r6 J
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;6 P7 l7 `+ W( `6 I3 k* t
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
3 V1 f: z& e2 }        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;& ?& ^& W2 R( \3 K# d( {
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
! ?- h9 h  K( [) l
  S' a2 K. S/ j# N- o& ^        // FME7/ S% D2 D: W4 ?3 X
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;" E8 g* W/ M5 f. n1 F0 y
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
! a/ A" U$ r/ x- m: l        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;- ~; D, Q% F  o+ {5 C4 e2 l
+ ^  U* |9 U; X: p) ~2 y
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;8 Q9 g  Q( \; @  b
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;4 `" q2 C; d/ S/ X" z4 C& c) V) I
  i9 R" A5 P' N" r
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟, g$ V/ l1 i$ W
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {: k  X2 O( L4 ~
                QueueFlush();7 M& p) m* m, N; Z9 e8 H
        }
7 A) B; {3 G. E0 \; c$ d0 }
8 a0 x1 L. ]9 h1 u! X) T! g$ X* e        while( dwLength-- ) {3 c1 e9 N' _# F
                writetime = (DWORD)elapsed_time;' L( A8 |) L3 c" K$ N

! ]! N" e9 p. Y" x* W" H                while( GetQueue( writetime, q ) ) {1 E% d# d7 j" K
                        WriteProcess( q.addr, q.data );  |; J# J# v. g0 B& e
                }) h1 U# S2 G2 h9 b% x. N
8 c  n" r% ?& q6 _. C: T1 N
                while( GetExQueue( writetime, q ) ) {
& p! N: w. B1 h. k5 F                        WriteExProcess( q.addr, q.data );
! |3 W$ D8 r% }& V& S. `                }+ k& p4 V4 |  l% c4 y
0 x! N: {0 c% {  o" U2 H! B
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
$ \7 Q( x: E) ?8 \% q0 m                output = 0;' Y9 l  h% j. s: Z  ^3 t) ?' `" t
                output += internal.Process( 0 )*vol[0];
5 ]8 R( w: S$ B9 S% I" B' J                output += internal.Process( 1 )*vol[1];) V* X' _6 H" \! K% P4 n
                output += internal.Process( 2 )*vol[2];: q" I, q1 I, F% K+ u
                output += internal.Process( 3 )*vol[3];* s( p+ ?2 u. {7 E3 V
                output += internal.Process( 4 )*vol[4];$ ^+ ?2 E5 O6 n! p7 o! _

* ^- n& U4 s4 R4 o6 f% e3 ]$ h                if( exsound_select & 0x01 ) {
' k) R7 I1 J+ U; [5 z3 k! ]                        output += vrc6.Process( 0 )*vol[5];) t4 R" P8 E% Y2 r2 b
                        output += vrc6.Process( 1 )*vol[6];
/ `0 `. ~8 l  p6 h                        output += vrc6.Process( 2 )*vol[7];
' ~( L* ]% y& h5 X                }. `7 L5 n- l) b1 Q9 K3 R' ?. F0 e
                if( exsound_select & 0x02 ) {
. C- z" G, N7 H' ^9 u! D2 K                        output += vrc7.Process( 0 )*vol[8];. k3 i1 W5 d9 a- E$ _
                }9 K0 ]& G3 }% E4 {, a+ w% j0 W
                if( exsound_select & 0x04 ) {
! f* v/ M) \: w# H- D4 V. ]                        output += fds.Process( 0 )*vol[9];
  I9 |+ q! l1 Z                }
1 A1 s; a8 x4 J6 \% u  H* R4 z                if( exsound_select & 0x08 ) {: [+ r/ z" s: h7 W  E
                        output += mmc5.Process( 0 )*vol[10];
  |% ^0 V6 l; |  J1 I                        output += mmc5.Process( 1 )*vol[11];
' T- G4 q& q; Q1 ?9 W. c                        output += mmc5.Process( 2 )*vol[12];# l  i$ s: c" C1 F9 L( i$ ^( f
                }# J* S0 x# P( ?
                if( exsound_select & 0x10 ) {5 e/ G- p+ c) C0 B  v7 M
                        output += n106.Process( 0 )*vol[13];/ w9 L) s3 n* X' [
                        output += n106.Process( 1 )*vol[14];
" O. T. g+ [* n0 U* Z% e                        output += n106.Process( 2 )*vol[15];( [9 V+ q, I9 c; V9 P( k, k8 t
                        output += n106.Process( 3 )*vol[16];1 B$ u6 Z4 Y$ {, Y* `& m" \5 B. r, K8 Y
                        output += n106.Process( 4 )*vol[17];
6 T- C! s: |, s! @) I                        output += n106.Process( 5 )*vol[18];
  x& e( h* W8 c& P; r. w) V% p                        output += n106.Process( 6 )*vol[19];5 A8 a  b0 ?" [, l( L
                        output += n106.Process( 7 )*vol[20];
- i0 j" f8 V& D7 ?" `                }
% B/ m, l2 L9 f& i                if( exsound_select & 0x20 ) {
1 q/ g/ R! y6 Y; @. K3 }- E. f: T1 r                        fme7.Process( 3 );        // Envelope & Noise0 A6 K6 d; R) Z6 K: O
                        output += fme7.Process( 0 )*vol[21];
4 a- U9 C: }7 O, _) _                        output += fme7.Process( 1 )*vol[22];* y. d  o1 ?' t( n2 q' ^4 }+ k
                        output += fme7.Process( 2 )*vol[23];
5 P) G- M: {9 H8 d& p1 l* V                }
' ~8 U" z  a- ~( E5 Y  t
: n) u4 a+ }0 B+ T4 d                output >>= 8;
2 G. T/ P$ _; c- ?$ ^8 o8 ~- N- V
, Z# i: |' ~3 g. _' s                if( nFilterType == 1 ) {
! p: ^6 I6 s( \                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)' J9 }) @& J: U: |1 V4 [4 O, ?
                        output = (lowpass_filter[0]+output)/2;- S8 F8 H4 g6 ^6 I4 D4 Q4 O
                        lowpass_filter[0] = output;# E. V! w' t" g" Z" B3 h
                } else if( nFilterType == 2 ) {9 k4 {; k. Z2 Z# r
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
" Z6 Q+ d7 D8 [" N                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
6 M+ R/ h' \4 ?' _5 ]! Z                        lowpass_filter[1] = lowpass_filter[0];
- _9 ?/ w- m) S) Q7 z  f0 J                        lowpass_filter[0] = output;
% ?: g) o9 l% [. }2 y6 F; a                } else if( nFilterType == 3 ) {
/ f; ?2 S+ F( `' V& X                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
7 O1 D4 N7 ~" p" y6 }" _- @                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;# [5 ]0 z8 f$ K6 A
                        lowpass_filter[2] = lowpass_filter[1];
% j5 O. a' i) r                        lowpass_filter[1] = lowpass_filter[0];
9 Y7 ^, K3 B1 K                        lowpass_filter[0] = output;4 q- x2 t& K* q; S# c6 i& X
                } else if( nFilterType == 4 ) {
% L! v& W! O' r, j9 }& B! L                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
4 y4 a0 [9 j" e8 e                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;  a  Z! u; p% B+ {7 `7 }: c8 F
                        lowpass_filter[1] = lowpass_filter[0];& Q: W' V; k% @4 K+ F
                        lowpass_filter[0] = output;6 k, t* ~5 l& o, N0 [
                }; J+ C' A( B/ ^" Y
: ?/ C* H  I8 D$ D3 B
#if        09 q5 w! r8 {' s
                // DC惉暘偺僇僢僩: }+ q  W. B% v
                {! n; r8 s! o8 D2 y7 H" h% b- G3 ?
                static double ave = 0.0, max=0.0, min=0.0;2 H/ I/ R- R7 T' v. n8 G$ B
                double delta;
* |' i: G" [) @                delta = (max-min)/32768.0;% t) ?6 b' t1 R% T2 O- d
                max -= delta;. Q# m6 c" }. Z6 j' O
                min += delta;0 F% d; q8 g+ _
                if( output > max ) max = output;! j7 c7 h$ @( u0 x: I1 [  `
                if( output < min ) min = output;# Y: Y6 u$ }. y5 R0 W5 X: n! }
                ave -= ave/1024.0;9 j4 q( l7 Y- s+ C7 g) F
                ave += (max+min)/2048.0;: \1 c4 M# j0 a" |; u' F9 H2 N
                output -= (INT)ave;
' C% i! W( w, ^) o" Y                }
9 ?/ ]) E7 s# R- S  l/ {; j( x#endif7 N. ^6 l/ k# a' d9 t. A8 u: N9 c+ H: x% I
#if        1/ G8 O/ R7 J$ M) O, m* S
                // DC惉暘偺僇僢僩(HPF TEST)
. E, {& G. p; Y                {6 y% @( `) y: {9 v$ d
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);5 }9 s4 [( e# e
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
$ ?9 T) }6 i8 h* b8 x8 l                double        cutoff = cutofftemp/(double)Config.sound.nRate;8 n. \* a- E7 w0 F- a
                static        double        tmp = 0.0;6 k8 i; E2 X* i3 r; m$ p: x
                double        in, out;- c9 Y3 u7 f7 x4 y* Z

! u" v2 F! e6 {% ]                in = (double)output;
! _7 z$ Y( u, N% j8 X5 Y4 j. I                out = (in - tmp);9 d1 }% j+ J$ I* Y4 x5 Q; Z
                tmp = tmp + cutoff * out;+ B( P; T# {+ P
' ~- d! {5 g) ], Z0 ]: }* _% ~
                output = (INT)out;
) T* H5 C2 c+ W8 l! L- ]                }' @' ^: V, L& m; a. o
#endif: [7 }( c+ |, c/ Y! F/ i
#if        0
( L4 [' B8 o- g6 V9 @                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
8 Y: J- Z+ {. r                {% a, M* O* j5 F7 ?% G
                INT        diff = abs(output-last_data);9 d2 Y% S; n3 b3 G  i5 J
                if( diff > 0x4000 ) {" I% G1 m7 `+ A' l3 t* b5 l# c$ l
                        output /= 4;& o0 M* a7 P: m& k# U
                } else ' C& c! z+ l* W4 D% \+ N5 I+ R5 H: Q
                if( diff > 0x3000 ) {8 r. x) T( I: m5 v
                        output /= 3;  [+ U" I6 V/ y) D" g. k3 l
                } else
- S# r( x4 i$ y, b) \, D& o                if( diff > 0x2000 ) {6 \9 B, h3 o0 e+ j( T6 N
                        output /= 2;
9 ]! q1 |1 P" }- O. }# c                }
/ K7 _4 T# \7 _5 ^* v9 Y6 P                last_data = output;& w$ r% w' m1 ]0 Q- S
                }, U1 `- D2 C- }' S, L4 Q, k
#endif
) y2 y3 H- g1 R/ q                // Limit& a5 |1 ]) l0 R& _) q3 s$ q/ B
                if( output > 0x7FFF ) {
1 p& u% _8 [+ I5 w6 ?                        output = 0x7FFF;& M/ [% x1 e- {/ e* M1 \3 s$ h
                } else if( output < -0x8000 ) {5 }, f6 n! _; D. h( i; ~
                        output = -0x8000;, v2 F3 f% @" z% }% A' r8 z; w
                }$ {: j6 }9 O! R  {0 x8 s
: z% W; D9 I% A: R/ V
                if( nBits != 8 ) {
8 Z: r2 H) W+ N$ R+ }/ c5 \7 a                        *(SHORT*)lpBuffer = (SHORT)output;
( a1 N9 W6 x  N                        lpBuffer += sizeof(SHORT);
7 e" t$ {5 t4 a                } else {! D. W6 o7 x9 e9 `0 o% H* `) n2 P5 b
                        *lpBuffer++ = (output>>8)^0x80;
8 J& W0 n0 g! G6 q( M, d                }
1 E3 |+ H' J5 k1 Z* E" M/ U9 B2 W1 n0 S8 _9 f
                if( nCcount < 0x0100 )
, U5 L; L6 ]6 i. e- c/ r                        pSoundBuf[nCcount++] = (SHORT)output;
) @9 l2 `; ]) t3 K# F  c1 |, u9 N6 Y! n  o) z! a
//                elapsedtime += cycle_rate;/ a& E3 G' n+ s, n
                elapsed_time += cycle_rate;  d$ v1 u$ M' ^3 a
        }
, I& X& F# i! k) `# p
* t# F# T* Y+ f0 }5 P5 Z#if        1
' h4 U, O* [7 u$ R! P% C( v0 f        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {; g( D, i' c/ \+ T8 X1 j6 K
                elapsed_time = nes->cpu->GetTotalCycles();
' `+ f) `' }$ v3 g        }
, i) w( C/ C" h        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {! S( J" T+ F; }2 k3 D" T
                elapsed_time = nes->cpu->GetTotalCycles();) B4 P0 }& V/ k: D
        }
$ F( m$ X" m) ?. C7 [* ]2 X( L) f3 p#else* F# w# P' d+ A- D1 A" P+ T
        elapsed_time = nes->cpu->GetTotalCycles();/ T# v' N4 @6 x$ [; r) W
#endif
* M3 o8 L: e0 A0 c. [}1 @. s/ ^: |$ b
  I+ |' l2 T" B' d* N, T3 K
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)6 {5 O$ C9 f/ h9 [4 |
INT        APU::GetChannelFrequency( INT no )9 o- G0 r% I9 U6 K9 p
{9 K, c# X. `/ u
        if( !m_bMute[0] )+ d( N' G5 }0 ^$ q
                return        0;/ d7 A. @$ T( |# e) {9 C
7 R7 w* n5 E7 b5 J
        // Internal. R- f2 B- ~7 [& @  V) l! v
        if( no < 5 ) {) K2 Q# s4 b( ^& J
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
8 p1 B9 K' X0 e. ~. @% V# j6 b' A& `        }! P) U: M+ k2 k6 a
        // VRC6! r0 E- [* d- }3 Z8 n! \! G) `
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {  J3 {! [& M' v, \* E' T+ n
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;) Z+ S/ i2 ?* z! J8 c( i: I
        }, L5 l: v& `* }2 G# p: l
        // FDS
0 z0 S$ s: ]8 w. E        if( (exsound_select & 0x04) && no == 0x300 ) {8 \8 h5 v/ u/ o; \
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
  r% A, V8 J: A! f# Y        }
( D2 D$ b, {* G2 y1 U0 J, E        // MMC5+ ^/ y9 w! r! N) h
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {# y9 L- ~; n7 Q; ]  Y2 J' B- p
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;/ @  ]1 w% n% u4 P8 z
        }
/ ~) v: ~6 }& j        // N106
4 f, [. G: E' Z& _        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
/ r  U; {9 K) r, I. `4 c( ?6 L                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;* e; k& {* [! i' r, }
        }
* P$ l) j1 w: q/ f. R' v& _        // FME7
- G7 s1 E8 c+ K5 r- w, ]. B$ q' x        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
$ K- s4 H$ I# O# j, w% O                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;! V' g5 K2 G& A" s+ _+ c2 m
        }& n3 U# f$ I) @
        // VRC7, a+ q+ _* s0 b+ G
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {% [+ A- B  D8 z
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;) F+ C  E* V# O. N/ [0 i
        }
" \0 ^, o0 C' y+ L' o        return        0;
7 @2 n- L( t; K' C* h% M8 u}
; p( r, x: S  J5 ]* ~
4 w4 _+ s9 d7 O// State Save/Load- E* i3 z: n* r
void        APU::SaveState( LPBYTE p )8 q7 S4 ~/ Y& Y6 Q: |0 K/ W( {
{! O2 Y9 Y+ g8 ]# P+ u9 E
#ifdef        _DEBUG
( y8 b: v0 E2 T# K9 N  _! H" sLPBYTE        pold = p;% J$ W' V0 S7 }& Y0 j7 f6 Q; N
#endif
4 a; C$ t2 \! [9 K
. E* W7 w7 Q4 U; G# Z8 I8 v: u        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
6 w& k) t# z) a. O" x/ j& U        QueueFlush();2 J, P1 V( S4 g' }0 ^  J

% A! y% M$ d& v9 f" Z! D  Q        internal.SaveState( p );3 }  k- R' K) Q% E! T; q
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding# j8 X5 x& R$ }. m4 Q; ?
' Y, M+ B' p- V
        // VRC6
6 y8 }- H8 H5 T, z) t8 x( }  p        if( exsound_select & 0x01 ) {
9 N" O& d" @! {) u  R" U; O* D                vrc6.SaveState( p );7 ]4 K8 ^$ f0 o) r! g* P/ O
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding7 I, O3 X; P9 k. k: J
        }
; [1 r$ Q# y0 Z        // VRC7 (not support)* ^0 T5 c: r; u& m$ x0 k6 R: p% ?
        if( exsound_select & 0x02 ) {
8 G2 Y* E2 N& Q, J$ A7 {2 @                vrc7.SaveState( p );8 ~8 M; H" w; k; d6 a, }
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding6 A% o' x' B5 I$ c2 R
        }
( l5 p+ i: q3 G/ V        // FDS" R2 t( z. F2 z  U: h
        if( exsound_select & 0x04 ) {1 C! ?6 m8 x7 J1 }( e: w8 g
                fds.SaveState( p );
' Z: J5 f$ W5 X" j                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
2 b: D3 L( F# R, \! S        }& d5 N2 x% x% E6 s% x. Z
        // MMC5( J4 `2 ?+ a$ \# t7 [; R9 \6 W
        if( exsound_select & 0x08 ) {
3 X& t* d5 {% G0 r" U                mmc5.SaveState( p );! ]) G' A1 f& U) [+ R; R
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding2 M" Z3 `* E) l" I4 \/ H; ~
        }
4 S% V4 Q) q% L% l3 n( w/ b        // N106) e/ `9 j& x: j* `, o7 c
        if( exsound_select & 0x10 ) {4 f7 q- r/ |/ D3 g( Y! g  Z9 a0 N4 C
                n106.SaveState( p );
5 [) L  o, Z* F: X& R5 ^/ O+ o0 H                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
4 p- o% V. N6 I4 E& e; S        }+ P! H3 ~4 ?+ N
        // FME7
- i: C, O4 K6 N/ q" x- s3 M        if( exsound_select & 0x20 ) {
* j" T4 F9 l4 L$ s                fme7.SaveState( p );) K9 G% ~; f" `/ R2 u
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding& p! y0 i* N0 ~0 a: d& j
        }
8 M' r$ }! R9 I: D4 ?) \) J& G
  b1 h$ E2 A- ^6 l: k#ifdef        _DEBUG
" i6 D6 P* G; p1 X5 t# ZDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
) B; ~* K' z' Y" M#endif) A* l/ d9 C3 i) a# s
}, m; A, Q3 t2 n: n
! O) O9 n& a' u7 E* N9 q
void        APU::LoadState( LPBYTE p )" H* n7 e6 S2 e, e
{3 ]+ n7 d5 z  v, B, A0 C3 Z/ u
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
( [' X  C! |" r, H5 J        QueueClear();- `  j  e& |* I( a8 l3 b

* I! ~: N& j4 V+ a        internal.LoadState( p );2 @; `+ N' |+ P& z* ~
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
$ o: s( b1 i2 p0 Y' T# x8 z6 ^. s) w# A* M2 P4 Z2 r
        // VRC66 b: g* ^/ x5 E4 f1 |
        if( exsound_select & 0x01 ) {
& g  d: Q$ e) X( C9 g5 b                vrc6.LoadState( p );
# i0 l3 x2 @/ Q8 z# C/ h                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding* A3 F. R# x0 |5 o% b
        }/ Q' ~3 J8 \5 R- M5 {' s* Z5 D
        // VRC7 (not support)
/ A7 @% p4 m( h- ^5 R2 ]! `: F        if( exsound_select & 0x02 ) {
  p; Y$ t. Y4 \1 J, v5 r                vrc7.LoadState( p );: I! z8 A, T/ c1 N! [& G( ~* V
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
7 i6 A$ c$ o6 M4 w8 f4 J        }
# ?% N! \' |6 _! W  R' N        // FDS
1 i* w) L5 a  O        if( exsound_select & 0x04 ) {
3 t3 N6 Y' X% E9 R                fds.LoadState( p );( S& ]& s, O) T- |6 \
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding7 I4 R8 C2 N: i4 ]
        }
# J3 n3 A9 f* \5 x        // MMC5
6 X, B1 {. ]# x: F. Q        if( exsound_select & 0x08 ) {
! Q; R5 L, Q) e% c8 g; h- P+ w* {                mmc5.LoadState( p );5 r8 N$ E. h) V) P1 Y0 W
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding+ \* [  y  [1 Z& b
        }& w$ c6 V+ B& k3 C- J9 ?1 X: r6 g9 n
        // N106
" X, _9 |0 \* T+ C; j0 l# j        if( exsound_select & 0x10 ) {
, d0 x7 i7 F0 ~                n106.LoadState( p );
( `4 K- T7 V) B2 _9 R8 @                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
) v$ Q: w8 [" f, U; `+ C        }8 o( S' `( r+ R" k; P6 D
        // FME7# y0 q! ?/ P6 X: }8 f
        if( exsound_select & 0x20 ) {
8 e7 v$ Q! U' A) M2 c* i+ e                fme7.LoadState( p );/ x  r6 ]0 g* i2 [
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
5 z1 V! A, u+ }' b' }. U' @! ~        }
7 V6 b# k7 F2 x# [! Z! T- G# ?}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
" g3 O3 s: p: N" K0 D7 l, U2 e9 P可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。* H4 ]. i- C4 [# J
感激不尽~~
- L1 x( B# }) U: F. ~5 H/ V
恩 我對模擬器不是很有研究,
; t- B% W0 D) E$ X雖然要了解源碼內容,可能不是很困難,
+ u2 i0 i( n5 g3 a0 V" E; a不過還是要花時間,個人目前蠻忙碌的。( r# x, V$ ^+ Y4 N) E4 s

0 H0 h0 m1 m9 p給你一個朋友的MSN,你可以跟他討論看看,
, I8 t; D' J4 A4 d他本身是程式設計師,也對FC模擬器很有興趣。
3 q: Y9 E" U9 |! n
: A8 j- _1 i4 @2 w0 g% BMSN我就PM到你的信箱了。
% e. H3 O! h& e
1 K  t; X& k- u希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 6 c$ x( \4 p( |4 Q; B0 z1 l2 i2 x# K
呵…… 谢过团长大人~~

0 K& O4 V( X! ~- A3 n  B
' E$ A1 T" b. ]0 n哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
, C" R. Y1 T$ |  ~  a, B7 T团长的朋友都是神,那团长就是神的boss。
" P/ H2 {- \# n& N$ O+ v
哈 不敢當,我只是個平凡人,+ a; ]( _0 e1 f5 |/ i! D
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
- [. ?  d/ ~" oZYH/ m$ c$ k, N2 }: y7 F+ ^
QQ:414734306" v) n& q3 d' u8 |( P, c4 r
Mail:zyh-01@126.com0 M3 |$ {) }8 [0 U6 Y- C
( J7 c  |& P' t, I
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
2 C" d$ F8 Y' \. u4 x: B再次对团长大人和悠悠哥的无私帮助表示感谢~~

% n6 E0 v' y& T( D1 c不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-11 21:49 , Processed in 1.069336 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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