EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?" p* h0 _; J6 S2 P5 }0 Z
PS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。+ \3 H9 j4 g: N' x
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~$ }+ k+ ~9 n  d5 h  `; F0 p$ Z
这里有相应的模拟器源码,就当送给大侠了~~1 t7 Y' Q; o) L" A
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
+ X+ i9 l1 F' a7 f( k4 E能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
; e* O( k% m/ V) B; F; Z楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
5 |" g/ K, @' b0 p6 D这里有相应的模拟器源码,就当送给大侠 ...

) s. G) `& [1 Q, I聲音部分(Audoi Process Unit = APU):  O& s/ ]' V3 H- Y8 p
.\NES\APU.cpp
* V( {9 y& Z- k( T! e.\NES\APU.h4 _: D  S9 Y4 n% |

9 F1 f4 {- k- d' c0 i4 C: A
9 }2 G% Q4 z' N' R影像處理部份(Picture Processing Unit = PPU):3 o( l3 q% r. z6 J  m% x1 W% p
.\NES\PPU.cpp
) S" z) i. F& h. \$ _.\NES\PPU.h$ G; T0 M4 d; a3 r& y6 O" K
/ L! @, V' J8 P8 D4 Q
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
4 [% W$ K& D( @0 c. g(由于很多专用术语和算法机理都不明白,所以看不大懂……)
4 u# @' T. a2 S+ v* x  g//////////////////////////////////////////////////////////////////////////
0 C+ x: n( ?9 M' [& N5 P4 Z//                                                                      //
: E% y( _* T0 u. X5 X+ C: z//      NES APU core                                                    //
/ W) W+ s) I3 a2 Q, k' f//                                                           Norix      //+ ~1 O+ j  u' G, C/ g
//                                               written     2002/06/27 //3 v2 `# D) s4 r# S
//                                               last modify ----/--/-- //- x/ c- M/ l" v# I8 Y1 A; `# B
//////////////////////////////////////////////////////////////////////////
: e6 S  S5 p! Q( l' i% P8 t#include "DebugOut.h"
  E2 ?, b8 F' A$ n$ t3 X# l' O#include "App.h", `7 |9 ~1 C! l0 `2 {
#include "Config.h"# B. d' i7 R6 ^" x. b, z$ r$ |
2 N/ f0 d7 u# H
#include "nes.h"
2 |4 I7 g/ f: [& _: J) T% f* j, b#include "mmu.h"$ F- T( X6 V  x+ {
#include "cpu.h"
- N$ P- O, h) E! ]#include "ppu.h"
, t0 j  z: ~/ x2 Y. E#include "rom.h"
4 i1 B3 a4 O6 n#include "apu.h"
, O& o. d2 Q/ L7 k  U9 V) @9 Z0 v# X/ c# M: `& V4 |3 a* R
// Volume adjust% `2 a1 W- z! _1 h
// Internal sounds
  _" h6 n( T$ T" J3 [) p#define        RECTANGLE_VOL        (0x0F0)
4 V# ~& M9 |- u5 Q, V#define        TRIANGLE_VOL        (0x130)
# J6 Z4 e% y7 O% u, [( {$ F#define        NOISE_VOL        (0x0C0)8 N; S" D6 m' z! z  l6 S
#define        DPCM_VOL        (0x0F0)
8 |5 X3 l6 f8 O- ]// Extra sounds: N$ v. B( J+ Q+ ]% j' F/ }6 E" W: u5 g" y
#define        VRC6_VOL        (0x0F0)! o) W) X, f5 l$ i7 j5 s$ G5 p- c
#define        VRC7_VOL        (0x130)
/ C$ h# U! e4 e, k) F#define        FDS_VOL                (0x0F0)' _  @% R' ?4 ~  e6 c  ~
#define        MMC5_VOL        (0x0F0)3 D$ n4 V! t6 r! U# L: ]# _9 V) l
#define        N106_VOL        (0x088)
9 I# q4 ]# P4 M7 ]0 u( ?+ |  ?#define        FME7_VOL        (0x130)
- R: j" i& w2 {1 m4 |8 E6 d$ R: p# O9 D
APU::APU( NES* parent )
+ y9 L% ]2 Q( }) N2 w# Z  x# F2 G, _{9 H* z( U; d5 X
        exsound_select = 0;* B0 L  V) d4 `+ r9 S% {' A* q) N
+ p( [" o. I! C# S; c5 |* m6 c
        nes = parent;
( [3 _0 o  K/ C        internal.SetParent( parent );! b3 i+ b# O" j  I2 l

  s0 w  S1 t3 U) u6 K& l( w. F        last_data = last_diff = 0;
' w% r+ h5 ]5 w! w2 ^" M* s5 G( x, _# b% G% q- N8 T
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
2 B1 Z0 k& j& ?+ f
& m+ `* ]5 P8 L        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
, J: U! \0 f6 {+ X. L6 E        ZEROMEMORY( &queue, sizeof(queue) );6 w5 [. q. I) Q1 b5 X- Z% t! Q
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
3 V+ p$ y' `' N5 B" }4 x( r
' {7 U' d' `- }+ r" F1 P        for( INT i = 0; i < 16; i++ ) {
  v) u0 j% W1 e+ j0 B                m_bMute = TRUE;
- c) u9 L4 |) M1 N0 b        }
: r( s: m$ C4 ], ]}: |; h; Z, @' `0 K7 K! q" l+ x
! P/ A0 z$ X, S5 ?, S3 r
APU::~APU()( ]# v2 \9 Y) o5 o
{
5 w1 p: y( E: @/ h" x1 S}
& y" R. F- y7 z0 ?) w( U: X/ Y. G$ f
/ Y: K  \5 X# \  x3 ~4 b$ Tvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data ), d8 Y& H6 `9 q! A2 M" l/ p
{
, J! @) s; L: d' C& l        queue.data[queue.wrptr].time = writetime;
7 j. E+ ^7 L: a- `0 Q5 f2 q        queue.data[queue.wrptr].addr = addr;
8 s* ~& {& z: D1 _        queue.data[queue.wrptr].data = data;8 @7 C# Y5 a6 b2 i. C1 E0 V
        queue.wrptr++;
; O' `& x- c3 k+ }        queue.wrptr&=QUEUE_LENGTH-1;* X7 m/ M$ v* Q7 B/ E) Q/ B9 i
        if( queue.wrptr == queue.rdptr ) {
' r+ a3 Y5 J0 {+ F% m7 _                DEBUGOUT( "queue overflow.\n" );5 V: E  O6 q" T$ _
        }
' U2 V) o9 D3 F6 N0 P8 s5 I}2 G+ u3 _) ?# v, I" a- V

0 w! ]4 O, l' g; D: i5 nBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
* x8 l% q2 \* |/ m{
6 o4 d6 w, z. I4 z; W  ^        if( queue.wrptr == queue.rdptr ) {
% B% q: O: @* ]5 h" ~" A                return        FALSE;
+ s! G0 W1 n+ H+ Z& Z, L        }
3 H4 w/ K  o* b        if( queue.data[queue.rdptr].time <= writetime ) {
& O" B. s. F+ Z" E+ f' ]                ret = queue.data[queue.rdptr];7 {$ X: v- ^+ p  n( N1 V0 [
                queue.rdptr++;: T% t2 t  w& k( s
                queue.rdptr&=QUEUE_LENGTH-1;3 b# H& T7 I! A$ B, T1 G! S4 `
                return        TRUE;
- {0 a) H* v& |        }
3 ]5 E* A+ d3 }& X. d& K; Z        return        FALSE;+ n/ r- Z5 p6 u# m/ [" ^8 z5 e7 s
}
4 M7 a# o3 p9 z/ H* w9 L" `
: H0 w* o2 a" e7 }  H) a+ ?* Vvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data ), o' q0 r& Z1 h" T
{: k( }7 e& a8 U% d' l
        exqueue.data[exqueue.wrptr].time = writetime;
) j& W: Y6 U; D; R: ], `! l3 k2 d, \        exqueue.data[exqueue.wrptr].addr = addr;+ [# W3 |( w% S+ a: l
        exqueue.data[exqueue.wrptr].data = data;
: @# ~6 g- G  _4 u% ~3 z        exqueue.wrptr++;
2 t" I8 d: ?! d  j, y" P        exqueue.wrptr&=QUEUE_LENGTH-1;2 _3 |7 k+ S4 }7 D$ @: B* J
        if( exqueue.wrptr == exqueue.rdptr ) {
9 ~  c+ i! N0 \( z8 E                DEBUGOUT( "exqueue overflow.\n" );
( F& p# k& a8 p, k' R, b        }# ?# @6 t+ P3 l, g, A4 ?
}
5 E& @5 h0 P0 g$ ]% a% e+ S/ O( v' m2 l
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
0 L* P  U7 r$ Z* d{5 h. M  j% O2 A. a' z( m
        if( exqueue.wrptr == exqueue.rdptr ) {
! \' B' M4 s0 v; d1 f; S8 z1 \                return        FALSE;+ O$ m9 N3 ~5 C* T' q
        }" Z, l- p. w* q/ T0 f
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
" X. G- J2 v  G! I8 V                ret = exqueue.data[exqueue.rdptr];
2 X$ Y6 \8 t; n& X7 [                exqueue.rdptr++;
4 M" y* ?" j* M                exqueue.rdptr&=QUEUE_LENGTH-1;. b( n: W. R3 f
                return        TRUE;
4 R5 M6 l3 n4 Y        }
8 l( [$ \7 O) i- X$ {2 M        return        FALSE;
4 U' [) `; S5 A  {7 z}
! r1 m5 K* a, u6 W. }5 d9 S
4 O# d, J1 a+ qvoid        APU::QueueClear()
) C& C. Z+ P8 g% x0 ^' A{/ o* i/ j6 J  b$ ^3 Y1 X8 `
        ZEROMEMORY( &queue, sizeof(queue) );7 j" P% Q% O5 `$ D1 W  t( a
        ZEROMEMORY( &exqueue, sizeof(exqueue) );" B6 E  K7 ]  q* F
}' y  @$ I( u3 h( \- o& _4 E/ Y: E' i& o! t

! p  W" I, d1 Svoid        APU::QueueFlush()
' m' [8 e( x5 W5 b0 [  X{
3 q4 ]" s5 ?4 W2 h, ^$ k; y: b  ?        while( queue.wrptr != queue.rdptr ) {
2 {7 J& ?9 d/ u$ [                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );3 b" l# j) Z: T0 F) D8 c, \
                queue.rdptr++;7 m" j4 [# d. ^2 P% W; i' z
                queue.rdptr&=QUEUE_LENGTH-1;/ J  u6 M+ f+ W* }4 e5 T
        }9 c# L3 L; F9 z7 y$ u4 l
9 A. n8 ?+ A& j+ w
        while( exqueue.wrptr != exqueue.rdptr ) {
/ X; L, B. b3 z# `! C9 J                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
- X, z0 `4 d0 e: R8 R) v# _                exqueue.rdptr++;" f+ u0 K' D4 N
                exqueue.rdptr&=QUEUE_LENGTH-1;
0 |7 G# ~+ N) c1 Z$ x1 b( N+ e: _        }
, U) w; }# m! [; D  j}
& a/ M% ~/ w" ^4 r/ w
8 w9 m, P7 `0 p& ^# wvoid        APU::SoundSetup()
. O9 w3 K* m4 g* X0 H{
% E/ ~/ w9 a: N* u        FLOAT        fClock = nes->nescfg->CpuClock;
0 x( ]7 u9 Y7 o3 }        INT        nRate = (INT)Config.sound.nRate;
1 V$ j1 s7 x/ s4 T        internal.Setup( fClock, nRate );
/ Z8 ~2 G* e& F* z, F3 V6 Q( w        vrc6.Setup( fClock, nRate );
* O. D  s- O) f7 i/ D5 F        vrc7.Setup( fClock, nRate );" o6 @& y5 C+ C& Q* x4 t
        mmc5.Setup( fClock, nRate );
* ]; z, D: j9 K7 L# P  w        fds.Setup ( fClock, nRate );
' z  c2 i! O; t0 C$ H        n106.Setup( fClock, nRate );
7 z* [7 d# D2 B2 W2 M        fme7.Setup( fClock, nRate );
  b8 ~0 s/ ^$ |- [5 j}
$ w4 p  d/ X2 z' Y, ?4 M1 ?5 s4 E; f: y" ~5 M* C
void        APU::Reset(), e: k, S% ^% ]' W/ Q2 G
{
3 H! V3 H/ O# k! }; ]: y6 J/ B/ \        ZEROMEMORY( &queue, sizeof(queue) );: f9 f  L8 p& Q, x8 D1 p2 L
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
+ i5 G! q1 `7 S% }) g. ?
& e, q9 `' K; t" u: ~1 M' J9 e" `        elapsed_time = 0;9 Z/ W$ ?- W8 v$ W- k! b
& x/ W) O' W6 M9 m: M: t
        FLOAT        fClock = nes->nescfg->CpuClock;/ u. c: z" ^" l. x6 C) P( O* N
        INT        nRate = (INT)Config.sound.nRate;
0 p. W0 d& `& }/ A9 K        internal.Reset( fClock, nRate );
- b0 P; X0 m1 N/ D# @6 M        vrc6.Reset( fClock, nRate );
- [/ I; D) |$ ^        vrc7.Reset( fClock, nRate );
; S" \$ i" x6 R* s) n        mmc5.Reset( fClock, nRate );  y$ `! m8 m3 z1 w: K3 |
        fds.Reset ( fClock, nRate );
0 J+ L9 N5 p9 W' e        n106.Reset( fClock, nRate );
( k2 E- H5 b( O( p2 S$ H4 ]5 C+ v  D        fme7.Reset( fClock, nRate );
( m, y6 b8 d# q9 L$ }3 p/ y
, U# @5 J! y& D! W, z( G# ]2 r! {* d- j        SoundSetup();
( K9 }+ R% L# Z}
6 M, t/ B  d' Z7 c3 Z, t
( r! Y  A8 b' B+ {4 ^7 U+ lvoid        APU::SelectExSound( BYTE data ). L( D2 f2 D& ~7 ]
{
, ?% n6 I( S" }+ t7 M        exsound_select = data;( ?% t6 |; U! _: I* A& _, {
}
1 Z6 L( Z) F. n
) K& }2 x8 k( H% l+ X/ CBYTE        APU::Read( WORD addr )
4 G9 X2 }) w2 f! M9 X{# W) ~( M4 F* Y2 I
        return        internal.SyncRead( addr );
( c5 {9 ?3 Z0 O$ w" }- o0 C( P, j}
: n. F0 m0 g) Z! B& H$ ?: I0 L3 r8 M5 [! B7 i# V$ a
void        APU::Write( WORD addr, BYTE data ). P8 C+ {* O+ I  k; d7 |5 V
{
. h# l/ R1 R0 K% W. X1 p0 {8 {6 Q        // $4018偼VirtuaNES屌桳億乕僩9 B/ E9 l3 x0 K% p
        if( addr >= 0x4000 && addr <= 0x401F ) {5 v! s- F% z& d% {/ n
                internal.SyncWrite( addr, data );! @8 N  D: Y. @- }& N; A: l
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
& Z. [2 g9 v6 r% q" t2 q6 h        }( d4 L: D- d; v9 X
}
7 c7 i/ i2 p7 ]
% x- h! m- o! `. X4 G- X9 b' _, NBYTE        APU::ExRead( WORD addr )
1 a: E$ z, G# P3 q- `. {' X* H{
8 ]5 j4 |0 k7 e( K, M% Q2 zBYTE        data = 0;
9 |  B" f, g* B5 F7 d3 A- q3 I& R  G. f
        if( exsound_select & 0x10 ) {
, Y* w) I6 T' Q$ s1 y                if( addr == 0x4800 ) {
5 p+ `. D; s0 o* n! [: j                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
( i2 v: |: ?2 A! p/ l" y. g, k3 s                }
8 |( }1 @1 Z% x+ @) g. a' M0 [        }! V9 Q" L0 ?9 a
        if( exsound_select & 0x04 ) {  u  Y, ?8 V+ C" @7 G. A0 F0 }
                if( addr >= 0x4040 && addr < 0x4100 ) {
- |! v, d! f8 x" j                        data = fds.SyncRead( addr );
  U$ i* s8 D+ S* G                }9 s6 R+ E* z4 \+ J; ?* S
        }
9 E6 O  }% q1 y& `  F        if( exsound_select & 0x08 ) {1 X4 X( g& K- T5 |& c
                if( addr >= 0x5000 && addr <= 0x5015 ) {
! [' }% y) l5 y& Z0 w' q- m8 x" j5 r+ R4 I                        data = mmc5.SyncRead( addr );
5 N/ Q' k! V" }: Q) S                }
4 I1 |, Z- x) b        }
( z. P. j% t; }& f
' L  u% y2 j# ?" E/ a3 o6 `3 f6 `        return        data;) E& f9 e  H' ], {2 d
}
$ b( ~" S( P, f$ J9 s, g! s4 y# l( C7 z0 G: q6 f2 Y# a. R
void        APU::ExWrite( WORD addr, BYTE data )
& F9 [$ r: \. X{
$ R7 d( j! R/ v: \5 U        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
, a/ A7 Z- u5 K- G# q
7 R9 s# ?; P; X: t        if( exsound_select & 0x04 ) {
/ _' l/ a" ^7 x& t; b0 s                if( addr >= 0x4040 && addr < 0x4100 ) {
1 S) E" _: ]8 c! e                        fds.SyncWrite( addr, data );
3 k# a8 Z! v. J7 [- ?- w                }4 |3 y6 E( s0 ~2 v3 y1 B
        }
' W3 l' P8 j- d) i4 Y6 j8 t5 z
( G" `1 N1 M: h+ @8 G3 O7 K- d        if( exsound_select & 0x08 ) {
7 }4 E  B" M; l% c/ R# K" i/ K6 v                if( addr >= 0x5000 && addr <= 0x5015 ) {
, m" E  l0 J& O2 L: C                        mmc5.SyncWrite( addr, data );6 f" ?, q, ?6 m' L, C8 P6 d9 R% G
                }& s6 P# J, V  q/ j) T( g( k
        }; a. q: X; ~  V/ L9 s, ~
}; f- z$ D$ |; m8 I1 Z. N, G
. J* y" c/ y! L' O
void        APU::Sync()3 h6 [) l2 t3 g
{
5 [% C! N0 C8 P}
0 Y7 s& s. z+ L# |* p$ s- m% F2 N9 f
void        APU::SyncDPCM( INT cycles )
+ _! y; W( ?( N/ K7 ~4 v{
  c5 |/ a6 L+ r) g& K        internal.Sync( cycles );
0 D# a: a3 h$ d
( C: `) h4 I" P/ s0 o' O        if( exsound_select & 0x04 ) {
. A; B0 a! ]7 v8 ?- E1 X8 U                fds.Sync( cycles );
& r1 x1 A0 T" ~' _        }# _& D) k9 G1 y* k" p) E
        if( exsound_select & 0x08 ) {
& t5 ]$ n/ h9 H                mmc5.Sync( cycles );
1 s1 y0 n4 C; [2 d6 x5 n        }5 {; O! H6 y/ M: s' }6 s
}- ^8 v. J( @- \- w4 _/ L0 \

( y, O# I, W5 S( t7 w8 B3 G) fvoid        APU::WriteProcess( WORD addr, BYTE data )) w$ G8 n8 w2 q8 h- Y3 J( J! B
{' R4 J; P: E, k: I/ C0 J* v  S
        // $4018偼VirtuaNES屌桳億乕僩
' N1 U4 v! h& i        if( addr >= 0x4000 && addr <= 0x401F ) {
8 R9 \! X, b" @7 [6 H9 u/ A1 U5 M                internal.Write( addr, data );
( k7 T# k: T) Z) \# ^        }' y! o2 ~* S5 D5 F" D
}
4 }2 R* u* H8 O& Q; ]$ }+ C" R& D. V2 ?! r9 k; h4 S
void        APU::WriteExProcess( WORD addr, BYTE data )
7 O0 A( T% s7 l{
3 J% \5 H# z, c* d# g- L        if( exsound_select & 0x01 ) {
/ w% z6 a0 O2 F- J- W                vrc6.Write( addr, data );
8 Y- [4 O$ }9 g# m7 p# l* ^        }
5 o* J8 q; V" E  g; L        if( exsound_select & 0x02 ) {
1 N8 a. a; _! m& H8 {! Y                vrc7.Write( addr, data );
0 e0 b$ }+ `; N) F# a* x7 e# ]  s3 o        }
8 Z. w  b* s; \' p' [5 f        if( exsound_select & 0x04 ) {, V( o6 H8 _/ k1 M6 c8 Z9 ~0 I
                fds.Write( addr, data );
$ K* ~6 w8 J2 Q0 [  g        }3 y/ k- |4 O7 n
        if( exsound_select & 0x08 ) {2 H- R7 c" l* y
                mmc5.Write( addr, data );
9 {2 F: `. j$ q- O7 R6 X        }2 t  C- f, r  H' m  f
        if( exsound_select & 0x10 ) {) J% K$ _; g' o" q
                if( addr == 0x0000 ) {, m0 q2 H2 n" W" ]
                        BYTE        dummy = n106.Read( addr );
7 }, O; D' x0 J) W- Z5 D, Y. P                } else {* t7 }0 D5 g' ~$ f
                        n106.Write( addr, data );# ?. J" J$ {) ^+ C) B6 `. Z
                }1 b; U; @) ]# M9 r7 g" n- ]# H
        }
: @9 o0 w1 N; C0 n3 e' f% ~        if( exsound_select & 0x20 ) {1 I4 E% u# a! I7 h) h) t
                fme7.Write( addr, data );; G( @& J; C4 d5 A0 c
        }
2 x& B* o1 Y- ]8 E3 g}
6 W( U" u" e" K7 H6 ?1 o: W. A4 |  A- X7 b" H
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )% ?6 n  u* i/ v: p% Q9 {
{- ]8 P: |; A/ E8 m6 m/ P# {
INT        nBits = Config.sound.nBits;, ^# }$ a$ M/ j
DWORD        dwLength = dwSize / (nBits/8);
: P2 u1 X7 w% {, EINT        output;" p& z, K1 L; X1 E
QUEUEDATA q;
, S# j/ M) i, r6 |6 eDWORD        writetime;
# b1 \8 D& m+ ~2 C" V0 e3 J( H" ~. e$ F1 E) w8 E* p8 }7 A3 c
LPSHORT        pSoundBuf = m_SoundBuffer;7 a! U& c9 [) l0 |
INT        nCcount = 0;0 e, E  I3 Z" h. }% F4 }# i
' Q& I% N% X2 D" x' a# p% o
INT        nFilterType = Config.sound.nFilterType;! K8 r* t* u: e8 l7 d. Z; F

9 c8 L4 T* |$ T" Z4 j% A" b        if( !Config.sound.bEnable ) {
* {/ W. @/ D+ C: E* l                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
) @$ ^! G% k# x8 S' ?                return;  C9 o0 F2 I* w1 ~
        }3 S  Q% _+ Q6 e6 S) C+ T$ D* F' j
7 ^5 f% C6 B# S# p) j
        // Volume setup* w2 g( m) ~$ P  g3 _! q1 s
        //  0:Master
6 w6 B, A' I1 \. O2 V8 K0 n        //  1:Rectangle 16 k7 L+ I1 C8 R4 q4 U# y5 L, M
        //  2:Rectangle 25 i7 |2 N% E/ X0 H% t
        //  3:Triangle) |5 R# v. W! H; B) L) a; t
        //  4:Noise4 n  A$ i' c& C/ Y% I! s
        //  5:DPCM
; @' q, @& p: ~- b" t  {        //  6:VRC6
* \2 d) _! r8 M- W5 J3 H        //  7:VRC7
7 s! _: d! n) O9 u" t        //  8:FDS
+ {) {) Q; ^6 _& J        //  9:MMC5
. M* g: Z1 b: w/ W: t8 Y& i7 ~9 L/ k5 O        // 10:N106
; o: M& ^( S9 v' |; w  T3 Q        // 11:FME71 r/ k: W& z8 d9 `
        INT        vol[24];
& v0 X# r, ^- c9 \/ b1 o7 g        BOOL*        bMute = m_bMute;
6 q3 d+ E3 m" E7 t( |        SHORT*        nVolume = Config.sound.nVolume;
( l' O- A' i/ v' J
% U$ _( S. N3 {7 Q        INT        nMasterVolume = bMute[0]?nVolume[0]:0;: m* u* L/ z: H% M
9 L" C" a7 R$ y/ [' e' o, I& ]# o
        // Internal
9 c% I, i# W$ S        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;8 X7 u8 h2 o( z
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;# I8 `; e2 V( _# ~4 W
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;5 R" i# g: a6 B
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
& [2 X0 b- y, J# S! C* A        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;4 D& O& k5 R5 L6 e  @  y

. S5 p. Z6 x( \" P$ H        // VRC6
; K% i) _; |8 T        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
9 O# o" W% Z0 d% x' [        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
& H; g, K5 s% O( P) N        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;! h9 M8 N, M4 y1 O& U

  u* a6 J: D  d4 J        // VRC7
& K/ P! t7 a/ S        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
+ }6 C. O" P& y% j6 h7 E1 D+ w3 L" f& y" O0 J' F! A; z; h4 a8 z
        // FDS
: M7 ?0 @! `' G        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
& w. o6 w8 E4 {
) s* p3 r. o( y" K* v; Z        // MMC5
% _4 c- u; \, ^* l! }4 o  _        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;& Z. W9 z' [$ N( A0 l$ k# h; S+ N
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;6 y, v+ H- u, _' i1 u- U
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
( m: [/ V8 b1 M* p( M2 M/ v' c" C
        // N106
0 ~! N+ j9 g' [! z: h* Z, ~; t        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& O9 N( `# q4 M3 I        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
! v( t$ k; {6 d1 }& L& S$ P$ A8 I        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
4 n. o! k8 h+ j- l: ?+ z# i        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
9 q. p" W6 c4 h  r, V5 x- T        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;/ u$ F& [) i6 ~5 O
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; A9 P  F6 \  U9 Z1 {7 R7 X
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
1 |" b; {6 b1 c! q        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
( r) O! H& S! J
/ s- p' G9 Z5 s. y9 n. n( L        // FME77 `& n1 B. B9 J; A& d
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
/ N; x; ]* J3 F: l        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
& i$ c9 p$ `3 a$ q3 r7 ^        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
# a& b7 e  T$ r& ?( M9 {/ l/ ^5 Z2 m4 Z, b: }! B
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
' |( u* X+ _; d+ V2 q) j        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
8 T  O% T0 D; ?( w! T+ _: n0 T0 j9 ?
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟6 i7 E5 F( n# ]& B0 m) V6 Q
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
0 f. y& z) `% C- O1 P: y0 S; m' ]                QueueFlush();
- J. _6 u  T) m2 T        }
! j, T% l9 w6 v! B# N# \- @8 t8 s2 i0 ~) L/ G1 z7 b
        while( dwLength-- ) {
( _" ?# C% ?$ h                writetime = (DWORD)elapsed_time;, K. `0 D9 z) A+ W! G
9 i: ^4 w; w# H# e: J. L/ N
                while( GetQueue( writetime, q ) ) {# y2 M1 E. J7 J7 i
                        WriteProcess( q.addr, q.data );: C8 t4 o3 U# \1 Q( F# r8 E) T
                }
( d! Z) X4 D, `# C" ?2 p, |) Z8 |1 J3 |- r) k2 M9 G
                while( GetExQueue( writetime, q ) ) {4 i% |# Y0 u0 @8 _/ _# V% s8 `
                        WriteExProcess( q.addr, q.data );! L/ P8 Y; Q4 J
                }2 u; _$ g# L- \4 l+ @/ {) }! e% ?

4 G; x1 I) Q7 u                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
; \/ |1 g7 }7 @$ g+ V                output = 0;
  Y0 j$ ^1 X% f( L4 k                output += internal.Process( 0 )*vol[0];
8 O) W0 Q; S6 v0 V( n9 j# E% w                output += internal.Process( 1 )*vol[1];
/ K6 I; M3 ?5 c2 j; `                output += internal.Process( 2 )*vol[2];# X& A  ~# N# H
                output += internal.Process( 3 )*vol[3];
% L' D! b& E) I/ S, z8 c( w4 R                output += internal.Process( 4 )*vol[4];
; O: h+ I2 |& h2 w6 }
; _$ t8 g( H1 p/ m+ f# P9 u) a' ?8 T                if( exsound_select & 0x01 ) {
: \2 h' _/ g4 J& T                        output += vrc6.Process( 0 )*vol[5];
1 B7 N+ P4 l- [& ^  Z) T7 s                        output += vrc6.Process( 1 )*vol[6];
/ K1 }0 j. |9 ]                        output += vrc6.Process( 2 )*vol[7];- ~  j3 a0 A5 s# K& ~% v* z  P
                }
. V4 d" h* q7 ?2 p. b                if( exsound_select & 0x02 ) {
9 B; H3 |& P* b5 A+ A9 X, s% K$ a                        output += vrc7.Process( 0 )*vol[8];
  d2 ^! ^9 w( R/ P- L3 R                }& h: q! Q- [$ e! B% ~! x3 ^( @( S. V
                if( exsound_select & 0x04 ) {  T* a. q' J% G. m3 o( P1 ^
                        output += fds.Process( 0 )*vol[9];
3 X2 Y1 z8 W! }* q: a% v9 J                }
& {) C) F! ?0 c  Y) s, X. W* D% O                if( exsound_select & 0x08 ) {4 g* H" u; _2 [. p; L
                        output += mmc5.Process( 0 )*vol[10];/ D0 N& H  X# O1 V' ?+ {
                        output += mmc5.Process( 1 )*vol[11];
! S  o0 D% D5 U4 A* c                        output += mmc5.Process( 2 )*vol[12];% p" V: Q- r8 k, ^# r
                }
3 |$ z; \" J* l) q- m9 ~                if( exsound_select & 0x10 ) {$ z1 n7 A/ D7 D+ C* c7 f7 b
                        output += n106.Process( 0 )*vol[13];
1 C+ i) A& u( e9 Y0 p; `                        output += n106.Process( 1 )*vol[14];: V% @' A" \& P2 C7 G& k) x
                        output += n106.Process( 2 )*vol[15];
; u. B7 R8 q5 ]/ n# P! u! _# h' F                        output += n106.Process( 3 )*vol[16];
( C# h+ d! n6 }% s; C$ x: g                        output += n106.Process( 4 )*vol[17];: H" Z7 v* B$ u0 r
                        output += n106.Process( 5 )*vol[18];) c: J( R3 j; o
                        output += n106.Process( 6 )*vol[19];- I3 E/ Q8 [) X7 N+ S) k0 S* P1 b" j. [$ h
                        output += n106.Process( 7 )*vol[20];; f0 w4 B" ~" D' }, d: d; F# S
                }
6 z2 k4 Y5 [6 }* `& }                if( exsound_select & 0x20 ) {
2 V& q/ l  ?) ^9 I3 |                        fme7.Process( 3 );        // Envelope & Noise: Y  r& D8 O6 y' Y! F; [: N- N! D% o
                        output += fme7.Process( 0 )*vol[21];
7 f6 p: ~! i3 \. K) C. }: n, w                        output += fme7.Process( 1 )*vol[22];9 M+ H# ^( N1 d# c1 w# i
                        output += fme7.Process( 2 )*vol[23];
$ C- e+ ^# \& ?) u' d1 u: l, ^# F$ Z                }
& ]* @2 o  Q' T- p
" y* Y& C! X& S& d7 U                output >>= 8;# o2 ?: X1 v/ R. Q+ V$ U' w% n; f

5 K$ e( w, r1 T/ y+ j                if( nFilterType == 1 ) {6 \  O( O6 I: G" i
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
8 [* I' |7 U8 m. n6 Y+ Y                        output = (lowpass_filter[0]+output)/2;
- a2 q" b' D7 c- X8 G( B                        lowpass_filter[0] = output;" A/ N2 ?2 ?' |8 T6 t- W$ _
                } else if( nFilterType == 2 ) {
& J! e" E: X0 l5 ]' s( d1 W                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
( k! n' H8 ]  h3 j                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;) @& n9 a7 l$ Q8 C* K# d1 l
                        lowpass_filter[1] = lowpass_filter[0];
6 Q1 T/ A7 ]( W                        lowpass_filter[0] = output;
7 n; B9 K2 t2 R8 _- z2 [2 U9 r                } else if( nFilterType == 3 ) {9 ]- x) a3 a3 o' O
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)- O: L8 F7 _) ?1 E; Y# B9 N5 V
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
, Q, {  K) t1 C: J+ z5 S* L                        lowpass_filter[2] = lowpass_filter[1];/ L6 F: Q) N, o
                        lowpass_filter[1] = lowpass_filter[0];
6 H2 e( Q; ?7 k6 d; c  X9 z                        lowpass_filter[0] = output;* _: d/ I% c- ^1 z5 [: A
                } else if( nFilterType == 4 ) {
: c! e2 O0 l8 c! [5 d" M/ M( M$ G                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)7 `  X9 l' q: a% F
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
% d4 @) {) _  {                        lowpass_filter[1] = lowpass_filter[0];
( K6 c2 w; }/ @, ^- K* \) Y& C+ b                        lowpass_filter[0] = output;5 u/ U7 \8 O5 N& ]6 Q$ k. s, O- i
                }
3 \9 t  M; p; Q% U
1 k: ?! f8 ~: Z3 U4 K" ]#if        0
1 b/ L3 j& }  |: R                // DC惉暘偺僇僢僩& ^. _! ?' A* ~) i$ a
                {1 H# E* l, `, N3 J9 i9 d0 q2 C
                static double ave = 0.0, max=0.0, min=0.0;+ p0 m5 t( \) Y2 r) c; G. o+ |
                double delta;
6 k2 |$ r! _+ V# C' x& T                delta = (max-min)/32768.0;
/ w+ e; g# c4 p/ e" ~  p$ c/ Z$ U' ^                max -= delta;
( h% t/ r5 e. Y$ t% U# l2 `                min += delta;
$ x7 Y: g" W7 q5 J; N                if( output > max ) max = output;
& E! A4 K3 a9 U                if( output < min ) min = output;
8 f5 p7 o  W) ]0 h- a, T                ave -= ave/1024.0;
: }6 M0 b# o$ b/ ^# E- m                ave += (max+min)/2048.0;1 ]) j6 x/ r) y: F/ U
                output -= (INT)ave;
, U# m) d0 w- y3 b& C; ?5 n                }
- F1 w$ S& ?4 V  m8 }4 _#endif
' _: G& o! `9 f0 C! H2 q0 a# k#if        1
: j" p& Z2 C: C                // DC惉暘偺僇僢僩(HPF TEST)" C( L9 G- Q- O- f
                {
9 ~& y' H" p7 B( v: ?) m//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
& a! K0 {; c, Y6 j0 m  e# R                static        double        cutofftemp = (2.0*3.141592653579*40.0);1 F* b4 L: M- [2 v" c" e
                double        cutoff = cutofftemp/(double)Config.sound.nRate;) O8 ]' N! b& g1 ~
                static        double        tmp = 0.0;$ O8 I! O5 f6 F( Z  P3 {
                double        in, out;1 n4 S( g8 z2 a/ Y1 P

% N! e3 t1 s6 H                in = (double)output;$ u; O2 o& \1 m1 V) {
                out = (in - tmp);
) L1 t+ N- M7 ^                tmp = tmp + cutoff * out;9 l' p8 X" e2 A7 ~. }
. V, e( b9 K& f2 o6 S" p
                output = (INT)out;
0 V5 i$ R$ T  |                }
( o: n7 S& [9 N* S3 Q& q#endif, Z9 E0 p) J; C: H2 U$ Y) h9 r
#if        08 p, K/ i# `6 D' x) K
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)- Z8 `6 \2 S3 {, P# u. F) k
                {: J8 s6 B" t0 w% C8 M
                INT        diff = abs(output-last_data);7 {- b+ B. q3 g) B0 V+ \& V9 y
                if( diff > 0x4000 ) {# U3 A6 p2 N8 H9 u
                        output /= 4;$ v6 B7 i% e, Y. v4 y4 g& N6 u* D
                } else # f: w$ U, H; r% A4 C% J
                if( diff > 0x3000 ) {. B9 ~. `, ]; p! X
                        output /= 3;2 b' N- c- x) x2 ]4 }. @
                } else
- M% @: s8 X# [! e9 E6 R5 Y                if( diff > 0x2000 ) {3 w$ P: u6 Y3 `7 P/ X+ o* s4 C7 @0 C
                        output /= 2;* X! m) b; G- x9 A/ h
                }
0 ?4 t2 G* h4 j/ M0 O' v4 C                last_data = output;2 P$ o' d, c* S
                }+ Q0 F. A4 j) i
#endif
2 t+ {+ m& x1 o' u! a1 W; }! G& I                // Limit  D$ `% }: W: B' s3 _
                if( output > 0x7FFF ) {
; f2 s+ v4 g9 N0 F                        output = 0x7FFF;: K- e0 X: s/ ?  A, S- g
                } else if( output < -0x8000 ) {( j2 E; A! J  j/ h. Y! W7 d! j7 \8 c  J
                        output = -0x8000;
* U7 A, s) v( J: T/ P+ r% V6 j2 I                }
# Y' H- ?/ ^1 O9 S. o
- W6 k/ D$ z% f+ B- L6 U4 w  @. \                if( nBits != 8 ) {
! R. a$ B& j0 ]8 z/ w                        *(SHORT*)lpBuffer = (SHORT)output;' |, ?6 x$ V4 m
                        lpBuffer += sizeof(SHORT);
9 ~0 P. u& {0 u5 Q) D/ T                } else {/ C- r# t$ `' u0 e. w! b
                        *lpBuffer++ = (output>>8)^0x80;/ [* ~8 L% @' _- P0 h. Q
                }4 ~/ }5 z/ i  {: x( t. o$ }
5 `* s- c) c2 s8 k8 E) Y7 z6 Q
                if( nCcount < 0x0100 )# V5 D) Q* E# I0 O  m/ f
                        pSoundBuf[nCcount++] = (SHORT)output;, |: r- a! P7 H
, v0 C0 A2 Y) L9 W$ W0 g
//                elapsedtime += cycle_rate;. g& s3 s/ b9 C5 }- B
                elapsed_time += cycle_rate;+ n5 d6 f' v/ \/ I
        }  X2 r" Y6 a& f. R4 I

( h7 U, a$ S1 D#if        1
1 g8 j2 a2 s# f) \% V! }( _/ h        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
. j8 z  ~. t3 N& p2 u6 c                elapsed_time = nes->cpu->GetTotalCycles();9 m0 v" t/ g8 g3 Y# \
        }+ q7 C0 X2 V: k; F$ |
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {) ~0 i( B4 j; a% L9 q# r# T
                elapsed_time = nes->cpu->GetTotalCycles();- x. V9 E& Q# T8 R. W+ d
        }
6 P4 I; Z4 l. [#else* C. e2 q7 c4 L9 U
        elapsed_time = nes->cpu->GetTotalCycles();
: F% U' J  l/ q$ M1 O3 G#endif* R4 N4 R: f% J8 j" H
}* c# b6 k& C/ G+ M' I# Z
" E1 m5 T+ c, Q
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)8 c; c, G' z4 V3 b
INT        APU::GetChannelFrequency( INT no )& M# T  b) i  x
{
# {" k& ?, X" `; k! w8 f        if( !m_bMute[0] )( Z! A& g; w$ l- [# Z- o
                return        0;" L+ r; M% D7 F8 K: S! ?9 m. k
& B7 q/ U' L; T( A: p  _
        // Internal
7 a: ?0 {  L! {& {0 L        if( no < 5 ) {
, F- k* N+ E. L( t                return        m_bMute[no+1]?internal.GetFreq( no ):0;
2 M; e2 B2 H0 b4 O' u) S        }
& ]9 K% Q& Z, [3 V; x( h! h        // VRC6
: f& ]; T( b( n4 P! O        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
% b+ `+ i8 J: l3 j, H: X                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
2 {3 L2 `0 @+ i' R  x/ q5 a) M        }& t+ n) g. x2 B9 T5 }
        // FDS- s2 B; {. @: [/ R3 h7 D7 L6 d+ F
        if( (exsound_select & 0x04) && no == 0x300 ) {9 e. `8 w7 ]0 k: Y0 W8 c9 M) s
                return        m_bMute[6]?fds.GetFreq( 0 ):0;& `8 C0 D0 E7 Z6 M0 {7 W, e
        }+ g, j" j/ l5 |, {$ Y( K
        // MMC5
' A9 r( M1 u3 [& Y+ a        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
+ O/ O; N: y! i- _0 Y                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
4 A  P1 G1 m6 K* o# {        }/ T5 F' J* ~& S* z
        // N106  ]3 U; ]5 k. I% F& w
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
$ B8 @, @1 j/ x4 r6 X! s                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;% s* s0 w3 S* `9 h# F+ v5 Z
        }
5 v% l- V; y( S& O        // FME7
: R7 V3 A: `, w( i" J5 Y4 k2 j        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {1 I  P" X4 ]5 R+ X" y
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
8 U$ t- {9 u% s+ ~" }% e+ |; Y        }2 I( ~1 }  o, z' A/ T9 p+ n+ x
        // VRC7
" ?2 s# l2 R* T' m        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
8 P. Z* ?  ]# [, O                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
$ N7 v) `9 o1 O        }
) a3 z. A1 u, w$ r6 {1 p        return        0;) d/ ^. l6 k* m5 J3 ~! s/ `
}" N; o4 \" Z% A9 k& Y
  k7 L; r9 b* R7 `9 x
// State Save/Load
3 P" J% N" w$ k/ b- lvoid        APU::SaveState( LPBYTE p )
! y6 u' s0 o& Y- Z1 j! z4 U{
- J8 k' ~5 v* q6 |, P1 D3 s#ifdef        _DEBUG$ \) N$ D3 B2 |8 W7 R2 f  ?6 [
LPBYTE        pold = p;1 }3 @5 u! y& B; M
#endif, T9 x7 r  \5 [7 J
1 g( A& r' c: T
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
: x$ z2 q, D$ j% o        QueueFlush();6 [3 Z3 ?8 @! z* v3 a$ g

: B3 b+ q9 T, a1 ]3 C$ E        internal.SaveState( p );
- Q% X% ~, i) ^. ?1 S        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding6 ?5 u( [  T1 X' ^% Z
) K) t- @3 g3 X( A* [
        // VRC6
) ]5 T7 C7 t' s2 O" ~5 F1 b        if( exsound_select & 0x01 ) {/ I( b9 o6 H" t8 }' l# p
                vrc6.SaveState( p );
7 R* s% k2 K; c/ \9 l                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding+ q2 Y2 ^0 R( m& n# h! I' i
        }
+ }+ X5 t, |3 e: I/ k( u        // VRC7 (not support): c) E5 r1 B4 S. |
        if( exsound_select & 0x02 ) {( W4 o. R4 O3 [/ c% L9 {) A* R/ c
                vrc7.SaveState( p );
2 P1 |  m% w) M( z$ L( j2 a' l# A                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
* v4 \' l$ Q, ^, V8 a4 t9 S        }
/ E- F9 v, l1 w: I        // FDS# R& S; G6 o0 ?& S
        if( exsound_select & 0x04 ) {
4 L+ p1 _) W; |+ y. t7 W                fds.SaveState( p );5 G' b6 J# t" _
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding2 j  _- Z" B& r
        }% O' z  J- |& {
        // MMC5+ z" y( \1 y- K7 H( h# L1 g8 [
        if( exsound_select & 0x08 ) {! t' |' E, h. `( X" A: m
                mmc5.SaveState( p );6 @" I5 G7 m* T: u7 I) m; q, o0 a
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding- N7 |0 u8 `; `  _
        }
4 D4 `4 K3 L6 x  w        // N106) M9 x8 o" F3 f+ A7 M! M5 \
        if( exsound_select & 0x10 ) {, a3 B* f; Y/ C2 M1 J
                n106.SaveState( p );
! J* |3 b+ `% [& C6 D8 U                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding& W, w3 Z) J2 i6 P- Z
        }7 H( W5 `, }4 U6 N
        // FME7
" N4 y8 D: f3 I8 g: f        if( exsound_select & 0x20 ) {: ]6 T# @) U  ~9 ^3 I, t* G- `
                fme7.SaveState( p );
  J4 |& X' t( G3 _# f% _5 I% g                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding2 d0 b& |2 O+ \. f# l
        }+ j; y/ x( S0 h7 a

) z! Y1 M6 j0 `6 M7 L# Z#ifdef        _DEBUG8 k, i6 @# W5 M9 |, \4 t
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );7 U% g5 Z5 I: S
#endif4 b" F4 K; Z1 x# s$ ~* o
}9 M; h, J" J3 Q( M+ S" S5 c* d
/ @) s/ d- _4 I; \: y( g- b
void        APU::LoadState( LPBYTE p )$ d* h; F! g+ L- h# F" b
{
9 v& k# }* s4 C3 s1 D        // 帪娫幉傪摨婜偝偣傞堊偵徚偡3 _' s' f2 p6 A( r+ s, M
        QueueClear();) s! {& R. o3 Q& O; w* u6 t. z
) R0 [+ Q4 }) b" O
        internal.LoadState( p );# _( b3 |9 c5 c& v
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding. o, i4 @- `+ g. f# A' O: @
* ~- u( b+ H8 {' j0 I
        // VRC6
9 O5 f' T6 J8 ?0 c1 m) a6 v        if( exsound_select & 0x01 ) {
: }5 |/ \1 C- d# n                vrc6.LoadState( p );% k6 m: O2 S. I
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
3 N$ D+ n4 ?4 v/ T. j1 g        }7 r* z8 W7 `' b$ K2 \3 C4 ^- n
        // VRC7 (not support)1 p6 G/ g* h* N2 i1 s" Z
        if( exsound_select & 0x02 ) {
) p7 b% P' }, p' e. T0 @                vrc7.LoadState( p );  m  v; ]+ z* C8 Q  H4 B
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
6 z% F) ^& \; C' d/ G  y        }
, m2 J) `+ H, K! C        // FDS6 e( H% p  q1 K/ B3 ?
        if( exsound_select & 0x04 ) {) n7 V- b! J1 M0 [. z
                fds.LoadState( p );  q! W* _9 ^# W* w
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding2 t$ T* H4 a9 Q' V- i2 K2 @( w
        }
; ]1 X, e0 g$ i4 {8 }        // MMC5% ~$ U7 _/ }& X* j2 |$ d$ W5 Y# ?
        if( exsound_select & 0x08 ) {
8 q4 e1 d0 ~3 ~8 @                mmc5.LoadState( p );
5 Y9 H* a3 `' V. F# S8 w5 p% N                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
1 b- |2 s* A" d3 K! X# B3 C        }/ G& F; Z! e$ E) f  `5 N
        // N106
0 {' g  `9 U* ]# F2 U        if( exsound_select & 0x10 ) {
  G( a# J, `$ Q; A                n106.LoadState( p );
% m% Q* n2 C1 D: {                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
/ k- a8 W+ K4 L: `0 `6 W% {; w' a        }
% m4 A5 `3 \# R1 a1 t        // FME77 O$ `  K. B9 {+ e/ @! N
        if( exsound_select & 0x20 ) {
3 @. A8 Z, Y* P# J0 w; ]! @" \$ R                fme7.LoadState( p );
& N& {, y; @* b7 x4 J& j/ ?                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
& n. [' }4 r7 c9 ?6 b8 f        }; X4 k1 V8 s& K$ a7 {+ d9 t' G
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 , k$ k" e) d( j$ S/ z0 p1 y
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
+ P) e2 F1 E# a' N2 f感激不尽~~
; N4 ^" u; P1 r1 a
恩 我對模擬器不是很有研究,
1 Y) p( \( t" Q# {& c  @雖然要了解源碼內容,可能不是很困難,
; c+ B/ |, j) B/ I1 O" `不過還是要花時間,個人目前蠻忙碌的。
* Q# t8 U/ @( ?7 e8 Y; A1 C% i  V7 {) _4 j% R
給你一個朋友的MSN,你可以跟他討論看看,
. \6 J- n) e7 F3 H" j9 @; v他本身是程式設計師,也對FC模擬器很有興趣。
( k; j' u5 ?/ h3 o$ q. H9 ?3 k, {# A! K
MSN我就PM到你的信箱了。
9 G6 \; U4 R5 b8 C% Q. G3 S& I: A
0 Q  Q9 w! M  y# D$ p; |6 n3 e希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 3 ^. \* {& q# w& R0 A9 t5 R
呵…… 谢过团长大人~~
: p( l6 x1 T' |! r+ z, Y7 b

8 Y1 e8 u1 i) a+ K% }  r1 A哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 . c; D7 w+ F6 T. P9 _+ x
团长的朋友都是神,那团长就是神的boss。

/ \$ m& e+ H& h+ R8 N哈 不敢當,我只是個平凡人,
$ U3 G9 _. E: |8 C" Y要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
( i9 ~4 n* E" ]5 h' r1 Q# NZYH; I8 n" F% i2 A
QQ:414734306
( F- X% `5 U5 s9 H, kMail:zyh-01@126.com
0 a: O1 m$ A' \1 y# D+ d8 O2 S
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 ; ^4 O7 ?# I& b; M) A
再次对团长大人和悠悠哥的无私帮助表示感谢~~

- w) k1 T% j8 |) B+ N1 p: `( R9 t不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-11-30 21:30 , Processed in 1.076172 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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