EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
6 R- f2 V) ?( o; O9 e; r! d楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~  {) i: G& @; j, v6 `  }- ~
这里有相应的模拟器源码,就当送给大侠了~~
( J+ y: A% z5 q7 jhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
/ n, q- p) S& w, }4 l能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
! y: B4 x) p) L8 }楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
  Y, d9 }4 N$ _- t$ W, v' H这里有相应的模拟器源码,就当送给大侠 ...
8 y' n6 Y! B' k9 D+ }7 {. m
聲音部分(Audoi Process Unit = APU):
1 O8 l4 X/ d6 y! c.\NES\APU.cpp! x7 E( |2 _  K+ U
.\NES\APU.h
) d* P! o3 O1 |0 O+ M+ Y) r
5 I* L. H; D( f2 g3 p8 A' Y3 x; T3 d! D1 b
影像處理部份(Picture Processing Unit = PPU):
( s' b! U! L* z5 _  C/ _! S1 r% l.\NES\PPU.cpp' u$ x% }; G+ d8 r8 {
.\NES\PPU.h) q( L4 s5 F( h! C1 i$ S
; C7 y6 X7 o" V& a; I  \9 ~
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
4 m8 @$ u* j: Q) y) J, D4 D0 L(由于很多专用术语和算法机理都不明白,所以看不大懂……)! u, v% v9 u$ X1 b
//////////////////////////////////////////////////////////////////////////1 u9 K5 @7 w6 Y# e3 Q
//                                                                      //
3 T' z0 ~1 \5 ?+ i0 ~//      NES APU core                                                    /// f& M# ~" ]/ }( X2 a
//                                                           Norix      //& T6 i4 ]5 t9 p" I
//                                               written     2002/06/27 //( [  P: ]4 \3 Z: s/ A
//                                               last modify ----/--/-- //
8 L4 y4 S! I5 j) d& F//////////////////////////////////////////////////////////////////////////: {, z: h* ?. u: Q
#include "DebugOut.h"
5 E. }7 B& i& }! N#include "App.h"
' Q! M; e! x# \  a8 n+ z; l' ~5 u#include "Config.h"
1 H$ v! O$ {, Z% F1 B) f
4 ]  U6 I" s: m$ ]7 B- `# V#include "nes.h". Z# R' d7 D8 u$ s- D+ v0 u
#include "mmu.h"8 C; v$ }" c$ G
#include "cpu.h". e8 E5 m9 b7 ]) B" Z, N
#include "ppu.h"" B1 K+ y' @) N6 t8 q' |+ d( t
#include "rom.h"
( I8 N0 A1 L/ v% ?, J7 j' Z#include "apu.h"
) T) ]4 ]$ q+ h3 x& |8 l2 A7 n, |$ I  k9 q( A6 S
// Volume adjust. D/ k! z6 J5 |; @; m
// Internal sounds
$ F$ ^5 F; _+ o2 m#define        RECTANGLE_VOL        (0x0F0)# n9 t7 |7 f5 h6 m8 p. m
#define        TRIANGLE_VOL        (0x130)
. }9 |: z1 `* s0 E& f#define        NOISE_VOL        (0x0C0)& N* Y% Y# p" j  J5 ?
#define        DPCM_VOL        (0x0F0)& X% s6 \6 d# f" e) X, i+ _
// Extra sounds, [: _' |2 S7 g2 D, B$ q
#define        VRC6_VOL        (0x0F0)7 M, N9 I0 {9 M
#define        VRC7_VOL        (0x130)
% u/ R! I7 z5 h1 R8 |2 N+ ^5 z#define        FDS_VOL                (0x0F0)+ c! B8 i0 h$ t: W' n2 C9 K% w
#define        MMC5_VOL        (0x0F0)
4 O; J* W+ t0 g6 C1 ^#define        N106_VOL        (0x088)
/ d9 s4 w' P/ Y4 y' }#define        FME7_VOL        (0x130)
6 s! K7 f+ y- _* V$ f) |
, p" o; {% \6 F4 O. w' C+ a' M( {APU::APU( NES* parent )/ P* B* }6 G- c; I9 J
{
, R) ]- b1 x, _% F! X. |2 j" @        exsound_select = 0;
4 m+ q4 i2 g" p$ n) J
7 j$ _* l- D7 v        nes = parent;, g. l* A1 T% M: E' J; U4 f7 q) C, A
        internal.SetParent( parent );
* O7 S' s& i( [+ \4 j8 U
$ G5 o& L. M: _% n) P: d9 Y        last_data = last_diff = 0;+ }! j! M/ G# `) p# w( E' k. C% P8 F
3 v" _( e" V( G8 K4 \( a
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
- i  N8 G& ~* P& H; W( T* f
! u- R; @% N1 l' W$ x# y        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
. e7 y- p& A" B, ?# j: S2 i        ZEROMEMORY( &queue, sizeof(queue) );1 z! ]- ]" f7 G0 O5 J; E
        ZEROMEMORY( &exqueue, sizeof(exqueue) );7 t) [- l) Y( ~" \8 b

. \3 Y1 k  i0 T6 v$ \0 Z        for( INT i = 0; i < 16; i++ ) {7 A. u/ V# k/ a# T, C+ S1 |
                m_bMute = TRUE;" m8 W  p! h( y
        }
) a, Y  i+ R0 a$ d! j* R; H}2 N  @0 s$ ^4 R3 T- n

) E, {) y. \9 I6 p7 aAPU::~APU()- ~% j5 @4 N6 S6 J( F2 I5 m  c
{
; z. ?  P# \& ~+ ?% G% Q+ z8 U}  J8 v1 U9 {" t( i
% g! a9 l# W! }! m' `. D7 O8 H( M3 I
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
, |5 E# T$ Y, m  _{* V( \( {1 Q- {8 D
        queue.data[queue.wrptr].time = writetime;
4 D& p/ F# u8 X- c& h" b" R        queue.data[queue.wrptr].addr = addr;: P9 R. h  j! D
        queue.data[queue.wrptr].data = data;( Y, A# R9 k" X. h+ k0 J  R3 u
        queue.wrptr++;  ]& G. Z; V" n" A0 J+ p: K
        queue.wrptr&=QUEUE_LENGTH-1;
+ Y. A6 m) E) W        if( queue.wrptr == queue.rdptr ) {# k) |. {" G7 W$ F/ e$ o/ X
                DEBUGOUT( "queue overflow.\n" );
& l5 [7 z3 d. }0 w+ l0 g1 M3 P        }
6 J' s5 \# [# f: O5 p}, H% f( M5 a8 R4 T* J

( O( s5 y5 H% p1 GBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
; m3 D% T8 l$ W7 W( P{1 D$ N6 R  U7 |# @
        if( queue.wrptr == queue.rdptr ) {' x) g- \+ _* ~
                return        FALSE;& F  d3 `$ U% C5 ~
        }; O% v. B0 W; N& p+ Q6 z& t
        if( queue.data[queue.rdptr].time <= writetime ) {
) R8 N9 c2 s0 E& d; V; ~9 \                ret = queue.data[queue.rdptr];% ?  z" ^; ]! L2 ^7 N
                queue.rdptr++;
: A3 K$ q9 N/ m3 v" ~5 j: m                queue.rdptr&=QUEUE_LENGTH-1;
- y! L' F" g- {1 B* E- r5 _                return        TRUE;
& `3 i. ?/ [: r. M7 t        }9 X, H5 j8 H1 A" @' C/ N+ ~
        return        FALSE;- ?' @6 V2 _( \' ^) |3 X9 @
}
2 o8 Y+ n; h* w+ T. c2 a( n( Q) t) d
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
" y* m1 i! [, d: w5 d{' g4 E3 g; b# s  ^
        exqueue.data[exqueue.wrptr].time = writetime;
0 P' s$ j* w5 \" n: p        exqueue.data[exqueue.wrptr].addr = addr;
* ^, e2 K, D0 C; h' P4 r+ K2 K% S! [        exqueue.data[exqueue.wrptr].data = data;
- F5 ?6 g1 s7 \' L% g0 i        exqueue.wrptr++;& D0 x4 B5 J$ `) q% L0 ~
        exqueue.wrptr&=QUEUE_LENGTH-1;
" H2 a+ [  d$ e        if( exqueue.wrptr == exqueue.rdptr ) {9 w/ @6 b2 v. Y3 [
                DEBUGOUT( "exqueue overflow.\n" );* p4 P: @5 J" `0 J/ `0 L/ r; b) x
        }
4 ]. p$ u& N% O* Y/ N3 q: A}
! k! u+ I2 W" R$ M+ J& P4 \! Q( u3 ?) Y, c/ `' [
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )" `* S0 ]- |: [/ q% D- `6 _
{
5 W+ U6 z$ c( N  _, x: e  X        if( exqueue.wrptr == exqueue.rdptr ) {
/ n4 I& S* x5 ^" I+ a# v6 d                return        FALSE;
% s6 t; [  Z7 ]3 \2 o% z' n. S        }
5 B6 \- W/ y# q, {0 R7 x        if( exqueue.data[exqueue.rdptr].time <= writetime ) {' A# M! d7 x; T+ Y+ }- q* ]
                ret = exqueue.data[exqueue.rdptr];
! X: I# Q" e1 V; V, t6 |4 ]                exqueue.rdptr++;
5 H- j/ W2 _5 G5 q. F                exqueue.rdptr&=QUEUE_LENGTH-1;
/ ?, v7 n3 |: N2 B- _% Q( u1 f                return        TRUE;7 m0 `: I  E$ q
        }- l. b3 K- |8 m  l* C
        return        FALSE;
' q" Q7 m2 B. k  f}8 N4 v1 L8 m$ V, `

1 O1 H4 j4 c& y8 J: _) |void        APU::QueueClear()/ f3 x. }+ b3 T$ ]  @$ J
{
% o- k, }0 e/ C% c9 ]4 k' S5 B2 \        ZEROMEMORY( &queue, sizeof(queue) );
6 w" P1 w. {) Z/ B- C+ @% i        ZEROMEMORY( &exqueue, sizeof(exqueue) );) |, q' O% r8 n7 t3 M1 P& j
}
+ N" o' U7 j% w% a+ X" m6 W
% p1 t# h. K0 F) \* x# i' O! Qvoid        APU::QueueFlush()- D5 }4 N2 `3 Y& W/ i1 a
{5 J# k" g; I- F0 B8 V! k! H
        while( queue.wrptr != queue.rdptr ) {
5 ~9 d# r9 G6 b/ K" F: s3 O                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
4 ?  M: v5 b1 a: v% M2 l& }                queue.rdptr++;
2 [, u& C! s, U( A5 K                queue.rdptr&=QUEUE_LENGTH-1;$ I6 m4 `. T+ D- Z! y
        }
$ o* l% a; r) h. _( L. e, N* T8 d( W# U
        while( exqueue.wrptr != exqueue.rdptr ) {3 w- ~. d9 z2 |6 b; t/ V9 A
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
3 w1 z: N5 h# {" r! H" e' _                exqueue.rdptr++;' i: }' d  o/ k  s
                exqueue.rdptr&=QUEUE_LENGTH-1;$ z" l- [9 _+ d. u9 _& \
        }' n3 }" x! c9 v" S" \- [
}
% H# M; ?1 Z. h( X: S- I% q/ B# {& M  @7 i( n* _
void        APU::SoundSetup()
' G  b) ], i6 ]{
" t/ H; k+ j# [1 ]/ K1 c        FLOAT        fClock = nes->nescfg->CpuClock;! x6 w4 g6 f8 a, l: U* \
        INT        nRate = (INT)Config.sound.nRate;
& @4 ~9 M3 d2 n2 Q1 e* q        internal.Setup( fClock, nRate );
/ s$ K& I- f9 q        vrc6.Setup( fClock, nRate );
+ D+ M  U. s2 I! I- u* [        vrc7.Setup( fClock, nRate );
0 ]) b7 g3 ~- ^- _9 B0 j. x        mmc5.Setup( fClock, nRate );
2 |) }- B7 m* r  o) G& b        fds.Setup ( fClock, nRate );
+ d0 X9 a7 L( s4 l- j        n106.Setup( fClock, nRate );
1 o% B' n4 n+ M        fme7.Setup( fClock, nRate );( ^# F8 v) ^! f8 P9 r4 \
}% ^5 _% F+ b/ q
( |) C3 [4 e( N+ i, r8 M" R9 |4 }
void        APU::Reset()2 a, k& H0 X& ~  l5 f, d
{1 o  v& |% P/ |, j/ \1 v& E3 [
        ZEROMEMORY( &queue, sizeof(queue) );  Y7 Y0 `3 e+ E! k2 e
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
- T. m+ b( H3 c( l% s9 p# Y
1 X  G8 F8 ]. y. T4 N        elapsed_time = 0;
6 Y+ z- {+ F  N1 Q  ?
# B+ }4 S# G4 }        FLOAT        fClock = nes->nescfg->CpuClock;
9 q$ C3 `4 r% ]/ j        INT        nRate = (INT)Config.sound.nRate;7 [8 m0 N" I6 @4 y
        internal.Reset( fClock, nRate );. o% Q7 b/ Q+ b" k) J
        vrc6.Reset( fClock, nRate );& F0 `" n2 g/ K* z
        vrc7.Reset( fClock, nRate );3 F: u, W4 g4 u4 K
        mmc5.Reset( fClock, nRate );% ~& f& w9 o, ~0 B( U* U
        fds.Reset ( fClock, nRate );+ t4 W$ r. r# q+ X
        n106.Reset( fClock, nRate );7 S# n; C; J8 z: ^8 o
        fme7.Reset( fClock, nRate );
, T* }. r" z3 b0 G7 _: w' `1 \' w- n, m$ P" ~
        SoundSetup();- a' G+ `/ @5 ]5 s
}2 G  s" i1 x% D9 d) A% U8 O# q
% A  g7 z' p! B3 E
void        APU::SelectExSound( BYTE data )
9 m, V) [1 B' c. l2 g' ^{4 s, B, y" f$ c0 M: s) P
        exsound_select = data;
8 X# v3 F* o# e- j1 B7 V' f& @}
3 ]* \: R5 h0 }8 i9 Q' @) c: a- u- }; x) e
BYTE        APU::Read( WORD addr )5 i8 J* ]& ^: c& Y; B6 B
{) M: O8 V# ], V  C6 n
        return        internal.SyncRead( addr );
9 ]3 C; y/ {% n3 j$ A& I}5 g. Q6 d7 ~2 V4 }, }. R! U

  v4 O# {/ r" Fvoid        APU::Write( WORD addr, BYTE data ), x3 y9 j6 i$ j( ?" U* {* P# O
{
; r' a. a( ]& Z% L, a( R        // $4018偼VirtuaNES屌桳億乕僩6 a1 p8 ?8 d6 r9 L1 y  ]; C
        if( addr >= 0x4000 && addr <= 0x401F ) {
8 y3 m1 o. }7 E1 l) r% Q8 v                internal.SyncWrite( addr, data );) \0 O# y8 x# Q5 D% F/ e
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
! M3 ~0 a! C2 Z' g5 P        }# V6 d% `2 D  g* Y2 O; Z. j
}
+ n8 O- [. i% o$ @; p" ^; D
9 |1 p) }! h7 pBYTE        APU::ExRead( WORD addr )
2 d* D& c3 w7 y, F$ \{0 N) j' a+ c8 c5 P2 k4 Q2 _
BYTE        data = 0;% l. D) s7 y7 i  [$ C
! W3 x/ X" Y* L( B  p  n5 H+ ^
        if( exsound_select & 0x10 ) {7 \) J) x  N4 ^8 Y! R( t- y
                if( addr == 0x4800 ) {
8 Q2 z+ `  E& V1 M% v                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
( w$ Z) L# C$ @: k                }4 p0 L# ~% @1 [/ z/ H" Q; e
        }
" A: s6 I) k9 z/ S        if( exsound_select & 0x04 ) {
# a! j% p" F6 i0 u                if( addr >= 0x4040 && addr < 0x4100 ) {0 E, H" a+ k/ }
                        data = fds.SyncRead( addr );9 ?: `5 o' P0 f# d( J: O
                }
, ~" m; _' ~; B# [- {/ l6 }) @        }
6 R5 F$ z: a. Q% h        if( exsound_select & 0x08 ) {
% c- b. u( k9 c                if( addr >= 0x5000 && addr <= 0x5015 ) {, \# f' i# G( R( L5 E
                        data = mmc5.SyncRead( addr );" S: u. Z! z. j- ?7 N3 h4 n  I, N
                }
6 D' f4 e1 C8 `8 ^0 ~+ x        }% }% {6 {. w- |7 t% Y: d: @( T7 D1 Q

3 ]0 l+ j' k) z" {; m9 i. S        return        data;, k! r) C( S& l) j6 H7 a
}3 `8 b; D# R8 D5 W2 F" c: c
4 b! h, p$ u" E- }7 ?) L3 h4 X& a! U3 k
void        APU::ExWrite( WORD addr, BYTE data )
. S. D, n, j0 K* ]1 @{% C3 N/ r  k7 p( A; D( w6 c
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
3 q* p4 v3 A& x& L' X( @/ G  p* b* Q
        if( exsound_select & 0x04 ) {
1 d: }4 U0 H/ v2 e. o/ g6 y" Q                if( addr >= 0x4040 && addr < 0x4100 ) {  A+ F$ M) s* B& p. N$ U- I: Q
                        fds.SyncWrite( addr, data );; W; Z7 [6 ~- h6 B2 z
                }3 `% C. z9 q7 [. y) S
        }8 c! r" Z( h$ l

0 L* g; A8 X8 Y! d        if( exsound_select & 0x08 ) {  f; a' ]5 F# E0 u* M# y
                if( addr >= 0x5000 && addr <= 0x5015 ) {
$ v# S' |5 H# o4 i9 y5 h. m                        mmc5.SyncWrite( addr, data );
, j9 j7 P4 u' Y6 U" v8 ?1 H  r                }
2 D: L' z4 F) Y9 c0 h        }
4 R& T3 C; H% z3 M7 z9 N. B; |! A}
% s1 h! H3 N4 `, K/ N8 C, Y. K1 F% G
6 e8 Q$ h' k8 `5 Xvoid        APU::Sync()+ K! X8 N! E  X* ^% d
{: |& ~! R9 _! {) x
}( Y$ }* N: ?  Y( m: B  I9 g
& _# y. L" ?9 c
void        APU::SyncDPCM( INT cycles )
4 I' [* t* m: |5 ]( `" @6 n/ l{  C. o+ ~( A' u0 e! M
        internal.Sync( cycles );8 w" e8 F8 Q0 Y# I, o, G

1 `. B. [. M2 k" n        if( exsound_select & 0x04 ) {" \  ~8 d; m9 l
                fds.Sync( cycles );
. @/ L1 o+ B3 o        }
  [* p' e7 ~! n, }7 J% b) \        if( exsound_select & 0x08 ) {% ^2 z9 l8 u. M- o1 @
                mmc5.Sync( cycles );
7 }) ]. R- M# M2 _0 G; V        }
( ?5 O( G; L% U# p}6 |* d+ j, g5 C  a. l$ y

5 X4 L) G5 S2 p$ pvoid        APU::WriteProcess( WORD addr, BYTE data )' h/ h5 u& d/ V, e+ {; o& F1 v, l5 R
{' r' s  s: u6 [% f; K
        // $4018偼VirtuaNES屌桳億乕僩
/ ~  z" I$ M( [6 [1 \& [6 V        if( addr >= 0x4000 && addr <= 0x401F ) {
% n# j8 j$ m; B- ]                internal.Write( addr, data );" J' J. U$ Z: g! C  e
        }8 u4 d7 L9 ?) r6 V
}: j' i! e% o' V
- o; c' y% h  a  |1 ^( d3 H  H# W
void        APU::WriteExProcess( WORD addr, BYTE data )
& ]3 H) K& y: O2 g! D: L7 _, g- M$ U{
! Q0 |5 d+ P9 X$ A1 x        if( exsound_select & 0x01 ) {( d  I( I$ E3 u8 k' W% g3 Q
                vrc6.Write( addr, data );6 H3 }3 ]/ b% ^5 Y6 S! ~
        }. p  E4 F5 x+ a- s3 O& n: p2 Y
        if( exsound_select & 0x02 ) {
9 r3 Y; b7 m& Y) S& o                vrc7.Write( addr, data );1 I8 q6 s3 ?3 j9 ?
        }
% a0 u8 Q! j# L        if( exsound_select & 0x04 ) {
! W% ]$ l$ P5 X$ m' P% v+ a1 Y                fds.Write( addr, data );' {9 K3 L" s; P' J! S! k
        }6 \6 ^; L5 @: L: m5 B0 z2 U
        if( exsound_select & 0x08 ) {/ N( }: f1 [# A% y
                mmc5.Write( addr, data );4 H/ J; `1 `( Q7 z8 `+ f2 j
        }
9 c  C* r. h: Z4 y. A0 F3 f        if( exsound_select & 0x10 ) {- F" E5 F0 c6 t
                if( addr == 0x0000 ) {
/ \1 d9 ?0 ]7 ?+ x: _+ ~                        BYTE        dummy = n106.Read( addr );
$ o' ^" k3 b$ |! N* e7 y7 u                } else {0 S( U/ g) W% R% b$ H6 B; P! q
                        n106.Write( addr, data );9 k# r# O% M1 T
                }7 j" F9 k$ C% E. A- H
        }
4 u0 O  C7 Q2 a8 v: x2 h& i        if( exsound_select & 0x20 ) {
4 `& L; B; Q. S8 B                fme7.Write( addr, data );
% o, y+ x% L) R1 H! x8 r        }
: U# {4 R- M% l' J2 n+ d& M; g}5 ^% B0 r% f& u& ]" p! K" T

# r4 M0 g7 z1 X' f9 |' cvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
' D3 w2 ?( F  N{, {7 Q/ R8 p8 W8 d$ {, v
INT        nBits = Config.sound.nBits;
5 L$ M2 G$ m# Z# i- bDWORD        dwLength = dwSize / (nBits/8);  c- }2 c2 S( X2 S( t- |
INT        output;, v' n- z- @2 ~/ G* t
QUEUEDATA q;, x' B7 L4 y  `+ R2 Z1 Y9 b/ i9 k
DWORD        writetime;
5 i& \  h% A( A! L
2 Y6 ~$ i  ^4 Q( A" w, M* G) OLPSHORT        pSoundBuf = m_SoundBuffer;- K7 C* {. e$ t0 ?4 O5 g- \
INT        nCcount = 0;6 h; T9 e5 [5 D. G6 m4 t0 J
5 H: Y5 p+ @2 B
INT        nFilterType = Config.sound.nFilterType;
+ j$ E) l. S. e. S8 b
1 }  F$ N5 i' v9 z        if( !Config.sound.bEnable ) {, S  U3 ?4 |: c: N
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
: I4 N* L8 `8 q" h2 }; E# S6 z                return;: f4 J$ r2 _6 e- E( v  k
        }8 W& c5 H$ W1 [* b
6 @, O" L; E) J4 ]( P! }
        // Volume setup3 {& m5 \  |2 L( k
        //  0:Master( C8 ?( M# T6 T9 z0 b; }' v
        //  1:Rectangle 1
, ~6 K; N9 ?$ T; i' m        //  2:Rectangle 2: _( O! [6 w! c
        //  3:Triangle/ A& y8 H0 V+ E( j6 l. F
        //  4:Noise# b$ g! c2 w' T" ?
        //  5:DPCM3 k9 I2 ?: W. @5 O, E( P( r
        //  6:VRC60 Z/ k# O. L, c$ x' F
        //  7:VRC7
% ?- s4 ~: y1 e& N. p7 P! B        //  8:FDS
- X& _  @# q% H5 P        //  9:MMC54 P; \* U$ }7 H
        // 10:N1063 x) R" c: Y9 H$ j4 n
        // 11:FME7
9 L$ x4 R8 g0 q( h        INT        vol[24];3 M- E8 [# k7 |6 K9 s, d
        BOOL*        bMute = m_bMute;
: m/ P3 u! Q3 I2 x1 H+ B        SHORT*        nVolume = Config.sound.nVolume;( |; w9 V; e. ~9 k2 A3 O- J3 V* t
; C2 I& V) X, v6 K
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
+ k$ t2 l+ r- {* J/ M; }  ?2 A) }/ I& C
        // Internal
6 N) E2 |9 ^) Z  U7 p$ l        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;& o6 s5 k" j1 @9 N6 f
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;% l& |2 M1 R# A
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;+ f: C9 M% i8 p& C
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;! f; _) h9 f( [
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
* o, i' F9 e+ F1 ~2 B- e0 k) Q. `$ ]. ?  `& o- u" ]' d- `
        // VRC69 q7 b8 P' h1 [6 k
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;7 T% Q% }6 S: X9 I, j( V' h4 m
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
; F) T0 K* [+ y4 G( O% _        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;, f2 ?1 q: w% _% R4 a: w: X8 ~
" v6 l& T% t- s" j8 T/ x+ D
        // VRC71 O! |4 V. X" u0 j+ X
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;# R* R% Q1 k$ _! ~' L

. p, I3 J, S+ A# M7 H2 c        // FDS
% Q* Q$ B9 J, v! U9 q3 G( @. {        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
. Q# ^9 L" h3 X# y) M/ x
4 R  q. [0 y+ e  ]3 f' g: f/ e        // MMC5
* P. w. [. G0 e  n& L        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
5 @6 e& n5 r2 g" T  J) f, e& d        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
$ c1 Q* D0 M; n        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;% T3 W' r6 p! h# A
+ w1 }/ r6 T7 [' ~) F: Z
        // N1064 Y. k& R9 F# ^# O: z
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
) j. R' v6 `8 X7 k% M4 n        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ r* Y/ q# o: {! Q+ `6 Z
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;4 U% d4 Q" C1 X3 h  \) b6 i
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;  [, G0 P$ h( h
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- Z5 U+ v% i, H2 n: G' m5 h- B2 m$ h        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;" Q  r$ |2 ]) ?/ a7 N) n5 ~
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& H6 @+ t! |  s        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;( y$ |+ J, t5 U! j( }

: b4 G. Q) @2 M+ `* L  X/ |) V        // FME7
" ?; v  j/ d; S1 A        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;4 E3 t# }( L6 k7 P# X
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;8 o! ]  g% s( c' p4 o( Z
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;2 p" B" ~, h7 v
9 z8 N, i, d% x& z7 y& w, ?
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
# B* H5 l# e" u7 v        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;5 x1 Y& w; }; G& ^% u/ H" }

7 t5 d, k6 R* o5 p, b  w/ U" v        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟9 J4 r* U3 v# a6 `/ W7 B
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {- A. B% n. Y; m& T
                QueueFlush();
! B# \$ ]/ F- j0 L0 X' c) J; a        }
0 R$ V6 F7 V* X7 H: i2 J; m$ [( C0 \6 o
        while( dwLength-- ) {
, h6 }9 W* \9 S7 I, K$ U                writetime = (DWORD)elapsed_time;: j, \* q6 E6 @+ s  ^

6 j6 F% O* |% V) d3 D. t                while( GetQueue( writetime, q ) ) {& ?( y% h4 z% U( \/ |% _) m
                        WriteProcess( q.addr, q.data );/ h8 A6 |; F' ^  n( l) H
                }
7 V7 v( L/ P, `! m- ]  J9 l+ l3 a5 G, ]
                while( GetExQueue( writetime, q ) ) {
) l+ t3 v" p# v$ i% ]/ R/ R1 a                        WriteExProcess( q.addr, q.data );
- ~. I/ z( n: l                }8 b4 l" R) z8 d: d
9 I1 x# }1 _) t6 x9 C! _. \! J
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
7 V0 p7 H) E3 b- z% Q1 z# b4 \                output = 0;
2 N9 n2 A) `! C& z) I2 N" \                output += internal.Process( 0 )*vol[0];/ ~3 f# w$ R0 ^$ k7 X. W
                output += internal.Process( 1 )*vol[1];
6 q% T! H8 c& r) j# |& Z                output += internal.Process( 2 )*vol[2];' L" W$ x% s! d0 w4 d% B
                output += internal.Process( 3 )*vol[3];) j) J( P/ G6 w
                output += internal.Process( 4 )*vol[4];
# Y* A1 q% t9 t, m& ?" K4 x9 M: M7 b3 i' l
                if( exsound_select & 0x01 ) {
' w% W* [4 q$ A0 E9 i) X                        output += vrc6.Process( 0 )*vol[5];0 O: E$ ^# s, ~. ]5 X0 s2 S  s
                        output += vrc6.Process( 1 )*vol[6];3 B3 F4 |) e0 j4 f8 ]
                        output += vrc6.Process( 2 )*vol[7];
7 e  m& }; p, Q/ a4 X" L$ @* G, W/ H                }7 D$ P( q1 u. }' N( J! b: @
                if( exsound_select & 0x02 ) {
( p! H, M+ m# v8 ?                        output += vrc7.Process( 0 )*vol[8];& [# f: b8 C$ z, ~  [
                }
9 V% O& \$ w% B8 `! b                if( exsound_select & 0x04 ) {
$ h- }. F- [; E; E6 U5 y2 w                        output += fds.Process( 0 )*vol[9];
4 ^  H) }4 z2 D. R. p0 \, B                }( O- P2 E: e3 b( y9 }6 b! S
                if( exsound_select & 0x08 ) {
0 h5 O" Q* m1 X" N) ~4 E. ~2 U                        output += mmc5.Process( 0 )*vol[10];! Y$ D( w6 ~; ~2 a% k7 i
                        output += mmc5.Process( 1 )*vol[11];/ c+ T4 v; L: B0 ?5 V8 I4 y
                        output += mmc5.Process( 2 )*vol[12];
6 r8 @$ _+ g% X6 b, w; |2 C% p8 T3 t                }
& Q) P# |( d, G) a1 R                if( exsound_select & 0x10 ) {
7 L7 O) X7 \" c, @: {3 E                        output += n106.Process( 0 )*vol[13];! x6 z- E) z8 U4 x( H0 \' n
                        output += n106.Process( 1 )*vol[14];
: ?1 e0 r. E* L- |                        output += n106.Process( 2 )*vol[15];
( ?7 d4 e4 h! m" d7 ~1 L9 r                        output += n106.Process( 3 )*vol[16];
' P( G4 b7 f0 [: B! M( z1 m. g4 _- R  j                        output += n106.Process( 4 )*vol[17];
- k1 h* [# ?8 Z9 L$ G! }$ \5 z                        output += n106.Process( 5 )*vol[18];0 g) `0 u' l7 x  E) b
                        output += n106.Process( 6 )*vol[19];: E3 Z; [/ h. ?5 M
                        output += n106.Process( 7 )*vol[20];
3 b4 j) U' E+ Y/ ?" V" k$ Q# t                }0 f+ Z# c( D9 N
                if( exsound_select & 0x20 ) {  O8 }( v# k, k
                        fme7.Process( 3 );        // Envelope & Noise
2 D; ?7 \" o  b8 B. ~' r                        output += fme7.Process( 0 )*vol[21];
9 e7 ~7 A3 u: ~6 D" b                        output += fme7.Process( 1 )*vol[22];* _! \5 C' r7 ~- ?
                        output += fme7.Process( 2 )*vol[23];, ?$ J2 I9 D, @# b7 z4 Q% Z
                }
% l* K% D& q/ g
' U) U3 x4 p* L                output >>= 8;
: H( _3 T% m/ p* {' _$ n; a" D$ V; p( H5 T3 [+ T; v  P
                if( nFilterType == 1 ) {( E3 [& N# r# z( k
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
. {4 u$ @5 V, N0 V( Z& r$ }                        output = (lowpass_filter[0]+output)/2;
7 i5 q/ E3 A7 r9 M2 A4 L, `) {: I! C                        lowpass_filter[0] = output;( ~5 U/ u- i1 O
                } else if( nFilterType == 2 ) {8 @7 h) Q- |4 T) T' J
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
2 Q* c$ |6 y$ y! s. R                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
( ^8 s7 i( }! {3 s. \- O                        lowpass_filter[1] = lowpass_filter[0];
2 @5 Z6 h, J! b$ q; E                        lowpass_filter[0] = output;
3 Q, i: H; A( m! _" ~: |                } else if( nFilterType == 3 ) {
- }. n) i6 L2 W5 [" \+ J                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)- y# ~) j, Y  |2 o- x: Q9 W0 i3 a4 J
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;! j- j7 H) a5 L6 o
                        lowpass_filter[2] = lowpass_filter[1];
% ~9 `  ^6 m: s8 j* M, \                        lowpass_filter[1] = lowpass_filter[0];# B, C5 U0 u! }) D' M' B9 D
                        lowpass_filter[0] = output;* H0 t$ j  c. B  |
                } else if( nFilterType == 4 ) {
5 l7 @( K" ]" G                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)% u3 Z# e- a; H5 Q. X& w4 r9 ^
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
% z  T6 a; y  W  E4 r                        lowpass_filter[1] = lowpass_filter[0];0 W6 t0 p! ?# O$ N) U
                        lowpass_filter[0] = output;
. u- F5 @* q. o/ l; ?8 C6 r" D8 w                }, I, @3 P  v7 f8 ^  N+ p

. Q- E5 e: h' L#if        0
% k8 b, B3 i# D' ]- X8 z                // DC惉暘偺僇僢僩
% k) b+ i, X) d3 v2 O- U! w: B) C                {' T  ], [3 ~/ R7 N" v4 O7 V* |  S) J
                static double ave = 0.0, max=0.0, min=0.0;" D" Q6 J* e0 ~/ S4 `
                double delta;
; I, ~, v& B! x! y" z                delta = (max-min)/32768.0;
1 u% O; y+ i  |9 ?' F* P                max -= delta;2 `; v# u: b# F4 W- A
                min += delta;3 o0 M2 E! C1 t8 r
                if( output > max ) max = output;% e8 L' ?( B9 {, k! M7 F6 ^
                if( output < min ) min = output;' F7 @; [+ P& ^, v  _/ I5 q
                ave -= ave/1024.0;) }. ?$ J) T0 A1 _+ h
                ave += (max+min)/2048.0;
& T0 k# t; u% P1 R                output -= (INT)ave;' n4 `% R/ I6 @, P: j0 e
                }& A4 k7 s& _& N% ^1 Z) z( b
#endif: a& m* M0 m5 C3 a* ]
#if        1
% V0 P) N" O# n" h9 z0 M, e( E                // DC惉暘偺僇僢僩(HPF TEST)) {5 D) n8 F8 G: {3 N, K9 n
                {3 G. r  f! y  u' J4 H- P; h
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);" o$ y) }8 b! a
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
- C" u' ^9 g, \! s1 W: v, U7 q                double        cutoff = cutofftemp/(double)Config.sound.nRate;
# }( e* M& k- y& B                static        double        tmp = 0.0;6 i& W7 _, _9 G. Q0 |; R
                double        in, out;3 S' t8 e1 G& f2 I
1 n0 K1 X& w) h9 l2 d, W! _7 d8 ]
                in = (double)output;
: V9 t: }3 n1 h* p2 G. j                out = (in - tmp);
$ L# |; H7 P) O! Z& R/ p                tmp = tmp + cutoff * out;4 }/ p% K$ ?" Z5 L* E

8 d  x! T$ C& B/ a6 d' R                output = (INT)out;2 s2 q% B4 @' E' R
                }
! K1 r- L" M7 k. `#endif* ~5 H& o5 j# U: m% w$ q
#if        0
, g6 N; ^4 _) d' L: a                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST), ~* q0 l6 ?+ }5 V" w
                {5 I4 t4 O$ B' a/ W$ I
                INT        diff = abs(output-last_data);
( [0 e* C- C; R/ T                if( diff > 0x4000 ) {4 s0 U, I; O8 h* V( b  Z( G
                        output /= 4;% ~* F; Q0 I% K/ K
                } else
7 |0 E9 C$ u8 O( Q                if( diff > 0x3000 ) {$ B6 D2 S% L! t  F  o8 t
                        output /= 3;
7 |" s2 b; I4 h1 d( W2 S0 x! J                } else: E8 d: M, D$ Q
                if( diff > 0x2000 ) {' a. n4 d/ s& I
                        output /= 2;
/ S0 M# V+ c, a5 e# G                }9 L/ u! e) l& [8 o1 [
                last_data = output;
2 B: n# O2 l( f                }6 n' y3 S' h5 M; O) G
#endif
" b+ i+ k0 {; M* {& {1 s                // Limit
. Q5 m2 }8 Q4 c8 C. R  D                if( output > 0x7FFF ) {( n- J; s2 C- @+ }! W* U
                        output = 0x7FFF;+ H; l% t! J3 B" _
                } else if( output < -0x8000 ) {
4 v, U4 g* t9 R' T0 l  f8 M# X* O                        output = -0x8000;
6 V8 b3 L* X+ d                }
: s  f% N. }( c( W4 N8 ?0 _) [6 T
% |8 ?) I3 l, X+ [) }& _, Q                if( nBits != 8 ) {# h  s* d: ~; Z4 i, ?
                        *(SHORT*)lpBuffer = (SHORT)output;
3 w; j% [9 q; q                        lpBuffer += sizeof(SHORT);
- s4 g( _( q  K3 ]" ]                } else {, `! K% {$ H( z7 z$ s8 M6 J
                        *lpBuffer++ = (output>>8)^0x80;2 u0 A- T9 H1 c3 D( ~3 C1 P5 y
                }
- x1 V7 W, L) a* b6 n) }. j# @) d8 Q7 E2 ?6 x
                if( nCcount < 0x0100 )8 e+ Z. [0 \$ O2 M& I
                        pSoundBuf[nCcount++] = (SHORT)output;5 }7 E9 ~* k1 n* z( N- g5 p

5 t5 @4 _1 A2 Y6 p//                elapsedtime += cycle_rate;
4 l( K& ?- N4 a$ ], d8 d                elapsed_time += cycle_rate;5 ~) a) p; F3 T6 Y! g
        }5 x5 ~7 Q% V+ Y1 s
' p9 P' L2 c7 b/ u
#if        1
0 J3 _. M) l, P- Q! U        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
# F9 H; B; c4 ?* t" q( F9 z, F                elapsed_time = nes->cpu->GetTotalCycles();
3 B5 V( ?/ W" ?% @' F        }
) x; N2 E& D* e# D' t8 @7 j        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {) d4 s4 b# `6 k) W  o: {
                elapsed_time = nes->cpu->GetTotalCycles();
! Q. N" ?* i, D8 [% `) B7 c' t        }
% D; z2 x4 t1 |- [1 I#else
* y. |. H$ @2 ~* S8 g2 v        elapsed_time = nes->cpu->GetTotalCycles();
! S/ M5 \. Y" Z8 v" K, a& n; h! K#endif
/ y$ _9 J" z2 A8 i, C# e}1 @1 @, R" l9 l: n/ l9 b
$ n8 r; n# [6 ]
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
" Q  @& Y$ i( P4 t! @INT        APU::GetChannelFrequency( INT no )
5 F! Z( w6 ~2 ]2 V2 X* q# P{
4 J4 D$ ?/ t' U        if( !m_bMute[0] )# b% {. Y  g* l- |
                return        0;
+ H3 f* e, K1 N$ Q6 e$ a
. [0 q! W) v$ {) P: H' l% ?$ h        // Internal( r0 b# B2 u. Z$ a8 n% J! M5 n
        if( no < 5 ) {% e5 @! F  X$ {
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
; L6 r3 `  X3 u; k, M% p* D1 _  Y+ e        }
" N4 W$ r% I/ i2 k; `        // VRC67 ?: v/ w+ Z, ]1 a: n! z7 ^' `
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
2 W0 [" v/ I" a0 r  x0 @& I                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
" B. d& N% v* j' ?/ O" B$ H        }
% N+ K6 s/ z- Z( l        // FDS* L( T: L0 J! m* Y7 y
        if( (exsound_select & 0x04) && no == 0x300 ) {  R  h5 l8 y% i
                return        m_bMute[6]?fds.GetFreq( 0 ):0;& N6 U& y9 }5 N* G/ b
        }
: h, [; J+ {; f! P$ p        // MMC54 e& k& {  G. V# a
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {/ o! C$ H& L% K3 _2 j) w
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;- P  {2 ~! J6 J+ B+ {$ R
        }3 P. z) T! L& J/ e+ e; t, M$ h* m
        // N106
0 A2 L& W6 d$ d2 k" E1 D        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
1 R) r* f" J6 O# ~                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
3 E6 {4 R  A$ U# x        }( t- c; {( @& `% [
        // FME7
+ v" e3 O2 `) V6 U' f8 R& R4 R- K        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
7 c% b3 |+ x1 J! e1 K* T                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;+ \: w  p4 V2 s
        }
! a- @8 l2 ~* s        // VRC7, r) u; ~0 U: b( T
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {: Z2 p( a1 F+ B7 M* d( U
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
- T. r' N7 X8 b+ f  E8 S: D6 P2 A& L) k        }
: ^! G% d' C7 u        return        0;
4 K6 p( S' L) V& y}
4 @/ g9 P, A6 T/ Y/ r$ ~  {- \# J$ W; k4 h
// State Save/Load
: H4 S  U" R" h8 Jvoid        APU::SaveState( LPBYTE p )! e) W# F# r( s$ }- _2 \) M
{
% d# _+ \5 e; m, o  L#ifdef        _DEBUG  w# B) `4 i: r4 A0 I
LPBYTE        pold = p;
8 q, n" e) V* m8 v. v0 {  d#endif
3 n2 l  l( T: `8 X
; w  l9 a4 Z9 b$ `4 z2 T  z) @        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞4 U9 |+ V' [4 ^, {* C
        QueueFlush();: i2 ]/ v% Q+ I: G4 q
& `3 E5 p" g' b
        internal.SaveState( p );
: I4 q, @/ Y/ y7 t& {        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
* u2 u7 J1 \; i; \* F) ~2 U
! {* Y3 V) G! l) Y        // VRC6; P2 Y; q/ z% W, W; ~
        if( exsound_select & 0x01 ) {
( e+ a4 Y: c' q7 `$ ^                vrc6.SaveState( p );
) W* t: e& p1 c7 U: B3 N( s4 [: ]2 r                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
& F3 Y1 h: w" i: E% z- ]4 z        }
4 d# s- I; s: n7 y+ Y! O; @! M' O$ T        // VRC7 (not support)
5 i) N/ y" x* r; }        if( exsound_select & 0x02 ) {
+ T- }/ Q3 M; S9 [: g4 N                vrc7.SaveState( p );1 |/ j# J/ `( R+ F& v5 D9 @
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
" |2 Y9 T. ~, Y5 p        }" L+ |2 J4 S' J' H& t6 T8 {
        // FDS9 c+ ^1 \2 s4 d7 q6 M
        if( exsound_select & 0x04 ) {' E; p4 r( s1 }- @1 |# q
                fds.SaveState( p );, a' M( |# {9 Z' R% e, O9 s% n  A
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
; S. Q' s) q$ [        }" J) X5 v4 Q/ F
        // MMC5
9 K) n  l  W! X1 C        if( exsound_select & 0x08 ) {6 r+ r) k/ q  p6 N$ U! U4 f
                mmc5.SaveState( p );
- |4 _$ S& @+ S6 ^9 k                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding# `( |7 @" p6 b# n
        }" \: w( V( B- i: i& I# K
        // N106
1 T. T# [& T! @1 [( Z: L        if( exsound_select & 0x10 ) {, p3 s' b, f9 }4 n' X9 c0 q
                n106.SaveState( p );
1 x7 z" \+ ?+ b, ?* z                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
" |$ J( ^) ~9 z9 ]        }, l4 G' Y  M: ~& W+ u
        // FME7% }8 _, G1 J, q7 u7 `" ?
        if( exsound_select & 0x20 ) {
2 n) N! R  x6 r6 j# p) c                fme7.SaveState( p );
. u* e- X( c/ K" U                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
: O  M' j. @  o1 S- |- k' e! g1 ~  w        }" m6 I* \3 ?9 M
( q4 y0 q# e8 R6 X- t
#ifdef        _DEBUG
9 S3 i& v0 I5 w: J5 ?1 f* ~DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
  }+ s% N- k  F/ d) d#endif$ O# K9 z" ~; w8 p) N  ?
}
4 a1 P0 q9 n7 A) l" F& {+ y" V! M  |5 I8 B& B
void        APU::LoadState( LPBYTE p )
8 D4 Z/ a# ?" k; @" S1 ~8 V{' w2 K; E# ]* p5 j: u9 W- t
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡' t+ p$ U* P# q8 y/ p: N5 P5 X
        QueueClear();: n* ^0 N9 E. p+ b& {0 s

, e9 T2 w& I$ D6 P# W  U        internal.LoadState( p );2 k. E( R$ `: q
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding* ~! I7 k2 f, N( W' I+ b# W

8 O; U& n1 O; t$ ~5 d        // VRC6
7 E; f' l+ w' f5 x" H- k. u        if( exsound_select & 0x01 ) {2 r  M6 C& {: o) ~
                vrc6.LoadState( p );' i) H6 U1 t, y3 z4 u9 N3 ], L! v
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
+ d- u) A0 a/ i7 ^        }
* L4 A8 w, x8 M$ s) Y        // VRC7 (not support)
% Z9 z; R! Q( p" L, j# x        if( exsound_select & 0x02 ) {" M; Q4 E/ }3 t: D
                vrc7.LoadState( p );
' j6 c- d; ^& F; N5 P                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding% x+ h$ h# Y1 V& ?& ]  V; s
        }' l8 V7 s" Q; `) |* i8 }3 J6 T& W
        // FDS$ x; ^+ y  b1 T4 |6 N; o
        if( exsound_select & 0x04 ) {
+ D+ k6 m: C3 }& B) }: @                fds.LoadState( p );
1 L/ M, t! r: K                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding5 l: l0 @) t0 s2 c- V" |9 J4 k
        }5 U- s% o/ O8 A* B( N
        // MMC5
% i* z/ h# s7 o! U        if( exsound_select & 0x08 ) {. Q' c& y: K, j! x; e9 \+ d
                mmc5.LoadState( p );' H3 k- z* p- K
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
$ N# J, V/ x7 W1 }; \, w* m) m        }0 u+ t; h5 o0 w$ U# B
        // N106
( M# ]1 ^  T- a3 j        if( exsound_select & 0x10 ) {( d9 J1 H% K2 a. b
                n106.LoadState( p );
4 y, L9 k5 h0 ?) K8 I* V                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding0 ^0 i+ F& |  L3 F# Y/ D( ~8 {
        }
4 v) f7 U  k" Y" |8 x" f0 u2 H        // FME7
5 l. I0 A) n1 a; e        if( exsound_select & 0x20 ) {
0 E5 H& j5 b* D  a' ]. ?                fme7.LoadState( p );. l3 B' n9 y6 O
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding; Q3 Z7 W9 {; u  e/ r  L1 C  ]
        }
5 p3 h1 a+ Z! `2 ~}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 2 s' k  z, ~5 p. ?( J
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
) m; n9 a* ]' [: p感激不尽~~

0 U9 _( e1 h6 U: A$ X- g9 W恩 我對模擬器不是很有研究,. P% x' e4 x* s& Q0 A) v$ G4 B  x% S
雖然要了解源碼內容,可能不是很困難,
3 |, ~+ U/ G1 Y不過還是要花時間,個人目前蠻忙碌的。2 @. h2 ~6 L+ S9 Q" d

+ R) J4 u  c5 y5 ~( T- n* n給你一個朋友的MSN,你可以跟他討論看看,
7 r- w3 y$ G5 O0 E/ G5 ?* |他本身是程式設計師,也對FC模擬器很有興趣。# x3 q# h7 M* `. G

6 @/ c2 \, y- N0 }: V4 T) hMSN我就PM到你的信箱了。" U/ }- a- a3 e* t! m# s% X  R

! U' ]% Z& V% P* h, y, _1 P5 m4 J# ?希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
4 Z, ^4 {* C1 G呵…… 谢过团长大人~~
. O. a% E. \# z
8 n, Q! O$ V7 z
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
1 }0 q4 {) }4 U" ]1 D0 A9 Q# Q团长的朋友都是神,那团长就是神的boss。

" D& R; n* ]8 i, V哈 不敢當,我只是個平凡人,
8 c( v! q2 X( A' t! T要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙2 \% p+ _" {: \5 T
ZYH3 a( U& h7 W$ P: I" {
QQ:414734306
$ y3 R4 h3 z6 S' Z& ]Mail:zyh-01@126.com( S4 Y. q4 d1 f& J- a
- n2 u/ G9 f, E
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
. u7 b! a2 n6 Y( Z! _0 B8 |再次对团长大人和悠悠哥的无私帮助表示感谢~~
+ F7 k( M+ J/ f- \0 b  b4 A
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-21 05:41 , Processed in 1.091797 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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