EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
3 @5 K& N. s/ @. Q) |  b( \: [楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
" o, c1 n' \- l+ t4 N: u这里有相应的模拟器源码,就当送给大侠了~~1 Y2 y1 s2 q2 h
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 5 s7 r& K. T5 I4 T
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
4 E# Q5 r' L- l" ^8 F0 f; j' Z0 w楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
2 K7 T! F9 d9 w: c这里有相应的模拟器源码,就当送给大侠 ...

4 N/ ~  F1 R7 [' q  @& E  ]* p: F聲音部分(Audoi Process Unit = APU):
9 Z- X$ p. C: r8 J6 z& m! D.\NES\APU.cpp
% h3 K0 \5 H4 u6 j.\NES\APU.h
$ a4 G( q, {7 [7 X9 {% D
, C& W* P4 \* ^, d$ k+ W) K( y/ U* j! d2 p5 _% Y5 z
影像處理部份(Picture Processing Unit = PPU):
# T. o$ O# f, Z6 v  a.\NES\PPU.cpp$ [  M; Q0 O( d5 J# l0 [, k; V
.\NES\PPU.h. P! Y2 W7 O0 S7 x. T# T+ ?

1 T5 U- [) U- A* h, S( F如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
( I3 ^( v4 k- s7 x2 z. \(由于很多专用术语和算法机理都不明白,所以看不大懂……)
  q9 w( s3 X) Q! c7 g0 M//////////////////////////////////////////////////////////////////////////
9 p) Y  q* \% L) i$ T4 v( E9 c' S//                                                                      //5 g4 }8 b1 R2 Q
//      NES APU core                                                    //# H$ w9 s8 c5 l* N
//                                                           Norix      //
' y% E8 q. R7 w4 |//                                               written     2002/06/27 //9 x  K0 E4 ~9 h3 F- N7 ^& r
//                                               last modify ----/--/-- //
$ n3 R' s9 W3 k9 p# k# z/ f+ j  \//////////////////////////////////////////////////////////////////////////
5 [1 ~! ~# ]$ p#include "DebugOut.h"/ @; X5 ]! y  u! [+ q# a: `' Z
#include "App.h"
- H/ q' P* U3 Z& i# e0 m#include "Config.h"
4 f; i) o1 v$ F% v  C
- [" L& K7 s8 i#include "nes.h". h; h1 k, n0 h+ v" G" Y! o, K: n6 `3 E% |
#include "mmu.h"$ K8 `! ?" ^3 E
#include "cpu.h"
; n7 ~1 \1 ~4 X- q; V- L! [#include "ppu.h"6 R  {2 ~; w: n- c
#include "rom.h"
! L% N4 l2 T3 l5 ~#include "apu.h"8 D1 q5 p/ E) w2 q) I  d
2 N% [+ J# r* A* v8 }, O- Z
// Volume adjust' W3 ?& X$ K- ?( Y( ~! w) ]& F/ v; k
// Internal sounds1 _8 N4 m4 }3 Z# _
#define        RECTANGLE_VOL        (0x0F0)# n3 K4 W# H# ]" _% ^7 j: r% B1 _, w
#define        TRIANGLE_VOL        (0x130)
( p* N/ k& Z. @4 a* a& ^& ?#define        NOISE_VOL        (0x0C0)& d- O6 U; g6 @! q& Y
#define        DPCM_VOL        (0x0F0)
# x8 E& M7 L$ W8 w* J9 H// Extra sounds4 H/ [  U8 M0 d9 L/ A: m4 ^- s
#define        VRC6_VOL        (0x0F0)
, v9 \6 M: P9 |$ P6 G. o; `' c#define        VRC7_VOL        (0x130)
( k9 w# `$ G6 v+ V3 Q1 J9 f! H#define        FDS_VOL                (0x0F0)
  w& ~& D# n$ i. L$ ^7 F#define        MMC5_VOL        (0x0F0)
$ z  y$ f) B: r- L# g9 s1 a* ^& Q#define        N106_VOL        (0x088)
" J( ^1 _1 P9 I' w4 E) v- X8 |#define        FME7_VOL        (0x130)( v1 I3 y+ ^9 Z4 l6 [' V6 f

8 D0 ^% [. _, W8 R" z7 [" RAPU::APU( NES* parent ), {9 p3 G  e1 o8 ]
{
+ Z) h/ A- X2 {- I# S        exsound_select = 0;5 W7 @3 d+ L/ W. G

% J5 W0 d2 ^8 V        nes = parent;
: l$ b* {( M$ E. N8 y; k        internal.SetParent( parent );' Z, z4 d+ L5 t

6 D! t' c0 l7 a4 l' C: q. T! W        last_data = last_diff = 0;6 n6 }, V/ e$ P* E3 d2 b

/ S+ c- k8 [( h. S1 ]- U        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
- q& m% \9 p. M0 M' R6 H" y, m6 ~* O! `- ^/ T0 A
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );1 q0 |& e6 V. Z% z" U
        ZEROMEMORY( &queue, sizeof(queue) );
+ B7 i; ]9 C) q- y2 H/ c# _  ^        ZEROMEMORY( &exqueue, sizeof(exqueue) );5 _) d: a# B( H3 T/ _9 }4 j

( g2 P: D' A. ~+ ^' j4 h. J        for( INT i = 0; i < 16; i++ ) {# q0 _; L/ R( {
                m_bMute = TRUE;% n* w" l8 A3 i# V
        }: X$ N5 G7 [2 E1 _2 {
}
& H9 X1 y5 s0 X, [. U' r
/ e( \, K* f- q6 U  CAPU::~APU()
6 l" R* r9 x' r: ]  [5 }* c{3 E+ A# I* _( Y1 K' x- O8 B
}
0 m% u7 g! f) n1 E0 |2 ^
& |# ?4 t/ ~8 W( X+ e0 E" Qvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
8 h7 V/ p9 S9 Y, `. W+ |9 w{6 g; v$ `% x/ h' O- M
        queue.data[queue.wrptr].time = writetime;$ M' P" M9 ?7 y6 i" d& p' n
        queue.data[queue.wrptr].addr = addr;
/ X- t$ n, s( G' j  M8 i        queue.data[queue.wrptr].data = data;
7 f4 P! g; u7 [        queue.wrptr++;; d7 b  `9 O* w# F+ a0 Y! }: I; I4 P
        queue.wrptr&=QUEUE_LENGTH-1;
% b- l8 ?0 f/ G! y: v        if( queue.wrptr == queue.rdptr ) {
0 m0 d7 N( s# [- M& v" n8 c                DEBUGOUT( "queue overflow.\n" );  i1 i& `, H$ b
        }/ [) k" \5 D- D+ r8 v/ n
}
7 |, [6 h& o, ?8 |+ E& D, U8 f+ m
/ L- k! A1 l+ F# MBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )( Y# h: i& V+ f$ R% O* \- j6 o
{1 \- m4 A$ W: z" d9 J6 z% k
        if( queue.wrptr == queue.rdptr ) {
- M9 ^0 l( y) u                return        FALSE;/ D# B; I; E& g6 C/ L; `
        }
( Z  j8 D- a5 g2 U4 p        if( queue.data[queue.rdptr].time <= writetime ) {
3 B% Q! |  k# i3 k) w$ r                ret = queue.data[queue.rdptr];+ `1 S& p6 N& n. b0 E/ d$ q7 r& q4 B
                queue.rdptr++;
+ Q* l/ C$ f1 @5 u1 M* V6 n; e6 W                queue.rdptr&=QUEUE_LENGTH-1;0 O0 |" E& Q# N2 j' v
                return        TRUE;5 D7 u0 h3 Z' U
        }
/ P, \2 T; @$ @: H6 y6 f5 s        return        FALSE;+ Y' x6 S% E; O2 B
}
* V1 S& ]3 W1 c( g: u- n  a: Z% V
. t5 J3 y# k9 Q$ Jvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )! q; L4 S3 t* `3 f0 S1 h" G" i, }
{
# X1 [: G  W7 x, y& l        exqueue.data[exqueue.wrptr].time = writetime;+ L( j3 K: g- i" p
        exqueue.data[exqueue.wrptr].addr = addr;
3 G% c$ g- U+ X        exqueue.data[exqueue.wrptr].data = data;, `5 ?5 x5 m$ x( u" E6 X+ d
        exqueue.wrptr++;& o9 r$ w! @7 R3 l, t
        exqueue.wrptr&=QUEUE_LENGTH-1;
7 o: V( M. R3 u+ P        if( exqueue.wrptr == exqueue.rdptr ) {
* Z+ n" [6 ^* G1 b5 ~                DEBUGOUT( "exqueue overflow.\n" );4 i' t. F6 g/ d. F" L: @
        }
/ V. ^7 f+ ?0 x2 p7 ]3 ~9 ]2 m1 B6 D" P}
! g1 y! x" y* B5 Z6 y" Q/ g8 s0 ~4 G  ~( f6 T9 U' i
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
& x% Y  W; B* D' q, f$ u/ s' ^/ l{
) m) x; D; R+ K/ b        if( exqueue.wrptr == exqueue.rdptr ) {5 s; o2 v! W" p% U- D* ^* ^) x7 O
                return        FALSE;
$ f8 `% w8 B$ e/ s  h9 e3 Z+ ]        }2 J0 L4 K; g/ A* [7 x
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {$ Z% V. y8 b8 w: b! V! l! e
                ret = exqueue.data[exqueue.rdptr];# D6 B+ Q( K8 T% |2 ]6 q
                exqueue.rdptr++;
) w* H, V( @* j$ l, O                exqueue.rdptr&=QUEUE_LENGTH-1;
1 F9 ~7 k2 g8 E1 I9 [0 a                return        TRUE;
( J: e) r) a5 T  H- L+ ~        }" ~: U# E7 t" `  f
        return        FALSE;
9 H" ]' M- h, g7 k3 J}
2 p- M3 Z9 n7 |( a! p
& J( s6 W0 c* D% ~: [8 Ovoid        APU::QueueClear()# ~' A0 N) }. j  E1 [
{- M; b* q) _1 y
        ZEROMEMORY( &queue, sizeof(queue) );
$ t! W) M4 B8 D) ]3 z, f& A        ZEROMEMORY( &exqueue, sizeof(exqueue) );
5 e: c7 g9 p8 O1 Y% m8 A; H# [- _# g/ z}' ]4 w- I% @8 K& j7 y6 ]
1 ?3 h( N3 Z% N* z. m1 p
void        APU::QueueFlush()0 Y+ u8 l  i+ ?1 n& |; Z( n9 ^+ q
{! |9 ]* @0 `- ]4 P% H2 N# I
        while( queue.wrptr != queue.rdptr ) {
% W3 `# ?4 Q; C  f. W                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
: h# \, j: ^1 {, {                queue.rdptr++;+ ^$ c. `9 M3 ^  s/ J6 n$ g
                queue.rdptr&=QUEUE_LENGTH-1;% R! A- ]: v$ ~) v
        }
& G5 e! ]4 B) E. Q' r4 \0 X9 o& Q; `/ y0 s4 X0 W
        while( exqueue.wrptr != exqueue.rdptr ) {
3 n6 }" o( G( Z* K6 A$ ]                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
, ^0 _% l. G* G; q                exqueue.rdptr++;; c8 ^4 W6 N7 [* s8 ]' S8 N
                exqueue.rdptr&=QUEUE_LENGTH-1;
+ M* {3 E) P6 x9 Z( _        }
- Z; }( c0 X. _}9 Q4 |+ a) u- x* y8 U% o
0 v* o! k. Q% Q2 G; T. j3 O2 O# Z
void        APU::SoundSetup()
1 N7 b$ e) [: [: y9 w$ v" t' b{
, t! T9 y7 o4 h% `3 `* a3 g        FLOAT        fClock = nes->nescfg->CpuClock;
9 K# F$ x2 ?  J: h9 S        INT        nRate = (INT)Config.sound.nRate;' j# u( u, j! K* ?; S
        internal.Setup( fClock, nRate );
- h4 ?4 d( a% O, E( V# i' O        vrc6.Setup( fClock, nRate );7 d3 d1 x! Z' l% J2 X/ w! d1 \- {
        vrc7.Setup( fClock, nRate );5 c1 s! r; a" M# J3 M
        mmc5.Setup( fClock, nRate );
0 C5 O; ?! Z7 ]. T        fds.Setup ( fClock, nRate );
2 E" K* j: Q$ E( i" n% l        n106.Setup( fClock, nRate );1 }# z  a/ o5 q/ q
        fme7.Setup( fClock, nRate );. T# |6 G! g5 [7 J8 ~' |
}5 f) Z- U7 x/ i& I

0 \6 S" l- ?1 y9 c# m& R) ?void        APU::Reset()1 `* S- {5 ]& {, X* i9 k
{
7 J7 G  W" {1 H4 Z        ZEROMEMORY( &queue, sizeof(queue) );" A/ W' ?) V4 s6 i6 f  j. U8 V
        ZEROMEMORY( &exqueue, sizeof(exqueue) );' k$ J6 B, [8 K: l
( N3 r5 |+ i& C- ]8 c' U& R
        elapsed_time = 0;
$ X, X1 O: s  ?) t1 ?2 v3 N& A1 f0 Y' {' b
        FLOAT        fClock = nes->nescfg->CpuClock;
  w# A( u* _/ B) E& @; a        INT        nRate = (INT)Config.sound.nRate;2 M1 y+ Z  S& g0 y$ i) O
        internal.Reset( fClock, nRate );
7 F2 g% z/ F0 V' L) f! L( B5 N. S        vrc6.Reset( fClock, nRate );
8 |5 _9 Z* }" J2 R        vrc7.Reset( fClock, nRate );
' p; {; t! Y$ g6 [7 k/ C        mmc5.Reset( fClock, nRate );4 U& a9 E/ U  S+ V, I8 @: r8 K9 ~
        fds.Reset ( fClock, nRate );" a: S" f- I% L+ w
        n106.Reset( fClock, nRate );
4 ^' p9 J/ A' B8 D$ T        fme7.Reset( fClock, nRate );
& X; F* e( h) {( l
8 w: ~$ {+ L. u  Y        SoundSetup();
3 _; R6 A9 H( n6 s}
6 j$ m. X: ]8 \. M6 x6 |* Y. ^7 ]# M( W: b6 h% P+ n2 ?) G, ^
void        APU::SelectExSound( BYTE data )
: u: }& ]$ q8 ?+ e4 _{
0 }( e; K4 Z6 P, j5 i+ Z/ {        exsound_select = data;: ~. m0 e2 T' n/ d' x- L$ E) F- ^
}
9 Z  k4 D5 }5 x5 z7 _' Y2 r/ P$ o% |
9 a* ^5 a% g% _  M$ L/ L' _% mBYTE        APU::Read( WORD addr )
1 V% u: I+ M5 U6 r; s{
3 E9 ^# A. h- @        return        internal.SyncRead( addr );# z5 t7 u1 a  f$ O9 k4 _% w& C5 I
}  p& \5 p2 d) F6 t+ U! b! v

$ z7 e6 b# G0 z9 f% y& }, ovoid        APU::Write( WORD addr, BYTE data )
5 C) q& |/ z( L2 a5 O! X7 {- D{
5 n. G4 i8 @6 ]        // $4018偼VirtuaNES屌桳億乕僩; q: Z( I9 h8 V: r* ?, d7 I) I
        if( addr >= 0x4000 && addr <= 0x401F ) {4 e! C% r' P8 M5 }( u4 F
                internal.SyncWrite( addr, data );
/ h$ c' c: g/ A$ i  n5 `' R                SetQueue( nes->cpu->GetTotalCycles(), addr, data );/ _9 p" j& T* z8 M$ t* b
        }
: ?/ L! V) P) r7 @/ f}
5 |* s5 I8 [1 A9 J9 |
/ {7 ?) g8 _% TBYTE        APU::ExRead( WORD addr )0 e" z3 d% C8 ?6 M9 [. G( E3 m
{$ {' v6 |5 g( p% t
BYTE        data = 0;
  q* Y6 `! }9 B; o) ^, s8 j$ p# \1 I& N* B
        if( exsound_select & 0x10 ) {
7 k. }8 T% s& ^" i, w                if( addr == 0x4800 ) {. L6 }1 L$ s" x: o6 g
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );& ?. W: h6 \* m9 y
                }
2 [. Z' i0 R; n9 f, e        }! U0 [3 G* [# T
        if( exsound_select & 0x04 ) {/ u, c2 D( f1 I7 W! i
                if( addr >= 0x4040 && addr < 0x4100 ) {0 E) O7 @9 h, s/ n
                        data = fds.SyncRead( addr );
' \, D' U% x; n4 n9 R3 o2 D. C                }6 O' h3 R% e* M1 @1 y* S
        }
" \7 I8 D" A( Z* R" M8 n( P        if( exsound_select & 0x08 ) {9 c0 p6 z; s# w5 V' O; Y' y; S
                if( addr >= 0x5000 && addr <= 0x5015 ) {
' e' K+ N* L2 i                        data = mmc5.SyncRead( addr );
2 ]" l1 L& M8 g( w                }% o2 _( ]% ~6 H9 c& u$ h
        }+ a9 t' Y( z% {" M
- U/ u- ?& D) y6 h2 O; u, t: X
        return        data;
8 ^! _3 I, o% l- [5 |7 S}
6 f0 e8 r, t( a& @, x4 s0 y6 [0 p* |5 o% s1 k$ k
void        APU::ExWrite( WORD addr, BYTE data )
) \' ]- k4 u5 W5 K4 l4 h$ p{: R5 T. }9 v- ?0 }: z, d
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );  a- I1 v: `# X6 l, N) W2 f

$ S( T$ U1 N2 Z, s5 ~$ V        if( exsound_select & 0x04 ) {
* u! k# ?7 Z" [* m" {7 W' ~& h/ {                if( addr >= 0x4040 && addr < 0x4100 ) {
+ x, @! T/ L5 u; r8 H                        fds.SyncWrite( addr, data );
1 m: O( Z4 H( u. t: K                }% P0 e# o. E" p+ F4 E: N
        }
6 Y7 `9 ~) s! V4 |$ B8 m) I( N8 r8 v+ ]) }9 c
        if( exsound_select & 0x08 ) {% u$ L+ p0 F, H9 y1 i1 v
                if( addr >= 0x5000 && addr <= 0x5015 ) {0 V- ~, m' O  i% ]$ |* U3 C
                        mmc5.SyncWrite( addr, data );3 w  b1 \2 X  U  d: ?& _" f
                }
5 T( }3 Z) T$ t" a. [9 v        }3 f! a4 A6 d+ m8 |* B
}( T* U6 m& V% ^  T+ |
7 P, A5 Y; I7 ^8 h* Y3 l
void        APU::Sync()
  C1 D9 H" I! X/ b% C* d" b{9 G+ M* ~' l$ I) i. _
}: {% p  ~# I( T- Q* s2 O
" ^( L! |# U( k1 x& Q7 u' I1 z
void        APU::SyncDPCM( INT cycles )
: _/ d1 I; W9 g6 X{; s+ r1 _4 y" u  V) M- c
        internal.Sync( cycles );+ q, T& X6 Q$ k9 b

1 q/ g0 Z& o' M. l        if( exsound_select & 0x04 ) {
6 C( o5 E( t6 @/ }                fds.Sync( cycles );( G  |2 L% _4 d
        }
/ X' }9 w2 E- j) R        if( exsound_select & 0x08 ) {
7 W/ Z9 a: q" g9 l$ |                mmc5.Sync( cycles );. q( `) v' s* L+ f2 N' j% V7 h
        }+ V/ D$ w% _9 u! u
}2 X5 W, a0 x% I4 `6 v0 b
$ S4 ]7 p" o" I- ~
void        APU::WriteProcess( WORD addr, BYTE data )
8 H9 \# W: e$ r9 }, j{5 m' R8 x( @! F
        // $4018偼VirtuaNES屌桳億乕僩3 b  N( j% s( G/ S, W
        if( addr >= 0x4000 && addr <= 0x401F ) {% G* n, {+ l0 L( X1 T9 K/ S
                internal.Write( addr, data );* J( d- V5 ~* X4 e  U( G
        }
- ~5 I$ Z" ^7 s. f  k3 j' p}
2 M& W, W3 O# M% T4 a0 `! Q/ v$ p% g' r( @
void        APU::WriteExProcess( WORD addr, BYTE data )" f' b& ^. C/ A9 `/ O
{
8 L1 b- F3 W" L7 h) s. b8 q5 m        if( exsound_select & 0x01 ) {% \& {" m5 n7 z3 i& ?
                vrc6.Write( addr, data );% R$ F1 x$ d9 h% l
        }: B4 ^2 M. `& F+ N- p5 C( w
        if( exsound_select & 0x02 ) {
# r( M, l0 k( H) ]+ i! J/ e8 F6 M. [                vrc7.Write( addr, data );
- p/ b" L( I6 @        }' C1 c3 V8 X9 [0 s
        if( exsound_select & 0x04 ) {! V6 v9 o: V# j1 s7 e6 J3 P  d0 _! @6 R
                fds.Write( addr, data );3 m/ ]4 |6 ]2 j- F9 y7 A
        }# z6 H' J" T& d: p' ~. y/ O2 a  r( k# A) y
        if( exsound_select & 0x08 ) {
' {  x$ z% o- D" N( g! E                mmc5.Write( addr, data );
% j8 ~0 G3 C  \& q        }4 |( R4 i) [# h
        if( exsound_select & 0x10 ) {) ^* r" S8 R& D) B5 M9 e
                if( addr == 0x0000 ) {: a- l$ V2 _3 _. y
                        BYTE        dummy = n106.Read( addr );
* b4 z2 C7 P1 R$ D7 _( q: D7 Y4 w& J" W                } else {, B3 Q# E- l6 c( Q
                        n106.Write( addr, data );+ F; G! ~. N' ^+ P6 C; l& D
                }- n4 A% d; S+ Q0 @
        }
* d: {8 M$ X" {8 ~+ [+ B' _7 K        if( exsound_select & 0x20 ) {$ L- z5 d8 i1 C& Y& g( q
                fme7.Write( addr, data );: ^4 K6 D+ s; }) g# H& M  e# i
        }$ D6 u' C0 y1 B; U) d4 K: e7 Y* L
}, a' F, t7 J. F1 D" W/ q& ~: j
4 V2 w7 F. M' T' f: X  N9 o
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )# b! p3 Z# d3 _  r; s6 J) Y
{2 P3 r5 l2 T6 s, i- D$ t$ x4 G' F
INT        nBits = Config.sound.nBits;7 g) m& C1 L8 p& T: e0 p+ F' G
DWORD        dwLength = dwSize / (nBits/8);2 S2 c# z- K( q6 i4 z# U
INT        output;
3 ^/ p( K# P/ b5 i' s1 I1 \QUEUEDATA q;
$ E& V6 v& X+ X( BDWORD        writetime;
! `3 \$ s5 [( i& {
: q' {# N: M4 Q. y9 C% r- i' `LPSHORT        pSoundBuf = m_SoundBuffer;
+ C6 T6 Q/ s5 Y! Y  M2 ~) d9 Z# SINT        nCcount = 0;* x4 H# n8 M( I7 S6 Z( n

2 M5 n+ q% ~9 O% ^0 `5 V2 G, oINT        nFilterType = Config.sound.nFilterType;
0 h! F, n0 T1 u# m6 G: _2 a8 f% T% o* C  @
        if( !Config.sound.bEnable ) {
3 [- y* ?0 [8 t3 \' O                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );* D. X0 [) @- U
                return;
  T+ l. [7 H0 t* D# K. G  m        }7 `6 J6 r% ~, u! i8 E
7 m: e/ K! ^; I/ C
        // Volume setup
) _3 i  R6 \$ a- ?) M        //  0:Master( c5 X) S; B. ?, P0 z
        //  1:Rectangle 14 x* y" T5 U. E
        //  2:Rectangle 2
" A/ v; s9 m7 v7 d        //  3:Triangle
1 V5 `9 P  P* ^7 q2 ~        //  4:Noise
' t, {& K1 n! |& b8 g/ C9 T        //  5:DPCM
9 O) Z3 g) W8 r        //  6:VRC6
: G' T8 X. S8 W) m        //  7:VRC7
9 ]# T! i! Q- f7 i1 G" G        //  8:FDS
. j! r' a- w( k' z1 _* O        //  9:MMC5" {! o. z* b5 d' v" a; ~
        // 10:N106
9 J; q% b5 \1 E" Q# `; L. D4 A        // 11:FME7
; ~, f' A4 `: y        INT        vol[24];
/ s7 J0 Z, F  E2 ^9 G/ J        BOOL*        bMute = m_bMute;6 I* R( e( i6 f) P0 E, j3 a7 y
        SHORT*        nVolume = Config.sound.nVolume;  `+ k% E4 A. p+ V1 }0 A2 g! v, S  z$ O

: `4 m* g/ n4 C( v$ I+ o! L        INT        nMasterVolume = bMute[0]?nVolume[0]:0;5 a0 k+ I# m) g: D

7 M2 r" V' r, [& |        // Internal
( t  T8 _+ K/ u9 e  }) y$ s7 |        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
( u. z, u' B) T. \' \        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
# ~& n/ P! i9 q, S        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;" ]3 `6 _0 ?+ O" t2 F4 L: B3 n$ P4 S
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;- N% D0 }4 w( F$ B5 G/ _) @
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
3 c) G( ]/ s6 d& R& d) n* c! B/ y; z' X- y1 h* Y0 @
        // VRC6% }5 |, K7 I- S9 B
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
  }8 I; _& C/ V8 v        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
, B" v. ~1 l5 j- E- S. e        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
& D0 u* a0 S4 t- i+ ~9 o% ~3 q! M" N! k
        // VRC7
; ?- }0 Y- o7 X1 p# x        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;7 g8 ~8 J, Q6 C9 A

/ x" Z- \1 t; Z) m- @4 R        // FDS* k  F" ~# Q' d6 o8 H6 r5 G
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;& ~+ o8 q- W9 ?8 j

; i) D7 r8 w, Y0 t! M/ [        // MMC5
1 b. Z. U& u. X0 W( _        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;7 g  ], r2 l9 c" i
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;3 U# b% T6 }/ O* m7 O, h( l
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;- \2 F3 E% _! m+ f/ E* @  r8 W0 V
- q: U. l3 D7 F/ F4 D
        // N106* _# [( R; _$ h+ S( I6 j3 ~) i
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ H2 B7 @% ~! J; r7 N/ P8 A7 a5 L
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;1 y' x& }4 @* }7 u- T
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
/ Y# I0 _: P  X+ }4 i- c9 g        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
2 Y3 [. v% }- j0 r& G' I3 B        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
# `6 O" ?2 `* o* W        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
/ B, o) {; [2 }5 I  b7 y1 b        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 _" u4 X  D! H% e
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;) F; o0 ^3 {/ N" I
) w, U6 c! U/ o7 u. W0 ^
        // FME7
' ]7 o! o% ^4 T9 S        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
$ o3 N6 K% y0 s2 r9 @        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
' i# X  j; e0 z. K( x# b0 X% M        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
* e! E1 E2 m( Z- @% o# @+ {2 y& e+ ?/ U( I! i) P
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;' n  |9 Z" V) N9 ?9 Z/ ^% `
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;* B1 k3 L0 R% Z/ g4 ^9 N9 F: X+ ?3 x7 j
0 Q! E0 o2 p. N4 f: T
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟* I+ {' d" L# D4 E) Z
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
3 I1 F+ G, I% f, M/ U( C  `                QueueFlush();
7 i, R; H* S+ g7 j        }
7 R" j6 ~& O. }$ a
* N& d1 k7 G' |) |- @/ y/ W        while( dwLength-- ) {0 F0 S. r$ Y$ L8 o
                writetime = (DWORD)elapsed_time;
" q6 Y# w/ b7 U8 o, \1 r5 U: I' G, z5 f- n/ A- `$ ~# J6 G; @% H
                while( GetQueue( writetime, q ) ) {
4 n" |% o6 _) S, |& q8 |                        WriteProcess( q.addr, q.data );3 J1 E. z/ y6 g2 o
                }9 G" u2 b$ L1 A

  d" q9 `: E. S' Q( n/ c- I                while( GetExQueue( writetime, q ) ) {$ h, P$ q( T9 x
                        WriteExProcess( q.addr, q.data );! p& D8 x- V. p9 u; ^! J
                }
& y9 a0 `# |2 M; L  ?
+ P6 T& f9 c  g9 O  w0 p  I                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
( g$ L" Q+ a# V" _5 [0 ?% X$ g                output = 0;  H: q1 b' B" g& F" N# X: Z
                output += internal.Process( 0 )*vol[0];
8 U2 V5 O) s; T) j                output += internal.Process( 1 )*vol[1];1 z/ F9 C0 f/ N1 m! ]/ T. F. ~
                output += internal.Process( 2 )*vol[2];
, g" P: n5 _# D# x5 H                output += internal.Process( 3 )*vol[3];( Q. y" q3 g4 R
                output += internal.Process( 4 )*vol[4];1 v: C# L6 |/ g- G6 j
  T9 k% A  h& X( F. c
                if( exsound_select & 0x01 ) {5 m/ d! z9 P9 H! @, h
                        output += vrc6.Process( 0 )*vol[5];6 X% O9 ]7 _% v, C( N0 o. F
                        output += vrc6.Process( 1 )*vol[6];8 ~, R( p# s% q4 ^
                        output += vrc6.Process( 2 )*vol[7];
% h+ f8 H' F5 q7 I$ z2 x  h) `$ }$ ]                }
  j+ L* s$ c4 f2 d" {                if( exsound_select & 0x02 ) {
  @4 u5 R8 l& ?3 R1 x                        output += vrc7.Process( 0 )*vol[8];
1 Y, I1 E8 K' J  U+ j                }% @9 t- l8 x4 f" t" s
                if( exsound_select & 0x04 ) {
" c' f, \; m+ X0 i1 W                        output += fds.Process( 0 )*vol[9];
: _8 `1 o5 d2 m8 ~                }
8 A  x" K; D1 m( }' b3 K                if( exsound_select & 0x08 ) {; L. c0 O+ J1 O
                        output += mmc5.Process( 0 )*vol[10];" M5 V9 b8 j6 r+ e, N9 |  j4 R
                        output += mmc5.Process( 1 )*vol[11];# F5 w" @3 C. @' F5 H6 W# W- M
                        output += mmc5.Process( 2 )*vol[12];& d) t0 i0 Q+ ?" }
                }9 D! J3 M7 D  }' D' e& Y
                if( exsound_select & 0x10 ) {0 d9 ?- F  e" C4 W" a3 I
                        output += n106.Process( 0 )*vol[13];
" x5 W  \, e, f) ~" Q2 p                        output += n106.Process( 1 )*vol[14];% O6 O$ z/ F7 _& {' Z+ {- t
                        output += n106.Process( 2 )*vol[15];
( r& z6 d& m" R/ }  @- G" c. Y" S                        output += n106.Process( 3 )*vol[16];$ E8 s# j- v. i: h
                        output += n106.Process( 4 )*vol[17];
) q9 B  ^6 |3 f; [3 J' {                        output += n106.Process( 5 )*vol[18];- S; @1 F) I' {/ d
                        output += n106.Process( 6 )*vol[19];# c9 r( ^& o; g
                        output += n106.Process( 7 )*vol[20];% q) ?' f: h# o8 M" q
                }- ^$ p& r/ ?5 s2 [8 e
                if( exsound_select & 0x20 ) {
5 f6 Z- W3 Q5 n9 ^5 ~  R' ]9 K                        fme7.Process( 3 );        // Envelope & Noise' \7 j6 j' Q' }8 B
                        output += fme7.Process( 0 )*vol[21];
4 y- `  u. a+ q- P. R- C' u                        output += fme7.Process( 1 )*vol[22];
) r6 A6 K- j/ ^# i                        output += fme7.Process( 2 )*vol[23];
+ b, k  e5 ^9 m                }( Y% Q/ G2 X+ m3 O

  g3 z  @& a% b7 Z                output >>= 8;) D0 T6 j3 R0 d9 b8 V- n
) w8 L( o1 |3 u. t- \
                if( nFilterType == 1 ) {* W( R) Z( ?$ S4 p
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
  |7 S: W* U. }; N5 [; \: Y                        output = (lowpass_filter[0]+output)/2;
/ f; ?$ s7 p. {! \1 ]                        lowpass_filter[0] = output;
- i6 [! R+ U/ {4 n                } else if( nFilterType == 2 ) {
- q5 w+ y: i/ M  a* f                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)5 Y; h1 S( x4 `& }( c  w0 L
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;  B/ P5 f( m! z1 k: T* [+ w
                        lowpass_filter[1] = lowpass_filter[0];
; [6 x/ c8 ^4 U" y3 v7 h                        lowpass_filter[0] = output;
. t# z/ u$ o4 Y3 {7 q                } else if( nFilterType == 3 ) {
3 c" P) ?' X8 z7 `                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2), O. z; `7 w+ }( ~0 |& \( d
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;0 L' Z; C3 \! s
                        lowpass_filter[2] = lowpass_filter[1];
) g+ ^: c$ F* M: I4 e! E                        lowpass_filter[1] = lowpass_filter[0];1 c" u$ X4 u& S( P) o! R6 ]$ M
                        lowpass_filter[0] = output;& I9 }, ?7 }7 b
                } else if( nFilterType == 4 ) {
, D- C) V, n; h                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)! b, `  s4 B1 R9 [' H, j
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
  V7 n5 o! i4 n) O; L# Z2 v( }                        lowpass_filter[1] = lowpass_filter[0];
, \: T+ z0 H1 X& F8 g$ N                        lowpass_filter[0] = output;; j% N; H# }  M0 T" o
                }
* v% v. d$ B3 h5 v- K
* Y7 d. o* h3 P4 [. M#if        05 N; v, j8 W2 w! y% y. K: |
                // DC惉暘偺僇僢僩
8 g: O: c" N- U                {
% T+ L0 V; a! k- b                static double ave = 0.0, max=0.0, min=0.0;
- v8 X% c$ x7 B                double delta;
) `3 \* t6 k2 f# e9 s3 N                delta = (max-min)/32768.0;% |* ^" e. Z% w& f
                max -= delta;
, W) W5 K1 \' G                min += delta;
$ H# p8 x/ V) v) \# O8 C- O                if( output > max ) max = output;
$ ?; t! ?9 K' y# R0 v  \3 F                if( output < min ) min = output;
' Z4 l9 S! b* v# x! a                ave -= ave/1024.0;$ B" m% e* X9 r6 b
                ave += (max+min)/2048.0;* f* L# b' h; y) N# N+ K0 b- u
                output -= (INT)ave;7 w% ?5 M7 S; }( Q( y
                }
- G, O7 y' v7 U4 s#endif# s4 @$ `! ~* @
#if        1
, L  K/ k# ]% @/ ]) v3 W- k                // DC惉暘偺僇僢僩(HPF TEST)5 W5 a* i+ A- A6 U, {1 E- r5 M
                {  q4 }0 z) d/ |. Y3 e; U, O
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);+ q" l1 Q& T5 e8 n% L: K0 T, {9 g
                static        double        cutofftemp = (2.0*3.141592653579*40.0);; c+ n3 a1 V: c# k
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
) @  x/ n) M! l" g) \                static        double        tmp = 0.0;
: ~( J$ L$ ^7 Q( A! m/ o                double        in, out;
0 [3 P9 D4 k) `
5 S5 M2 `1 M5 {% N2 D6 F                in = (double)output;
) N, f, z* \* R( B: H1 @5 v                out = (in - tmp);
4 u/ w" X) x0 W' j2 k                tmp = tmp + cutoff * out;) _" }; J& `6 e4 B

8 `2 K6 e; @  d: v/ D$ O- [                output = (INT)out;
9 U& s- \0 E7 X6 v                }; ?/ ?0 n3 T, f
#endif
6 m# \+ F0 r' {- g# [) E4 K#if        06 E' y6 x) z/ j2 _
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
: P# Q1 P! `# j# C+ Z$ [& N- t0 x                {
' n! Z3 d8 ]$ {4 T                INT        diff = abs(output-last_data);/ l  J  J% V/ f% o/ J- S
                if( diff > 0x4000 ) {
, E" B$ C# t& ^5 D+ c) j                        output /= 4;% u, S  {: Z7 {7 o1 r
                } else
! \4 R& o4 T$ E1 L0 f                if( diff > 0x3000 ) {: i- U  m" J- {0 O( |& V/ x# ^
                        output /= 3;
0 o% T- c4 ]  d" |1 K! g                } else$ w+ x! F$ h  @3 M% j. D
                if( diff > 0x2000 ) {. u* Y! J4 }. p0 r, j0 @' R& B( \
                        output /= 2;2 S$ m: A: u0 }5 J/ ]
                }
2 h* t7 v  n. l                last_data = output;
! i5 o5 a: r/ R" v" h$ a                }
1 @/ m" ~, S1 Q+ s' u#endif
; W7 B  O% b* r: W7 G* b0 }                // Limit3 H3 U) n+ T4 b/ {8 P4 P( j- f
                if( output > 0x7FFF ) {8 M3 t& K( C. G; ~/ P
                        output = 0x7FFF;
) }/ g0 m9 U" h0 u5 @( P                } else if( output < -0x8000 ) {
: z8 L0 y* W1 ]                        output = -0x8000;
, i. E3 _4 D6 z" s" a                }6 u8 T: m" ~( I+ }6 f# i
9 o$ ?6 `) {" \3 i9 b3 C% D' C
                if( nBits != 8 ) {
& S7 N9 p9 J& F/ D, _6 k- w8 J                        *(SHORT*)lpBuffer = (SHORT)output;
! P% M3 \+ m1 Y- ^6 f9 ^" G2 G7 U                        lpBuffer += sizeof(SHORT);
+ o: _1 ^+ w* G                } else {0 R4 m6 Q; F" i2 K
                        *lpBuffer++ = (output>>8)^0x80;+ e8 W- Y) I9 U  V4 d3 K, j& Z. m
                }
: N) e# L& ^4 n- t9 {& F: Y0 L. C8 C( Q; U9 f3 a" Q
                if( nCcount < 0x0100 )
  _$ n8 L; @! }- O                        pSoundBuf[nCcount++] = (SHORT)output;
' l6 `* X- d- Z
! P6 O6 z3 i. u7 E) ~- G  g0 b; K" R//                elapsedtime += cycle_rate;
* H6 q  p3 J7 m, N% `! b. j+ P2 r: Z. R                elapsed_time += cycle_rate;0 t7 B* `4 Z: P& s
        }
) R  v+ H" t; t2 ?% g( |% T; z# n  q! ]) ]2 [" Y
#if        1
* n- q2 D8 o2 ^  L9 ]/ }( v! s9 i: v8 I- j        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {6 q! G# z! [' C* z0 ~9 r: V
                elapsed_time = nes->cpu->GetTotalCycles();2 U1 T- U+ _5 y
        }
3 x* {" K$ l% Y. ?8 R        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
4 x6 L! m( Z6 [2 W0 ^                elapsed_time = nes->cpu->GetTotalCycles();
) e; f# J# Y/ j) h9 T        }
7 r! U1 T9 m2 }3 ~) E#else& P  j1 U4 ]$ n2 L/ M/ b* Q. x# H0 ~3 ~
        elapsed_time = nes->cpu->GetTotalCycles();
1 x& n* g. q; ^; t8 ^#endif
9 [1 }# f/ U0 X4 a}6 h7 w. P5 ]3 S- _6 B* `
" J8 P# K* M# R# n4 v
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
6 C" o" Z0 @2 V0 mINT        APU::GetChannelFrequency( INT no )7 P& `) w1 {/ |) P' _
{$ m9 c8 P3 X2 L1 M/ P& L8 q
        if( !m_bMute[0] )
0 O" F+ i4 E7 R) ^4 k                return        0;$ X& S7 D! C, p  P+ ?# j* q
2 \, L* t; u9 e6 u8 C
        // Internal
* E1 D( M/ S! Q6 ?$ Y        if( no < 5 ) {: x. S0 F8 D1 R
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
8 \3 u/ r% y" y. D        }
6 e; J0 F  n5 f+ X- e/ s/ f) X        // VRC6* T, I1 ~6 c  _. r0 V
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
/ ^& ]8 g8 X9 Z% T                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;! d' o# q6 @* @( Z5 ~
        }' e) y8 V, v3 ]5 x; b) I4 ?
        // FDS: ~8 s9 m1 z9 p2 F. k4 ?
        if( (exsound_select & 0x04) && no == 0x300 ) {/ {0 s2 S7 C' O
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
, ~% t9 W0 H9 h2 ]  R        }: d; X2 {& x$ K( o
        // MMC5
6 |4 ]) q% U* Z) _        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
- B5 A0 s$ R) ^4 `5 b+ O/ a# x! Q                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;1 m  P5 E& @8 P: G
        }8 s+ Z7 U  M' s- h0 t* U- S( @. O
        // N106
! y0 W; E. I9 N8 f; C4 b9 @        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {* }& l5 _, s9 Y) g
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;5 k( e# p1 b, w5 q) P0 v0 e
        }
5 ?, `8 f- \0 b5 V; [: @# S, u) z* O        // FME79 _8 g8 Z' P6 M+ m- O
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {& E7 P0 W/ I1 t) q$ R3 J
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;( v: a8 b1 }, j- Y( r- b8 L
        }
: z9 o- x% e5 t2 K+ i( q* c+ p) L9 _        // VRC7
& T2 x* B0 W& @3 G% O. ?$ d8 N- J        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {" x5 C# |; K7 [+ i: i( o% i# ]
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
) g0 {& B4 U' o  L' H        }
! `& Y- {# k7 T+ v( \        return        0;9 l* F& c, x9 l' i! \3 b# t, w
}6 }4 C: S1 ?- u/ q4 o( A

$ g. T7 v5 C$ x// State Save/Load  M  ^! k& u! {/ R( \7 x: k  J
void        APU::SaveState( LPBYTE p )
1 @7 q/ ~/ X* T& ?/ ?{# h  t4 T0 ?# T* }
#ifdef        _DEBUG  [! Y# E' ]% Q5 J) g
LPBYTE        pold = p;
& [! j; E, w0 P* ^#endif. z, v0 z5 ?- P5 }5 g

6 T& Y! |- Y  a        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞* E& s' L' }* S% G6 |) X: B
        QueueFlush();1 a  ?8 ^$ ?( i& R" d( |7 s

4 |1 b# R6 L' t) `        internal.SaveState( p );
6 v' b2 {4 w* v& x) ~  ]        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding2 Y5 y+ t  k4 u) z. }- d
1 V8 R: W8 {3 V! w+ H, X9 l+ c$ x
        // VRC6
( J0 D1 a; b" y        if( exsound_select & 0x01 ) {) y' r1 N+ b# }
                vrc6.SaveState( p );
; d1 u( ~; J/ ]) @2 e                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
# P! P3 P, R0 J        }
9 ^% r5 T7 G9 ~7 u1 ~        // VRC7 (not support)
* o' l, M8 z  b5 X  j0 h        if( exsound_select & 0x02 ) {) x1 ^: ^( V: R" O
                vrc7.SaveState( p );
8 D# J# r0 [  {                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding' d. n0 T* ]. o! n% ^
        }- u3 j* f3 B( q% d' ?
        // FDS' {- F. R7 ]: t* X2 h, `, v2 Q% V
        if( exsound_select & 0x04 ) {3 F3 y6 Q  U, P% `
                fds.SaveState( p );
8 }; _- v0 ?& L" t! `  [                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding7 J$ O( o1 [" e7 X
        }
  h5 @% @% z8 k9 V" a; k* t        // MMC5; D, }- L" F" d) a$ X( ]5 ]
        if( exsound_select & 0x08 ) {1 }! M" Q3 f0 `8 F5 a6 A
                mmc5.SaveState( p );
) u( M# [4 x  r                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
* H9 }0 Y5 f& s        }" v  Z6 K( v! Y4 @9 b+ `
        // N106
) t' _1 s& r! T0 l        if( exsound_select & 0x10 ) {
/ s& k  I' |! `# w7 s8 Q                n106.SaveState( p );
& w( g; `$ U9 t5 u9 E; A) H; T                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding7 B0 T1 Q2 b' K# A: a$ |
        }
5 v7 ]! E' O( g        // FME7
# m' `* t) L. A0 f$ I9 c        if( exsound_select & 0x20 ) {
4 @" ]% I5 z6 _4 c3 i                fme7.SaveState( p );
* ?1 Y) N% c, N% J6 {2 m% f7 m( D7 L" t                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding4 x: |) k# K$ a
        }
, t! Y3 b8 K' X3 p# v" r
' p1 k* d6 R1 K1 `: t9 r#ifdef        _DEBUG# J1 j0 i0 _( B# z# d
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
' P3 U* e; ^8 a#endif$ v  L1 q1 N! T+ G3 ?4 b
}
/ ^. n, F, \: O: M1 M
6 u6 v: d. b+ d; @5 u% I2 Lvoid        APU::LoadState( LPBYTE p )
  O* J8 r. M" u! g{
( e! m2 \. ?8 B        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
) C- Q# U# `6 g- x9 m        QueueClear();
8 u) L$ s% P" k, z4 r6 m# \5 p' E, K" x
        internal.LoadState( p );5 T1 B0 F3 Q: }$ Q
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
' {8 X9 r% t, A% l: I/ _/ D! i
" ^  D* Q& a: z1 }  b4 P" e' f2 G        // VRC66 c1 v/ w& M" e$ {5 g2 W5 ]
        if( exsound_select & 0x01 ) {
  E8 f& M- e! b  H2 Z/ Y2 e  ?                vrc6.LoadState( p );
5 {$ \- P8 H- }; w4 q* W$ p                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding3 o9 Z% _& Z3 v
        }
& K- y& |$ d4 V" j$ O. A        // VRC7 (not support)
& S1 I/ o3 B7 ]        if( exsound_select & 0x02 ) {" g+ T0 z& p" W# D  N1 i1 [! d4 z
                vrc7.LoadState( p );
$ k8 J' _# h" Y; R                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
2 Z+ j/ k- ?  _5 ^        }
  |1 F5 I. E" D& [        // FDS6 V9 P- u- ~7 q3 D, `5 b) }/ }; i
        if( exsound_select & 0x04 ) {
, g# J& N( t) x+ w                fds.LoadState( p );
* v! T  v( I3 X# H                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding; b5 `+ Y6 `3 P$ r
        }
: C+ H8 M+ j+ \- b6 Z2 B        // MMC5, s# |2 v5 [6 D/ F8 k  ~, b% X0 U
        if( exsound_select & 0x08 ) {4 A) @+ h  S+ ]1 ]) h" U# H9 k
                mmc5.LoadState( p );
  Q- ?* r# ~! j: e% u' Q/ B' d                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
' f2 B  c: @. r3 g        }% r7 r' i. R, H; d8 ?' E' W+ [
        // N106* M, Q1 P% Y9 `7 M1 a. U$ T+ }0 c- C* n
        if( exsound_select & 0x10 ) {3 _  w2 ~; y% |: F: B
                n106.LoadState( p );7 {4 Z4 [4 n. J+ T; U
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
1 o7 B% R4 R( L5 x# H8 U        }
( D" B5 S5 d& Z, }2 f6 M        // FME7
0 L- h# e/ u1 x0 B. L# A: \        if( exsound_select & 0x20 ) {. R$ d3 s% i3 `3 G+ N
                fme7.LoadState( p );
0 V% M& a& Y+ l! U" e                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding/ X* Z- ]& |! }9 A
        }
3 p" }. C3 U3 W8 F  ^}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 ) w: ~5 ?. l( E& f: p. c
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。- w: ?1 C+ ~4 t2 |: _* B
感激不尽~~

; j; J2 B  ^$ v3 K% [0 ~2 m7 y, R恩 我對模擬器不是很有研究,
/ e  v+ J7 \- u% |雖然要了解源碼內容,可能不是很困難,! I/ z: I; Z% j8 k" ]
不過還是要花時間,個人目前蠻忙碌的。( E& B6 }  k, C

. c& }. ^$ ~6 `3 s7 l$ l0 {給你一個朋友的MSN,你可以跟他討論看看,
1 Q7 Q3 l. C* L. k: o他本身是程式設計師,也對FC模擬器很有興趣。# y8 w0 J+ C9 d! m+ \/ T2 B4 e6 D: l. Y

2 e6 \3 t5 z) ]' L3 O0 G0 O$ FMSN我就PM到你的信箱了。1 I( ~, @6 u& R2 |

2 o: v# z. G  l1 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 发表
0 ]( s) u+ J) n* a% n! V2 \& P呵…… 谢过团长大人~~

- J" b7 Q6 h  B& e0 l: e( {& T7 _, y! d' v+ l8 O
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 % ?* P& L- e4 I0 B0 P& w8 e' O
团长的朋友都是神,那团长就是神的boss。

, z5 V+ l  H' ^3 `: y哈 不敢當,我只是個平凡人,
/ ^" X. z. T! D! F' W4 ~要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙9 B& m1 B. K! X+ w+ D) A
ZYH
4 b$ [1 K6 G# oQQ:414734306
  Z3 h$ Y( C2 D1 MMail:zyh-01@126.com
0 h6 h5 J+ s0 t5 o! e; }( l' N4 l
' M: v# Z8 e; U/ b他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 / Q7 k) S+ s4 e" K
再次对团长大人和悠悠哥的无私帮助表示感谢~~
7 Q* {1 C7 P) |7 y* ~
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-2-2 07:41 , Processed in 1.102539 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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