EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。  m; n, S# _7 b2 [) q2 w
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~7 B; }+ Q* T- R3 C: G; k1 ~% C4 `
这里有相应的模拟器源码,就当送给大侠了~~
1 p/ c+ F% K- @2 mhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
1 R& o0 I; ?1 I3 z能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。2 R2 c7 J& a5 P
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~9 f" B" k& @6 h/ H: u7 h; `
这里有相应的模拟器源码,就当送给大侠 ...
  V% |/ E& R" I4 m/ B- b
聲音部分(Audoi Process Unit = APU):
& M" X( J  K- ~; o4 K; H.\NES\APU.cpp
$ S3 J6 M/ Y% n. O& S  c.\NES\APU.h
; u. A; v# N! T; U' Y- o
$ ?! w& e9 B  T5 w. P  ~" `. g1 Q6 [( e5 {3 u- ^9 ~
影像處理部份(Picture Processing Unit = PPU):
1 @! D. J7 K7 t.\NES\PPU.cpp, f$ _6 J1 k! Q+ z, Z
.\NES\PPU.h- O! P" d6 a8 t2 T2 v7 P- D
: |+ n, ^0 ?3 {4 ?* ?% K7 K2 L6 y
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。1 c# d" B' }$ Z. n! |9 T! p/ r+ I
感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:2 @: I2 r7 G$ C0 B  g
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
$ G( M/ c: Z/ F$ R0 [//////////////////////////////////////////////////////////////////////////
' {; c- Q( B& d2 \//                                                                      //: G% q/ w7 l  U  ?# _
//      NES APU core                                                    //
$ o# V0 {, \7 z+ \3 z//                                                           Norix      //! a* v. C. \# R( z
//                                               written     2002/06/27 //
4 M) e5 y, F% n6 t: R9 T//                                               last modify ----/--/-- //( p) E* H8 K8 p5 \5 C) V# O/ Q/ p& v
//////////////////////////////////////////////////////////////////////////# T- q8 s8 s3 S0 N) A
#include "DebugOut.h"
: x8 S& p% R& Z2 E' i#include "App.h"- p) m0 {& |- G7 A! h
#include "Config.h"! }$ M3 }# a. u6 C, y2 B
8 T+ Q% B7 x& t1 _5 m
#include "nes.h"
, e% \* C# Y) A& l2 {9 v#include "mmu.h"  I$ O. p8 g8 ?5 ^: Y
#include "cpu.h"' Y0 g5 F( @# M8 K6 N4 S2 t
#include "ppu.h"
" s1 Z- Y9 G& ~( {5 y#include "rom.h"/ d6 b" w+ G8 r7 d' u' y+ g
#include "apu.h"
8 ?5 @# s5 v4 b& o* D! h5 S; r" h+ X! V" _- W1 U/ B: j3 ~' J; o
// Volume adjust# @5 J" M4 H% e8 l* Q0 N
// Internal sounds7 q1 j7 @( N3 n
#define        RECTANGLE_VOL        (0x0F0)
* ?3 d/ `' }* u& H% l#define        TRIANGLE_VOL        (0x130)* x& ?1 x: k$ [/ q4 E2 e3 f2 R/ v
#define        NOISE_VOL        (0x0C0)1 J$ q. `4 J: A, v' P  w2 N
#define        DPCM_VOL        (0x0F0)
+ L' H- T: ^. {. C// Extra sounds
6 H% L* e6 c, k- p. s#define        VRC6_VOL        (0x0F0)5 U( D. J! h1 k
#define        VRC7_VOL        (0x130)9 y: j  c1 m8 K* e, J1 B
#define        FDS_VOL                (0x0F0)
. {" ~4 A, W9 c5 [6 V" p8 }, ~#define        MMC5_VOL        (0x0F0)
# w) J. u. c: G#define        N106_VOL        (0x088)
* e' u+ c# t. ?, h#define        FME7_VOL        (0x130)
9 b5 H+ i& f" `: ]1 m0 H$ o
6 R5 z0 \- j8 W6 B! n* S: j8 sAPU::APU( NES* parent )0 z" n0 R7 D- M, F
{5 E/ X: |$ @+ S
        exsound_select = 0;; ]5 P1 h* \7 q( w/ X
) r: l4 K- r' Q& m2 W
        nes = parent;
# F- [* w; }/ ]. O0 E        internal.SetParent( parent );$ f) w" N: q* X7 M7 f3 ]. m
; U. P, ^! C8 A' ?2 j3 h+ [
        last_data = last_diff = 0;- j4 V" o( |( E: P8 k, A: Z1 L! ^
& K2 Q% C% b5 F8 a
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );" l# }2 x# M; F! R2 v
2 Z# e3 ]% _0 N( {$ \
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );. c- X4 l1 R) L! q  f/ e. W
        ZEROMEMORY( &queue, sizeof(queue) );
9 U3 i- l( M2 R6 g* Z' g' ]        ZEROMEMORY( &exqueue, sizeof(exqueue) );% V+ x1 x, e5 N$ J. o+ l

, z4 A: t+ m% t# I) B9 i( I        for( INT i = 0; i < 16; i++ ) {
9 E9 |- U- Y' a. @. p7 ?' x                m_bMute = TRUE;5 ~8 B4 z4 Y3 i3 B: `- [
        }% B- [' U, Q% K
}5 z% u+ l; W5 @8 V6 ~

) t' W3 N/ P# w1 I# _4 ?APU::~APU()$ b" ^/ K0 H$ a  B. N# r/ e0 r) C# H
{
  s1 e, _, f: l0 a' w# x}! u- x: z$ {: _
! [4 Z0 w* ^) c" _/ M9 w
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )  f, s7 e; S1 c3 C) S
{9 m( w+ q$ \  L! j
        queue.data[queue.wrptr].time = writetime;. j5 i+ ~& C: U9 @8 F
        queue.data[queue.wrptr].addr = addr;) q8 Q6 I# |2 U; g# x
        queue.data[queue.wrptr].data = data;
( @; o0 X6 p" o+ g, J        queue.wrptr++;/ n! Q) j: [+ |; @- P6 s
        queue.wrptr&=QUEUE_LENGTH-1;
, S( c) h5 N, _) c3 o) }8 d$ T        if( queue.wrptr == queue.rdptr ) {
/ |, b6 Q& o' T* |4 l                DEBUGOUT( "queue overflow.\n" );
# {9 k! Q- c# \0 U        }4 o( D( y- w8 F/ p2 h; M4 Z7 n  y
}& P( }" `4 M5 D' o$ i

, I8 B8 E( z0 {5 CBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )+ c1 k/ U- E. Z" L( ?
{
$ D- `4 z- G$ |9 N: y) p; y- I( J0 W$ u        if( queue.wrptr == queue.rdptr ) {
& I- I% O. Q& N9 Q7 D* j( g                return        FALSE;
, k& I# z' O6 b; D2 X6 s8 U% P        }) ]6 V! y; _6 s+ M" [% I1 B8 e
        if( queue.data[queue.rdptr].time <= writetime ) {0 c) y& H' L3 a7 T5 n
                ret = queue.data[queue.rdptr];
/ V: U0 K; Q( g* ~                queue.rdptr++;; t2 P4 g9 E0 Y( S9 X$ a. c; D
                queue.rdptr&=QUEUE_LENGTH-1;
& i( |3 s, M% i! ~. K, u                return        TRUE;
* R1 }( \- ~' F' I        }
1 k/ |% z' r2 u% U0 K        return        FALSE;
3 L) k: O6 S. j; b' N/ ?}
0 s8 L$ f; e$ `" c8 h/ S9 h
+ g6 q$ V0 c8 uvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data ); Z1 H3 m, x; O7 J8 k' l
{
" y- y6 V2 m3 U# w/ B* t- y        exqueue.data[exqueue.wrptr].time = writetime;
4 Q& o# o' S- k- ]" F        exqueue.data[exqueue.wrptr].addr = addr;
1 A- T5 V6 U! v- O+ P$ b* n        exqueue.data[exqueue.wrptr].data = data;/ J! ~0 ^0 n) ~6 K% o+ z
        exqueue.wrptr++;# H% e$ c# K& d, }7 w$ u
        exqueue.wrptr&=QUEUE_LENGTH-1;: B# z% H5 q5 \( p+ C
        if( exqueue.wrptr == exqueue.rdptr ) {
. e- U2 i: \" a+ {" D                DEBUGOUT( "exqueue overflow.\n" );
. k: g) S1 N3 j4 c4 G        }
" l/ w9 [# u8 B" G4 d! [. k}
# n" k" z7 L/ a+ q8 ^+ I, ]8 c; K6 @( }. y$ S7 k! m5 a
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )$ o, S! H  }, Q  H! g
{
# s* J9 e5 y2 j( I) z        if( exqueue.wrptr == exqueue.rdptr ) {, V1 F4 a0 f4 A
                return        FALSE;( K& ~: q+ w# m2 G% i) _4 A' ~
        }
) H( }" ?0 i- o; c        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
# T% e0 W. B5 s9 S8 L- I                ret = exqueue.data[exqueue.rdptr];( ?2 g5 a# }) E0 w) L0 G
                exqueue.rdptr++;
+ u# R, k, s! P( B# P5 d                exqueue.rdptr&=QUEUE_LENGTH-1;2 J; ]8 e# B1 U
                return        TRUE;
& }- [& G8 V7 X6 H        }
& H5 @1 Q/ Y  g+ O& I7 E4 {3 i- ?* r        return        FALSE;
; _: {1 n7 K3 H' K* l+ u1 B}
5 Q' R$ \" e- u1 n6 Q* @
* G+ W; b9 p$ O4 B' |void        APU::QueueClear()! B$ @' z# W- X9 f& l! C& q' a
{3 V: X- ^+ ?" C* I2 F8 j
        ZEROMEMORY( &queue, sizeof(queue) );6 Y: g# u& m6 n9 o* D! g
        ZEROMEMORY( &exqueue, sizeof(exqueue) );! b- J9 h( Z; r) I* ?" g1 A; X
}8 X/ N! |  U5 r1 j. w

( [1 m' ^+ w6 P6 J5 Pvoid        APU::QueueFlush()+ \! C1 Q2 s) g1 x" b3 i3 ^: M& w
{& N3 Z9 u; y& S4 Y
        while( queue.wrptr != queue.rdptr ) {7 J, G1 W. v4 r% q) @% z
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );) l0 [- J1 I7 ]) p5 o# a0 H9 I
                queue.rdptr++;
. ^/ D% I' H, ~; I+ A                queue.rdptr&=QUEUE_LENGTH-1;8 |" B$ f% D' h) I2 X
        }
2 J5 N& e1 A5 r! o+ B, O' A: T/ i, C5 j0 B
        while( exqueue.wrptr != exqueue.rdptr ) {) B3 P6 j  M" E, p
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );. P, x# h& @( N. B3 |# V
                exqueue.rdptr++;
% _1 X/ g. a  G9 l4 v/ d3 B" }                exqueue.rdptr&=QUEUE_LENGTH-1;
! k+ p2 O1 [+ X' Y2 O        }
  o8 I: s+ S# t3 ^7 `. F}5 D6 @+ C( N/ t2 y2 x( m" v% w
- P  b8 r" R4 ?$ l3 E9 g5 Q
void        APU::SoundSetup()" u, @! i7 f9 j5 z1 |
{( o3 b% Y% |% T. i& g
        FLOAT        fClock = nes->nescfg->CpuClock;7 y$ S$ W, ^$ U+ d3 X+ D& X
        INT        nRate = (INT)Config.sound.nRate;/ n4 _. G9 q2 R' H
        internal.Setup( fClock, nRate );9 v2 |, M. {0 D- ~6 y; h
        vrc6.Setup( fClock, nRate );
- H3 R( j0 A$ r; s6 C& g        vrc7.Setup( fClock, nRate );
0 F4 u7 _1 D5 k! L2 L        mmc5.Setup( fClock, nRate );7 x9 a7 C2 @% b0 j
        fds.Setup ( fClock, nRate );* m2 B3 c, S& I! C
        n106.Setup( fClock, nRate );
7 F# H8 I/ c9 Y. H! k$ D        fme7.Setup( fClock, nRate );
- y/ b! ^+ X0 x* s, C& f- @}
5 U1 X+ S8 T( I" P7 a% S( v( G1 c- u
$ R+ a" r& W% N9 C  p( Mvoid        APU::Reset()6 ?0 E1 g: {. H1 U# ~  w% `
{) [% d% _  |: g1 Y* J3 ]
        ZEROMEMORY( &queue, sizeof(queue) );
4 G! h% L2 Y( l- J) f$ Y        ZEROMEMORY( &exqueue, sizeof(exqueue) );. R) |- r% w. y' \0 b8 y  e; ?2 P

0 b( }. B5 K& p) s" M0 A        elapsed_time = 0;& @  h4 c5 M" F8 q

5 F. Z9 _* ~3 r- e) e5 \        FLOAT        fClock = nes->nescfg->CpuClock;
+ m9 R3 k( o/ F" f# T, s        INT        nRate = (INT)Config.sound.nRate;9 I2 v1 Y/ Q9 V$ G% A' e- t
        internal.Reset( fClock, nRate );
2 W$ Y2 y5 V$ |+ }9 Q8 B2 N        vrc6.Reset( fClock, nRate );
" U1 g6 m  V7 X; W+ S  o        vrc7.Reset( fClock, nRate );; |( j  `, ~6 W
        mmc5.Reset( fClock, nRate );6 a$ P/ `$ i" _0 B7 Y
        fds.Reset ( fClock, nRate );) k6 ^( g* j( f: ?1 X* X- F+ T
        n106.Reset( fClock, nRate );9 X7 p6 X" d. F
        fme7.Reset( fClock, nRate );/ @' g) {5 Q7 v2 d# N; k
' o. O2 U) k* w5 V1 Y$ e
        SoundSetup();
8 J4 _3 G% O& W* }$ q0 @}
0 {8 d% K) }8 q3 ]
0 Q$ T1 ?' e+ h. ]7 Nvoid        APU::SelectExSound( BYTE data )0 ~3 d0 l& d* }) {; f% `
{6 G# y4 g5 Y% O5 e
        exsound_select = data;/ @& y9 M/ h5 i6 @
}
: U7 [/ ^# ]4 ^/ U
; a, `' t; ~1 ^9 i3 o9 HBYTE        APU::Read( WORD addr )
7 B, b* y6 Y" q3 m7 F) n- `{
* }3 `! \0 Z, h        return        internal.SyncRead( addr );
! _9 V+ f6 [* S- X8 U}
1 s2 B7 v8 h9 D, v) N* O3 w* C" n& b2 p- b% G, G
void        APU::Write( WORD addr, BYTE data )
' }; _6 j1 n. h9 o& c4 h  e  C) Z{9 l; ?' C/ S9 f
        // $4018偼VirtuaNES屌桳億乕僩
) H8 I4 b( I( e/ w$ {' [        if( addr >= 0x4000 && addr <= 0x401F ) {- V  Z4 m3 E+ c4 L+ I3 s" D
                internal.SyncWrite( addr, data );2 ?/ I7 V7 E( b1 x( t
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );1 x$ v, R: j' K' X, l" B
        }$ q" a& C) c- A" Z2 z$ ~, X* N
}
; Z0 \% U) _3 M& V# W% ]% P; Z* m5 X, N( e& z. X- F3 y
BYTE        APU::ExRead( WORD addr )8 E9 Y, a7 l! [, Y' Q
{% h6 [3 ]5 H. a9 `5 g. o5 b
BYTE        data = 0;2 f4 D5 }0 q6 k9 a  o% f4 A! x
8 s- j# ^" e8 y4 q
        if( exsound_select & 0x10 ) {
9 l4 z* T' ~, K$ F+ c4 K! {                if( addr == 0x4800 ) {/ R- }/ }3 F9 v" {) S
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
" c/ g! D4 R1 H& p1 P! i                }: H0 s8 n+ b$ @2 T5 ~- w2 c8 B5 S  x; s
        }5 N& |6 k% z2 ^/ E/ b) q
        if( exsound_select & 0x04 ) {+ a$ t& Y9 j! [& z
                if( addr >= 0x4040 && addr < 0x4100 ) {' T% {& v% ?9 a- E  }3 z
                        data = fds.SyncRead( addr );
% S) k* q/ D9 S* n+ ~# K                }; r- ]% v7 t) ]: R; L
        }+ J5 v% f+ O$ H8 p7 Y
        if( exsound_select & 0x08 ) {! @5 o3 x+ Y$ P# }' ?7 R: l7 M5 s
                if( addr >= 0x5000 && addr <= 0x5015 ) {3 \; k" K  H6 w" ^% n, h  `3 \4 `
                        data = mmc5.SyncRead( addr );
1 Z( O1 c/ k- I- w4 o6 c                }5 Z. j' J5 J! P( ?
        }
1 J- A0 ]5 N  k/ a# A! R; j1 i! K+ S. A0 M& `6 K5 V$ c
        return        data;
$ q; N5 G* M: {/ E  M# [: A/ V}
8 P4 H- q; F2 K
6 x, r( g. [% r( {( E, Fvoid        APU::ExWrite( WORD addr, BYTE data )
8 X: s  y8 j+ o3 Q6 O; K6 p* @( Y{# h' p5 |6 @7 y$ }. x
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
2 N- Q% J' J$ w5 Z; P, A7 g/ X. f- F# c1 ]+ d' ]( W* l- b6 T
        if( exsound_select & 0x04 ) {
8 N" f$ w7 O7 m4 M( n                if( addr >= 0x4040 && addr < 0x4100 ) {
3 X" ~0 F/ ?' B0 F                        fds.SyncWrite( addr, data );$ R! ?4 n, {6 ^1 x% n. i! i% W4 w1 |
                }
( T8 h" }3 H; |! k, i; m        }4 {/ {9 s: c" _6 _5 V' M  ^) P5 t; }
" K, e9 F9 U5 t& p, z7 P
        if( exsound_select & 0x08 ) {
9 g) S" O2 i- W+ N$ U% r                if( addr >= 0x5000 && addr <= 0x5015 ) {
. n4 o$ n7 A3 i7 R7 A! G( f" ~8 ~                        mmc5.SyncWrite( addr, data );, c+ b1 E4 B7 f" R- d: R
                }" q) I3 _3 G1 X+ ?+ e, W
        }
" C) x$ s  ^6 |! s1 X) B  K}
/ `& j* H6 i" i1 k5 R; s; j2 U  U  J7 o  F5 n
void        APU::Sync()
7 N( H1 y, n5 p7 J+ P! `' |{
& T6 @- ]9 a# J& b$ M( c) z}
: f) W* g" U6 D6 r+ I6 d! C4 \$ @* t0 W( q5 s
void        APU::SyncDPCM( INT cycles ), z7 H! q- Z9 i% c" c  k% g
{4 l3 R/ L: `  z6 Q. K7 ~4 [7 ^6 l# |
        internal.Sync( cycles );
9 }4 P4 {+ p5 {3 o. k1 {5 t" m7 o. a
        if( exsound_select & 0x04 ) {9 R* o2 j! C4 H- T
                fds.Sync( cycles );2 A; n" w7 e* \9 Y, x. h; a8 {2 `" t
        }
! F& x) X, w. n5 z; r4 L* |+ R9 K        if( exsound_select & 0x08 ) {6 ~: I  z& _% E- C, W( v: d6 R9 c; T
                mmc5.Sync( cycles );
! y8 G4 T2 }: A7 D        }2 `2 ]! ^6 \. \1 C- {
}
# @( W1 m. M' L- _  r
. C! v/ P' ]# n  D: Mvoid        APU::WriteProcess( WORD addr, BYTE data )- g: j& I6 N8 O1 v: {# K- z! Z
{. h0 L0 {2 i! c/ s$ s" w
        // $4018偼VirtuaNES屌桳億乕僩0 p  P9 r/ f# a
        if( addr >= 0x4000 && addr <= 0x401F ) {
  j9 Z* A$ R) Z4 W! b4 j/ p                internal.Write( addr, data );# K# f! S5 J4 K+ f7 c3 P. I
        }
: \: o) r- N( j6 c! {}
+ o( Z0 R. O/ ]
; v8 \# S! ^& e6 y* Z/ r% p% Jvoid        APU::WriteExProcess( WORD addr, BYTE data )$ _( c# S& Z  a0 r3 ]) @
{
" B2 b- @6 H0 U) p7 z! t- d( m        if( exsound_select & 0x01 ) {
* G7 l5 L( ~! d                vrc6.Write( addr, data );
( v0 V& h; i: g1 c) p# X" q        }
7 d  ~/ P2 B  K        if( exsound_select & 0x02 ) {
$ b1 c7 A8 s& F' N1 g                vrc7.Write( addr, data );
3 Y: n. A1 n! D* h! B( l        }' ]! q& g9 Z' K7 i* [3 M
        if( exsound_select & 0x04 ) {$ |" J5 r% i+ y/ _) D% i& t
                fds.Write( addr, data );, a4 v, P% S2 {% L" u7 Z
        }0 V, P$ m  A$ Q+ z& L
        if( exsound_select & 0x08 ) {# W+ W7 T6 x" W7 e( M& u& @
                mmc5.Write( addr, data );
! |! x5 W9 h/ n4 ~) D        }
$ W" J" `, u% Q% _0 y  f4 ]% T$ ?1 ]        if( exsound_select & 0x10 ) {0 |' _% D& |+ g8 b
                if( addr == 0x0000 ) {
  T6 Q5 B, l& Y  T                        BYTE        dummy = n106.Read( addr );( v) q7 w  G6 o) S' O
                } else {
" ?7 Y! ^! X4 V( L                        n106.Write( addr, data );
+ R' g, F7 M3 I( u                }
$ {( z1 Y( f. Z2 L3 A4 N        }) h8 c. @4 H% A; v. [; @
        if( exsound_select & 0x20 ) {& {* a4 {8 A& R  H! G
                fme7.Write( addr, data );
* W" p% R; i0 J( M' I        }
8 v4 k$ s* r0 y: \: r* W4 C# `' y}; n$ v% D" _! @! @3 a. G( j
2 @) S' G- i& V8 K. t- U
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
# t1 n+ B9 w) V5 w! y9 i$ c& l, e{
: ]& M# g2 k' k+ p/ e' d% T9 lINT        nBits = Config.sound.nBits;0 V1 d# T& G+ Q- ]& x2 o
DWORD        dwLength = dwSize / (nBits/8);
" G* t/ v$ J0 O3 P7 k: }, FINT        output;
: {* l  J; e$ V& p! |' k! aQUEUEDATA q;
' r3 f; c" ~/ |2 XDWORD        writetime;
8 t- S) ?& r# q
1 f# E( K0 U9 Y1 M$ j4 p' lLPSHORT        pSoundBuf = m_SoundBuffer;7 `9 \2 C$ u. t, ]
INT        nCcount = 0;& O) X! K- g4 l: A2 s" V7 \
* Z& \5 u9 \# L) x: w
INT        nFilterType = Config.sound.nFilterType;% Q, V4 b9 N/ J! ?$ K# B
% Y. u  k5 {$ ^8 H& S% W" \4 c
        if( !Config.sound.bEnable ) {- U; p$ z/ _( }
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
4 E! Y+ p1 s9 z                return;
8 q4 u$ R2 q$ a' h8 R2 o5 E        }
; \9 f$ E1 H4 `/ ?& _
# \2 b3 y  A9 c        // Volume setup1 y: @& s% D) w. l' ?6 _
        //  0:Master& a5 W% M; ]1 c" T2 L5 I
        //  1:Rectangle 1
6 H3 t% W  L# }: r, Z& B7 h        //  2:Rectangle 25 C2 a/ ^" \9 Y3 L0 r
        //  3:Triangle
$ S/ n/ `( k* ^/ e" o        //  4:Noise
7 Z, w) s" I; {" [        //  5:DPCM
  y& R) P7 u7 j$ ]* f- D        //  6:VRC6
9 b! O. I* l; V+ [# ?; U0 j        //  7:VRC7! j6 u/ t/ t3 p; u/ @
        //  8:FDS
% `5 ~# R2 T2 E" E, F: ]7 q        //  9:MMC5
' q3 Y/ A9 A3 O, [& y        // 10:N106
0 ~$ w4 Z/ N+ ^        // 11:FME7
9 a7 P# p2 O4 x) q& ^6 U( J        INT        vol[24];0 ]/ v0 j8 a4 l' B3 E( a( J* g
        BOOL*        bMute = m_bMute;; c: n; B" x. \/ L! M) z0 O' E2 v
        SHORT*        nVolume = Config.sound.nVolume;- O; r5 S. k8 h
" u) V( Z/ z% w. `' w
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
+ W) W2 P0 A8 S7 N: Y5 _# v; u+ {- [
4 d8 `5 D# Z6 f% b& t: D        // Internal
, S& E* r5 K+ L  A+ y        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
( ~& z) \7 ^; e/ c* e        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;) j. m0 W/ o0 \! E3 n+ x) U
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;. w3 k& Q* p( Z! Y9 g" [9 B, c
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;5 i1 y; O1 B2 Q
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;9 x& l5 T; N/ l2 r

6 r0 B. V* s* K4 d/ F( A        // VRC6% i9 i1 ~+ V; }
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
4 _2 a9 Y$ h8 o9 Q5 B) X- l        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
0 D- ^$ Z6 t+ {0 K        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
' A9 f+ i- p8 y) ]' l8 F$ Q6 ~! c! A* ~" U- Y
        // VRC7" D! Y- h+ N1 s; f' J# d) l; V! N
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;" R3 T7 E8 X4 A
2 T/ @+ _( B! K; Q4 X
        // FDS
4 l6 p) u5 l7 G# m. D$ E        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;. N- W# ?) Y8 T( r

" S9 `' Z- s; A1 }. B        // MMC5
$ e& C+ `$ \3 X% N        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
0 E% e, V0 q( F$ a        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
+ ^  p% e- h$ ^0 u& L        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
0 Q, i& c7 ~$ n
( I0 T2 `9 X& m5 W/ \        // N106( c, d3 c! I3 i; f1 m: ]
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
' [) P6 A9 L, I' w& s3 h# L        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& L! g& p! I% j8 e' }# s        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: @' q/ T9 C" f        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
% g' a; q, O3 _        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;2 N- c# v3 L) k  H) `+ J0 o- a& P# @
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 F9 d: k$ N" {( E
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
4 ^9 j7 ~1 v: p2 ~1 r        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 u6 B* L+ K4 N: {0 l
% G0 s: v" l9 e+ D7 e        // FME7
  K1 \1 U4 |7 g! r  p3 C: L" a7 h# e        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;7 T" n6 o# ?5 C- {- a# ]5 X( ~
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
( Y- n+ _& |. u        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;$ C3 |4 X# V8 X
+ v4 F1 D7 S2 f* b- ?
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
3 m5 C" `9 t# o- G% W        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
  @5 H1 h& [* s$ N2 H9 r3 c# E
6 N3 L9 e4 c2 C2 g        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
- u1 V. ~, c9 ~4 b! B6 n        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
& E  ?% ]) U6 ~/ P$ g- |                QueueFlush();
0 _. p; `/ ^9 O/ S+ |0 E% O        }3 x& s  {% b, V) r
0 a# b. W' ]" g2 p- Q
        while( dwLength-- ) {" ]% F1 q# V% F% _
                writetime = (DWORD)elapsed_time;
3 |5 O- G+ F  n0 N6 W
7 G6 p, T% F1 k                while( GetQueue( writetime, q ) ) {. W" i+ {9 h5 |* J0 t6 r
                        WriteProcess( q.addr, q.data );! n3 W' W2 C0 E/ w" M+ N7 I! Q- h
                }- Y+ z6 O" m$ u) `- ^% d' L

1 z" m# ]. l  _- k                while( GetExQueue( writetime, q ) ) {
4 \3 u7 l8 Y6 q0 A                        WriteExProcess( q.addr, q.data );0 F0 t% H$ C1 S0 y) x" }
                }' B( C! H: _* [. q' L5 h
: `8 \' W+ [5 y  h8 b
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7- ]1 h8 H- ]+ v4 H
                output = 0;
+ g* [- |2 y) f7 c7 S                output += internal.Process( 0 )*vol[0];
- f& s7 v5 K, E& R                output += internal.Process( 1 )*vol[1];
! R* S6 K% B! X: Z' |7 r                output += internal.Process( 2 )*vol[2];) r/ E( j- r" R4 ?1 H7 a
                output += internal.Process( 3 )*vol[3];
4 i; E$ ?% }1 V; L                output += internal.Process( 4 )*vol[4];
, y6 H0 K! ?0 u, N  R5 p: W. ?/ `- L9 h) C. }
                if( exsound_select & 0x01 ) {
1 Z6 m1 f: u* x3 v( ^                        output += vrc6.Process( 0 )*vol[5];" }2 G: L! ]7 q7 p5 y
                        output += vrc6.Process( 1 )*vol[6];- {4 M: D  g/ u; z; s* h; U
                        output += vrc6.Process( 2 )*vol[7];
% m5 w, w) i3 A5 s/ @+ V4 C                }
% M) ~( B: }- N7 _" S2 I; ]/ X                if( exsound_select & 0x02 ) {) W5 n, z2 T' N* p) g' N- g+ A  a
                        output += vrc7.Process( 0 )*vol[8];- v6 }3 Y# W) w0 t2 N
                }
  E/ D) ?$ f  \: c* j  W5 ~                if( exsound_select & 0x04 ) {
- L1 Z' x* D4 i: J. k# q4 j3 s5 U                        output += fds.Process( 0 )*vol[9];! E. W$ _; f: B: F% ?  P
                }
, i+ r+ j# c6 K% X' s; q. A                if( exsound_select & 0x08 ) {; T  ~: B& e- x% G0 F7 Y
                        output += mmc5.Process( 0 )*vol[10];9 r% Z0 m1 M/ w% ~2 u1 V5 T
                        output += mmc5.Process( 1 )*vol[11];/ k) y5 k: g& ]0 t# `) U
                        output += mmc5.Process( 2 )*vol[12];
! \! E- ]* ~) ?* e, r( O                }. P  r4 ~0 {* [
                if( exsound_select & 0x10 ) {, B- _$ a- ^; x
                        output += n106.Process( 0 )*vol[13];
- P. ]' J1 A4 H" n( D' y4 }& U: K2 j                        output += n106.Process( 1 )*vol[14];
3 m' e* l% y5 K9 j6 y; j# q- F8 k                        output += n106.Process( 2 )*vol[15];
" s  u% F. A( I4 r# f                        output += n106.Process( 3 )*vol[16];! H8 L* o" q) Z" h2 m- m
                        output += n106.Process( 4 )*vol[17];) \" c  ]2 `, S8 b
                        output += n106.Process( 5 )*vol[18];
/ k$ }% ]  |4 o                        output += n106.Process( 6 )*vol[19];
: x5 e; ]/ _7 H  P6 O                        output += n106.Process( 7 )*vol[20];
. O8 R; q! a. L" ~8 G" l7 g                }
# S& c! s* M- I                if( exsound_select & 0x20 ) {! n& N2 J+ h% A. h7 D
                        fme7.Process( 3 );        // Envelope & Noise
( N- m9 ~' U+ K6 b                        output += fme7.Process( 0 )*vol[21];& K' H. {, t* w% D
                        output += fme7.Process( 1 )*vol[22];5 l( q2 {/ g& @7 F( e; f. L; |
                        output += fme7.Process( 2 )*vol[23];
3 D3 E# \' i/ I* K4 a$ ?                }
- T. c" q& m! r. u* ?+ n" l! ^4 p
* h; O* |+ b* p% A" A- S                output >>= 8;
6 _6 \3 C0 w1 U! P" C0 n$ }- v5 x# T" ^3 _" N7 V; b
                if( nFilterType == 1 ) {- O( M; P# m$ U4 B; r+ D7 h, l& h
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)2 z$ m  K' C9 ^
                        output = (lowpass_filter[0]+output)/2;
1 {# T& {5 V) A7 Y$ U                        lowpass_filter[0] = output;
9 @, k+ M* E: q8 i4 Z                } else if( nFilterType == 2 ) {
- L. w0 r+ N. G5 f! R                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)( T, X5 {7 q. h; |" r0 I- R
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
4 ?: m" j( m1 r* V5 L                        lowpass_filter[1] = lowpass_filter[0];
, {6 z& F3 N$ ]                        lowpass_filter[0] = output;
5 F  w; u: d' B  X# O" d0 j* C                } else if( nFilterType == 3 ) {! q0 _3 f5 D% W: q" e* H+ J6 X
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
' w2 C! V! `9 g3 u6 n; Q8 w                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;# ^. K; h# x: l$ \
                        lowpass_filter[2] = lowpass_filter[1];1 \2 I! Q. P* W0 u
                        lowpass_filter[1] = lowpass_filter[0];
/ T9 h* [5 w$ m$ k; b( _, V                        lowpass_filter[0] = output;9 \/ Q/ L! z$ I3 F- v9 h
                } else if( nFilterType == 4 ) {
  K* i' c6 g( ~! U+ |, g: A0 _! n                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
$ W$ W# N3 ?$ i. B2 p/ f6 N                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
3 w  j) i% s/ z( c' c                        lowpass_filter[1] = lowpass_filter[0];
% b" q# m$ E  J& A1 f                        lowpass_filter[0] = output;; r4 A+ Y: c3 q& @, p
                }1 b6 l8 h- E; @. k3 n( C# C0 \4 L
5 o3 f9 u: t$ x4 \" R  i3 N9 X( |
#if        0- N/ ?, ?" I  E' P" w* f' o$ A
                // DC惉暘偺僇僢僩  A) i4 Q8 D% r5 \' M+ x( X3 d3 H* g+ e
                {
% s0 y3 h0 Y& v2 W* K                static double ave = 0.0, max=0.0, min=0.0;
# w, i) r! @8 d                double delta;, \3 T8 {5 \& M
                delta = (max-min)/32768.0;$ }. u. ]$ @# o
                max -= delta;; _7 d, i+ G7 k" ^; a4 m
                min += delta;4 e# I# ]; |! R4 j5 K- k
                if( output > max ) max = output;, Q& S: f: w+ x( z
                if( output < min ) min = output;( |' F$ b2 k4 v9 _; K. U# e
                ave -= ave/1024.0;
/ Y- f+ d% H" K" c" p                ave += (max+min)/2048.0;  _4 l% s) l' G. A0 i1 ~
                output -= (INT)ave;$ B% K0 u" M: v" W  p  P
                }
* T9 y$ A5 B: X% j' O, F9 P" h#endif, C, M8 q$ c4 c- w* y6 z, O
#if        1* z2 s& L9 s) B- J7 ]4 T
                // DC惉暘偺僇僢僩(HPF TEST)! t4 \3 k2 F3 r5 {& I, d
                {1 {/ K! ?  y) L$ r1 u2 Q
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);( \# h- |" {2 @( r6 d
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
( z$ l1 _' S; M* l: Q                double        cutoff = cutofftemp/(double)Config.sound.nRate;9 ]$ j3 |; S( |9 y" r
                static        double        tmp = 0.0;/ y: O8 ?$ R" x7 G% N
                double        in, out;
+ L- p- i8 G3 k/ @* C. v8 ]$ p1 L. z  w% U$ E2 @
                in = (double)output;# ~  v( t7 V% [# p# h6 L. g
                out = (in - tmp);
$ N1 f* o) }: m* A4 Y' m                tmp = tmp + cutoff * out;
0 T) |" G/ D2 i3 W  G
! B% V. r. y5 H8 F                output = (INT)out;
6 I! Z# l* d# I  A$ ]0 e5 j. a                }; Z2 T6 N3 \; V. D& p: L0 P
#endif
2 ~3 E/ F( ~2 o7 p  \#if        0
8 `1 d0 y+ w$ Z* {: Y                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
9 K3 S/ v: q- d9 F# o8 x) K- w: O9 M                {
+ I- i& f* W1 f5 A( q                INT        diff = abs(output-last_data);1 x. u& B0 T' f' s) Y
                if( diff > 0x4000 ) {
0 ^, F* |/ O+ X8 n6 n                        output /= 4;6 y$ g- [2 U4 P' a. |$ z1 X9 _2 @4 ?
                } else
1 C1 v: M; @+ h9 m2 X! P0 i. J) W! V                if( diff > 0x3000 ) {
; @; ^. d* W# o) E' W                        output /= 3;
$ t/ Q# Z' s; a* h( A                } else' d3 H! C$ x9 e1 O+ U' N
                if( diff > 0x2000 ) {; b/ T. [' X, r$ r3 A+ m
                        output /= 2;$ B* L! Y$ o9 Z$ l- G- v0 }
                }3 L/ x3 U, @8 Y; D6 s8 I1 Y
                last_data = output;
" v% A9 O7 t( ~+ K& n4 t                }4 |' E4 I  n4 r, |
#endif& p5 [, J5 z( j# u$ k# c3 W
                // Limit  |2 O% z: n; q( ^
                if( output > 0x7FFF ) {
4 r, \! j2 \9 _5 S                        output = 0x7FFF;* K. _' r" B8 S* ]) j0 n2 P
                } else if( output < -0x8000 ) {
# O6 E% R' s# h* |2 {- P                        output = -0x8000;
  R- r, }+ N* L7 J- l$ s, ~                }
7 X" D) k. G! }6 S* v& i1 M0 [) N- ~4 W% f# u: v: J' Z
                if( nBits != 8 ) {
. U6 G0 I) e* z0 x4 X                        *(SHORT*)lpBuffer = (SHORT)output;* x8 A1 f+ ]0 X+ u$ R, V8 w1 w/ C- `
                        lpBuffer += sizeof(SHORT);# h/ r) @! s9 Q8 O$ _
                } else {# s  _4 L: R. m
                        *lpBuffer++ = (output>>8)^0x80;5 [8 a0 C2 r( H$ v0 p
                }
! ^; b1 d$ h- L/ r- x- E1 J8 y3 \, L, {
                if( nCcount < 0x0100 )
& ]1 r" B$ O8 @                        pSoundBuf[nCcount++] = (SHORT)output;
" l, z& ~8 P4 A1 m6 `5 T
3 K. G8 M  v% R, S9 W7 c# ~//                elapsedtime += cycle_rate;
; x' M7 ]6 N: R) {& P: \( ?                elapsed_time += cycle_rate;/ ^% M0 B. [* {3 f. T
        }
, @" g# `" `) p9 X  B  c" D5 q! O( `* p4 q, U
#if        1' x; b2 c0 G4 P" j8 \
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
/ }0 l0 |7 F7 Z% T" W6 f! f3 ]9 I                elapsed_time = nes->cpu->GetTotalCycles();% c1 @+ V- K7 k- M' W3 C& e/ k
        }
" ]6 G/ j; {( B; {        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {9 p5 V: o3 v4 I" }4 [
                elapsed_time = nes->cpu->GetTotalCycles();" F3 w$ j( n) U' l' o
        }: S3 r8 K" h& c: [9 \- u! ?! X8 p
#else9 v- m6 {8 p0 j
        elapsed_time = nes->cpu->GetTotalCycles();, j. V& H+ a7 E- s9 _2 a
#endif1 X2 z3 a! R2 g) O
}
3 t( t. t+ x/ ]# ]: a; [5 [0 m" e, c9 V% h: I  X
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
; ?6 W; E. P% B1 LINT        APU::GetChannelFrequency( INT no )2 ]6 ]# n( u# w5 a
{
/ v3 C; w/ U1 J- i: t* {! W        if( !m_bMute[0] )
8 u+ [$ {* L* d$ {* L8 B                return        0;/ h; ^( O- _1 B0 S9 k

4 t/ l. U9 {. Y+ \7 w( W  Q2 w        // Internal2 Q3 u  A. u" ]. B
        if( no < 5 ) {# n/ G2 e4 `4 Q8 M
                return        m_bMute[no+1]?internal.GetFreq( no ):0;) B5 ?# Z! Z% s" u' t; E: M+ E
        }
- T# b- p3 T0 k& O. D8 ^        // VRC6# k2 @+ M! |1 H
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {  Y' n% F! W5 k7 f, f
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
1 R) C7 S. x0 ]0 h) \9 i( c1 o        }
7 ]8 H2 A- G3 q+ Z        // FDS
  L: H' N+ h' X7 \  U: c0 L* l        if( (exsound_select & 0x04) && no == 0x300 ) {( F& |) o  y2 |8 V7 ?. Y. P8 L- L
                return        m_bMute[6]?fds.GetFreq( 0 ):0;8 g( R5 i2 Y0 f, R2 p
        }
0 d. t, A* O$ \2 m, r        // MMC57 J  f9 m1 q# r3 o5 @
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
' s; {8 ]: s1 H& G$ l+ U' I; b* z: G                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
. z# s1 Z" \, H4 x        }6 k4 g: C! ?4 m* x( E0 ^' I
        // N1060 F: v6 r9 c2 x" K
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
% R! {" }( n" u8 |8 J& w1 H                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
: x) g" `" C& E. b+ }% N* u  J        }
3 m% [9 i( l* X        // FME7- N" B: u, n  ~( W
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
& W4 S( N4 B6 d* f9 s* P1 ^                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;/ |1 w6 v' i( x: _- @, R- G$ A6 F
        }
) B1 I: v: Y9 G6 R) S! `        // VRC7; y' Y: M* O+ |. a" g$ h
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {: w) h* ?& \1 \9 z
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
+ ]  Y# A; Z( A0 d* o* r3 v        }3 N$ n6 _9 P9 ~' b! @, E8 Y3 N
        return        0;, E. j2 Q: Q3 L& r
}. Y6 ]; u- |# T7 ^/ k

# @* ^! H8 K& B. D+ _- F9 Z0 t// State Save/Load$ |" v7 o3 j" \' t6 y
void        APU::SaveState( LPBYTE p )
; S1 }0 e& V: n% q5 s6 |{7 j: p+ K4 ?1 \: T! t9 m
#ifdef        _DEBUG7 k1 Z/ y) u5 u+ u8 b  }5 {
LPBYTE        pold = p;' M, B5 I) {9 N/ F  y. p
#endif
  C" _+ Q5 G. X+ g- t5 B# t9 }: i6 _5 c
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞% C1 f6 c2 g1 t' M" \
        QueueFlush();
% @) h# Y4 N9 T( S6 H% J5 p4 Z' k  N9 T
        internal.SaveState( p );
, h: T* r* t+ S5 P0 W        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
: P+ C7 O$ a& ~  o
+ X' X! c" r9 O0 _8 q! |& S        // VRC66 R0 g. c, |0 a* x( _9 k
        if( exsound_select & 0x01 ) {+ @) L2 Q' s# G0 D. H8 ]
                vrc6.SaveState( p );
0 d# P# C" C3 r& e1 N3 M                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
; q  n* U+ M; J' s1 a* m% g        }
3 d9 |- U8 B; ?. P: ]  J+ J+ V        // VRC7 (not support)
7 [0 L% E6 B! J1 J        if( exsound_select & 0x02 ) {7 F" @6 Q5 F$ P- s) V  [% V. y6 m
                vrc7.SaveState( p );1 u4 F4 W7 g# }8 q. `$ D
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
0 ^7 Z) U2 ^4 R! C5 l        }2 ]& f0 Z2 H& w% z: U; }& G8 a
        // FDS
$ _4 r( o9 k2 J& U, V/ b  _        if( exsound_select & 0x04 ) {7 X3 d5 H5 j, F4 s* }
                fds.SaveState( p );
$ Y" g8 I1 ~/ [: L# P                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding& W6 K& t6 k. h' ]0 k: R3 d- g6 u
        }
' y# y  I" U& W$ A4 F        // MMC51 `  x* c3 e+ z1 L7 u1 ^8 s5 J; ?
        if( exsound_select & 0x08 ) {4 Y2 ?. P1 }3 M7 k
                mmc5.SaveState( p );
8 C4 O( a/ D8 W                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding' |4 q+ H- O9 x% k- R1 c0 w; ?4 g
        }! n. q. r4 I$ D
        // N106
" z  k. W& c) E        if( exsound_select & 0x10 ) {
: H" a7 u. v  K) q/ L                n106.SaveState( p );/ q2 g# i/ j( o  @$ o6 \: V/ @
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding. ?$ Z/ `, d# J) n+ u. y: M
        }
# e' n5 u, I" A  g: ]5 c& s* l        // FME7/ B) u$ Q: k! x; _
        if( exsound_select & 0x20 ) {3 ^& z# o  d% s* H( Z' v
                fme7.SaveState( p );
/ A4 f0 C! ~/ G                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding0 Q8 N, a# g8 A/ ]: D
        }
1 t* k3 C% \( I2 ~. {
8 ]+ u) B: W' }+ R9 T#ifdef        _DEBUG
& z! H8 [% ?0 x% @% ~* `, `DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );9 G  _0 _4 F* |, H# o  ?
#endif2 _1 E) j1 q6 c* k
}/ t# I8 i4 f5 @# h
6 g; \" A( Q1 l
void        APU::LoadState( LPBYTE p )1 m2 `' c1 T# y
{
9 q# S6 L, z! u" e        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
2 l8 |- g& p3 e( Y) N) j        QueueClear();: C0 X* l+ u4 w. V( T) q% g

& ?" N. b3 n8 }& m+ Z: K+ A        internal.LoadState( p );
+ b% R5 w+ {$ G0 I/ E        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding/ E( N! ~6 |+ T! u# P/ @
" V7 o+ F2 R+ f+ E( a2 I% V" D, i
        // VRC6
5 R/ g, }8 W( W  d; n        if( exsound_select & 0x01 ) {1 Y7 i. O8 z, D4 K6 w
                vrc6.LoadState( p );
7 k9 S( Y% u) S0 X4 q# x. k  g& m                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding4 l& s4 O# e0 _( S- i
        }, C' Z, t6 J' V* J/ s$ o& X9 x7 B
        // VRC7 (not support)& I9 L+ r* K6 A8 W# Z4 r* \
        if( exsound_select & 0x02 ) {
3 {) P# f* i  b0 x) ?                vrc7.LoadState( p );  [, h5 b$ R8 ~( R. k$ B
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
# j: G3 N' K4 x        }
3 K% _$ Q7 r8 `+ C- K2 Q9 [' u! J        // FDS$ J. P/ L1 o7 R+ ?3 j) P1 l7 e
        if( exsound_select & 0x04 ) {8 ?7 C2 k+ i; D4 B
                fds.LoadState( p );- Q$ I2 }0 M$ V
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
$ p  i  B! ~, H' v9 j& ]        }
* m- g8 n) ]3 O- I( Q, c# }2 T        // MMC58 x6 x! d! o4 ^) \$ T
        if( exsound_select & 0x08 ) {% F9 i7 H% @: R: |
                mmc5.LoadState( p );3 h" T/ D: {1 U+ A$ S" R
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding' n' |" W; [& X1 H( p0 E
        }
: q# G; J* u6 Y% J% X1 R7 _        // N106
' f1 F  M' j" L' g/ \7 `        if( exsound_select & 0x10 ) {  ~1 b: Z. n3 P/ G; f" A: w/ i
                n106.LoadState( p );
8 z, j. V7 S* [  ]( H3 d& r                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
4 @& }* Q$ B+ X2 x6 h' Z        }
# y" b$ m0 {5 `. `) \" X* W! [6 {        // FME7
6 C4 h- _/ J# v) N& M7 L3 D        if( exsound_select & 0x20 ) {5 B! `  Q1 p. z, j6 N
                fme7.LoadState( p );2 d3 T8 p! k( }& [" L4 _; c- P/ G
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
  q/ Z& x. I/ x9 J9 P" l, I: c- \        }
$ n4 y: u/ T! r7 {- {}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
5 G% M$ e4 J4 H- [; Q可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。/ V8 [( D! |  _: ?9 }4 g
感激不尽~~

( m3 q& Y% X6 q2 D0 p0 e9 C4 j3 n恩 我對模擬器不是很有研究,( Y# S# n! h8 V/ s* ~/ R
雖然要了解源碼內容,可能不是很困難,+ S* V% u6 w( M6 S# T
不過還是要花時間,個人目前蠻忙碌的。* @! J6 d" T2 J5 |

! j5 f9 o0 j' ?. _- A給你一個朋友的MSN,你可以跟他討論看看,9 A9 p5 c* J6 Y
他本身是程式設計師,也對FC模擬器很有興趣。
9 B4 W+ {8 p1 R$ k
2 Q; F' V+ W: AMSN我就PM到你的信箱了。
  G( P6 k8 j* r9 A/ E8 U
3 k8 |, z/ V3 o; K6 h4 N0 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 发表
) R6 o" [$ X7 D; Y1 t. R呵…… 谢过团长大人~~
/ l$ n( ]! t; Q6 _" d5 J  r
/ E4 m2 O5 Z/ h; X$ |3 f
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
& B1 X. g) i$ A团长的朋友都是神,那团长就是神的boss。
7 @& s" A1 |* M; n& y: N
哈 不敢當,我只是個平凡人,/ P1 M7 y, @' G. H
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙. o7 h, {) m7 `4 K  W
ZYH
7 D+ ~5 o& p2 jQQ:414734306
7 Q9 y/ V- X+ @* lMail:zyh-01@126.com& j6 W0 v" O% R, d

4 H" E6 m+ `( r9 f2 m2 F他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
, k* e$ q0 g, I再次对团长大人和悠悠哥的无私帮助表示感谢~~
6 D! z' A2 w, |1 y5 \9 b
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-31 15:07 , Processed in 1.090821 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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