EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?
) u5 g0 _. u7 T6 F6 N( D# h- hPS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。7 A0 A) ^0 {! [7 y# ~
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~: h2 @$ Y+ f" }9 q( @3 @
这里有相应的模拟器源码,就当送给大侠了~~/ ~# g6 E; s6 Z1 `4 F" @
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 * @4 m0 j9 C) L
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。1 ~7 ?' p# \( M! L) V: u
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
* `2 e3 [0 S! Y( {& X' V/ {$ v8 Z这里有相应的模拟器源码,就当送给大侠 ...

' B7 E7 f6 n. D聲音部分(Audoi Process Unit = APU):( S2 a4 k& g+ P  V" L1 h
.\NES\APU.cpp; m: Z8 o! e) b$ \
.\NES\APU.h; E0 T% G% }2 r, P8 J' p% a5 A
4 [6 E3 F& Y' Q4 l

( G/ c* q) W* H* s影像處理部份(Picture Processing Unit = PPU):' J. Q; T; E5 R8 F/ N: @! A
.\NES\PPU.cpp
4 r: F/ [7 C% W.\NES\PPU.h, K6 }" m% f  @6 K3 {7 Z

% ]3 y2 u8 |7 ]" ?: L  B如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:" S8 J( v+ j2 E5 [7 ^4 ^
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
9 X) E; n5 b& y: p. P//////////////////////////////////////////////////////////////////////////
) B+ ?9 z8 H4 `7 j* G//                                                                      //8 G. z- ^' h# \: ]- T' k/ `
//      NES APU core                                                    //$ ^+ e9 l! D' k" r/ W( P& Q# c
//                                                           Norix      //
# K1 H( H% ~  \. D//                                               written     2002/06/27 //
: Y& O7 t5 Y$ W/ j//                                               last modify ----/--/-- //( t+ O: A) I. H5 f' n
//////////////////////////////////////////////////////////////////////////2 E  x5 _/ A; ^9 L$ b
#include "DebugOut.h"# Q9 b# r  D0 }! S
#include "App.h"
0 \2 y3 u. D  g/ q8 A#include "Config.h"+ h+ O8 a8 O! r- z2 `+ Z
0 B5 w5 k! U  u
#include "nes.h"1 ^+ W0 A' D2 r; Z; @" E
#include "mmu.h"- t8 Z. a$ w& T" R3 H* w
#include "cpu.h"
. u9 a% u9 f1 k5 t# ^#include "ppu.h"; y2 U( U( y' M6 K! M5 H2 [
#include "rom.h"# u' E5 ]6 Y8 _0 n
#include "apu.h"" u' H+ v7 P! H& V
1 w/ L$ v8 I+ K9 c3 P
// Volume adjust
# p: A- l& Q( }5 Z: {8 P// Internal sounds
7 F. G; Z5 J3 Z# i  Z7 @8 I#define        RECTANGLE_VOL        (0x0F0)
! p$ ]' g4 E, k" N5 R5 H- J8 D#define        TRIANGLE_VOL        (0x130)
3 x+ P$ `" a! r) @4 H  {) ?+ V#define        NOISE_VOL        (0x0C0)
) {2 _( O( A7 y1 N$ d5 v& T6 r#define        DPCM_VOL        (0x0F0)
0 D' w9 A7 f  F7 d: G// Extra sounds
" ?+ Y: {/ ?) {2 ?/ K0 Z! {$ @% t4 y#define        VRC6_VOL        (0x0F0)
$ E) {% Z& T. C, S6 h& I! H( ^#define        VRC7_VOL        (0x130)
- J# M& a  o% w1 o#define        FDS_VOL                (0x0F0)
9 W& n) Z$ w4 t0 W& ^; t, u#define        MMC5_VOL        (0x0F0)+ e, v2 U- ]' s' V  A9 d
#define        N106_VOL        (0x088)$ F5 @  a& U' }  `
#define        FME7_VOL        (0x130)
* d4 J4 f6 g7 F) u( S0 m" g- L8 z/ }9 ?
APU::APU( NES* parent )
% B6 \% j( p" U% g& _: I{
& J% }  M, N+ ]4 S        exsound_select = 0;) f- D5 r: p- l& H
. f) f2 i8 _3 [& K) D9 k
        nes = parent;2 W9 p! _, t* H+ _% F8 v7 W
        internal.SetParent( parent );- g+ f- b# J7 I7 S

* ^: _! W9 G' `$ \: V" T: J        last_data = last_diff = 0;* Z4 |: ~' |2 G1 }9 a

: w9 N) c& y4 R, L' J& o' Q& O; U        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
9 l3 s' t5 z% {7 W5 F0 _9 K3 Q2 g" ]. r
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
, K) I) t/ m% U( w# L        ZEROMEMORY( &queue, sizeof(queue) );
' L8 S2 o# W6 m, |* H8 i/ K- w0 D- ^        ZEROMEMORY( &exqueue, sizeof(exqueue) );5 D8 j, s; m7 A% Z

) ?$ m& U  [8 b; _        for( INT i = 0; i < 16; i++ ) {' _; K$ B4 D7 \- F1 _$ x# g
                m_bMute = TRUE;- A& P$ N5 t4 m% z
        }8 Z5 V( }% e, C! p0 {
}" Y/ m" y9 r5 d  Q. ~

/ ]" f3 R* D* q5 dAPU::~APU()0 N+ f. D0 u! x1 x5 G( A
{
7 l* A( D. Q/ v: a}
) d8 b6 H1 p5 n; [# {3 w0 p2 M
3 f& K& b. b/ I& S) Evoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
, s/ K" T4 Q  z9 j8 W{- N9 H% s9 w# {9 q
        queue.data[queue.wrptr].time = writetime;7 q9 J1 `9 ?+ Y" I  i
        queue.data[queue.wrptr].addr = addr;
1 F+ g3 ]  A  {8 E# l0 N: D, c        queue.data[queue.wrptr].data = data;
% m& u2 c& d% G* \6 c5 S7 V9 W        queue.wrptr++;: E2 U8 ]1 Q" r
        queue.wrptr&=QUEUE_LENGTH-1;
) R! k8 V/ w& d+ F+ ?        if( queue.wrptr == queue.rdptr ) {
3 ~* ]( H0 D% T9 u                DEBUGOUT( "queue overflow.\n" );9 h. V+ R' m' u1 L/ D
        }! j) g0 z( }' M1 L
}: ?+ _- k9 Z6 Y* E& R5 @4 N
4 k0 J7 ~" \  t2 K/ h* k
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
/ N1 k: r1 d6 i& e4 K{8 `+ O7 ]0 W# X! r
        if( queue.wrptr == queue.rdptr ) {
) q7 S1 q4 _& T; T% F5 |                return        FALSE;2 Z8 o" H6 T$ u+ j6 L3 m; [
        }
1 b) U5 [3 Z  k& T# g* j        if( queue.data[queue.rdptr].time <= writetime ) {% O) C8 ^4 p  _
                ret = queue.data[queue.rdptr];; o3 Q. i1 f7 T& k
                queue.rdptr++;1 U; G; {8 {9 m% M) ^
                queue.rdptr&=QUEUE_LENGTH-1;( N; ?- H. O, j& j1 |* ~
                return        TRUE;' U% j! `) O- J3 T7 k
        }
- n. N" Y/ @% U* {6 h4 I3 ~        return        FALSE;
! Q8 _7 A3 V) i; {! }: W( h7 O/ K}
4 u0 N1 [# P$ G9 k3 [! z
" V- _9 f" c! G7 K$ Nvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data ); |' h/ r$ x4 L# ]8 n+ X
{6 U5 _- h, ~3 F5 n" q1 t
        exqueue.data[exqueue.wrptr].time = writetime;5 q" [! f3 Z' |
        exqueue.data[exqueue.wrptr].addr = addr;
1 R. d$ T7 S' w4 h        exqueue.data[exqueue.wrptr].data = data;
. C( t; @7 J% l7 P        exqueue.wrptr++;
/ F4 V3 s- m1 z$ h+ L. O  O        exqueue.wrptr&=QUEUE_LENGTH-1;
3 p" |$ b4 `+ t- B4 s( r        if( exqueue.wrptr == exqueue.rdptr ) {9 A& z% c8 S7 C" e- ~3 Y
                DEBUGOUT( "exqueue overflow.\n" );
3 O$ I$ }: A! q        }
' \7 O" L" s6 s2 ~6 A) v4 |# r" [}% Q0 v3 _5 w" B! p" b& b
' l$ _+ g) P2 C& g) s
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
! I" U+ s, A8 Q& a5 m! N' {" |* W{
( q2 n/ @) g$ V0 L1 D; p        if( exqueue.wrptr == exqueue.rdptr ) {& K* d% b+ }( q
                return        FALSE;; r* v$ _# O' C2 y. w7 T% _
        }' g2 W; Y. x8 |% a
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {- s5 R! r6 E" y% h
                ret = exqueue.data[exqueue.rdptr];
4 a: c5 H0 c$ T6 N8 {                exqueue.rdptr++;
/ [, E& `/ c+ |0 G5 M                exqueue.rdptr&=QUEUE_LENGTH-1;
- G  _3 a6 |. N                return        TRUE;2 \1 v- h- O5 M) i" I
        }" @) J6 v  v5 B$ v
        return        FALSE;
- W. ]  p! y- C9 D% D9 F}
' I2 e  J- S6 h% A- x5 G: V+ `
: j" F4 K* _$ w" m& j- \% Ovoid        APU::QueueClear()
* ]. [! P5 d& A0 I{- Z: p: c( ~* [: t5 |9 e, S( X" I
        ZEROMEMORY( &queue, sizeof(queue) );
' L. x# O. N  [) s3 U8 H! j        ZEROMEMORY( &exqueue, sizeof(exqueue) );4 ~9 r( J- Z' J; X: N8 p; s  t& h3 d* v
}
8 `6 h3 z6 H8 X( j; |
, O6 C0 O, n* Z* w4 xvoid        APU::QueueFlush()4 x( ]4 n  g; ^
{
% D0 C+ H5 j8 ~: G2 c        while( queue.wrptr != queue.rdptr ) {/ b5 f) o# t; Q
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
4 K. }2 ]- ?' B" T, C                queue.rdptr++;
' f" _9 h0 h. }* Q( i2 H! W                queue.rdptr&=QUEUE_LENGTH-1;* w& B$ m3 E# z
        }. _6 s! @# _. S. w6 Z

- i* E( _9 N0 m# v8 |0 X3 i# t        while( exqueue.wrptr != exqueue.rdptr ) {
% a! Q7 O" `: n  [& b5 ^                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
7 D. N% q9 M0 ^4 A% H                exqueue.rdptr++;
/ G3 |7 p" \1 x( |& M                exqueue.rdptr&=QUEUE_LENGTH-1;0 H6 U- F  z+ L5 v
        }/ X0 y% J% L2 O/ B% B
}
+ [$ v$ F! ~# |
' ^* c4 s$ H) @+ @void        APU::SoundSetup()
& c9 f% z' D& M; a% R. F{
, A+ _$ l' F  Z. x        FLOAT        fClock = nes->nescfg->CpuClock;! r2 p; r  Z4 |& y6 \1 u! h. W
        INT        nRate = (INT)Config.sound.nRate;
7 v1 X8 Q5 l* l$ |; S        internal.Setup( fClock, nRate );; {( v) Q- c% p0 ], N6 W
        vrc6.Setup( fClock, nRate );
% W5 W, T6 C" K$ N, m        vrc7.Setup( fClock, nRate );" M) t) C( A* _- R# U  D: t. P; f; \
        mmc5.Setup( fClock, nRate );- }7 q: |: F5 ^3 ~- _
        fds.Setup ( fClock, nRate );8 w/ [! V' a, l2 ], G
        n106.Setup( fClock, nRate );9 @# z+ P) p! ]4 I: }
        fme7.Setup( fClock, nRate );
2 T# s4 {2 E( l4 \% v6 Z}" M: w7 `2 G" u+ U, v2 ?2 w" J
1 ]: F8 k# W0 e+ \. S- a
void        APU::Reset()1 v9 i2 F  N- X) C7 C3 _; p' s
{1 b) N% a; m6 t' o1 e5 ?& N
        ZEROMEMORY( &queue, sizeof(queue) );
0 T9 P3 n3 @. [( v) Y        ZEROMEMORY( &exqueue, sizeof(exqueue) );
2 s8 _. Q/ h$ B$ |0 N. h; i7 n4 I
( i  h; P3 |" \4 D        elapsed_time = 0;$ _' A% {( y+ ~  j6 n$ n4 P
3 N/ k6 q. w. R$ K; s* t
        FLOAT        fClock = nes->nescfg->CpuClock;
% A& o) D; V" [% t) _: R        INT        nRate = (INT)Config.sound.nRate;  P* m+ _2 |. ~7 m% _+ W. A
        internal.Reset( fClock, nRate );; |: e1 V5 H! t+ e7 X! O
        vrc6.Reset( fClock, nRate );
- n* J, w  H1 t" n7 W: O/ J3 h        vrc7.Reset( fClock, nRate );
% d. p- m( `/ U  N6 _4 V        mmc5.Reset( fClock, nRate );
: U& I# X# @8 M; o' X        fds.Reset ( fClock, nRate );) c- Q: G6 f& m& T
        n106.Reset( fClock, nRate );* w/ u5 n4 ~: D# l' h1 i
        fme7.Reset( fClock, nRate );' x# j3 h' m  X% Y9 V
, a5 t! }9 C. e1 R
        SoundSetup();1 V+ t. k" S" B
}
% u. w7 X' O* x4 A( B8 P0 m9 l( ]+ ^( |: a- k7 I. ~( [
void        APU::SelectExSound( BYTE data )/ b- [2 d; d9 r
{
5 m+ t5 }$ V; ^; z8 F        exsound_select = data;) w0 s  X. v. ?
}
& R- W2 n  ~  V4 {. p5 `  \
4 w9 x' a7 V3 f: s/ d; gBYTE        APU::Read( WORD addr ): ~+ t9 f* N# _, ]" a' r* V# ?  s
{) y. Z: ~& z" k9 g8 w" c
        return        internal.SyncRead( addr );
/ W$ N4 y+ x4 b, n% i# t! T}
: L! S! t5 O/ W/ s
2 x. h, n! U, E& \. r- svoid        APU::Write( WORD addr, BYTE data )0 ^& I% V! @& V" t& F
{
9 L! E; t6 l# r& N) I( \' X        // $4018偼VirtuaNES屌桳億乕僩
1 C0 I  G* y/ [4 Q        if( addr >= 0x4000 && addr <= 0x401F ) {! Z4 h% l9 T. @
                internal.SyncWrite( addr, data );
, S" L/ B+ D$ B6 z  x                SetQueue( nes->cpu->GetTotalCycles(), addr, data );+ l, w( v, ]. _6 Q8 x
        }
6 U  o' f! c5 U- c" ~# L* {' ~% v}
: H1 m& I# \6 ^. E+ o7 W( O0 T0 H" ]* s' |; ~3 D- e) P
BYTE        APU::ExRead( WORD addr )* E7 o' |" _- w& R% q7 D8 d3 `$ U9 l7 r
{/ U! l. P9 ^. o- b* x/ @
BYTE        data = 0;
1 S# u9 f! C( s1 m" [' g6 x* `- v0 K' n8 `6 Z0 r
        if( exsound_select & 0x10 ) {, i0 M- Y. X, D/ U
                if( addr == 0x4800 ) {+ C2 t! t- @* O' _% W$ J( O" Y
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
) _3 X+ y( h, A                }1 t4 P$ B( O! Z4 |/ {
        }
* z9 K) A. m9 m! y        if( exsound_select & 0x04 ) {
* O# Y; O' I1 m3 c* R0 Y                if( addr >= 0x4040 && addr < 0x4100 ) {& k8 F3 _0 ^& ^7 i: j: A
                        data = fds.SyncRead( addr );
2 n" g  B  u1 d: Z1 o                }
$ A0 {, A4 |! z5 [        }7 X$ t- ?) v" O& C1 B4 h
        if( exsound_select & 0x08 ) {
0 U5 R6 N7 M$ `1 k, f, h1 Z                if( addr >= 0x5000 && addr <= 0x5015 ) {( ^8 f' }( P5 J
                        data = mmc5.SyncRead( addr );
5 Y' V& b# U& U; x5 ?7 e( `( W9 y                }2 k& S; x3 C/ x6 X) Q
        }
, r3 w: @8 P5 \0 M; H  ?: b
" n. ~) W. d6 ]/ T2 v( I        return        data;
6 z5 h* B& u, g1 x, m}
* c$ _( f0 `2 k3 y9 K8 z2 N7 I* a7 x  s, j
void        APU::ExWrite( WORD addr, BYTE data ); H% [6 e! g0 U; i
{
# k) S! g, W6 x% s, U1 Q        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
; ?* {* j) P+ @! B- S
/ }: ^5 z( L: `4 q        if( exsound_select & 0x04 ) {
6 l/ A; z8 Y# L                if( addr >= 0x4040 && addr < 0x4100 ) {. K- h; r% ]2 P, P' i
                        fds.SyncWrite( addr, data );. I) c6 y4 Z9 p$ p( a
                }9 W( v3 l" ~; A# {+ ^
        }
" Z% K4 L; o9 P. Q1 u8 x3 T0 V! [8 S4 Z* c: ]! v* ~' N
        if( exsound_select & 0x08 ) {
8 ?, C$ `( }9 G9 u/ f! X# u/ K                if( addr >= 0x5000 && addr <= 0x5015 ) {
/ o  c+ h# O9 ]5 ?+ ?                        mmc5.SyncWrite( addr, data );
% A( j. ~0 _& Z: e7 Z7 l' _                }7 P5 R- K  C) g" F( R, f( k+ ]) }
        }
5 k+ y+ Z- L7 g& b}
& v9 r5 D# g$ D8 }4 s2 {8 C: O/ E8 y8 u5 N) b
void        APU::Sync()
0 l. {) W7 D  q! O{' G, s. ]3 F# y- x. C# j, \6 A. K1 T
}
+ c' S/ L2 c& \( X- C
$ X# W: q2 L' G! A1 r+ Lvoid        APU::SyncDPCM( INT cycles )
' p) Q0 R5 E8 y9 g3 A/ E2 W{, S; q. w, X# l) I  V
        internal.Sync( cycles );
% {8 ^" l! G" n! @+ v* s3 i- ?! l* i* e, W3 x# m; A8 y/ I
        if( exsound_select & 0x04 ) {/ Y/ @  u* H3 z+ Z% S
                fds.Sync( cycles );' ?: A) h# d9 _; ]0 r( M, z9 h
        }0 {3 P$ P* o$ t7 f
        if( exsound_select & 0x08 ) {; K% c& `1 X) |, I3 u+ ], |4 w2 _
                mmc5.Sync( cycles );; @; H) Y* D1 O& r2 k
        }$ N$ G4 t' s  V* Y6 y5 C( B
}! X1 z, }( s! C3 _' P/ N
+ d$ W0 {$ w& [) e
void        APU::WriteProcess( WORD addr, BYTE data )' {& A; y* S! }
{/ p' f& y* H: H/ u" S: P0 [  B
        // $4018偼VirtuaNES屌桳億乕僩
9 `: X! a6 q$ j& f9 W        if( addr >= 0x4000 && addr <= 0x401F ) {. s2 f: [  \3 q  K# z
                internal.Write( addr, data );. D0 D9 b' g- l' R) V
        }
* s  z7 S( V" y( `}
& ]. x  m  G4 @" i! H: H6 I, W* r( o% ]- N( I
void        APU::WriteExProcess( WORD addr, BYTE data )
; f$ p  O3 I! Y8 ?5 w; }{. Z" L* A8 c0 L2 _' A- J
        if( exsound_select & 0x01 ) {
0 U9 I/ [1 e/ ]( C8 f0 |5 B                vrc6.Write( addr, data );, I$ X5 |5 i* B) k  \0 \1 o  q
        }. l' _; A* x; o8 R: ?3 T! e7 d$ [6 t# z
        if( exsound_select & 0x02 ) {0 o  H. ]) w# O" N& m8 k
                vrc7.Write( addr, data );* H- w3 y$ y7 y& w) ]3 O) H
        }3 H; g- I1 J3 x7 q
        if( exsound_select & 0x04 ) {7 B% ~+ l9 @! s( N) O, V
                fds.Write( addr, data );- \+ v. B8 S& j3 R& Q: ]
        }% R; D8 U0 l; a! A. c+ ?
        if( exsound_select & 0x08 ) {0 [* p" r! \1 N+ f9 L7 R* B4 p( ~! \
                mmc5.Write( addr, data );
) u8 @) e6 w6 P1 D6 l, N        }7 r1 K9 {! k0 R4 C
        if( exsound_select & 0x10 ) {
+ I4 R: e* Q- w* S" E                if( addr == 0x0000 ) {% [$ a6 J1 Y5 `3 w
                        BYTE        dummy = n106.Read( addr );& `2 V& F  c/ S) m  d
                } else {1 h' s4 w+ w( b8 F! x/ |
                        n106.Write( addr, data );+ E1 T3 w! m2 {$ e/ z  o. G" S
                }
2 x* g' }! r/ {7 x        }2 x6 q7 E* u- p1 Y' r- A$ {
        if( exsound_select & 0x20 ) {
% `$ T  }) s% M4 n5 W) C6 h                fme7.Write( addr, data );) j. G7 G/ J8 w
        }# W. D# z' R9 Q+ M) q
}! T" o" B0 a( ]+ x

/ b" [9 u" F' J& B! nvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize ), z1 v" G! m$ c0 [) M4 @. h, E1 k
{8 K" }$ i# k4 K8 J5 A
INT        nBits = Config.sound.nBits;
7 i3 a+ i5 ~6 R' [9 S7 X" Z. HDWORD        dwLength = dwSize / (nBits/8);( f0 i# w$ r4 `, D$ J+ \
INT        output;4 \( A' c- n2 i& ]
QUEUEDATA q;
, d* `6 K+ o$ v' ^8 m; H# UDWORD        writetime;6 O, G- F0 [+ H! d+ |0 o

/ N  Y7 ~1 x  W, b% v+ VLPSHORT        pSoundBuf = m_SoundBuffer;
- O2 p( w, w9 {: BINT        nCcount = 0;
3 |. i6 y5 @( s7 Y; [, [% j+ @
: v6 b$ Q5 F. l# IINT        nFilterType = Config.sound.nFilterType;
; N" s4 n& O, W/ B7 K) b
$ l6 Y9 S1 ?. N        if( !Config.sound.bEnable ) {( L  B/ D( U9 e  r
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );: X1 h" K; R6 F9 O6 p
                return;
, C# _0 e' q0 J  I1 ]! b5 [8 k% v6 A& t        }. P/ j0 @  \/ }  `! [2 E

9 T: _4 g  `6 S6 V+ t7 ~        // Volume setup
! i" q3 x7 Q- g$ {2 M+ F( y9 T" X        //  0:Master1 n) [' q  ^# Y5 n5 q4 l  z
        //  1:Rectangle 1& D- x: t6 A" \& ^8 k8 F
        //  2:Rectangle 20 |. y& L0 z$ }1 Y7 [$ U
        //  3:Triangle
" q7 b* k- D5 e9 v, t/ [        //  4:Noise7 r- \4 u  |2 G
        //  5:DPCM
: [" J: g- H# P' N        //  6:VRC6
  m- F: g3 z2 o/ n6 \6 @2 b" q( \% S        //  7:VRC7* c* P! ]( |0 @6 K/ v7 g( H# a. F* l
        //  8:FDS
3 t' n- @; ]. S( r        //  9:MMC53 _% X6 Q5 `, E1 V1 W
        // 10:N106( c: p: C; {/ f' R; c5 x
        // 11:FME7
; D( t9 V" Z+ t0 j        INT        vol[24];/ c  b3 f2 F6 c4 b1 B9 J. z
        BOOL*        bMute = m_bMute;9 l! J+ h' v2 p& _% x
        SHORT*        nVolume = Config.sound.nVolume;7 |8 u9 p6 G! i& _6 E+ k+ Q; _
. M9 s: N7 O7 _; R1 k. u3 @* w
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;' _+ \  i' o. I2 t* W5 o% t

& R( w: z0 J3 {2 A& h/ g        // Internal
- C& \) k& l  H* g( W0 m        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;) n, a6 L! q* u- [! @3 U6 F
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
- a; m: R0 g/ p% T/ o        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
( q8 F; K( v. W% \7 n1 w+ b) C        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
. F  h! X  i3 P# o& E        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;$ o8 N0 H0 N( ~! a9 B5 l  V% h

; C' ]* n- o4 t4 ]' j' Q  O! o        // VRC6
) k1 p8 w9 ^- o* N* }        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
+ N' s% \, @2 p        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
$ K4 i. U9 L* z( h6 s5 y$ F4 b! g        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
* {) \) @0 k6 ]+ O7 D, x) Q
! j& \- K  u6 V0 ^, C9 a7 a        // VRC7
9 I; ^  v! U  L* s& M        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
* `0 f0 N- J, X- R) w' Z$ [: m) K0 y- Y4 s( x+ R
        // FDS
& f9 v6 f+ R) ~& q1 V# L        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;$ D; w) E5 R. \8 `5 T& z8 V

; T% [* g3 m( U' P; }& Y        // MMC5
! H5 J/ B  a- O        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;9 @- F- l6 W9 p
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
8 D4 }) ]$ q. g, h/ a        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;1 M, d1 Y6 `- u, n) X! ]
7 P* D, l, c& n2 X& M7 m1 t/ [
        // N106) c' k$ w" g7 g  p! M' n
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, a9 |5 c4 l0 [* A/ L        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- K, m3 Z- L5 x. e. @$ U* u
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;2 ^' ~% c& p$ U" A% h
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;7 u- ^% t  O  @, y  B* N
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 ]. s( @% T) N; k+ r; m3 l
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
) ]9 `9 C: ?( K8 d8 g        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' A9 f9 I6 O0 t
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ F- u9 l  S- ?% f  |$ d" J
6 l, ~" w  b3 f. [7 n9 x3 ~0 |! w, |/ j
        // FME78 A  t% l" i, o3 P# @- J
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;5 T5 y8 a' ?, u; ~. v! o: j
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
; g$ O; I2 `; R        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
% A5 N' ?+ }; O. C3 J
  \2 m& q4 {& g//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
0 |- q, T( D& Y% E& F1 |0 h        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;! C" ]. L( ^" `& D, f4 c

6 Q( W& k6 Q- i- `        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
$ r: K6 T. F9 t- P8 w        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
7 E# N$ h# r  Q& s! n2 s                QueueFlush();+ f$ Z2 ~+ ?, u' ~& G
        }
+ j' N% h5 h" ]' [2 S* s# T4 G& D- H# y* V: A
        while( dwLength-- ) {  Y  ?% U8 G2 |! ^9 I
                writetime = (DWORD)elapsed_time;$ f* B5 p) l+ k- w! b) W& w/ v
0 s5 l' Z- j9 j- d, q
                while( GetQueue( writetime, q ) ) {
' [2 u& X! h( {2 w3 A- r                        WriteProcess( q.addr, q.data );) g/ p3 I8 B" v: u8 N6 F
                }
- e1 A) n# E' o5 S9 |5 n3 e9 l1 n0 `
                while( GetExQueue( writetime, q ) ) {* O; D# T* d' O% G9 L. e- x
                        WriteExProcess( q.addr, q.data );  r2 d4 S, D6 u$ F
                }
) Q8 Q; t# ?* ?1 w
& U2 `  A! w+ v                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
& e8 C1 u8 m7 y& v  }- L" t9 }9 T                output = 0;
. o# i1 @% \$ A5 |- D+ j8 c                output += internal.Process( 0 )*vol[0];# @- N* f- X( C- W6 _, @9 u
                output += internal.Process( 1 )*vol[1];
  ^9 `& l, ~$ y                output += internal.Process( 2 )*vol[2];4 U6 J) Y1 r/ z) T7 R* p) v
                output += internal.Process( 3 )*vol[3];3 B; D) G" F( q% F8 o- I  ^
                output += internal.Process( 4 )*vol[4];: A4 q) P6 V3 k  X. f' n0 l- [% i
, T8 ]. i. s. u
                if( exsound_select & 0x01 ) {0 H  j3 n1 b/ m% e+ F9 I" k7 S/ K
                        output += vrc6.Process( 0 )*vol[5];/ [7 r7 }# c# O2 x% e
                        output += vrc6.Process( 1 )*vol[6];* j" N9 f/ c' Z2 P3 C. s* ~$ i
                        output += vrc6.Process( 2 )*vol[7];4 @  u; U5 {/ A% s* s4 r
                }
7 k( ]5 P  V3 E4 R/ b                if( exsound_select & 0x02 ) {
8 S/ c) O4 ~0 B: @7 u' ?                        output += vrc7.Process( 0 )*vol[8];& q- h9 Z( X" j) _
                }9 s# w( d: H( @) B
                if( exsound_select & 0x04 ) {
6 g5 z9 S$ o1 x& C                        output += fds.Process( 0 )*vol[9];0 P( I3 M" u0 o$ L2 z
                }! _0 g8 B. I/ B5 H5 A
                if( exsound_select & 0x08 ) {
% x+ p4 l7 e' Y                        output += mmc5.Process( 0 )*vol[10];; e7 n8 P7 A/ g* k0 @# _
                        output += mmc5.Process( 1 )*vol[11];  c8 H* Q$ E1 F" |6 S) k% K
                        output += mmc5.Process( 2 )*vol[12];
, G6 S- R6 m3 Q% ~                }
+ r0 D! @: `9 e# r# e5 p                if( exsound_select & 0x10 ) {, Q. f; |% O5 B; ?/ Z5 E' _. ^
                        output += n106.Process( 0 )*vol[13];# s+ I: H* G' ]$ E, O
                        output += n106.Process( 1 )*vol[14];
2 k  l, b; h( b( A# ^( v                        output += n106.Process( 2 )*vol[15];# i' T+ [+ [( d& r1 D, a
                        output += n106.Process( 3 )*vol[16];
2 K3 d" B4 F7 |. f, L                        output += n106.Process( 4 )*vol[17];
( e& {# S8 @1 C1 r- Q                        output += n106.Process( 5 )*vol[18];4 P' J, r  g$ m- k# M$ X. }# }
                        output += n106.Process( 6 )*vol[19];6 ]" [0 B! _! k5 S8 d5 H0 O
                        output += n106.Process( 7 )*vol[20];
4 n+ N2 E0 b1 D& v* g                }1 f) h5 ^7 z2 t1 }% a4 {) H
                if( exsound_select & 0x20 ) {( c$ o! e5 o( _* D; q
                        fme7.Process( 3 );        // Envelope & Noise/ g" D5 C" v6 c7 G6 |, D/ [
                        output += fme7.Process( 0 )*vol[21];
0 V/ ]: t" R8 L$ B, V" e! @' v                        output += fme7.Process( 1 )*vol[22];
: J9 s; L$ M) |                        output += fme7.Process( 2 )*vol[23];' k2 y2 F5 A7 W6 N
                }/ B% X# p# N1 s  J  r. k! n
7 u/ \1 q4 D/ A! N4 _
                output >>= 8;* f! h" w$ z4 |' Q1 A% x
: \4 b: g: A& M5 A
                if( nFilterType == 1 ) {4 G  I1 ]& F6 {  q* w
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)  E, Z, i9 G- V, j# ^
                        output = (lowpass_filter[0]+output)/2;. y1 \4 _, u' a; d, W
                        lowpass_filter[0] = output;8 m$ R6 y4 p) o( M* b$ Z* G
                } else if( nFilterType == 2 ) {
" n  H9 m+ w- V% \                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1); g  |3 w5 T$ a4 L5 |2 ~
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
$ Z; H0 |% ^; {. F+ {- z/ R4 a                        lowpass_filter[1] = lowpass_filter[0];
! f" [* [' A' _; F' W                        lowpass_filter[0] = output;
  f' I2 z6 y4 p2 H) o% b                } else if( nFilterType == 3 ) {' i5 F; g! \9 @# F* h
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)4 g; g- n1 e5 y/ e
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;- Z8 [/ y, E+ b2 \! o
                        lowpass_filter[2] = lowpass_filter[1];* l. T# P! k3 L
                        lowpass_filter[1] = lowpass_filter[0];7 ]5 o% s( n0 g6 a: G
                        lowpass_filter[0] = output;
/ a" n) x1 y% H0 J4 I  N, _0 }: @" ~                } else if( nFilterType == 4 ) {
' N. M' v! Y' v                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
( R  f. c$ p9 t+ @: R+ e                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
" C& N* d/ z; p                        lowpass_filter[1] = lowpass_filter[0];
; h) v. v7 n! I. _6 b- v3 A% b7 E                        lowpass_filter[0] = output;2 K: G* ^# r4 P% Q: v) L5 d. F, _
                }
  Z6 J8 Q" s7 N: a
  n( H0 q' [* W& b8 }8 z7 @#if        08 _" w) u, s5 f7 R% @- u
                // DC惉暘偺僇僢僩# P/ R; Z6 v; z* |) |( ~$ W
                {2 `+ p& n* B% T- `$ L
                static double ave = 0.0, max=0.0, min=0.0;0 p: k  h; \5 Q8 K
                double delta;
5 ]( P9 x! ^5 t6 ?                delta = (max-min)/32768.0;* Q0 x* |% t2 o! `+ Y8 B* V' L& l
                max -= delta;
5 H7 V2 l8 |6 b+ }1 C- Z/ m1 S                min += delta;
- O1 ?0 ~  i3 a( {( V4 J5 q+ o                if( output > max ) max = output;
  R2 d0 o0 o  \3 Y7 n                if( output < min ) min = output;& O+ n9 W  H4 y
                ave -= ave/1024.0;$ t; u) K- c( `
                ave += (max+min)/2048.0;7 `/ u, o2 y9 n1 X7 y
                output -= (INT)ave;! ~' k+ f6 g4 N/ L
                }+ t1 e/ @+ C. ?" u6 P8 O8 G
#endif0 E0 }5 w5 T) w/ B* j6 s- p  Q; N! C
#if        1
! z+ E" d$ k& n) d3 y" w1 Z. w                // DC惉暘偺僇僢僩(HPF TEST)
0 y$ O5 e% u' z2 H- f# k                {" U) c8 R( J8 k$ b7 x! g
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);1 [4 t7 |" n' A" M  d% H
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
) B4 w  k3 Q2 {9 I' q                double        cutoff = cutofftemp/(double)Config.sound.nRate;
/ ^  N) H7 n. W* x  Q' M; R7 u                static        double        tmp = 0.0;
" t$ ]$ V# k- ^1 F- h2 c3 _                double        in, out;
4 C" g3 O9 R$ Q0 D# }6 N* ?& d1 W1 U3 T3 z! }
                in = (double)output;
0 u  i7 S6 Y. q                out = (in - tmp);( ]# G' v! {  k* z" P
                tmp = tmp + cutoff * out;
: g8 a5 \+ p' _+ p4 x7 ]9 B$ P9 q& y+ u# c" g6 M
                output = (INT)out;3 d) l" x$ Z8 T
                }
4 g/ {$ ?1 Z4 X6 T#endif. n4 Z: @" Z2 j6 K( I
#if        0' g* u& V' e8 A/ C# F+ \
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)& i  ~) i) g% J0 E# L
                {
# _# ]4 T1 E; V) }                INT        diff = abs(output-last_data);
* [9 i- M5 P$ h$ B+ q% ]                if( diff > 0x4000 ) {
1 q* L% R3 E5 d( v                        output /= 4;
* |! S* A% v6 o) J9 h1 O. m* @0 R8 A8 }                } else
7 U0 ]6 E7 }+ Z0 U) x- K                if( diff > 0x3000 ) {
0 b0 S8 _# T2 g, D: u- H) G                        output /= 3;9 v; z& {/ a4 b6 d6 N! Q4 C
                } else9 k! p. ~2 {, N
                if( diff > 0x2000 ) {
* Z: H: C0 M: o: `                        output /= 2;, |1 q$ S$ H9 K, y3 U8 h5 o3 N: ?
                }4 w. i( |5 d1 q, t
                last_data = output;
- ~& a& y% Q) E+ ?                }
8 @" a0 s9 x4 l! O1 H% D#endif
$ Y% v* ]3 p; G# m3 Z0 X1 d                // Limit# Y1 q7 m2 [# T5 m
                if( output > 0x7FFF ) {
* J* m! p6 R: T+ s8 k                        output = 0x7FFF;; ~" R) a! s5 h6 a' ?
                } else if( output < -0x8000 ) {3 a, }; B7 M; V1 q
                        output = -0x8000;
  I; n- `" M: k) m8 y                }
8 M$ O$ u9 w9 l/ }* X% X( O* F9 O/ q6 ^5 n
                if( nBits != 8 ) {
  Z/ j4 a) b6 f2 w" F' z                        *(SHORT*)lpBuffer = (SHORT)output;
' y, f! V" H: w4 O- ~/ L: G                        lpBuffer += sizeof(SHORT);
# i$ H* K) X% M3 |                } else {
2 ]6 M6 c. K. ~3 E2 D                        *lpBuffer++ = (output>>8)^0x80;
$ C; N2 D- I& \8 T4 o                }$ L; ?# R/ h& ^+ {

/ S, G+ t" G- x* I' m                if( nCcount < 0x0100 )
3 n; Z+ m0 X9 I6 w$ A                        pSoundBuf[nCcount++] = (SHORT)output;
& g$ q, Q( U+ S" S
& ^1 a. U, F, \3 g//                elapsedtime += cycle_rate;! @% ~4 m9 I8 n; y; q5 `
                elapsed_time += cycle_rate;4 i" k( @. H7 T! ]# p. t
        }
, o+ Z  _% f% |: [  b
3 x1 b/ J0 N9 S9 [& C: Q7 b. L' ~#if        1/ |, n, y  s, v3 s. H. b
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
& d3 b8 A. U" g9 ~- F* g                elapsed_time = nes->cpu->GetTotalCycles();" \0 o6 R# }8 r
        }
& z/ V4 z' H! I2 P/ ?0 [3 a& v0 ^        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {6 J+ g" I# K+ L$ C
                elapsed_time = nes->cpu->GetTotalCycles();" H; L) G: h( q, B  A( [$ o9 G2 x
        }
2 h( L; X+ E* k#else
" L! t% x. n* q1 h        elapsed_time = nes->cpu->GetTotalCycles();
' Q0 u: }9 X: {0 o) {#endif
% W/ t5 F& w! c9 \% s3 ]5 k}
' l  t( J* m( J
' e( c% ~4 M+ B" g// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
; ^* _; m) [1 NINT        APU::GetChannelFrequency( INT no )
0 J! o3 ]+ [- d  j. H{. b9 J- N$ M0 `$ o5 v/ ^
        if( !m_bMute[0] )
6 N6 |2 @$ @6 A2 i: q                return        0;: G! e- T! T5 o6 e! X7 t

9 u' e, }. u, N. z: j        // Internal
( ]" f+ H5 V5 l+ Y* H2 d        if( no < 5 ) {
) j4 s  B& J4 ~0 U, l  l! R4 H                return        m_bMute[no+1]?internal.GetFreq( no ):0;7 ^) Y! s* b- j$ t
        }
. _. {% k3 t1 V        // VRC6
+ q, B7 o8 ]  C; H  I        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {1 B1 y6 C( S/ m: h3 j
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;3 [5 h4 t, d, t0 y0 U
        }& |; @& t" b) ?9 \" }
        // FDS! l3 ]- z2 y/ V0 |6 t% h* P& Z# x* }
        if( (exsound_select & 0x04) && no == 0x300 ) {
: Y: u( u- V3 c/ ^& h( b: p0 O& A, b                return        m_bMute[6]?fds.GetFreq( 0 ):0;) p5 T& r6 O2 @9 ^* G% p, d2 e5 i
        }
$ ^; d1 H/ V& O. c- e        // MMC5$ s& }2 ]9 L- X& V8 C' ^
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {$ \- W: ^9 e! |: ~
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;1 I1 ]* s' M8 C: M
        }
; N7 j( O* A6 m$ y        // N106
; ^9 r' c7 e4 Z. L3 l  }        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
; C* j6 U* G" \- w# A                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;( y% [% n8 b" s! }
        }
0 ]$ e& n4 i; ]        // FME7
6 @( }4 e; U8 M- E& D        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {/ m" q7 b; q5 x& V
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
; R" W4 }0 V8 U0 P        }
9 p. t( g7 U# c8 |! p8 g        // VRC7
0 A% J5 a, R0 m3 J        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
5 ]( P% U7 |! m$ ]$ ]1 x                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
& T; [3 W" L' L6 w        }
5 i+ X" q7 w' Z1 M; E% d9 T0 T        return        0;/ A, c' L6 D- A3 h9 }, R" q, J0 @$ x% E
}
, Q: y' u, u9 H/ E! C3 \5 i
' f: Z6 R, J! q4 s. C) P// State Save/Load
% @6 D  C5 ~1 G% O% a4 Z  e1 K! W" zvoid        APU::SaveState( LPBYTE p )
; @3 c" |5 w7 Y6 d5 n- l{
6 R# I2 ]% H9 Q( j* q2 I0 z( R#ifdef        _DEBUG
+ {$ x/ D6 q$ `) P5 l! bLPBYTE        pold = p;) g; f- [# Z& \. E! p% X
#endif
4 {+ P7 s) t& a9 H3 M- W) m+ X0 R7 h+ C9 W# l6 g1 d: d) N
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞( ^- H# L; ^( v4 G/ c/ N1 A
        QueueFlush();
1 R/ N+ f. I) x5 b. {) G2 R+ K* M3 w0 D5 S3 b, I' u; ]0 `
        internal.SaveState( p );
! z  [1 W5 b' Y% f7 N  u- N% p3 T$ [        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding/ p2 |8 C6 v7 s% U9 b

. U; p% S# t  A4 s9 G: t7 L        // VRC6
( F0 q5 t+ |# D8 a& k+ O        if( exsound_select & 0x01 ) {8 v  @. y7 b! C& f( A
                vrc6.SaveState( p );. {8 O" @- e; C3 C* l* s
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
' j- Q4 A9 E  x- m0 P* ]8 ?* \        }/ r2 k2 P1 b  H- {  P* c8 O2 ]
        // VRC7 (not support)) F6 C2 v2 N* T1 l' |$ h0 v
        if( exsound_select & 0x02 ) {9 l- O/ C2 o9 ?: K. d# |8 h
                vrc7.SaveState( p );. I7 u: y4 D+ w- \7 j, Y
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding$ R: H# N9 U+ Z0 w
        }6 _9 o2 U# l' @& ]- c; P; l
        // FDS5 m6 t6 S. ^  ~- P% r
        if( exsound_select & 0x04 ) {+ E1 m& T9 t! [4 D7 ]  ]/ ]( z" {
                fds.SaveState( p );
% i- W* [" S0 i. s- c7 N; S# e                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding3 ~% n5 z. b. J5 d  }
        }9 n) ?% ?5 U5 t- n( e2 a" \1 E
        // MMC5
7 b. D  p' |$ t" \! q5 T        if( exsound_select & 0x08 ) {
; c% k. z5 G, [. ~                mmc5.SaveState( p );0 ~% Z$ H) O" Q. c
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
4 o  h! A* d0 b        }7 w( {8 A% e; P3 U& _
        // N1064 Y/ `- T; j9 _8 `; X
        if( exsound_select & 0x10 ) {
  D2 O: d' i# c/ c$ A7 k                n106.SaveState( p );
, c* ?* u- S1 f, `                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
% \9 W- F* u, X; Y8 j& k: L0 ]5 S        }
/ x3 {9 P0 \1 o1 O! r' ], Y. g        // FME71 `6 |1 g4 p5 q) B' B  y0 D5 z. `) d
        if( exsound_select & 0x20 ) {
) A8 j; ?" G. S/ p: \! M$ P' r1 }- O                fme7.SaveState( p );& x$ c1 b$ Y. G; c( z, _7 _  O' f
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
% e, d# i- u" p( S        }9 j5 P' s0 \( O. _! S8 y* S

; I; }: m2 `) {' {#ifdef        _DEBUG2 d& \. E0 M) f6 K
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
, N% k. z$ o. V#endif' L8 E# L. `! v* Y
}2 h2 {) r7 }( h* @7 T

: f4 ^) k( O& G' ]# nvoid        APU::LoadState( LPBYTE p )" f( \4 k# H; i- `' q% L1 J
{
! p3 q3 m" I: V3 G+ P        // 帪娫幉傪摨婜偝偣傞堊偵徚偡0 S% O* z% [( N% G; z; h
        QueueClear();0 ~% J0 L, i) o: w4 s2 k) h- F
) x$ H9 m2 t+ r6 p/ T" Y4 b
        internal.LoadState( p );  G' j+ P2 R2 R/ T) ~
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
. z- y1 E+ g8 y- H# T% U
+ E3 t8 S+ T, f3 t" u5 V% I$ [; d  J        // VRC6( b/ Q2 h; a3 R! l% i9 H
        if( exsound_select & 0x01 ) {
* q3 e2 N3 y! p                vrc6.LoadState( p );# A2 C* _6 W' ^! d' i( Y/ |
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
( s: u5 K% F/ `( X4 ]        }9 h/ i' r. ~5 x/ x( B- e8 b
        // VRC7 (not support)
2 }6 _& J; F+ S1 E+ Z+ e( ~' e6 {& D        if( exsound_select & 0x02 ) {$ E4 a* V, d" M0 {
                vrc7.LoadState( p );0 F4 J; M* R1 m
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
- N# r  w( r$ h5 I; V9 e2 L5 ^# J) a        }" I9 i2 L' j1 d# t
        // FDS
% n2 r, [6 c7 B2 @) B        if( exsound_select & 0x04 ) {" V. l/ q- h( d
                fds.LoadState( p );! x- _4 x9 _1 e8 i2 n
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
8 Y" P$ f/ T; w5 a; o% a        }7 G. O7 ]) t, o0 h- w1 T
        // MMC5
7 Q. ^& r* O4 B& I% X        if( exsound_select & 0x08 ) {2 D3 ~# |1 A" F' z# m1 y9 q# i# Y  R; d0 {
                mmc5.LoadState( p );
+ |3 f) F" C5 s' Q  x$ }                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
/ L" R6 g3 e! z        }% U; X: j0 M2 i0 l* L
        // N106/ I' d' I5 \: @; e5 ^3 c
        if( exsound_select & 0x10 ) {* v; B5 O4 b* ?" H( A  |
                n106.LoadState( p );
" D: O: l7 r+ N: G' R7 J                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding/ I1 P2 K, z" O  O# h, y
        }. k9 i/ j7 C& [1 @; ]
        // FME7. }; Z4 }8 B+ e+ J4 T5 F
        if( exsound_select & 0x20 ) {
% d- v% Y6 ?) w- m0 I/ B                fme7.LoadState( p );
" v, @1 h' {  }. w' {& b, O+ A                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding, [6 i  a# K/ |
        }3 y) }- E: H+ u- e# |' M* a4 X. U
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
$ c+ \9 ]( m5 a4 U. A可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
% l0 y; a2 P( t感激不尽~~
, f5 t5 u& N- F7 V) B; ?
恩 我對模擬器不是很有研究,% {! f, r3 G# G5 y& f' c$ L3 j
雖然要了解源碼內容,可能不是很困難,$ {  y5 U: |! P$ U+ S) m
不過還是要花時間,個人目前蠻忙碌的。
4 A7 Z" i' v9 G7 t" C5 V8 G
% X0 X) n) q$ `9 ?給你一個朋友的MSN,你可以跟他討論看看,
0 L. F" N5 _' @& e他本身是程式設計師,也對FC模擬器很有興趣。
3 {6 b+ n3 F8 p! y: q( C+ g% w0 g$ r7 ^1 d0 @
MSN我就PM到你的信箱了。( s; D9 u& e7 S0 _8 m

3 U# K0 Q% V9 x$ b9 `. [希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 * G" Q0 q( p3 X" [+ L
呵…… 谢过团长大人~~
9 `, }8 C$ F) v  Z+ M

1 t. O; k7 k* i. r哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表   i2 F7 ~( _+ r1 R8 |' D0 ^. z$ d
团长的朋友都是神,那团长就是神的boss。
9 U9 B" o& |* r+ w- ~: j
哈 不敢當,我只是個平凡人,
* a2 _- f* r* R( V要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙5 F6 K( c# _  W9 B9 |" ^
ZYH  |, b+ P, E/ X- @0 v
QQ:414734306
; w, u1 R2 d4 O! f. nMail:zyh-01@126.com
+ O# X4 f+ K, O7 y; Q4 \# T: Z
8 j) Y. w" Z- d0 J' p( G他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 7 D4 v: o! |1 N  D1 L8 }
再次对团长大人和悠悠哥的无私帮助表示感谢~~

+ o1 ]5 s7 Z) z2 }5 A. d不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-21 17:36 , Processed in 1.130859 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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