EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。. P0 O1 v/ E6 `$ y+ u0 Y
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
' F. s0 y, r* E2 P! T# \# u这里有相应的模拟器源码,就当送给大侠了~~# z+ L% X7 H) j; [% t
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
8 h! @( G% z1 ]7 m, c5 ]3 p能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。$ b' _2 Z' F1 n3 t/ T9 s! ]; M( v; X
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~- w8 W( a/ b0 H) w9 q! J  {
这里有相应的模拟器源码,就当送给大侠 ...

0 H6 Z* a, F6 C* r聲音部分(Audoi Process Unit = APU):& I; b9 m& Q3 H9 ]7 x$ I
.\NES\APU.cpp' l( L& f- p! o8 i# e
.\NES\APU.h1 ?1 Q! U$ z9 `: H( q1 n: Z
* A, F8 a, T/ B. x2 P% W9 A

! O, u, M5 p& \9 F影像處理部份(Picture Processing Unit = PPU):7 k( E' m6 t5 o" e4 Z5 m# I
.\NES\PPU.cpp+ R& g9 U" ~1 R7 N7 `) J
.\NES\PPU.h
& |+ f& d) i, r1 l' F9 x1 M$ T. e4 V2 I
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
' j; b) E6 ?# U( m) Z9 [- [* Z% U(由于很多专用术语和算法机理都不明白,所以看不大懂……)
6 ^/ y/ Z$ y4 d( ]) Y, e# h//////////////////////////////////////////////////////////////////////////; G* V* ^9 R6 w) ~6 L
//                                                                      //
  ]% D, D* b7 U3 Q9 I* v- k//      NES APU core                                                    //
0 K9 t5 r: o' q8 \- b' H! O4 [//                                                           Norix      //6 Z  ?0 U3 F# A- s. G. u& Q
//                                               written     2002/06/27 //; z/ E8 Q& S9 g( `# a4 Q5 K8 Z4 N5 ?
//                                               last modify ----/--/-- //
$ D  w- O: t. n4 V5 n3 c& X- h* l/////////////////////////////////////////////////////////////////////////// J+ _6 K9 C; p, w
#include "DebugOut.h"
% Y* j% F$ F2 e) }% x5 k- p7 W#include "App.h"7 `1 T4 J. X6 W8 N# h: t
#include "Config.h"
8 R( e3 ~* |, N6 E5 M1 A* d; J% w& T2 E3 s& m
#include "nes.h"9 r4 H* }2 w; ?  u3 y
#include "mmu.h"& T0 ?, c: |' r# R+ N
#include "cpu.h"
% E3 ^9 H; {/ ^#include "ppu.h"
" R2 t. U; J9 w" ^#include "rom.h"
% W0 d& t0 W- z# c" E2 H#include "apu.h"9 Y) i$ n, w( W& G$ |; i% f. i! T
: [' w7 `3 _7 U  ?. r
// Volume adjust
% i7 @5 c! `5 A. t6 [$ u// Internal sounds
5 G5 }! \) _$ F% |$ u9 x#define        RECTANGLE_VOL        (0x0F0)7 H. E5 X2 L( z, b" v. \) \) q
#define        TRIANGLE_VOL        (0x130): p* t" Y; h* |- c/ V
#define        NOISE_VOL        (0x0C0)
# c; d2 l; Z0 x& s#define        DPCM_VOL        (0x0F0)
- L. V  ?/ q5 l& W// Extra sounds' b0 P) J5 @. g( }
#define        VRC6_VOL        (0x0F0). ~9 u% b) [% @, j4 A8 B  N
#define        VRC7_VOL        (0x130)6 O! O( \9 z1 W' S" D, N/ J
#define        FDS_VOL                (0x0F0)5 p7 q1 @, w! z5 u( q2 k2 ]* ]  p
#define        MMC5_VOL        (0x0F0)
( g* G/ |, B  _8 y2 e0 W( \#define        N106_VOL        (0x088)
5 E$ u1 V9 d8 V0 t+ E/ R#define        FME7_VOL        (0x130)! n7 y" d9 r; y
) N4 w4 h7 u# B* V
APU::APU( NES* parent )
- W, V6 G% J* f" w9 _{& R9 p/ g3 c# X2 ~! Y
        exsound_select = 0;
' K$ m3 f% j: J- N* b3 [6 R
* I" J+ c( L, w2 {/ b: |        nes = parent;
$ p7 t" k$ W. e6 }9 Y4 M4 P/ F        internal.SetParent( parent );
' ?$ T# @4 s% U3 N9 q7 C" G
1 B5 c% H) E6 i% y5 R: ?        last_data = last_diff = 0;( k* a: f, m9 \4 J" i- K% ~

( {" N, ?3 y2 l% t. t# B1 p' I1 L/ O        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
# r5 I& ~' U4 v) D0 A# ~. a+ {+ c$ B& e2 y" L* l* L
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
, A! a/ G( G- L7 U3 X        ZEROMEMORY( &queue, sizeof(queue) );
5 k( u5 }( B" j6 t0 o        ZEROMEMORY( &exqueue, sizeof(exqueue) );+ F/ B. x% F( q" x% Z" S$ \/ D
' P# h" S8 P4 q2 u3 }
        for( INT i = 0; i < 16; i++ ) {4 F8 m  V2 W: [" n2 v3 `# y
                m_bMute = TRUE;" x% |1 f) c6 G2 f5 @
        }
  y* ~+ j$ x' j) c- d& ^6 Y}
; j2 P) k6 n- ?% c! M& i- c% c7 }) [; ]0 Y3 ?, H
APU::~APU()) Z8 W( }0 L! s
{
" g( e: G! }3 M; |5 ?}5 }9 e( s4 z. Z" }: ~& y
# I; Z! A3 z- i/ l6 }
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )5 T+ j# ?8 `5 U" g- ~
{
2 v$ T5 N0 ^) a5 v        queue.data[queue.wrptr].time = writetime;- A% f7 d) t+ R
        queue.data[queue.wrptr].addr = addr;
2 J+ @  {' U( {- a$ n) }7 l        queue.data[queue.wrptr].data = data;, w1 p) \4 P7 `: J7 ]3 z9 ]) K; k
        queue.wrptr++;
8 ~' a" [' o/ o+ j8 K; Q: `        queue.wrptr&=QUEUE_LENGTH-1;! _  t9 Z5 j. y8 ^& d2 ~3 t
        if( queue.wrptr == queue.rdptr ) {8 S; ~3 n' Z* |' V, `! t. U
                DEBUGOUT( "queue overflow.\n" );
0 c9 p, {0 E4 F0 v        }4 B" }* F+ ~1 s8 v9 r  Y2 L
}
! a( g, E4 Z; j: c/ W+ A  V8 S! o' E; W4 L0 _
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )/ Y# A- A% y( p8 S8 R0 R" Y+ d% m
{
" j$ i2 m0 s" h( _        if( queue.wrptr == queue.rdptr ) {
  G( ^' @2 s: a; b2 V! H                return        FALSE;# ~6 |' j! W* ~+ A+ S8 `! {/ }
        }5 r* b/ f' x; g
        if( queue.data[queue.rdptr].time <= writetime ) {7 J; M, j; s! h* f4 y
                ret = queue.data[queue.rdptr];- P) u; C* z( ^$ [/ Q9 P* m0 V3 a
                queue.rdptr++;
- r2 h0 r, e! R+ k                queue.rdptr&=QUEUE_LENGTH-1;- A+ n) p* `) r$ E+ ~0 P! y7 Y6 ^  |
                return        TRUE;2 J: T! g8 G/ R. |# l- h( F+ A! j
        }
! {& g$ X- K7 a- }1 l        return        FALSE;/ S+ [, A! R- ?  l
}+ c* e: z" \7 }9 }- M( }, y

( D+ n0 A6 Q6 y' K* g  c7 Avoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
; D7 O! f; a' C. d{
: T8 L" X' N  Y/ o1 m        exqueue.data[exqueue.wrptr].time = writetime;
4 C0 U; T2 x: z! N  H$ b        exqueue.data[exqueue.wrptr].addr = addr;( R! [5 E3 f$ K- Y% c: P. ]
        exqueue.data[exqueue.wrptr].data = data;
; X) V) p* i  S        exqueue.wrptr++;, y  _8 |0 w9 c& G5 z6 Z; E
        exqueue.wrptr&=QUEUE_LENGTH-1;# Y( S3 Y* \8 Z, @
        if( exqueue.wrptr == exqueue.rdptr ) {
1 [* {. v/ q( N9 ^1 U                DEBUGOUT( "exqueue overflow.\n" );
& L& m+ [( T! ~0 n) L5 z6 L        }
/ i9 k) V& T. i3 I6 a}
) t% B8 g( p1 n3 {" r
0 }% Q* Y  `3 n$ x" F9 Z0 qBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
- g; ~$ j* s9 B, D{- B4 ^: t" M, v- r4 I( J
        if( exqueue.wrptr == exqueue.rdptr ) {
4 N" E/ I8 F* V                return        FALSE;
" h: @( N- I3 [8 a        }5 T) @& P3 w6 x, s' |+ E- ~
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {3 f+ \3 a# K& y; g3 H- y/ g, I
                ret = exqueue.data[exqueue.rdptr];
. d. i  Z0 |) [! F                exqueue.rdptr++;9 o9 Y( I) h7 j* O$ T5 g3 [' y
                exqueue.rdptr&=QUEUE_LENGTH-1;
0 V# x* g2 x2 J$ E- ^4 v                return        TRUE;* [0 U# x& @5 z' f" e! v: [
        }3 ?$ a3 g3 p. F6 x* _
        return        FALSE;
" T0 M0 {2 K1 A' [}
0 {# O# M+ ]0 |7 O* j' D! B, ~+ N$ @  {" }" |$ Q
void        APU::QueueClear()6 ^8 [3 ~, s- U" ?8 i3 w- L" J  `
{6 \0 U6 d* Z) g) O' T
        ZEROMEMORY( &queue, sizeof(queue) );1 W0 r( _5 B" s, ]+ S4 G2 W
        ZEROMEMORY( &exqueue, sizeof(exqueue) );: J5 r3 e- v: R- W
}5 G9 C4 l/ T9 r  [$ a! p+ ~% y

* ?- T$ X8 h0 {/ a4 q/ [void        APU::QueueFlush()
5 m6 b/ i  f, Q0 I* R! N( f2 b: Y{7 J3 {" }' z4 u/ M1 k
        while( queue.wrptr != queue.rdptr ) {1 }$ R' X) X) E0 f
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
! M7 Y7 a. @0 N" [                queue.rdptr++;
8 u$ H: Y, ]0 Q- A9 E                queue.rdptr&=QUEUE_LENGTH-1;5 P* c- M5 t* D! T% C6 _
        }! m% _' S5 |5 G  E( H9 ~
" Z" b1 d5 R/ s3 y/ m
        while( exqueue.wrptr != exqueue.rdptr ) {
$ }" {9 H. w" i1 R  S$ W& R0 ^5 j                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );  T. E" L( o7 N
                exqueue.rdptr++;
: t$ E$ v+ _6 K/ z$ Z4 E                exqueue.rdptr&=QUEUE_LENGTH-1;
+ v! k+ H. G) a& \8 r/ K        }  U: Z% a8 x: L, y
}
! e5 R7 `# ?! z4 u
% r+ A( s5 w: N6 Hvoid        APU::SoundSetup()
& N& I! F7 y! R- O# C6 B% q: D! ]{! |0 a! I1 G# I  G
        FLOAT        fClock = nes->nescfg->CpuClock;  z, {; q. H: |) d
        INT        nRate = (INT)Config.sound.nRate;
- b! V' D+ _7 }$ ~: `        internal.Setup( fClock, nRate );# X: u: f4 [0 r9 [$ R; H0 `! x
        vrc6.Setup( fClock, nRate );) o% S, c' }. C, v
        vrc7.Setup( fClock, nRate );" ^1 g1 |! a$ z% s
        mmc5.Setup( fClock, nRate );5 A! ~; t2 ^; m. B2 a9 b
        fds.Setup ( fClock, nRate );
' H7 v  \' Z3 g: r% W1 A: K0 \        n106.Setup( fClock, nRate );
. Z$ ~/ u# R( F4 x6 i& d# z        fme7.Setup( fClock, nRate );3 D6 T. `, E* N5 X
}
2 v, j- @5 i$ A1 q( L+ y5 |" }8 }/ d) k6 _% p" h
void        APU::Reset()
0 A$ n% E; \$ Z( g# ]{# c' b. Q3 _5 X7 o' [: ^' f: j
        ZEROMEMORY( &queue, sizeof(queue) );! Q  L/ f( m9 J7 @
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
& P4 V% q( o! W* [. @( ^7 h5 [! r7 O4 {) v3 C2 P6 i" C8 t
        elapsed_time = 0;6 l4 k8 ?, r, _2 u* t
6 s4 r- \7 j7 }
        FLOAT        fClock = nes->nescfg->CpuClock;
* W. ~* a! o! w7 }/ s; |+ k  C0 e: B        INT        nRate = (INT)Config.sound.nRate;
  }* Z' W( W3 `4 y        internal.Reset( fClock, nRate );
9 {1 c4 z* n# G8 a2 ^' n' s( m        vrc6.Reset( fClock, nRate );
+ W! R9 b# G0 G3 P7 f3 ]7 Q5 _$ p        vrc7.Reset( fClock, nRate );, k" }  m, n/ W4 H9 H' `
        mmc5.Reset( fClock, nRate );" `# ^" ^( v6 o! D, k  J
        fds.Reset ( fClock, nRate );
& i  w/ V# k- g) @! Q) r        n106.Reset( fClock, nRate );0 A) E9 H  |" E: `( z; _' ~9 F
        fme7.Reset( fClock, nRate );6 c) ^2 o2 y) [& L+ _4 Z, m, W

  l9 m9 i8 t8 x6 L        SoundSetup();6 R1 O" q3 x# O: u" b& Y/ W
}
' J# X! P9 R0 p6 y
. `7 q% i) b) X1 f' J9 e6 r2 Gvoid        APU::SelectExSound( BYTE data )
: R5 `/ ^4 {- X7 T( Z{
. c& I( ^% d' U5 z2 C! O        exsound_select = data;; F+ D+ f) {) r* A# a- p% Q( n
}# x  R+ ^9 i9 k; g+ {: s+ g

2 B+ c4 {3 j4 B  H0 GBYTE        APU::Read( WORD addr )
( v% L3 l% n+ A0 C{
. w. U4 f1 X! V' I" `9 w        return        internal.SyncRead( addr );$ w% B$ y  |# u& T: u
}- a$ q) a/ q" l# D1 s; R
1 K  m) O$ c$ W( {0 e0 Q4 m+ g
void        APU::Write( WORD addr, BYTE data )
: V5 e- W& i) s# P; u{, J( r+ {$ x: w0 P, q3 S$ A6 t" m
        // $4018偼VirtuaNES屌桳億乕僩
- ?) u- x9 k5 l        if( addr >= 0x4000 && addr <= 0x401F ) {
; v7 Y7 o1 @# E' R$ U                internal.SyncWrite( addr, data );3 ~! b0 n# P6 O% ~, C* G( I" Z8 I& I
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
" o4 |% g) W/ y! i* @( z4 P9 F. P' c        }! m# K  X4 b6 E! u6 t6 q
}
/ j, T2 ^8 f( U9 c& D  z2 @2 Q+ ?' k9 O$ W# c
BYTE        APU::ExRead( WORD addr )
4 Z5 \8 A- A$ U, T. o{6 T, w& Z, U) c3 n- P
BYTE        data = 0;
' `# Y8 \  H: i% a. I) M& T
/ J5 |( _+ A+ a  _6 ^        if( exsound_select & 0x10 ) {
- v- E+ D. c. o- Z$ B                if( addr == 0x4800 ) {
; A! q+ i" i: e                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );7 g4 ^0 r' P( R, h1 u1 _5 N$ S
                }
+ g1 B& O7 K3 D7 E8 }, `. \        }7 w& t/ {9 ?: t+ a& P
        if( exsound_select & 0x04 ) {- f( }/ H# B* ^" C% v
                if( addr >= 0x4040 && addr < 0x4100 ) {
; q; D, W2 ^4 I4 }! e& _                        data = fds.SyncRead( addr );
* z7 M$ {& k; |9 Y, c                }! M3 x: N% |! z
        }
8 ]& ~$ G1 F$ K$ j/ Q        if( exsound_select & 0x08 ) {+ e" R# b+ R6 M+ w4 P
                if( addr >= 0x5000 && addr <= 0x5015 ) {
/ f4 u8 n# M3 {3 k                        data = mmc5.SyncRead( addr );
7 h4 d7 H' L8 b6 C: o( E# \6 w# }' ]                }) Q1 o0 B& w9 D' c
        }
, _# X0 M( t( H7 g7 ?
3 t, Q( y* ^# Y3 B/ F: ^! H: v3 a" {        return        data;
4 d; _" X* r! m) c# E2 m- }: n}) @5 V4 t; r; J
& `6 A' [- q- |5 V( {$ x
void        APU::ExWrite( WORD addr, BYTE data )  {7 c! k. \3 Z/ ^& {
{
1 A# [, ?# a  ]        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
2 \4 t8 s- r9 Z2 y' w  N' U2 H1 ^8 u3 g# L4 Q4 l0 P& _* A+ w) A& o+ w
        if( exsound_select & 0x04 ) {
3 H& a% f" [8 ^( ?                if( addr >= 0x4040 && addr < 0x4100 ) {
4 B) O0 Z( {! }3 o& y# A: M! X# r                        fds.SyncWrite( addr, data );0 W- g" h+ E* E7 y" c( d' p
                }
0 r! P- s0 q# W$ z        }: y0 W% s5 {& N

/ F2 Y" a& v' q5 B# A9 ?& \        if( exsound_select & 0x08 ) {5 B" N- N- c7 D8 S% W/ y  W
                if( addr >= 0x5000 && addr <= 0x5015 ) {, q8 h$ ~% d7 [. n5 H/ v: ~  f
                        mmc5.SyncWrite( addr, data );
3 e, ~4 V3 F3 P! {' }. L8 \7 T                }
8 ]. b& \( y# g# T- ]        }( i2 E2 c* D8 v0 G9 ~8 r
}, [0 g1 ]$ [, ]7 L2 u9 u

' `" [0 O- N1 [. {: A9 i4 N4 y+ u+ N! Yvoid        APU::Sync()* o2 {' r2 m" w; A
{
+ |& b$ i" s3 W# w/ z}
  t; T2 X/ D  e+ V+ o! Z% C  N' s- c$ t4 `  S+ A# `
void        APU::SyncDPCM( INT cycles )
* F2 `  p0 U1 @- x! K) x4 H/ P) n4 V{
) Y* C* J7 p5 E; _6 O        internal.Sync( cycles );
6 l- Q- o0 g) v$ A" i: {! o6 U" y7 u
        if( exsound_select & 0x04 ) {
4 r5 W6 M% v7 v                fds.Sync( cycles );7 ], V( N) r5 u$ ?4 n
        }
( i* a7 I4 U1 W4 T, o/ Y. `5 J        if( exsound_select & 0x08 ) {
* |1 b: `) W" K! Z                mmc5.Sync( cycles );$ j# A% \$ D# O* U6 U2 y* e- v
        }5 S% k/ o4 y5 [
}
$ {6 \+ _, o8 M9 h/ C- l, E7 P4 `2 Q0 E. ]# u' c5 @9 ]9 r1 ^* X) u
void        APU::WriteProcess( WORD addr, BYTE data )8 G8 d0 U: m- I, L8 E8 S, F$ Y/ A
{3 i/ f% t1 s1 r
        // $4018偼VirtuaNES屌桳億乕僩
) u0 v* j: l( ^" U7 n( L        if( addr >= 0x4000 && addr <= 0x401F ) {
; Q- R3 \) `, D9 r2 \$ d9 ~( s                internal.Write( addr, data );! C: n$ @6 {  G; f% f- r6 M4 H
        }; l: K/ A$ m3 M, m4 i/ c) t# M) @
}
  J/ e, H9 l! R: d% H: M! y
8 V0 g% c& |% y2 `# x6 avoid        APU::WriteExProcess( WORD addr, BYTE data ), I6 c. ~! u$ o8 q
{5 _5 R; T: m7 V) Z1 ~
        if( exsound_select & 0x01 ) {
- g2 o% |9 A4 X. W/ V5 C. s                vrc6.Write( addr, data );
: d& T1 b& s- W* E0 Z7 `6 o        }4 o: m+ t3 C/ H
        if( exsound_select & 0x02 ) {
: M. [3 v& A$ R+ h9 g                vrc7.Write( addr, data );
" x( P& H- y% l5 \2 h* ^3 G        }; f: h6 t3 n! A" z  H6 [
        if( exsound_select & 0x04 ) {& B9 O# f; F! F
                fds.Write( addr, data );7 S9 l9 D& l) N1 j2 E( p3 v& u0 T
        }! ~* K& a' H) x- u* V5 ]
        if( exsound_select & 0x08 ) {' L& X+ M  I* s# y
                mmc5.Write( addr, data );
/ y, a- N* i7 O! G        }
7 S& p5 ?6 I: V        if( exsound_select & 0x10 ) {+ o# g/ P; M% K9 q' H
                if( addr == 0x0000 ) {; |  p% [0 h# `% G6 |" o% l
                        BYTE        dummy = n106.Read( addr );
. C! n: W9 z7 K, s3 O$ C& t                } else {# R* e  W6 t2 c
                        n106.Write( addr, data );4 r. v$ z2 {9 S/ q2 S6 w1 W, d1 A
                }, q# U. |/ N2 T
        }4 I; g0 [( ]' C
        if( exsound_select & 0x20 ) {; S! A8 `6 N" ^9 O4 j
                fme7.Write( addr, data );
: }) S/ T  j- A# W1 V        }
% Z/ ^# \5 h/ w; K}* v2 s. P( O& |: p  m+ r( q

" _* v+ n# A) Yvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
( M( @9 P3 |/ d2 b, e{
5 X9 l) P- A% E% BINT        nBits = Config.sound.nBits;
" s4 x" P5 Y: O! dDWORD        dwLength = dwSize / (nBits/8);. }! V, y2 C$ i3 K
INT        output;
$ i' y0 _6 \/ X8 o: rQUEUEDATA q;
' N& ?, q7 b& \8 g9 B: NDWORD        writetime;
, \& O$ a6 n# |/ e4 z4 P+ f
- p! H/ z# S' M- f6 M% j* B9 CLPSHORT        pSoundBuf = m_SoundBuffer;
/ t* j; F) R2 R) b% JINT        nCcount = 0;% x3 M/ ?% m! P) v* V- f' Z8 T1 ~1 B

9 C( H  Z$ x5 \INT        nFilterType = Config.sound.nFilterType;1 S* }( ?1 s/ n8 k# n6 |# V

; M5 o& O$ ^+ C* [; M/ a        if( !Config.sound.bEnable ) {0 v8 Y( v( A  E8 ~
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
; x; {9 r* _; ^                return;
! Q; c( z& }& I! z9 N        }
8 X( S4 e& r% M  P  c2 z4 B& O0 K
        // Volume setup
* ]0 a1 i/ M$ q        //  0:Master
" N8 |" w+ m5 M* j* _/ t        //  1:Rectangle 1" B) C+ }6 z- Y, c
        //  2:Rectangle 2- Z* l3 `- m: d( `: h3 p' a  I
        //  3:Triangle' z* C$ M& N% r- O' v* D
        //  4:Noise
: J: Y1 J' V8 [% ^+ J; A6 _        //  5:DPCM: N: P* _0 R& b- D* I% A
        //  6:VRC6& @! }+ E) a. e5 }6 Y  u  b8 F
        //  7:VRC74 V" s1 k# S6 W
        //  8:FDS
/ S  @9 H2 ^* }, B        //  9:MMC5
; d  }8 d. r0 L/ K( w! ]7 N$ d- ^        // 10:N106
3 O* e' C# r) u. f        // 11:FME7
8 |! k  v4 m9 f$ p' [- O/ Z( P        INT        vol[24];
& Y% |1 n9 U3 ?4 m: y* b        BOOL*        bMute = m_bMute;
) K3 `( Q7 d9 m0 [  D& I1 C$ d6 h        SHORT*        nVolume = Config.sound.nVolume;, P# f4 I, u6 S1 t5 L- P7 D; k
  R, O. S3 K& l# y
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;0 D/ K  m4 O8 C% I
. U8 r- O6 h6 {$ @
        // Internal) S! Y4 j) r: k; c4 _
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;& F8 r2 s( t8 k7 B* |
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;# w/ v  U  _" G; T, b2 y
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;# d# o0 q3 j6 U( Y0 ?  K3 Q$ z
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
' l6 \1 A1 C% I/ d& v) Z8 y        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
# e5 w: K/ N! P( b5 P  x9 r# l$ X6 _4 J5 B  H/ y: v1 N' W" \& _
        // VRC6
5 `$ v! J9 D( }7 z        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;" e) r3 Q- Y; Q" B# j* B
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;2 L1 M- J5 y9 U
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
4 d0 v# s0 F$ H6 H
0 s" ]! ?" U) k+ K/ U  Q& H5 ]7 P        // VRC7- C6 |' r  g0 B) V
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;9 K; g3 i, G# y- z

' h) u5 K, i& f* m  R7 w6 Q        // FDS! x; ~% C# d2 y, Q
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
. g, U( y; A3 O+ M) w* y0 ^+ F0 b% s4 p
        // MMC5
; K; ?" ~5 i2 `+ K6 g; F  ^  E        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
5 W4 l: k% O, v. p8 h% h        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;5 O8 e- Y; X( X
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
7 z) ^8 z/ b, O) U, q) M; m
6 H* \+ j$ d& _% M" I        // N106% F- u; {+ s' e# P. k7 ~, R, S: s
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
5 l+ u2 x" t& T. O) I/ T        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: E2 H& L- h" G4 X1 o5 ^4 _7 }        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- T5 B) |: V- e4 V7 e, s
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- F! U' Y6 V* s        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
) H: j$ q$ J* v% m# t) I        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;& e( X& c7 e( S4 @" Y/ z5 l* ]0 U
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;# _; b" d2 r8 @& J
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;1 H/ d! C  I* c. X, I

( m1 C4 I2 o3 D7 B7 p2 Q$ y- J5 Q        // FME7
2 x1 r( z/ q; P! g        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;9 l+ S" {) [6 N+ t
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
, P8 m, ]4 q. x  c% g7 e        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;$ [- ^8 r% X' s; x
0 h, b/ K! @! F2 ~" Q. |% m
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;* j) \. S8 I+ o, b6 d
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
$ G- ?# F0 m1 C9 w  j6 S
( D+ }9 t5 _0 b# E" v: t! \; I) h        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟/ _$ q3 q$ Q" u( H1 \; \1 F- K* |
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
% }' Z. e; b  u) |                QueueFlush();' D( M0 ~: f( m- e
        }3 L0 m+ a: Z/ e
1 z1 U1 U! j6 o1 ~
        while( dwLength-- ) {9 A" l3 S0 a1 S3 E0 C, ^" ^  Q
                writetime = (DWORD)elapsed_time;% d' a3 T% Y/ m4 P
" ~# s3 h; F4 e3 o, @
                while( GetQueue( writetime, q ) ) {
  t& D' R% G6 k1 ]. }, q                        WriteProcess( q.addr, q.data );7 Y2 F0 Q) u/ ]3 t$ V
                }
9 d& I$ ^; D8 Z& X
- z0 y! C" j9 d2 ?* w                while( GetExQueue( writetime, q ) ) {$ \6 t1 U4 g- A  t6 q& u1 f
                        WriteExProcess( q.addr, q.data );
, D9 `- V; v3 p  `/ R" T                }3 [( u' @* Y8 L' G7 g+ p' s+ u
, [6 Y  E) L9 e. w% ~
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
/ t6 Y3 U& d5 f) A1 I: ]* A                output = 0;+ b2 P9 k7 U5 ~4 G* ]9 e
                output += internal.Process( 0 )*vol[0];
* w/ c5 N% f, s                output += internal.Process( 1 )*vol[1];
2 R+ ]& R2 x# t  }* K                output += internal.Process( 2 )*vol[2];7 i0 ~7 [- \: V& E
                output += internal.Process( 3 )*vol[3];9 h) H/ v% y5 d: s3 U
                output += internal.Process( 4 )*vol[4];
- t% @* ^/ W- h. Z$ Q' B+ ]3 \& {- J- q4 D( H7 `8 j% e
                if( exsound_select & 0x01 ) {0 e" S2 C6 A; \
                        output += vrc6.Process( 0 )*vol[5];
% a7 N4 h) Z7 f* d                        output += vrc6.Process( 1 )*vol[6];
# I; R& N( B- M" T                        output += vrc6.Process( 2 )*vol[7];
1 F$ T2 n! W% B4 ~- t                }1 U2 n9 U3 f. C2 L5 E
                if( exsound_select & 0x02 ) {
) h% ?6 M) M: r* N, ^7 y2 [3 O+ `                        output += vrc7.Process( 0 )*vol[8];. P" t$ E$ [) E7 b
                }
9 v% T3 y& d0 i$ {; R9 J. N                if( exsound_select & 0x04 ) {2 w8 ^5 V0 K* v3 f
                        output += fds.Process( 0 )*vol[9];4 {0 w* Q- z# w. i
                }- n5 }8 a8 Q( a% s9 B5 H
                if( exsound_select & 0x08 ) {
" j& J% ]! v6 w. I9 v6 \                        output += mmc5.Process( 0 )*vol[10];
. D2 c6 Z) G7 R5 `3 s! S                        output += mmc5.Process( 1 )*vol[11];$ F- q8 M: m+ `5 S, A, C! \
                        output += mmc5.Process( 2 )*vol[12];
& a8 Y  N9 y/ J6 ?3 L3 i                }
% G8 D, A+ o6 b9 I" T                if( exsound_select & 0x10 ) {
8 d1 L2 f3 I" X/ k; p1 C                        output += n106.Process( 0 )*vol[13];6 \! h, H1 G" p" ?6 e' B; v+ H8 m
                        output += n106.Process( 1 )*vol[14];* H2 n0 r( b1 A3 F5 I9 b
                        output += n106.Process( 2 )*vol[15];
: @( K# d; g( s                        output += n106.Process( 3 )*vol[16];
8 V9 _; e: g  x                        output += n106.Process( 4 )*vol[17];
& f5 M, y5 L/ b# q0 M# n                        output += n106.Process( 5 )*vol[18];- [5 z$ l& j* V8 v3 c. N& s
                        output += n106.Process( 6 )*vol[19];
5 \  c' D: h1 }1 i: b% ]# O+ v                        output += n106.Process( 7 )*vol[20];
2 r$ r) d" E. G! x                }
4 ?( k7 ^) ?8 M# s: y- P0 ^2 W  X5 ]                if( exsound_select & 0x20 ) {+ p& u  w1 T" i2 [& \7 [' i- ~
                        fme7.Process( 3 );        // Envelope & Noise7 U4 `' j$ T# ?, i5 I: `# B' h0 l
                        output += fme7.Process( 0 )*vol[21];
* K$ E3 X6 O- A0 ^, j/ M% U5 D% ]* l                        output += fme7.Process( 1 )*vol[22];) |; w2 @5 e, S, M
                        output += fme7.Process( 2 )*vol[23];
5 z0 D5 N8 d% y; `/ O                }7 t6 C+ A' t& s* r% g5 n
4 @1 Q/ O7 I4 d/ Z, ^8 Y) \0 L/ g
                output >>= 8;+ U* l) G0 y6 B3 q
9 F$ k2 C9 n7 z3 s/ W/ B3 @2 u
                if( nFilterType == 1 ) {
2 k5 A2 ^( b+ z                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
: F* v) j+ z. ~: w9 s: G                        output = (lowpass_filter[0]+output)/2;# s! M* N5 b% w2 r0 o, p* I
                        lowpass_filter[0] = output;
4 }9 f1 S$ @5 V5 L                } else if( nFilterType == 2 ) {
9 u( P6 S3 D: @; c                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
% O" |6 w& B" n' ^* c6 ?2 p0 k                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;6 D) h* D, J0 r2 ?  l+ {
                        lowpass_filter[1] = lowpass_filter[0];9 f# L/ B, I( @; c' T  v
                        lowpass_filter[0] = output;- D6 p! k) v8 ]+ \* S$ J
                } else if( nFilterType == 3 ) {+ O" g6 f5 P. {& b, o
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)6 [* t7 x' G" D# V9 b- ?& K* u
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;7 [0 P" a$ r* @  Z9 r
                        lowpass_filter[2] = lowpass_filter[1];3 |$ u$ ?! R& W" E
                        lowpass_filter[1] = lowpass_filter[0];( Z% a. V  g: ^8 s# U
                        lowpass_filter[0] = output;
7 Y4 n! m  \0 A) b/ N3 D2 u                } else if( nFilterType == 4 ) {
; |2 l! e# d/ P/ N( D* _" g* u9 E                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)1 G4 q. s+ ?* b, @
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
; V( v4 l7 _% b                        lowpass_filter[1] = lowpass_filter[0];
# d7 ~) B% A% A9 o% d  W5 [                        lowpass_filter[0] = output;
: }- c* b3 j, p( `$ `/ a* r                }" ]0 ?3 q3 ?6 ?- \3 C9 ]! ]

) E, L" t) z8 y#if        0
4 }1 m; X% w5 r' |                // DC惉暘偺僇僢僩
/ g5 q) ~- u$ I. ]7 [' R2 Z                {
8 S0 R: _; T: K/ J                static double ave = 0.0, max=0.0, min=0.0;
$ p9 j" j" A4 F  C                double delta;$ x0 L. o" k: u: q* Z
                delta = (max-min)/32768.0;
6 G' P, g5 E( l; x6 [                max -= delta;: X% U8 M. _, n
                min += delta;
8 h5 _8 h. i+ e. b! X4 g                if( output > max ) max = output;& b% j4 w- w' {8 d. x
                if( output < min ) min = output;
% H9 B! c- Y3 @                ave -= ave/1024.0;
7 H  e& N0 x2 ]4 f8 z( s                ave += (max+min)/2048.0;
& z& z- G6 c3 I9 b' t& v$ X, W( ~                output -= (INT)ave;" z% P# u: v; h
                }& h0 Z: d1 N8 w
#endif/ W4 h# e) u9 F! M4 @6 C% i4 a% G+ ^
#if        1
- g1 q# K% K' o8 y4 M1 \( F! e                // DC惉暘偺僇僢僩(HPF TEST)1 {0 k4 v9 C; K/ z# x% C, E" J
                {
# ~. s  }/ f6 b  W( D5 ?7 K3 g7 ?//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
2 r% p* T3 r' i3 }0 q                static        double        cutofftemp = (2.0*3.141592653579*40.0);
9 j  O6 Q$ o# P                double        cutoff = cutofftemp/(double)Config.sound.nRate;# o& l( @  V% [; X4 M& J, C
                static        double        tmp = 0.0;4 H" ]3 H) Z9 ]% W: x+ \) n! ~
                double        in, out;
- \8 @& g& G$ k% m3 N1 _" E& h4 l3 ?/ P" J
                in = (double)output;9 V3 U6 Z2 X4 J( j
                out = (in - tmp);
# A5 V0 ~$ n% T& h) G( K                tmp = tmp + cutoff * out;/ F1 Y* I" |9 D9 l2 U9 P2 ~! {

/ j4 L8 Z6 ?. J& M; y2 o4 n                output = (INT)out;  F9 j2 f/ G, s! W* T
                }( ^8 T5 X& \( ~) {% K" n* [- a
#endif2 f6 s* j! q) O
#if        02 j. ?+ E0 [: N7 I+ D1 d2 q7 w
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)0 @: t& s! p1 o  b, x
                {
6 B" e5 Y' K$ @, p7 M7 v                INT        diff = abs(output-last_data);0 q$ d6 Q5 {* m9 V4 n
                if( diff > 0x4000 ) {* V2 c! Q9 n+ R& w2 J3 ^
                        output /= 4;, m$ o2 u; W9 u0 D: d6 i& I
                } else % B: ^3 X' n% Y- a5 X& Q& V0 x1 l
                if( diff > 0x3000 ) {& ~0 q/ L8 m! f$ f8 s5 b" W
                        output /= 3;/ ]" a1 ?2 x8 }+ x: _% k) k
                } else5 T: u5 f0 b' w1 o/ n) N- K9 j
                if( diff > 0x2000 ) {
$ c/ @8 r7 W" _$ x                        output /= 2;
8 D$ \' h9 n& `1 ?' V5 r" n- F: Q                }
# n' A# N' u% W% v- t                last_data = output;9 T5 \7 \1 Y- a! @
                }) x; X. u7 r. X
#endif9 x5 N& h: {, f5 _) q$ Y7 |5 j2 Z- ~
                // Limit
6 G$ y! k6 Y/ h5 U7 v; F9 l                if( output > 0x7FFF ) {
2 W! P7 u% E7 a- Z/ j                        output = 0x7FFF;
& N# I# b$ `- J                } else if( output < -0x8000 ) {  T& k" f' L. T) q0 ?8 p
                        output = -0x8000;
" X' ]6 p; ]/ y3 v- i                }
8 R$ C* n* k* K. N) G2 V& Z6 x. {/ H# t( I2 d. K
                if( nBits != 8 ) {5 Y* A& g, J" U/ R3 @, W
                        *(SHORT*)lpBuffer = (SHORT)output;
/ G8 K- L' V( n) r% M2 `  B: C                        lpBuffer += sizeof(SHORT);
3 p- [+ F" x" ~, x4 E                } else {1 u: i0 c' b% ?, b: e
                        *lpBuffer++ = (output>>8)^0x80;
: Y9 T2 R( U; ?4 [, f                }, W5 S2 e' C0 n, F( N% ^7 A# P6 w
( B6 Z( F1 w0 q: P  ]' @
                if( nCcount < 0x0100 )
+ p; [, v6 x4 Y0 s                        pSoundBuf[nCcount++] = (SHORT)output;
5 E. o; f. T; B1 a
( v) a( `3 O/ A, a: E$ a//                elapsedtime += cycle_rate;0 d7 I& n$ y8 i- V% q
                elapsed_time += cycle_rate;
& q' I* p( [6 Y% `# R        }1 B% E/ w0 S0 X
; B9 [) o; A* i; w7 ?5 s' N' ^/ w
#if        1
) P1 N/ N3 K, c- U        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
( M' `; T( J9 {4 i) Y3 J                elapsed_time = nes->cpu->GetTotalCycles();
/ g$ V: I' e, v+ {        }
/ h- v  P) A( G- ?; {8 n% v0 U        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {  `% [  h5 }9 ?$ \7 x" [
                elapsed_time = nes->cpu->GetTotalCycles();( V$ G0 w* K5 B) ?6 _; g! e
        }# D& P0 K" F& P: Y
#else6 j: b2 d! \/ |3 R( N
        elapsed_time = nes->cpu->GetTotalCycles();
) ^: Z. X9 D# w# I#endif- F( p0 U4 c& ~7 j* [) W/ y) J
}) h( l' c! s) v+ z8 B  \, t
7 Y7 f' q2 d" f% ~7 Y) K0 S7 j$ g
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
# M1 {3 s* A8 R" D+ oINT        APU::GetChannelFrequency( INT no )
$ _0 `3 U1 E  D4 Z8 S4 v% {4 c{3 z0 J7 O9 B# @+ C
        if( !m_bMute[0] )9 I" V7 U0 H( l$ {0 c1 U, C& s2 M2 j
                return        0;
* d4 \& t1 N$ ^9 `
1 T# i4 N/ Y6 u4 o        // Internal  `9 i- k8 N1 I4 J8 }; S, C
        if( no < 5 ) {
& S1 H2 }7 G9 N# v% h                return        m_bMute[no+1]?internal.GetFreq( no ):0;' q1 e( ~) q: Q$ h2 Y& B9 E
        }/ X# E. i7 c$ `& o  g, S- d" |
        // VRC6
4 r* O1 r: a6 g5 \        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {# l" o, ?1 D  d. ^& }8 M- C3 l" Q
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;% ~$ K1 u2 \9 H; p; G
        }
2 X6 C' O( N/ V4 M7 U: y        // FDS
: k  W, j7 t! W3 c        if( (exsound_select & 0x04) && no == 0x300 ) {
4 ~/ E" l( v, C4 }$ `7 v9 w                return        m_bMute[6]?fds.GetFreq( 0 ):0;
; x( G8 W6 |" t) C6 K        }8 D1 @" B) X, ?4 \0 p. W7 v
        // MMC56 |% j3 V7 `! W+ d/ {. g
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
, r2 n# N4 r6 x% B5 _                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;1 ?! t- ^% U  L) W2 W
        }4 {* ^/ b0 d9 q2 {* C' y4 I. T
        // N106
* R! g2 N2 P* W        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
* V0 _# u% Y2 C# M1 E                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
$ U, Z% ]4 @( O0 I  f        }
  b5 \( P: r, [+ e# V* \# a        // FME7. L, y: F3 F  c; j
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
, J# N% I$ r7 t                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
! @9 l' F  t4 l9 J0 N        }7 C4 {( _8 a6 g/ r; G0 H
        // VRC7
7 W* @3 t& J2 B' a( ?/ d        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
' E% w: C; [( u( m, n0 ^0 k; n9 d                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
: N5 \% V3 p6 {! {8 W" E  o        }
! K; p3 a+ _" W" o        return        0;
5 t* p; z0 I& {5 J- F}6 o# s. a/ z; g$ E& s' G
9 J9 j  ~6 d  ~
// State Save/Load* B/ ^9 z5 e' P, i* Q* x" {$ h' ~
void        APU::SaveState( LPBYTE p )2 s1 x4 v$ d, [+ C
{6 `: G4 s+ y: m$ ~
#ifdef        _DEBUG
( p2 W5 \5 \, i6 oLPBYTE        pold = p;
: `7 \; s$ I# M' i, I0 L#endif
# P4 \( i/ A3 P# X: d) T+ h0 g4 }+ E; o6 u1 q. R! F& ]
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞8 X, y/ `- E+ S7 r' C, }2 @5 A
        QueueFlush();
/ z3 u* A6 U0 \0 z6 M$ L/ y
! c7 ^1 o' p: z" V8 H5 \8 l, _4 E        internal.SaveState( p );
/ p' N; {( K3 V( r5 u/ Q( w- r        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
. g6 X5 h) v( p
2 b" \% P! |$ z/ Q" v        // VRC6
7 c! t( F  l6 b) c5 E        if( exsound_select & 0x01 ) {5 x6 i4 [: v7 G- T/ V2 F0 Z
                vrc6.SaveState( p );
. s6 M+ r* g- |; ]; i                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
1 @5 a, P- G, _$ z' C( o! W        }
1 f+ J6 `% x1 f8 k( u        // VRC7 (not support)
5 ?" s; u; N5 m) X2 a/ P( a        if( exsound_select & 0x02 ) {: i6 f" u+ Z! h" n2 @5 \
                vrc7.SaveState( p );* u7 H8 m, \/ \( A- t- a/ i# W9 L% d
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
  v6 F) g* I$ N& j2 K- c: W        }
8 n2 ~- r6 [2 N! N        // FDS9 z" y0 d% h- n7 `0 @
        if( exsound_select & 0x04 ) {
% P9 h# T7 X* b5 g* x                fds.SaveState( p );
, L  f# i5 ~/ q" `* q                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding- q  |; c9 r  P; G) j
        }
1 z* V4 r& N2 F0 \        // MMC5* Q& O9 c8 y2 O" x0 J7 A
        if( exsound_select & 0x08 ) {# K2 b; \  I9 e2 _+ ^8 i" M" q
                mmc5.SaveState( p );* F) J! z  R: v# H. O6 h
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
4 F6 c0 T5 s; {. Z        }7 U4 {/ g9 Z% w; p5 B. r7 o
        // N1066 q- [# O% T  y6 `& W  I4 w& i/ `
        if( exsound_select & 0x10 ) {( ?: V( Z5 D) [1 v" w) O& m8 a
                n106.SaveState( p );
: }! m1 M; g7 I$ ?9 O                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
: y: G- q% C: g% |9 F5 X: Y3 S' N5 L        }
* l. ^& q6 ]$ Q& n' [0 f        // FME7
0 {3 D. U7 V& m7 I        if( exsound_select & 0x20 ) {
1 P5 @) P# f& Y" l. V6 n* Q4 V                fme7.SaveState( p );  y$ _2 u- s+ j. u# Y0 i/ d
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding% ^* c% z& s; ~- v( H+ X4 W' a# H
        }
! Z( v9 p  q7 U' c
. Z' m# X4 d3 t4 c; }* k#ifdef        _DEBUG
0 f! `0 W& s0 O- QDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
1 C7 r2 t! V- W* t0 a6 c- x#endif
+ j8 \8 D2 l% L  ]5 [5 R}
9 ]+ A3 f+ ?5 {& {" D* U% x, q) I4 t: Q0 M' B
void        APU::LoadState( LPBYTE p )
$ O" C5 H0 W2 o( F' q! m1 h1 `9 i{
, C. R! S2 d% N- ?$ \+ I        // 帪娫幉傪摨婜偝偣傞堊偵徚偡4 U. K1 C' k) J
        QueueClear();
5 P: v7 e5 f4 O- d0 ^
& J1 T. C' ?3 W+ u        internal.LoadState( p );
7 n. N/ }/ Q9 P0 ]% a        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
8 Y/ m# p+ U- }' n' a2 s( _- o, E4 H
        // VRC6
% u0 e' l, ]3 B1 P9 p1 n6 ]        if( exsound_select & 0x01 ) {
: y2 k# ], R# t3 O                vrc6.LoadState( p );
/ z; [6 K: R# [' F/ w; h                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
7 g4 |( B$ X4 q+ Q+ L, o        }7 b4 y, q- s% J. G
        // VRC7 (not support)% T8 V9 v) w8 s) y4 @4 Y7 K3 k) F1 ~
        if( exsound_select & 0x02 ) {; r; r) S9 L8 b# A) M/ n# u1 W6 X
                vrc7.LoadState( p );
% f: z) f. B, s+ [" `& O                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
7 i9 X" Y' Z; @0 X; b) F        }
# _, Z9 e( n' [( g2 h        // FDS/ m% s8 w- e# g4 p; {# X
        if( exsound_select & 0x04 ) {
* v, b" f4 K& ^                fds.LoadState( p );
" }$ _6 n0 M1 O( U. P5 k4 r/ A9 [                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding* y+ U7 L: H. ^9 C% u' m) U: L
        }
) L( ]1 P2 l6 j) x7 G( V# Q        // MMC5( P/ X) P9 M2 L% t0 r
        if( exsound_select & 0x08 ) {8 S+ b) J8 L4 n$ a* w
                mmc5.LoadState( p );
+ e. I; g+ H% ~- M% a% Z6 E- Q) ^                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding, |: U" n/ N2 F: _: S& x! H
        }
  e4 p  f8 ]1 z* h- s# T        // N106
+ l- P) i" s" S/ B7 L        if( exsound_select & 0x10 ) {, l. C7 Y) z! K( s; }* H/ p
                n106.LoadState( p );
2 T+ h% p( h) s& p! h. K                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding+ e- Z3 g! P; {; p
        }
$ h' H: f: v5 G  t        // FME74 ]: m3 x' b& E6 s
        if( exsound_select & 0x20 ) {# ^& g! W8 ~- Z% v/ ]
                fme7.LoadState( p );
' R" n- o- |; [9 |4 `                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding. o/ I2 ]7 d( }0 g4 s/ r
        }6 ~8 k' J0 P  P! b" M" X/ H
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 2 `+ ?2 h+ S+ K& n9 _' @7 [; h  |7 v" u
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
0 Z+ f, [4 t3 k' ]- g感激不尽~~

3 s, o* N0 J6 C7 L; ]( t, Y/ D恩 我對模擬器不是很有研究,
( y( C& R7 ?  K( D% `2 v3 w雖然要了解源碼內容,可能不是很困難,
6 t& @; f+ W; Z0 f# i4 ]不過還是要花時間,個人目前蠻忙碌的。
# _+ ]# r4 P8 e$ `7 `6 b
  y5 O9 `) E& I2 t  ^給你一個朋友的MSN,你可以跟他討論看看,
- c% J' M& ?1 Q他本身是程式設計師,也對FC模擬器很有興趣。
; L/ ^# P8 E0 ^: Y$ T
/ n0 i$ T) T+ a9 b+ ?* Z  ZMSN我就PM到你的信箱了。5 g: K* e. ?0 t; J! n. o- A/ j+ A
% f$ ]5 T$ X, s) ~
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
4 |+ X5 R$ g$ Z* F* [呵…… 谢过团长大人~~

" m) r! p" }  W7 d9 ~3 j" Q3 F0 ?
' h8 C! _3 D. j9 R# L哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 $ h( J2 ]9 j3 m1 p* m+ m
团长的朋友都是神,那团长就是神的boss。
6 a+ |. ]  d- n7 h5 X
哈 不敢當,我只是個平凡人,( r2 k) p" }4 t
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙  _& @. [( }3 Z+ m$ k8 A# ?6 b
ZYH
. J1 ^$ I  X: P8 xQQ:414734306
% R$ r7 u6 f) \- z3 A: g# ^* NMail:zyh-01@126.com
& z! f6 z8 X4 l/ W/ [
! N7 ], y: L; ^他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
0 {  g' [9 Z: J* Y& q! b% w再次对团长大人和悠悠哥的无私帮助表示感谢~~

8 J3 G2 W  Q* [不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-18 16:32 , Processed in 1.081054 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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