EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
- d7 F" Z) s  v4 c# L楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
' Z' H0 `* c5 w7 Y! a这里有相应的模拟器源码,就当送给大侠了~~, Z0 k4 }% r% T
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 / e; Q3 n  A+ I2 ?2 \$ i2 f8 l  ]
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
* m/ H; _: ^8 w8 E; H楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~6 W' f/ H6 \# F1 ~5 Y# T# L" y: |
这里有相应的模拟器源码,就当送给大侠 ...

0 x+ e; |% ^$ r% Q  y# E; l聲音部分(Audoi Process Unit = APU):
" h  l4 O* F/ K: J.\NES\APU.cpp
7 a' R5 z& E2 s, A7 ^' `6 |$ q* ]$ E.\NES\APU.h
' X, c4 D+ j: G/ J5 _, o
6 m6 f. \" e/ o
. O' b. k% b% o7 Q7 r. I影像處理部份(Picture Processing Unit = PPU):; ^! A( Q# P5 j8 S+ ?
.\NES\PPU.cpp. c! z* F( D# L- |! G; l
.\NES\PPU.h) E& ?& H+ l0 H+ n
' i, {* T  r% r# s6 A
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
1 ~+ E. N. L  `) l" j2 h感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:1 @! ~1 O% p" V3 Y  ?& I9 e
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
' e/ I0 V3 k7 ?. H8 v//////////////////////////////////////////////////////////////////////////& A" ~! b: z  [% S" F7 Z
//                                                                      //2 ~) J7 J- J! \4 e2 @+ I' K4 ~
//      NES APU core                                                    //0 q$ c- n. E2 Y6 [9 N
//                                                           Norix      //
1 K6 g2 G0 z# k9 N- M//                                               written     2002/06/27 //
8 e8 A- J2 T; b5 r* C7 H/ Y, |* O//                                               last modify ----/--/-- //% B$ D/ a  m% f' z3 t; {4 a3 g
//////////////////////////////////////////////////////////////////////////9 h" Y. A( H$ x  A- y0 M. D0 K
#include "DebugOut.h"
3 W& h" a* L, S1 z/ }1 p#include "App.h"
0 u  Q. n2 _! n#include "Config.h"
2 I' [/ v5 N" t5 J7 j
" r1 y2 F4 E4 Q- q0 n#include "nes.h"- E3 x3 F8 r. \% z9 S7 Q6 Z" j- Y
#include "mmu.h"* q0 x7 I# g9 P( D" P: ]
#include "cpu.h"& N; O5 D  \. l# |# b  B' k1 d3 h; B
#include "ppu.h"; K/ X) p' G% W$ |! r6 `. v
#include "rom.h"+ {1 x, k$ V. D) E
#include "apu.h"
# M; g) q  L% l: J! Z: i9 b
+ A3 u' d3 b5 Q2 y& b// Volume adjust
: N7 d! [  t5 e' G: }// Internal sounds
2 l; @. h" m+ b, O6 k4 I) B#define        RECTANGLE_VOL        (0x0F0)
9 b) L' y# j" G1 {! |  i* A* U#define        TRIANGLE_VOL        (0x130)+ v, v4 B7 }: }1 ]5 x
#define        NOISE_VOL        (0x0C0)1 o! W( @' J9 `" e3 D
#define        DPCM_VOL        (0x0F0). O0 F  N/ b: g5 j4 {  W
// Extra sounds
5 L  h/ F4 E1 l) B#define        VRC6_VOL        (0x0F0)
. H2 ^5 ?: }2 p! K: s- V#define        VRC7_VOL        (0x130)* S$ y" ~1 e5 @" D* @
#define        FDS_VOL                (0x0F0)
! n& Y" m) n  A  z6 F#define        MMC5_VOL        (0x0F0)6 @2 \7 U$ }( q+ |6 t7 p  X
#define        N106_VOL        (0x088)( m0 X) e& k' i, a- u
#define        FME7_VOL        (0x130)
$ [: z6 w* S/ {7 P* f" L& v4 `. i1 ^2 Z+ Q$ X6 i
APU::APU( NES* parent )
- S: h& C- L& }7 d; ]  r0 g5 G8 u% v* W{
* ~& k# ?: y: ~4 C* N- v        exsound_select = 0;2 |( l0 T. E5 |; _8 u

% H9 W3 K. v, `: i: G; x/ a# \        nes = parent;
; E% t: f* v4 `4 A        internal.SetParent( parent );
* z6 y* w- y& i1 C4 ^9 ^0 m
0 h) g9 s" g2 ?) f% _' |4 S; M        last_data = last_diff = 0;& `" u' t5 [& t( h3 b4 e; |0 m

- B9 g/ m7 }: [5 e        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
# i/ D5 Y+ a" B  z0 _" \0 A+ g, [
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
! _+ m! H- H3 m& U. j6 Q. H        ZEROMEMORY( &queue, sizeof(queue) );8 c2 ^+ c7 E/ S: e  O/ _
        ZEROMEMORY( &exqueue, sizeof(exqueue) );$ {/ M9 @" }2 N, ~
- t* T0 o5 \& C: R& d8 u. y
        for( INT i = 0; i < 16; i++ ) {
6 u; a& N8 d; ~/ x! M                m_bMute = TRUE;; V3 @6 R" o/ `# A; n  }% h4 x/ T% O
        }
4 [% _4 ~: P: _1 k! c9 @) c0 w1 c}& ~; L$ j8 }( M- t$ q7 {4 l- z

. Z8 `; T8 ~) U% ?APU::~APU()
1 m( m7 h! @0 ^& o{9 ]% N1 e+ F+ L  T1 k" o
}
4 w0 b8 M  F! c8 \0 r: ?. H2 n+ [# r0 [) ~8 ^8 r3 {
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
0 q1 n7 J4 }! a# K( {/ i{
- l  t6 x, J$ Y% c% G        queue.data[queue.wrptr].time = writetime;
3 d- j# B$ u& H4 q        queue.data[queue.wrptr].addr = addr;: `4 n& ~$ Q/ |" l+ ]. g
        queue.data[queue.wrptr].data = data;
5 ~, m3 z) w6 H9 p7 U2 X" A        queue.wrptr++;9 m+ M9 u: G: _# j
        queue.wrptr&=QUEUE_LENGTH-1;( H/ O5 [* i# f, m* u
        if( queue.wrptr == queue.rdptr ) {+ U* t( F: Y) T  h& q
                DEBUGOUT( "queue overflow.\n" );+ u) a" O; b8 ?' @1 ?3 Y: `
        }
9 u8 H5 ?) r( l5 `}
; q9 p) h. c' ?% y2 v. c  B* j4 X: U/ A" h
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
% [( e9 A5 N/ v* \/ m: S{
; f+ ?, b& a8 O0 u$ ?; N        if( queue.wrptr == queue.rdptr ) {
0 i/ k5 T. D9 o5 ?                return        FALSE;! F6 K6 N# f" b+ o( T. y7 @
        }
8 r! M2 ]+ ~- i% x% D2 k        if( queue.data[queue.rdptr].time <= writetime ) {
( a" s, v1 n- e* K" N! v9 F% q3 n: |7 z9 q                ret = queue.data[queue.rdptr];9 {( r/ @6 D5 ^. B5 C' @- v4 |4 ^
                queue.rdptr++;
: `4 d- A/ }" Y& N                queue.rdptr&=QUEUE_LENGTH-1;9 s8 E6 E* r1 P: k: e+ n
                return        TRUE;  S6 A; P: G* S8 B$ y
        }
" s1 G* a. s7 R& Y2 X- z        return        FALSE;7 F8 y( P1 E: C  z  O
}" e5 [4 f  y7 B/ `# `
: e, z/ I. @7 d
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
2 V2 j" Q" V' _9 k{
' _1 b& z; A# J  J        exqueue.data[exqueue.wrptr].time = writetime;
5 c( `' L- [. H6 f  i! ^4 n& {        exqueue.data[exqueue.wrptr].addr = addr;
  ?. e. L( n! T        exqueue.data[exqueue.wrptr].data = data;
) _' v* u9 V- B        exqueue.wrptr++;: F8 K8 `1 k; P: ?
        exqueue.wrptr&=QUEUE_LENGTH-1;
$ \! o% L2 L2 R4 O, ?        if( exqueue.wrptr == exqueue.rdptr ) {! J1 n0 D% ~, z9 [+ a% N% A/ z
                DEBUGOUT( "exqueue overflow.\n" );+ ?% z8 @% E" a: l: T; E  S
        }, b; ?0 ^' R# n  P8 x& ?( D7 D
}- T# B9 s' X6 g( U6 r! A( L. u
9 l/ f9 U8 ~: D
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
- B! D0 D! W: F4 s% v{5 Y8 F! [9 c2 c) B: p
        if( exqueue.wrptr == exqueue.rdptr ) {8 u6 b: s' i' O' c+ p( i2 z8 T
                return        FALSE;" {' a9 |, Y9 ]# M7 `
        }4 d# a6 B* n3 A& l4 f
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {  t; j* W4 l( p% K# k7 {
                ret = exqueue.data[exqueue.rdptr];* |* D3 ]/ \+ l
                exqueue.rdptr++;, `8 M2 |% b) c
                exqueue.rdptr&=QUEUE_LENGTH-1;) [5 d1 b; y" ]
                return        TRUE;+ z" O! E0 w/ C
        }5 ]6 U" X+ q' j4 ^
        return        FALSE;- S/ k. B- m3 m+ U
}2 R+ ?  @. I, Z2 N8 O2 R

0 Y/ g& V! [; G3 N5 p7 Xvoid        APU::QueueClear()1 U& F% S5 ]' e1 s4 J& D* s
{
, A( W7 k4 D3 U. X        ZEROMEMORY( &queue, sizeof(queue) );4 `; t; u  D( R! G; {
        ZEROMEMORY( &exqueue, sizeof(exqueue) );+ p8 ^! C2 Q; b5 ~
}
0 y& U, S( K! ^9 U+ M
  ?, H4 q- o( J$ ]7 Y) W9 tvoid        APU::QueueFlush()
6 n3 S0 @7 ^* h9 _) S  t( W{
1 B/ q7 }5 P( p! g/ ?5 O- Z        while( queue.wrptr != queue.rdptr ) {
/ x5 O" k9 c5 y                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );" V8 [3 u- d% Q1 m' ^& i
                queue.rdptr++;
- K9 A5 n2 p5 d! p! N. W                queue.rdptr&=QUEUE_LENGTH-1;
( A) _& P0 x0 B: h/ S! L1 j        }
5 Y0 M: q. j6 U/ L& Z% Z! v2 @3 g  B- J& l) q6 m0 Y5 G
        while( exqueue.wrptr != exqueue.rdptr ) {
7 ?+ L6 K1 O7 ^                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
' i# T5 r% b5 _: ~- Y; F( S/ V                exqueue.rdptr++;. e8 C- Y& j1 i3 b& l, g3 T, \: l
                exqueue.rdptr&=QUEUE_LENGTH-1;$ ^& L6 a! Y& E/ \$ F
        }  \% ]2 R2 U4 l
}
3 g- ]/ Q* O& F( c: A* o& C2 u' ]$ J2 m
void        APU::SoundSetup()
  w+ U, j0 x* i" y/ ?3 M. Q{
1 b5 ?' \/ J+ y) B/ R        FLOAT        fClock = nes->nescfg->CpuClock;; T! M% ?+ V6 D! ^, {* j* n
        INT        nRate = (INT)Config.sound.nRate;
+ U& F3 f. D- @2 L        internal.Setup( fClock, nRate );
3 e+ F7 I& C; I4 [3 k' O        vrc6.Setup( fClock, nRate );& V9 P7 Z  X. ^5 R( R' W4 @
        vrc7.Setup( fClock, nRate );
2 K- |6 [$ B) s* R5 c% T: k/ Y- K        mmc5.Setup( fClock, nRate );9 g3 W% o* D/ `! _" P. D  p" ^, ^1 Q
        fds.Setup ( fClock, nRate );
3 n) O2 {- m2 Y$ H( h7 B        n106.Setup( fClock, nRate );
5 J* @) J6 P- b1 V: f1 O+ u2 y        fme7.Setup( fClock, nRate );, ]7 n9 O% T/ z5 R& r
}: F4 z% O+ T, y- @

# O0 u( _- @7 O+ H% Svoid        APU::Reset()' E& l6 O& ^: f# D8 H6 K  }0 v
{
! O  F, @% H( P. l6 E        ZEROMEMORY( &queue, sizeof(queue) );
# Q* R/ a  k3 W        ZEROMEMORY( &exqueue, sizeof(exqueue) );* W9 O1 ~! e  N
  @1 z% J' ^1 `0 I/ |
        elapsed_time = 0;* l/ v' ~1 Z$ G% S0 F) y1 z

3 ?4 B6 h( ~$ a        FLOAT        fClock = nes->nescfg->CpuClock;
. f0 G' f- C; f8 p% f  d2 W* \        INT        nRate = (INT)Config.sound.nRate;! @+ y- @2 \+ F* O3 w
        internal.Reset( fClock, nRate );
/ B) D6 U( ]6 E$ M% s6 v: N        vrc6.Reset( fClock, nRate );
; j. S/ o/ L5 f: l# a6 [" X4 Q5 k        vrc7.Reset( fClock, nRate );( J$ d& c$ Y( W; i0 P2 v
        mmc5.Reset( fClock, nRate );  b  w/ |8 T. j) y
        fds.Reset ( fClock, nRate );; ^1 ^( l+ w9 T
        n106.Reset( fClock, nRate );
+ B, {5 q7 D) u( S        fme7.Reset( fClock, nRate );
: y5 R% c5 r: U
; ~( y1 z' u6 n0 Y$ r        SoundSetup();0 `; e) h% U# @3 J0 @
}
& c. G4 |$ i3 T  W/ z! V5 C: H0 Q) k0 O. Y, z
void        APU::SelectExSound( BYTE data )% A7 O* m# b2 U" w- b
{
: R- _, @) M& y+ B* Z        exsound_select = data;
1 m' ]0 B+ _% q, ^( z) L6 q}/ `+ u9 [0 |! r5 F$ |) p. p
9 m( b5 T& P' h% M5 F
BYTE        APU::Read( WORD addr )- @4 `  p: N; O1 Y( L
{
- E8 ]! h' P2 n0 u) y# p        return        internal.SyncRead( addr );9 N: N* r+ V( H# P0 B$ G
}5 H. Q2 y4 z  k, ^- ~  d5 ], N
( ?1 I7 T) U3 c4 n& z$ _; z
void        APU::Write( WORD addr, BYTE data )
) t* [. H& E- L' C5 Z. Y7 e. M; m3 A{- R0 s# Q8 @0 O  T6 x/ I5 q7 ]
        // $4018偼VirtuaNES屌桳億乕僩
) ~0 ]* S4 X. ~) g( |/ p( G; a        if( addr >= 0x4000 && addr <= 0x401F ) {9 p1 ^4 H9 M& s3 d3 E
                internal.SyncWrite( addr, data );$ }8 x2 [% F; b. D  D
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );, a$ m3 k$ o6 Z3 i7 Z: t5 f
        }  V% j3 ~% O1 Y* i- `% L5 C1 u
}! _' ^7 V% `; o) D& ]" o/ q
1 W  g% r; B$ x. {
BYTE        APU::ExRead( WORD addr )1 ]+ Y/ k1 Z% e3 |5 o- C8 z
{$ B' E6 g6 a7 _
BYTE        data = 0;5 b7 ]0 k' x! y

& P5 e( j* u8 t        if( exsound_select & 0x10 ) {
( g& X0 i1 n4 f2 v6 S* D  N# \                if( addr == 0x4800 ) {
" u* O3 S9 k( f6 N+ ^                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
/ F9 F; k. h- n# v                }
* P. {$ I2 U1 h9 W* }! ~        }2 U/ k) ]; y, U8 d! T6 G
        if( exsound_select & 0x04 ) {
; K, Q) y: t: S- n% ~7 O# h                if( addr >= 0x4040 && addr < 0x4100 ) {
$ s0 t7 S. O! R. S- Y! `" Y                        data = fds.SyncRead( addr );
& `* i2 u8 [$ a  b8 k                }: D+ q1 K, k) u% L0 g
        }; M% e5 V. W7 [) t3 O
        if( exsound_select & 0x08 ) {; t  p0 U8 D& f% w7 m, U
                if( addr >= 0x5000 && addr <= 0x5015 ) {9 t) c% r: p6 R8 c% R7 ?
                        data = mmc5.SyncRead( addr );
* _9 J7 v* r3 N% m                }
- _1 [3 O' j" J; s8 k% o# ^* l        }
* D6 Z. k7 x  `/ H' l) _/ [4 l1 J( ~$ p6 G+ L6 L
        return        data;0 l' V0 ]/ o. t8 Q$ C- Y
}
) F; ]& M0 r) z$ @* b
! X. a4 Q4 z# R+ \- M; E6 lvoid        APU::ExWrite( WORD addr, BYTE data )" ^3 b6 J9 _* `& x5 e
{  v  F* _. [: r8 E
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );/ E2 X9 l, ^* V2 Z+ @
# r+ j3 E  W1 J3 W7 P
        if( exsound_select & 0x04 ) {
4 S! {( L# _$ R' F9 E- ^                if( addr >= 0x4040 && addr < 0x4100 ) {
. y# L" v" o( V# ^                        fds.SyncWrite( addr, data );, `1 ?/ z% p- ]3 v; b/ N
                }, }3 x: a  l5 R' `  |5 G: ?% d
        }
* b( @' o% }8 A4 ?* R; Q) h  l% _8 h$ N8 f  ^
        if( exsound_select & 0x08 ) {
% E, a: s9 B* Y1 j                if( addr >= 0x5000 && addr <= 0x5015 ) {
* f% A9 @$ _! r, P+ M' C% W5 k+ F                        mmc5.SyncWrite( addr, data );+ O  t% h8 r( ^8 K8 q
                }' v- X& a- H7 F3 w
        }4 l* ^: B8 i+ K' e0 V( \
}
+ D! P( T0 H; ~0 `+ t- C$ r) V
' Z& d8 L0 @' k$ F3 i. Lvoid        APU::Sync()* f7 z& w3 v6 P1 U/ {
{8 Q2 L6 v1 c( j
}" Z+ _& y/ I/ Y, E# p

' ^( y2 _+ ^6 s# B* Jvoid        APU::SyncDPCM( INT cycles )
: Y  s1 |9 o7 u" g3 f. w9 {{
, X2 P5 q: Y' F        internal.Sync( cycles );! \" }# t( K. V7 w" Y

# ?0 _8 F% a4 o% T9 a' t        if( exsound_select & 0x04 ) {$ E& A- w( D' L4 q/ p
                fds.Sync( cycles );
. ^2 J% E/ V: L& ^8 A# e  _        }3 f% L% M! z+ _2 u* o, \
        if( exsound_select & 0x08 ) {7 l, |* ^1 E. w" Q! y
                mmc5.Sync( cycles );
" M/ x1 b3 \7 J1 l; M* q        }3 f, ?: C* c) p: c7 V/ |. a
}8 o6 H9 M+ {; ~/ f0 {
# ^+ @$ N& U( _! w5 u
void        APU::WriteProcess( WORD addr, BYTE data )% Q0 \) {. e* v* L: i! k+ x
{
. K) X1 n( q4 D4 k        // $4018偼VirtuaNES屌桳億乕僩
. R7 y1 g" f0 }$ Q; X        if( addr >= 0x4000 && addr <= 0x401F ) {
9 C$ \2 B4 `: k5 f$ O                internal.Write( addr, data );
) a, y1 f8 Y& n9 J4 Y: ^        }
7 P% l( a8 P3 o  f1 Z}
5 O  Z, w8 h' V+ |' o& N$ J# y. K9 y
- G) d. G: Z/ k1 r. B# v7 h. w3 bvoid        APU::WriteExProcess( WORD addr, BYTE data )2 R  e. ^) o' v; v
{
  h5 ~5 Q5 g7 r% O        if( exsound_select & 0x01 ) {
: s5 @9 X* k5 o3 b: V                vrc6.Write( addr, data );
$ J. \0 F$ w' C9 Y        }/ b- t% H2 u" S9 n1 x
        if( exsound_select & 0x02 ) {
% f: H/ X( r" Y3 H3 e( ~                vrc7.Write( addr, data );, O  Z5 K/ }3 f0 [$ B; F8 k" [9 l
        }: V7 m0 c; K: }* |2 |
        if( exsound_select & 0x04 ) {
; m9 W" k9 @* @' k                fds.Write( addr, data );3 u) D2 C. w4 U) r
        }
8 A% B1 B) Z" Z' g' n        if( exsound_select & 0x08 ) {
9 |: Q- e+ y6 u                mmc5.Write( addr, data );
6 H: M+ H' I$ w. K        }/ k$ U: A" T8 j  o
        if( exsound_select & 0x10 ) {; G4 e2 ^1 h* ^; P
                if( addr == 0x0000 ) {
6 B5 _: [) o5 r' s                        BYTE        dummy = n106.Read( addr );
  ^/ `  N8 z! h& v6 o                } else {0 k/ ~% P2 ~% e% |
                        n106.Write( addr, data );
* \: P9 O/ I" v: a) ^+ f                }& J- f" v+ U: Q' k; d9 j
        }
6 C( t3 X  a5 p" L        if( exsound_select & 0x20 ) {# ]; A0 t; X9 G/ G" U' I9 l
                fme7.Write( addr, data );
( _5 l5 j6 q; [  q- u3 S- ^        }( W* h# W( P" Q; j, K% i$ v: b/ u
}
, I% V: V! g8 C& s" K2 o# M" e+ L. w0 h; l" T; a
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )( n) X1 H. B: R
{
) O4 c! I2 R% q% B/ sINT        nBits = Config.sound.nBits;; W/ b( u1 J' `. R+ I
DWORD        dwLength = dwSize / (nBits/8);
) r- o9 f" x$ U: `! p- yINT        output;
3 f  h, ?* h( S4 L" KQUEUEDATA q;: H: R# G* M" q0 w' Y
DWORD        writetime;/ i2 Z) j: [6 `
. M6 H$ F. i' P! e" Z8 q
LPSHORT        pSoundBuf = m_SoundBuffer;
0 ?6 ]5 Y/ z4 c7 D8 lINT        nCcount = 0;' H/ P" H; T, ~) p% ]

. I; \/ K9 `$ v% m+ ]1 oINT        nFilterType = Config.sound.nFilterType;
, v, m7 h4 m  q' ?3 u5 @& O" L! x& q, M# \
        if( !Config.sound.bEnable ) {
( |( K8 U/ k% |0 L' u                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
+ M( g/ _4 k; Q0 @                return;
1 B& N1 W  z! f) v1 a" k+ q        }9 i: B# A3 G* ]6 f5 }/ t3 `+ q

$ ^$ |: H3 ~; c, @        // Volume setup
5 [' D& u# L0 _/ l% D        //  0:Master
! P6 l( s! M' j% n3 z        //  1:Rectangle 1/ W9 L4 y  d# N0 U) Q( F, [$ A
        //  2:Rectangle 20 ?0 R% q9 Z6 z
        //  3:Triangle
8 x/ H& I; M3 v4 o8 w6 U# b" S        //  4:Noise2 B* s* w0 ~( _, U5 a* c
        //  5:DPCM
* y: j( Z- R+ R5 R        //  6:VRC6
" J1 n& U- F5 [9 e# U& k# C1 u        //  7:VRC7
. l) b6 R) N) {6 p! g        //  8:FDS
0 J& w! v0 G7 B, r9 Z        //  9:MMC52 T/ M5 F4 @  m* D
        // 10:N106% G' |$ T1 c9 k+ T# }3 w" O4 \4 a
        // 11:FME7
- M) g9 i0 \5 ~+ f5 n4 ^+ `* T        INT        vol[24];
2 p; J! ~1 v/ j: g$ R        BOOL*        bMute = m_bMute;
6 [' f: a+ r; T! T# P        SHORT*        nVolume = Config.sound.nVolume;
/ y9 [# A% B0 e1 `2 O/ \' Y: `' }! q( U- g' B8 H. F
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;' k& B0 ^( M6 w! K% v8 J7 C+ _
+ L9 k# K0 K! E: r7 F
        // Internal
) K7 {& _$ O" [# z7 {7 f        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
' u3 Z8 L6 _9 N2 b  N        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;# l0 P$ w$ K" x" D& g- X2 p
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;5 y5 I8 e* B6 d5 [1 i+ U
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;$ W" y, h( q3 m. X6 X# ^3 ]
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
7 k2 f+ p3 k2 b, s4 w2 n' M; ^( Y( C$ h( q; p" e; K
        // VRC69 L, `. q3 J& M) s
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
  c& ~+ k+ n. u& X4 ~        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;9 U+ Q. Q! Q( R& a  C3 X/ R
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
) }# B$ X* B! ]0 |- b- H1 P) i6 v" h. Q) }7 b
        // VRC7
) T2 C+ F) H& [# p9 f! z        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;2 Y* J, f) Q( y
$ {* `2 M' G; a' R4 X  {6 H, s- t) Q, T
        // FDS
' n6 c7 k& ~/ T' ^+ x+ i        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;% ?0 U& _9 X6 T: s$ f

/ _+ Y7 K; [- ^; s5 I6 D( k        // MMC5
$ d3 N8 d8 l* u" n; g; Q9 S$ p        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;3 o6 C1 n! U1 c8 A  s
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;5 |! T- |, L- X
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;; a2 J9 l( S. k! `8 o3 M! c
, I) i2 Y, Z0 ?5 C: H2 A
        // N106! N4 g* U2 L  p6 P9 X+ x
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
1 A; T) E0 C8 }5 a7 d2 R; m) T        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 w8 J" ~- k" z, E) ^9 [
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;: C  `" A+ W% e% w7 ~8 F) ~
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
% x- j9 W& N( ^3 G" J& u        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ s$ g- m4 Z9 X) h' b6 {, \
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
% W/ C, {' w+ D: f1 R; j- N        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;6 R* J: u& |: n; n
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;! H  t; T5 N3 e& {

7 a/ P; e7 o0 A! S        // FME7
! F$ d8 F, B- W1 s/ j: d- ]        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;) |: H+ R  F0 s2 ~0 }
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;! y: n. w8 g. `* i. g
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
, a. C! v  N; [
' f( g- X9 i+ v& u//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
. j* C; D' Q- o* _        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;7 K& o! `* I/ m) J

' t" @- j% B+ T" E        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟! q- \7 G/ h( e& ?) o
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {+ x8 z8 B. A9 b, r, @0 l
                QueueFlush();2 X5 Q9 Q1 T& _; M" m" h
        }1 [' h  d9 S2 P5 i; b1 Q
8 H$ p! v% l7 O  L
        while( dwLength-- ) {7 P+ C( y& I( r3 b7 f
                writetime = (DWORD)elapsed_time;
$ q) k: k4 Y1 m2 k6 S( b5 Z' G  o% |% Q- o
                while( GetQueue( writetime, q ) ) {
9 m8 n& B8 I# M4 y: J                        WriteProcess( q.addr, q.data );
; k  a5 e: n2 Q; @4 n" ]                }$ T0 O) b! R. Z! q6 O

1 X: a1 n1 |. F# f1 i- M                while( GetExQueue( writetime, q ) ) {6 j1 m9 R$ N' u7 ^, ~
                        WriteExProcess( q.addr, q.data );
/ S4 g: s" D/ K0 w" ]                }
9 ?& U( |$ k9 y6 ]5 K" U* k# y$ S
5 `6 I9 n! }$ a/ l; t9 C6 E. L                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
  Z( O! u6 X$ j* d                output = 0;
! o8 G; ]+ q2 R5 Y' e, @: d! N                output += internal.Process( 0 )*vol[0];/ x: X! e2 u, v" X
                output += internal.Process( 1 )*vol[1];
1 p5 a1 z; m- X. h2 |) U' w                output += internal.Process( 2 )*vol[2];
/ G; d. E6 d" w$ k% F# v7 l2 r                output += internal.Process( 3 )*vol[3];
. B+ p8 p1 F; a$ m                output += internal.Process( 4 )*vol[4];
! I& c% h: w7 f+ K& s$ V$ J: f$ b
9 q; ]$ {" R; |, G1 \- H% y: P1 ^5 V& @, T7 g                if( exsound_select & 0x01 ) {/ l( |# @# l; \# t
                        output += vrc6.Process( 0 )*vol[5];4 Z5 }, i. J1 Q, m7 r' G" e
                        output += vrc6.Process( 1 )*vol[6];
' K2 @' t" I+ }, w. d                        output += vrc6.Process( 2 )*vol[7];) I* A9 f& {6 w3 [9 ~
                }  o- {. b0 f: T% n- r
                if( exsound_select & 0x02 ) {
  J8 \5 I  h9 O5 k6 D                        output += vrc7.Process( 0 )*vol[8];/ q2 L* L, N+ M! Z0 t9 M
                }2 z& F+ w- w$ M; M8 z; b
                if( exsound_select & 0x04 ) {! Y- W" U7 V) L: o; v2 ~
                        output += fds.Process( 0 )*vol[9];# r; f  x. ?4 L5 }; V2 [2 M, T4 P$ {6 @
                }! ]5 @$ H+ o( _
                if( exsound_select & 0x08 ) {
4 \# D/ n) R4 o0 o                        output += mmc5.Process( 0 )*vol[10];# ?/ d) S4 c5 r' p  p' M, _
                        output += mmc5.Process( 1 )*vol[11];0 R/ j  N8 |+ f8 W* ^3 Z  ]5 ?. F
                        output += mmc5.Process( 2 )*vol[12];9 b: E1 t1 r( ~; g3 c6 s
                }
& }3 Y. x2 q. p) g2 n9 i                if( exsound_select & 0x10 ) {
- y' _! Q+ L0 k4 I  C: ^6 W                        output += n106.Process( 0 )*vol[13];; |2 E) n8 c$ i5 A" q$ z
                        output += n106.Process( 1 )*vol[14];
0 f/ w' Z% D5 s2 f& ~) F4 N                        output += n106.Process( 2 )*vol[15];
2 ?+ S$ K; Y+ ]# Y) Y                        output += n106.Process( 3 )*vol[16];
' r/ K( v, y9 t1 g# V, n- ^% B; x) ?                        output += n106.Process( 4 )*vol[17];8 m( ^! p/ V0 a8 B/ L
                        output += n106.Process( 5 )*vol[18];, g! n: _/ k3 ~% X$ t& f1 V
                        output += n106.Process( 6 )*vol[19];8 e8 S1 X7 C$ j" H$ R$ ?! ~
                        output += n106.Process( 7 )*vol[20];
! |; d% m1 v  }! Y& l                }
( q: X2 I3 w- A5 c' h                if( exsound_select & 0x20 ) {! G. J" S: b$ ~- A
                        fme7.Process( 3 );        // Envelope & Noise2 m6 D3 D$ L( Y8 r" ~, }3 L
                        output += fme7.Process( 0 )*vol[21];" H( K7 I# |1 U% E
                        output += fme7.Process( 1 )*vol[22];" n3 q- y' p; s$ `  [
                        output += fme7.Process( 2 )*vol[23];9 K  o) b4 B9 r' c
                }
8 T$ t* Y0 q. K5 U' f' z) w3 T' `, q& p3 P7 Z  C( K# a
                output >>= 8;
5 b2 V7 H) c( `8 y9 a9 `% F' s9 _/ Q- l  G! E
                if( nFilterType == 1 ) {
+ y2 a& h) R) D/ w8 E                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
; S" X9 r- W. ?6 U' c5 s                        output = (lowpass_filter[0]+output)/2;
# t# w2 `; U/ O) w  `4 T+ [                        lowpass_filter[0] = output;* i. F" o/ u  g/ n, O/ ]: p
                } else if( nFilterType == 2 ) {/ \( e6 D. f7 ]7 D/ |: T3 R
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
5 B3 o: Z8 @2 O! L- M* P& E4 R2 M$ S                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
; |5 M/ F- _* y" n" a                        lowpass_filter[1] = lowpass_filter[0];
: U$ s+ E$ Z8 j. `& {                        lowpass_filter[0] = output;
; s9 a& t' D- X( @7 W  c! B                } else if( nFilterType == 3 ) {# M6 o+ S  g3 _  L
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
, Y. M  q* `7 u- L                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;7 p1 q. [8 Q5 F
                        lowpass_filter[2] = lowpass_filter[1];* }7 X  {* H5 l5 w2 n. m/ Q8 {; ^
                        lowpass_filter[1] = lowpass_filter[0];
6 l' p9 Z' C6 B4 Z& J& Z                        lowpass_filter[0] = output;! w) U! t6 n" d) @
                } else if( nFilterType == 4 ) {) C1 G9 y1 h6 ~  A# F
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)* R: _, _4 a) g9 t" H# L. P
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;* L3 q0 B, \8 [, m4 l
                        lowpass_filter[1] = lowpass_filter[0];0 a7 H$ {3 a( [- W% V
                        lowpass_filter[0] = output;" b9 E2 r/ l4 w3 `7 c
                }
) i+ p, Z5 |& Q* p# K& {, x! K0 {
- U$ K: T6 `, D. u) s; S7 C. y#if        0
% C+ e) O& Y4 ]  c5 q! B% r                // DC惉暘偺僇僢僩
# s; Y3 G7 h3 u7 L& L2 U                {( d, U7 T2 c0 I
                static double ave = 0.0, max=0.0, min=0.0;$ Q- H" _5 X- K; z2 a2 j
                double delta;1 s* {/ K, O% j1 z% z
                delta = (max-min)/32768.0;9 |4 X( ~3 ]$ _+ k6 P5 W
                max -= delta;% I, R* ~8 q" r& Y# f% w
                min += delta;! Y* D) j4 F# Y# h6 z
                if( output > max ) max = output;( D$ q! h; E) N# ~7 ~
                if( output < min ) min = output;9 w3 A) s( F2 F# ~
                ave -= ave/1024.0;
7 v1 s$ \7 i4 l0 h9 j* V! O1 W8 R                ave += (max+min)/2048.0;
. V" u+ ~% w5 Q! v                output -= (INT)ave;
1 h- ~/ }  Q" K, M4 e6 n* q* c                }6 d; U" x5 R6 O; L  K( I' X  w% J
#endif# v3 `) ~8 W2 h
#if        1
& Q& u# @5 p6 m. ]% p                // DC惉暘偺僇僢僩(HPF TEST)
5 o6 s% [+ A: D. U( _                {
- u; b( R. o5 _7 g- s1 L* [' j//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);+ ]' ]0 Q, P9 `
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
( z% x7 _; @5 y% A                double        cutoff = cutofftemp/(double)Config.sound.nRate;6 ?' O3 ~- I* R" r: r' O
                static        double        tmp = 0.0;( e" p4 b3 Y( O5 l% P& F5 M9 Z
                double        in, out;
, z' O* {2 W* j0 W
6 Q0 Y' }% a+ c                in = (double)output;
7 ?  B% A$ g* g5 ^1 `- h: l                out = (in - tmp);
  {, W* t! W( O1 ]7 B6 b' J                tmp = tmp + cutoff * out;
$ r* U, h5 _" m  U2 l0 e" m; c4 U; I% g- ]
                output = (INT)out;
+ v8 y4 y* M  @. S8 u                }7 a) B8 i9 D& r) i# U5 N7 }9 k: x
#endif4 R* c# A: i. F( h* N8 l. k8 ]
#if        0
. @+ R' Y0 A* W& R                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)1 @" y# X/ ]/ \# ]" V
                {
- s+ Y, L- i1 A' @" m( g                INT        diff = abs(output-last_data);
, e" x# Z# `; N$ [/ L5 S                if( diff > 0x4000 ) {  ~) d# t# h/ A7 V$ c* x1 s
                        output /= 4;6 K9 H( K. \: M
                } else 0 I! p6 U& L2 p4 w& E
                if( diff > 0x3000 ) {
- Q6 {" c6 h7 Q# v4 Q* _+ H' m5 Y                        output /= 3;3 E, v  B$ p( w. g& O7 Q4 }
                } else
* L4 c+ g, f& F' N- u' y6 N                if( diff > 0x2000 ) {
; Y# C' j2 ?3 s1 j# X  V# k# P( d                        output /= 2;5 S3 U3 M. R/ T" y2 U1 S+ y
                }3 j; P0 I; J, o5 s) d: o5 j- O
                last_data = output;
5 D, q9 x+ y0 |' j9 H2 i                }
5 v- g2 @' ^5 t& M4 ^$ I/ k/ A#endif4 ^" j7 f# H2 t! P8 Z& W. X0 }
                // Limit5 U9 F4 w0 [+ k! M
                if( output > 0x7FFF ) {6 Q) h! a6 _5 |2 n  }; \( P/ P
                        output = 0x7FFF;& U  i( u0 A# U
                } else if( output < -0x8000 ) {; B. H5 b- e% ?: w
                        output = -0x8000;
% S" M: r$ _! {' K" U- e                }
- _1 H1 J' V  h: x; Z, q# {( R! o; V5 u8 [; ~% H
                if( nBits != 8 ) {, v4 n+ ?* x5 I) B$ B
                        *(SHORT*)lpBuffer = (SHORT)output;# p8 T3 _( v. W- J# a$ c8 a
                        lpBuffer += sizeof(SHORT);
  U8 h% Y% a4 o$ p- ^                } else {
- x+ a3 h" z8 V7 k! d1 ]0 Z                        *lpBuffer++ = (output>>8)^0x80;  [- d: O( p/ ?
                }
* o0 H( z0 ?% a" P# N& i: }% G# t9 m+ t, c
                if( nCcount < 0x0100 ): v7 p$ @9 o7 R6 Q- e. B5 x6 h4 s
                        pSoundBuf[nCcount++] = (SHORT)output;
& k& b% T- O. L9 }- A- v9 w$ l+ _# x+ @* l; G5 J4 E2 }9 |
//                elapsedtime += cycle_rate;6 \& i1 Z! c* U
                elapsed_time += cycle_rate;
# E8 p5 e& K/ A& L        }( H: x3 H% T; [6 r
; t& B4 ^7 z3 ?$ ~
#if        19 s% l8 O& o+ ~3 }1 k
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
/ W+ H! P  [* W' `' s2 B                elapsed_time = nes->cpu->GetTotalCycles();
) d, u9 W) v) ~6 P) A: ^1 a1 v        }( @# V0 U; Q5 Q5 V+ Z" E9 {! X
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {' q1 q  l( q9 b* Z3 n) l$ F" e/ h
                elapsed_time = nes->cpu->GetTotalCycles();
8 R% T0 M# N* J7 s4 g% ~, {        }
3 ~* V/ D$ ~, L* h$ T! X6 R#else3 ]/ ^( w2 D1 W8 X  L* y- K
        elapsed_time = nes->cpu->GetTotalCycles();( F* m. j5 |/ M+ _$ \0 _9 L8 M
#endif
4 x' g2 ^2 T7 J  Z6 D}$ d+ M8 W  [4 B4 Y% s8 j2 Y  x9 h

9 r0 h  n* d# Z& U6 R// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
: X4 }2 q+ W2 R  j3 P7 ]" w9 VINT        APU::GetChannelFrequency( INT no )$ e9 z' P6 ?1 ^3 ?" e
{
2 m  T- z, B2 g9 o$ W+ I( z        if( !m_bMute[0] )
; j# w: ?" i3 U! t* R8 i) @                return        0;
& J# L2 r8 M$ c! o7 x0 C; y' B3 X' U. n1 n5 j& L( l
        // Internal
6 V/ x. g6 T' ?7 \' L. \        if( no < 5 ) {
8 t7 g, K1 q0 c- e" |, o6 K/ ]                return        m_bMute[no+1]?internal.GetFreq( no ):0;
! R" T% O5 I) c$ j8 I7 c7 M6 J        }
* Z6 p6 E  C- N( Y        // VRC6
+ p+ Z' ^' b; ]$ h& m3 p        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {  ]* \; q2 |! e+ m; i  x& S
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;0 O' ]1 I8 P' u0 Y0 d/ E8 o; G
        }
- Z6 N, m8 u! \4 @* g; o; @; u        // FDS
) l, y& K/ @' F1 Q" d' x  e/ m3 C        if( (exsound_select & 0x04) && no == 0x300 ) {
5 b0 l! t" d9 f( M* G4 Z5 w                return        m_bMute[6]?fds.GetFreq( 0 ):0;
! N9 m5 l$ F5 }        }# f5 ~$ c' Y/ n
        // MMC5
9 w& s8 w6 K0 u7 e6 O        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {. M* ?, x1 @) n# Q# Q: T, F, V
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;7 [! E+ o4 ]+ ~
        }
/ y+ h% ^* D; r. t) \        // N106
, F9 _8 n7 d' W) q        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {& l, r0 d# x. `9 W
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;  X: y( f% g  d) W7 f
        }
8 W3 B# w  F. Z2 n2 u        // FME70 s. B9 c$ Y% d" I
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {8 e; Z" O; y# u  _; Y( p8 \# w
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
  Z( E# ]2 z# U( K        }+ G* N0 \% n" E8 _# v2 |: I3 H
        // VRC7$ K. r# @% d/ W% r  ]# t9 J
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
0 y# G3 w, h/ f6 b. k* x, R                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;( E/ v1 `% Y* _
        }
. L; I- {1 ]& Z- Q+ u& b        return        0;9 g- [# ], ?+ d& ^3 d4 Q7 s* G
}
4 U! e) I8 M$ L, n9 W/ C" F# b' }3 {+ H/ w
// State Save/Load
# P8 q1 y  o0 C6 kvoid        APU::SaveState( LPBYTE p )' E4 k0 L' \2 I* |# u1 K
{; b, K- q8 o9 z  G' [6 M
#ifdef        _DEBUG( m4 I: \3 |' p
LPBYTE        pold = p;
! `* C& B2 O7 O5 w# k0 i#endif$ S5 }. F0 o& I1 t
% N7 ?1 ?6 W1 P3 P
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
+ ]1 m, w% e! h  x5 d        QueueFlush();, b7 b' J, Q% I% i5 C

3 f7 T0 l8 I9 V$ E8 Q5 \& |        internal.SaveState( p );9 b3 t8 M% s" `9 U
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding8 `/ ]  R/ C/ ^$ \, t/ c
! l& b, U. n( L2 Z+ b6 N7 a8 H
        // VRC6% {) S0 r# b* |6 c- `. }) X6 n' _
        if( exsound_select & 0x01 ) {! ]( U: J8 J7 V1 T
                vrc6.SaveState( p );
$ B/ T, u) I  N% k( z                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
2 K& R; Y9 N& A" W) Z        }( k% ?" E/ `( ]& N! n
        // VRC7 (not support)2 j. l% y/ E- V$ ~: D. Q, d
        if( exsound_select & 0x02 ) {$ O# b( C/ T- s0 [) c- S+ Y
                vrc7.SaveState( p );) s# c5 X7 B8 g5 G7 p+ H, K! V3 j
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
; U- M- |- T- o+ k        }# `, [+ v& |$ U. }
        // FDS* ]: C5 a2 O; l% u/ \, W
        if( exsound_select & 0x04 ) {6 W# A: H6 x! \/ |
                fds.SaveState( p );
) j; q! h8 v2 |" ~" ?                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
6 d$ U6 w. r9 n8 I/ {        }
* C5 ?& T8 R4 H        // MMC5
8 V5 z5 f- D0 Y4 }        if( exsound_select & 0x08 ) {( l0 E% I( v$ D/ n- U$ J7 X
                mmc5.SaveState( p );
. q9 G! A) @) }- K' W1 x                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
" K( V8 |6 a+ E: n) y. X! H        }( X6 I  [& v- [3 H, O
        // N106
: i  r# l, j) J' c$ n& h        if( exsound_select & 0x10 ) {9 V: r7 |2 _- z
                n106.SaveState( p );
/ H2 t1 J" R  Z- q# L9 I7 a                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
9 n& g9 x+ b0 ~        }2 a0 ~  _- W* C. r
        // FME7
  O; v! H. W( c9 B3 B' B+ p        if( exsound_select & 0x20 ) {
6 U% s0 ~: b9 W0 T                fme7.SaveState( p );
  i- h4 k1 b1 k. X! d$ ?, W1 w0 [                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
! v$ i# E" K+ i, R  P- t) Q        }6 c9 ?2 g' C$ f. b
8 K( w+ q5 z; W
#ifdef        _DEBUG1 G- M5 w( e! }$ k3 e! q
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );) U2 `2 y* M3 ]/ D' D
#endif
2 d( ~; _4 l6 A: |, U; Q* U}
: Q) a1 }5 T* _  h% B
9 @/ |! B9 f* H% l8 Svoid        APU::LoadState( LPBYTE p ); C1 v2 d+ w5 r4 T! M7 L: W
{
2 }; M2 D1 W! z/ \( n" n0 b# C        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
$ i3 m" {, B4 g$ _  j        QueueClear();
& O8 [% J2 z! d6 d
& v# k0 @) L7 p% f* F9 Z/ H# o, M        internal.LoadState( p );
/ L3 p# f7 ^) t% n        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
" l9 r' |7 O. c, s
% t% e/ e$ E: U        // VRC6
5 \# H/ b5 V  c: B: B        if( exsound_select & 0x01 ) {
+ t) P3 T/ H5 W3 M' v* @, \' G                vrc6.LoadState( p );8 A3 v" R0 b3 q+ J4 C
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding2 r2 {6 a+ }4 q5 G+ H
        }
% }: E- e9 u& W0 f        // VRC7 (not support)
, l7 G( M8 J3 d- }3 Y  s2 `        if( exsound_select & 0x02 ) {5 x2 R  Q; Q) U$ l, q6 M
                vrc7.LoadState( p );! B5 }4 e. ^& J# @; ^+ N
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
5 D. z, i- Q+ U4 Y        }
% f! D. q' W, O" v$ z. u+ \+ o$ t        // FDS3 r% U, u; `3 d5 t% S
        if( exsound_select & 0x04 ) {
4 ]+ t  [* Q, E$ {+ R  T: M                fds.LoadState( p );% k  l/ f. f  m' a; ]
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding+ X7 `: b7 f' k8 U; {
        }
8 C1 \, p9 e8 Y2 Z        // MMC52 C  W4 \  k/ j* Y$ P
        if( exsound_select & 0x08 ) {2 ?. Q- Y/ n2 Y6 B
                mmc5.LoadState( p );; G' Y  ~1 _. }1 C2 s3 w
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
5 J4 j8 W! e" {; f5 t3 d        }! T1 l4 \! C1 v, V  `
        // N1067 U' [/ S4 U" N) F8 `# p! \
        if( exsound_select & 0x10 ) {- L; C  _# e( X! T
                n106.LoadState( p );4 n6 E7 ~! y1 V3 m# H( n
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
4 H  E% U0 I5 I2 `2 j        }# u, v: P% J7 o# I
        // FME7
$ g* j) O5 o) S& P( G/ T+ o        if( exsound_select & 0x20 ) {" B! J; J; z7 q8 |
                fme7.LoadState( p );
' M, {+ Z- }( j+ n* g" Z                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding! n  i: v+ n7 S; V
        }, O$ w4 c' w( {( _* V
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
# Q* ^6 C" G% c可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
, Y; B& n5 J8 q  _感激不尽~~
8 I5 D$ A' f) {$ p0 D
恩 我對模擬器不是很有研究,, j# [! X# \" K* b1 F
雖然要了解源碼內容,可能不是很困難,( v6 ~- c3 z+ ]* ?! r. M: G" A4 i
不過還是要花時間,個人目前蠻忙碌的。
$ m* j+ [( p/ q; p" b* y: D$ O( P$ P; \1 t* E9 h
給你一個朋友的MSN,你可以跟他討論看看,
. W: u5 g5 Q- D! W2 K7 M他本身是程式設計師,也對FC模擬器很有興趣。
- Q$ T5 R. P: h4 G* \  B8 ?% [: Q/ N. H2 A# w. w
MSN我就PM到你的信箱了。, r2 q9 x+ a4 m$ Q" {6 O: W% ~

) {5 ?; x2 S* F希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 0 L* d$ s! e; M2 U
呵…… 谢过团长大人~~
) q" c9 D' V0 @/ T7 g2 \

9 M( \' k5 D! N1 ?5 `' k哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
* D2 f) E3 g6 k; j团长的朋友都是神,那团长就是神的boss。
1 h' t9 V1 ?9 B, a+ H
哈 不敢當,我只是個平凡人,7 R' F3 b; ^( N2 W
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙- T* L! X+ X' @
ZYH
& k4 X; g6 |) w  Y5 a& n+ D5 UQQ:414734306$ q3 }: \  K" |/ E
Mail:zyh-01@126.com
% J* S1 [1 x* Z0 y
: X( W% Q# ^2 B他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
* r2 u! H, y+ g+ |4 I再次对团长大人和悠悠哥的无私帮助表示感谢~~
  J4 ]( i- H; Q" R6 z8 n
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-25 21:12 , Processed in 1.119141 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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