EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。$ y+ h& K7 j8 J: n; X
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
) Z: O* |, ]! k: d# |/ l, B这里有相应的模拟器源码,就当送给大侠了~~5 i, z7 a& V  m( J) [( J+ l- i3 K
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
+ c0 P) J& z% Q- c! [( V能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。1 U! Z- P" u' @" y) Y, t
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~$ x0 F* @( Y7 f/ j
这里有相应的模拟器源码,就当送给大侠 ...
, A/ W8 r3 Z" Y
聲音部分(Audoi Process Unit = APU):+ V  |  E+ \! ^) X
.\NES\APU.cpp3 o% \$ j6 P& a: }# p6 a
.\NES\APU.h
) ?  ]2 y* e, M2 z% ~3 I8 q( @. i" h+ ~
2 [0 g: q, V0 u4 t# k+ M" @$ x9 |, r; k4 R. a# Z) ~
影像處理部份(Picture Processing Unit = PPU):( E2 ~9 ^; H3 F$ f+ p! e# e; S+ L
.\NES\PPU.cpp$ x) c9 j. n" j+ S' n4 S2 [
.\NES\PPU.h
8 \* ~0 D. E0 G9 m  ^
3 B: m- o' O+ M% O如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
# D6 `, x: b; s; a$ X; L0 i# Y0 @(由于很多专用术语和算法机理都不明白,所以看不大懂……); h6 H" n6 }. L- {
//////////////////////////////////////////////////////////////////////////
- `( M/ x. @, c8 d  z5 c3 p//                                                                      //0 o& F* Y; b# r- m5 o) l7 E
//      NES APU core                                                    //; n' S  A: P$ K9 ~
//                                                           Norix      //- m. T7 ]  E  Z
//                                               written     2002/06/27 //% m' g1 C/ W+ f
//                                               last modify ----/--/-- //" ^$ ~, c7 s' Q3 Z
//////////////////////////////////////////////////////////////////////////
2 |% A  R3 q* ~' J6 W#include "DebugOut.h"
! T# Q5 \8 A  l* _#include "App.h"; x9 n3 [. v% H
#include "Config.h"3 u9 ]  t+ @6 m! X
1 F0 `# c! r8 G; m
#include "nes.h"
0 E2 s6 \" H; K- H#include "mmu.h"
9 ~; [8 n( o- R; k8 i" D2 R#include "cpu.h". T+ Z. B6 h/ o& G2 n
#include "ppu.h"
# v; J9 A/ U$ a/ x#include "rom.h"
, f. w. l, V/ B) c2 o$ N6 d! |#include "apu.h"
* `: r' A1 O: |2 k: z% c6 M8 Z9 R$ H, ~" y6 v/ |# d' e; q
// Volume adjust2 ~) J) R( j- O+ S; M
// Internal sounds
  z; {. p$ W* Q, k. ?) N#define        RECTANGLE_VOL        (0x0F0)
3 I$ V6 ?# U) H2 i; i+ D#define        TRIANGLE_VOL        (0x130)
' {. X- A0 s2 d5 p#define        NOISE_VOL        (0x0C0)
5 x! Z2 T: `4 B$ G* r#define        DPCM_VOL        (0x0F0)4 ~7 a$ G2 G' A* m4 h8 V2 z
// Extra sounds
5 d+ }( J$ \3 |! F& @: o#define        VRC6_VOL        (0x0F0)
4 |# C. f! p- \#define        VRC7_VOL        (0x130)
" x, m: {" ~7 |9 Z6 [  H; R8 m6 V, X" f#define        FDS_VOL                (0x0F0)
- k; f7 A+ V; h7 f  U#define        MMC5_VOL        (0x0F0)" X! T; @; ~/ o
#define        N106_VOL        (0x088)3 i# z; S& k% v9 E* R7 b
#define        FME7_VOL        (0x130)
: z# K4 `0 i: @$ P
' e5 E* n* u( C3 YAPU::APU( NES* parent )
. g: r0 c& p7 d9 \- E: p9 Q{, t3 a6 I, u8 l4 ]8 z+ h
        exsound_select = 0;4 F2 J) w, J) e+ z) m8 W) S) g

8 Y6 Z6 d7 j. P9 V6 q        nes = parent;" M  o# b* g" t
        internal.SetParent( parent );
) ~# J; b% S  g6 T# _, q7 n8 N6 L! g. p) b
        last_data = last_diff = 0;% J8 A4 c9 y  x- Y$ x
$ m, w  }0 l  z# B. a7 U
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
+ o* ?+ a- ]: f/ L6 i  [- c; H; n! e% L, F/ X# h3 Z  }4 p- O
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
) D; \% n: z& @( _: g        ZEROMEMORY( &queue, sizeof(queue) );7 T4 V# Y5 @& W& q$ D: q. L7 o
        ZEROMEMORY( &exqueue, sizeof(exqueue) );! T0 V' Q7 [& |) h( B

7 r+ h. e, l8 w- U$ ]& y        for( INT i = 0; i < 16; i++ ) {
+ ]! N6 {0 i: a) @                m_bMute = TRUE;
2 S. [/ ]- q$ x0 S8 ]( e" Y        }
  J$ u1 R, ~& L6 |6 }2 h/ ~; _}
: @2 r% e  q+ {3 H6 ]& y6 W
3 ]& T. l" i8 d$ MAPU::~APU()
9 _: P# J/ a/ v5 c5 L8 V1 L{# _7 H" H1 K5 a5 [% T. \1 q' O
}" [8 ~+ v% e' F' Z6 t
( R7 j6 X3 V- l1 h
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
' _* I# y( s4 C+ R/ e& ]; @: _{
* f+ c# B  w' C+ I! f# y$ ~5 {        queue.data[queue.wrptr].time = writetime;
: c: Q/ M1 S4 `        queue.data[queue.wrptr].addr = addr;
8 W+ E. y$ a& t1 ]        queue.data[queue.wrptr].data = data;# p8 W. {0 _2 W1 d
        queue.wrptr++;- [3 q- {# c5 G8 X2 m
        queue.wrptr&=QUEUE_LENGTH-1;! |7 m7 i; u' A# P) C$ h
        if( queue.wrptr == queue.rdptr ) {
' y' ?6 T$ _+ k# `5 ]' B                DEBUGOUT( "queue overflow.\n" );) _4 ~* p2 u! v0 [; ?  X7 _; D
        }4 I& Q+ `3 _& G3 ~
}
4 ]/ I* Z  B% q( F: N  C; j4 n% L+ L7 P: k* e8 L/ D
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
- J2 m  u) T. ^$ V{
! ~2 c( X: [8 A4 {9 y( C+ V/ R        if( queue.wrptr == queue.rdptr ) {
9 R. B4 |/ J0 ]$ h4 M                return        FALSE;
8 r7 N& {/ d* e% J6 ]        }
: h8 S0 }, ~9 H% q        if( queue.data[queue.rdptr].time <= writetime ) {) Z* R* x' j. b, X
                ret = queue.data[queue.rdptr];
* R. ^, r. |  Q1 v/ @                queue.rdptr++;" a! X; G9 \, p) A7 ^
                queue.rdptr&=QUEUE_LENGTH-1;# @0 `5 K, ~, R2 W7 Z: \
                return        TRUE;
, x7 {3 F  f' a1 }3 m        }
* L: K9 m( ]4 h- C( |1 ^2 b        return        FALSE;
# W8 o2 I1 S* p  `' G" b}7 R1 M! w' n7 q
; n9 a& S$ T+ P
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )+ |4 s7 f6 e! b6 B  \  [
{+ Y7 Z/ }" B) l( O; y
        exqueue.data[exqueue.wrptr].time = writetime;9 m/ l* p+ ^6 R  a  D" K8 {
        exqueue.data[exqueue.wrptr].addr = addr;
! X% H( r  E3 C' r6 c        exqueue.data[exqueue.wrptr].data = data;
: {$ s% \. k8 s% s5 e/ i5 o. J        exqueue.wrptr++;
& F/ ^% j7 W% p+ G& L0 H+ W6 c        exqueue.wrptr&=QUEUE_LENGTH-1;
$ F) j/ N9 L8 w4 J; p        if( exqueue.wrptr == exqueue.rdptr ) {% l. P0 [5 s- ?% Y
                DEBUGOUT( "exqueue overflow.\n" );
$ N5 _5 C; R& ], w: G7 A        }# ]1 Y# N  S4 ]! v
}1 B6 [" q6 Z7 x/ w: e* t

+ s, W+ h' ^( B4 n- e1 y# h, Q9 }BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
& d) l3 Q* ]" _{
7 g8 h6 [) i( j2 Q6 u        if( exqueue.wrptr == exqueue.rdptr ) {5 Q! m1 p1 k$ J
                return        FALSE;
5 a+ O! Q6 L" [1 E/ ?        }
) U6 ^$ ~' P+ P0 j& ]- o        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
- H  m) w' \1 F5 y0 o; K                ret = exqueue.data[exqueue.rdptr];1 ?; ?2 N4 G( c4 a
                exqueue.rdptr++;, S  L$ C: G3 E8 v
                exqueue.rdptr&=QUEUE_LENGTH-1;6 m' P1 ?1 B6 z' e8 h, D+ u
                return        TRUE;5 s& h7 m! n+ U7 J  w" Z! w" h
        }
) Z7 a% R$ Y/ b  S  o. a# f1 T) i        return        FALSE;+ q5 l# m- X$ c% j% H' M8 i+ |
}
) C0 s  m  W1 g6 g& @+ `6 i; A; G9 t( z$ d
void        APU::QueueClear()
, N1 _4 C; b% E$ }0 \4 H% \" h7 A7 S{( s' d; I) @& Z( f6 E& p$ h! X
        ZEROMEMORY( &queue, sizeof(queue) );7 S1 n) E  Z/ o, o2 ]8 M
        ZEROMEMORY( &exqueue, sizeof(exqueue) );/ K0 U  Y" d5 @0 K  F
}
$ l: V& M7 q7 M$ Q' D/ V
( U3 ?% L6 P( G/ _* svoid        APU::QueueFlush()
/ ]! M3 b, c5 ]" j2 C{
! L! p' z+ u" h3 \; C: P        while( queue.wrptr != queue.rdptr ) {3 Q6 ]( R$ A3 y
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );4 s- W7 }& |2 A
                queue.rdptr++;
) n& k% l' Q% K                queue.rdptr&=QUEUE_LENGTH-1;  h5 I  d  K" J/ C2 c  [! G
        }! Z1 L, [* j; M9 b4 t

: i8 J- ^6 N9 z9 i/ c, a8 ?- c        while( exqueue.wrptr != exqueue.rdptr ) {1 Z0 f: y- b4 m7 H) z
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
. c; z/ i+ D1 Y( `2 m3 I                exqueue.rdptr++;
. h3 ?) @+ v& ]                exqueue.rdptr&=QUEUE_LENGTH-1;
- k% H& J8 H: @9 t# q( W6 O        }
5 E! F0 \8 c2 _! o) I}  O2 E3 ~  K) s! E
3 w4 u5 G% D( ^
void        APU::SoundSetup()
1 C2 V" i2 \8 x9 L% S{
* q2 U0 x  U. {3 G3 Q4 u        FLOAT        fClock = nes->nescfg->CpuClock;* H  Z% x  J5 ^1 \# _- P( c
        INT        nRate = (INT)Config.sound.nRate;) ]8 T/ Y! n, a& N) k
        internal.Setup( fClock, nRate );1 _1 n) Q2 w" z' V
        vrc6.Setup( fClock, nRate );& [8 U# j" y% u6 d
        vrc7.Setup( fClock, nRate );; b. F( J* {- D% Q6 S+ |6 |
        mmc5.Setup( fClock, nRate );; Y* q5 M, b9 i6 E/ @
        fds.Setup ( fClock, nRate );( M: N  I2 @& ^+ `8 m! Z- }
        n106.Setup( fClock, nRate );4 R- o1 J5 z( t# x* z! c2 i% E% ?
        fme7.Setup( fClock, nRate );
; _$ p2 s3 W) Z1 U  Q% I}8 A; k2 R* e: a; j! G# C0 f, I
* j* S5 n+ e6 E9 g! C- L
void        APU::Reset(), C  W  b' b) Z
{1 m" r& S; g  n: L, y7 w
        ZEROMEMORY( &queue, sizeof(queue) );  G, O, j0 P4 G  Q$ n& B9 ~
        ZEROMEMORY( &exqueue, sizeof(exqueue) );) O% n7 y+ a0 G( `. h- n+ `8 {; s
. S% Q  I1 j* M
        elapsed_time = 0;0 F! T; ]/ {7 S5 K( _0 }. x% e
: E/ y7 Y$ S; K  h" q
        FLOAT        fClock = nes->nescfg->CpuClock;
! k; r$ j* B0 G+ L3 k, `8 s$ I        INT        nRate = (INT)Config.sound.nRate;* s' q0 j3 y5 h* T  Y
        internal.Reset( fClock, nRate );
& v! p2 c0 I2 q; O$ e0 ^        vrc6.Reset( fClock, nRate );
6 i( Y( L6 A. ]        vrc7.Reset( fClock, nRate );
& v& g, f9 Y& E6 z: t8 o% S        mmc5.Reset( fClock, nRate );2 H5 V- ]9 i% q# Q* K9 K
        fds.Reset ( fClock, nRate );
! ?* x* `0 r5 j  [( V; M        n106.Reset( fClock, nRate );
0 b$ q+ z4 @0 }9 j        fme7.Reset( fClock, nRate );
1 O+ R( O5 d3 }6 `3 G% w% \+ X3 T& U. j' @: B
        SoundSetup();
, H. C/ B! s% ^- e7 W2 I}
& V; R6 @: L& X6 s: y8 f! I  C
9 j* n/ l: W1 @. m6 pvoid        APU::SelectExSound( BYTE data )
& E! T, W% p/ h{
, W  q3 V# C4 ?8 A/ a2 G, s* e$ Q& S        exsound_select = data;4 {! F1 e' S; J- i
}  S7 m. d% `0 O7 t2 ~$ W0 Y; A
; d* v5 D  J! X. W7 _: ?) S
BYTE        APU::Read( WORD addr ), D# @7 j5 e7 Z. t5 {$ w
{
! Y0 ]5 _! w9 f7 h1 a        return        internal.SyncRead( addr );5 q4 I4 j5 w# _& l' r' _4 J$ @
}& J! V9 `# y1 B) b* W! q* K: R/ N1 W4 ]

% m* m8 }; z0 bvoid        APU::Write( WORD addr, BYTE data )
+ l% n7 a( q% h{
( }6 [" q; x# ]/ s+ N" e3 c        // $4018偼VirtuaNES屌桳億乕僩
( O$ b  ]$ _# W$ q, m- @2 z        if( addr >= 0x4000 && addr <= 0x401F ) {* C. S9 S8 Q& T. r: R. s
                internal.SyncWrite( addr, data );
* A9 r$ J1 ]+ n9 {5 w" D# B9 y                SetQueue( nes->cpu->GetTotalCycles(), addr, data );' q; O6 [' m9 X) Y; L+ B
        }- i/ X& V. I- V. |  r4 b
}  V/ _# R  n; L9 P) L
' ^$ W% x4 d6 w: s0 \
BYTE        APU::ExRead( WORD addr )
2 \- Y4 @& `0 s9 L' w{( f" @! e1 k5 i" K; P" F! A
BYTE        data = 0;" ^; _  S6 s  t2 P
: H  C4 ~- A: k0 T  ^
        if( exsound_select & 0x10 ) {  F" E: V5 W0 ]5 W2 e! l
                if( addr == 0x4800 ) {
& P* A- P1 O2 r, t  E/ f                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );2 G- ?$ S/ L( Q, q4 X
                }9 X3 Z5 W* Z, k  S7 ?5 J2 D
        }! d1 ]  I7 F8 c& K
        if( exsound_select & 0x04 ) {8 K9 C: ]  g: _
                if( addr >= 0x4040 && addr < 0x4100 ) {
; J( l8 S0 M3 d4 y                        data = fds.SyncRead( addr );5 X$ s- o& y* u
                }
0 d6 F6 F1 F4 L& p+ P8 ]6 k, @6 m        }: \/ [2 P) g' r  f) J
        if( exsound_select & 0x08 ) {
; w1 r9 u7 U5 N+ |( y8 z" [                if( addr >= 0x5000 && addr <= 0x5015 ) {( i7 ?3 u6 D# G
                        data = mmc5.SyncRead( addr );
9 A5 ~0 _* K$ e& p6 C                }2 F' z1 v/ `1 X* s/ c" ]: x0 i
        }" m8 E1 X/ a( ^3 [* [3 w

- N0 Y: b6 o( Q& |/ h8 W6 ^        return        data;, y+ t/ U# K) w2 Z* k
}0 G  q( k# E8 q  E* Q
6 B, o0 @" O: r
void        APU::ExWrite( WORD addr, BYTE data )8 A7 ?. c/ V- W; c
{3 V* W$ _; P# z/ k' O
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );. R1 \8 S( U3 O7 z6 V% K' A
% M2 c' f' U" t+ H! \# ?% M
        if( exsound_select & 0x04 ) {; G# W" O) T; c5 i9 U2 F) D2 r
                if( addr >= 0x4040 && addr < 0x4100 ) {5 _% e7 q. h3 n1 m% Q
                        fds.SyncWrite( addr, data );
' J" h! ^- i. Y3 {4 a, y) M                }+ F. F* c2 u! h0 f6 m' o# ?
        }7 E! P% ^$ j6 b" ]: c* `
8 L; p9 Y" {1 K4 z4 O+ j' h/ j; ~
        if( exsound_select & 0x08 ) {
- i7 |/ a- C! P) L8 {2 O3 `                if( addr >= 0x5000 && addr <= 0x5015 ) {) ^6 m' m* C$ Z3 q. l: i8 _
                        mmc5.SyncWrite( addr, data );
; V0 o" r3 ~! z# ^                }
# M  h4 G+ O# u: O2 v3 `        }
* q% L3 p- ~- v% b7 z$ o& _}
, q" v* O- \- B) s! Z+ [# \& J" g6 C6 s
void        APU::Sync()6 u) {% {4 q9 C  W+ T6 V4 R5 y4 ~
{3 _& s& j+ b5 x7 g* A
}
* v- ^* r% Z6 A) }2 b
1 w7 u8 s- c* @% `' n0 Y, ?2 ovoid        APU::SyncDPCM( INT cycles )
% e& J; k3 i" o! ~3 Y{" p5 ^7 Q$ \' p! ]9 W
        internal.Sync( cycles );. z+ v: w/ T* c% A! m
9 X( J/ x$ W; V, N8 q
        if( exsound_select & 0x04 ) {* u5 A. o# o$ k+ b" W/ b
                fds.Sync( cycles );
7 B7 L, a3 ~; ?/ o5 q        }+ A4 n6 T) p" g- L  j, m3 W
        if( exsound_select & 0x08 ) {
' P# _4 l' y3 W7 \4 d( N, K" s( H" m                mmc5.Sync( cycles );
4 i. I8 [/ ?' l, w# [, @        }
6 k) @' d# x) K0 M}2 \0 Y2 I1 X1 L8 N  g- X
7 X( ?8 v4 \! V9 u
void        APU::WriteProcess( WORD addr, BYTE data )0 s" S+ e/ Y: e9 ?3 h' K% J
{. @6 z% X5 l7 y5 K  l
        // $4018偼VirtuaNES屌桳億乕僩
7 `4 b5 e# y' X3 b4 h) S: ^* r        if( addr >= 0x4000 && addr <= 0x401F ) {
7 H, v% h/ {& }: Z) @                internal.Write( addr, data );
! R, F6 x2 R0 s! b+ t& W        }
2 p, A  O4 w% e4 @}
. R# Q, B7 ^3 L6 i, J8 ~( _: M4 v2 Z: {1 m: H
void        APU::WriteExProcess( WORD addr, BYTE data )" ?5 e# c$ U' k; p0 [
{
. Y; x% w' H: b        if( exsound_select & 0x01 ) {+ N# ]- D7 i0 ]6 Q) B, A
                vrc6.Write( addr, data );; n5 c  @, D; h" W; N1 ~  U
        }
, N* d. H" L$ `! n        if( exsound_select & 0x02 ) {( f9 s& q) g" o4 Y% q1 n
                vrc7.Write( addr, data );; b8 p# x% L5 i2 |9 i' V) L
        }# c9 P' w) K( F7 y* h
        if( exsound_select & 0x04 ) {: V9 k0 h0 E9 y, o' u
                fds.Write( addr, data );8 k. ^! ~0 I9 c3 J9 \: E, J2 `
        }6 a& e" i7 c; w# m( p0 m
        if( exsound_select & 0x08 ) {! O: @& T3 K( C; W6 Y0 y
                mmc5.Write( addr, data );! P8 s4 s4 h3 J& a+ i2 ?4 K  B3 Q% Q
        }( g8 ?: C" j7 l
        if( exsound_select & 0x10 ) {
1 P7 a; z9 e. @  a  ~, i/ E                if( addr == 0x0000 ) {& N7 r5 [9 q. i' q
                        BYTE        dummy = n106.Read( addr );9 n; i! J4 a; R: w- M% f
                } else {
! B! i! e5 G4 o                        n106.Write( addr, data );  C# E! V* B& O0 G$ \! ~5 V# B
                }+ @2 p2 w& l. n8 r, A
        }2 e# X' s3 s; Q
        if( exsound_select & 0x20 ) {1 ~- l# Q9 c+ T$ W5 L. a, d/ M7 x, L
                fme7.Write( addr, data );% ^) W: n1 T1 j: _, d
        }
; Z# @  _# P: }}
( J! T; q5 v2 u; Y. Y4 s
& P& ]* J$ _9 E7 J) lvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
  M& F- \4 v9 g{4 q& [5 x/ i4 ]5 b9 ~4 i2 f1 |, Q
INT        nBits = Config.sound.nBits;1 f8 n$ `/ K/ ]5 c$ O6 [; ?* R
DWORD        dwLength = dwSize / (nBits/8);
5 b7 G8 v- Z$ }# qINT        output;% ~) ^/ ^+ o) g& C6 z- d
QUEUEDATA q;- |1 ]7 G( A! ~& \- L
DWORD        writetime;
' Y7 \  s+ u" N" {9 _' b6 t; d" d$ f3 ]* g0 N$ @2 @
LPSHORT        pSoundBuf = m_SoundBuffer;5 c6 v( L  a; V) g8 o
INT        nCcount = 0;
' Y1 R( z- v# k5 X2 T7 _- d2 u1 @% z9 B. ]
INT        nFilterType = Config.sound.nFilterType;+ f4 ^* w& {# O$ d

0 u: l8 Y1 _5 C1 ^6 A        if( !Config.sound.bEnable ) {
- n( J; Y2 |+ W$ _" ]" X- E                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );3 P  Y, b- D+ F; u# ~
                return;
& Q8 t" S: P  K0 g' @) ~, R# W9 Q8 P0 o        }. `) Q& W  F+ H* l
) C' m$ S) ]# s$ T! w, V
        // Volume setup
* C  k+ Z4 {' D. b0 x( t$ t        //  0:Master
4 H' c- l/ R, B: f5 E3 b        //  1:Rectangle 1
" N5 s$ C2 m) C( [        //  2:Rectangle 2
- |5 o# d- j  l* [        //  3:Triangle% f8 H- `. v: K: L2 A7 L6 [
        //  4:Noise
- V  c3 o6 Z, N+ X+ w        //  5:DPCM
$ e4 E7 @9 @* S$ O) C# z; o        //  6:VRC6
4 l% s% t9 N' ?* H5 o. [        //  7:VRC7/ H% E* e" O( V) U* J) H# E: F: l
        //  8:FDS6 Y9 Q' J5 `, W$ b' p
        //  9:MMC5
! N* e+ Z6 R* V) n0 s5 K0 O8 @        // 10:N1063 R8 ]/ c' K4 Y
        // 11:FME7
3 K5 ^# ?$ Z4 W# F/ R1 p        INT        vol[24];
: u% u' q! Z3 e        BOOL*        bMute = m_bMute;! ?3 b4 _4 {& H
        SHORT*        nVolume = Config.sound.nVolume;
" i6 Y6 g* j( w2 T0 M* y6 N1 d9 y% @
1 q; W) q  }# _, |( K        INT        nMasterVolume = bMute[0]?nVolume[0]:0;: ^7 z% D! l* s6 X- V9 H

) z( [! V" k& t# A        // Internal' w1 {  d. Y; b; n/ s/ N0 o
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;5 g, ]2 N: R" o
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;1 H6 Z0 y$ y+ J1 Y
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;. j: `; S. }+ n6 z, q$ k4 V7 L
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;: E+ h8 h) k; G5 [. y+ b
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
: o# O1 s2 \; p& c0 S
5 T. J: Y' ~3 Y* I        // VRC6
, u! {7 ?( Q+ x, A  t. }( @7 R        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;9 M( \0 e0 n( u8 ~
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;* Y' X" Q, Z. p( b/ v
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
) T* i2 Q" Z% e4 q2 R2 M1 L* s: v- N
        // VRC7
1 Z4 k, f- ^" \$ [  ^) |        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;6 L% v- S$ q. T
9 W+ f; F0 P' R: T2 A" R8 s
        // FDS6 p" y, X# r2 O! `2 `( R
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
: @8 B0 c: ^* G+ x% h9 R1 x) L+ G* w/ u. u% M7 I# K
        // MMC5
( t- F1 V4 g# R: D        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;: [. R8 Z& q* O2 D6 y) {- n& V
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
' E% H. K# a# ]  n! ?* g- ^        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
) L) W2 B/ ~6 ?( k* h% L7 C4 X& V2 J* m  m$ g/ N; ]4 p7 _1 S$ m# [
        // N1065 A+ v: D( ^+ b- c, W
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
1 S3 y6 j( ?$ [' \# [; i' t2 R        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 k  J5 Q. r7 q4 C8 i; j        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
( h, k: e: k8 A6 q) M: P: O% r        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;) ~8 ~( @0 q7 Z# i3 R
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;( m' d! o' h- r$ Z8 x3 Q4 N
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, A2 Q2 k# r" W        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
* d* t+ D  {  m, F        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;, b% i, S! `$ n, q! U" D, V2 e
$ U9 p, Y* K. y& D+ V5 q
        // FME7! B3 G+ S! C7 }! I/ m/ M% O9 i
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
- R7 \" m7 L) p        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
' j" T3 c/ ?) F% z, @4 M* q        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;$ I5 o" N- C7 ]9 _1 {/ g- ^0 i) \

9 i8 e$ r- c/ d0 X//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
3 y7 \$ O2 T! z9 P- i' L9 q# y        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;. `0 E! |5 C3 L; n5 R4 S' a# A" _0 Q

! w+ b& j- }# l6 [8 h        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
( d8 e6 o# g% S; J4 d& w! j8 T        if( elapsed_time > nes->cpu->GetTotalCycles() ) {* [9 @) J6 O. ^. b
                QueueFlush();
9 R. }6 s+ r% G$ L; t        }8 k! f7 y- V3 j0 `2 R0 c% ^( J3 L/ `
6 k* r& h' O, ?) Z4 w& H
        while( dwLength-- ) {
5 e3 ~% Q( Z7 l5 H- Q: y) F                writetime = (DWORD)elapsed_time;! f, k: {; t! m! T/ L
8 {. r( W8 l* V6 ?! l' y
                while( GetQueue( writetime, q ) ) {
' R7 `% K9 ^; Y0 x                        WriteProcess( q.addr, q.data );
0 f- Q8 k  O% o* z5 ^% ~# J8 v9 ^; }                }
* S% |! X+ J4 y: R" R3 M
/ q8 O& l3 G" p+ }% w9 O                while( GetExQueue( writetime, q ) ) {: y7 C0 I$ B+ q3 |
                        WriteExProcess( q.addr, q.data );0 l) [/ q) a) y; {
                }3 A& \* Q7 }# V! [! Q% q
  [( y7 y* l& Y
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
9 f" }- w5 j5 I. n1 k                output = 0;
' x% n, X( p* ~6 y( p                output += internal.Process( 0 )*vol[0];
3 T7 @# B5 S( C$ \: @! r7 r                output += internal.Process( 1 )*vol[1];
9 }% J5 U9 S, g  g- i, ~2 D                output += internal.Process( 2 )*vol[2];
: X% w! y2 c% t/ n                output += internal.Process( 3 )*vol[3];
8 ?% I% k( Y0 c$ F$ `9 E; E$ s                output += internal.Process( 4 )*vol[4];7 Z4 H$ O8 l/ O+ o+ o
  f8 j9 ^# j& O1 x
                if( exsound_select & 0x01 ) {
3 O; S8 P- H8 ^                        output += vrc6.Process( 0 )*vol[5];
9 F9 T2 c! V7 D6 v0 }                        output += vrc6.Process( 1 )*vol[6];3 y7 v0 n. n& [" q" s
                        output += vrc6.Process( 2 )*vol[7];
0 Q) k  j* s. j0 T! X                }
- O/ j2 L" |. J, V                if( exsound_select & 0x02 ) {
4 c# R7 B0 s- O( z7 X! C" R' `                        output += vrc7.Process( 0 )*vol[8];" }/ M# n; A5 w' v! q7 l
                }
3 w* Y$ Y' u2 n9 s9 a5 |                if( exsound_select & 0x04 ) {' _* w2 o! u8 s% z; G5 r
                        output += fds.Process( 0 )*vol[9];' ~! D; V) Y9 Y( g- N) Q$ z
                }7 G1 f# _: x, G
                if( exsound_select & 0x08 ) {
' H6 l: h. o* \! O                        output += mmc5.Process( 0 )*vol[10];" Q& n3 i$ V! ?
                        output += mmc5.Process( 1 )*vol[11];) K& a; ]% j6 U) w
                        output += mmc5.Process( 2 )*vol[12];$ y2 ]6 _# S  C5 h# B
                }5 j! ]% S: n/ \# H6 r' @
                if( exsound_select & 0x10 ) {
# D* O5 V1 A. f                        output += n106.Process( 0 )*vol[13];+ V  d4 e+ e5 W# Y! ~
                        output += n106.Process( 1 )*vol[14];
* D3 y3 G& e( P1 Q                        output += n106.Process( 2 )*vol[15];
5 G; D8 u  ?2 m" @/ G+ E                        output += n106.Process( 3 )*vol[16];6 N5 `& W( r. [* N! L1 F2 d5 X* ^6 G
                        output += n106.Process( 4 )*vol[17];6 w9 i, g. D  n* [, H% {
                        output += n106.Process( 5 )*vol[18];/ ~9 A# g% S! f" A  q; W/ T# T1 g" e
                        output += n106.Process( 6 )*vol[19];
" |4 Q# [% G$ S  X/ Z                        output += n106.Process( 7 )*vol[20];9 C5 [7 S+ R+ B) M
                }/ t; Z, e3 T( C; X4 r: Y
                if( exsound_select & 0x20 ) {
7 [& |) o- _+ X" k                        fme7.Process( 3 );        // Envelope & Noise
" [* D6 H$ t. }8 L2 y                        output += fme7.Process( 0 )*vol[21];
' y, B6 t) Z; S2 \                        output += fme7.Process( 1 )*vol[22];! p. W' {& b1 M/ e* @6 W# P
                        output += fme7.Process( 2 )*vol[23];4 n/ p; q0 n9 V. S  r. H! _3 f# G
                }
9 }% X7 T) B0 Z* ~8 O. I
. ]; ?, ~( D* B, B& G" \4 s) ?3 h                output >>= 8;
8 b0 v+ n! X6 l& ?
( B, p' V  u7 c6 i1 y: J                if( nFilterType == 1 ) {' f% p; k; @; _# s2 M9 d0 J6 j# f
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
; a4 K, J" `4 r                        output = (lowpass_filter[0]+output)/2;
* t) I3 M; e4 R& u+ @2 b0 ^" i& K/ t                        lowpass_filter[0] = output;
3 P5 a$ p6 ^) j6 z: b5 ?                } else if( nFilterType == 2 ) {
6 ?, g3 K3 G* Q! u                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
: A0 G: C' z2 S$ f* z, x                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
1 c9 n7 u! t. T                        lowpass_filter[1] = lowpass_filter[0];: N) a/ w* L. L: t
                        lowpass_filter[0] = output;
) @, w: B2 {% I, y  K# I                } else if( nFilterType == 3 ) {$ d+ P" z  G  Z  ^+ X' u/ T
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)! R' o& T+ H/ h4 h! U. ^/ ^, h" V
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
5 u6 N! h8 ^+ ?) U! u& \                        lowpass_filter[2] = lowpass_filter[1];5 }8 i3 \: C+ ?' [4 u& }
                        lowpass_filter[1] = lowpass_filter[0];
' Y: I+ Q* ^8 P2 ^0 s                        lowpass_filter[0] = output;
7 X4 M; P  M) H) [: ?+ X- d                } else if( nFilterType == 4 ) {, [- |1 @/ S( ?
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
' x3 t" J& z' V$ N                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
$ c7 k) O0 N5 K                        lowpass_filter[1] = lowpass_filter[0];
" g; u& w/ I. X8 x# J                        lowpass_filter[0] = output;) C/ m1 N: V4 Y. |
                }
( q* O& T% d' s5 J* C* r
! q$ F- H& r0 m$ e#if        0
' v# z% Q$ p  j" L                // DC惉暘偺僇僢僩
, y( }  B% j3 ^2 D                {# G8 @1 f: [  u
                static double ave = 0.0, max=0.0, min=0.0;
& e5 A- R0 j1 ^) z  d                double delta;3 C8 c/ }1 w$ s4 g+ E/ m
                delta = (max-min)/32768.0;  Q- ~9 w" B. L9 d
                max -= delta;
/ N$ q/ C4 i. ~4 q7 }) y% t                min += delta;
8 A9 ~! K* v' p" T4 I2 A2 F                if( output > max ) max = output;! W$ g0 Y- y1 y" c3 ?+ o# {: p
                if( output < min ) min = output;
( s2 f+ \: v& m                ave -= ave/1024.0;
) i" }$ D9 Z9 s" R, P) ]7 @                ave += (max+min)/2048.0;
( ^" h( Y5 f1 ^4 n8 ~" D+ _& w                output -= (INT)ave;
; z  U6 z& [" h5 U( d                }' q, v% w: g5 V  }3 Z% f
#endif
6 O; S( G% Q9 J, ]; o0 ~#if        1- e4 G& |9 \4 O1 `, G2 W4 Q7 k
                // DC惉暘偺僇僢僩(HPF TEST)
: I4 i# u: o, [& t% D/ v                {7 J8 }1 V# o. }2 m- O" u
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
! O2 {/ h/ n5 v3 |! N                static        double        cutofftemp = (2.0*3.141592653579*40.0);; ]+ k$ A4 N9 W6 |
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
; d9 H3 d; S# U3 V8 Z9 x2 Y                static        double        tmp = 0.0;2 x# Q5 Y7 k- ]5 S3 D
                double        in, out;
- G3 B0 y- N2 D2 M3 e3 A; P& o3 _/ L8 l  X9 p' `; y
                in = (double)output;0 m# f1 o7 Q3 \+ m
                out = (in - tmp);
2 w! P: S* A' S- Q3 N; T9 C! H                tmp = tmp + cutoff * out;8 q/ `. d- K# H7 H
( O: R/ ~( v- M# E; C
                output = (INT)out;
+ W$ w* p1 E' ?! E) P$ u/ {, B& p                }
+ D* u& E7 D& B" D/ ^4 m: d8 P8 m2 x3 `) h#endif, j- s: e  a* Y! F) l! B! R, E- ]
#if        0
2 S, G! ?( _9 H/ O9 q& {  E" w                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)9 D5 A/ B( ^+ m- ~+ k
                {
, {! u- r' S9 y  s                INT        diff = abs(output-last_data);
7 f# [6 J0 G6 z2 Q/ L8 V2 }                if( diff > 0x4000 ) {
) W" m+ `+ a( ]% b6 J                        output /= 4;! s- D" k; Q; B0 s8 o: H7 \
                } else
" K( E6 u/ k% \: `                if( diff > 0x3000 ) {
/ j+ c0 f: r/ C                        output /= 3;
  M! ?; i; W5 m; `& t. a                } else
8 l0 l$ B& {: B! t. u                if( diff > 0x2000 ) {& m" |* P# g. E& ^
                        output /= 2;
4 V/ T1 o8 l* T6 r6 _5 }1 v3 X) G                }" O0 r- g6 H  |% h, i9 k' Y
                last_data = output;3 Y+ K8 Z9 K( U
                }8 [) `: U# _/ p0 d' u3 r2 `$ h
#endif2 C6 O( h6 Y, u8 M0 p4 \
                // Limit
/ [; W+ j, c8 w6 |( F: Z                if( output > 0x7FFF ) {
2 c" r. Q& J# \6 j" u* s- s& W                        output = 0x7FFF;
: p/ w- @5 o6 z4 h% t7 ]                } else if( output < -0x8000 ) {
! ^  U& g. G2 u$ v% a                        output = -0x8000;! l- b; |4 E; G: b" C
                }$ [# m; t1 S2 h3 d- _# ]  X

  e" k) K4 \: G; r5 N4 `                if( nBits != 8 ) {
+ ^: N/ f' k1 _! }2 @6 c: w" n# s/ w                        *(SHORT*)lpBuffer = (SHORT)output;( h4 O+ _$ I' h- {; G, W3 z) Y
                        lpBuffer += sizeof(SHORT);
+ |( L" i4 ?9 s/ o                } else {
5 D. d& ?/ t3 }4 x  Q" N                        *lpBuffer++ = (output>>8)^0x80;
5 o' o& w$ x3 B1 U                }
" m& N5 a2 Z# @, q; e  Y5 p/ |# ^( Q# |: Y* t2 m! H7 @% Z
                if( nCcount < 0x0100 )
6 x+ b, t* e% P' |0 Y8 L% u                        pSoundBuf[nCcount++] = (SHORT)output;
6 ^& a7 p6 W6 o0 B
9 \* `0 J) z3 r4 |//                elapsedtime += cycle_rate;
& S3 K* h# `+ m/ U4 x                elapsed_time += cycle_rate;
) h% @/ d" `; G  K6 p: y        }$ {9 K3 s' G; e0 x

( q# O1 P! S- g2 l6 F#if        1) S6 K& \* p8 Z1 B- }) |
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
1 P! s/ n; l7 ~& |; ?                elapsed_time = nes->cpu->GetTotalCycles();
5 B1 h/ k/ c/ `( G( n5 \        }
7 V) [# z# e4 b9 [" j' _        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {, r; R( y7 Z- C* A$ G- B
                elapsed_time = nes->cpu->GetTotalCycles();
3 L) b6 U! o6 m        }
9 x: b5 K1 [+ q; K% J, c#else
2 e' `/ m; x0 f7 a# q1 y( |& O        elapsed_time = nes->cpu->GetTotalCycles();$ t# r3 O8 ?' y$ k
#endif6 S/ ~1 b7 d8 r- @' O0 h0 ?
}
" w( I- S5 y. U0 L  ~, I) l! K$ {$ f1 y! ^! z  l2 B1 Y
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)& g" J/ Z* w! d0 A9 b1 h
INT        APU::GetChannelFrequency( INT no )
) a: x+ n. m  i{) E* D% K+ D1 v' q: ?" M9 P5 K
        if( !m_bMute[0] )
: J4 ~' S% s% {8 i* i                return        0;
1 K: |" R( F+ L+ h
/ v+ g& v5 Z& @1 @/ C6 U  m        // Internal' F- O, A2 n$ R3 w) h4 s
        if( no < 5 ) {4 a4 G) p3 ~. C2 B7 A6 Z: N/ ^
                return        m_bMute[no+1]?internal.GetFreq( no ):0;8 q8 I2 @& i7 L  d7 S
        }5 w+ d1 E' r3 `9 ^+ V
        // VRC63 ]. J4 [* Z6 w9 k
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
+ C- x# T$ ?4 x4 p# c4 l% W                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
6 a6 r8 C3 `. s1 d3 R, S8 [" c        }  @! [9 N1 `" e8 r
        // FDS
' z8 T. q, q( Y8 M9 e8 u% Q        if( (exsound_select & 0x04) && no == 0x300 ) {
9 R' g' Q* P+ z6 ~( `8 X                return        m_bMute[6]?fds.GetFreq( 0 ):0;
6 m" f7 K; i$ |& H( _- {        }. \7 F0 x! O% w7 D& [8 a- M* _
        // MMC5- p8 h$ `4 ^. E
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
' ~) Y2 g# G3 Z% }! z                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;1 Q: u9 `% g) Y2 s' h" s
        }
1 O; G. U; M2 _, j+ V1 g+ O) K        // N106
& J: L( Q4 v- H( a        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {* Y( a2 @' T! x! s& n2 G* J: s( a
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
0 [5 m: B6 m( v5 ^        }
8 g& `2 M( u: P5 f6 R- x        // FME7
% ^2 k( ]$ X* x2 j        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {! s# s; H* Y$ x: P
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
4 j/ q" y4 @3 Z0 E, _        }
" K: ^' x: C' Q# w0 {- w        // VRC7
, |2 h3 Y( C: Z4 e        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
; I7 V* B$ {2 j( W                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
2 [2 O' q2 ?' a$ {, _% S8 {' Q        }
/ P" B4 L( N& p' K" P5 @# d; ^        return        0;  o, m" N: n3 J- r
}9 Q- \" ]' D1 c) U" }! s! K
0 O9 @6 k  V: O& H% N4 }! \
// State Save/Load/ r$ ?: u+ r% y
void        APU::SaveState( LPBYTE p )" J* }5 {5 `7 e1 z" A+ f
{
& A! C& D# E  S; }3 ]; T" P6 [#ifdef        _DEBUG" |" j: k, a* G- Q! a
LPBYTE        pold = p;0 w1 U$ r( g. G+ Y' h- d' K3 c
#endif0 g& L3 h5 N. \+ L2 K

" g3 y5 Q3 W3 i; K0 q        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
& \+ `) ?0 R% v, s) @2 D1 r        QueueFlush();
! Z" z% I( E' k5 S
: z3 Q4 G  G* \( n8 j        internal.SaveState( p );
* ]- _3 Y( h/ K" p; M. r4 C% Z        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding6 ]% Q+ K6 k- J. b1 `4 U
8 i: s0 `0 t  W/ |& F* ^
        // VRC6  p$ X' m$ o( e9 N
        if( exsound_select & 0x01 ) {
2 R- h1 f* d8 n                vrc6.SaveState( p );
4 ~1 s( q0 V9 K3 Y                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding% E5 J: _5 ]1 L+ ?1 j9 M. A
        }
2 n: Y: f3 O& Y        // VRC7 (not support), m6 y$ @: N8 ]& @
        if( exsound_select & 0x02 ) {  F! y" v  [5 T' \8 a
                vrc7.SaveState( p );
. P9 i/ l1 K+ w% D. H% _, u                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
) l) ]/ ]0 v( a" h( g9 f+ _        }! a! I0 F% B# f) G# E- w5 k
        // FDS
- Z/ E" _# R& y& D* C        if( exsound_select & 0x04 ) {& ~5 r. L3 ?: f% m8 {
                fds.SaveState( p );" Z3 V+ @3 c% k, m3 ^* m- ^
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding1 Q2 R! @" f$ c8 l: ^
        }4 A: ^6 s6 d% b8 t! F1 b$ V
        // MMC59 [0 [: q) v- ?- g- I$ k8 s
        if( exsound_select & 0x08 ) {/ l+ r7 x$ m# I5 Z3 C
                mmc5.SaveState( p );
1 {7 `+ b: U$ t' w                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding9 [, @' L5 Q3 q$ R0 H) _" V
        }. c) \, Z! F! p4 f
        // N106! J+ M9 b; L# R1 a( t
        if( exsound_select & 0x10 ) {) q/ w% V# R0 i; p+ {
                n106.SaveState( p );
+ S; G4 {7 A  v2 {                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding& w* s3 i7 N9 q% e+ A$ _$ x/ b
        }/ O: ^$ A2 P4 c  U- T2 D  t
        // FME7& I3 D$ X6 s2 R5 g1 d) n6 J
        if( exsound_select & 0x20 ) {6 |+ x1 m3 F& ^, T5 y
                fme7.SaveState( p );6 @' Y4 |: V% w4 h- ^
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding- r$ o0 t! w; E- ]1 h( Z; z
        }
8 J3 n4 P# a" j: L/ v1 v4 A- G# ^: h* J* ?, C- }4 H8 Z: G6 \
#ifdef        _DEBUG, h3 [$ Q$ N2 {* @8 l( B8 t: o! V
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );; k* o/ S+ |6 h* u$ {
#endif
. n: U4 g5 g% |}
/ I" _8 Y* K, Q3 O5 N+ l
8 t; X" U; i! s" Cvoid        APU::LoadState( LPBYTE p )$ d7 d) n( I3 E
{
/ d% D# {6 @& h8 x3 `* t4 M        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
, d  h3 v! ~& n/ X9 H        QueueClear();
  r: Z7 H- _5 f2 U( ~6 e0 I5 U1 R, ?2 T
        internal.LoadState( p );( O1 v! x$ k: F6 r5 ?
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
$ v8 R' a4 R) o! {6 P
" S# t/ H& |! o  v; q2 h! \* c8 ?- X; g, F        // VRC6
  c6 K- T3 c- P9 V& M        if( exsound_select & 0x01 ) {+ W/ w! l7 `6 C8 O5 [% F' w
                vrc6.LoadState( p );) M( j1 W5 U6 H) o% \
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding9 D; }. k$ v3 u7 ]/ Z* h; \/ t0 K
        }- ~- b1 z6 x5 a+ j" H! X- }( U
        // VRC7 (not support)
+ s* }. z) X, K6 s  Y        if( exsound_select & 0x02 ) {
9 n8 f, ~! Y: H0 C8 c/ Q                vrc7.LoadState( p );
3 A  d( l7 Q7 a5 n1 a9 e4 o4 A                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
, N/ R  ?* S( C        }
2 ?9 C1 |" m1 i. Z5 g- g        // FDS. x- Z9 b% w) }" e" J5 d
        if( exsound_select & 0x04 ) {" }% w6 N* ]# g
                fds.LoadState( p );
! z1 V* `/ u: B9 s) y+ j; O6 x, z. o                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding: p4 g! {& t1 b. T& o
        }+ b7 K: o! X- ]$ g  p  c1 u
        // MMC57 I: O. C  ^, D1 c7 Q
        if( exsound_select & 0x08 ) {
8 O( Y" R1 c* Y0 X                mmc5.LoadState( p );% ]: ?5 k1 n: f" b7 K
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding+ O. F6 G( a4 X5 L) c
        }
2 e3 v& z$ s+ N. L: n        // N106
# ^3 \5 C2 F' M  k        if( exsound_select & 0x10 ) {6 X( x" K& z3 s
                n106.LoadState( p );5 x6 P2 _7 S0 _2 b2 ?+ B
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
; o7 y" b' v; J$ r$ Z        }
' U4 v8 T% S  _& D/ G; e2 l6 {8 E1 l        // FME73 ?! u: {2 ]4 C/ K
        if( exsound_select & 0x20 ) {- m0 U( I* v0 b* m* i7 ?
                fme7.LoadState( p );
( P# a$ J, f# |2 n( D5 H) w                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding7 x2 w/ Q6 w1 L0 X1 N
        }$ p; `% [, P, s9 A
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
8 R5 [* n6 {4 d7 {可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
# w% ]8 M. q. l7 H: F% c感激不尽~~
+ O" X/ x. _7 Z8 @
恩 我對模擬器不是很有研究,7 H- ?- |+ L2 \* P
雖然要了解源碼內容,可能不是很困難,
2 x/ ~4 h* p; r. {) P不過還是要花時間,個人目前蠻忙碌的。
1 |( a" F" {! p. e3 [
7 q9 v9 y" y5 f2 m3 r" ?# u- r給你一個朋友的MSN,你可以跟他討論看看,
/ x3 a6 P+ B1 r- E# b+ |$ C" @6 H  {他本身是程式設計師,也對FC模擬器很有興趣。
7 h: V8 i2 ?* J9 H; }: R; g
7 M; Q: i1 C+ n# ~$ BMSN我就PM到你的信箱了。
; s9 p% P0 j0 \$ }7 L" r9 b: s7 |4 I/ L3 |, k# ?4 i
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 @: b& H* p; w1 B呵…… 谢过团长大人~~
1 D7 d$ L$ x* p
8 C, {/ M  _( a
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
# B$ j9 C% Y' f  ?团长的朋友都是神,那团长就是神的boss。
! d( g. u5 Z- T2 D6 T& F( \; `
哈 不敢當,我只是個平凡人,
( ~+ g  c) ?% c, q* [2 b, M) F要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙+ @; P4 j1 }) R) [0 {( R  s
ZYH9 i- M- O( R$ n3 P: a
QQ:414734306
9 Y# u& t+ T( @2 l* K' g0 JMail:zyh-01@126.com
. r8 v! v% ]; z+ R+ V9 F4 u. }7 V. ~1 ~, g
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 " M9 r9 {. L. R! s# _- E
再次对团长大人和悠悠哥的无私帮助表示感谢~~
- @( V; s& `2 [" ^
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-9 17:37 , Processed in 1.126953 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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