EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
  D- M4 ]5 z: Y* R- G楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~; r4 z4 C/ R# O0 r% R- u0 s
这里有相应的模拟器源码,就当送给大侠了~~
1 l) v3 \+ W8 Y% A% M( y1 Whttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 - U% `5 N2 Y. f: {8 n
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
: T% }# V1 e; R: W: J- i楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
3 S3 H6 d4 D% b+ I5 F, P这里有相应的模拟器源码,就当送给大侠 ...

& ^% E( u# k' }& V2 ]( F聲音部分(Audoi Process Unit = APU):
: h3 J) v( V* z; s6 z2 g.\NES\APU.cpp
/ X6 y3 `, i! q! A% q.\NES\APU.h; o1 n9 V; ?( y0 J) K' K+ @
7 h: u6 F/ ^+ ^6 [! i4 n/ x

! }8 x) y6 P* V  u1 `& J& k% I影像處理部份(Picture Processing Unit = PPU):3 P. S& _! x& e1 l7 }. X/ r  G: l
.\NES\PPU.cpp4 i; y( ~, s, W" o1 e
.\NES\PPU.h9 _9 G* M- L- A% c  ?9 R
( a* J/ r6 g! J% P* L
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:* S  B1 {/ V0 b0 S4 i$ I8 m- E
(由于很多专用术语和算法机理都不明白,所以看不大懂……)% c2 W6 L% G% m
//////////////////////////////////////////////////////////////////////////) `6 X, }; n3 S2 p- Y
//                                                                      //9 T, T* J. X" x" }5 n5 c
//      NES APU core                                                    //9 s, A: y1 C1 i3 X( y7 K
//                                                           Norix      //. p, U6 x4 X; F3 e
//                                               written     2002/06/27 //9 O5 J; d: y6 G& j% Y/ Z* J& g
//                                               last modify ----/--/-- //- i6 }% P# z5 V) O: s4 O) x' v
//////////////////////////////////////////////////////////////////////////" M) S2 A3 c9 m; L
#include "DebugOut.h"
! o. \8 m" C8 U% t* p) n! S0 ~* K+ d# F#include "App.h", l4 F# k  g( {: I( u, j
#include "Config.h"
3 u$ ?2 y5 Z' O" I) m2 l- `% F) Z3 c4 y/ q/ H% W4 m4 R! O
#include "nes.h"
6 q. c$ N/ @* D- M, T#include "mmu.h"9 R8 w! f+ u  z. ?# Y
#include "cpu.h"2 d# K7 Z+ d& f
#include "ppu.h"5 w) E$ v* \  z1 o
#include "rom.h", `& l. w' M* x( w4 P
#include "apu.h"% E, {* ]- T2 x; a5 t& {& c8 q2 I
, R+ d# e1 u' F; N- }4 F
// Volume adjust
! p* M. V/ ^2 g# @// Internal sounds
: F2 x9 c1 m$ k, P. h0 ]#define        RECTANGLE_VOL        (0x0F0)
% D9 c: o9 U+ m9 m- q) g#define        TRIANGLE_VOL        (0x130)
( y/ M) p9 t- \( t2 y8 g3 U2 W: S) p#define        NOISE_VOL        (0x0C0)
6 ~. F  h+ i* m#define        DPCM_VOL        (0x0F0)2 o- B1 U$ [6 x
// Extra sounds3 J$ ?1 m: E  G+ x
#define        VRC6_VOL        (0x0F0)4 S; {; R) `) Y
#define        VRC7_VOL        (0x130)
7 P+ O' q! `6 l8 e7 K; A' t( Z#define        FDS_VOL                (0x0F0)! ]( k8 ^# ?7 t; P" x6 J
#define        MMC5_VOL        (0x0F0)
& f* X/ w- d& F+ M- ]# M9 f' E#define        N106_VOL        (0x088)
8 d9 W3 o& \, D0 `. s#define        FME7_VOL        (0x130)9 P- Q, |: U9 f9 w# S- `
3 O8 J5 e# Y8 w; ], K8 L3 o
APU::APU( NES* parent )  i& C" h" {3 _
{
4 R+ T! O* V9 C3 @$ \. h3 i- W+ Y% T        exsound_select = 0;9 Q. r4 E  T) P/ M/ g

( b( r3 a) |* W8 ?        nes = parent;' O* D% k; l) O+ h! ^, v8 O
        internal.SetParent( parent );0 }3 i# q' S) d) R8 h, b/ N3 Z
2 @1 [* o4 W$ Q8 r
        last_data = last_diff = 0;
0 B% B2 f6 K; ^! l
% _8 V' P& G: b        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );8 H! H8 \" I# B$ Z& p6 H' t
) ?9 d" ^. z) C- J' B7 d
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );% l. n. h7 M# e7 {& w
        ZEROMEMORY( &queue, sizeof(queue) );" `, D) W& o, r$ ]6 r0 H
        ZEROMEMORY( &exqueue, sizeof(exqueue) );+ T2 o# Y; E8 O% ?9 W' S

4 `# i5 ^: t1 q& B$ v: M        for( INT i = 0; i < 16; i++ ) {# c) m7 D1 ^% E2 z, a
                m_bMute = TRUE;5 [) z) t& V) R" u7 o. ~: c5 M7 s0 a
        }
8 l7 V5 r% S& V' O}$ x# J6 ~3 N9 {: X; B
( E2 H% V5 V& p5 `5 a. G
APU::~APU()1 Z7 F! j% l6 v/ ], F; `- x
{
0 O1 a9 c& ]0 E8 R}
! J/ y$ W; D& @* B- W+ e7 z: \2 k4 {; _. P. r) m" N! x% ^* G$ M
void        APU::SetQueue( INT writetime, WORD addr, BYTE data ); S4 e) M2 L) c7 j
{9 |) c3 x: @2 C0 Q: d. T& w+ o$ q  ^
        queue.data[queue.wrptr].time = writetime;3 N0 P  h4 _0 t& x
        queue.data[queue.wrptr].addr = addr;
9 Z: x4 S+ u& Q; N6 ]2 c        queue.data[queue.wrptr].data = data;
9 v: A/ H0 S- X, D6 B# q+ D; u  N        queue.wrptr++;* g) F& C: @7 e6 }$ H
        queue.wrptr&=QUEUE_LENGTH-1;
3 H4 W+ p7 j. e6 V) E' B$ L! u        if( queue.wrptr == queue.rdptr ) {
: O1 Q& z, v' p) J0 F1 D1 F                DEBUGOUT( "queue overflow.\n" );% {( L. P% h; f8 j
        }1 e) H' A8 \1 J" \" I
}
$ C' {7 T0 n/ g4 Y( @6 e9 h$ [) ~7 }
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )9 r; N" L. \% m
{  V5 A: ]! {  g- u- I
        if( queue.wrptr == queue.rdptr ) {
+ {* t7 ~3 X5 ?2 L                return        FALSE;/ t/ l1 E, D( j) f
        }" q' f4 ?) T, o8 X: n0 y+ m
        if( queue.data[queue.rdptr].time <= writetime ) {
- V# U& j# ?# h                ret = queue.data[queue.rdptr];
+ B+ l+ F: m$ P* P+ h                queue.rdptr++;
) m4 S( l, R" |                queue.rdptr&=QUEUE_LENGTH-1;
8 F; [. ]9 V$ q" W5 K2 A0 I                return        TRUE;( ?* r. N" v  H+ I+ e7 v
        }4 r3 s  x! b# \6 Q/ M' M
        return        FALSE;
; f- e: s0 V- z  S% _2 W" b9 P}8 J! I! \: d' D4 y, N# L
8 T9 o" A3 `, ^; y, F% b* f' ^
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )! s  u# h# {2 a' R# b
{
1 E) J9 l) p  U5 G        exqueue.data[exqueue.wrptr].time = writetime;8 Q% w7 Q/ I$ H$ w" K
        exqueue.data[exqueue.wrptr].addr = addr;
1 X7 u) |) K% m) U9 i0 h6 Q+ E/ n        exqueue.data[exqueue.wrptr].data = data;
" B' _! c( E& S" g% @# N  y        exqueue.wrptr++;% f1 `4 g( A2 l' t  h
        exqueue.wrptr&=QUEUE_LENGTH-1;
0 k+ ~/ u" G& D9 P8 H5 M: J/ x7 u        if( exqueue.wrptr == exqueue.rdptr ) {
% N- F: A, c: E2 g- j* Z* M  T+ @                DEBUGOUT( "exqueue overflow.\n" );4 m. I" `& ~8 Q2 g
        }
7 q& P( M3 o6 [$ q}
/ S  R! ~% Q/ h, Q  D$ l
+ P% a% k& x1 [( v& n  \* C8 K# hBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
8 u' J" I0 |; a' K{1 L) q1 \* C! A/ @+ S: k
        if( exqueue.wrptr == exqueue.rdptr ) {
3 n4 t! n5 s0 Y0 f, L2 G; i6 j                return        FALSE;. m9 R' @/ [# R  {+ a4 H
        }
2 j( U3 N" b. `: n        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
3 m( ?! H! _! U8 W+ b5 [                ret = exqueue.data[exqueue.rdptr];
7 P2 S1 T: m' r' O4 Y% V                exqueue.rdptr++;8 r( ?& H6 r$ u1 v0 g- P8 j) b8 o
                exqueue.rdptr&=QUEUE_LENGTH-1;/ l1 ^% \6 ^/ m; z" r! W  |
                return        TRUE;( y7 z) A( M- s6 W( D3 P8 l; K
        }' T1 J8 V- k2 s' Q+ `3 }
        return        FALSE;
! y' h( S" S: P% o4 t: F) d}
- D( A, k8 n2 J5 g
$ ~& Q- B* t9 v7 d9 ~* Pvoid        APU::QueueClear()* j5 o) |' r4 ^7 C' j
{
1 T! Z; L3 k2 g        ZEROMEMORY( &queue, sizeof(queue) );/ c4 h: G4 E  o
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
1 ~/ v  u. H$ C& ?& `}
* _. k6 ~7 c+ L2 T8 E8 H  c' G
. O7 L) l) I8 a; l7 Yvoid        APU::QueueFlush()# [2 o! @) }2 q/ H# n& p" U" r
{
- |2 |+ k% @1 W' M* t  m        while( queue.wrptr != queue.rdptr ) {
% C' E1 S' v: k9 I! ]$ s5 ^                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );. W3 a& P# e9 o2 J$ A
                queue.rdptr++;
, T0 y* `3 t% S; }4 T! f                queue.rdptr&=QUEUE_LENGTH-1;
+ N3 T, b- o) w7 h! H        }) I8 y3 D/ z5 }, H; t( {3 B
& x+ X' C0 j0 W/ P
        while( exqueue.wrptr != exqueue.rdptr ) {
( J7 e- h6 |/ k& {  b; g( U                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );  F* K+ i6 B. D3 D
                exqueue.rdptr++;
) ]9 N& h+ f7 G& J; B8 M                exqueue.rdptr&=QUEUE_LENGTH-1;
" H( }( v  Y1 Y% }& C, b+ r        }8 S0 E9 Z, W0 P$ r& k4 B' q
}
5 N5 a9 p3 q$ `) f: ]4 G; ?" E( I/ |
void        APU::SoundSetup()0 ^: Q# k" z" N& G% Y7 O
{4 F6 U6 ~9 z0 `5 N
        FLOAT        fClock = nes->nescfg->CpuClock;
* i5 j  N* Y+ p$ \: E' b4 N        INT        nRate = (INT)Config.sound.nRate;
6 S/ f4 ^8 Y% J: y" e        internal.Setup( fClock, nRate );
0 o8 N$ H5 g" ?$ w- T# Q, i6 y        vrc6.Setup( fClock, nRate );( R7 X' z6 m! d- p8 F& L" T7 s  U. h- g
        vrc7.Setup( fClock, nRate );) _& O% D" K7 @/ |, J9 V
        mmc5.Setup( fClock, nRate );! K0 J3 A, n' M3 I* P7 i1 H
        fds.Setup ( fClock, nRate );9 w9 F+ v+ I- N9 W$ I
        n106.Setup( fClock, nRate );
' t; [% O" K# ~/ g) f$ F2 O3 d        fme7.Setup( fClock, nRate );. C$ n) W. b1 l" y" h  w
}4 @" z9 y* x$ N% |4 F, T
7 O! h0 a  C' V  X  g4 Z# t9 }3 r
void        APU::Reset()
$ G: r& }5 V; @  V1 j1 k; m4 K7 O{5 V- N! n/ c5 N  t, b) H
        ZEROMEMORY( &queue, sizeof(queue) );
* ]3 ~, S% H# k% G        ZEROMEMORY( &exqueue, sizeof(exqueue) );
& f* p7 A8 {( R* y' F  N) @9 s0 n; B, V, I  m, `
        elapsed_time = 0;
* N& @. [1 V8 T/ f
1 Q9 a% \. M4 f" \- K7 t        FLOAT        fClock = nes->nescfg->CpuClock;% @" Q* ]- q* t  e# ]
        INT        nRate = (INT)Config.sound.nRate;1 [+ o& @1 \, e1 l4 u4 Z. o
        internal.Reset( fClock, nRate );3 H: s' Z" \1 T" d6 A3 i
        vrc6.Reset( fClock, nRate );
  J& k  K+ I3 U2 Z' R& A* {# |        vrc7.Reset( fClock, nRate );
' x; r$ ]+ F$ E7 e. r1 L- {        mmc5.Reset( fClock, nRate );
: f  F% @5 W3 I/ t% Y4 w        fds.Reset ( fClock, nRate );( g4 I* p) O7 F/ ]( Z# G" u9 b8 o
        n106.Reset( fClock, nRate );
" W% `, Q- ]( \4 q) l- m2 r& q$ V        fme7.Reset( fClock, nRate );
$ I+ g# q- h! c' G3 U  b, K0 i/ q
        SoundSetup();3 U- s" c  [$ n
}
2 K7 T* b9 Y+ t$ H/ |' _0 l) d
4 ~2 Q5 k; I2 Z. ]! Wvoid        APU::SelectExSound( BYTE data ), O# K1 q4 T3 Z% ]+ C+ Y& w1 h" E
{
5 b/ f0 @7 i" z+ `% D  c5 B6 u        exsound_select = data;, I/ x  m1 j8 J& X7 ^' d9 i
}+ ]& t# T* i- g0 u' Q; @& U/ B8 O
, g# g& y2 K) V* f  J
BYTE        APU::Read( WORD addr )6 g8 g- T9 Z% Z! ?0 X7 `5 u
{
0 y& o; U$ L) Q1 x+ \        return        internal.SyncRead( addr );/ D; z  z8 _# V6 B
}, c; e- Q" r% e& y. ~
+ f5 P5 q4 j! C( a  P, u# k: p; J! G
void        APU::Write( WORD addr, BYTE data )
" j7 e  O, Z1 O! V  f{) o" X/ W8 h$ v6 O& b0 u1 Q
        // $4018偼VirtuaNES屌桳億乕僩  a. q5 m2 J% k$ [
        if( addr >= 0x4000 && addr <= 0x401F ) {
0 d/ o9 v" m: Q/ f7 D; b: d8 |2 q                internal.SyncWrite( addr, data );
' y# K8 m/ F& h2 @& V- ?- t                SetQueue( nes->cpu->GetTotalCycles(), addr, data );7 |" S0 b+ B2 _
        }
" S" x3 h* ~! V+ e}
* C* d% p8 {8 _8 b) E  c6 l' S3 n7 [+ t6 @7 ^  [& t
BYTE        APU::ExRead( WORD addr )( F3 s# B/ z& m4 C
{7 K5 [( ~' L0 @, t
BYTE        data = 0;- \( e/ J$ Q% s' M' h

! L* h$ S7 f7 M& l5 `+ u8 v, N        if( exsound_select & 0x10 ) {
) P& @; S2 t# c: z6 D2 \                if( addr == 0x4800 ) {1 c& _' c) J! ^) T* z. T
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );+ Q$ B3 s1 v: C# P" }9 y
                }& H6 D( w% j$ b/ E/ b
        }3 ^3 p% M5 k& i
        if( exsound_select & 0x04 ) {
( _" Z2 l+ e; L0 ~  ~* b: d                if( addr >= 0x4040 && addr < 0x4100 ) {
0 ]. v9 _! D/ h; q                        data = fds.SyncRead( addr );
- T& B+ ?, @+ @( n* Q+ k0 r# e9 b                }1 L5 a; G$ @% e  I7 i
        }5 q$ x3 F) m6 h; H9 Q% u# ~
        if( exsound_select & 0x08 ) {
) q' f3 `9 \2 b, c                if( addr >= 0x5000 && addr <= 0x5015 ) {
/ V( @- S3 _% w$ i3 h9 U                        data = mmc5.SyncRead( addr );7 A, V7 r6 ?* Y
                }
( E! @/ U5 J0 n8 y( F1 [        }) \6 L: v! f! f' k6 p+ `& C

1 ^0 \" F5 d" _5 h1 o! Y        return        data;
6 L) i( ~! i5 N, i# ^1 p9 e3 R}. k) W2 J6 I  [$ v1 E; \$ M( T4 [
, I  \- w* u4 P: X. }7 C5 o9 I) e
void        APU::ExWrite( WORD addr, BYTE data )& P3 ?" b9 W) O
{
. [" n) W5 y( h        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );  f' \+ e& Y3 r

! x6 p: ?* N3 ^- H4 o& |        if( exsound_select & 0x04 ) {; b' A  t+ v' e9 d; _  Y$ z& n8 i
                if( addr >= 0x4040 && addr < 0x4100 ) {
5 s1 |/ D' N) i2 N  O5 U3 o                        fds.SyncWrite( addr, data );- g9 L* u  B- V, f' K
                }
! [% ?/ W/ A+ M; y4 v) Q  m8 H        }
! B0 j! R- |) ]) I
/ \. j6 T2 \4 e        if( exsound_select & 0x08 ) {
' \3 ?$ Z+ X: s1 Y% M; ?                if( addr >= 0x5000 && addr <= 0x5015 ) {1 Y( s" X) f9 p3 B) q; o
                        mmc5.SyncWrite( addr, data );0 \( C2 Z& V; S8 f: Z
                }
' k1 _! r( @7 J% D7 x# m! c        }
2 l7 x; \0 ?5 c- y4 M& @}
7 J7 S' A2 \' u0 U- F* [
9 w3 |1 W& Q) j" q- v. J( h* {. w0 Mvoid        APU::Sync()
9 v* ^' D9 o0 w; m* o' D; ?7 H$ Q{4 A* f+ B& S+ B7 w* v
}
2 G+ }) s2 k3 s: ~0 Y+ W( K+ J+ a7 S1 {1 F  X
void        APU::SyncDPCM( INT cycles )& i; f1 D/ Z! `+ H
{8 G& H5 V! y2 t) M8 E& b4 u) x
        internal.Sync( cycles );
& E+ r* E" r* P) L* F6 h4 j
5 ^$ H6 m; n/ m, A5 H4 [! h6 ?        if( exsound_select & 0x04 ) {
: `; n5 x$ M" M, a                fds.Sync( cycles );
; q1 P8 u4 ?5 N" p: {( F7 \. d0 O        }" D/ [# r7 |; C* f6 S
        if( exsound_select & 0x08 ) {1 X6 w3 H; B5 I9 `* [
                mmc5.Sync( cycles );
6 O$ Y8 c$ y7 T6 D4 i7 [        }* F8 Z( c0 y  C- G% f, Y
}
/ Q3 z; q' g) h' Q" M% E% k  i
7 E/ t) z1 }% t% |( S1 v6 qvoid        APU::WriteProcess( WORD addr, BYTE data )
9 o2 }3 A$ E; s2 }{; s  x+ G6 X# p- S6 ^
        // $4018偼VirtuaNES屌桳億乕僩
7 n. J9 W  E7 C* m6 X( \' K, q; A        if( addr >= 0x4000 && addr <= 0x401F ) {
% K* H0 [% S' \. t% @                internal.Write( addr, data );8 }) \# k& R. _& i1 n
        }. }8 o& H, ]9 G# l" L. i" k) J0 y
}
, B" y, W$ G3 k& Y4 l" i, e, c3 ~% j/ @
void        APU::WriteExProcess( WORD addr, BYTE data )
' z5 c  k  n% A5 P1 R  g{
3 ?" ^2 ]* {2 _        if( exsound_select & 0x01 ) {
& V1 z& b8 y6 h4 S7 p                vrc6.Write( addr, data );2 e1 s+ V+ y& b" Q  D
        }/ F, G( P. A, q# d
        if( exsound_select & 0x02 ) {
& s$ M/ `+ [' P1 w                vrc7.Write( addr, data );1 J5 ]$ w9 h* V/ A7 t
        }# E! R) W6 y( o7 t9 X5 {1 J2 d
        if( exsound_select & 0x04 ) {2 i3 Z% M: b7 c! K+ _( j
                fds.Write( addr, data );1 h. W5 z; t& C6 @+ f
        }
  p" Z# C( K7 Y8 s% x! u        if( exsound_select & 0x08 ) {
4 d& n: z  C) [! Y, ~                mmc5.Write( addr, data );) P4 I  k# O( n% r+ ^% A$ @
        }
( L" j3 L1 B  i        if( exsound_select & 0x10 ) {
+ F% P" N8 C  h; [6 z                if( addr == 0x0000 ) {- H; Z7 f& h6 S* e, X9 q
                        BYTE        dummy = n106.Read( addr );
& {3 u6 Q- r  N; S% ^3 E" e0 P- n                } else {4 m& [* n  o4 A: G% E2 O
                        n106.Write( addr, data );' ?9 ^; M2 A. Q6 X0 E4 T
                }
; t0 k; j' R' b        }
, w4 B7 U4 [2 ~( f; B* @8 F        if( exsound_select & 0x20 ) {
8 u6 a# i* C1 q' b                fme7.Write( addr, data );9 w& v! c7 v4 `7 Z( T
        }
* m  X& q  b4 R, @! x$ K}5 n1 b' d  |( q4 a0 R9 y! w4 `0 ?3 P, n$ f

9 x6 W7 m1 `5 f( }" L+ svoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
+ t) j! O7 y9 u: Q+ Y. Z. K/ x$ E{5 ~* S1 j  M: ]' E
INT        nBits = Config.sound.nBits;
8 X6 V0 R% x3 W% e9 b. uDWORD        dwLength = dwSize / (nBits/8);: `, K" Z" b: |( P4 T# L+ [5 o% z
INT        output;; f3 L' B- ]/ J, q$ c
QUEUEDATA q;
2 ]; ?! I& Y& [# O# uDWORD        writetime;
. V# ^! P1 k$ h
: c) ^; c- B, NLPSHORT        pSoundBuf = m_SoundBuffer;" |* p( O/ R  w, h) E- F, e- p2 n
INT        nCcount = 0;$ I; S1 R- l5 [! ^! E6 B
4 H: \: m& q8 `3 S% D$ Z
INT        nFilterType = Config.sound.nFilterType;
% m' O$ g/ V: f" l2 s
% m2 S# A" c9 n3 V. m6 o# j$ x% r- f        if( !Config.sound.bEnable ) {) ~- G* Q0 ]9 _% P5 @6 p
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );3 k  F2 h% [# q
                return;! S( @. |6 V. k. [3 S- I1 G. D
        }3 i- n: x  q3 r( ^# _- B  d0 s

8 z- t/ o) x' N+ }  w3 p; J( R, V        // Volume setup' W* N, m0 r$ c: f4 _5 Q) w7 ?$ {
        //  0:Master
6 \( y- x. F+ a        //  1:Rectangle 1! _7 b: ]+ p6 J& u4 ^( k) M
        //  2:Rectangle 22 i4 V+ G1 L3 k( I
        //  3:Triangle
0 T# u; g& Y# m3 ?7 u: R* O# B        //  4:Noise! K. ?% Y0 R1 j+ i6 b# W3 k: a
        //  5:DPCM0 I2 p" C# W4 ^. u- t" i
        //  6:VRC6& \, [/ ^$ v  e4 ^; l4 ^2 o" [
        //  7:VRC7
5 Q' H  }. T$ y6 I" C+ R        //  8:FDS
! ?3 V5 ]6 P& Y' [+ D$ W        //  9:MMC59 v+ E8 p! s( U/ F  u$ @
        // 10:N1062 ?: }9 Z6 a4 s0 C
        // 11:FME7
0 ]* i  N' B. t: s- u3 w6 n9 _        INT        vol[24];: E3 M) l% L4 x, G! f
        BOOL*        bMute = m_bMute;
! g; o) x) h0 r( `3 E, N8 g% Y        SHORT*        nVolume = Config.sound.nVolume;
: d  o! D3 _$ L% t
3 Y. s, r3 G: A% |* }        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
# c2 X% ~( a/ @8 x8 P9 r5 }* ^& H1 d7 V5 E; X
        // Internal
! Z3 \- y8 g; ]" c4 p5 y5 @        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
+ u8 S  o5 h& ^- e0 U; v        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;; {7 T1 T+ j  m2 S% a( F8 S
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;7 I! G7 O" v+ r
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;, b7 i% e0 h' R9 Q, b2 H
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
, h# }, Q" P* H# W
8 B; C+ K$ Z8 [* q0 i9 g        // VRC62 u9 l- k' {6 t( [# F6 j
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
( S8 N2 s8 k" E; w4 J' c4 i- D        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
3 C0 K, {' T9 G- b9 W6 U9 C- v        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;- [; `/ h( G4 ^- A5 `( P+ @3 [3 M

% E% K1 ~* D4 C+ A& v7 w  g% o        // VRC7& ^& k5 N8 o# |; E1 S1 o
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;" \5 E0 B, M( _4 z
& t- Y$ i6 O3 Z1 v7 c( i
        // FDS- ~0 v8 x' U! H& A7 V
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
" n5 f$ K) I! U  e0 b0 h, w
. J+ Q7 c. @" \        // MMC5
4 r1 `9 w1 J) q" t$ u/ e& E1 V. g        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;- ^  ~; e; D/ l: m
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;7 H6 R1 A: ^2 _9 A; W( t$ Q
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
; T  y5 H' U' f5 j* O* L3 i6 A( a9 [& h
        // N1068 r0 x- j: t- t8 n: _) ?4 F
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
6 e, z( R, I; ?        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;2 c- u' R2 O* E: k
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;5 D: }/ O( @8 F6 {9 T- t, C3 U
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 j5 y% [* Y3 i2 P( g- u, S
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 u1 j- N. Q# r3 }  Y2 z
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
  f/ V8 J& v0 V! p4 ?* {        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
$ D6 V+ s3 _& M$ ?9 v        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;" \# }8 d5 I# F& L% j
6 n! C6 [0 Z& U! ]
        // FME7$ B" ?  K$ j4 {* N% [
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
' C6 o. q6 V! u! p  ~        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;+ U  d# o- S4 A9 M! X2 H+ e
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;2 b3 j' x' B; T) k8 j2 K
, |6 Y/ b* @  I; V
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;8 i' P, o2 b' r6 H9 S( @
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;8 N/ E" h+ X' U3 s+ C  i0 ^
4 H- N/ M6 {5 U& E5 t6 C
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
3 F- Y( C6 a+ X7 r3 B8 [: @' w        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
/ c7 B% C5 P+ K7 M! J" q' I) R. m                QueueFlush();
3 ?% l; h& x5 F( i        }
/ o4 ]; k, i! {( D$ M- V! K9 Y: t' ^& F. \0 q9 \! e
        while( dwLength-- ) {
+ V; F& Q* G: E; k                writetime = (DWORD)elapsed_time;1 v, @6 ^; N- r  f  G* D2 {" W
) W7 e5 l% u' D* A
                while( GetQueue( writetime, q ) ) {
7 K0 P0 _; b" L. r                        WriteProcess( q.addr, q.data );
. P" j6 O% ^& G7 B# T# [4 `. Q) V/ w! \                }2 o1 \9 D/ J# O
, J7 I- M0 o( p
                while( GetExQueue( writetime, q ) ) {
' ?0 b5 H6 P2 Q* ~& V                        WriteExProcess( q.addr, q.data );  T! Q( q7 k4 t, h- ^# D1 I
                }
  g9 J2 g) h1 e# S& u- x
0 G! y7 r; p+ p. B! j# i1 b                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7& h5 E* ~, [+ ^' B
                output = 0;
' @( q* S- I" T+ M9 R) o5 Z                output += internal.Process( 0 )*vol[0];
; T. h3 R2 G( g/ u                output += internal.Process( 1 )*vol[1];9 v( L) J0 e  v# K$ j
                output += internal.Process( 2 )*vol[2];2 J# Z5 b& n+ r! S
                output += internal.Process( 3 )*vol[3];) y" |. t+ k6 b+ m
                output += internal.Process( 4 )*vol[4];% i6 S( z5 Z8 ]+ _) D% h# ]2 r
  Z6 T! U# P1 G5 r
                if( exsound_select & 0x01 ) {9 _  ], }  \- p+ _7 H7 X$ w3 A% ?
                        output += vrc6.Process( 0 )*vol[5];% e) b/ C; u5 k: s
                        output += vrc6.Process( 1 )*vol[6];% D/ x6 `& b" t6 A$ Q* b# X0 U9 G
                        output += vrc6.Process( 2 )*vol[7];
* a! a6 n& g/ w) t- r                }
# a( \4 o! `/ l) {1 ?+ W+ N! ^" o                if( exsound_select & 0x02 ) {
8 b, a1 x3 b4 ~1 B; x7 k7 x                        output += vrc7.Process( 0 )*vol[8];' ?% B1 ?0 ^5 K1 ?
                }
2 k0 D0 g, r8 K& a) v9 T                if( exsound_select & 0x04 ) {
. @7 x& ]7 f( o+ L) F' k1 d/ P5 r                        output += fds.Process( 0 )*vol[9];- {3 a2 k  K; P0 o
                }
( O, h+ q; w8 C                if( exsound_select & 0x08 ) {0 p3 ~5 x7 }& b7 k2 E; D, K+ e
                        output += mmc5.Process( 0 )*vol[10];2 e- Q4 u4 @% f6 F
                        output += mmc5.Process( 1 )*vol[11];
: ?+ S7 `" h) k( H1 r- k3 j+ H                        output += mmc5.Process( 2 )*vol[12];
1 s. k2 u( H' r- @5 T                }* }6 N) i+ Y+ L5 j* R' O4 V" w
                if( exsound_select & 0x10 ) {/ {/ Q1 G  C. j; O" f3 B
                        output += n106.Process( 0 )*vol[13];
9 G( W: Y, P" l0 D+ t4 E7 s                        output += n106.Process( 1 )*vol[14];* \0 A% L: F+ _- x/ c
                        output += n106.Process( 2 )*vol[15];; W  P) Y% r0 x
                        output += n106.Process( 3 )*vol[16];
+ w$ ^' u# y) j2 z2 M/ b                        output += n106.Process( 4 )*vol[17];
( v' ?1 {+ c/ |& j                        output += n106.Process( 5 )*vol[18];
! ?8 R  q; H. @: _& p- H                        output += n106.Process( 6 )*vol[19];
7 D% K- d/ V7 e, y, y+ r% {; ~                        output += n106.Process( 7 )*vol[20];, B% D) [# x) W; Y1 R) v) t
                }% S9 W4 \, p5 f" K- M' [5 B2 A
                if( exsound_select & 0x20 ) {- C% x* |$ d% }+ _! T
                        fme7.Process( 3 );        // Envelope & Noise
  ]# ^! V, p3 f                        output += fme7.Process( 0 )*vol[21];
3 W9 m$ J0 q3 ?1 f2 y2 A" A& e                        output += fme7.Process( 1 )*vol[22];7 W+ U& I8 s) x4 }/ `/ V
                        output += fme7.Process( 2 )*vol[23];0 H) u: Q: {% D  N2 l
                }6 D' f+ c8 |/ O/ h) X7 V

0 j: j: i* x! F/ P6 A                output >>= 8;3 D( U6 I( ]  q9 v- ^  t
8 q- D" Z6 L. b' g' A
                if( nFilterType == 1 ) {
1 N+ |& H' F: \# Z" p- b( Z                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
- d8 q3 K/ ^3 M& U( b5 o) r                        output = (lowpass_filter[0]+output)/2;" [5 K1 v8 t6 w3 @
                        lowpass_filter[0] = output;
( d: N9 K* m! j                } else if( nFilterType == 2 ) {! s8 j  ]( D2 q4 I) i
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
! u' L. e9 I7 r6 f- Y! {  b  j$ T                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;) L' ?9 z) a5 k7 C) e
                        lowpass_filter[1] = lowpass_filter[0];' M8 C; b- a9 C* w
                        lowpass_filter[0] = output;& l* w/ j/ J  l* F6 A
                } else if( nFilterType == 3 ) {3 `( I6 P: p; ]8 G1 n- b
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
- O" w6 p9 n4 x/ l                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;( Y8 b# R, K% e( R& R: N% E
                        lowpass_filter[2] = lowpass_filter[1];. K, V; q3 f% F5 M
                        lowpass_filter[1] = lowpass_filter[0];& P6 I8 g& C/ A+ L6 C
                        lowpass_filter[0] = output;' x" [3 F! n2 c/ m2 Q% n. J
                } else if( nFilterType == 4 ) {+ m9 \. c" P4 o& |
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)( O7 _3 q# t! x% P: Z" a' E6 u
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
# }7 w# g) L+ Z7 m9 V% M& M4 @0 I                        lowpass_filter[1] = lowpass_filter[0];, Z2 a8 _# }% w& |( \2 r
                        lowpass_filter[0] = output;
3 O8 u% M2 ^8 c8 q. H, E* @2 S9 _                }) B' r1 {# N) S0 u( W3 ^

8 \/ \: ?' G) W% c# }1 O4 i8 h#if        0
2 E3 d1 b' K* K( R8 C8 Y! U# Z                // DC惉暘偺僇僢僩
9 V! |- v, G& p* \1 x( K: t3 a: _                {
* i" K8 j% b: X2 R7 B                static double ave = 0.0, max=0.0, min=0.0;
  k0 F- N& m4 @' e                double delta;8 m; W2 m# \6 F5 F4 ~) D
                delta = (max-min)/32768.0;1 j3 h; n9 e4 D2 r) I
                max -= delta;
! k; [7 k" w1 \- Z& G. B* N                min += delta;
( ~, c' E7 [5 ~! Q3 N! D                if( output > max ) max = output;
0 C% \& f& F- i( F                if( output < min ) min = output;( E) M( C8 J6 P! r0 u; @) [
                ave -= ave/1024.0;
6 ?* n3 s& i) C- ]5 p$ v                ave += (max+min)/2048.0;& p2 R! _# ?) F9 k  @
                output -= (INT)ave;5 e$ j: K' J  V
                }
. A4 `/ Y2 n2 }5 }6 N% L. I! U#endif! Z0 e( M6 i6 u, {/ t
#if        16 s0 `9 D! ], b+ k7 A$ W1 k
                // DC惉暘偺僇僢僩(HPF TEST)
4 ]2 K/ n4 Q/ Z6 M                {) D( x, y: v1 U- @
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);6 g( @6 ?0 r5 e" Y( x
                static        double        cutofftemp = (2.0*3.141592653579*40.0);+ Y' K7 ?8 {* b3 r
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
. c0 C- z4 R6 G( Q                static        double        tmp = 0.0;
1 ~" C; S4 f3 ?) v0 q8 L' R6 Z                double        in, out;( }4 C7 u5 f8 h
- m/ M. A4 K5 Z& c, \
                in = (double)output;4 M5 k/ s1 y' m& l  Q) f; M1 s
                out = (in - tmp);
2 C# W0 g! U' t8 f                tmp = tmp + cutoff * out;
8 h( E- [& z4 d/ m4 S) K% J2 z( v+ _4 O8 ?; c1 P  y: `  F0 R( J
                output = (INT)out;
' q# P; O! T2 r) Y                }
7 O/ G9 [7 c8 e& x" W0 F#endif* |4 v, d% n, z
#if        0/ V+ o. k& b5 Y5 k6 k- z- }
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)+ t+ ?- o  f" n: J
                {
: a4 R. |$ y# y  j/ O7 n                INT        diff = abs(output-last_data);
( j; v9 q8 J- q7 b# }                if( diff > 0x4000 ) {- ?2 J& x  b% f+ V
                        output /= 4;" t# t+ a% I- y- w
                } else
( K. F" Z# _/ R$ j% V                if( diff > 0x3000 ) {: C$ b$ U1 d$ [6 ?6 c+ W+ l  v
                        output /= 3;
3 H& P4 k9 Z; U" ^, C+ N" [/ ?9 \                } else; E+ V; x$ P! q6 y+ i3 w! j
                if( diff > 0x2000 ) {* |, M1 W2 o1 k. E
                        output /= 2;$ v, |3 i  ^/ f2 u# F/ i. \" A$ z- J
                }+ i4 [( b- B, }9 h9 L1 z
                last_data = output;
/ n0 ]/ x* S( X" p% \                }
8 B' ?  f. d! q5 S#endif9 R! }6 M  i2 |. V$ Q: d: E6 _' o
                // Limit  i, H3 a" h: H
                if( output > 0x7FFF ) {5 N8 {# R+ u) h& R; n9 }! A0 V
                        output = 0x7FFF;6 j  w, F. i. t# c( }- @5 [
                } else if( output < -0x8000 ) {
- G8 ^/ x9 R) `/ O- [$ Y                        output = -0x8000;
1 `$ ~4 w) `( Z8 ^9 A                }
, D& S) R& V4 i7 b$ t' e+ i' G$ r8 ~, s1 f) i; ?; f+ k0 p7 f
                if( nBits != 8 ) {+ _5 ]' B0 I7 f, f' u
                        *(SHORT*)lpBuffer = (SHORT)output;
4 R+ [, u/ M) S+ x, f  R                        lpBuffer += sizeof(SHORT);7 m6 J; C" z9 _% Q
                } else {
% h- J2 v# J% l                        *lpBuffer++ = (output>>8)^0x80;6 o4 V$ p- M, Z' S
                }$ I0 }  H2 m' r3 z0 U0 @1 W2 I
8 B; _* _5 z1 I
                if( nCcount < 0x0100 )
# S1 r8 L0 W; t. u) g) I                        pSoundBuf[nCcount++] = (SHORT)output;
7 {3 ~, i5 i) h4 E( I' O% S: I3 u! B7 ^% K' C" |- t" J" n/ P% I
//                elapsedtime += cycle_rate;5 T3 B6 f4 |9 J: e
                elapsed_time += cycle_rate;3 N5 C1 E$ z; X7 {
        }  F0 [, i3 G7 B* P& y9 x
3 p& r- Y& C7 Q4 ~; {3 S
#if        18 F+ X' p- e. P0 h
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
" L& i- E3 R/ q1 A% P9 B( H                elapsed_time = nes->cpu->GetTotalCycles();
" E8 a8 _. D; E/ A9 d9 {5 L        }
5 M# I& |6 r/ x& J8 b  y* ]4 H        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {' ^. K- R& {/ P' g2 b9 ^  U
                elapsed_time = nes->cpu->GetTotalCycles();4 U  w8 i$ o4 E2 d. U- i
        }
  E9 I0 T" j, e$ y#else
$ Y" Y* u' T# F6 `        elapsed_time = nes->cpu->GetTotalCycles();9 `% a; Q5 B6 D4 M8 D0 U
#endif& F* k5 q3 I& P% m
}
) U0 P; G. V$ V$ g9 Q# E
! A* L) c  X7 T2 |9 A. R// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
0 u4 ~% z  p) d( ?% d5 XINT        APU::GetChannelFrequency( INT no )
/ v$ p( R" i, W* q0 q, k8 A{
" J* b' K& b9 t( L# Y+ q        if( !m_bMute[0] )  {3 I: s! T! D! v: _& M: T
                return        0;" b. u. D6 g! c7 Y  s/ E

. @& G/ Z7 l1 `* U        // Internal; r! K2 p$ w: S
        if( no < 5 ) {
8 `4 [2 b1 g' d  e, {" X4 ?: N                return        m_bMute[no+1]?internal.GetFreq( no ):0;
9 y9 y: o7 d2 e        }5 y! u) G+ X; v9 ]" \
        // VRC6: b; A5 d# N& T8 I( p/ S* Z2 N
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
! E: J  Q: e) u9 N6 @/ P* s4 `                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
2 R& D* D5 o# N) u        }4 D! b% G! |3 e" H9 `
        // FDS
* ^6 ^! _/ A0 ?# U        if( (exsound_select & 0x04) && no == 0x300 ) {. h$ L- D- {( I2 [( V# ]
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
" k9 Y  u# a  J  W3 w        }
3 p$ Z9 d# M$ X  W& C7 L! n% f        // MMC5% s! `) y( l. c' L
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
8 U" K# H1 J% f9 Y$ A4 r                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;  y, g' C' L$ Z  ?- D1 r
        }6 O8 H; \' r* n% C: {; O
        // N106# C; B7 G6 c3 _
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
4 ^9 B4 c/ {# K( [+ L                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;0 r- V; d8 C& F5 ^5 H' t% C# u
        }
3 d$ u+ i$ y$ [5 C3 U/ n3 ]        // FME7
3 L' u) G9 e- h, R        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {+ [( c+ V7 `! Q- _9 J5 \. o; d
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;9 e0 _( z7 q( w8 D: W% U
        }- ]6 G" |& z3 O5 O
        // VRC7  N+ L2 }! a! y+ Y
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {& T: W# \% f, j. A+ u
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;" D5 }, R# I* L* \. h+ k9 H
        }; d, I3 S  G) A( f) e
        return        0;# X4 S$ }0 D) _3 S
}
* G7 D3 s1 E6 ^# E( d3 [5 g# ?6 f* C1 t' q$ Y/ x' f, ^* P. i9 b
// State Save/Load" h" P( z! b. a4 r- Q" D) x
void        APU::SaveState( LPBYTE p )
* d4 d7 o( d: {% V+ q2 {{
0 E6 W+ ~0 L& \& ?$ |- p- m#ifdef        _DEBUG- V, h: N" P) l
LPBYTE        pold = p;5 {) l6 p/ ?% P5 h+ g
#endif
" j+ ~. w# w& x& ?7 h" {1 q/ n. m$ P" @% @  Q; }
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞3 v  u$ Y9 L# [& E8 y3 }7 \7 Q! E
        QueueFlush();
- O* W0 W( h0 g. G$ P+ ^" t
. |* Y" a0 y5 B        internal.SaveState( p );
+ P1 l, h% E* \        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
4 u/ t  K- ]; [% o+ f0 @7 a6 A! G2 l: y) U
        // VRC6
7 a3 l) |; E% E% L        if( exsound_select & 0x01 ) {5 P! H5 g' R; y  `$ }2 y  X9 b
                vrc6.SaveState( p );
" O4 ?# x- A7 G( u# j                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding% x! j/ j; g6 y
        }! S8 A9 ]1 i' p) k9 h3 \
        // VRC7 (not support)6 Z7 E7 h% K+ ?  h/ N
        if( exsound_select & 0x02 ) {
, n! I  J9 E& r                vrc7.SaveState( p );' q. O3 \) n- r" b
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding( S: W) a; \- G3 h  q  k% ~
        }
! h& l5 M* Z: ]1 H% r9 ^        // FDS! _) p  z% k$ D" ^
        if( exsound_select & 0x04 ) {
) X: I8 B. B% j& d7 s9 J# r                fds.SaveState( p );3 V/ G- d, ]. S: t' [
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding7 N$ w! F1 v& s3 g* P$ n4 `
        }
  ]( `# ], H3 t# \/ h        // MMC5$ p. j  U5 H% Y
        if( exsound_select & 0x08 ) {0 \6 U" p4 k+ a7 P
                mmc5.SaveState( p );
* V$ h+ a4 x5 ]  e" U8 f+ u                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
7 i+ x3 n2 V) W        }  o+ O7 m: o! ?* v8 [: y$ E. l: p  i
        // N106, G7 P7 L# Q0 z! U; a" f: A
        if( exsound_select & 0x10 ) {/ k6 u1 _" z4 y& W( J
                n106.SaveState( p );6 h" c# s2 ^1 ?
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding; k3 ~0 E; i( B- {! C+ R9 a
        }
7 S2 R4 c3 W( k        // FME7
8 K7 B& h' a$ G1 U4 l. K6 B' S        if( exsound_select & 0x20 ) {( l3 @7 l, C4 P
                fme7.SaveState( p );6 p6 Y' ?; z/ l) \9 h0 q% |
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding" J9 }( }: w- j. }6 U; H
        }
$ w- n* u* g# s. g
9 \. i" r: _$ ]7 V7 R#ifdef        _DEBUG; z- o: H) r# V4 f7 h
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
3 ]% j4 I1 W7 q' c, B) e) z#endif
$ g& W' J0 C# Y/ G# b}
8 `+ u& P( H. e3 }' w
4 |! u7 f1 H6 N$ M" r$ svoid        APU::LoadState( LPBYTE p )3 w" g1 i0 X* Y3 |# j
{/ T2 A9 s3 [1 R. u1 Y
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
0 V9 x" g! E5 n7 c* _4 L( V. `$ C        QueueClear();
+ A& v6 u3 J8 F' ~+ ~( [' d% i/ R9 s7 e$ n
        internal.LoadState( p );4 Y* P0 f$ t6 _5 q
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding. ^; R9 ?( |7 L2 ^" P
" y6 r) @" k5 I: F9 f. [3 p1 n; y& B
        // VRC6
: M' Q% W2 }4 o3 P! X5 ~% u        if( exsound_select & 0x01 ) {1 m, x* {/ m, V/ I! c. q
                vrc6.LoadState( p );
$ c5 I7 b. T5 O, \- `                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
2 a! k$ O( p* Q$ `' j' F; N+ k9 @        }9 C$ p* G# a: k  s! G) y  \
        // VRC7 (not support)+ H8 X, a2 P+ b9 G; }8 ^4 C- B
        if( exsound_select & 0x02 ) {
" D3 L2 a1 N* B  ?/ ^' I                vrc7.LoadState( p );/ O2 F1 a0 [0 V
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
+ z2 ]1 W; Z& s7 O: c        }
4 Z. _- q, g: x' D, n        // FDS# m  x2 C: E+ X/ ^" h
        if( exsound_select & 0x04 ) {6 s' @8 G' i/ ~" ^: m8 ^8 Q' N
                fds.LoadState( p );- [3 p+ W/ q) u- ~  z
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
: ]$ |7 N. _& m$ u; B* D4 [8 o        }
; V; ]6 O8 |6 x8 X/ N* W  B        // MMC5
, _8 U5 ]* b0 d8 c        if( exsound_select & 0x08 ) {
: s6 v- ?3 p( s$ o5 W/ ^& S                mmc5.LoadState( p );. o- B# O) D& i! a; H
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
$ u- s. a  s' [+ ^2 E5 m        }
' `) a9 C( V* I& D, \! b9 w5 u        // N1068 V* A6 s- @  R3 l
        if( exsound_select & 0x10 ) {( B) c0 p% U5 F7 r9 K0 ?" I/ I
                n106.LoadState( p );/ o# E0 _- q$ }# M. I
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
/ w9 f8 u, ^; P* ^        }
- b6 ]& M$ H& l8 a# A        // FME79 A9 ~" @* j/ g6 f& k5 m' P1 n) |
        if( exsound_select & 0x20 ) {2 n# a# k( H7 G( j: n* j
                fme7.LoadState( p );. C0 Z7 Y2 d+ ~) D: ~
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
( H; \  E  [, x/ H) N! F( @        }; V3 ^: h7 r* l  y. H' W" m" _
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 + C' a' o2 \1 r8 \2 H! g1 _
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
2 N7 z7 N6 A; j0 G  a2 B3 l感激不尽~~

  V! D6 o  i7 u9 ]7 h" |4 C恩 我對模擬器不是很有研究,. P$ c/ i7 y5 z: O$ ]+ E
雖然要了解源碼內容,可能不是很困難,
9 u" P' z/ z7 ?2 |6 {; v  K不過還是要花時間,個人目前蠻忙碌的。
! o4 K$ b; T5 E2 d1 |
) R# H- M: Z5 Y, _. K給你一個朋友的MSN,你可以跟他討論看看,  f0 u6 b+ j9 Y- g' ]5 {
他本身是程式設計師,也對FC模擬器很有興趣。5 w* K: Q0 f! ]1 F. I1 @8 F
( a& q5 Z% ~6 z, y5 p) S
MSN我就PM到你的信箱了。3 `1 e1 z* l1 T; Z" d5 r+ Q* A8 n

1 O& p  ~- I, u- p/ m) }希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 ! }3 ^+ V( R3 e) @9 d
呵…… 谢过团长大人~~

8 x' `- a! u6 E' Y8 n- E1 F: s; c) ]5 ~7 x- \
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 2 L" @- J3 J/ ?4 ]
团长的朋友都是神,那团长就是神的boss。

( [5 q1 D0 Y% U' K* ~哈 不敢當,我只是個平凡人,4 @$ b) r) f; E
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙: p5 X; u# Y# h/ Q! E6 a
ZYH
; @4 }1 q3 A( j& ~7 mQQ:414734306  K/ T1 s# C8 u' |4 m; ?
Mail:zyh-01@126.com
) d) o3 {9 a7 D" f" z; f( S& B5 q& a; H* Y7 R
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
$ O" `4 i. ]( Y/ Y9 n! S% y再次对团长大人和悠悠哥的无私帮助表示感谢~~
& s* `  m( C8 k. @, o8 ]
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-28 21:23 , Processed in 1.109375 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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