设为首页收藏本站

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

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

  [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?
* B4 A( Z! A- v2 `$ l% e. wPS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。4 Y: B9 c8 e8 o) D- W# h
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
6 t( m6 E4 F4 X4 `% [' C这里有相应的模拟器源码,就当送给大侠了~~
8 M# \' V# `  N$ Y, e$ F' K3 _6 [! G7 Jhttp://kenkao.qupan.com/5096520.html
回复

使用道具 举报

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 ) h- F& j: T/ C& v- O1 V
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。8 t; l# ^% {& ?6 o1 C5 Q5 Q
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~0 Y; o3 Q. W( m. j$ ?1 P
这里有相应的模拟器源码,就当送给大侠 ...

5 E& _. J( u5 N$ ?$ k; t聲音部分(Audoi Process Unit = APU):
, E0 K# q  d* t6 B) d- T. w! T% J; L.\NES\APU.cpp4 w% ?9 D2 y* n9 h) g
.\NES\APU.h
' t; ?. Z/ L) |( b- u
! ~; x- Z$ n( C3 y
) K2 m, S& N  z6 m影像處理部份(Picture Processing Unit = PPU):
- ?2 @5 V/ R5 C7 F9 G.\NES\PPU.cpp
% x, H4 o( K; E4 k9 a.\NES\PPU.h
+ t' e5 ^8 c1 W- m  ?7 y6 X9 M( `. R
如果原碼用C跟ASM混搭也不錯
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
, l0 l' c- Z- _" J/ M# U/ }; K感激不尽~~
回复

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:4 a' u7 T- L# ?  [. e! }& I3 T
(由于很多专用术语和算法机理都不明白,所以看不大懂……)! Y4 K$ ]# D- c8 G
//////////////////////////////////////////////////////////////////////////
! ~8 r3 T( d' C//                                                                      //
4 J  v, Y( O. u* r- r- I3 j//      NES APU core                                                    //+ V3 @0 d+ f7 r  m6 G) ?: y5 Y
//                                                           Norix      //
) Z- Y$ _7 l) M8 `- M5 e//                                               written     2002/06/27 //
6 |* D; S% L5 _2 s, R//                                               last modify ----/--/-- //
- S5 y$ M1 F. Y( X5 t//////////////////////////////////////////////////////////////////////////9 q. I6 ~, ^. ]5 ]6 J7 I
#include "DebugOut.h"" Q4 e! {0 n) }) A  y
#include "App.h"
: o5 \7 E, f7 J0 \: |+ Z5 p#include "Config.h"
/ m1 ?6 k2 Y: G) f( k5 v& s- Y1 \6 b8 N' S' I
#include "nes.h"
( X1 h; {! {; j7 s  Q+ X  C: `#include "mmu.h"
4 {! [  T8 }4 M2 G! f1 U#include "cpu.h") D  O. J2 Y/ m( _7 H, Z: |: [* C
#include "ppu.h"
9 K; g2 ^) }$ X) w/ N+ S#include "rom.h"; {6 @2 h3 |8 A% z- s1 U3 l) J: f
#include "apu.h"" _2 s: H  e% G9 S0 o' A

. Z8 o' |9 v' C// Volume adjust% f" a4 Y' C& ]! Q7 b# G
// Internal sounds
3 G3 W! q# U& @* u#define        RECTANGLE_VOL        (0x0F0)
% u* R6 d6 u8 X#define        TRIANGLE_VOL        (0x130)
1 |! X4 {% m) |% B; K#define        NOISE_VOL        (0x0C0)6 L( L7 ^) s) W' _( B! |
#define        DPCM_VOL        (0x0F0)7 C! q- ~' [, L7 k
// Extra sounds
+ m0 P# ^# J# N( C9 u2 e2 E6 k#define        VRC6_VOL        (0x0F0)$ K" n1 p7 e3 [1 Y; |, N
#define        VRC7_VOL        (0x130)1 D( T4 P  I6 H8 r5 j8 S
#define        FDS_VOL                (0x0F0). w5 T5 V8 `1 ]! {' v' c' l9 S
#define        MMC5_VOL        (0x0F0)
8 C, K( S" r( v; z/ Q#define        N106_VOL        (0x088)2 C  P) [( o" X+ P; C6 e' d9 Y0 y
#define        FME7_VOL        (0x130)4 s! X* {: c: X7 k
1 j/ D1 v" H0 n
APU::APU( NES* parent )
" D+ V% Y& P5 c, U  u  T/ C{
9 ^3 e: `% |/ Q2 E2 h; s        exsound_select = 0;
: }) N# j$ p, m! w; P# g$ {: K0 L5 y2 f; s, {. j
        nes = parent;
9 s4 p8 W. t# a2 B2 R; J        internal.SetParent( parent );
. B2 E, C, i( Y$ }0 P2 Q% c) R% C' f
  e( P: e. U: r  B        last_data = last_diff = 0;! y. G7 m% [: }( {# d/ ]8 s% y3 e

1 R6 V4 P9 F6 l: s0 A        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );; Q2 g: E! I) A* B% t3 J) Y! z# e% a
. f( [3 K3 c+ e
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );) H  N4 ~3 y, J: x# }% n
        ZEROMEMORY( &queue, sizeof(queue) );- S, c9 f, ?0 F: f! k
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
+ v& y1 Q+ `" N& t, a
7 n, i1 }) @( A# S        for( INT i = 0; i < 16; i++ ) {
* G! V2 x7 R6 F6 ~                m_bMute = TRUE;
0 t, S* j' ~( o" }. P5 D" d' H8 v        }
& D2 ^2 q3 z! h}
+ |. S5 c2 [1 S1 l
( x5 e5 N- P. Y% q5 W( B" q3 mAPU::~APU()4 ^/ g5 k; p& a7 }+ i4 m
{7 B  W1 n" i& I' @4 T) i, e+ G5 W
}* `4 _2 Y4 K& G' z3 `  ~) z0 r

3 l3 K; S( C# ?void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
% J7 n1 V; c* n7 N- B1 }{' l( n6 z- {' Y% |
        queue.data[queue.wrptr].time = writetime;- z% q5 t1 Y% h* d8 L8 B0 Z
        queue.data[queue.wrptr].addr = addr;# D3 D( W5 M1 q6 ^
        queue.data[queue.wrptr].data = data;: V( x4 E/ A0 l4 J
        queue.wrptr++;
" o% x: G: z9 U/ r% {' `) U9 C5 |% Q        queue.wrptr&=QUEUE_LENGTH-1;
3 C* O/ O  _. G1 R+ d; F        if( queue.wrptr == queue.rdptr ) {
6 d0 D9 L( E/ F9 `4 u, }. r0 Z                DEBUGOUT( "queue overflow.\n" );, W+ v# Z3 C1 |' I+ D9 h% Q1 p
        }
2 {- z& b+ {* t; H}) j/ _$ W$ _6 h

, d2 J* {+ j2 c; o# {BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
  \4 n% p) [& E$ x. P# o& u{$ |, k" T6 F; ?
        if( queue.wrptr == queue.rdptr ) {  p3 e( \, F# a3 s, W" s
                return        FALSE;
7 P7 D' n! v# \; E, C- b/ n        }
% i+ l8 k/ X" i! W7 m        if( queue.data[queue.rdptr].time <= writetime ) {
- u) \. B) J0 r- t0 w                ret = queue.data[queue.rdptr];
3 l0 t/ J! n' `0 H                queue.rdptr++;' B9 \/ c& S. B7 A: v% N8 s: p
                queue.rdptr&=QUEUE_LENGTH-1;
0 |, [2 l% `& n* |                return        TRUE;" R% ~) E" J1 B: S# p6 v% N
        }
' W# I) `2 S' `& g0 u8 [2 U3 F        return        FALSE;7 F9 X$ m1 _" y
}
& I( S! X" ~' C* E" b& l0 N3 C. X# N' o! p, j" t4 F
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
% {+ v, ]6 H: |2 |6 S. ]{- P5 w8 @# t  o7 r3 G+ P
        exqueue.data[exqueue.wrptr].time = writetime;$ X, W8 F$ d3 W. X# W
        exqueue.data[exqueue.wrptr].addr = addr;
; a1 f, P2 D6 y        exqueue.data[exqueue.wrptr].data = data;4 u2 G5 H+ f! a, h( V6 N1 y
        exqueue.wrptr++;8 `% r. w* l2 k' l( L
        exqueue.wrptr&=QUEUE_LENGTH-1;
1 `; _% p6 n' g) f        if( exqueue.wrptr == exqueue.rdptr ) {
3 u( F4 F1 U# w/ F) J, _                DEBUGOUT( "exqueue overflow.\n" );
1 R. v' S5 c& Y, Q9 ~        }
3 H, e6 a8 I# y4 _}
  j' l1 \% U) G, l  ]+ s# g( J+ `# @& A! o2 U- Q( B
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
9 K3 v' ^  ^; ?4 [5 l{
5 V. l8 G2 R* z( v! {( E        if( exqueue.wrptr == exqueue.rdptr ) {+ R4 p6 }% i+ [9 d  |9 g% n, ?6 j
                return        FALSE;
1 f4 R  v1 y  f, j6 {1 f# |# J4 k        }
: v4 d1 [, N" G        if( exqueue.data[exqueue.rdptr].time <= writetime ) {& k) C  h' G  t- M  ?  y! X) M
                ret = exqueue.data[exqueue.rdptr];% E9 [! Q0 B, Q6 z8 ?% Q% c
                exqueue.rdptr++;) L$ l7 q4 M3 ^4 p0 [5 Z
                exqueue.rdptr&=QUEUE_LENGTH-1;+ d) _+ I) C( z- b- y- w* ^) Z/ f: p
                return        TRUE;7 Y: \6 V1 v& E! e5 d% T
        }$ z. x, R# @* B+ V/ [. J! G
        return        FALSE;% t2 p0 q" L. F' s: j7 w  A, P
}
) H! s) b% _! g8 I
4 c# a9 {4 S! [0 c7 U6 X4 Vvoid        APU::QueueClear()/ ?. ]5 v8 ]3 M3 L  Q
{
) h: j% Z; c) w1 e" U6 b        ZEROMEMORY( &queue, sizeof(queue) );
+ O/ ]2 P& `  V        ZEROMEMORY( &exqueue, sizeof(exqueue) );
. ?  j  L) _% q}1 q& a8 v( w4 b

: B5 V- X2 u& f) W/ a5 V% ~2 ?void        APU::QueueFlush()
3 I2 h/ R- ]! r* [6 Q/ }0 W{% R! O1 b- v; S, v, ]/ R3 J7 c
        while( queue.wrptr != queue.rdptr ) {8 }1 @( ^. e; `8 @
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );/ F, x4 ^. n: d, ]5 z
                queue.rdptr++;$ z2 e' P" r( c+ a/ ?+ i
                queue.rdptr&=QUEUE_LENGTH-1;
% |1 K0 `6 C( w        }, f, G  z5 w5 N7 k2 l
  c# Z; F, u& v; R
        while( exqueue.wrptr != exqueue.rdptr ) {4 j4 q# U0 E. t* O* {: b
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );( A2 ^( n- J( q( [' w% G6 x
                exqueue.rdptr++;4 j/ u9 X# h2 F: `. I8 Z
                exqueue.rdptr&=QUEUE_LENGTH-1;/ b9 {# E  B# E+ ?
        }& w( a$ x% @' U" R; v8 N' ]& c# N
}
7 l- r$ B, |  j0 [- D; z0 `  w. [8 D& S4 s4 O
void        APU::SoundSetup()+ t) \% f0 H: T7 i
{
2 p; i5 U3 ]3 A! a' G4 N        FLOAT        fClock = nes->nescfg->CpuClock;! [/ u0 m; K; v. S8 k- z
        INT        nRate = (INT)Config.sound.nRate;  B" w9 E" ?3 \7 b1 j
        internal.Setup( fClock, nRate );
5 m3 l; y$ g% p% O0 L* H        vrc6.Setup( fClock, nRate );7 h4 e1 p1 M% M
        vrc7.Setup( fClock, nRate );5 }  N/ m6 p! `' Y
        mmc5.Setup( fClock, nRate );
) k, [4 Q2 k. A) _! ]1 X        fds.Setup ( fClock, nRate );
& w" d1 _" o5 [! F        n106.Setup( fClock, nRate );
. Y4 f# A1 T+ l( v7 x        fme7.Setup( fClock, nRate );
# E$ c! B0 I8 Y8 P( m& h# g}
1 r! n+ N, U9 h3 f+ N( Z+ ^8 c3 p# A4 \4 v* B- o: F# Y
void        APU::Reset()% e9 c- S1 _7 d; u$ C- V  @: f
{4 }  K, K! D" T" d$ x5 g
        ZEROMEMORY( &queue, sizeof(queue) );- ?+ V9 ?$ \/ Y- b
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
6 z2 y9 m- S, s; o" v1 Z7 u; |6 I9 ]' N) I
        elapsed_time = 0;  a9 }1 E$ h2 x/ y: ~' r! `

% i4 v7 |( T) D. v& h# i+ |& o        FLOAT        fClock = nes->nescfg->CpuClock;
% {. y- ?: \8 ]! i        INT        nRate = (INT)Config.sound.nRate;( G4 C: h& E$ i2 q0 T' @2 T8 k
        internal.Reset( fClock, nRate );
5 k6 M: m9 w/ N, ^: t        vrc6.Reset( fClock, nRate );/ `. U, F+ B, ^+ X8 j" S; X, j$ q
        vrc7.Reset( fClock, nRate );' G6 r1 g8 P  j# l1 e0 }7 R
        mmc5.Reset( fClock, nRate );
$ r4 i& }6 J/ Q) u4 I' j& K        fds.Reset ( fClock, nRate );. @) u) M0 B7 r4 H
        n106.Reset( fClock, nRate );# Y1 U/ E7 V! N8 u
        fme7.Reset( fClock, nRate );2 P, e) Q. ^& ]! U

- f1 t, ^" C0 L, q6 T1 j  f        SoundSetup();
& `% w9 H9 ]( w# g$ g- G. x! P$ i}. f7 e* W* H5 [0 h% Q! a1 W
. ^2 H/ m, f* K+ n3 P3 n: x
void        APU::SelectExSound( BYTE data )
& H: X8 J8 E7 g  ]. ~{" L5 v6 f! t* e& a
        exsound_select = data;/ w7 D, k0 s& }
}
) {4 s) e9 W* W7 j& Z. {4 F4 n; \+ N( [& L/ [
BYTE        APU::Read( WORD addr )
' S  d9 q  [/ S3 ^, I; ^{( t3 J; V& `! t7 G4 |- I% e2 n7 a
        return        internal.SyncRead( addr );" m9 h9 R/ W- _; i3 W" N
}" u4 s( @8 r( W5 _# q9 c' p8 B
0 l/ a0 ^% J* _6 _
void        APU::Write( WORD addr, BYTE data )# Z- S! @$ ]; Y! }
{
0 N' _! N9 T7 \; S        // $4018偼VirtuaNES屌桳億乕僩
/ f. X- l+ t5 F5 x        if( addr >= 0x4000 && addr <= 0x401F ) {
$ k$ s9 X/ S  y. V                internal.SyncWrite( addr, data );9 G) E5 Z- ]& j6 S) B3 _% n6 A9 @
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );: _4 a  h; m$ }% v1 y* U% R
        }
6 E) M+ T* o; Y( @}
& ~: q# Z' o! n, e8 f9 H4 `! |. G
BYTE        APU::ExRead( WORD addr )
# p0 r) I8 R, \- y- N+ S$ j{
6 F2 @# S. P) F% }/ w' U0 r! DBYTE        data = 0;
5 O) @$ i) p0 [* C; N" g5 _! ^# v' p& A- q7 {! x' [
        if( exsound_select & 0x10 ) {" l9 s, }% k' _) Q% k3 v0 @
                if( addr == 0x4800 ) {
: E: e& X! Y9 W8 E0 K                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );$ [3 F$ I! F. n% F( r0 X
                }
: }# f0 [  H  X6 c* h0 Z        }1 Z' I8 G& P2 Z% `- C# Y
        if( exsound_select & 0x04 ) {
- `9 j+ a/ M6 j6 Q6 ]                if( addr >= 0x4040 && addr < 0x4100 ) {
1 y7 d! V/ i) Q* I& X                        data = fds.SyncRead( addr );
+ r5 v4 S) y( {& F. S% k! n                }
, f9 N  x; s* C6 a3 a- P5 s        }
4 K) [6 }/ y0 i, i8 R5 X- i        if( exsound_select & 0x08 ) {# ?  i& ^- C: B2 b
                if( addr >= 0x5000 && addr <= 0x5015 ) {
( p; x! N9 p5 O2 ]4 ?1 `  b; e                        data = mmc5.SyncRead( addr );
! j) h% z  [+ ^! z$ F                }
! M* d0 n2 W+ w; G2 E8 \6 X: n        }/ e$ E2 Y' j2 C+ E" b$ z" r
) F7 b9 o. u! J0 \+ G
        return        data;+ x0 F5 p+ s" ?& I
}
/ y1 D9 B" N/ o3 k$ S& s6 Q6 Y3 z, z- U4 i6 |  H" T& }" ^
void        APU::ExWrite( WORD addr, BYTE data )9 _* O9 }! {! V' \/ I
{+ K; n. U$ N" M7 P# o, F4 E
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
; B  n' a& l/ J, \) n- V8 A5 F& g9 T8 R9 k: y
        if( exsound_select & 0x04 ) {
% j" p. h( w" B! ?                if( addr >= 0x4040 && addr < 0x4100 ) {
& s! }4 W9 D& X                        fds.SyncWrite( addr, data );) }; |3 C5 r0 }% J& K
                }, Q2 h$ |& f4 u+ E: ?
        }
+ M- z! b/ C! F; J8 J2 p* t. p+ w) R
        if( exsound_select & 0x08 ) {/ V9 Y- X0 s2 F* U; t7 I. }' y& L
                if( addr >= 0x5000 && addr <= 0x5015 ) {! H# A6 d) l! K+ v% t% s6 S
                        mmc5.SyncWrite( addr, data );
3 ?3 C( s4 a2 [7 k) M                }
3 A9 l, D7 C# s$ A3 g        }. D- E  l" Y. J, t8 f: T  E& X
}: X% [' K9 F5 ~8 s

9 b4 F" ]: Y1 l4 g% R; ^2 n# |" uvoid        APU::Sync()
# n8 b) V2 p$ S7 g2 c{% a- B$ W: k& h) |
}
" m7 \0 x  K5 f3 j# K4 \9 J  v; e( y
void        APU::SyncDPCM( INT cycles )
- _# C5 |  L4 T. u{3 v* H1 S! a6 m0 }  S( ~8 v5 v- j/ d
        internal.Sync( cycles );' d+ h. D5 _- m9 ?( Q
( q$ |4 ^3 z7 U# M
        if( exsound_select & 0x04 ) {
- O7 L+ p) ^) g. Z6 k                fds.Sync( cycles );
8 f, Z; K9 v: ]% _9 m        }- o4 _% r1 l: g* z& y/ W1 [) X
        if( exsound_select & 0x08 ) {
+ d: }9 w6 \# q2 r6 a6 k5 U: n1 m                mmc5.Sync( cycles );( X* K4 u* G7 ?+ p7 d
        }
( M' y% O9 k! M1 z$ y}8 J' w  e+ o" l# T5 @

8 {7 f  l- X/ y  q% Y" |8 Hvoid        APU::WriteProcess( WORD addr, BYTE data )
- R9 b! h: ]4 ~1 F5 E' t. z/ D8 J5 T{
% e8 w3 q: P, f% D$ N        // $4018偼VirtuaNES屌桳億乕僩/ [* S/ r: T- ?5 w- P( l& i
        if( addr >= 0x4000 && addr <= 0x401F ) {
) h2 s/ g7 u  P4 E( k                internal.Write( addr, data );
& T+ G; R/ M- b9 i& Q, \/ s        }
1 L: l4 [$ K  u8 g* v# r. a}% u3 `7 j, f7 F
- n' f0 s- V! a
void        APU::WriteExProcess( WORD addr, BYTE data )7 ^. V, x% \* p$ Q+ P* y4 {2 A& v2 n
{
1 e4 L0 l- @) I8 ~% G% v        if( exsound_select & 0x01 ) {
( N0 p9 p" D; k- |$ o3 k                vrc6.Write( addr, data );( [) O! K: m3 s
        }- |( @" k" g7 e: J
        if( exsound_select & 0x02 ) {, F& I6 |, p8 I: ^0 r
                vrc7.Write( addr, data );
) O, ]3 ]0 D" i$ ]        }
- f! c% W& t/ O- B        if( exsound_select & 0x04 ) {
% g3 W/ ^- {! e                fds.Write( addr, data );
! M& P. y: g" R8 Z  U1 I8 o        }
8 ]  d+ J' _0 n9 D  Q0 w: R        if( exsound_select & 0x08 ) {1 y0 O  o; T4 @2 ~3 \0 F+ n
                mmc5.Write( addr, data );' T+ f4 ]# g0 @, n  N8 }* _
        }
% m4 d5 v5 [4 ~        if( exsound_select & 0x10 ) {( F2 j7 C* r. x
                if( addr == 0x0000 ) {4 ?) j  O, I! T' B5 z7 g
                        BYTE        dummy = n106.Read( addr );
5 y+ V/ l. Q" M. Z3 M                } else {' Z* |% W4 `6 E6 b- H
                        n106.Write( addr, data );6 B' a$ V& B. E. J3 f2 Y
                }
4 |# n' X4 w7 }( A+ v        }
' J9 ~% |5 e: L. v        if( exsound_select & 0x20 ) {
. w, W6 }/ l' F" X6 f) T* K: [                fme7.Write( addr, data );- e1 q; h$ I3 L" o( H+ S
        }  b2 W" D+ M( o
}
* z$ _; R, `7 w$ |! k! j9 ^/ F, ]5 R
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )/ m# ]  W2 {' f( Y5 C
{: j1 m, D9 {+ K& ^4 g
INT        nBits = Config.sound.nBits;( V  \' D* f& T- o! ~- c
DWORD        dwLength = dwSize / (nBits/8);( i, _) V2 r" g6 [0 Y3 m7 q
INT        output;, c5 E) D, D; V7 g3 k6 K
QUEUEDATA q;
$ R, G* N: v5 y; r; @DWORD        writetime;  q0 D' {. N- X% N( d

# J0 W9 D# ^" S" zLPSHORT        pSoundBuf = m_SoundBuffer;$ r( t: S/ R1 c! n  }& ?) W9 ^
INT        nCcount = 0;
2 B" M& R: ~7 P: E& K
- Z: B  O9 W$ j- g8 ~INT        nFilterType = Config.sound.nFilterType;1 l7 I! `& Z9 x" @0 M( w: g' c
1 a2 Z6 m9 Y# Z9 t$ b* b, \: `
        if( !Config.sound.bEnable ) {
8 T' {! Z* N% J; t( s: M8 |                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
5 h4 X: j! z3 _                return;
) z* D3 t% L% c! P* @        }( i1 b* F' a  z, @, Y5 s

' m  b8 F) \5 {# N        // Volume setup( n. D+ ?7 h- F' O" e6 t( h3 t
        //  0:Master
0 \" T; _+ U, @& C" l& e        //  1:Rectangle 1
, x, ~9 K5 K9 a1 H2 v2 Y8 h        //  2:Rectangle 2
; _; J8 a) O" f$ O7 P        //  3:Triangle
7 X1 |  _3 l& r: h        //  4:Noise/ W  l4 F; c4 K
        //  5:DPCM
2 R! L4 s1 C+ I' p7 k$ J        //  6:VRC6$ D& E# K9 S8 b5 s/ ]. o  z' b+ J
        //  7:VRC7
  `9 @5 u6 X: z. d( F        //  8:FDS
7 ~/ K5 q0 `! d+ o8 N( `2 A        //  9:MMC5, G' k) c+ _0 D' [; d
        // 10:N106
1 p7 V; w5 s. [% j; ~0 y        // 11:FME79 [# o- g# i* V+ e- _, Q7 E1 n
        INT        vol[24];2 \  C" h( B5 C8 R/ I2 @
        BOOL*        bMute = m_bMute;
6 t  j1 g8 U2 M; p2 `        SHORT*        nVolume = Config.sound.nVolume;# B; K) K' C4 U- V* ^' d+ w
6 n7 [0 o' A% g+ G
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
/ U6 L# |$ }$ T% B' h9 Z5 B% ~6 K$ l3 M, T
        // Internal' W# b8 d# _( X  R" g% Z
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;, D6 B, ]) [# v$ C$ c# L9 g
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
( ~* P) }6 y/ q5 b        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;: I! X1 ~8 ?6 @" A6 J  `  ?
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;, M$ k8 e+ b3 H0 Q# Q& M7 s
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;/ ~" y& O2 k# q
0 E2 G5 S3 c: q' v4 Q3 h. U
        // VRC6  X4 j2 ^% h  N7 C8 U3 Q# F
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
* s" n* }- H% G* h& {        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
4 a0 g; D( k4 Z) G. e3 n6 M        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;. o+ t  ]7 c; e0 T; e9 u% s  g, a) ^% m

' m8 k( ]5 d( a) w7 z" H2 ]3 {        // VRC78 J" v% d1 ^0 P  L
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;' E! I6 s' f/ {5 s" v: s" w( U

8 o$ I8 j5 r% E. |& `4 C; ~        // FDS# B+ w- d( V) e2 J' g& T% m% G. D
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;6 z4 i" l3 m; [. [/ u6 B
+ q1 n: W! j& E& s* Z3 J
        // MMC5
$ ~4 J( x' P+ m: E        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;+ K' r3 F+ n- ~8 g/ o( E0 }
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
- y; k( A$ A% a& `* {* Q6 W        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;& b; u4 x4 w6 D+ r7 {
7 k8 a! t& |8 @+ j  M6 N( C7 P
        // N106
( k* ~; L8 O/ v5 e' R        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;( z4 t! P! Z0 v
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
% X' U5 D5 m) \4 A6 G( v4 {- v        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;! d1 `) e$ S: v* d! o2 o+ D, }
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ w$ }% y9 J6 K, F0 Z& ^8 V
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
( X! J8 u$ l9 S! w3 s& @) G        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; C0 W/ E; E' }/ L4 l( }
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
4 r% N5 ^# F. w, G2 D4 k6 G4 P        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, X% o- m0 I8 l# [3 [
% g4 ~9 i, f  N8 p$ ~7 H        // FME75 h  N/ i, c  p# n
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
9 E, a" G  v) N! {% s        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
8 I; @3 p. Z+ Q2 _+ d1 B        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;: O9 c# ?' S4 A/ S1 J9 m

+ T" K+ n! i9 s5 n9 d3 t& I% @//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;2 X3 b$ i+ C1 Y  C/ l4 P5 g
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;/ k, A, I# Y3 V8 {
& v& }3 v1 A+ \& g
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟; G& |4 C* k* X3 o1 I% d" z5 I
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {3 M& [0 u" Z- N7 y/ T4 _$ O2 f0 B2 ?
                QueueFlush();
$ W9 T, b, x0 h. G0 i9 Z        }+ q! E2 P! @5 @6 u! z

3 A% {+ v# C  A& h" \$ V6 e+ O! c; x        while( dwLength-- ) {! V9 r$ f. j. \4 m: Y6 V6 X* F
                writetime = (DWORD)elapsed_time;
4 L6 e. w& ~% M; d* j4 Y
6 T) J5 Y) t' j: [. J                while( GetQueue( writetime, q ) ) {) H, g8 [3 p& y! \# k- y. ]9 A
                        WriteProcess( q.addr, q.data );
: c2 c. K$ u9 l4 @                }& h% {* b& F3 F( S3 z, _
8 I3 I; q3 |$ @& A- v
                while( GetExQueue( writetime, q ) ) {
6 B4 b" `( D; S/ _& A- j; Q, k                        WriteExProcess( q.addr, q.data );
5 i$ O- D$ R; j% }                }
# ]& c0 w+ J* E6 [& Z& Y& G
! M; _2 f2 t* @- c1 m                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
3 L" ]# w; D% y" E( y                output = 0;
1 I: k" k4 R1 R5 @                output += internal.Process( 0 )*vol[0];
* u3 h: Q) p1 r6 c2 ^                output += internal.Process( 1 )*vol[1];% _# x/ ?9 ~. E9 ]9 u8 d- a+ s6 a
                output += internal.Process( 2 )*vol[2];
9 Q; \2 o/ G: L  P+ n! z' W* [5 W7 a                output += internal.Process( 3 )*vol[3];
( z8 L% ]. a$ N9 e3 l* n4 D                output += internal.Process( 4 )*vol[4];  g+ k: Y) Z# z3 f+ _8 k
4 Y/ u0 T5 }' u! _- x
                if( exsound_select & 0x01 ) {
1 T+ e( d9 d8 l/ [6 x                        output += vrc6.Process( 0 )*vol[5];0 y1 M3 z( I& A; f8 n& S+ q/ [0 {
                        output += vrc6.Process( 1 )*vol[6];' E' r  Z) s  i8 Q- A" H4 E* }
                        output += vrc6.Process( 2 )*vol[7];: r6 ]# C/ Z* x
                }
7 j) ~5 H' }9 Z6 [& {8 X/ i3 ?                if( exsound_select & 0x02 ) {5 D/ k3 Y& z! _7 x' M; P0 M( O- g& M
                        output += vrc7.Process( 0 )*vol[8];# d6 {5 `3 R4 w
                }
% e5 v7 \. |/ S  X3 V- j2 [$ K  L. p                if( exsound_select & 0x04 ) {
' P4 `" B) M" U                        output += fds.Process( 0 )*vol[9];
+ p& g% s. E2 E' b                }
( X6 k# }" L, K( D                if( exsound_select & 0x08 ) {
1 E$ C2 g3 \8 Z9 W' ], ~+ M                        output += mmc5.Process( 0 )*vol[10];
& L  K( U+ A4 z) J5 f                        output += mmc5.Process( 1 )*vol[11];! \% U4 F( w$ J6 w+ l, j
                        output += mmc5.Process( 2 )*vol[12];+ J! Z( i1 V" v$ a7 i  W5 ?: Z
                }2 C# S% V1 y5 f, y: L
                if( exsound_select & 0x10 ) {' V% {/ {/ v$ @  r4 G* z7 R$ ]
                        output += n106.Process( 0 )*vol[13];
" B6 F& i7 D3 n3 j                        output += n106.Process( 1 )*vol[14];+ P$ \1 t; K# f- O3 j/ ~1 X, P9 o
                        output += n106.Process( 2 )*vol[15];7 F  A, N) P+ p% `2 O. @1 b; @% G; ^
                        output += n106.Process( 3 )*vol[16];
6 s1 Q  H. ^# p! t                        output += n106.Process( 4 )*vol[17];" |1 ~. V. n& [' b: o
                        output += n106.Process( 5 )*vol[18];
, A2 y7 x8 T! o6 e                        output += n106.Process( 6 )*vol[19];$ ^* v+ i( u% c+ w
                        output += n106.Process( 7 )*vol[20];
+ b% d- d; P( R6 U- d6 K                }
0 S. V0 Y: Y+ t, s# i2 W                if( exsound_select & 0x20 ) {6 R) Z/ k" g: B8 n0 e/ J; |" P
                        fme7.Process( 3 );        // Envelope & Noise
* W0 ^, l7 e% V$ O. G                        output += fme7.Process( 0 )*vol[21];
3 A  b; G5 j( X  E% _1 s4 q2 A/ w                        output += fme7.Process( 1 )*vol[22];  `4 p4 T' A  N
                        output += fme7.Process( 2 )*vol[23];
: ^/ Z4 j( I5 z9 D                }: B+ s5 f" r( x* J4 H+ v$ J

$ o- A: U/ X+ Q) g5 D" b* I6 }                output >>= 8;4 l7 K; N+ G8 g7 t5 Q- k, R0 j
$ J/ _0 T. q' |9 S9 u& m; b
                if( nFilterType == 1 ) {: G: k0 Z4 X1 c6 G/ G, T
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)3 q5 ~! p' s8 B
                        output = (lowpass_filter[0]+output)/2;% r% _0 N* j5 j7 n* M  K
                        lowpass_filter[0] = output;
; v" r$ ^# H4 d' m  D" c7 F% P                } else if( nFilterType == 2 ) {; h1 C% c, M; P1 N. r% s
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)+ Q: Z. d9 U6 h, Q' l
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
6 [# m2 R% i; f1 W! B                        lowpass_filter[1] = lowpass_filter[0];, d. {) ~! @6 x. K3 J9 }  L
                        lowpass_filter[0] = output;
4 x" L3 R3 s) M7 T& b                } else if( nFilterType == 3 ) {
2 r) }+ b  n7 R- H2 \4 g                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
* W0 J8 a3 V3 N# D$ x. g& O4 N4 E8 D                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;, n* T( q/ K4 u  u2 _
                        lowpass_filter[2] = lowpass_filter[1];
9 L4 F- X: a$ l( o0 @7 ^; _+ \  }4 T                        lowpass_filter[1] = lowpass_filter[0];
1 B; {$ I/ z6 I7 C0 ^                        lowpass_filter[0] = output;
4 O& c, @+ X# ~                } else if( nFilterType == 4 ) {
6 L! }/ v3 V" y' k1 `                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)3 z5 s* K& G; \% a
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;  D2 U; @* w5 r+ o
                        lowpass_filter[1] = lowpass_filter[0];
/ f+ k4 j0 k: A2 P. K& Q- U2 Q                        lowpass_filter[0] = output;
! q9 n8 [4 b, `( r, T9 g3 Z! w                }
9 N$ I# X! ?' R% o
1 h% C# o% c% X. B; {. v5 j0 W#if        0
2 X+ g& V% H& l8 r                // DC惉暘偺僇僢僩
3 Q/ \% M" e; e  c. ]                {
+ L" z* U, h) S) ~                static double ave = 0.0, max=0.0, min=0.0;
; v: u- f- j; |- l" ~& G                double delta;! [2 }; ^9 D: H& e; X) q: C
                delta = (max-min)/32768.0;
9 T2 J* W* c% D  I( z$ b3 ?                max -= delta;- m2 {# x5 [# j+ v
                min += delta;
- o, d8 r; h1 H; m9 h                if( output > max ) max = output;
, ?* Y3 q7 C& \2 m                if( output < min ) min = output;( P) K8 a8 d, l1 s/ [) G  G
                ave -= ave/1024.0;8 Q7 N: n% T! ]" A. E5 v4 D: O- `7 |
                ave += (max+min)/2048.0;
8 [8 B, U% c0 U- {  \0 F                output -= (INT)ave;
  a" \2 a; F- ~% f: b$ D  i                }1 b  ]0 k* y& r0 u( J
#endif: v5 s% w7 o" }% B5 u
#if        1! l3 @4 y5 h% [) ^
                // DC惉暘偺僇僢僩(HPF TEST)
1 f: L5 M$ l, A                {
4 @3 K; j- v( Q( A//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);* s- e* V% v6 a0 D% s; n; }
                static        double        cutofftemp = (2.0*3.141592653579*40.0);1 ?1 H5 A6 S" E' d7 d6 f' n
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
0 t5 b" ^! N1 F+ w                static        double        tmp = 0.0;5 y5 i2 M5 T2 y0 F
                double        in, out;
. K9 M' M1 |" |1 k8 Q
) E% n3 q  }) r  K: _+ B6 X4 ]- b" k                in = (double)output;. K. K) [" \7 a, I* A
                out = (in - tmp);
; o" X- c* q5 \                tmp = tmp + cutoff * out;* B" [( _2 ?  ^  _, ]% N+ c7 Q
! ^4 }2 O8 [: x) k  k
                output = (INT)out;
6 c8 k$ J* p/ j/ W                }* a1 f) w3 h' x, k
#endif% R; e* i# `6 [$ Q; @4 X) @: n
#if        0
; H5 Q, v" b* @- D5 ?                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
( z+ T  b9 J! }3 s" J1 O                {
7 X) |% u' s9 R                INT        diff = abs(output-last_data);
: i( @* G. ^- l0 Y                if( diff > 0x4000 ) {; f5 W, I5 x: L/ y2 ]7 _# N. z
                        output /= 4;
  d8 Q: f, N2 o% R3 v) x- t                } else * K4 y* D% t4 ^; ?) z$ o
                if( diff > 0x3000 ) {
  ?* v  T- F+ x" T                        output /= 3;
8 {* V8 W, h1 L. B: M( N4 @( e                } else
' |8 ^' k, T! |                if( diff > 0x2000 ) {
8 C$ V2 g9 a7 ~                        output /= 2;
: \" l: f3 G3 ?) c                }
, w: g0 P1 N( W* Q                last_data = output;
8 D9 L! x& k) D( S" t: A5 Q; a                }
, K: L# K# S1 u3 d#endif
% t& \6 N2 r/ m5 Q4 J9 L                // Limit0 n9 F  ~* D$ i, n
                if( output > 0x7FFF ) {
$ P. h: t6 Y2 A' X                        output = 0x7FFF;0 g: @. @8 A# E: B0 }: o( @. N1 D
                } else if( output < -0x8000 ) {! [5 r4 V9 a. G* I$ s! T
                        output = -0x8000;; `+ h; a& a6 l; [* p; Q# J' Z
                }
! _- J0 O/ T1 N* \% h  B+ ^+ n. C1 s( Y7 E
                if( nBits != 8 ) {( d4 t3 @. V$ G9 Q
                        *(SHORT*)lpBuffer = (SHORT)output;9 f7 O- k* f( h
                        lpBuffer += sizeof(SHORT);- l0 U( j4 o) {, ?% _' }
                } else {
2 {- g, ^# S+ a  G2 b                        *lpBuffer++ = (output>>8)^0x80;6 q' q/ L7 f: W# N' X
                }
  U1 o3 h9 _- i6 Z+ ?2 x
6 _/ {* _- B# h1 b* U4 Q                if( nCcount < 0x0100 )
, G) N9 w" q5 s                        pSoundBuf[nCcount++] = (SHORT)output;
" t, {* u, f0 Z" S+ g
. S0 T2 d& y- k- E: T  v//                elapsedtime += cycle_rate;8 n3 B) D- L& x$ I" F
                elapsed_time += cycle_rate;
) I' r$ O7 z* k% u+ N/ B4 j) \        }
! M' O" X2 Z8 H3 {' i1 k- N% o' ^+ Q% |% J
#if        1
9 x- [8 V! i  I1 U9 q$ S: [        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
, ~& |: W6 @; X' r/ Z3 q                elapsed_time = nes->cpu->GetTotalCycles();1 ]1 e. a: s' U0 ]8 i$ M
        }& g0 }/ G, S2 l2 O
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {& x! ?8 ^( @) c
                elapsed_time = nes->cpu->GetTotalCycles();% c* h4 J$ _' M' R
        }8 `* m' h# c$ b5 h3 E2 H
#else
/ K$ M* d# w5 k& W+ I        elapsed_time = nes->cpu->GetTotalCycles();% G* N2 H8 E6 {/ k2 U, ~
#endif- {1 E: z' B! w, ?; T6 \
}
& J& M/ ~  p' V6 N5 {7 E9 c5 R
6 ^( J7 C- [8 Y0 U# ?// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
5 t$ v% J& u4 V1 Q3 T: Q! TINT        APU::GetChannelFrequency( INT no )9 U5 e8 p+ d& |
{% I- p9 y, \3 u+ e" m, [+ V
        if( !m_bMute[0] )) g% P5 R) H( _' o6 v; Q0 T2 i
                return        0;/ A) `6 V2 Q6 f* Q2 R8 k( `6 C
5 J: u. O  q2 @5 v0 s; G; Z
        // Internal
8 c* y) f# u7 _        if( no < 5 ) {% L0 a8 x( G, C% _# M2 y# T" |
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
* d: M/ F9 n; `, N        }
# a* Y8 z# b0 N1 f+ [6 Y- Y        // VRC6' m" W2 p# Y  H$ u9 n7 P
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {# ]: i6 p$ G8 {. g
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;: r: P; T6 o# i6 s# R; S
        }3 T. f2 c6 @+ O# s; e
        // FDS; D: S/ X( [. d+ B, j6 l, d+ i
        if( (exsound_select & 0x04) && no == 0x300 ) {
. d3 O$ C  D5 i                return        m_bMute[6]?fds.GetFreq( 0 ):0;% t  E/ [* w" v8 _
        }2 ]3 C; q! a  c. Y; G
        // MMC5
' K* _: k; a" n. ?        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {2 T, u/ s9 B$ i4 ~; \+ B
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;' Q: U: e& L* L7 g* G$ c0 t! p) G
        }8 N- _8 j' H' n" ?- v+ i
        // N1063 N& ^4 ?; p% v, ^/ C
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {4 j' O2 ^2 `4 R  n/ X) e2 d
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;3 Y5 A  I) S0 R/ U8 l
        }
, O% K3 Z( M* x        // FME7
6 [$ K1 h+ _, {* `" k        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
0 ]. W' [3 P! J& K% {, p2 x4 x                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
1 \# b* h) L: g        }
6 m) q' f, p* l$ j( n' \4 S+ S        // VRC79 @0 S" q3 j. B7 L. m2 E, R
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
- `+ x6 H1 C% l3 ~/ w( ~2 |% e& _                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
/ R1 `8 d0 b( A9 L# B5 w        }
6 @/ J+ }# L" N6 h$ T8 _. n        return        0;; h3 r1 d3 y5 W# b8 p' s. w1 ]
}
; Q" h% u7 k3 M: Z( G3 r, p/ V8 E
/ ^( |7 {' O& }# {7 |7 S// State Save/Load) z% o3 J& N7 m  y4 b
void        APU::SaveState( LPBYTE p )- ?) ?; _7 c6 H$ o5 W% u" ~
{
* {7 Y, P: j' `9 k$ Y+ _, ~#ifdef        _DEBUG. Q! M* \) ^* F9 q4 q
LPBYTE        pold = p;
0 i' _' h4 ]  m% ]( p( o  ]  u#endif5 }6 h$ T8 C9 \- C' C( U) I

* h+ C4 l) C- s/ P- |        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞7 Z2 V3 u% E( {& y
        QueueFlush();7 z4 Z1 r" c& J9 p; R
) D# Q1 E2 i$ J
        internal.SaveState( p );6 Q; y% @9 J# C9 ]' ?7 e
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding" y+ h7 _# E( ?& k. b3 ]& e/ k
) w4 l7 t# y& q6 z3 o' K$ c9 Y
        // VRC6
# m  l" e' O8 u, P+ w6 w        if( exsound_select & 0x01 ) {9 j1 M8 K( r! l3 j. t
                vrc6.SaveState( p );
* J, D$ `, A4 ?  E( A                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding8 |1 A+ K9 y2 U' b! G6 ~- X
        }
! Q  w' ]6 U- ?& P) {# t        // VRC7 (not support)
- h2 D$ t3 n- ?' k/ h        if( exsound_select & 0x02 ) {4 Y" a) r" d! [8 h' a; F2 Y- J* g
                vrc7.SaveState( p );! W+ x* c' k6 t4 @4 N2 a
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
1 i! i9 }, t. D" n        }# }# t" q4 w8 P  V  N
        // FDS. V. e8 f* N7 n
        if( exsound_select & 0x04 ) {! K# p. o4 K# ^7 t9 ?
                fds.SaveState( p );
& D/ I4 M: U% i; z9 F4 D                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
* c9 j2 e5 X- F+ q        }
% J* v+ `7 T' E        // MMC5
# j6 I! B7 p* l6 f        if( exsound_select & 0x08 ) {- {& j& U3 d9 e1 e
                mmc5.SaveState( p );
; y, M' U+ S. v& m                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding9 o" u; e, Y. f" Y5 _
        }
1 z* Z* e. M  F        // N106
2 e: K- s! S9 L, k4 U2 X' T0 Q        if( exsound_select & 0x10 ) {
' E- @4 K* ^  m2 r                n106.SaveState( p );- x" g0 L; A9 F# ^$ U
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding4 S* d4 T) P6 E6 c
        }, N* r3 `' A' d! x
        // FME7- G7 C) Q+ }& s% D0 D( D
        if( exsound_select & 0x20 ) {
0 M) B7 ]+ R! h5 y- z6 ?# m+ ~) V                fme7.SaveState( p );
; o6 M7 f, p1 U! u5 v7 G                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding+ z+ k( F5 t0 a
        }, n4 l+ ~& B2 S
# w$ Y: q! t  P, T! L3 U
#ifdef        _DEBUG  V0 q% n" _- B4 p. o
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );( \: Y, o/ H: G: p8 K
#endif) {% w3 l5 s6 Q, w" q& `
}
: N: W6 X4 x; t) E  Z. d" c
" Q4 `4 C+ e2 Q: R1 Svoid        APU::LoadState( LPBYTE p )* N( w; _1 g" ?% a  N
{) x8 R' x/ j& f$ \5 f% C
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
% @# ?  K* g- J- C) ^        QueueClear();
9 |) }, E6 X- J0 w4 d2 X- K
/ e7 F3 I4 i6 T$ n6 E        internal.LoadState( p );. B1 H/ Z- s! s* ^
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding5 U$ |) R2 @; Z9 ~% x: R% k3 V$ U
; f% @' k2 B" z7 H0 e8 V
        // VRC6; [6 @5 N5 a- O$ c6 w; m) ^. R
        if( exsound_select & 0x01 ) {4 Y$ ]4 e! c. ^8 c: k
                vrc6.LoadState( p );
! J( A% j' t) E8 _6 n                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding  V- Y- _1 ~2 f( F5 J: k5 U8 o
        }
( N* h; d# p$ j% P" o% }        // VRC7 (not support)8 l* l0 I- o! `) w% L# g/ |' w
        if( exsound_select & 0x02 ) {
7 w1 E2 b  p- O  n                vrc7.LoadState( p );$ l1 V; O7 [! j7 ]2 W
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding: k8 ]& R' K3 N- ~" Q+ z  d
        }: Y) F: f# c; U8 r/ k: G
        // FDS
7 H1 X5 p) J5 G3 |        if( exsound_select & 0x04 ) {: h7 W; \5 q. z
                fds.LoadState( p );
4 G! o" }2 H# ?+ r" F                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding; q3 ~3 ?8 s9 u. H2 s2 O
        }
$ R4 ^) R; O2 h+ [; Q2 W8 V        // MMC5$ u' H% d  t. F& {2 b
        if( exsound_select & 0x08 ) {
2 f& O, ^3 ^4 r' _; ~; M6 `                mmc5.LoadState( p );# v# [( B& I& H0 c) T$ P% M
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding- L( Q4 m% w5 y8 n! O
        }( u4 j$ Y) M: M/ q9 T3 I" c
        // N106
9 N+ W9 a) U9 O        if( exsound_select & 0x10 ) {0 g) }4 z2 D8 J! W
                n106.LoadState( p );' T) V) o& x' d
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding; h% G* y5 M9 v6 H1 t
        }8 h4 |$ h+ g4 l  o/ b0 `
        // FME7
) ?# H( J. a8 q; ~        if( exsound_select & 0x20 ) {) i' m' X3 [7 W7 t# _8 o( H2 u0 g, w
                fme7.LoadState( p );5 i& K, c3 A: {( M
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding1 }- j0 I  s$ m) j. P' `' T
        }
5 r* v' _' r9 Y& g}
回复

使用道具 举报

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 6 Q  h: Y5 T! |+ \  u
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
% ~; t' k  ^6 t# Y9 X" l9 x感激不尽~~
* @* I7 Y, O' K2 W
恩 我對模擬器不是很有研究,1 L; J& j# j9 `5 Y
雖然要了解源碼內容,可能不是很困難,
- S3 N. D. b  Z6 k9 {不過還是要花時間,個人目前蠻忙碌的。- o" \/ \. [# {3 H

# p9 W9 B! P4 a9 j( t給你一個朋友的MSN,你可以跟他討論看看,
% s$ D. x' y: }( F) b0 I他本身是程式設計師,也對FC模擬器很有興趣。
* T+ v% e7 `$ \2 x" r. y9 }% y7 U, h1 Z; d5 p  {; @0 t
MSN我就PM到你的信箱了。5 v& a) l' Z) G
5 |& T5 V* z' U/ ?& u7 t
希望你能有所得。
回复

使用道具 举报

该用户从未签到

 楼主| 发表于 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 发表
+ A7 u/ j8 k- X$ M4 A呵…… 谢过团长大人~~

4 w$ H4 ^2 V1 t8 }  v
# k( K" M* @) |& K7 R哈 不客氣,算是順便幫他找個伴,大家可以一起玩。
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 / s6 v6 ]2 _# d, Q
团长的朋友都是神,那团长就是神的boss。

% l1 @# S3 |/ H' P! b% ]哈 不敢當,我只是個平凡人,
% `& M8 o# ?9 H* d$ {要吃飯喝水,光吸空氣是不會飽的。。。。 :)
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙; ?$ f) U: u' a9 z4 `* ^4 k
ZYH
8 l0 {/ L. k2 WQQ:4147343064 E+ U" t6 c- w
Mail:zyh-01@126.com
3 p: F+ T$ o" L% D: w2 q$ M- t( W
4 H* B! b+ Y2 ]2 u) @, I他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 8 @: c) T( U% N) T4 P. o/ P
再次对团长大人和悠悠哥的无私帮助表示感谢~~
$ X- Z5 Q% ^1 j1 R
不客氣  ^_^
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-4-6 17:02

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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