EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
. S0 o! f3 Y  R& u: O# C6 |楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~" ]8 e+ e+ ]& [2 q: W
这里有相应的模拟器源码,就当送给大侠了~~6 f, n: Y, Q- S. w
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 $ {- E$ p  {" C3 x& v- ?
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
0 g+ l5 r- A8 N7 |1 p6 J9 q楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
3 l3 Y7 p  E1 n3 r( z5 h这里有相应的模拟器源码,就当送给大侠 ...
7 ?+ J. w6 a0 x8 Q
聲音部分(Audoi Process Unit = APU):! X* J2 J& ^# U  r" J# G
.\NES\APU.cpp
; ?+ o5 x% R, e* b  u0 S.\NES\APU.h) h- |1 K6 M. M
) w$ t4 X3 u* O6 c
1 u  E! |3 W+ E2 ]3 f7 _! e3 r
影像處理部份(Picture Processing Unit = PPU):
1 l6 p, S+ M; @* C" b# ?# f.\NES\PPU.cpp/ m6 m+ O2 q7 m# w( [; A
.\NES\PPU.h
2 b' r1 }: Z; R( w4 g3 d5 G9 m$ \. r4 T/ A9 X
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
9 C5 f' t3 m# x(由于很多专用术语和算法机理都不明白,所以看不大懂……)
5 n" z+ C' [" Y) v& w2 W//////////////////////////////////////////////////////////////////////////4 _+ S1 e; ~* t4 L& Y
//                                                                      //4 J) ]% X7 G/ l1 J/ n7 K6 D
//      NES APU core                                                    //- A2 O$ H3 ~, A6 C7 n3 m
//                                                           Norix      //6 Z9 [3 j6 r  a
//                                               written     2002/06/27 //, ]& f) [! Y$ t/ u# R
//                                               last modify ----/--/-- //
9 p% R: ?3 x+ N# `6 m//////////////////////////////////////////////////////////////////////////1 f  B- j* B* ~, e
#include "DebugOut.h"4 c8 r( x7 t# z7 p8 t3 Q
#include "App.h") O5 I4 u! O  V$ r8 a8 J
#include "Config.h"4 d4 [8 v& Y" N% z- x
* _8 O% A# {1 F+ V0 J
#include "nes.h"$ o7 o+ L# T7 t/ x- k
#include "mmu.h"
, g5 X& L8 x2 I$ v/ D#include "cpu.h"
/ g+ H/ k! K* c% J2 A#include "ppu.h"
/ J2 C  }6 m# f/ V% O& s#include "rom.h"
/ _# }6 s9 E' a- Q9 ?#include "apu.h"
8 ^# n" t% A9 x$ E0 `1 R
: Y, N) ]+ J7 @1 m! x2 Y, Y// Volume adjust* Q! H. h" F# E! Z& X
// Internal sounds, X( @9 ~8 s, Y+ f0 c
#define        RECTANGLE_VOL        (0x0F0)! _/ D, |# Y) `8 u% _9 l8 p5 ]1 @
#define        TRIANGLE_VOL        (0x130)( ^" ^: e" ]$ l: h5 \$ J% t
#define        NOISE_VOL        (0x0C0)
" O) A6 q6 q, _, ~2 I4 Y( a% B3 m) F#define        DPCM_VOL        (0x0F0)
; m, i" d5 u. A// Extra sounds; g5 w- S3 m$ q! ^* w& b
#define        VRC6_VOL        (0x0F0)  ?& i8 @  {& X; v' C: Z2 A3 n( H
#define        VRC7_VOL        (0x130)
4 d' p6 @) L" P5 F" ~: w#define        FDS_VOL                (0x0F0)
( J6 Y9 y* P4 J$ B9 c) R% z& r3 A- [4 e9 N#define        MMC5_VOL        (0x0F0)) p7 f/ H# `0 R" R" Z
#define        N106_VOL        (0x088)
. i* d/ P0 w% b' N7 T; |& u* c#define        FME7_VOL        (0x130)7 s  ?6 b4 ?1 p6 D

7 f, d5 u* j! M$ e1 wAPU::APU( NES* parent )
- V% g' x' |& m# [0 v  {$ ], J{
+ h2 F. K7 T8 m7 z4 i, s% k9 k        exsound_select = 0;
, _! i8 v7 O$ _8 p! [) u* q$ `8 D) A5 P) u- ]
        nes = parent;# W0 y) |; T* ?+ v; H
        internal.SetParent( parent );' P! N# T9 M* n# h% A

- B6 m* e6 t; z, ~+ p+ N) m6 u        last_data = last_diff = 0;1 }9 ]( a4 L$ N2 Z7 N! G  N& r

  h9 h$ B+ F& T# N5 h5 Y' ^        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );4 ]8 `2 Q/ P( m  c
' `! r2 s6 K$ b$ P* i
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );( ?% P# z9 R$ `; d3 l
        ZEROMEMORY( &queue, sizeof(queue) );+ h4 \& c, y1 \/ I8 p4 q
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
4 a. e* p+ v# F! ^" Z/ l5 k% g2 V
; e: f3 q/ u* D9 S1 q0 F7 U        for( INT i = 0; i < 16; i++ ) {5 _$ W9 o- r- Y0 f1 ]
                m_bMute = TRUE;0 X$ u; S* y) b. j
        }
1 V- Z  Q7 k5 ?% b}' {! U8 w( [" l) k
* |2 e! t; ~. b
APU::~APU()" w. _. O# @1 b* g2 T- s( C% e
{1 t: Z( \4 ^0 w: x/ u/ ~9 e
}
2 d) n6 t$ g# T6 D& y5 w' {8 {5 l  V# _9 ^
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )0 F8 v: F5 f/ l1 n
{! [& ]& V  W( y- z) D  u# }6 [
        queue.data[queue.wrptr].time = writetime;2 I; o- I% v  c# }1 e! n* `; |. T
        queue.data[queue.wrptr].addr = addr;' x8 k( {' D/ T- b5 E
        queue.data[queue.wrptr].data = data;
0 h8 H2 t/ ^4 c/ |/ z" I        queue.wrptr++;6 a% a( L; U) @! K: ]7 h8 r
        queue.wrptr&=QUEUE_LENGTH-1;: j: n+ @- ], P  F- J
        if( queue.wrptr == queue.rdptr ) {* }9 T3 t2 {: i3 L- I3 k
                DEBUGOUT( "queue overflow.\n" );. r0 t9 L# X$ e7 ~4 i& A9 M
        }  ^3 a8 O& q# b
}
# }* A! M# i& h7 [+ \
" O$ o" ?# M4 M0 N$ M# J$ WBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
6 ^; m6 @) [% J3 W9 E, Z; \1 |{
/ B& r; |  u4 C; l        if( queue.wrptr == queue.rdptr ) {/ N5 n9 e, v! }
                return        FALSE;5 j  S- T5 \2 j( `- m% S4 `
        }
5 h, C9 X/ O: [7 ^$ R! q' T        if( queue.data[queue.rdptr].time <= writetime ) {3 m! t! b. G, a9 \4 e% h6 Z. W! X
                ret = queue.data[queue.rdptr];, m8 y; t. D" k) ^1 L# }5 p
                queue.rdptr++;
' i5 k& [, W( q8 w) k                queue.rdptr&=QUEUE_LENGTH-1;' Z2 I! j1 Y$ _; }* i3 K# q
                return        TRUE;
2 m4 Q8 {  O+ S; V: S        }
  W* ]& w5 k8 U: j* Z        return        FALSE;% `  H3 `  j" g$ {! v
}/ V* K( I9 l( d' V$ K  s2 {( F: ^

. F9 G2 B3 R9 w: S: wvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )6 a+ b1 B' |& I  R3 v, B
{
; I5 K, x' d/ a9 L: M        exqueue.data[exqueue.wrptr].time = writetime;
: S# J' N5 Q2 \# ?. k0 V        exqueue.data[exqueue.wrptr].addr = addr;) [% [" l8 w/ Z# ]
        exqueue.data[exqueue.wrptr].data = data;
. U; V; _4 A( e4 l7 A6 l9 J        exqueue.wrptr++;" q% \, z9 m$ \' }0 q6 g# d
        exqueue.wrptr&=QUEUE_LENGTH-1;- w2 T) t5 x# ?- V0 X
        if( exqueue.wrptr == exqueue.rdptr ) {* v. k- X( `3 r, s6 }) j) s
                DEBUGOUT( "exqueue overflow.\n" );7 m+ n# U7 s+ e; R' ~$ `1 {
        }' `  ?" L9 n: c; I5 R# }% e
}2 P& }: X; o8 v# X/ q
+ @4 h6 t& w5 j+ @: W$ E$ g6 g
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
1 }$ }9 w  M2 _" Q$ ~, ~{
0 B$ D. |5 Y8 Q& w( g        if( exqueue.wrptr == exqueue.rdptr ) {
; M5 a% [! a* S: P9 i$ \# o                return        FALSE;
/ C: m8 V  L3 K1 H* @        }
5 e9 S. Z" V4 m, I) T+ h9 K. z0 u5 c        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
. P) f5 i- B; V: [8 K                ret = exqueue.data[exqueue.rdptr];, }4 n0 B* C8 c
                exqueue.rdptr++;
) ]2 R# A3 s# e' p2 c                exqueue.rdptr&=QUEUE_LENGTH-1;
5 ]8 w9 `& \7 |, I' U                return        TRUE;6 n9 C0 U8 d, x9 s7 W( G! |7 b
        }6 a- C0 b* X. F
        return        FALSE;) v( d+ n, x- ~! m& {5 ?! [
}  V: b4 Q; o# @% D, V
* ~* h. Z+ W- v# f4 H9 Y
void        APU::QueueClear()) M" c$ |2 x+ W
{$ [! ^- ]* X& p) |( v+ a
        ZEROMEMORY( &queue, sizeof(queue) );
- W! m) S7 ~4 _  F* O' O+ B        ZEROMEMORY( &exqueue, sizeof(exqueue) );3 |5 L6 b: b( E) P+ W! e2 ?( H3 K
}4 N$ P5 a: F4 |5 K8 e
# v3 r% N, W* U
void        APU::QueueFlush()
5 w  s8 \0 {" m( |6 w, v{
* Y5 K; ]6 x+ S! q. ^, q  K! t3 S        while( queue.wrptr != queue.rdptr ) {
  a8 C2 L* W! m1 x                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
; B7 |$ N- s, q, K  `: t                queue.rdptr++;, I% \# D& ]4 v( f: a4 i
                queue.rdptr&=QUEUE_LENGTH-1;
4 i( S) e) K* j7 T5 p        }
6 r. [6 o( N+ U7 C0 f8 g3 j/ e7 \9 `2 |# S
        while( exqueue.wrptr != exqueue.rdptr ) {
5 \. l2 B; z/ V3 P/ a! @- P1 c                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
% q# e8 {' l- m3 D" C                exqueue.rdptr++;
. Q% D, G2 m( o" X0 O                exqueue.rdptr&=QUEUE_LENGTH-1;
% w% X5 n7 S; B1 d# n$ h" w5 N7 s        }
: j% T$ k2 Y/ w) d( i: W+ z}
* C, g- e* D0 p3 w
3 d2 g( f% A% J& S' |  Z) Wvoid        APU::SoundSetup()& f# \1 \" U, i4 t1 [) O4 R
{, g+ U3 |2 t6 u/ Y: B
        FLOAT        fClock = nes->nescfg->CpuClock;3 z7 e) h- p: @  g2 m# F* j
        INT        nRate = (INT)Config.sound.nRate;1 L4 }. B& J- h2 l$ X# E4 l! [, s
        internal.Setup( fClock, nRate );& [1 i! U. @: }3 K
        vrc6.Setup( fClock, nRate );- u6 m+ U2 |$ P
        vrc7.Setup( fClock, nRate );: K9 t- e) ~* \
        mmc5.Setup( fClock, nRate );
# q( X$ P0 ^0 y( k9 ]. ]        fds.Setup ( fClock, nRate );
$ S8 C" z3 _, Z        n106.Setup( fClock, nRate );
- C& P# \- m- b* q) J3 P# l        fme7.Setup( fClock, nRate );3 ?% p! N/ U! K0 p6 X! R
}; z) O" I9 `, q- U5 F1 N( o# A% A

4 Z: ]: z8 l" Q/ u6 y# avoid        APU::Reset()" {! V8 y. Z' U+ N. G: _! R6 }
{
! M, d# ~) h+ A! F7 a        ZEROMEMORY( &queue, sizeof(queue) );. A' k5 \8 ?" x! O# W
        ZEROMEMORY( &exqueue, sizeof(exqueue) );. X+ y  _+ s& ?2 s. ~* T' d

; ^# Y6 E* f' q$ [; M1 R, c        elapsed_time = 0;
% A8 C" l" W) K- v2 `# h8 J8 l/ w9 r, u1 r. {4 i. N
        FLOAT        fClock = nes->nescfg->CpuClock;, l$ F9 o( j& h4 G, l
        INT        nRate = (INT)Config.sound.nRate;
# ?/ l* A* d1 U+ j1 t/ H' _9 t9 x        internal.Reset( fClock, nRate );
  R3 G; n: |" ]0 c' O        vrc6.Reset( fClock, nRate );4 }% @: C( U# g' y/ ~9 m& i
        vrc7.Reset( fClock, nRate );
! z( x" m6 y+ f! I  v$ Q5 q- O8 T7 D        mmc5.Reset( fClock, nRate );
" Y4 M2 O8 F" o1 J6 r% R        fds.Reset ( fClock, nRate );; q; m4 X+ H0 S
        n106.Reset( fClock, nRate );" @0 ^3 X" E2 Y% Z( x  ?; h
        fme7.Reset( fClock, nRate );9 p7 i! S" L+ P
" [1 o* ?" h! o; {3 j* S- H( m
        SoundSetup();
1 w* i& A+ K* b; y; c6 s}5 |! I1 S: f- c) V6 e
, y) j# g8 ?7 Y8 l
void        APU::SelectExSound( BYTE data )  X7 l' e6 Y8 g- j! Y0 d! O7 U
{' r( U) L  l2 W6 r9 o# t
        exsound_select = data;
1 R/ \% X7 b1 {4 _3 P& U2 U}$ H/ ]' f7 F6 y9 }2 ]; r9 a, i- O

1 C  i3 j( v- ~* d+ o* s; gBYTE        APU::Read( WORD addr )
( V! D9 E0 T& r: X6 [7 k{
) A, u, |2 x" r5 B        return        internal.SyncRead( addr );
: Q, x8 L) F4 C8 }}
. w. [' r2 c: i. E1 p5 T% x7 t# f  F0 M' G. x$ A
void        APU::Write( WORD addr, BYTE data )
9 @- D. s7 |; s& r6 b5 {{! w( S$ t6 a2 i0 S9 Q: B
        // $4018偼VirtuaNES屌桳億乕僩+ H2 ^6 g- d) S2 g% k. Z1 t
        if( addr >= 0x4000 && addr <= 0x401F ) {8 I% K- I- X% Z: P" K4 |
                internal.SyncWrite( addr, data );
' ?" D( @: g% G) O! q6 f                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
+ z" G/ @  a: R4 P0 v2 x8 Z        }1 a2 a) W/ h# L( x$ ^1 h
}
( O6 T7 ^: ?  o/ F" w% j4 J* t5 y1 `* r" g6 {6 }# h2 ^
BYTE        APU::ExRead( WORD addr )2 E" ^2 H+ p3 L/ v/ j! h/ c/ F& Z
{" P' \9 `2 J/ w" s' }/ T
BYTE        data = 0;/ t7 C, Z+ i& S# X) y
  _( z9 O& P" M
        if( exsound_select & 0x10 ) {' t0 S. m8 a* k: Z$ L3 a2 V
                if( addr == 0x4800 ) {
6 H' d' g/ m& t+ n                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
5 v  ]3 Q' s" Y5 N                }
! u* h9 K; w2 V; u, x$ p        }
/ m  ]! u* \- V% W        if( exsound_select & 0x04 ) {
6 }1 p' d; c! P3 f) W. K- p                if( addr >= 0x4040 && addr < 0x4100 ) {
! Y! {) b! _+ A5 f/ [; S                        data = fds.SyncRead( addr );8 i1 Y% H0 I5 ^' L0 y
                }6 f: ~) t% |. H1 k1 N! y
        }- q) b9 q, r4 {  }. L
        if( exsound_select & 0x08 ) {$ P4 O$ y8 G( H3 ^5 V- h! Z2 @
                if( addr >= 0x5000 && addr <= 0x5015 ) {- U  D3 _5 |1 r2 f9 X9 s
                        data = mmc5.SyncRead( addr );
5 W: D1 B* |$ A                }4 p( ^2 o* W) D; J: l
        }) s2 u' H; K( h* g

& z# t( m+ V: m6 u) i        return        data;4 H, e$ O- m( B! [" o' V
}
5 d1 r: ?$ O3 U- X9 z7 Q
6 h' S- v8 b& c, k# F4 @) C0 Gvoid        APU::ExWrite( WORD addr, BYTE data ). N- v# n% `- @4 j
{
: e9 A' {! J/ P4 q% I/ q        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );1 S& T# u  r0 E2 e, [$ [

9 G' |/ J* B+ J7 L        if( exsound_select & 0x04 ) {& j- E5 a1 D/ O; ]! V/ }- G+ j' O
                if( addr >= 0x4040 && addr < 0x4100 ) {
( }8 H3 x+ y: M' a) ?; q                        fds.SyncWrite( addr, data );
! Z2 P% _5 K+ ^                }
, Q0 |) H/ J7 z  ^6 ^! W        }8 e9 i* ]4 l% b% l5 i

  K5 \  n8 a: B) Z9 K: X        if( exsound_select & 0x08 ) {
9 t7 v+ |/ U- [/ \- N) Z( f                if( addr >= 0x5000 && addr <= 0x5015 ) {8 J) [+ X* z4 \6 E
                        mmc5.SyncWrite( addr, data );' k- v% R3 T+ q* L
                }
8 T! Z% \$ g: Y* ?        }
$ m* }  F2 k1 Y- S7 o& ?, }}
( q- E* g) q  N6 R- ]/ f; X5 ^* L+ h% n  L' ^3 M
void        APU::Sync()( P6 ^# U7 |: o9 |
{  [7 m* G7 r3 s: w' j; ^. t. J' u! H
}* Y7 [: B( w0 }* m9 B  @6 Z
% {3 D( X" Y- e% C3 ]5 X
void        APU::SyncDPCM( INT cycles ). R! G* ^! h" v: d  s; q$ S
{
1 n0 q( @. X8 C! E        internal.Sync( cycles );8 [0 o% y+ \( w) H9 t

3 y; @' {- t9 Q! q5 U6 K+ {        if( exsound_select & 0x04 ) {1 I% Y' a, ]" i' \
                fds.Sync( cycles );
/ c3 u2 I; m6 y3 s) Z7 x" A" l        }
& \8 p# q1 c; J8 H# }        if( exsound_select & 0x08 ) {
8 m. c/ K" c0 g- e; P/ A$ Z                mmc5.Sync( cycles );7 Z  C$ F; I: h. n# S1 j
        }8 J9 Y( ?9 d4 v9 J/ D* Q
}; I* f& i0 p5 ], [* ]; Q% H

8 Z* z: J" W$ `) l/ Ovoid        APU::WriteProcess( WORD addr, BYTE data )
) I+ \  F+ V% ^, k/ ~$ R{
) W1 g( T  }; d  ?        // $4018偼VirtuaNES屌桳億乕僩# L: h8 o6 g, i
        if( addr >= 0x4000 && addr <= 0x401F ) {
6 a% {  c4 X, t& N5 U! V3 R3 E                internal.Write( addr, data );7 d$ [4 l+ a# L3 y9 q0 W6 u* s1 S
        }+ H) \3 v$ s7 e# l
}) {3 D- b) J  q% Y2 `1 O

( U* E, ]1 R* J8 U) xvoid        APU::WriteExProcess( WORD addr, BYTE data )
* P; Y/ c3 m+ g, m{) H; f2 @* q7 g5 E
        if( exsound_select & 0x01 ) {" A9 x0 R) E; ~9 S6 j7 x
                vrc6.Write( addr, data );9 g+ r5 t  U/ ~+ Q; ?! N" e( N) k: }
        }, B' a! b# I! D- e1 C
        if( exsound_select & 0x02 ) {
; V" p& u( f- f6 J, c" B$ \4 b                vrc7.Write( addr, data );3 e' N6 V8 o  _+ m2 s9 j( K
        }( O# [" R1 P. S8 j$ m7 x
        if( exsound_select & 0x04 ) {
9 V7 ]4 g% m9 u' A  a: U9 m                fds.Write( addr, data );
7 T. O- x2 Y; e* r- b- \        }
9 L1 h% j8 h8 l" U2 c        if( exsound_select & 0x08 ) {
9 d1 W) z" H$ t9 W5 A4 }+ }+ Y: }                mmc5.Write( addr, data );* }7 z, b" j& L+ _* c8 G
        }
; X+ c5 c9 u0 l0 a; i5 u( ]        if( exsound_select & 0x10 ) {
# S+ q- H- w. P7 L5 N) ~( H) I                if( addr == 0x0000 ) {
/ n- f  o; M: |) f: \8 [                        BYTE        dummy = n106.Read( addr );  M. m* ]1 p  l! z& Q5 u
                } else {  p: h; H; q* U% h
                        n106.Write( addr, data );# }& g+ b/ ?6 c! Q. N3 W9 f4 }+ R
                }, y! M  V* u/ L, V% b
        }
) U' z  B) Y5 p5 {* X& ^        if( exsound_select & 0x20 ) {
% Y5 L- ]9 `( u2 `0 H, k                fme7.Write( addr, data );
$ M* H: a2 J; @" S        }: r8 J" n) _# q
}4 D/ O1 n+ I9 ?# |: b/ w4 U

9 K8 J( c* u  _+ V4 [void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )6 V' @/ H" z/ y8 `. P3 K* x. `9 {
{
0 x. Y7 {/ e9 S) @2 \INT        nBits = Config.sound.nBits;
! D1 I; ?9 H- |- K3 cDWORD        dwLength = dwSize / (nBits/8);5 P% N$ N. W! g7 Z
INT        output;
  k7 w; u6 v- B% ?' mQUEUEDATA q;
8 S& l% |' {/ D) W' E; DDWORD        writetime;
! v' k" I( c# }5 ~8 G* |! V2 m/ n* h! q6 g
LPSHORT        pSoundBuf = m_SoundBuffer;. b5 s0 x* Q7 h' B) k' V
INT        nCcount = 0;1 j5 p) Z8 @' B( w6 b7 Z8 Z/ p

; K8 o( v3 e: ?4 e6 ^/ V/ ^* `INT        nFilterType = Config.sound.nFilterType;
! A" T) S8 D4 |1 C6 |- M
* n, g/ S1 n* I3 h$ t        if( !Config.sound.bEnable ) {3 q: v/ R! e. q9 C- W
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
0 N3 b0 B. l" ~5 w6 H& T6 }4 H                return;0 @' q( S# j3 R3 F! y( s/ K$ O: s: f
        }2 k! m% X9 V  n* |' ~
$ d1 E, g! {4 S) b) [# d+ ]& r
        // Volume setup6 w0 t1 ~6 @# k, B- o8 G
        //  0:Master
7 s, o. y" n5 H& G        //  1:Rectangle 1
( Z! _7 X. |/ C        //  2:Rectangle 2
- ~5 m' y/ W0 b: C5 D        //  3:Triangle, Q8 _) S" y4 o- u6 k' W, ]7 z
        //  4:Noise
. m$ }  [' e; T! j        //  5:DPCM: M/ ]7 T; m$ q/ H$ a
        //  6:VRC6
$ g/ o% l+ W* v' M        //  7:VRC7
5 X5 ]. D! D0 N2 L& c1 i4 n- M        //  8:FDS
& R& ]4 \' g5 }7 n        //  9:MMC5
! i: {3 t5 G  P' `/ q        // 10:N106
  M' J) {5 e; V( \, y. k+ R        // 11:FME7
3 f' r+ x# o3 ^8 X' Z" w6 o, M( B        INT        vol[24];
2 K, w+ X) |% B1 f; C! {" O        BOOL*        bMute = m_bMute;
. R+ K) S0 S$ r5 {& z        SHORT*        nVolume = Config.sound.nVolume;
2 ^; G+ f! j+ Z  R
2 G# D9 A0 c2 ^( q$ d* J) u        INT        nMasterVolume = bMute[0]?nVolume[0]:0;/ M, n7 d- T/ X& \2 |9 t% e

3 r, p5 W+ q' |% O% F2 d5 }        // Internal
/ R* z2 }# I8 [9 E        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
( q# B. C4 F! O- I' F! N+ i1 q        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
: ^- W7 E' H% k' \+ _! j        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
* @& b: }+ i/ u3 U/ [% u2 N! p7 d2 |        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;, s6 J% T. S0 _
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;. r4 p2 F4 x( X- p6 Z6 ~1 X5 T* p4 l" u

  f+ h- V9 w4 q        // VRC63 ~6 Z! ~+ `, P( Z. k9 B
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;" I$ T6 R2 S, g  D+ I
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
; S6 a2 C' S3 u9 }8 Y8 {6 |0 X1 \        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;- F8 ?& W5 G- v; J; t  U/ `: U

% V) g. T$ N2 Q- t        // VRC7
9 |6 R/ {% Z0 u# V  J. U# B        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
! W# s9 m* B+ q% {/ j( I5 H* L
; e1 x2 d6 a; y8 R. t" v        // FDS
/ ^+ k5 D, U0 M' L* E        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;2 c& r3 S* ^) u& {8 v2 v
, x$ C" Q- R" N( _) h# G
        // MMC5
' e% ?' [. R* K2 ^. F+ z; q4 E        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
1 H- d! C1 @) D: M7 t3 S        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
/ ^2 ]6 [$ j1 W! r( \+ v        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
  n6 I& C4 _" m: U, A! [* `, M# K8 d) F) h$ h/ i. r
        // N106
/ H3 e0 }2 P  Y* t        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" N/ _$ w8 b7 R  O* U- C; t. `% x        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, b$ L0 g* _) h4 \2 D        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
; c: H7 [; e- b- T        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: t' d' D- `0 d! H6 w: V, n& M% Z' W        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;4 Q, e+ R1 l, z& g: c
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;( ^* V8 p8 V7 P, E
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ i5 E0 H7 Z) l. r$ R: k. l! w4 N7 Y
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ A7 O6 O/ j# }7 T. E4 ?9 N4 G* A7 L& g
        // FME7
+ r0 v8 _$ c$ l# _        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
6 U: M+ R& D; Y7 Q. j7 y* f        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;9 d% h# H# w% F4 _" X5 I
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
+ Q% B; `1 @5 `9 `0 }) g- n3 v0 W$ e/ f9 B/ ?2 q( ?# ?( g" q
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
( q" z/ @% u( q# ?7 |% q        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;+ q6 j* P) S( ?9 O6 \: G' X2 b
: Y+ }2 j7 h1 W" f6 p9 ]3 G
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
9 m$ T! U% U9 U# F( ]% r# X4 O        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
# k9 ]+ ]" V, C: X                QueueFlush();/ I$ ~) B' A5 v# X
        }
  B, z( t4 V( J5 ?' X. t1 o
2 D/ D1 a- D. g. ^- t' |& g3 d2 i        while( dwLength-- ) {
1 I& |5 D( p: S9 K1 m  [9 b                writetime = (DWORD)elapsed_time;* k/ |& a$ i7 z, b
( h1 ]5 z1 x3 `6 r9 ]/ j# Z& o' M
                while( GetQueue( writetime, q ) ) {' A: G+ s- e/ x2 h
                        WriteProcess( q.addr, q.data );
* e$ p9 A9 f- a5 ^6 R2 ^, M                }
" a3 v1 Y% Y- @
5 z& u6 H' c% ~& u6 k8 N                while( GetExQueue( writetime, q ) ) {
& M0 X+ T/ y; R' t% o* A# S                        WriteExProcess( q.addr, q.data );
2 I4 o0 D% }6 {9 c. n) n: R. g5 w                }$ B3 Z, ]: K3 y! a- u% t% S

/ M5 g( N3 u. G4 @& x6 a% u% n                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7- y$ W1 B& e$ J: M: G
                output = 0;
. W/ d' I# p* k: {  q) ?                output += internal.Process( 0 )*vol[0];
9 A2 F! S" \/ K7 A, T                output += internal.Process( 1 )*vol[1];
/ Y$ M" t9 G4 F: b: G                output += internal.Process( 2 )*vol[2];
* {3 \* [! z$ ?  I                output += internal.Process( 3 )*vol[3];# a7 M) {* ^' d0 r% A4 k1 U! Y; E
                output += internal.Process( 4 )*vol[4];
% X  l$ L+ p! ?& I/ C. V4 O9 u
3 @4 k% o4 g; F( B( E2 Y                if( exsound_select & 0x01 ) {- v. N. a3 S. u& P- Q
                        output += vrc6.Process( 0 )*vol[5];+ k/ f: Q0 I0 p* D) n0 [( e
                        output += vrc6.Process( 1 )*vol[6];  L/ w+ ~! k2 _( {; ^2 R, \9 |
                        output += vrc6.Process( 2 )*vol[7];" I1 _- J6 t) y# [. z: `& |+ C
                }+ Y1 T: @" o+ s: }6 Y. N
                if( exsound_select & 0x02 ) {; T5 T5 E8 e4 |: ^9 X
                        output += vrc7.Process( 0 )*vol[8];
' t9 ]& @2 W, V( T# v                }; M/ ]% s5 s0 q$ p7 J
                if( exsound_select & 0x04 ) {* C5 K) m* d' X1 b; d" Q
                        output += fds.Process( 0 )*vol[9];
( U! ^7 n+ B: m& a$ Y- N                }
4 l& w, K: l/ k- a$ u& g, v& r                if( exsound_select & 0x08 ) {0 a, {$ N8 T: m
                        output += mmc5.Process( 0 )*vol[10];
- L& r& y; N8 H6 J8 K                        output += mmc5.Process( 1 )*vol[11];9 |) B( _* h# k* a1 o0 z
                        output += mmc5.Process( 2 )*vol[12];
! }. C$ o) s9 N& @: _                }# F) X8 U) e* N6 l
                if( exsound_select & 0x10 ) {  T% S+ A# l6 s0 \
                        output += n106.Process( 0 )*vol[13];
( \; q. W  i& [+ K$ D3 X0 Q: `3 N                        output += n106.Process( 1 )*vol[14];. @4 R! b7 a5 W* H( c
                        output += n106.Process( 2 )*vol[15];7 n" |5 V& Q. U/ B8 j: z6 O) \
                        output += n106.Process( 3 )*vol[16];
3 n* k3 }* y' d  N  V6 x0 A                        output += n106.Process( 4 )*vol[17];
  U) i) g* V& G                        output += n106.Process( 5 )*vol[18];
' G& ?7 v9 v5 a; r/ f                        output += n106.Process( 6 )*vol[19];
2 i. D. S/ t! P3 e/ M                        output += n106.Process( 7 )*vol[20];
. p$ B- M0 [% d$ @, d2 @# @                }$ a. @  X; O: K* T$ }) F
                if( exsound_select & 0x20 ) {5 Y( o+ ^  v9 r5 A7 ]
                        fme7.Process( 3 );        // Envelope & Noise
% e# Q8 b1 V1 V3 p6 s5 c' P0 o' X                        output += fme7.Process( 0 )*vol[21];
% S- b0 W6 e* T& r; E/ J" Q                        output += fme7.Process( 1 )*vol[22];- h  Q8 V  Z& Y& w( j1 N6 q
                        output += fme7.Process( 2 )*vol[23];
6 c1 W+ G5 Q! S1 R  V                }) _/ {2 J0 f/ Z" c
# q" n* ?! }* w* P9 }0 M" [
                output >>= 8;
' j. r! o* y3 d! ~4 `9 H1 M* P$ R$ o
                if( nFilterType == 1 ) {
) P* I( j; G5 p                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)) q3 [+ G/ y+ ]0 f) t, |+ L
                        output = (lowpass_filter[0]+output)/2;$ D! A3 k' N& O4 X" ^. }0 q
                        lowpass_filter[0] = output;- z5 L9 ]8 Q  D8 j5 F/ g3 W/ M
                } else if( nFilterType == 2 ) {
5 V" i0 P% F9 L8 [! v                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
7 c% U2 V) t/ Q- Z                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;' i. l' D" p0 Q% \' |# o2 s
                        lowpass_filter[1] = lowpass_filter[0];
. ~6 s9 B$ C* s- o: |5 X) `$ T                        lowpass_filter[0] = output;
" S* F) B( I& Q4 N! f                } else if( nFilterType == 3 ) {' c* ^- O% i8 k
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
5 r, v0 v3 D$ K1 }, I/ e4 B9 e                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;# F- w# a7 f- T
                        lowpass_filter[2] = lowpass_filter[1];
5 k" c( ~& V# t                        lowpass_filter[1] = lowpass_filter[0];
$ ?0 @  y. `8 o3 w- ]& X1 {' ~: m                        lowpass_filter[0] = output;
2 c+ E6 x: w" [5 R, @& c                } else if( nFilterType == 4 ) {; K, l. t) [3 G% `
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3), S1 d7 p$ s1 a2 ^8 n
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
5 ^7 U% K/ E$ x8 ?0 O                        lowpass_filter[1] = lowpass_filter[0];- V! V8 U2 i. K( P& Y
                        lowpass_filter[0] = output;
, E  b" Y+ k, C) p: O1 K$ Z! L                }
% a! E9 I; E9 {) L- E1 n  w1 z
& _& q* N- ]9 s! M2 v#if        01 z- i5 Z1 E, S
                // DC惉暘偺僇僢僩
& L) t" F) R8 G5 s- d6 P                {
! H& h' E, E( `6 z0 W7 o! ~                static double ave = 0.0, max=0.0, min=0.0;2 ?8 h2 s, k0 z& l/ n
                double delta;/ L7 q$ M1 Y: c5 }
                delta = (max-min)/32768.0;5 p6 z( k9 A* x! {) E8 s  n" U
                max -= delta;
$ H( \4 a8 [* k7 d( N                min += delta;# s0 s/ C0 P& l; ^2 C# \# ?1 }. \
                if( output > max ) max = output;/ Y6 K1 B. ~/ H) h  [
                if( output < min ) min = output;
7 f, u+ K3 `) \; d) v                ave -= ave/1024.0;
7 s9 p9 H: s9 s* ?                ave += (max+min)/2048.0;( y# B5 }7 {9 o4 T
                output -= (INT)ave;
+ W% t. [- L9 X7 c                }
# A" e5 |: Q- b8 e) }#endif
* e- E5 V( \% g#if        1
. K# m7 ~4 @7 _) e                // DC惉暘偺僇僢僩(HPF TEST)
6 E4 c) Q% D7 [% e5 Q- _; j                {) }. z3 E8 t6 ^. T7 H  u! _, X4 `! A
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);) X" e* B! _6 g1 f4 r
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
& M+ t1 s& v' H  F" p* Q                double        cutoff = cutofftemp/(double)Config.sound.nRate;
, |& X4 @% D  k5 g                static        double        tmp = 0.0;
7 ~- O( H; ]7 G% o% p                double        in, out;
% |4 ~0 d1 u& i; H0 s% D" ]+ s2 y1 y% n0 s) k
                in = (double)output;
  \3 |5 C! M( }                out = (in - tmp);
: P+ V5 |( P# S4 {# f                tmp = tmp + cutoff * out;
1 c8 v0 \( B6 [1 E! {0 D' I& e: W4 n. R- }! }
                output = (INT)out;" e* K6 g3 z, ]+ ?
                }
# w. o& G1 |" f. E#endif
% v, s8 t! U  h* Q* o; m8 u#if        09 x/ H! R- P! q) f# w* c; E- Y
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
4 P) k8 Y2 e. N4 h                {# w# m  }& Q% P* v
                INT        diff = abs(output-last_data);
: |) ?. Z$ a0 M) d; _6 q                if( diff > 0x4000 ) {
% x; V" Q; Q8 l: v! R                        output /= 4;( @. q) A( }2 V6 _. A
                } else 5 y' @4 d! m0 w! _& |
                if( diff > 0x3000 ) {7 u- G( W, Q: c" Y8 @( b4 k9 Q
                        output /= 3;
/ L7 b/ O: ^! h- k                } else
9 ]9 t( P( b0 U4 h8 G                if( diff > 0x2000 ) {" |' E: B! Q& z5 r% d9 \# M
                        output /= 2;( t2 m9 F' B! c, r
                }
2 o  G$ J( ?& H* o                last_data = output;
7 Z7 `) ?8 G7 C                }
' h4 d& b2 d6 @" p( s#endif
9 L, {3 _' J& _$ k. }7 h2 f) Y* {, u                // Limit! d6 b& z1 Y3 M- v
                if( output > 0x7FFF ) {# h# P. ?+ K) `' C1 [8 B% E4 s
                        output = 0x7FFF;2 X1 D7 E' ]% F
                } else if( output < -0x8000 ) {
7 W, ]( M$ D7 `1 f/ u, V9 _                        output = -0x8000;
/ S  Y% W) E: D( e7 P) x                }
& L4 W! d! n1 h5 @
8 H' o6 n' N& y0 _1 B, Y: [$ `" V- e                if( nBits != 8 ) {
6 n' N% Q  s, @9 \  j* y                        *(SHORT*)lpBuffer = (SHORT)output;+ S& i- f+ E; ^7 R
                        lpBuffer += sizeof(SHORT);) Q1 o9 d2 x& n& D
                } else {4 v( ^' `* G; L" W$ s
                        *lpBuffer++ = (output>>8)^0x80;
7 M' H) i8 @# B                }
/ i( a6 z. i! a6 q! c* s% \; r6 N, e
; E0 g  \( T7 a, z                if( nCcount < 0x0100 )0 @( e" U8 ?3 G, q. n: h( F
                        pSoundBuf[nCcount++] = (SHORT)output;
. c. t+ a: T2 f) ~* `& V/ |+ ^  q. d6 y5 Y
//                elapsedtime += cycle_rate;0 Y) J5 N% J" [# `+ n7 u
                elapsed_time += cycle_rate;& ^' d+ N" k1 i6 b5 v
        }
* q6 z" I: L, r7 ~  X3 W& @7 ~
! i6 G1 J' o0 }, X" J1 s2 z' H* T#if        1+ l+ l: m3 K) z5 \
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {) Q0 I7 F0 r3 B" q3 A" r
                elapsed_time = nes->cpu->GetTotalCycles();4 ~# a3 T" B7 A% E
        }) u, C. Z9 e  b. K2 O1 ~  z
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
" @. ^( ]' _# K! R                elapsed_time = nes->cpu->GetTotalCycles();
! U4 B: W6 B  x% E! s        }
; q  \- O( V5 g" e% A#else
& Q. S% T* p3 u* v" d        elapsed_time = nes->cpu->GetTotalCycles();
2 _. m& f0 a; p' U& f#endif6 s0 s# @( S7 Y
}
, j' ^8 `* n2 B
, w  k- m& t' P2 D# E// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)1 G4 z# D/ T0 D- N8 ]5 x
INT        APU::GetChannelFrequency( INT no )
2 u! @  Q/ l& }) j5 q9 A$ r{! `9 L% \4 l( E
        if( !m_bMute[0] )
% n' n3 M" |( i+ [+ G. |( P                return        0;% U, P) x: G: h' C5 p
+ S6 l  W! W- P0 F5 \& k
        // Internal8 ]' R& I4 x- @  |
        if( no < 5 ) {# K8 E0 H9 f" u0 j. o- f' x
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
: b# [$ {9 [) K. h- V" F5 O        }
5 @4 i/ b8 ^) e        // VRC63 g2 ]/ x( U8 k% |  ~
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
) w6 [; M) q3 a/ u# x                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
+ G6 R0 y# R4 q* M        }# X' k! ^1 ?% ?+ e$ C
        // FDS
9 A! u" t! N2 _: Z! y        if( (exsound_select & 0x04) && no == 0x300 ) {8 B* N8 }/ V+ q8 H0 M: K" p
                return        m_bMute[6]?fds.GetFreq( 0 ):0;& q9 P3 R' g2 P- B% }. E8 C, `& B# C) S
        }9 J6 h# m# i3 p" [$ y5 ?
        // MMC5# W9 G7 p6 P; g9 {  D' p+ D4 Z9 n
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
$ ~2 W2 V9 M- ]7 q$ R0 v                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;$ i+ |; `( V3 C2 l7 u! P, G# A( v
        }
! f) v# F' @6 d# W        // N106. v5 {- v0 g% S! ^
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
$ v2 n% y+ I+ d$ [                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;( Q- l. B  C5 ^6 W3 G' b
        }
# Y' h( `/ f4 \" N9 b        // FME7
, \+ A7 K' w& V        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
' v: f/ X3 v' W/ U! f* M                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
: H& `. S) D+ }        }
5 [) ^5 }# F/ h! @. Y        // VRC7
! s- U2 m6 b" t4 Y        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {3 U( Y# O, H2 U; G
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;, d) i' O, |1 F/ _6 d
        }
+ H7 u& f% A+ c6 h7 m& K. J% ]        return        0;1 w# ^% m' A8 t- Y, |$ k
}
$ J/ Z" s6 Q% t/ I2 O6 e( G/ n- Q! T# o4 F2 G: g+ J
// State Save/Load
" k2 L- e: j+ }+ ?void        APU::SaveState( LPBYTE p )
( \! u/ n) B4 T; W0 z/ |3 w{
. ^) {9 M) A" y; F#ifdef        _DEBUG5 L- L  b+ y  R
LPBYTE        pold = p;$ o$ B0 m% P: q3 {) w" K7 j  R0 P0 Y
#endif
8 m2 z) I5 s- T# R, ^
0 l  S1 ^# R' _, o        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞/ H1 F9 {9 J1 R
        QueueFlush();6 N- W% {/ ]. z$ y

* \# H% f; F2 Q6 L/ `        internal.SaveState( p );& k" o6 `: S) a& M
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding. a' y1 ]8 S6 }+ x( u% I7 m2 _
1 i& b) {. x0 f+ N  x/ q1 p
        // VRC6
$ m' E! \) U! F* [" z        if( exsound_select & 0x01 ) {
; I$ K8 s" x0 C& @% m                vrc6.SaveState( p );
% I' T4 a4 |5 ^3 S                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding4 D/ j2 V, B; Y  p' f6 Y
        }8 V& l5 R* j% G# ?$ d: y
        // VRC7 (not support)5 v; ^1 w7 a1 G- ?
        if( exsound_select & 0x02 ) {0 B4 g; T  ]" `7 {
                vrc7.SaveState( p );
8 k" r; Z* }( N6 v+ C                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
# o, g4 I) _, D        }' v" t- c  j) x
        // FDS
  h; w  g3 p6 [        if( exsound_select & 0x04 ) {9 d# y" d1 M; C$ i2 g
                fds.SaveState( p );' @& x: Y  A) l: T1 l, M, U6 B9 H
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
: H* K, Y+ Y3 m3 ?6 ~7 x        }1 p$ |( |7 x+ ?+ h* O4 C$ E! B9 ]
        // MMC5
) d& [7 c7 N' |$ a( }( ^! E. M! F        if( exsound_select & 0x08 ) {- k# B9 R& M3 B% ]: e  I( F
                mmc5.SaveState( p );
2 Q' g! i/ u5 c: T6 t( b1 U                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
" w9 a" X% M7 D4 ?2 G: }0 W8 _        }$ D. e/ m2 j' h( V
        // N106/ a" J3 E! x, F
        if( exsound_select & 0x10 ) {
7 `, u# A8 y0 u' C, u                n106.SaveState( p );
* z  |& a( T1 X                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
( y4 l) H5 W  L        }6 |5 M5 q& N" t* U
        // FME7! A5 l: Q4 H9 @$ e' \: f2 c
        if( exsound_select & 0x20 ) {! ~, D$ e9 n$ `, V& Q
                fme7.SaveState( p );
6 X! u% w7 Z0 r1 D7 P                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
0 [7 d5 z" t1 p+ c        }
( r' x0 @3 \0 E1 @; ~# S6 r+ u
1 P8 O  |4 D. w$ R( _7 _$ Y- p#ifdef        _DEBUG$ B7 V! z8 |' e2 Q, l! V; d, |
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
# D, q2 f# m/ R' G#endif
) ~# s- h: b% W2 H3 ]}! e, L7 ^' L) y1 p& b1 G

* Z, Z! I' I0 uvoid        APU::LoadState( LPBYTE p )$ h0 D9 z6 Z$ T5 W: J
{
$ @8 y* Y7 R3 b0 q% t( x/ R        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
/ P2 {7 g2 f: o5 r* ?& E% k        QueueClear();5 }# |# T' _" ]( O/ v

; _* ~1 u/ ]9 d' z2 e+ T, }# F        internal.LoadState( p );
7 W# f6 B4 i/ K5 w/ g        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding' q. M0 W- t5 l" ?) ?3 S# E. c& q

4 E5 u; s7 D7 w- E9 L5 b; y# g( y* }        // VRC6& ~: Z* Z; ]# J* Z- r
        if( exsound_select & 0x01 ) {' a$ S: W$ ?) O5 M' e/ V( e
                vrc6.LoadState( p );
1 L* ]/ m1 G  u8 _                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding! k3 L1 b  |! l
        }6 H! S% l4 \, Q0 W7 J4 r( O) c
        // VRC7 (not support)
8 e1 ]5 l) |+ F1 I# f0 b        if( exsound_select & 0x02 ) {; }1 [& _. o9 L: u8 I- r. f
                vrc7.LoadState( p );. q  `* ]) o: Q/ f5 _6 q* S
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding3 l* [: m+ c  [4 h
        }7 c5 o; Q; U6 f( o( r. W
        // FDS; }* o0 X$ E2 j( G( E% ?. K
        if( exsound_select & 0x04 ) {' U/ V+ q' H$ Y) g; ]2 h
                fds.LoadState( p );2 _' d) {7 N/ y
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
2 k& C% I" w& R        }
$ F: {# N2 U- ^, @3 V, q        // MMC5! t  Q1 X4 P. C7 Y% _6 f0 n2 O
        if( exsound_select & 0x08 ) {- Q4 a$ ~' O  |7 b, y
                mmc5.LoadState( p );' _' w3 g# `& a5 i' L
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
" n, ]" A. |# g- o9 U* u% i! ]        }
" c- \! W* e* T" N/ r4 z' W        // N106
5 V- n. e% V! P2 C7 I        if( exsound_select & 0x10 ) {
0 o# ~8 H9 x+ C( Y" Y                n106.LoadState( p );
( J4 r3 x1 L+ M+ c. F                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding# r( {% i& Z0 N* Q
        }
) Y  k5 r: u+ y1 B5 b0 f+ {- Z, u        // FME7
% l! ?. n6 z( D: @: e1 ?        if( exsound_select & 0x20 ) {
" l; p8 ~4 F" E& l$ W0 ]- a0 Y                fme7.LoadState( p );
. y: s+ \0 N3 e( g8 Y                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding0 P5 b) d; y- h6 G4 M
        }
  F2 e6 w# m8 }+ h* y}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 ( [6 ?$ e/ Y- b& i/ ?+ p8 j3 |- N' b
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。3 m* m9 H: q1 f, n$ l. I3 V
感激不尽~~

' }1 N' g# v/ t. I5 L, H& u恩 我對模擬器不是很有研究,5 u1 G7 l+ \6 p
雖然要了解源碼內容,可能不是很困難,
# w) s% l3 D2 o9 p* m, m7 \& [不過還是要花時間,個人目前蠻忙碌的。
5 t3 G8 `3 W7 `8 b3 u$ E
, H  j1 E# X2 i給你一個朋友的MSN,你可以跟他討論看看,% x& J- V  Y- L7 A1 C
他本身是程式設計師,也對FC模擬器很有興趣。
! |# @' P" X5 C8 y& H' X; `( J$ p7 F0 m6 o2 Q7 L
MSN我就PM到你的信箱了。* T" D+ [7 g- y. |+ @
8 j; }9 Y! Q7 |  R+ S7 V2 T
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 7 j. R- U% s; {: A9 R( L5 n5 o
呵…… 谢过团长大人~~

: T6 @& q4 A$ F9 Y( `5 r- e
2 C9 Z) Y' t! b哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
, k) x2 G+ d8 R+ p团长的朋友都是神,那团长就是神的boss。

* B( V; ^1 M8 C哈 不敢當,我只是個平凡人,
7 v$ U. |4 A( v& y; l要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
; W1 ^  R1 H5 A4 R; Q& pZYH6 m& [/ D- y% W% e/ \
QQ:414734306
6 P3 S  B' v- c0 |& KMail:zyh-01@126.com6 j" }+ x( n, [1 D' V9 Z3 e% d
: p. A+ ]/ [! `' e3 I# i
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 7 `2 a" D, W; s
再次对团长大人和悠悠哥的无私帮助表示感谢~~
) J" E) D! r7 u  C4 J9 q- }
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-7 14:39 , Processed in 1.068359 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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