EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。: ]2 y2 d$ `7 W" D- D
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~# a" i: t- P. f" k# J# M/ i3 ]
这里有相应的模拟器源码,就当送给大侠了~~
1 G+ l2 t- `6 o8 S  n, e4 Qhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
; N8 Y1 d7 y$ z能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
" [! F7 g. E' t; }5 _3 ~7 n5 J楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
! D6 c7 ], x: S" D' c8 A; ^5 P) S# B这里有相应的模拟器源码,就当送给大侠 ...
8 B" e; k) j6 d9 o; W! B. j
聲音部分(Audoi Process Unit = APU):
  g0 P6 a5 v1 v.\NES\APU.cpp
2 h" C: t  T% k9 L; \7 ~2 D.\NES\APU.h
* P4 O# T! `# J* R' O) d8 ]; o! `# k& f% U& |) Q: M6 j

, t( V4 }2 o+ y/ R9 G7 L  l影像處理部份(Picture Processing Unit = PPU):" z. x9 G) r( ~& {6 N# G: Z
.\NES\PPU.cpp
1 T4 R% W$ o% i; G5 W.\NES\PPU.h
2 I7 W! U5 B% g  U- u* Q  h
4 a& x, u7 p' H# W+ Y' E2 m如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
$ _' s1 o8 n8 B1 I(由于很多专用术语和算法机理都不明白,所以看不大懂……)$ X: q) M1 H# U4 U8 _$ l+ \& _
//////////////////////////////////////////////////////////////////////////2 v. ]# z% Q/ z, O3 d$ X
//                                                                      //( z9 C5 f8 P% `$ P2 @' `5 c8 J6 J
//      NES APU core                                                    //9 i, m: u* j# h7 Q! D6 }
//                                                           Norix      //& H# u- ~) E, T7 D
//                                               written     2002/06/27 //
2 `; w$ _$ Y: y" C# `//                                               last modify ----/--/-- //) F% \! e' W( |. G; u
//////////////////////////////////////////////////////////////////////////; g. J" `6 r9 u* C% W
#include "DebugOut.h"
; |( |% K3 p% Q8 Y' U# E! u2 u#include "App.h"0 y9 I3 I( C4 _8 d9 y
#include "Config.h"3 e$ m6 u8 ]  l$ Z! H
) l8 q( c7 w5 f* h
#include "nes.h"
, z* e4 j3 v( w( \5 t, ~- @#include "mmu.h"
! J  b' S. S# q* i% J  Q#include "cpu.h"
" ]8 \# z$ A* e; A#include "ppu.h"4 R: `$ n0 h" g2 r( u
#include "rom.h"
8 b! t) m5 F: I- {+ i0 ~' {#include "apu.h"' S) W. S$ ~! o9 z( U# u3 Y- N* [6 @! p

! O, Y. H4 T/ [+ n& g. e) N: n! t' n* ]// Volume adjust0 K' o: `7 R, @" G9 B
// Internal sounds
3 L# B0 r% ]- A# d: T9 T- B#define        RECTANGLE_VOL        (0x0F0)- i4 n' N/ H+ S/ t
#define        TRIANGLE_VOL        (0x130)
, v2 e' b% E9 E" k( C) }* m; b( M0 G#define        NOISE_VOL        (0x0C0)
/ a  K  D3 o* A/ w3 s$ T#define        DPCM_VOL        (0x0F0)
6 l0 s+ f% u; Z# z4 K8 U: \9 Q// Extra sounds
; V" E# J! Z: [! E, `( }#define        VRC6_VOL        (0x0F0)- p! W; h! i) o8 t
#define        VRC7_VOL        (0x130)
2 P& m/ R* u. |1 D5 \) A- T#define        FDS_VOL                (0x0F0)
% S  b. y% G, H- V) ]5 H/ m#define        MMC5_VOL        (0x0F0)6 S1 C2 z7 `6 I! u
#define        N106_VOL        (0x088)/ P9 J7 f: ~: _# [" B
#define        FME7_VOL        (0x130)) g, L- E: z7 A; w& |: F

. t6 p% o) Z3 B+ V4 e6 }6 dAPU::APU( NES* parent ): I8 [: h: V) z. w
{  W4 P% t$ c7 v7 d, j1 \7 j( s
        exsound_select = 0;% p; s8 c8 v, l1 Q& R3 ]8 J+ b, L- k

  n" t! X4 a2 C. s. [! X4 i        nes = parent;# G% u$ y* b' i6 ~, h/ u/ c$ h
        internal.SetParent( parent );
' t  z5 V0 I' P" A& a
0 B" n1 ?% X& D' Q1 S        last_data = last_diff = 0;
/ \! F; [( J9 c; j' t% L4 Q0 z2 S$ c1 @8 I
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );7 p5 q; G- ]+ @6 n1 E8 u9 b) Y+ }7 z

# j$ j% I; r% q6 P; e3 @* z        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
6 [7 B! e$ Y) j# ~7 U3 i        ZEROMEMORY( &queue, sizeof(queue) );) c- p$ T! S! M  u0 W
        ZEROMEMORY( &exqueue, sizeof(exqueue) );  g- j! l* v7 V1 ?/ `8 E1 ?
2 D* h8 H& ?7 u4 w2 p7 r; Q* G
        for( INT i = 0; i < 16; i++ ) {
# {: i# Q$ Z+ n                m_bMute = TRUE;1 d$ }3 u5 S7 s6 p6 Z* F
        }3 u! s0 ~; d; q" b& O1 T
}( [' P0 W% @" E: p/ S( ]

6 ^& z, Q+ F& J% PAPU::~APU()
" B8 R' y" B& k* p6 c{
$ X/ r# D4 j3 m3 A5 u}4 t" i" ~9 C& f: T

  P/ s, {$ c' ?2 \( A9 a5 k, dvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
( o: ~5 F# s  b+ E, `5 r' D/ F, m1 R{
) A" e0 z. e% F! q  z& |  G& G        queue.data[queue.wrptr].time = writetime;
" W3 [6 l# x8 u0 V% V0 S        queue.data[queue.wrptr].addr = addr;
& o8 n) ]8 `) y- D2 c/ \        queue.data[queue.wrptr].data = data;; `4 U% D: M( f- _! H
        queue.wrptr++;
* e: [+ R9 \% H8 t- X        queue.wrptr&=QUEUE_LENGTH-1;4 B) j6 i! B  Y& I% G, {5 J
        if( queue.wrptr == queue.rdptr ) {8 j: w' X% O' Y2 n/ J/ C( y1 ^* h" p
                DEBUGOUT( "queue overflow.\n" );: t# i: _0 P& D
        }) Z# {3 U/ [1 X4 Z; B, p, W
}, u, N9 q3 y; j: m* b

- L* s% \4 B% G. ~BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )6 M  w% K5 k* f0 z3 K
{- v( T1 T. N. J( h4 e3 i9 H" |, M
        if( queue.wrptr == queue.rdptr ) {& W8 C- p" _, e6 q& O0 Y% m+ t9 h
                return        FALSE;
: H+ d0 @2 U: s7 V        }
, y& w1 \. Z3 b) v, j        if( queue.data[queue.rdptr].time <= writetime ) {
" z% [9 [( s4 X; v# x/ s% V9 o                ret = queue.data[queue.rdptr];9 {, I) A) ^* n+ k! W
                queue.rdptr++;
% K" |7 \( h2 p# _                queue.rdptr&=QUEUE_LENGTH-1;; a7 O& W$ x7 ?/ t! C1 a3 C* y
                return        TRUE;
' c+ ?6 k5 S5 ^; ~" h7 j4 p& Y        }
: Q' Y5 A1 z8 ^' q1 M        return        FALSE;
9 |0 p$ @% s4 q, j+ W) H9 M}7 N7 S; P! s4 U: x% Q

! `+ f/ h. r) D6 P# b( gvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
! Y& Y3 o  x) e( Z$ T' F{- G  J8 d- d/ H, X7 `
        exqueue.data[exqueue.wrptr].time = writetime;
# v6 v$ L7 U" V+ }+ j7 A        exqueue.data[exqueue.wrptr].addr = addr;  A* V0 i# `) m) U
        exqueue.data[exqueue.wrptr].data = data;% d1 l& ^& ]5 p6 u$ o
        exqueue.wrptr++;! D( C* R1 ?5 {/ ]! F
        exqueue.wrptr&=QUEUE_LENGTH-1;0 D: W: k. G, \5 ?1 a5 B- R
        if( exqueue.wrptr == exqueue.rdptr ) {5 e# l8 x0 w6 N3 w
                DEBUGOUT( "exqueue overflow.\n" );
% x( _) F6 v3 U# q  ^: v        }
6 y1 `2 }* D  c# [; e3 ]% t}
) V2 E* [. k* C3 p( N; b1 ?# s2 f+ [. k4 ]( Z' p! U
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )6 F$ j$ m# V; g# B8 _. [
{
. _6 w+ t' w$ L8 h* V  x6 c" Y; |, f        if( exqueue.wrptr == exqueue.rdptr ) {+ z! O8 y' W$ o6 }' r+ @1 {
                return        FALSE;
4 }* F7 C* g. D, J  j+ J: Z        }3 l7 N- N' d* P" g# o
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {2 ]3 w2 C1 ?; l7 V) |6 n
                ret = exqueue.data[exqueue.rdptr];
( U% a+ p7 `) L                exqueue.rdptr++;
: K3 P; ]" e  [" h  i* b4 Q                exqueue.rdptr&=QUEUE_LENGTH-1;( n5 }  k0 b5 V
                return        TRUE;
* E9 k7 l3 a# z8 V0 c        }
1 e8 N/ a8 V0 w, w# [' }. v        return        FALSE;
5 [* w- R6 e- r* T) x. Q}
' h$ _! [) v9 n( ^6 X3 l+ i" Q
' m2 r$ a. z" \  z4 A7 g4 Nvoid        APU::QueueClear()
7 x6 K* C. x' j% Y( h{* {2 o0 c! x3 U: n5 x! o9 E
        ZEROMEMORY( &queue, sizeof(queue) );# N$ F0 o5 v" _( B
        ZEROMEMORY( &exqueue, sizeof(exqueue) );  ~  ~" ^( d* ^7 L% @
}( p: I2 i5 Q4 f" c* \3 a1 C
* d) ]( A  Y' ~& P4 b
void        APU::QueueFlush()5 X  s3 s: b" k/ U* T
{# @$ o, ^1 a. i0 {
        while( queue.wrptr != queue.rdptr ) {1 f5 Q7 z9 w2 U2 E: i
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
+ R/ E- L# H2 x, O2 B$ G* d                queue.rdptr++;
* G9 F" a* K  \                queue.rdptr&=QUEUE_LENGTH-1;
* G9 d4 W; h3 ]1 q        }
$ {2 R2 f4 M. d9 o9 ~
- K5 ~5 V$ p8 h        while( exqueue.wrptr != exqueue.rdptr ) {* V& v% D/ n) ~* ]
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
! n9 z- Y* C1 G, _: V                exqueue.rdptr++;, j. w3 s# {2 M6 f1 S9 S) j
                exqueue.rdptr&=QUEUE_LENGTH-1;$ S- r) u& @' l6 ], w" V0 [
        }) E% ?. M: ~- h8 g
}
* c, a5 l8 u5 x9 D  E  t
+ r* A* d+ q: G" Jvoid        APU::SoundSetup()
0 q8 ^) q9 j6 |4 [+ q9 h! r{1 Q" e' q# Y$ h
        FLOAT        fClock = nes->nescfg->CpuClock;
# l4 W: c0 g2 Q5 s9 _2 H/ X        INT        nRate = (INT)Config.sound.nRate;. I6 z5 e" c+ s/ t5 ^: C
        internal.Setup( fClock, nRate );
  I% c" C% r  K; C% Z" O; C        vrc6.Setup( fClock, nRate );
. F5 z" F! O5 G+ Y        vrc7.Setup( fClock, nRate );
3 I) s6 ^: d$ S% ]        mmc5.Setup( fClock, nRate );
$ V6 Q! C: u" g& @        fds.Setup ( fClock, nRate );
0 j- f3 G4 d3 q( ]        n106.Setup( fClock, nRate );0 K, ^  h5 T- q8 ]
        fme7.Setup( fClock, nRate );6 g! j! p" F1 [; M2 U$ K
}
4 V- Q- R0 ^' f* j& C% f, R3 Z0 s
4 L5 q2 F* N7 b( |: U% `* H3 K, ~* i* Dvoid        APU::Reset()6 d& E5 s; l$ }8 c! P* n9 y
{
# P' O& }% y, O3 ^7 j        ZEROMEMORY( &queue, sizeof(queue) );! v, Z- Z: F8 W2 _6 J7 Y5 n  l
        ZEROMEMORY( &exqueue, sizeof(exqueue) );* C/ q/ {5 s0 W6 n

$ e" ]" G& O/ N; G7 G6 h: Y        elapsed_time = 0;: U5 ^; q; M* m$ T7 K: y
  x% h* {+ ^" z& U7 a$ @
        FLOAT        fClock = nes->nescfg->CpuClock;; h  _/ O* y( U, k
        INT        nRate = (INT)Config.sound.nRate;. A$ q* y  D. B! K
        internal.Reset( fClock, nRate );
4 c6 [4 T( S. f* B$ t        vrc6.Reset( fClock, nRate );
% Q, o" |- w. d5 q% A( K        vrc7.Reset( fClock, nRate );
; Z' h6 S' d7 T; Q6 _, n# @        mmc5.Reset( fClock, nRate );5 C$ _; E" J* |  [0 P+ @
        fds.Reset ( fClock, nRate );
" ]  W4 I, p5 z; I8 r0 |# R        n106.Reset( fClock, nRate );
. U( Q4 a, t" O' K4 ~: A+ U1 I2 a        fme7.Reset( fClock, nRate );
; j  X7 B. O+ B$ O9 k* Y2 o. M. C/ }! {  n) X9 s  \
        SoundSetup();& A8 Y- n) M) B9 d" `9 a( U3 g
}  U1 h' W- C- E! k9 [
$ r+ e) d- b7 Y+ a1 Z# [; _4 d& V
void        APU::SelectExSound( BYTE data )
- X$ [; y, [: _5 d{
! o1 O5 y& G4 K$ {. l0 R( y8 J3 q2 o        exsound_select = data;
( `! ?' P. ?, u( i. `/ q7 m}
% e, M& j( c7 W$ v0 H
- k/ u2 E2 h- F- a, A1 Q4 oBYTE        APU::Read( WORD addr )
. e# j  k/ [7 ]) a( ~3 {. Q{. ?! d, z/ V7 g/ ]" K- E+ m
        return        internal.SyncRead( addr );
( O! w) R% r% S# U}- `* ~( z1 T% ?" V- h

$ {2 m$ {& I0 J. k: C, svoid        APU::Write( WORD addr, BYTE data )
, M* K( a' m9 m" A2 @* x( v# n{
; x- l! K- w# {, \! @; c        // $4018偼VirtuaNES屌桳億乕僩* E% C2 y, S! K' K
        if( addr >= 0x4000 && addr <= 0x401F ) {
2 P" p  R$ r; M2 Z0 f                internal.SyncWrite( addr, data );
4 `- G" |$ [8 h6 C  j) F& n; s                SetQueue( nes->cpu->GetTotalCycles(), addr, data );7 z. Q2 t8 }  N: W. s2 C
        }
( ]7 v, _# k3 {( K}
: l+ Z, X# w2 K. x  E  h3 _& n1 N0 s. o, V- k+ ?9 r
BYTE        APU::ExRead( WORD addr )5 C& F& R9 G% B- T9 \: W
{: a. {8 Y) x0 |
BYTE        data = 0;
6 V( h3 t# {) s5 e8 g5 A- p0 e# u) v0 m
        if( exsound_select & 0x10 ) {  B0 T2 R0 E: P9 M/ A
                if( addr == 0x4800 ) {
# n5 M3 J- B( F8 D2 T                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );% D% v; d$ Q) L- p; @$ b% s2 F1 q
                }
( `  {, d4 n% Z5 D. r        }- ?5 _8 I" K. q, r  @
        if( exsound_select & 0x04 ) {5 S: K/ j8 }) D+ m- v/ \
                if( addr >= 0x4040 && addr < 0x4100 ) {
4 ^6 B$ V' \: Y$ X9 o% R6 ]                        data = fds.SyncRead( addr );+ W2 g6 Y* V* t9 n
                }- ?4 X( Q& b6 k, j6 D& u. R% r0 a
        }
! e8 i$ `$ i3 x8 T! H5 w, t! b! x        if( exsound_select & 0x08 ) {
# p) F1 o, p% \6 z; C                if( addr >= 0x5000 && addr <= 0x5015 ) {
. ]# ^; _2 k! d. @8 |. z! [                        data = mmc5.SyncRead( addr );& y  D; Y! H3 j* `. b
                }
, g2 y; L" A: Q        }
8 g: t" ^4 C( R- W
1 Y0 y# s0 v  ]  l        return        data;
1 f( V- D  ^: [: ?+ G}
- g( _. E* H# H" R* c9 a; T5 l1 F: N2 X4 B% ^! _' d4 R5 R* {
void        APU::ExWrite( WORD addr, BYTE data )* P: N, v8 Q. v
{
  W/ z2 d8 Y" Q3 |7 f        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
: a- J+ [8 N9 S; D7 C# m8 `+ S9 B
) _  \: T; n$ i) R1 s- I        if( exsound_select & 0x04 ) {
& J% x, y2 n8 n! Y; L0 ~                if( addr >= 0x4040 && addr < 0x4100 ) {
% t* ]0 T: u" v" b                        fds.SyncWrite( addr, data );* D& P: u7 S3 L/ n
                }
. P+ U4 p- n( d  u0 D        }% t9 q. d/ x0 r9 z

/ G9 }  D' _  y+ }        if( exsound_select & 0x08 ) {
7 T: [3 ~; ^& V7 M3 B9 r; U$ v% |                if( addr >= 0x5000 && addr <= 0x5015 ) {/ m8 {* A. _: W- ]# b) _3 j
                        mmc5.SyncWrite( addr, data );
' U) T/ ?+ Q# C( _                }
- b7 C3 v/ m& e8 e# z        }; {: O. G" ]' F3 M# i+ G7 n& \
}
5 k4 i' s# u' _
5 a" J. v6 H; G; S6 I9 jvoid        APU::Sync()" x. e9 Q, Y/ N5 x# m& V
{
, M* I) }5 |* r0 ^7 ]& ^$ C}' F8 {) s- ?( L

/ y* I3 y6 X4 J6 o1 Bvoid        APU::SyncDPCM( INT cycles )8 O, F; z' a! D7 D
{
4 Z# }# v# p0 o7 C        internal.Sync( cycles );
# I/ D; e$ I2 ]% r! \/ R
. Q* x2 w" q* h, R0 Q2 N, B        if( exsound_select & 0x04 ) {
( o0 e: s4 V, F4 R" Z3 |                fds.Sync( cycles );8 G9 p; Q# @  B6 U" ]3 {
        }# S) V5 r  C% N
        if( exsound_select & 0x08 ) {
5 a0 ^  b- N- ]& K3 z                mmc5.Sync( cycles );  M/ E5 Z) i: x: t7 T! U7 X% a
        }: B2 {; q) x3 a' |! T$ o, v
}. ?  f% V6 W6 S/ D; C

) P" T. r. a9 m: S. p  Ivoid        APU::WriteProcess( WORD addr, BYTE data )
4 b0 B) U, e/ M# j9 S! y2 B' Z& R{& `' {8 ]6 Q! X. X/ E' Z3 ~, J
        // $4018偼VirtuaNES屌桳億乕僩
) R) {4 w9 d( D6 L1 u6 \: _        if( addr >= 0x4000 && addr <= 0x401F ) {
. d( ^: F( ^" Q3 B                internal.Write( addr, data );2 k4 L# x4 ^8 j
        }
$ R  o. Q& B; x! p; E}
1 C- L4 G( s: J' Q% j
+ q! g/ l1 Y1 d% c4 Tvoid        APU::WriteExProcess( WORD addr, BYTE data )9 h3 x$ ]7 A9 ^5 P( @) Y+ s
{/ X, I# M! J7 F: {6 E5 a; Z1 N
        if( exsound_select & 0x01 ) {
6 H" R4 Y. ~# C7 f2 T0 O$ J* p                vrc6.Write( addr, data );
$ X& T- I; D' b' ~  h+ l/ W        }6 \2 W- |4 L5 Y
        if( exsound_select & 0x02 ) {
% _6 y5 e: B& v; c                vrc7.Write( addr, data );$ X, t2 j/ _$ F, z! j( ^& ]! M) B4 j
        }) x3 h. l& G9 L: N) A+ v, v( ]8 D' i
        if( exsound_select & 0x04 ) {
8 r. b$ ^# d! P% \1 g6 V                fds.Write( addr, data );2 O: B+ q- q/ J. ~7 I- f: L3 B
        }
% N# R3 \3 k. G3 u0 n        if( exsound_select & 0x08 ) {! X) U  S; t/ h( ]& g
                mmc5.Write( addr, data );/ x* X) B8 L) M% f- ?
        }  v. n$ T6 Y4 g
        if( exsound_select & 0x10 ) {
) k3 V9 G, w2 F7 l                if( addr == 0x0000 ) {2 U  v2 V1 d# H! O) f: V0 e
                        BYTE        dummy = n106.Read( addr );
; l: i' p7 l& L( Z7 C4 k. O/ I2 Q' j                } else {
) {) G1 b5 R1 `, W/ q2 h1 L1 [                        n106.Write( addr, data );
+ l; @; c1 O1 ^$ k                }
3 a; j. W8 i% j7 I        }
" [, ^* \3 t2 y. J+ C6 S        if( exsound_select & 0x20 ) {
: D* X. Y/ G# G) z* f                fme7.Write( addr, data );
: Q; V% c( }# R2 P: [' E: F8 ]        }
8 P! f+ g7 B/ q6 r! Z3 r}
; d3 w9 ?5 _. |# {+ T, ]. E! |5 t: X: t0 Z4 t, |! _& o! n
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
; r4 l- s  J1 f/ Y0 s) Z{# s" C3 m0 y2 J. q+ _  x- _
INT        nBits = Config.sound.nBits;
! C/ [* H+ D7 RDWORD        dwLength = dwSize / (nBits/8);) p, v9 I$ }9 n! W- r
INT        output;
8 T+ Y  N- M/ P6 EQUEUEDATA q;
4 o' U" v- y8 O& u. n8 w  D6 S' BDWORD        writetime;+ u; `/ d( n# M9 H3 \( d

# `  H, @9 b8 z5 c: ?LPSHORT        pSoundBuf = m_SoundBuffer;( ~+ P, Y5 V* O" N* ]1 |0 [
INT        nCcount = 0;8 U5 o$ Z1 P+ Z6 g/ `5 e

% {* P' `9 b; Z- L- dINT        nFilterType = Config.sound.nFilterType;
3 s! o4 I2 M, ~7 r/ l, u$ K8 A$ B9 m6 D
        if( !Config.sound.bEnable ) {
4 i" A( o, e* b! L1 U! b3 A/ \                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
' c" T, l  @. L. A& u/ s                return;
" n: g# m$ d2 [! J        }& n5 C( q+ [+ u  N3 m8 P& p

# e; l+ Z5 x8 b        // Volume setup
" q+ m! |4 _0 I* N  N        //  0:Master
& q8 }6 U; }( S+ L. _  G        //  1:Rectangle 1: @" L9 \1 U( Q( [
        //  2:Rectangle 2+ j3 S5 u* c. B! x
        //  3:Triangle: ?: G1 `0 z3 S7 i
        //  4:Noise
/ ]$ o! i. W. u; T* ]& l        //  5:DPCM
( n' m$ x1 h$ w% D2 P/ _+ b        //  6:VRC6+ P+ V0 b/ t. s$ H: I
        //  7:VRC7. h9 s9 K5 g: O7 O
        //  8:FDS
$ k5 g9 Z7 Q* W: Z        //  9:MMC5
  v# G* U4 H; y) `( _' A        // 10:N106  G+ r8 w6 v1 \. |6 d
        // 11:FME72 h3 m0 V: Y' _: O- O
        INT        vol[24];
+ F. Y4 k4 M9 P0 f: U. ?        BOOL*        bMute = m_bMute;9 M( e6 v, V, M, g. Y
        SHORT*        nVolume = Config.sound.nVolume;5 t3 M9 o6 J5 B' C6 u3 Y; t

! K" i# @8 h9 s7 r& a5 }        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
6 y" Q  Y$ j8 m* N5 g' k9 u# g7 U: N
        // Internal
) q3 c4 [& K8 Q* ?# P4 |. H9 S, ?3 C        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;+ L' {+ G9 i& C/ [
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
3 W, T- Q* j* W        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
7 X6 C/ x+ c( Z# D8 c- I        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;. H9 J3 ~+ O, K6 @3 X( o
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
: ^- I7 Z3 Y* ]! b. v$ L( m
) L( i, w, L( f# U# x. A        // VRC6
- O1 b$ n' _  L  W  ~) ?        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;2 u* k+ T1 u# y6 H% _
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;6 r! @  i& A. Y
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
6 B% r( E! d3 A% C0 Q9 @, W* I
% X+ l2 |. q5 _$ N# i        // VRC7. w2 a. f% [, o- s" X* X# O1 \
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
' d1 |% h) a! S' O3 U. |: B6 X' }! D4 m+ U* R
        // FDS$ ~0 R: O" h: }3 V; I: r$ p4 z
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;; Q, K) T, p$ c: ]2 v

0 w- }# x3 U  m/ C        // MMC50 a; w3 i. @5 P4 x/ u. V
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;# M2 b8 ]) w3 b, O6 W
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;$ d3 G$ G# x  E" X5 E
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
7 w5 U# I: q, ~7 e4 Z
1 g( ]+ B3 t( R1 x9 B6 H8 Y        // N106
4 K. S. ^; D/ D7 l* x) D2 D, I        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. C9 [  O* m4 J; c* n) L        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;5 `+ X; t& e7 M/ l* A5 o3 V
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- G/ W4 o( r0 K. w3 L
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;2 V9 L9 G$ q$ \- M0 a
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
9 I% g& p) P: n$ l1 o- D        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;1 X2 P) [7 B7 @2 M
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. o* @! }( `7 H        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- v5 P4 H  t; k- ?
* ?: L2 H2 R7 z3 n4 S" C5 p
        // FME7
- S2 O7 n8 g! e, k9 f4 A        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
6 V2 V  b0 c2 R        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
2 f9 Z  A- P4 M$ B" C( s4 m6 a        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;+ l4 y7 v- M3 J  O; D

; O8 `4 e$ a0 w* j//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;0 r( u4 N# d  ?5 B
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
7 t/ ]# `4 l) `( B: Q+ I8 _5 ?7 t( ~; O! L2 ]! i# X$ s
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
0 M0 g9 U! D* i$ d        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
- X, D1 b' W: }                QueueFlush();8 X+ a+ J* A! L# ]
        }
0 m- s# e1 O' h& H
+ |6 k: O7 D: G        while( dwLength-- ) {
+ p! V6 T4 B, J- f                writetime = (DWORD)elapsed_time;
' b, ?) X9 v+ M  O  G2 X
, @! C2 r' N8 C( i; h* {) \+ _( l                while( GetQueue( writetime, q ) ) {! Z& T9 M, _' w& p3 }% D% _6 W
                        WriteProcess( q.addr, q.data );
: E; m8 T7 W; z9 S# O! O3 {% a                }
" I# M& d8 t2 a4 ~9 M
5 _. i( X, r+ R/ t1 J/ d                while( GetExQueue( writetime, q ) ) {
4 J* J6 t5 [* r: T                        WriteExProcess( q.addr, q.data );9 l# y. T: {: O$ u% x' E) W
                }% m& o6 @; S/ k; g6 q
1 O$ y* W& o1 {/ t4 Z5 ?( R5 E
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7, W& L  \  u8 y9 W$ c% `4 v4 T
                output = 0;8 P8 ^6 n* v, n8 O! i4 T4 m
                output += internal.Process( 0 )*vol[0];
. r4 x. I8 ]$ |                output += internal.Process( 1 )*vol[1];
- [( w0 c$ q, {, V: j+ O4 r' D0 E; b                output += internal.Process( 2 )*vol[2];3 ~& `  a) g" H, e4 Y' Q( U6 c
                output += internal.Process( 3 )*vol[3];9 F' X  S4 I5 g# t0 m2 K: J
                output += internal.Process( 4 )*vol[4];2 w4 K# K: Y# y2 a2 ]; b
- R9 U! F& a- n6 _. q
                if( exsound_select & 0x01 ) {  {, x( r4 I2 K5 y6 B
                        output += vrc6.Process( 0 )*vol[5];  M+ _) i/ |7 q, j0 @
                        output += vrc6.Process( 1 )*vol[6];
- x. @6 A: V. n6 q3 b                        output += vrc6.Process( 2 )*vol[7];
9 O- O- a3 C) S5 O6 }' C                }) D% c9 ~+ T& D! u" a+ K
                if( exsound_select & 0x02 ) {) s' U( i4 ^# i/ v% ?6 ]) P
                        output += vrc7.Process( 0 )*vol[8];# N8 s9 v. s& t7 n% p
                }
9 [! [3 w6 G3 U6 B! T                if( exsound_select & 0x04 ) {
4 n, I( Y$ W/ D' n8 B6 L5 {% o                        output += fds.Process( 0 )*vol[9];
5 O; E% e5 Q1 ~3 g/ g                }5 w# d! K1 {" O' t: @+ Z% g
                if( exsound_select & 0x08 ) {* Z* `! W( j' q2 n0 ~
                        output += mmc5.Process( 0 )*vol[10];
! G$ s+ F; m9 b+ i! I9 y  O3 x9 D* H9 Q                        output += mmc5.Process( 1 )*vol[11];
1 D9 e/ L6 D0 C- g+ j7 V                        output += mmc5.Process( 2 )*vol[12];
3 h( A7 ~! a* {  Q; p                }
% _$ J3 b, P2 k. j* |9 R                if( exsound_select & 0x10 ) {7 H4 M$ b0 y- f( W. @
                        output += n106.Process( 0 )*vol[13];) h3 s, q" S0 T) G' e/ I" T
                        output += n106.Process( 1 )*vol[14];- [/ R% q+ W  A: l
                        output += n106.Process( 2 )*vol[15];5 C9 o7 i- e6 O- e
                        output += n106.Process( 3 )*vol[16];
- |8 E: ]3 P2 D* U  K                        output += n106.Process( 4 )*vol[17];4 I' }( b% m  q! Q: w
                        output += n106.Process( 5 )*vol[18];
5 ]1 a; v  Y+ F                        output += n106.Process( 6 )*vol[19];
3 U& r+ }/ j, J2 _* s! x  H                        output += n106.Process( 7 )*vol[20];
6 _! P" C: m3 e! d  L                }
% M' [% R: @6 I6 ~) G5 G! c/ D                if( exsound_select & 0x20 ) {
# |: Q6 [% f. D) |. C2 @  |9 |                        fme7.Process( 3 );        // Envelope & Noise' l# ?/ E- {1 m: T& y( E/ ]0 g
                        output += fme7.Process( 0 )*vol[21];
+ w& k  j4 N1 e5 J% E                        output += fme7.Process( 1 )*vol[22];8 Q: _3 [7 y/ J+ y% t4 C
                        output += fme7.Process( 2 )*vol[23];
3 l+ Z! C+ Q- U( I' z                }
: O0 @3 t% V; |9 z  k' n: S2 P9 ?+ P' }$ v* i* k- X: D6 E8 _
                output >>= 8;; b! D5 x4 }2 Q+ T, q! I/ o' O
/ N& s, U/ f2 X7 i* i
                if( nFilterType == 1 ) {8 g. ?+ Y: O+ b
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)6 b$ M. r4 [. h9 h
                        output = (lowpass_filter[0]+output)/2;
) p# Z/ O4 W7 A" _( a  T                        lowpass_filter[0] = output;
% }! D% `1 r3 M0 b0 T3 D( \                } else if( nFilterType == 2 ) {' J; L* P% s9 L
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)/ ]) w( Q# w/ c
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
; f- S: D8 p( J                        lowpass_filter[1] = lowpass_filter[0];
, n: X; @  ^9 u' z2 Q6 Y5 K                        lowpass_filter[0] = output;9 F  r8 D4 j: [+ ]4 U
                } else if( nFilterType == 3 ) {
- W( P! v# @4 |* }6 H8 v                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)7 G1 C; T9 G# P( \
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;) U7 H+ ~9 f) A/ [
                        lowpass_filter[2] = lowpass_filter[1];
! Y5 t/ Y5 O8 e9 h( ~8 Y5 F1 C! j9 `                        lowpass_filter[1] = lowpass_filter[0];
3 j5 ^- w1 `& L' a                        lowpass_filter[0] = output;
+ a0 |+ S; a' T' z9 b1 ]/ _                } else if( nFilterType == 4 ) {
' W9 |4 v" h, a                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
7 _) z' f2 r& _+ y: q! W2 }                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;6 q& ~$ t2 f; ]
                        lowpass_filter[1] = lowpass_filter[0];  L# c# b) I: ^% e2 u
                        lowpass_filter[0] = output;8 X9 \2 d) v, w% H) a7 E
                }
/ L" `" A* A) ]* S) x7 i3 U; N! f( @) N+ y; `
#if        0
# }: Q: _) \* \& }                // DC惉暘偺僇僢僩
* B, S0 E- P' H2 f2 C# i$ k                {
9 G3 w" r% c0 @! E7 Y                static double ave = 0.0, max=0.0, min=0.0;
( Y+ q9 p& Y# J3 [                double delta;  k. T) z* g2 l  b
                delta = (max-min)/32768.0;
( r2 X% y/ v2 l5 H                max -= delta;
# W) N6 X1 h+ Y1 K3 A, u9 D, ?                min += delta;
$ G6 P# ]( x1 \. R                if( output > max ) max = output;2 x  i' C9 z* y+ ]- o( Q- {
                if( output < min ) min = output;
  V/ u( G/ R+ j# g7 U0 D                ave -= ave/1024.0;
6 m* [. q( c7 ?1 }% s+ d                ave += (max+min)/2048.0;
& L* j3 b0 J7 _2 A5 T                output -= (INT)ave;
6 g$ C9 q2 T9 [5 l                }3 S( w! P* n* B
#endif$ }/ p. b$ w/ X6 Q- s
#if        1
6 l# m" ^$ {$ K6 |% j                // DC惉暘偺僇僢僩(HPF TEST)
6 q( D/ Z# }0 J5 i                {9 ~; K( u, k" U& u
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
& P0 T; e/ l: {* n9 z5 @! W                static        double        cutofftemp = (2.0*3.141592653579*40.0);6 _6 t8 M9 P9 R7 _) t" m! y# ^
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
4 t* r& m; ^9 `3 C: H+ B                static        double        tmp = 0.0;
% [. n1 ^2 N7 e                double        in, out;$ f- x+ I, N. \

8 T8 ]& C! i9 r                in = (double)output;8 }% {8 j6 K9 ^& n/ l2 J
                out = (in - tmp);9 x# V9 d! X! x3 `% H9 I) x, T5 c! w
                tmp = tmp + cutoff * out;
: m9 ~# E' w  o& c1 S: c& X1 p' B
5 w2 P4 Z6 I& Q) v7 U1 W/ D! X                output = (INT)out;
; p4 j0 m7 ]4 z9 b7 R                }
& ~0 |) Y/ g3 h5 j7 P7 |#endif) m4 ~4 o. d6 s2 @2 d8 D
#if        0
3 L9 G6 `" N( N/ Q0 o0 r                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)$ [5 L- t# f9 d, E% z+ ~
                {
( }5 }( m0 j8 a3 s                INT        diff = abs(output-last_data);
/ y: p$ }0 V+ S1 D                if( diff > 0x4000 ) {
' y& @/ S1 m, \: t  g                        output /= 4;
( G/ K  e- b2 w1 ^" B                } else 4 O0 d0 o6 G! t0 m3 F. j
                if( diff > 0x3000 ) {; e8 g9 o6 Z0 B: J$ z. U. n
                        output /= 3;: o* }% m* Q/ ]7 u) e1 F
                } else' P; `8 n  A  U- C3 m: ^
                if( diff > 0x2000 ) {
: W  b" h& c4 y8 B# |1 E                        output /= 2;5 O1 R$ j- o: D; `9 E6 l! ?  D% z
                }
& f( p0 p  `: Y; x                last_data = output;/ V7 s' [# g- ?# T( X3 ^/ ~* `
                }/ {: `+ x6 h4 q. K; z1 D' ~1 r; H7 p
#endif
; ^$ `8 _1 Y) Q; Y# V+ L! ^                // Limit
& c  w1 {" W, J1 G: J0 o                if( output > 0x7FFF ) {
6 h& e2 C0 L' L4 u8 o- x0 J) s                        output = 0x7FFF;' T" X: o& W. \1 v: U
                } else if( output < -0x8000 ) {# w- j3 J0 x& A; \5 T* d# c3 ]
                        output = -0x8000;
5 c0 Q( M# s# E3 o8 k& k                }$ |1 @4 R3 j# I/ {" ]. c0 s

" p  J1 V- u3 |# d; A$ p% P                if( nBits != 8 ) {1 i& g4 x0 l6 n8 M% @+ s9 F0 z
                        *(SHORT*)lpBuffer = (SHORT)output;
7 s- T* p' }, x                        lpBuffer += sizeof(SHORT);
  n% r$ C  \# W                } else {
9 {" ?2 J7 [# P+ J6 C' S2 v                        *lpBuffer++ = (output>>8)^0x80;
' M, I# k5 n! h6 P; b6 q+ F9 O                }5 J/ J- n+ y( _* U
' ^% s7 s$ g3 w% q
                if( nCcount < 0x0100 )
7 r) C( v! X: |                        pSoundBuf[nCcount++] = (SHORT)output;; Q5 u" X( T/ ]- q7 J
6 Y# V- }+ p7 l2 Z: H
//                elapsedtime += cycle_rate;
. U: N, Z: ^2 @; X! W' X                elapsed_time += cycle_rate;
2 Q8 e* {- q5 W: o        }1 U& x: G, l, a; M2 o
# _3 G5 ^0 F* ~: X/ I7 [
#if        1
7 ^6 j0 D+ c( }& c        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
! V5 f2 Z9 d3 i2 [, y/ n. M* G                elapsed_time = nes->cpu->GetTotalCycles();
1 A8 w  V/ t* @        }
5 W* k  d9 A2 ^! W: B' e3 i        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
+ {+ f  k  y' _/ `* B- W* m                elapsed_time = nes->cpu->GetTotalCycles();
( P/ R- y  m: h% e; [/ A        }( C( O" \( E. e/ Z5 a. w6 i
#else3 f& N1 d* ^  A* J+ m
        elapsed_time = nes->cpu->GetTotalCycles();% p' O5 ~+ l8 O% `. t# {
#endif
  B" W$ y# X! n2 Z1 g}0 `; p" F, K/ x, N0 M

! X$ V0 b4 C9 G' K% S// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)7 c* X% ~, H# ]& U5 S
INT        APU::GetChannelFrequency( INT no )/ s: ~5 O( X; t  K" J
{
' U: v# P: Q7 X        if( !m_bMute[0] )9 r+ F% w7 u5 {& V' G4 A
                return        0;: Y7 k  A" A! r0 e2 e, p! Z% s0 l
' m7 s! w5 k$ g. C" y# _) e
        // Internal# |; {, V- h" }7 \
        if( no < 5 ) {
7 S1 ?9 M! n+ K; I% m6 e                return        m_bMute[no+1]?internal.GetFreq( no ):0;
- C. o4 J0 G# s: S/ @7 p$ i        }
6 A" ~$ E6 m4 F        // VRC66 u; x8 K: W: X: }4 q9 O
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {- y2 ]& `1 M% A3 \9 m( \
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
9 j3 Q* M+ _3 P8 o9 B. L; K        }
) P7 Y0 c& I0 \. x; M; y" T        // FDS8 E) B, S5 d2 u  ]
        if( (exsound_select & 0x04) && no == 0x300 ) {
& f. E4 R; F! _6 @. T9 v                return        m_bMute[6]?fds.GetFreq( 0 ):0;
  V4 N& I7 Q5 G% `% a5 u        }' a$ Q* O8 y7 ^, [) V$ r5 G  o
        // MMC5
7 I( H4 m3 v7 q: Z2 g! k7 U9 `        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {& E0 x3 R* _* J: z; r8 d& N
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
; ~9 r0 j. |5 ~( h+ ]1 B+ {- A: {( l1 b6 W        }
. l# s6 x( f( E8 p. l3 e$ Y5 ^        // N106
; h3 ^4 n& O' k  l+ O# r        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
4 M1 s# C5 @3 u4 V8 i                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;" a* W/ d: I# w/ t7 y0 p
        }
( x9 ^/ ^# S7 \% N# g        // FME7% t; Z# x% E7 G+ h* i  D
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {4 h9 {( v& K/ y1 D9 }
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;! b. y4 L0 m8 ^. U
        }
+ a( Z) e0 Y' d6 z- A6 y: y        // VRC7; W" K, i# T7 m. Z' o: O$ H
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {; o) S: V+ V$ _3 V
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;/ ]# M1 Y% S8 n$ K+ m4 F
        }
: ^' L5 O- W$ {/ S        return        0;4 Q9 z5 I8 l9 l- M4 s* {
}
% x1 V1 R/ ?8 u: }$ q4 T! Y: }: d' y; z4 k9 g/ b
// State Save/Load
( \9 e) L: y' U& J! U2 ^void        APU::SaveState( LPBYTE p )8 I) c9 C* O2 I1 B- X! M$ @" X9 g
{6 p% c6 f7 H7 t9 m
#ifdef        _DEBUG
4 q6 V+ A) E9 N. ]8 U  xLPBYTE        pold = p;; }" N7 I/ b- h* p
#endif% e  h5 j) \3 P' O/ \4 \
( ]* _# n. V0 n+ {( J0 _" O  @. X
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
5 N+ h5 w& ]6 S        QueueFlush();
' x2 ]& [2 R+ f; a( z; f# |5 \! |" _/ @, L0 o- A; P5 A2 _
        internal.SaveState( p );/ r& ]. x2 B& t
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding. A' O( s% l0 V5 G# g

  {6 @; A9 z" u4 m2 r& V& Q        // VRC69 M# {  A# s9 h
        if( exsound_select & 0x01 ) {" B* M+ Z3 w0 x# A( J
                vrc6.SaveState( p );+ D5 h. d7 f' A! o7 F1 e, Y
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding) S5 d% @5 z5 P' o% L
        }
5 r$ j4 Z4 M4 H) i9 B/ W        // VRC7 (not support)! N- u7 p- M# f3 M# ]) |1 s: W
        if( exsound_select & 0x02 ) {
5 z5 {. n  c) V                vrc7.SaveState( p );
. f2 Q, c& e" _+ z1 O                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
9 J: n# M5 H' l% n        }
  A% w3 s: q- |- J- U7 h! K6 h        // FDS
  r- F# n" h( @. g/ H1 U  V        if( exsound_select & 0x04 ) {8 v2 d) y) V. T- t  f2 L
                fds.SaveState( p );
/ r  y, U6 {! I6 ]                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
  @$ t6 v8 o' s        }
' z' k) n) c" c# u* T2 B        // MMC57 {9 f- p  c. B8 \
        if( exsound_select & 0x08 ) {
: [( ?3 Z( r* b4 ]                mmc5.SaveState( p );3 E. Q. a" G- F* x3 M  M5 W
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
! v! K. n% H& k        }
4 b  d3 u% ~% w6 |. b) H        // N106
% [0 V7 O* v0 |4 t6 N6 z/ l4 B        if( exsound_select & 0x10 ) {! x: H4 \( ~7 y- Y
                n106.SaveState( p );7 H( j: L6 E% Y  e; G5 a
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding6 \: g$ s( K2 V& f: ]( q
        }
! `  w$ p4 K; a  E6 V, ]5 H6 i1 I        // FME7, B) o8 t4 C3 M+ B: A! [  W
        if( exsound_select & 0x20 ) {( C* ~0 \3 z. [8 S6 F# g% a0 H: T9 [
                fme7.SaveState( p );
7 @# R; a1 A5 W0 w. c; Q                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
1 u6 r4 d6 a8 m+ ~# X6 o& x4 U        }; a6 u2 S, G5 f

  X* q% J. r6 }* }0 m! f#ifdef        _DEBUG1 c8 f) s2 p# X, G6 Q1 r
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );) T! p3 m; ]' y% V% _3 I
#endif
& x: P  `% R8 J. m/ `# x. A% e9 s5 i+ o}
5 z1 @& [, [1 H3 |+ Y! ]4 s( P7 U6 f
void        APU::LoadState( LPBYTE p )
* `) D+ e! L  P6 Y7 s8 s{
! u) s! l* R+ n: Y        // 帪娫幉傪摨婜偝偣傞堊偵徚偡( T# k  s1 Y" J2 T
        QueueClear();- F0 Z9 {  x2 z+ l" A  i
& m, Z: D3 @/ R( K' b' ?2 w
        internal.LoadState( p );& o% y9 M3 @+ \: O7 u, ?
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding/ e9 w9 D0 |7 |- d- D
- R- y6 I# r5 T/ F, S
        // VRC6
  {( J3 M1 N7 y+ P$ e8 Q% E        if( exsound_select & 0x01 ) {' y  T2 e- g9 o* t# u
                vrc6.LoadState( p );1 I; k8 {' S  t/ M& A
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding6 R& p3 K  C# S  h
        }
; W2 E$ N2 J) k        // VRC7 (not support)9 y4 x; U# `& n: M+ V! h
        if( exsound_select & 0x02 ) {
3 C4 u" {% u2 F) P/ r; `3 i4 Q. S                vrc7.LoadState( p );" p  m% l5 Q5 f- h$ ~( X7 b* P% T
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding' I# j% V" X0 P7 H: k
        }( W" v2 G4 ?) ]  N* R8 T1 M
        // FDS& S* R$ k3 r" Q
        if( exsound_select & 0x04 ) {! B3 t  h6 S0 k6 L
                fds.LoadState( p );: h8 ^7 d2 n# y
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding  q0 j& m! Z5 f+ [/ x
        }
# U0 t% ~% l5 k7 _6 b. ^' I        // MMC5: z7 j" l3 u8 j$ g' O- g
        if( exsound_select & 0x08 ) {* P, l' V# t  _& y7 \" `+ Z
                mmc5.LoadState( p );7 c& r, b; B2 U' u, w- a
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
5 k# B9 A7 _- O% w- |4 q. Z& C. I        }
8 g1 A: _8 _. \; ]        // N106
9 S, @& ~- Y8 U: a4 }- L        if( exsound_select & 0x10 ) {, J. x" j. c; w) ?3 N6 a& b
                n106.LoadState( p );
1 \# u) t) g, b. x, f" m% U                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding6 Y( T" H; ]) {$ u* k
        }" M# z+ {* [5 t+ R; v/ y
        // FME7
$ O, v8 N, X$ E/ ]3 T- {- i) G        if( exsound_select & 0x20 ) {5 \4 `( K$ o6 X$ B
                fme7.LoadState( p );
8 T6 H) l( s1 [. s3 f# ^& x( {/ J# m                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding6 X: x, a/ e" I2 V
        }
$ A, C) S5 [; Q& E' d3 J% a}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 8 K0 I' D$ r! ^. S
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。& ^8 C" [3 A9 x# {8 a2 x3 ?
感激不尽~~
# Z/ z. G7 K: D7 R/ z1 F" ]2 b* x- Z
恩 我對模擬器不是很有研究,* D# x; c6 ]3 v  D
雖然要了解源碼內容,可能不是很困難,
5 Y' U, {: Z& [9 _1 i不過還是要花時間,個人目前蠻忙碌的。  @& M1 t/ X. F& o8 o* ~
: N& p# s8 W1 a; S8 ^
給你一個朋友的MSN,你可以跟他討論看看,
$ f2 `7 x. S. n( V他本身是程式設計師,也對FC模擬器很有興趣。
6 t9 f" b; l, x( V/ Z- V5 E) Y2 {
. e- T8 f# b$ l" m# x& ]$ eMSN我就PM到你的信箱了。
/ R8 P( `. d/ v6 |4 I# _. e
7 w8 W3 o9 w$ l4 ]: N' v希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 . T/ H; H- W' z' _1 q
呵…… 谢过团长大人~~

& ~9 H. e$ k5 A, d8 U: Z3 x% t; }. w9 t
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
( y4 t$ {, E2 H- K' @团长的朋友都是神,那团长就是神的boss。
2 B; a: q. F) B. h& s
哈 不敢當,我只是個平凡人,
8 n8 Q& W  k+ k" i8 M2 s5 a要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙. G1 B/ S$ J4 ]4 ?5 }
ZYH
0 `. T7 x: o7 [7 q' }QQ:414734306
; X3 n: Y$ H8 E5 h1 ~Mail:zyh-01@126.com3 b/ D$ `6 H9 [4 g+ y/ X
, z1 l# q  C* t# Q- o
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
( A7 W: L0 B- T' ]! {( }" @再次对团长大人和悠悠哥的无私帮助表示感谢~~
7 q, s/ b& H( U' \% p$ O
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-7 15:30 , Processed in 1.118164 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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