EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。6 ~, J- w4 H6 l0 W& ?+ y# d" c
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
( U# m, {0 x) `; B& `这里有相应的模拟器源码,就当送给大侠了~~) _' s1 }. z' o1 w# k4 Z
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 % r$ O7 C3 y- G- ]
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
- e5 z6 m' m9 S4 {) d. D1 |- ?楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
5 v9 n' M4 i0 W# P  G这里有相应的模拟器源码,就当送给大侠 ...
0 ~% ?2 K' [. x* u  g! n
聲音部分(Audoi Process Unit = APU):( j8 _- @7 g# H% J- `+ J
.\NES\APU.cpp
0 U6 G: x; n* Y$ M% e6 `; q7 l.\NES\APU.h
- `& T( u" Y1 y5 A5 T
8 n5 \6 P( [, P! e# P9 o8 u: H4 V& A+ r/ X! c- Q  |
影像處理部份(Picture Processing Unit = PPU):" U9 ?4 j3 l5 f, G' y: Q) [$ P
.\NES\PPU.cpp' C7 w- _, j  I" D
.\NES\PPU.h
# P) A' [& i; ~7 f: t! m/ f) J6 C3 I) @$ ]' E& f
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:  K/ O5 }$ v- n: q/ P
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
1 i9 s: v. Y4 r1 b//////////////////////////////////////////////////////////////////////////& r, q; e1 Q* X- A  f
//                                                                      //. i, ~; t/ f8 X% X$ C6 }1 A
//      NES APU core                                                    //
8 Z% x; v- v1 i- \//                                                           Norix      //  f6 l7 Q$ k- E: l" w1 o
//                                               written     2002/06/27 //, U0 d8 r1 Q1 E' v: ]
//                                               last modify ----/--/-- //( `2 R0 ~1 C% z: K/ g# U
//////////////////////////////////////////////////////////////////////////
( c5 ?" k% v7 a* ~1 |9 n" f3 v. k! m#include "DebugOut.h"" i1 b8 r+ M( f% E  n
#include "App.h"
# @- l' k; g& u8 X, [#include "Config.h"
: H8 ?' Y/ I8 r, ?' u/ q0 b" B7 f0 s/ |8 U, |
#include "nes.h"
) O2 F3 ~$ d& c( ]1 S#include "mmu.h"* O4 J% h9 M2 t. ~/ x
#include "cpu.h"
" ]: l. _/ I+ z4 p#include "ppu.h"( k( {+ o7 i3 O  `, e5 |
#include "rom.h") ~* Y# W, Q" D
#include "apu.h") E( J3 Q" q* ?6 @; {$ o/ L

  ]7 R8 V- g  a5 R2 f0 k// Volume adjust8 G$ p. V3 f% g: p' f4 M0 W
// Internal sounds3 j3 m5 A$ T, c' x) c
#define        RECTANGLE_VOL        (0x0F0)
5 t6 U# ]5 W" a4 B! x( k#define        TRIANGLE_VOL        (0x130)
) Y; Z' T: p9 S2 g#define        NOISE_VOL        (0x0C0); P. O7 s6 w2 T- ~6 ~3 c# f5 O) P
#define        DPCM_VOL        (0x0F0)
3 L; \  K' M; s* r# f' R5 j// Extra sounds+ ]: {" ~+ P% W0 P7 f
#define        VRC6_VOL        (0x0F0), l1 {; r% I( U
#define        VRC7_VOL        (0x130)
6 E# X: a, [& B9 M#define        FDS_VOL                (0x0F0)
0 A. l8 f0 F( ^4 F# h#define        MMC5_VOL        (0x0F0)
% d7 f; j2 O' c/ a; t: r#define        N106_VOL        (0x088)  e1 `4 X; d8 D1 G  }
#define        FME7_VOL        (0x130)' i9 r$ H- ]. Z) m% _; a
  z9 g9 [6 y# M1 {
APU::APU( NES* parent )( P# g" y5 `5 e
{# `$ r5 Y: Q; `8 ]+ [
        exsound_select = 0;
8 P3 @6 H  C% a. `3 ~/ Y. Y, d* {( t3 g
        nes = parent;
, }3 s# j! c' r2 ^2 a+ e        internal.SetParent( parent );
7 O  f8 P; T% ?
& M0 F  x( D" n  e        last_data = last_diff = 0;* a+ d' G9 K* j0 h- f6 T
$ r' N4 x6 C) p
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
( u, Z( o3 F* e1 q. z% Z+ K' V; t* {  a' y
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
# j" v! m) t+ [4 c: b        ZEROMEMORY( &queue, sizeof(queue) );
1 n5 d. c, E3 Y& x$ _        ZEROMEMORY( &exqueue, sizeof(exqueue) );
, v4 m& t+ T+ I. v6 q6 F- k1 |# n0 j! R* v! W. E
        for( INT i = 0; i < 16; i++ ) {
% b! l; m: _1 u1 `                m_bMute = TRUE;1 e; P& y& n- `; ~, u& G  F
        }6 w! g% i% h: ?2 |1 w& H+ E
}
* A- M$ U. l2 n+ ~; n) a# |) F- F. V4 `
APU::~APU()( M0 \; T2 Y! h( ?
{
8 M2 d! G4 v5 [$ e/ B) }}
. u. u- ]% @0 k3 a) ]% L: s
  L3 O* L' U# {% m7 |0 ivoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )5 i6 |& z/ n$ P
{
2 D; O, T3 e* u& }        queue.data[queue.wrptr].time = writetime;
: p: B; ]( z+ F5 V0 B% k        queue.data[queue.wrptr].addr = addr;
* n% k: M4 u1 p) t% P        queue.data[queue.wrptr].data = data;3 z, W% \/ Z# \+ S$ y) ~* T) Z
        queue.wrptr++;$ u, G9 q/ P# I1 A3 b6 n
        queue.wrptr&=QUEUE_LENGTH-1;
0 S* g  V- g0 n* r& F! _3 }        if( queue.wrptr == queue.rdptr ) {7 ?- t/ P6 f+ N$ l1 |, t0 i; {6 B
                DEBUGOUT( "queue overflow.\n" );
0 H4 [" w5 {- c. C$ F  Y        }2 {" O+ j- v* Y3 M
}
6 x! H* Q+ J2 |# P. L
! B9 y- }5 I% Z0 h2 uBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
% c& f# X; }) t' [- h# L1 ~{2 f! e6 s* p$ Q" _
        if( queue.wrptr == queue.rdptr ) {8 m& M1 }8 I6 m% q
                return        FALSE;' a, d" C/ E2 _: I8 a1 g/ f, ?
        }
- f7 M9 s7 n* t+ T! @' W2 I        if( queue.data[queue.rdptr].time <= writetime ) {
& f+ [; A. I1 ~$ g% Q                ret = queue.data[queue.rdptr];" k2 i# }2 |& ^
                queue.rdptr++;
) `4 |' W: m( ]; C( E/ i                queue.rdptr&=QUEUE_LENGTH-1;
4 x4 g: t8 q. S                return        TRUE;
  m' M# v+ s/ `+ j  f        }
% K% \( a  N+ J+ [: W        return        FALSE;! y( Z; Z: z, ?( ^* A/ R2 J
}2 U- `. M. F1 t- F4 D- k6 Q

& p6 N% Q& ]/ H* p" @void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )" O3 x) ~0 U9 Z  B. [; s, q
{2 F  P2 D( X5 ?
        exqueue.data[exqueue.wrptr].time = writetime;6 Y4 ~5 {0 Z  z
        exqueue.data[exqueue.wrptr].addr = addr;
) t, i2 w( M' X2 y        exqueue.data[exqueue.wrptr].data = data;
2 D) z% ?- w. p2 D# f        exqueue.wrptr++;
* J" A+ c* H' W! ]        exqueue.wrptr&=QUEUE_LENGTH-1;. p2 e8 d* \, z
        if( exqueue.wrptr == exqueue.rdptr ) {
# d; ~- w3 y2 p0 L, g1 E' j                DEBUGOUT( "exqueue overflow.\n" );
: E! d$ E! I7 S+ B/ m; ~        }
5 s4 c% Q0 {6 u* c" r; A3 T2 D}2 P# i8 `: x! s* Y! F

+ Z5 ?: s) Q3 Q5 E% xBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
7 e+ E+ b+ |7 t% p2 v+ w7 n: f! x{
: c& E, Y' V7 l. N        if( exqueue.wrptr == exqueue.rdptr ) {5 I. n1 ?8 G, T% P+ V
                return        FALSE;+ f$ }1 E* i+ K' v: h% M/ O
        }' X; M! ^0 G5 o3 _* i
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {1 d% E7 X6 \/ d
                ret = exqueue.data[exqueue.rdptr];
; X8 {0 l# X( m* h+ R                exqueue.rdptr++;
# J3 {3 L: b' Z: x" `4 R* G5 r5 a' h                exqueue.rdptr&=QUEUE_LENGTH-1;
. O3 E2 o* p8 m; S9 J                return        TRUE;
! V9 E/ {, V* Y  B, v2 y: @* R- w        }
4 Z6 i3 N/ k# I        return        FALSE;
& l, z6 e4 `. H7 g3 x1 D}
7 P# v; F  ?$ b# ~
9 Z6 F% O/ Z5 `; H4 n. J9 fvoid        APU::QueueClear()
6 q8 A2 x1 W+ R: ?1 s{% J0 j, {$ S9 i6 n$ k5 I
        ZEROMEMORY( &queue, sizeof(queue) );
; z9 }3 f+ W: L) X7 Y) Q  }        ZEROMEMORY( &exqueue, sizeof(exqueue) );* i, n! L. N4 c* T  Z  H6 I# F
}
$ {" L% C, @. j% D( T  l  ?. D+ @+ \' m6 l/ ^3 p) x& f  F
void        APU::QueueFlush()/ Z; a0 P6 j9 k* ~2 Q
{
# X+ G1 {" L# A        while( queue.wrptr != queue.rdptr ) {
% l& z1 R4 o9 [                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );+ v) O/ U% l8 }8 |5 _
                queue.rdptr++;
9 z8 t) D& T" ?  N* ?- v# a                queue.rdptr&=QUEUE_LENGTH-1;
# D, }- j3 ?$ D) L6 x1 H- g        }
1 Y7 e# k5 k' S
/ ?  Q/ A" b# t3 i3 }0 M1 N- U        while( exqueue.wrptr != exqueue.rdptr ) {
) ]: E) _/ D; a1 q- v% n$ `; A                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );8 S: W: e8 t  o2 o3 i% m/ o! N
                exqueue.rdptr++;
* b  ], g) v/ w8 d! [) J8 E                exqueue.rdptr&=QUEUE_LENGTH-1;. \! J# s6 @4 F3 J
        }. [' P& W# S7 g
}
( ?( |' C) l2 \# t4 p* E, s
# _* z# r+ N6 K% E& c) `4 jvoid        APU::SoundSetup()7 @5 o# [5 {5 D. @. T
{" H- Q, T3 r- V
        FLOAT        fClock = nes->nescfg->CpuClock;- r7 r9 Z) k6 Y5 m' B) m. N
        INT        nRate = (INT)Config.sound.nRate;! ?$ G9 g" a$ M5 ^: \/ L
        internal.Setup( fClock, nRate );
! n; N  e! S" i' M6 s& p" c* {        vrc6.Setup( fClock, nRate );- H- J6 S: ^- `" L
        vrc7.Setup( fClock, nRate );
$ n8 V+ i# K/ c3 q        mmc5.Setup( fClock, nRate );
) P; b  F0 F+ b7 M8 c. ~9 w        fds.Setup ( fClock, nRate );7 C+ R" _) v( m( r! \
        n106.Setup( fClock, nRate );. r' F+ F3 O. o9 B0 k, S% ]
        fme7.Setup( fClock, nRate );  H  {+ Q" @- q! I# V" k: W
}
. W1 \% N% k, X
- P8 B8 T+ n# u; E" @9 t0 h9 M6 rvoid        APU::Reset(). n% W! A" {. m! s# i
{' H/ s; D4 J& m! _3 @
        ZEROMEMORY( &queue, sizeof(queue) );/ c$ i9 L0 O% f- s! ?2 x2 G
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
' D9 L' n) ?! B9 Y. I6 [3 r! u* I5 ^/ X' P2 F& @3 ]
        elapsed_time = 0;- b. X9 f; [! V' M+ r

, p2 p; i& v- m; R( M2 |        FLOAT        fClock = nes->nescfg->CpuClock;& D$ a/ V5 L5 @: @3 i
        INT        nRate = (INT)Config.sound.nRate;" f/ f1 o, y+ b
        internal.Reset( fClock, nRate );
2 J$ f9 V- D0 `; z        vrc6.Reset( fClock, nRate );- Y) ?* s, s! e5 `$ T) `0 v
        vrc7.Reset( fClock, nRate );  P% P" n  V5 J  }# m
        mmc5.Reset( fClock, nRate );. b9 U" S# b* C4 u2 r9 G
        fds.Reset ( fClock, nRate );
' D. F& Z) p, z- W3 L        n106.Reset( fClock, nRate );
) y* p& C/ ?* Y" O, o8 W* R        fme7.Reset( fClock, nRate );
! D) X- x" w9 M1 U' D" ]
, L* E* o" R* E8 D        SoundSetup();9 s0 j  ~( b0 Z2 ]
}% b3 G! X/ t3 e% z( H" V

1 M6 F+ [* U# m0 U/ V/ {void        APU::SelectExSound( BYTE data )5 c+ T1 h0 x  H, W0 p& _' k( ^
{
: p% _+ \8 s# n+ x3 K        exsound_select = data;
7 {& n9 V  C; T. b/ R}) Q1 B/ H6 O, r8 ?' ?' P1 k  R
; ]- Y- g% X& I2 h  ?
BYTE        APU::Read( WORD addr )0 U" j7 W; d4 R( G3 p2 |
{. L& j0 V, e# \  f
        return        internal.SyncRead( addr );, ~' {" D$ V0 j  V& m
}
6 f2 L8 H# _5 j& J- n" L+ [5 P0 H5 _7 a- f
void        APU::Write( WORD addr, BYTE data )
' k! j5 O' o( j0 i% f{
, r+ g4 S5 z- ]2 {( w3 p( Q2 z        // $4018偼VirtuaNES屌桳億乕僩
: j  V  u) N$ \: W' U! Z        if( addr >= 0x4000 && addr <= 0x401F ) {
" a5 _$ a2 A# w# A# O! C                internal.SyncWrite( addr, data );! O8 T% K: J- b- n9 f
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
% k( }7 ?; Q1 F2 Y5 g1 R$ D- Y        }
0 O0 H# Y9 W2 @. o2 w' C}: K% E2 ], m2 `* H) y: G/ T

6 _8 x7 j. q0 l$ [: E# n4 aBYTE        APU::ExRead( WORD addr )' f* }: m5 ^: P3 E1 r( l
{$ w- x5 w! U8 ?
BYTE        data = 0;
! T5 a6 I0 S! N3 V' b
8 _( r; ^  p( Q6 ~( @        if( exsound_select & 0x10 ) {/ o: @1 N$ B0 F% f5 o
                if( addr == 0x4800 ) {/ v' X% r) Y0 F7 v4 v, f' {8 f, ]
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
+ x1 i. E7 t6 {2 r4 E0 r$ r                }0 w  ]3 D* m5 x" @  d  W4 g. Q
        }% s4 H& U8 h4 W
        if( exsound_select & 0x04 ) {
: [6 ]) d4 |0 ?% p2 e' o! Y1 w* [                if( addr >= 0x4040 && addr < 0x4100 ) {
, L  s/ O# V+ X- D                        data = fds.SyncRead( addr );) D) ?0 t8 _$ V) L* m
                }' T$ w- I* B# R6 n
        }$ r2 i6 x. q* m9 B
        if( exsound_select & 0x08 ) {
4 _; D) S* F5 \: r# a3 B, w. f                if( addr >= 0x5000 && addr <= 0x5015 ) {: H1 f' J4 H- \* ^; Y- M4 \
                        data = mmc5.SyncRead( addr );
( _' H1 F# A; e, A+ J; p                }
* o9 V1 V6 k0 D4 k' @, w3 l8 @        }
) {  m5 I. I. h4 T7 q/ q, }4 G( u/ h! ~, D& G# L# t
        return        data;
8 D* ]5 F* Z1 V5 a/ \% _7 K7 K}" w) E; \9 `" x5 Y( w
7 n& b6 n+ U. o
void        APU::ExWrite( WORD addr, BYTE data )
& G3 |+ M3 |! A7 O3 _) X8 N3 a{
4 c1 i% T6 v. [9 c9 @        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
5 C6 `" ^2 g+ i+ `( g: \: n) K0 j% Y3 R( M* J6 _5 T
        if( exsound_select & 0x04 ) {
, b6 d- _/ o( t$ ?                if( addr >= 0x4040 && addr < 0x4100 ) {, M" b8 @( K4 ?+ u; y8 A
                        fds.SyncWrite( addr, data );
2 b0 ~! L  e. Y- J& D                }
& h. b$ k# L* C* w8 M        }% W; {$ L: u( h/ K" U3 i

$ f8 g9 e' n  \, s8 j0 o        if( exsound_select & 0x08 ) {. }: u/ D) @% ?* w# b' K# T
                if( addr >= 0x5000 && addr <= 0x5015 ) {. N' N3 |# ^/ N! X* b# t1 H
                        mmc5.SyncWrite( addr, data );
6 `# ~9 }5 H3 o7 @4 u                }+ i" y% Q5 P  C5 [6 A9 o- t, j
        }
1 F4 I7 }7 @  U. Q- [" }1 L2 L; b, {}
0 }& p+ f# Q' m, a
0 E$ h7 X% a3 n: dvoid        APU::Sync()5 \6 y+ t- X3 l3 J6 s
{$ _/ u6 Q$ F' g% }, a; t- }
}
. l) V5 r. t/ d' s+ x& f7 C0 R- Z7 w. H, x0 W8 H9 n
void        APU::SyncDPCM( INT cycles ), }- s" p* y( e
{; M, ^4 q& n' G, w
        internal.Sync( cycles );1 l) h, I: }6 S4 T

( W2 T2 h7 j- g7 T  L+ F# Q1 e        if( exsound_select & 0x04 ) {9 |7 e- b" h" R( |
                fds.Sync( cycles );
" I7 v' k5 P$ V        }
+ `4 X0 N* m) A0 G7 b        if( exsound_select & 0x08 ) {
: f6 G' j( S( {  p7 I( A, ^                mmc5.Sync( cycles );  K$ ]/ N, P+ D6 A9 C6 M( _9 L* s
        }$ o. G+ o9 d8 V1 S, E0 l
}$ D, v' [% ^1 y6 @" G6 \

, d( J" B6 ^* h3 g3 o, Q$ H2 ~; W+ ~void        APU::WriteProcess( WORD addr, BYTE data )
  s  R" u; O' \0 p4 T) |4 z4 A{! R8 w  q6 F4 n5 i4 X0 X
        // $4018偼VirtuaNES屌桳億乕僩
' A0 |: I. |; v( d8 j1 T9 Z: q        if( addr >= 0x4000 && addr <= 0x401F ) {8 N( i2 G" B) V, t  N
                internal.Write( addr, data );
+ _  D, O, i) L3 |  H; W; g# W, K( ]' j        }
5 r5 r5 E$ R, k* g1 H% w) O}
7 e1 d$ U* @2 Q, U8 Z( P: }% ], ?8 P. q
void        APU::WriteExProcess( WORD addr, BYTE data )0 U- @4 A1 e9 N5 Y# e6 v# d
{
& Y7 T$ b. \% W) E5 O8 Y/ R        if( exsound_select & 0x01 ) {
& v3 i( g7 r. T                vrc6.Write( addr, data );# F+ A5 P7 @+ G0 K) d- d& _
        }% j2 i* s5 \$ r
        if( exsound_select & 0x02 ) {8 Z7 Y/ }) V5 s3 E& Q
                vrc7.Write( addr, data );) g) V5 Z" q" R7 B! _
        }5 z5 C/ W( z; x& h8 {4 D& h
        if( exsound_select & 0x04 ) {
' {. }" B1 f: \! N% J3 D                fds.Write( addr, data );
& \. Y. P" M1 n' b" s        }& C$ I, W. {9 `3 t7 C* {8 o/ S
        if( exsound_select & 0x08 ) {
4 n2 `" Y  N- u0 q                mmc5.Write( addr, data );; \$ F- k3 u& Z* x
        }" {) C* y; ~0 W, E, i; P1 i/ r3 d
        if( exsound_select & 0x10 ) {: ]4 V3 [7 T0 ^& C5 l
                if( addr == 0x0000 ) {
; [0 w$ u3 O5 L1 E; \                        BYTE        dummy = n106.Read( addr );
$ k' x' k1 A# U: C                } else {
( I$ ~! {9 U" O! ]6 ?                        n106.Write( addr, data );
9 q3 F: _3 V( o# J  i9 T. D. W                }
8 r8 }; n4 `5 N        }. J/ G/ c$ P# y/ f" d( N
        if( exsound_select & 0x20 ) {
2 M8 I, o$ e5 ?$ S                fme7.Write( addr, data );' q! z: U2 N2 v* Q6 p
        }
( S. j' E7 m, v. u& q}  I& C- ~& i$ F$ H' e

; U. v$ ?4 h, ~5 ^4 avoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )3 s% W/ W3 y& d' e  f; Q
{
% `: q6 U" q( h( H3 M5 tINT        nBits = Config.sound.nBits;8 {& X9 f7 t  |) N- K  L
DWORD        dwLength = dwSize / (nBits/8);
6 ]: m3 s# s; k6 l6 U! vINT        output;4 @9 Z  g$ E4 }6 j  |5 j% V/ d
QUEUEDATA q;" P7 K2 d: u0 `* ]9 T) C
DWORD        writetime;# {  c8 a% a2 U9 S4 y4 A
5 [/ \, U/ y- H' C) W! k
LPSHORT        pSoundBuf = m_SoundBuffer;- U( W7 t9 c0 v' M
INT        nCcount = 0;; C9 s5 g; S9 B

7 G. e/ z  P6 w( |& }INT        nFilterType = Config.sound.nFilterType;
0 u6 }$ \, n! ~% z& h  u8 }
* A5 D3 u: {9 X* F        if( !Config.sound.bEnable ) {1 |# M0 j) ~! `& M; z
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );& K' s- g: G& r
                return;
1 d# ]+ |) O/ F- C* y  ~        }$ M) ~) [5 n- w/ w& ^

# ~# a9 B) }! S- t+ g$ O        // Volume setup9 W4 M1 T+ C- A/ ]6 v$ D; k' E
        //  0:Master; @$ Q* ~. j- T
        //  1:Rectangle 1
% i5 X9 n! y! P4 R1 `) t7 K2 |7 N        //  2:Rectangle 2
! a( \- S, Y* D, I- S        //  3:Triangle
1 ~) ?8 k9 i$ ^# t5 s+ [        //  4:Noise. x* s) P- z. V- L% l/ l1 F; Y
        //  5:DPCM( f- |+ d" p$ e5 ^+ F# A
        //  6:VRC6
! q* Z9 C$ H7 N5 d0 I, v; K+ r! r        //  7:VRC7
( Z( ~' n9 `2 y# Y! E+ m        //  8:FDS) Z8 Q7 V1 N" W4 O
        //  9:MMC5
  m, }( z3 t, K* S8 R        // 10:N106
" W5 [. z) G6 I3 ^        // 11:FME7
5 J6 y4 G& N: C3 U2 `        INT        vol[24];
( o4 g3 Z  p9 J        BOOL*        bMute = m_bMute;  l/ D: V6 V3 `
        SHORT*        nVolume = Config.sound.nVolume;
, ?1 L4 N) D1 t3 `  d0 B& `5 ]* `. o
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
, s1 b3 Z! `, [' A. _- j; |$ i; c' U, W  m2 k/ A
        // Internal2 p# ?* c: X) u1 x- [- V0 s
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
0 F+ @5 P# U/ H8 ?# q        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
4 V' r1 ?7 M/ ^        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;9 D, T: e1 r1 a+ `% D+ k  o
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
# j, l2 @4 t, ~1 m/ F8 v        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;$ H, H+ V7 H+ U1 D/ N

8 B+ U' Y' R0 _: v        // VRC67 G7 T& N9 S' |- G& n" }5 d
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;2 c0 A; z% l; f/ E* \- W! ?
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;$ l( K7 `: y3 [3 ?; e
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;: ^' w4 \" ?5 e  D: B4 R# m
4 D# S$ j' F4 P: K* o$ g
        // VRC72 b. a" L" X: l- _3 |% T
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
$ X1 P7 w" p! c. [, b( p
8 i- u$ `% B% ^3 Z# V2 y        // FDS- A4 y' y3 Z% \5 \
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;& r& ^5 D' ]+ I. N" A- [
7 T! r4 ?, [' R5 }. u
        // MMC5
0 Y) g9 Q/ c+ I7 k1 X; M        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
/ `. a9 e" {8 d6 }! ?1 H        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
* r* U& u& H( W/ F. \        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;$ x5 J1 w! o8 m: v; C3 Q
: ^# ?( v# @+ o! @
        // N1063 v: ?2 N/ w. j6 t
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ p* v/ Y: O% D1 @" q7 p+ c" f$ X# T" ?
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- D! N2 S. u. I' A2 i/ J7 V" N        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;. `& @/ m+ o0 J' \
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ J( K+ x. J; H" N% J2 l8 @* A+ a2 H, ^; }
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
* ]. T9 s0 Z$ ]- y        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ A: p5 \# [: }$ I        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;, y; o, h; G: u* C; L. H& q/ }
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
$ q- I  g" B2 d# W3 J9 Z
0 Q& Q" D6 @* }- }% I        // FME79 s& y6 f; V9 V! E  ^9 S. e& O
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
; j7 B' [4 I* N9 Y+ c        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;1 n8 M% p  m- l5 j: z, L
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;! K* T/ B4 V) m* Y% z  F
! o' _5 _. r+ M; `9 [
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
. V5 t& Z2 A$ w: q6 I# o! o        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
/ ~" A; O+ h# A6 J) m0 Y7 `& W4 ]2 e8 ]" O3 z
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
) F9 S0 `8 l) n8 `- w        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
* o. j  x% G/ Q7 M( z8 x, l% o3 J                QueueFlush();7 z7 F3 c1 p5 \3 N- m. P5 H: S  O+ Q" O
        }3 b. S! k5 C# Z+ x' i5 V

; N) s7 S' Y% p. `! _& y        while( dwLength-- ) {) F" }! y3 E0 n- _; Q
                writetime = (DWORD)elapsed_time;  E9 ~- z4 i( s8 |% r4 t, Y6 y9 k

3 W% e/ [9 ^$ w                while( GetQueue( writetime, q ) ) {  J; S' V6 V: x6 K* k( r) X# N& |
                        WriteProcess( q.addr, q.data );" c! M9 |3 H5 r$ E6 a8 C, \( F
                }2 _. j" S6 v& c

8 a" T( _3 a- B0 h( v3 m. K' r                while( GetExQueue( writetime, q ) ) {
% e* t. i# R1 z* t! u                        WriteExProcess( q.addr, q.data );
1 V4 G1 Y) P$ R8 l9 d$ ^                }2 H# \$ q+ ]" E" p

. k2 l5 j2 {% p2 c. z  D                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
5 M( |3 W0 b5 ]- H3 X* \                output = 0;
7 k4 n9 M. d+ P' x( }" }! k                output += internal.Process( 0 )*vol[0];1 j$ `( \) z* u3 W* v
                output += internal.Process( 1 )*vol[1];
; ^0 s0 @! V) \8 ?: E+ N                output += internal.Process( 2 )*vol[2];2 }1 c5 e9 c) J4 p# |$ p
                output += internal.Process( 3 )*vol[3];
. f" s5 N' C# n& ]5 p2 g                output += internal.Process( 4 )*vol[4];
1 D3 J- e7 b9 D# K, g/ U' C# W' o2 W) g) e' _! ?$ R* t
                if( exsound_select & 0x01 ) {
& P8 V6 b6 J( `                        output += vrc6.Process( 0 )*vol[5];1 y( c& S2 h2 _5 x9 U
                        output += vrc6.Process( 1 )*vol[6];6 Y" t5 J* y9 N+ ^
                        output += vrc6.Process( 2 )*vol[7];: j4 O6 c5 i; l/ }
                }
" i9 [- T' m: F1 w# ~) U$ V                if( exsound_select & 0x02 ) {+ R* ]9 ~3 H' H# I
                        output += vrc7.Process( 0 )*vol[8];
) p% d' x; Z3 B4 {* l                }  p. R, D8 j; l$ K. i
                if( exsound_select & 0x04 ) {
- J8 z4 D* o7 m                        output += fds.Process( 0 )*vol[9];
1 T- q/ D1 n* Q' b; z; {                }+ r6 S" r/ I) Z$ F
                if( exsound_select & 0x08 ) {
3 R# i, J9 S1 e% `( X                        output += mmc5.Process( 0 )*vol[10];( R( {0 v/ O' H: K7 `3 u
                        output += mmc5.Process( 1 )*vol[11];
5 T# v9 w; ~# e& Y9 ^8 }                        output += mmc5.Process( 2 )*vol[12];7 P' e( `- T6 z8 j
                }
$ `% v4 g9 y/ T6 g                if( exsound_select & 0x10 ) {
) b4 v% j% P  }$ P4 Y' [$ [                        output += n106.Process( 0 )*vol[13];
8 q5 W7 _3 D! o6 A  O                        output += n106.Process( 1 )*vol[14];3 x4 a" N: O, N$ w: H/ T. d
                        output += n106.Process( 2 )*vol[15];
$ N+ t* r: x- ]7 }2 `/ `6 u                        output += n106.Process( 3 )*vol[16];- X; o: C9 F1 ~( o0 r& I* L- L
                        output += n106.Process( 4 )*vol[17];; T/ ~  F( O* }# A- J0 a0 q2 c
                        output += n106.Process( 5 )*vol[18];  z6 U3 ?. m/ q& P7 l
                        output += n106.Process( 6 )*vol[19];' Z" r6 \: u8 m5 q& @
                        output += n106.Process( 7 )*vol[20];
: D! V: x" ~* P$ f! w                }
4 q$ R: G% |8 C) Y; v                if( exsound_select & 0x20 ) {
1 M" G: H' s. L0 O                        fme7.Process( 3 );        // Envelope & Noise; D- N: g5 g" F( R
                        output += fme7.Process( 0 )*vol[21];
' S6 \6 V: c3 t; V( I+ o& Z/ _5 k                        output += fme7.Process( 1 )*vol[22];
: }3 ?( V$ t8 i' L8 |3 @                        output += fme7.Process( 2 )*vol[23];' C) ^6 n3 H# D/ E) _2 i
                }
: q' ~8 u/ J- r0 J3 D
. Z3 t8 g  n9 ^                output >>= 8;& K' O4 O0 V5 s  @  g8 K
9 |1 ~/ k# |) S! P  Y& c
                if( nFilterType == 1 ) {/ T6 O1 |; [# }
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
$ w" k3 b' |8 |1 E/ ^; p                        output = (lowpass_filter[0]+output)/2;
1 F1 P% O0 ^% P+ a1 {                        lowpass_filter[0] = output;7 T$ N; F4 j7 {0 g4 \, z- l
                } else if( nFilterType == 2 ) {5 ^! w0 x0 M  L' w- x
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
4 }( D) @" ~9 b# p' H; G2 j) U8 E9 [* A                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;( K+ i5 B: |( w% \2 |9 d% X
                        lowpass_filter[1] = lowpass_filter[0];. U/ s7 {7 Z8 O1 s+ ^( I' C
                        lowpass_filter[0] = output;
# ]5 D7 A7 X; k6 e) v9 A$ k                } else if( nFilterType == 3 ) {# _8 r8 }# [+ s& X0 Q* y
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)3 ~9 ]6 k0 i% J7 }* A' K6 j5 D8 @! C. \1 P
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;, W; [0 [* G9 v. U' l$ X: `
                        lowpass_filter[2] = lowpass_filter[1];
; n% I: G( k; ^0 n                        lowpass_filter[1] = lowpass_filter[0];7 e  [. u( e% j2 N7 L# Z
                        lowpass_filter[0] = output;
  v/ I8 Z; f5 C  i5 I. m6 h                } else if( nFilterType == 4 ) {
- }  q: r- w) K1 m                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)6 H" v0 a4 e# g" J' K- S- c
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;4 C' T4 A' z4 o2 W9 o- J6 Q) o0 u
                        lowpass_filter[1] = lowpass_filter[0];
) ^2 J) Y* T8 G/ O( f2 r  X                        lowpass_filter[0] = output;) ], b# C7 \* k6 P
                }
) p8 b( t8 `5 p% K: E* ^6 d* v
$ L/ [( l8 b; N#if        0* v% }5 B2 e% ?
                // DC惉暘偺僇僢僩
6 g- I* Y3 w7 S) Q8 j0 a$ w, y4 c                {
4 }/ u& s8 c. ^4 @' R                static double ave = 0.0, max=0.0, min=0.0;6 \  y% z+ p( J1 d8 ^
                double delta;% V- e/ a1 ?% {9 U9 W7 b! i- V
                delta = (max-min)/32768.0;
& A6 `  B8 H$ ?& k' }: s/ h5 h                max -= delta;& ]% [% \+ r1 H4 W
                min += delta;( x6 t8 h6 V% ?: o- x: Q% F
                if( output > max ) max = output;/ e% j" Y" l5 l/ J9 A
                if( output < min ) min = output;. U3 j6 v- k" _
                ave -= ave/1024.0;, {, a: A2 p% U! _7 l4 D
                ave += (max+min)/2048.0;: a( w8 |$ w4 D3 V. b. _
                output -= (INT)ave;
% X, O$ b& L# A+ H! G                }
0 G  n2 K. n  M+ Q8 j8 [#endif- C" x  I5 p8 i& x+ V7 ]9 k/ @% I
#if        1! o6 A/ {/ Z7 m0 R1 Z; t
                // DC惉暘偺僇僢僩(HPF TEST)+ z* W- }9 Z3 K- Y4 m  x" S
                {
" A  K% t4 O% V/ e2 A* _/ \( O9 @//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);7 J. n" n6 d) w5 x8 {7 I; I
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
3 |! S. k1 f% F* g. e$ W8 g5 X6 v7 J                double        cutoff = cutofftemp/(double)Config.sound.nRate;6 L! Z0 d& v+ K( l0 z& L
                static        double        tmp = 0.0;
$ p( y; P1 h  l% R& B! b0 j                double        in, out;! G  u+ d/ x* \
5 t: |: D6 n" G- x6 h% K9 q
                in = (double)output;
7 h3 l2 I4 ?: r6 I: q                out = (in - tmp);2 B4 }9 ?0 B: N4 m6 M3 _5 I; B
                tmp = tmp + cutoff * out;
1 }( \# w* p$ V$ g% _5 Y
' b/ c- b8 E1 j: {$ A' N; b                output = (INT)out;
( O: d8 U; d) s* o. o" e# \+ r3 M                }( T4 `- f4 Q" F! K% ]. U
#endif
4 y& M, H, i; m- k#if        06 t6 g, [0 n0 t% E2 W
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
/ R$ j( w: r% W$ }# }; a                {
9 [" a, i# @5 s# k8 Z                INT        diff = abs(output-last_data);# w8 Z7 W9 X4 F3 H" [
                if( diff > 0x4000 ) {$ J0 U7 l& H; |  _8 M8 G4 o
                        output /= 4;* B" r; C9 H2 A' h* a  B
                } else
9 w& M. B3 [) W+ G) l8 X+ _+ b2 X) F                if( diff > 0x3000 ) {
7 ]$ c/ s( U* p. \& X4 [; i5 _. ~* N                        output /= 3;5 I0 _8 B5 p- A
                } else
( R; y+ \/ q2 _5 k! I6 ]" ]                if( diff > 0x2000 ) {
( g. ?9 W2 \' w% A; r                        output /= 2;
/ B0 J/ N* J2 }7 u                }# }( w; i+ f2 T- T7 Y- D& _4 y. O5 U
                last_data = output;- \; ?  [! @. @) N# K6 g  m
                }3 |+ L  |% e" {0 C
#endif
0 L: T8 |. ]6 t- r( S                // Limit
5 {4 v) A, o5 r* K5 {. P                if( output > 0x7FFF ) {
* r9 F- S* x0 M$ r7 Z7 ?                        output = 0x7FFF;. M9 ?1 p# x  T7 l% O  z. I$ _% p2 g
                } else if( output < -0x8000 ) {
$ ~! r" I7 O- T# d5 m6 c% E                        output = -0x8000;
1 V4 q' r! `4 W( p8 V                }% }4 h  Z' k4 |$ I$ L+ C  }
8 G+ V, R; Q/ x- r! j% a& Y1 U
                if( nBits != 8 ) {
' G4 m9 O2 u9 U9 f  T/ x                        *(SHORT*)lpBuffer = (SHORT)output;3 p. b1 H+ l; d3 d) b- H0 {
                        lpBuffer += sizeof(SHORT);# F0 g( J1 }! z# Z) ^3 s( U
                } else {
- ?/ C# q: t6 W                        *lpBuffer++ = (output>>8)^0x80;  ]5 }4 V+ A, U- \" T9 }
                }
% x0 c, D/ T* `, [2 q- A1 d( U
6 O% L6 ]* W/ T* m                if( nCcount < 0x0100 )
- I* ^# H  R1 N                        pSoundBuf[nCcount++] = (SHORT)output;$ _8 Z; p3 ]- U$ L/ U, x1 E

9 t2 Y4 }! @% s5 N4 t4 v//                elapsedtime += cycle_rate;; L3 B. d% O8 Z" L
                elapsed_time += cycle_rate;6 f6 l; O( G8 C6 x$ i4 P
        }
) S9 t* C) f$ [& V
- n. Q7 `1 M$ j3 \6 _9 T#if        1
+ ]$ l6 H$ R9 ~  R& r0 s, h        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
" i* ~* p* [& T# e  n                elapsed_time = nes->cpu->GetTotalCycles();
* v$ ?. I! y' D" R        }
7 k1 b2 Y; ?5 w$ k        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {7 C$ A/ {! C& g) M+ O; I5 t
                elapsed_time = nes->cpu->GetTotalCycles();+ z1 s, W# b. b6 L; v0 w6 q8 k
        }* u. r6 a- M  J! Y5 ?
#else
0 `* r% c- z+ x- @+ A2 J0 |0 R$ ^        elapsed_time = nes->cpu->GetTotalCycles();# j) Y( K3 o8 {; E* S; N. x8 |
#endif
3 e0 S: d2 i1 B' z}+ |2 h4 \0 y2 E# ~9 R& S% k
- h2 [9 G$ x; A$ m1 T8 i% ~% I
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
( u, C7 _3 U! `INT        APU::GetChannelFrequency( INT no )
6 f9 G3 c+ B0 o& B" L% J{) U0 `0 O/ |% ^' F8 s* l  d
        if( !m_bMute[0] )
0 H! p+ X/ z/ d; v- C$ `! m8 H                return        0;! {* E. |  d; h0 @3 {
! v8 h, k! ?$ Z* |
        // Internal/ }. `+ r0 x8 P( C( q6 L& H
        if( no < 5 ) {/ f: I0 ?% L/ a- o5 X, T; a, l
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
9 I! _  v. ~# S# ~( ]+ m' @, u& z        }6 q* r6 O, p1 Z. f7 V
        // VRC6  Y4 n% Q7 b  N; w& E$ T2 Z7 m
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
# P7 L. F' O, ]3 Q                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;' p/ Q% @7 ^& L9 c# x; H" a
        }5 e8 D# M  J0 U2 c( N
        // FDS
, h2 Z) z  L, I- w) C" T! j        if( (exsound_select & 0x04) && no == 0x300 ) {8 S2 A/ C2 N# [2 S7 @1 }& ~- f9 Q
                return        m_bMute[6]?fds.GetFreq( 0 ):0;, R2 o# ~, s) h  U; @4 T' {- I# Y
        }
. ]3 G9 h& W' W2 P4 x        // MMC5
1 J5 R( k: b4 z8 W% W% a9 Y        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {8 }% h; Q: M7 \" l3 Z+ R  h3 F
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
  T1 F2 ?1 P, P0 |9 r, x6 ]- @        }( {7 L8 Q- S+ g) ~3 H
        // N1064 Y  ~. y4 q' h" u6 F" S
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
- B) [# ^& C% o5 e- t% I                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;1 M1 w- u2 g1 D( A/ I: a' Z
        }& h. m, w1 _0 S& j; ^- k
        // FME7) K. K' h& P) r3 l, a
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
. ^) D1 x6 k0 n; D: _( k4 G                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
% S& Z, ?: ^8 Y' |# u( o        }, o3 n- x" h' C6 d
        // VRC77 D, K/ q* ?2 H
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {8 |$ {( J  i: y0 u8 |
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;/ ~, Y. [+ q, G: B0 B+ m/ Y
        }
  n( ]' |. M" \7 k- X2 H, [& A        return        0;# l' A. C" h% Y8 h4 }0 [' ~
}
2 m0 t( H2 E5 P! |5 c! `
  b5 x; g: |$ K$ p: _// State Save/Load
9 k+ ^  j& V1 B- a* Jvoid        APU::SaveState( LPBYTE p )
7 k0 \) S0 M: V, f" x{
: I" R/ v! }, @' u: A+ _1 n  y#ifdef        _DEBUG
+ N7 M9 `, _# a- g9 kLPBYTE        pold = p;
+ P: k1 N6 l5 z5 c* g) f1 ~#endif( ~% T4 S$ M2 ?
5 \# D/ F( c! f- L1 G
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
( o. H! d. V& r7 D0 [2 x+ i  l        QueueFlush();
* R# q; h- n3 N3 @+ Q! P" D% V
5 a5 r& g( }( {$ J. @7 I        internal.SaveState( p );1 l. L7 G. b/ ]
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
+ U7 `9 F! `4 w: ~! P. a( G
8 g' F6 o& c+ t4 a1 U5 `2 d2 Z5 \; {        // VRC6
6 f- N3 \3 \! {$ _        if( exsound_select & 0x01 ) {: X* e8 e5 J# R) A% m1 z9 s/ j2 J
                vrc6.SaveState( p );5 x$ ^; b* p2 O2 l6 M
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
$ h) j+ a# G' H; t+ b        }- h5 n! ~; o' Q' I* R* ]! y5 t2 V
        // VRC7 (not support)- ^4 R' n% F% t
        if( exsound_select & 0x02 ) {% W; g( h' X6 o' {* G6 x' \# ~
                vrc7.SaveState( p );$ x2 N5 T) t4 I# S/ x2 o5 h
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding  J  ?( J& V! W3 B) n
        }/ F1 p2 l' V) b$ T5 h9 g
        // FDS9 u: |9 t# I" a8 h+ ^$ u
        if( exsound_select & 0x04 ) {
' O# t, t, C0 {" k                fds.SaveState( p );# r! B- {! \* R/ L0 w6 @' I5 j
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
$ R! m1 }/ _+ S: s" @  n( e        }2 }% y; W1 {/ r" a
        // MMC5
0 O" x$ n2 g7 b3 s/ Y8 w0 s- d        if( exsound_select & 0x08 ) {
7 j# _1 n% B/ w) c                mmc5.SaveState( p );3 B! v) Z* B1 H" I" Z( M" B
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding5 p2 B0 B8 i' A9 W' ^1 v4 ~' }0 `
        }
. }. c5 M! W2 n- k! Z7 u        // N106! ]4 k" ^8 }! D3 p4 [0 w
        if( exsound_select & 0x10 ) {) t5 u' g! O& P8 {. [
                n106.SaveState( p );8 n6 X: M$ O: k- l$ F% o4 t
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
8 ^- o! p- D( j        }, P3 p* C: G' J
        // FME7, j; @3 J+ F, @8 ?6 V7 k  L
        if( exsound_select & 0x20 ) {
( T( J. k0 }$ k( K$ u# ^6 v+ H                fme7.SaveState( p );
- Z$ {& g+ w' b7 _6 F( u7 d                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding3 l1 N( e4 O* Y$ @+ m. `
        }
" B/ m, o! y% h$ q& B0 v+ d  X
#ifdef        _DEBUG
4 b% f+ ?0 l) {/ vDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
/ k0 n( e  f  y% f#endif6 P* D( e3 P' q1 \
}
" K3 O) T* ~, P
, h" [# N; V9 H. Bvoid        APU::LoadState( LPBYTE p )
: ]1 I% N2 N) \9 S& ]{
2 I& z7 F) M& \& B) D: X        // 帪娫幉傪摨婜偝偣傞堊偵徚偡; d  i! u; o- W) \& w( O/ ^
        QueueClear();# ^$ E* c4 K$ d, n$ d/ M3 r' G, L

# x+ G7 T) H) N' b0 ]9 l        internal.LoadState( p );
" x, n) p9 N. l        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
; ?% u  i# A+ l0 N) c6 p% a7 V; Z5 e* t+ g& L, Q& }
        // VRC6
5 C1 q8 T; I8 J) u: L2 r' Z        if( exsound_select & 0x01 ) {9 d: C+ X# U% P, v; ~6 P5 R1 i% i
                vrc6.LoadState( p );+ E) H7 ^: k7 l) |. W  J, I: n
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding0 x$ j3 y+ u4 B5 [
        }
$ J/ n& Z; G- j3 |$ F( C        // VRC7 (not support)5 _; ]; Y+ F0 Q# M) ]
        if( exsound_select & 0x02 ) {+ A" _3 I, d7 p# F* ?
                vrc7.LoadState( p );% M# Y# F9 q' Q
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding& I8 H0 H0 S$ E0 h' F! X5 o
        }
0 q9 ^# x" y) Y$ N        // FDS
7 H9 ~% o  S, l* g2 w, t        if( exsound_select & 0x04 ) {+ K* u# I- E# N
                fds.LoadState( p );
' ^8 }3 @/ `( m$ J, }& a3 A) t4 ]                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
, S) D  {( ?, ^- k! f        }
: R; V" h+ a: X5 F6 M        // MMC5
- A0 y6 M$ F* B9 @$ v9 ^" w9 ?3 E        if( exsound_select & 0x08 ) {6 ?/ _4 R4 k' s' x
                mmc5.LoadState( p );
$ W# k5 J1 X) V) i7 g$ c7 C. }9 E                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
# E( O9 H2 N! r: k" B. f9 z        }3 w8 E5 v# E! B' B& E5 _
        // N106
9 X( H, q% N  A- Q8 q3 V* `- @        if( exsound_select & 0x10 ) {
& J3 B9 Y- x+ |: Y; c/ b                n106.LoadState( p );
2 p) N, b) ?/ _2 f                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding2 J; Z7 l1 O4 C  q) y/ A
        }- g) D9 S( V0 T
        // FME7) d2 I: O+ g# R
        if( exsound_select & 0x20 ) {
* ~( f! w( g, [                fme7.LoadState( p );' }% o( `) U- p- a7 {+ r
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding2 a+ K  Q, `8 i% L! h# G+ W. P
        }& Z$ _/ J2 ^  ~  o- p8 w* m* j
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 & _1 d3 ]+ e$ L( Y
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
% }7 g3 u$ C) c$ B: B$ h感激不尽~~

- I- n2 t, q6 o- N) y1 r2 @. y" o$ E恩 我對模擬器不是很有研究,. y! L1 ?9 I/ D, \; j$ a- }. ^
雖然要了解源碼內容,可能不是很困難,. U4 D, x8 s4 n# c3 @2 l" ^
不過還是要花時間,個人目前蠻忙碌的。
$ p/ w8 E! h8 f" P7 W1 i/ U" z: W4 _- g& b5 U& g8 E$ m0 V
給你一個朋友的MSN,你可以跟他討論看看,- F4 g2 R9 R, ]5 L" q
他本身是程式設計師,也對FC模擬器很有興趣。6 j9 V- ~4 Z. A9 y! c3 T# f) K

* Z# O( l4 q# s" Z9 |! k0 ~/ O' A! xMSN我就PM到你的信箱了。
- W% r$ J6 o6 D- a( _8 Z. a
; C/ C* E, B. y/ v: D希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表   K+ p- o0 G) O( h4 H9 _
呵…… 谢过团长大人~~
$ A5 K. q# c- Q) Z. B

, I9 J' e  q& S4 G哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
5 j0 i6 x5 `# W' {团长的朋友都是神,那团长就是神的boss。
) L6 q) s  e5 z4 j! U+ D
哈 不敢當,我只是個平凡人,
2 y. ?0 v+ A* X; z' E& c7 v& T要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
$ r6 o% A9 _. _" T5 P8 Q: iZYH
9 J8 N5 R' E; q, w# D0 D  KQQ:414734306
# i+ ]$ {- `! @0 U- _% P% R- dMail:zyh-01@126.com9 I1 N+ p- g4 L& _* s& W

. y% ^1 L: S8 r; I( b7 u7 Y他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 ; |, y1 c* ?$ C( r; K0 S) a
再次对团长大人和悠悠哥的无私帮助表示感谢~~

, i/ `& i, v% h. O6 B1 r不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-2-8 03:07 , Processed in 1.066406 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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