EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?( x2 r2 a0 K* V- [$ C
PS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
) Q# Y7 Z) q/ _) N* }) p楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
+ U6 b2 |, \  c% e  |7 y: v6 V( \这里有相应的模拟器源码,就当送给大侠了~~1 `' t7 c: ?6 H0 G
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 * F1 n- q1 ^2 C. n" p6 X' z
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。7 o2 Y8 h( u3 X# m( G; }# u
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
, B+ v) d$ h0 U  n% c1 P这里有相应的模拟器源码,就当送给大侠 ...
0 }7 u2 `9 p# {* b( s# U6 O1 I
聲音部分(Audoi Process Unit = APU):
9 L7 U, a. G! k4 P.\NES\APU.cpp# C9 P4 W( z$ H2 t4 V% b
.\NES\APU.h
, D4 Z( p; T: o0 p+ @: B2 v" ?8 ^' D
3 ?3 N1 h- ^' ^- {) o
影像處理部份(Picture Processing Unit = PPU):# q+ g0 b5 t$ T9 F. W( _2 `3 f
.\NES\PPU.cpp
3 [* ~4 C  f3 b+ y$ E.\NES\PPU.h/ Q; K3 w0 F% |

! n6 {7 j! T3 b8 n; P' A如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:  @, g/ J, {0 D; G
(由于很多专用术语和算法机理都不明白,所以看不大懂……): X5 g. F; l# f  D( D2 H
//////////////////////////////////////////////////////////////////////////
: J) l1 \, l  E) o7 ]; {5 j5 G//                                                                      //
3 U  A0 i, d- V0 o2 L, q0 B/ x//      NES APU core                                                    //8 |3 c- j+ `: j6 t% @
//                                                           Norix      //
! S' T/ I7 L5 \8 ]% R! W, l- X//                                               written     2002/06/27 //
+ A; D% t" ]- f3 V5 f//                                               last modify ----/--/-- //! c2 {& d3 V, f; C4 q5 S
//////////////////////////////////////////////////////////////////////////
$ C! F! t( p& M7 q7 b, ]#include "DebugOut.h"
+ t* a2 Y: e  f9 U3 r8 Y#include "App.h"+ r! ^: K2 x; V0 E8 X
#include "Config.h"
  {. U0 c' |" t  C
1 T0 S6 r  p- Y, r% ?- d#include "nes.h"5 y% ^7 o, A! o5 C
#include "mmu.h"3 o7 x$ F+ V7 K7 M. y8 g
#include "cpu.h"% G1 m& e8 n) o. w( C3 r2 Z0 P
#include "ppu.h"+ b% v( u5 j% U, m
#include "rom.h"
( u. J% Z- L* B/ I$ T8 @; u5 r- b#include "apu.h"$ _! N" ]' F% X. P( j
2 D+ Z" X. p3 x) r
// Volume adjust
/ R$ B* O' f' p' \, Q1 {: V// Internal sounds' m8 t+ |4 t1 x/ l3 N. r3 i% ?
#define        RECTANGLE_VOL        (0x0F0)' \7 l. J( N$ M  P' B3 R1 F* A: [9 A
#define        TRIANGLE_VOL        (0x130)( U/ x# a& w' |1 h' [
#define        NOISE_VOL        (0x0C0)
2 ^' R7 H: V8 Q/ [#define        DPCM_VOL        (0x0F0)
- {, v* N/ {$ w( {// Extra sounds' \- B4 j( `4 C7 c; ]
#define        VRC6_VOL        (0x0F0)
; b+ _/ B4 _+ K#define        VRC7_VOL        (0x130)& o! B. r& H" |4 ]
#define        FDS_VOL                (0x0F0)# u; c* X" K5 \. m
#define        MMC5_VOL        (0x0F0). C0 \/ b# ]% \2 e! y; i; w
#define        N106_VOL        (0x088)
+ ]( G4 K% V! ?: t( I$ w3 C#define        FME7_VOL        (0x130): k- H4 Q0 R5 A* l3 W, h  K0 g

4 e" m# |5 z# C' xAPU::APU( NES* parent )
2 d5 ^" T: J% i1 w{
# ?# `9 {3 f* ?$ A- z' `% @2 ~        exsound_select = 0;3 S/ _/ K6 I* ~6 a0 K
9 p" X+ K6 Z6 L% [- ~% V
        nes = parent;
' }& M. R2 \+ \; ]        internal.SetParent( parent );
. t" X  t% i- ?2 A" F" n9 I3 h( H! T; b/ F( ^& X$ Z
        last_data = last_diff = 0;, e# H0 c- |2 W* M# Q( F9 F

, i8 y9 W2 q: C* L        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );! p0 e% i: c( I$ W' o) L& c& Z

# ^7 O8 `/ o+ a  }7 {        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
  c+ C9 z+ n. X$ ]# t2 s        ZEROMEMORY( &queue, sizeof(queue) );) K$ |) E4 }, `8 G1 F: x
        ZEROMEMORY( &exqueue, sizeof(exqueue) );7 H' J: W" u; O7 D2 W

8 c* }3 ~3 S3 }' T3 `; j+ P: @6 {. B        for( INT i = 0; i < 16; i++ ) {. l4 }& C  ?5 v0 b
                m_bMute = TRUE;
: b& X5 I- P  O7 `5 ~        }
( y2 m: V4 P1 c2 Q' ~/ {3 k* d}+ G4 p: c  q2 ~, C' Q

: F: _, T; Y6 p4 l* I, Q+ y" dAPU::~APU()
; x8 M, h3 C+ i$ E7 Z) S{
4 l! A) b4 w( v# v  C/ m$ O& G6 y}
5 m  R' y1 H/ w2 C  L* J, Z* H& E3 J& G
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )6 t* ?1 p* ^7 n" Y$ V* N. U
{
( U1 `2 L' l! C, z6 M        queue.data[queue.wrptr].time = writetime;) Y3 Z9 K: T7 [! G5 b  G8 b& Y
        queue.data[queue.wrptr].addr = addr;' D. X- s' r4 D* }! x4 M% m
        queue.data[queue.wrptr].data = data;
, ^1 e6 m& q2 `6 b, S        queue.wrptr++;
$ y' `, s2 j! o1 w7 X# z        queue.wrptr&=QUEUE_LENGTH-1;
' @" `) v7 F1 G        if( queue.wrptr == queue.rdptr ) {
( W# m3 N- H4 s: V                DEBUGOUT( "queue overflow.\n" );
. Q. A& L: o2 d6 c- f- Y        }
& G8 u: o6 Z, O}
' t0 m( N' M2 D+ B. |* G! g3 `9 v7 _4 T5 s( j3 f
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
7 T" N$ `7 r! k& J{* [& N1 [- @/ d* o1 M4 O2 ^1 s
        if( queue.wrptr == queue.rdptr ) {
5 G/ Z% ]7 c. V$ T' m6 w                return        FALSE;. t3 y4 [. E4 L5 _7 N; `$ [9 n6 f
        }6 O+ t9 X0 N6 A3 I
        if( queue.data[queue.rdptr].time <= writetime ) {
! @& t* F- {( X. b: ]2 O                ret = queue.data[queue.rdptr];" t. }: j' F- ^4 R) X" {1 d; c
                queue.rdptr++;. N: U4 Y2 H5 M1 T: y2 V
                queue.rdptr&=QUEUE_LENGTH-1;
4 m& o/ z/ s+ W) q                return        TRUE;# O9 H6 u) B6 C4 Q5 R5 R
        }, g, p, Y+ c" S/ b' L' R. I0 E
        return        FALSE;
& S6 y! P, y& X5 G8 [}
: i# z. v. ]+ U6 `+ j6 T1 k$ B( N" w; k4 i3 C) \
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
; k! V9 C# \+ Q{
1 G( E% T/ ^5 p! c2 R; a& T& g        exqueue.data[exqueue.wrptr].time = writetime;
3 F7 U3 |& v( T8 B        exqueue.data[exqueue.wrptr].addr = addr;+ j# b" l) s, w2 {
        exqueue.data[exqueue.wrptr].data = data;: g( ]" @6 V, |9 g1 k  e
        exqueue.wrptr++;
6 U/ G6 _* h# z$ _% Y) a        exqueue.wrptr&=QUEUE_LENGTH-1;
1 n: r. ?, c- r- d! X        if( exqueue.wrptr == exqueue.rdptr ) {
& M9 b0 N+ a7 ^3 j1 E& u4 A                DEBUGOUT( "exqueue overflow.\n" );2 {0 ~( Y. f! i+ H6 y
        }
  B6 A% f) b+ `( e* X4 M2 r}) u! H7 I) [% @) q0 i3 F

+ e' j  G8 e, k* v( s! \BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
0 @. ~: @# {! Q$ Z/ j$ R5 [: H{
5 r; |) L( I$ ^  E+ A        if( exqueue.wrptr == exqueue.rdptr ) {
: i6 U0 B$ v" i% l9 Z# o                return        FALSE;3 U6 N3 X7 p9 O2 A+ ^
        }/ H# |. G5 N* U+ k) b% k4 }6 {
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {2 h4 C: N0 U: E: d
                ret = exqueue.data[exqueue.rdptr];5 D" [- H, h3 b) E- m$ T$ i# a
                exqueue.rdptr++;1 z. H9 |, G& N& ^' r/ }. u
                exqueue.rdptr&=QUEUE_LENGTH-1;/ f! D  u: x% k( C5 F
                return        TRUE;
7 B: f' B3 b( H0 S+ `8 w5 C+ s        }
, D; F- `0 K! C. d1 y- f        return        FALSE;
2 ^# o$ ?+ s; H% Y  b6 O}
6 r3 U( f. a/ T
, s4 ]9 \5 l4 D! j% ovoid        APU::QueueClear()) T( Q% c' [8 l* u4 [5 r8 a) T% m
{  x  a& ?: {+ d% f) _. r
        ZEROMEMORY( &queue, sizeof(queue) );
4 a9 W0 L3 ~( z; h0 {        ZEROMEMORY( &exqueue, sizeof(exqueue) );6 V2 S; s" F6 j8 `, O  l  [% ^+ a
}
% ~+ D+ E1 h0 V7 G1 `( u& ~/ e! Y( m$ U. w" {% \, {
void        APU::QueueFlush()6 }4 Z( U; k2 z" Z# T
{
' v5 U: Z& u) Y        while( queue.wrptr != queue.rdptr ) {
+ i! @% g5 t4 {$ W+ H                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );" U' R9 k9 G3 c
                queue.rdptr++;
5 R. t+ ]+ G4 f$ p+ T                queue.rdptr&=QUEUE_LENGTH-1;2 J% o3 t8 s/ x
        }* Z+ S: [$ N; N5 Z/ |/ c

3 [! A! @' p1 {6 T9 V# L0 X0 x* M3 f; S        while( exqueue.wrptr != exqueue.rdptr ) {
; F" P, ?7 I' T: E, C( t' T* @                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
$ X/ h, @/ M" o! E% |3 C                exqueue.rdptr++;
$ G9 E0 W2 }, `9 N& x2 @                exqueue.rdptr&=QUEUE_LENGTH-1;
! C' H1 l6 L0 s7 R5 d  y+ A* `- W/ T        }5 W+ g% B3 ^* X' n
}' f- s6 L0 K8 `2 @

0 Y' c% M' O0 F+ n9 Zvoid        APU::SoundSetup()
6 |4 R$ k; F. E  t/ C{
, B  w0 e' q/ t3 j3 }/ f        FLOAT        fClock = nes->nescfg->CpuClock;
3 f" U0 K" x8 C& Q6 W        INT        nRate = (INT)Config.sound.nRate;3 a3 d' S. p% _  T; U
        internal.Setup( fClock, nRate );+ m' @+ N' L) i) n- y7 Z
        vrc6.Setup( fClock, nRate );$ S8 U/ [$ L$ S/ J9 q1 O
        vrc7.Setup( fClock, nRate );
4 u/ m2 w+ h, J6 `4 \        mmc5.Setup( fClock, nRate );
* V  E# ~9 l# e3 x" J1 h        fds.Setup ( fClock, nRate );
2 ]+ c0 b/ X, g1 B        n106.Setup( fClock, nRate );
$ E4 D; t" l9 [" @2 \9 ?  G+ c        fme7.Setup( fClock, nRate );
& I8 y$ ?/ q& o5 u/ x}
1 {2 C" ]  d3 m+ G; ~8 p: m/ R  T1 _1 N% d2 T4 J
void        APU::Reset()
' s. b( Z2 H4 G" L9 ?5 ^, G. P{
* v5 T* n; m- F6 y! p- M        ZEROMEMORY( &queue, sizeof(queue) );
3 q+ C. v. ^& |: x9 a! v; o        ZEROMEMORY( &exqueue, sizeof(exqueue) );
+ a5 ^, M) Y9 J2 w/ Y* q. O% y  Z: }2 Q+ A' Y, z8 k7 g. [) \5 x
        elapsed_time = 0;5 ], x6 p) M2 ]0 W: D

+ r  V# k* |* u: R/ l3 e        FLOAT        fClock = nes->nescfg->CpuClock;2 g" h$ Y9 G0 B! g5 [" D' N
        INT        nRate = (INT)Config.sound.nRate;- ~* a9 h  Q& t* k! u
        internal.Reset( fClock, nRate );
& c/ N, ?1 k1 N6 Y) s! ]        vrc6.Reset( fClock, nRate );, `& M$ G) _% B
        vrc7.Reset( fClock, nRate );( X4 T/ z1 `* H  \
        mmc5.Reset( fClock, nRate );
% `& A0 A# Z3 E: p        fds.Reset ( fClock, nRate );/ v& W2 }2 B6 O- i- @
        n106.Reset( fClock, nRate );
9 s; \3 {) X) U- O" ?& O- u        fme7.Reset( fClock, nRate );; C$ N! Q5 U4 }. z) f. Q

8 K9 ~  f2 D; p2 D        SoundSetup();, C% x6 M  s3 v" }6 _, w' H
}
6 _; q3 {1 |* w* }, m
# c/ s( [+ ^* p! w+ |9 {% q1 I# _void        APU::SelectExSound( BYTE data )5 H8 q1 b2 q2 ?/ X8 I
{/ V+ A0 ~: D6 u: `
        exsound_select = data;
+ T  U  l, {& H% W( B0 D}
6 V+ |8 T9 Q6 z3 G  V$ h3 _2 |8 s* Y3 |* [1 Z2 O  M
BYTE        APU::Read( WORD addr )( o0 K: E1 f& ]5 j3 Z
{2 E! S; ?1 O6 W) Z, t  V
        return        internal.SyncRead( addr );- x6 s, L' v% [* @! c
}1 X" [* c( T: n9 b
* |& F; X- g. J9 R
void        APU::Write( WORD addr, BYTE data )1 _) M* a6 b3 t! U/ m7 t& ?
{
8 t1 f9 W+ |) B! y: Z, l8 O5 x+ R        // $4018偼VirtuaNES屌桳億乕僩* f' r  i! p5 }) n/ A
        if( addr >= 0x4000 && addr <= 0x401F ) {3 ^* J& Q! Y- K# m5 O( \
                internal.SyncWrite( addr, data );, I$ k0 m' ~2 r% F0 {* R
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );: c# h) w+ C' h; P( ?
        }
: D( ~9 t0 A/ G4 d! b; B* I}* P) L' w7 G( G0 Z6 H

: \. N: Q6 Z% _: r" zBYTE        APU::ExRead( WORD addr )
/ T# ~! \% M4 K& T{! Y8 O3 K* u  P2 y  e2 J- D
BYTE        data = 0;
1 y9 D# l4 z1 b% z" x9 ?# |
) ^3 o& B/ i4 c. F        if( exsound_select & 0x10 ) {( z3 L+ q8 I$ P+ ^" O5 v& e3 c
                if( addr == 0x4800 ) {, R/ o/ _% @4 l$ r
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );9 X5 B% x& k: l' P: \' F/ I. j
                }5 h) W1 p( C2 I; B- v0 m
        }
8 I% F2 D7 q( R6 w$ V        if( exsound_select & 0x04 ) {2 Q5 Z2 U- A/ }( Y
                if( addr >= 0x4040 && addr < 0x4100 ) {
) i& A- p- a- ]* u. j                        data = fds.SyncRead( addr );
; w* n* j3 s. \* m' n" p4 A                }
0 D/ g( i$ G0 ^* z        }' Z: ]# }( q/ ]1 K+ n) m+ n. S& a" M
        if( exsound_select & 0x08 ) {$ U+ R- W* o3 _7 I% _' \
                if( addr >= 0x5000 && addr <= 0x5015 ) {
7 o" J8 u7 u5 s2 k6 |- D; n                        data = mmc5.SyncRead( addr );% v% J+ x8 m6 J: u" ^9 P4 x
                }" y2 v) u1 [/ _8 {  @, w: M
        }9 T6 b. d+ k! m8 M5 m! i& S
- {# X9 h9 W8 S, q- @. R% o3 e; c8 w
        return        data;
, G8 e% K" K5 f8 T( \8 O}
. C' p: U) k# l' g+ F, ~
" r8 {; v! {" ~  H' g6 Jvoid        APU::ExWrite( WORD addr, BYTE data )" a8 f) c- o1 z5 t' |
{
. _- e0 S8 S0 W0 f$ ~/ \! \/ Q  X2 k        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );3 I+ d7 l! L4 D5 C2 V
1 L- [! ^8 c6 Z1 M# _
        if( exsound_select & 0x04 ) {
: O% v1 k% E& r' _) K8 a6 [5 e3 c                if( addr >= 0x4040 && addr < 0x4100 ) {
$ F( P! y7 D" f: ?                        fds.SyncWrite( addr, data );
0 u7 S4 C% W$ j2 l( J2 N                }' G" K9 w# W9 `! j
        }
% m' k4 v+ [& v* J3 X+ O' D
/ z1 M$ p9 S" P9 E# w        if( exsound_select & 0x08 ) {( @: b9 L( @! U- @. S
                if( addr >= 0x5000 && addr <= 0x5015 ) {' T) V" a( }1 L9 X  M
                        mmc5.SyncWrite( addr, data );
  f! f* }/ H% W                }% K3 ]- q6 b- B# a
        }
" A) X0 @: W; q5 I% v2 `- a}, ]! i- Z; w+ V! {! A, F# f0 _
8 g; ]" D3 Z+ }3 P% n, [7 Z
void        APU::Sync()
4 q- {7 J1 O* }* z6 P) W+ x1 g$ z4 e1 E{
# |0 u& S8 `8 P0 m, n' K& Z}9 x* ^- w1 E  I7 K+ Y6 o8 L& q7 A% [
+ x. M! G+ i. L$ r; e
void        APU::SyncDPCM( INT cycles )
- p! K" V. x+ t/ E* d{
2 R- M$ M0 @4 h) E8 B        internal.Sync( cycles );2 h$ p7 n  Y, z

7 Z# f" z5 e) J$ F1 S3 R% v        if( exsound_select & 0x04 ) {  t- S! B0 Y* r$ _* f8 Q: `3 O
                fds.Sync( cycles );  t4 {/ V& M9 F1 x* d# X" C
        }( W( O, H& ~  M7 P
        if( exsound_select & 0x08 ) {
' E) R& R# C' R6 Y' P2 N                mmc5.Sync( cycles );4 e. Q3 X; a$ {
        }" w0 _3 O# g2 U" I$ {( A4 S
}7 v' G5 y. E# P8 _+ h
# {/ A& q% b/ V+ L# l" Y: [5 E
void        APU::WriteProcess( WORD addr, BYTE data )
4 |" F9 ?, B/ H% M3 r3 X9 W, d{9 D# _4 i2 h; j3 {% n5 _3 \$ P
        // $4018偼VirtuaNES屌桳億乕僩+ [! `& B3 D6 [# c% q' J, z
        if( addr >= 0x4000 && addr <= 0x401F ) {3 S" P+ j& m! d, H
                internal.Write( addr, data );* q& e4 w$ C, H( B# Q
        }) t0 v  C0 g3 I" r- p, @
}
% j5 n& A2 q. m  }1 Q/ v
9 L" K; i9 G$ c, h; {void        APU::WriteExProcess( WORD addr, BYTE data )
+ [6 F2 Z) q& f/ O) i{
0 A0 T& x, y$ B* ]; \3 Z        if( exsound_select & 0x01 ) {: w( R* u7 f1 }+ _
                vrc6.Write( addr, data );0 V! l1 T7 w  q
        }5 W/ |9 e4 o: Z3 r4 m( e
        if( exsound_select & 0x02 ) {
5 |, f- S# ?- D; C$ s                vrc7.Write( addr, data );
  g5 F4 Z4 j6 U+ ^        }* t* y2 d" ]0 x1 z# L8 |
        if( exsound_select & 0x04 ) {
5 w5 z& Y0 l5 D1 Y4 p! }                fds.Write( addr, data );) n+ ~& R1 W& @2 W$ n* p- u
        }
" A3 ~: i$ s1 c2 y" {+ Q1 O        if( exsound_select & 0x08 ) {
# J; p) W, L4 K4 O4 w- g                mmc5.Write( addr, data );7 L* F- j% i( N
        }
% n7 |8 {6 W6 t6 C0 ^9 P        if( exsound_select & 0x10 ) {" Q7 E  Q! l( ?( M2 L; t& `' ?
                if( addr == 0x0000 ) {/ l3 U3 V/ Z6 }7 w& y
                        BYTE        dummy = n106.Read( addr );
1 b  u  v9 y' p4 m$ z  j( s                } else {+ A$ K8 G9 \* K; E: C; E' Z
                        n106.Write( addr, data );
" I! M/ Z& W( x                }
& `6 x7 Y5 a) [4 L$ j" g        }* t4 H- V  f2 h. y, g2 d# m
        if( exsound_select & 0x20 ) {$ v, |. F' k# i; x7 s$ a
                fme7.Write( addr, data );
& B: t" t4 W* J9 w5 M0 Q8 x        }. G! L2 C8 X; P- {$ J' e
}
: Z/ C" W; M" H/ k: E6 G
* a: g( O' R" qvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize ); J. v- C1 y$ ~% s  f% o' P* E
{
5 m# U- l; ]( @+ ?0 @. d7 FINT        nBits = Config.sound.nBits;
3 u9 J6 [2 I! Q5 KDWORD        dwLength = dwSize / (nBits/8);
" z" G5 ]9 R7 x% DINT        output;5 q" o  _) @& o+ ^
QUEUEDATA q;) u4 S! l6 N+ z% l9 o
DWORD        writetime;! \- X- P; Y& b; w1 K# z
& E# ?4 r9 k% y/ y
LPSHORT        pSoundBuf = m_SoundBuffer;
8 _0 E2 M$ d; H( }8 Q8 I) bINT        nCcount = 0;
. C+ r8 ^! k7 C* X; H! c
- t7 {- a6 b& H& `, s/ g$ mINT        nFilterType = Config.sound.nFilterType;
) g/ U, y: [/ y3 @9 V) D. \$ O
" x5 w' a& @! |% f7 S2 w3 L        if( !Config.sound.bEnable ) {4 K2 v" Z* P) X. g. B2 d
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );2 H* M' g9 P+ V8 c
                return;
% ]7 R1 |+ t  _4 F        }8 F0 L' f) T. K  a2 |3 M/ l; R" x2 `$ A
8 ]' \( \; l  \6 v- d/ _% I
        // Volume setup& M8 Q8 v* ~2 `3 H. L2 W% G, T% {
        //  0:Master8 t5 w, g* B- j" d3 l3 x
        //  1:Rectangle 1
/ j4 t9 o! B9 ]$ c! R+ C        //  2:Rectangle 2
! }1 {  y1 u3 n- t' U; E8 D        //  3:Triangle/ H$ s& O0 |- x- @( k0 f( l0 z
        //  4:Noise
: t2 J. E; T4 c" m        //  5:DPCM9 v% J+ x" d4 N/ A  n
        //  6:VRC6
4 F1 N, y+ P7 n2 r$ b* P" D        //  7:VRC7
$ E' f7 }$ h6 x        //  8:FDS: v$ W% N7 Q! a4 Y8 M7 N$ H
        //  9:MMC5& Y# C5 E2 E& ]* {5 m
        // 10:N106) d% a& {$ T% [
        // 11:FME78 p2 B; O3 \& u
        INT        vol[24];
7 @# G+ m& _$ Z7 c" o0 s        BOOL*        bMute = m_bMute;
3 }5 S$ v- J6 x) P# ?! B        SHORT*        nVolume = Config.sound.nVolume;+ ]* r  g: }8 R( K, c

, d. R# h4 B1 R& T& B        INT        nMasterVolume = bMute[0]?nVolume[0]:0;/ B6 b" c- v0 a& c0 h! m, P3 y; t
/ `7 ~6 g/ @% L, a/ g
        // Internal
2 T) A' x* S9 c! f5 q* {        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;4 f- {4 j, L; x% Z
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;/ x& ?& r2 X) |: q
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
6 P! E: A; n% z; R" g        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
& ]" A+ P! m- q2 e- n- i6 h$ J! n        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
8 ^# `9 @% _# q1 d  X
4 Q1 w# {' z6 \' V, \4 r        // VRC64 L  R0 h7 Z" D) N1 V% C+ X& A
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
2 D2 A# E! P9 b, X8 \# K        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;9 r. p+ ~$ j3 y- }$ Q
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;  R# \( D8 ?; K  ], \

3 j5 C# |6 R* M        // VRC7# P$ [+ i4 k  r6 s/ a
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
- [' L9 k+ K' S. V' H7 V) u
& o/ {" Z/ q# ?5 \- L        // FDS, B. e! n  V1 W9 X, c% v; \
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;: S! b% U$ h+ k1 Y  W
8 \. l8 C+ `2 U1 J
        // MMC5
7 m- C3 U' ]0 x  k" u        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
1 I& D) ~- M2 t$ [        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
& Z1 @5 c( d. ~% @% P9 B- U        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;4 }) y# \  O+ B7 U6 l0 P% \

* ~' x% G7 R$ r+ a# k        // N106
# }1 p# z4 w7 {4 ?1 R- V7 ?        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' ^/ J% q% A% H; W4 M
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. y3 U' T. o0 M$ ?" i( e7 H2 h5 x        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
$ [/ [4 }! v( G( J0 N# ~' a& M6 G        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
2 y5 `, b: O# a6 T3 s* `        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ m' N( a1 |  c# Y3 I1 b        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; h' ]- |8 D2 |/ u* o
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;1 g+ U% ^6 s' S, ^5 A& y6 Y, c
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 z# P* a' T/ Q! k) c. C, [1 ?+ ]* p7 Y9 h' M+ v5 F# ]! v
        // FME7
7 G/ M0 s+ u, B' g        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
! ^1 `: O# b" C        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
. h2 Q& l# p9 l7 J1 \9 c* D        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;1 |0 h0 E, d! Q# G

# ?& ^$ g! z. D; Z//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;5 T+ f  A! A: Z* q  Y
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
: v# O5 z4 k) H4 N  ?( D% Y& f8 l* w; V$ t
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟3 |" D& N6 i1 v9 v
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
( @2 J+ D/ S1 F( `. T7 i) b0 g                QueueFlush();8 e6 L5 F( B! C, d* v, y5 ?5 ]$ T
        }2 @2 E& A1 k" \+ R% C9 j
  p' J) ?5 Y8 z2 D4 z$ c
        while( dwLength-- ) {
4 v) r$ j) `+ p# g0 s; Z' q                writetime = (DWORD)elapsed_time;
; P7 {5 i4 f  N% U$ Q! P9 e, W) \# X' b. q
                while( GetQueue( writetime, q ) ) {5 R" [; q/ @/ {! M/ Q" d
                        WriteProcess( q.addr, q.data );/ L2 C1 U5 y2 C
                }
0 ~6 }7 q" P3 o' O* q. V$ g8 K8 i. F; u5 p; `
                while( GetExQueue( writetime, q ) ) {
% D- @: D8 o- Z$ x( {2 h9 c+ k                        WriteExProcess( q.addr, q.data );
2 w; H- C/ a  n6 ]; D) ~                }7 l# j4 E& I6 W: K

3 `5 o1 y3 w/ x                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
# M4 {$ {8 e* b: B% n                output = 0;
0 m% ~6 X8 V- r  H% {                output += internal.Process( 0 )*vol[0];4 K5 L0 H* w  ]4 P3 o& p" e) L
                output += internal.Process( 1 )*vol[1];
9 c$ r$ l2 k1 R/ G2 G; I                output += internal.Process( 2 )*vol[2];8 J" Y; C7 }  P, W  P
                output += internal.Process( 3 )*vol[3];" S% l8 F8 C  u, b( c
                output += internal.Process( 4 )*vol[4];7 _& ?# \# H$ y' p' A, U
/ s" u$ m/ a% |9 v* n
                if( exsound_select & 0x01 ) {* _' Z3 f3 D' B+ f2 o
                        output += vrc6.Process( 0 )*vol[5];
; h0 O, j7 J3 Y+ V1 t/ Z                        output += vrc6.Process( 1 )*vol[6];1 T! S, `& A- z- h% C
                        output += vrc6.Process( 2 )*vol[7];2 F4 E1 i. F) Z2 v$ N) Z
                }
0 I3 n) @5 M) P$ A5 |                if( exsound_select & 0x02 ) {( M7 A% |' N: Z3 B9 s
                        output += vrc7.Process( 0 )*vol[8];
: H; R, o$ f$ }! b! ^1 j( D  |8 u* z                }
; |7 z0 _5 _+ b4 q                if( exsound_select & 0x04 ) {
8 c) e1 o( \  I. F9 b                        output += fds.Process( 0 )*vol[9];$ |  w2 H3 y3 B+ y
                }% G+ H3 A% N* u2 M& m; L: g
                if( exsound_select & 0x08 ) {
. N, R2 l* h( ]& w                        output += mmc5.Process( 0 )*vol[10];7 U: l' p2 ]- y/ G/ [
                        output += mmc5.Process( 1 )*vol[11];: r7 _+ {8 m9 D
                        output += mmc5.Process( 2 )*vol[12];; y) d+ t% H9 b3 C
                }
* g7 F# `2 ^1 r* L# a( b. J) a                if( exsound_select & 0x10 ) {5 ^' e3 ^" q" z. F( V* f$ X
                        output += n106.Process( 0 )*vol[13];
% E/ b/ l1 U) s4 B' b  N& c) S                        output += n106.Process( 1 )*vol[14];' ], ]  Y7 ~7 ]& w, z, V
                        output += n106.Process( 2 )*vol[15];
5 f3 R6 }$ T# B" k" |                        output += n106.Process( 3 )*vol[16];1 Q/ C+ Y: }2 @3 j: T
                        output += n106.Process( 4 )*vol[17];
$ s+ a- I; ^1 Z3 e                        output += n106.Process( 5 )*vol[18];
) B1 v! ^$ u# v. x2 S                        output += n106.Process( 6 )*vol[19];
/ U, |3 l2 `. a8 r                        output += n106.Process( 7 )*vol[20];
% y, y9 P8 x+ G' Y# U5 }& \6 G                }+ |2 L& W( B0 F' o
                if( exsound_select & 0x20 ) {: W% g' Q! d8 A  p
                        fme7.Process( 3 );        // Envelope & Noise; q% I( e* S- [+ a7 F% w
                        output += fme7.Process( 0 )*vol[21];
: j- Y8 ?0 Z% j, `8 c                        output += fme7.Process( 1 )*vol[22];7 l5 c7 g9 H# |# a
                        output += fme7.Process( 2 )*vol[23];" G- t6 Q) O* A
                }
& J+ B9 d6 l7 k) O
( T  v% K5 v6 y; C- f$ Y4 [                output >>= 8;
% z8 G" W6 K' U
% g$ H. y" h- v9 w! Y& K4 G                if( nFilterType == 1 ) {
  q, v% ^" ]5 P+ X/ F$ Q                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)& N" H1 c+ ]3 R' U+ k
                        output = (lowpass_filter[0]+output)/2;
2 n3 b- T' C. S, r6 I+ p                        lowpass_filter[0] = output;
, B6 V) g; s3 F* Y) P: t% Z                } else if( nFilterType == 2 ) {
( s' T: x. o* {                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
; Y  c3 O6 i! {" T                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
& p: X1 r) F! V& u# v& {                        lowpass_filter[1] = lowpass_filter[0];: a( A) B! ]0 G. v
                        lowpass_filter[0] = output;1 }) V0 P, t1 B! \) t$ j# B. A' ?
                } else if( nFilterType == 3 ) {8 Q; T2 ^4 d) @5 T3 _5 e0 ~4 D1 J
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)" L4 |0 C/ u0 K. g! h! ~
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;% P' N+ z) [' ~! p; z' f
                        lowpass_filter[2] = lowpass_filter[1];
8 Z4 ?  J- n. J) t7 |                        lowpass_filter[1] = lowpass_filter[0];+ V- \* j( R& E( B9 m  `
                        lowpass_filter[0] = output;3 E  e3 I5 y* h% t
                } else if( nFilterType == 4 ) {
+ i" a1 J5 Z9 Z& f                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
, r9 g9 ]( T" x, `- _8 \                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;! w: L1 p; T4 T- }  V
                        lowpass_filter[1] = lowpass_filter[0];
! g* F# T6 J. q                        lowpass_filter[0] = output;1 |$ O; c' T1 b- y
                }
3 |: c& P$ g# g7 q: m# K8 n- {! }8 g6 a) q
#if        0
1 l0 \& \4 ]( K+ m4 j8 E( a1 ^  D                // DC惉暘偺僇僢僩
( C( O( e0 T: M: a                {% Q* {, M; H& V
                static double ave = 0.0, max=0.0, min=0.0;
. B/ f$ M4 ~  p. |- J                double delta;0 w, y8 r! x& E( W/ U, i$ E
                delta = (max-min)/32768.0;
2 H& l' d& x: P$ @9 r; V                max -= delta;
' {& I( t7 L( o+ U2 P& x( F8 h& X                min += delta;8 T) k& n' z* b% o: x) @' x
                if( output > max ) max = output;8 m& T' H  ?! K- |4 j* r8 U
                if( output < min ) min = output;
7 [0 y/ X9 r; a- `; s  r                ave -= ave/1024.0;
4 h* g# o9 y" @3 z/ [                ave += (max+min)/2048.0;
& W& ~# \1 u2 P2 Q. E9 `8 i                output -= (INT)ave;
0 B0 ~, \0 P( @: {/ P                }
" l% D+ f9 P& c. a  O#endif
& X( r5 S" @: L7 g#if        1
# B) o  T6 E( |; g4 s! d, |                // DC惉暘偺僇僢僩(HPF TEST)
! y5 o, n4 b# |/ W                {
* n7 |) B  G6 _6 @( @! ~//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);* s' U  x  C) W
                static        double        cutofftemp = (2.0*3.141592653579*40.0);. T6 _  d! x% V9 q: }7 t
                double        cutoff = cutofftemp/(double)Config.sound.nRate;9 w' ~! M" G" |. u6 U
                static        double        tmp = 0.0;( p) g7 n! r, ]0 [
                double        in, out;. g. F+ o* K6 P6 i* h4 `
) D  }- ~1 V/ J( [( ^" h
                in = (double)output;: T. {( V- n) {& K& m6 E9 U! T
                out = (in - tmp);
1 X( S8 b: [+ {' c. ~                tmp = tmp + cutoff * out;% R8 _1 J: \' C3 r1 {0 P! U
/ F2 s$ i( n& r  @, Y
                output = (INT)out;, _7 J9 y; p( q' P8 e
                }4 h* d6 v- }4 |& L0 ]- e  {3 @8 Z8 H6 n
#endif
9 @) q, z0 J0 A. f#if        00 E9 e2 _# ]3 c: ?, R
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
: q: T1 Z" u5 P7 V: O4 J2 m( _                {
3 l! m' @( o8 N6 O  O; O% {2 |! A                INT        diff = abs(output-last_data);+ D2 M1 G% m* F
                if( diff > 0x4000 ) {
8 M! }2 J/ @; c1 f                        output /= 4;. |6 [9 R/ w! b0 f4 u) e
                } else + `0 A9 I- a1 _2 K6 ~
                if( diff > 0x3000 ) {8 V! l% x" L+ ~
                        output /= 3;; B9 B- }- Y/ S/ X
                } else
3 Y- |* @0 T4 [                if( diff > 0x2000 ) {
( A5 ^/ }" d4 m                        output /= 2;
; M* u& s4 m9 j/ M& A( n! \, u                }
6 x. Q; f9 T6 l" ^9 R                last_data = output;
, N$ V) F) l' W  u                }1 C% b  Z9 V' Z  J. g) b- d
#endif$ F! k* U, g/ r3 z' S
                // Limit
: j+ i5 D9 r7 e' G                if( output > 0x7FFF ) {' Y, z7 Q9 v! M
                        output = 0x7FFF;4 a3 Q: d8 @( U9 F+ T, x
                } else if( output < -0x8000 ) {
9 g, M* R& B" a7 J3 A. R* J                        output = -0x8000;4 j" U% z# Q$ i" G+ [1 N7 H( k0 B% P/ A
                }( M. F% Z8 `5 i
5 X3 y8 t* X" L
                if( nBits != 8 ) {+ G$ ^! G1 ^$ t2 h/ l# K# s
                        *(SHORT*)lpBuffer = (SHORT)output;
, R% O9 }: h' A4 x3 `, e, g. x                        lpBuffer += sizeof(SHORT);
# k2 I. U" R7 G2 {: k0 |0 w                } else {! l8 r) O5 C+ e
                        *lpBuffer++ = (output>>8)^0x80;
/ L) K. T6 t% l                }9 U% P  Z* P( }9 b% |

+ o6 \6 s0 B  r0 T# K6 ^3 s                if( nCcount < 0x0100 )0 p; z& O2 E: A) o. {6 K
                        pSoundBuf[nCcount++] = (SHORT)output;9 \& K7 ~6 D9 b7 v" W4 X* i
9 L, p: Y4 Z1 q( j) i( L5 z# j
//                elapsedtime += cycle_rate;
6 R. f$ N  n: O$ p; u) i                elapsed_time += cycle_rate;, |# z& F2 d9 _: F# t, ]" l' T9 J" m
        }
: b" Q! ^% H7 t+ P# t6 }3 M+ Q! p7 h; N( \! P0 W$ N1 F
#if        15 l" \* X8 ^7 [7 f) A1 c, T
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {. e- O9 E' c- y
                elapsed_time = nes->cpu->GetTotalCycles();6 E9 y, d3 Z& c. w* p
        }- t1 n9 W& U8 u  r9 j/ o2 O
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {8 ^. S' }& ^" q: J; ?
                elapsed_time = nes->cpu->GetTotalCycles();
4 X" i' o# ~. P, X8 i* [        }7 g! T3 y& p' n: t6 t6 T, b) o
#else
; D8 z% d9 B, ]7 T        elapsed_time = nes->cpu->GetTotalCycles();
3 N, s- n7 N4 X$ }, R% j#endif8 y* V) x; _9 G0 z
}
/ `$ l* U( h8 X+ w; ]0 q( {1 Y6 X* U
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)4 p) D! P7 h0 T9 P
INT        APU::GetChannelFrequency( INT no )
  y$ Z7 A! ~* A- W{4 q4 o- F" V8 r$ x* {
        if( !m_bMute[0] )! B" s( g% h1 u9 @2 S4 y
                return        0;) B  `% g. \% r( L5 H2 R, h% ~; P
/ L  L2 n5 _1 O0 I  m+ B
        // Internal. H' c# _0 M" F& c: m& n
        if( no < 5 ) {
( x5 Z$ b1 P, {+ x5 g5 G2 h                return        m_bMute[no+1]?internal.GetFreq( no ):0;' _$ s1 z% Y0 m* Y: e
        }
0 x1 Q9 v4 h* x' E6 ]" N        // VRC6- Y; y4 Q  F8 P; |5 m/ E
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {! q) v* m+ D" O! \
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;' y2 `* P) s% m5 [1 Q
        }, @; a% G5 B0 n5 m$ a1 r0 J9 K" p
        // FDS/ g- s( `! f0 L; t
        if( (exsound_select & 0x04) && no == 0x300 ) {4 A# _$ n  `& g6 i
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
/ Z. P. F( B3 d% w9 V- G9 Z        }
5 p" U5 u+ @1 E8 q+ G' R, r1 t        // MMC53 U; U3 ]$ D: x/ \4 A. E
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {# t3 |* N. c# s
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
1 {! z# D; O# u7 \1 S4 A        }
9 i: L" n5 _- c) C" O9 |' d' P  Z  _        // N106* `8 F1 v. Z9 l# f! S
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {) u3 `$ J5 i. E, T$ u6 G) s' O
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;0 s$ ^% |# w. V5 u
        }) h$ u8 o# }$ e* {' n) H
        // FME7
' a/ P6 u+ Z" V+ D% p        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {" M* L, d) p+ g! e+ l% r9 d
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
, v) a2 S6 B+ w' O3 p, f        }) w5 S8 c3 G% U# T! H+ @
        // VRC7
' G: u! x* D! m. u" D+ z1 C        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
- V* L' C3 E, D! k                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;' F) i2 w" I  t+ [% C
        }9 T; d. o: s. N1 z, u% R  G
        return        0;4 y2 S5 ^9 r7 W% j4 M2 q' F: Y
}
0 M& q/ C- Z( q  e2 u) i- d' c( n+ A% e2 _/ H6 V* D
// State Save/Load5 E+ w$ u3 A6 d  |
void        APU::SaveState( LPBYTE p )& `6 Y, h- h9 U: d
{
# ~$ V8 _# e; b2 D. T#ifdef        _DEBUG
' v3 V1 U4 {2 I' b! {1 aLPBYTE        pold = p;! g( u* U# T6 u7 T
#endif
3 f6 k+ ~, r( `, P" \
+ H2 w3 h1 H# @4 d2 n, O. J' G        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞- f, }# ~3 h" t0 j% ?6 M5 L) G6 O- M
        QueueFlush();2 N2 ]/ a- e) h8 y+ T
! ?% h$ @' A+ D% g0 j8 }* F$ H
        internal.SaveState( p );
* X4 }: u- n% ~" x! o- S# ?        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
# C$ M: j' W$ K) U$ W
0 ~, R& Q5 q, K/ y) U9 h7 P        // VRC6" `6 t/ e, J0 |' H8 y: @$ @
        if( exsound_select & 0x01 ) {
0 y6 O# E2 ]8 w! o                vrc6.SaveState( p );7 h2 P# k+ U( a5 J% X' X3 g
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding) `' o2 y) C! m% N  w
        }
& m) B" T/ E. P) v8 K        // VRC7 (not support)
5 ~7 N4 I. j0 e$ `2 o0 l2 J+ d        if( exsound_select & 0x02 ) {
+ b' q0 K, I/ q# X7 w                vrc7.SaveState( p );
; u, H( u' f4 r) f) C( i                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding/ v  ~/ \( ^6 J& x
        }
2 {$ x+ Y2 a2 q; W9 X( M        // FDS2 L: W6 ]. H- |- X
        if( exsound_select & 0x04 ) {
2 l* A# l& `2 K                fds.SaveState( p );
" }: Z, ~' n" A                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding" u$ q9 N  `/ d- L; f& W) b
        }6 O7 u5 ]# Z6 ~& M1 z1 r* w, T
        // MMC5  S; n! t3 q! R6 I, C, J  ?
        if( exsound_select & 0x08 ) {: O& [; y2 S6 J( @8 G! h
                mmc5.SaveState( p );
# }8 q# |* s# N$ T. m                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding5 r: ^4 m% p8 ~+ s0 ~5 j% [6 R- Z7 m/ l
        }
- }3 k; q. [4 ?( q! m# A        // N106) ]2 O/ r2 `' R  i! @- U
        if( exsound_select & 0x10 ) {6 J; \/ ~1 C+ J, J: }
                n106.SaveState( p );' A  W% |& f0 K4 b
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding4 i1 Y0 Q6 u5 T
        }: Q. d$ i0 {1 s
        // FME78 d+ {- K7 \) K5 r2 }
        if( exsound_select & 0x20 ) {+ |3 D; D+ z" }
                fme7.SaveState( p );- F- m: X: A* }- Z$ i
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding! v9 d  c0 {) g9 u  w; t
        }# L# B, N$ C* q

9 t* K8 N- H- \$ w2 f  e- K#ifdef        _DEBUG2 d6 I( l/ r) w! C9 O% K
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
. a1 M. `" k  o: j#endif
) g; N- M9 V2 s  a4 t  {}
! b; V# Q- D( P' \& Y% M# R, B3 G
void        APU::LoadState( LPBYTE p )
% U2 H6 `% o9 O/ }9 D" f; b8 ?{
* x: T) ^' H. X. `. T: j        // 帪娫幉傪摨婜偝偣傞堊偵徚偡1 f( F' V$ D. E5 _3 @& E
        QueueClear();( i, B0 v1 d1 @8 f
5 V1 `: H  n5 c/ c4 W5 n3 i
        internal.LoadState( p );
: ^% U; U' @# q  r) k; c        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding. \' u( L6 {0 ~. K8 Y* K
" x; R3 V7 [+ }7 `9 ]6 z
        // VRC65 _5 X' Y/ h5 A! ^- s
        if( exsound_select & 0x01 ) {4 y* K. O! X5 ?  C) y; ], X8 ~
                vrc6.LoadState( p );
0 S% G$ k! ~' L5 O0 W+ G                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding: Y. B  c; Z: U9 p5 b
        }
4 r9 F5 B  C3 x( t) x0 S8 O6 P        // VRC7 (not support)0 _/ J. f, {* E+ J
        if( exsound_select & 0x02 ) {6 ]! m. F0 Z# l3 L" \
                vrc7.LoadState( p );
! D7 r& p8 g4 j' `9 n                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding2 Q( B5 {. u" X: M" V1 p  `
        }, _% j* Z  v7 @# i) x
        // FDS9 b( W6 |) |0 v! |0 X
        if( exsound_select & 0x04 ) {
* X' O" r, c$ \5 q" S! `                fds.LoadState( p );% b& Q) F& O2 W- z1 ~, w
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
6 }2 h7 l: _& O        }5 e; {, [: Z0 @
        // MMC5
+ R7 z  ?( ?' s+ ?, Z6 k        if( exsound_select & 0x08 ) {
! {& n( O+ D% U0 G                mmc5.LoadState( p );
: r/ p4 g5 e, b, u$ s# v& h                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding, n- {, _; N5 L
        }+ f; s; Z* X- T
        // N106
6 v" E& [' u" _! Y+ i0 @3 O        if( exsound_select & 0x10 ) {1 Q4 y3 N+ s. d( y& Y( J
                n106.LoadState( p );
0 y+ c- j4 l; e2 C  G                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding! f; P4 c$ x- i
        }
8 z9 J  x' F0 `, c; j. n        // FME7
! ]% M1 B1 g2 v( L        if( exsound_select & 0x20 ) {9 y% Q7 r' U/ f/ {* X: S/ F; [
                fme7.LoadState( p );5 @" X, }7 f, b( Y) [
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
' j8 T' c' @% t8 ^: Z        }
2 E. U: y1 j+ m}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
; v' g) a: _+ j( C# a可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
8 w& r4 g  d6 I, P' i+ p: b* ~感激不尽~~

) n' V1 y6 V1 F2 D5 d恩 我對模擬器不是很有研究,$ T" l0 e; }9 F- J/ {6 y
雖然要了解源碼內容,可能不是很困難,
: U! n: D' B! n: ?$ L- k8 A不過還是要花時間,個人目前蠻忙碌的。
2 q& k7 y; Z: N1 Z  I" r+ E
0 e! @* r1 u6 N5 @7 _) }& p+ J給你一個朋友的MSN,你可以跟他討論看看,
" a0 I4 h) j) [4 ^3 h3 `) o$ o) ]他本身是程式設計師,也對FC模擬器很有興趣。; U. s- G- |9 v8 l% n: [6 Y

7 e- E; w- w8 |9 gMSN我就PM到你的信箱了。& _% H0 C* _* }2 m
3 F1 `+ s1 y! \( r- J
希望你能有所得。

该用户从未签到

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

签到天数: 80 天

[LV.6]常住居民II

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

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表 ! g) |5 m( X$ N$ y' u* F' g' z
呵…… 谢过团长大人~~

" ^4 O5 I. x1 F1 Q3 b/ a
# O, _8 n" z4 }4 I$ Z1 h哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
, T/ j7 f2 G% X" t* b团长的朋友都是神,那团长就是神的boss。
4 H- G' I% Y( U' q8 _+ R* D4 w
哈 不敢當,我只是個平凡人,; D( }  H! I" Y
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
5 B; e( Z- ]7 u1 \/ `ZYH
. |3 p% `( P3 i$ @. `* O  [) FQQ:414734306; ~0 M2 u7 W  ]) g- ~, s0 G- z
Mail:zyh-01@126.com
! c! S- P' ^  L* X  y  d# X
$ b; ~1 ~9 j9 w/ X" H* K/ S+ Y他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 / e0 z5 m! k2 c) _* }
再次对团长大人和悠悠哥的无私帮助表示感谢~~
( h% [* s- |1 Q2 t7 V
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-2-21 03:03 , Processed in 1.130860 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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