EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
" d$ b) N$ S  H楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~4 W& Z$ t) o+ k# t9 p6 l
这里有相应的模拟器源码,就当送给大侠了~~
! U- [& X* s. g5 J5 A  n& Fhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 % G# f- d1 m9 X- y, G
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。3 i! }2 r; I" g# [
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~/ J% T" p( q8 i8 Z- T& k, i
这里有相应的模拟器源码,就当送给大侠 ...

* d/ `* ?# F2 Q9 E- u聲音部分(Audoi Process Unit = APU):
2 O7 H1 s* O' f. d8 N% }4 t1 W.\NES\APU.cpp( [) A4 ], t" A% {
.\NES\APU.h$ u4 V7 C* D/ p4 h% g/ J* T

! ~, N# V# c6 Z5 n* Z( e& C, Y$ I2 }6 j9 V' Q! W: k0 h# C7 \0 @
影像處理部份(Picture Processing Unit = PPU):7 u8 y7 r& O( J! q: p6 X" ?
.\NES\PPU.cpp/ m- O: _9 D2 A3 h& F. r! ~
.\NES\PPU.h
  M9 E: `) ~( W! j2 L0 i7 w( F
2 D+ ?) s- R: M2 }8 w如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
) h' ?7 w" {, l$ ~( Y1 f/ ?& F5 Z感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:. `  E9 I* X$ v7 s# e- ~
(由于很多专用术语和算法机理都不明白,所以看不大懂……)7 X% Y/ p0 D) C# l1 b7 ?! Y; y3 e1 o& [
//////////////////////////////////////////////////////////////////////////
8 S) ]) g/ V% _: q+ I5 S//                                                                      //
0 t1 i) }+ s- L# R$ M1 C//      NES APU core                                                    //, i5 O" c8 }8 z" g, O8 k
//                                                           Norix      //
( M) h0 d% L9 b  F; t7 o//                                               written     2002/06/27 //  N* Y3 s' w+ q
//                                               last modify ----/--/-- //2 i4 z; F7 H' E% P( [
//////////////////////////////////////////////////////////////////////////( D$ Q+ [6 u: ~8 F$ W  I7 z  f
#include "DebugOut.h"( T2 Y; x4 c% k: W9 f3 e! t
#include "App.h"4 k! X% v9 ?0 q& d, S' c; U3 H: F
#include "Config.h"6 C- V, _2 L" v% Z, F

0 ~, L- `" m! g8 r! v) F) h1 x#include "nes.h"3 _* I9 M  H" F$ ]" n% i
#include "mmu.h"
/ r- L+ x: y- e% A1 _#include "cpu.h"" s! h( P3 G( c  g% _9 S* B# e6 j
#include "ppu.h"
) J6 @8 U$ H: D7 J#include "rom.h"; W% \5 Z) c0 f# C! `1 B8 t4 @
#include "apu.h", a$ |4 v, Y* m1 t

; ]0 H- {# T, o: I// Volume adjust
* W0 I0 T+ y% w  e! V5 A% `( P// Internal sounds
; N( W- `9 R) q#define        RECTANGLE_VOL        (0x0F0)  m9 E: x. s  K  a& j& u5 G: v" ~' C" D
#define        TRIANGLE_VOL        (0x130)
- w) V& c% v" P/ a, m7 h3 B( k& d( H#define        NOISE_VOL        (0x0C0)0 i/ D8 N) y8 d2 v: E& n
#define        DPCM_VOL        (0x0F0)
# t2 g+ S/ q7 z1 |% i* K5 u+ c// Extra sounds
% p5 A$ ~3 t4 V#define        VRC6_VOL        (0x0F0). b/ A1 {! K# s7 p( |6 P( J
#define        VRC7_VOL        (0x130)2 p) A2 G' A( `
#define        FDS_VOL                (0x0F0)
; h* Y* e2 Q; }1 @#define        MMC5_VOL        (0x0F0)# H3 M( J* j; J$ `3 [' z
#define        N106_VOL        (0x088). D  W; m9 q+ |" n
#define        FME7_VOL        (0x130)& L( F0 ]7 e* ^
8 v, l0 l/ E9 M/ h0 _
APU::APU( NES* parent )
! o- W3 i: R* u9 ^) y) x$ `{& e  y' _% d# F- g( [3 `
        exsound_select = 0;) ]1 \0 [5 U+ L, n. n+ Z5 o
/ B7 i! w% C% t0 }4 F, q) D
        nes = parent;; |$ l& O$ C, T
        internal.SetParent( parent );* t( V' ], S4 Z) K% }" c

  [7 o' L5 ]  `. c        last_data = last_diff = 0;
. Q7 O! R( ]9 Y! }+ A8 v
% h" V; h5 L; [7 x3 e        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
2 ^! O" A) s: F% ?2 d1 Q& a( V8 N) i- ?5 Y7 d3 u0 [. I$ C2 y& h
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );, r  |% @/ s. I1 q# v
        ZEROMEMORY( &queue, sizeof(queue) );) l+ o6 v, m* Y9 T7 Z9 m" i" x
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
: _- T$ H" V0 r
  c, [6 g' c& Z/ w7 T, A% r        for( INT i = 0; i < 16; i++ ) {) d+ |% F. f1 v" c) ]7 L' K2 f
                m_bMute = TRUE;
# ]% e% X+ y" g/ L+ T        }- N, f. `) `' ?
}
) x  S( x. X) s( M4 ]6 @- D3 i
) y  I1 K4 r; U" z- aAPU::~APU()# b* y! T: X8 k5 `  p8 m
{: V! W6 y# o# ^0 T5 |
}' p3 U: a, _( {: F/ ]# l" O
4 r0 T& o; j7 }
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )' i7 e4 r/ \0 M. ~
{# I  b4 K* F& D7 [9 M
        queue.data[queue.wrptr].time = writetime;- [  E+ i6 g4 K
        queue.data[queue.wrptr].addr = addr;9 l1 Z2 C8 W2 W7 N$ I7 r- E4 W2 {
        queue.data[queue.wrptr].data = data;
( k, Y; U) {" \        queue.wrptr++;
- {1 d& C1 J5 ]- ~6 Z        queue.wrptr&=QUEUE_LENGTH-1;
/ d- a4 ^8 Y7 M# f: H; d        if( queue.wrptr == queue.rdptr ) {/ s8 p0 n3 c% C; K. [
                DEBUGOUT( "queue overflow.\n" );# @5 w: a' B$ x
        }9 Y( L# H& M2 \- `
}
- m6 H) k. z( U2 D" r  l9 }; {' v9 a
9 k) w% F+ R! ?  ?* ZBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret ); W( C: K. c% ^2 p$ S
{- `$ i9 X  ~1 k
        if( queue.wrptr == queue.rdptr ) {
  W7 |# _2 g2 A3 i) B) \( m                return        FALSE;4 G2 J% ]5 \1 a2 O
        }8 Z) w- z8 n6 M. j6 R
        if( queue.data[queue.rdptr].time <= writetime ) {9 k# o8 B( B! r  }4 q
                ret = queue.data[queue.rdptr];; O0 D( V+ e( o! ^
                queue.rdptr++;
$ E7 p9 Q5 x8 P+ ~& g. i+ n                queue.rdptr&=QUEUE_LENGTH-1;
& `1 e/ m  ]. p5 Z# L4 y                return        TRUE;
: O( b; J! o" J" U        }& m& G# d/ C6 y& W
        return        FALSE;9 r7 S9 t' r1 B" p) }6 P
}  U- M, g. }& \' x( ?1 O
. q! @9 y' \' H5 \
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
/ q5 w( Z4 g/ @{
/ J4 u. I/ Q- @- k0 I9 a" e        exqueue.data[exqueue.wrptr].time = writetime;7 u3 E* g: J  h  e- |; h2 J
        exqueue.data[exqueue.wrptr].addr = addr;4 j7 J2 H) E, {# }# _
        exqueue.data[exqueue.wrptr].data = data;
; @; H: u# j2 W5 T        exqueue.wrptr++;% K8 w( o& q0 K
        exqueue.wrptr&=QUEUE_LENGTH-1;: p& n0 V; t6 E* j7 y
        if( exqueue.wrptr == exqueue.rdptr ) {1 x, {% z9 z9 @1 O3 e
                DEBUGOUT( "exqueue overflow.\n" );: \# o7 f" V! `0 c% k
        }; n" f% e2 b% X, r& T' ^# x
}
0 Z3 q' ?+ O8 {; |0 i" A+ p( I- N% R  v6 q$ \) |& B. _: k
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )+ {$ r/ m, x  F+ f% i0 h
{
& v1 I  P2 e5 X. b& d$ V7 C        if( exqueue.wrptr == exqueue.rdptr ) {: \4 s/ _' r! A! L" c# D7 M, n; B
                return        FALSE;
1 ~- o4 r  M$ Y/ T* N        }
' ]! D7 g  B- y( {        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
" e& b* E# d$ j# o6 {; d- J                ret = exqueue.data[exqueue.rdptr];
2 T( z/ f  o# X                exqueue.rdptr++;4 n' w1 o% @1 q% h( F5 m
                exqueue.rdptr&=QUEUE_LENGTH-1;8 Q/ H5 [& `: T
                return        TRUE;
& P& ~1 Q$ {0 @. d        }$ j/ K) V' O% B* U# d$ Y& K( q
        return        FALSE;
6 B4 J# v4 I& A}
+ G; A" T6 C; v$ L9 L4 o* }/ o; Z5 Q
void        APU::QueueClear()
( x, O/ u) X% H' I) w4 `{' d: Y% L8 @6 N) K$ m3 s
        ZEROMEMORY( &queue, sizeof(queue) );' {) ^- p1 t) ^: G9 N" F4 O. v
        ZEROMEMORY( &exqueue, sizeof(exqueue) );! [* r6 P6 {  b
}+ s) B8 n; n2 E1 S
3 z/ e3 P' H! U' ^. C( Q* `- A6 C
void        APU::QueueFlush()  h% P0 r+ k/ u' i# g9 ]) i
{  z# v! g+ J- d* A$ @8 G  U
        while( queue.wrptr != queue.rdptr ) {  U! h& s; n  u- R% j, ^% |! W5 c4 b
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
$ k8 T# ^; u$ z8 f! ~; S6 N                queue.rdptr++;3 }; I+ u% e9 D% X) J( n* g  a
                queue.rdptr&=QUEUE_LENGTH-1;
& b5 P/ ~8 i9 G5 G6 J        }) ^# m9 k8 A1 A0 o
6 N: q0 m- L! Y0 ^! a
        while( exqueue.wrptr != exqueue.rdptr ) {& V* ~# E) _5 }! l8 q
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );# G5 x& Y  c2 u9 N* z) K
                exqueue.rdptr++;( b6 b, f/ V/ A/ b2 O8 k8 G% q
                exqueue.rdptr&=QUEUE_LENGTH-1;" T$ X9 f6 S( C1 t
        }( y9 [- D5 K# D' c- M  D
}. p. K* b# S+ X3 e: [" V

! S! K% Q) [$ r- j0 n, [& C# tvoid        APU::SoundSetup()
( I% u$ c  |9 K  H8 t{
, \9 O# J6 w7 L9 s6 \% X" K3 `        FLOAT        fClock = nes->nescfg->CpuClock;- N/ R% E/ g/ Y  k9 N7 Y
        INT        nRate = (INT)Config.sound.nRate;  n2 f  z9 k$ k. H! A
        internal.Setup( fClock, nRate );
& F8 U1 F/ T; {        vrc6.Setup( fClock, nRate );- U& x+ m4 t/ T
        vrc7.Setup( fClock, nRate );4 [( {' g9 G' w% s
        mmc5.Setup( fClock, nRate );
& t  M5 @' I/ E& y. g2 p        fds.Setup ( fClock, nRate );( I9 y8 p/ h- _) [& F7 y
        n106.Setup( fClock, nRate );
0 t' W. O4 m. H* h        fme7.Setup( fClock, nRate );
; j7 r+ ~+ Y/ c. C}
" Y( r& T: _; |/ s  o; [; s9 M% b: A4 T4 r
void        APU::Reset()( l+ \) i# ]/ E+ @. J
{8 s: F0 d. u' N! h1 M! }
        ZEROMEMORY( &queue, sizeof(queue) );
8 s# E: A+ ]& X0 K+ w! ?" u        ZEROMEMORY( &exqueue, sizeof(exqueue) );
  E8 d7 U+ C0 m& L
- o% h% h0 g4 i6 G" j" @        elapsed_time = 0;( x. F. s+ @6 N$ Z4 i3 T
6 i7 e: E8 x* Q4 [: i$ R
        FLOAT        fClock = nes->nescfg->CpuClock;
& |8 }# K7 R5 m# O. y  U  R        INT        nRate = (INT)Config.sound.nRate;: S5 P' c" ^5 C
        internal.Reset( fClock, nRate );
2 G" {; k/ @3 \5 y& D- R, ]        vrc6.Reset( fClock, nRate );
4 E2 m6 W. Q/ [        vrc7.Reset( fClock, nRate );4 ]+ p) B+ G, u) J$ F6 y0 B
        mmc5.Reset( fClock, nRate );2 j: \% g& q5 e3 Z
        fds.Reset ( fClock, nRate );
# I9 i8 F2 m( y6 B  I        n106.Reset( fClock, nRate );2 l7 R4 g+ D* f4 m
        fme7.Reset( fClock, nRate );) Z$ b3 B1 F& L  Q' X
0 u& r/ o& H  {/ Q6 ^
        SoundSetup();/ E1 E# J* a& @$ S$ l' u
}
4 u6 {+ E" s" ?& S7 q$ m* y4 p" a7 f9 @0 B8 z
void        APU::SelectExSound( BYTE data )
$ P$ J9 h9 z+ ^. j1 j; e{5 T  f0 J& g' o
        exsound_select = data;
, N, {6 e' ^" u2 T}
3 G) k4 ?( Y1 A! T( _' _& e& O4 {0 ^0 e
BYTE        APU::Read( WORD addr )
9 {7 X3 a2 C) P' z1 I! k{
- M+ m( m' |  K( m        return        internal.SyncRead( addr );$ Q- B' o# n& h0 y& H
}2 C/ B) t! L. x. m- X1 G

" Z/ U1 u1 _  J) n; K8 ~void        APU::Write( WORD addr, BYTE data )
+ p- q+ @- \, L/ H{. e- c5 C/ B. a- L0 [4 ~( [# O6 G
        // $4018偼VirtuaNES屌桳億乕僩$ e$ B3 s5 ]. I  o
        if( addr >= 0x4000 && addr <= 0x401F ) {" H. Y: e& ~* L
                internal.SyncWrite( addr, data );6 |4 v0 O+ y) _5 }" N; @* O
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );2 G6 I. z5 N* |- l1 ]- f! I! Y. p
        }
! `9 a4 a$ z- p6 B, n}
& q5 {+ h( c; c' e! y! Z3 X) y; z0 h
& W, u0 w1 s; oBYTE        APU::ExRead( WORD addr )
% F7 h9 c' @  ]3 d( D1 f) o{1 R% {: w) e- N$ x  j4 }3 s
BYTE        data = 0;
9 n' H3 K/ I* w- o# N4 _
8 ?# V& m3 d2 u  A* d, r  ?        if( exsound_select & 0x10 ) {
8 B5 e$ ]; z+ T8 Q( B  `                if( addr == 0x4800 ) {
/ u7 T1 }8 n! ^* `3 D) `# H9 l; S                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
$ V7 `6 W4 l' P% S& V: ]                }
1 ~' x* E2 p! ?, r1 q' U        }% d. }" S' U+ C8 V1 l! ^
        if( exsound_select & 0x04 ) {+ f2 w3 f: y5 J. S7 E
                if( addr >= 0x4040 && addr < 0x4100 ) {
5 {2 F! a  T: L; V2 `                        data = fds.SyncRead( addr );
( C4 e  U. Z! k7 `9 S) M9 m: c                }* Y. ]+ d* b7 c; P& t1 U
        }5 E, n$ _) o0 C# @% M: Z
        if( exsound_select & 0x08 ) {$ P6 N, o/ r/ a/ X3 |. O2 L3 D% e! U
                if( addr >= 0x5000 && addr <= 0x5015 ) {8 L" P" W( r+ a" k  E( \6 v
                        data = mmc5.SyncRead( addr );
" H1 H- J7 V' s                }
# P/ @3 G! t' z( A6 n        }
) q0 R4 ^; i7 B5 h; T  y' V# c1 G* i4 F9 E
        return        data;
' V& V! q( B5 C/ x}
: I' ]5 C' k  O; y  \+ \' @6 x. z; g: ?/ k7 g, C: T7 p
void        APU::ExWrite( WORD addr, BYTE data )
- h7 X. K7 G! A{
# M6 C' o( p% [% q2 {        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );- l( A( v7 G$ F( v  e8 C$ o

* T: S, \' Q9 W! E  F2 j' s9 S        if( exsound_select & 0x04 ) {
" w6 L  c" e% h                if( addr >= 0x4040 && addr < 0x4100 ) {" P# s) a. p& Q' \% Z, u( I
                        fds.SyncWrite( addr, data );
2 S* P6 [5 ^" }2 |8 `) ^                }% W7 u/ B- s8 I% o3 [" x, t. z
        }
5 Q% Y( v* j4 l- h0 d% |! R( W0 q" O7 \5 t+ |* r1 k7 ^
        if( exsound_select & 0x08 ) {) [; g6 H9 T9 @. S" u* m
                if( addr >= 0x5000 && addr <= 0x5015 ) {
* D: R4 [! z: |! y  @5 t                        mmc5.SyncWrite( addr, data );7 s6 @: Y4 X* |. R* `
                }
) F3 ^# r2 U3 l" E- A' B        }
3 ~: G  K; K. S* Q& A}8 |* }0 c1 L/ p1 f6 {2 ]6 n
6 [. a9 m2 x/ i( P  |4 m
void        APU::Sync()/ t" P+ [& e4 O
{+ n5 D( o9 ^. O( I) @
}
, a  n/ u5 m! S# M, P. W' J. Y* y- M- O; S8 d
void        APU::SyncDPCM( INT cycles )
' J+ T) P6 L3 F5 }$ s; R- X9 Q{
+ s/ f+ D: o% j, W  }        internal.Sync( cycles );
) q# t% C* B6 }" e& Y: l! D6 V. ]1 a1 w: p4 Z1 b  e& N' P
        if( exsound_select & 0x04 ) {( f" v& f8 O- _  i2 U$ V, g8 b
                fds.Sync( cycles );: P. v6 ]5 X; d0 b- e4 b
        }9 R, H( J& O3 Q  f" @" P. T
        if( exsound_select & 0x08 ) {# S- E5 P' _6 U+ h1 D
                mmc5.Sync( cycles );% E& N% R1 r% g4 W. W& [" v  f
        }. C+ \; u5 d$ j
}- Q' I/ @+ D( o0 z

% H6 _# r9 }4 @1 B1 }void        APU::WriteProcess( WORD addr, BYTE data )! j3 l6 S  T% D" t2 K1 I, j2 J
{
1 B# [. W4 K) _3 z        // $4018偼VirtuaNES屌桳億乕僩
7 ~2 O# C/ ^5 q" Y7 \: M' i  ^        if( addr >= 0x4000 && addr <= 0x401F ) {& }9 ]/ D& \$ v: ?8 a( V" g
                internal.Write( addr, data );
/ M' U3 i5 ]# j& _        }
$ n  u/ ]4 r4 v2 j  ~( F}
& k; C7 @1 s: o% A; c' D  g) }$ m- E' I3 w* o
void        APU::WriteExProcess( WORD addr, BYTE data )
, ]2 O$ Z2 a! _2 w{
4 C5 R8 k! ]3 Q) \        if( exsound_select & 0x01 ) {" z: b( I8 u' ~) u! `! K( M- @; g
                vrc6.Write( addr, data );
- v7 h+ ^. d4 q5 e4 @+ @, d$ q) f        }
# i5 o0 f: Y$ ~        if( exsound_select & 0x02 ) {  d6 ?  L& }. {
                vrc7.Write( addr, data );% v) q4 |) J3 X5 E8 T
        }" i# P+ j& E3 G3 h% n- e
        if( exsound_select & 0x04 ) {3 R: n; K# J% `; \+ O/ ?) }% }
                fds.Write( addr, data );
/ [# h. D' ]2 V: I        }: Y: h+ E0 T, k  R
        if( exsound_select & 0x08 ) {
6 R, s- X/ {/ N- d$ s0 p( g- J+ M1 B1 o                mmc5.Write( addr, data );
! D# r! Q8 f: ~0 [' }        }6 L% {$ v+ n$ n; l8 h0 z
        if( exsound_select & 0x10 ) {4 t8 ?" q" J7 |7 z8 a
                if( addr == 0x0000 ) {2 F: Y+ N- o+ c) j
                        BYTE        dummy = n106.Read( addr );
( k/ G% x' _) y. o/ w1 a                } else {# U; \, H# D1 L/ ^# V; f) D
                        n106.Write( addr, data );
. T+ e( S( ?8 K+ P- T5 o/ b0 a                }* ^2 A1 P4 U' E0 W. ?# D0 Q
        }" ]0 y$ F3 ]; q7 t6 p9 G! L) Y9 R
        if( exsound_select & 0x20 ) {: B2 V. Y% b: e5 W/ t/ c
                fme7.Write( addr, data );' S% x# n7 `& Y% i9 s
        }  v0 ^$ j/ Y: J  h0 {( p
}
( C' x- O* |# z2 z' K9 O, F  T" ~8 e7 G- A: p0 T# \# c) F
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )3 T3 [+ h: B* n2 i% B
{
3 m1 i0 z5 p: c3 T- F+ h0 u; xINT        nBits = Config.sound.nBits;
) m" f& c- \' T: N# i+ qDWORD        dwLength = dwSize / (nBits/8);
; z! [( L, ^% a! X2 p, \INT        output;4 V. e) \$ r2 S6 d. W4 k3 i0 d
QUEUEDATA q;% S8 g1 ~' d5 n0 [, N* R& Y
DWORD        writetime;: o% i7 u7 X# v  W2 g: V

- E3 x' U) ]1 RLPSHORT        pSoundBuf = m_SoundBuffer;
$ s( @+ M, y* oINT        nCcount = 0;
3 ]' l* ]/ x% q, U/ K' M
" p, H% w: a& }' ^) nINT        nFilterType = Config.sound.nFilterType;
( I9 ^" ^1 }# ~+ I( j8 o, `7 o+ l! o2 F+ a
        if( !Config.sound.bEnable ) {* n) ^5 g9 H( c8 [
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );, h# M+ }' x" u( P
                return;
) {# {5 W2 z3 y0 U8 x: Z        }
/ T7 z: q) L( \( f$ d4 }# g  R" y
$ t4 M. |. H/ s& L9 n. g) \        // Volume setup& ^- P: I3 N' U; ]: K# K
        //  0:Master. M& r: f1 _2 a8 |: _+ Z
        //  1:Rectangle 1
' f. Q4 i& g( q0 i0 x7 K* s9 r% N        //  2:Rectangle 2
4 E( B0 Q1 c( k        //  3:Triangle
9 o$ K+ z7 o7 i* Z        //  4:Noise0 \& g4 H1 o& A' Q- `; a- ?7 X
        //  5:DPCM
) w5 o! `1 o' H- S/ \        //  6:VRC6/ _3 n! I8 x& j5 e5 s9 L( W0 B
        //  7:VRC7* ^7 y$ f" T3 N7 a. z& k: P5 V3 T& l
        //  8:FDS+ m& C. T+ c4 w# G
        //  9:MMC5
7 Y" x0 {  [! o0 \        // 10:N106/ H9 U7 ]/ R3 Y# }6 M/ B, ^
        // 11:FME7+ d+ S5 t0 J5 i' C0 g
        INT        vol[24];
; i$ q1 p/ a6 w' g* c        BOOL*        bMute = m_bMute;
* `& T( g1 }3 f& m( N6 _        SHORT*        nVolume = Config.sound.nVolume;4 }2 z* Z$ |2 K( d. N5 C* a

1 A3 _4 H& f* F& t* m3 H$ ^        INT        nMasterVolume = bMute[0]?nVolume[0]:0;9 t# h" m) W* _, L& H: C

/ y! Z# d7 Z8 m! F8 Z4 z        // Internal) ^5 I5 a7 P6 T0 x- J
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
- j! m( W( T; U, G        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;0 n! J: U! u' ?. X
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
+ w% \; {/ u8 H* M4 q        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
" R/ c! T/ E' A+ q& u, |8 u        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
: [; J- C/ `& s  K+ e. ?; p+ I" ~" ~# d3 _# [" @3 w
        // VRC6$ A9 d5 K  ]; ?
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;+ U3 X! W2 z& j, z7 w5 K: y& g
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
; _/ B$ h  h, C& p, V$ a  N2 u        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
6 w2 f- o; L- c% b3 _$ p
  u) [1 u. J) M4 p7 l        // VRC7% D6 m* {5 k/ V) O4 |3 z
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;# e# s1 O+ p  v0 X. G/ u9 ^
5 s; ?. K% F& A/ F
        // FDS( ^3 G. Z# L. t: ?% N/ n
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
6 x3 c7 H% x+ c4 s" R% }9 c5 _
! v( Y2 i( ]% T: M3 t        // MMC5
& p; x) K" O1 v$ Q! |        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;- o( f3 k/ V2 ?# X
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;5 ^5 x7 F  Z- g9 m
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
$ D3 b3 G. i) h( Z
4 J/ [* {% u4 G* _        // N106
9 I& J: K4 ]) n% @+ Z        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ M" p/ W3 Q3 \& \: b& o" |: `
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
8 a" B5 R/ A! p- r5 f8 l        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;4 Z4 E$ |" n4 m& |4 m
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;6 r8 y/ W1 z( ^, W% B) z# K: _
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;) K  \+ N4 ~" c" p% G3 c) U/ U
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;, j+ c- R7 k7 n. K2 M
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ d8 W3 H6 u  Y  b1 a
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' w: D/ }5 H$ Z# Q3 s

- {. y4 J' p5 j+ p! G' l0 ]        // FME73 u. |7 |8 Q# W3 q% B: B
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;; J+ ?3 z8 J: N# O0 D3 R
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;0 n/ h- ?" _! E
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;- b* X6 A8 T8 T

, K- G& j0 s8 X0 L, G8 X//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;9 p8 _" |  G5 X" m+ _
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
/ K3 c7 v+ K3 L$ c8 k9 ?5 k; A1 r" r# p3 I& J8 P) X/ S
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
" K+ S, m3 ]2 A/ B4 L        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
( H2 o; {. O; Z/ m                QueueFlush();! P: }2 k+ ?+ c1 N+ i
        }
$ @& i' t- J, X# `. @6 [+ I* l
5 o( U& b& _0 s( X        while( dwLength-- ) {
; p) R  J- ]+ P/ M# T& J: @                writetime = (DWORD)elapsed_time;7 _. U/ U# w% ?) f8 f9 _8 u
* W# q- Q$ I7 x5 {$ c
                while( GetQueue( writetime, q ) ) {/ R2 K1 Q% R$ ^) |+ j: k' `
                        WriteProcess( q.addr, q.data );
: T' g; j* Q' v# F# F' o! }: E                }  k8 W# F/ U5 g4 H- Q6 }7 I
3 @' T" t( \4 U* f* ]
                while( GetExQueue( writetime, q ) ) {) a4 a+ ~  s. L
                        WriteExProcess( q.addr, q.data );- f7 o1 C: T$ {" q& `  q$ \
                }. j; q7 f0 B8 \
- j# C) z9 h7 h
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7# {( d4 D8 q# k" x* z
                output = 0;6 l2 L2 ]: l6 D/ h8 C9 l% l( ?
                output += internal.Process( 0 )*vol[0];' J, A- w/ B* [) _* f
                output += internal.Process( 1 )*vol[1];
9 C" h$ E$ Y& V5 n6 d5 z0 b: _                output += internal.Process( 2 )*vol[2];5 t; M- E8 G5 L9 |2 b# ^4 g7 x2 p4 }
                output += internal.Process( 3 )*vol[3];0 r9 q7 k; x( d/ Z! z
                output += internal.Process( 4 )*vol[4];" x8 t. l$ a2 X- W5 D5 H: D
7 z1 I$ J5 ^8 G, r# P9 a: h9 d; T7 v
                if( exsound_select & 0x01 ) {
, L' F/ @  f8 J4 \; M                        output += vrc6.Process( 0 )*vol[5];
5 O! V3 Z, c4 N3 [! ]' E/ ^- a                        output += vrc6.Process( 1 )*vol[6];
+ O! B7 I1 \2 ?6 n% j) {, ^                        output += vrc6.Process( 2 )*vol[7];
6 q" O- @* v* G  U' q+ J                }
( a: ^( S+ U7 L                if( exsound_select & 0x02 ) {
* D( ^: f! _5 I' f9 m' u6 o6 ~/ l                        output += vrc7.Process( 0 )*vol[8];
' ]: P# `9 w. g7 |) _2 ]8 o                }$ E3 F" f2 o. T6 C; ~. g. r
                if( exsound_select & 0x04 ) {; \. E* M$ F% X' g: ?: S8 O6 P6 D
                        output += fds.Process( 0 )*vol[9];
' {+ f" a9 y8 `                }, W/ T/ Y' d0 `' O. S7 R5 a
                if( exsound_select & 0x08 ) {
9 p" k, [" F+ L- l                        output += mmc5.Process( 0 )*vol[10];
8 J# V1 z! H* P: k% k                        output += mmc5.Process( 1 )*vol[11];8 }8 c3 a5 q) ?3 @( p/ a
                        output += mmc5.Process( 2 )*vol[12];
2 [# H6 ~( n" {( Q5 S                }9 U( ]% x1 b! ^. U
                if( exsound_select & 0x10 ) {" d0 W6 R- ]& ~) l( x3 r' F4 q" x
                        output += n106.Process( 0 )*vol[13];
, ?& n! S" r( l% e                        output += n106.Process( 1 )*vol[14];
- z1 @0 b" ]( w0 m( s# m                        output += n106.Process( 2 )*vol[15];
  S$ ]& d- e# }4 I8 g; l- }% S                        output += n106.Process( 3 )*vol[16];' S2 }4 ~5 p2 S9 y6 x/ ^4 O
                        output += n106.Process( 4 )*vol[17];' s. K1 f9 U$ N
                        output += n106.Process( 5 )*vol[18];
+ F) |: S+ R" w/ j                        output += n106.Process( 6 )*vol[19];( g0 K1 j8 O& W3 @) e+ s5 d8 l7 J
                        output += n106.Process( 7 )*vol[20];: G% ~! ^& Q! k
                }
% k7 K. E. E3 Q% X& G( w5 Z                if( exsound_select & 0x20 ) {
$ w* U/ N" v5 X- n4 w* ^  e# j  t' ~                        fme7.Process( 3 );        // Envelope & Noise& r9 {# a/ F/ w; @: g0 F9 i
                        output += fme7.Process( 0 )*vol[21];
, F0 c3 J5 Y$ r0 a/ ]                        output += fme7.Process( 1 )*vol[22];7 k1 M' [9 Y; ^8 L$ E' {9 }9 Z8 t
                        output += fme7.Process( 2 )*vol[23];4 Y6 G: c/ W" g( x: n& f6 p
                }* Q: |- o( F6 O* n& {

! r8 ^; `6 w. v- d3 k% s8 M- m                output >>= 8;
3 n  x& ~1 z  N5 l* i1 [
# x: h; M/ K) K! b# f5 y                if( nFilterType == 1 ) {
# l# o' l& Y4 E  T                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
( H3 K' W0 @2 i* O                        output = (lowpass_filter[0]+output)/2;
7 Z* f  F/ t# E" k                        lowpass_filter[0] = output;2 u* u1 p( S/ |+ D2 I& o: P
                } else if( nFilterType == 2 ) {
7 h- b8 C7 m* ^3 G- Y                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
% x3 V  g9 ^5 r- D  N  Y                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
8 L# o- v4 V' ?7 ?                        lowpass_filter[1] = lowpass_filter[0];  Z$ }8 p1 h' ]; c# c6 ]) V' D
                        lowpass_filter[0] = output;( ?( q* M. x, n2 y4 u
                } else if( nFilterType == 3 ) {
+ K' v7 y0 O. \: m, z; P                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)7 Q0 B0 Z0 i) y* W0 m% |
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
$ b! g5 e6 |3 i  W                        lowpass_filter[2] = lowpass_filter[1];3 d5 ^6 e6 L+ ]3 i
                        lowpass_filter[1] = lowpass_filter[0];1 J/ @8 V" v, T7 [
                        lowpass_filter[0] = output;5 }! Z  b2 l5 _) A5 S1 Y
                } else if( nFilterType == 4 ) {5 a' e5 j4 k/ y' o
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)% a7 h1 O/ n9 L* F4 M* [4 M
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;) X: g) e  b/ a. C+ Z% G+ a, W1 V
                        lowpass_filter[1] = lowpass_filter[0];0 W8 o2 v7 V  V+ W; ~5 p
                        lowpass_filter[0] = output;
: j! r9 l9 M# v' y# B                }
! s5 K( ^( R8 _' O  p( p. E. c0 `+ r$ u# X6 ?! i, F6 Y
#if        04 y( |- C) A% d! `* }
                // DC惉暘偺僇僢僩
8 [' \% W+ ~5 ?- o                {
' N: \6 r; U( X  e& x" e- C- S                static double ave = 0.0, max=0.0, min=0.0;2 F1 p2 F/ P) _: _* `9 q' D( u
                double delta;
$ p/ r7 V" r" b1 E                delta = (max-min)/32768.0;
. x' W! @! u2 t! r0 R6 Y                max -= delta;
7 {: s: f* q/ [- D. J5 h4 y8 j6 O                min += delta;% w: s+ {! p% M5 N
                if( output > max ) max = output;8 ]/ ^* s  H' n- L0 C
                if( output < min ) min = output;2 f8 @9 S0 J: q: x. M( d7 @9 R; g5 S
                ave -= ave/1024.0;
7 y; F; j! `4 X4 g4 a5 v/ z$ g* w0 S                ave += (max+min)/2048.0;) j# H" ^) v2 f5 Y2 j) E
                output -= (INT)ave;
8 u! q6 ]  x6 ^7 {, C' i                }) d/ i6 J% ?% g" l/ u
#endif. T1 S; T- m# H! u' @5 z% s/ p
#if        1
7 D1 {; z2 p) W0 ]                // DC惉暘偺僇僢僩(HPF TEST)
* v5 |' r# o  O                {2 e# ^& P" U4 V$ F# x, F
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);4 `4 d8 d/ _: I2 W2 `
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
# v; V+ k0 D6 J  O; \) @                double        cutoff = cutofftemp/(double)Config.sound.nRate;
3 c) x$ t/ u3 ~: c; r, I                static        double        tmp = 0.0;. }; h5 y9 G9 v9 I
                double        in, out;! z- o% c9 a" Z  o! D& y, [

- C% {! B) u; X! @* J& y: I4 O( a                in = (double)output;
, i" [5 U0 p' b1 K1 U0 d5 h                out = (in - tmp);
% W2 A* i) i3 X8 u: \8 i( t                tmp = tmp + cutoff * out;
# F' j* F6 @; d+ ]/ H$ Q( K8 K$ f. N% x
                output = (INT)out;
/ e/ Y9 l" P" X                }
: Z1 l0 g  @9 G#endif
( O+ t' g; p* i#if        0& `5 P8 ^! m8 ~! G1 i3 o& t/ _
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
- ~" K$ R) H6 N) D0 C                {
7 Z7 ?& s, J' J) _3 C0 S: T                INT        diff = abs(output-last_data);* S+ c  q0 x% S& \- t0 u; @8 g
                if( diff > 0x4000 ) {, n' z) [$ l: h4 [3 \: V/ R" N2 M9 k
                        output /= 4;
- P2 U8 u2 y- ]9 R4 l" P# `1 ]                } else ' V5 ]; [# p( z! s+ U/ J9 O7 U
                if( diff > 0x3000 ) {
, A# c! o. f# t                        output /= 3;
$ O9 u+ {/ Z7 ~% ^! v$ ^. i                } else
" N. Z& ]. h" f2 A2 \# [                if( diff > 0x2000 ) {+ w" T" S/ z1 Q& ^* |
                        output /= 2;
. ?( y: M2 E6 }: Q                }
# z' b* ^; R" d6 S& F4 Z                last_data = output;* O6 z( ~; K4 ~
                }
( X( L7 Q0 X7 n7 L' E#endif
6 C4 N. u. o8 ]* j4 y  h  e                // Limit
8 S! e% \/ ?% u1 A, \3 g                if( output > 0x7FFF ) {- h8 i4 v$ ^& m& k/ C' T: [" u* |
                        output = 0x7FFF;# c4 P  L" Y/ N  L1 Q, T- D+ C- l
                } else if( output < -0x8000 ) {
" u3 ~1 m, B# o                        output = -0x8000;# H% ]) T" j" _! }( p
                }
; r5 }) v/ _3 d& e
: H2 w9 s9 z) [" t0 o                if( nBits != 8 ) {" y3 N3 E8 T6 c5 b
                        *(SHORT*)lpBuffer = (SHORT)output;5 u  U" e0 D( D" `7 D: T
                        lpBuffer += sizeof(SHORT);  P; G9 r/ z$ a( Q7 _& h
                } else {  v5 \+ m7 ]# ]% z- K  Y
                        *lpBuffer++ = (output>>8)^0x80;
' N% B5 V8 u8 T9 @: V                }7 z1 u, S5 P+ Q+ }7 `
* C7 H* Y8 O: v8 J
                if( nCcount < 0x0100 )
$ M% ?6 g4 t( ]- O1 y2 M5 y; s- ]                        pSoundBuf[nCcount++] = (SHORT)output;
* U/ n  m1 D2 ?1 M4 ^5 I7 A9 G: ]  Y7 B
//                elapsedtime += cycle_rate;
/ N' y/ w3 {( K! e9 l: Y0 Y                elapsed_time += cycle_rate;/ }9 l1 Q8 e: `5 i) u  ?
        }
$ v7 c% K" p1 i# _: |& S8 O$ O) |+ x/ b0 ]
#if        1
  V: \9 x  e9 |1 B        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
2 W8 L9 {$ s0 C1 P7 f* k                elapsed_time = nes->cpu->GetTotalCycles();
4 P8 l# x$ D) {$ w$ C* g1 P        }
) T4 d9 z6 m4 G4 h        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
' {+ i3 x+ E1 P" c                elapsed_time = nes->cpu->GetTotalCycles();4 Y. F4 I# r. j: o8 r
        }" |) W3 m( C# U9 ^& u( F
#else' L3 f% U* G$ m
        elapsed_time = nes->cpu->GetTotalCycles();
6 S0 F6 a8 L% c! p% H5 k#endif
1 x/ k. i; w4 u& F% X0 ?}
- p8 j" e8 b4 e7 Y: `/ I' T2 O! a/ R4 E
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)" t( }. [0 o$ J$ q" S9 M8 E
INT        APU::GetChannelFrequency( INT no )
7 ^% K' J0 k2 [  v2 t! V* F3 t# q{6 o5 C( G' r  O0 o* D& k
        if( !m_bMute[0] )
8 g$ b6 S, g% n; n, I9 Z                return        0;5 k; Z4 b5 o! z' P" Q6 P+ R

9 c+ n8 f/ Q* ?# h& `        // Internal
. t; w) B; L4 r) ~# p. v, l5 b        if( no < 5 ) {
# h+ `; L4 \; V2 n9 u+ E6 E% _                return        m_bMute[no+1]?internal.GetFreq( no ):0;
" ^1 `* r9 m, ~( N4 r        }
6 D3 u+ c; X! V0 M4 {        // VRC6& U5 K2 T4 U2 T" k. g
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
/ R5 l& O4 p3 M3 [/ t+ |5 m                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;* C: I1 r) R0 c0 O
        }& i1 G+ Y2 Q6 R- Q/ C4 M
        // FDS
% V( @4 p, ^5 U/ d9 V- A; g        if( (exsound_select & 0x04) && no == 0x300 ) {
& j6 Z# q. O; q# k                return        m_bMute[6]?fds.GetFreq( 0 ):0;
! l- _) F& s' @7 B9 x        }
: o* f6 c% n8 u3 Y/ p  T        // MMC5
. R# V- u, B" M" v5 m7 C2 F- {        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
# Y5 K- M7 h) h7 a  ?* O& H. v; v                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;6 O$ A4 z: |6 c! v, \% C: z
        }
+ D  V# X3 x: _' G$ u6 l8 T        // N106# B+ u9 r& h) s; [! f8 r1 e) }
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
5 w" x# C9 S0 d. x: F                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
1 G" i* g, y7 E, y/ S1 |& t        }
( R9 a& ]/ T9 v& F        // FME7
- u: K$ x. q0 Z8 U' D5 F2 F        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
2 Q$ `  i0 N) ~2 [                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;, T$ }8 o7 P3 i0 M
        }
2 k3 |) G; Q' H7 m% S        // VRC7
9 |  \0 i5 N1 u9 H        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
8 ^7 F3 ^: Q  F/ @, `2 U                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;) R2 E2 e/ l7 G
        }4 v0 L% V5 j3 H8 @0 ^! s
        return        0;
  A7 F2 D5 F( L3 o$ D- |5 B}1 C3 \; c" D% y
1 Y# v# K; }. \. Q6 z. \
// State Save/Load0 R  S( J! x1 S% C
void        APU::SaveState( LPBYTE p )9 _5 F9 w2 R" G6 ?% d- o& I
{
7 w% d) p' I; ~9 p#ifdef        _DEBUG
6 X- C( r+ D7 q% MLPBYTE        pold = p;
6 g0 D! i: F( |' W$ @/ O#endif
* D% w' e( x0 k0 n
9 s, e8 E2 K# g) V+ Q) {        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
' H2 p& z; f9 E( T$ B. Q7 v4 W$ _        QueueFlush();
+ W4 g) B" {/ \7 o/ Y6 r7 z9 q* C# p7 N
# a4 `5 z$ D9 G: M, W. M" e        internal.SaveState( p );
" j5 u! K2 l5 I! X- J5 F3 @        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
9 D; [5 h1 z: {0 p4 Y' C& H' N  j% i9 h" r9 }9 C
        // VRC6
% A3 F1 L; g5 g8 ?$ @        if( exsound_select & 0x01 ) {
9 ~7 n" `" E9 r, z& k                vrc6.SaveState( p );
& k6 ?; Y6 u% x9 O8 ~' o5 H" B3 l                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
# b7 W4 T( S8 R0 T        }. r/ z& e; ~, b" S* {4 _  a
        // VRC7 (not support)
. q4 G/ t6 N& q1 q; L        if( exsound_select & 0x02 ) {
7 S3 I1 R; p  c8 x                vrc7.SaveState( p );
' e3 v/ O$ T+ [9 ]/ E! _/ ]& l                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
+ p$ K# X4 e/ _# D" N        }# o2 R! ?+ }: y$ z7 P
        // FDS$ S6 Q7 r4 W/ a, ], V
        if( exsound_select & 0x04 ) {
9 W0 T0 V0 d- k# b3 ^  G                fds.SaveState( p );
1 k; E& p! t2 F% b4 P2 o0 c( k                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
3 S/ f  F' _0 [        }. T2 ]# N8 J5 g$ W- r( k/ i4 P4 E
        // MMC5
6 o2 P$ b* K3 s& W, C        if( exsound_select & 0x08 ) {: |" S1 P! X) }* }: f
                mmc5.SaveState( p );
  [: Q* u5 V( o- Y) f' B                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding. q1 H. r, D1 `! T7 Z( p. Z! R
        }1 m% U  @9 o  T3 z  b4 A
        // N106
0 g8 N' ~$ W+ g, o' P3 l        if( exsound_select & 0x10 ) {
! ~2 v4 n; D- V' L# y6 S                n106.SaveState( p );
4 s: f3 }8 @$ ~. e/ J# q5 a  R                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding2 j* i6 c8 V, F' r" {
        }
  S9 H3 `' i/ h4 e' b* Z        // FME7
' J3 Z+ [% `9 O! l# [        if( exsound_select & 0x20 ) {
4 b* E* x* F: ?- r3 U( c' j                fme7.SaveState( p );! J; C  K9 ~6 N
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding5 {) g1 B/ x! H: C  W  C9 L; f
        }1 U, l9 P0 q5 E5 @1 J

1 d$ V8 w+ i( m* N' n/ O7 C: N#ifdef        _DEBUG
2 A# h4 K4 p7 f1 l9 e7 c3 F) jDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
* F0 P" p. U$ h6 D, A0 h#endif2 ]! `$ ^- _  W% t: J. ?
}
1 k6 K$ S" X* e( s  t" j" W
0 h$ h2 k9 y; ?void        APU::LoadState( LPBYTE p )
4 n* W! ?$ R+ e$ Z- u8 H8 J2 P& y; b6 l' J{
5 E. j6 k! Q% ]  H  r        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
4 H' |! H* l) Y# ?        QueueClear();6 l8 T0 c5 F; |2 h1 o

* P) \* ^/ T- Q        internal.LoadState( p );3 U( x7 `2 W, t0 i
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
. j) Q7 X6 E- @( s6 h
  _9 t3 x; c5 _9 r6 F        // VRC6( a% B. {0 x6 d1 F( s  K6 [
        if( exsound_select & 0x01 ) {$ z4 ^7 u' k" @7 U: G7 ~/ N
                vrc6.LoadState( p );2 i# x0 f3 r& J% P! _
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
' c1 C3 b1 O" r% h  J7 C        }
" m& B' N' t) j( }) y5 O8 P        // VRC7 (not support)8 w0 m/ k/ M* m* g' k+ v' ~
        if( exsound_select & 0x02 ) {
* P+ M7 m1 H9 W) _: w# [                vrc7.LoadState( p );/ [+ D% i3 c3 N( E: Y
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding, b& a4 _& G; }* u- q, o( D
        }
& `( o. }. p/ S. l" a  p% w% v        // FDS
$ }; C) t& W, j) K# i( X) t        if( exsound_select & 0x04 ) {9 z; N2 n0 e6 t- V4 K2 q! q. f. b
                fds.LoadState( p );" \9 w  _! d! X" N" K
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
3 [$ g: e6 b- C' o        }" T% }3 s8 i- O: D
        // MMC5
5 P; W( _; O3 a  d1 X7 y" X        if( exsound_select & 0x08 ) {, v1 W7 Y9 z. R9 F
                mmc5.LoadState( p );  A& L8 |( t* m! F# r
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding' a1 Y4 f% S/ i
        }
# T$ z8 g& n$ u6 l8 g        // N106
6 w  P2 u2 T0 c        if( exsound_select & 0x10 ) {
! m6 ~9 v  [; N* c                n106.LoadState( p );
' f0 p. w' t6 O                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
8 ]1 p% k. J2 R/ i' b( H        }
; G1 h0 i  |1 E& [        // FME7  G9 g! o2 X' q% Y7 t7 ]+ p
        if( exsound_select & 0x20 ) {/ O* C1 ^( v3 F3 k
                fme7.LoadState( p );* R5 I3 \/ m: g+ Q
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding- Y' V4 q( @& U' |, @3 o; Z
        }0 Q$ Y- L( t* ^$ K/ ]2 |: u
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
/ }1 ?/ ^: K. L+ {' \可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。6 p, o' s0 r' V* L
感激不尽~~

9 z4 K$ T. `, B3 M" v2 s7 U恩 我對模擬器不是很有研究,' g: m* I* l0 \2 [1 {" V
雖然要了解源碼內容,可能不是很困難,
# B( w- J3 x' U& U( A) M8 I' w不過還是要花時間,個人目前蠻忙碌的。2 y) }' r8 C$ ]. w4 G
" Y8 N* z+ ^0 X! b$ O2 @$ x  Y4 \
給你一個朋友的MSN,你可以跟他討論看看,
& _* ?. g6 l; v% ^8 B他本身是程式設計師,也對FC模擬器很有興趣。) I' h7 d9 F/ q% ~# D

1 e& Q9 m7 @1 J% h' NMSN我就PM到你的信箱了。" a* @: d2 M. q' [- p
& _# H- l2 ]0 a  Z
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
1 R5 Y1 b. u8 n# E" ^" e  K呵…… 谢过团长大人~~
+ Y" ^8 |, e! Q  o2 c8 l
1 k- \( _9 G! }9 C) i) a8 x
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 0 V- u0 s6 S0 A0 J8 ]4 F% N
团长的朋友都是神,那团长就是神的boss。

0 ]% y- H) i* ]3 l$ E$ [$ c0 j  l哈 不敢當,我只是個平凡人,
, r) J" C' P; \& q( N+ `要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙: e: }4 t# {& r5 l" b
ZYH
  v3 V2 o) B1 ^/ C+ M9 r8 X& rQQ:414734306
( \5 M4 X% I2 o9 h& mMail:zyh-01@126.com8 {2 l5 c' @. H
. E1 }7 ]# K4 s" ~
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
; r6 U& N7 y, L8 T再次对团长大人和悠悠哥的无私帮助表示感谢~~

: z  {& W9 Y; N$ k7 E不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-12 21:35 , Processed in 1.098633 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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