EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?
, `' E( U4 ~5 }4 f- [) ]PS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
+ K% M2 A) i- F; v  T& P# ~楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~3 h  L0 `, b& x" t9 w/ m" I; p
这里有相应的模拟器源码,就当送给大侠了~~! c: S8 o& n- }: ^
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
% P; n! i" G  L, Y; b能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。( v8 T7 ?1 }9 x  u
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~4 o5 V8 X$ _0 P0 V
这里有相应的模拟器源码,就当送给大侠 ...

1 p+ a/ c% {8 h% \8 |2 T5 ^聲音部分(Audoi Process Unit = APU):
0 ~6 W2 h$ X  c' x  `5 E.\NES\APU.cpp
& D+ u( o: C6 _6 z.\NES\APU.h
" o, o& I  r, S7 U0 [  t3 a8 T1 R1 f; z

. V1 H0 F7 P& u. E/ z影像處理部份(Picture Processing Unit = PPU):' d2 ~3 K, z: _! e: S  i3 {
.\NES\PPU.cpp
, m- q7 ^4 ~$ D4 u.\NES\PPU.h
, N/ g* S6 j1 \2 L2 x! D8 `$ _- l; v* ^0 h) g1 L, W, v) p, e
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:! n7 U: g5 Y5 E
(由于很多专用术语和算法机理都不明白,所以看不大懂……)+ @/ V  K' h: {
//////////////////////////////////////////////////////////////////////////
* Y& s! m# }4 N% E# H% V//                                                                      //
8 k1 M) o7 O# [& t1 E2 u//      NES APU core                                                    //! m% N' K! \2 F5 |1 l( t& l- ~
//                                                           Norix      //
1 ]7 x% \. l3 ?! ^3 p1 c//                                               written     2002/06/27 //5 M/ B/ M$ k1 }  w1 I! |
//                                               last modify ----/--/-- //
! H( [5 `+ \8 v% g+ Q' D//////////////////////////////////////////////////////////////////////////$ H) l1 @& Z& s, Q. L3 ~0 }( A
#include "DebugOut.h"
" h, O1 G7 ~, S#include "App.h"
; |5 m2 H  t7 q3 D& j: [# o" _5 D#include "Config.h"
4 r# ^: N2 z# h& {" U: i# ]! ?' b) a" z8 Q/ U, X3 X
#include "nes.h"
6 U4 I6 ]. H2 v( O: E5 {9 F  I#include "mmu.h"* g0 ^- l( }4 U, Z; z  ^# l
#include "cpu.h"
) W5 Q/ {, P" }- q1 p9 B- z#include "ppu.h"2 o/ ^9 f; L& R- o
#include "rom.h"
5 v9 A- z/ c- I4 W# L: ~#include "apu.h"
" E7 ~- I& c  w& x
) S- p+ K7 g1 H" u// Volume adjust
3 h  W+ M' K# b6 g// Internal sounds
5 Y3 P, r$ Z4 R* o% j# i, }#define        RECTANGLE_VOL        (0x0F0)
2 m3 F- v! Y; R* ]0 J" U% q, v9 C" X" F#define        TRIANGLE_VOL        (0x130)
( j2 `/ a8 \7 g2 K#define        NOISE_VOL        (0x0C0)
) c5 `8 H1 X; W9 X" X/ N& z#define        DPCM_VOL        (0x0F0)
" {. s$ l: Y- V1 c3 S// Extra sounds
6 h: O4 k1 I- N8 b9 ^9 l#define        VRC6_VOL        (0x0F0)
% I* ]& [2 y; X  {7 l% V( j#define        VRC7_VOL        (0x130)
" L% U$ l0 a. r) w! e#define        FDS_VOL                (0x0F0)
8 Y. G4 ]& h/ b9 ?9 y5 B$ j8 T#define        MMC5_VOL        (0x0F0)% U% C; p8 w. ~8 e1 w( W
#define        N106_VOL        (0x088)
( m" `  b7 @6 X#define        FME7_VOL        (0x130)6 Z: `3 r8 e* x* }# B, A' G
8 w  C. K% Q5 o& v1 Y
APU::APU( NES* parent )$ f' B2 K" l7 ~' f# ^
{5 h! w7 @. n* X/ B& |4 {) y% T
        exsound_select = 0;
& l  C& e+ _' c7 c7 r, H& _9 b( @& t% q, f# R. I6 g) ~
        nes = parent;
* k/ P4 `/ _4 [# y* _        internal.SetParent( parent );: J8 B- p; m8 {

# J+ d6 G- Q+ C& L        last_data = last_diff = 0;
' Y' @* l4 k: r; ~. f, c2 E% N  I$ p' a2 N" _
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );/ Q8 c/ C) [4 m9 K8 N

# K( O2 I; r' M+ {' q9 z0 j        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
' ]0 q1 W1 f# Y6 S1 F$ X2 T, h        ZEROMEMORY( &queue, sizeof(queue) );4 c8 r4 c! Z& L) M
        ZEROMEMORY( &exqueue, sizeof(exqueue) );* w* I7 E% b' x9 a9 ]/ \
8 S7 @' y: {! p9 b
        for( INT i = 0; i < 16; i++ ) {& X# v! k/ ^& g; Q% R# X7 r
                m_bMute = TRUE;
7 D+ F# S/ i8 \( t8 Y8 n$ }/ L        }
- H9 A) `* [9 N  U0 j$ Z, V; K  f}
1 O# r; l) R4 ?3 q2 N
. f8 l- x8 w( o2 e: aAPU::~APU()
, s- u0 k6 Y: b3 v{" U1 S6 P. a- l9 I+ I, B' v
}
6 k! ?  o' f* B: g7 ^$ X  [( g
: \0 D" O. `  @0 x9 [" @void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
* y2 j# ?- C) r' [1 ]3 p  q{
, ~' Y$ l# [' b! l7 d% W, ?        queue.data[queue.wrptr].time = writetime;3 R; b# c( y* p) Z/ q1 w+ q; \3 ]- \
        queue.data[queue.wrptr].addr = addr;
5 c0 U8 ]( J: T8 t3 m1 Q1 T        queue.data[queue.wrptr].data = data;
( q# |+ m; K7 x0 \5 `% u        queue.wrptr++;" B, E. k8 t; F+ w7 e
        queue.wrptr&=QUEUE_LENGTH-1;
2 M/ G! N3 A, ~0 Q* i* d- s        if( queue.wrptr == queue.rdptr ) {
8 ]! g& P! P5 r6 ]                DEBUGOUT( "queue overflow.\n" );
1 G( Y  i2 C' A. a8 Z+ S        }
: ?% R& m% Y0 o! R  n" K}
! i) Q9 Q* v0 z8 p  N/ W, y/ U/ w, l# l" |8 P  R( e
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )0 @% B3 }% |  s8 y( b
{
. y; B8 T$ o' {4 u. }        if( queue.wrptr == queue.rdptr ) {; D* A2 b5 b% E& z
                return        FALSE;' z1 b; h- x  b. D, X
        }& z+ A5 c! l+ }! J* o3 q5 t( J
        if( queue.data[queue.rdptr].time <= writetime ) {9 {$ x0 v& O9 N% e1 n
                ret = queue.data[queue.rdptr];
, I2 b& n# ~0 W6 z                queue.rdptr++;. V# U3 G+ n  s1 @
                queue.rdptr&=QUEUE_LENGTH-1;( I1 |" u$ p- m+ [: X% C9 l  s4 }
                return        TRUE;
' A! Z1 |8 f0 M! g1 z- X        }
) D! o- g* k8 m) v2 j        return        FALSE;: p4 Q7 U% b9 E/ y5 n) F4 C
}+ @) _8 w. [8 N/ N2 L+ ?
" k) b/ y) c, q0 V7 c( E9 k
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
6 u  H# L2 h$ t' O7 q# @0 M) L{2 o+ g! k8 X  \- J
        exqueue.data[exqueue.wrptr].time = writetime;& l5 _, d4 m2 h8 g
        exqueue.data[exqueue.wrptr].addr = addr;
6 a9 L. r) b5 D) X- h$ E        exqueue.data[exqueue.wrptr].data = data;
6 a$ P. Y6 Q- @4 K        exqueue.wrptr++;
$ P3 m, b/ z% r, P! p7 X        exqueue.wrptr&=QUEUE_LENGTH-1;
; a2 U0 Q& c: z: t" v        if( exqueue.wrptr == exqueue.rdptr ) {
- A+ ]& N6 a/ _/ Y0 C6 N4 }$ Y                DEBUGOUT( "exqueue overflow.\n" );
3 M+ W0 `+ g1 K) Q$ V0 ~/ \. w) V        }% Q/ r- N6 E* V/ P
}
& J# R; T6 h# }/ g) E8 ]3 I
' b0 R1 M: e- a& f( t! f7 xBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
; v3 Z6 h5 _3 E4 i{, U; N, ^4 G& l
        if( exqueue.wrptr == exqueue.rdptr ) {# F2 t( R, [* o; p$ V8 \
                return        FALSE;
& P; y4 ^  f4 _6 s3 S5 T        }  ]* V9 }1 g" W3 n6 ^  V0 P! {8 ?
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {+ j) ^4 [2 Y( _( i$ g2 z! v- ~
                ret = exqueue.data[exqueue.rdptr];
8 a: p( b( m, h2 e% {                exqueue.rdptr++;
( O. u5 @# g! w; O                exqueue.rdptr&=QUEUE_LENGTH-1;
' _* J: A* Z0 M4 W                return        TRUE;: M* M) I& p! e, L: E
        }
) k3 y  V! _7 ?3 C        return        FALSE;
# |7 I, C5 _1 O, F+ R, z7 A; `}
& v# O! S" ]/ U2 T+ z/ x: b0 Z8 o  x
void        APU::QueueClear()
7 k# m: R; s6 {. h2 W4 @6 v{# v/ y$ L' A0 M+ a
        ZEROMEMORY( &queue, sizeof(queue) );; `) p8 B' U, }! n& D
        ZEROMEMORY( &exqueue, sizeof(exqueue) );8 K- y& a' I: i5 P9 z; A( ]
}
9 w! }( t/ R; q# T
: K$ ~4 Q, L' A, c$ O. nvoid        APU::QueueFlush()
; k, e: v' }* |* Z- b) V  p{2 R8 O9 ]# M8 f! `( X) F
        while( queue.wrptr != queue.rdptr ) {! C6 c8 w8 s* T& k2 T: E
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
9 h' N5 F5 k* k/ @                queue.rdptr++;& U4 V, \9 S) K6 F3 \) L
                queue.rdptr&=QUEUE_LENGTH-1;
7 U) n7 i( f) @, e$ d        }
4 |  q* b( C6 K$ y' b$ ]5 m
4 H# o! Z8 X# }( u        while( exqueue.wrptr != exqueue.rdptr ) {" ~, k- n- |5 h9 l
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );; ]( z- s. Y7 Z% Z; Z2 F/ u
                exqueue.rdptr++;
( i/ D2 n6 C$ W- m/ D- s/ B                exqueue.rdptr&=QUEUE_LENGTH-1;
; p4 V; b" P& g" ]& h: E        }
( K8 g! M. d4 ]}  d9 q* K& L. ~+ b4 Q8 ^' W/ ~
6 d3 `1 Y2 ?9 ]. n' _, s7 L( G
void        APU::SoundSetup()+ [/ h! [( |2 N9 c
{
) _+ J* l# ]) L( F  t        FLOAT        fClock = nes->nescfg->CpuClock;3 Z9 \* E3 n9 t- J
        INT        nRate = (INT)Config.sound.nRate;
- u3 p; k0 K' s7 {/ o& B        internal.Setup( fClock, nRate );
3 u/ B" w" w$ G7 d3 Y0 D0 G2 d6 H        vrc6.Setup( fClock, nRate );1 P( w! i* ~. L5 D) z/ r- c
        vrc7.Setup( fClock, nRate );# x( m! u! ?0 E  A; b% Y
        mmc5.Setup( fClock, nRate );
2 ^# N( Q' v9 g1 i6 ~' ?; Q        fds.Setup ( fClock, nRate );0 S& k  F; V0 d% l! h& M$ C' t
        n106.Setup( fClock, nRate );# y, c$ u# w+ Y
        fme7.Setup( fClock, nRate );
1 E# c7 c  e& O}$ s5 V6 P1 l+ R6 I8 r7 ^% ~# [5 H

- \5 b4 P; }+ h3 p+ P/ Svoid        APU::Reset()
1 T/ e' X; T; e) V# q{5 W8 A# f  g+ Y! T
        ZEROMEMORY( &queue, sizeof(queue) );
* G$ g/ h& @$ F3 w$ @/ ^        ZEROMEMORY( &exqueue, sizeof(exqueue) );
! n& R0 a# s1 I- O
9 W/ Y. w1 f/ F% d; t2 R2 N        elapsed_time = 0;
3 _- o/ a0 X( k9 F, q! T6 O8 a! t( m" N; a; z' s, A0 ]9 q
        FLOAT        fClock = nes->nescfg->CpuClock;& J! N7 E( G- k2 L0 @) {
        INT        nRate = (INT)Config.sound.nRate;
/ \) M' W  y9 t! f% E        internal.Reset( fClock, nRate );
1 \+ R0 r: c3 y. R4 X! v/ X        vrc6.Reset( fClock, nRate );
/ z: ?$ m9 b' X0 O) r        vrc7.Reset( fClock, nRate );
/ W5 h  I+ c. R, Y# u        mmc5.Reset( fClock, nRate );
4 [. S# z: G, _        fds.Reset ( fClock, nRate );
/ S! _5 {! L, l' t4 b+ [        n106.Reset( fClock, nRate );1 _0 Q* d  L8 m$ j% V4 s* C# V
        fme7.Reset( fClock, nRate );
/ L. G- e( _% X$ w4 F% J
+ h1 F7 J' z) b4 {/ M        SoundSetup();0 V5 T( J4 y$ I5 s3 h7 N; X# x. X
}
6 C+ [; b! }1 V  O9 G& ~9 C7 J: ^3 y* A" r/ X
void        APU::SelectExSound( BYTE data ): g+ \. n/ t5 Z" D; |
{
8 O  t8 B! m3 h        exsound_select = data;
; G0 A# ^  p8 Q0 b' W' v}
- K2 Z' K1 I4 L3 S( W1 R
1 x& x; n; v" gBYTE        APU::Read( WORD addr )
2 p6 P0 ?1 E5 d' I; V{' Y6 D' g4 K0 S  t- T4 |' _
        return        internal.SyncRead( addr );
- n# j$ [  v; U* Q}/ Y4 n2 d2 C9 G
% M- e: c9 F3 C  G+ W% U
void        APU::Write( WORD addr, BYTE data )
9 P% d  a" T- F{
1 k. P! D1 N1 ]0 y  s& y1 O        // $4018偼VirtuaNES屌桳億乕僩0 A. f( Q0 z8 p$ ?2 V" M
        if( addr >= 0x4000 && addr <= 0x401F ) {
  P5 P) w  h- j7 ~! m+ D. }                internal.SyncWrite( addr, data );9 s6 l+ d  U% H- [4 r0 T( K
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
% z1 T( U+ z# n2 a/ p        }' H' n9 \! A  [
}2 a8 e, m$ x8 U8 c" R

# L2 R  F0 N3 f8 l; |$ CBYTE        APU::ExRead( WORD addr )9 L: `, n' ?. y: V- R0 E
{" B5 ?4 `" M: r5 j+ e/ C* ^
BYTE        data = 0;4 t0 p3 b- j$ g, T& d! c+ O4 `
) N; F+ ^' C' F# A; w" d0 D+ x
        if( exsound_select & 0x10 ) {/ ], }1 ^5 U" ?& ^/ r2 ]2 @8 b# T
                if( addr == 0x4800 ) {# t1 w9 V; @, a- m
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );% x8 a* H( R/ h- o4 ^
                }# F" d" F+ [$ m( `9 {# i
        }8 J# |" f& J1 D4 v7 [0 Y
        if( exsound_select & 0x04 ) {4 E: Q- x8 x! \  Q( x7 d4 O
                if( addr >= 0x4040 && addr < 0x4100 ) {8 j# v; f. N5 W- T6 D$ [
                        data = fds.SyncRead( addr );
! v  f, ], _* G) D2 k4 r                }$ f( G$ H% J+ o( |
        }
/ K; D8 G  @1 W6 `        if( exsound_select & 0x08 ) {0 ], ^8 D, J4 _
                if( addr >= 0x5000 && addr <= 0x5015 ) {
; {6 `3 c8 M8 @) g# }                        data = mmc5.SyncRead( addr );3 T% u1 O4 S4 Z; r
                }: p. ~# x- Q6 W6 X
        }
: E& p: l: d7 ^' b# e7 {) R. x/ p4 t: |4 e* J( J' a6 M
        return        data;
3 P# [; V1 P8 U/ G- Y7 h- n}: l2 s! e" C3 K; S

+ W0 i$ z. a; O7 zvoid        APU::ExWrite( WORD addr, BYTE data )% w# ^+ M& v/ [/ G
{
8 l2 l+ F( T( ^        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );/ x% u  L+ F$ N% S

! {' B1 F0 q" A        if( exsound_select & 0x04 ) {% w% n- l. p; n7 U$ J& `
                if( addr >= 0x4040 && addr < 0x4100 ) {( {* B) P$ O$ [6 k* l% G
                        fds.SyncWrite( addr, data );
; y5 C( |/ A9 s9 b                }& W# Q# m5 K: m' H* c
        }7 J: d% @5 L# J; m
4 ?$ Y6 R( }% A4 \
        if( exsound_select & 0x08 ) {$ F* ?* j& H" D" k) b& ?5 e# Z  c
                if( addr >= 0x5000 && addr <= 0x5015 ) {
/ `1 D! Y+ p% e5 c# D                        mmc5.SyncWrite( addr, data );. @' X5 x- s: S  \& u& U( J
                }
$ ^9 L$ l7 M1 I- j" q0 _        }: h4 D( f/ d3 {/ w
}' [6 C8 N& @" i* N7 X

: k$ L; Z: F3 P1 Gvoid        APU::Sync()$ K: T5 j: U; k3 j
{  {* P0 k# c8 K, M, B( b
}
- C: t1 s# |$ ]6 n/ [4 J/ V5 m" a  O3 g8 k( _& r$ l  q9 C( r2 s
void        APU::SyncDPCM( INT cycles ); C6 i# y3 f% ]
{  x: r3 p( l* N) N
        internal.Sync( cycles );
1 B: O9 b' J( s% t: @
4 ]3 e5 U) {6 D: e        if( exsound_select & 0x04 ) {
. i2 [) O9 l8 u9 g( b% L' z) r7 ]                fds.Sync( cycles );
7 U; _9 [0 ]9 O        }
" d3 M  D( u+ Q% t; F2 p        if( exsound_select & 0x08 ) {2 i, g7 v% V, B" X1 n0 _1 Y7 d2 S: [
                mmc5.Sync( cycles );
! p% @/ @" a/ V9 \' E5 h        }$ k& y, S' D6 {* O5 _3 q$ x
}
% ]5 F8 G' C$ N" X/ X% ~( V2 A; s& x1 y& e  R+ _( d% S% q
void        APU::WriteProcess( WORD addr, BYTE data )' T% _9 C' y  @6 o, V
{: b: A4 w  a/ a9 D" J
        // $4018偼VirtuaNES屌桳億乕僩" i0 I4 ], n9 ]; V0 _, h
        if( addr >= 0x4000 && addr <= 0x401F ) {
$ a+ j8 b/ n4 \                internal.Write( addr, data );; w1 {. f& J5 c
        }
5 u5 j: C5 l8 X7 `}
/ M% W) `8 o& }' z
0 r2 ?2 O4 n7 Z$ _+ M, P3 qvoid        APU::WriteExProcess( WORD addr, BYTE data )
* w' D; U& |6 {7 z3 }{  n- r7 E; B; {! g2 L
        if( exsound_select & 0x01 ) {
  i7 h4 f4 y7 @3 a% a                vrc6.Write( addr, data );6 l4 p, W( L6 a; M# s* V+ G' R
        }
5 b, x, D. C( a! w/ I        if( exsound_select & 0x02 ) {1 w3 k% p& R9 h  J/ J
                vrc7.Write( addr, data );
4 a4 x8 H4 S! r! ^; F        }
6 p# b, v, z) i/ y) _        if( exsound_select & 0x04 ) {
$ K; W" @3 l) r- ?; r% i% H% B                fds.Write( addr, data );
" K, {' R/ F  f3 P        }
6 H; }# u. p, m- m2 }        if( exsound_select & 0x08 ) {
# o" d6 y4 a5 i& N6 I6 u                mmc5.Write( addr, data );3 L* v/ O3 l6 M7 W( N- U
        }( l' J8 i( Y7 ], P7 ?% h7 |
        if( exsound_select & 0x10 ) {( ]6 K! x6 ^. k. o1 m; Q- e* y
                if( addr == 0x0000 ) {' W6 X5 G8 I8 g( O$ D5 n) o
                        BYTE        dummy = n106.Read( addr );! V( H  `/ {4 @+ X) ~3 `
                } else {
% q8 n' O/ d+ E$ m2 s, \; k  H                        n106.Write( addr, data );1 _8 {0 [9 @- `5 ~' E  ^9 M
                }% {( e# Y6 R/ R0 A, S  |$ c* s
        }
/ u! q: g2 U; H2 h5 W6 U  @: P4 q        if( exsound_select & 0x20 ) {: o1 f9 S* n2 ~3 F% f
                fme7.Write( addr, data );7 w1 s# r( g; f& R$ d; `5 }
        }
/ T$ Z$ i- N2 M: G2 q( @$ C$ p4 ]}* K* a( ~: G7 I8 D/ F# R

! h/ _# O/ r4 Y$ x# ]. e2 pvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )# g1 {2 d$ p5 j# h* n1 X8 s( T
{
9 B9 a4 t0 a: i" k0 dINT        nBits = Config.sound.nBits;
1 F) B) g9 R; i- l  x( kDWORD        dwLength = dwSize / (nBits/8);7 W' _* m, o: _; _
INT        output;4 b% A! ^  ?" Z; d6 T$ k
QUEUEDATA q;
6 N7 r( i1 C8 T6 S* z  n1 KDWORD        writetime;
8 v" }2 C0 W- y/ L( |! w/ r
3 B) i3 g2 g* a9 }) n* x- |LPSHORT        pSoundBuf = m_SoundBuffer;
3 X4 i' W1 i8 t5 I+ GINT        nCcount = 0;; t0 A% \) d6 d6 A; I0 n

5 c. x: G" w+ ^INT        nFilterType = Config.sound.nFilterType;3 S2 J8 _8 g, o% z# u0 d
) Y9 M" B$ t: p
        if( !Config.sound.bEnable ) {
+ \9 o0 s6 {& K# C) ?                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );; ?) j/ f* \9 H  x2 J3 M- w! z
                return;
0 w% K# O6 n/ X! y/ L: f        }
+ Y7 x4 s7 C2 M7 B3 k! w# z: F' H- ~. p) G/ E1 t: m' f
        // Volume setup
' @2 V+ f0 }7 n% e; W        //  0:Master
3 n) W  k& H/ O6 Z  @        //  1:Rectangle 1% ^- d: O  ^6 C+ u6 t8 {- X
        //  2:Rectangle 2) c) a5 `8 ]; t0 F- z
        //  3:Triangle
4 i2 n( s; \, k) x3 f; w        //  4:Noise& t! I, E0 Q) u6 C. J
        //  5:DPCM$ s; x& s# y7 T0 \! @
        //  6:VRC6
& O$ c; t9 ~  P* _% z        //  7:VRC7) h' N( E8 q. M0 z  {& ~/ j. Q  d" L6 `
        //  8:FDS7 U# I' M) |& ]! q7 l7 ]
        //  9:MMC57 n: }. h/ q/ B% @
        // 10:N106
3 [* f8 p2 Q8 C$ i- ^, C+ W        // 11:FME7
; V# H/ Q% A% E+ b; \* G        INT        vol[24];% ^2 w3 j8 E3 _' Z
        BOOL*        bMute = m_bMute;7 J) {! y6 t6 B+ N8 A5 c9 n6 e
        SHORT*        nVolume = Config.sound.nVolume;
0 N# V7 X5 g% C6 |
5 e7 ~, A( q8 H        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
! K- K+ K0 B8 q; E) Z9 ?* g4 r% w) m) I0 A
        // Internal" C2 u" M$ A1 i
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;( m9 {4 L5 N3 B( l; c, y" j1 ~
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
# ]0 g* D7 C2 W  Y& c* f1 a, t6 i        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;- s( ?# H, J* \5 d- Z3 o  o
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;/ }2 R% L; @% K
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;: n  ]4 I) T( U6 X

$ f$ }& i6 N, c0 Q        // VRC6. L2 [/ Q* w4 S( X
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;/ F7 t& T6 u# t! l- R
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
! }; `0 {' u1 T& ?6 B        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
9 i9 P3 w# r  W0 d) X% U; `( s
: f7 C) C1 J0 c7 x' \4 X        // VRC7
! }# A, }; T* u5 C        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;/ ~4 B6 V0 o3 M4 Y

; y9 q! w. _" j( X* h4 d        // FDS" I+ ]% l$ Y2 }' S9 b
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;! u! P- h! Q3 u- A  k5 d

- _3 {' A. j3 C. d3 a9 p/ q, p6 o        // MMC5- H. m: s4 G, S- w% C
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;; [. _  d  |+ E- f4 T3 {; I
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;: J4 g' V( }7 a8 |9 M
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;* {% y  |& @: H2 g
$ I7 p" f9 ?+ ~. v5 U4 M/ x2 e
        // N106
1 N/ d% C6 q. t/ Z/ |# q0 T2 G% p        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;7 M- W) T9 e6 f% _" q8 C. J+ |; I
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
3 U" d5 Y0 |5 ?* ]' z        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
2 ~; \3 V9 U1 c0 a5 ?9 d. i4 q        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;  V% ?# q* z1 {$ C( p
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 w% h$ p9 f! s7 S' i# l        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;1 t( I1 T0 P. A0 A5 ^  [
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" z( c0 d" S1 x0 o1 _: ^        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
( y* p: ?3 u% _. g8 X/ u+ K7 O
1 Z/ u& D. I7 ?' a, E+ B        // FME7
/ e: t* J& ]# O        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;! p0 E+ |' B& G2 r6 v* t
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;: R5 w! m: \- p9 z* v$ ~( B; T6 a
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;4 F% }( Y# Q( j0 a& f7 D6 y- U+ t
8 |3 L$ L) x* h; Q2 l& l
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;8 c0 z1 [; x+ [* {2 e$ V( [3 L
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;3 ^( T! _) p, D. X6 S4 s

. z% s% h) q  v  Y0 b        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
  n" g1 c2 Z2 q1 |4 t: P        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
4 k9 p1 U) O8 e6 u! o                QueueFlush();
* ?" |2 a' W' e7 B        }2 K5 G$ j4 [) n

$ c' Q+ Q1 I5 s0 A5 _3 K        while( dwLength-- ) {
# Z5 @$ Y% A8 Q* s& r                writetime = (DWORD)elapsed_time;
" p* @& n) q$ [2 o" p' N2 o* V' O: u! f  Y9 q: l
                while( GetQueue( writetime, q ) ) {
3 U+ [# |$ G. E$ Q( b4 Z                        WriteProcess( q.addr, q.data );
8 L9 H! f+ F# z; N' t                }
" R2 r: F! o, t" |; n3 V. d! m4 k# \; z' i: q% a
                while( GetExQueue( writetime, q ) ) {  g) l% ~& ^, l* i, C2 j8 [  u- U
                        WriteExProcess( q.addr, q.data );
) {8 l6 y" G3 {# B5 c' g$ j2 a                }
; ?! Y5 Q0 ~% G
. {. J. v  s  c                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
8 z- L" W, v& ]; p* l- i' p8 T                output = 0;
  c% z! Y4 [( h9 x( C# U( S3 {# Z- p                output += internal.Process( 0 )*vol[0];
  K: @7 q+ r( m/ O2 I8 Q                output += internal.Process( 1 )*vol[1];
* v2 {  y# V( S2 ?7 g+ ?                output += internal.Process( 2 )*vol[2];
0 ^$ @9 a9 U5 w: I                output += internal.Process( 3 )*vol[3];1 u8 w# k* u: d5 C6 R' K* [
                output += internal.Process( 4 )*vol[4];; N& `+ Q/ I1 _! o- h

+ z; k# Q. G$ @, O                if( exsound_select & 0x01 ) {$ j# ~7 d5 b$ k& Q' o5 j" K2 T. I
                        output += vrc6.Process( 0 )*vol[5];2 \( {- ]8 w1 ]0 {# P
                        output += vrc6.Process( 1 )*vol[6];
9 \& n2 k& o  b) \                        output += vrc6.Process( 2 )*vol[7];% |5 o9 E. E) C( q- {. e
                }
. n- _$ d. n, t$ h$ I! ]( u                if( exsound_select & 0x02 ) {  l; F/ G: H0 j/ L* l, M
                        output += vrc7.Process( 0 )*vol[8];
* E+ j. w. D+ |* Q# U; Q: T                }1 P; F- P; d  ?' n7 l% g
                if( exsound_select & 0x04 ) {
& q! S+ @+ D2 J, N                        output += fds.Process( 0 )*vol[9];- n) ?9 M8 j3 x; @0 s
                }+ ~: e% w, g" n
                if( exsound_select & 0x08 ) {2 k9 }  Z- Z9 I8 \+ D" G
                        output += mmc5.Process( 0 )*vol[10];
% L$ l* I) H. A/ P                        output += mmc5.Process( 1 )*vol[11];2 i+ E3 b0 j+ P8 j* e
                        output += mmc5.Process( 2 )*vol[12];: t; C0 t7 _! [+ |" v$ _- r
                }
/ z9 Y! A" z: l! b" [3 q" G0 ^9 {                if( exsound_select & 0x10 ) {
* a. |  R$ o: S* ~8 F! X' p3 f& b7 f                        output += n106.Process( 0 )*vol[13];
# q9 s( F1 x4 S' V! w8 ^+ ^                        output += n106.Process( 1 )*vol[14];
. c7 d" e8 }$ Q                        output += n106.Process( 2 )*vol[15];5 Q: i' e: `/ _. H1 Y2 e% l
                        output += n106.Process( 3 )*vol[16];! W+ g& G, I( U- f
                        output += n106.Process( 4 )*vol[17];
; v0 }4 M% z2 R6 M: |                        output += n106.Process( 5 )*vol[18];" f  F. S  S  s/ P
                        output += n106.Process( 6 )*vol[19];
! @6 L" S- p& G3 G  K( G                        output += n106.Process( 7 )*vol[20];
2 _, R$ o& N; U+ A% R2 X                }* Y: F* R& z/ S
                if( exsound_select & 0x20 ) {3 t( a( A1 |  ~# v8 j6 {+ ]
                        fme7.Process( 3 );        // Envelope & Noise  t3 d" G: g& y" p& a5 m5 K
                        output += fme7.Process( 0 )*vol[21];' U) y" B' d6 z* o: B5 C" Z
                        output += fme7.Process( 1 )*vol[22];! l: F) D, R' Y) j- P
                        output += fme7.Process( 2 )*vol[23];! m! x6 M2 l6 m& A0 d& A
                }
$ t) C! V1 k/ O. H- z
6 S( c6 N$ v3 m* n$ _                output >>= 8;- u. E  L% J; G0 a" [0 x

, Y4 b/ S7 H; i0 X* F& B2 }                if( nFilterType == 1 ) {
9 c2 H0 P* P( q" y, E1 X                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
: {, @2 V+ A$ j+ s2 M3 u. @                        output = (lowpass_filter[0]+output)/2;0 a2 z% m# p8 r  r& f+ M- b
                        lowpass_filter[0] = output;7 Q+ e( V) J! [
                } else if( nFilterType == 2 ) {
  F6 o. ?' U& L7 X3 |9 d                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
: c2 b# m8 W% F$ c' M                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;. {' r" m6 Y; d' {  ~2 x1 x+ p
                        lowpass_filter[1] = lowpass_filter[0];6 V& z) q# f1 y  ~  a; X
                        lowpass_filter[0] = output;
* q, Y( y! Q/ |$ u, N3 V                } else if( nFilterType == 3 ) {9 n4 E0 h1 z9 ~, C+ O
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
. @3 L. J% \0 ~5 D6 W% M8 j                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
+ g$ e9 p5 {9 m  P  k7 E0 ]                        lowpass_filter[2] = lowpass_filter[1];. e8 n& N; B0 ]3 `$ P" t# I
                        lowpass_filter[1] = lowpass_filter[0];9 `2 o7 |5 d8 U2 r5 B1 Y8 ~6 j, v  I) F
                        lowpass_filter[0] = output;% |8 z. i2 B7 A4 D/ J* V
                } else if( nFilterType == 4 ) {6 d& T+ G. c, Z( g4 q6 _7 o/ r
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
# O; p3 q3 [* J2 F' K6 k) r                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;# g  U7 D1 F7 V
                        lowpass_filter[1] = lowpass_filter[0];5 N' C3 ^' G5 {
                        lowpass_filter[0] = output;1 y7 I5 a% D- j/ K1 B% u
                }1 m$ C$ H& C. H6 ?) U* [% o

' L$ l1 k: M) C#if        0) c4 y' ^  j# C4 v* P
                // DC惉暘偺僇僢僩1 ?6 o0 O& g$ L
                {0 b3 _1 J  ^) M3 e  C3 R
                static double ave = 0.0, max=0.0, min=0.0;
: M" T9 S8 V; r6 S                double delta;
0 e9 \' O; A1 M5 w# W                delta = (max-min)/32768.0;- J" F  K$ M2 Y, K0 w4 {
                max -= delta;
* ]/ d2 a0 w- c* V1 E                min += delta;7 S) P' {/ d) y( P
                if( output > max ) max = output;" E" B, q; G. I7 w2 P& B) x
                if( output < min ) min = output;9 z/ X7 }5 c5 u7 f7 Y
                ave -= ave/1024.0;) G& c* w5 }. S8 v
                ave += (max+min)/2048.0;
. k, @, _& r. ?: j  }3 }: d                output -= (INT)ave;& k7 f$ f9 e3 ^+ ], L! |
                }& q( ~) }9 ?! U1 r3 j9 y1 Q
#endif0 O! ?7 I) `9 q- F5 O
#if        1
  S8 n- ~: r0 n, i8 L3 L& p                // DC惉暘偺僇僢僩(HPF TEST)* j$ j( G* ~% z1 j( ]( n  o- Y
                {- f% O+ g7 G4 ]6 E. N' n) I
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
1 ^  F/ b! a7 b) I; O                static        double        cutofftemp = (2.0*3.141592653579*40.0);  p) ]" p0 M% O! @  e
                double        cutoff = cutofftemp/(double)Config.sound.nRate;  e# _# j1 i( A5 w5 o
                static        double        tmp = 0.0;
. ?( s1 @, n7 ~4 ~% l5 Y                double        in, out;; S% s; k' \, s  P% A, }/ K
- P! x- ~, I3 t& ~% V
                in = (double)output;: e9 s& r( ]; L6 Z
                out = (in - tmp);1 _8 q$ G2 k. k4 L5 l4 x
                tmp = tmp + cutoff * out;4 _% M* _7 p) h) s6 l

  {# h. \3 r# ]0 C- v1 G                output = (INT)out;0 K' _$ g4 g  [. H3 P# W
                }1 A" e1 Y" \" O$ Z3 L
#endif
1 @; U. F+ z) J$ E" K#if        09 u1 j$ [3 g* v7 Z0 e& v3 e
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)5 j" v) Q5 s8 B) G
                {
; \' G1 e+ \. @% E                INT        diff = abs(output-last_data);2 E- F; @0 ?9 K  v
                if( diff > 0x4000 ) {
- J! N4 d: }9 H. u8 {; O, f                        output /= 4;) y. ^# a- J9 {; I
                } else
" e( s# g4 y' I( \" R                if( diff > 0x3000 ) {$ N5 @0 o7 ]% ]/ E3 }) l# F$ i9 R, G
                        output /= 3;
+ g0 L/ I6 x5 U8 ?                } else3 @! P$ ~1 q! A/ v2 k6 m; F
                if( diff > 0x2000 ) {/ k* v6 I: Q6 J; T$ d* K
                        output /= 2;
4 E1 o5 z( e2 K5 `2 }, L) A                }) i6 f( t1 Q  c# n0 D7 {
                last_data = output;% i( h( I, g  Z6 D
                }
) j$ Y9 o9 p3 v/ B6 k) q3 A! c( {#endif
4 ~. I2 J$ b* _4 e2 M5 q* s5 x7 p                // Limit
  }0 h0 X9 W1 K# _0 N- m                if( output > 0x7FFF ) {/ M8 P# T9 u# L. ]9 h
                        output = 0x7FFF;
- F, @+ R; b) F! D) r1 R6 h- H                } else if( output < -0x8000 ) {
1 R0 M# s! t" ~5 }; U                        output = -0x8000;: y# q+ m9 y$ E' A8 a3 f% L. X% z+ r9 i
                }: Q% c& Y1 q& c! T+ w8 c
% j! {8 X1 l( P0 d3 P3 ^& v
                if( nBits != 8 ) {1 s0 Y5 P' v. N1 y$ f
                        *(SHORT*)lpBuffer = (SHORT)output;
$ b, y/ x1 y2 j+ P                        lpBuffer += sizeof(SHORT);
; m& n) Q1 \* k9 S# q                } else {' g' x! O5 N! X) ]+ J* G, E
                        *lpBuffer++ = (output>>8)^0x80;: H2 k2 O- y: P; \  t
                }1 s- n6 T1 D2 U, z2 R) v" \9 l6 T

& [; M" u' l- l" p* Y                if( nCcount < 0x0100 )1 v3 k" z4 z: P2 G3 E) o
                        pSoundBuf[nCcount++] = (SHORT)output;0 m% `) r, e9 T" x% y$ O! }* Z
# Q$ l8 f8 Q6 U  X- w
//                elapsedtime += cycle_rate;* J0 A4 `7 [3 ]* q2 r8 h3 @
                elapsed_time += cycle_rate;6 h  N9 I1 ]! Y) n
        }+ ~. C/ @5 O5 x" g0 a, h; r4 n

* N& M9 f% p* z3 x; q+ |) G$ S#if        1
4 b  `4 N. T, n9 P: D9 f% @" k( j        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {' E7 W8 o# g! k% s; }" Y. o8 ]
                elapsed_time = nes->cpu->GetTotalCycles();/ I4 N8 O4 g6 _3 J, y
        }7 B+ I) Z) ?" }# X9 Q1 e
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {+ W4 {  X+ ~% n0 f+ L+ j" z7 i
                elapsed_time = nes->cpu->GetTotalCycles();% I, y: R! n7 j
        }1 c7 E3 b1 {: g$ }) a" `
#else
( y/ L3 W+ r) ?! A        elapsed_time = nes->cpu->GetTotalCycles();$ E3 f+ u7 U/ p5 S8 F
#endif
/ x, J  M! ~. G$ C" Y2 J8 F}" Q, ?; x0 F3 u) e1 a

6 t5 f! q  a8 l// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)! z# L+ [: C: @7 s. R! b
INT        APU::GetChannelFrequency( INT no )
- ~5 |$ g/ k/ T' U& q1 H: B/ y/ A{
6 I1 e  @0 R" s! a0 F  _        if( !m_bMute[0] )5 [5 ~( _: O0 T3 ]- x* p
                return        0;
: B# N2 [" ^% `3 f- I& u: L5 Y7 g0 S
        // Internal
5 R9 S: o8 a; y. n4 b) `2 n; _/ ]  t        if( no < 5 ) {  Z7 ]0 M) b' Z1 K  T! h8 z
                return        m_bMute[no+1]?internal.GetFreq( no ):0;& |3 Z2 R7 Y5 J2 [5 }' q' @- X
        }7 C! J2 \9 b7 b# Y% Q
        // VRC6! t4 O" p, e# l2 h
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
3 a; w7 g8 ]& l# p  c% s0 ]* g                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;+ F4 t$ |2 F4 f1 J$ y$ |
        }( x! p( P0 H+ y! u: f& r
        // FDS
% V1 I% C7 F& y- C; a9 x: O8 `        if( (exsound_select & 0x04) && no == 0x300 ) {2 L2 X% q, g& X2 I4 T
                return        m_bMute[6]?fds.GetFreq( 0 ):0;% o! J" o/ S  `7 P8 k
        }
% w  m2 R7 t5 {5 _- p4 k' O        // MMC5, k/ k9 I+ b! @; D3 t
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
, W7 D) }3 x% Y9 n% z                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
9 ?! _: j- @" @9 j2 K+ d        }
& c7 V- L# `7 ?" _        // N1060 U' k, Z. y* v/ \  m- |: }, E
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
* j0 p) E# d- \4 K% U! K                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;* y  p  o$ q: z% n# Q
        }. X1 |- T. g& n5 X6 u2 ]
        // FME7
, @7 G- N# x+ V8 c! [7 i4 R! p9 o. d        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {: v2 ]4 S+ D, Y( p
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;' `# b. ]! i' e( b7 g% Y
        }; [- {# @0 L* C! @
        // VRC7
/ g4 \( p# H" q) Y0 E        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {) i$ @8 y2 N& f& S) m# j1 B
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
: i) ~& X* s$ X2 {0 x5 j% L" J        }
5 p2 h" X2 j/ K        return        0;
1 s* B; V0 D. g}
1 Z" L/ l6 R' `9 f  R6 p0 l& ]" L( r, y: X7 ~! ]
// State Save/Load
. f) X  g3 w& }  P2 C: T6 p+ v6 [void        APU::SaveState( LPBYTE p )- j/ D6 v1 w6 n
{3 Y+ `& r/ @- u: {
#ifdef        _DEBUG3 D! S' X5 |+ [) O( r
LPBYTE        pold = p;
/ ~% R& l3 y' U* X$ d9 M#endif
' G' r0 L+ j# X7 Z4 a) E7 c+ H, n% z; O2 M! W/ v8 R  v
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞5 T% l' F; p3 U, j8 \; P7 o2 E  a, u
        QueueFlush();
! J1 \% j8 w" v$ F5 O
3 I- N" l+ c, i        internal.SaveState( p );
7 C; A6 n" g- ]        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
, w8 z4 r# q% c  k3 l; @/ ?5 {
# j& P2 z' }0 s# H. Z        // VRC68 W9 G0 I5 q( y% l  C8 }4 u9 ~+ ^& q
        if( exsound_select & 0x01 ) {
* H) V; ]" t: G$ ~' y                vrc6.SaveState( p );
3 s1 R3 K) O, w# G2 Z) ~                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding! w% F/ I2 k8 ~6 j( m; T, @
        }1 Q3 }9 u. l3 i- ]+ ?# Z0 I8 K  T* D
        // VRC7 (not support)/ o4 Q. _$ V- R/ L
        if( exsound_select & 0x02 ) {
5 _* x0 @; M1 D8 W. y                vrc7.SaveState( p );4 g" a5 {8 X/ S$ |( D
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding7 i+ x; V/ l8 c4 m' h" m0 |
        }
; _, ^8 c1 f1 @' d        // FDS
) v: t3 J2 L* `  Q; _        if( exsound_select & 0x04 ) {2 k* i. ]% u5 w3 Q. A
                fds.SaveState( p );
2 P" s) V9 T1 O! O9 i! i; c                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
& H: Q: G4 v! H# Q" Y5 U) ]        }3 _' `7 I, H9 {  `- q2 |$ ~
        // MMC5
$ X+ i& y/ m" K* K, u        if( exsound_select & 0x08 ) {
+ N$ X0 _" E- \# H                mmc5.SaveState( p );! V& M) \* d& L" k: ?. N
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
/ p; Q' w! M: y        }& F/ w4 f9 V- F% M  V
        // N1061 o4 t3 A% Z, u5 w
        if( exsound_select & 0x10 ) {: V; {; B/ P3 {6 p
                n106.SaveState( p );
7 R! {3 p2 t( W4 r4 j                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding( b0 K2 C2 x2 ?$ f8 n' C1 C3 D
        }
7 k0 F5 s7 }) ^        // FME7
" G+ |1 q$ v- m: H  j3 F$ t        if( exsound_select & 0x20 ) {5 U5 f( }5 x3 Z% T. h9 ?
                fme7.SaveState( p );" {* `4 J2 Z- |, x  e
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
+ H" |$ g* A5 x  v5 L- ]        }
" @5 G6 i. y' n* B7 {
8 R' k% W/ L6 ?( }2 x#ifdef        _DEBUG" t, x+ [8 @+ C0 G% Q
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
# x4 x. t) K- \9 R: e  S#endif
$ A+ T$ F: g# E6 p& @}
/ h; E) K8 q) H7 J0 g5 N4 U1 Q, [( z/ O- ~! X
void        APU::LoadState( LPBYTE p )7 f( |3 b6 @" i/ O' D
{
5 x2 [2 D2 Z$ c; h( u        // 帪娫幉傪摨婜偝偣傞堊偵徚偡0 E0 w' C! k0 s$ r
        QueueClear();  N2 i" d& \; _# Z

8 Y6 G: v+ s0 I3 }        internal.LoadState( p );: V/ I/ D% I) y4 R; s
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding  E( m. F4 n3 s6 h# G, l8 X
' M: I! b8 D2 u) E, h
        // VRC6( [5 L4 f+ p; Y$ R5 P
        if( exsound_select & 0x01 ) {
% L! [- Q4 }: o" i" K# j2 h: ~                vrc6.LoadState( p );  c3 z6 t0 G/ E/ f
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding# I' v6 f) z* q: H
        }
% q) c' B  R+ C; D8 g7 X- g        // VRC7 (not support)1 f9 A2 T+ H/ H* B. `
        if( exsound_select & 0x02 ) {
% e; q$ j& E: M6 m                vrc7.LoadState( p );" ^9 I  M, X' g9 t2 j% F! j" [' N
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
8 S. o! E1 d9 s& V! L, {( u        }, l4 B  ]& j1 i1 B
        // FDS
/ c! J$ }, O5 |7 m% a1 A        if( exsound_select & 0x04 ) {: D6 a" b0 Q$ v
                fds.LoadState( p );
: U( J# m) Q3 p8 D7 D                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding; p0 i! j, m5 R$ R9 ^: H
        }% ]7 V/ E2 G, c: {. z& f
        // MMC5
: o" P* E* @& ~, w2 [- q        if( exsound_select & 0x08 ) {
" G" C+ G7 P  J9 t7 Q1 j  K6 |                mmc5.LoadState( p );2 A' j" I. x. e+ l
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
' U) c2 k, W. A, P( B0 W* B/ r$ j        }
! }2 o  f/ i7 a5 G- u        // N106! |! i; x% ], Q
        if( exsound_select & 0x10 ) {
8 ~  |  P7 Q9 e( |& }, U; S  t0 I                n106.LoadState( p );
9 U0 A/ u" P7 r" m- P0 W7 d                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding' l' Y' e, t4 D
        }9 h! }4 Y* {- G: Y
        // FME7
3 H: d2 C% |" i* a" x        if( exsound_select & 0x20 ) {# V1 V+ s* x: S4 P9 b6 I
                fme7.LoadState( p );* Z8 b. A2 n  F7 C/ R0 q
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
- E, N9 ^& A: ^, G8 G        }
2 X+ |1 j' f& T' V0 {- Z$ m$ ~}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
' ^/ w7 g( E( E' g; d/ n% h可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。6 Z& e* e8 C5 f' n, q
感激不尽~~
3 Q9 e2 X$ ]8 m
恩 我對模擬器不是很有研究,
2 h/ h! s  \( m4 A8 J* q雖然要了解源碼內容,可能不是很困難,  \8 b8 t( s& m
不過還是要花時間,個人目前蠻忙碌的。: N3 D# T& q4 D( {) X3 z

$ V# \9 i3 l9 o) U7 A給你一個朋友的MSN,你可以跟他討論看看,
/ G% a) M2 V6 ?' k! G2 ^1 C; N他本身是程式設計師,也對FC模擬器很有興趣。1 u2 I/ B& S; U# _2 V$ d

7 A" T9 N9 S; m0 A/ r3 dMSN我就PM到你的信箱了。7 B5 _7 |9 D5 T

8 o! E! W2 s# f6 E6 c3 L希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
. `: F" j3 \! j, I4 M  `+ M  w呵…… 谢过团长大人~~

4 F* C- c4 ^* F; S6 S: k! n& a3 P) }/ U% {6 @4 @
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
1 H& i& k* z: o0 g- q团长的朋友都是神,那团长就是神的boss。
% B+ |2 j8 a# y1 C% g/ ^
哈 不敢當,我只是個平凡人,$ U  U7 ?/ b3 O6 X8 _
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙' C* _1 J) u+ z: ]
ZYH
1 B! O9 |2 w  _- n/ cQQ:414734306) O4 S. R: g% l7 y+ \# |1 Y' L% ?# k- r
Mail:zyh-01@126.com) t$ O4 z0 i7 }" X2 K+ r
9 b  U2 H+ a  F0 [# X
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 ! {8 A" U2 o1 R  i
再次对团长大人和悠悠哥的无私帮助表示感谢~~

7 u( Z5 w( B) y; `2 }% G" }不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-8 04:58 , Processed in 1.081054 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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