EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。( E% }0 F4 L) M; V8 ^
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
2 Q+ \: u) K. \6 r这里有相应的模拟器源码,就当送给大侠了~~
+ q6 V1 q. |$ Z6 P4 Xhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
! C, {+ i* M$ x# y& x  p能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
/ V. e' K" R; ^! h' Q2 A1 J1 n楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~# V7 I7 o: ]7 Y3 N
这里有相应的模拟器源码,就当送给大侠 ...
1 _) V# P- B4 l1 t
聲音部分(Audoi Process Unit = APU):
7 ^9 C7 c& c6 }( T% U.\NES\APU.cpp
2 x/ a$ N' s! e; `.\NES\APU.h
, [1 p% L4 |( f% D) `5 `* \# B+ s
% t# a0 L: C' M/ ]1 g4 a( C: \3 N) y( E/ s' y
影像處理部份(Picture Processing Unit = PPU):
3 t4 g  b$ Q, o6 T# a* r! k( V. a.\NES\PPU.cpp
, t0 @8 Z9 p' {.\NES\PPU.h
! S" ^$ b, }# w& n9 R; _: P7 l( M  S8 w$ J% S! p2 @
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:  P( h/ V: e% g% Q) U
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
* c! w2 F0 \9 S- ~# G& p//////////////////////////////////////////////////////////////////////////7 `) _: m) I  x3 n
//                                                                      //
4 }7 G4 O. w4 }% m! z//      NES APU core                                                    //8 Z& k( D/ C( q* ]9 d% e# E" x1 ]
//                                                           Norix      //
3 h; _7 K: @8 w% y# z//                                               written     2002/06/27 //) J. N% i; n6 k1 n- S0 Z/ H$ Y
//                                               last modify ----/--/-- //
& I( r- n% @7 h% `//////////////////////////////////////////////////////////////////////////, T4 I( b* g) a
#include "DebugOut.h"
  L. k% l( h3 S0 \8 n9 D, i. q#include "App.h"
  Q9 i! K: e, O# D, e7 z  _#include "Config.h"( h* J6 `" L! B/ G1 ^2 p6 q
) |* g5 `* J6 Q
#include "nes.h"1 q* N! m9 |- w9 S+ M3 Y, b
#include "mmu.h", V) W* L  B* E$ S+ ?
#include "cpu.h"% l5 }- q) X9 |8 y, w8 I6 M
#include "ppu.h"
5 h5 L* v) q" n$ ]#include "rom.h"* i+ A3 o0 f! X5 w7 C% m/ e
#include "apu.h"
) q: U- q: }3 L
1 D0 ~8 M& G- z) F+ ]5 @; j# d6 `// Volume adjust
7 D; m# @- W; Y' w! L// Internal sounds+ V( w  `5 H2 M+ l3 {6 Q' G5 R. v
#define        RECTANGLE_VOL        (0x0F0)) u9 F7 o8 B0 Q" i
#define        TRIANGLE_VOL        (0x130)8 J7 L1 u. _% k! r2 X
#define        NOISE_VOL        (0x0C0)
& i+ c1 z8 Y% ]0 p( }% H#define        DPCM_VOL        (0x0F0)) ~3 X+ c* a# w  a3 a3 H& Z
// Extra sounds- _/ V# z+ E1 ~( F" h' m
#define        VRC6_VOL        (0x0F0)
$ Y& `; j' J4 ?  R, F% ]! E2 q#define        VRC7_VOL        (0x130)
6 f# A8 y  @: m+ ^  T, m  k#define        FDS_VOL                (0x0F0). w  D3 ]% d' d0 @
#define        MMC5_VOL        (0x0F0)
7 R9 G; M: \( V. E#define        N106_VOL        (0x088)' q$ K, S1 C% `9 o1 d
#define        FME7_VOL        (0x130)( q- M5 o) p2 ~0 g. \2 b) C8 m
7 q! I* h8 |) |3 h* G
APU::APU( NES* parent )
" K3 Z7 y! D+ W$ o3 G" J3 N{
, H8 N( U0 o: P* z1 F  f+ p        exsound_select = 0;! u/ N4 U4 S4 L" J" @
4 c" e' [$ y* D. d5 V% v
        nes = parent;
* o+ ?0 K) t3 R" _        internal.SetParent( parent );: w. [% ^( U# z+ G: p  {$ [
, j$ M! ~; E: E+ C  _  C: w: D
        last_data = last_diff = 0;
% T4 v/ p5 Q% g$ J, ~0 K* o+ ~% H; z- R" H
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
  E$ [; Q& Y& b5 V! k0 P4 V4 H) i5 D% O4 F2 u1 r0 ^
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );6 D4 j- s1 e& W  g/ n
        ZEROMEMORY( &queue, sizeof(queue) );
- W7 `4 I+ N1 `: W/ v        ZEROMEMORY( &exqueue, sizeof(exqueue) );: l4 i" h. S8 y3 F+ I  N

! N, o2 G5 i: ^& H        for( INT i = 0; i < 16; i++ ) {& B6 N) X# M' p- ]$ M5 e
                m_bMute = TRUE;
$ {4 H  @  v4 w6 j        }
7 E- j( P% n3 w0 g, X8 g}3 q4 ], h3 V( F7 Y3 p

5 ~+ Z9 J  d& O! f0 R4 nAPU::~APU()
" h8 A! Q$ Y2 n0 g4 F7 {- F/ R{
- E7 R4 S# v, N; }3 ]}& k, o" o: C0 n" |+ v

1 U5 c- `2 x8 A' U. A& S& c% wvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
" C7 V2 k6 i7 u{
1 A( ]/ G; w3 O& z  e2 B: ~        queue.data[queue.wrptr].time = writetime;
' S$ s0 ?# T) T: p9 e6 b) o( g        queue.data[queue.wrptr].addr = addr;# }+ g- x, i# t+ m( _2 u, W( l
        queue.data[queue.wrptr].data = data;6 {1 g) r) V8 D
        queue.wrptr++;& @& s) q" [, q4 H6 w2 P6 u3 \
        queue.wrptr&=QUEUE_LENGTH-1;
9 Q( ^# H5 V5 l! g( g) K, a$ m8 N        if( queue.wrptr == queue.rdptr ) {1 [  B1 w, C/ E9 ?8 A, j% b5 }4 _6 c' r
                DEBUGOUT( "queue overflow.\n" );
+ X6 m4 {! F$ a& F        }
: Q: q5 s5 L: U7 f& x5 I1 S}
7 `6 o4 P: N8 r! d1 _+ J9 K8 [4 `( z& Q1 m& c+ [4 F
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret ); [% ~# E$ ]  c5 x
{
/ [0 D+ r6 d  W( u7 A; M2 l+ @5 I        if( queue.wrptr == queue.rdptr ) {
! }8 r6 a; i& |* y  D                return        FALSE;9 D& M3 u% F0 c  S
        }
& W2 h7 C1 k3 o/ j" s$ _        if( queue.data[queue.rdptr].time <= writetime ) {. `+ U: d7 S, x# R9 m
                ret = queue.data[queue.rdptr];9 A7 Z0 l9 ]  Z  g# T  e8 h; l/ b. s
                queue.rdptr++;
1 Q, O! q& w* I8 m# u; G- [$ d' |                queue.rdptr&=QUEUE_LENGTH-1;
/ y% t: I& d6 y; V) j                return        TRUE;' h+ E7 H; |; ~' Q
        }
( h% e5 M! G0 o% L1 N        return        FALSE;! \7 _% _9 ]3 F* o
}- {+ q- q1 O; r# F
# C! b1 q# e4 g* m6 G
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
$ \( A. P) N# e{
6 \  |4 e+ s# l( @        exqueue.data[exqueue.wrptr].time = writetime;4 b9 Q4 e* y8 V+ M6 L+ o
        exqueue.data[exqueue.wrptr].addr = addr;
# k- }" L7 Q8 J; ~4 `0 l( I        exqueue.data[exqueue.wrptr].data = data;  ?; n- @7 s6 q; ^2 P" U/ @4 A
        exqueue.wrptr++;
- U: B) z3 W. w! y0 a6 q        exqueue.wrptr&=QUEUE_LENGTH-1;# N+ G! `0 j9 j. d/ t
        if( exqueue.wrptr == exqueue.rdptr ) {/ S% K0 i  ?; `5 H. o4 }
                DEBUGOUT( "exqueue overflow.\n" );1 T0 q% P; s0 V8 ~& I# G7 }
        }
8 {) ]$ N, J; N( n( ^% @}+ ?- g9 v  t. L
6 z2 g2 D6 A! X; r6 Y. D' S5 u# j
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
% n# I" ~' r0 ~$ `{
' f4 O6 b  [5 l8 r+ {        if( exqueue.wrptr == exqueue.rdptr ) {7 u0 X. z% v5 L4 i4 ]9 X2 I- B1 m
                return        FALSE;% {8 _  i2 g; h
        }
8 A+ |* T# ~' V) P2 |9 }        if( exqueue.data[exqueue.rdptr].time <= writetime ) {. l4 j. p! t( v  Z% n, O( R
                ret = exqueue.data[exqueue.rdptr];5 A; P! E, T. C" H) k
                exqueue.rdptr++;
5 T7 W. \8 e1 R+ i' m                exqueue.rdptr&=QUEUE_LENGTH-1;
; h* a$ D/ h: W- [                return        TRUE;" L: z0 l) H! J/ g
        }
3 d) X: z8 W* |        return        FALSE;
( S! ?2 X. _* ~% }}3 t( O, i4 ?3 I7 |/ H
- r+ m0 G9 Z" M( ?3 h1 e
void        APU::QueueClear()
6 L/ q+ k) a1 l3 L6 b{4 c1 v+ A6 ]* z9 t
        ZEROMEMORY( &queue, sizeof(queue) );
5 s* {1 B/ B' e7 L" R4 @, F        ZEROMEMORY( &exqueue, sizeof(exqueue) );
9 @2 {( k8 A# Y3 X}
/ V9 Z* t3 l) @) M' ^4 P1 g
0 C2 R1 X! K5 m. N! H6 O. jvoid        APU::QueueFlush()* K. `$ k, J" x
{) O; b) A/ b- ~' {9 k# k
        while( queue.wrptr != queue.rdptr ) {
: I* U% R8 C( o8 }4 m$ t8 @" J                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
) t" c2 j" p/ W& `                queue.rdptr++;' F; M' p, O. D0 p
                queue.rdptr&=QUEUE_LENGTH-1;
" ~9 V- B  ]2 j        }2 F' h8 j* t% L% ]5 V
  E1 S8 h0 Q7 _
        while( exqueue.wrptr != exqueue.rdptr ) {
$ V  b  ~" P( {+ K, e9 x8 S5 S                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );& B; _) x4 s2 V# y( C% n, K) F4 Q
                exqueue.rdptr++;9 b, Q* G1 S; s% N4 p
                exqueue.rdptr&=QUEUE_LENGTH-1;7 J9 ]  a) z# }- K- U2 I
        }9 o0 i- J5 f9 Z/ Q, U+ Y2 v
}5 L' P' G: k& ~5 E* Z9 g* L4 a9 D
2 `6 s* e6 O: i- m) E- ]( R
void        APU::SoundSetup()
, \) R" \- z/ ?! k{$ @. A! z& W; D* u  p, [
        FLOAT        fClock = nes->nescfg->CpuClock;0 e) n0 u, [& ]
        INT        nRate = (INT)Config.sound.nRate;( ~; U) l+ k/ F% ~- C! W0 g
        internal.Setup( fClock, nRate );6 }9 b  p1 W0 f
        vrc6.Setup( fClock, nRate );. o, N% U4 _8 h1 v: j
        vrc7.Setup( fClock, nRate );; j( D8 t% r  l  i* `# Q; w, |
        mmc5.Setup( fClock, nRate );0 _3 j) [0 c4 A5 M! x) ?
        fds.Setup ( fClock, nRate );* V  S$ Y& n8 ~1 D& q! p6 w% O) {" v) [
        n106.Setup( fClock, nRate );' z0 j  r& S4 h1 J
        fme7.Setup( fClock, nRate );% m  S) I, E3 L  C, d
}) q$ H, B  i: u$ H  m# h

. I' x8 M2 U0 w5 |7 Xvoid        APU::Reset()
$ t' F2 t! k  g7 B/ {0 A6 m{
/ D1 y5 r' w( |; q4 q        ZEROMEMORY( &queue, sizeof(queue) );
/ D- a. P% T% p. G$ g' r        ZEROMEMORY( &exqueue, sizeof(exqueue) );
5 P3 v/ q; {: s1 v, I8 [* a$ d0 v4 e1 k: p3 T9 S% K5 W6 t6 }3 i, a8 g
        elapsed_time = 0;# k: c# L8 u, o# Q, J/ L2 j
8 t* ]2 ]/ `  ?: x- i9 L
        FLOAT        fClock = nes->nescfg->CpuClock;
3 J( ?$ A1 l  D6 G) ~4 `; L# q        INT        nRate = (INT)Config.sound.nRate;* u) c, F' d& k- ]' |# w
        internal.Reset( fClock, nRate );
" A' a" J3 c6 Q7 i: `5 ~' W        vrc6.Reset( fClock, nRate );6 S6 D) D5 g) Y& V
        vrc7.Reset( fClock, nRate );" r( a9 [' i# I
        mmc5.Reset( fClock, nRate );
; H% p6 ?' D3 q7 j        fds.Reset ( fClock, nRate );
6 D! }7 v$ o* {, T0 D9 H; m" a        n106.Reset( fClock, nRate );
' d* |% _0 h8 L* a" U        fme7.Reset( fClock, nRate );0 x: h5 h$ a6 ^: e/ ~9 X
; p0 U' C# u; y, H
        SoundSetup();
6 z2 Z% j: O0 h! v7 `. o}4 a* w- F' Q0 e2 M. a0 g3 z; i

% p2 _6 j# t8 v* k( T( ovoid        APU::SelectExSound( BYTE data )
1 Y: ^3 D  O" L1 [9 Q{2 c$ g: T% p. J( n9 d" |+ L  @" U
        exsound_select = data;
2 v2 w8 Q; }( _( `8 Q}% p) c# U( d- m7 j- B5 x

! _$ o0 T3 X) Z$ e! f  ]4 kBYTE        APU::Read( WORD addr )8 Z& w9 y# i$ b( d+ s
{
0 I, a7 Q" X7 V2 X        return        internal.SyncRead( addr );! o9 S8 {" B% \% o
}
+ ~# }2 ~- a6 H. Q: f$ Q7 q
8 w3 q; K9 E& k: lvoid        APU::Write( WORD addr, BYTE data )
/ u7 m5 f" x7 Y, j3 c{
* |" L6 C! j3 W5 w" a4 ?        // $4018偼VirtuaNES屌桳億乕僩4 I8 B: A- V* F; \) T( G
        if( addr >= 0x4000 && addr <= 0x401F ) {) T5 O5 F" o* W- V0 o
                internal.SyncWrite( addr, data );! ]# r6 \* ~) p* i' U
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );" Q( t6 m5 d' L  F2 o
        }% v& A, A" j' `
}
9 r  {* J/ x$ {1 z* U& |# L, _' `$ U. W+ Q7 |' u7 ^2 p
BYTE        APU::ExRead( WORD addr ); Q1 p) r. \' b  U, n5 V7 S) d8 }' j
{/ q6 _# I% c7 `2 w
BYTE        data = 0;6 n* n3 K! Y9 T  w. [3 |0 S
; ]; V8 g9 O/ E5 |9 s
        if( exsound_select & 0x10 ) {
) T# j& J3 O& c! n/ U1 i9 v5 e( q                if( addr == 0x4800 ) {( z# y- P# S6 r1 b; y
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
9 J! q1 ~; z' Z8 ]; l- p                }
, F) B+ ]& Y5 _/ @        }
+ l) f7 C1 j  i) T. q, I8 }! M( I  U        if( exsound_select & 0x04 ) {
" x- c3 G8 C% f/ i  f' T" r                if( addr >= 0x4040 && addr < 0x4100 ) {
8 \# W! h( G" P6 v4 t8 k/ _' {$ [7 \                        data = fds.SyncRead( addr );
% |* X: e) v3 E- P                }
% x+ {1 Y" D! T        }% L. |( I! u3 A% I" `' O
        if( exsound_select & 0x08 ) {9 q7 [2 E9 I4 A
                if( addr >= 0x5000 && addr <= 0x5015 ) {  L- @  O# o" p, _& R5 M* m. ~7 I* \
                        data = mmc5.SyncRead( addr );
$ X  R+ l4 v- \& v% O                }: w0 G( i3 u6 [
        }" [( c' v" @) E/ y: a! @" B! i  B5 l

7 ?8 D8 ?( z2 `        return        data;
; Z8 v7 @  M$ _$ f9 P/ ?}
) M* ]/ k5 k  n
2 e* z0 l( ]. T: t0 Z4 `0 }' kvoid        APU::ExWrite( WORD addr, BYTE data )% O; d- Y$ F2 S
{& m# s7 ]/ T! w8 D- C4 V* M6 J1 e
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );; {8 D; j- M/ Y  c' v5 [

: j& X# f& G% K3 Y9 M        if( exsound_select & 0x04 ) {1 T- o$ y% q0 P
                if( addr >= 0x4040 && addr < 0x4100 ) {* \% O& l7 C: b, r0 l* u
                        fds.SyncWrite( addr, data );
& b9 I8 F, a/ z' z3 F( J  A' X/ D                }
- c5 e# P, R. |8 k6 ~: h; Q7 h  u        }. B2 G" c9 v+ T7 n
7 i2 j/ H$ `4 V, Y$ V% [
        if( exsound_select & 0x08 ) {. y; o0 n! M) G4 e/ P
                if( addr >= 0x5000 && addr <= 0x5015 ) {
3 }% s: P3 S0 z                        mmc5.SyncWrite( addr, data );. X* w% _; E7 g$ Z) L( I0 \6 Y0 z
                }0 J8 E1 C2 M  T& ]" u* O9 e6 y
        }0 a5 S: h7 a- {, m+ z
}6 r) m( u; ?0 t

, {3 Q* `7 p, ]void        APU::Sync()/ O% i* w5 H% F, [1 j
{0 p' U2 u/ [3 M2 }
}
, O* N1 T+ z/ r6 B1 a& }0 _6 U& Q( j* H) H. h& Y
void        APU::SyncDPCM( INT cycles )
$ Y8 p3 C' k) z. d7 K{
0 h" F8 D9 h0 Z3 a: |  r3 O" P        internal.Sync( cycles );
3 |9 k; X6 a$ p" n! f. `, Q! \& C/ s! b3 O
        if( exsound_select & 0x04 ) {4 x- n  n" F6 q
                fds.Sync( cycles );
: @2 ~- _' a& \; r# K) X        }/ n7 k! a4 K% e* w
        if( exsound_select & 0x08 ) {  T+ f, F$ N- D; _+ z
                mmc5.Sync( cycles );8 ^2 F2 J3 i6 Z4 L
        }2 G2 K- `* a4 c" w
}+ q9 f1 }' i% h8 G

. t7 |6 T# o5 ?5 \! Xvoid        APU::WriteProcess( WORD addr, BYTE data ): G0 Z4 P$ m( F' h
{5 B, y" F. c4 g7 n3 u2 d  I
        // $4018偼VirtuaNES屌桳億乕僩$ \+ A  d& w' R0 B  O  S3 h: u
        if( addr >= 0x4000 && addr <= 0x401F ) {( r9 A6 v! W. k9 P) T% P; W
                internal.Write( addr, data );
$ _$ D% O* F+ m1 O+ ^7 _" k8 g        }
5 S5 U4 t6 X; }( y}& a  b# ], p, u1 o1 \9 w. _
$ d* i* j8 M' m  G
void        APU::WriteExProcess( WORD addr, BYTE data )" o. F! F+ H/ t* }( {$ a% a0 _
{6 ^  x7 v9 }& \. V! s, z7 r- B
        if( exsound_select & 0x01 ) {! ~3 H  K5 ~  Q1 {# y7 G
                vrc6.Write( addr, data );/ t; W" `. h- x5 f: m
        }; k& W& E0 U* _" A4 L# ~
        if( exsound_select & 0x02 ) {" \- k" b; l, i  q0 ]  R2 p
                vrc7.Write( addr, data );1 o1 |+ `( L. S+ p* E4 B
        }
" _# ~7 ?4 B0 j: `; W        if( exsound_select & 0x04 ) {! j. j& k# x# V9 M0 E
                fds.Write( addr, data );6 y' H5 d8 z+ N' a% f
        }! G' S0 N2 A% D+ k$ ]
        if( exsound_select & 0x08 ) {. A5 J3 F; ?" q/ J/ `# f& X
                mmc5.Write( addr, data );/ `8 ~6 L! s$ F1 g/ ^% z: a
        }. c+ M2 m4 L4 o0 k/ [& N
        if( exsound_select & 0x10 ) {( O  M# i* \1 ?, ~) ]1 V
                if( addr == 0x0000 ) {) ?& R" R  n" V" k8 w9 M# F
                        BYTE        dummy = n106.Read( addr );  Z' Q% ?% ^0 j
                } else {" w9 G0 M, @2 ?! N8 p$ A
                        n106.Write( addr, data );" p  \  e* y& g- P# Q# ~
                }# Q% I% ~; A3 q+ f: t3 @
        }$ S6 F9 E( {- W) M' J5 |0 O4 q4 o6 d
        if( exsound_select & 0x20 ) {0 h* j' }' K, |; K& ?( d8 l
                fme7.Write( addr, data );
; |1 w$ I& n2 v  \1 g" H$ ~. D        }
  M$ ]; B, f, L) M}/ I5 `, ^: c( t- L, D3 Y- s

6 D: m" j- j& |( T  [! ]void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )8 g. t4 n+ @. r( s! p. A
{5 J9 N" V' }) h
INT        nBits = Config.sound.nBits;
0 N8 W; M0 h9 T% E/ XDWORD        dwLength = dwSize / (nBits/8);- c4 T7 s7 X$ H! U/ M
INT        output;
4 H8 m' _) j8 y7 T2 I4 BQUEUEDATA q;
3 x' m9 \' W% ]& @: _; u4 o3 MDWORD        writetime;
1 S0 j1 A* E) r" @) o% r& ?/ Q8 t" W
LPSHORT        pSoundBuf = m_SoundBuffer;
7 |' L" T% R- O5 z# jINT        nCcount = 0;- P* s' ]& V! s
# N' W; T) d) m0 U
INT        nFilterType = Config.sound.nFilterType;
4 ]0 W$ P8 U1 L( K  a6 D
1 a* @" L) Z: H3 D+ I$ b& ]        if( !Config.sound.bEnable ) {- V, Z1 s( Y' s1 w  n$ m/ m* B! y
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );8 t/ u9 b- c" o9 I
                return;$ g& F6 ?/ `3 i
        }
/ P- r, {' K& |6 r  R
" `) V8 @9 `# k        // Volume setup% R! t: ?2 O$ @, K9 ~
        //  0:Master( X& m( l$ @% r& ^; t' x
        //  1:Rectangle 1
4 x) J) ]# q( m: Z) P' d        //  2:Rectangle 2
. l9 Q) f" D4 X  |+ G$ {        //  3:Triangle& }4 L+ u  q3 P& b
        //  4:Noise* B& |# Y9 a" [2 g1 w) H$ _: r6 M: I
        //  5:DPCM6 j/ b9 M! F8 [1 R0 e; i
        //  6:VRC6# v3 ^) _5 z7 A
        //  7:VRC7
6 ]' o. U. A7 ~( ?2 }! ~/ J6 _        //  8:FDS
6 I  V: Z. I* H        //  9:MMC5; {! m5 s) g( I! T1 p& B! a! _
        // 10:N106
2 s* Y& A" j' c/ r        // 11:FME7
% t) u' D. c* b, \6 b+ e        INT        vol[24];
, O7 ^; L5 {; q* }        BOOL*        bMute = m_bMute;
+ a3 U: H. V# R: H        SHORT*        nVolume = Config.sound.nVolume;8 U7 [1 Y$ z' r% i2 L9 S9 o# C- W) F
+ g* Q! }* s+ r9 m
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
# C4 k5 I5 P4 `! O9 o9 q) m5 f9 v4 Z5 ]
        // Internal& R, h0 i1 `" ^' S, [. z
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
$ U+ R# U0 s" N% N4 Q  q- ?& J        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;$ ~4 m( K8 }* }0 f8 g1 {0 S- S
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;! k2 K! \' v& N4 G7 j+ p$ |
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;( x; h; w: a% l( r) b; N
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
, o' r% L( {0 r; |7 r( C% s  x" L, ^, l1 Q. Y$ l2 ]" p
        // VRC6! G  D2 J- n* z
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;# m8 B" x7 y( V) Z6 q
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;% L5 A+ J3 M# h/ U
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
$ m1 z% \0 Z, D: ]
9 V0 ^1 X- Q* C7 q        // VRC7
( M# k5 ^, O% c! _, t) O        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;8 `# Q) d2 W* D/ n" Q) z
& c$ V( C% [( G: \
        // FDS" a& m  x6 B! b9 f% X- i& r
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
1 H3 a. F0 G7 x5 W' e. S( ~& M$ ]7 [( j/ L# w/ x3 p5 N
        // MMC5. {9 {' I0 Z: O( {- ~' z. Z5 L- x
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
% o6 ]" S" a$ J5 j0 Y: i        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
3 X8 K. ]8 j. }        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;4 O7 j9 B9 F5 q! \* ^' |/ D
" k& I. U' X1 n  q+ N) B' P. y0 u
        // N1064 C! d% F) |) x4 |* ~, y
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;& F& o5 N( \' c4 a6 O1 j  |: G4 j
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
5 B7 U& y2 h3 i- D+ @        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; M8 X( ~8 g: V* i! \. I. u# z
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- b+ V( }& l% I" z
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;! j! B: Q( {$ H
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ {9 |8 s: K- k( N* U* V) U
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;% J& P* U( V0 _. K, V2 A
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
; k3 x% |+ t- _5 @; e  _4 T, {* f6 h' B
        // FME7' j- K/ ~- Q( W# @
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;6 A) H2 r) U7 U  A9 v& [  \
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
+ D! p' `9 W; P# K2 q        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
1 F# p+ h- _0 w$ X6 u. t' ]4 N6 m; r, a8 t% h" n& f
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;- I  t" `7 {: \  A1 k4 F5 W
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
2 i' R5 C$ }: y
. t2 a" z  O  b0 M  l        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟1 P( P8 n- O, s5 M5 \
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {$ `) A" f7 S: W* m. Z1 g& U$ v6 u
                QueueFlush();
" q/ Q7 U% y5 J! m6 o; ~        }
; i& C( ^4 N5 v' G4 N
: e, x: v, ?5 s& N8 }! n6 g        while( dwLength-- ) {8 j3 O' E- y: Y+ V3 O: x4 w. m
                writetime = (DWORD)elapsed_time;' G' N: l0 z- ^; j2 |& d0 c' d9 {
) X; b0 N; e" ^0 Z7 d/ m
                while( GetQueue( writetime, q ) ) {
2 w4 c" y5 T+ |, ]                        WriteProcess( q.addr, q.data );
4 S  z) a8 o' _! u  z) o6 }                }
/ h/ O; Q$ E7 M/ [3 P
9 n3 b2 q5 X( C+ U# c                while( GetExQueue( writetime, q ) ) {( p: w% y5 i5 V1 r/ t
                        WriteExProcess( q.addr, q.data );8 c$ x. {3 v* O, V
                }1 S& Q0 n1 b) ~$ X& n) z: _2 t; C  j

5 D( Q+ M0 {, Q2 K- j                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7, T0 k' ]9 S0 X4 q
                output = 0;' `  H) b. I: C0 J# l" y
                output += internal.Process( 0 )*vol[0];
) s+ l! I- l5 e  k! w* D                output += internal.Process( 1 )*vol[1];
( ]# \+ P; z* |' k                output += internal.Process( 2 )*vol[2];
3 h( F# U0 |8 X6 c  r2 @+ \                output += internal.Process( 3 )*vol[3];" L3 O% a, S9 e# G- U
                output += internal.Process( 4 )*vol[4];
1 j! A, q. h, w# `' l
$ f9 l- h1 x. l                if( exsound_select & 0x01 ) {
( x- {, Z' |* `7 j8 E+ @                        output += vrc6.Process( 0 )*vol[5];
2 K. {/ }) V& m4 D0 ^( s  ]+ [& p                        output += vrc6.Process( 1 )*vol[6];* u2 t) x; A; I3 G6 a% h7 ~
                        output += vrc6.Process( 2 )*vol[7];
9 S9 M% v4 a0 _! K                }
% r& I/ j" Z/ E4 Q( P/ V                if( exsound_select & 0x02 ) {
# Y- V5 \- U) a) f                        output += vrc7.Process( 0 )*vol[8];/ w8 w- N, C! ?' g8 |
                }
0 A. `( Z4 a0 J! s* q' [$ v                if( exsound_select & 0x04 ) {
9 t' e1 U$ g# {; F                        output += fds.Process( 0 )*vol[9];
. n4 ^4 }% M4 g. Q+ @; m' b1 {5 [                }) b7 d( Z6 T5 ^" p& J' v
                if( exsound_select & 0x08 ) {
& }# c% o: w. m: H                        output += mmc5.Process( 0 )*vol[10];, ~7 x/ J- b- S. f8 L
                        output += mmc5.Process( 1 )*vol[11];" B4 {; n  B# g
                        output += mmc5.Process( 2 )*vol[12];
  E3 p4 w0 @9 [* G6 u                }. A$ r# I4 M2 J
                if( exsound_select & 0x10 ) {8 B- n5 {( w* i
                        output += n106.Process( 0 )*vol[13];
7 Z# W" w' f' _# Q* \. [  b2 n                        output += n106.Process( 1 )*vol[14];! _: Y8 N; M# e3 k2 j! h; O
                        output += n106.Process( 2 )*vol[15];1 @( N7 d+ w( q+ g6 e: k+ w/ a) O
                        output += n106.Process( 3 )*vol[16];
; d" i3 h7 V) U2 j. Z: P6 U                        output += n106.Process( 4 )*vol[17];9 Q5 {& K# E' _
                        output += n106.Process( 5 )*vol[18];
5 C' p8 l3 X" Q  v+ ^                        output += n106.Process( 6 )*vol[19];5 T6 n1 N) d* d  ^0 J2 t6 O  k
                        output += n106.Process( 7 )*vol[20];
3 K) c- h5 X+ K5 _( {) y                }
, d0 G* u- i: g7 Z& W. `/ ]0 C  u) h                if( exsound_select & 0x20 ) {
. E) z% h- |& P, ^2 Z, E/ a                        fme7.Process( 3 );        // Envelope & Noise& p! B" w5 N: k, ?
                        output += fme7.Process( 0 )*vol[21];
6 x3 s; C' I/ ^; \                        output += fme7.Process( 1 )*vol[22];
- z  r3 l6 ?' E                        output += fme7.Process( 2 )*vol[23];6 t' L( p' P3 f" B3 l
                }, X# d5 W( @- o9 Q- k. }2 d

" l/ g3 M: [8 t                output >>= 8;
) B& C' `0 m" P4 q4 e' ~/ ^3 K; r! J' t2 _
                if( nFilterType == 1 ) {4 z: `( a# v( A8 m
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)1 U- t) Y$ g7 @3 E0 r" ~
                        output = (lowpass_filter[0]+output)/2;
0 c6 b) A' M5 w7 T  K8 S- M                        lowpass_filter[0] = output;
& ]7 \! ?- F  H9 @                } else if( nFilterType == 2 ) {8 [: e4 H# @$ h" x
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
6 s8 i: m, s0 H                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;/ A& H, b  E9 ~: B% Z
                        lowpass_filter[1] = lowpass_filter[0];
- z+ j2 h2 O4 s  @9 l! K/ T                        lowpass_filter[0] = output;
) D* L& G, J: L5 G# f& f                } else if( nFilterType == 3 ) {
3 L; Q: U* g+ @: c* `                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)0 T, w. }  y, h3 g% Q8 G
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
3 e% Q3 ^* S& [2 J! B! l  J! q                        lowpass_filter[2] = lowpass_filter[1];
& E) v. y" s) {5 M$ h5 l; p                        lowpass_filter[1] = lowpass_filter[0];
& F% J6 i7 X& q6 B+ X                        lowpass_filter[0] = output;: H) C; G$ Y! a, Q
                } else if( nFilterType == 4 ) {6 p0 p3 _$ S$ k7 n2 T- F
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
' v" V  ~: Z! y/ m  u# G" \5 Q                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;$ w2 K4 k0 x' ]9 s
                        lowpass_filter[1] = lowpass_filter[0];! m4 E9 D5 \8 m# e9 I4 R
                        lowpass_filter[0] = output;
8 {5 J6 _$ W7 G0 |                }
8 ]- Z1 y3 m; p* P" N
  T) ^/ i- q9 q7 \* L#if        0
7 J3 S9 h# K5 \  H4 j& j/ I8 x                // DC惉暘偺僇僢僩5 f6 ?% W7 X& c6 o7 p( \
                {
* \% S3 X1 p  |0 J6 Q. {& _                static double ave = 0.0, max=0.0, min=0.0;
) I- v; S4 x% s/ R- m                double delta;. [+ O( ~. S  i( K3 _- e0 I
                delta = (max-min)/32768.0;, m( N) h/ k' f2 I
                max -= delta;/ x5 k" m* K8 r& s
                min += delta;6 a+ b, H5 l/ y" [' F
                if( output > max ) max = output;
' A% a6 S. E( a. I' p3 z                if( output < min ) min = output;2 \) s5 q! c$ }$ s: y" D% [' m2 Y  z
                ave -= ave/1024.0;
' R/ q& O; ~; I+ O( E1 r+ r! ~                ave += (max+min)/2048.0;
- S" S2 F3 N* v$ O$ C! }                output -= (INT)ave;
4 A- W9 i) \' `+ `1 [                }
  ^7 n% C( a/ K1 m$ Q' d5 Q#endif: R/ G$ I/ Z: m1 G$ V
#if        1
* g3 M' ?; k% m* v                // DC惉暘偺僇僢僩(HPF TEST)3 I+ C4 N4 X, P. b- F. P' A" G' ~
                {
+ A  f7 _' `# e//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
: ?( |, D& T' D  \3 F5 `( }7 Z                static        double        cutofftemp = (2.0*3.141592653579*40.0);
* |, u/ R- {' ^# J  s% @' R' [0 r                double        cutoff = cutofftemp/(double)Config.sound.nRate;
7 P* K) K+ a& L( \, b; B                static        double        tmp = 0.0;8 _( ?/ R' e* r* t+ d  A! E+ ~
                double        in, out;
0 D+ Q4 Y2 b5 O. L& ]2 \/ z6 G: f% C0 t% R6 }) _1 D: c+ ]
                in = (double)output;3 D( r. v, X) j, L2 V( R  K
                out = (in - tmp);
& Z8 I9 D1 F5 r! L. i" R                tmp = tmp + cutoff * out;3 H" Z/ }3 J+ |5 m) r

. ~+ }$ P: z0 `" Y* _! d0 r% Z+ _                output = (INT)out;+ \. x% @1 Y8 _+ |6 v% ^  V
                }
8 P* F8 g! J2 {0 C, P" D6 ]1 w#endif
* R# u+ o. @7 x, g5 ^, _) P2 U#if        08 E* T$ Q' t; a' v# L
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)( S! e! V/ X& O  R
                {
3 x7 B, t  j' ~# f9 a! B* m' V( }- J5 |                INT        diff = abs(output-last_data);/ U% U( n  ?' e1 X
                if( diff > 0x4000 ) {. f/ x, ^1 E8 r) C5 W, e$ s
                        output /= 4;* y% m# R! I0 f2 ^
                } else
, H1 Q# C5 W5 M' D* [8 d                if( diff > 0x3000 ) {% `( ?) G/ G8 M# Y
                        output /= 3;" ?0 i8 h3 _* B& D
                } else: K7 R, x9 W2 D; p
                if( diff > 0x2000 ) {
. C' X* ]  I+ n: \: F: X% A. i                        output /= 2;9 H( o: \9 U- }* [" [& w& }
                }
# ?* c: n6 ~& x+ p2 q. j! V! b( f                last_data = output;
: H. i( v4 c( M% O# _                }2 Z# v4 O/ |- Z2 l% s1 P2 J
#endif9 M1 l' P1 L7 e7 a5 w0 C
                // Limit4 \) M' [' A, \7 D( q" e
                if( output > 0x7FFF ) {6 Z4 q! U" h: l, e8 m3 G
                        output = 0x7FFF;# \: }* [2 L# B' S# I8 s% M
                } else if( output < -0x8000 ) {
0 }6 {$ F- o/ l4 R+ M                        output = -0x8000;8 ^$ t+ G* y2 c9 r) a
                }
+ q# }4 @: `( y/ f, k5 r( d3 e1 ^$ r- q. O  U5 F$ j
                if( nBits != 8 ) {
5 P4 T4 T) {: H7 R8 G3 x3 r                        *(SHORT*)lpBuffer = (SHORT)output;, a8 X3 Q+ Y' Q: r" z' P3 U/ T" B
                        lpBuffer += sizeof(SHORT);, o+ W" u( P, ~- K8 I
                } else {
0 \3 I' ~$ t' e                        *lpBuffer++ = (output>>8)^0x80;
5 e. E( P3 O1 v" R                }* l5 o  E' z/ d% O

. c# l$ f( Q2 F2 k                if( nCcount < 0x0100 )8 l0 G$ n6 N1 L/ _) x$ X  S6 W, _9 a
                        pSoundBuf[nCcount++] = (SHORT)output;4 v6 _5 T( d5 L" R; Z
' W5 I$ m: R4 B# x, ~
//                elapsedtime += cycle_rate;
& E6 Y  r1 D& C/ }                elapsed_time += cycle_rate;
! P6 N+ C8 A" D6 D- t  B- j        }
0 U. Y0 s) d6 F9 ^; o% x' F$ [
$ Y. [' B0 x' a6 D#if        1( Z8 c/ c  w- m1 V/ L. b
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
+ @# C% o% @" }- Q                elapsed_time = nes->cpu->GetTotalCycles();$ e* E- ]" c8 J" t6 Z5 w4 Y4 r$ j
        }" X( Y! i( b3 b2 K
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
# W* x0 [, ~6 g- T+ T                elapsed_time = nes->cpu->GetTotalCycles();. A' O( q! {' A7 \. T" H3 Z% c
        }
5 p3 Q# D/ |: D% g9 b9 M: V5 n#else. p5 u) q4 o3 \- F* d$ ~
        elapsed_time = nes->cpu->GetTotalCycles();" A0 j3 f1 O; [0 K' D$ y
#endif( k3 Q  X6 ~7 E# Q4 [8 \
}6 ~8 H' m1 u0 m/ a) s; G
) c( |3 |( K# C
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
! v2 E: M  s' E4 Y/ ]INT        APU::GetChannelFrequency( INT no )6 [5 {8 |9 z1 U
{
3 \/ |) i1 [; k) S2 M0 t! ?1 i2 v        if( !m_bMute[0] ). o; ?: h2 i, P  F  p8 L$ {
                return        0;
2 B0 U5 u* ?  w1 N  K+ \' L$ _/ T: Z& x; _
        // Internal
2 u, [6 y, J1 n5 ^1 j: A* Z! p        if( no < 5 ) {
8 V+ U. V. d3 _7 `" \7 [                return        m_bMute[no+1]?internal.GetFreq( no ):0;. \, R2 D2 g, J; v
        }8 k4 q: {0 z  a: Y  F' o: X
        // VRC6, b6 U4 i  d1 N' R/ [$ I
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {3 o5 u8 Q" ^8 ^8 ?) a- v# N
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;  z3 b5 c' U* v3 f5 v
        }
4 I, o1 N+ a$ l8 L        // FDS
- f0 ~" H" e4 v        if( (exsound_select & 0x04) && no == 0x300 ) {  M0 k) k( n- y
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
( [2 W8 f* h* W8 }# J; b        }
6 T" v1 l1 Z) a  ^9 q( N        // MMC5/ }; R# n' N) h$ z4 ?
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
( m; H# g7 {4 Z9 Y0 p- D                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
% A0 a  Y0 |8 @2 M& T7 \3 m# O        }
9 T. r, r. n) a! z, n        // N106( `' Y7 Z! F# i- X( U5 i
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
: @% m; s& m( N7 k- g                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
7 b/ n3 A9 v( C        }
; S( Y) M, x: V, E  q$ `        // FME7
6 S- k6 v- ^7 p% p# |1 ~/ q. M        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
6 \& j0 h9 m: c1 F- |6 Z; A                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
9 S6 L( \) J1 t5 J! u# U        }
/ A6 o! a8 E) k        // VRC7
& D% L, c/ c, s# N% P& o        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {" I' O0 g/ |" X9 S0 ~- X3 k5 r
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;! M2 L& F( A7 |( c- U$ l% c
        }, O" h& w. U0 T8 Z& i7 Q  A
        return        0;5 A+ x  u7 w( t9 ]
}
. H+ \# ~) q3 B6 H  ?! t
- ]9 t. X9 b3 q' c// State Save/Load$ W, @6 @4 Y$ {
void        APU::SaveState( LPBYTE p )
: O) t9 q: }2 p" y9 ?, Q8 f% H{, t; I+ x! W1 D8 J. x" Y7 _
#ifdef        _DEBUG
$ I3 p: b  O1 f& J/ Z$ |5 cLPBYTE        pold = p;7 w1 v2 ~# o7 b, o+ [* s
#endif% f% L) f7 b, Q0 a. A' p5 @
; c" W& C. _) z8 M0 Y5 g
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞* T& P, E" m" G# F$ ~  h. T
        QueueFlush();9 t6 m9 ?# [! P- j" [, N, ^

7 `4 I& @, Q  {  u8 U        internal.SaveState( p );% \" e; H+ m6 `: D  a7 d& M
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
& d3 o2 [7 ^$ `( j8 s0 P+ U' K0 R" m: N8 q. `2 K8 j' l
        // VRC6
' G' S1 ~7 }9 D. T. V1 V6 F" Q        if( exsound_select & 0x01 ) {
3 i# I0 b, A- I                vrc6.SaveState( p );* q9 L* D3 }: c4 E, i8 G
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
6 t, A* \: {/ }. K1 w+ S        }
5 `. h+ s  ~3 K5 g        // VRC7 (not support)) x3 L2 _5 C1 m
        if( exsound_select & 0x02 ) {; e% l& \& A# k9 A" s& E- \, a8 ]0 B
                vrc7.SaveState( p );; E/ P3 F& g* f. F5 n! D
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
, r. c0 K8 L) G0 m        }1 Q+ U9 y0 b: b3 C4 `- l
        // FDS' }' V% S* U! N7 N
        if( exsound_select & 0x04 ) {
9 Y4 i* U7 G2 h$ b                fds.SaveState( p );  F' r* f; [6 g( K
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding, R2 r, ^  Z1 E! s: a
        }! p3 {0 l: @, d+ @: T7 a& W
        // MMC5
1 N  ?/ Q( t( R; C1 g6 w9 A        if( exsound_select & 0x08 ) {0 Q& b6 i+ X+ R
                mmc5.SaveState( p );8 p3 M3 q# b: U7 k. F1 Y
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding9 p7 t/ S7 R: z, K
        }
; S: m- m* t; E" U! A8 J1 `9 d        // N1066 @  O% x2 ~9 D+ g& M7 r1 ]
        if( exsound_select & 0x10 ) {
) m5 E# D+ G; `% p" L1 i                n106.SaveState( p );
$ }6 }0 F* {# d5 m) L% R& j                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding1 |8 O: [' h; T9 E7 m$ I6 m+ m
        }' D1 B2 ^# u$ U& D" o7 A9 i
        // FME7% j, f0 a7 ?' [
        if( exsound_select & 0x20 ) {& {7 q# ^& i" d( A" K) R$ \/ U" K' z
                fme7.SaveState( p );$ p* Y3 A* R4 T3 t
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
9 M* H8 O" g4 {" [        }3 m7 v; e; m7 P2 c! I

6 N' l. _7 I; d" P/ s" U8 v#ifdef        _DEBUG
/ U( [0 ?( J& NDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );0 r+ S) }- N5 c- \4 z% Z
#endif# I# f  O9 P2 d2 g
}
. }" P7 N. [( @
5 i- i9 c# b- c% O: [- @# Qvoid        APU::LoadState( LPBYTE p )2 C- K3 n" S$ s  r% F4 M7 N
{6 l! Q: L6 k( y/ J! ~  y7 I
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
( A$ `0 U% i2 {& |# b+ @        QueueClear();
" H0 ^: Y" l6 i# X" `" [& m1 I/ J/ _$ R/ ~! [
        internal.LoadState( p );' d! m( P1 Y3 w2 y4 l) V% B
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding2 d# [5 R3 j7 f2 Q, R
; c& }" `$ r# y8 S5 w2 l5 R
        // VRC6* c7 R6 V/ J* ^5 p- {- T& T
        if( exsound_select & 0x01 ) {  x) |4 }  p8 O2 Z' s: Z4 |
                vrc6.LoadState( p );7 s' P+ k3 z! T; |' @" W% W; y0 O
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
9 v; U8 Z; R- b6 h0 B        }! n; F- i) R" {! n
        // VRC7 (not support)
+ L. u9 X* R6 \, y0 m        if( exsound_select & 0x02 ) {
4 Z1 @, x/ O% n. X& ^1 a                vrc7.LoadState( p );
2 a# [5 q3 u; W                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
; p# z3 k$ ^& O        }
/ {6 }$ H- k5 ^9 o( C$ [        // FDS6 M& ~& Y4 I; }9 V  |# T( M
        if( exsound_select & 0x04 ) {9 A* z8 R4 C; S$ k0 K) \
                fds.LoadState( p );- t6 Z& t- w9 j9 K
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
$ w2 N) Z8 i9 T! B        }
7 a; ~2 g4 H1 G( `2 h8 J        // MMC5- F5 j  f7 p" {
        if( exsound_select & 0x08 ) {
" G/ s& O4 V; z3 A                mmc5.LoadState( p );
1 X. S3 P( A7 I! V6 Z5 q! \                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
; {/ T) Z1 C; e1 P8 u        }
! B9 k: q- A4 s5 H& w1 M* b        // N1061 B3 b& H  k1 \3 \0 N! x6 H
        if( exsound_select & 0x10 ) {
7 b3 y( |' h' I                n106.LoadState( p );6 G& |' n4 Z. S! x& W
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding" `  a" e5 l& z& e- b) `$ z* t
        }. c" o- f+ M: S
        // FME74 t, z. a. g/ S# D1 N6 m, z
        if( exsound_select & 0x20 ) {# \9 a; ^9 q; v  ]# G
                fme7.LoadState( p );
) ]/ X# b" ]% p6 x3 l, m                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding% n. R6 f8 ?% }, Q$ I
        }
; L( k+ ~, M2 e  \5 @}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 ; k- ~" Q7 _! N* `6 b' Z) N6 U
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。4 [* u# x, a$ \. u3 r
感激不尽~~

  ~/ |( R/ W- A7 |恩 我對模擬器不是很有研究,
0 M  \, q' [0 V) L雖然要了解源碼內容,可能不是很困難,7 [$ T. x; i7 y- `# |8 Y
不過還是要花時間,個人目前蠻忙碌的。! _) Q2 V6 V+ H
9 Y' B5 P1 M9 o. B& C
給你一個朋友的MSN,你可以跟他討論看看,. t3 T" I2 W1 s; P0 M# {/ d! r9 D4 _
他本身是程式設計師,也對FC模擬器很有興趣。0 e( B* l2 l' \# d; M- x

. U. i4 c  P9 gMSN我就PM到你的信箱了。9 B  \5 ^; e# `1 P

$ b+ v( i7 l  |9 I' [希望你能有所得。

该用户从未签到

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

签到天数: 80 天

[LV.6]常住居民II

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

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表 ) D" P$ Q' h8 X" i. r1 ^
呵…… 谢过团长大人~~

0 y% R0 W% `' H/ {) Q+ ^$ g+ X
5 |* ^& \$ z$ C2 ]. ~哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 6 f/ Q4 P7 V( [) v# z) R6 [
团长的朋友都是神,那团长就是神的boss。

5 U' P; l7 C' g7 D$ v3 ?. d哈 不敢當,我只是個平凡人,2 ]7 S+ {! }+ k$ n4 X8 x/ j
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙; ^1 `1 B& P7 v& e) A
ZYH
2 j- j9 t" j  ZQQ:414734306/ N# {, A& o" T
Mail:zyh-01@126.com- x3 q, K/ f  A" N0 A, S

* m% O( ^+ m" [/ D他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 + i9 b1 d/ m! P! H2 q( n
再次对团长大人和悠悠哥的无私帮助表示感谢~~

$ t) `& W4 g/ U8 ]. p不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-30 11:28 , Processed in 1.113281 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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