EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
) ]- i7 @/ o; V- v楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
% c& M& c7 l! T% H6 D, o. j6 w- r这里有相应的模拟器源码,就当送给大侠了~~0 n2 x5 S3 V4 d1 c" I9 v
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 1 Q# _1 S$ l1 ~1 }6 f1 P
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
" S- I1 ~$ H1 i" J楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
% i  W" }3 b% P& Z" y/ B这里有相应的模拟器源码,就当送给大侠 ...

/ j2 e0 N5 n! Q3 g% ^" x: G' q: h聲音部分(Audoi Process Unit = APU):  z) D' l* M/ ^) [
.\NES\APU.cpp6 r3 X7 b: U6 w. S& U( M0 a3 f
.\NES\APU.h
9 j2 P5 C* b! x0 W! _' n8 t9 u0 P9 [' C+ |/ B) v# R

- H, [% ]+ O3 Z& \5 @影像處理部份(Picture Processing Unit = PPU):* i' O2 k5 s9 A( D
.\NES\PPU.cpp
9 ]1 ~2 k0 D2 G$ |4 B$ m7 a+ T.\NES\PPU.h5 ?* N. ]$ _" r+ n
# v2 `8 I9 i3 A
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
+ m* U3 B8 p$ W/ P(由于很多专用术语和算法机理都不明白,所以看不大懂……)
4 Y/ }% g/ A. L; v* b0 U" |" h4 R. z* X//////////////////////////////////////////////////////////////////////////( \; @) ]) c7 n
//                                                                      //
) Z0 U+ _. y7 K( C* w6 W" C, z//      NES APU core                                                    //! P4 K# J4 H7 y
//                                                           Norix      //
2 O+ e  b" p6 ?$ K//                                               written     2002/06/27 //$ F" d5 z# S1 v7 Q$ ^  |6 [2 R
//                                               last modify ----/--/-- //, J4 k* d3 R6 d( C& Q& l; [
//////////////////////////////////////////////////////////////////////////
7 ]- z+ a& c. ]. |4 s1 b#include "DebugOut.h"
- W5 a; c) J: |* o( q  f/ L5 z  e#include "App.h"
# b# a( Y6 D5 Z6 t#include "Config.h". |' D: ]2 t% ^8 r
% M# L: F/ H% f4 ?# V) h7 J$ c0 T
#include "nes.h"
+ E9 {( p. R  R* M" I! V6 u: @" M" L- r#include "mmu.h"
# S5 S' v7 g6 A$ R#include "cpu.h"' f- v% g, j/ c5 w$ y% z3 ?  S
#include "ppu.h"% [6 a; Y7 Q) p5 @6 `$ X
#include "rom.h"
3 q2 F+ ]& |, {7 Z$ u$ C! _$ m2 Z#include "apu.h"
' O1 I1 A4 _- h+ |, i
' R- U) O) V+ r( X// Volume adjust
: t* K- d2 v/ \" }2 r% A$ O; F8 \// Internal sounds
. M$ p* G+ v7 U1 O) S#define        RECTANGLE_VOL        (0x0F0)
( \2 R; C' e* h#define        TRIANGLE_VOL        (0x130)- R+ w# g8 @/ }, U, X$ ]
#define        NOISE_VOL        (0x0C0)" z4 |4 ?6 y' D2 _
#define        DPCM_VOL        (0x0F0)8 a* Z" n0 g- ^9 u: ]% P
// Extra sounds7 w% `' X8 J+ G6 A9 A' T
#define        VRC6_VOL        (0x0F0)0 H8 I/ o: y- U2 S( {# k* H$ |% n
#define        VRC7_VOL        (0x130)
  G+ ]/ p+ M& Z# l#define        FDS_VOL                (0x0F0)
4 r- L% r5 X& \6 d9 y8 |$ S: A#define        MMC5_VOL        (0x0F0)
2 Y  e) Q4 ]/ n0 B% \) {#define        N106_VOL        (0x088)
1 D4 _* C) G) i( }#define        FME7_VOL        (0x130)
, Y! S9 w& g; D( b
/ X5 L: C5 r6 ?( eAPU::APU( NES* parent )
$ c2 H8 ?! \. E2 M* I{
) D" g# ~* N- c1 m        exsound_select = 0;
% o1 C8 Y& J3 q) G5 Y% g5 R( r; X
0 N2 W" |" R& x- Q% `        nes = parent;
( I$ S9 J2 E8 R/ V3 N; N2 O9 m5 |4 X        internal.SetParent( parent );2 ]* D2 R4 F  o0 h% Z( ~

7 e4 x/ O& `+ f        last_data = last_diff = 0;6 [& G0 `+ g- J+ I$ w6 l, s
9 }3 H; @& z! I& {, I
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
) |- S, h. Q; l0 n# x: A3 k
! Y* `6 \: L1 d0 p5 C& F/ O        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
) i5 W2 C$ L" R3 \2 m/ a, a$ z2 p        ZEROMEMORY( &queue, sizeof(queue) );
; j1 x+ o2 _. S5 L7 ~        ZEROMEMORY( &exqueue, sizeof(exqueue) );
8 W' K, S0 a+ c. {: R( c6 K9 k9 N# `- g
        for( INT i = 0; i < 16; i++ ) {7 e( Z& Y( E% K
                m_bMute = TRUE;/ r. [- [+ z9 H2 o, a5 W; M
        }
7 A5 `5 y  u' I; f. i. e. w% j}6 {' b' p8 r$ z. A
; e) M/ L( q) C% E! @' B0 a
APU::~APU()
# a3 J& Z1 j! A7 O* |$ D{
3 `$ y+ M- `0 J/ W0 L# e}
6 V; L: {0 j  K9 G# l- X" S! S8 G
( y# Q5 k7 }' ~void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
# P7 p( P! D9 Y" q& g{5 b% I( Q! l) o# I
        queue.data[queue.wrptr].time = writetime;& i" F0 l/ m) O6 T1 \4 }
        queue.data[queue.wrptr].addr = addr;
0 ?/ w) f- C+ g, N( M. B# u        queue.data[queue.wrptr].data = data;
' j+ M+ k5 P0 `% T& V! N2 _" ~* Q        queue.wrptr++;0 M( a; M' O: x( F, O
        queue.wrptr&=QUEUE_LENGTH-1;3 j3 L6 [# W( O  k% E, ]5 ~
        if( queue.wrptr == queue.rdptr ) {
5 c6 O2 Z9 Z" p) j" t                DEBUGOUT( "queue overflow.\n" );6 x5 J* ~: v# B2 ~) P" {1 C+ f
        }; V7 F1 m$ U5 ?! @5 v( @
}
- j- _5 V: K" ]# ^+ D
9 [" B" b' o) v; _6 S+ mBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )! O6 w% w# G% j) k  e. ~/ ?
{, z3 e  h+ i+ k
        if( queue.wrptr == queue.rdptr ) {
% |  V5 A% G% T9 M# E& F                return        FALSE;; [" M3 i0 e& t
        }
* C2 ^2 P! b: q3 Y8 h        if( queue.data[queue.rdptr].time <= writetime ) {
: a( Q& s5 {; r% _6 u                ret = queue.data[queue.rdptr];; Y+ F; [+ D( C4 d$ j
                queue.rdptr++;) ^% \! `: B' l& \
                queue.rdptr&=QUEUE_LENGTH-1;
+ ]; i- ^, U0 V" l# s) n                return        TRUE;' C* R6 p8 f: b. z
        }2 r- H& G. z( `2 V0 j
        return        FALSE;
5 T/ g! V0 W8 Y! g8 }8 y}/ J2 [4 D0 @. I2 O  Y! A

5 S' r5 E  P) e1 I& A  t  s/ I2 Qvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )8 d; l6 d& X9 f
{
0 Y# g0 u2 a& k0 F, r        exqueue.data[exqueue.wrptr].time = writetime;. l4 |# g& F: ?- F! y5 Z; A
        exqueue.data[exqueue.wrptr].addr = addr;
- o5 g& J) `5 U        exqueue.data[exqueue.wrptr].data = data;" K" C- F) H; C% c" {/ T
        exqueue.wrptr++;
6 D: o1 I: \0 I7 W* ]        exqueue.wrptr&=QUEUE_LENGTH-1;- ?$ v/ ^& E+ }: U* c/ S
        if( exqueue.wrptr == exqueue.rdptr ) {
7 s5 v4 F7 M2 p7 k' U                DEBUGOUT( "exqueue overflow.\n" );" E- T6 r, w: L2 }" Y! q
        }  R; p' y! f7 L2 P" ^1 x
}  V: R4 ~$ h, x3 t! ^6 F
: }" ]# ^' X( K" _0 b& k
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )1 g5 F( ^1 d. K+ q/ Q2 |$ x" i! p
{
( Z$ V/ I0 h/ O9 L        if( exqueue.wrptr == exqueue.rdptr ) {" b; Y- s) M: a
                return        FALSE;) I1 F  {: f! m2 `: u
        }/ `$ r7 ]* p8 {
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {5 I! H+ U/ l3 [0 o
                ret = exqueue.data[exqueue.rdptr];
" Q9 U) I# [6 ^$ [. h! c9 S1 j" o, N                exqueue.rdptr++;
8 ], r' d( W. P% l: U! N                exqueue.rdptr&=QUEUE_LENGTH-1;
( r8 T- n" O. B0 Q5 \                return        TRUE;
. P3 m1 z+ Y, Z5 r0 l6 r        }
+ ^4 q! ]. t. J/ x: H% l' |        return        FALSE;9 C- [4 Q! D2 X, m/ u
}& q5 N2 Y2 u4 r7 f& T- g/ I: E

+ Q, C, U( t( Z+ lvoid        APU::QueueClear()
7 [$ t& G0 g3 p8 [{
9 |1 m- {& v  s        ZEROMEMORY( &queue, sizeof(queue) );1 V, |% w$ G" e
        ZEROMEMORY( &exqueue, sizeof(exqueue) );; L" D+ }1 O5 v
}
/ e- t$ ?6 R' C- W' h- m; I2 D) B1 G1 |( }5 Y+ {1 i) u6 w
void        APU::QueueFlush()& y7 d) ]) e- M: q# S5 F& r
{- q3 D5 q8 X. a1 w( R
        while( queue.wrptr != queue.rdptr ) {
# I0 @  v' g6 d. `) w7 I) F* s4 \                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
2 E( s$ Z1 U% V. d                queue.rdptr++;
& j1 B! J& p: S                queue.rdptr&=QUEUE_LENGTH-1;4 T. T# U6 G% H! j3 W
        }/ c! k, P/ `5 u) R1 s$ V0 B

0 E6 `1 Q( L' h9 f; p        while( exqueue.wrptr != exqueue.rdptr ) {6 D  a4 m$ o2 a' I2 f
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );$ G/ O5 ^! F; M8 c, R
                exqueue.rdptr++;+ y! }0 k# N3 g) ^/ K+ g: K" |/ s
                exqueue.rdptr&=QUEUE_LENGTH-1;
7 T/ a5 Z: U) W- `        }% x) f( P1 O6 D' p" M4 ~1 D
}3 h; ?' \1 t" r  g2 ^* z+ A5 ~
+ ^- R$ J& |- `$ K/ V3 g
void        APU::SoundSetup()
0 [' M1 ]; Y! q* i3 D: U* w" @9 Y{
* J$ [% p/ u% Q7 q8 Y5 n        FLOAT        fClock = nes->nescfg->CpuClock;
" V, Y- R/ z4 r" V( ~: h        INT        nRate = (INT)Config.sound.nRate;
8 J# ~& A& N5 |- W  `        internal.Setup( fClock, nRate );
0 f4 P! W. @4 m' b4 Z6 I        vrc6.Setup( fClock, nRate );+ ?- A" w7 Y  l) }2 I$ g
        vrc7.Setup( fClock, nRate );0 U4 P6 h9 `8 g! R9 j
        mmc5.Setup( fClock, nRate );1 B7 j! i: ]2 r) v. Y" Z7 l
        fds.Setup ( fClock, nRate );8 T9 \' x$ @- _5 R5 x1 ~
        n106.Setup( fClock, nRate );3 M$ }' i8 G, X% I+ |) b( q) u
        fme7.Setup( fClock, nRate );
6 {3 F0 b9 _$ c: q' e! i}
* R8 D9 M- K( t
$ l! h, c  `! Fvoid        APU::Reset()' ]( i# G5 b6 s1 b8 f7 w
{
! k* T/ }3 Z6 W        ZEROMEMORY( &queue, sizeof(queue) );. G/ H) U0 S  Y8 a
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
5 j6 C* l! ]* q" ^1 X
5 o2 S8 ^  |  \# P        elapsed_time = 0;
- J3 N$ @9 ~6 ^: `# E' v& z; B! @. H& X0 c3 U9 g. w6 d
        FLOAT        fClock = nes->nescfg->CpuClock;  q# t. T! C8 N9 x7 e- S+ r  w, A* J
        INT        nRate = (INT)Config.sound.nRate;; s& M: @6 g3 a5 T9 j' |. ]: E
        internal.Reset( fClock, nRate );- k! F& r1 B5 T4 [9 z% B2 Z. M
        vrc6.Reset( fClock, nRate );0 B; f* s5 }$ o* S0 m" ]7 C3 ~
        vrc7.Reset( fClock, nRate );* _7 R2 s: I8 w& I- t& _
        mmc5.Reset( fClock, nRate );) i" y, q6 k9 m8 a0 `
        fds.Reset ( fClock, nRate );* P  C2 c, T- c  q, v
        n106.Reset( fClock, nRate );
  ~1 V9 b5 D1 j5 \: [( D        fme7.Reset( fClock, nRate );# i3 y3 {2 `1 ]4 U# h' ^

& A' j0 L' }8 I; E- g$ N        SoundSetup();6 m8 W, g0 v* F" k$ l/ O2 D- ?
}
. C& P$ d& j2 V6 b$ ]# F. |  ~8 K* W, e+ c! y
void        APU::SelectExSound( BYTE data )
2 p0 T& G* q( v{
2 I3 g% d$ ^, P' k6 ]        exsound_select = data;( U4 {4 e7 a: E& E8 R
}: ~0 A" `0 ~9 u. Y' C: T# E

; z" ?: q* w9 X3 V% d! cBYTE        APU::Read( WORD addr ); F4 c; Y3 A3 i; Q: Q, W* O( C
{
8 k" g- j- F1 \. e* |, N        return        internal.SyncRead( addr );. n. o' Y& Z6 v& ~# \2 _) T) b/ A+ G
}
3 p( R; u5 e$ j0 M7 L9 Y4 m( Q4 ?3 c. ^4 |, f9 x8 B; ?8 }: ^
void        APU::Write( WORD addr, BYTE data )+ H  J* h5 `4 y0 I) f- c
{. l/ c& q! N! r8 S
        // $4018偼VirtuaNES屌桳億乕僩# E2 x( @( T& d7 [" O
        if( addr >= 0x4000 && addr <= 0x401F ) {
* s: B4 ?7 W' y, V  \                internal.SyncWrite( addr, data );5 ]7 ^3 U) |5 n0 \6 K2 J8 ?# u
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );- e/ E" b6 c8 o  C6 I$ M' i
        }0 d9 Y2 w) m6 f& b) E+ L
}
' r( b. q# Q1 d7 A  |9 V
) p' N, u1 K  RBYTE        APU::ExRead( WORD addr )
+ O/ F7 b4 t5 z2 I{) F3 b' F+ I- F. k1 ?" n
BYTE        data = 0;
( H* v2 X/ y4 Z2 Q) M5 D# J. W5 `, @/ g
        if( exsound_select & 0x10 ) {
3 c* ^) N" W- l- ^                if( addr == 0x4800 ) {
7 ^; _$ z7 Q' `, m2 }" I6 p' D( L# ]                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
+ v' ^) d+ \7 i7 U! H; T/ l0 b                }) t2 y- B3 ]2 B5 C
        }
" l7 E1 f* `: j! A* b4 P$ X        if( exsound_select & 0x04 ) {
1 }0 M% O0 z0 k% P/ z& p0 \, i                if( addr >= 0x4040 && addr < 0x4100 ) {
6 x  H3 {: {7 A                        data = fds.SyncRead( addr );
# ?1 Y$ n, Y6 f- c. T' k/ }3 N                }& t) i- S: y; m+ {; W4 I* E' e
        }
( p; Y8 ~- M( f        if( exsound_select & 0x08 ) {
8 @6 v. b9 S" N0 m3 H& k0 s& r                if( addr >= 0x5000 && addr <= 0x5015 ) {
; d& ?% z  I1 C5 ]3 p  H  V  Q, W                        data = mmc5.SyncRead( addr );
% ^: e5 i9 Y" e1 B" g  O                }) y) i0 t; s* W/ {1 t  J
        }
9 F! ~5 |, R0 A  c% G3 L7 C
4 |+ T: J( w8 q! B7 z: E. o& y) P+ O        return        data;
0 l, R. W3 J9 q$ h2 _4 g5 V+ Q0 m' ^}2 h. p! Z$ k- o* h6 Q
( o9 ~2 m1 y5 t$ |
void        APU::ExWrite( WORD addr, BYTE data )
) H; r" X8 y" }# K{
2 t9 C8 X4 z) ^- v( x% n        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );4 R) _! {" U8 T

( I+ p' [( B9 Q0 `        if( exsound_select & 0x04 ) {
  \' W, H  \9 L; L% E                if( addr >= 0x4040 && addr < 0x4100 ) {
$ q2 O9 _  B" c/ o                        fds.SyncWrite( addr, data );- F' c3 U# F8 T! {; F  A8 @
                }4 V1 y, A! `8 a5 q" ^* q+ f- k
        }
+ e' p% V+ T6 V+ N
  P* Y+ x8 {+ Y- ]; n# D3 y        if( exsound_select & 0x08 ) {
( I) l9 T! P: t4 b                if( addr >= 0x5000 && addr <= 0x5015 ) {
& @, ]4 m5 b0 A3 w                        mmc5.SyncWrite( addr, data );
: b1 A! I! h/ V8 B' Z3 E" r                }
* _/ v. R7 J* J: F        }
3 J6 L' a/ H! J( ^$ x3 T* \}
  b0 B( r; {$ _  e. D
7 y: c8 I: g7 Zvoid        APU::Sync(), d: u# x& q# ^
{
- n% E! Z  Y4 K}
3 f% V! p2 T; i5 a+ d) }. z
' U$ p+ w  w& [& ]9 s4 I1 bvoid        APU::SyncDPCM( INT cycles )
4 N( t- V- d; N5 p( r{
. q. `/ H. T: o- I% W) s        internal.Sync( cycles );) Y# u% X. g! Y2 m  n* K
; H: d1 p1 C  t( a; l% H, b2 ~
        if( exsound_select & 0x04 ) {
- ~4 I. n1 H; b, d6 F                fds.Sync( cycles );/ Z7 ^2 b4 D/ E
        }5 L" C" E2 M5 ^% Y
        if( exsound_select & 0x08 ) {8 b; e: h) A* f( Q
                mmc5.Sync( cycles );0 y( G* E: k$ c$ E# Q) w
        }
; U  e/ T) j/ W! d}
0 {- T( U- b% Z% |! Y0 E! h, r' y, r$ ~7 q: v' B3 U
void        APU::WriteProcess( WORD addr, BYTE data )$ }2 j/ _( k, U1 ]- q+ L# S# L
{
3 q& V9 @4 J: A7 h        // $4018偼VirtuaNES屌桳億乕僩7 Y2 C; z1 e  C/ h# t
        if( addr >= 0x4000 && addr <= 0x401F ) {
; B7 f6 V4 G" y3 w% e6 `5 d* X                internal.Write( addr, data );
5 ~1 T5 o- i; b2 {        }7 M( s+ |7 D; T4 y
}+ ]$ C2 E! s1 b7 {5 ]
) \" M5 }/ |7 N( g7 L8 g
void        APU::WriteExProcess( WORD addr, BYTE data )9 A( ~. U7 N& o2 f  v- `( [( J
{
' g/ k3 Y( m+ V& I7 {; H+ ?/ K        if( exsound_select & 0x01 ) {
3 h8 S9 U: w* |  E: ~: n                vrc6.Write( addr, data );
9 A$ e6 h8 T) `3 T5 I* Y0 w1 I        }2 c5 `7 e/ X  a' b" p4 e! K* {) v
        if( exsound_select & 0x02 ) {
1 u" }5 X& U$ i/ Z! H" H                vrc7.Write( addr, data );" b( t% h( \/ @) `2 r" p& e3 u  M
        }, v6 H8 B% x$ c: U
        if( exsound_select & 0x04 ) {
3 u0 W4 a9 c: G" O* J8 Q                fds.Write( addr, data );, m& J( L) T; i# G3 @5 ]6 L
        }
: n& {" `5 i5 p7 ^) y        if( exsound_select & 0x08 ) {# w$ k7 X" Y% N: L7 D5 L4 F1 {" t
                mmc5.Write( addr, data );4 c% ~5 y) n& @, P& P6 r
        }
5 F% K& V) s+ [/ \+ L+ c+ e0 e) z/ \        if( exsound_select & 0x10 ) {
( \8 ^9 j2 L2 T4 a. u$ s. N) q$ B                if( addr == 0x0000 ) {
7 I# L; r1 g* T3 q: f                        BYTE        dummy = n106.Read( addr );
! s% g. |6 T! E8 ]/ p  A* C                } else {0 m7 O: x! i( P- C4 D4 N+ x
                        n106.Write( addr, data );
3 w/ i0 O; n6 I- r, z3 [                }
- l: J5 T6 y) T- B3 g        }$ K5 O/ W) t0 ]9 p+ {( y
        if( exsound_select & 0x20 ) {5 Z% D7 a8 t/ H3 H
                fme7.Write( addr, data );  i0 O( _  a* S  E/ L3 t  g8 U
        }
7 F: T' \% X, f! \. O}# }3 K. s0 u" }6 \* v$ V

* v% g% \3 X' w+ r4 Ivoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
1 x8 R" f* b! U( F. S0 b% k{
+ T8 P& Z2 Z/ S, E' q$ Q  ?INT        nBits = Config.sound.nBits;
3 t: L' O6 g# E$ ?DWORD        dwLength = dwSize / (nBits/8);
. D+ Q/ X6 k) xINT        output;1 `. M% A/ T+ R) A: |/ J. B
QUEUEDATA q;
. ~' s% z% o0 |5 j+ M" g3 @: N0 t2 d6 oDWORD        writetime;
0 V( f; F! e* {) P& s$ O* E; g/ M  d# m
LPSHORT        pSoundBuf = m_SoundBuffer;
6 Y& L4 S' q8 A5 f6 ?INT        nCcount = 0;
1 P& R/ v4 }1 g) F$ @' |) I, K" Z  z# C
INT        nFilterType = Config.sound.nFilterType;7 h- B' c7 M1 ?7 s+ S+ M
! L) o! D: _$ v3 \# R8 M. w* o+ C
        if( !Config.sound.bEnable ) {
# w* u3 S- Q2 `" S0 n4 l) I/ J% D                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );3 ]- X& O( i" f0 r' g9 ]* p' J
                return;2 R# R3 w8 ~3 Q2 q. `+ B* Q3 \3 o# c
        }' B/ x8 y& N: e( Y0 d% y1 {
1 b9 I2 l; h7 T$ v
        // Volume setup. j0 A. `" ?) V! }( N7 k+ x
        //  0:Master
9 f6 H+ t- y1 W: _: w8 Y2 F        //  1:Rectangle 1( ^' q; U4 K; }5 C9 C, ~
        //  2:Rectangle 26 N! g8 x, V" G
        //  3:Triangle
& j/ X& f& ~2 z# |8 v3 j0 K        //  4:Noise
' P- U' J+ n& J5 J+ A/ \        //  5:DPCM1 [1 b1 [& M+ U8 b* p5 X" _" w
        //  6:VRC6
/ X; k2 z# c- i1 J$ B        //  7:VRC72 P: O2 {; V1 T8 w5 o+ G! X
        //  8:FDS
2 K2 R- v3 F( R6 x; b5 G: M        //  9:MMC5* j$ n' Z$ `% U2 Q0 J8 a$ a1 d1 x8 R
        // 10:N106. u+ `! a4 ]7 L
        // 11:FME70 u2 s2 I8 m& o1 ?. V) u$ }% b
        INT        vol[24];
! f% w8 U0 A: O        BOOL*        bMute = m_bMute;
0 X; o8 `3 e. V5 n        SHORT*        nVolume = Config.sound.nVolume;
/ w) V% |/ y$ o% h1 V
0 }1 \5 q! v" x. i5 @        INT        nMasterVolume = bMute[0]?nVolume[0]:0;3 h7 {7 L6 o. a  i8 m: G$ T1 v' S

* x1 P& v8 w- y0 J        // Internal
0 K, q, v, L. y! v/ x+ e+ t' n  `        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;" a1 L6 d  E; x* b! @, b
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;- }7 C/ @6 m1 ^' ^2 x
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;7 A, ]/ O, \1 E" ]9 R$ D
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
3 p/ H4 k/ A# k1 e        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;3 H( `$ l( K( N7 S- I4 C

4 N# |, k. p% j6 d+ f% L        // VRC6$ O+ |8 b# l; Q7 p  ^, |, [
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
7 v8 @8 x1 g7 d1 M1 Q        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;! }- M. t! o+ }0 R! Q! L
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
8 c; M" T  p. X' }6 }
$ K" w( @) V, W& ~9 b+ k: R        // VRC7
' o$ Q) N) m8 n) B7 _4 A        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;# U1 T6 w: _& o) Z+ R& }, \

* Q- M) n8 s- u5 k' K        // FDS* T: c# Z% i, G: n5 L3 H# j8 m
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
! f0 T4 ~2 |6 ~% O( `( ^3 k8 Q+ ?2 U/ N/ a
        // MMC5$ [. ~( A9 u; ~4 Y" F0 v& f
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
+ l) v9 u0 x) t' g/ l( o- I+ F        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
; G% m/ a' o2 q4 |: u) p  X6 s        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;# H7 E. f# W5 \6 S. ?7 R8 ^4 t
2 j* F) F& }* a4 D! M7 i
        // N1060 L5 G; Q0 a5 Q5 ~; ~$ i! E
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;. I1 s8 H8 a: O
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. D9 T! Q3 I: d. H  Y( u$ ~3 a        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
* P. @1 `6 i' J& n; `( a        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;1 r# n! D9 I% J& E. v: G& U- s
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;. @, [' f* S4 B# L% N7 s
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
9 H' q: |# [5 y& j3 h1 u% J        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ D3 L: w1 ]/ m$ w
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;" E9 Z* J5 i9 q1 `! L( `

$ T" P, q- ^" |/ c" D        // FME7
0 a6 i6 ~& I$ z- T! I& ?        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;5 @+ ^- `7 m8 `
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
- s9 M, B+ U4 E: j! T6 a2 b        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
1 V8 C. s5 l4 H; t8 v# j. K- }% x: C7 M7 I- f  Z
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;6 m" F: Z- y1 \9 d
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;# f. q' R" d: t% b: E. B* {( L% b
5 H! r  t% A' P6 C0 ~: S
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
1 N; G; K  L, j! _- H6 V        if( elapsed_time > nes->cpu->GetTotalCycles() ) {& P2 w- |& T- H* [
                QueueFlush();
/ o& K; N5 r3 k+ w$ O5 q  n" r        }, e/ Q1 F8 _8 F- y" _0 I2 _7 ~
4 Q% q0 T( d9 s2 k& ]$ Y' S: ]7 ]  R
        while( dwLength-- ) {. q( w; b$ i) r0 z! L3 u, }* y
                writetime = (DWORD)elapsed_time;- {) R) d1 Q' Z$ |* H

+ U, c4 @: @# x- x/ g                while( GetQueue( writetime, q ) ) {
% t: l5 I) a- g7 c% I* l                        WriteProcess( q.addr, q.data );
1 N2 E, p' @7 \/ z                }# d4 h& J2 l# v9 S

( K' }( O. c' S" _* Y                while( GetExQueue( writetime, q ) ) {
) U; n0 x+ w2 g1 E5 G; }                        WriteExProcess( q.addr, q.data );
% C  ^/ |& ?* F& M                }
; c' d8 Z, R7 h$ a+ w9 P7 g; G; y' b$ M
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
0 _- K, e9 f# G+ z2 {                output = 0;  ^0 U% P8 ?  h$ y
                output += internal.Process( 0 )*vol[0];# B- L, q& U7 _, v4 g, p
                output += internal.Process( 1 )*vol[1];
+ s% R: i5 d* M3 u                output += internal.Process( 2 )*vol[2];
* v% J0 W& X1 S+ O* E                output += internal.Process( 3 )*vol[3];0 B" F1 R2 l& U9 y) ?! F
                output += internal.Process( 4 )*vol[4];+ n3 r' P( W7 m  I, t  ?
! t  r! |: ^* F) u4 D& }  V
                if( exsound_select & 0x01 ) {
; ~. Y3 m9 v6 m% k                        output += vrc6.Process( 0 )*vol[5];
4 v& x/ d9 Y5 q; q, [$ E; x                        output += vrc6.Process( 1 )*vol[6];
- P) N3 O/ U  Z, I. {. ^                        output += vrc6.Process( 2 )*vol[7];) M6 G* z' s4 R$ g( [( G
                }
* K+ q4 j! Z0 c3 r* y6 c( L                if( exsound_select & 0x02 ) {
7 b7 B% D/ @6 Q                        output += vrc7.Process( 0 )*vol[8];0 U0 _" _) n& B5 G3 K
                }
9 g' ^: x) Y/ A                if( exsound_select & 0x04 ) {
" P/ l3 D" Y  h% L- e                        output += fds.Process( 0 )*vol[9];0 D( N* ?+ J& f+ b. i& ]3 |
                }7 v  u& J$ O& D/ L6 _$ E
                if( exsound_select & 0x08 ) {
! S) K1 ]8 J, c                        output += mmc5.Process( 0 )*vol[10];; g. O- F( F( {8 @2 r% B# K5 V  @
                        output += mmc5.Process( 1 )*vol[11];
6 O( V- H: c' e8 r                        output += mmc5.Process( 2 )*vol[12];' C1 h; X" x0 O* \  p. T
                }
" X( U$ \3 _$ o/ O% S, A6 l                if( exsound_select & 0x10 ) {
/ U! x" z2 u2 u& w8 V                        output += n106.Process( 0 )*vol[13];; V/ P( }* T' n, Y
                        output += n106.Process( 1 )*vol[14];
7 f, }4 M8 W% T  ~                        output += n106.Process( 2 )*vol[15];! _0 e  @/ Q# _
                        output += n106.Process( 3 )*vol[16];- y$ t  L  `5 A2 |
                        output += n106.Process( 4 )*vol[17];3 J- @* ~8 P  T7 S* A
                        output += n106.Process( 5 )*vol[18];
( t  M3 O1 R: U0 s! e                        output += n106.Process( 6 )*vol[19];$ M, U# e* {. a: Q9 F. F
                        output += n106.Process( 7 )*vol[20];
2 C' ?) S' ^/ Z4 T                }
$ A0 ~) Z  b5 V9 |( W4 ]/ h                if( exsound_select & 0x20 ) {
# p0 y; Z, g# z% G$ b; ~1 ?9 ]                        fme7.Process( 3 );        // Envelope & Noise
6 L; r$ `) G! c7 h% `; [; j9 K                        output += fme7.Process( 0 )*vol[21];
: j# b; A; \2 ?/ O5 k                        output += fme7.Process( 1 )*vol[22];. F4 a. O  [: t7 t
                        output += fme7.Process( 2 )*vol[23];; t  o, C6 U, @; N+ b, o" F: i
                }/ _) D% K# U1 x, @. N4 z, ?, m
$ q7 ]& e2 H. F) L" a
                output >>= 8;1 p; `7 D8 J. Y( o3 t

$ ]/ X' w$ x8 C                if( nFilterType == 1 ) {+ H+ [# q. a7 _5 u6 s
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)% `( G% s+ @0 ^4 ~7 ?& B
                        output = (lowpass_filter[0]+output)/2;- N% S& R3 z$ C
                        lowpass_filter[0] = output;& N; L* }$ C, U, J0 B4 x1 u
                } else if( nFilterType == 2 ) {
* i6 B$ G9 W7 G; Y' c( S                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1), O! I) i2 m0 C  _) m$ G3 e3 |
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;; T$ R: _9 F3 p
                        lowpass_filter[1] = lowpass_filter[0];
, J0 p" V+ z; d$ r                        lowpass_filter[0] = output;
" l9 K5 r! p% k6 ~1 C                } else if( nFilterType == 3 ) {
) N2 p$ |* j& k  F                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)6 l5 m/ n- z* a6 v
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;5 H% W0 z2 e  z) Z1 k7 S
                        lowpass_filter[2] = lowpass_filter[1];
: O2 r5 h; Z7 X9 b( i/ J1 x# T" i                        lowpass_filter[1] = lowpass_filter[0];9 W( Y5 B* H& X5 N
                        lowpass_filter[0] = output;) {. k  D$ k) c/ q
                } else if( nFilterType == 4 ) {0 Q% n! d( K  b, w8 m& F* Z
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
+ h0 ]& x" `" [                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
1 r$ |* l9 C8 h( t& j. d                        lowpass_filter[1] = lowpass_filter[0];
" x( }$ z- k5 A. T& i; V+ y                        lowpass_filter[0] = output;! P8 |  [! a, x* ]7 a, z& z3 U
                }
8 d2 o5 [- ~( [& G# c) B
1 O" }% K( W# l7 Q% A( H# }; W. e#if        0- F3 F, ]# i$ m" s: _- E
                // DC惉暘偺僇僢僩8 j, j( K( T2 o1 @" N+ o- J
                {
% t. T6 d' }" z& N, C' O                static double ave = 0.0, max=0.0, min=0.0;2 M5 Z! V, [6 k0 x7 o1 j- U5 A) T
                double delta;- l5 E5 O* r' I6 ^- [" E1 @/ z, i
                delta = (max-min)/32768.0;
9 d2 A! H/ P5 t0 R                max -= delta;- ]( W5 o1 S3 T8 G
                min += delta;( |& [! N: T4 ]" n6 M" V$ J" b
                if( output > max ) max = output;; e( v  h' ^0 n" @
                if( output < min ) min = output;; Y3 z; O$ b& p+ K; u0 Z9 [
                ave -= ave/1024.0;
! u) [# ?0 r' r                ave += (max+min)/2048.0;/ U3 v+ e7 a' M9 t6 {, U
                output -= (INT)ave;
) v- q% g" d% I) o                }1 _  b- A% p* f' J( L7 {/ l! }+ t
#endif
5 c+ C6 v5 B+ L' c0 X2 s1 {( n#if        1
% N. s8 O# k  ]1 |                // DC惉暘偺僇僢僩(HPF TEST)
+ G/ e; {& d8 @                {
! T! ^, }4 [7 U1 o. v) A//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
( A) j- T% _, Z2 Q- ~' F; i( u                static        double        cutofftemp = (2.0*3.141592653579*40.0);1 L! Y3 ~5 D- j1 c7 o
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
0 \2 M& a( R/ F  z8 u: R                static        double        tmp = 0.0;
* c" r3 Y6 y( r6 E5 G3 Q+ d                double        in, out;
; C& b, o  |( Z8 n/ s% a# P) g# W0 Z# M+ C; v
                in = (double)output;
2 _6 f3 }% ^4 G0 r7 _                out = (in - tmp);1 v! \2 V2 x. [  B. Y
                tmp = tmp + cutoff * out;
3 b' Y# A4 p+ ^5 H8 m$ p% J5 g$ g0 w( Z8 }' n, z1 j2 l: y
                output = (INT)out;, b% R, I! P  q/ W
                }
- q, X5 M3 O1 G  ?/ |$ q#endif: V5 d% ]: v& |# [
#if        04 x4 H- c! @% e
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
; s6 S3 l- [3 {1 |: j                {
0 ^- a1 V6 {* [( b( e4 n                INT        diff = abs(output-last_data);; Y% x9 W7 z; i9 w6 D6 |- `
                if( diff > 0x4000 ) {
, \. Z3 T# M" W! h8 s$ b' L& I                        output /= 4;. l% p! g! M8 K# F/ @
                } else & u' H: U- s7 i; ^; ?1 [
                if( diff > 0x3000 ) {  J4 D  k, B( V/ H# h
                        output /= 3;
( H" |7 s1 S3 B6 C                } else
! o6 U% I! e* C1 o4 u                if( diff > 0x2000 ) {
: Z0 A0 U9 N' F! d$ r9 s0 h8 ^                        output /= 2;
% v% R, f" E' f8 f0 @                }" X: t" L( V+ e6 r+ c% C+ w! i
                last_data = output;
' u4 \) O& `6 B* L/ C                }
1 C+ a% N8 G9 L' M+ n#endif
0 h$ d% L$ {1 P6 N: q& C                // Limit2 m/ W! ~, o- p8 x! ?4 C
                if( output > 0x7FFF ) {
% J9 G3 A! c! U& d; `3 Z                        output = 0x7FFF;2 W* E1 }7 J3 H7 g8 a
                } else if( output < -0x8000 ) {
& F1 F( S+ r6 m" ~2 Z+ ^                        output = -0x8000;: X8 o; x5 [' T2 Y" j7 K" t7 P
                }
& _# T3 o9 @  e
9 `2 B# H/ k2 S0 ~  t/ z# t% Z                if( nBits != 8 ) {
9 \) X# }% o6 n( s) ~  }9 s# l                        *(SHORT*)lpBuffer = (SHORT)output;% U+ j# }) d+ [" ^
                        lpBuffer += sizeof(SHORT);
* |5 b0 w. \, g                } else {# o5 x" k  H7 U9 X- S
                        *lpBuffer++ = (output>>8)^0x80;
" \" x) {, s, X- F1 _. S                }
4 `% V/ z+ Q, H% T! w5 x5 i$ k. z( f8 Y3 C4 J
                if( nCcount < 0x0100 )
5 J, O8 i. y/ Y, P/ f1 n4 ?                        pSoundBuf[nCcount++] = (SHORT)output;; k! w  i# v7 J" ?7 r) @- z
9 e" n6 f4 L( p) p/ l5 d4 H
//                elapsedtime += cycle_rate;7 ^4 x+ h  a0 i0 h
                elapsed_time += cycle_rate;% e  P5 k3 @! G
        }
) B7 `# v! O& L) @  d. J* \- o) v
9 P4 D2 j" J" e( ?7 z#if        1
4 g# u- G9 H- U0 b6 a9 Y        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {( a& R, T8 p2 x
                elapsed_time = nes->cpu->GetTotalCycles();4 `3 a5 C7 X, ~; G
        }$ Q1 N0 S! b7 v/ _+ n+ ~
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
& l2 K, J5 w1 c; P6 ^$ X                elapsed_time = nes->cpu->GetTotalCycles();
! B8 k" \" {. D0 O8 `2 Z* }        }
. ?3 }# c* ^# L#else4 `! N- `; |! f9 ?
        elapsed_time = nes->cpu->GetTotalCycles();
/ S3 X( {  ?. f: Y/ `1 |#endif
' z9 m8 R$ Z& R7 N  N. Z}5 q% M  g0 ^6 m" F9 Y- I
: E- ~: V# Q* |. Q) [% e6 z
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
. r0 J( y$ @$ TINT        APU::GetChannelFrequency( INT no )4 V% ?6 Q1 t5 D8 O2 z
{# r' O$ @0 a$ U2 a% K& A1 o
        if( !m_bMute[0] )5 R' D3 j+ N& }9 W6 Y+ l% }1 A! s
                return        0;3 @# f( e: x3 Q  l  j* d# W4 h
' W) B8 q3 o. k
        // Internal7 L' X& g6 M0 f# {# z5 e' M
        if( no < 5 ) {
8 C. p4 U) R& m5 ~$ O9 u& A2 V- |                return        m_bMute[no+1]?internal.GetFreq( no ):0;
  d" T4 o* w  I' B7 N        }% m& r$ V, B- y; ?
        // VRC6
. [% h6 n+ r3 P* K- E) j        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
2 D0 H6 a) W. ]                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
" F- l1 |3 l3 U0 {4 H2 s; B        }" _( z# r2 }4 y) t
        // FDS5 [$ h' @3 R* t, z
        if( (exsound_select & 0x04) && no == 0x300 ) {4 ?) L. Y! h$ u$ O5 P
                return        m_bMute[6]?fds.GetFreq( 0 ):0;6 K5 k# Z% x6 s  n; F1 S4 F
        }
  ~& d7 v9 U+ d% G0 T        // MMC5
5 `+ Q5 _; Q3 x. e$ N. R3 A. {        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {  U9 S- U2 X8 y7 b# H0 J
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
; \9 K/ K: _# P( G, t4 [+ P( N' ?        }
# t! }) _; D7 f        // N106
1 V  u  ^! Y. A6 m- `3 z        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {- D( u( R  J5 \( V/ ^
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;+ S& s4 m. E) x! P. B: d
        }
( P- j9 y! ^' {. o# T        // FME7% c0 C( L3 d3 @9 L8 k: ^7 x1 K
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {0 N6 v+ i: T0 ]! G
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;0 G2 g0 B  w* G- B* j0 g1 L
        }
: D- F& C2 U6 j; y        // VRC72 p+ T9 y+ \+ Y
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
2 Y4 }4 r. c) |& y$ I" D                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
" p, A% O( G& P) F8 s2 O2 L; r% C8 D        }: d4 z# N3 ]. F2 ?% p: N. _) F
        return        0;/ L: x- R" ?4 ]9 P6 `
}. A1 A4 n# v9 I! y2 B, E) C  `; m
+ y$ g! Y$ M+ k3 ]5 k
// State Save/Load4 \- {% W. ]) c* F7 S1 m
void        APU::SaveState( LPBYTE p )( _6 _" B+ B$ x+ p
{
) p/ X# \* Z4 S7 F0 {+ s1 D2 f! a( ]#ifdef        _DEBUG( `! ?; w! P5 j  [' N( Y* [
LPBYTE        pold = p;. _7 f9 l  A: ]
#endif
+ |* g7 p' q8 Z4 `- i+ d  _
2 U2 c' t, e' v% V0 _) f, Q7 X        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞; Z5 v! T, }; x. `0 G
        QueueFlush();/ X4 v- _7 V# g2 E7 L$ j4 ^
+ v3 t" A- M2 O; E) \
        internal.SaveState( p );2 ~! \( D& r2 g* o; t* M
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
* o5 ]9 ]5 t) l. l8 M; q- q4 V
: M& q1 U; ]* g# C6 X# a6 k3 N        // VRC6
' L( ?! |, N2 F6 m! R        if( exsound_select & 0x01 ) {9 I" s' {5 y+ v. a
                vrc6.SaveState( p );
! B. Y6 |# v9 W4 H! K7 G3 i" b: K! E5 ~                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding2 b* p8 d8 d5 v) c6 ]/ P
        }, _+ E* x1 G6 z. b% Q
        // VRC7 (not support)
7 ^7 z+ b. p. `2 [/ F        if( exsound_select & 0x02 ) {
8 R& h" X5 V) [$ Q4 ?3 c                vrc7.SaveState( p );( o6 q7 n& y2 p7 z) L) ?; t
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
4 c) s  `# {4 O( K. M4 F$ D        }4 g1 y: H( p: ]" b
        // FDS3 \" k/ `4 V* @9 o3 t$ R+ l
        if( exsound_select & 0x04 ) {& t) p, [$ j2 h. _
                fds.SaveState( p );2 I. B3 X$ {) W
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding; B. V  S: n8 H. ^) |
        }# {% l2 s0 c; J& m
        // MMC5
% Y) Z" W# ~3 o- a+ ]8 _$ u5 A. o# Q        if( exsound_select & 0x08 ) {
5 s" o: i, x. O2 W9 a0 L3 B1 _; [4 ]                mmc5.SaveState( p );
+ z3 }8 Z+ u4 F# N' u1 d/ r! F                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding0 x9 H  R4 h: U/ }) b& m. ?+ @
        }- z+ C% [9 }( y
        // N106& x. I" P3 F8 c/ k
        if( exsound_select & 0x10 ) {6 @3 m/ a: T6 \+ k; g$ n( J: w
                n106.SaveState( p );& A2 N! L% k8 V( i6 y. C
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
, a% c+ a6 C% {/ w3 c9 T2 \        }
4 c+ W/ L$ f& o7 T7 m        // FME71 ]  a; e/ `. v0 b/ m6 [  M
        if( exsound_select & 0x20 ) {
5 j# P0 C: n# ?( p                fme7.SaveState( p );
2 p0 e( Y1 [, l8 J* |/ X/ u                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
! A* n! }6 x) W8 v% ]5 Q* Y        }
& g- r3 N/ j7 c4 T
  r# a( ^7 o9 g#ifdef        _DEBUG2 `1 J/ l0 b5 }: M1 g
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
, u& A( q1 E5 c# _7 e/ v#endif6 g( |6 V. u3 X4 j1 n! @
}
* P' [9 A6 k& W! L; N9 A) Q' g# V3 R0 r
void        APU::LoadState( LPBYTE p )
. L6 a: h6 Z& S{
' \% O+ L/ |9 S2 _        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
+ b9 o. @! U6 I        QueueClear();- s  ]2 c8 @8 @7 n
0 F( t$ {6 ]" B/ R7 D
        internal.LoadState( p );. z% }( F$ B( e7 Q
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
* h* ^" ^* ]9 |8 g
8 a) f$ I3 w% g* }7 J        // VRC6
3 s) ?+ U" K; e' S9 Z  {        if( exsound_select & 0x01 ) {) n7 {4 C- o$ A4 ~
                vrc6.LoadState( p );
2 R! L% M3 n; o# B  _! U8 `                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
( Y4 J0 T; }; V+ Y" B        }3 f- u  E" f  U- L) K: I% b. S% W" t
        // VRC7 (not support)
1 S+ M% g  w& q* T+ m        if( exsound_select & 0x02 ) {
% q9 Y8 N! v  K- O                vrc7.LoadState( p );
  c, Q5 m" x" ]- ~0 d2 \6 q  c                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
( S! q, n$ K3 g+ I8 @" j9 `        }
5 I' y: J1 j5 C: o& H+ `  X# ?, x6 @        // FDS
, a  P" F; ?1 @" I+ a2 a; r        if( exsound_select & 0x04 ) {
% Q& k- w5 U6 \; B/ b* k# ^0 |                fds.LoadState( p );  [8 @. G8 B7 j% T2 k2 L2 i7 G4 L
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding( U  ^1 F, T# W9 k+ t3 ]) y- Z. v
        }
/ p1 [, w: o) d4 Y& d: i) h        // MMC5' {3 i; T" I. L0 ?) \7 ^3 b
        if( exsound_select & 0x08 ) {& l7 V; m0 O! m: D% D+ p/ P2 n2 G: Y$ y
                mmc5.LoadState( p );% l/ X5 B6 ^4 k3 t( K8 r+ S+ H+ S' A
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
8 i# S: t+ a7 v2 i2 p        }
0 K! k2 z' |* m# c! |: O' a/ |        // N106/ d! ^  L8 V. m4 U$ G* W
        if( exsound_select & 0x10 ) {" s/ J9 m& V1 E( ~4 f1 C* `
                n106.LoadState( p );; ]. m! g4 Y" L0 n
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding3 B$ t) m8 @5 N2 L" X% w2 c
        }
6 A) ~! h; B& T, N1 q/ W  K        // FME7
2 k9 Y: n4 s2 ~; v, \        if( exsound_select & 0x20 ) {1 ]( Q- @# s$ a. z  W! s
                fme7.LoadState( p );
9 a. D2 q1 L$ v. |. V1 K% {' r                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
+ `9 c( Q# \6 e0 w4 o9 O1 q( e        }
! H" o4 U* Z4 ]8 a8 O}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 4 c  ]- [; Q+ U! c% p/ P, E
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。! \* d, Q2 k' A9 r, }7 J2 U
感激不尽~~

5 K' Z5 q( r+ o恩 我對模擬器不是很有研究,
% Z- v9 ^& L! S' w" @9 {雖然要了解源碼內容,可能不是很困難,/ ^: e, }0 Y( j5 k" u  _+ @
不過還是要花時間,個人目前蠻忙碌的。- t$ y7 j; S- R- R7 ~" `, r
! X! {4 |0 x$ ~0 c9 g( A
給你一個朋友的MSN,你可以跟他討論看看,
6 d& A9 `- Q/ A! w他本身是程式設計師,也對FC模擬器很有興趣。
; x$ \# P6 j3 s8 G- y$ s. f$ c3 m4 m: {* A, n8 e" P
MSN我就PM到你的信箱了。9 _# P# E& c3 I9 l! _

" i( t. f$ J2 n- p希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
- h5 K7 ^( d& q1 q5 ]& v呵…… 谢过团长大人~~

" j/ S# y" m1 ^3 ^8 z4 Z/ M1 s6 V" Q, A/ C
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
4 _3 z6 ]+ }( k$ e团长的朋友都是神,那团长就是神的boss。
; \7 b0 v5 n4 Q$ C1 o! C( Q
哈 不敢當,我只是個平凡人,0 X5 u$ p0 q( |/ J, h
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙$ [8 z& r0 O* K* ^2 C) }4 _9 W
ZYH
' A" z$ K: z/ @6 F% c3 g% VQQ:414734306
2 N5 O- O+ z1 O# B5 R% D! \Mail:zyh-01@126.com4 L" n1 ~6 V0 q1 }" T2 i5 p; x8 M
; P: u0 e5 g, `* z0 ^1 W- @
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
5 C4 o( N) q/ m再次对团长大人和悠悠哥的无私帮助表示感谢~~
: ^- J5 a5 a  {5 I
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-3 03:11 , Processed in 1.066406 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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