EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
5 D5 k7 K- X' i- y% L5 _. N楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~/ s/ G# e8 m8 D3 `/ {! v; ~/ Z
这里有相应的模拟器源码,就当送给大侠了~~
) q$ B! x. T/ u+ Yhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 7 |9 `6 N7 z4 A
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
! q3 I, A; P, p5 u: O. z, ]' e$ y2 o楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
  [( i% I' ?- \这里有相应的模拟器源码,就当送给大侠 ...

5 g, Y, A* z; L/ g+ D8 t- m聲音部分(Audoi Process Unit = APU):
/ e5 Y$ y0 k+ `1 x7 H  F.\NES\APU.cpp
" N  j! w6 A! r' B.\NES\APU.h
) f+ x5 I4 c% ~. C  c* g5 o# r1 F6 Z
2 @5 d( \  ^& P3 @( X7 q: |- }) e+ z
影像處理部份(Picture Processing Unit = PPU):
0 L+ G  y! G* k9 C0 H.\NES\PPU.cpp
, }" e9 @# }% Y7 _. b.\NES\PPU.h
' B; e( q. H8 f( r9 {  N4 d! L* h
4 {3 }( |5 M) D) L如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:) Z* ]! @/ w6 {+ @
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
- ?/ i' G8 O2 e//////////////////////////////////////////////////////////////////////////8 Z. Q4 J+ n3 T& f6 ^
//                                                                      //
- K# h) F- h1 p; D0 j' {& N  [//      NES APU core                                                    //
7 J. s- o) \3 p3 u9 s7 c+ c//                                                           Norix      //5 K& U, q0 T( g
//                                               written     2002/06/27 //
$ P2 D% a/ d4 I% C8 @. x" h" f//                                               last modify ----/--/-- //
" R! w- m: O- u9 r8 R//////////////////////////////////////////////////////////////////////////( b% \  Q' U, P9 b
#include "DebugOut.h"4 a/ x6 y- G; @, s2 S3 p: U
#include "App.h"
2 O. L8 r& M* j& ~& o2 I% e#include "Config.h"
7 W, e4 K- E- H* x. @
- h/ ^! J1 q; B' j+ z#include "nes.h"- }9 w/ F6 e) _3 t7 @( L! J
#include "mmu.h". t. I: P' P2 u6 o  [
#include "cpu.h"
' ~; A% ^: Q- E#include "ppu.h"2 Y4 A6 g7 E  \9 k! V6 S1 m
#include "rom.h"
5 E; d7 X9 ^6 b1 p" y$ A7 D" ^#include "apu.h"0 _7 \+ }+ I2 g3 q

  y+ s% y. g3 J1 G; o) G1 |- b; m// Volume adjust
: Y) R% Z( c) l$ X// Internal sounds
$ R/ b: ?2 {- C( ]#define        RECTANGLE_VOL        (0x0F0)5 r" K  v& z1 |9 ^" q, Y
#define        TRIANGLE_VOL        (0x130)1 X7 o' o* _  a& k
#define        NOISE_VOL        (0x0C0)
. b( O% k' q& I/ x% L#define        DPCM_VOL        (0x0F0)- v6 ^: w# V6 |& `
// Extra sounds
: s% u* T/ Y- Z5 c5 o3 Z6 q$ X#define        VRC6_VOL        (0x0F0)3 c, b: Q" i8 o% g; u
#define        VRC7_VOL        (0x130)
1 v1 N- `% a( w9 ?  Y#define        FDS_VOL                (0x0F0)
2 y) o- b' J" S' M: a#define        MMC5_VOL        (0x0F0)9 S# M& p$ F' l# R% z( W8 u
#define        N106_VOL        (0x088)/ C$ c2 V& V6 ?2 T1 O+ u
#define        FME7_VOL        (0x130)
7 w4 v" V0 ?5 i1 M  h
7 }( s8 |* t! t& A3 Y  mAPU::APU( NES* parent )
0 I9 b* L0 G4 \" x{/ \( y% _8 a7 f- R) a5 F
        exsound_select = 0;2 z. m& H+ l5 p. ]0 U2 `7 o0 u% Y# o! ?
% i- ?1 M  G2 n5 _) G& K
        nes = parent;
& x* L+ z6 F2 B: G  ]' s, J        internal.SetParent( parent );/ Y* H) s) Y1 @% J# t

8 w8 D* ]. h; n: ?. ^( R8 z        last_data = last_diff = 0;; v6 I% ]: |. T! J" R7 |
9 v4 E$ h; ^" z% v2 [* Z2 I2 O
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );2 L1 t5 ^- c# ~5 f" b; S9 u/ n$ a  G
+ U' _4 Z5 J/ N$ M! m
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );4 y  q' p$ T* _- C/ v0 u8 \
        ZEROMEMORY( &queue, sizeof(queue) );
7 _  P; G8 \0 H6 s+ b        ZEROMEMORY( &exqueue, sizeof(exqueue) );0 q* N, D% \! P1 ~) C

6 N- W% j3 F0 x7 ~        for( INT i = 0; i < 16; i++ ) {4 h3 p0 D. v% v, o, |' z
                m_bMute = TRUE;
3 ^$ a6 c! C  }9 i8 E        }( T* u. N% ]  S+ c. \6 ?$ m/ [8 ?
}& i) @/ x4 w5 n  u7 D. N. D( e

) [. P1 [: V" E+ B$ o) i" e$ ~8 jAPU::~APU()" z' T& u3 F1 V  p+ l4 J& K
{
: S# ]+ Z9 S9 ^: G; N' D}) W* ^# E5 B. }1 ^( Q

- X4 u+ G7 ~/ e* G' dvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
$ ]( P4 O& l( _3 |{# X* y" E4 z  ]
        queue.data[queue.wrptr].time = writetime;5 {/ ?6 Z- ]% Z" A. Z1 l9 Y
        queue.data[queue.wrptr].addr = addr;5 X) @, K2 E! x* M% C
        queue.data[queue.wrptr].data = data;7 o3 @+ b8 e) g3 d7 P
        queue.wrptr++;/ i8 Q7 |7 Z: R; A% h
        queue.wrptr&=QUEUE_LENGTH-1;* T9 E; i  N: q/ O3 d
        if( queue.wrptr == queue.rdptr ) {
, g9 a: Q& I7 c) e/ |; \$ F                DEBUGOUT( "queue overflow.\n" );. [. w# b1 S$ y5 ~+ q2 q' Z
        }5 F2 z% \. k( \6 Y' o9 K9 |
}
6 x# ^5 |8 ]- n. e. B4 A
+ l  i3 h; X4 w3 V; S* SBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
: {. J- l, u2 k4 t/ Q' K{/ j7 s4 j1 _% {! M5 V, n: k- X- F" T: @
        if( queue.wrptr == queue.rdptr ) {
7 S# x7 K" w$ B1 E* \                return        FALSE;
% T2 O* C3 x0 \! `1 A2 l7 p- G        }
- m# c, \/ h/ l' O% g        if( queue.data[queue.rdptr].time <= writetime ) {2 H& p7 {) @9 a$ @
                ret = queue.data[queue.rdptr];' i5 ?. G9 J+ d) c* L$ N
                queue.rdptr++;! [* Y( o: I! y/ t2 {6 K* ]) N
                queue.rdptr&=QUEUE_LENGTH-1;
) Q9 f6 h; p+ Q' K" k                return        TRUE;
7 D3 X; m' G1 |        }2 F. g! f3 ]. t  V7 k
        return        FALSE;& A+ u$ r' K+ P0 l# Q
}
7 @/ r% R( x7 p  G4 a: c% W! `7 B$ K& O* x* I3 C  `1 v
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
; O8 x4 \0 T: z9 y) Q{
. c' }2 ]. u( w! q3 c& j# \; @: |        exqueue.data[exqueue.wrptr].time = writetime;
) N$ y2 m0 m6 V# @' Z) R1 }% ~        exqueue.data[exqueue.wrptr].addr = addr;
' h' e0 I2 U% ?        exqueue.data[exqueue.wrptr].data = data;
+ a3 r9 m5 E% Z        exqueue.wrptr++;
9 o) U7 c3 D6 P        exqueue.wrptr&=QUEUE_LENGTH-1;
, p1 W0 W) N1 d! I0 h9 W' ^        if( exqueue.wrptr == exqueue.rdptr ) {# r6 v" ?& t- @! e' v
                DEBUGOUT( "exqueue overflow.\n" );
+ x' g2 o6 T- \: a2 Z! n; D7 }- S. V        }) p) ~& F8 N5 F4 e
}
! S# c9 k) t* s+ j  A( R2 H9 c9 m" Y: `& N
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )+ w4 v. P% I- L, X% {! R0 u
{6 a* ~' d2 q* s/ e9 t6 w/ X( D0 p
        if( exqueue.wrptr == exqueue.rdptr ) {
+ b3 _, b6 B1 t" K! ~8 @                return        FALSE;
; b: r1 y* u4 M$ x4 l* k, ~        }
" x& ~: O' _9 A! s9 U        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
$ f) x8 w$ ~+ t; {' B                ret = exqueue.data[exqueue.rdptr];
0 U1 }! J% h& y+ k& x                exqueue.rdptr++;: j8 Z0 ?& e5 x2 E' w( C
                exqueue.rdptr&=QUEUE_LENGTH-1;6 s  U% _, A3 ~# r( i6 i% G
                return        TRUE;0 [4 X; l, [) k9 `5 R( r" S1 I0 k
        }
2 g( C: _3 Z3 Q+ G" y        return        FALSE;
2 |0 u6 v- U9 h/ x}
0 u/ G5 y: y! D$ m" m
2 ~% B" J- ?3 E2 S; Ivoid        APU::QueueClear()
, P$ g- s8 E! z# g/ q9 R{
& F* v  r9 L9 D  w4 ^        ZEROMEMORY( &queue, sizeof(queue) );
* Y5 _- l9 \6 [% g$ o        ZEROMEMORY( &exqueue, sizeof(exqueue) );
6 H' a# y: I. x% d- l) {}
* z8 w5 s" K0 }9 c7 f. }
3 c  P' ^8 G8 x! t, L, U9 K6 a$ A% Nvoid        APU::QueueFlush()1 @  [' E, A% d7 f% V8 ]3 P1 P, R$ M) n
{) W: p3 c/ R+ Q: Q
        while( queue.wrptr != queue.rdptr ) {
" d9 j$ O" Z$ ^0 _; _                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
2 @) o1 M$ B/ N                queue.rdptr++;+ @4 O( Z4 b% P4 h/ j
                queue.rdptr&=QUEUE_LENGTH-1;/ }/ `9 ]' @5 n' |! s
        }  n: j$ f" y; ^& {* {' w# L7 A9 x
+ ~' g- \1 t5 O: u
        while( exqueue.wrptr != exqueue.rdptr ) {9 R7 E) N) I; Y7 M
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
" E2 Y$ g+ V; b                exqueue.rdptr++;; }7 y) Q9 i6 T9 ~4 D
                exqueue.rdptr&=QUEUE_LENGTH-1;
" R5 F: }4 W! I- |        }
( a6 L0 u5 J: ?% |8 s/ y}; ]5 j8 f( F0 F+ P  T# F  Q4 q
+ z! t: F( r9 P8 _" u8 ]1 w, [
void        APU::SoundSetup()! `0 h/ b4 I" S; U
{" t. }  |' z: k* t& C1 V
        FLOAT        fClock = nes->nescfg->CpuClock;3 w+ ]* D0 H6 k3 w; g9 d
        INT        nRate = (INT)Config.sound.nRate;
) q* d& \* X# p7 C8 n) w2 J% N        internal.Setup( fClock, nRate );
; p( B* _' P' W$ D8 S% ?. o5 [        vrc6.Setup( fClock, nRate );
7 V, b3 t& g3 E# e- r        vrc7.Setup( fClock, nRate );
( W0 c$ {: j- r' q        mmc5.Setup( fClock, nRate );
  P8 x( s; e5 c        fds.Setup ( fClock, nRate );
  X& y1 X" m7 u7 O( z1 _        n106.Setup( fClock, nRate );) K9 i/ v. @$ ^# [* o
        fme7.Setup( fClock, nRate );
4 p$ W" r- x& J& e3 W# Z* s* O6 e  U}9 o: S" k' }' C' i; S# D8 j# p. ^
0 s/ w) T3 z5 T7 |) E' ?
void        APU::Reset()
9 X& h5 b6 P- L# g- T& Q- C. s& i{
; Y  E1 e8 Z* B, m1 P        ZEROMEMORY( &queue, sizeof(queue) );5 h1 p" p: S+ |. K- m+ I, y% A
        ZEROMEMORY( &exqueue, sizeof(exqueue) );' I4 r: A2 P, F' w

9 S; p( _1 x; I4 C1 M        elapsed_time = 0;
) g& z: ~) h5 {- S! `: u5 M, ^& b4 X' V" u- }! |
        FLOAT        fClock = nes->nescfg->CpuClock;7 _& ?2 r& z' u  o
        INT        nRate = (INT)Config.sound.nRate;
: U) `# b* K" K( N        internal.Reset( fClock, nRate );
4 [7 E! X. ]# ~/ I3 V0 I, J        vrc6.Reset( fClock, nRate );: n) \' j8 t$ b; u5 w- }
        vrc7.Reset( fClock, nRate );& z8 X( b5 J8 r5 ^. a! p( M
        mmc5.Reset( fClock, nRate );% Y6 s% _3 e! Y$ U9 m0 p- U
        fds.Reset ( fClock, nRate );
6 D$ Y6 @/ H3 z+ t! Y        n106.Reset( fClock, nRate );  N. x  w3 ]: c2 M/ b
        fme7.Reset( fClock, nRate );
/ @$ o9 @3 k8 c! @& V3 M7 I) O% @6 ~; L) ~) y
        SoundSetup();
% u% f# ]" R+ x) d( C& S}0 b8 v" i2 a, y( }' E, [& s
% z  v5 u2 e$ r" K% l  Y
void        APU::SelectExSound( BYTE data )
8 L/ ?' r3 I! ]# h" F{
2 m. t! X% \* p' F$ f" b4 j; s' o" z        exsound_select = data;$ B1 \! l( k8 U
}) M2 o( q8 G( K+ T& B5 s! i7 |2 K
* S* a" J' t& n6 a. ]! }
BYTE        APU::Read( WORD addr )
. o- \/ u( E9 |8 t- ~/ A{
) ~) o) w7 m- o9 [6 T0 m  J1 N        return        internal.SyncRead( addr );
  ]: M! n- T3 b& c}
' H) h3 X+ {; R3 U5 T
5 }5 q" m. p6 o/ Ivoid        APU::Write( WORD addr, BYTE data )
) }- {4 l, U* ]{
9 ]& c& J& m, e1 T+ ]% P, B5 V        // $4018偼VirtuaNES屌桳億乕僩" I4 H& v3 n1 n  d+ p
        if( addr >= 0x4000 && addr <= 0x401F ) {4 T, q* Y( r- B! w9 }
                internal.SyncWrite( addr, data );
% V! H6 o* I0 ?! s/ s! k! [# k                SetQueue( nes->cpu->GetTotalCycles(), addr, data );5 |" ^4 V" B( N: o/ e3 k
        }1 Q2 i. h2 o5 M: Y/ l% i: u9 a
}
  ~7 I$ [8 h0 ^
; t2 |7 E' Q: a" Y' j4 {$ H" BBYTE        APU::ExRead( WORD addr )( z; I0 u) h5 U2 G" w4 m2 N
{* Q9 I& i1 ~7 f& ?+ w; o
BYTE        data = 0;
+ `/ M  i0 ]7 b7 T# @
! w4 R( Y( d. f6 ^! d# [/ n. s        if( exsound_select & 0x10 ) {/ \4 ?5 t0 u* D( m0 h) F2 F$ ^
                if( addr == 0x4800 ) {3 j4 Z3 O. I/ ^! _  Q- A
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );: f) L( a% }" I2 {1 I9 h
                }
, }+ Q" h! e9 ?0 q+ L* O# M' J        }
2 B: N- c5 M4 K9 ~% V        if( exsound_select & 0x04 ) {
) d5 y' j6 d, H: K' D. q! C                if( addr >= 0x4040 && addr < 0x4100 ) {
# Y. T( I/ N/ T& B! ?2 Y                        data = fds.SyncRead( addr );" W) C$ ]6 N6 E! e
                }
  u) e; T: `, @% f& X% x        }, _+ D9 ?0 ~  F0 u* D
        if( exsound_select & 0x08 ) {
$ f5 [- l; n$ f& f) d! J: x- B& ]* L                if( addr >= 0x5000 && addr <= 0x5015 ) {
5 M' R3 K' P% }4 \( e$ a                        data = mmc5.SyncRead( addr );. D/ Q3 I, q9 O( _
                }
) X: ^4 x7 w' u        }. r) E; Z# [! P5 h* z

5 O, d* X1 M# n$ |" U5 V  j        return        data;
- t+ b  Y! [) J- B: \' A( @; a}3 R  {3 W  g6 Y! D  l5 b  E

! w( d4 H. m8 R3 Vvoid        APU::ExWrite( WORD addr, BYTE data )7 T: R' \) n$ U0 n8 @! `+ M- \0 {
{
8 s. A8 ^! G! `) R& U/ V' t        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
# q: \( l' [2 {, Q& t" M3 s" M5 y! R2 Q' T0 f( P
        if( exsound_select & 0x04 ) {
5 |1 L! P1 a0 \. e: V                if( addr >= 0x4040 && addr < 0x4100 ) {! U+ m& B( C+ i/ m. X% H+ D  J/ m
                        fds.SyncWrite( addr, data );+ Y" b$ x* _/ x3 U$ r
                }
2 z3 V1 k6 T$ b- J0 i        }
; D+ W( o2 n( H+ b# O* o& ~% I  Z. A8 {
        if( exsound_select & 0x08 ) {$ {5 ~7 n& J) _" G* C1 u) E
                if( addr >= 0x5000 && addr <= 0x5015 ) {' ~0 [! n9 V3 v2 Z+ Q
                        mmc5.SyncWrite( addr, data );9 Z2 c/ d# t/ }' w% E) l* n
                }
: Z  }0 s, e0 L# |        }. \! O; i* q( B; u. \
}2 c; ^7 U7 A2 c" e& K$ `4 v

1 G2 s" |: ]; B9 E$ Dvoid        APU::Sync()3 Y0 l6 n$ a+ R
{
- u! `6 D. J3 {5 i( h* i2 w  e# }}
* w: `. a* w4 G3 E5 S4 g/ P
( u6 E3 o) [" ?  l" t' Zvoid        APU::SyncDPCM( INT cycles )' A# b& {2 D0 J6 z) _& E# R" r+ X
{
) E! o: a8 k+ d% b5 M' o) d        internal.Sync( cycles );1 k, {: C2 u8 x- w, }6 ~
+ g& S7 b4 P3 ^* K
        if( exsound_select & 0x04 ) {! |7 e. m* J. v% y+ `6 Y
                fds.Sync( cycles );% P# |8 ?6 c2 n
        }- d+ M8 i) s  n) v/ }
        if( exsound_select & 0x08 ) {( j" ]! c! Y0 j
                mmc5.Sync( cycles );5 u+ o# ]2 T& F3 M9 q3 I8 U
        }
# r; }: N# W  g}2 X+ X3 t; J* f

2 N! |  w6 G' v( V" Ovoid        APU::WriteProcess( WORD addr, BYTE data ); t; i& V2 q. j% b' B2 X
{
, i$ b5 d$ s5 t7 @0 I# `        // $4018偼VirtuaNES屌桳億乕僩
! {8 L# v4 O, k$ h        if( addr >= 0x4000 && addr <= 0x401F ) {; H% G' a1 _! a% D; K6 s% J
                internal.Write( addr, data );
7 @! r( q& ~4 H* z$ A5 Z        }5 @( s$ L, ]4 _" V7 i' q: r" j; d8 y
}
' U) ]8 M$ ?7 l6 m$ O6 c. I% f0 g* c2 I8 ?) `0 f
void        APU::WriteExProcess( WORD addr, BYTE data )
3 A, _$ M' s5 q. l" y' L{. z8 H# \7 v, r) o1 Q; j
        if( exsound_select & 0x01 ) {
1 F- I3 K7 R% D/ y9 x                vrc6.Write( addr, data );/ ^( t+ G0 C' U' f
        }
; e- D, y9 a$ o( }        if( exsound_select & 0x02 ) {
9 m% J  B7 L( P- a% [" c                vrc7.Write( addr, data );
7 u' h' A9 P/ X        }
6 l% ~& Z. J) v' S        if( exsound_select & 0x04 ) {5 z0 t' u2 a6 @% B5 _/ \+ M+ D, ]
                fds.Write( addr, data );
) W, `  ~' y$ G        }
' J  d' j% o) G  q, Q- ~        if( exsound_select & 0x08 ) {
& W( u0 }! k3 H  k                mmc5.Write( addr, data );4 h. G% X+ F9 L& L' H$ h$ n
        }
: d: X2 v) Z- w        if( exsound_select & 0x10 ) {; J9 T  A! q7 b, }. t6 R
                if( addr == 0x0000 ) {5 _* I7 o3 L1 M
                        BYTE        dummy = n106.Read( addr );' B# n1 V0 C) q" E4 S. r$ A
                } else {5 M/ V# b: u" l2 Y8 c" Y
                        n106.Write( addr, data );
4 l8 r5 a5 v3 P% ?* U6 d% J7 L! \                }
6 t3 P) `5 K. V8 A9 p+ M+ [        }
$ u1 h* V7 F0 W- O        if( exsound_select & 0x20 ) {
6 x( o- ?# X4 e0 A* o' U& f                fme7.Write( addr, data );
6 x3 M% G# h9 |        }. N1 ^1 F' W: U3 R! @1 H* z  M. N
}
- l; q: t6 N/ f5 p2 [3 W* o" `% L, D5 k8 t* I5 i
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
$ [6 b+ Y3 J- Y  L9 Y- ^{3 o! i  ~/ q3 Z
INT        nBits = Config.sound.nBits;
$ E9 U4 F) J. k9 b; uDWORD        dwLength = dwSize / (nBits/8);
+ G7 o2 v1 E2 s* yINT        output;
" _& c2 l9 Q; ]; J& X: _QUEUEDATA q;
) y% i5 b* A/ lDWORD        writetime;, W8 O, n# d( K( }
  ~7 L. r9 N# F% u
LPSHORT        pSoundBuf = m_SoundBuffer;
" z; G, V) n0 q$ RINT        nCcount = 0;
2 Z- g! L( U9 c( N
; U% ^( V. m) [INT        nFilterType = Config.sound.nFilterType;9 ^8 V/ M$ B6 f9 r' o

" c' T6 W# Q! [0 ]  a        if( !Config.sound.bEnable ) {9 c5 D. P) b0 w9 V( K
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
/ ~) U9 H+ a1 T                return;3 X& m0 A. B2 f
        }2 {6 f2 H5 L  Q9 r
% a" j7 K8 v' E5 d/ m" U
        // Volume setup
8 \  N. c$ ?4 w- }8 Z        //  0:Master% t. t' c1 O/ @& H' F
        //  1:Rectangle 1
* b& F" N7 f0 s  y5 O1 p        //  2:Rectangle 2
5 Y$ r1 ^' R. Y  s" u# Y        //  3:Triangle
; V$ k* {0 s+ U        //  4:Noise1 ~" n. `- h; l' r
        //  5:DPCM$ P; Z+ P# k  _# l. V
        //  6:VRC6
& F! z  P: f. |) u        //  7:VRC76 f5 t, G5 H) ^/ R1 ]
        //  8:FDS
7 d$ v/ f. g' a3 ~, n% q- _        //  9:MMC5/ u- _/ v& A6 @- o4 R8 H- X
        // 10:N106% c& L& D  V7 T+ F
        // 11:FME7
9 N, m3 ^8 _& E0 i; E. h$ a0 Q        INT        vol[24];2 v7 G  F$ P; K& [- V) W5 S
        BOOL*        bMute = m_bMute;; V! C0 R  F& p
        SHORT*        nVolume = Config.sound.nVolume;
* ^$ q" D7 M/ p$ z; T  y" v9 V
4 G' f! ^. b$ }" D; M        INT        nMasterVolume = bMute[0]?nVolume[0]:0;$ T" h1 p' g! Q

( {7 B3 a* H  l; ^0 h) ]6 T- Q        // Internal* p' v2 V  _! z% |8 b  T
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;" H" [  C$ f- I7 h4 d( d% D
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
+ ~5 H6 W; c" {        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
5 [* k; l* ?; G- k1 i$ p( l        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;( c9 {3 t& R3 L# ^. R
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;8 g: y! D" @5 H( \0 M9 A; e3 R
. A0 Q0 [% g+ \2 U0 Q
        // VRC6
+ f: W6 y6 y# u! ]* `2 Y' E        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;0 N; t6 i" I& H( n: d
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
) b1 Q4 ~: N$ N! Q# \        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
" S4 @7 X# O. X
( m6 d+ v& Q7 p6 D" ]+ s        // VRC7$ |5 K; b$ N* O! H5 U, c
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
. w; V: ~$ x3 L' ?$ u6 d4 a
/ \3 O0 E9 t8 J& f6 O0 @0 J5 S        // FDS
& f6 F' }4 k, B: d# R- r0 X( z( I        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;3 x0 i, P) b3 Y7 ~! ?

( Z+ d1 t' u$ [# q2 v" U0 ]        // MMC5$ A  f, M) `3 c) Y8 V6 v& }+ A" ]3 [
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;+ `  Y, I$ G. ^3 d! M
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
' t# o3 m4 S6 a  r. f; B! P, w2 V$ x        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;! Q, g8 ]* W1 T: Z$ f1 \
8 P3 u% X# U% H; a/ N( ~
        // N106
) m/ K( r& x5 Q% M6 U        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;/ E. W! Y: C5 Q  n* S; Z1 _
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;( S( y# D0 d, Y9 y; X4 e2 X! G( t
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
! ~6 S" G% p( S. |9 b7 O        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' A1 g/ s6 Q* {  I
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; l- X2 g& V7 C; m  T) X& b
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
' y4 x1 E8 \$ \4 }/ u, i, q# W  F6 |2 `        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 M- @9 J$ u* u, Y1 ]
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;4 P% j' z6 j; B( c& L
9 L1 p/ X% V$ u" ]) U% O
        // FME7
# ^: `1 ]+ R" }4 U3 q+ g        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;! d, Y& o% j) `3 R( R
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
. s& g' @- w. b8 X. u3 v        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
- O5 G1 H: @. |3 q9 i5 ]
! U8 Q$ p/ y5 ]" T//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;3 Q8 k) g% ?% \4 s7 Z
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;) T! A8 Y( V7 \

4 d$ t0 V+ o" v$ y0 Y        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
3 ?( \# g0 Z- |3 M; E) T# b        if( elapsed_time > nes->cpu->GetTotalCycles() ) {- O' S( X4 F  m/ @
                QueueFlush();* h8 P/ [  Z* o1 F
        }
. y# ?- G4 Z2 m& F$ i5 f
, Q3 i2 W( X# _6 g7 h        while( dwLength-- ) {5 f" x9 y+ O/ }/ s" T6 H
                writetime = (DWORD)elapsed_time;
. n* i- j7 F% Y7 q$ g  J( n( E3 K  T
                while( GetQueue( writetime, q ) ) {( }; n. n. Q; Y9 x; L
                        WriteProcess( q.addr, q.data );, a5 i. Q( h5 \+ Y
                }# q/ S9 d5 Z. W# z* ~$ B

' S& V% a, N* W: P                while( GetExQueue( writetime, q ) ) {
! z2 R) C$ i: m0 p- n0 `  h- ~                        WriteExProcess( q.addr, q.data );
$ a! l, j1 W# \( M( L                }# F+ T5 \5 B7 X4 B7 D  @9 i
; l2 l) h0 `0 ?0 B8 w; I$ _
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
6 ~: H* {! n  ]7 F                output = 0;
3 c+ F& y$ Y# f/ [9 S                output += internal.Process( 0 )*vol[0];
) y& t2 V3 \7 @5 A                output += internal.Process( 1 )*vol[1];  `& o2 m% v* ^9 m0 Y
                output += internal.Process( 2 )*vol[2];* \9 \: H% q9 _) Y
                output += internal.Process( 3 )*vol[3];5 ~( ]! c: L9 Q
                output += internal.Process( 4 )*vol[4];
! J: M/ k( k9 V- Z; V$ C' U, a
3 m  ^% k8 h, P# \: X                if( exsound_select & 0x01 ) {
' x0 Q4 z  \. ?( L* o                        output += vrc6.Process( 0 )*vol[5];
) S3 E2 `. b" \( j                        output += vrc6.Process( 1 )*vol[6];% U# ~* L# A5 p+ S3 C9 e: s
                        output += vrc6.Process( 2 )*vol[7];
) ]: v2 M8 p4 S2 o$ ^2 c                }
3 T& S0 Y: ]" y+ _6 x, B+ F5 \                if( exsound_select & 0x02 ) {
  U3 _, n: f# l8 M6 @& |                        output += vrc7.Process( 0 )*vol[8];
7 W4 V: N  [* z7 ^1 e. H6 M+ U                }8 D) K. w# G/ `( E  y7 O5 ]$ p
                if( exsound_select & 0x04 ) {. ^: P% h2 C! R1 o  w
                        output += fds.Process( 0 )*vol[9];
4 n2 f6 S1 U4 T' g                }
: q  H! o* k3 r0 Z+ q1 D" ]                if( exsound_select & 0x08 ) {
: ~+ X$ W& L* a5 g1 k1 X" c8 H& h2 L                        output += mmc5.Process( 0 )*vol[10];
4 y: @% o( H1 k) F+ V/ O& T/ n                        output += mmc5.Process( 1 )*vol[11];
( l7 Y( O9 J0 B$ m                        output += mmc5.Process( 2 )*vol[12];
% w# K) {. n4 n" r2 C# W3 ?                }
$ o) H1 x0 R3 k                if( exsound_select & 0x10 ) {
( n# ^5 H3 `# R& m  f& J3 t2 U                        output += n106.Process( 0 )*vol[13];/ F( ]' @8 j9 ?6 }9 G2 |* f
                        output += n106.Process( 1 )*vol[14];' O5 ?$ G/ A6 i& v# |+ Q
                        output += n106.Process( 2 )*vol[15];
. G4 e0 l" p% B- H3 ^5 c6 b; {$ f                        output += n106.Process( 3 )*vol[16];" p/ k  _9 ~8 V; L: D# T
                        output += n106.Process( 4 )*vol[17];& E) ?* J: Y( \; `5 |; C, P
                        output += n106.Process( 5 )*vol[18];4 Z$ X) l$ Y# z% F; w
                        output += n106.Process( 6 )*vol[19];
$ }: J/ v- e% g- Y                        output += n106.Process( 7 )*vol[20];) ]8 A7 N' L5 c" w
                }
- P& [# z, }# v5 M' `                if( exsound_select & 0x20 ) {$ ]8 K- f' s$ s
                        fme7.Process( 3 );        // Envelope & Noise3 J1 l6 a1 J; ^7 s! s
                        output += fme7.Process( 0 )*vol[21];% C8 N- d5 J+ y- Y* k( q) i
                        output += fme7.Process( 1 )*vol[22];' ^6 R6 J, X% S
                        output += fme7.Process( 2 )*vol[23];; ^" F' T- L- K/ c
                }5 n! c% [& x0 W+ ^/ S7 Q, o
- k% P0 R$ j$ q) B9 y' L' s
                output >>= 8;
2 V7 ]/ |6 s  B' I. Q6 {+ g5 ~! ?) D) n, w
                if( nFilterType == 1 ) {
& w/ K1 I" E9 ^2 R                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
4 D* E. V1 R  A( y/ a                        output = (lowpass_filter[0]+output)/2;
" A8 o! W" E. c8 T, S& Y1 N. {4 Z$ u                        lowpass_filter[0] = output;
6 g" s/ |; a# ?, |# t) i                } else if( nFilterType == 2 ) {
& k# u, s) ?; J, l5 d3 A5 K' Z                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
/ `0 Q. |2 @& A                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;! f! E% U8 ?/ ?- v& r# f
                        lowpass_filter[1] = lowpass_filter[0];
3 c3 [+ X, C6 G$ d+ J0 Q                        lowpass_filter[0] = output;
/ O+ b3 U; [* @7 k2 i                } else if( nFilterType == 3 ) {
$ {7 G2 ?: l. S' L% }                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)( a+ q9 U. }1 M. c  d) a: Z# K
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;  U8 y1 K1 P. S* X  t
                        lowpass_filter[2] = lowpass_filter[1];  m0 I0 _* Z2 b8 C4 ^5 d
                        lowpass_filter[1] = lowpass_filter[0];
4 x+ A0 a7 W, ^/ I! i6 T& _5 ?                        lowpass_filter[0] = output;* ]0 O; ]* h, I" L% [) F' _
                } else if( nFilterType == 4 ) {
% J: c+ u/ V- z6 ^& X  ~+ `                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)) h0 E1 N1 ^' O) d" p+ L& V7 Y
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;" \* X5 p' S2 l( D; R7 h% I9 `
                        lowpass_filter[1] = lowpass_filter[0];
/ I3 @: b, c! r2 @/ e0 M  l" t" x3 ~                        lowpass_filter[0] = output;
6 Y' B" c: }. @                }
" C8 K+ Q. [! X+ v
4 V6 u# k7 C2 a1 c* ~  J#if        0- p1 y( c6 T1 _( p1 `" n* ~
                // DC惉暘偺僇僢僩5 u6 T% K) Z5 {2 B. [! v" e
                {) v6 `4 V& L) z+ l5 h4 g8 c! I$ {
                static double ave = 0.0, max=0.0, min=0.0;
2 R+ j* t$ a, W; Q4 B                double delta;
, [$ D+ J, O  y  Y0 E                delta = (max-min)/32768.0;
1 K5 i, B( Q, _                max -= delta;
4 G, ]6 B# F& U) A8 C2 {! c. L                min += delta;. F1 _3 ?1 _% i9 R0 C
                if( output > max ) max = output;9 o  Y, m6 S6 {1 b3 ~
                if( output < min ) min = output;
" c7 r, U7 A2 g/ B* o+ F  I                ave -= ave/1024.0;# f1 i8 \$ Q$ d9 X
                ave += (max+min)/2048.0;: N' @2 h5 ~4 J% S$ q: F
                output -= (INT)ave;
7 C$ ]2 z& W  G3 X% D                }
  a% h- G& T" O#endif3 I) B5 c% I4 c+ y/ [5 O/ O, t! l( K3 g
#if        1
* J; f- w# [) W3 Y( \! F                // DC惉暘偺僇僢僩(HPF TEST)
  v9 C* E" R0 d2 I% J                {( \+ g9 g# n8 r# P
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
* ]: W- Z; v5 @1 J                static        double        cutofftemp = (2.0*3.141592653579*40.0);
: \$ ]' {1 M, `8 k* G                double        cutoff = cutofftemp/(double)Config.sound.nRate;) B5 H  J5 n1 O; C
                static        double        tmp = 0.0;
% f$ L4 H5 U1 A* a# h; g                double        in, out;
/ h; C5 `. u, v* }, H' X0 D2 W( c9 }8 m" C" f& z$ h, r3 F2 f: O
                in = (double)output;+ U! @1 g5 ?% p* G6 O7 S" L( g! q
                out = (in - tmp);& g" B0 f- I. B' U0 W7 [
                tmp = tmp + cutoff * out;
& Z0 Q: k( d" R& u0 r7 |" }6 ]- h8 ^  Z- `, Z
                output = (INT)out;
: g6 C7 g# O+ j2 l8 \. Y: t, V7 w6 {                }8 x1 R( k- L, a6 v! Q+ ^! w
#endif* c  O# h# R+ W8 n* ?
#if        0
$ K/ z- f# C8 l* s+ P                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
$ j. s: w3 O6 U+ G% ~/ y3 B                {0 H8 @, P# S* ^1 ^$ I3 N9 |7 u$ Y
                INT        diff = abs(output-last_data);
/ {  X% k# R5 Q! u                if( diff > 0x4000 ) {1 \& U3 R! a; u, n9 U
                        output /= 4;
1 V& F! b' }1 l5 y6 k6 n: g                } else
9 W: X% L5 ]1 ~* W" [7 p' H                if( diff > 0x3000 ) {9 E! G% P% Y8 H
                        output /= 3;. h5 P4 |& W1 o
                } else! g1 c! H4 f7 b+ R6 H9 ~1 L4 r
                if( diff > 0x2000 ) {
- G- a9 J/ Q& U, [& f$ X- Z                        output /= 2;9 h- z( c6 L6 u
                }) i0 Q  j' F' N2 O3 l, u% a- W
                last_data = output;
3 q! ^( }: u5 D, E+ _                }( ]* o1 c3 y$ L
#endif+ y, @3 ?( t1 }( V! `( w/ {
                // Limit* }1 H9 O- B3 p, F2 d/ n
                if( output > 0x7FFF ) {
8 c# z; t( n( I2 `. W) p& E                        output = 0x7FFF;( L# R9 _  V$ k! i+ B- S! r5 A6 y
                } else if( output < -0x8000 ) {
# p: ~9 k2 y3 g' K1 H0 ~9 R% W: z                        output = -0x8000;
$ t. a7 H7 g0 d, c- o5 C                }
  E" O) I9 n% Y+ F5 |4 c4 L& e
. z' J7 p& z3 Q9 P2 x, y' K4 _                if( nBits != 8 ) {6 g: b2 @$ J0 v/ M6 _
                        *(SHORT*)lpBuffer = (SHORT)output;
- `; G8 o3 p* W/ [2 U                        lpBuffer += sizeof(SHORT);
# V5 _& ?* w' U. T                } else {. T, |8 K# t# }" V
                        *lpBuffer++ = (output>>8)^0x80;7 `" l, c! M. p3 P5 i! [
                }2 H# g* R0 }  g

- x! M) g: j9 B& c& ]                if( nCcount < 0x0100 )) I8 q" R0 M+ ?  _6 e0 _* u! f# L
                        pSoundBuf[nCcount++] = (SHORT)output;
9 u) n+ _; \) w
. A# |% F' d- A//                elapsedtime += cycle_rate;
- C$ t; B1 t+ {2 E7 f# t* ^                elapsed_time += cycle_rate;
- {+ c$ V9 `$ v+ {  W        }
' W* Y1 a2 E4 V5 Q1 k7 q' e
- q. V$ |  M3 q$ G1 y3 U; P#if        1
7 t: X$ B2 X% }( t" r& z7 U% F        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
; Q( |, C* O) ]; q7 w( H                elapsed_time = nes->cpu->GetTotalCycles();9 u" w; ^/ d$ [8 w/ g7 J8 e5 @
        }
8 |- z& E+ l) G$ `2 [        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {0 k  b8 `$ X. b) c9 N4 [9 `
                elapsed_time = nes->cpu->GetTotalCycles();! N6 ~, o1 g4 K: t
        }  O9 G$ i/ D+ o% V
#else* k* ?7 x+ Y# [  B. K- A
        elapsed_time = nes->cpu->GetTotalCycles();
  P+ U& ~: t. O7 Q" @- t3 U" j#endif
  M. C/ O3 i! U}+ N- E) y; e  i) s
& H8 k4 q. Y2 F- o7 h4 v
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
) T  S  Q9 ]* w; e6 _INT        APU::GetChannelFrequency( INT no )
& o0 f7 Y( g$ T0 C8 q/ w{
' S& m# D( |0 }        if( !m_bMute[0] )" d$ F0 X4 L& c
                return        0;
: F) v4 q# x9 ?9 k7 d8 \
; l9 @, P/ `2 _' l1 f  y3 p6 Q        // Internal) C" X& v+ P1 g# z
        if( no < 5 ) {
/ J! j0 U% `; }. ~# [" V8 v7 w                return        m_bMute[no+1]?internal.GetFreq( no ):0;
' O6 ?; x. m2 n+ ^5 C" U5 i; [1 C$ L        }
8 B+ v/ i8 c8 R( i( V  }- {7 b" H        // VRC6
/ O1 T1 f3 s# \4 \2 K& r' D* l0 q9 J# [        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {# H: t/ ^3 m8 u& ]# a: X3 r, o
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;7 N$ i: A" j7 v7 l1 U3 n
        }
; [( {, i3 ^1 ?9 q( ]- a+ _        // FDS
8 L1 h. E0 [- B! Y: p( y        if( (exsound_select & 0x04) && no == 0x300 ) {* j1 a5 @3 H0 x( l/ u0 x6 p( E. f
                return        m_bMute[6]?fds.GetFreq( 0 ):0;( h3 W9 ~7 @) b, h
        }
. h; W3 Y( b8 ]3 p: e0 F        // MMC5' U5 s1 p/ P$ V- O
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {2 d7 [& v" x6 ]( F8 |! X
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;9 b5 P3 v; k  w' W+ ]
        }! m6 F2 ~! I" T: r7 A$ ~# U
        // N106
4 m& r" i; z0 I# Z( h3 k2 s; ?        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {$ r! y/ V9 F; f9 u. j1 z
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
$ _# m; H  `; E$ H/ C        }
8 @1 p8 y9 b* r. [  O        // FME7
( T3 s. s) x* m7 {0 R; H, r        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
' y8 S- o: ~8 v! l! J: w                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
2 |, T2 |. l3 y# Y; U+ r+ o& v1 A8 B        }
4 S9 w1 M! [" H3 F        // VRC7
! l! U' T1 c/ {        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
4 x1 C% j+ _+ e5 V4 w7 y0 ~9 G9 q                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
! k. S. B5 i. o1 k; m5 ?! X        }
$ b# l4 O- ~4 O        return        0;! Z# I, G. U' E; D) ?
}3 Z7 N) A! g, l, w* w
7 c: f# @- r2 P% C, ~
// State Save/Load6 ?$ G2 p4 d) t4 c/ h3 L0 C+ g
void        APU::SaveState( LPBYTE p )) z9 q# m; o9 T* A
{
$ Z' Q/ J+ Q* m0 G/ k6 }#ifdef        _DEBUG3 j5 d4 n# C6 s: f
LPBYTE        pold = p;
2 h8 o! B5 d& R  Y#endif6 m* v# [; N' G3 R  R
$ t. e0 D  Y2 f% V8 u
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
. q  X  D2 D1 Q        QueueFlush();! g# O6 K: @- n  J

" a0 [& y6 W2 @1 R        internal.SaveState( p );9 F/ z% K, }& d
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
3 c% P* m6 Q% f/ G
- g, a( k  S; c- `* k        // VRC6
) J4 _9 L- T3 C1 C        if( exsound_select & 0x01 ) {+ U' J: p# s6 X' S6 _9 m
                vrc6.SaveState( p );
8 a) V1 Y3 B- |' [6 w8 B7 P                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding3 d$ ^. ^- \+ ~7 @$ \! K
        }
/ F9 p+ q: Z" R- Z' k( R        // VRC7 (not support)
/ b1 L9 \) G5 ?% j        if( exsound_select & 0x02 ) {
3 t7 L! A& ~; g* T7 ]4 s4 o                vrc7.SaveState( p );; P5 G; N4 B$ Z1 J3 j9 P4 C* x
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
: {! {7 [9 s( v- {- H+ @% d$ N        }$ C& s/ C4 j; _2 G3 i1 W$ M
        // FDS
' k7 Z" l* S. G  P( m& b( s# Z7 D        if( exsound_select & 0x04 ) {3 B; M, O- L% W2 F
                fds.SaveState( p );3 @9 r# B) h1 W
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding3 ]% o% {2 b3 H
        }
5 Z* Z, k( M2 a2 k6 d8 ^/ q        // MMC5
7 O! @6 ]' B* t/ B& Q        if( exsound_select & 0x08 ) {
, I0 r+ t  K7 U  k8 g/ h6 G                mmc5.SaveState( p );, E$ Q! o8 e/ C5 D
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
! L. I1 H" @& \9 R/ h/ W        }
, o" J& ?6 p# ~: x$ \        // N1062 Y# X0 }( j: f( y) Z$ A; [) l9 s
        if( exsound_select & 0x10 ) {
3 @7 w1 `6 k& {' f+ v, J                n106.SaveState( p );) U& y2 m7 m% L# a
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
9 h0 E* H, Q3 s: }. m, G        }6 b; v$ @; Y% ~4 T9 x. ~- w
        // FME7
; m/ G; G. e2 ~$ K        if( exsound_select & 0x20 ) {
9 a+ m! R9 }  u1 i% b0 v. v8 |                fme7.SaveState( p );" l  l$ j1 n( z! v( V$ s
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding# G5 E' n8 k; V6 i4 ^4 b: t; F7 J
        }
6 U% G7 V$ G# X* Y/ |! ^+ ]$ U/ @& @# C8 {+ [: _
#ifdef        _DEBUG
2 _1 G  e: i& A/ F5 t& zDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
. M8 a8 _% v/ t; ]#endif9 e* t6 m/ [# O; Z. g
}
) ], P# ?* w) [& }4 o! M  C% V1 ?+ Y
- Q. F  Q8 z+ {* M+ J4 {5 }void        APU::LoadState( LPBYTE p )/ f3 D0 A4 W! G$ A' k4 f* v
{
) U" k7 i% C8 q1 e' Y        // 帪娫幉傪摨婜偝偣傞堊偵徚偡8 z7 q: n2 z5 S& k
        QueueClear();/ T, F7 s9 d) v7 I
+ r) e& V8 u  K+ |3 I. C
        internal.LoadState( p );$ Q: C% g2 H5 ]/ D' q) G
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
' m4 g/ n2 P% d7 H" m/ H) q
, b; j7 d% I" t9 ]& H7 D' k1 n, o        // VRC6
% h  c5 T4 q$ r/ P8 p7 B        if( exsound_select & 0x01 ) {" W5 H, o0 W6 Z! M5 \/ K  ^3 v/ T
                vrc6.LoadState( p );2 ^- V; v$ t4 q0 T3 E
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding0 h& p4 d. L5 _
        }0 r* h& v0 h; a4 ^1 s; T
        // VRC7 (not support)/ _! _8 c* v& ^$ D7 Y6 ?) Z6 F
        if( exsound_select & 0x02 ) {
5 k# r1 y! n% ^                vrc7.LoadState( p );+ ^. R+ j: ~6 k' m  i. ]  |6 b
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding2 U) ^( R; Q0 f; l" M  g( k% c3 M
        }
+ e" A' S  p: v2 n: }- r: g        // FDS4 }8 \7 H* f, y
        if( exsound_select & 0x04 ) {
7 C3 G4 O& g0 L! k/ D4 P                fds.LoadState( p );  V5 e& W1 n; }+ e. ?) e2 n: @
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding' Y4 x) }8 I: L2 W) e0 @8 s" X
        }& ]  Z8 c) ]/ `! J
        // MMC5! R# s  Y2 j" X/ s, `
        if( exsound_select & 0x08 ) {
. P1 L  p1 J& |% }- [                mmc5.LoadState( p );
* R; d2 L, e  L. [                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
; O4 Y% D5 |  ^' S6 ~4 v, i        }
; T/ n+ Q" T5 o4 Z& n        // N1067 @% c1 V) Q+ f; L% a7 K
        if( exsound_select & 0x10 ) {
3 w/ ]0 k% h% {) L4 v2 U& a                n106.LoadState( p );
# c2 F- S& d9 D: L& a( a; e                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding) \* G! A: {! [5 p+ [& X
        }
. s3 @( {' x" \        // FME71 {8 i1 h! l! o& J' x$ B# u( _
        if( exsound_select & 0x20 ) {
) m" v$ s, }# X% e0 _, ]                fme7.LoadState( p );* I9 o# L8 e8 i1 z' i, H4 C' O
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding+ t5 F- z$ u7 x9 i
        }
* H& F! g- @6 g8 P}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 " t+ K. [. y9 A$ k
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
$ @7 @6 M1 K9 \) F感激不尽~~

% Y4 w8 {) E3 s+ h恩 我對模擬器不是很有研究,
( l' k% z: d2 v! S% ~+ q9 H雖然要了解源碼內容,可能不是很困難,
8 k6 a# u5 i; t% Q不過還是要花時間,個人目前蠻忙碌的。+ d) m4 l9 R9 `) Z
( O% g0 C& H  p( T: @/ G
給你一個朋友的MSN,你可以跟他討論看看,
  x( Q8 K% J# J$ K. }他本身是程式設計師,也對FC模擬器很有興趣。/ R1 Y0 `/ D/ M& F# Y# V2 y
# P- F6 ]$ _" }% u  y3 K
MSN我就PM到你的信箱了。9 M7 N. l, e& z9 B+ j6 {
5 u5 j$ i6 k7 k8 {# g7 u2 S+ S# z. r
希望你能有所得。

该用户从未签到

 楼主| 发表于 2009-11-9 13:23:59 | 显示全部楼层
呵…… 谢过团长大人~~

签到天数: 80 天

[LV.6]常住居民II

发表于 2009-11-9 16:02:29 | 显示全部楼层
团长的朋友都是神,那团长就是神的boss。

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表 3 A1 [' F1 S5 T8 A5 J% Q
呵…… 谢过团长大人~~

0 k  i3 C% c. s! X* _5 r# G9 [6 p) Z' R
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 $ |) _9 P' G  E2 U# @
团长的朋友都是神,那团长就是神的boss。

7 L, z3 O  E( K% s9 M# F哈 不敢當,我只是個平凡人,
) m7 p: [- Q+ w7 g要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
( C6 b& I( C  d$ h  AZYH
5 W7 v$ B4 m6 g; i" s' hQQ:414734306' P/ W6 I& C' B
Mail:zyh-01@126.com
/ p, b  A+ V1 V" ?7 u' ]
: g+ l( U2 R/ k1 v他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
- o3 E. o3 v2 ]) J0 {# @+ M2 w再次对团长大人和悠悠哥的无私帮助表示感谢~~

& R5 h  W- M. q" _不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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