EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
8 S! ]2 A4 `* y: k& X0 l/ Q9 z楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~/ |+ w: T) j% @
这里有相应的模拟器源码,就当送给大侠了~~
/ k/ Z6 H' r! w% K- ^9 Mhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
4 j+ J! g/ P. {( Y) b" m' W能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。4 }. R: V- N% H. E1 C6 U* l0 o5 |7 ]' n
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~$ }& y6 O8 a* ~% X
这里有相应的模拟器源码,就当送给大侠 ...
% B) v. ]/ s0 L  v! B
聲音部分(Audoi Process Unit = APU):+ V$ |6 h2 I5 @* h
.\NES\APU.cpp/ {* M  [5 j8 z2 K& U: l3 w# P
.\NES\APU.h/ g* I4 }, h9 W+ R( M# e8 l
$ v+ G0 Z' R: T( P9 D2 p
  u; w8 \2 H% }& j8 g
影像處理部份(Picture Processing Unit = PPU):& J. ]! p" x1 j0 T+ u
.\NES\PPU.cpp- C  y4 D  i8 w3 a! f
.\NES\PPU.h# N2 h) j8 g8 `! |
3 [  W& q% O3 ]( ^9 p; T
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:# ~! G0 `! s. p5 e9 x. H
(由于很多专用术语和算法机理都不明白,所以看不大懂……): F+ f3 J0 d, @+ p: e9 D
//////////////////////////////////////////////////////////////////////////, V6 b9 j8 A- @0 V' v6 p+ J
//                                                                      //6 }9 h  @/ ]$ ~- ~4 O
//      NES APU core                                                    //
' M. v. [  j" {) G//                                                           Norix      //1 a$ Y- d9 i/ O9 g1 m
//                                               written     2002/06/27 //8 _  k4 e* o" t( N, }' W4 p
//                                               last modify ----/--/-- //( Y% Y' ?8 I( z- @- ?
//////////////////////////////////////////////////////////////////////////
2 k" |8 C2 U8 h  X! A#include "DebugOut.h"
. r+ a. L4 F6 R#include "App.h"8 ^% i2 r5 d" `
#include "Config.h"
0 o0 K/ b$ j: `: Y! U1 [4 ~- P! h  k/ W% l  q% s! t4 ]
#include "nes.h"
& P7 ^9 x1 a. {, a& Q8 b#include "mmu.h"
6 j$ I- s" m1 G0 v  @#include "cpu.h"
. D' [: A& Q/ ^4 f6 O" e5 [* Y#include "ppu.h"- J' w+ r" a* }
#include "rom.h"
% p7 |9 \( v5 w! {. _7 s  g2 d#include "apu.h"2 M7 J3 E9 X1 B. S& V
5 ?! @# S  ?; K: R; n1 a4 z
// Volume adjust; ]$ ]: f2 a- k+ R, M5 l) _; |
// Internal sounds
, f, F  [0 [. g. C: d% V/ [#define        RECTANGLE_VOL        (0x0F0)
* W# L! m% L# b4 A4 A#define        TRIANGLE_VOL        (0x130)
( N* K9 |7 r! I2 A7 w4 T$ @#define        NOISE_VOL        (0x0C0)7 ~. X; o- G- `
#define        DPCM_VOL        (0x0F0)
* }0 [' O8 B3 B% w- ?& t( _// Extra sounds( ^5 F; n) ]0 R8 I- O
#define        VRC6_VOL        (0x0F0)( ]# g3 [# B# H# t
#define        VRC7_VOL        (0x130)/ [/ F" f, ?. ?& @
#define        FDS_VOL                (0x0F0)2 W) V. u$ [+ b9 f9 `+ V3 g
#define        MMC5_VOL        (0x0F0)
$ _, d& t; Z% ]0 t#define        N106_VOL        (0x088)
; b! I' \$ v8 a8 y) l. p4 F% g#define        FME7_VOL        (0x130)1 v3 T, }( ?. J2 V

$ D& N" p7 T, k1 `1 _APU::APU( NES* parent )6 g) z7 v# V0 ?" D9 q
{
+ t! u. P4 ]8 K        exsound_select = 0;( f9 f# t2 a% \" u6 M2 O0 V8 g/ H$ x

& U2 E5 k" ~# b' G- @        nes = parent;
9 g7 J: T; N6 v+ {) n, K$ K        internal.SetParent( parent );% K/ o* x! E7 k- H) W1 {! |
4 g! b+ d' Y" n- C$ z
        last_data = last_diff = 0;8 j' U- b. M. S" n: G5 H$ o. z

2 x; Q! t' `& h5 [3 U  \        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
* {# l; K4 j  E) `8 X  C. k0 y) }# n
; m, i5 F' ~; r) T+ r        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
1 y& N' f- N# E& x, N        ZEROMEMORY( &queue, sizeof(queue) );
+ E6 ^5 E5 A3 A8 ]        ZEROMEMORY( &exqueue, sizeof(exqueue) );1 Y3 \' A% q& j( q7 h+ Y9 s
* z: M, e* r4 R. A
        for( INT i = 0; i < 16; i++ ) {
3 B! ~# R' B+ n7 B# S                m_bMute = TRUE;
6 @2 ^6 v! B5 f6 T+ B; f        }
. _" e0 n8 a3 n: K- J3 i}3 _% F2 w$ ^( l" Q, |1 K; R

2 t# ?9 i- H$ @4 LAPU::~APU()
6 f& q7 e7 y) O, [6 ^  K3 O{+ |7 ?, ?, P3 g9 k6 j0 ]
}
% Q) k$ a; P1 x% I6 [+ G' J% l' e  P& J( E. h# B% [/ t
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )- S- b7 b, `* ^  a2 y
{3 H9 A, |  P4 l& `2 ~
        queue.data[queue.wrptr].time = writetime;
+ v' @3 B. w# T& k4 t6 D        queue.data[queue.wrptr].addr = addr;
9 L% x( T: ]  V+ N+ g. W* ]$ o        queue.data[queue.wrptr].data = data;
/ U/ z& y/ ]4 r' B6 b5 u* D        queue.wrptr++;
) P9 H+ R1 x5 X9 g, n( I. B! o        queue.wrptr&=QUEUE_LENGTH-1;
8 D9 i& Z6 C3 I& r- b        if( queue.wrptr == queue.rdptr ) {
6 f/ b7 F6 F! \) e                DEBUGOUT( "queue overflow.\n" );
) S7 u/ s0 B) x: |# u" w        }' o$ [, m% f  @  {1 [
}
' d4 S5 L; ~$ W, z. L/ M  |+ A+ |) _. U  `
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
( {* R' W! U2 N0 \{
" G, l: w, w1 j3 C+ @1 m        if( queue.wrptr == queue.rdptr ) {. F7 D' [1 K  u* C4 Y6 G
                return        FALSE;' |8 x- R2 [# q
        }; }, ?6 X( ]/ F6 k0 q- h
        if( queue.data[queue.rdptr].time <= writetime ) {. G1 l1 {/ F9 s3 _
                ret = queue.data[queue.rdptr];
* f+ z( l, c& G! t) g( x4 _                queue.rdptr++;
$ L) w* Z/ R( m% K& ?1 g                queue.rdptr&=QUEUE_LENGTH-1;
& w& _3 @5 d7 V3 U5 W' ^                return        TRUE;
2 z$ l- o  b0 w) A2 Q3 D        }; L$ M7 n! Z* G( i% p( }) E4 Y0 l- c
        return        FALSE;' ^( o- K9 S; `- g, y
}
, P/ B+ r( d4 k5 `  |2 M; L
0 Q5 w# l! S6 Q, X, F+ uvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
8 m3 h7 b5 w; ~. T. h+ j{. `2 f5 m+ L. C+ ]
        exqueue.data[exqueue.wrptr].time = writetime;
7 i+ g! c0 R4 M! S( v7 ?        exqueue.data[exqueue.wrptr].addr = addr;
6 ], o  @( Y4 c$ ?4 ?        exqueue.data[exqueue.wrptr].data = data;* I, c. @% X! ?3 b; i
        exqueue.wrptr++;; i) P# j" ?; J% M
        exqueue.wrptr&=QUEUE_LENGTH-1;
( j: s* j1 V1 f4 q) u        if( exqueue.wrptr == exqueue.rdptr ) {
! q, l% d; K: F! |: L& X                DEBUGOUT( "exqueue overflow.\n" );8 ~( D2 }5 h- h# N
        }0 T* N& K- B6 k
}; H/ x% O) v, [; y) R5 ^: t
: |+ N. s5 |" C3 C& L( f9 V
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
/ _4 R: R, @# I( y7 Q# a{
, b  W( ?" y/ E        if( exqueue.wrptr == exqueue.rdptr ) {/ B( M7 m" B7 l
                return        FALSE;) {3 S  U9 L/ w' M8 u. d
        }
% L9 _& |( S  t3 k+ k. Z6 l# S7 h: A        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
; \- C- @% n. m: r0 Z! U                ret = exqueue.data[exqueue.rdptr];
" B; d  _1 _8 U, @! q( R                exqueue.rdptr++;
9 L3 \$ D- d/ w! l$ \' W                exqueue.rdptr&=QUEUE_LENGTH-1;
: T2 b& o$ _& A5 K! b8 i7 c                return        TRUE;! U' j8 n% m2 x) J
        }
3 \" n( q' y: J6 d        return        FALSE;4 v$ g+ s4 d/ b
}
  `' L" d- {4 u* g" y7 b- y% H: ~$ L+ t' w
void        APU::QueueClear()
& p- k# l( a+ ~4 ~8 y; s; w5 w{) D% A6 O* `0 P3 ?. k9 S
        ZEROMEMORY( &queue, sizeof(queue) );
& `( N& t2 t& j4 s9 W        ZEROMEMORY( &exqueue, sizeof(exqueue) );6 f0 U. x. d, E- l1 R
}- v; N  [4 k; \! N$ s
/ R" p" }, T2 j$ }3 b0 n
void        APU::QueueFlush()3 d5 Z/ a1 x0 \
{
4 [; ~: X: F, n        while( queue.wrptr != queue.rdptr ) {7 p- E" E& S/ U) Z( r4 g
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );2 s; `. K3 A3 w2 ]
                queue.rdptr++;. f! B+ V$ p/ ^/ _4 b0 {
                queue.rdptr&=QUEUE_LENGTH-1;
3 f% E: X) [. \        }" X5 Z1 h4 K" C; ]3 z4 l9 {

% L* L( C( W* B- j5 C4 `        while( exqueue.wrptr != exqueue.rdptr ) {
8 [3 I9 l% v' f; c4 M+ x( Y                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );+ X- o. H; W4 L  w1 J4 B5 s
                exqueue.rdptr++;
+ Z( W' ^+ E0 ~. L                exqueue.rdptr&=QUEUE_LENGTH-1;$ ]; |4 `8 ]- s, l- O
        }8 a) n9 Z- v0 o) Z
}
3 E- P  b, Z" K& G8 B$ l, Q* k7 ~- E6 q* h1 {- o6 `, S) S
void        APU::SoundSetup()
, V- N0 E$ v0 U4 p7 j{1 I6 M: r! X  i8 g1 W) F4 X3 I
        FLOAT        fClock = nes->nescfg->CpuClock;
0 K  W" Q% i+ g4 C" R# C        INT        nRate = (INT)Config.sound.nRate;
( z/ C# Y/ E! M1 X0 r        internal.Setup( fClock, nRate );; P) D5 u4 U0 T+ G3 q0 c" t2 C2 x1 `! f
        vrc6.Setup( fClock, nRate );
; o! I# g" c2 x+ I. X; [' Q. q        vrc7.Setup( fClock, nRate );3 U- P/ F/ s+ ^6 P; ?
        mmc5.Setup( fClock, nRate );1 _3 I" f+ c& J& q$ Z1 C+ n: F
        fds.Setup ( fClock, nRate );
/ u, u3 ]# [7 p: U: U& y& e        n106.Setup( fClock, nRate );
0 e& J8 O, x6 r, ?2 B" y/ v0 [        fme7.Setup( fClock, nRate );* @- N. |6 }4 C4 Y6 W
}( K3 L+ R' _( @

* R5 Z1 ~6 z. F9 O4 vvoid        APU::Reset()
! P2 d# y6 n# j6 k2 `; E5 T% b" a{
% q. t& {. @" n+ S6 k4 ^6 I% Y        ZEROMEMORY( &queue, sizeof(queue) );4 t- b# o6 ?) B( H0 F/ ~6 c3 _
        ZEROMEMORY( &exqueue, sizeof(exqueue) );; D" A# Y& |$ B7 n
9 w" O( ~) e* s( X
        elapsed_time = 0;
% n3 b1 P' s' C0 C
! U7 R2 N2 V4 e! |4 l        FLOAT        fClock = nes->nescfg->CpuClock;  L: i/ e: |. d2 \: C. H
        INT        nRate = (INT)Config.sound.nRate;% t# g+ W0 e: F% v( @+ `) Z
        internal.Reset( fClock, nRate );* m$ A$ ]5 E; G
        vrc6.Reset( fClock, nRate );3 T' L8 ?9 |- w% P8 Z" k
        vrc7.Reset( fClock, nRate );7 T5 |4 j7 i( J/ z# q
        mmc5.Reset( fClock, nRate );# @: F9 Y$ G0 |8 |: H5 E5 a' e8 o4 }
        fds.Reset ( fClock, nRate );6 e1 U0 k3 s1 n5 Z! \# H5 f
        n106.Reset( fClock, nRate );
+ d8 C  k& q9 _7 w' U! {( ]  F        fme7.Reset( fClock, nRate );
% F/ `* ]7 u' Q9 {6 N' E7 t2 I; W$ x9 W5 u" \
        SoundSetup();' N( P% f( u8 V7 h$ M
}( R4 G$ S3 c* n1 Q
1 `1 b4 K# {2 v
void        APU::SelectExSound( BYTE data ), M- p" L0 D! a9 l. [% n, |
{! W+ ?7 C9 D6 I
        exsound_select = data;
4 L) B2 H8 K! ~! T; @}
, _/ p  G7 s; S" }+ y9 Y2 z4 p% g7 d! ~) ~
BYTE        APU::Read( WORD addr )
6 @0 _* a9 ~  I4 f; R- f2 Q{4 n* S8 c& k% S4 S! s
        return        internal.SyncRead( addr );
: \# s. h/ L1 G3 \2 L7 @}
" q' K, U' U$ h3 y. M7 H0 ?5 ~* o, D: ^! C
void        APU::Write( WORD addr, BYTE data )
' i  Z7 q1 O, r5 ^: |{
4 j5 |+ S7 d; z1 \- E        // $4018偼VirtuaNES屌桳億乕僩4 T# e& T% T' d
        if( addr >= 0x4000 && addr <= 0x401F ) {
) S0 F8 c8 C2 R% T# B# ^                internal.SyncWrite( addr, data );
% a* X! {" N. V6 m! f0 P7 Y4 J7 t. f, N                SetQueue( nes->cpu->GetTotalCycles(), addr, data );  c6 E. ~! |' b6 T8 N
        }- U& Y7 X1 G; z6 Y  B
}
0 d6 i( N" G, t' H( B% V$ X2 D
# e6 O8 @6 i6 H$ xBYTE        APU::ExRead( WORD addr )
$ F: F7 V1 d1 ]. C4 [. f5 E9 E{5 l" d: e$ E8 e6 [1 S
BYTE        data = 0;
" t' g! F  U8 x3 ^' D- c
% H1 w& t& f* e7 S        if( exsound_select & 0x10 ) {$ y. p& V+ g" B! x! b, q
                if( addr == 0x4800 ) {7 B) B% ]5 H% c9 O! K6 ^7 E* Z
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
6 _! g# C8 A9 @$ ]& b' k0 |                }: F( {' w6 B. F+ Z, B
        }
( l/ c% L- Y$ f2 z' V5 c0 `9 c. L        if( exsound_select & 0x04 ) {
' `$ H* u. O, P9 d4 `# d: m/ `                if( addr >= 0x4040 && addr < 0x4100 ) {
/ Q+ B9 C# Z  j3 l/ b8 ]& e$ K                        data = fds.SyncRead( addr );$ h: u' C. C8 q" v
                }
/ t9 o- {6 @' _. v+ u& X        }  \3 ^1 x7 E7 i6 z1 V' n! `3 d5 ?* u
        if( exsound_select & 0x08 ) {
% t9 o1 L# O, D                if( addr >= 0x5000 && addr <= 0x5015 ) {
; ^+ Y# g7 H+ _$ Q                        data = mmc5.SyncRead( addr );3 U- ~9 M) Q( K
                }
0 |' ~7 e. d4 K" a/ e7 _        }
# n# P& I' C8 N* O7 q& }0 ~/ \. F- J+ o3 ?
        return        data;9 Y, r$ ^0 \6 T; H. Z% ~4 W' i
}  U* r( b' j+ h7 r1 }; P! ~

- s0 L6 n  I6 g" M( K/ S4 C4 Xvoid        APU::ExWrite( WORD addr, BYTE data )
* ]3 e: @# f- q6 a2 V' D{
# N6 V5 w" o; X7 }5 J8 ?        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
5 {# A& S2 K/ M7 p7 N, `2 n* d+ w  r6 `
        if( exsound_select & 0x04 ) {
6 S" [$ a0 r9 Z4 m                if( addr >= 0x4040 && addr < 0x4100 ) {, G" ?8 H( V4 N5 J4 D* L2 j3 J
                        fds.SyncWrite( addr, data );$ o5 o$ M5 z; R" m9 @
                }
7 V2 P9 d; ]& e% |3 o1 N        }
: P% w( _7 i5 T) ?6 p$ y1 x" e: [6 O7 W2 b& A/ X2 v
        if( exsound_select & 0x08 ) {
9 r" V5 J2 e: J# `                if( addr >= 0x5000 && addr <= 0x5015 ) {
6 ^: f+ o7 U4 d* V                        mmc5.SyncWrite( addr, data );
/ S$ ]0 z: a6 Q0 M. S+ p                }( T! K' e) a$ R! x
        }0 ]6 Z0 X2 E$ y: J% g/ P
}
2 X8 T% ~# e2 k4 W  ~
( X: e0 V  {$ G/ q* `( x) c) }void        APU::Sync()
  ^$ h% Z9 f: A' Y& |{
3 x# t5 e) @4 x1 v, R! _4 \  @}
. L9 ^6 ^0 [* k0 S( D
/ _1 k5 Z/ `% @  o% Xvoid        APU::SyncDPCM( INT cycles ): `3 |9 a% u! o; P/ E  e8 h
{6 m; J& q: f) d; j
        internal.Sync( cycles );3 N  ]3 W( u+ r3 Z, Q; w/ g+ s3 x% _
5 N5 P, z' n- K+ L
        if( exsound_select & 0x04 ) {+ j4 `, Y2 {/ Q' n! T0 s0 |% S+ E
                fds.Sync( cycles );
! K+ M! a2 i0 `3 V5 ^6 @        }) o  T4 ~: C! M7 a% W" @
        if( exsound_select & 0x08 ) {
8 A* [5 `1 v, U! @% |2 y                mmc5.Sync( cycles );
* ]; s7 u, Y9 {+ v* j( |( t: v        }, w  y$ a' }4 D: s0 q
}( N: E  ]0 Q: n7 ]; h

  r4 u" w+ E: C2 cvoid        APU::WriteProcess( WORD addr, BYTE data )
; k0 U5 t7 J: b7 y' V" X- h{; ?9 m) d2 C- I4 r" i/ p1 R
        // $4018偼VirtuaNES屌桳億乕僩, }) x+ U4 l5 Q8 G# i$ j1 B
        if( addr >= 0x4000 && addr <= 0x401F ) {
0 E' i  \- T2 K& O) v/ J                internal.Write( addr, data );
2 f5 B# j( Q, w, n8 o1 S) h        }
/ x4 S: J  i; ~" N}' R2 g! V* s; [" f" S/ H  ^

  B- V% Y8 C  X) p8 o; w# ivoid        APU::WriteExProcess( WORD addr, BYTE data )9 @& n  s4 F6 P: ]
{
6 K2 I7 a1 b, _& s: z& J9 \4 R        if( exsound_select & 0x01 ) {
* h- W+ S# m8 b) t- S                vrc6.Write( addr, data );
# _4 y: O3 }: r( f, p+ w; }1 R" v        }, E& |  f" Z' F6 h. E3 l! y9 f
        if( exsound_select & 0x02 ) {
; B5 }' e4 h  y0 T" a3 q                vrc7.Write( addr, data );3 [( I! A  X6 G8 F  K' y
        }4 f) J7 x4 n+ y2 |1 t% ]4 J
        if( exsound_select & 0x04 ) {
/ t) n0 \: l  R% n- O4 @- `2 K                fds.Write( addr, data );, k  E" m+ }  a" O( V$ h4 j4 s
        }
+ G" {  P& E1 K/ ^0 d) t$ g; s7 A        if( exsound_select & 0x08 ) {" P' Y3 i+ c1 c5 r) e
                mmc5.Write( addr, data );" j: D5 e% t  d& W: ?9 f* }& p# s
        }
- X. N  c% U( D7 T3 e, |        if( exsound_select & 0x10 ) {3 Q1 A' L$ q* I3 a* l) ~
                if( addr == 0x0000 ) {
4 @. N( S) ~0 d. N3 F$ f                        BYTE        dummy = n106.Read( addr );& Y" A2 Y- u  l4 p1 ]# y
                } else {( o+ m1 ~3 E2 ]" J
                        n106.Write( addr, data );0 O. i% M( y7 c0 Y  A1 D9 X
                }
2 |: ?" a( c2 t2 t5 A' r        }
7 j5 Y  S* ~) ~, X. c/ \  M        if( exsound_select & 0x20 ) {
% e3 h) n/ M2 P( Y! R& ^6 ^                fme7.Write( addr, data );) a! W! a  g, K2 B' p) T
        }
$ k. ~" K- D# R+ G}. q# F" m( [: P$ Q  a
" a# L6 {0 Q% M- F. B. Y$ r' A- z
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
" Y6 y" ^7 j0 X{
* h3 ^& e5 r- _$ _) m. eINT        nBits = Config.sound.nBits;! m4 s& Z' r1 B7 N# s' R) V
DWORD        dwLength = dwSize / (nBits/8);
3 W, v5 Q& \$ b& sINT        output;
% b+ b. ^! z5 oQUEUEDATA q;5 V8 I8 M1 N  J- Q! P  Y
DWORD        writetime;/ {1 t- a/ Y/ s8 m1 {& r& E

6 G/ |2 o0 u5 R1 e9 LLPSHORT        pSoundBuf = m_SoundBuffer;7 K; E( |- E( G" g1 D
INT        nCcount = 0;
  z4 {4 n/ L1 j4 f' B; v# A* W  N5 v; D- m* [
INT        nFilterType = Config.sound.nFilterType;: U6 T! ?: l8 i& Q

. m7 g( v! j% l$ B) A        if( !Config.sound.bEnable ) {7 U& A& P' q9 P6 Q3 F& X9 I- ?
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
4 t7 t; P0 {' H% m, c/ h( Z                return;2 L& R0 Y  z. z" n+ ~
        }
: [' v. f! n! |& [2 e4 U% Z9 O) R1 V0 B) A
        // Volume setup
, |- B1 T+ a3 J- ^$ e        //  0:Master6 r8 l! p9 ~8 b1 |# C+ S/ l
        //  1:Rectangle 1: m7 M$ Z, B3 k8 B) R4 Y9 @- }
        //  2:Rectangle 2
1 m8 n2 t; n: V' F. c2 F        //  3:Triangle
% Y  `. R8 l+ d& z  I; p8 w        //  4:Noise. F5 n  N+ f  f* T; \
        //  5:DPCM
4 D8 z& x: p* n6 h        //  6:VRC6' K# L9 R7 W/ z7 U% y
        //  7:VRC7( }# b/ _( N- X' i$ s9 ]- a! u( p
        //  8:FDS
$ U: Q9 u# y7 m$ R, k        //  9:MMC5' W' n& J9 s5 k% I. D- u
        // 10:N1063 I2 _4 v2 h' H- d1 r
        // 11:FME7
8 q7 f) ?4 \! ]( W* ^# U        INT        vol[24];' B. B8 _6 @# @" {* |
        BOOL*        bMute = m_bMute;: n8 M$ V; V: U) m+ F+ g' q
        SHORT*        nVolume = Config.sound.nVolume;' T/ J+ y% F' V5 s1 F
! `3 f7 y5 Y! w" c9 o  G
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
' Q4 N( R/ s; M2 J6 p9 z; `- [# T+ Z3 d0 E
        // Internal
% e% n- H3 c. O9 F9 ]        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
9 Q6 L. ^, q, s) a! s) P2 ^' h        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;& E& y) B! M. P- O
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;  ?1 S6 O9 e& Z' N+ f2 j; _; A
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
) V2 a# P( I# z. H. ]        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;( O7 C3 j! O& K. P
9 Z' D6 S! n6 y4 R# ~
        // VRC6: x5 @5 K* A9 @! c& L
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
9 |' R4 n' a6 a) h/ E: Q        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;; {' l; ^" M! `7 W9 ]6 X# W
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
" I; ]( c/ }8 q: g, v$ W. W. X( {
        // VRC7- h) F& I' E# p& s0 a  G  C
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;. T) K2 m, J% C$ {$ y8 t* P
8 D# a7 y4 W1 X8 Z9 G) T
        // FDS
7 {8 [5 E3 J: g% m  B        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
5 ^# }6 W" g7 j0 D
8 `9 D% X# o3 V        // MMC5
$ k3 P5 R) s* m$ Y6 Y) j' O4 I        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;  z6 n9 V) B, B1 t$ c
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;% i2 {+ H* r( z  c' J1 @# H
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;6 K6 b+ {# p# D5 q& `% x
3 o7 B0 y. X/ `' T
        // N106
7 Y, Q) F0 ]/ d        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; ^" M/ y: ~: z$ V) P8 I
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;4 m1 _; y$ J& f# ^1 U5 U. K
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ T* W3 @* c" \: i% O( P        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
' {3 x9 V4 }! x/ M% K        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
6 ~# `7 l! ]1 F4 G' I$ g        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
* X5 c! c& `) V+ w2 P; Z, ^) U        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 R8 p) s. T* Y* M        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 s  J9 V2 ?( j1 F2 e' W5 s) t0 K% d  F2 ~* l' Z
        // FME7
' ~2 G( N- p2 m' j$ V2 R        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
& ~8 p! T. X) O& f; Z2 E# x& x        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;, V; V& o' R1 L5 \7 d% @' h
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;+ e, Q. \1 ^5 |# u
4 C" v7 |& d% ]) I
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;4 }/ {( `) V& e/ ?3 |7 N
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
, b7 E6 e( e; f
5 l: N2 e2 I3 s' F) |2 c2 d2 b        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟) |$ c0 z' _8 Q
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
% P* ]0 ?. g) c                QueueFlush();
* [& y9 C# Y' n6 ^        }* J7 q. ~( K" {2 _
5 f+ j2 Y1 p; i3 q* Y& f7 W
        while( dwLength-- ) {; W2 V1 a+ }0 z0 c. _  X* \
                writetime = (DWORD)elapsed_time;5 _; Z5 l7 ]5 j8 {2 d* W7 F
8 p' @7 D9 i0 U1 [
                while( GetQueue( writetime, q ) ) {: d: G1 h  @8 M
                        WriteProcess( q.addr, q.data );
: v: V* Q* ^, {6 H" V0 a                }
9 o" _6 _* h% F" O& U) _. P" A$ ]+ N  ]$ m$ M
                while( GetExQueue( writetime, q ) ) {
4 F  e' @3 j( C3 o" H                        WriteExProcess( q.addr, q.data );; ]! `4 d4 o( O% e
                }) B' ^4 X2 S: R; s
! ]9 P$ }" O5 d; R/ ?3 ?, n- Y- b% i
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
* K, k! G/ M1 Y6 O2 @                output = 0;
' k. y6 A% y$ f. }' s4 l  o; v# h+ e                output += internal.Process( 0 )*vol[0];$ @* h) M6 T. k6 g1 B
                output += internal.Process( 1 )*vol[1];& y0 F. k9 T8 Q; o* r( t
                output += internal.Process( 2 )*vol[2];, _( Y8 {/ }' T: V; D3 U
                output += internal.Process( 3 )*vol[3];  |) x' J  e9 @* N2 ~& O1 T* Q
                output += internal.Process( 4 )*vol[4];
) M- D: `: I% ]( T! @( g1 n* A5 E8 t. f9 K
                if( exsound_select & 0x01 ) {( {* }  y3 i- Y$ k( p
                        output += vrc6.Process( 0 )*vol[5];7 d9 `: t: d0 m5 a, d3 G7 ~# q, C' o: v; R
                        output += vrc6.Process( 1 )*vol[6];
# Q  m* |- f, O9 j: b                        output += vrc6.Process( 2 )*vol[7];& M* Y* @+ R1 d: R
                }
% E! z1 q/ X1 o/ w  L6 j                if( exsound_select & 0x02 ) {9 v; c2 w/ D" h# M3 y
                        output += vrc7.Process( 0 )*vol[8];
2 Y) Y0 p3 J2 @+ o8 e, G                }2 J, ?- p9 m' d! _4 M' y; p* {
                if( exsound_select & 0x04 ) {' Y' X/ ~8 V# f" U: I, R
                        output += fds.Process( 0 )*vol[9];
  y, n! f* @- O                }
4 w4 n/ v5 r+ H& ~; L+ v                if( exsound_select & 0x08 ) {7 N* l8 E) e& F
                        output += mmc5.Process( 0 )*vol[10];
5 A9 p5 s1 s, L1 I6 p* u                        output += mmc5.Process( 1 )*vol[11];# g6 v/ M6 V6 a, r0 y
                        output += mmc5.Process( 2 )*vol[12];9 l" x# E7 Z2 t9 x
                }, Q. K( X+ Z3 K6 Q
                if( exsound_select & 0x10 ) {
& j" ^1 l4 f' Y* A# T) d, F                        output += n106.Process( 0 )*vol[13];! Q- v: V7 H3 a* C- g
                        output += n106.Process( 1 )*vol[14];- X9 j/ d: l# l
                        output += n106.Process( 2 )*vol[15];1 _0 Z) ^4 O3 v) D! {+ T. E9 \" m! b* e
                        output += n106.Process( 3 )*vol[16];
/ i) w6 O! F4 `: o- Z% U$ ]                        output += n106.Process( 4 )*vol[17];
: Q/ r2 m/ L4 _, L' v, q5 u                        output += n106.Process( 5 )*vol[18];
3 ^4 J2 d. M* y                        output += n106.Process( 6 )*vol[19];0 n7 k, G2 @' h* z  R4 O" c( _
                        output += n106.Process( 7 )*vol[20];4 k& }' Q/ \! y" @( T" M' c3 h( p
                }
7 a' X/ s) Z. w: E$ j# x+ @. d                if( exsound_select & 0x20 ) {
  y, |" \5 S/ A1 X                        fme7.Process( 3 );        // Envelope & Noise8 X. O' T; X/ m
                        output += fme7.Process( 0 )*vol[21];
: D+ ^, q' k: ?. S, S, @3 A9 E- e! @                        output += fme7.Process( 1 )*vol[22];
" l% e- C  f( b8 f5 A- ]) ^                        output += fme7.Process( 2 )*vol[23];
' R$ Q7 O! [2 ?; M                }
! w8 Z: v8 ?) `) c* G9 n
# {: D( |( N* i/ C8 ^/ G2 K$ U                output >>= 8;
, a( R: @( P, }0 i' s$ Y% ?% F9 n- o* |
                if( nFilterType == 1 ) {% b1 Q$ F5 n: |4 [
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
; t* s2 i) t2 E: ~4 Y                        output = (lowpass_filter[0]+output)/2;
1 z4 \, v6 e4 ~) h3 d& \                        lowpass_filter[0] = output;/ q! ]2 m& h+ B+ M& b
                } else if( nFilterType == 2 ) {
1 _5 U+ R  G% Y9 C& J                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)( L  D) N! Q2 E: X4 q# l& @
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
! x0 ^" l; [* v1 l7 t/ d                        lowpass_filter[1] = lowpass_filter[0];
" }6 T( A$ b# T8 c# }; t; l                        lowpass_filter[0] = output;
% x7 B' X  Z: J. e6 x                } else if( nFilterType == 3 ) {% E1 ^8 K3 ?* ]" d
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
* Q  @! M/ Q7 U! R                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
0 ]7 q  x1 j5 z' ]7 V( M                        lowpass_filter[2] = lowpass_filter[1];
" K, ~% h" `9 l& E- B                        lowpass_filter[1] = lowpass_filter[0];
; i/ n) {: w; @4 Y6 S$ `                        lowpass_filter[0] = output;
  o1 G7 {: I- \+ K( U                } else if( nFilterType == 4 ) {+ E' ^  ^; r5 ]6 O2 F8 U. D
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
( j% g0 h/ v! [1 V6 n) E6 a                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
2 c$ [8 K& b2 K3 y/ x. B                        lowpass_filter[1] = lowpass_filter[0];
" P& h' `6 v( y4 ?$ X                        lowpass_filter[0] = output;
2 D: c: K4 K* h$ N5 s; O/ k9 ?                }( A4 y* m* ~5 B' F
; e' L, o# V8 u% A% b
#if        0
* x6 O/ V8 E, |1 Q6 L                // DC惉暘偺僇僢僩
. ^: Q, T0 ~$ o$ P0 U1 [+ r                {
! S) p% O( J4 {                static double ave = 0.0, max=0.0, min=0.0;- o) n( x* o( _4 U0 ~! k
                double delta;
, \& v% P% l3 u: G                delta = (max-min)/32768.0;
7 _; f! N+ r3 Q8 g& d                max -= delta;
! C3 \& [5 P$ x! S* Q& x                min += delta;+ V* q+ w/ m3 u, ~$ n
                if( output > max ) max = output;1 w4 q( @. p5 r/ Y" C1 |3 i
                if( output < min ) min = output;
: E8 g; R4 j# `+ }3 u# s7 R% `                ave -= ave/1024.0;0 Z0 R3 I2 ~$ `4 ~/ K  s2 E. q
                ave += (max+min)/2048.0;
$ u0 Z& `% X, g0 z0 a8 a                output -= (INT)ave;
1 x* x4 d6 |# K/ o! _) Z                }
0 S6 ^! f  H% A#endif2 X1 P9 r% R( O2 K) v! r" {* g" C
#if        1
9 X1 q" M! ?+ Z' Z0 O( m1 s                // DC惉暘偺僇僢僩(HPF TEST)
  `& O; V$ W9 m4 S+ V" |                {
1 D9 ?$ l' j8 R, D, B1 y" n1 i1 j9 `//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);& M9 J. {% t( V- s
                static        double        cutofftemp = (2.0*3.141592653579*40.0);! G. ]4 T1 N0 C, i
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
# w4 P( L3 w& \& X  G                static        double        tmp = 0.0;
! q9 c, U( `7 u                double        in, out;7 O6 ^; j9 \4 }3 m
) ?& ]/ Q3 g6 Y: L, }* N
                in = (double)output;
  `% |4 o# Q$ P                out = (in - tmp);
; F( l2 i+ x1 i" x0 C                tmp = tmp + cutoff * out;. z' x5 V% ?" d
  n. L: e$ V. h2 c5 i* e  u
                output = (INT)out;3 r) E3 I2 O2 C- u( p0 c# V3 e
                }
: U9 o8 U7 k8 K* _- u6 R#endif
( B) W3 U- A; k9 J7 B#if        0$ v4 \4 {1 y7 r' }+ h: o* u$ A) f
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
0 k5 f" I) Q! [( T7 D6 I                {# Z0 c+ Y! S4 q& N4 o9 O
                INT        diff = abs(output-last_data);. [2 H7 ~: o3 q! J
                if( diff > 0x4000 ) {
+ H/ c: V6 l. s( C9 ?: H3 R* W                        output /= 4;' i5 {* D& A" o6 Y
                } else
; t, g6 F0 _4 f0 C- Y, I                if( diff > 0x3000 ) {
! m: g& c5 j" A; ^$ ^5 u! Y: o                        output /= 3;
6 x) N; w9 A1 o# b' l                } else( b# @0 C/ @2 P$ P- [
                if( diff > 0x2000 ) {
% _" q  f6 E8 q" E) ?. _5 o                        output /= 2;
5 U- @4 G: H% ]; n                }% c, r0 l# K( g9 t
                last_data = output;1 u( P5 H/ c2 [8 e8 [5 f( ]
                }
/ B9 y1 D; e1 \$ V#endif
, f: M- W1 z* R. o/ D                // Limit
6 {( a. e) h/ V' \% f                if( output > 0x7FFF ) {2 Y6 d: `# O) ^# Y  b5 x  |4 Z; p& W
                        output = 0x7FFF;
" W! ]$ x3 u; x                } else if( output < -0x8000 ) {3 g4 t( s6 C, [0 t$ o4 |7 P5 t/ g
                        output = -0x8000;
; t5 b" f1 u  V- i3 i5 ]                }
2 T3 q8 |1 G* Y; k! V
3 N0 f7 t" U6 X  S; X8 p                if( nBits != 8 ) {
9 x  |: N, l' \' s  C; ?) ^                        *(SHORT*)lpBuffer = (SHORT)output;, V' t  M# [6 f. R2 N. U* ]2 k, d
                        lpBuffer += sizeof(SHORT);- n9 ?+ p# B( w
                } else {
7 y3 x0 P& Q# ^* e; t7 O: H                        *lpBuffer++ = (output>>8)^0x80;
$ E' B% ]# y5 U0 B5 d                }
$ y+ R6 N2 I. R2 N
6 C; M' N5 s7 O4 `                if( nCcount < 0x0100 )
9 N( Y' a0 y& R# `, Y) b                        pSoundBuf[nCcount++] = (SHORT)output;  z# ~  x$ v/ l- r9 C3 z" k
4 [6 n& ]8 ]- N+ V
//                elapsedtime += cycle_rate;
3 I+ L# O' y2 k3 O4 Z                elapsed_time += cycle_rate;
' t0 S9 `3 c: P. |! ]  T- s        }
6 w' K, D. }+ ^& d- g' i7 w
( m' F/ _7 z5 L# H( ?#if        18 X( D6 M! O4 ]
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {/ ^! A  i4 m; ^' l$ }, g3 M
                elapsed_time = nes->cpu->GetTotalCycles();
2 r( Q- N- t8 t1 w. B! [& z8 t        }, j# R5 g7 A4 a! n0 u, K
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
7 Z3 [: y7 N9 q6 _                elapsed_time = nes->cpu->GetTotalCycles();2 M8 W# b' z" {# n% E; {' r$ K6 l
        }- C: u3 V& W/ {1 ]4 A+ Y
#else
! N- A, I" I! M        elapsed_time = nes->cpu->GetTotalCycles();/ J2 D+ w1 v" c( c
#endif( ^0 U6 @& J7 l5 Q
}
6 {. ?0 e7 S% L! L
) s9 [3 r7 I7 @' i$ \& [// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)( G% @: J5 Z3 @- b& X' w: g; T- z
INT        APU::GetChannelFrequency( INT no )0 J# x5 c/ T( W
{, P+ Z* S# Y' n1 _7 a8 ^
        if( !m_bMute[0] )
. E6 z' E; O" `" m: w                return        0;
3 `/ R1 S6 d% [5 _: Z+ O* W% I, m- d% \8 J* A, |" e/ h
        // Internal
7 A- n8 C/ N0 e, j* M        if( no < 5 ) {: M+ K$ ?" V- j5 J2 I) t
                return        m_bMute[no+1]?internal.GetFreq( no ):0;2 \+ q$ i! j* V+ i( e6 D
        }5 A& F: t& o1 A, ~6 Z0 R
        // VRC6( d' ~3 F0 d) K
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
0 s# w* x+ P) M! k0 _2 A( t                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;% m: N  _5 b: Y2 U! C. M
        }
9 V/ t8 H0 k2 Y$ D0 Y        // FDS  f1 `7 v/ L9 C- ~; c: n. Q/ W3 V
        if( (exsound_select & 0x04) && no == 0x300 ) {/ [9 t. r+ L6 t2 v( C
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
/ |( G" k- e* Z, f& \$ G- K        }
; p9 z1 b0 l1 r2 G4 L: g; Z        // MMC5! M) O# e* ]6 u* P
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {" j  U6 G! ?% y+ [' ~
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;* y0 B4 g$ {7 c7 ]: _' b
        }9 _5 V0 e: ~) i! S# W9 V7 \/ o. M2 s% n
        // N106- \' y# _  V7 c% k( U! f* U: h
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
; [" r9 `/ [; R: f" m; j2 {% S                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;4 `* a1 ^& y$ l) b5 d4 b6 {
        }# l. M5 k7 W/ f8 ~: V3 \0 n
        // FME7
" G* @" s" O% Z5 g7 q5 s        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
( J8 ~7 R; |3 H+ H                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
( n5 L8 l0 O+ H( L" O        }3 _( t+ V( U7 t7 t" |/ o' c
        // VRC7
( s+ l' r" }2 g5 C$ m* r        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
8 p. V3 ]2 j; ?& m                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;& p* R+ @+ B: x
        }' U6 y/ ~7 ~7 P1 M+ u
        return        0;0 A" R* T1 A& F
}: W% _) e7 ]$ `) R4 k$ G
% ^4 p9 f+ E5 B& s7 O+ V- J5 E
// State Save/Load) P- G& w  a3 N
void        APU::SaveState( LPBYTE p )
! K  {6 q8 K/ L" e{/ `* l" W9 u8 w+ ?
#ifdef        _DEBUG1 X+ w" h! `( O6 w4 P
LPBYTE        pold = p;" k: t1 V9 \. U: T
#endif
* l% L" n& e  A( i" h, |+ x& h7 ^2 G
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
' ?* ?' m& G+ k; t- t; i        QueueFlush();
6 i" k& [+ E: `, m+ g! y. G: B6 J& v  p4 W" u( n! u+ g
        internal.SaveState( p );
9 L" L8 D$ W9 U/ X        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
+ k; C; J3 G6 Y& b% I: }  s2 j3 u: a# z! \8 n
        // VRC68 u0 F9 n7 I0 z$ r+ G
        if( exsound_select & 0x01 ) {. J0 p8 H: K2 A7 S
                vrc6.SaveState( p );
/ k. o% i8 G7 c3 {& Y1 y; C                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
5 W" N. j! q, j0 \5 _  s        }
. F6 S  \. r+ Q. g! l) u        // VRC7 (not support)+ ^' b7 d9 k2 F; o8 w6 }; z
        if( exsound_select & 0x02 ) {
$ @' e+ X; l" k                vrc7.SaveState( p );# ]6 A: v1 J/ n1 c7 ?
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
9 F) R1 h9 Z8 M- K        }) Z. H- z9 m# i; O
        // FDS' [. p. q, x" H0 ~' Q
        if( exsound_select & 0x04 ) {: M: j+ m5 j* i& ]! B. |
                fds.SaveState( p );
1 h+ S9 Q/ y. W: j* Y8 r                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
6 U+ ^8 a9 q8 C! }5 v: n        }
( E8 m3 M' U0 z' G# {" _0 @, s( P) J        // MMC5+ S) o6 t/ W: x# z& D# t+ [1 L% _
        if( exsound_select & 0x08 ) {
/ ]7 i9 \1 L! J2 X7 ~                mmc5.SaveState( p );, e) X0 O! ^9 o) T+ h
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding4 @9 d5 z& I7 c, ~* b, ]6 q. {% \- X
        }( p& F4 l2 d0 J- G, c
        // N1062 c! U; n5 S6 u% q1 c% H
        if( exsound_select & 0x10 ) {
& y, Y9 n0 D& O. J9 P                n106.SaveState( p );
- {' I0 O- g& x                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
9 h8 g* F2 N" G3 o% g        }( T4 y! n7 u5 {. @. q( K+ F! E
        // FME76 S) t$ }9 u) _/ b
        if( exsound_select & 0x20 ) {' I' Z# F' H& D" |
                fme7.SaveState( p );9 t3 k, M9 n2 X
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
- B8 u5 N8 ^& n  R  L        }
# j3 ?8 n$ w$ \
: I% @5 X& D# p. e#ifdef        _DEBUG
  _) }" C8 Z. x6 `* Q5 IDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
) E0 A; T% A. r; w#endif
1 H, E- O& }) b" e) M1 w& G}
; m1 ~7 ~6 H" P+ H# N; y$ P
) ]* I3 r- o% m1 _: Uvoid        APU::LoadState( LPBYTE p )
: x+ g3 q% W  T/ p6 C0 I; g{1 H' m8 B' V6 p3 g$ u7 w# B  k
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
+ v; T# ?' }; }# m        QueueClear();, _2 ?, H6 \! W) D
4 R1 m/ c! ^5 {; _
        internal.LoadState( p );
* {# B3 q+ x6 ~; x        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding) K5 G. O. \3 i, @" ?: E

" [8 X6 S* t  [& e$ ?) N9 t        // VRC61 j6 |8 B- o1 w" @
        if( exsound_select & 0x01 ) {
  A* T* |; ]* j% P4 D, c                vrc6.LoadState( p );
$ U' \; u" Q$ q$ _- G  _' P7 p                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding* c8 P( O' ?- I" W$ K1 _+ ?
        }0 ?; S( b6 H/ o  S. R" ]5 C
        // VRC7 (not support). u; g  X, ^& \  ?7 L* |
        if( exsound_select & 0x02 ) {8 h2 P( W  W6 Y" E* O9 z8 d
                vrc7.LoadState( p );! n8 g: k/ \: z
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding1 U4 Q/ e% M" D0 f9 [
        }
) S8 n6 ]6 O, c4 O( [2 X        // FDS
6 l4 ]+ \9 V5 D        if( exsound_select & 0x04 ) {' K5 e5 W4 K+ o: @
                fds.LoadState( p );
5 ?$ K5 [: m6 j6 u3 T1 h, s, S                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
- U' M( p' e+ s+ |) r- ?+ `! c3 f        }
% `  N& Z, m  D  b7 E, d' s        // MMC57 y! j6 L4 ?' [, \7 C
        if( exsound_select & 0x08 ) {, o! x1 ?3 R2 G- j, l3 e
                mmc5.LoadState( p );; {3 J/ b: l# [) ]
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
4 z0 B% ~, k- Y) \# D- \        }
4 A: V5 _3 w9 [/ s        // N106
; I) h0 Z. F/ \1 G& H        if( exsound_select & 0x10 ) {4 F6 v/ R/ }5 K# W$ L% Q. ^* D2 T
                n106.LoadState( p );
, o% G9 `$ p  g' \, B( S                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
3 \( Q* F9 J5 A5 l        }$ q+ ~. D) O0 N' \' y2 D3 ~
        // FME7
  _* m7 X' |: W. l/ c( ^5 i' u# J: |        if( exsound_select & 0x20 ) {( T, s6 W$ Z9 m; c, J
                fme7.LoadState( p );1 W  l) K& {3 ~
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding8 ^) @+ E- Z1 V9 r8 Z- d1 i
        }' j; Z& w: {: s5 v
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
8 U7 w+ x% X3 {! b9 N可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
& b6 a2 f6 |3 e2 X2 {5 B感激不尽~~
, m' O2 t9 Y  e( w) {) b* h
恩 我對模擬器不是很有研究,
$ l! m5 D6 s' W# ~2 }! E; ^雖然要了解源碼內容,可能不是很困難,
% P! [/ E/ ~; y3 J. R3 u不過還是要花時間,個人目前蠻忙碌的。% {2 d  F- b/ ?" x1 u8 L3 V
* z# t+ L: K+ l" S# t" |* [$ a# n7 {. l
給你一個朋友的MSN,你可以跟他討論看看,
4 _2 x. h2 v* z4 Y; v/ t" ~7 x+ ?他本身是程式設計師,也對FC模擬器很有興趣。
+ a! B0 z. s8 x5 I2 z$ V& U0 n; t, d$ h: F) r7 H8 \( S
MSN我就PM到你的信箱了。
8 k+ i" L: f2 s+ ~) u
, y; y1 H5 h% C3 u3 n$ p: w; ]希望你能有所得。

该用户从未签到

 楼主| 发表于 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 }3 V8 F" s# T7 V8 l/ \, r0 `1 {. E1 _
呵…… 谢过团长大人~~
3 D& w0 D2 |1 F# n
8 }* v4 E- B# s1 p) O, `
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表   J0 ~- O5 f9 P6 B" Z; y
团长的朋友都是神,那团长就是神的boss。
7 ]. j1 K# N! f% x9 i8 n
哈 不敢當,我只是個平凡人,% R  D2 b) N: }  |: a
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙; V% u: l* R# C  G# a5 Z7 r
ZYH9 O9 V6 G; D* E! B* D5 U9 P0 Y
QQ:4147343061 U/ ^) a' W. e1 z3 ]+ t
Mail:zyh-01@126.com
' K5 t( }$ e6 [4 ^' p
; u7 O$ V1 v. O) v  z, w1 @他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 ; c/ ]0 j$ N8 n5 z; a3 r3 ]
再次对团长大人和悠悠哥的无私帮助表示感谢~~

8 c5 t9 J; m/ ]不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-18 10:37 , Processed in 1.138672 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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