EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。, s6 z2 c7 Y6 L' Z- Z6 c% P% `7 D
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~" _$ `, T2 E  W! }2 W  j4 R$ i
这里有相应的模拟器源码,就当送给大侠了~~
  H6 f+ l6 c+ ?2 _) B2 D* ?6 hhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
! ?  D7 I0 e* ^5 g# w# M能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。9 q+ G  p9 Q0 h
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~( k/ |: o4 z( ~" _+ \- R3 v' P
这里有相应的模拟器源码,就当送给大侠 ...
9 Q7 W% O1 F: r
聲音部分(Audoi Process Unit = APU):4 \: Y- F0 g7 \. j. L6 R7 S
.\NES\APU.cpp# Z; r% V/ H, Y% b/ w
.\NES\APU.h
! s3 R. l% v* q" Q: _0 @, ^  @2 J% v' C9 `7 w6 \

' U6 M. j" Q0 ~影像處理部份(Picture Processing Unit = PPU):/ d/ U  e! Z- |4 j3 \
.\NES\PPU.cpp# G& q" S- D4 B/ k0 ?2 @" ^& O
.\NES\PPU.h1 p! B" j: G9 H9 i% G; ]
$ a) ~# R$ ]3 T' Z; L# T
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。5 s3 f" y5 A( Y* z  h0 M
感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:; b' q( b: I8 ?
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
& p% Z6 m! {; f: r//////////////////////////////////////////////////////////////////////////
( o  p* {5 J  m) D1 V//                                                                      //, C) h7 V' ~7 c9 c
//      NES APU core                                                    //
5 z) \" R7 Q) p//                                                           Norix      //) O1 R+ ^+ N' H4 @
//                                               written     2002/06/27 //3 }7 d" a2 D  E: l0 Z8 U
//                                               last modify ----/--/-- //! c: }: D  @( Z9 Z$ ]: `5 F
//////////////////////////////////////////////////////////////////////////
) E( r" l, n9 i. r  k0 q" s" I#include "DebugOut.h"& A& j0 c" `( a
#include "App.h"5 @% p5 i& P8 [
#include "Config.h"
1 f9 G& M+ X' U6 h0 `* |% r! y1 f. R$ I1 i
#include "nes.h"7 t4 \" r# X; F! P" K/ x
#include "mmu.h". ^7 O! |2 F% u' G0 R
#include "cpu.h"
4 z2 I8 u* a, z3 p7 K- r#include "ppu.h"
6 P- i4 i. j( D8 a: o8 z1 l#include "rom.h"
6 H  \7 b! V5 |! \# Z#include "apu.h"
. h9 ~* u% P: d2 R5 \* ^, I
$ B5 D# A! H3 {1 r) W. d- Z' e0 z// Volume adjust
2 c5 t" c8 R/ `$ x// Internal sounds% p0 f8 |- f0 ~5 ?6 v& q, c
#define        RECTANGLE_VOL        (0x0F0)3 j7 a" h0 ^* G1 n2 u2 @6 o2 \
#define        TRIANGLE_VOL        (0x130)
/ `# X, m4 Z) e1 f* x#define        NOISE_VOL        (0x0C0)
1 P1 l& s2 _* @! ~#define        DPCM_VOL        (0x0F0)0 ?0 p1 d" c" ^
// Extra sounds! B8 q  A4 n" j
#define        VRC6_VOL        (0x0F0)
+ m+ Y$ j, l, V0 Z: ]$ L! M#define        VRC7_VOL        (0x130)) M; a* b3 X% u  w- J
#define        FDS_VOL                (0x0F0)
9 b; I. {/ p4 Q% a3 ?  ~! E#define        MMC5_VOL        (0x0F0)) y0 d, _& h" }. g; I
#define        N106_VOL        (0x088)" e6 C- P2 L1 r  r' Z* e' B5 Q
#define        FME7_VOL        (0x130)' V% r3 O8 a9 a+ g; ^( x
# K# b0 R& L. H
APU::APU( NES* parent )
, r9 n' B* O# Y! S{
3 Q! y" v" N9 ~: B% y- h9 S        exsound_select = 0;
/ |0 a" H# Y# E
% w& P* S- n7 W% `/ {! B! V- E        nes = parent;
  i3 @, b- o. p0 W1 R        internal.SetParent( parent );$ {9 B2 K/ |' d) e+ Z
$ X" _* F0 y1 |3 n2 ]( P' u2 B/ o
        last_data = last_diff = 0;
" |4 Y2 O" D$ m5 s* T
8 @+ K8 Y7 ?4 {' S        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );8 g0 x: r: \' L1 m3 x- |. j
0 |% J2 q8 Z# s5 u7 ^
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
- _0 A* r. n: s9 O. }; B        ZEROMEMORY( &queue, sizeof(queue) );; M1 ~' @5 D" x! r6 o5 p9 X! Y
        ZEROMEMORY( &exqueue, sizeof(exqueue) );; o$ ?* u, g  h& a- K6 a

; V+ k. [0 r: Y5 q6 P        for( INT i = 0; i < 16; i++ ) {" @) p2 o9 V7 {1 v4 r
                m_bMute = TRUE;
% [# l- d1 s6 P! G  Y* k+ J% i        }9 S% W# h0 D  _- H, t
}
; h# M: m: `6 T% {7 {
3 E& J( m8 r, TAPU::~APU()
) c9 Y  U- b1 K6 s' r# l" o, ~{4 d/ f, b! p+ N; o% o
}2 g, z, d5 K. E  P

1 Q# Q" Q3 {3 O6 F; D/ G. ~% Pvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
8 e4 T7 s, Z, Z4 V7 N$ E( i0 h{
% A) n9 Y" d+ {- S6 O" D( N& b! f2 o# ]        queue.data[queue.wrptr].time = writetime;
, q  n9 O. r9 l6 t. Z" O9 E5 Z! ^        queue.data[queue.wrptr].addr = addr;
" i0 y- b5 W, e/ \        queue.data[queue.wrptr].data = data;
9 O. K1 H7 {9 n3 h        queue.wrptr++;  P% P  M2 d: |" n% t8 b' A- S
        queue.wrptr&=QUEUE_LENGTH-1;
$ h. _" f' r$ w( U5 N/ j* W        if( queue.wrptr == queue.rdptr ) {: s  t4 V5 R( B! C" s0 p
                DEBUGOUT( "queue overflow.\n" );! I9 _/ M6 }. O% `/ b' q0 b5 i
        }
7 H) c. s2 A; k3 O8 G, N" H$ I0 R}
7 ?& o' `/ U' Y# Y% S, `
* S/ H+ V5 y# ?6 y! U5 n3 q  ABOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )2 ~( d5 S0 C/ I: k* V( `2 i8 q
{
) L  z- T' z- E  b  y2 D        if( queue.wrptr == queue.rdptr ) {2 @& C+ m5 M- I) J4 Z) D- T
                return        FALSE;' K3 w) S; \; {9 ?& m
        }, x8 L- }! A$ g$ R4 M2 O4 D
        if( queue.data[queue.rdptr].time <= writetime ) {
) z  \- ^7 ^3 H* ]: k4 i                ret = queue.data[queue.rdptr];
" l5 o& p& z) o" d                queue.rdptr++;$ z/ o. V* {8 h# j
                queue.rdptr&=QUEUE_LENGTH-1;
; _9 Z5 o4 e4 A                return        TRUE;6 a: K# \" o/ Z# O
        }
  `: ^; a0 Y* `: D9 @        return        FALSE;4 k& t: |4 @5 h1 [+ S6 G
}
5 M  v6 B* d8 |9 T. B  ^- C+ U
. L9 r! V/ f. f, Jvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )" O" T- v* ^& O$ w% v
{1 [* g. {0 K! E# T% F# j- B( N
        exqueue.data[exqueue.wrptr].time = writetime;
% n; l& p2 s1 B' O        exqueue.data[exqueue.wrptr].addr = addr;
+ _( F. L. |. _0 k  m9 o7 O: L        exqueue.data[exqueue.wrptr].data = data;0 e6 _( ?: V2 J: r% @) R2 T% B% h% Y
        exqueue.wrptr++;
5 E1 U+ }' ~6 b5 k) E        exqueue.wrptr&=QUEUE_LENGTH-1;. X: s( X# J" K' C/ i: \8 E
        if( exqueue.wrptr == exqueue.rdptr ) {
$ H1 q( {# @) N* f' O) l1 j                DEBUGOUT( "exqueue overflow.\n" );/ M0 ^4 ?6 c! O* V1 M0 S& c
        }( [( m2 s! V: ^. g0 D
}6 X9 w. |( |/ d) R
' l- O& o8 L0 |+ L
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )$ l9 o4 I/ ], Q5 I, M: c
{
) @4 F; Z$ s- V1 O4 \& t        if( exqueue.wrptr == exqueue.rdptr ) {
" z! H8 r5 V& ^0 ?                return        FALSE;1 F: U' X8 q! O7 c8 e1 U- i- E
        }
9 Y7 G7 w, k- u4 N5 {+ |& p        if( exqueue.data[exqueue.rdptr].time <= writetime ) {' }0 ]  K4 l* F7 f. Q4 I; c* c
                ret = exqueue.data[exqueue.rdptr];. [+ L2 N& I5 `0 B
                exqueue.rdptr++;
# r7 t( S$ Y5 _1 V* |* \3 R                exqueue.rdptr&=QUEUE_LENGTH-1;
- |- `- t' R' G0 p; ^9 O                return        TRUE;: N5 `. ]2 c2 i" v+ U  w
        }
# ?; b( E( l& P* X$ ?0 ^        return        FALSE;
% }( I# J/ \; w/ O8 n; \}
' c1 p1 f: _. g7 I+ ?. E8 q. p4 O* B+ U1 E
void        APU::QueueClear()/ s# R1 Z% g" I# A2 I" U
{
7 |1 u5 |9 P4 d: X3 U        ZEROMEMORY( &queue, sizeof(queue) );
( _" U0 M$ ]" i1 k6 b! w8 y& C        ZEROMEMORY( &exqueue, sizeof(exqueue) );
8 |3 X( \5 O% m5 ~}
8 g# }9 S- Z. {
  F# N: D: h, G: n& b) Cvoid        APU::QueueFlush()
  Q  o4 x6 ], j- V{
- b) d8 k# X$ ?; k3 S8 m) G        while( queue.wrptr != queue.rdptr ) {6 R% I: J' L& I' s% S$ ]( z
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
. R! ?/ T( ~* G  h                queue.rdptr++;
3 K1 ]/ v, V; {. ]( O                queue.rdptr&=QUEUE_LENGTH-1;
/ g: R. I& Q- P        }& g. c/ t2 d, D/ F7 h9 x8 V( j

) A' \9 ^) N6 `0 J& F7 y        while( exqueue.wrptr != exqueue.rdptr ) {
" C' l- f# w  o* h' o1 R                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
; {( V% B1 `' L+ e0 t1 `                exqueue.rdptr++;
7 [) ]  D+ a0 |* C! i2 E0 W                exqueue.rdptr&=QUEUE_LENGTH-1;1 V( G9 X7 q/ q3 |5 F
        }  }! `# ~0 P" O( _/ O
}1 @4 I2 P" Q# f+ K

5 G* b7 p0 y3 t1 @' \5 t6 Evoid        APU::SoundSetup()
  b: g: z8 x% S{
" X8 {3 R( ?7 y        FLOAT        fClock = nes->nescfg->CpuClock;% ?: ]/ T6 c) d; N) _
        INT        nRate = (INT)Config.sound.nRate;, Z. a8 Y( v% F6 ~0 |) ^
        internal.Setup( fClock, nRate );; R! S. b  e6 ]# h( l$ `. _. l
        vrc6.Setup( fClock, nRate );
1 {. ~8 Q" ]7 x; P( u- Y: T        vrc7.Setup( fClock, nRate );
% L& R6 N9 k  e+ Q0 f" Q        mmc5.Setup( fClock, nRate );
  b% G- d! O' n2 W: m* R        fds.Setup ( fClock, nRate );
7 W  t5 X( w  P2 ]        n106.Setup( fClock, nRate );
3 Z3 O! i% @% s" _. L: C        fme7.Setup( fClock, nRate );
6 F* w0 s$ W( m2 K: k( n, w}% h' t  K/ a8 O

  x% s1 r0 c) e9 a8 C* Z# X; gvoid        APU::Reset(). Q+ \# ^, g2 Y$ h# [& ~1 p
{
0 r9 @; i! k* ?% D1 ~        ZEROMEMORY( &queue, sizeof(queue) );2 ~( p  P+ J8 H. a0 J
        ZEROMEMORY( &exqueue, sizeof(exqueue) );$ F3 @- c. s8 w
; B' s- X0 V+ I5 M3 d
        elapsed_time = 0;
9 H/ o( n* \( ^* F. D3 {1 v3 ]3 F9 L/ W4 i7 e% X( G: n
        FLOAT        fClock = nes->nescfg->CpuClock;
' `) P6 J1 q- y" f2 @# s( Q; ]2 Q5 s' S        INT        nRate = (INT)Config.sound.nRate;
7 ?0 V0 A1 v. t& b8 Y8 d6 ]        internal.Reset( fClock, nRate );" Y, ?# P4 ], D+ ^7 w- _0 _
        vrc6.Reset( fClock, nRate );/ |- \/ \+ n0 j5 _; M
        vrc7.Reset( fClock, nRate );
3 K! C8 y2 Z9 p* V        mmc5.Reset( fClock, nRate );  m! z1 E% e4 C* g  q
        fds.Reset ( fClock, nRate );& ~! U" d6 R: S7 ~
        n106.Reset( fClock, nRate );
) N) r9 w  R. @        fme7.Reset( fClock, nRate );
2 Y  B$ v: _. M: U+ c$ p
! c( v% i6 a- j: ?% Y        SoundSetup();
3 ~  L# j+ I2 @6 y1 }5 v}
  c4 t6 E' B1 K9 c- F3 c) e' Y4 q& ]# v1 j* G' x
void        APU::SelectExSound( BYTE data )1 l  ]/ V/ s5 S& {" S* a# V
{% ^: [2 R5 a! _
        exsound_select = data;
8 t( T1 j. P' \* y% m8 H' E8 g}( q+ `5 v+ v2 k! z& `
) q5 e: W+ s! R+ ?7 v
BYTE        APU::Read( WORD addr ); V. B/ a9 i7 I8 u" H" j: h8 m
{
# Z# ^* I% i% r7 M* L4 r        return        internal.SyncRead( addr );, S4 f8 Q7 e7 G8 c1 _
}
0 i0 a4 I  z! _
, W. s! P2 w; jvoid        APU::Write( WORD addr, BYTE data )
% v& U- P, m' l! t: O7 M$ d{
: O* k9 J. Z. D# t; |! I, {        // $4018偼VirtuaNES屌桳億乕僩
. D7 @( X- b! [8 I        if( addr >= 0x4000 && addr <= 0x401F ) {
+ J7 C; q+ ^" P6 ?2 x! v                internal.SyncWrite( addr, data );
+ z' x* L, `# o                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
: F* _- a( z: E        }
4 O3 l0 B& V3 J5 ^}
5 j1 J; _  N: @5 @; b( V0 z- [
7 o* P4 f3 s+ h0 F. pBYTE        APU::ExRead( WORD addr )
$ P: R  g7 E9 M/ O5 C, C{( F, R. H1 Y$ n6 ]7 ]- F  \8 X
BYTE        data = 0;
+ i- U( i' c8 @0 v3 e1 F1 t. R' t
7 R) c+ P5 l- Z0 r% [        if( exsound_select & 0x10 ) {
% T2 ~7 e# ~4 p0 {6 C/ q9 a                if( addr == 0x4800 ) {0 H6 v2 @1 K9 F0 `/ e
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );. K$ |# ]% ]" w$ Z! I! H
                }  k$ W# l7 z, l4 X1 A& V
        }
$ Q  H1 W: t9 ~* K3 E0 u$ R/ i        if( exsound_select & 0x04 ) {* c0 x1 v1 F. h- w0 T
                if( addr >= 0x4040 && addr < 0x4100 ) {
' I# ]7 x7 S/ ^6 w- y                        data = fds.SyncRead( addr );3 m8 \2 Z  X' n  G
                }
" v; ~* c+ @6 w0 `        }
2 y! r0 W8 `  A$ L% n' y3 m        if( exsound_select & 0x08 ) {4 H1 J2 |; N2 A% p+ g7 m* ]8 \
                if( addr >= 0x5000 && addr <= 0x5015 ) {$ c5 y! P( K) R2 _' K  M: i+ b
                        data = mmc5.SyncRead( addr );
, O) a3 K9 o: j3 N. E0 r                }$ L/ T! X0 O# F
        }0 }% Z6 d2 b1 ^" e: z1 ], O; z& L0 s- t' |
5 P7 y7 ?; D& ?' E* p9 C
        return        data;& p, ~, Y* d8 X' P: ~2 X
}
7 B* J2 I  t% `% z
. g, X% w: ?4 h" cvoid        APU::ExWrite( WORD addr, BYTE data )% I9 a; T0 ^. h+ I7 [( {; h5 ]  I
{: P% q! ^* \( E  L2 p! |
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
( {( x6 k/ B$ s0 _2 r8 j7 j- w5 b$ ~/ q; g7 m' H  ~, w$ @
        if( exsound_select & 0x04 ) {. G% f; P; C, [& r+ z. W2 O4 |
                if( addr >= 0x4040 && addr < 0x4100 ) {! V; R# ~  `& A3 V
                        fds.SyncWrite( addr, data );
' E- u1 w7 W5 q8 U( L                }
: I# s5 F3 u' W5 [% J7 U4 n7 z        }
7 @* m3 w+ b4 |: ^3 S# N: \0 V$ T. Q5 A5 t
        if( exsound_select & 0x08 ) {4 y* F9 _' X0 ?% Y- a7 m4 @
                if( addr >= 0x5000 && addr <= 0x5015 ) {
. h8 P& T) s1 B. c1 p  h                        mmc5.SyncWrite( addr, data );
$ p$ x& d& Z: {! H$ h# j                }
& X& [, n7 `) w4 }        }
, G8 T% D; N1 O}
1 U5 f  c: `4 L: Z8 E' U! G: M+ P' t1 H$ ^8 p( O
void        APU::Sync()3 J# n! C+ W# L9 L, u
{
) P9 n* @- ?; |+ k4 H}
9 f5 c! I1 }5 u8 d" `# n, ^. p) T' A: a
void        APU::SyncDPCM( INT cycles )
. V$ r* E! E) e1 V" D( p{
; e+ j. m! _7 m7 \        internal.Sync( cycles );
9 f& o6 r# q5 H- _3 k% T+ c3 S: f5 d2 }# E" ?6 f: b
        if( exsound_select & 0x04 ) {
2 g8 R1 [: T! |( [( a                fds.Sync( cycles );' [) Y' \0 k; ]8 _
        }
: d  E! `! b% v9 c        if( exsound_select & 0x08 ) {/ X) }2 v% l* H- P! `
                mmc5.Sync( cycles );$ P6 b3 R# ?8 u$ P" u1 p% t
        }  X9 T7 f& g: a2 q; h! W  b" m
}
8 `' e" l  r  {
" _, ?3 m9 w- n. B9 W. lvoid        APU::WriteProcess( WORD addr, BYTE data )
( C" N! _" V# ~. b, W5 r6 }{0 D4 }0 ?# g6 J: T& D! ~- L
        // $4018偼VirtuaNES屌桳億乕僩
6 x" {* s& r! d8 }* L  ]        if( addr >= 0x4000 && addr <= 0x401F ) {
5 v) c6 M2 Z5 `6 ^# X3 L                internal.Write( addr, data );
1 n. Z) ?4 M0 ~2 ~9 x        }
4 m5 y" J6 I! w}
: n8 C/ `# U$ }
( e# @" A7 I! j, l9 T0 m4 svoid        APU::WriteExProcess( WORD addr, BYTE data ), {4 ~# t! Y" K
{
- r; `. u6 Y. N% ~* s6 r" I        if( exsound_select & 0x01 ) {* \2 K6 K' [9 F: W6 t1 x% k
                vrc6.Write( addr, data );
; }2 T8 a$ g7 ~8 b: O5 ~7 ]) M        }( @9 r8 X) w4 |; F! ]* s0 J
        if( exsound_select & 0x02 ) {" L3 S( ~/ G/ c1 A* _4 v
                vrc7.Write( addr, data );& j1 L* J* u: Q! @. V
        }
( y+ P# Q/ Z0 _- }        if( exsound_select & 0x04 ) {
, l5 J" z1 n0 w0 W0 F                fds.Write( addr, data );
, K7 ~/ R; W$ i5 W: V' B! B4 v3 n        }6 o" F! Q5 H8 s, f
        if( exsound_select & 0x08 ) {, A1 x6 c9 ~' B1 j
                mmc5.Write( addr, data );! o5 y7 L% R0 [  m3 |9 E
        }
4 Q2 N/ t- T7 k: Q; D        if( exsound_select & 0x10 ) {
# C3 b0 ]" C2 b' ?4 g# {                if( addr == 0x0000 ) {
/ b8 o& V8 |% B                        BYTE        dummy = n106.Read( addr );& |( v; m9 s6 t! ~
                } else {
: x% {" F/ T. u                        n106.Write( addr, data );) z# v$ \4 }, C' C4 M1 Z
                }
* P! V# |9 w+ k" h* }1 T: r        }
5 Y' f& s  w! ~( v        if( exsound_select & 0x20 ) {
% l! r; x+ t$ C+ J" W                fme7.Write( addr, data );+ d2 s" @; Y& o! V; J
        }& W; g# n% b$ x, }& |4 K
}
  ]% \& a' k+ h7 x$ B' V4 ~# I. a% z
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )4 z! l" v; r0 A, `
{
8 @3 T8 R8 U; Q( YINT        nBits = Config.sound.nBits;) J) z  m3 p- d+ Q: w
DWORD        dwLength = dwSize / (nBits/8);3 i6 b/ |) O1 A8 s; `/ e0 t
INT        output;
/ ^* b* [- |. T$ rQUEUEDATA q;8 n0 @" ~- k+ ~
DWORD        writetime;
' D. k' g$ M& q1 m! O
7 O4 B" b5 |% W, ?LPSHORT        pSoundBuf = m_SoundBuffer;$ F5 @+ m% c! E' N' T. ~! j+ u
INT        nCcount = 0;
( F( e5 b3 @: e% x  b$ B2 \
( n5 r+ b% ~! w, ?$ P8 W& I. a; vINT        nFilterType = Config.sound.nFilterType;
, Q/ c& a2 Y3 ^; ~: ]4 I$ I) w  d  C! F9 G" k7 |- |$ T$ g% e
        if( !Config.sound.bEnable ) {' |( l& k" |2 A1 |* S1 o( p4 W
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
: o" ?7 k/ R8 x, u$ j1 U                return;) E9 O$ A* V8 |1 P. R' E1 O
        }
5 [0 n. r# b: K7 P+ q5 {5 r1 L" p; I4 G. W4 f0 {" L
        // Volume setup
6 z8 f" u# p0 x+ D& h, ^        //  0:Master
: X' Y0 j$ U5 i1 }        //  1:Rectangle 1  O& i8 x; n+ ~) H$ k0 X$ z
        //  2:Rectangle 2
6 V/ d% p- r/ o. E+ N' Q8 y        //  3:Triangle( W# j; Q9 i+ \  m& h
        //  4:Noise/ n: w# I5 U! w
        //  5:DPCM
) J5 _* ^2 c# ~/ }2 V        //  6:VRC6
2 }' u# k: C- W/ e5 ^        //  7:VRC7
% R0 c+ L8 _7 l7 ]. N. l        //  8:FDS
' B! L6 Z- [" o0 m1 V5 Y        //  9:MMC5- C* G8 V6 H5 ~# K% {+ p
        // 10:N106
& n! W+ V: L/ c1 r- [; ]$ f  S        // 11:FME7
5 D" v% J' |! @4 p; j, z4 o$ n6 G        INT        vol[24];
/ ^# \; M; O+ N, ?' D: D        BOOL*        bMute = m_bMute;0 P8 C, G# v6 j. l- M8 x# }
        SHORT*        nVolume = Config.sound.nVolume;) z! U+ p  t/ p( y- O
) Z7 n1 U) {6 P% o2 |8 m
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
: \. S. ?$ s; |$ W8 i; Q
8 a) V- |: U( r+ b9 C+ O        // Internal
( Q1 E3 i3 `. A( L! [: w        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
' T' Q/ p1 M( D- c        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
) ?7 R* Q& a, Y# _, F: }8 h; P% Y        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
$ k6 \1 s- |# i( W0 I: R* N2 r        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;7 j! H1 U* L1 q" H- E
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;2 f. }$ ^) y# v! t4 {
5 e/ y) f' e" F) ~. B7 _
        // VRC67 ]* U, _' s) G8 x. z
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
- k5 C( g3 J& x( P: u. z        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
0 D3 C! B  B, j# I        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;& Q4 I* L: Q" i( s$ T* {5 p! X. f

- }, S7 m: }) t4 ?8 [. ^7 O3 x( Z        // VRC7
, ^! T" Z3 y1 v% B        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
9 i( T* s6 |* N2 ?0 q* ^. Z) @; q* k5 \- \  G
        // FDS: X; M. c  [+ I! [
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;) H1 ]3 k" B' o( k( Q1 `" G; O

* D8 ~# ^2 j* I5 ]- b        // MMC5% C& R0 T9 }& x
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
7 B( l5 Q2 ?; d* E  o        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
4 B1 B. g6 H9 E( P3 N0 A        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;, J: z6 j- A& r3 \3 u: \

( E4 U9 N$ Y* ]: u1 x0 y        // N106
$ I+ O1 I1 S' D6 Y* J4 H+ K# @% |" T        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 n1 \$ G1 t& @% ?) @7 @& |        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 Y1 P% D  ^0 u1 M! o) G; Y0 q        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;# o3 T+ V) J- e$ l0 i& b
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
$ u9 x& k4 |! j. w1 f        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. R/ P# J- w0 Z9 x: d% y; I        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;2 _3 L/ o4 o4 M* ~9 q& n3 k% N3 b9 u
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& ?3 @# o( ]+ A' E% r# j9 [4 d        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;5 u' a* ~7 h9 p; O4 Z/ a! @1 s/ h
" p5 s+ U# a. i+ ^
        // FME7
" {4 p, _4 Z; ?1 h) M# I        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
, s+ Z- p9 X6 I. t        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
- v( e) g& R, v" s% c        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;  q8 X0 C1 U( }7 o% @
: q5 B+ }* g$ W3 c/ J. I" L
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;. r+ F1 M+ j  B$ F& T1 K
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;, L7 |* H* E) Y# T' a& j0 B
& I  k4 T- d: ]' q
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟! z! f5 o# ^7 ?! k. O
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
$ R8 O" g* E/ R) f9 p" Z: j4 J& h                QueueFlush();: P; U2 E: r/ H! g
        }
- U' N- @2 D# R" j* W" l9 I/ j# H8 m7 k( L+ V6 D9 a
        while( dwLength-- ) {
$ G  G0 H, z' p                writetime = (DWORD)elapsed_time;+ ^8 ]& ?( ^) S

; D0 x% r, G# n* q0 c                while( GetQueue( writetime, q ) ) {9 W3 j' W$ d9 L* v5 X) z- ]
                        WriteProcess( q.addr, q.data );' o  y7 c% |) {; E# F! {+ {: ^, l
                }
2 u# M% i3 t% W  U! ]$ b% V- ~( s6 T5 L! B) {0 F9 ]
                while( GetExQueue( writetime, q ) ) {4 b- k7 `9 `4 d1 n4 R6 ~
                        WriteExProcess( q.addr, q.data );
) X5 t, X6 b- F% s6 u9 e# U* w7 }                }
% s3 ^- E3 l) \8 M
, ~3 q; e$ J# g0 v2 a2 l- a- Y                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7; a/ q7 u/ b5 w
                output = 0;/ I0 f, X- w, L2 u$ H. L
                output += internal.Process( 0 )*vol[0];
/ R* j( `+ O. a                output += internal.Process( 1 )*vol[1];0 v& O2 L2 A" T5 Q& }$ l3 B
                output += internal.Process( 2 )*vol[2];
/ p9 I: B/ }: A% j8 a1 M6 o+ q+ i  j                output += internal.Process( 3 )*vol[3];9 {+ Q+ a/ ?' r3 Q$ |
                output += internal.Process( 4 )*vol[4];$ Q) B. z$ P0 w+ r. C2 p3 T9 y

3 H$ K: L3 R; u! v$ K, w                if( exsound_select & 0x01 ) {2 q2 d( X# p- h# Z3 L3 p/ D
                        output += vrc6.Process( 0 )*vol[5];
$ n& a. G5 P5 x                        output += vrc6.Process( 1 )*vol[6];
# ~$ E8 ~, k4 E. K' l+ K% g7 v1 E                        output += vrc6.Process( 2 )*vol[7];
; D* a% f1 Z; w+ j6 D( Z1 L                }3 P/ ^& M: s# e: M
                if( exsound_select & 0x02 ) {! a7 O* m8 X+ c% M) X7 w0 X8 k
                        output += vrc7.Process( 0 )*vol[8];/ {. i8 M& ]7 W; x2 a
                }
$ W& w& M. m9 ~9 r2 o, x                if( exsound_select & 0x04 ) {
! R4 O# E1 l9 e6 r/ K6 r6 K5 y                        output += fds.Process( 0 )*vol[9];  z& K0 i! D" e/ n1 {
                }
( p- [$ p5 V1 ]# d8 m( [' y; B                if( exsound_select & 0x08 ) {
, P: T) h; ]. s7 Y/ |' U% n                        output += mmc5.Process( 0 )*vol[10];
/ S) R. @* V9 F8 z& S1 y                        output += mmc5.Process( 1 )*vol[11];
! O* @& Q& d+ E                        output += mmc5.Process( 2 )*vol[12];6 ?) |8 `, s) A+ A7 L  A% R
                }4 Z, n; N; y2 P5 N0 O8 y( F
                if( exsound_select & 0x10 ) {9 i7 b. P) x$ N. ?+ o
                        output += n106.Process( 0 )*vol[13];9 ?6 X) I, ?1 a8 O* S$ g# \' L+ P
                        output += n106.Process( 1 )*vol[14];
; Y& c) C7 g& x) [1 y1 m7 P                        output += n106.Process( 2 )*vol[15];
* k6 B! Q" R$ h: t                        output += n106.Process( 3 )*vol[16];
; c( v$ X2 U" M' L) C                        output += n106.Process( 4 )*vol[17];
# Y3 N/ e# q$ H% f/ i                        output += n106.Process( 5 )*vol[18];; A; Q1 p* y1 B6 N
                        output += n106.Process( 6 )*vol[19];
; g5 t4 G$ e# a, K2 ]# R                        output += n106.Process( 7 )*vol[20];/ `! j6 u  X, e3 G& m8 N" c6 T
                }
( @6 @2 C6 d$ L4 [1 ~+ R                if( exsound_select & 0x20 ) {' P# j  \& I3 ]1 K1 M3 X# y  F
                        fme7.Process( 3 );        // Envelope & Noise
, n: Y5 W, q' f' R# h  z                        output += fme7.Process( 0 )*vol[21];( V1 x& t& e+ c. Z
                        output += fme7.Process( 1 )*vol[22];
, A) {9 _4 l# G+ j% z                        output += fme7.Process( 2 )*vol[23];
, w- J; }6 @0 ]2 x                }
9 o; i6 p& \8 D
. F8 y# V- p2 j/ k* T: {; h8 [6 G. V                output >>= 8;  `- j. U2 n! T( f# k
: O" Y; q/ b1 a; b7 s' D  }
                if( nFilterType == 1 ) {
. @$ h, R  d. F& l4 K                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
2 v0 p0 i8 F4 P! n2 p                        output = (lowpass_filter[0]+output)/2;
, l2 e! h* T# \& J, X' |                        lowpass_filter[0] = output;( ?6 u0 A- Y# p$ Q- D
                } else if( nFilterType == 2 ) {
/ g* \7 g3 q" Q# n4 k. w# q) F                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
; C; t# A5 Q, l# T& w6 c4 o                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
0 y5 f! M) @4 \& N2 T                        lowpass_filter[1] = lowpass_filter[0];% b* H+ p' {- g) n. k; x7 }4 m
                        lowpass_filter[0] = output;
. O, M  ~& `2 [                } else if( nFilterType == 3 ) {
3 @% u' s4 ?! K9 N$ `* A                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)0 T7 Y# S4 v/ J/ C2 ~
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
) [; J4 q2 x# ]( \: j+ n                        lowpass_filter[2] = lowpass_filter[1];( {8 N& \# q, C. z' g
                        lowpass_filter[1] = lowpass_filter[0];
$ Q8 L7 [- W3 D7 X  }0 \                        lowpass_filter[0] = output;' M  y9 h8 d& B+ C2 M" g! v% o
                } else if( nFilterType == 4 ) {
  X2 L8 r/ R  m% o                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
5 f+ a8 c6 V( ]0 Q2 K                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;2 {9 W9 B$ }. W4 ?+ J$ a
                        lowpass_filter[1] = lowpass_filter[0];8 [+ N+ ?. ]" R% L& F
                        lowpass_filter[0] = output;
  K* q5 |' Q' ?7 T! N: r                }0 S4 k$ Q& x" \4 E& s/ B! N. w
( K# ]* e& M- s/ t) X
#if        07 y2 t2 K/ u3 q
                // DC惉暘偺僇僢僩
7 {2 v( T( T4 m  x                {
% P% g, m! e0 M$ B                static double ave = 0.0, max=0.0, min=0.0;5 q6 X+ P( c. G5 C3 Y& J
                double delta;
' H0 D! ]% U3 Q/ F/ A& y                delta = (max-min)/32768.0;
2 [( K% S* o( D+ U  Z5 |                max -= delta;+ E7 e& H2 ]" X% ]/ _; U
                min += delta;
2 S* J+ h+ V! w8 T) R( O  X                if( output > max ) max = output;; w3 h9 V5 Q% g% g& e  Y
                if( output < min ) min = output;0 c2 G& W1 v) S% I2 q
                ave -= ave/1024.0;% p# H* \8 W/ `- ]  [8 m
                ave += (max+min)/2048.0;/ u- J) F. Q5 n! H" Z
                output -= (INT)ave;
2 A, r. P3 b- X* v  h: K( A                }
5 w9 z7 z, p9 d& z) X2 g#endif; Z% Q3 V3 j; j. K8 q$ [) _$ @
#if        1$ H. z: ^- g- D( F/ e7 i
                // DC惉暘偺僇僢僩(HPF TEST)
2 B7 d! {3 I8 u                {
. S: k& H$ J7 N  T! s//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
% L0 ?/ \" l3 S; Y& ^3 G                static        double        cutofftemp = (2.0*3.141592653579*40.0);( |$ P, C3 I3 w- Q/ T
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
. C2 D$ J# P! L  @% s                static        double        tmp = 0.0;$ h. a- }" N3 s4 E
                double        in, out;0 @& d2 d* p# ]4 H; d
" ]# K8 b- _$ f- Q
                in = (double)output;
+ N: W' \5 J& T; Q- B. C                out = (in - tmp);
4 ~; k9 g7 ?' i                tmp = tmp + cutoff * out;! G8 F8 ^# ?& V; A6 v
% V6 `  ~$ f& T; g7 t! e+ u5 M
                output = (INT)out;
. V+ t/ f" k0 O  F' f8 Y0 {                }
3 }5 O* y8 A" C/ q5 X+ C: x#endif
" i$ w" S2 Y4 `# @#if        0# p/ t1 ?) H& x1 d! N% e# W
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)' J. S# _" z! ^2 X1 T2 I
                {
' G. C9 j5 W1 K" o! ]                INT        diff = abs(output-last_data);2 c: R+ j. f" P* x5 S: x0 d' c& G
                if( diff > 0x4000 ) {
" n3 |9 X# a9 M! p  _                        output /= 4;
/ p1 y' P. j+ Y9 G                } else " D7 R# U. ?6 U/ i6 q
                if( diff > 0x3000 ) {
: K- R! Y% O) {1 H* W; e7 H4 r                        output /= 3;
) H7 L$ B2 ?, J3 k; i' t" f                } else/ a( s3 [7 a! G5 B" f1 W9 _
                if( diff > 0x2000 ) {) r; C! f; d) P+ _+ b' K  e& x7 f
                        output /= 2;
5 W0 a. L5 Y0 c+ l                }- a5 Y( F- z/ q
                last_data = output;6 G1 ^+ y8 V: i' w* D3 [) V
                }
% n1 n7 ]+ K4 i5 _3 \#endif
4 N! o  S3 m/ `" J8 }: W                // Limit
0 T5 h! C1 e% I# J+ g                if( output > 0x7FFF ) {
; Q& T0 z8 T2 M$ `7 O" V! A) ]4 k9 w4 _                        output = 0x7FFF;2 z8 a8 P7 O* O/ H0 w
                } else if( output < -0x8000 ) {# A8 V% J1 _" {9 i1 {+ x
                        output = -0x8000;! Q2 H* b2 R) d0 C; L0 M
                }# X" K% w) P5 j/ p, p6 Q/ o
0 i: \/ O: O$ W7 r" K
                if( nBits != 8 ) {* K( ?5 W0 a/ P9 U2 T+ o
                        *(SHORT*)lpBuffer = (SHORT)output;4 `) l: Z8 o6 W7 l, d0 k
                        lpBuffer += sizeof(SHORT);9 J5 B8 b5 L% S0 H/ x/ u$ ~
                } else {+ P' T, K  ~, F7 b" \" E/ d( d
                        *lpBuffer++ = (output>>8)^0x80;  [7 j2 E% l( n
                }
% F$ q! k' W) k" H6 n# w
  ^9 N) J) H5 T) }3 [& Y                if( nCcount < 0x0100 )2 B: a) }' C  J
                        pSoundBuf[nCcount++] = (SHORT)output;
& t2 N4 M) `. V0 L3 n1 J3 q
6 X* `2 b3 s. [9 a/ E$ R0 A+ t; w6 i//                elapsedtime += cycle_rate;" f+ L6 P1 i# ~  N5 ^9 L0 Z1 s
                elapsed_time += cycle_rate;
; Y% b3 i  n9 ]3 {+ J        }
4 S3 |7 c) B9 I
+ p; Z. W+ z" c; N$ q#if        1
3 x. O& _# L; A. c" U6 y        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
9 O9 o( k5 Y+ k, G                elapsed_time = nes->cpu->GetTotalCycles();
# H/ S- X7 R: e& ~& ?& Q- I        }
% v( {# F8 o# f. @7 P        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
" H) x8 O, q. X                elapsed_time = nes->cpu->GetTotalCycles();
& @  X! _) i# Z5 W9 R        }8 k+ C1 Z+ R' c6 Q6 w& p/ p2 k
#else
9 ]7 @" L3 o" m6 O: [        elapsed_time = nes->cpu->GetTotalCycles();7 `& J) x) y( i  M, C* O
#endif5 e; X9 j; y/ b3 q" X9 u
}" I& q1 ~+ `+ L1 F4 Z) p
# u" r8 ^. l; X. a# V8 t5 k
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
, [% E2 {# V( L+ ^# N+ lINT        APU::GetChannelFrequency( INT no )2 q/ M- i5 ?- f4 K' A/ S
{7 i6 @) m% G4 h/ S: u& _5 J
        if( !m_bMute[0] ). @( b% q# S3 U0 d6 O( \
                return        0;
! H" m  j4 a9 j9 ]2 B
" X" i3 m) U, p  Z4 F3 B: m        // Internal1 z8 f* q' P( k/ v& V
        if( no < 5 ) {
+ j4 @2 J3 A9 X: ?" J                return        m_bMute[no+1]?internal.GetFreq( no ):0;0 T$ `  s- x- Q0 f
        }# n7 w& X7 d5 d" l  f7 \2 u
        // VRC61 X8 f4 {; y9 f! Q9 f4 m5 m: x
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {+ c* S9 u: _! S/ F
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;" r: o# k1 X' i( V; @
        }- i) k8 j2 Q9 f! c. f
        // FDS2 s* H# U5 z8 Q' Y5 G. X1 y+ T! d
        if( (exsound_select & 0x04) && no == 0x300 ) {
. P( N' {- w& R, N7 q                return        m_bMute[6]?fds.GetFreq( 0 ):0;& |9 A) T# B3 ~1 H+ p
        }8 s: }  U! Q' T2 P8 ^
        // MMC5- l% w4 H* W# L
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {$ z& c. T5 T5 R, v4 X& q
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
6 `3 e5 A6 q- R2 k        }
2 Q0 U! J$ U, }1 g% f6 b) E        // N106
9 n! s4 B) }& J8 y8 W/ M5 _        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {5 {6 _2 {" r' b1 w5 H/ U
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
) Z: i7 [8 b6 j. V% r$ o; E        }6 o. J4 |1 e8 \  O
        // FME7
- s6 e9 K, `/ G0 C: b" R        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
; I) M8 o; H1 c                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
2 r. z/ d/ c0 U! A        }& [$ o5 q/ s7 g  _
        // VRC7  y+ M$ |7 @! R
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
' F1 ^  t0 Y' m5 O6 R                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
# O% l0 c3 n9 T  V        }( w% R3 d8 N4 W$ A
        return        0;4 h* w. x! X" l0 ~/ |. d. {
}
& [( @6 g! r0 d( ~$ N: e( u( A  @. e8 O1 ~7 A2 I$ \2 A8 D+ }
// State Save/Load
3 }5 v/ `, O0 K1 N3 nvoid        APU::SaveState( LPBYTE p )8 R+ ~5 n! A0 f8 ]
{; i, b! F! m( Y
#ifdef        _DEBUG
$ M% J$ ^2 u' t# `. J* u& PLPBYTE        pold = p;
- B! X9 \( q6 a" S  f& E) i#endif
3 U! |$ N: X) u7 {% s( a& m! F# i& T! o, ~+ e1 T0 y8 V
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞$ _! J- c" v! l% u. m- v
        QueueFlush();- ~7 x9 {0 P! H$ G; V

5 z/ v( ~& O! Q+ ^" p& U+ `! z% E- B        internal.SaveState( p );' C5 z$ @7 s% n% V- d+ s6 ?" z
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
" W& [2 j5 u- u4 M- Q- w
/ u( j* v" m/ }: W8 f/ ?        // VRC6
& c& ]2 s! e$ y        if( exsound_select & 0x01 ) {
8 M( z8 Q( R9 m9 x( Y9 E                vrc6.SaveState( p );
: B- n9 c2 Z) A: n                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
: z+ b9 t  V; x4 _* S& G+ U. n        }
  y5 J& Y( S6 Z4 a* N        // VRC7 (not support)( P  }1 j6 Q+ L
        if( exsound_select & 0x02 ) {
2 e' _/ z+ x9 R7 N$ I4 E                vrc7.SaveState( p );
5 g* @; \# Y1 V3 n- _+ x                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
& W% H& y  I* g8 x# M& \        }, N* ~/ {1 p  X) n% F1 ?
        // FDS
( {/ z+ p7 k: t% [/ N        if( exsound_select & 0x04 ) {
# T; L0 w9 m6 X" r- b                fds.SaveState( p );
4 r: a5 C" @" Q+ d4 [7 R                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding" O/ l1 d# N6 t" o5 E' c! b
        }
1 `) f  R8 v8 J  P4 c: U        // MMC5: C5 l5 A8 V+ E& T. u$ x1 x
        if( exsound_select & 0x08 ) {4 y8 {7 Q) {8 U/ ?  G8 }* Y
                mmc5.SaveState( p );
/ P7 ]8 i! p, o" `2 L; }                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
8 H* G2 d/ |  D+ X  J! s        }/ J5 r/ N. v1 Q4 d9 [. m  M/ x# L; y
        // N106
1 l$ U. O5 P% w- _+ I* w        if( exsound_select & 0x10 ) {% A) r' v3 O4 t* h! X
                n106.SaveState( p );
3 \  B. W- I- x& K! _' G" q                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding3 G5 z; Y2 l# o' [& i, X) b! |3 \) `
        }) z$ g9 L- Y# p/ W) m
        // FME7
3 l  O# v% S; h6 T* I5 j) Y        if( exsound_select & 0x20 ) {# h6 l* L, E& Y9 \1 M) G$ K4 a
                fme7.SaveState( p );& {# n3 W# A0 j) C0 P- I# G4 `
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
0 J+ H/ d# o( @9 y  L) L: s6 J        }- s  P6 z' c( o7 g* M0 X$ M; I/ r

7 t/ `& [  j" E/ w* I# j#ifdef        _DEBUG
2 N! H/ d: ^+ t% B* {( U4 CDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );" F+ T3 I; j8 Y% v6 |
#endif" A2 G0 i* k/ r5 z5 T/ T9 E
}! z& W' J9 ~3 F# G; Q: s- P2 S6 e
7 g; r2 V8 Q' I2 A9 m$ a
void        APU::LoadState( LPBYTE p )
3 @3 K5 D( d0 X, y{
2 ~. Q! O, k9 e* o. Y2 H        // 帪娫幉傪摨婜偝偣傞堊偵徚偡  |- @. k) ^' q. w5 g& G: w
        QueueClear();
; A7 ^# H5 W6 N) ?$ d
1 P# r2 Y- P* {. ?        internal.LoadState( p );
9 q* r, h! u" U! H& m9 w        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding2 H# q* C8 x& L
1 t  U( G$ t+ X* z8 b
        // VRC6
' i; q0 L/ s. u' q        if( exsound_select & 0x01 ) {* \, F8 h$ O, c: `. }
                vrc6.LoadState( p );
& c$ O1 E- v, Z9 ^) Q5 Q                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
9 @. V) n: X- P4 h0 W6 n( k1 u9 d        }
/ o8 D. F& A) I! c        // VRC7 (not support)
3 j( c' z9 g" z        if( exsound_select & 0x02 ) {
8 H( `- J, n+ \) G  Z                vrc7.LoadState( p );
# K( l- I3 K# j( @+ N                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding" C8 [& z8 k0 z4 d& @% Q' z' M
        }
7 b* j  l" _6 c3 e        // FDS
( x. V" A( _% @# x- R        if( exsound_select & 0x04 ) {
  y1 O: X1 d4 a6 m5 ~! s$ h, y8 a                fds.LoadState( p );3 I9 I+ y, B: U  W& ]
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding) M8 s2 `  k3 k2 q/ ~; f
        }
$ t% h0 a, \; B4 x8 E) K        // MMC5
0 E' O' a" g& _: C; n- U        if( exsound_select & 0x08 ) {
1 _! q" |- ^3 M7 w$ ~                mmc5.LoadState( p );$ G: b) F# ^5 G! n
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding& T5 N  f7 l( q& E2 D& H, p
        }! Q" V8 p9 h; e9 d, c# X+ V2 n
        // N1069 G: l5 i) i1 z; I; O
        if( exsound_select & 0x10 ) {
' v0 e) {$ N/ E) ^5 z+ T                n106.LoadState( p );/ e& b5 w% P0 T, ?/ I, d
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
2 X7 a9 A: _  t' a3 i        }
) w% |- \. T8 f5 w' y  B        // FME7" H" g6 o- X3 O; k
        if( exsound_select & 0x20 ) {$ v& t7 d$ Z( ]0 }  I6 O' X
                fme7.LoadState( p );
- b: V9 U# S2 b4 t2 s                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding8 W0 V) J6 H) u
        }
/ X* z+ w+ H  j" F$ P; b4 p) {}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
1 S1 U5 a) M6 x2 \1 O$ \可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
- B# I" T( J# k3 E+ b( W7 ], R感激不尽~~
9 I; f2 r& s. A" w1 c
恩 我對模擬器不是很有研究,: S2 A6 |. N! i6 B+ V. q9 ^: z" @
雖然要了解源碼內容,可能不是很困難,( A; w. e/ y$ u1 h
不過還是要花時間,個人目前蠻忙碌的。3 \( N5 D% x# o$ X

' n% j3 x3 i) `% X- L* U3 _給你一個朋友的MSN,你可以跟他討論看看,' r/ a$ n0 q. {
他本身是程式設計師,也對FC模擬器很有興趣。
8 d1 I) H3 r1 G) O# y! P
3 e% s0 T& h! u& k5 AMSN我就PM到你的信箱了。
7 n. e2 p) g$ ?9 p5 n/ a
# o0 Z& @, D  E4 V9 l4 ?: H5 q+ k希望你能有所得。

该用户从未签到

 楼主| 发表于 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 c) \- U! f7 g% L  \* d
呵…… 谢过团长大人~~
8 g7 X2 j! }0 D+ q# J

& K, q: C% @+ n  f哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
! V4 c2 w7 G" h3 f+ a团长的朋友都是神,那团长就是神的boss。
) v; L) ?/ v  ?5 e/ l, Y, t! B  C* W
哈 不敢當,我只是個平凡人,; f% l$ X. A! a  l
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
4 m3 g3 U: V& A# oZYH
9 M. u% D+ c# d) }% W5 K( |. DQQ:414734306
5 ]5 n" X2 g  I2 G9 m9 FMail:zyh-01@126.com
" y# ]  i( _" K- G% [
3 v2 I) K4 B# @  N4 \# X. }! N* X他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
1 f0 L2 l5 {5 Q4 ?再次对团长大人和悠悠哥的无私帮助表示感谢~~

) \; m; H$ e6 G: v不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-5 03:25 , Processed in 1.095704 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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