EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。6 s' v* y$ Q4 r
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
) [: X1 B4 @1 o0 w6 V3 f9 ?- _* ~7 ?这里有相应的模拟器源码,就当送给大侠了~~
( P9 H/ i. j+ T3 Q% Bhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
% E: R& O1 _- s: {: y能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
3 Y, k0 m# W2 V7 G楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
) n& d& A* K: o6 I. B% S2 [" [这里有相应的模拟器源码,就当送给大侠 ...
- B$ W1 P  X" G8 I# k
聲音部分(Audoi Process Unit = APU):: W$ @# Q7 l  z
.\NES\APU.cpp3 U1 D6 _- }6 w; _$ W- Y6 P. o
.\NES\APU.h% @" @' C' {& C* R/ X1 d
! ]/ a3 B& Q! Q. ~! B4 F
5 w/ g/ c2 Y" |: C3 b
影像處理部份(Picture Processing Unit = PPU):' v+ j4 r7 `5 R3 c. v8 |. q7 u
.\NES\PPU.cpp
# M. i9 ^8 {, A8 O.\NES\PPU.h
  T- L0 K* |& i/ V' C, C2 R9 ?3 s* H+ v3 Q
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:+ E2 y+ r9 Y% j, A  X
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
5 `2 @5 ~: L1 i6 ~& [* J/ I//////////////////////////////////////////////////////////////////////////1 d+ v2 v2 R( M1 q. D7 `1 n; v
//                                                                      //
5 T. y; p& _% X  V0 _//      NES APU core                                                    //( ~7 V; N3 M: z  O8 r, y+ |" u
//                                                           Norix      //
- d, ^  \" G! J7 ?, X8 _* @//                                               written     2002/06/27 //
' q+ k' m3 I7 p+ n//                                               last modify ----/--/-- //
0 a  X0 @1 A0 F5 Z. I//////////////////////////////////////////////////////////////////////////
# q# r$ W) B5 ?#include "DebugOut.h"+ m9 d4 H& C- A9 B7 z- H8 w  C
#include "App.h"
8 m4 W: L7 z  ?) X#include "Config.h"/ W% t2 ?2 K6 q
) z+ r  C/ _% j( E4 ~
#include "nes.h"
5 _' n% V1 C7 s5 e0 _* f; R( c( @4 Y#include "mmu.h"
) X  t0 V: ?" r% Z1 s& ]#include "cpu.h"
4 _' o2 k1 i) W; E8 G5 x+ D5 {#include "ppu.h"
4 \4 K5 R$ t$ ^0 W7 s8 N% q: s#include "rom.h"
7 z% v) `, m9 J/ Z. {#include "apu.h"
! ]% x" V5 j( D8 k
9 v: R" p1 b2 K6 C  w// Volume adjust7 Y% e0 ~# F, n- n$ x4 V
// Internal sounds
, a! r# o0 r) q- Z8 p#define        RECTANGLE_VOL        (0x0F0)
( H3 W4 W6 C7 }#define        TRIANGLE_VOL        (0x130)
) t3 m9 M: z' T/ R" b$ ^#define        NOISE_VOL        (0x0C0)  _: S+ `% K/ n+ N5 ^. z* Y9 k
#define        DPCM_VOL        (0x0F0): U) _$ j+ Q3 i4 k% e
// Extra sounds8 `4 P. t; A# E  [
#define        VRC6_VOL        (0x0F0)& p/ c6 X6 k. f0 b
#define        VRC7_VOL        (0x130)+ ^! g& m6 p) M$ l* ?
#define        FDS_VOL                (0x0F0)0 E' l8 q+ i, y1 d. `
#define        MMC5_VOL        (0x0F0)8 }5 W7 P$ ~3 t$ d; r, \
#define        N106_VOL        (0x088)7 i; E+ l% x2 Y$ \8 i. a3 Z5 _
#define        FME7_VOL        (0x130)
' T' S! `" P5 ]7 S; G9 |+ S6 z8 H+ @
APU::APU( NES* parent ); z* i: x( E4 S+ A1 }8 O
{- e5 G' h1 d- }( _" t: x
        exsound_select = 0;- f9 T8 x$ z; f5 T! k& d
' T4 Q% ]$ K+ ~' a3 f; v4 V
        nes = parent;, T: l  G3 j& _9 {
        internal.SetParent( parent );, y: d# P, V  [
8 [. m+ b& H+ ^' Z1 J2 v3 Z
        last_data = last_diff = 0;3 C* }/ D1 t7 g8 Q  P
8 D+ u$ O8 H( W$ [) e( O" D
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );* b4 ?4 t8 t' R7 D: {

  s6 y2 E, Z% @  U        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
2 Y, E- {4 i. X3 q$ D+ Y3 K% v        ZEROMEMORY( &queue, sizeof(queue) );
* a% p9 t1 \- y+ H        ZEROMEMORY( &exqueue, sizeof(exqueue) );2 ^; C7 N7 G) j$ I
6 C& l3 T9 C* j
        for( INT i = 0; i < 16; i++ ) {
0 {0 b+ g7 D, @3 x, ]* |( m' t- c                m_bMute = TRUE;
+ x3 N! @1 Y3 B2 ?2 M        }
. L2 B; L5 I9 U2 H6 e}
# }6 _, p1 U5 w* ?+ Q  t% a8 |( _1 n9 R9 _2 }
APU::~APU()4 h$ a+ a( |# {( B
{
9 U' M# t/ t5 |! b6 a  j}
) o$ i. y. {" P2 T, d! [. F6 {
# J9 P1 |) I3 P2 Z% z& `' t/ Mvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )- v) S3 H7 O# E  S4 m
{
! j  Y$ u# Y1 S5 N' W$ {' u& j        queue.data[queue.wrptr].time = writetime;5 ?7 x/ V% r' b- n: [, B/ ]/ `
        queue.data[queue.wrptr].addr = addr;
+ }& w% d3 y& C% |        queue.data[queue.wrptr].data = data;
* j. e: A- j7 t8 k1 f( G! }9 b3 P        queue.wrptr++;
* ?2 n& ~% }/ \% Q% [, f# E        queue.wrptr&=QUEUE_LENGTH-1;
( i( P5 M: w' `        if( queue.wrptr == queue.rdptr ) {
9 O4 Y, w' F7 E4 I% q                DEBUGOUT( "queue overflow.\n" );. t: G9 l3 D' Q8 s' I
        }0 L7 I2 n' B+ V
}
4 o' b( h, f9 |2 Q# W0 R7 d$ }: u. b
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
  ~) K4 K( Z( o/ }! _' T( Z- P{' R& h) C9 J) w
        if( queue.wrptr == queue.rdptr ) {; O" w) S" R1 |; P# h
                return        FALSE;
- x3 f  j8 O) P  }+ @, F2 ]+ [        }, g+ u) O% \" a
        if( queue.data[queue.rdptr].time <= writetime ) {4 r' g0 W. z9 D. y
                ret = queue.data[queue.rdptr];
; [' r" H- {3 S* r* ^  h' x                queue.rdptr++;
0 C8 J1 P6 N; d6 @                queue.rdptr&=QUEUE_LENGTH-1;9 s# ?* }& \* ?; m7 [- j4 @
                return        TRUE;9 ~/ q! w* I% Q0 T  ?" @
        }
2 \! O0 D* T/ z* t3 {1 `" I        return        FALSE;% \, [- i3 j) L% |
}  R) d- o) C' U8 l

. c+ Y# \! f- n! {. E1 nvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )9 ]/ A. m* R6 \# T: ~8 [
{
1 U' e' Z3 u5 @8 `5 Y% }        exqueue.data[exqueue.wrptr].time = writetime;! x( j/ e, X* I- _  R: m
        exqueue.data[exqueue.wrptr].addr = addr;
, G- F" R0 N' E# }/ [/ I6 {( N2 T+ }        exqueue.data[exqueue.wrptr].data = data;
- M) G8 r" H; v5 v, `; D8 K, v1 I        exqueue.wrptr++;# v) s8 r$ l7 R# w- D& E
        exqueue.wrptr&=QUEUE_LENGTH-1;/ x$ j3 _) A, v6 f! X
        if( exqueue.wrptr == exqueue.rdptr ) {; L9 U/ }. K% d( t' H
                DEBUGOUT( "exqueue overflow.\n" );) g2 T! s  ~# r# {' l
        }5 i+ V7 R! ?- N) N$ z; ]0 O3 B9 Q0 w
}
8 n$ O' X$ J+ i6 c2 O* [: X" B* a) t2 U2 E
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
4 N' T5 y( A8 E2 P' |  G{. m+ J9 f' b: P* I
        if( exqueue.wrptr == exqueue.rdptr ) {; l' O$ M" J' I1 n: d# S
                return        FALSE;8 X) d$ l  R6 N0 b( \2 u& V
        }
  F% t7 j' h7 A+ s8 }" v* y        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
7 C6 s" \* E5 Q! F' a, f                ret = exqueue.data[exqueue.rdptr];* W- s/ g5 g) D0 ]. j9 p
                exqueue.rdptr++;# u8 A+ O+ M/ L0 g8 m1 C5 V
                exqueue.rdptr&=QUEUE_LENGTH-1;: w# \% i" ?7 x' i  M' Q' w6 X& G9 ^
                return        TRUE;
/ B, N" |6 K3 u8 P$ G        }
/ H2 E3 i8 M: Q& }& ?        return        FALSE;: y( q1 s5 T" d2 [5 f8 ^: z
}$ h. i( O& a# B+ M( Z7 o

3 J6 A( _( Z4 K6 n! M9 H+ I, V. Yvoid        APU::QueueClear()
8 j2 |9 P7 Q( ]( W; k: N{: Z: c, F3 y" M; H% i
        ZEROMEMORY( &queue, sizeof(queue) );
( e2 d! n& _9 `& L        ZEROMEMORY( &exqueue, sizeof(exqueue) );) i$ Q0 J6 Z0 q+ {3 J  H- F% z
}; k. V: |5 ^9 w# g
2 x/ A$ ]) a0 P" W, b" O/ c
void        APU::QueueFlush()
8 S# @* G: g  }( Z6 _; y{- S9 i, D6 F/ v  r
        while( queue.wrptr != queue.rdptr ) {
( N% A8 g' {- B: B, B9 m9 C                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
& h1 k* I7 ^! F3 Q6 Z. N1 u( f                queue.rdptr++;
. }. _& x4 A8 W$ @9 ?3 c                queue.rdptr&=QUEUE_LENGTH-1;
3 c  T' U/ d# e7 n8 I' u        }- `& {4 y, h9 h9 [

2 G- k5 E% w$ J% d) l$ l% Y        while( exqueue.wrptr != exqueue.rdptr ) {
5 Y% H' t, U- x" v$ V) W' R                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
3 O7 T* `6 |6 ]                exqueue.rdptr++;5 r- U( O0 w# p% a3 \9 M
                exqueue.rdptr&=QUEUE_LENGTH-1;$ U% n$ F( o& O' r$ U# W2 U. b; Z& l
        }
8 h- |! Q2 N! [, ^}/ ]& x  i) a! L

% t! p3 \5 U& \; n% wvoid        APU::SoundSetup()
, n3 C' r& Z  I7 q6 f; X{( A% U7 e- x5 F; `8 m$ }0 t
        FLOAT        fClock = nes->nescfg->CpuClock;5 T) A4 r( v7 U
        INT        nRate = (INT)Config.sound.nRate;
/ c, Q4 ~8 E, L, G" l8 Q        internal.Setup( fClock, nRate );6 r3 y* H) w0 v* ~) k
        vrc6.Setup( fClock, nRate );6 [4 q- z8 G, }
        vrc7.Setup( fClock, nRate );
! q/ C8 M+ M3 n# z2 T. @        mmc5.Setup( fClock, nRate );* {+ M8 f6 m0 S$ E* T" t
        fds.Setup ( fClock, nRate );
7 {' [; z) D' ^. ~" {( G' {$ n, Z" V% V6 @        n106.Setup( fClock, nRate );
: E0 z! g: K4 o8 w& A        fme7.Setup( fClock, nRate );8 r) z1 f4 n: w, Y/ J: B- `& U
}
: S8 D. p$ U6 H6 w9 o
# x' a8 o' x- K1 u, U$ M- Fvoid        APU::Reset()) R, J. w& E, x4 J5 R1 {8 h
{! W0 b( x1 c7 o- A8 Z
        ZEROMEMORY( &queue, sizeof(queue) );
% m5 @. o( S$ N        ZEROMEMORY( &exqueue, sizeof(exqueue) );' v  i+ R$ f+ ]
* E+ _$ j1 {$ U; g
        elapsed_time = 0;
6 L# X! ?0 u+ R. \  j  R8 Z, m; m, X& E+ e3 g3 w6 h: M0 h
        FLOAT        fClock = nes->nescfg->CpuClock;  P' j, M, Y1 ?" M: M
        INT        nRate = (INT)Config.sound.nRate;
8 ?8 \  E9 D5 [6 ?; _        internal.Reset( fClock, nRate );
6 X. G* n7 }6 t# H  r- j; o        vrc6.Reset( fClock, nRate );9 B7 |# P7 P# I
        vrc7.Reset( fClock, nRate );. s! j8 p5 Y) B1 y$ F* z
        mmc5.Reset( fClock, nRate );
0 @$ }* g) `* A# \7 y7 c6 I: g        fds.Reset ( fClock, nRate );
7 C  l0 o, r7 C! M- T5 n: [. `        n106.Reset( fClock, nRate );
8 q7 B  e- H) Q% H        fme7.Reset( fClock, nRate );- a7 _7 ]* i! W! A  \5 U7 @

+ y4 K( Q5 Z4 b' p        SoundSetup();. p, Z9 C* J' u) ^
}
2 `4 r' D! {, N' C
: d/ Q3 o5 Z! @% P' i$ H/ O+ qvoid        APU::SelectExSound( BYTE data ). w  d) {) I! F0 r
{
; g% D) z2 ^, B4 E: L  I5 D        exsound_select = data;
) X  b6 }8 _, W' ^9 i# X4 ^9 }}
( a8 D9 u- T, G6 F7 r3 |' Q, w8 ]1 w5 q0 c  O! I
BYTE        APU::Read( WORD addr )
- J- f# K$ o: o, P- X+ s{' l  Z6 m9 Y) ?* j5 G3 F/ h
        return        internal.SyncRead( addr );
3 h) G9 F% O& X# T# }}6 u: Q" {" m4 M7 l6 G

0 Y( O2 N" m$ t7 j1 qvoid        APU::Write( WORD addr, BYTE data )( B* R4 B0 [( j4 _1 i
{2 O/ h& C- }/ o" `' O
        // $4018偼VirtuaNES屌桳億乕僩2 V! i  L! V7 B4 t/ @; V3 U
        if( addr >= 0x4000 && addr <= 0x401F ) {% V- }& j$ y8 e8 ^
                internal.SyncWrite( addr, data );
* D1 {5 S3 H6 |1 G" F- Q                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
7 U: U, d0 r: Y) b7 J        }! B" p7 |! q# [3 x
}% N% K0 t* c0 `; B0 l' {4 F+ y

1 F1 [' g3 _# h) O( dBYTE        APU::ExRead( WORD addr )9 [0 J! a: u2 \( L
{
9 |" l" a, i3 q5 _, e3 P3 h0 `! rBYTE        data = 0;/ F8 t+ R7 X) w  E3 N  z
2 L+ E8 }2 @) Q, A0 B7 ^) [
        if( exsound_select & 0x10 ) {
6 i2 {+ P% V& I2 @                if( addr == 0x4800 ) {
. L2 l& O& J' r                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );% A+ U$ }) u/ V4 b* S5 z
                }
, D7 Z& }: ~5 o7 q        }
& L1 `& e1 p! d+ p        if( exsound_select & 0x04 ) {) U% q  s: l% B
                if( addr >= 0x4040 && addr < 0x4100 ) {
: D: i' \0 i& ~" M9 [                        data = fds.SyncRead( addr );
8 [* y8 y# m7 y: y& K                }1 j( i+ }! r% u4 j: r
        }" W1 A: b4 \- G5 b, w
        if( exsound_select & 0x08 ) {. d; z* @2 m+ |
                if( addr >= 0x5000 && addr <= 0x5015 ) {9 \1 [" ?- ^9 U; A
                        data = mmc5.SyncRead( addr );
) C) u7 M% I! I) B                }
. F' N6 l4 m* A0 y' S( D: W8 w( \# H        }
# I' l. |8 _1 Q  J0 D6 h) b: f. k( r9 }
        return        data;' q( |2 e) q% H
}% _7 j5 k& j& r* t

! a1 W( `9 E& J( k% wvoid        APU::ExWrite( WORD addr, BYTE data )3 K! i3 ?  p1 j9 |
{2 v7 V4 ~: I* ^* v
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );. ?5 y: Q& m8 V) v5 |0 L$ Q
2 Y" u( V/ Z$ Y
        if( exsound_select & 0x04 ) {, b% _1 U  \$ r( f% k' B
                if( addr >= 0x4040 && addr < 0x4100 ) {
5 F6 H: X2 |. J                        fds.SyncWrite( addr, data );. A' V& y. p$ f
                }& S, v( y* i. N. A- I4 n- d5 q
        }
, j9 Q! z3 S( h) W
" f! G! t3 H2 d$ x- X( }        if( exsound_select & 0x08 ) {( v# P. U, s0 l6 H5 i+ m3 P
                if( addr >= 0x5000 && addr <= 0x5015 ) {% f) H. M4 |; i& \
                        mmc5.SyncWrite( addr, data );
+ }4 t( _, |* y9 p                }
' ]9 D( E6 m1 ^) `* N: c* v        }
/ I# L! U. _" W/ Z/ Y}2 D, ~/ `5 K0 h
3 m: S$ C" _2 @- g) o% _  J
void        APU::Sync()
+ g0 E/ B* Z7 J, ?' g; A{& @& X- C0 y1 `- ?& n8 ^# g
}
5 R4 z1 P  X% h# n# r
0 R  ^3 E/ ~( r5 o* I! jvoid        APU::SyncDPCM( INT cycles )" n4 A  w9 Q# G/ \0 r& z
{
6 f  E) a. C% L        internal.Sync( cycles );( ^( _' i- ~1 ~

/ o, _  f1 I5 D1 |        if( exsound_select & 0x04 ) {
2 T1 d- d& {$ I: f                fds.Sync( cycles );
% _3 X! m$ t$ G; K. C! U: l! z  t        }% H$ x9 w2 T! {6 l. d
        if( exsound_select & 0x08 ) {
, a" M5 `# P) {" S5 C                mmc5.Sync( cycles );
- c- S9 k8 y( Y, x        }( H7 A* ]1 K. H# S) w
}
2 K7 u. Y0 F% |: F# e9 A
% X! k+ v5 M% a3 Fvoid        APU::WriteProcess( WORD addr, BYTE data ): r! {; i0 b$ _  T" s
{! x# _7 E! I3 g  t$ B  b
        // $4018偼VirtuaNES屌桳億乕僩) G1 `8 E: o0 B" `- Y& y
        if( addr >= 0x4000 && addr <= 0x401F ) {
! E- n5 w, E; X6 {2 H                internal.Write( addr, data );7 }" p# b2 j4 l& _
        }6 l  `( o, L, k, E
}& X+ r7 c3 ~/ i
9 z7 L9 K) N7 R  J
void        APU::WriteExProcess( WORD addr, BYTE data )
. M* T3 ?# q4 n4 o{, `( G+ \' E: k6 ~' n" Y- |8 z
        if( exsound_select & 0x01 ) {/ c' _3 P) {% j/ J, V. j
                vrc6.Write( addr, data );1 c9 W' }6 H4 v# M
        }4 `! _9 v1 z3 [+ O- y: z
        if( exsound_select & 0x02 ) {( z5 V; q8 F$ j: p
                vrc7.Write( addr, data );
, F+ N+ c3 C4 D# [: }7 D        }
6 J7 x" y( [8 f8 T8 d* }        if( exsound_select & 0x04 ) {( o: p/ K$ j* o+ d6 h
                fds.Write( addr, data );
0 D+ L8 G8 c1 e2 I, h) \/ X        }0 C' a* S# t9 F; x+ @, U- r9 I6 s
        if( exsound_select & 0x08 ) {
& _" j; C5 A6 f6 S7 }7 C1 z' \; u                mmc5.Write( addr, data );
( v0 u/ a* ^' O, c        }, q/ r2 Y+ S& r6 g6 Y
        if( exsound_select & 0x10 ) {
3 I; p! T- w8 m" _/ O* T4 k                if( addr == 0x0000 ) {4 k: w. N$ Q0 [, @. }
                        BYTE        dummy = n106.Read( addr );! r+ P  }8 X( g6 k% N
                } else {
0 i( E) O7 Z3 s, o: C                        n106.Write( addr, data );
) K- U$ I* g0 A                }$ z& e; l( M( l* x
        }
. m# o- g. C, R3 `5 v        if( exsound_select & 0x20 ) {
0 q2 N8 T9 P4 J. B# [3 w                fme7.Write( addr, data );
4 Z( C6 F9 b* Y- ~8 R5 K' G. y) V) d        }
7 q2 D7 C0 ^+ R2 P, v1 H}1 n- P0 R7 @, O% Y1 c
6 w% L0 z7 h) i; ~5 K; `; r6 p
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )2 B2 e. c8 q0 y
{* S( I6 S/ ~! i& y- O. Y
INT        nBits = Config.sound.nBits;# [  Z( o% G4 t
DWORD        dwLength = dwSize / (nBits/8);3 i) e; f9 @& M) m3 t  Z
INT        output;
" b' O* L& A, r# h2 {QUEUEDATA q;( v2 e. W" Q4 a, n
DWORD        writetime;5 F1 L% I5 B/ S$ l  ?2 `' F

8 w5 @$ n. Q* F. aLPSHORT        pSoundBuf = m_SoundBuffer;
. z# e$ X; `6 ], _% @INT        nCcount = 0;
# _( g! W, y+ |" ~
4 C6 g5 x% x% @& S! NINT        nFilterType = Config.sound.nFilterType;6 s. ?& p+ r$ `$ Y9 C

. [: Z8 q( O! d7 ^9 ?- h        if( !Config.sound.bEnable ) {9 ?8 C2 P' d0 O' U2 w' M
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );- ^8 N& F& l) [' |( `  \' t
                return;; ?$ V  d7 ?# v) k% c; J
        }
* @& m, [1 V# q- D2 V
# {5 n  U0 g+ m        // Volume setup
+ i7 a1 {9 _+ `. m        //  0:Master9 I/ s" `4 F! |7 a: n( U) `
        //  1:Rectangle 1
+ ]; k, ^3 W3 V5 T! Q0 z  N        //  2:Rectangle 2
/ _- ]+ ]6 j4 n9 g        //  3:Triangle
! m, I% W9 i) O3 |5 T# f% Z        //  4:Noise
4 T3 X) b% s9 S9 j, I& _8 Y        //  5:DPCM* Y  b  @1 B4 _  l
        //  6:VRC6; x) m/ ?9 ~* _# s
        //  7:VRC7* H& m8 k& `( M- H+ F- S
        //  8:FDS
* X8 ~" a0 Q( _' c2 z; x. W; a        //  9:MMC5
" T+ m& L  W5 U4 |& ~! l        // 10:N106* v( P, G, M7 s& f; O* M9 Y
        // 11:FME7
8 A" r* B- |3 t! X        INT        vol[24];; K6 ]; ~5 M' G* S
        BOOL*        bMute = m_bMute;  b5 T" ]1 o) n! H+ T9 E  l
        SHORT*        nVolume = Config.sound.nVolume;! Q& ?! Q5 i5 W: H( t
: G. u/ w: |7 U- M7 Y
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
% U, m) h/ p. J( H' |3 w9 h2 E6 m0 v1 M8 @: f# \$ `) a: L
        // Internal7 s; G8 e6 E: b9 p8 p' z- Y1 m! M
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
6 I, _4 Q" f' N# O! D+ g        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;3 r2 [4 m/ E+ i/ M' ]: R, f
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;- E' v. Q6 b  l0 z5 O
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;! I/ o3 F, ~& N- Y9 y. l1 \
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;# U: }, o. V0 J" w, `
7 V, r' o4 k, w
        // VRC63 t  L! L) _3 ^7 c7 m
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;9 ~( ~4 g8 z9 K$ A# ~8 @
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
; Y% J7 ]9 f3 R" `# b5 ^) e' G        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;  ?5 q4 P) S; |2 n, {8 G" w
/ E; ?% T( g) b- v; q- y
        // VRC7
5 P3 J) ?2 o$ p1 S        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
6 G/ M7 Q, s6 l) c, p. H
& q% U" I3 _1 n0 {- }        // FDS
0 m, `2 j, ]/ q& @( O        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;% Z- Q, ~1 z  X* n  a2 J( k, z% G

+ A; S- f( H* h: S: g0 W        // MMC5" W9 Z; f9 O* U) `( d
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;$ L6 r9 b- b" O3 V% @( L
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
9 c$ w" s7 F/ j6 p, H, m  y        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;6 n! W9 ?% |0 i+ ^2 P
9 y! N- x, e5 [- r& u0 |. u
        // N106
9 `2 `/ v; c6 k7 x        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;/ J2 X! P7 w+ C$ a; X: e
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
3 R7 B9 Z# Y3 l6 l0 L. v9 v        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;2 h& r; h& A# D4 e( C) Q
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;/ d0 i# i6 p4 ]+ _. I5 h4 R/ V$ A
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;5 u$ z* v2 I  r8 t. P* u) V
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ @# X2 |2 d) v9 t2 }
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;, r* ?9 o0 j1 Z0 h5 N
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;( g0 r$ c+ [, X" T" A/ ?2 E. q
5 ]4 j: x3 v0 z! L
        // FME7
, ?9 `4 [0 @: w+ x) E* n        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;2 g0 E/ C% a0 @9 U, v
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;  Q4 R3 z# |) \5 F  D0 q& ^
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
2 H1 D, r/ n3 ~; q' Y) h7 T* I6 b9 b* D& l: S
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
: L4 E9 b( S6 N. n7 Z) M5 r        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
' q% ]' L7 b) P: A" m8 T& M7 _& O. Q* s/ F  ^) S
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
# X, y. b% {; z. X2 ^5 }        if( elapsed_time > nes->cpu->GetTotalCycles() ) {6 V3 Y4 z# W( G
                QueueFlush();
# f" N4 V$ G: S5 u# i% J        }
* L9 |+ ]% j/ f  k& n! {. ]$ {* f. z/ {$ ^2 D. L) i/ x1 {8 _
        while( dwLength-- ) {
& l3 c! H" H. N9 l& ^. R5 X0 n                writetime = (DWORD)elapsed_time;" ~5 \7 @4 V; ~5 F

3 y7 A9 U  ^  J% V3 \1 ]                while( GetQueue( writetime, q ) ) {9 _- |4 _9 x* C7 C4 y
                        WriteProcess( q.addr, q.data );
: F9 `$ g, n! t$ c* a% i                }3 V( |  N) A2 B1 L; `

, S* y  f$ _9 U& f1 [! a& n/ H                while( GetExQueue( writetime, q ) ) {
+ D* R/ D/ U$ M/ z2 f0 {                        WriteExProcess( q.addr, q.data );* p/ U7 J% M$ Q: P3 ~2 f5 _
                }
( U( ?8 ]1 T, _7 x' }, J8 w3 K! H# V7 i0 _+ C8 r' L
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME74 y  J6 V' C* I" M" [  d
                output = 0;
! b8 J8 T+ c- {5 c% E2 ]+ X                output += internal.Process( 0 )*vol[0];: a. Y4 I2 \' V: P# {
                output += internal.Process( 1 )*vol[1];
0 n( J+ k7 K/ Q/ \2 u4 B3 d5 ^                output += internal.Process( 2 )*vol[2];* Z2 V8 R& b3 {/ C1 R  F2 Q
                output += internal.Process( 3 )*vol[3];$ w) y4 Y: {5 J, |8 N. B: B
                output += internal.Process( 4 )*vol[4];# V6 M: ^0 M  U2 N, r

9 B' ]: O6 c2 F/ s% ?6 f                if( exsound_select & 0x01 ) {/ `/ h8 p, @9 |, \( V5 D3 m
                        output += vrc6.Process( 0 )*vol[5];5 g) N' R* A: q0 G
                        output += vrc6.Process( 1 )*vol[6];! D& K) M; K5 {8 A& j6 p" n
                        output += vrc6.Process( 2 )*vol[7];% i& O1 G0 r# l) |" w7 ]8 a; Q
                }1 f: d$ C' {$ X3 D7 Q# c$ i
                if( exsound_select & 0x02 ) {
; b3 P9 n' i/ t4 p5 b: w: _                        output += vrc7.Process( 0 )*vol[8];
: `1 l1 u- w- X6 N7 B9 W9 m4 M                }
' w8 O$ P- |+ v+ B1 e' Z                if( exsound_select & 0x04 ) {
% S% ~" P7 x8 L1 B# R; M7 d; t                        output += fds.Process( 0 )*vol[9];6 U2 R  x4 M' p: C. j( V4 O0 m. Q
                }
" s7 ]6 a3 [- n$ m- n                if( exsound_select & 0x08 ) {1 V. N2 a1 Z( R
                        output += mmc5.Process( 0 )*vol[10];
6 q6 E; J; F4 j# ]% ~                        output += mmc5.Process( 1 )*vol[11];
4 {  X: l' s" q                        output += mmc5.Process( 2 )*vol[12];
- \" W3 M0 f- |9 E- C& f                }
8 O* v" |- r, u8 l                if( exsound_select & 0x10 ) {  K0 u% p7 K9 C
                        output += n106.Process( 0 )*vol[13];; w( o" p9 _7 ]) K
                        output += n106.Process( 1 )*vol[14];
! P" u6 W$ @$ l" k; ^* {+ P& O$ h. o                        output += n106.Process( 2 )*vol[15];# L0 d4 S9 d: `% R
                        output += n106.Process( 3 )*vol[16];
: r+ M. c  P  N) O$ u  l8 [! @2 o0 D                        output += n106.Process( 4 )*vol[17];
# i: f0 J' U. `# H* H0 R6 ?                        output += n106.Process( 5 )*vol[18];
7 m8 W: D5 `" p5 L0 p1 c3 j5 U                        output += n106.Process( 6 )*vol[19];
7 h4 R7 N6 L! S( P, z( x# {. _                        output += n106.Process( 7 )*vol[20];; S' h" a1 E! i& z) o
                }) ]' R8 g  H3 ]' f: ^4 i! J
                if( exsound_select & 0x20 ) {  |+ @0 U+ o5 b+ X
                        fme7.Process( 3 );        // Envelope & Noise
" A5 p; x- |6 m1 j4 p* k8 L. [                        output += fme7.Process( 0 )*vol[21];
/ J" \9 z5 A+ ^. L- f7 F                        output += fme7.Process( 1 )*vol[22];
# [6 P  |: n/ L. v" h                        output += fme7.Process( 2 )*vol[23];! b2 ^: j! Y# {! V7 x
                }% S' }  C( N- a

% O  v4 a4 y) t9 `7 h1 i                output >>= 8;
( f  F  V# q9 b4 l
0 d4 V/ M# i  K4 }/ Y$ J                if( nFilterType == 1 ) {1 I5 K, n. D( q9 w
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
2 R! [1 b5 {' y5 R' ~( l7 T                        output = (lowpass_filter[0]+output)/2;
) o+ T. |' K" E% T5 A% v* ]) T1 v                        lowpass_filter[0] = output;8 P" ?6 a* Q; v
                } else if( nFilterType == 2 ) {* O3 Q8 G* C$ |! s3 U$ {+ V2 k7 R' P
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)9 b) A2 _6 U) o8 W
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;/ `3 _0 W% P( }: @1 ^- h9 M
                        lowpass_filter[1] = lowpass_filter[0];
" ~& L0 e( q/ A0 z                        lowpass_filter[0] = output;
# ^3 o4 J( q7 [                } else if( nFilterType == 3 ) {
1 ~& g2 u- Q( G                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)  N; B- a/ T! I& L0 R1 H% j
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;0 q: h$ @! M1 P
                        lowpass_filter[2] = lowpass_filter[1];
: ^' \/ ?2 ?4 G$ U. N6 E) H. y& [                        lowpass_filter[1] = lowpass_filter[0];
- S; M& t4 u5 V' y( ~+ F                        lowpass_filter[0] = output;
5 _) q% ^6 [: b+ o7 y' S/ X0 [5 W/ Y                } else if( nFilterType == 4 ) {, e! w) j( P4 t" V' ~' E7 l) K
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)5 i6 c2 M* g" ]* L; a
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
* }* \. D6 @5 d                        lowpass_filter[1] = lowpass_filter[0];
! n" f" A& t8 L4 p8 A* Z0 ~) A1 o7 T                        lowpass_filter[0] = output;
: _- X& e# S2 C  x1 E                }2 C1 F4 b3 Z% u2 e- I1 Z

/ L; k% u& O7 O+ T#if        0
1 T: B6 ^2 d4 S. L                // DC惉暘偺僇僢僩/ S7 i% Y' T5 z4 Y5 B( A" q, v
                {
  V6 j1 F1 w4 I$ N- Z                static double ave = 0.0, max=0.0, min=0.0;
. q4 k3 e1 I% B8 |6 j3 {0 G                double delta;
) Z8 C8 W* z0 z/ F$ k                delta = (max-min)/32768.0;
. ]2 `% V) Z- ~1 \. `( `                max -= delta;+ y, C2 L5 ]+ R1 y. [/ p8 ~
                min += delta;
8 u; b+ r: Z2 ]  U6 d                if( output > max ) max = output;
) p* e+ h( K! J6 E                if( output < min ) min = output;
' _% Q+ M7 }) H$ l0 K                ave -= ave/1024.0;
7 o! c* }: c, d, V                ave += (max+min)/2048.0;  g0 P+ m& R/ y! P9 L% p2 k$ v
                output -= (INT)ave;4 {; k  S& ?! O. v. C( u
                }
# t& j5 q# b4 X+ G6 p( X#endif3 C/ x- I* }* o/ H
#if        1
( r! f5 ^1 C2 T- ?! ~  \                // DC惉暘偺僇僢僩(HPF TEST)3 |- C& q" V9 E6 {0 H
                {
* C; ?. z9 z3 i//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
. v. ?' k& ^( ~8 i3 N                static        double        cutofftemp = (2.0*3.141592653579*40.0);; v8 Z5 ]& ?6 I  P, P7 ?
                double        cutoff = cutofftemp/(double)Config.sound.nRate;; ~/ ~* r0 |9 ?
                static        double        tmp = 0.0;
8 J( X. Z3 D2 P, I0 N; x( p0 l: ^                double        in, out;2 P8 m$ O# {: z0 t# O

. P  l$ B- `. ^                in = (double)output;2 b3 ^) L' q! l: W1 D
                out = (in - tmp);1 f( ^& O8 Z( T- ^* Z
                tmp = tmp + cutoff * out;
$ Q- x/ l( y1 p& z/ S% Z/ K' e0 w
* V; j( x+ @6 k1 q2 t( e0 y! ^                output = (INT)out;7 H6 T2 L+ [* Q7 \2 U7 v- x
                }
8 k+ r! ?6 N. C4 h* d+ F#endif
/ d9 @2 }' M2 f+ c* R#if        0" h9 X1 u; _1 d5 p& P! J7 y
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
8 Z3 v* V. P! Y# x/ j1 q& v                {
8 [4 l3 b9 Z/ H5 X$ Q& ^- x# L                INT        diff = abs(output-last_data);" r' E9 H# B1 y( a0 n% D( K; K/ r
                if( diff > 0x4000 ) {
2 Z- M* b4 u+ z                        output /= 4;
' o) w) m9 Z; h" ^                } else
6 `! D9 k+ {4 S                if( diff > 0x3000 ) {( a$ Z4 I3 p, W: K& }+ t0 H
                        output /= 3;
+ X8 `0 b5 u5 F# Z/ n) k" I% G! @                } else
+ \$ v* w# \' r* I* w: r" x; T                if( diff > 0x2000 ) {
! l! g) J5 W$ M; {, Y                        output /= 2;
1 T. }2 y3 m: d4 M; W                }
  r" Z7 c$ u. o3 w+ d+ D* ^                last_data = output;$ O, Y: l; M9 Q3 N5 s0 X9 D% @
                }
) S* L8 E* e6 f- o- }  Z, x% m2 Q# ~#endif
8 x8 F% H1 m7 D" h9 d; l- g                // Limit9 d+ \) y3 _  G# e  z$ Z: Y
                if( output > 0x7FFF ) {
) Y' g, P2 y2 T1 X) @0 U- i                        output = 0x7FFF;
# D- X" W- P+ p4 e                } else if( output < -0x8000 ) {
: P$ }8 T: C- v                        output = -0x8000;7 }) m  X$ t. k, H6 r
                }" b1 ]6 N7 E: Q6 @+ f
( C1 L6 m/ l7 ]! X8 r
                if( nBits != 8 ) {
2 g/ }* ?8 [- H  W! d; N; y                        *(SHORT*)lpBuffer = (SHORT)output;
. h6 i/ w% H# C1 r4 P' p# Y* ~                        lpBuffer += sizeof(SHORT);; K/ O, u' |. M2 f
                } else {" k+ e3 B* w  x
                        *lpBuffer++ = (output>>8)^0x80;
/ O& ?) M/ G3 q& o                }
& E. e3 E" ]4 P' @- h) y0 l1 n  @% h! Z1 G& j
                if( nCcount < 0x0100 )
( h' b( X0 @( g% ~                        pSoundBuf[nCcount++] = (SHORT)output;" G9 [" a" u) w9 c, K) H
" U& x$ [: V0 |% W  i
//                elapsedtime += cycle_rate;# c7 Y3 L# A  L3 K, I' F4 N
                elapsed_time += cycle_rate;7 k# E7 K! [6 B9 T& @9 W, O  v* t& H
        }
3 u* ^7 T& R' Z: N! U& P& ~* L; g5 _) h2 {* N1 E
#if        1+ r8 O" u; a: J  c, d
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
) H& `: J3 E' I, K                elapsed_time = nes->cpu->GetTotalCycles();
4 Z( E, w, j) F& F& r/ M( \8 ?        }$ T) [7 H5 K" [0 v/ d" S& N9 z
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
  {0 H9 g; g  L3 ~$ A: I                elapsed_time = nes->cpu->GetTotalCycles();
+ V; X0 v$ P# W3 F3 {        }
  Q; o+ v& V, Y- z- Q7 ?$ e& }; T#else7 w  u& h: J% a) c' b% ^6 x: ?
        elapsed_time = nes->cpu->GetTotalCycles();
3 ~8 h+ z& L0 x# V* ~$ y#endif
& ?" P9 P* }  }- O  C4 K0 w}
# f; c2 o5 }2 |7 x  n
" ^4 t2 W3 ]9 h8 O* u" |// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)" z0 `; w5 R$ r/ E# D/ B/ W
INT        APU::GetChannelFrequency( INT no ). S; k7 v0 V  e( A7 x
{
  W% r$ Y: J5 S% {/ _        if( !m_bMute[0] )# D- _& d+ D6 ^! s! ^- C
                return        0;
% C$ R/ R& s5 S* W, z0 M* t$ z. _  K$ b
        // Internal
0 V3 [. z6 l  e        if( no < 5 ) {
" }/ X4 o  _. T                return        m_bMute[no+1]?internal.GetFreq( no ):0;0 E2 B- l. O' B4 A& m
        }7 m$ c- N; m* l) ~6 e4 k) F$ o! H
        // VRC6
! v! p4 s0 B8 E% ]( L/ t        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
0 W5 G) t5 d; G" W/ ~) F                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;7 x/ Y5 A& j+ Q3 P* u
        }
9 L% e$ b1 X# R        // FDS1 k% n# c* y* k
        if( (exsound_select & 0x04) && no == 0x300 ) {
9 N  H$ z' K) M+ K; x- w: B                return        m_bMute[6]?fds.GetFreq( 0 ):0;1 `9 ]9 K" X* g8 B; d# A. x$ f
        }( s$ T4 b( ~. R7 p
        // MMC58 \& \" }1 n( ^9 {2 q& b
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {1 K" W1 O6 I: |1 a% A* G! F
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
, {) ?  d2 z' M; y- B7 i        }
: j6 s% H2 ?% E! u        // N1066 y0 p) Z4 O9 @- B" {9 o/ }+ \
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
$ b1 _- E4 C  w) L                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;1 i  m. H! f6 j1 J3 {, C
        }
  |. p+ O  K7 u9 h! m% ?4 p* R        // FME7
" ^, W/ g$ u- ^  O# a        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {: a/ Z8 I2 z# Z. w5 C; b" t) k% \
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;! c# x& q1 d. k. L8 }6 K% x& S
        }
8 s5 r$ f) w$ M& c1 c        // VRC71 R0 ~; ?+ u) I- z
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {& k. F1 B% K- E/ h/ n
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;) z, k+ n" w& r8 w) \( M& Q2 m
        }
$ X4 V9 I+ f) W  W4 ~: h        return        0;
# j- ~# E! e, C2 ~8 h3 h" @: U}3 K% c6 q& M" {  m9 J% h4 _

% R# f5 y; m1 d6 q& N// State Save/Load
* m1 Y# V! r5 T! d; \# ?+ T1 w, _void        APU::SaveState( LPBYTE p )* p$ b6 f# J/ a7 O- U
{' j( }) s" g) ?$ P: |0 [, I
#ifdef        _DEBUG4 x3 _! b. @5 i5 A
LPBYTE        pold = p;
- Q8 i( V# }. ?#endif
* D; Q# O  _, K; ]
' O+ S: ^: @0 L6 p8 C% K0 Z( C        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞8 K6 \2 h$ T5 F- ]: z: a- }
        QueueFlush();9 F2 `  {6 `' W, G/ D

0 a2 S& @* g* H* G/ D7 U        internal.SaveState( p );2 G: S+ x) ?, V. }) \. a
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding4 |/ F, U) i1 C; u
; u% Y& |( h% ?* F; g, a# C4 B: {
        // VRC6& v- A% E8 }3 g1 q. I, J
        if( exsound_select & 0x01 ) {
, q1 R# F" c  F+ \6 t: m+ k( _                vrc6.SaveState( p );2 e2 d' J( [3 ~( j
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding' _) X  w& {6 M; f  j
        }
# l8 u  ]' o" h! O6 [/ f        // VRC7 (not support)
3 r5 B) Z6 v5 m' l; U# Z8 @, x, x) a( B        if( exsound_select & 0x02 ) {) j2 U" v$ w9 n& I! _  {
                vrc7.SaveState( p );8 {4 P$ v$ e  O
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
7 v2 T& @& {5 N5 ]8 w        }
" n4 h  t/ ?* j* D& l        // FDS& q- z: a( H) |9 T2 _6 P/ s
        if( exsound_select & 0x04 ) {( K2 N; `: Y- _* F4 O, K+ z3 R( I
                fds.SaveState( p );: M" n4 P, }, `& _
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding% h* |+ X& c. \
        }- f, n# i( \4 L2 {7 G4 [7 ~0 B
        // MMC5
* u0 e; `9 Q, b+ `        if( exsound_select & 0x08 ) {
/ r" C* Y% U. F  {' U                mmc5.SaveState( p );4 Z- J/ X- X7 g
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
6 Z/ ?7 f2 j2 F' z0 a* b/ F. W+ `        }
2 R, L0 @: x1 t) ^9 c        // N106
/ N5 T- d4 I2 s- R9 J        if( exsound_select & 0x10 ) {
9 E9 b# }* s9 e2 |                n106.SaveState( p );6 L! r3 E' f2 x
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
3 |; n" u, X- p- B        }
$ Q9 N0 O& P0 [. t+ G        // FME7, W" {7 ~9 X# e% I5 o; ?5 L
        if( exsound_select & 0x20 ) {2 }1 e6 W. t. ]& @) T9 U
                fme7.SaveState( p );
8 B8 a# l1 {4 y6 l4 E                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
, A- _) H0 I% ~. `        }4 X; `9 Q8 ~2 q! o9 h$ Q8 D
1 S/ M% o% @* ~6 ~
#ifdef        _DEBUG; r5 W! v9 J0 L0 M( Z( E
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );6 w4 i, g. N( ~3 r4 P' z
#endif9 G% F2 I, F# t9 p0 Q
}# o" j8 n2 }9 K& K1 K

- j0 @1 ~3 e: y7 J% U" nvoid        APU::LoadState( LPBYTE p )' q3 y8 ^2 v6 f  S8 M  N/ h
{4 x7 N' d+ A* q7 i, J6 c4 m4 ^4 i
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
1 z( b" G: k! q9 z. I8 |        QueueClear();; s3 u, V8 m  T4 \) O3 Y/ A
+ M; ?1 H& E" [8 ~* [
        internal.LoadState( p );
  Y- {/ x6 `( i. v( g/ _, j        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding7 d& m7 p) G; A% U

. P9 w  g  `1 p( y! b+ B        // VRC6/ }' j5 P& [+ o. ~: ^
        if( exsound_select & 0x01 ) {; }1 E$ T# V1 G0 P
                vrc6.LoadState( p );0 d* A2 K1 Y# I0 H; m
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding1 @! {' I) V9 {6 d0 @: h: ^! B; ^
        }+ E0 O" U- r/ s  w) q9 K
        // VRC7 (not support), G# e$ F, p& Y1 J. C# b
        if( exsound_select & 0x02 ) {# T% D/ w  |8 ]; W+ [- ?% t
                vrc7.LoadState( p );
, q- }3 p& N7 u  J4 I& O+ A+ k                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding# r. T8 I9 L0 K+ Z0 ?3 E
        }
  }, `; f$ i) n! D        // FDS4 k6 X$ v3 r0 z( ~7 z
        if( exsound_select & 0x04 ) {
& z" E, \# S0 {                fds.LoadState( p );& s& M) Z( T( d: e+ H3 N1 ~( e" m4 s
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding' y5 K5 @1 ^. D, A5 c2 Z
        }. O( Y6 c2 @& k
        // MMC5
; a, k9 b) D# [8 G6 b/ J! O        if( exsound_select & 0x08 ) {+ g; h- h9 a4 y4 Q, e& s0 H
                mmc5.LoadState( p );
; L, u/ ?, c3 j& I5 B                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
2 Y) R% S: o1 z, k9 j        }
5 n$ Z2 R, ?& I$ ?3 s; N        // N106* F. [& V1 O/ B: ]+ y4 [; z) J; u
        if( exsound_select & 0x10 ) {, p6 ?" E) M& F
                n106.LoadState( p );$ m" A! ?& p0 V" j# @7 E/ }
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding% i; N. v3 c$ [1 `; V  D- Q/ d+ ^% c
        }8 A1 b" B0 X1 M/ [9 s7 O
        // FME7, \8 G+ S. _/ S; f' k* |
        if( exsound_select & 0x20 ) {
) V# d( H# W1 @; {                fme7.LoadState( p );- c$ A( l0 `- L9 Z7 B+ T% f  s" [
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
0 c: \; b7 V. y" |* [        }; e6 K7 b. n; Y" R3 ?( d5 z
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 6 R" q: c( d- n
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
/ N. Q3 Y+ {& x2 X' Z' Y感激不尽~~
; G, `8 T, v9 v* L, k2 z
恩 我對模擬器不是很有研究,' G# G& p) G. i( ^# |
雖然要了解源碼內容,可能不是很困難,
9 I6 ?. v: i! r( y: q" p  |不過還是要花時間,個人目前蠻忙碌的。3 R) A8 |* n: {  u7 _5 t4 M- Z. l
; Y1 `5 l1 z' L$ D. F
給你一個朋友的MSN,你可以跟他討論看看,, D& t" a( n/ Q# D# d8 o4 m
他本身是程式設計師,也對FC模擬器很有興趣。; \; S& n) m* O/ i1 i9 }4 s* }
. {% h# F9 n4 ~( G6 x/ U( V
MSN我就PM到你的信箱了。
2 k( }: T# m/ O% ]7 L* _- t0 L* @$ y
2 u, m) Q1 z) M; [2 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 发表 5 r- {" j6 G& J
呵…… 谢过团长大人~~
7 O; S/ j4 a: P

9 [" v( b$ d: |8 D# L2 _8 \哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
* X9 L. n1 w, Z9 N, W+ ^/ x团长的朋友都是神,那团长就是神的boss。

# G6 l1 {3 C, i4 ]/ w/ I哈 不敢當,我只是個平凡人,# i1 I! p. i* s2 F+ t# k+ ~
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
4 s5 y$ t1 t) b8 E: FZYH3 s; e# X0 G; I! G& i
QQ:414734306
* n2 W- r& x& EMail:zyh-01@126.com, j6 f( Y$ E9 Z, H1 e2 y, F

) {: y& ^3 S" |. l) a' d& D& a. X他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
% n4 j. M# B- d* [再次对团长大人和悠悠哥的无私帮助表示感谢~~
3 V- ?) w; b. V4 i9 u( [
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-10-5 16:14 , Processed in 1.086914 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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