EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?& {! q9 n& C. _( T; H5 E- H( [0 G
PS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
7 V, z6 f) u* y2 j. X4 \, x楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~% W9 h( h6 ~" S) G
这里有相应的模拟器源码,就当送给大侠了~~
/ i3 ]2 W+ r: \% K; o7 Qhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
+ t, Q% r3 t, i, c# ]能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。9 v( C1 [3 _+ L6 B; A
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~8 c' \5 Z  V* j- b
这里有相应的模拟器源码,就当送给大侠 ...

# {' D3 m& L) [1 z8 [! e' P) b聲音部分(Audoi Process Unit = APU):# E  E5 d9 U5 G8 Y  A
.\NES\APU.cpp! D) ?: V. _$ w( k
.\NES\APU.h' ^5 p& I1 r( a' `: n

' C$ v9 n  B7 c9 _* y) l4 z# c6 e' f9 _1 T& F8 W7 z
影像處理部份(Picture Processing Unit = PPU):1 _% r! w9 V& T% A. H% l
.\NES\PPU.cpp
1 T) b0 n4 U. T  [5 U.\NES\PPU.h% u- f# a% I* [( J

) I8 `1 n5 B+ C( }4 k9 Z如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:- \6 ^* Y4 E9 ]0 c/ \' F
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
  Z" j5 a; s) F- R//////////////////////////////////////////////////////////////////////////, P% x3 {; l1 x/ j. x- o8 k
//                                                                      //7 s2 V$ a! a; S) R& e
//      NES APU core                                                    //
; l: E$ |, V" C3 [//                                                           Norix      //
/ e7 J9 p8 z: k, ?//                                               written     2002/06/27 //
; W4 G6 i* ^1 F) {  C//                                               last modify ----/--/-- //
5 O3 B0 K3 C7 k) l7 \4 \( E//////////////////////////////////////////////////////////////////////////% e; Z+ l" m. m- {6 A5 c  ?# T
#include "DebugOut.h"5 h3 c( [' U# r% x
#include "App.h"
# t9 c! `: O; \2 m1 ~#include "Config.h"
+ H: L+ t* `# C) D3 e- s0 h6 E# B1 B7 K
1 Y) x  e# q8 J# M. n7 u, ]  J# p#include "nes.h"4 y  V1 H( T- |/ v* d2 X
#include "mmu.h"# @- [: [2 L7 c2 g- r) K, E: H
#include "cpu.h"
. d* G/ M0 q3 X#include "ppu.h"
0 g* W. t1 V- G) w#include "rom.h"
$ M: Y) U! o7 z: {7 Z. k#include "apu.h"
: T4 |/ P8 X8 e' w4 k  s4 @; D) W4 u' ^% J; H( [5 i; y% F) E- O! g
// Volume adjust  e& O. p- e; H" k3 V
// Internal sounds1 C: p# ^- ^) u- w3 [
#define        RECTANGLE_VOL        (0x0F0)  w) [- c" C4 ^3 ]
#define        TRIANGLE_VOL        (0x130)
) i4 [/ b0 N7 L#define        NOISE_VOL        (0x0C0)" o5 v8 }9 @, y1 u# X. A
#define        DPCM_VOL        (0x0F0)
* W& ^% d8 r( {1 [/ e! H# V& A// Extra sounds  L3 v3 W3 u  E( b$ j
#define        VRC6_VOL        (0x0F0)' Y$ j5 u7 J) g9 |4 v' L
#define        VRC7_VOL        (0x130)
/ i# h' Q- y+ m; D6 i5 i#define        FDS_VOL                (0x0F0)6 ?9 m2 t9 d/ q
#define        MMC5_VOL        (0x0F0)
0 L# O" R  e; t; O/ s2 q#define        N106_VOL        (0x088)
& z3 M$ d' r8 q#define        FME7_VOL        (0x130)7 Q! [# e0 E: o
  Y1 K# f: ~3 O" o
APU::APU( NES* parent )! v- j( B, w" D
{
3 _" `( |/ V" \1 |' I/ K4 f        exsound_select = 0;$ ~: N3 L# I3 _  U9 e6 n* u

2 y* k- U6 M% Y2 N. b9 |2 n        nes = parent;
4 ~1 v+ `, M, ]6 \& t2 c* [7 b        internal.SetParent( parent );$ S. F/ p7 i0 E: e  i

( Z% Q9 P/ q/ G. j* E        last_data = last_diff = 0;1 i5 M) B" e/ N/ Y
9 S2 ?: S' s5 k
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
5 T- d; X* W. j2 f0 L* i. B
& ?. f$ _; G" v& m4 o3 z        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );+ r* [* w) U0 P8 l) p" i/ \
        ZEROMEMORY( &queue, sizeof(queue) );5 w0 ^! `/ z6 l# B! y6 l
        ZEROMEMORY( &exqueue, sizeof(exqueue) );. X0 K3 t9 q4 y. e* G

+ E& T  k/ P  W5 F/ d- q        for( INT i = 0; i < 16; i++ ) {
+ Y' ~' s% v- A8 U( o                m_bMute = TRUE;
$ ]  y: x" ?$ w% I: l        }, S3 v: S* m0 \$ C' ?4 \+ o/ h
}
! x) q& u0 n! Z+ I: N( P8 t" v5 g/ w5 @* |( U, P4 R  x
APU::~APU()
2 v( ~1 K% B( C: |6 K{
' h7 u7 e3 u9 y  Z) I9 u# V}
# ^: y; A9 k9 A/ i& N# K1 V6 ]% b7 Q; w9 r% ^! e, a$ K0 A
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )- E5 j) [1 f8 n8 `  m4 k- n
{
# \: o# h& i  z6 w5 r        queue.data[queue.wrptr].time = writetime;# _8 K/ D8 n+ u2 E
        queue.data[queue.wrptr].addr = addr;
$ q! j! Y5 B& a6 T        queue.data[queue.wrptr].data = data;; O$ {, B5 U: x% G7 {. k& D
        queue.wrptr++;
8 t/ i/ h& C& r+ e        queue.wrptr&=QUEUE_LENGTH-1;: H2 F- q2 l& H  f! o% `
        if( queue.wrptr == queue.rdptr ) {
% t  E* l2 `3 p* @) L                DEBUGOUT( "queue overflow.\n" );1 W5 f" e9 F& z7 H
        }$ z! f& a& b* t  Y" @4 g) |! _
}% S  k0 a9 g* H  r/ q: j

) G* v! r+ l5 h' @; dBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
+ S2 |$ _: j3 f3 p3 Y: j6 }- S8 R{
. h$ `0 w: \, t) e2 M# }% f0 @; c# p        if( queue.wrptr == queue.rdptr ) {
  C; x- v% H; |                return        FALSE;
9 h9 Y( {% i! B- g% [        }, K1 `1 O9 I4 v6 y2 g+ f5 \5 l% H* F
        if( queue.data[queue.rdptr].time <= writetime ) {
/ G+ ^0 y5 X- q! U5 r9 O8 ^                ret = queue.data[queue.rdptr];
6 Q- w- _  w/ ^6 Q8 s2 ~1 E  T                queue.rdptr++;
4 i4 D: i8 r5 ?3 X  f7 [4 [* Y( m                queue.rdptr&=QUEUE_LENGTH-1;
7 j9 \# A  m* D6 Y6 G' @6 ]5 Z                return        TRUE;+ d$ Z: _! p. K/ o. w9 h
        }! i% P& g( _& A0 G% }8 x
        return        FALSE;
! B9 _5 H1 s( k4 g0 ~" s; m, l8 v}
5 J0 _# |2 _0 o3 P; z
* v3 b$ f" J. ^. j: M' ~) B9 `  svoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
2 U7 O7 w- y; _# l! ~, x{( @& O' S. J# b. ?, H: O8 p
        exqueue.data[exqueue.wrptr].time = writetime;* u% n1 C$ ]* x
        exqueue.data[exqueue.wrptr].addr = addr;
% n) u4 ]4 T1 g2 N. |( K+ I+ [        exqueue.data[exqueue.wrptr].data = data;
3 o6 N8 `4 F* k        exqueue.wrptr++;
1 n9 e, u4 R$ l- r# u        exqueue.wrptr&=QUEUE_LENGTH-1;
3 D- u4 q( r5 h9 `6 M  ]  u        if( exqueue.wrptr == exqueue.rdptr ) {- B8 ^1 o1 J/ I; S
                DEBUGOUT( "exqueue overflow.\n" );0 u. \% @$ c# O
        }
, V  M" `- i- X1 ?0 ~}: N( M) i# u# O3 P% G9 Q, p

1 _8 k/ k9 l: Y- N& d" ~0 ]BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
) s5 V8 f  y3 c4 T$ Q! P& A{
' L  i! ~- ]8 g" @! {3 g        if( exqueue.wrptr == exqueue.rdptr ) {
7 ^: x% |, [3 S2 `; E: l                return        FALSE;
' J; \- x' {0 W0 N5 X$ W2 a) f( U) N: ?        }
; B( O3 ]1 M# v+ l8 L        if( exqueue.data[exqueue.rdptr].time <= writetime ) {, `  ~  N% _* \8 ?" x1 x
                ret = exqueue.data[exqueue.rdptr];
5 E/ g8 O) I+ ^( X- K# {5 [" l                exqueue.rdptr++;5 z& f# g4 ?" T( p- e0 P3 X+ ^* a
                exqueue.rdptr&=QUEUE_LENGTH-1;
" E; U2 w+ K. F9 A0 @0 Y% [! V                return        TRUE;
1 x& I' y9 C) @0 g  G        }
- k. g$ c# B; E' g- r% L1 x! V6 h2 b- w: A        return        FALSE;/ {4 h* k( N! `5 N+ J& V
}
2 ^# T+ _1 f$ T" ^, g8 \5 H9 k; N9 c- ]4 A7 \0 C
void        APU::QueueClear()7 S0 i3 z, E3 ~
{: `0 I% J. n/ m1 n
        ZEROMEMORY( &queue, sizeof(queue) );3 I; L! L, d( n
        ZEROMEMORY( &exqueue, sizeof(exqueue) );: m0 ~4 U& E$ b! _" `( ]5 l
}
8 L+ _# M7 }4 E( m- P8 R( a/ V/ V6 E. [1 C
void        APU::QueueFlush()
- q9 p! g# l: S! v/ X+ u; I& g{
0 i, l( _+ |& ]        while( queue.wrptr != queue.rdptr ) {
4 G8 w+ \6 c* {) x                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
: l( X0 `# s8 t3 ]                queue.rdptr++;8 P, U; j  p* h9 M2 C
                queue.rdptr&=QUEUE_LENGTH-1;8 U5 c9 Q6 V2 l, w7 ]  X
        }3 J; T, M/ ^: I& W  O

4 ]% i+ _* i  R' U& x# O        while( exqueue.wrptr != exqueue.rdptr ) {
( u+ f- d. j: Y& T                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );% q2 j/ J, X: J) q, y, J& p
                exqueue.rdptr++;
! G" f) B# d0 Z& i1 y                exqueue.rdptr&=QUEUE_LENGTH-1;
8 L, e: T/ E- _" [' k        }
1 t, g( |* _: ]4 Y}2 N' T6 g( N  ?3 H
. e; s9 r' q- f) J- K0 ]' f( ~" S
void        APU::SoundSetup()1 X- I$ Y; m3 T, N% o/ E
{
) W+ E( V( L1 Y: g        FLOAT        fClock = nes->nescfg->CpuClock;4 K$ s5 n  E  T' V; e, j
        INT        nRate = (INT)Config.sound.nRate;* k$ v5 y0 |- g- L7 B. m' y. M4 i
        internal.Setup( fClock, nRate );- F5 O2 O, S1 W
        vrc6.Setup( fClock, nRate );8 ~+ D* ^2 D! m! t) Q7 F" k9 G# }
        vrc7.Setup( fClock, nRate );4 Z9 p8 h3 O7 h8 n
        mmc5.Setup( fClock, nRate );
+ W9 {# K7 {7 d5 y/ o        fds.Setup ( fClock, nRate );, B/ n5 y- ?. I6 l' U( g0 m% X
        n106.Setup( fClock, nRate );2 a* X; i* P: z6 M
        fme7.Setup( fClock, nRate );
4 W/ w1 H" [' w  k" [9 J}0 F8 r; G. ?3 y/ G

' d. B4 X2 F- b% X4 A+ s) Gvoid        APU::Reset()
8 E5 `+ t+ N/ y( o9 [{% U; [5 a( S- C0 i4 ^# i; v6 o7 }
        ZEROMEMORY( &queue, sizeof(queue) );
2 T8 R- u2 G9 L# @        ZEROMEMORY( &exqueue, sizeof(exqueue) );
# V+ u/ T+ E$ |+ U) s& k, ?+ |0 a' l( J  ^" T' ?' \1 R7 x6 N3 j2 k
        elapsed_time = 0;
- `$ i4 }1 n& y  I: R5 e6 D
- ]1 n  x. u9 L+ |        FLOAT        fClock = nes->nescfg->CpuClock;% l$ \( _# q  E+ Q- L
        INT        nRate = (INT)Config.sound.nRate;2 l9 ]6 n. ]/ r* t, }
        internal.Reset( fClock, nRate );/ l# H6 _: A& {! _( G4 k# ^
        vrc6.Reset( fClock, nRate );9 g+ e* l& p0 X. y
        vrc7.Reset( fClock, nRate );" l5 m; D8 p( G6 T6 _# n
        mmc5.Reset( fClock, nRate );! v& v2 ^. t! M
        fds.Reset ( fClock, nRate );$ h! F$ Y, x3 A% @/ F6 p) W; r
        n106.Reset( fClock, nRate );
3 d2 a% \/ z) }' G; b        fme7.Reset( fClock, nRate );
& p- ]6 |) M5 ~, Y
4 p8 `# v, W1 [+ X" m( b; {        SoundSetup();
% G% ~' p3 I- b- o! b}
& H5 x9 Z2 @) k& T! v( J1 U8 Q0 s' F* l3 i& e: ?9 C
void        APU::SelectExSound( BYTE data )
7 ^" d5 F6 g3 V3 \2 x, y+ u{3 J) F& x+ u- n2 m" W, n1 Z7 g
        exsound_select = data;
, d4 M- Z- H! [  i5 G( W, [. [7 k}4 P; m$ W5 O$ J3 p1 o$ }* Y
! Z& T8 G. [  e+ p3 Y
BYTE        APU::Read( WORD addr ): W% b* p+ A6 H- _
{9 ^/ X2 T6 D* z, d
        return        internal.SyncRead( addr );
. \) [/ X9 m. Z. @) _4 {}3 p$ x% n; j8 \

8 C) E( d5 y1 q9 K4 Wvoid        APU::Write( WORD addr, BYTE data )3 y/ d4 X/ l& E4 @) m) f
{
' y/ I; ~! I! g+ a2 Z1 ?% q" r        // $4018偼VirtuaNES屌桳億乕僩& \5 ]; U; ^2 l2 O8 x9 a$ t
        if( addr >= 0x4000 && addr <= 0x401F ) {
/ [7 W4 u- C* h' F                internal.SyncWrite( addr, data );9 A( D3 R, z  p, s6 m: s5 v
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );( _4 O! Y6 A7 W* l
        }3 L' E/ ~+ r4 |% H' ?8 M
}" K! E+ l; \  X! i
. H9 i3 ^' O+ V0 I$ V) m+ _9 w& Q
BYTE        APU::ExRead( WORD addr )
* b* b4 R- f0 G4 C5 g2 ?{1 v* @6 V2 K) O7 \# O, Y" ~) o
BYTE        data = 0;' p9 L. i9 w% U, x% W
, L$ {$ \( f( a$ Q
        if( exsound_select & 0x10 ) {8 l" `7 a% c4 }1 J
                if( addr == 0x4800 ) {8 V) S* R  B0 g- ], T# u
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
9 E1 ]/ i. Y( ~                }
$ k# g& b0 r( p& Z3 A        }* W+ ~3 K9 W' I( E) }. S2 s4 s' E
        if( exsound_select & 0x04 ) {4 \" V1 Z- p2 p2 b
                if( addr >= 0x4040 && addr < 0x4100 ) {5 |1 X/ m( U+ F+ |: h/ }
                        data = fds.SyncRead( addr );
- m5 W4 ], k/ Z9 d& h                }, `/ N: F+ O5 T+ s% M
        }
! d! e6 W1 r* e" U) F3 V% b( E( E  k        if( exsound_select & 0x08 ) {
: i4 T0 C: B( Y  v, h1 H                if( addr >= 0x5000 && addr <= 0x5015 ) {
# U' |, }6 U4 N  k4 i# w( _                        data = mmc5.SyncRead( addr );# r% L, p+ L, o, E
                }
) U  I0 Y; `( d0 u  Z  E        }
$ y( k. Q6 ^, z* _, w7 D- y$ m% G, C$ t* @
        return        data;
! P# U% s9 Y& I$ Q% x( A}9 X/ i8 q: Q% p* Q8 E9 N3 }# s/ g, q' K
. a2 X) Q4 B1 ?1 w0 ~4 B
void        APU::ExWrite( WORD addr, BYTE data )1 d# ~4 @. o. ?8 v  d3 B. b
{
5 W% }1 f" _0 d1 m) |7 N        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
1 y# m# R5 e# Z" u1 [: Z" {; h# A9 R# h* K
        if( exsound_select & 0x04 ) {
8 d: l, ~+ L4 r: @4 z                if( addr >= 0x4040 && addr < 0x4100 ) {
$ M$ N' L! T5 C                        fds.SyncWrite( addr, data );0 ?( ~+ j; @- u2 H3 G
                }: R' N. S7 B' u+ C% \% V
        }
2 l4 ?, e, n6 Z. l
* z1 e9 B# _! Q/ J" q: c( l4 c% l- r( @0 M        if( exsound_select & 0x08 ) {
! m( e  m. j# s2 l1 _# i1 X                if( addr >= 0x5000 && addr <= 0x5015 ) {* J9 V& Y7 T3 O" i4 `
                        mmc5.SyncWrite( addr, data );. s) c3 G* I5 i' R
                }
) u& c5 w/ k% K) D: I, o        }  R9 b- r8 a4 ~
}! D/ g/ N% Q* ^  y
4 a0 r6 `+ K2 L. }
void        APU::Sync()
/ K2 b& N: r7 `  l- W: @1 L9 ~* e0 i, ^/ [6 v{7 d* E  ?7 I/ ]) J0 d
}
0 y# P8 l& r! D: _
6 y) M9 ]% b  `4 z5 V3 Q5 Fvoid        APU::SyncDPCM( INT cycles ). C' U+ y9 c- X5 t
{& N3 K7 R9 B! n# I; H
        internal.Sync( cycles );
" r' f2 O$ [# M* s' v; L. w& Z" z7 v1 b$ \/ Y
        if( exsound_select & 0x04 ) {
& |5 t/ r4 z) P9 |                fds.Sync( cycles );
; @5 c, s0 Q9 g4 \        }. C1 h% @; l) \% j1 x
        if( exsound_select & 0x08 ) {
8 m, n3 T9 j4 y: {9 p                mmc5.Sync( cycles );( l- N+ k& j  p# c- ~1 {1 g1 a
        }
0 X9 W- E: O7 y( ]! X9 V1 \}& V6 G) s4 g' e- h

! U0 `$ w! _) h% \void        APU::WriteProcess( WORD addr, BYTE data )& O. e8 f/ j$ O/ g& x7 o
{
* ~. j- z( h4 H  }) X! C        // $4018偼VirtuaNES屌桳億乕僩
" s# P* I9 ^' q% y; ^/ M9 L        if( addr >= 0x4000 && addr <= 0x401F ) {
9 @' h0 S0 T" P  b                internal.Write( addr, data );. _  ?5 k) z4 e1 \, K
        }
! H0 h6 _2 i0 V1 k}: w" U/ g* f& j1 P" x2 V% J
% |; L; a% B, d1 E4 ]
void        APU::WriteExProcess( WORD addr, BYTE data )
' z: I' |5 M: X$ G1 Q{1 q, C4 ^* q- ^* D8 M
        if( exsound_select & 0x01 ) {. u$ i& I0 ]" \& V. w
                vrc6.Write( addr, data );
5 h9 u3 b0 z& u0 `4 n  N  Q+ s' r        }
. u; p; l2 |1 ?* ?+ j        if( exsound_select & 0x02 ) {
- a5 a3 Y7 W  A2 }( F                vrc7.Write( addr, data );
/ ~/ l, Z" s! j/ x& j        }
4 T5 N( B; F+ D! a9 x5 r  i        if( exsound_select & 0x04 ) {
  E' I9 w5 J4 A" c1 x* \                fds.Write( addr, data );+ @( S: h0 {" t3 K( R
        }
2 j" A, z2 C. m, N; n        if( exsound_select & 0x08 ) {
) W3 F* D4 w; X. F- K9 m4 {( V                mmc5.Write( addr, data );
9 W8 {: _4 W, k( @, p5 f        }3 {4 t( |- P, b# l: W% _
        if( exsound_select & 0x10 ) {# u' R, V' b; g9 A/ J4 [2 a
                if( addr == 0x0000 ) {
9 [: N8 ?- C5 {8 P                        BYTE        dummy = n106.Read( addr );# p) Q& b5 |( z1 i; F0 b# m: v
                } else {
% H4 c4 B* U' }3 Q4 C0 e                        n106.Write( addr, data );' g  G4 Y& s  P% o' f
                }" X. t6 |, n6 l' Q1 s: d
        }
/ E0 e3 g6 ?2 @; C- A8 z& h$ A& P* o        if( exsound_select & 0x20 ) {
3 L4 M6 W! K4 d& A- S: {: D4 o( C8 T                fme7.Write( addr, data );
/ ^  p; F" d. M9 Y) }        }$ B/ Y$ T6 i. q* |3 R
}1 I5 J2 M; B! L
! v) T: p6 m" {# C. h# r3 w
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
2 p7 N. S: y7 \; u+ U0 ^{. C6 u+ B8 x, H1 B6 C
INT        nBits = Config.sound.nBits;$ B% Z, i- E3 I. R
DWORD        dwLength = dwSize / (nBits/8);
1 H( x8 p: p+ C& n; u7 W; R; EINT        output;5 f% Z5 c5 X1 e6 H% V+ T. H* k$ p
QUEUEDATA q;
5 I' z: f' v; Z) [, K& v4 n- `" Q: pDWORD        writetime;' Z# j" N6 J( f  j/ c  L

. {+ i# [' G4 x6 z# p; WLPSHORT        pSoundBuf = m_SoundBuffer;
1 K8 W5 }) K0 L' Y8 EINT        nCcount = 0;2 z  k; R. z, z; @* Z

) W9 f1 r4 ]8 _$ c) |4 Z5 t4 |INT        nFilterType = Config.sound.nFilterType;
5 C9 u6 G$ Z4 D$ t1 R) |
; s, A/ c3 n% U$ |+ ~        if( !Config.sound.bEnable ) {
. b2 E# B2 O7 z! G  q* I: k* Q                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );+ M  t* R. K) b# ~, @7 [
                return;9 N; ~* x/ [4 \7 d: ?
        }/ b0 ~. ~6 a" L9 d
; i9 g0 c- A  }5 f. W9 J; b$ N
        // Volume setup" A$ y0 n# |& J" {: N+ |# W# h* |
        //  0:Master
3 k* G. m$ s% l8 i3 @3 E7 N: p        //  1:Rectangle 1
6 @- N: ]7 t; ^7 F" T2 z4 o# ?        //  2:Rectangle 2
! @: K" M& E) H/ p9 d        //  3:Triangle
: t8 ]% J% Q5 O5 `        //  4:Noise$ i, A6 J  i6 ^
        //  5:DPCM+ Y# h+ j. A; L4 X' \* o
        //  6:VRC6
. b5 o* y' A( m: ~& p        //  7:VRC7
$ s* w" i$ B: M4 z, S  _        //  8:FDS5 }7 c- n  ?- K2 \9 U
        //  9:MMC5: C8 ~) o, m. ~, I! ]! S3 Z+ q
        // 10:N106
( w4 u( O; a& g7 i) z        // 11:FME7- P8 B3 l" l' D1 w
        INT        vol[24];) c" _  {" {6 ?" V8 X+ o8 T
        BOOL*        bMute = m_bMute;) {& d9 k6 x2 h) M, M0 t" s" O
        SHORT*        nVolume = Config.sound.nVolume;, f' B1 s7 W2 m5 F  F

2 R: C5 g4 T3 {  x7 a7 J        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
" N2 p- y5 g) f# ~% ~  c& i7 @4 L$ ~! D& e
        // Internal
7 u/ t) _: G! g0 U% K7 J: s        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
% F0 P) d0 \( X        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;3 x6 C1 x. u: D, D- Y  G. D
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
0 S8 m) j$ n4 I; U, Z- M        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
& }( {) p3 }: Z8 Q! L1 m" w        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;8 r+ S4 t9 w7 S% b
9 u* c5 ~$ r: p/ G  C5 {9 Q
        // VRC6
+ g% h3 k7 w3 u# w2 \5 u        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;. U& v* s4 f+ {+ n
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;* _# O: h! v0 F) H
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;+ N: w0 l( D8 [5 e6 A
" b- K" X: K& B& }
        // VRC7- ~6 E( A, ?* b
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
0 d1 W: Z2 _( q4 k
( f$ }' y( k, P% w) m8 z% ?        // FDS
5 X$ z% f3 R; K/ p4 C0 V        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
% T; x6 _5 X$ {5 @+ ?; d: O9 C: N" B4 M; i- d; s5 Z6 y: U
        // MMC5
+ Y( v( ?* ]4 S" H        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
( ~; w& i! _* Q        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;' l; V* H7 b5 @2 H6 s* A
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
- a; O8 R! C" ~* F( k5 Q1 h
* X7 k/ M! u% ?& T% x        // N106* j8 e. @2 @) ^' J2 r# d
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
; b0 ?& [% R9 N        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- r/ E  I9 z' I0 c
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" Q8 M. `( t7 u0 K6 y        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 K+ K0 F% Q3 V8 b* u
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;" f( r2 E* J1 f/ C5 F
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, x$ C" `+ |$ m& w1 O/ F        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. S6 x) {5 F1 v% o6 C        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;1 V$ W+ ~/ l3 f3 r+ z
# H* [$ I: l, N* o6 a: q. `; j) K
        // FME75 ~8 V0 d/ ]+ v4 N' o
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
+ y: @6 i% Y; {/ T0 J: N3 @0 {# F        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
  Z% h" h" I: t4 `) B        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;' t; I- ]/ P0 a# w' H/ c' e- a
& d/ ?: x1 N, t; [3 f4 w8 ]
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;. F: U0 {; S2 {. ~9 }. ?+ N% O
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;0 C9 s- {6 g( k$ }

) E! V+ r- I& W4 V, T5 E* @        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟% M2 k3 _7 ]) Q% L
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {2 ?+ S9 \; N$ K$ w3 c; \) x% I
                QueueFlush();
" q- R. j. r5 B! S6 X6 J3 c" b5 Z        }
) ?2 r( j. v/ J0 Y1 K- C/ k
4 _/ T- h  ?* |, X3 T        while( dwLength-- ) {
# ~8 f* e& s: I4 F8 }& G+ N: R0 q                writetime = (DWORD)elapsed_time;
$ {# |5 \* A, G" z1 k' U
1 o' i" R3 a9 a% ]- N1 D5 R2 i9 T9 I                while( GetQueue( writetime, q ) ) {
: P/ P5 j! w. R2 u! F0 Q                        WriteProcess( q.addr, q.data );
% ]0 b7 H% j2 D6 X& y# E' d                }/ {' I' N- y, n
% Q- t+ a' p1 {5 j, O4 d' E( q
                while( GetExQueue( writetime, q ) ) {+ D- n+ g' ^1 B% c$ [4 Y0 {
                        WriteExProcess( q.addr, q.data );2 {3 H9 {+ g* N! s, G) ?
                }
" h0 g  l! G# l* v# h3 c5 Z) j
5 k- R  ]& Y# ]9 n; O                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7! z" O. K2 ~- t0 @
                output = 0;
* L8 a* d$ W2 Y                output += internal.Process( 0 )*vol[0];( X7 [1 b% h. @) T
                output += internal.Process( 1 )*vol[1];
( j' m1 z. C9 j/ N# o* m                output += internal.Process( 2 )*vol[2];$ ^2 r1 g9 F( o1 ^3 @
                output += internal.Process( 3 )*vol[3];' S3 G2 j1 V9 v5 m6 P6 q
                output += internal.Process( 4 )*vol[4];
& Q7 M4 n9 K1 R7 a5 A  \. O% M/ [
. X9 p6 j: g  X* ~1 B% T                if( exsound_select & 0x01 ) {
* C' S+ O* [$ n                        output += vrc6.Process( 0 )*vol[5];
* q, y( \' g$ T' C, K+ L7 q3 Y                        output += vrc6.Process( 1 )*vol[6];! L& ~, m2 C0 g# a; p7 `+ e
                        output += vrc6.Process( 2 )*vol[7];
( i3 Y' K! \  e1 t6 v                }
  ~/ R8 |9 ?7 Q4 m                if( exsound_select & 0x02 ) {! d: s4 s( `0 i, z
                        output += vrc7.Process( 0 )*vol[8];
% s# Y# }$ [" M  A0 y7 K                }
/ R2 {* Y& Z$ {  ]  G1 g/ q                if( exsound_select & 0x04 ) {5 F- \5 K% }8 f4 T; g7 f) @
                        output += fds.Process( 0 )*vol[9];
$ d; [: v" j# B                }
7 S" u) ~# g" U0 H( A' a' D                if( exsound_select & 0x08 ) {2 z* ?2 y; `) Y4 }+ z" ^; x3 n
                        output += mmc5.Process( 0 )*vol[10];
3 l; Z$ J6 |+ P  V" D) U# ?* ~1 T                        output += mmc5.Process( 1 )*vol[11];6 k) c  Q! J3 f6 p1 E4 J
                        output += mmc5.Process( 2 )*vol[12];
4 S( q' ]; g5 |4 M                }. O  H" ]; y5 M9 b' o3 j
                if( exsound_select & 0x10 ) {/ U' F, t. x5 x: W' D
                        output += n106.Process( 0 )*vol[13];
: ~4 x% k/ l: i                        output += n106.Process( 1 )*vol[14];
9 [7 t, P$ O7 I                        output += n106.Process( 2 )*vol[15];
( l. e" t! n- t- l$ }9 q. ?                        output += n106.Process( 3 )*vol[16];
/ p1 M' q" L' z$ ]7 g6 r# ?1 A                        output += n106.Process( 4 )*vol[17];
- v. A" i4 B( y& Y                        output += n106.Process( 5 )*vol[18];, X! D$ F& r1 e: ~* l, {! s
                        output += n106.Process( 6 )*vol[19];
# |0 J" D9 m) ~2 [9 w6 i                        output += n106.Process( 7 )*vol[20];
% o) t" z* j! H4 z7 W                }
+ z% t- c; a! @5 m! _! P, w                if( exsound_select & 0x20 ) {; `. f( A0 C7 `8 U0 F( @0 ?
                        fme7.Process( 3 );        // Envelope & Noise& W/ B# f) N) Q& a" S
                        output += fme7.Process( 0 )*vol[21];
0 v* f: q3 w# R- ?% l! U                        output += fme7.Process( 1 )*vol[22];1 |  V7 @$ V7 \/ U% Z- l* _
                        output += fme7.Process( 2 )*vol[23];
+ N! e7 B7 B9 n, q% L- j2 |                }
' C: y# o0 `  ]6 H1 p2 }; |5 [2 W$ D. V% `. z: @9 S! |- H/ r
                output >>= 8;: O2 D2 d/ h# w0 S' S" O- m# `) x

; i/ V# w+ V* a/ o/ H                if( nFilterType == 1 ) {2 \9 U" R6 ?: j3 I% q) e
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple). N7 E6 c2 f, t% Y
                        output = (lowpass_filter[0]+output)/2;
# R1 L& |4 l/ q/ I. l( Z. t                        lowpass_filter[0] = output;
" a  Z9 p  H; K( ^4 y" u                } else if( nFilterType == 2 ) {2 I& ?  K$ X  B; i1 G
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)# a% ]+ ~# P$ m$ i" ]* V6 c
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;( V' g+ P, q9 q) t4 o% ^: {
                        lowpass_filter[1] = lowpass_filter[0];
3 n2 a' y0 A% M                        lowpass_filter[0] = output;
8 Q, t7 n4 `" j# k                } else if( nFilterType == 3 ) {
3 ?# A. x- ^- {% l8 D                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)8 {4 E  O+ T: v& ^" X; H# K5 B6 W  U
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;+ X4 z! u: \# R0 [& h
                        lowpass_filter[2] = lowpass_filter[1];
* C' `0 G. @* v  |9 ?* d" i* r                        lowpass_filter[1] = lowpass_filter[0];% D/ z. y" s1 _6 l. }) w9 Q2 a) k8 t7 P
                        lowpass_filter[0] = output;
: p+ d5 I! W7 }. ~0 e5 \4 y                } else if( nFilterType == 4 ) {
4 {6 r2 t/ n5 z) b, c& G                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
: H! T, r* Q$ N1 y* j                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;8 p+ |, `' s" Y3 R
                        lowpass_filter[1] = lowpass_filter[0];8 e% V  q7 P8 W7 B# s% X
                        lowpass_filter[0] = output;0 r' n8 ?# Q* p: m
                }# z! G* D* K# X" s

0 Z# @! Q/ C1 q, ]: L/ n#if        03 x6 @5 x% Y; |9 h
                // DC惉暘偺僇僢僩" ?" Z- C6 ^$ f. }% [& p/ P
                {
0 _) h1 @, H! p8 j1 M                static double ave = 0.0, max=0.0, min=0.0;
3 {0 \/ k) E6 Q  _# G+ G1 F! q; e- s                double delta;( {! U! F$ K, x; G
                delta = (max-min)/32768.0;
# G8 w6 Z7 h4 X; f2 l0 r( O7 Y                max -= delta;- Q  [0 J2 w/ |( p, d; m" N
                min += delta;
! h3 a4 Y  h/ W$ O( |$ y6 ?3 v                if( output > max ) max = output;
4 v9 m* u6 f/ s2 ]* H                if( output < min ) min = output;; ~6 j2 |% ~( L: @  i/ F
                ave -= ave/1024.0;
, x! w3 X: Q3 k" j9 x( W9 q                ave += (max+min)/2048.0;
) o& r  G$ H  K0 [( }                output -= (INT)ave;
, c2 o! k9 r3 w: u                }
) |4 Z2 K$ Y4 _3 j) L# o#endif& M: ~6 W8 N; H: O- t7 T3 J
#if        1
# m4 \0 h0 h" Y1 F, }                // DC惉暘偺僇僢僩(HPF TEST)
5 }5 X" z* C) P& K( j8 K                {
% s9 q" |7 W9 |//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);# R) p! m) _2 i+ k/ t
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
) u# [* H5 G! O0 G% J                double        cutoff = cutofftemp/(double)Config.sound.nRate;
: r8 V7 N1 F* t! o. j3 ]/ K                static        double        tmp = 0.0;" Q5 E; V2 r2 p9 r. a
                double        in, out;1 U- x& @. m4 p6 L1 ~( M

8 ]- _9 v: o) q; G$ r% Y                in = (double)output;
( n+ E1 c2 @2 H$ g9 P3 P                out = (in - tmp);
# Q  E0 v) q5 c9 D* }                tmp = tmp + cutoff * out;3 ?. W* M" J: m& x% v

' }: s* f) u9 _2 H3 C$ U                output = (INT)out;
# k2 r" s! n( z1 I0 L                }
1 Q! R* B, \- H& _: I/ i' S. a% d#endif
& p1 E8 e2 A, f% h6 i#if        03 \  R( Q. A; S& H9 Q6 h
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
: K% e7 h' b8 k                {
) O9 R: H# Y3 @9 M4 A5 K2 l                INT        diff = abs(output-last_data);8 a. s/ B* [/ {0 b
                if( diff > 0x4000 ) {3 `3 P2 k$ U: U" p2 k
                        output /= 4;
6 \. W: `# J9 g+ R' ^; [5 V3 V                } else
# J/ M* o6 F; i8 y$ K3 ~$ B                if( diff > 0x3000 ) {; ~0 d2 t/ I, t( u
                        output /= 3;
- Z8 R4 y, a* p                } else/ a" m5 \" R7 Z* P7 J
                if( diff > 0x2000 ) {
; `0 `) n, T2 j. D* a: \                        output /= 2;3 B2 c. P% f$ \" a( J/ w$ S
                }
. V3 H* _' {/ Z7 Q* F                last_data = output;0 _% p' H2 a8 ]% V0 N
                }
" h0 @8 e9 P. I# ~( {1 I, U9 p#endif
: X9 g; X% e' L, l: Y                // Limit1 j- d1 X8 N: y- X: ]
                if( output > 0x7FFF ) {% [; }5 o  R3 W0 ?! R0 Y5 z* S
                        output = 0x7FFF;" z, |0 X. v1 i8 e  a
                } else if( output < -0x8000 ) {
* R6 Q% q) C1 P                        output = -0x8000;
$ u, O; }/ _' V, N) E) ~                }& I- k0 n. a6 |

9 G* }; C" Q1 [! R) O) p: L. _                if( nBits != 8 ) {
3 \. {/ e0 o' a5 X3 N  I                        *(SHORT*)lpBuffer = (SHORT)output;
: m; C; P  ]. _4 c/ }& V( h9 c2 R                        lpBuffer += sizeof(SHORT);
, p; t, y( N0 o6 a/ U9 i' `9 G                } else {% Z8 a' m2 T, `' x9 }
                        *lpBuffer++ = (output>>8)^0x80;. D3 d# q/ t/ R4 t, V
                }
8 a# ^- O' u( ~, c+ ~6 ^7 _" G* L: L& e) q
                if( nCcount < 0x0100 )
' x) C+ j9 R7 R5 S6 ~                        pSoundBuf[nCcount++] = (SHORT)output;8 B+ r9 F0 F5 C) p4 e' Q; T4 W( S
; R! k. g! o- }- |# q: `5 Y+ ^2 R
//                elapsedtime += cycle_rate;
3 Z0 i" ]2 |9 T. Z                elapsed_time += cycle_rate;
/ J2 _/ s: t5 E; A& \5 m4 c        }& l, u, D+ Y0 a3 w- P
0 U! O" P( t; i( ], p' L
#if        1- Y* _2 t1 H% b; }
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
; z5 T; W: }9 W  R  a/ M                elapsed_time = nes->cpu->GetTotalCycles();
2 Y* Q/ e2 ]: o; j! Z        }1 I4 d( E, X4 h  t- A( I3 m# W, f
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {* G; O4 {: B% ]7 m. @
                elapsed_time = nes->cpu->GetTotalCycles();
/ G& x/ ~2 J2 B6 d& D        }
/ |, N9 b& J0 {# N5 y3 M' l9 W#else
' L: ~* g4 c0 Q4 O7 j  [        elapsed_time = nes->cpu->GetTotalCycles();
; w4 a/ X* I6 g- B7 m% I/ e#endif
% x3 ~3 g5 G7 [5 x$ e# D$ K}  B& V3 h& `$ ~! X) {/ {  c

7 Z" ^3 [* }  a" J  O// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
& w% G( H0 r- T- J$ }INT        APU::GetChannelFrequency( INT no )( g2 M  X9 E5 y0 M+ m
{
2 B, C. f; p7 p$ g7 i$ D" i        if( !m_bMute[0] )& P" M8 W5 m$ i$ y9 U
                return        0;
" \0 U$ {* q1 N; h# K# y1 J( G2 L1 S: B# g5 a6 @& S' v8 {
        // Internal) u: U1 b) ]4 G' M
        if( no < 5 ) {
! L$ z! q6 t, V  Z; O                return        m_bMute[no+1]?internal.GetFreq( no ):0;2 D, B; O, q5 t; s
        }7 h- T0 d# ?% t0 N, {+ e* R5 G
        // VRC6
& P2 \9 J, L1 i) k: J# L% J        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {- C; u# P% c& ]) f3 d: J
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;( {+ A: {0 v: |; i2 Q( ?7 h" K
        }2 w4 g. X0 v+ O: s& K  i
        // FDS; f4 x9 B! |8 W5 ?' ~! w( q
        if( (exsound_select & 0x04) && no == 0x300 ) {
1 f1 F3 p# f+ b2 r                return        m_bMute[6]?fds.GetFreq( 0 ):0;
  a7 \% `+ c% K' }4 N# L        }$ l. ^6 j7 |8 O- O+ B
        // MMC5" D. a+ B- m4 K4 v
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
5 v! `1 i; v, n5 b( y                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
1 U  j( ~/ O# }. D) w( J        }
* W  @# f. v  _        // N106
8 i. E: h% K: \( j6 j9 {& `        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
* n7 p) Y3 a5 B7 @; p) q+ w                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;* n  m, R) V6 n1 F
        }& U" r+ p2 M) ^5 ~
        // FME7
1 V! v" D. _2 _        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
; ?" N* }. y2 u' I: O, Y3 ?/ @, c                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
8 A* `) ?. F/ S8 Z' C        }4 B5 e2 ~7 l9 L# s, n
        // VRC7, B7 x! }6 e' a! f2 k- U
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {; X  l7 T' L! P% E- Y9 V
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;* R) g# b& Z7 i' c0 c* Q8 ~0 y+ {
        }  W- a( o- `: n+ s
        return        0;; n8 B: D5 y6 t3 h* S
}. L' r& y& w' a& _/ o
7 x6 `- _* L& ^3 A( f
// State Save/Load
3 B5 t9 G9 v5 l6 r" S6 v4 Gvoid        APU::SaveState( LPBYTE p )
4 R4 l# w. J- A" b  ?{- `# T* i+ J. o+ `- _! B1 Y
#ifdef        _DEBUG* A, j0 j& m5 I- O- D2 T
LPBYTE        pold = p;
+ U# K% a8 }- |, y) M* Y$ H#endif
  Z9 L0 R* L  k* P4 d# m1 j- }2 c- C, c3 z# \- J# s# v: u% S
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞: m7 t5 {# G$ D; p% {, t
        QueueFlush();
3 I8 J! |: k5 y, s5 ?
: l: e, [5 v& |+ d        internal.SaveState( p );
) d- W  H% a4 v+ V% z/ l2 |* f: ^        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding: Z" ?) L( T/ T, g4 o1 U

+ ~( T" y; g  N" @, ?        // VRC6
. ^( N# q8 Y2 y        if( exsound_select & 0x01 ) {8 F7 i6 d7 a" O1 Q; C
                vrc6.SaveState( p );$ U# c  a# j) M2 e) ]
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding0 e/ ?( Q2 Y1 p9 b& J
        }
& t; ?1 S$ [( J  D) F        // VRC7 (not support)
/ m4 Z% T8 W% O4 t        if( exsound_select & 0x02 ) {
/ W' q& v) D6 h4 W' q( [, N                vrc7.SaveState( p );
2 A: H+ h5 {1 X9 x2 `/ R: o' z3 G0 B                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
6 d) d/ m' g* @* G        }
! _6 G, I% V8 ]$ F- R# [        // FDS
+ e" s; B6 q& d0 m) l        if( exsound_select & 0x04 ) {
! G. F! l% ]3 t. X6 b0 {                fds.SaveState( p );. q" d" {5 t: o
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding1 q5 P% r! [. `2 \$ t' b
        }8 G0 F  T+ j4 [1 I! G
        // MMC5$ [( j, @/ e# R+ C) }  |. k# h" j/ u
        if( exsound_select & 0x08 ) {, t% K7 N& `; o% Y
                mmc5.SaveState( p );0 A- O' w& U/ a6 B) d$ X! i
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
! Y& Z2 f" ]$ X& Y# s        }, i" l4 D2 R& s+ {3 K
        // N106
9 T& ~( R, ]7 b4 |        if( exsound_select & 0x10 ) {
3 Q" T1 B; K, z1 k                n106.SaveState( p );: i1 t' L6 U) F! K  }3 D. U) i
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding6 c# Y+ H0 Y+ N6 R
        }- [% n+ h* B: y& X
        // FME76 s/ W7 d& L- {" z
        if( exsound_select & 0x20 ) {* D  V1 z: m6 ^% a
                fme7.SaveState( p );" g5 _: h0 a8 H
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding% e% h  }' i9 m3 e5 T
        }
' x& h: l, J) x  e/ u: }8 q! s( t7 H
#ifdef        _DEBUG
! Y! `- Q# V. u1 E/ k3 Z- [DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );$ h7 Z: {4 y3 l: U$ P, v
#endif% E  n" \- M! G8 M, \5 A
}
- _" u0 G5 N* L6 H
/ |8 U0 d) f6 @* qvoid        APU::LoadState( LPBYTE p )! |6 h' O9 M0 Z# w
{
) m) U( s# b9 i2 r- x* _; ^/ P; S/ |        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
3 K+ e& ^" Z. A6 }        QueueClear();
8 R7 ^, \% v/ e( ~  L# p
- S/ V" b; u5 S3 l* h        internal.LoadState( p );
7 g! g: v; _" }& ^/ e1 `9 b/ ^: S        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
  s* x/ ^! y& y8 `5 w& s& t3 S
$ q& N8 w! f' J& q+ Z2 r' @) D        // VRC6; u7 P/ u+ e  K4 `  M
        if( exsound_select & 0x01 ) {9 V' M/ V1 n$ Y- i9 i) g9 ~- s2 L
                vrc6.LoadState( p );& V+ j# x+ v; M4 i
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
0 U3 }! h1 W5 I+ q+ j8 i% E        }
) }( n# M' q, [5 k        // VRC7 (not support)
3 c3 f$ t- ~3 E! R4 R        if( exsound_select & 0x02 ) {' o4 h' J5 l; Q2 e  t6 e. v6 n
                vrc7.LoadState( p );
+ ]" S7 U& `; z7 z& F# d9 _- }                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding! |# P8 z6 p6 ?: m7 V8 Y
        }
# E" C9 S- B5 x2 K        // FDS
1 \# T5 V. n' \. i        if( exsound_select & 0x04 ) {5 r7 O, y/ c+ V4 Z$ F
                fds.LoadState( p );
, [7 ^7 q/ ]# l3 S7 `5 o                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding, `. |2 c6 p& X# P
        }
  U- P7 f# P4 `9 L4 L        // MMC5' l% q& P2 T- W+ q+ w
        if( exsound_select & 0x08 ) {
& R2 v$ ~: E; }8 U# \                mmc5.LoadState( p );: C! S8 P- a4 c6 r2 Q
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
5 W7 h3 K/ I# I/ O( I" M! p4 K        }- c- _- j3 x0 ]5 }5 `* q1 M
        // N106& ?1 m, \, S8 ^0 g9 P3 [! j% r
        if( exsound_select & 0x10 ) {
- Q) \, m; `8 K8 f$ y# p                n106.LoadState( p );; C2 W" L/ j: H; Y% Y
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
& K2 p$ l* c0 y( e8 n1 d; x: j4 T        }( [$ P) p9 M/ G' w7 b
        // FME7+ J& G2 P9 \: S" Z* U% ?  G
        if( exsound_select & 0x20 ) {( p: [4 D# d( `2 U1 b
                fme7.LoadState( p );
% d, K/ D8 I( H, @                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
1 a7 d% C( S" X2 D0 J& F        }
; M. C! q4 z! R5 r+ O  k}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 # M: j0 p# i6 B. @1 ]$ I: h0 g
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。0 q& e6 N2 e9 d
感激不尽~~
2 I! J/ j: V: q$ j; J, [3 E& ~$ w
恩 我對模擬器不是很有研究,
9 X* N# c" h3 e  L- k" x* {5 H雖然要了解源碼內容,可能不是很困難,
0 I+ J% n2 i' P0 K. h# Y不過還是要花時間,個人目前蠻忙碌的。
: Y: q% F! Q% x! S7 G& Z! h- o# {# U& ^( o9 N( j5 ~0 _
給你一個朋友的MSN,你可以跟他討論看看,' s  z; A$ Y: |( Y# V1 X5 F
他本身是程式設計師,也對FC模擬器很有興趣。% F4 w+ ]" B  P' `& D" I
8 u4 m# f" g2 h* d$ H
MSN我就PM到你的信箱了。' G3 q- O, |- x# ?: X
6 c! R5 l: y7 ?
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 $ O1 V  |& ^" _7 Z& t
呵…… 谢过团长大人~~
" d3 U  Q% c! c6 v5 f9 g# _

) Q  z, [( S9 s6 l( {0 Z哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
3 J. D! i0 B! G7 q团长的朋友都是神,那团长就是神的boss。
, i( p* M( m* l* l% t/ W
哈 不敢當,我只是個平凡人,/ a4 E  l0 ?$ M) W& S9 ]
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙: v) d4 d' A- B7 A3 b8 r4 Z
ZYH9 H. g4 _, ]. s3 w
QQ:414734306
( m* T- [7 Y6 ~5 H7 |0 i/ s6 s/ aMail:zyh-01@126.com+ ~, B( v8 i  b6 v1 X5 d( h
3 C9 Y. V/ |! }. V1 b5 K
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
* _0 d% w! I1 [% _1 r再次对团长大人和悠悠哥的无私帮助表示感谢~~

9 \! N5 A, k9 N( A( S不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-2-3 11:11 , Processed in 1.093750 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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