EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
1 J2 i# H0 X1 u& m4 b0 u) d# {) i: f楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
( T* y. J3 a5 P  W. m. G这里有相应的模拟器源码,就当送给大侠了~~( _* K' L% n/ w; G1 }6 p$ W  u
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
& n$ V: H+ n7 S0 D9 n2 D4 a* o能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。7 ~% u4 u$ B1 p7 D8 u+ g1 m
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
+ ?3 h4 C6 |$ C: j" I" O6 b这里有相应的模拟器源码,就当送给大侠 ...
8 S0 }% |+ B: _5 Y- k
聲音部分(Audoi Process Unit = APU):' [9 _1 ^9 q$ p) N+ P2 ~3 ]) F
.\NES\APU.cpp2 ~& K  j  Z% W' x
.\NES\APU.h
8 d, q; k+ e; o8 _+ u# x% W' ?2 {3 d% ?
' d9 @/ S' \& l) {
影像處理部份(Picture Processing Unit = PPU):
5 R& H# G/ M# T* G.\NES\PPU.cpp# p# M) ~2 I0 `, q8 ^- U. G
.\NES\PPU.h
* e) i+ O; W$ |. q3 s
$ @, U) Y# |4 e8 c+ K9 W6 }如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:# h4 s* b. f9 A
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
7 e/ `2 z" b% ^! k0 Z. A//////////////////////////////////////////////////////////////////////////
6 k( Q5 \4 Z0 {4 G* {//                                                                      //% P+ X# O; `9 [* t4 n7 b, v9 @
//      NES APU core                                                    //) N; Q; G1 R% N) X6 m
//                                                           Norix      //
7 s5 \  b6 }5 k8 i6 ~$ h# M) [//                                               written     2002/06/27 //
8 t. \. x; G1 ]/ a//                                               last modify ----/--/-- //( x/ R, ?# [6 [+ }* U$ h
//////////////////////////////////////////////////////////////////////////
! n7 X8 n" O& L+ N3 O1 A/ F#include "DebugOut.h"
5 Y3 Y- {& l7 l- A" Q#include "App.h"
& z( q3 _: I, ~/ p#include "Config.h"7 g" Z; c0 _9 j, J6 n
) \& m! @( C! C, k6 r) k
#include "nes.h"8 e: N5 T3 n9 g
#include "mmu.h"
  X* F5 v$ T0 K#include "cpu.h"6 m. C  h1 j7 e; D: C2 q
#include "ppu.h"/ a. `. L: S' ]8 B) g
#include "rom.h"
$ z# r, X+ K* |) }/ W#include "apu.h"
8 I7 ]0 N: q' r1 m  f& Z3 n8 f- T9 L# H: B5 n
// Volume adjust. N) E# ^" l3 K9 R  ~2 E9 b; u
// Internal sounds
. G* }8 K$ g. t% o#define        RECTANGLE_VOL        (0x0F0)
6 M2 G5 V5 V3 o- A6 l1 P' T; u#define        TRIANGLE_VOL        (0x130)7 A  w. o) I$ o; {1 f# B3 R$ ~
#define        NOISE_VOL        (0x0C0)8 j! h. s! Y  m
#define        DPCM_VOL        (0x0F0)' P7 d. I- E5 L( ?
// Extra sounds
0 J% l5 v5 k! c( ^" T2 \* I5 s#define        VRC6_VOL        (0x0F0)
( P1 |8 K5 {' |$ @; D  I4 J4 M0 r#define        VRC7_VOL        (0x130)
* M$ y' N. m/ M7 a6 P' q#define        FDS_VOL                (0x0F0)
0 R8 M1 }, W) Q- r1 Z3 n+ f! c$ C#define        MMC5_VOL        (0x0F0)4 F/ z6 _2 z; \% s$ a0 F
#define        N106_VOL        (0x088)
" l& {# \! C5 Z0 f, Z8 \; |#define        FME7_VOL        (0x130)
- X5 W# e* x: H: ~
% z/ t2 B# @5 l/ R0 L- ~APU::APU( NES* parent )
, ?' d# g; E& l  v9 V( I, l+ M3 H{
, L9 J0 X8 k  `+ B% [        exsound_select = 0;3 v$ @& W( `8 S: E" z7 w' w
2 W' v- w0 S  T
        nes = parent;
, h4 o6 o" U5 Q5 B; g# t  x# t        internal.SetParent( parent );
  N. b+ M; W4 X: ~( o! F
& ]1 v3 ^+ O8 W5 g. T$ L7 l        last_data = last_diff = 0;2 s& Q2 V) g) D, z, k" J

7 S4 f* N. z0 X" Z        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );2 h  v/ M. i( b: ?* j$ l
8 M+ ~+ g' ^/ t2 L
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );5 i0 b$ t! P4 ]9 f' |
        ZEROMEMORY( &queue, sizeof(queue) );# |* r/ G1 o7 |0 @
        ZEROMEMORY( &exqueue, sizeof(exqueue) );4 u8 r2 z* ]2 s5 L
* Q& K1 v0 a" n1 k- m6 |% n7 t9 w
        for( INT i = 0; i < 16; i++ ) {
& d3 a: \- Q# P2 H7 f7 w4 q" p                m_bMute = TRUE;2 Q+ W. n6 B' k8 i  R  c. ~' k
        }
% [. i* B  s; }5 d}
( G# H5 j. j/ p: V5 w; q
) R$ T' b9 N+ U3 I5 Y6 }% {APU::~APU()& r& A  t0 m2 j
{+ V1 F; e6 K" l0 l; N2 ?
}
6 l% N5 G5 F( x1 B) A
. n8 O( b3 o5 g/ U* K. [void        APU::SetQueue( INT writetime, WORD addr, BYTE data )0 `/ l, I8 `' g7 _/ ?
{
! r8 x3 n% N4 [$ b% k% ~        queue.data[queue.wrptr].time = writetime;
# E" `. A0 j0 H* c7 K- {/ r        queue.data[queue.wrptr].addr = addr;
: m  ^: @: X' \0 [- R) O2 L        queue.data[queue.wrptr].data = data;1 F, p/ `2 t" O
        queue.wrptr++;! K+ j) ]9 _" V( d
        queue.wrptr&=QUEUE_LENGTH-1;' E( `7 q& P8 `( ?# P( n
        if( queue.wrptr == queue.rdptr ) {' \) w1 M- c, B
                DEBUGOUT( "queue overflow.\n" );
# H  D7 y  Z" j5 S" i2 e! Z& x        }+ y. A( {" k" ]4 [
}4 y. C3 G1 r. @

# H9 b: C% P5 \& y( vBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
# Y, j6 r  N8 J& z9 f( U1 P% H{
& q1 j- d3 F# U( P: X        if( queue.wrptr == queue.rdptr ) {
( U+ @9 X2 i5 O                return        FALSE;2 t  a$ K+ `5 @; V/ e) a. d: J+ X
        }! T% x# X1 v4 I7 |' L  J: h
        if( queue.data[queue.rdptr].time <= writetime ) {
0 V2 U9 a' p8 D7 R- v6 ^                ret = queue.data[queue.rdptr];
3 ]7 z* q1 Q) b. y5 a5 Z: r/ m                queue.rdptr++;3 Z" r# M2 i) R5 [& F" c
                queue.rdptr&=QUEUE_LENGTH-1;
# F; _* ]9 y" d/ @                return        TRUE;4 g5 n( ^5 A5 t! m$ g2 c7 {
        }
/ X, S6 c4 y2 A4 ]  W' M, Z: g; m        return        FALSE;- f7 ?- E$ T' S: h3 u# i* {5 G' L6 ^3 W
}
8 A+ y: U/ h2 p* r* A1 V8 G
, s% D& B% i' Q  e+ R4 O! Xvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )$ x: b! m& j& v( v7 G
{2 }8 r4 a! Z3 V" X6 u, z+ h
        exqueue.data[exqueue.wrptr].time = writetime;+ n! f% R" Q" V
        exqueue.data[exqueue.wrptr].addr = addr;
, l- u/ y: V9 V' Y        exqueue.data[exqueue.wrptr].data = data;: z6 I/ u  x! j* |1 r' m  o& |
        exqueue.wrptr++;
: z9 v! q5 n; V; a8 w' v3 W        exqueue.wrptr&=QUEUE_LENGTH-1;
8 g) {. G- J" S% U0 c8 b% i        if( exqueue.wrptr == exqueue.rdptr ) {! p: q. O" ~1 p- S, y" ?. Y
                DEBUGOUT( "exqueue overflow.\n" );& ?6 T( f1 U* I/ G
        }
6 j9 K( d8 \& f" T( y}
, u+ p  B0 x2 F
3 d% A- Y7 i5 R) T+ G& ZBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
) h% Z( L/ G; l- W2 F" i{
1 o9 z3 m5 n6 Z; o  F5 U        if( exqueue.wrptr == exqueue.rdptr ) {4 b# f: y' y) d1 _( p9 E# Z0 @
                return        FALSE;
* q1 F% x  @; g) b        }# z# P8 E4 B1 d( _
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {! J8 W# }2 z& R1 @
                ret = exqueue.data[exqueue.rdptr];
9 x/ s) P' L" F                exqueue.rdptr++;' w" K. A2 v& m( o; N
                exqueue.rdptr&=QUEUE_LENGTH-1;$ C& A& }# [9 w" G7 |# p. y/ p
                return        TRUE;
; ~  T4 X4 p. F1 u( ^, ]! m' ^        }1 R0 f0 e1 N$ H" }& O" R% U
        return        FALSE;
- P5 w% F7 q1 W( i8 S}, g( N. {6 l# X, r# f7 P

$ W. _# Q4 r! f5 E' i& ^" [6 z8 }2 xvoid        APU::QueueClear()) C- O1 _+ ~/ }: ], O
{
) ]$ b7 c6 `* h$ l5 L8 K, ?) D        ZEROMEMORY( &queue, sizeof(queue) );
2 m7 B# p9 N( ]  I        ZEROMEMORY( &exqueue, sizeof(exqueue) );
. G% I" y' C) g+ ~4 b}! D5 y! x; {0 n$ w! B

6 j" b0 y4 ?9 X6 m: k4 Qvoid        APU::QueueFlush()
) z2 k* I1 v  G{6 l2 @& V1 P9 e9 H7 |
        while( queue.wrptr != queue.rdptr ) {
1 i3 l7 @' y- |+ W2 }# C                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );" Q+ R6 S2 }0 m
                queue.rdptr++;! l$ k0 v( e  u5 N
                queue.rdptr&=QUEUE_LENGTH-1;
* Z1 S: ^6 D8 w" X2 O        }
& K) u) }5 j/ W5 H, d
3 m( ~! X9 A% r2 t        while( exqueue.wrptr != exqueue.rdptr ) {  z% h4 k: W3 r; p2 P
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
" |" J* c4 H2 h                exqueue.rdptr++;9 n4 _" c% d: D" u0 e2 Y& a, P
                exqueue.rdptr&=QUEUE_LENGTH-1;
0 |" Q/ C" K, }5 Y& Q9 e1 U        }- X. Y, K' ^0 j2 d, I* T+ P
}
. F+ C: E) k0 x5 h# _. E% _3 B: ~: q; ]; M" I5 f5 {3 Q- D% y
void        APU::SoundSetup()* R: N: H& E6 L5 s& b$ ]7 e: b
{
2 h2 a# |" v& O4 M- p4 B        FLOAT        fClock = nes->nescfg->CpuClock;* Q* R+ x: w% M$ C2 ?. L5 e
        INT        nRate = (INT)Config.sound.nRate;
8 `" R$ w4 S& b0 n1 t& u        internal.Setup( fClock, nRate );
: M5 F: f  D! E. H7 A& F4 C9 }        vrc6.Setup( fClock, nRate );
: l( t( m# B0 u* G; m2 h& R( J        vrc7.Setup( fClock, nRate );
* I5 z' P. U9 ^        mmc5.Setup( fClock, nRate );8 l# i" _9 R4 p; r
        fds.Setup ( fClock, nRate );. u1 R4 P9 ]1 l! p. b' G2 Y, k
        n106.Setup( fClock, nRate );, \' t4 V+ P+ E
        fme7.Setup( fClock, nRate );
9 R1 }. i2 ^% Z6 t( u" N}
4 i6 |2 n% T8 q* |+ y  N# L8 `1 I& n9 P- p6 U5 C
void        APU::Reset()1 J, [8 D% o+ x5 y' U
{& l, u7 R# t$ a& B- q8 N( u
        ZEROMEMORY( &queue, sizeof(queue) );2 ~7 C3 u0 e/ g! z
        ZEROMEMORY( &exqueue, sizeof(exqueue) );+ N) A+ r/ f' [  G) @9 \

/ t: A  k$ l: h. p0 M9 I        elapsed_time = 0;6 ?& y/ t0 ~. `$ i. Q- }' S

3 T5 |  _9 N: k- K+ T+ W        FLOAT        fClock = nes->nescfg->CpuClock;
" ~2 I9 ~' r/ `# N# N7 e        INT        nRate = (INT)Config.sound.nRate;
# O# K7 M2 e9 Y7 k        internal.Reset( fClock, nRate );
; u, Z# ~) |& O( @: E; M. N        vrc6.Reset( fClock, nRate );
5 @1 D9 I' I0 _! l2 M        vrc7.Reset( fClock, nRate );& ~  a* C, }3 [( D4 D% G# s+ v
        mmc5.Reset( fClock, nRate );
3 w. k# u9 V# j9 G2 |        fds.Reset ( fClock, nRate );9 A0 s: i- c  L# k
        n106.Reset( fClock, nRate );
8 L5 T; N3 g. T$ N        fme7.Reset( fClock, nRate );
  h  X, }, R. \* i
1 K$ V/ j# Y$ ^- B- `$ R- i% Z! z        SoundSetup();
) I' a& J" U! F# A" N* ~}; h$ R4 F% k" a' d: ?; C

5 @5 \2 w3 [& D  uvoid        APU::SelectExSound( BYTE data ): x4 Y3 {0 a3 D- j) `
{
& N# c( I9 s; o6 W! i( m7 l        exsound_select = data;
6 v# z4 {$ ^3 z% V0 ]6 N" ]9 G}# G  n2 w6 i  f
& N8 b* u$ I) a% ?
BYTE        APU::Read( WORD addr )2 i1 d9 o2 p% z  `( X
{
8 c3 O" G. Q* ~* e, G# g* p        return        internal.SyncRead( addr );/ ]; d' u4 i( Y1 B; K; \) N  e
}
6 A" h6 i4 j0 W& m* n8 F: \" E5 s4 c4 o7 C0 L
void        APU::Write( WORD addr, BYTE data )
2 ^$ c& q4 r, o+ Z  M% r{
( L) v; k* e9 C* b6 o3 `4 p( r        // $4018偼VirtuaNES屌桳億乕僩  x5 Q+ `7 e* J6 C/ D4 C
        if( addr >= 0x4000 && addr <= 0x401F ) {; M1 F6 m4 G* K- D$ }
                internal.SyncWrite( addr, data );
; [7 ]7 Q& I! U9 z- ~                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
( Z1 Z3 I2 R( n" }4 i        }
+ x0 X/ ?. J0 `0 x1 X: D}* F& X3 H+ J5 q5 M; z0 r
  c1 ]3 x% w2 m. R2 [! W% u
BYTE        APU::ExRead( WORD addr )
, X$ O) K/ \- Y: X3 ]8 I+ K$ y6 V{3 F7 |$ F% U8 m8 z
BYTE        data = 0;
' f8 Q# t, m# v' j) ^
+ p4 a. X) d- i( \) g        if( exsound_select & 0x10 ) {
7 z, E) z* R, |5 N: `, n' @                if( addr == 0x4800 ) {
/ Z9 _9 C' s- d7 J" V  Z                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
1 a+ b- |2 x1 e                }0 `# E' i6 x3 a# V
        }
1 M7 r, ^0 u! g, c: x        if( exsound_select & 0x04 ) {
) c( N$ V% X  }8 r6 p                if( addr >= 0x4040 && addr < 0x4100 ) {
1 v3 f) S: a. A* R                        data = fds.SyncRead( addr );/ ^2 v$ @) X1 [, L( P/ e
                }
; i/ d+ ^1 I# D. \; s2 [        }
  Q' x, P! A! N% V/ E# }/ M8 f        if( exsound_select & 0x08 ) {
- m/ B$ V% B0 D- [: J. E                if( addr >= 0x5000 && addr <= 0x5015 ) {
( l; x6 `+ j# K9 Y7 i6 E                        data = mmc5.SyncRead( addr );" S  m6 e7 P1 I2 [. Z5 F/ o
                }* r4 C, y, k) h! L/ C# \9 N* W- E
        }
% ]6 A; @( F6 t  v$ l. M4 `( g  @) g$ P7 {- m, v/ T& V" v/ m
        return        data;
) @% l1 E5 e0 D3 U1 ?& C9 ]}. D* x5 v5 v9 ?9 r/ E( A& r# ~

5 _- C1 A$ O+ V0 {( svoid        APU::ExWrite( WORD addr, BYTE data )
, k+ p$ ]* `! s9 Z$ A{- E! ?3 ^& ]+ I6 n
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
$ \: C$ O" l. H9 C* \
5 V3 x4 n, e# l" n0 q( q        if( exsound_select & 0x04 ) {
7 T- d# |  B, ?  J                if( addr >= 0x4040 && addr < 0x4100 ) {
/ `$ Q8 Y8 b6 C$ P2 P                        fds.SyncWrite( addr, data );* X2 `: N/ m, I, ]% k
                }
8 R4 T0 c% F3 b- k! m        }
9 [. ]; o* S$ ?* J' C9 |0 P/ ]: |4 D; y; W6 {
        if( exsound_select & 0x08 ) {
" M/ y% E, _% m  G                if( addr >= 0x5000 && addr <= 0x5015 ) {  r7 l4 J( @/ g& O
                        mmc5.SyncWrite( addr, data );
, ?1 e* |& g7 d. X/ o                }
. A/ s: R+ m5 T) @# T8 Q, i" R        }1 i& u: K2 A: C$ C  ]
}
3 i. s2 t0 ], Z7 _9 `+ a, `5 P6 ~
" z3 R( }( [6 v, qvoid        APU::Sync()
! r! C  }) |# u' z{
* H5 z7 i6 n' S  v$ Z}
; J  ]" G* B+ a6 W3 D8 w4 q7 b/ P$ O" T# x
void        APU::SyncDPCM( INT cycles )0 c: Z' M" z/ z* o( W
{
8 d2 N2 V0 C: W8 A$ n# P$ w: ^  Z+ l/ z        internal.Sync( cycles );
. X8 z9 U) H' R4 |( K7 m# }, C+ P3 ?  ?; T' b1 P
        if( exsound_select & 0x04 ) {
, W& k; L& m; q) o2 V0 U                fds.Sync( cycles );) L$ ^2 {0 Y' I( n
        }; I& p/ Q/ s! `: c2 S+ @2 q. R8 g, q
        if( exsound_select & 0x08 ) {
0 H' j7 q! i* {- Y3 M                mmc5.Sync( cycles );
0 R, {% @6 K. A, L. A. u        }" {: [: t( H+ L1 S7 P
}
: L8 g4 @/ y9 b1 F8 i
* f7 `+ d5 o6 avoid        APU::WriteProcess( WORD addr, BYTE data )
: w# ?! S$ f: u% B& X  }{. m) q- p5 Z' v5 b& ~
        // $4018偼VirtuaNES屌桳億乕僩
* [; Y$ a) l1 W$ b; J        if( addr >= 0x4000 && addr <= 0x401F ) {
# h6 B* U; m% g- R5 q                internal.Write( addr, data );, ?% b7 m' ?& v4 G3 i7 L& m
        }* s% D) h2 ?0 F
}$ b$ Y+ \" }5 I* V3 P9 @
  t9 d% \6 r% m1 r$ T, a% K3 Z
void        APU::WriteExProcess( WORD addr, BYTE data )7 S- G& a- R- u$ ]+ ^+ ]
{
' g: r- _& M. G3 G        if( exsound_select & 0x01 ) {- B9 b; g% i  W/ v# k! `# w( a) n
                vrc6.Write( addr, data );2 e* c$ L! o* L
        }
$ [: a  S9 ^7 W' Q7 \4 o5 G        if( exsound_select & 0x02 ) {
% }4 {; h$ g+ {# r2 ?, y                vrc7.Write( addr, data );
$ y/ W; w. k0 c7 l, N0 q2 e        }
+ I1 {6 J  }/ n+ ^6 S8 R        if( exsound_select & 0x04 ) {
' p! [: V" t( {' |* D' J/ M7 E( d                fds.Write( addr, data );
, }8 ~" }. b4 _7 `& q/ t2 r# Q( h        }
* Y8 j/ _9 _6 O: B% P; R2 E! N        if( exsound_select & 0x08 ) {
2 M; K5 a7 ^% h: E                mmc5.Write( addr, data );
3 P4 x3 i$ I. r) ~7 \        }- i2 s1 d6 @% L  o: s+ R- \) B+ E0 A
        if( exsound_select & 0x10 ) {- C8 V/ ]! V2 k% z6 [4 n' F3 a6 J$ s9 A
                if( addr == 0x0000 ) {
, |, S0 K* y$ _5 [4 ]6 {                        BYTE        dummy = n106.Read( addr );
. T5 ?" @7 v8 v9 \0 E# g                } else {# j" r4 J  u6 T) W
                        n106.Write( addr, data );
$ u6 @# q+ \+ |! A; t% U( _                }
) x. L- z' E8 c/ J        }
6 T; p/ A0 G" J# I8 g, Q        if( exsound_select & 0x20 ) {, M6 @# h2 X  j; P1 u4 h! B3 N
                fme7.Write( addr, data );  \6 U( g' y* W0 p  `
        }
4 F" |: X# R3 |3 E2 u}
4 R( C( T2 _5 ^( O* n* }2 ?/ G9 m- u- M, Z4 T: c; G; c# y
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
2 D) F* ]( \8 J1 S1 T" P. E{9 N/ ]% {, H* m9 G! P$ Y. G& _
INT        nBits = Config.sound.nBits;
. h! I( \  L3 [; ZDWORD        dwLength = dwSize / (nBits/8);
$ T+ z' x" [& V/ xINT        output;
  G# D; A) F" ~$ y) A1 \QUEUEDATA q;
& z# P& W: I& {# {9 E' KDWORD        writetime;7 N4 R; Q# {8 v* L5 e* W, o

) V0 F  `  r$ ALPSHORT        pSoundBuf = m_SoundBuffer;
  a7 N8 q' ]1 w4 n/ oINT        nCcount = 0;  @5 B+ A" r3 [3 y  Y

$ s0 h( t6 o7 a0 b8 tINT        nFilterType = Config.sound.nFilterType;$ [1 w: t" u/ {* l9 ~
# z8 c1 v$ e- b/ T' A
        if( !Config.sound.bEnable ) {3 Z3 a2 O+ A  x7 l5 N
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );. j# n  S. l$ s8 w$ f" {, m
                return;) \- I( Q6 ?7 m
        }
- c& Q# W0 d" t  q3 d5 `0 f9 H, J$ J; E
& }. B. P5 S' A        // Volume setup
+ Z# T: A4 d9 {# v        //  0:Master3 k0 H! d) o! ]# r
        //  1:Rectangle 14 K: v! ?0 j- i/ [7 S( @& J. K
        //  2:Rectangle 2/ l2 e4 y4 A, R2 `( }6 g- Q% Q3 M
        //  3:Triangle
3 u6 X+ |* j/ W; K# X- x        //  4:Noise1 \* v8 z4 N; U* f5 v
        //  5:DPCM4 j( s, i, [8 R0 U- |
        //  6:VRC66 L, o: i- D2 K6 L+ J9 V
        //  7:VRC7# L2 H0 {) c1 Z. m; m4 w5 r
        //  8:FDS3 d' ?% G+ U$ o" Q+ E
        //  9:MMC5
  W% |8 |: C, D5 z. D# `. R9 s9 J        // 10:N106
& ]2 P( \. s' @; Y" V+ z        // 11:FME7
4 [- S" O6 f2 a7 Q/ T( J, R, K        INT        vol[24];
( X: Z0 A" z+ l" H        BOOL*        bMute = m_bMute;
6 a/ l/ l% R& ~# T/ U        SHORT*        nVolume = Config.sound.nVolume;, u  M7 g, B' M5 w

+ S) R9 m! y* R% }) F        INT        nMasterVolume = bMute[0]?nVolume[0]:0;: m; n& G5 D: y% W; Z) j0 s$ v& M

# x/ z; V& ~0 l8 A1 Q) Y) t: \        // Internal2 N# ?# b" Q$ h. q9 m
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;' `6 I1 f) L9 w* c& L0 R* j
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;1 j. w! M: N  o( ]$ g
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
: D4 T+ l! q& x  _        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
. r0 H5 a4 n+ a% A* o. r. @# t        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;- ]: o0 V8 V+ X, }
/ i7 k: o7 r. p- f& Q% L0 X
        // VRC6* X2 ?5 {! X% f. o3 N  y
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
0 Q" v1 q7 p/ I3 v0 O        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;) [  ?, Z* R1 D7 _5 e( ~; V
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
) F0 E: o+ O  D1 j1 k' X  e+ {, Q9 ^3 p  z$ v  ?7 }8 l
        // VRC7
! u& F! F( V! \        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;7 @5 U+ D; @: [* f  C: ~; {

' N" f: y- s; Y& ^% N        // FDS0 F5 k# \! z- [& p6 S. H& c
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;/ v* F  I6 a0 x: b2 |; _

! w% p0 d- v5 O  s: A+ s        // MMC55 i4 Q5 t; Y( i' ]/ O5 G' D5 A
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
/ F) i* f- V4 i8 B) `  D) R        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;% C, N; y3 ]2 E# }' g
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;; l* x$ R/ @$ |5 w/ c! _# T
5 Z2 D6 q- C5 H4 O; [& E9 [
        // N106
: i: F8 {3 D) }        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;: X8 _2 }; N9 X: j* Z+ K; x
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
1 R8 s# }4 M. ]( X4 W' u. F        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;4 b7 c/ w4 D( p0 z) K. C
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;0 k9 ]9 }$ e4 Q
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;* g9 ~0 I* v6 _
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ X" i. \' t. S" W' u/ F        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
  g, A% g2 R0 c+ u: i        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ U. S8 H0 s% Q! m& n4 w

0 l% z. \6 r( A        // FME7' G9 z8 v2 g, i- {
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
$ E, H9 _& T- e+ V% h        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
7 s6 w5 d' ~! Y        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;% s* x1 b6 K; E0 ~# n- @0 o

! x/ e, g* J: T% F0 {, |//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
! ~5 l% q* p6 I1 q: z        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;3 n2 H3 ^/ ^3 j! l; [# ]3 s

6 d) U- }% G& b& e        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
, }' w- P- s/ x8 A' I% c' e        if( elapsed_time > nes->cpu->GetTotalCycles() ) {' t& {; [0 V; i" z, p/ V& t" N0 v1 a
                QueueFlush();
* d5 M; J. N+ ?; V7 D6 l$ M0 `        }
1 R2 r+ G& T6 \& b
8 s2 j4 C# j9 L/ h! X% D& j% i        while( dwLength-- ) {  E) s# ~8 [0 m' Z, R5 T
                writetime = (DWORD)elapsed_time;
1 s$ E# y3 Q' d: I( l& ~0 e9 e* S. M( w: s3 z
                while( GetQueue( writetime, q ) ) {! [3 u. G6 q" H* P# _! r$ N+ |
                        WriteProcess( q.addr, q.data );0 a" _2 ?" o0 b
                }
  k- ]8 p& {: u; T) D- U0 q. o* |# e/ r
                while( GetExQueue( writetime, q ) ) {
  F# H, u7 V$ }& z+ x- M                        WriteExProcess( q.addr, q.data );
4 I. H6 p, K+ F! N" z  }9 r                }
7 z- U$ c7 q4 W/ G7 h& o8 a$ S  Q( k3 n2 F
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7( F; l/ r% b4 `) J
                output = 0;
, s* R8 Q: X' g( a' l( h, e& }                output += internal.Process( 0 )*vol[0];
* p/ |0 V& v& D$ ]6 J                output += internal.Process( 1 )*vol[1];* Q2 Q* G' [& `2 b
                output += internal.Process( 2 )*vol[2];
! d9 p% A0 d6 u% _                output += internal.Process( 3 )*vol[3];( k0 I! [( Q2 h) g
                output += internal.Process( 4 )*vol[4];
% C3 Z1 {* z( Z. a' n2 @/ @
  F: K: N% Y; \3 Z  w                if( exsound_select & 0x01 ) {! b, H! V) c# h6 ]) Z8 N# i8 @
                        output += vrc6.Process( 0 )*vol[5];0 D9 Z% [8 l9 _6 T4 k7 q
                        output += vrc6.Process( 1 )*vol[6];
# H. @! X0 ~% Z( m                        output += vrc6.Process( 2 )*vol[7];
4 m+ A) ?& l0 s                }/ R  J' ^) e' Y8 p& o! s$ |
                if( exsound_select & 0x02 ) {
, M, R+ X6 R9 z8 Q! I! W                        output += vrc7.Process( 0 )*vol[8];
, G- p) u3 D) c# f                }  L2 y/ {8 T- d/ G3 S3 A
                if( exsound_select & 0x04 ) {
- Z- g, |, r' {$ }1 b! N                        output += fds.Process( 0 )*vol[9];
0 R9 q, X! ], s6 h                }
3 V( o+ z! v# w9 O0 A* S* _                if( exsound_select & 0x08 ) {- [2 ]; v7 V! ~4 k
                        output += mmc5.Process( 0 )*vol[10];! i9 Z2 X/ `' x9 z, Y0 i/ }
                        output += mmc5.Process( 1 )*vol[11];  d8 `( ^% A" n0 E/ D5 V& G
                        output += mmc5.Process( 2 )*vol[12];
4 M2 w, ^8 Z0 o  j% y                }, J% J1 u! r! J* G
                if( exsound_select & 0x10 ) {
7 _+ W+ k0 i) p2 z7 C                        output += n106.Process( 0 )*vol[13];- C" X7 c) e% i; t. a& \
                        output += n106.Process( 1 )*vol[14];
  d  [0 o8 z5 N4 f! Y+ i                        output += n106.Process( 2 )*vol[15];! X$ O! U- @7 A# O. c/ W/ I
                        output += n106.Process( 3 )*vol[16];% e* R" {* z& k$ v! J9 y
                        output += n106.Process( 4 )*vol[17];
- w0 y, P6 \# g5 l! {5 _                        output += n106.Process( 5 )*vol[18];
& {9 w) \) o) @7 t( G( ]" |! m                        output += n106.Process( 6 )*vol[19];1 p0 k* X- Z8 {, O, \
                        output += n106.Process( 7 )*vol[20];
- X' h8 k% M4 N& p: L5 g% m" }: S                }
- l0 L/ y+ d8 a                if( exsound_select & 0x20 ) {
1 h* b3 C$ _6 X3 H7 W  C* e$ r& i                        fme7.Process( 3 );        // Envelope & Noise. n3 p( V! J/ C# _: Y8 X: L
                        output += fme7.Process( 0 )*vol[21];
0 t" c& ^/ v. T% h2 B1 f$ U+ ?7 j                        output += fme7.Process( 1 )*vol[22];% U! M# }: H. F: E
                        output += fme7.Process( 2 )*vol[23];' ^) Y5 n  Z0 H8 j
                }
% e5 P1 s$ H! Q( j/ q; Y; \$ m
                output >>= 8;7 g2 O5 N/ t+ I$ Q& {& d4 p

" _3 n" O5 W2 Y2 ~- \& @                if( nFilterType == 1 ) {) ]; j: o, t4 ?
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)2 J. H+ O; N  S' T* K9 Q, F
                        output = (lowpass_filter[0]+output)/2;
. I$ G! V$ c. |# q( Q                        lowpass_filter[0] = output;
& W; r5 Y1 I& i% R; n2 }; H% f4 q                } else if( nFilterType == 2 ) {
5 a, K* u9 B# \) A/ f/ s                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
" c+ f4 d/ ~& R5 {0 X! f# j8 b                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;4 I4 m/ E0 \- T7 i" a
                        lowpass_filter[1] = lowpass_filter[0];2 e- x" Z$ _7 x3 e1 m6 R$ |
                        lowpass_filter[0] = output;, f/ e* K9 b0 G; {! ^- X
                } else if( nFilterType == 3 ) {# \& w/ p; G/ Y# C% `) I6 U
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
, K9 S( ^% L5 `4 B# W9 L                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
( i3 F0 C9 R% P$ l1 X; ]                        lowpass_filter[2] = lowpass_filter[1];
4 b! g4 T/ A3 F. S/ r% ~7 d                        lowpass_filter[1] = lowpass_filter[0];( e# _: W9 ~0 e) ]1 c, Y
                        lowpass_filter[0] = output;2 E; a( o3 c2 X: i! [7 E4 Y* }  s
                } else if( nFilterType == 4 ) {
8 w! J; i  m" i9 q, G( L5 K                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
0 r& K. d7 e+ P0 C# E                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
! ^$ n) n8 _' F) v( g( K7 T3 ]                        lowpass_filter[1] = lowpass_filter[0];
& d( {3 r% P* `8 X' w% a                        lowpass_filter[0] = output;
5 w0 @/ }0 A* X; P* i) H/ v) M                }) `# w$ M6 R9 j1 X
5 S* h0 k/ R4 b% ?
#if        02 B/ C. M  \$ A
                // DC惉暘偺僇僢僩
8 c* Y# A" V  L                {2 Q# b. c$ m3 S$ P* v
                static double ave = 0.0, max=0.0, min=0.0;$ `" r4 e% |9 g; ~
                double delta;  v  D$ ]& Q( O
                delta = (max-min)/32768.0;2 j7 i! }  ~9 d/ w
                max -= delta;
/ U0 z: z# o) Z5 q! J! X$ t                min += delta;
$ M& d. v6 ]& L9 p: |: w                if( output > max ) max = output;7 P% A6 |- v! U& _0 `
                if( output < min ) min = output;  Z7 B/ m! L4 o
                ave -= ave/1024.0;# H& w+ _; w6 c6 ^
                ave += (max+min)/2048.0;
4 }2 C) B5 {+ X, v9 R6 m' l                output -= (INT)ave;
# H1 s+ p/ f1 f8 b                }
1 S$ s: x, D# H  }3 T+ Z1 V#endif2 T* s" q& c- y% ]7 M& s
#if        1
9 [1 M# o% {3 q! a% q8 {3 L                // DC惉暘偺僇僢僩(HPF TEST)# e9 J# d+ C1 @1 o. e4 F
                {' o! A& T2 Y/ s# N0 F+ O
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);& ]' Y* r* y: N6 ^6 u
                static        double        cutofftemp = (2.0*3.141592653579*40.0);$ H- O/ J: m/ h( U
                double        cutoff = cutofftemp/(double)Config.sound.nRate;- H1 ^& g8 X( M5 p) q3 A  |
                static        double        tmp = 0.0;. I  H4 i2 M4 C: T; n3 Q3 s
                double        in, out;, p' u$ f' U8 y3 |5 k: B( r. p

" D- ^$ R2 }* t                in = (double)output;
; l, e* l, c+ J$ {                out = (in - tmp);. Q$ t! `5 m9 R, h, f
                tmp = tmp + cutoff * out;" e9 s; b; n2 X: L3 j7 N

) _- ^3 A, [6 l( p& W7 c                output = (INT)out;, H8 ^* D4 ?+ i5 m' l
                }) H% j2 e" g$ P! e
#endif/ s: m' V% T$ J
#if        0$ m! {2 @5 J- k$ I: q
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
9 L$ h& U0 {0 O( e                {* i( T- [. R  ^7 X% E- U1 N
                INT        diff = abs(output-last_data);
8 O) P8 u8 S& p* w, {                if( diff > 0x4000 ) {0 j0 j% R9 f  T1 g! w
                        output /= 4;
( b. L+ L% F6 x/ I                } else 6 u& T9 ^) {* C" e# R- j) _
                if( diff > 0x3000 ) {2 [  J/ ?( _6 o) V
                        output /= 3;
" A- R6 J! b* \$ a" F, o: k; B' d                } else6 v9 ^9 U7 \3 R- g4 b8 Z% f
                if( diff > 0x2000 ) {, W6 N1 S( u! g9 s4 k
                        output /= 2;8 U0 R2 x& m, ?
                }
8 G( D( y& p1 c$ }) @                last_data = output;$ H! b, F) ^% g& n2 W
                }
: L/ i3 R  {" d$ B; c0 R$ j% V5 Q#endif+ w# V5 }; [' S! ^9 J
                // Limit3 \" o) Z  q6 g" Q( f/ e2 r- P3 N
                if( output > 0x7FFF ) {
. g/ q6 {) x4 G1 q4 P                        output = 0x7FFF;% Q3 y; }! X" T/ j3 D; |) y
                } else if( output < -0x8000 ) {) g% d" i# Z- M8 k+ I/ Z# E; W
                        output = -0x8000;
( k) K1 h( P% F3 R/ Q7 j& m                }
- h' T  a  V- I
4 \4 T& H# D6 t. B" a9 R) g( g                if( nBits != 8 ) {) X3 x" I" x/ x% t
                        *(SHORT*)lpBuffer = (SHORT)output;0 |4 C' W, S" }
                        lpBuffer += sizeof(SHORT);
, }7 w7 L( h8 F( E1 q: F0 _                } else {  ]  S/ P# T! d5 u
                        *lpBuffer++ = (output>>8)^0x80;# s0 b/ ]# x: _# H" C
                }
- h; B8 y: |- m  W6 b& m" ]# ]( x: y( K
                if( nCcount < 0x0100 )# ?8 T5 c6 ~7 h) Z! D9 Z
                        pSoundBuf[nCcount++] = (SHORT)output;* X/ ]+ G/ ~5 E0 J9 N$ c( P
7 F+ M! X/ g9 U( C( L$ z4 b
//                elapsedtime += cycle_rate;
3 K4 I) k. H  i                elapsed_time += cycle_rate;) [3 P! N0 v$ c$ k3 ]
        }
& ~4 n* L# k3 m# y3 \3 N) m0 I6 a8 D& b, W* P1 i/ X$ p- {
#if        1
- G' P5 |6 s: J' C0 c& y' ?  G* b        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
) P2 h- Z( G. m                elapsed_time = nes->cpu->GetTotalCycles();3 d, z7 I& g( X! f* \9 q/ ?, G
        }
) U  u9 \) I+ B) Y+ |        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {" m; ?3 ^9 ^9 i; R: G: t/ \( W
                elapsed_time = nes->cpu->GetTotalCycles();
  K$ a1 x* g0 f) h        }6 `/ |3 |  V* M- P
#else
. D) c  G$ A0 [$ K& v" R# R+ |2 H        elapsed_time = nes->cpu->GetTotalCycles();
* K' Y: c: A6 ^( p#endif
- s" q9 z7 D$ u}
# c% T; Z0 k) B  `& P
4 L: Y; \% f; l8 I8 D- W$ y// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)& n# j  `* k/ C$ j
INT        APU::GetChannelFrequency( INT no )  m6 S1 G, E' ?2 E
{
& h8 g$ T7 \" h2 V/ \! ?        if( !m_bMute[0] )! D% _8 v4 O/ H( o+ x. c) O3 x
                return        0;4 U0 x0 b: a9 t' i9 D0 x7 }7 L; A% n
: A. \9 U! J+ t! f4 d
        // Internal8 g/ Q6 A! }) N  e
        if( no < 5 ) {
- @$ U- w- n: P5 k( W                return        m_bMute[no+1]?internal.GetFreq( no ):0;- q1 o: O: Y5 o
        }
( ~5 H& q1 m3 B$ n2 Q        // VRC6
" Z5 Z) a! G# X& p% A        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {! V6 D1 I8 T) o  E$ l8 \# O
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
; E- s+ e' p4 p8 O7 _+ ]* m, [        }6 o! \* a- Q. _7 M
        // FDS$ ], {6 ^  _0 k% T' s
        if( (exsound_select & 0x04) && no == 0x300 ) {
# m. j7 X# x4 u, |: A8 P; A                return        m_bMute[6]?fds.GetFreq( 0 ):0;
/ V* Y( P, M3 K; T% O; h1 X$ V* ~        }0 E  Z0 k. l$ C; F- k/ s; Z
        // MMC51 g6 ?# H( n, m! P8 t
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {' o1 x7 x2 @3 N: p( }" V' W' H
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
( h$ G9 x+ P6 c& l" T        }
  p! O; r1 {# ?/ F8 M        // N1066 l! B1 N0 x" N
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {4 `* |4 @( E% \5 s1 A6 F7 T5 ]" Y% J
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;' q) @- L, Z; i! L
        }
6 X' l/ x- v+ j7 f* ~7 @. w& x        // FME72 }: j( P. p  l" ^' B) g5 |7 L
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
8 e: t( Y6 }0 p                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;, c6 @6 p* H) I- y3 X+ I
        }
) P; c3 Q) y: r0 @3 T7 g3 c        // VRC70 c- P; i2 p8 |& w1 m+ {: `
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
& V4 A) o! Q4 Q9 e: a, G# _3 G, F                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
5 u2 H8 A8 A9 v# T8 @# u& z, t        }: m' D: J! l# H8 X0 r) i, W
        return        0;3 l/ f) d' @! L, C4 j& G
}" z% n; a* e6 r- a4 ~3 M9 F; |

4 D3 T, `4 I" p) B1 @# }& T' H// State Save/Load
* k3 M) {4 \, z1 fvoid        APU::SaveState( LPBYTE p ): k6 o- F! h2 @& E( i4 D- J
{
  f* Q5 m  @7 q% F9 Q3 v#ifdef        _DEBUG/ K7 w, M! U$ Z1 Z  s5 t
LPBYTE        pold = p;- \% ?# d7 R2 W% x6 e" o5 X
#endif; s# F* D2 o- b, H# p  ?, h

3 i7 ^- }! @' T- {        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞% b/ ]" E) I# E+ l) u1 n
        QueueFlush();
! x, e4 P0 o4 G) C( K
' s  L) e8 B/ v/ }        internal.SaveState( p );
7 A! }' q1 u* k2 S5 n: [/ s8 L        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding2 b% i3 Q2 r. j: q

! f$ J8 C5 Z* y) g0 |  {  I        // VRC6
8 N+ y; J9 N* S7 ?, N        if( exsound_select & 0x01 ) {* E4 Z  ]+ z: ?1 f
                vrc6.SaveState( p );
8 j/ q) b% H6 {& Q% b9 Y- m                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
( \  V/ q/ P- z  a: r5 @$ N        }1 w7 H. `  G$ n* T
        // VRC7 (not support)
4 U; t( U6 d% a- ?3 h8 L; a1 O; v        if( exsound_select & 0x02 ) {; @! ]& f7 U5 ~! [- E" q
                vrc7.SaveState( p );" l% {  a( l+ v/ L8 L, L) c0 E$ y
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
3 X/ f) H; C) w) M# Y( c3 f        }
) e! R& d- y$ M1 q        // FDS
* Y7 A9 F" U3 F% D3 C- q        if( exsound_select & 0x04 ) {8 Q- J  p4 m6 H- B; r
                fds.SaveState( p );
- D9 g) y( r! v1 V9 a                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
. N$ b7 ~( }9 j2 ?3 \2 _6 ]1 M  w        }; y6 D) N1 C* u. A" U, K" u. _
        // MMC5  _! |% w/ N* S( M6 s7 A
        if( exsound_select & 0x08 ) {
, a: w0 _# t/ s: f, d                mmc5.SaveState( p );2 }# b) d4 Y( L! H0 M% b7 c
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
3 \; I  R2 r$ X4 J: F        }
2 z9 D& ?+ E" a2 o/ X- ]$ T        // N106
$ F1 J' D2 o9 ?$ j9 h' T        if( exsound_select & 0x10 ) {
% P: X# a- w# Q# |3 p                n106.SaveState( p );% Y  W" L& ^* x" f) \" \
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding. h* s  v2 p4 L3 i; p8 ?
        }
/ J8 m0 h" ?. v" F8 b* |        // FME7, k& Z! i6 k+ I+ m. h
        if( exsound_select & 0x20 ) {0 l& @' L: W8 j; {0 B$ ^6 f
                fme7.SaveState( p );4 s) s+ d& ^4 E$ b+ z
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
  I; e  Z: ~6 {9 h! E# r        }: B2 U6 a! P) h

& J- `6 }/ l# j+ A4 E8 A#ifdef        _DEBUG  q  M& \+ j( f; |1 ?$ \
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );+ I7 s; @/ u( F5 h# Z" Y- y
#endif
  O" F, A2 F9 _6 I}
2 ]$ _" O  R1 k5 H, \3 C5 X% c) [. s! [, a$ N: g, t4 f4 d8 F9 {  [
void        APU::LoadState( LPBYTE p )' j; v, ^0 x5 g1 B; o
{
5 S( t  s! k" F& C" v        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
4 i! R% `1 c3 A4 x/ \! S        QueueClear();& t2 p. W5 _; ~4 z
6 M/ }4 h6 c4 L( Q5 G! r) m8 N
        internal.LoadState( p );
5 J6 P+ ~9 `; z( u) J9 \        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding5 ?# L) f! U6 C# O1 l

. E# t1 G2 f  Z8 n. n        // VRC6$ O, S, `9 s3 Y! o! t; t2 {
        if( exsound_select & 0x01 ) {
. X7 u9 I/ ]1 I                vrc6.LoadState( p );- G/ w. f3 o) B. @( p6 w, D$ m' f
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
: d2 S& R# @4 W. f  S3 x% v        }
* ]; E+ W" u% P8 P4 Q8 M7 M  T( M- \        // VRC7 (not support)9 [: L7 t1 p2 h( L
        if( exsound_select & 0x02 ) {
: z% C5 P. e+ ?( u# E) A4 Q3 ]8 c                vrc7.LoadState( p );
4 ?: u7 R: T0 G9 A# g( ~9 n                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding# U- `/ Y) x" K: p3 w. h) U+ s. S9 R
        }* Q) z# j7 i8 E7 H
        // FDS0 R/ _$ ]7 f: F1 G
        if( exsound_select & 0x04 ) {  g# B& w5 t( K2 B& B2 ]) Y% W" z
                fds.LoadState( p );% o# x; i  P" i, U9 [
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
5 l( X7 X, p8 u# C        }
3 F: X' o  o3 [$ J/ ^8 ^  s- E        // MMC5
  ^! [0 K1 F7 G/ P- O  a% q6 ~        if( exsound_select & 0x08 ) {8 D% N+ A  V9 {
                mmc5.LoadState( p );9 R9 A! t5 b9 M3 K7 R/ U* D$ M4 _
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
: ~2 e8 w3 Q# D; r9 N; E! }# `        }* @+ }' `4 E5 B3 i6 p, u- W
        // N106
( C1 y- X; z4 @; X        if( exsound_select & 0x10 ) {
: C" p4 y# u% ]" y0 ^                n106.LoadState( p );8 M; W8 s  G7 r3 W5 A. N9 ~
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
/ {" M! G% c/ w1 H9 B        }
* X: M/ l" q- U6 I) s        // FME7
+ A7 d( Z6 h" c! i        if( exsound_select & 0x20 ) {$ @  N: }7 `) I! P# I% g0 {
                fme7.LoadState( p );( ]8 p: }9 S) h& z% C4 c, w
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
# k: E$ _3 ]" B- L( T        }
" O& d. J* O9 w2 r% m/ D}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 . V# @* W+ H- ?# _/ k6 l
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
4 g. g9 Y9 \3 u4 B: x感激不尽~~
# r8 {! u- c: A' d% V6 U9 h
恩 我對模擬器不是很有研究,& a, r+ N4 u$ s
雖然要了解源碼內容,可能不是很困難,; |! a, Q8 @3 D; @/ \
不過還是要花時間,個人目前蠻忙碌的。
2 R# D, }6 D$ f
/ t$ r7 N$ D9 t( l, p1 Y. P給你一個朋友的MSN,你可以跟他討論看看,
9 _; o' y7 P3 T7 P8 o+ C8 a他本身是程式設計師,也對FC模擬器很有興趣。
3 M5 k+ _* n1 ]# g! L9 e8 Z& O  K. L, X$ Q* z$ X
MSN我就PM到你的信箱了。
4 ~% I( ^; k) D
6 X. M6 z/ A7 }5 p0 k9 t希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
; J2 t, w& f7 A* N  g. J+ E呵…… 谢过团长大人~~

! r$ ]) n# [. J; G; B1 Z4 s5 p
) S# x6 v+ a$ }; {1 J0 f+ y哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
* S& ~1 J2 b( k团长的朋友都是神,那团长就是神的boss。

  Q3 i2 W$ {; }2 p哈 不敢當,我只是個平凡人,
- J7 C- P% d8 a3 O* I要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
9 T7 N  Q! e& iZYH
. p4 I2 F0 X+ QQQ:414734306* M) g' x' U! @2 o. ]! T: c
Mail:zyh-01@126.com
' G* @. A" N8 q2 H  O' `( p; N" G& s/ p( b
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
/ o9 n' J8 P/ A' _) b% }4 T( e再次对团长大人和悠悠哥的无私帮助表示感谢~~
; ~; q' @  f7 w3 I% T, H
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-8 20:19 , Processed in 1.096679 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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