EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?
) X3 t9 Q! S( w( O* E, T& dPS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
8 {! Q+ F9 ?7 K2 `' N9 J$ a" k楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~, B3 C6 e  u2 Y; X' q
这里有相应的模拟器源码,就当送给大侠了~~) g6 j- R7 A; `0 e- A5 ]
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 : D" U* C0 c5 k
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
. `. K: H! [/ N+ Q: Y3 O3 K楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
' a" Q' `) S( w9 z+ o* \# w这里有相应的模拟器源码,就当送给大侠 ...

$ R: a+ g, _  |6 L聲音部分(Audoi Process Unit = APU):7 L# m! ~% s* K- ~, `
.\NES\APU.cpp) f; [) L' [" z8 e( x6 U: I
.\NES\APU.h
1 H  t6 |# Q% M& K6 V6 A/ t
/ f/ G7 n$ H1 ~1 [, h5 O. }3 A+ W0 j, t. d. h; q- D
影像處理部份(Picture Processing Unit = PPU):
+ r4 O1 u  w$ m/ f.\NES\PPU.cpp
& t6 r' ~0 D  v; {( e.\NES\PPU.h: v; {5 ~; O; y4 \

7 _7 j5 W. j2 U/ k  m& [) U如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:/ M! J3 E! h" \) _1 j
(由于很多专用术语和算法机理都不明白,所以看不大懂……)4 [; ?9 L, J% o: W5 Z
//////////////////////////////////////////////////////////////////////////: a7 `( F% i3 l" c
//                                                                      //
2 p& M2 G+ o6 P, I  ^0 G# i//      NES APU core                                                    //: Y+ h+ t2 x6 D8 I* s& x
//                                                           Norix      //
: [; {$ e; v, N5 c//                                               written     2002/06/27 //
  d* k5 Q, N$ g: b; E' a//                                               last modify ----/--/-- //# w+ ^/ ~% V  K9 h
//////////////////////////////////////////////////////////////////////////* \5 x7 t2 x- K- W4 P( Q/ G5 }2 ]
#include "DebugOut.h"/ @3 s$ W& r% ~' ?
#include "App.h"0 C6 D0 c% n/ I2 Z/ t" M
#include "Config.h"5 F( m  G5 B: P" z1 \# t

! s0 s4 V2 |3 d#include "nes.h"% P/ ]: n0 s: I1 ?4 ]4 x/ G
#include "mmu.h": Q9 W! P+ u; y% x( I/ W4 c
#include "cpu.h"
9 J7 }4 b8 b5 ?; S& b2 d7 z9 ?8 ^+ U#include "ppu.h": a% q. G, n( {9 q$ l( s! c
#include "rom.h"& u5 G/ r& r) Q. W0 l
#include "apu.h"' v9 |5 ~/ i  f0 O+ j( x  ~
& k1 k+ K# M! Y8 V! ]
// Volume adjust/ L4 o) A. \( F- c" [! @  F8 K
// Internal sounds
, v; K" X, R) K0 L  k#define        RECTANGLE_VOL        (0x0F0)
9 u& W9 I, q( @( ?( T% ]- U#define        TRIANGLE_VOL        (0x130)3 _2 A% N# }; q0 o
#define        NOISE_VOL        (0x0C0)' ?7 Z1 ?$ |1 A9 `% N
#define        DPCM_VOL        (0x0F0)
9 ^; j- T5 u# g0 I// Extra sounds
' W( N3 \% E2 m( \7 C# N4 e7 k& ^#define        VRC6_VOL        (0x0F0)
' f; Z/ F5 [/ O) r4 h. c#define        VRC7_VOL        (0x130)4 w4 @4 M$ C' {, O: d3 x2 e
#define        FDS_VOL                (0x0F0); R( A$ T' v( D0 c# V
#define        MMC5_VOL        (0x0F0)
; |) ?# B* ]  E5 r#define        N106_VOL        (0x088)
) g: x  K7 l% R# N4 ~0 E#define        FME7_VOL        (0x130)
5 C! e9 i$ o/ p( E+ A; `0 M7 {+ u/ Y
APU::APU( NES* parent )
2 Z4 N- V1 s" [5 t1 p7 ]{9 L, N- u4 A4 q3 H  v" D" I
        exsound_select = 0;
: S2 R4 b  q$ o- E6 T0 p9 H. y0 ]9 |9 ~
        nes = parent;
4 E* j6 j1 P/ ~) U* t* N        internal.SetParent( parent );$ `9 Z: ?# Q6 R3 C# f2 L% n" o

1 w/ J* X/ v- \/ G/ T        last_data = last_diff = 0;6 f& d( S$ B+ G' A$ s' T

+ q7 A  i2 v! A5 l! m/ Q: Y        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );. t" R, [* G( B0 d0 x: P6 d

5 W. y6 Q4 G0 |        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
1 V# o& K: @( D  ?( u2 f3 B        ZEROMEMORY( &queue, sizeof(queue) );, Z1 ^' x7 r4 `- |
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
( y7 a6 G7 t) }3 ~( x7 X' O# v' c& M9 a8 V$ B8 f
        for( INT i = 0; i < 16; i++ ) {2 I. ~$ V2 |7 F* R6 b! g# D
                m_bMute = TRUE;
8 V8 v9 ?! @/ B) O        }
( z# c9 n& W. L  O" I' H' ^+ }}
+ J# [" \% O, B6 ~/ H
, H' T$ E, o3 E$ f$ o! G' e4 h8 RAPU::~APU()
0 Z3 y, z, B) v  ^{
* J' K& e8 t, Y' f}8 d# C9 r0 T5 x, o. Y$ ~4 ?8 O
! R5 O! s8 _2 e" F3 H" G
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
7 e! u2 L4 b; @* H8 h0 y: |{
# }, U4 a" ]* H- H( p        queue.data[queue.wrptr].time = writetime;9 N1 P% i1 C* F3 X/ t
        queue.data[queue.wrptr].addr = addr;  S" Q" n1 U! z! T' v7 X
        queue.data[queue.wrptr].data = data;3 l0 l6 _0 b: `7 v" q* w% R
        queue.wrptr++;
0 b! X! h( a$ O6 U2 P        queue.wrptr&=QUEUE_LENGTH-1;/ D( H% K0 P  j
        if( queue.wrptr == queue.rdptr ) {
  K  L  A0 m3 Z                DEBUGOUT( "queue overflow.\n" );! K) G2 ]" |, d: f$ Z" A6 w) K
        }
+ L5 _5 C# `! w& P1 l}, \* t4 E" [" I( v9 H/ |& ~' S

2 j- C4 q6 L1 A" A* C" u9 fBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
" K+ L, C6 h2 D9 [! p{
" f5 x) W- R' w8 P0 F2 Y/ P; L  S  u        if( queue.wrptr == queue.rdptr ) {
, k/ Q; P8 w/ l4 b- B$ F                return        FALSE;. P8 T  J2 J: Y, F, p; W" Q- M
        }
. [8 A' f: s9 [2 E% L( K        if( queue.data[queue.rdptr].time <= writetime ) {
2 p* u7 W2 r/ W3 ~& u                ret = queue.data[queue.rdptr];$ m6 M5 G/ w# f5 Z% e. h+ ^# p7 F
                queue.rdptr++;
- ~7 x  B( C7 A3 D, _# P0 j! v                queue.rdptr&=QUEUE_LENGTH-1;
: v/ F( C9 `3 t                return        TRUE;
+ j' M8 ~1 y' w        }
9 v( i1 J' r" l  J0 O, L        return        FALSE;* \1 ]" i+ a' U" d& s" C
}: ~9 ^( ~  k+ \7 b2 m0 a  Y
1 E7 w. Z# e, {* v
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
: f( P5 j' ?6 ^& K  J7 V6 _{
- ]. G' n: ]( [* C5 r        exqueue.data[exqueue.wrptr].time = writetime;0 r7 o% v0 Z* m
        exqueue.data[exqueue.wrptr].addr = addr;- q: C$ F: h# Q1 v
        exqueue.data[exqueue.wrptr].data = data;$ V# ~3 x! c9 H: V2 M$ u
        exqueue.wrptr++;
% R8 P  Y9 C' i0 f' E        exqueue.wrptr&=QUEUE_LENGTH-1;) z* ?1 a3 X; N( I" y/ B1 E
        if( exqueue.wrptr == exqueue.rdptr ) {
, x" M" |# p% n                DEBUGOUT( "exqueue overflow.\n" );& H9 ]. R9 C1 F9 U' R
        }3 H5 `% J3 ?8 Z6 f
}7 H9 {% ^! o4 o0 Y: }. M. i# B

9 P3 X5 }. c5 e7 E4 Y5 X# `BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )$ K$ ]$ e- @. \8 N; y2 W
{
4 F2 B3 L7 k$ c9 h: S        if( exqueue.wrptr == exqueue.rdptr ) {6 @( H. n- |+ n$ R
                return        FALSE;
3 @# }7 g% j! g5 c! I        }
" }* G/ \1 p, ~: [( @+ J5 B* k        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
$ q  o. s6 S5 k" Z  N* ^                ret = exqueue.data[exqueue.rdptr];  n+ d* |5 i) b- Y  c+ t$ O) i
                exqueue.rdptr++;- Y* D/ V* K5 s2 n
                exqueue.rdptr&=QUEUE_LENGTH-1;
. S, N& B! Y  e( V& z7 z* Y% p                return        TRUE;/ W( F1 E0 X; i( H, X
        }
+ t4 k1 t2 o7 b) u        return        FALSE;* r" m2 S% i2 V) S' ~8 a
}
3 z0 e7 ]2 H# j' }) q, v' f1 s2 f' z% O( S$ T# G5 m( X  |% _
void        APU::QueueClear()
& b$ R% c4 i; x3 V7 a{1 `/ f: y- K+ t8 a5 E% ^' U* Q- e3 r
        ZEROMEMORY( &queue, sizeof(queue) );+ Z7 Q( p" ?4 H: Z) h, I
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
  b, |; Z# i: `: ~4 l}/ _( z& g, v) ~! z7 ]
/ ^' @: J( b7 ]4 `. E* U1 t, j$ t4 f
void        APU::QueueFlush()+ }$ q8 Y% _; x4 _2 r
{
0 d. j) E1 q' s; ]6 ~' ~" D0 E        while( queue.wrptr != queue.rdptr ) {( C9 I" T( e8 G% [1 ?9 u. e$ r
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
& ^7 i& U; p, T1 @" d  K5 Y: m                queue.rdptr++;
0 A) P$ T! c( @* r( m$ g, A                queue.rdptr&=QUEUE_LENGTH-1;
$ _( Q5 q  J6 Q( p        }" A$ P( N$ M( V6 x( T+ a/ V9 Z1 {1 |
+ _( ?, H) V- s+ {
        while( exqueue.wrptr != exqueue.rdptr ) {5 f9 D  t+ @; ~( x: @* w* [3 _
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
/ m# J* J; U  ?; z6 _* s                exqueue.rdptr++;4 @" E. j4 {: s% m2 F& F; c( }
                exqueue.rdptr&=QUEUE_LENGTH-1;9 s1 J+ O" C9 ~" s$ O  E
        }7 G0 m/ s) L& h; F
}* S* Z# B( C9 r& T

) c6 M- F0 I# i4 c( I% Cvoid        APU::SoundSetup()
) X' \% m6 c7 N! p* X  c  V* `{
* |; d2 {, ?/ `6 m4 v        FLOAT        fClock = nes->nescfg->CpuClock;
+ S5 J$ H2 q. |        INT        nRate = (INT)Config.sound.nRate;  v2 N7 z1 q6 a) Z) p& g
        internal.Setup( fClock, nRate );; W+ ~; j0 u4 w0 W, B
        vrc6.Setup( fClock, nRate );
6 G7 O9 ]: O: I/ [        vrc7.Setup( fClock, nRate );
  Q1 E5 X; ^) ~        mmc5.Setup( fClock, nRate );. Q; A5 h' m2 X& G# h! ~
        fds.Setup ( fClock, nRate );3 [3 h$ @4 C# }, _7 N
        n106.Setup( fClock, nRate );
0 ^$ B  ?$ a  L8 T1 D" T7 T* c2 ^        fme7.Setup( fClock, nRate );% c6 l' p8 \7 i2 R7 ?6 m! |
}+ m, p# R& W4 q4 V7 a7 V' r

: m3 c6 q, b6 h# W$ s/ y0 b2 p: tvoid        APU::Reset()
, @! J# W" p& f6 c{
% K9 h! l+ d0 d7 ^, ~. O/ q5 v1 w) c        ZEROMEMORY( &queue, sizeof(queue) );
( d7 }. W* U8 J0 z4 @3 A7 U" t# |/ x% j        ZEROMEMORY( &exqueue, sizeof(exqueue) );" U+ {, I. ]) m& A, p  G. K
+ Y4 X5 y: r  w% w; W
        elapsed_time = 0;% G2 B9 c: X/ s: _! Y5 T7 q) I6 F

  j1 p1 i4 N$ W* p7 {; R        FLOAT        fClock = nes->nescfg->CpuClock;
$ s+ p5 j( T4 G1 y+ i2 i  M        INT        nRate = (INT)Config.sound.nRate;2 k* r5 V& V' \4 P6 g
        internal.Reset( fClock, nRate );
, C$ H! Q' k9 c1 D$ V8 g        vrc6.Reset( fClock, nRate );
* F/ T; H& z7 h' K- _- \        vrc7.Reset( fClock, nRate );0 a) H  h) v$ W" x) i  Q
        mmc5.Reset( fClock, nRate );
! Q' J7 E2 v1 Q& F7 i" `3 c$ X        fds.Reset ( fClock, nRate );4 T+ k: [- m# H! \2 Z& u
        n106.Reset( fClock, nRate );! e/ d/ P9 }3 z6 `3 Q/ O
        fme7.Reset( fClock, nRate );
+ F- l# S* O8 U3 C5 L% |; ]8 d. ~
        SoundSetup();+ ?" D, D1 ^6 B  W$ M- i1 c
}3 s* |) K  y. D7 v9 A  |

- u7 \* W# m5 l, bvoid        APU::SelectExSound( BYTE data )/ k( E/ L" ^9 P" _! ?
{
) c) g  D' ~" s6 H        exsound_select = data;
( I7 S6 |! j+ n& z* k( b}
9 l% r) I# h% S
  d- D1 n/ ~- TBYTE        APU::Read( WORD addr )
5 @+ o% `- o+ e: _{
; ]* x, z" L% h% n4 |        return        internal.SyncRead( addr );( T9 `3 G  a. Z0 Y; u7 l
}1 S- o/ h0 w, a$ d
% _% q  c5 [; [/ G1 i" A
void        APU::Write( WORD addr, BYTE data )
  l* y' C+ c7 K3 c{$ X7 l9 E/ d1 ^5 M; V9 }* I
        // $4018偼VirtuaNES屌桳億乕僩
2 q# f: K7 ], y$ @# ^  z        if( addr >= 0x4000 && addr <= 0x401F ) {
# A- P% D& Q7 ]9 K8 v+ z                internal.SyncWrite( addr, data );
2 j5 |4 f/ L0 t& G& ?2 A% l; U                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
/ Z% D! T' U8 ~" R! b! o$ j        }) f7 A' O: _$ R
}( ?2 v4 N8 `4 l& W( M

$ F5 J' t4 U* d/ n1 S% LBYTE        APU::ExRead( WORD addr )& u$ y4 d  n  H) y4 @6 h3 |2 m6 ?
{
. |9 P! w9 [2 u3 ZBYTE        data = 0;0 ~) y6 W' W* e  [

( [0 y5 q, `. B) ^& W5 w" k5 k; R        if( exsound_select & 0x10 ) {
6 l; S- [' s) X6 o. w# k                if( addr == 0x4800 ) {
! a8 A1 i  f  Z1 x6 C4 P                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );7 P8 J8 V) Y7 c) }& F. m3 j+ E
                }
* O$ X8 B/ P, `- @/ M. s% M        }
; v: b. o" J( O" e        if( exsound_select & 0x04 ) {. x9 B$ h9 _3 @0 \- ?; u% B, [
                if( addr >= 0x4040 && addr < 0x4100 ) {
2 I: U$ f0 z  ?9 a& {                        data = fds.SyncRead( addr );
+ t0 _3 l5 J2 ?& O5 {                }
6 P4 W' a! }3 Z7 I        }" Z3 z; f: n' p+ X+ r
        if( exsound_select & 0x08 ) {( s4 P+ D; ?6 D2 _( W6 Y: z
                if( addr >= 0x5000 && addr <= 0x5015 ) {% ?) i+ y! Y( B3 @! x9 Q; P+ @
                        data = mmc5.SyncRead( addr );6 }+ S7 u* N2 [$ g+ `" e8 f
                }
1 d/ v4 W% ?  o* |/ G: h        }
, f/ Q: w/ W- @  J: C
/ J6 ?0 D  o4 ~0 V( g        return        data;
+ M1 z1 w9 d/ g5 n7 M8 N}
9 e& ~) o+ i( S2 a6 f! J+ b, U: H) _/ @) P
void        APU::ExWrite( WORD addr, BYTE data )8 z- i7 b4 _% q. Y4 r1 H
{3 G$ v  A& Y  E% |! J  o4 ?: j
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
6 Y# g* f+ O, W6 i( ~
0 @! V$ `: F5 [$ P- ]5 A        if( exsound_select & 0x04 ) {7 O- A) Q( {- U0 R1 O
                if( addr >= 0x4040 && addr < 0x4100 ) {  m) e6 D( c) I/ `& f& y
                        fds.SyncWrite( addr, data );$ p/ w% E& ?4 D8 y' C7 y, \5 A$ z% B
                }
# |: C& L8 _0 U* b* k1 F        }
- g7 E6 J: o& u3 {, v. O. h
: x3 C$ R, O* h3 \, [. @        if( exsound_select & 0x08 ) {3 N" _- j0 w$ P: ~
                if( addr >= 0x5000 && addr <= 0x5015 ) {
- N3 u: {% d$ o  `                        mmc5.SyncWrite( addr, data );- q6 @; q" B8 ?3 y, R8 `) ]8 T
                }
1 Z3 Y7 ?5 w* [! ~* g4 ~- X        }9 Y$ p8 q" p' u  c: ]# \- l( E7 H
}
1 @% L/ o, p$ j; X8 @! b8 e( D* b
/ }6 J( b5 y+ [. O% mvoid        APU::Sync()0 [* T$ I7 c  i0 {8 i
{9 {! a+ J% ~# G- ]9 E( m& g: R
}
$ {' \' _2 X: C# e: n2 w
% @. R, {$ Z* U! d8 X) uvoid        APU::SyncDPCM( INT cycles ), C3 q1 `0 ^3 U+ V% O; y
{8 S+ U. v( b( H; m% m
        internal.Sync( cycles );, O. |3 M# m  @+ S; l$ T
; o& E& w8 X; ]) r/ }
        if( exsound_select & 0x04 ) {1 \% ]6 _6 h# h, h. M. e2 f7 u
                fds.Sync( cycles );
/ F9 ^5 s) a7 m, d8 v        }
  F8 ?, p) I  Y5 y+ w5 F1 g' u        if( exsound_select & 0x08 ) {' Y. I5 R; ]' e1 k
                mmc5.Sync( cycles );% R+ @; J6 m* ^; K4 h
        }
0 W, ?' i8 H. c( Y  e! [}# y3 Z$ p) h. u' ~' U; d
7 n" Q4 c  }" y9 L- k* f1 r
void        APU::WriteProcess( WORD addr, BYTE data )6 |5 g  I5 I% p8 A( V# E! i
{# y& C$ z1 b1 \0 d  \% p
        // $4018偼VirtuaNES屌桳億乕僩
& d$ q5 v+ _- {) b+ I/ w        if( addr >= 0x4000 && addr <= 0x401F ) {
( T1 `) s: \5 K$ k* o$ m0 M5 J                internal.Write( addr, data );% w, [: `; J! O
        }
2 ~* y8 ^% Q$ P/ q9 A( [8 t}& b9 T* j! Q& N5 [  V: d7 |
2 R: [# A3 Q0 b7 l( n% A
void        APU::WriteExProcess( WORD addr, BYTE data )
) q( S% M6 w2 f; E' w9 J{5 e6 A( Q! a- k' Z) N
        if( exsound_select & 0x01 ) {, W2 n# m' y1 D, Q! y+ x
                vrc6.Write( addr, data );- X9 e0 @7 D4 g) A5 `8 D- d
        }
' o+ H$ ]/ y6 J        if( exsound_select & 0x02 ) {
5 F; h1 Y- b$ o2 ^) x: u2 [9 l) Y- s& A                vrc7.Write( addr, data );2 l, q( C  `" Z! C, e  m
        }; ?0 L! F0 u3 r2 k' y
        if( exsound_select & 0x04 ) {
& x; c! |  ~: k                fds.Write( addr, data );
  U7 @9 R9 \( p) {4 l' ~& L- t7 U        }9 \' p9 F, F# P+ l* C
        if( exsound_select & 0x08 ) {) P# i, b* \+ K: A2 e
                mmc5.Write( addr, data );6 c$ t8 M( d# u) F
        }  h6 `  ?( }; s0 z! v; Q
        if( exsound_select & 0x10 ) {
' m. B7 ]; a3 L1 [, [' `                if( addr == 0x0000 ) {! }; G5 h7 ?! _3 p
                        BYTE        dummy = n106.Read( addr );
' T. k5 S( g% n1 C                } else {
% F- k; w+ ~2 k/ \! I8 i                        n106.Write( addr, data );; T' z2 w: s, h0 F3 h3 a
                }
  ^/ g7 r$ h7 t' M+ C! \9 Z        }9 g) C8 I8 b# S
        if( exsound_select & 0x20 ) {
- W5 P: I1 z6 N+ Y5 E  c                fme7.Write( addr, data );
4 O! [/ B- D6 F! b2 e# M        }) I0 n3 G5 K: A. J7 b
}
4 O) C& A, w) G' o& r' {9 S% }$ d2 @
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
9 D  l& E3 m. _- q3 c1 m3 |{
6 N' x# d  w; O5 @! i/ [$ D5 yINT        nBits = Config.sound.nBits;- g) v! V3 A- a3 m& a& w2 e% @) n
DWORD        dwLength = dwSize / (nBits/8);
; Q' i7 n3 T3 b$ Z- dINT        output;
% h8 ]: Z' w5 i/ w# eQUEUEDATA q;( V" ?% c& Y4 C0 C; d4 Y2 A
DWORD        writetime;
) i: Y) c$ n! i# ?" T! w% O  i
1 W/ M5 u% [' N8 r# RLPSHORT        pSoundBuf = m_SoundBuffer;
- e9 i5 O+ e/ j+ T5 XINT        nCcount = 0;
9 S- C# |: l! s' c/ v3 K, ~2 }
7 T  y" u! x8 c5 G* MINT        nFilterType = Config.sound.nFilterType;
" m- J5 y) ~4 W: P  v. d7 L' q' M7 ^. d9 F! z4 ]
        if( !Config.sound.bEnable ) {) n# M. @) ]/ y% q7 s  R* \
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
0 E0 V1 K" p% y9 P/ W& q                return;, f: a- o( E+ h6 [9 U3 a
        }& L$ n% \0 a7 H& J) Z. @$ E

9 B, s) V/ g9 \) q- w& w& Z        // Volume setup
) |6 K3 c4 A  `' P: P1 i7 R        //  0:Master
% V5 ?; \/ `6 g- Q& l* D        //  1:Rectangle 1
$ L" p! h/ Z, k        //  2:Rectangle 2
+ e- O" O% v5 m/ [; W1 o: \3 w        //  3:Triangle' R* {5 ?3 g4 @
        //  4:Noise
: G) a( _* v$ o% A' g        //  5:DPCM
6 H4 r$ R& B( ?; R( j: n        //  6:VRC6# r8 U6 v$ w9 Z: C2 Q
        //  7:VRC74 V/ R; _- S' k
        //  8:FDS
4 X, t9 L, g5 I% @0 p0 d( X        //  9:MMC5
$ B% c* `: v5 ?: p- w        // 10:N106
" ~2 b4 b# [/ \- z! ~$ R, m6 n        // 11:FME7: c0 |* u- e1 f( j# K, d
        INT        vol[24];+ _( W, b  H" f. k: @' s: a: h
        BOOL*        bMute = m_bMute;
; y8 x( P- E6 C+ _) T# k8 W        SHORT*        nVolume = Config.sound.nVolume;
4 \) [. _1 G6 o4 E# J7 }$ u- x% G! y  |2 C
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
& S, H7 g8 H8 H0 T! M) ~& m5 g) ~- Y& w9 p: k+ W& h
        // Internal* O2 q6 {1 V& f/ _8 h0 {
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;6 d1 {% ]2 D: p4 n: ~7 ~
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;* C3 \0 u. p& S, E
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;% U" D( Y; N7 e: s9 p- o" f4 j- V
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
3 m2 E2 D' D0 m        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;3 ]9 H8 P3 n" o% v& D# o

' K& j- c) H$ e        // VRC6* ^7 ^+ M. e/ M, _% T
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;5 R. x, y; c5 l( ~9 @! ~( O1 V
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;$ c1 z" X- g: y- M
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
- x9 o+ m, w! n$ |1 P# [8 q4 t1 O0 F6 Y2 T  M
        // VRC7
4 u5 P+ j0 R6 v        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;5 r( x0 o2 J( d$ O, D
8 R: i6 e5 C: F( Q1 l! v/ n# h
        // FDS
0 b! a" ~1 |8 }        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
/ _  r; q9 [) x6 E  [: C0 x3 u, ]' L. R+ q2 ~7 [, ]" A0 P
        // MMC5
, k, \1 }( ^& o( U        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
, Y+ H+ L: [9 s( C( `6 Q+ x" V) p        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
! G/ [2 p9 @: D        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
& }- a- B4 W) P; k  N1 B4 ?; l% [- H5 Q
        // N106, R4 G) h) [: d$ J! S
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. L  c, [6 V$ a# u6 k. P# Z1 U        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;  `; N" _; j' t
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;7 p8 {- O8 x' U$ E2 O; O
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 I- w4 Z$ i$ U3 w
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- x- a: B' M6 W1 L$ J; D        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;0 @) S  S/ ], P& M  K+ c+ W9 m
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
; c6 ?7 q& `. _! s7 b        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
1 |( Q6 Z, c2 E2 g( T9 _1 ?  U3 ~' V5 e' ]$ _) R, i, Z0 }( T
        // FME7: T' V' r' q" b# @
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
( p4 G/ u2 Y6 Y5 J1 R( X& {        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
9 {; V6 q9 @6 Z" S8 O        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;( R3 ?* K, [2 h, i8 q# d+ q$ x

0 P( N' I3 g$ s/ K//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
0 V9 Y( e" z7 k, D' D; ^        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
3 v& }3 R! l4 g+ Y
5 w; `4 w: P6 X7 R  }8 B        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
( ]/ H9 O3 p* s; R' R+ `# S! {        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
) Q. ?2 u7 e# b7 V0 \% u                QueueFlush();% X5 k* c, I: \( }
        }
. ]. ?2 c$ s. c: V# p% x. |. N) M5 p7 W) U
        while( dwLength-- ) {
% R9 b1 U3 M  ]: A                writetime = (DWORD)elapsed_time;) I/ \7 M3 _! D# r4 A

3 o  y6 q% [" c6 ~9 ~/ [                while( GetQueue( writetime, q ) ) {
! K/ @$ F; W" o$ Q( R                        WriteProcess( q.addr, q.data );! w/ Y0 L9 l' o' y3 L3 v/ T2 P7 e5 ^
                }2 S! @6 b# P9 [% P
$ n9 J  |; o" {
                while( GetExQueue( writetime, q ) ) {: f( w- u. m5 J1 C) Y( D+ y' i
                        WriteExProcess( q.addr, q.data );
' u7 f* `( T% I/ I+ F                }
0 X* u- b* n! C- i# z7 Z6 J, n
% S% w+ w: ?  N5 c5 j                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7; U1 C6 J/ L+ k$ q7 y$ o
                output = 0;
! F% {# W8 P& V9 T                output += internal.Process( 0 )*vol[0];% e: V2 {' T9 L# x" W( I% q0 X
                output += internal.Process( 1 )*vol[1];. r3 a% y$ z0 b
                output += internal.Process( 2 )*vol[2];
2 o" }% d6 z( T  `# G  Q/ _; l                output += internal.Process( 3 )*vol[3];7 L( E2 O5 i/ k7 S: j" ^' X: j  u
                output += internal.Process( 4 )*vol[4];0 Y3 a1 l/ c# A+ T( L
+ o7 W0 L% N, V! J6 V" H6 \
                if( exsound_select & 0x01 ) {) U) Z, h1 ~, ~- E/ N$ U) g0 J2 Y6 X
                        output += vrc6.Process( 0 )*vol[5];
! P9 \3 y( x9 C" O9 [                        output += vrc6.Process( 1 )*vol[6];7 p8 |1 g6 ]. |8 n# k
                        output += vrc6.Process( 2 )*vol[7];' y1 q1 [6 b* D& Z+ M8 c1 `
                }; H  G$ N4 p1 p
                if( exsound_select & 0x02 ) {  h3 {% y3 A: R) _4 ]
                        output += vrc7.Process( 0 )*vol[8];  X! z$ K, [6 G) ~, k
                }0 {6 q, t: D+ y2 N% A1 w0 [( V
                if( exsound_select & 0x04 ) {/ c' E1 b2 R7 d/ H+ h. t
                        output += fds.Process( 0 )*vol[9];
$ E3 E" C- X- p  [8 ^                }- t7 `! x' S% [5 e4 j
                if( exsound_select & 0x08 ) {5 g7 t4 B% I4 o4 z6 l
                        output += mmc5.Process( 0 )*vol[10];
$ B1 k- g9 |2 V* x. F) n                        output += mmc5.Process( 1 )*vol[11];7 q' I5 \; |5 K9 J- \
                        output += mmc5.Process( 2 )*vol[12];
' H' }8 N# P8 I# M% ]                }
% P" R8 I" `, K' X% k8 U& s                if( exsound_select & 0x10 ) {" S2 b! J9 E* t5 R
                        output += n106.Process( 0 )*vol[13];
# Q1 f: ^* f: _                        output += n106.Process( 1 )*vol[14];* D' u9 C1 M4 A! |9 u
                        output += n106.Process( 2 )*vol[15];
' w9 `7 }4 k: g                        output += n106.Process( 3 )*vol[16];' i# Z1 j0 _9 A
                        output += n106.Process( 4 )*vol[17];9 i* J# s, v7 u& {
                        output += n106.Process( 5 )*vol[18];# E5 ~0 W/ i- D4 c1 B
                        output += n106.Process( 6 )*vol[19];
7 l1 Y  B3 T5 I- M( i, _                        output += n106.Process( 7 )*vol[20];
% A- t- r9 G9 z  F* _) S                }
8 }+ `: C! K8 A! c7 Y% l5 L  d$ q                if( exsound_select & 0x20 ) {
; z! D/ L6 P& O$ z# ?                        fme7.Process( 3 );        // Envelope & Noise
, x  B; k( |" A# k( g4 C! ~5 B                        output += fme7.Process( 0 )*vol[21];$ n0 i) F# X: t5 V* A
                        output += fme7.Process( 1 )*vol[22];: j1 X9 E" a0 |' d
                        output += fme7.Process( 2 )*vol[23];
) C, G+ O. e( K( E                }
4 O/ i( Z( R' U* N. C7 w8 r; ~! N! a+ C
                output >>= 8;
6 g! U/ W# b' b3 [$ @# C7 {( X
7 |* H3 j- z- k, K! v7 m                if( nFilterType == 1 ) {
- {  x" E+ s2 `' b: p5 l                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)2 b, I0 u) v/ i: X1 X2 B& H6 Z
                        output = (lowpass_filter[0]+output)/2;# o& \4 D2 X: L$ z1 c3 u4 E6 U
                        lowpass_filter[0] = output;! B/ V+ t' o1 M' U. V5 r: A& P
                } else if( nFilterType == 2 ) {
. I/ G: K1 {% }) ]# P* x                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
. d5 }' A: l8 Q; g                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
5 x1 I( `0 ^6 B! J1 ]2 Z                        lowpass_filter[1] = lowpass_filter[0];) `# ?8 N3 l: b, H, q9 p: }
                        lowpass_filter[0] = output;
* _" ?4 @" @& B# F, m' s                } else if( nFilterType == 3 ) {# v8 S  h: k* \% B$ }. T
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2): O0 O' v9 B% H& J3 |
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;, V! t2 O$ U% |/ f8 z4 l7 D5 u
                        lowpass_filter[2] = lowpass_filter[1];
: q. y& \# R- @( S6 Z8 @7 X                        lowpass_filter[1] = lowpass_filter[0];+ n) O  m* u; H6 {$ t8 N
                        lowpass_filter[0] = output;
+ P( n9 P1 r4 S) |( \; h* Q5 ~1 G                } else if( nFilterType == 4 ) {
7 c; j& R: z% H1 V  v                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
; p8 ]/ Y, i. {9 p2 W. |: @                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;& G3 {+ A; a2 u; {) i1 p, T+ s
                        lowpass_filter[1] = lowpass_filter[0];3 l4 v- h0 x$ {. I6 ]
                        lowpass_filter[0] = output;
6 O3 d3 y" z2 c( F2 b. g) U                }
# U* n, g$ k  j2 _! b4 e# A- T2 ?' P4 o* n+ N
#if        03 r& l. r3 Z5 M  c
                // DC惉暘偺僇僢僩- L# r! c: ?7 H+ p' o% S0 e- i
                {: i2 E: z  R& h$ K' }/ x
                static double ave = 0.0, max=0.0, min=0.0;- E, ~' ~, o/ x7 y! X
                double delta;. I$ u8 B: K. V3 p  Q, k
                delta = (max-min)/32768.0;
6 _3 Z) O& r$ g                max -= delta;& P8 {. \# z4 d$ W$ |- {
                min += delta;  R$ ?  i2 a- v+ h
                if( output > max ) max = output;) i& v  I# I$ X
                if( output < min ) min = output;
4 n1 w+ [8 @6 J9 g& k                ave -= ave/1024.0;. g, o* Q. g2 ?% W# W6 ]: H& X: u
                ave += (max+min)/2048.0;0 W% b$ J3 b8 [5 A4 y8 w: m3 s
                output -= (INT)ave;
0 n% e) r) v4 T) _) \* y                }2 a8 U* o( O9 \. l- F
#endif
5 ]# w  n4 u  x1 P1 D' M#if        1. R  o3 O% [6 U& ~
                // DC惉暘偺僇僢僩(HPF TEST): J1 O) r  p% k# j8 p
                {
% [2 }' H1 k" ^! S0 I//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);6 H# `4 r& S7 O" C8 f$ M! ?* p
                static        double        cutofftemp = (2.0*3.141592653579*40.0);+ d: E0 [. q  c5 n2 b
                double        cutoff = cutofftemp/(double)Config.sound.nRate;3 ^# k- M! H9 T" G
                static        double        tmp = 0.0;1 B' }, P% l! Z, b9 R  g& k
                double        in, out;" U1 @" B7 e3 S, \0 o5 m& v* I
7 I* N) [" C6 m  Z
                in = (double)output;* o% K  O4 j- N- A
                out = (in - tmp);% }( E$ G& C' e
                tmp = tmp + cutoff * out;
% R- s$ E- e* t% t
- [% ^  ?( n, t  c* h                output = (INT)out;
* ^; A: B- s4 D( H/ m& w" c                }9 w7 n2 E4 z! F) w/ G. C0 c, C
#endif
# L' o) Z$ U) o8 _. B8 U#if        0. E: x+ y- Y, B0 n
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
: i. O$ g3 ]0 \. [: C+ c                {
: Z  W% n& I& ?% H) ^' ^                INT        diff = abs(output-last_data);" k5 E' _6 z3 r, s
                if( diff > 0x4000 ) {
8 Z" m+ E/ [' m) _9 o7 l! g* o: C                        output /= 4;
1 x# F# ^  f+ i4 J                } else : j; P, J8 e% P& j* w5 n9 A
                if( diff > 0x3000 ) {
; J' R. |) }# h( s5 U& Y                        output /= 3;, F8 N! ?4 f0 V3 \! c
                } else- q2 b& Q* D" }
                if( diff > 0x2000 ) {
1 g# r! g# a, }1 @9 u4 g4 }3 z                        output /= 2;3 ~/ E0 n% h) {9 u9 n- V
                }
& T0 T& v1 h1 V& `, Y+ g% V                last_data = output;
1 z( b- }, V/ g. Y5 A* O" P                }8 \# |" K8 f8 N) ~! R
#endif
+ c* i3 J" f. R' ^' [: W                // Limit; H. h0 X& P& l  G! z7 U
                if( output > 0x7FFF ) {
7 W, C  Q7 Z0 p" }# F0 s, \                        output = 0x7FFF;
8 ~/ z9 r3 o" A. d( {* x1 j2 b4 _                } else if( output < -0x8000 ) {: Y2 T" W1 d: v
                        output = -0x8000;
5 q# p! c( W" ]0 d* e; H# W                }1 z5 F; f( ^3 A4 ~, k* A: k

1 n5 T; B' \3 M9 ^) a' ~# ~+ B                if( nBits != 8 ) {- Z- ~3 D$ L0 I; l
                        *(SHORT*)lpBuffer = (SHORT)output;
9 s8 N+ U4 o+ C& t3 k& P2 G* a( a# G                        lpBuffer += sizeof(SHORT);* R. I2 Z8 H# T# b7 Q; H$ T9 n) {; S
                } else {
" x) x- i: {# Z$ o4 c. S  X                        *lpBuffer++ = (output>>8)^0x80;
. T) s5 f5 l( c5 D4 \: X                }
$ A4 ~. C' i$ o: v! a. ?
8 M2 M$ Q9 M) _. V9 L) k$ k, b                if( nCcount < 0x0100 ), o/ f$ o4 x7 r* l* \0 B
                        pSoundBuf[nCcount++] = (SHORT)output;
$ V$ F# g5 k, k. e4 [$ ~
% c: L* I6 D) K  r# e, s3 W' i! v//                elapsedtime += cycle_rate;
) {1 b- G/ K/ R0 k/ O7 \                elapsed_time += cycle_rate;; p. `& k; h. ^3 n4 w
        }; K2 Y1 b# ]( c, u" s- ^5 M
5 ?! k# O& J( c  R; F. b# i
#if        18 M+ ^/ I  V9 x7 j/ G4 q" W) t; f- f, K
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
7 d. b. M% d+ e/ N) `                elapsed_time = nes->cpu->GetTotalCycles();, C1 v& y: Y; P
        }
, K8 M. p4 u; d. ~* @$ A        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
8 V2 X6 o4 i. R                elapsed_time = nes->cpu->GetTotalCycles();
* @7 @+ [" \0 @0 I        }
* \6 Z9 P7 w, N# _2 P5 B1 e9 X#else7 |( j6 Y. G" K
        elapsed_time = nes->cpu->GetTotalCycles();" {' `3 v5 _0 a1 {) k
#endif
* a2 J$ N4 x* j6 H4 g& Q}" V2 a. k* f0 h+ W( `3 k
, K) i' K. K$ I& q
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)/ H6 |: l* G& D' h
INT        APU::GetChannelFrequency( INT no )2 Q, K5 M: t& h6 a) O; K, `
{% r) h# c4 Z& O+ b/ U
        if( !m_bMute[0] )) C) o" o  Z  L) F
                return        0;
" K# u% V2 T7 o5 H" w
' k1 O$ _2 ]. e2 ]        // Internal
' V8 l5 h2 b" M* H8 |        if( no < 5 ) {- L8 j5 B9 Q) i, d$ P
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
. x, N9 Z, O; h& e/ R5 I        }
" w+ N. B4 h) B2 D        // VRC6
1 O" L& Z5 a, D" M6 I( _        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
7 }3 V: z) V0 @: G  |  _                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;! p! e; Q1 z# C5 j
        }, h% e3 u2 H5 @  S( D
        // FDS
6 F/ B/ I$ E( U: d4 D        if( (exsound_select & 0x04) && no == 0x300 ) {( @  c- e( V& g6 ]
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
8 X( |) `) a7 |8 K1 Z        }
, _6 h$ c& s) G, ^        // MMC5  i: H$ A1 R" C( a
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {% ~2 e8 u# r% ]* a+ ?7 r5 d6 }
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;7 y$ G( V7 u& ~
        }0 ?( r$ m9 r1 y$ b9 F
        // N106
$ a8 U# P  X% X3 g. D8 ]        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
4 ~0 I( l0 H* h8 d4 k+ q                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;+ d; b; M$ p2 c7 E6 r
        }2 `9 w) V( I8 L- Z5 n6 f
        // FME76 K! j* _2 X2 N3 g) g/ Q2 i6 O
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
4 n, O: Q0 z! @8 M' _# r                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
5 v9 X9 `) ^4 L! w- _6 h        }( i# J% F( X- r; S
        // VRC7
  [& Q5 q" G# {# j1 F- R        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {! [: E* i& J# d8 O% h3 v) q: ~
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
0 N: `1 [: y; ]& p3 C# M  O# m5 U9 O) A        }9 T, r; V7 T4 Q$ j  w
        return        0;8 d" x8 j* C( G) i( h. {/ H
}
4 h' H  d% c. J2 @
' B! Y, d  O( N7 v, I// State Save/Load5 u% J* O/ O( B8 P& s7 j3 W
void        APU::SaveState( LPBYTE p )
+ Z" I$ k; U! [% G{1 _- u9 `3 `4 T( M
#ifdef        _DEBUG+ a! N; |! T9 Q2 q. |: V, u& P
LPBYTE        pold = p;
8 u/ _4 }2 d! W. i#endif
3 h* {9 l$ @$ ~2 Y  b3 p# H; S* ]
( a2 w3 X9 d5 S/ X% p        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞5 [/ e* _9 K. t! x" a
        QueueFlush();7 H* M4 e5 ?  B) R* Z+ {9 O, I

3 N7 b' {$ p  o& t0 p  ^        internal.SaveState( p );
7 P9 {8 {, B8 \        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding) _. g; W5 N" O
8 Z9 K' Q7 J/ S1 D6 I: d% D
        // VRC6% Y0 F- C! D1 M/ L( R% M
        if( exsound_select & 0x01 ) {
5 D; c, U1 O5 L                vrc6.SaveState( p );
  T; t  P8 E. x7 J0 w& i8 m" l                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
+ u8 Z+ d; L/ O        }
7 g# e" b) }4 ?1 p. o        // VRC7 (not support)
7 {5 ?1 `! M1 o        if( exsound_select & 0x02 ) {2 W+ G$ K- Y2 i/ x, Z! q2 a
                vrc7.SaveState( p );. i& W$ z+ u- l6 k5 v
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding% j8 d4 D, F$ r# h4 C, s+ V+ `+ V
        }* ]" v. X- V7 `8 N
        // FDS) S  `% @1 r+ @  \7 z. r3 x) I
        if( exsound_select & 0x04 ) {
/ S( n* j$ ~: f                fds.SaveState( p );
: I4 P: H  U4 C                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding3 ^8 D- i/ j% ]$ j- \' L; P5 s
        }
7 M8 ~( U9 @: t2 c: k$ l9 B" j        // MMC5/ G/ |. d* @  Q9 u/ R
        if( exsound_select & 0x08 ) {
0 m; u" j) W/ Z/ P& s+ ], y1 z                mmc5.SaveState( p );
8 C: t1 q6 S  F+ C# G/ o                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
; M, D7 s( k1 A9 @0 H        }1 `5 e: e$ m1 P& f7 T* g
        // N106
# c4 D. @; t- `; z# r        if( exsound_select & 0x10 ) {, h# y* E# i- _* r1 w* H2 L
                n106.SaveState( p );
/ O" \, r9 T6 d* [                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
: b% [' M4 o6 V8 k        }
2 k1 K6 F# G6 `7 i8 @) ^        // FME7
- [* M7 x* q1 E7 N( _        if( exsound_select & 0x20 ) {) O* w5 t* F' }1 Z
                fme7.SaveState( p );  Z7 M( u2 v* e
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding) D1 O3 H6 \6 ~8 [; J9 r9 z2 V
        }+ r/ D8 G6 X7 ?1 J( c% f
0 d, b3 t5 g' g- i" r
#ifdef        _DEBUG# s# u3 L4 D: i& d% t8 ]
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
# S# p7 U; R+ U% P# m#endif: y$ S- R; j" e) J5 P$ d  s
}
0 H0 i; Q+ `$ G% ?/ C
  G) |+ x+ P0 U2 bvoid        APU::LoadState( LPBYTE p )! m7 t4 K/ {. M, _
{6 j# |$ X- h& x% U. W
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
8 T5 z' ?. A* ^. O        QueueClear();$ v& V% a. D% j; a9 A4 f( v% e4 I
, X. |. C4 o: d) w0 I8 ]2 T
        internal.LoadState( p );
. `: E7 @3 P7 n  P" @8 [        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
- s% L$ {$ \) B( N, d6 u/ V4 F' J7 p* X5 w8 ?  z* n6 O
        // VRC6
4 c# e. C/ J1 |3 H        if( exsound_select & 0x01 ) {: O, Q6 m) c% l5 d5 c) P6 Y$ k+ p
                vrc6.LoadState( p );
3 v, s: B8 ?. x. o( v6 `/ c                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
, t% W9 M9 ^' [; }+ y' W$ Y        }+ r- }2 j8 ?1 b- V: d
        // VRC7 (not support)8 M, L8 M6 l. c: T3 x3 y
        if( exsound_select & 0x02 ) {/ E% k7 ~" p1 @. N
                vrc7.LoadState( p );
, c5 _( n4 q  L6 @9 z+ I                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
' v. Z! M7 [+ G9 x# O" {% I! c: b        }) x+ y6 T; {: ^" G/ V3 _( l
        // FDS
) {# ~8 E- U$ X) p        if( exsound_select & 0x04 ) {7 R9 Y( y! H8 W2 y. f' o
                fds.LoadState( p );/ b0 v% d8 ]7 B& s- q- G9 Y
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding: V" }& v; W" u; G
        }$ t2 y" |- Z1 U" o- o, f
        // MMC5, G" Y0 R. `2 }3 P/ w% w8 q4 `
        if( exsound_select & 0x08 ) {
0 {2 ^9 m, }8 _: S) t0 C9 g6 i                mmc5.LoadState( p );+ x. o& ?% G' R0 `2 V4 X
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding5 c) I4 n3 y! K5 @* o0 @
        }7 ?! I" R+ u* k% {: E9 u& A0 c, c
        // N106/ }& Q/ J9 H% N
        if( exsound_select & 0x10 ) {; L+ P0 L. \9 @$ S7 g. ?
                n106.LoadState( p );
' D$ Q' k: K% a2 C  P                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding% s; J$ P0 A5 a  b1 ?2 W
        }! A; f5 }! l+ l: d
        // FME7
' @9 f+ o  C3 }) b- M3 t4 ~; H        if( exsound_select & 0x20 ) {
, \9 G) N8 j) K                fme7.LoadState( p );
/ u3 K8 n+ a# J& a                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding" R) [8 e4 A  Z( W6 z3 z0 w/ `
        }
3 N/ m& y5 v& K( b( L( Y}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 4 {" |! r' d8 a$ R8 O3 _: n
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。3 f) x: X2 S+ h0 }( |: L
感激不尽~~
' o9 H" a0 N0 M* ?; I* B$ e
恩 我對模擬器不是很有研究,: l+ T! i+ y3 ]+ k! ~0 H  w2 r0 v
雖然要了解源碼內容,可能不是很困難,
& n, V# P( {* b2 B$ ^- s  w不過還是要花時間,個人目前蠻忙碌的。
) O' e3 X! T) h9 Z1 d2 p2 Z' M6 B2 C; Y& V% E
給你一個朋友的MSN,你可以跟他討論看看," U% |+ V/ d' @$ i
他本身是程式設計師,也對FC模擬器很有興趣。, Z' v$ W# g6 y

' q" }5 }$ M, H' R! LMSN我就PM到你的信箱了。0 x3 ^: G3 D: V/ R  N4 w

$ a( C9 P( @+ a; e$ l# f. Q希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
. K, s, n6 `+ [" c呵…… 谢过团长大人~~

* c& D" g" H) t# T3 o
5 P" L2 ^8 a  G& N# k; U哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
( {" r" @, _7 O团长的朋友都是神,那团长就是神的boss。
' o4 w4 W/ A) s8 K# j
哈 不敢當,我只是個平凡人,
3 f9 R# W, N8 z2 E( A要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
8 c  ^6 C2 X3 U- M# M" KZYH: Q: H" Q6 ]  z
QQ:414734306
/ E- A2 r/ b- o: O; |# a4 p8 |Mail:zyh-01@126.com1 I4 I* w% ~) m2 c" c4 R5 ~

$ C( x/ i& h/ X他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 , P, Y) p% a' h# w0 n% ?! B. y
再次对团长大人和悠悠哥的无私帮助表示感谢~~
, o! a, z* q/ w6 J2 D. t+ z
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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