EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?- O+ x9 @1 i. P, z# E- N: \% G
PS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。4 c) y8 ^7 H; Q! c& i: T8 e
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
! n/ @- E6 B, E/ t* i这里有相应的模拟器源码,就当送给大侠了~~
: I! n( i# s, o$ M$ w% Zhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 2 n0 g* {# j( p" n1 y$ ]
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
% Q# W0 g8 j% e: S) M楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~  @. _' }( M3 j: D! E
这里有相应的模拟器源码,就当送给大侠 ...

* S3 V% k' Q. K7 l聲音部分(Audoi Process Unit = APU):+ I; d/ G6 T. K- Z
.\NES\APU.cpp
$ e( z& L# S$ t1 Z.\NES\APU.h
' G! D! @( E7 u" V2 n  e
4 ~/ j! d8 v8 \2 d, W3 X* ~/ `5 ?' b1 U
" R& r5 Z" }& n1 n影像處理部份(Picture Processing Unit = PPU):% J1 h3 }# M( f3 w
.\NES\PPU.cpp
$ v; M0 I% d( t5 D$ [% ]/ I( ?6 G; J.\NES\PPU.h
; W( K9 |+ r  z/ k8 U) \9 p; M' Y$ O, n
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:+ m- a& B5 N( W# \& w. ?
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
# J, h1 [8 D& P, ?7 E! c0 T//////////////////////////////////////////////////////////////////////////' ?7 Y$ L. v# p: |1 n
//                                                                      //
7 x: C4 u) m( Q; a. y- A1 b//      NES APU core                                                    //: `1 b; L$ F$ \& h( E
//                                                           Norix      //$ @. F. c# g% F8 S4 {
//                                               written     2002/06/27 //
2 {0 Q) t9 t- [+ z# C, ]//                                               last modify ----/--/-- /// [, D8 R5 A4 |" m& H# R: m9 y% Y" I: c5 W
//////////////////////////////////////////////////////////////////////////
" {- P* B1 m5 n# e& L% T#include "DebugOut.h"  o5 b7 I3 D. @  A# g
#include "App.h"
) M' y' r1 }! z#include "Config.h"- g' J5 m5 h+ X9 }2 m' w

+ R  U& w5 O: k0 M#include "nes.h"
! V4 w9 M" J! E# _; Q' N#include "mmu.h"
* J' v8 i% t# Z! {#include "cpu.h"
/ M1 Z* x- Z# w3 F, l1 R#include "ppu.h"
- {$ d# y" h) _2 x2 p#include "rom.h"
$ @$ p- `% t# U#include "apu.h"9 T! V4 z1 w- e9 b

; L# x, e9 e6 R+ E// Volume adjust( g! K) x2 \4 h8 [- Z
// Internal sounds# t1 o& J( r# t% l6 R9 [
#define        RECTANGLE_VOL        (0x0F0)
5 Z& x# w* v# R% Z#define        TRIANGLE_VOL        (0x130)3 P8 j0 c: a& I7 y; ?. z9 ?
#define        NOISE_VOL        (0x0C0)
0 K  r+ h  y9 ^% C#define        DPCM_VOL        (0x0F0)
" h  x! B/ K. w0 @3 H! Z// Extra sounds2 n) b5 d! D* V( |2 h
#define        VRC6_VOL        (0x0F0)
+ _0 v' B  a# ~4 A% O#define        VRC7_VOL        (0x130)5 w  O8 l7 {1 x1 h$ t( l2 k
#define        FDS_VOL                (0x0F0)0 b+ i0 r/ B' j  a5 b
#define        MMC5_VOL        (0x0F0)
1 K' U' E+ O1 z+ r6 ?6 ?#define        N106_VOL        (0x088)7 @) Z( O4 [6 H# v$ W
#define        FME7_VOL        (0x130)2 J  U8 }2 R$ n# \# G! D

1 n& G6 e: {+ x0 _5 t( KAPU::APU( NES* parent )6 Y2 {; y& n3 I( i) S' H
{0 S5 O, \3 N! X! H6 b
        exsound_select = 0;
0 e) n8 f" h8 G# o. b- J6 z0 J# {8 G! L( z" y) q1 x
        nes = parent;3 n3 m( D& E) ^+ m" U8 o% T; |5 x
        internal.SetParent( parent );
0 t3 c3 I; _6 @4 F' l9 K) v4 A0 ~" x* Y
        last_data = last_diff = 0;: D$ b4 t' X1 T0 E) V
" [  K: W# {4 H0 k& I2 p! i
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
# n5 |( v7 D/ V. a" a1 `7 P. n, l1 c
* `8 L; r) M9 O0 j) o5 K        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
3 c! r  M( @7 D7 H0 }7 K* P        ZEROMEMORY( &queue, sizeof(queue) );. x3 _* ?: B6 [" K6 }
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
  i- F# Y) m9 c& q( L" C& O. p. `! Z# f2 C: P3 G
        for( INT i = 0; i < 16; i++ ) {: A$ w! V1 r9 o2 U
                m_bMute = TRUE;
! `6 C) \; C5 e8 {9 z2 ^  }; Y, e        }
% l( l. ^. P8 K% W* y4 _% N}$ P, K  I" |, Z+ a6 t9 i
( m: b+ t: W, [8 U- ^
APU::~APU()
: ?( ]" Y4 D% S* F$ g4 Z# Q{
& ]- d# s/ b: |8 _1 V}/ b: m5 @: f& f' Q/ f7 m0 |) e  p

! V; y* P/ h1 T: @  A0 Evoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
9 O+ O7 g' k/ V9 @5 o# V9 T( ~{4 X% O* \; `) z* @  Z
        queue.data[queue.wrptr].time = writetime;
: b! f; |$ p* h4 q6 T        queue.data[queue.wrptr].addr = addr;8 W( w+ W0 s* @, W
        queue.data[queue.wrptr].data = data;
' ^1 s) `( f5 G        queue.wrptr++;* ?; r1 O7 t" _; t! V: x  k6 k. F
        queue.wrptr&=QUEUE_LENGTH-1;1 Q  i9 D$ u" }
        if( queue.wrptr == queue.rdptr ) {
3 S8 R; ?- k5 t- {: M, |( I* d) W                DEBUGOUT( "queue overflow.\n" );
4 ~, h0 p4 g' n) V0 U        }
+ D- E$ f) Q- b9 x7 u8 P) n8 v  M}9 r0 z  [$ ]( X; \0 w
+ c' d1 f/ \# u# U
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
: T1 R+ Z  J; P% l{& ]$ N5 d0 ?- C) u
        if( queue.wrptr == queue.rdptr ) {* P+ O2 B! g, Y
                return        FALSE;$ v  i6 n6 l" u  s! k- U8 r) x
        }" K) o  o) Z6 X5 ]: W3 v
        if( queue.data[queue.rdptr].time <= writetime ) {
9 ^+ Y' L6 ^6 _                ret = queue.data[queue.rdptr];
! ^' a7 v, f0 _/ @                queue.rdptr++;
$ a% X2 P6 W$ @6 i+ W, P                queue.rdptr&=QUEUE_LENGTH-1;
( O  j: o4 \/ i9 q" C6 t8 E, p                return        TRUE;
' }$ P0 ~0 b. Q' C: w: [        }" r$ `/ t' C* }. F: g
        return        FALSE;
/ e, k8 R# O1 D; `1 S' U' z$ c}* |1 v9 Z8 w, W  ^

$ I5 m; o" R# b+ zvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
0 r3 i2 `6 c+ j& C% W4 X{3 d6 G7 x% A2 L1 k. O7 [# f6 \( b
        exqueue.data[exqueue.wrptr].time = writetime;
. g. ?( m) r, {, Y        exqueue.data[exqueue.wrptr].addr = addr;. u1 o* C. }% V* ~2 T
        exqueue.data[exqueue.wrptr].data = data;
6 e% D+ j& Q6 \; C5 G# [& M        exqueue.wrptr++;/ \. k" l: K! [  t5 A& h. j
        exqueue.wrptr&=QUEUE_LENGTH-1;
- R2 c) r( H! l5 l5 d8 L5 y        if( exqueue.wrptr == exqueue.rdptr ) {
9 a- I% x) U& N1 I3 ]/ o: ~3 N                DEBUGOUT( "exqueue overflow.\n" );
- i6 h+ v  D0 ], E0 `' \        }
8 G. K2 ^4 p; C2 h- u0 z}( g2 s% W; I8 [7 J. \
2 q: ?* A! v: J7 u( h
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )* f6 b, {% ?, \/ Z
{! P. _. a. u$ N2 ]. z0 w
        if( exqueue.wrptr == exqueue.rdptr ) {
% F7 ]& o- D3 S' R9 ]. B                return        FALSE;0 \8 Z! z8 D$ v0 {$ o
        }/ m6 ~1 ?, k4 l) s, I
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
+ c) n. A6 Z- A" \0 E: Y                ret = exqueue.data[exqueue.rdptr];8 Y& {+ C, q% |6 C/ W
                exqueue.rdptr++;
8 H" a2 y9 D7 s( t; l9 T6 y. a                exqueue.rdptr&=QUEUE_LENGTH-1;  W! m2 r2 M- s* U% X
                return        TRUE;
; E. e7 C' @/ r" A9 C8 J  c/ g        }: A) v% m7 ~/ x
        return        FALSE;
6 f; R2 l( y& ~" f6 O1 D/ D7 u}
- d$ S" i0 M. g! g
; v/ E( F6 P$ `5 ^0 Y) ~void        APU::QueueClear()
" [) x$ u0 o" k9 B( ~8 o; X( f" C{3 b# M" O% {7 O6 X! E
        ZEROMEMORY( &queue, sizeof(queue) );5 @  S" I+ [3 H$ n' _9 G  |
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
8 N( @$ @) ]( Y8 n. Q}; q$ J/ n$ H, W& i
1 I  }  I: e, Q5 j9 Y  l
void        APU::QueueFlush()
) {# e5 ?/ D4 U. R{" t2 v% A! `$ Z& Z
        while( queue.wrptr != queue.rdptr ) {
3 D: u: t9 H8 O; Q/ R                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );$ z) ?& h8 p( _7 f3 b
                queue.rdptr++;
# h, i8 k1 ?9 E% q( C$ g  V                queue.rdptr&=QUEUE_LENGTH-1;' I8 O0 u( J. Y9 j2 A6 a: u4 Q8 U
        }
/ g" a! v0 J: L$ u# I6 q) K) R2 s( z& F+ n
        while( exqueue.wrptr != exqueue.rdptr ) {
1 c( `. ^; w% Y                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );5 Y  z$ T2 Y: c+ \7 z; {8 c
                exqueue.rdptr++;
9 Y+ {; B/ c6 F; ~* z                exqueue.rdptr&=QUEUE_LENGTH-1;  v# v" s% O! ~
        }: ]5 W+ ]( t1 P. f8 x
}
% s; w1 u8 }& u4 B- M) c& `  O% X; V& a& T+ j. v
void        APU::SoundSetup()1 e* @" h7 H' W$ W3 W3 D1 c  Y+ X$ [
{% o0 p, ?, l" p/ i! q( \7 |
        FLOAT        fClock = nes->nescfg->CpuClock;
6 D4 I6 W5 L, k& ^6 n        INT        nRate = (INT)Config.sound.nRate;
' c0 e; M6 I4 Q5 r8 k        internal.Setup( fClock, nRate );
4 y* w1 u2 g2 E* ~8 j4 y* d3 Z        vrc6.Setup( fClock, nRate );
" ^! s& Z, K3 m' K        vrc7.Setup( fClock, nRate );0 _4 X/ m6 v6 {, w/ H( C& A+ I
        mmc5.Setup( fClock, nRate );. o2 E4 D& T9 r3 G; M, u: m
        fds.Setup ( fClock, nRate );+ H, \' o6 t" F" T( j6 i$ G
        n106.Setup( fClock, nRate );
( ^$ c+ x7 r1 O! c: J( }/ E4 ^        fme7.Setup( fClock, nRate );7 c7 ~# s' e; T, g/ O# \/ E  z
}
& f$ g; S* J' A8 v6 f; A% ~7 C/ k
void        APU::Reset()
: G+ o5 K# k, d6 [9 r% ]- W2 c0 v{
; \9 p' m8 M' v1 d% B        ZEROMEMORY( &queue, sizeof(queue) );
: A$ M$ Y# w; T        ZEROMEMORY( &exqueue, sizeof(exqueue) );7 i3 o. x. M2 c0 |4 w) \

2 O4 P% L2 b3 I' ^# [        elapsed_time = 0;
+ m4 w" a4 m- s8 B8 |: U3 Y1 f
" k' L( j1 h" ^) P5 h. z        FLOAT        fClock = nes->nescfg->CpuClock;) ^& j% q, [$ C; q6 E
        INT        nRate = (INT)Config.sound.nRate;+ G! _/ W+ D6 C5 J
        internal.Reset( fClock, nRate );& i7 A3 W. d# Z$ A; b) Q: i
        vrc6.Reset( fClock, nRate );
8 X- v+ E! X$ @2 P, |5 \- C  Q0 e+ N        vrc7.Reset( fClock, nRate );
, c5 ?. o, ]) E2 h1 P        mmc5.Reset( fClock, nRate );) x, |; w# Q) |7 |- y) g
        fds.Reset ( fClock, nRate );1 w2 q: U0 u7 K2 B* }
        n106.Reset( fClock, nRate );- _8 v: ?9 N1 ]( v6 ^, P+ j  Q
        fme7.Reset( fClock, nRate );5 z: w6 Z& B/ l5 ~- B1 B6 M0 \- u) S
6 K9 h, c: |+ I5 p
        SoundSetup();$ G1 v, _# f: r9 I3 f
}7 m0 M6 g% f7 k  h) s6 z5 y

  L9 _2 X9 _/ u& m! jvoid        APU::SelectExSound( BYTE data )8 ]$ H+ U9 }6 ]
{8 ^5 ?/ ^, P% I
        exsound_select = data;0 X, t& s6 H% `' k# D3 X
}
9 N* U* \% n/ d! b( `; R2 f8 M3 S1 U5 o
BYTE        APU::Read( WORD addr )/ {( O+ Q$ G$ A
{; j, r4 _7 |0 \7 \% k9 m0 c4 Y2 W
        return        internal.SyncRead( addr );7 ?0 r1 B+ b" J" U  w! a5 \  z4 Q9 J
}
9 U0 Y+ X' s( n1 R8 e' s! b
1 C* R! Q( }3 |! p6 W; z/ ]; o$ Wvoid        APU::Write( WORD addr, BYTE data )) d' ], O3 q6 D
{
9 _! s' ^9 s! _; |; r* H3 m3 u/ b0 I        // $4018偼VirtuaNES屌桳億乕僩3 X- ^$ u- K3 O6 ?# N
        if( addr >= 0x4000 && addr <= 0x401F ) {- A+ f) l) t7 X0 ^: m, `; X
                internal.SyncWrite( addr, data );, J# f7 o# O" n9 m9 h+ t+ B  z
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );- P6 k% S/ _6 }0 W
        }
0 t( S; S! O4 `5 n& C, _4 l8 L) n}
4 ]0 h9 ]* Q2 U- u4 b" V9 C% @3 I! }( Z7 h! _0 e  H1 e% w
BYTE        APU::ExRead( WORD addr )) U: T5 g! N9 K0 t' c
{* x- V6 M9 h' S# l1 T/ ]3 M
BYTE        data = 0;
% c9 l# q, B8 g1 U! p( ^
2 |. j" m8 R& z: x        if( exsound_select & 0x10 ) {. B$ T$ _& B+ ]" u
                if( addr == 0x4800 ) {6 x( l/ X0 ]7 N' s$ o7 s
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
4 m- Z9 |* H# H# d                }* d' ?4 `5 |2 Y( b$ W: @$ r! m
        }
' o8 Q" x$ j$ f+ e7 H% m" U3 _1 l: y        if( exsound_select & 0x04 ) {
' z. f4 u3 j$ s0 b1 o                if( addr >= 0x4040 && addr < 0x4100 ) {4 Q$ n1 C# d0 y* F! ]+ w5 ^
                        data = fds.SyncRead( addr );
% w3 B1 |& c$ ^) r$ W- l                }9 k, P+ d$ g4 Y; V
        }
1 X4 R8 _+ I+ M! y# n4 T        if( exsound_select & 0x08 ) {' M/ S' G' j2 L7 ?" c
                if( addr >= 0x5000 && addr <= 0x5015 ) {& B" C8 p5 T( y/ M0 q- b% U% q
                        data = mmc5.SyncRead( addr );
+ @6 i( H+ k$ A& o                }* _: X8 A3 V) ~* W
        }; ~' m% i' G4 M& G' Z
! R% Y" x! r( X" V* F& n$ V+ \
        return        data;% e' Q9 [2 F' t, O6 \
}
' M; R' r1 k1 H- N& b4 z5 i7 \9 e) o
void        APU::ExWrite( WORD addr, BYTE data )" t- N2 T. {( b; d% t4 J
{: y4 r  w$ A( |( V: l. T
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );9 |1 j4 a& \: M. a1 H1 V+ h8 L
7 L' {  S6 [; m! c3 L1 _
        if( exsound_select & 0x04 ) {7 C) P7 h* k8 i& |
                if( addr >= 0x4040 && addr < 0x4100 ) {0 p- X  T" R9 E$ J$ d
                        fds.SyncWrite( addr, data );
9 P' \$ L9 b3 C9 r0 W) q6 B                }
, ?$ u) a8 z* }, ~2 z        }, S, ?0 ~: H+ |8 [# z4 E2 E# k3 Z! o5 |

/ D& d& R( `3 l# e) g        if( exsound_select & 0x08 ) {
6 g8 H4 f' X. x                if( addr >= 0x5000 && addr <= 0x5015 ) {
- E& Q1 ~& u4 }, a+ _% }) t                        mmc5.SyncWrite( addr, data );8 B7 S/ U/ u3 S! m
                }4 L9 k1 W' ~0 K' l
        }+ B6 n/ H* o5 W: a3 b
}
3 ~+ O# M2 B1 }" v
/ U8 K2 c9 g# e9 W' bvoid        APU::Sync()% O9 X. M; v/ i
{) z4 I# y! y" C: `
}4 F( H1 S# ^8 ?

; v* a* U. D. `7 xvoid        APU::SyncDPCM( INT cycles )! L( w4 D2 ?8 @+ q+ s4 e& n
{; g' U( s, M0 k* v/ [
        internal.Sync( cycles );7 r3 }. K5 T6 V9 e
3 t2 O5 u7 ~/ O  Z5 ?1 A
        if( exsound_select & 0x04 ) {8 C, O* o. q% b- V/ D; k
                fds.Sync( cycles );
6 d8 _+ w, s! r; I+ x        }7 e" V2 W1 ?8 B) h  i
        if( exsound_select & 0x08 ) {
9 z  {1 g# ]: j' J0 S* U                mmc5.Sync( cycles );/ J0 b: W5 d$ x/ C4 c+ j
        }
4 Q0 o$ z1 O# I}5 L1 k/ u0 y# V/ X  M& g7 `! ]
9 j- P  k3 z/ ?* J3 E# n
void        APU::WriteProcess( WORD addr, BYTE data )% I* ?6 h: m: n/ p' L6 t5 u
{# |; Z) N2 m+ L1 I# j
        // $4018偼VirtuaNES屌桳億乕僩
" P) c3 d1 `4 Q4 Z        if( addr >= 0x4000 && addr <= 0x401F ) {
- k) F( P/ k6 J                internal.Write( addr, data );
" }& f$ P8 {- l1 \! J        }
: m2 u# Q' {$ H) ]' M) @( y" k. T6 U}1 k) D/ j+ \) _$ N

! e  U; A7 T/ v. [* ?. B+ L( Zvoid        APU::WriteExProcess( WORD addr, BYTE data )* K1 t  V8 v. N
{  v. F3 m8 ~9 X& W6 m+ K
        if( exsound_select & 0x01 ) {
) }5 L# O5 ]& Z- \: C! k! O- D- n                vrc6.Write( addr, data );/ Z2 W, K' L0 E* i
        }
2 k7 t* e* _" K% z' l( h" }0 s        if( exsound_select & 0x02 ) {
$ B' V1 E8 D) d, S0 T1 A- |                vrc7.Write( addr, data );
6 u$ W  j: G# x# D( V        }( k4 {" \! L+ a; s5 A
        if( exsound_select & 0x04 ) {
: n5 ^6 A* v4 N: P# X! u2 O                fds.Write( addr, data );# J9 D8 Y$ Q7 t  p
        }
  Y: A5 Y4 H) ]9 _. Q7 |# m: v        if( exsound_select & 0x08 ) {) k2 O" b( f# n. P
                mmc5.Write( addr, data );
8 E0 Y4 f' [; n, M0 E# m( x0 ?; H        }
; K3 o. o0 ?, q, E2 V( |        if( exsound_select & 0x10 ) {
3 E" q7 k6 r6 B$ l7 g( N                if( addr == 0x0000 ) {- }/ r1 q& m* M) c; M8 o. ?
                        BYTE        dummy = n106.Read( addr );
% p, x' m5 j& J! E                } else {  ^7 a" ^! M: K- K1 |# B
                        n106.Write( addr, data );
) S6 P4 i) y& {+ F% K2 R% t                }# }/ J6 q% T6 K8 B; O1 G
        }2 Q) n6 U+ Q- b- p7 G
        if( exsound_select & 0x20 ) {( M. t! X& d% V; H9 S& `
                fme7.Write( addr, data );
/ u. y4 c) t3 |. |1 {        }
- z, A+ h& A. c. {7 t; x- w}! `' t) @2 B8 X
& q1 V6 k3 f2 B9 Y# l: g: ^4 P, j4 b
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
$ _% j; L2 U" w' ^+ U* ]' L{
& K+ t" e! W" _# F  d$ NINT        nBits = Config.sound.nBits;+ n0 U2 I9 |6 a$ o  Q  C3 ?
DWORD        dwLength = dwSize / (nBits/8);
" t. L" p  Q! Z" HINT        output;! D4 W3 b$ i3 b: D; l: [
QUEUEDATA q;
! t& Y5 ^; o9 {0 W* w  ^; qDWORD        writetime;# q5 \. N* k* P; c  C0 k; x

) ]; u$ q$ ~% T& e- yLPSHORT        pSoundBuf = m_SoundBuffer;
/ D& y) R6 D; q) jINT        nCcount = 0;
8 M. S" F" \8 _  N' }5 M% [7 @& f4 N; c& w+ x
INT        nFilterType = Config.sound.nFilterType;
+ X  Q% S* T! v1 r/ Q
) b0 B# z7 i; |        if( !Config.sound.bEnable ) {9 n- `, @" o5 J  u
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
, u  e/ i0 F  ^4 P                return;) Y. J7 r: ?' Z7 `) x' Y3 S
        }
. R4 T* @* q, Z6 H) Q$ r% H4 e1 \8 m$ t
        // Volume setup+ x5 I& f" h2 o! h9 d8 n
        //  0:Master: }- _6 \/ ~) R) g& ^0 z
        //  1:Rectangle 1
. r$ ^( I& z) v  n6 N        //  2:Rectangle 2$ I$ g' A- L5 h/ j
        //  3:Triangle
2 S: D$ I6 i. V; b2 _3 q7 f$ g        //  4:Noise
- H6 z/ D6 v5 Y        //  5:DPCM: t, u" a! F: v2 u. y
        //  6:VRC6
) Q9 v: n) f9 f6 O        //  7:VRC7
& G. R. ], |+ g        //  8:FDS1 J5 e1 Q0 p, Y' p7 a# Z7 [* D* S
        //  9:MMC5) L* R' B' h0 d9 a0 e% S
        // 10:N1065 f$ f* T! x7 ]3 l+ H
        // 11:FME7
; Z9 ?, Q; c* m: m2 y* K' {        INT        vol[24];
5 X" A- E2 H1 x& ]2 H% X        BOOL*        bMute = m_bMute;
, Z$ \5 i' `& V4 p! A6 z" P        SHORT*        nVolume = Config.sound.nVolume;5 ]4 d. X; w; T! r1 l: W7 y

" j, E. `1 }  ~3 t' i8 `        INT        nMasterVolume = bMute[0]?nVolume[0]:0;# U* O/ R5 y) ~' |3 y; L' w$ f6 w

5 ~3 K5 ^/ _  d        // Internal
) a3 e  b8 p1 |  m7 B9 v: L: Q$ S        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
' |2 r' b% \1 C, a1 M! S        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
& D3 @0 v3 ~* M6 z/ K$ Q0 T        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
5 H/ H* P+ K' E, u0 i* q        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
1 n7 j' v# F" l0 _# \" ^4 O        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;% z5 ]5 O, g2 z- _) }2 d
" R! ]3 h  U, N" |& G: e' h7 V  v
        // VRC6
& G. s, P  _8 q$ m5 K/ v+ U        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
8 D! E! T2 [7 @( ?# o# \        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
2 H$ o. H' b8 e, E. x2 _# K/ E        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;" {; i& M) A9 N  [  L. @
2 k  V7 r4 ?2 s: \
        // VRC73 |% w! V$ U+ R8 J( v% ^
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
. m& M* w% \, ?9 C6 {3 Q7 t+ f* f
5 m$ T" k# |+ @        // FDS. _2 {/ r7 w  o/ k5 R5 l/ [9 ]
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
; o* ~# X. F1 A; z! y; Z; s! `) t' b/ z1 n# T1 T& t# W
        // MMC5
& A% F; ~$ S8 U- D7 r0 i        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
) Q3 O/ s7 U- K6 V6 _: u        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
. V1 P/ o% Q" P/ N: I1 u        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;) K8 n* W: I$ e' q/ f# E1 ?- e; a

/ g9 C* a/ Z1 y        // N106
/ A  U) V0 C& V! {! k        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
/ i8 |0 ]( a6 N: h* ^7 R        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
9 I3 r  I) c9 D7 U) s' {9 n        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;: d- g) q# p( [+ z9 Q$ Y
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
1 k3 h0 E& Q" |3 ?% }: |* T        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;! Q3 Z" I- B% f3 s
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
$ ^  y+ o8 u. G/ H2 t2 ?        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;! a9 y$ S; w; E
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
* M& W7 w+ R* g5 I! Y- _2 F: r+ O9 j! k& d( _0 g8 O6 ]" z
        // FME7, z+ }' C2 l& j7 d5 _! Y) P7 m
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;. P6 H. F2 V8 x2 W1 B" {/ V
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;* k. }2 ]$ U1 e7 R
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;0 g$ r0 G- i* W2 Z. J

# f0 t* p# a" M8 c//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;2 |6 n: f: V# ]
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;3 c* i! E4 Y( X& ?* Q# W1 G, [
3 M% |  a) R, w) n% @) @
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
9 D1 i3 a; g% d$ q! H3 i2 ^        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
) b8 m. S1 M" E* T1 Q                QueueFlush();3 w0 H. s0 Z# F
        }
9 p! D3 Q+ M' M# j3 J( \& |! g: k5 j8 Y& W
        while( dwLength-- ) {  F8 l" s$ {) @* r: s* P
                writetime = (DWORD)elapsed_time;
- l) |$ J! |- J# T8 S, }' L3 P
% j; w8 q3 I6 L" m' W8 `  G/ u/ R                while( GetQueue( writetime, q ) ) {) ?/ h% @6 _$ W8 u. y3 v
                        WriteProcess( q.addr, q.data );8 t: u" k* X0 [$ X, l7 `
                }
2 }3 N. x: i* E' V6 P( U9 x0 p3 N/ X+ g- L1 k
                while( GetExQueue( writetime, q ) ) {8 P1 M: }: W/ p6 T* }
                        WriteExProcess( q.addr, q.data );
* @2 k' w# |. O9 o" P' N* P                }
% z( S2 @9 u( |9 Y; D( O/ y6 V/ A4 `2 I  l4 C! w
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
) @  f, v# C/ U, Y7 n" k. s2 g$ h" B0 U                output = 0;
/ P% Q7 z* D- p1 o                output += internal.Process( 0 )*vol[0];
' F; t3 W, _4 W: C% c9 R                output += internal.Process( 1 )*vol[1];* F) N9 l) ^7 a2 W
                output += internal.Process( 2 )*vol[2];1 ^' D8 Z& @  B4 f, \
                output += internal.Process( 3 )*vol[3];
' G; Y1 o# A. H1 r! {0 Y0 Z* z5 _4 y# A                output += internal.Process( 4 )*vol[4];0 n. V7 f" ^/ ]& v

" S" k7 J" b. x* H& ~) ]! t) z5 `                if( exsound_select & 0x01 ) {
& o0 s* |7 A4 Y* b                        output += vrc6.Process( 0 )*vol[5];8 `6 M1 e- S( s& v/ E: \# g3 `5 Q
                        output += vrc6.Process( 1 )*vol[6];5 |$ p, @6 x7 h. s* ^$ U
                        output += vrc6.Process( 2 )*vol[7];
& M$ p" _3 @% T4 M                }
7 b6 K) R, x$ E: S: M$ f                if( exsound_select & 0x02 ) {
- D) ~# S: u6 O( N( `: M, v                        output += vrc7.Process( 0 )*vol[8];
) ?) D# S: n: `  h! I4 s                }
8 b* L6 J: W& e, b5 h3 K8 W                if( exsound_select & 0x04 ) {" A1 U' a* s+ y# S9 ]
                        output += fds.Process( 0 )*vol[9];
5 a/ {, A4 V5 O& M+ A. g7 z                }
. f2 L& g7 k- r+ U6 {                if( exsound_select & 0x08 ) {
3 X2 X; Z" T- u) M# j$ \                        output += mmc5.Process( 0 )*vol[10];7 \' f" f8 C* m% y0 T, }2 Q/ K
                        output += mmc5.Process( 1 )*vol[11];$ F/ D- r8 L5 S6 m% E) L
                        output += mmc5.Process( 2 )*vol[12];
3 _) ]. X( H+ `& f0 f                }3 @) `9 ^0 T+ G, z6 W
                if( exsound_select & 0x10 ) {
+ T, s" S; x4 x$ I8 ]- s                        output += n106.Process( 0 )*vol[13];( A: Y5 ~6 R' H
                        output += n106.Process( 1 )*vol[14];
: Q, W0 m" E& Q6 r! j                        output += n106.Process( 2 )*vol[15];  e" P( s" W3 v4 G. f8 S% k) h
                        output += n106.Process( 3 )*vol[16];
3 L3 O6 l+ O% X                        output += n106.Process( 4 )*vol[17];
4 ?# p. a7 R9 Y5 H8 q                        output += n106.Process( 5 )*vol[18];
" I# U+ a6 \/ H                        output += n106.Process( 6 )*vol[19];
8 T; w1 v& |1 x% H                        output += n106.Process( 7 )*vol[20];& u  u( w) M0 _- ^, M9 v2 o
                }
. S9 A1 N9 z  w+ v7 u' P% h2 H% n3 e                if( exsound_select & 0x20 ) {
/ C9 Z7 N. M" r& p                        fme7.Process( 3 );        // Envelope & Noise$ b$ w9 w; b% |8 ?
                        output += fme7.Process( 0 )*vol[21];, |$ s! p% i  x) n7 @
                        output += fme7.Process( 1 )*vol[22];( }; s& N' _$ r
                        output += fme7.Process( 2 )*vol[23];
# n0 K  Q* k9 d0 O) `+ N# A                }* W# E% `+ A4 t  M
" m. B# r. t8 A4 ?/ A# W
                output >>= 8;+ N0 r! E+ f+ |1 r, d4 o( r

2 B2 j3 C, g, w3 h                if( nFilterType == 1 ) {" ~  C" Q  o' ~# u" {
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)( k9 p8 f: m# [  t
                        output = (lowpass_filter[0]+output)/2;
" d; p( U* Y3 f                        lowpass_filter[0] = output;
0 l+ E- N' e6 m& f, U                } else if( nFilterType == 2 ) {
! @( u+ S$ u8 y/ d% M0 e7 k6 G                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1); w& d9 a. |, n; n3 Z. A6 J' L
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
6 b) R6 g' }/ D, x                        lowpass_filter[1] = lowpass_filter[0];
9 m4 a0 t, q6 M! |( E% u2 z  m                        lowpass_filter[0] = output;
- C4 v% @9 j6 m* l5 u                } else if( nFilterType == 3 ) {' H  o: r) O4 G3 X. V
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
' c; l8 |% h. s                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;* @7 M' _* }: x1 ^$ |7 K7 b; a
                        lowpass_filter[2] = lowpass_filter[1];( M! ^' s9 Z; }/ |9 W
                        lowpass_filter[1] = lowpass_filter[0];
# }, \: K( c+ f! u0 x  ^                        lowpass_filter[0] = output;0 ^4 V9 B* R6 E  d
                } else if( nFilterType == 4 ) {
8 r$ N8 X3 S9 l) b" b3 _- I                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
' C) Y& I+ r5 v: H                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;2 @/ }, J. V. E* Z+ o. t
                        lowpass_filter[1] = lowpass_filter[0];
3 K, X$ `& W9 v/ a                        lowpass_filter[0] = output;
+ u1 K+ C: v, C' a$ ~3 t                }
* Q- |+ T5 o" ]+ |* k" \( a& h5 v) L1 G6 M
#if        02 O6 [$ W8 z) r, z4 ^0 o& @* ^
                // DC惉暘偺僇僢僩
* W+ n" n4 E: {0 c/ ?                {
9 ?2 J( A$ V+ E                static double ave = 0.0, max=0.0, min=0.0;+ T0 Q# M6 b2 n
                double delta;( z) r% R1 K& e
                delta = (max-min)/32768.0;0 q$ U" D, j! [$ }& g1 U; L
                max -= delta;
! L7 a( z7 ~* [( t9 R: H                min += delta;
! x3 f+ Q) Q; |; r/ i  e' L                if( output > max ) max = output;
  ?; B  j7 T3 F                if( output < min ) min = output;0 a' [4 ^' p4 q7 O4 l
                ave -= ave/1024.0;
! s4 Q$ E6 \9 G8 f1 r$ L2 W- ~  d5 U; [                ave += (max+min)/2048.0;
$ O# G  S( }8 N3 Z- M' K2 }                output -= (INT)ave;9 `4 b. f9 J$ |
                }
, f( s! N! s5 B, ^& I; P/ {* Q#endif. }- j6 D) D- B, {6 t
#if        1& \! i1 Z% d3 u) d2 t
                // DC惉暘偺僇僢僩(HPF TEST)9 K) r* ]* R+ H4 T5 K% O4 c
                {2 ~% q' L7 ~. I9 \
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
# g4 R' W2 U: ]  t+ P                static        double        cutofftemp = (2.0*3.141592653579*40.0);. |; G& y2 P. d9 q9 K# n
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
' B. H% S5 U4 D& I+ z& Z9 w                static        double        tmp = 0.0;
# B# i! w# U7 S6 e: O                double        in, out;% \2 h2 \- O; D! |3 a: ?$ N

- s5 Z! ]; N: X) i& L2 \                in = (double)output;! X# v/ B  b2 l9 F1 W+ N/ S
                out = (in - tmp);
- h+ s3 _0 [; z% v                tmp = tmp + cutoff * out;" `) ]+ d; X3 D! a% b6 N, r

  H* a7 D- j/ C5 |4 N; {                output = (INT)out;
% J+ P! N! X( q8 q3 W                }
' A: d+ f/ O; T7 C: R  C2 |  G6 o#endif
! ?! c7 z: d- q0 P+ B: a) a#if        0& ]3 t% \' l- E6 d
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
1 C7 `$ ]9 k9 ]: a9 b4 A$ x2 q                {
3 Y% M* z1 K; p$ X5 T) U                INT        diff = abs(output-last_data);% x4 Z- L1 L& h8 V  H
                if( diff > 0x4000 ) {$ n9 D) \$ r. T
                        output /= 4;) ]4 `/ L2 _  z+ v3 P; R
                } else 7 l& P2 |. C. i4 i) o
                if( diff > 0x3000 ) {$ B) r2 Y5 k$ f& f
                        output /= 3;
; f) Z0 d; S  j# }/ f                } else% \# p7 }" T# G% F
                if( diff > 0x2000 ) {
& W1 X. M8 E+ u; p                        output /= 2;
5 N7 p9 U" m9 M8 U- q- e; F                }
( b* i/ E6 G& @/ a7 l                last_data = output;
, N& ~8 f3 `+ O6 E. A3 X                }
  B0 Q. `, E* {! T$ \#endif/ u; V5 K9 F) W8 J
                // Limit+ w; n1 ~/ y5 h& H
                if( output > 0x7FFF ) {
5 O1 y5 ^: o4 A& \/ m6 |+ R% d                        output = 0x7FFF;- S* ]) S8 z. q# i0 g: P
                } else if( output < -0x8000 ) {7 l& s* q) \- y
                        output = -0x8000;
! h+ ?8 O+ S$ ]' C3 n0 l4 r0 P                }
* I- C8 w# \; a% z9 l+ X2 d5 v2 r* |
                if( nBits != 8 ) {
) k2 u4 v1 u# v7 s& V, q                        *(SHORT*)lpBuffer = (SHORT)output;4 g1 R: P* c2 ^0 A6 D4 Y! A
                        lpBuffer += sizeof(SHORT);
; N& c' _5 g* C4 b- _/ X9 [4 A- _                } else {
2 O; j$ E1 t" Z+ ]" [, b0 i, ?. C- ^                        *lpBuffer++ = (output>>8)^0x80;/ g+ o* u% ^; ^% j7 d. W
                }* N  R8 `+ O6 k# M
$ e% ~8 L7 c: j) X, D+ l- C' Z
                if( nCcount < 0x0100 ); C0 C* B# v% G  o* p( f0 c' B6 e
                        pSoundBuf[nCcount++] = (SHORT)output;
1 _8 ^6 Z( i! s5 B2 k. K3 o# X: C7 q
% H5 u- I  D4 E//                elapsedtime += cycle_rate;7 l6 y& L- {  p: ^
                elapsed_time += cycle_rate;
+ o# r: h$ I( S3 M( P. S        }
% _; v; L1 _/ k$ P9 O! E5 N: @# o* z/ R" P2 D
#if        1; ^2 F- V* ^& {6 i; d
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {7 u) g& z. d7 z
                elapsed_time = nes->cpu->GetTotalCycles();4 u1 t: l  N7 j  ]1 Q- c
        }5 O0 d! v- T4 C( Y2 d
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {8 a: m( \2 H) |! C
                elapsed_time = nes->cpu->GetTotalCycles();
" @. k9 G: @' ]# ~" X8 S        }
- e' L' W# M8 C; A6 B3 t  k( B#else
6 V, H0 P9 u5 u        elapsed_time = nes->cpu->GetTotalCycles();
  o4 z2 M5 z: d- M) G( Z2 U. a& ~#endif
; }* ~. w: T" n3 j; E}7 F0 t1 j  y* z4 U

) d/ o3 P6 T4 H& t# B/ ~$ q2 }// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)0 s4 e' o) d) p1 d+ e6 m3 M9 U, J8 _3 ?
INT        APU::GetChannelFrequency( INT no )
7 a# S! Q1 B9 a- C& O( ?{
! ^$ T0 u: [7 }        if( !m_bMute[0] )
, a4 E2 d' C1 c/ e7 ~6 j* A- y                return        0;& f  p3 i4 ^5 E9 u

1 N. k* I. Y% S- ]( [        // Internal: N. z, Y4 x+ I: e& E0 g" `
        if( no < 5 ) {' w% v) T5 }6 I- s7 q) l
                return        m_bMute[no+1]?internal.GetFreq( no ):0;4 _8 R. [. z; X1 c6 t
        }
' C0 k/ U5 X; J        // VRC6
& _" |. T2 D' C% T        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {+ k$ O% y4 q: C8 \) J
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
$ {( ~2 D: d9 l5 r+ x        }# J) G- H5 P- b! b5 y) X
        // FDS
7 ~, U- m: c' W/ s* b        if( (exsound_select & 0x04) && no == 0x300 ) {
6 N5 G/ m' \6 _8 P/ {                return        m_bMute[6]?fds.GetFreq( 0 ):0;
( w! m- y! G2 B0 D. @, L; Y! g        }
+ F7 ~6 p1 ^/ ?0 r# E        // MMC51 P* N9 p5 ^& B; \
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {% J( K7 a1 d3 ]8 Y2 O2 {
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
5 w6 f3 N5 J+ d- v/ Z6 A" i  W, R        }
1 j; w3 f; R2 h& [        // N106
, h1 Q( s. w/ c$ R. @) f  F1 O        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {$ @# R, `: E- p" |
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
5 c9 Z2 w; Z* i( z, F        }
: Y- u* ^' T4 m0 L* `) M2 T        // FME7  y9 N. A3 j3 e- \
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {. Z! j; P0 j+ `1 N0 v- w, |3 I8 m
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;* Y- q9 U6 L  |4 f
        }; t1 L9 E. t- d* b+ G
        // VRC7
- X6 j" K; h6 W& q        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
; B% V5 Q- t6 L& W# l& N' P                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;) [+ o3 X/ u' a3 u) @  ^
        }
1 ~; A7 I; \/ H) O* y1 U        return        0;$ X+ v$ {: S& A; a" C9 \1 J; i9 a
}0 {4 Q: W+ k' R9 U1 _. g$ A
1 z5 k4 M& F' F- O) i
// State Save/Load
* @- e/ c- \% S7 B! I. z' \9 avoid        APU::SaveState( LPBYTE p )
; _8 u! g9 q; c5 I2 n{* N6 Q4 j) ?) w, p  D( f
#ifdef        _DEBUG
0 m( V' n; @, J# ~+ Q9 c8 fLPBYTE        pold = p;
3 k- h/ L, s' a# J$ v* P: w3 X#endif8 n3 N6 {  S; R2 ?- b! o

# i2 j0 H: W" p! t        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
; z) t9 b* s% w2 l        QueueFlush();
( K0 N( o  i6 c0 R3 k, G7 Z$ ~% w. x( a; j/ ?5 m
        internal.SaveState( p );2 d9 d% |% h% b" y8 ?& M
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding4 M: }& I0 L- ?  n

. w- s. r& K; F  P" H1 R        // VRC6
! R1 E$ g8 U! g+ o        if( exsound_select & 0x01 ) {
: }, }. M& F4 H! |" g( T                vrc6.SaveState( p );
- s2 C& Z- O& P* w6 T- b                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding0 P+ v4 z& A) p' r1 z9 b
        }' _4 E2 L( m+ c' N/ S* T
        // VRC7 (not support)0 m4 }6 d$ I0 v$ ]2 D
        if( exsound_select & 0x02 ) {
* j2 b0 f: u" h4 [3 D7 Y+ u- q. ^/ R# T                vrc7.SaveState( p );
$ a5 ~2 X% u  }) P1 B$ V4 Y* P                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
0 t7 k+ q1 e8 n, m! u8 Z3 s9 r        }
" K* [5 {* A) G9 X$ g0 [0 B6 W        // FDS
: r5 w7 [# U/ v: Y; |) Z* G        if( exsound_select & 0x04 ) {1 f" J. t7 F- i' I
                fds.SaveState( p );) t3 |# ?* W3 y2 Q. i& E
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding/ |7 [5 k7 R8 b4 q
        }, \2 k8 h6 S) D% w" v
        // MMC5
2 Q# l5 B' Y, k6 N        if( exsound_select & 0x08 ) {
4 a% T1 p0 n+ C/ i+ s                mmc5.SaveState( p );
4 {  t% ?, v, w3 [                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding6 g- o8 n$ S/ {5 t, o
        }
# s- ?' R1 R, L; U/ P& e' d1 U        // N106
; M7 a# @2 e+ C; S- L7 F        if( exsound_select & 0x10 ) {
3 t' U# C" P( z# n" N0 M4 l  x1 l                n106.SaveState( p );/ r. Y. L  T4 Y2 R9 m  q) X
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
' B* u) \$ u1 c: \        }  S% _% i' |' r# [) s$ {  _
        // FME7
6 C3 _) P+ V& `3 O; K        if( exsound_select & 0x20 ) {
5 [# h3 G4 @5 l' g+ {, P                fme7.SaveState( p );  k# D( C0 B- s6 r3 g
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding& L; P) ^7 t- E6 [# O
        }
4 F, N: s7 K* u
( E: ^) d  z, u( q; p' w#ifdef        _DEBUG# _6 ?9 k0 z* R: B
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
8 [. X0 u% w- E! K- H2 P3 m. F#endif
) W9 i' ^1 z& s( T: _- Q}7 }5 C; P: Q& R

3 D0 ]! f7 ?: ]- Svoid        APU::LoadState( LPBYTE p )  w+ t! V8 g( f% P; N) J
{1 x$ a+ i) \# w% _: z7 c: M# k* n2 b
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
/ B- K* [7 h6 J! _  t        QueueClear();8 S2 E- T" A; r6 u. ?
+ f2 ~% U4 H9 h7 P' ~' v1 `" M
        internal.LoadState( p );, p4 R) t0 l7 S
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding9 r0 X( l: H7 k+ o
- J- H8 ?6 {, T
        // VRC66 m1 p( e7 M% g8 r, @7 f
        if( exsound_select & 0x01 ) {$ h! a2 `$ T' w0 e9 ^
                vrc6.LoadState( p );; Q% h( }$ D2 B: }" l6 p$ h
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding( b* F  |' m1 N$ D
        }
0 q( e, G! M4 m/ y6 t6 h        // VRC7 (not support)# G2 \- s) D4 h. ^# J/ F; ]
        if( exsound_select & 0x02 ) {- Q$ [/ Z: \- n9 w) I/ z
                vrc7.LoadState( p );0 N- }) ?5 g9 t
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding8 Y9 @1 n0 n+ V/ [6 O% m
        }
3 J" E0 M* X  l) Y9 k* ^        // FDS
  T! X0 Y0 L& }8 G# j) \        if( exsound_select & 0x04 ) {
5 ?7 _$ u4 B, X                fds.LoadState( p );
$ ^- x2 z( ^9 e, l! Y6 ^                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding9 h6 e0 e- k, u% F- J( n8 ?' g. A
        }; k' J, l+ o4 f. ^
        // MMC5# l2 D& I* K( c" F5 s7 \8 a5 s
        if( exsound_select & 0x08 ) {0 h$ z% I9 D1 L- u% b
                mmc5.LoadState( p );/ b8 G$ v+ {' z
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
4 c5 L. Y1 `6 u  y5 T  [, e        }
+ x. q$ j6 J, ~/ ?" B7 Q+ B        // N1062 o7 o7 y- E2 Y& ?1 m. \: }( s
        if( exsound_select & 0x10 ) {
7 |) ~* ^$ `: P- A3 x                n106.LoadState( p );
% `7 E1 h! Y8 V) m6 b& E  T9 i                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
: I, i1 e7 n& P- r3 ?& P; b        }
1 B1 ]7 ~* [+ i        // FME7) u! o. c: g; Z, E- L5 ?
        if( exsound_select & 0x20 ) {9 ]# R! F1 D; U8 {
                fme7.LoadState( p );
, j: M0 l6 t$ X' H* v& _; \+ G4 a                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding9 u* L8 B) e& A$ R4 Q  x
        }
$ J' Q; o# l0 R; s5 B, E2 w  \, s}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
& l3 j- T# t# O% ^可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
4 H: P* `4 _8 S0 U# l感激不尽~~
/ |' q, V8 N8 p/ |( _9 q0 V
恩 我對模擬器不是很有研究,& g& s7 E8 q9 {( W2 m9 a4 \1 t
雖然要了解源碼內容,可能不是很困難,
0 ?, D7 i7 b# E7 D% Y! i: k不過還是要花時間,個人目前蠻忙碌的。
" A" e% \+ q: x1 K4 T+ V* b( f; G+ k; u/ V$ ^" I) b1 ?8 N. q; L
給你一個朋友的MSN,你可以跟他討論看看,1 B3 m& U0 x: Z" W
他本身是程式設計師,也對FC模擬器很有興趣。$ @' U# Q* X5 o% E  K! ^3 H
8 f' G5 Z0 |, v: K' c/ Y
MSN我就PM到你的信箱了。6 z3 G9 U" G5 m: m1 B  p* }

% U, ?" L, z7 X& A希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
# s# F% V5 O. L' T3 z呵…… 谢过团长大人~~

& M6 ^3 B, C" c/ \( P0 ]
" v7 w" s6 Z! p哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
' X# U& n1 ~. j* `团长的朋友都是神,那团长就是神的boss。
% p+ U% O$ U+ j+ g8 j* a
哈 不敢當,我只是個平凡人,) t& m0 ^: }! Q* n
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙- o7 X8 `  M9 I5 |, e
ZYH, P; q6 \# N( q6 L  W
QQ:414734306
. p: b  o! l' o/ G6 yMail:zyh-01@126.com
! L6 a% c# D" v/ W2 q) U/ L3 K0 t/ `3 v$ S
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 ) Z, v( E4 M  m+ N; t; {
再次对团长大人和悠悠哥的无私帮助表示感谢~~

' u5 a4 v. Q' k/ U3 [不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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