设为首页收藏本站

EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
8 L) @5 P0 P( c) }6 m8 K楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
1 O: n* O0 K9 q7 d0 y# Y; V这里有相应的模拟器源码,就当送给大侠了~~
9 B" A* Q3 ?! O1 Y5 Dhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 * Z6 q( l8 O$ a( H3 s
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
8 ~. X6 F2 v( u2 b$ Z5 Q2 D楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
% T4 q3 E) a! C这里有相应的模拟器源码,就当送给大侠 ...

* \. N6 v! o  e$ R8 Q1 K' d  t聲音部分(Audoi Process Unit = APU):' l7 G( J" K2 [
.\NES\APU.cpp( U' h* O8 V' T( R
.\NES\APU.h: o1 r) C- \0 }7 t" P8 m
' F1 E0 b0 e/ W( Z" Q- a8 d; x

7 F& u3 h0 d0 Q. d7 h2 z影像處理部份(Picture Processing Unit = PPU):
& Y/ X) z1 x( o, `7 U.\NES\PPU.cpp! ]. x2 d6 H! C1 N- @
.\NES\PPU.h
3 v+ @4 ^! |8 ~
- C9 ?! r, k( ]# C! a如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:" z4 o. P  J5 B3 a
(由于很多专用术语和算法机理都不明白,所以看不大懂……)9 Y, c$ q* W$ z# `8 b
//////////////////////////////////////////////////////////////////////////5 p& q* f. f- C5 x- `
//                                                                      //: D3 e! d9 a2 K) P7 p
//      NES APU core                                                    //, K$ O9 Y6 `2 t" C7 E9 u1 ]2 X
//                                                           Norix      //
( G8 [5 H& Y2 `$ c8 t* z/ ^+ \//                                               written     2002/06/27 //. ]& K+ O6 c- B. [7 R% @6 c0 y
//                                               last modify ----/--/-- //4 q3 l2 J" X, R$ R4 j
//////////////////////////////////////////////////////////////////////////6 A6 X- P' P6 V7 B4 e) K
#include "DebugOut.h": W; {- _+ g) v
#include "App.h"; n' X- p) o+ u6 z1 b- ?3 s
#include "Config.h"
2 @7 ^0 W. E3 c: q; f3 |8 m7 M7 F, U0 v2 X* V6 A5 x- N2 [
#include "nes.h": ^+ q6 Z. D+ w' C# h
#include "mmu.h"& @: ~' O$ F6 h! Q
#include "cpu.h"
/ _& m* k( C1 B' n% M& G#include "ppu.h"
  c9 u1 e, M+ r; y$ f#include "rom.h"
4 N: |2 M5 n  g5 R5 ?" z#include "apu.h"
/ V" ~' D4 z5 |$ |, a8 G+ p' v% _' g
// Volume adjust8 G9 c8 W5 @$ S3 ^* q
// Internal sounds
& G+ |4 x: v6 |8 f) h) ^#define        RECTANGLE_VOL        (0x0F0)
/ V- p% [' A* `#define        TRIANGLE_VOL        (0x130)
; q8 Y" A; D5 f$ V: S% A$ y#define        NOISE_VOL        (0x0C0)4 F2 y: X6 p/ F2 u/ a. }6 P  h8 F
#define        DPCM_VOL        (0x0F0)' w% `6 T0 E  c" B$ N& N/ }  g' M
// Extra sounds$ O" K2 h! I* Z
#define        VRC6_VOL        (0x0F0)
  J7 O( \- z  N- i, [#define        VRC7_VOL        (0x130)
( J( @6 N. \4 n7 Q2 W$ Z0 |#define        FDS_VOL                (0x0F0)$ z. Z' z2 `$ [9 J
#define        MMC5_VOL        (0x0F0)1 S) _2 s% k5 L0 i
#define        N106_VOL        (0x088)
$ s! R; B' \' p9 A7 J  f4 E#define        FME7_VOL        (0x130)
# w' i9 D( W- U: f" o+ S; T1 j- [% ^
( ^, K$ i. m' |* k' C1 ?3 W3 AAPU::APU( NES* parent )
; d( T( r  a/ Y% B, {{
4 ?4 F' {: I. E# i# w5 t. h        exsound_select = 0;! [1 r5 N7 C' _6 o% F
6 C" T* D' Y, e1 h+ a) r  q
        nes = parent;5 o% h) s" ^4 u3 z: n
        internal.SetParent( parent );
" A3 @; k/ U6 v5 B1 v$ Z, H9 E8 }( C
        last_data = last_diff = 0;
' W) B. U0 }5 U
7 n3 j5 y0 w: l        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );- S( M) m% A9 M2 g! K; u/ W

0 k* a: `& t2 j4 L( n        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
! \! r6 ^7 m, z; x        ZEROMEMORY( &queue, sizeof(queue) );
  e! Q2 C0 e2 V' d        ZEROMEMORY( &exqueue, sizeof(exqueue) );3 F% H& W2 z1 r7 W( n. [) T

( O/ v6 E* x9 t        for( INT i = 0; i < 16; i++ ) {3 d4 G  e/ p- [# D
                m_bMute = TRUE;# P: A4 t& X; h/ H6 W: V3 P
        }+ H5 H6 }- B0 ^1 i8 ^' f
}
! q/ q& x: N1 X  ^* j# w8 Q( \4 ]: g0 T0 z/ e
APU::~APU()% d+ O$ U: a# {" \# q% z
{
3 s0 x: c& P5 h% S}
0 \$ j# y" q- d! d* z* @1 o, i
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
; ?: {. \) F+ }  g  I+ ~{
3 @3 e/ A8 ]1 q% z        queue.data[queue.wrptr].time = writetime;
4 _& t1 c' b, t9 }0 B- e        queue.data[queue.wrptr].addr = addr;& e* I. X- w" u6 ~% j" \
        queue.data[queue.wrptr].data = data;5 ^2 `, ]# d3 `" b( w" z. r
        queue.wrptr++;* Y3 h/ s$ C  C
        queue.wrptr&=QUEUE_LENGTH-1;7 S4 @9 ^0 k  o9 g
        if( queue.wrptr == queue.rdptr ) {
, t$ j8 ^# B* Y0 f  Z' _3 }                DEBUGOUT( "queue overflow.\n" );: i1 k* ?) D5 C
        }
5 }2 t2 I/ }6 ~/ h& _4 W}
/ E0 |1 H* o; p
, Q" ~3 V, f# RBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )5 W  S" t2 u  V! D$ F
{+ A  ^) ?$ v3 }% e- i
        if( queue.wrptr == queue.rdptr ) {
# s# x  Y* E% W9 q) }/ q                return        FALSE;
4 U# O  |6 v3 C2 r/ `        }
; O6 |0 k% Z# d; o' j" S        if( queue.data[queue.rdptr].time <= writetime ) {  U& v5 s$ }% }5 G; Z
                ret = queue.data[queue.rdptr];! I1 I4 J: B0 D! E- V- Z
                queue.rdptr++;3 K" z, T3 p: C  u7 S7 n" Z
                queue.rdptr&=QUEUE_LENGTH-1;8 n" m! h$ v( Y% _* r. [4 H/ @- [
                return        TRUE;
' g/ U% ?/ T% ?        }& \. }/ E5 ^2 Y+ I5 [2 G
        return        FALSE;
( i( h* p" f* M, U5 F}, q# j* ]  H+ s* r

( x" Q# S: l2 Gvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )6 q" k3 ^' F& b; S% l$ R5 R
{2 H/ ~" p7 ]9 r
        exqueue.data[exqueue.wrptr].time = writetime;, _" J7 r9 H  F) ]; t4 t" f4 v! ^' q
        exqueue.data[exqueue.wrptr].addr = addr;
' E! ?/ L% W1 x$ x4 m        exqueue.data[exqueue.wrptr].data = data;
, y0 n4 {4 s1 f) o* N: B+ ?        exqueue.wrptr++;1 a& k  T; ^5 e, V# }1 E- e
        exqueue.wrptr&=QUEUE_LENGTH-1;( H! L0 B. k$ u" u
        if( exqueue.wrptr == exqueue.rdptr ) {# |: [4 I) [  y
                DEBUGOUT( "exqueue overflow.\n" );6 W" K$ ?& [( d6 S4 i' B1 i
        }
: F* R/ B$ B# P$ v5 ?; A1 r0 d) `}
+ a; f0 M) ^! e6 y0 R3 [
2 f, {8 a# t0 {; JBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )3 }; n, g0 ^# Q; C9 z- N
{" V/ y2 Z* g; @; A5 [( m1 B, T
        if( exqueue.wrptr == exqueue.rdptr ) {
* w  `% a7 ~+ F/ K; j; u                return        FALSE;
& @( Z. V5 {. Y9 W& ]1 q. [        }; M4 F' z3 L2 r2 c' e: F: R
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
5 l0 U3 L8 x1 U0 Y, x                ret = exqueue.data[exqueue.rdptr];6 R9 @  \* E) u6 T
                exqueue.rdptr++;/ ~0 k- `% r+ \0 ?5 D+ M5 ^
                exqueue.rdptr&=QUEUE_LENGTH-1;9 Z  g# }* ]7 a$ f" o4 w. K" C# v
                return        TRUE;1 i' B* b/ t' z3 v. q$ V
        }
1 U! v/ @8 `( B3 l* F- |        return        FALSE;3 [/ b# o4 H7 Z# `6 L% ?6 q1 `, b4 j, b
}) |) o! k, a. d0 Q. P6 e+ E) b; X
! b# @! [1 }* V5 P& r
void        APU::QueueClear()/ F' I% _3 x, |1 `
{
* T4 U6 p3 N7 d( Q1 K7 G. s0 B        ZEROMEMORY( &queue, sizeof(queue) );8 [" ?: q8 z; W7 s% R$ O
        ZEROMEMORY( &exqueue, sizeof(exqueue) );9 N) V: [, c  Y' }
}
; l4 b; Z; I+ u2 C/ v( V
! I8 [/ b' Q* [' v3 o$ u9 F" _void        APU::QueueFlush()/ q3 f: ?0 M! ]) S6 z: P' B7 u
{
5 P# V3 Z1 B' U" i- a7 X        while( queue.wrptr != queue.rdptr ) {5 ~1 I: \4 D5 `- J
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );1 U( ]2 N( g3 u$ v4 Z$ [
                queue.rdptr++;& h1 W+ n% I4 n3 J/ r% I
                queue.rdptr&=QUEUE_LENGTH-1;$ t2 J, D' j, s0 c0 F. u
        }1 v) G8 g/ [" \2 ~* `0 ?9 a! q- \2 }

% j0 {2 B# X+ B! V+ {* H) D) h        while( exqueue.wrptr != exqueue.rdptr ) {
0 s# Y0 f* K. C( ^' _6 Q                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );! D) H: q8 w+ K  C- [5 a
                exqueue.rdptr++;7 L/ e8 M* A& V* P
                exqueue.rdptr&=QUEUE_LENGTH-1;9 }; I9 R; C7 L3 c/ T
        }! N* M3 l1 R0 f2 {! {
}
% f; q2 d+ r7 P& t! h# N0 y+ P2 }, b) h! {: M: y
void        APU::SoundSetup()7 F4 z) l: v1 S' i( w# @
{* a  n3 r4 M) @0 B6 s
        FLOAT        fClock = nes->nescfg->CpuClock;
7 `& X& S5 Z- E1 H& @6 @! l        INT        nRate = (INT)Config.sound.nRate;
0 e9 X6 ~3 K6 @0 i        internal.Setup( fClock, nRate );
' A  @& T$ y# U0 Q, x: e/ l        vrc6.Setup( fClock, nRate );
+ n8 t, D/ ?" H$ t* J9 G        vrc7.Setup( fClock, nRate );
7 R# {7 C/ f% g  B        mmc5.Setup( fClock, nRate );
5 w! e% P- B( F! `1 W  [) K4 I5 e2 [        fds.Setup ( fClock, nRate );
* c. L. ?- \( Z        n106.Setup( fClock, nRate );8 h9 [* n9 Z. X9 f$ D1 [
        fme7.Setup( fClock, nRate );+ l5 T4 V0 c. r7 o6 R; i/ n
}, O% p# C$ ^0 a8 C! L
" |5 R8 `: X2 m
void        APU::Reset()! l, N5 R6 v9 C4 E
{
% ~) x+ K* o9 \: s) ~        ZEROMEMORY( &queue, sizeof(queue) );
  s+ |- Y% H6 ~" k, P: s        ZEROMEMORY( &exqueue, sizeof(exqueue) );- f. T! V. n1 H1 V" _3 r

7 o( r4 j5 A, G        elapsed_time = 0;
$ H+ ]& s5 U" y3 x! c; r" S/ z+ a7 d5 |" Y5 T! s2 p0 S/ F
        FLOAT        fClock = nes->nescfg->CpuClock;
$ r! l( Y5 L1 F* i" ?  Y        INT        nRate = (INT)Config.sound.nRate;
3 b$ e, t, X; ?& n        internal.Reset( fClock, nRate );1 l: b1 }; f  P- j6 i# v5 p% V
        vrc6.Reset( fClock, nRate );
6 ~; n# C/ l6 A6 N8 D0 Y! [3 U8 r5 w        vrc7.Reset( fClock, nRate );
6 h! d6 `/ L6 P# x        mmc5.Reset( fClock, nRate );# ?( I2 k7 @9 o/ _3 `* @9 {
        fds.Reset ( fClock, nRate );
+ [7 F4 m: N9 Z/ s/ |0 {: F# l! u' J        n106.Reset( fClock, nRate );8 }: ^- s3 Z/ Q) T8 q
        fme7.Reset( fClock, nRate );
! Y) o% L# W# I: j5 x0 J  R4 Q! M, D+ L4 l# j9 t
        SoundSetup();
. d6 a9 K9 }8 p# w0 S- D& ]' [* o- b; w}, d) @$ ^' b' m' `; q

5 x) e) c* h8 S1 F2 F( }; k9 Ivoid        APU::SelectExSound( BYTE data )
' o! F4 H; E& [2 r1 x  |. `' V{2 u( C( n4 k& u) R/ w% Z* i
        exsound_select = data;7 f* g2 ]$ m; n) ^
}
) [4 l6 F# [1 I" o5 Z# F* V4 J
# |6 {; e# M4 d' S0 p2 @4 }' {BYTE        APU::Read( WORD addr )" M& k: V: v! l% g
{
$ ]  ^" q/ f" [2 U& w        return        internal.SyncRead( addr );
' _4 n1 M  l: o+ n/ L4 L}5 H& x1 Z+ c2 T5 j' O( f  P+ V7 k& Y
! g+ w% \. ?, `  h" [( a
void        APU::Write( WORD addr, BYTE data )
  E* A6 Q" P, n- R{, d6 d3 G( c, v1 j' @  e$ a
        // $4018偼VirtuaNES屌桳億乕僩( p+ B2 `0 Y, U6 s: [
        if( addr >= 0x4000 && addr <= 0x401F ) {' {8 ~' K* J1 ^2 F
                internal.SyncWrite( addr, data );8 q; y% `2 T$ B" M0 J5 z) P
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );/ j( o2 S, ~% w) P4 Q
        }- m! U4 a; Z& a4 N! I( N
}# D' h4 ~) }5 G, c* y+ s
3 z7 c8 J' l7 J: z6 ~+ }% x3 j
BYTE        APU::ExRead( WORD addr )
: a" ~7 E! @2 Q7 S% I: o{
3 `& h2 b) _0 x" p/ sBYTE        data = 0;
0 x. S( z- P- `) q" N) N: w1 k; s
        if( exsound_select & 0x10 ) {
9 z+ v6 J9 M' v                if( addr == 0x4800 ) {
3 u. E' @+ s5 Y4 R7 C, M7 S                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );5 I# k0 n1 @, n4 h
                }/ [7 Q3 d1 ]7 d. `
        }: z7 d, Z) E! p% O+ m
        if( exsound_select & 0x04 ) {/ F' x- P0 x9 g+ Y
                if( addr >= 0x4040 && addr < 0x4100 ) {
' r. s4 T- a# t7 p5 q( H                        data = fds.SyncRead( addr );0 ?& U) a: r& I' _% M3 y% b
                }
' ^! U# w) Z9 s& g  [- m/ O  m        }' V* o7 g, W& m* L, V- L
        if( exsound_select & 0x08 ) {
  z2 B' k# ~' f. G                if( addr >= 0x5000 && addr <= 0x5015 ) {! h& w. n2 f4 S0 i
                        data = mmc5.SyncRead( addr );# R$ s& b( B& H& P
                }
6 ~0 M1 c4 ^7 S" k2 h5 O        }
7 V6 ~$ n7 U' V9 j$ I* r/ g! Y9 h: x2 A  f9 `6 g8 z' \
        return        data;# I% N0 C  O& ^$ Q
}* y8 Y' c, I" a" C. K

9 e' q% C; ~1 y: q+ ovoid        APU::ExWrite( WORD addr, BYTE data )
( ]- L8 F  r$ k* N" C" u{
) a8 ]# D: P2 O, l3 F! p7 @        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
! n# o! y8 I0 m" z) L7 d: s7 I9 H" G% P! _( u0 D( J9 l; N& p1 `/ A
        if( exsound_select & 0x04 ) {
; C+ l6 L+ U0 ?; |8 d, c+ Q                if( addr >= 0x4040 && addr < 0x4100 ) {8 `! e( O# J* h+ J1 b
                        fds.SyncWrite( addr, data );
- [. H# ]7 k- Y- o                }
" h2 R) Y0 c* n$ r        }, {8 V6 I  H, K9 q& [4 A! E
- _4 V, C* f4 b: N+ J( G
        if( exsound_select & 0x08 ) {
/ I; t* M% j5 F% V: u0 w( Z                if( addr >= 0x5000 && addr <= 0x5015 ) {
8 k% P. b" ?4 S) s                        mmc5.SyncWrite( addr, data );
- {1 F+ l5 x% \9 J. y5 G5 g; H                }) ~9 w4 B5 t3 Z/ w! g% d$ A7 C
        }9 w6 _" r, |7 b9 T% F+ Z
}
5 r/ H6 b/ _6 H) C! m' B6 |5 X
2 |% h  _# F2 n1 i/ E9 C% J! rvoid        APU::Sync()
& c! E/ i; O3 ~+ ]/ |+ w{
- H$ c/ c5 N+ i! y) p/ e}
/ h7 ?2 b$ R1 e" f% \- H) b" k, g& N$ b
void        APU::SyncDPCM( INT cycles )
$ m' ?# @  I& b5 X9 p{
) \5 Y' u4 x" ~0 I' E* R2 r6 E        internal.Sync( cycles );
* B7 f# }8 x4 X- o$ I7 U( u7 K
/ b! Q1 u+ {) E        if( exsound_select & 0x04 ) {
$ E5 T: [: ?" q                fds.Sync( cycles );) P% q. ^3 Y4 O- h" }! \, \% t
        }
- A; C& m0 ~6 U# V7 D) s1 |% h# {        if( exsound_select & 0x08 ) {
( s7 Z% S" m1 J4 O2 R* O! @                mmc5.Sync( cycles );
) f7 @. a2 _: Y" N        }" y& l& j0 d5 Q
}0 r( \2 e" y( B( o% D# i

. x2 C: F, ?" qvoid        APU::WriteProcess( WORD addr, BYTE data )5 G" c, J0 v3 N
{
( r3 ?/ ^1 K! p7 F        // $4018偼VirtuaNES屌桳億乕僩
- \7 X& H  e% ?        if( addr >= 0x4000 && addr <= 0x401F ) {3 D4 B/ l$ X; S4 T
                internal.Write( addr, data );
( o5 \' U* e) T        }: Y, i3 Z+ M9 Z+ w
}5 ^6 `$ r6 ?5 a& ^8 e/ A, y

$ G. M, a2 j. E, n. A# X% qvoid        APU::WriteExProcess( WORD addr, BYTE data )) n( M9 A; f: y; z/ z; F; G3 I0 b
{9 s( `( c& ]  D$ O
        if( exsound_select & 0x01 ) {3 [2 w6 H+ ^# [& {
                vrc6.Write( addr, data );
5 `8 |8 B4 v: P( G; g        }. Z, ?) Y6 h6 \0 F# Q8 l' q* Q/ S. X
        if( exsound_select & 0x02 ) {. H5 S3 f, f1 ^3 A% ?* D
                vrc7.Write( addr, data );' s4 R2 m1 F* k* j. N
        }
6 }6 Y( ]! z: M* R* Q        if( exsound_select & 0x04 ) {2 Y( M3 b, [9 ^- [9 v' x+ o
                fds.Write( addr, data );
2 ?. c# O( Z4 K7 s1 e        }
: ?7 u1 d/ w' q+ r        if( exsound_select & 0x08 ) {- I% H" y$ C% I4 ?! p9 C
                mmc5.Write( addr, data );1 B% I7 q7 \% g( D* b' c/ x! ]8 z) K, B
        }) r5 _) g" b0 O6 C/ a
        if( exsound_select & 0x10 ) {
9 V/ x* U5 a  A3 c                if( addr == 0x0000 ) {" m) d1 Y9 h- _; _+ o
                        BYTE        dummy = n106.Read( addr );
( V# i6 Q6 q) p$ ~) K; i                } else {; e+ X; z& {0 `5 ?# i
                        n106.Write( addr, data );9 x8 F0 r/ {3 P
                }! n: A+ c1 ]; x6 W7 Y$ r
        }5 O) J& V8 N1 C7 U: Z
        if( exsound_select & 0x20 ) {
& a* X: ~9 o; I- W6 [9 P+ P                fme7.Write( addr, data );5 r. H) p* p5 k  D* k$ ?# e* E
        }) L- u/ x( [; ~
}& Q! E6 [! h# X7 u$ o

) }9 X. C7 z7 K( q1 J8 @void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
' p( n; l% E9 C% R: U9 s# s{9 Q: j$ |1 {: m# Z  t- N7 y
INT        nBits = Config.sound.nBits;
: u- t8 H+ v0 Q: w  w4 c4 b9 [3 \DWORD        dwLength = dwSize / (nBits/8);
/ t9 e( U* R7 N! W8 lINT        output;7 A" a( E6 W: M/ W
QUEUEDATA q;' D9 u, I" J- Y2 J
DWORD        writetime;
3 V( G9 P/ _% }4 |/ ~/ I: o0 i9 y$ e5 a% l2 \
LPSHORT        pSoundBuf = m_SoundBuffer;+ H! U) K. A, V2 @( o
INT        nCcount = 0;) c/ O( S9 V0 Q2 a% t
  }5 d0 Q+ I9 c4 h& g
INT        nFilterType = Config.sound.nFilterType;
: A  [% p) E# l
+ K( b0 E0 s! U2 V7 D" r2 A        if( !Config.sound.bEnable ) {( C7 N0 @) y) f) j7 G, x: {
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );; Y& h, M1 ^; ]1 ]* I( g; @
                return;2 T( W! G8 F( B( r
        }4 \8 H0 i" v8 V
, \( X2 t+ j4 z; X# y8 E/ \, J
        // Volume setup
" O% q. |: a) K" _4 {" {# J        //  0:Master
" O/ G' ]3 U# w        //  1:Rectangle 19 B& {; Z) G2 p' F
        //  2:Rectangle 27 i, A* A$ i* E
        //  3:Triangle5 [& C3 F9 Q0 n  j
        //  4:Noise9 K8 V* ], M2 q, e' {
        //  5:DPCM
& @3 g& {6 [8 I7 V0 h3 C2 {        //  6:VRC6; s4 W0 p% h7 O7 p2 e$ J. p
        //  7:VRC7- m7 F1 T2 a* B/ x
        //  8:FDS
+ c3 Q: M, \2 G' V; o        //  9:MMC5
6 X* g" l5 N) H        // 10:N106& \" ^& D% D1 x
        // 11:FME7; ^" I) c% O+ N/ N. q4 |4 M0 u
        INT        vol[24];
: w, @2 L7 o3 A( z        BOOL*        bMute = m_bMute;
& k5 h# a+ s4 O$ B: E: a4 C        SHORT*        nVolume = Config.sound.nVolume;5 u* {9 v1 s6 N, D
8 H* }, z0 x4 Z5 ^7 O! X" p
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
4 r' Y  {2 m5 D' w* g2 t: S: z4 Z% U( C" c- x
        // Internal% E) ?$ S& l/ Y! f, g
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;- M8 c% ~) z( [( F* }! d6 S
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;4 w; G% Q# K! O- p& L1 D% ?
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
/ M9 Z2 [& y1 g        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
4 x+ ~' b1 X, Q/ L- n; t3 A        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
0 ]+ _. s4 y' m" e5 q) a1 R2 I5 Z6 w) W$ s1 m
        // VRC6
$ g4 h& h! D' I2 ?% ?        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
4 {: S% Q! u" B, H' r9 f" I; ]        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;" p# A! ^- K; _" ]
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
1 w' T9 a$ D: \7 H  q+ s- s; C4 s2 _
        // VRC7
$ E8 q/ Z! W7 v; r, W4 C% `, \        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
$ W0 [1 J' q3 c4 m/ K/ o; y, h; M4 E; _! q) _
        // FDS$ T  V  k% v  N) f8 l
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
1 F" ~4 v, l$ Y& L! n! A& ~! k5 G+ p: x: R; j9 o
        // MMC5
! R6 S+ R4 A- {7 e& P        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;: }  k# r3 b- e
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
7 ~) U1 m5 N5 O  J9 O5 r% C4 \        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
5 ~3 z# f. y5 M# `. [* R" \8 E
$ x1 ~6 g2 C/ [2 C. X5 v        // N1065 d# b% ]  d* R
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- y$ N' c5 G% V* C        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
2 @7 U; b# X7 d/ ~2 v        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- h& N8 X% ?5 w6 w0 j        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ x% ]& o8 _3 R! s8 r* Z. C
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;( `+ u- f# M# b
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
9 b* U: L5 X7 H: f0 U        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;! \% M% m6 |4 W, v* f
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
5 o2 P2 Z0 b8 W( R+ i; c$ d' A" g
0 g2 k1 z2 g3 y2 a% G& N        // FME7; T$ |* {& ^! ^; s. a
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;4 V1 D: g' ~# I) f  m
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;1 a8 V2 J( C$ P! |8 D. |
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
+ a2 W8 Z. o! D/ `- t5 {3 b
/ f5 u. b0 K) q8 u7 N) M; H' q, A//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
2 r2 ?4 n4 Q1 _$ V        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
' ?# {* T+ O- v9 u. x" R" i
8 Z5 ]" V* D( m0 f. a8 L% ?8 ]        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
/ h3 S- A  y0 x  l5 _9 n+ \8 ?        if( elapsed_time > nes->cpu->GetTotalCycles() ) {1 W0 U6 A- y0 o7 c% V
                QueueFlush();
) g2 W% U0 x( p1 M( r( }  _        }
* W! j7 n" ~; ^9 C4 n& J# a  }, `% k, I( `# o7 J2 N. B
        while( dwLength-- ) {
9 W8 E9 k) l* L5 O1 G                writetime = (DWORD)elapsed_time;5 _: S: h! S; S# Q9 ?9 @6 q3 a

) M) M( x2 U, `7 o                while( GetQueue( writetime, q ) ) {, J6 k+ I: ^7 T* B; D. L+ C
                        WriteProcess( q.addr, q.data );0 ^+ M. Y! l2 N1 {- y
                }& r7 S0 n6 a$ t0 Z
9 q, v4 [; `& N, A
                while( GetExQueue( writetime, q ) ) {% R0 i/ g+ r  v0 A: f9 @* K
                        WriteExProcess( q.addr, q.data );! K* [, Y! U/ _: p0 @
                }
1 T  ^3 Q* Z, R# R  K" A2 c1 P+ f5 G
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
0 G/ }- {( k6 K' g                output = 0;* i/ v. \' G' o0 j. K
                output += internal.Process( 0 )*vol[0];
3 v" n. [( G$ f! d7 S7 c                output += internal.Process( 1 )*vol[1];$ D; n6 r5 V( Y4 P6 V* s( g* X1 |
                output += internal.Process( 2 )*vol[2];
: j4 U$ f9 Z1 o4 ]                output += internal.Process( 3 )*vol[3];
/ _5 t% n2 v) b+ J8 `% v; X                output += internal.Process( 4 )*vol[4];7 D  J$ m4 X8 C$ ]* K- x/ Q8 [
& u. {3 e1 r5 E9 [7 _" e
                if( exsound_select & 0x01 ) {
0 \9 Z; U* A& L& ^( a8 G3 h! I' ~+ Z! ]                        output += vrc6.Process( 0 )*vol[5];
1 _' c! [8 K5 r                        output += vrc6.Process( 1 )*vol[6];
  j8 }7 Z, w& M; X2 @                        output += vrc6.Process( 2 )*vol[7];+ `% `* t1 R0 Y# c1 |. `
                }
* P2 {5 ^! y6 l' s                if( exsound_select & 0x02 ) {
7 G% l& U3 q' n/ f* `" \                        output += vrc7.Process( 0 )*vol[8];( X5 `) E- e: C. s! {
                }2 G* s: D- f% O5 ~0 j+ \
                if( exsound_select & 0x04 ) {
# H" A  l$ q' O% X+ Y                        output += fds.Process( 0 )*vol[9];
' ]4 i( m% @" K' X                }, x1 n8 T  _* k4 p' T- J! N$ D9 h' _
                if( exsound_select & 0x08 ) {# Z8 r. j$ p" ]  Q' h- t- \5 d
                        output += mmc5.Process( 0 )*vol[10];
4 [4 _2 l6 A0 o                        output += mmc5.Process( 1 )*vol[11];
7 |6 v! o8 a! g2 N1 w                        output += mmc5.Process( 2 )*vol[12];
$ u' S- y5 h6 [1 l                }4 @+ w: W' ?3 z8 u
                if( exsound_select & 0x10 ) {3 ~5 r2 w) T, ]" x$ ]
                        output += n106.Process( 0 )*vol[13];+ J) P* Q. Z; d, g1 X5 F, }
                        output += n106.Process( 1 )*vol[14];, w6 k8 G! x6 |+ Q$ Q1 V2 Q) J
                        output += n106.Process( 2 )*vol[15];
6 e( |& S7 p# j                        output += n106.Process( 3 )*vol[16];
2 X! u2 x: Y2 F' M/ g' s                        output += n106.Process( 4 )*vol[17];
  _$ o/ s! \$ v                        output += n106.Process( 5 )*vol[18];# n4 Q6 \. l# X& R1 a
                        output += n106.Process( 6 )*vol[19];
* g# a2 P. q$ e" w                        output += n106.Process( 7 )*vol[20];
& I8 L- m9 J7 w" B                }, ^; c3 C2 F4 e4 ?
                if( exsound_select & 0x20 ) {! E- m7 q' z6 z* o0 u
                        fme7.Process( 3 );        // Envelope & Noise
( ^9 U5 K5 ]8 t, p. Q8 v, G1 O                        output += fme7.Process( 0 )*vol[21];# W/ d. F! y. v. _  g
                        output += fme7.Process( 1 )*vol[22];4 y+ O4 _+ f4 o
                        output += fme7.Process( 2 )*vol[23];- s& F: E0 `$ @3 G- ]8 V! }9 N
                }* ?; ^! n4 O2 P8 U! D, q

& A3 J$ e. g( V3 o% N                output >>= 8;
# g% ]1 |4 ~6 K  E% D4 n% m3 b6 A* ^( A' T3 L
                if( nFilterType == 1 ) {
  j( X6 a1 p% `# r: X                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
* w" Y( S% B5 J8 s4 H                        output = (lowpass_filter[0]+output)/2;
- I% Z; O9 r, @* f1 R                        lowpass_filter[0] = output;
/ l& g# g$ V: [; A6 D8 i                } else if( nFilterType == 2 ) {8 z- T! h  w( s( i
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)0 G' Y5 T5 ?& r
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;5 K8 M* u4 B$ Y! s! E
                        lowpass_filter[1] = lowpass_filter[0];* s/ I: |! _- M3 h
                        lowpass_filter[0] = output;- S- ~) A+ @3 Q5 z
                } else if( nFilterType == 3 ) {, |( B4 ~$ i" Z0 p8 \- B7 l
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
2 H0 D2 X% Z$ i0 L7 Z, h                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;* K1 B$ C3 q7 d! ~1 T' w( j
                        lowpass_filter[2] = lowpass_filter[1];
5 l: n& I5 ~5 H0 I                        lowpass_filter[1] = lowpass_filter[0];
$ _/ Y( C' g: Z, @                        lowpass_filter[0] = output;
! {" s) `- H; p; T+ R9 Z; n                } else if( nFilterType == 4 ) {" T9 M  e  c1 D
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
. z0 P( i6 j* y. U                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
& C) L, ^0 d$ A% C9 _) Z+ L                        lowpass_filter[1] = lowpass_filter[0];
; ]" f; ]+ ~5 u# h" \0 m                        lowpass_filter[0] = output;% W: `. R7 t* d- I/ {
                }
2 s" C) F% ]  q) ]
7 n' T6 G8 \$ s/ Y) @5 O$ F6 y) M#if        0! v  a5 M4 e9 w- r$ p
                // DC惉暘偺僇僢僩, e5 a" C4 R( C7 U# H% q% L4 Y
                {0 D/ b% d3 b& M& l6 o
                static double ave = 0.0, max=0.0, min=0.0;6 a6 o8 \. @6 u0 \& A0 \) c
                double delta;" K  @9 {% W. p& ~, a
                delta = (max-min)/32768.0;
7 X+ G' R+ e  e- v5 o                max -= delta;6 I( r0 m9 b* p# K3 ^0 C" `+ c
                min += delta;
7 F) w: ~! b2 \6 v, J% O0 C                if( output > max ) max = output;  z: P! f2 ^- {/ n3 }
                if( output < min ) min = output;( J. R) j3 Z2 w' ~. N7 n* z! F
                ave -= ave/1024.0;6 c' z6 ?4 E- C$ E$ k5 g9 j% B) f
                ave += (max+min)/2048.0;3 k2 ?- d8 ^& f: H
                output -= (INT)ave;7 [* {! u$ x& L3 j6 \
                }9 g+ e$ {8 G6 p& I2 V7 s2 D  l
#endif
/ D- I! p/ f  n3 D; [* _+ u#if        1/ g% h% m! [6 Z* N+ m. W" J
                // DC惉暘偺僇僢僩(HPF TEST)! f' {1 J* }! A. Y& k+ [
                {; n" R/ ?' a9 {, m# ]2 v
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
3 L7 t1 c/ v  f$ P' R3 R% m% b1 I9 K                static        double        cutofftemp = (2.0*3.141592653579*40.0);6 X5 I7 T% j, K0 {! G
                double        cutoff = cutofftemp/(double)Config.sound.nRate;  S! `4 _2 T2 ~5 f* t: p8 V
                static        double        tmp = 0.0;
4 F- h7 O# S+ ^) L5 y9 T0 X                double        in, out;
8 m9 g* H5 k+ X8 a2 n! b) Q% N. ?# `  ?
                in = (double)output;
8 U3 ?6 \* E* a" i- a9 Y" a                out = (in - tmp);9 @' g1 D+ t6 l& r7 b# p7 p
                tmp = tmp + cutoff * out;& o% E3 ?/ Z3 D9 M

7 t8 h4 e: @  z& k! e                output = (INT)out;
3 }5 \. ^& ]8 h* Y                }
. ]7 X$ @- `) e$ J+ e! E#endif
, k1 t; D  M) [0 ^/ h7 `) {#if        0
# g9 }& r8 Y* T$ _                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
$ R8 w3 x9 r$ P  J. G2 i                {
" f0 F8 D% S8 E8 w1 v  U                INT        diff = abs(output-last_data);
) L0 b6 k$ e' Z$ L  ?                if( diff > 0x4000 ) {
1 L: @  p2 l3 }! B) T) s; d6 M                        output /= 4;
5 d5 j, A4 ^2 q                } else + |7 g+ h$ i" _2 G
                if( diff > 0x3000 ) {3 [8 J, C6 Q  ~7 V
                        output /= 3;
1 \/ p, P( Y4 g7 F                } else
0 S$ A, q5 O+ w/ L  v                if( diff > 0x2000 ) {
5 H) o$ B$ ^. B8 o/ r1 y% U                        output /= 2;# ?; H8 M/ T3 S/ ]3 V, v
                }
3 u! e. t6 f& P! r5 V( _, ^                last_data = output;& Z6 [2 H" ^0 T1 [  @. f: h& ]5 G
                }. P4 m# ]% b7 _6 A- g8 S! D! v: r
#endif3 W/ ?1 p5 j& z" |& e- B
                // Limit0 ~& J3 c" H; Y0 h
                if( output > 0x7FFF ) {
7 D& }  q1 b; p                        output = 0x7FFF;* q; F' w' P: ~) g- R
                } else if( output < -0x8000 ) {6 i$ Y. J; v7 ?/ U! |9 u4 S* j
                        output = -0x8000;
( U  r7 F4 @$ @% w, P. ~                }. Y5 F5 B$ `0 D4 t" k8 Y- A& G

) k, C. Q; ^" F) n                if( nBits != 8 ) {
" U, u& L- R, Y& c                        *(SHORT*)lpBuffer = (SHORT)output;
4 Z/ U* |- Y3 g& Q! `: R                        lpBuffer += sizeof(SHORT);
1 a3 _/ Q1 u4 _5 v& F. o+ Z                } else {
7 |4 a# B1 P* M1 R2 y& t                        *lpBuffer++ = (output>>8)^0x80;
1 |  a6 o9 o; b. X( j. B& X                }
5 V/ _# x2 Z6 M$ T* l& _9 s  C
4 p; T' P$ N6 A9 \$ s                if( nCcount < 0x0100 )- @3 K; n. Z+ m4 J% u3 H
                        pSoundBuf[nCcount++] = (SHORT)output;0 p" O1 h/ a9 f; n% w# }

1 r: \# p# S, M" p//                elapsedtime += cycle_rate;
( Q0 U! y. N9 S                elapsed_time += cycle_rate;
- M$ ~1 p1 m* P$ P  L  K4 V; `        }
9 G4 H2 Z+ U, _. d5 ~; K% M
3 Q+ t2 E1 u8 a& G# r& I: Q#if        1
1 S, `, k9 q' e- [+ K' p        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
4 K/ @9 N" u1 }. c! |& d                elapsed_time = nes->cpu->GetTotalCycles();
6 {* C0 l# k8 h. }5 G" E# H1 C        }  b% y2 E1 a, a( I6 A, X1 r9 N/ F% C. I
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
9 E, H( [( E% V, m5 o6 U( A, x                elapsed_time = nes->cpu->GetTotalCycles();0 ^6 X; y* r+ @5 P/ Q  j
        }: m$ i8 C) _0 T% Z& S
#else7 L8 a' |5 Q' G+ p$ S
        elapsed_time = nes->cpu->GetTotalCycles();/ P0 ]. y) t/ u8 T/ P+ p7 k8 W
#endif
7 D1 }" U4 t6 A$ r& Q+ Z}
' d& D0 ?9 k& |& T. b. n
3 H" T9 U$ I+ I! s% l& B// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)' d: \6 ^# ^& I& \5 G
INT        APU::GetChannelFrequency( INT no )6 c3 q2 I7 A: N/ d6 T; U4 V" C2 s
{
. a. K- `1 j: ^# K        if( !m_bMute[0] )+ e' Q8 @& \; D0 ^; g
                return        0;& m+ e$ K) u$ `

: L! o- U. f8 y0 D( V# f        // Internal! {% b! U1 e) u0 q9 X+ q
        if( no < 5 ) {
& `$ S6 Q4 M" @9 p( t5 e                return        m_bMute[no+1]?internal.GetFreq( no ):0;% x8 e# a- q7 \
        }; H! I4 s# v" R/ ~
        // VRC60 Z9 b! Z, x0 O( [
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
: n; t# t1 @& y                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
4 M8 V4 F2 ~8 A) Y8 w' W        }
$ {; y" T/ d2 U5 @        // FDS
- q6 r: g( H2 v" V        if( (exsound_select & 0x04) && no == 0x300 ) {
6 m" k! e) _/ [6 V4 j. t8 q4 ]  P7 G  z                return        m_bMute[6]?fds.GetFreq( 0 ):0;$ E9 Y; y7 R  A+ {# x, o% S
        }, F* t0 b& P; J7 ]  G. W% Q
        // MMC5: E2 Z6 V- [, l- L5 Y
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
3 _1 `2 ^& L9 E. K( c, O8 u                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
1 W. Y$ @& J5 I  p4 D( {        }3 B2 j5 Z; p  j, R, J) A
        // N106: L  L, G% R# v6 U" d0 E
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
' F0 R8 R4 n4 w# _7 R8 w8 P6 b                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
+ C0 T" [7 d3 a2 I: c6 }        }: {1 [; }! X7 F1 K
        // FME7
6 M' n% w/ k$ \: w  }$ v  [        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {1 [1 i% Z5 K, C9 `& h
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;5 {7 ?! I  S, @6 v9 _2 {
        }' y- B8 z/ H4 G6 V9 t, p6 E  l) Q
        // VRC7' G, q" X; K  `! n; U5 y# \
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
! s7 L/ a! c% J( ^# t                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;( ~/ {; [2 a$ B- S6 k9 ~. {, e
        }
& x6 H8 R) {" n1 |        return        0;( V& W/ n7 }. h2 z& U: ]/ _; P
}& z6 N4 D  G& ~6 Z

6 ^1 i, }( n; q/ ?7 L9 w  i3 _2 x3 B: q2 v// State Save/Load
" D2 l& [2 o; f. c$ cvoid        APU::SaveState( LPBYTE p )7 q' u3 q& r! E+ [
{( N' V5 J) b+ y2 s: w+ D% d# v
#ifdef        _DEBUG
9 H& }% G" a$ k9 h  ZLPBYTE        pold = p;- c% H; v" F5 w6 B/ z+ r- }
#endif/ B) L6 f% Q1 U

  @7 E7 {+ y! M7 x. T        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
- `% H4 @* ^' W# o4 L) [8 h* Y2 ~        QueueFlush();8 l/ Q9 J* `) W  C  i6 i) D  s/ o

9 o# r5 p7 d: t. u2 ~! n        internal.SaveState( p );
  T' Z5 F, l/ T# i2 P+ x& N        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
  m, w. u/ p* c0 U2 T+ u( z& F) j6 U0 ~4 U! _" G: R3 o
        // VRC6
; Y# b5 `' o, E0 A8 W' N  A0 `4 ]        if( exsound_select & 0x01 ) {  k; o: {9 Q9 q! u8 [2 n# d3 I
                vrc6.SaveState( p );
( M3 z! |9 }; p9 S                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
6 G/ Z* }5 S! X) P5 }. s2 ]        }
' s$ h  a* Z' A3 G$ k        // VRC7 (not support)
& M6 X3 {  C% h3 C) i        if( exsound_select & 0x02 ) {
3 t5 n! V5 G; X. ]! c) x& ^                vrc7.SaveState( p );  r8 N, j' D, y4 U& T
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
  ^: j1 p& I& ~) C. l* h; b        }
% \4 e1 T" w9 F) I        // FDS
& A& @" l5 w) t: K        if( exsound_select & 0x04 ) {
+ i1 Z# V' w) q* q2 r                fds.SaveState( p );
7 q; k/ Y1 }8 v1 S- e                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding+ @3 B/ y7 k' y2 N4 T* Q
        }
3 S6 o. m" h& w5 V5 d* i- K        // MMC52 l) N3 P# |/ J, ^0 Z
        if( exsound_select & 0x08 ) {2 e! ]/ }) b3 U& N
                mmc5.SaveState( p );
2 c, T5 H. t4 }; I                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding. @2 u- E2 @/ s; B
        }
6 y5 ^& H, E8 R- A3 l! {        // N1067 e6 C/ h, I2 d
        if( exsound_select & 0x10 ) {0 J; u% C/ S, ~3 P% w
                n106.SaveState( p );+ z' k0 F7 t! ]0 e3 Y( X, z
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
" f0 s# e0 z5 A        }% z1 j, O* ~/ F+ b& o8 L; X# M! O
        // FME7
% [. S* Y, w* _" k6 m' V% y        if( exsound_select & 0x20 ) {
# Z) x/ C$ l. U. ?, C; @4 e                fme7.SaveState( p );
$ c9 R  Q" e, Q; Y, ^                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding8 D: @/ r0 C; E# \2 [
        }7 r  k& C$ ]$ N( [0 ?; F
- D0 [: e4 o! i0 D8 X5 k( `0 p
#ifdef        _DEBUG& t% |/ o; _  r' `& ?9 \0 j
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
( b! h7 t, }/ T0 {#endif* ?  o& B8 j7 o$ b( z) x
}
# z! E' p: [" t
" R, K' i, A8 L' ?* g# g, F! K* Lvoid        APU::LoadState( LPBYTE p )
2 Q: E+ `, F# q/ A4 W{4 X- w0 l' p7 r$ l% G) L
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
+ C# q0 c( B3 j, ]/ S7 j        QueueClear();
, V4 k$ t2 }3 Q# p/ u) X. E/ y9 A- |, O% z
        internal.LoadState( p );
- [) l! z" F4 M9 z- t6 r        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding0 H) K7 m' N% G  j  y4 G# m; u1 D1 N

" q& O; B, J# S% f+ O/ _        // VRC6
$ ?- S# c. [% H& {0 p$ c0 b        if( exsound_select & 0x01 ) {# I) M8 I* l8 o' T
                vrc6.LoadState( p );
, X$ y( X: a6 ^, J" ]# {" q                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding- i. `. Z0 ]2 @  t2 \
        }
+ H) U, N% p9 }9 e0 F2 \& d        // VRC7 (not support)
7 p' q: \- L: F# ?        if( exsound_select & 0x02 ) {
  h0 ?/ V: k2 g* l                vrc7.LoadState( p );
$ H- y4 M4 \% P( V                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
: s/ O$ X3 B+ T2 _        }
- Z; t9 T, E5 I7 G        // FDS7 P* _; N2 I- Q' z) p+ i* W
        if( exsound_select & 0x04 ) {2 k9 H/ s& ^6 V7 D6 a" w* J
                fds.LoadState( p );
% t+ Q) r. I- d) C                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding8 l6 d% }8 I1 T( w
        }
: v3 q# P1 j+ ?$ e  D1 M( s" ?        // MMC59 ]  e- b- D% J# N
        if( exsound_select & 0x08 ) {
" S! f1 u" m! U% m9 h                mmc5.LoadState( p );" [# M( R5 P3 u$ e1 c, }7 |
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
  m9 Z# h- D2 N4 s        }: a  h8 t3 ^: t9 C
        // N106
# w3 a# ?% H$ X        if( exsound_select & 0x10 ) {
+ X3 N0 n& M% k                n106.LoadState( p );
3 |5 j4 I3 u9 y+ M# p                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
) y8 A2 R) h: Q3 j; S* E* L        }
+ v' D3 M) X# R: H% w5 K0 W) N9 n        // FME7
" c8 D# J; k9 D- }1 [6 G5 Y        if( exsound_select & 0x20 ) {1 |9 J: I* C3 f3 G4 p% j
                fme7.LoadState( p );# _$ h7 V/ v% D+ N: d
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding- }- L& v) e4 I2 y4 s& ?
        }: _4 t8 Y# K  O$ A  K
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
7 h0 y* z6 t& H- h4 s可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
$ M  u( o9 H, \& N  V, J感激不尽~~

1 P; H. K9 w% k+ h& n+ ~恩 我對模擬器不是很有研究,( P6 Q4 }5 Z9 D& f/ g: U  n, E1 D; k1 u
雖然要了解源碼內容,可能不是很困難,
+ n% u4 }: ~1 x. O$ Y* _/ y  R不過還是要花時間,個人目前蠻忙碌的。1 x. ]# a. l- M' p

- p# w# y! [8 X給你一個朋友的MSN,你可以跟他討論看看,0 }" U3 R% I/ B6 S
他本身是程式設計師,也對FC模擬器很有興趣。
- N& c+ d  p5 }  K
) r9 c& A1 b7 K7 D9 q  G; ]MSN我就PM到你的信箱了。; \$ w' C& D$ r  t+ v
8 O0 U% O9 E8 ^; m% o
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 ~2 {+ Y; a8 s5 C8 z
呵…… 谢过团长大人~~

# c' m- k/ U- Q& h7 T
8 I* c, y" d9 n. Y9 P) D7 S% z3 q3 {! M哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
5 D% u- R# l  `+ e* v# \团长的朋友都是神,那团长就是神的boss。

0 M, ?+ E& A( M哈 不敢當,我只是個平凡人,2 ?4 J0 l5 L/ I6 p9 f. |
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙2 B% U& {9 @$ Y
ZYH  ^6 G# e; d2 `, V
QQ:414734306
1 A- i3 d; I7 p0 L! Y  aMail:zyh-01@126.com$ |9 Y' i+ A! x  B9 |) Q' K+ H
9 `& b& k: Y6 Z( k" E# p, O8 c
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
' A6 G" m1 M7 W再次对团长大人和悠悠哥的无私帮助表示感谢~~
) S" z3 A' s: h
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-2-28 06:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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