EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
2 q2 J, S  Y3 Y+ V楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
& Z# i9 p$ L$ v( F* X这里有相应的模拟器源码,就当送给大侠了~~* c2 v& T$ C; Y+ T
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
, J( `/ [- V3 _( c5 v7 }能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。8 E! }6 A/ B2 M
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~% y7 J8 \) Q7 K/ |
这里有相应的模拟器源码,就当送给大侠 ...
- P) |3 r9 a6 P' R1 b% T
聲音部分(Audoi Process Unit = APU):
0 \1 U# m6 t% w/ I.\NES\APU.cpp8 p  J- w& Y( F/ _* E/ ~
.\NES\APU.h
( E8 c2 a6 p0 {: I% x/ ]! T5 m. f% F

  [) a4 B* j" ~  `, s8 R影像處理部份(Picture Processing Unit = PPU):
! T; K! ]" D" e0 N8 Y( [.\NES\PPU.cpp  {- P& V$ R' j% ~
.\NES\PPU.h9 n9 W$ N; W/ L5 p4 w$ G+ I

: V8 T: ?3 D2 D1 _1 I如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
3 ^. w  ?2 x9 Q6 o7 j感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
4 N) ?3 b! c3 Z3 q; M* l: d(由于很多专用术语和算法机理都不明白,所以看不大懂……)
( S6 u+ C. k- `//////////////////////////////////////////////////////////////////////////3 G* m3 W2 _+ U0 j+ Q' |. }
//                                                                      //
! c  s; j5 _+ H; s; m//      NES APU core                                                    //
# q+ [9 O. B& [6 f+ I- h//                                                           Norix      //! \2 U8 ~$ l  S7 Y) G& V
//                                               written     2002/06/27 //. @6 W) x7 R# I) G
//                                               last modify ----/--/-- //5 l+ e* J9 }8 ^7 ?( G) R. B: n
//////////////////////////////////////////////////////////////////////////! b0 Y, Y2 U3 ?2 F6 N1 S
#include "DebugOut.h"
) \+ c% F2 i  J" r- b8 P# I#include "App.h"( S5 r' W+ p: H0 T! ~
#include "Config.h"
; l8 [  m; k+ i: Y, y" e9 \* C5 m9 n2 ^8 F  G; s# X" X5 @
#include "nes.h"$ r7 ?. B2 W- n2 h
#include "mmu.h"
0 p5 O9 Y% ?0 `- h" Z- l, l#include "cpu.h"0 d% A! Y6 A0 K. d/ ^3 x. u! T
#include "ppu.h"
6 I2 r( O% c9 h+ t8 i#include "rom.h"
" C* q7 k, o: C) `#include "apu.h"! V1 A' g- m! {' V; {6 n

) B: ^( u1 ], y// Volume adjust
  i! ]5 d5 h( Y$ m3 G// Internal sounds
0 r; u  s& L$ z2 ?#define        RECTANGLE_VOL        (0x0F0)6 g2 P9 {( @% a
#define        TRIANGLE_VOL        (0x130)6 B' y9 n6 y9 A1 G$ g2 F6 r
#define        NOISE_VOL        (0x0C0)% F, B3 E6 }& g7 M9 x
#define        DPCM_VOL        (0x0F0)" Y2 d+ s. x9 S" F) K3 m' X5 D
// Extra sounds9 X1 ^. D9 z$ e$ j. e
#define        VRC6_VOL        (0x0F0)
$ v, ], {) r  K* D; W( d; a2 K) c#define        VRC7_VOL        (0x130)
1 @2 l" Z2 ]) ?  H# c, I- G! j#define        FDS_VOL                (0x0F0)
( R, ]7 W* f2 h4 {2 h#define        MMC5_VOL        (0x0F0)
9 Z9 k( q5 e* r9 ^: J#define        N106_VOL        (0x088)
* q8 }+ w8 A: ?3 V- O" z#define        FME7_VOL        (0x130)5 P$ c, X7 J/ o2 W" x* S- J6 l( h
$ G- ?* ~7 c$ ^
APU::APU( NES* parent )# s, c/ r+ I1 g1 v3 Z! T
{' x- q* X& v0 U9 a! ^
        exsound_select = 0;
6 k9 S8 |( ]4 g5 G( @; r/ ~* q% \+ ^  @) _) I
        nes = parent;" p) [, i% o6 X" W4 G" L: S
        internal.SetParent( parent );
& B, Z; W9 ~  h2 g8 S" G" J: \! _3 T
        last_data = last_diff = 0;
" e- D& T" E6 T0 O/ }* L- K. _+ Q0 N1 d9 k7 a9 ?% o( `- f( T
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );7 @6 d: p& ~5 V- S' G7 c! [

: s3 h, P! w! |  z1 z        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
) y- S& C- k* X9 D. `6 L$ u' f        ZEROMEMORY( &queue, sizeof(queue) );# N  ?7 k9 M" w- }  p9 E3 u, r
        ZEROMEMORY( &exqueue, sizeof(exqueue) );$ y! ~/ f4 V$ H

9 B$ S; p3 T5 Z0 F        for( INT i = 0; i < 16; i++ ) {
' v" {) x$ B4 D! v3 g4 U9 z+ _! c0 Z                m_bMute = TRUE;
- W5 A3 `1 k1 ~- T9 V4 e0 Z        }
1 p+ _/ `/ a. q" q}
: W2 V/ o/ {% A6 Q5 }
1 V# `3 u) b: d" i( NAPU::~APU()
* r4 E  \" U* J4 A% }+ @) l{
1 l1 A# _* y6 j- [; j}
! [+ ?/ \' v1 Z/ m
" G& r/ y: F$ @- a2 {' S6 Pvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
+ w$ |* r4 ^' S  o9 z$ O; Q, @{3 ?! @! W. B" r" F9 w8 W' v- n; S
        queue.data[queue.wrptr].time = writetime;
6 {! f3 {8 k5 c, Z        queue.data[queue.wrptr].addr = addr;4 e+ j  `. e4 G# K8 {) Y; @
        queue.data[queue.wrptr].data = data;
+ d% r/ d( E0 i9 }* ?/ d, W        queue.wrptr++;, Q) ?9 n' B; T2 b, O% u$ m7 ^
        queue.wrptr&=QUEUE_LENGTH-1;
  s% N! R4 j. H, G; G0 |" ^        if( queue.wrptr == queue.rdptr ) {
  ^8 X4 P. I+ U/ `, L' o                DEBUGOUT( "queue overflow.\n" );
" {; m- V& O: `/ J. D        }) c8 M3 `1 C0 G1 J: p7 D
}
( f* f3 |# z: H1 z. Q9 X* z% ~
; P9 K4 e. k7 ~: y( eBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )0 O4 V& Z7 h  l7 l5 E
{
6 X! A- B6 P+ V- U& {+ T        if( queue.wrptr == queue.rdptr ) {
8 |) u7 _7 D2 {- v                return        FALSE;# l7 t3 Q) f' B0 m  \- V
        }
' _# R, ]# ]+ D0 \0 A        if( queue.data[queue.rdptr].time <= writetime ) {
# O# b2 d% G; }! L0 R) t                ret = queue.data[queue.rdptr];
# \* O' l; i- r                queue.rdptr++;
' ?9 ?' k$ o; v. h' m5 w" ^/ h& T                queue.rdptr&=QUEUE_LENGTH-1;
0 V' _  f  `4 v                return        TRUE;+ G3 V$ {" d* s" h& x" E. P; B
        }
  q8 O/ B& x" W/ ?        return        FALSE;
" I3 y% a! v' r}. [7 `" g! \' C+ M4 ^6 Y% k9 ~
' E2 M- C4 g; ]% l; O8 U
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
' |+ _: f6 h/ P4 k  h{% @4 ]; r$ g! a( J* ^
        exqueue.data[exqueue.wrptr].time = writetime;! p: j' G, B$ ?; T
        exqueue.data[exqueue.wrptr].addr = addr;- u% v' Z8 [' \) c* R% J& T' [! k
        exqueue.data[exqueue.wrptr].data = data;
" c" Z9 c9 a7 o( A5 Q5 w2 l        exqueue.wrptr++;
$ z8 H# Y5 i5 O! w! _        exqueue.wrptr&=QUEUE_LENGTH-1;
7 F% v* s) F( C0 ~! l4 }, E        if( exqueue.wrptr == exqueue.rdptr ) {! P2 E  |. t) b6 O) w
                DEBUGOUT( "exqueue overflow.\n" );( m7 P& I! Q8 L$ k5 z$ l
        }2 |+ O# _  [$ }$ ~, o$ q$ N
}
( r* K8 V/ K7 C4 _9 C+ [2 X0 Q- j
* X* S) k) b$ E5 PBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )5 I. G4 _( N! i0 m
{
: @0 S2 a( u' @/ w0 y4 ~$ D        if( exqueue.wrptr == exqueue.rdptr ) {# z( ~" D; [$ O7 Y0 Z
                return        FALSE;
: M: }9 N6 {, k% K        }
% n6 q! y( \  p! p9 m7 U; H        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
+ Z$ p: h( ^) g; f                ret = exqueue.data[exqueue.rdptr];4 t* _7 Z4 ]! X' ]  c1 @
                exqueue.rdptr++;' q: a, b/ [; t0 v6 s1 O5 m
                exqueue.rdptr&=QUEUE_LENGTH-1;" M1 q- H3 P6 y% N
                return        TRUE;' i% n& f+ O# d) P7 u
        }0 X9 O$ z+ J$ a
        return        FALSE;
( u# ?- M. s) t. }" b7 w}9 w0 l0 C, h/ @5 a: Y
, W) Y2 y8 @, n: {
void        APU::QueueClear()
( [1 P( E& K3 A* f" T{: L, x, u; ~1 L0 V% V
        ZEROMEMORY( &queue, sizeof(queue) );. V; P% ~6 E- U9 [% i5 d- @
        ZEROMEMORY( &exqueue, sizeof(exqueue) );4 u0 d+ c2 R/ q/ H1 n
}2 C' H* c6 |/ A- r- e
/ e" g* e: X8 U( [
void        APU::QueueFlush()
  J  H0 p* D& v+ D9 ^+ r+ ~/ f{- D8 r9 q. R* Z+ E
        while( queue.wrptr != queue.rdptr ) {" S* c2 t  [0 O: n
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );. y4 L+ Z& I; W1 D% i
                queue.rdptr++;
$ ~. E# f9 N  Z8 U                queue.rdptr&=QUEUE_LENGTH-1;
: Y) j; g9 {4 a( S. o        }6 u5 R' S3 p( h9 }+ x# \
+ q# a$ G7 e* B' x9 j
        while( exqueue.wrptr != exqueue.rdptr ) {
  c2 t/ @6 z3 h! M( d* B( I" b                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
/ z0 `% n$ i2 p+ `$ b9 F                exqueue.rdptr++;$ }6 i  ^/ ~# j" p  a$ C
                exqueue.rdptr&=QUEUE_LENGTH-1;5 x5 l! s0 ^' v8 [# W6 m" g8 ~: U& S) ?
        }' X) q- }" f2 X, C: f: g3 V
}
) T& q! T  U8 n& Y8 o& a( v2 K
0 n0 n4 W; L0 ivoid        APU::SoundSetup()
( R* G$ a1 _. |2 {7 @{: j/ T; H6 k4 e
        FLOAT        fClock = nes->nescfg->CpuClock;
5 v' Z) o$ Z; W) J& K) j4 f        INT        nRate = (INT)Config.sound.nRate;
8 ], A5 H0 }  |6 G) y* t: N) [        internal.Setup( fClock, nRate );
# a7 V2 c0 {: r        vrc6.Setup( fClock, nRate );0 O/ {6 s( b4 _0 j
        vrc7.Setup( fClock, nRate );
7 h0 i! d. w. i, q/ o7 d8 [        mmc5.Setup( fClock, nRate );
7 ?6 D8 ?$ w) z* [) y: m  n! j        fds.Setup ( fClock, nRate );
2 G* ~* K( M: }% a6 U" g        n106.Setup( fClock, nRate );
2 a! g% w( w+ q5 Q$ \        fme7.Setup( fClock, nRate );5 ?% y) p' d5 a% B$ f( p4 X
}3 q: A3 R, s- Z1 j

7 _0 O# v+ M% s0 ?. [# Q6 Cvoid        APU::Reset()
4 R4 n5 }, l0 u! {- X* Y: X! b- T{7 H1 S' d+ B( Y0 H& |; D: U
        ZEROMEMORY( &queue, sizeof(queue) );8 i+ ~% U9 t4 `* a6 n( J
        ZEROMEMORY( &exqueue, sizeof(exqueue) );+ a5 V5 L$ }8 Y& }7 B3 D

% A& @2 D# n! K! T        elapsed_time = 0;: p& ^5 A$ b  Y

# b" q- c5 W" W, S7 y! P+ P        FLOAT        fClock = nes->nescfg->CpuClock;
: a2 y& z2 o+ }9 ^; {* e        INT        nRate = (INT)Config.sound.nRate;
$ E5 q- j' r" w1 Q5 {4 @$ h        internal.Reset( fClock, nRate );
: B) B5 W" w; S( j/ r$ L" }        vrc6.Reset( fClock, nRate );
1 C  H: L, r/ }$ f  U/ R7 F$ B; E" h        vrc7.Reset( fClock, nRate );
* x7 U0 `6 x. r2 r9 E2 z        mmc5.Reset( fClock, nRate );
( X& O" b4 j' |. k6 h% V        fds.Reset ( fClock, nRate );3 a2 Y1 `3 S1 s' X; p
        n106.Reset( fClock, nRate );
3 F: d6 w# z3 Q- x( j        fme7.Reset( fClock, nRate );
% N# A6 r7 J+ u$ g& [$ h5 Z% b( P8 \/ b
        SoundSetup();
  H% u* p/ K+ f}
3 a3 S4 J7 I+ V6 \* A* I1 X9 t. y! F
void        APU::SelectExSound( BYTE data )* i1 A. r! S  v: ~- G- Y- p  J
{; Q. N( X/ U: x3 y2 H1 d( ~, }
        exsound_select = data;
0 p' y& \* Y5 V' N' c}
* o. D3 b3 q& ]' A9 u' i2 q: n. M9 `9 d" _8 b7 x* F
BYTE        APU::Read( WORD addr )% Q" {6 f6 w  c" I7 F$ V
{
- v" z* h! F: y5 Q        return        internal.SyncRead( addr );/ P) V2 I  v1 q5 H) p
}
5 e8 }! i$ |1 {, V* q8 m# }& ~& \. h1 e9 U" }
void        APU::Write( WORD addr, BYTE data ); ?+ a# U/ p& y  i- \( \
{8 m2 c) ^  M0 @; P' n
        // $4018偼VirtuaNES屌桳億乕僩
) j; x  m0 t# M# b" Z- E/ i6 y        if( addr >= 0x4000 && addr <= 0x401F ) {
* \/ d+ |3 X) J' _                internal.SyncWrite( addr, data );
/ M3 m( D1 `2 r7 S                SetQueue( nes->cpu->GetTotalCycles(), addr, data );  R! _4 `0 C) s- S7 n5 D
        }+ {% R' e7 s; V# x7 W" a$ j# c2 ^
}& E! h: O  L) i0 h
; q$ _3 b# Z; l* x- E; A) D
BYTE        APU::ExRead( WORD addr )
) F- z( Y1 @, Z5 m5 K{# C0 N. y& n& D& V  O% G" q7 {+ G
BYTE        data = 0;# H  {- Q8 a  `6 s

+ f# c& }& F3 g0 j0 B5 d- b  H5 g        if( exsound_select & 0x10 ) {
+ b0 {; l8 J( i                if( addr == 0x4800 ) {* k6 C8 [9 I! A7 _8 i
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );# P+ J/ i' v' D7 A
                }
' m: s6 W5 u" r8 }& u        }! c& i" Z! ^5 p+ o1 e
        if( exsound_select & 0x04 ) {
* q. S- o' ]6 n- I% {6 a                if( addr >= 0x4040 && addr < 0x4100 ) {4 b$ Q- L4 I5 |; r+ P5 A
                        data = fds.SyncRead( addr );) ^  z5 H! ^( X3 C, Y
                }4 i* q& I! H+ C- Z8 K
        }
" e8 t; l7 J* [        if( exsound_select & 0x08 ) {
4 W2 T  U7 T# u+ }2 ]                if( addr >= 0x5000 && addr <= 0x5015 ) {- r) b! T. n+ Q
                        data = mmc5.SyncRead( addr );
2 j0 n, i3 i5 y) Y# F1 y+ H; |                }
& n  p" f3 D* f        }# c' z* R( c9 L) g7 m* l! m8 a7 Y
$ b4 r0 A1 z" Y' I6 f) L+ C
        return        data;+ m; a- L) p1 j% n0 m) F
}7 i: `( y( K' Q: x

2 R3 K' s1 i8 @) C  t! Hvoid        APU::ExWrite( WORD addr, BYTE data )4 h7 U: @1 v- K4 g( _$ @" P
{
; [5 T% e( j! \7 O# c! [4 M* i( J        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
" t/ d% b/ K. g- h, x4 d" X4 F/ o& H, h) \
        if( exsound_select & 0x04 ) {
3 c3 m* j6 S7 |; _  I                if( addr >= 0x4040 && addr < 0x4100 ) {! R, G/ o+ w- |/ X
                        fds.SyncWrite( addr, data );
5 R& l9 q& h/ ^9 _& I/ T9 h                }5 h' U# C9 k0 D9 N9 h% K
        }
2 X( |- B/ E, b5 D$ I  d8 N& }, \% ]. H8 @: I2 z
        if( exsound_select & 0x08 ) {5 G2 d! G7 U' }" I/ |
                if( addr >= 0x5000 && addr <= 0x5015 ) {
0 _+ @9 s8 C0 G' ]% h5 F2 M                        mmc5.SyncWrite( addr, data );
; N7 j* T3 }! n; N( U                }9 w" g0 o7 j3 h  F$ f. `
        }! |% p3 X6 C7 r7 i. h0 ]
}9 V; B! O9 i+ ^# d
) z6 q+ g1 y* @- C) j7 |; x3 ?
void        APU::Sync()
/ g8 P, [* u+ v{6 |: ?! J4 t! d3 |; ?
}
" `: P6 I( I5 O% T3 C
! Z8 Y, a# Z- H3 s1 hvoid        APU::SyncDPCM( INT cycles )
, J/ P/ V+ n  T{) `1 {/ k: C- ^( i
        internal.Sync( cycles );
! W$ @3 S; x+ I5 ]0 H7 i2 {% _: T3 {/ J8 r1 B) u' b( u' {& ~3 w5 J! r
        if( exsound_select & 0x04 ) {
5 q' e1 A% A+ }1 [- e( Y7 y                fds.Sync( cycles );+ q, b- ?8 S- V& Q" H
        }
* q  [% e9 q' t& C        if( exsound_select & 0x08 ) {
8 [" n9 K% e2 n3 t: E! I                mmc5.Sync( cycles );2 u2 L( n7 [( l$ X8 a# ?
        }
; ]" ]; d& b7 U) _, R$ k4 H' l}9 v8 r; J* E  b
! B( u5 D+ Z; z
void        APU::WriteProcess( WORD addr, BYTE data )  s0 @3 `  s; G9 P4 I1 ]
{
8 W% t$ w- A; {1 r% t) X" Z% J' V        // $4018偼VirtuaNES屌桳億乕僩4 C$ m( K8 s. T5 F" H6 {
        if( addr >= 0x4000 && addr <= 0x401F ) {
! v, u8 r( o2 q                internal.Write( addr, data );2 P# q& H* h$ f/ @" y! ?3 z
        }- V9 z3 U8 Q5 q/ S
}
8 S. t( d6 x3 A7 U  d
; G! J. N& r3 n. a9 v1 G, ^9 Nvoid        APU::WriteExProcess( WORD addr, BYTE data )
, A9 P: g( O9 J{
: X" C! W# m- f% n4 ~        if( exsound_select & 0x01 ) {$ P- g& c' y8 k  }9 j0 F
                vrc6.Write( addr, data );& p, a" k( j9 j+ D
        }$ e' q8 _8 M6 O* q6 d' t
        if( exsound_select & 0x02 ) {& h5 C/ w' ~7 C0 _6 h. b
                vrc7.Write( addr, data );
- i# K, p  {5 q9 `        }
. x+ k. J! x$ n5 Q: m5 }# j' y' p        if( exsound_select & 0x04 ) {% J8 s/ y# X5 }) t4 u$ N
                fds.Write( addr, data );
( s8 c* F% h8 a! n  S# ^1 V        }2 A/ F$ O- J" U% p
        if( exsound_select & 0x08 ) {
! L; w: u6 t* A& w/ t                mmc5.Write( addr, data );( ~4 Q' S* g8 G; F1 ^7 ]' Z- M8 l
        }
- R# j1 K% b2 t- D9 p9 h/ L        if( exsound_select & 0x10 ) {
1 J* M6 o6 h6 ~9 d/ K; B. \2 ~/ Y                if( addr == 0x0000 ) {+ Z6 k4 @* f8 K* U8 j1 ]
                        BYTE        dummy = n106.Read( addr );
% L8 m8 t+ w6 H4 e+ h! q% D                } else {
" ~! B- p* Q8 d/ q4 w  q                        n106.Write( addr, data );
  Y" ~9 p. `* o# ]9 Z0 a                }
% u! Z( o7 O( K        }
, F1 R4 E: y; \. h$ G        if( exsound_select & 0x20 ) {8 l0 L, O  o+ f. y
                fme7.Write( addr, data );, I+ X8 e4 F$ f+ a
        }9 ]; m% Z. `8 v7 }. b- s
}4 i9 r# {; E/ G9 F5 m6 F3 N8 v/ o, l

" _1 R/ Z3 @( p5 i/ Y- nvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )/ W2 U9 j' c8 \' r1 a
{6 ]8 c, F9 e; E; L1 q. G3 `! o, V
INT        nBits = Config.sound.nBits;5 o$ }9 b: K8 s5 o
DWORD        dwLength = dwSize / (nBits/8);
0 A0 `$ p  T' g4 fINT        output;
  ~# e  n" l- s, XQUEUEDATA q;* ~6 k% Z* m: X: h' [  X: G+ @
DWORD        writetime;
& V0 c* g/ \. t2 @: q( X8 ~# e0 n' v& b1 x$ v
LPSHORT        pSoundBuf = m_SoundBuffer;- L  q6 s5 _9 |8 U, _$ |! E/ V
INT        nCcount = 0;+ H2 V; K8 V# V( `

: n9 c+ R6 z8 T1 S  C4 _INT        nFilterType = Config.sound.nFilterType;5 v2 M, o  Z- n6 V! B

& X+ z/ Y/ g3 v- c' h) F        if( !Config.sound.bEnable ) {( B: R  ]2 P7 {3 S9 E- Q
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );6 U3 d, }  {& n, ?2 a8 F3 W
                return;; O2 Y2 I: ~6 v
        }1 a; f+ m3 p5 @% C# d
6 U- ?/ I# M7 F+ Y/ ~% s, E$ c- y
        // Volume setup  x4 C+ M4 }( I9 B" X; N( q% B' B
        //  0:Master
, y# a/ ?! K, ^) ^* V' b8 P        //  1:Rectangle 1
# T4 S' q% n( A+ Y  o; {        //  2:Rectangle 2
: \8 s, x' U4 L! w        //  3:Triangle
  X- W" I! K' c, p        //  4:Noise
1 ^! a  `% Y' q: q$ {; t        //  5:DPCM5 M8 n! q- ^* E( F! G  q: V
        //  6:VRC6
4 w8 c" Y! A& n  M/ j5 J# x        //  7:VRC7  d& G+ ~9 v( j' v/ t
        //  8:FDS2 X* g* w% b2 v1 j# Z9 t2 w  N$ b
        //  9:MMC5# Z9 n$ O* f2 r9 J. T/ i8 ^% @
        // 10:N106& H7 {& i$ {* g# E9 O
        // 11:FME7
/ f. B/ }3 l0 h" Y* u        INT        vol[24];
' c: E$ O7 s  _2 `        BOOL*        bMute = m_bMute;
$ Q( f& k& N# e8 c. O/ j$ x        SHORT*        nVolume = Config.sound.nVolume;
* j* c" O  Z0 Y3 q% h8 T" G: V( a8 `: i2 i* D
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
3 I; ~$ x! j# C- Z& w
" i& L% E- f" [5 y6 y$ I        // Internal7 D2 [# |( m8 `% _. ~/ ^. J
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
2 ~0 D+ O" x! `% J: I2 B3 M        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;: g; B; M! |. X5 k: N8 u
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;5 C$ V* t! M$ @' H* n% M
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;' n) T, R. [3 b+ H6 W7 g
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
1 q- z# L7 y" g9 o' _' g& @" P8 A) ]; y' x4 x3 S
        // VRC6
/ f+ M  |4 B7 Z        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;) Z; ~5 ^0 V: j' i
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;6 S$ y" z# c# P3 R/ N- f! y5 l
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
3 X7 U) m2 i; Z$ u, C% _6 Z" |5 o9 I9 k
        // VRC7
* g; B" y( w' K! _9 ~% L7 }        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;3 B" l$ p4 S3 l) I: {2 M

: w6 S7 w4 M! M! j; S' V  M        // FDS: f7 p' z9 ~; S9 I6 p, P6 b- `- C
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;$ e# s/ F/ D3 n- r# L/ b1 }

' q5 Q5 m' ?  G* F        // MMC5
1 s. s8 u- c' p* r) h% f0 [        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;( a  ?' M% ^3 D+ v  c
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;9 V5 ]" |6 Y1 r$ H1 K( k5 b
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;. [, V3 R0 ~0 b, k. n
+ y- q  c. X, M
        // N106
- s7 _; p5 m, }, q+ S        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;. t0 k! X9 v* S0 Z
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- f$ g. ^, N1 N( W8 l5 B9 L        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 @, d! d  r  C( d& @- l! M- R- n' v
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
8 @8 z; J0 m# }3 [) V        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;6 A/ A% O8 u# f0 k
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
) k' J7 Y$ M% r5 I# x3 D        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;5 Q  |$ W( }; D, N
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;% h6 X$ z  u! B' Q
- n! k/ `, q' l+ C0 a
        // FME7
6 L$ _! m7 L) _: o9 n3 A1 @) H- Y+ C* k        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;- o3 Y5 o+ d% |- L
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
; J/ }1 o# B; U2 R' s        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
! o, D9 _- G/ i- G- _% s! ^8 s3 y- Y& u7 }6 j0 ?$ C, o
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;/ ]# p  l/ i% a
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;, `0 H8 H: g# m4 s: Y0 }& b

/ l8 c- x: v( z! Q        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟& |5 b: g3 h8 x# P3 Z0 O
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
1 {9 A( G' s# u                QueueFlush();. c5 W; {9 B% T" @2 s. Q1 Z
        }* H: N8 k7 E$ t% H! K! l

. k4 k% `4 J- r2 A7 p, _2 ?: a        while( dwLength-- ) {: E* i' {1 l- Z/ `: v4 e
                writetime = (DWORD)elapsed_time;
/ B5 F+ t: T8 ~; A: \5 n& r: |/ E( q
                while( GetQueue( writetime, q ) ) {
: v0 U! v/ W8 ~# Q3 y0 ?$ k                        WriteProcess( q.addr, q.data );
( n* i3 [; h3 |9 a7 M( v                }
! c: W6 ^$ k- f1 A( y. w/ W: C7 }! i) g
                while( GetExQueue( writetime, q ) ) {
$ |/ g( E! O' S) d  B                        WriteExProcess( q.addr, q.data );
5 U* P4 U& ^3 g                }
1 L, @- @/ ]9 ^; [3 x; M; M1 ~8 {! {  |1 f9 P) M) f% a
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
/ @2 X9 P+ X4 P* d0 X+ T; k+ X                output = 0;
7 }3 o' t% o4 {7 I/ g3 W6 [- Q* E                output += internal.Process( 0 )*vol[0];
" K/ v2 O5 g7 }* b3 t                output += internal.Process( 1 )*vol[1];! i; a7 f% k4 k. P" }* W
                output += internal.Process( 2 )*vol[2];0 d  o7 B, e9 c! _! b, t/ h: g% |
                output += internal.Process( 3 )*vol[3];
! n2 z1 {: K& b- w" b                output += internal.Process( 4 )*vol[4];" M1 ^: z0 Y6 i' v7 z+ z

1 g& O  r6 ?2 e: j/ O0 ~                if( exsound_select & 0x01 ) {. K* u7 P7 _$ y$ @. u7 L" j( w
                        output += vrc6.Process( 0 )*vol[5];( e9 W  F/ T* i; a" f& f  y
                        output += vrc6.Process( 1 )*vol[6];
  N0 [! ^7 M: h: U7 o7 ^' O                        output += vrc6.Process( 2 )*vol[7];+ p; n/ I  N. b% e
                }; ^4 |) _, E: J$ Q4 p; ]4 W
                if( exsound_select & 0x02 ) {
3 W5 w% L+ J, p2 z  R                        output += vrc7.Process( 0 )*vol[8];. e% `9 w1 J# k% g7 o
                }
' [, ~* o" A$ I                if( exsound_select & 0x04 ) {' Q, N8 s( b$ }2 G+ z0 S- x
                        output += fds.Process( 0 )*vol[9];
; R' n$ F3 k3 Y, ]7 f                }: m/ ]1 j5 ^  B
                if( exsound_select & 0x08 ) {
- R5 \5 J" j8 u; L4 M& w, S                        output += mmc5.Process( 0 )*vol[10];
2 N9 R3 G; T. M6 h/ E                        output += mmc5.Process( 1 )*vol[11];+ I- E2 @7 ~0 Y
                        output += mmc5.Process( 2 )*vol[12];
3 w5 B2 j# n% F* H                }
6 o+ z6 ~/ D: d+ c                if( exsound_select & 0x10 ) {! d4 q) p3 h& t$ C$ w* T
                        output += n106.Process( 0 )*vol[13];$ v1 `' m3 ^& l) \& F. ^. U
                        output += n106.Process( 1 )*vol[14];, [# r! d1 ?8 n4 A3 B5 K3 F# {( \2 j
                        output += n106.Process( 2 )*vol[15];
  J5 V/ f4 ~( I& c' X' W                        output += n106.Process( 3 )*vol[16];
. Y2 f' H5 b3 f8 P                        output += n106.Process( 4 )*vol[17];
' l) \8 p4 A9 w6 r7 b                        output += n106.Process( 5 )*vol[18];
0 c( F/ L! Q: R- v* E- u' B                        output += n106.Process( 6 )*vol[19];
4 e& j! r$ m% z1 ?; ^  \                        output += n106.Process( 7 )*vol[20];5 e7 C# h/ v' a& K: T, d
                }9 |$ k1 \0 T4 a+ s
                if( exsound_select & 0x20 ) {/ q9 ?. s4 ?" b9 b, u
                        fme7.Process( 3 );        // Envelope & Noise
; v9 z! B9 G; O: v$ c9 z& }  b                        output += fme7.Process( 0 )*vol[21];, |0 P; G' f8 c) `7 j
                        output += fme7.Process( 1 )*vol[22];% o1 f7 K) a4 p) D2 d
                        output += fme7.Process( 2 )*vol[23];
7 Q; Q. t" B# ?/ W6 @                }
" B; A& E/ F( x: q1 ?1 Y1 L" m  b: \. n6 X
                output >>= 8;
  l1 x/ Z- i- G% }* j. r) g$ v% _. u  N$ \
                if( nFilterType == 1 ) {* @# G4 Y7 M1 h. J4 L' `
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)7 y9 _. n* H8 ~2 Y+ J9 G' o+ {
                        output = (lowpass_filter[0]+output)/2;3 r1 b6 i, c. h2 E: Q3 T9 u: w
                        lowpass_filter[0] = output;+ `# d% E7 x, W/ N$ J/ x
                } else if( nFilterType == 2 ) {# I& p8 m/ B. O9 q3 ^3 v& m
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
  s( X* n4 Q. Y) G                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;' W4 l/ w( a/ R% J) H
                        lowpass_filter[1] = lowpass_filter[0];
5 B' U2 H+ g( A7 i* p! l$ `                        lowpass_filter[0] = output;
& T7 r2 h9 s- @; @5 A6 L                } else if( nFilterType == 3 ) {. ]: T5 M' j. C' k" w" Z; x; e$ X
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
0 T9 ~, o8 _) |' @8 M                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
0 j) g& d1 Z  W2 @& c$ n. b                        lowpass_filter[2] = lowpass_filter[1];' k, @8 Z! ?$ ]8 j  ~6 U5 m, A
                        lowpass_filter[1] = lowpass_filter[0];9 q6 `& o. a6 u% e. W- I0 R
                        lowpass_filter[0] = output;
. M2 g& K2 l& `- d. X                } else if( nFilterType == 4 ) {8 V5 {5 f% }" Z; y
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
% K0 J4 f, P+ a5 d                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
( ~) j1 p! ~( s% [+ K                        lowpass_filter[1] = lowpass_filter[0];
% U# v( m9 S0 @7 `                        lowpass_filter[0] = output;" w9 N/ r: s( k8 v% _% F! J! r
                }/ l  [3 F+ o" F1 q" q7 C

" w& v' l; ~) c! |! O% O) f2 F#if        0
/ }8 ]4 N4 C- e3 M                // DC惉暘偺僇僢僩
' K: P) A; F* W                {; O) X  L# h- F4 b8 S" _) J
                static double ave = 0.0, max=0.0, min=0.0;
" G  V  y; P. H2 _- C3 c. M) e                double delta;( l2 S; k7 G- U; n! w9 T  r  _
                delta = (max-min)/32768.0;
6 u8 G1 x1 A  x                max -= delta;
% S3 f! a1 H- s- r1 F                min += delta;5 W/ j1 l1 E, k# V) t: P( i; D; ^
                if( output > max ) max = output;! _, e# r% q0 e' A- c9 ^/ G* ]3 v
                if( output < min ) min = output;
% B' D. U  m$ b& s& p- J7 k: q                ave -= ave/1024.0;1 b+ H  d  N1 \2 b
                ave += (max+min)/2048.0;% P2 s; Q' o7 d. m' u
                output -= (INT)ave;' s) W: ?+ P; {3 K6 R: H0 Y. o
                }5 |  ^. F- [7 E8 L$ q4 v6 s" F
#endif4 J3 J0 M1 j* b6 O7 M9 {  ^, w
#if        1
3 d: b! {9 P( A, C; }% G: S                // DC惉暘偺僇僢僩(HPF TEST)
) p9 n. O- R4 f                {
# h" O0 h2 u- |7 Z/ F' R//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
/ V- q4 W% L' D3 j/ {& y5 {                static        double        cutofftemp = (2.0*3.141592653579*40.0);1 b! [6 L7 R; D. u$ q
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
4 S5 g5 x3 A$ j, v: b& a                static        double        tmp = 0.0;
* Q- Q9 q2 D0 e2 S3 i                double        in, out;$ L6 O: e5 y9 w+ G" @

- H! F+ d2 U$ c$ A( b" K                in = (double)output;$ Y, K7 R9 F* ?: E9 e! {8 Q# a
                out = (in - tmp);
+ Q3 T& P5 ?, r4 l. j* d                tmp = tmp + cutoff * out;
! O7 v; d8 Q% b8 D# E8 c" k3 j! J  @, {" T
                output = (INT)out;( m! _$ v3 ?& M& ]- o& R* w9 I
                }7 j6 f" `, ^2 l
#endif
7 P. z, g! ^6 v' w' y# }#if        0
3 t. c; m  Y2 n! x' m4 \                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
: c2 D+ j/ Q2 ^9 s2 @- x                {- z( A3 g; w: I0 L" m
                INT        diff = abs(output-last_data);! s; F5 c( ~2 B2 D! A4 G6 t
                if( diff > 0x4000 ) {
- k' I- ^  A% P0 p                        output /= 4;0 g, k# s* \/ v6 z1 ~. ^9 y! L
                } else ! S0 ~! k1 P+ O5 p" I& m3 o8 x
                if( diff > 0x3000 ) {
7 W- r1 t, i" q9 F, A                        output /= 3;! [5 j5 U7 @. {( L6 c# M6 c
                } else
7 C0 G6 G, y; g) A4 _- z                if( diff > 0x2000 ) {
  i4 |0 Z; N8 e" n5 A                        output /= 2;/ M+ ?& G% G' \; t! M
                }
! ^8 C% s2 [2 j* s+ m$ C! y                last_data = output;
$ u3 h* Y0 l( g) ]                }
  G5 T9 z+ r8 {# T/ H0 d: }* k5 @#endif
, M1 @# d+ e( t3 B( Z                // Limit
- e: s* o% I9 w- u7 }                if( output > 0x7FFF ) {
* t" U+ ^8 @) w% ?6 X- v                        output = 0x7FFF;
6 t# U* J! V5 C5 q2 N. `                } else if( output < -0x8000 ) {5 m* [9 c* k" h( n) B) k3 L& ~
                        output = -0x8000;
$ o1 U( w" O9 u; l, L/ K                }1 G( a7 S6 e1 r2 {4 |; I: j0 V
+ g3 V7 ]! d7 o5 b8 \
                if( nBits != 8 ) {
# ~, z$ b4 C- e# M' R                        *(SHORT*)lpBuffer = (SHORT)output;
- i) a, M4 K7 S, J                        lpBuffer += sizeof(SHORT);' H" S% \" e2 |% |; l1 v; i# M5 e
                } else {
) i8 v+ E. d) y. S  g                        *lpBuffer++ = (output>>8)^0x80;
2 H4 l: r5 e6 I                }8 X. {: Y0 L% w& ?
3 u) }7 i1 q4 r% p
                if( nCcount < 0x0100 )
2 f% q" t: M$ F/ g% C                        pSoundBuf[nCcount++] = (SHORT)output;
4 K. }) Z' E6 r) Z/ W' b7 ~
& H( w1 o2 p0 q//                elapsedtime += cycle_rate;5 ]5 p- S$ k, K, P
                elapsed_time += cycle_rate;+ u; t! g1 C3 p, b+ ~
        }1 s4 R# k7 B  }$ |9 T

% D; ~* S1 Z7 M; M; q$ n' Q#if        1
# M; a' v/ F, y; E% G        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {0 ^  c* G( g  e1 \3 i. C: y
                elapsed_time = nes->cpu->GetTotalCycles();
* N* r6 C" F' X6 R" b; O; l        }9 L2 z1 g8 a8 M
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {# s  w. l( [3 s' X
                elapsed_time = nes->cpu->GetTotalCycles();8 W. |  Q+ V. H* U: V7 D; {
        }
( }& j, r" z4 X7 y! C; ]( g#else
* T3 v, \8 \8 x5 j        elapsed_time = nes->cpu->GetTotalCycles();
& Y8 N' ?+ ~, |3 T$ r#endif
. l- w7 K) D* E( }+ t}
, q. W( w* E4 x
" M# y, j! g- b5 D' Y/ J% C// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
9 q. C4 M8 i  T' Z% k$ TINT        APU::GetChannelFrequency( INT no )$ b8 ?" R1 Z4 {
{
# j" o) h6 p4 u        if( !m_bMute[0] )
1 l+ I& N8 e' t0 O                return        0;! k# D& f3 B( o& W
* L7 N1 I2 Z. y; X. d
        // Internal0 B( p9 n  H/ E/ p0 d
        if( no < 5 ) {
) [/ l/ a# l9 |                return        m_bMute[no+1]?internal.GetFreq( no ):0;: Y, {+ v# r# i$ }5 V3 U5 n
        }+ W; V( P" _- v% i
        // VRC6
; t' S8 q8 {1 H6 K: D6 ~+ f; `        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {: m8 n, |! C) H6 ^8 ?
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;. \& e2 J2 {. x2 h6 ~
        }
. T1 [& ~, |$ X/ \! |. p8 G        // FDS+ J+ F& S  z8 ^5 Z+ p3 w% d9 i
        if( (exsound_select & 0x04) && no == 0x300 ) {
( f. F. }1 }+ v$ {' G8 @                return        m_bMute[6]?fds.GetFreq( 0 ):0;
& |5 l5 |% a, }! H% }        }
5 Y) `/ B! f/ ~- K        // MMC5
+ Z% m+ E8 ]& v3 V0 z4 W( G        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
, v( [! c) F% k                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;$ Z! ~) W0 Q, C$ v" x
        }
, j' ~4 G5 d; {: W        // N106/ O0 C: p4 ~/ u6 s/ V2 v* R6 s
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
; V5 |& N" w% a8 t/ K1 r                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;. b" r* k, E" M* z% x" }& r
        }
  j6 J8 O7 q. ^3 V! [( t        // FME7
* Q) r1 n. M& e, O        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
: x. N5 P  P& C& Q! G; T                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
, k7 d4 }& Z- r+ u" R/ x* s3 S* n        }; k* C: ^1 ?8 @
        // VRC75 @! h- c' w+ x3 P% J
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {* B5 j# V$ c$ L$ ]3 c
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
+ T) I% K" @7 e' Y  _        }4 C8 o0 u& P7 [6 ^6 `2 x) W
        return        0;. B' \% |4 }3 f: z& o
}, o; w/ ~: s8 t, c

+ V* \( }' E3 @3 Z2 P// State Save/Load
3 M8 j% R5 m3 G/ pvoid        APU::SaveState( LPBYTE p )
$ s  Z4 R8 ^: M2 ~% T9 d{/ Q" d8 y: ?4 Y* X$ h
#ifdef        _DEBUG
- q: ]: P0 ^  S3 _LPBYTE        pold = p;
1 K) m% W5 d! K* \" _' t% t* c/ M5 w#endif1 `& @- L) f) U/ N9 I+ _9 o

) `4 Z. l( ~) b( l8 R        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
/ r) K# z1 [/ Y0 s7 l        QueueFlush();. j9 C, ~9 n% h  x( O

3 p& f# Z4 ^& P( `2 ?5 E        internal.SaveState( p );
8 x) E, u. ?! `3 j9 Y        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding. }: B% M: |: b& [

+ B# u  @9 {6 j1 _        // VRC6
, K. k0 d( [  ^' x5 I- _& {        if( exsound_select & 0x01 ) {
4 w+ X! _/ m% {                vrc6.SaveState( p );
# S5 `, S) W0 ^1 ]. T                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
( _1 f& }' \7 s" ?4 ], E3 O        }
/ t$ {1 T, P/ m        // VRC7 (not support)
$ l5 }# p, Q( H, S4 s! J) B. Y9 r        if( exsound_select & 0x02 ) {
- f. o! b0 u' Q                vrc7.SaveState( p );2 g6 w6 t8 J0 W
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
0 @! `3 Z. ^- q6 J* N# n        }! E& t6 d6 ]" @$ x# p% [& e
        // FDS8 v; N  h% R, \
        if( exsound_select & 0x04 ) {* P+ o- w% k7 X( h
                fds.SaveState( p );
) t9 [  G8 B/ c% l; s. w; @' e. W                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
7 b, t% s  T+ v+ E        }
: Y) n- u# w% k( C3 {" B        // MMC5
$ U- e* @0 I! b* x  ~" H        if( exsound_select & 0x08 ) {
% q. U6 T& N' ]# w' F, R                mmc5.SaveState( p );0 ?: F/ L3 m0 d3 z/ _$ O
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
4 |% [$ @& q  o; f- d        }
0 x& N0 h0 j0 Z& }: W        // N106" z3 o3 v( @: P: B
        if( exsound_select & 0x10 ) {
- X) F3 A, f6 z7 i3 y. l3 |                n106.SaveState( p );7 P2 }4 {3 Y9 `
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding) u  v0 ^2 s$ C) n  ^$ F
        }( P3 z' k6 T% a
        // FME7: A8 b5 l) A2 V6 h( A  T
        if( exsound_select & 0x20 ) {; @$ p" Y9 D% C3 C
                fme7.SaveState( p );! g3 R4 L! b2 b+ Q) u% R5 y
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding9 s, i- Z% C6 X7 M& ]( W0 w. h
        }& D, L# e( Z! z9 v. B

) ]& w$ E/ T. O9 j3 A#ifdef        _DEBUG
" [; V" \) R' ~* `* Y8 d8 I. N2 CDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
: x7 ~- z* R* E- Z! L- p#endif' g- S/ v5 g) y  x" C3 L
}4 C; ~% u. A% g6 h& y' K' v2 C' n

1 Y7 I: ~7 X8 K: I; P. l; |void        APU::LoadState( LPBYTE p )
1 z8 i3 u% q# E& w, e3 ?. |% {  n. v{
9 R- N* X" V8 n        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
% m7 y$ `) h" z  C5 f7 H        QueueClear();5 }, J2 Y3 c( Z
- u- |" n8 O( }3 y/ Q
        internal.LoadState( p );
8 K: r& E8 t; @" _        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding  l! ^& z% D' I6 T# g

" t$ X+ x9 m* S! v% l        // VRC63 z1 d# I8 p. x" L$ A; [4 M5 E
        if( exsound_select & 0x01 ) {
% X! i% g7 M( d0 b+ d0 H0 }                vrc6.LoadState( p );
2 p, J- _$ K! J                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding# s4 ^( T# A: P1 ?) ?
        }6 F/ v; P; c* L6 M
        // VRC7 (not support)
8 `3 m! y+ `" s# \: R" e        if( exsound_select & 0x02 ) {
7 U; Y6 r5 U1 `* h- I                vrc7.LoadState( p );+ t8 b2 e$ u+ W3 M9 b4 _7 J+ c' g
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding' S6 p; g: X. o0 M9 T: p) y1 u& Y
        }
) a5 z/ B( b9 r        // FDS
! U3 ?! y3 v. C+ u        if( exsound_select & 0x04 ) {3 |$ U. `6 o* Q8 h2 p1 L
                fds.LoadState( p );
1 M# z: c& x6 t; \9 {6 I+ q                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
8 F# {/ F; [& o        }6 m; x; |7 C7 H  Y% d0 F. ]
        // MMC5
( l! O: X3 h8 V6 [- T        if( exsound_select & 0x08 ) {1 i* R; _4 c( A% {' X
                mmc5.LoadState( p );* S- O6 W' a8 y9 A1 p
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding" F/ j* |/ J$ |
        }* s* Q/ R1 K. Z2 I$ a5 @6 a. W, M
        // N106, ^. u0 n/ B5 P8 ~! Z1 [
        if( exsound_select & 0x10 ) {1 j& t. U) C# E. ^
                n106.LoadState( p );- M2 J5 \% c# f
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
' S. v1 {% a4 b: E2 H        }
7 c8 `0 Q+ v- `& i# u        // FME7
" J8 L) F$ M! f( I  e        if( exsound_select & 0x20 ) {
: x0 @' o" V7 L  X                fme7.LoadState( p );) c1 }; c3 O6 {) S
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
0 X9 s+ c: E8 Q5 K        }$ C2 v3 n% T' O) W  t) u' g+ x1 k
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 * p5 B' p4 W* B% Y
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
5 H3 }7 L3 H% z+ H$ D感激不尽~~

4 P9 J% _4 X; M$ |恩 我對模擬器不是很有研究,) P5 j* c& c1 Y. Q
雖然要了解源碼內容,可能不是很困難,
0 t( C4 i& @6 ?# l/ L6 g' |0 v7 o不過還是要花時間,個人目前蠻忙碌的。( ~7 v8 ^- A, F3 l- ?, F+ T
4 B: h1 h1 H* d# [6 p0 i# ?; u
給你一個朋友的MSN,你可以跟他討論看看,
* V- t9 Y( K% ~他本身是程式設計師,也對FC模擬器很有興趣。
5 X$ C. |3 {) V" w8 V; i7 Z, ]' B' d% U# F- n2 h9 \
MSN我就PM到你的信箱了。5 K3 ]+ J$ o2 S4 [9 l" c

) G! ?/ S. Z- T, B4 G希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 5 q$ @2 d; o: O/ y1 U1 b7 w
呵…… 谢过团长大人~~

- c7 \/ o- Q; V* s
% D7 b* x7 p1 u/ A哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
: `' U; j# s) z6 m8 Q3 l1 j' G团长的朋友都是神,那团长就是神的boss。

6 ]: y4 i" p, Y: m1 `哈 不敢當,我只是個平凡人,, G3 H6 i3 q7 N# Y, n
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙2 M# q* n- c8 L4 Z  K
ZYH
" p# s% `& u8 Q4 mQQ:414734306) z0 @. o9 g! R' R/ Y; H9 v9 f) ~
Mail:zyh-01@126.com
  c5 F5 u6 j, h+ G4 T! S) O7 ?/ V, n! p+ l) I6 n) J# j
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
4 R9 t1 _0 b; j. B4 q7 V再次对团长大人和悠悠哥的无私帮助表示感谢~~

* S# ^4 e% u4 j6 b1 w1 _, @* \不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-26 07:25 , Processed in 1.105469 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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