EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。5 u+ _/ W) X6 k6 }# A( ~
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
! L- N( \1 C4 }" c" V0 K2 h这里有相应的模拟器源码,就当送给大侠了~~
+ f& P9 K) U9 ~! H. {" ^http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 / D2 ?2 k& Q% q
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
& a% [0 O; Y1 u楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~9 q0 g, F$ t, g! P: ?- l- d8 T
这里有相应的模拟器源码,就当送给大侠 ...

( F9 a# {9 `# `聲音部分(Audoi Process Unit = APU):! P) O- j- F2 K; y+ j. c( v
.\NES\APU.cpp4 |" m8 p4 d! U/ Y- Z* B2 \
.\NES\APU.h
0 q# Q, k( b9 ?: l; Z  _  f3 q- b
) ?/ Q" h, k) B
$ O$ s7 V& I! ~$ \% S- R9 F影像處理部份(Picture Processing Unit = PPU):  v2 l2 D+ R- u9 x$ w7 h
.\NES\PPU.cpp
+ w0 }2 B% D; I# a; e( {: q.\NES\PPU.h5 M% Z2 {; T2 k7 j( a' |
" K/ }  q% ]2 z
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
+ j, G/ v. `; d5 `, ]) |. |( i(由于很多专用术语和算法机理都不明白,所以看不大懂……)
" B( @# O1 W- v. Z* f//////////////////////////////////////////////////////////////////////////- M& Q1 x4 k* d% p
//                                                                      //
+ f2 e. _1 I3 k2 }/ v- ~. [, Z//      NES APU core                                                    //
& R; A6 J2 d$ V. R//                                                           Norix      //
( L, _7 R( x( K* ~) v0 E//                                               written     2002/06/27 //
- n/ X' H3 b# W9 B: r; z9 [//                                               last modify ----/--/-- //
7 Y6 b9 _1 s, s0 O//////////////////////////////////////////////////////////////////////////
  ]8 l0 q+ F  n% n2 {  }8 U% @#include "DebugOut.h"+ [' r8 w& R: f- O" f
#include "App.h"
& d/ c4 ]- z# I6 u* i- }#include "Config.h"
  c2 r+ `5 s  _1 f. l3 b1 |; l' s
#include "nes.h"" H+ H: U0 s' |5 T
#include "mmu.h"2 K3 F+ G; @3 L6 N+ m: |$ M
#include "cpu.h"3 D; m+ P3 l" M0 J- F! B, V5 x
#include "ppu.h"% x7 u5 c' r- ?  G
#include "rom.h"
" K2 n3 ~+ O' [+ l; v) X- V. C#include "apu.h"* c+ N5 M9 B7 b6 |/ r8 h

5 L2 O- A' a" \2 D1 q" f: E// Volume adjust" w9 r( }# z; i1 ]# K6 w
// Internal sounds; l# f. V- E( L1 M" \
#define        RECTANGLE_VOL        (0x0F0)
% A' k8 a% J: ^  }0 d#define        TRIANGLE_VOL        (0x130)- E3 c, c) [# t8 c2 J
#define        NOISE_VOL        (0x0C0)
9 z7 H8 @$ C2 Y1 {1 b, S( X+ P. w#define        DPCM_VOL        (0x0F0)
0 h: A$ [7 ^" x. {// Extra sounds
+ k. k- I  e) |& U& H, V6 d9 Y# {#define        VRC6_VOL        (0x0F0)" N: l$ }9 p$ F6 P* x
#define        VRC7_VOL        (0x130); J8 O+ z  X+ L2 H1 ~* _5 |  o
#define        FDS_VOL                (0x0F0)
* x. c& s2 ^7 Y$ E0 ^1 @#define        MMC5_VOL        (0x0F0)1 q( b$ p2 X5 }- X
#define        N106_VOL        (0x088)
& }# I8 M1 K0 e' p- f$ z- o#define        FME7_VOL        (0x130)
. K2 W9 h3 i# X9 }. a% j' I, y( Y3 ~3 v+ K
APU::APU( NES* parent )
" j# P$ h% E6 O2 @- |" T( l{' m/ S- A+ |8 T. @9 k0 m1 L& X5 i
        exsound_select = 0;
( f# P7 T# y( z) G* u  E4 O' |& ?' W7 p# v
        nes = parent;
+ z: _* K4 Z3 o8 G7 g        internal.SetParent( parent );9 }0 f0 A/ ]9 h- R3 x6 a

- _8 o; i, \7 _- L! H        last_data = last_diff = 0;
4 [7 C- q5 K; ], z5 S7 T$ F4 [) ]* q# b7 y( b. }# I5 a+ X
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );8 F5 w0 O( F) O

9 Y6 ^8 v1 j9 f6 ?) T- u        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
+ x3 r1 `' X) X" Y7 Z3 l( C% y) ]        ZEROMEMORY( &queue, sizeof(queue) );
/ w# K3 X- G. r4 J2 c        ZEROMEMORY( &exqueue, sizeof(exqueue) );
/ F; w" h% k& q: p
5 \! Q2 h. ]4 S9 d; M        for( INT i = 0; i < 16; i++ ) {' b: G+ M) h+ a; L) _7 D
                m_bMute = TRUE;
+ }4 M" U' M4 f" I  \8 s        }& q6 A; ]9 C  ~- ]- n" h* L
}
- Q( S+ \1 F, j+ n+ S2 \2 P
" O5 l+ K" @" M- wAPU::~APU()7 k* C$ G9 t! R
{( i4 p- Z2 _; c1 A; I- a3 t# N' x
}8 k  j8 S9 ]. f: @3 \& S: C. O8 {

0 m* U8 I  i6 Q( W# }void        APU::SetQueue( INT writetime, WORD addr, BYTE data )/ x* w5 j1 d$ V5 G) z" |
{# c3 _5 o. x" o# u
        queue.data[queue.wrptr].time = writetime;: I" |  G) ^/ N
        queue.data[queue.wrptr].addr = addr;
  \; J+ {/ ^# F+ o/ t4 h8 F$ |        queue.data[queue.wrptr].data = data;( r+ T0 G! }6 P+ D/ J, y( H/ V) p' |% u
        queue.wrptr++;
* o& i" v1 @; L8 z- R        queue.wrptr&=QUEUE_LENGTH-1;' W: M7 S3 X4 K" B- C, G# R
        if( queue.wrptr == queue.rdptr ) {8 {2 I# {9 e9 d+ c+ t8 H
                DEBUGOUT( "queue overflow.\n" );
0 N1 _0 K9 H. d) T$ J        }
6 c0 e% ~+ f, s}+ ]+ b2 A" }9 Y- T8 F
, h. J" _6 _6 N' Q
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
1 N, c# \: ]1 }: y8 `- m{
" t+ h& l, C5 b; j7 [        if( queue.wrptr == queue.rdptr ) {' F; j8 ?" j; S9 o* f$ C0 n2 G
                return        FALSE;
4 R0 V  O( s1 W/ c        }' A3 l. D0 {$ n$ o, s
        if( queue.data[queue.rdptr].time <= writetime ) {
* W, c3 a" Q/ X                ret = queue.data[queue.rdptr];
/ x5 l& t7 M4 `7 U- G3 U( m$ A                queue.rdptr++;
& @* s# j2 A2 w% m                queue.rdptr&=QUEUE_LENGTH-1;
. h3 J5 j1 i( ]5 Y/ c3 m                return        TRUE;
  U+ e, o9 \3 ~        }. P. {& S% {) S% M+ L0 |' A
        return        FALSE;
4 d0 F0 i) ]$ z& ]2 }; L! d2 V" S}
/ N2 S# ]( V$ h7 U2 j# j( R7 s' k+ Z- Q
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
4 d6 B* A/ g/ Z{
5 [6 ?. w) }! k        exqueue.data[exqueue.wrptr].time = writetime;  H5 c2 \  N1 _9 {. {' _" k* B
        exqueue.data[exqueue.wrptr].addr = addr;: ^, t# ^) S& z; y# c: t; Q
        exqueue.data[exqueue.wrptr].data = data;
/ c( S9 J  P: N/ i( y8 e        exqueue.wrptr++;
7 _0 E  V* g6 h        exqueue.wrptr&=QUEUE_LENGTH-1;
: y! A- j6 O+ F( {        if( exqueue.wrptr == exqueue.rdptr ) {
8 C1 r, w. V. m3 U; N% o7 Q1 d3 e                DEBUGOUT( "exqueue overflow.\n" );& X) ]9 G1 ^1 n% |
        }6 ^! q7 K$ x) j9 e0 J
}  Y9 D0 d- l2 r

5 P+ r3 r4 w# }/ d+ ~5 ?& }8 JBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )* ]* ?( z- @7 `
{
* ?# }$ k# D# U        if( exqueue.wrptr == exqueue.rdptr ) {
: A, s' Y. T$ o8 h( z                return        FALSE;
# X: ]; d3 S7 i- t2 T        }
+ O4 b; ~* K- Z6 p2 S9 w; |        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
1 [4 M8 v7 K- M' ^7 r( J                ret = exqueue.data[exqueue.rdptr];4 e0 s  G+ d9 t1 R/ D
                exqueue.rdptr++;, t0 s# |2 U) n! J, C
                exqueue.rdptr&=QUEUE_LENGTH-1;3 v6 O% N6 s! c3 K
                return        TRUE;
$ }* ~0 N" D+ S- |& i7 j        }: {: B% G/ _- F% ^6 B+ q9 p/ ?8 D$ f
        return        FALSE;  e/ }( y' M8 A" D0 d! h4 f! R; W
}
% j) n* B7 ]( r3 e/ w7 E/ a  B  D, O( s/ u
void        APU::QueueClear()6 V$ G0 \- e" \  f6 `' t7 [2 S
{0 n) H) z& q0 [
        ZEROMEMORY( &queue, sizeof(queue) );' y3 j' }& D- I4 j
        ZEROMEMORY( &exqueue, sizeof(exqueue) );, F3 o0 O0 m0 a5 v% ^) J( `1 }' a$ f5 v* h
}
/ c0 T5 V8 ]8 D& |' n. M5 L2 i1 L' F% v$ W" z2 B1 T2 n& D* l
void        APU::QueueFlush()
% ?" K  B* a1 p' J: t4 h{
" V, c3 E- E, z6 {4 |        while( queue.wrptr != queue.rdptr ) {
( L- Y% Y/ P* v1 d7 {                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
4 M1 h" X5 L* w  x& G) [8 |- z                queue.rdptr++;* B8 _' ~# z: f
                queue.rdptr&=QUEUE_LENGTH-1;' Q1 g6 k  @/ ^( d) `
        }
+ t  m- e6 C- w
3 s. q% c1 L" e6 Y6 s3 L        while( exqueue.wrptr != exqueue.rdptr ) {
  [; L3 G* ?" C1 U$ v, [' g" j                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );% a+ q$ E# K3 c$ W. m! j( @
                exqueue.rdptr++;, O) u: f: n& x$ `7 A+ D/ x
                exqueue.rdptr&=QUEUE_LENGTH-1;; l; x9 _1 g& |" E* F
        }
' y  _! ]2 Y. W8 Y3 B; K! n}* K6 V2 Y: [) L& H! |4 u9 c

' V! \; g3 v& Tvoid        APU::SoundSetup()% }  |8 i6 d1 L( ~& v* E  d
{) m6 k' P! s, Y8 y; J5 [" j
        FLOAT        fClock = nes->nescfg->CpuClock;; r* F. _& ]6 g" k) C' u+ D  A
        INT        nRate = (INT)Config.sound.nRate;. M, n2 F7 f: i) r5 y
        internal.Setup( fClock, nRate );
, ?( F1 s' R3 A+ c8 f        vrc6.Setup( fClock, nRate );
3 S+ x9 R, o5 w0 c3 e; m' h& L        vrc7.Setup( fClock, nRate );
& A% I2 ]+ X1 T* X# |5 _        mmc5.Setup( fClock, nRate );
! U  ?$ X0 I+ {1 l! ]        fds.Setup ( fClock, nRate );
! n; T6 v+ @, d0 y) _        n106.Setup( fClock, nRate );# ^7 O2 s( }/ V1 a8 B. N( k
        fme7.Setup( fClock, nRate );& G4 ]5 r  f7 e# u; I# k7 z* B' n
}
- u; d5 l( N9 |
2 f2 \7 U! g" K6 ^- i- T9 pvoid        APU::Reset()8 a+ N' W0 a) }
{7 n1 ^. R0 v5 ?& W4 ?! }
        ZEROMEMORY( &queue, sizeof(queue) );
" j& G7 a: c( i% ^        ZEROMEMORY( &exqueue, sizeof(exqueue) );- A1 E- j6 v7 K% g

' P1 D8 N$ R8 G9 b1 I/ N3 e        elapsed_time = 0;
) C) q2 k, s: I2 ~8 P7 I, n
# s5 o- }0 y3 N, e        FLOAT        fClock = nes->nescfg->CpuClock;+ e# @, R  v& a$ |0 g  _' L1 B: i( ^
        INT        nRate = (INT)Config.sound.nRate;
, O/ c$ t, j9 k2 _        internal.Reset( fClock, nRate );0 g+ j* }7 E# J3 L8 k# [
        vrc6.Reset( fClock, nRate );4 }- u6 l' [$ f  k; e4 B
        vrc7.Reset( fClock, nRate );* A) o- M3 q  u3 F
        mmc5.Reset( fClock, nRate );
- l" D' x! `% P0 S3 G0 O( Q. Y        fds.Reset ( fClock, nRate );
' @* Q6 o/ i/ c. w3 E; _/ B        n106.Reset( fClock, nRate );
) S! B4 d7 N9 E9 q: n, N        fme7.Reset( fClock, nRate );
5 z7 Q! r! w6 d( b; Z, a0 \5 y  s8 I, I9 Y6 Z0 {, i) o, i' K+ z4 e. H
        SoundSetup();: y5 L6 A1 t' f( r& }* V& N
}
6 l- I9 c  {' z. d: Y3 k! f; X
* W4 Q& o& V% ~' ~( x$ Ivoid        APU::SelectExSound( BYTE data )
0 a! N2 o6 N" C* K$ N9 R) Z: P{
# x. G" @. E, m3 g" S) V4 ]# ^0 Z        exsound_select = data;$ {9 f! i$ l! x7 k# }
}
* v& {9 V0 A+ }6 |) u9 k! m7 E8 P/ a+ a& v' B
BYTE        APU::Read( WORD addr )% x/ {( `( u' j& m, P- D- N; J
{/ b8 D8 f* z: ^) D* X2 T
        return        internal.SyncRead( addr );
3 e" u7 [2 ?/ u3 e" z0 R}
( c( d' |- Q& [1 k+ z* F7 r* l1 a# E% j( j+ `8 @+ ]2 I
void        APU::Write( WORD addr, BYTE data )* H8 C: R7 v1 B
{/ c) O& r# i* i# @% g
        // $4018偼VirtuaNES屌桳億乕僩9 X" w9 N  I! Y7 }3 z9 L8 U+ x( X
        if( addr >= 0x4000 && addr <= 0x401F ) {" P* z: s8 c% i3 e/ ?
                internal.SyncWrite( addr, data );7 X' U/ f' }- A0 X% w* A" n+ Y
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
! ~; Y9 E% r) t: G3 V7 D- T. X5 o        }
5 I/ e$ b5 Q7 I# }* o( W: F3 _. E}- g$ p1 O# ?. t' g

$ X, N/ M4 T7 {8 V! ZBYTE        APU::ExRead( WORD addr ). U! |% E# b9 G
{
, ?/ Q; {5 D5 W2 @/ ^BYTE        data = 0;
# V! v& h8 M8 Q+ Q0 ^7 S/ Y" ~1 ^( N* x& ?) Q
        if( exsound_select & 0x10 ) {
% r  b* l- l( x, n. t                if( addr == 0x4800 ) {
" w4 R- ^* O& a8 f- }1 R                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );: l1 E' ^! g6 m$ h! ^% p
                }
& N7 T, C- S6 v        }. e& m8 i+ O# @8 R5 D- q0 v
        if( exsound_select & 0x04 ) {9 }8 _& G: J: C% V, g
                if( addr >= 0x4040 && addr < 0x4100 ) {
; |% ~! `: ~+ U- D. P                        data = fds.SyncRead( addr );
2 H8 g% D& U5 B) e& _, h% R                }- l9 i* I. M* P# {$ n
        }+ g7 G' i, b: d1 x. E, ?/ ^) o
        if( exsound_select & 0x08 ) {5 ?* ]+ \2 I0 R
                if( addr >= 0x5000 && addr <= 0x5015 ) {- ?* m7 D! ]1 E  U( C1 F0 w. [; V
                        data = mmc5.SyncRead( addr );9 F4 g3 t! L0 b. Q5 Z  @
                }
* A- \1 d. n9 n& K, S( u        }
4 }) {9 k- o  w+ m5 g) }) c
. |3 A# ~) ?4 ^- l$ H! V5 X- Y        return        data;$ R% f9 p& Q- @* t7 Y& r
}% i9 }6 W9 n6 B3 @
& z: F. `8 Q& a) }/ n( C( f+ a
void        APU::ExWrite( WORD addr, BYTE data )0 P" @- @6 ~# I( c( M
{, _' {$ M3 c+ k  `" A! Y
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );3 M. o% b) p9 {5 U

  [/ S! n4 @: j" P. E6 f) Q: q/ D        if( exsound_select & 0x04 ) {
0 z6 H, O( i6 k5 q3 Y                if( addr >= 0x4040 && addr < 0x4100 ) {
8 V& A" E2 O9 W6 |9 Y+ d' M' s; T                        fds.SyncWrite( addr, data );
7 b( Y9 m- U2 S                }
9 o' c3 ^* d. y9 z' c& P" K        }
4 x- d1 `1 ~+ O; r
! T' |+ L3 [4 }: K        if( exsound_select & 0x08 ) {
- Q0 L% E- ^' P2 W' a* t6 p! ]+ ^                if( addr >= 0x5000 && addr <= 0x5015 ) {
9 ]% I4 J# j' i, Y                        mmc5.SyncWrite( addr, data );
  I3 a/ U3 ~$ Z                }
0 Q/ ^3 G% g# @, w' O* s% r        }. q2 X# P8 G5 d& F8 u( I) x
}& @5 d, j, q# c, p, y9 @
6 t& }. Y  v) x2 V, P, K( j
void        APU::Sync()6 c7 X3 C" L- K$ w$ X# B
{+ g2 G0 A0 ]' _+ N, W* y3 r, v
}$ E3 h9 b" D' R1 O/ t/ O1 q

* {; U, U6 ]# d. s0 m5 I2 _void        APU::SyncDPCM( INT cycles )% W6 k5 ~% B( v6 h& s6 `
{
1 z4 Y/ d, n: ]2 ]- X0 v        internal.Sync( cycles );% u5 R& Q1 t$ i* U

2 x8 Q$ d- L$ v5 l4 B/ S" n        if( exsound_select & 0x04 ) {3 K9 U: }8 K2 i* v( r
                fds.Sync( cycles );
9 G0 j/ q9 M2 N" v        }+ k, }/ R* g* [3 q  X
        if( exsound_select & 0x08 ) {
/ G  l6 [! s& {                mmc5.Sync( cycles );1 ^4 b, a9 @& b# y/ j! `
        }
4 J6 q2 i. A8 G3 [}8 I2 a# d7 G7 [, N

, n1 q4 _6 r4 K9 Y4 uvoid        APU::WriteProcess( WORD addr, BYTE data )
4 s" b+ S; k3 j) c{
9 @$ E* k; Y0 l7 D# L5 @        // $4018偼VirtuaNES屌桳億乕僩
' h7 D* z2 j  V" c/ J( ]- Y        if( addr >= 0x4000 && addr <= 0x401F ) {
" Z" {# U2 t' I( I8 j, t                internal.Write( addr, data );$ }! d- T" }5 ~( o
        }. Z3 r" X/ E4 n: Q
}; r& v0 \, A0 ~" M: z
: W: y2 o+ C2 @) Y: k: z$ \
void        APU::WriteExProcess( WORD addr, BYTE data )( s) a, Q' G5 ]! T* X$ `
{
4 |) w9 i7 v) n# ^        if( exsound_select & 0x01 ) {
. P" B' d' k9 x0 X2 d                vrc6.Write( addr, data );
% v" `; Z2 y/ R$ Q- p1 c        }$ C6 Y% S. R. [
        if( exsound_select & 0x02 ) {6 p2 B- m; W* |4 C% `8 F$ I
                vrc7.Write( addr, data );
: D. c, _( k3 r2 }        }
! v0 N/ }) U: b- @7 E$ ~        if( exsound_select & 0x04 ) {
" ?* x9 }6 ?$ O, H1 a3 m. p3 F% q4 B                fds.Write( addr, data );
) i! v8 ?- n$ u. O" V8 \& F        }) W  g+ v1 t8 B4 ^8 y
        if( exsound_select & 0x08 ) {- @0 ]- b. V  L4 a- n  Q  E( Z2 P# l
                mmc5.Write( addr, data );9 ^3 [1 Z2 L  y! F& v+ [" h4 X
        }
% T8 Z2 A0 t* j, X& ~) Z2 {        if( exsound_select & 0x10 ) {+ G; G5 t) W- l! o7 t; Z1 V. l/ m
                if( addr == 0x0000 ) {
( F8 w- B# M. Q7 g! {8 e                        BYTE        dummy = n106.Read( addr );
( g4 z) r6 h% A4 ]3 \) `9 ^& G& S                } else {& n" R3 Q5 H( E5 H; `- g
                        n106.Write( addr, data );
% l) `3 C8 w9 n. B/ T                }# K" w3 E+ \# I, e
        }
+ h# U% \# I( j        if( exsound_select & 0x20 ) {+ J% x: U  U* M$ K. Y
                fme7.Write( addr, data );
# D5 I9 J; F0 p) H2 N        }* b8 c% J3 ]8 ~) V
}! ?4 Y- I; Q: O% }( }3 p& U
+ x6 [5 ?$ q/ I# J6 u1 x5 w1 n
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )3 o8 e6 \; u; O1 [) {
{" H: Z/ Z, B2 P# u- B
INT        nBits = Config.sound.nBits;! t$ Y, T/ S# _. D# b6 _6 y
DWORD        dwLength = dwSize / (nBits/8);
2 F1 G; B( p( h/ ]- }' }$ xINT        output;2 l9 f/ T2 U; F: S. q1 w' r
QUEUEDATA q;  ^) p2 U2 h' G. L8 Y9 o3 q4 u
DWORD        writetime;0 ?4 V( D2 u) F. ]

  m  S4 \8 a; V1 w+ ]LPSHORT        pSoundBuf = m_SoundBuffer;
/ I: \( o( t/ L' \: u$ CINT        nCcount = 0;
; p- @. U9 L) v3 R5 B( A
9 R4 p3 i& {  x8 w+ Z$ s8 @3 wINT        nFilterType = Config.sound.nFilterType;
3 D) H5 q  [$ Z
: K- N7 B& I4 A# Y6 Q: K7 t        if( !Config.sound.bEnable ) {- a/ u: E* e% Q- R& y4 ^( S
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );1 @( t- f! ?2 @2 J3 b+ y( N! x( H& z
                return;
. W4 T7 L# J! B; @        }/ U8 f; h" ?7 G7 B  k6 g. }, N  H+ R

( R! m7 x# |. q% f" x2 [        // Volume setup
) H0 [6 @. E. F$ d* m# _; c* D2 g        //  0:Master5 D4 l/ r  S8 w6 h4 _" T
        //  1:Rectangle 1
; p5 S) W2 p' ^8 K3 ^2 F' n) K        //  2:Rectangle 2% h) W& @* H2 h$ t- r; y
        //  3:Triangle+ g( X0 f5 a: k1 a0 q
        //  4:Noise9 X3 H4 K+ v0 ~* G
        //  5:DPCM! k# D3 j  C  a
        //  6:VRC6- \- H3 V* X$ Z0 c7 j' R
        //  7:VRC7
, o" L7 P+ m% t6 U( [" O        //  8:FDS, i! R: a  K" Z( S( L5 y+ u+ S% c" C
        //  9:MMC5
" |, z& j5 D! }        // 10:N1068 p5 w/ i5 E9 p6 y) f
        // 11:FME7
/ p9 D/ c/ u( X8 I, j* p        INT        vol[24];) d+ v& o# X% e) ^; Y! @: \# k
        BOOL*        bMute = m_bMute;
# P3 z, {* z+ y; `        SHORT*        nVolume = Config.sound.nVolume;  ^: q6 m6 X; `
/ n9 ?9 j; t+ {( m' _; r
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
( }! `  y; r, x) `# ]! _6 ~( d
5 W% m& t8 W( O& m% e' a        // Internal3 Q% u: x' w! k5 M& \6 V7 v
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
, d' B8 x( @4 Y; {        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;( b  v7 D; g' s# m
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;! i9 D; ?8 K( J7 N( s$ D: v
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
% c# t# P" _5 D: W8 Y        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;' I% X% ~% v6 H7 d& Q3 J
' G6 s5 n/ S8 t% \
        // VRC61 V7 q* s) J$ F  E
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
( t, @( B! Y8 ]8 _& n+ r        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
* q& O8 Z! [$ o) d6 \# v5 b        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;; z; y" M- B2 S' E4 G
% m) I. m9 A! G) w  s
        // VRC7
' Q; k* b1 |2 j0 d        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;  h8 N& H7 B% E4 s
6 b# e" b6 n) K2 L0 R& k/ @7 Y
        // FDS7 e' B7 [3 o" [2 _3 ^2 D: q% M
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
2 y2 x9 M) w+ F3 E
, w7 k& Z: F9 @, c4 N6 w        // MMC5$ d& N  y; a" N
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
& p( c* o& ^# u$ Q        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
1 v# i: S3 r+ N        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;9 c' ?6 Q5 ?; Y7 G, w- L
: S8 i1 m3 J% {. P# i0 |
        // N106
) X: t" s- x) z7 H2 M# i& {        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;7 Q$ h" J& Y! v* q7 B8 s
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
3 j2 F) ]) a7 R" K; r        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& ~' U9 @, `& e9 d        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, @, A6 p5 ^5 K# L" n        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
9 V+ V( X/ O0 a        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
! s% ~! F$ c' c7 D1 ^4 L& F3 e$ Y' s, M        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;  a/ E7 j" C7 s
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
4 ?& H2 b9 X- ~" V# e, V) C( K" x) ~
: t+ S4 \+ `7 o& T: M/ w9 \8 b        // FME7& S3 g  P6 l! }& |
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
) p$ W3 {! u! G) ]) D2 E0 Z' t9 S/ b        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;# A: }7 }, E6 K
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
( m& r( m: b" j0 a8 C1 J
, d+ v8 c. L- }. b8 }. [//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;  B6 n. P, l8 A. k; E% i' ^/ U% U
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;# }: y: o0 ~6 S
0 w) Y8 ?9 Z& G. B6 t5 j
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
( D. Q2 `9 `+ ], h8 ]        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
% \3 m7 n6 J/ l) ^+ O. l                QueueFlush();
& O4 p: y3 N6 G# A* v        }
" @/ p8 P6 R" m2 H% {7 i# j, O8 c! J
        while( dwLength-- ) {
1 m6 y  a9 _5 T$ p                writetime = (DWORD)elapsed_time;" v3 P2 O9 }* J. \3 V. e

# c6 R1 i; g# L7 C9 s                while( GetQueue( writetime, q ) ) {* m- x. d( s5 k/ I  _: t9 y. G8 o5 q
                        WriteProcess( q.addr, q.data );* H3 G) k, @1 _( n* R- \
                }
2 ?% d6 b3 q% C+ Y' M9 k
! k9 |, o) }# ?/ H                while( GetExQueue( writetime, q ) ) {  O' ?* n5 p6 F
                        WriteExProcess( q.addr, q.data );
1 U' n1 V3 R7 x8 ]5 I% b                }+ |) j% q5 t" u9 G2 i
1 n7 l) d- D& b, Q+ L/ h0 W6 B
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7! U3 M: K6 V. G; q2 b
                output = 0;7 b- f8 U+ G% I" i
                output += internal.Process( 0 )*vol[0];
9 d/ x  d% Q& o, C- k                output += internal.Process( 1 )*vol[1];
6 @0 Z4 @" T# `                output += internal.Process( 2 )*vol[2];
( F( T( f& f- g                output += internal.Process( 3 )*vol[3];& ?: X3 y% S0 }2 ^( Z
                output += internal.Process( 4 )*vol[4];
/ e9 T, g) x8 ~2 z2 t! v
, I. G  @% T/ V* n" x+ X: `; D                if( exsound_select & 0x01 ) {
; Y' y8 r8 {, Y                        output += vrc6.Process( 0 )*vol[5];
4 ^* }( Y5 V5 X- z                        output += vrc6.Process( 1 )*vol[6];
+ d. }! k- y7 s' z  x* R                        output += vrc6.Process( 2 )*vol[7];
& W7 I( m8 l9 z                }( l- ~4 T3 O; H; ]
                if( exsound_select & 0x02 ) {; C. f/ ^" @3 `
                        output += vrc7.Process( 0 )*vol[8];9 h" ~, \: d& `0 T" ]  P' T
                }
+ [! A$ g; n( h                if( exsound_select & 0x04 ) {
, w/ B* B) A% V% `$ W                        output += fds.Process( 0 )*vol[9];
1 Y& {0 ]8 d" N9 }" n7 U2 N9 N                }
" Q* V* S$ a4 K+ o) e. e. Y                if( exsound_select & 0x08 ) {! S- |4 m4 ?9 J% p4 ^
                        output += mmc5.Process( 0 )*vol[10];5 h5 ]% J7 N/ T! {5 \9 P
                        output += mmc5.Process( 1 )*vol[11];1 {1 m! j  J/ s& o, D8 _* U
                        output += mmc5.Process( 2 )*vol[12];
, w; B( j5 Z- b' i# X/ k                }1 f3 N% |# J9 e+ `7 Q1 U$ ~6 F* A
                if( exsound_select & 0x10 ) {
& _* ]- y. b6 ?9 [                        output += n106.Process( 0 )*vol[13];
, Q  J- e" z. m; U+ \5 h3 P                        output += n106.Process( 1 )*vol[14];$ V( q- \3 z- e2 Y; E
                        output += n106.Process( 2 )*vol[15];; [* e0 e3 b5 f9 p& p* p
                        output += n106.Process( 3 )*vol[16];
$ @7 B+ ~$ q+ q  h  j$ t: P                        output += n106.Process( 4 )*vol[17];
/ D4 v' `% V& L1 v: j                        output += n106.Process( 5 )*vol[18];
* @( M, r6 @; O( `4 n/ E6 C                        output += n106.Process( 6 )*vol[19];
- W1 R& k& ?( a6 w* q: i5 K3 y                        output += n106.Process( 7 )*vol[20];) J* m# J0 @) A/ {# N( T
                }$ r% Q9 ^  g5 w) |9 ^8 `/ ]
                if( exsound_select & 0x20 ) {8 Q( a8 ]0 u3 ~* W3 n0 {- [, ?
                        fme7.Process( 3 );        // Envelope & Noise
4 j5 Q1 Z" ^% E, E0 P/ E                        output += fme7.Process( 0 )*vol[21];
2 q9 t' u8 N) I                        output += fme7.Process( 1 )*vol[22];6 [8 v* F/ L, V; N
                        output += fme7.Process( 2 )*vol[23];( h- j3 E3 G9 f
                }
1 P3 C/ N7 c' W4 k6 D( y: S& t# j5 l$ r* b7 g
                output >>= 8;
. L1 \3 J) L4 p
( g) R# z$ Q* P% X; K                if( nFilterType == 1 ) {
: |/ \& ?$ }4 u6 M" S4 s2 N                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
- E% C1 {4 y* j3 C, |" b: w                        output = (lowpass_filter[0]+output)/2;
3 e- B  E: M0 m6 }+ N                        lowpass_filter[0] = output;8 {6 C0 }( @. S: `/ g7 X( Q
                } else if( nFilterType == 2 ) {
5 K) P0 i5 n" P' B2 U, l                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)/ j: H4 j6 b) R3 B9 w1 @
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;; A7 b9 @! _% n8 U
                        lowpass_filter[1] = lowpass_filter[0];
1 x) [% c7 F: Y                        lowpass_filter[0] = output;! M: f* l# u9 |# E
                } else if( nFilterType == 3 ) {  x, A# R/ f, Z
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)* a& J, a+ K' Q& H8 h- x0 ^
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
' [; k/ \! `/ v                        lowpass_filter[2] = lowpass_filter[1];
, u. @5 v0 b% x" k. h! h1 ?+ _: r                        lowpass_filter[1] = lowpass_filter[0];+ Z( r/ o: D3 x- d
                        lowpass_filter[0] = output;
. B) T6 m. z$ h1 O- z                } else if( nFilterType == 4 ) {
" A$ `  `; H8 i/ _                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
$ ?  X8 d8 n9 `" N                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
+ I% _3 t# K4 w% A% A( @$ w/ f7 f( ?                        lowpass_filter[1] = lowpass_filter[0];  h5 `6 i$ c" F' p4 v9 y
                        lowpass_filter[0] = output;9 x* L( T6 g; {
                }7 P, z; G/ j$ ]2 y- T$ O8 Z
, A1 }3 _. u0 E0 ]
#if        01 l+ K2 V( n& B' d) M
                // DC惉暘偺僇僢僩. [1 L+ l" y8 d) H' g2 I7 e4 x
                {
: z/ r% k8 Q8 Z( O                static double ave = 0.0, max=0.0, min=0.0;
. T8 a5 \7 j) R- {) E5 V0 z$ g$ s                double delta;
" e0 W; o0 [# w4 A% f" R, I1 p7 X                delta = (max-min)/32768.0;% S2 R; N1 V7 N9 L' ^
                max -= delta;; m6 u- M; B& \" c
                min += delta;
% Q* t( f( U8 T( u+ Y& ]0 [0 X                if( output > max ) max = output;
+ w% O8 X8 `  ^; d$ b                if( output < min ) min = output;% [* o+ J* v1 P  O) _
                ave -= ave/1024.0;
: N; G4 B4 c1 U& n, c# O, n                ave += (max+min)/2048.0;
# ]% W% t1 M9 X4 ?, X  U/ J: W8 P                output -= (INT)ave;
' Y5 K1 y" h- s5 Q7 v% z                }
) {, z) c* A6 p- f" r#endif. x- U: ^3 Z- b4 I+ j
#if        1
- Z$ a! I( Q% u9 I) A                // DC惉暘偺僇僢僩(HPF TEST)
9 l) w/ @% b# _. @5 ?  [6 u2 l                {
* I* F, e5 K% z1 B) V( j//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
7 V3 _1 K6 C) D* p7 }. R                static        double        cutofftemp = (2.0*3.141592653579*40.0);
! ~2 r; G& B: m                double        cutoff = cutofftemp/(double)Config.sound.nRate;4 }% d" h. Q- Y9 @$ s  ]; p: u
                static        double        tmp = 0.0;3 O6 q+ ?; u$ c6 q) A6 A# o( V; s
                double        in, out;5 U- z: u7 n' j$ n5 y9 I
( `# N) m) q, y& N
                in = (double)output;# s4 W) a! K# q
                out = (in - tmp);& A9 S) k2 i" k$ J; t
                tmp = tmp + cutoff * out;" S6 o3 T- o2 {( b* u/ O
3 e  N1 B$ c: l" @
                output = (INT)out;! X! Q6 ]( S$ e( j. l! ^' J& m# n
                }
9 |0 S( B) K: H#endif
: B  q% g) C  p& z' R: l8 K#if        0
0 ]7 [( [  c2 |  i# K8 A                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
' |5 ~9 c8 M/ ^/ o                {5 C4 M. w$ Q" L
                INT        diff = abs(output-last_data);
% J3 _* s2 l8 m& y1 I+ Y6 \                if( diff > 0x4000 ) {1 d1 h, w! Z4 t+ j" S0 `/ P
                        output /= 4;; ^& R' s5 B  {7 t
                } else 8 M  P0 w# a5 A2 i+ p+ @
                if( diff > 0x3000 ) {
. s4 b; V5 n8 p5 E6 E, ^! A2 c                        output /= 3;
3 O; V' V3 D; i4 |3 q, E1 p                } else7 ?+ n4 {* N8 z( X( J2 C
                if( diff > 0x2000 ) {
& n/ q5 l& s2 R& Z                        output /= 2;
7 A! \) a3 A" V# R, f- z2 R                }
+ E4 o% U1 N8 z( E+ i( E                last_data = output;) j3 J  d1 ]; E
                }, D+ b4 [- Y6 k- d5 d& p- ~
#endif0 G3 U5 `5 x/ P! X& z9 Y) t
                // Limit9 H; a+ n7 M' O, t0 T$ f: [2 g% L0 m
                if( output > 0x7FFF ) {
; C0 t( r, i6 l6 x' s5 Q4 a; I# L                        output = 0x7FFF;0 s) S# M8 L& M. o8 M( Y9 g
                } else if( output < -0x8000 ) {
- e. y: F! r; I( C' m                        output = -0x8000;
; X$ r2 L, }- \" p3 X+ |                }
: g1 i% j' T: G8 v
9 Q7 T4 ^0 W$ O) Y                if( nBits != 8 ) {$ F& t1 Z/ v, g7 q3 T1 n1 H
                        *(SHORT*)lpBuffer = (SHORT)output;/ ~+ @2 Y* {* _& h6 a" O  m3 z) X
                        lpBuffer += sizeof(SHORT);6 }1 s4 N3 `. y
                } else {! ]0 b( X8 y7 q$ S
                        *lpBuffer++ = (output>>8)^0x80;
& F7 s. d( D; ~" s3 D, o" V                }( S$ D% ]0 u3 l7 N2 a

- T- d+ z3 @! s, f                if( nCcount < 0x0100 )
9 C, x0 d: P* g( i. T, |# X                        pSoundBuf[nCcount++] = (SHORT)output;
  N9 ?9 d- Y6 g( F/ Q+ N9 }& b! O
//                elapsedtime += cycle_rate;
' L# s5 Y* t! P$ \                elapsed_time += cycle_rate;
7 W1 M0 _$ O$ R5 q9 d        }
' T/ _" t# B3 @3 l& \" p
" ~3 d' R3 X5 [3 D: P% L#if        14 b+ |0 ], e. `; a0 u2 b; {5 z- ^
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {' Z* I6 h$ [) B3 u
                elapsed_time = nes->cpu->GetTotalCycles();
* J' ^: U/ m# `' S7 \# }8 z        }
2 K& X' T6 }/ O1 U+ s        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
+ H( }! o2 f2 p8 A! _* ~                elapsed_time = nes->cpu->GetTotalCycles();
* h) C+ T  s+ ?" L        }
0 B+ X' Y4 Z3 }2 `#else
. ?" S/ s' c# a# T  n! X        elapsed_time = nes->cpu->GetTotalCycles();
# a, t* P, {3 B# ]* b3 c' b#endif
" C7 z# U# W+ }}- n$ l% b4 u: @) |/ X/ @
, q& ?' |2 @7 O- `$ c
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)+ v7 f; c4 n. C4 ?6 g  M
INT        APU::GetChannelFrequency( INT no )) k: C% T6 y  ~) y2 I, [
{5 ^* v6 r/ V, u! b1 E! b( J! |) @
        if( !m_bMute[0] )
) M" b& k& n* \8 `- b                return        0;
& V- d' g9 b2 k$ n/ L8 K% C% m
2 T5 D2 l- F5 V7 x        // Internal( G( ^+ z2 Z0 W, q, o( Y- |9 B4 U
        if( no < 5 ) {' f$ o  K# s5 O
                return        m_bMute[no+1]?internal.GetFreq( no ):0;! o; [. P8 F7 H5 }# x% K* m
        }% Y1 b! D  A' l( H- Q
        // VRC6
, q. C! n" @0 J* `3 t$ e" r        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
+ F8 s" N$ N4 e4 ~7 |# S% E# }                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;& _1 c" P" p' f9 }
        }7 h) n( I* W1 j; h% R
        // FDS, C, ~) j5 M; d7 f  E
        if( (exsound_select & 0x04) && no == 0x300 ) {
" |( ~% h3 Y+ x" T                return        m_bMute[6]?fds.GetFreq( 0 ):0;; ^+ m0 r: O/ O( B
        }0 p* d) C; s$ {- K3 O" [2 Z) y
        // MMC5
9 t1 W% k8 V! J! z  e$ U: q* t        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
3 x8 o0 Q# ]- k. i* N7 j# F                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
+ D& a2 F& x3 K- {        }
" l. V' a! v" i6 n$ z( ^        // N106# F  P) d4 b9 |! _
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
& H# p2 h1 q. V% P                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
; t$ S8 e9 t& d: b0 g9 k1 X( ^        }- B# E! v# H0 @9 K. I: U* [
        // FME7
% r# s% j& {  P2 [        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {6 `- P2 D; O6 w7 `: J" D
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;5 ^0 t) _3 K- S4 @0 I
        }
6 Z9 M; m4 |5 T! ]0 }  ?        // VRC7& k6 y, A( O! a! `! p" W8 A$ e0 U
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
+ O* _  e- h; D* Z                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;. D1 s0 _: t3 x) G8 a% f" E
        }
3 v: }# J- R) K. a9 |, k, T1 P        return        0;& R  m# @* Z: j' F8 f$ B0 a3 ?
}
0 F! v  h3 B$ i0 v
: {7 f% b1 i- A" h9 [/ A+ n// State Save/Load
, M2 `. T+ Q# P; W/ e9 Z' ]void        APU::SaveState( LPBYTE p )6 q8 Y- G$ J" x) \) ?+ }, b% C
{
, V: C( d2 q! P" v6 J#ifdef        _DEBUG3 h. ~( U8 W* z: r; c& O  w9 S
LPBYTE        pold = p;4 x; I. [3 C3 Q+ d$ C2 s" `
#endif
, t$ X/ q0 r3 h; `) v/ Z/ R; O! l; [: R' ]. ~& N5 L1 N
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
, o, [) z4 B9 A" k6 h        QueueFlush();- p. f4 A9 ^6 f- j3 i

: X  `1 g* T+ F! X3 F9 E  Y  k        internal.SaveState( p );
8 v2 l- Q; `4 N        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding# ~9 Q% x! l9 Z7 X/ F
" O8 [+ ?1 O- U* v
        // VRC65 r" Y& }. B& K. }9 o% T, R
        if( exsound_select & 0x01 ) {; D0 q. j( g- h' z
                vrc6.SaveState( p );' u. |9 y6 l9 o1 {8 S4 J
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding* ]* d: D7 ~7 H! R: I8 y
        }
" F4 O% Q, i' i' T# `        // VRC7 (not support)
; S+ \! L; Q3 w        if( exsound_select & 0x02 ) {
- ^* R' C) S  b" l5 }                vrc7.SaveState( p );7 u) w( Y- a* M" V( E, i! R9 F4 Y8 n
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding# {3 c1 t% B5 t9 U! W: A
        }
+ C( o. `: t, E% z        // FDS3 D1 Z# _. v! P' A9 c- L: s: g' T
        if( exsound_select & 0x04 ) {
* Y7 M9 V( }3 ^4 r                fds.SaveState( p );6 T1 Q8 p  k; G
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding" o& G% L2 K- }* b' n
        }8 U4 P. {# P+ Y$ x. ^; l
        // MMC5
8 P0 @( l% g4 Y0 e: j8 D% f; s        if( exsound_select & 0x08 ) {
: T4 N+ l" A' `7 D: T' x% e                mmc5.SaveState( p );
' C  s, s) W9 L4 f8 i. I                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
2 E! x5 U0 Q9 u        }
2 a& I5 m. g# n5 h        // N106  H- T0 O& g. H: j( V; {
        if( exsound_select & 0x10 ) {
% A8 _  [1 |2 T2 a# C3 w3 R2 I* v! x                n106.SaveState( p );/ d. [' c& [8 u! j; \0 Q
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding, A- Y0 }5 a/ t: Z6 w
        }
- T- ?! Q  S  F  u/ h7 _        // FME7
- m* _$ u9 |# {& R  F        if( exsound_select & 0x20 ) {$ f- s8 [7 M" e5 H" E. m
                fme7.SaveState( p );
# s- Y- E+ X  _                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding  z* W6 W! s/ g: q8 C/ y
        }
" D0 x( g7 \( y4 |
. o( ]! g( @' Z( f* I% h# s9 ]1 c# b* l#ifdef        _DEBUG7 v7 ~% F9 Y& Y, Y" n6 z
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );3 C3 \! Y- t, J  y9 i! p
#endif
  U8 {! f' m0 ?/ {* y}  }1 \9 l1 y  m6 }( f1 G

/ d) r0 t( h. L# E4 e- w- ]void        APU::LoadState( LPBYTE p )' j: l* {& d: a8 y4 x+ ~
{
' n, n$ k6 i, _6 L        // 帪娫幉傪摨婜偝偣傞堊偵徚偡/ r- h, u9 S4 G/ a
        QueueClear();
( t8 D, d2 \5 x# T- a) f8 v. p( d7 F" j) w+ g& K! D. H) Q
        internal.LoadState( p );' W& X" g& H" h5 x# e5 `
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
$ @  D( _, \: ]$ b2 }: ?$ G7 J% t7 a: c- M$ v% b' b' s
        // VRC6$ V; ^; @* b/ {  h8 o. O
        if( exsound_select & 0x01 ) {6 k# K6 W9 `: B# ]3 R/ k. N
                vrc6.LoadState( p );
- Z3 [: n2 R8 e) _                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
$ ]3 `6 M8 `; g! C- o        }
- K5 C# i7 r$ p1 Z/ i. m        // VRC7 (not support)+ \% p: P; ~' C. i$ O; e
        if( exsound_select & 0x02 ) {
. J# G' P1 E. w) z  A! P                vrc7.LoadState( p );) A' q$ e# |8 f2 W/ U
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding, c6 J/ J5 d* Y7 i$ p
        }  ~' L0 j  v( n9 v' X
        // FDS& h; M; j- ~% m- I0 ~: @! K
        if( exsound_select & 0x04 ) {0 X; ^9 M$ f3 T: q) T" P
                fds.LoadState( p );% z8 `; g/ `% S$ z  Z9 o: I8 G' x
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding3 B. O1 |+ x" q6 J) @3 k9 Y/ s4 Q
        }% `( r1 R) |: N, k, J. }
        // MMC5; N8 n, S! @( g! K( R% A
        if( exsound_select & 0x08 ) {' Y5 b; z6 j1 A+ p6 |0 m
                mmc5.LoadState( p );
* C, |/ d; M$ G7 f                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
4 |1 q2 Q, @, r! l8 g! U        }
, _5 p' W1 v" w: Z: T. F        // N106
+ o2 ?7 r* w1 z        if( exsound_select & 0x10 ) {
$ |7 D5 ?+ ]; I% h                n106.LoadState( p );
1 x; |/ }8 n( z( a; Z7 ^                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
! S  a: n0 X) t. O# k        }
# C; S$ ?; R& {' U9 O        // FME7$ H  x6 m8 y& c- w/ @  K- m/ h& d
        if( exsound_select & 0x20 ) {6 i+ E, x3 ]2 o) r" o8 v+ I( C
                fme7.LoadState( p );
6 o2 F/ N. i2 U$ o/ E# r1 j                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
8 g. T, ^- p% k* {$ d        }9 y: B. n1 R9 B+ W' F/ u8 J8 O
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
. v/ f; L/ [9 S  Q: F7 _8 {可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。0 v8 c# a& g( o/ }. R0 |
感激不尽~~
1 a4 d$ {, z, ~
恩 我對模擬器不是很有研究,
( ~5 N& u( J7 h雖然要了解源碼內容,可能不是很困難,: N4 R" C  W, ?: C; D8 Y
不過還是要花時間,個人目前蠻忙碌的。! B1 j$ h5 ?* T+ @# u5 T
3 T$ Z0 l$ [! n6 d( {, O
給你一個朋友的MSN,你可以跟他討論看看," i' ~2 b; c5 {" ?
他本身是程式設計師,也對FC模擬器很有興趣。
9 P. c. Y1 O) k5 T; W( x) t7 w5 Z- l6 n4 S% t- [6 g1 p0 s1 v
MSN我就PM到你的信箱了。% W) r' b- t' @, u2 L* h

( k6 B! V8 @) I% l1 n9 ?希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 8 r) i' i) x6 _! p) W8 Q  _' \/ O3 \
呵…… 谢过团长大人~~

1 w6 d! D2 w9 {3 t, H, t/ G5 C9 }: q$ k: o% V& `: b
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 7 M6 [8 B6 b! s" M* w2 |  |* J
团长的朋友都是神,那团长就是神的boss。
; o6 X2 C* t% c
哈 不敢當,我只是個平凡人,+ g3 z0 o7 t2 }( U4 d* m( Y
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
( u, _0 U9 d2 m* Q, v+ aZYH1 K8 t2 `% n$ l$ O: a
QQ:414734306
6 i% L+ l5 q8 g3 wMail:zyh-01@126.com
/ q' h5 z0 N) }/ \( A- Y( A( n) V9 ]5 {! f3 p6 _1 M, h
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
! _3 j$ C6 H( g/ J8 C再次对团长大人和悠悠哥的无私帮助表示感谢~~
: I6 w0 K+ E: f/ j7 x) C
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-2-2 20:21 , Processed in 1.124024 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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