EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。- Z8 v) Q6 t( Y1 J
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
/ M2 X% p) M, M5 j) u; i这里有相应的模拟器源码,就当送给大侠了~~+ n# u1 J% D! t- i
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
, ]  U; [- b! \, J能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。9 q- i0 S  o/ D
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~7 i7 `' d. t1 o0 |8 w& Z- X0 Y
这里有相应的模拟器源码,就当送给大侠 ...
; N; ]6 o/ m# ^8 Q0 Z
聲音部分(Audoi Process Unit = APU):
2 p& o( a- R' m4 m) S0 S; A7 i0 K5 W.\NES\APU.cpp* }- R& ^, U9 b- E/ C8 h0 d; b
.\NES\APU.h) W. S+ S# I% ~

: F4 m+ M4 |( {. O6 H7 H' k
' h1 F2 U3 |( j: W影像處理部份(Picture Processing Unit = PPU):! I) ]) Z( z1 Y# J! U7 E
.\NES\PPU.cpp
! t- J1 |* i' r+ f" `6 t* g7 Q.\NES\PPU.h" P+ [1 T/ H6 ]! }, H4 z$ F

. _# R: p, ]  Q1 p如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
. \  L0 G0 m5 \6 k& l(由于很多专用术语和算法机理都不明白,所以看不大懂……)
3 |$ ?; L8 H: d1 O1 E6 F//////////////////////////////////////////////////////////////////////////3 Q1 D+ s$ p# C  x
//                                                                      //- t! |% _& }" w
//      NES APU core                                                    //2 S9 _5 D2 }. a1 G
//                                                           Norix      //
) @& B% c: F' S//                                               written     2002/06/27 //
5 I4 G6 y5 v& m" X; h+ g" B//                                               last modify ----/--/-- //: F3 T% x3 i4 Y- @1 F
//////////////////////////////////////////////////////////////////////////
& |  g7 F8 _* ]3 T  o7 u/ y" {/ K#include "DebugOut.h"
7 z4 b5 a, U6 ^3 [: L#include "App.h"
  }$ L4 o  d" H) w9 g" P% p#include "Config.h"* Q+ |; J: @- o' N
2 }2 Y7 ^0 \$ E
#include "nes.h"/ Y( N) Q6 ^2 h6 u
#include "mmu.h"
9 {& R9 t* u# V9 }#include "cpu.h"
6 d1 n# [3 ~: t#include "ppu.h"- _  D$ s' I9 f% _4 Y& z
#include "rom.h"
% R9 R) ?2 [, v#include "apu.h"
) d! p4 c5 n$ z* Q
. K# j0 v1 I2 i! c0 d$ ~5 F! W// Volume adjust
; }: K* c$ s! u9 m// Internal sounds" z2 [2 a$ p* f, \0 {4 Q% r
#define        RECTANGLE_VOL        (0x0F0)% |  d  }( v9 u, a
#define        TRIANGLE_VOL        (0x130)8 U9 R2 p3 r5 g& i# U/ G( B
#define        NOISE_VOL        (0x0C0)
$ ]% C5 A# M) ]! s  w7 d! R( w#define        DPCM_VOL        (0x0F0)& u# C  U2 [6 s2 j3 p
// Extra sounds& n1 k1 x* u/ T0 x4 g( o, r8 i
#define        VRC6_VOL        (0x0F0); D5 g6 I: ]- Y2 i$ j4 X+ m5 m
#define        VRC7_VOL        (0x130): v2 f! Y. f8 x& Y7 f) L
#define        FDS_VOL                (0x0F0): b- C& u, w% `" j" _; r  g
#define        MMC5_VOL        (0x0F0)/ F9 {+ D' f0 I1 J3 K1 t% k
#define        N106_VOL        (0x088)
4 }% t0 f2 O8 I- ^* \5 r2 o#define        FME7_VOL        (0x130). s$ b9 u. i4 _* q3 n
4 h5 o* Q) k$ I3 Q8 M  J$ N
APU::APU( NES* parent )' i- S3 f+ U+ l; c5 D  F
{
7 K: @, I1 C+ B4 a1 m        exsound_select = 0;
) C: \" }& ^, s; D
. W, S# ?4 q' ~# s9 m4 E; H        nes = parent;8 T) p5 N4 _; c- |: T$ @/ F0 H1 O
        internal.SetParent( parent );$ ~. w9 u, t' ?+ W& I

+ s+ f$ [0 ]. D3 a0 V8 K        last_data = last_diff = 0;
; K. u2 b& L  ^
9 T' o( H& Z$ O        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );- z1 N5 i4 E1 H% m2 B4 w$ _7 ^4 L

, X- B1 p4 k6 [6 X! P0 ?4 H" m        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
: k0 s4 g: o3 |( e        ZEROMEMORY( &queue, sizeof(queue) );( \$ ?; I: Q, r+ V
        ZEROMEMORY( &exqueue, sizeof(exqueue) );; j; s2 c% V& P7 O
( M0 j- U! n7 C! D
        for( INT i = 0; i < 16; i++ ) {
! T1 U+ t$ J) A5 T                m_bMute = TRUE;9 q) [9 T! ^* h' U) I
        }
/ [" J% f1 S1 j: k  p( |}$ i9 m9 d: B6 F% ?! [
2 y1 k5 i  `' h
APU::~APU()" S$ B$ T' \( K' S* D7 u$ x  B' Q/ e
{
# ^0 F$ X/ b3 X5 A7 W# b}  z* q$ i0 r3 P0 r

3 @% v( f) v  Hvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )8 B+ t8 ^1 u- ?9 }+ A, s  D/ d
{, V3 c6 @5 b$ [4 m
        queue.data[queue.wrptr].time = writetime;3 l  ]  [& D5 M; P" M# n1 j3 b- \
        queue.data[queue.wrptr].addr = addr;6 S5 x# S9 C( l7 L& r! S/ k7 {2 U
        queue.data[queue.wrptr].data = data;: l1 |0 ]; {% i$ z! x: b# s- H
        queue.wrptr++;  X; X$ \" V/ B. g/ a, e4 N4 T$ r' y
        queue.wrptr&=QUEUE_LENGTH-1;: J1 W0 [0 O4 w6 `
        if( queue.wrptr == queue.rdptr ) {
5 G3 J# H3 a" S                DEBUGOUT( "queue overflow.\n" );
' {( _* U$ I2 r6 S' e" u: W        }
. `' V! z5 {7 \% _- D}
! n8 z+ j' }& N- z! h& J5 H9 V' a8 y" {
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )* m$ r) v! B  S8 B
{7 i  k) B# v1 r  a8 n8 ~0 i
        if( queue.wrptr == queue.rdptr ) {" Z2 n& E+ m4 I
                return        FALSE;
3 O2 g" W, j- A# I1 m" ]        }
% G3 ]* r5 p/ r2 T        if( queue.data[queue.rdptr].time <= writetime ) {5 M7 g, r! }: X2 l
                ret = queue.data[queue.rdptr];
' K& }* Z$ m8 I+ `                queue.rdptr++;2 W# r1 D6 {" j5 F/ U" ?
                queue.rdptr&=QUEUE_LENGTH-1;$ `0 B7 x; q5 s4 a
                return        TRUE;
7 s( }: u. J! d1 s/ O( q- O! B& ^' I) n        }% [; {7 k# o& t; z6 |9 t- e8 r  }# Z
        return        FALSE;' T3 x5 M5 _9 |7 b. @8 R8 v1 H
}2 T! B* q" z2 h/ o; j  c8 k. l8 Z

. j3 K' ]8 g. {, L* j  uvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )8 z$ x: Y) U2 b, {* ~# `& {
{* j& P8 e$ o$ @* i& s" N' P' ?
        exqueue.data[exqueue.wrptr].time = writetime;- M5 J% Q& K) l6 Y6 R: B
        exqueue.data[exqueue.wrptr].addr = addr;! _/ s: K" i2 i( E( G
        exqueue.data[exqueue.wrptr].data = data;0 B- Z+ m3 @4 F8 a0 w6 j: P  \
        exqueue.wrptr++;
7 S+ l$ D' m$ h" d' ~/ T        exqueue.wrptr&=QUEUE_LENGTH-1;: B- s% ~1 E# |9 ~9 G4 s0 ]
        if( exqueue.wrptr == exqueue.rdptr ) {7 b4 V8 ?) A# ~. l) ^4 Z4 Y
                DEBUGOUT( "exqueue overflow.\n" );
8 F3 r- f) Z( f- o% D- T        }
$ |: [$ n' V" |4 m- [  V}
& {9 h) n6 a8 t% p) F/ T. \: Q2 U! _$ K" c. Q' \
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )7 y' _& Y$ ]. D! v
{, X% V# X5 N- c% h  C) ~: Z+ [
        if( exqueue.wrptr == exqueue.rdptr ) {
) S" ~' M# d4 g( Y* L                return        FALSE;! M3 z: j5 `! a+ h
        }. m# C* t# [+ I- u( H4 j% ?
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
) Y! X+ c/ u2 `( U) w4 w% S                ret = exqueue.data[exqueue.rdptr];
5 e# i" k- o0 N& @                exqueue.rdptr++;' V7 b* k% w/ W8 Z
                exqueue.rdptr&=QUEUE_LENGTH-1;
$ i) o3 X+ l* P: V1 S" j                return        TRUE;
, n0 \, e2 S% R        }& {! E/ e; T7 U: B3 n8 S, P  h
        return        FALSE;9 q2 N, L: `) t2 h4 h
}( @9 b) C2 X8 R. F0 p% }

: H% o' s2 n) K0 w3 _void        APU::QueueClear()& f/ N& v8 [8 R. T- Z
{8 ~- _$ C3 O5 ~7 C2 B* w' m
        ZEROMEMORY( &queue, sizeof(queue) );
$ U" e5 ~/ B% A) T        ZEROMEMORY( &exqueue, sizeof(exqueue) );: F: G4 {8 I( Y5 @4 Y4 p; H
}
# b0 A6 O% e7 w! G* |; _
+ T, G7 J+ S. Pvoid        APU::QueueFlush()5 ^: t. ]- S0 U5 O8 Z
{) y: t( R$ M3 Y2 p7 Z% C; q% k
        while( queue.wrptr != queue.rdptr ) {1 W9 d$ l6 F5 Z' p* g' Z
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
9 F$ I3 @  I5 V0 z( l" V) F                queue.rdptr++;9 u! p% N9 k# R8 l) l" f$ k; J
                queue.rdptr&=QUEUE_LENGTH-1;# U5 O0 f+ U9 J/ p
        }
( q7 e" C) K/ r6 e- E, i
2 {# ~8 `+ {7 O: j5 m        while( exqueue.wrptr != exqueue.rdptr ) {& T8 q9 a0 F2 [/ U. R% y6 E# i# `  t
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
9 y" j  i' w$ w0 I5 X/ T                exqueue.rdptr++;4 [* c* R+ S- G  A
                exqueue.rdptr&=QUEUE_LENGTH-1;
7 {2 |* Q) j& {( m( n# \/ E4 O        }( S/ v( D6 P6 \0 L- S
}+ s) G6 J: v: R, L( M

8 ?9 I# c! A; _# [; xvoid        APU::SoundSetup()7 G" x0 A7 V5 r' {$ o/ Z$ _# x& q
{1 ?$ y" Y+ R& t+ x4 H8 u, n
        FLOAT        fClock = nes->nescfg->CpuClock;
- ^4 I, j. ^2 A5 \        INT        nRate = (INT)Config.sound.nRate;5 R4 }+ G9 K* D$ l. w3 t
        internal.Setup( fClock, nRate );! T6 p" O; h6 g
        vrc6.Setup( fClock, nRate );
# `, v' p6 N6 |9 d2 J% o) r6 r7 h7 W        vrc7.Setup( fClock, nRate );3 ^7 W1 g. A6 e( `& T
        mmc5.Setup( fClock, nRate );+ v; \( u4 P/ o3 {3 w7 L/ l4 r
        fds.Setup ( fClock, nRate );
* A+ n8 @* g5 N. g& r5 [" X        n106.Setup( fClock, nRate );
* E8 w( l2 H- B% u1 }        fme7.Setup( fClock, nRate );
! L- U6 j7 V6 V# ~: F% ~- u4 _}% G, Z  D! Y  c* w7 {

. i- F, X1 @; s$ F9 l" X# ?+ [void        APU::Reset()
7 q6 i0 ~( ^! `. V{
9 \, V; i, {) b  J5 N0 C* f        ZEROMEMORY( &queue, sizeof(queue) );* h" A& W% q: e. d. F1 M+ A: e
        ZEROMEMORY( &exqueue, sizeof(exqueue) );) [/ e5 O2 u8 C- J

' w. x$ f% ~6 |, N        elapsed_time = 0;8 C& f  ^  ^/ `2 H$ U6 V2 V7 v
; k4 n: F/ t! C, h( `
        FLOAT        fClock = nes->nescfg->CpuClock;/ g/ V. P- [$ N3 p& I
        INT        nRate = (INT)Config.sound.nRate;
) V: Q5 q- e' M5 s- v4 y        internal.Reset( fClock, nRate );) m7 m) W9 ]. d; o% Y6 j
        vrc6.Reset( fClock, nRate );
  [1 p, \; V2 C+ Z2 q+ \8 D7 A3 t# J        vrc7.Reset( fClock, nRate );
# q# V' J" R& f        mmc5.Reset( fClock, nRate );
! {' c. s* ~! ], z  r6 [        fds.Reset ( fClock, nRate );0 L, b; K! C' `9 N. E$ n
        n106.Reset( fClock, nRate );
4 `! t" a3 `% }7 k# d        fme7.Reset( fClock, nRate );0 k0 X8 V$ x: S$ h  X  r
1 I5 Z- S  C/ ?8 w+ h( X4 G* d
        SoundSetup();
5 }/ {) I/ o8 @}! F# _) f; D' O, K! B0 _! s

2 h% C% d! Y1 O1 m0 H( b- q. Ovoid        APU::SelectExSound( BYTE data )& V( _- h+ i, T$ B1 X2 l* b- n
{
. ?0 x2 h8 T" r8 Q' m        exsound_select = data;
" ~; D9 \- h# u% h1 O}  W: K# y! V# @& Y" y( s
) l4 o6 p  b7 a% c
BYTE        APU::Read( WORD addr )3 M" v/ g0 ?5 F1 @5 M, j
{( H8 w3 s, i4 I  c% B
        return        internal.SyncRead( addr );9 q6 l, i. M# u6 h
}
  q% V' R. E9 F& N  \  O# d. c
7 a) [# Q9 Q$ M$ fvoid        APU::Write( WORD addr, BYTE data )
( [0 @: u; J. l. E/ _; F: C- G{
3 Q1 k& I/ Y6 @5 N+ O! L9 c3 O9 f        // $4018偼VirtuaNES屌桳億乕僩' y- J% y3 [0 d
        if( addr >= 0x4000 && addr <= 0x401F ) {
  G. s# c* Z) L4 y8 n                internal.SyncWrite( addr, data );- v5 z6 J: R; ]9 q# u
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
) B, S0 S2 T. j& x5 K, C) m        }
; U# f6 ]% [* M4 m- J2 J, E}1 S" }7 e$ {# Y5 v$ c, s
1 |$ }0 a& Y8 a; N1 ?* {
BYTE        APU::ExRead( WORD addr )9 n) p% \0 ]/ |1 B* [6 N. Q7 ~
{/ G' w* m1 m8 e0 H3 e
BYTE        data = 0;- Y# k7 C, [; d- ~$ i8 b
6 d4 N0 x5 S3 C* g- x! D. V4 v
        if( exsound_select & 0x10 ) {$ ^/ V. o! g% Z# P
                if( addr == 0x4800 ) {1 V' ]9 x) d5 `
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );, I) _9 z3 @; k  Y
                }
5 G7 ?1 w+ n0 r! ~6 l+ }        }) D! h9 n( L9 ]
        if( exsound_select & 0x04 ) {
0 X. a; {2 Y# I! I# W; t                if( addr >= 0x4040 && addr < 0x4100 ) {
5 V6 e1 A0 G9 I+ P                        data = fds.SyncRead( addr );
$ f8 \2 q7 C: l" F1 ?$ J                }
0 q- @! W0 w; q0 C, Q6 S        }: W( B' |- t8 q$ [
        if( exsound_select & 0x08 ) {" D) @: u0 w3 b. `/ J/ k5 ^$ |1 D, ~
                if( addr >= 0x5000 && addr <= 0x5015 ) {! n7 B9 g; V+ D4 {$ _$ w9 h
                        data = mmc5.SyncRead( addr );
$ [# o) O$ O% @0 b+ L  J                }
2 m: l# Q, ~) i3 G! L        }
1 f) v& Q1 u. @: E% H) d8 P5 r0 A( N3 p8 g% _$ [0 s+ s& B
        return        data;7 b! S8 e8 V. q0 M0 ?6 [/ I/ A' s6 x
}
( b: l$ j. D2 [$ u3 j! o7 \: ]( N, T. e7 i
void        APU::ExWrite( WORD addr, BYTE data )
4 b6 m1 A, v; W: d5 w: Z* X- N$ N{
* r$ e+ ]) [1 s: L# m! e& C        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
3 K3 @6 Z/ T1 m* @, z3 m( x% `4 L
$ U* C' i0 Q3 g3 v' w$ n        if( exsound_select & 0x04 ) {
# C5 {" f0 \: C# v                if( addr >= 0x4040 && addr < 0x4100 ) {
9 y7 f" m" c+ T                        fds.SyncWrite( addr, data );
" M4 C, w2 [5 Y9 L                }
1 O# L; _2 Y# l9 W3 L        }
/ |8 S) x) x9 ]3 q
  G# N) V  T( k- X. C        if( exsound_select & 0x08 ) {6 ^" v" p3 D6 s0 ?7 B8 G1 n
                if( addr >= 0x5000 && addr <= 0x5015 ) {  U- a+ \% D; l& n* Q% [: p- v
                        mmc5.SyncWrite( addr, data );: G& `& }) W) ^/ a$ J0 q0 N! [
                }
" w  @" i  r2 a' B5 |5 N/ f        }/ d) M0 w7 C9 h/ O* @9 n& H! ^
}
. ^& I9 O  O! ^* F  y# r7 T( m7 r; f* D9 F/ q& G! F
void        APU::Sync()4 I; P( {) h9 B: v
{
; B, K$ v; P, G: \3 }8 V}/ |( Z/ R; v+ ^; Z, }3 j
. N! g' y* u  u
void        APU::SyncDPCM( INT cycles )- b4 q  `$ u# Z3 z2 n" q0 ^
{2 I1 H2 r3 r+ ?3 }- j4 q; A
        internal.Sync( cycles );
+ J) C, D3 [4 T/ t+ Y8 n3 Q5 ]
9 k& T  |3 K" y- i) s5 d( }' s        if( exsound_select & 0x04 ) {- D& T/ _6 s! `* n! ^. f$ V
                fds.Sync( cycles );$ r6 n$ t) r9 Z$ k# _& A9 p
        }5 ^5 a$ L1 E7 c# B9 C/ b
        if( exsound_select & 0x08 ) {6 _. O1 L; V2 `$ a
                mmc5.Sync( cycles );$ f$ }! H. Y" ^6 H
        }
1 ]3 d. f8 j$ m' {. D5 s6 S8 T; Q}
2 A- V) `  w* g3 T0 R& u' Y% `5 G0 i" [, Q; v2 a7 ^. O
void        APU::WriteProcess( WORD addr, BYTE data )
0 f7 d9 x: M8 F$ H  L% d3 |{* X, e+ R5 Y/ Y0 N
        // $4018偼VirtuaNES屌桳億乕僩
' C* U& r3 n9 [4 d4 N        if( addr >= 0x4000 && addr <= 0x401F ) {
( M4 a8 l' O" L+ Q( x8 a* l. n                internal.Write( addr, data );
/ t5 u, I6 C0 k! W. j        }
+ g3 _! N- g) ?. C7 G}+ c' {; p9 {7 C: N% E; Q1 L
; g3 o$ D! `1 F- e7 x0 t9 L- g
void        APU::WriteExProcess( WORD addr, BYTE data )% |8 I' G# M* V6 f. j: I
{1 u$ f. @; {" K- ~* ~' T6 \
        if( exsound_select & 0x01 ) {/ q$ F8 |4 N1 S! W* ]
                vrc6.Write( addr, data );
4 d  r: k+ s) R  C        }/ G7 u2 |; D* u  X6 I! v" X9 t
        if( exsound_select & 0x02 ) {/ X' V3 c) M; @2 M2 |
                vrc7.Write( addr, data );  J% p! s. p' s, Z
        }; P) i: l. t/ k' h1 w1 m1 ~
        if( exsound_select & 0x04 ) {; z6 Y& F# o! U% u8 p5 P) h; x
                fds.Write( addr, data );
1 f: b1 N' _: ?; t. m        }
% w3 z% V5 B: A* B  V        if( exsound_select & 0x08 ) {2 [6 \5 @* `: O' s7 U' P  d
                mmc5.Write( addr, data );
# ~" K% s/ T8 F8 r9 v& S: F        }8 \) z% Y8 b6 Z& m$ \
        if( exsound_select & 0x10 ) {# i' z; l$ `4 c' l  \. f( }
                if( addr == 0x0000 ) {: M2 j2 R2 z6 U; F5 X" ^4 k; g
                        BYTE        dummy = n106.Read( addr );
# E# V( q7 z5 K  Q4 B/ `, @7 @) Q                } else {  i8 e/ g! @# A# H8 U2 }
                        n106.Write( addr, data );& n" s+ U1 `5 w, l7 ^
                }- T4 w' |8 l9 L
        }
; U" r5 _$ y! n' I7 r, t, G        if( exsound_select & 0x20 ) {
3 w6 e+ I' r. |  }- U) E6 ^! L. W7 ]                fme7.Write( addr, data );& ~: o) r  i' c6 j# X/ g
        }
3 I$ q, q' g5 `}
! X+ P: M# H. f5 s3 N, u7 r! X" ]
- y' @: i) L0 o6 M8 [& Xvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
# k/ |, M/ P7 m) T{" g4 O/ T* s" Y( q
INT        nBits = Config.sound.nBits;
$ A+ c9 d1 F& J0 F# a/ nDWORD        dwLength = dwSize / (nBits/8);, U) }" [3 U6 Y! H- f
INT        output;
  c$ s  p3 t0 n) v8 H7 eQUEUEDATA q;; u, X/ F; |4 d- c9 w5 V9 Z
DWORD        writetime;
, f! Y' W7 c- ~( }( @0 S7 Q+ Y2 @) \) q4 R& C9 e
LPSHORT        pSoundBuf = m_SoundBuffer;
( D; c. }' J% Q+ H. p  uINT        nCcount = 0;4 |+ i* E: P3 i9 j- Y- B4 J
; I! `8 ~0 z# f" h( j$ F% I
INT        nFilterType = Config.sound.nFilterType;
. `; j# ~$ m, y2 n+ x3 H' A! w8 O) U) O# ~3 t
        if( !Config.sound.bEnable ) {! F) F+ l# M$ T  e8 N& {  l6 z, q
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );: t( y& t3 Z! r: p8 I
                return;* y3 g: c( R# Q" {# J
        }
$ ~# E- i: Q8 x6 j3 b: [7 b% P/ Y2 R! Q
        // Volume setup
1 @4 Z* r$ ?1 G* Z0 L8 }# K) L7 S        //  0:Master% I; Y) W0 P! t! e' \  r% t
        //  1:Rectangle 1
+ K5 \! j- v, g' J0 Z3 H        //  2:Rectangle 2
, s4 c. |/ c) g; L- X. H4 r, w        //  3:Triangle4 y# l3 y7 U5 D5 v' h
        //  4:Noise
3 e' u1 B& Y; n5 l! t" N# L3 C( I        //  5:DPCM
0 `. z6 |6 E1 s( L1 s        //  6:VRC6
* e$ w' m- N. L( P- |        //  7:VRC7  h6 y3 p6 l5 S+ z* q
        //  8:FDS
2 i0 g6 r  K1 [( n+ D        //  9:MMC5
0 z# D$ G& c) [) D8 _& j        // 10:N106' u- @' \2 A* G
        // 11:FME70 [% T3 p# w' F) C7 }2 w
        INT        vol[24];
( ~6 Q  z  s3 O        BOOL*        bMute = m_bMute;% N# E1 K( ]1 J. q; r! t
        SHORT*        nVolume = Config.sound.nVolume;
1 n0 w% L! X1 A" i3 x
: A6 a$ z; k0 j3 V, {2 m1 u        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
& y5 D( L1 d/ q) ^
* g8 B1 l' a) o. H        // Internal8 X& K$ n1 f0 B1 a! y- d
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;1 y4 y; _1 b/ h
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
9 o3 u2 W& j, I/ w( b        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
+ v) c3 }1 H( m        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
& U# g) k6 W9 j) m3 [  @( P        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;4 j  o; r. L6 V0 _7 T7 I' J

( D1 V; \& P4 z: k; @. i        // VRC68 z+ `+ c) x, q. I/ h
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
' E) A4 M$ F; K6 {; l* X& u        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;( r) o; @0 \7 y& S  h
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
8 U$ X3 Q8 b. d4 `" F2 i/ I& {# {, ^& K, O* C" W+ }6 \. `8 A, R
        // VRC7
) T: K5 Y4 D) Q        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
7 i; h$ c3 {# y% b3 F! w! L1 h3 ~/ l/ d6 |( b" |3 d
        // FDS
, {% s- `% b" L- t        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
' R4 Z4 P, m% }! @3 p3 A  C; f* p3 J4 G
        // MMC5
8 Y, k7 S/ C: x, c' R        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
& J' C$ ~/ U3 c( e        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;% t; W! V% n1 j+ h$ s' O
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
* m( l. \2 I) P
" h9 A! p9 i& I1 _9 ]* Q        // N106/ N% d: U- f' [0 w& Q
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;" U: @/ ~: t% e
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ N( g$ U! ]2 J4 U! U. u
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 r/ S2 |7 D1 n) v$ G( h        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;* R/ H+ s/ i; Z) j% R( z9 I
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
/ N* j  ?5 u) n7 i; G9 |8 w* p$ l        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;" j! U, c& ~( P
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
5 [* ?) w, w' W( k# r        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;  i% s/ Q2 o# |9 f) Y. |3 [" P
) e0 k+ c# g3 Q' k# k
        // FME7
  a, ?3 d! f9 ~6 i8 b' s; |6 E$ K' Z        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;5 W, R8 t  ^6 A5 D& D  N0 f
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;, J$ C* y$ _( `) Q' O1 Q
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
! x( d6 S2 s- \' t$ ]" A
' A; }0 r$ K0 T! F# i//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;# Q. D3 B) @4 S2 l
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
, Y. Y+ O7 ~' j. M
' l$ U$ d" ]( }4 _        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟3 w! Y5 N( W4 t" K! o5 l
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
( q: F* I6 V+ Y. B4 r                QueueFlush();
% o+ X: c& W2 ^8 G8 B$ }! k        }
* S/ @  F! b# b) e$ ?/ r( ]0 z) X/ [; I. ]3 }
        while( dwLength-- ) {* M3 O; x4 k4 G" E# p/ s6 g& \
                writetime = (DWORD)elapsed_time;
0 C* m+ s# d) k* x6 D; k8 c4 U# d+ w; X
                while( GetQueue( writetime, q ) ) {6 @6 K) K: \9 G% ~+ b1 w
                        WriteProcess( q.addr, q.data );# {# x. j; t) k9 e5 p$ A3 b& ~
                }0 d5 d% u0 c) d  P

% e$ j3 ~; V# w6 m0 ~                while( GetExQueue( writetime, q ) ) {
- k. [. T' b: A- `7 ]; u                        WriteExProcess( q.addr, q.data );; o. L  I2 A1 B% Z7 t4 G
                }
' |6 ^( B$ B  i0 a) ~" n7 e1 A, y( J
& O9 v& L8 E, j0 B$ i& `, H  I; d: ~                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7- ]' d8 B/ X; j8 F" x: s+ q
                output = 0;* W, f, w3 z% L+ b+ ^
                output += internal.Process( 0 )*vol[0];* J% M+ r  x# ?
                output += internal.Process( 1 )*vol[1];1 ]2 g7 w# G2 K0 }
                output += internal.Process( 2 )*vol[2];% ]' ]3 f) e; G9 q; G8 W; W1 C/ b
                output += internal.Process( 3 )*vol[3];3 `$ ~0 O+ B; I! F" o9 Y& J
                output += internal.Process( 4 )*vol[4];* h/ g- s, n5 Q
3 S- X& r7 |$ X+ L! I5 R* P
                if( exsound_select & 0x01 ) {: ]& F# k2 Q, T$ j
                        output += vrc6.Process( 0 )*vol[5];. I1 B$ T) \% b# P
                        output += vrc6.Process( 1 )*vol[6];
/ F+ ^" t, U& r4 N4 e& ^                        output += vrc6.Process( 2 )*vol[7];+ }% i' A+ D  O( V% F, {
                }* v( [9 J: V- {4 c) F* X
                if( exsound_select & 0x02 ) {
, k8 _$ O! l: r$ w  s                        output += vrc7.Process( 0 )*vol[8];( g8 K0 @( r8 |2 s& r' @
                }* m: {% \3 g9 l! F! l9 K+ u
                if( exsound_select & 0x04 ) {' X- S- Q/ z2 x5 g
                        output += fds.Process( 0 )*vol[9];3 Q+ M3 _/ O5 O5 n: c: Y7 y  D
                }# }  p$ R( A- L9 N
                if( exsound_select & 0x08 ) {- t# |! I7 k& {& Z8 g1 Z+ a  b3 |
                        output += mmc5.Process( 0 )*vol[10];9 e. O8 P' J' t( m( D8 P* ?
                        output += mmc5.Process( 1 )*vol[11];9 }( ]3 U; i  {0 q: z
                        output += mmc5.Process( 2 )*vol[12];
, W* n6 Y. F: A1 _4 G4 B9 |: f                }, z' b1 j0 X8 I: K* Q* ^. E( s
                if( exsound_select & 0x10 ) {1 s  o' |0 ^" ^3 ~; G8 H
                        output += n106.Process( 0 )*vol[13];1 T5 i! c5 M) `* G
                        output += n106.Process( 1 )*vol[14];
2 e: L" y, m) V9 b8 z                        output += n106.Process( 2 )*vol[15];
( N  E# J4 ^) I4 Q' U                        output += n106.Process( 3 )*vol[16];# |: {6 d* Q. O& I1 `$ q
                        output += n106.Process( 4 )*vol[17];4 h; K4 e' I' p6 u; o! c, ^5 e5 }8 i
                        output += n106.Process( 5 )*vol[18];
5 [% T, u7 d/ w4 x; H3 G6 s9 ?( e                        output += n106.Process( 6 )*vol[19];
( E, _0 q. i% W) y                        output += n106.Process( 7 )*vol[20];
  o# f; \* i& W) {% [, s                }
# e4 F6 }, P% K  ]                if( exsound_select & 0x20 ) {
1 X5 h2 p* j; ]                        fme7.Process( 3 );        // Envelope & Noise
$ b0 r, S" G. u9 G; M9 F* c0 X                        output += fme7.Process( 0 )*vol[21];3 Z' [' E1 n- h1 h2 ~
                        output += fme7.Process( 1 )*vol[22];2 x" B6 f& v) N( C
                        output += fme7.Process( 2 )*vol[23];2 T3 I, _: W3 I% \/ v
                }
  K; u9 U7 |2 a9 F' x6 P
- x/ J* z8 E2 Y) y2 a                output >>= 8;
4 S  x& A' \  P* t/ I' T& S0 Z9 O' b5 M" o" T
                if( nFilterType == 1 ) {
+ G9 E& T( y$ @* t/ x                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)6 k; z2 [2 A6 i% M
                        output = (lowpass_filter[0]+output)/2;
5 Q6 O* E2 C) w- M- Z                        lowpass_filter[0] = output;6 `; ~# j! w& x+ S) R$ W
                } else if( nFilterType == 2 ) {( P0 a& l& r4 Y! }
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)' @, O% F0 }# h( l
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
* b& b; R0 W7 V                        lowpass_filter[1] = lowpass_filter[0];
/ Q! `' Y# {. C3 a                        lowpass_filter[0] = output;" {8 K3 x2 l( b& O+ P( ?, d* d4 X
                } else if( nFilterType == 3 ) {
, L2 r' e5 ]! v1 S                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
. E8 [, K! ]% I: J& Y' ?+ ]% O# b3 K0 ?                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
7 L+ D. u( R2 N& t6 `                        lowpass_filter[2] = lowpass_filter[1];9 t- d; w# g- Q- k, M1 I0 r
                        lowpass_filter[1] = lowpass_filter[0];
- ]7 R1 J: a" ~' Y8 c2 |3 v- V! ]/ ^                        lowpass_filter[0] = output;4 ^/ z3 L! d$ r* A
                } else if( nFilterType == 4 ) {
" W& y0 z5 y' }! M% |                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)% `) |" a) m: d- y3 E/ g3 o
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;' U# Z% k* k  z" S) t: A
                        lowpass_filter[1] = lowpass_filter[0];
3 g, s* u; [$ K+ W                        lowpass_filter[0] = output;# h& ]- o+ I/ z/ J1 u5 d: @8 H
                }* o. [$ f( K1 V% q4 {

4 c( j* c4 ]% y9 J" _#if        0
* h8 X9 A5 C/ V: j* H                // DC惉暘偺僇僢僩
" o! w0 l4 M' z3 R  Z1 m4 x                {
$ }8 F6 H' D7 f                static double ave = 0.0, max=0.0, min=0.0;
) ?) @) T5 d% _. Q                double delta;
. g- R+ |' C# u. w8 e7 X                delta = (max-min)/32768.0;  K9 h- e( j9 T& X: ]
                max -= delta;3 E% D/ s7 U- x& [
                min += delta;
6 y$ ~# l6 n# a/ o- |+ k! O+ N: W& g                if( output > max ) max = output;
0 L  K4 r! ?+ X( O/ h) L  Z0 C' d+ u                if( output < min ) min = output;5 N- \: x5 |$ r9 z3 O, _) K7 K( L
                ave -= ave/1024.0;
) _; }+ T/ T% \# J/ g) r                ave += (max+min)/2048.0;
. s8 ]- k. R) a2 K                output -= (INT)ave;
; V) e! G" d1 w( T) M                }
- D1 ]. _6 [  ^9 ?- I0 Z" t" M#endif' x5 Y$ {# y" x4 I7 X
#if        1
( b7 p* A7 l5 ~7 w; S7 F* L                // DC惉暘偺僇僢僩(HPF TEST)
/ Z, K+ o9 m7 u* @                {
8 o" Y$ m- ?$ K, a8 g" O! h//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);5 p6 ?( _, H3 i3 I0 c
                static        double        cutofftemp = (2.0*3.141592653579*40.0);! U6 K9 J% R4 v2 V9 I6 B# k0 W( {( [
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
& G( D% H0 I1 Z# Y0 @$ s                static        double        tmp = 0.0;% }, @" m5 Z/ F" ?4 T& @
                double        in, out;
( J; e% m% ?. D* E( J$ ~% D1 u
* S5 }# k/ f1 n7 _1 ^                in = (double)output;% r, i5 B2 V8 B
                out = (in - tmp);  ]% c1 F- }- A8 d6 }+ u$ R  I
                tmp = tmp + cutoff * out;. E1 o2 _6 x4 X( n2 D

, X  P% Y3 a! L, ]                output = (INT)out;7 |$ k- v9 h" X; h7 u. Z# ~
                }! v6 E7 F" M# B3 r9 F& w
#endif7 l- L" a: S  V
#if        02 a, a4 n/ d$ f& u3 }% \
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
" V" @! p  q5 G0 h5 b$ P+ w                {
, ]) o  Y, z' ?8 M4 [                INT        diff = abs(output-last_data);; u# [5 K6 g. }; I9 H2 r
                if( diff > 0x4000 ) {
+ E8 L) ^. A4 x4 ~1 ^# t                        output /= 4;
; F5 {/ d0 T$ Y. J* O& x                } else
6 c: A. s5 C, Z4 m                if( diff > 0x3000 ) {2 K" v  U3 x+ q& H9 n- L
                        output /= 3;
/ ~  m% o7 u; p: S" ], Y5 j                } else- O: J" }; |( p# C
                if( diff > 0x2000 ) {
. e/ M1 }4 q$ {* `                        output /= 2;
2 m. e7 ~8 V' j4 z  ^% `                }
5 E  m8 A7 j2 N2 t5 ?5 n                last_data = output;
1 f4 E. U8 C/ W0 X                }" Y7 c2 B8 R; _
#endif
* }( X# |. F- {5 H; M- X7 f! ?" G                // Limit5 c0 s- x' y4 v
                if( output > 0x7FFF ) {
) b+ P2 L7 T* K+ P1 ~% n                        output = 0x7FFF;
8 }2 ?' b$ h% l* r* W                } else if( output < -0x8000 ) {% y8 I8 E  e) z  @9 }8 a, ]" E
                        output = -0x8000;0 {# p/ h# a4 i7 e5 w, c- n
                }" Q2 u/ D3 k& l  ]( N+ p
$ T; B" W4 n: ~& E
                if( nBits != 8 ) {& K: L/ [+ C6 ~' D: X. j
                        *(SHORT*)lpBuffer = (SHORT)output;
, n- ^8 Z+ R& L% p9 g                        lpBuffer += sizeof(SHORT);
# L' O4 p  H( G. h2 d) R! L, a$ [. Y                } else {
  w* k& l8 b3 Y1 N                        *lpBuffer++ = (output>>8)^0x80;' u- X0 O9 d5 _  s  J
                }: S1 m& L5 \& ^' G1 {
" i. V! Z( T- @2 L+ H( j( h
                if( nCcount < 0x0100 )
* J  h- q" c7 t- V                        pSoundBuf[nCcount++] = (SHORT)output;
3 z# [; ~' }2 U  F
1 h2 e9 A( [$ O- v# F) c3 T//                elapsedtime += cycle_rate;
7 H1 {' y9 {' V# `+ u6 y. G, F+ V                elapsed_time += cycle_rate;
5 N" T& f1 \+ f& a" ]# T4 e- F        }, c6 I) t. \: B: J) G" z/ y
4 w0 R5 _  o1 v+ |: d2 g  t
#if        16 |$ T* l! x9 o0 Z: J: k& u
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {/ h5 u. H% ~" j0 I
                elapsed_time = nes->cpu->GetTotalCycles();: ?6 p' a+ i2 c( p' ~+ O
        }) p9 Q  O/ S) ~* h* u0 y9 ]
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
0 L) X: B8 ^4 |3 h4 J                elapsed_time = nes->cpu->GetTotalCycles();
/ P7 q% m+ x9 o" D9 ^        }: i* s6 z' o7 c: E# ?
#else
$ @' O6 m5 c* _- L( m- i  j  [        elapsed_time = nes->cpu->GetTotalCycles();
, I- A- [  L3 @: r; m1 o#endif+ ~9 K8 [7 z: Y- z
}1 e" U6 A( `) v

& Y" G( B1 \$ m# F8 `// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
6 w! t4 |. i& `) N( [+ eINT        APU::GetChannelFrequency( INT no )
% K9 S" u) J# U" X1 C: V2 u{
* L; C6 _0 v4 h) n- M" c        if( !m_bMute[0] ), ~! F$ Q- [; ^- h
                return        0;
- s9 }# f, p8 V+ I7 [$ j! d3 W7 j# j; h
        // Internal1 ]8 m* `  m( k9 t
        if( no < 5 ) {
8 G- Z2 N' e! d; O                return        m_bMute[no+1]?internal.GetFreq( no ):0;3 e4 v, C% q  A+ X5 N
        }
6 {5 U5 a0 r# _. Z" l9 E        // VRC60 B* I; G+ y% v  V6 E# m3 y
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {3 L3 a) ]; N( w
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
- Y* P9 _1 E+ K' ]        }7 ?- o3 i- H/ s4 L# e1 I5 ^7 [
        // FDS
( Y* }8 R' t1 `        if( (exsound_select & 0x04) && no == 0x300 ) {
7 D- E0 x6 w) W$ j" K5 y                return        m_bMute[6]?fds.GetFreq( 0 ):0;* Z3 C6 m% P, [, \! T2 @
        }) M, h6 i$ j0 X# Q" g4 j
        // MMC5
! ]0 Y0 v) X/ |5 O$ p2 F7 ]        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {6 I. w- j4 o$ Z3 X+ C$ N* b4 I( J" ^
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
9 b: e! c7 ]6 {$ w        }
! y$ I# C/ X8 N1 E$ S        // N106
% }/ e6 m% i6 {1 e) |" V        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {3 Z7 m# {6 Q. i5 X; d& O
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
0 u  E1 [' P; k: ^$ L8 A        }
! Y7 j& ]+ u9 I2 k3 N8 N4 }; v        // FME7# w1 H4 |: Z) J  M0 y
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
. B, B; L) J4 f6 P1 X) X, Q$ ^, q5 L- W                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;+ x8 L7 F  F/ B6 a; G
        }) `" v0 s0 h9 p& {/ P/ ?
        // VRC7
+ c$ e. b$ L( ^& M0 y        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
8 H: L% ?! W* W9 t6 Q                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;! K5 p1 u8 U0 v2 l0 M+ V5 D5 g" o
        }
+ z+ k0 J, C% ?$ n/ M        return        0;/ K2 K" L8 `3 l7 f3 N6 E& F3 A& o
}
+ a9 C1 u( x* \( o4 W- W$ ^( f! _2 [
) E+ b; y5 G2 F+ K6 l8 h, g// State Save/Load
- y8 z& s4 F! X; P0 a5 o3 Wvoid        APU::SaveState( LPBYTE p )
  F. u6 j: N  t{
9 s  e6 j) A% I5 s#ifdef        _DEBUG
' E: k3 a. S0 OLPBYTE        pold = p;
9 t3 W* a1 X" x#endif' ]& B* I# u( m0 }1 p8 k4 b( Z, \
+ h3 w! x3 i* ^7 w
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
# ]/ T8 ^- J3 p3 J        QueueFlush();
# K4 Z/ S& s& k$ r
4 v6 f" |( w0 C" F% X& z8 v        internal.SaveState( p );
- t. u* C. d6 u7 T        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
0 I( F8 |, h" L2 @6 k9 v/ L5 L. W$ i/ v9 h* ?' |
        // VRC68 L$ h  n6 q7 F
        if( exsound_select & 0x01 ) {- b. U& O. m- P) o+ t# c3 k
                vrc6.SaveState( p );
) T$ d+ P5 ]7 l8 P7 O  R                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding' Q3 ^. U# B$ H
        }
" ~! r  h+ v, K# J6 E. n        // VRC7 (not support)
6 R  C, w: O, B/ t- P5 Q        if( exsound_select & 0x02 ) {( k8 q" }3 x# ?. T, h
                vrc7.SaveState( p );. W2 z5 a) W) f. H
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding2 {4 V/ @* y5 X2 I( l/ H( Q: q
        }
* o: A; t; p  k: l        // FDS
& |# N; I! j5 [/ ?. B        if( exsound_select & 0x04 ) {9 W( J8 ]! \7 Z8 b5 }7 x1 V
                fds.SaveState( p );
% J% V# F/ P- [) _& d                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding; I1 ~9 M, T% z$ c
        }: h8 b/ R: u# l/ |
        // MMC56 s8 v5 ^6 U1 x
        if( exsound_select & 0x08 ) {& J6 G8 s; L, r9 f/ t
                mmc5.SaveState( p );2 c; S) ~& D# I5 n: V3 ~
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding& s$ N2 |% I% b" i7 s8 s
        }& L6 A4 h3 m& p( p1 j- U
        // N106
3 `3 R/ y6 K6 K& m3 O        if( exsound_select & 0x10 ) {
: L( R. l2 s0 e4 I                n106.SaveState( p );
8 ]- g7 B3 ?* x, M! p4 q: Q                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
4 L4 Q- l1 ~% ~/ x. b% d8 T3 m        }
- L* Y$ z3 f: N7 m# [% E  Q- S/ M& H6 T        // FME7
5 c& w, P' D4 k/ s' ~+ {+ Y0 \        if( exsound_select & 0x20 ) {. l: X$ h5 a0 S- f' x: y
                fme7.SaveState( p );( B: e% _- |4 I+ J7 z
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding% P$ M$ R% G! T$ B; _! s# q
        }
( N- f( i" A* r6 p- ]" [6 M7 T+ G* C. O6 ?; h0 s( S2 m( a; U) @
#ifdef        _DEBUG" w# H3 a& ~% Q  ?* O
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );" [: J+ X+ ?& h% P+ v
#endif+ ^" z5 x. y; S  y; T( Q
}
+ N4 J  x7 W& @/ V6 X
  e( S( c7 K4 `( n) w$ Avoid        APU::LoadState( LPBYTE p )
2 y$ n+ G# X& i/ Y{
6 D) W3 T& b8 E" n( F5 X( q        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
- I2 h4 o  @8 T  \" I) f& x        QueueClear();
& ~2 k( K* ^4 W) e% [, S' k- E
+ S- U8 [$ t: d' ]        internal.LoadState( p );/ u. G  q4 a  r. }* b/ [$ g
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
7 w$ E! @' _/ p4 l) N6 U- ?  u, J  E: m; t% |) w/ W
        // VRC6
' I7 h5 H9 K3 J6 n/ |9 K9 q        if( exsound_select & 0x01 ) {$ f) w: v0 |5 ?+ C1 c/ ?/ Q
                vrc6.LoadState( p );) {  e' I- `+ [$ a, O$ `: t& Q
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding% J7 @) |  T  l2 C0 p
        }
6 g- \/ }& [" Y$ s6 a6 a        // VRC7 (not support)
* r/ y' O3 d; N3 ]. h7 ~, J        if( exsound_select & 0x02 ) {2 |4 o' F, k* q( Z
                vrc7.LoadState( p );( s: |3 |, d4 _# i% t0 d: S
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding/ |! O  v+ f: p3 ^- f
        }1 f2 v3 w6 x3 o
        // FDS
6 |% o0 A& j; S5 f8 }1 o& H2 C; A3 Y        if( exsound_select & 0x04 ) {
# b, V* V7 x: A( R4 _                fds.LoadState( p );: F7 j) G7 {# U( z. X# C
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
% m! q$ R9 E% i, m        }
- u& V; i, q, u  N' _3 g        // MMC5( r5 _  V5 N* \  C9 S3 G6 @( U1 Z8 W
        if( exsound_select & 0x08 ) {
/ Q5 a8 K- J$ k6 P/ I/ `                mmc5.LoadState( p );( {; T9 H/ {, u# K
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding# X! L6 f' R! v5 f5 m- S% V! h' @
        }
, V( c6 h* K* g1 D! ^        // N106
- G0 R8 I+ |* N3 ^/ i/ B% p        if( exsound_select & 0x10 ) {
* Q' p/ t7 W  U2 H9 |                n106.LoadState( p );
, X$ g) J$ G7 A5 y; Y                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
" G$ v3 S) l$ b6 n! i% K9 R        }
  d- ^+ T$ D/ b4 a+ A7 y        // FME7
# L4 a: y4 X+ C8 K        if( exsound_select & 0x20 ) {
" N- D9 F1 p. l                fme7.LoadState( p );
# l" Y5 X5 {$ U# a9 Y                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding( V, a% b- Y. {8 U" X# B: J7 r% V% E
        }2 c) L: U7 @  N4 b$ o- N
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
, X: d2 r" A: D2 {# G! D' A可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。( C& v9 T# w% N! J- c
感激不尽~~
5 Q% F1 F4 Z# x/ t8 ]8 l* J3 F# m
恩 我對模擬器不是很有研究,# o  n& T0 G  H
雖然要了解源碼內容,可能不是很困難,
3 [" t4 S  @# x( G' _8 O9 Y8 p# U9 J8 u不過還是要花時間,個人目前蠻忙碌的。
4 y! R& P7 Y2 R2 @
6 G# J, p3 `2 v8 q給你一個朋友的MSN,你可以跟他討論看看,
1 a2 v, n; F4 [0 x, a' n$ O他本身是程式設計師,也對FC模擬器很有興趣。1 X# ^. |5 f4 W' O, x
. N& s4 z: b$ m  X2 b
MSN我就PM到你的信箱了。* S: H. o% A$ p8 ]% }" t

: _1 M" Z; a) R, Y/ T2 W" z8 _希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
$ }5 ^* P9 R- g9 _; k5 i* K( d呵…… 谢过团长大人~~
# G+ D) x. C7 }6 W/ I9 O, H2 B
) E0 v2 E' g& p
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
# Y- A0 f) J' c# J: |团长的朋友都是神,那团长就是神的boss。
; F8 s2 x% m# B* z2 @7 q4 U9 n
哈 不敢當,我只是個平凡人,
0 w( A1 n" ~! ^要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
6 |" |& [6 A, b( h+ W; m) dZYH" m) N& S+ D) X) r8 t
QQ:414734306
/ n  T2 m: g. Y3 M% N0 JMail:zyh-01@126.com
  h8 ]  G2 Q4 Y# [! X/ t
9 O' `0 L! g9 D3 K% U他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
  f; O/ }& @. w2 N+ W3 E再次对团长大人和悠悠哥的无私帮助表示感谢~~

" x5 o0 q) E, M- [2 I1 W7 ?- I不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-12-19 12:07 , Processed in 1.093750 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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