EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。+ W/ G7 S" Z& g- x5 V
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~, v4 B3 L. v. z. F6 E- E" K2 z
这里有相应的模拟器源码,就当送给大侠了~~
: ?1 d. L* ]1 h' O4 H# Shttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 2 b, a, G6 k5 T
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
& Y! f- E+ u, H6 x6 d" B9 w楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
3 L: h; A, E! z/ c这里有相应的模拟器源码,就当送给大侠 ...
3 J/ t# c5 |$ R' M
聲音部分(Audoi Process Unit = APU):" n( U3 J. Z/ H4 y& T" H& T2 C
.\NES\APU.cpp, f, h* [) _" w1 j
.\NES\APU.h
$ N! L* H5 N4 Z. s( {  X7 F5 ^6 l5 M+ H( \$ j
7 A, P( x0 k* g( b
影像處理部份(Picture Processing Unit = PPU):
7 C8 D; e: _* |+ v2 [.\NES\PPU.cpp8 n/ U# \6 r0 ^: }: M8 U* e
.\NES\PPU.h  p& E3 H& D  f5 h
/ e# g: q7 h7 V- F. \
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
! C: Y+ a' w$ \  R(由于很多专用术语和算法机理都不明白,所以看不大懂……)
* g" N# n% m. Y4 P5 S//////////////////////////////////////////////////////////////////////////+ _5 {9 k* f0 p8 V9 k- ]
//                                                                      //
' l7 I- q5 N5 d' ^//      NES APU core                                                    //
+ a9 N/ Q1 \6 Y6 z$ E' Y6 E//                                                           Norix      //: D, E4 e. ]' ^9 U7 j/ s
//                                               written     2002/06/27 //
) g9 I' o' |* D1 V; w3 h//                                               last modify ----/--/-- //
; b! `$ i# }/ Z5 [//////////////////////////////////////////////////////////////////////////+ L. L8 a+ T9 v
#include "DebugOut.h"% k/ }1 q! L! g0 ^2 k, p4 O; j
#include "App.h"
- n+ b6 b, e4 c' o9 u5 h! D$ B. X#include "Config.h"
7 N. G5 @+ X/ s* _5 u6 c7 d" N, q* l: K- b% e. @
#include "nes.h"5 v% ^+ n5 {# C1 C9 q
#include "mmu.h"
# y  ~, _. K7 Y3 ~9 s; u2 `6 c#include "cpu.h"" B" r; Q" T# t5 v
#include "ppu.h"
( j! @( B2 j9 M- V' f#include "rom.h"5 k, \4 b' ^* U) d; B+ U0 ^' Z
#include "apu.h"/ h7 |/ w* N" Q2 F; u; B

* f* j9 T" s! G! K: m- U: G* O// Volume adjust5 A% E$ H1 Y. Z2 d" M) c! f0 N
// Internal sounds
$ G( c0 v0 S1 g. a. V! q$ ]#define        RECTANGLE_VOL        (0x0F0)
" Y" x) Z3 |  X8 F. t& Y' e* k#define        TRIANGLE_VOL        (0x130), ~& C. R' a: V2 s" k, O* @. K
#define        NOISE_VOL        (0x0C0)8 W2 I7 Z; V0 V, r/ N
#define        DPCM_VOL        (0x0F0)
2 {  d. i: \) K4 [// Extra sounds
. h" Y9 p  B* |0 w#define        VRC6_VOL        (0x0F0)- Z8 C5 H2 s1 c; b5 u  t# u
#define        VRC7_VOL        (0x130)  }, L. ~/ Z" C7 g7 [6 s
#define        FDS_VOL                (0x0F0)
$ B! q# }3 l4 m  x, Y#define        MMC5_VOL        (0x0F0)! D* L( }" Z/ x  F" H5 N! f' _
#define        N106_VOL        (0x088)4 T( P( x: S7 ~
#define        FME7_VOL        (0x130)- L3 o* k% |- S; H
% }/ a$ e- O/ o- ^% U
APU::APU( NES* parent )% k) I0 y0 s; f! {
{' o. m# d7 Q  c$ H, a- n
        exsound_select = 0;
: V  b! Z7 r* j. C) [% C& T1 h( k# T: l5 @' V6 {
        nes = parent;7 {! A! o& H1 l3 v
        internal.SetParent( parent );
7 n/ ~& x* t3 v- D* D4 n. a- q9 S& H: }$ w
        last_data = last_diff = 0;
. |: C5 [. w) s2 Z3 `; t. \/ ~6 b8 P. s+ \+ l$ I; M# E) u: |2 K
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );% T/ C# I" }+ q; f! q% Z9 o

/ E5 X2 ^& ~/ U* M        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
$ U" g5 f* l' s        ZEROMEMORY( &queue, sizeof(queue) );. u. P) ~9 O; u" f" Z
        ZEROMEMORY( &exqueue, sizeof(exqueue) );1 J5 y) Q# g( e9 C

# u) x8 g4 D5 Q9 @        for( INT i = 0; i < 16; i++ ) {5 b! E: p- d; n! q3 i/ k
                m_bMute = TRUE;* c+ ^# h+ y( R3 y, m  l
        }
: p- F- J% i) \3 g. G- E}) j* E' d$ b6 t* H

$ W( ]5 d! F0 P% C' I' F) G+ U5 EAPU::~APU()
; o3 T6 r: F, ]/ c+ H% z5 {1 M{
) i9 f: O6 C( q: J5 T}6 L: R+ ]; t+ h( G1 @( J' F
# ]4 T& C5 b- D
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )3 t0 h8 z+ I# y
{8 e# P" x1 ^$ e8 N  W
        queue.data[queue.wrptr].time = writetime;# d5 v8 Q" [' l5 S0 c
        queue.data[queue.wrptr].addr = addr;
* Q' |: M- H7 J2 k7 D        queue.data[queue.wrptr].data = data;) \/ s, |2 y6 x# Y2 K. B4 [; b6 S
        queue.wrptr++;+ {4 H, u/ z4 ^+ l% z. v( m8 s4 h
        queue.wrptr&=QUEUE_LENGTH-1;) f5 ^) U7 F% F7 t( E1 d; S" l3 k* X8 [
        if( queue.wrptr == queue.rdptr ) {6 Z& o1 g8 b1 n
                DEBUGOUT( "queue overflow.\n" );
$ |: _7 a0 e" e' y        }$ E& |! Q* w1 O7 T2 x' |8 d
}
' F' b4 d8 H( V+ b) z% x2 P4 |
8 A7 Q8 h! e6 x2 G6 U  B4 C4 KBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
1 X* K, [. L$ J8 y. ?' O{
0 C9 r. c$ j% B1 t, V" R6 {& q        if( queue.wrptr == queue.rdptr ) {) _* r. [2 g0 B
                return        FALSE;
  `# D4 W% C% {% u9 j        }+ K; t( _! f0 o
        if( queue.data[queue.rdptr].time <= writetime ) {
$ B& ]% ~" k* F' u* M0 \                ret = queue.data[queue.rdptr];
5 O" e  c1 [" L                queue.rdptr++;* y' Y, G- {  A$ z# y' i
                queue.rdptr&=QUEUE_LENGTH-1;2 j- ?' f, t5 o, k! V: Z
                return        TRUE;
0 O$ z4 X4 m+ f5 @* _        }# a$ V4 v0 ~' b4 M+ F7 L$ V
        return        FALSE;
8 L: [- S1 g1 G# E}) I, h9 @; u0 V4 w* a+ P1 i. t# W" B

( N) o0 q. L8 Z$ u: qvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
0 U6 `9 W0 G& M8 K5 n{
' A! [9 S8 v# A) f        exqueue.data[exqueue.wrptr].time = writetime;
$ ]0 t8 V/ P" r" }* ]        exqueue.data[exqueue.wrptr].addr = addr;" d8 i; A+ f7 H8 R) G) P$ y
        exqueue.data[exqueue.wrptr].data = data;
1 a$ o1 C& f$ [) e. I! k9 d        exqueue.wrptr++;
% n# D9 l& p; s8 p4 S5 T0 z% ?        exqueue.wrptr&=QUEUE_LENGTH-1;3 \6 X, Q4 W: w
        if( exqueue.wrptr == exqueue.rdptr ) {- f6 U' h! r- i' g1 A* D
                DEBUGOUT( "exqueue overflow.\n" );) r" P+ {# ~1 i( }" p* x
        }
9 H2 v1 G9 ]3 @7 Y6 F}# L0 l( X( E* A& V$ Y
7 O& h- r6 r1 i% B
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
) F# |3 W6 A& k* \{& v/ s% b  `7 [/ e2 l! k( R6 `7 M
        if( exqueue.wrptr == exqueue.rdptr ) {# [# a; o% P/ r0 k2 ?
                return        FALSE;  p. k0 l' @$ Q+ V
        }
3 `9 C# H/ H' G        if( exqueue.data[exqueue.rdptr].time <= writetime ) {; \" Z! N7 Y$ m" t
                ret = exqueue.data[exqueue.rdptr];
, w* k$ j4 E7 {% K7 i                exqueue.rdptr++;  ?' t4 ?2 o7 i' z  K$ L' J
                exqueue.rdptr&=QUEUE_LENGTH-1;
3 e$ W+ k; k3 _. m3 S                return        TRUE;  ]' y) L1 [/ g7 i6 a! l0 a5 V5 Q
        }
0 O8 U) ~4 }7 d        return        FALSE;
' j5 O. p5 r; j' c}% d3 G9 I! W" U6 x

# `- f( I( x, y4 M6 v* h& o) fvoid        APU::QueueClear()
& }3 Q9 O& z9 ?% T( n{! i" |' S" ^* ^# a
        ZEROMEMORY( &queue, sizeof(queue) );7 A* r  `9 B7 B  c' F4 x( o- c
        ZEROMEMORY( &exqueue, sizeof(exqueue) );7 O. A5 l  g0 Q5 m
}6 @* h2 _# d& A) h( h3 J% q

( f# i3 w- N+ _; jvoid        APU::QueueFlush()- [, Q: w* W) k3 Z
{
8 E' p7 }3 B8 w        while( queue.wrptr != queue.rdptr ) {
' z" w* O/ _( }( D1 ]( r                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
4 \0 B; G3 K- q3 U) B( A) L                queue.rdptr++;
" Y& E3 e* L8 y# g, l                queue.rdptr&=QUEUE_LENGTH-1;
8 n: h/ B# q1 {& L$ T        }
$ ~) d& O% l' o! |! D3 f* X; c/ Z4 @) J& A
        while( exqueue.wrptr != exqueue.rdptr ) {
- n( m4 A  \8 v) A: G0 l$ \2 d                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
; X6 M1 P5 X9 j! g$ ]5 W2 p' n  x                exqueue.rdptr++;4 d/ }" q# c5 j  E1 V3 I6 T
                exqueue.rdptr&=QUEUE_LENGTH-1;
# e$ \* t/ f# g0 z3 `        }
% A' ~+ x2 f7 M) ]1 g" B, q7 M}
5 f4 f5 M0 P6 C* ]( H$ d! C% Z+ d( \2 K  C4 K# W; L& D
void        APU::SoundSetup()
) ^8 d2 a: V/ T; T/ U' U; t2 U0 G{3 i& g3 t2 O: B
        FLOAT        fClock = nes->nescfg->CpuClock;
. ?, O  y$ k7 u9 ]0 s; J% U5 ]        INT        nRate = (INT)Config.sound.nRate;
. |0 L3 n0 b9 m3 |% ?$ k        internal.Setup( fClock, nRate );
9 m" B$ d2 W, E) o        vrc6.Setup( fClock, nRate );- e0 U! q. N0 n2 z% C! e
        vrc7.Setup( fClock, nRate );
' U6 f. h+ ~# U' }7 J0 }+ d        mmc5.Setup( fClock, nRate );0 j  ~" n  v! W  l
        fds.Setup ( fClock, nRate );6 _9 P% V- B8 C: b6 s$ G
        n106.Setup( fClock, nRate );2 Z' H7 S$ \+ ?+ q# Z  V- U; K
        fme7.Setup( fClock, nRate );
8 E3 P9 X; i/ D) k5 g4 L/ ?% b}
2 [9 l" n) @7 r$ b6 S+ @0 S
6 a" i# B$ d4 ]+ J6 {void        APU::Reset()
8 x/ V( m, M3 ~( R9 c  s- H; e{
8 T- H4 m, F& \. M7 }        ZEROMEMORY( &queue, sizeof(queue) );$ d- N' _8 j$ I# T. q. B
        ZEROMEMORY( &exqueue, sizeof(exqueue) );+ g7 A5 ?) `% m4 T1 W2 Y6 E' i

4 F. c) p" w, L* X        elapsed_time = 0;
0 L9 q  O, u9 h! l- T6 z- q5 w" S
        FLOAT        fClock = nes->nescfg->CpuClock;4 V3 x; A6 A2 l  x0 J' K& J
        INT        nRate = (INT)Config.sound.nRate;
3 X; R7 C- w' M3 o        internal.Reset( fClock, nRate );
9 J% n7 Q' d/ \1 B; ~        vrc6.Reset( fClock, nRate );$ N$ K! E. r4 t
        vrc7.Reset( fClock, nRate );- K4 V4 K, o+ |8 {+ w
        mmc5.Reset( fClock, nRate );
- o3 Z8 o' d+ e* x1 Z        fds.Reset ( fClock, nRate );6 x  X, M  K# b$ z' [
        n106.Reset( fClock, nRate );
1 ]. J5 X% f  f$ S        fme7.Reset( fClock, nRate );6 e* f6 s/ A  u

& i- e$ f6 B. n' R/ T: v        SoundSetup();
( C5 {, p. D8 T# {/ A- ]; @0 J" J}
1 q( Y3 `$ P3 {$ G  n2 u! R: @4 R7 W' R/ j9 h
void        APU::SelectExSound( BYTE data )
& q4 H1 m4 M$ D' g- D{
  S0 ~+ l2 d2 p$ S' z7 Q        exsound_select = data;4 W2 g$ Q. ~* @$ A! R9 _! }3 N4 {
}) B# P/ N" e6 m- _5 {& F

' k8 U( B: L- UBYTE        APU::Read( WORD addr )
1 {" H# s0 C7 i+ F, `" E4 t{4 [2 i! ~$ l: y) s
        return        internal.SyncRead( addr );8 @! u& U6 S: m$ c" q; d3 s
}
+ T( ?: ~  N3 h9 {6 q% q0 b5 b
; t/ H1 _+ a& dvoid        APU::Write( WORD addr, BYTE data )- [- R9 Z. r* }  W2 l1 e
{! v$ e0 }. ^3 o
        // $4018偼VirtuaNES屌桳億乕僩
4 w2 K/ c0 \. d% M1 {- N$ b        if( addr >= 0x4000 && addr <= 0x401F ) {
3 n6 }! X' \& N3 |/ Z: @                internal.SyncWrite( addr, data );5 E. G) L% i, i
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
  b3 r: w7 n6 z& g0 [, u# N        }
$ c% n% H) y' Q5 j}
$ `7 `) ?* D( t* r2 o
8 A0 r! h' K+ i& }3 u6 nBYTE        APU::ExRead( WORD addr )
( y; E, D7 b) F. |{
) }7 V1 U8 k& ]/ _/ W5 c+ eBYTE        data = 0;% H2 h4 v% W1 _( J

9 S: p  U$ w# n- S        if( exsound_select & 0x10 ) {
( W/ H; |( R+ n; Z" ]2 }6 L  N                if( addr == 0x4800 ) {: H4 Z" G" Z0 W. {
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
9 F* E+ d* o3 M% {                }- [0 r5 {# T, o. g" F
        }0 M; w$ B' g5 a
        if( exsound_select & 0x04 ) {3 U0 R2 S" |/ S) `/ v# H" a
                if( addr >= 0x4040 && addr < 0x4100 ) {
& ^( f: c/ m3 e9 I& ~6 y) R& W                        data = fds.SyncRead( addr );
6 ~" K" `# M2 Q  U9 R* b                }3 O6 O0 N$ N+ v" p( t8 L
        }
' m+ G8 w3 ?3 w# z8 P        if( exsound_select & 0x08 ) {
9 }- L1 \3 `: Z                if( addr >= 0x5000 && addr <= 0x5015 ) {
7 p. X% c5 e  O4 i                        data = mmc5.SyncRead( addr );
0 d4 m4 l' U5 G$ i                }/ B2 a6 w! m( ^! B1 y
        }7 ?& E+ E" T. ?  i

  _! R' S, O& |8 W- d/ }9 s  K! R        return        data;4 a/ W" U7 s7 ^. z1 G9 K
}; |" Q3 L$ L- N4 y
& Z7 ]/ D0 ]; V# P& h
void        APU::ExWrite( WORD addr, BYTE data )
2 ?1 ]7 J0 f- x7 g{
6 h# @/ N. P8 q+ [( Q. t; L        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
6 \% G* ~* ~0 }
% I- a  s  A; W1 d# I5 n( g/ j        if( exsound_select & 0x04 ) {
2 ]  G9 u: h% s                if( addr >= 0x4040 && addr < 0x4100 ) {' I4 B' I* m) I( U/ R, O( t
                        fds.SyncWrite( addr, data );
, Z: G4 V) w) B+ o4 d) [                }0 {  x: _8 S. j2 ]4 D  s
        }
' b% u* `. C* G- k" R, F: p" |' D/ T  ]4 V" G3 g7 r
        if( exsound_select & 0x08 ) {, \, s" j+ Y3 s$ g+ Y: X, |7 G
                if( addr >= 0x5000 && addr <= 0x5015 ) {3 j2 p; n5 u( F4 ^" v# k; b
                        mmc5.SyncWrite( addr, data );
4 \! k; m! I1 C& {0 b                }
4 Z1 X5 L8 P: `; f9 g: }        }# H3 o- Y9 _$ [* U% z) w4 C
}
% s2 J- V! S/ z+ h: I! w) }  T1 T7 p: B( I' l
void        APU::Sync()0 b( i  {; g5 `1 f5 `
{- u) b" O2 a* k( j5 N: ?2 U
}. w* F$ @9 Y/ I' b; F
3 y! E# [8 x- O; m
void        APU::SyncDPCM( INT cycles )
& F4 P* Z. B' a{' j; R! c  L) y" ?% |+ U# h
        internal.Sync( cycles );- O! n, v& P% Y* C/ y

( g, F6 D. s9 S3 h        if( exsound_select & 0x04 ) {4 W3 J* Q* G5 Z  x
                fds.Sync( cycles );
* g- Z% m) \* R5 o/ }4 g        }6 [* E/ h& m) }% z5 X1 q& [
        if( exsound_select & 0x08 ) {( [" ~9 @& F" X8 Y) E/ G$ C
                mmc5.Sync( cycles );6 r& A$ w- I0 ~% M, B6 z& b
        }& S3 `4 S( B8 T
}( |" I) t# r6 F. V" j3 J/ D1 e
( |% \3 F. M  ~7 N5 A7 s+ t3 g
void        APU::WriteProcess( WORD addr, BYTE data )
* e- D, v6 x! A. e+ q% d{- T9 h2 ?) R8 [/ Z7 @% b
        // $4018偼VirtuaNES屌桳億乕僩
& a/ u$ `! r! Z3 n/ u        if( addr >= 0x4000 && addr <= 0x401F ) {
7 t; J) l* B$ n0 h$ o                internal.Write( addr, data );
6 z# f$ a- C. c9 U0 f) ^2 \6 D* _        }4 `. q* Z1 U* X6 h2 k( ?4 }
}9 y/ U# C/ q1 l! Z$ p
; E2 {3 p, r: {% v1 v% ^& K2 _! Q
void        APU::WriteExProcess( WORD addr, BYTE data )
' d1 ]7 k  L. g' M, O: a& @/ I{
7 a( ~/ p- h, q" W2 ?6 J1 X% @        if( exsound_select & 0x01 ) {3 r( U  Q; a9 v' ~9 X* j5 ~
                vrc6.Write( addr, data );
# G9 r: c" b3 k7 Z& f        }
; D0 l% l5 D' r) i        if( exsound_select & 0x02 ) {" _. |- [: V+ t3 m$ J! i
                vrc7.Write( addr, data );1 ^" A! d! {) T' j4 @, S
        }
" _' ?# }6 f* J7 }! M. x+ e        if( exsound_select & 0x04 ) {6 x4 N. r3 J2 `+ X7 j
                fds.Write( addr, data );
9 ?  l. O# z# l/ R1 b+ B        }( _# ^; `: \: O. [3 k$ n1 X! V
        if( exsound_select & 0x08 ) {
. o& ^4 w" w. C  G& b+ t' p# v* O                mmc5.Write( addr, data );" n% c) L! s; N8 V+ }# X) P
        }% v) c7 X5 U6 x6 M
        if( exsound_select & 0x10 ) {: v6 P/ v) t+ y- {1 {
                if( addr == 0x0000 ) {
- G  Q% P. |2 o  s: {                        BYTE        dummy = n106.Read( addr );9 _' u# c3 G. @3 p5 {
                } else {/ g, ?, ]/ t3 H) \9 U
                        n106.Write( addr, data );
. c1 V+ V$ e" D( ]                }: m4 ^4 B2 A/ x; X& C1 s
        }6 K5 E8 [! q6 u0 ]$ C
        if( exsound_select & 0x20 ) {
1 x# t) @0 }$ i' X4 i5 T                fme7.Write( addr, data );
  R& _& J' \4 W: p        }
8 `! r; N1 H% t% W! Z! N8 C}
( @, @& F; U# ^  _, \
( ?% ~' Q' u! U  I2 gvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
1 }, Y7 r3 h5 o7 E7 z{) c9 C9 y0 q3 u; r8 _8 d. t! m
INT        nBits = Config.sound.nBits;9 [& [$ {+ e+ L. M
DWORD        dwLength = dwSize / (nBits/8);7 Q5 g. x: d; H( P
INT        output;
0 E3 V$ @& V+ |* G; f9 q! X8 s4 HQUEUEDATA q;8 Q1 L( \( A: |. ]( C
DWORD        writetime;9 u5 g" W( h9 Q) |8 f
9 p* \$ u6 |, l- @3 z
LPSHORT        pSoundBuf = m_SoundBuffer;$ x( F! j8 \. o+ g3 Z/ H. E" M
INT        nCcount = 0;) V' ~! p5 R5 F* X  b# [
. c6 u. c  @3 N
INT        nFilterType = Config.sound.nFilterType;
- T# ?" R' y+ H+ [( {* H2 Y/ N/ Q$ V. X. Z2 K$ c
        if( !Config.sound.bEnable ) {
! E5 \' N7 G/ {6 x' w: b% T                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );# F7 e3 b* \0 C, N1 g$ ?
                return;
" x; M% `5 L" }: L. w        }. \0 B2 Y5 [, K, Z, I0 c
: e. z+ i  X4 q7 O. A
        // Volume setup
3 V- u7 V( d- ^" F/ @9 C2 ^        //  0:Master) ]( p) x0 X; P  j) P  m9 |: |, F
        //  1:Rectangle 12 @( t- U1 Z* T
        //  2:Rectangle 2
$ U3 g" }+ z% ~6 K! ~$ m8 L0 \5 j        //  3:Triangle
7 q! {5 u7 n% m2 R        //  4:Noise/ J4 k, a& ^8 @
        //  5:DPCM
' O) ?* _( u0 Z! g  z  S) s2 L        //  6:VRC6
2 P# p) \# K; R) A+ T- n        //  7:VRC77 z/ g: ?+ C8 n  Y. i* H3 B. W
        //  8:FDS
, B4 `8 H5 J6 F. M5 M) [9 m- {        //  9:MMC5' K. R7 B) E, D4 I3 {8 H
        // 10:N106, m; e" o  e* S6 L% h5 n8 p1 x& N
        // 11:FME72 s2 ?6 E0 [- R3 F
        INT        vol[24];7 f/ a3 M4 X& h9 P
        BOOL*        bMute = m_bMute;2 E; R+ ^& g0 P, [
        SHORT*        nVolume = Config.sound.nVolume;* ~* D) o% A+ \/ ?; Y; ^

, Z/ L2 s6 f6 H2 {- d  V2 i8 g$ x        INT        nMasterVolume = bMute[0]?nVolume[0]:0;3 W& u# q7 g/ r1 Y% K
+ B# t$ x+ z9 W) K
        // Internal
7 M" b5 b- N, `        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;* C" C* Y$ i1 G& i+ g, w& m
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
9 a: B) k+ {; z        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
( D. `7 ~3 G/ s0 _. H        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
% L6 g; L1 [( J' |/ T1 ^        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
2 m1 x" u; Q" z$ F8 w( A
. b$ [9 [: v" L. D1 G9 B% m        // VRC6, z  P. [( @" v# q( z! F
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;; x1 W! I- C+ S, s
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
  W: w" k, J! x) U        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
5 P0 [; d% y# |& l1 A- }% y! Q2 D& `
        // VRC77 {7 Y  ?9 H3 X& ^- r
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;$ c( a2 w. F! L6 u2 n+ M

( @0 x7 N* G/ G$ Z" R: [' Q4 u        // FDS* P4 T$ L1 q; d  M) K" o, P2 U7 c6 b
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
; t2 T2 U4 k: V4 Q2 c5 K2 ]5 c  J
! J% X. y+ K# \4 u' B$ A) Y/ y. Z/ @  }, o        // MMC5# a1 N. l$ R1 V" \8 e+ [
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;1 s  F0 P( m/ e: {! R: n
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;& m* f/ Q5 r0 w% ?1 V: q% f1 d/ f
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;4 ?6 S+ d2 }+ d. K" `$ E" R
* d( ]2 H8 H: `: _- G. p, [, i7 K
        // N106/ D4 C* J3 @! W$ M# J9 p. P
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
* V' v3 ^" Y% G- k4 r" m        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 M4 ^- D. p, P  D9 a0 v0 n8 T, p
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& \4 [" }: }: p. R        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
' ~, z: \2 o$ i        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;7 C* f# ~" h5 Q* o
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- N9 `! V, K4 J" g% l
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;3 I4 \. [" A1 r% d$ R& y; J# Q5 s
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
( j: F/ L8 W0 h( w6 y$ H- \7 q) \2 x$ q* c( b" v3 ?8 V
        // FME7
; v9 X7 j) E9 T8 p        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;. ^+ W5 t* E, |5 S9 c- K3 X
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
, X$ z8 S, e: H' F! V        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
4 `0 x, y/ q9 C
" q5 ?1 s8 b& F: ]9 p; f//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
* K$ H; M) Q3 g2 S        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
7 B6 V, e: N. _6 d' D7 ^8 H* w+ V: B6 ~  j: K5 `/ C
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
2 a- `6 v2 X! K. e# c; N        if( elapsed_time > nes->cpu->GetTotalCycles() ) {; G* j% {0 t3 b5 ^4 B
                QueueFlush();
. g/ h! I3 e- [7 k1 h5 u* B; I( t        }7 ^; ]4 u. n9 A/ j* R

  C4 Y: W5 Y$ K        while( dwLength-- ) {/ j2 n  F4 y: X" N. i
                writetime = (DWORD)elapsed_time;
, {1 g7 _0 s. z& X
; X- O" X/ v* w' Y# g                while( GetQueue( writetime, q ) ) {
! L0 K5 k4 S, }5 k$ v  [+ A- R                        WriteProcess( q.addr, q.data );
; \; b9 k9 y0 g; C- ]: D9 _, N                }. X/ G  |7 i; V0 E/ J1 Q. U! r
. V* T$ M! A7 F. U' r
                while( GetExQueue( writetime, q ) ) {/ t: B0 Z1 L9 k0 F
                        WriteExProcess( q.addr, q.data );
* }! p: S2 K/ t! q3 R: B. t7 y* S                }
! G9 H& P- R3 H+ S" @7 N, M/ X! A8 k. _" d$ q! Z. d; Z
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME73 o; J4 w3 O$ `7 y
                output = 0;
1 c# t" Z3 M* u0 ~# h% @                output += internal.Process( 0 )*vol[0];
" [1 I% _) B, G: L+ R3 q                output += internal.Process( 1 )*vol[1];
' t3 a- }/ V% r                output += internal.Process( 2 )*vol[2];
9 J5 L4 [4 {, e8 x7 H6 _                output += internal.Process( 3 )*vol[3];
  z: r& E) F( h                output += internal.Process( 4 )*vol[4];
7 y% \/ }6 I) \7 ^" F+ }  \! t" F4 ]: s) I; S
                if( exsound_select & 0x01 ) {
6 z) K1 i1 ~; p, ?: j                        output += vrc6.Process( 0 )*vol[5];% [  t  H. m" G! |2 P' I2 a9 K
                        output += vrc6.Process( 1 )*vol[6];7 `1 D0 B6 _& b& d/ |8 T" l
                        output += vrc6.Process( 2 )*vol[7];9 G$ k3 l! F9 Q: o" s
                }0 s+ [) ~$ k1 i. k* `9 D4 H  m; N
                if( exsound_select & 0x02 ) {
: ^: z0 B: F" Z8 w5 u                        output += vrc7.Process( 0 )*vol[8];3 s2 w- i" f0 X7 m" J0 K  R
                }- a5 I3 {, u) M" l& Z% S! |
                if( exsound_select & 0x04 ) {
1 i+ I9 ]% H% A: }                        output += fds.Process( 0 )*vol[9];
! ^: d% _) _+ C1 ^, W                }6 `& s. S+ l7 N1 g6 q5 R# v
                if( exsound_select & 0x08 ) {* c2 F7 A+ S* F5 L4 |/ N- U' |3 |
                        output += mmc5.Process( 0 )*vol[10];/ r+ v! L: T- o1 k; Z6 d: h0 [
                        output += mmc5.Process( 1 )*vol[11];& |, X' x3 F& f7 D( P
                        output += mmc5.Process( 2 )*vol[12];
0 n9 [) m' K5 z$ h                }0 M9 J! H1 I7 J, Q9 \  X* \  T
                if( exsound_select & 0x10 ) {; c$ G1 j( y# @2 A- g- \3 f
                        output += n106.Process( 0 )*vol[13];
; g% b1 e6 W, d; [                        output += n106.Process( 1 )*vol[14];
# q: O4 k/ S$ C* W' Q. M                        output += n106.Process( 2 )*vol[15];1 a/ o; a, h4 \- W
                        output += n106.Process( 3 )*vol[16];6 t) a: F( J3 z7 l# B. V. a5 ~
                        output += n106.Process( 4 )*vol[17];
* e$ y! Z5 _/ m9 G1 |                        output += n106.Process( 5 )*vol[18];
1 {2 Z* {1 p7 D: a                        output += n106.Process( 6 )*vol[19];5 [( d, i& I. m1 X% K# p! y) w
                        output += n106.Process( 7 )*vol[20];3 s+ `7 O1 d7 T! K! F+ t
                }
  f' U0 ]3 |) U! A; P4 a7 T/ s; k                if( exsound_select & 0x20 ) {2 t; i! [3 g$ T! I
                        fme7.Process( 3 );        // Envelope & Noise; L& u  Z) N4 M- U. }
                        output += fme7.Process( 0 )*vol[21];
. u8 D5 p5 f0 i: F9 b( y; e                        output += fme7.Process( 1 )*vol[22];( T: Z# S4 \6 q' K( J5 s
                        output += fme7.Process( 2 )*vol[23];  d  l! a7 ^2 T/ p* u* _
                }
+ J5 @1 ]; t( o! b' Q: L( S
1 J9 }" k* ^/ y. n3 ^: j; m; K                output >>= 8;4 H% f( F% V$ W: z

) p3 P5 Z' V1 o* U                if( nFilterType == 1 ) {8 Q  `8 ]5 }! n3 }9 N$ N1 p
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)+ b1 R7 x+ N: [5 r4 L
                        output = (lowpass_filter[0]+output)/2;. X- I3 r3 [- v* h1 w! x* L+ T
                        lowpass_filter[0] = output;$ Y2 i6 j! k, i8 l/ d
                } else if( nFilterType == 2 ) {
* }% j5 [0 L! z8 B& N# t/ i8 f                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)& L% c7 w& l; U/ l5 v
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;% r  G* a$ ~! H- y
                        lowpass_filter[1] = lowpass_filter[0];
* m5 j0 r: M& ~) m3 K3 y" p                        lowpass_filter[0] = output;
! L. Z& d. r3 I: y3 a                } else if( nFilterType == 3 ) {3 i6 t3 M, ~& Y; h
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2); |( h2 K) q$ M1 g- ^
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;, _: j) S& I% [3 i9 J5 s0 z' [
                        lowpass_filter[2] = lowpass_filter[1];8 L  @/ {/ N" G! }/ `
                        lowpass_filter[1] = lowpass_filter[0];5 u5 _8 j* z- a- X# A% ]
                        lowpass_filter[0] = output;
9 }) C% |. o' I                } else if( nFilterType == 4 ) {
* M6 Z1 G, ^2 T" [  t) U                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)$ }9 k' _' `3 f
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
6 z3 ?& w+ ?% s/ {8 c: W4 ~8 S9 Z                        lowpass_filter[1] = lowpass_filter[0];: a8 {1 `0 a, A! @
                        lowpass_filter[0] = output;
: N4 p8 O% z- _% ]  u! _- Z                }
2 f; N5 r) w8 R: [) r9 g- [* k# V. y- Q5 Z, U- b7 s0 h
#if        0
- h' t5 h( n' {  y+ @5 E                // DC惉暘偺僇僢僩
/ z% V3 `/ {: T( u! e6 e; o3 z0 k9 L) u0 k" ^                {2 w* z7 o' b6 w, M. G, R
                static double ave = 0.0, max=0.0, min=0.0;
1 J- X' |/ z% r9 W3 a9 V: h                double delta;/ f/ z% |( a- \0 P, U2 z
                delta = (max-min)/32768.0;
6 u8 {' I! j6 Z  K! x                max -= delta;
5 q7 B5 w* k! C4 a) Q( I; W" ^                min += delta;
% U1 T% f; r" {% l. ]                if( output > max ) max = output;
# l9 O6 w9 x" V! o' j6 ]. Y                if( output < min ) min = output;
4 w/ K' s; k: r% g                ave -= ave/1024.0;+ b' Y7 K! Q: Z! S7 C  Z
                ave += (max+min)/2048.0;
- V. n' K5 ?6 u  E! i% M1 h# o9 ?                output -= (INT)ave;
7 e3 d6 [& `' I# G                }
" Z8 q4 m" H0 I3 L' S" ^0 R#endif
* N5 t7 O8 r/ a! F8 |( B0 ?' a#if        1
: W. _5 w2 \0 s6 v                // DC惉暘偺僇僢僩(HPF TEST)
  M* `% C# o* M" P                {
% N! j# l; p) W1 K( E//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
; N+ F  J( V9 t* r; Q                static        double        cutofftemp = (2.0*3.141592653579*40.0);4 c  y9 k* r1 ~0 q9 r9 L
                double        cutoff = cutofftemp/(double)Config.sound.nRate;) G1 N) H& M, o; t& I- G
                static        double        tmp = 0.0;
1 R# E3 e8 T* V9 L; b" Y                double        in, out;
; n. g$ Y* }& T8 P' S" x; a1 \0 Q" ~! y- P! r2 ^
                in = (double)output;
/ ?- {) S* k2 J( s1 b                out = (in - tmp);! _# M7 C+ `7 y0 Y# l, G: v8 i3 X
                tmp = tmp + cutoff * out;' |  w' c# b8 ?8 l

9 v9 ?: j7 ?" ?                output = (INT)out;
; r+ U, j3 H- N5 Y7 n- s, b* x& Y                }
! x3 g- ~9 u5 D% W; q2 o% ]2 q#endif
4 ], r. k" w- u#if        02 z$ h  o; ~. n$ J7 u# m
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)* C) ]' @" K  e& g
                {. ?( [6 }8 H' W0 K$ u4 Z
                INT        diff = abs(output-last_data);
8 M. A5 o5 r- M) g8 b4 ^                if( diff > 0x4000 ) {; f9 d8 U% D( s3 \7 I$ O1 M
                        output /= 4;6 |! [  R$ d% W, [5 ^
                } else
( H0 C" C6 U; m8 P) ^/ Y9 |9 z                if( diff > 0x3000 ) {
2 b: U. L) j( s" y5 c) R: |                        output /= 3;+ g3 Y$ s% p* Q% _! L
                } else
- d9 W5 c: B9 v8 W3 x                if( diff > 0x2000 ) {. ?, v$ o* ^6 S# h6 w0 b7 M$ @
                        output /= 2;; C8 \7 W6 O, c, E6 g5 y8 o9 \
                }
+ k2 f' O* l  ?" c0 d9 a+ ~                last_data = output;
& F$ U7 l/ X7 ~9 X2 R) O                }
$ a! K1 u( v( m5 n#endif* `/ ?1 `$ Z; W6 L
                // Limit
2 \, S) N  I; H" k! ~+ C                if( output > 0x7FFF ) {
/ s( z' f. L9 b! b: d0 ]* I                        output = 0x7FFF;
" ~- S1 B7 d/ E1 S# D0 x                } else if( output < -0x8000 ) {1 N- b8 |$ y* \( K
                        output = -0x8000;6 i7 [4 z" j8 a9 O
                }
2 Z' o( O4 m6 P% k
* N# z, M) v; N% D                if( nBits != 8 ) {; l1 ^- ^5 [/ B
                        *(SHORT*)lpBuffer = (SHORT)output;7 N/ x* z7 X; ~* s0 H( ~
                        lpBuffer += sizeof(SHORT);
0 ?* ^( l$ L: U. l# E8 P' I                } else {+ R- t6 ?5 @4 h" P$ }* _. \& c$ s
                        *lpBuffer++ = (output>>8)^0x80;
% O- d7 g# G' {7 k                }, m, Q3 K* ?$ x3 G5 O$ A
* T% W" w: f2 a
                if( nCcount < 0x0100 )" r& C2 C% A5 N4 X
                        pSoundBuf[nCcount++] = (SHORT)output;9 U1 l$ I  J! f' @) l% ?6 R
8 s" Z' W* p* }8 _" b1 |6 C2 P
//                elapsedtime += cycle_rate;( g2 p3 g, x) K3 `6 i
                elapsed_time += cycle_rate;
! i* `% n- \4 y% Q# d        }8 O9 R& T" i. M8 z( \

6 l: G1 a/ f# G3 f#if        1. b# W7 s$ d7 ?% {
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {9 ?. O. `! c9 W- I" L. g) i9 L# S) V
                elapsed_time = nes->cpu->GetTotalCycles();
* g) a* m. q* M8 D8 V  }  }        }6 X1 u7 }- F) d/ t
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {/ [# m' O* @9 {
                elapsed_time = nes->cpu->GetTotalCycles();
" k  [0 i4 W9 [; M0 k        }
, N3 i: I, d. X3 {4 D# f. _#else; T7 u  V9 e5 B. Y% X. f5 i
        elapsed_time = nes->cpu->GetTotalCycles();0 O5 A. \/ e9 Q" c7 ^
#endif
* _2 `6 o5 g( @* q/ C; O7 x1 _}
. s5 A9 A3 Y) u( g7 l9 E
" {* Y9 p3 R" ?: d" V* |" D8 y3 J+ X% P// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)9 \9 r* o# u+ ]6 L7 T" W8 a
INT        APU::GetChannelFrequency( INT no )( w: d* q5 h/ U
{8 b/ t" Z3 L% k- w1 q1 B7 G
        if( !m_bMute[0] )- z+ U; g) F; u/ \
                return        0;0 Z! z1 G0 `+ q
" j; P' ]* |; x- R0 d9 g
        // Internal
8 e7 v3 O; l$ o7 X% `        if( no < 5 ) {
. }  z% a5 c) q. m" ]                return        m_bMute[no+1]?internal.GetFreq( no ):0;
6 F) ^2 N3 p" N- J* K        }
; L; r, y7 l3 B: i8 T3 K        // VRC6% o  q% ?8 m+ v$ e0 s5 W% E( w6 \
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
% P' o) m  i6 ?" O                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
/ [) n" W: {! b$ m4 m        }
. w, E9 o; ~# E# _& h        // FDS& d0 [$ P+ m. E& U& r5 x
        if( (exsound_select & 0x04) && no == 0x300 ) {7 t, Z5 I- T3 C( p3 ^- t
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
4 f# C4 p7 v3 N/ ?        }
, k" F' L+ \7 A1 c0 d& ~  x        // MMC58 W. C( C" q+ r6 I- {
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
( L# ~' I/ d3 E7 F                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
1 c& W* f  D4 V( u& K, m        }
, u& x% d3 w% W/ w3 m        // N106: {, |2 }4 [4 K# Z' s
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {; r# C; Y" w8 t& X) t# H( k
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;: [) n/ S/ ^3 _, S. M8 C
        }
/ t$ g% v' i. s: W) T% [6 O        // FME7
; H; Y  _! ~0 U; x7 K5 [' y" D4 W        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
6 f; v8 w! P( q/ F+ O/ U0 X& `0 V                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;( U, }( \' d5 y+ H4 u' [- [
        }
& T( B' o4 U3 W- v; t" {        // VRC7
' T  ^# Y" r- r# p0 E% q7 i        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {( e! z) k, P$ [1 w
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;' A1 a" ~$ P1 w  \7 ^- ]% f
        }/ W2 B8 g0 D) x0 r* @$ h9 {# T' f
        return        0;6 L: I2 Q0 d" ~' V" J
}
4 x$ H, ]: x( m; v' z, `/ U! ]0 b8 R0 K8 y
// State Save/Load
. R4 H- F/ _* X+ I' V4 |- evoid        APU::SaveState( LPBYTE p ): _+ x5 H4 a* a5 N. i; H
{
/ w# v( \5 W! |- r* s#ifdef        _DEBUG
' e0 g/ G3 W" q1 ^; J# {/ B( eLPBYTE        pold = p;& P8 {& D, z. x# G7 b7 E
#endif2 ]& R, `) b) J  h
9 g) v0 ?  f. h# ]1 d
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
6 c  y) z2 B( r4 R; J. ~        QueueFlush();: m0 y2 {5 A, ~; B/ s4 v1 b

' a: O4 N: f* J; l0 P3 @        internal.SaveState( p );1 Z; @) r/ H- A5 T5 I* f
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
$ G" _/ K% p4 i0 K8 Y3 A# A2 Z5 M- {& U
        // VRC6
: b8 C# f8 ^" l& Y/ I- W        if( exsound_select & 0x01 ) {
9 |! ~6 q# o* I% {0 a! X                vrc6.SaveState( p );, I. C! I2 ^$ j% C8 S, a
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding" {0 [- b- q3 J, T/ u  @
        }
7 M; u9 K9 b* S8 D* N3 H& o; s        // VRC7 (not support)9 q( R8 D0 T7 Y0 W$ L7 l
        if( exsound_select & 0x02 ) {
4 Z8 l# C# P  @* H/ f                vrc7.SaveState( p );
; X& f5 r$ O4 o& o) U! a3 c                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
& `$ N* E/ A* U' l6 u/ d0 p        }2 k3 ~& F! W' u; t2 v
        // FDS
& |6 y5 X* R. X) ~" e        if( exsound_select & 0x04 ) {
! j3 L8 i6 T7 b9 t# U                fds.SaveState( p );
$ r- a  H7 ]0 D# b' W8 n" N: w' A                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding3 g0 Q5 }0 r( j6 H) Z! ^; j2 _4 l
        }3 H1 [' P6 Y6 K5 ^# O+ C% }* S3 c
        // MMC5
  T* ]  n0 }# v5 N$ w, E$ P        if( exsound_select & 0x08 ) {
- [; i% n9 s& }: B+ F$ w& P# y                mmc5.SaveState( p );5 x; M4 a) S. i: h! T) @0 n1 |
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding: _$ w# V- g: g% R
        }
' ^, n- ~+ O8 n8 U        // N1060 n$ F2 P: r1 r2 |  `
        if( exsound_select & 0x10 ) {( i& X- e+ J' N5 ~; I8 B
                n106.SaveState( p );
$ B4 \" N5 h' T9 C& I                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
. q/ C+ S! J6 m6 Q9 q        }
; M9 K* G# a: V( y        // FME7: K1 u2 R( U; Y7 b+ ]$ b  c& j" |
        if( exsound_select & 0x20 ) {
: j. A" S9 |% v  M                fme7.SaveState( p );
7 L# g" Z$ i6 U9 z                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding1 p5 e3 F- B, i: V3 Y6 r0 ?
        }0 _1 {- @2 L) D% l" B* f

7 g8 l3 V) j0 K5 l- A* T0 K; V#ifdef        _DEBUG
+ A" n6 V9 w0 z! R  `* ODEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );6 j: y+ n' K- v) l# y
#endif
0 i% ~* Z7 `/ ^% g' S1 O8 t& Z+ w}
3 K3 Y1 u1 m: l! W5 {/ W. X1 F, h4 E
void        APU::LoadState( LPBYTE p )
* ~- ?- S; `: l- T3 i{
# v5 {! s3 L8 L1 @; K7 J- U        // 帪娫幉傪摨婜偝偣傞堊偵徚偡7 O6 |2 |- z1 n! T( Z4 R. l/ g) I
        QueueClear();% N% m* v6 _7 Z' h4 d& `! z! H
) R8 K' l& s. j- N
        internal.LoadState( p );
* S: V" J7 ?, h/ a        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
+ g& G) k/ {! U" R
# j3 G: D0 j) y: l) M, u, M$ O  B, y* Z        // VRC6
, n$ U% [8 L9 i3 c' B        if( exsound_select & 0x01 ) {$ ?( R9 y. X- U
                vrc6.LoadState( p );3 d% N0 ^) X' ^+ N& ~" u2 [# t
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
% M# J  O; q% `- r! `4 o0 O) H        }2 Y, v0 G- W, y% l& x# S- w
        // VRC7 (not support)
% v4 J! i0 k/ J& @& g1 J; U        if( exsound_select & 0x02 ) {
+ x4 B+ M: p# u0 r0 a0 A, R& _                vrc7.LoadState( p );
% e2 c( N2 |) q$ U                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding6 [0 a/ M  M1 W: \; D
        }
9 t4 v+ V% U4 w7 ]$ c        // FDS
& z" r+ E; k2 A, O- z5 m; u        if( exsound_select & 0x04 ) {, [6 p2 y! t; y% c' N# ]' x( F0 m
                fds.LoadState( p );
1 h- k4 z* T' q6 n# g5 t2 P; T5 d5 U                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
: p' W* v( a- M5 t        }  l4 ?' a0 Q4 Y5 R
        // MMC5- O6 v1 u3 b! W6 E
        if( exsound_select & 0x08 ) {
" c9 c2 `, X* n* a- q0 q, H6 v" e3 q& ^                mmc5.LoadState( p );, p5 h! u# d3 g$ O+ ~
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
6 }2 K5 L$ H/ ^6 K        }! g. C7 q7 B3 U' ]; R/ u* C, P
        // N106! L1 H/ }: w! ^
        if( exsound_select & 0x10 ) {
2 W, a! o2 W2 v& Z% s0 Z+ Y                n106.LoadState( p );% s+ w: j7 C' n; h# S
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding" o. L0 _$ K! U5 U# `
        }
8 h4 |$ T* c& {5 \# z4 V        // FME7
& `/ q/ |# T* R, p$ a9 e) z; j        if( exsound_select & 0x20 ) {/ J2 {# ^0 U, B$ o
                fme7.LoadState( p );
: R1 S& A% Z) {) p: m                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
# o, m% B7 t# k6 w6 G6 f# i- d9 }! i        }! e  ]4 ^7 D. u( k0 l, Q
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
3 K% m) j  ?4 [可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。0 t4 F" ~& l1 f& Z( L$ z4 `5 V
感激不尽~~

: o8 L; A3 @" l% u) C0 m9 i2 Y恩 我對模擬器不是很有研究,
1 x5 _3 Z0 ^3 `0 G5 ]! f) q4 U雖然要了解源碼內容,可能不是很困難,8 u/ ?' z3 ]4 C! [
不過還是要花時間,個人目前蠻忙碌的。; l6 h/ y3 ~4 S* v- z3 i

- ]* G% L$ g1 x6 E9 ^給你一個朋友的MSN,你可以跟他討論看看,
' L; h2 _; n) d/ n他本身是程式設計師,也對FC模擬器很有興趣。
5 k- B) Z: r/ J7 J$ l, p" P3 ?0 Q- C6 y, S
MSN我就PM到你的信箱了。) S. l2 r6 q+ E( ?9 y. O& e

4 N4 u5 e  t) l4 ^( p) d希望你能有所得。

该用户从未签到

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

签到天数: 80 天

[LV.6]常住居民II

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

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表
7 S+ h" ]$ l  i呵…… 谢过团长大人~~
3 t/ M& h8 G( a0 Q  K
$ }6 t- [; h4 J: V& X6 H( l% l1 a
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 9 P" A1 [6 u+ a- ]$ t  G) s
团长的朋友都是神,那团长就是神的boss。

! J$ Z/ j: F( D* w( X9 E0 c哈 不敢當,我只是個平凡人,8 {4 l$ A( d8 b* Z3 O
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
6 z, k' x/ {: f5 I( }4 ~0 g' ~ZYH: p# z3 J/ H6 ^- d
QQ:414734306, ]' J4 Z1 J' v( Z
Mail:zyh-01@126.com2 A- S" Z9 `2 i# c
( m- y1 M/ i4 `7 S" O  E# N) ?. c
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
/ x& G" @/ |& [3 o. y6 y再次对团长大人和悠悠哥的无私帮助表示感谢~~

% P: ]8 s, P# d1 {8 [! U0 Q5 e" M# ~# Z' U不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-4 21:46 , Processed in 1.098633 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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