EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?
6 l* w5 F3 _$ I& P3 h" P8 O" FPS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。7 v% t2 W) S( r: N
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
% h$ Y2 F8 Y6 e4 \* c2 O$ h, ]这里有相应的模拟器源码,就当送给大侠了~~
5 g; d1 z  H1 c3 F7 @$ ohttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 . N+ o( b* H5 R& U" }) Y1 t
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
0 \6 \8 I- A9 ?楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
0 ]) ?0 O) J5 }; Y5 t. M, @  A这里有相应的模拟器源码,就当送给大侠 ...
# Y- x: Q* i* K' ]  o
聲音部分(Audoi Process Unit = APU):7 [9 \, q& p& c: b3 |+ t; r
.\NES\APU.cpp8 c" k1 ]; m- a# a1 `) F
.\NES\APU.h
# n( `* R- X" Z8 B
* F2 }1 r# j$ @2 h% A
2 y5 ]! _' Z' U# r9 ~影像處理部份(Picture Processing Unit = PPU):* a/ [' V, Q0 f( y9 r- z
.\NES\PPU.cpp! I( `# i+ [( p2 ?) C3 Z6 E
.\NES\PPU.h; M$ _/ N* ?: Q0 f! K
. d+ ?8 V/ j9 F; p& l/ M4 z
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。3 Z6 `. |$ l" y- B+ ]5 }9 b) x+ V
感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:0 J0 ?( i: r! L* k
(由于很多专用术语和算法机理都不明白,所以看不大懂……)4 t% j1 _  a2 \" c
//////////////////////////////////////////////////////////////////////////; F( a: E! G8 A: d& }
//                                                                      //& u6 D$ M: j2 k) x
//      NES APU core                                                    //1 Q; {! g% e5 A: v3 B. q0 J
//                                                           Norix      //; m/ T6 u- H* h' i: F
//                                               written     2002/06/27 //
' B* o/ Q$ s. N$ r8 b//                                               last modify ----/--/-- //
3 D  @3 D1 |7 q//////////////////////////////////////////////////////////////////////////
3 R2 M! ?) r; a6 w( M+ g#include "DebugOut.h"4 y. j3 j2 N, r+ @$ [. Z' i
#include "App.h"6 D) y, e) p/ z& h9 {; f+ o
#include "Config.h"
* L" o+ x! I; p
# n6 S6 W0 ?4 R#include "nes.h"; V% u& ~4 M4 w- [2 A; T% G1 g
#include "mmu.h"
8 D% J2 Y9 [. T3 h5 n9 o$ c/ @#include "cpu.h"
& {0 S1 N4 J7 g3 s#include "ppu.h") M* m& |, S! {& Q
#include "rom.h"
: d' t9 o% i  \; t0 I0 ~#include "apu.h"5 T8 v7 c. }9 ^

2 X( `0 B3 I9 L+ R& {5 }// Volume adjust: l! Q3 ~8 T) p2 U
// Internal sounds& P+ A1 N- I. d7 S
#define        RECTANGLE_VOL        (0x0F0)3 R. O8 [7 n5 m' R
#define        TRIANGLE_VOL        (0x130)
" x! D  q2 d6 ~0 ~3 O1 j/ S#define        NOISE_VOL        (0x0C0)3 f+ v( [: B3 C/ F7 d0 c
#define        DPCM_VOL        (0x0F0)
3 ?" I4 s: H+ ^7 m. f// Extra sounds
) {2 J; [7 j# D+ L4 k#define        VRC6_VOL        (0x0F0)
/ |* Q1 \1 p# i#define        VRC7_VOL        (0x130)) k7 B3 L, q( j+ i+ c
#define        FDS_VOL                (0x0F0)! a1 h8 x) S7 F& L
#define        MMC5_VOL        (0x0F0)
& d- G3 d/ ?6 t#define        N106_VOL        (0x088)9 M9 ~% j5 J# v2 L$ L: h8 E. S
#define        FME7_VOL        (0x130)$ x. j7 K8 `- U( T/ y* p+ V; {
" U) V* e& {" s7 F1 a
APU::APU( NES* parent )  U! W$ k3 {) C9 Y
{% B! S8 Y0 J8 v( W# U4 v
        exsound_select = 0;' ?3 k3 o, T: y6 n

# ?/ e- B) t2 F/ Z8 ~* {! ^        nes = parent;
5 s  I4 q" W4 {  U        internal.SetParent( parent );1 W& E' h) C% z' ~( M

* \9 }, c! J$ ]4 U: d        last_data = last_diff = 0;9 U  u3 q8 F/ s# ~2 q7 b: d/ ~
- ~* |. U# R( z1 _( M8 C
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );3 S( v( R5 P# N2 H0 [6 p. R
6 R( x3 d. A5 t7 l5 E
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );' |2 H3 N1 u1 t4 n$ c% W. x. J7 {# x
        ZEROMEMORY( &queue, sizeof(queue) );
+ C3 z' ?8 H. w' B, M& z        ZEROMEMORY( &exqueue, sizeof(exqueue) );
8 v: p0 f5 z. }9 \$ U$ ?
7 z  _' f" D3 ]8 Y        for( INT i = 0; i < 16; i++ ) {
+ Y% b8 O5 S0 [+ Q- z                m_bMute = TRUE;
$ `: t3 m. z  |8 e/ ]; z9 \        }; z( L! Y; O5 f# J
}5 V: W# \5 \% d' n3 _
& C. F$ E+ V" c$ B0 w
APU::~APU()" }( ]  t1 a1 o9 X
{
, }3 e, g' i4 z* U3 e$ U}
& {; h' }  a8 O0 n8 G9 `/ F
5 S9 r2 f$ I4 [+ ]+ e; A5 fvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )  q  i* r8 {  w5 ~
{
. C: }: s. l5 @; z3 q/ p4 [1 ?        queue.data[queue.wrptr].time = writetime;
* H9 k# F$ F7 r6 Z! {' r        queue.data[queue.wrptr].addr = addr;
) A6 k8 \1 h0 R9 v3 D$ p  Y        queue.data[queue.wrptr].data = data;
& ?& u, D+ I7 A/ ?/ ?; g0 ?        queue.wrptr++;1 x" W3 z6 L) f, }% O  R
        queue.wrptr&=QUEUE_LENGTH-1;
% \7 F4 p0 `0 n) b        if( queue.wrptr == queue.rdptr ) {
2 i, I4 c5 d, ~( V$ x                DEBUGOUT( "queue overflow.\n" );3 d- O* I4 V5 @5 x6 L( q, o
        }
9 A, ?; G6 w8 c+ B}
* C! e: E0 G. h# L( Y9 U7 N2 g3 K! a9 ]  U
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
" ]. n2 ]- J( J{9 g4 x/ \5 D/ {& _
        if( queue.wrptr == queue.rdptr ) {
1 u) T! x* a2 V& n                return        FALSE;
( M: y' i1 d6 V  w% ]5 p" I& J5 ?        }
7 T) Z: M* C: ]. w        if( queue.data[queue.rdptr].time <= writetime ) {
& C" E8 G0 Q+ V  K, w                ret = queue.data[queue.rdptr];3 b! T+ i. m6 F" R. C
                queue.rdptr++;
9 g' B/ @  i/ r& B                queue.rdptr&=QUEUE_LENGTH-1;, V: V3 E: w9 [; i& R/ q9 \6 M7 ^" i: f
                return        TRUE;
# y' }# {; q. R9 Y% k        }+ E8 N0 _7 s, y! n8 @0 h# K
        return        FALSE;
0 C+ X) e" X% |}
/ c8 U; I1 V0 C3 U/ k4 W6 S4 i6 X: }
* K! z) u% P1 C& y' {. R+ R( i: uvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )* A8 b0 g9 _) ]8 S1 C
{
; ~$ R" ~: h* U0 X* C4 {4 q0 I        exqueue.data[exqueue.wrptr].time = writetime;
3 |: a. ~- {; `- U9 w5 G5 z: ]* q+ I        exqueue.data[exqueue.wrptr].addr = addr;4 K2 `, l2 }8 E" p
        exqueue.data[exqueue.wrptr].data = data;
- ^( ?/ S/ v' [4 S" |        exqueue.wrptr++;+ F& z6 ~# N5 A
        exqueue.wrptr&=QUEUE_LENGTH-1;  O! d: J  o, O, p% K8 H" @! c
        if( exqueue.wrptr == exqueue.rdptr ) {
2 J- P* v2 p8 z; q) `, r                DEBUGOUT( "exqueue overflow.\n" );
: W% C- V& @( |2 \# U, k        }* P" [) [# {6 l4 \$ y9 @8 Q4 [
}
( a& C; r: R, Q! j! A9 k) }& {" V" ^& |- I7 ?
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )$ @/ B! j% J& x: l: ^/ G
{6 ^! a* Q$ m( I- g4 B' U
        if( exqueue.wrptr == exqueue.rdptr ) {
' r9 W9 P" W8 E$ b0 f                return        FALSE;. u2 y( o8 n* x8 B8 |% K
        }
+ {3 }3 q8 v/ H( D/ |        if( exqueue.data[exqueue.rdptr].time <= writetime ) {4 j0 Q! b' T' Z! V5 R7 x& T
                ret = exqueue.data[exqueue.rdptr];
* e8 n0 t+ o% r; o5 v( B                exqueue.rdptr++;
6 z9 z% W2 h" i+ ^                exqueue.rdptr&=QUEUE_LENGTH-1;/ z$ O; s: L5 I, q8 B
                return        TRUE;
* C7 U9 [- |6 ]: _3 s3 U$ h! v        }
) @% ]4 k/ ?+ K/ B2 {9 @        return        FALSE;
- J4 j$ y% I3 S: x}
/ d+ W- G0 Q( F) U! U/ K
2 s, h' N4 k( Ovoid        APU::QueueClear()
, ]! N1 a2 B1 c1 v4 [3 A) K{
( u) q. w8 b* J2 \+ @, ~9 {; Y        ZEROMEMORY( &queue, sizeof(queue) );; I+ E" W' w# p, m! R1 E* }
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
, V: M' B( m8 g$ O+ M1 d/ t}
0 i' V$ I% j$ ]! _% T; G8 L: u
void        APU::QueueFlush()1 H5 n$ V, R$ k/ _
{7 q4 K' q$ N  x
        while( queue.wrptr != queue.rdptr ) {
/ T0 \- @2 x5 F- a# x0 m3 r                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
3 x6 O3 x0 C2 O+ I1 w                queue.rdptr++;
6 _9 a" X% V* X* y                queue.rdptr&=QUEUE_LENGTH-1;. x( Q3 @' x, _$ j8 }) K5 q
        }
( n7 d8 v2 G6 B/ |7 X; i$ G
3 x! f5 p& T! n' W        while( exqueue.wrptr != exqueue.rdptr ) {$ q' j( j6 l5 m  b9 S% @) v& Z
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );$ Y( d& ^( n( ^3 q
                exqueue.rdptr++;) g: r; {# P# W1 D! T
                exqueue.rdptr&=QUEUE_LENGTH-1;
8 P: }! c9 `" T2 `- [. D! p0 @7 K        }3 @. a0 ^* t6 A
}" M* P3 U5 }" Z) m
& E3 ^  @0 R; q: p0 t! y) |$ N
void        APU::SoundSetup()
1 O5 y" @6 z- X4 @) S- Z1 ^: k{
, `* n3 ]) {: `  g. f        FLOAT        fClock = nes->nescfg->CpuClock;
' R% n- q4 o+ h5 l; x/ A        INT        nRate = (INT)Config.sound.nRate;' m- f- w5 }- [7 o5 k
        internal.Setup( fClock, nRate );5 e- p1 Q7 C2 k# D7 ^. I" K+ W! B
        vrc6.Setup( fClock, nRate );' j# @1 L" C1 K4 V: f; d% F/ v7 h
        vrc7.Setup( fClock, nRate );
( U+ ~5 T$ u- q$ z5 q& B! W' S9 I        mmc5.Setup( fClock, nRate );" U! q) F- }; ~. X- N6 P
        fds.Setup ( fClock, nRate );
2 ?+ R- ?) k" Q( x3 P$ g8 z        n106.Setup( fClock, nRate );
* _& N/ s2 ]4 d. w) w. ?        fme7.Setup( fClock, nRate );
+ y/ f0 Y2 Q0 c+ D}$ O# z5 H+ _! b7 D. M
: `$ Z( ]# C  d( _1 K5 {; Z+ k
void        APU::Reset()" J$ |3 @4 m) Y  p- p9 l
{6 Y( Z' G. F# j% ~4 P
        ZEROMEMORY( &queue, sizeof(queue) );
1 T' Y5 E0 D6 @! ?        ZEROMEMORY( &exqueue, sizeof(exqueue) );
8 S+ q! o6 f' X" a/ @, R
" f- g7 J' B0 }& M) c- r. j* ?        elapsed_time = 0;, Z7 S) d4 x8 V

4 A1 Z; L9 y* Z# [        FLOAT        fClock = nes->nescfg->CpuClock;
4 C# ~* K/ M7 j* a( f2 K7 d2 z        INT        nRate = (INT)Config.sound.nRate;; s" Y/ l% p& y0 b) M1 `; n
        internal.Reset( fClock, nRate );* S- Y6 B. \; g8 C5 |
        vrc6.Reset( fClock, nRate );
: u' F  r3 ]3 r8 H+ p8 [* }7 b8 [        vrc7.Reset( fClock, nRate );
! g: ?6 s& Y% ~& }9 s6 u        mmc5.Reset( fClock, nRate );, D2 s- M$ c' Z" d2 U! U8 e
        fds.Reset ( fClock, nRate );4 h, w# @) [" o- A+ h
        n106.Reset( fClock, nRate );
, @+ q) s" N& Z4 x0 M5 Q        fme7.Reset( fClock, nRate );
# w+ `% N: e4 c
1 `' z- c0 T& l        SoundSetup();6 E: j$ a# G+ g5 L; s6 @5 j
}
& l, }, u( T4 w) N. I) b- y
; z! [9 a+ \0 E$ E0 t* Avoid        APU::SelectExSound( BYTE data )) n/ P3 V- c: h# Z
{
; x5 W4 h' R7 H2 |5 ^2 ?        exsound_select = data;
. m7 l* A/ |0 A& b}
+ k  [% Z9 t! O" P% H6 \' R9 ~/ d, f- T/ U& S7 h, x
BYTE        APU::Read( WORD addr )
9 a; T( {' ]4 s" r, S8 P+ l{
' F8 w! e5 E, k5 G9 b  y        return        internal.SyncRead( addr );1 Z) G& w2 s2 r9 O% f2 }, t) Y# I1 l
}5 t9 k7 k7 W( r- w

5 a: h$ u# ?4 q+ G/ Fvoid        APU::Write( WORD addr, BYTE data )
& b  x7 r) u8 F; r{8 b8 M  ~- e1 E: C* ]8 b  L2 R" ^0 Z
        // $4018偼VirtuaNES屌桳億乕僩
7 d2 g3 X0 n# t) `        if( addr >= 0x4000 && addr <= 0x401F ) {
& e! |4 P, I0 ?3 n# h2 V! c                internal.SyncWrite( addr, data );
, `7 N* \+ R) K: |1 ~                SetQueue( nes->cpu->GetTotalCycles(), addr, data );. u2 J. `$ w1 O5 h
        }/ k' o* M3 ?1 X' h' U) A
}5 N: T8 s7 C7 f* j8 O

  z& E& c; A, I. d- z+ MBYTE        APU::ExRead( WORD addr )
/ u/ D! \+ n: q! H: i, t6 i) K{
( _0 q2 F$ S4 s2 f0 O( hBYTE        data = 0;7 h2 k2 T) e, f! M

, Q9 w1 D% R: o        if( exsound_select & 0x10 ) {
1 V& W, x6 `! y: O+ w                if( addr == 0x4800 ) {; m# L9 a$ i' V8 K6 K
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
, @1 v9 H2 x+ i: `, |                }. [0 {  [0 \: z# p9 ]: X0 T9 K/ r" x
        }
. J2 k5 w3 U1 a  P$ s        if( exsound_select & 0x04 ) {
( |8 z, g3 r; P4 ]. `0 n                if( addr >= 0x4040 && addr < 0x4100 ) {
& g0 c7 O8 b' ~1 O                        data = fds.SyncRead( addr );1 a  s' J1 M7 u! j& }8 _
                }" w4 j/ a+ z- Q! K: g
        }* ?% E) R& J3 V) n& j4 B
        if( exsound_select & 0x08 ) {
; q& d0 D; {9 }, ^+ h0 s" E$ ^                if( addr >= 0x5000 && addr <= 0x5015 ) {1 N: R8 L  R8 h2 p* J
                        data = mmc5.SyncRead( addr );
6 G/ C4 |- o2 I2 e                }
3 |9 x1 f" V9 Z& H        }
; |. L4 w1 }+ I( r/ W- ~
' ?; \0 S1 b- K& _4 T        return        data;
* z/ [$ d2 M& R* {}/ z, B1 a) i; P% |$ t% k

% R- f- D# k# y% k$ C: Fvoid        APU::ExWrite( WORD addr, BYTE data )- [& I* }9 p- F5 z
{' U4 u1 b  g* F6 [0 C  r
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );% E+ B! Z  P. `! u: `' H. m8 g

2 g; R: b5 u: {4 X5 n7 D2 c1 H        if( exsound_select & 0x04 ) {! Q2 t) X" s' u6 \- \/ L) w) m6 }
                if( addr >= 0x4040 && addr < 0x4100 ) {
' b* @3 ^" ]% _+ v0 S2 W. Y1 X; T                        fds.SyncWrite( addr, data );( w: ~! P8 |$ T" I# }7 V& \& l
                }
8 X0 D4 U" k7 n5 h7 _, {% t! K& |        }
: e" s; a# r3 {1 W2 N3 W
- C% L0 H/ Q+ ^6 z/ E. N& d        if( exsound_select & 0x08 ) {
! r5 r9 A( l; [2 x7 v4 s) z: P                if( addr >= 0x5000 && addr <= 0x5015 ) {
0 e* A) ]- b: ^  w8 s" O  \                        mmc5.SyncWrite( addr, data );# L1 X1 e" u( n& y6 L
                }9 T/ d( b) s% P
        }
9 Y) R- B1 N3 K: \: o}
4 K; W, m) D, O( S/ @( E
: w7 ~$ e) X% o& W3 S' Jvoid        APU::Sync()
$ b  q* q5 Q8 M- J: k# a9 V{
+ q$ ~( b3 R2 B8 T! j) S$ I}: X6 x' W# f8 k- u

( i7 ~+ M. ]% G% @7 a( N% Mvoid        APU::SyncDPCM( INT cycles )
, ~, k4 ~0 F+ V" N- C6 R  T. O{
! ~' @/ I; Z9 T2 ]6 j) n, f        internal.Sync( cycles );
6 r) H! k5 t' G5 P  }" \
: h0 t, V) C7 J        if( exsound_select & 0x04 ) {" I# X* B, A8 p, F( K
                fds.Sync( cycles );
9 ^3 v% D# |, Q' G6 m        }6 r9 O( {9 S# \( U! V
        if( exsound_select & 0x08 ) {
. i8 m3 R' m/ ]. U7 d9 c$ x                mmc5.Sync( cycles );
, i( j1 a; w% b4 I1 e" o        }( n6 R3 q* n7 X- n6 u
}& f/ D1 A+ D: I# V: L

0 ^( V3 \* F, T3 }6 U+ I! Qvoid        APU::WriteProcess( WORD addr, BYTE data )( ^; C! j5 k. R
{4 K' ?- u4 D+ ^
        // $4018偼VirtuaNES屌桳億乕僩, A* b4 v4 r" m2 x3 i! e
        if( addr >= 0x4000 && addr <= 0x401F ) {! @( a4 u  o" m2 R
                internal.Write( addr, data );
/ I" V6 u$ G  z: }        }* ^6 A# q" n( e( B+ }% r) w
}
% X& p  E+ C! i7 [9 q# y1 `( ~6 c. I+ H( q
void        APU::WriteExProcess( WORD addr, BYTE data )4 P. C) Z! |" }4 A4 o* n+ G5 z+ K$ o
{
1 g9 P1 P4 x: L: h/ f        if( exsound_select & 0x01 ) {* J# N" J8 N5 a# s- P' ^& s# L
                vrc6.Write( addr, data );
/ j8 {# m- y0 ~        }& X  {; w: b1 b6 p# z  v) x5 N/ P
        if( exsound_select & 0x02 ) {
! ]3 J; w8 `6 }9 s  \                vrc7.Write( addr, data );5 z# g' }# q" n  [
        }
0 ?+ s* L. }7 v$ X) D  V- P        if( exsound_select & 0x04 ) {8 T) K+ J. O$ \% f  Z- b6 A
                fds.Write( addr, data );
9 H  v5 b! ?* r6 i2 V$ r0 d, ?        }$ O9 `' R1 E' a' P4 A
        if( exsound_select & 0x08 ) {
9 z% q" \3 e- U# `( U& ^* R                mmc5.Write( addr, data );9 `. g5 \4 _# s1 s5 y: F
        }
1 V8 L$ d# a/ S- a        if( exsound_select & 0x10 ) {. ^; v& L2 m* x
                if( addr == 0x0000 ) {
1 y6 H, Z% {6 E* ?                        BYTE        dummy = n106.Read( addr );7 m; }- k1 P$ J
                } else {
$ T4 _; K, q2 Q                        n106.Write( addr, data );$ f& C) n  A  \
                }
4 |0 X! y1 d5 m        }
4 z- R" Z  C2 y# D  z9 f        if( exsound_select & 0x20 ) {4 z5 u1 L. E1 n! q8 H+ f
                fme7.Write( addr, data );7 [% p/ q( c2 ]3 y
        }2 I) I. D" L( @# M) V
}+ m, w) H/ M" d5 ~6 M) S$ J- ^9 M& t
. O0 q1 i/ s8 B: ^
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )$ `3 B' }! T6 i7 u
{
3 {/ H  a5 F" t: ?6 v) {* gINT        nBits = Config.sound.nBits;
6 f: P& k4 l2 qDWORD        dwLength = dwSize / (nBits/8);
- ^2 Q4 t: l& j3 }INT        output;
& C3 y% f; i- n2 V; {% A: SQUEUEDATA q;
" Q( q; A* x* V$ m6 z6 G  QDWORD        writetime;3 I2 m) u3 b  |8 R7 b* N
/ _5 K1 {! j4 A  x( X8 v1 V  c
LPSHORT        pSoundBuf = m_SoundBuffer;
) u% T6 Z$ q0 a( d- Z& ~INT        nCcount = 0;
. P8 Z; P: W) u% U9 I0 V  a% |  n$ Q" i3 S3 n! d
INT        nFilterType = Config.sound.nFilterType;
8 W5 `6 ?) T% t8 J; u5 n" s2 R4 O' G) H; J, [6 D' z; t
        if( !Config.sound.bEnable ) {
( N( x1 Y( z2 O0 _0 x, O$ b) T7 D                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );0 l" D- ?( D' u
                return;2 r: `0 O# L& d+ O- B+ d6 v& z
        }8 b' W& J; v1 T9 b6 C

# k3 T: h$ L. _7 z6 a        // Volume setup8 M6 D$ m6 t3 q8 H2 C1 T4 [
        //  0:Master  a6 b( h, K0 `  }6 q. x
        //  1:Rectangle 1% j) h. h9 T' x1 _/ n6 P. S5 T2 J$ x
        //  2:Rectangle 2' q. e: u  g# G. i7 V9 }+ F6 q3 W- F
        //  3:Triangle' O# t0 H* T8 c
        //  4:Noise
8 Y& S3 e; v1 R" ]        //  5:DPCM
# @- S* n& v( ~5 a" r+ A% E4 A        //  6:VRC6
* P6 v% P" O# q3 b- A" ^        //  7:VRC7
* H/ X  Y; `0 A8 h) p        //  8:FDS8 r$ \8 ~% S: V: n" J4 d# N
        //  9:MMC55 N+ P# }6 D/ _9 `. K' ~
        // 10:N1069 W4 G' A: X+ R6 x; B
        // 11:FME7, v& k9 D4 u6 Y- G0 L! h, W: A
        INT        vol[24];1 t* X/ v1 d1 S, p7 R# A6 I
        BOOL*        bMute = m_bMute;
0 [/ g3 ^7 t) K7 u6 O: n        SHORT*        nVolume = Config.sound.nVolume;
& O& k; |! h" }; g; |  P* ~5 u: S. v. ?* m0 B+ b1 ^
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
: I. i. h, B6 |2 l1 u: s9 X! V4 O' v0 e+ t( R( V% }
        // Internal
7 O0 s% [9 f; h! J) I' ?- N        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;0 o8 T) R( L! J" H; E) a
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;* ?0 J. ~+ I( A  _8 U
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
3 ?* u1 |2 D. _# s9 Q+ k  M        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;. D7 X1 B3 a# j# |+ |- F
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;' A0 t8 i9 r9 g; `

  s9 S! u4 J9 }        // VRC6- R9 {+ @/ u) u: c: v
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
4 o/ v; ]9 N7 I, m( ]7 Q- G3 o        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;; F: Z! w+ v/ J" D" l3 o
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;4 I8 N  e; z, u( y1 e# H, w
% P# @5 t: S; n5 ?  E, [) d( W
        // VRC7
7 w) R8 x+ i: ^" ~+ @0 g& `        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;) |+ H5 _4 n! `% o- z
5 r( b: ^. ?% ~& j4 x) M
        // FDS1 x% ?3 x1 V8 H$ l8 p% e
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
: N! K( `, G/ W9 k6 [' U
5 L2 K! R4 w9 }2 H; y( A        // MMC5
3 B' @2 J# C$ s, P, ~, s8 W# r        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;" d0 S+ P* K# h% z
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;# o! C" b9 d! Z1 r- |* L
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
. C5 p2 |3 k/ F, H
% [; s- R9 H9 k        // N1066 b  B* M3 j4 z% s
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
# @' }) c8 r2 y) `        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
$ ~+ S5 l% ]: d) L% z3 E0 X; C6 X& J        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;3 F  G% j% w/ J) A4 j& s! n
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;1 z9 o8 Q# Z/ y2 J! ?
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; b$ z3 H- r( [9 n* r/ [) w& W7 @& @
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;6 j- K( O1 @5 x6 g" G3 N
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;% ]8 D/ A2 j1 F" |
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;1 I5 U2 t! Y" G/ I$ o

, @9 F" J/ u3 v, o' z        // FME7; o2 w% ^+ }% m8 [/ F
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
$ m8 x$ @- j  M3 Y/ `        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
. R, a: A! F- R        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
5 f4 u/ g. Z" ^8 J# n+ `, o$ W8 m# f% E  a
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
9 h8 D* Z+ `8 A7 ?- T        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
: j5 ]6 S; u6 k( E" f: V% `' Y
% s# E3 G9 p' ~! X; L) k' }        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
& a& G: D& {7 A( J5 U        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
* s, ~0 Y6 ~5 z( Z6 l, M' B+ z                QueueFlush();1 H2 {# n8 [1 b) I
        }
7 o. N; m7 |7 q' y& y. R+ v, y4 m- T% x/ u
        while( dwLength-- ) {
5 P# N$ v( [1 S2 ]5 {/ c5 h' d! v                writetime = (DWORD)elapsed_time;* G5 ^- f# J) b6 T& g" W* k

4 q# b1 I2 P9 X% \; d. G: Q                while( GetQueue( writetime, q ) ) {
! P5 {2 o+ Q- ?, q5 V% i                        WriteProcess( q.addr, q.data );
' ?) f( a4 n  t) A; z/ R                }  r( J3 P4 r0 L

2 j5 l/ e6 |* d- j                while( GetExQueue( writetime, q ) ) {
  n2 a7 t: Y: n4 x                        WriteExProcess( q.addr, q.data );
, |4 w+ B& M* t$ |                }( T, g7 b- T3 c3 @! X
. I) f8 }' }6 }6 n. x0 f
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7. `# j& [* G) S- s1 Z" F" X
                output = 0;, P/ C8 F- Z! N! z
                output += internal.Process( 0 )*vol[0];
( B9 s% |: n3 _) C5 [                output += internal.Process( 1 )*vol[1];0 s% g; B) Y; R' W/ M7 w+ q
                output += internal.Process( 2 )*vol[2];, K7 K1 ^) T, P+ G$ C! \% X2 e6 @; W
                output += internal.Process( 3 )*vol[3];% N5 U- n7 j) ^, c8 u
                output += internal.Process( 4 )*vol[4];) B' K5 r0 W; ]* \  m# a1 |

& e' j4 \7 p% x! i& J1 f! i                if( exsound_select & 0x01 ) {' Z9 H7 u" ^: i7 q2 O" p
                        output += vrc6.Process( 0 )*vol[5];
/ V  ~2 h2 @+ D) Z8 e                        output += vrc6.Process( 1 )*vol[6];  K* L, B$ r+ ^6 I* i
                        output += vrc6.Process( 2 )*vol[7];' S5 _: v/ X2 @) d, b
                }, Z8 k) K6 ?' O
                if( exsound_select & 0x02 ) {
5 C6 s/ ^; P4 {3 \  S" E4 F5 T, d                        output += vrc7.Process( 0 )*vol[8];+ J- b( i& F: x8 l* o& Q6 L5 Z
                }/ U, `8 _  O3 q3 X+ b- X6 g' y
                if( exsound_select & 0x04 ) {
, n, e. \' |+ ^* r: ?" H" z1 d                        output += fds.Process( 0 )*vol[9];+ ~: U' Q3 k7 g0 _9 ?' t
                }. f  O6 ], i- ]7 H: n$ m
                if( exsound_select & 0x08 ) {
0 x5 C' l( l0 J4 a5 ?8 W' y" D                        output += mmc5.Process( 0 )*vol[10];
9 E0 X/ ^$ ~% J" J& n  ~                        output += mmc5.Process( 1 )*vol[11];, J8 f: h' K) ]- e. w8 X
                        output += mmc5.Process( 2 )*vol[12];
" ]: \# [( D. p3 ~) {                }; _2 y+ Q, O/ n( K1 M7 I
                if( exsound_select & 0x10 ) {' G( i4 W0 h; v, W, S, w
                        output += n106.Process( 0 )*vol[13];+ z* m. o! L* N: p8 |( q  O
                        output += n106.Process( 1 )*vol[14];
" @( k2 M! d" ]! \- i# l                        output += n106.Process( 2 )*vol[15];
& B& t( m: H* k5 D& d8 o                        output += n106.Process( 3 )*vol[16];$ {; a$ x# [# O+ g: _4 N9 O
                        output += n106.Process( 4 )*vol[17];
! b. C+ y% q$ i+ t/ @                        output += n106.Process( 5 )*vol[18];
% B  w0 z" ~: r0 y                        output += n106.Process( 6 )*vol[19];2 Q- r' p; c7 H3 n+ z% A
                        output += n106.Process( 7 )*vol[20];7 ]( U0 ~( a6 D$ P# e) _
                }
0 ]( K& \% [- ~' M                if( exsound_select & 0x20 ) {
4 ]9 ?& `0 V( H+ n7 {4 @                        fme7.Process( 3 );        // Envelope & Noise
- o8 X* |1 A6 K( A0 s9 a+ ?$ T                        output += fme7.Process( 0 )*vol[21];3 A1 r: v8 O" K6 l8 P* ~; t
                        output += fme7.Process( 1 )*vol[22];
$ Q8 k7 C/ K2 d: y4 g. D8 }# F4 |                        output += fme7.Process( 2 )*vol[23];
2 H9 j% b2 y+ d0 n% y& ~/ C1 P* ^                }
0 |( K3 `& r  U" T. n5 h% A% F1 y; }. S2 _: Y, W
                output >>= 8;" x, ?! f' u& q5 d* w/ T: `& e

7 `5 i, j% r( ~5 W, i2 n: S                if( nFilterType == 1 ) {
1 a+ `5 u0 D. b4 ?                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)3 @; v0 c; v) u# x
                        output = (lowpass_filter[0]+output)/2;
* w7 [* y  v, w                        lowpass_filter[0] = output;: [* H# W- `0 K
                } else if( nFilterType == 2 ) {
9 R, h4 l3 d0 {7 r$ g                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
8 b  O7 s4 U; X3 ~6 |% x4 s7 e' V                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;8 n! J: z0 X* s3 l4 H
                        lowpass_filter[1] = lowpass_filter[0];* ~5 P) `; h9 @3 k* J% ^& d
                        lowpass_filter[0] = output;
4 g- `; d$ c- p3 G* O! D  H# c- y                } else if( nFilterType == 3 ) {" i) ?1 Z3 o2 E1 W$ X
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
) [" D* {- s" P; S$ \# m0 p                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
, j+ l' h" s7 o! g                        lowpass_filter[2] = lowpass_filter[1];
  O$ ~1 K" E6 m6 t  D                        lowpass_filter[1] = lowpass_filter[0];5 V5 _' V! C, s0 M& X
                        lowpass_filter[0] = output;: O/ e# C6 O" B1 Q5 c
                } else if( nFilterType == 4 ) {: ^. r. y% H2 o( r/ b' C1 V0 B/ a
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3), F3 R, V0 O2 g. x; z/ Z. n; Q
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;- N/ M9 W! C+ `5 R9 g
                        lowpass_filter[1] = lowpass_filter[0];1 z  X3 T# {; m5 h3 |
                        lowpass_filter[0] = output;  Z6 n) ?9 k. x$ U. _
                }
: g$ c9 P6 v" k4 w. |% ?3 e3 e/ f0 ~& Y" H& e; M8 F
#if        0
* t& D3 M' O; |# X" C% Z' g; V                // DC惉暘偺僇僢僩+ [0 z$ G1 a, e
                {  k+ N4 [9 C$ g% B
                static double ave = 0.0, max=0.0, min=0.0;
* f/ X7 v- ~3 h                double delta;
) L% m+ W- v7 l$ `' x/ B                delta = (max-min)/32768.0;
) B/ J6 z1 s# Z# u: X, Q  D$ F                max -= delta;2 d6 Z5 m+ a/ n; O3 z% \8 T
                min += delta;
$ C: X& ~6 s: P' z                if( output > max ) max = output;
9 |/ T( d& J3 @0 A' @! J! H- H8 t                if( output < min ) min = output;
* w% ~1 k" B6 J, A5 i5 A' [                ave -= ave/1024.0;
1 @+ Y) ~( s$ O0 }2 X  G                ave += (max+min)/2048.0;
8 e, |6 ~7 P$ G2 [  e8 P* |                output -= (INT)ave;
+ A- i0 r1 u0 d& X9 C  S, @                }$ _6 k' q/ M! _$ H6 W; R
#endif
+ [& ^" X) t- Y% l) L8 R% V1 E#if        1
- i: P; r" N) r. E1 d/ S2 _4 y                // DC惉暘偺僇僢僩(HPF TEST)% j, M4 c3 C, F$ C, Y+ }
                {: r7 w0 U! t  r6 M& o
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
6 j; o7 q1 t- w0 P; p0 J                static        double        cutofftemp = (2.0*3.141592653579*40.0);
* A+ L$ P) V) @                double        cutoff = cutofftemp/(double)Config.sound.nRate;% {9 y. z" T! t5 ]
                static        double        tmp = 0.0;/ e7 G) ~% L6 `! q
                double        in, out;& F8 G, L1 U, a* i$ Q. y
  R+ ?# U1 B, ?9 D. Y2 y
                in = (double)output;5 k4 Z8 p( O2 v8 L
                out = (in - tmp);
0 \, C( l# n0 ^* @; R, `8 W. t7 Y                tmp = tmp + cutoff * out;1 D7 h) A1 f, U. Z
9 ~2 W9 d/ j( O- c$ T# I. p) o
                output = (INT)out;
2 _1 y) J7 ^) E6 q                }
+ M8 n, X2 `; P# H  E3 E#endif$ }/ F! T2 g) T' Y. R) H' A
#if        0
, }5 \+ H4 H, `8 ~6 J" Y( U                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)4 k# A( Q3 h! q5 k# U, X) f
                {5 |) O$ s& B0 E( p
                INT        diff = abs(output-last_data);
7 r9 I9 M2 v2 B  j7 r. }5 H                if( diff > 0x4000 ) {
4 ^2 _6 t- K+ B0 U+ u8 k                        output /= 4;
* K5 B; q1 q, {9 {/ y3 G                } else
* `; j, C" V+ K3 _+ m) D                if( diff > 0x3000 ) {- U0 f3 h9 Z6 F: E3 I
                        output /= 3;8 @2 G3 i2 B  b( e1 v& F
                } else
- z# P4 X( o$ h+ k- b                if( diff > 0x2000 ) {3 b# G2 {  ^2 d& Z3 w1 f' e
                        output /= 2;8 E8 D+ M3 _  x* B
                }
6 b8 N- v( H8 A- J# M                last_data = output;
8 F# ~" y' ~7 e6 R                }
& M  P* V8 c% R3 C/ H#endif+ L5 c2 |4 o3 _1 `/ O! E8 Q' u# h2 F/ v
                // Limit# ^( T1 {8 c) R+ w
                if( output > 0x7FFF ) {
7 ^3 t( T/ ^3 e5 h+ u5 Q                        output = 0x7FFF;
' E# X% J/ j  w. X4 c; t                } else if( output < -0x8000 ) {+ z7 d$ q! N- l$ Q! L
                        output = -0x8000;0 {' V: i- l7 |" q  f/ k/ S
                }' G3 v5 w8 [' N5 {) l
' \, x/ H, ^; h( L4 k
                if( nBits != 8 ) {
; b# c1 H3 \5 s4 D                        *(SHORT*)lpBuffer = (SHORT)output;; v* K# G$ ]. V( O7 X
                        lpBuffer += sizeof(SHORT);
7 I/ N( t8 m. U6 \, O5 M8 b                } else {
2 @7 x1 B- Y7 [# m# t4 L                        *lpBuffer++ = (output>>8)^0x80;4 N  f3 E" H; N$ N! v
                }
; z; Z" f" ]2 U, P! p1 B
) T  _" F/ G5 ]: Q                if( nCcount < 0x0100 )
- j' p! d/ x1 k                        pSoundBuf[nCcount++] = (SHORT)output;- \8 H# U* ~# p# Y3 w2 L% U1 U

& E4 u( b1 L9 F# ^. X//                elapsedtime += cycle_rate;% g! k7 C! v0 h; Q3 ?
                elapsed_time += cycle_rate;1 Z, H7 i9 r( [2 R  K
        }
; v8 G$ i6 f$ J& M3 a
2 d/ p4 h& _' y6 \% [: L3 S# k5 X3 l1 b) ~#if        1
$ ^' v2 e# \+ i3 F2 _        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {% h% [. [& J! E' b
                elapsed_time = nes->cpu->GetTotalCycles();
7 U) ^8 r8 i' }5 l' p: k        }: D! v: J; z2 L5 D! }
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {9 D2 n0 X! S9 }+ ~. T6 O1 H, p6 w0 ^
                elapsed_time = nes->cpu->GetTotalCycles();
$ l4 l; K+ C# v6 o9 `) e5 y% V" B        }) N, g8 J; Z1 P. H! Z
#else  t% |6 j5 p$ J2 g  h( h( Y
        elapsed_time = nes->cpu->GetTotalCycles();
/ a+ K4 W. F& L4 K) k" g#endif) c- l" F& [( r1 w3 V
}- k" o% n! @( e9 M3 r

+ @& D" S+ m8 }- ]- B* U// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)/ U) y$ |! B: `8 s
INT        APU::GetChannelFrequency( INT no )
' l3 i( o2 D) `3 }; \{: ]3 b9 y( |( k2 h# ?
        if( !m_bMute[0] )# a0 Y( n5 c) p0 G, Y! C
                return        0;2 Y# g( Y, I7 B) |4 A* ?

7 |6 n4 S+ r# P. i2 Y        // Internal  V/ I; v0 e+ _3 O6 {% L! v  B" b
        if( no < 5 ) {
/ D$ c1 j( p9 I* c+ B                return        m_bMute[no+1]?internal.GetFreq( no ):0;" U, S, J  Z; c
        }2 ]* a3 g8 j# i  i2 l! X/ D
        // VRC6% R/ E/ `8 t7 O% m
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {& X7 V6 }1 C' j
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
4 ^( d5 F6 W$ J, `9 K        }
1 U; o! t# R- S4 O: W. [8 m        // FDS
6 {% D+ _( O0 Y# p        if( (exsound_select & 0x04) && no == 0x300 ) {! \5 p7 g, U2 s# z# d0 n, S; w
                return        m_bMute[6]?fds.GetFreq( 0 ):0;4 Z) t6 v! F+ e+ M% V
        }
+ C8 X+ T3 _+ v  o        // MMC5
# b5 y' f% d2 T6 S# v" |% o        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {/ N' U- d" l1 U% j$ B3 @; A. |
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;  h# R5 Y, w9 H0 {  y# g
        }: h; ~; `, B. u: [) p
        // N1067 D6 T6 p0 c7 R. Q9 Z
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
$ V; ]9 Z7 ]! }5 h                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;% b- Y; \& j) z( E) v4 y
        }
, J! c9 C4 B: m1 I1 j        // FME7
% f( S* O5 C' C% P. `% a3 M. T2 U        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
- w; ^" Y2 H# Q% q2 u9 L: U& }, x                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
' u' u, ]1 M8 C. A0 g% F        }7 G! G! h) l" T
        // VRC7( C% A4 G1 q& Y3 {1 B
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {- V* Y5 {5 m, L+ R' p+ o0 T1 C
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
" w# u; [* [( P* F3 T- H: q" Q        }
% P& m+ Z* a/ u0 F        return        0;* W$ {; e3 t' W; g: y4 J" [* L
}
$ o7 J/ Y7 f! E! S5 P- u- J9 T1 R6 a( b# K, P- ]
// State Save/Load6 V2 A: r9 J. w; S. R( Y
void        APU::SaveState( LPBYTE p )6 m% y, v, L. k, c8 T" G- {
{# \1 @' H8 u; {# e
#ifdef        _DEBUG/ G$ c; A/ D! x! A- E1 b
LPBYTE        pold = p;
5 L; s& w2 x* m- M% j1 g7 g9 Y  J#endif1 W$ e' A2 c; Z9 r0 O
- P" J! Z9 Z* j1 x6 e
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
7 t* ~. x" T( L% ~& ^7 G        QueueFlush();2 Q' _2 G+ a0 S, y# W& o0 \7 x
+ H: _3 L5 r# c9 r* I, B- f
        internal.SaveState( p );
  W8 N  t- v: ^# h% |        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
0 u% Z  [$ t& r! ]6 {# E0 f& ?6 G: }" m
        // VRC6, M) t/ X8 H5 ?$ K5 x
        if( exsound_select & 0x01 ) {
- @  a$ C8 {, Y. K+ B                vrc6.SaveState( p );3 K* b6 k; n2 `% d$ c, P5 X
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding/ \' v; @8 ~, L! c
        }
- F) E; H  k$ p$ b( U        // VRC7 (not support)
, @3 Z: C; |: t* B- \        if( exsound_select & 0x02 ) {
: T% M& |" t$ u1 s+ B$ f; d                vrc7.SaveState( p );+ ?* q9 T  N- M
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
5 x: R0 e. t/ x3 O' S        }. A/ @. _) F/ J+ b+ S) s
        // FDS
- L( [- n8 u/ ?) D& Z        if( exsound_select & 0x04 ) {* I( i6 ~4 m& R0 R& {) ?# @
                fds.SaveState( p );
& {$ P1 o2 n  R5 \; A& S                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding4 ?0 L# ]% H( m, Z9 S( w
        }$ T$ A* e3 y. Z6 V- u- j: O
        // MMC5
8 @( Y4 f5 Z9 I0 {! C- c        if( exsound_select & 0x08 ) {1 ~0 G; h, w# K2 h7 k7 I
                mmc5.SaveState( p );
! ]/ R! Z% W. ?1 P                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding+ V6 i* j6 b  i- v: f% L
        }1 {6 U9 e: B% T7 W' A1 p
        // N1065 N; A3 L2 `( P
        if( exsound_select & 0x10 ) {, |8 M- s  s& E& Z# R4 B
                n106.SaveState( p );
* l) T3 A, p  u$ t  A. t                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
% f3 M* d+ }3 _; T+ v) Z4 H        }0 ?# O* Z$ A! i  m, B1 u1 ^
        // FME7
; j% ]" s9 s7 b. W! A- V( F/ M' ?        if( exsound_select & 0x20 ) {
$ y* f+ m7 }) f" @8 u  K' Z$ H                fme7.SaveState( p );
  C5 D2 y5 o! f( i2 G                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding, T3 X! |$ M* |$ [% F
        }
8 e0 {( Z3 x2 q- e& q- Y1 t
5 U7 I0 N5 Z1 z6 @% s# |1 }#ifdef        _DEBUG
$ F0 @, K1 \3 j7 ?7 T% oDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
- p! W* m/ Y3 U5 {#endif
- o2 ]2 z$ k6 n: r* X: S}& @8 Z* w) q# J4 S* L$ e
% Y6 I- l! N" n2 [& q* B  a" ~* j6 u
void        APU::LoadState( LPBYTE p )- J, {9 y- D: C8 l7 v6 ?
{
9 B# D7 g' |0 K' c3 B        // 帪娫幉傪摨婜偝偣傞堊偵徚偡( Q  v: n4 y" J; N5 `
        QueueClear();
7 `% ^" q7 [# n/ X0 t! n; o
& R* C" Y) ^. |! A9 `' O        internal.LoadState( p );+ z4 G8 @& [5 J, I2 ]
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
% {% ]& U7 e* S! C& Y* E
' T3 p8 U1 z" h/ y; x9 x6 l        // VRC62 r% f7 d5 O1 A) P: X" z! v8 l
        if( exsound_select & 0x01 ) {
+ _8 i; ]9 p/ j7 w8 A! J                vrc6.LoadState( p );# s% X2 v5 g6 Y& ^# I: f
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding% R2 A2 ?1 V9 V
        }
! C% F! F, {% M" U! [: s6 G# v        // VRC7 (not support)
! A- z" ?/ }9 C7 ?9 e5 {        if( exsound_select & 0x02 ) {9 N, U5 h6 s' y. j% d2 o
                vrc7.LoadState( p );
* i9 V  @6 p! c                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding; K2 |! X5 c) N  w/ D/ {2 H2 \7 T
        }
; X* K8 m- J0 Y: N& B7 }( d: M        // FDS
! w6 n3 X+ g( a  R: `$ y2 n2 ~) l        if( exsound_select & 0x04 ) {( v. p4 V/ F! @
                fds.LoadState( p );1 |- e6 a1 U9 F* q/ q) ^$ T
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding* }' ?# |) v1 F! s+ @+ y5 x
        }
8 d, F8 H. k: i, ~, m        // MMC5
: E1 m0 Y# n, f9 z: m/ U1 h        if( exsound_select & 0x08 ) {
: Z1 R: X8 U  ]) I) Y% \5 _7 z                mmc5.LoadState( p );4 Y; b5 X) T- p3 V
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding0 p# }: F5 |- K
        }  e' o/ Z1 I# z0 C/ o& i
        // N1062 u) n, I! C9 W& o- x
        if( exsound_select & 0x10 ) {( y) B6 |" i0 ^3 k& W% G2 @0 w
                n106.LoadState( p );
! P/ E( P8 Z+ y9 ~                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding% M. _$ d: H& c8 T$ V
        }
6 C# R, z5 m0 S; @5 ?        // FME7# N" n9 a" q+ N6 O8 H; ?
        if( exsound_select & 0x20 ) {" ]) T& A% [  r/ [& Q( |/ t
                fme7.LoadState( p );
: q/ s1 n. A# p* p                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
7 Y1 p& u% l8 L3 V, X        }3 r+ x" ?) }& f' j" a
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
8 f5 ?1 D, M7 @可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。" s) @7 E7 |' F* s3 {# R
感激不尽~~

5 Z# e# k1 ]9 T恩 我對模擬器不是很有研究,
, z2 c% f: W6 q雖然要了解源碼內容,可能不是很困難,
( q" `+ X7 @( v8 ~6 [# f+ p不過還是要花時間,個人目前蠻忙碌的。
! W$ e( T) o* W$ |: V7 f  w# y% i6 Q  S$ _5 {2 Q
給你一個朋友的MSN,你可以跟他討論看看,5 _- ^4 l$ E# @3 E& d, `+ A
他本身是程式設計師,也對FC模擬器很有興趣。
% G  I2 Q9 ^4 k. \5 [8 t/ \0 k6 k4 A5 T' }; ]( k) J
MSN我就PM到你的信箱了。6 v, ^0 V1 k$ i
* X8 K' w7 d: e; w
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 9 q! t' u* J$ K, m/ G+ c
呵…… 谢过团长大人~~

  o& m' |$ |6 c
+ w  I4 {4 ~  H4 k0 }1 h哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 * E/ Q7 A2 e, O4 _+ l
团长的朋友都是神,那团长就是神的boss。
2 ~- J" F+ V8 e0 T) d- G' ?
哈 不敢當,我只是個平凡人,: U: L  ^$ f( G% D
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
4 [; L4 w! Y5 f* q. l/ _  K  |; G  S& \ZYH4 `. g7 V$ s% ]) O
QQ:414734306
2 G2 P4 N! B% f/ Q! j; V% L4 b7 pMail:zyh-01@126.com
( p( C. I) @. v9 {8 U) w0 w0 p
' e  d; o7 M  _: S+ F* E他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
5 W: ~( c1 l& k# J3 x9 R再次对团长大人和悠悠哥的无私帮助表示感谢~~
! m5 G* v1 r6 V3 j* Q0 U2 k
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-11-30 14:43 , Processed in 1.098633 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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