EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。* Y, O) [) A% G# k2 [, }3 T
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~6 h4 P1 ^# P( B2 Y+ w
这里有相应的模拟器源码,就当送给大侠了~~; y. m9 j5 [1 C) @. g
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
6 x$ M, ?( \* A0 p; i) L/ V5 P/ j能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。/ I# E2 \) p( W( W; m
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~  p' ~  T: M3 n5 h+ M
这里有相应的模拟器源码,就当送给大侠 ...
: r+ |8 b# b$ X; y7 D, `
聲音部分(Audoi Process Unit = APU):
7 g6 k8 o$ k2 e.\NES\APU.cpp/ M/ Z  T3 S7 f+ {" M9 H* z& _
.\NES\APU.h
- x! X( r4 W4 A: G4 E1 D5 n' Q* x( h! |; a0 A  E$ g
4 x" l# c; {) t; u. N
影像處理部份(Picture Processing Unit = PPU):
' I; ~" A+ X: E$ W* |0 h.\NES\PPU.cpp
1 d0 O3 M( v% j+ [: d% b.\NES\PPU.h
0 l6 N) @5 t: m  b# r& u
" F: V" t. I# @* e$ _/ s如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
. b  U; s5 @9 j2 f(由于很多专用术语和算法机理都不明白,所以看不大懂……)
' ^& t! o: v, |7 e( [1 M7 g& n//////////////////////////////////////////////////////////////////////////& @9 H; ?3 P. f* z& E: u
//                                                                      //
# `& n. F; J' e//      NES APU core                                                    //
' N- ?, ]2 j- [/ E' m3 f//                                                           Norix      //
9 O. P, D) O; Q, r2 I//                                               written     2002/06/27 //
+ `0 g. c9 t( {, i//                                               last modify ----/--/-- //5 _. T4 ~* X0 n
//////////////////////////////////////////////////////////////////////////" G1 n( d! R' T. @& j- V" F' z' L
#include "DebugOut.h"% ^9 J! K+ F, Z% W% i8 _; Z
#include "App.h"
& [6 v; W* L: G#include "Config.h"
' N4 H/ v; _4 ~5 k* U
2 \/ Y4 o: M2 D#include "nes.h"
( s! _, O& U7 W; G" v) Z, e, t#include "mmu.h"7 B# @0 J4 U3 H1 I2 F
#include "cpu.h"
, \: z, [' W, |0 d+ }! z3 z#include "ppu.h"4 _5 ~3 @7 p! R/ m6 G% k
#include "rom.h"
" y5 \/ P$ d, B3 e#include "apu.h"  b8 j6 S  }  u' B- T

# M- K, I7 v2 X* m; {! c// Volume adjust: L) @8 A+ Q6 h1 F8 m
// Internal sounds7 s( o1 f3 g; h0 C. C
#define        RECTANGLE_VOL        (0x0F0)
6 J1 |" q# U; s" @" ?9 ]/ q#define        TRIANGLE_VOL        (0x130)
1 H) x" p( l; a% `, y#define        NOISE_VOL        (0x0C0)
+ z2 s8 m: Z/ d#define        DPCM_VOL        (0x0F0)
0 q6 H' @- i5 B: B1 s// Extra sounds
" W* v% n9 M8 P#define        VRC6_VOL        (0x0F0)
9 W9 R  l+ Q$ ~) f: @9 D#define        VRC7_VOL        (0x130)
1 S( K. K: [7 L1 x- d#define        FDS_VOL                (0x0F0); J) }9 Z. C& r- z% U
#define        MMC5_VOL        (0x0F0)
- Q! d# \' q  M, w) G#define        N106_VOL        (0x088)$ q7 F$ m& F, ~5 k& n& V5 c
#define        FME7_VOL        (0x130)3 z' _+ b0 L- p9 Q9 W4 V
0 c% u3 _, }: D: f: D2 T/ [& w
APU::APU( NES* parent )8 i  F( A4 c( i4 D
{+ v: t' W, d2 w" D  ^) o# S: q5 }
        exsound_select = 0;
0 y* M$ g& \' ]: a7 O& M
1 y! T' z' Y- F        nes = parent;
* p$ \4 n8 n; v/ m. ~5 v        internal.SetParent( parent );# o2 U5 `4 P- \9 K

( t9 J; m- ~3 S) l& y7 d        last_data = last_diff = 0;% v: P5 R5 P8 M8 C; }" h1 M" L( x

; |4 Q5 N6 y; B! t  N/ p9 f! A        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
! {4 H: W6 ?! |* m' y
; G% ?! J+ X4 [2 w: d6 B8 h        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
5 W' l* E  u' e        ZEROMEMORY( &queue, sizeof(queue) );
, h0 C. N' X: a# u/ D        ZEROMEMORY( &exqueue, sizeof(exqueue) );
+ j" }7 r& Q" y- h" }+ P1 H: M( d' Y7 o$ W. Z2 x$ b
        for( INT i = 0; i < 16; i++ ) {
4 h, x; d$ U9 _1 ^                m_bMute = TRUE;
) T1 u) w. s+ B        }2 Z3 |4 i; w5 R) u4 r6 f/ g
}
& s0 {; F) C! O% v. G7 Y- U5 i. W& A7 h& @
APU::~APU()
" `, v$ _, E: @+ @2 e2 u5 k{. }2 g% [2 V4 `) s; @( b
}- q! m7 N, T# c( \. P- |7 C
2 m% r3 D* z( a$ q7 |
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )" g9 E% ~! m, \+ R; h5 A- [1 l
{! M! l; V: i8 z( ]$ Q
        queue.data[queue.wrptr].time = writetime;4 [) @! _/ v+ i, f# I
        queue.data[queue.wrptr].addr = addr;' P& v  ]% K. g7 g* v4 ?7 J3 D
        queue.data[queue.wrptr].data = data;
5 K9 J7 v- I+ R! |        queue.wrptr++;  ~/ f4 {- p9 |9 ~# I1 D
        queue.wrptr&=QUEUE_LENGTH-1;
; F; l( Y1 y  H) B% A& A        if( queue.wrptr == queue.rdptr ) {- g! J8 e# A% z2 @& L' U8 Q
                DEBUGOUT( "queue overflow.\n" );! X8 M, i- F8 Q6 v7 v0 C4 c* ]
        }! ^0 f  l4 S- [6 V, \) e
}
7 ?: p5 c: }1 e4 z# Y( t) \# e6 o, J# X$ q
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
! [% b$ }$ d% h- t+ D! P( d6 w{
* J) M" O3 t( X9 h/ l2 b        if( queue.wrptr == queue.rdptr ) {& L0 }2 M7 _8 u" H* Z0 r
                return        FALSE;+ `, n* l# N5 V5 j( s7 O4 Z* P% x+ t
        }
7 U1 r; w# m2 [* f% t& `        if( queue.data[queue.rdptr].time <= writetime ) {
2 o. b  _& e& k5 Z                ret = queue.data[queue.rdptr];
  ]6 F0 N) k( h6 {                queue.rdptr++;
4 u2 l  Y9 \$ J. F2 R                queue.rdptr&=QUEUE_LENGTH-1;
- ^3 m& `& g6 f( I% }: G, o# W                return        TRUE;4 W$ M. ~2 B+ p* `  i; C0 J8 r
        }
/ X# v, [4 t% G4 Q( a        return        FALSE;' m( B( n/ Z. f4 y8 V7 R# }
}" f  w2 F' r* M1 v+ s% N
9 ?% u6 |1 {: H$ |7 @
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
6 A; T5 n$ s- [# R: D{# Y# O( Y' v0 _9 ?5 e& ?/ J8 @( Q
        exqueue.data[exqueue.wrptr].time = writetime;
; R7 b( f5 S2 i" Q/ p        exqueue.data[exqueue.wrptr].addr = addr;
9 Z' v& R9 A; L9 A. ~0 e: o        exqueue.data[exqueue.wrptr].data = data;
' z* g/ V. _9 B( y! y: T        exqueue.wrptr++;
, S! C8 S% ~+ x2 I  g        exqueue.wrptr&=QUEUE_LENGTH-1;
, H+ E$ K% j' b) I. C        if( exqueue.wrptr == exqueue.rdptr ) {
- r( ~2 n8 j+ ]) _                DEBUGOUT( "exqueue overflow.\n" );
( k( p& Y2 R, r2 _        }
; D; o/ N( w& |5 C/ o- M9 o, T5 A}8 y# W) ^  i) p% c) w# Z
( Q8 T2 a& j# v
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
; ^% o- y2 r) c5 b$ G# K8 H{- M4 _* W% Q- f5 h6 w" g/ X
        if( exqueue.wrptr == exqueue.rdptr ) {
- {% A7 s+ O: H3 I; A                return        FALSE;
5 O4 f# _- c: ]1 u& W8 |+ M: c1 X        }
* _" V2 ^9 [( e0 {$ P; F        if( exqueue.data[exqueue.rdptr].time <= writetime ) {8 S  c0 S. n# M0 L$ L  P. G
                ret = exqueue.data[exqueue.rdptr];
- U: m- c) A7 q# W7 v6 w- g                exqueue.rdptr++;
  ?8 O* Q1 N9 Y/ U  C                exqueue.rdptr&=QUEUE_LENGTH-1;' M! k6 I8 _' l7 l
                return        TRUE;: q) l3 F6 E# c  J
        }
6 w0 M7 |) k) V2 v2 @        return        FALSE;
; _6 h* x% Y' e) i5 @* |}& w$ i9 j1 e) [5 m7 ?

# Z% ~. t* e2 Bvoid        APU::QueueClear()
  W" K. `2 x+ l. y7 e& J{
- t: Q. y# f2 H        ZEROMEMORY( &queue, sizeof(queue) );
* |, d  ^7 {. K% t5 v; V        ZEROMEMORY( &exqueue, sizeof(exqueue) );
* {6 M( P. a, e( l}
0 x/ I2 X+ v/ ^3 P4 i8 Y( g7 R/ j: I0 h8 d8 M/ j! K+ ^
void        APU::QueueFlush()4 H, r8 e. D( q% K% A9 ~
{
" ?# f# ?( i& s' m        while( queue.wrptr != queue.rdptr ) {
" b3 y7 J6 H$ f1 c                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );! `5 z' t4 m& n3 C) d
                queue.rdptr++;7 h2 ~4 t) B- z# N
                queue.rdptr&=QUEUE_LENGTH-1;
: E, U/ z* M( ~+ H4 }. ?: W& e        }9 [- t5 N7 I' _  G5 g* O4 W
# Q5 q' Q" @) U# |- P8 l
        while( exqueue.wrptr != exqueue.rdptr ) {
( U3 B) [' g3 ~8 o/ R                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );  w+ ~( D, d$ X  A, \8 ^; J2 a3 w
                exqueue.rdptr++;! Z+ `2 y0 ]8 c3 b4 G
                exqueue.rdptr&=QUEUE_LENGTH-1;
5 O5 ^( F. k! U0 g0 @        }0 @* r8 f4 Z  K+ o0 A9 z* Y
}' ?7 u- ?# A" D9 S

) C2 C* g, s3 _) b1 avoid        APU::SoundSetup()9 v2 ?6 X6 B. g* R5 `
{
3 W+ y+ \5 T" F5 h9 H% d        FLOAT        fClock = nes->nescfg->CpuClock;
* M% P; c2 }" x* N        INT        nRate = (INT)Config.sound.nRate;
5 I2 q8 n& m- S  \( |8 B- T        internal.Setup( fClock, nRate );% X7 x. [- p: |; a4 t
        vrc6.Setup( fClock, nRate );
" G8 r4 G6 v* L; x5 Z  s        vrc7.Setup( fClock, nRate );: s  K# O& }' A6 O/ c' @3 R9 F; [9 U& q
        mmc5.Setup( fClock, nRate );
1 [) B. }9 h3 o$ [4 L  y        fds.Setup ( fClock, nRate );
5 J* |7 c  s# f& @5 ~        n106.Setup( fClock, nRate );( v% T: M) |3 g: K; {5 Y( R9 N
        fme7.Setup( fClock, nRate );
2 w3 u0 g3 m0 S( e- N* _}
9 _  E! }! Y* w1 ~: ~2 Q0 s3 F) O
& s' W0 V6 F1 i( t( c- l* ovoid        APU::Reset()8 z$ f) x* o+ J* T' I  Y( G
{# C! v8 X& d1 D" `
        ZEROMEMORY( &queue, sizeof(queue) );: P. M! h: K- z6 E
        ZEROMEMORY( &exqueue, sizeof(exqueue) );) T2 K' B) K- i% ~

& V1 r8 o5 |3 N0 @% c        elapsed_time = 0;
8 q2 R8 l- Q3 n! Z. b3 v% G* ?% @7 [6 r% ?# D6 b" h
        FLOAT        fClock = nes->nescfg->CpuClock;5 ~3 E) ]( {+ n1 p3 M4 m5 k. X# u
        INT        nRate = (INT)Config.sound.nRate;( Q7 a( C0 N( _' Y, H% `/ w
        internal.Reset( fClock, nRate );
1 ?4 w/ W6 G8 j% n) I3 \7 x; e        vrc6.Reset( fClock, nRate );" [) ?' C! P/ ?6 p+ y
        vrc7.Reset( fClock, nRate );7 g- w! F, @5 |% B6 w
        mmc5.Reset( fClock, nRate );3 b, s2 \/ D3 b4 A2 B
        fds.Reset ( fClock, nRate );; m% {8 V3 x! N- O* Y. E! s
        n106.Reset( fClock, nRate );: o) x1 ?3 f2 Y
        fme7.Reset( fClock, nRate );7 q+ K, Y% ]. w6 i  B

2 C  [. M* u, U  Z9 I        SoundSetup();; H" n. l& {# ~/ i- Q
}
! c$ |; W5 Y* t2 L; H$ {5 S0 X3 M& D
) I% i7 D8 ]* Q6 Rvoid        APU::SelectExSound( BYTE data )
! u: E/ V* @7 o) X* ^" N+ g{0 M  }# h& l/ _
        exsound_select = data;+ s2 h1 }, W- H: I$ s$ U4 C+ U* T
}
+ `4 F+ G) Q, F! ?. Z) D7 g! `6 R" U8 a2 r+ ^
BYTE        APU::Read( WORD addr )- ~1 m* e8 N! ^" h/ i2 M% ]" z
{
2 f3 E) u/ g9 G        return        internal.SyncRead( addr );/ l; R3 F9 i! t# E/ e( P* @9 C
}+ m1 R- i4 ?% L& Z

1 ]# \1 k, e1 g- u& n& Wvoid        APU::Write( WORD addr, BYTE data ), b9 [* b: B8 K9 k8 q8 T( S
{
0 a( r( n/ `' }: f) T        // $4018偼VirtuaNES屌桳億乕僩
7 p- s" `" H& g  H  h  J        if( addr >= 0x4000 && addr <= 0x401F ) {
7 q2 J  X3 n( J) h: ~7 }) T                internal.SyncWrite( addr, data );
% f5 R$ l* d+ U2 H/ j$ _                SetQueue( nes->cpu->GetTotalCycles(), addr, data );7 h; [  {7 h+ e% x) n2 {6 i4 e
        }
8 S" a: V" Y) c6 \" _}5 X/ B) [1 q' d. Q
+ C6 ~6 N( g+ l% {% v6 T' X5 t- }
BYTE        APU::ExRead( WORD addr )2 `+ T# ?- k. {+ i& u6 T) k4 e; J
{% [+ m' U& }' W
BYTE        data = 0;
! v1 t3 g* p% E: g, ^; ~8 z1 V0 z! \% u9 S% f+ i% A* X$ [6 x
        if( exsound_select & 0x10 ) {
8 p& U. w7 R' R1 O                if( addr == 0x4800 ) {
8 @; O  ?6 G  O: @, E5 L                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );+ V- ?7 O+ v* K* }4 Q4 k$ A# L
                }
' @/ W6 P0 X" Y$ x' X; K        }
2 S/ B1 j! d+ o6 K0 J! r        if( exsound_select & 0x04 ) {
: _! |  K4 W7 J, o* d                if( addr >= 0x4040 && addr < 0x4100 ) {
* P) D3 B0 m2 D                        data = fds.SyncRead( addr );! K: s  h' @, _& `: j5 p& `- ?: ?
                }
# s" U" V7 \$ j4 J        }
* ?6 W9 f) L! P1 t/ U- W2 ^9 v0 l2 ^/ Y        if( exsound_select & 0x08 ) {
/ {' N6 r( K8 X# y+ H  y9 G                if( addr >= 0x5000 && addr <= 0x5015 ) {8 X# o7 d4 |3 @
                        data = mmc5.SyncRead( addr );/ d# W7 ?! G0 [. v: B% t* M8 Z5 X2 p
                }
2 S* |( B$ L3 y- y+ v, ^  W        }
, J. q0 A6 ]9 x! r! a+ E; q7 s7 R6 E6 L0 u: J9 P. ^; w( c, d: E6 A
        return        data;
$ v! A5 S7 Q& C& B! J}
" l! o, g1 c) s
# l* D  E1 j" k7 Jvoid        APU::ExWrite( WORD addr, BYTE data )
+ v. T) b* |8 _+ E. _, Q1 [{
. _3 M; V7 `! W        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
3 ]( e3 k5 @! `5 t% b
1 c8 Y  h" [- q        if( exsound_select & 0x04 ) {
' w+ L3 J3 I# q0 R; y                if( addr >= 0x4040 && addr < 0x4100 ) {
$ }  p% L  P4 Q9 _4 R4 N                        fds.SyncWrite( addr, data );" f' n" N1 Y' m& ]7 p( ]) `
                }
/ [3 I/ d# T0 Y- C        }) {) `6 m" K% @0 x( x" B

4 X' G* z# _9 Q8 P9 ~# @. I- z        if( exsound_select & 0x08 ) {+ W  F  i/ F* d
                if( addr >= 0x5000 && addr <= 0x5015 ) {9 V; Z! ~& Z# |9 R+ y, ]% S
                        mmc5.SyncWrite( addr, data );$ S% S  V) w$ a$ V( p
                }
7 v% S' n3 u' o# E5 z" W        }
8 @$ \3 w( ^: f# P5 V}
6 Q7 w* C6 D" p8 b% t0 g4 Z! @6 F9 n+ H. C: S
void        APU::Sync(): O. _" R4 `. @9 G5 y
{( _6 a6 w. f& g# r9 ]# B* C. c
}. f2 ]( v8 I. e2 t  Q
/ O& {5 E$ O. d( h
void        APU::SyncDPCM( INT cycles )( N1 U) C/ k4 G% P% o  |
{; k+ L' ^2 \# B
        internal.Sync( cycles );9 J3 y$ L. S# M! f( E& i
% x. E' p! C3 D  X- Z# i$ }1 S- j
        if( exsound_select & 0x04 ) {! h8 a# o7 n; j
                fds.Sync( cycles );
. ~) L; s. h3 z2 i8 p& ~+ |        }% |$ l( ^; i0 ~1 x6 V. R3 D
        if( exsound_select & 0x08 ) {
7 u1 p1 V) ?* q6 `( U. J% R& h; k1 F                mmc5.Sync( cycles );$ x( j8 F" g! W
        }4 a0 D. U  k" n; V. i+ e* a
}
1 n! W( L' T; f; Z$ l0 @0 p+ x. _& p8 m: K. N, A7 W& a- Y+ `) ]
void        APU::WriteProcess( WORD addr, BYTE data )
9 a$ p, Q) g5 R; n) O{5 |0 p* F$ z7 e+ @3 F) J9 k$ f
        // $4018偼VirtuaNES屌桳億乕僩# O6 ?8 P: ?' F  u( m8 r
        if( addr >= 0x4000 && addr <= 0x401F ) {( R% I0 L( ?* m! y6 p/ Y1 d4 _
                internal.Write( addr, data );
! \7 E$ j% a$ a+ g. N  n        }( G: G& V. g1 m+ w  e( w
}! ]( T4 K% D9 P) e2 [' ?$ _3 m9 [

/ d+ i- R: Y# Yvoid        APU::WriteExProcess( WORD addr, BYTE data )
2 i" \4 J5 J2 y! P{! n/ ~# q# Z6 k: L
        if( exsound_select & 0x01 ) {
& T4 U4 p: s" M                vrc6.Write( addr, data );
5 {( B# D1 A7 L" V4 M1 L1 Q7 k        }' l3 }* o4 \( y0 X' U3 M
        if( exsound_select & 0x02 ) {: a2 k: \5 ]$ ^2 H2 ?) A
                vrc7.Write( addr, data );1 r. K1 Y7 C1 ?( F, O: F
        }
; E6 d. a8 R8 r- X( a        if( exsound_select & 0x04 ) {- l4 d/ {+ K+ M& H0 o6 w; I
                fds.Write( addr, data );: Z. a; r* N" H+ M2 m
        }- h# T8 O4 C$ n, o" X3 m
        if( exsound_select & 0x08 ) {1 w) k) x) `8 o0 I8 C- q
                mmc5.Write( addr, data );
( i# p4 o8 q* _# q* C/ _% {        }( j+ L: [6 q" f2 b$ Q$ Z5 v
        if( exsound_select & 0x10 ) {& C4 _( ?% K1 ?& T
                if( addr == 0x0000 ) {8 X# t* c9 a1 v! m4 P' X' G4 O/ q
                        BYTE        dummy = n106.Read( addr );- I) U! V4 f& |0 g
                } else {7 C$ W+ T2 t: j( f5 F/ e4 N
                        n106.Write( addr, data );
8 t8 Q. b$ M& ]& }8 d                }+ P' t5 M5 y# l3 {/ {# Z
        }! N& V# u7 G" T7 r
        if( exsound_select & 0x20 ) {
' M; o1 m7 a& o- V/ r1 \- o                fme7.Write( addr, data );
% I. ~1 D) N* b& H6 F: u  l        }
0 y6 I& f/ H+ T& S0 u' P}
4 T& g$ N/ Z; m7 o1 P: J# e
( Q& V* y9 s4 D  \( B- b# `void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
: q' x# o1 f  _6 ^: m4 }9 s) ~% O{
' W+ O9 a& Y* S6 X1 U) n" WINT        nBits = Config.sound.nBits;3 H$ N$ f3 j, \  B6 o
DWORD        dwLength = dwSize / (nBits/8);
; j# A% U! V1 _( {  D, `INT        output;' F8 L5 r6 M" N: R3 q' a
QUEUEDATA q;
' T$ P. Q+ l2 p9 H% ^0 ADWORD        writetime;0 J; R8 g# A+ d) o# b, a

- e& ^. x9 R  r+ X, C/ r" u, }LPSHORT        pSoundBuf = m_SoundBuffer;4 ]' q) X# Z4 X  x$ A
INT        nCcount = 0;
9 p) F$ z" |1 L2 B  r0 M  @# S  \
  b7 [& b: @9 N5 F# M& I$ {INT        nFilterType = Config.sound.nFilterType;, F/ P$ [$ [) T* E* Q' n
. m$ B$ _/ j2 i# A; ?- m
        if( !Config.sound.bEnable ) {
9 x# W9 J( c3 p9 J5 u                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
! v! r7 l- R8 E9 y. o/ z8 B+ ]: \                return;
3 c1 `. K3 F. p$ Y1 D  ~        }
8 A9 L7 p3 M) E# B' A* M8 u- A$ W8 s! {* }, r
        // Volume setup8 B  O) w  L# D" t9 E# q+ L% r7 B/ w
        //  0:Master
4 \; P; P* e8 X0 m0 V        //  1:Rectangle 1* W8 T8 x7 f" `/ s/ G8 h
        //  2:Rectangle 2' Q# [, q/ D9 h" \6 z: I
        //  3:Triangle
& `8 o& d8 Q0 M( R" M$ ]        //  4:Noise
' W/ r3 M. Y; |3 {! W1 u, F        //  5:DPCM/ A9 M  A  z) n) V6 }/ D' ]
        //  6:VRC6+ [$ [* E3 g7 q
        //  7:VRC7* ?% N  l. i% V, ]
        //  8:FDS
, k! B+ M6 [2 P' q% m$ ^! `# E  f        //  9:MMC59 Y- o0 ^7 E% {4 O7 g
        // 10:N106
' I" x5 V! `0 h# {3 X        // 11:FME7
5 u5 c) `! ~+ p        INT        vol[24];
% N& h9 _0 k' G+ }% s        BOOL*        bMute = m_bMute;# x6 h% E0 h( x1 S
        SHORT*        nVolume = Config.sound.nVolume;$ V' X" R' j- Y* \' o" S
; i" `7 \5 {" m. B- X* V
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
' O4 h4 C9 w% R: [: d4 B& d" k
9 t0 N5 ]: A, `8 S7 B3 g        // Internal
) T/ J0 K! f8 j4 [$ t; V        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;8 a# r- k2 N5 B5 r3 z
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
' C+ S, }# {( }& A9 o5 c        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;" p3 S+ K* Y# y9 D" [
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;7 q; ~( r, G2 Y- f% I1 R
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
0 q' [/ Z, K  I0 n0 }# a* _' i
7 W+ r: C% d! O$ i8 r. N6 Z# O        // VRC6
% C2 W) s/ [( h: {+ s4 f1 _% h        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
2 |4 T+ ~3 ^7 X+ |, i; w4 L        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;2 e! c1 N$ F$ |5 U$ }5 P5 o
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
& p, W* a& J3 C
1 |) r. g! p: ?5 u8 ]8 N. b        // VRC7
5 P" j) [. n9 T        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;! k& ~$ Q, j9 b4 {& h+ B

0 O, F5 L: p" [4 U" c0 i, J; K' J        // FDS
! F5 _8 a- x  q        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;0 N- _1 }% q7 M$ }+ ]# ~
3 x# |4 T% B& V1 Y4 Q7 X4 e
        // MMC5
4 Y; C3 N- ?8 `3 X! K) k. Z- N        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;" f: ]! L; A( {# |) ]' ?
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;1 g1 Y% `% D) _
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;! u: k- Y- R+ C0 E3 s

6 V% ~! W, {9 x- m5 E* q; Y" j  D/ T        // N1067 x, x: T1 o( w+ a, n  y
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;& e2 ~* g% N; ^3 I9 |) x
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
# R+ Z6 [$ N( I  N/ L; g        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;( S# c' W6 E$ x2 x+ q3 Q9 T& h
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;) t4 g% O4 O9 N: z/ q. m" X; ~  e
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 H9 Q. P  x/ V0 m* D- i/ h8 B/ B) ^
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 _2 P' p* a1 Y$ F. l, J% n7 P! J# {2 r        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 ~2 i8 h2 Q  f; Z5 _
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
# {1 `3 x$ d7 M! }/ D( D2 K, e6 N- E" C
        // FME7
$ X, b/ ?- n7 j- ?# u+ F        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;0 c9 x  l$ A- h8 I& y/ J
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
) n- q& z" p1 x2 m3 C) c. w        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;' E- ?$ z0 b3 y* E
! {/ J9 T/ T# _
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
5 z% m# @" X/ B, x" A        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
. n4 Y1 p% B3 d5 y9 N' K/ x/ z  G9 \" U! W% `) p
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
9 v7 e& z* Q0 E9 e. t( Q+ D# y        if( elapsed_time > nes->cpu->GetTotalCycles() ) {9 o% j. u9 x- j7 i* @* v
                QueueFlush();. l' V: P! b3 X
        }
  w) {7 z& A+ z! r0 I$ q( R5 N' k% H/ _0 D  r# u8 F7 e2 y+ L  c: L
        while( dwLength-- ) {" Q. w8 A. j' g
                writetime = (DWORD)elapsed_time;6 G$ z% ^9 \% d1 \
' x& U: O( o( H+ r/ b
                while( GetQueue( writetime, q ) ) {& g5 `% x- g  _  K% [: ?/ ~
                        WriteProcess( q.addr, q.data );
  S9 l% m4 C7 G, I9 a                }; _+ \9 M* a8 `3 v; h6 e# M) M4 x

  K/ t$ g5 z8 `; k0 C% h# ~                while( GetExQueue( writetime, q ) ) {5 L+ x7 J' j& S
                        WriteExProcess( q.addr, q.data );. F7 d1 `2 c( H  \% g
                }
% L3 f7 b- k5 [8 A. G1 }& X
+ l* F# G" Q* D4 e* h) e$ o2 T                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7! q1 b8 z+ s' @3 u8 R
                output = 0;
6 w" w9 c  i' g8 g7 w                output += internal.Process( 0 )*vol[0];
: g- \* S# y) O% x& t                output += internal.Process( 1 )*vol[1];
; l+ b- k/ Y8 P' k) q1 h                output += internal.Process( 2 )*vol[2];4 g" m% w" f7 B* _/ I$ R
                output += internal.Process( 3 )*vol[3];, C  M% X# j$ J0 F7 Z6 D
                output += internal.Process( 4 )*vol[4];5 G7 i( ]& R- `- G8 k. B0 O* }# d

% R% b' ]: B" Y9 X; T                if( exsound_select & 0x01 ) {
  Z6 h8 {; }/ G& L3 g                        output += vrc6.Process( 0 )*vol[5];
* @& r! s/ }& T" A, _                        output += vrc6.Process( 1 )*vol[6];
3 |  ^8 _8 C2 }5 w5 j  U                        output += vrc6.Process( 2 )*vol[7];
" p% n! [5 o. a; |8 I                }; }$ z) R' S# x
                if( exsound_select & 0x02 ) {
; L' v( S$ p- ]0 x5 E% C, w- P2 u! I                        output += vrc7.Process( 0 )*vol[8];
" l; k' A. l3 A( r4 @3 {7 h# a% A                }0 T( f% f3 l3 M9 ~1 @
                if( exsound_select & 0x04 ) {8 N; j* H; a$ i
                        output += fds.Process( 0 )*vol[9];
. p. w" |) H4 J7 [  i9 X                }1 G2 \* o: g) V/ \  M9 T0 b
                if( exsound_select & 0x08 ) {
, R: ^! T5 h* B( Z) z' v6 b                        output += mmc5.Process( 0 )*vol[10];3 j1 V3 R4 E: Q! G8 y9 u) T
                        output += mmc5.Process( 1 )*vol[11];
( y- y" s, J1 i4 n: |                        output += mmc5.Process( 2 )*vol[12];
9 [' v5 W0 q+ \! X, G. ?$ s2 {; ?                }
& a  Z7 @) _0 k                if( exsound_select & 0x10 ) {
9 N! V; G. L: c0 M+ W& d# ^                        output += n106.Process( 0 )*vol[13];& G9 Q3 u* i! @* i) g: s6 f
                        output += n106.Process( 1 )*vol[14];
9 V; f$ x8 i+ v) T6 S+ B9 s                        output += n106.Process( 2 )*vol[15];
5 V/ |. U- I3 H; ?2 r                        output += n106.Process( 3 )*vol[16];
$ l1 V7 y7 K1 h( w6 F- R' O* \; T* k+ T                        output += n106.Process( 4 )*vol[17];9 m. E7 Z; j: K0 C0 q
                        output += n106.Process( 5 )*vol[18];
, p! V3 K* b1 j4 ]                        output += n106.Process( 6 )*vol[19];0 D" d1 H8 y3 R( w! R
                        output += n106.Process( 7 )*vol[20];
/ j5 N# ?1 }/ I" G                }
# B6 A( A4 j8 Q( z+ F& x! Z                if( exsound_select & 0x20 ) {
9 _! x3 @4 \+ }! L( n- t                        fme7.Process( 3 );        // Envelope & Noise
) f( r; e) c8 t/ ?4 N                        output += fme7.Process( 0 )*vol[21];
; @4 c, q- B  G: Z" r                        output += fme7.Process( 1 )*vol[22];
9 Q0 R' h7 X6 e, _$ i                        output += fme7.Process( 2 )*vol[23];& s  I) a4 r% c( e' [# v
                }
. ^$ P4 y0 w6 Z
% f  x  p) ~; q) i1 P8 I                output >>= 8;% I- r5 c' c! k; d

! @8 F' e9 a. K+ Z' W9 g! e: Z                if( nFilterType == 1 ) {' Z2 x& `+ |* y  C" z* r% v  j
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
) t) ~5 ]" Q2 m4 T9 r* Z! O% ~! O                        output = (lowpass_filter[0]+output)/2;" j4 k5 c: Z+ @/ Y0 t) T
                        lowpass_filter[0] = output;
% {) g5 j8 M8 G( Q/ r                } else if( nFilterType == 2 ) {
) q+ I5 f- ?) ]                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
9 D; `! v; N' ~4 Y7 [7 Z                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;' J/ C) `, G* ^- S) _( X1 L, Q
                        lowpass_filter[1] = lowpass_filter[0];. v# H) }3 V. `; h" q$ J
                        lowpass_filter[0] = output;
% v* q4 n) `- Y# p                } else if( nFilterType == 3 ) {- @% [$ f5 c8 |5 A% I
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
) f# J7 E# R) S, f3 J' b                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
/ p) T0 |( D& R4 _                        lowpass_filter[2] = lowpass_filter[1];- q, U8 \! o0 D5 s
                        lowpass_filter[1] = lowpass_filter[0];8 Y1 \' c, e/ w( F
                        lowpass_filter[0] = output;
9 F# J9 y' N! M* e; @                } else if( nFilterType == 4 ) {
. X1 ~4 z) ]7 G; g8 V                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
1 `. @8 f5 {0 Z1 G4 ]2 j                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;% ~8 g2 p" \4 P3 {$ `  k9 |
                        lowpass_filter[1] = lowpass_filter[0];) q+ i7 r" G/ x1 E
                        lowpass_filter[0] = output;
% a6 W" o' _6 O3 `                }
* I) J3 v' r# }% j0 g0 k0 [: i  j
, e7 v6 \; ~% U. h+ u+ e#if        0
, }# M$ U  f- E. v1 B9 j                // DC惉暘偺僇僢僩
: |1 l6 Q9 h3 E2 p                {) M% [: H4 W; [$ u' x
                static double ave = 0.0, max=0.0, min=0.0;' Q. l8 `* L" y# L- r. O4 Q
                double delta;
5 y0 }5 t4 b1 N5 q6 J; B                delta = (max-min)/32768.0;& Q, u" ^3 S: |6 R
                max -= delta;
# ~0 `. ~' q$ M7 @" t                min += delta;5 F) ?& S- p; p7 Q, H
                if( output > max ) max = output;6 t4 h' z! D7 V* }
                if( output < min ) min = output;" y8 W5 _- N+ ~
                ave -= ave/1024.0;
; x! E% x' F0 h9 n8 B                ave += (max+min)/2048.0;
5 Z6 c% X  m8 B2 A                output -= (INT)ave;
" U6 v  o5 g. b& l                }
5 Q# k6 [$ E0 U* Z+ D& [( {9 p# e#endif! n* s4 c$ o& j, ?& m6 k; X' c4 r
#if        17 B! h7 ^) i7 N& X: n
                // DC惉暘偺僇僢僩(HPF TEST)/ u: s5 O4 L) }0 R4 Z( P6 ]
                {
: G3 _; _- R- ]: c//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
  d( w% \( ]9 T' b6 C                static        double        cutofftemp = (2.0*3.141592653579*40.0);
. X: A: S9 x& H" q  K                double        cutoff = cutofftemp/(double)Config.sound.nRate;. d5 J' ?) C( ~) E0 c
                static        double        tmp = 0.0;2 C4 x6 U3 ^7 _
                double        in, out;
! r; [! w& h. [# D) E- }- @: f9 H% ~3 M# i
                in = (double)output;3 w# p6 M4 X! q0 N- \2 U3 o5 W
                out = (in - tmp);: \6 u9 Y5 l( k3 ?. A: j
                tmp = tmp + cutoff * out;
* ?# \, K* C6 X" C1 m9 a: \+ w1 P( Q) ^( X( z+ E/ Q; t9 I: `5 V0 m0 [# M
                output = (INT)out;
+ T  y7 f  @* B9 h5 M                }
9 y, N! h. C1 y. n#endif
, p' l# l. l$ r#if        0
, R& T" Q5 h+ V9 ^# y. @                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
3 c5 g+ F$ g2 }, b# y, x                {
2 m9 w4 P4 H; Y                INT        diff = abs(output-last_data);; `/ c  F/ V- _4 H5 n. e0 B) v
                if( diff > 0x4000 ) {  T+ T/ p& `) j
                        output /= 4;
8 p9 t/ \- K+ |8 Z; X( W                } else 8 ^; f- W. C7 X
                if( diff > 0x3000 ) {0 R: I, o0 b% n& z
                        output /= 3;& |: |3 R/ g1 c$ f5 e3 S8 e
                } else( x; @, w# F3 p4 X8 O" M
                if( diff > 0x2000 ) {
$ A* o; e7 C% `                        output /= 2;
. T; t/ Z  M6 K- c: _& E                }+ R  t% g1 t5 ^& e7 B/ F
                last_data = output;" ?" j6 h8 t# x' [
                }9 B/ m1 l& u+ n2 X# w1 r0 Y# F) S
#endif
( L+ P- k  i4 g2 x6 G( F8 {+ I. Y                // Limit; D' W- ^4 m6 x- Q7 `
                if( output > 0x7FFF ) {
+ u; a3 E5 p* z3 a2 E5 Z/ x                        output = 0x7FFF;
* h7 X, c- F1 I$ K% L                } else if( output < -0x8000 ) {, h! w) r" c+ q! \$ ?
                        output = -0x8000;7 \% l: M: u, y' O. g
                }9 s' n9 C) o" R/ S

4 e# ^7 t" u* U/ U( i8 r* Y                if( nBits != 8 ) {
1 E/ q$ s  W0 X                        *(SHORT*)lpBuffer = (SHORT)output;& U) I0 `$ Z! g' n0 |& ~
                        lpBuffer += sizeof(SHORT);
8 @# N. c2 }% P) A; W  V$ i                } else {
# X  N5 d9 E7 D' ~) g% h! m                        *lpBuffer++ = (output>>8)^0x80;
  w6 u  E, `; S6 ^% n                }# s# U1 r5 l# i# Z1 Y% A
2 g# D9 ]8 m. w$ S( `. t
                if( nCcount < 0x0100 ), ^! v' x: M1 }, L: E
                        pSoundBuf[nCcount++] = (SHORT)output;
1 ~( N  H4 i7 `  f0 x  o3 [
3 G  B- @1 I( Q7 _: B//                elapsedtime += cycle_rate;3 w  q' y/ G; }7 Q
                elapsed_time += cycle_rate;
& B+ `3 }! A9 A5 @9 e3 O        }
5 \, h8 S, e8 N2 W- k# n% C4 |7 O& _5 W0 t: V8 Z
#if        1
, ~5 G+ x. t% ?$ Y2 f0 T        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {3 n& d7 ^) s' S5 ?2 f& [- a# b0 x
                elapsed_time = nes->cpu->GetTotalCycles();
! u. h. ]* U. V- W1 {3 ?        }+ O4 [) {8 x7 g" ~, J
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {% A0 ~6 U' h  \* F+ ]
                elapsed_time = nes->cpu->GetTotalCycles();9 G1 W) m8 B- P; ~: a" R+ q
        }
6 b1 ]; @% y; i" r( P+ Q. a2 ?$ w#else$ _% j; r% x4 a: }, a
        elapsed_time = nes->cpu->GetTotalCycles();7 C0 D! \5 i& F# X3 U# @
#endif. Q# M4 @& c$ K! K- I5 D6 D
}" O. B# S" r3 s

* L5 ]2 ?$ Z& s& ^" s// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡). u) ]& M: T* J( }% M. k
INT        APU::GetChannelFrequency( INT no )# p9 }7 o5 E! f* Y& ]! `& f
{: u( T& ~  y4 L* K$ q" l/ I
        if( !m_bMute[0] )
; |: p9 J9 V! |8 H% P                return        0;
) X* o) W) ]; \% [( h( n
8 G' d+ K% `  K9 e# s$ L" ^  V        // Internal; J7 ]; ?* H  Q
        if( no < 5 ) {  c2 R7 p4 l3 D* V# L* {
                return        m_bMute[no+1]?internal.GetFreq( no ):0;, V& {7 R6 g( n" A8 o0 @# g: `
        }
* W: w' m3 a* P- P. t        // VRC6
% O) G& i0 Q. x* ]6 e1 ~7 J        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {! v% T: s4 x' E; X
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;5 z! L5 t3 s4 q% ?( z: x
        }
( Y: T3 ~; N: U& q  a6 ~$ Z        // FDS
0 i9 A6 w6 i' b( @) D2 D7 @4 n/ o        if( (exsound_select & 0x04) && no == 0x300 ) {
0 K! c% {5 a( l* f- t, S- B                return        m_bMute[6]?fds.GetFreq( 0 ):0;
. `4 M" [6 ~0 A8 t1 R; A        }
: e7 J8 S: p. k1 W8 L3 q" Q" S3 E3 V        // MMC5
6 }8 ^, d4 Z' M" v0 A! J        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
% E/ P$ ^. u0 {( K                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
5 o. @9 K8 S1 V) R2 D7 P- e        }
+ C  f$ h# k2 k7 O: j* q: q  I' }6 P' U        // N106, E- ^: s. \" T7 r+ D
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
$ W1 x6 q4 C( l! P5 i                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
  Z. z! [" _1 ]& v: v3 c        }! ]9 g) ~" h1 U& z+ C  ]& R
        // FME7
# y1 M$ E" k7 e        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
# K: z' x) ^* o" J+ K7 R                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;% F  e: l& J  U- V( u" T
        }! _! G3 ]6 F! N% G6 z
        // VRC7
! C. z2 h# V+ Z7 i0 a4 v7 I        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
9 b5 Q* _. }7 ~; f* Y+ B8 z                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;! a9 c, W+ N0 G; C( A% Z+ Z
        }4 C6 l0 B9 b7 J- T
        return        0;5 E( v7 {+ [( R) n3 w' q
}
7 F7 m4 U9 P* X% e$ v+ o% W! v4 r, I- d& Q& v
// State Save/Load* `8 U1 g+ l+ b6 H* f
void        APU::SaveState( LPBYTE p )$ s1 R* t' w9 d4 R
{
% g6 n# c; T# S3 v! a% T8 q#ifdef        _DEBUG( @. e* Y# n! U. l1 n: S! |
LPBYTE        pold = p;# W1 H% }* S3 ~& s/ x1 x0 O
#endif
# ^+ {. r) X. K! Y  M( g+ q! o7 G# G& O7 D
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞& R- C. p4 y% @2 n+ X0 r1 m" i
        QueueFlush();
; j( |/ y' y; q9 X0 o8 \7 [
, e% i; {# E$ {; b: V        internal.SaveState( p );
4 ~8 S2 W4 q4 c        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding+ S7 b) R8 x$ m& Y! Q( z

, B/ g7 @' _8 L; V        // VRC6
7 S8 C7 J/ N6 [8 i& `4 F2 D. W/ Q( I        if( exsound_select & 0x01 ) {
8 w& c7 ]- a$ a& z& @5 ]- @                vrc6.SaveState( p );
. X7 }# u7 V! c2 r; R                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
: Y% e; G! ]! B        }. c! A" H" A: J# y7 r- q6 |* t
        // VRC7 (not support)
! S7 H- N- Y; z        if( exsound_select & 0x02 ) {
! v5 f0 J( Y* m3 @# x! X                vrc7.SaveState( p );
  C; O. g- [; I6 a9 q, n9 U                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
4 g/ W2 b6 n2 p% W: Y        }
, ^# e% i+ v1 P8 z& z        // FDS
4 ^' d0 d% H# o4 b  ?& {, a7 L1 p        if( exsound_select & 0x04 ) {
6 N5 z0 y$ y& z. @0 J0 E0 z                fds.SaveState( p );
2 f$ _: x4 |0 Y8 b, T* w                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
) Y% X9 N  x) c* c# `8 Z        }
; X# @2 p4 l  U# W. v* M        // MMC5$ G' U* h; a5 S; H6 ]3 N
        if( exsound_select & 0x08 ) {
' X- E( w/ ?  U" m                mmc5.SaveState( p );
* U: d  w5 ~+ n                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
( z' c3 l8 Q4 S5 l3 v* @        }
& N& k: {  L2 q  V        // N106
; U! m( V1 X/ b( T7 a9 k        if( exsound_select & 0x10 ) {' L: D9 a' {% p# w# f4 Z& T
                n106.SaveState( p );
# A. Z4 Q  g) n                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding% u4 A) S5 u2 }9 f! J
        }
+ c: B. b( q& O9 A2 N: n) s( `        // FME7- r$ |( Q4 ^3 t7 U3 W) b
        if( exsound_select & 0x20 ) {
1 I0 n1 t9 w) Z% \                fme7.SaveState( p );7 g! O8 Y6 c3 k% k6 d
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
- d. J! o( f! p( x0 B        }# H" ]' K! \8 ?5 E

5 `7 Q- h  J$ g5 [0 A* e; d! n" Z2 |#ifdef        _DEBUG
0 t- I. `5 j" z  G6 cDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );) U% W4 h2 z: S3 x9 K+ {/ |/ R8 W
#endif
" q/ e) z$ I: U, r9 S}; E7 X' O2 G2 T3 P. J& V

- X+ o( u8 y) ~9 w  E4 o! F$ b  Qvoid        APU::LoadState( LPBYTE p ): p, a$ W& s8 h
{" y1 F' M  A6 J' x- U4 t7 v/ Z6 ^
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
4 R3 D; _( N( |: K: b        QueueClear();
+ Z- X4 b( h; V' k
- q- R: t# H' ~  O/ {        internal.LoadState( p );$ x4 G. I+ N8 {4 L. f, J) g6 u
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding; u+ m6 Z- p8 L# u# }
! s7 A: J" n; _7 i" |: q$ I
        // VRC6" V1 o1 g' v3 ^" e* J4 P
        if( exsound_select & 0x01 ) {# k; j6 Q$ I0 s* V& |
                vrc6.LoadState( p );
+ M7 r& e# C, V% I: }. \; Q                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
# A2 @! U0 e2 ~7 x2 E        }
) a$ P" O3 k! @6 g9 L1 q        // VRC7 (not support)
, Z! j+ x. b" v; [% y; Q+ B        if( exsound_select & 0x02 ) {
" Z6 @, Y+ L# q- x                vrc7.LoadState( p );
$ M& t. B' K$ S1 b4 |; V' K                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
' D4 y! z( s" s        }3 t+ l( X" F) E8 ?
        // FDS
+ _" b1 ~# p$ p        if( exsound_select & 0x04 ) {
; x" Y1 ]& Z: e0 v* ]! a6 Z; O. x' S* g                fds.LoadState( p );' V/ O! I% N' F9 F
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding  o: d6 ]' I8 `( `, w* Z6 x
        }
- L- |, i8 ]* \! I7 _( L, c- ]        // MMC5
) ]+ }3 y3 I, i) E, h, @0 a' L  f        if( exsound_select & 0x08 ) {0 |$ D- D/ z$ c8 b% t
                mmc5.LoadState( p );3 f5 c3 p; c/ A* @% s, d: @* b
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
3 L% p% u; H, m7 i1 _. ~        }+ j* J! h: ?: p. l1 K( C& {' m0 h
        // N106
( G- }$ W0 }7 a, ^, f! z        if( exsound_select & 0x10 ) {4 o  Q  y" H# g# U) r* N$ R
                n106.LoadState( p );  ]( }' T) A- H
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
* Y& H) P$ x9 Q1 X, ]        }
1 `' @$ @. T+ Y" j2 E. H% v+ ]        // FME7
* x* }: [3 [; l! k# K! i9 j& J/ L( c        if( exsound_select & 0x20 ) {9 ]/ ^" J! X$ _- N! T+ a
                fme7.LoadState( p );
; `/ f4 U- }/ t& X' D$ V                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding( X7 N/ d+ k9 h1 [' j: X% [8 b
        }
' B/ S) n. p8 d# _% w% p+ }* m}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
8 p, E& S3 A; D6 j/ _可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。7 J6 P* o( c( h7 L' U
感激不尽~~
7 B$ Z* d; t: P5 \/ k( E
恩 我對模擬器不是很有研究,
! k7 i7 G: h' M$ @雖然要了解源碼內容,可能不是很困難," ~  X; W% N, |: K9 f+ X( M( z
不過還是要花時間,個人目前蠻忙碌的。
' h" {4 d- ]) v8 k& ~5 L$ G  }6 w& i* W; u  N# _1 J
給你一個朋友的MSN,你可以跟他討論看看,. Z; u  X  k- G: h5 _7 f
他本身是程式設計師,也對FC模擬器很有興趣。
; b, M9 `, G: X0 A6 C  f# z6 N' W" j3 O6 ^7 v' A/ d/ R
MSN我就PM到你的信箱了。
& s. d  m1 l. U6 ?1 Z7 B) \7 ^. r3 Y' r. _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 发表   J. D( q5 i$ e  Z" v
呵…… 谢过团长大人~~
1 b& }! Y* D7 r; B. i9 |( s6 L: c7 V- a; {

# W! n0 {/ Q- p7 h哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
% E: d: Z9 H! c0 i; @团长的朋友都是神,那团长就是神的boss。
% ]2 z9 b1 F; n+ A# P; B9 f
哈 不敢當,我只是個平凡人,1 f) [  W6 C1 ], G1 l; Y
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙; ^, z8 z9 @8 S, c- ]# H
ZYH
. n1 N* d* R: ZQQ:414734306
8 N3 a1 |' d1 D1 Y! R4 B  J$ d* DMail:zyh-01@126.com
. I% K& {# h+ w/ Q. K" E+ Z  d  `0 @  d1 {6 H
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 / |3 b9 Y$ o1 h* e
再次对团长大人和悠悠哥的无私帮助表示感谢~~

4 ~# V/ e6 n, E7 E  m% w' c& Q不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-30 10:12 , Processed in 1.100586 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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