EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。4 l# D, [1 L# s6 ^7 m' r4 O; _5 X
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
. f9 D) e. w- H2 ^$ B; q0 Z这里有相应的模拟器源码,就当送给大侠了~~
* Y: ~4 g& U. ~5 }9 K4 K; b/ Dhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 : ]( H1 C- j! ]) J! M5 m
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。  S, u' G7 Z! q+ N) V2 D* E6 n
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~! k/ X  r2 D7 s1 c% U- e4 C
这里有相应的模拟器源码,就当送给大侠 ...

  K8 H: H1 c/ v) c% k聲音部分(Audoi Process Unit = APU):
. S& ]+ C' n+ K0 f/ Y+ \" T! m.\NES\APU.cpp) ], |( m+ k7 M6 E- A
.\NES\APU.h, N% G, N% [% t8 `" R! A: g$ ~% U

- x+ `$ b# k* D6 u2 k7 X: W' ]1 q. b7 n1 Q2 ~0 v% q
影像處理部份(Picture Processing Unit = PPU):
; a, p' H" |( j0 Y4 V$ n.\NES\PPU.cpp  k9 @7 F" m- i6 |8 q' R" b! [$ `
.\NES\PPU.h4 ?  {" }. x" [- y5 j" r
+ T3 t9 A( |$ G& W, n. k
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
3 {( m, v/ U4 j  M! v' x0 D(由于很多专用术语和算法机理都不明白,所以看不大懂……)9 u. G; |7 h* j9 U
//////////////////////////////////////////////////////////////////////////$ r( O3 j8 E& f/ ?5 C, C
//                                                                      //2 U- x8 U$ U3 a. p! f; H
//      NES APU core                                                    //4 T* Y. ~' @# Q8 k8 v- \
//                                                           Norix      //; G2 s  i+ E4 Z3 J, ?
//                                               written     2002/06/27 //9 Z  V$ q- s( c" d/ F% K0 X1 O- M
//                                               last modify ----/--/-- //- m# c( T) A) J
//////////////////////////////////////////////////////////////////////////
! [4 b! D& q+ y. x% K8 [4 X#include "DebugOut.h"
# ]" ?5 e7 o- E/ O$ G, `#include "App.h"8 {0 F1 w' D% r* w6 z5 Q
#include "Config.h"* K" [: X  f9 P7 }
; g0 h* M( @# T4 d# G6 ~5 a/ k
#include "nes.h"
( k, _8 f* A- h, v  b9 ~#include "mmu.h": t2 d  ?3 N2 C( \1 A: H/ c* _5 q  @
#include "cpu.h") j2 [. {- q2 I" O% b5 ?
#include "ppu.h"$ ?! T" n1 C+ ?: G( w- i9 i
#include "rom.h"- Z; A& o/ _6 A( y2 A
#include "apu.h"
! q% S" b" a9 ]* h, S
0 B& e& E/ J1 c. m3 m// Volume adjust
5 [/ J/ q( Y! K0 Q3 ^$ _// Internal sounds
+ i4 j) n' |0 C* p; g$ U#define        RECTANGLE_VOL        (0x0F0)
7 `* b  B. H/ q2 ]" s9 ]" v( n#define        TRIANGLE_VOL        (0x130)
, i8 p- P0 R  h! ^) x6 X#define        NOISE_VOL        (0x0C0)' f  M8 s# ]. A3 m' g7 @3 Y: Y' w+ P
#define        DPCM_VOL        (0x0F0). L  q! i$ ~% \' Q2 N; _4 p3 b
// Extra sounds) g' M8 @# Z% Q4 S( a3 [. {7 Z! w$ U
#define        VRC6_VOL        (0x0F0)
8 M1 w) i% g' d- {#define        VRC7_VOL        (0x130)9 [) L' h9 d9 G9 f
#define        FDS_VOL                (0x0F0)
1 N$ r+ F4 ^" B2 c#define        MMC5_VOL        (0x0F0)
9 d  [- R, G$ ?* @" H( ^& t#define        N106_VOL        (0x088)
! ]$ a2 ]. ]- S3 V8 _#define        FME7_VOL        (0x130)6 f5 r( k- k! p+ H+ m0 Y+ O, b
: X7 Z- n! D8 B6 f
APU::APU( NES* parent )( g0 j! f5 M0 W7 N& I6 S
{
3 a. \& `- d$ \' A  F        exsound_select = 0;
6 k, o/ K0 m! Y& P7 w  V0 h
, o0 {' d9 x4 ~" \3 d; X! \0 {        nes = parent;
: _4 L0 F8 n" c        internal.SetParent( parent );% ?* c# c# \7 k2 B" a
- _7 P  H: g1 ~' v, ?* O9 D0 [
        last_data = last_diff = 0;
2 \) k  d3 D: N9 }0 q. y4 G; A: D) q' g! f0 ~1 ?7 x0 S- \+ N) ~5 b
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );  p2 u" }& F4 r
8 b- l8 G: j4 L8 P" K
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );# e; ~  T' K& Z% }
        ZEROMEMORY( &queue, sizeof(queue) );
( @$ [6 W" Z, s9 N0 a7 a) p- Y( D# [        ZEROMEMORY( &exqueue, sizeof(exqueue) );
% }+ P: U9 \6 v8 T8 Y/ j, \# y+ p, ?+ e! l* m
        for( INT i = 0; i < 16; i++ ) {. h6 k# D3 {  Q) D* e* d
                m_bMute = TRUE;
) f& ^) j$ c$ u( {, s        }+ }- q! W" c, A) N6 k3 ~
}
- D; K, G( D3 G6 P& T0 W7 j: ]8 z8 N9 W8 u- c
APU::~APU()+ B/ T1 g- x; F2 u! V. [
{  [, e# ^4 A. z+ M1 {
}
; p. L7 q, D) k% H% Q( E
4 F2 X0 c( }/ e$ W/ Tvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )9 x" c; w7 V, {' Q
{" I( f6 v1 F, o% ^! y
        queue.data[queue.wrptr].time = writetime;
$ S! v; Y2 ^$ S3 v' z# h        queue.data[queue.wrptr].addr = addr;
4 E1 W- i5 Y' b$ h9 |        queue.data[queue.wrptr].data = data;
$ m! M+ q9 k5 Q4 I- R& k7 C        queue.wrptr++;& s2 c* Z# E( ^8 Y- t5 `
        queue.wrptr&=QUEUE_LENGTH-1;5 c+ `/ I& h+ x7 O9 y/ {1 q% b
        if( queue.wrptr == queue.rdptr ) {
1 n4 ~3 @# z" M& Y  @: r* j                DEBUGOUT( "queue overflow.\n" );; ^8 D5 l/ F  |5 z
        }
% p% i& f( D: B6 O}, o# V: z, d6 n. u0 Q
7 c: E4 ?) k, N+ m, U6 b2 B
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
' o' j# }/ l+ v{
5 L* W/ x; U- A) e5 ?7 |# W  F: v- o        if( queue.wrptr == queue.rdptr ) {
) D8 p# }* U7 F% A* w' y2 j* T                return        FALSE;
9 P0 @/ S$ m' O' b9 @        }
/ C: k9 M+ p$ x1 E        if( queue.data[queue.rdptr].time <= writetime ) {- l7 Q* y' ]7 v, U5 M7 {+ U
                ret = queue.data[queue.rdptr];
" F0 }, o2 q" B: R                queue.rdptr++;
- Q$ w. G5 c. F. N                queue.rdptr&=QUEUE_LENGTH-1;
  f7 ~: r1 E6 ?1 g                return        TRUE;2 v+ {" E8 z2 p
        }. W0 ]1 R4 M3 l6 R1 x
        return        FALSE;
+ Z. M2 m9 r5 b3 g, W0 @+ @4 s}9 _* Z! A" P  }; r! ?4 ]0 k0 b* h, t. q

& K- c" W# Z/ x+ v3 c" R1 z3 p; tvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )1 s* [" R  R$ Z" T8 X6 O5 ]" H% b
{
$ {! B: |! N) b        exqueue.data[exqueue.wrptr].time = writetime;$ l/ {" v, A% t4 ^4 M7 Z# O. C* q
        exqueue.data[exqueue.wrptr].addr = addr;
0 J( q. @. e$ }8 ?4 b        exqueue.data[exqueue.wrptr].data = data;2 C% k2 Q3 r( x. L4 v; g
        exqueue.wrptr++;
- S7 P: D* b) v& q$ H        exqueue.wrptr&=QUEUE_LENGTH-1;+ v" s. L: D2 n3 F& |" L9 _
        if( exqueue.wrptr == exqueue.rdptr ) {
1 K: H# b# \. ]$ F. }                DEBUGOUT( "exqueue overflow.\n" );, {' g3 l& E- Z# I4 R# b
        }# D& m/ k0 m4 b7 f" n
}4 d$ H4 Z3 Y) x5 Z- p( {

2 G; N$ W: I3 D3 P- }1 A+ NBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )/ ~: C% y5 t# C* I! D7 b' ^- A& u
{
: W4 V% r5 S; Q4 U        if( exqueue.wrptr == exqueue.rdptr ) {) W7 A1 t* Y5 M: O
                return        FALSE;3 l, k2 {3 ^; P6 n: Z" Y" t
        }0 S! T# _1 J8 Y( r* I, |
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {6 S- I& g4 H9 K9 O5 \" \) }
                ret = exqueue.data[exqueue.rdptr];
7 N% W; A6 a/ [* p, Z2 Y                exqueue.rdptr++;
9 O! c3 J0 V8 ]$ r: |                exqueue.rdptr&=QUEUE_LENGTH-1;
( L% t/ V9 T& [- Y- |  m5 c$ u: O                return        TRUE;( E4 y, m4 J7 j9 ?
        }
6 d; H; r6 ?9 ~        return        FALSE;
# ]) w9 j; G& r5 Q! K* U}
& t$ J6 _$ X0 u# @8 w4 y; i6 k
3 \8 Q! m, N8 i( R4 Cvoid        APU::QueueClear()
- T. Q1 S5 T( ?" c- a4 f4 p1 G, m{
& j; _9 ~  G- U        ZEROMEMORY( &queue, sizeof(queue) );, D: _$ t% s( `! S. n. a
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
3 H/ o- i. r# w! {7 L' e}
# w! O1 q1 @, x3 h% v5 y- `# u+ }3 h1 W# C3 P( n
void        APU::QueueFlush()7 B+ N6 S" ]: D5 O) D: P
{& o2 b. k6 Q3 t0 D/ f
        while( queue.wrptr != queue.rdptr ) {
+ m% G7 `6 }- x1 h3 z+ L                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );$ u3 I) @( `& K: c! b1 C4 K: a
                queue.rdptr++;
+ B( o* c5 J. n  R7 v7 [                queue.rdptr&=QUEUE_LENGTH-1;- }- a) f3 I& y$ U6 o* H
        }
( K) n: S% B% d# Y5 @$ i$ s; ]; Z. c  I) R
        while( exqueue.wrptr != exqueue.rdptr ) {+ K9 H% ]! V. N4 D, Q1 p
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );0 D) c4 U4 q9 a" H5 Z0 {# T
                exqueue.rdptr++;, u$ n1 r3 k4 w
                exqueue.rdptr&=QUEUE_LENGTH-1;
+ g5 y( `% U( Z1 w4 T9 n        }7 p, x" s+ v, r% n! A+ H
}
2 l' b0 B3 O+ `+ v; B; Z2 x( P' B0 v
void        APU::SoundSetup()4 X3 z* H8 g8 ]( M0 T* {
{
! S8 u4 e8 e: ~, M7 t& R7 A; Q        FLOAT        fClock = nes->nescfg->CpuClock;
* L  c: C7 b( c3 s4 U        INT        nRate = (INT)Config.sound.nRate;
" Y3 N# f: e% E, U5 l8 J+ n        internal.Setup( fClock, nRate );3 U9 y9 P# b9 }2 j- q8 P6 A6 q6 e
        vrc6.Setup( fClock, nRate );( n+ F# B! i$ c1 t
        vrc7.Setup( fClock, nRate );2 U* o3 S0 {' G6 G( m
        mmc5.Setup( fClock, nRate );/ n( X# q- r/ }3 \: S) R, [
        fds.Setup ( fClock, nRate );
( C# s7 Y- G' J* U3 Y# q        n106.Setup( fClock, nRate );
0 C4 p& }( |& a0 c' {5 _+ ^        fme7.Setup( fClock, nRate );
3 |: z- m' h4 N6 @}
* ^  q4 D4 j9 h( \) V+ n8 K: [/ U% W! I  j" X9 \
void        APU::Reset()9 e, T: {# t& a: B
{
; N7 B  _1 k6 H; W3 i' r        ZEROMEMORY( &queue, sizeof(queue) );
, L# g. `2 m1 u+ P        ZEROMEMORY( &exqueue, sizeof(exqueue) );4 g1 D4 R% B9 R6 h/ d# P
7 x. T! [1 s8 |! Z
        elapsed_time = 0;
' H( ~* f8 l7 G: h1 F  s$ \0 r
  Q% W" V% S' ^$ M9 q* S        FLOAT        fClock = nes->nescfg->CpuClock;( T$ ~) a  d7 p
        INT        nRate = (INT)Config.sound.nRate;
8 T9 V! P! z" O  i        internal.Reset( fClock, nRate );
0 ]* n' O- z! P) @5 Y6 D        vrc6.Reset( fClock, nRate );
1 @7 F+ W% |4 r        vrc7.Reset( fClock, nRate );2 S. E1 ?4 m2 M* c5 u
        mmc5.Reset( fClock, nRate );2 n) M. u5 }/ f1 |. E
        fds.Reset ( fClock, nRate );  O: V: a% ^; D1 P6 T$ v
        n106.Reset( fClock, nRate );3 n) u7 c. \6 _+ a& {; P/ y
        fme7.Reset( fClock, nRate );  W& c. d' h1 N" P. i
" H( @. V, M' i0 m9 [# |! ?4 j
        SoundSetup();6 j. o# X2 H9 {( I4 C+ u* M* |
}
1 K& J- V8 b) u) g+ |: ~* K
0 {( F% G5 s1 [' Svoid        APU::SelectExSound( BYTE data )
9 |/ a% \& o' j6 }2 m4 {- {{
4 U, H' I4 e. ]( m7 @, |        exsound_select = data;1 U* A/ `" g- Q8 G% m9 F
}7 N8 @0 j1 e0 q2 Y( |

* s8 ~. d* x. p4 eBYTE        APU::Read( WORD addr )* E$ l1 Z' |; P3 Y1 r& F$ _3 E$ i
{: x4 ]1 J* m9 e. F! a
        return        internal.SyncRead( addr );
# X; `; a1 `( |! `. A- S}
4 Z- H) B% @' m+ ]  `7 s6 [1 C0 I" j
  e% x! _9 z" d" Uvoid        APU::Write( WORD addr, BYTE data ): e2 `2 E8 X. |) ?; ?0 [
{
0 g. O" \# b- ?& K0 x/ X        // $4018偼VirtuaNES屌桳億乕僩# w4 S6 Z7 u0 Y
        if( addr >= 0x4000 && addr <= 0x401F ) {9 e$ G7 i  t$ C6 K# r% \
                internal.SyncWrite( addr, data );* P3 d- z* y* g4 S1 m/ K( B
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
" x: Q0 a- I1 d: U4 U3 ?& O) l, v        }& C# H0 y7 ~! g, m, U
}
; j' O0 z9 S) z! N% r
4 g4 G) Z: A" ]5 bBYTE        APU::ExRead( WORD addr )4 `. e- d, m4 C) s8 @2 r6 c
{. H) I3 R) ^, o
BYTE        data = 0;
, z: s) ?  J+ B1 Z
* v' [! S/ ?# ~/ a        if( exsound_select & 0x10 ) {: P% K3 n$ p! i# u! f3 F# n
                if( addr == 0x4800 ) {5 J( F) [1 z% h' ]9 V! _
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );4 H; ^! ?2 C8 A! o6 E
                }
) Q3 T& J1 A" t3 x" i" L        }8 s2 t' y0 S, n% J! C) T# H
        if( exsound_select & 0x04 ) {
% h  J) @" a; E6 O# i- @                if( addr >= 0x4040 && addr < 0x4100 ) {
, Z( R2 {3 Y) j( }# U                        data = fds.SyncRead( addr );
4 }' H/ N) k( P' p$ ]5 F+ @" W/ x                }& G% l! m* H) p8 ?5 @
        }
+ i) w1 E" y$ d' o        if( exsound_select & 0x08 ) {% F" q6 t( r! e7 ~) x% p
                if( addr >= 0x5000 && addr <= 0x5015 ) {$ n9 L( Y/ {' p; T" _- D
                        data = mmc5.SyncRead( addr );2 r, ?, I3 G' m6 h6 {' H) K" q
                }
5 p- f5 a( G! S. {! H) E* f- x        }# I, e5 c; W9 |& l6 g9 ?5 V$ x

7 D8 i) g" [. L4 D/ l        return        data;
! I# n0 s, k& ~% W' T}
; `& |0 b& p! P- }  V1 s9 O
3 a' Y; v; `) N& T) s3 \void        APU::ExWrite( WORD addr, BYTE data )
1 r5 o' v$ c# N: u7 L; m* {{
& L/ Y8 j8 w' p' M% s        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
+ K) R/ c9 u* r4 m( u3 @$ s+ v
6 k* D/ D, j% y3 A        if( exsound_select & 0x04 ) {
# ?" @9 m0 }8 `# J                if( addr >= 0x4040 && addr < 0x4100 ) {
# ]. Q" _% f* c, ?- R; l                        fds.SyncWrite( addr, data );
0 K9 j$ A; y& S& J' u* m                }
/ D( m! V) Q! u: ?        }
6 R& T! x# Q: Y. \3 k
8 R( I2 k# e, Z, _3 C        if( exsound_select & 0x08 ) {- J" o; B- {/ _3 Z  p* E
                if( addr >= 0x5000 && addr <= 0x5015 ) {
/ G/ y5 A) D1 r; z                        mmc5.SyncWrite( addr, data );( h( N$ C, _& C
                }1 \/ K0 c) R6 x3 |/ B  B! q0 \+ C
        }
+ b8 N; G' q, Y  X( ?}1 M$ J# v6 g* p3 c; Q* d/ o
& i6 f9 W& u5 f
void        APU::Sync()
4 A. }5 d9 m- a{4 [, e8 Z" i8 `' h( [3 T3 e
}
7 O4 q  P4 p& y3 t9 {: l9 P" Z5 c7 K9 `
void        APU::SyncDPCM( INT cycles )  Y) R1 m9 q# j7 _9 T5 ]: R0 D, t
{
9 `, _# g# y# c" F  h4 J% k        internal.Sync( cycles );# s% x4 T8 [( k( `4 [2 J( j3 J3 d

$ d7 d. Q! {# l* B* V9 `& m+ f/ V        if( exsound_select & 0x04 ) {1 `$ x$ O0 j- |( y: v
                fds.Sync( cycles );9 t, ^! Z7 ?# H7 S
        }
% x; {% ]6 j8 l- N# j. [. b        if( exsound_select & 0x08 ) {' G+ w+ W, }  K* z) A
                mmc5.Sync( cycles );4 T; g) O$ B  |$ A
        }; j/ k5 q9 \8 W6 ?  B" z% |7 Q
}
2 @7 ?0 v) H  M, r
: P6 x+ P# z$ Y: `void        APU::WriteProcess( WORD addr, BYTE data )& ?# s3 g( _8 l7 S4 j' o  w2 u
{8 w- Y/ r5 X7 e6 [1 B
        // $4018偼VirtuaNES屌桳億乕僩# t; t+ M& d* A
        if( addr >= 0x4000 && addr <= 0x401F ) {- H8 b1 A" I# I  U  l
                internal.Write( addr, data );
3 ~, T8 m. T4 J8 k7 R        }1 N* w7 B( N* h- g) s7 b
}
* s# V; D4 R* R- N5 [
7 d$ m" i- Z" xvoid        APU::WriteExProcess( WORD addr, BYTE data )- P! _' I- o9 O: B% n0 E" v
{
) s8 y" t; S5 l) z; R- R& z        if( exsound_select & 0x01 ) {9 [3 e  m7 f. A. s3 }' j% D7 E
                vrc6.Write( addr, data );
8 I0 G6 B; N0 l6 W% p        }
/ M# A& t! \! y# H# D1 V& z        if( exsound_select & 0x02 ) {
+ y) V( k% @; I3 d/ ^% G& _* T                vrc7.Write( addr, data );
: `% G8 T; @! Y2 G+ O4 ~        }
: l2 \2 x& U8 I# d! l4 I        if( exsound_select & 0x04 ) {
. A. Z, R- c2 N$ M: A                fds.Write( addr, data );
7 u7 Y- {9 V7 {$ X# @  }        }
) i# _+ J# y5 h2 N+ K        if( exsound_select & 0x08 ) {3 Y; @1 p  y1 A1 y/ \) d7 U
                mmc5.Write( addr, data );0 q" ^! w' `6 Z  \4 z8 W! W6 @
        }9 K( ]# z& o8 l, X# `
        if( exsound_select & 0x10 ) {  P6 `  R& d: Q7 s, p7 S
                if( addr == 0x0000 ) {  J. v. M, T+ W
                        BYTE        dummy = n106.Read( addr );
2 Y' K6 R1 l- N6 f; |1 o0 o                } else {6 E/ r) K8 j: P/ C8 t
                        n106.Write( addr, data );
$ j& B8 _  ~% i3 i9 v                }9 o8 b7 Q3 u) {; k$ z1 o0 a
        }+ I7 M( w( P- j
        if( exsound_select & 0x20 ) {& J; o- @. k% ]5 y" ]+ d
                fme7.Write( addr, data );/ V# }0 l/ B8 V+ }$ h
        }+ Y( T% Y# h. L; o0 k/ p
}
: l4 @# }# D, `7 ?6 j) Y5 ~9 l3 Y
7 A7 `6 Q0 }& u4 s; G; |void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
+ m  o2 M9 t5 G3 M& l9 a2 T{+ u8 ]* `- I& v& [! X. Z- s. f3 g' d
INT        nBits = Config.sound.nBits;: I( j/ X# L( A5 Q
DWORD        dwLength = dwSize / (nBits/8);/ c: W' \, N9 O8 f9 i6 v
INT        output;
. @* B( R/ G9 |7 M1 H, CQUEUEDATA q;# T- g! n6 v- u: N3 P
DWORD        writetime;
2 g$ u# t. T& N, a$ c2 C, @! \2 _, G1 G: i2 u! T% G
LPSHORT        pSoundBuf = m_SoundBuffer;
4 E% g6 ]/ A( L- ?" d! lINT        nCcount = 0;
3 q/ Z. T$ ~% V: P0 m( U7 S* D8 P! B3 c; E
INT        nFilterType = Config.sound.nFilterType;
( d' y1 A( P" z( ]8 j
6 K- E: q( x7 N1 j8 t        if( !Config.sound.bEnable ) {; Y& L" g# I1 q8 t4 {
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );, f# ^3 j5 o# M$ g0 L9 S
                return;- C9 j2 \; k$ H
        }
! w* e* `! K4 g/ n
' F* u/ I) r1 P+ E( f( S0 ~3 E        // Volume setup% G. x8 ]7 K  U( f; `7 v) z7 i3 K
        //  0:Master
; z+ @( l1 ~, k- I% g        //  1:Rectangle 1( B7 h$ q9 Y) l* O# B# p) Y
        //  2:Rectangle 2: m' j4 C/ P# L+ W
        //  3:Triangle( S" d5 E$ m/ Y2 i
        //  4:Noise! \/ B4 S0 Y: R$ X$ \( H
        //  5:DPCM7 x, q0 U& w$ Z* p
        //  6:VRC6
* K& Z2 y: F8 n. {4 [        //  7:VRC7) o& J: M" ?2 t3 H- [6 C
        //  8:FDS
" Z4 v3 h6 r0 S        //  9:MMC5
6 p2 f! t1 {4 }1 y1 F        // 10:N106+ H  h5 }- {2 f- Q; {
        // 11:FME7, P# ?% F- t9 v2 Z3 p! J6 c* w8 R
        INT        vol[24];
& V- b4 I7 f: \# Q, ^        BOOL*        bMute = m_bMute;- W0 o1 L8 ]/ t. _# |& L$ `* h' F
        SHORT*        nVolume = Config.sound.nVolume;' q3 d6 m9 G2 S/ S6 P  U

3 T9 p9 R! m8 L& ?& V        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
3 h% T* v$ @% g3 H# f2 ?/ W& _1 d5 e! u
        // Internal! u8 R) Z8 |  _
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;" v" A! ^# P) D. r& T
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
1 y- q6 v* C( w5 z& g        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
! g% T7 O9 D7 D7 M' ~        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;; E* L) a! b' {' c
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;2 U) ]# j" O; h+ h7 w

- O! P( |' R1 l  `! \! U8 ^        // VRC6
. z' @0 J( |6 R4 B        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
; ?8 H/ @' s$ R5 _; f/ s# p4 K        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
4 A, a, B! n5 h        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
, I- Q- Y% Q- k( O4 j! h" w( H' R4 s1 E% I
        // VRC7
/ S, b+ }9 ]2 ~3 R" _        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;6 M  Q! p, c( A6 T+ Z3 `
7 S4 t( N( H; }1 _/ k3 m
        // FDS$ @2 M; U3 W8 N) K" K7 l
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
' s2 _' I9 N& S  x
2 n' n; _, s  W( Q5 ~; v: |! X1 R  I        // MMC5# W% o! Z! o/ t+ J. _1 t
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
. f5 s, M- D' @' ^        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
6 k7 }+ ^0 U3 Z# s, n$ {        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
: a; `( @4 H% y  p: j7 n! Q% A; l8 H& O2 t
        // N1061 u0 Q/ F  s" x( k8 y  i
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. w. d* Z' {% u" E' ?" K9 i  }        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
) T" A* x! b; n- G& w3 M' S+ ]1 d        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;0 V: l: m$ l4 Z7 U
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 b8 A. ~+ D/ {6 @% G        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. j4 ?' n) n/ e$ ^9 t5 D' n/ G6 @        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
6 {( @. L% V( C: @% o        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;5 h6 u! R& H. g
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;2 b* a# N- ^! c8 [

( P! ?2 ^; V# o2 M0 s, `        // FME7
6 U5 l+ W6 w, n' P6 R/ R9 o5 F, F- I% r* e6 K        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
# m- v8 {& X' o9 H/ B% [! l, C        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;* N7 A! n3 B" T2 V! k
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;' f: I# d5 k+ [( g. K
2 I9 }  g% f+ W  X* `" B! Z. {" I
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
; T0 j* d  f) ]+ U        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;& H* C: o$ M5 K3 c1 H4 I9 G

: i7 f$ W) O9 L( w( X* `- b        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟: ]. n( L5 t; K8 L- }
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
2 y+ p- X" t% U/ q0 K                QueueFlush();
+ o" U9 e5 Q! i        }3 L: s) Q6 V! U) Z$ f' `
* C* V2 z% }# f& T' }
        while( dwLength-- ) {6 @/ o/ I0 ]- }  D
                writetime = (DWORD)elapsed_time;2 Q: b9 ]" S* d! o; m6 P
& `, N9 @$ a6 Z
                while( GetQueue( writetime, q ) ) {
6 c  E5 _8 u9 H2 r                        WriteProcess( q.addr, q.data );  B' D. g; \5 d. q8 {
                }
' \0 D! P, z* a0 n
) l3 P. h! t' G6 F9 r9 F7 _( w                while( GetExQueue( writetime, q ) ) {
  |) Y; N( ]8 q% @                        WriteExProcess( q.addr, q.data );
! i" }9 q* }: n4 j" K0 y                }
; h7 o) d' j% X" G* E7 [7 A6 A
9 u( u6 N' c# `. Y* X                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME77 ~- C- b6 N9 ?& ?) W# X5 R2 H
                output = 0;1 p! o, i7 b9 G0 m
                output += internal.Process( 0 )*vol[0];
, q4 \* C) J" j* x7 z: {4 e                output += internal.Process( 1 )*vol[1];
5 X4 u9 x! z! i                output += internal.Process( 2 )*vol[2];8 }, C+ h" v; P' p
                output += internal.Process( 3 )*vol[3];
( ~/ g& m) h) N0 q: R6 e( a- j                output += internal.Process( 4 )*vol[4];
8 H; }7 G4 M# E' Y0 F; V* D5 D3 x* g/ v
                if( exsound_select & 0x01 ) {0 J: E4 u0 ~3 M8 Y7 s$ O7 |
                        output += vrc6.Process( 0 )*vol[5];4 i8 a, V: d( ^; N
                        output += vrc6.Process( 1 )*vol[6];
- p7 B) o$ U5 b, z% P                        output += vrc6.Process( 2 )*vol[7];
6 \/ _7 r0 h' F) g                }) `9 Z/ H  {2 A* ^" n
                if( exsound_select & 0x02 ) {
* e2 e$ A& ?1 `+ K8 }, k7 Q                        output += vrc7.Process( 0 )*vol[8];. h! G4 J: K' w5 a. l/ S: U
                }
+ C' ~1 ^# ~* _4 e  B3 B& w8 B                if( exsound_select & 0x04 ) {7 y' Q7 O& u% W  i
                        output += fds.Process( 0 )*vol[9];
4 h& o. g, J1 L4 c" k; w                }6 k8 v( D7 f" Q% p' v% A
                if( exsound_select & 0x08 ) {
7 o5 g7 H* l- r2 s0 |                        output += mmc5.Process( 0 )*vol[10];
- O; f* i- ~7 ?                        output += mmc5.Process( 1 )*vol[11];. l! k$ v* O; y
                        output += mmc5.Process( 2 )*vol[12];
' b0 I, B& F, x5 {; l                }
6 m3 U# `% G* z                if( exsound_select & 0x10 ) {& }' E. N! N, `
                        output += n106.Process( 0 )*vol[13];8 |- v7 |& I) C+ K; @
                        output += n106.Process( 1 )*vol[14];4 ^3 L2 L/ h) [$ [
                        output += n106.Process( 2 )*vol[15];+ x) ?) t4 d: B( K) q
                        output += n106.Process( 3 )*vol[16];
( N" B2 T- K6 A7 U+ y% }                        output += n106.Process( 4 )*vol[17];0 Y0 U$ s% U. p9 r- T  h) i. X
                        output += n106.Process( 5 )*vol[18];, p. m$ g: F  ~
                        output += n106.Process( 6 )*vol[19];
: [" o" n$ k/ y- _! ^" i4 c                        output += n106.Process( 7 )*vol[20];5 F/ s& k% W/ G* X1 q) J
                }
$ A9 t. W3 o) c1 X7 m' H; c                if( exsound_select & 0x20 ) {; k; D8 y. ~9 g+ S2 h: I# P
                        fme7.Process( 3 );        // Envelope & Noise0 D8 Q( R0 n8 W1 k& G: w
                        output += fme7.Process( 0 )*vol[21];
) |/ h" _2 w& m0 W  x& l                        output += fme7.Process( 1 )*vol[22];
6 ?# Q+ y( U. y1 z. L- `                        output += fme7.Process( 2 )*vol[23];! ]) k7 U% c. V# d
                }" q5 S: n/ [4 B( r: Z9 u2 G" b- p
' ^& O+ u- P# w4 I* C6 |
                output >>= 8;
) o0 L, h6 L9 U% V6 w& B2 v+ l7 }3 L# F
                if( nFilterType == 1 ) {1 p0 c6 |9 ^" m+ t0 A: j' p
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple), E3 M% P7 N5 a) m. l' O4 o3 S5 v
                        output = (lowpass_filter[0]+output)/2;
4 V7 O" @2 V* V# V& d" k9 L                        lowpass_filter[0] = output;. I: J) C3 P* R
                } else if( nFilterType == 2 ) {
* p5 {% A! B9 }& J9 z5 n                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
  S* L7 Q9 x/ X$ _                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
$ _# v4 i, q# k                        lowpass_filter[1] = lowpass_filter[0];* Y/ p$ j7 S" B
                        lowpass_filter[0] = output;
' Z7 c* M: c8 @                } else if( nFilterType == 3 ) {
# E/ h) H  A. t                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
5 R, G: z& U5 r/ x* O                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;+ n8 a' r4 M7 g$ F
                        lowpass_filter[2] = lowpass_filter[1];+ Z+ i( ?* f7 v7 W& x1 m
                        lowpass_filter[1] = lowpass_filter[0];6 ~7 E1 Q  q0 d/ p
                        lowpass_filter[0] = output;
% T6 R# A- f3 `3 d$ N                } else if( nFilterType == 4 ) {% j, N1 f/ E) e  }" Y' M- N
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)3 V$ E$ n. S* }, v
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;% w/ y+ B7 k/ A4 s; u6 ~; {6 M' V; N
                        lowpass_filter[1] = lowpass_filter[0];/ s7 d4 N5 {5 H; g4 p# n. p
                        lowpass_filter[0] = output;' q; W8 `) m' E. j# k2 l2 u
                }
8 g7 @# ^9 w+ X0 \( v  j
5 V. X2 k  b# U0 Y#if        08 b! o. P7 x+ ~9 c" s0 i
                // DC惉暘偺僇僢僩
, ~2 w6 F7 m9 z                {
/ @6 n% c" R1 t                static double ave = 0.0, max=0.0, min=0.0;
9 N; [# j/ \' s2 _. v' ?                double delta;
7 P# \, h3 J5 }6 x9 I                delta = (max-min)/32768.0;
  v: `& f9 C- p+ |* \$ ^6 v+ L! Y/ y                max -= delta;
1 H  `- B  v# N$ K* o                min += delta;! H& N! ^' Z$ B: P. M
                if( output > max ) max = output;% [9 |0 N# k& k) G
                if( output < min ) min = output;
: d7 F: w3 P/ E                ave -= ave/1024.0;& e. h) d1 ^* ~8 r# Y
                ave += (max+min)/2048.0;/ v: R2 s7 [/ \$ I( W
                output -= (INT)ave;
# M2 z- c* N# R! a' Z! X                }2 Z. A' E( R1 `% O
#endif2 Q7 k, y0 n/ Q, K# S  h  z
#if        1
# r0 Q1 o) p  t! ?, E                // DC惉暘偺僇僢僩(HPF TEST)  A. n* ~/ t7 l& ]. n+ |
                {
" j* X) T8 g; z# ^: D5 }//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);) @9 Y% B  h, A7 g3 {
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
1 K9 ~5 a. @) `; Y4 t* N                double        cutoff = cutofftemp/(double)Config.sound.nRate;. w6 M0 S4 M. Z) E/ i1 H
                static        double        tmp = 0.0;
+ @, i& l2 r& w4 p8 Z                double        in, out;
6 {2 s3 C" ?$ g) }& t4 E( \( x8 t- O5 k4 i* ?- Y
                in = (double)output;
3 s* R0 s1 h: t$ m4 x                out = (in - tmp);4 |' a) ?9 a; \, r: w- @
                tmp = tmp + cutoff * out;# {* d  n4 N& @" O7 ?2 s4 _
5 M" Z$ s; T! q7 }8 k) n; ^& k  d
                output = (INT)out;' I7 k- c$ k5 z0 [$ }- U7 o$ [" \
                }: K2 A5 C0 K; F# s: Q
#endif
- C. Y; v7 P; |) b$ j#if        07 O1 b; G0 D1 U) T
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST); j9 B7 n9 K5 b- B1 G% o
                {
$ Y) S2 b. {% S1 E' B& }                INT        diff = abs(output-last_data);
( [& a3 H, G7 ]3 I: [3 s" X9 Z9 b                if( diff > 0x4000 ) {' S5 }- {" W/ ~/ ~$ x8 b# R+ F
                        output /= 4;
" N2 g1 k% r8 W) [' o* U                } else
" a5 e+ v5 w$ D2 C7 m. w                if( diff > 0x3000 ) {; v' v/ x# q: V9 {! g4 V
                        output /= 3;
/ q2 T- ^: u, A- x5 I! J! V                } else* d7 ?. D8 H7 ^) Z) f5 f
                if( diff > 0x2000 ) {. x3 O& E9 t  \9 Q: L( _2 j( L
                        output /= 2;
6 f* U# D) |+ g8 m                }1 Z% o& n4 o3 I1 V# t
                last_data = output;# P+ A9 Y0 D7 z2 R
                }
3 T8 Q# C0 {: g3 e! ~#endif
) p$ n3 O/ m8 A7 ~' E8 i                // Limit. q# D3 n9 X/ d
                if( output > 0x7FFF ) {
7 O1 g2 ^: J3 S                        output = 0x7FFF;; s# i5 h3 b) q, H. B
                } else if( output < -0x8000 ) {% \, p, t5 `0 `5 q2 N2 \' X% o
                        output = -0x8000;  j2 y6 E6 z3 [" @7 @
                }$ O" k4 ?2 ]3 B
9 V1 j* c# t7 M3 k+ ]
                if( nBits != 8 ) {
, k* q7 g" ?2 E. ~# ^                        *(SHORT*)lpBuffer = (SHORT)output;$ o: k5 V' C) f' m4 }! r% s) ]
                        lpBuffer += sizeof(SHORT);4 {  O; L# {/ G, F
                } else {1 U6 g: R) A; G$ x' F* @1 @6 A5 g
                        *lpBuffer++ = (output>>8)^0x80;
) {. i: w' Z7 ]5 S, i1 V                }
# L- m$ A) N! w) D: ~! T
. o" x, K! y# J1 r+ K( U                if( nCcount < 0x0100 )
3 G( Y& |3 A1 j0 W; D  Y" h; f8 m) k4 y+ T                        pSoundBuf[nCcount++] = (SHORT)output;
. S% P9 J6 m6 F) A/ q$ P' Y% C6 T2 o. G; N: G
//                elapsedtime += cycle_rate;% \, ~. U4 R$ ?5 D
                elapsed_time += cycle_rate;' P4 Z( B! ]% b& {' ^
        }8 Q  r- I$ ^3 {9 F
6 j2 n, r+ g. E8 F
#if        1
4 C- p4 T2 t/ z3 N5 ~9 n        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {$ C) E3 q4 z, ]% l" l- z# O* ^
                elapsed_time = nes->cpu->GetTotalCycles();& D5 R# B! K& T- V; Q
        }! @: H& B- M$ A( G
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
  u& k5 d) X- q  b6 H! b. `" R( l8 v                elapsed_time = nes->cpu->GetTotalCycles();
. V, J  m5 x0 @7 r( S' b        }$ R* D4 A8 ^: Z, n. s3 _
#else# Q1 S2 S" X4 V1 s$ D
        elapsed_time = nes->cpu->GetTotalCycles();
+ P2 G; m( j% |1 I( c& P#endif- ^- w0 X4 y; g# c" t- w
}( _. c  `7 h9 K; o4 N% i; n
/ Z8 ~( ]+ X4 }! Z
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)2 G+ P) h; P' a4 w2 H9 }7 e% a
INT        APU::GetChannelFrequency( INT no )
; F8 W0 {3 V: a4 O+ x{
& x! ]+ N# V& c+ H        if( !m_bMute[0] )2 `( X' j& U9 b3 \% y% W; I3 e
                return        0;7 p, U# i* v0 n% K

' k" H' T4 \, a9 ~, G4 r- h. o! c6 N        // Internal; @) g& {  c( ^3 `
        if( no < 5 ) {3 c8 E& b/ I3 ?5 V9 K+ V
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
3 x" f7 D" c, M; i/ P3 j        }
, B  ?; P% S" R1 e& R& v. Z$ j        // VRC6" U8 Q: O. K( @0 b2 W0 T$ H# G6 W
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
& l" M3 q! T4 ]: j                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;8 ^( G5 Q/ I: r7 k; w1 v5 r
        }
5 D- ?' e  P  ^$ n. P        // FDS
) Y! z; I& x- n/ J        if( (exsound_select & 0x04) && no == 0x300 ) {
0 k/ y6 R1 Z% I2 s  _. P  p0 f                return        m_bMute[6]?fds.GetFreq( 0 ):0;! P3 j* ?- i- U$ C2 d# L8 n
        }+ ?( q* X# h/ J  ]8 x+ S; K
        // MMC5/ }, z% l& F5 V1 a& b
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {+ Q8 F) d; f( _. Z
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
2 ^- U3 [  l! P$ L. ^/ v, ?% x        }& }# S! y  U* q' h$ A6 u
        // N106
9 I: [0 q% ~4 U+ l        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {* e, L, I! U1 j; r7 Q" K
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
  |5 r+ `4 l- f6 D: m' Y$ z0 L8 V        }
9 }' X" S  |$ f5 p, ~1 v        // FME7
) T' T) T) p. i3 F        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
7 m0 E  t; c5 O1 Q                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;. {# J- U7 W- I% U5 s
        }
8 p6 k( A/ ?/ _) ~; N( j( U3 Z, t        // VRC74 Z& a$ S4 l/ W) d1 ]+ J! ]- E0 c
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {  g" s: `$ ]5 r+ U
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
" [; i- F1 g  o" O! ^; x        }: [2 }3 X; J3 x* a7 R8 ^6 _* |
        return        0;
: k; s$ D7 x1 |) D5 ~+ n: K. S* H}
) J( M2 m$ S* |5 Y9 P& w5 k/ O+ Q. j$ Q3 s5 m, L
// State Save/Load
# b1 ^# A) H+ j4 P" |void        APU::SaveState( LPBYTE p )
% l% ]: v7 J1 v{5 z! ?- z# Z5 L. r
#ifdef        _DEBUG# k: ^$ T* a# M& U% s/ w7 i  D
LPBYTE        pold = p;
8 `2 ~, |: X  V" W#endif# R- U: z- q4 T/ c
- U( y2 p* u3 t, E
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞0 ], [3 c* z+ H9 z# \% r1 G
        QueueFlush();
1 C) s1 m, V, e
* J6 L( \- T+ Y5 S9 l        internal.SaveState( p );$ z9 S) h3 I( O9 @& ?0 o# P4 H- C' z
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding" g, Z3 ], T4 _6 u8 j* U: ]
5 L* z2 L, \* d# E
        // VRC60 n+ S+ \2 _" v- u% h5 J) L/ Q
        if( exsound_select & 0x01 ) {7 e$ t2 g8 ^2 j; m# l, r5 b$ g1 ^
                vrc6.SaveState( p );
+ f$ ^& |5 d6 _                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding9 Z% g; U  H7 f+ `8 q( H3 O
        }8 B7 C* J3 `4 _! O$ n; y
        // VRC7 (not support)
+ l. F; ?, A7 w, ~, o" w0 z8 x        if( exsound_select & 0x02 ) {
: `2 ?5 x9 y7 _8 q, v$ j9 ~2 M                vrc7.SaveState( p );
0 u" l/ I2 m) E  \7 d+ I3 m+ x# I- V                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding) q. \4 _8 m7 m; X) p6 ~
        }) s% Z8 z; X8 ~9 A
        // FDS9 R4 r$ [6 L1 \% o
        if( exsound_select & 0x04 ) {
, w/ S; O$ K. V0 c" L4 n                fds.SaveState( p );, o  k0 C; U# s/ _, o, @0 y' |6 y
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
, z- n$ b( ~+ p; E( N+ z# [        }
  P% w( ?, ?& E7 I6 i        // MMC5
+ O6 r+ y5 s) I. v6 v9 g        if( exsound_select & 0x08 ) {8 l0 G  k7 H# [9 u# A/ B1 V; T) l
                mmc5.SaveState( p );
# G9 ?; y4 w. z0 V, o                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding& m$ r; n7 V, D' W: W& h
        }( n2 e3 O* T. v' t& d
        // N106
' ]! u. A% a: [# I7 T4 ?7 ^        if( exsound_select & 0x10 ) {8 Q! ]- U9 g' o
                n106.SaveState( p );5 m* h% b4 [8 y
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
% j3 Y9 N* F# `' d        }
/ C9 W3 V1 c+ n- f1 X        // FME75 V, N$ n+ ^) x# Y
        if( exsound_select & 0x20 ) {
/ F# r' r9 s7 v( E3 U* j0 |7 L                fme7.SaveState( p );# E" `& W, j4 t8 v2 B
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding. ?, t" R4 V; O
        }: a3 k0 Z9 s) k, j; E4 l. q

! z9 v. D* w+ U4 U#ifdef        _DEBUG; z4 |( t! u1 }# B2 V, k7 H. g
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
; K5 Z  [8 m( {8 ?  h$ o#endif
- i4 w+ f! c8 `2 c}/ I1 T1 k9 I6 u+ L
5 V2 ~7 {2 R/ i; S: y, ]
void        APU::LoadState( LPBYTE p )5 f& h! \5 }+ J% i
{
% t* a" w6 W: ?0 e! F        // 帪娫幉傪摨婜偝偣傞堊偵徚偡) |0 l  ]9 X6 P: r4 A/ e
        QueueClear();' i7 s4 T- a; {. N/ G

1 v4 D& B& }+ V7 V, t        internal.LoadState( p );8 f# G9 C, |- R, U
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
% a9 _& s; x! |: Y3 w2 B+ S# [5 O, ^: I# p, O3 K, b8 d& |6 N
        // VRC6
9 ]% X' R$ h3 y" D3 a  t, z) ?) s7 g        if( exsound_select & 0x01 ) {" `9 W2 U, d3 M- U* @8 E
                vrc6.LoadState( p );' k5 @2 f9 c) s/ m* _
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
  \& C% o# r- r8 ^        }
) |' b9 N+ Z- e8 A        // VRC7 (not support)1 \+ @7 Y2 O$ F
        if( exsound_select & 0x02 ) {+ z+ K* w: e' f7 Y9 F. a; }
                vrc7.LoadState( p );
3 |1 S, O/ F# k( A$ o                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding/ ^& c  E% w' t2 V, F+ @0 @' Z; V2 g! u
        }! |8 _& [& z6 |+ B' c, r5 x6 V, r
        // FDS
$ j2 K6 b+ D; s2 S! Z        if( exsound_select & 0x04 ) {) D# U5 a: ?) H( q9 S6 w# d
                fds.LoadState( p );5 s9 v8 Z5 d3 `3 o
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
5 d8 x, x) L, c        }! J6 C( f' p/ T* _
        // MMC5
& T; }0 W5 y% w- ~) q5 }2 X        if( exsound_select & 0x08 ) {
' o8 P$ C( m5 L                mmc5.LoadState( p );
% V# m2 _9 z/ l6 e. q' U                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
5 f1 f$ U; V: I0 r  k8 f        }& {' k2 y' M" c- V
        // N106
# W0 ]6 n% v' l, {/ N        if( exsound_select & 0x10 ) {
7 E; c9 J8 A7 A' }; Z3 k* b$ z                n106.LoadState( p );
, ^) t( Q! A0 ~: y+ y" ]. }* v                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding6 y. _" v5 v1 i5 V& h0 ]
        }% j9 B7 V6 ]& c' k( q
        // FME7
' k2 j/ o: Q3 }$ m        if( exsound_select & 0x20 ) {
5 m  ^4 p7 @6 @3 h% o* q                fme7.LoadState( p );3 H/ P( R' D: C3 X
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding$ R7 e  ~$ M: O: }% H* |" V
        }( O. F* V+ h* b* \# J  M; g/ q
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
$ D" }6 n3 Q; w9 d# N可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
8 s0 K; b3 L& p2 ~. N3 @$ O, O感激不尽~~

! M4 p% K$ w/ ~! h- O恩 我對模擬器不是很有研究,3 z$ G" d7 J; P: a1 I$ h3 G% E
雖然要了解源碼內容,可能不是很困難,- d6 y7 i" \/ w$ I6 ?9 F! N7 [5 T
不過還是要花時間,個人目前蠻忙碌的。) n# r; ^* _+ C% Z( Y

6 w! \2 h: h% h2 \# A6 N給你一個朋友的MSN,你可以跟他討論看看,
8 i) {3 M" I4 Q0 t( ]# k, ?他本身是程式設計師,也對FC模擬器很有興趣。
- i1 d" w) S$ z9 d7 d9 D( z# t1 y$ @$ m2 l! W
MSN我就PM到你的信箱了。6 j! L- p! c, \: @1 w

, R" j3 f1 C2 Z4 X2 K) _希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
$ f0 e5 [+ U: |* f8 X( Y0 ?呵…… 谢过团长大人~~

( j* g. o/ Y8 ?0 E- l( M. S4 {1 q- \# _. M3 }: [+ D
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 ' l7 c- c+ j- ^: f. H. a
团长的朋友都是神,那团长就是神的boss。
9 C" A/ ^( Q- q+ R; E5 |& ^. r
哈 不敢當,我只是個平凡人,
4 ?$ @! X; B4 S* [$ h  A: \要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙7 G5 q4 v+ ^- x
ZYH% j% H( m. |) }
QQ:414734306
: i3 a* a2 C+ M8 h: E% wMail:zyh-01@126.com- r/ s/ T, f/ o* C& x5 j
5 z+ X! w! }# E; b) J  V3 e
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
  [# {" i3 U4 U9 @9 o7 L再次对团长大人和悠悠哥的无私帮助表示感谢~~
  ?% q8 L+ N, L* a6 P# N
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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