EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
, ]6 ?! c( K  \: t4 C1 M/ @0 v0 x楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
$ ~$ Z! q6 a5 A9 j" j% `这里有相应的模拟器源码,就当送给大侠了~~
0 d# T4 C. Z; b( r$ {$ qhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
* C' h& {9 J! |' H6 f. W& ~: _" @能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
5 q  V  w$ o7 b' u& Q楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~5 y8 k7 w$ l/ ?( l% M' @
这里有相应的模拟器源码,就当送给大侠 ...

/ U  f1 Q2 D4 r) H聲音部分(Audoi Process Unit = APU):
) r& _1 U) x# n9 Y: i- j  N.\NES\APU.cpp8 W& a8 C8 l, R8 ]. N: e
.\NES\APU.h  g3 o  I1 _. `
: A4 e% i5 D: l  d
# Z+ @" P' }+ J$ I% D, Y5 f# d/ m
影像處理部份(Picture Processing Unit = PPU):
) F! F( `: }) m; q% O) S5 M! q0 `3 Y.\NES\PPU.cpp9 ]$ D* Z/ b4 ^
.\NES\PPU.h. j* N9 Q, J1 @: N+ U# N
% N5 D! G/ H+ V; L# n
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
: Z  T! v: O$ a. C$ a& K' ?(由于很多专用术语和算法机理都不明白,所以看不大懂……)
9 ]/ Q# h2 A7 d3 y9 c& k) J//////////////////////////////////////////////////////////////////////////
2 F: v- F4 V' h( A2 t4 ]//                                                                      //# f6 A$ I* Z9 a# \7 R
//      NES APU core                                                    //
* s, Q+ T2 B9 e5 x//                                                           Norix      //6 `1 j' W3 [% t
//                                               written     2002/06/27 //
9 M. x$ t- B. O//                                               last modify ----/--/-- //
4 a5 o# v$ D8 d# T9 s- Y: C//////////////////////////////////////////////////////////////////////////
3 f0 F5 \, N6 e; Q4 ?* A' N, ^- w#include "DebugOut.h"
4 L4 @1 g" P0 [8 F; K#include "App.h"5 f/ O2 S* p6 G+ G; C1 p) k' j
#include "Config.h"
9 v6 R6 X% }. Z' x. R0 O/ V8 H" v4 s7 f3 Z, a: d
#include "nes.h"
1 `( H/ m8 P( Q; K, g#include "mmu.h"" `# c+ _" r7 Y
#include "cpu.h"
) c( \: Z. F% q) ^# @: w#include "ppu.h": [2 ^" M( C' E) W& R9 n/ ]/ E
#include "rom.h"
( ~- {7 N2 ]4 o/ e#include "apu.h"
. y) L0 a9 o/ b9 Q6 A' U3 \! Y1 Y  A/ T0 I0 Y9 L# j
// Volume adjust
: D0 [3 f$ Q7 x5 {// Internal sounds
( F/ y0 }8 u* U- ~% s, o; E#define        RECTANGLE_VOL        (0x0F0): e2 [! o  i+ A) c/ a4 z! T
#define        TRIANGLE_VOL        (0x130)
: ?  d% P6 ^- R3 Z' F& p#define        NOISE_VOL        (0x0C0)" U# c2 O( }. t; Q, Q
#define        DPCM_VOL        (0x0F0)+ i2 M' A9 m; E+ i: D$ S. @" [
// Extra sounds3 V: w' ~. [" r8 C% o9 A( F
#define        VRC6_VOL        (0x0F0)
' \! l; l; v: `' H#define        VRC7_VOL        (0x130)3 a1 M/ L6 C' r
#define        FDS_VOL                (0x0F0)
# |( S+ B% {1 M/ I7 M" _$ l#define        MMC5_VOL        (0x0F0)8 P; l, J+ O, x- {1 I, E  G+ C
#define        N106_VOL        (0x088)/ P) C! {* z/ D- J7 J
#define        FME7_VOL        (0x130)5 M5 H  y: p6 i( d. q7 a; Z" D
1 @# V* H+ d2 O7 J
APU::APU( NES* parent )
% m6 _, `/ B- @" w) Y3 P{1 A: p- U2 g# Z7 n) I  q$ P$ I8 O* S
        exsound_select = 0;1 t4 N) c  Y% W' ~; q2 _7 p* M

) }6 C: A: p$ ^. V        nes = parent;5 d! _) n  C4 \4 e. |
        internal.SetParent( parent );
% y+ A& W6 U7 _
6 f; U; ]% g: n        last_data = last_diff = 0;$ L; Z5 f4 O8 J6 F

( X5 i' w1 y% a1 R. A        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );5 Y0 F  \, O2 t5 w' `
7 K9 D2 ^, _. Y& z- j
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );' T- A* r; D$ p, I* V5 o! z
        ZEROMEMORY( &queue, sizeof(queue) );- \3 X8 X" f  _( {- G3 I
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
- R$ N. C4 c8 N# m4 l% u0 L9 G9 B$ U) Y2 ~/ ~: |
        for( INT i = 0; i < 16; i++ ) {7 M5 n: `# _" F6 S5 u9 |
                m_bMute = TRUE;7 o) q. }. T$ i( B- [0 A# ]. a
        }- X1 k* O+ B0 v3 `* X
}1 a4 d( x9 l, |+ ~/ I3 l
: M. E; K: c  l" t/ G# X& w7 C
APU::~APU()
* E0 L% q1 _2 d* \; z+ V" e  p# d{
7 s5 h4 C9 F# _5 J$ _1 o}
  z2 c3 y' d! K& b2 i: U
2 N5 I; [' u; Uvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
- F) B! N8 E2 X% l6 V{6 B7 L3 Z& h7 Q0 G5 C& M& }' N: l
        queue.data[queue.wrptr].time = writetime;9 A, V9 Q$ s5 c+ u
        queue.data[queue.wrptr].addr = addr;
" L, {/ F1 u: H        queue.data[queue.wrptr].data = data;. T0 C% M; P" ~$ N3 S( l( c+ H
        queue.wrptr++;. n& q9 q/ T8 `) }  Q
        queue.wrptr&=QUEUE_LENGTH-1;
4 H# ?: T6 e  k* X4 _        if( queue.wrptr == queue.rdptr ) {
7 |$ R- C) |/ k3 V* B                DEBUGOUT( "queue overflow.\n" );
: _6 d' [& d, N- O/ {' k% Z        }; H2 G6 `: c# t1 K+ }
}' I+ ^7 ^" \3 t

3 M" {9 A" K* {$ ^2 oBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )5 L5 T) t' e0 ?
{: f2 u0 V/ {( ~9 u7 p1 L
        if( queue.wrptr == queue.rdptr ) {
/ j7 D( m1 M* y0 m% S                return        FALSE;
. n' ^3 }3 N# l  }0 x) |. P5 e        }. Z( S+ l' \5 v; q7 V! J
        if( queue.data[queue.rdptr].time <= writetime ) {
* Z! H. ?& _7 v( {                ret = queue.data[queue.rdptr];
$ {$ o$ A: E/ v* |! A                queue.rdptr++;* M% p) t4 a, H: \
                queue.rdptr&=QUEUE_LENGTH-1;; Z1 {/ y, q6 }" ^: |2 Z: t+ ^
                return        TRUE;: \& ^# x2 P* o) K! T3 x; P3 k$ y
        }
, x4 V' H; L/ E- T        return        FALSE;
$ ~% P+ {. K( M3 h  e) m) [}, x) v5 X1 K; M. q
9 ]5 ?: `) W- }% O6 Z) B& I
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )5 ^2 S) B5 ?% S4 H3 H$ x& j9 x
{
( I- G  k0 a& C5 P6 j        exqueue.data[exqueue.wrptr].time = writetime;* ^. H9 v- H* T/ c, @$ C1 g
        exqueue.data[exqueue.wrptr].addr = addr;
8 x9 g5 o+ ]" K% |9 K; M! D; [- H        exqueue.data[exqueue.wrptr].data = data;
% `" c. d& X% |4 M$ Z0 X( \+ B( l        exqueue.wrptr++;' x3 P3 [3 Q$ ~$ F
        exqueue.wrptr&=QUEUE_LENGTH-1;
) v2 W& f& T! I* {, ^4 W% }: U* }3 F        if( exqueue.wrptr == exqueue.rdptr ) {
2 e2 E/ }  L3 |0 d1 Q  D1 m, t                DEBUGOUT( "exqueue overflow.\n" );
/ K3 e' }( x" }' T+ b: x        }
) a/ c! c" w/ t8 }( e2 V& R}6 H6 h* p3 L$ t  `6 u& M

  L& q: {6 S' |9 A6 ~BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )# u9 X9 S# I0 p+ e5 `
{! j/ \( `: b0 T: A6 l5 Y. \
        if( exqueue.wrptr == exqueue.rdptr ) {& J$ f9 x& O; s8 b6 i' ]+ `, X
                return        FALSE;
& Y4 M' w5 `' x* C( R1 x2 Q# p" ~* {        }
+ W  g- g5 ?& N        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
, b! Y: p6 y/ @8 `0 Z* [8 w* V                ret = exqueue.data[exqueue.rdptr];3 }  ?. M  h- S, O
                exqueue.rdptr++;
, \7 `$ r2 m* }! L4 T6 }3 }                exqueue.rdptr&=QUEUE_LENGTH-1;
! a9 m' M7 l9 K5 e                return        TRUE;
: ?7 z8 O2 F9 u% Y1 Y4 G        }
8 K. E+ C. |. q: j        return        FALSE;
# u* X9 Y8 p+ i}
' `" R# M$ R' d
9 _+ {: e/ q# Nvoid        APU::QueueClear()
6 T- }  ^6 h/ i8 M{
( m' Q' ?1 h0 K3 C5 O# r        ZEROMEMORY( &queue, sizeof(queue) );
8 D. a3 j$ x2 Y        ZEROMEMORY( &exqueue, sizeof(exqueue) );' t. G" H! Z: j( N" Q' ?. x) n
}
# P' z- p) T" X+ w) U( C5 z0 d! y2 E$ {* P  T6 @: h: Q5 f
void        APU::QueueFlush()
7 w" Q) D# t3 c2 h  }3 ]{1 O: h/ ]1 C* N6 s* W7 D
        while( queue.wrptr != queue.rdptr ) {
$ G( E4 ^4 X8 Z0 c- f% i                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );- H3 ~0 g' ?$ f) J2 C9 E: d
                queue.rdptr++;
% ^; t: H* e9 l' O5 B                queue.rdptr&=QUEUE_LENGTH-1;
! A: N  _# N5 `7 P# A        }
, A0 L! w2 Q& u7 V# m$ h
6 ^0 G0 T$ N) Q$ ~" b' {        while( exqueue.wrptr != exqueue.rdptr ) {# u  S( k  }' V+ d
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
+ @' {8 N; d/ Y- c0 u                exqueue.rdptr++;( J6 M/ a: K+ u( u
                exqueue.rdptr&=QUEUE_LENGTH-1;0 M* f4 Z' G3 f+ y( H, r! n
        }
5 D6 Z; G- ^/ w" [7 @5 Z}. F8 O! W+ T0 d% a/ W) S0 U
% u4 P% G9 a$ v) e
void        APU::SoundSetup()3 C/ z, y$ v$ g' n
{. {9 |( B7 e' a  o1 H% @. @5 c
        FLOAT        fClock = nes->nescfg->CpuClock;1 x' g0 |8 X% y  N
        INT        nRate = (INT)Config.sound.nRate;
6 \3 B$ ]/ h* _1 |3 P        internal.Setup( fClock, nRate );
2 n0 R6 I! u' `        vrc6.Setup( fClock, nRate );5 [$ |8 w, R/ X+ n' \
        vrc7.Setup( fClock, nRate );; B5 j1 c0 F4 |# t  G
        mmc5.Setup( fClock, nRate );
# [+ |1 {* a* |9 V, ]+ h. w        fds.Setup ( fClock, nRate );# U6 b5 W( k! ^. s2 J# i: G
        n106.Setup( fClock, nRate );
1 Y6 a* N6 G; ^6 R" {9 C        fme7.Setup( fClock, nRate );
5 j3 d8 o# Z/ F9 v2 x8 A}/ D4 d. D  m( F( }0 R$ s7 O
& r& P) X- [" k4 z1 s8 n* x
void        APU::Reset()% R1 M& ?: h! x2 b2 h
{$ V# M9 y9 K5 m4 K  V
        ZEROMEMORY( &queue, sizeof(queue) );/ C5 @' u# x+ @& m) A, v! m
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
  _/ ^/ T' e" n. C# w* g3 F/ }) }& b1 r2 D. _& G& x
        elapsed_time = 0;0 Y$ C" v4 u5 C/ G
8 \8 w  @: M; l4 k% Q
        FLOAT        fClock = nes->nescfg->CpuClock;
- u3 g7 }$ B, q6 ]' u  q        INT        nRate = (INT)Config.sound.nRate;
) |7 ?7 e, q2 a4 D8 @/ d        internal.Reset( fClock, nRate );8 L% _1 k9 e4 e% D1 Y& _
        vrc6.Reset( fClock, nRate );
0 o- P7 B( L; ~5 S4 l; i        vrc7.Reset( fClock, nRate );
+ Z) E6 j+ e) F- a9 I  U        mmc5.Reset( fClock, nRate );
" A8 h! @* ^' _& }: }7 [: F' s6 N        fds.Reset ( fClock, nRate );
# D& \: e% B! I4 a  d" F        n106.Reset( fClock, nRate );
# x. y$ p# U3 Z& j6 J6 h        fme7.Reset( fClock, nRate );
% Z4 Z; {, M1 U3 g1 j6 {% Z3 a; F2 J+ e
        SoundSetup();# }' a* |# b5 b
}
# i" Y# W# m* W8 x8 J3 H0 {6 a4 L3 Z( H& U' r6 |. ~
void        APU::SelectExSound( BYTE data )
. r7 W+ n/ Y6 V# T! B, v$ X3 l{
8 v3 _/ S# i; q- i8 ^$ J        exsound_select = data;
0 v5 L, }* }; t}
( ^. h" T. ?2 V/ @4 |* e" p* Y' h8 w$ b' G
BYTE        APU::Read( WORD addr )  @5 U' J2 D" q2 u" t# G8 H8 J/ L  h
{& l) E' I* p$ P! S, \' X
        return        internal.SyncRead( addr );  D" c, Z' O; d9 h) m
}4 \* f6 [/ E1 a9 @9 [

* h0 p& s3 o0 H  }void        APU::Write( WORD addr, BYTE data )7 h) T) K6 G) u3 g- ~, D8 Z
{$ M" L2 z7 c- k
        // $4018偼VirtuaNES屌桳億乕僩  ~+ y# g  D# }
        if( addr >= 0x4000 && addr <= 0x401F ) {
" F: H9 x+ q7 s7 M2 }! V                internal.SyncWrite( addr, data );& k; \1 ^8 a( [) o3 p
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );" B; S& B# T8 g$ @( \$ ^1 D+ ~  Z* L
        }/ I) q% u8 q, S+ k
}1 n5 m9 j& `+ @9 X

! i# Q9 c$ q  g) @) \9 P* c! v  rBYTE        APU::ExRead( WORD addr )
8 Y6 [  n( r. Z8 s% Y{
4 ]9 Q4 e% Y  [BYTE        data = 0;+ X4 ?, Q2 N/ s

& p( H* P( l1 y4 F. a+ b        if( exsound_select & 0x10 ) {! N" N; }# P9 J
                if( addr == 0x4800 ) {% E* I% F: m" X6 n; ~/ u
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
/ ]" L( n0 p& C9 b$ M                }
% ]7 L* F2 P, B; m, T& o        }: ~! L5 G5 D' N& @8 X* e) C
        if( exsound_select & 0x04 ) {
+ r; L$ `) Z3 h- r% a  S; O                if( addr >= 0x4040 && addr < 0x4100 ) {
/ O8 m+ o1 Z) X9 g                        data = fds.SyncRead( addr );
+ `- k& ~6 I0 y0 [/ S! S1 S' ?' K                }
7 @- O1 b" V' W& F+ n2 Q, M/ l' P3 @        }
, r7 f4 L% Z2 @) W        if( exsound_select & 0x08 ) {' w7 i6 [+ Z3 u# R- v: D
                if( addr >= 0x5000 && addr <= 0x5015 ) {
) g' E0 ~2 W6 E6 {( O' U0 X                        data = mmc5.SyncRead( addr );
4 Z2 h5 I1 N  S+ R3 B0 O% i! `                }' @1 N- }2 j' _
        }( \' A# z( d5 S1 c! [

# B( x# \  f: u' I        return        data;% k$ v; z0 n& \3 V- M% I( E; ^1 o
}2 l9 g6 o: R: ]2 A# g/ l0 o
, J3 y4 x" R  \! @) X2 h+ q
void        APU::ExWrite( WORD addr, BYTE data )
7 y6 Y( F& }- F" a{
" @) B5 a" B9 D& V) G4 O        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
9 ^( o+ G& l! v$ U7 Q4 k' q: ^1 d# J& I1 ?- R! l
        if( exsound_select & 0x04 ) {5 S" e2 Q. F0 Q# M( @
                if( addr >= 0x4040 && addr < 0x4100 ) {" B8 l. ~/ w/ x* ^  s7 x
                        fds.SyncWrite( addr, data );
8 p* f# D4 x% Q  S" B# L/ E* Q, _                }3 ^5 j3 e$ `- q8 s
        }- l1 Z2 p: e/ X/ s& r  j/ E
2 `' q7 ?8 q. b" F' r7 W  J
        if( exsound_select & 0x08 ) {6 K2 t9 c* F8 ~2 l: K
                if( addr >= 0x5000 && addr <= 0x5015 ) {
  Q; l8 [9 J, E5 k0 m8 P( L                        mmc5.SyncWrite( addr, data );
2 y( [. t3 m% k; c                }
. a& v) f+ R( ~! S+ M1 f        }. F- j$ m+ @5 q' F5 ]
}6 |7 t5 d4 d6 g. O

- T: G& D+ r+ I% p. Kvoid        APU::Sync(): B; z, {6 \* y
{
4 h/ |* `  L! ~: e}3 k% E, \, y/ E
: T# b6 b0 M' ~& Q2 E$ L1 Y
void        APU::SyncDPCM( INT cycles )
  B! R% p4 K7 v* ~4 Q% T1 N4 B{
$ Y0 }4 U" k6 Y8 G* c        internal.Sync( cycles );
, S8 x; h( i; e8 E& l, {5 b
. Q; T, w$ S* N& k8 f6 d6 Y        if( exsound_select & 0x04 ) {  ~$ U& v" {& b
                fds.Sync( cycles );
- i- H9 o+ T/ \0 J! M        }
( |  _+ d6 ]$ ?        if( exsound_select & 0x08 ) {
, i* Q3 m) Q- l$ o) Z6 h                mmc5.Sync( cycles );
* o  K; t3 u/ S( d# e        }) d8 u; N' O# W% E4 n5 c
}
1 `7 R8 m9 \4 ~+ f# D  k) m8 M1 Q) l2 e6 P, a
void        APU::WriteProcess( WORD addr, BYTE data )
" F3 A4 \4 k1 E{
- _, j' _& }: P- k* c0 O        // $4018偼VirtuaNES屌桳億乕僩  q$ g  J1 w! O4 P) U3 G
        if( addr >= 0x4000 && addr <= 0x401F ) {
& Q! U' A4 d9 B8 s& [3 E4 P                internal.Write( addr, data );
1 Y/ W! D6 e0 U# U        }
4 J' p' F7 ]  b0 X% \}' E4 `' {7 L* a7 O2 l' l& c4 O( O

; Z9 L- u3 g( z4 @void        APU::WriteExProcess( WORD addr, BYTE data )* N1 a. `* _: c* e- B5 J0 E9 u
{( }$ l4 o1 s7 O4 Z/ `1 b  j
        if( exsound_select & 0x01 ) {; e' I  c+ _1 h% f9 T0 j5 o
                vrc6.Write( addr, data );% {9 s: c* N( i3 h
        }
" g& }. g# Y& A        if( exsound_select & 0x02 ) {& s9 K( I9 V7 V) [
                vrc7.Write( addr, data );
, k% `# n+ K. c3 h        }! I( j. |( T  ?& j5 x
        if( exsound_select & 0x04 ) {# }0 {/ z+ m  Z
                fds.Write( addr, data );+ Z# r" O! n  D& l
        }" @% o! g' E* n8 r
        if( exsound_select & 0x08 ) {$ X6 {7 B1 p' d4 a- k
                mmc5.Write( addr, data );- P& L/ D0 T$ k' @: K
        }: y* x1 g" A7 Z# B
        if( exsound_select & 0x10 ) {
) s# p7 h2 f- s; E) `6 c' Z1 g                if( addr == 0x0000 ) {: \: j! s8 ]8 t) }4 w# ^1 x
                        BYTE        dummy = n106.Read( addr );
/ T' l$ o% u7 u, q                } else {7 L1 h3 `7 v2 f
                        n106.Write( addr, data );& j( t; d7 G& x7 J5 Q( G% u
                }
& `& F3 @& I9 Z9 Z: r' q& J/ D. b        }* S) W$ h' ^7 v1 _7 T' B
        if( exsound_select & 0x20 ) {
) {" K# X' R+ V. ^                fme7.Write( addr, data );
# N2 h% V! Z& J! S        }- K# b  p8 Z& }9 ~- N3 h; x
}
6 b% I( L! R# E0 ]+ m) ~
# G1 `+ P0 F6 z, svoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )/ R% L1 D* U% a* h
{# K$ m7 M2 ~1 C3 ~# o1 S9 b
INT        nBits = Config.sound.nBits;* ~; v8 o- J4 _3 M2 l+ Z# e
DWORD        dwLength = dwSize / (nBits/8);
, _% n6 C+ [0 @" }! U7 eINT        output;1 J: K! y: o( f# D
QUEUEDATA q;
) e6 |; W- i$ K# F' WDWORD        writetime;
# F1 z% g5 t5 M" Q! ~4 K
; s, j. [* d1 n. z2 eLPSHORT        pSoundBuf = m_SoundBuffer;
% i& [# ~5 l  v0 }INT        nCcount = 0;
4 Z' B2 b* ~& |2 G1 \" y  Q: |3 B7 S% D1 {# ]
INT        nFilterType = Config.sound.nFilterType;
! ]7 {: \, w. E2 H$ Q/ Q5 u, W, S7 z9 p- R, X# [, _% \0 U
        if( !Config.sound.bEnable ) {9 d, O, @0 m( I! V+ d4 H, ~
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
' g, L- N4 T' J                return;
  g- I; ^3 R5 P8 Y- G        }3 q, e/ c2 i: E4 O9 o) F4 V

! Q1 H: Z3 S0 \3 c! T$ H        // Volume setup
1 A, y% U& l1 R* p! V! W        //  0:Master& s" ^8 A+ \( p5 ~1 v7 n
        //  1:Rectangle 1
; q# H3 K2 m  `1 d- }# K% ?6 s' S% m        //  2:Rectangle 26 d  X: r. R0 @1 |: \# I
        //  3:Triangle
. a( {+ r* Y  P) u& D        //  4:Noise& D! t+ ]9 K/ q3 Z! m
        //  5:DPCM
3 l8 N# Z2 F6 T3 X4 D( ^, A3 a7 I        //  6:VRC6
- Q  j6 U, o/ J9 F9 {$ A6 F        //  7:VRC7
# X, S3 r+ `& N& L# J$ V        //  8:FDS
/ e3 `" a3 @  C7 d/ R1 M% E        //  9:MMC5
. i; J- r4 E$ R, o' U" f        // 10:N106
$ {6 l3 @! W. ]; }4 I        // 11:FME7
  ~4 f$ _: N7 h- C        INT        vol[24];
- K4 @9 ?1 V/ }& V+ u- q; Z        BOOL*        bMute = m_bMute;
8 O1 o' O6 ]0 R4 Z4 S        SHORT*        nVolume = Config.sound.nVolume;0 @& S! h7 ^" S% t- B

7 z% t9 |5 y1 x        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
( y8 G# j2 A: `% q8 b. j, W, u* O1 }" K' \' w
        // Internal
8 O5 `7 L0 o; }% y. O        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
' {$ K1 k* |* a& w. v        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;. W) y8 }. [4 v" W
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
7 G, c" t6 W( W5 _  l. k! X- b        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;' v& f* c  m6 _# J+ W% A5 T
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
! u8 U4 w- ]8 S* l$ Q# x1 r' k8 {2 ~+ K% U
        // VRC6
2 A; c, ~) m( S        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
+ \  b5 k4 _* s$ F        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
8 T6 s, l! @  {  l6 q        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;" j( J: ], H# {! x

" D/ z3 N$ P/ q6 u* Z$ L( x% B        // VRC7
7 E2 W& ~% ?7 T4 D) V  B        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
6 L2 [5 V" W; Z5 L6 j9 f/ o) d$ T4 T  I
        // FDS$ _) X1 [: ?/ D7 D! H7 }7 l
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;- ?: a4 S: b9 Q0 c1 u# `
4 B: O9 y& i9 j. _* P' m
        // MMC5
8 V4 s  m) ?9 w2 a4 A8 m        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
& ?( d& @; k* ~        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;% h6 T5 [6 ]0 v3 R. I# j( R- \
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
: F5 ]2 F& J% S4 b6 m* U5 Q8 s1 a$ ^6 H) ~% k& T9 w
        // N106
1 X9 b9 Y  n9 _6 V5 P( |        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 X  l' L2 Y# a        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' `- C! i- D( S. \* Z
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ |$ ^7 H) K, w8 ^' h
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
2 r& I1 H2 a3 V2 v& t" B        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;2 ~8 ?+ w& {- F5 \  D7 H
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
; V/ i  m, d# `* T: c5 W        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;  s+ C/ i+ T2 @8 w1 I; l% G4 S
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ n9 k# J7 \+ c$ \

' m+ T+ z) S, o0 {9 c        // FME7
8 r  I3 ?2 l8 W9 c& K% Q        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
+ `- @+ w5 Z  Y: i        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;& l0 \( r5 W1 M3 Q; c9 D
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;9 f: K3 w: t5 }5 F" o4 ^+ i

! M2 ?% x9 y: K6 @1 F4 g//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
/ @' P( _5 ?6 n9 e7 k        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;/ }+ c, q3 t  e; U) s8 D1 h4 w

  T, N" f+ g. p4 ~        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
2 l8 m% Z$ G; R" W3 T2 Y  C' e        if( elapsed_time > nes->cpu->GetTotalCycles() ) {& G, |6 v6 X& |0 Q# e
                QueueFlush();5 g3 S( V8 k- d/ }* N9 o
        }
1 h! E3 v# I, u# z# ?' F& W- d" h! D! M% G/ N( K6 z
        while( dwLength-- ) {
$ W2 e9 J6 A3 }$ d  R$ o0 k% Q                writetime = (DWORD)elapsed_time;; V/ f, N6 n) \2 V2 y

' @" y6 S. W4 J                while( GetQueue( writetime, q ) ) {- j4 t3 \3 k0 q9 F! V
                        WriteProcess( q.addr, q.data );
0 U; D/ w1 ^- J1 i$ I/ c& U  I                }& H' n. t3 v- l2 @$ l: p

- K; k  r) O: y  d/ L: @                while( GetExQueue( writetime, q ) ) {& a4 V0 M9 Z- J/ v# Z
                        WriteExProcess( q.addr, q.data );
: {! Y& s7 l: o3 g                }
  s3 D9 g( `) V+ S$ J
" o, |# x( q, _' u9 a                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7& v  P; n8 {# F& D! J
                output = 0;
' p$ U# e4 i& e3 f# A, D                output += internal.Process( 0 )*vol[0];- Q! ~9 x" F: l; ~* [; e4 t7 U) x. k
                output += internal.Process( 1 )*vol[1];' s& _' s# f6 Y+ Z* M: k
                output += internal.Process( 2 )*vol[2];
; Y6 {1 v/ O; W3 u- q                output += internal.Process( 3 )*vol[3];
3 b+ l) l% t- i' \( h                output += internal.Process( 4 )*vol[4];5 e+ k: ~1 Q; J5 m. b3 \) O
6 V( ~" J( Z; m# R% U9 k& d
                if( exsound_select & 0x01 ) {
; G+ E4 A% D# u% H; q. J/ `                        output += vrc6.Process( 0 )*vol[5];
# B* z6 l3 j* y+ ^+ w4 d5 F, X3 V                        output += vrc6.Process( 1 )*vol[6];6 b0 z: E6 Z0 z* S
                        output += vrc6.Process( 2 )*vol[7];# I4 T! |- m1 I: y: N  z) k3 |
                }, d5 F) o5 \# x# b3 R
                if( exsound_select & 0x02 ) {
  E% ^7 W) J  f4 L( p                        output += vrc7.Process( 0 )*vol[8];8 ]- t; `$ O. C
                }8 }" l3 G; `9 z2 c# P1 F8 t4 a  _
                if( exsound_select & 0x04 ) {
  N9 _  J3 U( b" K( }                        output += fds.Process( 0 )*vol[9];
8 m7 Q! x9 M% r! H# p2 T7 I1 \7 `                }7 p/ [. r7 c4 d  c" E
                if( exsound_select & 0x08 ) {$ f! l/ _( b8 o, l
                        output += mmc5.Process( 0 )*vol[10];  P1 ?! E7 k$ Q6 Y  ]+ G
                        output += mmc5.Process( 1 )*vol[11];7 W6 y+ o" s/ C: \
                        output += mmc5.Process( 2 )*vol[12];
) \& s  t5 |. `3 i" T                }  ~  W. W) I3 Q+ @' N8 S3 o/ _
                if( exsound_select & 0x10 ) {
& n' |- p$ [7 T1 w                        output += n106.Process( 0 )*vol[13];
( \4 A! l  |0 _/ x' I                        output += n106.Process( 1 )*vol[14];
: @# a$ k1 m" I                        output += n106.Process( 2 )*vol[15];
6 ^+ o7 E* o8 @1 N) F4 c. x                        output += n106.Process( 3 )*vol[16];" y* D& V8 `0 X  |5 k2 h
                        output += n106.Process( 4 )*vol[17];; ]6 D, B2 N: _( r  y- ]$ \" N
                        output += n106.Process( 5 )*vol[18];
/ |( R8 s' P+ W% r( G& \/ v                        output += n106.Process( 6 )*vol[19];
, w) @; E4 N: \% X' |                        output += n106.Process( 7 )*vol[20];, d* h; x7 @: A: b5 H
                }
' |  S7 g. V* W; T                if( exsound_select & 0x20 ) {8 {) U; ^/ Q% h0 u
                        fme7.Process( 3 );        // Envelope & Noise' t, G0 X+ @; ?) W$ ^6 R
                        output += fme7.Process( 0 )*vol[21];2 @: z/ I7 U2 \" r* S
                        output += fme7.Process( 1 )*vol[22];4 \% K  }1 D+ v+ Y% F8 a+ E
                        output += fme7.Process( 2 )*vol[23];
& w: b2 k; \  e7 v                }; F7 g+ Z: u! Z; H

# ~$ n1 G6 S/ s' {/ A2 C( F* u                output >>= 8;
: |/ m) E9 f. w4 l4 L8 n& l! o" c: c6 `7 U& t5 N
                if( nFilterType == 1 ) {& s- a' e4 B0 u" I  t' ?
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)% q& D3 c9 G' C% H
                        output = (lowpass_filter[0]+output)/2;4 E, w0 T6 ^9 i( N' y2 H3 N
                        lowpass_filter[0] = output;4 N. |+ y6 i) Z, d. l8 H
                } else if( nFilterType == 2 ) {
2 Z& v! `" Z4 y" V3 j, z                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)4 N% F( g% S$ |$ v
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;. x, K4 I* ^& O2 |$ }8 s
                        lowpass_filter[1] = lowpass_filter[0];+ S0 k. a# z- s
                        lowpass_filter[0] = output;
$ t# T. L; |/ @1 |8 f' S4 w                } else if( nFilterType == 3 ) {
: R! |7 B6 H6 @. t, b+ g8 n                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)% l: [3 B- X- R% J
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;% q/ C+ ^8 ^+ D' v& b: h
                        lowpass_filter[2] = lowpass_filter[1];
8 `! Y4 `/ u3 K- k$ y9 [2 z, O  g                        lowpass_filter[1] = lowpass_filter[0];
& ?3 \) U! E% ^) `3 \# j                        lowpass_filter[0] = output;/ W4 `! f7 u! \8 ]
                } else if( nFilterType == 4 ) {
- i- S- P, N# m* P" s5 z/ ]                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
$ z% A- z7 W5 H8 S                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
) Z  n9 j, S4 w) {/ F  A                        lowpass_filter[1] = lowpass_filter[0];, ?& }; s/ r! q+ S2 K+ t
                        lowpass_filter[0] = output;
7 a" x7 B, x2 e/ {! A$ d- p                }
3 g  I9 `+ L4 N2 `( r3 W1 J. H$ S. n9 I# ~. Y5 P! u
#if        00 ]& J. g$ k' T# W: n
                // DC惉暘偺僇僢僩
& r: {* R; S8 }5 ~' ^                {: ~6 r9 N, ~2 g, @, o
                static double ave = 0.0, max=0.0, min=0.0;
2 t- p% i$ x2 j  B" g( @                double delta;
) H! Z5 Q+ V$ r! D9 i( h/ x                delta = (max-min)/32768.0;0 E6 P4 t; _" U1 @8 j% C9 i
                max -= delta;# ?6 W9 I0 ^0 t' Q2 K
                min += delta;
( w1 G5 i: s2 p7 Z4 u                if( output > max ) max = output;
) g3 G0 x0 @5 g; w, l# D6 c5 b                if( output < min ) min = output;
8 {0 N/ T5 C7 E% S( n! H! F* J; u                ave -= ave/1024.0;
; c' S$ B; W5 W2 v  I/ L- B7 K                ave += (max+min)/2048.0;
6 O) N' {! J3 c                output -= (INT)ave;* b0 d& Z& z" D5 t( v- `
                }! C! m+ U/ O  q% f; F# Q( e6 F# U
#endif' Q$ ~! t. v9 z! c8 _4 T
#if        1
) S+ b' R6 \/ |+ N' Y                // DC惉暘偺僇僢僩(HPF TEST)
8 w0 }- l' o" v  ]6 G                {
7 R0 T% F) y' j//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);+ g* T; K( f, K. T
                static        double        cutofftemp = (2.0*3.141592653579*40.0);( \' Z! ?  k7 x+ i* J
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
) ]/ R8 ^1 g" Q* a2 O                static        double        tmp = 0.0;/ B- n  X9 p& K0 v9 |
                double        in, out;
/ W, [8 l! P2 p5 e* u; N) L2 q- N; X# `- [5 D# N# C3 u" Q
                in = (double)output;% v' `+ z3 e1 `# I+ Q0 B* K, I
                out = (in - tmp);( ~6 ]" Q; ^) Z# b1 U0 a
                tmp = tmp + cutoff * out;
$ q' m  `% I4 e
' `$ q8 z6 J3 q/ S' n( O                output = (INT)out;4 X) N$ O$ @, Q6 G6 ]. J
                }
2 M+ D3 W4 q- U#endif
. v9 c6 M( ]8 \6 Z* `, N#if        0
" o5 C8 W4 ~4 ^4 O2 ]! m2 d                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
# L4 p5 ~* z7 p5 E                {
' ?; B* y; `, j; }% B0 w                INT        diff = abs(output-last_data);" U; T  d6 R- A
                if( diff > 0x4000 ) {
0 J) R$ Z* K8 {2 c* t                        output /= 4;
* r2 k7 x5 M* E9 x! U$ f& j9 i                } else
- S: v3 K( Y' W2 Z/ Y* p                if( diff > 0x3000 ) {
6 l0 S, d, v/ P/ J6 i2 M* t- F                        output /= 3;& S. V; z. z& @6 I  a9 g
                } else
: G+ ?" y- `3 r4 A% w1 }; _% K                if( diff > 0x2000 ) {) B3 Q, x5 A! N
                        output /= 2;9 F+ f+ ?+ _1 B% w
                }. A! s! \. S1 E5 ]8 ~
                last_data = output;
* B) m" o0 Z. l* q2 V7 t8 @6 x+ v                }1 a) h' ^% L7 l& V& P
#endif! O2 B0 I5 [& |2 ]: J$ w  [
                // Limit
; v1 @. I0 h$ Q) J. z) T6 P8 X! x1 p                if( output > 0x7FFF ) {
- J5 r# e( J. n3 p7 G6 P! L' l                        output = 0x7FFF;
1 G( ^& ]  n$ y% e                } else if( output < -0x8000 ) {( H  V* L* C1 v4 R
                        output = -0x8000;$ q* |% f2 k2 ?) D( }+ R. d
                }3 t, B1 V5 B- K
; r% Z$ |( X8 F3 E# b$ A! N
                if( nBits != 8 ) {
0 V( k$ {3 G8 |                        *(SHORT*)lpBuffer = (SHORT)output;
/ s8 R0 Q2 O8 j" r: p: m; v9 W/ Y  n                        lpBuffer += sizeof(SHORT);
* `% e$ u$ H& h  [                } else {) m5 P7 z6 H1 [" W2 b& l& r
                        *lpBuffer++ = (output>>8)^0x80;
! i6 V, g2 j! M: A; ?6 i. l/ q                }
" C9 s( }& A7 x* L
8 H  z& N3 d; A: J* ~/ b                if( nCcount < 0x0100 )6 P& ]7 {2 M1 F- u" {% s+ C
                        pSoundBuf[nCcount++] = (SHORT)output;& H7 p/ {. G3 j! X
* W- g& j( C4 [; a3 y5 f1 J
//                elapsedtime += cycle_rate;& F; e, l5 v4 g, _7 Q, R8 I) \
                elapsed_time += cycle_rate;) d( M; X7 S& g" z9 z
        }9 N8 H$ `( l3 a" U# [+ J
6 Z' n% @, X% D' p. X
#if        1
1 x5 w& d( ~: a, w* D        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
$ d: A6 Q* m  L+ |2 j! X7 ^                elapsed_time = nes->cpu->GetTotalCycles();5 N8 Z; `) }! A" Q6 V7 ?
        }
5 j) B& ?) [1 W8 Z& p+ a8 F4 h        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
* B+ }; ~: E7 Y( Y8 A                elapsed_time = nes->cpu->GetTotalCycles();: ?- G/ X& T! h$ J9 l( J( v8 Q7 |
        }, @# O3 Z! m- T3 }& r5 T# x
#else" H. ]) n8 _2 T
        elapsed_time = nes->cpu->GetTotalCycles();/ G% N' b: g) V( l8 i; O2 m% ?5 U
#endif
$ E8 d7 s8 o' ?* }}
& e9 v( [( B4 F" W! A" U8 u( \! V; _" y! [9 `
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)! Y) P6 Q) ]( w$ k
INT        APU::GetChannelFrequency( INT no )
& ~1 L, [: X0 k$ y{3 m9 ^3 F& Q; m* n5 h+ t8 V) Y
        if( !m_bMute[0] )
! s: P/ S5 ?5 f! ~* c                return        0;! X( i& K( l  A* M( h: X% V
) U; r5 K- e1 E) p# N
        // Internal" P6 h; L. K6 S5 z# F7 w7 v5 @
        if( no < 5 ) {
, Q0 q  \- ~  L9 H                return        m_bMute[no+1]?internal.GetFreq( no ):0;$ N. X! f$ |7 F$ M2 W  P
        }0 Q7 |) k( a: f0 s+ v+ W
        // VRC6
8 ^, M# @! S9 l* ^/ t$ m        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
0 f5 A, g: l- L( G% ]  {                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;' Z1 m2 e! U3 J" P3 y$ P- z
        }5 k1 e+ Y! ~  ]" T7 M: V8 x' w% h
        // FDS0 G$ q( k- i$ e/ N
        if( (exsound_select & 0x04) && no == 0x300 ) {
8 n3 \4 s; \8 D5 d3 f( b                return        m_bMute[6]?fds.GetFreq( 0 ):0;
) e" W& `) h* Y, }3 ^/ v% k        }. D; e7 {/ P/ N2 M* p. f
        // MMC5
- K1 e5 h1 G' O0 }1 R! t8 X        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {# I) W% V0 U6 r0 i; T  p& p, F
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;1 {' g% {- b3 ~/ d& \; `
        }/ p1 R3 ?6 O8 A& |) m- ~
        // N106
. |+ M7 J# d. B# r: l; b        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {! |$ p. E; v7 W
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
* E$ Z$ W8 R2 r0 z: `$ K        }
- n& h/ v6 S/ B" {& w1 X6 @& C9 x        // FME7
3 D! ~( y: t. T, o0 j! \% v2 p        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
" {( G  _9 J3 h* p# P) I6 j( Z                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
' v, C% p  L& C0 U7 ?/ Q! [7 w' O        }. G, @2 a' E6 I8 }% Q9 Z
        // VRC74 H, d  l6 [7 L4 U
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
0 \6 L& d- ?% r! T6 i                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
5 E6 y3 }3 I- X        }
# c/ t* J: ^4 j, v$ I        return        0;+ S6 ]" M: \& t$ S- i
}, w: B3 p! q  X/ y3 k, K6 Y
; a( L1 {; U* m
// State Save/Load8 t) d1 s- `1 Z: o
void        APU::SaveState( LPBYTE p )
  q# B; @+ V0 H, y; u{
) J9 [& M& A) {. t0 ]#ifdef        _DEBUG. T' b# M# V9 U4 Y& i5 i8 R9 C
LPBYTE        pold = p;
7 B$ E2 R/ P- |- F3 b#endif7 j# J1 A) m* b; R# J" j% _2 M9 y

. H+ V& U& j, [& _/ ?( A8 h% e        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞: w% s6 |3 Q/ D6 J0 Z' t, v
        QueueFlush();
4 o- `; C) n- U3 f0 o. j5 C: C' X
        internal.SaveState( p );
* g4 Y) S3 t6 q' g( ~/ c" ^        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
9 X7 C  E" D5 P" |2 _& ^( U7 ?, o$ E% d- G3 L. ^
        // VRC6
% r' i2 J+ k0 G: x$ R+ w) K        if( exsound_select & 0x01 ) {$ V4 S8 ~" q( i! y
                vrc6.SaveState( p );
- e; s; A4 n+ D8 v& ~! r                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
5 x. z6 i1 M0 `        }
( {: y9 J3 z  ~/ x6 d        // VRC7 (not support)5 S2 P$ u  u- O1 M! H4 p. Z, j
        if( exsound_select & 0x02 ) {# m/ z: S& A, q0 e+ Y
                vrc7.SaveState( p );! q  G) t+ `: u& f; N. M2 o) _
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
! x  g$ d/ h2 X" p4 c% M        }
6 x2 D2 j% a) \. @/ o0 V$ X        // FDS; K  _9 j1 t# d+ W+ K& d$ B
        if( exsound_select & 0x04 ) {
7 g8 z; E3 o% ?  }$ r                fds.SaveState( p );# P2 z6 A* \% w. z4 I
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding$ s$ i; [" o9 X
        }9 Y4 A4 v  ^6 _1 L& e: `
        // MMC5
) Z  \2 y* G& h- d$ J$ l: D        if( exsound_select & 0x08 ) {
- d5 P  v3 o, t5 N* J; b" L8 M4 H                mmc5.SaveState( p );: l; ]& {+ F0 S# Y
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
! U2 N* |9 d9 \: [0 Z" O        }! l" V* m) S% ~! {: l3 q8 G5 x
        // N106$ A2 m  d$ W2 m8 S& y0 _8 E' s
        if( exsound_select & 0x10 ) {
4 b) J, e2 a% e: t* Y+ H                n106.SaveState( p );! q' e# X8 V' u+ K+ R
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding# ~' }2 e* K! d3 `$ N; T; }
        }
+ ?+ h! b0 e* l# ^9 Y5 h& G        // FME7
0 Y4 R% n, p8 d8 O5 A        if( exsound_select & 0x20 ) {
, E( [8 e; C0 U% C* b, ~                fme7.SaveState( p );
2 t( v4 F& T! X. v) j- _                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding7 |5 l; v2 ~5 R  ?, z/ t
        }
: U2 p& i7 \, c4 a- T
9 i2 H# U7 T5 `6 z, s3 J3 m- l5 I" i3 o#ifdef        _DEBUG( T2 i$ D2 j* m. ~7 B  s# h! y% V
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );) L2 q: g( Z9 I- y4 U+ c+ I! x
#endif
6 y, A$ N8 r' `3 J/ T}! |" c% C( S2 A

* ^% _) {" F3 G2 B" c1 P, Tvoid        APU::LoadState( LPBYTE p )
3 P; O& q2 b3 S1 r5 ]1 e{
# A7 n! R: {/ E        // 帪娫幉傪摨婜偝偣傞堊偵徚偡1 r+ ~! g9 i' D5 f$ `/ }0 Q
        QueueClear();
% p" C/ {. g" n5 a- A
( |7 v5 ?' Y, n) ^. L$ i        internal.LoadState( p );
0 f, t+ v( Q2 j) o  c        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding3 T- x; L# V1 u5 Y3 m. J; m

  N+ t8 J& D& S) p- E        // VRC62 R8 w. v- X4 e% O
        if( exsound_select & 0x01 ) {7 B' N* d/ E8 y
                vrc6.LoadState( p );' N, V9 b- ^# ~; e! M
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
# p( }- T0 C2 o4 \" Z) B        }- {- t: J9 i: g1 e* p; M
        // VRC7 (not support)
# M; Z1 Y  T6 A5 y        if( exsound_select & 0x02 ) {
" |1 L$ D4 `1 r2 D0 t. S4 Z                vrc7.LoadState( p );, h' O, |8 q7 t" M2 b
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
5 B. }& ^! q' h0 a. D/ o: y4 i4 G1 D        }! W* M1 s% w* q$ V4 I
        // FDS
# {2 x  C) D4 j1 f8 N0 d        if( exsound_select & 0x04 ) {$ k2 v: [- ]4 J6 x8 M
                fds.LoadState( p );6 \; o4 K: W9 b4 @3 P% H
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding" G5 r9 \& L- ?8 q
        }
' W: t2 |/ J% m2 x# h3 u        // MMC5, G, y0 k, b7 j! w
        if( exsound_select & 0x08 ) {. `) Q& `, ^- |
                mmc5.LoadState( p );% B0 r4 y' K9 z! s% H" @) e
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding( ?) ]0 g. P! A0 ^, Y2 N
        }- V, ?# {, |3 X, V0 [/ o
        // N106
$ q; }# X5 `4 L1 i. A/ [4 D! R2 x: d        if( exsound_select & 0x10 ) {
6 q1 I8 k1 I  J0 b                n106.LoadState( p );
  ^1 j6 Q. f$ {7 v' D  G' D                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
3 L% q$ z* W! ]& I) n  m( V        }" @: X5 n# R) s- M) t. v& L
        // FME7
, I3 Z8 u8 \0 f        if( exsound_select & 0x20 ) {
; b: O7 Y+ \9 K$ i                fme7.LoadState( p );
6 u0 k! u* ?! x7 m8 ~( ~' F# N+ f; Q; r                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
. b" Q* f+ n% h        }
& I1 [6 e& q" m  w% C0 X, ?. S}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 4 y  N; N- K: @5 `6 E" R/ L
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
% ^# M3 a( `! w7 N4 T) e* C感激不尽~~

( I2 i2 q( i0 N2 l恩 我對模擬器不是很有研究,
) _) R4 Z' M' R3 q9 k雖然要了解源碼內容,可能不是很困難,5 ^6 g! Q  A1 p' R7 z: `' d
不過還是要花時間,個人目前蠻忙碌的。1 K' k' f+ ^$ Q$ {: T

% F8 `  Q! }1 ]- V, F3 |' X給你一個朋友的MSN,你可以跟他討論看看,
& Y5 J" Y. h7 L! q6 O他本身是程式設計師,也對FC模擬器很有興趣。" W& y+ g" B$ \( J

0 S0 a( v7 i, [: [MSN我就PM到你的信箱了。' Q; f: s) Z: @7 f* ?! }$ H* V

; y# M$ H2 v4 D4 `7 [# G希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 $ A0 Z: W: o; q5 X7 L1 p
呵…… 谢过团长大人~~
1 b- d: g4 h  U

& W- Z+ T) ^6 }* Y# T& F# \- T  b* N& W哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 4 A' z' f5 E; E, Y
团长的朋友都是神,那团长就是神的boss。
7 O) S* x3 Q0 G" }- A, l, e+ u
哈 不敢當,我只是個平凡人,, H/ h; ]" n6 [+ f( Q2 n
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
3 h7 }1 I0 x' U+ C: V" Q. F8 K9 ?; SZYH
( E! H1 m9 [% }" V4 FQQ:414734306
) a9 [6 x, c" i" A; C) {$ @Mail:zyh-01@126.com3 k* y3 \4 y3 t4 q* o! b" m

1 l7 e* ^/ o+ b& ~7 s  p5 f3 b他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
7 n. s5 A1 C" F5 W5 J+ }再次对团长大人和悠悠哥的无私帮助表示感谢~~

3 B/ ]4 ]/ o. j( W不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-2 21:09 , Processed in 1.066406 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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