EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。+ v5 \0 {) ^  N  b1 o
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
( v/ M0 N3 c+ |5 ^这里有相应的模拟器源码,就当送给大侠了~~
$ q0 @8 D5 [( B" _: f. Q# d* yhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 0 C: p& Q5 W( e, O
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。! U. h0 J3 E8 m, `
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
+ A+ h9 n5 P: z& Q这里有相应的模拟器源码,就当送给大侠 ...

! J' o! S: l+ F" Z聲音部分(Audoi Process Unit = APU):% Q9 K/ O( c+ m( N5 d* t1 J
.\NES\APU.cpp
7 C/ k( L: d/ t3 j7 ?4 K0 G* L: S( W.\NES\APU.h/ k8 f( i5 Q" @, n* T2 `
3 v: @' l0 M7 X) Z9 e: [6 W

1 [4 a0 {  @4 ~* @- [影像處理部份(Picture Processing Unit = PPU):/ s, w: y* j/ z7 h) L0 J" A" `
.\NES\PPU.cpp
$ `* V! M' C4 T8 f.\NES\PPU.h5 P( `0 u. R+ z6 e6 A
; p" e; k- `* B: w: c9 Z
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
7 B4 Y! @" U& M& e& L+ V) c(由于很多专用术语和算法机理都不明白,所以看不大懂……)8 U, n5 A+ C; V/ [
//////////////////////////////////////////////////////////////////////////
- _( R/ M& f9 A0 W//                                                                      //
! O. |- I# I' X+ G, X; t# r//      NES APU core                                                    //% z# O3 r* ]* z3 i( `4 C& ^
//                                                           Norix      //" w9 ?9 o/ @) A, n9 X) G' j
//                                               written     2002/06/27 //
5 w1 |7 y9 m- K0 |1 Z! p8 [1 w//                                               last modify ----/--/-- //% W1 t1 t3 V8 X& ]
//////////////////////////////////////////////////////////////////////////  P  G8 W, h, A. q- M1 V# L- a/ ^6 s" S
#include "DebugOut.h"
4 r# B; c, M# U! P& ?#include "App.h"
6 E) E* e( Q5 Z#include "Config.h"$ j+ |2 N3 F/ Q4 i' X+ _/ q  B3 b) X

1 M- d% s: A0 T5 W7 }7 m#include "nes.h"
. _' w5 p6 c) |" Y4 j#include "mmu.h"/ C' E: I  @( G7 Z% B. I
#include "cpu.h") y' m  G! f! P( Z$ ]( Z
#include "ppu.h"
* [3 P- ~$ T9 G#include "rom.h"* x  B9 V) i  l
#include "apu.h"3 h! }1 G8 ]0 d( {

, r9 a3 z  }" q4 v% `8 y* r// Volume adjust
4 f) d' D) X* B3 K8 _; y( c// Internal sounds! W% {2 U4 h5 {. c- L, P4 k
#define        RECTANGLE_VOL        (0x0F0)4 o: X7 l$ [6 y. Q3 P# R
#define        TRIANGLE_VOL        (0x130)# [; c+ L; {( _& t2 h. t' ~/ ^
#define        NOISE_VOL        (0x0C0)
9 e) t, k4 T) W#define        DPCM_VOL        (0x0F0)6 L. h, i; o/ j. D$ \
// Extra sounds* Y3 K: B1 F0 s( p+ S
#define        VRC6_VOL        (0x0F0)+ a1 k; ]+ |' ~4 ?
#define        VRC7_VOL        (0x130)
* P* G+ ^' k. v- G; p#define        FDS_VOL                (0x0F0)3 P7 y2 {) s: U- e; u/ g# v; k
#define        MMC5_VOL        (0x0F0)7 L3 y5 P! J: c: C- q: c
#define        N106_VOL        (0x088)
1 F" Z( z% [- L0 O#define        FME7_VOL        (0x130)
2 l  S1 [7 S+ V) @- U! U" x: i
: @! G0 h: J$ `APU::APU( NES* parent ); s% |+ T2 N$ r9 R7 a- ?
{- b2 I) i( ?# l# c9 e$ c0 N/ @
        exsound_select = 0;
1 c1 l% f& c9 S/ g4 V) q+ o" k+ p6 l, ^+ g! m2 U& n( W
        nes = parent;( C' A8 R5 v' X: @$ o- l6 M
        internal.SetParent( parent );9 ], Y  b* |) O  ?  B! x; L; [. q1 r

( e. h1 {, m% O        last_data = last_diff = 0;
; `# X! `; i' H6 D: q- S& }+ x  E  V4 x+ u
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );* k1 g5 ]+ w3 O: f$ _+ ~

0 r, X# r, W% S6 \, ^        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
5 k  Q+ a5 [' V- G7 t1 o        ZEROMEMORY( &queue, sizeof(queue) );
1 x# J0 K& c: J/ U# \        ZEROMEMORY( &exqueue, sizeof(exqueue) );
  Y9 d( o; I& d6 ~9 A6 t7 r) {: h2 W/ a8 I/ e) p. e+ Q: `7 T
        for( INT i = 0; i < 16; i++ ) {
/ F& Y7 E4 O: w2 A; V                m_bMute = TRUE;9 q! d4 N: m# @
        }
, Z# V9 y/ @2 I' r8 E8 ?/ Q) s}
- A, c& M9 ]6 J- ]3 g+ @
0 N* f( |0 w$ s/ z+ [/ z- nAPU::~APU()+ Q6 k# _, A5 }
{, B7 \! i/ U1 p2 L8 [
}6 Y! T: [& Z. d3 ~8 r+ \

3 q& F7 E# J1 b4 z! G9 I4 Cvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
/ r3 @/ V# V* ]" |{) L- R! o, W: k( j! r
        queue.data[queue.wrptr].time = writetime;! v' o7 o& o1 ^  E8 X5 a: z
        queue.data[queue.wrptr].addr = addr;& O* ]6 i, T/ X5 y& R
        queue.data[queue.wrptr].data = data;% j+ u- l# D- A/ Q# M: x/ ^/ b* ?& B
        queue.wrptr++;/ _$ a0 `  L* v* E
        queue.wrptr&=QUEUE_LENGTH-1;
8 J9 Y0 Q: R% `# _        if( queue.wrptr == queue.rdptr ) {
+ B  {- R: x7 @. j9 \+ B: `                DEBUGOUT( "queue overflow.\n" );0 K$ q% u: ^& c- ^% x( W4 y# e
        }& g! Y. _$ T+ T  ]) t6 v0 y2 m
}$ q2 |4 W: y% Q, B, O0 O2 j

( x0 w. ~6 k" E% V" _8 |/ aBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )3 }6 |- B. U+ R) \) K# X
{3 U; O' Z$ ]" z5 x: `: m& ]- J& ~
        if( queue.wrptr == queue.rdptr ) {* Z; g* h% Y9 Z6 U& q) ]4 E- y* w
                return        FALSE;* H+ j0 w# s/ }
        }0 T' {) ~9 \# i
        if( queue.data[queue.rdptr].time <= writetime ) {
" U: [( Y( _! c0 ^6 B* K& @                ret = queue.data[queue.rdptr];1 C1 |1 F# B) H8 p+ J9 Z7 F
                queue.rdptr++;
  t6 Z* |# e' D. |3 G                queue.rdptr&=QUEUE_LENGTH-1;0 H' N) F; \+ z. q/ V
                return        TRUE;
; d% ]0 g/ y( l        }2 ^) n% A" k" A/ s1 g6 G1 `/ u
        return        FALSE;
/ w0 @6 d* r9 V0 B  _4 w$ d% T}! \, |7 M- V8 r% t- @  @1 Z

$ S  w7 E) T/ |  R* C# Svoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
9 N7 d, I; j" C7 ~3 D{$ G8 N& v; B" N+ K3 ~! F2 O2 w
        exqueue.data[exqueue.wrptr].time = writetime;
2 o# W2 I  i* ~5 E, w7 h        exqueue.data[exqueue.wrptr].addr = addr;
* z# k+ X8 U; B! D0 P% b; o& A        exqueue.data[exqueue.wrptr].data = data;
9 v* r3 j7 W8 n( q8 K( v  A        exqueue.wrptr++;
4 b$ Y& u9 N' u9 ~        exqueue.wrptr&=QUEUE_LENGTH-1;
( F1 D4 u: B0 ?- C! ~        if( exqueue.wrptr == exqueue.rdptr ) {
4 L5 D3 [) \7 |0 a6 a! H                DEBUGOUT( "exqueue overflow.\n" );8 D6 @8 i4 M6 T* a; Y/ `5 ?% t
        }
* ]% }$ |" X- c4 D" e; c; G}: P( j' `8 l* |! Y- f. f: j
( P6 k' C# Z1 U6 q$ Y" {
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
' _$ z9 F+ T# I9 I{1 m% z( |. B* i9 ]
        if( exqueue.wrptr == exqueue.rdptr ) {  P: S9 m9 v2 H7 P- `
                return        FALSE;
  Y4 `9 d& J0 ^$ n9 {% x& O2 D6 _        }0 E# N# E$ o+ b% ?
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
" U% b+ L, t, ~+ n4 h" b                ret = exqueue.data[exqueue.rdptr];
( g/ N* c5 w  T" f8 |1 `3 S  ]9 a, X; ]! x                exqueue.rdptr++;
8 b- y. d/ Z" B" y+ I1 z                exqueue.rdptr&=QUEUE_LENGTH-1;: b$ C; U+ @$ E% ?4 i. o) E
                return        TRUE;
9 Y& S. r' N4 _& A        }7 g) ~9 ^1 ~. @  [* x
        return        FALSE;
2 C" P% I7 Z! X$ ]2 J}
' o' N# L* O$ `
3 c; d; C; ~: a+ X/ {" Tvoid        APU::QueueClear()
# f5 g2 w. }# w: s# P. Z! C{& D5 H- m( e( f7 ^" {& T- b
        ZEROMEMORY( &queue, sizeof(queue) );3 T& m* z+ R$ U  @$ t
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
1 [& t& |) @: K6 {1 d; E}+ t3 Q% N5 S& `! c0 f" ^7 d

" @4 ~% M8 r% Fvoid        APU::QueueFlush()2 N8 ~2 e; O' s0 @
{
% C' U# h; w. E) p1 n        while( queue.wrptr != queue.rdptr ) {
* |" p# p) O. @                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
; r/ ]# j3 ^7 n# C* M4 n2 T7 p                queue.rdptr++;* H/ C2 L6 k7 `% B, F
                queue.rdptr&=QUEUE_LENGTH-1;, b9 F# s! m  l, X, t
        }7 g; C6 b& W* }, o. V# _% ^) |

" i1 u/ E& C. v3 w' U" y        while( exqueue.wrptr != exqueue.rdptr ) {
/ W8 l# q+ H% {4 [/ I                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
1 p, R, ^4 D( v! E                exqueue.rdptr++;- O& O# x; k, `/ a
                exqueue.rdptr&=QUEUE_LENGTH-1;6 V6 R4 }+ i: B/ O) ]8 l
        }
& \4 r6 y, N& C}
& O; W" V# ~6 ?  R7 W) F9 w
. b. {  x4 ]: I6 \void        APU::SoundSetup()
" F& a$ Z7 Q1 C5 O  S" w{* X$ O: a* Y4 ]7 q: J2 r' ~
        FLOAT        fClock = nes->nescfg->CpuClock;! [1 e6 _: w- F8 ]
        INT        nRate = (INT)Config.sound.nRate;
' F) }/ a+ [4 Z# A; B        internal.Setup( fClock, nRate );5 c% c4 G# [2 m/ {, f) O3 p& k, ]
        vrc6.Setup( fClock, nRate );
- H1 g& Q* r, [4 K& }6 t: u- m        vrc7.Setup( fClock, nRate );
  ]% Y: P5 X7 H7 V! b) w        mmc5.Setup( fClock, nRate );( F& y1 c/ X- B& X4 Q
        fds.Setup ( fClock, nRate );
' ^& Q6 S" e1 a# ?( E! i        n106.Setup( fClock, nRate );2 ]* V! _1 Q$ G6 V% r' _
        fme7.Setup( fClock, nRate );
9 C; `& \. M: u6 a}# e; I9 V- p+ p  v1 [0 r

" D- Q; o* @. V3 k$ `6 xvoid        APU::Reset()3 B% e: S7 h$ Q9 O& t5 p0 J7 s
{6 S2 ~* F$ P) G: D( n2 V
        ZEROMEMORY( &queue, sizeof(queue) );
* m) ]9 Y2 ^2 s        ZEROMEMORY( &exqueue, sizeof(exqueue) );# s" ~# ^# y1 b9 d9 P  Z: B

* ~3 Q% ?% T' L& q: ?# U5 w( [7 a! b( E        elapsed_time = 0;
5 ]3 K7 w6 y( r8 F" N; W1 V
2 N9 p  k* H( h$ V. y. `        FLOAT        fClock = nes->nescfg->CpuClock;! I  k+ R5 U- R# E
        INT        nRate = (INT)Config.sound.nRate;
; p2 k1 k! n: T) m; H: t4 c! X, A$ i        internal.Reset( fClock, nRate );) x# j  k( w% J! d
        vrc6.Reset( fClock, nRate );
8 R9 t$ M' F1 W* Y% B        vrc7.Reset( fClock, nRate );
- G  |; f. l. S' j$ x- j        mmc5.Reset( fClock, nRate );
7 w7 B: c3 A5 I# j        fds.Reset ( fClock, nRate );" L& Q6 T( }$ d3 _
        n106.Reset( fClock, nRate );! e4 o. j$ j9 p0 z0 x  D  O3 v, e
        fme7.Reset( fClock, nRate );5 Y: S2 h; e, z: Q
+ s8 m" e3 m. I/ K& x( k, x5 M% q- K+ H
        SoundSetup();' N1 L" [( }1 o- z! L
}
) v5 a8 }( c) ~. I% Y# ~% w
" B7 |/ j6 o% y7 S- Rvoid        APU::SelectExSound( BYTE data )6 Q* V" K5 Y, T5 [
{
% K0 m: r8 G8 x) L        exsound_select = data;
8 a' ~1 o  V- R}' e7 O) k' v# W0 [4 `' p
4 C! i& `, w: p( Q
BYTE        APU::Read( WORD addr )
+ @9 s# G/ o/ W- ?) F{; E; |+ y: Z# Y- p. @
        return        internal.SyncRead( addr );4 k/ z0 ?+ X! g
}' A" n" _% R% E* z  z/ Q
& G5 {& n1 T8 w6 a
void        APU::Write( WORD addr, BYTE data ). t) M2 s! t' M1 Z9 ?% [: p5 y
{) J& w! K' z7 v/ H# N( ^' V
        // $4018偼VirtuaNES屌桳億乕僩
# b* N. P& Z/ T3 o1 A& i        if( addr >= 0x4000 && addr <= 0x401F ) {
# p8 x* O+ C% }. H                internal.SyncWrite( addr, data );. l% d) [2 w+ G1 O: r
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );' H8 E9 z# M+ k1 E' z2 H, @
        }
: u  l: H6 r1 A  U2 W! Y# Q, W}; \( W& v% W  P; A7 T0 Q5 Z
1 m) `& c  L' b1 z
BYTE        APU::ExRead( WORD addr ), i8 M+ [. ]/ G& j0 B4 R
{; u! y6 y- i! n  i& y
BYTE        data = 0;9 J8 l: y  N; V# Z! ?; |

4 _) u' P( q" i  A6 h        if( exsound_select & 0x10 ) {3 [  |/ K5 j3 I$ P0 d& a! Z  {
                if( addr == 0x4800 ) {+ T' b) h: T' |# ?: W( ?% g* @
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
0 Y( e, c, K. {9 H% r4 e1 w! X                }* o; l, f, G$ F& O. H
        }
/ a: d: E2 [/ v0 K( b        if( exsound_select & 0x04 ) {2 P7 r. S! d) W" s
                if( addr >= 0x4040 && addr < 0x4100 ) {- U; P- n3 w0 H3 _. w
                        data = fds.SyncRead( addr );
; U1 e" T7 l, \  q8 W, M# }. a                }
5 u  b8 d+ G5 [& U6 q1 T        }& K* v, `; k2 E2 U
        if( exsound_select & 0x08 ) {' U  S% |1 \# `& I
                if( addr >= 0x5000 && addr <= 0x5015 ) {
0 S0 l: B* }3 H& D                        data = mmc5.SyncRead( addr );
2 E( ]' @0 L0 x1 \. V                }
7 V+ b9 y, p( ]7 A- g, U9 K        }
& r% e4 w4 I) v7 |9 g7 \
. R. o8 W% [' t        return        data;
1 {) R; x* x. o$ ~- Y& q" r}' O3 e; d$ x3 H# k1 u4 Z

. b" q* S' A9 lvoid        APU::ExWrite( WORD addr, BYTE data )3 h) Z! B8 N7 i) s# r
{
) l$ T. Y& s( T3 C2 S. K# |8 K        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
0 o( p- H. t3 j$ z
6 l+ q& `8 w7 a; f2 d, _        if( exsound_select & 0x04 ) {3 E+ s* J9 D% c' ?, f1 a
                if( addr >= 0x4040 && addr < 0x4100 ) {
: z4 U* k: V' O$ Z                        fds.SyncWrite( addr, data );/ X8 g% C5 O0 s
                }5 F% S6 T# w( v  \
        }
7 R' {( X" v2 O. T5 P( u% \0 l
9 P2 z+ b7 K/ d! f9 j        if( exsound_select & 0x08 ) {
8 M9 }$ n$ u/ t  b$ E: b6 f                if( addr >= 0x5000 && addr <= 0x5015 ) {
* S9 D" M' S3 h7 w. j* n5 g                        mmc5.SyncWrite( addr, data );) ^3 `3 n7 k- H% K( @8 O) L$ e
                }' j4 B* z# J. t# H! L$ ?% q4 b4 q0 W
        }
# U. {8 w2 N( S+ s}
+ n! ]5 p' j0 `- Z) I4 a5 }  s0 [% g3 o# w+ Q7 a" @
void        APU::Sync()
7 U+ u- ^  A# W/ O# O- ]4 U{4 p1 I6 P! P/ g
}  ~1 j* b$ ?) [- _1 E

/ n0 Y, u6 ?0 }  D0 i( i# `8 Mvoid        APU::SyncDPCM( INT cycles )
: t, m$ v7 e0 a4 `/ y, Z; j{  V9 ^7 p2 o8 D
        internal.Sync( cycles );. h7 M- |& u1 A0 g: W/ X. o
& m9 b) x& f7 p1 A! f! ?
        if( exsound_select & 0x04 ) {
  X7 ^' k* r. ~0 x" n; l! J% s' b                fds.Sync( cycles );
4 {( m) ~9 F* s! H0 H8 i+ t2 J        }
# v, H4 S2 L7 u4 I        if( exsound_select & 0x08 ) {
/ w! D) j; b3 X  y7 B* v9 ~                mmc5.Sync( cycles );9 T* c8 o( G/ m/ s4 ]- z+ P
        }4 D2 g7 ]/ i0 o) K+ U# M
}% h6 @1 \4 g# N$ Y* ]5 z

2 Y. x9 W+ ?, b* \3 D- Zvoid        APU::WriteProcess( WORD addr, BYTE data )
2 n! _3 d! t! _! M: h7 K{
: \( U. j* t' N3 V8 m: s% x        // $4018偼VirtuaNES屌桳億乕僩0 H3 O# v( V6 @0 i  Q
        if( addr >= 0x4000 && addr <= 0x401F ) {
4 w. x3 @' y3 O7 T, d3 w                internal.Write( addr, data );" J: {2 Y- [0 N: f1 I
        }& P; p4 o9 \! L' F( M& `
}
% z- {3 _8 M) e3 c6 Q4 `* @- k/ X- y& ?7 W- v- h
void        APU::WriteExProcess( WORD addr, BYTE data )6 R4 P: a9 X" j) L9 P
{5 x0 c* v. E2 G" u! ]
        if( exsound_select & 0x01 ) {
- Q1 B0 `; u) n& h8 X0 L: h                vrc6.Write( addr, data );1 b5 `9 ]3 g& M8 _1 D4 r& E/ u
        }0 M) d3 B8 k& k: t) E7 x
        if( exsound_select & 0x02 ) {
2 B% b3 n% D5 w1 R7 o4 ^' e9 J1 d                vrc7.Write( addr, data );
/ s" V# R. b9 w- q9 k$ r        }
, j. [3 t2 @- }        if( exsound_select & 0x04 ) {" R# }6 ~. M# a9 |/ a" {" s7 J  }
                fds.Write( addr, data );9 h0 c/ X1 ^# a2 l; u9 a; s- @
        }
) B: H  J5 q4 X: D. e        if( exsound_select & 0x08 ) {2 B1 f8 x8 X6 F  u1 I
                mmc5.Write( addr, data );$ F  K# {2 p% |8 _7 W7 r3 G
        }* W2 r& j2 R' d( C) }
        if( exsound_select & 0x10 ) {5 q4 o6 |* h( c7 K" s9 x* k2 `' n
                if( addr == 0x0000 ) {$ Q( D  X& |" A' ?
                        BYTE        dummy = n106.Read( addr );4 ~6 n1 i0 \  ^. v9 A& Y
                } else {  W; T* O: _) |0 V
                        n106.Write( addr, data );* g# i, J4 Y" f: Z
                }
8 H" x6 `5 F7 S; H- [+ L) @        }
% Q8 i( g2 _( m  P        if( exsound_select & 0x20 ) {
+ S- O' a" l! u. m% c$ c# R- r                fme7.Write( addr, data );0 P3 o! l% C9 N) t# t, o, \
        }
0 w9 H- |1 m6 a* x}
5 _/ l2 g0 C- k" ~8 j5 a& H7 |% \9 S
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )% D# t% ?) c9 Q" d
{) y, Q, U! N: |. W" I: P
INT        nBits = Config.sound.nBits;; E8 {! N2 P0 o- P' l/ {
DWORD        dwLength = dwSize / (nBits/8);
/ K2 b' D+ b; L2 `1 A1 a: wINT        output;
9 ~1 J( T, Q% z) O" |' R' iQUEUEDATA q;$ d* {1 |' k0 r
DWORD        writetime;8 ]) [+ T; S1 R4 C% n2 l) n
+ e$ {# k4 \/ Q( _* x7 k
LPSHORT        pSoundBuf = m_SoundBuffer;
2 x1 ^7 O4 @9 I/ p0 t& [( u, OINT        nCcount = 0;
# |( Q- H% e& e) B5 _8 T! `2 l3 w$ c
! c) X$ {7 `7 i% d) I9 D- x0 NINT        nFilterType = Config.sound.nFilterType;
. l$ `) p/ m- E  V3 W5 \
# ?, ?2 g/ d4 V8 P7 V5 K1 J        if( !Config.sound.bEnable ) {$ i4 g5 Y) _  F  Z2 v
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );% m' Z( N7 O, L3 I* ?
                return;
& {$ I5 \% O( g& B        }
$ n) t! a. s3 U# j; `* M( J6 E% y; I5 f) M( r
        // Volume setup1 n' v9 r" ~4 J, ^! H; ]# q6 ]5 n
        //  0:Master) Z9 V1 w9 V/ ^- A, m' ~
        //  1:Rectangle 1/ U: T- D! O2 o8 K" m
        //  2:Rectangle 2
. E9 d3 f$ t7 o1 T+ `0 O        //  3:Triangle
4 C* e1 k/ U' @. H% f" R$ ~& x        //  4:Noise/ I: F) s- `3 |/ R/ k8 f
        //  5:DPCM
% p. @4 k3 q$ c- K/ G- s4 Y        //  6:VRC6) y& f# B, @" W
        //  7:VRC7
( h% `0 F0 v, l; p9 ]" e        //  8:FDS. {% _- T9 Z( y  {8 v
        //  9:MMC5# M- i* H3 p* i
        // 10:N106
) z5 `. H& `6 Z- G        // 11:FME7
' e$ [6 W8 s3 C' N        INT        vol[24];
$ v6 u1 _# z/ \        BOOL*        bMute = m_bMute;
# p( P- z. a8 e$ o7 o        SHORT*        nVolume = Config.sound.nVolume;
' g* C' B! Q, i2 {  t" j- l$ G5 v3 [0 I, e. u. X
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;  I& d2 t# B4 y0 {3 L, B
- r- E9 e- o* C, X' P
        // Internal
) i1 Z# H- Q% d. Z- @7 t+ r! Q- p+ r        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;1 h2 Z9 z% X9 Y
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;% r' \* U) ~6 ~. t2 R
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;: C0 k- N, j+ w6 X1 u" p
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;2 G5 \! M. Z4 f8 w+ L' u
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
# x3 u) X" t9 \) k  H! ~1 `
. v- |- Z  {# s# `8 l7 Y, q        // VRC6) k/ y# m# M6 p( n) J/ N
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;( t. O" W7 |+ }, G$ Q2 R
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
$ h( m' y# ?9 D2 e1 h, C        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;5 n7 c0 Z/ g  D0 x- \2 \3 J

4 j1 O0 K- P2 n+ i* {        // VRC7/ j% \, D* l8 t
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
1 ~2 \: v% J9 d) f9 N* L: D$ x8 B! V% t( ]8 P+ S% {7 H
        // FDS
# J  q8 G2 C9 v+ Q* E+ g' T9 e! N; H        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;( s4 u7 K% W* R$ r; ~2 x

0 p$ p+ p8 i% d3 V! m( c        // MMC5
7 u2 z/ H) n* K3 ^+ X- a# D: t- G" f( I' F        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;: j: F6 y/ [  l( L
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
/ [/ K; d8 y" x$ c  k, m$ X        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;$ v" i# L3 R$ N! Z1 ^* H2 [

7 q4 Y. R& D9 H2 B  p6 N        // N106
  ]% S( A% S/ |% O. }$ G, n! L: ~        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: p. n' ?+ g; Y  @' r# g6 d        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;1 L8 g& ]' z+ ?% i
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;# X; ]" S9 j' U0 u* ^  a
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 ~+ i* g% o1 T' p- Q
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" Q" V0 t7 \; R. W) L& b        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
6 s- C: }; G! {3 f! ]# p7 p) P2 o        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ ]$ w. K# e/ t        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
' z; W' y8 O( d' H+ z0 n3 P9 g9 k. O6 j! `8 k* ^
        // FME7
& H3 R- A1 g5 h; }3 V        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
7 G0 d+ p+ g0 p5 R; e+ U4 x9 |        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;# H1 ~* N0 \% _4 Q& m2 `
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
- ~7 r7 E: j# h3 j+ d2 J6 k
# N$ K5 q% S1 \! x//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
% x1 [3 Q/ D& L' [        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
. M' J! k2 c- ^7 f# t7 a: m7 v$ W, k8 M. n) H: M! x- I5 p) {
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟: H; f1 \. Z% L. A  F# T
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {/ u, F; \" Z1 F+ ]  b
                QueueFlush();
, H% y/ U, e$ i/ S6 I8 u- Q        }
. q! h9 ]: ^  a7 N4 j: r0 o4 a8 Y) K; ~) _' w
        while( dwLength-- ) {
# u/ G. x0 o5 ^                writetime = (DWORD)elapsed_time;- ], k. K% @& R. F7 X
, N- h( B; M5 N8 X$ O0 h
                while( GetQueue( writetime, q ) ) {/ b/ l, _" g3 o, d' V* H
                        WriteProcess( q.addr, q.data );
0 o0 P5 d# V5 ?6 O; S* q                }  d7 \0 K! X) A/ d3 K
0 K7 B. [$ h: D* ]& [9 ^0 M% g7 d
                while( GetExQueue( writetime, q ) ) {
3 O8 L/ D# c4 ?* T$ J2 _$ O% S                        WriteExProcess( q.addr, q.data );
) u! `) g# ?! \& b4 i' M7 x                }6 b7 f0 ^3 p$ P

3 Q- d* R8 w3 l7 P8 `$ V6 @                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME73 Z  A7 i. D, p6 {* k0 w, w% r
                output = 0;
2 w4 S- S* ^5 h                output += internal.Process( 0 )*vol[0];9 \+ g) ?' d( \+ H9 Z+ s, A+ O3 o
                output += internal.Process( 1 )*vol[1];
; A# ^) m8 N. ]! B7 x                output += internal.Process( 2 )*vol[2];5 p4 p1 {# M. F: }. H
                output += internal.Process( 3 )*vol[3];
# \: J+ A% x; ]4 |                output += internal.Process( 4 )*vol[4];. K" `! v, J0 Z* L6 `" v6 s- R; `
# G, h% ?) D: }. C9 ?' g2 P" Z( C
                if( exsound_select & 0x01 ) {6 g; `  R* ]# V, h" V
                        output += vrc6.Process( 0 )*vol[5];5 z/ ?2 w$ Y3 r' X$ Z1 _
                        output += vrc6.Process( 1 )*vol[6];
. ]9 w: A  |: d6 _' v                        output += vrc6.Process( 2 )*vol[7];
, m7 g- {, r6 ^% x% o                }
0 R3 C) [# q, F4 }% T                if( exsound_select & 0x02 ) {+ B" _3 F: _2 W& k) S
                        output += vrc7.Process( 0 )*vol[8];' h2 z; M- s. t% c: ]
                }8 J5 z8 I6 P" I  f
                if( exsound_select & 0x04 ) {
" Q7 W. e3 W3 D7 J( L                        output += fds.Process( 0 )*vol[9];
, Q# l2 q( X$ ~1 P$ k$ x7 U4 B                }1 u  C* w0 ]$ r( v4 M, l" `* Z
                if( exsound_select & 0x08 ) {
8 E- }. p5 m( s  i1 c9 [3 e7 K                        output += mmc5.Process( 0 )*vol[10];
. C& g! ]) m* s  n3 b, n% o                        output += mmc5.Process( 1 )*vol[11];1 Q1 u, |5 F2 T0 ?9 k1 k
                        output += mmc5.Process( 2 )*vol[12];. U  G4 m" f0 J6 o  T# p6 x
                }% y  z8 z  _# X+ H
                if( exsound_select & 0x10 ) {
( [" c+ o2 `: G7 c) ]: [                        output += n106.Process( 0 )*vol[13];" X3 w9 m9 e) y3 N7 W3 E/ [$ e
                        output += n106.Process( 1 )*vol[14];5 T9 r3 u" H2 a% Y! z  b; L
                        output += n106.Process( 2 )*vol[15];( b8 S! M. q5 J& d( p
                        output += n106.Process( 3 )*vol[16];
9 l8 N4 T& x+ S  ?4 _, N, c. P6 @: [" v                        output += n106.Process( 4 )*vol[17];( w; P  Z- y8 z& Q
                        output += n106.Process( 5 )*vol[18];6 J1 U; m. r, a. [3 L4 ^
                        output += n106.Process( 6 )*vol[19];
# Q) Z2 x, g0 v) d! d$ I                        output += n106.Process( 7 )*vol[20];; Z, J3 ?5 S3 e6 S
                }
6 R- H8 L9 U' F                if( exsound_select & 0x20 ) {6 ]0 q  ^, R! }% O" E; B. ~
                        fme7.Process( 3 );        // Envelope & Noise
7 ]  S; s" b1 P+ f7 Q9 _5 a                        output += fme7.Process( 0 )*vol[21];7 Q; b) {# @* e3 u1 H+ o4 }) `
                        output += fme7.Process( 1 )*vol[22];
" ^+ Y. ^( J4 V9 S6 c4 F                        output += fme7.Process( 2 )*vol[23];
6 V" |. Z: u$ R0 }1 f                }
6 w$ B  H  \0 q1 j& a* R7 A' }3 p$ f7 h2 U- ^6 Q$ {* m1 H
                output >>= 8;0 S9 E9 D1 c. B- o1 l
; U+ U# x+ e& D+ a1 g: w9 ~
                if( nFilterType == 1 ) {4 A0 m& \  U" ^+ g' r2 x) }4 b
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)! I& V0 ^: a) o0 b
                        output = (lowpass_filter[0]+output)/2;
; ]. D: ]  O- o) x- a' ^                        lowpass_filter[0] = output;6 m! m6 N2 V: P/ Q$ u+ w
                } else if( nFilterType == 2 ) {* G# J9 y3 `  s: h: t
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)5 h! ?9 ~- X/ S: V; W3 d" N
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;9 z. g/ }1 J$ y( v
                        lowpass_filter[1] = lowpass_filter[0];
& O/ X5 r% v. J. Z4 F                        lowpass_filter[0] = output;! Q$ F, Z, D, [3 Z1 X5 o
                } else if( nFilterType == 3 ) {
6 W  s; }: s: ^6 ~0 ?5 y3 f" V                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
0 T% k1 F0 D9 H6 s# O* V$ y                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
' Y. I# z& U  u                        lowpass_filter[2] = lowpass_filter[1];
8 t+ I" J7 S  c* G2 ^9 \; B. M                        lowpass_filter[1] = lowpass_filter[0];
, Q, m2 q* v1 t2 W& o+ W  {                        lowpass_filter[0] = output;; s9 P! U- ~4 [- Q6 ~0 O
                } else if( nFilterType == 4 ) {* l! k+ y2 E2 Q9 `. y
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
% V9 K! B% r* q                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;* T4 w" Q& Y& n$ N. ^$ _  W, J
                        lowpass_filter[1] = lowpass_filter[0];( r$ @! J% X( A1 J- P7 S
                        lowpass_filter[0] = output;
* O1 Z" l4 o6 J4 @2 i  \                }4 T6 p. o$ C$ B0 |
8 t# g8 G& O: |- D# o5 z
#if        0
4 _; I4 [3 Y0 d                // DC惉暘偺僇僢僩8 k% I0 @" a& b" U
                {
& x! M3 U) T* e8 B                static double ave = 0.0, max=0.0, min=0.0;
6 L! C6 }% r- v7 i' F2 h6 U                double delta;
/ p5 t: h$ E7 h" d4 g1 z                delta = (max-min)/32768.0;2 `+ m, a/ A; {# t
                max -= delta;$ v( Q  S$ f: a. `+ V6 x$ u, W1 L
                min += delta;% e5 f* A- Q! n' s) C
                if( output > max ) max = output;
) ?/ M$ s" R5 w) Z' ]/ y                if( output < min ) min = output;
2 n$ |6 T# E7 Y" Q0 _                ave -= ave/1024.0;
" E9 Z6 R2 E7 ?& W& V9 D, {                ave += (max+min)/2048.0;
. N9 O+ p, Z$ G! X2 u4 G" t                output -= (INT)ave;
* ]" L: `3 Q' w+ G1 a                }
( x# \! F8 c( F+ n: y/ K- U#endif
, M9 p2 h4 A+ P+ v- l- C#if        1
. n. K2 N( {) E7 ^$ A: ]; N                // DC惉暘偺僇僢僩(HPF TEST)
& P+ n; J# h% j) k                {. C  m7 `. ^% I* _9 Q- k; e9 {
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
' [; @' L2 w# |! r8 e  g2 t  i                static        double        cutofftemp = (2.0*3.141592653579*40.0);7 q7 s6 U- S+ [) _/ G3 q6 T
                double        cutoff = cutofftemp/(double)Config.sound.nRate;  Y7 p3 U) }. D  [" _; s9 ]9 k
                static        double        tmp = 0.0;0 E8 ^8 k5 T7 f5 g$ d; l4 i
                double        in, out;9 G1 K, V2 e. _

" j7 a' ~1 U) }/ w) E- v                in = (double)output;
9 `: t& z2 u5 l                out = (in - tmp);
7 I3 V6 O8 M2 j) l* Q2 U, O1 [                tmp = tmp + cutoff * out;6 I8 [! c( f6 r6 y: M) d6 y/ C% i: l

1 b* ~: d" {0 \" p7 t9 D                output = (INT)out;5 j; B) `( v) g; z9 ~& l* e! C5 ~5 L
                }' ]( E7 b5 b5 f3 G+ y( [
#endif
3 I- B! W$ M& U#if        0
3 @' H/ X/ P: V& t                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
- D& O- U. v9 d# t2 K                {6 B' E) l6 _" |& w) Q1 @
                INT        diff = abs(output-last_data);1 l/ M  N: Q/ z; {. I: z3 l
                if( diff > 0x4000 ) {1 h: o- _! ?; n7 [/ K
                        output /= 4;
! [; J! Q, ?4 f& }                } else 2 T! N% b: @, y- H$ A5 V
                if( diff > 0x3000 ) {( G' f* O4 h& F
                        output /= 3;5 ~! d1 F9 i# h1 q& P( k5 |" W
                } else( }9 I: `7 i  r: q- {2 o' ?; o' m
                if( diff > 0x2000 ) {
6 z- |- C$ c0 B) b                        output /= 2;
7 o" P* l1 @" c6 I                }
- x- ~6 \- {( e) l, G( }+ d! S, N                last_data = output;3 A/ p' b3 j( [  d4 d6 a
                }% x: u0 w6 p( _, }1 [. D% O
#endif
; M2 L! x  |2 P                // Limit- n' F. g) L8 R3 w3 S2 f# W
                if( output > 0x7FFF ) {4 Q  i* A; y/ e- ?
                        output = 0x7FFF;. o( s$ ^( M9 K' S/ i
                } else if( output < -0x8000 ) {
2 M! M+ @/ `/ c2 g/ i# }                        output = -0x8000;
( P2 c5 T1 V* K8 j- \- @0 ^$ T                }
" _) Q# Q0 D2 ^5 I" \8 P" H' y. ?6 I2 z# e: x, A
                if( nBits != 8 ) {
& d& ^1 E) I' C: v                        *(SHORT*)lpBuffer = (SHORT)output;5 e' r) U- f7 a- m
                        lpBuffer += sizeof(SHORT);; }$ i8 f6 D; N- e3 u; A/ {0 o7 K
                } else {
/ r3 a8 F( h0 z                        *lpBuffer++ = (output>>8)^0x80;2 [5 S* A: P$ |  w' \. W; [  Y
                }
9 i; h% t0 U4 i4 y2 F/ m' k8 e5 W% `$ r+ r1 K) z' @
                if( nCcount < 0x0100 )& [8 v" h' c. d+ I
                        pSoundBuf[nCcount++] = (SHORT)output;
. q! C  r; m' R( P9 o
% ]6 r3 u, O- S; r) {! Q  O+ Y6 U//                elapsedtime += cycle_rate;
0 r' l5 U9 A7 Y2 V1 _                elapsed_time += cycle_rate;
2 X5 _  Y# [+ m, b* b4 j( D1 q' e! G6 O        }
# L6 w$ r, P4 S( u# O! z: T" J2 \9 Z( i: }9 J
#if        1
, t1 _, y/ t$ w& R" f' `- x        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
1 }, C$ s( Y8 g) d                elapsed_time = nes->cpu->GetTotalCycles();, Z4 `3 s. [. \7 \
        }6 L9 n; A% I5 h2 D' A  W5 _
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {1 @8 f4 q3 q- I
                elapsed_time = nes->cpu->GetTotalCycles();# N4 Z, j+ n$ r: z) C
        }5 ^  ^9 X5 y  E2 [- e
#else9 A1 G/ d+ U; w0 w9 }
        elapsed_time = nes->cpu->GetTotalCycles();
8 b' T, H$ s% H#endif, L, u! s6 h2 T5 d  U
}
5 n( P1 J3 \+ |* l; G7 }: [( G% ]
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
9 ~  N* u  Q4 B, z- b$ E) a, bINT        APU::GetChannelFrequency( INT no )" p1 \6 p% _, k+ ], p* ]6 m
{
+ [3 |8 Q9 T; m# v! r        if( !m_bMute[0] )6 {2 k9 {9 H+ n2 T
                return        0;
0 V; e2 v4 d8 C; C4 }, p8 v
8 r' G5 q! @1 h* x$ E, L9 A) \" b        // Internal* h8 i$ O" n: g8 T7 x
        if( no < 5 ) {* O, ~  \4 p  W( t' s! u
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
0 i+ C: }3 i1 [2 i        }/ p+ I3 g- C, S! T  h
        // VRC62 D+ Q4 b9 s" H/ a4 G+ U7 J
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
, t0 ?3 B  x% G6 \6 O( O                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
: O8 d, [; m) k. X; A5 l; s2 V6 W        }
: R4 k/ r# i& ~' s' x' Y        // FDS- z9 Z" G: C$ f& _9 u
        if( (exsound_select & 0x04) && no == 0x300 ) {
2 {$ C0 ~* q( b: p. I+ ?% U                return        m_bMute[6]?fds.GetFreq( 0 ):0;
. P* q- L; @* W7 p        }; V2 ~( G7 g: }, Q! |
        // MMC5
& k* S9 g! c' ~0 @        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
( e" U6 |/ H# n) v7 w0 e                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
1 _& P/ f$ j! O4 {! U: J! ?        }2 X( U1 s$ A% `! S7 e- l
        // N106# }4 q- B4 a# b8 F! D: _% K
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {+ |  v8 {7 {; {+ j# a5 z  j9 L
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
% _# e* N+ A0 ^# I* ?        }
3 H, O* r7 v0 O) G, q        // FME7
& e5 T, `, d. N! o4 R        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {/ H. _! N& [- w) [% h  R1 Z
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;& y7 ~% @7 C# g7 ~: z
        }
0 @( V- s3 q  d) N& l        // VRC7
! p6 c1 K4 z* Q" B' k        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
; G# g. i# Z- u5 h$ z1 Z; m% J                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
4 a1 r% Y: O( T        }# z9 o& I/ N0 i* {3 I/ R- F
        return        0;
; X% x2 a: g. c( ~}
1 u% |7 W4 g# H5 k5 P: q& {, i3 Z3 j6 o' R, j$ n; r% h( ]
// State Save/Load
' S: `& |" n4 g3 E$ rvoid        APU::SaveState( LPBYTE p )
4 w/ G$ y) q- q( j, h" X* @# H{
( k! [" {8 j" U9 L% H#ifdef        _DEBUG: Q+ i2 x, k4 n# p) Y0 q8 v: I% E9 c
LPBYTE        pold = p;, C: R9 H7 X7 z4 d  \
#endif6 n) F6 A* }. Z5 a9 J
8 F. y* n+ ~; R7 [8 T
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞( f* N/ h5 u% Z3 ^* N" H+ e
        QueueFlush();5 Y$ q* a! ]9 h/ b* H- O

5 L+ B; n, }5 d# s! G        internal.SaveState( p );7 |2 Y* m5 `- {( v# `# n$ o7 G
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding  H2 j) {' G7 {6 _
0 w+ B9 [# ]" [; \
        // VRC66 x; L9 V& \# ~) _
        if( exsound_select & 0x01 ) {
2 s" q# {- o% u& Q; Y0 ~                vrc6.SaveState( p );9 i8 K; D& E6 C6 \
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
$ O% u5 _. |+ \! \9 q9 P6 y8 ^        }* ~+ E) G& W9 t6 i& f3 A
        // VRC7 (not support)% L! y2 u& ^. f% ~
        if( exsound_select & 0x02 ) {* N- g/ N  x; s5 l+ H. ^
                vrc7.SaveState( p );
- R0 g$ l- e' R2 r                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
2 Q: k7 q' z5 }8 l, ]+ I        }; f- K3 r- b9 ?6 ?( ]% C9 Z. T
        // FDS* b6 b" |3 Z$ R2 _7 k/ P
        if( exsound_select & 0x04 ) {
3 R! v5 T2 Y% N# _) S: C/ N6 D                fds.SaveState( p );
" q; y9 l- u6 l( g2 g                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
! y8 c" K0 I% p- n        }
! d% p) m) Y6 T$ S$ K        // MMC55 ?! F' @! ~$ F# L! {5 f0 u
        if( exsound_select & 0x08 ) {
. V' t$ ?$ B) Z* c                mmc5.SaveState( p );# A2 A/ `. W8 t/ i  v, \, E3 y& T( v
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding: ?: c4 R5 W8 i  ]( j/ i
        }
4 Y, E& s+ Q5 I" u        // N106
. @: K4 U8 v) O" e( w        if( exsound_select & 0x10 ) {  h8 j! q2 o5 }
                n106.SaveState( p );( d0 O3 d# c2 l. Q
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
1 d; t4 f# G$ D, }: i6 \1 M$ M. d        }
5 G, e: [7 C6 i- e        // FME7
6 R- f4 K: y( x) ~' v% E/ Z; Q5 K        if( exsound_select & 0x20 ) {
! E* ?! u4 k' f                fme7.SaveState( p );
% S1 l; u2 ?0 Z$ r) R+ }                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding& u' p3 j4 V3 R; z. w4 g
        }5 E7 H3 q+ r! }  g6 D4 u

4 p3 E  Y! A1 r" W  m#ifdef        _DEBUG1 N" ]/ E9 q) X/ m( N- L% ^, W& J
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
0 T( {) i1 W4 ~$ [#endif
5 x9 e5 `+ ~& D' @}
# F9 {' n' }6 j& t5 T! o. P: k
. S% M% Y. D; S. n1 ]3 Fvoid        APU::LoadState( LPBYTE p )
* n% @. N, ]& T6 {' \{1 l3 ]$ k' c/ `- H- w) s  s! f
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡, s$ e+ y! D% ]: a3 N% q" d
        QueueClear();+ [( E: n! E  b" _* W2 [
6 F& Z/ u  r5 g% K9 ?/ b, Y( P
        internal.LoadState( p );9 G% ?( ^' B, a+ k; H
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding! v) G$ o- u1 d  L/ t& u9 |
1 i. s' N9 h/ {8 ~1 h
        // VRC6
: q2 v8 C9 O) y3 p9 p6 Y, k! z        if( exsound_select & 0x01 ) {
0 h0 F! W1 y. G# A8 S0 b& y: R                vrc6.LoadState( p );
& J( G! [# v8 E                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
! Y9 U- y( ]2 }        }& n& N+ A' c2 o% F6 `6 v
        // VRC7 (not support)  O* R' ~3 P4 B
        if( exsound_select & 0x02 ) {
6 t3 S/ g; G. v( e& H! `$ E7 U                vrc7.LoadState( p );( q( o" ?0 K4 A$ ^
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding! V0 e4 e3 V" g% [: @9 ^7 R  T
        }
5 m4 _& _4 C' P( [( h1 \        // FDS2 M$ ~& x3 z4 W1 Y
        if( exsound_select & 0x04 ) {
: m7 T& |& T9 M& j/ k                fds.LoadState( p );
2 }7 x& I! e) I/ A6 u                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
- @: V2 g+ ]# T' O        }0 d  {$ k# Z* N4 s
        // MMC5) s7 Z- Z9 B) q+ S( o1 }3 p
        if( exsound_select & 0x08 ) {; W8 w; W/ A8 M
                mmc5.LoadState( p );$ Y* u. w/ |5 V
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding5 }6 q# j# e# Z
        }
( ]& c" y; v( E) q/ a        // N1064 \, J, t# {  T
        if( exsound_select & 0x10 ) {
1 c) t, W! _4 S- Z$ K" p) o                n106.LoadState( p );. p4 E0 H( T! Q( u0 ~: ~  s
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding( k& v& T6 ]8 @# h' z4 X# `& M
        }; d- W2 ~: [& ^) g9 N
        // FME7+ l; [4 F7 l6 V* A: ?1 H
        if( exsound_select & 0x20 ) {- n  U4 X- u6 w0 o0 d# u
                fme7.LoadState( p );. n" F. Y9 z% u( _9 |5 O
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
3 M! n8 K, }! Q( Z        }, |2 k9 A  F, r1 q: c+ I
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
7 o" G: j( W$ b+ [! q) L可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。* L3 X: \  Z: z5 m) D/ S
感激不尽~~

" k6 T9 V. \0 a恩 我對模擬器不是很有研究,
  u0 q' ]4 U; W. @! l1 i雖然要了解源碼內容,可能不是很困難,
, _6 L) I( `0 c不過還是要花時間,個人目前蠻忙碌的。
3 a5 ~) m5 `' R
( m( Z& Q' ^  ?* X3 `% T2 c( L+ a( W3 z給你一個朋友的MSN,你可以跟他討論看看,
# U# c0 b% C& o7 D& ]: `8 Z他本身是程式設計師,也對FC模擬器很有興趣。( A0 R9 d2 x' M& F* J
4 w0 h* a/ N  q. i- V
MSN我就PM到你的信箱了。3 z: Q$ R" [" b, B) ^
0 u7 y1 F5 d# k' s& Y5 |
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 M* i9 S! D& D$ s2 w1 d
呵…… 谢过团长大人~~

1 C9 D+ Y" V3 q
+ ]. I) h) k& v* x9 T% h哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 . Y) l' M) f  a" q9 v
团长的朋友都是神,那团长就是神的boss。
! J% d0 y3 b4 N9 k
哈 不敢當,我只是個平凡人,( {$ `* Z9 M& e8 n2 v0 k3 I
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
0 {# Z0 _0 V! W# Q$ RZYH9 A7 v% S6 L$ p) p
QQ:414734306
, a2 m; K4 y2 P% W5 DMail:zyh-01@126.com2 c1 ?+ i4 F( M; B

* P) l) I& t& }1 R. }: B他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 9 }7 n5 x. r5 n% r* V' a! ?1 z
再次对团长大人和悠悠哥的无私帮助表示感谢~~

2 ^0 O* F9 B. q+ ?) F7 }不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-2-10 16:53 , Processed in 1.077148 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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