EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。+ T8 F/ }6 E" c$ J( Z
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~& B- q/ P$ Y3 r- Q8 U" V' e/ Y
这里有相应的模拟器源码,就当送给大侠了~~) A  x5 f% e2 C5 c% C# o
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 2 r9 G+ i( A, t: C- j' [0 y
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
; _2 B  L9 A7 K1 d9 U楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~. w$ _* Z* G3 A% u& a! f
这里有相应的模拟器源码,就当送给大侠 ...

; }  p* ^8 Z: w& Z; S聲音部分(Audoi Process Unit = APU):8 o; l9 d+ c& Z2 Q/ k& j# W
.\NES\APU.cpp8 `0 J( @: e' j" ]% t
.\NES\APU.h+ t$ }+ |* g" g' @

/ n, Q. E; q6 g% z- S. {% W$ g+ u- [) n
影像處理部份(Picture Processing Unit = PPU):
( V% ^- b* N3 `$ w1 e8 s.\NES\PPU.cpp& C% o, E7 U5 D& q' K% `$ H
.\NES\PPU.h
7 Y2 K4 ?9 N! ?% [1 ^9 P
; J1 |9 y3 w- Q  w0 q1 L如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
/ h" m2 w2 U- y3 j(由于很多专用术语和算法机理都不明白,所以看不大懂……)
. ?# K% M/ X) W# Q//////////////////////////////////////////////////////////////////////////5 _4 k% {$ R; d9 {/ H# I
//                                                                      //% D8 [5 e2 P' r3 V. P
//      NES APU core                                                    //
$ P. k. E1 l5 [1 g2 k' @9 V" k7 G//                                                           Norix      //
/ A' c% @0 b; |//                                               written     2002/06/27 //
2 m0 E# Z  ?, F5 \6 \//                                               last modify ----/--/-- //5 b. ^: f' J8 _5 R7 e" `
//////////////////////////////////////////////////////////////////////////
- k% p/ M9 v- _! d& J#include "DebugOut.h"
6 P: d3 D8 R; C/ o) G' n( l#include "App.h"$ ?! H6 \* f' h( e, F" n
#include "Config.h"0 }! |* }( W+ B1 u

* n" ^4 y0 j0 p0 C#include "nes.h"1 T! I1 V/ }0 }, @6 ?
#include "mmu.h"5 I$ {' N( E) o, M2 \0 C
#include "cpu.h": a) C- f" Y4 m! F' R4 {
#include "ppu.h"
1 a$ n% l/ H. L1 R, B- G% |- ]. K6 r6 h#include "rom.h"
! x1 J; ~; W/ Z9 }' p  E#include "apu.h": O# E3 c+ d; q8 i1 @
* w7 Z% [' }$ p
// Volume adjust  u& i, `, i1 X. g: f$ W
// Internal sounds( r2 I1 V! V# a8 z
#define        RECTANGLE_VOL        (0x0F0)
/ e1 d8 P: `* D$ _#define        TRIANGLE_VOL        (0x130)" c& h& I+ w1 r7 h1 n
#define        NOISE_VOL        (0x0C0)
1 o; Z1 \# R  w' L& x7 D1 L#define        DPCM_VOL        (0x0F0)
" |* j: C& c( ~$ G7 j// Extra sounds
0 L$ Y6 m6 ]) ~+ v+ M#define        VRC6_VOL        (0x0F0)# v: k8 d- m5 G: |; S/ \5 Q
#define        VRC7_VOL        (0x130)
5 Q# G1 S# f, s6 [1 E% O# V#define        FDS_VOL                (0x0F0)- q- y' h; l8 ^& P
#define        MMC5_VOL        (0x0F0)
2 i$ V& Q3 K, n* L% W* T#define        N106_VOL        (0x088)1 E2 s0 U; w0 L' K
#define        FME7_VOL        (0x130)
) A" Z2 H- Q1 e0 K" ?1 u5 L
8 K- E8 E. C6 ]$ T- T( |, OAPU::APU( NES* parent )% f& K7 ]+ j# R" L/ u
{
! q, L# X5 m7 G0 f! b* Q: g        exsound_select = 0;9 V7 ~9 W! z" B) N3 z( G# D

' U1 i5 M6 S$ h* u        nes = parent;2 F" K& [* J2 Z7 o+ p% n8 e9 Z
        internal.SetParent( parent );8 x% Q( x& @! E4 k4 C
. k5 t- P3 g  J* F1 _3 d# f2 G2 B6 F0 u
        last_data = last_diff = 0;
2 v* H2 i7 U4 c( C' u& V/ N1 D( b) o8 i) r
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );; V( D% W, ]( {

& u/ l" a/ w) o! G. T! W4 k" T        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
3 f( a! u- F1 l0 r/ I        ZEROMEMORY( &queue, sizeof(queue) );
( j) b$ z. j) P2 D2 W: A4 s' J- n        ZEROMEMORY( &exqueue, sizeof(exqueue) );
% R3 z5 w% q# J- |6 {9 T* \+ r- Z, Z" N0 B
        for( INT i = 0; i < 16; i++ ) {& |" T8 Z' f: ~7 T$ {) Z
                m_bMute = TRUE;: ^  w, Y; P1 D; i
        }, s3 x, O9 v. P; x0 D6 C! ?
}+ u+ W4 F2 d# ^: q6 `8 n

* k2 t4 u8 h, A+ mAPU::~APU()
& B! n  \; S* \! p) U{" N& l* y) ]" |, ^# s
}
/ W, F. c1 L6 [7 i* N# e* Y+ g+ @  W; J3 x, U+ [, t% K
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
3 ~  q" D. h: v3 t8 n4 W8 i& C& `{) U& q+ i$ ^4 E2 s
        queue.data[queue.wrptr].time = writetime;4 x* P/ q1 F2 K3 T- l
        queue.data[queue.wrptr].addr = addr;0 E1 K! F7 ^9 T
        queue.data[queue.wrptr].data = data;3 c8 y& a5 W0 v/ g9 L4 r7 G
        queue.wrptr++;
+ t! x$ t2 V" ?! O8 ^        queue.wrptr&=QUEUE_LENGTH-1;+ t2 N( w: \% v3 }' B' r
        if( queue.wrptr == queue.rdptr ) {. A% }" Z3 A; L
                DEBUGOUT( "queue overflow.\n" );
/ l: X2 p- B4 B! }- T  {        }
* z* \! W3 F8 ^) Z1 P}
' [  d6 n9 C* F6 l0 |2 c+ Q# B$ X0 A  A8 o
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
! {& ^9 a# a9 Z7 I8 f5 \{6 f# j0 h! q7 b/ F. y7 @
        if( queue.wrptr == queue.rdptr ) {
1 ~, v  r- g& P2 G# s9 c                return        FALSE;
$ Q: N" Q: H/ w' b3 m( O" O7 V        }7 s( D* F, p! W7 Z
        if( queue.data[queue.rdptr].time <= writetime ) {
* q' G' L' [+ A2 n8 |0 y                ret = queue.data[queue.rdptr];/ s! _- }2 G. M/ x7 ]% @/ ^1 I
                queue.rdptr++;
0 R% r$ Q) g& j+ z                queue.rdptr&=QUEUE_LENGTH-1;
" p( e# T2 [  p# ^2 }7 ?                return        TRUE;
$ v+ F) \- x+ O5 ]) ]9 K4 k. {' a        }
" g% s( m9 `4 m: c7 G        return        FALSE;1 q$ l7 ^  M' G6 Z, R
}4 i, t$ ]% y2 u- U; }. l( s
  a, m6 c3 c, `
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )* s3 j/ i/ r, v0 _1 j& A
{
6 W' v( f( Q# c" N        exqueue.data[exqueue.wrptr].time = writetime;
2 K* e/ o: O+ Q( T' \9 b        exqueue.data[exqueue.wrptr].addr = addr;
8 Y$ U( b( B  u        exqueue.data[exqueue.wrptr].data = data;
. P* J4 \3 O( D/ |- j        exqueue.wrptr++;
  u$ c7 `" H1 |+ c+ ]        exqueue.wrptr&=QUEUE_LENGTH-1;' _8 e0 F% p4 }3 w# T$ s2 P
        if( exqueue.wrptr == exqueue.rdptr ) {
% @  Z/ c9 J# \5 {: _                DEBUGOUT( "exqueue overflow.\n" );% C+ d, p# P; v1 D) S
        }
. a( I0 V" j4 l5 [4 s/ R0 c}
3 X* q; b* {& S! i1 z! I* a
. N$ {& f0 W! S$ o' d' F+ }: A: l6 XBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
; b! S: T8 p# j% d/ Y" y# N6 l  I{
( ], Y* [5 @. ?        if( exqueue.wrptr == exqueue.rdptr ) {
# V' u5 o8 r+ ?6 e9 Z                return        FALSE;! I1 F6 C1 j6 H5 m+ [8 F
        }
- U8 U* E$ a  B1 b1 n/ x        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
, @; i& B# K2 }+ P                ret = exqueue.data[exqueue.rdptr];0 n* Z' F$ t& m& q! A) Y
                exqueue.rdptr++;+ n) P" d% K) k  e) z1 k) e, w
                exqueue.rdptr&=QUEUE_LENGTH-1;5 }; r2 Z, t. ~# ?
                return        TRUE;
" [7 n" i9 W3 Z) S7 E% O& l        }7 d+ c: {, A. Z/ @. O
        return        FALSE;* U, m1 m% H, W
}
; U: y3 N" x. U. j/ I
7 R% S7 T6 L2 i8 \* t1 J/ evoid        APU::QueueClear()- f/ j7 {! A4 [! T5 k& v
{
! C$ f, e$ j6 |5 T7 }% U4 Z+ ?- I        ZEROMEMORY( &queue, sizeof(queue) );$ d" M- ~- B3 ]  {5 n8 A  c3 H  K
        ZEROMEMORY( &exqueue, sizeof(exqueue) );+ A/ Z% ~: g- _" k  O. A9 a& G
}
$ f  ?9 C& o& K! a
9 ~* h/ _4 d+ G0 J9 wvoid        APU::QueueFlush()4 w) \0 @, p" h( T7 U" \
{
, z% d+ g3 z9 x4 m6 U- d1 ]        while( queue.wrptr != queue.rdptr ) {" `+ h# n4 v+ ?; B  g
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
) q# p( ?0 P  v- f1 F# ^                queue.rdptr++;
  n6 u* Y8 g  j8 w' u6 `9 Y( ^                queue.rdptr&=QUEUE_LENGTH-1;9 ~9 [& d, N. R/ S
        }
6 ?& a, e  I2 w4 N7 D' O3 J( P( U6 u: d9 e( r
        while( exqueue.wrptr != exqueue.rdptr ) {/ k$ w# Y1 H3 f5 ^2 p
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );; Z: U- ^" R  P9 j1 }( T
                exqueue.rdptr++;
. u9 W' |- l8 [6 Y  s) M4 T                exqueue.rdptr&=QUEUE_LENGTH-1;
9 ~/ \! F$ r3 [1 [+ X& C        }9 E" L8 P" c2 B) m5 C4 x
}
/ ?3 S/ G1 o0 b3 f" a6 J9 w" f; X' Y0 a5 y" O3 |8 I5 D0 k4 |. E5 `" E
void        APU::SoundSetup()2 f+ d4 X2 X' b( n) D9 z
{$ v6 I5 }4 z5 y7 I
        FLOAT        fClock = nes->nescfg->CpuClock;! b3 q7 o9 B( o3 A# R+ T* m3 w( R
        INT        nRate = (INT)Config.sound.nRate;" v8 x6 O- C# j# T/ p' L
        internal.Setup( fClock, nRate );, \3 h) A2 x8 ~" r. ?" I! I! G
        vrc6.Setup( fClock, nRate );
2 D0 k- e6 z4 x  R4 m0 Z9 H        vrc7.Setup( fClock, nRate );
. r9 G- e& Z  T' K6 v: V3 |9 K        mmc5.Setup( fClock, nRate );
! h2 Z* g4 Q8 i6 D$ l+ k1 ~        fds.Setup ( fClock, nRate );* f1 D9 o' J. V; Q5 z- {! V
        n106.Setup( fClock, nRate );& I$ {2 N# H" s
        fme7.Setup( fClock, nRate );
6 {, i& c  W+ a. B; b}* R5 W# S7 v; l, s' t7 s
/ Z$ R* p3 l2 F, K0 `. ]: s% z% @
void        APU::Reset()2 a2 y. ^) Y; Q& j3 g2 |
{
! @4 V+ O  C( t& a8 p" f        ZEROMEMORY( &queue, sizeof(queue) );& i; i' h2 L2 ?2 g* e. a
        ZEROMEMORY( &exqueue, sizeof(exqueue) );8 \) _3 Y; R4 K% U: B7 X" ?
* p8 }. \% x" W
        elapsed_time = 0;% _# r3 D$ [, B5 i3 }
& M+ L% l4 A* k5 Y. x
        FLOAT        fClock = nes->nescfg->CpuClock;
8 }4 |6 ~- d0 ^, s  [' x% R6 S; K# W        INT        nRate = (INT)Config.sound.nRate;
! ?6 N2 q' }% p        internal.Reset( fClock, nRate );
( K3 a8 U3 r6 ]! c        vrc6.Reset( fClock, nRate );6 `( ]7 e3 h3 W0 W; e( A; _
        vrc7.Reset( fClock, nRate );' I) r! V' i% {. d7 t
        mmc5.Reset( fClock, nRate );1 I- P7 l# d: w
        fds.Reset ( fClock, nRate );
/ j6 }" [$ Q3 R" K5 k1 m. Z" I3 A        n106.Reset( fClock, nRate );
* z% `/ P5 ~3 n        fme7.Reset( fClock, nRate );/ w( t. v+ o* L# [) _  p$ h
% T: G$ G' e$ Z) e0 H* x. a7 J
        SoundSetup();
" S1 s, a  |) [. o( Y. c}% m% h2 h- j. s* F/ l
7 y) S+ q. u0 a; K* T9 o; r7 |
void        APU::SelectExSound( BYTE data )
( m1 ?/ |6 I0 Z{
" C7 b; A! g0 H/ g! `        exsound_select = data;' ^9 P. ~* N4 V1 n) @) j
}
0 E7 [  z) N$ ?& }4 }6 l, T7 t* ]; Q& _+ h6 q: D# j2 y! p
BYTE        APU::Read( WORD addr )
/ b) C* ~9 a+ _3 Q; h* S& N{# h' {6 t& z' a, D: `- t1 U- h
        return        internal.SyncRead( addr );
- V# P& l/ t3 o) O/ x}
0 ?" C) p+ ?6 {
8 |' F( f! U3 H6 `, K- h; Wvoid        APU::Write( WORD addr, BYTE data )- f/ n& _) h( [
{
, ^4 e8 x) M4 i0 a4 g4 \( Q        // $4018偼VirtuaNES屌桳億乕僩
- j+ L( o) G8 G+ o7 j+ }        if( addr >= 0x4000 && addr <= 0x401F ) {6 k  m2 c( y( Z, c0 E! w
                internal.SyncWrite( addr, data );
  F0 n8 q: m# T/ S                SetQueue( nes->cpu->GetTotalCycles(), addr, data );( y6 A* s2 Y9 G6 L9 ]! f
        }
& p3 T0 Z2 h8 r) k- ]: x- z" F}
* k4 g/ U. A" |4 W1 s) T% R# u
) S: A/ t+ ^' f; Z9 @BYTE        APU::ExRead( WORD addr )
) k( j% d/ _1 L. T' [# U{3 `- D2 J2 j( x' H
BYTE        data = 0;
. B2 C" X" Q3 y' O: r9 a4 f& G/ P" [; q* @
        if( exsound_select & 0x10 ) {& C& l1 q6 `4 w) {
                if( addr == 0x4800 ) {
9 u/ }" J0 v, q6 M8 m                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
, s! F5 v) C, S' T0 r9 B, h5 \                }
. k2 m# E: M/ p& I- ~        }
. l2 i7 g9 [' |6 d8 W        if( exsound_select & 0x04 ) {
8 l- ?  N+ U0 ]+ b, {                if( addr >= 0x4040 && addr < 0x4100 ) {
9 Q3 }) E  C- a) O                        data = fds.SyncRead( addr );" t- R/ S) u$ }5 c* f" ^4 G0 m0 z
                }  J1 P! j2 \6 C1 h
        }
/ V" S7 n9 a. p  O+ l1 h) v        if( exsound_select & 0x08 ) {. A7 Y0 Q3 u" p1 ^3 S) f  M% |2 ^8 T
                if( addr >= 0x5000 && addr <= 0x5015 ) {
; u" H1 g/ h$ O4 V4 x8 T) H                        data = mmc5.SyncRead( addr );
& V9 C5 i/ X: M* }% D! W                }
& `, s& n$ }0 t& B' k5 x        }( ?2 }4 g# `' `4 J* k2 z

: O- b" T$ T9 a9 D        return        data;
1 Y& B$ L  U) J6 {1 S}
/ Z: w8 f# T7 ^$ g& k- w3 D# M
# Q6 ^& J8 h5 D& wvoid        APU::ExWrite( WORD addr, BYTE data ): O" x& }% ]" O3 u* M
{
/ m0 L2 d3 C- j9 e) I- w: w; \        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
; g+ e, B2 F. s$ U& S5 V
1 J7 r0 t. E0 \# e5 G        if( exsound_select & 0x04 ) {
) ]: K+ y9 q5 G* j% U                if( addr >= 0x4040 && addr < 0x4100 ) {6 L) f0 I0 H, E/ K& _+ q( ]( G
                        fds.SyncWrite( addr, data );7 y; |2 ?# ]3 |# b* I
                }( C6 D: O" c$ b2 G/ n9 j+ ?  ~$ E
        }4 b5 {3 t" s# O1 v4 y* `- @2 o
6 u. T6 p9 J1 P( M8 _4 n" J% D
        if( exsound_select & 0x08 ) {
% B* t1 U  a! a9 L, F# j- Z! b, q2 m                if( addr >= 0x5000 && addr <= 0x5015 ) {
6 F$ g4 R) q8 T4 G; L2 l" k                        mmc5.SyncWrite( addr, data );
5 Z- G$ H+ G4 U% Q/ T- B9 p                }, m' V& G' D. t# ~9 d) N
        }
1 T6 @: i9 h4 p}
$ z0 e& b/ q- K( S& B9 W& X2 M: T! C
% b  ?$ ~4 h2 a0 ]void        APU::Sync()7 A; S' M/ Q, K/ v( D' c( M. l
{7 u* \* b& q2 w: f: g3 z3 C3 N
}1 M. X1 Q( Z. g3 W) \( v) B

: ~4 Y7 Q9 _5 Ivoid        APU::SyncDPCM( INT cycles )
1 f. x9 B! Y/ ^7 v6 ~* H$ Y( r{7 [; e* {1 U% y8 j" e5 k8 h
        internal.Sync( cycles );" s, N) S) g: K6 y) E" \, @' e) U4 c
, m# p& i4 C- |" j
        if( exsound_select & 0x04 ) {" ~4 q  J" h0 d
                fds.Sync( cycles );
  s6 i; f! D3 Q8 j5 T( O; i        }/ `2 \: K! l" ~! `4 K
        if( exsound_select & 0x08 ) {
: g' _& H8 O- l+ ?" ~- Y( a' z                mmc5.Sync( cycles );
  t9 g3 J2 T: g/ x0 k        }$ f" n& H! h  \0 q3 s! s
}, n9 s  T0 O' u6 I) Z  m4 D

8 G2 R, h4 j. b# S) w" h. x! S7 X% Mvoid        APU::WriteProcess( WORD addr, BYTE data )
' D, u% x% I* y4 [$ }, G{# b. G8 r% q" c; J7 Y: c& y2 Q; ]
        // $4018偼VirtuaNES屌桳億乕僩
# J7 w2 T: d/ [) v3 m        if( addr >= 0x4000 && addr <= 0x401F ) {
' p& |. X/ B+ K' |$ T) D                internal.Write( addr, data );. p$ ~: S3 ]5 T- D: E
        }
/ U% I( `# f# M}( d" N9 w4 r/ X  s7 ~6 Q
1 f( u- Z1 W/ p2 H
void        APU::WriteExProcess( WORD addr, BYTE data )
' I. k9 u8 O) P. H! \/ w- Y7 y{/ p3 u" n& |/ c7 x) {- w/ k- O
        if( exsound_select & 0x01 ) {
- u7 _" M; {# r0 I9 l6 T: F& l                vrc6.Write( addr, data );
7 x2 w, N* ]+ W/ m$ S; C/ F4 H+ x        }
- ^0 f6 @) g) y" u8 r8 d: B        if( exsound_select & 0x02 ) {
% F" t5 w4 F* {& k: |                vrc7.Write( addr, data );
( h) f0 j; j0 X  ~% e6 l/ R        }
3 f; E5 V- l. ?  G* @' x        if( exsound_select & 0x04 ) {" N- P0 v( a0 k8 D1 o2 }$ W
                fds.Write( addr, data );
/ F- B, E. o5 S+ R        }
: Z) M/ N! s! K, L        if( exsound_select & 0x08 ) {+ t; o. b$ v9 m' B7 V0 ~
                mmc5.Write( addr, data );
/ x" d3 E; L; Y& ?, O        }
5 M9 R  m# J6 A1 [) L: F& j        if( exsound_select & 0x10 ) {
; c9 e& @5 F) ^( i- G4 B3 e! }                if( addr == 0x0000 ) {
" ^& Y& A# J: y' I) a1 N% f( J; C4 F% ^                        BYTE        dummy = n106.Read( addr );
$ s! k- i- W5 X2 S- `                } else {; \1 M6 r" d- d% @/ S
                        n106.Write( addr, data );# q& Z7 N: N1 p
                }
1 r0 s8 e& K3 d        }
$ O- T/ P: C. G8 L8 M1 W4 |7 Y        if( exsound_select & 0x20 ) {1 O2 Y) E8 I2 q8 w8 c
                fme7.Write( addr, data );
; s: v* u6 C) |2 L        }
+ `8 H+ A0 G$ Q5 K, T7 E0 k}. C8 k2 \- ?: D" O/ }
9 h4 d; b& A" P3 q, ]  o
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )  x7 {: B/ ~! U- Z
{# g. m. I- W3 {1 ]
INT        nBits = Config.sound.nBits;
' N7 ~+ d( D7 n$ O: s3 ADWORD        dwLength = dwSize / (nBits/8);3 `# h% _: y( z% ~$ {
INT        output;7 u. Z/ V# }2 c
QUEUEDATA q;
+ Y: [0 n/ U/ W3 q2 M0 vDWORD        writetime;
9 X% I  w' D$ Q% C* e0 g( X; t; q: D8 i
LPSHORT        pSoundBuf = m_SoundBuffer;( \! W; Q; L8 A  |  @, p
INT        nCcount = 0;5 W' Y/ v4 W6 @: V
: S. p5 c/ f/ S
INT        nFilterType = Config.sound.nFilterType;
$ y- }) Q' d# o. K8 X, K
& m( t  F- r$ M3 B; Q% W        if( !Config.sound.bEnable ) {
: w8 M% K. k) M0 a+ w                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );- V# T" e  e5 y5 o* {
                return;8 f; V2 t( c4 Z: x- y  [
        }
2 k9 y; Q) D) f8 h
8 K- B5 a6 y+ H        // Volume setup$ C+ C& I7 n( x5 q0 f
        //  0:Master0 F9 S  L( O0 R2 D9 O% E% H# s
        //  1:Rectangle 1% `1 x& l9 i8 }; A+ U
        //  2:Rectangle 23 e) X( N" s% E: h
        //  3:Triangle7 N: o2 W/ T, h
        //  4:Noise3 V- \7 r0 Y2 |
        //  5:DPCM( U9 y! R" G! C4 M
        //  6:VRC6$ @5 v7 _" r" ?, k7 r3 V
        //  7:VRC7. K- B# Y( F7 M6 {
        //  8:FDS
# A4 O" M6 |5 C" `        //  9:MMC5  Z+ q6 ]$ n7 B+ T
        // 10:N106
( k" k; y" `4 A4 i% @) R        // 11:FME7& E- v1 Q( u  m3 E
        INT        vol[24];
6 T" a$ q$ g1 {" ?0 f) Z' @        BOOL*        bMute = m_bMute;9 N! m! s6 F8 n$ D3 K1 w
        SHORT*        nVolume = Config.sound.nVolume;
4 @' q/ i6 r+ D/ z7 `# N
0 ~, Y* c) a1 d* S        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
0 _& p4 {/ ~& m1 e) G, O. m0 j) l5 O3 R5 |
        // Internal9 c9 m+ V0 {# L0 u) x1 y
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
% ?  s. Y; v- z$ w! X        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;# P/ R  W1 `4 A
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;: j3 s/ e3 |% q
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;6 Q4 K# `& b" w4 e. `' T
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
- c. o% @$ F) P3 Y( s! B1 j1 g4 P% \- A
: w4 j/ K. q0 R$ a& V' Q4 s8 F        // VRC67 v; L4 h$ n8 l4 Z9 H% n
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;: P5 z- c- f, D( [4 V
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;8 w. _  `( N: T) q  ?' N% c* C
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
/ M9 n1 R# b8 A4 V" e" R
, r& V  |$ `$ L2 v) a$ X7 M2 B, h5 t0 E" n        // VRC7& Q3 R% S6 q3 F7 E- @% I
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
1 \* h. k$ ~% q- I; v6 e" z' P3 r5 P3 p# d" h5 G* _; K
        // FDS& p" }: F" Q$ `1 V- T9 V. s
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
2 D0 y4 H$ _" p% e$ I; r1 f+ ]0 i& |, {  z+ q0 {+ m1 U
        // MMC55 p# P, j/ \0 K, J" w# J
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
$ t" b- d( A# w! F) K* N        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
' Q$ M5 |# u4 F3 P  W  V        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;: M" F0 ?7 _5 L. U+ p
6 ]1 w# ~" f/ \" R! ?* _/ `
        // N106
; ]  F% s2 B( Y5 x8 I0 H        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
* G1 U# M9 n& K* a  n& y9 H- @5 L        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
! w1 r2 E2 Y# K) p6 j) y        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 q  i2 c2 W: h  x& q
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;: s# r5 H; t! S2 g) S
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
! M& u; n# Z7 B6 L        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- K& d! n& A6 [- }& R/ `. O        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& U$ `2 d7 C7 a5 e" u8 c/ Q% ?3 I        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
* L3 T( p. }" ?
' T& f! [. Y9 X, s' c$ _        // FME7
9 x4 s8 W6 Q! K        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
) E3 m  O. L4 E9 ^4 ?/ S2 q6 V        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
" F" h; N2 Q9 R7 v1 h# c. y        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;9 W+ W3 w; t' N' O

6 a4 I# x4 h+ G* _; s//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;2 F5 C: ~9 L' E! |( ~& Q
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;+ ^$ s+ a% V! s1 A4 Z+ [! z* O) }: J

/ L& N9 a/ p. c        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
2 J/ w6 ]: M9 u+ P# p3 e; i* t        if( elapsed_time > nes->cpu->GetTotalCycles() ) {! J% P! R& y* s1 u
                QueueFlush();; T$ ^8 [! a6 Y* e$ [5 P
        }; R, h6 B' {: l& g

. h9 o; N1 Y8 n5 Q; `9 W; y        while( dwLength-- ) {
& O  y! ^9 B+ [' g, x2 c                writetime = (DWORD)elapsed_time;0 B  M8 c) b0 P( G% Q) u
& F( s+ W5 ^5 Z; \7 |8 O
                while( GetQueue( writetime, q ) ) {* J1 n$ \6 [2 P9 ?
                        WriteProcess( q.addr, q.data );  _( w  O; A! L. X) r
                }/ P, Z7 _) B9 t) |  S9 S5 h6 [
( G! {9 K8 X! F0 A  ]: N7 S5 }$ T
                while( GetExQueue( writetime, q ) ) {6 U$ C( ]+ d6 ]6 E
                        WriteExProcess( q.addr, q.data );
) M$ i9 S# \3 O; h$ Q6 ]1 i; g                }
0 @7 s( K* C" @; D3 f, j+ N4 {" @0 B; L. _9 {* r0 o$ k
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
, |9 j6 {0 _& n6 o1 S7 o                output = 0;! j) ]0 c; m) _: c, S$ W
                output += internal.Process( 0 )*vol[0];
$ b7 b7 P0 d$ N& Q  v1 o: {+ f                output += internal.Process( 1 )*vol[1];& r6 {3 y0 V" L. S8 d
                output += internal.Process( 2 )*vol[2];
0 x7 o" ^* {8 s* a' q/ `                output += internal.Process( 3 )*vol[3];( _% D/ g2 ?& }( W% t
                output += internal.Process( 4 )*vol[4];
. R1 P6 P& S* A* d) @* m; f
: L; z4 M! K* ]                if( exsound_select & 0x01 ) {
4 F4 j4 \7 f% i                        output += vrc6.Process( 0 )*vol[5];
1 C4 s) Z, F( D9 |, l! z. M$ w                        output += vrc6.Process( 1 )*vol[6];# @, {+ b9 V+ T, N6 v
                        output += vrc6.Process( 2 )*vol[7];
" v0 \" n1 O+ ?! ^3 W0 l- n0 ^                }1 U+ r& [" I1 |5 V) e- L
                if( exsound_select & 0x02 ) {
: o( w) n* ?. j+ W                        output += vrc7.Process( 0 )*vol[8];
+ v+ B, u# x- J  S* f                }+ k! y  T0 [* r# y! y
                if( exsound_select & 0x04 ) {! c* a* j7 p3 S5 m$ |# d
                        output += fds.Process( 0 )*vol[9];
" q. p( ~/ F' e) R/ [                }
: v. j1 ?) ^" C3 S4 d0 G% a                if( exsound_select & 0x08 ) {
7 s& M$ C; D2 J6 f% o: u                        output += mmc5.Process( 0 )*vol[10];, |6 R$ S2 W: r- }- w
                        output += mmc5.Process( 1 )*vol[11];, h; m9 q$ U* y! N' C8 L
                        output += mmc5.Process( 2 )*vol[12];
! o! E6 `- W& w. c                }  ]9 [! T8 P2 i3 d3 z; \& x, }6 v  [
                if( exsound_select & 0x10 ) {
1 v3 Q0 F5 N) N0 ^/ n% Z                        output += n106.Process( 0 )*vol[13];* d% W; S* }$ V
                        output += n106.Process( 1 )*vol[14];
" p* G' x; g5 c' l- a+ `                        output += n106.Process( 2 )*vol[15];* `. M6 A5 K; v$ @, j
                        output += n106.Process( 3 )*vol[16];4 x9 W; j9 f. n" G9 ~% `
                        output += n106.Process( 4 )*vol[17];
: k  e' t7 K8 ^; v. O0 @9 w+ [2 G                        output += n106.Process( 5 )*vol[18];. O4 e! k! X0 s8 Q: s
                        output += n106.Process( 6 )*vol[19];: J+ o* |9 t5 S1 f8 q; ]
                        output += n106.Process( 7 )*vol[20];
- i& v3 Z2 y8 T# }8 Z                }; H3 A) s7 y6 `* j/ T5 i/ `
                if( exsound_select & 0x20 ) {
) p; m2 h, K! s                        fme7.Process( 3 );        // Envelope & Noise' t9 B2 C5 _: ]
                        output += fme7.Process( 0 )*vol[21];6 F) @9 d" o( _$ [. k+ N
                        output += fme7.Process( 1 )*vol[22];# G7 e& z6 r) a# [9 o' R
                        output += fme7.Process( 2 )*vol[23];
' [6 y: Q, P0 A8 N7 r" \4 b2 e0 }                }& d* g  s  G( H$ R; k6 ^

5 Y# L2 ?7 s' [5 u8 z( v6 p5 f                output >>= 8;
4 p+ f8 W. E+ B$ E. Q( P8 b1 T4 @3 c7 i
                if( nFilterType == 1 ) {
, Z4 `% j' B4 `3 [) ^2 ?: u. K; K: t                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
8 S8 I. }. v9 z, \8 b9 N1 l                        output = (lowpass_filter[0]+output)/2;$ |" Y" z2 b  J  w4 ~' l# Z9 J
                        lowpass_filter[0] = output;# c/ x  n) E3 u7 o7 w
                } else if( nFilterType == 2 ) {
$ P0 m9 R4 h8 K                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
5 d8 Z+ b% J/ |1 E                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
# u% g+ C$ O# m8 q& v                        lowpass_filter[1] = lowpass_filter[0];8 t4 |% R' A" O; w( |9 e7 U
                        lowpass_filter[0] = output;( s) `2 [4 w0 ^9 n+ F# y
                } else if( nFilterType == 3 ) {
5 x0 q7 R, I7 `) y) k                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
4 g* z' b$ B( [2 C3 |4 D4 `2 f                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;: v0 v1 l/ M0 Y" a
                        lowpass_filter[2] = lowpass_filter[1];2 g/ l/ s7 l( f, g$ T  c
                        lowpass_filter[1] = lowpass_filter[0];
$ `: G& U3 P5 P                        lowpass_filter[0] = output;7 s; m. U" S, r
                } else if( nFilterType == 4 ) {
3 x- I1 w7 A% P4 O                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)6 m2 C' r2 R7 e* [. t
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
# |7 I) h& ?  C                        lowpass_filter[1] = lowpass_filter[0];
* Y( W0 V6 _+ f: c                        lowpass_filter[0] = output;
, S; S  v$ y8 x, N/ J                }
/ Q7 _! J! L9 f" W& ?
, n1 L2 J% a) \, K" ]" a' \#if        0' L% E( K3 S3 X2 [
                // DC惉暘偺僇僢僩; h( q7 ]9 H- L
                {" M* R0 d. x9 \) J; I
                static double ave = 0.0, max=0.0, min=0.0;
% `4 X- p$ a- d! \; i, T                double delta;
) C  c# n! z& ^$ z* Y                delta = (max-min)/32768.0;0 z6 ?5 t- ^: _9 |* G" p( X7 F! ?1 d& i7 f
                max -= delta;  d; v/ m% e* V0 w3 T" z  ?) C
                min += delta;
& _7 C& q2 D2 @1 i- D                if( output > max ) max = output;
4 t1 s  l: k1 I. v' v7 \! V                if( output < min ) min = output;3 T- w2 N" D% Y9 V5 q
                ave -= ave/1024.0;
; O# |: R. ^$ z( l                ave += (max+min)/2048.0;0 I3 a- c" F) i: ^
                output -= (INT)ave;7 k: H) K6 F; k1 G
                }
) X, X0 V# E% R; ~: s4 J#endif
4 H  F* |! {# o#if        1
8 x* m! v' T5 M, l* f0 ^                // DC惉暘偺僇僢僩(HPF TEST)4 c5 o) E) q0 d/ |9 I, ]7 c7 b5 _
                {) p: t) y3 f; @
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
# A+ g7 ?# w$ Z3 S7 X                static        double        cutofftemp = (2.0*3.141592653579*40.0);% ]. u: G: `  B3 s
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
# m/ r9 C" K& A( R( x' ]                static        double        tmp = 0.0;3 l- E* g) N, d0 A% C" U: j' \
                double        in, out;; \/ x3 d& _: C2 K$ _& M

0 K5 c$ p7 t$ W! A. K0 D( o                in = (double)output;
. v5 W1 a: @; O8 g% d5 T; U                out = (in - tmp);
2 w9 M8 b- b' Z                tmp = tmp + cutoff * out;
% A( j$ Z" O+ {" h. q6 S( b/ d  S( u
                output = (INT)out;
- M7 Q* t& A& T( |( {- Y! M' C3 H                }
3 p# G' A1 b; f5 y) J( Z+ ^#endif
4 V" t. X1 b" n8 _1 n3 X; P& b; ^2 V8 @#if        0
2 N- N0 o) x9 X2 T& P8 `                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
0 G; Y2 w. U0 f3 f# S                {
2 z3 h# V) g9 M$ Z' B9 U; C% S! f                INT        diff = abs(output-last_data);
, W- T. [9 r& m: v9 a" [. k/ l                if( diff > 0x4000 ) {# A5 m% ?0 M1 y$ R( m
                        output /= 4;6 ]; L$ l# R3 Q( \/ Q# m; m3 x; F
                } else
1 o% g0 k( x( {+ w( I3 ^                if( diff > 0x3000 ) {
6 g+ B2 _  y- J& e. g9 V4 J                        output /= 3;
) r* P+ @9 G* n6 _' w                } else( f& \3 t) a5 j% J
                if( diff > 0x2000 ) {
7 A, H! P8 |) y1 @  S                        output /= 2;/ i0 _- D' l( z5 W4 }5 ?
                }" s6 ?0 M9 M) k) Z- S* R
                last_data = output;3 j9 I+ x7 d# i/ t; K, z
                }  d" M. M: v7 c& T6 k
#endif
; Q* q, [/ q) C. z) O% n                // Limit
, o" e. t! j5 ^7 i7 s7 m                if( output > 0x7FFF ) {. U+ U9 o" P# N
                        output = 0x7FFF;* C) Q/ S% f9 ^/ L2 V! t
                } else if( output < -0x8000 ) {
$ I8 M$ {0 w: e$ t8 i                        output = -0x8000;
% [' l$ b4 l/ B                }
6 ?, J; k' v* ]2 h: \
0 V  W( [/ R" E4 u7 E8 O8 L' f                if( nBits != 8 ) {
3 b- a0 m, ]& z8 V# h: u* n                        *(SHORT*)lpBuffer = (SHORT)output;6 p3 ^7 x+ H1 A0 G* T
                        lpBuffer += sizeof(SHORT);
8 \# s  x2 Y2 W: V# p  ~                } else {
& B2 q' d/ R* q: c6 c. p                        *lpBuffer++ = (output>>8)^0x80;
' V7 b5 @4 k( s: s- u                }0 G' D) j8 ?$ m6 [0 j- ^0 ~
. q& Q- }, I$ {9 S. E7 k  r
                if( nCcount < 0x0100 )7 x& C  x- T$ r
                        pSoundBuf[nCcount++] = (SHORT)output;
, A6 K0 ]9 C, |# R7 b
; j0 v: e8 M+ P( O% q2 U0 i7 F//                elapsedtime += cycle_rate;6 F' h) K' J0 n( Z: ?8 k
                elapsed_time += cycle_rate;
/ q  q4 h$ H. u: d( ]" d        }
3 p+ E* [. R/ d! X
1 R$ q5 u+ {$ u  y( E, d#if        13 ?2 H* R- C; [% |
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
* a/ i1 ^1 s% Q% |6 `! |                elapsed_time = nes->cpu->GetTotalCycles();  {" y5 k( U: j* m1 `+ ?. @
        }8 I  z5 a3 S* H5 Q: v
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {8 a& `, h6 Z) k. ^2 f5 K7 D
                elapsed_time = nes->cpu->GetTotalCycles();3 w/ }0 l' B% p( R  q
        }
4 }" T2 Y  B. {8 s& _  [#else
7 k; p  @  n5 r% O8 ?6 R* R* _        elapsed_time = nes->cpu->GetTotalCycles();
# Q6 B. ~$ ]9 F& {6 C#endif+ J' d3 A) n( m5 u5 A/ P
}. S( ~) ^% {: e. R* m

0 N% y8 C& ]6 V* G7 b. O0 F) T// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
( Z& ~* a* w- c( PINT        APU::GetChannelFrequency( INT no )% G) ?; g' `) Y) I" C) E; n( q
{. K1 }  C% r  ~6 U  t
        if( !m_bMute[0] )) G; H* [( T5 V
                return        0;
+ g# x5 a* B! _9 h, C9 M( u; y7 K5 _6 ]$ H
        // Internal
, N9 ]( L$ ?3 Y9 F9 B: h' E        if( no < 5 ) {1 E7 h  b9 i- _; M
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
5 Q3 I* f& a: Z0 t- x0 w        }! h7 I& M) o) |/ V# W4 Q3 k- {
        // VRC67 X# w( C3 k: F
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
7 @) o% |4 {1 V                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;+ m' n4 f5 K& {$ c: B
        }
5 H; _4 I9 C% w$ H8 k( E1 j# z: z        // FDS' n4 y7 e3 ~! B( {1 {/ b7 |
        if( (exsound_select & 0x04) && no == 0x300 ) {
) e% Y4 ?" n# W8 T0 N                return        m_bMute[6]?fds.GetFreq( 0 ):0;7 D  F  z: R1 q& r- h
        }
7 A, N7 @5 }2 e! p5 R1 K. E* X        // MMC56 n- P- Y1 D2 H( y
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
6 y6 h) T4 }' l2 ?' z                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
: U/ Z! k4 c$ y7 @8 u4 H        }
1 [1 V3 B8 V! L# S" E; o        // N106# ^5 A9 a' c. K; |" B. @
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {8 w. }* B' ]/ A, J% P/ M2 _+ e0 P
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
  T( ]4 {7 ]5 B* f$ ^- g        }
0 X1 o8 u+ R6 i2 F9 p! K        // FME7- r& h2 }; H: S
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
7 z2 b& H( ]% M, e: w* L                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
2 _2 E- J& m6 y& c, u* u$ o        }- X, x" l5 P) `* C7 n
        // VRC7
( x) c, o" y; {4 V" U' E        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {# l! X) k; _& c$ c( W5 i
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;2 I6 G8 B5 g2 q( n- c0 f! A
        }. K5 J% I5 I3 T" D5 U0 c+ d8 K5 t
        return        0;
- ^& @2 `) ^1 J- f8 s2 n9 r( @}
" O2 s8 m* Q8 ]0 E! H- Q! R2 I+ H- ~2 \3 @0 V, W* B) l- y- @, f, u
// State Save/Load
7 }. V( v' z9 p/ d7 Svoid        APU::SaveState( LPBYTE p )9 R0 r  m3 i1 b& k
{
5 r2 R. _* p+ d6 N( w* `+ a#ifdef        _DEBUG$ s. D3 u4 v& e# K3 e
LPBYTE        pold = p;
% k+ }2 y7 m7 _- ]#endif8 j4 Z* T, \4 H9 v

- [% L, z1 j. R        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞9 }$ b: s) F& I7 y0 r. @! S
        QueueFlush();
& H# v8 S- J$ Q/ V( r
! k3 X2 Z9 N, F/ m        internal.SaveState( p );
* T1 D- o3 Y+ y5 M2 q% U        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
9 {. R& i7 i& l" ?
0 a8 d# Q8 O/ ?) {. W2 Q& K9 e        // VRC6
# i: O) B; N$ B  O# }! g        if( exsound_select & 0x01 ) {* x8 _1 _- W8 w# D% i3 L/ X+ J3 `4 U
                vrc6.SaveState( p );
. v* Q! T3 X' c. [2 y- R                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
" B+ {# P9 I0 a' I        }
# R+ P+ g) `" i$ H. L2 _        // VRC7 (not support), p( s$ a! Y$ r
        if( exsound_select & 0x02 ) {( n' \0 I6 {( L- |+ |
                vrc7.SaveState( p );' B; Q* r/ V: ?8 B
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
2 \- Q* N" c6 E7 \9 K        }3 a# p+ O$ N3 }+ f' _4 M
        // FDS
$ E2 X; {5 j; ?        if( exsound_select & 0x04 ) {9 `, A- H! R( e9 ?/ ~; G- p
                fds.SaveState( p );
. H( A$ _2 m" v3 _4 \- \                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding( q9 F) Z# `1 M1 {
        }
) L  S% v+ U! `' g. ~        // MMC54 k7 k& c3 D& o
        if( exsound_select & 0x08 ) {5 d) t7 ?3 N) ^, ]
                mmc5.SaveState( p );$ W' s0 {# x9 h" D2 n/ e
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding! q& c7 X/ W! S; I
        }2 i' F) _' V4 d( e2 s
        // N106
/ j7 y5 u: ?9 j0 _& X        if( exsound_select & 0x10 ) {
1 @9 O, J/ r8 E4 ^" V: C                n106.SaveState( p );9 i9 N' |" a# S9 ]7 U  k1 q7 `  {% h) ]
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
- G- r+ I% [% }' N6 j5 K: B1 T        }
1 T* Q5 \+ m* Q) D        // FME7
  ?7 I8 S6 Q9 n, P% S: ~- A        if( exsound_select & 0x20 ) {
* u6 s! K% @! L: _" Q                fme7.SaveState( p );) c7 p! O: T# P/ n  P* g$ S  D
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding7 H$ n, z3 B: o* a+ \( A
        }0 {* ~% z$ R2 S' c

% a( Y$ o; M* j; G#ifdef        _DEBUG. T* l- v* K; S; |# E$ e  L3 N
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
2 h# U: _" C8 {* d* ^$ ^#endif6 D, A1 B5 K8 z* s3 \% P
}$ n( ^2 [+ X. P( E
3 J4 }1 N7 v5 }) ^* w, U2 f
void        APU::LoadState( LPBYTE p )/ ^" L; ^  U5 q3 W, }) I% o  n
{  \. M; O, p& K  ]
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
0 _# i" W& q# _/ z$ |, i- L/ q# @        QueueClear();
$ A0 E3 ?4 }1 ^. A! S, A. p; j- W7 G" w: w( b
        internal.LoadState( p );
3 l- `; M9 M! m2 T) s6 ?: L        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
. x8 Q! R) {- s; H9 B& I7 z: d4 ~; N
3 a/ e3 p2 Z: n$ H0 z        // VRC6
' ]8 l' L. |9 W3 x* a9 G' g        if( exsound_select & 0x01 ) {6 ~% A+ s, e( u/ W
                vrc6.LoadState( p );
$ D  w3 ]! h, D( V# f& R% U                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding) j, L( ~/ {9 C
        }* {& k6 `! N* s9 I; s( @. W; i
        // VRC7 (not support)
- B; A' C) T+ g# Y, f        if( exsound_select & 0x02 ) {
  \0 h) b. U( I  B+ {                vrc7.LoadState( p );
! g* N/ Q, W/ b                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding& f1 b9 Z! c. E1 O/ ~6 m
        }# {5 O/ o3 t9 Y6 x' q1 v  R" n$ d! w4 {
        // FDS
7 A7 ~/ O- I$ q. [        if( exsound_select & 0x04 ) {
# {: r5 Z% R1 K! y2 F  h7 _                fds.LoadState( p );  b  D" y' i+ T9 C, r
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding0 r: s: \9 U. R( _
        }7 ?) g" b0 I* [# d: m
        // MMC5  Q5 ?  l" X5 I+ N+ I' S
        if( exsound_select & 0x08 ) {
$ ~; e6 \# F, n                mmc5.LoadState( p );
" {7 Q* J4 m& A4 n, M) Q                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding. C! U4 A2 j7 r6 _
        }
) t9 z8 O# D! M& R9 K" }        // N106& ^: e  s# k4 k2 X2 U9 n) ]- {7 E
        if( exsound_select & 0x10 ) {. a# R& X  ?- Y) T% [
                n106.LoadState( p );
4 p$ ?$ S2 a6 ?* g. N! P                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
3 |/ F4 H& G- j. s        }
# V$ }* ^/ g* ]9 ~+ W, ^; W        // FME7
6 b7 F6 U* W% p5 l- O        if( exsound_select & 0x20 ) {) t. U! q6 h  `& J. P
                fme7.LoadState( p );
0 F, Y8 _+ X, Y9 s- [                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
& ?/ K% N+ k9 l8 X3 I! l        }  h& K- ?2 _& z9 u
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
5 m* g( p' i6 @% Q, Z' ?可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。) M5 h  N4 C  |
感激不尽~~
( _0 O+ U$ c2 L6 Z4 p
恩 我對模擬器不是很有研究,
# z, ~5 E+ a* x% r& T: ]& c! e& [雖然要了解源碼內容,可能不是很困難,' v( K! H3 n" G+ L3 E
不過還是要花時間,個人目前蠻忙碌的。
9 t6 p+ s2 g# W" t, m+ H7 H
( q$ `: V, r3 I2 k- ~3 N給你一個朋友的MSN,你可以跟他討論看看,
- E$ i0 @2 ~) c他本身是程式設計師,也對FC模擬器很有興趣。1 p! M3 j* w# R' N# ]+ j
8 ~  F/ \) n+ c4 u+ z2 \
MSN我就PM到你的信箱了。
  _, C7 H% @* r8 C! E$ i5 }) I6 A6 O) o" i+ O* J
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 ( m$ A& B4 k" w. x9 ?% y( N, a
呵…… 谢过团长大人~~

+ P+ ~! E) w. X2 p
1 N  F& B( K. |' c! g哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
, K# n) d0 h/ O6 ^; i团长的朋友都是神,那团长就是神的boss。
, Q- P: k( ]7 T
哈 不敢當,我只是個平凡人,- k; x0 b8 K& O: E; d; @
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
, a# [5 Q3 K8 d, n3 a4 zZYH3 [# S3 s7 t4 B$ J0 J+ R/ H
QQ:414734306
( Q9 w3 J7 B; aMail:zyh-01@126.com7 Z; m1 Q( j. F8 n% z
; P) _* }7 k) y/ U9 O4 R
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
: v: c/ Z* e  N2 F% J% f7 H再次对团长大人和悠悠哥的无私帮助表示感谢~~
- i; b/ C1 E; x! x' t
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-14 22:56 , Processed in 1.073242 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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