EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。* A+ Z" O7 M7 o* w
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
! e6 f5 X/ D8 g& {# h这里有相应的模拟器源码,就当送给大侠了~~
9 d" B. |+ j* a  |! E, Jhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 , I' {  F. P2 R& }' ^& k
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。/ m3 I7 ~5 W7 g% r+ v# L, x
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
6 x8 _; S0 K) r+ U这里有相应的模拟器源码,就当送给大侠 ...
4 |- Y! [* ~0 n( b) l- I
聲音部分(Audoi Process Unit = APU):8 i) I* k& O8 E6 R1 y
.\NES\APU.cpp+ Z+ `% F2 I# M; h8 s& f- n
.\NES\APU.h2 }0 s+ k9 _" x+ [+ l
. H- \' B+ s0 j5 Y  l
- P/ z6 \' x1 b. C: q# S& w7 W  ^
影像處理部份(Picture Processing Unit = PPU):2 i) K( P) q% @6 x  S
.\NES\PPU.cpp
3 D3 Y# d; i) h.\NES\PPU.h
! d1 q/ o  x  D! s  E; @& j: x0 H  P0 Q2 P. Y. n* x9 Z2 G5 s
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
- Z  P+ ]$ ~: j- V(由于很多专用术语和算法机理都不明白,所以看不大懂……)% z7 A/ |, U2 @+ o: G7 |
//////////////////////////////////////////////////////////////////////////
) {* a2 f) D3 J& {//                                                                      //
& o: N* F$ q1 o) _//      NES APU core                                                    //. S7 f  V: J! H! {7 l" o" N4 ?0 a0 W
//                                                           Norix      //
) |! W% c% b* v+ x+ y3 x//                                               written     2002/06/27 //7 o- d) c  W- z& [8 w$ {
//                                               last modify ----/--/-- //. t" ]( c% J" }% ^
//////////////////////////////////////////////////////////////////////////
# |' W7 j# s: r$ W6 O* Z#include "DebugOut.h"! W0 U& D6 M0 o5 R  t+ T0 ^
#include "App.h"9 o- R, M2 ]. H: j! U3 @4 q3 }
#include "Config.h"
! N$ _# E6 A  \! j/ C# ]  x+ o- U6 ]1 P5 N. E! P
#include "nes.h") T% m  F" c. B3 M/ Z, k+ r) k
#include "mmu.h"' {7 R1 i9 ]9 ]6 X
#include "cpu.h"
: f/ J: J# z2 i" G/ }#include "ppu.h"4 S! e( }' Y1 Z
#include "rom.h"5 |) J* j& k. i0 n' E6 ?0 ?
#include "apu.h"( W/ N8 o+ j- g, q( q5 k; A+ y3 f1 k0 @

' D; K& ?; v' |. G2 i0 d) i// Volume adjust/ h0 B% ^. k+ J  u- M/ {
// Internal sounds) N" w8 y3 x; T0 _1 ]3 D) h
#define        RECTANGLE_VOL        (0x0F0)& u, c/ B* l  e* ^$ t* W& r3 n. I$ N
#define        TRIANGLE_VOL        (0x130)4 E/ G& `; W$ C) D- T+ V0 z8 t
#define        NOISE_VOL        (0x0C0)* ?) h) Q; ~+ [! M! o% {6 @2 L
#define        DPCM_VOL        (0x0F0)
5 _4 a: Z, l) w4 Y// Extra sounds4 d% T; Q# _, P4 S# _
#define        VRC6_VOL        (0x0F0)
7 E' M9 I; C! l" a#define        VRC7_VOL        (0x130)* N9 k5 v3 I5 D6 J6 `
#define        FDS_VOL                (0x0F0)
+ A( q. d! {! I* D& X. I$ V#define        MMC5_VOL        (0x0F0)
- w, k- ~! a6 W) K#define        N106_VOL        (0x088)0 |7 [4 e7 c( u& ]2 P
#define        FME7_VOL        (0x130)1 q5 Q, p2 Z" o! y* J5 k
% G' K% v  q1 J1 g
APU::APU( NES* parent )5 ~, W# d$ B2 c
{6 n6 C6 q2 K2 }4 U4 F
        exsound_select = 0;9 ^9 H+ }# t+ Z3 I  z; r: N' m
* [6 q+ o7 N# w- q
        nes = parent;
, L, E* Y" E1 W* `: G0 R: D        internal.SetParent( parent );1 l3 r! t4 N  h5 B0 f

& f2 u; D4 q  V' b        last_data = last_diff = 0;
2 ^# J& K8 c. N3 d0 ~% p  D
2 m4 F, e. I- d0 _        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );1 ], k' s: B* K0 L( i: n5 B

. ]8 I, }! E( S" o4 G        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
; j/ `2 X5 ~+ x8 \0 x7 F" F        ZEROMEMORY( &queue, sizeof(queue) );
. ~, ]! ?5 u  [; b  ]7 E        ZEROMEMORY( &exqueue, sizeof(exqueue) );
3 a+ ]$ z$ I6 u: D6 @' `. d/ u! b# z6 u" f
        for( INT i = 0; i < 16; i++ ) {2 t; z. t: \" H' h
                m_bMute = TRUE;8 v; }1 I5 K. f8 d3 ]2 G/ H
        }2 v/ c7 ?9 F) g; v- h
}
2 s/ r- M/ A$ |" ^1 z1 u; y# ]4 q' K5 c8 p" z1 M. y
APU::~APU(), w% q' w. w" {4 Y! o; H3 U  w1 @2 r
{
8 f  w$ O4 U$ e1 w* v}
& {5 n2 ?4 Q; D! l- ?# j" Z, ^  i6 q9 M
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
$ c$ @) @$ e2 o% l  b{6 |+ \. u/ A; U, Y
        queue.data[queue.wrptr].time = writetime;
$ @+ J2 ~; F* ^6 @( B        queue.data[queue.wrptr].addr = addr;
. v; n% c1 Q; u% m" V        queue.data[queue.wrptr].data = data;! W/ q) l+ S' f+ h: y3 p
        queue.wrptr++;
: g- @' Y: {- {: _% h        queue.wrptr&=QUEUE_LENGTH-1;
0 a, e0 N, }1 w% g        if( queue.wrptr == queue.rdptr ) {% r2 @2 x( N& o! c8 B( W" o
                DEBUGOUT( "queue overflow.\n" );2 G  u, n# t- Q; D: Z
        }6 P) F5 v% ?9 D% ~
}4 ~4 e1 v- ^0 n3 E
1 D: m: K# X. V+ I, I' J) ?
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
# s3 E. v; |9 _4 t/ L: P{& V6 V1 I' U0 w* z( K* z0 X
        if( queue.wrptr == queue.rdptr ) {
% |; m- a6 L8 Z) l                return        FALSE;4 W6 l: x! A9 \. A
        }) {- ^, ~- z$ v% e
        if( queue.data[queue.rdptr].time <= writetime ) {
3 l4 F( M) G; V5 j( X                ret = queue.data[queue.rdptr];8 f) n( M9 o( G8 N: f" w+ J/ u
                queue.rdptr++;9 S+ q, x/ _4 V8 \
                queue.rdptr&=QUEUE_LENGTH-1;6 y$ b. C, m4 b1 c0 ~
                return        TRUE;: g. T5 O6 E3 _9 u2 o- U
        }- j7 L3 J' k- I0 {6 @3 D
        return        FALSE;) ^. G+ |; X( K1 a) X
}6 Z' O) @. d. v7 q3 o+ y  U
/ Y2 C) b9 S' d' X* D
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )4 j$ r& k2 p% ]# U+ P( l1 W# Y+ j
{
! J0 L1 l. C% H' J/ \# ?        exqueue.data[exqueue.wrptr].time = writetime;
8 {% }1 I' _. K6 [! g        exqueue.data[exqueue.wrptr].addr = addr;! T+ Q0 S: p4 R- z2 j0 q
        exqueue.data[exqueue.wrptr].data = data;
7 a# j, u  |# y8 X1 X: {& ]4 p        exqueue.wrptr++;2 g/ y) U; S$ W# e) B
        exqueue.wrptr&=QUEUE_LENGTH-1;. B) Z' x! b7 F- p8 h
        if( exqueue.wrptr == exqueue.rdptr ) {
. P& s. T1 Y: @% w0 a$ D4 h                DEBUGOUT( "exqueue overflow.\n" );6 H  c) V& |9 @6 [1 n# v5 I6 f
        }
, p+ J; K# }% m8 x8 Q3 W2 {+ e}
, t4 l/ p; q9 j9 x; z) D; i9 Y
! l  G9 w: E! c' S$ EBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
! E- u1 j. Q: x1 s1 e{5 h( E" W) z% Y8 ~' g4 }  ~
        if( exqueue.wrptr == exqueue.rdptr ) {8 ]: S" @# {2 I" E( b% I
                return        FALSE;# {! Z( l" X8 ?# v& P  m
        }9 e/ M9 Z+ }; ^9 K. R1 \% V# j
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {5 U1 j0 T' X8 e# W5 X" ^
                ret = exqueue.data[exqueue.rdptr];7 K! H9 T# f* @8 |+ i6 n
                exqueue.rdptr++;% P: Q) T+ p3 x6 Q& m2 A8 G, J# o- }# v
                exqueue.rdptr&=QUEUE_LENGTH-1;  c+ a2 o* l8 E+ D! u, d) c& u, }
                return        TRUE;
, r/ F, z: X* A; x4 R& F0 c3 V8 M6 ?        }
  q( X5 M% p1 _5 ~        return        FALSE;2 ]0 c. _6 a* W4 F3 [$ v
}
; n. p! V0 i: {7 U% T5 C3 ?3 o# t
2 Q+ ?6 r  G4 Bvoid        APU::QueueClear()1 W* T" J' S: i8 o
{
+ B/ L$ ?; f, m, e        ZEROMEMORY( &queue, sizeof(queue) );
  D3 ]6 D* \2 V; g$ t4 b2 ~7 x        ZEROMEMORY( &exqueue, sizeof(exqueue) );/ \3 d5 n) e5 t
}
& J3 v7 E3 A6 l- b& I6 f  d0 u. T$ K6 Q+ O6 H
void        APU::QueueFlush()
% ~1 n0 p5 d+ `7 {: V! L- f{
" i2 ?9 ?! o3 I8 \# P" T5 i        while( queue.wrptr != queue.rdptr ) {
) U. D( A& h+ d0 }. o                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
% O( x1 I" {) Y2 f8 W                queue.rdptr++;! a2 L# @. y" L- H- k, j
                queue.rdptr&=QUEUE_LENGTH-1;7 y8 O) f# n( v% U) X
        }9 l. }, ]( V" z# e  Z
1 d5 x. w  K4 M0 y, z# u/ C$ E
        while( exqueue.wrptr != exqueue.rdptr ) {
+ E1 H1 @) l" |0 r( X' @/ |5 I* ~                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
) P% ?4 T4 V- K0 P5 u                exqueue.rdptr++;
$ h) F- J# ?! d8 e; T2 N# H6 m                exqueue.rdptr&=QUEUE_LENGTH-1;. {' `  ?) U6 D+ x* P
        }
+ K! h- y! D! m- q6 ]7 r- W3 b" u}
; R0 x+ V: `8 p7 t( p" S' K- g; j, t; ~. L$ D. Q
void        APU::SoundSetup(); j1 `$ ]+ Q2 ^
{3 ]5 J. B" M5 N
        FLOAT        fClock = nes->nescfg->CpuClock;
7 b$ e4 ~6 B, |8 t        INT        nRate = (INT)Config.sound.nRate;
6 A1 c$ G- B8 w: M  D        internal.Setup( fClock, nRate );
6 @2 _% b# i' A! c9 d1 K8 a; A        vrc6.Setup( fClock, nRate );* X% i7 C6 C9 h9 q
        vrc7.Setup( fClock, nRate );
0 K3 e# R& r7 L" O0 n9 T- C5 o8 E        mmc5.Setup( fClock, nRate );
6 T; E: P) q% Q* E, R0 q        fds.Setup ( fClock, nRate );
- A4 J6 A: P& M4 u        n106.Setup( fClock, nRate );2 U  H' r. D0 u! ~
        fme7.Setup( fClock, nRate );$ t1 q$ `; }7 H8 y
}/ `0 _4 n  b# w6 P) L
& o- y/ G+ e3 \# X8 C' Y
void        APU::Reset()( C2 |/ _. |$ {  G; N0 z% ~+ t
{
( H# p& Y; ?# |+ N% {        ZEROMEMORY( &queue, sizeof(queue) );
6 ^8 [  u# o2 m+ n9 I        ZEROMEMORY( &exqueue, sizeof(exqueue) );
$ Q7 ^( x# h2 }) c5 V1 a/ w, ~
8 s) v( @+ q$ \# u        elapsed_time = 0;" f6 n. n  ]% s0 l7 Y/ q
# ]- h0 }& v( u& P# A8 N4 s
        FLOAT        fClock = nes->nescfg->CpuClock;
- v& \& f5 T, b! ~3 L* l* Q        INT        nRate = (INT)Config.sound.nRate;7 |% A' ?/ i9 Z$ @4 }$ X, x- y
        internal.Reset( fClock, nRate );
6 {# \; o5 t% g+ x4 j6 \        vrc6.Reset( fClock, nRate );
, G) A# ~, z1 v8 N( S6 X% B9 E5 C7 U        vrc7.Reset( fClock, nRate );5 \* J" ?: ~1 y
        mmc5.Reset( fClock, nRate );( T* P, p" ?, \+ u9 F9 P
        fds.Reset ( fClock, nRate );, n( a" i! E; ?( b. V
        n106.Reset( fClock, nRate );
; F- A7 d+ v0 V  I1 {* C( S  g        fme7.Reset( fClock, nRate );
3 E5 \, \$ V9 L+ R2 a) W3 {# X8 M! i0 G. o9 J/ z7 O+ ?
        SoundSetup();
" B. m  e# e: d}5 |) Z* @+ A. D. M% x" T: {, n

5 A; \. l& `& yvoid        APU::SelectExSound( BYTE data )% c! p- p5 I6 H% a+ G! h0 P
{
1 M% y% H7 g% n# ~; q8 H        exsound_select = data;0 j1 u6 G1 y$ Q* K' ^) S
}
! e4 U: F7 F4 d* f. F, T" H4 Z; U) I. F
BYTE        APU::Read( WORD addr )
, A0 p. e9 x6 u% A{
) C2 J: N( Q  O# F8 O        return        internal.SyncRead( addr );9 {4 y) F% U4 Y0 V
}2 T1 v1 s9 E% R* z8 R8 R% ^: t1 G
8 }( J: ?' ?, f# C/ H) e9 k
void        APU::Write( WORD addr, BYTE data )
8 C& F- i7 d6 I4 N{; X, U! P5 ^5 ~8 T! b9 J6 g- [
        // $4018偼VirtuaNES屌桳億乕僩2 J( E* h( M- G  }- I. w
        if( addr >= 0x4000 && addr <= 0x401F ) {4 C! m$ V* i! C. K+ H1 Z6 w  M% X8 d
                internal.SyncWrite( addr, data );" q6 F' K* L2 c8 H) B! {
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
8 h7 C4 e, n+ `9 y# Z! Z! t; T9 r        }
$ z4 m. {) g: u* T4 f; o% o}
- D& o1 n( Q. v# D6 G5 H
: N) B6 G# u; O0 b' Z& HBYTE        APU::ExRead( WORD addr )2 u) ^0 M; j5 ~- u1 q
{- K' T. a8 w; d
BYTE        data = 0;2 p8 ]4 J( t$ i1 Q2 L2 @& l
( ]8 _7 K: Q6 A( i! d2 F
        if( exsound_select & 0x10 ) {" |& Z* P9 K: F& W
                if( addr == 0x4800 ) {
, D; O+ a$ G7 N8 V6 P                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
! I. Q, o) \* k( P/ ~                }" N1 l: L! ?3 c  }
        }+ L4 P1 `7 E" D9 ^0 b, r* f
        if( exsound_select & 0x04 ) {" O# o% s& t* l# ]
                if( addr >= 0x4040 && addr < 0x4100 ) {0 x* I) A3 C. K' R/ h2 A* W
                        data = fds.SyncRead( addr );
. z; o. I1 w. _2 |5 c                }
: w2 O- w: F  ~6 I  `& G        }. k4 U/ J6 o4 E6 j4 Z1 E
        if( exsound_select & 0x08 ) {# n5 P  x, p% S% Y# L( c5 u2 r' \6 C
                if( addr >= 0x5000 && addr <= 0x5015 ) {2 d4 o8 E. C# d' ~0 k, U! U' r
                        data = mmc5.SyncRead( addr );
. q6 }% i% L( Y; @& N+ e                }8 P( q( r2 ~% W; Q3 u' a5 R
        }
2 v/ Q' Z( p5 T. I9 X3 {6 i6 S; H6 P* ?6 `; I: X
        return        data;
. I' E& f. T7 ?- y. e9 B- l}% ~# ^) ?) d1 J0 c" i% ~0 W" Y

& G  U# }, c' o6 _# Nvoid        APU::ExWrite( WORD addr, BYTE data )/ M" R' S' I  Z
{7 S; h9 E& G0 A1 E/ F/ X
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );' X$ o1 [! _# w. C4 b. n- b: z
4 |$ d. [/ V9 H
        if( exsound_select & 0x04 ) {
$ C3 a+ W8 H0 B) T. J  c" B9 G                if( addr >= 0x4040 && addr < 0x4100 ) {+ a+ W2 O. q/ K7 C. w: ~
                        fds.SyncWrite( addr, data );' f0 V6 x, [! m6 b6 f7 I
                }
+ F" g; B7 g& M+ I7 N        }
0 u, o. n$ X$ d4 n# W/ ?8 f6 ~/ B: [* N
        if( exsound_select & 0x08 ) {3 U$ s, u( F; J4 g- Q
                if( addr >= 0x5000 && addr <= 0x5015 ) {0 \+ d+ [" m. M1 J+ k0 G8 L
                        mmc5.SyncWrite( addr, data );+ t. S6 ~# x* A% l6 j
                }
# v/ |7 I, b9 B- K        }" ]2 w' X# t% d5 d
}6 C$ L# R6 C! g3 S
8 G# D* `3 n6 q! g
void        APU::Sync()  b" n8 Y; M1 @
{2 @' C# z% O! Q( d* V: J1 i( C/ Z
}- i! ^# B# L0 E0 I/ G

1 ]9 P* k4 _; dvoid        APU::SyncDPCM( INT cycles )
: F' K+ U$ i6 R& u7 m2 S1 M( d{2 o, b$ ^$ f* Y1 O# m
        internal.Sync( cycles );; X- g5 w- d$ ~- l* }8 H/ G2 R
2 i* x9 d1 I& r( F, r2 [
        if( exsound_select & 0x04 ) {
; |# U0 P4 q& e6 M' U4 m                fds.Sync( cycles );
; k" Z6 h/ C/ c3 t        }+ r; p6 @9 t) f. E$ ^1 p( \
        if( exsound_select & 0x08 ) {
. q& \/ {; Q; H- ]' R% o1 _' @                mmc5.Sync( cycles );+ L. y( m" N% I
        }
& }. @) H1 Q. @; L' x! Z}
- ^" G. a) d8 T0 l) Z# p. V% V
; R( `# ?/ }1 G% U5 }+ x; Nvoid        APU::WriteProcess( WORD addr, BYTE data )& H1 r2 U& z1 ~1 x; w% B% f
{
1 k, w& |/ R+ n2 \: W. c        // $4018偼VirtuaNES屌桳億乕僩
% G* ^1 r5 {% [: O6 }' X% X        if( addr >= 0x4000 && addr <= 0x401F ) {' D( p& }% v; R! J) z
                internal.Write( addr, data );
( V4 z( c9 P% ~$ l* q        }' W5 E4 N) w1 @% o
}1 {$ b1 ~# A( a( U0 m0 X
* d8 s! n; H  F# A
void        APU::WriteExProcess( WORD addr, BYTE data )
4 c5 j5 u: V. G; U' P{( q1 [- c9 R' L( X) H8 g, V# R
        if( exsound_select & 0x01 ) {' {5 p/ g9 {/ _& k( R3 O
                vrc6.Write( addr, data );$ w3 r) N+ v. g+ h" W. b
        }
: x; E! ]; P+ o! ?' @% \        if( exsound_select & 0x02 ) {# }. Y' K+ B) C) D4 ^/ M! L
                vrc7.Write( addr, data );1 h5 e: @% W/ h( c8 E* B2 y
        }' {/ `+ P3 @6 z+ t: C
        if( exsound_select & 0x04 ) {
: n4 q2 f% {' E4 x7 U" ]                fds.Write( addr, data );
7 k: ~) a: \$ X4 l4 K8 B* B        }
# l' L# {+ D( z3 ~( B& H        if( exsound_select & 0x08 ) {
5 \; t  s! W5 U& {                mmc5.Write( addr, data );
- g* Y1 w' f2 a( @- z/ S        }
& s1 [% D, H6 V: t        if( exsound_select & 0x10 ) {
& n5 p. u0 h% Z/ I; n                if( addr == 0x0000 ) {  M! n$ }$ U" P6 R
                        BYTE        dummy = n106.Read( addr );
) V5 |. P) ?8 J- V                } else {; K4 @- ?  {5 R& k+ ]4 g
                        n106.Write( addr, data );5 e) A+ ~0 [) e6 `4 T$ |
                }' O0 b1 u2 k% ^+ b% n8 I
        }5 z* K) [% s% |- {
        if( exsound_select & 0x20 ) {+ t  B8 D* R& Q6 P0 U2 O1 V! y& o
                fme7.Write( addr, data );; e$ Z* O6 n: b
        }/ P8 g4 L% S# e9 Q
}3 W! j  p* [8 b
# b7 x: v% E  K* B/ Y, m" p
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
2 \& D$ ?. S6 R# ]# c/ C: O{
. {" e7 B% {0 X* g$ ]3 V4 a! A7 n$ aINT        nBits = Config.sound.nBits;, A! Q$ u, Z$ D3 d9 K" V$ V
DWORD        dwLength = dwSize / (nBits/8);
6 V& G! W7 x( a( XINT        output;4 C$ g6 q  t+ q, Q# V# j
QUEUEDATA q;7 h4 w* [0 a# r  |7 [9 i/ i
DWORD        writetime;8 ]6 H7 N; ^+ n

' I: `8 {) O; o6 O0 s0 F+ KLPSHORT        pSoundBuf = m_SoundBuffer;
. w! W& S! S- tINT        nCcount = 0;8 V6 ]! U9 K! x: @2 J# s# H4 p
. j8 ~* T$ Z; j& |/ f# [& u' x
INT        nFilterType = Config.sound.nFilterType;
0 C# l- E5 U5 G4 v) f4 m! k
7 N- r+ ~5 ^3 @( B2 v2 E/ s        if( !Config.sound.bEnable ) {
9 j, }7 E) Z. l- g                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );0 p5 c4 c: R+ c, B# V) P1 A  t; ^
                return;
3 e0 i# p8 y& W. S, i% c        }! z( P2 g" o& L: }8 P
- `' [; }! z0 r- `
        // Volume setup
$ E" R" l  l) J9 F* t, i        //  0:Master) V5 M$ a2 ^# _; ^7 Q
        //  1:Rectangle 1
* x& u4 w% k* ]        //  2:Rectangle 2
1 k  P. ?, A7 N0 Q1 k        //  3:Triangle
* X+ R. o$ {5 q( t        //  4:Noise( {' p. v: \1 S; Z: T! j8 Q* Q
        //  5:DPCM
; v) v7 O+ r( A9 I2 y) z) ~        //  6:VRC6. Q" R0 H2 l& B
        //  7:VRC7
( ~8 O1 A; Q: g! R# P        //  8:FDS3 U2 J- b% ~" b: C
        //  9:MMC5
/ s3 h3 V, L2 m& X3 i        // 10:N106
5 A( d9 |5 C0 S) N        // 11:FME77 H# u, R- V, `1 S
        INT        vol[24];' D5 f! b2 t. n, g
        BOOL*        bMute = m_bMute;( M* }; u9 o% [
        SHORT*        nVolume = Config.sound.nVolume;9 A, C, l, \. o- _! @+ ~

) g& K. {, W; i) K' G( Y        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
$ r* m6 t$ _6 Y# _6 P9 B
! {8 q. s' Z# g% K6 y/ a5 k/ h; @        // Internal; I$ E# V, V( `1 ~2 G/ U* {) D
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;3 z; k- r  V# G! m/ n+ |
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
& P5 z. v: W. ~$ h  b' T        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
# ?* S: U" p2 m$ V/ i* s0 h        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
8 u1 ^# h9 x  S        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
0 w) b5 ?% m. H: x8 |1 i1 i) {9 Z# P. y
        // VRC6
9 W3 _$ \7 e; W5 b9 e: f/ N        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;% q0 P7 g2 n, T+ J" \( t1 s
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
2 L+ ^2 O6 D2 A- s        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;. h. Q1 T. [2 s6 ^# V

. T: o1 @: ?, T" C% b% Z        // VRC7
5 h; O2 M8 @; C; u( H: j2 _4 Y5 `        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;$ K* ]+ c0 i. e3 p& E$ E/ p6 k
1 N' k' h! l) E9 o0 o
        // FDS
2 b2 F) F) `' x" L  \( Q. Q        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
3 N8 T0 y+ J- _6 P  N9 b- E7 M/ r  O; @- d
        // MMC5
& R, r% }: H# j7 D& S# s6 x        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
! }& g8 Q3 F, o' d6 o. @        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
2 Y  I" {& O8 L        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
0 i' ^6 f5 e9 E6 j0 t% w! k3 i0 ^5 R4 J4 f; K; I+ i# L5 e
        // N106
: z' R- v3 w5 u/ M. ~' V        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- e3 s2 h+ N) w( K2 i
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
4 o) H* S5 E9 u- S# R- ~' }* a        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;/ Z& c  _" j# t- T; y: B' Z  v
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' i, [& t/ S: L3 ]) m$ F
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
% h* ~  k7 q" \* ]4 ^        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;* k" U7 i" M) h6 _1 p
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;3 d5 M/ S$ K4 e
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;/ Z" C- ]+ j) Y

+ a2 a* W+ G  Z- [8 m* o+ q' i        // FME7
. l+ L8 G$ R1 G* z+ L        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;5 ~9 o. ]; T! I  E  d5 z& t
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;! f5 x, K" A; r. R: g: c: u
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;$ v  y2 T6 A0 z8 S: H2 ?- T

2 I; v0 [, m: h6 C  P3 ]" m5 Z//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
- U/ E- ]; Z2 i! I+ r3 A9 c        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
2 ~6 @7 H% {6 F+ K. V( {( K! s
* @3 {' p# u* S        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
# F; H. O' Y6 h3 j; b  b% _2 K% |        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
  a+ Q: h7 Q6 L. s5 N4 f- R, G                QueueFlush();& f0 N9 w' J% Y+ n5 Z
        }7 M# p: P: N2 j9 M# m+ O

) e) {( S$ d3 f7 G+ G. S- ?        while( dwLength-- ) {
5 H' N5 h2 v8 T9 J: P+ U4 n                writetime = (DWORD)elapsed_time;
" A$ k" I, m) I8 y" W9 _
! j% ]" \1 z4 H7 Z! l! u0 b                while( GetQueue( writetime, q ) ) {# A- S7 K! |" q6 x5 [7 G- m
                        WriteProcess( q.addr, q.data );! K$ m; O& _" G" _
                }
+ a. A) n2 ^3 \$ B/ |
) L& U/ J; u: l  ?5 T7 Q                while( GetExQueue( writetime, q ) ) {1 T' p9 a& d  K3 D! d' p" T
                        WriteExProcess( q.addr, q.data );6 e1 ^; p/ t4 I
                }
7 J3 h8 Q$ h: D% J
3 m( z1 n) W/ }1 f5 E; B4 X9 [                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7# }: }; f' U* k5 q5 M) `
                output = 0;+ S' O7 B/ C7 X- u2 G
                output += internal.Process( 0 )*vol[0];
7 X5 |  l$ G( z7 y! `+ Q( v                output += internal.Process( 1 )*vol[1];% y4 B% d0 J3 ]
                output += internal.Process( 2 )*vol[2];
! ^& P( w9 n& P3 W+ H4 X$ x5 p% D& @6 f                output += internal.Process( 3 )*vol[3];
  H+ H. R4 P; e8 m$ t                output += internal.Process( 4 )*vol[4];
/ S) N0 o4 S8 D7 w- c7 F/ h/ u' I& G
                if( exsound_select & 0x01 ) {, Y- \  @0 v( b. g" w* U" J
                        output += vrc6.Process( 0 )*vol[5];% v  k5 |; Q' N5 ?; l# m
                        output += vrc6.Process( 1 )*vol[6];3 N& M2 J1 w4 P' F
                        output += vrc6.Process( 2 )*vol[7];% E/ i6 k# B" Q) M
                }9 G3 @- X6 t) r
                if( exsound_select & 0x02 ) {# ]) I  ]) T; d% F" K
                        output += vrc7.Process( 0 )*vol[8];) l( b5 f) o9 u" y
                }3 a% O; R' _/ R* ?4 ]# B. s
                if( exsound_select & 0x04 ) {
" e. d. P* f( Y9 B                        output += fds.Process( 0 )*vol[9];
" a6 ~5 f) a4 E3 @+ v                }
7 P3 S" ?( |, l' x, {                if( exsound_select & 0x08 ) {
; [7 |% D; N+ h                        output += mmc5.Process( 0 )*vol[10];- k1 d2 ]1 e& e  b  }
                        output += mmc5.Process( 1 )*vol[11];
* {4 v! t- S& B% W                        output += mmc5.Process( 2 )*vol[12];
. e; x4 A1 }5 v) b) Z                }
  Z$ K7 F  {6 J                if( exsound_select & 0x10 ) {
) _2 Y: g$ I9 i9 ?  x                        output += n106.Process( 0 )*vol[13];; @7 U2 k" ?' N% J; m; O  V
                        output += n106.Process( 1 )*vol[14];
5 L3 b. T5 F* N, c% @, f                        output += n106.Process( 2 )*vol[15];
3 J; U) c# g) k7 H                        output += n106.Process( 3 )*vol[16];
. S5 D, s2 N! d" @                        output += n106.Process( 4 )*vol[17];
5 s: ]4 f9 w0 a                        output += n106.Process( 5 )*vol[18];* k) ~, s$ H, W& M, `1 x6 i/ }: b
                        output += n106.Process( 6 )*vol[19];
5 Q( w8 F. @; }- ^2 ?& _" @& v                        output += n106.Process( 7 )*vol[20];
% D6 q" e8 n  }" a3 @7 i% C! ^                }
" {, ?% q' @. ^; `8 m- j! p                if( exsound_select & 0x20 ) {
1 \  _8 {' T& V  f$ f# l% i                        fme7.Process( 3 );        // Envelope & Noise
  L+ d4 P0 X: w9 C* ^" y4 ^# c                        output += fme7.Process( 0 )*vol[21];
4 T' ~3 r8 y; |                        output += fme7.Process( 1 )*vol[22];! d, B/ ^1 G% |6 f3 w
                        output += fme7.Process( 2 )*vol[23];
6 N' p2 `7 ^( r# \: f* o$ q3 T) r                }
3 _: ]1 g0 y" T% T" m9 K
/ U3 p, I+ l2 v' w$ `8 p                output >>= 8;  B" r4 s5 S1 a% \1 ]/ I
# @2 P7 I, Y$ S/ K/ f0 l
                if( nFilterType == 1 ) {
2 Z+ E3 P1 U$ W: S+ Z, U* O                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
1 h% E( {4 T! W                        output = (lowpass_filter[0]+output)/2;
& m, r! d# C6 t" z( P; H9 O                        lowpass_filter[0] = output;" d0 s5 Y  D+ Q6 A
                } else if( nFilterType == 2 ) {3 v/ ^6 V' j& X& |- f4 x# T
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
$ _5 [* Z& ~* G1 U1 P- E                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;+ d" P9 M- Y! h: S
                        lowpass_filter[1] = lowpass_filter[0];' Y5 Q5 k: G5 t* N
                        lowpass_filter[0] = output;
/ q: O3 @; r- U9 y3 A                } else if( nFilterType == 3 ) {3 }: k) B& D0 m, U" O
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
% x, w% G6 L4 S/ ?2 R                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;* {1 s) H% H$ w; V  H. G5 Q1 D
                        lowpass_filter[2] = lowpass_filter[1];1 [7 ^# f, D6 S% r7 y/ R# O
                        lowpass_filter[1] = lowpass_filter[0];
/ m* n* M# L1 d$ z$ k. w                        lowpass_filter[0] = output;
# a, P' Z6 \3 b+ g                } else if( nFilterType == 4 ) {
" A2 \" p# e8 L- p5 ]; `  |6 w                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
0 X, B6 G. |% q/ e+ ~                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
; x' S/ L; Y2 ]- T( q                        lowpass_filter[1] = lowpass_filter[0];$ u: F0 ]* i2 n+ Y- Z6 N
                        lowpass_filter[0] = output;5 y3 d8 }% Q2 u. \# j. @
                }2 |" U8 x) U. d( {7 u
7 ~- _* t+ ]& H3 I( ^/ S% a
#if        0
$ v3 a  ?- l3 P: r/ S  i                // DC惉暘偺僇僢僩- n) r/ q) Z- h$ b5 {9 Q7 s
                {
7 U9 @* b6 [8 V( Y9 l2 W                static double ave = 0.0, max=0.0, min=0.0;5 B3 Q2 e5 `$ R. E, t, L
                double delta;
6 C" n) ~; _9 M: n8 t% ]                delta = (max-min)/32768.0;
* m3 V2 z2 l5 K& g. k2 _( d# @1 I                max -= delta;! e4 B$ @' d& |3 H! j$ @6 c6 S
                min += delta;
6 }0 |+ k" p! M5 i! K* T                if( output > max ) max = output;5 F2 X+ y- y/ s8 n$ X; v3 C  C: k
                if( output < min ) min = output;
  A4 H* _$ G) b  c                ave -= ave/1024.0;
9 q& _" Z0 o1 R% V1 n1 |                ave += (max+min)/2048.0;
2 b# K; m# ^5 J9 I; I' E& f0 [+ F/ [                output -= (INT)ave;7 q# z( z8 E# q! f6 j
                }  p0 {' o6 d- `7 z  Z
#endif' l/ t6 W# I2 T+ X
#if        1% X' o' l9 a! e/ |3 G9 r9 g
                // DC惉暘偺僇僢僩(HPF TEST)
2 X: _" l. ]: {( k                {
2 P1 g  j8 h$ k0 g7 h1 g6 o+ Z//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
: ?; M- x) o7 H" Y                static        double        cutofftemp = (2.0*3.141592653579*40.0);* o- r# \& z  m) ]/ n5 X) @# }
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
2 {; V* ~- a. u9 L# c                static        double        tmp = 0.0;
, j/ k' S% v% c% X6 v                double        in, out;: o! I7 y8 O2 o# ^& w; K' t/ ]# y

! B; c/ i! D- t! _% e1 }                in = (double)output;
, A: w/ o3 F% J, i                out = (in - tmp);
& J6 i8 z8 C. U3 i3 n: S                tmp = tmp + cutoff * out;
/ f; j" A2 L0 E$ i' G2 T6 a  h
  \/ j- T+ d; }& j1 Z: s                output = (INT)out;* ^+ z2 n# \- }5 ]$ F
                }6 A7 \/ t. [, W& d' {
#endif
1 l8 L/ |0 f; c0 T! T4 v, d#if        0
9 ?1 D( v+ v4 E5 m, C                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)+ u: z) S- \. W) j& X3 |1 S1 m
                {" S, S/ @+ `8 y
                INT        diff = abs(output-last_data);
& g6 g" b# z" o3 D8 F6 U                if( diff > 0x4000 ) {: V+ k# O' C0 l, V4 J# K
                        output /= 4;
, i' Q& p% |( r* N1 a; K: i                } else
; W: L- ]( S: ^' `                if( diff > 0x3000 ) {
4 I" L- e2 n$ S                        output /= 3;3 v- O7 @" o, T; f! s9 J
                } else1 o% d' ]5 k3 E. [# e- [6 k
                if( diff > 0x2000 ) {) Q5 |, |+ ?' x  K& C  S4 p2 s1 n
                        output /= 2;
; K5 a: J7 `( Y                }
. N1 A7 D1 \" Q4 i  P0 `2 t                last_data = output;0 \( H% H: v. @) e/ s
                }+ q: g6 v1 ^, k+ H, J
#endif
  g8 l# J7 w! _; r/ A' E1 f                // Limit) C' x8 s" t: a$ m* @* R3 [
                if( output > 0x7FFF ) {
3 a. \, i6 |7 G* p5 }, s                        output = 0x7FFF;
) C$ n% J! E$ n& o  y* ?# n1 o                } else if( output < -0x8000 ) {0 ^; {* I3 \7 ?8 d9 G
                        output = -0x8000;
+ C( O- r; q3 x6 {2 l, ]                }
- {. b! |0 |0 c; G2 `. M. ]
5 j* ]( B- A! _0 l3 _+ ], W                if( nBits != 8 ) {
- X9 s2 }5 g& N, L                        *(SHORT*)lpBuffer = (SHORT)output;! r7 Y2 R# |4 w. K) w. l4 O
                        lpBuffer += sizeof(SHORT);+ S3 z" H9 }5 N: f4 ]! V; O: O5 ^
                } else {
3 a+ u2 l6 a* K. N$ o0 |" {                        *lpBuffer++ = (output>>8)^0x80;
3 ~& X) r# H6 X                }% i3 Q4 x( z5 p- j, _9 V4 b

- ~" N3 V, m3 T$ M; i8 _5 j2 `                if( nCcount < 0x0100 )
7 f: [  X3 O) ~+ |# p$ D8 b                        pSoundBuf[nCcount++] = (SHORT)output;
, W4 z. y$ j% ]/ ^6 J
7 @; y4 N9 l! f+ A2 B7 {//                elapsedtime += cycle_rate;5 j6 R$ ^/ m- u' i4 ]
                elapsed_time += cycle_rate;: `5 J% ^% K! C/ e  ?
        }
* u8 }) s& R" k. N" F! ]4 ~6 \3 z+ @* H- b5 I7 f5 b! H
#if        1
2 e$ X9 w6 \& |2 b" S        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {4 I9 x2 h  Z9 p, _8 z. e
                elapsed_time = nes->cpu->GetTotalCycles();' F0 ?, B. y8 U/ w) p6 h2 V4 H7 ?
        }# X+ Q9 P: r6 w( I
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {% f0 R- v4 w- D4 |
                elapsed_time = nes->cpu->GetTotalCycles();8 Y6 D( n& k0 N
        }' c* N6 b# R) p7 T
#else
* {( D- k2 o5 c- a" Y. \9 R        elapsed_time = nes->cpu->GetTotalCycles();$ ]0 V4 T4 F8 o8 Q3 ?4 P- b
#endif$ K& {8 a5 U% P. \; `! X7 L' t
}
7 F5 ^$ t7 m( @) l" R5 Q4 g. H& O6 I! c
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
$ c- T" i* K2 g" K5 }; M9 @( x2 ^INT        APU::GetChannelFrequency( INT no )
& q( z7 [0 W' s- F5 W/ b{. B0 R/ Q2 t8 ~* I; y+ v
        if( !m_bMute[0] )
" z' M' [: h# u* j& Q. F                return        0;' L; H( r/ J  J; P1 t

$ u, _+ v, ^' j4 I$ W) B        // Internal" ?3 W$ O$ w4 ^! h' K6 J) h
        if( no < 5 ) {
* g( r& x8 w, r5 c( I                return        m_bMute[no+1]?internal.GetFreq( no ):0;! ~  C2 N- S, J
        }1 z+ M& W7 u2 {/ J
        // VRC6
/ u0 J3 |& }& h5 k7 A/ g        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {, v5 e1 G" n* c8 c% M2 [
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;- H/ ~9 L9 Q6 f+ D$ K# T1 w
        }
0 _7 ?* b: D( Q1 q0 r8 Q6 ?7 Y        // FDS
4 m6 N# p) l. G' q! @        if( (exsound_select & 0x04) && no == 0x300 ) {$ o2 U' t) f9 o
                return        m_bMute[6]?fds.GetFreq( 0 ):0;1 K. i: U7 G; ?5 A1 ~0 p2 ^
        }3 u: m$ k( ^2 b5 X: Y3 S/ J* `0 M/ @
        // MMC5
3 ]4 F" n; {) {  M1 o- w( |) a        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
% G7 _' c# F! k  y& ~" e0 V: @                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
# ?! Z/ \3 z: K7 T  w. D        }
4 `% W% v$ w' C, p        // N106( t9 L: T7 v" V# X
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {, i% G- `. E( v* S
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;2 M2 _8 q. D0 r$ t% f8 v  w
        }
# g0 N( p% K+ p/ ^/ H* h        // FME7/ T0 \8 W/ f+ c/ f) L
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
/ j6 n  R# h: @+ S' n1 `                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
7 o, t# _$ c( B- U$ e, Y, g9 K; y        }
& f4 U) r/ Y3 _* [; }        // VRC74 V5 |  I- T# b, C8 j
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
  P+ q3 s4 c& B                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;" O0 b9 B3 h1 Q' u9 K
        }
4 e: Z( ^, @2 q/ f+ M        return        0;
9 b& G! I3 t. a7 D) v  j}
' l  b% O2 U4 n* W# R  R$ f# O( s5 x/ q1 h
// State Save/Load4 }' F' y5 Q' i; {4 W$ \7 C
void        APU::SaveState( LPBYTE p )
6 {) y( X" n' p3 d{
( E* U$ u; L7 k+ w( l0 M% {#ifdef        _DEBUG. l% g/ ]3 U0 Z5 ?& ]
LPBYTE        pold = p;
" D, C4 u# D+ c& `#endif7 p' `+ r' W, p7 m( A2 d' y

" f/ [- H  H6 o3 \+ |4 k        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞6 J5 s/ w8 O0 d
        QueueFlush();
% x: e; k# a2 }$ h3 r8 ^( T3 ]7 h5 R
        internal.SaveState( p );3 ~5 A* O, [# f( L- q0 y# L2 [  r
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding9 K/ x/ r6 ~* E% _2 t) S, Q

6 e1 M& U9 r, `7 k# f  w7 s" {        // VRC63 W! S' c" U$ `0 o
        if( exsound_select & 0x01 ) {
5 J5 J8 V2 j& Y! d- A                vrc6.SaveState( p );- E7 H! ^% h" t2 Q; y& K5 z' V
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
9 b. ~* m2 V) w) r5 G$ l9 O        }
. E8 g% c3 \: \5 X9 a        // VRC7 (not support)
, g1 W( e2 M* B# x        if( exsound_select & 0x02 ) {
# i$ D& a0 \1 w' S: s5 V                vrc7.SaveState( p );
% R( Y/ `: t* d: G1 k                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
1 |4 m  t* P5 _% X7 d9 q% n. d8 z7 k4 I& A        }
- O/ B( t- h# O$ Y' u        // FDS
" X9 s3 w. [: I        if( exsound_select & 0x04 ) {
  D  n% F% P, H% B. y" A9 R                fds.SaveState( p );
. }( h: L0 N  m                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding) ^2 A% N; |( T! f# J3 p+ A% a& J
        }
! }2 l! q2 e9 W8 l5 N1 l# b        // MMC5
- d* y: z  Q! Z4 O5 W2 R9 `# B        if( exsound_select & 0x08 ) {
1 s  W! S$ N  D4 u+ `# z9 _                mmc5.SaveState( p );/ L$ w4 M6 d6 `! n- U/ d, w
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding, t5 Q$ T4 X  K0 v
        }
. o" B% Q1 R; F7 r; N, g0 \        // N106
9 f5 n) B- f4 v. d4 P5 z, R# K        if( exsound_select & 0x10 ) {$ s4 |" x4 z5 ^! }
                n106.SaveState( p );
4 i, \7 r. A; y/ E* K" g: W! Z) ^                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding  d* F2 _" C( ]- u& o- a8 f: z. i- V
        }, ]1 r, j. \8 V
        // FME7
+ l  t/ q# {4 E0 c+ s        if( exsound_select & 0x20 ) {5 r8 l0 g  I6 U4 k! I. R% g
                fme7.SaveState( p );
. }7 Q/ [# q! K0 J( b1 i. M                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding; C  K4 r% |; a, H  x  V
        }
6 N+ n6 u! R$ C3 O
; a( ]# P. N! V#ifdef        _DEBUG
5 @2 z- u! n4 ^7 O  @( I* I, pDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
& W$ x/ [$ K; |, H# j' F: F# Y#endif
# d: E/ x) s4 m}
; V, N# u1 `2 X. j5 }4 g/ d$ o- P( `4 P' t+ d
void        APU::LoadState( LPBYTE p )' l; y5 s% l4 w) Q; u
{
  E5 H# E$ M* n" w7 I        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
7 @$ o+ \- Q0 w$ a( w" @. D        QueueClear();
  c9 R; u4 b4 ~; o7 y+ l
2 n7 o5 O$ N/ t0 J: G' j" I        internal.LoadState( p );
+ r. K5 O7 D& ~* j, ?# g; b. Z        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding, s: B- U3 t* n

( ~6 H$ r1 S  H        // VRC67 T5 a0 `% f: o- }
        if( exsound_select & 0x01 ) {
: f0 j" \* ]0 Y' z: [8 o) U* ?# S                vrc6.LoadState( p );
+ R" N. x. w! W, p/ j3 T+ K2 R                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
9 Y7 s$ C" }" I0 O: [' F8 o( T        }
3 g+ E* E: ]5 i+ z' B        // VRC7 (not support)
" l  M5 A( f! L9 d" t* J: m( P        if( exsound_select & 0x02 ) {
2 ^" s8 z+ i$ l                vrc7.LoadState( p );
  x, y6 p$ l. |8 i8 {* i  o; k$ C                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding. h# N- o4 y( F+ Q* m' N* @  m
        }
+ n, E6 k5 n" N$ c8 T7 d1 k        // FDS$ x' T9 j; x$ i2 m
        if( exsound_select & 0x04 ) {' ~% O' J+ o) U3 {( |
                fds.LoadState( p );4 z3 z, W. t. Y* f$ I* h
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
( U# f1 b, N9 V- p/ u        }
: Q$ c) j$ R9 v0 {/ r2 [% M4 t        // MMC5
' N! y  `+ L" H3 E7 L9 X; Q        if( exsound_select & 0x08 ) {
# U1 m" o5 w, Y+ e" D: L1 B                mmc5.LoadState( p );9 z. u1 G' z; }3 L* m: z( ~
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
6 W% C4 W3 h' D7 B  g2 }: m        }
$ X: T( u0 W& ?        // N106
0 K- _' ]  |3 a$ ^) V        if( exsound_select & 0x10 ) {$ Q2 F) f+ ~$ b0 F% y1 G2 r" l
                n106.LoadState( p );
6 X  a" N. _& l                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
5 M& I% |& Q- g1 Y5 H* M3 a6 M        }' t4 P: B* @% J& z' K7 W* D5 W" R; O
        // FME7
- r( Q" ^1 Y9 K) I        if( exsound_select & 0x20 ) {
5 Y% D( j) O! X0 s2 s: d" N( q' f                fme7.LoadState( p );
* y7 M4 o& t6 r                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding. N  Q- w. g, K3 ]$ e% s
        }
' ^0 P+ m4 h. l+ D) g}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
; q" V$ i! F8 ]( U& N4 Y4 _5 C5 C可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
' m7 r6 V; H% c+ V感激不尽~~
8 v1 M8 s1 K1 E5 |, T1 N" L' E
恩 我對模擬器不是很有研究,
, O$ r# c3 }& ?3 @" B# M雖然要了解源碼內容,可能不是很困難,, V* C& X& w+ X) j. ~) q2 D
不過還是要花時間,個人目前蠻忙碌的。6 c) v0 M: N' c, N7 b6 Z+ h/ ~

( V+ q8 h. v+ f  f4 u4 J給你一個朋友的MSN,你可以跟他討論看看,
5 ?  j. V; E$ t! t8 h, Z' f他本身是程式設計師,也對FC模擬器很有興趣。
/ c. O  F& W( E; L2 P# [6 X) U
MSN我就PM到你的信箱了。
  A. P0 T) B- `1 g: b2 F7 x; d5 ~
0 B! ]. ?* t5 N0 O希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
$ O* X! P6 t6 t  K呵…… 谢过团长大人~~

* A" I+ x2 c5 v$ L3 e, g; D0 @/ i6 N' A! J# F  p( _* A
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
2 W1 k% ^  J" i0 Q2 H, I& N( s团长的朋友都是神,那团长就是神的boss。

+ J- |* e3 G+ [" R哈 不敢當,我只是個平凡人,( F( Y6 f$ J" ]" M
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
$ L  D1 h) [2 u8 s, r. k- s+ jZYH
" ^" @; V; w7 p/ O' x: x2 Y' O1 }QQ:414734306
2 ]- P% C9 W$ I( g* L1 a  |Mail:zyh-01@126.com' c8 }/ c* i) c1 O  s

5 p5 J: X' r2 K0 [0 W. f. u他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 # W" H% B# S' D' y% k: i- `; Q
再次对团长大人和悠悠哥的无私帮助表示感谢~~
; a2 a  w1 |5 V& Y0 J
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-8 01:37 , Processed in 1.113281 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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