EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
* f: Y( B7 p# P( K楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~5 v/ ^1 P$ u* A+ i3 ^
这里有相应的模拟器源码,就当送给大侠了~~/ o4 X$ c' {: G
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 . T0 n, l. R6 c3 Z
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。, s$ M1 T0 u, ?" T" c  Q8 A7 N
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
( Z1 w$ j! [  ^4 m  w这里有相应的模拟器源码,就当送给大侠 ...
  e4 X/ k- ~* b# z4 b
聲音部分(Audoi Process Unit = APU):6 y1 W1 e' J/ c6 G% Y
.\NES\APU.cpp7 ~  [# `" p) ^; i* f
.\NES\APU.h9 x: U0 v; j3 N" ^" r1 u: |

7 P. n% F. V  a/ q1 A& I1 ]
+ _+ m' V$ W5 y& U5 @, [影像處理部份(Picture Processing Unit = PPU):
4 {- ?. U6 a: C3 Z8 C  s# R.\NES\PPU.cpp
  g  ?3 v6 z7 O$ @8 d.\NES\PPU.h
' G0 y. j  o; N% I1 {" f  d6 K1 ~7 a. t
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
& p  Z3 e+ g( B' v1 _* q( P(由于很多专用术语和算法机理都不明白,所以看不大懂……)- ?) {. g2 k# j
//////////////////////////////////////////////////////////////////////////
5 i7 Y1 a) q+ A: Q# l//                                                                      //) X" |8 o" X- U5 x* D
//      NES APU core                                                    //
  L" u8 Z# n( a//                                                           Norix      //
  U$ M  r! ~$ {5 g. M, V2 {//                                               written     2002/06/27 //
# E: }& c5 L4 ]9 T7 p//                                               last modify ----/--/-- /// O, D! g0 K( A6 J8 m- |
//////////////////////////////////////////////////////////////////////////
7 p7 I& A# f2 t" f) z#include "DebugOut.h"; J; r) W8 o" t8 T# c  R% o. T$ N
#include "App.h"
6 F. t' ?  @# }0 T8 B' L#include "Config.h"9 c! \! M7 d& Q8 E
* m- H6 }' ^2 G- D, l$ D! f
#include "nes.h"
2 j  q% ]/ p& S0 {$ h% _5 h/ ~2 @#include "mmu.h"
( }" A) t% L  E( Q#include "cpu.h") b* F/ K1 @" O$ f
#include "ppu.h"
% O9 E% {; H0 B" K#include "rom.h"' p( |" O( h% ~- Z
#include "apu.h"$ ~6 C4 s0 {9 a, S! ~2 i3 |
1 R, T$ `9 R$ P1 O3 {5 i0 j
// Volume adjust
  B4 F7 W/ P# V3 U// Internal sounds0 \# ?6 D1 o" H' {/ R+ h
#define        RECTANGLE_VOL        (0x0F0)
6 }3 i# s& E$ r4 @2 P9 R#define        TRIANGLE_VOL        (0x130)% Z" m3 v( a$ U
#define        NOISE_VOL        (0x0C0)5 N2 \! L3 m6 |, h* h% y
#define        DPCM_VOL        (0x0F0)
5 l' d8 ^. y" j1 i// Extra sounds5 _5 l# r+ o" k6 j7 k& w+ n6 ~7 m
#define        VRC6_VOL        (0x0F0)6 `! n( H3 g/ i# W" h
#define        VRC7_VOL        (0x130)( i( j, E! N+ E$ [, Y
#define        FDS_VOL                (0x0F0)3 o% \6 A" O$ f. i1 ~  c5 C
#define        MMC5_VOL        (0x0F0)
, l6 w+ @; ~; W#define        N106_VOL        (0x088)5 |% t/ z4 g6 E5 W& k, c( m* ~( g
#define        FME7_VOL        (0x130); L/ ^) q6 N* p

* X2 c# o4 j8 hAPU::APU( NES* parent )
. D  }4 d4 y$ e, b" `{' _% h0 g/ v7 V7 G* w
        exsound_select = 0;
, e# p2 B5 Q8 k& p9 E% i% H) L  ]5 w2 M* u; @' ?
        nes = parent;
2 o1 g1 R5 r8 B+ C% u& O  ^        internal.SetParent( parent );8 ?* \) M! H# `

5 Q7 ^- Y' v1 H# }        last_data = last_diff = 0;# u) A4 R( e" |) |2 `

2 _8 D6 {2 U/ ~4 i) V        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
% B; W' J: l# s7 b
2 u0 m' B2 J: Z; H! a% ?6 [/ J$ k; s        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );4 @% `! B; ?3 Y0 z& b. [; b
        ZEROMEMORY( &queue, sizeof(queue) );$ A) U2 \4 ^- u7 [7 U) s8 D
        ZEROMEMORY( &exqueue, sizeof(exqueue) );" n! P' A+ e! y* X' F( m0 _$ `
) r+ G. w0 z6 r- _# \
        for( INT i = 0; i < 16; i++ ) {; r' j( t1 k% d! Y/ A
                m_bMute = TRUE;( X& l  e' R" p% ]% u, Q9 I. h
        }
  P. ^; D% m) Q9 S3 ]# W}+ l  C" S: |% J7 u

' A0 j" w3 u; hAPU::~APU()8 X& T! H; k, o' w! E7 I3 X3 ]% ?
{
9 N) a$ X! |/ [6 _}3 N6 K& `7 q+ A( X! D

# {: r; C+ v3 v  R" Fvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )) j0 g3 {. d% h5 i. S5 h
{6 O" `6 w& z0 S5 W5 l7 B
        queue.data[queue.wrptr].time = writetime;! E% _( i- `/ C3 [: ?
        queue.data[queue.wrptr].addr = addr;
) x7 p" ^$ O- [% }& v% t- h        queue.data[queue.wrptr].data = data;
; l- X/ F9 r8 }8 R        queue.wrptr++;
- x6 z: I: y. R+ \        queue.wrptr&=QUEUE_LENGTH-1;/ S9 s, ~) ?- _! U0 y5 ^
        if( queue.wrptr == queue.rdptr ) {
; V! g8 z. H! B4 J) M                DEBUGOUT( "queue overflow.\n" );* R- A/ M0 J3 U) O* G; |* d
        }* d# n$ G  T3 F, s6 C6 m& R
}
5 Q! a/ K/ u* `
3 b/ p( n  L3 P4 X! eBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
* S& x$ h7 t" H% W{
4 Z4 J* {1 O* w3 A( q        if( queue.wrptr == queue.rdptr ) {: b, j6 X) x1 d
                return        FALSE;
  t: j7 G, t1 T* S/ Y' I        }
1 x7 n7 N' X8 m, l# M3 Q8 f        if( queue.data[queue.rdptr].time <= writetime ) {% p2 `$ y/ D+ a( ?- g
                ret = queue.data[queue.rdptr];
) h+ c+ P* a0 ^- g                queue.rdptr++;
! X/ L& b# ~3 G7 P5 h5 l7 b3 o2 d7 O9 M                queue.rdptr&=QUEUE_LENGTH-1;
. h$ W8 z2 K4 e  r# P; \                return        TRUE;$ |6 |4 Q7 O# M9 W. M' J2 Q
        }
5 ?4 h" S' b0 ?  U+ c" t" B8 w        return        FALSE;
" b5 ?" H' E- Y7 B) c}+ a6 ?4 z3 Z! s8 L) }

  {$ L& c* S& f  Q" e; wvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )8 n8 |3 |. K' M/ ]2 g" p  p
{( d/ `+ G1 t4 ]
        exqueue.data[exqueue.wrptr].time = writetime;: |; G: Q* d& v0 i( y! A
        exqueue.data[exqueue.wrptr].addr = addr;7 Z2 d8 Z% t; i( d$ ?5 ~3 [" `8 ?$ V. I
        exqueue.data[exqueue.wrptr].data = data;: p$ k/ o4 q- H7 O
        exqueue.wrptr++;
' d: }3 ^8 H6 k& A- c( K  _        exqueue.wrptr&=QUEUE_LENGTH-1;
; @# W/ {0 c  L        if( exqueue.wrptr == exqueue.rdptr ) {
3 y! Y: O5 C/ z* o: B                DEBUGOUT( "exqueue overflow.\n" );
9 z- ?0 C0 X3 N1 a+ U' v7 I        }2 D. M  [$ q5 G" W; D
}
% P6 W: J" z+ E. h) Y* D' |5 b% ?- Y4 k
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
0 \% q0 z& T) S/ ~2 P8 s{
5 j4 A! `  J, h+ g        if( exqueue.wrptr == exqueue.rdptr ) {
( E2 w, X, d; d/ C" q. `+ O                return        FALSE;
5 f! x3 k7 B: |- \        }, }1 i7 U" ^6 |/ U
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
. j/ b. c# C7 }) J. F7 y                ret = exqueue.data[exqueue.rdptr];, e, f. r3 w8 [" H0 A- j; c
                exqueue.rdptr++;# |8 W  r* z, s
                exqueue.rdptr&=QUEUE_LENGTH-1;4 c* @* D1 @; \! b7 w: ]! p3 A
                return        TRUE;  u2 l; C* m+ u: z4 C# w
        }
# ]/ i) [& e! a1 K* c& m( k        return        FALSE;
. Z7 b; b+ ~) i}- D. H' Q; S( M, \9 A! G8 s" d
. l4 ], T4 C: `- A" s
void        APU::QueueClear()
  h( Y- g2 k, V, P  g# n# G{
( b+ M0 S2 M8 H& _3 j        ZEROMEMORY( &queue, sizeof(queue) );, E/ R9 X) N, X) z3 y! Z
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
7 |# Z) K4 N" K& _2 H- T$ e}% {$ T1 s# D" V4 j# ^
4 ~  }2 t( Y% C, `
void        APU::QueueFlush()
+ _: p: l2 u$ l8 n1 _2 `" t) N{
( `$ _& I% e4 W# ?; h" r        while( queue.wrptr != queue.rdptr ) {
9 N# T2 A% R9 J0 z8 d8 T                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
5 r: {# @- `9 K0 f& ]) P                queue.rdptr++;
! ~5 W0 r9 G3 v/ I8 Y* I# I( `0 o                queue.rdptr&=QUEUE_LENGTH-1;9 C0 m) S, B4 K# u, P2 M
        }  M# m8 G" Q8 j/ N6 q! X3 @2 K

. t- |  ]9 M/ a        while( exqueue.wrptr != exqueue.rdptr ) {
$ M+ m( H: a0 ]4 _5 n5 T' Q: O- ]                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );( w1 V0 @$ X6 L3 b" g
                exqueue.rdptr++;3 m5 T6 Y3 v) [1 k9 l
                exqueue.rdptr&=QUEUE_LENGTH-1;
' ~- r7 ?# k8 R6 [* c/ ], B        }
- E& L* l- e9 e$ V7 _. u) b& S}" b) U$ y" L1 w& ?  ?8 z2 f/ X) Z

. Y  r2 l0 _0 Q) Qvoid        APU::SoundSetup()6 T" [5 j0 y2 p
{
+ Y# Y) \% ?) C: Y# h        FLOAT        fClock = nes->nescfg->CpuClock;
. s7 N* o, Y8 C1 x2 k        INT        nRate = (INT)Config.sound.nRate;
' x, U3 H- L% k$ |- Z3 Q1 Q        internal.Setup( fClock, nRate );
2 D  W+ a; R! T3 }5 e& Y  x        vrc6.Setup( fClock, nRate );
/ d3 ^) \. C# q        vrc7.Setup( fClock, nRate );
5 h+ N$ L+ z$ u        mmc5.Setup( fClock, nRate );
. A9 f2 {1 U' s. i        fds.Setup ( fClock, nRate );. i: e! F+ y1 e0 s
        n106.Setup( fClock, nRate );( g7 @) ?& R7 q+ D+ n, O# a$ e' z& i
        fme7.Setup( fClock, nRate );  _" [6 N) f5 e
}: o! R! Z  |/ z6 Q! U0 U

" K( L" ~9 t. a8 Z8 S; W. a3 fvoid        APU::Reset()" T* @) }1 \! V+ e9 m
{: c! @9 m! u* L. K; G. f
        ZEROMEMORY( &queue, sizeof(queue) );
4 u8 U( ^6 I" }        ZEROMEMORY( &exqueue, sizeof(exqueue) );
0 |  ?; T  Y5 _( O
  n  X- Z2 w9 O3 c        elapsed_time = 0;. i) |% i4 R5 {, D! a& `" T  r( t4 B

- u* l4 A& A$ s: T6 x# D' A, L        FLOAT        fClock = nes->nescfg->CpuClock;
* z2 f' b# k- s6 F9 F7 Z        INT        nRate = (INT)Config.sound.nRate;
' A3 [: W1 @, Q        internal.Reset( fClock, nRate );# Z% y2 N( @8 F" `+ r2 k! _/ D
        vrc6.Reset( fClock, nRate );
8 D' S$ ~5 G+ x3 j1 J+ ^        vrc7.Reset( fClock, nRate );$ S6 I3 {/ D8 ^+ Y
        mmc5.Reset( fClock, nRate );' b1 }3 W8 {, y# R
        fds.Reset ( fClock, nRate );
5 q2 s+ m% A# Z* q1 Q  k% T        n106.Reset( fClock, nRate );$ i5 q$ @3 J' P/ o1 l: V
        fme7.Reset( fClock, nRate );" g2 g0 j2 c' y8 c7 r

7 r; F# _  ^: L8 B! ]        SoundSetup();  \- x: E) Z( x2 _8 x/ Y- c
}
, G2 ~6 a! `. Q* |; c, q5 Z8 s' w5 A. T% X, |! C5 Z& `9 N
void        APU::SelectExSound( BYTE data )
4 P& J; U2 S0 i7 v# p{4 Y0 w8 G* ^/ e0 h$ D
        exsound_select = data;# a# m* e+ i# P3 g+ V$ j
}( S  G6 n; B; m( C9 ?1 o
  @" V& {! v9 m) P: T
BYTE        APU::Read( WORD addr )8 Q+ |% J% [7 L7 O; ^' c
{
- X4 J* q: I* X' r        return        internal.SyncRead( addr );2 ]' M! Q3 l) [9 d. R9 ~8 X4 Y
}6 g# S4 u& j4 U, P# n

/ q7 P" S- U' B' ]void        APU::Write( WORD addr, BYTE data )
4 _# i. q% _* ]8 t{' T" k: f9 r* ~' o( u
        // $4018偼VirtuaNES屌桳億乕僩4 |7 M" J: \% D& R0 o3 V
        if( addr >= 0x4000 && addr <= 0x401F ) {
; o* i6 p1 o9 O                internal.SyncWrite( addr, data );& h& H1 ^: q3 m& I
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );7 `0 D( u/ n' }; P- S+ P
        }& p3 \' c& @% Q6 |
}) T+ q  I) L0 W9 v  H

7 N) f, `  j: K0 w, U( LBYTE        APU::ExRead( WORD addr )
. `' K3 [7 _1 c- w3 g$ F{
- F5 b2 V! ]  \) ^7 tBYTE        data = 0;  `% q* Z6 r. i$ [1 r4 m) S
+ v2 R# c8 m  F9 M
        if( exsound_select & 0x10 ) {
- I/ ^# Q& S* b* e                if( addr == 0x4800 ) {: i" m4 D, S# {5 d. d
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
5 A# U) X0 R, n  w/ x                }
: {% z" |5 r' |* M, L( A        }; S5 d; ?6 R# F& U6 ]3 J$ @
        if( exsound_select & 0x04 ) {' \7 b9 r1 a0 X2 X5 x1 e0 ?
                if( addr >= 0x4040 && addr < 0x4100 ) {: j8 ]: Q2 Z8 w8 }0 d
                        data = fds.SyncRead( addr );
) V/ U  p" k7 s9 M- i2 I                }
% \* S2 D  G4 @% P# s; u: x        }
( y2 x* J# o! s& ^        if( exsound_select & 0x08 ) {
9 f1 r0 o% u$ R8 w7 r8 i                if( addr >= 0x5000 && addr <= 0x5015 ) {4 r; ^% v" Z9 e' v$ S2 B* o+ l  O
                        data = mmc5.SyncRead( addr );
% w4 X4 i" s# V0 O" c$ A( ?# m5 c                }: D' M2 J2 i' n, \, ]) n
        }# e3 B7 v6 H4 {, j2 ~* |, X2 W
: Z; s9 A; t. x% {8 Q9 ?0 V
        return        data;
' \( ]4 p; v5 m& g}
7 q# z% _/ d! A$ `4 X
% f) B9 d1 E+ g3 b% b6 ^' |void        APU::ExWrite( WORD addr, BYTE data )
4 c+ S: s7 f% [7 I{6 n8 }+ V' `% r
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );9 K6 u$ e# ^& Y6 Z9 h) X

/ u6 s7 ~& v4 O: S6 c' N        if( exsound_select & 0x04 ) {
) \* a- ?7 m, ]9 j% Y& z5 C                if( addr >= 0x4040 && addr < 0x4100 ) {$ c: F3 m# T+ K' v
                        fds.SyncWrite( addr, data );7 T. E2 O! {9 \) s4 k" g
                }: ?1 H- I. A; z1 c1 T
        }3 v' P& J. I; g8 A  G

  S; s' M* F7 f% |( N, b        if( exsound_select & 0x08 ) {
# R$ n- W% g  h/ W                if( addr >= 0x5000 && addr <= 0x5015 ) {# u$ |* C/ f, s# a3 ]* @
                        mmc5.SyncWrite( addr, data );5 L& }0 k3 A7 t4 T/ ?
                }8 \& e' D: {4 ?! ^) ~1 V. d
        }0 j& d+ i+ y. u& {/ I" M+ U
}
+ S3 d% J$ S( ?" r/ U9 m
. I5 d% N+ X$ l" u9 V% C9 w' p& l3 k! zvoid        APU::Sync()
9 c4 U/ z) c3 @0 m0 u+ B& k{4 G" }! k* Z+ s- H" n
}2 Z& f/ v/ n) Z4 ^7 J1 x
! V: R8 f4 v( L5 u) Q& b/ U
void        APU::SyncDPCM( INT cycles )2 S$ w  n$ l% S4 p7 T4 o4 A
{
+ B6 h/ _: T, I; J1 \: G        internal.Sync( cycles );0 j7 }: v  k' \3 J7 [4 N3 A8 M

% c' u" H2 b# I& w7 H        if( exsound_select & 0x04 ) {
/ T. T* L/ }' R" h3 x; b                fds.Sync( cycles );9 U5 A& A9 X* m) g
        }2 i- Y+ N6 C$ }6 J2 s$ ]2 |$ T) X; ^
        if( exsound_select & 0x08 ) {
' g, J: W; r% y7 m2 e                mmc5.Sync( cycles );9 D2 U3 k( C) y, T3 e( E
        }6 o9 ?0 @/ u' p
}
/ ?  x3 K$ ?( m* ?& r% V: h+ @; v) K  R4 a. o  \
void        APU::WriteProcess( WORD addr, BYTE data )
% h/ l! B7 E# `4 D, {{# |0 x, `5 a+ I9 e9 I
        // $4018偼VirtuaNES屌桳億乕僩
% ?  r+ h  G: u3 n, ~        if( addr >= 0x4000 && addr <= 0x401F ) {
2 W' e; \$ ~- k, I1 b) J0 p& e' R                internal.Write( addr, data );* t& \+ x' M8 B3 p+ u- q
        }
: h+ j( K6 `$ E: E1 G}1 u9 S: U" j! e' C& X

1 C1 t/ {3 W8 x' @void        APU::WriteExProcess( WORD addr, BYTE data )
  b* g/ W0 i6 {( B7 w" X$ w{1 l9 u$ Q) w! v) S/ G
        if( exsound_select & 0x01 ) {, T1 f* W* o& `7 d
                vrc6.Write( addr, data );
2 S  w. j9 X) l2 f% T6 _! \" m        }
& F- b/ |0 h  A" B' `% [% D: u+ U        if( exsound_select & 0x02 ) {( \% P7 A& t  k3 F9 S, i
                vrc7.Write( addr, data );
, p5 M. i$ N3 u+ h# l" Z7 n        }1 O. Q' Q  o) o6 t
        if( exsound_select & 0x04 ) {: e2 K) F' n5 F& V
                fds.Write( addr, data );$ F4 P8 k1 [+ a) H4 [; @1 ?
        }! P7 `5 ~, M* f( J; Y
        if( exsound_select & 0x08 ) {
9 s( j% D  t, G                mmc5.Write( addr, data );
; g( _4 D7 g8 L4 [( I8 T; ~        }
  K8 W2 r8 `- `% a- _' n        if( exsound_select & 0x10 ) {+ T' a% y0 Z/ A: l: m- x/ n* ]
                if( addr == 0x0000 ) {2 h: O, p( k# G6 z+ B5 G  K2 Q# E
                        BYTE        dummy = n106.Read( addr );
9 `7 x: n" I: e                } else {- `8 |+ x9 i5 Y3 z% i6 p% ~9 h
                        n106.Write( addr, data );
) e6 L4 \  Z. [3 O                }
" X& C7 O- ~" I$ D. ?& e        }/ _3 P% N) Q4 a- [3 Z
        if( exsound_select & 0x20 ) {1 [5 s- |& j, i' Z6 `. K( _
                fme7.Write( addr, data );
' ^* y- i, B+ e2 Q* D: k) e# W& q- W        }
5 ~) i- ?+ g1 P& H$ M( e% {! [: ^}
7 N7 x3 i, A/ n* l! {; C! L& ]7 _8 s. Q+ V9 W
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )6 D" i! |  z* h
{
( m( @2 x* E& H9 ]' ~INT        nBits = Config.sound.nBits;  n) v3 r) v: A0 l6 O4 z
DWORD        dwLength = dwSize / (nBits/8);% w  H; b7 I- H- x2 l1 B
INT        output;0 w  G. {! r' ]$ y, _/ N- M) V
QUEUEDATA q;
% D- z4 k( r. Z6 P4 tDWORD        writetime;
4 Y0 Q. X3 u1 [+ G/ X6 j7 w; B) Q8 j+ k1 N& |* Z9 G9 `
LPSHORT        pSoundBuf = m_SoundBuffer;/ {9 x- B  Y5 Y
INT        nCcount = 0;
. f$ N0 k/ F& K' l$ L6 F" |
  @7 J4 Y0 C( Z/ TINT        nFilterType = Config.sound.nFilterType;
& N% ]" g$ p0 s/ c
: l4 p4 \, R5 S& v; `$ {" v( @        if( !Config.sound.bEnable ) {7 J: W5 |; v$ l( w+ ?& |: }
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );! ^" B& u/ g4 x# R
                return;2 C7 N& c# k5 @2 ?+ t  V
        }
/ d$ V8 ~. D8 r$ F, F( @. K* @. \6 D
        // Volume setup
' p2 q5 {* ?# \3 i$ n% s  }7 r        //  0:Master5 e4 T3 x  P. f' L0 ]) O
        //  1:Rectangle 1
4 Z9 c" s; V+ I" h        //  2:Rectangle 2% m' c, [) X  g
        //  3:Triangle6 ~+ T4 O! ]% k. ^
        //  4:Noise
2 X% I5 ]$ ^7 D* [7 v$ \& ]- h        //  5:DPCM
# D' U* R8 @1 z# n, [. }* C        //  6:VRC6# I3 ?& r  M+ H- @* V2 N
        //  7:VRC7
9 f' h/ A: N3 z+ T: s0 [* ?: p        //  8:FDS
8 R2 ?# S! u; x% L' }        //  9:MMC5- _9 @) a  h! l! ?. }  ^
        // 10:N106
8 q" H1 s0 E" U$ x1 d+ Y: i2 ~5 t        // 11:FME73 s" g9 J! n( w
        INT        vol[24];
4 z* r9 l0 r' m2 j! v        BOOL*        bMute = m_bMute;
+ ]9 r, \" m0 y, `, x        SHORT*        nVolume = Config.sound.nVolume;& M+ h! w% l8 v1 h, A
3 c+ K2 F: k* l& r6 P) R
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
; n8 ]' C0 ?" s% O
2 h& K( m5 F9 {' x) I        // Internal6 F: o0 @. \( j' o
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
, Z$ _0 a4 [6 B5 y        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
+ X5 Q, Q. ]6 m% b        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;: |( g1 Q/ o2 F
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
4 B% f2 ^4 E2 S) w& K6 Q. V  G        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
' J% D# A- ~/ |( ^5 \8 s; l- `( ?) \1 F$ I( C
        // VRC6
: Y' Y  r9 n& I- {8 Q        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
6 n6 W. _- w1 |' L- x6 v        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
( c' P& a* m( B: }) |5 Q        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;% u9 w: t0 H" k

+ X1 Z0 |2 ]$ i2 J* t* ]$ [        // VRC7  K0 O' z0 H% L/ b/ u/ `
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
; I# p9 a/ {2 T  P9 l5 v9 `3 Q! s$ I; K3 T" d  w3 @6 w& M2 y2 W# K, t
        // FDS- H9 J0 |5 p6 o5 a6 L$ F) I) j+ H
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
& U, C) ]3 f5 S# h0 T1 a5 t- K5 N; v1 m3 Z# N5 k
        // MMC5
( G: O8 j; }# @/ A5 F- c9 X4 u8 z        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;+ O" L# |( {/ b6 c/ \  n3 F
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;/ D/ h7 a( |" n1 v
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
9 E5 X) v, Y: |' k1 A5 ~& V+ h$ B0 ]: Z: |3 z7 A0 c+ l  p; y
        // N106- y4 ~8 n% b* ~1 f
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, `- e2 ^/ l5 Z% O, {1 }        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;& f! }. b/ a/ O2 c! P7 C$ G
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' P, q' u9 m* y9 ?2 ^5 ~1 K" p
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;* H, Y% m7 [/ p! W7 {
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;/ T* M1 [4 ^6 P: D2 B
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
8 I- a* o; m' f: G        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 z1 x$ a. a$ L* ]) b. S$ M        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- Q8 y$ B$ Z1 M4 ~, Y" v# V7 @, @' M; O& O/ x7 f( Y
        // FME7
) U3 H" T( w1 R! B( I" l1 ]        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;" u& l& ^5 Y2 m8 u2 D5 u
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
9 i7 f3 {9 H" y9 T3 V        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;" w- Y/ L  @* S

$ L: y; S, x* d' c$ I//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;% Q& q: J# N7 O% Z& Y2 k
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
% }& d4 o; f; \6 \- \& F$ e0 w6 z6 g1 k0 Y3 F* C: q
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟. G! j% |( A/ N3 a% Y* y
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
8 S4 G' a, F! j  b: k6 A                QueueFlush();
9 p# [0 m! j5 |& L- ^9 g        }
2 n' }- ^' J) J$ a" l+ h
* c8 m/ Q6 j. i, Y: d% \; }        while( dwLength-- ) {  Z0 Z! B- P0 N. F& ]% w2 _- h. n# Q
                writetime = (DWORD)elapsed_time;
; Q1 L8 {! V/ X( j9 g: r7 u1 Z+ f
                while( GetQueue( writetime, q ) ) {$ g2 f' u1 [$ j7 C0 \: p+ e
                        WriteProcess( q.addr, q.data );
/ Z& O# G  l3 E: N8 W                }3 b- O' S) x5 i' V& J. b

  \  N9 P; E' ]3 V4 ]% ?& Z8 |8 K0 u                while( GetExQueue( writetime, q ) ) {
$ p- [6 ?& J" I; Z9 w+ x5 e                        WriteExProcess( q.addr, q.data );
0 ?# }( K5 q: ~" t4 ^                }+ U% v8 ?) f8 }: T- e' M! k

5 q% U4 ^+ v& h4 ^' O                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7' i) }3 J7 j( B: n* e. P
                output = 0;
: {3 T. r, R& M! W& e                output += internal.Process( 0 )*vol[0];* O' `& m# b6 b/ |3 k' Y3 q
                output += internal.Process( 1 )*vol[1];# ^% A; t6 v; H5 J4 o
                output += internal.Process( 2 )*vol[2];
' J  X0 o; T6 u* o$ N5 A$ e9 q                output += internal.Process( 3 )*vol[3];2 |1 P; E" g# A9 Y  ^2 _
                output += internal.Process( 4 )*vol[4];4 H3 k5 E9 c6 ?

1 n1 d% @- Q  g; g2 H                if( exsound_select & 0x01 ) {
5 N8 _3 d/ a5 N$ b+ N, k, ]& O                        output += vrc6.Process( 0 )*vol[5];7 o5 ?7 \/ M2 ^/ F
                        output += vrc6.Process( 1 )*vol[6];
$ \4 Q6 M: D' j8 u9 e+ w                        output += vrc6.Process( 2 )*vol[7];
, ]0 h. ^# G- I: r                }
( l" P# Y9 z; }; w! F7 B                if( exsound_select & 0x02 ) {/ u* }# v9 G& _8 |7 ^1 X& |
                        output += vrc7.Process( 0 )*vol[8];
1 k8 O* G9 q( O6 Y( q                }
  s! U$ E* m# |5 G                if( exsound_select & 0x04 ) {- h% v3 g% Q+ m( S2 {6 @
                        output += fds.Process( 0 )*vol[9];+ g; Q: B) W9 i- a+ X5 @
                }/ B, h4 B9 p& U+ a. ~3 A5 I
                if( exsound_select & 0x08 ) {
& C- b/ ?- ^; z                        output += mmc5.Process( 0 )*vol[10];
0 @% i' `8 V# p2 S- q                        output += mmc5.Process( 1 )*vol[11];
& _! S% e" d4 [6 q                        output += mmc5.Process( 2 )*vol[12];
* F4 Z# J& I3 A! Q$ `                }
$ c( A2 F  Y+ A8 e- B                if( exsound_select & 0x10 ) {
# b0 R' z9 n6 I4 j; \( o                        output += n106.Process( 0 )*vol[13];
0 x0 G+ a; R" F" |                        output += n106.Process( 1 )*vol[14];
3 X+ ?: z2 @) Y% g                        output += n106.Process( 2 )*vol[15];
- D8 k- K  |& G                        output += n106.Process( 3 )*vol[16];$ B4 [8 `& N5 n" [$ Z1 u; M
                        output += n106.Process( 4 )*vol[17];
' d4 h. D- ?* {1 r, R* @/ f3 D& m& S                        output += n106.Process( 5 )*vol[18];
, l0 @$ P1 ]5 Q( x  i9 x2 W; ~                        output += n106.Process( 6 )*vol[19];
  G* m0 g$ o) |; Q  I! L                        output += n106.Process( 7 )*vol[20];# u% s! A5 M0 }( N
                }
" |& T; B- R# s7 N+ [                if( exsound_select & 0x20 ) {
6 g/ w( r$ O) q( z- O* ~                        fme7.Process( 3 );        // Envelope & Noise" h% M& p: _# ?2 m' U
                        output += fme7.Process( 0 )*vol[21];6 r5 l3 B7 @0 q* r5 s" r
                        output += fme7.Process( 1 )*vol[22];' X* j7 o/ ~4 r
                        output += fme7.Process( 2 )*vol[23];$ ^6 Z" O. b4 t6 f/ ~* Z( c
                }
' Y3 x( L& x  P; L) G4 G  |8 U$ w% D' _* \. L; k. u' f
                output >>= 8;
4 E1 A" ]* n$ C) Q! g4 G$ W/ W' R! t7 \& f& r' l/ p* S. I. H
                if( nFilterType == 1 ) {( \( @; {' u$ a, B) Q- {# }
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)/ j+ A% ~1 o: A$ X% k, V
                        output = (lowpass_filter[0]+output)/2;! a2 m% n0 \! }& Q+ f3 d, K
                        lowpass_filter[0] = output;
, Y8 n! a# E: F9 }& p( u) {                } else if( nFilterType == 2 ) {- F7 x" p4 }* A$ {; V8 r
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)  O; Y5 P& |5 F. W$ `* Y1 G
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;8 e( A1 T' I& q
                        lowpass_filter[1] = lowpass_filter[0];! A% ?- q  W3 U4 i: |- I: k
                        lowpass_filter[0] = output;
/ }" G! u' r% X$ v6 b( i                } else if( nFilterType == 3 ) {
' g4 t( p2 @# g' q) C                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
8 ?+ B: u6 M* O; ?2 m                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
  B7 j, U- k/ Z5 A+ @: t9 g& h8 _                        lowpass_filter[2] = lowpass_filter[1];
- p, \! |$ G0 z$ W" |$ L: @/ C                        lowpass_filter[1] = lowpass_filter[0];3 |8 S9 ^4 N* C' k+ @0 j
                        lowpass_filter[0] = output;
: p( {4 u0 p+ K8 M8 o% S                } else if( nFilterType == 4 ) {
' \3 ?+ w; T* u+ A; s& N                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
6 o0 n9 ^# t; c3 j6 W                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
# |; G3 V* [  ?- R* ]; g! _" E& Q7 v- L                        lowpass_filter[1] = lowpass_filter[0];$ U. h* Z3 y& |7 I. M  C8 b7 Z7 n
                        lowpass_filter[0] = output;
( {1 M% K9 ~; {                }* t! B* C1 @* ]3 n/ s
. G; i+ j6 K7 B
#if        0* |5 l+ L5 B$ s. O2 j# a- k. [' o
                // DC惉暘偺僇僢僩
( k$ E  d3 g0 ?" }' o                {& e3 w& O1 m3 c3 s$ |
                static double ave = 0.0, max=0.0, min=0.0;4 g/ c% _, f) W) X$ M  F5 f* e
                double delta;
' C9 z8 J9 v; h2 H% @" E7 R% R                delta = (max-min)/32768.0;: h$ O! r. h! G3 O4 |
                max -= delta;) p5 K) G1 x/ ^
                min += delta;9 f" F/ ^" h7 u: O
                if( output > max ) max = output;
$ T9 C3 z/ a$ @! R1 y                if( output < min ) min = output;
$ T, }# u- E) S) i7 S% T                ave -= ave/1024.0;& y1 g( D; g4 c
                ave += (max+min)/2048.0;8 _5 t# ~: d  G) m' O
                output -= (INT)ave;, P4 U, a3 A/ ~0 T4 L. _3 Z* c$ V- b4 z7 i
                }0 q3 Q6 s5 e7 R$ C# U
#endif
$ N' E6 \3 g0 H; J" j; W9 f#if        1
7 D6 _9 r( _/ f( ~                // DC惉暘偺僇僢僩(HPF TEST)
: B* j: Q0 @+ P0 W                {* G- L- k5 g0 e) j3 A5 A# s
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);# H& q( }4 m' S) \# b& o; d: [
                static        double        cutofftemp = (2.0*3.141592653579*40.0);) h1 x0 N5 l7 |' Y  v/ q) R
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
2 @% S9 I- s* z, r                static        double        tmp = 0.0;
- j8 l! k( |' F; B$ |                double        in, out;# H! @, A3 q: f9 O6 R
8 e8 X2 ]# k) K
                in = (double)output;# k* C6 F* T6 f2 C% Y9 m
                out = (in - tmp);
9 y7 k. d% Y1 d% P( [  J( }/ w                tmp = tmp + cutoff * out;" M; b( l2 Z, a* O

1 M  y& n0 ^' D                output = (INT)out;4 f8 [# I( f# o( r
                }, j5 G+ M; c* p7 b0 W
#endif
' P5 r! i1 P2 u9 }+ w$ j6 B* o5 M#if        0
6 S% F# }6 D' [  Z                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)# s; q# K1 y8 J5 {" c3 ?2 i9 G
                {+ @2 U# u! K. n, T; Q1 s0 U" u
                INT        diff = abs(output-last_data);5 T1 L4 G0 K. t) @' T% j
                if( diff > 0x4000 ) {
" n8 U4 Z' m& {6 Q9 X/ ?7 L                        output /= 4;
. k) E% r) I8 h3 F  h                } else
* F& ^8 m. v3 K- `) @) u$ ~                if( diff > 0x3000 ) {
: R3 V% m/ Y: |2 A! R* _2 a                        output /= 3;
. J: t1 g6 r7 o5 {+ @                } else4 x! I: Q1 g0 b% p( _, e
                if( diff > 0x2000 ) {4 U2 h4 \- h. `8 ~) R
                        output /= 2;% a. W) M' V. E3 g- F7 K/ B
                }: ]/ A% A( B: Q! |2 V
                last_data = output;, e# G: Q% K3 A0 p5 l9 w2 G. ?
                }
9 l9 x* D/ j7 [$ d- Z4 c. V, z) W#endif+ L+ V7 x8 V/ p6 u6 O/ d- Z
                // Limit
" U" n5 |2 }5 _1 ]2 I: ]                if( output > 0x7FFF ) {
0 s: N/ W% L) u, V7 K6 c9 ^8 H                        output = 0x7FFF;/ ~9 Z) C' R5 ~5 Y
                } else if( output < -0x8000 ) {
3 \  {9 a  u+ p- Q. N1 X8 K3 b                        output = -0x8000;
* Q, k" C- c# u: S! L4 K" a/ F. H1 j                }! D7 X8 }9 j: B! M! \" |
2 U0 _, @, }) X' ~
                if( nBits != 8 ) {
1 F* |! w, b8 p                        *(SHORT*)lpBuffer = (SHORT)output;
4 |# V- r* ~% L& w% M                        lpBuffer += sizeof(SHORT);! ^9 f- w+ D) W
                } else {3 J7 l& P! u0 e3 s! J! P
                        *lpBuffer++ = (output>>8)^0x80;( v7 C' z0 A+ i( \; m
                }7 A& Y! v5 l! H& o, U" Q4 D: P% C
7 \$ r" X/ V7 x) }
                if( nCcount < 0x0100 )
; P; t2 y9 `9 A, ?+ P2 f, k                        pSoundBuf[nCcount++] = (SHORT)output;) d! V1 M9 u8 Q2 }5 `" s

% g4 E1 Q& D# I( F# t, p! f7 }//                elapsedtime += cycle_rate;3 R; O3 ^+ \0 @3 O0 \4 R7 r
                elapsed_time += cycle_rate;1 ^- G" C  o* {+ }
        }# ?2 m3 z9 \+ R* h# _, c# R

: q7 `/ j" }4 P; V  y6 _4 x#if        12 S1 t( Q3 n! j! a: |" S, H# Z* J
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
+ [5 ?; F$ o3 ]" U% b                elapsed_time = nes->cpu->GetTotalCycles();
7 n6 c- g: l8 X4 h/ W* T' Z        }
; n( R5 Y5 f3 Z) ~/ _8 x$ A' y        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {7 e* S( {3 _* ^. T6 r
                elapsed_time = nes->cpu->GetTotalCycles();. y: c& g$ Y) J
        }
7 B1 J( Y$ [$ y) F#else
/ s% L2 m8 O* j% x' \0 F& ^6 {$ T        elapsed_time = nes->cpu->GetTotalCycles();4 B5 E8 P  V8 [0 M( R* e7 y
#endif
4 c9 ]3 L( v2 N; U4 T- ^& u}4 x! d9 V$ d( O: _- Y8 S  r
, q9 u1 x7 y# }6 k  n2 w
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
) b9 ]$ i4 F0 J2 R) _$ xINT        APU::GetChannelFrequency( INT no )" S) W' p5 L9 `0 C1 I
{8 d. N, H$ N  }* s0 e
        if( !m_bMute[0] )
; X. R) {% v  |! S                return        0;( Z" }0 n* e  C/ M. I3 j. Y
9 p/ l2 Q7 I# C& P+ F3 t/ `8 I" v
        // Internal
7 x* k# x2 v& `. u) t$ f# A        if( no < 5 ) {# ]% K" Y( r, H% r
                return        m_bMute[no+1]?internal.GetFreq( no ):0;2 u3 _9 N6 Z! ?# y: o$ M
        }% C# e  b1 V3 v1 X% N; @% J
        // VRC65 [) z3 U" a1 ^4 f& j7 F: c
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {9 l2 p/ A6 h1 Z" S3 @& A9 \  Z
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;7 ]/ z/ K: j2 j2 o& J% M& L* B
        }
. P' Y! [* R) P5 ~5 C3 |" v) P        // FDS9 q6 t! a5 _1 y
        if( (exsound_select & 0x04) && no == 0x300 ) {6 s$ C; s6 @/ }5 m3 O# d6 ?$ {9 R
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
( r4 m! J% S: P. {! ~6 e        }
* x& Y- l  r5 h. M$ J/ v4 }        // MMC5
- Y" U% [5 o' c- b4 c$ S        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
7 c6 S4 V% `* T. u2 O                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
0 r1 N. _1 D# z# K" G* W        }! d- P8 T) g/ b7 \8 q* D" p
        // N106
- {1 V2 \  r1 Z1 [) {  V4 _# W. T        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
+ m; ]! u; s4 h/ }  H5 I6 h                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;1 ^$ c6 {$ a! t2 C% R2 }/ _: }
        }
. @8 V% x# u) H& Z& E8 G        // FME7
( j8 y9 M: w# I' _' q# k/ |( j        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {0 a# x, k- i5 V" u7 O2 j9 g0 V
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
& l8 J) P6 w4 K        }, [6 A, a+ x" B. [! m; F3 s
        // VRC7  \6 G8 P1 W$ N  o: |3 k, |, W  D
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {5 ^' I5 j) d1 W3 r. r4 y" W1 x
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
+ w5 s/ ?& |0 ^* d0 D4 f7 Q        }
9 k: C5 w# s/ ?; @% Y4 e        return        0;% k) `' E  |! A; i6 ~$ z+ z  j
}+ Z4 ~4 q6 Z& J$ ?) v) u) z" ?
, ]% |. s$ X( R" x* E
// State Save/Load3 }( i5 f* [4 A8 x; {( t6 z. [
void        APU::SaveState( LPBYTE p )8 n' s/ }' E+ o( v
{# ?& z* s& I9 H& f  j$ L8 l. I/ R
#ifdef        _DEBUG
- _# g& G) p3 j7 b8 g  G0 PLPBYTE        pold = p;
9 M# K6 L9 F9 `$ n$ ], ?#endif
! [+ c! y. L  @$ ]& N: J7 L; i. B7 z6 G/ W0 ?- ^- n
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞8 i5 o( ^9 _. h! H9 w
        QueueFlush();
( ~( I' I+ Y7 N; J9 z& B; r
3 a' p. Y+ y# y        internal.SaveState( p );) m3 v1 S. C% E/ q
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding" B, m$ |. o' X" j) }

: f& |* s3 H, x$ l8 Q        // VRC6
4 ^' V* J) [2 _# v        if( exsound_select & 0x01 ) {' P/ D5 |8 ]6 T4 g/ K( E
                vrc6.SaveState( p );( |2 W7 g* a& a* R: L4 T1 g8 B
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding4 ^; F, B6 G. ?4 l/ f
        }
9 \' R5 D# M( o) |# f        // VRC7 (not support)
( r1 u  L# S4 x" E/ n' k- i        if( exsound_select & 0x02 ) {- Z3 B- J8 P- m( B+ f. {
                vrc7.SaveState( p );- v3 B5 J  k6 f, Q$ s
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding1 E# B6 V9 x% V9 {- C' ^, F" L
        }
+ N! D7 R* l1 p9 R$ B/ P9 ~+ i        // FDS
: ?+ c3 S3 u3 o  \, g        if( exsound_select & 0x04 ) {3 E6 @$ u; [( b$ h* X7 |7 b
                fds.SaveState( p );+ T# M$ q! J6 x2 D: [
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding; s) ~8 [+ v; v, i5 w8 D: j9 H' Y
        }( |8 d# E, z/ e  k
        // MMC5+ ?3 y6 |* G9 G/ r* ^
        if( exsound_select & 0x08 ) {
9 L1 C* O' s0 b* J9 _+ p/ j0 l                mmc5.SaveState( p );1 o  i- V" m2 P+ J, ~
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding2 `/ W* N/ I, u, h1 }3 z( e+ k
        }
. Y  {4 v. Y9 a1 d( q        // N106
; I! |2 ?4 f  c& e        if( exsound_select & 0x10 ) {, q7 Z4 L! g; x1 m# V8 T
                n106.SaveState( p );
: V9 C, G  j6 _. U* ~+ i! K2 }                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding# I" x1 E9 a6 Y" y+ P
        }
; ?- w% C/ e- a& ]% `        // FME7
) ^5 g$ g' d  U  n! f        if( exsound_select & 0x20 ) {) M3 [, e$ r5 i+ K
                fme7.SaveState( p );
! C! V/ Z- l1 F8 E0 j- \                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
! Z# ]' [& H! F8 E        }4 v5 F8 Y, i1 o) O
. b7 b7 G% \; ^
#ifdef        _DEBUG( R0 Z4 l& l- b6 X
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );! u* ^5 N; [' R) Y
#endif
2 _3 Z* }3 C2 x+ z! o}
- Z2 a; m7 r& x, l) r' {6 y! y9 _, {6 }4 g
void        APU::LoadState( LPBYTE p )* w, z  [% `: U0 |4 A
{
* u" a  y4 d* t) u9 y        // 帪娫幉傪摨婜偝偣傞堊偵徚偡* g& i  z# r$ P- X: b% D+ o
        QueueClear();
1 z" l9 C" o1 ^9 K' ^, e
; E" M" A- H- B/ n' V5 T( X2 R        internal.LoadState( p );/ ]4 D+ H/ x' }
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding& j+ |" b, d% v; V

7 a. }6 V1 \1 a! y* ^; t: e        // VRC64 ?+ c, L/ T# }6 h% v& W/ }: x
        if( exsound_select & 0x01 ) {
- u1 C/ Z, F+ T3 I3 E                vrc6.LoadState( p );' t* _2 m3 F' N$ Z
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
* j; p' s  }9 j0 R+ ^        }
4 l+ T& X. _# n8 U" y  |; R  f        // VRC7 (not support); V8 G# k# O. A3 W$ r' F. Y
        if( exsound_select & 0x02 ) {, c! }' V( `) K+ Q
                vrc7.LoadState( p );$ ~& Q1 w7 R% k4 y
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding: m. k- v4 i8 Y4 M/ ?- t
        }$ O7 W* X1 q3 ]# U4 M' X' g
        // FDS
' x) L2 s& G1 |$ X        if( exsound_select & 0x04 ) {
( Q0 B$ G+ ^0 l2 ~                fds.LoadState( p );
" q5 J; M+ n/ Y, I- S9 t' F' k% U1 A                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
* C+ y# ]2 [# @' j        }  c; `5 N- |7 z; d
        // MMC53 m0 F0 }) `7 S3 t
        if( exsound_select & 0x08 ) {
5 G3 A  e9 E0 [: I                mmc5.LoadState( p );3 f# S0 k5 `; z3 h) q. j
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding+ ?6 E. c% J8 G
        }
* k7 B8 J! }$ d& q7 Z+ D" v        // N106
& \/ z( Q" ^' y- r7 k& ?        if( exsound_select & 0x10 ) {. A- T4 l% O9 u' Z
                n106.LoadState( p );
# a( }' I8 y/ z% p3 p2 S                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding1 F/ t% \% D, z  `* X  L* @" ^
        }
* z. e) A! _; S# `) h        // FME7+ A! [" @1 v& M. Y
        if( exsound_select & 0x20 ) {
, [! F* Q4 i' C7 T* X                fme7.LoadState( p );
; @7 z. M' X! f3 O8 s( J# K1 E                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding1 T! T% E; f$ e6 ^& w
        }
& z( v9 v! f8 p1 s( N) ^}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
) R. K0 B' L4 C, f可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
+ S+ Y* B; b2 x  i) `* k感激不尽~~

6 u  w$ ?/ l; [1 j5 B9 A恩 我對模擬器不是很有研究,
/ @+ [, A, u# u( [# F! s. ?/ l0 D1 g雖然要了解源碼內容,可能不是很困難,
( k2 Z# ]: |* ^' t1 K( X* N不過還是要花時間,個人目前蠻忙碌的。
" l$ m1 e) z9 y" e( p3 v( t
* ^, W! G% [# O' Y! \給你一個朋友的MSN,你可以跟他討論看看,) ?. |) h* t% z( n2 ~( P9 ]4 [, z
他本身是程式設計師,也對FC模擬器很有興趣。
, y4 c0 e6 M  R( {( k+ B
6 a0 E- A& v7 P) ~8 MMSN我就PM到你的信箱了。1 k; {1 P6 D& I7 X# L7 ^9 H
; B- P$ E( J) V1 b! C" W
希望你能有所得。

该用户从未签到

 楼主| 发表于 2009-11-9 13:23:59 | 显示全部楼层
呵…… 谢过团长大人~~

签到天数: 80 天

[LV.6]常住居民II

发表于 2009-11-9 16:02:29 | 显示全部楼层
团长的朋友都是神,那团长就是神的boss。

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表
- S  Y: h' u/ j! l  ]呵…… 谢过团长大人~~
; i- o* E, X8 g' B* o" f0 u) v

8 _' l' q2 W/ Q) q$ M0 V7 `- _哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 9 x& P5 x( K# @, z3 N" d& D
团长的朋友都是神,那团长就是神的boss。

" A6 e& I- M  V. H* K# ~哈 不敢當,我只是個平凡人,
9 ^; R( |6 ~& [- ?7 r- a8 s9 i* d要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
0 l5 R2 F3 J# c- A0 a$ MZYH
+ x; N' U/ V7 X! J8 D( uQQ:414734306. _- C1 S# ]6 u6 q: T7 f4 m
Mail:zyh-01@126.com7 o$ y6 M0 U* Z. Y: q, j

" T4 w5 e: w* W4 @他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 8 s1 r: _- o1 C1 y
再次对团长大人和悠悠哥的无私帮助表示感谢~~
/ u; |, Y" y' e, n
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-12 01:03 , Processed in 1.089844 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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