EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
2 Q7 t/ m8 {" @( e0 {# G$ A楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
$ s) O, U" \, m7 u" o这里有相应的模拟器源码,就当送给大侠了~~+ g: A1 M* r: g' m6 [
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
& M6 b! C: s$ _+ g7 @能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
+ l% u7 h7 Q% f! K# h楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
# ]; e  ~+ F9 ^7 e这里有相应的模拟器源码,就当送给大侠 ...

+ j8 X9 h0 _) A9 M1 h+ E( C聲音部分(Audoi Process Unit = APU):4 ]  w  y) a. [
.\NES\APU.cpp
% v" l& g8 O! K9 g0 `! G; `" o.\NES\APU.h
9 e4 S% o1 Q* Z1 L' ~8 }. q3 N5 I! W& }3 V' y( d* m" h
5 q* t" l9 \4 ^9 M$ K  q
影像處理部份(Picture Processing Unit = PPU):' Q% y; _3 C" g/ Z% J' o* u! u2 o
.\NES\PPU.cpp
* f0 K* H% n: O' X0 f$ o. w.\NES\PPU.h
; o. f$ y8 [3 L0 e3 U" O) @0 V( Z4 p$ v  l, v5 r2 U, h! X
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:1 L" U: V* K3 r( I1 h: W
(由于很多专用术语和算法机理都不明白,所以看不大懂……)4 e1 ~  l4 J; C6 y" e. k
//////////////////////////////////////////////////////////////////////////
' Q& ~+ q) q' {7 j9 }$ M//                                                                      //4 |0 T, E! v3 ?. m
//      NES APU core                                                    //
2 M' i  z9 M" z" U//                                                           Norix      //
$ L+ `7 J) Z% G7 M6 H7 h. Q' Y; @//                                               written     2002/06/27 //2 j! q5 r- X7 n2 M, [: a
//                                               last modify ----/--/-- //6 A# I( E/ j" Z5 w
//////////////////////////////////////////////////////////////////////////
% x2 K2 |% P* q& M2 B; ^2 z9 l2 k2 L#include "DebugOut.h", K! b  r& o3 o
#include "App.h"
$ y& ]; @  x2 K0 v9 q#include "Config.h"
- {. D2 F1 W" H8 }# o2 {
! @' W4 G& I' q/ y7 E6 B; f- |9 u#include "nes.h"
# h9 C- {+ t4 n9 \. o, E2 t: H#include "mmu.h"2 h/ s, X5 T$ K# V# U' f; z7 m& T
#include "cpu.h"
  S, U+ m0 ?* y7 k! I& z# n# b#include "ppu.h"
$ w3 |% J: p, q6 W5 e#include "rom.h"2 o8 h6 Y& }+ p0 n6 p( }) D
#include "apu.h"% G1 z6 Q$ V" a5 @# I
4 s( A# ?  o; C1 y' F! [9 h
// Volume adjust  s# `- Y! B4 A$ ?8 |; |- f
// Internal sounds
% [6 v( j7 M% i2 y. \" C#define        RECTANGLE_VOL        (0x0F0)1 Z$ V  X, \) p' p9 z5 T! Q' C
#define        TRIANGLE_VOL        (0x130)
. q8 Z0 _$ n$ r, ?: W#define        NOISE_VOL        (0x0C0)0 w- P& {: o) |( }0 s
#define        DPCM_VOL        (0x0F0)9 A3 U% W! a' y; k- P6 ]4 d0 K
// Extra sounds- e! |" d7 S# a5 g3 C
#define        VRC6_VOL        (0x0F0)% Y* ~% A$ b1 ?0 J- q$ ~
#define        VRC7_VOL        (0x130)
% m1 o* e' B+ y& S#define        FDS_VOL                (0x0F0)" N* x" \7 i; Y2 |- U( J) y. @! `+ j
#define        MMC5_VOL        (0x0F0)2 B' t8 A- l- Y9 S) ?
#define        N106_VOL        (0x088)
4 f! P# H; `  h4 ~#define        FME7_VOL        (0x130)
* z- I# M; ^. t9 `! m. }  K6 {0 q0 E
APU::APU( NES* parent )2 u( O3 E: S$ \
{2 ?2 d" u+ t- Q( ~# g
        exsound_select = 0;
2 A% R' ]4 U$ M' K: s& a# K! [& f8 F- Z+ e! D$ i  y' v
        nes = parent;$ X3 o' F! O! ~: l& D9 ^
        internal.SetParent( parent );
* q  O/ C; ]$ ^3 j! v  q& O2 l  \8 u+ h1 c5 Q" I
        last_data = last_diff = 0;
4 d9 b: p" ^9 W. R6 R; u4 G. X& ~1 y' g* g3 u. ~, F7 M5 S2 ^4 Q
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );1 R0 ?5 S2 d3 r# K. u

2 n" v9 W9 Q6 s% o5 L7 t& u: [        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );3 A" Y9 z/ ]: v, i% J3 O; \
        ZEROMEMORY( &queue, sizeof(queue) );
, o1 E, d) G+ c$ e! [        ZEROMEMORY( &exqueue, sizeof(exqueue) );5 A6 l1 E+ p9 Z  c7 n) s

/ R9 x0 Z. F9 W2 p        for( INT i = 0; i < 16; i++ ) {
  W% L6 z! A& V6 M! M- x! o                m_bMute = TRUE;/ m  g/ ]% H& y/ N
        }
8 z) y0 [6 u; h: e$ d7 U! A}" t# D7 s/ c3 d4 X! l; `( b; p
3 u5 w$ O# o9 g( X
APU::~APU()
+ [% A, k7 O* C2 ^{: z$ ]. B- p: |% v" P, [- ~
}
9 T8 A+ I7 N. Y# u. l7 G/ {3 N8 m% C8 G* w0 j( f2 ^
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )& w8 z0 _  v3 |$ ~" ~- L  l1 k$ \
{$ A$ }7 W3 a: s2 s4 j: o
        queue.data[queue.wrptr].time = writetime;$ S2 o( F" A! r; u) t
        queue.data[queue.wrptr].addr = addr;- W! f# j. u2 `1 \+ \
        queue.data[queue.wrptr].data = data;1 e9 Z" s+ M0 P0 u3 P' X
        queue.wrptr++;
% v2 a) C1 y' F        queue.wrptr&=QUEUE_LENGTH-1;3 k* Q+ M% K3 i0 t, {& Q
        if( queue.wrptr == queue.rdptr ) {
5 |5 ]( n& u' ~9 q' f- m                DEBUGOUT( "queue overflow.\n" );' L/ P9 l0 p8 u4 }: Q
        }
8 U+ R, G  x$ B. \}
2 j: m4 J: n/ F0 C& l' x3 ~0 o% I6 i. r% Y! M" \( a% S# k
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
" r6 B  n" _4 i; z6 d7 U{1 X4 A- Z* l  L5 G1 f- \1 T& z
        if( queue.wrptr == queue.rdptr ) {
6 E' p1 ]+ _* E! Q/ Z* \3 j! P7 }                return        FALSE;4 T# Q  l9 j0 \6 J
        }5 p6 o! L4 h5 P
        if( queue.data[queue.rdptr].time <= writetime ) {
" {9 g! \. S; O4 e, c                ret = queue.data[queue.rdptr];
1 Q4 y" Y  B" l$ l3 {; `                queue.rdptr++;
, M/ w  O1 Y0 R                queue.rdptr&=QUEUE_LENGTH-1;6 c; m# Q2 ~+ x
                return        TRUE;
3 a# \- E9 V2 D/ a* P        }
. [+ Q$ K9 v+ S        return        FALSE;
1 f' z4 p& y) ^  ^0 H; @}2 ^7 I* R( M3 `7 D

3 K' w* ?6 T- F2 bvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
. y( {0 |  z4 a2 Q4 y/ n: R2 X{
" @; c( p  D# V: b) m0 n8 t        exqueue.data[exqueue.wrptr].time = writetime;
+ C# K" e8 p$ N; s! o4 g, m        exqueue.data[exqueue.wrptr].addr = addr;$ _4 u1 c) v. k/ K
        exqueue.data[exqueue.wrptr].data = data;, _7 Z* A! p5 N0 ?: x0 q
        exqueue.wrptr++;
) N, \3 z4 X; K- @6 h8 b0 [        exqueue.wrptr&=QUEUE_LENGTH-1;
/ \4 o' _% S+ V2 |. A        if( exqueue.wrptr == exqueue.rdptr ) {
" I& C2 {9 y6 j9 Q, u. R                DEBUGOUT( "exqueue overflow.\n" );% j- O( Z5 h' m  m
        }
3 B& X/ N  W7 G. B0 K( [}
+ t1 B3 }/ p" A
6 Y, y! [% l+ V) N, Z; J% tBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )! a  U+ l9 o* B1 C9 C( |6 S
{
. q% I: ]7 a% Z8 w        if( exqueue.wrptr == exqueue.rdptr ) {% g/ O8 D4 a0 K: t4 k* i; I- ?% i
                return        FALSE;
! w3 Z! }( B/ B. d8 D" ^        }6 Q! }# A8 T4 Y" Q! q8 ]5 h+ q7 g
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {, l" A: f4 a% u
                ret = exqueue.data[exqueue.rdptr];& ]) J/ }* R0 X
                exqueue.rdptr++;
, h+ @4 y5 ~9 P$ p7 W$ s                exqueue.rdptr&=QUEUE_LENGTH-1;
/ l9 u$ x6 r7 n* H* l( |                return        TRUE;
3 g3 U3 Y8 f6 m        }
& f% R( C1 c' ^' F+ k5 S8 y$ v        return        FALSE;
# w% ~# E# F8 X3 r( b}) m) x, H& h* ]$ A0 }+ n: K' r
/ k7 m& a1 t# X# s
void        APU::QueueClear()2 ?0 e7 e  {) d
{- C2 F* F! Q3 V' f6 F; t
        ZEROMEMORY( &queue, sizeof(queue) );
6 x2 ^+ f: `, T; w        ZEROMEMORY( &exqueue, sizeof(exqueue) );
$ Q8 l1 @' @' \$ M" h}9 K* V  z: {8 X& B8 H3 X

. j# M- w$ P  i- {6 C+ D" vvoid        APU::QueueFlush()
9 P- B0 h4 L- v{
( {; M9 b" m7 X6 _$ |6 T/ {        while( queue.wrptr != queue.rdptr ) {
4 q4 r9 Y/ l/ }: f3 c9 j                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
: k% M2 E* S/ f5 ^! M. G                queue.rdptr++;
% G8 I2 D5 i+ J3 U6 G( r( z& w& a                queue.rdptr&=QUEUE_LENGTH-1;
; k  l6 e, X/ q8 o" F        }
$ i" W8 Q- U3 f9 X
  g& u! h9 b! ^+ \. w# ]  C        while( exqueue.wrptr != exqueue.rdptr ) {
9 G1 G* a7 e+ h+ |8 F                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
. [6 g. f% o; y* u1 S& @                exqueue.rdptr++;6 U& s) U* I" x; E  s+ Z
                exqueue.rdptr&=QUEUE_LENGTH-1;
" F, F# J! O& C9 H! r: H+ a        }1 O5 K# J. I2 ~# @+ X
}+ X8 O: ^+ a; C- H$ B' H% \6 h' y3 q

5 e$ _" W5 ^% t6 Y7 F+ d# \void        APU::SoundSetup()
8 J3 R: |( P7 p. t! T+ _{
0 f, v  M* }4 g9 x7 {# D% p/ p        FLOAT        fClock = nes->nescfg->CpuClock;% F) t" l# k$ w; L/ s- w% \
        INT        nRate = (INT)Config.sound.nRate;- U/ [- W. u; k" E7 o5 o
        internal.Setup( fClock, nRate );: X9 L! G; o( @+ E" F0 L) O
        vrc6.Setup( fClock, nRate );
) C& u2 I4 O3 a  z. e        vrc7.Setup( fClock, nRate );
, b5 ~* @. z/ u' f( t# U        mmc5.Setup( fClock, nRate );, ]9 ]7 l, V2 I" U4 V  ]
        fds.Setup ( fClock, nRate );
# u& v; k, N+ a+ `: w7 U+ n6 s        n106.Setup( fClock, nRate );- {7 [! A8 n, M% O2 o+ {. j% S
        fme7.Setup( fClock, nRate );4 p5 L1 n$ @4 E+ Z
}: j1 ?/ ^( b' H! b' {6 Z7 s1 T3 V+ o

( K! {* Q. Q5 Y3 o, Pvoid        APU::Reset()
5 g: j" V1 A. j, n{
' Q8 F( E9 S+ X. u. {. ]5 O        ZEROMEMORY( &queue, sizeof(queue) );5 \0 u7 }( O/ A
        ZEROMEMORY( &exqueue, sizeof(exqueue) );# i- y4 _: X6 r3 W& r2 y+ o5 X" k

: Y$ a/ `* v; V        elapsed_time = 0;
- R6 N+ a4 G' r
2 l2 I3 s* Y/ |# _; M        FLOAT        fClock = nes->nescfg->CpuClock;
, q0 {/ k! m2 B7 D        INT        nRate = (INT)Config.sound.nRate;
3 }+ ^7 v) h9 w3 Z' x0 K; ~        internal.Reset( fClock, nRate );$ x+ G  U' W( H
        vrc6.Reset( fClock, nRate );
9 i5 j( y; e  H% W        vrc7.Reset( fClock, nRate );# ]3 e) }& g$ O+ @+ P
        mmc5.Reset( fClock, nRate );5 e* G7 G# [7 s3 a9 s/ E) g2 S* j
        fds.Reset ( fClock, nRate );
' m3 p* o. b' |( ?1 m: [        n106.Reset( fClock, nRate );
+ z! \! y: i% i7 ~$ j        fme7.Reset( fClock, nRate );
1 D- ]; B7 U8 k" F# h* [# G% F3 F3 o! ?0 m) `
        SoundSetup();" I0 `. a1 t9 t
}
1 w; d/ F. W* ]( R2 i: O$ K! S) y; b  I/ ~) T6 B/ a
void        APU::SelectExSound( BYTE data )
0 Y/ w$ M) q1 c! R9 [4 \. s{
9 K/ R( |0 W- F        exsound_select = data;
: c/ ?9 B$ `' l& U5 p+ g7 X5 _, K/ |}* s2 B# J5 V+ m' [! }' k

0 y0 q3 b3 f; T8 YBYTE        APU::Read( WORD addr )$ b. [4 f' y( k2 ~& h* C
{! w% V2 Z! a, h4 J  z* i% w
        return        internal.SyncRead( addr );1 l! F+ C# k! t1 x/ z
}
7 w8 e) _: g- b  y2 z
& u# }+ s2 O. X" v: @" _void        APU::Write( WORD addr, BYTE data )$ ^& i- J, F: L  w/ }
{. o) t0 U! |  p7 R+ s' S6 k
        // $4018偼VirtuaNES屌桳億乕僩+ _) \6 O8 y& {4 ~- D" l
        if( addr >= 0x4000 && addr <= 0x401F ) {5 M1 r5 |( A  {+ r; U
                internal.SyncWrite( addr, data );
7 d0 t; H7 F; U: j2 U                SetQueue( nes->cpu->GetTotalCycles(), addr, data );- F( C: L; G# y3 L. H  s
        }: a( R8 Q0 I, y& E
}) ?1 ]  f/ l( X, m
- y" O9 N  a/ q, w2 d! o1 y
BYTE        APU::ExRead( WORD addr )* ~1 j+ F- u' W
{
2 k5 _% K6 @! O( o5 cBYTE        data = 0;
4 Q& _. {) H% U; {! V/ M, v* X( i0 ]* l+ v' M6 _% k
        if( exsound_select & 0x10 ) {2 h) A* ]- w9 t: {$ V
                if( addr == 0x4800 ) {. |: |' g" @6 z; E
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
  h  w. F. h& ~# Z8 }; K4 @* D2 Y                }
) r2 ?- |5 M$ g        }
' @6 L9 [! \& \) f2 I% q* P' c        if( exsound_select & 0x04 ) {1 f5 X; \+ S% b% s; C- u) I
                if( addr >= 0x4040 && addr < 0x4100 ) {
; B/ d$ Y7 K7 n: u1 ?& F                        data = fds.SyncRead( addr );
9 f# q, n$ `/ v& b3 D- Y; Z8 A/ e3 L                }
' z7 e: X- k9 O' y* Y* W3 h1 y2 u/ ~' p" Q  Y        }
6 n4 \; @7 D  s( M# K+ n/ _$ q        if( exsound_select & 0x08 ) {
$ \  Y# U: a/ s& A/ y7 v: `( N* ]( j                if( addr >= 0x5000 && addr <= 0x5015 ) {
) l$ v, J' [! c$ O                        data = mmc5.SyncRead( addr );, p" {6 I. a: d9 P
                }
. m& a. L" }) B9 C! X! {8 O- s        }% }  ~8 C, X( V0 a* h7 K& J

% x4 ]4 h. S+ Z% N" b3 }        return        data;
& }: w: O) G3 {- t; E* O8 T, \}8 U, i' ~7 ?+ M" T1 f  H' r

$ {/ H% \& h: T8 Rvoid        APU::ExWrite( WORD addr, BYTE data )
9 ~. j% }" S0 u{
% A: v0 I: x  Q3 \6 ]" \) V+ F        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
. `& U" i: c2 L# V. U" m' M; u/ h
0 w! j9 }4 P- ^# e        if( exsound_select & 0x04 ) {% s  w" V1 [1 Q1 |6 R3 Q( q
                if( addr >= 0x4040 && addr < 0x4100 ) {: @! b# m% m( I( H5 R
                        fds.SyncWrite( addr, data );' E. M6 L  M; R
                }, B1 V* o/ E- M. _% a
        }
' [+ e3 W6 y3 w  y- [- W
* r* B$ |7 x& e        if( exsound_select & 0x08 ) {
, o- ~% ]% t( X6 F                if( addr >= 0x5000 && addr <= 0x5015 ) {% k  y* c5 `( q6 N0 Y+ {
                        mmc5.SyncWrite( addr, data );  d% x0 m" `2 W# U, Q) K
                }
2 I8 q$ k% X) ^7 G        }  I7 C0 m9 z1 u0 k: c
}$ r; T. o" c  U. a9 U& f
; [( R( D" U6 _' q4 L
void        APU::Sync()
" ^4 M' a$ H7 W1 N# I6 H. q4 K& ?1 k{
) Q+ X; y2 g( y8 W$ y6 u}
1 D" E1 Q& O8 d- H( O8 x6 f5 @0 M) `& [0 I
void        APU::SyncDPCM( INT cycles )
$ x# b! q; B' Q8 ^& t& I{4 o* V4 r$ T" B3 F3 Q, S. H; D
        internal.Sync( cycles );! F  _0 t% ^! A) P! W7 \) d% C

, d( X3 c6 J1 I8 i0 r2 \        if( exsound_select & 0x04 ) {/ B. o7 ?3 C. n) z3 m: ~
                fds.Sync( cycles );
- ^2 N# ^. h+ C% t        }) }5 M" ^/ w* p" g( t' c
        if( exsound_select & 0x08 ) {% G+ R4 f& L$ n3 [9 q
                mmc5.Sync( cycles );1 Y$ n9 l9 R' J/ e, i
        }* ~! f& y6 x! b& D0 ^% s. H3 ^) j" Q
}+ W  w' V  |2 F0 Z0 D! p
# w9 b. x" j7 R% ~" U- l
void        APU::WriteProcess( WORD addr, BYTE data )- K& x, j% v  M1 p7 t5 y0 L* o% X4 [
{
: W1 e! d, t& P        // $4018偼VirtuaNES屌桳億乕僩
, b; o/ U& U' @9 i4 ~        if( addr >= 0x4000 && addr <= 0x401F ) {% S/ f- w$ K& I, R5 W8 h$ c
                internal.Write( addr, data );
* }% R' d1 b7 h& _; e. P8 w        }+ e1 H; z9 A4 h4 F# y: _/ d
}
  J7 w$ a$ M( O+ E( h
! n4 r; ]7 P  l# \9 ~void        APU::WriteExProcess( WORD addr, BYTE data )
* R0 T& b9 X' M" `& a{
7 M5 ^/ ?( o; r8 R        if( exsound_select & 0x01 ) {1 R7 t) J! l# o& O) Y" }
                vrc6.Write( addr, data );
  s% h1 w. i9 p7 S( r+ r        }( R3 {; f1 \1 _: \
        if( exsound_select & 0x02 ) {
0 N6 M3 i, }* z9 ?                vrc7.Write( addr, data );5 G4 _. b# b) w, p2 m9 ^( Z) v
        }5 }! ~- `/ c5 K; F  i' [4 \
        if( exsound_select & 0x04 ) {% O' R2 m# H, y* |
                fds.Write( addr, data );& a. k2 a" y! |
        }4 b1 s/ ^6 e) Z! v4 I
        if( exsound_select & 0x08 ) {
" ~8 x6 Y2 K8 c% |5 C" k; G9 t4 T                mmc5.Write( addr, data );3 A6 P- g) v  p+ T8 q; X
        }
! ^$ c1 j2 S$ r6 {        if( exsound_select & 0x10 ) {
0 T: [; `' s7 }) g' y& P" `9 v                if( addr == 0x0000 ) {' t! T. q: k8 s* L: {4 h) L$ g
                        BYTE        dummy = n106.Read( addr );
( k7 p8 k4 x3 C9 y                } else {& \5 v) o) x7 L
                        n106.Write( addr, data );: E+ i3 Y2 T% z7 H7 \
                }& ?2 b7 Y9 f% x
        }, y* {6 {% g4 U
        if( exsound_select & 0x20 ) {
  A/ w$ g3 S' c! c! r                fme7.Write( addr, data );5 P& o" b% ]3 X, [4 m! ~8 D; E
        }
9 T0 a6 V3 \! a9 U6 X3 o- w9 R}: V8 l- c$ |* g' _( i

- U; L1 Q0 e. ]! mvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
! O; i  ?6 ~! u- S{
, E& e+ Y3 m* R3 J  _INT        nBits = Config.sound.nBits;
- n' w: G8 K3 n/ I/ _0 CDWORD        dwLength = dwSize / (nBits/8);
6 D# a; |7 G9 g) l1 Z: MINT        output;
% t  W& w) ]9 O) G% mQUEUEDATA q;
: l# u3 y/ Y$ p3 z0 @DWORD        writetime;8 ~$ s3 a3 V6 l/ i5 Q! r/ O- a- a

* F5 H; X3 g5 C/ fLPSHORT        pSoundBuf = m_SoundBuffer;
, y4 ^5 v% m2 J& |" d' SINT        nCcount = 0;5 R" b% ?: n& j0 Y# n  ?8 ^

: x& F, n8 A. {& }% {9 p) i3 z5 ?INT        nFilterType = Config.sound.nFilterType;
8 Y( C; F% s' N& T$ p
, ^& v% z' W9 j4 E) }; C, o+ U8 V8 C        if( !Config.sound.bEnable ) {* C, m& m, m( y2 L7 A
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );! l! h; K" I- J- j# s
                return;  L5 P: ]7 x7 [
        }
2 z6 ]5 j  E. e/ u! F0 |: F0 M7 I3 f( j
        // Volume setup
6 C# }" {- n1 O' {/ |% O" D( ^        //  0:Master
2 Z; M8 e8 ^" a; j! F. u        //  1:Rectangle 1$ X6 h% k3 J% c, H+ @
        //  2:Rectangle 2; g2 k! J$ S: q
        //  3:Triangle) W5 l, h, j, W, C! U
        //  4:Noise& u) O, n6 {* Y* g8 p
        //  5:DPCM  w6 h- L& R8 E
        //  6:VRC67 {, @: [" c, M8 u: V
        //  7:VRC7/ g1 a3 O- J8 d3 ]) ]4 x- `
        //  8:FDS
& R; G- ?/ N$ b" ?5 A        //  9:MMC5
% X8 D/ c2 B2 c: ]. _; o        // 10:N106
4 b7 `" l. c0 D7 L4 J2 v/ x        // 11:FME7
  N1 b0 a0 Z; a2 E& x1 R        INT        vol[24];
: o8 M/ E' I& p+ D+ p        BOOL*        bMute = m_bMute;
" `$ ]( `. q4 r. |        SHORT*        nVolume = Config.sound.nVolume;
, ~5 o! E( a7 L7 @3 s! s7 J+ s& ^" }, v0 F8 T( S" ?
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
: K4 Y$ ^+ X& z1 d6 M$ z! q
% T- P7 {5 e, _& `: F* f5 y* F; S        // Internal
2 H% g8 I  B+ H% V        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
6 ^- }! |# F/ M: u5 @) N# {        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
' F& U5 D* c/ Y3 X  V5 ~        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;: c2 h  W7 U) C( K" ?" S4 T
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
+ u2 V! Y: V8 }% @4 }! R' |        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;2 j- j- h* ]4 |: X" {
5 o% a9 w3 K; R- ~
        // VRC6
" [+ W2 `# }! y' r7 ~, D        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
& j/ c, W- f. R8 S6 d3 @/ K; v" O        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
. _5 L6 i5 R5 c" [/ b; f        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
# E, l9 m/ Q% b
5 Z7 S, L' M  F5 Q! E        // VRC7. |5 z+ [- A$ F9 f2 g- K6 _) k( }
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;( j9 k4 h& _' |! ]! l

0 r. i+ s# O* ]: t6 `2 J. ^        // FDS7 h: j& f% b, Q4 K3 U
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;, ^6 h2 Y1 r3 `) e' S; x! ?
6 R  G" E1 m' A- j
        // MMC5
3 F+ T1 @9 x% v1 N        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;: D# j) C" o! y* H& e6 Q! k
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;8 J2 `$ o+ ^8 s5 `1 T4 m
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
. [- u- o( {0 s/ R  [( J( z& H2 u2 O) T6 h7 S4 u
        // N106
& z8 x2 _1 ]: p4 O2 R! }        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;3 I0 e' m8 x  I4 P
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
% S! o: h$ |0 c/ |/ t  m        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 X5 O& X* J$ d8 `        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ d2 i! y% y+ \! j: w1 N        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;  W& l" a- G+ t! f
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
( u% d- R( M  T* M        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;6 Q0 F4 J8 i$ }, ?
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;0 D: ^' Y, U5 H: q. @+ v/ o9 X0 O

: K8 t/ d- Z- d1 `$ l/ p( c        // FME7/ i* |/ L* d* j  h7 l" f8 c0 |- k; D
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
1 F* ^, d! I' h& c8 F        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
- Q, E& W& B: p        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
: z9 w- R& P; H0 O# B
, z8 V, n4 s; O. W2 s$ T//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
* L5 s6 t! J  n, B) p        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
& p  f! t9 K" ?& h8 A7 @! Z  `; }# x- T( H. o; y
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟7 X" |4 P9 D' ~  d2 A
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
9 I, _1 s3 y/ Y8 ?! ?                QueueFlush();2 Q! f- o, X: s  d! i, k( ~
        }
8 I, o' S" Q3 w8 m; M* G
, t1 P" [4 E% k% E7 c        while( dwLength-- ) {
& x4 t9 f& i9 J" j- N                writetime = (DWORD)elapsed_time;
4 t/ o0 Q1 l. T8 B% p8 y+ \9 F6 n
6 Z7 \7 C* ]( v+ u+ a6 J                while( GetQueue( writetime, q ) ) {
6 r! [; H4 n% _6 I5 y0 P                        WriteProcess( q.addr, q.data );9 a2 t' @; e4 y/ m
                }
8 T7 j* c9 x5 G! E, n. d. W5 k) A, p/ N2 V1 o7 x5 f
                while( GetExQueue( writetime, q ) ) {# W5 _( ?! A* k/ Z% {" S3 b9 h' J
                        WriteExProcess( q.addr, q.data );
( U5 b# s. B) G# P. ]5 v& j) J                }
. [3 \& l( Y& S% T4 K2 [
, i: Z! z6 E! V                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
) j! t% }1 l3 s8 X% r# _4 C                output = 0;! I7 i7 Y! D- i3 ~0 Q
                output += internal.Process( 0 )*vol[0];
) E5 ?7 @. B2 G                output += internal.Process( 1 )*vol[1];
2 M/ f5 r$ t) \1 J                output += internal.Process( 2 )*vol[2];
$ m" ]+ i6 z7 ?* ]7 F& @. V                output += internal.Process( 3 )*vol[3];& c+ m" t8 }1 E/ P3 C! r
                output += internal.Process( 4 )*vol[4];: l0 j7 b+ z) x- L8 L
% S9 v5 @+ j  z3 f
                if( exsound_select & 0x01 ) {+ b! j% d7 n) j  Y" }' e
                        output += vrc6.Process( 0 )*vol[5];: R3 O  C) @3 l3 E
                        output += vrc6.Process( 1 )*vol[6];4 g9 {$ \( g, u
                        output += vrc6.Process( 2 )*vol[7];
+ w! p4 k  |1 c& o. r* u. M                }
- a- s9 |4 l! K                if( exsound_select & 0x02 ) {' q* g+ [3 Z7 {
                        output += vrc7.Process( 0 )*vol[8];  Q% i, ?- s" O( k3 S1 {
                }7 Y1 g6 _0 T4 e7 n6 `
                if( exsound_select & 0x04 ) {
2 D$ M/ R8 }) D$ P* Q  j                        output += fds.Process( 0 )*vol[9];
6 I8 T8 q* r2 O- i! q6 u5 l2 b                }# }2 G" N( \9 |$ v+ q5 D1 g
                if( exsound_select & 0x08 ) {2 M+ h( G$ s& h
                        output += mmc5.Process( 0 )*vol[10];' n: s: d$ d8 \$ }3 f3 F5 v% S
                        output += mmc5.Process( 1 )*vol[11];# C* L5 P7 G% n! s* M' C4 _
                        output += mmc5.Process( 2 )*vol[12];. D7 K/ B8 i3 a
                }
6 g$ a3 V8 H* y5 d- X( h8 [5 @                if( exsound_select & 0x10 ) {
( J9 B. |) g2 t3 O. k8 B6 V                        output += n106.Process( 0 )*vol[13];1 L9 o% D9 `  m* \8 n
                        output += n106.Process( 1 )*vol[14];; R9 y$ V5 |7 E. ?# p
                        output += n106.Process( 2 )*vol[15];
1 F' N4 M+ q# C) y                        output += n106.Process( 3 )*vol[16];
9 \6 r, b4 q) j  F                        output += n106.Process( 4 )*vol[17];8 i$ {" _# G5 P$ Y" p
                        output += n106.Process( 5 )*vol[18];: M' q# O9 c, H- W# ]6 D/ I
                        output += n106.Process( 6 )*vol[19];
: a" r- q- Q, l. B6 M# S* @                        output += n106.Process( 7 )*vol[20];
& `# `7 [: p6 ^9 y' @                }* s4 i' i- `# R; I' d
                if( exsound_select & 0x20 ) {7 U  F, O8 `# B5 [4 C
                        fme7.Process( 3 );        // Envelope & Noise; t  K# G2 t3 m8 `8 n8 V
                        output += fme7.Process( 0 )*vol[21];/ p  s1 U1 }5 {
                        output += fme7.Process( 1 )*vol[22];; E$ I$ I9 u8 S1 P3 s$ [
                        output += fme7.Process( 2 )*vol[23];
* i& t% ~' x6 U; Z* K0 w                }5 ~+ g1 ]8 m( R  Y, c! s' u
9 K2 L: G$ }/ @3 e
                output >>= 8;
; r1 Y$ P" i+ x2 H" G2 ]  ]3 n
. r4 J/ c2 V& _8 t( L! j                if( nFilterType == 1 ) {
, `7 o$ `8 p- x                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)+ Y; i- `7 r3 C5 z8 e; k$ _
                        output = (lowpass_filter[0]+output)/2;$ H4 ~4 Y$ H; {, X) M3 X& S( T
                        lowpass_filter[0] = output;
+ t- X$ ~# C9 v( a- s3 V                } else if( nFilterType == 2 ) {7 c6 o" J+ L" ]) V  U* C
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
8 I7 T9 M$ c  c% v& I9 s' ]( e                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;, y- \4 k" t( A' h: S0 x* y3 t
                        lowpass_filter[1] = lowpass_filter[0];9 W8 y3 R8 Z! }
                        lowpass_filter[0] = output;
5 Q+ f( q) k9 j+ P. r                } else if( nFilterType == 3 ) {  A- g0 w/ T% b! C
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)$ k5 B2 v4 h) S* q- M+ T
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
/ r8 e' o+ d% P" M                        lowpass_filter[2] = lowpass_filter[1];
/ H  u: ^& j. d$ P! B                        lowpass_filter[1] = lowpass_filter[0];
% b& J+ P/ O8 S+ h                        lowpass_filter[0] = output;
3 k% a7 a( z: u, ^5 u                } else if( nFilterType == 4 ) {) W" ]1 U7 ?2 U) b5 R3 i
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)) n# i0 m: i) V
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;6 [* d& i& y& b; P6 G
                        lowpass_filter[1] = lowpass_filter[0];
% R% o+ s- W- x- {                        lowpass_filter[0] = output;
% Y0 W$ B4 {8 i1 c                }$ _8 O- G% t, i" y6 H
% i" p5 u+ e1 L; s1 G6 j* x
#if        0% W5 Z! f3 W4 I4 a& e
                // DC惉暘偺僇僢僩
9 y' T7 l" ~: h                {5 ]3 \) I6 m) Y9 I9 @
                static double ave = 0.0, max=0.0, min=0.0;0 X5 P8 I. N. B7 M( I1 B
                double delta;/ h! `8 y4 Q; V& E$ c
                delta = (max-min)/32768.0;) A  ?' z" r4 |1 L
                max -= delta;4 A& j; M& D+ j: }) ^- y" ?
                min += delta;0 \* P; [$ q! O+ C/ s7 N
                if( output > max ) max = output;
$ \# U5 `& r1 x! w3 p3 V                if( output < min ) min = output;! n+ o( k3 W9 o- X; P
                ave -= ave/1024.0;
( ?( j- D4 J- f! v. a; q+ t2 g                ave += (max+min)/2048.0;0 @# D) B) ]" N9 x& p) d
                output -= (INT)ave;* T7 K$ t, k' b. s* d/ J8 p
                }
, e4 [* K: Y6 h" j# M& ^$ b& ~2 L1 X" j#endif
- h4 J3 Y" K  ?#if        17 y7 Y- z  y4 L  I+ r% [  r. h
                // DC惉暘偺僇僢僩(HPF TEST)
5 q- b1 o6 H: A2 s" U! n& u' P/ m                {
; D5 ?( |  a7 K3 M& l' |//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);1 ~4 l1 l2 L( Y* O8 p* ]2 {  t
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
) t! m  T: z. p7 h                double        cutoff = cutofftemp/(double)Config.sound.nRate;1 E) S$ }2 Z+ L, t2 S2 Q: Z$ j
                static        double        tmp = 0.0;. L% T5 h& j) [
                double        in, out;
7 R) d4 k, [& y
" ], @5 n( G0 U5 Y' W, x' q                in = (double)output;
1 ?3 Z1 h3 f5 j9 G6 s5 o                out = (in - tmp);9 B5 D6 o3 J. b5 _
                tmp = tmp + cutoff * out;
; C2 U+ ?4 K/ h4 s$ p4 @" T  k& W- p7 f& @
                output = (INT)out;8 ~7 [9 u, @2 i) o% U7 P
                }! e9 l: O+ i7 w
#endif. ]. J1 u. r6 [; B  @8 y
#if        0
& y3 w/ ?' J' j8 o2 A                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
* K/ M5 R9 g& w                {
% ~6 E( m. G( P6 k: d/ Z                INT        diff = abs(output-last_data);' m  `& j, X7 z9 M
                if( diff > 0x4000 ) {4 M( a( U  ?: |% x) f
                        output /= 4;- j' A* E; ?" x" h- `0 J/ T* h. s# i
                } else ( z9 Q5 @) m, }% ~; O
                if( diff > 0x3000 ) {. H8 Y2 [; P* Z2 x
                        output /= 3;& }: Z8 ?9 [- o" w2 K! p
                } else1 y# M% Q+ d# f& f5 j
                if( diff > 0x2000 ) {
. v4 c0 {& i) F8 D+ h6 J- _, N                        output /= 2;  s0 K* @9 X$ h1 _2 s, ?
                }
# }+ i- Z- q0 F2 v                last_data = output;
* j$ |1 p; X* R; X9 R                }6 Z$ J( G# ~! Q: a) Q' o( R
#endif
6 p7 p# ?  @$ |9 {( p9 e9 l                // Limit* {+ n: W$ ?* ^  y
                if( output > 0x7FFF ) {
  U  J0 ~6 u7 f! T                        output = 0x7FFF;
$ R. w" t* Z: J3 U                } else if( output < -0x8000 ) {+ d: m+ f% @. r! t
                        output = -0x8000;
$ q. _) R; P5 S7 i/ {                }
5 [8 b* }( a* p9 I. o5 ]
6 N$ N% H  N- F3 l2 O1 y' c2 `; Y* |                if( nBits != 8 ) {
. s8 g' _3 U4 T" [( b3 B                        *(SHORT*)lpBuffer = (SHORT)output;
& A. b8 g& q7 }) u                        lpBuffer += sizeof(SHORT);
- ?4 A& Z! K- [3 Q- L& R4 |( u- i                } else {
0 X0 ]; k$ N! u: n                        *lpBuffer++ = (output>>8)^0x80;/ I. z! ^  g# Z$ C& J; y6 Q) \" P
                }
" j. U3 H: X7 X* c: c8 P$ b& q3 s4 O6 T2 f( v
                if( nCcount < 0x0100 )7 h+ O4 B/ K/ [5 A8 B
                        pSoundBuf[nCcount++] = (SHORT)output;, X! w2 O9 v( f" ^" K6 p" J! z2 v( m
( K4 l+ Q( ?+ ~8 u, w6 k( M; W
//                elapsedtime += cycle_rate;( T1 j6 t$ P; K! N
                elapsed_time += cycle_rate;
- ~# s/ ^# I( v: A" v/ b% q+ y        }
0 r) y  W" ^) W( p! f- G/ q6 V8 j$ A" f7 r- E5 K7 n+ w
#if        1
# |! M# L3 O! N8 r        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {7 ~9 [* v% F# E8 _& T
                elapsed_time = nes->cpu->GetTotalCycles();
7 }" K& U- x( J        }
6 m4 F# C4 j9 c9 h5 v9 U+ k        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
- s- t, O* D5 v2 Z                elapsed_time = nes->cpu->GetTotalCycles();( c, T. e% c) h( f9 v
        }
! I6 a, I9 W. l  n( v' {5 {#else
/ c* M9 ^" P1 n" e        elapsed_time = nes->cpu->GetTotalCycles();
- q2 t* t7 `# _% y. z#endif
4 E( k- Y5 @( Z2 e8 }& }2 h}+ ]( O7 J( [4 E2 }" \- e2 k

7 ^& ~. y) Y* w7 d// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)8 O( s/ V8 U) M4 f/ {
INT        APU::GetChannelFrequency( INT no )' w+ z1 o: H: V4 C# p# {
{; i" o: s  h% D( _( O  H1 }
        if( !m_bMute[0] )+ C) V0 q" c: W4 b+ ]: K
                return        0;
" }  d8 b9 I% {: Z! F% S) v  `; @0 ~
        // Internal
# ]2 z9 f+ M$ _8 Z        if( no < 5 ) {3 e$ W8 b) }9 Q
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
# d# L5 a- Z$ G: }6 j, C        }
3 y' n. R- W, {! N        // VRC6, p: W7 r& {6 W  O0 q7 z# Q
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {  T5 [/ E5 E. W: |8 X; E
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
0 ?0 D% ]+ L  G) a" `3 g+ }        }2 Y* \" y/ z1 L( r2 v0 ^; K
        // FDS
" j0 g* [7 P- ?) L, e+ H        if( (exsound_select & 0x04) && no == 0x300 ) {
/ S) j% T7 |6 g1 N5 d9 C                return        m_bMute[6]?fds.GetFreq( 0 ):0;  C; X2 _4 l( j1 @8 O: H9 F. w
        }4 s* s( B) {/ u0 J# e
        // MMC56 a/ R+ A2 v. O9 I. d( |
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
& n! I" {  K4 t5 o                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;% t5 Z$ t4 y+ J  k
        }5 e/ N, {: c) Q5 O8 t* U
        // N1069 d! b. Q) u5 P3 Z
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {' M3 w8 T3 K5 h% x/ {) C0 N
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;) D/ R8 w2 E0 W! g
        }
* r" k8 k. v$ [/ [6 g8 B        // FME7" W$ O( x; [1 h9 h+ R% I
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
! x# P4 b% N5 ~1 l+ Z                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;9 U: D$ n* j4 ^4 w/ K7 w$ S
        }1 @- v  A0 ], M
        // VRC72 x: P6 ?5 H- M4 C
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {" G2 ?' a7 u- J
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
; K9 b* |6 a6 p# V- d' F$ @' \        }/ W$ H. }( [5 \/ p7 C- Z2 X2 B9 u7 {
        return        0;- I/ @$ r& K" ]. y; ^# m
}' d& V" S* _5 ^& r

- j* V5 h8 n0 J// State Save/Load2 v& H$ n7 k. Y0 J
void        APU::SaveState( LPBYTE p )3 q, Q: Q0 D1 i9 j' Q
{
; P( B  r6 p% Q! F+ {& O* ~#ifdef        _DEBUG/ o, {# i' B) F6 v5 C
LPBYTE        pold = p;" H" I# S  z, W# ^6 z$ c4 R& Q0 w
#endif* X- i4 h% k* n7 }7 K

) H/ f; ]& Y. N1 g; i. z2 W        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞# E' p! j# t! Q5 @, T
        QueueFlush();
3 q) Z' Q3 w' y6 d+ Y  |/ r5 |: f
1 p% [" S7 u; N; `        internal.SaveState( p );
5 I4 Y6 d, ?7 T8 M' r        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding) m7 o2 ?8 g' @: d' D
% A* k5 u3 z7 r: l
        // VRC6
+ W- j* ^) q. }  T        if( exsound_select & 0x01 ) {& ~2 |# X: s- U' t2 l4 y( R
                vrc6.SaveState( p );1 v! I3 `- }  E2 f
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding0 I; v0 v4 U2 q' ^% S4 ^
        }% Y: A4 d+ _, h0 o) R, ^$ u' S% E
        // VRC7 (not support)6 d2 I! v, J4 A  w1 s+ {' e$ F, V% {
        if( exsound_select & 0x02 ) {" ~, @. W! F! w) J
                vrc7.SaveState( p );
( {! C, i3 t+ f% c+ @' U# `! T                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
- a" l& {, T: b$ Y8 n. i: b3 f0 t3 U        }/ J. M9 a( V+ g  W
        // FDS
! C2 ^) j$ z7 m        if( exsound_select & 0x04 ) {
2 k% ?+ a+ A* w4 E' s                fds.SaveState( p );6 ~& B9 \& Z4 u/ G/ y0 R
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding5 A9 y% S; c/ Z3 d1 v. \5 b# s3 }
        }
2 H5 p3 F! C# G4 O. g9 W  s9 p        // MMC5$ b; a5 z) d0 n  @; r  G
        if( exsound_select & 0x08 ) {
- c5 ?7 ~- b, }8 Z+ e/ h                mmc5.SaveState( p );
) ~: J3 I5 q8 E' J" U  {                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding0 H0 ~$ |3 L4 o/ N  C' H. }( Z
        }
# P3 S  `: q% V        // N106
& \6 M  w) D7 Z2 f4 ^        if( exsound_select & 0x10 ) {
. L4 R% ^' q9 t; S" [. d9 W                n106.SaveState( p );1 x3 y( P) g& s6 m' t$ g
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
9 S; d0 H8 p  P% Z& A0 Y        }7 I% J6 d9 P; U' `
        // FME74 n! {# r9 v7 ?2 K( Q5 {% T; L9 v. o
        if( exsound_select & 0x20 ) {: l  ]$ q% J$ e, ?( `
                fme7.SaveState( p );  I: M+ c7 x. l6 i
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
% F0 k) l8 w, u' O8 s        }
# d- y, J9 C, R# S7 \9 o# x/ u8 Q9 s
#ifdef        _DEBUG5 D; L% b( k/ e: H
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );6 T+ i& O4 }& p. h+ ?
#endif: z1 `' N1 \5 [! @' f8 N$ k
}" Z" C1 V& Z$ ~6 h8 J: ^

5 @) |( K3 R; y  Xvoid        APU::LoadState( LPBYTE p )- [+ u# U6 t! ~+ N0 @* B
{6 ]/ s4 d% X: T4 i& J5 ?, L
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡( _- q) J% ]" D8 G( G# W! S
        QueueClear();
, W; r) H' B$ F$ ?, G* C9 Y7 o8 [
) p5 h# ?( v- S7 O        internal.LoadState( p );; D! k5 _# q3 ]7 j4 N5 N
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding6 k8 J% T5 f" f3 R3 X8 Z( g

0 E! p) q6 L# j5 K        // VRC6
! ]; Y  d6 M7 M8 ~+ S, {; I        if( exsound_select & 0x01 ) {
' n6 ?1 u7 v" l. p; }0 x4 t                vrc6.LoadState( p );3 B& T# u' |* q3 U
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
/ _- U/ q9 I# L        }4 n8 j  c) }; J: [: R2 |
        // VRC7 (not support)8 e; q3 z2 _! u1 y  J3 h5 n4 U& g
        if( exsound_select & 0x02 ) {
9 i0 Y# T5 p4 n) t                vrc7.LoadState( p );3 R/ P  z% f& t2 T. {- s7 N  E  M
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding3 n  M* S( Q/ m- [
        }: W9 z) a6 |& V) c* P" s" R
        // FDS
9 c8 U& [" @6 K4 {. s        if( exsound_select & 0x04 ) {
; j5 W( Y( n) J. a                fds.LoadState( p );
# d2 l: V4 q1 \* r/ h# v$ ^, n9 P                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
, {" E6 k, m4 D        }
7 d' r$ H. W! h* ~        // MMC56 g' Y& V( F+ c% a4 R7 N
        if( exsound_select & 0x08 ) {
) C& G" F: c9 o6 G$ L# U                mmc5.LoadState( p );
1 \& X* l/ u, x- A7 h4 A: O! f                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
! h" i/ r1 {* V" H) F        }
& i7 |5 X; O3 s; x7 C        // N106+ k# }# k0 |  j( Z3 b" q4 r
        if( exsound_select & 0x10 ) {
4 ~: l- X/ W- A$ K                n106.LoadState( p );
5 \* n& R4 }' \0 ~# W# a- O                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding4 z  s5 d' g) M/ r. W' F3 l. f9 v
        }9 i  R9 I- V( f+ H
        // FME7
/ Z# J7 O1 u, K, D5 f7 y$ n        if( exsound_select & 0x20 ) {
! a4 X+ K4 C9 X                fme7.LoadState( p );+ k" s7 @) W0 P- i' g2 I
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding/ ~" `7 J+ h7 s% d- _* Y, Y4 O
        }" I* r& C0 x' C: r8 @3 I' o; M
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
  I0 @! q8 \  F" J& \$ g: \8 J0 C可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
  u3 x" W, C9 w8 B; O9 p感激不尽~~

, _) J- J3 v' f3 b0 J恩 我對模擬器不是很有研究,5 J2 l: l& z6 L& h7 _
雖然要了解源碼內容,可能不是很困難,
8 ~# L2 Q3 N9 P不過還是要花時間,個人目前蠻忙碌的。  H, k) u5 l7 V6 j6 e

" d5 m. [& {' L; I8 Z1 H給你一個朋友的MSN,你可以跟他討論看看,
/ z3 i  k8 ?% R- P& V2 J他本身是程式設計師,也對FC模擬器很有興趣。
2 X, |( W" g/ S* B2 X/ ^0 S1 ]" o# L% d' P/ h& V% ]. l9 J" x
MSN我就PM到你的信箱了。, P: S5 b( G$ X1 t0 M' c" |

; u$ a' p) t; B  k. 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 发表
2 T( N! P; u) |; r+ e5 E呵…… 谢过团长大人~~
' W# B) Q& u6 u7 C' B

% `8 k2 u) o3 T% ]6 ~* X哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表   v( Q- N- @1 U5 m) |* G6 W1 o
团长的朋友都是神,那团长就是神的boss。

5 u$ m( q9 {' D7 x( o5 p% Z哈 不敢當,我只是個平凡人,1 A/ Z& e7 T+ q! ]  b- l( w6 V
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙7 g% I  S- V0 v3 b: I; k2 W5 Z3 a* N
ZYH# q' a5 o# e$ S9 B. s
QQ:414734306' q$ E  f2 i1 B7 [" n
Mail:zyh-01@126.com
5 \7 p6 j% T# q7 k' n7 m0 ^$ h: [; {3 [5 C7 Q$ _5 G
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 # t0 c+ l6 g1 L
再次对团长大人和悠悠哥的无私帮助表示感谢~~

9 O# ~) f& y+ U7 H不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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