EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
6 T( V. Q* u8 @" W- F/ U- |. X楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~/ L, y; o$ x: `
这里有相应的模拟器源码,就当送给大侠了~~
5 a) T; ~$ v& F; r+ p) U0 u7 mhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
3 d3 ]+ y  _* J  A能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。3 Y# ^+ N1 x3 k/ e
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~/ G5 |3 I; d( o% h. Z* `
这里有相应的模拟器源码,就当送给大侠 ...
, T) x2 x2 p9 ^3 u. n: q7 j3 Y
聲音部分(Audoi Process Unit = APU):
5 {3 z' b4 d8 ]1 s& r( T  Y.\NES\APU.cpp
. @. C) {1 E. }# W.\NES\APU.h
6 G: j1 s$ j2 J
. |% n4 V' {0 I4 s" J9 k$ ]' _
5 C& }' F! L* A& g影像處理部份(Picture Processing Unit = PPU):
+ _/ d5 t* M6 C0 e& U$ }1 v5 ~/ |.\NES\PPU.cpp3 Z8 k* V% p7 \0 \. w
.\NES\PPU.h
8 @7 N! @! x/ [$ R' f
+ D* y6 Y* {( n* j  O4 N/ t如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:4 J! r' |- r# t4 B  P$ G9 R" u
(由于很多专用术语和算法机理都不明白,所以看不大懂……)( o/ }3 E; R* M" F7 t2 s6 F
//////////////////////////////////////////////////////////////////////////5 F# m  S- t4 q- n& P2 G
//                                                                      //- A0 E. u2 i) M
//      NES APU core                                                    //" f/ b5 U* X( W( @6 t4 d8 @
//                                                           Norix      //% S' t% D+ t7 b7 _' e- q% V1 @3 }
//                                               written     2002/06/27 //
0 ^. z/ d) J" H  K, w: v//                                               last modify ----/--/-- //* \: ~8 g8 E/ ~/ A' D
//////////////////////////////////////////////////////////////////////////
  u3 M6 S: y& w3 W5 G1 l* P# q/ M#include "DebugOut.h"
6 e+ M" S3 y% |3 R1 q7 }#include "App.h"
  S, R( |/ K. B7 i5 o+ U& c; |. T#include "Config.h"
& a$ l4 j' S  S3 ?6 k# F; ~% `: s3 x$ N8 o# [- N5 e
#include "nes.h"; g( B, l4 O; c9 q: n
#include "mmu.h"* b* ?( c; l! B8 r/ t
#include "cpu.h"! K7 r, Q  P/ k1 G( W4 R
#include "ppu.h"
& `3 i1 W- v% |% I5 a#include "rom.h"
, H! L  R7 E. K. ^- f#include "apu.h"
% S0 l" Y& \! `% G
8 J4 ^* O9 a: `* Y! C$ F// Volume adjust) Z0 c; |0 q, ]& Z2 p( u: Y
// Internal sounds6 J/ R5 j# d" O0 {8 ]
#define        RECTANGLE_VOL        (0x0F0)
4 f6 F, Y& R5 I4 J- @% m* w4 e" A, w7 r#define        TRIANGLE_VOL        (0x130)
5 q- E1 i5 w3 I, B#define        NOISE_VOL        (0x0C0)' c& y5 h& C; W8 y
#define        DPCM_VOL        (0x0F0)
/ a- E' o  n  q! ]// Extra sounds
( t+ L( T+ k* P6 B. Q, j0 d7 Z#define        VRC6_VOL        (0x0F0)
* U8 @; a; v( L' M2 g#define        VRC7_VOL        (0x130); W9 l- B- Y& S( m# z; f& g( ?) H1 [7 n
#define        FDS_VOL                (0x0F0); E9 X" r1 {3 N# R
#define        MMC5_VOL        (0x0F0)0 b1 X7 k6 @9 p/ v
#define        N106_VOL        (0x088)
# _( O5 h$ u5 Z4 T& g) o- q8 S) [8 e7 D8 \#define        FME7_VOL        (0x130)( U" J3 n) @  N% @

3 h4 q8 u, j3 @+ ~APU::APU( NES* parent )
; d5 D$ ~+ |; U) ]# V{
8 N+ j( E2 h8 t- V6 K2 \5 m3 z        exsound_select = 0;8 c  o- [9 u6 C" L( a
) T3 c% X/ {) f8 ]% g) j
        nes = parent;  N, S' ]! s7 z1 i0 ~
        internal.SetParent( parent );/ s8 L4 _0 x9 T$ `3 N. ~
3 _" |2 B- T8 U3 \. ^' _
        last_data = last_diff = 0;- a% g1 p7 H3 L8 }: u" m; o9 f

1 C: b' p4 _8 d. l5 Z2 j        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
$ U; D  g9 ~& G) x# N/ o
8 n5 Z' m0 P" f/ X+ X        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );* s% \. }8 \! k  Z4 e5 i% e
        ZEROMEMORY( &queue, sizeof(queue) );) o* c) A/ M% C" V
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
" o& U+ b- ^3 p! \& y0 |# h8 J
; _: v; |+ k1 O3 k' I        for( INT i = 0; i < 16; i++ ) {# w1 V( m# f- O+ B& r( [0 I
                m_bMute = TRUE;
7 Q( |2 c- [# p, \        }
* _. _4 j- L9 k}
' {- F0 m+ h3 Q" |' T8 f/ [' R( ~. Z; c2 P& a5 _7 T
APU::~APU()
, S& T* W# p+ F- _4 y/ r5 o3 O{+ l% Q$ t$ t' `
}
* _0 Z% y4 w2 c2 m+ e5 }( V2 w( T2 t8 h
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )( E9 c) q  a( |8 V' |, w) ]$ ]
{
0 ^1 o% [' J* I' p        queue.data[queue.wrptr].time = writetime;
% Y% R$ w: E2 ^# S* ]. _, e        queue.data[queue.wrptr].addr = addr;" \$ ?) q' H3 q4 F; _* M
        queue.data[queue.wrptr].data = data;' P+ x- A# y' z& U4 @( q+ O. }, P- Q8 N
        queue.wrptr++;
' ]/ u" U% h+ ?  n5 O/ `( a) L        queue.wrptr&=QUEUE_LENGTH-1;
9 L& `# |% k, n; r) O- n        if( queue.wrptr == queue.rdptr ) {" @; I7 u# r" A
                DEBUGOUT( "queue overflow.\n" );
" L) c  V% W3 r5 h        }' Q5 G% J; z9 ?3 j: y
}- p* l8 Q2 A. Q6 X6 k! Q% C
4 o+ M5 x4 y. v* B  {; L
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
1 Y7 X* W& I' V' D5 ]( |{$ ]; T. i& v+ G
        if( queue.wrptr == queue.rdptr ) {
( P* I4 L6 ]# m4 |                return        FALSE;. F- V* k0 I' X; a8 u8 c
        }
2 b9 d; V2 ]$ Z0 Y, K# J        if( queue.data[queue.rdptr].time <= writetime ) {
3 N7 j9 C1 X, [$ g                ret = queue.data[queue.rdptr];
# z% V) Y) B: o" W$ q* _                queue.rdptr++;
1 }' B2 Q  g9 J* e9 t                queue.rdptr&=QUEUE_LENGTH-1;
3 L" H" y3 q: G3 f                return        TRUE;$ T- [: h0 _5 a1 `
        }, Y- t, P2 O2 u
        return        FALSE;
7 I* K2 I/ l4 Z6 ^3 N# O- c6 q}
( w. Q" F% H1 H/ E$ Z0 ?6 Z7 C) d" F0 G! K4 b4 x, R8 b
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
) k  b' O. N! e  v7 L{
# [5 a$ d# }  h. w+ [0 k+ i* o& J        exqueue.data[exqueue.wrptr].time = writetime;
$ w& r- {9 x1 w        exqueue.data[exqueue.wrptr].addr = addr;
( h, @. N4 E+ B5 O8 n        exqueue.data[exqueue.wrptr].data = data;
  Z. @( K* ]4 e8 e        exqueue.wrptr++;. ]" }$ g& X4 H7 \, l5 @
        exqueue.wrptr&=QUEUE_LENGTH-1;
8 o* g( V3 X( u# q7 {) [6 \        if( exqueue.wrptr == exqueue.rdptr ) {/ |3 f# s! {) {0 z( v
                DEBUGOUT( "exqueue overflow.\n" );
; c; _" D7 m. d* @6 G        }
% `7 H& B$ x  n}% r. Z7 ~5 Y8 c

9 G. _5 O5 F2 ~' k' cBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )9 g2 D; @  c2 U2 t8 M7 l
{5 d$ S: Q6 f. O
        if( exqueue.wrptr == exqueue.rdptr ) {& K0 a5 b( {' i4 |
                return        FALSE;+ p( o& {% X) y9 H  E( `/ v
        }
- m! Z  x( [* K        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
/ f( U/ f! O+ K6 N                ret = exqueue.data[exqueue.rdptr];+ Y$ Z  }( L8 G2 H/ R- f0 t, Y
                exqueue.rdptr++;% C' R" o- x1 G. \- K3 }; b% q
                exqueue.rdptr&=QUEUE_LENGTH-1;
$ T( e+ I' Y4 l0 `: k                return        TRUE;
& D. R' F% B+ i- H1 d        }
9 v2 Z9 |# J' C+ }. [        return        FALSE;: M+ O/ G! A& H+ O. x
}: ^8 Y& r  q  ]2 D

  O) K+ I: ~; `6 ]4 @( Mvoid        APU::QueueClear()+ H$ D$ {6 v( b
{, n9 l$ q& P7 S4 _
        ZEROMEMORY( &queue, sizeof(queue) );) O% p& ^  V# u4 J0 t7 D; I
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
9 c# G: l5 B4 `. N) ?}
! h( ]6 x) Q) d9 A2 m0 T" u- [& E. N9 C; K" W, x
void        APU::QueueFlush()
+ N% }" Y$ Z7 q! z{' s1 ]8 C" ~4 n" ?+ K! a% w* A
        while( queue.wrptr != queue.rdptr ) {
0 A; P* ~5 o* b; e2 b" Z                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
6 i' @, w; T. V4 M( \( L4 u7 x7 m; p                queue.rdptr++;
# }  t0 Q! f+ s) C" w                queue.rdptr&=QUEUE_LENGTH-1;1 C5 a' z$ O1 }* R' \$ K1 p& f
        }, u! g( w1 i8 ]! v0 i# d* U4 h
/ t6 ?6 \# w- G0 G
        while( exqueue.wrptr != exqueue.rdptr ) {( h, d3 {( b' V& G' l. E2 n
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
$ Q8 _! D+ X* V, ]                exqueue.rdptr++;
( C' m% s0 ^7 ?6 ]                exqueue.rdptr&=QUEUE_LENGTH-1;# c8 K' {/ s6 H  w4 E! J% F
        }
2 d4 x! a0 g( u/ z( u0 O}' S$ V, r) \1 P7 w1 A" `, b
  {' q4 }5 \' F& d% k9 _+ I
void        APU::SoundSetup()
2 q% L& P1 G. o, T$ l! M{
* g6 a: @, B* [5 M8 Y; \, Z" C; L        FLOAT        fClock = nes->nescfg->CpuClock;
- c1 i6 @4 c: z        INT        nRate = (INT)Config.sound.nRate;
* m+ q) Y. g( {' t        internal.Setup( fClock, nRate );
2 {! ~/ y8 M7 F* }        vrc6.Setup( fClock, nRate );8 V1 [4 P' g5 n4 }" m2 L
        vrc7.Setup( fClock, nRate );: \" q- L/ }4 }1 U3 l
        mmc5.Setup( fClock, nRate );
( y* V' f) f( j: g% M  y2 k        fds.Setup ( fClock, nRate );$ _: H/ j! ]# d7 D
        n106.Setup( fClock, nRate );
1 @/ P' d/ E( a0 e        fme7.Setup( fClock, nRate );6 t8 ]4 w! j# F; C' q7 t
}
! N2 f/ {2 Z4 ]1 b5 D8 f' k; }. D; }# |5 Z/ i5 r
void        APU::Reset()
1 Z0 @; d' T1 C1 K5 n- M{, K, i8 s& Z- ]
        ZEROMEMORY( &queue, sizeof(queue) );
- I" \) K9 i1 O* V- @$ f6 \$ d        ZEROMEMORY( &exqueue, sizeof(exqueue) );
) Q  `& m5 o/ J: x4 \6 ]6 ~, u4 ~! I0 B; H
        elapsed_time = 0;
' s! ^. d8 Y4 w
- ?- K$ Q( F+ s6 F  x        FLOAT        fClock = nes->nescfg->CpuClock;
4 ~5 k& i7 c* a" t7 C* c/ e  h        INT        nRate = (INT)Config.sound.nRate;
% S% \0 @2 t! ?! C        internal.Reset( fClock, nRate );( m8 k/ `- ?$ k# P+ K3 k' N
        vrc6.Reset( fClock, nRate );2 H& Z& z3 {4 ]7 D0 r$ w
        vrc7.Reset( fClock, nRate );
! Y5 X- p; v" V( z/ G: G1 g1 C2 B        mmc5.Reset( fClock, nRate );
$ `) G9 Q6 ]) d: q. J        fds.Reset ( fClock, nRate );- S" O! [/ S$ V* M
        n106.Reset( fClock, nRate );
  X* l4 V& r8 U  B0 e: f  V        fme7.Reset( fClock, nRate );
1 J& ]% T- e" H0 M" F9 l8 h1 w7 O! I0 J" P
        SoundSetup();
6 M; z7 G% l. q7 w! b  K}
8 R* d/ f# y! J- k7 @& l: i9 ]' v& Z1 t. O# t8 r
void        APU::SelectExSound( BYTE data )2 G- a! e- p; m6 ]! Y+ Y. j$ h
{
: Q/ O' T0 a3 J; ~        exsound_select = data;
) O4 v. c! o( |  t* X; D& T}8 @1 n9 c0 d& l; ~
# N2 E/ Z3 \! U' t
BYTE        APU::Read( WORD addr )
3 x4 J; f/ H. C8 P. j0 n{
7 |; m6 d1 K. E/ E! r0 S6 Q: `        return        internal.SyncRead( addr );9 p4 [' q9 |+ q) m3 P2 ?- n
}4 N) [& l6 b! `

2 N0 q' \& Y& ~9 u% y- E6 |5 s3 yvoid        APU::Write( WORD addr, BYTE data )
- Z& i: h- b& F) P2 G0 O3 x8 j{. Y) [) G# E5 P# r6 \
        // $4018偼VirtuaNES屌桳億乕僩1 o4 e2 J& L7 a3 ]2 B) u# `
        if( addr >= 0x4000 && addr <= 0x401F ) {
( y6 c- ^; p% Q7 s9 I                internal.SyncWrite( addr, data );
$ q" v2 c+ u5 `7 q5 h! z- ^                SetQueue( nes->cpu->GetTotalCycles(), addr, data );( j6 N" x! J' w: Z1 X: ^
        }4 e4 R6 c8 Q( ]# K5 l! g
}- `* p: B4 J) z) v
. |% W* E( ]4 v; m' F, ~
BYTE        APU::ExRead( WORD addr )
" s5 E( I2 D0 V/ N{2 w+ M# G$ s2 Z
BYTE        data = 0;
6 p$ L( ]3 r- e% R
& g1 y% G: J: p) @  \& l/ n        if( exsound_select & 0x10 ) {$ M$ w  Z& F, g: d  J
                if( addr == 0x4800 ) {5 ^: X* K: O+ X
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
1 Y/ ~3 l3 z' H" W0 M, d6 Q                }
( h' _/ ]7 J3 X( h        }
! R% v; w* s8 B2 k        if( exsound_select & 0x04 ) {0 m+ ^7 G6 Q, x6 r: c3 g' V: k$ W7 m
                if( addr >= 0x4040 && addr < 0x4100 ) {
3 ?5 K  E0 s6 I5 O/ J( Q                        data = fds.SyncRead( addr );$ c7 n1 f9 s- z9 B8 L0 g
                }
7 Q7 P6 J4 K3 ~4 @4 \8 p        }9 F; U! |9 Y2 j" R" O7 C
        if( exsound_select & 0x08 ) {0 l3 [! X- \6 W% E5 a% [
                if( addr >= 0x5000 && addr <= 0x5015 ) {6 U9 o' P+ y3 \
                        data = mmc5.SyncRead( addr );3 }# b& K9 ^0 |! b; K
                }8 m7 A9 K' i$ \& y0 p8 \+ a/ }5 D
        }$ x# a8 x/ A9 G* l

/ ~9 v  `+ E3 H6 o  _        return        data;
; F4 z) B) m. X" X+ D}5 f0 ]* t, O$ _7 _" p

2 s( B$ d1 i8 n4 C2 v" p3 ^$ O* Hvoid        APU::ExWrite( WORD addr, BYTE data )
+ |( \; ?; A9 j, Y0 ^) y# [* n{
2 i8 u: h+ V+ X8 o) x% @7 v9 o        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );0 B# v# G! ~/ {$ V; r4 q
) a% q# N0 m  y; X6 k
        if( exsound_select & 0x04 ) {7 s7 z0 M1 d0 j7 x' N3 m: y
                if( addr >= 0x4040 && addr < 0x4100 ) {
( W0 e/ Z4 A( L. _6 g" E( l                        fds.SyncWrite( addr, data );, }* O+ ]3 |! y: h) e/ g
                }
9 G& Q  T; C' D- B8 z6 O        }
7 D5 X) s7 ~- Q; j% @( e, ^! X" Z% X$ f) J
        if( exsound_select & 0x08 ) {  o9 Z/ S/ [; R8 T
                if( addr >= 0x5000 && addr <= 0x5015 ) {
  H. t7 D& l: u4 B' [8 e  a                        mmc5.SyncWrite( addr, data );, o8 f  x$ m4 K1 s1 u
                }
: R* a4 F+ e/ G2 L; D        }* S5 C2 F; B% q. ^
}( q: |9 \5 s  s! \" ^- F7 V

: h, p7 Y) _* Lvoid        APU::Sync()
- k8 ~& a% u: o4 G3 G2 t{" \) ~2 Q6 k/ |5 _. y9 d9 c
}& t# h8 }9 x- i( e/ a9 e4 d

/ Z' [* x" z/ d5 _! tvoid        APU::SyncDPCM( INT cycles ): L; o+ G; \, @5 [! X
{9 C2 M; @0 j6 l3 e, j, J
        internal.Sync( cycles );
) @0 c" [# N. X' c& j; s( t% Y, T" I% G0 S+ M" i# Q
        if( exsound_select & 0x04 ) {
9 P8 a7 {: d9 E' D, q1 X8 L9 p                fds.Sync( cycles );
- g. u  s5 x) F/ g        }
1 _# z( O% C! V        if( exsound_select & 0x08 ) {* L* l& w- f; T5 m7 x
                mmc5.Sync( cycles );# [2 G5 o0 x% Q9 w, t% Y
        }1 S5 x5 T1 D  c2 J/ |5 E
}
8 X5 V* b# Z8 |. z* C0 o3 l
$ B6 Q# L1 L4 w8 dvoid        APU::WriteProcess( WORD addr, BYTE data )
' V, Q& O9 q& n0 ^  m{
) B, q& [6 g, j        // $4018偼VirtuaNES屌桳億乕僩
. B* q9 a3 [/ p6 o! {% q& D# h        if( addr >= 0x4000 && addr <= 0x401F ) {
! ~. e: s) b/ I                internal.Write( addr, data );
0 i( E4 G) W1 D; U4 s) z        }) C5 L  Z" c3 n) f
}
0 n  z0 s7 i5 f$ d8 ]1 R9 Q1 i( O, q' {  o* g9 u- d
void        APU::WriteExProcess( WORD addr, BYTE data )$ G( k7 b1 N6 j" X& @) ~
{* D' g% S+ U, v
        if( exsound_select & 0x01 ) {
& U7 z$ X+ L0 V/ u' A5 G: t5 G                vrc6.Write( addr, data );3 i/ r# w9 _9 R
        }. X$ S$ ^* q) d1 b% ?
        if( exsound_select & 0x02 ) {- k9 Z: S% e5 V2 C. k) B+ m2 l; B
                vrc7.Write( addr, data );( T- ^; o9 F) p1 _  s0 P
        }4 C% S9 f& w7 L/ y6 V
        if( exsound_select & 0x04 ) {
6 J, r, `# c4 i% U1 y                fds.Write( addr, data );6 V2 D: q' H5 d6 _& h
        }
. y  `: f: @' g: W5 H$ T' V        if( exsound_select & 0x08 ) {( ?& s! m( k4 S5 \& b$ w
                mmc5.Write( addr, data );
3 B" B" h; A7 |  b' d        }& P9 s8 e2 L0 f6 ~) J  X
        if( exsound_select & 0x10 ) {& J" A$ P( V! _
                if( addr == 0x0000 ) {$ y7 ]; N# r- A2 @+ T5 E( J
                        BYTE        dummy = n106.Read( addr );
" B& g5 p' W/ z! k6 u                } else {5 v, Y/ o4 j6 g8 T
                        n106.Write( addr, data );
( I2 ~: m. |8 }5 t7 Q3 F                }
% E5 y; `; W7 Z: d8 a; l        }
4 K6 `+ @2 \) u' z6 d/ P        if( exsound_select & 0x20 ) {! T3 }3 Z2 }2 y- k, V
                fme7.Write( addr, data );; B% x) ?( w, R% u( S, N# A
        }/ ^, k- Z8 G. `
}6 f2 u( M# N& b# u( `" p
' U0 r% X8 o" Z$ R5 b& s2 ]
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
! c4 _; D. w5 A+ a2 e{/ E* b/ ~4 r$ b6 N1 ?& A
INT        nBits = Config.sound.nBits;
+ u2 U2 v  t* c$ G/ {# xDWORD        dwLength = dwSize / (nBits/8);& f& m1 k  O5 \+ Y' H. N: h! P
INT        output;+ Q) r' z# x7 _9 N% a  |
QUEUEDATA q;4 ?9 _  r6 }, g% ~
DWORD        writetime;
: Z# \  s% U/ |$ F* h$ z: v$ \% w6 R
) v' t+ G# \1 tLPSHORT        pSoundBuf = m_SoundBuffer;
* q! e3 R% N9 I9 KINT        nCcount = 0;
" L/ Q* o- j$ Y4 f7 l' C$ j' H/ T8 f6 b
INT        nFilterType = Config.sound.nFilterType;$ s% e; w) k. g" S, }

% f4 x8 m* L- W$ `5 _1 K. R        if( !Config.sound.bEnable ) {
; s/ ~. p3 r2 @                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );# e. M% g0 w/ V1 T% p3 ^* @; O* r+ a; o
                return;. z# V, U6 @( @2 U# o9 D
        }
: b  L7 f  A: M* ]1 j% b
& T+ k- q6 X& n        // Volume setup
6 \, i& G2 I; c" _        //  0:Master2 `' D, Y: p) C  |
        //  1:Rectangle 1
+ N% P9 W' l. s7 {0 Y) ~# W2 D        //  2:Rectangle 2
: i. Z& L4 X/ N7 l$ U3 [9 F" v% J        //  3:Triangle# C5 z+ D0 F2 w$ T# B8 t
        //  4:Noise! P% `1 P9 E( y: I. q
        //  5:DPCM7 S* l1 X# }) V5 T) D
        //  6:VRC6/ Y. M3 i; V# w! I6 j
        //  7:VRC7
6 R( S, |9 _& O        //  8:FDS
: _! X5 P% C& H8 V* I; F        //  9:MMC58 d  T* h* w3 H9 l. l
        // 10:N106' R0 _8 l: m2 J* y9 W; [- {' g( ~1 m
        // 11:FME7
! s7 Y; D  ^; O2 j        INT        vol[24];4 R) N7 s' U9 b0 O
        BOOL*        bMute = m_bMute;
+ D* S! K( V2 ]% U        SHORT*        nVolume = Config.sound.nVolume;
/ n7 ^# g& Z9 [3 B6 t
" C& {% E& C" h0 F. G3 U+ f$ g        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
" y, R( v, e0 ]' {) x/ g8 F% \2 e8 e+ M. I
        // Internal) w) m; h9 p% B# U* V* K
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
  C+ y3 t# d: B        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;* f1 N" {5 Y. S/ ^. n
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
% ]6 y; P% S# G% N4 e8 {6 O; H7 g* m        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
# w6 Q+ M+ t" v* _$ G. V" h        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;8 F8 C2 s- o( [3 G, j/ B

5 x" ]9 ~8 o+ J2 X$ M& ~( B3 P        // VRC6' I  s+ A$ `) h8 l
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;6 h5 C/ n, U1 M8 W
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;$ y5 V2 c" G" R: w, i0 z
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
% k, c2 e8 J3 w+ d, M% P4 I1 \9 c( }2 ^$ {6 [7 _7 S8 Q0 t  y
        // VRC7$ {. ?4 ?; @) z, r  i% d$ x8 b% F
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
( A. O; y. f7 G6 k2 N9 Z! f% X4 g. A
        // FDS
$ }  A0 r# i; v( {; ?% B4 r        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
; [( q4 m8 p9 ]6 X  M) b2 M* ]& o7 j# a9 _& G0 \/ v; ]: P+ r
        // MMC5  z9 F- g  p) t& x. ~; y  h9 z+ F7 r' f
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;2 Y1 G. y. W3 r! r8 e& ]
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
/ `  ?! r& n" H' k        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
% B- N  }3 \: x% R/ N% K  \9 r. y( l/ r# L
        // N106
, P9 u" y9 X/ |6 l7 q# D8 m0 C        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 ^2 F! \& [& k" x        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
) A$ z2 y( {6 L; N0 [# [$ C        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;% I; |' A; t* l- F% O
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;. S3 n- N; ?6 c5 C( d+ X4 ~
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
% ?. I& w# i" k1 t# `: D: r) Z        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 @" v# \/ J( m9 g
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. l5 {& n5 e. i0 X        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;  q5 e/ S8 q. b9 @3 k4 g, t- J5 d8 ~
+ i0 ^* m  r: e. L* N
        // FME7* {4 b' M4 f. |/ X( ^2 z% V+ b
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;' w' d6 @+ w- H* h( t9 q* K  L- I
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
9 K* Z0 @& O2 \& t. {8 @" T        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;7 B) l& W5 G$ k1 E# u
) j; k1 f" B, g, m
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;/ G' F5 u6 v. }* h2 ?7 Q2 F
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
7 }* d# a5 \' K, A% @. {  x5 L; B+ `/ K. c/ [& I
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟% p# K% D9 }/ _; a2 k  u! u! m
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {) C- T' b# T) j: N
                QueueFlush();
( h0 c5 C& i! Q        }9 `+ `" \; t% i) X
- p* c3 P% Q+ a+ G& l% i
        while( dwLength-- ) {! w! G$ E' K; {# w- _' z
                writetime = (DWORD)elapsed_time;
( w" Y3 ?# e* m7 r4 L) u! o' W
: ~, F4 O5 H: h" t/ w                while( GetQueue( writetime, q ) ) {
4 D0 S; [% i, @5 j3 y; b                        WriteProcess( q.addr, q.data );
+ _3 Q  L1 v& z9 w1 v4 u                }
9 E. u. [) l. t0 \
3 C/ F. \- ?/ U( W# _                while( GetExQueue( writetime, q ) ) {% z$ O" f) H- L6 B! h" v: q
                        WriteExProcess( q.addr, q.data );
7 g, J' r" _% ]& W  k! R                }
1 k5 a) _) g' y+ p4 U& `5 C8 J# s; T* R2 D; c1 w
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7* U3 r& b( K, B4 P+ A5 r3 _
                output = 0;
4 `+ B3 X% v7 G. [/ @( V                output += internal.Process( 0 )*vol[0];" q4 }6 a1 f: J% u6 I& d( d- o
                output += internal.Process( 1 )*vol[1];
5 N& i. C2 p7 X" _                output += internal.Process( 2 )*vol[2];$ {: z, m# T2 }" M
                output += internal.Process( 3 )*vol[3];
+ |+ s6 _. v( w  `2 j5 ~4 [3 u* u                output += internal.Process( 4 )*vol[4];
4 }4 N4 [) [- V% n9 E3 k6 O; {1 s/ L' z5 f. D  p; T
                if( exsound_select & 0x01 ) {
1 f: O/ c8 l7 ]  r# |' t: x                        output += vrc6.Process( 0 )*vol[5];( p) Z% g1 p  G
                        output += vrc6.Process( 1 )*vol[6];3 b3 p. W$ L/ }- I7 A# G4 ?# T  ]
                        output += vrc6.Process( 2 )*vol[7];
* x. f. u; S+ w2 e                }
/ I! V( U/ \' j2 Y                if( exsound_select & 0x02 ) {% x4 n  B0 Y3 x" ^  [! E
                        output += vrc7.Process( 0 )*vol[8];
3 h& i' W6 m* S                }% y* H; w4 x+ b
                if( exsound_select & 0x04 ) {) ?3 y5 t& |, D3 }; U' i7 k
                        output += fds.Process( 0 )*vol[9];
* u8 v' S$ T1 H5 d4 }7 I3 J                }% m% A6 K7 g% ^2 t% P
                if( exsound_select & 0x08 ) {
: @5 O, i- X6 Q! t; f  A1 t. A* ?                        output += mmc5.Process( 0 )*vol[10];6 S# n$ R9 L) J, z
                        output += mmc5.Process( 1 )*vol[11];2 A6 Q- ]7 N; g5 V( }
                        output += mmc5.Process( 2 )*vol[12];
- V2 S5 |, }( P; {                }
) \2 {! |) N3 Z! H( f( {# O$ ^                if( exsound_select & 0x10 ) {0 E( }3 X8 r; Y  p& u% V; |  c
                        output += n106.Process( 0 )*vol[13];
/ M* P1 {- J! e2 x- y7 g( d                        output += n106.Process( 1 )*vol[14];7 h. }/ i! C9 K7 G3 H% ^4 L3 C) A
                        output += n106.Process( 2 )*vol[15];. A: \, K7 P* n+ d) F" _( X+ [! k
                        output += n106.Process( 3 )*vol[16];
2 v8 i( X5 f, Q- N" p6 Z                        output += n106.Process( 4 )*vol[17];, ~6 Y+ X9 X" \, O
                        output += n106.Process( 5 )*vol[18];* `% w- z! C6 K9 t2 |4 G
                        output += n106.Process( 6 )*vol[19];2 U7 s. z6 I( H
                        output += n106.Process( 7 )*vol[20];% w0 s7 q/ D+ G/ {
                }
1 F  u9 O* Y: L4 c& `                if( exsound_select & 0x20 ) {( y' e0 h# P# j/ _
                        fme7.Process( 3 );        // Envelope & Noise
( t) K; N( d9 @0 Z                        output += fme7.Process( 0 )*vol[21];* R: J; \* O1 m2 P
                        output += fme7.Process( 1 )*vol[22];5 i' _& V5 d$ t* \7 |
                        output += fme7.Process( 2 )*vol[23];
3 i% ^! q7 T$ G: D                }
- a) Z* G; A( Y' o/ y! }" {* N0 V( a$ j
                output >>= 8;* i3 Z# X/ k9 N0 ~" c+ h, N

% b4 `" V/ j  c7 W                if( nFilterType == 1 ) {+ T9 Y" M7 F" ~9 f; |+ E8 m1 m! B
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
2 t$ t& L( E( W                        output = (lowpass_filter[0]+output)/2;
0 U5 \8 {. ^! J3 m% n; F8 a, T                        lowpass_filter[0] = output;
" F' n( J4 C; X3 |. w; i& C                } else if( nFilterType == 2 ) {4 U- _6 s' H1 q, n1 v/ ^
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
+ G* s6 u0 z$ A" |5 Q                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;$ X& y/ x% ^6 l! Q" z- `/ x5 q
                        lowpass_filter[1] = lowpass_filter[0];
8 T; U) f- r5 S# Y+ j) q4 r                        lowpass_filter[0] = output;
% R7 A8 }0 b& D                } else if( nFilterType == 3 ) {
; i& ~/ c9 g  Q: h                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)! `2 n4 Q$ q* p) r: c/ I1 y
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
: H2 p; y8 y, d* n5 |: O                        lowpass_filter[2] = lowpass_filter[1];+ c! ?. Y& @$ |. [, q. W2 d) y
                        lowpass_filter[1] = lowpass_filter[0];7 s; h7 e8 A5 R+ Z+ m+ G
                        lowpass_filter[0] = output;
8 y) ^+ U# z" t8 `. B2 P+ w                } else if( nFilterType == 4 ) {
  h- l8 x- h. y  H8 o+ q                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3), w9 D) m, @) U( E: \. m; \& }
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
* S6 c. I. {5 h: y                        lowpass_filter[1] = lowpass_filter[0];  C! O3 H* \' d; a5 S4 `; N7 W
                        lowpass_filter[0] = output;
/ Z% ]3 v8 ^9 D  q                }0 Y# g. z  R1 p8 K  X- X
& W9 Y6 V/ `' d/ z/ e2 ^
#if        03 N( f: v2 W  p8 z# [4 x
                // DC惉暘偺僇僢僩
  m, |% h) X# s7 f                {
& V! A" w1 p! I) z2 w* r. o) s                static double ave = 0.0, max=0.0, min=0.0;
  ~! s  l& a0 r8 W+ |                double delta;) e$ H! B4 @: l; ~  M: Z' R
                delta = (max-min)/32768.0;
: B$ h: n  g4 F. o: h0 p                max -= delta;
. V9 y: H3 g& c+ Q4 z, k% s                min += delta;
" Y+ U9 B# o/ t                if( output > max ) max = output;$ u' O) N, |3 [" y/ k" }7 J; K+ C
                if( output < min ) min = output;
0 E. N" ^$ a. a+ c: J# h                ave -= ave/1024.0;8 }. }# U, o. V* N- o. M
                ave += (max+min)/2048.0;3 l# o/ m/ l( O4 l
                output -= (INT)ave;
- w5 [% o5 @3 t$ `                }
3 d/ Q8 F7 f7 \" Y' D#endif
5 [: t5 t9 Q# Y; M6 z#if        1
, |' E1 i' a2 z# l                // DC惉暘偺僇僢僩(HPF TEST)
, d2 \# A, L! w! ~5 d                {% U" E0 a7 _4 T5 p4 x) |: `0 v
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);8 C. |9 \: F5 D8 L  q5 t
                static        double        cutofftemp = (2.0*3.141592653579*40.0);3 N$ L$ z& R3 Y+ [5 }" c) b
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
6 i. ]7 U. v) U; W% p) K/ h                static        double        tmp = 0.0;* U% e8 ~4 e* O8 s( Q' l% F' R6 d; D5 H
                double        in, out;
. Q+ [" l: U6 i% T3 M0 w8 J
6 d& L( Y: X0 {2 G                in = (double)output;
- x0 c7 Y+ [; v                out = (in - tmp);
' f3 q; v. J: H- l3 T9 n                tmp = tmp + cutoff * out;, O( o) L8 V; r& O

% j3 T: B; Q, Q8 r                output = (INT)out;
  g# F6 r* T; _& @) c( h                }1 `" q1 p& C; w* Y; w. F
#endif; j' f, A& ^- M6 b7 S% x9 G6 D* U; `4 F
#if        0
+ R; B  U- |+ G/ b' V* f1 U                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)/ i+ O% l* i' B/ r2 ~4 m: N; ]
                {
( x% d/ j" _; n. C5 n& _3 q1 p                INT        diff = abs(output-last_data);9 P1 c+ `: n' p) s( k
                if( diff > 0x4000 ) {7 B" `+ I* o7 J
                        output /= 4;# H+ {; V" D  p
                } else
' }2 K! |- p) ^6 w/ \                if( diff > 0x3000 ) {
0 U# _$ x4 A% \9 n5 W- X                        output /= 3;2 I) y5 ]! A- E& O6 w" I, U
                } else
  x0 K5 }5 l! P; \+ R- ^                if( diff > 0x2000 ) {& `5 K: F. f/ G/ v5 g# b: t
                        output /= 2;5 ]" f- x% b0 {5 R# @
                }
# E7 m1 o3 z3 G: M                last_data = output;
4 U4 ^1 X/ o: [9 N0 M: ^                }7 t& L. p) a, x1 O: Z, J
#endif
/ O. w! O, n$ g                // Limit
% A- j1 b! H+ Z* n+ z/ T                if( output > 0x7FFF ) {
) z- Z) N/ Y7 V' {; d                        output = 0x7FFF;
1 ?5 z0 A- {  L% C                } else if( output < -0x8000 ) {+ v5 C2 V8 C$ U' `
                        output = -0x8000;
$ ~( D$ H/ D. ]$ N$ j                }" a7 M3 ]! w/ ]  w
* T( _& i& A! e) j7 q1 j
                if( nBits != 8 ) {* j  j' V& a& R1 M0 Y* j
                        *(SHORT*)lpBuffer = (SHORT)output;  `* X/ V3 r+ o: i6 b" X* A* }
                        lpBuffer += sizeof(SHORT);
* ]/ H6 U& g/ e' F+ J/ V2 b- X                } else {
7 W* l6 R7 @% |% U* j! G                        *lpBuffer++ = (output>>8)^0x80;
. @" k- y; ^6 F) A3 t2 t# Y5 g                }
: @/ U1 K: A" Y6 u) z0 z3 h6 z7 s7 ?$ A% F7 K. N' T! c; z
                if( nCcount < 0x0100 )' l+ k5 f$ ^. I9 |5 b% O. V- g9 \" n
                        pSoundBuf[nCcount++] = (SHORT)output;0 B/ T6 `5 t: J( |% v: ?

! I0 q) U8 `1 l; Q- i//                elapsedtime += cycle_rate;
( M+ Q" ?$ {% k) Y  p8 [; j: a  C                elapsed_time += cycle_rate;
& f2 ^" ~: F# |. s        }
& C0 M; h/ m0 Z6 K- A3 z( F# D8 K# q/ a3 R- }* i# N% l
#if        1
8 P2 ~4 w9 B& t. U6 o, ~5 O( y3 a) g        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
; Z- H2 \/ k0 O4 j' S                elapsed_time = nes->cpu->GetTotalCycles();
- _0 _0 B" E1 b8 k2 p; w0 M        }& g/ j9 A% T) y) }8 v6 B3 m
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
& e6 |( |3 [' d. z                elapsed_time = nes->cpu->GetTotalCycles();
0 v9 v' }& s) F+ k        }* h2 {; O  @6 q6 t! N
#else- a" J) j/ H2 Y( O( j7 n
        elapsed_time = nes->cpu->GetTotalCycles();
) r) t' Y, ^7 k  `#endif
) k8 p" A  J( p6 k}" N7 k$ c/ f" T0 g9 ?" y

2 b! O3 [: _  B1 H# X! d  H// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
% [, b% D, K0 G! hINT        APU::GetChannelFrequency( INT no )
+ _9 P" R1 I" _$ r4 d  G0 G. e{; Y6 m1 y# I9 H0 Q+ B
        if( !m_bMute[0] )" I% g0 O$ l7 e2 R( p$ Z2 Q& u: T' m
                return        0;. g$ @- y5 p, E2 a/ q

% {3 \+ i$ p2 {) v& h        // Internal" ~0 _% s3 w+ U* g3 @
        if( no < 5 ) {+ c9 ~6 _' ]8 N/ e
                return        m_bMute[no+1]?internal.GetFreq( no ):0;# H+ v0 E" b7 L  d, u+ s7 d; l
        }
. ~! A, a2 B! t7 d        // VRC61 I+ }- _  G- V& Z0 W8 W3 }+ P
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
9 X" O, z! x% D+ x; ~                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;& c  e% C  o) ?3 t) v7 C7 w' C
        }
* z, F" m- S8 l. z- n& t' L0 {        // FDS+ E5 G# Y) n. `8 `) H& ?
        if( (exsound_select & 0x04) && no == 0x300 ) {! k7 z! @9 P) W5 K! E9 }7 ?" H
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
& i0 o- m. O- N, \5 v+ w        }
4 {4 h8 B  s# B4 ?' O  e        // MMC5* H7 Z- G; ?9 e9 C- V. A
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {" y3 H7 I: @9 {( |7 }" `, v
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
$ s3 r1 @! {4 t5 l# }0 Q        }5 o3 I' c' j/ J2 i
        // N106
9 w; G, A8 P2 f5 Y& ~        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
) l( k6 S- Z/ T7 _( J- b4 Y                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;2 N3 H4 d( M2 T, z3 _$ A
        }
) @$ {2 d" x/ `0 e/ N# b        // FME7
, l5 ]* M: B. R$ d' f0 r        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
" |4 ~3 M% @$ F                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
3 L" _) G/ Y' z. a  ^; N! P        }
9 W/ ]0 _  f0 X3 c8 }        // VRC74 u- a- [3 h; u0 g
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
6 |7 P3 l6 z2 i  t% C' c; q                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
2 A" B6 S$ E, L' Y$ R" A6 P8 S        }( Y+ C, V, }% ^
        return        0;
6 n" @* W+ P) T. f}
% S( |4 w% }" D# G! ]
* ~( @8 t5 d( Q/ s# Q& g+ ?2 a2 K  v// State Save/Load# b' \4 ~9 \8 K2 z% l  m' ?1 H2 `
void        APU::SaveState( LPBYTE p )
% Z, w- w* b4 x/ e{+ D" f8 o: ?( |+ o
#ifdef        _DEBUG- H* C0 l% t: q% ?" L% B: |  U
LPBYTE        pold = p;
0 h' M  I* R# _' B+ j! j9 V#endif
, H3 m/ m2 z( i' i. J+ f
2 Q3 Z- j1 K8 f0 H' g        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞% t+ X  H: Z6 m; H
        QueueFlush();  J4 s5 ]0 L, O; R" [; {

6 C' E5 r1 t/ |; ~# R& T        internal.SaveState( p );; }' ~6 c! j+ Y. e* k
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding% V$ o9 V& A0 c4 \) O6 ?# a
, P: s5 i6 G; C4 l3 T  F
        // VRC6
; W. V% }) B& v& x1 Q7 b* q2 d        if( exsound_select & 0x01 ) {
% M) \, R! q; }# p                vrc6.SaveState( p );0 K4 J: h% X/ h  M( `! q8 x- q, h
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
5 _( T+ Y9 a5 K8 C        }
' Y) _# o1 P* C        // VRC7 (not support)1 x% h; N( R3 M  t3 @
        if( exsound_select & 0x02 ) {
+ E$ k( c8 |. p5 a                vrc7.SaveState( p );
% k9 O6 S! _3 M3 b                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
3 ?/ v: p0 D( R7 n" V! _        }
- f# m0 I& N0 s8 U( x6 v        // FDS6 z* T5 |$ M- _6 Q
        if( exsound_select & 0x04 ) {, Q2 v: e6 M! }5 P: t1 T1 D
                fds.SaveState( p );
3 W; ^4 K8 C, P/ N/ z) _                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
" Q2 o, I. D% g. ]        }
; |, L+ m4 Z  b' G        // MMC5: b1 ?! W' |7 u, h5 w, p
        if( exsound_select & 0x08 ) {/ z0 o( ^" ~' [: a/ `* j
                mmc5.SaveState( p );
/ {, C7 s& e5 A7 A3 P: G% A                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding1 f3 U, q  V2 n! y; K3 j; L
        }
/ f+ r4 u0 m4 _* i, D3 b        // N106
) V0 T' O/ q( w' H! S! L        if( exsound_select & 0x10 ) {3 q$ {  K6 a. ~8 S" t8 f% q# U
                n106.SaveState( p );
! B; Q/ U8 K$ c, L! s2 ~; a) B0 E                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding$ y+ I% ]& x4 W# G; ^
        }' Y& i9 v. [( x- s# F
        // FME7
1 v) ~- Y5 Q; W; |        if( exsound_select & 0x20 ) {
- u# k! k: P3 C) l* e                fme7.SaveState( p );8 l7 H4 \$ V% o1 Z
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
. ~2 S2 ?/ U8 H/ Z0 f9 q        }# Y2 b% F6 ?! R4 `7 D' p1 o
9 Z6 C4 l9 R; D& U& m
#ifdef        _DEBUG+ x) X/ X( T$ X
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
" A/ X+ O6 s% i& L4 ]9 T7 _#endif
7 j8 W' t& a- c' g. R; @$ Z& w}9 f! H: b" N/ ^, x9 \/ V1 O

  Q1 F" r7 {* vvoid        APU::LoadState( LPBYTE p )2 I, D9 K& T  V2 e
{- P: i! t. {1 M. F% `% N2 K
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡6 }' X3 O6 i5 u" \& C+ ^" k
        QueueClear();: ]8 O! F  t4 X

+ q. v( \7 z& J" P2 c1 W7 w9 w; Q- m        internal.LoadState( p );% s4 `6 P9 `. _  `9 I
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding  R/ t7 W. k5 M; T5 A) g

3 d7 o& ?6 V0 \0 J. P        // VRC6
7 W/ ]: X/ x, j% h        if( exsound_select & 0x01 ) {2 U2 w/ I+ Q& s- F
                vrc6.LoadState( p );
5 }& h  o& K  H; L                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding) a7 O, q8 N; G8 \5 {  g2 D
        }
4 B4 j) L" y. a3 _+ f5 r& m        // VRC7 (not support)+ b3 C! d* _' h. Y; V4 h4 h9 R7 Z/ Q
        if( exsound_select & 0x02 ) {& h7 h6 E2 V$ O0 ~/ M1 s
                vrc7.LoadState( p );7 O' w; o3 U* ?1 S
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding9 n, R* _; b+ S, R
        }* [3 V; A* U- ^, I* k8 g% N
        // FDS( J# z# Q% i! _( l' q4 |
        if( exsound_select & 0x04 ) {2 d, b3 z0 Z( G, g; D" I
                fds.LoadState( p );8 u& F8 t: ~# [, {5 {& @0 l; F4 y
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding0 T% q$ F! U' y  R5 J
        }- T2 P( y! Y1 k% f
        // MMC5
& [* N7 o' Z) r        if( exsound_select & 0x08 ) {) O# o1 r3 g1 n3 V. L
                mmc5.LoadState( p );
; o4 C. V2 t; W6 ]                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
! J" ~7 _8 {! L' M$ c+ Y0 ~4 c& e        }
! r" t) B' e* a, J; Z3 [+ Y        // N106
7 v8 t) j7 O( r( `5 j        if( exsound_select & 0x10 ) {* E" a1 ]$ v, Y
                n106.LoadState( p );2 e- P# g; O: c. d& P
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding, d* ?+ `, e+ d2 {0 W
        }
4 `8 Y: A6 N" N7 n* s# P        // FME7
! y$ x- e' A) f, [0 l; S        if( exsound_select & 0x20 ) {9 O/ k; X; k7 {/ A) [- @- {
                fme7.LoadState( p );. J2 Y2 m& |8 _6 P& j0 \! [
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding" C8 a& l( r; ^+ v- A5 p  m% {
        }
9 X5 p: {6 O$ @% [: ^}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 ( U7 F  ~. A: d# D0 J
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
. M  a# x0 t1 m( ]  L1 x感激不尽~~

0 _4 z5 _8 a/ o5 `恩 我對模擬器不是很有研究,- W, N6 m4 y: X% s' Q9 T' w3 e
雖然要了解源碼內容,可能不是很困難,; k6 ^/ S' D. c- U: i3 f) j7 i
不過還是要花時間,個人目前蠻忙碌的。
7 k' s& S( r" b# u( g0 _" r' Z. H& i7 J4 E6 M1 l
給你一個朋友的MSN,你可以跟他討論看看,
5 g! L1 u6 d5 F2 W# s他本身是程式設計師,也對FC模擬器很有興趣。
! t% Q- W# o8 F, J4 }  V1 ]5 ]8 D3 e/ J' E. Y- v
MSN我就PM到你的信箱了。8 f& w' ?* l' f, o; V5 ?" l/ x

4 @2 y0 i8 {; Y# N. n: b希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
9 T3 a, D* E, O) D! p) N呵…… 谢过团长大人~~

8 {5 S# Y2 o5 D: M" w- x) D' a  F* v& ^, B4 J) K
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 $ `( X/ \% @- \
团长的朋友都是神,那团长就是神的boss。
4 L7 N/ u: Q2 m7 Y$ @7 T0 C7 m0 ?# {' Y
哈 不敢當,我只是個平凡人,
- ]% G9 f& x' }# ?' t0 k要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
- \7 ^5 ?4 N( Z$ v' x0 g. xZYH
5 N/ a/ M# w1 RQQ:414734306
$ e. k( p3 }* i7 aMail:zyh-01@126.com
) {5 ^7 m$ n# g9 `( ^' R8 t  n! v0 W8 ]: p, e$ x0 a2 }, y
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 # B9 d1 P3 H! F) x
再次对团长大人和悠悠哥的无私帮助表示感谢~~

% q- u; W- F$ p2 o/ ?6 U不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-31 06:53 , Processed in 1.092773 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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