EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。& r7 m; x+ C) l% A
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
- \2 e: c* P1 ^$ i这里有相应的模拟器源码,就当送给大侠了~~$ O& }4 b8 j, i! t8 f+ ^  W
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 ' ^# N+ k  j* I- Y
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。! ?" u# {& w  f
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
0 z8 x3 c! {- J0 i% L这里有相应的模拟器源码,就当送给大侠 ...
3 X/ _$ ~$ D. i
聲音部分(Audoi Process Unit = APU):! _# i# }! j; M# R; R7 j
.\NES\APU.cpp6 q% U8 P+ u+ l* {9 a+ m; r
.\NES\APU.h
* V  p5 C. B# i8 Z
3 V% D" H( n% r
; O1 m' m$ X( f" o' w6 I影像處理部份(Picture Processing Unit = PPU):' S* b; s: v; N8 k4 C
.\NES\PPU.cpp! V* o& V( |. @5 P: p" U
.\NES\PPU.h0 z" Q4 K2 M4 R4 J3 Y: w5 \: }
$ R, f  L. s' t* w
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
- b& q# p. \' _9 U(由于很多专用术语和算法机理都不明白,所以看不大懂……)# f0 F0 o- d7 K& D
//////////////////////////////////////////////////////////////////////////1 E6 [2 {7 C$ r& @, e+ ^8 V" c
//                                                                      //
; J' _: F8 V$ J* T3 ?) h! I//      NES APU core                                                    //1 Q9 @+ t5 Y+ D/ v  V" A5 b8 U
//                                                           Norix      //- z4 x( |) r) B/ K$ N% k' p
//                                               written     2002/06/27 //+ {" }+ H& t) g$ w
//                                               last modify ----/--/-- //, e0 t) @# }# c: U9 y( W& e* \
//////////////////////////////////////////////////////////////////////////2 @' k; P& k% R/ p: W7 c
#include "DebugOut.h"$ i( [! i: @% D9 G! K2 k. o
#include "App.h"+ |8 O% E+ u! e
#include "Config.h"
+ C/ }( ~6 l5 U- q, _5 x
; C" ^7 L- Y- ~; F' Q3 |# W#include "nes.h"
0 P  V3 p" p1 u+ }2 c' c, J#include "mmu.h"
# a2 }4 R2 H6 E% w% q7 p: h( B#include "cpu.h"0 k* n7 T) T/ [& e6 I
#include "ppu.h"( g# ^0 L% c# r9 b; b% ?
#include "rom.h"  f. T- ?/ k! M. N6 ?
#include "apu.h"
( C7 G8 r+ x3 e8 e% I7 |2 b9 a0 R* o5 M* w. ?$ w
// Volume adjust0 b% A1 I( I3 ?4 m3 b5 D' w
// Internal sounds
; M$ a, N, c+ B5 t#define        RECTANGLE_VOL        (0x0F0)+ _# ^9 K  w2 Q9 c( A4 f
#define        TRIANGLE_VOL        (0x130)& p% ]) h+ |: R1 g
#define        NOISE_VOL        (0x0C0)' k% q9 x) P3 U! \$ r5 T7 s9 J
#define        DPCM_VOL        (0x0F0)  T3 w; R6 B$ G$ f
// Extra sounds2 K9 u3 D9 i% U4 H' `+ N
#define        VRC6_VOL        (0x0F0)
0 ~5 X! W. `; }4 R#define        VRC7_VOL        (0x130)
# V$ u1 |5 B* N& x; d( _#define        FDS_VOL                (0x0F0)9 O+ R# o, v; e% g2 ^
#define        MMC5_VOL        (0x0F0)
' P. U: s& N% `7 \3 c#define        N106_VOL        (0x088)
* Y( m6 Z- m. |% U4 s#define        FME7_VOL        (0x130)
# u0 |, P% U0 D9 r# ^0 X( D" c, Y" @! ~/ U
APU::APU( NES* parent )" f7 n% _% @& c# J
{5 k  r' S* \, j' R4 c0 H
        exsound_select = 0;) n# m' B3 o' b, @

% h3 L2 b& B4 k+ S& I        nes = parent;
7 E0 f% i+ P$ A( y        internal.SetParent( parent );
/ \" _" Q: G' F) ?: G$ ~4 n& ^" Y
5 z. q5 d4 k& ~  b8 u: r        last_data = last_diff = 0;; p8 b. m) N" _& ^

& G8 T7 k$ i! X" B9 S        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
( |$ S$ i2 o! Z- s
7 q' }3 P& D5 p6 g2 J9 J        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );' r* l. y( j/ d+ L, q& Y- |( A
        ZEROMEMORY( &queue, sizeof(queue) );
7 o! B0 n' Y. f! ?. L, r        ZEROMEMORY( &exqueue, sizeof(exqueue) );
( @) m. M0 l8 B! H  \& |, g; u( }- |6 a
        for( INT i = 0; i < 16; i++ ) {
8 r1 V7 `8 J3 o0 z: `: }% A* z                m_bMute = TRUE;) Y# f, U- E0 O- I& Q( ^* r
        }
; p9 s5 c( l9 ?4 _, A$ L% a}; A% t& d; }) [, M8 W3 |
  K2 c1 s& A" @+ @& w
APU::~APU()% U! @! L) Y1 }. c9 \
{
8 a6 {1 o: R% Z( A- w# O}
% F0 M* T8 F" s+ y/ N7 H7 E7 _4 O7 t. m" Y9 |
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )8 L; K" U( I( h" j/ h7 a
{' E0 G9 [# [" W# J
        queue.data[queue.wrptr].time = writetime;5 |1 M2 u) S. I1 n8 |! C
        queue.data[queue.wrptr].addr = addr;1 N0 P% }6 P5 p7 ~, k  O
        queue.data[queue.wrptr].data = data;8 o# Z. O& k6 M& |: K
        queue.wrptr++;
: M9 p- l! C. R9 k) I: j        queue.wrptr&=QUEUE_LENGTH-1;
- u; s! S6 x" y3 e! g        if( queue.wrptr == queue.rdptr ) {
) ^* F3 p8 L5 [, ?4 t5 O2 v                DEBUGOUT( "queue overflow.\n" );
8 B0 t( V, W1 O0 d        }
! T& v8 s7 W1 Y$ m# C6 r}4 s3 g  J( p9 Q# L# G" V

" s  Q8 h3 t2 GBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )5 w" f( k2 b) D' y! Q, {9 c7 J, b
{; x; ?% b& F6 b+ Y: I
        if( queue.wrptr == queue.rdptr ) {$ _& {* Y& ~+ }$ ]+ |3 w: r
                return        FALSE;* p8 d/ k$ h2 u! [; N- `- z8 t
        }6 N. ~5 L4 D5 D" I0 ~  K
        if( queue.data[queue.rdptr].time <= writetime ) {
6 ?; o! D: y; f/ \6 v                ret = queue.data[queue.rdptr];& e" E- C7 i. v$ l# y3 _
                queue.rdptr++;
. M4 N4 _- P  d2 R                queue.rdptr&=QUEUE_LENGTH-1;0 i% k- X9 |% q8 U' d6 U& a
                return        TRUE;
* L7 A4 X6 c" k- U& a        }1 r* }$ W0 a  _' M% `
        return        FALSE;
$ r6 ?/ K5 w; O2 b$ L* |. q}
5 e4 g' m% h, y1 p" N
. |. j* f, }' Fvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
& `& Y0 M8 `3 f( C% r/ n: w{5 [. r$ D: v. q1 `/ ~/ I5 j% |
        exqueue.data[exqueue.wrptr].time = writetime;3 l2 I1 u& ^# h. i# S8 g
        exqueue.data[exqueue.wrptr].addr = addr;
! l& A" A, U7 @9 `& S! Q        exqueue.data[exqueue.wrptr].data = data;1 V$ }1 t8 l9 Y: G
        exqueue.wrptr++;; q% K6 D9 f5 U9 \2 T8 H3 B
        exqueue.wrptr&=QUEUE_LENGTH-1;' d* {- r) M. s9 @: y4 l& z# F
        if( exqueue.wrptr == exqueue.rdptr ) {
+ H# T: @0 N5 a                DEBUGOUT( "exqueue overflow.\n" );
- N, a2 e/ [! b0 Z        }' [0 D* N- U# g6 C9 z
}
% n9 U* |, M2 u1 ^
* ~0 r. I; a/ [# F7 I+ b5 UBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )- S9 n, i5 S9 J7 P! u8 ^1 ~
{2 c: k6 r# e: X$ [. f
        if( exqueue.wrptr == exqueue.rdptr ) {
! A8 n2 s+ V+ a) r( T                return        FALSE;# i$ H" C. |$ c: H6 y: L5 ?: Y! X
        }  E4 P* R& F9 ^5 f) b  L
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
9 o0 Y7 i# T1 w6 D% R                ret = exqueue.data[exqueue.rdptr];
9 S4 z5 C$ P! A$ K) z- H4 v                exqueue.rdptr++;
* i3 o0 I& Q: @1 _9 s                exqueue.rdptr&=QUEUE_LENGTH-1;
, S; A) W; u7 B8 q( q0 p; ^( {2 U                return        TRUE;
2 U/ B: l) y8 [' z1 {9 e        }; M& M& v( E" j; U( l; m
        return        FALSE;, R4 G  Q% M- z! G" I
}
1 i5 X% a5 S0 C) G* Q2 e# O6 X* I7 u8 L7 I( V: H
void        APU::QueueClear()
4 p' L, z- {9 ?5 u4 z: _8 A$ S+ @{
% S5 o1 h+ ~' v2 A. _5 F        ZEROMEMORY( &queue, sizeof(queue) );
' v1 f! c( H; t2 [4 U* L" r3 H6 p        ZEROMEMORY( &exqueue, sizeof(exqueue) );
8 @+ J- U9 g" c, G; Y! {9 K) a}
4 I: P% d1 D* Y/ K# Q. W' f1 u# J  `
: b2 I2 H7 [' ~* e1 @void        APU::QueueFlush()
! x2 e& u# |$ ~/ x" _{
4 {2 @, l1 S1 S, ~- r        while( queue.wrptr != queue.rdptr ) {
/ j9 J6 ?. n  A- A                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );0 s# I3 k7 j/ j/ @
                queue.rdptr++;
0 u  z9 r  e' N; I                queue.rdptr&=QUEUE_LENGTH-1;
! O: O) H6 g6 D8 C* Z! |- ?        }
7 v& ^9 t9 Z8 {) i
# ]# c( r5 T( D, @! [6 F5 i        while( exqueue.wrptr != exqueue.rdptr ) {) x) ]) i* B5 M& s; W% b
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );, z( y4 ~: I+ y9 ]- b- P
                exqueue.rdptr++;+ Y2 B6 T" m' w' N) z
                exqueue.rdptr&=QUEUE_LENGTH-1;
% m" ?: J% J  e, f* U6 e        }
1 D% p! t* B7 k; z; N}
( u/ Q0 M; x' Z9 n8 s9 N2 n2 ^
3 [) j2 h, e8 V2 bvoid        APU::SoundSetup()8 d" q9 A% {1 W( j. A: B
{
. u6 |- G/ E8 `* e  ]8 Y, C6 \        FLOAT        fClock = nes->nescfg->CpuClock;
% h" p) Q/ t7 ?3 n, S, s        INT        nRate = (INT)Config.sound.nRate;. I8 j, T6 I. c( \; |8 }$ Y
        internal.Setup( fClock, nRate );
) I( B, }' D- B  ]* Y$ V        vrc6.Setup( fClock, nRate );
* T; t- E& w1 m9 q/ c  m        vrc7.Setup( fClock, nRate );7 l5 c0 F* t' q- `- _) y
        mmc5.Setup( fClock, nRate );
3 M$ k9 D$ f# p! z: K, ~8 F        fds.Setup ( fClock, nRate );6 }8 ?1 j7 o2 ]/ |+ l- b# v
        n106.Setup( fClock, nRate );
9 t1 C6 P) S/ r5 F: B        fme7.Setup( fClock, nRate );
, T9 X) i2 c4 `4 N' x) z8 w. [}
! c2 p+ D3 _7 h: z; v" d& d- T; k9 D0 G" c$ u2 a" W
void        APU::Reset()7 l/ X' V; k# o
{3 ?/ o, i; z6 ?( Z9 W: C1 F# z3 Z2 g
        ZEROMEMORY( &queue, sizeof(queue) );9 t) @: }$ |/ r
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
, g+ }  D7 L3 g* b4 V* T
3 d; S% h8 i! }3 i7 Z6 @        elapsed_time = 0;
2 x2 Z. h8 w9 S6 i, a! v9 s0 b, T# }' k0 g' v6 T
        FLOAT        fClock = nes->nescfg->CpuClock;# X3 N. \4 Z( t0 Z9 _
        INT        nRate = (INT)Config.sound.nRate;7 [9 C" s0 \; q& y# K7 U/ k3 C
        internal.Reset( fClock, nRate );, U* b/ u% |+ x/ `# X  K9 c
        vrc6.Reset( fClock, nRate );
2 s6 P0 I# A' o% c& ?  Y        vrc7.Reset( fClock, nRate );
3 K% I9 s: t! |7 s        mmc5.Reset( fClock, nRate );6 ?. s! C; l# X  Y+ I
        fds.Reset ( fClock, nRate );7 b' v% }( y5 |6 {5 w+ p9 }
        n106.Reset( fClock, nRate );
8 Z1 r: p" G& h! k2 N: l9 R        fme7.Reset( fClock, nRate );( N) ^# z5 X+ _

! i& `  O4 v& ~: M        SoundSetup();% v- @  ?) D( @6 p" i6 p
}$ _( ]/ O9 m: {% B% H( v+ x7 w% i" F* L

$ N8 Y- H( P8 ]void        APU::SelectExSound( BYTE data )3 ?9 K# J. K" a) L) ]
{5 Z  x9 o' i( R/ w# b
        exsound_select = data;
- X* ?0 P1 }) m2 n' X4 Z! {}
5 H0 d9 O, D! `5 L  B# ^: I1 m* P7 s  b7 g
BYTE        APU::Read( WORD addr )9 e$ {! R/ g# Y0 D5 j; j' a# s
{) x$ _( K/ T; z! a3 W
        return        internal.SyncRead( addr );$ s# h8 t+ J7 u
}
% t7 O$ X/ h, L) ]4 m+ M/ H, K0 k* w# n( [
void        APU::Write( WORD addr, BYTE data )
$ C, I' u9 ?6 S6 a' |7 g7 ~{
. l3 J, g+ B) k( Q. ?: n0 Z. y        // $4018偼VirtuaNES屌桳億乕僩
: s3 [3 n3 m& G        if( addr >= 0x4000 && addr <= 0x401F ) {
9 N0 y0 X3 _% w4 V                internal.SyncWrite( addr, data );6 L; x/ l6 A/ t+ Z5 I8 a
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
/ j% w, P! G0 ^/ [! o; v& K        }
! E* U5 `. L' j$ Y) N  ~}+ ^/ V! H- [$ x( h9 v2 d$ C

/ r( E  k9 x# f4 x/ S! nBYTE        APU::ExRead( WORD addr )* w* j; j% q% _# K% b4 M/ l
{
- F2 V: E% x5 uBYTE        data = 0;
: Y0 j. N1 e/ L  C/ i/ I# _0 Z2 Z% N/ v  c+ l9 z3 L& \; d
        if( exsound_select & 0x10 ) {
2 S, v; Q0 w2 J/ S5 H                if( addr == 0x4800 ) {
6 u+ K- @; K8 J+ C+ a9 Y                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );& V  H/ m% g* z( X% m  U
                }
! ^$ d  K/ l/ d+ k        }8 j- T* G+ F( t0 a7 I. M; H) P' ^1 f
        if( exsound_select & 0x04 ) {/ y- b/ ?( v! L8 Q
                if( addr >= 0x4040 && addr < 0x4100 ) {) Y4 c/ f6 m7 Z0 s
                        data = fds.SyncRead( addr );* r0 P  u. d6 v1 v
                }5 h, c' j5 Y* ?& c, ]
        }
/ z/ y8 c  [' K0 ?        if( exsound_select & 0x08 ) {
- A2 k5 Z9 L9 l                if( addr >= 0x5000 && addr <= 0x5015 ) {
7 h- {& ^7 b4 Y9 Y$ ~                        data = mmc5.SyncRead( addr );& c. _; n1 j- Z# w8 S7 l2 d: u
                }
1 e7 U& g! Y% ~5 l4 S, q3 j/ \        }4 n% k# T* i' R! c+ x* D

' f/ D5 a  b' @) r2 w/ Y8 n# S1 J0 G        return        data;2 k7 z3 c9 w( O6 r
}
; }% C* Y3 {( N+ A. J2 [
4 @: k" l# {4 R6 o! G; Yvoid        APU::ExWrite( WORD addr, BYTE data )) L9 r3 B2 Y9 O/ y% y
{
5 b9 ?- W5 |: u3 r2 {  u        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
% q% c5 X) |7 ?0 |& f5 ~3 l& L3 a2 [4 X
        if( exsound_select & 0x04 ) {
- Y3 L# m  ?( V7 {7 P                if( addr >= 0x4040 && addr < 0x4100 ) {7 u% G, }3 @6 G8 h! H3 b& S4 R8 {
                        fds.SyncWrite( addr, data );4 u* E' [5 S. F5 ]) ]
                }1 l* k- F. K% V/ b
        }. \2 B* ~5 Z6 x! x

, [0 _2 Y$ s3 x/ i' P+ K        if( exsound_select & 0x08 ) {. S" q% p# I) a$ b4 B- |4 h
                if( addr >= 0x5000 && addr <= 0x5015 ) {% m2 H6 _+ |8 ]4 B0 s
                        mmc5.SyncWrite( addr, data );: O2 J6 w6 s. [3 ]% w3 |; g, O
                }# O3 t) {' \7 |1 O. f4 ]# q
        }
1 P/ N# ~0 R- W: e8 I1 }}
5 P- o9 `. h4 X( P
/ \$ W2 h) {6 @- ?3 s& W% e: Xvoid        APU::Sync()
$ X, @' \- U3 @4 z! n{7 D0 x  v& ?  ]3 H
}
0 b1 K! Q3 k: Y- e
* f3 u* h1 [( h, i3 Nvoid        APU::SyncDPCM( INT cycles )
9 a! |3 N! o$ c( i2 y  d% R0 p{
' W! o% j% k0 n5 U        internal.Sync( cycles );
. E- U1 U. ]0 [" R- t) e
2 _  E0 w+ ~" b        if( exsound_select & 0x04 ) {
" d2 F, }6 F+ u/ ?9 _1 p2 `                fds.Sync( cycles );8 o4 F& c/ c9 _4 J* L, F0 K+ [* y
        }
% a8 k6 h: H: g4 ?+ L        if( exsound_select & 0x08 ) {
# T2 X! F! J" J6 F: \# ?                mmc5.Sync( cycles );
$ q1 n) g* g$ j$ e8 z7 }8 q        }* }! u' a) {1 T7 C
}
! W2 [+ |' [+ _+ d; ^$ P8 n; c' k9 k4 X5 l- C& x
void        APU::WriteProcess( WORD addr, BYTE data )) E, D/ m3 c3 d4 @& }# q* s9 e" W" l
{! W" ]% e  W  t. K6 I% _
        // $4018偼VirtuaNES屌桳億乕僩( s, m$ g; Z: D4 E7 x& p
        if( addr >= 0x4000 && addr <= 0x401F ) {" r1 u2 T! N2 v) I
                internal.Write( addr, data );
( T6 x" K% J" w0 O, G        }
! C( @7 @0 u1 d}
$ o" N+ k5 y4 G9 D+ t; g' u7 z# m$ M" D) }3 ^+ w
void        APU::WriteExProcess( WORD addr, BYTE data )
9 Y+ F9 g: I/ L2 G1 t/ _2 i# E: M{; W8 \1 ~/ a" M/ h( i% e
        if( exsound_select & 0x01 ) {
/ g3 [; m" F& A# _                vrc6.Write( addr, data );
. V5 w: B, v+ a" l4 L        }! `) y2 b* B; a& B; U$ O3 F' w
        if( exsound_select & 0x02 ) {7 w6 U0 M% o8 W/ I/ M
                vrc7.Write( addr, data );
3 y; O; J* o2 J! s! S9 {( o        }+ s6 H6 G7 c: U/ }1 c5 I
        if( exsound_select & 0x04 ) {
% @+ b' G0 ?( d3 _                fds.Write( addr, data );' ~2 _! T9 p4 A) E
        }
; c! Z7 K$ d. g9 [& Z5 Y- c+ S( D: J        if( exsound_select & 0x08 ) {
4 a8 Z' _/ Q! t6 }                mmc5.Write( addr, data );
" E/ p) X0 P1 r; i# T7 r        }
8 h0 |* a8 v+ ?; Z- F8 }* d3 k5 F        if( exsound_select & 0x10 ) {
5 M4 O/ F/ u( u" y' k1 J( c                if( addr == 0x0000 ) {0 U) J& Q, Y0 x# R2 D1 i( Z8 t' T
                        BYTE        dummy = n106.Read( addr );
7 L5 L) E7 |5 L' N( D2 F2 `                } else {/ v, r! e; b$ ~# R4 C7 b' Y
                        n106.Write( addr, data );9 C' B' R8 l( X: q: r7 k
                }
# c2 K' b& k3 s        }
; w1 M+ k8 k* n! C" c- R        if( exsound_select & 0x20 ) {
$ V2 g  s# X2 r7 Y3 h; i, X                fme7.Write( addr, data );
& D5 P, B: p! [8 `' X2 P9 y+ J( Z        }+ k$ g! }0 \4 O! \, N& S9 ^
}
4 t; m# e) `9 w, F  P( |
! x* V0 b" K; G. D7 ?1 wvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )5 ?; @6 \2 T0 \+ ]9 f, x. U
{0 {) ~' W& G- M, w+ a3 k
INT        nBits = Config.sound.nBits;
: j% }# Z" u2 \) c) z( i; ^, gDWORD        dwLength = dwSize / (nBits/8);" _) n+ M8 ], F3 Q/ O# R; V  y6 O+ \  N
INT        output;# ~1 Y$ E/ N' Y9 m) K7 Q8 k5 t
QUEUEDATA q;
* i) w) z- w) T% w5 dDWORD        writetime;
  b7 x" W* c$ u, x+ o* T2 x& r6 B! {/ Y
LPSHORT        pSoundBuf = m_SoundBuffer;
; n3 {1 V3 W) X8 e& T( g) j2 xINT        nCcount = 0;# B$ t# W8 ]: u2 k" j
% o7 x2 i1 W5 L/ b( Y$ a( Q
INT        nFilterType = Config.sound.nFilterType;, q$ B2 }& c- ^; m& f

5 b0 ]( i4 h! o' u! P# h. d        if( !Config.sound.bEnable ) {2 t0 n# {8 `4 _! ]7 S
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
; ^/ G' c8 P+ n/ d                return;
$ H/ n4 O: ?$ Q; @# v  M$ t        }- [/ n; U6 u- W% d; b6 W

' r5 {/ |# i- t        // Volume setup( u$ v9 w9 F  n+ j' E
        //  0:Master6 m9 L' }( K. K4 u0 k
        //  1:Rectangle 1
( H, A, u) U7 {! R. C0 k7 f        //  2:Rectangle 2
( H  G& z4 r/ l. O6 [7 ~6 w+ ~        //  3:Triangle7 u( k0 ]. M1 [9 K
        //  4:Noise  P% s" }2 e0 f# J% r7 Q
        //  5:DPCM7 u  c- `5 O0 D; ]" p) }5 W
        //  6:VRC6) z& q' E8 P; R, ?6 C& i* c) Z
        //  7:VRC7
: q9 j& e, m, Q6 O$ m, q' q        //  8:FDS' R$ S3 e7 x6 B8 l- @8 G
        //  9:MMC5
. B/ H4 G+ W* s        // 10:N106+ y5 C( y7 k/ t( O7 T
        // 11:FME76 l! {) u; P. v
        INT        vol[24];
( ]' x) K1 F3 s4 S( P5 h        BOOL*        bMute = m_bMute;
- H# S1 L% Q) s& ~        SHORT*        nVolume = Config.sound.nVolume;
$ {' E4 h0 J/ y) ^% k) F3 {& c+ h- @4 \
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
! S/ a. F5 m2 M6 U
! z+ i' E: ]  M0 f  M        // Internal
" r8 {* y3 e! E  i" S; [9 r: b* u        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;3 I& z; X7 _1 i* y, M7 a
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;4 j+ b9 X. |: u5 M
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
, M; {4 [7 F7 c0 G# W- b, u! ^- k        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;/ \( _7 d/ _/ N
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;, m6 l( U7 v9 e( m

8 j+ x( K8 O, I* S0 ?: A: q, ?        // VRC6
! R1 A0 k. d* B# L        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
/ H% @/ P% T- W- |3 N6 u( _7 {        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
) V, M, E- M& h4 L        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;- a- L! i# g0 X+ D& [8 M1 I
9 O) t3 ^' K7 J- h% x
        // VRC71 g( s& r; q9 ]7 J- f5 F
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
9 B; K+ O/ s1 C- M/ s, J
9 S0 r# p4 `. @" h2 D        // FDS
3 f. @! e! W) z( ^        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;& Y3 J# a8 g6 T8 r& d7 O
; _  n9 R  I! X2 q5 O$ x) K: ~
        // MMC5
2 f+ m: Q  f$ J3 r2 u0 ?        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;/ M4 [1 F& T5 U" Q9 }) }' h, n2 ~
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;4 p( G% e$ L+ N  A5 o4 z3 R; f, i3 D2 t
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;0 `" ~% w3 F, P
6 C; U7 B: f& C2 r- o
        // N106
0 \4 Z( t' A# r( m% t        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;3 P, Q! l3 I' T
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 [: u& Q( M" P        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;# [0 m6 j6 I' ^/ w% E( x
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- E2 k' o1 Y2 N9 }# N; t0 p
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;3 n* @% T" A( s5 E) J5 A
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
5 F2 g; C0 D) l% _4 n        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;. y, k* G  N) m/ N+ P' u  i
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;! A* [3 H& N3 e/ f6 p3 Y" U* }

2 u: W. D6 T% |' t5 K: g        // FME7
6 ?0 R$ F! x/ P- ~        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;% ]/ F4 R6 M! V  w* S
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;( Q  P8 i! l5 W% w7 }) C2 d
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;( }6 V% l' E: e5 s+ \
7 a9 V! G& H9 m2 l* g
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;- m! }' \7 L. d
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
9 K/ \6 ]7 J7 P3 V2 O& E, F) b: _! d. Y6 g+ \0 U: j
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟5 I4 P! ]7 D+ h& w7 c4 ^
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
, M/ L' C" t" J                QueueFlush();
$ G6 d1 {. b* [7 d3 d4 `        }
8 T3 c) u5 F, q8 C9 Z/ C  n
; t& U5 Y; X- K( x3 Q- Z: c; u- S        while( dwLength-- ) {
# \" f; q4 {' c* w6 @8 }7 Z5 z3 V- i                writetime = (DWORD)elapsed_time;
# R+ z% W6 @9 L" `+ ^
5 |+ x) l3 h' M8 X# v/ B                while( GetQueue( writetime, q ) ) {2 f+ u. @7 D: i+ p0 F
                        WriteProcess( q.addr, q.data );1 z7 Y$ g. T3 d3 F6 i8 G
                }
6 ?4 k: \" r* |1 k6 R; H. p" P% p8 e& R1 S
                while( GetExQueue( writetime, q ) ) {
  q9 @7 }% j9 t& S5 e                        WriteExProcess( q.addr, q.data );4 h+ F* m! q: U1 e& p$ E
                }
) A; _  m) X3 k7 i2 u
2 D: |. T1 V9 ^0 L% r9 x                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME74 r+ A+ L3 b4 [9 i
                output = 0;
3 }/ S% m7 }# q                output += internal.Process( 0 )*vol[0];
, \% b' K5 S  m  H# I3 E* Y  |                output += internal.Process( 1 )*vol[1];
1 E# O9 _- i  z9 E2 k$ E                output += internal.Process( 2 )*vol[2];) f& @9 ?/ Q: g& {( ]5 }9 J
                output += internal.Process( 3 )*vol[3];
8 k1 l1 E. ~1 Q! l                output += internal.Process( 4 )*vol[4];' \$ O/ I1 Z2 R$ i( G; [

" _% o" O; n7 I                if( exsound_select & 0x01 ) {
" L5 n0 h, V9 R7 G/ y( V                        output += vrc6.Process( 0 )*vol[5];: p8 V7 M# s3 C5 _+ ?* S
                        output += vrc6.Process( 1 )*vol[6];
& r8 P$ J; B4 {* s- N. Z( q                        output += vrc6.Process( 2 )*vol[7];4 g3 F. Y* q! P* T
                }
% V1 o" t4 |+ J/ B9 e! J$ M                if( exsound_select & 0x02 ) {" y" _3 X2 T  a- N; f; I
                        output += vrc7.Process( 0 )*vol[8];* `1 E$ E: S6 b& u& \: a
                }6 _- C& k0 D! A+ m! V3 T
                if( exsound_select & 0x04 ) {
9 _4 h+ q- t( k; L! T" U                        output += fds.Process( 0 )*vol[9];, N, V* W% j  j3 M) O
                }
+ N5 p* }# C5 G; ^                if( exsound_select & 0x08 ) {  Q' }, P! d+ _. H8 F
                        output += mmc5.Process( 0 )*vol[10];1 i6 y. g  j5 o8 B
                        output += mmc5.Process( 1 )*vol[11];* K+ _2 T& _" h. v
                        output += mmc5.Process( 2 )*vol[12];' G. S+ M2 F  T
                }9 E1 _9 q+ D# K: T2 P/ ~
                if( exsound_select & 0x10 ) {0 c: v) U) i: T. r
                        output += n106.Process( 0 )*vol[13];% v0 }1 z8 y' p* |% u
                        output += n106.Process( 1 )*vol[14];. E2 d& }# t" m5 q% G
                        output += n106.Process( 2 )*vol[15];% P! S8 u( |7 R+ j5 d" j6 S
                        output += n106.Process( 3 )*vol[16];" Y) L0 Q3 J# H9 D
                        output += n106.Process( 4 )*vol[17];
! ?4 [% @6 `, J8 ]2 F6 I                        output += n106.Process( 5 )*vol[18];5 p" Y: u) F/ O# c! ~" c5 S
                        output += n106.Process( 6 )*vol[19];$ M: ?( `7 W7 w, e  A& c+ `
                        output += n106.Process( 7 )*vol[20];
4 B' O# L  C. n5 W  j$ i3 c                }2 s) a1 h& ]4 j( S1 X0 R
                if( exsound_select & 0x20 ) {
! L5 e: X7 h- X$ t                        fme7.Process( 3 );        // Envelope & Noise
1 w, c% @, E' n! _/ R0 O' O+ {                        output += fme7.Process( 0 )*vol[21];
* M# D- f" K6 g; X5 Z                        output += fme7.Process( 1 )*vol[22];
) e, ^# P- `: }- ~' m2 A                        output += fme7.Process( 2 )*vol[23];0 y  s/ e' y6 o/ A- k- F
                }7 ]+ H4 n5 \3 ~  W
6 M3 d- V# A4 }# N6 @
                output >>= 8;- s' i" ~0 }# P( I2 O
1 @% D. @/ g( P; A2 ^
                if( nFilterType == 1 ) {' W2 z  R' n& C: X) n  T
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)8 N' _7 e$ w8 w5 [
                        output = (lowpass_filter[0]+output)/2;3 K8 b" W9 y8 @0 w$ {
                        lowpass_filter[0] = output;
4 {- ~2 s" ~( f. C                } else if( nFilterType == 2 ) {
" l  J1 Q5 F  u/ X/ k. U                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)0 _9 ?' ^& D, ?3 n
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
* @0 p/ B3 \8 p1 Q% M                        lowpass_filter[1] = lowpass_filter[0];; ^; @) F' x! x! x
                        lowpass_filter[0] = output;0 N' i6 D2 Y) V8 o3 i
                } else if( nFilterType == 3 ) {  Y( E) t8 A: w( e8 B+ R& T
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
5 }( R  o( ~! d7 W) Y8 r  L% B& N                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
, [0 t9 n4 i" |) m% Y5 C                        lowpass_filter[2] = lowpass_filter[1];
4 Q5 b7 ~' U1 V6 d# K' A. V- g% [3 U                        lowpass_filter[1] = lowpass_filter[0];2 Y( ?! i" Q7 j! _1 L
                        lowpass_filter[0] = output;
! O% e# Y0 {- e                } else if( nFilterType == 4 ) {
4 O9 A) `. ^" [' x& p( o/ D6 ]                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
- _. I: y" f# ~2 h$ d2 W( M/ V                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
# b1 n1 X1 s) m: N9 T                        lowpass_filter[1] = lowpass_filter[0];' \( e6 p$ t! T+ c0 L( b) X% S
                        lowpass_filter[0] = output;( v" y2 ^7 M$ g
                }# {9 S0 R! r/ K. H( o, N6 I& f
" ]3 ?9 y, x& [/ s4 Y( ~* T8 O* ~
#if        0
% V# x1 c5 Z6 h( q, w- z0 f( J& V                // DC惉暘偺僇僢僩2 V* V! {4 C! u
                {2 _; v6 F3 u9 H' B7 M
                static double ave = 0.0, max=0.0, min=0.0;
4 T! W# b2 _) x' Y' A* q                double delta;4 ^- z- _( Q6 Z  `) q1 `
                delta = (max-min)/32768.0;( Z3 j/ c* Y" U9 @, H; j/ c& T
                max -= delta;8 T1 W9 m! ?9 Z# |
                min += delta;0 y1 y8 d& c* \% m" U4 [
                if( output > max ) max = output;
6 O3 s% i, q* ]                if( output < min ) min = output;2 n! x1 r3 F) ~# _+ [/ v& G9 D! ^* f
                ave -= ave/1024.0;4 L' c5 l/ F  E; \9 P1 L
                ave += (max+min)/2048.0;
2 t3 U0 Q! l- J- v+ c& ]! b                output -= (INT)ave;
' r0 K+ m3 ]4 e: m                }
9 F8 j! s* B" E. [#endif+ Y$ \, d3 T5 v! u% f( f. j
#if        17 ~5 I% Q+ D- W7 d% u' K: ]8 {" O
                // DC惉暘偺僇僢僩(HPF TEST)
1 w9 ]8 U) X- w5 W2 e% j                {6 O/ U; P6 q/ O, c
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);8 y- c# ^( a. G" F' P4 ?) @( v
                static        double        cutofftemp = (2.0*3.141592653579*40.0);# g8 p$ Z6 F) p; E6 g5 Q7 Z7 x
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
7 A8 V1 X4 I- [: I- c: o6 h                static        double        tmp = 0.0;" T2 N! p9 ^: F9 T. }
                double        in, out;9 l. |) s1 M, Q
% t. O& H7 u- U3 V# T5 T
                in = (double)output;" N; L+ G/ T# e. J- y$ Z8 [4 L4 |
                out = (in - tmp);. O" |# H/ d  w* o
                tmp = tmp + cutoff * out;
" K9 }7 s' H0 b0 m
' a( K! ]  A. V% p0 n, ]                output = (INT)out;
' _# S* V, u- H9 V                }
' D: h& i- l( \6 A#endif5 E0 d, T: X) |& s
#if        0
* d+ F  d- g, ~* G7 i4 K                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
) B( o+ ?( S* B; ^$ O6 `. L                {
+ [) O+ k& }0 u/ k, A/ R, w3 n                INT        diff = abs(output-last_data);
5 A1 a" _9 D  t) F+ r6 P' Q                if( diff > 0x4000 ) {
1 b! D5 U- R  y6 w( g( m                        output /= 4;) N3 k9 K$ r5 x
                } else
+ ]! {1 `/ H/ y& F                if( diff > 0x3000 ) {
6 f7 K' v, O' C+ \. X2 w                        output /= 3;
  ?, Y( q6 v& t% w                } else
! S: j* c1 b' _, N3 |4 G                if( diff > 0x2000 ) {  e! Z  c5 b. w' `: |  r, {
                        output /= 2;
2 n( i4 ]' K( i" ^/ ^* x1 e7 H                }* ]: E4 i! S& l$ @+ y7 D# T
                last_data = output;
' N" O6 x3 q. o3 o3 Y1 v                }& `9 y; A( ?1 o& n6 o' a0 r
#endif* J* q4 i4 S; ?% `3 S5 Q* X/ m6 k- {
                // Limit0 L- D9 p5 D7 t
                if( output > 0x7FFF ) {. O+ A4 u5 q' K) p  |) z
                        output = 0x7FFF;
3 T5 M0 ?6 c" b9 S                } else if( output < -0x8000 ) {  Y" l7 y- C  l) v6 `  o2 `7 m+ t5 V
                        output = -0x8000;! f* s8 x" a* A' C3 E7 A
                }( V: F4 m4 D8 O8 h' t

+ q1 Y3 s. j- k1 \' c                if( nBits != 8 ) {, J; x# X# ~+ Y$ r" \
                        *(SHORT*)lpBuffer = (SHORT)output;
) N* Z, u2 S2 `7 _- w8 `* q                        lpBuffer += sizeof(SHORT);3 m/ v8 M, e" ]4 @$ `
                } else {
! c; {+ R; K& x$ E2 x9 {                        *lpBuffer++ = (output>>8)^0x80;( g- I9 e8 H/ u& a
                }2 j  M: j4 B; g
+ ?2 x$ O; A. i8 M' v
                if( nCcount < 0x0100 )
8 `1 i% }7 e5 y; l                        pSoundBuf[nCcount++] = (SHORT)output;2 w: N) V6 z: V6 K+ p+ v
6 P; B" |, d0 ?7 K5 S" d# o' L' |
//                elapsedtime += cycle_rate;
) j# Q% M% M; H                elapsed_time += cycle_rate;
5 ?5 c  A1 ]1 w. q        }$ P( v- n( C9 r4 z4 @" a
; j; Q* d' V3 v% z
#if        1" E1 O7 @7 g/ j7 \- p8 `; A+ B6 |
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
% q, K" P4 D/ d' P3 B* R$ i                elapsed_time = nes->cpu->GetTotalCycles();
( @, C* J5 b7 w6 l  ?        }; B2 u: ^5 C) J2 ~
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {7 z; Y. K$ H' T
                elapsed_time = nes->cpu->GetTotalCycles();0 z* L& u: |8 R& N% h4 l/ `3 U7 [
        }
) g8 W# M/ {& a, ^1 m1 U8 s1 M#else
  @7 e$ |# V* D        elapsed_time = nes->cpu->GetTotalCycles();: w# x# s' Y2 ~( M6 C
#endif7 T' G, S' d' u$ X7 l+ u4 t, Y* Y
}
$ G7 C3 B" I8 `; Z! U
1 ]  o0 k' ~/ u8 E// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
' K7 M2 z% r8 p5 aINT        APU::GetChannelFrequency( INT no )3 H3 k- o! ]( W
{
$ W; d  F0 V1 B        if( !m_bMute[0] ): N- k, u+ b6 x" ~0 J
                return        0;) G# N/ k$ C: \6 j/ N: @
' D' C! u& l: k% n
        // Internal3 K4 R: [2 W- m( F9 [# g9 E
        if( no < 5 ) {# \" m; B; O- G: H% H: J( S
                return        m_bMute[no+1]?internal.GetFreq( no ):0;6 t9 D8 _/ m4 w2 ^/ ]( E, V+ V
        }$ S" {, D% t2 ^8 W5 M: L# @
        // VRC6: f* _$ }% A" \' \( O5 c
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
6 C3 v9 F& a+ X" t3 U                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;, r7 V1 _8 g; q0 M6 w; k; O
        }
( E# l( d3 |( q        // FDS6 g) ?$ d% \% G, k# h+ R
        if( (exsound_select & 0x04) && no == 0x300 ) {
& p( n! K* [9 W- A                return        m_bMute[6]?fds.GetFreq( 0 ):0;/ p  J/ g0 j2 G3 a' }
        }% \2 y3 G( ^$ y; J) ]+ Z
        // MMC5; W' Y# `8 p- n- M8 K5 z
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
' I( ?9 d8 k: s( N/ S                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
9 q$ w7 @2 U5 Z- T, a8 V+ d        }
5 E  t, K) j" |4 q6 N4 _% y! Q        // N1064 R9 h* e4 [% D! ~' M% B
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {4 W0 N2 @6 B5 _. ^$ `9 U" Z) ^# ~
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;% U6 u% ]; X- h
        }
( R0 A  T7 t7 f/ E        // FME7" t8 ~* w9 n5 h7 v' q' H
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {3 @7 p' |! p7 F  L; [; z1 `: n
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;6 Y! b+ P% M1 M3 ^8 ]: P
        }
! w, `' A# K) |( y! \/ g8 _        // VRC70 `: |! F/ [9 z, Z' R) _6 @
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {" `4 T1 z( g& {) F8 n
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;# l2 c1 ~* B* S
        }
0 C$ R( q0 V) F2 ^! m* p5 d/ J        return        0;
/ h. ]' f) ^; \  y# [" Y}; j) o2 B5 ^5 K/ T  N

  V& w( s4 n. ^8 G: Q" h// State Save/Load9 }1 C+ B+ A) I$ q9 Z1 l3 g
void        APU::SaveState( LPBYTE p )
! V) e6 o; ^5 N5 S& i{% R: j# p$ }: B3 m
#ifdef        _DEBUG
& i2 X1 B3 F+ u; n8 e# |& M5 h* dLPBYTE        pold = p;
3 x& b  m9 _9 m. O; z4 x#endif5 W7 ]$ p" M) T& w

5 X3 T/ b3 O( ?$ ^" E8 r        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞% l; C  n% a; i
        QueueFlush();! A1 i9 A- a6 G) h

' R$ X* A4 i$ I4 g        internal.SaveState( p );
  N+ x4 N4 A: d! i( p2 T1 H: J; o        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
3 |/ q$ L- w- B, g0 k7 J
- h  b: ^( a7 K2 {) Z4 O7 f        // VRC6) C2 w5 W6 P& M2 G/ e" ?
        if( exsound_select & 0x01 ) {, k( ^1 ^3 h( L4 U
                vrc6.SaveState( p );# s9 j: g6 e2 I3 B1 v! A1 j4 D
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding* D1 H0 K6 n$ J, t8 N5 n
        }
2 i: j( C: ]5 w) U        // VRC7 (not support)
3 V" B: d7 z9 K7 o        if( exsound_select & 0x02 ) {! ^0 K6 o* b: W$ ?! _" C% {
                vrc7.SaveState( p );
& `# z9 A3 h) o4 ?& m                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding5 C7 O4 L" L9 B. u8 [, T' N! q
        }* N- w* Y8 \, I, S: ~, d4 h
        // FDS% j: D% N( w/ Q3 R9 H/ ]0 S
        if( exsound_select & 0x04 ) {" w9 J( R' v5 k, B) F; ?( }) P0 g
                fds.SaveState( p );! l7 i, ]& T6 b" N, `
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
4 }! ]) n% \0 z        }. ^0 p( Q5 V8 h& C' Z6 D
        // MMC5
5 t6 V* J" I5 ?3 }% s/ a2 \. n; O        if( exsound_select & 0x08 ) {9 X& B4 S# B4 `  _7 M" T/ M( \
                mmc5.SaveState( p );4 E1 a$ H# C, q( R; s
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding- a% [6 J; w' |2 p( v( _
        }, z1 m" `5 p; M
        // N106: S; w% [2 j9 b1 g6 z
        if( exsound_select & 0x10 ) {4 m; G2 f! M8 y7 G$ i, L
                n106.SaveState( p );5 H* ~' _! d6 _; h% p
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding- Q; D' H+ G3 o. |
        }
1 g* _$ T& }( h        // FME7  H- M0 Y+ A- U) _4 U
        if( exsound_select & 0x20 ) {
5 u! U0 K% }* h% T' f, e8 S5 s                fme7.SaveState( p );& `4 O& G1 }5 U
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding! [+ f  V* a7 j; |$ l" ~
        }
7 Q5 ~, c3 ^' v8 y' U, {. U& v  W# z4 K8 F  {
#ifdef        _DEBUG
& D# O  o- B0 `# e. W$ sDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );: c& r/ D+ W5 c# N' ?3 s( o% a
#endif  ~1 v- l. f4 R" D8 {! o/ ?" ~# F
}5 ^4 g% ~' C8 x) ~; A5 V2 l

2 T5 T' ^* r4 a5 ]7 u0 }9 cvoid        APU::LoadState( LPBYTE p )
9 Z! i  \% I0 G" U& Q" q% z{
/ `" a9 M2 [% }8 @# _        // 帪娫幉傪摨婜偝偣傞堊偵徚偡9 [$ M5 O" y3 r  X% M) [
        QueueClear();
% r  J' V" |$ J7 A
/ T- g& t& x+ g( }3 j) B; c, e        internal.LoadState( p );
5 t' @/ [8 c' W$ {5 U* x        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding3 r* y$ y$ z7 v$ l6 O+ p, W0 ]4 N, v
5 g( Z! g* B% D, O- O
        // VRC6$ q) y. Q6 w3 O! `3 c' ?' M% f- w
        if( exsound_select & 0x01 ) {
% ]% c: N, G5 w' Z4 y" @                vrc6.LoadState( p );
9 l. u( S$ J# b1 g, u2 T, |; i                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
7 Q) W8 y/ q  I/ b0 U        }+ C2 s* W  U$ `3 p! b: F/ X/ z3 R9 o
        // VRC7 (not support)4 }3 d$ e; }/ Q
        if( exsound_select & 0x02 ) {0 Z2 b' T9 E5 W* Q
                vrc7.LoadState( p );$ \/ J- ?: i, p$ I, M7 C1 e
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding) A4 j! i2 b& a8 q. z4 o6 C2 K
        }
- ~# Q4 `% n- A        // FDS& o9 t0 F: a* m  i* g" s( ]: b7 d
        if( exsound_select & 0x04 ) {
3 H/ Y. `0 ^* E7 x9 i# d                fds.LoadState( p );
. L" b* ~1 }3 ]" D+ y1 [6 B                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
( @% h6 x2 F: j+ v8 z) ~        }
0 H* F/ k$ r( |* c  f        // MMC5
6 _% Z8 U/ ~. }. X! \, w, {8 A        if( exsound_select & 0x08 ) {
6 `3 F. F+ D% Q! O                mmc5.LoadState( p );4 M% o- {6 k% K; P2 [
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding/ L0 v9 s( ?; ?2 N0 ]4 T2 \2 h% {
        }0 u. Q) ~, [( J4 k
        // N106
3 O! Z+ J, r- L  ~9 L0 Z- N        if( exsound_select & 0x10 ) {
5 X0 i% J! i* f( P, I# }                n106.LoadState( p );
# P' D8 ~6 w) p- u                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
! y. h( c" d8 a( |+ c' c4 P        }: D9 }/ e# D2 P  \
        // FME7
" k( x6 M6 r& {" A" H        if( exsound_select & 0x20 ) {/ z1 y+ Q- W. b
                fme7.LoadState( p );
/ ?; ~6 q. ?/ A* o; `& i' T                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
- f) D& b3 _5 y8 B4 k5 y        }
" u* Y4 Y) C! D8 O9 V3 S}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 * T$ w+ [( p, c: S- @/ m
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。. t, d' b8 F5 Y6 |6 L* \# p
感激不尽~~
% n6 u, |/ {; H2 b+ T: k+ V
恩 我對模擬器不是很有研究,7 ~/ G5 C( h0 E
雖然要了解源碼內容,可能不是很困難,
. l$ g) u( X, ^  u" ~  u4 ?不過還是要花時間,個人目前蠻忙碌的。
- a& ]7 V( C' c  i+ s/ Q
8 N% E% t- ~; E3 t6 N9 D4 @給你一個朋友的MSN,你可以跟他討論看看,  S" l# H/ h" j! z2 `7 G: s
他本身是程式設計師,也對FC模擬器很有興趣。4 Z; ~  J# @7 W1 {! |
( ~9 K2 {0 M6 v5 c7 |7 ~( F
MSN我就PM到你的信箱了。5 t! W3 D( l; i* U4 X; v6 W1 Y
$ Q& C4 H+ E! B$ l# q
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 # H6 @' _% L; ^7 T$ E
呵…… 谢过团长大人~~

( Y  |" c" T. G
+ F/ l) \; \* l" a) c% }; ^# T哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
  B: p% O5 u, D( H* N9 }团长的朋友都是神,那团长就是神的boss。

( l4 ~& {8 N3 e& Z( _哈 不敢當,我只是個平凡人,
  M- O; I  N7 @$ A+ ]  e0 M要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙! V" s& e: H2 S1 S  C
ZYH
0 ?7 a$ ^2 ^! o0 ]. iQQ:4147343069 j6 I( w9 t0 w  r2 d/ C0 V' {
Mail:zyh-01@126.com+ ?8 K/ l2 ]) U; w* ~

: {" x( h; S. u- q0 \他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表   ]4 n0 K) j6 H! ?8 p# \
再次对团长大人和悠悠哥的无私帮助表示感谢~~

- E! S" f4 y/ ~/ m0 i! {+ ^: N) p- a不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-2-2 03:45 , Processed in 1.079102 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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