EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。0 L1 [' K+ i) b7 X
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
' O7 j0 V" }- _这里有相应的模拟器源码,就当送给大侠了~~
' Z4 c5 \  T( b! F3 N5 Shttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 & [% h. \9 S# o2 i
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。) o& T9 u" S& r3 h/ ?7 `
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
7 M" J4 H+ Z- Z! D+ [0 m这里有相应的模拟器源码,就当送给大侠 ...
4 Y1 _: p6 [$ s1 q4 Y! i3 F9 s  d
聲音部分(Audoi Process Unit = APU):% s5 f) c. k- |& C8 R
.\NES\APU.cpp/ p- C# |  P; X- L$ W5 A2 C. d1 T4 C
.\NES\APU.h& e5 }4 h% z$ Z3 C' @

6 J$ U" s% e3 V& N
* C1 B7 g* q. Q5 \: @影像處理部份(Picture Processing Unit = PPU):# \5 l7 r6 Q9 L2 M1 T/ ~( _
.\NES\PPU.cpp
0 E3 X# c$ I2 M! t* m8 K/ p.\NES\PPU.h
+ o7 D# O7 u/ P. T7 e
8 r9 g- Q/ [4 D( A如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
* J1 C$ |) _0 i& G" W: |7 ?(由于很多专用术语和算法机理都不明白,所以看不大懂……)+ X: _1 G; l/ I) g) I
//////////////////////////////////////////////////////////////////////////
- s2 Q2 v! g: ]) {//                                                                      //6 W  C; P( t* y! u0 f3 [( r7 Z
//      NES APU core                                                    /// O9 z4 X8 `1 C( n- I  U- {* [! q
//                                                           Norix      //
1 P. a8 r+ s" ~2 \# ]  Y3 U& Z//                                               written     2002/06/27 //
) {" X& ]9 M; d% s//                                               last modify ----/--/-- //
) w6 H9 z3 X) g7 S8 ^) F/////////////////////////////////////////////////////////////////////////// d: M" I' u3 q( Z' p* R9 I
#include "DebugOut.h"/ _( J6 t: }; ~+ A5 e  G9 `2 [2 j
#include "App.h"* N9 I+ S/ J- @% v  b
#include "Config.h"  ~$ r- S/ x+ r: h7 n7 W/ R% ^
# a( W4 g6 k5 F0 P
#include "nes.h"
6 y  `9 X2 N+ c% C+ o# l) _#include "mmu.h"0 R5 q( c2 @+ h* ]) L
#include "cpu.h"; q, o+ L* u* D0 x
#include "ppu.h"
5 P& I) o/ q# ]$ D#include "rom.h"7 v$ @% o, g6 N& N' X- B
#include "apu.h". v9 A+ W% n5 B) O" ?+ t! n
; _; {; D8 @* u5 J! Z
// Volume adjust
  O9 {% `, r  ^// Internal sounds" h+ n& G$ J. Y! w' q7 }
#define        RECTANGLE_VOL        (0x0F0)
( u" F4 [8 m2 e; d% Z6 q#define        TRIANGLE_VOL        (0x130)1 v, z& t" T5 `7 v+ _" i
#define        NOISE_VOL        (0x0C0)
- q* Q3 u$ C" v#define        DPCM_VOL        (0x0F0)
- f7 l: a8 m; I0 n6 m// Extra sounds" {3 }3 f: l) c
#define        VRC6_VOL        (0x0F0)
; q  t8 w* Y- ^0 s4 u1 ]#define        VRC7_VOL        (0x130)
  l- w1 F! M$ Y3 B4 f#define        FDS_VOL                (0x0F0)9 Y3 z2 [) M8 Y6 ^- M( Z2 T+ N8 U% D
#define        MMC5_VOL        (0x0F0)
. E6 N1 ]& H7 K" d& z#define        N106_VOL        (0x088)
; p( H8 b; S- p5 B7 {#define        FME7_VOL        (0x130)
( `, i+ m7 {4 ?) B8 A, N
' g7 k& r/ ]& k7 W, _APU::APU( NES* parent )
5 y4 n" i) N! x{1 c5 c" ~# g0 |+ t$ u5 ^4 M
        exsound_select = 0;8 w" e, p# g7 a; \$ H& n8 h

) R! W5 D2 e: F6 o; q4 c: a        nes = parent;0 y1 U" M3 A! [' U
        internal.SetParent( parent );
0 I  ~  e: F8 F8 q; M; ?1 P$ J6 o: q: A% g, w/ d) l
        last_data = last_diff = 0;
1 G5 ~, m8 i0 A5 T* Z( x* x: f% Z$ k7 z* r
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
6 ~+ ~. r0 Q& K5 ?8 E5 H# J, h( h- `% r5 I1 u8 H
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
8 \3 |: e5 l9 ?9 l; e4 s        ZEROMEMORY( &queue, sizeof(queue) );; z2 }5 ^; C% a9 L) v. K2 m
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
8 @0 e* [& d7 i  [& |3 m: _
$ \3 |4 P  A+ d8 R9 N        for( INT i = 0; i < 16; i++ ) {9 q6 H8 m* ?( m: g, s) j0 c
                m_bMute = TRUE;" @) E7 D% K: \1 N) r1 `
        }9 a' n/ t/ O5 R* |, ^
}/ ]% \3 G9 a! g! M# o! b

) ~, v5 V; f) T% |# ]8 oAPU::~APU(): {$ `( E0 F0 J* D
{
, g+ I9 e9 L; h. v1 t}2 ?6 F8 u, d+ T6 K3 S! m) X8 o
2 Z7 y$ F, j( J5 R) a
void        APU::SetQueue( INT writetime, WORD addr, BYTE data ): n; f$ v" _! Y- n2 m3 E
{4 z6 M# U. o3 Y& i. W
        queue.data[queue.wrptr].time = writetime;8 T  d) s1 E* E
        queue.data[queue.wrptr].addr = addr;& ?4 L3 h+ E# v4 R2 A8 _
        queue.data[queue.wrptr].data = data;5 s2 z) x4 A& K( F
        queue.wrptr++;
& N# d: P( c% D        queue.wrptr&=QUEUE_LENGTH-1;
/ u9 P: Q  @5 t$ y7 S! ^2 x        if( queue.wrptr == queue.rdptr ) {
; Z" i6 G7 k* ]                DEBUGOUT( "queue overflow.\n" );
: N0 P3 G% Z: Y        }2 r1 z0 R8 h: ?
}% Q: i# g2 W( f' ~
* f% `/ a) U7 h/ @# E& K
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )2 o& L$ b* s( t) f* B8 S4 ^( ?' c
{) \0 U; z2 a0 y' p) z  F
        if( queue.wrptr == queue.rdptr ) {
: c9 H0 Z8 s. N* N7 M$ g; m                return        FALSE;+ q$ ?. x% J; `& j* l
        }8 f( Q, `3 |; O. H2 T3 u
        if( queue.data[queue.rdptr].time <= writetime ) {
9 F- c" W% s$ n1 A                ret = queue.data[queue.rdptr];
, P+ W* |/ T7 f4 J8 K                queue.rdptr++;
4 W. n- \! q0 T/ W6 Q0 N                queue.rdptr&=QUEUE_LENGTH-1;
" `* h) \! \' b% l) P" }" r                return        TRUE;+ o; K" n$ k9 e9 i* R$ D: x2 u, h1 b
        }6 O1 Z, v  I* Q8 S9 I+ k
        return        FALSE;8 Y( n8 a( U, R9 ?( G+ ]
}  K  _# E$ B3 }# N0 `- X$ b
+ x0 H/ q) k0 c) D
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data ), C3 M" G% j) g; n. ]+ F( |1 K
{
5 |2 ^2 Y8 g4 p8 a        exqueue.data[exqueue.wrptr].time = writetime;
; `. R' s* ]2 L$ C! _) [3 X. T+ U        exqueue.data[exqueue.wrptr].addr = addr;7 ^4 ]8 m/ L: ^2 |# a% l
        exqueue.data[exqueue.wrptr].data = data;
& y+ d* A- I7 d& h* S8 q        exqueue.wrptr++;
( a- G% F& x0 ~. c        exqueue.wrptr&=QUEUE_LENGTH-1;
: J: G8 F' Z: o1 F  Z$ E3 g        if( exqueue.wrptr == exqueue.rdptr ) {
. f6 `3 g) Y5 r4 Z1 y# j. `- ~                DEBUGOUT( "exqueue overflow.\n" );
/ _! P# J$ G5 z, f        }
9 _' m% E9 p1 V6 V}
% Z) l3 l( C, x8 {- i" y3 l8 O0 m9 H" K! R/ P* x8 Z6 S
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
. F  r" I3 ]/ W' \. Z4 v' h{- \8 Y7 E; u: H  n1 y5 W
        if( exqueue.wrptr == exqueue.rdptr ) {8 h9 b# f) F, H3 f4 ~% O$ T+ L
                return        FALSE;5 A8 y; O: {6 ^# G; d: Z! H7 V6 ~
        }# F" F" A  A- F! K+ ]& F: @
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
) L1 M: O  t, V! Q& G                ret = exqueue.data[exqueue.rdptr];
8 O/ m5 Z" T) I                exqueue.rdptr++;4 Q; j! j6 O5 [. \$ m4 N% ?
                exqueue.rdptr&=QUEUE_LENGTH-1;
2 j9 J8 v! O+ d6 T& o+ B                return        TRUE;
2 z' _. K2 I0 _        }
) Y) |9 F$ }) U! A4 G6 ~        return        FALSE;- w# N* b: ~! M" `; o; K& J
}) X! C  \$ W; t9 {: c5 D
: W; V! H0 C8 V( P' l5 Y9 K$ r% b
void        APU::QueueClear()
- h: V2 Q. B) [: g+ F% p1 x  _{
% M: M, p# }1 U        ZEROMEMORY( &queue, sizeof(queue) );/ \) w) z; r0 K) C) v# @
        ZEROMEMORY( &exqueue, sizeof(exqueue) );& q8 F; y' P: G
}- Q( y9 x; Z/ f0 H0 D

2 |" W% T9 e; qvoid        APU::QueueFlush()
/ D" m( N( @$ Z{
: J! X" B& y4 a' V: V5 p8 }. Z+ o4 K) W        while( queue.wrptr != queue.rdptr ) {
" C' ^% i' j# N5 V  j) Q                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
( a/ M: h- V# F, U5 I4 j# A) U                queue.rdptr++;, A) O8 H+ c: M( E
                queue.rdptr&=QUEUE_LENGTH-1;9 A5 M( N9 z+ D; |4 p
        }
) y3 Q. Z) s* T' Q7 p( W; j5 t' s$ Y" H
        while( exqueue.wrptr != exqueue.rdptr ) {/ }* x% I. M* |5 x1 G; b
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );- N: e: [1 i' a8 A
                exqueue.rdptr++;" D' p1 q* t" P; e6 t: Y2 V9 \
                exqueue.rdptr&=QUEUE_LENGTH-1;1 i2 B1 I( n. ^* ^" b% U
        }; j6 K; G/ e6 {3 Y. b
}
4 U! Y* f- x5 `' @0 A- R% A5 ^/ Y! V+ q! q) r
void        APU::SoundSetup()9 N& S$ S, V/ @6 E  A, U( h* H5 V
{7 |' U$ }3 G0 K/ B+ [& {5 k" c
        FLOAT        fClock = nes->nescfg->CpuClock;8 t3 I' p: ~. W1 \
        INT        nRate = (INT)Config.sound.nRate;
& E& e- Z* i& ~# I0 x3 I% R        internal.Setup( fClock, nRate );
1 J# A3 O, C" Q% X( T        vrc6.Setup( fClock, nRate );
! j5 Q% z5 I8 _6 d        vrc7.Setup( fClock, nRate );$ I+ S$ D6 h' z, m& w7 Z- L( k
        mmc5.Setup( fClock, nRate );$ `" }  |5 U. a! o' |$ y! |
        fds.Setup ( fClock, nRate );; ~+ ~3 h+ A, P6 m
        n106.Setup( fClock, nRate );8 A2 O8 C" O) j6 y' _4 ^2 G* C; X
        fme7.Setup( fClock, nRate );
) t: z( F3 F$ g% m' W}$ F& n6 u5 R, ?9 ~$ }6 ?" C

: p7 F. \1 F1 x# f( fvoid        APU::Reset()/ B5 c5 d% v( x6 R4 }
{( K6 x6 m2 H: M+ w
        ZEROMEMORY( &queue, sizeof(queue) );. ?& L+ F/ i" K3 k" M
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
1 S. |9 S6 M" h; \9 |
3 t2 _7 d3 f1 Q( C1 g- {3 q        elapsed_time = 0;6 \4 v; v: p$ `: P7 z( a  a% V
3 Z1 _4 @4 v( v& l. L$ A5 o( l7 B
        FLOAT        fClock = nes->nescfg->CpuClock;5 {  S. T6 Y# _% p2 w" x
        INT        nRate = (INT)Config.sound.nRate;
, [, c# z6 D0 t. U$ X6 x: A        internal.Reset( fClock, nRate );0 B6 E& u* ~% A: \9 g
        vrc6.Reset( fClock, nRate );
4 h1 l% f  }9 E( K        vrc7.Reset( fClock, nRate );
5 k. Y! G4 K( A7 m& E        mmc5.Reset( fClock, nRate );
4 p3 W  B. p- x/ B( D1 k6 e. M        fds.Reset ( fClock, nRate );7 a5 J) m& b0 t* D9 \
        n106.Reset( fClock, nRate );4 b8 f3 P# b5 T, q0 Q% Z5 r7 y6 T
        fme7.Reset( fClock, nRate );# @1 ~* i1 l# L) {/ ^! j9 i& I* Z
& [) R4 T5 ~- n) ^+ z! r) C
        SoundSetup();
! f' C4 j9 m3 h" S- a9 W* r! \& G}
0 H/ I4 K% ?1 |, x
" h7 [0 I& Z7 h# Q5 q0 K# Kvoid        APU::SelectExSound( BYTE data )3 m# f( ]( F, E) @' z7 H/ v- e
{
8 `9 V4 `$ L3 z  M6 ^1 a8 }8 W        exsound_select = data;
; \8 L) X7 f% }+ Q}, S4 r+ N1 a: ^% c- Y7 ^
! \6 o! F2 m: Q8 g* Z. j
BYTE        APU::Read( WORD addr )
6 H9 A% A/ }4 G& A$ O3 Q{2 F2 u& u) r) R- ?  ?
        return        internal.SyncRead( addr );
. E5 u7 u8 E6 E" X}2 j8 O) H+ \; G

# M/ c; R% u* p# ]0 Nvoid        APU::Write( WORD addr, BYTE data )0 P7 ?" Y! Z3 e+ a
{
4 B( L  z2 y2 L2 `# p" a- {7 Q        // $4018偼VirtuaNES屌桳億乕僩
9 R& Q/ ]$ |. R        if( addr >= 0x4000 && addr <= 0x401F ) {' ~' U, _6 \3 h. {: C% B/ `
                internal.SyncWrite( addr, data );5 C& h/ P$ N7 u; v+ R! \/ R* A
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );! i# Y; u. b7 ?6 n' k
        }5 O; z% R( F" d2 o  Z' V$ N7 ]
}$ l; `6 N4 U2 \9 z! @/ \  }, J; ~

. L" ?* |3 x, a% ]BYTE        APU::ExRead( WORD addr ); V5 {& M  H: B5 W9 o2 |* n  |! w
{; ^) q* K+ t' F0 `
BYTE        data = 0;+ V& [6 t0 V4 |* I# f

) F" O& j) K. `4 ?        if( exsound_select & 0x10 ) {
5 g) h+ \; F2 q4 r6 f- P1 H" i7 [                if( addr == 0x4800 ) {& O4 h% r7 U6 Z, q8 G0 ~
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );1 {  F! b4 z. A  z( r9 c
                }
+ r% ^5 @0 C- E/ O7 @9 W9 X        }
* G2 X0 b. V+ ~7 U; H5 H        if( exsound_select & 0x04 ) {
5 T; A2 e8 s7 }% X+ u                if( addr >= 0x4040 && addr < 0x4100 ) {
2 j: ?- A0 o7 B. R# ~5 C7 i5 b                        data = fds.SyncRead( addr );
- q5 {6 l" r& E+ T7 X. k3 f                }: {' V. y  M! a$ `* Z/ ]7 e( r
        }
# ]/ w, x4 q! T3 Y" @6 M+ H        if( exsound_select & 0x08 ) {/ ~+ L: X  q9 D
                if( addr >= 0x5000 && addr <= 0x5015 ) {' `+ B+ D4 I5 G8 R# q! H4 m3 F. u
                        data = mmc5.SyncRead( addr );
0 \- a3 i4 S) p: P; L8 ^                }
8 {* q* f1 j  [2 m% V! x5 j        }
9 L# r( f2 Q, d0 `" W4 y& p! Q& H# `
        return        data;& p# d- m9 m% \: x% i5 Q; b# M
}8 w9 e3 M; J8 A- p
3 a- Q, Q% f& f6 T$ l+ P4 o% i
void        APU::ExWrite( WORD addr, BYTE data )
. x. j) _$ M, g9 Q! ?0 }: [& Y7 o4 i{
% b. ~8 ]# m- A( ~# x; ~! D1 e" ~1 J        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
5 G8 ~1 O# S- O3 B! k9 _" `" n: g' k9 J8 M/ y  g, n' u
        if( exsound_select & 0x04 ) {
: \, ?4 H+ V) ^1 f                if( addr >= 0x4040 && addr < 0x4100 ) {% F( J8 K' t: Z( Z" [5 m  d/ U- z
                        fds.SyncWrite( addr, data );: x! M) ]2 [% @$ c! L8 ^' J3 k
                }) Y. t  U. B3 E$ b9 H2 t
        }$ b) J0 f/ z$ j# s* k
: m9 B8 j1 U. z  c/ h
        if( exsound_select & 0x08 ) {
6 j  V3 f4 u4 W. D$ g/ H/ A                if( addr >= 0x5000 && addr <= 0x5015 ) {- d1 n! r% z& {. d0 e9 o7 v
                        mmc5.SyncWrite( addr, data );7 H3 C- P4 y! @1 y
                }
% Q4 L# p" s2 o% e        }
7 p0 M8 k$ ?+ b" k8 m1 k/ n4 p}
! b! z; g8 L5 A9 F6 h
! k' x! h6 Y& G; X! \8 x9 pvoid        APU::Sync()
( x: x1 ^' W; F) Y2 f9 o* k: p1 s( z{
  y) E+ Q: `1 I8 Q6 d& L( v4 ]}
1 C9 B" k& x2 Z% T
) t6 K( g' E' k& Rvoid        APU::SyncDPCM( INT cycles )9 q8 d/ [0 N2 x/ n3 k: T% p0 C0 N
{
2 z' r7 {% X5 r" F- f9 S% P        internal.Sync( cycles );
8 O, R6 R  t! s
+ e* p. C( {+ V' U* ^- M( ^/ a7 O0 H) X        if( exsound_select & 0x04 ) {
4 o! F- }% r4 n3 i0 e; m                fds.Sync( cycles );
# D( ^1 M' Q& l6 B        }
) o8 n* q" d2 |+ V3 v5 q: ~- d3 V        if( exsound_select & 0x08 ) {8 a6 R; z% }+ S1 B* u3 y
                mmc5.Sync( cycles );
" ~% i0 H8 @9 t" U6 x7 Y        }6 F; m9 s/ c( y
}, Y/ \) A0 c0 N7 z) a! [3 L0 }
6 D  c- \2 ^' X  s/ M9 _
void        APU::WriteProcess( WORD addr, BYTE data )
& d5 m- Z! L& d7 u. ?, p* e% w{' S( F3 Y, w. `- W( B
        // $4018偼VirtuaNES屌桳億乕僩
. i, x' @% N; X/ @( C$ A$ x        if( addr >= 0x4000 && addr <= 0x401F ) {4 l7 Z& [6 z/ }3 A
                internal.Write( addr, data );
: u% t$ y' D# U" E0 h. e        }
! ~. g* `. y* o* `. {, s}/ y3 Z+ Y9 J" x

9 @; S9 s, O! r4 i% E  d+ @/ jvoid        APU::WriteExProcess( WORD addr, BYTE data )
% R3 L9 c/ D- _, R& _{
. e6 a! Q0 c. M6 L% f' p        if( exsound_select & 0x01 ) {' P+ U: f5 z. [- A4 Q
                vrc6.Write( addr, data );1 b$ H  r- ^( T% P. z
        }" t0 i! `# G+ b9 h) h! S  k- h8 O  m
        if( exsound_select & 0x02 ) {3 n' L2 i/ w" p! r7 O& I# o9 d
                vrc7.Write( addr, data );, C: X9 |! d# I1 X6 O
        }( o8 ]; X9 h% T' n. H: y$ L
        if( exsound_select & 0x04 ) {
" V. C; L8 S/ y7 E: h# n* \. l                fds.Write( addr, data );0 q' |2 @& y+ E- O2 M
        }) N- p/ V" h# O/ y
        if( exsound_select & 0x08 ) {
$ ^$ f9 V/ Z( X9 {                mmc5.Write( addr, data );
; V' X/ m9 @+ D- @; x        }
+ e9 x4 D3 M/ }8 q  I* @        if( exsound_select & 0x10 ) {
7 K8 {& b# O- j5 [) W% I1 P                if( addr == 0x0000 ) {
, f  N. l/ D) X. E                        BYTE        dummy = n106.Read( addr );
6 C. x  e2 r7 i' z0 V* ^/ A                } else {) C) d( b5 P1 }+ F
                        n106.Write( addr, data );
6 c3 `" H' Y6 N  O                }, z" |* @; Z) t$ a! B- A
        }
* {% ~5 t5 v% J. W; f, g$ x        if( exsound_select & 0x20 ) {! @$ f$ i6 \9 [( F
                fme7.Write( addr, data );& E5 V( P9 M, M' q* B' G! O( `
        }+ ~5 B6 M+ S$ G$ ]3 y7 I! R
}
, F9 a9 Y. L! t$ S7 R/ u. w
, k6 v3 J4 W5 S0 ~void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
1 L0 C5 A8 O. h  ]{
, {6 ^2 q/ N- z6 K# ?. {INT        nBits = Config.sound.nBits;
  L  y9 R' J7 }7 X! {DWORD        dwLength = dwSize / (nBits/8);. s0 n  }7 C$ b! C- s6 o
INT        output;1 j$ Y+ |9 q4 T* \# G$ ]
QUEUEDATA q;- U0 g# v9 S; C7 _
DWORD        writetime;
* q' X  R! i/ i6 l7 @* A! Z# u4 ~. Z" s# ?  H$ t+ }
LPSHORT        pSoundBuf = m_SoundBuffer;$ w$ Q7 T* X& s) }& i9 \, m( u" w
INT        nCcount = 0;4 u" L% i6 Y4 Y0 `$ r5 d' A. _
) \$ J5 Y) l7 F* [
INT        nFilterType = Config.sound.nFilterType;1 Y$ U. O( p$ l2 l
2 Z; i  w' R1 }3 U+ R. B7 r
        if( !Config.sound.bEnable ) {
  c, t- n4 b; i* O. A                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
" H! y# g& \( w                return;2 z( e) X* j* ~- m0 o
        }# n. r3 v8 t3 w

8 G+ o1 p: C# v. _$ L" \. [; @6 ]! p        // Volume setup
* v* o) k, B) r1 y9 o" C        //  0:Master
) n: M* E% z1 p7 i2 j/ T# c        //  1:Rectangle 1
& F6 u' ~) A$ N* r        //  2:Rectangle 2
% K1 d7 f% [8 K% i! F) Q        //  3:Triangle
: E  l# g# d6 ?! W) Z+ @2 h        //  4:Noise
  |; k/ a. e' _; E- `1 ^        //  5:DPCM
- ~8 @% F& k1 G3 I- G/ M! X        //  6:VRC6
  j4 W1 `, D  W. I) Y# y- K& I        //  7:VRC7
* Z! \! Y3 r6 C9 |        //  8:FDS. |2 l1 s9 v& s+ q' i
        //  9:MMC5# [7 y$ O3 t$ }! O1 D. D  e
        // 10:N1069 f* g$ P2 x% u: P2 i1 K4 }# J6 q+ s
        // 11:FME7( f( C; ~. t) O8 Y5 @' ~( y2 f: Q" X
        INT        vol[24];
6 n4 g9 g2 t, n3 J: d        BOOL*        bMute = m_bMute;0 ?' V+ Y6 W, {. L7 s5 F9 \; j, @
        SHORT*        nVolume = Config.sound.nVolume;2 |, z) Q1 t8 X. R: F

& r' `/ s' I% X2 e# l- G- ~2 r        INT        nMasterVolume = bMute[0]?nVolume[0]:0;$ L8 ?0 Z! e+ e# R  P0 V% g
4 f& a+ G- k' T6 O8 {5 C; b8 N( u
        // Internal+ \0 O$ R, e; |6 [& Z2 `6 N
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;: n# b  ?4 m' w( z6 q
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;4 r  A2 `( y- Y; B( p
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
, a- M2 U! H7 `        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;1 n1 j" I- R" P5 v' G' j4 v& @
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;2 \9 x8 n+ y4 A1 z- e& j2 t

3 r* i8 ?  Z# Z/ b3 Q( S        // VRC66 U$ H0 y# I# C- Q! \% Q
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
- C' E% g5 a3 S; c: y" A        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
4 ~/ r; a* U8 B7 y$ [& v        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
/ B( ^" i  H: {/ `* r% b0 Z3 S" U1 H5 r$ d' c
        // VRC7
! v" m: V* A- k8 n$ A* Z8 ?        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
5 O5 J4 w/ K, u0 n+ B  t. S
; O0 [4 u7 b) @        // FDS
% ~/ u: c. Y6 L7 O. \        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;( e: W2 V  C4 K6 c9 {  ]7 U

7 f, l: Z2 ^; l. }* y" _        // MMC50 R* n: P& G* {: I8 _' c* i$ M
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;  I  [- X" l% r! i$ `  I" `. y
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
4 T. [' k9 P; s( j" [6 h, ]        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
7 p; E  i$ b  B$ b9 |6 p
% p  M) S3 f) \, t        // N106( C; O' `/ f9 _+ X
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 }8 ?; V# w6 g: v/ W
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 a9 V% D( c! G5 Q; q9 u
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& z2 A9 V1 V5 `3 X, [        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ S$ N) C; e! Z; C2 }
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 x0 Z( @  j  V3 C        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ J! @7 l$ i- R/ M0 v9 ?        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;. O# b; H2 Y4 P- t; Y6 ?% G6 V
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' y  I0 i2 B9 }

4 T1 G7 V" ]2 X: [8 f8 I        // FME7* f% r+ c9 G4 y; ^9 P
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
! m. N* B$ ]- i( I        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;7 g/ X; |9 U: t8 {$ a8 W8 H% b
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
2 p( a4 D9 h( G. f, L+ J6 @9 a! C  U9 j
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
2 p$ S$ }3 A1 z: ]1 c. o. M        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
5 e4 y0 [4 |; V5 b4 D
/ N8 S4 k" b7 y7 U6 U        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
  r7 Z/ ^& v9 s, l, K8 u        if( elapsed_time > nes->cpu->GetTotalCycles() ) {- k' i9 R7 t$ V+ ]$ o& O- n+ W
                QueueFlush();
* _5 D( z1 ^1 S. X        }
$ T; g4 Z/ H3 u" F5 d2 @. F5 F5 m
2 v3 i/ ]4 K3 G0 k- t        while( dwLength-- ) {! p# \. ~. k% [& d+ C4 z
                writetime = (DWORD)elapsed_time;
0 @6 `  v+ \1 I7 V( M' x7 K0 V
6 s4 e3 f. `1 D4 w! y* c/ s                while( GetQueue( writetime, q ) ) {3 I6 r- r' g  L4 @
                        WriteProcess( q.addr, q.data );
1 M2 f* j! [( p9 E( h* C: {                }* N0 `& z6 K+ t, ~4 P6 ~& ~

+ D  M" p" m" ?# M/ D                while( GetExQueue( writetime, q ) ) {" I5 ^* c! D/ {, t* R
                        WriteExProcess( q.addr, q.data );
! H7 e# r  K; d                }% F7 q% P6 m1 n6 G4 f* C
: }$ e7 Z4 [+ l
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7* v7 ]+ C' I! Q7 A
                output = 0;
: ?: p; j( r$ ?  F& @$ t                output += internal.Process( 0 )*vol[0];
7 y3 M. \! @7 ]- c, [                output += internal.Process( 1 )*vol[1];
8 W3 ]- ^& w/ C' ]6 K) ^                output += internal.Process( 2 )*vol[2];
9 P4 V2 g! Z( B1 I* P' O% B9 \                output += internal.Process( 3 )*vol[3];. A( S" `5 ~+ X7 f& f
                output += internal.Process( 4 )*vol[4];, C9 K  f0 F& {! t8 z% A2 g' ]
: T4 }2 A; g* M8 G/ Z
                if( exsound_select & 0x01 ) {+ m! W; {# a) ]' r- [6 W
                        output += vrc6.Process( 0 )*vol[5];
% a2 G0 W+ h* g                        output += vrc6.Process( 1 )*vol[6];0 A; ^- T, e6 X0 A3 t$ A
                        output += vrc6.Process( 2 )*vol[7];
" a% q) U* k! s+ M7 t" B9 f% F                }
' c) Y9 J' N/ o0 O3 Q6 }, c                if( exsound_select & 0x02 ) {2 l% v9 S/ D5 H2 C+ [/ g
                        output += vrc7.Process( 0 )*vol[8];
- u2 Z* X! Q0 z0 p- ]$ e4 D  R                }4 G" m/ `( \& N- e1 |0 `
                if( exsound_select & 0x04 ) {
* u( `6 D, |. ^& @, r                        output += fds.Process( 0 )*vol[9];& E# w1 d- B& o0 K' L
                }+ P& t6 O) f; R6 z( I3 v
                if( exsound_select & 0x08 ) {
0 F9 |& C4 b: H1 ?# f- B                        output += mmc5.Process( 0 )*vol[10];1 d9 m+ W* D; d; t
                        output += mmc5.Process( 1 )*vol[11];; N# t" }) c# P/ |# X7 \
                        output += mmc5.Process( 2 )*vol[12];* o4 l+ L* ?4 l- K; N+ W
                }5 L6 {, K. J) Z% Z/ E
                if( exsound_select & 0x10 ) {) `' h. V& z. w" ]
                        output += n106.Process( 0 )*vol[13];
* y0 }# U7 p0 W7 `% n' A, |& U9 P                        output += n106.Process( 1 )*vol[14];: d& L/ K) R7 o2 l  o
                        output += n106.Process( 2 )*vol[15];9 F/ D% G2 |& y' H7 o
                        output += n106.Process( 3 )*vol[16];* X" j* D& a& Z9 H" f
                        output += n106.Process( 4 )*vol[17];
3 m. B6 ~  |( d0 K- v/ \5 U                        output += n106.Process( 5 )*vol[18];
& J/ n; P* w1 b* g3 R                        output += n106.Process( 6 )*vol[19];, w- y, L" D/ x  P. x; g
                        output += n106.Process( 7 )*vol[20];! c7 o, @( X; x; k* L% O
                }
/ [$ A# G" a. z% H2 j                if( exsound_select & 0x20 ) {) }8 q# I1 {/ L: r( _' A
                        fme7.Process( 3 );        // Envelope & Noise
" i5 q$ w- ~3 ?. ]                        output += fme7.Process( 0 )*vol[21];* p6 k) k+ T5 O6 `: j
                        output += fme7.Process( 1 )*vol[22];
+ D7 @8 s! r9 \) j  J. W+ g                        output += fme7.Process( 2 )*vol[23];
  |6 }' p9 F- \; h3 i, b2 t2 W                }
; M+ s' f( F: M7 e. R4 l8 Q8 Y# c/ W6 v
                output >>= 8;
. i5 y' ^8 i* D: n) [/ _2 w% ^3 y" s" g/ F" e, \
                if( nFilterType == 1 ) {3 t$ B  b* K6 o8 u; U
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
; B$ p+ w1 @" e# L# y6 n                        output = (lowpass_filter[0]+output)/2;
0 H6 A; S, w* ^                        lowpass_filter[0] = output;7 r& A# X) }8 {; x
                } else if( nFilterType == 2 ) {  A0 ?! @4 d( s) V' D% ~
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
7 e. f) a/ S7 @7 n* ]                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
& L9 t5 d/ K( w& F7 z0 S4 r                        lowpass_filter[1] = lowpass_filter[0];" x, A; E2 R1 M8 T3 T
                        lowpass_filter[0] = output;
5 [( r- C9 H) i( d                } else if( nFilterType == 3 ) {1 B  B$ N, \; f1 ~! c! k5 Z  D  M- P2 h
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
: T& _3 p) l# d. j/ g  n. W' M                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
0 K$ _1 t3 A& Y5 [                        lowpass_filter[2] = lowpass_filter[1];% x, U  N6 B/ `6 [# D. @/ }
                        lowpass_filter[1] = lowpass_filter[0];1 q0 F) d+ k% y# `, I  L1 ^9 t( S$ k: ~
                        lowpass_filter[0] = output;% Z) [& S& q/ }2 ^& R' K7 e/ f
                } else if( nFilterType == 4 ) {/ q" j& F  w9 d: ~! _
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)" q; ]6 w4 u/ A  t' m% c% s
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
7 L& x' L; D  D" g& f: c. x                        lowpass_filter[1] = lowpass_filter[0];
! ^) j  j) R( c% b3 `+ a5 h                        lowpass_filter[0] = output;
! @; p: \- h6 t. u2 l                }
% t; k; M# u% \+ l8 i, z+ p) e% m0 ]+ @
#if        0) B* U4 o$ s) D1 X& j0 P, d% J
                // DC惉暘偺僇僢僩3 _; X' }! Z4 ?- Q5 R/ l( Y
                {
3 P8 c9 P/ r$ _/ O                static double ave = 0.0, max=0.0, min=0.0;; k2 U! m* F8 S) n8 A( Q
                double delta;( p3 E* F- x( V7 [. C
                delta = (max-min)/32768.0;
" f1 v( T2 \% ?- Q3 u$ K, m0 d                max -= delta;  }1 Z9 z6 j( X
                min += delta;! T) S- m' T# w8 N  m" X6 m4 n
                if( output > max ) max = output;, X; q6 r# A! b7 e  ?8 Z
                if( output < min ) min = output;
" A* t  E  V6 E8 S. W                ave -= ave/1024.0;; a6 ^- G* b+ L. C; p6 Q/ w
                ave += (max+min)/2048.0;
- e( H; _8 j1 q' B3 _                output -= (INT)ave;) i( S7 A6 _) `. C, O7 }7 I
                }
- L3 {7 y' G* y#endif0 G: _! T( B0 i3 i
#if        1
2 }/ h# J. G7 s* S" Z8 F, _                // DC惉暘偺僇僢僩(HPF TEST)
! q8 _  K" n$ r" M+ y                {
: S; S) b! I4 D4 q//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
& I3 z5 L& M- U+ D1 L+ d/ ^/ u. R                static        double        cutofftemp = (2.0*3.141592653579*40.0);+ O/ D( u$ e* I/ w7 p' c9 m  G
                double        cutoff = cutofftemp/(double)Config.sound.nRate;3 M0 {& G, p6 C# s) j! j
                static        double        tmp = 0.0;3 ?9 j; B: u3 n: \& l2 y# c
                double        in, out;
2 f# W5 e) `0 y# u* \) C3 m8 a: O2 X
                in = (double)output;* L' M& |( t* b7 J, k4 L
                out = (in - tmp);
, b1 _, v+ V2 X/ m                tmp = tmp + cutoff * out;
- S+ y) P' a% l. b$ u
' @% C4 t  q0 V# R. {                output = (INT)out;4 |  V& t! x& V
                }
# \, N3 \* Y0 c4 @#endif8 j. }5 v- z- C
#if        0, D$ P( y. d8 {( h
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
0 |7 F' N9 ?8 U  J' ~9 k1 u  z; Q                {
; ~% W" W+ e3 N                INT        diff = abs(output-last_data);
5 w% n: G/ c, C$ \% c                if( diff > 0x4000 ) {
: t9 f( b0 c3 k' q! r                        output /= 4;
2 j! w6 k5 V+ w3 m/ _# t  }: K                } else . }+ R6 X- k7 T* E$ }; k5 ?
                if( diff > 0x3000 ) {
; F5 y& k0 N" S- h; @                        output /= 3;$ b' O8 l1 X0 |
                } else# @9 l* b% y: n
                if( diff > 0x2000 ) {
4 r3 x2 F$ U* A. h' f+ c                        output /= 2;
  m# h3 m& X# s; L8 L                }
. N) t, r2 B8 i2 d                last_data = output;
: r) D) Z7 A3 w                }
+ V) m$ Y3 v8 X#endif
; G  r( g+ v  i4 Z. {                // Limit8 w5 ~4 k/ @& R& L; r3 k, O
                if( output > 0x7FFF ) {2 I% \: [/ v. T! R1 l# r. R7 p
                        output = 0x7FFF;
* x1 R$ L( @0 }( x/ Z  v, V, ~  `                } else if( output < -0x8000 ) {9 a4 x0 o% J( `9 ~# p2 ?
                        output = -0x8000;3 H) t0 u! A2 `" W0 U
                }$ F7 }  L1 y! Y
; ?5 n# x; N' T
                if( nBits != 8 ) {
- z0 }: x% P' V                        *(SHORT*)lpBuffer = (SHORT)output;
7 b1 k& V% O  R" e                        lpBuffer += sizeof(SHORT);% T* d$ }) ]. M: v. B9 c
                } else {6 l# h( ?& D. G. V) w
                        *lpBuffer++ = (output>>8)^0x80;# f9 x; ~+ `+ `1 r3 {
                }1 H. G/ I  Z8 C. ~1 K
) o1 ^* q) g- `
                if( nCcount < 0x0100 )8 N* r' @4 i, r# p- {5 Y; b
                        pSoundBuf[nCcount++] = (SHORT)output;8 F( o" Q1 g4 [' B, m
' P5 b1 a7 {6 w; [( D4 f
//                elapsedtime += cycle_rate;. q# x6 D- Y. o( r' O
                elapsed_time += cycle_rate;6 m8 U3 n0 f( r
        }" C. d/ j3 r5 u! \" \4 P' W
9 q+ m9 e& j6 S& I0 U2 Q; v* E
#if        1  ^* F; [* J/ p# p+ Q
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
7 s) J3 `" n2 U) @" {5 o4 b                elapsed_time = nes->cpu->GetTotalCycles();7 Z' |4 i$ V+ Z: h0 y# z/ A
        }1 O  y. G; c5 t4 T: v$ h& Y, _
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {- ~( {3 ]3 a7 A
                elapsed_time = nes->cpu->GetTotalCycles();
4 U& i* {# p6 i        }
0 y! v# e# q, V$ x/ ]#else+ Y" W9 b: E+ j5 ~
        elapsed_time = nes->cpu->GetTotalCycles();# u: `, b9 `5 J& ^
#endif
# l7 Y3 x! x$ l6 }. G}
8 x7 c  C8 s- b) _$ S" [! d  T) c* v3 m3 l. N" H
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)5 H2 H9 k( _' ?9 ?4 M" E
INT        APU::GetChannelFrequency( INT no )# b& |7 e, r7 v9 u2 h/ m
{2 [. C' `" p0 X9 a$ [/ F4 B8 G
        if( !m_bMute[0] )
$ @  Z5 E4 S8 n: \$ Z8 I                return        0;. F/ P8 t+ K2 a+ {0 a
( R/ m1 ?- h0 S2 ~
        // Internal) O6 u/ B/ A# @6 |0 _9 u, F
        if( no < 5 ) {
6 U" B2 [; g/ W, A/ L                return        m_bMute[no+1]?internal.GetFreq( no ):0;! Q/ e0 K- S* ^" v# f8 F8 ?
        }
! Y6 L  T5 W' @2 P/ W+ S, ^        // VRC6
1 V8 Y# B" A9 ~4 _        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
* x7 Z# N4 Z0 Z1 a" k( @. `. T                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;& @% C" Z6 }, J+ W# t( E- M
        }. p! ^' \7 M4 W1 J) S  {
        // FDS
$ M3 b4 x, n# R3 e0 O6 d; x# p        if( (exsound_select & 0x04) && no == 0x300 ) {
( |7 ~$ Z% ~$ m( G% G                return        m_bMute[6]?fds.GetFreq( 0 ):0;
* e4 F+ u  G# g8 ?! n        }
7 M+ a+ G( z3 S  l1 O) l  S  m# Z        // MMC5
1 K, v- U7 i3 ~' p0 [* V$ i# T% q        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {6 u  z8 ^9 w$ j/ h! a
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
1 |; d/ t( M8 F        }
; ]* _& u' E0 ~) m2 |# V        // N106
! ?; B7 @- l5 x        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {. `+ M1 e. j' [
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;3 K2 N+ c) i# E9 V# W% ?
        }8 t0 `5 y! h' u2 K/ E$ ~/ y
        // FME7( O' U; ~: f5 B5 Z' c
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {7 i9 c  w- W" {; d9 E: f: W3 g2 \
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
, I+ e- B# \( m- X        }' E; s. L2 `7 ^7 e; _
        // VRC7
) o* _% e8 [( \        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
* R2 M" d# ]# T5 ]                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
4 q# `0 r0 G% |, B6 d  N        }, f- d* x7 c6 M* o$ U  U
        return        0;
' p, Q  C* Q$ f' l1 a) p3 X}
5 z9 r3 W9 Z1 {) o, E2 a- c0 f: z4 m  A0 }0 D; d& O8 q/ Y
// State Save/Load
+ H5 p# f) r0 `# ^' s% Lvoid        APU::SaveState( LPBYTE p )4 x* z' v* ^# E
{& D, O  G- `) I+ Y4 u) r2 a  c
#ifdef        _DEBUG) t0 ]+ S  D6 h! K' {. w3 f- v
LPBYTE        pold = p;
4 {5 n2 f6 p- g1 e( q0 b4 D#endif
, u, G* D6 I3 i. Y+ Q, |. U7 A
: r8 y; k% c2 n8 \( T$ G' k2 A- t        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞, X( C" q2 E( B6 r: w+ b8 E
        QueueFlush();$ W' K* J$ `- N* @% v
; D- f0 s9 e$ W0 W6 Y
        internal.SaveState( p );& M2 t  p. z$ q9 d. i4 {# P: r' Q
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
, N. ~) b# K0 d, D
+ a: w* l* V9 D/ Y        // VRC6$ `: D0 _, W# J' h
        if( exsound_select & 0x01 ) {9 L" K) R$ d2 e- e0 a4 a/ O, k& H$ x9 U
                vrc6.SaveState( p );: y" ^  q/ H# Y& R) E
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding  [+ C1 O; y3 e* R- R$ \) d$ t
        }8 \0 {+ j: M  e5 a) g, G
        // VRC7 (not support)6 P  h* o2 Q$ D0 R, G: m5 b
        if( exsound_select & 0x02 ) {
. A5 U- t7 t$ E" F: a+ ?                vrc7.SaveState( p );; I  [8 x$ t0 v
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding0 B8 U! x; J' a. v
        }
* Q9 m% Y# ]" w7 c        // FDS
7 x% a! S2 o# y, Y! d        if( exsound_select & 0x04 ) {
3 E, `5 C. z% i8 U4 i% d                fds.SaveState( p );. Q% b) F4 W; D2 @! q7 E
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding0 u5 E7 P* l: @5 O
        }
) r& K* {  ?+ x, [% f        // MMC5
) _5 m  i$ Q$ `) `, i% E5 F. `: F        if( exsound_select & 0x08 ) {$ D4 s! C% U' r, _
                mmc5.SaveState( p );
2 i3 ]# V" [$ k' b; ~: P# v! ]. U0 t7 M+ u                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
! T+ p, l# A, y5 ~        }
" N3 T* p: X4 t+ C  M! S! ?        // N106
) ^/ O. D9 z# H- ]% t* E0 ?, s1 c. F        if( exsound_select & 0x10 ) {
' P$ [6 L! q7 I; A: m7 i  I                n106.SaveState( p );+ _+ n( V; d9 m' ]
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
& R& t; Q0 u, G! f. u0 k        }
2 c2 a$ m& O  R        // FME7" A$ v& U; l  A0 D3 L0 H
        if( exsound_select & 0x20 ) {  m. ?0 A: \" e$ _9 i
                fme7.SaveState( p );
, Z/ y1 b# W- O' g8 U                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding6 J4 L- h' |: d' i3 \8 U* k& j; K
        }
! E7 m* r9 R. _1 a' y
% ?1 i% `1 ~2 w. T#ifdef        _DEBUG
- a% J6 {; o$ l6 Y7 i% U) sDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );% G$ A: P: O3 Y& u) n; i3 a
#endif
& A3 b7 v+ l  T/ F% r' z' X* j! q& O}
5 P$ `7 ^6 _; }
) V3 n5 @7 d* vvoid        APU::LoadState( LPBYTE p )5 A8 n& u8 B/ |7 f0 H3 Y/ `! n
{
! w7 W+ [& w( e. k0 w        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
; o0 U, X; Y5 d& x* _/ O        QueueClear();
' M8 R( m$ c) C9 {# m- N: L" p
. s; w1 y: F7 Q( w        internal.LoadState( p );
* S4 x: j) M0 z, {; O) ?3 j9 K        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding  }" K3 z' |/ U7 F! f3 q
2 [6 e1 c  A& Z' T% B' A$ i8 w
        // VRC6
1 M. n* }9 b7 x        if( exsound_select & 0x01 ) {
& F. _1 ~/ f6 Z                vrc6.LoadState( p );
, Q6 b+ g3 S; M; {6 x* S) ?$ p6 |% T                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding  Y$ q" c6 t- `. H1 U
        }
) B) M& b5 ]$ @5 r! V        // VRC7 (not support)2 G! A3 j: W7 w/ X* s- c
        if( exsound_select & 0x02 ) {* ^5 T* v+ Y) O2 a4 R- W
                vrc7.LoadState( p );! N5 v1 ?: v; O+ a
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
9 r9 _6 L/ h' o$ B* z( L        }
; G( K( j' D1 S0 ?        // FDS
3 i4 O, C0 A$ W$ K5 s% f- P        if( exsound_select & 0x04 ) {
# d& i4 e) |2 `& w; g                fds.LoadState( p );9 m$ w9 |5 |4 [+ T( \9 o. J* q! M
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding# K- P6 y  H7 |, e/ G! d
        }4 T3 @# r; y% d
        // MMC5
" j, u1 K' B) y4 `( X) B. g7 A2 W        if( exsound_select & 0x08 ) {
' v: ?4 Y) F% M* E8 U; f5 }' T                mmc5.LoadState( p );, i0 C. |' S* w! ~
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
. @( g* P# _0 ^5 U; x# t- Z+ L3 l* y        }
' [" T0 @8 e* T* {# \        // N106
( G* X# b0 |! T% I        if( exsound_select & 0x10 ) {' g  _7 p6 N7 E( o" f' q- x
                n106.LoadState( p );9 ]/ V4 K2 p  Q2 j; l
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding* _( Y' m+ ~! ?3 N2 o7 F
        }
. j$ Y, C, y! ^3 n) e6 |5 e% A! Y        // FME74 U8 s% Z7 Y, a9 r2 _8 |4 O
        if( exsound_select & 0x20 ) {
4 P2 k+ l# r+ t8 U; b- [. c                fme7.LoadState( p );
6 }+ ?# l: A  G                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding1 D8 j# `9 \3 r7 I( O
        }
) b: ?5 N+ Y1 `7 J1 m+ t. z}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
: r9 a0 B' j4 \: J/ o5 H3 I; W可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
1 _- J" |/ e3 y. [! v感激不尽~~
" c/ M% c  J* ?8 n0 `
恩 我對模擬器不是很有研究,
  y. _2 G' q; b1 d/ S( \雖然要了解源碼內容,可能不是很困難,
: y1 J  f- _; y; f3 {) G( L6 b不過還是要花時間,個人目前蠻忙碌的。% y& Q0 ]  \( C5 y7 ~! B5 D

; T3 _( F  e. L; O給你一個朋友的MSN,你可以跟他討論看看,
& ?9 ~; h1 a& G3 T- E他本身是程式設計師,也對FC模擬器很有興趣。
% R; G8 R6 r* c- q+ e9 u' q0 b5 A3 k/ x! @1 g* w
MSN我就PM到你的信箱了。
5 P) P7 I. R8 x+ X1 z% i. t- Q  R: L
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 : D/ I$ `8 o. l3 ]. f- C5 I
呵…… 谢过团长大人~~
4 |, f- W: b6 O* k7 e. b3 u
% N& d# f0 I, M( h6 [. @7 T8 Q
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 " Z# ^0 ]; Q* ^5 u/ z# o
团长的朋友都是神,那团长就是神的boss。

' B: |: t! E+ G* x1 P. h3 b( M哈 不敢當,我只是個平凡人,2 D$ m4 i- J& \9 T( K; s
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
; _$ R  D$ c" y! l$ O' ]- ^8 @) NZYH
5 H8 G. v2 D7 `! @QQ:414734306
* V. B$ N4 c, ~4 z2 U3 @: ZMail:zyh-01@126.com
! s! v7 H6 @6 s) k! e$ q. R3 g% Y  d" w
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 3 K7 B: F5 l6 D9 |
再次对团长大人和悠悠哥的无私帮助表示感谢~~

( [2 ]; u- V- ]- c0 g不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-11-28 21:54 , Processed in 1.204101 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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