EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。$ A6 m( C- T: ], j7 w
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
9 F3 I8 s- v6 s: F/ G* S# D+ N这里有相应的模拟器源码,就当送给大侠了~~( Q4 t4 q5 L3 N
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 ! z) H9 }" y2 {) o; I
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
  J8 d! X& W8 b8 }1 z楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
. }' N, o* }+ n' z; n* w这里有相应的模拟器源码,就当送给大侠 ...
% |$ b5 P8 j- O+ {6 y7 @
聲音部分(Audoi Process Unit = APU):( E+ J+ x( _9 _& [4 P8 v9 L
.\NES\APU.cpp
$ x! u. F' y# X3 u- ^  F% J.\NES\APU.h8 d/ U3 d: P$ H, c* N

  e' X/ y: B3 n/ f, R' x! S) H$ P
影像處理部份(Picture Processing Unit = PPU):- j/ \- r) c2 S  z
.\NES\PPU.cpp8 e6 j; A* o+ Y6 I; U1 {* E
.\NES\PPU.h1 x" F4 d/ r/ h; v/ H0 v0 W

! v, n" W. p0 P如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:# l5 Q3 S" D6 H( l5 o
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
4 h8 F( E8 ?" g//////////////////////////////////////////////////////////////////////////
5 {1 ]! m0 }/ r: }! I  z//                                                                      //
0 \: b1 J  ?5 w& h& e2 c. `$ u- n! D* ~//      NES APU core                                                    //) `  ?& C; f, G4 \
//                                                           Norix      //3 Q) m9 b- r- F. e. R
//                                               written     2002/06/27 //: R' V9 `8 u& W6 H9 M) q4 y
//                                               last modify ----/--/-- //
4 K  Q6 k% M, C6 W9 J* o//////////////////////////////////////////////////////////////////////////+ d+ F  \& ]+ b
#include "DebugOut.h"
( `5 R! A2 n" |" ?7 [; l9 y5 l#include "App.h"( H3 \. f! j, d! c4 _6 [
#include "Config.h"
; O8 k6 J! Y# S6 T9 M% M" n, b" n3 ]; t8 f0 ?' T
#include "nes.h"1 B& E$ W: n4 D
#include "mmu.h"3 P9 ?3 X  D$ |8 u4 v
#include "cpu.h"( B0 V3 U( Z+ [% f( _) x
#include "ppu.h"
* C, y8 w, \" _2 }6 v* r1 d#include "rom.h"
) P- Q5 l; i! u  _- r" y4 A#include "apu.h"/ m3 {: s8 a$ s* l( _( E2 X

2 }: ?& r2 {) [// Volume adjust
7 L% o$ W  Y# {# q: D  A// Internal sounds. U$ J2 g8 _! ^9 I) I% S
#define        RECTANGLE_VOL        (0x0F0)) Q2 H  E: }  O7 H1 v; B
#define        TRIANGLE_VOL        (0x130)5 y# Z- X. _) K( D3 W
#define        NOISE_VOL        (0x0C0)% R& d3 |% Z0 J0 U4 g; a7 k) i
#define        DPCM_VOL        (0x0F0)( C6 h2 a+ t: s0 \1 Z- ]
// Extra sounds- y: }* Q( j, b$ T: S  Q$ [! [' _/ X
#define        VRC6_VOL        (0x0F0): V" R; ^5 I5 C9 s" h
#define        VRC7_VOL        (0x130)1 D4 T& O8 W% X1 {/ |3 g
#define        FDS_VOL                (0x0F0)
6 O3 ?7 {* L& w$ Y#define        MMC5_VOL        (0x0F0)0 I( ?9 Y" h3 |0 L' v: X) Q
#define        N106_VOL        (0x088)0 b7 ?; `9 |, a
#define        FME7_VOL        (0x130)  R. C* l, f+ Q# X" i

3 e4 _; K! s/ S# m* KAPU::APU( NES* parent )" Z5 m1 f1 e0 E- f/ r5 _. D
{8 U& B8 _8 I$ T. e
        exsound_select = 0;" [3 U* s6 P& p
3 {% @: L" W* X8 |
        nes = parent;
/ N- D( t; w4 \( d) o2 l" t: X        internal.SetParent( parent );
, q1 S6 Y& B1 X* ~7 ^
9 N( |5 {: a) M( F7 J        last_data = last_diff = 0;* C2 B4 l6 P1 E- S8 X+ P% M; k
3 U4 x! z: W$ G/ l1 U
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );, V) e8 Y9 ]9 h; T! Q/ v

9 I. E$ `4 r. m( {: {        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );8 b& y- t! v4 D2 n# `
        ZEROMEMORY( &queue, sizeof(queue) );' x( y8 X/ `: Z7 P4 A+ Y2 S0 T
        ZEROMEMORY( &exqueue, sizeof(exqueue) );" e$ Y/ w1 [7 I$ u5 P5 i
9 h7 y7 F9 T+ b9 l% D* e2 o
        for( INT i = 0; i < 16; i++ ) {
. g+ |3 e8 d$ a( L- V                m_bMute = TRUE;
5 @# D/ {7 L! j/ x' `7 M        }
. T0 O1 t2 s8 I1 B" r( _) j}
& f6 `% _- j+ C& F$ n* Z& i6 L& [! ^( t, S9 x( u
APU::~APU()2 ~. T: {! w' d8 c9 m
{3 Z$ p! K6 Y% D5 R
}
. H$ g; L. Z8 D  u5 l2 l  \7 t& U2 _9 w' T/ Q" R7 a3 s, c& {
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
& R" t- q7 Z" |) _$ p" F) {6 {+ y+ `{6 W4 P5 K: s( l! @7 j' z5 q
        queue.data[queue.wrptr].time = writetime;  V3 L) `$ d0 M9 p# I  h' t! y
        queue.data[queue.wrptr].addr = addr;7 g' M- W7 H0 I9 m( t  T- u
        queue.data[queue.wrptr].data = data;1 N. |4 N+ p% n0 e6 L9 r# P
        queue.wrptr++;
# x' d0 p- x& d4 n        queue.wrptr&=QUEUE_LENGTH-1;
# Q. B- m! D! Z8 X" D4 s; v        if( queue.wrptr == queue.rdptr ) {( E8 l7 X& \7 f  Y2 [2 O9 v) V
                DEBUGOUT( "queue overflow.\n" );
# ]% c6 ?5 K9 P& s0 P        }
  O" c3 X! L  ?}) y% ]  n6 S4 Z) V) X0 d
: o% Z' x4 M+ z* W- {1 x5 o: }
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
6 g+ q2 R& {$ B; ^; E( a  @{
3 m& u: ^5 L( J1 u2 O- i$ A/ f        if( queue.wrptr == queue.rdptr ) {8 q3 w5 n7 U: G9 n0 l2 U
                return        FALSE;. g  c# h; m# \7 y
        }
; b; B8 q3 m5 p5 a  ?, X7 ~: p9 z        if( queue.data[queue.rdptr].time <= writetime ) {2 ]9 Z8 r. O5 U# }4 i
                ret = queue.data[queue.rdptr];2 R* M  \# j7 z: m. _
                queue.rdptr++;2 |0 Z* l9 z/ _: W3 K: @7 S
                queue.rdptr&=QUEUE_LENGTH-1;
- D$ J; W6 l7 x/ {% `) l1 G                return        TRUE;5 f9 r! b' D3 G2 V
        }
5 h; U! Z8 u; y0 K        return        FALSE;
" Y; [3 ^/ R% o7 X# Y/ K}9 Q! Y! I1 U3 P2 C0 S8 \
7 @1 Y5 `# s: B
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
, {; L9 b; ?8 u8 {7 U! y  {{; L7 W+ T. S, A5 A+ ]  F; P
        exqueue.data[exqueue.wrptr].time = writetime;
6 p0 P& w9 f) B3 S2 Y; I        exqueue.data[exqueue.wrptr].addr = addr;0 Y1 I& X" e1 V! \+ S* }( y
        exqueue.data[exqueue.wrptr].data = data;+ @- Z0 _' T6 l) A! Y) u2 n  z: F- f
        exqueue.wrptr++;
8 }% y+ a) @. N; b& U9 Q* g        exqueue.wrptr&=QUEUE_LENGTH-1;
6 [& b1 y0 W* p' r        if( exqueue.wrptr == exqueue.rdptr ) {
- y; R" H  ?& b  [* u4 R2 w                DEBUGOUT( "exqueue overflow.\n" );
6 x! U0 D# q' X( y& W7 B4 V        }" j3 \4 S  a& t0 g7 @$ a+ u
}
% O/ _- Q" \, F3 _+ f/ c$ N  I$ e; @# S: L: d' q! i8 D
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
; K7 B% B  e  ^1 G8 I. ?{
' p) V1 U5 Q. K, m6 V+ e        if( exqueue.wrptr == exqueue.rdptr ) {
: s) x, `! W- W                return        FALSE;$ @% W4 ]8 F7 a
        }
7 V, Z! b: R9 v0 w        if( exqueue.data[exqueue.rdptr].time <= writetime ) {0 V6 N- R- g$ p3 l# I4 {5 k  b0 l4 J
                ret = exqueue.data[exqueue.rdptr];
+ s2 [: R5 \+ W/ N) {  G% C                exqueue.rdptr++;
" a" f' K2 \$ O1 S9 i+ J3 e                exqueue.rdptr&=QUEUE_LENGTH-1;
5 H- A* {2 z7 u# ]) ~$ S                return        TRUE;% l/ l7 U6 _+ L: W- D
        }
2 I6 l- c3 j% \) G: `" Y        return        FALSE;
. y- N$ P0 B* I}& r0 D& b- x* k/ v

* a/ y4 P$ d: m- jvoid        APU::QueueClear()
( Y$ h% ~. p$ i{5 F) t, ~6 P  d
        ZEROMEMORY( &queue, sizeof(queue) );. c# D8 z  t* g$ ~0 ~! G, q0 J1 g: K
        ZEROMEMORY( &exqueue, sizeof(exqueue) );+ ], O* u6 h; G9 p
}
* x6 f0 B# R2 _+ t+ y' _" f1 h* N! a, y
void        APU::QueueFlush(). i- Z" \2 d0 p2 k' I
{5 s* @  V3 v% |
        while( queue.wrptr != queue.rdptr ) {; k# h9 \- U( w8 L9 k9 ~
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );) P3 F5 R0 t5 {8 `4 f; f
                queue.rdptr++;
0 R0 P. {6 b$ a                queue.rdptr&=QUEUE_LENGTH-1;: s! H; ~( @8 l7 ?9 d# e
        }
4 \5 `7 O, b; K9 `$ _, M7 ^$ H! N6 c2 L
        while( exqueue.wrptr != exqueue.rdptr ) {( Y3 W' R" t7 W* v0 w- Y
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );+ ]8 @6 w2 h. `  j1 r. I
                exqueue.rdptr++;
2 f. e) T6 e6 e/ s) z3 [7 Q- P7 g                exqueue.rdptr&=QUEUE_LENGTH-1;
2 w9 r+ R( S6 Y8 L        }, W6 e& E; f7 i% y" j2 {
}( M0 V# B7 r4 c% [6 E7 U

) ^: i/ ~6 f" c  `, F) kvoid        APU::SoundSetup()$ ?8 B0 F+ E/ J
{* c/ m/ S+ K9 ~  X% t7 Y
        FLOAT        fClock = nes->nescfg->CpuClock;0 C+ K( f" k) _0 |5 {" X
        INT        nRate = (INT)Config.sound.nRate;; q# D  Y( V/ r, k3 ?. |3 o* v7 o
        internal.Setup( fClock, nRate );
2 k8 f3 d1 d+ G9 `$ V2 ~        vrc6.Setup( fClock, nRate );# Z- q  e3 [5 C1 ]3 C- o. J
        vrc7.Setup( fClock, nRate );' s. Y7 M+ A) d! @+ N
        mmc5.Setup( fClock, nRate );
( x. _! G) J# [$ I        fds.Setup ( fClock, nRate );
6 @# P' [# s' }3 |& K9 i- J        n106.Setup( fClock, nRate );
0 c% ^& y5 q) |6 ?3 c        fme7.Setup( fClock, nRate );
6 I5 G4 Z  z% e3 ~8 H}
& d0 x, \* Q; y7 o5 R- _1 W$ o) f/ g& y7 w+ n% E! t
void        APU::Reset(). _9 w8 `4 o2 ]$ H9 l6 g& ~7 L
{
1 k" J! g; L; @: `6 p/ `; _3 B! g        ZEROMEMORY( &queue, sizeof(queue) );
8 I- F6 c1 ?! Q/ P. _* P        ZEROMEMORY( &exqueue, sizeof(exqueue) );
1 U! _  K' `! o- y7 @% Y
; a# U6 V# F7 e1 w. ~3 e        elapsed_time = 0;
9 b9 ?7 F1 e4 E7 y: A; R8 @6 v) w9 M# ]& w8 D$ n% V
        FLOAT        fClock = nes->nescfg->CpuClock;
, }# {# M+ I) ~9 t( M0 W- F        INT        nRate = (INT)Config.sound.nRate;
8 ?$ r+ [! L# N  l  D& P        internal.Reset( fClock, nRate );: K6 O  i$ n+ T7 Y! N
        vrc6.Reset( fClock, nRate );
! J& Y% P; a: q2 N& c5 l, \        vrc7.Reset( fClock, nRate );$ W7 p: k) v4 M6 b* k$ s
        mmc5.Reset( fClock, nRate );8 X3 I. q: N$ P
        fds.Reset ( fClock, nRate );2 M: e; l. a; h$ I0 d
        n106.Reset( fClock, nRate );
: p! W) o/ Y. @' K; @        fme7.Reset( fClock, nRate );
; d8 H4 G% _$ x  y* }5 |( T/ g7 I; P+ r$ s0 @3 Q2 d- l9 ?
        SoundSetup();# R9 {# x8 T7 {- ]
}
; n: k* Y$ U. _+ f3 B6 j. D, g9 r7 a( a, W
void        APU::SelectExSound( BYTE data )
2 V7 M; c: s9 m  R{
. N/ b  j7 i1 l) a9 k2 P        exsound_select = data;
3 \8 |' r% Y  E, F, e; w, R}
0 Y7 p  G9 S" o% u, K/ O" l3 n% p$ `) l# g: u; Z' Z
BYTE        APU::Read( WORD addr )+ R, P3 Y5 w' m* v/ `/ y" I5 X  f
{! S6 a6 _; q5 O( \, J2 E  b; ?
        return        internal.SyncRead( addr );
' C, O& i2 X' Y' k! b9 f" G' F}
/ Z, Y' I2 A4 P8 O- C( R+ J! C! j: G# Y" K! T  J
void        APU::Write( WORD addr, BYTE data )4 R# d3 ?4 o2 O$ `
{, N6 s/ ?6 M% H% d" ?' O
        // $4018偼VirtuaNES屌桳億乕僩9 F* Z; B$ j6 |( [1 w- r
        if( addr >= 0x4000 && addr <= 0x401F ) {
2 {; i! W) p1 D- R  S* }- {                internal.SyncWrite( addr, data );8 F0 }; _$ \; B, q5 k' q$ R- P/ z
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
/ b: H$ N8 K7 D6 x3 c- W7 W* b        }
  D. t% u1 c" }% r% U}
( s, ^  |# p2 s- Q' x$ {4 Y
2 r5 K& I3 b3 F; u6 ^  B  H& F; V, hBYTE        APU::ExRead( WORD addr )
  N3 Z! h' D, H' {{
- m! G, }9 K5 h( F9 b7 J* y5 VBYTE        data = 0;9 z+ W  s4 y: M9 f& t$ T/ R

/ R$ v2 u* y4 H) `2 G        if( exsound_select & 0x10 ) {; N% o; m9 D2 u$ q
                if( addr == 0x4800 ) {
: ?6 {. K  `' V/ |4 U0 q% H                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
: ^# c4 |, A( A% ^                }. X0 y2 `+ B% U4 |: `6 Q
        }
! }7 |+ \' Y$ p4 r# Y        if( exsound_select & 0x04 ) {
0 q  [* T: ^. d3 z: c                if( addr >= 0x4040 && addr < 0x4100 ) {  D" M8 @8 ]/ u3 {+ v- ]
                        data = fds.SyncRead( addr );
: p9 ~  S$ P  Q                }
2 _. A. I/ ?- F' b% A" v( p& A5 f        }$ ~% U* D" ~& C# @& K' g& b. D
        if( exsound_select & 0x08 ) {& c8 i2 |" _& L1 J' h( {4 A
                if( addr >= 0x5000 && addr <= 0x5015 ) {# S# \# P+ K5 e' m9 D
                        data = mmc5.SyncRead( addr );
4 ~* ]8 i, e# Y; d7 M                }
& ]( J& W6 c) b/ x# h        }
7 D4 o6 E/ @: g. m
( v+ z+ D% u7 _% F; Z' ?/ f        return        data;& M9 t. s1 t+ o, D; W, L7 y
}' a6 V1 q& @- [) w6 R

  ~5 g6 m! i( v3 `# \# Zvoid        APU::ExWrite( WORD addr, BYTE data )! d" A: Q9 r# I) a) b
{3 n0 T2 o. `* s9 |7 g( `
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
! {! D0 E) s! @) I/ N5 @' D
& F) g' P3 h9 ^' d/ i. O        if( exsound_select & 0x04 ) {; b& a  ]% D" o. N& s* p$ `- |: S
                if( addr >= 0x4040 && addr < 0x4100 ) {3 h) u2 l; Z% @* y& e4 l
                        fds.SyncWrite( addr, data );
9 G; p/ i; Y2 B& H$ u% s" e: F                }
  n$ c; j  \; R# ~        }/ c* e  N7 `( g+ R6 Z4 D+ V$ S
! @+ ~+ U3 z8 v/ W- @9 `- x1 g
        if( exsound_select & 0x08 ) {
) F9 d( k8 M4 k                if( addr >= 0x5000 && addr <= 0x5015 ) {3 m" {; r/ M, \; i4 i! Q
                        mmc5.SyncWrite( addr, data );
8 `' a! X& n; ~! \9 }0 ~                }. t: q/ Z4 M' T+ p5 f" o
        }* M6 v1 d6 _/ U! V1 g+ c
}* B' L1 t: F0 t# @7 F  @" g
) A: o4 S( k, U7 J9 R
void        APU::Sync()
& L* Q( ?* x. l{
# w1 O8 J; p- M. @}
- t; ~4 ?$ U9 @1 P
: I4 M6 c  f5 R* yvoid        APU::SyncDPCM( INT cycles )
6 G" P& Y. D+ ]$ {. S5 i{
% h1 s5 {7 T2 Z1 y0 B        internal.Sync( cycles );; a  d- W: `$ s9 n- U$ q! d
) L8 }5 T) d* i  \
        if( exsound_select & 0x04 ) {
2 v0 C$ P! X5 ?$ M8 B7 e# ?                fds.Sync( cycles );: b/ s, E1 q7 G
        }, A# O: f# q+ K, H
        if( exsound_select & 0x08 ) {( N4 R1 v- P" n' t6 u4 y
                mmc5.Sync( cycles );+ \& _, A  m/ b- U  G
        }4 m- w4 `) i; ?7 A0 p
}
0 [! }4 F0 |# A! ~+ ]4 l+ W: E
void        APU::WriteProcess( WORD addr, BYTE data ), D5 K, r, g* ^( V' j% M7 G  g) a
{
  s$ X4 p$ W, y( b' ^0 N        // $4018偼VirtuaNES屌桳億乕僩0 t% R+ |* S( b) x
        if( addr >= 0x4000 && addr <= 0x401F ) {$ S. {$ e! w6 _7 s: z
                internal.Write( addr, data );
1 I- z+ T+ G/ W- S4 ~$ z        }1 I6 H, b6 n, M. Z8 ~
}  h" G# \/ u+ ?4 s3 d$ ~
9 E& X' H! x& {' r
void        APU::WriteExProcess( WORD addr, BYTE data )- }& X/ l. N! |2 N$ N- w
{
, @7 e" U3 c9 Y2 s( j. b4 O        if( exsound_select & 0x01 ) {
6 Z% w7 @* j, J% s                vrc6.Write( addr, data );
  b9 ~! j; w" _9 Y        }
& e" x1 o" E7 \. v" t        if( exsound_select & 0x02 ) {
9 j; S2 P8 w4 C. X2 N$ Z                vrc7.Write( addr, data );
9 V  B% c/ V5 s( e        }1 i9 R5 i/ B3 f
        if( exsound_select & 0x04 ) {  j. T' Q+ C* s  b0 H
                fds.Write( addr, data );8 `7 u# p, |1 n( n; M* N3 i/ O, p
        }
5 Q$ v: e( }% {! x2 F        if( exsound_select & 0x08 ) {/ f0 F/ C4 i% R+ i# k% I
                mmc5.Write( addr, data );
/ [2 \& j. o" \+ a" q: i; W. E        }' b! ^. y* V$ t* \0 @8 R
        if( exsound_select & 0x10 ) {
- J: S  \& L" V6 t; z( S                if( addr == 0x0000 ) {' ?! h/ x7 e! U0 m
                        BYTE        dummy = n106.Read( addr );0 K9 C4 @2 @& b4 j( l8 K
                } else {
5 u/ T0 m5 g6 a; Q                        n106.Write( addr, data );
3 E) q; Z4 Y5 D0 f                }
' a) b- m4 D9 I        }
0 w+ d* T0 i  W% S$ Y: I        if( exsound_select & 0x20 ) {
. f2 W$ X3 K4 G! X, ]* B7 O/ n                fme7.Write( addr, data );
1 W+ Z5 v, |! ~        }# f4 o) ]7 W- b7 g. c
}# \+ Y) J. o% @0 Z" t
  a% G* R, U4 m+ ^
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )6 l$ s$ g, T# T, [! Q, E
{' r& e* r4 g+ @/ n9 u
INT        nBits = Config.sound.nBits;
( T; _' i  u3 pDWORD        dwLength = dwSize / (nBits/8);
- L" N) H! F7 U2 _INT        output;
4 h" r  C8 k) c. d' V' t+ FQUEUEDATA q;# S4 W1 f/ _; @* n  }
DWORD        writetime;9 W" b. T- R0 A- p0 f1 R) F" N. r+ v
8 `/ K  J7 h) f, k2 d
LPSHORT        pSoundBuf = m_SoundBuffer;& V8 I# X  s  T* y( Z0 W
INT        nCcount = 0;5 n& p+ U# _$ K, w+ L. T  m- A

& R) h* a5 e: g) L1 [. \8 _% lINT        nFilterType = Config.sound.nFilterType;8 `0 _/ {' W: R: K8 ~' L
* z2 [% D3 Z" L# R. `
        if( !Config.sound.bEnable ) {8 W+ ]- N- S: t' C
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
  `5 A9 ]" w7 |8 R                return;
" I, d4 r( ?; A7 j* u        }
5 A+ h4 E  X1 U- r& {$ _$ h# a
' J1 X: N# w% F1 g# o        // Volume setup
. y4 Z9 k- _/ c7 Z- X        //  0:Master# q" K. F) T8 P4 ?7 W! s
        //  1:Rectangle 1
5 r, d3 Y/ p5 @        //  2:Rectangle 2
9 u" ]9 p/ @1 Z; \- p0 G        //  3:Triangle* m3 _0 _6 g9 M
        //  4:Noise
5 ?; k& x1 U0 K, E        //  5:DPCM
4 s' |* l& t" s% I' D        //  6:VRC6
/ Q" Y9 @, D6 V2 T        //  7:VRC75 M: o  H3 L1 Q, ?0 |2 g
        //  8:FDS# x* S( F; V6 U2 [" q2 \" T& l" ?
        //  9:MMC5: X# W9 M+ x( b0 e
        // 10:N106
; \4 p# S, f* F; o1 X/ }& S8 x7 `" J, o1 ~        // 11:FME7
2 I4 k, A2 Y- ^$ \3 m, b2 V1 T        INT        vol[24];
( l) c6 F* j1 x4 W% n+ _% b        BOOL*        bMute = m_bMute;
5 c/ r9 |" }1 l        SHORT*        nVolume = Config.sound.nVolume;# J" t; }( Y+ u

4 B/ G8 ]) m$ {; J0 H9 d        INT        nMasterVolume = bMute[0]?nVolume[0]:0;1 j4 E; ~7 R1 G9 O
" k$ ?( n$ i! c$ m  v
        // Internal$ D8 ~. M0 @- Q$ k5 Q
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;" l# W$ e2 u' M2 d# _. `
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;; s$ V" D( n5 ~8 E/ ^- ?* H
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
' w# y/ x* @+ M  m  g4 w) `4 N  H        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
- U- [* J% e( H! j8 R- Z) U        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;: @8 P- H( _, O

0 r/ H4 C, z0 u9 D: f( i/ R        // VRC69 I' n; \/ @7 z) B
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;+ W; z" q: n* h0 l% o/ l& h5 t
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
% F( @7 ^1 r0 B& Z        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
! T0 R" [9 i! U4 c7 P6 g5 p# l: S6 O7 V! X
        // VRC7
+ n2 \- V3 v" f# \3 r+ R8 b; A2 s8 Y        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
: g+ M% g( k5 ~! `9 t4 d- I+ g3 T+ |' e! C
        // FDS! Y( l* Y0 P& t5 a$ n
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
- t) B/ P9 n: w% j# ^+ p( @  p3 w& K' o% g+ p! r
        // MMC5
9 p/ s- G. Y, O        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
* C. N; K$ j# L        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;. _! ~' F& |4 Y! B% Z: ?+ ^
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;+ h+ R! L7 M( K6 c& }- f

% L+ I: {. l# h        // N106
& k' C6 f3 E9 O# x' Z/ r        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;. Q: i% K( _. K6 O. ]
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
; _# s, X6 Z! n0 j; [* K) A        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
1 S4 R5 X" h* {: v9 \1 J9 x% y% X        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;3 `) w! A- `5 Q" T3 d- T! O7 W6 `( Y
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
* J5 p- l( G2 k- D5 G7 X        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
) M1 w0 S) C: ~5 \        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, ~; @, Y5 V* Y9 p' l, S        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; B( S* F. p- _
& a8 h9 U; J2 h2 ?: R
        // FME7' e+ E  I7 w6 d- K9 Z
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;+ {1 o7 S: x, O2 ?% E
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;! q# s- H3 y1 C7 L. v3 e
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;# S5 F) }  \9 m$ p; }" Z1 g* ]

9 r& F6 ?0 z0 i) u3 q//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
. J* N* z' z7 ^$ A        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;- n$ S7 j$ l) C/ v: A

2 N) X6 @9 t# W2 c        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
/ a" H  K. \0 t+ H1 o1 j; Y4 |4 _        if( elapsed_time > nes->cpu->GetTotalCycles() ) {% r# [" P, C9 N2 r5 N
                QueueFlush();3 g: q) [! Y/ }
        }- L# w1 E% T% }7 J1 L, U# G
2 w. u% W/ W; y, C' \
        while( dwLength-- ) {
! R/ H3 _. n* [5 ^9 i* e                writetime = (DWORD)elapsed_time;4 }. Z+ Z& o% X& G  t* I& U- i

" f0 q2 K7 H" B" X9 W. r) l                while( GetQueue( writetime, q ) ) {) v( q: e4 j3 j
                        WriteProcess( q.addr, q.data );  q. l: y6 P: Y& ~( z& x0 K
                }
- b7 r3 E" ]! ?' t* _  H9 P8 f
7 v/ }! g+ p* t9 q: r3 f, X                while( GetExQueue( writetime, q ) ) {
8 w& i3 g* {4 _& N% }+ h; e4 O  U                        WriteExProcess( q.addr, q.data );% ]1 D8 L3 g4 u: U7 X
                }
; u+ o2 D& h, a8 m3 d/ G' B; \1 }$ O; g, E. F+ S5 w. r3 V
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
5 f" F! o8 b2 h4 L                output = 0;
5 ~+ Y; @0 D; z) m" y                output += internal.Process( 0 )*vol[0];% \, U" P; m- M' t
                output += internal.Process( 1 )*vol[1];6 F& W: D- f) Y# U- a
                output += internal.Process( 2 )*vol[2];8 ^: |) r" e% i/ I8 y
                output += internal.Process( 3 )*vol[3];3 q5 j0 u+ w8 t/ g0 C) X1 L
                output += internal.Process( 4 )*vol[4];8 o5 [! p# P( G4 h! y. K
; ]* h4 s$ O- k) j2 A) }, w
                if( exsound_select & 0x01 ) {
0 K2 \0 n2 n+ T* {8 m                        output += vrc6.Process( 0 )*vol[5];/ S' q4 Z+ o. g4 W7 {7 h
                        output += vrc6.Process( 1 )*vol[6];( E' m# j& D* Y+ O& l
                        output += vrc6.Process( 2 )*vol[7];6 k. o( c2 ^/ C0 D  W/ t
                }
5 }9 B, H: g/ _8 ^6 F; A# x                if( exsound_select & 0x02 ) {
/ ?8 `' M: S/ N* g                        output += vrc7.Process( 0 )*vol[8];
& k/ s" Y* }2 ~. e" h$ e                }
0 D5 a9 Y, O# C, x% i                if( exsound_select & 0x04 ) {
2 m( D3 j8 {( l" ^4 M                        output += fds.Process( 0 )*vol[9];
3 j& f1 g+ |% Q0 _8 J                }# W* F$ c% v7 U9 N) S% s0 j0 C' t
                if( exsound_select & 0x08 ) {1 `2 G4 L; ~1 ?# |) P6 z
                        output += mmc5.Process( 0 )*vol[10];( U$ I2 j( ~" y
                        output += mmc5.Process( 1 )*vol[11];
8 ^! v# b: i/ |# J9 I                        output += mmc5.Process( 2 )*vol[12];
5 U" d2 \1 r4 c& ]+ _$ c5 p4 I9 S3 Q- y                }6 ~" {+ ?3 ?7 `2 u1 @1 H6 i+ x
                if( exsound_select & 0x10 ) {% z! Q( p1 }7 P' w, X# F' B, I
                        output += n106.Process( 0 )*vol[13];
+ `' p  |1 o/ x% Q1 V, w                        output += n106.Process( 1 )*vol[14];0 P5 q% @, K. r. E8 w# A( H# J
                        output += n106.Process( 2 )*vol[15];
! B  q% G+ i8 L8 X                        output += n106.Process( 3 )*vol[16];
5 \1 h, t* l$ s                        output += n106.Process( 4 )*vol[17];- f- v2 Z3 [1 F& s! [4 G0 y
                        output += n106.Process( 5 )*vol[18];
! |7 @6 s: R3 D" X, n- y                        output += n106.Process( 6 )*vol[19];
- \4 `) @4 Z, {7 x                        output += n106.Process( 7 )*vol[20];% c& W7 s' ?& F8 @
                }
  U8 T5 [% K. _( o1 d                if( exsound_select & 0x20 ) {. t4 E  ?: D0 u8 a
                        fme7.Process( 3 );        // Envelope & Noise" F* @# G+ |' ?5 o
                        output += fme7.Process( 0 )*vol[21];
" G6 T4 f0 G, [4 [" K                        output += fme7.Process( 1 )*vol[22];
* ^8 A% s1 G- T# e: @                        output += fme7.Process( 2 )*vol[23];
% p9 L5 B6 H; m* X# z6 |2 p                }& m/ T5 a4 `* ^  f
. d" Y- V5 D; p# l8 |' P. ~
                output >>= 8;6 S1 `- I! k5 L2 C# \& @, |/ h8 j

( e" ~! G& m6 R) C2 R                if( nFilterType == 1 ) {$ l9 u" |' I8 s: [1 H& H5 W1 j
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
! g5 c, w4 |+ e* Y                        output = (lowpass_filter[0]+output)/2;9 ?# T* K& ~' _
                        lowpass_filter[0] = output;! @) ~2 ~$ a3 j! e
                } else if( nFilterType == 2 ) {0 Y* y6 O. c6 L; G' b/ O
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
2 X3 f) X5 {% H7 L: a4 p                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;" S; {& C( H5 B- m2 Y+ j
                        lowpass_filter[1] = lowpass_filter[0];
" K' z4 g$ S1 J) N) A                        lowpass_filter[0] = output;7 A0 b: F( V* W. }$ }
                } else if( nFilterType == 3 ) {2 T3 o3 Q$ X6 e, S! O. \5 E
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
! y5 i2 t  ^1 J* c, n& R8 r- Z+ M                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
# H6 |- F7 u; z& h                        lowpass_filter[2] = lowpass_filter[1];- b. ~4 f. Y7 X9 t2 J% b" {/ p3 j9 C  Q
                        lowpass_filter[1] = lowpass_filter[0];' L6 H; B9 Q+ v4 W6 w, r( L/ i/ k' T
                        lowpass_filter[0] = output;
1 v; \4 D* C$ q9 t' e" k                } else if( nFilterType == 4 ) {
3 F3 j, v5 j) Z5 n- C" L                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
& L$ k* t3 a6 j                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;' g) h9 o& V2 Y6 {$ C4 l
                        lowpass_filter[1] = lowpass_filter[0];
6 `; p% P8 ]3 P& m6 B" i8 n9 b! V" C6 x                        lowpass_filter[0] = output;) s% O0 I8 n: u4 U& R( X  C
                }+ o* R' C# n  B$ l
5 Y$ t5 }& m4 w0 a# Z2 b0 X
#if        0
) O4 Z2 ]5 {8 w3 w                // DC惉暘偺僇僢僩% E8 k: @' W) U
                {
8 X" P% |4 P/ o4 v" ^                static double ave = 0.0, max=0.0, min=0.0;
* e: D* T! u$ Z( b' {/ t( _3 ?9 o                double delta;1 V! m* {" U* I' x9 T
                delta = (max-min)/32768.0;5 k" _9 q: i# B' ]6 u* d; w
                max -= delta;
3 S7 D5 c8 t/ Y! K1 S                min += delta;' ^6 U% B$ X, d) E1 J
                if( output > max ) max = output;
& I2 t" D; Q7 R) C) r. S8 x% E                if( output < min ) min = output;4 Q/ k1 ~7 t9 N% O+ `7 p* _3 o
                ave -= ave/1024.0;5 u1 h) V5 \( P7 t( v; `. x) O
                ave += (max+min)/2048.0;
( {* h# T) g4 l, ~, v! e& l                output -= (INT)ave;
. J+ z, V' [( \& f( o; c& A( I                }
% Y# o" R. H7 J4 c9 g2 V8 b8 X#endif6 f( w- s! Y. r9 S
#if        1; O" ^1 e+ J# ?
                // DC惉暘偺僇僢僩(HPF TEST)7 ^( s3 U, E7 q% y8 J) D; ^
                {  z) ?5 p" ^( @/ \; S
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
' V5 A" N" e& e! W0 Y                static        double        cutofftemp = (2.0*3.141592653579*40.0);
9 C' s% U. S- j                double        cutoff = cutofftemp/(double)Config.sound.nRate;  w1 L: F/ J8 b% l& V5 b# a  S1 n
                static        double        tmp = 0.0;
% `! W- Z, R6 O1 f! j+ n# Y- _7 @                double        in, out;
' r7 e1 p& [) e1 Q6 e7 h4 D; J
6 j3 v. W& w1 |# D0 D                in = (double)output;9 J6 d7 g9 o# u. M# k" h
                out = (in - tmp);
) z9 d% R/ A' _/ B; a) h( _                tmp = tmp + cutoff * out;4 W/ ]  B3 D4 [" t* }& R2 z

2 L! v% X8 k  |9 x+ d4 c$ v/ x0 A  m                output = (INT)out;1 k0 Q' {& K6 G( z/ v" ^
                }
1 }8 i. B" \( ]5 X( _#endif2 U$ r# M1 n5 g. ^, f2 O: J- p
#if        0
% [" [9 w: N2 r. _5 I. u                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
! A/ _& q3 M3 f+ X4 |                {
+ e' ~* g' _) h                INT        diff = abs(output-last_data);5 x, A( i0 H) u
                if( diff > 0x4000 ) {
* r' u2 t0 _: U/ T% a9 Z                        output /= 4;
" H" V% o9 C  T# ]- ]  X, Q! U                } else 3 l/ T5 Q: A1 c; L
                if( diff > 0x3000 ) {
2 v. z% V! v" i7 [. x5 N! ^. A$ Z! R                        output /= 3;
: G9 }5 t# a& [  f' t1 ?+ r                } else
, j. s  s, L. {8 d1 Q! ~                if( diff > 0x2000 ) {) G+ M+ W# |5 G- w0 j: F
                        output /= 2;  c8 F$ o' v1 F! N
                }
( A+ I- z/ W5 g/ Y( V7 Z' V$ s                last_data = output;( E* v$ G# \8 m, a  a
                }9 r% P$ |: I# Z$ p. S6 O
#endif& H* e8 `7 p. L( H  i0 c. p0 t
                // Limit4 H; t/ [: a- G/ E# E
                if( output > 0x7FFF ) {) t+ M$ e/ Q$ v& J( M0 `
                        output = 0x7FFF;/ c% I6 r- b" t) [
                } else if( output < -0x8000 ) {7 m# T' w/ T3 o) p# O
                        output = -0x8000;
1 i& n. R  w- S9 S( W- A8 _                }4 Y; F6 j9 S! z$ Y* y
; E9 B7 C* U- u  e
                if( nBits != 8 ) {
) D9 u4 J, Z- V2 j6 G                        *(SHORT*)lpBuffer = (SHORT)output;2 p  y  i5 t: X
                        lpBuffer += sizeof(SHORT);
1 |9 T4 I* B, p) h$ E. y: g                } else {
- [6 v) z: o" _2 ?, p7 G6 H                        *lpBuffer++ = (output>>8)^0x80;
1 o2 A: k9 D3 x5 b' c" e5 c                }3 @) \& x* U% \% `& a( A( k

# G) {/ S2 a- {) g3 D  k) U3 @9 q* B                if( nCcount < 0x0100 )7 Q' |  r7 f# f; X! m
                        pSoundBuf[nCcount++] = (SHORT)output;
+ i' t: H6 ^$ |9 R( \* P$ B
8 ^, Y& r" U/ U& g/ K* a. r- C//                elapsedtime += cycle_rate;
# U' E; |) Y7 ]  Y9 y4 r                elapsed_time += cycle_rate;  B! r/ \$ P0 Q7 [8 ^" ?! T* o
        }
9 q: e  S" j) b5 g- S- O" n6 L" J  X" |. R
#if        1# D2 h1 g2 K; A- K
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {" o# I* p* h# F
                elapsed_time = nes->cpu->GetTotalCycles();
  z# _. S9 U  M- R; D) y        }
) p; u3 g4 h. P' O- j        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {. e! S& B6 a* O$ N/ b5 v
                elapsed_time = nes->cpu->GetTotalCycles();( \& s4 F  S$ o" }3 V3 @
        }6 u4 }" ?3 q4 `1 B0 d1 `+ L) o4 m8 c* M
#else8 F) l# F) T. v) [& T7 T" K
        elapsed_time = nes->cpu->GetTotalCycles();
: l( a$ U& W8 I# I' a#endif
/ q4 K! ~. Z0 e! a- w! f}* u' E8 O  b; b3 z

) R( ]% X8 e" q& v// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)/ j7 Z" r/ I7 d4 ^- \% O
INT        APU::GetChannelFrequency( INT no )
  _& d9 }9 n9 ^/ Z9 p{
. c4 I/ s, i5 m! u7 F3 E        if( !m_bMute[0] )
$ D+ u2 E0 v6 ]" D# x* k. l+ N                return        0;( z8 r, Z4 w: t( A& f2 h5 N

$ [5 o1 k# B9 g  g: N! i, n        // Internal4 Y$ W; O% ]+ w, Y6 x- y+ S5 ]
        if( no < 5 ) {
9 ~; X. f3 ^& I. E6 F# r, N$ R                return        m_bMute[no+1]?internal.GetFreq( no ):0;
3 o$ u' N4 G: U  L$ ]6 _1 {1 R        }
+ k4 v8 p# F& C' S9 ^& m( a- B4 _$ u) m        // VRC69 ]' J5 U5 u' H) i7 |, E
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {( B: D. w& x6 E
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
3 M& K" R# l( g5 p. O        }" s1 g+ K1 P" ?7 D5 E2 \# \, u
        // FDS
1 q: h. D' ~% E        if( (exsound_select & 0x04) && no == 0x300 ) {5 g' H+ T" f) a9 p3 E$ t
                return        m_bMute[6]?fds.GetFreq( 0 ):0;% }/ d5 z9 N/ M; U4 l. K, w
        }! {, N/ u. u2 P+ O. f
        // MMC5
1 G3 d4 l0 r0 c4 L        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {: Y) m" z7 b. M% S
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
  o! }& w' `) }! i        }
4 O) w* a/ O; Z' |. x' ~        // N106
; @7 O) B8 O& A! W        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {+ u( ^4 |8 E; p( x9 i" G, _
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
8 P% G/ r; ]4 [- G        }0 f0 a' r& M; D; P9 t
        // FME7
& h' j# |/ q: {; ]. j        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {4 _* ]. R8 o! Z" k" n" D  K& r
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;, F& n6 c+ l9 D) W
        }$ O& G/ }6 c. T9 e1 a" \0 Q. q
        // VRC7: F3 F8 `+ V, }, N* z
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
* ]$ J% [; h4 j; \                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
/ a" x1 Z2 F/ w7 `0 K+ |: K        }
  T5 @7 |0 v& `+ }) c        return        0;' L/ b- Z/ S- q2 ^% ]
}" n( ?' |9 X: X1 O* A' B- F! X

% N7 L* G* f. p& q) z' f7 J3 X  g5 d// State Save/Load1 H/ O# w. X4 _0 R( m
void        APU::SaveState( LPBYTE p )
+ L' ^8 V1 l% Q$ J  {0 r{2 u' m" [# c. H# [" C+ K+ `' P2 @
#ifdef        _DEBUG7 r7 ~- Z$ i" k. ~' [( r# ?: p& ]1 Z
LPBYTE        pold = p;! D5 w) @7 X* }8 }- C
#endif8 M. X% r! v* \& Z

. p& G0 s$ n7 b, n        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
0 O7 i% M) o/ q# W# Y        QueueFlush();
" H# i# u: F( D$ A, m' p/ g: s6 _9 e# O2 y5 w( Q
        internal.SaveState( p );
2 D0 K: t+ q" X        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
) i/ h0 S  b4 d3 B3 H
8 R( _5 x7 y* m( W- P* T        // VRC6
9 r% G5 e. ?( L: h        if( exsound_select & 0x01 ) {
* T6 U: T  q9 s, N6 A                vrc6.SaveState( p );8 g! T9 q9 @# `) N  s( B8 m
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding$ T( w& @8 C6 H* ^
        }
' J# U0 v/ e! U# j/ k! I! q        // VRC7 (not support)  n; N) e0 l- S: Q9 X$ ~
        if( exsound_select & 0x02 ) {$ e5 q5 N( }: B
                vrc7.SaveState( p );: Z* o2 u" {  o$ y
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
; F/ q2 h  p6 F8 r/ D% ?        }
% v6 K' I0 l: W9 W' a+ ^( l5 Y        // FDS4 R, z. w5 G( y) t
        if( exsound_select & 0x04 ) {2 M% V' [9 B5 u+ {' M9 D
                fds.SaveState( p );
2 b& f/ a; C5 D4 \3 R: @8 A2 f                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding6 U7 h* X* |/ |" Z
        }
9 T" `5 g  c6 N- n& U        // MMC5
. P+ k" S+ e4 x7 d4 w( }! d        if( exsound_select & 0x08 ) {
4 B8 l$ h8 c/ n: q2 \1 R! s# L" F                mmc5.SaveState( p );
+ {7 _( X1 ]6 R8 k* \1 F                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding7 L. W& z! C1 q) {* R
        }
  }1 @- I' e  S8 v        // N106
% Q, N/ F- m0 w" v        if( exsound_select & 0x10 ) {
% y0 c" B  S9 {. F8 g& i9 G! L1 X8 ^! y                n106.SaveState( p );
; I+ D( u' C. ~. Y/ z$ J                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding1 w, h6 ~8 w( I% y! S
        }
) i) ?7 N- ^( l! z        // FME7
- E$ N" p" y% v/ z/ Y" C        if( exsound_select & 0x20 ) {
9 ^9 a4 o& f  P$ N0 M' m                fme7.SaveState( p );8 ?7 O5 V! o5 G+ A  g  Y
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
* l8 l& i' \  n" D' `; t9 p        }" u4 f5 V. c7 e7 s

/ O4 _& t) Q1 v% @! g' y9 ~#ifdef        _DEBUG
8 |' j$ g7 h9 P6 xDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
6 v% z9 c: r. g  t+ ^#endif
8 T% t' w; A& w}& g( k, T3 y0 U
$ a" B9 N% J: u9 g( b
void        APU::LoadState( LPBYTE p )
1 S( |: Y! N! w{
8 j+ u7 U0 P" Z, t: k% b6 W& A0 E        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
! X/ p' u* c2 ^        QueueClear();
/ |8 ^& d) i8 W% W/ p- D3 o' r: a" x4 r- ^
        internal.LoadState( p );/ y6 X3 I% m% ~5 ]! @) ?1 t
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding0 J2 G, W5 A; X# e' j! L" W8 Q

3 W. Y, Q% Q% d4 I6 R. D        // VRC6
0 n& a0 O, L- B        if( exsound_select & 0x01 ) {7 H; z& W7 s  }- i  l6 ?9 m
                vrc6.LoadState( p );
2 @( H5 i- e8 j6 B+ K                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding( I, K7 z7 x0 ]; K4 H9 K, w
        }! r/ h9 ]" H  I( ]! m; O
        // VRC7 (not support)
" X& W, x3 Y( L3 b6 B8 w7 m        if( exsound_select & 0x02 ) {6 S7 N# F6 N( }( B- j
                vrc7.LoadState( p );
) C7 X& f& ]9 O+ e+ \5 B: Q; a- b                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding- R' e6 r% h9 C* q
        }
/ g! M& W5 Y0 ^% X2 L6 _! f6 O        // FDS
9 s: d) d$ o, ?7 e# j        if( exsound_select & 0x04 ) {
5 T5 B8 G7 Z- s5 ?/ }7 x; w7 L                fds.LoadState( p );# c  Q6 G0 }( Z9 ?$ v* K
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
" k, C5 p5 w8 e. `+ P4 \6 l7 g( v1 @0 O        }7 m- m/ `. |% M" F8 j/ ]
        // MMC5
, c/ l  X7 x3 ?- l" s; Q        if( exsound_select & 0x08 ) {( O+ z- @* d  i  h
                mmc5.LoadState( p );8 b) R0 w- P& Q( G* b
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding. I5 N- F! P+ H8 S" g. v$ t
        }
5 Z; h* c8 G" _9 n        // N106; f1 W% x& i' ^- _1 `& {1 e: \
        if( exsound_select & 0x10 ) {
4 U4 L2 G% C- B+ k9 S! ?                n106.LoadState( p );9 A0 {$ |& D8 W' p5 Z+ O
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
* c7 {5 I, j0 f8 K! Y        }0 m* `/ T% P7 ^
        // FME7
" t- \! l. t, U2 m        if( exsound_select & 0x20 ) {
. v9 R5 u) U) V                fme7.LoadState( p );7 M" e8 ^. j. M7 ~8 X# @8 D! K
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding$ g: r. J- P% F0 l) Z7 ?
        }
! F0 R' t$ a3 U3 I% h- {}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
, _6 R, G+ t$ I2 r  z可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
+ Z7 w# g/ `% X感激不尽~~
) d( o1 ^; F' J9 p( G% q" S
恩 我對模擬器不是很有研究,& B9 d- q1 N! i2 V
雖然要了解源碼內容,可能不是很困難,
6 j+ W5 J/ N8 Q) r% Y# t不過還是要花時間,個人目前蠻忙碌的。
' h8 L4 o+ O5 M% q' s
6 i7 Q% z9 n+ u6 v給你一個朋友的MSN,你可以跟他討論看看,
& [  r' `( F8 P1 U/ x& N他本身是程式設計師,也對FC模擬器很有興趣。; g; P2 ]/ f; }8 W' x! N% Y
/ _9 v1 R! D* U& H* p; {' m3 ]% C
MSN我就PM到你的信箱了。
6 W' G' E* @) m2 B5 u4 g1 s
* v0 v* i5 Z9 C! ~1 r; z* S希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
5 G/ A5 m2 P1 W! X" F呵…… 谢过团长大人~~
' V0 }6 y7 U4 C) s) {8 }3 @( |4 x
1 O5 H/ P: b& q! [0 z
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
9 s$ X: e$ I& s6 Z- x+ r团长的朋友都是神,那团长就是神的boss。
7 f8 j* t9 H6 I
哈 不敢當,我只是個平凡人,
+ i: X* R1 G' J  `要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
+ J* \! \. \. u) _1 F" L2 OZYH
( x, c. X  j+ ^% o- z$ RQQ:4147343063 t, G; `4 l3 L
Mail:zyh-01@126.com% O" n  ~; M. h; F6 g

6 I* ^$ m1 z4 Z, M他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 ; u7 ?8 _0 F! L( ~
再次对团长大人和悠悠哥的无私帮助表示感谢~~
. F  h1 R, x# @# c' `/ R, V: @8 h
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-2-1 16:37 , Processed in 1.081055 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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