EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。- `" M/ S9 y5 L' d% z
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
  H6 f  e4 x# c+ Y' t& ^这里有相应的模拟器源码,就当送给大侠了~~
2 E1 l: w6 m$ J+ G5 \* U- yhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
5 Q3 o5 Z* I4 R! b! d! h能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。; l) j& r" x% C& {# h% U3 \
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
  r& J# ^6 C8 `: g这里有相应的模拟器源码,就当送给大侠 ...

  m6 K# h& @0 d# _( u聲音部分(Audoi Process Unit = APU):
( z  ]0 w8 A' F$ E$ _" \% A% {: j.\NES\APU.cpp- }# ~# }+ H1 J& n4 {, w: P; M
.\NES\APU.h% Q% n9 q' H  F5 J

" c2 F; h' C1 [; y* e5 A5 b4 @/ @/ l% H! r" r3 \, q! j8 k; M
影像處理部份(Picture Processing Unit = PPU):
* p  w/ g8 e- U.\NES\PPU.cpp" B- S& K8 {" C; i: _
.\NES\PPU.h
- b2 o* G" J8 j3 h* v- Y: B/ r% ^6 [9 v* A$ ~7 @& c) R
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
: l9 D) @6 T; H$ S# c; e感激不尽~~

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:; u8 E. C7 g4 T
(由于很多专用术语和算法机理都不明白,所以看不大懂……); f) Z0 U0 `# W  Y& F  `, b- \
//////////////////////////////////////////////////////////////////////////
, m+ Z! \$ f; s' v; a! z) ~//                                                                      //
( t& K6 t- x, G4 W* l//      NES APU core                                                    //
$ m) J1 d1 ]0 I6 U! o//                                                           Norix      //' ]$ J1 T5 [; H
//                                               written     2002/06/27 //
- s' q8 |7 ]" ^3 K0 p% \; I, v//                                               last modify ----/--/-- //0 C3 W/ W. L, X0 l) v' n4 t9 y
//////////////////////////////////////////////////////////////////////////
. s  u; e; u& |5 u0 V& M# h#include "DebugOut.h"
  X$ B; _/ \& N. |7 h* C; m2 @' ~5 j#include "App.h"
: u. b# U6 X, {7 {( q& ?9 ?. c#include "Config.h"# h8 j( V/ C- [/ `9 g2 `
5 I5 |+ q. x/ m+ d
#include "nes.h"9 W$ `6 b. L$ |0 v3 f; C% h
#include "mmu.h"+ q1 p- q" g- \
#include "cpu.h"$ o2 a# ]  a3 n2 f; Y3 `  Z$ G( c
#include "ppu.h"
2 G6 Q, v: V' w. S: E3 H* W% r#include "rom.h"; |/ I  @2 J( A4 `0 P) e
#include "apu.h"
! ^1 }1 u$ A! b* w: \3 K* f
: Z$ j; ^0 {6 f6 Z/ b// Volume adjust  [0 {# L( r) a/ r$ t
// Internal sounds" V6 y4 ~& Y% Q  ~
#define        RECTANGLE_VOL        (0x0F0)
% m7 L1 E. D9 G) n0 S#define        TRIANGLE_VOL        (0x130)
' H# P- ^4 U4 R( k- X/ W! `#define        NOISE_VOL        (0x0C0); \2 D/ n8 r+ n" ?  G' h$ u
#define        DPCM_VOL        (0x0F0)! L; G" B6 `( l3 q0 H
// Extra sounds
* h/ E7 ~2 i& O0 q/ g8 o#define        VRC6_VOL        (0x0F0)
3 E8 t. l( ^8 o! ]* M#define        VRC7_VOL        (0x130)
; d+ s" R& l5 j& a#define        FDS_VOL                (0x0F0). O/ f9 ~8 W1 f# o1 z& m3 a7 e
#define        MMC5_VOL        (0x0F0)% _+ j" T* d$ i5 a
#define        N106_VOL        (0x088)
! b( \+ b4 g7 _' N% S8 N- Q; g+ ~#define        FME7_VOL        (0x130); {  B7 \, p- _5 Q& {' I
9 H# ~5 A' H$ z9 n0 m* D$ l
APU::APU( NES* parent )9 m" ]  o% G. K! [! ~* b; Q0 P
{
4 p5 w. c4 ^: I  n/ H        exsound_select = 0;
+ m( z2 M4 N9 i# Z/ s
$ M. |. h3 Y! p( u. H7 I6 G        nes = parent;5 }! s/ i  r: X: W9 x
        internal.SetParent( parent );: f: U# y1 V- ^1 V! M$ X
+ M6 t5 D: `7 g2 z% n  R
        last_data = last_diff = 0;- b+ L2 X  j0 J% Q+ Z

/ c9 i7 }4 Y2 L        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );$ h+ Z2 V$ S1 L* ^; U- S9 D
, O& I* A  _1 V. H$ d; g7 N+ T4 g
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );, o2 D# u8 a8 Y' g2 R7 P1 g" b& r
        ZEROMEMORY( &queue, sizeof(queue) );! C0 @+ @- N* O- f& e* n5 v
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
7 M8 {& C* c  c- v% ?
# R% r( P. }, t2 C* a9 U+ N        for( INT i = 0; i < 16; i++ ) {! ~, A3 Y4 a; r' T; ~& C
                m_bMute = TRUE;
( @$ P$ i' n+ m" u        }" k+ h8 W" L# j2 \- k0 R
}8 b# }! a' Q, Q) r
, f$ z/ E; M( M% Y
APU::~APU()
7 l& ~+ i+ H& f( W" L$ m% a% R{0 F4 N0 C% P% U- o0 w- R
}3 b9 C* R" ~4 Y& ?
: Q" z$ s8 `  N* F$ d2 |" ]$ m
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )4 H- J! m( p  C1 A1 |, H5 Q
{
+ Y5 z1 Z% h  _2 c* s        queue.data[queue.wrptr].time = writetime;4 s& ?" \1 D" o1 i( Z
        queue.data[queue.wrptr].addr = addr;
; W% g+ U, r( G; |( Q: f( X2 n; M        queue.data[queue.wrptr].data = data;
' W* ?0 Z. b$ O3 l1 s        queue.wrptr++;* w: S; H' a9 e* C# Y( P5 |
        queue.wrptr&=QUEUE_LENGTH-1;9 q: B% Q7 [: J  ?& Z( D
        if( queue.wrptr == queue.rdptr ) {4 H' |& |' Y1 l
                DEBUGOUT( "queue overflow.\n" );
: V2 b+ H" {) `) u+ A7 U7 |* @        }4 @3 P$ C# g, O- `9 E: v3 }- [
}. e4 D3 l4 V9 I- @5 d0 A

; H8 d! I" Z$ f5 Y$ D+ j% ABOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret ). `; o5 U9 u9 c( @  R
{
4 j+ H1 E& O- Z9 Z        if( queue.wrptr == queue.rdptr ) {! s: N/ J! g  Q/ G3 n) a. _; R
                return        FALSE;+ q0 h. f; W/ F8 E+ n6 [
        }
! T' \, |9 Y- P- ^  i        if( queue.data[queue.rdptr].time <= writetime ) {! E- X9 O1 s& q- r! u
                ret = queue.data[queue.rdptr];' m) L5 l2 s/ K1 ~
                queue.rdptr++;* I/ p) A5 a4 }* h( t& Q% d5 }; E/ j
                queue.rdptr&=QUEUE_LENGTH-1;
, H3 u6 b8 H/ ]- [. s/ @. A4 v                return        TRUE;
4 }3 ]( v- Y; j' n+ z        }
8 m7 T: O4 N$ M, u        return        FALSE;7 N' R) c3 h" U1 b' M
}
7 o; C4 b3 \* n3 k
: u: Q' N$ x) r; P* L/ Kvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )7 D$ o6 P. \0 U
{
' S! g5 O2 m; h6 F$ A        exqueue.data[exqueue.wrptr].time = writetime;3 I' z" C9 X* v5 y, T! @: y' j
        exqueue.data[exqueue.wrptr].addr = addr;9 H* }! [( x$ c1 w. `* G$ {
        exqueue.data[exqueue.wrptr].data = data;$ N$ I4 E. d0 |; N
        exqueue.wrptr++;+ s! L: J4 F/ \5 R8 I* R/ x
        exqueue.wrptr&=QUEUE_LENGTH-1;! L9 O. w; f& w+ C0 V
        if( exqueue.wrptr == exqueue.rdptr ) {; f) N& p2 D0 I* a# S
                DEBUGOUT( "exqueue overflow.\n" );: Y0 ^3 K( Y) B( E, T4 s) f
        }
3 m0 s" a( |/ A5 D- B9 Z}& M- U* w- V, D$ p( b/ x- R

; g9 o7 c( ^: {; S- q7 W0 x' MBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )7 ^+ A" G3 j+ j( g4 t
{+ i  G( {! K  a" P9 ^. @
        if( exqueue.wrptr == exqueue.rdptr ) {
, R/ ?5 }, X4 f6 w& d5 s4 r                return        FALSE;! N2 t% u* T" c0 F
        }
: o) F: V! F- t        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
) v, I0 l$ p) Y+ f2 ~                ret = exqueue.data[exqueue.rdptr];
, H% h' m! K9 ?; W0 V2 S2 ~! X                exqueue.rdptr++;% S& H( U6 b) K# k" ?) ^0 k
                exqueue.rdptr&=QUEUE_LENGTH-1;& d( i; o. n: @+ ^) V. }( Z( _
                return        TRUE;! ]* x# L1 [6 e; g# _$ c5 v7 M
        }
5 z& p7 o1 c$ f0 `# E0 ?! F        return        FALSE;
5 D, h0 ^) u9 W% n3 j0 f}6 G* f  d- c% d

0 O0 X7 r" {, ^void        APU::QueueClear()9 Q4 \7 ]) E4 i8 h
{
3 @4 u! j$ Q3 u- k. x  E6 Y        ZEROMEMORY( &queue, sizeof(queue) );1 [/ y$ d" P* k& B" I9 |
        ZEROMEMORY( &exqueue, sizeof(exqueue) );: X6 ?7 I0 Z& J; Y" W: Z" b
}
" ~3 W1 U$ i: `# r  L" M" Y. j# C  r0 v) ]8 L1 V7 [: f- w
void        APU::QueueFlush()
2 X( w+ \3 @% d  |{' K$ g/ q0 l0 C9 ]* S/ }$ c- {
        while( queue.wrptr != queue.rdptr ) {. s7 t9 U7 f% U6 @5 n, i
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
. Y4 O9 x3 u8 z; E9 F; v( O                queue.rdptr++;/ a% P- m$ X' c  U
                queue.rdptr&=QUEUE_LENGTH-1;+ }1 |+ i; I! ?7 n/ @
        }0 |% |7 W' S0 s' t* x0 f& F

- C7 K" O+ H) v$ x        while( exqueue.wrptr != exqueue.rdptr ) {* ?/ E  B: H3 v0 R2 J
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
% h5 e9 h. ]. ^1 h4 q6 k                exqueue.rdptr++;+ X5 x4 t; f: P  \! a' z; w% P
                exqueue.rdptr&=QUEUE_LENGTH-1;; W% m4 K+ t1 g3 b# w7 S
        }3 [" F1 ]; U& P" [  h: G
}
" I* O; X( l$ M4 }0 t  Y2 I# d. W* p! g! d8 w, B7 S5 ^
void        APU::SoundSetup(). d9 ?2 z0 ^) _( D1 x# Q
{; ?& h& l! T! j; |3 g' D
        FLOAT        fClock = nes->nescfg->CpuClock;7 _* j& X5 U, R2 k+ v/ B! [( n/ n+ T
        INT        nRate = (INT)Config.sound.nRate;& `$ X% R% [- Z1 ~1 ~) X) a
        internal.Setup( fClock, nRate );
& G- I* n) B" g, f. z        vrc6.Setup( fClock, nRate );
! J% g; T& x' N* G6 k5 r        vrc7.Setup( fClock, nRate );
) ?2 i# ?" o1 d; U8 \$ ?        mmc5.Setup( fClock, nRate );2 ]% `0 D; W1 w; z2 Q7 b( A
        fds.Setup ( fClock, nRate );0 h" A! m& z7 J9 B
        n106.Setup( fClock, nRate );
) @$ k1 ]  H1 p/ R/ x5 l# C        fme7.Setup( fClock, nRate );( y; O9 y6 r8 f8 q9 W8 @: k
}  _  Q  s* C. b* A4 z. ^4 J* _

5 f( o: z# a; x' |3 E# gvoid        APU::Reset()
2 ^4 K$ I& m- t& b( Z) `. v6 B{
4 r! j; v1 s; c" l5 k: s$ w        ZEROMEMORY( &queue, sizeof(queue) );
0 h* J5 c8 C( ]7 t        ZEROMEMORY( &exqueue, sizeof(exqueue) );) n0 x; S. W( N/ x: `' D9 G

7 W$ e  a0 W8 N* [6 Y" o        elapsed_time = 0;
8 l7 ]. j7 A' b: O0 _  N2 J
; W3 O# }' C* r: `& J% y        FLOAT        fClock = nes->nescfg->CpuClock;
4 Z" Q( b$ \* U, g: Q5 A        INT        nRate = (INT)Config.sound.nRate;% W1 u' R' C% |4 z
        internal.Reset( fClock, nRate );
, Q: _3 [9 H5 \# `! ^        vrc6.Reset( fClock, nRate );
" e* \- R8 U, \$ \/ O; v2 ~        vrc7.Reset( fClock, nRate );- o) F/ l) `. g) m" M: E) T3 x
        mmc5.Reset( fClock, nRate );+ b! o9 ]% @* \
        fds.Reset ( fClock, nRate );
: V6 r! c# Z5 A5 J$ x9 U. I        n106.Reset( fClock, nRate );
' S; M; Z4 R. o6 n        fme7.Reset( fClock, nRate );) F4 j/ o% Q; x. p  l8 ~

  Q8 s3 f: M0 B$ A! F$ w5 ]        SoundSetup();" N$ ?9 ~% `8 {( L! ~
}
- D. P# ?) K' q* A% F# z8 i- G0 ?" j: `! G7 a1 H
void        APU::SelectExSound( BYTE data ): L- R5 Z7 V1 w3 \$ h% T* U
{5 r2 b$ t. S, }7 q6 T
        exsound_select = data;$ a4 F4 k! o5 G; O
}/ y; e6 Q( }% y; y; n" O! `

; A  K$ v$ Z/ a) Y0 K6 n7 ]BYTE        APU::Read( WORD addr )
6 [/ m2 K+ b) y{1 K2 |. @- r; T  u: o( E
        return        internal.SyncRead( addr );6 c# E  B: ~, _6 r  |( V% ~
}6 h, w' _. V8 C+ u5 x' C: E
* t! `7 n& W6 T
void        APU::Write( WORD addr, BYTE data )
  m+ i) D4 t' u( ^& ?- i/ b{
9 t7 f, Y# D/ e' l" ?        // $4018偼VirtuaNES屌桳億乕僩
: D+ g, ~) [7 [1 u        if( addr >= 0x4000 && addr <= 0x401F ) {: s4 x) D9 z6 f) v5 B! ]* t
                internal.SyncWrite( addr, data );
5 ~( o5 y* X9 v* ]                SetQueue( nes->cpu->GetTotalCycles(), addr, data );7 r6 \* ~7 a0 o: q
        }
% j( r2 M9 m3 i}  H* Y' @0 d, }
; d- D& r4 x9 T. D% M4 z. R
BYTE        APU::ExRead( WORD addr )& s. f* [3 S0 g) [  Y/ I
{
7 g3 r$ m# Y0 wBYTE        data = 0;
$ w$ c6 O, h' P0 L1 _% ^) g7 h$ _( ~2 E; C7 q
        if( exsound_select & 0x10 ) {
; `6 F+ a3 }# x- P                if( addr == 0x4800 ) {
/ i5 [. d' L/ Q3 F                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );: x! D) I4 b6 Z
                }) U. Z8 k6 p, T" z. ]3 ~
        }
( P" P! Z3 t6 {  }3 n3 J3 h6 N        if( exsound_select & 0x04 ) {
! f$ J* S: ^( h6 U                if( addr >= 0x4040 && addr < 0x4100 ) {: X3 i9 O: g5 v6 y2 o
                        data = fds.SyncRead( addr );
# R9 y) k% H2 N6 n                }
0 Q" ^; |. z/ c& }        }/ r2 c: H+ x7 _. C, V0 W
        if( exsound_select & 0x08 ) {) X6 V0 l' i6 \2 V5 P
                if( addr >= 0x5000 && addr <= 0x5015 ) {
& T8 W+ a. t3 h                        data = mmc5.SyncRead( addr );9 E$ @7 Z( U4 i' L$ n
                }. K& {8 B8 ]; l7 S  `& Y& L
        }
9 h2 W* M9 m1 k  A" L* h1 {% K+ t& k$ u
        return        data;
- f% {4 E7 Y3 }' k}
2 ^+ V8 I+ S, |$ I, s5 [2 ]1 O- h3 I2 p$ ~, @0 E
void        APU::ExWrite( WORD addr, BYTE data )+ D, d6 T$ ]. S' E
{
9 P; v2 `0 n, V$ U        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
/ \2 ]: J1 J* X, P( w" O) P
: S1 L2 f  U! s        if( exsound_select & 0x04 ) {
1 u2 j( e8 z; E( z8 M0 ^                if( addr >= 0x4040 && addr < 0x4100 ) {) @. _0 r' R) ]4 C) @
                        fds.SyncWrite( addr, data );
5 y5 ^# x& ]* ^: {( ^                }
- s7 s$ f* k- U2 N8 w. n. ~0 J        }  x) q& P2 i# k4 T  K$ W

$ W" w6 Y7 q0 D1 |# F        if( exsound_select & 0x08 ) {/ H  P( L& a3 ^1 J  L
                if( addr >= 0x5000 && addr <= 0x5015 ) {
9 a; M( R4 L' i" j1 _( \                        mmc5.SyncWrite( addr, data );
' M6 o! o1 S% d/ V# i7 k8 c, Q                }
1 P: x% m( ~" ]* ~6 x        }
3 z/ A4 p) F; R. j) p$ l}
% M5 |" s- q3 A$ k% m9 p& ^. n7 n6 k$ S: f, m! P
void        APU::Sync()
+ p6 u% f6 U8 }1 U0 O% f{
3 Q9 H* U9 Q9 ]% L& w( m2 Y' g}7 X. t7 o' ]5 E) [# y
  L4 `# W; \) F7 d% O8 M
void        APU::SyncDPCM( INT cycles )
+ @" k4 L% |! u! _8 M1 M{
9 A; s$ X4 T* ^        internal.Sync( cycles );5 I: U8 @. B: X! D$ b7 `

: o2 }8 I: O- O' u2 O+ }        if( exsound_select & 0x04 ) {, x" \1 ]0 Z8 K
                fds.Sync( cycles );
* J( {2 g5 e3 h& s( n% R8 ^        }
' ?/ R4 T. l1 u* l  A% F        if( exsound_select & 0x08 ) {
: E1 O  |+ t* u* d$ w2 W                mmc5.Sync( cycles );; {( D# m* j! c9 s7 X: P: Z  p
        }
$ ~: c% j8 d6 J! H, P& j" i}: L. `4 @& H6 f" M1 g; q3 c' k

2 G/ S& r( Z, _" O7 }3 ~void        APU::WriteProcess( WORD addr, BYTE data )6 k1 N; I$ R" R( S4 _  E( B+ J
{- T$ O3 A8 R/ L8 K- j6 m( \3 L, U- |3 |
        // $4018偼VirtuaNES屌桳億乕僩
- g: @$ ?8 ~7 p        if( addr >= 0x4000 && addr <= 0x401F ) {8 d. O# Y2 d2 N- n* G6 i; s5 p
                internal.Write( addr, data );- v' k, b" y) d2 E
        }
7 f3 Q5 G- z7 }9 u1 L0 N! ~7 Q* C}4 Z$ [0 Y2 I; l  d! q
; H: {/ q) k  ~1 T6 d$ S7 w- M, X9 d
void        APU::WriteExProcess( WORD addr, BYTE data )) Z6 g3 f6 `" g4 C8 u  ~' j( v7 q
{
0 s' B7 V2 z! f8 f# k        if( exsound_select & 0x01 ) {
# W: R8 H4 B; M                vrc6.Write( addr, data );% Z4 L5 r2 M% o+ G- y! |) U2 R
        }* B" l6 E6 U+ v. e5 l5 G$ v
        if( exsound_select & 0x02 ) {  ?) S7 g& X6 O" w8 f
                vrc7.Write( addr, data );
% V! \& B1 E' _# K5 X6 J/ |        }! v- _/ ~0 p& s5 ~+ J* v6 A3 n
        if( exsound_select & 0x04 ) {
9 f1 r6 {) j1 v" M9 w/ R                fds.Write( addr, data );
0 C6 ^4 F6 o/ g; U        }
% Q) n7 `! T) C2 o) f" Q- D! }        if( exsound_select & 0x08 ) {  v$ _0 V" k) H* p) a) u; e. w9 }
                mmc5.Write( addr, data );$ i. a! `# }1 e; S
        }
7 E+ l0 T. B* b( Z# l+ d: ?! E0 T        if( exsound_select & 0x10 ) {
2 d2 x0 q; \' m                if( addr == 0x0000 ) {
  I% H7 M& |* O* I0 G; T" F                        BYTE        dummy = n106.Read( addr );
8 `6 \  J: z, }  C                } else {. v, v* k, [8 W
                        n106.Write( addr, data );: T  N6 V3 w( c9 o: ^7 s* c
                }+ g1 x: @+ C# L
        }' U, m0 T' {+ ?  y2 A  H; ~1 a
        if( exsound_select & 0x20 ) {5 Q; L* {( i% {. x+ o5 v
                fme7.Write( addr, data );$ [! S' T6 U9 t4 t  h
        }2 `/ s8 q) ^$ U+ a3 J( O8 X
}: [1 N% k# ~' s! ~1 e2 A
2 F7 u7 q/ l- u3 L8 O
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )1 f! x* v( }( _9 q% m/ B
{& q! G' t/ a) H# `8 @0 z
INT        nBits = Config.sound.nBits;7 G9 h+ a7 m$ S9 @3 M( q+ F
DWORD        dwLength = dwSize / (nBits/8);
  O  ^) H3 F; m* @9 ]INT        output;
6 ?" ^5 m& D, v6 w* K1 r! BQUEUEDATA q;; ^; s* i% y8 t* B
DWORD        writetime;4 ?' a( }$ i3 N

" A; l% l* n+ KLPSHORT        pSoundBuf = m_SoundBuffer;
. m# @' J0 @6 v) U8 O# VINT        nCcount = 0;# p1 O" V4 n8 c1 z2 g
% K5 W# @9 l7 p# e
INT        nFilterType = Config.sound.nFilterType;: k/ v: H, I% @9 x7 @$ O' ~4 F( Y& S

/ L9 B7 m" D9 ^0 t/ `2 x        if( !Config.sound.bEnable ) {
3 e$ E: b  {9 t3 a7 X                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
, i5 {5 }) A  P  r                return;
1 V% k( L5 b' K" L* M        }
0 K3 h9 f: }- X" t3 F0 N0 I8 q/ l/ c
        // Volume setup7 ~0 [6 N# g& i( y0 {/ `
        //  0:Master1 a3 h, z8 D+ p% q  O# ?
        //  1:Rectangle 1
1 P. k( ?. w* @; Q- I' C        //  2:Rectangle 22 z/ {' Y* o- l3 U7 R
        //  3:Triangle
8 p- i6 d6 Z/ {: E" n5 B+ [0 J        //  4:Noise" M4 w% g: ^$ Z0 D# |9 S, K
        //  5:DPCM
  {# y$ S: i! H. i        //  6:VRC6
0 H  ^. Y! r+ c! ]( y6 _        //  7:VRC7/ h, m8 V* u$ w' n, d' h
        //  8:FDS
" m0 {( O' m. Z3 s- q9 ]4 |        //  9:MMC51 I+ B0 B# g- g0 o0 e
        // 10:N106
1 m# Q2 C' C9 z6 f8 c+ k        // 11:FME7
5 ]- O: {6 z# R7 m        INT        vol[24];
6 z* E* d/ g- T  h) V7 L        BOOL*        bMute = m_bMute;  e# c  H1 J' S7 D, ^# |8 d
        SHORT*        nVolume = Config.sound.nVolume;: [' x: ?' K1 }& F7 Z! E
, e/ P1 S( J% q/ I* `. F! ?* R
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;0 g: h) ^# m- ]% v$ t1 \3 ^

4 L5 P4 D" a( _2 L        // Internal
6 \! [) z) m+ ^* c        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
/ l8 N' }5 Y' f3 K4 e; O3 W        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;, M: ^6 {" C$ W" j0 G' @1 D
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;# ]8 @4 x6 B' w' ]) u
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
. p0 f; H( r5 S" Z4 Y$ g        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;7 F$ ?7 i* ~! W0 w+ i6 i

! `# d, K2 z9 v/ X& |; w        // VRC6
+ n7 w3 \1 _* m5 j9 s, S        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
8 J9 q& r. ]0 x  g) g+ o        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;5 }. Q! h! F: z
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;% v" x0 ]- N4 A7 k+ {" I
# y+ G! Z/ i( ~  S1 [$ x5 s( Q" [
        // VRC7
% W& X& Q! D' |& E        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;  w. u) [$ V6 o  X# {  w- x2 ]
" ~) K) N2 ]' E; }: w; O; {$ {4 h* ]
        // FDS
3 d* ~, F# w9 o# _- d: {        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
: p* z: M* M8 H# u$ Z4 Y7 a
3 m3 u) [# ~$ ^( |$ J9 b0 \8 D5 G        // MMC5
, h3 _: e8 d4 e0 W        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;, `9 I5 c- ~3 s
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;* P  f' I9 ^& L8 G
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;; t, E1 V" N6 l# i8 f1 C

8 e- j7 K) O, t4 u2 D        // N106
7 ?+ e& f6 a/ `2 |6 @        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" d9 s8 z9 y( e2 E1 ^- i        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& q7 u. T+ K5 l# u! |# x7 `        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;3 ?9 _+ U- G2 |  _
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ ^) c# H2 j, ~# R# C% [        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- ~' i6 x3 H, Q9 U0 |$ S4 m
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;" ~" [# b" v1 \9 q; _
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;# f/ X, B2 Q3 b
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 y/ P; e3 ]& ]
, I1 Z5 u0 k3 T        // FME7
3 M7 K# I/ j* Y$ O5 h        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;1 Z1 P& X, Z; Y/ R6 A& f/ [5 T
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;; L3 {; F' A1 K4 `) U9 r
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
  ?1 u% b  a" t& j8 \2 \, \) X8 F; M0 z1 M; z
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;/ c; ~7 M  h- z1 G
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
8 k$ Z; N/ Y( A" I0 Z5 _% ]$ A# ]" X
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟7 ~0 V' U0 F$ t
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {# {0 _0 K' w$ Z2 \! q
                QueueFlush();
' y" w! U) v! M, [        }! H: Y* ], }1 o8 W% q! X0 M

- s" J2 Z& u/ O6 p, F$ w        while( dwLength-- ) {
4 `5 A' E) Z& j2 I% L                writetime = (DWORD)elapsed_time;; i5 I& e) L/ v1 ^, t! R

; ^- v0 D- ~3 ]4 e3 _6 ^* D                while( GetQueue( writetime, q ) ) {6 C! ?+ j/ T* {' d
                        WriteProcess( q.addr, q.data );
) W& y* g( b2 @; Y* N/ q# @: r/ q% x                }1 _  Q: H8 [5 V5 X! _3 Q* h. f

+ l' h1 j, h* G  I3 v                while( GetExQueue( writetime, q ) ) {
6 z+ q* w4 l& j2 H                        WriteExProcess( q.addr, q.data );, H# F) n* a, g9 i
                }& ]0 D2 |9 b% H. X: b4 b  G

0 `% M& L' `# A6 H# o, K8 H9 J                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7$ ]  ?+ p: o! C% C3 v$ V
                output = 0;; e  Y# f, b4 L, b& O8 Y
                output += internal.Process( 0 )*vol[0];
8 w3 M2 B  w; B1 e                output += internal.Process( 1 )*vol[1];
. E5 ^# w! e* J, h( l. P# E8 ]8 g                output += internal.Process( 2 )*vol[2];9 |5 [/ Y; h3 ^( W
                output += internal.Process( 3 )*vol[3];9 M: Q3 S* |. L, K" S9 w
                output += internal.Process( 4 )*vol[4];
4 i/ `& R  B/ K; `/ f: I2 ]% f; g# V
                if( exsound_select & 0x01 ) {& i1 C0 m" ~. ^/ ?- |9 }& E' ?. _
                        output += vrc6.Process( 0 )*vol[5];
" Q- S2 ?% y8 E9 V                        output += vrc6.Process( 1 )*vol[6];* k; z! S# \* D4 a
                        output += vrc6.Process( 2 )*vol[7];
0 q- J+ r# E+ X* M: E# k% F                }
) b) Y+ w1 x  I2 \5 o' g                if( exsound_select & 0x02 ) {# U) m) T1 Q; S7 c
                        output += vrc7.Process( 0 )*vol[8];( r  i9 \7 u3 z5 ^
                }
8 ]" f# d* g- M* [1 B7 P                if( exsound_select & 0x04 ) {
# N. r* P7 W: d" k                        output += fds.Process( 0 )*vol[9];
4 p" U: R3 u. M4 \                }" `) x4 i& U. x+ w9 N
                if( exsound_select & 0x08 ) {
* B% Q: |. P* |, N/ X% f                        output += mmc5.Process( 0 )*vol[10];) y* u0 F( h! j/ z0 ?6 h
                        output += mmc5.Process( 1 )*vol[11];
& n/ s0 x& x% A9 |/ C                        output += mmc5.Process( 2 )*vol[12];
/ }$ J6 o0 `- _6 E                }$ @' v2 Y! v5 _5 V. m! s2 K  M
                if( exsound_select & 0x10 ) {; g3 z3 }8 w9 W5 w$ q+ Y; z* k
                        output += n106.Process( 0 )*vol[13];
) Z' A3 _' ~: `6 H: T9 ?                        output += n106.Process( 1 )*vol[14];$ f6 S+ T- K* d/ |8 m; R' F
                        output += n106.Process( 2 )*vol[15];
. ~5 w7 {7 v8 A; V, D6 z; U                        output += n106.Process( 3 )*vol[16];
( Z4 X6 n" k; _5 n# X2 a                        output += n106.Process( 4 )*vol[17];
. Q1 ?; B0 R: @: z                        output += n106.Process( 5 )*vol[18];
' E5 m% H$ f0 v- P" m                        output += n106.Process( 6 )*vol[19];
4 W7 x$ C) d+ Z; M2 l9 C% g0 ^! P7 M6 O                        output += n106.Process( 7 )*vol[20];) }5 \$ d" o0 k
                }+ U6 S. ?# n! y! n* J, ]( P3 [9 p
                if( exsound_select & 0x20 ) {
. J4 w, J* B5 ?( L9 Y* ^. B                        fme7.Process( 3 );        // Envelope & Noise0 Y2 [% k" K# C' _  g. `
                        output += fme7.Process( 0 )*vol[21];
: H, D: v8 Z! @, M, ]" Z" w                        output += fme7.Process( 1 )*vol[22];0 F; h- i' r  u
                        output += fme7.Process( 2 )*vol[23];, i* X. P3 M8 Z, ?# m7 {2 w
                }
/ ?" K/ U7 F" Z3 G* P2 |% U. O, A
: Y' n5 h" \+ I: K$ w' l                output >>= 8;8 ^/ G7 n% J& ?' l" `. U
( m3 b4 Z5 T  p8 @" b7 D
                if( nFilterType == 1 ) {0 n0 L( y6 L3 M' N$ t8 k; p& B
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
& [* n( }2 O% f: D# k9 N                        output = (lowpass_filter[0]+output)/2;
& ?7 a! ]! o/ w% L                        lowpass_filter[0] = output;; U$ Y9 }. B* y0 J. z
                } else if( nFilterType == 2 ) {
. b, k  |' O' w, x% K: c* }                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)1 h; _' f2 R: G2 I. v* e9 b6 U
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;/ Z/ l# Z( C$ {2 X3 \3 v
                        lowpass_filter[1] = lowpass_filter[0];! c) d7 k$ |. w. S' L/ v! k8 w
                        lowpass_filter[0] = output;
1 m; Z, u) {+ E; R6 o) v                } else if( nFilterType == 3 ) {
$ F2 i- G  o4 K* `5 Q7 C$ u! H                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
! J4 U4 g/ z( C% A+ ?2 M                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;; U" s+ I) N5 ~4 E' {) u
                        lowpass_filter[2] = lowpass_filter[1];6 @' n) p, ]# b1 Q: G. U" w& `$ {1 O
                        lowpass_filter[1] = lowpass_filter[0];
! l5 l( e+ @5 P* E' ]5 I                        lowpass_filter[0] = output;4 F! a/ Q' J# D" @; |( v
                } else if( nFilterType == 4 ) {* b* b8 [% J' ^9 }  \
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
/ B$ ^8 y+ y: g9 S                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
2 f9 y$ S# m/ }/ W+ `+ Z                        lowpass_filter[1] = lowpass_filter[0];
2 L. R5 Y5 M5 c                        lowpass_filter[0] = output;
8 F1 x1 h  i7 `% S) |/ a" ]( S9 E                }
1 k" W* z  ~, k! U' s+ N& j& \# t/ n% o, B
#if        0
1 j9 o: S. |" M! @                // DC惉暘偺僇僢僩) }5 v6 x; {" a, n, p7 S( f+ k
                {
2 s% f& _) D5 {% v* n- p% V1 Q9 J, ^                static double ave = 0.0, max=0.0, min=0.0;0 [. z4 U# B. E
                double delta;- [2 c! j" S7 {0 {8 A3 Y* x
                delta = (max-min)/32768.0;7 j; g7 y4 g0 f- D- T1 e) `2 d- J
                max -= delta;
  V3 p( b. ]4 P1 G                min += delta;# W7 i6 b( W: U+ w1 i4 y
                if( output > max ) max = output;
1 X# S  u: k- r6 J+ j                if( output < min ) min = output;
) d& o4 T# G# a; @9 d                ave -= ave/1024.0;
  S. x5 n# g2 P                ave += (max+min)/2048.0;
7 x8 u( ]8 p9 w/ O$ a                output -= (INT)ave;( o2 F! q: {+ s4 u
                }0 g" f( i7 M' V2 E
#endif
* Q9 Q: H9 V6 a: z8 s+ V#if        1" C" L3 t( I8 n' v8 t% K* _3 z, Y
                // DC惉暘偺僇僢僩(HPF TEST)3 R% s; Z7 y2 h4 V. |& ~5 c
                {$ _' y% u0 j7 m* Q8 c
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
! P, y  Z1 s. A3 A, [$ h! l                static        double        cutofftemp = (2.0*3.141592653579*40.0);
" R* ~* w  K* I7 g* g) `                double        cutoff = cutofftemp/(double)Config.sound.nRate;
0 L8 n1 G. R5 \' m; W                static        double        tmp = 0.0;
0 n! G7 H, Q: M: s$ S8 W                double        in, out;  o" ]5 t' w# p5 t
2 ^( g. v. e$ z' ?8 b& x! b- B
                in = (double)output;' f2 I7 S. W' u8 t
                out = (in - tmp);
" i7 w4 g  r. |& I- ^                tmp = tmp + cutoff * out;
2 f! s7 C! w( G$ h; k$ }; g- a: I3 c( Y# p* z
                output = (INT)out;1 n& U9 p$ x+ ^/ j& d2 G/ v4 p1 ?
                }
: I+ b# n0 x  E#endif2 J, Y9 i/ S9 W, e
#if        0
  P9 C' f7 i5 {5 o                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
. Y9 i+ G  ~/ M( G, F8 N+ Z* T0 l( h                {& J# q: k4 Q8 g
                INT        diff = abs(output-last_data);
6 |5 i8 a7 K% a( i( g% J                if( diff > 0x4000 ) {. r: @. l! [5 w3 z* ]- c( d
                        output /= 4;; Z: t8 N5 G$ }8 `; l: ]7 P2 V
                } else ) a" J! R1 q) ~7 j
                if( diff > 0x3000 ) {% x: e0 S3 `3 @/ F9 R
                        output /= 3;
* p' f* {, F$ N3 }  x% B                } else
  w  [9 B1 a8 [- }" q3 S$ E& H                if( diff > 0x2000 ) {
( q7 K. z' @7 ]8 I' b: P* r1 \4 l                        output /= 2;2 ?- m9 Z9 a1 @: R- h2 Z$ m/ r& D
                }
2 n, }" X+ [/ R  }0 X% O                last_data = output;
. a7 R* c2 }) s1 D9 u# e                }- J, k2 C5 q  F! d# {
#endif
1 C$ K) c) ~* B$ t; |' X  x0 q. U0 a                // Limit+ }0 y! i" c; e9 D  J
                if( output > 0x7FFF ) {
9 j9 M$ h6 x4 T3 r  ^                        output = 0x7FFF;
, }% D1 S9 `) g: L                } else if( output < -0x8000 ) {1 G( A& ?% p  J, m3 ]& O0 m9 F
                        output = -0x8000;
: s2 R! R, i! o" u( e                }$ x; Z* J7 K3 }7 P

7 n& w" |  W1 L* X5 V1 |1 C& d                if( nBits != 8 ) {
" ~+ O/ b+ z9 N, x' v                        *(SHORT*)lpBuffer = (SHORT)output;1 l0 k- c! _1 e& t, d
                        lpBuffer += sizeof(SHORT);( h/ O4 t; M; L+ n
                } else {
5 P& c! p. f, n, X  f$ P: q4 U                        *lpBuffer++ = (output>>8)^0x80;
5 V; Y+ C: H5 s3 |( {# x. ]                }9 n  s, {( Q2 {6 ?& g' \# `+ j: B
  z( d7 P; v7 q5 p/ \: N
                if( nCcount < 0x0100 ); B0 d6 p* L' V( |6 [6 Y5 A/ ~# c! e9 j
                        pSoundBuf[nCcount++] = (SHORT)output;
% O# a& V6 a: f3 D0 }/ I0 b4 G  l( V; d% r
! f- v" `$ L* J5 B+ I. a' w1 p8 E//                elapsedtime += cycle_rate;* k4 z3 R0 [" X6 q
                elapsed_time += cycle_rate;
7 x3 `& n) J4 `5 q" d3 V7 _, g        }
$ S  ]8 c- W/ X& Y- W6 A5 A$ Z
4 A+ Z. R2 X3 B/ x' u( R3 }* }#if        1. {& C" i+ r" L4 \: ^
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
; p, A) s- m$ g                elapsed_time = nes->cpu->GetTotalCycles();
+ e8 l% J0 Z, P/ I        }
$ |1 n! T  }& G# w. F* ]* @        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
% D& U0 ?8 V- O  |9 j/ }                elapsed_time = nes->cpu->GetTotalCycles();; [1 O+ H7 V2 `. B' x9 A; p9 |
        }
# i& i3 r4 [" G* ~% @#else
: F* \, f: |8 \$ N; M+ u        elapsed_time = nes->cpu->GetTotalCycles();. G! N$ s5 u4 w( Y1 R' j+ X
#endif
8 y3 ^& j; H' m( z8 P}
6 m# |  S" P. ~
3 j0 S3 `: j9 |8 c// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
" L% u+ E2 c0 c' UINT        APU::GetChannelFrequency( INT no )
4 p) x7 U( }* p( C{
5 h' f7 l3 b) Q6 W+ H1 c# m0 ^* i3 |        if( !m_bMute[0] )
5 A  I$ ]) \- U                return        0;$ m: r- J) M& Z* g% j
( E6 c5 M0 i9 {8 _
        // Internal/ J9 i+ F4 v* {6 z$ v" l
        if( no < 5 ) {
9 X6 X! I$ M3 i1 L4 O7 ]) U% r( m  _+ Y  E                return        m_bMute[no+1]?internal.GetFreq( no ):0;
4 z4 R" }2 d' W0 G9 h8 t0 x        }
+ J# d* _* `5 j2 U% z$ [8 v        // VRC66 w. R2 p% Z5 q; i' [; f2 c9 g
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {3 |- T) l, v& v- O1 g
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;: _$ i9 a. j* _* l! Y- j
        }0 [6 g- n3 i, V6 y
        // FDS
: ^4 K- t7 _: i, S0 F        if( (exsound_select & 0x04) && no == 0x300 ) {
* v' g' X2 g: T; H                return        m_bMute[6]?fds.GetFreq( 0 ):0;$ o5 d: |9 w$ ~- \( c* N& B
        }& e2 `1 J1 S0 d$ z+ w7 P
        // MMC5
) ~4 b. m+ l3 S1 x% G        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {5 @& w6 j" N5 S  Z3 \3 W
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;- S% A- V6 _2 b# a
        }
/ o% L% B) }' F# x, l        // N106  l: |/ b3 C( F$ n
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
! N6 K8 M' |  t; \                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
+ M, O) S3 ?/ s( l        }) ?! s) _: L' t0 ^7 {$ l; N- R" P
        // FME7
3 k% h8 M+ ]( |7 x; X* b        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
1 m$ g8 q1 w4 U. v4 |# a                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;- w% w6 k/ Z1 K5 S; t' {, w
        }. h4 r* `) Y5 u' ]
        // VRC7
0 b. `: c, Q6 _        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
. M' D9 x' e8 |( m' }9 B2 B8 _                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
( s* e+ h' A* ]) D' N1 {1 T/ O* \        }
' Z7 n5 ]% P0 _4 f. X6 D        return        0;
8 v% @5 H( _# q6 I}
; _* a; q+ h7 _# N" l5 Q# B* L0 T; k- @" b
// State Save/Load
  @4 P: M5 @: [7 `1 E4 nvoid        APU::SaveState( LPBYTE p )
- y8 k' p3 f0 X6 u% k- D{9 h9 Q( S5 i$ l
#ifdef        _DEBUG; Z. \: G* f0 a" k, r! y# T$ h
LPBYTE        pold = p;$ T1 g9 e* F- W  q+ b0 g! F) m
#endif6 [" O$ p4 }" x0 }/ o- X
  O: y0 Z% q6 Q$ s9 \4 R7 |5 B
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞2 s0 x% u9 m3 F# k
        QueueFlush();2 ~3 {1 O, z9 V( u. D, U

2 w; Q* G4 F( O( V        internal.SaveState( p );
& d4 O8 J# g, ^0 \) |        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
: ^2 h6 c: s. a. w- y: U- i3 D) g3 ]* R0 V9 N
        // VRC6
9 [2 ]% b0 D+ |' I* D3 b% P5 A        if( exsound_select & 0x01 ) {
, t! K( Z, {; h  H4 W1 ~( Y# ~# I                vrc6.SaveState( p );
% w# ~$ q% w, O: G  N! ~& P                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
1 U' Z2 p+ W: l8 G        }
/ G8 O% E7 R9 _' |( r        // VRC7 (not support)
7 d" s4 h8 g  j# M; ^* F3 ?        if( exsound_select & 0x02 ) {6 i, M/ u, q# a( {! |
                vrc7.SaveState( p );5 ]. [/ Q( b) i# `. U) i+ E
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding( T6 n& d2 s5 G
        }2 U, M+ l5 J2 V7 D6 T6 Q- ~* s
        // FDS
- I7 d2 S+ }/ F        if( exsound_select & 0x04 ) {
1 v7 q& l' A3 {. x) W+ {                fds.SaveState( p );# p5 U7 r' g7 B; m$ {
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
% r( U- D: b- @. I. z1 p, L        }
8 C0 `" R3 A+ R$ d  {        // MMC5
/ D: b' B7 q9 H: ^  u$ ^        if( exsound_select & 0x08 ) {" G: [% O2 s- t3 g4 {* @
                mmc5.SaveState( p );
& U3 |4 y  Y9 c: U% x                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding) f1 h& n7 A- v' d
        }- t' L' S( e( w; m7 y
        // N106. u; K9 U+ ], B. R
        if( exsound_select & 0x10 ) {. N- w( @3 L8 H* I
                n106.SaveState( p );
$ b6 c, [+ b: `* r# v. j                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding/ K6 O; L- R, ]! z3 d
        }
2 g/ {, t4 O( Y# F+ b! ~$ e        // FME7
3 q" y9 i4 c; x5 Q4 k0 u8 W        if( exsound_select & 0x20 ) {
& U; B/ l5 K. x1 \                fme7.SaveState( p );
  s% G1 r+ d) G/ [                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding$ s1 F# `: Z! A( D6 y$ g) B1 c
        }/ ]9 C; n1 \, i: O

1 X1 k* I( P# Z( h7 |+ ^, g0 c#ifdef        _DEBUG
% V. v# C- V0 X' xDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );  Z. A1 S) t/ ?
#endif  ~) O* U( L! B) X! Q
}. J; J) A- c+ h* ~( K" S

, o+ K) n* f% c3 A  M9 u  zvoid        APU::LoadState( LPBYTE p )
& f+ C3 K) X# D% |% }{% _4 T7 Q* V5 ~9 |# n" p9 d. L' F
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡- U% t! g% \* V; g& L
        QueueClear();
4 U2 I+ L% {" t# ]# X1 ^/ \0 E5 ?8 J* R+ |8 I
        internal.LoadState( p );
9 J9 t% p; J9 D( l! R        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding, y0 T5 I- `) c. m5 N9 X
# G: B, u& U1 F/ z! E' U
        // VRC6% }1 w% b) `* e
        if( exsound_select & 0x01 ) {
) J0 b3 v* z6 |# V9 C. v1 @3 T                vrc6.LoadState( p );
) F+ w$ M' U# \: M" L                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
3 N, U# p# ~; r        }
* Y' j0 i+ {( \' V/ Y% ~  W        // VRC7 (not support)
2 P- }4 e2 H$ s        if( exsound_select & 0x02 ) {5 B4 \/ X  @/ t
                vrc7.LoadState( p );
, `* \, M& y% h4 R+ X, F                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
  \) O% Y; l. W3 ^2 b        }
* k2 ^" ]6 g3 M- Y' f        // FDS: c+ P* q4 u- g3 B7 K7 r+ p
        if( exsound_select & 0x04 ) {
+ B3 ~3 b/ j$ c: W7 C2 o                fds.LoadState( p );; l$ z7 A0 [2 ?& n
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
# [0 R7 S$ l: ^7 h: ~  k        }
5 A5 g3 F" ~4 f$ U' t% A        // MMC5
8 n+ K- g$ {' y7 q4 o        if( exsound_select & 0x08 ) {1 K& S9 T+ V  g' b* x
                mmc5.LoadState( p );
7 g/ ?' X% a4 O- R9 _. Y                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding. N1 Z# w( m8 z$ ^
        }
0 O( x3 Q; ~2 \' p        // N106! C' [9 `2 p# _; r# k: y
        if( exsound_select & 0x10 ) {
: ^2 [5 E6 [; N0 ]. c3 i# ?0 i                n106.LoadState( p );
% r* W. i9 a. s+ C! e* M                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding) f5 \/ _' Z& o7 M
        }
# M6 X* Q) G& N# a9 U        // FME7
: U" {- l( S3 B        if( exsound_select & 0x20 ) {8 d; Y: S+ N" @6 o
                fme7.LoadState( p );
2 W% \1 |. L7 t5 Q  H& S                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding# J, W& H0 O* p4 S( O% h
        }% H6 E7 M( i' M% u
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
4 y& s/ Y& `. I可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
! K, H( C. V& F) ]3 U4 X感激不尽~~

. @3 P$ Q& V; o. H! L: L& p恩 我對模擬器不是很有研究,( B$ e3 v. o2 W* u+ c, K- o
雖然要了解源碼內容,可能不是很困難,2 s" [! n9 m# z. v: B. h% ]
不過還是要花時間,個人目前蠻忙碌的。
9 |: L$ k3 A& s1 i
: b, B- a6 }  \6 h9 n給你一個朋友的MSN,你可以跟他討論看看,
5 z2 C/ A. H1 w8 e! d他本身是程式設計師,也對FC模擬器很有興趣。1 o- u- f. x. k) t  u2 q# p' E3 g

! m+ f- X, ?7 tMSN我就PM到你的信箱了。
: \. f; j; J8 B3 _+ z0 r; J' O/ w8 z% H5 ~$ R/ |) }
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表   u! v  E; J  o& ^! \
呵…… 谢过团长大人~~

$ g3 G- `1 [1 g6 |# q9 P* B% e9 J2 Z# \8 z# G# ?$ l2 ?  O
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
6 l/ o5 K5 Y( x4 y6 \/ H# b团长的朋友都是神,那团长就是神的boss。

0 T& n" j/ O: F3 _# R% v哈 不敢當,我只是個平凡人,' j' J7 c+ f) u! g0 C
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙! q5 |. I' e2 S& f0 F9 v$ r
ZYH, Y  A3 H6 X$ k1 P6 R( _4 D
QQ:414734306
6 _. \. e/ `/ r' tMail:zyh-01@126.com6 j7 s# }  `+ r  m

0 @3 q  C: o+ n. z8 ^他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 2 h4 A* j7 ]1 r+ K4 t( I
再次对团长大人和悠悠哥的无私帮助表示感谢~~
; l. `6 G; h0 w. u/ l
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-14 13:47 , Processed in 1.109375 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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