EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
9 B9 E* P8 x/ d% ]5 ?4 g楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~' m+ w3 M  ]- q: T) z3 `; H
这里有相应的模拟器源码,就当送给大侠了~~
$ U0 _" n% i" M+ ^" n  D- G& rhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 : e& P8 l7 f; w& V
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。' |2 X3 g/ T5 K7 {
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
8 E. n7 t& z9 u6 E这里有相应的模拟器源码,就当送给大侠 ...

- W* |3 q( c# N; w' P& ?) F: |  o聲音部分(Audoi Process Unit = APU):
4 i/ ?9 N2 ]! Y% ~, p  h.\NES\APU.cpp, o! {- v% z; L8 k) k
.\NES\APU.h" i3 u" [1 V' B1 Q7 U

( N* d% i$ B- n; n% Z) `1 e; b5 E) Q+ F2 B# h  j: q
影像處理部份(Picture Processing Unit = PPU):# W. |1 I' S5 E; B$ [& s4 ?
.\NES\PPU.cpp
$ o1 |, W, Y# N" y.\NES\PPU.h
/ E. i) _9 x0 H1 Q
& ^- j, |' {$ \3 _如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:  _6 @/ P( }+ Y. x% }7 g
(由于很多专用术语和算法机理都不明白,所以看不大懂……)3 I! B# {$ F/ }1 s
//////////////////////////////////////////////////////////////////////////' ~/ C& G' W% Z2 V. b8 M
//                                                                      //  d, \. m2 a2 {% H1 x0 N7 b$ D
//      NES APU core                                                    //
. @) x! Z) C2 z//                                                           Norix      //
- y8 ~) w) ~; ]( z//                                               written     2002/06/27 //% ?' M- M/ R& ]/ d4 j
//                                               last modify ----/--/-- //
: v8 d3 t1 \5 ~9 E5 q! H//////////////////////////////////////////////////////////////////////////
$ {! f/ Y9 `* u  d: ~+ F8 K- Y! p#include "DebugOut.h"4 l3 x8 B3 {4 j# O
#include "App.h"8 z3 k- y# Y2 z& s: o  [# `5 F# N
#include "Config.h"
: w/ s* I" I5 _0 ], G
0 P, ^1 c# G% C0 f#include "nes.h", w% I9 D( H2 j9 P! Z9 E0 ]
#include "mmu.h"2 L+ }' s, a3 A) d  f
#include "cpu.h"
: X5 A8 r- [3 v7 B! G#include "ppu.h"
1 d" N, p9 d, ]5 u- d: s& K#include "rom.h") l6 K4 c' {) X, L
#include "apu.h"
+ ]/ b; Z4 |# N5 g8 B
2 r7 M- h  S1 ~+ `+ F// Volume adjust" Y% a  Y2 M& Z8 v; u5 h- n3 Y
// Internal sounds
1 U2 P% U/ l4 v  X( F#define        RECTANGLE_VOL        (0x0F0)
" m$ s0 f) f8 _2 r$ y4 R# Z' ?#define        TRIANGLE_VOL        (0x130)
7 C1 k0 }0 K5 a. ?$ o+ G- B#define        NOISE_VOL        (0x0C0)
* w5 C0 T  |! j! }! A) N8 g5 F; ^#define        DPCM_VOL        (0x0F0)
' T0 h' J' w/ B* S// Extra sounds3 N6 {0 t: G$ }8 c7 t5 T
#define        VRC6_VOL        (0x0F0)% F0 p6 Q  e  ]$ k/ {9 t4 E
#define        VRC7_VOL        (0x130)
# E0 z- F) }/ W6 J. q7 _* l; V#define        FDS_VOL                (0x0F0)
, ]" `' r3 J! x4 ?#define        MMC5_VOL        (0x0F0)
$ J! Y0 o1 E- M, w2 I* A; C8 j#define        N106_VOL        (0x088)* r) m: \# M4 I' _3 r
#define        FME7_VOL        (0x130)
! w  K/ T9 f; k% m& V/ U
7 k3 Y2 }! _6 h8 g5 vAPU::APU( NES* parent ). U4 _+ C! ^1 O, _8 s, [
{& E4 Z+ l( l+ ?$ t
        exsound_select = 0;
' C) n+ ?' v6 R" N1 X8 o0 S7 K$ j& T9 L3 R7 F1 X  ?
        nes = parent;: W; w* f8 G, G
        internal.SetParent( parent );! s' p+ s# R) j, ^0 {5 i* X

& W( |* _$ M9 L7 P        last_data = last_diff = 0;
; A* }8 [2 c, ~, P$ |% t. H$ Z' n) ^+ P$ h
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );) `7 z8 m! ?( q7 V1 l) H. b" i3 y' J
7 {  I( f. j9 v7 e' n; y. Z
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
. T( O5 `8 q$ O        ZEROMEMORY( &queue, sizeof(queue) );
3 T" Q% f3 s6 c: y% s        ZEROMEMORY( &exqueue, sizeof(exqueue) );' c" C9 C- I1 M% I, Z

' B5 T/ c2 W0 W# u/ H        for( INT i = 0; i < 16; i++ ) {
& C* [5 ~9 @; @) L2 U                m_bMute = TRUE;
- l( l& S7 {7 D1 _7 \0 A9 [        }
) b! w' I& b- ?: o* _}: Z% v# M' S0 R3 h

3 @: A0 K5 S1 \; T$ n6 bAPU::~APU()
+ `1 h6 O& n  k/ `# ~0 m{
4 V' o" Y6 D; w* i7 k3 J}
. \: R6 ^1 ^  x- i& I6 L1 B: h, r+ F
2 {# f- @: }2 i- P; t7 K' U4 Jvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )9 X- X. Y! T# L; L" k
{/ R2 @, u2 h$ |0 o! [/ y5 p  p! s
        queue.data[queue.wrptr].time = writetime;& z, k6 n( |- H* g
        queue.data[queue.wrptr].addr = addr;
7 p& T2 N9 X8 S1 n+ Q$ B; S: ]6 G        queue.data[queue.wrptr].data = data;1 v$ E" n, w- X$ d
        queue.wrptr++;8 G9 z3 j- z! C2 J3 O
        queue.wrptr&=QUEUE_LENGTH-1;
( a8 T% l( L5 X2 r! i        if( queue.wrptr == queue.rdptr ) {; ]3 t$ S6 n% H- Q( J3 S
                DEBUGOUT( "queue overflow.\n" );) i" I/ o3 m! _5 P" F" o
        }
* F+ g" _3 w* _- A}; F+ E( p+ N; w, b

  _+ k+ ~6 w, E8 C1 F% N' |& qBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret ). b9 L, b8 X2 Z& Y9 x4 h
{
4 y+ y& c1 r" `0 s) r& f        if( queue.wrptr == queue.rdptr ) {
& g& x5 ?  K6 k) b' h                return        FALSE;
! ?' E3 D) u6 J0 F        }
" q! @& |0 \- S9 b        if( queue.data[queue.rdptr].time <= writetime ) {
# ^' Q& s/ m- `& k+ j6 t. Q) M                ret = queue.data[queue.rdptr];
, G5 G* P& J) x                queue.rdptr++;; r) b/ @1 U% U, v: \) n6 F( D% F* t. \
                queue.rdptr&=QUEUE_LENGTH-1;% J: r# G; |0 E
                return        TRUE;* t) _1 z9 r7 D% E3 z  C7 ?
        }5 ~1 d, I0 d8 m  t- C
        return        FALSE;9 |- ?- w4 @, z, m
}
1 ~' x" b  n5 A- w( D- t+ u4 U4 V* |
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )6 A9 S6 u: z; {& z( k
{
) I# s. o) J4 H        exqueue.data[exqueue.wrptr].time = writetime;# z# {, e6 @5 N4 B3 J0 s  v
        exqueue.data[exqueue.wrptr].addr = addr;
* ]: Y, S1 |! y" x        exqueue.data[exqueue.wrptr].data = data;, r/ D, F& c7 a! b0 v* X
        exqueue.wrptr++;
. C. q' y$ Q! \! I* l: ~5 A1 J9 q        exqueue.wrptr&=QUEUE_LENGTH-1;/ k+ C- W1 A* j
        if( exqueue.wrptr == exqueue.rdptr ) {; ?: v4 k6 P! C5 H/ v7 C3 P
                DEBUGOUT( "exqueue overflow.\n" );2 C' b1 @7 v9 _# T
        }
5 g% Y8 t) J. h/ g5 `1 F}
; O9 r. t; v4 j' b% P# y* L# T, R0 y3 A/ \
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
/ B! z% g1 h$ E- a! ]8 b' j- q0 x$ m{3 h, B! c3 I/ F# \- e$ x" a5 z
        if( exqueue.wrptr == exqueue.rdptr ) {
% u) v: r1 M9 E" _1 k6 h% O                return        FALSE;
0 R+ H6 e' G3 Z6 c9 G' D0 c, D1 `        }
, t: ?9 R& }: r) ?5 ~: I        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
. I- s! [. f2 ]& Z: a2 [9 F                ret = exqueue.data[exqueue.rdptr];
) [% T$ k+ M* _' r                exqueue.rdptr++;
* ~! Y7 e9 G  h  d7 v1 c                exqueue.rdptr&=QUEUE_LENGTH-1;0 b6 ~* s: w5 b% |* T
                return        TRUE;# Z- R. B( w6 v" @; M
        }
) j6 w4 R0 l0 T  {5 z: O        return        FALSE;
  F) L6 U+ L5 n' C$ `* ]" V}3 \0 l, O+ }/ l; a8 Q- w& d
8 `, v4 [' W+ {+ Y& ?! U4 g
void        APU::QueueClear()7 z3 G8 u! Z9 u* Q& O
{+ S* l3 Q3 L5 R% W7 M/ C
        ZEROMEMORY( &queue, sizeof(queue) );/ U4 y+ V' Y! K/ V' o( @  ^& ]
        ZEROMEMORY( &exqueue, sizeof(exqueue) );- Y8 f( W1 H+ A
}
, N( }7 U+ u8 ]6 j$ _8 ~: ^( \
" J4 ]/ I. p. D. uvoid        APU::QueueFlush(); g- A- Z. D5 ]3 A. d
{6 D& A1 Z4 g# q! H$ r
        while( queue.wrptr != queue.rdptr ) {: h) Y- C9 z( ~9 o2 I: v" [, s
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );# L* d* `7 a; F5 ~8 C% @
                queue.rdptr++;
/ w, R' w' G5 ?5 C                queue.rdptr&=QUEUE_LENGTH-1;
$ f6 A9 N7 A2 |$ o* n2 `        }
- X! `9 f4 z3 X1 Z# X) S
* U! ~) v( F9 r5 d: Z        while( exqueue.wrptr != exqueue.rdptr ) {
) \, y4 O# o" h8 W' p! [( g                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
3 ~' R; S3 u& k3 R0 D: t/ A1 \) }" f0 Y                exqueue.rdptr++;( s8 Y+ K8 B$ L8 I+ J# d: q( ~
                exqueue.rdptr&=QUEUE_LENGTH-1;9 X3 M: }& N: S: I8 B
        }
! x$ |. P6 d% n3 r1 U2 k}8 l- a" l8 n6 q) b* A) }) ^4 k
1 p, S- q- q0 ~# y) e" \
void        APU::SoundSetup()
1 I+ E9 U; u* P8 g; j{  T5 u* q9 W* W+ U0 u6 j
        FLOAT        fClock = nes->nescfg->CpuClock;- m( Y& g( J+ {3 y% Y1 G9 a
        INT        nRate = (INT)Config.sound.nRate;' c8 z( K% c* V; }
        internal.Setup( fClock, nRate );' M' Z5 V  W2 A8 W) t, p) U8 y
        vrc6.Setup( fClock, nRate );
% z+ E' E0 B" |. R9 d        vrc7.Setup( fClock, nRate );
  U7 ]/ z/ D8 h& `& A/ b        mmc5.Setup( fClock, nRate );
6 n* ?/ y1 }% F- I        fds.Setup ( fClock, nRate );/ a2 P! r$ c. ~. z) P( \$ j5 d6 j
        n106.Setup( fClock, nRate );" M6 X$ x* z, ~5 X! N& R
        fme7.Setup( fClock, nRate );' g8 \9 p) E* v; x
}
* z4 @5 [4 G% y" v* M2 l1 q; K" g4 }
) Y2 X# t4 G3 Jvoid        APU::Reset()
% M7 H% I0 Y- ?5 W; r" T{% o/ E! W$ X0 F; x0 o0 C
        ZEROMEMORY( &queue, sizeof(queue) );4 ?! y2 h. \# o5 g, ]" P8 x
        ZEROMEMORY( &exqueue, sizeof(exqueue) );+ f* Y1 z' R) m8 @

' Y6 @, C# [# ?4 d, s% d# B        elapsed_time = 0;
$ L. h- B0 b/ \. ?/ l6 l* G; {+ X+ M$ {. K7 Q2 @
        FLOAT        fClock = nes->nescfg->CpuClock;( e9 z. t% q( u  v- M
        INT        nRate = (INT)Config.sound.nRate;% B7 G( J/ [# m% J' Q: q. F
        internal.Reset( fClock, nRate );
7 G' W9 o: g1 t, U        vrc6.Reset( fClock, nRate );) q. ^& D, T* P2 c
        vrc7.Reset( fClock, nRate );
1 @% u0 V9 F- W0 N8 S: p7 s3 P  _        mmc5.Reset( fClock, nRate );
! |5 E' M. x/ H% y        fds.Reset ( fClock, nRate );
, ?# A7 T1 }1 q        n106.Reset( fClock, nRate );/ T- K4 _+ G- y3 q' G$ ~) k
        fme7.Reset( fClock, nRate );
! B, l. d% J9 b
( A$ T7 D6 h( |" g$ G        SoundSetup();# w$ [* x2 B. ]
}
- {4 v" ?2 R, ~; E. f+ |
4 g- V6 b! w1 Uvoid        APU::SelectExSound( BYTE data )
$ T6 ?! f0 {7 ~3 |7 K+ k9 T" e3 o9 ]{
/ i4 l3 g, t$ K' ~- k, e. J7 w        exsound_select = data;  H+ ^/ o: g& W9 m
}
' Z8 t( w0 t2 ]' O( T
* e* C% A5 {# V  q: x& v5 ABYTE        APU::Read( WORD addr )
% Q6 T% f, h; c# W3 {{6 b7 j. O/ S) _
        return        internal.SyncRead( addr );
* @; U) h; z* S* s) Z}# I& k( o+ |6 k" @* e

  Q. ^2 j9 g( P% f1 W& k. l1 Ivoid        APU::Write( WORD addr, BYTE data )
$ s; D: B5 e/ X3 t, M( g+ Y3 d{
+ L+ ~" c6 B% ]; _+ g. \9 W        // $4018偼VirtuaNES屌桳億乕僩3 \, ~: j/ n$ _! ^$ }; ?
        if( addr >= 0x4000 && addr <= 0x401F ) {
9 P  y4 m) m6 k6 K1 M                internal.SyncWrite( addr, data );
" l! R( x7 x) _$ x6 u                SetQueue( nes->cpu->GetTotalCycles(), addr, data );. M6 J1 D( Z$ S8 P- ^
        }
7 B, K7 a7 d1 y}
( C$ l: q1 ~3 E
3 o, Z1 R; l- v) G* [4 p3 ~BYTE        APU::ExRead( WORD addr )
8 l: r: l+ {  w. s{
/ H$ g  C& v  a2 RBYTE        data = 0;+ u+ p3 g& ^+ O+ r

6 {2 Y- M/ K' J% i        if( exsound_select & 0x10 ) {
& |6 I* n: o& d3 B3 T& M                if( addr == 0x4800 ) {! R/ J6 Y$ Z' u) i
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
! l3 H: `/ g- h. r                }
) z# j( r9 G3 ~" B8 J        }5 H/ w% {" n$ f, g
        if( exsound_select & 0x04 ) {
, ?5 \( P" U' x1 Z                if( addr >= 0x4040 && addr < 0x4100 ) {: y4 {$ c, c  a
                        data = fds.SyncRead( addr );
0 |5 K% q9 Q# F* U0 r( q$ X                }9 ^$ C8 \; ?- f/ c: F% I- d
        }
* ~& a7 c7 b, e( g        if( exsound_select & 0x08 ) {
8 T3 t( {3 t; L( u                if( addr >= 0x5000 && addr <= 0x5015 ) {
4 n# Y! j" e1 ~0 c! Q                        data = mmc5.SyncRead( addr );, z% ]0 ^9 s* |* P5 j& W
                }
) C/ N& \+ O; ~! @6 i$ R        }( L; @9 a1 n, r$ g
- T3 ~9 s7 N% q
        return        data;
) B+ q. \. n. ~9 k8 d" u}8 z7 v* I4 y& K; u: A2 n

, u, J1 o4 B9 p# u8 L0 avoid        APU::ExWrite( WORD addr, BYTE data )  Y( M' z! A- z6 T8 P$ l
{- p- K! h) ?1 f0 S9 [# {$ ^( D( y
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
' X' o4 ^2 L& V) w+ W
1 T+ N" E2 ~7 }' E' @% \4 I        if( exsound_select & 0x04 ) {$ `6 j, N/ t- |
                if( addr >= 0x4040 && addr < 0x4100 ) {
- v8 ~4 p1 z0 R                        fds.SyncWrite( addr, data );
  C2 a: Q* S" p4 I0 ^! ]6 Y  b7 F" z                }
0 L& j% e5 [8 K9 O" x6 b* Y4 ]# m1 }* X        }4 a+ s* S% L8 S7 t6 x. E

8 {* Y. K& n2 ^        if( exsound_select & 0x08 ) {
& h7 e% H/ \: N6 y                if( addr >= 0x5000 && addr <= 0x5015 ) {1 F# ^7 w$ D: Y' c
                        mmc5.SyncWrite( addr, data );) _) L* n( G# W) S$ Z
                }
0 r& V' B" K1 q8 B( L        }
0 G5 }2 `' _& m: |}2 t7 T' Z1 o  A5 N7 j
* f: E+ v- z# n+ J. h
void        APU::Sync()
3 t0 Q) V  e# v' z/ [# I4 `! E{0 q; ]: [$ x' x, D: F
}3 T6 |6 F6 I* J: Y; |/ m9 p
5 O! {/ e$ z; M- G4 X  `7 B" M
void        APU::SyncDPCM( INT cycles )
3 r7 j( s/ R& v{
% D( p2 Y; K, O) c+ l        internal.Sync( cycles );
6 K3 l/ o' z' X1 ~* Z5 d7 ^6 p5 s; E8 W8 N$ M6 j2 S
        if( exsound_select & 0x04 ) {
6 ?$ H4 G5 ^% |  B* O$ X7 o( d: X0 J                fds.Sync( cycles );0 z. j: d1 k3 L9 u6 T
        }8 Z) v- L7 b' n: t* B8 o& I5 I
        if( exsound_select & 0x08 ) {, D# y# }4 K) b9 i+ _& f. ]! |& [
                mmc5.Sync( cycles );
) {" t0 Y9 _; _8 ]0 e" J& ]1 J1 ?; P        }
+ C0 o) E7 X2 Y$ u}2 N* q* X' G* K; Y! H" s
0 ^! ?3 \8 e/ }3 i% `; e
void        APU::WriteProcess( WORD addr, BYTE data )
% N2 C' k) F; ~* `! G) {{
& g3 r2 N/ w9 F        // $4018偼VirtuaNES屌桳億乕僩5 i' E$ Y8 s1 i7 @  @
        if( addr >= 0x4000 && addr <= 0x401F ) {' j4 C/ [. N) p5 r0 a% A
                internal.Write( addr, data );
* ^# L/ s9 B) J        }; r8 C  ~( O1 Y9 r- {
}% u* I6 J! h7 e# d; ?

7 ~0 q3 m; I4 a- B1 J( tvoid        APU::WriteExProcess( WORD addr, BYTE data )
) e) _+ c" G9 Z5 l- P' c. |3 ]{9 K, U4 l+ D: [- O% n5 o6 m, A
        if( exsound_select & 0x01 ) {
2 Y. F; c- q) h                vrc6.Write( addr, data );$ `- `! A8 g$ X  K7 E4 `
        }
# b+ j5 H- U4 K" m        if( exsound_select & 0x02 ) {
6 I. |4 t* Y) R4 r2 G( j. A                vrc7.Write( addr, data );" ]# n# X- _  g* U* w" t3 y6 b; M7 F
        }4 Y  ~* a! [# V, T  v4 x  p. w. B
        if( exsound_select & 0x04 ) {
+ o  ~( s/ D$ ]( W                fds.Write( addr, data );; o. ^0 ?0 j8 @6 v7 c/ v# r
        }
% b  S( P/ E9 P& a2 W+ J( x        if( exsound_select & 0x08 ) {
* X. r3 v0 ~# T3 A+ ~" c! T7 y                mmc5.Write( addr, data );0 V# C  ~2 @, X4 P
        }5 R( z( ?! S8 Y1 e: {! k
        if( exsound_select & 0x10 ) {
4 u, ~" Q/ K" w% _+ ]$ v2 n                if( addr == 0x0000 ) {% E1 h2 ~& G# t; f) z' z8 X
                        BYTE        dummy = n106.Read( addr );; e% C1 b& w3 w1 E7 j
                } else {: ^9 A) u7 S5 @# w! D8 M0 F
                        n106.Write( addr, data );
6 e* ]: c3 h2 j                }, _  C& A/ f4 ]$ U
        }
( z0 ], f3 _6 x- B0 a- W* l5 x( R        if( exsound_select & 0x20 ) {) t; ^0 n" W% m5 p  m( _
                fme7.Write( addr, data );* [1 Y8 b) F: P" n; j
        }1 w# J9 C/ R2 j6 y7 q$ s9 }* }" t
}' s5 J* r; c7 m7 _# R
% o" S8 w( q( Z  H4 v  D% U* @
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )+ m1 H6 T0 F" Z
{
+ N9 m  Y& S. I) s# _4 U- XINT        nBits = Config.sound.nBits;
- [' w/ @, i  b# ]DWORD        dwLength = dwSize / (nBits/8);
  X) B- h7 E) |) XINT        output;5 R! S6 S3 A5 \( ]3 |% Y6 F
QUEUEDATA q;
' E& Y9 [( o# q7 K2 D9 ZDWORD        writetime;, F( G" P5 }) x; b$ m! Q
' K5 K' x7 ?: X  E, O
LPSHORT        pSoundBuf = m_SoundBuffer;
. k) P) Q+ t; l5 IINT        nCcount = 0;( d1 e$ k6 \& ]5 m, o8 u
- p5 F; l% B$ [+ Z+ T* Z' G9 k
INT        nFilterType = Config.sound.nFilterType;
6 E, W9 Y9 e* J$ u0 `( c* t# y3 q- |) ?8 k* b( X5 _
        if( !Config.sound.bEnable ) {
* x! b2 P# M3 J1 _& Y                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
$ {) D2 W4 \) ^6 T9 n$ y9 R                return;) e& Y9 `6 F+ B' B$ n
        }/ l2 |8 R0 L% ]! _9 ~

' Z5 H5 `4 l* Y- y9 w        // Volume setup
. [$ i( v  k- X: f        //  0:Master
0 R: X( x( w! t% c. r        //  1:Rectangle 1
" g+ T$ z' ~) l3 H( z# O        //  2:Rectangle 25 |8 ~5 n+ G2 {4 K: V1 P* e/ v
        //  3:Triangle
' ~) N* S9 E$ k0 }9 H: I        //  4:Noise
9 |, d& |* d2 h6 n0 ~! T5 w        //  5:DPCM* [; w7 w: t5 }! ?3 O
        //  6:VRC6" O8 [$ e( }  o+ v
        //  7:VRC7; N3 [' O+ Q0 r- K7 N) D
        //  8:FDS
/ V( F6 K1 U. B2 R8 x* ~/ g        //  9:MMC5
# O2 W2 D% F: D% [! Y( T        // 10:N106! A$ p. V3 ^$ d( t$ k$ H' r
        // 11:FME7
7 ?7 w% I) Q- J2 w) V1 u        INT        vol[24];+ z1 r3 e% y6 c( p9 S8 S4 o% l
        BOOL*        bMute = m_bMute;
+ a! }3 t4 h9 j. T/ d1 G: Q; k        SHORT*        nVolume = Config.sound.nVolume;- m) h( ]- g, B# O

; R! A( S+ @; D8 P        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
/ `; F. c1 G" [4 ]. Q' t9 f. a
: d6 D& m! W7 ^6 k, s" X% Y7 N+ P        // Internal. s" U! m# J9 D
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
8 Q  X0 Q5 l8 L' b, w$ c5 C        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;+ {! _5 [, K& S2 M
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;: Y+ b( O. I/ `4 l
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
* L) g% p! j) f! E# t& y        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
( }6 W; k) ?  q) t# \$ v1 i/ d) f  p3 S. {  p! B
        // VRC66 E4 V3 X* q# w/ u* ?
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;# v) u# r, w0 s0 Y
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
1 B4 w, u* X- f# N8 w/ ]        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;) g& ?0 j# T1 B3 ?8 K1 `

* C. h" P4 W% W  A) q9 g, M- Z4 @        // VRC7+ n( ~. h6 V4 M( f4 v3 l
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
5 t# B% O. _8 _: E- F# S) p1 ^5 J0 v+ T
        // FDS3 o( Z% X5 t; @: h/ d& N9 r
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;$ F( I8 b! r9 O5 l# g( z: l6 D; v3 W
! g4 [: ]# q3 S
        // MMC5( p3 S6 \* Y" v; G3 ?
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;* Y! t5 s, I* x7 t7 }* P
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
2 a7 J+ k" o* T8 s9 x        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
8 q8 c- |) R& N$ f5 |, V+ y. ^7 Q
6 ~, l/ [4 n. D# U; k        // N106. E3 V( E1 F5 }
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- z. o8 G4 s( p1 d' I
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" S+ Q* E& A4 g  \8 R        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
( u- r0 n- v# {9 N) {        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ O6 g, [1 |; X6 U+ ]; f- }% o        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' |& @4 q4 m# y; T6 @* W) {) @. U
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
1 P; }( r3 K) c$ `* g$ r8 Z8 Y        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;2 ~! \0 c7 v. L1 |: |
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; u3 G. h1 z/ B8 Y
8 I" ]8 B" p9 M; V
        // FME7
6 B: o  ?0 F3 h$ h1 v: N/ c; |( h9 Y        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;7 z- r, Z  p5 e; |
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;# Q$ _9 }& H9 a% L6 f
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;+ R  k' U. h( x1 g9 ]# X- ~! S

# R) m* {# ~+ R5 g0 V$ |//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
( ]: i1 V- N( ^. p2 m        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
0 {2 E- L1 h: [- F
3 C; h! l$ b' H: u        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
/ S$ W) K( y; k3 b( B# U        if( elapsed_time > nes->cpu->GetTotalCycles() ) {# R; k% n) T2 N$ }: A! o
                QueueFlush();9 F- B9 n+ ?5 P( q- r5 n. L1 E
        }
) q1 ?) [" i7 G
4 ^, l; Z' F5 O        while( dwLength-- ) {
& o6 M  j+ z& m* H                writetime = (DWORD)elapsed_time;& n2 k+ Y" \  \* S4 s

' ]+ e( }0 u/ s- T' H& m& Y+ v                while( GetQueue( writetime, q ) ) {, L9 ~0 z! g+ u" l
                        WriteProcess( q.addr, q.data );
* n9 Z5 B( K& ?, M  e2 q" p& o                }5 C4 k, C; B* {6 ]  c
) N3 p7 _4 G3 J& E, l0 `+ B' s
                while( GetExQueue( writetime, q ) ) {# Z9 A$ A- r3 a# e5 }  |. t' V
                        WriteExProcess( q.addr, q.data );, |4 m; `. t7 b( ^. L7 n. m
                }1 A6 U4 \: g/ a! s% M! J" P
9 D0 d/ l) {  d
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
; f7 G6 N8 ^6 v# v2 R8 v                output = 0;% k( q3 e. U4 U  r
                output += internal.Process( 0 )*vol[0];
6 b* k; l' }4 Q( ]6 Z: i                output += internal.Process( 1 )*vol[1];
" {3 _/ Y* f2 ~. g8 S( x: e                output += internal.Process( 2 )*vol[2];& n  F9 R6 Z/ P# v
                output += internal.Process( 3 )*vol[3];
: b( w) C' Z* R: T, @% A+ f) a. J                output += internal.Process( 4 )*vol[4];( Q5 C, H7 S: P& t9 P% ]) o

: o" N1 _2 P% X8 R7 P' a                if( exsound_select & 0x01 ) {
/ D! ]2 f% h! q  c0 m  r( q                        output += vrc6.Process( 0 )*vol[5];; e$ {4 w% `; J2 G9 D
                        output += vrc6.Process( 1 )*vol[6];3 k3 F) a- K+ F5 d7 R+ c
                        output += vrc6.Process( 2 )*vol[7];
: [, t5 W! z  j" c# {$ |! y) T                }7 [/ n+ E: v# K. e! ]1 X$ h
                if( exsound_select & 0x02 ) {
/ H: L( }, }, }2 A                        output += vrc7.Process( 0 )*vol[8];
& d! n! v& k  m$ l% L8 ]- ?                }
0 |0 ~; I; o2 j$ x% ^. }# h9 w! o                if( exsound_select & 0x04 ) {& d7 H, R& t, P6 O: O  p% E
                        output += fds.Process( 0 )*vol[9];  U+ M4 J, {6 O3 V: n$ O
                }
; F( j. x# u; \6 H$ @; p                if( exsound_select & 0x08 ) {
# u5 @. d" i$ [" ~7 o- a                        output += mmc5.Process( 0 )*vol[10];/ p% ?5 K0 R. A& y8 S" d
                        output += mmc5.Process( 1 )*vol[11];
+ N$ f" ?$ g: [2 k7 Z% \: i" E                        output += mmc5.Process( 2 )*vol[12];+ z! g7 M$ x- t. W
                }
2 K" ~5 x4 }6 P+ q/ m' E                if( exsound_select & 0x10 ) {
) r3 W# P9 V8 [                        output += n106.Process( 0 )*vol[13];
! s( C5 c9 Q8 ^                        output += n106.Process( 1 )*vol[14];; t. x& R" n! X  ~" b
                        output += n106.Process( 2 )*vol[15];- K5 Q2 f2 e. _2 {: i) r
                        output += n106.Process( 3 )*vol[16];
# u& ?+ E2 j% n8 U+ w                        output += n106.Process( 4 )*vol[17];! y. T* N$ L4 I
                        output += n106.Process( 5 )*vol[18];
$ @: z3 ~/ z, D* Z+ D3 f9 |                        output += n106.Process( 6 )*vol[19];. q$ E) }- b8 j
                        output += n106.Process( 7 )*vol[20];& }% R3 g3 o9 B  i! w+ a: K1 U6 u
                }" j1 U. I$ i& ?3 Z3 `: x- L: G
                if( exsound_select & 0x20 ) {
+ ]" ?& Y& U2 j! L0 r5 g                        fme7.Process( 3 );        // Envelope & Noise1 O: b, L9 [0 O
                        output += fme7.Process( 0 )*vol[21];
4 e7 Z/ P9 S4 l9 g$ f0 i                        output += fme7.Process( 1 )*vol[22];4 k8 `; C& h- j8 B; H1 y
                        output += fme7.Process( 2 )*vol[23];
1 A8 m3 J! d! ~) q  Y; |* @6 Z  v                }4 S, X6 t0 \( a, a' G  r8 ]& i" E1 z

7 w) E3 D' g0 {9 B; Y4 D                output >>= 8;1 b: g# K0 N3 L2 z$ P

9 {- A/ n9 B$ _7 `4 m* Y$ s9 {                if( nFilterType == 1 ) {# E% }$ [! }& ^" u4 O9 ]
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)- I  H+ C& b& H
                        output = (lowpass_filter[0]+output)/2;
4 m3 Q0 r" j8 n( b                        lowpass_filter[0] = output;
, y1 g6 L, h. v                } else if( nFilterType == 2 ) {
( ]+ `5 f! \+ A                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1): w2 S3 _' J) d' o! ?: e. y
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;3 ?- `8 K9 C% F, }) b3 u
                        lowpass_filter[1] = lowpass_filter[0];
+ |. _; O9 u! n8 J" e3 u! j6 C                        lowpass_filter[0] = output;7 f$ O7 i; y6 X! c# ^
                } else if( nFilterType == 3 ) {! G) D9 T% `* s$ U# D9 L& d% q& Q
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
: A- x& f0 E, X. W2 L0 T8 g% y                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
" V; W3 ?( D0 {                        lowpass_filter[2] = lowpass_filter[1];, Z7 b' P( `  C7 {
                        lowpass_filter[1] = lowpass_filter[0];
6 K3 r" G1 \/ Z                        lowpass_filter[0] = output;
) }0 \' t8 _7 m& E' _                } else if( nFilterType == 4 ) {
  r5 d3 {  R1 j0 s7 z                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)4 G* t5 }; Y, ^! {; R+ T- m
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;- G: u- h3 a: ^/ F" ?" i
                        lowpass_filter[1] = lowpass_filter[0];) I% F; |8 R- R$ E- }$ d+ I! j
                        lowpass_filter[0] = output;, V. z% o7 z& m  z3 b
                }% G5 Q0 u  Z6 j& R2 B
/ ~( M0 m" J1 G& I2 c  {
#if        0
: S0 s) Q6 D& e: F. i2 U; A                // DC惉暘偺僇僢僩/ A8 k+ B2 D% |
                {
. ^9 I, f8 ^" e3 |7 V. z# {) n6 y6 C: o. U                static double ave = 0.0, max=0.0, min=0.0;
& p) m' C/ w$ L7 Z7 @$ g: \                double delta;; f; k: T& Z( R! Z& R
                delta = (max-min)/32768.0;  h! A, f5 q0 Q: d. O& g7 e
                max -= delta;
1 i, R7 p6 Z; f* D" \" Q5 X$ o( c                min += delta;
' h/ N, m! q1 Z$ |                if( output > max ) max = output;( D# K% ]' J4 H& K
                if( output < min ) min = output;
5 e& ^* Q: U6 ^) H                ave -= ave/1024.0;
1 x# x* k% l! @& w5 S1 A                ave += (max+min)/2048.0;0 Y: V$ T) Z$ u
                output -= (INT)ave;; ?  {7 l' e% B$ a) V% B# w
                }1 P( m# i4 m% _# Q! m4 m) N6 w
#endif3 `4 ?# ~) Y1 J
#if        1
- k5 S8 _* r8 t. n                // DC惉暘偺僇僢僩(HPF TEST)
/ K7 S+ P8 N8 {                {
. O8 D, m, h0 N# i0 g//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);4 E% g( v, \" q
                static        double        cutofftemp = (2.0*3.141592653579*40.0);8 I8 m  Z, a* ^/ e6 a# T
                double        cutoff = cutofftemp/(double)Config.sound.nRate;4 X: S! I" v9 ]- p6 c
                static        double        tmp = 0.0;2 S1 S, h& b2 t
                double        in, out;, R" l5 ^% h$ A, z) P
1 a0 l& M' h9 x' H6 S
                in = (double)output;
9 ^, h4 \" J$ I  `1 t7 f                out = (in - tmp);% ]) g# d$ M, l9 A' S
                tmp = tmp + cutoff * out;* E) n' B. e) x/ u$ r
& w* t6 f3 [6 Y6 `1 r
                output = (INT)out;" L( }# r' a% X3 a% y
                }
0 K7 P# B- l) R9 O$ O) ]#endif: u* s& H0 l9 d& G; A* [( K- C
#if        0
; R  v% D, x6 a" N# G0 |                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST), T2 y5 f* l, e, K
                {
9 y, b. M3 F9 M1 _, }                INT        diff = abs(output-last_data);
6 I5 J; z1 \; m( P% j7 w9 e                if( diff > 0x4000 ) {
. N1 C0 q& V  U( }6 T                        output /= 4;
% }) t9 J' T) Z                } else
6 `$ _6 f& B  h/ K                if( diff > 0x3000 ) {  s. r) [& A& p3 v: ^8 {# ]
                        output /= 3;
% ~5 H* e8 Z" C) I+ P, R                } else
7 W0 r- {7 H7 J4 C                if( diff > 0x2000 ) {. a, R8 d2 c' A- `: `' a9 g
                        output /= 2;+ a9 r/ \% ?# U% s. k
                }
9 y) U) W5 b+ f2 f' ]3 N' {                last_data = output;
& P. |+ a" t) L$ D                }
2 b- H# T, X# @9 n, D9 \#endif4 H. l$ a/ |( t, Z% M
                // Limit
4 T; q7 v* H% q5 {- A! w* H" o                if( output > 0x7FFF ) {4 h" n9 r# ?' `  s9 I2 c
                        output = 0x7FFF;
; @/ A4 ]( e) t                } else if( output < -0x8000 ) {
9 c3 b1 T4 \- [- f) M                        output = -0x8000;
3 }. \7 t1 o2 {+ F' s6 c' q                }
$ f; X4 r2 `( b3 V- i/ G" V1 C5 s0 Q/ S, e& y, j" [( p& t, r
                if( nBits != 8 ) {2 o. x% y' M# s& B+ _
                        *(SHORT*)lpBuffer = (SHORT)output;, O9 Y- j' o6 e" n( o1 N
                        lpBuffer += sizeof(SHORT);( }7 G& R. H; L" l& i, J
                } else {
( X* q/ x! P: R6 e8 ^& G" j# r8 c                        *lpBuffer++ = (output>>8)^0x80;
3 U- e5 }& B  o                }
2 s. J% D! k0 i8 e# G  U- I5 `$ F5 Q8 j6 F; j, q) V+ \9 C: P) W
                if( nCcount < 0x0100 )
+ m7 z  o! ]9 V2 U3 M# u                        pSoundBuf[nCcount++] = (SHORT)output;5 x0 l" p5 x' [' D
/ y9 y8 X7 L# i/ X$ r
//                elapsedtime += cycle_rate;
2 ^/ B; m% Z" S% r8 _                elapsed_time += cycle_rate;) W: A) H* b+ D7 |
        }
& e) G* U$ C( l. H+ L2 f: I8 R' |* v! G4 ^  j; J: g
#if        1( D$ C! m) [( T* ~5 [
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
. Z/ g; Q" A+ h6 m/ W, ]" ]                elapsed_time = nes->cpu->GetTotalCycles();
/ x3 B+ `3 A$ X, \  W        }5 S7 V) o9 o; z
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {6 `8 {; t: \, L
                elapsed_time = nes->cpu->GetTotalCycles();
, B$ Y" B9 j7 N+ @$ \* N3 ~        }
& J6 q4 G" i# _: ~#else7 z8 d# ?* V5 R* h. ~
        elapsed_time = nes->cpu->GetTotalCycles();
$ b5 ?/ M: _4 m2 H( E3 y9 @! G#endif
- N8 i  D' V" l1 f7 p" ?' H}% I% z% x' d- L
& ]& r! Y. R6 `; O! o
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡), `# D" h7 ]& X, t7 \3 k/ v
INT        APU::GetChannelFrequency( INT no )
8 ~* y9 C4 g9 `, K. K- }! i{
1 \8 B4 U3 A3 L; n; R. Y* c        if( !m_bMute[0] )0 F8 \6 b) f8 f4 X, `( ?# L
                return        0;
4 }5 H5 Z/ Z" L7 ~7 f  j4 f8 ]- w) |6 ~8 q9 c; q5 q7 W
        // Internal
7 K3 J* \4 `1 v2 z2 j        if( no < 5 ) {
5 m/ L( k; C( O7 \; O                return        m_bMute[no+1]?internal.GetFreq( no ):0;
& H9 Q% \# K+ q+ _) g- L        }% |5 G9 G, Z0 Q2 E* }, Y& e2 a
        // VRC6+ U% c7 V/ \1 ]) w0 ^# V) t# L
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
" ~( U. B' ^) b% |6 q; R+ c, x5 R/ ]                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;. Z, F( I+ y7 P* ^1 I
        }6 {1 F+ q3 Y) Z4 z
        // FDS! g- `7 l+ M2 F5 l
        if( (exsound_select & 0x04) && no == 0x300 ) {
. R, j, W; f& T/ V' K8 W* t# n                return        m_bMute[6]?fds.GetFreq( 0 ):0;0 R% v. F; N/ `5 z, {( @
        }# t$ l& c) R6 c5 r. c& G
        // MMC5- }7 F" L: H, }" K' }
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
4 _: @3 [, j; E+ Q5 }. g1 D                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;0 F6 u* F% l7 U
        }. w2 f) c0 J1 j7 N1 R& C: f/ Y6 X
        // N1060 J  g9 A6 Q. R5 P
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {3 J' w4 C. w/ v7 T
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
. d; H+ U" |7 E9 L+ G. ^) A        }2 p: L; _# L4 H- g% @) ?
        // FME7" i+ h5 u5 L# g# V
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
  N4 q0 T- D% h/ b% Y                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;. H; M2 J: V7 P8 J2 h+ H
        }
. @7 C5 Y* c+ {9 |1 s: h        // VRC7
+ l1 j' S1 J' E8 i- r        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
: k7 W) y; ?/ V) S" h                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
6 M: N2 a" D( e) K        }8 l2 f9 |; o8 k  T2 _
        return        0;( Q( G4 z% _. B; `$ v3 _
}5 D. b0 C' U# Q3 b" m

, P7 }8 Q& P* Y. I/ {4 _// State Save/Load
/ r) _: f& `) g+ Z1 wvoid        APU::SaveState( LPBYTE p )1 {5 F- Y7 [; `/ ^& E6 f- B
{, x& t9 s' ]; l/ J! i" I
#ifdef        _DEBUG
9 `9 n7 N2 ^) y5 {" L  \4 [LPBYTE        pold = p;
8 b) w) q  D) \#endif
* g* e4 ~; S1 L9 o6 X: H; S" I! A* @- y2 q$ n
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
0 x) o% L4 O2 e! Y  L        QueueFlush();
, ?% h5 E5 _0 i% ?
0 R2 T5 X( k+ u; G        internal.SaveState( p );9 [5 b9 l0 ~& _* G4 C* K
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
+ p) x% {% d3 i/ t6 B" n
6 t: ?/ H7 R+ _, r        // VRC6
9 V; \  K" f& E* w        if( exsound_select & 0x01 ) {
: o3 M: E: s. j/ [2 T7 N8 L                vrc6.SaveState( p );0 p4 s6 i; R1 {. V/ k. t
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding8 s( L3 w5 X/ Z! U7 h+ ]
        }3 U" D3 m2 |+ x: e& d0 |. R
        // VRC7 (not support)2 ^; O1 u! r6 l4 T, o9 M4 U& W
        if( exsound_select & 0x02 ) {
* `- R$ Z# C$ m! F# T                vrc7.SaveState( p );
$ v* h* N1 A6 E  W) y1 r; u, c                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
5 d: G* ~3 I1 L9 ~& \: ?        }$ R; S5 C& `% s
        // FDS3 H' C. b- b  d: e) l( B- K5 E
        if( exsound_select & 0x04 ) {# K5 ], |7 a$ y1 b
                fds.SaveState( p );3 V4 S. u, _. j* {' z: L
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding3 T5 c* q& [* b+ L1 a; P0 l( s( U
        }6 O3 E! [' S, |7 [% S2 t) ^
        // MMC5
' M8 U' ^6 j$ s, H; c7 J        if( exsound_select & 0x08 ) {4 G* q% z$ K0 s' \9 k' T, F: U1 ?# z
                mmc5.SaveState( p );
6 m/ ]# a" i( T0 E6 j& N6 ^) Y! v                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding) M' v( I1 W. A6 Y9 n
        }
; G/ k2 u4 l5 o% q9 x+ p        // N106
+ i, X+ e, p2 V( v. a        if( exsound_select & 0x10 ) {0 y0 w9 z+ ]. ^$ r) l- y+ E, {
                n106.SaveState( p );
7 u$ F4 E9 E3 d3 `                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding& p1 \" T2 B3 [) `& \
        }' B' I6 d9 V$ w3 B! x
        // FME7/ W; O2 b. c: K# x
        if( exsound_select & 0x20 ) {
! @7 ]! u, z" X6 Z! k                fme7.SaveState( p );
& `* O( L: i8 x) r$ Y7 x" W                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
% ]) c& z. ]9 t9 Y9 a5 ~9 \        }$ q6 E6 ~0 w: [; m0 e! j

6 V0 \$ p4 T6 @0 A#ifdef        _DEBUG6 o9 m% ?& X- H; d# W" U1 l. v
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
2 F# l8 p) e/ m" r& @  a#endif5 a, n4 e6 J( h! K* \
}
, Z4 F  ?! `0 H+ M& |+ V1 b8 K; Y% Q5 ]
void        APU::LoadState( LPBYTE p )
8 L) v) Z( r% C2 y{0 A$ h) {' N4 F" M+ B* m3 f# B
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡7 s; A$ V! |' B% N/ b
        QueueClear();
; u$ z+ X, p2 u5 c1 k! U) ]8 r1 H7 ]& g. F$ l! F
        internal.LoadState( p );
7 L1 z& K5 z( c. f1 F        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding% e* [5 C* _8 _1 k; y

9 q# t7 `" s. T; n1 T. J; {        // VRC6! k' C, m. f3 |- u4 z+ ~$ B; Z
        if( exsound_select & 0x01 ) {( a3 {7 ^3 I/ B5 Z4 i% j( n) Z+ B
                vrc6.LoadState( p );% o4 g5 w6 w/ l1 G6 r
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
; d/ j: e+ y- W3 M* u7 T- x        }
' X! x* u# s4 ?! B$ R4 H        // VRC7 (not support)
( r  `) X0 G% I! X, F: x        if( exsound_select & 0x02 ) {
  t1 l$ B7 g6 N5 L                vrc7.LoadState( p );7 Y& o2 i  o  l8 I0 }1 ~
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding. o- K9 p# C7 S: M
        }
. Z' L8 G! y) e- N" B8 p* |        // FDS
: A8 D9 n* M& S5 j. Y* _. p7 `# h        if( exsound_select & 0x04 ) {
8 L8 R2 }' P& Y* F& X  Y                fds.LoadState( p );; N0 _8 ]% W1 Y) h9 ~
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding: S9 d  d& [+ R: P( D
        }& N6 a  H4 v5 D
        // MMC5
+ {! C- X, g* ?4 N5 I, l        if( exsound_select & 0x08 ) {& N( ]1 q3 @" k2 i1 d! @& Q% E; w) U
                mmc5.LoadState( p );
( _# Z, {# O- h& ?& p, w1 h- n' j                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding' X1 b7 [5 A2 r" I, d/ `* z7 L) E
        }6 [. H  p/ b* x4 e6 I0 ?
        // N1069 x* c# ^7 @, F/ u2 q2 ]
        if( exsound_select & 0x10 ) {
. a: q- S7 [0 g3 ?                n106.LoadState( p );, @# l6 C% {' f3 }
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding3 ^9 s4 q& g" |! m7 }) `& R4 G0 L$ S& n8 ~
        }. o1 J7 M& {6 i$ O. ~
        // FME7
) O  f8 Y3 Q1 p/ H. N        if( exsound_select & 0x20 ) {2 j! m' t* L$ p8 v/ ]0 {
                fme7.LoadState( p );+ {  q; ^2 f, u- n. \( s0 k
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding1 E9 X; t3 l8 }' A. F' F# e/ F! }
        }
8 t; Z( Y3 [! c7 W3 a}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
. d( E- S! b# A可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
2 t6 t+ \. {! d感激不尽~~

+ t5 P5 I. v* S' T; H* e恩 我對模擬器不是很有研究,
  z) J2 I- l5 J, Q$ b, W# s( f4 c雖然要了解源碼內容,可能不是很困難,
) Y0 i5 V% S# ?* i* v不過還是要花時間,個人目前蠻忙碌的。
* Q9 t7 f- K7 }! g4 l9 f  X& m4 ~0 q% M
給你一個朋友的MSN,你可以跟他討論看看,6 z, f" D' |% W2 S: B
他本身是程式設計師,也對FC模擬器很有興趣。
9 \2 ?6 U7 T& p3 m3 {
1 i2 b. Z9 Q2 _7 A) z4 z, {* b2 l9 OMSN我就PM到你的信箱了。# j- R" Y* Z. v; C7 f0 [
$ }8 }4 a' w3 V  Y  B
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 1 \& D3 h7 N! K% I
呵…… 谢过团长大人~~

  K1 l3 O) m. S4 J; n) f; y) b4 g: D+ q& K0 w! S
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表   @: E3 H1 g2 n  k" g# l
团长的朋友都是神,那团长就是神的boss。

4 E7 e3 M# Y0 `* L哈 不敢當,我只是個平凡人,. Y5 f1 A# q8 q% O* W% s& F
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙+ Q! C+ i2 n& l1 {' P6 L
ZYH' f9 h: o& F: d: g5 A
QQ:414734306
2 ], s; u6 `& s4 j% Z" GMail:zyh-01@126.com
* w3 B' X. h3 C5 S
+ \/ i3 e$ {3 r: x& a1 q他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
+ E3 t, H' b# v: j0 @% J- A# U再次对团长大人和悠悠哥的无私帮助表示感谢~~
. ~, y7 m& \% F) t  Y3 S( U9 }# N
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-19 22:51 , Processed in 1.127930 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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