EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。4 F& K! s$ ~. l7 g+ [. g, R
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
1 D  M1 }2 X% g4 h6 G( K这里有相应的模拟器源码,就当送给大侠了~~
7 {. z; Y5 ^( ]  y- @5 d' u4 jhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
3 `* h! b4 T* e! a; r9 K能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。0 H5 n2 |& r+ ^( q2 x/ Y+ D( @
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
( ~, K2 t7 F/ ^0 y; k4 I/ @! E这里有相应的模拟器源码,就当送给大侠 ...

7 i% o. B* b* ?. e9 r6 Y  E聲音部分(Audoi Process Unit = APU):
9 v8 Y& _' r- G+ d.\NES\APU.cpp
  Y8 o! V) d& t% ]9 J" R.\NES\APU.h+ p# i+ u; c8 t, w' J$ N% ]
* ]& T' m: p$ I& e+ K3 T" `+ J- [

2 \& o$ d5 _% _# v+ W, _+ a影像處理部份(Picture Processing Unit = PPU):
! K2 I' j) u9 b$ r.\NES\PPU.cpp
6 @' R; P0 ]( l4 k0 @8 {- R.\NES\PPU.h
0 n6 ^7 P5 D0 J4 S# K- l, k- [: _# i2 Z. M: Q% I1 o
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:; `1 `$ E. B$ H+ A
(由于很多专用术语和算法机理都不明白,所以看不大懂……)0 Z! N7 n; d- h7 l6 e. p) T
//////////////////////////////////////////////////////////////////////////% ?& v- K$ B+ f1 q
//                                                                      //
0 f3 Y' P  {/ P) [/ @0 p  D5 m0 z; R//      NES APU core                                                    //
2 K5 u/ b. b9 j2 e//                                                           Norix      //8 Y1 T' ^9 Z) y9 H4 C
//                                               written     2002/06/27 //% h" E' a$ |2 z+ S
//                                               last modify ----/--/-- //
0 u& b4 ^3 L) a& O% ~//////////////////////////////////////////////////////////////////////////, U. d1 h2 Y5 A  q$ Y
#include "DebugOut.h"7 \' S/ n) H) ?6 f% C2 L
#include "App.h"! N9 [/ S5 l9 f6 s9 n
#include "Config.h"
# X* B( a7 U: Z* z, U( E* D8 |! E7 V; k6 O
#include "nes.h"
) J1 u3 M2 u9 J1 A: E  J#include "mmu.h"+ L- }0 a4 J* h% i/ O' a" q& d
#include "cpu.h"
/ l: u* {: {8 b6 }- I#include "ppu.h"0 y9 n1 {1 h$ g6 u9 Y1 y
#include "rom.h". s) x/ F7 {; ~5 Z! x
#include "apu.h"1 R7 {" Q2 Y3 D+ f: R

& e8 }' L' Q0 u4 A; c// Volume adjust! Y  u8 k6 f' Y# s
// Internal sounds
9 M4 X2 J3 n* V+ Z#define        RECTANGLE_VOL        (0x0F0)
0 V, h6 {: G$ z% |1 X, u#define        TRIANGLE_VOL        (0x130)0 D- j  g4 Q( N0 {0 [
#define        NOISE_VOL        (0x0C0): w2 [0 a- Z2 F( w. c0 Z* c3 k3 Z
#define        DPCM_VOL        (0x0F0)
$ p/ M/ @7 a7 ^  p  q// Extra sounds
4 _* t" D' a7 G* l  C#define        VRC6_VOL        (0x0F0)0 c7 \$ ?' S1 h6 D$ t3 q
#define        VRC7_VOL        (0x130)$ _7 Z$ ?! z" y4 ]1 B4 Z/ _. {+ q
#define        FDS_VOL                (0x0F0)
3 N! ]- _: a( L/ k- r#define        MMC5_VOL        (0x0F0)! |7 d' o5 z! h& K# [
#define        N106_VOL        (0x088)+ C+ d0 G9 s1 E# @2 K* m
#define        FME7_VOL        (0x130)
2 O) P: B4 B9 G, }  h
2 C! ~" t$ h9 p- P& t4 v' pAPU::APU( NES* parent )
  _, I9 N9 b  F% X/ x{
& S2 B; w3 y2 P, ?        exsound_select = 0;
- A8 i  s3 n/ v/ [5 u8 b3 S, y7 G! r) t6 l5 R
        nes = parent;3 ^. b2 f: k, u0 j# ~! r
        internal.SetParent( parent );
4 s8 V8 o1 S$ ~- w+ b
& P3 h, u: K. J7 }, _. R        last_data = last_diff = 0;
! x6 S/ T, P$ u( _- ?; t! W* t) d" P% W! ^/ }' o5 S* o
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );4 @* P% W, u) {5 v
  m8 `2 u) @$ w( D# j; }( G$ N
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );7 v8 I$ O! I: W2 Z/ C( T) B3 Y
        ZEROMEMORY( &queue, sizeof(queue) );2 c$ P1 d# }1 G$ B" B# y4 g3 _* P
        ZEROMEMORY( &exqueue, sizeof(exqueue) );" o# I5 \/ g! w9 H% \( o
7 Z- {5 ?  \+ l; P
        for( INT i = 0; i < 16; i++ ) {
7 ^- D1 b6 p. s6 i                m_bMute = TRUE;
- F5 y* R' m2 y        }: s8 ]3 K6 f1 b
}+ k+ {; _  x! w

9 i2 ~( U" e/ e3 v9 n4 gAPU::~APU()
- F( F- C/ y: Z6 c! X9 @- c: S# a; o{, f3 I2 N" d8 J5 a) f& V& A2 R
}1 p% L1 c4 f* `% S) g

4 q5 j6 m0 o0 V8 S9 ~void        APU::SetQueue( INT writetime, WORD addr, BYTE data )/ G2 g8 t) b6 w" ^* `% k
{
/ p. G+ X: o" X/ z- h. E" S- ^        queue.data[queue.wrptr].time = writetime;
( ~, v( n2 }) p- G        queue.data[queue.wrptr].addr = addr;: f6 j2 a+ ~; C  X, P1 ?
        queue.data[queue.wrptr].data = data;: @: ]6 m* h3 Y2 A3 L* B0 r
        queue.wrptr++;
8 L+ M4 p: I5 p) I6 r8 u        queue.wrptr&=QUEUE_LENGTH-1;
5 B6 e/ b: v/ [4 r* [        if( queue.wrptr == queue.rdptr ) {
4 J, g% r' j# w                DEBUGOUT( "queue overflow.\n" );
0 h/ E8 S: _$ G" g        }
; Y0 D' Z* t, J) S4 S}" c/ D9 C# J' W$ R3 V% `, e
5 x# ^, |6 K6 D9 y, f  v- u; X
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )! e2 w* c# H& ?% [/ n7 X
{
  d1 P2 w# H+ D1 K        if( queue.wrptr == queue.rdptr ) {+ [3 p% E# b% w4 R+ q4 l
                return        FALSE;
, @/ c# m% L  f6 T4 ?% y9 h9 W        }# c3 @. X3 v7 [9 p
        if( queue.data[queue.rdptr].time <= writetime ) {
# K4 ]6 W$ j, {                ret = queue.data[queue.rdptr];
! k3 F# k5 A' N                queue.rdptr++;
' C7 t& b! X9 t# i: A! d                queue.rdptr&=QUEUE_LENGTH-1;
" Y  ~# Y  p5 ^                return        TRUE;5 S% Y8 }+ y( v% g
        }
5 }$ r6 a. P. t3 E  w        return        FALSE;" e2 J' ?% g/ |  i5 J% [2 _
}( s8 T' N1 K' z9 J  i6 j

# z$ S0 e/ a& nvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )( g# `# e& [: W5 ^
{
  C# f" |+ g3 M% ]! {8 v! G        exqueue.data[exqueue.wrptr].time = writetime;* B% H9 B# \& g
        exqueue.data[exqueue.wrptr].addr = addr;: m% s2 C( G  B
        exqueue.data[exqueue.wrptr].data = data;
8 |& b. d) h/ j1 ?: z4 K        exqueue.wrptr++;
* x9 k' S3 e' g: _0 U" e        exqueue.wrptr&=QUEUE_LENGTH-1;4 N: P$ R2 b- @/ n9 [2 f
        if( exqueue.wrptr == exqueue.rdptr ) {
2 t+ Z" ~9 R$ l) ~8 ?9 A                DEBUGOUT( "exqueue overflow.\n" );3 ]3 Y' Y# y* ?. ?2 h
        }
, X/ y$ I) E, f6 |: S5 h8 y}' P( C/ b: [: w& C( A1 h

- Y- u; e" M6 j$ a- Y* {$ Q; kBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret ): v2 {3 ]* t: ~: W4 ^" V
{
) V9 A, v8 d9 y: p/ ]        if( exqueue.wrptr == exqueue.rdptr ) {
' ~! j0 c! ~1 t- c2 R                return        FALSE;
" u! l* I7 a9 r! |: h        }9 U1 U( ?  B8 J# G
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
3 Z. h% d& d. r; T# R. q                ret = exqueue.data[exqueue.rdptr];0 e7 H3 j/ n! V4 @
                exqueue.rdptr++;2 N6 ]- p# F. Z0 T1 P' L$ C) H7 H
                exqueue.rdptr&=QUEUE_LENGTH-1;& y! a1 l; Q8 r3 `3 D
                return        TRUE;
+ P) {$ i) ]5 k6 n. S" \        }
9 v* y  \/ T6 X4 w/ U3 Y        return        FALSE;
; T: C7 F2 A: a9 g}
* l; ]$ M8 `0 e6 [8 q0 l: K  F1 k- c1 Z" h- X3 Z
void        APU::QueueClear()
# m8 Y/ t' P' a! u  H{( l3 d8 M8 `& q3 _4 R4 N" ~9 q
        ZEROMEMORY( &queue, sizeof(queue) );
1 w+ Y& o0 B3 r3 d! S4 t( W0 W        ZEROMEMORY( &exqueue, sizeof(exqueue) );+ C' x9 H1 q( h( A8 {/ g
}
7 `; a& c2 |! m- ]. R: R# R7 G% I3 F  X$ ~4 o1 B9 M) {
void        APU::QueueFlush()
9 N# \% `9 c( t0 k. P0 O; j{
9 Q! t7 i1 \2 w: c) L2 J( F2 ~9 \        while( queue.wrptr != queue.rdptr ) {
$ e0 c! h5 _; X                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
2 N' X% L: q% X  [, k! H                queue.rdptr++;% T- d1 z. M( w+ I" U+ ~7 i
                queue.rdptr&=QUEUE_LENGTH-1;( ^9 C8 p2 F/ l, h' L0 t7 ^
        }, Q: E5 J) g; S2 d. v
& f( T# w) Q9 J6 H; V
        while( exqueue.wrptr != exqueue.rdptr ) {
' }8 D' A2 o3 ]& I. ~                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );/ \4 N) h  u. D4 y/ B
                exqueue.rdptr++;* x, v) ^) P% Q( L1 X+ Q
                exqueue.rdptr&=QUEUE_LENGTH-1;) E, b3 C# Q5 M5 N. _
        }' z% Q3 P4 r- f# M  L
}
' Q( \, B( f' s3 J" X/ }4 K4 {4 ~! R3 E# J8 V5 R
void        APU::SoundSetup()
( n* S% X* Y9 v{
: B( c4 |9 |7 z4 K9 p1 I7 B        FLOAT        fClock = nes->nescfg->CpuClock;
7 B4 q! n. i' ?# I  @0 M5 s1 G        INT        nRate = (INT)Config.sound.nRate;
2 i. O2 Y' A8 S2 S$ q        internal.Setup( fClock, nRate );  j! i% O  Y. y- F  c) r3 F) o( L
        vrc6.Setup( fClock, nRate );
- Q: X! S$ A7 z  w# \3 m* a. N, m; z        vrc7.Setup( fClock, nRate );$ J' I) G+ G8 E5 K
        mmc5.Setup( fClock, nRate );
2 z$ p$ d1 Z  B: @( T( E        fds.Setup ( fClock, nRate );
; H: D& L) s; E) L  ^  W! P        n106.Setup( fClock, nRate );2 F" g7 w& \, }% U9 y, I
        fme7.Setup( fClock, nRate );
" U" f9 L0 }2 x}
$ @2 e$ O. p0 V( a" a- R5 {" a% U1 K  y6 m
void        APU::Reset()
! \7 \9 P& l) v9 k  Y{
) _* E0 @* q2 `5 ~- o+ X/ x$ o1 b" r        ZEROMEMORY( &queue, sizeof(queue) );2 ~  q8 }$ D/ S, B+ @( C
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
  I- p6 l1 O  V! l. Q
. T$ O  O9 r& v4 y) w6 W        elapsed_time = 0;
3 E6 [9 X1 D* Y( M7 X. c8 b$ z; a5 U# \
        FLOAT        fClock = nes->nescfg->CpuClock;
- m. ?4 C8 {- @        INT        nRate = (INT)Config.sound.nRate;0 X' c) W* ], h! Q8 z: t/ A( i
        internal.Reset( fClock, nRate );
# k2 o7 s# k) q9 T8 T        vrc6.Reset( fClock, nRate );
! h: A9 w8 L4 ^, t        vrc7.Reset( fClock, nRate );
' W5 J7 W* }# o; I4 ^1 q; K% |+ L        mmc5.Reset( fClock, nRate );, F$ `8 N, G& d9 Q
        fds.Reset ( fClock, nRate );; U8 }& r4 h- s9 ?  x8 Z+ u3 Z
        n106.Reset( fClock, nRate );
+ i  N% R, n) c! p( ^        fme7.Reset( fClock, nRate );
+ _# a/ C) `2 r1 Q
5 `+ b* b: }/ [; ?- m        SoundSetup();2 g  J% y7 u7 a6 `7 e& t# }+ ^
}
  G0 y9 ^, ~% N4 l" W) B( S1 }- K# b$ d  h' f6 L: d' d# {5 O
void        APU::SelectExSound( BYTE data )4 @5 E" |; ]/ ?! q
{4 c, X, ~' E1 A
        exsound_select = data;
( n5 J  j! d; \' ?}2 W# ?! P, d- w4 q9 S+ I0 C
! `% b  ]( ]& j3 c
BYTE        APU::Read( WORD addr )  P) n9 q6 k; n$ |
{
4 V) P7 W* {4 Y1 V$ g        return        internal.SyncRead( addr );
$ T- x1 `/ K+ C+ P4 F}
$ R% a. ]. }- [5 B! l+ j* ?& y+ d2 l2 i! x
void        APU::Write( WORD addr, BYTE data )
+ R6 ?( w! g# J- R3 J; ~: o9 D' x9 t{  C4 g8 w3 I+ f/ \$ F: I5 C% }4 P
        // $4018偼VirtuaNES屌桳億乕僩, u( I: Y5 z# x" S& ~% K( T4 d
        if( addr >= 0x4000 && addr <= 0x401F ) {
; U. \( b$ O6 a; b+ i                internal.SyncWrite( addr, data );
, Z& k; ]  }) }) s, Q: x4 t                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
! l; F$ d- \7 x: x# t7 @1 r        }
1 U5 v4 A# d1 f1 s! H- l}
# m. |" x& y  o; t) L  N' Q- i% M% k( A8 C, O
BYTE        APU::ExRead( WORD addr )
8 B+ p4 q6 F8 J% `3 r{
8 X+ H! P% r  MBYTE        data = 0;, ~  V- F  E( V/ b8 I3 u& B

9 N( s* O7 B2 I        if( exsound_select & 0x10 ) {7 a+ E; l& H$ p- i
                if( addr == 0x4800 ) {& j( k* t  ?) ?# ~) n& v8 Q
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
- I2 c; s, ^& Z1 }2 C- S- \                }
$ O  U: _; @" p) \7 W. X* f8 r        }+ K0 _) a" \- q+ H
        if( exsound_select & 0x04 ) {
: }$ ]0 g" }8 k# w  C3 }                if( addr >= 0x4040 && addr < 0x4100 ) {& r% Y* K  n6 o4 V: k2 b& t9 k* H: P5 o
                        data = fds.SyncRead( addr );$ W1 S$ D5 p" w, ^9 S$ n
                }9 t2 o% e( Y, r7 x5 \) s
        }1 ^) k4 C8 f3 J0 N, _5 I
        if( exsound_select & 0x08 ) {
. d( \3 S( P  D                if( addr >= 0x5000 && addr <= 0x5015 ) {# I) E; ?5 Q1 t1 x& K) b
                        data = mmc5.SyncRead( addr );0 W4 A; \+ Y% y1 K
                }) R+ i! L. [9 T) d9 r* c  j
        }
5 X5 o- `; m$ g5 B+ j; h9 R/ o: n+ f. O8 A7 i; m
        return        data;& Q( N0 ]7 ]5 ~  {2 `+ J* W9 {
}
% g5 v# E( D3 u, O
7 }# B# A4 [, B3 g* Mvoid        APU::ExWrite( WORD addr, BYTE data )
3 w5 m: o& ]/ M  [! N{
% \' B7 X( b3 Q% i4 c) S8 A        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
+ B7 |4 M0 G' D) Z3 y9 f1 s5 N
7 ]2 V9 U% ?1 {0 \- W- |7 o        if( exsound_select & 0x04 ) {
+ P' T$ g& G# c) v& G                if( addr >= 0x4040 && addr < 0x4100 ) {/ U" `# ~& ^6 Z
                        fds.SyncWrite( addr, data );
6 n8 ?  [3 ^9 j2 [5 H                }) J, E) T' m( z$ f' n# Y
        }
; G) B: m1 m. v/ `; h
) U7 q4 _1 E$ M0 z/ T: l' x4 [        if( exsound_select & 0x08 ) {) J2 @& ~5 T# `" C) X
                if( addr >= 0x5000 && addr <= 0x5015 ) {4 w7 S# c' j3 _; P* T
                        mmc5.SyncWrite( addr, data );2 o. m- @) W) H- c+ d* H$ Q$ }
                }1 u: \5 g( P' i* z2 W6 H- n
        }4 ~6 @5 f. ~3 p! B( L6 |
}
% `) O4 m* ]6 I/ ]! w  Y
( U0 M. s9 g7 J2 U' Kvoid        APU::Sync()# ~7 P; Z* n1 c1 w+ I4 [4 J6 F
{
9 F- ?$ c) @' ~' U! s/ D0 |}
* w: K% m+ A1 o* @4 S1 X' |$ f0 ?
void        APU::SyncDPCM( INT cycles )
2 t- B. g' Z7 y* y6 m{
1 m* m! `5 {9 h( k% g6 s        internal.Sync( cycles );" Y7 K) _/ C4 h" W4 J( Z
" F. v! Z0 _) L3 w: e# h/ u
        if( exsound_select & 0x04 ) {
+ u& F8 `$ c  b3 E, s                fds.Sync( cycles );
) U% T/ G0 I6 |) O' Z5 S        }
* q* V7 `+ i2 Q" O( q1 j        if( exsound_select & 0x08 ) {2 G$ B% @5 z. k! X
                mmc5.Sync( cycles );
: N1 S4 ^- w4 D1 k        }$ U- K+ H) ~+ ?( Q8 A4 w  L
}* C4 p8 {& N* a8 E7 P. L8 _$ [

8 L5 \; _% j$ T$ dvoid        APU::WriteProcess( WORD addr, BYTE data )9 l" v7 `% j5 h! x% g
{
% V) @9 ?, w% t: R$ Q3 R        // $4018偼VirtuaNES屌桳億乕僩% [: ?! i7 x) i" v, F
        if( addr >= 0x4000 && addr <= 0x401F ) {* A2 K. {% f( [0 {3 t) g# X/ R
                internal.Write( addr, data );5 b& M6 I( m: D% h
        }; Q3 X' \0 n+ j1 P. Y+ w
}6 P6 v' s, G7 p: ^

8 k* r; x; T' d0 }void        APU::WriteExProcess( WORD addr, BYTE data )
1 x& [4 E* _" l6 {# V6 |{
7 U( {: e0 [8 Y7 |        if( exsound_select & 0x01 ) {
% m7 Y8 Q& u, B3 ~' w# ^/ \                vrc6.Write( addr, data );& h5 l, U# l: T9 h; P# [
        }, A; l8 h/ j  c- r2 {$ D) @. Q
        if( exsound_select & 0x02 ) {
" }" w" S- b: i# L' D' J4 W7 c1 `. @                vrc7.Write( addr, data );# A; j! j2 F1 V5 r
        }
9 T2 R- p; F" t        if( exsound_select & 0x04 ) {
+ B: U) C4 L# b6 v                fds.Write( addr, data );, [& ~" Y  u( W/ {
        }3 Y3 i% M5 u- y6 G1 \0 w; X
        if( exsound_select & 0x08 ) {
% g1 D, O1 p# {  \" R1 ]                mmc5.Write( addr, data );. ]; E4 _5 [0 e
        }) D3 a# D7 C; X8 v
        if( exsound_select & 0x10 ) {
  _  @) O) B6 `! X% ?# a6 D6 L                if( addr == 0x0000 ) {9 k$ m: p( C8 m* \3 f/ f* J9 }
                        BYTE        dummy = n106.Read( addr );
# o9 b5 ^* `, j! X                } else {- S: }1 K" Y% G# M9 V: s
                        n106.Write( addr, data );
$ ]( c0 M3 n* i                }0 T+ V5 V+ k! J9 q: H
        }
0 h) S0 G. b/ U6 B) W7 _5 a0 e" @        if( exsound_select & 0x20 ) {
) {2 }+ W1 h( f; Q: ^                fme7.Write( addr, data );( B; ~2 p+ M. x  p/ i; o8 F
        }% I2 X- v- Z1 N3 u4 Z/ c
}3 B" U* S$ A" r; H' y& a8 A5 z
0 G$ L1 m. n' E. J0 y' Q) b7 g4 ~
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
3 V3 a, S7 s+ s. Z6 l{  D* b5 e( a) }/ s% [; i. k8 R; T
INT        nBits = Config.sound.nBits;* {3 T( u1 w$ y# ^; N
DWORD        dwLength = dwSize / (nBits/8);5 [7 D5 Y: a/ p* r4 {3 D! C+ a
INT        output;4 k- I& b  k6 j. v/ n' p+ y
QUEUEDATA q;
2 q) O7 `% `& A5 a1 f! @DWORD        writetime;
5 c% y5 I) J! ^* |, v; h
  Z8 f, y5 r& WLPSHORT        pSoundBuf = m_SoundBuffer;
# e, C" ~$ D" F; ^INT        nCcount = 0;
' k& l5 u' Q2 S+ u
) k1 L: X( Z; y- lINT        nFilterType = Config.sound.nFilterType;
0 ~$ t4 X* ?: k0 S
7 |$ X7 j  o! R5 Q        if( !Config.sound.bEnable ) {
/ y* h# W! V; L! b, Y" L  M                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );; z( v* r! b" ^- \% a" {
                return;0 q+ m! r( \/ z' u
        }7 S3 P7 }/ Q* C$ `) h

, E: W; l$ f$ s  t" O  f        // Volume setup: l0 H# g6 Z/ ]/ ]  t. D
        //  0:Master! n% P* Y9 y, l# i8 k& E- I% ?5 K
        //  1:Rectangle 1
& _# n& h! I  K" Y9 B/ K, v        //  2:Rectangle 25 u$ G+ F) H! u) E, F6 r5 ~7 k. }
        //  3:Triangle. Z* ~6 ]. Z8 \9 H& ^7 j- s
        //  4:Noise
, q" D) K; H% u4 d$ ?        //  5:DPCM
: y$ y# L0 p* ]; q0 j        //  6:VRC6
2 X6 g6 N& O2 O4 p" e        //  7:VRC7/ f4 w9 Q2 W1 G7 J5 Q4 T0 a
        //  8:FDS
- n6 s9 x% h$ w4 J; f  c* r        //  9:MMC5
9 D4 ]- L0 @6 F% C& b        // 10:N106
7 Y  t& ]1 x: S" A" [$ p% c  \- v! m        // 11:FME7
) A. @6 P/ Q- i# j3 l% w        INT        vol[24];
0 a, ]- R, N0 o# m+ L" ]  ^        BOOL*        bMute = m_bMute;; t0 h2 t9 Y6 G. A9 R5 `0 D. k
        SHORT*        nVolume = Config.sound.nVolume;
, L: ?- z! `6 |0 k0 k) \4 O6 M5 \  K2 g( I
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;9 t8 D* |( E# c5 L+ L

3 `3 q$ A( |4 K+ [" d! S2 {        // Internal
0 X( z: Z, _# N8 M        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;4 [9 n/ f$ B# _  ]* G0 b
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;' }  m- w% e8 R  R  D* l. c
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;9 e+ X4 ^* g7 L' J2 p; Y2 z
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
3 q+ O) p1 l; y% ]& p: ^5 e  B  x        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
; h# X7 X) E5 N1 P- o' k
$ X3 j$ Q% c6 L* }        // VRC6
6 B9 g2 h3 b0 X0 c9 P9 r. Z5 D; A        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
% y) ~5 k$ @7 u+ l2 |5 S        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
9 d. t, b3 {- E. \" g        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;  q; e: ~) K5 [- ^* J

, s+ l7 ?$ {% w$ t        // VRC7/ }* G5 D, v9 Q" ?) j
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;  U9 ]! `/ k3 _1 I% w
& y" G0 a+ J1 O: A- W
        // FDS
, s- g2 N+ o" i, c        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;1 y: h. V/ V$ t: @* |
, N9 u/ m$ F2 Q2 a# v; X; L; L
        // MMC5- H2 e: N0 ^7 a' a4 _1 {
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;7 ?# A; ^3 {+ P! C0 p* I
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;" n. U  G0 a" Q
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
$ Q' T3 D  r  {% [# f, u6 G6 k' x+ r' N0 `6 R* r2 K
        // N1060 R; Q4 X9 Y5 z9 J1 ^- p! Z6 W
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;" P! h2 L; {! E7 r$ V& e$ x3 @. T" _) L
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
/ p# o5 d; y1 x& K        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- d7 U6 Z$ K; K7 `
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;% ?% ?+ M( z$ x* Y
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& A% v( w. s0 F/ B  v        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;/ R/ ~. p& O6 _
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' b8 @( v! d$ `) v: v4 y
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;  L6 x$ c+ E9 o& E( }& [; V
3 {. n3 m" U% N6 i% j; T8 i
        // FME7
5 h, d) o, c) i( U! d! F" R" Z        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;' l  f# q* T! J
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
5 j- L+ {; ~3 ?' j* \* [# j        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;2 S6 I) a& z0 {

2 J1 n0 ?6 c: s4 K8 i! J7 L//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;9 a9 G0 O9 x" a
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
0 {  r. ]& t! _1 N4 Y. Q" H% O1 R; Y7 k
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
. o' g5 ?, o" I6 m        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
# ], d: S9 f& K4 ^                QueueFlush();
# A/ ?$ _! \# p# j7 o5 J        }/ @5 E+ ?2 y, ~( ^" @% V

4 V; b6 E" H3 k8 |; A. P        while( dwLength-- ) {
- X; M! i; D& e) R2 g9 a9 D9 P                writetime = (DWORD)elapsed_time;
5 S( h2 _, G3 N; j3 d) |
- E$ J1 f+ Z3 @' r4 v# \' e                while( GetQueue( writetime, q ) ) {
- E) k( K; D4 s( z% [& j: K2 c                        WriteProcess( q.addr, q.data );! L+ s9 @1 A4 |4 S
                }/ Z' u7 ^' k/ ~3 W
" c5 r0 \  |, g( \
                while( GetExQueue( writetime, q ) ) {
* i. [& \' t- E/ d: x. K" O- Q3 S                        WriteExProcess( q.addr, q.data );
4 C; E% u9 Z; |                }
( C# {4 N9 R! A* Y  j
1 n% p0 U* I5 D% E                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7' c0 e2 S' T: K1 H: B: L, |) D
                output = 0;
* T3 }" i, s, K7 Y: ~                output += internal.Process( 0 )*vol[0];
  X: `' Q5 D' F- F                output += internal.Process( 1 )*vol[1];$ a8 }# ^4 Q+ ~' B4 r' n8 x
                output += internal.Process( 2 )*vol[2];
( m# K+ H9 c3 ?. B                output += internal.Process( 3 )*vol[3];$ h/ I) o& R3 X) k  x
                output += internal.Process( 4 )*vol[4];
8 Q; j" ?7 q+ J# _$ @0 L% p+ K9 U; h; r. r+ E
                if( exsound_select & 0x01 ) {6 l. X8 D+ ?5 ^' v6 c
                        output += vrc6.Process( 0 )*vol[5];9 L9 Q3 W' e, l/ R5 t
                        output += vrc6.Process( 1 )*vol[6];9 o$ p& ?+ m" o" d
                        output += vrc6.Process( 2 )*vol[7];# l4 ]8 t. V. Y4 k9 p. \
                }! b4 s* Q6 J. n( w7 w) J
                if( exsound_select & 0x02 ) {/ D  k7 L7 y6 ^8 D& p
                        output += vrc7.Process( 0 )*vol[8];
/ f) s% ^7 h4 f! O1 s9 r                }
8 t3 @4 N3 e! f! Y/ q3 Q% o0 y* z7 l                if( exsound_select & 0x04 ) {
; p, S# o( S1 g                        output += fds.Process( 0 )*vol[9];
1 W( u. i0 j& S7 `  Z1 \                }: {) K$ T+ w/ @# s2 f
                if( exsound_select & 0x08 ) {1 `* B6 c* F6 ]& J- U
                        output += mmc5.Process( 0 )*vol[10];
) [: Y# [6 o& M9 Q& @7 [; w; A+ I                        output += mmc5.Process( 1 )*vol[11];
; b6 h$ x' ?+ S3 \- o, n6 A0 y                        output += mmc5.Process( 2 )*vol[12];
7 e1 G0 p% J3 u4 |  C/ c                }
' W/ \, N. b% q                if( exsound_select & 0x10 ) {* \- H8 n; O0 g( S1 J8 _# j: ^! M; c
                        output += n106.Process( 0 )*vol[13];. J# y% B) O7 P8 d3 Z7 H
                        output += n106.Process( 1 )*vol[14];
% Z) d0 N  d; N3 ?3 I# t$ i6 l# A                        output += n106.Process( 2 )*vol[15];- F' |" Q1 S, X0 h
                        output += n106.Process( 3 )*vol[16];
. |* d7 _* K% _$ A6 ~1 j% k                        output += n106.Process( 4 )*vol[17];
6 R8 Q& T, c' K' q* i& b  H3 y                        output += n106.Process( 5 )*vol[18];0 d0 {3 ~6 o( C' W7 i2 ~' R
                        output += n106.Process( 6 )*vol[19];
6 t* a, r% r" o" _  V                        output += n106.Process( 7 )*vol[20];8 r, ]) p( @' N
                }; }0 R5 S! L3 @8 c
                if( exsound_select & 0x20 ) {
+ [+ ^+ y) T. G; l6 s8 r2 G                        fme7.Process( 3 );        // Envelope & Noise& P+ C  d5 |' I, j0 x7 ~7 S
                        output += fme7.Process( 0 )*vol[21];
6 B$ m4 d( ?0 a$ K                        output += fme7.Process( 1 )*vol[22];
# z' L4 z1 g8 _+ u, ~* E5 S  L                        output += fme7.Process( 2 )*vol[23];
# a( d: P) }0 ]" Z; k                }( [6 P  H5 T4 k- D" l5 _' e

6 o- V5 G' Y1 F3 M: f* J# Q0 |                output >>= 8;, _: e# R, `* J$ B  E* V) w6 b  F* C
2 P! }: s  B+ z! a+ W
                if( nFilterType == 1 ) {
: i0 o7 S, R6 c; k# i                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)% S7 n% j2 p) k3 Q4 g
                        output = (lowpass_filter[0]+output)/2;; ?2 H1 g7 r5 d, p
                        lowpass_filter[0] = output;
( d- l8 d0 `2 x& h                } else if( nFilterType == 2 ) {! S+ q. B: g( }, W- Z4 x
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
0 X8 l: {3 Q4 @" }" P! g3 N8 V                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
, Q0 t" x& h# z2 Q8 P1 U5 D7 V                        lowpass_filter[1] = lowpass_filter[0];3 \' }% D  b! J- O
                        lowpass_filter[0] = output;
8 _2 t" B6 Y1 {7 t( G9 X9 \4 I                } else if( nFilterType == 3 ) {9 o- t( B! ?* L2 Z8 s8 b- Y
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
% J8 P4 [, E, m: ~* p% t                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;) h& T9 T2 a! E6 t
                        lowpass_filter[2] = lowpass_filter[1];
3 i# P4 u1 A2 R& C7 _8 G/ e5 t                        lowpass_filter[1] = lowpass_filter[0];* B' H7 D" s5 h. I& b+ @$ x( O
                        lowpass_filter[0] = output;' O% C: h( `, F6 j# J! s% u# b8 v
                } else if( nFilterType == 4 ) {
2 O. a0 o9 B9 g* W- l% f                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
( V$ K& E% P; D7 ]" P                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
/ H+ a$ g6 v+ R# n8 |) Q; L( k                        lowpass_filter[1] = lowpass_filter[0];- V' j# N$ Q4 p, o8 |6 z' i* ]
                        lowpass_filter[0] = output;
" X6 p1 D* s0 g                }' R; \7 S9 k8 v' V; I3 K4 S! V' h
  L& i2 ?7 V; a% R% s4 L
#if        0' X7 w4 f1 t  F
                // DC惉暘偺僇僢僩& I; Q. B$ b: V7 m
                {
4 W) \- T) O% ]8 W                static double ave = 0.0, max=0.0, min=0.0;- b3 Z4 r% O0 t: ~# q
                double delta;+ W1 K% a' y  a/ T- Z. |3 v
                delta = (max-min)/32768.0;* C4 z( G  ^1 |' v( e7 i' h
                max -= delta;3 d2 O3 r$ m' V5 e
                min += delta;7 |+ {3 F" D. t9 Z- F+ [+ e
                if( output > max ) max = output;
* b7 {, A" f. Z$ f6 ~! ~                if( output < min ) min = output;4 E( d: B2 f0 C! |1 |
                ave -= ave/1024.0;& D1 ?% _: B" D/ r/ Q9 d0 S3 X, K
                ave += (max+min)/2048.0;6 W+ W0 h& ^7 X2 M4 i' s- g5 t
                output -= (INT)ave;
% U3 J& g9 H% e. B) D7 N, J                }
) C# J/ p4 ]3 k1 O# r2 I' u9 U) a: R#endif- ~/ ^  L& M0 \  \
#if        12 R$ S0 X( d1 G: \
                // DC惉暘偺僇僢僩(HPF TEST)
0 l) e& ^% |7 Q+ y+ s" Z! b                {$ i' O/ }( a6 C" _9 k! v
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);& H7 j0 L" d3 G0 U9 f& [
                static        double        cutofftemp = (2.0*3.141592653579*40.0);/ A- K  R# A/ S8 V
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
% N' Y0 X2 V5 H& N/ [                static        double        tmp = 0.0;0 y2 `& @; R$ w+ O) z
                double        in, out;% A2 L& I7 x9 q; m  E$ D

. x9 _! t( j9 K0 e8 Z( h                in = (double)output;* L: j+ H2 A/ [7 N
                out = (in - tmp);
/ \6 z& ~( F7 L: k. ]  D                tmp = tmp + cutoff * out;# ]1 [. S8 ?3 u) q: P) V' x
+ Q8 }$ ?  T5 p
                output = (INT)out;
- @" Z4 Y; M% n/ [' _$ A+ o# I                }$ s9 S. J2 N/ ^6 j# A, O6 E
#endif
) _- B: {# x" S2 l#if        0
2 J. \5 E  ]9 ?' [$ F                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)( h/ D2 o9 u! [+ e% {: Y
                {
+ `6 B- K& Q. H4 F! R6 o                INT        diff = abs(output-last_data);7 q6 y: ~! V1 Q  n9 }
                if( diff > 0x4000 ) {. [9 `0 K' g0 x! c0 Y2 N
                        output /= 4;
" v  i7 g' ~) u# ]5 f                } else - }% @* K& {6 {  R' `% w4 J' S
                if( diff > 0x3000 ) {
) v  U6 q: u% c, E1 X1 I! M% o& a) B                        output /= 3;  B+ Y( W6 |- Z5 o
                } else: |) c/ V6 ~' l& r. k
                if( diff > 0x2000 ) {
! E8 |4 L: y( N& r9 x+ `                        output /= 2;
. o8 p( }& m/ S7 |0 U$ V# T! }                }
2 e) a: d$ d4 Y                last_data = output;  W) v! W9 ^2 S
                }: {: d/ {* H$ R5 c# A
#endif
! s* a# V4 `  a5 E* B$ {. C                // Limit
% u# f. ~" |4 b0 `                if( output > 0x7FFF ) {
+ F0 L  u; s1 I: \# n! p) S" l                        output = 0x7FFF;
% H: u7 ^% ?* {0 y& m; l) P$ M                } else if( output < -0x8000 ) {( o- D! Y; B+ J8 u% D4 j8 D' k$ m
                        output = -0x8000;% C6 _6 d: b- ?" q1 q
                }
9 H. O3 E9 E& c2 ]5 Q" _4 t0 Q* J% I8 _/ c5 I/ t2 j
                if( nBits != 8 ) {
! X4 T4 ?( n9 Z+ M+ @                        *(SHORT*)lpBuffer = (SHORT)output;
/ Y! J3 J, c+ g                        lpBuffer += sizeof(SHORT);
  t* \3 j* ~/ L. p6 I; E& ]/ _                } else {  S1 `& V2 r/ t5 \2 H
                        *lpBuffer++ = (output>>8)^0x80;
3 r: N+ j' K9 Q                }
1 M$ y) D- D& ?( W5 r* ?8 o0 t8 r, l- e7 e
                if( nCcount < 0x0100 )4 X, B# ?( _8 D; v0 \
                        pSoundBuf[nCcount++] = (SHORT)output;0 f" w3 @+ i- ]/ t' M1 ?2 w

1 J. \% E5 o$ `5 B- [//                elapsedtime += cycle_rate;; R- G6 k0 r* |& |
                elapsed_time += cycle_rate;
; \. V8 W/ T) \$ F4 F, |; d, M        }
8 [: b7 @4 F# _' Q
* h7 b; X' J0 a# W  X, x6 G#if        1
: L6 `" H! K) m1 U' f7 p) T: o        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
8 U* d5 d1 S# h  \2 t. f                elapsed_time = nes->cpu->GetTotalCycles();
( e6 v" x: G: R- [        }' p4 t" a) c1 `; Z3 ~" ^/ x
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {! B: M2 t& p9 ^. P, @
                elapsed_time = nes->cpu->GetTotalCycles();" o8 A8 g% e3 g# M$ s' c" I/ H8 u
        }# q. Q& w, a: ?3 K
#else
7 C$ w8 U$ b5 E! F        elapsed_time = nes->cpu->GetTotalCycles();8 A: p7 c: V* I  L
#endif/ j/ D/ N; n1 E7 E6 z
}
- z; P# z5 \3 w2 T" _+ b8 U' ]* T9 g' T0 x# Y- i" P6 P
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
! m/ q$ s2 C- K- _7 g# [" S; O$ gINT        APU::GetChannelFrequency( INT no )% ^8 y4 r$ |# b) m8 Z0 \
{3 z% j" f3 k$ _" a" V, O
        if( !m_bMute[0] )- Q& P- J! j7 e% U" L) f
                return        0;" r6 d) W: y' i9 j1 p( S
+ ]8 D+ L9 @/ ?! @
        // Internal
# W" u" H& z5 b4 l        if( no < 5 ) {  Z0 g3 R* {1 m" G
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
( x* P/ S+ C" ~: B$ |0 z        }: e( k/ ?4 t+ [. D5 w; E
        // VRC69 v7 a( q9 T# w) o6 ^6 s
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {+ {9 W' U4 D2 B* Y' V( h( Y) j
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
+ ^) P% v! _: o6 G7 M) z        }- \( Q" r) i) ~5 I# e! ^
        // FDS3 \% ~* |: D9 U4 P. v
        if( (exsound_select & 0x04) && no == 0x300 ) {
/ i! f: U4 h' y! J; y. ]' O1 G0 z                return        m_bMute[6]?fds.GetFreq( 0 ):0;
8 _' [" K- {7 x  i$ t2 @) j        }/ K# W$ J9 C. v# l
        // MMC5
$ L1 ?0 h9 l- o1 `        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
" U/ i4 r1 ~$ ^( |                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;. R% Y9 H; x- @! V' [5 S6 V
        }
! W- M( W% b! I/ ?- G6 w  y+ O        // N106, w3 N" B1 C6 p5 E: M5 P5 l
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
, i4 m, }. ^- S: `; V* J                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;/ ~2 h: i) [5 ^$ F
        }
$ \2 n- @+ G; M) s/ m9 D0 a3 Y        // FME7) \$ V" V; m8 @! T0 N' D
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {& r  ~4 X7 J- S& p) ^
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
  @- [* {2 r" ]        }
' s4 o" e! Q. B" J, F! N        // VRC7* ^% S" F, W6 j  S
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
+ P/ c) F6 r& _4 ]                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;4 t. O( o* b5 q! J+ m4 d+ R
        }7 w- H/ z. g+ d! n- b, }4 H
        return        0;
& z; c# `* Q2 t}2 n8 O: z  l  Y& b% p

( ]* B! d6 k* ^( G8 q// State Save/Load
/ w. @4 [4 v- {( K$ t0 }. T/ qvoid        APU::SaveState( LPBYTE p )) g1 b- L! T/ T2 l% F. G, F7 i
{" p7 F$ k- S/ `( d
#ifdef        _DEBUG' M# Y' }4 ]" R$ s: l: e4 n
LPBYTE        pold = p;- a1 P! p- `2 R3 _/ x
#endif# Y: F1 n6 L5 [' X4 R
: s: G- I: O* l6 o2 v2 Y
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞" B# j0 R9 S$ R) e5 Y
        QueueFlush();
6 ^8 _! M4 n' G3 n+ \4 ^3 N7 l" L: v0 ~: J
        internal.SaveState( p );
! w5 s3 [3 q; a- T) m0 Y( D        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
7 h" q  b' K; P* t6 Z
& Y! ?. _8 }* C$ o# k) ^        // VRC6/ `& d9 t0 {- c: J* ?2 x. \
        if( exsound_select & 0x01 ) {
; I1 z! H! E4 D                vrc6.SaveState( p );
# _' X" A5 ]8 Y  j  p. {  E                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
# I+ C4 y/ z; [/ v        }2 y8 q4 k5 A) O5 b. F
        // VRC7 (not support)
0 w" c" i$ c2 B( j        if( exsound_select & 0x02 ) {
' D" o" T9 c( c+ d                vrc7.SaveState( p );
% a7 w; T5 S0 W% f5 \( c- D                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding5 }  c3 Z6 X; m2 c: _
        }
* J; g6 \. u# B" s        // FDS
. P( b. V, X; E" h* b; b4 E        if( exsound_select & 0x04 ) {
: ~1 H" w$ H9 A1 F% H1 h7 T$ Q                fds.SaveState( p );
6 {- L0 b+ O- C" `- x                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
8 u; _, X- m- x7 X' t: v2 U9 G1 V        }- r. I6 ?. {  |  o7 f, t. L
        // MMC5. C( _" s! d) Y
        if( exsound_select & 0x08 ) {
1 }* V0 b' v7 s; G3 J6 x                mmc5.SaveState( p );/ i2 e' d7 O8 U- Z0 G
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding8 L8 y# Y2 P2 f
        }4 S0 z7 `+ N& {6 K) U7 `' k
        // N106
3 y5 J, q6 [3 _. U        if( exsound_select & 0x10 ) {
4 R  t( N- z! r+ F$ H, L                n106.SaveState( p );# T: R& o. S" e# ^
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding0 F8 |( q& T* [% Z$ w+ [
        }7 B) P4 s" \$ e  }
        // FME7
$ O+ M, [! w$ d+ j0 h        if( exsound_select & 0x20 ) {
2 H- E+ m/ k2 f: d                fme7.SaveState( p );, M, S3 m4 k) P8 V  A+ z. F) Z, q5 s
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding  r6 {8 g: i6 T% s( U. [
        }
& u" r1 M. [+ }+ Y9 g) }
- o) `6 |+ M# o( N4 Q# d- o8 Y#ifdef        _DEBUG
2 N4 ]8 X/ K( ~" p' A" ?4 dDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
- r& z5 Y" y6 x9 [#endif
2 l# Z6 U  d8 S3 Y+ Z6 o}
# u% V2 z' X1 [
8 F6 d4 ^  W3 M0 @void        APU::LoadState( LPBYTE p )( }$ w, s) o5 K2 S# o* ]1 w
{9 m6 T& b1 B3 p5 z# j
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡: D; ]: z( c* {8 H# ]8 F( t5 R& [1 k
        QueueClear();
' b9 v0 E7 c; j+ J6 |+ Y
% E4 Q7 _5 @2 b+ ], K        internal.LoadState( p );
9 u* a6 q" Z9 d6 @        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
1 N& c! C; D/ b, D0 V
! J+ t& a5 ]2 O/ S        // VRC6. o+ x' s! B& z2 e4 B% e
        if( exsound_select & 0x01 ) {6 X7 ^: a# y3 J0 i
                vrc6.LoadState( p );9 {  Q2 T: k. w7 i+ }) A0 C2 ]! P% @
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding: [/ V( Q0 s, y. S2 V" |& i. p
        }) i  O1 @( Q" \+ M7 G* R0 X; i. Z8 R
        // VRC7 (not support)
7 Q6 I, y2 Q  [6 ~( X1 {7 G        if( exsound_select & 0x02 ) {* p& z6 X' ?# b) b9 F
                vrc7.LoadState( p );' ^7 W1 z  _% O  k- n1 e
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
9 H* @) \8 Q6 H. i% O0 J4 {        }: |1 Q) k. H& y
        // FDS
$ }! q  {4 n/ K/ Y+ h        if( exsound_select & 0x04 ) {7 b+ f6 X+ n0 v! L1 ?% V" S8 j7 t
                fds.LoadState( p );
# I* Q& p! O  p( e1 j/ ^                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding: y2 l- D" \: {* ~0 K' o  ^5 K
        }
2 @( Y! d8 i& e: h  b  b        // MMC50 _4 ]  q0 ?& K2 l7 T
        if( exsound_select & 0x08 ) {8 f! {; ?" X0 S+ q* }8 C7 s
                mmc5.LoadState( p );
3 k3 k, R- b) H) S2 s                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding" \2 Q2 m! ?+ f$ }# Y: E
        }
1 O/ `' U' {3 b        // N106
& X/ y1 Y" x- C" T9 o$ w  m        if( exsound_select & 0x10 ) {
( u! M- e, T0 p2 |! v                n106.LoadState( p );; W  C0 J: {0 w  J* i9 t. m
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
' I1 P( `5 S( y8 A$ p- Q6 ?* {) e, c        }
' I3 \  v2 u- O+ `5 T" U- J        // FME7
! y/ H: ~; g) ~9 i- [4 }        if( exsound_select & 0x20 ) {
: ~! Y0 Z) ~! y5 z* q. R) e                fme7.LoadState( p );6 D% M) _7 ~: y3 ]  w" H5 S- O
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
: @! S4 b' c+ T: |" m+ I2 {+ I( P        }# [' l; o' A7 l, l8 A$ X
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 ) x' J' |- V! k! j0 r) E+ z( V5 X  K3 y
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
& M: d7 P6 L$ _5 i) B- v感激不尽~~
( Q( s" W6 C8 T6 x4 w% I+ Y
恩 我對模擬器不是很有研究,6 f8 j+ x$ N5 P- G% v/ t0 W$ c1 U
雖然要了解源碼內容,可能不是很困難,
6 d- M# @1 t# F不過還是要花時間,個人目前蠻忙碌的。: j" S# Q1 S: q4 y# @8 j

0 h7 [7 W! p! O7 p" f3 x6 n2 ^給你一個朋友的MSN,你可以跟他討論看看,/ e0 [0 ^( e0 Z9 B
他本身是程式設計師,也對FC模擬器很有興趣。7 [, L, g' W7 U

5 b+ j3 q, i" p% u$ EMSN我就PM到你的信箱了。
& C7 X3 e0 i9 r* |8 \) W% \4 U9 W& W4 Z3 ^6 I( 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 发表 / j5 g# X& z( K& P- z; X
呵…… 谢过团长大人~~
' N9 y; m; C8 f3 T

  x2 D! j( w1 t5 Z# O4 J) K哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
& k4 |4 `! b$ A- m/ w6 J团长的朋友都是神,那团长就是神的boss。
5 O* B# b% O# o; {3 H% `  J
哈 不敢當,我只是個平凡人,
5 q3 o( t: i' Z4 V/ x1 x: B6 j要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
3 @3 L3 o8 @- ]! @4 b, w$ T' RZYH# C2 \  U5 D8 P5 [2 L$ W: P
QQ:414734306% n% D5 U- j1 h
Mail:zyh-01@126.com. B" Q. R6 j- P, [8 d9 T$ V
; x- U% O* t) r3 Z$ ], k
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 2 Y2 B  b- W" O' J$ C. ^% c0 B4 L" z$ ^
再次对团长大人和悠悠哥的无私帮助表示感谢~~
3 T$ j, ^( ?- D" X
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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