EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?7 g( C! D( r1 t1 _4 R0 d; d
PS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。; r' X& c# w# U: _
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~& R+ v+ {' ^1 G1 c4 ^) Y9 c
这里有相应的模拟器源码,就当送给大侠了~~
" h7 ~3 {0 u1 y' whttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 / g5 d( L4 R/ @7 |9 ?0 f
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。6 w1 S3 ~( l0 A4 S0 S. D2 X
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
* G5 t) Z8 U) D" x; [这里有相应的模拟器源码,就当送给大侠 ...

+ r/ p0 R* P0 h" N4 @' _- C聲音部分(Audoi Process Unit = APU):6 T' [3 E9 i) ]& v' B
.\NES\APU.cpp3 n; V# x3 T' ]$ r7 R1 }" E
.\NES\APU.h# I# u) N) G  I
9 q; c0 O* l5 x, x9 V5 e* v

/ O" O: ?" ~% a; M2 o2 _& F影像處理部份(Picture Processing Unit = PPU):
# Q; k" z2 D* E.\NES\PPU.cpp
9 ^8 P/ V4 y6 B$ @.\NES\PPU.h
' s, V7 M+ Z3 Y) x/ [. a% {* X# |4 f0 V2 X
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:. F6 c5 Z7 B" r' D8 o9 x
(由于很多专用术语和算法机理都不明白,所以看不大懂……)5 u) b$ g5 y. ~7 D( i  Q) A
//////////////////////////////////////////////////////////////////////////6 [6 c7 z& z: _, |: x1 N
//                                                                      //
" m& V  f" s% ]# v- _- k) Y% x" V//      NES APU core                                                    //# a- a% _$ S1 q' R) T& A# Z, Q
//                                                           Norix      //
3 }3 l+ Y/ `" x  R5 A! }2 |. A/ }; j//                                               written     2002/06/27 //1 Y$ H  P6 l* g+ n; T; g, [
//                                               last modify ----/--/-- //
1 p9 n$ X& ^8 ]. ?//////////////////////////////////////////////////////////////////////////
$ @$ e0 f/ T5 L0 t6 U#include "DebugOut.h"
5 i) l1 A" ^3 q; W0 V$ q#include "App.h"
1 \9 I/ u4 b7 d( k: _( }% h; B5 K#include "Config.h"
0 g. g. g7 [: h, {0 n+ ]1 H' i$ H8 F7 ^2 E# i9 ?; b
#include "nes.h"$ O+ o. r  O3 U2 z( o- Q
#include "mmu.h"$ J) k. @: _) ]
#include "cpu.h": p# f% G7 |$ M* w- s4 F5 Z6 q
#include "ppu.h"
+ w9 ^- j8 O3 g, J) ^  v7 Y2 m#include "rom.h"1 h  K  B, A. Q" g# W$ q0 X0 w# Q
#include "apu.h"( D( _- w7 e! @: w2 ^

* N7 e9 G  F, a- z0 @4 I// Volume adjust) M  L1 M/ e4 W/ C. z
// Internal sounds
0 }9 Y' S2 {9 F* a( y# j3 d#define        RECTANGLE_VOL        (0x0F0): d( C5 `8 U, e5 t4 O+ k+ C
#define        TRIANGLE_VOL        (0x130)
- y/ E! `7 i' ^; @# X#define        NOISE_VOL        (0x0C0)/ A, T( X, @1 T' j1 h
#define        DPCM_VOL        (0x0F0), b& }1 i4 h7 y. d  X  p
// Extra sounds
) I0 q# b5 ]+ v8 B3 F8 \  L#define        VRC6_VOL        (0x0F0)
' P' B8 u: ]4 O  X#define        VRC7_VOL        (0x130)
0 B( m9 O! p/ ^+ z#define        FDS_VOL                (0x0F0)
: v  }: f, G! y4 C4 y#define        MMC5_VOL        (0x0F0)- [; w6 O" p" Q9 k: r; z  A
#define        N106_VOL        (0x088)
* K2 w# v5 [  K: {  e2 f#define        FME7_VOL        (0x130)
) w! |) l( L6 l" z% O* E
  W8 G7 O1 z4 P/ a. XAPU::APU( NES* parent )  T' y1 s: D8 H  f
{
' _9 ^5 b8 L% c8 n  a+ b* }        exsound_select = 0;- A7 m0 G' E- q& n5 l) r

1 z: o) g$ s6 {" c        nes = parent;
4 V3 W7 u8 {$ \! O# N0 |  p8 n0 ]        internal.SetParent( parent );" y+ ~. T* t* U3 T( U0 e2 @
, ~  \1 ~7 _6 y/ J. M
        last_data = last_diff = 0;! w$ H9 u" ?6 v
) `9 u3 s. D. Z8 [  D! E* {
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
, N; }/ o' o  E0 y) R6 D2 U0 \" W+ ]0 m
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
% s7 J" m& E- ~        ZEROMEMORY( &queue, sizeof(queue) );
( a0 a8 i% n* @9 E        ZEROMEMORY( &exqueue, sizeof(exqueue) );
+ r3 g# [) a4 Z' J! B- P8 z9 }0 n( d5 x7 j- t
        for( INT i = 0; i < 16; i++ ) {. B- g1 G/ |% F+ t
                m_bMute = TRUE;
6 C, n( h: a; D0 u* F        }- n* T; R- a* ~; K4 k( d
}
0 d9 O4 R6 S6 X) y9 g) H7 [$ Z$ l9 b9 t4 u: e0 @* x9 Y  d: B. o
APU::~APU()' F( ~3 f  r% ]% I
{% d- Y  u4 T& G/ q
}
: `* K9 B+ `* _8 X* g. f& c# W9 A
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
: c4 D+ }3 \+ [, b{' E! R" m3 e+ ?
        queue.data[queue.wrptr].time = writetime;
, F& E/ F5 ^7 F        queue.data[queue.wrptr].addr = addr;6 M# r1 y/ d. _, y# X
        queue.data[queue.wrptr].data = data;
* g' P, [' b$ D) |, _& d3 f3 ?        queue.wrptr++;
' s! l- j2 x% W7 K        queue.wrptr&=QUEUE_LENGTH-1;( p3 I; U+ ?$ }* ?
        if( queue.wrptr == queue.rdptr ) {- k* U) `+ M& h7 I( b
                DEBUGOUT( "queue overflow.\n" );) `" R2 s7 o0 ^- W" c
        }
% q9 i" e  w- G. [}
; v( [2 I% y) c; w/ E% H, T
. H: c7 L; a$ C$ v7 }1 H# M2 aBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )6 I9 X" B6 V* m5 Q: d# V
{  K; N% G1 @. {; |
        if( queue.wrptr == queue.rdptr ) {
9 Q2 m; ]$ M! G! Y! Q                return        FALSE;
  z% L0 Q/ U8 [: i        }
: ], F% V" U% K) U/ L        if( queue.data[queue.rdptr].time <= writetime ) {
, F; ?& M+ f9 W8 V) z' W                ret = queue.data[queue.rdptr];
2 X* Q4 d* m' n6 T' v                queue.rdptr++;
+ q+ o& i- P$ Z' }) @8 m5 \" p                queue.rdptr&=QUEUE_LENGTH-1;
; T4 O- ?4 h3 Y+ q2 r, A& `                return        TRUE;
2 S% ~! Y) u# j; Q        }
0 h6 r+ m* {) S6 a        return        FALSE;" y: }, N/ q6 l
}. |7 d# D9 g: }; r5 S/ v

' T+ N% p* v2 ^; o" j% {! B9 G6 g- ^void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
# l5 ^( \! H9 s; q{
& \6 m, r- z: q( m+ L# m4 h        exqueue.data[exqueue.wrptr].time = writetime;9 B; [! P: u" h; y
        exqueue.data[exqueue.wrptr].addr = addr;" \; ]8 }: r1 @1 Y7 C# M
        exqueue.data[exqueue.wrptr].data = data;" v# n# T/ F$ F5 o3 n
        exqueue.wrptr++;
& h4 q0 l8 L+ N: |        exqueue.wrptr&=QUEUE_LENGTH-1;
) M2 ^/ ~7 Z2 R4 _5 L3 B        if( exqueue.wrptr == exqueue.rdptr ) {3 o9 f& B" L# T8 M
                DEBUGOUT( "exqueue overflow.\n" );; {/ U- {0 y  L7 O% f7 C& [3 E1 y: v
        }
" a( A6 o6 a% R( q+ R0 G( U}
' m* l7 C. N" v5 F* L" M% H- T! w8 |" b( f# p
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
( j8 q$ O5 {7 `* M8 q& L{# o- L( U: W) J  G( m' `
        if( exqueue.wrptr == exqueue.rdptr ) {& r* E/ x+ D6 \
                return        FALSE;) c- }$ u  {# f/ v, }
        }6 k/ ~( S  V" e; e8 m
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {( h6 y* k  i! J: {
                ret = exqueue.data[exqueue.rdptr];
1 M( V2 t) G7 ]! r6 Z4 |                exqueue.rdptr++;0 w4 V6 W9 P" n: R% q
                exqueue.rdptr&=QUEUE_LENGTH-1;
+ [" D/ K! T- _0 Z- [8 A3 K                return        TRUE;
/ K) F7 S3 O( t7 ]$ g        }" I* k2 h4 }8 s
        return        FALSE;
6 h2 V* T+ M+ M4 Y}
- C2 V3 u1 \' H# @) p& d- ?; j
! w5 W% r9 L4 W3 t" zvoid        APU::QueueClear()# o$ Y& N' O' f9 i) m
{
5 R1 w6 ~9 q  U. s" k        ZEROMEMORY( &queue, sizeof(queue) );+ e  l- w/ R6 J; {/ A# h! u- x( z9 [
        ZEROMEMORY( &exqueue, sizeof(exqueue) );+ y9 T+ }8 D/ M3 S
}
2 E; @1 V6 ?3 y7 J9 P% n4 R7 g* H- r/ L; ]
void        APU::QueueFlush()
- y  s. A# }$ L0 S  p/ H1 n) x{  {5 T0 y% l, I* ?( l  T) H
        while( queue.wrptr != queue.rdptr ) {" ~) ^; F. {# I' ]* i5 q5 P
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );6 a0 o7 B- J: X1 }$ v
                queue.rdptr++;. v9 K' _! N0 |( @3 F
                queue.rdptr&=QUEUE_LENGTH-1;$ }* ?* ]) F; J
        }
1 }  ]( a* H3 B4 ~0 Q. L$ K- z/ A
; i. J( z* ^+ [6 x        while( exqueue.wrptr != exqueue.rdptr ) {6 x. N( a# n1 R5 ?  ]
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
# w/ p' U7 \! d/ k  q! s                exqueue.rdptr++;7 l* B0 u; D. @7 c
                exqueue.rdptr&=QUEUE_LENGTH-1;9 j9 q/ r3 }! y) i
        }" M* L$ V0 J& D: Z  E, ?5 t
}! C3 D0 L, O2 X3 s8 M6 U6 }

7 _6 K- n& d& @+ i8 }% ~( l* Bvoid        APU::SoundSetup()! u9 u& D1 x% z4 N5 [. t1 Q
{
+ E0 B$ a; w8 Z1 {+ Y        FLOAT        fClock = nes->nescfg->CpuClock;! E$ c/ E# ?/ A/ j0 R; ~
        INT        nRate = (INT)Config.sound.nRate;
- F3 Q& x4 [3 L( {$ k  ?# s        internal.Setup( fClock, nRate );
6 h: {1 O# [4 R  E+ D0 N4 H        vrc6.Setup( fClock, nRate );- y3 L2 I  ?8 \5 E
        vrc7.Setup( fClock, nRate );
* x6 u' B% k5 c1 a% V: _9 Q        mmc5.Setup( fClock, nRate );# H# ~7 R, C, c3 x) P( w
        fds.Setup ( fClock, nRate );
7 a; X% S0 B5 D9 S2 K3 ]+ w        n106.Setup( fClock, nRate );
0 M9 a, h" q5 K7 S+ m2 t# E" e5 m- ?        fme7.Setup( fClock, nRate );" N' K" ?& `+ [$ l
}9 Y0 M  a: h# P! R. w' Q2 H- `
) r7 D1 Z: J: S  x8 e6 K4 @
void        APU::Reset()
6 [1 {9 w/ ?2 V& Q4 x" r: P2 x{" \! o; F) \- k
        ZEROMEMORY( &queue, sizeof(queue) );
) }1 }  D# W7 R& h0 C5 c. {8 d* _        ZEROMEMORY( &exqueue, sizeof(exqueue) );6 N* S$ q: D: f% s, T- C& W6 q8 V9 s

% Z1 k7 w7 N: T, l$ V6 e/ Q" k+ B        elapsed_time = 0;" s$ T9 j( ?1 \9 S

5 W" o4 A6 p: u3 j1 @( |        FLOAT        fClock = nes->nescfg->CpuClock;) {, P+ d6 @: n# e1 u
        INT        nRate = (INT)Config.sound.nRate;
$ S( G  G* o, P/ W        internal.Reset( fClock, nRate );
3 S, s$ K8 v7 E        vrc6.Reset( fClock, nRate );* e7 I' W. n6 N9 B3 o' U' Y" V. p
        vrc7.Reset( fClock, nRate );
  E3 J* Z) o& Q        mmc5.Reset( fClock, nRate );" k# Z2 h. O. j
        fds.Reset ( fClock, nRate );8 o1 u7 @. |& B: m
        n106.Reset( fClock, nRate );9 T0 w! w7 k% a  d; R
        fme7.Reset( fClock, nRate );
- V/ h$ [7 r3 R# s; ?
% i8 R  b) t9 j2 }* Q+ ^# L        SoundSetup();
5 w  a% m, O; t. V% v}
1 }3 J3 n! \9 ^5 W; Q3 e7 Q8 Z7 C8 Q% j- [2 a
void        APU::SelectExSound( BYTE data )
" F9 V3 e+ M9 S1 Z{
& ]5 T; o3 a. h        exsound_select = data;4 n& W0 m/ i2 s! r& I2 a
}3 b5 d; _  U5 f( R1 M

# i# |1 Q. t4 M# i2 YBYTE        APU::Read( WORD addr )1 c5 O( l+ n* A5 {
{
5 F2 J! P$ j) J: S$ V/ q! U- I  f        return        internal.SyncRead( addr );
! K. d+ C. e7 n8 \}6 S, Y( a/ e! m. }* s# l6 |
% w. B( p, e* o5 d' t& k* Q- E  J
void        APU::Write( WORD addr, BYTE data )
* N" A' p3 R8 L: F8 Y8 {! y9 A{/ l0 R( v$ a0 S3 a
        // $4018偼VirtuaNES屌桳億乕僩6 B. U  i) \, [7 {& _
        if( addr >= 0x4000 && addr <= 0x401F ) {: ^* z( B( u2 T2 [# R; m- z
                internal.SyncWrite( addr, data );; D- D. k" w/ J$ W9 |0 y$ |6 z
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );; x: w* ?5 B9 j; {/ S4 u6 g* q) O
        }% w, v+ D7 e1 h/ y+ v3 j
}
  Q1 U# ~1 v) H# V9 F1 V( W$ f, @2 A3 C% P3 S5 ^/ I
BYTE        APU::ExRead( WORD addr )4 ]. L; e- Z8 p8 Y# }
{9 {2 b5 A. N8 q
BYTE        data = 0;- a# H9 y/ P4 _" f; T: J

7 c: s8 ?  z& P5 v0 q+ ?9 \9 G        if( exsound_select & 0x10 ) {
8 h) q( v$ i: h  [; S' G% s                if( addr == 0x4800 ) {! g7 s4 N. t( t/ ^- M
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );, M1 ^# s: K: ~
                }
% K1 [9 ~' r$ Y        }
6 \( l5 G; M5 {" ~1 M" f* B        if( exsound_select & 0x04 ) {) {! V7 m7 L) Z9 o9 s  i; H
                if( addr >= 0x4040 && addr < 0x4100 ) {( ~+ V0 c6 ^; w! M# p6 \
                        data = fds.SyncRead( addr );: R- T$ ~0 D2 |  n
                }
4 m* Q3 Z' H: G. Q' K6 \        }; w1 @5 K9 C9 t& L) U
        if( exsound_select & 0x08 ) {! w' w9 X) l$ P% [7 `  ?5 p
                if( addr >= 0x5000 && addr <= 0x5015 ) {
. p% G6 [/ z) o8 k  g                        data = mmc5.SyncRead( addr );
5 v& z2 k- Y' I3 Y2 ^+ J! h                }2 N# i- l/ P. S$ K5 v' C" r8 N
        }0 L- l- z+ A; q2 p7 r) p$ X8 O7 b
2 `5 g' b  S7 f  o
        return        data;
, p, d9 g; G5 Z}
0 T% M$ z- Z/ {% j
$ F3 Q! Z8 r3 _( W5 Qvoid        APU::ExWrite( WORD addr, BYTE data )
  T$ B/ U/ n$ u: g5 ?2 Z{: W. A8 C" e6 H1 a/ Y1 i
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );- a" }% w! [2 J9 B6 M+ B

: d6 i  n+ T5 X; U9 Z( A        if( exsound_select & 0x04 ) {
5 p; {& @" q; F6 {* T) s. `                if( addr >= 0x4040 && addr < 0x4100 ) {
$ `: d5 ?4 d" _' }4 L$ }                        fds.SyncWrite( addr, data );
! x' f( ~6 C. w; w$ }8 V. O                }5 f( `# c/ k! e0 p
        }. C  `# E! Z7 z, g8 K/ w! w- J- @* I
3 w0 N: U4 Y2 G6 q
        if( exsound_select & 0x08 ) {
7 u- H! B" {, U; Q5 \6 R                if( addr >= 0x5000 && addr <= 0x5015 ) {' X% F% M0 S0 f: ]4 K# P( X
                        mmc5.SyncWrite( addr, data );9 ]! l( J% o1 s% }
                }
$ y. ^1 O7 m# G: Y/ D7 w: `, _        }! {0 o  u9 `. h
}1 }  T  A, A* S  p: i. \
: O5 h" E  ~/ C( A8 I4 d
void        APU::Sync()
5 ~: {. L. \( p4 |{
$ Z+ m$ [2 G( y2 O  m) [! X/ w}
% N8 X* T3 r. ^* d9 O0 F) g& G; _* C  M2 b# K' y2 A, t
void        APU::SyncDPCM( INT cycles )# Y! N" A) v$ M1 X7 r
{
( N( M1 E3 J( t  W        internal.Sync( cycles );
1 O0 l6 l) u4 H# f
! b! W, O4 y2 k/ ]; n        if( exsound_select & 0x04 ) {# {, D4 o: u: h4 V  Y: Z0 _
                fds.Sync( cycles );" u% H3 G2 ]3 @' k1 G
        }
) n: T7 E+ Q+ J, C5 L# A! Z+ F        if( exsound_select & 0x08 ) {
  w, N, L# H5 i6 E                mmc5.Sync( cycles );/ e& f) d* s8 s* M/ @
        }, |( T/ K; q' i
}# ^. l! t* q+ x

& P% F& }! B4 K" F: Yvoid        APU::WriteProcess( WORD addr, BYTE data )) j6 ~- \0 I) i5 b. d0 _
{4 C7 N3 ?$ }7 c$ z$ B: M  F+ n
        // $4018偼VirtuaNES屌桳億乕僩
! r2 q" v- h: h$ _- n( L        if( addr >= 0x4000 && addr <= 0x401F ) {
. B8 O3 j& i1 F* N& V1 o0 G" l6 F                internal.Write( addr, data );
2 o0 l' ~9 D# D8 n: B3 W        }' s* r1 _! I5 q0 h- E! y+ F/ N
}
& s& \4 @7 W& i/ G6 A% o) ~! c! h% R1 c$ q2 M; h
void        APU::WriteExProcess( WORD addr, BYTE data )
" J: u, X. v& ]! i% e. ~6 v4 h{
, u/ V/ q* F$ X- P; R        if( exsound_select & 0x01 ) {
: z# {( m! D! [# c                vrc6.Write( addr, data );
' Q5 r* [" g$ i9 M1 L; y        }! d' I: w: s4 X
        if( exsound_select & 0x02 ) {) X4 r1 q! d( `0 s
                vrc7.Write( addr, data );
6 x5 M2 b/ ~" k6 g" Y) X+ N8 e        }1 I0 c1 V8 x$ N9 l. P. ?' l& D3 z9 S
        if( exsound_select & 0x04 ) {, @  w# A% X# }1 e8 T: Q/ G5 t
                fds.Write( addr, data );
9 \5 o% j4 k* w- T4 c3 p        }4 e9 h; d& h6 X1 u7 r/ X
        if( exsound_select & 0x08 ) {* G$ f0 E% W% W2 X. X
                mmc5.Write( addr, data );$ F3 v+ P: x0 V
        }
$ C+ R/ ]+ _& Z( S        if( exsound_select & 0x10 ) {- ~5 a3 S/ w- ?# f0 q
                if( addr == 0x0000 ) {3 I) j! d% M6 X2 I3 V' |
                        BYTE        dummy = n106.Read( addr );( T& {& O, u: |; ^/ m' y
                } else {0 m  `( x" u8 R* ]* _
                        n106.Write( addr, data );
) E0 h; k# Q7 E( Y9 f& `9 i                }* D# Q# b$ k0 K
        }
, g- t8 ~: f2 O) w9 k0 ~        if( exsound_select & 0x20 ) {; D# \3 p8 o& r
                fme7.Write( addr, data );. C1 @& u+ Z0 |: W
        }) l+ |' T9 \9 i0 x- V
}2 b0 D% g0 }! O- Q

# u9 w- O( l4 {) E4 Gvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize ): H, M/ p/ x( H/ b5 ]
{
1 i& s! u  V# J4 DINT        nBits = Config.sound.nBits;
2 t3 N- Y! _* V$ z& \DWORD        dwLength = dwSize / (nBits/8);
) _2 m7 j5 R1 a+ }- J9 c  Q6 _1 Y# eINT        output;/ @2 z. Y( L, n1 m3 A
QUEUEDATA q;
; w- C# ]/ ~5 k+ ]# JDWORD        writetime;( _+ b0 I8 u8 A* j

/ D* P. U8 }4 x1 t7 Y) ILPSHORT        pSoundBuf = m_SoundBuffer;
0 Q4 P5 e! j# _* \+ ~+ TINT        nCcount = 0;
' F6 [. F* a$ L& K# I& F- W% x0 m; R' N5 [6 t, I; ?
INT        nFilterType = Config.sound.nFilterType;
/ `2 H7 d% I5 m; `( K# L2 Z% u0 z0 I+ R+ {
        if( !Config.sound.bEnable ) {
' U3 \6 K* N. j& i                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );* O# D  w. U3 S# d
                return;) z; i# T8 Z8 Y  Q9 d! C
        }
$ V1 I% G5 x) F+ D
# w! k( T3 r* K+ f! w( \        // Volume setup
$ `4 l6 h3 x! w7 O$ n1 X3 _        //  0:Master
$ q8 ^; U! w; a' n7 N; C        //  1:Rectangle 1( I% r, F7 X( D' K) W
        //  2:Rectangle 2
$ ^2 n: z7 Q. n; y4 V9 w; p  I8 w$ Z4 j        //  3:Triangle3 ^% I, I8 D( h# \9 z$ m, T- W$ I
        //  4:Noise& A& m5 |- F, \) L  {6 _
        //  5:DPCM1 k7 h4 q/ f7 |6 p" x
        //  6:VRC6
9 N+ U; H: A" Z' I0 K, O        //  7:VRC7
; a1 Z- {0 h0 N/ A        //  8:FDS3 J' a9 J! P. w& X% r- ^
        //  9:MMC5- ~/ V6 S- j5 E) v7 G5 [1 U
        // 10:N106. h* z" \1 _+ u* S
        // 11:FME7
% t+ z/ d  [& H5 L  Y. e        INT        vol[24];
! i, L- d1 {% g' L" j        BOOL*        bMute = m_bMute;6 |1 N5 w: {# x
        SHORT*        nVolume = Config.sound.nVolume;, F5 X0 o7 F8 Y- P% p

9 O' K4 O! E) J* ~0 T( x/ o! z        INT        nMasterVolume = bMute[0]?nVolume[0]:0;  ~$ C. i% c5 Q; w
) B( j' s; p# t( t  |5 {" D; F2 `/ d- C* L
        // Internal
; \7 [% c) x, X2 f+ e9 ^        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;) O7 J! m" |3 ]3 j8 ]
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
3 [% `) D( x3 M4 \- `        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
9 ^) J2 i# v! j* A5 I& I* p        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
9 O; T% w* m" n        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;! w/ u+ B' j( L, A0 p9 o
& D) S9 J; O- R$ z5 }
        // VRC66 b6 I4 O3 R* r, l% N3 M
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
  t" c4 k8 h$ e2 }3 f# t+ Y        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
; Z" I6 A  D/ h2 `1 `" }& H        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
' L2 s+ ]2 s' h+ o  e( ]* A
) Q5 _) u8 c* E3 C        // VRC74 L# A3 l7 c( l  U
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;2 d$ \0 _4 f+ j+ W8 t: l6 W

- o2 x* N1 x+ h8 U/ b: q0 M2 L/ T4 u        // FDS
2 h; F4 j" R! K7 f5 i3 i$ J        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;/ T7 G9 @8 D3 R. d- f

9 b6 L' m, @8 C9 k6 v1 n* T; D        // MMC5
$ D4 L, T  t7 u9 ?        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
) C( z6 m: Q" K/ b7 P* F        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;$ D* P# N/ G. x6 d9 O1 d
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
- D- c2 i/ I% q+ N/ I0 k) d
1 h' e* |" _; z6 Q2 v! r        // N106
0 J* |) j9 n1 a2 [- W3 w  S        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: h3 U# Y1 d6 q: t. ?, I        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: u" D& c- u2 i        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& u# k) `* u% m        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 M9 J3 i8 _' }3 n$ Q        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, R. W; T  B$ H& R        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 E9 h0 R6 ?% k- x        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;: V0 ]. n! z( \$ B" P  J
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, ~5 @  X" H8 C' a9 g
9 ~% R; k* Y6 z( h+ W& A        // FME74 ?8 k2 w6 G, v) u: Z- E5 P
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
: v9 ~; Z  U2 \! J: M" l' b        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
* E9 ?3 w) g' y        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
3 X: A$ b# `6 F$ F4 D; K; n7 Y- F8 B! R% `5 F0 ~
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;+ N  @6 f3 `+ a- e. R4 x
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;1 Z# O: _- N0 @5 U

& N8 ]  v1 j( T- W1 j4 M' _5 K  E4 n, `        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟& b8 K  \" {. S+ E
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
( M2 n/ I4 K2 A8 G( |$ Z                QueueFlush();
) o& n+ ?; j. R3 u) ?4 `1 \        }. L  Z; ?$ o2 G7 r  D

( c. `% j" X# J8 |        while( dwLength-- ) {
( E7 D5 {* i, n) H                writetime = (DWORD)elapsed_time;" x* V7 Q7 M  [# b
! U0 Y: Z% L3 b4 x
                while( GetQueue( writetime, q ) ) {
# }, k! Y$ }: f0 `4 a/ f) p+ V6 D                        WriteProcess( q.addr, q.data );
1 h, w3 [% [) F( C                }$ l! ?3 p. B+ y+ j
& R, B+ w/ A( R2 {8 o
                while( GetExQueue( writetime, q ) ) {4 m$ M# g6 ~* D8 k* B8 G7 R
                        WriteExProcess( q.addr, q.data );1 J+ H, D4 s/ ]9 R  {
                }
: ^/ {1 [- n9 Y
' N0 R' Z1 I2 C5 [, ^                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
1 q+ x9 ~4 H& H. K! I/ q                output = 0;
4 M6 ]  G  @" \" Q/ ^. Y                output += internal.Process( 0 )*vol[0];
; h5 D) U5 G2 z. k7 @$ j                output += internal.Process( 1 )*vol[1];+ H5 y) K: h* E  r) P) ^
                output += internal.Process( 2 )*vol[2];9 T; S. L2 R3 v, `# g
                output += internal.Process( 3 )*vol[3];+ l/ l/ V' k; Q
                output += internal.Process( 4 )*vol[4];8 L. L, `$ Z) e# _

  R7 \* L5 g4 K: X: |                if( exsound_select & 0x01 ) {
1 n! {! B$ ^; i+ O8 H, U: m                        output += vrc6.Process( 0 )*vol[5];; x* w. V  U9 r: i! k/ a1 J: z
                        output += vrc6.Process( 1 )*vol[6];! m0 B. \. p0 @' H8 {* G4 O
                        output += vrc6.Process( 2 )*vol[7];: _6 E, \8 e/ o# I( Q+ N9 a8 h6 ], x
                }
- L' u! n- R+ _* B; ]9 O  o( }; J9 Z                if( exsound_select & 0x02 ) {, ^0 e, T' e/ n8 ^
                        output += vrc7.Process( 0 )*vol[8];
. f" H2 O7 l6 m                }
+ R9 q& h; @, A                if( exsound_select & 0x04 ) {
' T: j0 a) F  W$ S, ?                        output += fds.Process( 0 )*vol[9];
; y+ a3 r* r- @, l! c+ ~0 n+ @: d6 L2 J                }
! k; F# `2 w: }, B                if( exsound_select & 0x08 ) {  }4 q' l) ]. W5 Z8 D# s) r8 h
                        output += mmc5.Process( 0 )*vol[10];3 k' b" F$ O8 L# f5 \
                        output += mmc5.Process( 1 )*vol[11];- T) ]: G% j$ b
                        output += mmc5.Process( 2 )*vol[12];
$ Y5 C6 Y% N0 k) D& k                }: N% M9 [6 n2 p4 Q" K$ q
                if( exsound_select & 0x10 ) {
$ @3 _2 ^0 Z) ]0 N$ a                        output += n106.Process( 0 )*vol[13];! C+ w: R5 A8 }# ?3 W
                        output += n106.Process( 1 )*vol[14];1 j7 E7 ^# ^& R
                        output += n106.Process( 2 )*vol[15];0 P9 p# i6 O2 g; e
                        output += n106.Process( 3 )*vol[16];5 {% u% n- P5 X! H9 Y9 w
                        output += n106.Process( 4 )*vol[17];
3 A# d* v! o+ n$ a) H6 Q                        output += n106.Process( 5 )*vol[18];4 m) g# F' O% }/ p( s
                        output += n106.Process( 6 )*vol[19];3 H  F' a$ Q" M2 U/ t8 _
                        output += n106.Process( 7 )*vol[20];
1 y3 I6 @/ \$ l9 K- Y: E                }+ J" Z' Y. c+ e& }4 l. {
                if( exsound_select & 0x20 ) {
* }( V& m9 [+ Q. k                        fme7.Process( 3 );        // Envelope & Noise* }( h8 Z+ e' \
                        output += fme7.Process( 0 )*vol[21];7 d* {, T0 w: u  w8 b
                        output += fme7.Process( 1 )*vol[22];
+ I8 p  t$ {" p9 W                        output += fme7.Process( 2 )*vol[23];0 T& b7 k; ]% p2 ~' R
                }( v1 f/ y1 }- I7 X, v
1 V8 }! d; e7 R  h1 B: H
                output >>= 8;( d" o  w) l0 M- p4 _2 q

+ {- g- ?3 X* k) @5 c* C                if( nFilterType == 1 ) {
, ^7 N$ s! E1 ^% \( c                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
% l- F) ~6 O7 u! i7 y5 L* \                        output = (lowpass_filter[0]+output)/2;
0 j  C" {8 ?. T* R! C* ?  B+ H                        lowpass_filter[0] = output;
$ ]3 E8 x4 w) e4 v7 `% a( n                } else if( nFilterType == 2 ) {& S! n7 Z+ M- {' X" {" r7 K
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
/ ^8 i! c4 E% @; k                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
3 L# v, h, Y7 S6 `: w7 s                        lowpass_filter[1] = lowpass_filter[0];" C6 H( h! }# p. k7 W' o
                        lowpass_filter[0] = output;' ?. h$ r* I# T) J* i# V3 o# H
                } else if( nFilterType == 3 ) {
; q! w% ^' I# q$ `/ s  P                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)) X6 I* R: d; x/ ~. M# T! x$ r
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
. u" X/ R0 k- K7 [0 H. A                        lowpass_filter[2] = lowpass_filter[1];
& b$ H! r( ]# g                        lowpass_filter[1] = lowpass_filter[0];8 J$ }2 Z: m2 G7 a
                        lowpass_filter[0] = output;: o+ g* P/ y" O. A6 p8 |
                } else if( nFilterType == 4 ) {$ ?( S: \7 Y2 o7 g* R2 @
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
0 c" k) s5 Y' M# W. h7 }                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
4 w8 i% q' _: K' ^7 c1 R                        lowpass_filter[1] = lowpass_filter[0];
$ K5 _" R" [' I" |) n                        lowpass_filter[0] = output;
5 Z7 j! ~2 j$ i: @' U% B                }
8 l  c* T( L( n+ @. t# J; n
; @5 a; j2 D0 W0 R2 H# r2 V, H) |#if        0
# k  g  H! Z% {* ?$ t                // DC惉暘偺僇僢僩9 n- ]# V( q" I" B4 t$ q4 i% S  F
                {& ~+ a0 X6 h4 O4 c
                static double ave = 0.0, max=0.0, min=0.0;: `* x, m& D1 `) n. s; I8 X3 S
                double delta;
6 b6 v% h! J( p3 X                delta = (max-min)/32768.0;
. W8 y9 y( v  m, f& h) N                max -= delta;4 R% O  M; Y( D% h; V
                min += delta;/ Q$ c7 j8 n+ K! B- ~
                if( output > max ) max = output;
4 ^' d: O2 u/ O# I3 \8 X                if( output < min ) min = output;* s! ]- `. f$ h
                ave -= ave/1024.0;
  r0 K% y* |; r1 x1 `                ave += (max+min)/2048.0;
1 G1 w6 K, D& I- R                output -= (INT)ave;
: Y+ j' H. F8 Q" U                }# }+ `/ P( A; H* }, U- @$ K2 A
#endif
$ v% u$ m+ ?) s#if        1
8 V9 w' |) T6 f5 [                // DC惉暘偺僇僢僩(HPF TEST)
1 r3 D8 j, n3 i0 o                {, M/ Q( z: O/ x$ n3 W
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
' B: a7 A2 z' a# g                static        double        cutofftemp = (2.0*3.141592653579*40.0);! {: ]1 Y9 O/ }0 j5 L! |( c) K/ v
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
6 L  `/ e* \! k8 ^. i                static        double        tmp = 0.0;0 Z! W: t6 ~* _& ^; a' B  d
                double        in, out;
$ ~7 L1 j. S: J- @: u& r& [# Z0 u. R' I1 O& o% k
                in = (double)output;: R" ^/ o' J. k5 C, N3 ~0 x6 W
                out = (in - tmp);
4 J4 b% X  b& g  o, `5 J6 \                tmp = tmp + cutoff * out;1 j7 C" p) ]$ N# t# X- d

* u" w& [3 Q! f( l( l                output = (INT)out;7 p& s% f* c) ]( D& A9 j+ d
                }0 z* b! s1 D8 m( A4 Q
#endif
: J9 F2 P, G6 S8 Q5 g- u#if        0
$ k& P7 G) u( t6 U7 |& r                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
: O4 n2 l% {' k) s+ A, T                {
2 E  |  ^; R& r! q2 C- S                INT        diff = abs(output-last_data);
1 G5 |5 C! q# T% w8 i( M0 j1 S$ g                if( diff > 0x4000 ) {: v& j& i* c, x+ s1 |! i* c
                        output /= 4;" ^. c6 u7 i: C9 n* l6 W/ p
                } else
! @; R: D2 t! l                if( diff > 0x3000 ) {
6 F$ c# ]& }3 D" n7 Q                        output /= 3;8 i6 [# ~8 a( a9 P
                } else
' e4 R! F+ Q$ e4 q                if( diff > 0x2000 ) {
% ]; ~' Q$ }3 ?4 q/ t" d0 Y  Q                        output /= 2;
: p0 D" C7 C1 |/ ~% r2 d                }
1 a+ R1 ]5 Z  P- d                last_data = output;
' D6 e9 O! e$ _& w- o                }
, m$ h) Z9 B2 V#endif# h9 G+ U5 J8 m- T0 ^% ]9 C! P
                // Limit
! F, H; t2 h. ?6 }* _$ X                if( output > 0x7FFF ) {
$ c( S) j- S3 H' O6 _5 X                        output = 0x7FFF;; e" s* v6 A6 j- u; r' \& x
                } else if( output < -0x8000 ) {
( e; K$ l" [( V9 ?* y+ W4 O6 V                        output = -0x8000;' C/ |/ X' ]6 [2 ]
                }$ g: r$ c6 t9 q1 c
/ |. y) {, R/ l, b1 X
                if( nBits != 8 ) {; U% g4 s/ C; G( x* Q
                        *(SHORT*)lpBuffer = (SHORT)output;4 X' d2 ~+ Z! ]) \# G. Y4 k9 _
                        lpBuffer += sizeof(SHORT);6 h9 y: j6 D4 y2 M& U
                } else {
% ^: U8 K' q6 c5 y# X; k                        *lpBuffer++ = (output>>8)^0x80;
/ ~# u: ]1 m  H4 N- k, j0 v" K1 h                }
: `# S3 }8 X  L0 s+ K) ^- `$ ^# m2 i7 k( {$ M" J
                if( nCcount < 0x0100 )
: X) B* h6 w. H* m' u  G, M                        pSoundBuf[nCcount++] = (SHORT)output;: o" R. P! v* [1 s2 I

- e' D( V: Y3 M. w4 {( F( s; K+ W//                elapsedtime += cycle_rate;' o# Y. ]2 q2 `8 c& }) s- h
                elapsed_time += cycle_rate;: f( ~, Z) C5 S- g4 J
        }
7 Y( P  @+ g% c: k' B7 d
7 w3 J' i" L. L/ E#if        1
$ h4 [% a- ~' P        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {' `3 g6 u# h, H" B) f
                elapsed_time = nes->cpu->GetTotalCycles();- v" K$ }" v2 x. Z. T6 K6 {
        }  M$ E) W, s0 Z2 y( ]
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
7 C" W# G- `; }0 o: F6 M                elapsed_time = nes->cpu->GetTotalCycles();" g, W; X) L; l  S, n( R
        }
8 {3 G  ?) l) o. M#else# p, t4 C7 |. o
        elapsed_time = nes->cpu->GetTotalCycles();, l% B" o6 Z( q6 Y3 m
#endif
  G4 @: K- B) j1 B}0 E$ ^5 D4 Q' C
: v/ k0 @  l3 I3 _1 C8 L. a8 n$ T
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
- ~0 l& ^# {2 Q- C* T. V+ E; |) pINT        APU::GetChannelFrequency( INT no )
5 X* S; {/ F& X" D- V+ U. l{
7 w- m4 c) |9 a/ t) [        if( !m_bMute[0] )/ d( z+ }1 c' t* q8 \3 S: o
                return        0;
" H8 w/ z+ O* N2 r$ E- Z' n* [5 O% j; O: B( o" ?
        // Internal
6 g, H3 t4 M0 N        if( no < 5 ) {
& I; U, r4 E' E# Z7 v; z4 p                return        m_bMute[no+1]?internal.GetFreq( no ):0;
1 i5 s  h2 S7 _% [. w' N. m        }
9 g' T1 x; v+ [  e        // VRC6
( r3 R/ [5 N5 N0 F        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {8 \% u; b5 \- ]4 j
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
( j0 q- Y2 W' P9 a* E4 ~        }' H5 |- p6 O) Q- w3 @
        // FDS
2 w2 \0 [5 i  {( F, E3 y, j        if( (exsound_select & 0x04) && no == 0x300 ) {
0 t, W  K4 n( J% q2 _                return        m_bMute[6]?fds.GetFreq( 0 ):0;- Q9 ]& Z7 _2 m" \. [' R# v! \/ h
        }
) P4 a9 @) S& C8 F4 T/ O        // MMC5- j$ ~) U  y' P# n' \) i$ P
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
4 G, O( @/ Y- I: _! v                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;0 T! |, v, p$ d
        }
8 E$ X# D6 m: ]1 n1 Z7 _1 s* W        // N106
8 F9 R, `- U4 S& j; o# x9 Q% Q6 A1 ]' w        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
0 Y( y+ w& Q# U) H                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;9 I% B. t0 ~, D
        }/ h, ]  O7 B9 H
        // FME7& z0 w* h1 h9 ~/ k3 _/ q. E
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {2 ]- e6 j, @! r, J+ T- K
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
# N% c+ [7 g5 X9 l3 M8 C' a        }+ {  H3 ^6 T9 G$ `% z& \
        // VRC7
1 c9 G6 X% A, I2 N# K& C        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
/ Z# E  t7 r- {5 ?- M* S& D                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;8 N+ [# L" x% ^5 y
        }
% U3 J) V# B  R& d+ s) P$ M  k        return        0;
, l# N0 J  _8 T}
3 @6 X! Q2 n+ S) j! R+ _8 p' w3 R& _) T1 J4 V" `
// State Save/Load3 l6 U$ V( f: J$ g# @
void        APU::SaveState( LPBYTE p ). ?. t/ M9 a6 r8 S
{
* v( h$ g: [  B#ifdef        _DEBUG4 z  ~7 e/ B: H3 d
LPBYTE        pold = p;  h6 I3 R3 u- W( \
#endif0 G) L/ B! I6 }) e0 ?
! D  Y0 O  [* i6 k# Y2 A
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞  c# e. i$ U# H) T. T  R
        QueueFlush();4 o9 e0 k4 R$ g, J, q1 c& U- w- T

: S# u4 h8 |( B' l/ o* f7 b        internal.SaveState( p );5 u, t% ?: u6 h  A2 \
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding( V  Q, r2 a# u- g) c

  L8 I5 \2 ]4 |; Q7 z; W( x        // VRC6* o# {7 F# X2 v
        if( exsound_select & 0x01 ) {' W) ~# C0 ?) p/ t
                vrc6.SaveState( p );# ]- o8 H; V* p% j6 x4 j$ o
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
  B& m$ U: j" m. S        }# u4 u! c8 J- i( r
        // VRC7 (not support)
+ t9 T7 z) |% F9 n5 @* I2 \& Y* [# B        if( exsound_select & 0x02 ) {
+ J1 G" }* Z/ H( U% i8 B% q                vrc7.SaveState( p );
; q$ }/ A1 w* g% b* H3 L  j! z                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding; {) b4 d4 Y! @- x$ A% z, n
        }
% H5 l2 {) t& e' l        // FDS% E. C: \2 S" Y; \$ y
        if( exsound_select & 0x04 ) {
3 k  ^9 T' c$ K2 q9 z                fds.SaveState( p );& v4 c/ u- v  `  e  X3 T4 }
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
* v5 [$ z; v/ A! g        }# A( t' ^% m; H5 R, U
        // MMC5* a$ a1 f; [$ I/ _- B- R
        if( exsound_select & 0x08 ) {
$ d- T. u6 n6 z  g( N                mmc5.SaveState( p );# o8 |5 l  v# b1 Z: M
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding! F+ P1 K! T3 ^# A) C7 G
        }
1 A% u2 J6 K% O& D        // N106( K- u/ X( t4 T( L! ~
        if( exsound_select & 0x10 ) {
$ m1 K; V& D" S; L  O$ g( l                n106.SaveState( p );
2 M% n  {2 }/ j/ m                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
) O% @  k* U5 J0 }3 y        }/ y3 Y3 o/ W1 }0 u% O5 @; m% H. {, W
        // FME77 |6 y$ U" f! e' i9 I
        if( exsound_select & 0x20 ) {
8 g: x9 o8 P- f) o- i2 C                fme7.SaveState( p );" C$ [  N# b/ b9 Z: N. Q9 n
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding- ]3 ~3 p' G3 H/ O( y8 [$ c
        }/ _* R( |- x6 M1 B: m
; n) N8 T; c* r* s: O  F
#ifdef        _DEBUG
% B6 u3 b8 u- {' hDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
5 i9 e6 T6 B, }6 m" z5 R#endif
5 {! }6 c9 b  N7 E1 t. i}
* h2 @! ~, g0 x* q9 T3 W9 b, O& I" S- {9 q! |, W/ ]
void        APU::LoadState( LPBYTE p )
0 }* @8 e  [8 ^, w{
" |( r+ c8 a& `/ F        // 帪娫幉傪摨婜偝偣傞堊偵徚偡: _3 ~: B) M# ?/ \0 z; C
        QueueClear();( \0 E; D& g% `- @8 X; S+ x6 W
; g/ D- b/ ]" B' c7 L9 \9 n! S; I
        internal.LoadState( p );
/ i$ s! X6 X% Q( E+ C        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding8 t. |: P* G: r: _. t: s: b* ^

/ p$ O. u' I6 ?3 s3 I- X' p. k: G        // VRC6
0 o8 f: M- i$ `        if( exsound_select & 0x01 ) {
8 Y5 P' ~* D/ [/ J. `. I  G                vrc6.LoadState( p );8 }8 R3 H- D# P3 E* d  I  ?
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
, r1 ^; x) R4 m& e        }
3 T9 p0 I2 F* k$ o% u3 K" p; b4 `        // VRC7 (not support)
2 E  Z& X! P) `2 S, z; ?        if( exsound_select & 0x02 ) {! y& M. ~1 s/ I, X
                vrc7.LoadState( p );- I& u& _: N: ^
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
. U" r% b! d% P        }
- U4 t9 u' K6 t- ?! `: J        // FDS( N) d6 A- X/ `& d% v1 u9 f# Q- |" S
        if( exsound_select & 0x04 ) {& o: \3 q& ]/ n$ H% y4 |; E5 W
                fds.LoadState( p );
& g0 `3 }, O  S6 {                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding  n% Z' s6 V! a# F1 M
        }6 ~8 z5 C1 M5 ~3 N
        // MMC5& d4 \6 K% s2 \- `
        if( exsound_select & 0x08 ) {
& {4 x( ~% T: N. L, Q) T                mmc5.LoadState( p );
$ g  Z' z7 U8 l# \3 }0 t                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding# H8 }4 u3 l* g' m
        }  E% [- b2 |0 ~  x
        // N106
/ D1 {' P* L4 `* {        if( exsound_select & 0x10 ) {
3 [0 D8 q/ `4 m* g: f                n106.LoadState( p );
' k" Y' T  Y6 A# G( E- y                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
: `; u1 C: S; V5 q        }
: Z) Z! x" A3 }: R        // FME7; K" Y0 R' e- F3 |  U! a' j
        if( exsound_select & 0x20 ) {
/ g' L6 v8 S" ~6 n: z1 F- o                fme7.LoadState( p );
" q! v+ u% z4 Z* w$ x6 }" Z) {                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
& m7 G, N" A  h( @( K3 G' p        }
+ V8 n! p4 H% X3 ?: S}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 # \4 Q, b& a1 m: r& u6 M
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
, |- |6 q. }, [1 r- l9 m, ]4 [感激不尽~~

4 o: c8 w. E7 x/ A+ V* n恩 我對模擬器不是很有研究,
4 p2 H' S9 y# S) P! k' M' z% ?5 K雖然要了解源碼內容,可能不是很困難,: m% p- ~- J3 B0 j5 l8 S7 O- e/ P" r
不過還是要花時間,個人目前蠻忙碌的。
  [) b% F. N  ^! P* }: D# C( l! a1 x: w; @4 I
給你一個朋友的MSN,你可以跟他討論看看,
% w- U& {: U# E他本身是程式設計師,也對FC模擬器很有興趣。8 G4 j3 b. h7 R! f# k
0 ^" O! N( L: M# J) Q) m* U
MSN我就PM到你的信箱了。+ F# ?& ~. c# P7 H- N

  m( O. [& ?9 C( R7 A, ^希望你能有所得。

该用户从未签到

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

签到天数: 80 天

[LV.6]常住居民II

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

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表
6 p  ~9 S5 a" m4 _" a. D- \呵…… 谢过团长大人~~

$ r1 {# x: o# X: U; u) W" S; S* E9 D$ ]% @- q
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
7 H. w: C0 v4 {团长的朋友都是神,那团长就是神的boss。
3 Q5 A$ P. e9 a$ {# E3 {
哈 不敢當,我只是個平凡人,# q& t6 U0 M6 }* W
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙1 o5 f; o0 Q$ |" J# u
ZYH6 P* m3 q& i* `) y2 _! v! K
QQ:414734306# v; [7 n# e* Q  p1 s$ e2 Z0 A& H
Mail:zyh-01@126.com* f6 W4 i$ i7 a

. W; R4 x: Z0 T他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 2 x4 c) R0 y! \* j; Z
再次对团长大人和悠悠哥的无私帮助表示感谢~~

2 [  c' X7 e3 u( R/ q不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-2-6 08:20 , Processed in 1.099609 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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