设为首页收藏本站

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

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

  [复制链接]

该用户从未签到

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

该用户从未签到

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

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。* A0 I- W& `# ^
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
' s' X9 F% _* Y& H1 ?" U' y9 X这里有相应的模拟器源码,就当送给大侠了~~
; Z0 a" u3 O( k+ l7 A0 s" _http://kenkao.qupan.com/5096520.html
回复

使用道具 举报

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
% E0 Z, y# a3 o  `能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
$ `9 |$ f$ ?, Y, y楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
8 h' M5 G( B4 h$ ~/ C这里有相应的模拟器源码,就当送给大侠 ...
, }  i! B- J, @# j, F1 X7 r
聲音部分(Audoi Process Unit = APU):
. x; N+ I( k* T/ x& e4 [.\NES\APU.cpp% n; p) g& U7 `
.\NES\APU.h% N/ o- c* l$ n/ S8 c. J# e+ W
* P2 s! E5 T# I
9 [1 L! ~# s9 v! V; p0 w7 g
影像處理部份(Picture Processing Unit = PPU):* L7 o# `. W9 d8 A
.\NES\PPU.cpp3 b; X' ?3 a) L: W
.\NES\PPU.h# q7 b5 z: y3 d2 {' `0 C+ y

3 {+ V% q& s. `! W  B/ G如果原碼用C跟ASM混搭也不錯
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:4 ]" z" c. Z( {! z' v
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
. C# X' j: x  }) E- Q& }5 j+ H9 ^/////////////////////////////////////////////////////////////////////////// X- q% q) R* M8 `7 q1 V; T5 t
//                                                                      //
% j0 ^) n+ S/ A: _: o3 Q//      NES APU core                                                    //; `% E% r2 F2 B1 w9 T1 ]
//                                                           Norix      //- L& P$ X0 z; q. Y  Y' {% q) A1 T
//                                               written     2002/06/27 //
5 c4 t6 ?/ h( p7 n, ?//                                               last modify ----/--/-- //
1 L  O# A  Y0 i& o//////////////////////////////////////////////////////////////////////////8 C- W+ U' q+ s
#include "DebugOut.h"
' Y4 b9 Y" i5 C#include "App.h"3 N. x# s4 }" j2 B
#include "Config.h"" l+ j7 o7 S7 K1 }& w: }1 u
& `! o& T) n: J/ c7 q
#include "nes.h"
" k9 t. C; `- Z0 x+ C. F#include "mmu.h"7 }- a9 u/ V- s( |
#include "cpu.h"# k( }' ]% L3 {
#include "ppu.h"
8 H( B8 V& |" ~$ d+ O, y#include "rom.h"
( _0 P2 j7 B- G9 C, O#include "apu.h"
* G1 u* x2 K. G" D* }) \' c& ~* Q9 S9 E+ n0 K" N
// Volume adjust  G9 \: X  v$ }: a: c
// Internal sounds
- O$ A; d& {: @/ R#define        RECTANGLE_VOL        (0x0F0)
' ?+ R" g/ u+ K#define        TRIANGLE_VOL        (0x130)
. P) p2 C& a2 C, u0 M#define        NOISE_VOL        (0x0C0)
: i8 h8 v9 z! w2 q6 G8 C#define        DPCM_VOL        (0x0F0)
$ U& a' V. ^  w" r// Extra sounds, Z0 G- g/ b9 `" y, ^6 c1 V3 i6 r
#define        VRC6_VOL        (0x0F0)
2 F# B$ U  x9 B7 L( g1 z- L+ z& n% F% Y#define        VRC7_VOL        (0x130), e1 O9 W( `/ y9 l9 `
#define        FDS_VOL                (0x0F0): {, {- M( z! u6 U
#define        MMC5_VOL        (0x0F0)
: r  |# _7 o0 C3 u9 k3 p#define        N106_VOL        (0x088)
% k1 f$ }. G" e2 V1 i6 J#define        FME7_VOL        (0x130)
# W# b, M' s6 \" Q1 L" z
4 m. d$ R' p1 b: Y* K3 lAPU::APU( NES* parent )
; k+ C2 S# }# p6 X' S/ x{$ N) s! w! t) U3 |2 P, T+ N
        exsound_select = 0;. i" Q, s* H( f, N3 Z0 X

$ ]8 K* e; t$ W        nes = parent;
6 d% R4 |+ X7 {        internal.SetParent( parent );! w# b/ N) Y' s) {# S% B
7 S" }* H3 d8 R9 C# l! J! y6 h
        last_data = last_diff = 0;
6 b  ^$ a& H/ M) X7 f6 W; S5 O# v
" X5 i, }" d. I! }2 N        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
1 ]3 f8 {! P) d5 @0 O5 I7 t; f+ p8 \6 w0 Y: b7 T& p5 g
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );! ~/ r# A; \& Z* b: Y) t, r$ t0 ]; f
        ZEROMEMORY( &queue, sizeof(queue) );
' n2 G- K7 I9 |4 m' o: ^9 Z        ZEROMEMORY( &exqueue, sizeof(exqueue) );
2 o& J6 k) o! E5 _: N. A3 ~: p. \1 k1 P0 w$ B  L
        for( INT i = 0; i < 16; i++ ) {4 O9 h, p, j  J7 X; a6 \
                m_bMute = TRUE;
* v9 N& |8 G4 K, V( G& _! }        }
! [) t) Y! K; c* T+ i}& ?, G  ?( B9 x5 f

) f' Q: d- `  d: I9 z! cAPU::~APU()
* ~3 Q: U7 W9 l9 V7 p{" Y: A5 c; n  Z. O: z  f9 H& m! ~
}3 _) {5 p2 `6 y4 u* s6 F+ |5 {
- r6 e+ q- G( d& c; j% t5 x
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
' ~1 X! p# A. a3 x! v+ e) b{0 l# W# M1 h. r1 j/ ~, M
        queue.data[queue.wrptr].time = writetime;. d; m  c/ O3 c+ F8 T% J: v
        queue.data[queue.wrptr].addr = addr;2 [, ~9 [6 v' a4 z
        queue.data[queue.wrptr].data = data;4 o. y6 ?6 I8 g% ~
        queue.wrptr++;- k# G) A  c$ U7 K
        queue.wrptr&=QUEUE_LENGTH-1;
6 Q3 g) c- h6 q) C9 C+ ?9 \0 |        if( queue.wrptr == queue.rdptr ) {
! [6 b3 \. S* b                DEBUGOUT( "queue overflow.\n" );& V1 r4 q7 ?2 }1 l" X- s% \$ ?
        }
3 E- h1 [. I, _! D! r+ A5 P}
, q9 x1 b. \1 a- g3 E2 S3 j3 Q, D& G  }6 C3 A  i) v! V
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
# ~4 F% S7 H! H) r9 @9 U& H{/ G: q6 C# a" r' D7 S& p
        if( queue.wrptr == queue.rdptr ) {- g* A: k' S1 Z( b* c2 g9 A
                return        FALSE;
4 {% Z' S9 X1 j8 u! H        }
: Q3 p9 z+ ]) u; i4 A: v! p        if( queue.data[queue.rdptr].time <= writetime ) {. i& M; w3 l6 _* w! x2 v/ k
                ret = queue.data[queue.rdptr];
: Q5 e# x) O! J3 `$ s* P                queue.rdptr++;
" [" I0 o9 B2 E( w                queue.rdptr&=QUEUE_LENGTH-1;( z5 x1 ]6 k; J( ?
                return        TRUE;
2 m2 S/ x/ q4 C6 q/ n        }# R. R/ y& ^) A& Y
        return        FALSE;. b: \# X3 K: H$ j9 }& M2 J2 F9 b
}7 ~  J0 t, H  P9 R- ~9 C& h: f1 `
. X8 Q1 ?6 W- R  B$ e
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data ). h6 t; `5 r+ P3 O# |
{
+ M2 k' S0 S' P& b, L3 W$ h" a        exqueue.data[exqueue.wrptr].time = writetime;, r5 y4 g8 Q) Y; a( H
        exqueue.data[exqueue.wrptr].addr = addr;1 q" c- K2 A( K7 }
        exqueue.data[exqueue.wrptr].data = data;
) U) `3 b: N8 n0 j        exqueue.wrptr++;8 ~" c& T5 n: g/ g/ ~
        exqueue.wrptr&=QUEUE_LENGTH-1;( Q: k8 r- z/ f' Z, I# Z
        if( exqueue.wrptr == exqueue.rdptr ) {7 Q# y5 @/ F$ X8 s, ?, ]' s: o
                DEBUGOUT( "exqueue overflow.\n" );1 y- K, G0 ?. l
        }% T: K. Z3 }; b: z9 d) l9 q) g  O
}) t" X! O/ @* @- _

! |& b# T7 c' {( l0 ?, g8 gBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret ): ~, c, J: Q# j3 x- @: E" F
{
/ Q/ u9 V: u; C/ L+ p  i* c  K        if( exqueue.wrptr == exqueue.rdptr ) {
( e/ D& A; B/ X4 r                return        FALSE;8 \2 z' d: |8 x4 W6 m5 W/ n' K
        }' P! `5 H. r4 Y6 O7 j
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
- z9 @- N# X* O& o5 C; K; \2 E                ret = exqueue.data[exqueue.rdptr];' q5 b. F9 c% ~8 w& [
                exqueue.rdptr++;
" w# ~" k2 a9 k0 ?  k/ ~                exqueue.rdptr&=QUEUE_LENGTH-1;- N, l; @1 u& R
                return        TRUE;
! {8 o/ Z2 E6 ^8 }8 K        }8 M& u$ E0 H# F4 h! ]  Z2 X' M
        return        FALSE;
" K& Z) n* X# E1 V& e}
% N! v* _5 a) B
5 G: E; \" n4 M- E+ S/ S9 evoid        APU::QueueClear(), u% k6 W+ ~4 ~. _( a) Z: ^
{& T" T# r3 M' S- o) R" K
        ZEROMEMORY( &queue, sizeof(queue) );. U5 S5 B+ T2 |- e# W
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
7 L( ~$ b/ U, a}0 f/ o# \2 D* d

) k2 K0 \3 N6 @9 q8 T- ?0 T# m9 pvoid        APU::QueueFlush()6 i2 [6 ^  w# Q8 N- A
{
7 I/ f7 m) Q: J. C  a3 {/ m& [6 W2 Z( j        while( queue.wrptr != queue.rdptr ) {6 A3 _% m; N) D& `
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );) n. a! r' S* V6 m, U3 p+ u
                queue.rdptr++;2 c1 ], y0 h# j( Y3 H
                queue.rdptr&=QUEUE_LENGTH-1;4 v% c* h6 [( V  y; o1 A
        }
  ]2 }$ V: v; O4 E! j1 g- g* u* h' J9 ]. q
        while( exqueue.wrptr != exqueue.rdptr ) {  d9 @* l% X: ^5 m! w
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
7 B. S7 P5 K% U5 ~% [: j  K                exqueue.rdptr++;
7 D3 K- g& @& I8 z" T& ?                exqueue.rdptr&=QUEUE_LENGTH-1;
/ R0 b+ D7 ~- o+ R        }4 v& Q- \3 }# q. X
}
6 V) ?8 _  Q5 [+ K; a# v$ Z
! z/ C& z2 v- e4 N" O: m, Avoid        APU::SoundSetup()0 M% k: m( s0 r$ [. M! K& x* s
{& @0 K4 z9 }4 Q
        FLOAT        fClock = nes->nescfg->CpuClock;7 {  y% y9 }1 T8 o7 n0 O4 E; ]
        INT        nRate = (INT)Config.sound.nRate;1 C7 y: L6 {  {0 M; }  m
        internal.Setup( fClock, nRate );
9 ^; F1 z. h  g# G; e) O        vrc6.Setup( fClock, nRate );
& e/ u: U3 S* `# ]" [$ [        vrc7.Setup( fClock, nRate );  z; b8 Q: F! a7 A- a
        mmc5.Setup( fClock, nRate );
8 M- I) `! r+ E4 g        fds.Setup ( fClock, nRate );  `" E. S3 g( M( z
        n106.Setup( fClock, nRate );
6 X  @" o# r$ m! U( `# n( F        fme7.Setup( fClock, nRate );, ~4 t9 ^7 |( k- @
}
3 h' D4 i7 I# q) q
; @8 g! d# R8 Qvoid        APU::Reset()/ q. ^5 d& }7 O- l4 V1 |7 ?
{
! j* T7 J! _$ l        ZEROMEMORY( &queue, sizeof(queue) );8 ~: b) ]) [+ j  r9 P" X7 `! |
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
1 {, g: }8 t2 G2 s
6 p" \* n. e& H: d& G9 t        elapsed_time = 0;3 M8 Q9 x+ Y+ r8 I: _( X
; k/ I; O4 [5 F* @3 L% O2 q
        FLOAT        fClock = nes->nescfg->CpuClock;
: c/ n6 y( ~( {        INT        nRate = (INT)Config.sound.nRate;  S+ C, `" g, K" m- Z0 h
        internal.Reset( fClock, nRate );
/ U: |; ]& R8 x& J: y3 l        vrc6.Reset( fClock, nRate );
) K% Z' U# C" |6 r& \        vrc7.Reset( fClock, nRate );
4 P" p. Z! s+ y6 x, |$ W$ {        mmc5.Reset( fClock, nRate );& S9 Z* Z. I: k
        fds.Reset ( fClock, nRate );7 [" A( P1 l9 u* b: X
        n106.Reset( fClock, nRate );
# z' U9 ?( H/ k( h$ F        fme7.Reset( fClock, nRate );- E  l$ N' F1 S8 D; _) Z# T

+ x) t) Z" K' u8 V" A7 V        SoundSetup();
% ?* q# E% u* f) E1 }& ?+ G4 P}
: c- {9 f4 @0 G1 i  k: S5 v
1 |2 |  ^; W% a! `4 A- zvoid        APU::SelectExSound( BYTE data )! i$ X4 P  M/ T4 X- ?( }. z! ]# |
{  [! }! B3 `/ ?; B* s- k
        exsound_select = data;
& o* R2 E" e" E. G: R1 g6 ]}: G% R9 F; _5 g
# I. H0 _9 \* ?+ M5 Y9 d5 {
BYTE        APU::Read( WORD addr )  F+ K& L# H6 o' [
{" |+ [  z( m9 n2 n  Q1 Q2 O" |
        return        internal.SyncRead( addr );
: B- t/ y. g5 R* C- ~7 k. Q. Z}
5 ?$ C7 H5 a1 x& G, f7 B% e% l- r' k' s
void        APU::Write( WORD addr, BYTE data )
9 L3 M0 o. k! E- x{
; O" j8 p  ~' M' c- N& x* p        // $4018偼VirtuaNES屌桳億乕僩
1 x: E/ r4 a2 m        if( addr >= 0x4000 && addr <= 0x401F ) {
' ^7 J4 e1 Q5 _: e5 c2 \/ M                internal.SyncWrite( addr, data );
0 V9 S/ \) V/ y                SetQueue( nes->cpu->GetTotalCycles(), addr, data );* H1 L4 U& a# V8 G9 d; S6 p! H3 c
        }7 B/ a. @2 J0 F# K" a* h& `" T! y" r
}
5 l; Q4 l6 u; r' E7 m0 [+ b3 `6 J3 W  x/ u' y7 m& o. s
BYTE        APU::ExRead( WORD addr )
- T) r! e1 u. U6 J- I{
! I, `2 Z: l3 PBYTE        data = 0;
& P% z$ i8 b7 b) N4 E$ v( r+ q' y9 @, b7 }  Q4 t9 w1 K
        if( exsound_select & 0x10 ) {; T( ]3 y& r1 {$ m/ O
                if( addr == 0x4800 ) {
: {$ q7 S( m9 w, C+ n+ n  N5 x                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
0 g4 D/ h) Y- n6 t$ b: ?                }
7 A6 n8 G5 {) l/ d        }
) P! I' @$ n2 {1 I7 R2 e        if( exsound_select & 0x04 ) {
9 g* ?8 A3 @" Y6 t7 z                if( addr >= 0x4040 && addr < 0x4100 ) {
- b/ d0 e; o$ D2 [                        data = fds.SyncRead( addr );* @0 |. M! [( R7 t2 k; p
                }- \( Z# c5 _: [# s1 H; @7 u* `0 Q
        }+ j1 n  R  G  H9 j+ C5 Q
        if( exsound_select & 0x08 ) {6 [* [' D0 Z; E/ _9 i
                if( addr >= 0x5000 && addr <= 0x5015 ) {
' h4 a" T2 }; L  _3 @                        data = mmc5.SyncRead( addr );! d: O% K3 S7 ~
                }
7 R* o% B" A+ }2 C, j        }
8 i! I  [% ]* c" Y& ?0 w8 n* P2 Y0 P* h" }( K
        return        data;
+ i" P; Y! I" V4 F4 I2 y0 ?}
4 F, Q% Q5 G5 R; F& L) _" j7 A. J& W
void        APU::ExWrite( WORD addr, BYTE data )6 n2 q$ B$ D+ P7 k- l) ]
{
$ r* C2 g( _" [        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
3 f1 ?& Q' A- D$ Q( W! c
& \$ {  ?0 C/ ~: P        if( exsound_select & 0x04 ) {& t8 ]+ V6 X9 ~& I: @
                if( addr >= 0x4040 && addr < 0x4100 ) {
/ |2 N% `6 E( N7 L% G  i3 M5 M                        fds.SyncWrite( addr, data );0 \: y5 a* ~* e- X* h5 _
                }3 k! `5 v9 O# w
        }* M. e2 |; `: ~: {- x1 m
* r! i& V7 J: B' B& o3 U
        if( exsound_select & 0x08 ) {
( P2 J$ F. }' l                if( addr >= 0x5000 && addr <= 0x5015 ) {
2 U2 A5 f$ A% @+ k                        mmc5.SyncWrite( addr, data );
; {7 A( E" Y$ a6 H2 P  h                }# Y7 p! V. m  z
        }
( f! C7 E% M' s/ H% y4 J1 {/ j/ e}
( U. R. x( F4 R$ s( U# r8 n& X& D8 _4 c0 m& e
void        APU::Sync()* n1 |1 V: I, f7 M
{
6 |5 g7 u7 Z, e- Z  E; j5 v5 M}
2 J: C" ~9 I2 q0 K  \3 |4 I* R5 ~7 L( ?$ g0 ~6 Y$ n9 R0 F/ P8 ?
void        APU::SyncDPCM( INT cycles )
& C: Q* k+ R3 P! x5 Q) |{
' Y% T6 x$ Q' A3 O, T, z# B        internal.Sync( cycles );
) `8 K# t2 [' g4 I4 o+ q( o2 y! M5 f# E* ?# s. t  e- R
        if( exsound_select & 0x04 ) {+ y& k; w/ w% Y9 i' t
                fds.Sync( cycles );6 T- Q! l0 k2 D2 H9 P9 h0 W" I
        }: {' J9 x1 B$ v
        if( exsound_select & 0x08 ) {1 i- q% D" I6 N: N' f4 Z
                mmc5.Sync( cycles );
% Q5 E. p* X8 Z3 q        }
! f2 h. |2 [$ n}  w/ z3 r0 c. o4 n

6 Q+ A  [6 K6 A6 I! c$ R9 j  Ovoid        APU::WriteProcess( WORD addr, BYTE data )
& H& q! y; a" i) z8 o{. q6 i3 z  U. r% p# v
        // $4018偼VirtuaNES屌桳億乕僩
2 b4 I! j: h" n6 G( l        if( addr >= 0x4000 && addr <= 0x401F ) {
( h' W6 U% ^% g2 L* q  q! D                internal.Write( addr, data );
9 s9 u5 y+ O  ~' @        }
) \8 x+ c% V7 {- P}
" [9 V0 O4 _. S% ^7 k- n0 e" ?  O5 s: ~- _' [% V$ S- F
void        APU::WriteExProcess( WORD addr, BYTE data )
! |9 U, W) x/ E0 e( F% v- p{" w7 }. f" K4 h/ S3 \/ E
        if( exsound_select & 0x01 ) {
2 P, k1 \* d9 n                vrc6.Write( addr, data );5 X7 H2 d8 t# _
        }
( f+ ~" _+ v, H        if( exsound_select & 0x02 ) {2 |1 f9 x% t( f- S
                vrc7.Write( addr, data );: e( P; V8 F# @# x5 i6 ~
        }8 a9 h7 ?; ]+ _. H  y- }0 m
        if( exsound_select & 0x04 ) {% ^. }" R+ a5 X
                fds.Write( addr, data );8 V4 ^* o  ?% z6 Z. C
        }' J! L0 B6 V: x2 {9 r# ?, S
        if( exsound_select & 0x08 ) {
! I, {- m; g. o' a                mmc5.Write( addr, data );  V+ D' \. ~( V$ W7 r1 Z
        }! Y7 _% J, u- {: Q2 v! j  V
        if( exsound_select & 0x10 ) {3 f' t, j* i' U6 D: z
                if( addr == 0x0000 ) {
7 a5 X. T2 \2 ]7 f; L+ c8 N                        BYTE        dummy = n106.Read( addr );
; r5 j$ |+ E$ {1 f5 v4 k                } else {
6 e: r1 H  R7 o$ S2 s9 G7 T' f  d9 o                        n106.Write( addr, data );, t7 o2 Q' n2 J7 s& I3 H
                }
; T- N( }  E( a  T8 l        }2 y+ J3 a7 |- Y! i. F: {$ K
        if( exsound_select & 0x20 ) {" n& h: I' Z' }# |3 x, C/ E3 y
                fme7.Write( addr, data );
8 b/ m' t1 l8 h6 y$ I5 W: ~        }
% Z/ u5 {, P5 V& ~- A}4 S/ u: F+ \2 Z. V2 a
4 Q% m8 m: L/ @$ l& p5 T; N
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize ), q. f7 y7 S3 J. W5 ^, i
{
8 m. A9 D5 C4 ^% m: I' y8 pINT        nBits = Config.sound.nBits;! w7 R5 Z/ s" |9 U: z% F: _
DWORD        dwLength = dwSize / (nBits/8);. Q& \5 [* n" R, u8 N
INT        output;
9 n$ P1 a3 o/ ?" f  AQUEUEDATA q;( e, h4 G0 Y1 l+ b2 x  S
DWORD        writetime;
5 ?; _" s2 |* c) Q, _" V8 q1 K0 x6 k9 I- U' m7 K. c% R3 u! c
LPSHORT        pSoundBuf = m_SoundBuffer;
# i" y/ s  ]5 LINT        nCcount = 0;
3 J4 v9 N1 {- j  C' t/ H' y" K  ^3 V4 ?. l4 I, u2 i7 d, {9 W. L
INT        nFilterType = Config.sound.nFilterType;
2 e' p* z7 R1 s. Q8 l9 ]" c6 o
2 {: i' Z! v7 D: s        if( !Config.sound.bEnable ) {
' O. L9 O& l4 q                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );6 P- G, q5 |; R- _" d: d2 w' P8 _
                return;
( s( v9 Z: {) l  }1 S) L" E! [        }
$ u' ]% c! ]' ?# E8 y1 u
; r: x9 a1 E" g! j% z. s0 Z        // Volume setup
4 _, w7 j1 J, ^0 r        //  0:Master  \( o, s+ A, |0 k. F5 M6 I& [3 \
        //  1:Rectangle 1' p% a0 n$ p& U, h( j
        //  2:Rectangle 2' x% }' R: G7 F/ j2 F6 H( L
        //  3:Triangle
( U0 v  P  T# Z" n        //  4:Noise7 T% [" V$ E4 C
        //  5:DPCM
/ [: H" O5 v2 u7 c        //  6:VRC6
5 M8 a, x% @5 h        //  7:VRC70 T# [% l* ^2 U" q
        //  8:FDS1 U: ?+ \. ?0 v
        //  9:MMC5
7 w& f) W3 x; E# D        // 10:N106
( ?! M# O' ~# i& q& E& V        // 11:FME7. }. }. D0 o8 l9 B- x
        INT        vol[24];% g. o: k3 e& |# M" Y2 w* S7 y4 w% n
        BOOL*        bMute = m_bMute;- i+ e0 Y" ~$ }& m
        SHORT*        nVolume = Config.sound.nVolume;
% F* k1 t4 S+ c, L# W, G. _( z/ n& |) C+ q# U( P
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;7 Y/ l$ q5 p6 m8 D6 q: Z" |

& o5 n, H: ]- h2 I8 b& g) {1 x& @        // Internal. @& o8 r0 U( |  Y3 w  L
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;+ m- }$ z, Y" U1 {# U
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
$ e- {% x0 O. l' E; J* r/ U        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;1 X. k7 n; L3 h0 G/ C
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;. k4 K1 R' m7 ^3 |7 `
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;  \! H6 n; b( _0 W6 P$ Z
! k; P" D5 Y/ z( L
        // VRC6
  t+ J8 H* |+ [. k, L/ J        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
* K3 e" ~" r) P4 p        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;' \# y6 z  w8 s3 O1 z0 F. G
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
3 R, p  ~1 q7 d: r5 Y, }3 v
; r' p# B1 _9 E, L' q$ I) i        // VRC7
3 y7 v. F7 |5 [/ y" W        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;' O4 `9 f$ a: Z# R0 _" X" G

+ ?" t, `$ x5 o$ v9 {# L- Z        // FDS
( t: z! j- ^9 V$ F: G6 r        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;4 d: E+ ^% z6 D9 i  g/ @

, @% v+ Y- k" o! N$ D7 l+ P        // MMC5
' E) `# m7 [2 x2 L6 b: q! C        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
( a- {: J7 Z3 }3 N% a) p; [        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;5 K- k1 w# t0 ^0 M  @+ L, C+ T
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
7 I8 \; I' l( b7 u/ Z
4 e0 e( {  Y. s6 g7 r1 p1 n0 W        // N106/ R5 ^. T4 r; t1 c" t5 e% Y2 a
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ ?* f* }4 b9 D& P: D3 `        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;) @) U& ]' m. k) }- o0 `, ^, ^$ z
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
# r& I2 O- T, p# `; K        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;. s6 O4 m* G! J" U
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;5 A9 P3 J6 q6 \3 `, F% m
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;6 I# |6 P4 a; F
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;& C2 U3 X; C# P: w  B: x4 e
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;5 i+ W1 x6 U' C3 T8 b- y' ?$ v: l

1 I4 w6 ?  w' V4 V        // FME7
3 S! g8 D. q: m" e, r        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
$ k3 o6 W. b0 W8 E        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;- Y1 L% H# D6 T2 u. K4 b0 ?6 P" j
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;1 X# [& |- `: ~: X( V! @
, L, i6 q0 K8 C  Z* I  C
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
' v1 a2 c) E/ \) d6 E  m$ q& c( o        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;, Q' z+ w9 |/ t: x: h
/ C* {" p/ \0 q
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟% @, O5 h' q/ `$ Q3 ^
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {4 R) F7 T- M, o
                QueueFlush();
: W, F; S0 N' W( V        }
9 N# \1 o4 n# w$ q; \6 ^3 n: C4 a5 [
        while( dwLength-- ) {, ?+ p$ M4 u& n+ L, s7 e& T' w' j: y
                writetime = (DWORD)elapsed_time;" h0 D; q. A* Y  q% x9 c1 {
# i3 V% ~1 C/ w
                while( GetQueue( writetime, q ) ) {1 b2 O, V" s2 h4 |6 ~/ S2 D% ?2 E
                        WriteProcess( q.addr, q.data );' ~& G$ ]/ t- I1 |* R2 I6 J* u
                }
8 X, {: {4 z' y3 w- W& B, v% _6 o  ~
                while( GetExQueue( writetime, q ) ) {8 H$ s% |% P- w7 ]5 P5 w8 A4 Z
                        WriteExProcess( q.addr, q.data );. k; L' o5 k* O1 m0 S& I/ B, v
                }& }) j3 y! \6 u& {' q* w

" h' |7 O5 H: _, j                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7/ w( X  P. o! y
                output = 0;
3 N/ i+ ]# \/ m0 l; @                output += internal.Process( 0 )*vol[0];- R2 S; |: J9 e: }- L3 k0 Z
                output += internal.Process( 1 )*vol[1];3 R5 Q# S1 `; a* Z
                output += internal.Process( 2 )*vol[2];% u6 ~5 K* O; g' t( H
                output += internal.Process( 3 )*vol[3];
& l/ d+ S4 g: k# t                output += internal.Process( 4 )*vol[4];  ~3 q. P! S' o

- q0 i. H) r$ d- V, L                if( exsound_select & 0x01 ) {5 f  @/ T8 b+ T' K
                        output += vrc6.Process( 0 )*vol[5];
) b( c2 \5 Z- Q5 r6 [                        output += vrc6.Process( 1 )*vol[6];
5 p" i4 u- Q% N- H0 b$ C                        output += vrc6.Process( 2 )*vol[7];: R5 }6 b% }* D, w% j; J- H
                }
  K* y" K6 N' M# I2 Y" K+ o5 h' a6 z" ?                if( exsound_select & 0x02 ) {: p0 N" i; c5 n- G
                        output += vrc7.Process( 0 )*vol[8];7 p# a- a- ]& S- Z# t0 `/ `* f3 @, _
                }; G1 Y% }7 Z8 n8 C7 g0 g% B' V% I
                if( exsound_select & 0x04 ) {
" y) w* ^% t9 n0 h! v6 w# u                        output += fds.Process( 0 )*vol[9];
. c* W' X0 e: ?4 r                }) i3 v7 ?( y3 K$ ~: u5 B" a
                if( exsound_select & 0x08 ) {
$ k( B( l% c8 i, P  n5 L8 M2 U                        output += mmc5.Process( 0 )*vol[10];& ?9 e; F+ q( u! i6 ~0 R3 m- ~
                        output += mmc5.Process( 1 )*vol[11];
. t" V( g/ K( j& G                        output += mmc5.Process( 2 )*vol[12];0 J: _' I% k5 r& `) q+ ?6 ]! C
                }7 Q* R2 ?5 e' W2 x- D0 C
                if( exsound_select & 0x10 ) {; c8 E8 K9 P0 B- }  K8 t0 F. V/ T
                        output += n106.Process( 0 )*vol[13];; g8 m7 b4 R& v* r: A
                        output += n106.Process( 1 )*vol[14];
7 y+ a/ D5 {- x/ H( B  h' `; u                        output += n106.Process( 2 )*vol[15];
# n5 k. {2 Q! {) A0 h( o                        output += n106.Process( 3 )*vol[16];/ T, c/ b8 o$ M3 f
                        output += n106.Process( 4 )*vol[17];
6 p! u+ ]( U1 d4 ]" p5 M! q: g                        output += n106.Process( 5 )*vol[18];
- x6 l$ f$ H6 M: b                        output += n106.Process( 6 )*vol[19];
2 T* D* C' m  b8 t$ q                        output += n106.Process( 7 )*vol[20];
) R0 M0 |" p4 g' [3 o0 W                }7 e& Y  n5 f6 d4 N* z5 F# \* d
                if( exsound_select & 0x20 ) {( E! C% o7 ]- ?, E
                        fme7.Process( 3 );        // Envelope & Noise% E! e' d% \; \" j
                        output += fme7.Process( 0 )*vol[21];: h) M: l  Z$ z7 l( T9 t1 _
                        output += fme7.Process( 1 )*vol[22];% P+ d; [0 V3 y* q% R2 @
                        output += fme7.Process( 2 )*vol[23];
: n+ N7 D, z% C/ R9 J; a' X                }
! a- j# A: M$ l, \6 p* B( s
3 s( @0 O" b% @* m3 F5 N# Q: [                output >>= 8;
: q; D) q* L! Z: d( D$ S* q" b8 S
                if( nFilterType == 1 ) {
. X4 |) I6 @, ^- s" b  c                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple): e- g2 z2 h! ]2 Q! p& {  F% q- K( M
                        output = (lowpass_filter[0]+output)/2;
) N; h/ Y. w3 P* l                        lowpass_filter[0] = output;! }+ i$ O, m, H& ^7 H/ }5 G4 C
                } else if( nFilterType == 2 ) {5 C; }2 @, _( \
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)% v6 ?1 [- S4 c/ I4 `( Q
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
5 G; W* E1 g& A& E, C( p. p                        lowpass_filter[1] = lowpass_filter[0];- K, {; g* M- {" x% ]9 E
                        lowpass_filter[0] = output;
) ^" |, g" E1 e7 `6 F                } else if( nFilterType == 3 ) {
9 P, y0 H1 A: `# k7 a                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2): O0 H  T8 k+ l$ R  k' ]: U
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;* l/ s$ f# r1 I
                        lowpass_filter[2] = lowpass_filter[1];# g. p8 }8 q9 G" }8 O6 H
                        lowpass_filter[1] = lowpass_filter[0];
$ L5 P5 z; k1 Z+ c: z' x                        lowpass_filter[0] = output;
: |. ]# y; K, g                } else if( nFilterType == 4 ) {
" C* t- h. S) D  N) n" {                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
/ K/ a6 w! o) t+ f                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;, H6 k% b8 P: ^) G8 [1 _4 ~' ]0 x$ I" `
                        lowpass_filter[1] = lowpass_filter[0];
: p+ Z+ s% w- v8 `8 E, O$ g                        lowpass_filter[0] = output;
; j  |; f* t; O6 K. E                }
0 o( f4 |3 ]3 s, Q" b% M7 E) v( |: E# Q; r0 p& _
#if        0% B' d, }7 D- J9 y0 m1 e
                // DC惉暘偺僇僢僩
' X8 i4 f1 E; G* s7 V/ r                {
) [; d1 D  Z  h& H                static double ave = 0.0, max=0.0, min=0.0;
1 k+ f* k. s4 i7 ?/ I% K9 E1 P3 ]9 S                double delta;7 {8 s8 x/ J0 S1 }1 ]
                delta = (max-min)/32768.0;
/ G, v1 A6 K8 E' c" O9 Z% X1 D. P  e                max -= delta;
8 R9 x' Q# w2 I1 ]/ e                min += delta;* S0 H* J  g4 y3 M" e
                if( output > max ) max = output;
# v. B: j4 s$ d7 f                if( output < min ) min = output;
# b6 Z' v! Q, G& s0 A. z                ave -= ave/1024.0;- i) U6 L" m$ s
                ave += (max+min)/2048.0;
8 _" S1 S6 T8 k/ m                output -= (INT)ave;
3 b. H  X1 S0 b6 l9 S                }# ]/ G* J% m- v7 ]3 g
#endif
' J& h, ~. J1 d$ G# c' w* E7 E( O# O#if        1& ?7 ]- H7 l9 C' r
                // DC惉暘偺僇僢僩(HPF TEST)
. \( R  V4 G1 H6 O6 G$ L# m: q                {
; e4 ^: x+ K# @/ [3 f/ j! L//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);: p- w8 P$ X2 @7 C: `" s
                static        double        cutofftemp = (2.0*3.141592653579*40.0);. P& c" O7 g5 H4 {
                double        cutoff = cutofftemp/(double)Config.sound.nRate;6 j, H9 Z/ R" ]3 {5 N
                static        double        tmp = 0.0;
- D+ }8 X# _% @% `' O7 ]3 X. y                double        in, out;0 \$ H9 M; V9 s) w7 [
$ I  p. J4 J4 _' J4 Y
                in = (double)output;
4 ]: h2 S2 ~$ K4 ?                out = (in - tmp);* p5 a2 n- B4 ~5 A: R2 _) X
                tmp = tmp + cutoff * out;: l+ s0 V0 H! o; d, t: Y& S$ \" o

. `7 b' u6 q' W5 S4 i: U8 O$ {9 U                output = (INT)out;
# g, P1 ^% X0 q* q+ b                }& P8 ~; ~; P7 n% l( f
#endif
" X: T. q3 {8 M; d) {5 t#if        0
; S: v& S  X2 D4 f# p' X* D                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
% E9 V' c6 C& p$ z* _: n8 k" a                {; t, J7 j% d! r1 F" ^! S$ {3 h
                INT        diff = abs(output-last_data);
* A% y! k% N5 Z2 b0 s2 k                if( diff > 0x4000 ) {2 u* a; X/ h3 V' s4 t
                        output /= 4;
& }; z9 S; ~6 N, K3 l                } else
, n/ W. t0 k- o' a  J                if( diff > 0x3000 ) {2 E; h  D! F$ E9 {' ]
                        output /= 3;
" n, i$ w0 {5 C1 Y                } else, |, ?/ @( k2 Q* u  ]; i9 ^$ C- U9 T
                if( diff > 0x2000 ) {
! J+ ~9 r5 I5 ]& V7 a                        output /= 2;
0 X1 p# }  Y3 |. q. u                }
# F3 V5 ~- v7 X, R$ V                last_data = output;4 S0 {( ^8 Q- D7 B. X4 y1 |4 z: T% u
                }  B3 |7 l  r" ?$ ~' S# s
#endif2 H- L$ v: V1 y4 L" k( b
                // Limit
3 K( }. V8 E  }! c                if( output > 0x7FFF ) {
# o. @. Q; z2 X                        output = 0x7FFF;* l: d5 _: K1 V' w) i9 O/ D
                } else if( output < -0x8000 ) {: s/ q* s+ j6 `, Z/ |' e- P- Z! Q
                        output = -0x8000;4 z  @4 f8 b" T7 D6 g9 t1 ~, L0 q9 b  h& ?
                }3 _. b$ }) @' M7 P/ N$ a
& |  j2 y5 a' n8 q, h* V" S/ y# S; h
                if( nBits != 8 ) {  g+ u3 d3 R1 y! p/ n! P
                        *(SHORT*)lpBuffer = (SHORT)output;
, A  H/ h7 i+ m5 S; Q                        lpBuffer += sizeof(SHORT);, X5 V' t7 h6 K
                } else {6 w5 G- }, _! ?0 J
                        *lpBuffer++ = (output>>8)^0x80;
: R, @5 R1 X8 S- f* H2 d                }
$ r8 B( P$ Y+ l6 J5 q/ h( H4 Q) R+ Y
9 N$ p# ^" n7 o+ }! M1 S  B                if( nCcount < 0x0100 )- k, r' k% R* P& `  {
                        pSoundBuf[nCcount++] = (SHORT)output;0 X0 r' z- y4 g% y; a& N) d
+ N7 t5 C4 \& ]
//                elapsedtime += cycle_rate;
, a( |: Z2 o, ], P                elapsed_time += cycle_rate;/ B3 s" h, ~% M# q
        }
3 i. h, T  q8 P  y7 V& c+ g! e# D6 q, J+ B% G) `, }9 @2 D3 x
#if        1
; s2 {2 M' f- A        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
1 U" D; e; h8 g4 r. Y) f( K                elapsed_time = nes->cpu->GetTotalCycles();& v4 N- U% I  g( u! v. k
        }+ F- n, @' K; ~5 A( n# L7 h
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
0 I1 j% b6 _/ u% o                elapsed_time = nes->cpu->GetTotalCycles();$ b. k# b  S. a4 e9 u6 i: C
        }" [# m) p0 V9 l/ c* W4 l2 F3 L
#else, s; ?6 f( D/ O4 N  n
        elapsed_time = nes->cpu->GetTotalCycles();
4 x/ C. _% Z1 c% K1 k#endif' F+ A4 i- E, w3 B( b* l/ P
}
" m* W0 b- D1 u; D1 l: F
( x! `; e0 ]9 I// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
% T6 ?8 F/ y! U3 ?8 [' }" YINT        APU::GetChannelFrequency( INT no )/ b/ r% ]$ ~+ K+ X. q( F
{
8 }) f8 M% Y4 F/ X9 O        if( !m_bMute[0] )
2 e, F" E6 |, l! f3 X                return        0;. q4 n* z' f* o. W/ |

9 L( b  g7 o% k0 C8 i. z        // Internal
2 |6 c5 n7 E* S) `# U' p        if( no < 5 ) {
) m! \/ _/ d: k; S                return        m_bMute[no+1]?internal.GetFreq( no ):0;
3 t7 G$ \6 u; \; h        }
4 c4 z3 S- d# C, B: s$ y        // VRC6
; Q" r$ }* a8 O  v        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
* L7 l' I6 V6 ?                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
* y# z9 R! u: M- Q) L        }5 B$ P) Z6 ^! y8 Q: q
        // FDS2 i5 F) q4 g1 {7 m" Q
        if( (exsound_select & 0x04) && no == 0x300 ) {
/ W! K/ v' D  C, c                return        m_bMute[6]?fds.GetFreq( 0 ):0;
- x9 v9 Z! T3 ~* c" X        }
7 R2 g% m3 j, B- v        // MMC5
) \8 c$ f8 h4 U* T2 `& W        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
2 C2 t; H# }- U                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;( t8 t1 S+ d9 j
        }
; R9 A8 a! q1 T        // N106
% }# g" q! q# v/ Q        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
6 y% k+ g# T' e3 w                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
# l7 ]/ o# f: V8 L        }
! n4 e& f% r! i, ~' f3 Q0 T& ^        // FME7) D, K$ j- r8 l+ a& d3 G
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {( U' E+ P/ Z8 o' t
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
0 X- m( k! Y  k# _+ S+ f8 K        }. v7 m) u8 `! |4 V' a) h
        // VRC7
* O0 Y5 L8 h# ~3 [/ N. P8 P        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {6 o& d* p6 J( R2 z! J) G
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;4 o7 K1 \4 }) o* `+ B
        }
! \/ W# q; I- q/ y9 h) l: ]0 W/ s0 E" U        return        0;- G/ s% M5 W, c4 X9 {
}
; V4 p7 q  @) Q4 C3 X
9 J4 x1 s* O* P+ S! l// State Save/Load
) l) y( G7 L; H9 e' \, ]6 ?- Rvoid        APU::SaveState( LPBYTE p )
' i+ s  `- B- R2 i{5 j, a0 t9 u& l& B' c; r
#ifdef        _DEBUG
7 y7 Q3 v( q" }" }: O; JLPBYTE        pold = p;
; c& o( Z' T( P( h. B#endif9 |2 K, e# v3 z7 Z  A1 P' e

6 h: l; x! H/ e( D3 q( |8 ?# P' E        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
! D: \/ Q& A, Z! P        QueueFlush();" s7 Z3 m# Q/ _7 v: h/ V2 ~4 x5 z
& K. M; P% [8 s4 O0 |! K
        internal.SaveState( p );
, y1 _. C7 Z& @% n) D, y9 g        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding: `+ A( G0 `0 m

& \, z* q: `( r* m2 x8 }* r        // VRC6
" p9 g: j  u9 \2 C7 W/ u( R        if( exsound_select & 0x01 ) {
2 c8 O- D2 o; L8 i7 u                vrc6.SaveState( p );
+ x/ u7 ?3 w/ d4 I: _7 e                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding" c' `2 k* @. M
        }
9 c6 M) q$ }, P. v        // VRC7 (not support)6 N! ]- \0 z) [1 m
        if( exsound_select & 0x02 ) {0 d6 v, I. v+ Q: x
                vrc7.SaveState( p );
& M" r1 m. l& ?2 t2 N2 D                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding( A2 E2 ~7 p3 \- ]7 s
        }) @- Y& e# X4 l; B1 G: e
        // FDS" z6 z$ H# ^3 C0 L# g  k0 O
        if( exsound_select & 0x04 ) {% @5 v" e9 b" j& W, e, f
                fds.SaveState( p );- w! H0 b. p- g+ i) d
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding% b# S: K1 K3 R7 p5 ~
        }
, d# u& x5 C/ J' q1 I        // MMC5; S' x0 Q7 e7 |5 Y' j
        if( exsound_select & 0x08 ) {
  p/ v6 }) Z: W5 n+ o                mmc5.SaveState( p );
: o7 r; a2 d$ x* i. d' r                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
! D& {% I+ R: K3 C2 m        }5 w- D, ?0 d! ?* `/ D) L4 l+ D
        // N106* M1 ]2 S' D$ j5 R+ {
        if( exsound_select & 0x10 ) {1 q! L! @' B% S+ k$ K* x
                n106.SaveState( p );
& e+ |$ V0 j, @8 ~. ^8 `& w                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
, `% d% n$ C2 Y/ ^" J- p        }& w& n* v  E- O) k+ U. X6 e8 i
        // FME7  Q; V% X6 c9 P6 S! i0 H
        if( exsound_select & 0x20 ) {2 z' D% J2 e' [4 W) _- L+ q
                fme7.SaveState( p );
( o! X7 }3 f! r  M- u                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding4 J2 v( v8 d& T' {8 U! T" l
        }5 ?4 _. G& n5 J. K) E4 z
( g, Y" l5 R' U. u3 y* U
#ifdef        _DEBUG
1 _/ u; D2 e; J# q" f- zDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
: O! W, c7 {4 m#endif
9 M; @- Y( z7 s}
  y* w2 P: H$ A: e0 n+ V1 ]8 |$ a1 q
) ^. A% Y4 I) W% ?9 `/ Lvoid        APU::LoadState( LPBYTE p )
5 r/ r0 t! f1 l/ Y( d3 j: j{
- P9 l. X* W1 s( m# A) j: f8 y! a        // 帪娫幉傪摨婜偝偣傞堊偵徚偡8 z. K2 w; `* s+ ^
        QueueClear();# b" \& z3 e$ F* o7 ?
) ]8 c7 y$ |" q0 a. U. h
        internal.LoadState( p );
3 T9 C3 h# C" [$ m        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding1 v% f7 m. k) A% V- Q1 {6 P/ r0 m

+ b) L) ]. ^, v. o: e        // VRC6
3 g! Q8 ]6 s* @, j        if( exsound_select & 0x01 ) {
. ]0 p3 b2 E1 q4 h                vrc6.LoadState( p );
6 `/ P: ]( C3 t$ b/ L# l                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
6 h& c! a: ?# w3 ]' J  L        }8 X+ Z( T4 V; ^
        // VRC7 (not support)( G  m6 D7 ]5 J9 Q: {
        if( exsound_select & 0x02 ) {. X- H) z- O' b
                vrc7.LoadState( p );0 q1 h$ N5 |( X3 \" i# p3 W* q
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding2 G) c. G& I$ u) [% u- V' C1 |
        }
" [! X5 k0 g  k/ h5 m, u. l0 X        // FDS5 t8 q9 V; ^: a
        if( exsound_select & 0x04 ) {6 V0 p1 U# ^* l( a. R3 r& }+ E, s; b
                fds.LoadState( p );
4 S  j8 X4 r1 ^4 z                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
2 w6 S" G. g# h" K. \' ]- a; w        }
3 b; n  d. _6 ^. z        // MMC50 l  j2 u3 _6 M* U3 \8 @4 h
        if( exsound_select & 0x08 ) {
8 r- W2 E9 Y2 Q- {                mmc5.LoadState( p );7 z, T7 [3 z% k" b! ~1 w
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding; t- d; v7 o  w4 O
        }
6 F. J3 t9 p* s, Q        // N106: v9 r+ a: F. o" ~( P
        if( exsound_select & 0x10 ) {+ ]: N  a: X0 g/ n- P; @* x$ }
                n106.LoadState( p );
" M. e7 Z; o* E' S5 h                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
7 R' ?/ B* H- p        }
7 o/ _/ q- a! d  W. ~        // FME7; ^% J' f. D' `  }6 J. {' q  Y
        if( exsound_select & 0x20 ) {
6 z. t! Y# H' ?. F; d' Q                fme7.LoadState( p );7 i& Y0 u3 Y' `
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding8 u6 m/ y0 v( f& [) g8 H6 K
        }
- S" F" G% ]  D. X- @}
回复

使用道具 举报

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 : p1 k5 T" X! Q( {) N& m
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
$ m9 N) D) M& `8 o感激不尽~~

: R  |* E+ C1 q# O. D5 ^恩 我對模擬器不是很有研究,7 |  E& [' T* L4 ?" Q2 ]
雖然要了解源碼內容,可能不是很困難,
$ N/ \+ I% ^& @/ q不過還是要花時間,個人目前蠻忙碌的。
, d+ k5 K  ^. ~/ k, A" I
- H+ q0 x0 x+ O8 w給你一個朋友的MSN,你可以跟他討論看看,: W5 e: f. ~2 C- M$ t
他本身是程式設計師,也對FC模擬器很有興趣。
! m+ o8 R! ^# V6 p2 |! s& h4 C6 a: o, i* w9 A+ C
MSN我就PM到你的信箱了。
( x! P; P# J6 Z0 v) T& w* b) H/ h  d. x! E
希望你能有所得。
回复

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-9 13:23:59 | 显示全部楼层
呵…… 谢过团长大人~~
回复

使用道具 举报

签到天数: 82 天

[LV.6]常住居民II

发表于 2009-11-9 16:02:29 | 显示全部楼层
团长的朋友都是神,那团长就是神的boss。
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表 + s) }  v* m  z' Z1 s. r$ d
呵…… 谢过团长大人~~
$ ^. w$ n5 L2 O

7 o8 C7 i0 v5 b% H" v1 V: _9 z! n哈 不客氣,算是順便幫他找個伴,大家可以一起玩。
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 4 F* @2 C  l* b6 ~, c
团长的朋友都是神,那团长就是神的boss。

8 R! m/ K/ ^, W哈 不敢當,我只是個平凡人,5 F" G2 s) D9 D9 ]2 w+ B
要吃飯喝水,光吸空氣是不會飽的。。。。 :)
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙. L* y1 O/ Z0 M: Q8 v
ZYH
( V9 S9 N2 w( a- _4 tQQ:414734306! I$ K3 v+ |% D& R
Mail:zyh-01@126.com
0 G6 d0 l+ x+ d5 y' ~2 y! [" z' a: U% C0 R) m: O% P% s3 D/ w# d
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
( n" R- S1 p: W再次对团长大人和悠悠哥的无私帮助表示感谢~~

' u% [6 i! K# \( R不客氣  ^_^
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-4-26 22:48

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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