EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?
3 j, [' n$ V0 X7 Y) Q* a+ H, LPS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。" D+ @2 A$ Y9 K+ I. u" S
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
/ U( d% ?; _4 j这里有相应的模拟器源码,就当送给大侠了~~: F0 o$ p* w+ M6 u3 V  ?
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
2 _" m; s- U0 }' r能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。; s3 o+ N9 e1 P8 N
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
( E. Q/ V7 P( D2 m% B' A: E! z这里有相应的模拟器源码,就当送给大侠 ...
6 A5 i$ ?2 P3 }1 f4 g" x
聲音部分(Audoi Process Unit = APU):% P& b2 z9 p6 K! c! o2 h! I
.\NES\APU.cpp7 w. U# S/ t/ m* K! z6 }4 k9 W2 c  `
.\NES\APU.h
% \3 j/ }! U5 W; w$ n5 l3 n  ~: y  Y

/ _" b( m, {  s4 |影像處理部份(Picture Processing Unit = PPU):
* P' I9 L7 U- }! d' z4 ^" D.\NES\PPU.cpp( c8 \& c. ^( r4 F$ r
.\NES\PPU.h, P% g8 K. E) D% p0 `- c) D+ [; D
% i: Y( s" o0 S4 P8 ^
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
( u/ b. C# S8 T: G0 N" q感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
( _5 {" R6 c8 ^8 z$ J' K( J7 O(由于很多专用术语和算法机理都不明白,所以看不大懂……)
) `# [2 b* L) E//////////////////////////////////////////////////////////////////////////
) U7 g) G* A+ B! N2 x//                                                                      //! L( m5 ?. r* Q
//      NES APU core                                                    //* g$ ]$ ?9 t2 a5 Y
//                                                           Norix      //. ^' L0 u! N9 C' N0 w9 n& u4 l( E4 ^
//                                               written     2002/06/27 //  f! a; p/ f" S& L: }# W3 S* g
//                                               last modify ----/--/-- //
3 Z, R( I6 V7 F//////////////////////////////////////////////////////////////////////////+ O( h4 x" K8 j/ T
#include "DebugOut.h"1 f/ ?# Q* s; z: D4 }- e0 L
#include "App.h"* }7 U0 U( U5 [2 ?8 G/ R
#include "Config.h"
& T: ~* D4 ^1 |
7 R% m' b, p& o+ n#include "nes.h"
+ Z( i5 m; v; M6 n* [) P#include "mmu.h"
$ W5 T, K/ \1 ^4 ?4 M: g+ i#include "cpu.h"
% V3 z* s: P7 ~; K" t#include "ppu.h"* N+ ~$ q" ~9 B. ~4 V
#include "rom.h"
, D) w; `" ]+ d1 R#include "apu.h"
- e( C3 ~' E: j2 e0 r, F! _3 F
7 b7 M# T( |4 [" X9 ]$ n; d// Volume adjust# v& C) [) D& K
// Internal sounds5 k& ?* y- k- p$ [$ q  {
#define        RECTANGLE_VOL        (0x0F0)
$ U# W3 H! z+ m' W#define        TRIANGLE_VOL        (0x130)
$ g5 m: f/ @! o+ N( I- X& ]9 A#define        NOISE_VOL        (0x0C0)5 H7 S. a9 s$ S2 l8 Z5 R$ w
#define        DPCM_VOL        (0x0F0)
0 t, c" U5 h6 |7 X; E// Extra sounds3 z- o- u& z! R" U! }
#define        VRC6_VOL        (0x0F0)9 Z4 |+ K! B, ~& R
#define        VRC7_VOL        (0x130)+ d& a  k, c$ l! N$ E
#define        FDS_VOL                (0x0F0)
; k9 c# A, w8 O/ n, u% x" `#define        MMC5_VOL        (0x0F0)& A, V/ Q) @1 p. W
#define        N106_VOL        (0x088)
2 F2 U' T) A4 |6 b#define        FME7_VOL        (0x130)
  e1 J3 ]2 c' p+ i. T8 {4 v/ o  X. l: t9 z* a1 M
APU::APU( NES* parent )2 p& c6 N5 t9 K# D; N3 n
{
/ v, j% E' d- y& k8 c, t2 D9 j* d        exsound_select = 0;
6 l% H+ G( q& a/ y  ^" N* ]; E% P# P
        nes = parent;
% n3 Q% L* N& X2 |( T        internal.SetParent( parent );
, l) o* N  h# S) x' u
# B( l3 t0 [- A. f  W5 |- F        last_data = last_diff = 0;
4 x. Q: s8 k+ w# }7 Z
3 B3 N8 h# |. V, A        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );$ i! T/ T. \/ @

/ ^! X9 c, |- ~1 e9 p        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
; C" \5 k  \* {) N        ZEROMEMORY( &queue, sizeof(queue) );
& s8 g* J' B: |1 e        ZEROMEMORY( &exqueue, sizeof(exqueue) );
: P+ b1 \6 d/ D" ]$ j( y5 @9 Z  h2 D% s! I# n
        for( INT i = 0; i < 16; i++ ) {. E; T6 c$ B3 L2 ]2 w1 s
                m_bMute = TRUE;4 @; Q9 I4 q3 g. S5 V3 _# ]( M
        }8 C# V1 O8 g, x; X
}) l% m, [& D# N. c& S. p* o. T
5 m/ ~  D: k; ?3 |0 \. p+ k- s$ ^, `/ K
APU::~APU()9 c6 E; E2 v5 D' L
{1 p2 g$ x* a2 t7 ]" ^2 k
}1 ^' T1 T3 p' s5 A. V' k% U

4 W! H+ z1 u7 x4 R1 d) Z5 m  L6 Evoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
( F1 H' i1 \) u0 Z5 ^/ H  a: y{
- d; I1 I: h/ {0 ]  h        queue.data[queue.wrptr].time = writetime;
; K5 R( M/ @& ]        queue.data[queue.wrptr].addr = addr;
# B5 z! n; c* a& i! j0 c        queue.data[queue.wrptr].data = data;
; i; f% k4 n. A        queue.wrptr++;1 f# V+ r, M8 J2 i
        queue.wrptr&=QUEUE_LENGTH-1;
, m0 y# R$ @+ K/ ^" x        if( queue.wrptr == queue.rdptr ) {/ W" k5 q9 I3 C( }
                DEBUGOUT( "queue overflow.\n" );% h/ L. T1 z/ i  l
        }) u3 F: d/ c7 L- f) J( Q. j- ?
}$ H& S+ t1 b5 Z- N5 B

( K2 R, q& }3 O$ {, W$ [9 IBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )5 c. d! b( j& g" f* A$ X& {
{  e* K. C3 @# t* I8 k% x4 M* \
        if( queue.wrptr == queue.rdptr ) {4 ^9 @6 d9 }/ n2 C
                return        FALSE;
( D$ E6 g9 |2 G1 T2 G8 G7 @        }
; X! l2 [' L! z0 `- g. H        if( queue.data[queue.rdptr].time <= writetime ) {4 q* h  j7 d8 x' A
                ret = queue.data[queue.rdptr];% k7 J" }' @/ D$ W8 K: i1 ^/ Y% V* B7 w
                queue.rdptr++;+ r/ r# O- p9 \6 ~/ g
                queue.rdptr&=QUEUE_LENGTH-1;$ P$ e; v4 D4 \. b# A
                return        TRUE;
/ s7 I9 |( k' f+ f        }
; Q7 `6 v  P: O/ i: `; B& i  z7 N5 T        return        FALSE;- N. J% m, {+ x
}$ S1 \/ r2 g4 V; m0 v
& L% [$ i' c- ^
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
: c3 R" e  ^2 n- w0 d8 @& x{
( D. u( {4 |* a: ?8 q        exqueue.data[exqueue.wrptr].time = writetime;' u& }% e: K( `6 A2 v
        exqueue.data[exqueue.wrptr].addr = addr;
* ^0 a  }+ s1 f- P7 @% b* y        exqueue.data[exqueue.wrptr].data = data;/ R- f" r* K6 u3 [; N9 ]
        exqueue.wrptr++;; D0 @, O; d' `9 Z
        exqueue.wrptr&=QUEUE_LENGTH-1;
1 b  V8 o2 q% q4 |. \  x        if( exqueue.wrptr == exqueue.rdptr ) {. o6 g% m9 n5 Y' E" T
                DEBUGOUT( "exqueue overflow.\n" );9 f5 P  J  j( A0 {; |% t8 ?" \
        }7 ^5 D: b4 O/ v4 g
}* M% a! c2 C- q* ?( O! q, Z- P& e
9 ?/ t. P& k0 U) I4 O9 ?
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )9 h# a, e% N( @$ ?
{$ E/ }# T& d/ c: q0 ~4 [
        if( exqueue.wrptr == exqueue.rdptr ) {
- g$ ~/ `1 z2 \) P- U, u                return        FALSE;. H7 `/ |1 B8 j" w1 t/ L/ @
        }9 K. ?2 T, g2 H3 C1 b3 A7 H) w$ Y
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
' e0 ~, H0 H( u8 y                ret = exqueue.data[exqueue.rdptr];
3 f- B  d' w6 L, V                exqueue.rdptr++;
: w) S$ @( O( K: f8 N3 l# n- k+ i                exqueue.rdptr&=QUEUE_LENGTH-1;6 N3 T: C' c" t0 U2 }7 e
                return        TRUE;
7 E6 R- z$ n0 r. m/ |0 S( J( \        }
5 B. a# R$ k) n( s; T/ u        return        FALSE;
) r$ u( i  `: n& z7 `}
2 P+ Y: d5 q" D/ z8 x% Y
/ ?3 |( a6 x6 ?/ r1 W7 gvoid        APU::QueueClear()
5 u7 G9 W( P3 i% Z. P( j{
4 W9 ~6 P( X- A" f7 }        ZEROMEMORY( &queue, sizeof(queue) );
2 s8 n+ y: N6 O: Z4 U        ZEROMEMORY( &exqueue, sizeof(exqueue) );+ I% ?. g' Z6 Q0 a7 k$ j
}
2 j6 K  Q3 ^" x0 j
6 y7 f: q- H5 f5 |, C$ |7 A0 h2 x3 rvoid        APU::QueueFlush()
. a; W: d  o$ B. @4 J7 @* }{
, a5 r9 c& Z; W5 J        while( queue.wrptr != queue.rdptr ) {5 W7 E& m" y- l; l9 m, Y9 K
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
6 R. [- p* j; B                queue.rdptr++;
: w- x7 Y( \+ H! ?" x% y. j! ?0 i                queue.rdptr&=QUEUE_LENGTH-1;
. K# N1 y1 D! n" _6 T7 y! o/ D        }
1 D5 }8 M* `) D' h; j4 b% ?% l/ O% X
        while( exqueue.wrptr != exqueue.rdptr ) {
+ ^4 k6 o* |2 p& I( e$ S) c                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
, o! C, `6 R0 x$ R) a8 b9 v                exqueue.rdptr++;
  R  g( e5 j' l) _9 k; C. r  c+ E                exqueue.rdptr&=QUEUE_LENGTH-1;' H2 o, A  ?$ `' }2 V& Q/ D
        }
, G) ^2 J, O. J9 z( f; U}# R( R2 n% s) ~7 \( _6 A

$ f+ [$ j) E- U* Bvoid        APU::SoundSetup(): B# D7 i: d2 q
{
; M2 d! F, u5 V) N0 l. \        FLOAT        fClock = nes->nescfg->CpuClock;& |2 C0 R* ]8 Y
        INT        nRate = (INT)Config.sound.nRate;, U' [" F) i* T! ^7 e7 k
        internal.Setup( fClock, nRate );8 ?; ?9 K& E% D/ Y0 Z
        vrc6.Setup( fClock, nRate );, _0 ^  Q8 a) @2 `
        vrc7.Setup( fClock, nRate );
% ^/ B' b1 a8 U3 f+ k- u: j7 o        mmc5.Setup( fClock, nRate );
1 D  a* {# r' W# I! n. \+ S9 _1 ~        fds.Setup ( fClock, nRate );
4 L" S# i3 T  U6 A        n106.Setup( fClock, nRate );
2 p' ~9 o6 I2 W: }  K3 M) F        fme7.Setup( fClock, nRate );
& F' F  f$ W" ?. ]! v: {}
7 ~9 q1 ~7 f8 O) X. Z1 \& u+ ]
* U  I; c4 Z7 Lvoid        APU::Reset()
5 [% D% p0 B" |  x# O/ f{
" B4 {& h7 o4 Q- E9 {- R5 \: F        ZEROMEMORY( &queue, sizeof(queue) );0 G8 v% {9 I' A* Q* \
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
9 M# f) H8 i/ f. E3 t
3 l  ?3 Z- k8 g( D        elapsed_time = 0;1 w5 s3 N4 Y6 g; C4 H/ X

( z( {2 _' R2 [4 {; B        FLOAT        fClock = nes->nescfg->CpuClock;1 u' L, z: N+ d
        INT        nRate = (INT)Config.sound.nRate;/ U& c# W2 B- x! X% H
        internal.Reset( fClock, nRate );: K' c; X9 a& m' i2 k% Z# {
        vrc6.Reset( fClock, nRate );2 [, |1 y/ b0 I" _/ V
        vrc7.Reset( fClock, nRate );: Y5 c9 `7 C  k  n" A% x
        mmc5.Reset( fClock, nRate );
2 k5 `/ m" P1 b9 N4 a9 ?        fds.Reset ( fClock, nRate );3 m0 `* t* u  y+ a7 W0 T
        n106.Reset( fClock, nRate );
4 O6 }! g& ?# `# z' |8 z* A        fme7.Reset( fClock, nRate );* V* \0 P! c2 T

$ g4 i+ x& a/ f' z' j        SoundSetup();: l; T: @2 t: x# D8 {
}
$ C/ E! D: B; o+ c" h# H
% v5 ~* g, D/ f7 O# S. a; s0 |void        APU::SelectExSound( BYTE data )
9 B/ a, s0 J* C4 O8 L{
* \- `; L% |" q' F8 d# F( ?        exsound_select = data;
0 W- k$ r; B8 x+ p5 {. P}
- k( k! e. w) n5 a% _$ y7 P9 m; G5 h1 Q1 F
BYTE        APU::Read( WORD addr )
) |% j' f. t6 }{
, _, M5 ~/ @& {" q6 m        return        internal.SyncRead( addr );
( F: D" ^- k- D- r}
3 ]# u/ O: D1 X. @% |
* e8 D7 J' [  Wvoid        APU::Write( WORD addr, BYTE data )
" s4 |7 B/ C. g{; c+ [7 |, b9 A1 P- d
        // $4018偼VirtuaNES屌桳億乕僩' Z4 b# ~8 Y5 L: w& Q! w) }
        if( addr >= 0x4000 && addr <= 0x401F ) {
6 T  B. q+ x' g; V( i4 i% _3 `                internal.SyncWrite( addr, data );
* w: T( u% d" A" b2 Q8 ^  O+ m                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
1 u; a4 p& E/ V; C7 A/ ]        }
, E' z9 P6 e) L+ b4 U}
& r$ G: x1 g4 m
7 Y( s) p* Z  HBYTE        APU::ExRead( WORD addr )
* `5 `5 q. \+ s% [: \) z! s{( |/ {/ l$ p7 ^# d  J7 o8 @, d
BYTE        data = 0;8 ?6 [. I# n- k5 b
2 h, f9 i' R' V. ~5 L# Q  u* j  T
        if( exsound_select & 0x10 ) {
1 o9 d0 \: }/ k2 R5 f, O                if( addr == 0x4800 ) {, e  r' Z7 U6 J# w6 n
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
/ M+ `% o, U& e3 Y# B& l( Z                }
& S% B# a$ ^$ K9 l8 o  y. i        }% ?9 A& _0 D6 ]8 g' c4 D6 |
        if( exsound_select & 0x04 ) {) F( e/ h. {# L: b. N2 A2 t: r, s
                if( addr >= 0x4040 && addr < 0x4100 ) {8 [& Z! t, ]! Q2 c9 y% n/ N
                        data = fds.SyncRead( addr );% Y/ m* }3 X8 a9 k
                }7 s3 O/ n* \2 c- P" _- W0 |
        }) w4 m8 l; N3 ]6 M
        if( exsound_select & 0x08 ) {: ~% ]0 h0 R( N' ^7 j8 f$ C, |
                if( addr >= 0x5000 && addr <= 0x5015 ) {9 g4 i8 X) F( y! [- F
                        data = mmc5.SyncRead( addr );
# X$ C" ?; p" \4 n; b5 w                }0 C' b( Y7 X+ j; O4 D# D' K
        }
+ l8 T; g, A1 k, V5 n- d8 q/ t" a0 {* X& o! r8 k
        return        data;) Y+ ^. Q; c5 ]7 Z5 @: j
}
/ U' O9 f2 y- |+ m6 ^- B1 E/ Z- q4 F5 ~7 H( [" Y) n1 c& H
void        APU::ExWrite( WORD addr, BYTE data )
- R" `9 ?6 d6 l+ }# g; o: f5 y{, m- ~4 g' h9 w
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );; M. v  _- W. a( T

& T* z4 ^) f: f        if( exsound_select & 0x04 ) {
" J9 E7 t/ E! P# {  O; w, ]$ V                if( addr >= 0x4040 && addr < 0x4100 ) {
, r* r& i, z/ {. V/ h5 ^! Z" L                        fds.SyncWrite( addr, data );3 _! ]% i2 d, Q. d, g
                }
' k" C# e+ A) }" g        }3 q# C  E" t0 d  l4 S

; s1 ~5 u2 J2 `        if( exsound_select & 0x08 ) {; S% W# Z9 @: P6 j
                if( addr >= 0x5000 && addr <= 0x5015 ) {8 y1 x* N+ T, x$ t7 H* H
                        mmc5.SyncWrite( addr, data );0 |7 @& I$ i+ U! p! ?8 _
                }
  l. m5 n, I7 T$ j1 Z, S/ u        }
) P5 `$ j4 C# k}
0 ^0 b& a, D! k- j7 K0 P+ y1 l/ \* @6 ^
void        APU::Sync()' B4 B$ D6 m; m6 S# n
{/ k! x. ^0 M  ~0 N+ O
}
8 L4 S# v0 U5 u9 u7 |, N: s( P6 V  l8 [( o2 X2 }/ _+ o
void        APU::SyncDPCM( INT cycles )
: M- x* m6 u, q6 [  x{
) ]* A: \* j' M        internal.Sync( cycles );$ Z( D1 L) \0 S& B$ [! N* h
( ?. f) T: s: j7 f0 J! o* P
        if( exsound_select & 0x04 ) {# B7 w. Q4 O) r5 t
                fds.Sync( cycles );1 v7 |! i5 m: c) {3 x; n6 v. Z
        }6 R1 s( N' A% {! W2 L8 o- Y
        if( exsound_select & 0x08 ) {/ t( G" A( v  n; _
                mmc5.Sync( cycles );
) G+ S3 l) P2 ^9 k7 l* |        }7 l8 F" y8 U# U0 M
}8 y2 z: e! `! g1 l' e4 s. @% g' Z  c

; o4 D8 h5 w0 e7 Z4 n9 Qvoid        APU::WriteProcess( WORD addr, BYTE data )( j) i$ s1 C/ y$ _) f/ k) o/ W! a
{
- q4 }8 S# Z. y& D        // $4018偼VirtuaNES屌桳億乕僩8 N6 y) f, l4 j
        if( addr >= 0x4000 && addr <= 0x401F ) {" N7 z/ z& B: ?& X
                internal.Write( addr, data );5 L' B/ d5 m( A; \2 E( Y" j% n$ ~
        }) a& Z  a! `; R& m
}+ ?. v- ?* {3 @8 q4 ]6 p+ h
" N/ n1 i4 Z' {2 H" m* u( [
void        APU::WriteExProcess( WORD addr, BYTE data )1 y3 w2 E3 |2 H2 y8 |
{
- f* r  |- O* B        if( exsound_select & 0x01 ) {
  K' ~1 X; {9 g* s9 G- P# z, l% c: g                vrc6.Write( addr, data );
- ]2 [+ f% O! b1 A7 @" I        }
0 K" w& ?: O2 y. a1 {( j6 D        if( exsound_select & 0x02 ) {7 A* ^' t5 @8 `
                vrc7.Write( addr, data );$ d( ]1 {  |1 u+ h. s  `3 @" i2 b
        }$ e: [" `5 p5 Y7 D  f8 k: L
        if( exsound_select & 0x04 ) {" C. E; N( [0 c
                fds.Write( addr, data );
( [! H7 q, t: i% Q        }
8 J$ V6 z# Z0 W" y1 i9 n        if( exsound_select & 0x08 ) {
, g. G$ o. O* O% [- l5 ]. c  O3 T; N                mmc5.Write( addr, data );, u8 w2 A4 [, V: K% Q! k
        }
) a/ E; T+ r3 n( r& v" E        if( exsound_select & 0x10 ) {
; G- s6 {- g2 q) V3 I# Q* Y, h                if( addr == 0x0000 ) {% K' X6 u$ e: r! B
                        BYTE        dummy = n106.Read( addr );' S+ z& @3 `6 h8 {3 s" z
                } else {. `& g8 A9 z2 }- p$ H7 d
                        n106.Write( addr, data );# x. \9 h& l# b6 k" k
                }! j, z5 u! j( \
        }' U" [2 v2 Q8 p
        if( exsound_select & 0x20 ) {
+ r2 s' p; }, S4 ?: |                fme7.Write( addr, data );
' B; r$ K8 R0 ~( C# _5 |3 T        }7 q3 \2 w4 M; p1 T5 z: n, J- K
}5 W( K; ^- X+ ~

+ C8 Z& P/ G5 ^0 D8 e1 u/ xvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
, }+ m3 u5 `: {' h+ `{
$ @5 k! h  {/ R4 ]5 T0 MINT        nBits = Config.sound.nBits;
7 a# ?2 {* M' R1 F5 MDWORD        dwLength = dwSize / (nBits/8);
% G" S  t- ^, p$ [INT        output;+ Z  B" c- W0 M. O8 R$ m& j
QUEUEDATA q;
; p8 V8 P- w. f( NDWORD        writetime;( k3 ~' k4 S4 e4 g. n( t8 _5 B( @

3 d+ _0 I0 E6 }6 Q9 `7 i" f& ^LPSHORT        pSoundBuf = m_SoundBuffer;
; {: b( L% `' n; m  K! NINT        nCcount = 0;
6 Q* P2 D( [! q' V; ]+ r$ h, ]- d* P! ]8 Y* [. |: x  J- a. a
INT        nFilterType = Config.sound.nFilterType;1 |! ~# w: \2 J2 q7 r. Y% C
- O) {' E  {* y6 K! v9 Q
        if( !Config.sound.bEnable ) {
/ T! d+ u! c# \/ \# w. j: V' c& k                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );- n. Z* l# o* s' q; Z/ Q5 l
                return;, I- K! b0 S# p1 u6 P# B6 B
        }; }; G; a- _  E& @
0 X; }5 i- }7 V" [& \
        // Volume setup# S: s- T" a8 d% W1 H; A# J" Y
        //  0:Master
' a. c# U% P. G! w- D        //  1:Rectangle 17 S. K) f& j% f& n' b1 e! p
        //  2:Rectangle 2% c9 h$ ?+ T: f1 Q4 [
        //  3:Triangle# M7 _4 n2 Q3 B3 W" {7 f
        //  4:Noise
" T( P9 t4 t% S7 U4 c5 E: U        //  5:DPCM
( j3 K1 H: ?* @1 e        //  6:VRC6
4 Y+ I! G. q  S+ ~0 e        //  7:VRC7
1 Z# t( |% \2 E" H        //  8:FDS& P, ~* r$ y1 l8 B# S  h% L
        //  9:MMC5$ t6 h# x+ W5 r* |
        // 10:N106
) [( h) {+ C& u8 @3 u2 f5 f; @! J        // 11:FME77 d$ q# ^( A3 o
        INT        vol[24];* Z$ R. C  G$ `
        BOOL*        bMute = m_bMute;6 ?2 u$ `6 I4 R' E# }  t  @! X
        SHORT*        nVolume = Config.sound.nVolume;8 ^2 P4 f2 e. f# t* c1 z0 m

+ u* e( ^1 N! L' ]+ M1 i! I; `        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
+ Y8 I( w3 e- v# J- c+ p
5 b" T; C* E- C1 I3 E        // Internal
% A6 T9 M* D/ C3 W& e/ W! l        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;9 D+ g& |% S$ M5 A3 {9 ?* ?+ A
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;! a" `  Q  F8 C6 {# p0 v3 R  [9 ^8 x
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
7 P  V, K' I( ?4 K. ?; G        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
4 f  ?- J  W# u        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
" N" I/ t* h: E( P0 Q) K
/ }/ x# S& M+ q( T        // VRC6
& P7 R. {; r- X+ _( M7 ~( H        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
3 ]& q) t0 D7 r, i  \! z        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;* c% S6 ]: d7 y6 D, V
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
* g3 M9 n- C0 P3 ?3 h5 f# u8 h8 i" T" n/ i
        // VRC7% J0 l& F+ [+ m* {* f* s$ w
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;, h! ?8 T6 W5 H! \6 E8 [, I
0 T' j4 ?" c1 Z, ]
        // FDS
( N( H  ]+ J$ D% d/ ^, z        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
) ^% Z9 _7 g. L- ~' a
8 P+ P8 _5 Z" `        // MMC5
; o# M# }8 V& U; q5 |        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
( [2 N& k7 T( Z# b9 H. S# s: }        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
/ Y0 X. N$ o9 S0 B0 {! ?        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;( Z- L/ u; g* ~% x) B! _" H

5 b7 l3 |) a- Z* C+ R$ p% r3 `        // N106
* Q- a+ e: ?$ f* h1 f* k+ y- m        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;: X+ f  w/ Y1 H
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;# e) Q6 a4 A3 |, x# h
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;, r2 _( K/ x, `. H8 T4 i; Z
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ H" j9 t0 X9 m0 d$ J* N( c
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 \# U! E: q9 U  N* U3 A/ L+ I5 A        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
' B( _  I7 G- h: y7 e        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- @7 Q; g& i& j+ |        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
* |( r; E( s+ B9 ]3 v% C
2 t5 g" D0 C) L        // FME7
/ ?$ M% e8 l7 @; P" a        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;4 N/ I) a6 i3 w7 D1 j2 J9 M4 ^
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
( o0 Z) p4 ^5 ~5 |6 _. j. W" o        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;" |% s$ i) \2 Q

! a; C; \; w% H: z6 c7 \" b( b, h* r//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
. x' J. `; ~5 b+ Y/ N2 C* m2 Q  b        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
- U5 b/ g9 T7 H2 b) p" ]
  m! X) |3 G* ~        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
7 R# ^4 P6 C* c9 m        if( elapsed_time > nes->cpu->GetTotalCycles() ) {# t! r$ |3 U3 d) V8 K' [2 \
                QueueFlush();- Y( C, z6 M0 h) U# \
        }
* H6 e! k8 A# W4 x: N4 C& [$ y# u* B9 v) `
        while( dwLength-- ) {
) ~1 ~! u5 }& ?: Q8 d; u3 ~                writetime = (DWORD)elapsed_time;6 x& d  n% `: E: _' f. f; [  K
9 u2 T) t" J: M7 X$ e; n
                while( GetQueue( writetime, q ) ) {: M7 ?0 a% @+ K% c7 ]$ }; r
                        WriteProcess( q.addr, q.data );: X0 o7 C- L* t( R
                }% k2 C2 |: Z, Y3 l
5 x2 T: j5 M$ p5 q+ |9 c7 m
                while( GetExQueue( writetime, q ) ) {
. h8 f* ^' L4 ~1 J* `                        WriteExProcess( q.addr, q.data );. P- y$ L8 _; C6 u# b
                }
9 y. o* ~& H- U! b) z- a# `( W+ j( Q; u4 ?6 J' C
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
1 L8 Z0 ~0 o8 Y* y- K: L5 Y                output = 0;
" K" s" w) |" c, ~: ~. z                output += internal.Process( 0 )*vol[0];
5 x9 X2 z; A  ]2 }& X- h0 ^                output += internal.Process( 1 )*vol[1];6 m4 Y% X! C- s: W3 z
                output += internal.Process( 2 )*vol[2];
% z6 r" v% u2 i& Q; L                output += internal.Process( 3 )*vol[3];
1 F1 L2 I; V! r! I- I) `. s                output += internal.Process( 4 )*vol[4];
2 M# l( [, }8 ^3 O5 J# _' h! v$ L
                if( exsound_select & 0x01 ) {. M6 |2 d' _: ?" h' p/ m# @2 n
                        output += vrc6.Process( 0 )*vol[5];
/ X/ j- q4 _( i. Y                        output += vrc6.Process( 1 )*vol[6];
5 M! h7 a! |- s/ |                        output += vrc6.Process( 2 )*vol[7];
$ W" A* p7 q) I0 k4 a3 s8 a  \                }
; f. F+ S3 ]- u# T7 w6 N2 }                if( exsound_select & 0x02 ) {6 A+ [& d0 m! L. S3 n
                        output += vrc7.Process( 0 )*vol[8];
/ A. f1 t+ s2 M                }$ Q7 N) \+ `7 W
                if( exsound_select & 0x04 ) {
; I( k% a' B! b( f$ A' D2 [                        output += fds.Process( 0 )*vol[9];
3 l. r% K7 p. ^# {: Y                }
2 c* c. ]3 ?- H) d' C$ t7 |: E" Y                if( exsound_select & 0x08 ) {7 H7 s% G9 k6 m  g/ @
                        output += mmc5.Process( 0 )*vol[10];- l0 j4 M8 R2 R6 z+ F' _! l
                        output += mmc5.Process( 1 )*vol[11];3 E; p/ P  f3 K0 s+ q* x) N: M) F' k
                        output += mmc5.Process( 2 )*vol[12];2 g, _8 ~7 Y4 ^1 i
                }4 D8 f1 i1 |0 O* o
                if( exsound_select & 0x10 ) {
7 ?. _( F+ b% l( u" v                        output += n106.Process( 0 )*vol[13];, P9 n. R! R& Z0 ?, @! q& D! b4 \
                        output += n106.Process( 1 )*vol[14];
; P! _4 C' B1 v+ ^7 L                        output += n106.Process( 2 )*vol[15];
) a% D- h, R1 s1 b                        output += n106.Process( 3 )*vol[16];3 v- j! C0 [( n7 l
                        output += n106.Process( 4 )*vol[17];
1 f. B* V# `7 u- p0 s) @) r                        output += n106.Process( 5 )*vol[18];1 Q: _$ T4 E/ C! C' s/ x9 e" i
                        output += n106.Process( 6 )*vol[19];/ ]! @0 i& v9 B$ X& n  q
                        output += n106.Process( 7 )*vol[20];8 P! A9 y& [# v2 i8 v  C
                }$ n6 j& p( v; P/ b, K; }
                if( exsound_select & 0x20 ) {- G6 G8 F! P4 y; y
                        fme7.Process( 3 );        // Envelope & Noise! T! G9 ]' r! q" t; V5 r# o# Z
                        output += fme7.Process( 0 )*vol[21];
0 {6 q; _; `9 W: d% U( t                        output += fme7.Process( 1 )*vol[22];
) R# O- C- O2 N7 d; I3 E  d                        output += fme7.Process( 2 )*vol[23];8 ?! C: |  c7 f! ?
                }
9 i7 U9 |( n% X: Z* t
' o* B( X+ i4 p+ b2 _( L9 U5 E                output >>= 8;/ k0 ^; i# h9 {6 e2 R

+ ~6 u/ k' ~8 `) v/ w9 z2 ?# E                if( nFilterType == 1 ) {$ S: Q- Y# `9 @) V  q* r# y  u
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)) G: a3 {& G% y9 m+ d
                        output = (lowpass_filter[0]+output)/2;
2 p5 T9 O7 V9 d# H                        lowpass_filter[0] = output;% H5 U: D4 Y+ n" A
                } else if( nFilterType == 2 ) {% m* O* x. ]3 h
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
% z. s/ F8 i7 {1 J- ^                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
2 _' {/ E* Y/ z                        lowpass_filter[1] = lowpass_filter[0];
# X# S) f) G. a" ]                        lowpass_filter[0] = output;4 E. {: l+ i6 Q, ^& g9 t  t
                } else if( nFilterType == 3 ) {5 @5 T/ Y( a5 J8 s+ D. n
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)+ y: a; X* E. J
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
+ H" `$ P2 Y! |1 s2 }, F! o/ ]                        lowpass_filter[2] = lowpass_filter[1];
" r, N' l" B3 G4 N8 V                        lowpass_filter[1] = lowpass_filter[0];* S1 t+ L! D' g6 n, l: C4 t% p
                        lowpass_filter[0] = output;) b/ a5 q- E5 v6 ]$ u/ P& H& M
                } else if( nFilterType == 4 ) {# T# n; X0 W% J5 y
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
8 a  Q8 F9 z* i9 D% Z% u                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
) y: L7 R: p3 r                        lowpass_filter[1] = lowpass_filter[0];" M5 M* \/ f( c( F
                        lowpass_filter[0] = output;
  N% W2 Y5 }* V! O1 ^4 V                }6 G: L- f9 Z, [' m; q0 p6 V4 q3 U
( m" w6 Q1 m9 R& \
#if        0' n; K* k8 h" S
                // DC惉暘偺僇僢僩: F. W) M; Y( O. O) @
                {) d: F' ?8 o# U/ g4 g3 B
                static double ave = 0.0, max=0.0, min=0.0;1 b4 J8 o/ g+ l
                double delta;
  z4 U1 G: \( s9 F  x! I                delta = (max-min)/32768.0;
: H# r& {* u3 ^6 Z8 t) l                max -= delta;
3 _  {4 x8 g4 ~1 i0 ^& v                min += delta;& a! q+ ?+ K7 h
                if( output > max ) max = output;: d# S; A, w" A! u& t9 d8 l
                if( output < min ) min = output;% |# _3 }: ?/ l( j
                ave -= ave/1024.0;) {5 w' N. {- M# E. z
                ave += (max+min)/2048.0;
* d5 h9 N( ^' H                output -= (INT)ave;
" l8 J0 Z: M% X6 P, l/ h                }
& t8 _' L) r+ \/ d3 I#endif! p; ~; c6 ?9 F3 M& s0 ~3 f
#if        11 ?0 O7 z7 F. I9 I. T
                // DC惉暘偺僇僢僩(HPF TEST)
% `( H8 F: ]8 g                {8 S5 j% @+ E2 Z; {
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
, T; u% L, q5 v3 G- x                static        double        cutofftemp = (2.0*3.141592653579*40.0);
+ p" S! m$ |' b: a) u8 B                double        cutoff = cutofftemp/(double)Config.sound.nRate;
# U* x. i% X* }7 |( n  ?% ^                static        double        tmp = 0.0;# O, K4 T' Y7 A+ g- [
                double        in, out;# Z" v( f, y7 A+ L2 m6 ^) ?' Q: L
* O2 i* ?3 u8 j( N
                in = (double)output;; M" n% z7 g$ d8 P# [6 w
                out = (in - tmp);
  C$ N3 T4 ^9 L# R5 o                tmp = tmp + cutoff * out;. i5 Y9 }& t! |( T5 Y4 R
  u: B& r9 L; T: h. f  G! y4 F
                output = (INT)out;
0 {$ v8 W# `5 U                }
. d" t$ a: m7 M. N) u& y#endif
9 ^7 g4 A8 K7 N2 E& [5 J' c#if        0
/ R( y  X" e6 S0 U) V8 ^! l                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)! F, {4 u* A' V, E% A
                {* F: l2 W" q; Z$ j. |0 l5 M
                INT        diff = abs(output-last_data);
5 f/ O8 e+ _4 w                if( diff > 0x4000 ) {* h8 P' ^0 g. Z, I" E
                        output /= 4;
, G, G$ c# P: C. h                } else 2 t" |# F% X9 ~. W' f2 a, m& l' O  L
                if( diff > 0x3000 ) {$ _- S. L, S6 o  {7 y- q
                        output /= 3;
& P9 G% n( |" }0 f0 X9 `9 o0 p! A                } else
! w" g7 U3 p7 T+ _0 J                if( diff > 0x2000 ) {& ?& n7 P/ G) d& n
                        output /= 2;
7 w; w5 V: N: q' K& x                }
( |% V  N# o! X; w& V% X$ x1 q6 T; C                last_data = output;
' l: v3 V" p" k8 k                }
0 ?  j+ [% _3 `0 g5 h: c- f+ Q#endif
, J/ r/ E& |9 `                // Limit
' N7 `( u. M& f" J2 w& i: n: ~: Y                if( output > 0x7FFF ) {
; V+ a% B0 d/ l& H: D" N1 P                        output = 0x7FFF;
8 N. K& A1 c+ o1 H- }2 b                } else if( output < -0x8000 ) {
+ ]3 B0 T! C/ I+ M" ?                        output = -0x8000;
: A" `4 g+ @3 J0 [2 w                }# F# z2 p8 g( t3 B% z0 V
' z3 d% ]$ O5 l" P' b
                if( nBits != 8 ) {
1 ^9 C1 T% I: B( p                        *(SHORT*)lpBuffer = (SHORT)output;
; ]# j  f$ z) \! y; b, s9 D# ^, Q                        lpBuffer += sizeof(SHORT);
7 B8 S* @+ a2 _3 A* N                } else {# H; f) l8 c! j
                        *lpBuffer++ = (output>>8)^0x80;
! \  @! x8 X) J+ R/ v& `. v! i                }
- i# f: k6 y0 Z7 e% }  f0 s7 Z; ?) v! [, r. ?
                if( nCcount < 0x0100 )
6 z( k" y1 M% `) ?4 ~                        pSoundBuf[nCcount++] = (SHORT)output;
- a$ Q! v/ H' q& W# E4 ^) z
/ I$ `* d9 w* _& k//                elapsedtime += cycle_rate;$ J, X; l3 o0 o" B0 I1 @- m1 E9 i: L
                elapsed_time += cycle_rate;6 E: u3 U0 k6 A7 N) c1 X% y
        }# T) g/ b4 f, ^/ ~( I+ ^
1 u' m' \, X9 ]' A& @! X- h  |
#if        1% r0 L' ?& N) D; l. N5 d0 O
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {9 S. G0 a9 x% `( S1 d
                elapsed_time = nes->cpu->GetTotalCycles();
' u: x% D7 g3 H0 E) J, N9 E& G3 @8 b        }
* z2 y6 p6 ^( K9 t6 {; C        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
6 A) Q* e1 n! }) b) z                elapsed_time = nes->cpu->GetTotalCycles();
- o3 k( X( Q# M& ~! Y! H        }: ~  D" r# E, A* B
#else+ W5 [0 f1 Z  D2 x/ C  K, Z
        elapsed_time = nes->cpu->GetTotalCycles();8 c( l" ?) O1 T; p. ^! o% s
#endif
1 R, W3 K8 T5 r+ Z9 q}7 g8 c4 J( q. X! @1 ~- Z" {' R3 T

( I2 [+ u6 r! g% a  D// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
  P0 i) \8 A0 E2 MINT        APU::GetChannelFrequency( INT no )
. D+ ^& _2 k" a1 o/ b2 O, o{
1 s2 n3 B: x- c        if( !m_bMute[0] )
* R+ \$ v+ {" Z; E& h; ?6 y; d. W% A                return        0;( L% Z3 Q( D" n$ Z
4 a* J8 h0 F# V3 z
        // Internal
/ h) |6 C. D1 J. l5 d" p- p' N        if( no < 5 ) {
5 B9 l6 R; e) M, o( p                return        m_bMute[no+1]?internal.GetFreq( no ):0;3 y' s+ U, Y( b( l) j3 C
        }
8 @8 [- D; U6 g7 [0 E" y        // VRC6
5 {; I2 M6 V7 D4 W' `2 }        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
/ i5 F- Z( t& d3 J                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;/ U5 J) V( ^6 d7 B0 s- _/ m& U
        }
! m2 k4 k' D' g+ o" D: [- C        // FDS6 M* t0 J) Y. d- @' _# q
        if( (exsound_select & 0x04) && no == 0x300 ) {
! R( i2 I2 B: d5 u$ \; E& r4 [5 d                return        m_bMute[6]?fds.GetFreq( 0 ):0;, z- v; q2 }) g9 O. D, a
        }1 J$ A5 X6 a8 L7 u8 V& u
        // MMC5
/ ?! D( |2 Q* t, a1 A- o* W        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {5 g* C  u8 B9 f- A' e: G* e
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
  D3 C. x5 M$ S- b        }
3 D0 w8 B4 f! z2 E1 q0 y) E: O        // N106
2 }, a& M  t2 {. J1 x2 x        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
, m) Q9 V* @& G) Z                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;# i, B; ]& ]( c- ]! y+ o1 S
        }/ S2 i! E. M# ^0 e4 ]( j
        // FME7
9 n( u& Q( ]7 J  S        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {& C4 }1 ~" b, o3 Z: l1 C
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;0 G4 `  o# N! z& D/ Z3 }/ g& [
        }3 x0 f% S, O9 Q% g# E
        // VRC7
9 o; `$ U4 @" _* i$ F) V        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {2 t9 w, G' L1 }  Z2 F
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
8 y6 @3 `) z1 v' C1 }0 |3 P* A        }( G1 I: U) g( o
        return        0;
) w% h- ~* }$ e, Q6 t2 l7 y( }}
( ^3 l. n$ w' f8 M" N. d  M& o& y. w5 S1 z$ a7 w
// State Save/Load% t' |6 s2 V6 Y. D% T
void        APU::SaveState( LPBYTE p )
+ p2 w* k# l1 s# r{
1 I$ m' l' j, T3 T" b  Z& P#ifdef        _DEBUG
; }% r& X* U' i$ \8 Q7 xLPBYTE        pold = p;
% d6 \% Z0 f2 m: c- V#endif
/ V! R! g; n# l$ C
3 {$ I/ w. q) L( j        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞: q! v# K1 O9 f: T
        QueueFlush();: D( S2 F9 b2 s8 k& ?" |
8 U5 |2 M4 ?* y- D2 `' X7 S3 z- e
        internal.SaveState( p );
8 ]0 e3 e: H* E8 ^# S- |% I/ |        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
# B- Y3 B8 j# F* N
/ C* l' F, ]  v& \0 y% h# o( p        // VRC6* w" E) D; g- J/ Z( g+ a* H2 U
        if( exsound_select & 0x01 ) {
6 {9 s; h; ]' ^3 B5 T2 r$ @1 D% [                vrc6.SaveState( p );
- v- g. Y% j5 }5 d/ D& H1 e1 ]7 ?                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding9 h' l' `0 O. B+ e. M; q
        }- W9 x: v6 k1 W
        // VRC7 (not support)4 s4 J  U$ m' ^, L
        if( exsound_select & 0x02 ) {
, D5 V) U9 U: s                vrc7.SaveState( p );$ C, Y+ |3 l, X, f) J& P7 I, p
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
* |% L( t& w9 F: V* J  }        }) U+ j& [' {8 z8 m
        // FDS( O' B9 f/ |5 o% G
        if( exsound_select & 0x04 ) {
, m) n8 B. B: [4 x* l  N                fds.SaveState( p );# {5 L% m% {% k8 m
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
0 P. D& ~( ^" ?2 W        }* C7 J- V6 ]: M) w$ t( A
        // MMC5
. S3 K$ Z6 w4 A( _  c$ I& ^+ J: h3 m: s        if( exsound_select & 0x08 ) {
7 ~3 V0 T) T' Q& o. p! U                mmc5.SaveState( p );# C2 b: _: n) Q8 D- S
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
/ N! c( G. d3 k        }
+ T9 `6 V- A/ J        // N106
- j5 ~$ X: f. L0 z2 Z( n# [        if( exsound_select & 0x10 ) {+ |% B8 {# M2 R6 N: d
                n106.SaveState( p );' w. }: s, C8 j$ u; @& d: {
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding! z# g0 X0 ?/ s6 M% R
        }& ~, U) y! T6 K* |0 V4 n1 o2 i
        // FME7/ u% B" }4 X+ B' q3 C( A5 d
        if( exsound_select & 0x20 ) {
% A+ g2 W2 Q. l6 X  V6 h, v                fme7.SaveState( p );
& d& s1 F/ X; n% V* h, Q2 `2 i# e9 v                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding. m+ {2 W$ v7 ?% L% T
        }
1 V7 s& _8 p3 I! h8 k2 L
& e# n0 M1 T, z$ g7 }* U9 d#ifdef        _DEBUG. b1 A: f$ R/ h) [
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );5 M9 Q, d# f! i
#endif6 A$ D) c" _9 R+ b' x1 v! m
}# B/ X/ E- L# H2 Z' R0 {* A3 k

2 n6 w- M1 L! I1 o5 \void        APU::LoadState( LPBYTE p )
6 Q4 M) I, T6 R1 O* |$ Z{& J5 J7 V9 F' o- V/ J1 m' a
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
' T! _9 @0 _, V' F0 J1 ~6 M' d        QueueClear();  Y+ g1 v1 W2 X) r+ {. L$ M( ]: ?. T

$ l2 @3 `* h: Y, U        internal.LoadState( p );
, K5 \; M" H+ W/ ]        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding4 H3 a- V: R/ g9 g8 C8 C
( h  ^4 M/ ?! ^$ p4 `# P; w
        // VRC6, ~& P9 Y' E0 i4 q
        if( exsound_select & 0x01 ) {/ k  _2 q' ?* S( w7 q
                vrc6.LoadState( p );( y1 Y' R. ?# B  N1 ]! l
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
/ o  e, k" C- U  }- I0 m) `        }9 M4 x8 G' V' v- S- G* G0 l
        // VRC7 (not support)3 x" I  j2 _; ?6 e, W) U( ]! o
        if( exsound_select & 0x02 ) {
4 ]- ^; z. w' ?# g* S                vrc7.LoadState( p );! q) a$ M, \# a; a+ r4 m& c0 Y
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
" W) Q9 Q& d% d4 H        }
4 m; z; ]& U7 V4 @: i0 O% R: C$ W        // FDS8 N% @' X; {* H' p' S( u/ b1 J& x
        if( exsound_select & 0x04 ) {
$ K$ x/ `: Z' }                fds.LoadState( p );' b6 e$ |# a+ V/ g% q5 e2 @2 u
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
" O8 {9 O/ d# f        }& S- N6 ]0 V3 h- ~! a+ ~
        // MMC5) N  q9 A* x( a3 O- e- ^9 Z
        if( exsound_select & 0x08 ) {$ I  F5 ^) L7 W; ?. i
                mmc5.LoadState( p );' H( B; U. q. V9 I& ?
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
7 j! O/ ^4 F8 H7 G3 d4 N5 u' W, w        }) X/ P4 a% J6 @3 X6 I
        // N106& P8 b# T9 m  ]6 S8 ^
        if( exsound_select & 0x10 ) {4 o' T# L7 }1 @' l
                n106.LoadState( p );
1 {; q" Y( ^6 K% g1 a0 |5 W2 f                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
2 @" i( f& L8 _$ e        }# D; v9 v( z( t7 U% \" f4 C4 b2 g& J
        // FME75 m3 N* m* I" y) k
        if( exsound_select & 0x20 ) {( d2 t1 U" k5 L, c) f* d( ?* K
                fme7.LoadState( p );1 i; c+ M% K+ b' g  W, i8 S! t
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
- F' f- S. |  K$ \7 R        }6 |8 w, ~6 W) v5 z+ r0 P# a, k# r. ]
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 ) ]% R, f+ q& k0 `; k# f
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
( F+ G  d5 ~& m  a感激不尽~~
9 E- M; l2 |4 o
恩 我對模擬器不是很有研究,
4 |' X3 g; @" E雖然要了解源碼內容,可能不是很困難,
& x5 {: ?" a3 G& h3 E. E1 h) H不過還是要花時間,個人目前蠻忙碌的。& g7 V' s: v. i0 d, E( R

  m! A( g) `& g7 I9 |- d給你一個朋友的MSN,你可以跟他討論看看,  X& Y7 J2 x8 ]. ~) k
他本身是程式設計師,也對FC模擬器很有興趣。  F/ \7 y$ W% ~9 x. ~  J: p6 O
: `& o# l1 j3 u" k- g7 S
MSN我就PM到你的信箱了。
- i2 F9 v- N  D8 y( K8 X
- a0 v% E; B; ~: f" h( f! M# Z希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
6 k4 Z2 [; e2 {" a$ E呵…… 谢过团长大人~~
+ K! \' h! t2 f+ Q- g) H4 \8 Y- y

9 y  l+ F" P5 `2 ]# j哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
% X4 z+ Q; C/ Y6 I团长的朋友都是神,那团长就是神的boss。

$ \" o& S& _, K" B哈 不敢當,我只是個平凡人,3 o- S% Q% x: v1 A
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
3 f. n+ D- f1 x  J1 ~ZYH1 I- J! z/ {% ~* g5 X  B3 D
QQ:414734306, W0 B6 E+ B9 L5 K: W( S6 Z
Mail:zyh-01@126.com$ H+ Y2 d& [" o5 J

4 h- x: p/ N1 r. t5 K8 ], U他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
+ Q* p: R! C! N- B" L4 ~: R再次对团长大人和悠悠哥的无私帮助表示感谢~~
! [1 @9 z; o& r$ ~, d% M2 d
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-23 15:09 , Processed in 1.112305 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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