EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。' A3 P2 p/ g+ I7 u. A
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
* n) B7 {2 _' V& ]  [6 \这里有相应的模拟器源码,就当送给大侠了~~  f6 P0 t8 K5 V" p% c/ r- d
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 # h7 n: b1 w2 ?6 y" t
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。' `1 K3 E0 q/ X
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~7 |: W' j" _  O* f, A( U
这里有相应的模拟器源码,就当送给大侠 ...
( F+ w4 t  R9 C5 [
聲音部分(Audoi Process Unit = APU):
1 _- D- [8 e& u.\NES\APU.cpp0 J& b; h* d- A& Q) a' G6 ]
.\NES\APU.h  k9 J6 N7 j3 E5 l! z: k: C8 Z

% O) v$ u, J* A5 Y5 z/ c8 V% O  G  V  O; J8 g+ }$ T
影像處理部份(Picture Processing Unit = PPU):9 J% a' k- x! Y8 w& u! ~
.\NES\PPU.cpp2 _. M, Z) c! D& m& L
.\NES\PPU.h
7 k, R  ~" u2 m  U9 _4 ?* Q/ l9 T0 T/ B! ~  _
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。' ~" t5 F2 `* S9 e# ~; [* _# d
感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
# |( @% w( [3 w(由于很多专用术语和算法机理都不明白,所以看不大懂……)
4 b; l' c6 e, L1 F! ~2 ?' }//////////////////////////////////////////////////////////////////////////6 v" g. |# f! k, r0 y1 l
//                                                                      //1 [+ g& z- @: P' |
//      NES APU core                                                    //( M$ J- H% l+ _! F- A, S( n
//                                                           Norix      //- j% s1 r8 p* `  K/ `
//                                               written     2002/06/27 //
7 E/ E% y! f* E9 P6 L( P5 h% ]! Z//                                               last modify ----/--/-- //; X9 s2 f! W7 F: }1 h2 |! ~) g
//////////////////////////////////////////////////////////////////////////3 R+ ]0 `: T9 `  d4 y
#include "DebugOut.h"
: @5 o/ U5 E: _#include "App.h"
/ x* Y: j. ?. t7 u#include "Config.h"! N2 H( B3 |4 g. n3 F; O* @
( {- a9 X) @, K  r' f6 [& r& l
#include "nes.h"
7 u  Y% s9 e9 Y% b1 Z1 [#include "mmu.h", L% e  H( P; H% D4 }
#include "cpu.h"
6 ]# D, F/ e  p2 L+ j#include "ppu.h"
/ A5 X: B* ~. b# ]! M3 V& }! a% N% D#include "rom.h"
" s6 o1 F5 F: y#include "apu.h"
9 l  a  h, [0 _& M1 l( }" P
( n+ @6 s" {3 ^& r// Volume adjust
" J* r2 L: L: l. S# g. ?// Internal sounds5 w+ c6 ]8 ?5 Q# g. I
#define        RECTANGLE_VOL        (0x0F0)
" T1 Y4 f: d" ]6 \#define        TRIANGLE_VOL        (0x130)8 t4 p  |9 J4 a- B( C+ Y
#define        NOISE_VOL        (0x0C0)8 o7 a9 f& |, ~3 P9 w) j
#define        DPCM_VOL        (0x0F0)0 {! R( y& D2 Z5 d
// Extra sounds. d8 n% m4 P2 h) A
#define        VRC6_VOL        (0x0F0)
# c3 Q" z/ N( J& _) J#define        VRC7_VOL        (0x130)8 }: C9 k. d3 `# E3 [# ], K: {! z
#define        FDS_VOL                (0x0F0)
6 ~0 Z1 f5 n+ @  C" K2 Y0 P" o#define        MMC5_VOL        (0x0F0)' X5 Z* |2 V9 Q8 [- `
#define        N106_VOL        (0x088)
% b" R8 D1 v/ e% x& i#define        FME7_VOL        (0x130)1 z* U0 \. E8 U" z( N7 C" E

+ Y+ u( L3 B; OAPU::APU( NES* parent )
1 e5 L& a$ S, Y( h0 w$ S{
- l* \+ u) n+ k6 e9 e        exsound_select = 0;
/ ~  ]9 N# u# C6 A+ F, ?, W$ y, Z
$ g% V* [' x- v- k/ X        nes = parent;
4 z; M& [# C8 R0 C  _0 m        internal.SetParent( parent );; D) W4 r" @/ P/ F$ A3 Q
; ?/ ^& |" R9 _; M3 i2 e
        last_data = last_diff = 0;/ u2 U4 Z* ?1 L4 R# ^. ^1 [2 s
/ c# _& a8 P+ g1 b. q0 T9 y! `
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
: d) x0 i" R& s4 M5 x6 G& i, A5 m
! ?. m, b2 y, ]3 q" u$ Y6 J        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
5 r9 \- C( ~1 Y; M' f! P2 u2 x        ZEROMEMORY( &queue, sizeof(queue) );. @& c  f- R- v/ ~/ p+ k: X. i
        ZEROMEMORY( &exqueue, sizeof(exqueue) );: t2 v7 ?  N! L. t, j, _! U) U/ w

" M- K4 O3 ~- k4 L* Y. [" a: y1 G        for( INT i = 0; i < 16; i++ ) {* ?! H. |# ?; a9 c9 u9 I7 U
                m_bMute = TRUE;$ p  S/ e  J3 q9 n
        }- h1 w% j  s1 ~, U) Q3 a/ s
}
& N0 o3 [; Y% n) N2 h) R6 K
  l5 E& u& f* @! d+ r6 m( ZAPU::~APU()
2 O: Y+ q( Y, Z! ~7 i{( \) e) y9 N! M" N( j, l
}9 l2 y! Q- m* c+ y; r6 |
* ~0 K, e: s: `- m! r
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
- v, f! C2 u$ D0 M{
4 I9 \% E& i( l! f3 {* C        queue.data[queue.wrptr].time = writetime;7 h0 t* H0 ~( e1 ~7 g$ i, X" T
        queue.data[queue.wrptr].addr = addr;
/ J, ]/ ?, H9 M5 a& H1 h- S4 l- R  w        queue.data[queue.wrptr].data = data;
, |. \4 {. b( {        queue.wrptr++;) V4 c# k- J! S) ~
        queue.wrptr&=QUEUE_LENGTH-1;: ]; {6 [+ s% r) R
        if( queue.wrptr == queue.rdptr ) {+ u; \% i9 f3 @  {6 l
                DEBUGOUT( "queue overflow.\n" );
4 A, a# e2 q4 @3 P, w3 P5 |        }& }! E8 U* [1 e: D9 h2 e
}4 j) m" x; m1 ]% e# }1 k$ Q
4 P, z% ~0 k+ p4 z0 E2 G
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )4 {3 `6 S$ q  R: i. J. I, w5 `4 ?6 A
{
4 r5 G5 m. m% B7 ?9 V( _  H        if( queue.wrptr == queue.rdptr ) {
' d5 X! p  H. i- ^- y% |                return        FALSE;+ b5 c' K; L6 d
        }
+ M7 f: Y& Z. A1 d, p$ M        if( queue.data[queue.rdptr].time <= writetime ) {
+ @5 e0 L+ Y- b) ~' M                ret = queue.data[queue.rdptr];
8 j( o* f  o1 s9 U7 ~  V$ j                queue.rdptr++;
" n/ R' y8 ?6 K' o                queue.rdptr&=QUEUE_LENGTH-1;0 l3 V- g2 j! f
                return        TRUE;  R: ~2 R6 d3 |: d7 }1 y
        }
! e& L' t$ [! Q        return        FALSE;" U' {. m$ k/ \" v  L
}
% ]; N( }; V* {: l
; ?6 Y' Q9 a4 l! g& ]6 X; Z) Svoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
( N: }9 u2 y* n/ x+ I4 Y& i- G3 P{" ]8 @+ q" B; D5 J- w- R3 I
        exqueue.data[exqueue.wrptr].time = writetime;/ |$ [& e" b2 Q+ b1 e# f
        exqueue.data[exqueue.wrptr].addr = addr;* b/ w1 D( e7 w6 ?8 B
        exqueue.data[exqueue.wrptr].data = data;
& N) H% B+ `  S$ O% ~" e! k& h1 L5 x        exqueue.wrptr++;! f5 p  E7 j1 f. ^
        exqueue.wrptr&=QUEUE_LENGTH-1;. l5 y* h+ U2 Y) f
        if( exqueue.wrptr == exqueue.rdptr ) {+ }  w2 ~" J* \: }& x
                DEBUGOUT( "exqueue overflow.\n" );, ^' a! c5 I0 u  V
        }
( U+ A8 Q+ L5 b9 m1 V}
- u! k4 C- D3 ~+ s
7 h- D  L2 n) y6 LBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
% u! `- x: j% G7 H6 D{
% i8 _9 _+ [) p7 k( k# x2 i, x        if( exqueue.wrptr == exqueue.rdptr ) {
9 _2 M- O# e$ t# G) P                return        FALSE;2 L/ n4 \4 t4 k# ~% q
        }
" P" v; `7 {5 g8 ]2 g# I        if( exqueue.data[exqueue.rdptr].time <= writetime ) {, [: p) |: y0 D3 d
                ret = exqueue.data[exqueue.rdptr];
; F0 h2 i. t- L% X                exqueue.rdptr++;5 b9 B7 V- D( |7 }
                exqueue.rdptr&=QUEUE_LENGTH-1;
. k4 j9 s3 z  j! e0 X+ v& O: K                return        TRUE;" X( a  ^# c1 C1 f5 j
        }
/ Q( ^9 b6 J" _! n: ^" c        return        FALSE;
  z# x. K& X' [2 O2 h0 Z* x- d  p}( [/ x1 ]6 p& H( i

4 N' U9 g: X1 ?" w' }+ Yvoid        APU::QueueClear()5 \7 c7 I5 R+ Q8 _7 a# f. X
{
; ^" G) ^. G# G5 ]        ZEROMEMORY( &queue, sizeof(queue) );
( B+ }, M* X( ^7 X        ZEROMEMORY( &exqueue, sizeof(exqueue) );" L$ n- t3 w8 i  o! {) h, |
}4 t2 d, J1 Z& ]0 N5 i

9 l- ~$ v' K5 _2 e1 P2 f- A8 Avoid        APU::QueueFlush()
5 C8 p% X; [  [; e* V{4 W8 Q/ {) K) N. z' `1 G
        while( queue.wrptr != queue.rdptr ) {, E3 i1 {1 W# H0 f8 [6 A8 e, E
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );; a' a$ u7 }* L. r
                queue.rdptr++;% }- b6 T, i8 w2 x
                queue.rdptr&=QUEUE_LENGTH-1;
3 i0 ~6 J$ q6 E        }5 m7 `. K# y( q- Q; t9 O, C

! v1 C0 s$ F' Y: |% ^        while( exqueue.wrptr != exqueue.rdptr ) {
! ]: [6 G7 e( l* e" W0 ?                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
3 w& T5 p# \$ q  u6 E8 }% x9 ^                exqueue.rdptr++;6 V7 E! {2 R, ^, ^% N" k' \1 T
                exqueue.rdptr&=QUEUE_LENGTH-1;1 }7 `7 h# g) S& @2 q+ G' N
        }) |( |8 K' X& s3 @. n% o7 w5 ^
}
2 t7 W  P* `. f+ `! t1 f5 a
" U' Y0 F1 c: Q, evoid        APU::SoundSetup()+ Y* _" p, a7 D/ S
{
' u5 V4 q* u8 x' l& P5 ^4 j        FLOAT        fClock = nes->nescfg->CpuClock;) ~  L  a5 ~3 C0 `3 W, S  g
        INT        nRate = (INT)Config.sound.nRate;; E% d6 u, n' B+ j
        internal.Setup( fClock, nRate );9 t" n; M0 p) i9 C0 K- S
        vrc6.Setup( fClock, nRate );
6 l  g% c, F& f9 E% H        vrc7.Setup( fClock, nRate );
2 @: t) C5 y$ r' a& \- b, D# [" C' I        mmc5.Setup( fClock, nRate );6 p) P: I, ^/ }* ^5 E' V2 [% t
        fds.Setup ( fClock, nRate );; t* _# a2 s" D/ x0 ]  I
        n106.Setup( fClock, nRate );
$ j: _3 K9 A" V" w3 E; ^" s        fme7.Setup( fClock, nRate );! V) L0 X* f- n
}
' a% v( T# x8 l! W$ E  \" i8 F* W7 a6 b: \) B) u/ P
void        APU::Reset()
* q2 X0 R) C7 k6 A{
/ [& S- K) j. ?) O. Z' h* x        ZEROMEMORY( &queue, sizeof(queue) );2 |7 b6 u& |! o$ a
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
! s% d  |, z- F
7 R) C) f, x* w, L# u( v2 q        elapsed_time = 0;
/ k/ |# Z! ?: ~3 D5 t! ~( E1 t
* q7 V, X! [# H' t* \        FLOAT        fClock = nes->nescfg->CpuClock;
& r# s' [. \# J5 t        INT        nRate = (INT)Config.sound.nRate;
3 A3 E8 @" _. Q  U9 W        internal.Reset( fClock, nRate );+ w1 a+ a+ [" z9 O6 v
        vrc6.Reset( fClock, nRate );
8 N/ l2 N2 U; N* t# A% k1 _6 r        vrc7.Reset( fClock, nRate );6 h* s. W0 b& l0 e$ s( `# I. c
        mmc5.Reset( fClock, nRate );
- ^; W# A7 z- `' [1 ^        fds.Reset ( fClock, nRate );
# e) S* C; }0 {' H/ a        n106.Reset( fClock, nRate );+ P. _3 ~2 A3 ^; h; a
        fme7.Reset( fClock, nRate );& h  _; a& M/ H) t; a
- E* p8 G/ Y0 ], ]
        SoundSetup();
) }* w" L' o2 O' B' G4 Q4 H/ n}
1 l3 n# |' O3 Z
+ T+ f# @0 V; N3 n: z4 X) S1 Jvoid        APU::SelectExSound( BYTE data )- e7 s% L9 e/ I1 z5 ?
{3 V+ m, r  }; W( w8 @
        exsound_select = data;
; o8 J6 L$ a# M7 z}3 N) M* U) ]5 p1 J2 P& C' S$ g$ ?* w

+ D; Q0 b' r3 q7 n4 e/ h$ j; l: D: ^BYTE        APU::Read( WORD addr ), r* [7 z3 E+ U2 q5 i; `* \6 b) \7 T
{0 l$ \) v: ?1 {7 h9 r6 v% V1 {
        return        internal.SyncRead( addr );
( x3 n2 m( p9 {( k7 v6 n}& v/ c/ O5 p8 V6 v9 j
  v0 C5 o, r& P* q
void        APU::Write( WORD addr, BYTE data )- M( D1 r0 i: Y# L
{. q6 s' F9 ~8 X) c
        // $4018偼VirtuaNES屌桳億乕僩
5 e1 @, R7 ^. R  D. m        if( addr >= 0x4000 && addr <= 0x401F ) {2 S, H% Y0 e  W. A3 P" R7 v! D
                internal.SyncWrite( addr, data );% [$ N0 W- F. s; ?: V
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );) T9 V: l0 {' c6 \: A, c
        }" C; G' C* T7 `
}! K1 J3 S/ \: z& ^

" d; h. c- s; b+ TBYTE        APU::ExRead( WORD addr ), ^( ?! E! v5 `% w
{% z. z- D+ }* v
BYTE        data = 0;+ Q, C+ S- `2 N9 L

" x( f% L" q% A3 U: i        if( exsound_select & 0x10 ) {6 p3 _. ^: T) _2 E4 @' f
                if( addr == 0x4800 ) {
- y2 ?% e5 T" ~' y! j6 V                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );+ J4 j8 J) |7 R6 j  J/ r2 q
                }
& n1 w; X! T- ]5 [1 W        }( |. g- y6 a; {% M" d+ p5 `1 G
        if( exsound_select & 0x04 ) {0 j. ?6 a' q7 J
                if( addr >= 0x4040 && addr < 0x4100 ) {8 @/ Q- A( \7 c3 }  _
                        data = fds.SyncRead( addr );
5 G( B; U% i# F/ E# g5 ^! a0 p                }
5 |9 H- F5 V3 E! X0 z5 q        }; X  |* _8 ]  k. u( Z
        if( exsound_select & 0x08 ) {3 i; Z; q3 T- k: F
                if( addr >= 0x5000 && addr <= 0x5015 ) {' Q8 |( _: [$ W1 @" Q/ a4 r$ [
                        data = mmc5.SyncRead( addr );
6 o8 O( ^3 W8 v) W! L                }
! M8 Z- |3 ]9 Y3 O  R, i        }
- v' x2 L4 ]  l" _" i( K  Q: U0 \+ E" z8 T0 u5 B# w: Y$ T
        return        data;
6 Q5 p1 h( L- a1 {. o4 J}
. u- z% c6 W' Q0 G: k- M/ P: M/ B& e6 R" q
void        APU::ExWrite( WORD addr, BYTE data )
; F; n2 h2 P/ r% o0 n% f/ i- W{
8 J4 Q9 t( P0 z) k5 L1 n7 A2 e        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );9 ^3 C7 A( e" n: B$ t. I3 o

/ F  v6 c3 I+ M* U        if( exsound_select & 0x04 ) {
" _! J+ Z6 i8 P. }/ V                if( addr >= 0x4040 && addr < 0x4100 ) {4 }# ^. d( K) j
                        fds.SyncWrite( addr, data );
, {; m. ]( F" u- D                }
: ~6 I8 D" T* Y2 \        }% L5 f( I8 c8 Z7 T" o! u

: L) f2 s4 B  M! g) `7 x  V. W6 |- ?2 J        if( exsound_select & 0x08 ) {
/ `4 M5 Y5 H+ \                if( addr >= 0x5000 && addr <= 0x5015 ) {
  y) D4 r6 v" l$ K# Y                        mmc5.SyncWrite( addr, data );
1 A1 N( \) {- {) [1 s/ G                }
& _- g, c, `& n! L0 ?/ J' W' G        }
  x( o  m. {/ a. @- s}
) K0 O( S  ?* A' Q* B% k* z$ x+ ?3 N0 t* T8 Y
void        APU::Sync()1 N- y2 c' Z; Q
{
: ]9 m) [% m2 i4 U- y* x/ F% e}3 a3 B' W+ l6 d3 w$ j
* \; f  a6 j5 o" A) u* w) U
void        APU::SyncDPCM( INT cycles )
/ s0 n  x* `9 Q{1 p$ i( a: D3 X) g. w4 b
        internal.Sync( cycles );% G0 m! ?, T3 w# {% h) \. B2 Z

* `/ ^( s9 i% L! }/ j        if( exsound_select & 0x04 ) {
% v9 f  d: g( [                fds.Sync( cycles );
3 N- c; T$ C# P+ q8 h9 ]        }+ `' I! y% z( }$ Q1 l# N: i
        if( exsound_select & 0x08 ) {  s; R! Q' D( z+ ?
                mmc5.Sync( cycles );( {. k/ g1 E1 f( i: F
        }
" t6 r5 A) r8 S3 j' l! M" R. W4 l. B}7 f; M8 F7 e; L% e* L4 B; I# _. v
. p. v5 A2 h+ A& }6 {0 [
void        APU::WriteProcess( WORD addr, BYTE data )
# b* Q! Y" w' ~! W: Z{( y4 t! q1 `7 o7 B- j
        // $4018偼VirtuaNES屌桳億乕僩# h4 R5 P4 v( d
        if( addr >= 0x4000 && addr <= 0x401F ) {
( E/ x- H1 A& Z' |6 _9 a                internal.Write( addr, data );/ K# M) v5 f8 Q+ \7 {( H
        }
0 H" f( x" a3 }}  k$ `! s; X( q+ q+ f8 ^
$ r; d. g1 O# P. U  n* }
void        APU::WriteExProcess( WORD addr, BYTE data )5 [+ G/ T" H9 n& G- Y: _
{
/ ^$ x. a& f, h        if( exsound_select & 0x01 ) {
- d8 y' b7 I  @) s& T                vrc6.Write( addr, data );
4 j: J) S$ k% K$ w1 h: }        }
& A# [4 B; g$ r1 B        if( exsound_select & 0x02 ) {
) `$ M$ m6 P' z) w% [$ {: h& M                vrc7.Write( addr, data );7 }) U# W5 r$ |+ h* Y; e" ^- p% J
        }& }5 s9 J7 c% g0 z7 w
        if( exsound_select & 0x04 ) {
& @- F. E) ]  x4 Y                fds.Write( addr, data );
& v3 ?  F% p# u        }( }! ~7 f9 M2 P2 {9 v) Y
        if( exsound_select & 0x08 ) {0 h" g4 w8 r, d. \: Z& b
                mmc5.Write( addr, data );; I& F3 J. a, o: K/ P
        }
6 t7 h1 r+ P* T, k9 v        if( exsound_select & 0x10 ) {
/ |/ i: h  K. r+ J7 x: o4 A) `                if( addr == 0x0000 ) {& \; ?9 O& ~* Z
                        BYTE        dummy = n106.Read( addr );
0 O9 S  ]* d: `' C6 Q' I2 z  {+ u                } else {
8 Z: k* |( }/ o% A3 \# `0 i% V                        n106.Write( addr, data );) T2 f" x5 H: K& w
                }+ D9 @' H0 T+ C1 N  m
        }
# u1 B' ?$ H" j7 k) k1 j        if( exsound_select & 0x20 ) {, ^: H1 e$ K, B6 f7 f
                fme7.Write( addr, data );
+ R6 Q4 ?, `3 O% G, ]        }8 B, A; f1 u  I4 A3 K
}
9 T2 x% U; ~3 d! Z0 \5 Y
# j" |7 Q4 l6 v+ Z, ^  U8 ?. pvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
% K! m8 U* f& q  M9 H{
" s( i$ P" R$ ?4 S  sINT        nBits = Config.sound.nBits;
& j# D+ _" j8 y2 F0 ADWORD        dwLength = dwSize / (nBits/8);- v8 q2 w- M- \4 o7 F5 k
INT        output;
. ]" M- X2 R" H5 {5 B8 L$ BQUEUEDATA q;0 a% Z- O# D8 M; N6 P, f0 d% ~# B
DWORD        writetime;8 u+ j6 C3 Q* r# R! z2 ?% t9 }2 _

+ @' c8 z# L( X! H1 s2 N; nLPSHORT        pSoundBuf = m_SoundBuffer;
2 h) {3 u5 [& P5 z2 bINT        nCcount = 0;
2 f/ M0 `$ `. p+ U& }$ @8 x* y6 L% o
INT        nFilterType = Config.sound.nFilterType;  x0 k8 n6 M" c' i8 S2 X
0 B. T# _! i% V# X3 Q( \8 n' R
        if( !Config.sound.bEnable ) {9 b" r  m) @# B$ F' @7 f
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );# H0 a- u" S5 C, J, K7 b5 V7 e
                return;* _* m2 ^# Y: t* ?% F
        }/ U% A$ E8 A; R3 \8 C
6 C% S" q  e9 N
        // Volume setup/ k5 ~" v: Z# o$ C; k1 j
        //  0:Master( Q8 V+ z3 k; m' H& i% i5 v
        //  1:Rectangle 1
3 W+ L5 D& M$ n7 Z        //  2:Rectangle 2
7 k6 E( U$ `4 K5 p7 X7 U1 x9 O        //  3:Triangle* Z2 o  V1 K$ z2 `
        //  4:Noise
; [& r* E! D# \, d5 R5 B/ z. z        //  5:DPCM
1 Y7 T% y2 U, N* a9 d        //  6:VRC65 W0 M0 F) d5 `9 H6 f
        //  7:VRC7
7 o! h. f# V5 t, M: O9 A7 T0 w! y        //  8:FDS# B4 f6 j; X0 N; r0 Z
        //  9:MMC5$ F3 u" _; O4 P. q/ Y
        // 10:N106
5 B  g. j4 W7 ?8 b) s& G) l        // 11:FME70 I& K+ M% ^+ k2 C" O
        INT        vol[24];
9 z. [5 I! x* D6 h' S* V) E" j% @        BOOL*        bMute = m_bMute;
' U( B4 F% q7 ?3 L4 `! v( m6 I2 m        SHORT*        nVolume = Config.sound.nVolume;
* d  c9 N1 a5 W4 z$ Q  w
' F: [; c+ b" `, o0 A        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
6 C  l5 j+ F1 O$ N0 E+ T. ?. Y, n/ L5 }+ H1 M
        // Internal
+ W5 x7 Y4 L; a# W5 q, Q0 Z. N' W        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
2 J) X6 J7 [& x        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
3 H" z6 U2 b' |9 m; [2 `- P        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;: N4 l0 q9 I' h1 W6 t7 e+ S" n$ p
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
: L) z% b1 k* x! C& X2 x        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
! [6 k7 n9 M2 Z/ Z; J6 J5 k8 s# f: J/ }6 \
        // VRC65 Z" P9 f  ]4 V* {! R* b
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;% `( a% h7 I6 G: R! i3 ~
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;; c! L9 }8 Y  u- j( n! `2 Z1 R, k
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;1 \& D; H) n9 [" j" f

: O/ G* I3 [+ d' n" }8 F3 V        // VRC7: p+ I% n8 I* X% x' |  \' h8 p
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
9 W3 w9 o' Q& S& i+ i  X' \5 f* w" \
        // FDS: C, D; u0 \1 ^1 Z" }; d7 g9 A/ L5 T
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;6 Y& S* u0 ~: }# n, W% W1 M3 S
4 A9 g# `! n% Y2 n# w0 y
        // MMC5
! C. v$ r+ ?; C. E        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
& K  e& b0 j* e- U; Z/ T# l        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;. j+ V/ @+ R& A4 D
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;- u% x1 Z# R5 @) w$ h
7 z* a" p- e+ c& h- ^
        // N106( V4 L; g# ~1 q7 V7 R- S0 ]8 ?& \
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;4 \, P: b1 E# Z4 R: C
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' b, p' n. _* C& v, v! C$ n4 ]+ U
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
* O$ ^1 q4 l/ H( D        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;6 x# l$ \( }* b5 o1 x7 _
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;4 D/ c$ T  h% K8 H; q4 q% \
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;3 r! w7 b: k/ Z& E
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;& |' F, |' L6 ~, ^" e3 O
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 i6 N6 c: _# h! n" f. w6 A7 M; f
, _' l3 ~" W) z6 W4 Y( b
        // FME7
4 h* Y( C: Y1 [' M8 I# h        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
2 v- _) w8 j8 E3 I; S        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
" v& W( s2 L5 h4 ?8 Z; o* a        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
& C7 d. A6 w- ?( B% K; U5 K9 X( ~5 [9 W* [4 ?
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
+ I$ V- G+ @0 [) q5 U& G        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
) M2 Y( P) z: m! f) l' Z
: S/ p' L7 \# y4 l        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
- r9 E* k, I6 V3 T3 @        if( elapsed_time > nes->cpu->GetTotalCycles() ) {6 T% p+ @3 R$ c
                QueueFlush();) r3 |: W# r* ~; b+ S/ e: `
        }2 S8 y+ f9 N# z, O2 B
/ @. L! Z" F3 w( L& N, g; C" q
        while( dwLength-- ) {/ h, S$ t0 o9 o6 `% S) ]+ ?7 A
                writetime = (DWORD)elapsed_time;
' i9 \3 H& w' e# g2 W% @: L7 C9 \% e  G( z
                while( GetQueue( writetime, q ) ) {3 o( M, G0 Y+ l0 H/ k0 B( O
                        WriteProcess( q.addr, q.data );
5 b  v! c& J# Q3 A. C7 k                }
/ H, j' e- a$ I8 O" |) i% Q9 f2 L7 E" K4 ~: x- ~, n" L
                while( GetExQueue( writetime, q ) ) {
9 z) c7 O; x" I                        WriteExProcess( q.addr, q.data );
0 ~0 k$ F9 s7 h# [4 r                }0 ]) \" x$ ^* t, k$ r' s

4 r8 L: _. @( e- d$ n                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
9 }9 C" U5 i: ^% G8 `                output = 0;
6 \' o2 U6 }1 A                output += internal.Process( 0 )*vol[0];4 f0 J5 i/ z9 H6 R6 S0 S: D3 i
                output += internal.Process( 1 )*vol[1];
! U: L# W/ @+ O( }                output += internal.Process( 2 )*vol[2];
, q4 F% L. j2 v" [                output += internal.Process( 3 )*vol[3];
6 F3 P! J0 d1 R* N. v                output += internal.Process( 4 )*vol[4];
  [$ K$ J9 ]# y6 ?9 n$ L9 i# [3 ?; [4 T+ u( I
                if( exsound_select & 0x01 ) {, C: U8 K% M# x8 ^) `- u& F( W' O7 A
                        output += vrc6.Process( 0 )*vol[5];
. S; `8 [2 V1 Q' C8 c+ w                        output += vrc6.Process( 1 )*vol[6];5 @% Q3 U2 b  P* z
                        output += vrc6.Process( 2 )*vol[7];
4 c) e6 F7 G) q2 [; S3 `' v                }
: |1 @% G0 q! U0 I+ u. I                if( exsound_select & 0x02 ) {; Q. x: t. t/ ?2 E1 |
                        output += vrc7.Process( 0 )*vol[8];
+ L( d) B, n! K5 A                }
3 u8 I+ P; L: p$ v5 p- |& x                if( exsound_select & 0x04 ) {% F2 |5 m+ E' J* V
                        output += fds.Process( 0 )*vol[9];9 c5 A( G+ M) [! q( u% L7 O; j
                }* Z5 g# R2 s( L# ^2 U' W' H! X
                if( exsound_select & 0x08 ) {
$ w8 m( @: E" |+ |/ J* K                        output += mmc5.Process( 0 )*vol[10];
. r7 b0 {9 u1 P6 q/ @* V                        output += mmc5.Process( 1 )*vol[11];- T% W3 [2 D  Z
                        output += mmc5.Process( 2 )*vol[12];- t. S+ N7 p6 j( M3 R2 _: o
                }0 d1 R) @& i2 z. g
                if( exsound_select & 0x10 ) {! y" K( R+ L8 C
                        output += n106.Process( 0 )*vol[13];+ \. J- c9 R) K* i% n5 ~$ ~" V
                        output += n106.Process( 1 )*vol[14];2 z5 b7 G7 a7 k
                        output += n106.Process( 2 )*vol[15];, f( s5 ~! Q4 n$ Q. q+ B
                        output += n106.Process( 3 )*vol[16];
- E3 K) |" k1 _0 X3 O                        output += n106.Process( 4 )*vol[17];9 E  p3 B/ v6 g0 @( r; f
                        output += n106.Process( 5 )*vol[18];2 j4 T% p0 v+ ^4 D1 Q; j8 Z- c' p
                        output += n106.Process( 6 )*vol[19];  M) D; M; h6 V  \% _
                        output += n106.Process( 7 )*vol[20];
* H: P6 `  a% q                }
3 }5 |1 m. w- z+ j8 r                if( exsound_select & 0x20 ) {! m: ^) `$ H! a' |: {* S
                        fme7.Process( 3 );        // Envelope & Noise
, z- s/ Z& L+ A4 r7 t6 _6 k2 F6 S                        output += fme7.Process( 0 )*vol[21];
) F4 g4 q) g! n# n8 G                        output += fme7.Process( 1 )*vol[22];/ V3 _% x- L- }  C5 ~& t
                        output += fme7.Process( 2 )*vol[23];  u- ^- e1 k  M6 m
                }6 M4 I% v/ w# X7 E! J7 z
& p) ^$ W; z1 q% @4 J: S$ M: T
                output >>= 8;
% R( S8 `; M; X% B( E1 B2 L: ]. t+ Z! m5 H- Z
                if( nFilterType == 1 ) {4 L4 P% L3 V2 S( V
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
$ ]2 I7 }- `0 r. c6 ]                        output = (lowpass_filter[0]+output)/2;
1 k7 i/ e8 {; A1 u. _, I' T' C: ^+ \                        lowpass_filter[0] = output;
! q$ M) X8 v9 j) p$ ]1 h2 C6 ?                } else if( nFilterType == 2 ) {9 Z( Z' i, ?0 `- U- k: C" Y
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)9 S2 t) Y% l& ]" I" H. i
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;. @( E3 S; `7 S0 [: g
                        lowpass_filter[1] = lowpass_filter[0];
' C2 }- ]; M7 Q: S! z                        lowpass_filter[0] = output;
& }6 ~) }# j; z7 R. r) V, s( E                } else if( nFilterType == 3 ) {* ^" W3 ^! s* m$ n; B" a/ \" u
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)# h9 Y: j6 E- ?  K. V
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
- F3 c* R4 x% h                        lowpass_filter[2] = lowpass_filter[1];
/ M1 m: u( y/ a0 l5 S4 l                        lowpass_filter[1] = lowpass_filter[0];
6 _3 P( r' s( C6 j6 n                        lowpass_filter[0] = output;
; q0 Q  G! m0 k5 s$ o8 Q                } else if( nFilterType == 4 ) {9 S; c0 G# l6 R. A# N8 ^: t
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
0 ?4 k8 y" ?) p* i& |+ ]                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
( n1 M  E7 u: s! _                        lowpass_filter[1] = lowpass_filter[0];
2 H2 A' N8 Y% }. R/ Z/ Y                        lowpass_filter[0] = output;1 \0 r% N: t0 c
                }) s* k3 T. s3 K( ^* o7 g/ g9 @$ R6 z

- e) X3 s* ?  E1 J# o" f* i#if        0
. s2 a# g' c7 M* H  R                // DC惉暘偺僇僢僩
/ S! j3 A  V7 K$ _+ S                {
  w& ^# |. S# ~9 ]3 u                static double ave = 0.0, max=0.0, min=0.0;
& z3 f. f, z1 w                double delta;+ u% I- \" \$ ?0 n* ?0 k: v! o
                delta = (max-min)/32768.0;
, f0 |5 q  o5 Q% j6 n                max -= delta;
2 \3 Z( ^' p  {8 B: C                min += delta;, I0 Z4 P* U8 {, \( @$ s
                if( output > max ) max = output;
4 o- R1 v# L) S                if( output < min ) min = output;
1 _% ^; L) ^! \; n7 K- T                ave -= ave/1024.0;, S& S  [) ^2 }5 P- S
                ave += (max+min)/2048.0;
9 }( u* G- E  r) O; a                output -= (INT)ave;
- T+ z' z! I* }; |+ \: U                }0 d+ F9 x3 ]. S# Q; z, I
#endif) d* v& u, |# L6 J0 s
#if        1
7 e; |0 j% w: e  X& n                // DC惉暘偺僇僢僩(HPF TEST)1 I# |5 W5 f6 J- P: J$ G$ l$ \4 w
                {7 F2 `" y3 t1 j& R
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
" D+ O: i; P' j                static        double        cutofftemp = (2.0*3.141592653579*40.0);
# m# }4 v7 \; J& I( c( b" x2 y                double        cutoff = cutofftemp/(double)Config.sound.nRate;
$ A+ p& z; X2 }8 z                static        double        tmp = 0.0;
* n& U  E4 l  z, q' u                double        in, out;
. v' d- u3 n2 C8 l1 _: o% ]
* F% a3 m4 r: E, L! t+ E7 Y$ k5 {                in = (double)output;
4 Z* _% i' z) J, U8 a! r                out = (in - tmp);& ?7 m- ^4 \3 p
                tmp = tmp + cutoff * out;
! M8 d. h* n7 B8 I+ ^
: d1 l+ @/ ]3 Q. X* K                output = (INT)out;% C0 M! n6 S/ U7 d6 }
                }7 x9 c& S" B- B/ i& x, f# j
#endif
" w) A+ J& X/ {1 P( v  z9 o#if        00 K% c! x, }9 K* t' |4 O5 Z' R
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
  k2 u' H% P- X2 ~6 T                {
( j$ u3 U: H1 H/ W                INT        diff = abs(output-last_data);
) ^( G7 s0 a, @- L  @3 m5 C                if( diff > 0x4000 ) {" d" {! e, y9 r
                        output /= 4;
  z& ], J" O6 n                } else
6 G( s3 r: F7 P" i                if( diff > 0x3000 ) {( N. ^) J. k% ]/ @, T; ]
                        output /= 3;' F* S$ F" `9 A9 K. U+ R+ c  F
                } else1 [/ j" i6 l% |* T1 a! b: B
                if( diff > 0x2000 ) {
( i% M, S1 _- A6 k                        output /= 2;/ ^6 B9 u; a. D: s4 ^* u  M
                }8 M( Z! F, `8 Z7 K
                last_data = output;
/ n2 X8 u  X! _5 Q( K  g( j* ~                }
! [- ~7 G- G" z4 x  q# D#endif0 ~7 [8 Z, U" o) {1 [! I& s
                // Limit
9 E, H6 ?- i. B                if( output > 0x7FFF ) {8 _3 z4 |' q" u* T8 P
                        output = 0x7FFF;
+ a. |( q2 [6 l% e0 Y, l                } else if( output < -0x8000 ) {
$ Y, N- a' z# n" \                        output = -0x8000;
) S& W  H- {' {& V  M                }
3 ?% h$ H1 b* ^3 U: e2 z! J1 x
, N6 M) r. h7 M! L6 b                if( nBits != 8 ) {
; f& d0 {& k$ b" V                        *(SHORT*)lpBuffer = (SHORT)output;. h5 W6 }9 h! l' M& i+ C
                        lpBuffer += sizeof(SHORT);7 X/ h; C' w) H0 y/ e
                } else {
- k% n7 m, R+ J" `                        *lpBuffer++ = (output>>8)^0x80;
" ~8 _2 p7 R; W! s3 M' x                }
! Y, H, V, A5 B; A* L! h, {, e$ j8 R2 \/ W( c: P
                if( nCcount < 0x0100 )
6 T- |! O( @% |: X% N) |                        pSoundBuf[nCcount++] = (SHORT)output;
$ ?7 M  {/ u/ [: j5 g& j$ j0 K2 K; j" e: ?# e
//                elapsedtime += cycle_rate;" K+ J5 t( i2 ?9 ]
                elapsed_time += cycle_rate;0 m/ S7 g; P; B" T+ F  F
        }
2 s6 I; e) d. S, B* T: I4 z8 b5 \3 B6 b$ i
#if        1% n: d0 I. y$ }; T$ M
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {( x# F3 B7 d5 m: r6 ~$ ^& b
                elapsed_time = nes->cpu->GetTotalCycles();
8 ?$ H! {7 p1 b4 w! v  E6 ~0 Y) z! `        }
. `- N! {% h0 n$ w/ t) B        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
' t5 G( [( Y" I, p& D: Y                elapsed_time = nes->cpu->GetTotalCycles();6 {8 w2 M8 J% G2 @: F
        }5 L+ S3 m! Y; \* n0 A2 m/ z5 Y, ?
#else
: {1 L) p" X3 k- r' H  X1 R% o        elapsed_time = nes->cpu->GetTotalCycles();' `6 s% Z3 u9 ?; m! h5 X6 i7 M
#endif
8 h( [& ^; D+ x0 O! Y}9 ]$ p3 M9 ?" J( ?
# S# `  R8 Z+ g- `
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)3 p$ B7 _8 @: E- |' f
INT        APU::GetChannelFrequency( INT no )5 B% U' B# S3 C; b. N7 R8 j9 c( b
{
8 s, {9 r0 X  ~9 I, m6 H        if( !m_bMute[0] )
$ p  D8 \9 Z) D$ G; t                return        0;8 `* W- e' f7 p; _# i( l/ v
  @" S( J8 g! \: ]3 D+ P& f7 g* N7 j/ @
        // Internal
! t( Z8 K# t6 l3 J# V, X! Z2 U        if( no < 5 ) {
2 R3 `# D0 X  L4 ]3 {; t+ A( Z" E                return        m_bMute[no+1]?internal.GetFreq( no ):0;) {7 Y8 C# |/ e
        }/ \" |8 G8 v; z- y
        // VRC6
- f8 u9 a1 {( f1 @1 M% g        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {- y5 B% c5 G! p0 |2 j' ^. p
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;6 R8 r: O0 J: v
        }
5 I/ _3 R, R+ i6 S        // FDS
" H) h( n, H3 e# X) N# \        if( (exsound_select & 0x04) && no == 0x300 ) {
, l) [2 Z5 f1 w1 L" ]6 v8 L                return        m_bMute[6]?fds.GetFreq( 0 ):0;5 `$ q1 ^) {7 F/ a7 y1 ]
        }
' }$ a5 z! i& O$ U2 x! j        // MMC5
  [7 E, T0 x. w1 E        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {, c3 R1 K% z8 @& A6 X1 ]
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;, Y$ b. c! G; [9 i  n: L
        }. m, }% ]. W7 r: O" m3 N. U+ y2 q2 h" k
        // N106- b% K4 S; {: b% @$ Q1 D
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {2 f( j# B. ]" h2 O$ ]5 C; `8 j
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;4 Z+ e; d$ ~% v
        }
( y1 J  }( B: y8 L" e        // FME7, Y: B' u! U! K
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
: [' k; g/ S5 U1 O2 @. j" D                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;7 k0 l: D4 e6 d& d
        }
4 g+ ?+ t" I3 r0 Y: v1 A        // VRC7
$ c" h) D+ Y4 c' N) k  d$ p) j        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
# Z& S( y, {0 C' }                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;# v; S' }1 H& V. t! V$ w* X9 k
        }
  X6 S; m8 B9 X! J! z1 I* U        return        0;$ m. ^2 F' U" L. {# m" G
}
3 A& P/ {! \+ o" t2 L
& N- s* S; ~6 P1 ?+ f! M  j// State Save/Load
. c3 b3 o& \! n# p& R* \void        APU::SaveState( LPBYTE p )* |, y4 P, {6 F9 v. W6 Y7 t& ]
{
7 M6 \# x% I+ t#ifdef        _DEBUG
- O* Q- }" D% B8 iLPBYTE        pold = p;
* k! w, d# o' n' w% {#endif
7 l6 S, ?7 u1 Z1 `) j/ b8 |, _2 ]3 _+ ]
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞" d/ ?" E9 a% n" e+ g5 |
        QueueFlush();5 I6 J( V: }# l; M( `! t7 E5 T

0 z$ o5 E* g$ m% C# [' V* J        internal.SaveState( p );
' s9 `" T) G' I3 H5 w        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
& ?- h  w2 b9 y, k  B
$ F6 Z; y' z( ^+ g        // VRC6
; U# C8 ^4 ?, K3 Q2 U7 ~' F5 ^        if( exsound_select & 0x01 ) {
% i0 Y- D' n9 t& L                vrc6.SaveState( p );
) ?+ D+ e) Z" H- t) r                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding$ F1 }2 P2 h2 L) r3 s- _6 j! E
        }) o, f2 r, s" L  ?+ n6 N, c( _$ f
        // VRC7 (not support)& ?/ q, P- c' c# C! w: f2 I+ K
        if( exsound_select & 0x02 ) {
0 x& V' V. p# Z  G  ~! U) k                vrc7.SaveState( p );
# Y. l; K$ l, X& l                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
! V  U' W  K- f6 d6 b+ f$ Y        }
7 R! \% b* {2 h        // FDS% `, l  N( H2 c4 C
        if( exsound_select & 0x04 ) {
9 T/ L# J1 P. ~  I: t                fds.SaveState( p );, L3 g* n/ o# D1 d! a
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
" b" Z: A) ]* V6 {9 K& g        }
8 B% `* N$ q, ]9 S2 `& J        // MMC5
  o# Y5 o1 y# r* ?" L! x        if( exsound_select & 0x08 ) {; I1 d3 n5 r, P. i9 x5 g4 k- j
                mmc5.SaveState( p );. h2 K# J, s/ ?% Q
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
' S0 F  z1 Z7 ~5 j        }
/ E" A% ^- I2 e5 e1 n1 ~        // N106( A0 W* p, J& [# h9 l/ B7 K
        if( exsound_select & 0x10 ) {
: L/ x* S0 }6 ?                n106.SaveState( p );$ R7 U& w& p0 `
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
+ p! {' X; g; I$ a) c' k        }" |, v/ H. H) D- [+ m& l
        // FME72 j9 b5 J/ T! d& l4 L+ @6 H- G
        if( exsound_select & 0x20 ) {! g7 M0 G2 p- D7 P) k) r2 ^
                fme7.SaveState( p );) |2 e' {9 {- R- f9 D1 T
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
# P+ B1 ]5 V: _6 d- ^% K7 ~6 e2 F- d' _        }5 p, k8 m% h9 F- ]8 V0 ^3 Q
; C% V) \: E6 s8 w  R0 Z9 S4 F$ q
#ifdef        _DEBUG$ \, s. C- Z% P* W' G
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );. d7 e% N( V* G9 n
#endif
2 a! J. U( `3 u& |! O" c}7 E! t  {8 |. A
& d3 \9 |; H% `0 a4 C  E- v) c4 l& s
void        APU::LoadState( LPBYTE p )3 A, N0 W5 O: ~7 Q! b
{% ~% n$ F7 y1 [
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
6 t- H, |) Q/ d; S) j3 r( s; u        QueueClear();
. w7 o; h1 ~  @; Q+ c
! S8 s/ d4 O5 [        internal.LoadState( p );
' V0 S: z: G6 h5 }; y! f$ o        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
/ o" e- Z/ U* a+ g9 |5 w# C* Y; \7 i4 L
        // VRC6# S; J( H" P( q9 ~1 W
        if( exsound_select & 0x01 ) {% a" c7 y1 ?, A# x) @" P
                vrc6.LoadState( p );
, Y9 r! B& u, j$ B7 @0 N& R5 V. t0 [                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
" _3 w* s3 b# C5 J0 C" X: Z        }3 Z: D6 t; t  u. Q2 p& c* u4 w
        // VRC7 (not support)
+ ^: f+ g  h/ v% s4 Q2 T) w& P        if( exsound_select & 0x02 ) {: X. m( d! ]# s% N% k5 U
                vrc7.LoadState( p );
3 @0 E( {; \+ q                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding7 G; ]# s; W4 p3 A4 z7 s
        }7 j4 @* A2 Y6 [3 _
        // FDS
7 d$ j/ r) q# K7 B, Y) E5 B$ L8 F6 u        if( exsound_select & 0x04 ) {/ ^/ g1 I( l5 V' S5 x
                fds.LoadState( p );1 R9 V( {/ G" ]* |$ B8 D" q) |3 V
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
& R" Q; }2 T; Q4 N        }- Z* ^4 Y+ \- t
        // MMC5+ D" P% v$ {( U2 E9 H* D7 S; m
        if( exsound_select & 0x08 ) {
7 H  [  V5 j6 h9 {5 X2 `1 W/ u3 t. n7 b                mmc5.LoadState( p );+ M0 _. L4 i+ c4 H
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
# t+ u' c% K/ H% i/ q        }
8 E( K6 L  y! N+ u0 w" k* {        // N1065 X: I! ~& ~% O+ j9 M5 ]
        if( exsound_select & 0x10 ) {) Z8 k/ H; y* g4 ]
                n106.LoadState( p );
1 Y- i0 g' _4 ^5 w2 _* _* y                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding0 {% w/ A$ ?8 W5 D" G4 D- J7 o6 h
        }+ S, S0 d$ _2 z5 r/ z: Q2 T
        // FME7
; [" }, \- X5 T' V& D8 I/ L        if( exsound_select & 0x20 ) {
  P, j7 v% @1 \! W8 Z% n! q                fme7.LoadState( p );1 P" N+ n8 ^! O3 c) c9 d
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding7 o: U. T& e; a* f
        }
  a  D" s+ _+ J9 A}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
" N1 r3 u( r) k( n可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
3 F; v/ Y  R$ E& |感激不尽~~

5 E, {( ^( l6 e" }4 ]% w恩 我對模擬器不是很有研究,* z3 q' y- ^3 Z0 V' `$ U6 D( ^
雖然要了解源碼內容,可能不是很困難,
% [3 @, H/ O3 _  R5 u6 Q* @不過還是要花時間,個人目前蠻忙碌的。( e! @  k" v: }6 G+ I" N
7 L0 g% c% A2 v# b5 Y  s5 \
給你一個朋友的MSN,你可以跟他討論看看,
, c. }! H9 c3 U  O6 Y7 m( C他本身是程式設計師,也對FC模擬器很有興趣。9 N) k* F0 |0 b2 b; \6 K* w6 y8 y

1 `& Z4 }2 _$ F% B/ wMSN我就PM到你的信箱了。+ ?( N3 ~/ k$ c5 q2 v
8 u, [/ j- j, @$ j
希望你能有所得。

该用户从未签到

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

签到天数: 80 天

[LV.6]常住居民II

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

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表
; N" X, K$ B6 h0 K+ D呵…… 谢过团长大人~~
7 |  C) Q. l% a. p: L  {5 B

- q" ?; R2 B" [  R  [) Q, \哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 : O2 y( x" k3 X* x8 @: `
团长的朋友都是神,那团长就是神的boss。

+ V! t- W$ v3 O) R哈 不敢當,我只是個平凡人,) ^5 O  Z1 y9 F; {
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
6 X" o* m. ^' p8 G. {! R  |& b( Y: a6 BZYH6 I1 A5 {7 u$ v& w9 E" }
QQ:414734306
6 S% }+ f* y7 K7 yMail:zyh-01@126.com
3 I& y* _4 R3 k  y; I0 g
# v; m% {% o) [( ]5 ]& P* U他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
9 C) f! @1 n5 ]4 a再次对团长大人和悠悠哥的无私帮助表示感谢~~

  j  X7 u) |: f8 W5 t% D不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-9 01:44 , Processed in 1.082031 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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