EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。: G0 ?% b) y  f# ]2 {2 t7 V- R4 |
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~' l* b1 l/ u. o2 F$ Q5 Y
这里有相应的模拟器源码,就当送给大侠了~~
/ V! c8 x; O+ f( q. X' z0 xhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 # T; d" I, @% Q& z* \1 h
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。, _) X/ L* b9 X( W( l. G8 ?
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~- t7 I9 C4 ~, k2 g9 M5 w8 i/ t% U
这里有相应的模拟器源码,就当送给大侠 ...
+ F+ s- Y% e! c* U" L
聲音部分(Audoi Process Unit = APU):, r3 ?8 h1 {+ C& K
.\NES\APU.cpp, P0 n+ l' z+ n. Z- \' W% A4 k
.\NES\APU.h
2 Q8 ?% t6 R8 R! M, O
0 Q  f8 q3 Q3 e2 B/ S& K4 M; D- y5 s$ B/ U; B
影像處理部份(Picture Processing Unit = PPU):
) G, W0 O% @4 G- Q/ X: N.\NES\PPU.cpp7 @3 Q1 f% G# ?* z# y' H
.\NES\PPU.h
4 l8 Q9 K9 `" j+ c
6 D& k0 I2 E1 i( G9 j! @- _如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:% d, J! L, l& m# P# A1 s! m
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
9 K- P& F9 C7 E$ ?8 ]//////////////////////////////////////////////////////////////////////////  w0 S% h. l1 F, f
//                                                                      //* J8 {! a6 j7 m6 |2 T) o
//      NES APU core                                                    //6 j6 w' l5 h3 _) V( V, k
//                                                           Norix      //, d1 u( N/ W4 m3 c; a4 x
//                                               written     2002/06/27 //% g3 ?9 L$ n  X% m& ~0 ]
//                                               last modify ----/--/-- //
6 D+ f! j: k9 H' Z//////////////////////////////////////////////////////////////////////////( E0 d# ~: k; w' _: H
#include "DebugOut.h"
/ o! W* {0 ~8 l% J#include "App.h"
9 u) M5 X3 [& z+ e: d7 ]0 f+ P#include "Config.h"% }# V+ i% q  @2 l8 z3 z& S& M
. ], L+ W6 m/ R' g+ X: t7 J, @
#include "nes.h"
2 C" U" O# d; _# N#include "mmu.h"
+ }6 o5 x! r" U8 r3 |9 @7 o7 c: A#include "cpu.h"
* U7 v: ]5 r5 f; ^: d/ k* q9 n#include "ppu.h"! ]( Z! |. _' n$ r
#include "rom.h"7 Y. f2 d" h9 q4 a8 L$ d+ C5 R8 O
#include "apu.h"# i6 J& Z+ Q! P
9 J  H# a7 H1 B( g
// Volume adjust* W' J9 ~- E0 ~* F/ g1 I
// Internal sounds8 A4 U) `7 ~6 o( A: T
#define        RECTANGLE_VOL        (0x0F0)3 {2 ]' k/ L& m! b
#define        TRIANGLE_VOL        (0x130)1 L% y! [0 O+ d& {' N6 j# w& \
#define        NOISE_VOL        (0x0C0)
9 y- }3 h. T2 x* J6 I#define        DPCM_VOL        (0x0F0)
/ M2 g* V$ O  [  r. j) D// Extra sounds2 L; l# p8 f/ Y# }8 _: L$ S
#define        VRC6_VOL        (0x0F0)
; D1 U: \( |/ D' T( h) N#define        VRC7_VOL        (0x130)
1 q4 x& d& F( i8 ]#define        FDS_VOL                (0x0F0)
% g) b. x2 _+ m/ l' s' A#define        MMC5_VOL        (0x0F0)
' G& X2 s" n3 @. s4 C  j" O8 H# r#define        N106_VOL        (0x088)
, c+ u+ [& M$ U#define        FME7_VOL        (0x130)
! }8 C& C' E- h" @
* Y3 X- S# s: E$ gAPU::APU( NES* parent )7 f' ~+ J/ W1 S3 t
{% H# G- [! d) D* y: A
        exsound_select = 0;
# I* _- v0 E1 f/ z4 i5 r+ k: a
2 W3 F" m/ _! I/ G! M7 f& D$ Z        nes = parent;, w4 v1 p7 A& W* y4 K
        internal.SetParent( parent );
( [( s2 u8 C8 m" D5 e& B* Z% ~2 b$ b9 C4 ]& d8 h: J* E
        last_data = last_diff = 0;
+ @/ E( u+ m5 [8 C  N7 H1 K, n* k; e9 W
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
0 K  r) c6 e8 c" s- f0 Z* m* _
  [/ _; {" i- q: u        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
4 j4 D/ ~+ y) H: g5 r0 B, k4 m        ZEROMEMORY( &queue, sizeof(queue) );1 D" Z7 |8 X' h. C
        ZEROMEMORY( &exqueue, sizeof(exqueue) );6 C% U7 |* u( A" [# v# U; K+ A

" h1 e. n* t7 a        for( INT i = 0; i < 16; i++ ) {; T$ `: c- }% s5 S1 e: c
                m_bMute = TRUE;
: h+ R; E/ O, `" D* I        }
, P6 t1 N2 p4 ~9 i: l2 ~+ N! d" ?}1 q9 q$ r7 m  E8 G3 C2 e' N

- H- D8 i. m3 @) k8 v4 ]  AAPU::~APU()
( m% j' i% F/ ^! Z{5 m- x: ]. g- k7 _: z0 l
}, C1 G) ~( B) T5 r7 e

) F; p  @$ a' G, ^% j7 t7 R; s2 I8 Hvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
$ ^2 ~+ F5 I! }{
; H5 Y7 U2 E; p. Q; R7 M  {, n        queue.data[queue.wrptr].time = writetime;
% ?% w: S$ l% ^( y3 l5 b/ q        queue.data[queue.wrptr].addr = addr;
/ Y/ X+ i) q0 I& w% E5 b: k        queue.data[queue.wrptr].data = data;
# C1 B! p# T5 {8 G! h% k        queue.wrptr++;
( B6 Y4 k, x( W$ D        queue.wrptr&=QUEUE_LENGTH-1;
' l& }/ X+ h5 L! U        if( queue.wrptr == queue.rdptr ) {. r7 w- B) z1 F2 G9 \7 J
                DEBUGOUT( "queue overflow.\n" );# Q0 P" r; {, Y* |6 M) h
        }5 A% {) D" l( J$ j' ~
}$ N* p6 |8 `( t% N

9 m, D1 G% h$ fBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
% N9 z, ?& [2 n# N" k( N6 b{- k$ m2 Y* |" S: Y
        if( queue.wrptr == queue.rdptr ) {
# v0 y- S! i* H8 |- w- B5 {) B' y                return        FALSE;+ e9 Y" M1 f0 o  f5 a, B
        }
" c7 T% R- p# Y* O" M& B        if( queue.data[queue.rdptr].time <= writetime ) {
+ x3 `3 `+ b1 r3 d" M5 p- q                ret = queue.data[queue.rdptr];, ?+ W7 Z4 y- U( M0 x. ?4 z+ v
                queue.rdptr++;
6 v' W  b3 G" g+ [% i6 i- u, }                queue.rdptr&=QUEUE_LENGTH-1;7 S7 x. D& y1 [; V! R! e
                return        TRUE;0 z* p7 [# I8 _, w* J! _" L
        }* A4 {* C, i$ n+ D3 s$ [) s  H
        return        FALSE;
7 X9 Y# t' P2 u. [}
- F2 N3 a: a/ \& B  e
. g% @( ]+ v8 Q- e  T9 T* mvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
- P7 f5 W% w4 ~" j& x{
/ p+ P3 B, `+ |/ d- A- `7 q9 r        exqueue.data[exqueue.wrptr].time = writetime;# D$ B; r: k4 `7 h( ^9 @
        exqueue.data[exqueue.wrptr].addr = addr;% }! A$ S" @. s  b, S: D
        exqueue.data[exqueue.wrptr].data = data;
# r9 N3 n  \' y4 K$ v        exqueue.wrptr++;
4 [6 E$ U3 L! D" A        exqueue.wrptr&=QUEUE_LENGTH-1;
' d" C5 d& Y# x/ J$ Y        if( exqueue.wrptr == exqueue.rdptr ) {3 ?8 ^9 _+ C* F2 o( s( Q( Z" |
                DEBUGOUT( "exqueue overflow.\n" );
: n- t# S8 T9 B' @2 A- @0 I' `        }
- ?1 _! O( H8 b; u# s}
7 {1 `4 l9 N8 P# x( Z! {
0 j5 J8 ~0 }* Y. H$ `2 uBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )' Z  J# h" M( x% v; a
{  a& Q' f0 V: f, Y' b$ |9 `
        if( exqueue.wrptr == exqueue.rdptr ) {
" O) E2 y, x% d                return        FALSE;% Q  `/ U0 c1 g( W! Z: b
        }
8 x7 ^) a2 H5 r1 |6 B        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
0 e4 g& z& z! s: Y" {7 r- M7 I* j                ret = exqueue.data[exqueue.rdptr];
4 x8 `4 J9 s1 \; v1 x* D/ u. k                exqueue.rdptr++;! D6 B3 o/ A* t0 d; |1 }8 V
                exqueue.rdptr&=QUEUE_LENGTH-1;
; x0 t: f, U5 @, `# Q9 d                return        TRUE;
7 l9 {, s3 O" @9 X" w, ]+ a( G        }
0 s' o0 s. ?6 u& z5 P9 M        return        FALSE;  e( N+ u' N2 e$ a) V* H
}
! G* T+ S; d+ q& H5 a1 j0 ]
* P: A9 W! F0 avoid        APU::QueueClear()
7 m9 r  W$ F8 b: E/ f{
$ l. R: @6 E- m+ k1 X! O4 L        ZEROMEMORY( &queue, sizeof(queue) );
' M  ]) `( [1 v' t6 _2 P! }        ZEROMEMORY( &exqueue, sizeof(exqueue) );% Y/ V% `2 s# r! v* W7 e2 m6 K
}
3 h) u/ ?3 `; \* r% L: a- N# V! F9 ^. J4 N% C
void        APU::QueueFlush()
9 b; b/ Z+ x' s2 ?1 x. O) C{
$ g* u* J/ o4 y, R, c) o' O        while( queue.wrptr != queue.rdptr ) {& [0 m' O5 S: r! _( ~
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
8 p' A1 q5 j3 v                queue.rdptr++;+ [: h6 C. n- T6 q, k
                queue.rdptr&=QUEUE_LENGTH-1;
& k# F. e! b5 M/ y1 k  P9 [" T        }; n7 I' r* D( e; {0 a* q0 V" C

0 C* O9 U2 O; y2 D4 |$ Z' q        while( exqueue.wrptr != exqueue.rdptr ) {
- O# K! E8 @) W3 q                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
; y% b6 C3 Y1 h+ b* k                exqueue.rdptr++;( V+ R& \; W- [/ }3 H# a
                exqueue.rdptr&=QUEUE_LENGTH-1;" I& `  B$ j/ U% S/ X  \4 q8 s- G1 ^
        }
/ T5 @6 d. @/ D& m9 V& I}' X# u, e# M; P* g+ E, L

* ~# J& ~; P* j8 m  \+ uvoid        APU::SoundSetup()# P3 Z0 ~1 [; e, S5 x
{; a# V& s8 q$ ?% b
        FLOAT        fClock = nes->nescfg->CpuClock;
" n% X/ U5 b+ T' [2 d! v0 z        INT        nRate = (INT)Config.sound.nRate;
# p/ b, q! M$ g+ s3 }" O        internal.Setup( fClock, nRate );
6 M, i# [" V" z8 Q        vrc6.Setup( fClock, nRate );2 ]* @9 p& @0 q( z8 {0 t! j, M
        vrc7.Setup( fClock, nRate );
% }7 |4 v% L! d8 k        mmc5.Setup( fClock, nRate );
. ?( F5 l3 ~8 q4 A& K1 K        fds.Setup ( fClock, nRate );
3 _7 R: F- V1 r        n106.Setup( fClock, nRate );
( E/ o, T  |* i3 p$ o5 h        fme7.Setup( fClock, nRate );  u2 ^; O- u: p, h: [
}
5 f3 m7 ]6 c0 c$ a: E6 ^9 J: H, z- T5 `3 [- }. I: ^
void        APU::Reset()
2 K% W( Q& g: ]  Y{; j0 K, g6 {- ~' \
        ZEROMEMORY( &queue, sizeof(queue) );
' ]2 x/ }) J* m2 T9 u; b* U/ P, t        ZEROMEMORY( &exqueue, sizeof(exqueue) );5 A; g1 |3 l" \- V0 y/ ~) D( ^

1 n# z  q0 W1 k1 F2 W8 j% ^        elapsed_time = 0;
9 e/ O7 s/ y' ]
- I2 [2 D+ _& o5 w4 ?' @        FLOAT        fClock = nes->nescfg->CpuClock;
8 o" C0 u6 c, `$ A8 f) L4 }1 p        INT        nRate = (INT)Config.sound.nRate;
6 U, q- G8 j# |/ `$ t* I* |) q& f        internal.Reset( fClock, nRate );4 Y( K3 `- n8 |  e$ H
        vrc6.Reset( fClock, nRate );
/ S% K; R* H  O1 S        vrc7.Reset( fClock, nRate );
9 |# T0 B; M3 ^        mmc5.Reset( fClock, nRate );& P  M) j8 r. S. G* C
        fds.Reset ( fClock, nRate );
* Y4 `$ l7 u3 G7 P. c3 ~7 _1 Q' j        n106.Reset( fClock, nRate );2 F3 ~# p8 [' M- v
        fme7.Reset( fClock, nRate );
% o. {. k8 L' h2 P" m5 h* L4 [- s$ H! C) H* w. H
        SoundSetup();
' K$ J! _- a  E: L; ?}
7 S% k; h2 o6 E9 W
% ^7 F2 l( `. e5 z6 s; m# R0 evoid        APU::SelectExSound( BYTE data )
8 x7 {0 D/ ^3 v4 @6 [3 B{+ J4 v+ J& N& g7 x6 l
        exsound_select = data;5 A0 Y7 D* U0 s: v! X% W4 g  j
}1 a9 s' Q7 b1 c$ p8 z5 n

8 I/ t) y( \+ l4 P* V- r7 S/ NBYTE        APU::Read( WORD addr )
9 c, W3 Z; h9 q4 w8 I6 [, O7 l{
+ Q, K3 A5 ^% g* j( e. o        return        internal.SyncRead( addr );
" V) m# Y7 _, R6 F}
) P' a4 A  q* E2 p. e! B3 r. L4 s7 H6 \6 }+ r
void        APU::Write( WORD addr, BYTE data )3 y0 R0 R8 K; }
{
5 Y9 M9 w- I! a  L. G& D        // $4018偼VirtuaNES屌桳億乕僩
' {3 h6 |( y  `" H0 N  J2 e        if( addr >= 0x4000 && addr <= 0x401F ) {
4 q2 x1 K4 n7 Y9 M2 L, u6 R: k                internal.SyncWrite( addr, data );/ e4 h7 c5 L  U" s/ a
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );/ e3 N: H: |7 H* ^* G/ c+ i
        }" C: k7 d# Q1 o: c
}4 V' s0 {" x) u  q! L7 ~9 Z. R5 H
0 w6 R" \- }* [
BYTE        APU::ExRead( WORD addr )
" t! L, f' Y9 G$ u5 Q! j{
9 _3 y! m: T2 D- ^BYTE        data = 0;
7 a9 }5 [# S7 V" V- X0 P6 L5 D( E- A' N# M% ^+ f: Y$ B6 ~& ^6 s; S
        if( exsound_select & 0x10 ) {4 b5 l, R1 K" n# |% k0 a
                if( addr == 0x4800 ) {
+ i9 y* q) A% W8 I. R                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );* K: f+ V: H9 G& A; t' V$ P! S
                }
- ^' s: f4 f- E  f! C5 {0 h. _        }
8 w1 @  f( i0 Y6 D        if( exsound_select & 0x04 ) {3 _* }' E0 F0 e0 x
                if( addr >= 0x4040 && addr < 0x4100 ) {' R$ I0 P$ s# i
                        data = fds.SyncRead( addr );
9 C8 P+ M! N7 O% p$ v3 K8 c. i                }
6 h" u$ L+ u$ p1 \        }6 J* E! J/ _6 ^
        if( exsound_select & 0x08 ) {
- E( H( u' Q7 R. H1 d( P& u# a                if( addr >= 0x5000 && addr <= 0x5015 ) {
, L$ w0 F) O. H                        data = mmc5.SyncRead( addr );2 ~9 z9 b, a3 K8 F; q* _+ ^4 b
                }
( {$ p+ a  p! K        }
0 v! `0 a! {: a( I: q* ^& t& ~  F) u0 Q1 q; M% q
        return        data;' d! L8 R" a' W  u
}
! w4 w, y8 ?% b& }- x! n2 o" P
6 G- y! |7 B' U. p5 fvoid        APU::ExWrite( WORD addr, BYTE data )! h* [, T. P- x8 O/ U1 Q# X
{9 i7 f8 @: k- ^4 s0 ~1 t+ S& Q
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );( M  O. l+ }7 `- O+ Y
; U9 ]  u- N6 B
        if( exsound_select & 0x04 ) {# ]. W7 W: W/ t' |' N- ?
                if( addr >= 0x4040 && addr < 0x4100 ) {/ Z$ X2 ^& ^: u% x2 k& s
                        fds.SyncWrite( addr, data );6 a( F7 K" g! V
                }
. t. x# Y: W4 l  P        }
& X8 ]. r% ^  O) D2 h
8 p  e! @, O% O* T/ z) H( U        if( exsound_select & 0x08 ) {9 ~) T6 P0 H$ H
                if( addr >= 0x5000 && addr <= 0x5015 ) {
' K6 n/ P4 b3 Q& v                        mmc5.SyncWrite( addr, data );5 T( S. [2 e0 h+ e) y) W5 ~) n
                }7 P. l5 i' `' f+ o' b
        }
4 `# B7 \9 F# \0 |}5 |0 }* ]4 T! F( h: y# j

$ K/ `  j& F8 Z4 w; b8 Wvoid        APU::Sync()" o, j( D9 C& z; O  W) [
{8 V! }+ D+ u/ j9 `0 u. C2 I
}
0 S% R7 L7 }3 Q# N9 f! E# D3 G5 n! Q* K; ]
void        APU::SyncDPCM( INT cycles )
, ?5 r( \1 \0 R2 J. K. s# l% {) z{0 S5 e& |: Z4 k* i8 h# Q
        internal.Sync( cycles );; Q* ?4 m+ X9 l/ B- Z2 a

# _1 b, N+ @9 q        if( exsound_select & 0x04 ) {3 F. Z+ V* Y2 c5 r5 q3 R3 Z2 n3 S
                fds.Sync( cycles );
( J' p+ A& @# U$ B: N7 U! J        }* F4 m2 Q2 A/ z$ g& {7 r: g
        if( exsound_select & 0x08 ) {, b3 }# z8 U% k0 A( c% ?9 |
                mmc5.Sync( cycles );
' g3 F; s+ Q  s# P5 Q        }
. J; _) p0 C$ X+ e9 v: D}' _/ [. i: r& q& X5 `& F( Q

2 w1 h, h% j* w( V& `0 }3 Vvoid        APU::WriteProcess( WORD addr, BYTE data )
4 Z" K% M" I* H) j. h- [, u* s{. L3 b5 D. R! i6 c, p# x
        // $4018偼VirtuaNES屌桳億乕僩
+ K% n, l2 Z5 `# s! T$ k! p  Z        if( addr >= 0x4000 && addr <= 0x401F ) {
" p, n# t! D/ F                internal.Write( addr, data );
( G" U- i3 G) K" ^+ k4 e        }
1 u, S( r5 [3 k2 C! G}: Y. Q1 |0 r, D* L& j4 s) C
& _! h% l! X4 Z- C
void        APU::WriteExProcess( WORD addr, BYTE data )
" D! d5 F% ]# T8 }{
/ n! i( `* K! u6 b  p0 F7 Q        if( exsound_select & 0x01 ) {
# q7 m! z1 H  \' D$ Z. Z                vrc6.Write( addr, data );
3 f& L$ q5 \  e- d3 e% [$ F1 w9 K  \        }: w5 S& ?( j' b+ D. I1 S
        if( exsound_select & 0x02 ) {7 Y! g; e/ {; y+ ]: p
                vrc7.Write( addr, data );
+ [1 w" C7 \9 f5 S; F( l        }
( L1 `" n1 D9 R5 C5 ?        if( exsound_select & 0x04 ) {% [8 |3 H0 @5 W6 ]3 y2 M: P: u
                fds.Write( addr, data );& w, A; o0 q+ @: ?
        }
, ^0 N$ T6 b6 f7 i        if( exsound_select & 0x08 ) {7 H* {9 ~+ I  c6 S) H7 x  J
                mmc5.Write( addr, data );
1 V6 P) q" h0 T$ R/ j% O        }
1 h/ P7 C" e& }3 h1 V: d' D        if( exsound_select & 0x10 ) {3 c( N: N8 N4 `3 W! u
                if( addr == 0x0000 ) {
, ^. g" `4 k& w' A: E                        BYTE        dummy = n106.Read( addr );, D# r$ H1 M- T' _* X( \
                } else {$ E& R2 n& ~0 l8 A+ _# m2 J
                        n106.Write( addr, data );
- w# b; Q* l  ]0 H, m6 r                }
0 H# p. t1 G, n. a. H        }
; i, m7 q9 u( Z. e        if( exsound_select & 0x20 ) {
" Z. B- D* q! {3 f7 |                fme7.Write( addr, data );% U0 u% `  @5 J$ w7 _2 T8 P# W+ g
        }
# t/ H1 C5 w2 t2 ^3 f& g0 F}
/ E- l8 d  Y5 j2 o. g# h# [% u8 T- y: g5 |: r/ V
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
" z# v, H: H$ R( N0 o% c/ l{/ S. p$ A6 F3 k5 t' b
INT        nBits = Config.sound.nBits;0 L# d1 u1 E/ ^* X
DWORD        dwLength = dwSize / (nBits/8);# i  K% P, L( m" g5 W$ M2 B+ R
INT        output;! o7 _0 n( I& r  f" k
QUEUEDATA q;) c: v' ]% @$ ^2 e9 L- t: i# }
DWORD        writetime;
$ W) H# t4 o/ Y. X$ w2 J4 r$ V$ E( j6 \( Q1 X9 Q
LPSHORT        pSoundBuf = m_SoundBuffer;9 \2 z$ N* b  M, u6 D6 l4 n
INT        nCcount = 0;0 P! ?( X- }$ I' ~" Q

7 f8 D+ D8 n2 B. R* gINT        nFilterType = Config.sound.nFilterType;
2 @/ H; i) {* i9 B7 ?& z+ k6 c3 A4 H' _
        if( !Config.sound.bEnable ) {6 @& J+ C1 L" y. w
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
& ]- V2 R9 y! {  r" O                return;; L4 _2 u. S0 N6 O& q! F+ O; ~0 b3 l
        }. L$ V! u  |3 |7 r: T
8 w' C/ A) w: I2 C1 D- L) w/ q
        // Volume setup% A; `) R* D, n+ M3 q% e0 T0 }! O
        //  0:Master; `1 ~0 @6 B1 t4 f  O" ]
        //  1:Rectangle 1
2 K  n3 w! D7 O! w        //  2:Rectangle 29 l  O% ]2 `0 i2 ?& q' p8 ^
        //  3:Triangle
  E) M0 a4 `. P1 S9 p( U( u        //  4:Noise2 w2 M) u$ q1 [9 f8 Y/ e& k
        //  5:DPCM" }: c+ V5 }, ?, ^8 x  B7 W$ j; J
        //  6:VRC61 ?% G# z& j  s
        //  7:VRC7
- o' ?. O' b4 G        //  8:FDS
. C4 N1 Q; b. h, ]7 Q: ~3 |        //  9:MMC5
0 w$ }7 Z5 W. p3 s& R+ e1 J$ |        // 10:N106
: D' I! T" F+ K        // 11:FME7
- K1 z0 S3 @! K        INT        vol[24];
- V6 ~( k. t* D4 B        BOOL*        bMute = m_bMute;
0 ?, ^  r: @9 }4 w: [, @        SHORT*        nVolume = Config.sound.nVolume;. w, H; N! [: x+ n: i

! R; h* H$ r3 r        INT        nMasterVolume = bMute[0]?nVolume[0]:0;7 R; D8 `8 a6 [, f' z) @) m

( {$ c1 K( u$ _- X( I+ B8 \$ K        // Internal7 l0 r$ C1 c2 E# `6 o' O1 S0 h- v
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;3 U- C8 `, b; @. J
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;* |" H8 ?* A$ G
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
* v  f% B6 d. F- f        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;! {. S& b) |  u
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
6 Z" L( n& K0 @% ]% O+ B
0 k4 p, @9 ~6 y) X) x        // VRC68 a) d5 z* ]+ ]$ {9 y1 X" Q
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
1 \) O) U% b( ]! f1 u; {  Y        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
( h% }! i! M: a        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;* [( M  {* c1 [( s$ R4 d" l
* B- X) Z( R) X  b9 i& t
        // VRC70 Q0 h7 n" |) |5 h6 f( u
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;- Z# V3 _5 _+ A7 q6 i) D6 f5 [
6 s7 s2 W, o& |$ R* r) x
        // FDS" w5 G% B6 q& P9 z( [* K
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
! e- [0 ^6 I6 i, ~# G/ e  W  i1 V. J% ~
        // MMC5/ D% o7 t; o5 `6 H
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
6 F$ D1 ~8 U+ o$ v6 J5 l' e9 N( u        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;* t( f! k; T1 x/ A% q7 B
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;% i+ u6 Q1 z( F4 u' [

+ e9 z: p: b+ I0 u, i! A5 d        // N106
9 g/ q( ?( ^. h0 [" I1 {        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;7 @0 a+ q( \. Y" H8 r' _, a' b
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
) A) e5 G0 X+ h3 h/ o        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;4 }4 d& x& u- _+ r! G( e- y
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ |, u5 |* C# |6 l
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;0 j' X' K' m% z
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
$ B4 v1 b( w: L        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& c( U1 D8 B, v3 v% R        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;2 F: }# ?1 |, T

+ A  y* `: x& }) a$ l3 M- H" Y8 c+ ?        // FME7
( s" c& l* n8 Z3 B        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
2 h  q  d( o0 L$ L        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
! y7 x) ]7 k9 E, G/ P5 q* c* @! g        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;( t0 J" n9 R) c4 m2 ~

6 `. K$ v# p5 b+ o8 b5 x//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;9 i% D2 ?" j, y2 L
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
- k; |- t5 Q( d, J* y& O1 R4 _( s" y8 ]
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
$ O2 h7 W! W" E) m9 Q        if( elapsed_time > nes->cpu->GetTotalCycles() ) {5 U) l, m1 k6 i2 o* f& N
                QueueFlush();
6 e( v8 E7 _: C: f        }. v1 X5 L0 [( I  r

% w* I5 Q( x4 t, ]0 @( J        while( dwLength-- ) {
0 p9 b1 a2 a) R' `# g3 m                writetime = (DWORD)elapsed_time;( u, B$ x! }% t0 ~

8 S) U6 |, I4 j3 P; g7 s                while( GetQueue( writetime, q ) ) {
; f0 D/ U: [# s$ a# A                        WriteProcess( q.addr, q.data );, l/ U5 T" I! t; D7 q
                }( t: k" i  x* K
4 `1 E+ V$ S& W; K# k4 }+ x
                while( GetExQueue( writetime, q ) ) {4 K  G$ F1 v4 e1 [+ o. v4 k
                        WriteExProcess( q.addr, q.data );  S+ h+ F* m4 c' L; _  [
                }, c; K: v- v" K
% Z; W7 Z+ h" N! @
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
& z* T8 P, O7 K6 }* _) g                output = 0;
9 D% X! [$ c0 O6 h, }5 B1 i; }& ?4 L                output += internal.Process( 0 )*vol[0];
3 E2 n8 ]. v  W4 M8 i                output += internal.Process( 1 )*vol[1];  f: C% g" m: r
                output += internal.Process( 2 )*vol[2];6 W" y1 b; [5 C7 E5 I* \
                output += internal.Process( 3 )*vol[3];
; a4 K; \/ Q% a; g9 }6 ]1 v& T* \                output += internal.Process( 4 )*vol[4];: g& t9 _& O6 O& `' w- B! x* A3 V
, f/ R. q7 @+ w5 l( }$ H# x
                if( exsound_select & 0x01 ) {! o: h& I. A' A. W' S
                        output += vrc6.Process( 0 )*vol[5];
9 D. P, F$ S: V7 W% v                        output += vrc6.Process( 1 )*vol[6];
! V- U3 x- Z7 B) y9 H' u                        output += vrc6.Process( 2 )*vol[7];
7 `. W2 i& p' p5 c, A$ \                }* ~  s6 X6 S- {5 @  G0 b4 ^
                if( exsound_select & 0x02 ) {
0 n: Q5 @- t4 G( y8 q                        output += vrc7.Process( 0 )*vol[8];
" [; n3 d8 c& t- U8 A) d                }5 G' n! Y3 }+ N* U$ W: i4 Y
                if( exsound_select & 0x04 ) {$ {& c5 V" A( w9 J; \
                        output += fds.Process( 0 )*vol[9];7 y+ Y& ]( F. n9 R. y" X: q8 |: B
                }
- h( T; f, ]% A- l                if( exsound_select & 0x08 ) {" O+ s9 A3 m4 U
                        output += mmc5.Process( 0 )*vol[10];* f! e( P+ p0 l2 L+ d. p
                        output += mmc5.Process( 1 )*vol[11];6 ?4 u4 \) U0 `% g/ D9 K
                        output += mmc5.Process( 2 )*vol[12];5 U, Z7 D1 {1 w, H1 F
                }( _/ E" u7 v: S, O
                if( exsound_select & 0x10 ) {
. S0 X. V) m' f" N$ V4 r8 q                        output += n106.Process( 0 )*vol[13];) e7 p3 {! f( ~3 R  Q
                        output += n106.Process( 1 )*vol[14];
) `; b3 p6 F/ _  X1 k                        output += n106.Process( 2 )*vol[15];1 N  p: v( v3 \! w! ]) W# p6 q  q
                        output += n106.Process( 3 )*vol[16];% r/ V* d3 a+ O+ B
                        output += n106.Process( 4 )*vol[17];' [  Q+ z+ n5 g/ Y4 N1 t
                        output += n106.Process( 5 )*vol[18];
: r8 G$ J/ S# C1 V/ e# p! e                        output += n106.Process( 6 )*vol[19];3 I; I/ |: y9 |! O2 j
                        output += n106.Process( 7 )*vol[20];
& C0 l' j8 o9 p# c( C- D; g                }) ]" J; l7 ?) Y
                if( exsound_select & 0x20 ) {0 w. Y  f" X- R% P
                        fme7.Process( 3 );        // Envelope & Noise, B$ T: `' C1 ^. R0 p6 Y
                        output += fme7.Process( 0 )*vol[21];
% H$ N6 F. q, g/ p; m8 G( F                        output += fme7.Process( 1 )*vol[22];" _1 _9 w7 Z+ i7 N4 n
                        output += fme7.Process( 2 )*vol[23];  j2 h! Z- K. o: v7 a# U# J
                }2 J$ G9 B: ~1 {* C5 D4 }

4 x# F% z4 j6 y" s3 D9 {                output >>= 8;/ b. A1 R. ?: r0 s5 ^) I9 x
4 ^, _) @7 C( M5 t. T& i2 @: _
                if( nFilterType == 1 ) {
" R6 ?4 }( D4 R                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)0 O2 Y7 m+ M; C
                        output = (lowpass_filter[0]+output)/2;6 N1 @, \. W( S% X3 w9 L
                        lowpass_filter[0] = output;
4 @: |* o$ C2 P; o                } else if( nFilterType == 2 ) {7 O" l0 {2 T! {% x+ r& q
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)8 E$ I; K- w" a0 M
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
! S4 w6 ]# u' @- C4 ~+ t                        lowpass_filter[1] = lowpass_filter[0];) w4 a5 V1 E0 M9 _5 m: S& ^& L
                        lowpass_filter[0] = output;
: I6 _: P5 w2 z3 @9 R: M- `+ B                } else if( nFilterType == 3 ) {
, E4 X4 a1 _, z6 p+ U                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
6 Y6 }, y! V- ?3 e% J                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;2 L1 P. {/ H2 n
                        lowpass_filter[2] = lowpass_filter[1];8 \" c2 x0 u! \2 D/ ~0 {+ \
                        lowpass_filter[1] = lowpass_filter[0];/ {/ z9 l( y, T! Q# f' O! }
                        lowpass_filter[0] = output;; M2 @1 y# y. Z3 i& l
                } else if( nFilterType == 4 ) {8 ?8 H7 o$ k' M; D9 L* X
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3). b0 a% V4 O2 x; }
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;! H% n' D2 H" }7 B6 `4 B
                        lowpass_filter[1] = lowpass_filter[0];
7 I( u  }4 i- B! z5 V- r                        lowpass_filter[0] = output;- A& H& f$ I, Z- N; c6 d
                }
/ a: t9 ~* D1 u2 s. S
0 D, y4 g+ ^; q#if        0
) z0 k8 c. L& K9 p6 C8 z* Q. L                // DC惉暘偺僇僢僩- w7 K0 \" p+ _7 p
                {# m' ]- n( v2 M: ]/ B) p$ \
                static double ave = 0.0, max=0.0, min=0.0;! M$ q8 W# I, c- d
                double delta;# a. r: Q5 ~/ u
                delta = (max-min)/32768.0;5 b' E: U$ a! [! N
                max -= delta;
2 |$ M- n/ \6 |. ~, x" L                min += delta;$ q4 ^7 Y' I% W$ [6 H/ b" z2 H: s/ |/ j
                if( output > max ) max = output;+ C: S4 F3 y" i/ E1 T
                if( output < min ) min = output;
' t. M; d( o6 N; y0 x                ave -= ave/1024.0;
9 c. ]+ O+ X8 _: F1 _8 E& l/ O                ave += (max+min)/2048.0;
! Z' |# ~- J5 O% W6 M+ Z  F                output -= (INT)ave;8 X! s9 y4 L: ?' K% W% y4 T
                }: l- o+ W. b; e2 ]1 S; g
#endif
' k8 U; m) e  C1 M% a#if        1  |6 G5 w0 b1 y! H: K
                // DC惉暘偺僇僢僩(HPF TEST)
) L+ s9 n1 n& `$ C                {
2 `1 d3 m5 `) G4 X//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
& `# _6 Y5 l' o3 W3 e                static        double        cutofftemp = (2.0*3.141592653579*40.0);
7 h* P  O- f, j9 p# b5 i                double        cutoff = cutofftemp/(double)Config.sound.nRate;
! U  V! u5 u4 {2 h4 d                static        double        tmp = 0.0;% S8 }* Q- P0 J3 r2 L2 u
                double        in, out;
  j5 S: J" D7 J8 v0 C
8 S  d4 P$ h! l/ v( J( j1 i6 `: v                in = (double)output;- ]! i4 U8 v* d' v2 B* Q" O
                out = (in - tmp);, P( \6 O* I/ j. h& k: r6 o
                tmp = tmp + cutoff * out;  g9 Y. K5 K3 l1 [

+ Z$ @! w- {- P/ x6 v: r                output = (INT)out;
  E$ i% l( |$ R( J" v                }
4 {/ q! [+ [5 @: n& p#endif
  Y! ~& F3 @  _" Z8 i: I' K. Z#if        0
* B; ^! |% r" T( ^4 _; O                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
1 c: d$ K$ w, g* O1 P                {, `/ S& ^7 n* _+ O' d
                INT        diff = abs(output-last_data);
$ I+ N4 _# s* s: v  R- u/ M                if( diff > 0x4000 ) {1 k* h$ ^' }; D8 |+ ?4 r6 y
                        output /= 4;
7 d! H* `6 j  a( X, y9 o                } else ; t) x. H/ L6 `" ~# H3 }
                if( diff > 0x3000 ) {
" F; w1 p# [0 u                        output /= 3;- W2 Z# B$ |3 @& M/ W5 R+ j8 x
                } else5 B. r) _, N  {, S% H5 I* y" d/ t
                if( diff > 0x2000 ) {
+ J% n. I9 G1 `; ]) s4 m; R8 `                        output /= 2;2 t/ [9 F& @2 d  w) @) I7 r
                }' w/ ~* L" Q0 p, u. N3 i
                last_data = output;% C6 f) I  W* d. B& |8 @+ v
                }
( d$ Z# u0 e* a#endif
! H  w4 M! @: s$ N  s                // Limit
6 j( ?0 `: H/ {                if( output > 0x7FFF ) {2 _1 Z) P  t. G% H0 @& q
                        output = 0x7FFF;+ p& I$ ^. }. M7 e
                } else if( output < -0x8000 ) {
# ~2 S# m4 E& w3 d                        output = -0x8000;
( I3 P% J0 p0 ]8 k# H' ]( p3 n                }
6 r# m3 @( e* x% P  Z5 V  u" _3 v& R( O. v+ ^0 |- B7 K; Q
                if( nBits != 8 ) {
6 u) E8 l9 i- a' }! h                        *(SHORT*)lpBuffer = (SHORT)output;$ E1 }4 t3 \7 P9 \6 B2 N
                        lpBuffer += sizeof(SHORT);
- Q, b& o8 j# D; `- y                } else {
) C$ Y  N  c2 O; N' c                        *lpBuffer++ = (output>>8)^0x80;
/ {/ {, z5 n7 a8 J+ s0 ^- H3 `                }
; d0 t) X& u  q0 s7 K6 Q3 k0 w2 h, p  a( Z- H
                if( nCcount < 0x0100 )) R* K, ^8 Y; X9 [' ?3 D
                        pSoundBuf[nCcount++] = (SHORT)output;4 C- b- R; t0 t4 C
* ~/ g  d4 r& w& p2 O' h* c
//                elapsedtime += cycle_rate;
' p9 A5 Z9 a% D! f) [                elapsed_time += cycle_rate;# g- @; ?+ h5 m3 L! y
        }
9 I. a; y+ |7 R9 E; D& q  n, U( d+ m: {+ T+ `- m! r: b
#if        1
. b4 S, e: q1 E' ^$ D. C        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
0 V% l8 M4 ~4 E/ S8 i' d) z                elapsed_time = nes->cpu->GetTotalCycles();
9 y4 ^2 m- U# ?3 `        }, U2 Y" w; O) H2 E( {
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
# F2 S3 e" M  E4 y* ~# L                elapsed_time = nes->cpu->GetTotalCycles();
; Z$ \( D! B8 N        }, e; x9 b; `: G! s( @1 k! C
#else
0 W  ?+ k3 R9 A- L3 F7 l        elapsed_time = nes->cpu->GetTotalCycles();
" |7 U5 k3 D8 h# F) F#endif
% a/ M! H# @8 z}
$ E8 M' }; b$ h' X. \! P4 Y; ~# a
2 A4 l( @* G* p/ p7 \// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
& Z& ^/ _8 I6 T5 R4 h* hINT        APU::GetChannelFrequency( INT no )
# B8 q9 A3 e2 _{3 G& q$ {) j7 d* r
        if( !m_bMute[0] )8 B. g7 m/ [& Q" ?* R+ ~
                return        0;
0 u9 _( m9 n0 x+ c5 T
3 v7 K& c) X% {        // Internal$ e" U+ I4 b" Z8 e9 F
        if( no < 5 ) {
( v; X) a* |9 x9 B                return        m_bMute[no+1]?internal.GetFreq( no ):0;* A8 Z$ ]. j  @: `$ F* b5 p# c  {& A
        }8 D3 E8 ]' d6 \, t! J' y3 l
        // VRC6
7 J5 g  U. k% R& Q9 G& P        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {" X( f2 R9 M# W5 v1 x1 Z
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;' G. V6 L% i$ S' e2 s  n
        }
! n0 I. Q, K! N+ K) S' ?' {+ ?" p        // FDS) C3 Y  ^! R: ~$ t: ?
        if( (exsound_select & 0x04) && no == 0x300 ) {
7 j& K' o0 T# t9 @& E& w" z                return        m_bMute[6]?fds.GetFreq( 0 ):0;' S9 C9 Z+ A: W( f$ A+ `! N. h
        }2 Y. Q" D; y5 O! [5 ~: P( z
        // MMC53 b8 `% `6 P% w2 d2 i+ \3 E
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {7 K3 s" D/ M: ]. X# Q
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
) @0 N+ Y+ R* F2 [        }* @+ g7 u2 _# X
        // N106; @: ~. q1 y/ V7 a
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
6 Q8 _0 o8 @9 _/ `6 l! i& l; Y                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;* \1 \+ {7 Z, I
        }3 Y  {$ N7 S5 B7 s$ O" F/ J) D
        // FME77 f5 s, m* @+ T) \& Z4 W
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
- u. ^0 }; Z  J+ X3 O: I" p6 I4 m                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;3 M+ r% o( a% P/ }4 T6 t
        }# s+ Y; f' ]- k/ H
        // VRC7
7 t- |7 M6 ~. \: U6 P        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {; n( X: G9 p# k/ S. h" n- p* J1 T# b
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
  l+ E  Y; o2 A/ _9 X0 H' \        }; l, @4 Y. |& ^( u6 m5 ~. V
        return        0;1 L2 C5 l9 _8 R$ P. n
}( M# Y+ h. P; o3 _
/ Q1 V" a+ q4 v& o8 v
// State Save/Load" s7 s6 \7 t: J# @( l
void        APU::SaveState( LPBYTE p )
! S  R  T% G4 G6 E3 W( t  p1 E1 h{1 C; c/ \' U  g! n
#ifdef        _DEBUG% i1 F% q: u; ?1 y# Y5 _
LPBYTE        pold = p;
' O; H" x; k; K- C2 K! V( z#endif
% m  {* w  x% Q5 K. w1 u5 Y3 Z) U2 h* @$ ^! m& q* o' @% M
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞7 o  R: g- K* Z/ C) U- C
        QueueFlush();' s0 J  f# p9 f* C

1 c7 \* K9 H9 n. `6 d5 e        internal.SaveState( p );
# s  `1 j1 |* u% C4 \2 p        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
/ i% V- J8 k! r4 k
. L5 m$ O+ N- k+ ?4 X% S        // VRC6+ F2 X7 {, v) y. b, k$ s# e
        if( exsound_select & 0x01 ) {
, }- w; ?) H, ]* V                vrc6.SaveState( p );
) V/ }' K6 W2 X  D1 A  @                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding4 m! f: Z0 u3 x
        }( a0 m  Q* |& A1 @7 r
        // VRC7 (not support)
3 V8 [, e3 f: `5 F) b6 a; G. H        if( exsound_select & 0x02 ) {
4 j+ I" B( f1 v                vrc7.SaveState( p );
8 `, D5 O( l' E. L) \                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding. n  ^* W, h1 |. m
        }
6 f4 C4 c# j8 v4 b. t        // FDS
3 y, J; H2 Q; v# D1 g* J& S        if( exsound_select & 0x04 ) {
' {. v8 p, \& @- o# C                fds.SaveState( p );* ~; B$ f& M7 i" o6 H" Z# @
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
' l( |& s1 x$ s1 ]2 z1 ~3 W: A        }
# w5 A- j  z" _2 `0 \! h$ t0 y- S        // MMC50 J' Z1 E% a1 y
        if( exsound_select & 0x08 ) {* e: t5 g4 B9 }2 S7 R% D& Z
                mmc5.SaveState( p );7 |1 G( _) h# {
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding4 {$ [6 P7 {2 m$ f2 @0 t" ^
        }
! i  F8 J! c0 N, X5 M! b' B8 t        // N106
0 d& v8 q9 y4 K2 b! ^9 R& I        if( exsound_select & 0x10 ) {
* |% B# T$ }  o8 P" e3 f  ]( T$ R                n106.SaveState( p );1 q% x0 E1 P6 y- b- U5 J
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
+ b! i5 q$ ]& A: d        }
6 ?  U1 H: a& c& T        // FME7+ o/ r9 v2 u$ s
        if( exsound_select & 0x20 ) {# z" F) k) |; ^# t: r
                fme7.SaveState( p );
9 f0 l! ]* S& |8 i; W                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding2 P8 h$ ~! v7 `' O5 n2 G6 C
        }0 @& c! Q  m8 n, ]7 S
9 [3 _0 y! g1 ~7 M! {2 k
#ifdef        _DEBUG( P! K6 V) L9 u
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );9 V$ R) ~' s+ G* a- i/ w! @( Q6 e
#endif
7 z! k9 w3 v0 h}
) h" D# M! R% t- t# C* I2 ]# I6 V) f3 ]# J5 ?1 ]
void        APU::LoadState( LPBYTE p )
) ^( K& y9 e: `2 e9 i" D{
1 ]/ I: N6 P- g5 f! w$ m        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
" X, }1 p7 z' j4 \$ E3 X        QueueClear();$ ~  x6 c: Q; i- E$ C
2 g, O5 Y+ m) G/ I% g
        internal.LoadState( p );& ^4 ]: h1 P& }
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding) g( O. J9 x. ~" R  P: j) B) F# I& u
; k# M6 }5 Z. m/ _6 Y
        // VRC6
! y6 ], [% b0 J- `( t        if( exsound_select & 0x01 ) {* A1 G" d( n; m- [0 E2 p: x3 t
                vrc6.LoadState( p );
- g, G' q4 v' q* u! Q+ A                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding! o& Q; J- g, n+ _5 w! P
        }* c( S+ i' J* i3 O
        // VRC7 (not support)
' l& h5 I; i! \        if( exsound_select & 0x02 ) {
6 \5 d% `% k, h3 \                vrc7.LoadState( p );
4 g$ k" w- P8 o- N0 \  b; _                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
7 {# @. `  x& Y" {. h        }
" J' z" ]% K6 E1 c8 o        // FDS
( o. I1 v- v5 ~6 Z7 T+ p        if( exsound_select & 0x04 ) {; ]# v5 S6 S) A$ O
                fds.LoadState( p );5 N. r0 O0 b9 I2 p8 h) O% F" s
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding( G/ E- ]0 H! P& f" b
        }
, Y0 [; E, S. c$ O$ @  z        // MMC5( Q" N" d' X" b# _
        if( exsound_select & 0x08 ) {1 I! N9 G( w& Z( |
                mmc5.LoadState( p );1 l; l& N( W; s% j; b1 b3 z
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding- ^- B- y/ a1 M6 Z* v7 C! p) C  o
        }  h& Z7 }+ D6 [7 f" N1 B4 p. H1 l
        // N1060 i7 r$ {9 i- u+ j9 F
        if( exsound_select & 0x10 ) {
, e5 i% Q8 @8 v1 A0 ?4 o5 p                n106.LoadState( p );
$ H& L4 p7 b! M; ?% @                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding* }9 E* y. P% Y' b
        }
; G/ b9 G+ `1 }6 Y& G4 ?        // FME7
# }% G* q3 t) g2 m: H$ g* J; E        if( exsound_select & 0x20 ) {
# P8 i, o' C" x+ {) e- j! H; G                fme7.LoadState( p );3 l$ o, V$ s4 w4 {- X* ~
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
9 m1 {* I) l) l8 ~/ e0 p% u        }
' {) `0 a  w0 J4 m# u  O, J5 Y}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 ! A7 U/ ?9 W2 s) M  R  p
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。5 f& t. k: N  u, `9 X; t
感激不尽~~
) Y9 A5 T1 T8 s7 r5 G$ p
恩 我對模擬器不是很有研究,
! t6 u1 U4 [2 a7 ~雖然要了解源碼內容,可能不是很困難,
& j: T% x" z7 m9 r9 z* }9 q不過還是要花時間,個人目前蠻忙碌的。
2 K9 Q$ E" @& [; d& K; R8 P. y7 R4 L. _
給你一個朋友的MSN,你可以跟他討論看看,7 T' h5 s- g1 h( a9 C( a* r( n
他本身是程式設計師,也對FC模擬器很有興趣。3 \: t1 a* m0 N' `! G5 }( L3 n
) z9 R2 T* ?! z% E' ]3 |% R  Z
MSN我就PM到你的信箱了。
$ R, K. v' S- K( v
1 G' n: z3 j3 |+ |( i; ]" h  _希望你能有所得。

该用户从未签到

 楼主| 发表于 2009-11-9 13:23:59 | 显示全部楼层
呵…… 谢过团长大人~~

签到天数: 80 天

[LV.6]常住居民II

发表于 2009-11-9 16:02:29 | 显示全部楼层
团长的朋友都是神,那团长就是神的boss。

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表 5 `. R; M; |) V' i. N9 P! i2 Q2 O
呵…… 谢过团长大人~~

* j- C0 y; l" a' c$ D% m3 V# l6 E  q. K8 |9 w
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
& I" Q2 D; w; Y团长的朋友都是神,那团长就是神的boss。

# q- T6 _: K8 }- j哈 不敢當,我只是個平凡人,$ Z* T" C2 T! w/ L5 S
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
: g) [- k; v9 B4 r/ vZYH
1 A  l. g% ~6 T" S/ F0 V/ s2 A) UQQ:414734306* }# W2 V1 e) k+ X2 \
Mail:zyh-01@126.com
4 J0 l2 C% m- S, Y) J1 \$ T4 e6 q( d& Y
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 9 ?* w7 [8 m* ?1 ?3 j2 t: c" A
再次对团长大人和悠悠哥的无私帮助表示感谢~~

6 d+ ]/ q- K5 l不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-2-1 18:58 , Processed in 1.085938 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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