EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。. q% i7 a0 a4 w; d
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
- q3 x3 i& c( M" T这里有相应的模拟器源码,就当送给大侠了~~8 f& a# C: w) N: ^9 n
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 5 I7 X7 p! s  F& w$ y3 V
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。) @# A; o. g# W( ?/ ]: D
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~! s3 r$ b, \4 U0 m6 I
这里有相应的模拟器源码,就当送给大侠 ...
7 ^7 c0 {. g- h& @& O) y; J" \) r- G
聲音部分(Audoi Process Unit = APU):
0 d6 d" G- F) D& J8 v) t.\NES\APU.cpp( w* v6 g) l/ x, G. A
.\NES\APU.h" A# d  }" s4 J9 S
6 l9 U! Q2 s3 w" _

4 v, t3 h- K7 U4 w# @- E0 X3 y影像處理部份(Picture Processing Unit = PPU):
  J2 w+ X' \* W.\NES\PPU.cpp
8 {) d& T: d$ O1 J.\NES\PPU.h
6 v# W1 U% E4 S# u* R' |' ]( d8 R+ i, J5 p% ~& u4 B: r$ f
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。( E# t  L7 l+ x, O3 _  Y4 ]
感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
2 M9 V+ L8 V4 _0 c  D(由于很多专用术语和算法机理都不明白,所以看不大懂……)" \, [, ^) ~* i
//////////////////////////////////////////////////////////////////////////
+ Y- k3 {) w# k3 z) b//                                                                      //
9 i; R- b3 ~9 |( L7 K2 [//      NES APU core                                                    //
" D# R$ p$ z- c. b6 I7 T+ U//                                                           Norix      //
# \# |) A0 I+ v//                                               written     2002/06/27 //  T. D8 _4 f3 x6 y+ w3 f
//                                               last modify ----/--/-- //
% h9 I( D) F& M* i8 t* e//////////////////////////////////////////////////////////////////////////
' E" C3 G4 m1 H3 U7 _#include "DebugOut.h"- O1 v* R! H) K8 s; O/ q
#include "App.h"1 m- E/ B( I4 i) |5 x
#include "Config.h"
4 g0 F5 V& G3 _$ V6 O9 B: a5 s1 D, {+ ~3 E* f! R6 _, D
#include "nes.h"
  j9 x& ~- E3 I4 a, ~; e* ~) e#include "mmu.h"
  l# \# v" ^3 t#include "cpu.h"- D; N% {; q; V# U+ w$ f
#include "ppu.h"
; w5 {0 w: X1 q' t) o4 y#include "rom.h"
7 _; B  `9 }- s" }; u4 d  q#include "apu.h"' J, d& [  m( ?6 o$ i; P- U

. [: i6 `5 B! P; G6 O1 }' X// Volume adjust0 t9 E  |, v: a6 G: V
// Internal sounds
0 m7 g1 N: P: A+ H. `6 I8 j#define        RECTANGLE_VOL        (0x0F0)7 ^3 ~& C3 y8 ]/ u+ U2 I
#define        TRIANGLE_VOL        (0x130)
& i. K9 D5 Z% ?- `9 A+ }) O$ l6 ^#define        NOISE_VOL        (0x0C0)
& s$ m. l, c% F) j; R! l- m#define        DPCM_VOL        (0x0F0)8 s% f  Z3 q% O- k% `
// Extra sounds' Y( x0 \5 i+ U" k/ [1 Z% ?
#define        VRC6_VOL        (0x0F0)- O& `" e8 ~" s2 z
#define        VRC7_VOL        (0x130): `- n. ^. a+ @+ g& H
#define        FDS_VOL                (0x0F0)
# L2 }, l( {1 ~9 `3 V& S/ q#define        MMC5_VOL        (0x0F0)
! }+ V( O9 @2 V1 p) q#define        N106_VOL        (0x088)
7 c1 e0 n: B; p+ ]( E- t9 u#define        FME7_VOL        (0x130)+ E* s$ N2 u, f% I1 Q1 X

' M, x4 B( x6 t/ {APU::APU( NES* parent )" U4 M% [8 X8 W
{
, O5 i& K$ \3 [- a        exsound_select = 0;! g! c+ H- Z+ H& Y

: w) Z1 c/ v5 m2 y8 V        nes = parent;
0 V' [$ ~! h9 z, m" r        internal.SetParent( parent );
: r& d% N0 j# P6 u3 [: N, j9 `0 I5 `
        last_data = last_diff = 0;# W: E3 ?! n. h

7 X# `! X( e2 q5 ]& |7 i3 ^% F        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
. l2 l1 z+ o/ `
* ^' b* @) z( t+ J        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
# t- K! X  h9 B' [) q: E        ZEROMEMORY( &queue, sizeof(queue) );# p4 j: ^/ E3 a, X6 S+ i; B! A5 a& q
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
! S; x6 r. K7 k# K1 e5 P: \( G# Y) X+ z0 X* i  m$ Q& X9 A. }
        for( INT i = 0; i < 16; i++ ) {4 K3 }) |; j# T* |: j
                m_bMute = TRUE;
3 k& |8 a/ b* ~- m        }
4 Z/ J  ]0 \+ t& D}7 F; k6 E; g! |+ C& S! M2 k' b

3 |/ o$ w  |3 x$ EAPU::~APU()- {9 t8 u6 U3 D
{4 {$ }; @0 @" }$ G6 f
}7 w; G$ c3 y0 p4 L
8 r; N. i- b0 Z+ W
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )/ ~- T* v& T! \! T& G
{
0 [! _2 w, F/ ]8 F( B' r' @        queue.data[queue.wrptr].time = writetime;5 b! r% E1 B$ u7 I! j4 _
        queue.data[queue.wrptr].addr = addr;
7 E2 x/ f; A' l3 k: Q: }; \        queue.data[queue.wrptr].data = data;) _# e8 B3 m5 Z) |' @/ p  J6 u. ?
        queue.wrptr++;
' r4 f5 N+ i! X0 {        queue.wrptr&=QUEUE_LENGTH-1;3 g  z# r0 r) i" X5 X" G
        if( queue.wrptr == queue.rdptr ) {
( u# U6 I1 ^' D. s# g5 ^( l! V                DEBUGOUT( "queue overflow.\n" );
, Y8 D3 r8 o+ j$ d        }4 {" k. L1 R) j0 o2 `* r3 h4 H
}
9 j4 x  q+ ^) g9 A. I. @7 S
! {  S; |+ E* O5 M/ |BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
- F) o/ ~* k# p{5 [4 j& w% y: e$ Z4 w
        if( queue.wrptr == queue.rdptr ) {
! _( Y% Z( s# D7 T- A/ H8 d* i                return        FALSE;1 Z" g7 F0 \. k
        }! Y& n8 @& v- A! l+ A1 f
        if( queue.data[queue.rdptr].time <= writetime ) {/ _$ Z! U: ~$ I
                ret = queue.data[queue.rdptr];. j! u: i: l" |4 x( a( d* ~4 M5 W2 e3 c
                queue.rdptr++;
; u; w9 d. s* W+ ?                queue.rdptr&=QUEUE_LENGTH-1;
( q7 l, C& }& O  ]8 E/ z                return        TRUE;) e# J  {; O. e* o
        }9 x. ]4 \% c4 I" |$ W5 E, M
        return        FALSE;
# z0 O5 ?. D9 J! J  \}
$ X# J. R. j7 L; h1 q' z( n# w
3 X, G7 J! N: jvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
. k  d2 z; a0 `6 _{" `* E: j- h- ]
        exqueue.data[exqueue.wrptr].time = writetime;
) K' A) o  B# b( X4 q        exqueue.data[exqueue.wrptr].addr = addr;1 X& |! r6 ^5 ^, ~
        exqueue.data[exqueue.wrptr].data = data;0 ?1 a, K# ~0 u8 N% e8 ^  `
        exqueue.wrptr++;( ^6 n" W1 G1 \, Z
        exqueue.wrptr&=QUEUE_LENGTH-1;
4 [9 y/ x2 j2 W1 l        if( exqueue.wrptr == exqueue.rdptr ) {
' J7 m8 e/ |) j" w. k                DEBUGOUT( "exqueue overflow.\n" );0 Z3 h. o; d0 o. E& }
        }& j5 T' P- m: s! A
}
/ V3 Y. Z8 ~, G$ D9 c4 k# r
# ~2 |6 C0 T# l2 X! ~, s; w) I5 iBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
: k9 W) O+ p; P{
4 F! F# O$ ~0 Q% a, C9 K        if( exqueue.wrptr == exqueue.rdptr ) {( f- e# R* V2 q( `9 }$ ?
                return        FALSE;
+ Q2 o. {# z  w; g3 Q9 ^# [        }( |& A0 E% z- s9 \/ L; V8 Z
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
- u' X+ y# d* t5 v% ]                ret = exqueue.data[exqueue.rdptr];, ^+ @/ K6 W( d4 g4 A
                exqueue.rdptr++;
- t, F: L* _6 t. p2 q                exqueue.rdptr&=QUEUE_LENGTH-1;* Y" M. L% k6 i+ S" X
                return        TRUE;  P+ t, X0 _' y
        }
7 I  t9 S. M! A        return        FALSE;
" [: }! R  T4 x8 X$ o) a9 z9 L}
+ e- J3 F' e2 f2 }( ]" D0 f2 r' U* W& s2 v6 R8 U
void        APU::QueueClear()7 T& ^+ F6 l$ C# X
{" u9 D4 \8 ~) F7 V6 a6 \
        ZEROMEMORY( &queue, sizeof(queue) );( }. P9 r7 b& r5 o
        ZEROMEMORY( &exqueue, sizeof(exqueue) );& k- c& x) [8 W# Y
}
7 S  F" O# f6 y2 S7 J
9 |7 E# B& |" K  ovoid        APU::QueueFlush()
3 n; m/ S: e7 F( }{) ?( l" H7 V" i/ }* N- s1 l
        while( queue.wrptr != queue.rdptr ) {1 H9 ]' i* }: l# j5 X' P
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );. P1 R  W& \% r8 X- P) }
                queue.rdptr++;
/ w5 i9 g/ `; U. \9 m                queue.rdptr&=QUEUE_LENGTH-1;
5 S, a1 ]# _& W& R        }% I8 W* X# f' {. j6 b# d

: x' S( ?1 Q# p# I/ @        while( exqueue.wrptr != exqueue.rdptr ) {( _0 ^/ Z! g( W* W" E
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
% H. b+ d/ m& W9 J                exqueue.rdptr++;
4 Q" o) B1 v1 r$ I8 _                exqueue.rdptr&=QUEUE_LENGTH-1;0 f; k" o. ~: T+ v8 Q8 C; u
        }/ X& e7 R# V5 ?6 u
}0 C0 t5 v  j: m  ^0 E% r

% i/ }2 _. L) ?2 Z0 `void        APU::SoundSetup()+ i$ m# ?3 W3 T9 m% e
{" t6 D7 R8 R* d% P  m1 j% _4 n$ V
        FLOAT        fClock = nes->nescfg->CpuClock;" M  @8 H( {; C8 T8 b7 s# o
        INT        nRate = (INT)Config.sound.nRate;
1 M$ N+ c' z4 O' B- d' x4 N        internal.Setup( fClock, nRate );% @5 n- Y( X6 R. P" B2 W, Y
        vrc6.Setup( fClock, nRate );
" `& y$ k4 i; Y% q        vrc7.Setup( fClock, nRate );
2 p& U5 X7 I/ z4 D# H5 Y; f$ C        mmc5.Setup( fClock, nRate );
9 g& o9 F, C0 ]) w7 |' _6 R, m        fds.Setup ( fClock, nRate );
1 R6 @" J0 ?3 z  C7 l: k        n106.Setup( fClock, nRate );+ a) k$ P0 ]  P' y$ u4 L
        fme7.Setup( fClock, nRate );
; e. z$ J  n$ c- N0 j" q5 i}
" [! h* |3 V. S5 B1 q3 ]# K& d! S' ~6 h9 ^% P7 z/ _$ z% z# l* o
void        APU::Reset()
2 I& S/ E! M$ x/ F7 [{7 R( S% x$ x0 |* K& j
        ZEROMEMORY( &queue, sizeof(queue) );6 W2 }1 L; r; ~
        ZEROMEMORY( &exqueue, sizeof(exqueue) );( k% M4 k  l5 b. |. T" `- ~$ z

8 M3 f! a. W# C        elapsed_time = 0;% m5 y9 c8 t6 x3 _1 V7 `+ H( i
. i5 H# v; L' [8 L# D
        FLOAT        fClock = nes->nescfg->CpuClock;; c; V2 ^& t' d8 H- _
        INT        nRate = (INT)Config.sound.nRate;
" o  m6 L$ k9 |$ H! M6 P' c6 m        internal.Reset( fClock, nRate );2 S2 r: J5 j- X' x/ w/ k; d( w
        vrc6.Reset( fClock, nRate );& n# @2 [: o' [' j5 T
        vrc7.Reset( fClock, nRate );( u# U% @8 y% K0 p& e
        mmc5.Reset( fClock, nRate );
9 a' b; G9 V: ?: Q. ^        fds.Reset ( fClock, nRate );3 |. _# J. `, W1 n, l$ l4 O
        n106.Reset( fClock, nRate );! S/ w! M: S( O. x  C
        fme7.Reset( fClock, nRate );
# E2 P" w" h( T* `6 F: l. A! W+ ^, n
+ o  z8 X! G) a2 e4 m* ?6 y: w        SoundSetup();
+ q' V7 O: \7 Z- r}
2 J) w( o- j' S8 O5 d" H- b
5 u/ z, O- x: y/ v" ?( k- ], pvoid        APU::SelectExSound( BYTE data )
4 v0 E+ ?3 _5 R% [& @2 @6 o+ e! P! E{
- b3 T2 w$ e2 h        exsound_select = data;
% }4 k7 h8 D  f" E7 E! v4 Z  i/ w2 y3 d}
" x( Q$ i! L/ e, ~, l2 H  g0 `% ]% B1 [  d1 {2 k; j
BYTE        APU::Read( WORD addr )
! }/ l( N* g% j/ q( c6 z6 |{
1 C) ]9 I% b: |& b3 E$ [        return        internal.SyncRead( addr );5 F' X7 g5 R5 M7 L
}
/ [6 t4 B! j6 m; c! `" y; @# g; j8 T% s+ F7 S. m7 e  [
void        APU::Write( WORD addr, BYTE data )% E4 _+ o# _) Y- G2 N
{( i9 @6 s$ \% B. `
        // $4018偼VirtuaNES屌桳億乕僩
7 z2 b# q9 M1 f+ t        if( addr >= 0x4000 && addr <= 0x401F ) {
. v$ B8 v1 P- w$ }+ h                internal.SyncWrite( addr, data );' m" A! a: g0 J% [8 e. W
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
& A) {' L! F5 J# F& Q( j        }4 F8 {6 |. Z& b! b$ x
}# E2 ~! P! J: K. c* X, G( {* M5 D) m

) I- j6 f3 X+ Q/ f3 I$ H5 vBYTE        APU::ExRead( WORD addr )+ w$ Q! R3 d+ _% i  d* b
{
: P9 w6 D+ C/ M$ S- l7 }BYTE        data = 0;
2 P: v7 Z) d! @+ i9 H' g/ m( Y' L2 c8 Q$ G" W( q% l
        if( exsound_select & 0x10 ) {: R3 l' R: @4 ^* Z& m
                if( addr == 0x4800 ) {
$ t5 |7 S8 @9 u; w& b; B                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );, p* O' C) e# l" N6 v
                }& N9 V7 m' y  z
        }
  f" D% m2 C; Q0 F        if( exsound_select & 0x04 ) {
4 X8 F4 d0 }3 F# O3 Y2 I& I                if( addr >= 0x4040 && addr < 0x4100 ) {$ |1 K: q5 E9 K( q
                        data = fds.SyncRead( addr );! i, ^; j1 b9 a6 `
                }
7 P2 \/ A2 }6 M4 W; W) ^1 g2 n        }. {0 p" r0 h6 U
        if( exsound_select & 0x08 ) {
1 r+ F/ H; J% B2 b, C                if( addr >= 0x5000 && addr <= 0x5015 ) {
6 f6 R2 l0 T7 R: h: y% ~& M                        data = mmc5.SyncRead( addr );% Q2 j* R4 M- \
                }  n5 _( O& Q+ X! L
        }
# `/ I' u% P) W: \, j2 H: Y
6 u: b1 _% i; _& A        return        data;4 T: O8 \9 q2 o4 }+ b. I" n2 }7 }+ T
}. r4 l1 V# t, e, o; z
3 n; V: f6 m% C$ c4 }
void        APU::ExWrite( WORD addr, BYTE data )
& \2 w/ [& S$ v- \* x{
4 c. R) w8 S" \' _! @8 ]- Q" t        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
2 O2 ^  W8 X$ V% W9 Z' F0 f5 z0 L: l
        if( exsound_select & 0x04 ) {' E& O' y  I" q
                if( addr >= 0x4040 && addr < 0x4100 ) {
& c3 }* I5 y) |. @5 z5 f                        fds.SyncWrite( addr, data );" F+ H  q2 @1 P5 ~" x
                }  J- u! _9 P! b) D
        }
# z% |0 |4 I9 N9 {% A# E. q! a5 F1 `+ t+ @& }( @: L
        if( exsound_select & 0x08 ) {
  M$ M/ D; k- z9 \; q3 S5 M+ a( @                if( addr >= 0x5000 && addr <= 0x5015 ) {
+ b3 G7 I! t( F% s                        mmc5.SyncWrite( addr, data );
7 ^/ F8 @& s3 T- s$ c% D7 p                }/ p  O# {4 Q$ G8 |) W0 r3 S' n
        }! z  O+ _# v+ B1 R  _
}
' ^" y* c6 W# b' K- |7 m$ A" k: |) i5 q1 ~* C2 z
void        APU::Sync()
4 F& j' ?7 Q7 G* U8 j8 K+ u4 I{
% ~! l9 E- m$ p. |! ~4 F' _}
$ L: e  {$ k* _+ q" ^) r! H6 \& K
void        APU::SyncDPCM( INT cycles )
/ I* {2 e6 q6 H$ j( X# n{
6 ~( A9 [9 z/ N+ G5 w1 [        internal.Sync( cycles );
3 y' n. W' j7 j$ o! d" |3 e" e/ {! R
( P2 a, m: P& r        if( exsound_select & 0x04 ) {
8 K! J6 B+ o% T% j! @                fds.Sync( cycles );
8 S# M. x8 A  i1 l' b4 ]& N        }& a. [" a9 r8 V( o# h& d% X
        if( exsound_select & 0x08 ) {& G, C2 s7 h; \4 L  }/ A
                mmc5.Sync( cycles );
/ ]+ O& v$ h' a, n        }
, H1 \" a/ z- {: y}6 {. K) J; b+ W+ K* U3 i% K! E
& c$ Q# [! i! v+ t' E
void        APU::WriteProcess( WORD addr, BYTE data ), R# x7 s' Q( P$ y4 i1 A
{( q- i; ^9 M. ?9 D& m; I1 Q* Q
        // $4018偼VirtuaNES屌桳億乕僩+ o! `# W, `4 B( ~% I: y
        if( addr >= 0x4000 && addr <= 0x401F ) {
/ b- B! ?, z2 E& L# P                internal.Write( addr, data );$ o4 C. V# N6 |. M9 W; y8 v% C
        }
6 ~3 S1 S: a9 @, l7 h}
! s' @( O& ]" K+ q1 J0 V# b: Q* l2 o7 p% U$ T
void        APU::WriteExProcess( WORD addr, BYTE data )
- \7 |' d6 x3 P# U: `: ~1 O{
: T4 g6 k" j" E; H$ n2 A% z, i        if( exsound_select & 0x01 ) {
% C) i- U- x- m. ^5 r$ `6 _  I                vrc6.Write( addr, data );
) n7 k5 [' W9 J+ }8 A* ^- k9 Z        }
9 Q( R9 N7 s$ J$ u# v        if( exsound_select & 0x02 ) {
5 c( f5 \% e: b/ \1 v                vrc7.Write( addr, data );, G$ o  `  L, S3 v$ H' o
        }
0 Q4 n. \& z& B0 _        if( exsound_select & 0x04 ) {
. Z5 d3 l6 b9 o; H" ~8 ^                fds.Write( addr, data );" ?/ q  Z0 z! q" P- f
        }
1 V. I# J0 [7 e! @; J        if( exsound_select & 0x08 ) {2 I. ?( @# L+ g% w% V+ i* f
                mmc5.Write( addr, data );
$ C5 P% s, ^2 o7 g2 P( k        }6 E4 [4 z! L3 k
        if( exsound_select & 0x10 ) {- i! |8 |& D8 P# f" U) v+ D+ B
                if( addr == 0x0000 ) {
4 x, G9 E/ h6 J3 E6 P                        BYTE        dummy = n106.Read( addr );* {- O& R, s( ]/ U/ T
                } else {
6 n1 [7 z3 c+ N2 [                        n106.Write( addr, data );$ S, Z# a; I- d0 K
                }; j9 g) V9 M9 C& @0 o* ~
        }3 L6 g! A$ m( W+ j& m
        if( exsound_select & 0x20 ) {9 q$ U4 ~1 q* C/ I
                fme7.Write( addr, data );
7 J* O( s- U, }" Q, f' O        }. C. l4 ^; {5 Q1 z
}
0 D; c. U" s" Q0 t4 h# ~& k/ E4 K' p/ u9 h
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
0 f" T8 g/ O6 \/ p{$ ~# p! [$ j$ p, ?" {- r3 y
INT        nBits = Config.sound.nBits;, S  k( G) o- s; Q& X! |0 v
DWORD        dwLength = dwSize / (nBits/8);1 K# x: ?. S5 L! m7 V& m
INT        output;
; b1 C: q5 R% q- r7 l4 d. w9 ~( JQUEUEDATA q;/ @" V* G5 q* ~6 s9 ^5 g" M1 m
DWORD        writetime;
8 ]- l! N* [' N4 U
/ }- r( q2 J7 T) a7 G6 Y& k5 kLPSHORT        pSoundBuf = m_SoundBuffer;
4 R$ Z9 n8 g$ }5 }* e' mINT        nCcount = 0;8 V5 G9 w& ?9 G$ J, D4 U# f

, Y% F, O/ e: R$ Y- n# t  I4 w5 uINT        nFilterType = Config.sound.nFilterType;
5 m" f. o5 Q& v2 I% S
/ D  M- Z# ]1 C. d        if( !Config.sound.bEnable ) {
: F" a1 m% L# p- w  ]! e                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );; K  G8 J+ {2 W/ G1 ^  G/ q
                return;
5 `- C; O% N7 I. X        }
5 H0 g$ m" n1 ?0 A* _
$ P, ]1 Q2 B, C3 ~3 m9 y        // Volume setup6 w- [9 \/ u3 H& h) M# Y
        //  0:Master
7 f' g! R. N# G; T" D% q6 w4 M  m7 ?        //  1:Rectangle 15 f8 M7 S$ P1 @, J
        //  2:Rectangle 2
& w0 B7 f/ a$ r& Z" r- Q4 W. P3 w  |8 e        //  3:Triangle
6 \3 _, w4 C3 ?: r2 U, V1 F1 O( o        //  4:Noise
9 e* x! L" [& D$ T, \: I3 o9 n        //  5:DPCM" s: o" N. ?8 k
        //  6:VRC6- F* G' y$ V; a( w1 D! S
        //  7:VRC7
( D5 R( d' V6 D  U7 Z, A7 C        //  8:FDS
' W, q% |5 J9 [6 W$ ?$ ]& W( v        //  9:MMC5
. D! ?* t! S/ k2 c5 W: w        // 10:N1062 W! q% l+ E) V! m9 q  N' [+ e! h
        // 11:FME7
7 N9 D/ S! M+ U) `6 ^9 g        INT        vol[24];
5 `$ g- C& u- ~; _: T" D/ o# a        BOOL*        bMute = m_bMute;
3 i& j" j; e+ t0 A/ C1 N! t        SHORT*        nVolume = Config.sound.nVolume;& C1 m. G' A6 m& F- i

9 ?, W: s' x5 c% S0 I+ A0 D( B        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
  Q- e5 h& S* L3 o; U, P
; k3 d7 y( J8 n4 ?3 o# L        // Internal
; x" T/ Q$ l# C4 X        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;. n1 j6 k# G) K" q2 o" |
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
8 R# C. R; C7 W) ~$ I        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;0 F: q& w% t3 V( [/ u
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
$ ~* L/ M! G; r) @8 q        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
" j* V9 y; l0 B% j/ v
3 y7 x% F- b( b        // VRC62 _5 {8 b- ~+ I$ X* b3 V
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
/ `) p4 O/ V; e4 d9 P( p        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;, F& A1 U2 f) H* L" _( T
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;; [% f8 V1 B9 r, S& U* l
3 n) R5 p6 N5 n# b) Q% w
        // VRC79 U4 i8 u0 D$ p
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;1 q+ y- l  B2 ^* n! J. d% k2 D3 w
* M2 k' \$ f) E% \$ Z6 i
        // FDS. _3 M- }& b" U8 Y4 R: N' v
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
1 m# w8 T* [& o& n( u1 h8 G7 m2 e
; {# M. r3 @* `2 H: c. v        // MMC5! o, B# a1 ?0 A
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
3 {' A/ F$ {$ R1 }: _5 T9 z6 R        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
  m; h5 y; F1 g) o        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
9 z* W, m# ~1 C- L1 S
; }% p  R. }  Q        // N106
' t0 t* L3 C9 q( \) k0 ]! x7 ~- c7 C% I        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 r) ?+ Z# Z1 H% k# F3 M        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ \* v( ?9 n4 t6 v, i
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
) o& {# {7 p0 l3 ^$ _. Z% Z& Q* V) O' S0 c        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 k8 B4 U# }* q* ^8 T+ H
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;0 c7 r; a: Q- @
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;" Q# M9 L9 D$ p( q
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- a/ ]; |5 \/ j* b
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;. I! B& `  d; c
" t! B, o8 s. X6 n0 n
        // FME7" G2 M' B9 y) e
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;0 v8 f8 T5 O8 p% n: ~' L- L
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;7 g* i3 X* r9 }7 i
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
& ?3 _5 `3 H3 ~7 v% R$ }  q
3 Z+ [, m1 [& U6 u" D5 e//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;: s& J2 |9 h* {
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;. P8 c; L. ^6 a( s% b
6 f, S' a2 `0 A( q* x
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟6 C+ K- Q* ^* @7 k, |
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
6 i4 V  z- b6 b2 H0 ?. w                QueueFlush();
; K7 ]* X4 \3 z7 c/ `; Y  E2 V        }
5 [0 H- x9 g0 w6 G' s' c- ]9 B2 r  r
        while( dwLength-- ) {* ~0 O& E5 f, A. p
                writetime = (DWORD)elapsed_time;/ C( n' s  s' ]; i8 A) V, c/ i2 a
/ W4 }. W  T! j# L9 T: t
                while( GetQueue( writetime, q ) ) {. K( H' w9 _: q
                        WriteProcess( q.addr, q.data );
* |) }; t! f( T! b5 m$ ?                }0 K- {9 d5 ^; q  V6 z

' x- Q3 {2 ^- k5 {$ P$ ?2 O                while( GetExQueue( writetime, q ) ) {# b1 g) c3 _) u8 _; t3 `
                        WriteExProcess( q.addr, q.data );
7 ]- t# ]+ @* K) X+ R                }
/ O) X7 w" K7 a% Z. J: G  \" [* t  M6 h$ q0 T5 a
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
1 G3 l/ Q: a! l6 y: s9 x" A                output = 0;) F3 m* A) P8 R0 V" s
                output += internal.Process( 0 )*vol[0];$ T! q: v% U  d/ O% Y
                output += internal.Process( 1 )*vol[1];
" O9 a* q+ F  Y% C/ `6 }* ~                output += internal.Process( 2 )*vol[2];
9 Y' r% J3 [) G: T1 o: R9 E- _                output += internal.Process( 3 )*vol[3];* d4 E! s" W( H1 [% j! m& S& s
                output += internal.Process( 4 )*vol[4];
- r' z7 G5 S+ @# W
4 o' E. W4 Q$ }7 }- S; }; Y                if( exsound_select & 0x01 ) {
$ S& |2 L6 R: |% X" f" n                        output += vrc6.Process( 0 )*vol[5];. W+ M$ V6 G! P+ d3 h/ ~9 _: u
                        output += vrc6.Process( 1 )*vol[6];
+ S- }7 Q6 f# ]) x                        output += vrc6.Process( 2 )*vol[7];, i+ p2 f# ~6 ~( ]
                }. X' ]# X1 q2 K
                if( exsound_select & 0x02 ) {
- E; E) I$ S+ T3 @                        output += vrc7.Process( 0 )*vol[8];9 d. Y. e% l- ~
                }. W& C6 J  Q- I
                if( exsound_select & 0x04 ) {$ D1 }6 Y* h/ ?5 ~2 o" P
                        output += fds.Process( 0 )*vol[9];& [8 Z3 o, h$ p, E! K
                }9 g) }  T, i6 _  x$ N
                if( exsound_select & 0x08 ) {
" T* N& V! P5 Q3 T  b; F7 `7 q$ R2 i                        output += mmc5.Process( 0 )*vol[10];. Q/ U0 I) \6 t, X
                        output += mmc5.Process( 1 )*vol[11];# O2 }( i: ?2 V* f
                        output += mmc5.Process( 2 )*vol[12];
- I' @3 P4 ~8 P# c* a. ?7 ]) A0 J6 L                }
; T) N8 `" Q$ W6 [/ n- a7 Z' y                if( exsound_select & 0x10 ) {
/ [* B# \5 v  z7 S                        output += n106.Process( 0 )*vol[13];, |( @" z% O- ]4 p$ O
                        output += n106.Process( 1 )*vol[14];
6 G6 Z5 ^& M+ F1 W3 `+ G                        output += n106.Process( 2 )*vol[15];
# }5 V7 V* w. _6 s                        output += n106.Process( 3 )*vol[16];9 v! C  y* o$ V9 ^, z) n
                        output += n106.Process( 4 )*vol[17];1 ?+ p0 c8 _: E
                        output += n106.Process( 5 )*vol[18];
4 V4 }  c0 v5 k- L                        output += n106.Process( 6 )*vol[19];
8 @$ x6 h6 I3 C  E                        output += n106.Process( 7 )*vol[20];
+ k& b) F8 H8 u3 S3 j9 X# h                }
: L/ t; \5 y8 |7 D0 d5 `                if( exsound_select & 0x20 ) {1 B: G7 O6 R$ J
                        fme7.Process( 3 );        // Envelope & Noise
6 ^/ g$ R( `9 Y                        output += fme7.Process( 0 )*vol[21];. c! \1 W2 S6 z5 q* n) e
                        output += fme7.Process( 1 )*vol[22];) }* y8 V6 d. R
                        output += fme7.Process( 2 )*vol[23];
; a; k4 Y4 h) K" i. F# {* e' M                }$ o1 @5 C1 j7 x7 c
! U' v6 G2 p7 C
                output >>= 8;6 s0 ^' p" L$ p. Z4 ~% @

. ?+ T, Y* J/ z1 K                if( nFilterType == 1 ) {
/ w/ ^; r7 U, V                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)- u5 D0 \) K( p) W% p% {
                        output = (lowpass_filter[0]+output)/2;1 R2 ?; V5 H6 h9 z
                        lowpass_filter[0] = output;1 b. D3 e) M6 ~( D
                } else if( nFilterType == 2 ) {
, e) G9 O( f# ], k5 {, D* \/ Z* P                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)3 Y9 y' E5 _+ [/ D- L, M8 ]$ {
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
* T3 Q- B4 w8 c8 k                        lowpass_filter[1] = lowpass_filter[0];
3 H. E# E; U  \+ o7 |8 s* @4 d. U: S: k" P                        lowpass_filter[0] = output;3 W! T  x( a7 c7 G  {
                } else if( nFilterType == 3 ) {7 Y2 w1 O4 I6 A
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
( w3 a2 ?- p. T2 p9 q                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
( v, j; x0 Z; Y) I                        lowpass_filter[2] = lowpass_filter[1];
+ @5 E! s9 S( P( E6 ^, Q                        lowpass_filter[1] = lowpass_filter[0];2 h8 _. A6 G' p8 H
                        lowpass_filter[0] = output;  Y# c% u& w7 z! x9 p
                } else if( nFilterType == 4 ) {
8 z0 ?9 b5 e7 Y' m! U) Y. z                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)9 V" Q5 K" X  L. M
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
0 `; e( [$ W4 |0 s                        lowpass_filter[1] = lowpass_filter[0];
/ b: }2 Z3 `  p2 V6 r; `3 E                        lowpass_filter[0] = output;/ l' L9 r" e# @. U
                }
; D. e3 }+ V* u4 y# {4 |, _1 I
- D" _" w& w7 w  ^9 ]5 d6 }% @9 B#if        0
  [$ a7 ~" G9 V, [" w                // DC惉暘偺僇僢僩
" k( F& _. _1 |; D# i. b                {+ r0 x; p8 x* Y" ]) k
                static double ave = 0.0, max=0.0, min=0.0;
3 ]7 ^4 \  S. N% R) c3 `$ ?                double delta;
& D. |% Y+ i+ r- H                delta = (max-min)/32768.0;& l, s' X$ f6 q
                max -= delta;
8 V7 ]  R1 k4 J' ~                min += delta;, R7 C+ Q3 d" m5 A! r4 g" X" @
                if( output > max ) max = output;1 N1 c6 `9 N9 M, u7 c% g7 ?: }$ u
                if( output < min ) min = output;
( I( j1 J( _% J$ R8 h; b                ave -= ave/1024.0;
: H  H/ ?6 v& ^; h$ F' O# V                ave += (max+min)/2048.0;
8 F& `8 i: K- K  n                output -= (INT)ave;7 {! Q. |7 I7 ^! A! ]
                }6 Z9 O) r' }' i9 _5 p7 p
#endif% a  t0 Z5 X' X/ P- b* _' l8 [
#if        1
( W" q  b: S0 v! v. f0 U                // DC惉暘偺僇僢僩(HPF TEST)
8 Q3 O1 A7 f# P5 r/ D                {9 t9 C! _+ U5 ^4 z
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);% q! s$ ?% \: L1 V: ~; N$ K0 p
                static        double        cutofftemp = (2.0*3.141592653579*40.0);. h! C8 ^) ^* m& g" Q( P+ a  w0 ?
                double        cutoff = cutofftemp/(double)Config.sound.nRate;; C0 J: m' t4 b/ q5 C
                static        double        tmp = 0.0;
; }* q) X5 n/ ~7 [                double        in, out;
9 A1 z) l/ z2 z% H
. i. n# C' N$ T8 S8 u  Q$ o9 W                in = (double)output;
" K4 m. |% n; u3 c8 D4 O                out = (in - tmp);- M3 r1 A4 z4 X- k- ~/ j& C* o
                tmp = tmp + cutoff * out;2 ^5 j1 J' @$ K" T; N0 `

% t% w6 K- v% y  d9 A. j* k                output = (INT)out;1 A$ N, L0 m9 H+ n* G( ~
                }
& X" M8 Q7 ~- n1 {  S#endif
* l3 \6 ^8 m6 q: t3 i5 G* O#if        0
2 n! T; a! C5 x0 b' @, v+ F) x                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)/ M, z  ~) P7 S% A# L* O
                {
# k) }, z9 V; k0 _                INT        diff = abs(output-last_data);; \% P, z7 U1 A* X4 k, L
                if( diff > 0x4000 ) {* `7 y" J$ N7 z! \% c8 J
                        output /= 4;; f' Y$ r) q: x% m
                } else
5 [. c4 }# U4 a# Y1 P9 y                if( diff > 0x3000 ) {- j! v# @- V7 B4 v0 ~5 _( x
                        output /= 3;
4 y! {0 E3 }& N! E7 s) L                } else0 }9 b" {5 G  ?& m$ M% a5 n2 H
                if( diff > 0x2000 ) {, F7 _0 L) Y3 Q; u9 s
                        output /= 2;# f5 T, l+ ~; Z  j' K1 A% `. p
                }# r  Q; G( R- W! q% ~( b( n  g- ?7 ]
                last_data = output;. K' w9 C# j" Y0 d4 h( u
                }* m$ d+ E/ B4 O3 F3 ]
#endif7 |+ C% `6 r5 p( @9 \4 {
                // Limit
; e$ ]" p) y4 Y                if( output > 0x7FFF ) {, j" v- _# Z( |
                        output = 0x7FFF;
  i5 c2 ?2 N% K) N7 H; y                } else if( output < -0x8000 ) {" \  E& e- w3 |5 d0 M3 {
                        output = -0x8000;
7 j; P& _( n* P' Z7 B: U; E                }
9 a* j' z% |/ N: q3 `( Z2 y% ]* h7 k# A; _
                if( nBits != 8 ) {
! d( {# }( E# y! J                        *(SHORT*)lpBuffer = (SHORT)output;
$ j1 U5 Y( @: M                        lpBuffer += sizeof(SHORT);9 M3 V* l* {/ r- R1 \
                } else {
. k: k/ ^/ L) `$ X* G                        *lpBuffer++ = (output>>8)^0x80;
2 U& [* O! m- v6 d* p                }4 b& |0 K% j% o& |* i' N7 |

1 V6 D: q% Y* V9 \- G# R0 ^  }                if( nCcount < 0x0100 )
6 C. j7 |+ d. @3 {6 Z7 U                        pSoundBuf[nCcount++] = (SHORT)output;
, Y5 [: g8 }2 ]. l  R/ o8 n0 Z1 ]4 H3 z8 K5 N3 t/ C
//                elapsedtime += cycle_rate;* q/ l/ E7 J4 x9 k
                elapsed_time += cycle_rate;
" f! z( r9 `: l: K) R        }6 E) p4 o. N9 ^! j

3 R2 O" X- f1 n#if        1
" G7 k3 f& Z7 }1 r' K) q        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {4 H. v) m3 f8 p$ G; y- J# K
                elapsed_time = nes->cpu->GetTotalCycles();# K: L' x& _  ^
        }
( `- N+ Y) b5 q+ ~+ s; \        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
: F5 N. d" L9 z* m7 ^+ {& W                elapsed_time = nes->cpu->GetTotalCycles();
  i, ?! C0 w6 ]2 [" S- I% U        }. \4 V  b; {# G& a: G
#else
* z. X( v4 J( V  P2 b6 s! d  p/ b        elapsed_time = nes->cpu->GetTotalCycles();
0 }; T% c% b+ h  j  ~#endif
4 K9 c6 p" Q4 i7 E) g}
; m/ v$ `9 o& z% c
7 k! y. L" A# B// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
2 S! a8 M, R. X0 _; `INT        APU::GetChannelFrequency( INT no )9 u  c# b/ S- S7 d* X
{- o0 F) m( e/ ^; E* v
        if( !m_bMute[0] )
  o7 }' N0 I5 X% k6 ]& [5 F                return        0;
* N# `* |$ G7 T7 f. a2 o  j. k6 e2 x2 h2 @
        // Internal
, f1 u% _, ^$ K6 t# A        if( no < 5 ) {
) E; x4 o! K& {! \' I/ m! A* S                return        m_bMute[no+1]?internal.GetFreq( no ):0;. \- Q, p: B& f3 f
        }" V9 z. g+ }. p7 J( k
        // VRC6
; e, `! l4 t3 s        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {: r. O$ U  O3 D/ R0 V6 @" f
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;7 K1 g' b/ k+ J
        }) s, G! c( ]8 a& {! E
        // FDS
( g/ v5 u% l9 |/ z5 }( Q/ t$ s        if( (exsound_select & 0x04) && no == 0x300 ) {
! g% E; _# i2 E4 _* ?                return        m_bMute[6]?fds.GetFreq( 0 ):0;% I5 G' _0 K4 Y# P5 ~5 h6 y
        }
9 Y( n) z3 ]8 G7 I1 d        // MMC5
+ B/ W' Y: |7 H* g6 j2 d& H        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {( E" m! V4 q9 `2 V
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;2 B7 d7 p% F6 n+ y
        }+ ?: k4 k0 R4 A7 d3 _7 u
        // N106
+ x9 n4 A- B7 n7 ]        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
3 t0 a0 @9 J3 v, u' L8 f                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
3 b3 ~6 ]/ R, {& y7 z3 X# _/ j$ D        }
1 q0 I5 {$ U1 n3 z1 E        // FME7; A$ b7 G9 u) ~- r5 \8 f
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
6 J4 B& i, T9 L  u0 F( S9 Q( b, z                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
8 I& S! {! y+ s; l, T7 ~        }
1 M$ h+ R9 M1 w0 u' B$ A8 b/ f- [        // VRC78 M( j8 D. m1 X
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {* Y* H, y" z7 E3 y
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
0 g% D9 k- M+ w& ~! j* N        }8 r5 Z( B" u4 ]  y' @# u) Z
        return        0;
/ M& c; f. Z1 m) D3 Y3 l! U}, F- Z& H6 t+ P/ g5 ]

- v1 D* S4 y  Q. R- f5 c0 o// State Save/Load/ t8 c% c  I" F
void        APU::SaveState( LPBYTE p )5 d( q; b9 w* b; J
{' R# u& \- w9 Z) T4 M
#ifdef        _DEBUG
3 D1 N, I( M, ?7 RLPBYTE        pold = p;
' I& z7 K% M2 Z: X4 ]#endif& u/ M9 ~$ X. j7 K. v; O

; ~: ]( a% ?1 `4 Z6 ~        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
9 @# }" u8 c3 z  p4 d        QueueFlush();
5 L7 s  g" c+ W) E
8 x1 Y: Y3 J9 R# }* o        internal.SaveState( p );
% i' V0 L0 ^+ V5 o' L        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
& X: g. ?5 n0 F( V1 V: y" T5 ^
2 L% G( C" I, ~' P! c, ^        // VRC6- V7 f: B1 c: T; i) m- b3 U8 G
        if( exsound_select & 0x01 ) {  g: n( \, P5 F- I+ L% U0 V
                vrc6.SaveState( p );7 P# P) o1 k2 `1 s0 v! @
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding* x) z, `  H* N& @' m' P. C
        }
1 Y3 U- U, ]6 n; h        // VRC7 (not support)
* d+ G7 ?/ G* ^6 e8 v* }5 \        if( exsound_select & 0x02 ) {4 [" T0 ~1 c, W  a0 z0 D+ x
                vrc7.SaveState( p );
) G* g4 ?, V4 F# T: {3 [                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding: t. l  _" z3 g3 L2 p
        }9 j3 w. W- D6 `0 `% @" S$ g
        // FDS5 L7 ]9 w2 K6 q5 M; F$ ^9 K8 ~
        if( exsound_select & 0x04 ) {* }! g8 p( W5 C
                fds.SaveState( p );
4 p& i7 V$ }5 Z8 m# N                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
% N) Q% e7 T# ?# x# P5 S        }
$ X% n) ?! t( S1 X        // MMC5
6 X/ Y! N4 c3 C        if( exsound_select & 0x08 ) {- U& q. H4 U+ ]" _* [. [( }
                mmc5.SaveState( p );
2 v7 d2 o! w4 }1 W                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
+ A% O  f& ]) r- D( [: N        }
! c& B& o4 G. C+ z( i        // N1068 Q* q' C" y9 @& m( y! E; _
        if( exsound_select & 0x10 ) {
6 L( r$ x( g4 v( E( |( o2 Q$ j2 r                n106.SaveState( p );6 ]4 y1 m" u2 r" @& }
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding9 G% W: o4 [7 s1 i- l3 b
        }
" I! c5 N2 t! {# b5 V        // FME74 P, Z$ z* V% m! u5 o2 W
        if( exsound_select & 0x20 ) {& ^1 w2 y- q4 C& G- |0 ~' ]
                fme7.SaveState( p );) r, N7 N" L8 r, C6 x0 J3 f: r" M3 s
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding  V% k8 e+ T/ O! k/ B& C& I
        }- z" q  A8 f0 Z% f, K
( W& y* `$ \* V7 L) s  ^
#ifdef        _DEBUG
. v4 b. s/ s% M% j4 BDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );: z0 {- r- B6 |% a$ T1 s
#endif
* ?  @2 u% N2 |( f}& n* _$ Y" J( d+ j

2 g4 f3 M, U4 p  l/ L5 l' v6 L9 ivoid        APU::LoadState( LPBYTE p )' d. J+ V" a+ @+ d4 D2 ?
{4 D' h* a( o: J4 d' M, M- H1 Z: x
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
4 J- j5 S3 T+ i& P# F        QueueClear();
  |( e5 i5 M3 V$ v! `" a
( B6 K0 t  Z9 o7 V" z  S: {" N# @        internal.LoadState( p );" l6 q( q6 w6 N
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
7 k) `. D/ G  d: e  b( y: e& C: ^& s7 U& M) @! a) y
        // VRC6" r& t, b; V7 ~# @" ]; f" a1 d
        if( exsound_select & 0x01 ) {1 j7 k; ~$ ~0 Q% g% E2 J
                vrc6.LoadState( p );. y. u" ?) y1 u
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding6 r& [7 [: r4 {8 ]4 \( g. |* T
        }  r+ ?6 k/ b- H% V. \( {% M
        // VRC7 (not support)
, u# I: C) Z% z) m# r# z. _        if( exsound_select & 0x02 ) {* ^8 @  K9 m& S0 k0 F% p
                vrc7.LoadState( p );9 H( [2 ]- i2 w  @
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
1 Y6 ?* e* f8 r  E# t        }
* S# I2 J) ?, |8 h* C        // FDS: z2 v; y2 E3 Q6 }$ F8 B5 e$ {) w
        if( exsound_select & 0x04 ) {: k6 j6 M: }# b+ ]
                fds.LoadState( p );  l7 C; h# P8 J1 _, l
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
) r$ O5 x8 ?: m7 y, `        }& S9 Q2 N7 |8 L- q- `
        // MMC5; X; I9 y" Q" m5 f
        if( exsound_select & 0x08 ) {
# u. h0 ]5 e! v' T7 K& g- E                mmc5.LoadState( p );
$ F9 Q0 X' k0 L- V& o7 z                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
, o" B8 K. h5 U6 E% D        }
( o3 `, _* q  h+ }. S+ M        // N106
. Y$ s. X9 g% D# R9 M5 i        if( exsound_select & 0x10 ) {
3 i' `+ b+ ]0 p. G- f, t% a                n106.LoadState( p );# v8 i4 q$ \3 T% M
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
; H5 |7 Y3 d( g! |% \4 _* z        }8 @: ~2 c) g9 c4 ?8 @6 S
        // FME7
. P2 l1 U& m# H' m        if( exsound_select & 0x20 ) {5 K7 k- M, b- q( q! ^3 H: z) k
                fme7.LoadState( p );* J; f+ o- o) o, W6 q) S& f0 v) {
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
; ]) H3 K7 ]% C0 h7 h, s9 q        }
3 D, G# Z( |# h( T}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
6 |! U. d; ], B, V+ J$ x. {5 P可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。  o$ z* E( l6 [/ f$ c1 ^) o2 z
感激不尽~~

! Z( F5 g: E& N1 z/ f$ k8 W" J/ z' B恩 我對模擬器不是很有研究,) m) v# q+ h, p; |# z5 a. `% _
雖然要了解源碼內容,可能不是很困難,
) O! U8 Y6 s- a2 E; `不過還是要花時間,個人目前蠻忙碌的。
7 `  X' h) a! O1 I. ]
( C. @  n( U3 t9 b給你一個朋友的MSN,你可以跟他討論看看,
! n7 I% F  u  Q1 H* `) l& Z6 V他本身是程式設計師,也對FC模擬器很有興趣。( P$ I% R) k. A3 m8 ]( D% E% e% z
& a& ~3 n% w* j1 S! w; `
MSN我就PM到你的信箱了。8 p6 v1 ~  M8 }& l1 I

. Q1 f9 e) S- M5 Y, \希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
8 i# `2 Y+ H" q* ]7 ]呵…… 谢过团长大人~~
& L. F& s4 }. @. A
0 {# I1 L% Q) H: b
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 2 O) s" b$ G$ D" M+ D' M
团长的朋友都是神,那团长就是神的boss。
6 S! \0 ]& {* \) g. N
哈 不敢當,我只是個平凡人,% f( n% |) k, l' W; v
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
3 R9 d- {' @; F. ^/ m3 wZYH
' o2 s& y0 `7 VQQ:414734306+ n* d( |0 ~/ L/ ?) d7 C' ~
Mail:zyh-01@126.com0 k, i+ l" v" t0 |* Y
+ m* b$ c& U" v; r; y: G
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 " j. ?+ j/ b$ S: h3 i0 {, g
再次对团长大人和悠悠哥的无私帮助表示感谢~~

& {% ~2 c# _+ H1 A! j, R& K( D不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-9 16:20 , Processed in 1.085937 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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