EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
; m8 l, }9 c$ }( Z( k8 Y! x& ?5 Y/ }! l楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
5 g! `  k3 K4 g" H这里有相应的模拟器源码,就当送给大侠了~~
- A/ C2 s4 j) D# l; uhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
" b4 ], n9 x, _9 m' k+ [% a) W& Y能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。* O5 l+ O* s  g- [
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~/ k0 x1 e4 n& x8 L
这里有相应的模拟器源码,就当送给大侠 ...
: l, |- p* `- `- ^
聲音部分(Audoi Process Unit = APU):8 t5 [* y  ]9 @) h) F
.\NES\APU.cpp. Y- K  i; o) [' K
.\NES\APU.h
/ p% r: o! V2 u8 ^$ B1 b1 C; ^/ H
6 ?3 G/ b8 ~: k" L3 a4 e# x
影像處理部份(Picture Processing Unit = PPU):
% l6 f, ?! y3 c+ ~- T, P) V$ U) A.\NES\PPU.cpp* S, ?3 T# q) B7 `9 S9 J
.\NES\PPU.h
% T# S: V* {+ Z2 R& D& ?* w+ [* Z9 h' Y' s& d
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
; @" X3 u' ]# k5 v- k+ g8 }2 R6 H" I感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:; A. y. Q' A7 M5 h% O
(由于很多专用术语和算法机理都不明白,所以看不大懂……)9 W2 w; J0 g6 Q! u9 b
//////////////////////////////////////////////////////////////////////////
* `" o: c' j0 W6 {5 {/ \//                                                                      //1 ~5 Q5 ?! y2 `) C! i& Y2 J
//      NES APU core                                                    //
" I7 m7 t2 n, G5 F" z' d' R% Y//                                                           Norix      //
0 Q$ p1 A- e# V& T4 E* j//                                               written     2002/06/27 //# t, L  N8 u2 b3 y
//                                               last modify ----/--/-- //
' E: v9 b0 c& v. s//////////////////////////////////////////////////////////////////////////& q3 O1 j( c, f1 [
#include "DebugOut.h"
) S$ \& T/ z" H% y( q#include "App.h"6 ^4 v' M- d- U: Y) N* m% i$ X
#include "Config.h"
( n4 F$ m  T2 J/ k" ^
! M5 t( b# _* L#include "nes.h"
1 M5 g% `  |" P; @#include "mmu.h"
: B4 N" s  f- u1 X, P#include "cpu.h": m% @( s" l0 F0 E& I) P
#include "ppu.h"/ K! P6 _6 K9 f2 G# h: e! O8 b) m
#include "rom.h": W* R+ n5 i1 N9 {0 H$ Z
#include "apu.h"
: ^- @& o' m5 x* g# b! Z( {& f$ J* ]. c
// Volume adjust. A( E& [8 z. m; L% k& }( K
// Internal sounds, }2 \2 _3 R5 ^0 C5 c% H$ D: ?
#define        RECTANGLE_VOL        (0x0F0), {5 U4 M; h0 ]" i8 @) u5 `
#define        TRIANGLE_VOL        (0x130)
# ?4 x6 Q% O8 Y- U1 I#define        NOISE_VOL        (0x0C0)
$ [2 X& q' }! S#define        DPCM_VOL        (0x0F0)" Q+ T$ C' d, y# H: o+ D. e
// Extra sounds" S4 \1 Z( ~. K
#define        VRC6_VOL        (0x0F0)
$ T& f: n  l. E4 j; ^& T#define        VRC7_VOL        (0x130)% K, |6 y8 i* S4 h& M
#define        FDS_VOL                (0x0F0)( B& e& r  V0 k- g
#define        MMC5_VOL        (0x0F0)' @: {8 r( |: f! ~- B4 W
#define        N106_VOL        (0x088)
+ D3 q3 s4 U! A#define        FME7_VOL        (0x130)
3 H( x# i- e+ D/ ^6 N) J, z% _2 D5 A+ f* }' E& g
APU::APU( NES* parent )' L' ^0 n" u5 i9 m
{! C5 Q* I9 M9 c
        exsound_select = 0;  f; D: g5 q$ I% [
8 |9 q/ N( R# w; W3 L9 z9 J
        nes = parent;; w  l6 B) [9 w5 k
        internal.SetParent( parent );
2 C2 ^' r# C! Y0 k( L# X
5 I$ o2 R( J, v% S: q1 l. J& k        last_data = last_diff = 0;
& b* H& u2 L( Q4 k
0 H  C" O3 n) t% I  J; S        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );# I/ j9 D$ E% q$ q
+ J4 b% v% [9 X* v  x2 |
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );1 |& U6 P3 S$ |6 ^
        ZEROMEMORY( &queue, sizeof(queue) );
. X* E9 o: k+ l; f        ZEROMEMORY( &exqueue, sizeof(exqueue) );& H0 l7 q7 Y( D/ H; Z

; G$ L9 H3 d& f6 H        for( INT i = 0; i < 16; i++ ) {
$ u. P, ~( F* o2 e- E                m_bMute = TRUE;- \) F% G2 J1 h9 b' Z
        }
, E  s, ]( k5 D$ b1 ]: X}
% _& ]/ ?6 V. y' R+ P0 i  n+ T" |8 X( z+ [- Z
APU::~APU()0 g( v. e% E" S' U2 h+ F
{8 x* Y7 i  l' a4 R1 V
}
; C5 k2 b9 R' g6 C( ]) c
0 Z& {1 L: l. v8 _8 Xvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
. L: D4 b/ }. m; T8 d. F  |{
1 l& j+ g6 d; _% C% y  s! ^. n        queue.data[queue.wrptr].time = writetime;
7 Y% w5 p; q9 _( B        queue.data[queue.wrptr].addr = addr;
3 U4 E5 z! K" h( }        queue.data[queue.wrptr].data = data;
6 u8 H7 a& W3 |- w        queue.wrptr++;3 K" s7 U; S% v8 C
        queue.wrptr&=QUEUE_LENGTH-1;  a5 |! ]! Z% t0 L$ g
        if( queue.wrptr == queue.rdptr ) {
5 S7 `8 k4 k7 y/ y0 u                DEBUGOUT( "queue overflow.\n" );
# n- C  M' w1 F& ^        }
* K* n# |! t' E% }}, }9 b$ r! z+ E/ b% h9 n; R8 L
2 y2 k. e& E  \; w
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )- U4 y7 y  S1 G3 p; s% K
{  h$ I& ]7 y. g% D/ d
        if( queue.wrptr == queue.rdptr ) {
+ P2 ?( Z) @: `: B3 U: B                return        FALSE;
2 T: s& Y, F1 d* [: @$ {        }
: g, p: F4 d, |# b2 P; k) Y5 g        if( queue.data[queue.rdptr].time <= writetime ) {7 W: s3 Q  n9 ]  ?) o* W
                ret = queue.data[queue.rdptr];8 ~8 L# y  V7 K+ e# a+ u) E
                queue.rdptr++;, {  |& A" r6 ?( I* t; p
                queue.rdptr&=QUEUE_LENGTH-1;! B" N9 B/ o3 {, Q! E0 G
                return        TRUE;: W  o, n& I* V+ K+ ~8 Q* x
        }" g- Y) V: l& _( \
        return        FALSE;
* f5 X  g8 }0 n2 t$ G  \}
6 `1 }5 ?6 {1 i8 ?
0 n% M7 Q# a; d2 F$ D* Pvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )5 `: l& t% |" V' o, B& j7 [; O2 I
{+ U1 w" Z2 u% G9 F9 Y$ _
        exqueue.data[exqueue.wrptr].time = writetime;* `9 V% G: P% K- s' E1 c
        exqueue.data[exqueue.wrptr].addr = addr;1 U6 z' L4 }% v; q) C8 W% ]4 |
        exqueue.data[exqueue.wrptr].data = data;) g9 K' s" t- k, N
        exqueue.wrptr++;
. [4 R! r& G. O        exqueue.wrptr&=QUEUE_LENGTH-1;
4 x8 _1 a+ R1 `0 K$ d        if( exqueue.wrptr == exqueue.rdptr ) {) |. ]5 g! h' t" P  W
                DEBUGOUT( "exqueue overflow.\n" );
) K, s5 b2 h/ B( ?+ I% f        }
; \& c% a* Y, O) X! g}
* G& N7 D! C! b) R* I
5 f: A. v, ]: yBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
3 ?1 ~' ~6 m! A$ ]8 c{
( b1 g: A1 T0 C- ]. ?& D& ?. O        if( exqueue.wrptr == exqueue.rdptr ) {
$ H3 P2 O# p3 s) ~                return        FALSE;
. u; C$ Q" n. L+ S4 x' Z& z        }
3 U/ z% @! S  p5 o        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
+ ?4 J3 ^5 }. K                ret = exqueue.data[exqueue.rdptr];
$ ^/ m- w+ W( Q4 w- ], d* Q                exqueue.rdptr++;
4 j3 k* s/ N+ q6 u                exqueue.rdptr&=QUEUE_LENGTH-1;
% ]/ I5 i9 b2 l                return        TRUE;! \& w7 r' M3 H) s. T9 ~
        }* z" p9 ~3 M2 n9 U
        return        FALSE;2 u) y- |) o8 {& c" Q: B
}$ F" i: f" Q: S" V, x1 j0 |

0 w9 o5 n  v1 w! s7 J, S! N/ J( t1 uvoid        APU::QueueClear()2 @* t; H; j9 m% g0 b. J
{6 e& z. R5 _- C% m- [
        ZEROMEMORY( &queue, sizeof(queue) );% ^/ l! f; s/ l4 B4 P' r
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
1 O( q) H. i  d! P1 ?# o}
( Q$ z& [# I/ k
! w8 q- D" ?4 H6 \7 uvoid        APU::QueueFlush()0 b+ P9 d5 O( X. i! q0 t. g) `
{; U5 W: c9 V; \$ X4 v8 M
        while( queue.wrptr != queue.rdptr ) {
- |, ^% q. I6 {! A: n7 o                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );# v8 _6 C* ?6 V
                queue.rdptr++;$ G6 Y+ z3 D5 ~0 t
                queue.rdptr&=QUEUE_LENGTH-1;& N6 j/ t7 q& `+ o; `# u4 O9 G; \5 n
        }. k0 w! @- d+ k" Y8 Z
" B% K, [/ p% m- F5 T: s2 Z
        while( exqueue.wrptr != exqueue.rdptr ) {% i1 G0 {& ~* t: U7 S
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );+ q& s* q- Z" {9 I8 q3 S- o
                exqueue.rdptr++;8 u1 m+ L6 u  ?: Q
                exqueue.rdptr&=QUEUE_LENGTH-1;
; H' o& z/ z  c3 ^7 q- f, S        }
! G- M7 j3 l# x}6 e& [0 e  E& q" U; A2 H7 O+ ^
! w9 n4 D2 d  a3 t- z" Y# l
void        APU::SoundSetup()
0 {" G- ?1 u# S& C& F{
& N" H/ r& b0 @5 y% d: H        FLOAT        fClock = nes->nescfg->CpuClock;. E: m- }; M4 p4 }1 D
        INT        nRate = (INT)Config.sound.nRate;
6 a$ B) Q( S& ~9 u+ b: H* d( w' R        internal.Setup( fClock, nRate );
6 O. x- ?. N- c/ a# K9 h        vrc6.Setup( fClock, nRate );
7 u9 k( I1 _2 O) P        vrc7.Setup( fClock, nRate );6 E3 D/ L6 z0 `
        mmc5.Setup( fClock, nRate );
/ P0 u8 s. M4 t" |        fds.Setup ( fClock, nRate );0 @, f& q: {* g, }$ S
        n106.Setup( fClock, nRate );6 k/ @3 U! G0 Y, h/ g; _; P7 s$ n
        fme7.Setup( fClock, nRate );- v: z4 j# G( |' c; w9 @
}
& ]4 y8 I6 O# h  c% c. u2 K! }& n+ a, Q5 Z& q
void        APU::Reset()
% ~/ b4 a- Q+ z{$ o7 C/ z: v8 K: m. m
        ZEROMEMORY( &queue, sizeof(queue) );
7 B, a6 F, n$ ^9 r, F5 K        ZEROMEMORY( &exqueue, sizeof(exqueue) );) Q3 m: c# k! [; @" n

& Y' P' F1 x$ H8 G7 a3 p& P        elapsed_time = 0;  R2 h8 A! O9 a
& ~1 \& ~+ B! ^0 h% h
        FLOAT        fClock = nes->nescfg->CpuClock;' m" X  [9 f# h) u; Z% }
        INT        nRate = (INT)Config.sound.nRate;! L) x+ W! [# T3 \+ }: L2 ^
        internal.Reset( fClock, nRate );
) i9 X# X3 U: A& A  u+ S" C  q7 K        vrc6.Reset( fClock, nRate );% e+ M4 w1 o! ?
        vrc7.Reset( fClock, nRate );4 w; B9 r6 r/ x6 E
        mmc5.Reset( fClock, nRate );7 A4 c$ G/ `3 c' A
        fds.Reset ( fClock, nRate );
9 ^* ^  [0 A6 w& u# c) K6 ^) \% @/ l        n106.Reset( fClock, nRate );
* G# x/ {/ g4 _$ L' W" d, S- v        fme7.Reset( fClock, nRate );
. N1 K( h8 u% l. Z9 d5 _- }+ s% \7 o: R: ~
        SoundSetup();% J1 W5 ^- @" |
}1 i2 x9 D# K+ u3 }- y/ K/ C9 J- l
7 D% C4 T4 p7 D
void        APU::SelectExSound( BYTE data )
) K9 B, G, u2 p, L" ^+ d{
# ~( g) B9 e8 L, a) _. o" h        exsound_select = data;( @  [3 _0 z; I4 {
}4 H6 ]9 d0 n" J" r" B: T
/ D7 y" a+ z: v& ]. a
BYTE        APU::Read( WORD addr )& {; p7 ^3 A% H4 ]+ O% _
{0 \# u+ C$ p& S8 h5 S0 g
        return        internal.SyncRead( addr );3 R& {4 @# |! T) n
}
1 k5 _/ u9 j, |' }
, d9 }7 s& i+ B# zvoid        APU::Write( WORD addr, BYTE data )
8 G- ~+ \, b3 f& y{% {, C1 D2 `# [4 X" \
        // $4018偼VirtuaNES屌桳億乕僩
3 }% ]( a, Q7 @/ c) K1 b        if( addr >= 0x4000 && addr <= 0x401F ) {6 W( @* P: `" [- T+ U- J
                internal.SyncWrite( addr, data );9 u' r/ }/ v! D0 r7 r$ ~
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );# n: T; H; B/ M# ]5 Q
        }% f! n: ^$ I2 \1 y+ |0 j4 u
}' |+ L  w( I( ]% K( O& p% A
' z5 H" j2 f* [$ ^# b& Y* y" {
BYTE        APU::ExRead( WORD addr )" F% B# q$ u7 R- b, y4 I% Y
{
. V$ l3 z: G4 A7 o! B/ ~6 |  BBYTE        data = 0;4 @2 H8 a" x3 d- M; c/ q$ f

& Z5 `+ }, o3 \2 }& f        if( exsound_select & 0x10 ) {7 m) C5 t+ |7 U& S
                if( addr == 0x4800 ) {: b7 X! C0 @0 s* m/ j' h3 p9 j: o
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
# D1 N% U+ b, U  O2 S+ L$ @                }
6 j+ N; X# L+ w2 b% y        }+ C% r1 Y: C! L; o
        if( exsound_select & 0x04 ) {( a4 D- |* r. {$ Y/ Z1 z" T
                if( addr >= 0x4040 && addr < 0x4100 ) {
+ r& Z6 S2 N- F- W, e                        data = fds.SyncRead( addr );
6 c+ p4 K( o; ?. G& A  m/ |4 O- b                }
1 A9 ]' Y& O- a- @$ Q        }
: Q; f$ v0 J. V2 Q/ k7 q        if( exsound_select & 0x08 ) {
8 D+ ?# t. ~" M7 c  B7 F                if( addr >= 0x5000 && addr <= 0x5015 ) {
8 y& s8 h& G7 o, V7 e                        data = mmc5.SyncRead( addr );
& m, [* n" s' f                }
. B, G3 p( Q* F2 u, j1 \        }5 y) o* ~9 W8 b- {" B3 l/ k6 k

" N2 ]6 x$ |, d+ g/ C; }6 y/ h        return        data;
5 z% ]0 W1 M6 u% z+ h% F7 l}) E& J- P  V- y) j4 D! m5 I; M
- f! u. \& E  O  f6 J
void        APU::ExWrite( WORD addr, BYTE data )
0 J, T$ V  T7 I% J7 i% ~) r& l6 {- k5 j8 @{- s& W  J1 ?4 H- w8 P& P
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );8 N5 p" f% D7 S6 Z2 E  [' s$ Y/ X' S
; L& b. }0 Y7 _7 m: y4 z
        if( exsound_select & 0x04 ) {
! P+ Y- ~7 w5 d/ E) e                if( addr >= 0x4040 && addr < 0x4100 ) {
* e* o1 ]2 V2 {7 w/ |  b. U8 c                        fds.SyncWrite( addr, data );  T$ X- z$ a' c" S
                }
9 W. Z; s0 B+ h$ ?- M* @3 Y        }; o& p- I- C) p% t5 B

/ u, s) h, M2 D2 T        if( exsound_select & 0x08 ) {3 `( ~! a, g; F& h4 Y  B) `! `" a
                if( addr >= 0x5000 && addr <= 0x5015 ) {
1 Y, Q( Z; @. H! t& e3 @+ g                        mmc5.SyncWrite( addr, data );+ [) G8 c3 g- l) a
                }; L& @, T( m& S- f8 {  l2 ?0 C
        }  [$ g' }- m, [1 e. M7 V* q2 p5 p
}
$ V6 X/ `0 F( A+ D3 D& g2 K
( D6 Y- C8 L( Y9 evoid        APU::Sync()& P7 R" H! Y# A; g+ q$ s
{' \& Z6 s# r# b2 b) l0 x3 O/ p
}2 ~, [0 \" d" _' g. n
. A" E# @' p0 A( N" C
void        APU::SyncDPCM( INT cycles )4 r- Y) r( L- j. m% T# K& b
{& H7 t; \* G+ N% m* }
        internal.Sync( cycles );, M7 e. S8 m" |* K" J

& W2 t* d5 ?2 g5 l- H- u5 V9 c        if( exsound_select & 0x04 ) {
. B9 g3 t& G4 ^# ?7 ]; d! J5 V$ Z                fds.Sync( cycles );" N+ Z- ~- [) ?0 M) P/ W
        }' d- m% j9 v! U$ E5 p
        if( exsound_select & 0x08 ) {
9 y. K/ M9 O, s$ D4 A/ r4 @                mmc5.Sync( cycles );
0 s" t" o3 D  m% O: o; M! Z        }- s5 @5 j6 {$ Z. g6 J
}
/ T' ]( r; p; \4 i# @# {# X1 \8 Q7 y+ T
void        APU::WriteProcess( WORD addr, BYTE data )1 @  b2 _4 r& l4 |0 N. r6 A
{
! Z/ a( B5 S8 h, }$ Q        // $4018偼VirtuaNES屌桳億乕僩' y2 `, o6 i5 `# s/ M/ r
        if( addr >= 0x4000 && addr <= 0x401F ) {$ B& E9 o3 h, ?8 B4 ~
                internal.Write( addr, data );
2 E/ l1 m0 w/ L8 A7 m* f* w        }$ N# w' y1 W, u2 L2 `
}
* `6 w0 b$ w% ~: t% f5 @; N; F" V6 U( y. ]' J* u
void        APU::WriteExProcess( WORD addr, BYTE data )
  q( M0 M2 F8 H{, C2 ^1 R3 y- ^
        if( exsound_select & 0x01 ) {
  a- H8 K% H  g" h                vrc6.Write( addr, data );  m3 ^, {+ d1 i4 M2 s; _8 `+ H
        }
3 }! s. Z9 L% z+ M2 L        if( exsound_select & 0x02 ) {
6 g$ [. R/ f1 a  p5 q" T# G+ z                vrc7.Write( addr, data );2 l$ ~* D7 C- w
        }: {/ z: c8 {: o4 e4 v
        if( exsound_select & 0x04 ) {9 s4 i, m% x4 l0 b; u
                fds.Write( addr, data );- Z! Z- z1 `3 U$ v
        }
, I8 L0 ^) s# z9 j4 o        if( exsound_select & 0x08 ) {
( P! k& r0 }# Z+ Q! L5 ~                mmc5.Write( addr, data );
' p* x4 ]$ A' a, K3 l7 ?  w        }
/ e8 n0 R6 W2 C6 I. n  Q: X        if( exsound_select & 0x10 ) {' j7 J. W. i# o: t9 P7 L
                if( addr == 0x0000 ) {7 s( ^1 u' W: Z
                        BYTE        dummy = n106.Read( addr );
8 {: s- [4 A! W& P0 i                } else {/ G5 q' n! o- D! ^, A7 O
                        n106.Write( addr, data );3 x& f1 B/ \/ a* y! y$ m
                }
' C* ?( t4 \2 ^7 j. d0 |, x4 e        }9 \2 v0 K6 F' ^& z) n; O0 P9 _9 D4 b
        if( exsound_select & 0x20 ) {1 o& a8 ]9 N) e$ c+ ?
                fme7.Write( addr, data );8 k5 H* k( S, g+ f( s
        }# Z( r' N& o0 l
}! u4 g" Z5 y  ?5 e

* Q# y2 X2 x! u4 I5 E3 y% uvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
) j. h# ?0 e4 B6 {, L5 z{
6 C3 Q9 x! G; ?& C+ p  X# EINT        nBits = Config.sound.nBits;
) s: `1 A/ l" h0 K: ]. `/ _DWORD        dwLength = dwSize / (nBits/8);' y* E, o/ A9 S. }  l
INT        output;
  P/ @7 `' k5 _3 LQUEUEDATA q;
3 p$ n/ d* {# Z  EDWORD        writetime;
$ d  j. Z1 O. H% r1 Z
; [& b3 W+ V6 Y. {* h0 I- D: ?/ `LPSHORT        pSoundBuf = m_SoundBuffer;- s* K; M' S) l, T/ h
INT        nCcount = 0;4 j7 {. ?& U1 Q1 C+ T! K1 _
$ R0 X& q% R1 p) @
INT        nFilterType = Config.sound.nFilterType;
. j0 n3 N3 j1 L" l) U7 C' I& M: p9 H- U0 x
        if( !Config.sound.bEnable ) {, o+ l. L2 V& P, W/ m& F5 B
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
/ B, v7 ]$ Y9 z+ z1 x# p( H( y4 \                return;
  S) _8 X* t& w& d% M        }7 T6 {' n% T) E( x. q8 n2 J* W1 f
/ v" ^4 Q2 z6 Z& ^; A
        // Volume setup
# `8 q, `) i, h$ {6 D        //  0:Master2 e. h+ [3 l0 b
        //  1:Rectangle 18 b3 S; S% ]0 \- g3 u
        //  2:Rectangle 2
! \  v7 Q8 h1 ~6 x/ Y! ~        //  3:Triangle
" T1 }7 j- _  h, n5 j2 z        //  4:Noise6 G1 f$ `: `9 K  a
        //  5:DPCM
7 T, z& i6 V: K# Z$ J, I2 `3 d        //  6:VRC6& Q# S: K- j3 J. i
        //  7:VRC7+ X/ q: H1 Q$ X, w( L' t
        //  8:FDS
. s- F0 M; |9 H- P& _        //  9:MMC5
' i! `- C% V- T' i8 E1 W; V( G        // 10:N106! U& G' Q5 g7 i
        // 11:FME76 n7 G; j: ^7 n9 h
        INT        vol[24];
  l+ W7 Z6 Y2 i  f/ p        BOOL*        bMute = m_bMute;
  e' I, b( t6 X: J0 _3 A1 Y        SHORT*        nVolume = Config.sound.nVolume;
: Z# ?- [8 J3 k/ o6 x3 i; ^+ Z. e4 \& Z9 d( `$ r$ a! h
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;) y7 X4 v, G: D6 C% T

' S1 B, C; z$ P6 o+ Q        // Internal
1 |' K- x9 N  m7 g* x        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
5 x2 w8 ~7 \% y' c+ K3 R; e! i        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;- d1 }& Q) s3 o' p; S; s
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
" o/ s+ T1 h* [' P        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;! ?4 {  ]' C8 l/ J5 Z' ?
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
4 v- P  M3 _3 _
- C4 E0 r2 E. D1 l3 V        // VRC6
6 j) d5 L( k  M3 X* g2 V: ?9 X        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
8 J7 n- i$ c. B6 r1 K) V6 H        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
& E; P: C! Q5 Q! X        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;# z5 p9 H9 @& C- b6 R
  Y* ~. [2 y. v* M/ }) @
        // VRC7  Q* A. Y+ b' R+ T$ |  u
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
1 U1 I# i5 K: ~; F$ S# ~6 c3 Q* X5 p) W
        // FDS+ A( F2 r  p2 m; o. S( d
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
( p& W/ M9 `0 \: y5 Y) B* M- B* \5 @, p/ N1 b% u% ~: t
        // MMC5
* n. ?! |7 |. V1 ?9 N2 t& Z' L9 I        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
! B5 j( D9 c; A. q        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;4 r; v6 H) H; j- a. e5 H/ s0 j
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
2 I. q3 G9 e5 j9 ~% j2 e9 r3 Z2 c3 a8 e. ]& i( j7 n# B
        // N106: K2 [- `: Q. B" J
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;! K8 O; {- s1 z' d& D/ X( y6 t
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& p5 B- k" `3 ^, m3 d. \0 Z$ _. _        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 c( K: F( s1 `  F
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;" c( x1 T3 X6 M: O( m8 R
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
/ W* E+ N4 @. J" l# K' T" |        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. Z) i7 V1 b' I; w' n. _        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
5 i' U# E" T; |0 V) U$ }! d9 E        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;* I3 f" U! I  N4 y& F1 e
3 W" G7 \6 M( S& |( v
        // FME7
  Q6 B: S  N' ^        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;- L" a  f* H5 x1 c( q
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
) O  ?: k7 O/ D        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
* w% v* t9 ?( c6 w4 B& L6 l# ^8 g' x2 F5 D
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
/ A# F3 [0 ?& y        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;# [( ^( d, b* M; u1 l" T

  U) p. [9 J( c8 X& y: F7 Y2 \        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
) r2 Z  A4 x; o5 H1 S. ]! E        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
: s+ H& J3 |& o0 u( {5 v0 Y8 m                QueueFlush();
/ P- ?) Q2 }% V- ?& t" c2 z2 I        }& F3 B0 G$ F. L% }2 P; G

2 _$ O9 z. |; J& [' B" v6 x, O8 v  N        while( dwLength-- ) {! D9 R) {  k2 N
                writetime = (DWORD)elapsed_time;
! V2 A' i& t0 o' U8 ~5 h% U: s/ I8 b: x  G5 p* d
                while( GetQueue( writetime, q ) ) {
, g: @- |6 u4 X5 p                        WriteProcess( q.addr, q.data );
$ O# a0 g( w5 i8 p( ^4 e                }
# i3 j; ^; G# N' ^  U: r' D0 `) O5 |0 _5 D3 D8 _
                while( GetExQueue( writetime, q ) ) {
( g# B& s2 X8 j                        WriteExProcess( q.addr, q.data );$ q: ]% j. `! m0 W9 B* V& {
                }. [' ]+ L5 @5 N! Z6 Y) ]- {& h" T; W
* W! P! ~% `) A3 W* p, y# D
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
. R; t9 z# D, }                output = 0;
, E1 Z! e9 f, o" S% j6 T                output += internal.Process( 0 )*vol[0];
. S$ C' L" m' O5 m. z; |  _                output += internal.Process( 1 )*vol[1];
6 r7 T$ K( j( d                output += internal.Process( 2 )*vol[2];8 E  A$ D6 e0 @/ L5 q
                output += internal.Process( 3 )*vol[3];0 w/ A' H6 Q5 E" I, Y
                output += internal.Process( 4 )*vol[4];
. s; o/ H9 p+ M" o* l8 z4 l2 Y' ]% B% B  ]# g
                if( exsound_select & 0x01 ) {
7 }" Z. D: K" q9 ]7 ^                        output += vrc6.Process( 0 )*vol[5];
/ j4 c& d, |! }                        output += vrc6.Process( 1 )*vol[6];
9 m$ v- u8 e$ T$ i  ]6 y                        output += vrc6.Process( 2 )*vol[7];
. l$ E" }" C; D3 o- V/ \8 j3 g                }" ]; a8 [. }  z0 x6 E
                if( exsound_select & 0x02 ) {
, _+ \. B% ~) F4 j9 V7 ~# c                        output += vrc7.Process( 0 )*vol[8];9 M, d  t) b" t% n: k5 U; {4 t0 q6 q
                }
" m. T( g' t" c7 S  d; c' n                if( exsound_select & 0x04 ) {! C5 L7 q0 _  \4 i3 k; n, W3 U1 H0 V
                        output += fds.Process( 0 )*vol[9];' U) b5 k/ `& ~. C8 F( \
                }6 |. P) Q3 C/ L4 Y  j3 Z
                if( exsound_select & 0x08 ) {6 I. j% ?- y4 x1 P  A
                        output += mmc5.Process( 0 )*vol[10];
1 w$ ~* t* ?& w/ D                        output += mmc5.Process( 1 )*vol[11];
9 U2 Q) \3 X7 j- b- h                        output += mmc5.Process( 2 )*vol[12];
; V. q6 Z# o+ W7 g                }
, J9 q$ c4 U) i/ H9 l; V                if( exsound_select & 0x10 ) {
6 E. q. h' r% b" j4 X                        output += n106.Process( 0 )*vol[13];
! l0 S' p/ u0 n9 Y! ?                        output += n106.Process( 1 )*vol[14];, M* d  x) H; I0 H& H
                        output += n106.Process( 2 )*vol[15];+ ?' b' G& Q  N6 _0 i
                        output += n106.Process( 3 )*vol[16];# q% h! l9 ]0 G
                        output += n106.Process( 4 )*vol[17];* P: v7 D$ ]) D& r* j
                        output += n106.Process( 5 )*vol[18];* k: E- K3 l  r& \3 A5 ]4 K  l' I
                        output += n106.Process( 6 )*vol[19];2 F, ~* q" v  e7 S+ d
                        output += n106.Process( 7 )*vol[20];2 S4 z9 l+ _6 f5 R" A7 _/ r
                }
2 ^, W1 N8 ^7 T; s4 \$ W! I7 P                if( exsound_select & 0x20 ) {
- W5 x+ C% C, l% }5 n% C0 B2 f                        fme7.Process( 3 );        // Envelope & Noise
, a- y/ ^2 ?- s6 U                        output += fme7.Process( 0 )*vol[21];
' k) p; F- Q) F3 `+ T4 r                        output += fme7.Process( 1 )*vol[22];0 ]& b' C3 K9 n7 ^; Q! k
                        output += fme7.Process( 2 )*vol[23];
' c; v2 W9 [: O' u) ?$ {0 ^& b* y                }" {  P% w3 n! H# K

8 q; F8 w/ Y" M, K2 P! B! S4 Z  i0 D                output >>= 8;2 ]* T+ G: l1 m- U, J
/ j# V  h9 \! k' B) K
                if( nFilterType == 1 ) {$ _% E$ y! W4 c7 w! ?7 h: c* d5 T
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
& n* h' U# y5 T( U+ ~                        output = (lowpass_filter[0]+output)/2;+ F& b. v! }; N
                        lowpass_filter[0] = output;
! E, c* o3 |$ e" O# A& `) h, L                } else if( nFilterType == 2 ) {4 |3 z( b' g5 t, C, \7 l
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)+ p  r7 q) k) l+ V2 b8 T% I9 B$ d
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
  O8 w$ X4 \2 a' f5 x/ m& G                        lowpass_filter[1] = lowpass_filter[0];
1 \0 j2 w1 D' f. ]                        lowpass_filter[0] = output;5 O& f+ g; ]. \% J" s1 K0 S) _
                } else if( nFilterType == 3 ) {8 w! [9 u4 g: l* x" D9 h
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)* s( \! D" E0 e! C; L
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
: @0 F4 Z+ O$ p+ i                        lowpass_filter[2] = lowpass_filter[1];
. u6 k+ j* H4 l2 C2 ?: e1 b                        lowpass_filter[1] = lowpass_filter[0];
) }) h- B6 G- U0 x  j- N                        lowpass_filter[0] = output;
5 Q2 j- g% I' }  M# w  X5 K                } else if( nFilterType == 4 ) {
) A, U) c1 x* w( i) R" j2 f                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)7 O0 a2 G1 D! v5 N- e! o
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
1 Y& N' |4 ~0 a, m8 S                        lowpass_filter[1] = lowpass_filter[0];
4 R  a; A- s" w6 ^  f- l                        lowpass_filter[0] = output;1 A2 |+ o- T# X' Z
                }( I9 S7 s$ K& Z/ h
2 s/ H) q9 }0 }7 z! ^
#if        0
2 S8 e3 a* Z) C+ v! A( {                // DC惉暘偺僇僢僩) v: K' p3 g: u
                {: i6 T2 G3 F7 s# p6 }, R
                static double ave = 0.0, max=0.0, min=0.0;
- m0 ]) C) q6 K                double delta;
# M, |3 _8 n9 S% ^                delta = (max-min)/32768.0;
, P+ {7 ?! L- A6 V                max -= delta;
& `: N# T% b* @6 o- ]& f0 e; a                min += delta;6 Q/ J  P3 n; b8 z7 j4 n: m, W, u
                if( output > max ) max = output;
8 r& q  k) g; L2 ]& k4 ^8 X                if( output < min ) min = output;5 @$ y( c( r3 M/ ]  F
                ave -= ave/1024.0;; E0 n$ s1 J9 l, Q6 }
                ave += (max+min)/2048.0;" R. c6 }% ~" O; j9 I( N
                output -= (INT)ave;3 f+ l% _1 p* ]6 ?
                }$ F3 G/ r+ c& j4 H% z1 ^
#endif
) R" w& z- ^& t! p#if        1) g3 E  Z% q  ]. H0 D/ j
                // DC惉暘偺僇僢僩(HPF TEST)8 o0 y: f( S1 q' \6 _# T
                {
$ m; t6 x# l! Y. V//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);2 @5 A5 Y/ c. I" l0 s9 K' f
                static        double        cutofftemp = (2.0*3.141592653579*40.0);, r7 t5 w2 g! k0 r
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
" k3 O/ M5 g# W2 ?! X                static        double        tmp = 0.0;* P, {9 a% C( F: b( G: P* N; v& m' X
                double        in, out;& Z( t  u/ B5 a* D  v% w

/ s0 Y. T% X4 L% D                in = (double)output;+ \9 _! J; D/ }$ P! B( H8 m5 F
                out = (in - tmp);. X* }$ _; G" z- c5 T6 j9 Z5 T
                tmp = tmp + cutoff * out;
8 ]& A, X& I) g
; v; {0 F* b/ e7 ?% a# x                output = (INT)out;
1 x( U/ ^' ~* o4 Y# j0 N" o                }
9 S$ o$ o- U( L- R9 z#endif
& v4 ]5 E* E' ]4 J$ P#if        0* u3 q9 h/ T1 X9 D& N
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
% V9 H$ O# [  Y/ o! L% i$ S8 @3 @, r                {
! S( C, T# ~& ~  x  t                INT        diff = abs(output-last_data);! G8 V: _5 x9 O! C" D# N* N
                if( diff > 0x4000 ) {
) D* U, g& K. V- T1 G; Y/ }) V8 O                        output /= 4;: S- `0 ?; F$ j" h$ O5 R. a( B9 r
                } else
0 A: d8 e( q7 u                if( diff > 0x3000 ) {
2 `/ D7 B: D- b- _2 S5 E                        output /= 3;
& i9 X8 h. K5 ~' w                } else
& F, o+ @5 z% F, U  Y* w                if( diff > 0x2000 ) {
( c9 p4 o* m& B" H* ^" e& S                        output /= 2;4 h8 }4 s1 G& a" ^) k3 Z: r
                }
( B/ Q. B, k2 E                last_data = output;) R( g' n, c6 E9 Q6 ]) v
                }5 x- k5 \1 P7 g# f- U
#endif
! T0 h* t  _% I                // Limit
' T& d  [% Y5 c  y                if( output > 0x7FFF ) {
9 Z) t! F' }$ V3 `( z                        output = 0x7FFF;* H" \3 {7 n+ X! q; z
                } else if( output < -0x8000 ) {
4 ]) a! P$ n0 E* ^, k$ l4 w* P                        output = -0x8000;4 u. ~. O& B8 o# o1 h* v
                }* X% |! s& P9 M- n  [

' u' u( f9 G% U  z  O  Q4 t" D                if( nBits != 8 ) {8 K; Q* L9 H3 s. ?
                        *(SHORT*)lpBuffer = (SHORT)output;4 E0 E8 a$ M4 M* @  h3 s" b
                        lpBuffer += sizeof(SHORT);
- ^  r# `5 ]( I                } else {' n: Y' U, R# e( M- A
                        *lpBuffer++ = (output>>8)^0x80;& M) B! @( l1 ^2 `8 v0 K' d2 T4 f7 S
                }1 N# |5 h, ^' H# }# O  _! }
4 \/ G  L3 @5 g! T' D0 Z& @
                if( nCcount < 0x0100 )' ]+ X4 K- m* l, o4 O) }: l
                        pSoundBuf[nCcount++] = (SHORT)output;% J8 L, a' t- [/ [8 ]

; O" Q" m6 N& s//                elapsedtime += cycle_rate;
; T1 ~  _7 k+ A1 Z) C                elapsed_time += cycle_rate;$ p: ~, n" O4 O+ f1 `
        }
" t/ ], K3 J1 f/ ~
) p" l  T, b; ^3 E2 u#if        1: s) Y( Y. @% ?; J* e1 k% Q1 C9 z+ R. {
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
# f1 M  L, T% i: ?5 W; Y1 c* P" i3 g                elapsed_time = nes->cpu->GetTotalCycles();
$ \. t. L$ [5 ]: j4 [$ k, t! Z        }$ K% h% d. Y0 P* y/ l
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
, j: Q! ^" i/ u5 O                elapsed_time = nes->cpu->GetTotalCycles();) e3 r5 g6 m7 ~2 W+ N6 \; m+ v$ J
        }
) e  M1 u1 t! ]- H8 T& r: g( {#else
2 k; _2 u5 p# J. J5 U        elapsed_time = nes->cpu->GetTotalCycles();' w: Y* O7 b) P; _
#endif
7 g4 O, R7 n# h: o. g4 ~( X5 }. |}% Q4 |( z2 m4 y- w# n- X! ?. x
( P* b4 g+ @, T
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
- a: j: |/ k, {, |* `: V9 @INT        APU::GetChannelFrequency( INT no )
. M. z& p" F. ?, j8 T, l+ |{
/ [* q% Z, t. |8 e6 {        if( !m_bMute[0] ), D3 U% y) t. ~
                return        0;- P0 s: V+ w- w% C6 T2 q! x
4 _# \- {* I& C0 v% J. k
        // Internal
7 J5 Y3 I5 @9 H: u& O. ?        if( no < 5 ) {
2 u( J5 d3 T; p2 R1 e) D$ {- H                return        m_bMute[no+1]?internal.GetFreq( no ):0;
. c, o/ ]" }! p- g; ~" x: b        }
3 j- E( `# w4 l/ |) f; ]4 k        // VRC6
, ^8 K( Q9 m, k& s* x, ?        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
8 Z4 o. F$ W8 S" S* p                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;, y  B4 I3 @9 G3 B2 z) ?
        }8 `3 U! }, e' D* @9 @) i' J) Y, W
        // FDS$ m/ Q# T# j7 p8 {. {/ l
        if( (exsound_select & 0x04) && no == 0x300 ) {, W0 T# D: A6 u! Y  J
                return        m_bMute[6]?fds.GetFreq( 0 ):0;( [: e# ?! G/ G0 `+ @* C" q( ~
        }; A" }% h+ ]7 H2 b
        // MMC5- z% ]3 L/ Y/ `3 d
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {6 ^' g! F: b1 ^  W5 _6 O) U
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;* A2 }! |( W; u4 w" H
        }
* S6 l4 a2 Q: T6 g1 \' {        // N106& L$ [3 N8 S1 i7 H; G. c/ j; H
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
5 h: s" ]; w5 ?1 g" r6 C( B                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
; _$ C  B  V3 d- S, O- B7 E6 e( a        }
. o, X6 z$ c+ z        // FME7$ ?: v; L, ?7 a! l( v; `
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {8 j9 e  _3 c4 O7 t
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
# ^% N8 P% g9 j9 g        }. Q6 t6 T( v" L$ U
        // VRC7. C4 H* z4 t( k& r+ t  J
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
1 S  g6 j& L! u                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
$ [0 S5 j# @7 P7 Y% X        }
4 U' r; }; r2 x: x        return        0;
- m; E8 }# a0 c! f}3 B& ?# u5 S7 V: c

1 V5 }7 t6 o# E4 D// State Save/Load8 ?' o& Q# R$ ~
void        APU::SaveState( LPBYTE p )5 g: }1 Y) z1 y! l4 @. d, n3 b
{
# x# l2 W# D8 s#ifdef        _DEBUG
. H; k$ _$ d: }& L- V+ NLPBYTE        pold = p;
: s8 p) H4 _& g  z6 u9 s#endif
9 b5 d1 z4 ]6 u% A5 h: T5 o$ u- }6 h1 G6 E- p/ L
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞0 i! ^" _5 f3 u* w- \- n
        QueueFlush();, P6 p4 @8 D9 z6 r2 K
/ Q" n9 c+ ]; l4 `# M0 ]! E$ P
        internal.SaveState( p );  }# I( ]% N# |' I+ a1 v
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding& [! Y% h- e  e( B$ K4 L0 ^: b
( X2 M6 O0 t: s9 a# a
        // VRC64 C! i/ p- R& O+ T; e
        if( exsound_select & 0x01 ) {
# a6 K7 g. Y8 A" Y0 b: j                vrc6.SaveState( p );
9 }6 v3 F3 b6 {, _3 p4 b- X                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding% ^: B8 x  _/ z- g; v( j# z
        }* N9 D" f1 r1 ]0 G1 @- E
        // VRC7 (not support)6 G7 n9 n7 ?3 N
        if( exsound_select & 0x02 ) {, x7 V& R7 C( i9 K
                vrc7.SaveState( p );  W2 t! I, _% I: M
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding3 x, T3 e% z7 K$ s5 I9 b) m
        }8 z( X( i4 h; H1 p- ~
        // FDS$ d/ n) U' `' f! `4 c5 t# e
        if( exsound_select & 0x04 ) {: n- S2 b' D# s1 \' `! M
                fds.SaveState( p );& N9 h5 ]" `! r! h' U
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding* f+ Q6 T9 t5 d9 H; ~3 @/ @
        }8 B1 k6 u% Z: G/ S( h
        // MMC5
* c7 c: ~  Y/ t5 J        if( exsound_select & 0x08 ) {! t6 B3 O) e0 M4 |% f
                mmc5.SaveState( p );
" d; N4 T0 H) \5 U$ Z$ s6 M" W, p0 d                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
* x+ ~. ^) }  |1 o0 v" \; U0 M2 S5 J( E( V        }
, o' C( s* J- M3 M+ v) X& F4 [        // N106
/ u; d) `8 ?/ M+ f7 B8 q6 C        if( exsound_select & 0x10 ) {
  ]# c* \% e9 H2 ^                n106.SaveState( p );
1 z5 ^0 b; G2 @9 _4 a- F                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding3 _8 D6 A  w' }
        }
" `. m/ u" D) Q- a5 v+ m. u1 v' Y        // FME7
% L, ?; ?6 X( w- L: H; H        if( exsound_select & 0x20 ) {
. P" J6 _$ A8 S. V2 k3 ~. q0 \                fme7.SaveState( p );
# c: P! g- T$ s( y- v7 h7 [, q                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding+ ?* e3 |' f& C: ]7 S8 h
        }. ^$ z4 M) A: R* E$ w% A9 m

& P8 B$ J4 \5 L7 ]. C( n#ifdef        _DEBUG
. }" K# u% E1 _. l! U( YDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );7 }: w" n/ W# e1 V" U- |
#endif5 u7 v/ S0 B- t$ V8 r( _' y: c
}
) w4 T" @4 h5 ?! s. t! H
( p1 h( X3 z9 S+ ~void        APU::LoadState( LPBYTE p )
3 b& g/ X: e8 G* X1 ~{: D+ F! g4 q8 W' v! k* @) U
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡6 M' N1 D5 C, e, ~6 @* M
        QueueClear();
/ v" c5 F8 G* R& I# k
2 O% W' s$ m, U: `        internal.LoadState( p );/ |, b) {" C' j* F# y
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
7 s: r" k1 U6 Y
& h$ ~" _8 g" x7 i3 m( i" V        // VRC68 y, I) `0 V( o9 H1 }  p
        if( exsound_select & 0x01 ) {
0 `0 n4 Q2 V! R! H                vrc6.LoadState( p );: ^% O4 j- `: B
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
: p+ ~+ X/ h: z3 m7 I+ ?# {        }
2 s! e  F0 j" S  ^: N  h5 _        // VRC7 (not support)
; g) S2 [8 G! I        if( exsound_select & 0x02 ) {
/ y, Y( T; A# a                vrc7.LoadState( p );
0 Y$ Q* P; D/ Z8 e) i                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding( ]; n; }9 R, x- S; r: m
        }) }1 k2 q9 h, v
        // FDS
+ j, ?; ~8 j& E' A1 D  a        if( exsound_select & 0x04 ) {( C, P9 Z; x  J4 k& m5 }3 n
                fds.LoadState( p );
5 y* r% [9 X. o8 b2 m                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
( }9 f3 Q) Y) g/ t% P        }
  \3 A2 g5 U) b6 l1 s        // MMC5
  o6 S+ J! @9 |0 Z% i        if( exsound_select & 0x08 ) {) a/ p2 I2 k. g
                mmc5.LoadState( p );
/ p: w0 q/ R* }6 S" d                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding3 d* H/ v8 R7 b/ P; K
        }
* g0 W$ Y2 D1 B9 F+ L        // N106
  T: R* |1 a6 U) p        if( exsound_select & 0x10 ) {
6 U% P2 t' G5 _+ H                n106.LoadState( p );) w; w2 i/ ^- T. t1 n6 J9 W
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding+ ]& H' B. |. D, o
        }
/ q, L0 B4 [& |' e* J9 Q        // FME71 K% t2 O# T- C- G6 G
        if( exsound_select & 0x20 ) {
) F6 c+ y" m  H                fme7.LoadState( p );
% ?4 u8 f. d" D6 x+ p+ p                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
( ]* `2 I$ A5 |* e' X! A. t' w        }
7 F9 O% d0 c. G$ k7 m" o& ^}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
* {# t9 [: v6 t可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
2 J" S6 H2 K5 y感激不尽~~

" g" y6 r' @4 R, m( q0 G恩 我對模擬器不是很有研究,
& d' r' k( X7 W3 Q" o- ~0 U雖然要了解源碼內容,可能不是很困難,
; b7 e. z  M( A. k, A7 P  z8 d不過還是要花時間,個人目前蠻忙碌的。
1 n/ e  D6 S3 |6 D, T- B; L0 B
  ^0 z) h' |' P" x! @3 \# T0 U給你一個朋友的MSN,你可以跟他討論看看,# W; F# v9 c8 G# d
他本身是程式設計師,也對FC模擬器很有興趣。
, J: Y6 K4 u. V% J" W% ]2 \% f1 f: p- }2 D
MSN我就PM到你的信箱了。: x. S2 k' g6 s3 w3 c0 y: i. t: j

# k/ m) W7 P" J希望你能有所得。

该用户从未签到

 楼主| 发表于 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 q) D7 B6 R0 |呵…… 谢过团长大人~~
# _! V. y0 c3 {+ `* }( V$ U
. }+ |% e- C% u, m& i  f- j5 L, C
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 * c9 K8 ~& D% t# @2 [  k% w6 u
团长的朋友都是神,那团长就是神的boss。
& c6 x1 W. f) Q& @
哈 不敢當,我只是個平凡人,: d' }$ T- G6 A/ b: R" H& s
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
* V& N3 z/ i7 E% fZYH
, }1 E: u- f) M0 A, Q  tQQ:414734306) i# f0 ]3 y9 |. @# X  x: ?
Mail:zyh-01@126.com% E/ l% E7 |* r
' t: ?1 q9 s  H
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
1 h  c, @5 G& p& Z! X4 e6 d再次对团长大人和悠悠哥的无私帮助表示感谢~~

1 t- ?& T+ o( V0 U& e6 y( b' I不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-2-7 20:27 , Processed in 1.091797 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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