EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
% O! m! Y: q7 M  u. v楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
3 Z! O" v, a* C9 Q1 e这里有相应的模拟器源码,就当送给大侠了~~! ?' g$ S* H$ _# L) v2 A* V
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
+ ], |- {0 L6 D% b) K' {4 @能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
; o$ I8 ?: j2 H/ X/ x  o" y! p楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~0 v! d1 A$ C( V0 R5 p0 |
这里有相应的模拟器源码,就当送给大侠 ...
* l" N  m: a6 R8 e! N) K
聲音部分(Audoi Process Unit = APU):
3 B4 {+ q% \9 Q8 c/ {) b.\NES\APU.cpp+ e6 i- N1 {# R3 E( q( d; h' o
.\NES\APU.h, `/ H. T  W- r$ Q

4 f1 s# t0 k7 L2 X7 X; H  |' K9 ~
影像處理部份(Picture Processing Unit = PPU):
3 f& K  S8 Y& C% T! ?$ d; x' T! A.\NES\PPU.cpp
  U; Z8 }! T9 A/ A# H$ p& @.\NES\PPU.h5 q. W2 l/ {. B. t. j4 C+ F
4 Y7 F4 w! u- b2 @
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
% r/ q5 G2 \( o( \(由于很多专用术语和算法机理都不明白,所以看不大懂……)
+ \5 q1 z8 W7 K3 Y' Y1 n7 M- C2 C. M//////////////////////////////////////////////////////////////////////////7 F3 o# c$ ~7 @3 M  O. N
//                                                                      //* @& f0 d0 l9 ]' @% [
//      NES APU core                                                    //9 x; h6 ]* m7 D9 m6 f1 u$ c- X8 t
//                                                           Norix      //
7 Z) {, i! u, w* x+ [//                                               written     2002/06/27 //9 n1 s. I9 s: a$ ^0 }
//                                               last modify ----/--/-- //% P9 Y, ?* L  w; ]$ L* x
//////////////////////////////////////////////////////////////////////////
: v* |8 @2 q0 [  t1 d. L#include "DebugOut.h"( O- Q* m, ^2 C( ~& m) W) L9 ]/ ^
#include "App.h"
% [: f) `3 W& w& H4 ?  \#include "Config.h", o6 m4 e: l$ F

6 F! y  g3 S1 I  x9 ~; @#include "nes.h"
, W( ^6 {4 C) [! Z#include "mmu.h"
% H% g3 C  ?2 K#include "cpu.h"# B5 @9 E! ~7 s* b
#include "ppu.h"
6 W+ p/ M9 t. y#include "rom.h"$ V" o% H! t/ B. X
#include "apu.h"
% |, Y# S: E+ i& l3 z) F
, X- \* D+ U/ \! J# H4 l, z// Volume adjust# X+ |7 x$ a6 q7 s) |$ I
// Internal sounds
% |. {, f% ?: v1 D3 S, n#define        RECTANGLE_VOL        (0x0F0)
) {# e/ |; \4 W5 j: {. q" L- _#define        TRIANGLE_VOL        (0x130)0 q; U* j& q1 ?" k
#define        NOISE_VOL        (0x0C0)0 y4 E# h# O% B7 N
#define        DPCM_VOL        (0x0F0)
* z$ ]; S) e/ L6 v. ?+ H3 D7 G6 \// Extra sounds
8 G% x- l7 E5 q0 f; T' T5 p#define        VRC6_VOL        (0x0F0)
$ g% J' e1 X" M  u: I2 e$ C#define        VRC7_VOL        (0x130)
) S& g' E2 [4 [#define        FDS_VOL                (0x0F0)8 B2 H7 @& k. J6 U/ s
#define        MMC5_VOL        (0x0F0)
9 A: X/ S! ]: x7 ?#define        N106_VOL        (0x088)+ J4 r; p8 [8 v* o9 K/ i
#define        FME7_VOL        (0x130)1 f! ]& W, Z% t4 R' z6 y' v! U& B
6 U; X8 `7 `) y2 k- ]7 [% k4 ?/ M! S
APU::APU( NES* parent )
! ?- H. [  H; S3 v3 z{
  ]1 n: `) s8 z5 S        exsound_select = 0;5 ?) Z. P) _3 q$ [

( K5 `( A' f: B) v$ ~( s        nes = parent;
+ e% I4 @, O2 i, E1 _        internal.SetParent( parent );( K% j7 {- D1 n/ x) Q' [
. X7 P& A0 y2 F6 Y0 X5 ^' U
        last_data = last_diff = 0;
( l. E; ]" v# P' l- {0 x  ?8 U: U4 ~8 |4 w) l3 y
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );2 W- i# S. P5 z5 Z: U
8 ~) Q" h& c! T$ X$ z
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
, E# k* [! f0 B7 _/ F7 g9 i        ZEROMEMORY( &queue, sizeof(queue) );* F* T+ V- v) n, [7 N/ x0 X
        ZEROMEMORY( &exqueue, sizeof(exqueue) );4 U6 m6 }2 f: J. Y) w2 y

. Y7 a* U# z2 v% k) ^        for( INT i = 0; i < 16; i++ ) {1 W) o% m1 l9 g1 Y$ o$ v) e
                m_bMute = TRUE;
  s# |+ J+ S: V        }9 P9 Q2 O5 b, _  o. w/ v6 B
}
2 a. [8 V$ c% j: R/ t
5 ~! t1 o0 w' IAPU::~APU(): ?" U& W/ g7 ^. N
{
9 v8 h+ f( [$ Z& _% V}
9 v/ s% z1 n3 L' E+ Q% K5 K/ \6 k! _1 K0 u/ U
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )$ Y# _: j$ M/ O& Z
{- v5 A9 [" q+ t, f4 Y( `. H
        queue.data[queue.wrptr].time = writetime;
+ |2 E+ Z: w$ t4 _: k; N' J        queue.data[queue.wrptr].addr = addr;
& n; b2 [8 h  z/ g- ~# O  l! O        queue.data[queue.wrptr].data = data;
# {7 C* B0 I8 B4 ~' ]        queue.wrptr++;
  [7 F5 c3 g5 }, Y        queue.wrptr&=QUEUE_LENGTH-1;% [5 o# R2 n- G2 q
        if( queue.wrptr == queue.rdptr ) {
3 u. [& f% T7 F1 I) R' w                DEBUGOUT( "queue overflow.\n" );( P; j( J) _2 L% R1 k
        }# W, i1 {4 d! Q! ]
}
! s9 X2 C$ x: k  f) ^
5 I7 L8 X# U8 s, [* SBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )4 j. ]6 y' `; a  f" z3 p  V& L, L
{
. t8 ]- z% d! G& P; c        if( queue.wrptr == queue.rdptr ) {. @7 ^' X( G1 @( P' V/ [3 U2 ^
                return        FALSE;$ k, C$ a2 O' H$ S- C% E; l0 {
        }
2 u2 I# y: ?; N% ~0 c        if( queue.data[queue.rdptr].time <= writetime ) {8 y, I6 q6 p6 g& z3 k6 B% C
                ret = queue.data[queue.rdptr];
0 o6 d2 y. J' m& n2 {                queue.rdptr++;8 o) @$ L# w3 \# K' u7 H" `' h
                queue.rdptr&=QUEUE_LENGTH-1;
7 z# U* p. P* ?# _' f                return        TRUE;- _4 R  I5 h0 t2 ?7 c+ T
        }& Y7 c/ O2 c  U; L
        return        FALSE;
0 Q. R7 d& l" _, z: x}
; J& }( F# o7 J: P+ u. Y& X
# b8 k$ t- z6 J; {. y) ]& kvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
: e4 l5 l( f" A  [& C' F0 }5 S{
+ }5 ?9 d" F: g7 w) R* M/ @- o' T; i        exqueue.data[exqueue.wrptr].time = writetime;
; s% I4 j' ]+ g+ A% u! I        exqueue.data[exqueue.wrptr].addr = addr;
2 t/ p8 C4 z' E. U0 @4 m3 k        exqueue.data[exqueue.wrptr].data = data;# b  ]' Z" |: g! b7 g: T, H
        exqueue.wrptr++;
$ {# \- C* M5 J* N" y7 R* t        exqueue.wrptr&=QUEUE_LENGTH-1;, K, t. Z% w& b# u$ F& N5 h: ?
        if( exqueue.wrptr == exqueue.rdptr ) {
) Z! O7 c- ~& H5 V" ]! O; W                DEBUGOUT( "exqueue overflow.\n" );
$ d# @" x: X9 A- k; `" ^- E5 j0 t        }' Y# a7 x3 {* G
}
' `4 s1 m1 e: h( ?1 U9 `5 |- w$ N& b
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
3 ?; \, f6 a' U& ^7 Z/ z{
$ w' h2 o, ~6 C2 P" b7 x        if( exqueue.wrptr == exqueue.rdptr ) {
) v+ b9 `: D8 v- F8 r$ `                return        FALSE;
: P; V2 g7 V. L- B        }
! K$ l! t0 C/ a( ^" z        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
% Y) J8 s# w; ?& {                ret = exqueue.data[exqueue.rdptr];
# o/ P: I0 W1 X3 z. x                exqueue.rdptr++;
( `' t2 O* Y( k* |0 t                exqueue.rdptr&=QUEUE_LENGTH-1;
" ]2 v$ c$ d' m  I% d                return        TRUE;
3 J3 Y% A1 |3 r1 J+ [" H' ~) _        }* K3 @3 M/ n0 w
        return        FALSE;
7 U  {3 r9 c1 `9 C! N7 D}
% B7 R6 q; {$ f8 j) o. i: O% A- a7 W4 m" ?) L, m' ~9 _" {' D
void        APU::QueueClear()
8 p9 K' G- \- v4 B! Q* q{( ~- d- _7 f+ u3 [" Y% \5 k% i
        ZEROMEMORY( &queue, sizeof(queue) );: h. M: U3 z0 C! N- w& F
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
4 W/ p2 J7 o; O1 N9 V; i1 _3 H}/ Z2 F: |7 j! ~  J; r/ \* U( |
$ `1 L, s1 [6 v7 k! B+ ~
void        APU::QueueFlush()9 e" e1 f) ^0 X
{
+ n5 E0 C) F; Y( w        while( queue.wrptr != queue.rdptr ) {* Y( p( Z. g, V
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );" t9 \1 p) ?$ g
                queue.rdptr++;
) U6 A  G/ u5 r5 U+ Z- _                queue.rdptr&=QUEUE_LENGTH-1;- H1 p3 _- }. Y
        }* _/ `/ c" ]1 F7 X9 D) N* o
* Q& Y' I" f) Z% T
        while( exqueue.wrptr != exqueue.rdptr ) {9 |9 m7 U, k: h9 f$ [6 ?- ]6 [
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );0 C& U1 \8 x! N
                exqueue.rdptr++;
. E. v' s0 n" X+ A" s& J/ }                exqueue.rdptr&=QUEUE_LENGTH-1;
1 }1 \4 X- `5 O4 G# O        }
& r, {# G3 ^6 h2 C% q, F: ^# t}) q* k$ _& z: @8 ^2 v2 Z% J
$ s1 D" x& T) x$ ?1 c, F8 o
void        APU::SoundSetup()
$ P0 W, F8 ~$ F% B) z. p% n  H{+ C- w2 Y3 G/ f# G: I& Y- p
        FLOAT        fClock = nes->nescfg->CpuClock;
9 {- T6 C/ a, c) F        INT        nRate = (INT)Config.sound.nRate;" N2 K$ o# p3 o* @0 x  N7 ~
        internal.Setup( fClock, nRate );& O" x+ I( k6 m& O
        vrc6.Setup( fClock, nRate );6 q7 s$ }2 p7 }! g) ~& |! A% S2 x
        vrc7.Setup( fClock, nRate );2 a7 u4 M' V! B% f$ x" F) u- J
        mmc5.Setup( fClock, nRate );+ R$ C( K2 Q2 R( H& {2 q5 p( M- K
        fds.Setup ( fClock, nRate );5 u1 [* m: U% ]8 ?4 @0 ]1 ~
        n106.Setup( fClock, nRate );$ X9 v3 g+ t6 e; Q
        fme7.Setup( fClock, nRate );
7 d* x* T4 ]* M; Z. W+ f" A- \5 _8 l}
8 @( D' d0 Z5 D; i$ K! B; l, P- W) o; Q- e
void        APU::Reset()
: \5 H  p* G. q5 \( t1 S! l# o4 x{
( I9 I! [5 W1 F- ~        ZEROMEMORY( &queue, sizeof(queue) );
+ ]+ r, z4 L+ s6 _        ZEROMEMORY( &exqueue, sizeof(exqueue) );5 p% o" F! h' S

3 f1 c! n, O$ V2 @7 j        elapsed_time = 0;
$ S7 e7 V* X$ @# K& p
% A% a- m: w! S! y2 F9 H$ @/ \        FLOAT        fClock = nes->nescfg->CpuClock;
% X$ B& x2 Z# W2 b1 |+ u/ _* F" f        INT        nRate = (INT)Config.sound.nRate;
  t5 g6 I' ]/ M        internal.Reset( fClock, nRate );' ~! z. z6 b5 [/ N
        vrc6.Reset( fClock, nRate );. V2 g3 _2 h1 |+ M
        vrc7.Reset( fClock, nRate );2 y; P& d, B* _& g, o" J
        mmc5.Reset( fClock, nRate );
5 l& G" x- ]' |4 n        fds.Reset ( fClock, nRate );
# X" o( R  U: V& `# q1 H$ _+ [. s( l/ m        n106.Reset( fClock, nRate );* q" k! ~3 j8 m+ U9 j
        fme7.Reset( fClock, nRate );
5 l+ e" [7 x& o* ]
/ A* _+ p( P0 @& D6 `. U        SoundSetup();
9 i3 i, P; s8 r: E}
: F8 M+ P  h7 t( v, r7 o
  o5 k( d0 y, \, Q& C$ @' ?! k" a7 vvoid        APU::SelectExSound( BYTE data )
0 |5 v4 d: I1 L{! {. U' ]" Y# s& j$ a  E% P+ U
        exsound_select = data;$ W7 i3 G: a4 _" E( I8 s+ |" w: E: g
}5 {3 V# r9 F8 _. l

, n: C: d: p1 G$ z3 yBYTE        APU::Read( WORD addr )* o/ ^7 j2 z; d- p) S
{. z2 q' F8 P& u8 H6 C
        return        internal.SyncRead( addr );0 q0 n8 ?2 L& P1 c1 b' ]; U
}
$ E+ G6 _' r  u" `- G0 B% e+ o5 i; k' o* V1 v5 v" j0 e  a
void        APU::Write( WORD addr, BYTE data )+ V& L" B/ _! \4 |
{- Q5 A0 I" y; A
        // $4018偼VirtuaNES屌桳億乕僩
0 r8 G' E8 G8 w: ?% E0 o% s        if( addr >= 0x4000 && addr <= 0x401F ) {
4 `$ q. X  k7 n                internal.SyncWrite( addr, data );
+ G; X' O+ a. \                SetQueue( nes->cpu->GetTotalCycles(), addr, data );4 G' M0 W2 k: G1 P' ^9 f8 R- ~
        }
% x6 E* [. U9 U) S2 Y- z! @}- B/ |9 i  j  u; W& ^
9 z2 w7 @, ~. q; J- B
BYTE        APU::ExRead( WORD addr )* x, q# A" Z: h
{
  o5 Y0 [3 V. {. s  w( q; UBYTE        data = 0;/ F2 D9 F8 j1 g4 A- C" Z0 N2 [
% d0 j" U3 G; G' F( O) g8 D0 z3 }
        if( exsound_select & 0x10 ) {
3 n" K  y% ]7 m8 b2 S! G3 ^                if( addr == 0x4800 ) {; `. n, V0 L) N3 k8 Q& j3 j' a: b0 p
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
+ V, _: @: n/ i# J9 h4 y# X                }
3 l9 H3 |6 x6 s) q! o& u# `$ W        }1 |. L! e/ }$ t3 X1 h* Y
        if( exsound_select & 0x04 ) {
4 I# E* h/ A) a  W! k; w                if( addr >= 0x4040 && addr < 0x4100 ) {$ f, ]0 K% I; G1 b" y3 {
                        data = fds.SyncRead( addr );# ^4 W$ R, M8 @( f5 Y# q+ i
                }6 a% d/ |# C. B4 ~( J
        }' S9 _/ R8 {3 {0 h
        if( exsound_select & 0x08 ) {
. b4 x# Y' C2 O: i                if( addr >= 0x5000 && addr <= 0x5015 ) {* N& E" B: {$ V! q3 f! i7 x
                        data = mmc5.SyncRead( addr );3 M: G- {. M0 @. q: ?& F. U. B
                }1 K" o, h% [1 W0 ^
        }
/ z7 K/ A8 P$ M3 \; [' v* @7 a; q4 k8 H8 c' s$ _: f) K
        return        data;7 x) \% f7 t" t& J# r2 G/ d
}
! s7 t& o3 M$ d8 X& P( C5 x# Z4 ^- M% T, T3 d
void        APU::ExWrite( WORD addr, BYTE data )- F7 f6 F1 x3 X& _+ u* T4 t
{
( Q" b- E4 U1 x1 c, ]0 A        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
/ ^% _3 F: F- b7 X2 q$ z" Q9 C! ~; d( x# d! Y* Y' J6 _; |
        if( exsound_select & 0x04 ) {
0 a2 S. _) G2 r/ V                if( addr >= 0x4040 && addr < 0x4100 ) {
. s# M) P" g" c) |- U. ^                        fds.SyncWrite( addr, data );. ~8 b5 u0 \2 o) y- l
                }
6 V# B5 }6 C: A1 H8 N        }3 V- f$ b- e9 C: O% t6 ~% [
  x4 J0 D4 ], y9 W. |! d9 i% G
        if( exsound_select & 0x08 ) {, T- R9 y' ?6 n) X" ?0 V+ K
                if( addr >= 0x5000 && addr <= 0x5015 ) {* e( F' Q5 s* D
                        mmc5.SyncWrite( addr, data );9 w9 Q5 T; U3 S8 ~9 ^
                }5 B3 u1 @, [/ p4 e. t# q, O
        }
% `0 a' b" _$ c( H}
6 Z7 P9 h' v/ R  o! a
9 E  l( ]/ K2 A0 P" rvoid        APU::Sync()
1 S1 N* h3 S3 s4 M{% a1 C" B9 ^0 V) J% \  e9 @
}
( E2 [" K/ d! G2 ^5 O+ P1 J1 y5 f# d; X5 S# t: I9 ?5 j
void        APU::SyncDPCM( INT cycles )
. A1 O$ g; L9 `. j2 K" S7 n5 p0 m{% I; Y7 j" J2 f" b
        internal.Sync( cycles );0 r, b6 W7 T% a  x: b6 K  U2 |1 ^
* R6 }) c4 h. @* P/ W0 ~
        if( exsound_select & 0x04 ) {
' r/ [% d: y+ h) u                fds.Sync( cycles );1 C5 p4 R( p% W" W4 h5 z' i% W
        }2 L! N  K0 J( d7 P
        if( exsound_select & 0x08 ) {& |& D) ~" b5 ]5 t- c0 Z
                mmc5.Sync( cycles );
/ h6 p9 x, A2 \2 Y4 u; V0 N& ~        }
9 u$ d* H( M: ]% r}) |  @5 {6 j! Q. x. v
4 h: D* p0 R: x
void        APU::WriteProcess( WORD addr, BYTE data )8 l; X& Y/ l" N( c( W
{
) P2 }7 J- M8 z        // $4018偼VirtuaNES屌桳億乕僩
6 J, L* l; @& ]3 i        if( addr >= 0x4000 && addr <= 0x401F ) {
: |- }: S1 m% |2 r0 a0 r9 e                internal.Write( addr, data );" }# x8 q% I. X! y. u" r' E
        }2 W2 J. {. G3 H* [3 t% L0 g: b5 e
}  C' c# U0 w/ r( c
+ Y; ]. o1 a% N( o
void        APU::WriteExProcess( WORD addr, BYTE data ); y5 p' ~- `* e  d, {8 b
{0 Q$ h0 R9 ^( L
        if( exsound_select & 0x01 ) {6 {- V6 i8 w" \2 {1 H
                vrc6.Write( addr, data );# H7 s! b6 h; O8 ?" x" K
        }
' I6 ?, n8 V; `* T& M  c        if( exsound_select & 0x02 ) {  D  u) s3 j- \! Y# A
                vrc7.Write( addr, data );- ]& q& t& T2 X* i
        }
: l& d) S5 {: `' h) a5 w( m        if( exsound_select & 0x04 ) {
- q2 |% X% U' a5 E                fds.Write( addr, data );
/ M) _3 Z2 t+ N& e/ U& l3 E4 F        }
' |* j0 m9 A& K; ~        if( exsound_select & 0x08 ) {
7 G$ q5 P' n! y                mmc5.Write( addr, data );' ~5 T8 Q3 I4 v0 T
        }9 H. z- H6 z7 ~& g4 t2 R& k% r
        if( exsound_select & 0x10 ) {
5 F$ C5 }; R9 q                if( addr == 0x0000 ) {
* H* f2 u5 p! i! B                        BYTE        dummy = n106.Read( addr );
8 n- v6 N+ o' p" b( \                } else {
0 N& A3 v, j. }6 D  Y8 Y0 v# x                        n106.Write( addr, data );$ ?0 S! K/ C" N* R+ G- B) S1 A
                }
: D; b* E7 ]9 J% T  g        }: v& x9 ]  M" Q" K
        if( exsound_select & 0x20 ) {
7 r" D0 M# Z! j7 j2 l- T                fme7.Write( addr, data );
6 c3 N" M0 c  L        }2 y8 E+ j9 X2 [" E' T
}
! N0 M" h5 E& G% G8 ?# Q3 M# L: d0 f
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )! K3 f1 q$ |: i) ?& E  F
{
3 ~- p2 \' B4 J8 w. r! v1 z. |INT        nBits = Config.sound.nBits;
* O2 }3 a7 j/ H4 M! uDWORD        dwLength = dwSize / (nBits/8);
- b/ X  V3 ?! J! E. M- u2 QINT        output;0 n& {9 b  B& [6 d+ O
QUEUEDATA q;# Y! [/ }' k. R6 Z0 v. {( s
DWORD        writetime;- y; a0 N( U9 s  c' Q( g8 B
+ k% b  ^# n& L+ h2 S$ Y8 ~+ X0 |( V, b
LPSHORT        pSoundBuf = m_SoundBuffer;
+ x0 I  q3 L8 D; ]: S& H. RINT        nCcount = 0;1 g! F  l6 S# _: G0 ^
5 I0 @9 A8 B+ M6 `3 F) b; m/ X
INT        nFilterType = Config.sound.nFilterType;  q: s/ u4 K8 n+ \$ O' S( c
( e. J8 C" H, V; `- h8 m6 x
        if( !Config.sound.bEnable ) {- @! ~0 \9 a) D$ \  A1 K
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
" Y  a) n2 J5 F' w8 e                return;
, @% m4 [0 F* X! V! N1 d8 P% N        }4 Q9 `; s( P6 a

& d" l/ k6 }! `8 i        // Volume setup2 J* S: ^* o9 ~% J
        //  0:Master
+ }+ w; G6 J8 j        //  1:Rectangle 1
( u/ D- ^/ k6 O# g        //  2:Rectangle 2
. z9 N5 K5 H1 h9 Y% B; E        //  3:Triangle
, t0 o" C3 \7 R9 k3 r# Y+ |0 S8 j        //  4:Noise* _% M* A& p5 w
        //  5:DPCM
" [3 ]: y8 [) Z3 Y5 `        //  6:VRC6; ~4 L1 p5 ]" E; \8 R, }2 p3 p
        //  7:VRC7& G$ e0 t2 I+ R* N
        //  8:FDS
; l0 b' T( X4 f$ B+ f        //  9:MMC5
+ v- R* ]* w- C) A+ k- u3 h% a        // 10:N106
/ O2 W% z2 Z% {5 t        // 11:FME77 S9 t. m7 w. s, {0 U' _' c2 T
        INT        vol[24];
( D9 b% U4 R8 w  z* ^. E        BOOL*        bMute = m_bMute;
% I9 n1 e$ \# V! _& M$ p1 P        SHORT*        nVolume = Config.sound.nVolume;
3 }) u$ t# |. {, k& V; I
- I3 t9 \+ Y  z/ ?: s  ?* S        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
9 v$ V7 Y: \( e! K3 F% A& J0 f! f! a* S  C- Y/ O- c
        // Internal
+ ~9 O1 N- ~) p        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
# P  T) X, t  r8 X6 h        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;" o, m! Q% Q- F6 a' C: B; t
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
4 B6 D4 U1 R1 L& n7 Z8 i        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
2 F& E. G- A6 ?        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
" d5 V) W4 A' }# u! t5 `" U( R5 t( D0 W  G) z, [
        // VRC6
+ |5 f0 v! E% l( k" c# J        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
* N. _& z& L( Q% h2 K% U        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;9 h/ o$ q3 ?- Z5 E4 C4 w
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;; ?$ U% X% i6 o. f# [# H# G

9 K( w0 Z3 X7 x; G! S. }        // VRC7  }5 b3 [  `  M- I5 K3 q6 E
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;3 E5 _8 m9 @' }  N0 I/ P) d- ?  ]
) h: P% u% \% D' F: B! I
        // FDS
' ^: `) Y. i/ e        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
; X8 e9 ~; t" H* M$ F
  k% n6 t2 g$ z8 N4 V0 t& D        // MMC52 ]7 c# j1 n7 J$ m* e
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;* ?3 K, o2 l( ~- I2 w/ k
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
+ ?) x) v! ~6 m8 ?, `        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;* |' C+ J4 O" o

: Q. D4 C- S2 [" W8 E  T        // N106
7 G! W; N0 \* s, ^" V: C        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: F$ q1 B9 b$ B% {& ~" q        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;2 Q# h7 J7 `4 J6 o8 r% c9 V* A+ z5 K
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& N/ X8 t( g  R; x, b2 N        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ L4 o+ ~1 G/ {: C8 J3 Q
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- n. Y% Y& @; p- Q& d        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
  g$ N- a# D5 t- |        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' P; S1 K4 T6 {0 A. l
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;& |& Q# U& K0 Y; X! r7 u
9 c7 N6 ~9 h+ \6 k
        // FME7
( t: j1 Y( \7 H+ A/ ^- w        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;( e! Y+ ?8 \) _$ M
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;$ Z" I& P/ X0 [; ^: @8 C0 v8 z. u
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;( o' Y" J7 C( r; V3 W

; }8 d) g  c2 P6 d//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
1 E( B+ _% N. g: N        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;) f( P' p: C, U4 N* U2 M; r0 B

0 `- P: [0 D) H! E" }# R        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
# x0 T. G' S# P5 b# y  o* ?        if( elapsed_time > nes->cpu->GetTotalCycles() ) {' z( w# n3 E  i1 o! U6 U5 T! Y: \
                QueueFlush();: b" K: D7 @) i9 E$ n
        }
* j$ M( \. M- r6 k! p; b9 d! A  x4 B+ v
        while( dwLength-- ) {1 p$ T. c+ J$ Z1 F' z+ ]; _
                writetime = (DWORD)elapsed_time;+ t, R7 K* H- t2 [/ s
$ h3 _5 A& E7 \' ^- ^& p/ n% x! z
                while( GetQueue( writetime, q ) ) {* {0 F& k. d& z4 b+ v0 |# S, n6 V
                        WriteProcess( q.addr, q.data );8 l) O( Y/ D2 I$ j! l$ W# x
                }8 M+ N+ f7 W: H! O

, N6 Z' Q+ _; L4 l- K6 \                while( GetExQueue( writetime, q ) ) {
8 n* T" @2 }& w                        WriteExProcess( q.addr, q.data );
0 ]7 o$ b% b' G$ A: K' y8 B: S                }
1 k! D  d! E; {! A' N2 G
4 d  |/ O$ o% c) Y( L& v2 I                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME79 s2 T7 E( b* V
                output = 0;* S- O, z; A$ ?, ]
                output += internal.Process( 0 )*vol[0];
( u/ R# Q! Q# r7 j; ?                output += internal.Process( 1 )*vol[1];* _+ d9 }% ?3 g5 f
                output += internal.Process( 2 )*vol[2];* i  a* ?. m6 D. C9 M$ e0 d
                output += internal.Process( 3 )*vol[3];; L' j" z6 ?+ [# b
                output += internal.Process( 4 )*vol[4];$ h# @& g; C! y. g5 @4 z) i+ Y
' }* s0 X) z& e6 d# V- e
                if( exsound_select & 0x01 ) {+ n; s$ E) _# K" k
                        output += vrc6.Process( 0 )*vol[5];
* d- [9 j$ G. f  N2 [9 {6 }8 _( [4 y                        output += vrc6.Process( 1 )*vol[6];' t" [( r; h: o  ?1 ]* A
                        output += vrc6.Process( 2 )*vol[7];8 y) Y( g7 M3 x+ J2 \9 R
                }( w$ X: R, |2 L+ L+ m
                if( exsound_select & 0x02 ) {1 M% V5 Z  D5 y1 ~* ~% d( V( h) E
                        output += vrc7.Process( 0 )*vol[8];
9 d6 R: R) y! |* L6 w8 h                }, W9 d6 U7 x/ k$ G$ p$ _
                if( exsound_select & 0x04 ) {4 e% I- k( ], k9 l' k) l
                        output += fds.Process( 0 )*vol[9];
9 O' r+ m; h$ O/ X+ d; h9 J                }% j! E; L- M/ g8 s1 J
                if( exsound_select & 0x08 ) {5 g( M$ T' a* Y' T8 U# x
                        output += mmc5.Process( 0 )*vol[10];
& T$ }& N. ?( x4 b/ o, d) A                        output += mmc5.Process( 1 )*vol[11];
6 O9 Z7 M$ [* N                        output += mmc5.Process( 2 )*vol[12];( {) u* v4 ]# [; E' {9 J
                }
) L  R$ s$ Q: F; ?  L/ V                if( exsound_select & 0x10 ) {# B6 h4 Q, H# \  }% F) t
                        output += n106.Process( 0 )*vol[13];
* W0 V, H7 Z1 c; A; U                        output += n106.Process( 1 )*vol[14];2 {6 _: {( c! }
                        output += n106.Process( 2 )*vol[15];1 \2 X2 J! y0 V$ i& u! d5 d; s; F
                        output += n106.Process( 3 )*vol[16];2 k- l- Q: ]. z/ F3 `% _
                        output += n106.Process( 4 )*vol[17];: A: B* `6 [+ W$ }" [  l5 c; m
                        output += n106.Process( 5 )*vol[18];/ ^8 y) \! r3 {& a' h% M2 H/ `3 A
                        output += n106.Process( 6 )*vol[19];0 _; _# h" [% V
                        output += n106.Process( 7 )*vol[20];# o9 a! F9 Y5 M0 n2 J! t) X2 y" F& l
                }0 _4 E. \( M3 R, Q: E6 O
                if( exsound_select & 0x20 ) {/ x/ V( a( R6 @# {6 L
                        fme7.Process( 3 );        // Envelope & Noise
2 k9 a6 N. M* B6 y                        output += fme7.Process( 0 )*vol[21];
: w( }  p  m! _+ n                        output += fme7.Process( 1 )*vol[22];0 U8 n0 E. p, H( B
                        output += fme7.Process( 2 )*vol[23];
# a; J2 m( k( ]5 ^                }
, B) y* `# }* J4 r$ i. q* f
: w( T2 `! t0 I0 ~' D5 X6 v4 H                output >>= 8;
  C" F8 x5 S4 J4 g# N/ V
' C& V3 l/ e5 M) j4 i; h                if( nFilterType == 1 ) {$ n& I& \- L9 U9 a4 C
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)% o$ |( P: g5 U3 {( Y
                        output = (lowpass_filter[0]+output)/2;$ @% T! x1 i# Z% k
                        lowpass_filter[0] = output;
% A- H, P4 @4 u: F4 N                } else if( nFilterType == 2 ) {
3 s  d; b, g* i; Z. ]% ]$ T( V                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1); Q% u0 d7 G/ [# q- ^' L  X
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
; k- @2 U! J2 A7 s- g  f  F% n                        lowpass_filter[1] = lowpass_filter[0];% f/ I5 R% g" m. a2 T, G8 |8 V
                        lowpass_filter[0] = output;! ~0 n4 M2 P8 Q7 e' w0 W
                } else if( nFilterType == 3 ) {" A# K, t# I& u# r$ Z3 Q
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
7 ~& \- o4 n1 u0 C- W" i& T; Q                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;9 g" ]. B) [$ f5 E
                        lowpass_filter[2] = lowpass_filter[1];' t' m8 g* C$ U& l; }. d
                        lowpass_filter[1] = lowpass_filter[0];
2 i* t/ o* G, Y: j! o                        lowpass_filter[0] = output;
& E! I- e2 i6 q  I                } else if( nFilterType == 4 ) {& m! ]! B2 |3 S3 q& U
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)& u2 x6 v1 m- A7 }2 y, I5 m* i4 F
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;, X0 ]; Z% h. p0 w+ W7 ^* C7 j
                        lowpass_filter[1] = lowpass_filter[0];! ?+ n. i$ \% e' P, T* Q! K
                        lowpass_filter[0] = output;& c" I% t0 I4 \' w: s8 q/ F
                }
# d% G: Y$ K: g% w8 ]
; A) Q" i& n( h" i0 J$ A, ~$ J# d, m#if        0
5 ^: m' j3 I' N% Y: V9 [7 T! a                // DC惉暘偺僇僢僩
, C" a$ ]5 G% i( E8 \0 e0 G                {) _. ^+ t# H2 z& Q; `
                static double ave = 0.0, max=0.0, min=0.0;
: x; R- F+ ]! ^9 w0 S$ I- W                double delta;
& B3 j. u; E2 c/ N8 q                delta = (max-min)/32768.0;7 L7 U2 r9 a+ a. \
                max -= delta;
/ }7 I7 H7 u6 C                min += delta;( e1 A  i' L' R' \
                if( output > max ) max = output;% K- V4 r, z+ ^2 H3 X$ K" P& D1 E
                if( output < min ) min = output;, @. R! L& B& d+ j6 |8 q; I  `1 J
                ave -= ave/1024.0;0 z' a; F2 z" S" d7 p; r6 C
                ave += (max+min)/2048.0;
; [) E, t; V1 f9 y                output -= (INT)ave;
' w3 M) K7 G. B                }6 a, Q) U% e# R
#endif; F4 S5 m5 b% Q" r; m- O# E5 N$ O
#if        1
2 X4 @7 ?# H% y6 J                // DC惉暘偺僇僢僩(HPF TEST)
4 r5 ]7 k* v2 h0 p  F                {4 G- Q( g: i3 |" \, w4 o' p9 ^7 L& {' i
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);+ @; E8 O+ Q: t! @9 Y9 T; u
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
6 q* s% C, V: w1 B) Y& M: {                double        cutoff = cutofftemp/(double)Config.sound.nRate;( K- z$ g% G* X9 p8 l& X% t
                static        double        tmp = 0.0;3 E! o( |& Y- v: n) T& l7 v
                double        in, out;
( o" x7 y' ]6 e1 P5 ]$ r
7 U) u) r1 U( x4 w5 h( i6 J                in = (double)output;
. G7 [+ J  f/ T                out = (in - tmp);# C4 ?' {$ s" R$ F- x; a, Q* R3 C
                tmp = tmp + cutoff * out;2 I+ ?$ b/ L8 b3 R
  ?; V* U' `& n) c, z9 A
                output = (INT)out;3 l4 N; F' @- S" ]/ p: I
                }/ H* K' l  ~3 Y8 [5 b  b& K) T5 ]
#endif; k  P2 L; X3 F6 o8 W$ B& `: L
#if        0
& C, F! O/ x- t                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)* ^5 u+ @, i* G4 c
                {
: m+ q3 [, M+ x3 C4 G* `1 v5 v                INT        diff = abs(output-last_data);  n  b$ F. U, C3 t- k. P
                if( diff > 0x4000 ) {& K6 Y# s4 \) V) N$ F, ^
                        output /= 4;
7 X* x' [' \9 y5 c                } else - H9 r5 e7 p5 _2 t) ~2 B
                if( diff > 0x3000 ) {2 c" N6 {1 }- K& Z
                        output /= 3;- n! R8 A$ {7 h
                } else) U& |* S: G1 l3 u1 W
                if( diff > 0x2000 ) {
9 g* k) J& e# m8 k' K" m5 k9 J                        output /= 2;) U0 S9 o4 J" n$ [! j  l" K
                }3 K' \, p  b1 {! @; T
                last_data = output;& j0 R3 b7 p. X8 ]4 D
                }
4 J; \. D+ b0 P  q5 m# r#endif4 [5 d2 k: l2 Y6 `
                // Limit
9 T. T( m( E$ f" n4 \                if( output > 0x7FFF ) {
" ^/ @* ?- p7 b$ e9 @                        output = 0x7FFF;2 f' w6 C( K" x5 \- y  z
                } else if( output < -0x8000 ) {
- t) P  {% x8 `$ y. y) J                        output = -0x8000;
9 e3 n( D! C, g2 N- A5 X                }
- L0 V& j5 B) O! R) Q( F: t
3 ?4 v* [2 G3 Q6 y" k                if( nBits != 8 ) {% w' C5 A. Q0 Q. q$ n
                        *(SHORT*)lpBuffer = (SHORT)output;
$ z5 w; D% w7 q+ k                        lpBuffer += sizeof(SHORT);7 P0 O2 t+ }( G9 I0 x
                } else {
( q# R. D9 x9 o7 o) f                        *lpBuffer++ = (output>>8)^0x80;
2 {4 m. @1 P' k; L2 U) H- B                }
4 Y3 c6 l# z6 Q* J1 S* l
% z, Q' y) P& w$ O                if( nCcount < 0x0100 )& t% Q0 }% o0 p! e+ z
                        pSoundBuf[nCcount++] = (SHORT)output;. _/ X, C6 W; o4 @
) P* w$ z; j, V: E$ E2 t
//                elapsedtime += cycle_rate;: k% t4 N' E6 e+ f# X  f  f, [
                elapsed_time += cycle_rate;( f# b, y; z+ x3 N
        }2 L4 f2 V4 `6 ?

3 X7 R$ x/ k/ c! R$ ]; N#if        1
/ }! p& t( ], ?9 T# l  _( ]1 y        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {! K8 c6 W( f1 `& S8 g5 R# G- }1 F
                elapsed_time = nes->cpu->GetTotalCycles();
2 |7 T, `% ~0 [0 F6 z" B3 I        }4 J3 K& }3 a! N( z% d& y
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {5 ~) F+ k, c& |& P
                elapsed_time = nes->cpu->GetTotalCycles();9 y3 R6 {+ w- i; O
        }. |' o9 h0 h+ ~& P+ Z( V0 Z8 E# @
#else
: z2 K6 s0 {$ a        elapsed_time = nes->cpu->GetTotalCycles();) W0 V5 O- j- B: L& [1 H5 D
#endif
8 k. e, o2 U( q/ r& C}  |2 z: c1 A" r4 l/ z; P# Y

/ B% {' M1 x' I: H! |// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)* R( T" m* ]5 g% g
INT        APU::GetChannelFrequency( INT no )
" s9 ?. v/ ]% b$ n{
# i  {* k  ^. ]% {' b0 Q        if( !m_bMute[0] ); b; C, c8 f( \
                return        0;! Z' M2 n' d" i

$ c2 B. D. s9 M9 C2 i" K- {2 k4 @        // Internal
; `/ g4 r4 f' a' k. U6 b; {* `+ B        if( no < 5 ) {
2 ~$ g8 G  ~8 I                return        m_bMute[no+1]?internal.GetFreq( no ):0;/ h8 Y8 T+ ^4 E$ I8 j
        }
9 j/ V/ f1 `2 ]' j8 Z        // VRC67 a, ^: B0 S# d9 P5 s& l0 m
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
- K8 F$ w7 y; Q. s4 g" Q8 E                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;: v" E' {3 ?+ ]& l
        }
0 x' o7 u/ a$ L        // FDS
  o5 h! l8 E4 c        if( (exsound_select & 0x04) && no == 0x300 ) {' f/ A9 {% K# ?
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
& m" L" q* L6 E, }1 p1 @        }
2 ?0 M8 l" S: v( T( d1 p+ z1 [. t        // MMC5
- E% @! H! I# D7 u& L& G6 t  e        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {. s8 d) P' s+ S" v0 |2 [( D  e
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;7 R6 J; E/ X5 k' ?' R7 y0 p
        }
( g3 X5 {7 ]9 i$ N: w* P' ]        // N106% z) T7 X- o. _- A6 t4 u4 u# p) d
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {" d4 p& u! H/ H: M) W% o
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;6 U3 S. t) m- R& D' p. w
        }, J1 L& J; {" r& Q6 A: w, c* i
        // FME7, l) Z* _8 o8 p: b
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {3 L0 _  a' [2 |0 N2 U/ h2 i' K
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;( A8 q9 Y% n7 e/ B* @
        }
- P) h* @. f: |' w$ h        // VRC73 @, V' R0 Q" P. ?3 |
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {0 y  {/ P. h$ @/ l
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;) z( X' E8 V0 }6 i2 ^9 r* U2 L3 l& p
        }; n+ M$ w! U6 {) s
        return        0;- n( K9 o+ f* `% K( C! S, S
}
2 x, f$ s2 F/ o$ M* F$ p9 [- T
// State Save/Load/ n' y+ d$ \: O. _! B# S
void        APU::SaveState( LPBYTE p )  [& L( s) s! ^$ i
{
6 h  M9 j, z9 P5 [2 B: M#ifdef        _DEBUG
5 X: O% z& _! e' }/ qLPBYTE        pold = p;
' t' Y& D2 L- u( a6 U#endif4 t+ F2 H& A1 h  s( n/ T

5 Y& G3 A# I3 x        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞  A7 |6 s& b! {1 P. E: [
        QueueFlush();
! E! H! C7 i# f7 K# X2 @
$ v! E; T1 G; ^* T( l$ {  p        internal.SaveState( p );
& w% G, U  j7 l- N* m        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
4 }0 P1 ]' J" G9 _! g3 e$ u1 E2 f) W: s0 C. q, [7 t
        // VRC6! [! W' |1 H9 v$ T
        if( exsound_select & 0x01 ) {/ X. C+ F7 G0 H' j: H2 ~# `
                vrc6.SaveState( p );
) L/ ^0 B+ o- R; a3 r                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding- [8 L4 L. D, r. T/ v6 }9 K' h
        }3 _0 L; T( |& n: p
        // VRC7 (not support); {% M5 U0 m" j# o; B8 r
        if( exsound_select & 0x02 ) {, I  e4 n9 C! V
                vrc7.SaveState( p );
& H2 ?9 |7 P, |8 P+ m2 T, C                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding. R- A" d$ `8 Z
        }* {/ N  Y( R; o  w  u9 M
        // FDS
# m9 v9 R/ [8 k. P        if( exsound_select & 0x04 ) {& j' w, [. b3 ?/ i
                fds.SaveState( p );
5 ^' @: [, G* }- z! q* `' Q                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
4 A0 s' J: x  I* j9 S% T7 R& X        }
8 s+ W* D& d3 A( N: P! l6 o. H        // MMC5; J+ N: V, I( F) g0 q
        if( exsound_select & 0x08 ) {, F  q2 l/ V/ ^; `0 H* l- z
                mmc5.SaveState( p );6 k" e0 C" m  u& j3 l4 d
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding, j8 v  n% \& F7 _9 o
        }
% U+ l( Q, W& H  j        // N106) q; ]* m8 N2 c( ?
        if( exsound_select & 0x10 ) {
0 a" j6 \8 |* V- K& j5 b                n106.SaveState( p );6 J7 T$ H7 c' ?7 y
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
4 I; x( r9 r1 ?1 o/ J2 }* N5 e  g; X        }
- }. M- ?$ i) u& L        // FME7
4 r# M7 c# u; Z$ p2 w2 J        if( exsound_select & 0x20 ) {( K; @  s/ z: ]. C& z9 X* `" Y
                fme7.SaveState( p );
/ J- ^3 I: a' Y  G3 v                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding7 N+ |' s! r) o# g3 y$ J8 }+ \
        }
% I9 c# X5 ?6 m( s# \( R4 K8 w% E" I5 o. ]4 A3 h
#ifdef        _DEBUG
: k6 ~  `" e3 H" I* LDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
* y4 v5 O8 V( ]& ?' A- c0 F" @#endif
, O0 V  M( D7 p% x}
* M& u7 F- k( J& W1 O' j  z' C; j3 j) a5 v$ u
void        APU::LoadState( LPBYTE p )
6 j' X# v) n7 }8 \) N% z{+ ~8 G1 R5 G1 @% f
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
  ]* g! w! ]& q  ?        QueueClear();
5 X7 X' s& d% Z, g0 _, v2 A3 ]" u" Q
$ p/ G; e: r2 j' K        internal.LoadState( p );1 b8 F  i6 m# K2 P/ V
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding) x) A! a' F0 }) l1 C
3 |2 ~" p) L8 _2 h0 F* U
        // VRC6
" f: V7 g# D: q        if( exsound_select & 0x01 ) {
* Q4 y2 M& n5 y9 U! J$ H3 x                vrc6.LoadState( p );
3 P# j" a4 c9 @2 E/ q4 Z: N! d                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding! D8 b# W- n' f2 T
        }
4 ^5 a6 d4 l' [  Z: X) b        // VRC7 (not support)
2 i: d0 z" f; p& h$ p( a- `5 ?        if( exsound_select & 0x02 ) {0 M. T0 m2 t# N4 A% y( \/ z( x6 k2 F1 q9 `
                vrc7.LoadState( p );% X6 P" {* o  G$ Y
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding! c; H6 l$ I- x+ R* l# L: ]( ?$ n
        }" ?& j' y+ U* K6 ^, e
        // FDS
( N: I, |' {. f/ ?, ?        if( exsound_select & 0x04 ) {; V4 g8 C- J( ]* c8 ]7 I+ n
                fds.LoadState( p );
" q8 f' \' S4 M/ Z: j" U: P                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
0 [0 b& k" d( [' R- Z        }
% e# K# N0 n, A( O        // MMC5
0 x, Y1 q2 n' n& v        if( exsound_select & 0x08 ) {1 I2 M; S. w9 x- d/ c5 U9 U8 k
                mmc5.LoadState( p );% a! p) y) y* R; k, y* B$ p
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
3 J8 p; N  Q( [0 l3 R1 |+ r        }3 @2 g8 w" o4 P2 V; H( Q
        // N106
& W; D  n4 b' b        if( exsound_select & 0x10 ) {% n1 k7 l" I, E5 b8 z- C! Z# x- J
                n106.LoadState( p );: m, L% k- V3 s  o( [. y2 z0 u
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
1 b0 n, [" E3 m5 @! D/ _        }
1 g& J9 A- u6 U        // FME7) R; `& O; Q* m' i
        if( exsound_select & 0x20 ) {3 c5 Z1 ]+ B0 f# \& x- e
                fme7.LoadState( p );% ?" i3 Y4 q% f0 q* Y( M* j
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
' o, P8 v; n, U+ [6 H0 M9 A* b        }; O% V) a9 p7 Q4 s. d
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 6 i: r3 O/ z* ]; }! u# \
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。5 U- L# A4 {) h
感激不尽~~
: f# `7 [( B. l' R- q1 R* H
恩 我對模擬器不是很有研究,% ]' ~! C' }7 H( \3 u7 s& P( X
雖然要了解源碼內容,可能不是很困難,
0 h+ X0 v2 ~5 _: B不過還是要花時間,個人目前蠻忙碌的。9 R- }+ U. p. E7 R+ I. _5 o
0 r3 t. N5 A8 Y
給你一個朋友的MSN,你可以跟他討論看看,5 N7 [$ |6 Z& f+ @; N8 ]
他本身是程式設計師,也對FC模擬器很有興趣。
4 h/ D: o$ ~: Y% N3 D; e4 E. J! Q4 N! p2 S4 [1 f
MSN我就PM到你的信箱了。
, i" l4 l. c( P* G
4 v8 Y2 g. N- N希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
8 Z+ B$ L) I, c( }% I% C7 D/ P' v呵…… 谢过团长大人~~
( M4 O9 Z% M! @6 u7 Z$ M* n

4 J5 x. f/ F9 V; i8 y哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
% K' y( Q( ]9 t' s# n  Q3 d2 S团长的朋友都是神,那团长就是神的boss。
1 q5 j3 L+ S$ @8 A4 C: `
哈 不敢當,我只是個平凡人,' [4 v# H3 H% R; L: B
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙% q! H$ Q! v1 n7 K( a% w
ZYH, g9 q( Q& x$ ~
QQ:414734306) q( Q, Z" J! R) O$ i8 ^1 q7 n
Mail:zyh-01@126.com6 k8 L, X% z4 m0 R

" ^( a7 `) V* b( h5 @他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
) T4 \' z# k2 P% r" T+ |) b再次对团长大人和悠悠哥的无私帮助表示感谢~~

; }6 F/ _: }: V9 {7 G不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-20 13:28 , Processed in 1.086914 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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