EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
6 k! Q* }: f, p楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~7 @! W/ W# W( m4 P& j  G  y% M
这里有相应的模拟器源码,就当送给大侠了~~
! e3 r" q. n: R) k3 whttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表   L6 C4 H! G7 y9 ~( }& B; _  i) @7 j
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
; Y! G# y3 q( n, R# u1 o楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~6 I: p; H- x4 Y! K
这里有相应的模拟器源码,就当送给大侠 ...

- r$ o: p2 ~( R( r  ^聲音部分(Audoi Process Unit = APU):
2 a+ R% q1 `7 @, a.\NES\APU.cpp
) m- z3 a7 U& k, k8 s, Z+ J" z7 Y.\NES\APU.h
3 [4 g0 S2 I6 k: E* S3 Q5 U  ]5 t3 {
- x/ O7 H" u- a. l7 }6 Q: }
/ O+ }. b; r3 u影像處理部份(Picture Processing Unit = PPU):: z) M+ }1 Z) _* S% c& W
.\NES\PPU.cpp# i$ C1 Y1 I5 L2 y
.\NES\PPU.h" G) P% z  V+ `6 `' C9 t+ t! i
* k6 U; O2 l1 A0 w
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:' f- _+ v# _6 W! M, \: {
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
# P! w9 {) y% B//////////////////////////////////////////////////////////////////////////+ k. p8 t. R6 X1 @
//                                                                      //
' T' b) P7 F7 _  s//      NES APU core                                                    //- t. g& R+ s6 u! y. Z6 L
//                                                           Norix      //7 J  t5 m$ o, t1 S: G: k" U- [
//                                               written     2002/06/27 //
( g! p0 a# z& _4 H6 ]6 T//                                               last modify ----/--/-- //
" A$ A) v7 B4 G+ c( E. g//////////////////////////////////////////////////////////////////////////
4 v' ?1 v% N3 J7 Z8 s# p. Y: Z- ^5 f#include "DebugOut.h"1 z. o( H, i/ K
#include "App.h"
& Y; G& w0 v# ?) F: a#include "Config.h"* T# q# w2 |2 n, a) x3 A) K
/ |- B/ z, b2 S- a$ o% F3 u4 K
#include "nes.h"8 b0 x0 f( }1 k. D: y  v! S; c
#include "mmu.h"
4 V9 h  _# G/ Q4 d8 ]5 j#include "cpu.h": I6 I; ?# @+ w5 m  D$ q' _
#include "ppu.h"/ x: g6 ?, t; b0 @0 ?2 E/ G7 {
#include "rom.h"
6 b2 v/ S$ G+ i  }' g5 Q& n" c#include "apu.h"
; q6 U. d3 C: @+ D, Y
8 l- i0 N) \. F; {; C7 D% B. Y// Volume adjust. I( Z% G- Y5 T2 e! j) D3 s) \- Q
// Internal sounds, E' W5 B% O- E4 z/ i" n  M
#define        RECTANGLE_VOL        (0x0F0)5 ~, }. K1 ]  U& _, F
#define        TRIANGLE_VOL        (0x130)  `4 W3 ^( ?" c8 t
#define        NOISE_VOL        (0x0C0)
% a0 n9 ~% k" {  F/ p& P, v#define        DPCM_VOL        (0x0F0)7 b6 F. b: R$ L. C9 o7 _1 h' V3 b& N
// Extra sounds5 U0 p6 L$ e% h' i/ ~# Z5 z1 X' q
#define        VRC6_VOL        (0x0F0), Q* b0 v2 X+ m5 u7 c/ e5 l" s1 Y% D
#define        VRC7_VOL        (0x130); F9 U' W! y- a. R( v) b
#define        FDS_VOL                (0x0F0)
" e! H5 |7 m, J# m! i1 n, S% }#define        MMC5_VOL        (0x0F0)$ ^- {" O/ k7 r# @; C: q2 u
#define        N106_VOL        (0x088)
) \3 Q# K- ~& L#define        FME7_VOL        (0x130)
1 }$ _  m4 ]5 r) n' g9 k' R* F
* I3 c5 @( B0 V, ~1 f) bAPU::APU( NES* parent )
3 ], M$ `2 p0 i6 V. y1 c8 A4 |{2 Q& q4 I/ o2 j0 g: [9 d
        exsound_select = 0;$ f( Q/ f* Z$ I  D
! ]# `9 P# V; ~# j% u
        nes = parent;
/ K$ r' V' I# c2 _* M        internal.SetParent( parent );
6 e: s9 B4 ?% f( J  e" ], I# W8 o: f: f
        last_data = last_diff = 0;+ T* l+ u9 k- l  }8 L& g8 j( M

& @; F- f; X4 o6 ]7 S4 {9 K        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );2 P7 C. J, k2 Q& S5 Y% T2 k

( ?; b& H4 Z/ l: ], I- h        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );: F- s+ a7 _1 [- C/ v
        ZEROMEMORY( &queue, sizeof(queue) );
  Q! C) w7 k* p: }* Z, ^1 P        ZEROMEMORY( &exqueue, sizeof(exqueue) );4 R; H: e# S0 \" a/ k# p
4 q8 c1 u, f+ D) o
        for( INT i = 0; i < 16; i++ ) {
; L; r! J- h8 ^                m_bMute = TRUE;/ j. S7 R' T* \  O2 |; \8 ?
        }
$ W( `! \. ^0 f$ t& n}+ L/ i# p) L, x2 s( F7 b

" p( o4 b8 {2 i4 [/ \APU::~APU()
* m& M9 z/ Z8 A2 W3 u( ^/ b: o{
) A7 k- r( c. ^  n& E; [}
! B* A) p: h2 j, _
, i/ N; g! L* p  s; {6 ^. @void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
0 S: @0 S* ^" f2 D{6 P6 E  ]7 w3 d
        queue.data[queue.wrptr].time = writetime;) W& H- I. W9 T8 v3 a
        queue.data[queue.wrptr].addr = addr;
/ n' {- |+ e) s        queue.data[queue.wrptr].data = data;
, I0 P1 b! b) L( K* u        queue.wrptr++;& e) x& D: Y5 E0 c
        queue.wrptr&=QUEUE_LENGTH-1;
! a% G/ l' W  L2 S        if( queue.wrptr == queue.rdptr ) {; \" C7 O8 n, {
                DEBUGOUT( "queue overflow.\n" );! f" x. N- r1 p9 y9 W
        }
% N( D! h& ~# S}
' k8 S; }# D5 Z* k# {
& O8 t! G5 }& p$ b1 B$ VBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
7 d; `$ f% ^; t2 u0 I{
! K; h1 _) Y+ b2 k0 [. m2 V! n        if( queue.wrptr == queue.rdptr ) {' [# b, \0 j! l5 \( _
                return        FALSE;
2 A8 H4 l  z; S/ I* s! o        }" P: G" O+ J, g( d5 Z6 L5 L
        if( queue.data[queue.rdptr].time <= writetime ) {) R9 ~& V/ d% x! {- s  s
                ret = queue.data[queue.rdptr];$ D9 s9 h, T0 ?
                queue.rdptr++;3 q, ^% _) N3 c  `6 m; E
                queue.rdptr&=QUEUE_LENGTH-1;' v8 C. d* [! A1 ]% C" {
                return        TRUE;5 K& w. L  h7 v* j% j4 C. [( d
        }
7 h/ R8 S9 ^3 V0 M, Q0 U* d( L        return        FALSE;1 z! Q* q6 _- w. K3 u/ m9 {2 U5 x
}7 M9 d% u. m8 a$ j; z: h
& H3 q3 O; K, g+ b' d
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
' d6 g- D3 P3 l  n6 d, ^# }{
/ u1 |8 x5 @4 i7 f, w, z% W* `        exqueue.data[exqueue.wrptr].time = writetime;8 x" c$ b6 y+ s' a2 Y3 ?
        exqueue.data[exqueue.wrptr].addr = addr;
" I, W+ H" p0 F0 `4 @        exqueue.data[exqueue.wrptr].data = data;% a( e# g9 ^6 S
        exqueue.wrptr++;: M4 s/ r) x. ^0 h' `! B
        exqueue.wrptr&=QUEUE_LENGTH-1;; J6 y" ], N" z9 e* X% e
        if( exqueue.wrptr == exqueue.rdptr ) {
2 V% ~& G# I* [! R                DEBUGOUT( "exqueue overflow.\n" );
/ d* L4 n" J8 s- ^        }
$ e! Y: P; k2 g- k}
3 @2 l; @! D3 p1 O6 p; T! p0 c; V% B+ S/ A. m8 E2 J) y  S
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )9 U8 v" Y% p8 L9 \: M- C! ?
{
* h5 r$ x/ M6 U9 w        if( exqueue.wrptr == exqueue.rdptr ) {
1 l* ]) f/ M* m( t1 b* D2 K+ k                return        FALSE;
# m0 K$ w( ^9 D( G! p$ {4 Z        }- I9 J6 F+ Y) l
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {) v1 y4 D0 j- P5 G# n+ z) R
                ret = exqueue.data[exqueue.rdptr];
0 A" }3 J. r+ R' w5 s- r                exqueue.rdptr++;
4 |, f% i: h0 T/ K6 A- s1 ?9 C                exqueue.rdptr&=QUEUE_LENGTH-1;
/ B5 p$ F+ O- W                return        TRUE;4 [2 c( ]2 }+ P- r
        }+ Z5 n1 l5 y6 \4 q' q
        return        FALSE;
5 R# g% y, f& S2 F# ^; r* C: O}2 a$ q. d/ _( y# V
1 _  V" q. }/ `6 n: M
void        APU::QueueClear()8 @: U3 f& L0 i7 k) b: Y
{' i  I4 w' o3 [$ j( T0 n
        ZEROMEMORY( &queue, sizeof(queue) );
% G/ L, r2 [* ?" l        ZEROMEMORY( &exqueue, sizeof(exqueue) );
6 u2 a- h8 C8 X- \}$ |' C1 i& i6 Q2 ~8 T* t; k7 B) c6 \
1 R- z. g, f' g" q
void        APU::QueueFlush()+ h+ \2 l9 O4 H0 c7 r1 ^
{
% M. h! c6 b2 l; w        while( queue.wrptr != queue.rdptr ) {  q" g2 X( B9 R9 B( h9 S
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );  `; C7 z' \( [6 W: x1 |9 }& [
                queue.rdptr++;
' d5 a4 @! |' v& k7 k1 n3 Z                queue.rdptr&=QUEUE_LENGTH-1;  e  w7 }  {% a, |1 d, l3 H
        }; m. J" V2 i0 ?; H

% e+ w8 G+ p' i! D        while( exqueue.wrptr != exqueue.rdptr ) {8 |; }/ F4 |- O- I
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );8 F, E. @! _) ^% x: n
                exqueue.rdptr++;
, {! u4 b4 d! {$ y                exqueue.rdptr&=QUEUE_LENGTH-1;+ a/ u6 z0 H% P- T# d
        }0 J3 ]* C+ X6 |
}
6 T  U( o( u# K* S! @8 W
3 F5 ~; A" f/ m6 M* A: ]8 jvoid        APU::SoundSetup(), R5 I. I6 ~( |2 E4 C7 J
{7 y& U0 k( S! I( ]- q5 ~
        FLOAT        fClock = nes->nescfg->CpuClock;  s, N4 b& D8 l0 Y- l
        INT        nRate = (INT)Config.sound.nRate;; a% J& {/ U, N$ `6 G
        internal.Setup( fClock, nRate );
, J! M& j, _) m7 ?        vrc6.Setup( fClock, nRate );
& l' \% N/ [. t0 C6 U# d5 _        vrc7.Setup( fClock, nRate );' v6 L, h7 k# `# q; G& _, I6 g
        mmc5.Setup( fClock, nRate );
& k0 Y6 L4 `9 f) d& K( B        fds.Setup ( fClock, nRate );
; w; u' x! W+ J        n106.Setup( fClock, nRate );
5 A2 b2 X' k$ |' B2 ], h# z1 g- a: T        fme7.Setup( fClock, nRate );. X  u9 V8 _) V+ A
}1 s  E2 l9 @( {% l% ?3 a* w
3 L$ H' `2 u* S) C% V3 O% d# g
void        APU::Reset()
' r+ `; ?! o+ n. `' x! I4 H8 f{
! o1 V3 M( h; S        ZEROMEMORY( &queue, sizeof(queue) );
; Q8 V* j/ f3 e: U        ZEROMEMORY( &exqueue, sizeof(exqueue) );6 L! i2 {5 f- }. Z  n9 [

. \  d, `3 _1 W        elapsed_time = 0;9 a- p/ ^7 K1 a  }4 [1 \, V3 G

- t: S+ h2 n# z0 Y2 s( A2 y        FLOAT        fClock = nes->nescfg->CpuClock;
1 ?. z2 j! x# b: V        INT        nRate = (INT)Config.sound.nRate;
3 \* a* n  n! h( N0 m# b1 e6 v        internal.Reset( fClock, nRate );
/ {$ {8 ]  E8 h4 E% q        vrc6.Reset( fClock, nRate );- m8 s# V0 X9 @; e! s" |
        vrc7.Reset( fClock, nRate );
5 _/ d. U) C- H* `( g1 }# ?6 `        mmc5.Reset( fClock, nRate );; r5 m& C6 K4 B
        fds.Reset ( fClock, nRate );/ s0 @: ]% E' D, _6 {4 R1 L
        n106.Reset( fClock, nRate );: I7 p6 p8 j; I& b' G
        fme7.Reset( fClock, nRate );
5 H- ^; J$ t  E# H1 S5 P, Y9 t/ b7 y: j1 `" i) ]  ^% ^- H0 I
        SoundSetup();. T! i; A8 _& J& U8 N3 j9 ?/ n3 A) C
}
% @4 _0 f/ s$ {7 \% \5 @9 ^- m8 _, p7 u
$ i2 G+ _3 K# b# {# D9 n( dvoid        APU::SelectExSound( BYTE data )
1 O  q) M3 n1 E# p{3 Q8 v7 Q) a' Z/ E6 v4 y
        exsound_select = data;
0 `* V8 t; x3 \; R) d8 B- |}- j3 P9 I2 j) f2 d* ]+ z- P8 e

7 Z9 {+ y6 j+ C! e& [BYTE        APU::Read( WORD addr )
9 G7 L5 P6 v# t; M" r. w{
8 t& B/ E0 a0 \$ ]        return        internal.SyncRead( addr );( \( N7 c6 L' s4 E% {
}: s. U: j' s0 X' V9 {8 m, g
2 I  E* ?& C4 p5 J+ y
void        APU::Write( WORD addr, BYTE data )
) S$ y4 t7 r( X: z9 }8 r: d7 i{
9 F( M; z3 |6 q( m) X' r0 R        // $4018偼VirtuaNES屌桳億乕僩) [& x. S# F. [! g6 K
        if( addr >= 0x4000 && addr <= 0x401F ) {, Q8 ~  w  B1 t  ^
                internal.SyncWrite( addr, data );
4 s) c# Y7 Y8 G9 F                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
. }8 T) u9 R* y1 z& |        }
& K' f) |! x1 V6 T}% e& k2 z. f/ H. i0 J, s
% x, |8 n" Y) c
BYTE        APU::ExRead( WORD addr )
  _" t: Y% a7 E5 b! Q{
9 G$ W$ Z( L& T! k# H& [( lBYTE        data = 0;* d  G# C) |" J7 u
: |% O2 d( a0 R6 ^
        if( exsound_select & 0x10 ) {6 d" l& t, g* J4 Z+ Q
                if( addr == 0x4800 ) {9 `) _2 H' }' Y/ Y
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );8 Z6 l1 Y; i& [; G% w& t3 i5 j
                }  d; h% }- |% @5 |' S: L" K
        }
2 [! t4 b0 f6 E$ Q% r3 d1 j! n        if( exsound_select & 0x04 ) {
0 I4 R, I/ a9 g                if( addr >= 0x4040 && addr < 0x4100 ) {
: [( U8 m% Z3 C                        data = fds.SyncRead( addr );
) o$ r! h2 u1 ]3 H                }8 d) o9 f2 J! ^/ E- Q! I. X$ }
        }- I+ `& [: m7 @" o" p
        if( exsound_select & 0x08 ) {; r- k, l$ V& p* _# Y
                if( addr >= 0x5000 && addr <= 0x5015 ) {
& U, k+ P1 l) C% h                        data = mmc5.SyncRead( addr );; g; ]* \& U" Z) H- ^6 S6 T; R
                }
7 B7 c# [4 o; M! C( F3 W9 E7 L) z" `# o" }9 O        }) a5 V( `- Q5 q
3 C  x. o0 U. g  T% q7 K! k$ P( G
        return        data;1 H  ?) F; w( ~4 q  ^) ]* {
}$ S4 R) M0 G3 b; p
, O% n+ P& x8 u# r# L! [$ c
void        APU::ExWrite( WORD addr, BYTE data ); \" I6 b  G+ q. L" ?1 P
{6 n, @6 D: D  B4 O" s
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
" A0 M3 r) j: F( S5 }& J$ g: O4 V3 @+ A
        if( exsound_select & 0x04 ) {; c2 A( T6 w7 ~
                if( addr >= 0x4040 && addr < 0x4100 ) {' n2 L$ y$ x# V
                        fds.SyncWrite( addr, data );9 h. `5 B9 }* p! D
                }/ h/ e  w3 ?* C6 i9 A
        }
7 k' v+ K0 Q- ?: N; K% J4 Q0 v; t6 k* ]) Y
        if( exsound_select & 0x08 ) {( @8 N  {$ |7 ?' Z( X
                if( addr >= 0x5000 && addr <= 0x5015 ) {" x( g8 G2 P- N
                        mmc5.SyncWrite( addr, data );" I& }' Z: \" }% {" X" h$ g
                }
" x' K; Z/ f" d        }* g5 N+ e' C" g) D$ E" d- X8 S
}/ M; j  t/ \1 [8 `0 w7 A

8 k+ K5 S' o0 e7 l4 r' ivoid        APU::Sync()
" ]& H' k: Z) c# t+ N9 ?8 T: j{- z+ Z" G. g" {% B3 _3 S
}
8 E! I4 K& U# }' ^0 A# d7 l) [* i$ Y0 Q, b$ S1 p
void        APU::SyncDPCM( INT cycles )/ M5 l# G* v( H, N
{
" `6 i5 h& Z- t; Q. S) C2 ^# _        internal.Sync( cycles );
2 r- H0 w: k6 C2 ]. }0 w; W! y* u( y0 X
        if( exsound_select & 0x04 ) {
* j4 Q' b4 g9 `: Z7 w                fds.Sync( cycles );
2 y6 N) f" b. L4 o! N% Q2 A        }: N5 g! ?/ ]# w  ]# A
        if( exsound_select & 0x08 ) {
* ~/ N- B  R5 H- R% ^                mmc5.Sync( cycles );
4 v2 K' e8 K6 n+ Q        }( |( g  E) l6 z7 G8 b+ f
}) G, v' n+ ^0 P& V6 u. F5 \

5 d( q6 a! @  @; T' cvoid        APU::WriteProcess( WORD addr, BYTE data )! Y/ m' e8 u( I5 J0 H
{) U5 t2 {8 v8 Z5 a
        // $4018偼VirtuaNES屌桳億乕僩
3 o3 H* C6 K! j" k" v        if( addr >= 0x4000 && addr <= 0x401F ) {
' e5 r+ ^/ v* P, G  j* l& m                internal.Write( addr, data );4 w/ u" C5 a7 X% a! U
        }& N- E& P0 r6 `/ k
}( K% s( ?! Z! l4 Q$ J# x
5 x/ T, T' A0 _& Q) Z) G* @7 q/ A3 `
void        APU::WriteExProcess( WORD addr, BYTE data )/ t: f$ A! n+ p& d
{) B/ p; X+ O! B8 r1 @  w
        if( exsound_select & 0x01 ) {
) V+ f+ K$ U6 S# L- q! _                vrc6.Write( addr, data );
, a5 A4 D3 \( z7 X, P6 @' ?; w- g        }1 f+ n7 a) y# ~) E
        if( exsound_select & 0x02 ) {+ g& D  Y) h) o# g% L% X' ~  C( n
                vrc7.Write( addr, data );/ B7 s. W/ `3 q( F" V
        }
) w0 Z. B3 a( k1 Y2 \0 z$ t        if( exsound_select & 0x04 ) {* S7 v1 ?# k$ c( k
                fds.Write( addr, data );  U* ]" F  u# ~6 q7 [
        }. l* q2 j( ]0 {
        if( exsound_select & 0x08 ) {3 X& D2 \* ], v2 n, F+ x( g
                mmc5.Write( addr, data );
! p6 Q+ O  T' a* j4 C        }
# y( a- Y1 P) o        if( exsound_select & 0x10 ) {. W7 ^6 B0 }& [6 C7 M5 L  B
                if( addr == 0x0000 ) {. C* ^) _# s% h1 _5 x/ s
                        BYTE        dummy = n106.Read( addr );+ V. h# V0 R! Q2 [8 z
                } else {! r9 o* B' ?+ J2 O+ o
                        n106.Write( addr, data );
" W. g0 b$ M" h# H2 ^7 y, g; I                }6 j7 Y. H$ J( e! \
        }8 g( `, p5 X, l. U
        if( exsound_select & 0x20 ) {
' Y0 I" x( g- E2 R/ P3 @                fme7.Write( addr, data );
, ^5 h  ^4 Q/ z" w        }" V4 ]$ e- V% p
}
) }& V; l+ u) B& y* t# G; t/ R/ p$ D) \, e3 m
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )( t8 w4 C6 i' b* f. `
{1 k/ G. m' U5 q: a. Y* z& E6 ?* u# Q
INT        nBits = Config.sound.nBits;6 u# n+ i* @* i6 Z
DWORD        dwLength = dwSize / (nBits/8);4 V; j2 E2 O! Y" s' r2 L/ w
INT        output;1 V  B" \; X2 t/ }9 N/ s
QUEUEDATA q;
; W& Y/ G% J7 a3 t% P4 Z, sDWORD        writetime;
: J+ o% t5 }$ P0 h% ?. N! N
' H( N" S" @2 Z- ?! m$ {0 s; {" BLPSHORT        pSoundBuf = m_SoundBuffer;
0 A3 a& }: _% g4 RINT        nCcount = 0;
4 E3 e! g5 O9 y& t0 u) ~( [% K4 R, a0 \
INT        nFilterType = Config.sound.nFilterType;
, H  _# T& y: P! N2 B# M- l# N2 W& \* x9 ~7 O8 l5 ~
        if( !Config.sound.bEnable ) {9 ^; X6 j$ t% p# o) H" e$ B/ K
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );6 y9 G2 x9 M% R: t! `
                return;' K4 }  g% h$ h
        }2 S. J, k' n3 x2 `3 c
, z. m' [* n1 N5 c  M2 }' }
        // Volume setup* G) C; ?6 ~* U- S5 i  T* K8 ]
        //  0:Master
& R' D% J5 I2 U" q! r0 `, R        //  1:Rectangle 1
. B: Z4 f, K2 ~& P9 N0 A; H5 L* ?$ p        //  2:Rectangle 2+ m: Z& C6 Y2 k, L
        //  3:Triangle
. X- ?* E! d5 X, Y/ S        //  4:Noise
& O! h& E6 K. L7 L* J+ L        //  5:DPCM9 A' M9 l7 K3 r
        //  6:VRC6
! s; s( ?. L- X( _; `* ]        //  7:VRC7
/ r" N% m8 ?; D6 E  U8 a9 ~        //  8:FDS
' N+ j% c4 \' e$ w# v) J/ U& U+ D        //  9:MMC5
) s9 u3 n# x% B9 W% o& v        // 10:N106
/ ^' e1 ^. m: D        // 11:FME7
' z! ?6 R/ i" V9 s, t% E$ Y        INT        vol[24];
- K+ r1 ?3 T, b4 ?5 W        BOOL*        bMute = m_bMute;" O5 H4 K$ s1 k4 S9 [( K, x
        SHORT*        nVolume = Config.sound.nVolume;
8 H* J" u1 Y5 D) C
% [0 K6 a- _. D) c1 _# L        INT        nMasterVolume = bMute[0]?nVolume[0]:0;6 n; z$ h' Y( U# R

7 H! W' q2 r9 a4 j        // Internal# ?/ e6 H( H, S8 v* c
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
& N" X' @0 G7 g  C) e) Q7 i; ?$ O        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;! K* C6 z4 C" m1 w$ Z$ l* @1 I
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;# I2 D; P3 z5 ]( e
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
; K+ ?" W* H  g0 W1 h        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
) H# s# w! R& w# k: D4 b) c
" S; ?& x  P( q  P$ R        // VRC67 ^. H# |3 O4 v
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
) v4 N/ Z  X0 a" P$ e9 v        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
& p/ T3 F. J9 g* U- X# b  `        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
6 k" S! ]  m0 g3 a3 ^2 W8 S
; b/ [! q. O2 _7 E4 S8 K% L8 z* M        // VRC7* Q4 C) m+ e/ j: p( {
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
( j+ `* Z# r" a0 Y  E0 W
/ A% Y1 R& H$ X" C# A) F" @        // FDS
, \' D8 G% \7 b7 Y3 x" f        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
8 `; z( Q7 ^( I3 z5 W' D0 s1 S* ^3 h* d6 o+ R
        // MMC5. v' a3 N0 S" D. l
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;9 H8 e8 x1 K$ ^( }) C
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;2 ]# f' C* o9 _- R* X# ]
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
8 m; \0 v9 D/ ]- v0 B
4 @: B+ @' F- a) _' N& U& E' F/ C) B& g        // N106
2 k3 [3 p& g2 w        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: ]2 M6 {" C8 ]9 M0 O) D+ r. j3 Y8 r        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" L2 u& ~& N7 g5 M        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; o0 e" ^' u2 W$ R. q
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;2 B# {; @% C0 h! ^+ T. `. n2 z
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
  B0 T' L: z0 X9 z$ g        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;3 {8 b3 A* B, {: Z7 U8 G8 h) R
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;3 q  x9 h+ I+ e
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& W/ L# g' B/ w4 A! c
) ~0 t- C: L% g$ g' y7 B        // FME7
) j0 o7 D% U  l. h3 @+ _        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;+ a! i3 m" \! t) G  `$ n
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
; R' c  c4 Q: @- W9 N! ^! `' E2 |( [0 B        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
' g6 L; k( v7 X( B6 j% y2 \: ]9 c- ^. o) b/ N
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;) u# k* y! X6 J) f
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
$ p$ w) x* B$ H, ?3 [# |' ?5 R! `
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
& M7 p# l- N" S( o3 @7 g, d( `: M        if( elapsed_time > nes->cpu->GetTotalCycles() ) {$ B- @9 @; M; \
                QueueFlush();+ v5 X) q2 N/ D- E
        }) w) S$ A8 [: a1 m

/ R/ F5 U8 {# A5 N5 e2 j9 t) x3 E        while( dwLength-- ) {
: c9 ~& Z. R- e7 b% R9 b! O1 h& k8 p                writetime = (DWORD)elapsed_time;$ X; ]( c2 _) ]- V2 K( y: L' [

6 L* {1 r( X# ]! ^  l! Z$ m                while( GetQueue( writetime, q ) ) {$ ?/ ~. a# S6 V" K* s$ M
                        WriteProcess( q.addr, q.data );
7 H/ _' z5 \/ ~; }: X% S2 f                }  a, g3 Q( u4 F3 ^  {

% O7 o$ p/ I& i                while( GetExQueue( writetime, q ) ) {
8 z3 a; x- r) g+ C, g/ |2 ~: v: x                        WriteExProcess( q.addr, q.data );
, j; M4 g7 Y0 e8 v2 ~: e                }3 l0 V2 X# ]$ x: y" E$ D3 |* V' O
  N  @" K5 y/ z) Y
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME73 a; N6 w# E( Y3 x$ O
                output = 0;
: }- F& k0 J! z0 @                output += internal.Process( 0 )*vol[0];9 c, \& M/ v9 G0 }3 b0 f' k& C
                output += internal.Process( 1 )*vol[1];
' G& B5 N" Z! z% W. t! k% e% Z! p                output += internal.Process( 2 )*vol[2];
& Q1 n2 y5 i8 L3 L% a- m1 T3 a3 a                output += internal.Process( 3 )*vol[3];
' W/ q/ W! B- u. E' O                output += internal.Process( 4 )*vol[4];
1 U+ X; ]8 u  }2 h! B1 r9 x* ]& e. T$ N7 u' e% o$ y2 H7 u
                if( exsound_select & 0x01 ) {. h& M8 W5 b3 g: }( h, q2 W- ]
                        output += vrc6.Process( 0 )*vol[5];
3 R: t5 L1 x. ^                        output += vrc6.Process( 1 )*vol[6];, q& c, x$ q! ?
                        output += vrc6.Process( 2 )*vol[7];3 W$ o' ~) f. C3 C4 a; P; U" p
                }
6 ^9 b1 A% h' I% U) H+ {$ P                if( exsound_select & 0x02 ) {
( W: v. i5 U: v9 @/ P  n: k- ^6 S                        output += vrc7.Process( 0 )*vol[8];
1 \- r$ Y7 B4 C8 i8 x1 h                }
5 l- V) g6 i) N! Q/ F6 W                if( exsound_select & 0x04 ) {
; n2 u5 o6 C1 l$ b- ~                        output += fds.Process( 0 )*vol[9];0 n. A: X" ^1 r0 Q6 N  m: i- ?
                }
: A9 V2 y: _3 m8 G2 Z$ U, h. c                if( exsound_select & 0x08 ) {, f4 U# t& C6 o
                        output += mmc5.Process( 0 )*vol[10];
$ F% Q5 e- ~/ u4 L9 ?  y8 B                        output += mmc5.Process( 1 )*vol[11];
3 V" _3 @! x4 y* F( Y                        output += mmc5.Process( 2 )*vol[12];
) L: r' {) c: W" F                }  a5 [1 ^8 z. A- Y7 Q# t9 Z% U
                if( exsound_select & 0x10 ) {* ]( W2 `; }* o" t" w* m  g
                        output += n106.Process( 0 )*vol[13];
7 u8 U3 d9 Z* D7 x$ G, O6 ]7 V                        output += n106.Process( 1 )*vol[14];
7 I4 v% v3 y# E9 V1 E$ q                        output += n106.Process( 2 )*vol[15];1 S# u& ?7 c, H
                        output += n106.Process( 3 )*vol[16];1 m, s  s- P- O9 }) L- d
                        output += n106.Process( 4 )*vol[17];7 X# R! ]' S5 \! l! D! ?2 o
                        output += n106.Process( 5 )*vol[18];" F  N. U0 o, g9 p2 L* f& y
                        output += n106.Process( 6 )*vol[19];
6 l3 }! j) A8 c2 b5 X% o                        output += n106.Process( 7 )*vol[20];2 m9 {4 K( W8 y* G6 y6 W& Z
                }2 `5 Y8 Q& g1 K1 `6 P  i1 K# f
                if( exsound_select & 0x20 ) {' a& K+ V" @/ G9 U) L5 b
                        fme7.Process( 3 );        // Envelope & Noise7 [8 f6 C  O' }& g3 Q0 t
                        output += fme7.Process( 0 )*vol[21];& x  h; L1 V; {0 |' K9 m
                        output += fme7.Process( 1 )*vol[22];- s6 l; O: \# w) F
                        output += fme7.Process( 2 )*vol[23];
$ K/ M# O' I2 V9 D' Q9 \1 a                }
- O. B0 g% G4 {
  |9 z" Z3 U, [# _- B                output >>= 8;
2 v2 h7 f# Z: D7 {7 B. H1 u
# ]% _$ G9 B( V% q7 Q                if( nFilterType == 1 ) {
2 _: K3 ~7 Q4 V1 g2 D9 S) z                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple); Z0 y3 s3 [! _7 d" K% E9 l
                        output = (lowpass_filter[0]+output)/2;  w. ^% |0 T1 p. V  g
                        lowpass_filter[0] = output;6 @3 V9 I% f; w! f6 g2 ^
                } else if( nFilterType == 2 ) {
$ t8 m4 Q& M$ `4 ]) h! N. u. i8 u                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
. d; \: w  b7 z- \" J2 w) {                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;+ [2 h& `3 R) k, u" z
                        lowpass_filter[1] = lowpass_filter[0];
+ y8 q6 g3 z/ E1 `                        lowpass_filter[0] = output;
5 J# O. [+ n) \, ?0 C                } else if( nFilterType == 3 ) {9 i+ l) P5 q/ E; x( p# f6 C) {
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
: W7 ~" }4 N  U7 _5 z0 N$ ?                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;. a( P& ^+ R2 x" d" E% k
                        lowpass_filter[2] = lowpass_filter[1];
3 H- n$ m/ F& X* `                        lowpass_filter[1] = lowpass_filter[0];
$ |' {" ]- \  V+ z' T. L                        lowpass_filter[0] = output;1 m2 n3 E' s7 N  N+ n
                } else if( nFilterType == 4 ) {$ |' s# o$ j* o3 {, y5 q
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)0 v9 v8 v9 I$ v! B8 u) p
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;4 Q8 J& N9 D, G1 V4 \2 X
                        lowpass_filter[1] = lowpass_filter[0];5 P3 O+ N" f4 i
                        lowpass_filter[0] = output;
9 x/ A. F( y; u" T                }# V1 h! I9 u7 o
+ r. t. _# ~( r$ k# W% I! r7 O
#if        04 Q0 L3 c9 d- N# D
                // DC惉暘偺僇僢僩
$ f+ }7 k( p& z& @4 U                {5 f1 P4 j0 t( w7 }
                static double ave = 0.0, max=0.0, min=0.0;; ]% d6 u# c4 a% B$ R2 n- \
                double delta;
, A& y7 T" q* s# J4 b$ v                delta = (max-min)/32768.0;
0 K% U$ S! i' Z& ~7 V8 b) q( G                max -= delta;
8 e$ F# K! {  ^% C                min += delta;/ U" Y1 ^/ e" b8 d' n
                if( output > max ) max = output;
9 a6 v* z& q. @. S$ a% B                if( output < min ) min = output;
2 M: T# R9 f6 S1 \% ?9 M                ave -= ave/1024.0;  ?5 W. Y$ m8 ?! _1 X" y
                ave += (max+min)/2048.0;
+ [7 J7 ]- N/ \                output -= (INT)ave;
/ u1 }" v9 s/ F6 C2 \* Z, D                }) J7 [& \7 s% O) Z/ `
#endif
. A) O/ L$ }& T: ]7 w#if        1# B* c  h$ x- N* l6 r1 \
                // DC惉暘偺僇僢僩(HPF TEST)
, u; e* B* _+ C5 h8 F                {
; @( n. b& _. `//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
6 n. d& i8 H1 P( N" Z/ }                static        double        cutofftemp = (2.0*3.141592653579*40.0);: @5 N6 O$ n' ], N) K9 ], [$ Z
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
3 j$ l8 B9 E/ d: ~" H$ ~( @                static        double        tmp = 0.0;( F8 z- X; V/ R6 O2 a
                double        in, out;, U9 F3 y: ^0 Z( P4 R
- L! M$ L% {4 z7 q& @
                in = (double)output;, V/ E+ J- a/ R, c; M3 M8 i
                out = (in - tmp);! x! ]! f: R+ W$ g8 q
                tmp = tmp + cutoff * out;4 S6 L) {7 o) t6 ]7 r
( s& C2 F* K4 E# u6 t
                output = (INT)out;, C* j8 f/ J8 B  ?3 m, w% H
                }
  n; Q. B2 Z0 P/ s#endif
  g6 h" ?( r" v& d1 I; S#if        0
* ]  [5 p5 g3 C8 T: w) C                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
! Y0 t; G8 E2 U3 O9 E% n% f                {8 a: l6 @, Y4 {% o# Q0 j
                INT        diff = abs(output-last_data);
/ L$ d1 p5 g, m* N! V# `" t                if( diff > 0x4000 ) {
( L; H  O3 o5 _" j* W  G                        output /= 4;
. e+ Z5 a9 ^3 G8 V9 m                } else ) m2 b; S" a8 ?% l9 Y) W/ r
                if( diff > 0x3000 ) {/ F7 Z) H0 x+ t% v' L! _- y( j
                        output /= 3;% Z6 [( @: m6 J. \: N- y* N
                } else
0 D& Y% E1 E8 O+ M9 b" ?                if( diff > 0x2000 ) {
  o7 D) {* q) a( o                        output /= 2;: w( [/ k2 Q3 A5 u: n0 H) p
                }# Q  n4 w" M: Q' w( E7 s! M
                last_data = output;
  a% ~. g( R4 F8 {, X                }8 P2 X& O% H" ?5 i6 v
#endif
, n; C$ r+ h7 {. Y* V5 ^! S/ t                // Limit% d' `( _7 h4 W  X) k
                if( output > 0x7FFF ) {
8 v2 m5 g( l* e: Q9 z3 ?% u. q                        output = 0x7FFF;
. X4 J! o* z- f9 x                } else if( output < -0x8000 ) {
& q8 v/ @. y. @8 ]8 n2 t                        output = -0x8000;
2 @* s3 H0 N2 I" F( k                }
* T- h& N1 g% F* ~
$ ?/ Y, b: x; z8 B4 u3 c2 G5 ?                if( nBits != 8 ) {
9 _% }( D, g% R8 ?                        *(SHORT*)lpBuffer = (SHORT)output;! n$ M. a  m/ Q/ S
                        lpBuffer += sizeof(SHORT);
6 v) x. p) ?+ x/ K4 m) |                } else {
8 Y5 o1 J3 F5 M0 ~' F* G                        *lpBuffer++ = (output>>8)^0x80;  t; W/ u' r. y+ N9 Z
                }# N+ N9 A$ U& X8 G5 I0 x- U2 \- P
- H1 Y. J% a" q7 O* n+ z: [/ n
                if( nCcount < 0x0100 )! ~2 l3 Y. R, n! y5 X5 L
                        pSoundBuf[nCcount++] = (SHORT)output;, S1 B+ E& V9 ~% E3 E& F' ~# H$ e

- B( G/ D: \0 y2 O//                elapsedtime += cycle_rate;- V7 s; U* @' A2 e
                elapsed_time += cycle_rate;& Y8 t" ]+ r4 ~( D" b
        }
# |3 B+ D( [) w  u. {
1 n) e, `% o! x* I3 @1 d; _#if        1- m' E' [9 b: ?1 \1 r6 c( Q) R
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
7 F9 P1 ~1 D  x5 s                elapsed_time = nes->cpu->GetTotalCycles();2 P; R& k! o" w# x
        }
4 |1 ]6 f$ B; M' D5 P! a$ B# b7 |        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
( T+ d0 V9 y7 C" x/ u( g                elapsed_time = nes->cpu->GetTotalCycles();
; N( h8 j$ s3 y! L$ G9 q9 d        }4 B+ U: u, w* j( l
#else/ G" h' \- O, N5 ~  a9 A1 T; P
        elapsed_time = nes->cpu->GetTotalCycles();
+ l  ?1 n8 b" g: U3 L4 o#endif
  `" D) |6 ?& W% r8 x' g! ?}! i& n3 ^+ S- f

+ Q5 X) M; t: f3 J) Q. H// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
& c, Z2 V$ h* B0 C4 P" c0 B) I( pINT        APU::GetChannelFrequency( INT no )
2 C0 b' x% T$ k1 r; _{
7 o2 o1 H  u, x6 E5 u6 S, n        if( !m_bMute[0] )
2 r  H9 P+ W3 j2 S                return        0;
' i' w% p- R0 q; `1 [" l/ E& F; }1 [) T% ?; }( L( i
        // Internal6 M) N3 e8 h4 Y. T) u
        if( no < 5 ) {5 I" X) T2 _  i) O7 e6 J( ]( @
                return        m_bMute[no+1]?internal.GetFreq( no ):0;$ h, H- ]9 d/ W4 P; m9 K' o: ~
        }
  S! F( {5 |! g3 K9 C        // VRC6& E0 q: f) d0 [6 O2 c
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {/ W; Q, t! v8 W
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;8 X3 Q/ y1 m# F7 {* u
        }
! E( W) D" _; N. x( Y& s0 L        // FDS- [7 y4 ^) `! |2 _* l( {
        if( (exsound_select & 0x04) && no == 0x300 ) {
% Q9 I/ q$ r3 ^4 G                return        m_bMute[6]?fds.GetFreq( 0 ):0;' R; ?0 }. G2 l! c
        }
/ `- Q: L" O0 y3 K        // MMC5
1 z; g4 z( l% l  ^9 R0 {        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {& G' H7 a4 i/ J
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
* C' t) M( e- _        }5 {6 B: z' v- t: i! z  f: v) M
        // N106
* w5 {' N$ i5 R+ [/ O2 a        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {# P, I; L7 |9 y# E- w+ Y
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
3 E# \! J" x: d" W/ l3 }7 S% O        }
0 f5 S6 R$ G1 x+ E7 x' q        // FME7+ G& P% l, G0 ]
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {  U. R& n9 s' P
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
. H5 T2 ~  r$ {        }# x6 W' W2 F5 l$ s: k3 n. f
        // VRC7* M& i0 I; v/ y2 }
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {- w' c# E3 S, `8 S7 |9 O
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
, E( B4 T7 h: V! C0 ~        }
# S* F, e5 d. z2 m        return        0;
) d8 A3 _% ?1 u( ^. t& U, s}
5 t3 j4 D. u/ {- O$ L% \& L
- l+ R- o% H5 s) e+ K7 A5 W// State Save/Load
! e  a" w) W' k' hvoid        APU::SaveState( LPBYTE p )
/ ]: t2 B5 H; E3 }  R! O  N% ^; Q6 j{- @5 y$ j* W( h7 n3 j, f
#ifdef        _DEBUG" @9 l) T, z" y9 P: I
LPBYTE        pold = p;; I6 D6 @. ]! P5 R5 G* b( R
#endif
1 ]4 g! ^/ A4 z  M6 t! d; s
, J& }: y1 }; u. d; p        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
: K' N) h6 o( b1 k1 s6 }        QueueFlush();$ m/ d& N; H3 A! `" e
! ]. l! ]) T) A
        internal.SaveState( p );
8 v2 e* B: o3 w  x( W- |2 t        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
6 H$ R1 {, y7 r( h
7 F* `3 j6 t  e+ ]' ]        // VRC6- Q% Z) z7 z: H, s
        if( exsound_select & 0x01 ) {4 w3 l/ r) d* A
                vrc6.SaveState( p );
/ ?- P9 a  g0 E. j4 K  s: v                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
" A2 M/ X$ ?: @+ L" D$ H        }
/ ?" Z3 H2 a. {+ j1 e        // VRC7 (not support)
5 o$ x5 D: x" H        if( exsound_select & 0x02 ) {
  @' K, d- _& E/ f) H                vrc7.SaveState( p );
6 T7 F7 z( z$ Y: d                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding# R0 A6 }/ G# c5 u2 J! U
        }
+ h4 @& r, e$ ?2 Y8 }        // FDS  f! m+ S& J. g1 {' Q
        if( exsound_select & 0x04 ) {
' [: g7 i9 U/ i4 B4 W                fds.SaveState( p );
$ {! ]+ Y( N) H" p; x* Q3 q& h6 X9 d                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding6 P- X; e6 {1 U8 C+ `
        }4 L+ c/ h3 D9 N8 S( _
        // MMC5
5 O' J. {5 h8 f7 g, n1 n- n7 W        if( exsound_select & 0x08 ) {
( d8 F$ u7 j5 X/ \1 n% A7 k' d3 v                mmc5.SaveState( p );/ g( [* p8 A" K
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding% m1 I7 K$ _# p, E7 u
        }( F/ g1 C9 ~3 V
        // N106+ U% Y* t6 l1 X2 i
        if( exsound_select & 0x10 ) {0 n1 N' A3 ^2 c) ^! ^
                n106.SaveState( p );/ @7 X! g+ ^: A
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding; o5 ?* _) J( ^) I$ y  l- j- T
        }2 G+ Z8 a; z/ c* V) q  F- b
        // FME7. X9 E" I( x. M) I  ?
        if( exsound_select & 0x20 ) {" e9 T5 o! ~- L7 j0 z2 F% L8 r
                fme7.SaveState( p );
6 k2 D$ }% J! T" a                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding( A" q, K( V$ s0 B3 ^# L
        }
' n& A. y2 D/ x. G+ \
6 C+ z6 s, f- \#ifdef        _DEBUG! S5 ~7 z/ V" e0 W5 w3 H8 A
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );/ Q: O7 W* z6 t% M4 b, C0 d8 Y
#endif3 C' ?- _2 Y' g' A  r
}
) F% b& w$ T" n* ^4 r8 p
' P/ F0 f! S2 R# T9 pvoid        APU::LoadState( LPBYTE p )' d  i1 D: m4 ?( T2 v! Q4 U3 _
{
) R3 X9 I2 V" A& ], T, m; R        // 帪娫幉傪摨婜偝偣傞堊偵徚偡+ @" H2 u* ~5 m$ d6 s$ [) X
        QueueClear();5 S! Y7 r: k: |2 q* H. p2 S

/ C8 u5 ~' Y5 ^* n% N9 e& C        internal.LoadState( p );
9 E& [. U9 \3 Z% Q6 A        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding: O; e2 R" D8 M2 j- E( R( A

* @; m; ^  [' ?  m# {        // VRC61 F9 V( m/ u% z
        if( exsound_select & 0x01 ) {% T  `+ f! b0 a
                vrc6.LoadState( p );. ]$ {, F% @& u7 Y. g
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding% U4 P( y5 g, Z* D; r
        }# @& v3 }! N; p/ u$ U% n! l" d4 {, y3 L
        // VRC7 (not support)  w$ @% E( l, q& ^8 k4 E5 h
        if( exsound_select & 0x02 ) {
# O# m& s& Z5 ~/ Z& p7 H2 q                vrc7.LoadState( p );
4 Q2 ?% ?( V$ O$ o/ U                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding( [3 }% w: F/ U& v
        }; Q5 m- [  J1 Z, D4 E0 m% {
        // FDS7 i* _% u1 O$ b/ B. {, [
        if( exsound_select & 0x04 ) {* \! Q2 b! g. y! @4 k
                fds.LoadState( p );+ E3 w7 h; x# E/ L
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding: N9 F) i# P4 m' m0 `
        }
" i& E4 X' s5 O        // MMC5* z/ c% q! m% |6 r
        if( exsound_select & 0x08 ) {
0 m4 Y6 k' `  V, p2 q+ X0 ^                mmc5.LoadState( p );3 x; P; H4 O( q9 a/ }2 \2 q
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
4 {6 v0 C6 y( a1 Z8 @5 S9 W        }$ a# W+ X, @5 x! r
        // N106
+ G( \& O$ y8 ~        if( exsound_select & 0x10 ) {& X' ?. u) L4 h
                n106.LoadState( p );/ n: p( ^3 w! Y  H7 S. c2 E
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
$ h6 Q# }& a9 z/ T# x+ Z! D; \2 {        }
5 P7 R9 m7 n4 j        // FME7  @% a& I5 f% K9 N+ S1 g% r7 T
        if( exsound_select & 0x20 ) {
; @9 A2 Z% }+ }; q% Z0 v% }                fme7.LoadState( p );
! \9 K- |, A3 S% ?                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding9 z( [2 s8 j1 x" ^$ U4 |( i2 c$ ~
        }
" b4 Y5 q/ w( y) O4 g) ], l! \}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 - \, p& r0 v; d1 f& l
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
7 [* z& L; D+ c5 `7 h; W/ w  U% I) c感激不尽~~
- ^. d) ]2 }! f) \" A
恩 我對模擬器不是很有研究,+ T7 q7 h3 a3 g, z
雖然要了解源碼內容,可能不是很困難,
8 R$ i4 l+ N8 v. J! w3 j: \9 A  q不過還是要花時間,個人目前蠻忙碌的。
) z' m! C0 S" t) ^( C/ m
3 v( ~* b4 `$ ?# V3 X給你一個朋友的MSN,你可以跟他討論看看,( Z" y- }" O' D) x/ O4 c
他本身是程式設計師,也對FC模擬器很有興趣。, h5 ?0 v" g: j

6 I/ @  c7 x1 q' g* M# @8 U% GMSN我就PM到你的信箱了。
9 c. i, S; H0 D* V* }  y( U8 a3 w' {% d  y( H% [
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 * X1 o  ^; X0 K
呵…… 谢过团长大人~~
& m$ y; A5 e. r; w$ P1 O

5 z- ~  T2 I- Z" G1 j/ K( D哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 ; o  G% @: p; e+ H  i8 S
团长的朋友都是神,那团长就是神的boss。

" k( v* _8 J; @5 L哈 不敢當,我只是個平凡人,
% R+ K" g4 X6 C( y1 D8 k要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
. s) G) t6 K$ d& t" ?ZYH
( Z* j# d! [! B& jQQ:414734306
* n2 R7 V" V3 E( A. K2 t3 i) a" A( DMail:zyh-01@126.com
" Q1 u% D6 e8 a4 t
, \4 f1 l; e  l他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 8 O9 j1 O7 S- R3 o! v9 s
再次对团长大人和悠悠哥的无私帮助表示感谢~~
4 {$ G6 g8 ?2 Q" I
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-13 17:11 , Processed in 1.088867 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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