EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
# Z% O0 T" V! w2 d+ g3 \$ {. O楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~8 `% m1 v7 c+ m
这里有相应的模拟器源码,就当送给大侠了~~* \4 e+ H. @- [: h1 w, `( F% Q4 S: D# i
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
2 W* D; ^( j6 [; C能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。- L/ q0 H; l1 l# d8 `* [
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
5 Z& `2 X4 C/ J! H这里有相应的模拟器源码,就当送给大侠 ...

6 J! l0 s1 }3 }聲音部分(Audoi Process Unit = APU):5 p2 r* i% [) r: g2 L
.\NES\APU.cpp! q$ D# G$ U. f0 y; ~
.\NES\APU.h
) z8 c3 ?$ L- \1 l1 S
& y: a& k- U# }- }( H  J
/ _) u  N1 B: S: f, n; Y影像處理部份(Picture Processing Unit = PPU):$ C8 w/ b, Y9 y! q6 G
.\NES\PPU.cpp
* w. V" U& c# I1 q! Z0 {2 ^8 x.\NES\PPU.h2 `0 V4 f. t! c& Z: ~

2 ]7 M( `+ U+ E  x2 H4 F1 n如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:9 h) I: x7 z& {8 V! {/ m
(由于很多专用术语和算法机理都不明白,所以看不大懂……)8 D4 U" p2 t2 X- |
//////////////////////////////////////////////////////////////////////////; X. ^1 r8 V# [" R5 b( k/ E
//                                                                      //
- i: @0 Z$ t, w//      NES APU core                                                    //% k" J$ o4 H. b/ Q, O# [' q
//                                                           Norix      //
9 \' J7 w; i$ z. z* M. _6 x//                                               written     2002/06/27 //! r$ w* A3 d3 n+ o$ i4 g
//                                               last modify ----/--/-- //1 N3 V+ }1 C* x" ?: a
//////////////////////////////////////////////////////////////////////////
- G6 b2 D5 u$ O% M. Z# v#include "DebugOut.h"
! A* C& X4 o$ R" E#include "App.h"
) L& J* \$ _5 Z: F6 f1 G#include "Config.h"
7 d6 n, g2 P/ q$ }0 \' |: j3 G' S% z! V, o, w
#include "nes.h". X- ], c! Y$ X& l3 k
#include "mmu.h"
$ [( T. r) d$ z$ @#include "cpu.h"
" N, p  w8 N7 p3 f  Q8 `% B" @$ s#include "ppu.h"
% q) S0 I" e9 o8 B: [, i#include "rom.h"
1 B- A8 f2 K% {+ I. K, C! X#include "apu.h"
2 D8 a% O9 G0 K5 y9 Z
# I: W: s& y+ c. x& F6 D3 q// Volume adjust# T: W6 N4 N/ F
// Internal sounds4 t; H) G8 |$ {0 d
#define        RECTANGLE_VOL        (0x0F0)% ~. O5 ]; j* ]3 ~' g3 r
#define        TRIANGLE_VOL        (0x130)& h( |, ~6 g  E3 J& B0 [
#define        NOISE_VOL        (0x0C0), p6 y# _( G& D- u
#define        DPCM_VOL        (0x0F0)
" {6 N0 S: J; Y// Extra sounds
  Z" W) q& M! r  M#define        VRC6_VOL        (0x0F0)
) P1 V9 k0 x- f" j$ B6 M% x#define        VRC7_VOL        (0x130)
, [# B, \3 r: q5 k, e#define        FDS_VOL                (0x0F0)
. I0 F$ x  {% X# ?! ]6 `#define        MMC5_VOL        (0x0F0)# C3 e+ q* V# C
#define        N106_VOL        (0x088)
0 G, S5 g  s9 |  S, I3 \5 j#define        FME7_VOL        (0x130)! x- v$ E. y& P- n
7 L; E' Y) q, U
APU::APU( NES* parent )
/ {" F; d% P: \7 V+ H3 {7 t{
: _: [/ D8 L4 n- y( [3 E1 Q, |        exsound_select = 0;
6 O! k; w* _% o  C# H- U; y* z5 M- W$ o
        nes = parent;' X7 J" W4 j& f6 D1 Q, k
        internal.SetParent( parent );! L, j) I6 A$ ~) [2 w; V
. R+ N6 Y* x( m! f% t
        last_data = last_diff = 0;/ z# ]" x0 S' e3 H1 U! P
' u  X+ F- Y  s# h' l' K
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );# z( y( t& a( k. Z

8 \" u3 m) t) x) ?& @: b        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
) o* J% U2 C1 u+ X+ {        ZEROMEMORY( &queue, sizeof(queue) );
9 {7 H+ Z( M  ?% o        ZEROMEMORY( &exqueue, sizeof(exqueue) );
  [% q2 r1 M& z/ C" `' Z* E: G  e) n( ^/ I
        for( INT i = 0; i < 16; i++ ) {
4 {7 [) F% s0 R0 x8 {; i$ q                m_bMute = TRUE;" _2 A5 g+ x& P
        }
8 Z0 O* h5 h# E( p% }: R2 ~  e8 H' }}
5 G( a- b& a) L. u6 ~+ C
0 ~+ F$ ^( ?- z0 G+ m2 S1 p7 HAPU::~APU()' m7 w* R2 x/ J7 a/ Y
{! r. h) u' N: `$ J# e2 H: G" H
}
. c7 h& t8 _: n4 x; U9 i
& ^1 ?) i' Q" z# W5 g( nvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )- U7 O, U$ K& p* D4 `
{! @1 X0 i6 V' b; X) r% H! @8 e
        queue.data[queue.wrptr].time = writetime;
: u0 E- ~- w2 t8 q) v        queue.data[queue.wrptr].addr = addr;2 a0 A- @# w) m9 E( U$ z7 V; M
        queue.data[queue.wrptr].data = data;6 L5 Y7 I1 x9 J  F' J
        queue.wrptr++;) D, U  o2 V5 w2 |
        queue.wrptr&=QUEUE_LENGTH-1;
2 Z4 N* e8 a% x' x% i        if( queue.wrptr == queue.rdptr ) {
1 i2 M+ R4 r, G5 j% J                DEBUGOUT( "queue overflow.\n" );8 h8 M9 s, \4 v3 V7 P
        }$ u- k+ N& q/ \4 }; j
}1 G' Y4 X3 k5 A2 n9 z
9 {0 P* b8 {  u# u
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )8 D- ]7 Z5 ~5 N& N6 t! K4 {! |
{
4 q" X. A" A3 B2 q1 p' R' w        if( queue.wrptr == queue.rdptr ) {
$ F6 Q4 F1 b# |2 A% U; H                return        FALSE;9 @) D. o! B- R+ [+ o
        }
6 H2 t+ H3 B% e; Q1 O7 `! Y) _; J) B        if( queue.data[queue.rdptr].time <= writetime ) {- r. R8 A9 n2 Z5 [! R
                ret = queue.data[queue.rdptr];
/ R# f  G6 F. A( u9 y                queue.rdptr++;, }% z5 q9 R) c; o; D! e
                queue.rdptr&=QUEUE_LENGTH-1;6 e' ]' I' g/ E8 ]* n' ~
                return        TRUE;0 @2 g+ w4 X+ \5 y+ Q" a# q
        }; p# Z0 R! E! f6 b2 J, Y9 P
        return        FALSE;6 [0 T1 ~2 T: u; v
}) @$ [" ~3 R7 ]5 z& m- i- d
; Y1 r' F* Z$ y8 K
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )2 _$ _& j) U' a
{
( g2 Q7 B! _. q; L* }: ~; i# n- Q        exqueue.data[exqueue.wrptr].time = writetime;3 s4 m# X3 H8 j5 u
        exqueue.data[exqueue.wrptr].addr = addr;  [/ w7 ^* l6 e6 `% u( t
        exqueue.data[exqueue.wrptr].data = data;8 E7 R/ U! ?3 Z1 Y, b
        exqueue.wrptr++;
3 i+ \* V+ J. X        exqueue.wrptr&=QUEUE_LENGTH-1;
! F  j& [& F+ }! x% H" Z        if( exqueue.wrptr == exqueue.rdptr ) {& }( ^( F# E% A% o/ V8 J6 s
                DEBUGOUT( "exqueue overflow.\n" );
) k8 S/ f0 F) c$ i0 K        }
0 l- f, i  Z! }) [+ @) I& c}
" z/ w4 G6 e, i- [9 \$ b/ _8 \
* _+ P+ ^, h) Z' y7 N; s3 [: eBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
$ @- _  d& g* P{2 n8 Y- h- g+ q# }, m5 F6 P6 y, q
        if( exqueue.wrptr == exqueue.rdptr ) {
3 R3 ~! }+ P* [4 B. \                return        FALSE;
3 o. _7 n# O2 E. N) h; b# d5 s% B' ?8 n        }* k  E7 m, A* j% H0 H: E" i% ^) D* N
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {% z) g6 ?. f0 Z. a/ m
                ret = exqueue.data[exqueue.rdptr];
# w( f% V) A! _) h% ?4 x$ q                exqueue.rdptr++;5 D/ N, y" J' J& L* g
                exqueue.rdptr&=QUEUE_LENGTH-1;
; d7 ]3 I5 S5 {# J* ?8 O                return        TRUE;
4 Y* ^' U0 }- Q" ]( F9 c2 d        }4 S% U) ~- z9 K% m8 j' Y
        return        FALSE;2 Q% V" b& s. f6 H! {& ^- Y
}
5 L  H  F# \3 ~, Z" |
5 N  e& f0 r0 Y5 L, \void        APU::QueueClear()5 \2 a8 p# W2 v# |
{& t: b( t6 K  J! N
        ZEROMEMORY( &queue, sizeof(queue) );* ?$ T3 Q5 }& B
        ZEROMEMORY( &exqueue, sizeof(exqueue) );2 p. [5 V* e0 r! {. A7 t# C
}
# B7 g7 O  f6 G5 n' d6 c
9 q2 z, K* H6 C+ ^: X5 d" ^void        APU::QueueFlush(): n9 @7 h& j- k( X4 U
{! o# V: w+ g5 `7 D0 {
        while( queue.wrptr != queue.rdptr ) {( r) Y$ g( J1 e2 t% ~+ O# ]
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
5 J/ N# `" S+ r! b                queue.rdptr++;4 O% E) `) c% T. i6 O
                queue.rdptr&=QUEUE_LENGTH-1;
. G9 ~7 w9 \( M, w- W( m( T        }
. Y( n3 E4 N1 {2 j" J0 K0 [& l* W- Z3 ^2 n" x
        while( exqueue.wrptr != exqueue.rdptr ) {
% s4 X! w6 T7 O# D( S1 |% k                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
, [4 h: b0 v. X' d, s2 b2 p/ G                exqueue.rdptr++;
- W5 d- ]0 @1 p. T                exqueue.rdptr&=QUEUE_LENGTH-1;
0 c' @1 B7 E8 p8 C7 m" _- g        }, g6 J4 j2 v4 n" ^" I% G
}# `5 ], @( i+ Q% b$ p2 C

- y- N. Y4 W7 k  ^- @2 \6 ?. Mvoid        APU::SoundSetup()
+ N5 T# T  Q) n: |{
* z6 I/ K" M4 P. E1 V        FLOAT        fClock = nes->nescfg->CpuClock;
% S- G& T1 p3 T. `/ u        INT        nRate = (INT)Config.sound.nRate;! O* u& X' i- h$ o* d* t
        internal.Setup( fClock, nRate );
# z. C/ B1 `6 x3 E& s' D; t        vrc6.Setup( fClock, nRate );7 Q# }" Y9 g+ m6 Q8 m! ~
        vrc7.Setup( fClock, nRate );, K4 P' }! D  q, a& d
        mmc5.Setup( fClock, nRate );
/ Z: b; w' A8 a( y) @8 h        fds.Setup ( fClock, nRate );
3 j5 P% S5 S- m5 X        n106.Setup( fClock, nRate );
; n# q: \9 `# y4 L3 a        fme7.Setup( fClock, nRate );+ q1 B  p5 w" a) f) ?
}
$ A+ ?. `) F; \; m4 D# N+ F3 `8 X8 k
" q; I; O7 G, g) f' wvoid        APU::Reset()
7 U+ J+ {% z: c: ]! |{
1 M+ P, b/ `4 e  r; O        ZEROMEMORY( &queue, sizeof(queue) );
/ E" x5 o4 n; T3 Z4 m3 N- p        ZEROMEMORY( &exqueue, sizeof(exqueue) );
% l& g: n8 h0 M! C+ L
8 l7 C& T, Q3 {. ?& b        elapsed_time = 0;
- f0 ?$ M, F# a. s( g. m# f
4 X  d- W. L  L# g0 ^' u# z        FLOAT        fClock = nes->nescfg->CpuClock;
' {* [8 k1 [' Q) |7 I        INT        nRate = (INT)Config.sound.nRate;
1 L2 l  N: Y" I, b: D2 K5 J8 C        internal.Reset( fClock, nRate );
  J- ~% I4 Q  w4 L- ?        vrc6.Reset( fClock, nRate );: w& Y, z3 ]  ~/ m# ?
        vrc7.Reset( fClock, nRate );
- C4 H+ B! ]$ l! z        mmc5.Reset( fClock, nRate );% G# ]" G) X1 V
        fds.Reset ( fClock, nRate );6 K, t) @0 ~+ z! P7 _: L: Y
        n106.Reset( fClock, nRate );) P, K2 G, R" s
        fme7.Reset( fClock, nRate );  R: k5 H2 {. @5 X# N
: C# Y4 v. t; o* ^; P6 l
        SoundSetup();1 k1 X4 D9 F$ [" Y& Q. l$ N5 R
}
/ d4 l4 L% j2 Z* A% b, }8 V& j% E" b
2 `! |5 l/ v( \; W0 O- evoid        APU::SelectExSound( BYTE data )
! c, m4 `. m9 j{
$ ?# `- H3 D4 W        exsound_select = data;
: P% Z8 b  b1 l}  w- m6 p& U  @6 ?. t$ u+ U
- j) r3 u0 E- z- _5 [" V
BYTE        APU::Read( WORD addr ); b# L0 \0 O: [
{( W) k- ]4 X  b) X( T
        return        internal.SyncRead( addr );! R, C, G* `$ j5 [3 g% C" z
}$ Q9 a- ^+ ^3 x

' W8 ^9 \, R2 qvoid        APU::Write( WORD addr, BYTE data )
4 ~/ v6 K; T/ E3 X, ~& y{- C5 B: x9 O. Q2 n( K. q4 A
        // $4018偼VirtuaNES屌桳億乕僩( ]8 J1 |' v. ~- h  s
        if( addr >= 0x4000 && addr <= 0x401F ) {. r2 C8 |1 h2 P3 ]  t* m6 Y
                internal.SyncWrite( addr, data );
' x: ]/ f, K7 G, |$ g3 Z; I7 j6 m% d                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
) q$ @- Y: C3 b* E  f        }
. ]# P, N0 X9 c- y8 Z* i}
! j4 q# p6 S( X) {) z' E$ i' I0 }0 D+ x# y- I, l# w
BYTE        APU::ExRead( WORD addr )
! o+ _  Y  X' u4 E5 E6 U8 M{1 m. w/ R  \& H# v( Y$ I  M+ e% Q
BYTE        data = 0;
" R" d3 T4 n4 s+ ?' @; J$ h6 D" C8 x* J* I- W, I
        if( exsound_select & 0x10 ) {  T5 Y1 n! P# f1 C1 \
                if( addr == 0x4800 ) {
8 q2 s# h, U4 t9 \. M                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );6 N% E; i) J& ]0 U, H6 {
                }
8 d$ O* Q$ D) x4 s: q' e        }4 N; U. O4 ~, x' {2 s
        if( exsound_select & 0x04 ) {2 ]9 s+ W1 f! o$ a* w0 N
                if( addr >= 0x4040 && addr < 0x4100 ) {
; W% R6 {, v2 W6 X. Y                        data = fds.SyncRead( addr );) d4 k( g$ _& w4 U2 T/ w9 b1 {
                }
: V3 \' Y- z+ L$ c+ e  Z9 k3 e8 a, x        }
/ [2 O: w9 c$ S. H8 q        if( exsound_select & 0x08 ) {
! |, {2 w7 I; I$ x2 v1 X                if( addr >= 0x5000 && addr <= 0x5015 ) {7 M9 U5 {& {& K! n1 u( ~9 c
                        data = mmc5.SyncRead( addr );* B5 ?/ S& C' h# c1 t$ \
                }
2 |' [, J) U- N/ w        }+ }; T3 x- O; I" o' P, U4 {

# s, z( \7 y7 Z. v        return        data;$ o1 f$ E1 ]: |) ?
}
2 D; o" O9 T7 T# P# w7 U
4 E/ e) _9 c8 N9 Dvoid        APU::ExWrite( WORD addr, BYTE data )
) h0 T5 U: l, M" s% _6 s! N. M3 B: o  b{7 K! |5 N" t3 q0 N- H
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );- _' f' ]9 U5 E; V* a; ~9 t( w
' ~& y" W( [! \
        if( exsound_select & 0x04 ) {
# n2 {8 Z: o) E6 r5 s+ C                if( addr >= 0x4040 && addr < 0x4100 ) {
, ^6 ^5 S0 H! s7 p6 ?                        fds.SyncWrite( addr, data );- n: J9 Q& |% g9 A) ^' R
                }
) z9 z7 `. q" O        }: C1 P: C+ a1 B" \. G* H6 @

$ ~$ ]: t! a8 \$ W        if( exsound_select & 0x08 ) {
3 c5 p9 n+ q) ^9 V8 D% a6 A/ L  V                if( addr >= 0x5000 && addr <= 0x5015 ) {
3 x' T4 d* G, S0 o4 s                        mmc5.SyncWrite( addr, data );
% s8 O4 m$ J. s                }
6 ~/ B7 B* O! N# r% ]- T        }
" i; u, E4 D3 w+ v5 W}) {2 `  V9 z# z, b- C% c
8 T- g" q% \; F. U* h# g
void        APU::Sync()2 V2 c- j5 c: B$ g" y
{
% j% L* j0 x$ ^% I}
9 W8 @- J3 n& K
6 n' H7 X  i$ q1 ?void        APU::SyncDPCM( INT cycles )9 t2 P( n2 c. v1 y
{
6 Q- N2 |, \0 ?8 _7 h( v, v$ U9 ~4 X- W        internal.Sync( cycles );
4 i  B0 S* C; D7 K4 j
/ Z8 [. a/ j' O; Y, d4 `        if( exsound_select & 0x04 ) {; W3 A* x, }, r& T" D
                fds.Sync( cycles );
& s! l2 R$ C" L+ W% i# t5 m        }
% B* h7 @4 u- z        if( exsound_select & 0x08 ) {
8 G( J, D' {* ?$ B                mmc5.Sync( cycles );
- _6 V/ p$ z0 m, K7 X        }# m4 V6 |. R# W& z! ?+ l
}
0 O0 A. c4 t, a# {3 M) a9 P6 j+ D7 a" z- i5 j
void        APU::WriteProcess( WORD addr, BYTE data )$ d0 [2 U* L  A# }8 j$ _, I
{
$ H0 r  c% J( v' B8 W        // $4018偼VirtuaNES屌桳億乕僩: R. Q; U' H2 C% v  d# |
        if( addr >= 0x4000 && addr <= 0x401F ) {( n& Q# h8 E, g. D( m- s* z6 J
                internal.Write( addr, data );+ |; Q7 y2 E" W9 B" t: g
        }
2 p2 N4 i9 i5 Q$ p' s}! E; R- B: i  D  B9 L' F
1 ~. g2 o* O! K: y! u' }: P
void        APU::WriteExProcess( WORD addr, BYTE data ): v4 S, s5 A6 P- Q
{% R8 `0 C) P& u
        if( exsound_select & 0x01 ) {. s  E9 y2 t6 Z: A( i* _9 F1 z) k
                vrc6.Write( addr, data );
- W, N" e5 V9 z- v* O        }
  T) A% Z/ p. o% {4 b        if( exsound_select & 0x02 ) {
5 P2 n+ W0 a0 J' s6 u                vrc7.Write( addr, data );: h9 _: D3 ]6 X% k: c& `" A  g
        }
6 t! w7 m  ?( \6 E' n7 b  d        if( exsound_select & 0x04 ) {+ V9 H: k' H' Z& t
                fds.Write( addr, data );0 q2 {, F, }% h  f
        }
* g& M' `6 \/ G        if( exsound_select & 0x08 ) {5 T; j/ y1 b" e
                mmc5.Write( addr, data );0 s( h. d$ \. i8 |. J) A
        }
3 n8 M0 x4 Z4 `- ]: R" _6 ?" E8 z& u6 y8 q        if( exsound_select & 0x10 ) {
. @( G3 E# A, _0 N                if( addr == 0x0000 ) {
* ^6 W* S% N( X* X                        BYTE        dummy = n106.Read( addr );) ?8 k: e' ?' E/ B; N$ o
                } else {8 W' G: q- G- v4 |- E1 g
                        n106.Write( addr, data );. J6 [8 C; W( n6 k/ x# f
                }
; a( ~8 d) L% _% Q+ l/ H1 S1 M; k        }
7 v, [! u8 Y' Y8 R5 B- d# H        if( exsound_select & 0x20 ) {' U# u# U9 i1 H) d
                fme7.Write( addr, data );( k+ H& l8 K8 E4 z1 A
        }
8 h5 t5 q$ a4 N2 Z# u' _. u7 Y6 L}# Y7 g8 b9 y. l* Y
8 k6 Y+ Z6 n! j3 L& U+ @# i0 |4 S6 W
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )' v' ]0 n* b- e) h: W( I# m
{- v* w3 q3 ~5 r' q! n; Q
INT        nBits = Config.sound.nBits;' f! S9 t+ m: u2 [/ c# ?
DWORD        dwLength = dwSize / (nBits/8);
6 w! N) `: l  w9 s+ lINT        output;
! A3 P) k3 ~  m  n6 j9 b3 J% t2 vQUEUEDATA q;
! v: R1 W, [, y' `" A* IDWORD        writetime;
% z5 M6 z( H6 _. }3 l  C4 p( r5 Q/ ]
LPSHORT        pSoundBuf = m_SoundBuffer;
3 L5 O# m8 z) s+ K  @2 d5 f( rINT        nCcount = 0;
6 T0 q3 O, p4 c3 H% ^# A3 Q/ E) u+ ^
INT        nFilterType = Config.sound.nFilterType;0 i! b( N8 w% F

9 C& c2 g; n) z        if( !Config.sound.bEnable ) {
# V. z0 k6 y' U! O% f4 j6 H                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );0 M1 t' ]# b: M1 [
                return;
% U: H2 _8 R  C5 K        }, X, w! K* M% K2 T
# b7 f& n3 @. G
        // Volume setup" {& o. h9 Q8 y. }# h) _* |
        //  0:Master
9 N; p  o8 K" L6 n7 m) Q7 o        //  1:Rectangle 1
5 ?0 S' T+ `' G/ B" Q; P& Z# o        //  2:Rectangle 2
  U8 I- d9 P: g, I+ l3 @2 D        //  3:Triangle
: F( r0 i- x$ g        //  4:Noise( A# w7 z0 l( A7 v
        //  5:DPCM; q. p2 y3 m4 ?- w( t
        //  6:VRC6
: I, e* f- U; @+ s( h# k- H        //  7:VRC7+ I; I! ]7 b1 [
        //  8:FDS  E5 L) t+ K9 E' \0 Y: T
        //  9:MMC5+ B; B6 Q0 o/ G! x' \
        // 10:N106
1 o7 l( s% @6 x: _) o        // 11:FME79 z2 x2 a' A( C7 G# B  E; r
        INT        vol[24];" h1 }- |1 ]7 H3 K- F4 ]. L
        BOOL*        bMute = m_bMute;# E( X( [- }4 c. W
        SHORT*        nVolume = Config.sound.nVolume;2 J! b; h& G* H; E( E4 W5 n

; R  O5 A- |3 w" u! ]. f: h; z        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
0 l4 L1 K9 w/ c8 l: [4 N
; p$ i6 [" o. E- j3 Y        // Internal% i6 Q7 c: f7 A
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;" u+ \1 m# m0 V% ~
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;/ E% @/ G' T3 r% O% }: Y  B
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;; T0 p  @3 l- O7 a
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
* y/ U# S4 P: r7 L: q        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;  z7 J4 W" l1 R
# W# O; r& U. k+ ?- }
        // VRC6: N( P" G7 P2 f5 r
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
& W0 n# l, k6 g; ]5 k! S" \* i# L        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
- y1 ~! f: x2 l! A" z* N. L+ b        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;* ]$ c, ~3 @% F0 C$ V, C! {
! _& ]2 @+ P/ [7 B
        // VRC7( ^1 |5 p& n  O, v* Z4 y& ^8 L
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
. J+ L% M, r! p
1 ?' l/ o" ~8 {! Y7 X; a# t        // FDS
) ~* k9 \* U5 S" B" v) k        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;  Z$ G" A. S0 d7 U9 n+ ]

+ x" j; R3 T% T% ^4 c/ c" T        // MMC5
' d3 W" J1 O0 e5 Q% C% o; |4 r        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;5 G# z2 G1 o# j3 N9 r- ^3 x
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
: m5 q4 |. c5 `7 m" p        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;8 |( }* b% l3 F

. \% L* S7 w; I, N/ ]* u0 Q' T5 G        // N106
  w' d2 E- ^, Q: F, E' J# d8 x2 U6 W        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ e2 ~+ U* M, Q* {. b
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
4 Y( B5 d) E4 F9 Y7 v7 w+ I( `: E$ ]4 S        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ d8 c) m- [' S8 C$ u; @; l" }        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ D, b0 p: ]# D7 r
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;! a- Y1 Z! J2 C5 C3 G- z8 c# U# ?
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;5 ^0 J+ g7 ]  `) x
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
5 |( M3 u, |. Y# N6 w# d6 Y( Y        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;# Q6 ^0 n/ h/ \9 l+ i, M% M

; N4 A$ V- l3 I% y        // FME7
/ J- p( B# x* o3 S        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;6 c4 e+ e- z$ o# h4 s/ X7 Q' }
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
0 n0 t+ p: `' ~* ]; M( r" Z. W        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
# e) D$ W, I$ R# }" w3 J% F9 ^0 H- k' {4 h2 [
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;% K6 ^, w& @8 q8 A  D# i+ ^
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;1 p+ [% U1 U3 |5 M' B; Y
; b3 ?$ r( q9 h- h" I
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟1 F: G! S: U! P: h, @
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
& S6 o9 b! _- I( R3 @" }                QueueFlush();) `; J9 D1 q! ^; r  d
        }; j1 d4 i4 p( k5 b$ [& E

1 p7 V7 T  Y, v% H! N5 O        while( dwLength-- ) {) A& c3 g, N# l( w% v7 ^$ M
                writetime = (DWORD)elapsed_time;8 ~1 y; ~3 @: ?

: B  |5 u  l- m5 S0 |$ P                while( GetQueue( writetime, q ) ) {+ d8 ^- s) `* Y% C; x% l, @( V
                        WriteProcess( q.addr, q.data );
) a+ n+ S% G! P9 r" {                }" ^* {6 L' O$ h* ~
7 J, O7 [* I0 H( m+ W% C/ t8 O
                while( GetExQueue( writetime, q ) ) {
& h2 p. H5 p  M: c# i) ^( m8 ]                        WriteExProcess( q.addr, q.data );: g. k# }& V5 }! B! s
                }
8 ?  q3 _& g7 q& `& C, J  F; \+ F! R! @6 ]' G4 p$ ]; t; y
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7# P" y/ ]6 R* M& x; ]. j% m2 w
                output = 0;$ s' x4 c5 P% A' H! e4 k  E- g
                output += internal.Process( 0 )*vol[0];+ _. |# ]: Y; s& U" b: H( t
                output += internal.Process( 1 )*vol[1];
6 I. U- W& L6 A! q0 z2 n) F! r  j                output += internal.Process( 2 )*vol[2];/ i; Y2 W+ v4 [# b7 Y
                output += internal.Process( 3 )*vol[3];
9 N6 z2 I$ H* f, e8 q                output += internal.Process( 4 )*vol[4];
3 }% t. \0 ]( p; e8 M" _2 Z- [9 s/ a* B+ c4 X' O3 }
                if( exsound_select & 0x01 ) {
$ D8 z, Y- z" X" i3 i6 n2 e                        output += vrc6.Process( 0 )*vol[5];
' o# d7 k+ p! e" |: U                        output += vrc6.Process( 1 )*vol[6];0 H9 C7 a1 w4 d" t8 }- G1 c- l
                        output += vrc6.Process( 2 )*vol[7];/ Y0 w- k) N# e, Q. Y2 i- W2 a" Z9 A
                }
) B" W: P' ]0 y+ [- u' O                if( exsound_select & 0x02 ) {
; h. g, k9 H1 U& H9 ^                        output += vrc7.Process( 0 )*vol[8];) c9 }9 y0 Q7 Y
                }. w9 F# T+ z( v' V4 g4 E
                if( exsound_select & 0x04 ) {
0 |% X* }1 R8 C, Z                        output += fds.Process( 0 )*vol[9];
- m- _; r/ R9 b2 K                }
: V# d- ~# C" [/ u0 @                if( exsound_select & 0x08 ) {
) b8 b4 _% d3 [/ s                        output += mmc5.Process( 0 )*vol[10];9 d  S; @9 U, [( h$ L& w
                        output += mmc5.Process( 1 )*vol[11];
# B4 H& X  R; U, j' G                        output += mmc5.Process( 2 )*vol[12];
+ Y1 i% ], z7 T8 {6 R8 \                }
9 `0 C0 p$ ?2 ^7 L0 C                if( exsound_select & 0x10 ) {
8 |( P9 U, S7 g. q0 h+ q& p                        output += n106.Process( 0 )*vol[13];
: p7 ]3 j( |. j- f8 e                        output += n106.Process( 1 )*vol[14];4 \; P7 U& e+ B2 i
                        output += n106.Process( 2 )*vol[15];
' `/ R' T! v! L$ g- I! E                        output += n106.Process( 3 )*vol[16];
$ i3 w. @  s( D& D+ L                        output += n106.Process( 4 )*vol[17];
! }; f1 F% H' `' m1 R7 M1 ^                        output += n106.Process( 5 )*vol[18];
) [. z2 g  F( x5 t' I8 r2 r                        output += n106.Process( 6 )*vol[19];# Q+ n( I/ }3 J7 j! z
                        output += n106.Process( 7 )*vol[20];# D% Y  o* m, h+ I" B  l$ H
                }3 y( x" W9 m4 z( Y9 @1 r1 S. g: I
                if( exsound_select & 0x20 ) {
  }% A7 x# L4 S5 ]( @& o- j                        fme7.Process( 3 );        // Envelope & Noise
4 U- u2 J  _8 t  c& J                        output += fme7.Process( 0 )*vol[21];
: A0 }. y' Y. P' y0 ~# {5 f                        output += fme7.Process( 1 )*vol[22];+ C" Z% ~5 D- m! O4 L8 u5 n
                        output += fme7.Process( 2 )*vol[23];
* u8 ^: R! Y6 x! G                }* ]" [- g9 M0 X8 L
( v% k) d! M- r5 f2 y
                output >>= 8;
  N) F2 s% c6 O6 r. f, ?/ ^5 \1 h& W; S/ o3 a/ k, p1 W
                if( nFilterType == 1 ) {
. {  }9 K* r% }, [& J/ @! ^8 c, {, S                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
* I6 l5 j3 ]  P9 M  [; e8 V                        output = (lowpass_filter[0]+output)/2;5 o( U7 {7 e# v0 f
                        lowpass_filter[0] = output;
+ _& ]/ m. q: v: L6 T( f                } else if( nFilterType == 2 ) {' E: T( a: l4 e7 Q! Z- B
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
7 R/ t$ D& ^6 A* w                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
6 H9 D$ U9 i* g- |6 T                        lowpass_filter[1] = lowpass_filter[0];& A6 o) d, R5 S4 z5 S6 d
                        lowpass_filter[0] = output;3 e/ d6 A# j+ V9 B/ |( k; a
                } else if( nFilterType == 3 ) {8 n! h: t+ t) I
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)' W3 l* M5 ]. [2 |1 K0 O
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;4 T2 p5 p4 ]8 B! p8 j
                        lowpass_filter[2] = lowpass_filter[1];) h2 {! q) u4 M2 R0 @1 m
                        lowpass_filter[1] = lowpass_filter[0];' m( b; L4 n  u0 w$ m
                        lowpass_filter[0] = output;
- E* |9 K" i7 R- h                } else if( nFilterType == 4 ) {- d" H  N: A9 u  z6 P2 E& e
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
! ]- h2 Y) w0 }0 Z! a, X2 J                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
+ @, B8 m# e! @) o; h: C; ^1 i                        lowpass_filter[1] = lowpass_filter[0];
9 k' s! w0 Y9 h# \+ ~* [2 _: n/ I                        lowpass_filter[0] = output;
# Z) s+ a; t9 d9 [  W% w( }                }
( m+ `" \9 A  g/ V9 n; q; s0 ^6 R1 ^) g' w5 B( }) d
#if        0
9 n/ t  s0 ?% Z                // DC惉暘偺僇僢僩
6 K- `  a% t: T# D1 p1 s# }                {) I. }1 E# M5 O4 b# v% y% j
                static double ave = 0.0, max=0.0, min=0.0;' v' |1 L6 o" f+ J
                double delta;2 s; I' z& F2 K& J% V3 t/ W
                delta = (max-min)/32768.0;/ M' T: U: L( z# _1 _. I* U% z
                max -= delta;5 `3 w- b/ r2 X
                min += delta;
4 f) l  ~3 q5 s; Y( I                if( output > max ) max = output;0 C+ {- K$ q. s  Y% A' V2 ?3 T
                if( output < min ) min = output;, M2 Z8 f' {$ i4 d
                ave -= ave/1024.0;2 c5 f/ m* O7 C3 T+ ?
                ave += (max+min)/2048.0;
0 q2 v5 o' d  A! G                output -= (INT)ave;( f3 R1 m' o% S
                }7 L5 E6 x- \7 I1 G  T& X4 A
#endif; c* |! s! S+ M4 Q/ J
#if        18 l6 I4 z4 B1 o# \" X2 }. @; P
                // DC惉暘偺僇僢僩(HPF TEST)
3 A1 N/ o+ }- B3 i  f9 e                {7 b1 j9 j( d' T6 ^" B7 I
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
# B& r5 s" S8 b+ S' U4 B$ A                static        double        cutofftemp = (2.0*3.141592653579*40.0);2 M. A3 \, i4 Q8 Y/ D. B) r; B
                double        cutoff = cutofftemp/(double)Config.sound.nRate;  |- u7 b- B+ e! _+ A0 @1 B
                static        double        tmp = 0.0;' {8 b/ m. D4 u4 y& X
                double        in, out;$ L( t5 E# Y1 S3 t- @& s8 _
& x5 o' ]- y5 I2 \3 S. Y8 _7 }
                in = (double)output;& ?8 n7 g2 i: R' }
                out = (in - tmp);2 ~! {  O! u& F, T% e8 Z9 M
                tmp = tmp + cutoff * out;
& [: `. V2 `" s- Q6 L; X
. b8 k* r9 r. e, b, O7 n( j# c                output = (INT)out;. H4 {- M8 u$ e& w3 A
                }
# Y7 R9 g* t7 ]& E5 Y#endif
0 x0 u* ~$ q( O9 X' |0 L* @% P#if        0* U% t" A# v3 I1 H) h9 e
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)) ~1 M% {* }  E& q& ^8 u
                {, I/ f2 p  X$ G
                INT        diff = abs(output-last_data);
' f0 S$ f5 ]* D  M2 s- g5 {2 H                if( diff > 0x4000 ) {
2 _. p. y3 K2 ~  Z& k0 n9 D7 g1 q                        output /= 4;8 S+ M7 A# C0 c
                } else 3 }  Q! i  }+ P2 L4 a  G
                if( diff > 0x3000 ) {
$ `7 p9 ?. }0 c/ V+ {( P                        output /= 3;
1 @5 `$ M/ T) r$ a* R                } else
! c3 S* e, X# M/ L                if( diff > 0x2000 ) {
+ T# F$ V5 ~1 ]" I. w, I" R                        output /= 2;
# L2 w: ]5 |4 e: S1 n5 h                }
, O  a  d  X) T! }1 E* r                last_data = output;
; s* [5 U) A9 N- B& L                }: j' V3 A& ]: P+ b  `4 E/ N3 l
#endif( f$ [# f, Q2 m6 E$ g
                // Limit
$ z; z( N: v. ^                if( output > 0x7FFF ) {
1 y2 _& G- a7 Y! e7 M+ n                        output = 0x7FFF;
5 u1 K) Q+ Y! U& l                } else if( output < -0x8000 ) {
8 K5 V9 \+ i/ L6 V2 S, U- c                        output = -0x8000;
6 m8 v9 P8 T: u, z0 M                }
' y. w' G# T* r# L
- o9 o. V5 W6 `. T: x) ]0 @                if( nBits != 8 ) {& p& x% M* R# e4 V# U/ @
                        *(SHORT*)lpBuffer = (SHORT)output;0 y" U1 H5 ?5 q8 s
                        lpBuffer += sizeof(SHORT);# x5 d' U- Q+ w
                } else {& z! h( t1 T$ D" Q0 r. G. e/ B
                        *lpBuffer++ = (output>>8)^0x80;
6 w7 }" F9 X6 {. R, M1 K                }
6 u* c% n& O+ V2 {) U- m3 E
5 y% a. N2 N8 m                if( nCcount < 0x0100 )
4 X* ~. f+ h4 K5 t( w2 x' M                        pSoundBuf[nCcount++] = (SHORT)output;
  Y7 C# Q, \9 a5 f! O/ `/ s2 N0 }1 b# M/ `7 t
//                elapsedtime += cycle_rate;
) I4 i- e( X. g$ g4 L& w  P                elapsed_time += cycle_rate;3 e) K0 J$ U4 ~& L( a8 ~( O
        }/ d8 @/ D$ V9 i) _1 }5 V8 ]) b: }0 w# b
1 K4 B! ~" K. d  }) W- k5 v
#if        1
( q5 T& ]0 R. w1 y7 C" k        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
3 b) M, D' Q; w                elapsed_time = nes->cpu->GetTotalCycles();
! u) n0 S/ y& P  P/ a, n( j* Z$ K" m        }6 T/ P" Z7 W+ ^9 b0 X  a
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {0 O" W8 k2 ?% {7 j# M) F. V: s
                elapsed_time = nes->cpu->GetTotalCycles();/ i+ _0 f( I$ ~! Q& x  f. I2 C
        }: Y- K& l$ M. m( w7 y" w
#else* h6 e/ f% p2 _
        elapsed_time = nes->cpu->GetTotalCycles();" A! C# P) ]% \
#endif
% Q6 L$ G6 J+ E% K( T}+ i1 g. O$ R( G% |* T
3 |4 w: t0 U& m: `1 ^
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
# M2 H  T: m4 j' K9 mINT        APU::GetChannelFrequency( INT no )  t9 B# O' f/ R; Y  W
{1 n$ V0 T" Z$ @6 {
        if( !m_bMute[0] )& e( ?& s4 q/ l5 i" o
                return        0;: f/ N/ N7 z4 f
: D" H, [" m* q5 {  c/ V* S) I
        // Internal
1 Z4 D. |/ E. ?( |( _4 Q, `/ w. t        if( no < 5 ) {
' P" t: I: s8 Q, ?2 ~; a' K                return        m_bMute[no+1]?internal.GetFreq( no ):0;
' M% n1 e& g4 o* l$ w        }
; \  h+ s) c5 l1 e; c        // VRC6
0 N; l  f4 y$ J. Y) D+ O* f" L  ~        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
' S. t6 T- j& P, i1 ]                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;' z& _0 `8 Z% J2 [$ U, _8 M
        }2 x* s  y1 g/ V( h( f$ M! S
        // FDS
9 z# H8 O( w+ ]1 l- S7 d- Q3 w        if( (exsound_select & 0x04) && no == 0x300 ) {
$ i" r1 J+ w% R                return        m_bMute[6]?fds.GetFreq( 0 ):0;
+ M5 u: n# _) T$ T% {        }) b1 v. p9 h: L9 d; T8 f
        // MMC54 x5 N! R' j' s/ [# Z& m! f
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {) j8 |. [+ c" L, W$ b
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
7 M6 y6 X: N; v) S        }
2 U: y% n: _0 u8 ]; o( o        // N106
" I! _; H( k! S, ]. J4 q1 r- [, Q        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
: u' `7 U: x6 Y( u                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;7 \: F, j5 X& |4 g* `6 {
        }. }+ Z4 c/ U0 g  F* g& `
        // FME7
" B+ t: w1 @, y        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {+ ~* O1 r9 d9 P2 R
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
& ~$ ^# P; ~, C$ S8 t' v, y! i        }. k& V0 a5 N0 T. X
        // VRC7: K4 ~. O9 D( o
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
3 I# F- \$ e7 d& S2 f; f$ R  w                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;$ L9 G% ?5 ^: i! D, e* }* B- X
        }
/ _' k2 I5 O% t! g        return        0;/ ^$ y5 S, s4 U2 X* H" a' T
}3 V4 {5 L0 n& H3 Q$ @6 c

5 g% N6 K) k/ p: K( \// State Save/Load
+ ~& q8 N, }, |void        APU::SaveState( LPBYTE p ), c& t" Y5 p$ i, K$ A
{
. O# N. R3 z7 v# g% ?#ifdef        _DEBUG; f7 u# ^6 y; @8 H" p* B
LPBYTE        pold = p;( ?3 Z0 X4 F9 U9 o& x! {
#endif& W, v$ ?- U5 g8 T$ {9 N
9 c6 a8 t" B8 e; Z
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞) D4 m0 }- u8 j) }7 ^
        QueueFlush();! ?2 A5 R! Z8 N6 W& y8 t, A% ]% f
' c7 A4 M% }2 h7 c, e1 r
        internal.SaveState( p );0 \; p: H0 K5 }% X9 U+ i8 \
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
3 M' ?7 @# N" c
6 w: G# X5 r/ T9 l" g        // VRC64 A$ L! K5 P7 w" |. m* B+ k1 Z7 Y* U
        if( exsound_select & 0x01 ) {
$ O! l) T/ k6 b2 }% q/ ~: U9 x4 o                vrc6.SaveState( p );
2 |/ T1 @2 {( r                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding7 {% u4 v% `0 d! |3 [+ V
        }
7 W2 ?! j+ r; S+ F) I        // VRC7 (not support)& }; E" F0 b6 c( s
        if( exsound_select & 0x02 ) {( ~3 Q/ Z8 {7 \1 g1 I% b, J
                vrc7.SaveState( p );8 N5 u) q" p% @/ `" \$ k3 [
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
2 S+ F4 s& d8 b        }; _% Q/ P" Z* \% I
        // FDS, l* D9 T& X7 p) n: _* k
        if( exsound_select & 0x04 ) {$ {: `( f& q  L) ?- {' j6 q
                fds.SaveState( p );$ A% w: w; x: g/ d; ]
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding) p% R' B' ^' l/ F! M
        }
" L  y( [' y7 x& k) p8 Z6 t, n) M        // MMC50 F2 }9 x; g  W/ p, k  R' n! h
        if( exsound_select & 0x08 ) {9 H3 e4 Q4 V4 i0 B
                mmc5.SaveState( p );' M. ?( b& ]; [
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
. ~  E% y3 a. K        }3 E  n7 U3 O# Z1 \9 G$ d/ T& H4 C
        // N106+ Z9 {- }: c8 x2 R/ k, z, o
        if( exsound_select & 0x10 ) {
7 l& j( V( i8 E) N; h                n106.SaveState( p );/ F# i, V8 m6 @4 T1 n
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding9 L8 j' W+ v  `. `0 O! b) D
        }) W# B! ]( A) `, V' Q" F0 R
        // FME7. t1 w& r+ ^% ?. [
        if( exsound_select & 0x20 ) {; u8 u; P" Y4 S3 s; @7 m
                fme7.SaveState( p );  q2 M9 d% _! m4 y& J
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding8 }; @3 Q5 ], c" z
        }: v  E+ Z0 C6 {+ w; W7 `' [

2 N! P, G4 |7 j# N- A#ifdef        _DEBUG
: M# {. J2 k8 {' h7 N: u% V- n& bDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
7 a. C) U5 X- k0 n  Q% {( T8 `& |#endif
4 ?! v+ ^9 P! E. ~2 q% G, g) C; {}
2 i5 x! G; u- e" \: O1 u- ?: ?0 }; i$ `9 L: [5 q$ o% L' R
void        APU::LoadState( LPBYTE p )! O0 J$ b" `( o' k
{
- _5 h5 s$ S% S! H+ {; C        // 帪娫幉傪摨婜偝偣傞堊偵徚偡- P- k/ o( e7 m
        QueueClear();+ J! B, L: x& d# P. f$ R
6 b" R1 r( c: [$ L& W6 X
        internal.LoadState( p );0 E/ |& M$ Y8 H" D. r6 F, G# g: U$ X
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding" R4 p  W/ h% d1 h$ b! }
2 u! _. X* Z, u9 c  l
        // VRC6
1 _& Q* X, U0 G: Z$ V, Y2 L        if( exsound_select & 0x01 ) {: L+ r5 o/ D$ \: |& g4 X, D
                vrc6.LoadState( p );$ Q$ X% L- D2 R1 L5 {. j( r& x6 N
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
2 e, t/ H+ i% i+ H- I( N# D6 I! x        }$ `7 i# ?' C& M
        // VRC7 (not support)
7 e2 X+ G: _1 O) F9 A( ?9 v$ w        if( exsound_select & 0x02 ) {( H7 P6 F; k% X9 E* A! p* K
                vrc7.LoadState( p );
' x9 n. l& @, L( V& N$ O& u                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding% l3 u$ ?' t' M% N; a$ ~6 U
        }! O. g: J8 u3 f
        // FDS% Z' y- }! R0 e6 f/ b7 K
        if( exsound_select & 0x04 ) {
& S1 ^, }) D0 b! E: M! ]  l                fds.LoadState( p );" n: N' P% g: {# S
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding* L& ~3 U  l/ O" g6 ~3 ]2 p
        }5 `" x! k  ~: ?" \' R
        // MMC59 U8 `! s% E7 g8 g8 |4 F0 q
        if( exsound_select & 0x08 ) {
4 O/ i' D8 `8 e% z! \  v5 y                mmc5.LoadState( p );
$ d' B/ e, A# {6 O1 ]% g2 N: ^                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
- N/ u# ~# Q, @9 ]5 w        }
5 ?& z2 v6 @! t$ I) N        // N106
* j4 E; f& e/ q) ^1 T3 j: e5 d        if( exsound_select & 0x10 ) {
& d& ^. N3 T! b+ J% K                n106.LoadState( p );2 \% C+ W. {$ L0 w! r8 q7 q
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding) q6 n$ p5 O* c" @
        }
3 b5 n! r! z6 `4 Q' S  n3 P        // FME78 L) G: N( E/ d+ g
        if( exsound_select & 0x20 ) {
1 o/ w" z7 H" f& u! f, J- A                fme7.LoadState( p );2 l9 d9 o" T2 K6 r
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding' g* A- f/ @+ w3 ]
        }
! j# y2 i1 U* [# c}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 ( a0 x1 F9 b  n# _: W# P8 [* u
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
5 p: |' p# H( M$ O$ o感激不尽~~

- A, C: P% [. k; D. _) x' c( H% Y$ J恩 我對模擬器不是很有研究,
" @9 c% P0 F- [( L雖然要了解源碼內容,可能不是很困難,
$ ]# ^8 l* z, c& G4 Q0 N不過還是要花時間,個人目前蠻忙碌的。4 A7 }% `+ d% B# s1 V" {) `

1 V# V, c+ Q' [7 P給你一個朋友的MSN,你可以跟他討論看看,1 s5 A/ E: A8 [; I
他本身是程式設計師,也對FC模擬器很有興趣。
( v* a2 a1 e' X( v8 }/ p+ y) ?) ?) t/ z% [" L" O9 T# v
MSN我就PM到你的信箱了。
7 k" `$ V9 P2 U4 x4 g% J
( O5 U# `8 k% m; p4 y希望你能有所得。

该用户从未签到

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

签到天数: 80 天

[LV.6]常住居民II

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

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表
  {: Y* T( G* y4 z+ J7 P  |4 R呵…… 谢过团长大人~~
8 Y1 t7 W- H' [- B+ l8 a, {

: a; K2 Y3 c" c) e, d5 c哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 3 y  |3 l- Y9 }! v& t; E/ F. s  `
团长的朋友都是神,那团长就是神的boss。

9 a' O1 L& ^( z( o! f9 J* q哈 不敢當,我只是個平凡人,$ ^. m0 H9 q& w" o& _1 b1 O2 r
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
# I  q/ L0 w# J" g2 |7 n7 _ZYH
1 Q4 c7 e! ?9 ~- c7 ]QQ:414734306, ?6 L$ H: f% k3 M0 R. w
Mail:zyh-01@126.com  M1 H0 u3 m& y( m8 A) q

& @% N) s6 x' P: D: A他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 " l* G+ U( f0 I* K2 b$ Z) n4 f; H
再次对团长大人和悠悠哥的无私帮助表示感谢~~

8 n0 f) u$ b  x( T, Y' |不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-2-19 05:58 , Processed in 1.089843 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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