EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
2 ]6 r6 o7 Y8 i- I' c楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~" h3 g9 z/ T0 g" Y0 ^- E
这里有相应的模拟器源码,就当送给大侠了~~8 E2 ^, ^7 o; t, ~$ R$ w' v' D
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
6 R& a! }3 l$ u- n9 e, h: L能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。* r" l$ F7 g0 O$ E  j4 q& L7 l
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
( R2 i5 K( F* u1 s这里有相应的模拟器源码,就当送给大侠 ...

  [  A3 V% U: L: `$ T( t1 T4 i  ~聲音部分(Audoi Process Unit = APU):7 S( Z5 d3 U8 u  }& r% e4 g
.\NES\APU.cpp
8 U) V* G9 v" I7 b8 |9 H( a! U.\NES\APU.h8 w. k  x0 w+ F  ~* E( _# U) K

1 v/ X2 t5 N3 ~( b8 b: y% S2 O
7 T, [5 h5 C8 c$ |9 e$ |影像處理部份(Picture Processing Unit = PPU):  `3 k: ~8 p6 B6 R! A
.\NES\PPU.cpp) q" e+ o& o! _+ J# D% ]5 r9 [
.\NES\PPU.h) C  U( y' p* n8 C( [7 n

# I% Z& v% b3 j7 S9 Z, u. R3 _如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:6 z8 O: A# D: x# E
(由于很多专用术语和算法机理都不明白,所以看不大懂……)6 [% j% {$ n9 X4 c6 ~
//////////////////////////////////////////////////////////////////////////4 w8 W- p9 ^( c- C8 M
//                                                                      //8 E8 m5 p7 w, q- a/ u
//      NES APU core                                                    //4 b6 ~  C- K8 R3 m; b* V$ J7 v
//                                                           Norix      //
$ \3 x9 u/ ^9 Z& Q/ O* M5 j//                                               written     2002/06/27 //0 A: t. v) }5 k1 s& w: t
//                                               last modify ----/--/-- //3 z1 u) r5 `& I: ~  z5 n
//////////////////////////////////////////////////////////////////////////
2 y, Y% p7 M" N#include "DebugOut.h"9 Z% a2 q4 v7 g! R2 [. z3 s
#include "App.h"
  W' C! \7 B  N) n  F) x6 @/ u7 L3 f#include "Config.h"( g( _. `0 M$ D
% U5 ]# O0 V& @9 x
#include "nes.h"' I9 m0 Z/ N) j$ ~5 a/ y
#include "mmu.h": Y) |+ G% r! ]
#include "cpu.h"* @2 A) w+ `3 x: t/ F
#include "ppu.h"
  M6 R* |9 z7 x; i- A9 Z#include "rom.h"+ S; p, Q9 x2 ~1 W' Y- c7 f* @
#include "apu.h"
4 W5 m2 H! H+ r" Q# K
% K7 Z1 P5 S3 E* O// Volume adjust
6 Y' \  Y6 Q/ c6 ]// Internal sounds) T; G1 y  M0 @* P( r2 w
#define        RECTANGLE_VOL        (0x0F0)6 o; \% z" f- @' s; O
#define        TRIANGLE_VOL        (0x130)7 K# z- m: Z+ i' L0 p
#define        NOISE_VOL        (0x0C0)
- p# x  X$ Y: V/ c#define        DPCM_VOL        (0x0F0)3 E. a6 o! c4 m$ L0 d2 [1 J, [
// Extra sounds
. K% T: i. r9 _& u: o#define        VRC6_VOL        (0x0F0)
* ~4 H$ R3 u! U#define        VRC7_VOL        (0x130)2 i$ G4 X" ~9 n" Y
#define        FDS_VOL                (0x0F0)
+ v0 h2 I& H' [6 U- q2 y#define        MMC5_VOL        (0x0F0)! `) e9 S) U7 [. c# H* q
#define        N106_VOL        (0x088)
% v8 D3 j% Z( d  S. Z#define        FME7_VOL        (0x130)0 m/ Z# N7 a7 h

7 A2 w/ O6 B: pAPU::APU( NES* parent )% z( F! Y+ [+ }2 J6 y
{# X. f8 b- g  c7 O/ O: o" s) r4 F# s
        exsound_select = 0;
- G* T8 w- m9 J1 M& n2 g0 j5 n  U: G# T
        nes = parent;: w* D* g0 A1 j: u2 b
        internal.SetParent( parent );  @" \0 [5 h2 L. |* L
2 M5 @1 l  M. A  n& H* a, u
        last_data = last_diff = 0;; q9 U* Q! J# C/ n7 j
9 c* D! `! k& u5 ^4 }/ h% q
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );9 B8 O3 j5 r& D) `. m7 G- {
& m, }! }  [/ {! S" h
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );/ g  _; t$ U4 m# V# X0 }3 O
        ZEROMEMORY( &queue, sizeof(queue) );
1 \% O$ C+ i1 G( h, z- a5 U! u  X        ZEROMEMORY( &exqueue, sizeof(exqueue) );
6 `& u( k; G# R+ m: d8 ?- c' B; I; C# v8 x# n. ?  \
        for( INT i = 0; i < 16; i++ ) {
0 T) E/ G3 V/ `+ {3 ?1 D% ?                m_bMute = TRUE;& u0 A2 h' W6 p7 @
        }% f- }! r* o. y  b; n* m
}/ B5 x0 T! j4 \9 `: K- q( _2 U8 t

* ~/ ^6 P/ X2 ?- K; u8 p/ }) ]0 y" ]APU::~APU()6 T- z4 t! k2 r1 g
{' X+ r" I9 s' w- y
}6 C) Y  P9 W- |
3 {* c' `% g1 O5 |" Q& \5 ]
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )5 v/ M  u  {' c8 G+ d# i2 J- G
{0 D& `) q5 m3 L! w6 ~' n# Z7 |
        queue.data[queue.wrptr].time = writetime;
( `6 [3 a& f  c8 R9 ~        queue.data[queue.wrptr].addr = addr;" M) t# A; w( G" X' M9 j( F: J8 `
        queue.data[queue.wrptr].data = data;+ W, I, {) T0 @" M7 b7 Y3 m" [
        queue.wrptr++;7 Y2 ?3 ~1 z  ]! H2 H3 t
        queue.wrptr&=QUEUE_LENGTH-1;) ^  W% \. T; w: |: v
        if( queue.wrptr == queue.rdptr ) {, E, I" c, A3 m+ x' l
                DEBUGOUT( "queue overflow.\n" );6 p  \. j* _5 g; r2 w
        }
7 v1 k+ X5 {( j$ d3 w}
% w6 d8 ~# e+ e( n, X! }
2 G+ V' H( T" ?  _( sBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
' W: V' {3 ~8 C# R' h. Z* u{6 d' a% x; p2 b( \" c2 L
        if( queue.wrptr == queue.rdptr ) {
% H: b7 {, ~$ g/ Q: M                return        FALSE;
  z3 X: u0 g/ K: x- A: u: X        }5 X2 Y& P- `' P6 j4 E% m0 u
        if( queue.data[queue.rdptr].time <= writetime ) {
6 \2 t: ]; d3 r                ret = queue.data[queue.rdptr];
- T2 e4 v% w1 H6 \6 N- X                queue.rdptr++;
  A5 n$ E4 h4 T                queue.rdptr&=QUEUE_LENGTH-1;
" {# f+ q& _3 m+ A. v0 K1 z/ ?                return        TRUE;( e5 u" p9 P: {/ f
        }
- y4 i: j0 v' f$ z        return        FALSE;
' b# Z0 \# |9 d4 @+ L}+ z+ B$ c( b6 A4 k4 ]$ L
) O2 i4 J8 q  r: m) r
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )' M4 e! u: t, m* y5 |$ |; w
{5 j3 H7 v: `5 p! n) n! R
        exqueue.data[exqueue.wrptr].time = writetime;; l: K/ t6 ^3 K6 j3 r
        exqueue.data[exqueue.wrptr].addr = addr;
( p( d; w6 {, T7 b7 G( V. u$ [        exqueue.data[exqueue.wrptr].data = data;
( g8 u. [' }4 L* w- ?' c$ h$ I" X3 J        exqueue.wrptr++;
# b* Y  c- [" O5 W; M        exqueue.wrptr&=QUEUE_LENGTH-1;, R4 X" \$ v+ Y' F( N1 v' H
        if( exqueue.wrptr == exqueue.rdptr ) {7 V! l3 C4 x2 C7 @9 V
                DEBUGOUT( "exqueue overflow.\n" );
' C8 T+ i( ?" Z. ]        }/ ~: f5 F  H8 h7 \. F
}2 o6 M. {; i. s5 m

$ r) b/ {. }  K: |4 O, w2 X3 r& {BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )1 v. @8 J$ ]  G$ F
{
% S* F1 i% }. q2 R; `: }8 Z        if( exqueue.wrptr == exqueue.rdptr ) {6 M: g% m1 M+ X; Z2 f( g
                return        FALSE;! I0 m2 T2 R) X9 W9 o
        }
% X3 @8 m( s9 X' _3 s/ [        if( exqueue.data[exqueue.rdptr].time <= writetime ) {7 K8 p* {+ _, S# ~
                ret = exqueue.data[exqueue.rdptr];
) i) a2 b$ [# Z  g1 \                exqueue.rdptr++;
  o2 ?: x! j5 E  ]' L: H+ L                exqueue.rdptr&=QUEUE_LENGTH-1;
# u  o0 j. r5 X: i                return        TRUE;( r, W, N, `. W4 z" s9 _' }
        }) Q  h! `: s; w) X; v1 j2 v1 Y  q
        return        FALSE;- K1 [( N; Q! w, N( q' U" n6 Y
}
" H5 p& }# E* @7 Y4 y; J- O! e' x' {3 _- h7 T7 [
void        APU::QueueClear()7 F8 J( _( \. P+ x
{) o) J4 y9 C, A9 o- t
        ZEROMEMORY( &queue, sizeof(queue) );
4 q/ \" K3 ~/ |- r  \        ZEROMEMORY( &exqueue, sizeof(exqueue) );
' S: U/ N, s: E. T3 B}
/ h) j1 M' t9 F( D3 `' _  O3 b+ b
% G9 f* m5 E# g& G5 L) _& O4 i- ^3 \void        APU::QueueFlush()
% {8 p; g1 {  ^# b6 o* K: ^/ V{; S  e* m) M3 a' Q: o( b& M
        while( queue.wrptr != queue.rdptr ) {
& |" I: a$ {) z; C/ K9 L1 R                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
3 G( w( S( `+ F                queue.rdptr++;/ \# ?2 y, F# O- a8 A
                queue.rdptr&=QUEUE_LENGTH-1;
5 A* E$ e2 e6 N$ w        }
/ G7 U/ C& K' D+ E. n9 H5 i3 S/ `/ _. d# m! _
        while( exqueue.wrptr != exqueue.rdptr ) {! K  m: G8 g" ?" n, B
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );" R. M9 ^8 N; y4 J+ V1 ]" q9 Y  E( f
                exqueue.rdptr++;' M9 ~8 m  p3 L5 i+ [; B2 T: d
                exqueue.rdptr&=QUEUE_LENGTH-1;
: a# K7 D( }2 H- J  j0 \        }% J5 O" I# [* Q9 {% N
}
$ q$ B: g* W" l7 D2 B5 h, A
* w# e% b* i; @8 o- O& j3 X. d8 R& `void        APU::SoundSetup()
" j) A6 i/ J! l{
& l. X3 a& p+ `% H7 S! \+ R3 U        FLOAT        fClock = nes->nescfg->CpuClock;
) `) ]9 f6 [3 K6 b! }3 l        INT        nRate = (INT)Config.sound.nRate;
' x/ @2 p% A: w+ @# w        internal.Setup( fClock, nRate );, p( N6 V6 j6 n' S
        vrc6.Setup( fClock, nRate );
+ \: W$ A5 _# Z3 E        vrc7.Setup( fClock, nRate );
0 E: k* q+ Q4 ^- T8 H2 N" J0 ?' m        mmc5.Setup( fClock, nRate );
6 B5 {+ {$ g5 y        fds.Setup ( fClock, nRate );3 k5 \, a0 K3 r4 h: A9 }8 n3 G- L
        n106.Setup( fClock, nRate );
* q  E( ^' f- ^5 l4 C        fme7.Setup( fClock, nRate );3 g, g% a, D  f0 G$ V
}% x+ {# b1 o; F8 a5 r2 ~9 Z! a

2 X* a5 b5 l: ?7 d+ Cvoid        APU::Reset()
3 w2 \/ h" X" |4 s4 ?{
, \& y& L8 _# y0 X* A7 q/ p% |        ZEROMEMORY( &queue, sizeof(queue) );
& R4 k  }- L( D9 B, u        ZEROMEMORY( &exqueue, sizeof(exqueue) );- g, {; B2 v% ]7 ^. K+ G# b

* R9 g$ O0 i4 `9 K% b* u        elapsed_time = 0;
+ O0 e; o2 }) |' O4 O
! Z4 l! s1 N9 T6 z( V# l( F        FLOAT        fClock = nes->nescfg->CpuClock;& G) b! [$ y" B9 ?. ~
        INT        nRate = (INT)Config.sound.nRate;& _7 ?) B6 i, @( m. }+ {+ e$ d. U
        internal.Reset( fClock, nRate );
7 j& t3 o3 `' x+ }/ W" L- c        vrc6.Reset( fClock, nRate );
- d; F, `: l+ A) ~/ q        vrc7.Reset( fClock, nRate );  }- v2 }6 C5 u6 L, {- D$ U% a' ~
        mmc5.Reset( fClock, nRate );8 ~( K2 R) l2 Y! x! g
        fds.Reset ( fClock, nRate );
: l4 w8 a7 `* _8 t5 b5 F3 Q3 i        n106.Reset( fClock, nRate );
8 U# b+ @2 c! q' \& ?% J        fme7.Reset( fClock, nRate );
) d$ T! Y% W7 O- H7 W3 @* v$ u
7 I$ j) o7 W: I        SoundSetup();; T0 y0 r$ v& a/ `) P
}: p! o% k" j# Y6 k
' k( @7 c( V# v* J
void        APU::SelectExSound( BYTE data )
  e7 t  T) Y* J2 s" P7 i# z{
8 m8 n2 s. C. M: a        exsound_select = data;
8 g/ Q1 s+ G- u}
2 p4 p! v$ c4 f( N: ]+ p, s* @! ]- y" R
BYTE        APU::Read( WORD addr )
, U- ]9 [; U* X  q{
4 t3 j7 B) [% A. E( @        return        internal.SyncRead( addr );
8 K# E% q- F" A, q# }9 }  A}# _3 w/ q- ^/ w) k" j+ h% X

  e/ p) I' D7 ]! o, Q7 z* r! W/ w& Pvoid        APU::Write( WORD addr, BYTE data )
% Z2 x9 m3 t. q, k{, C; s8 M9 m9 x
        // $4018偼VirtuaNES屌桳億乕僩9 y' R- F& }  J8 `3 Q
        if( addr >= 0x4000 && addr <= 0x401F ) {
; f* ?% M+ y, C' j                internal.SyncWrite( addr, data );
) p+ O8 G1 P! S% j3 e5 J                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
! N# L( w; G& h        }$ m% N  P) g8 N6 a" A% }8 s
}! b6 U" k8 D6 q6 J# j5 a$ X3 w

. e4 L  |  D  }. A0 a. T0 b4 nBYTE        APU::ExRead( WORD addr ), |" c5 S3 A* D! r" j
{
7 J& m% I% v* q' e! [BYTE        data = 0;
! T% E' P( r0 @/ E: [+ U- g. @2 P% c0 O( z& K/ S/ |$ O/ o
        if( exsound_select & 0x10 ) {* L+ e* s" [" Y4 ^
                if( addr == 0x4800 ) {0 v  J- m6 u' A; ]+ b
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );/ z& N1 a1 U. N* o; J/ t- D* I
                }
  `1 M+ x: U3 d! Q4 a3 x        }
' y: Y9 S9 ~% Q        if( exsound_select & 0x04 ) {
/ s1 K. h3 I( ^1 n( l! v' x/ o8 B2 {                if( addr >= 0x4040 && addr < 0x4100 ) {
: L: I* q$ O6 Z2 J& X: @9 J: S                        data = fds.SyncRead( addr );5 |. a! a1 e8 s
                }
0 w  J" L0 J  M1 m9 y% C        }
  n6 c1 r4 W) l( t- O7 f7 r) F        if( exsound_select & 0x08 ) {
( J- G# N  ~" ?8 {2 S/ y! ^; n. U                if( addr >= 0x5000 && addr <= 0x5015 ) {
1 M; g/ v; W- ^' N# h1 ^1 i                        data = mmc5.SyncRead( addr );
1 H1 \2 m# k( b- g' |( P7 U                }
. n7 ?. S# v% z$ T- z  D! ~        }
" {/ S( K: G0 U, U( p% W
4 @& t: w& j# g* ~( \        return        data;- E4 u( _: d) T+ A3 P4 }
}
2 i; \2 o' c4 L: w2 I( A! c
, M. X5 H9 {3 J/ f& s6 wvoid        APU::ExWrite( WORD addr, BYTE data )
: d4 c% j" h& q6 t( ]. h/ M{3 Z5 g! ?! p( B5 F# F
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
4 @; b6 Q& e2 c& I9 a% c8 F
4 v/ q! m/ R8 P( u2 P7 w        if( exsound_select & 0x04 ) {2 Q' |! E* i0 _3 n0 \; S
                if( addr >= 0x4040 && addr < 0x4100 ) {
* G5 e2 m/ Q- x% g# a# W  e                        fds.SyncWrite( addr, data );! n  R0 o  {/ _2 ?
                }
' d, i0 b3 b7 k$ `8 O) l& s9 {        }
# K$ w5 W' i* ], i
5 C9 j1 v9 s: V        if( exsound_select & 0x08 ) {( S" q6 I9 o+ f: p3 n. T
                if( addr >= 0x5000 && addr <= 0x5015 ) {
  G6 {5 s- z7 K2 g! U( }/ h, K                        mmc5.SyncWrite( addr, data );
( o3 S* j6 V& g# p2 H/ s                }
) I  r& h" d; W- n  V        }
) ?8 n' Y8 ?) ^/ V* f}
" \  h  D  E" F1 V- H
& j! o9 i% [4 M0 ^void        APU::Sync()
: E# K" m3 c6 ^2 f' W0 ~+ C1 S{
' [- G0 g9 P1 y4 q0 @5 p% S3 u}
' e2 i5 o' ^, o8 T( S7 @7 j- G7 |* l
void        APU::SyncDPCM( INT cycles )
6 X1 I' L6 ~* a2 n{5 P# I; J6 V$ l' k2 f- ~4 Z
        internal.Sync( cycles );
) v! t7 G& I" ~: T+ g& t* i7 G0 a. f
        if( exsound_select & 0x04 ) {
) m0 M+ f2 M# q7 ^                fds.Sync( cycles );1 O4 I: Z: j8 n9 _* {% ~# h
        }
0 t' p, G3 B( f        if( exsound_select & 0x08 ) {$ z8 J7 M! V! z  F6 ^! O
                mmc5.Sync( cycles );% U: r) K. m, g8 v
        }" \9 {/ l, u  U6 h0 _/ \
}
' o1 H8 E" V2 K6 G& g7 p! |" X( j
  v+ w7 f' E$ V* i2 Ivoid        APU::WriteProcess( WORD addr, BYTE data )
9 l: _4 x+ ~8 X/ ]- a* x5 f- s+ I{  \8 m' e. i' e4 H! J
        // $4018偼VirtuaNES屌桳億乕僩
4 m! C4 B; P. ~& F1 Q7 z  i        if( addr >= 0x4000 && addr <= 0x401F ) {
1 x: l! b5 _3 f( i8 f                internal.Write( addr, data );' [; r+ b  r$ z- @# |9 M9 g
        }3 p+ ?8 O( s6 w) b6 q! A
}
6 A2 E, U* r9 q; ^1 c! R) u! U& v( Z0 O0 U) P+ q& ^! j
void        APU::WriteExProcess( WORD addr, BYTE data )
# D* @. V$ `) V5 \{
- g; i% L$ y, Y  x9 t        if( exsound_select & 0x01 ) {7 \& [% S; G9 f7 m& M3 T' W
                vrc6.Write( addr, data );
3 E- r- F! i: G5 G        }
1 G! s% V( R$ {6 x! D1 E        if( exsound_select & 0x02 ) {" h1 o& |' k2 V9 F# u1 Y9 Y
                vrc7.Write( addr, data );4 T. O9 ~% e9 [" ?$ U
        }
0 ?- a/ [* ?1 N& o        if( exsound_select & 0x04 ) {% `. q. I4 E! N' X, h
                fds.Write( addr, data );
- t5 n* S+ o0 {9 `* x        }9 u4 o% C5 U- w& R6 K0 p
        if( exsound_select & 0x08 ) {  V% o( M% w) C3 T9 }6 w3 H5 {
                mmc5.Write( addr, data );
0 ~; p) q" z( x        }
  Q1 \8 g1 b1 t" j* J        if( exsound_select & 0x10 ) {9 W: }. l+ }% ^" o# t' v* Z
                if( addr == 0x0000 ) {
/ O0 N( i6 p# C  B- u) w) ]+ ?                        BYTE        dummy = n106.Read( addr );
( r# A, U; l, h# [                } else {1 n4 O& q' e" L* l; E# d
                        n106.Write( addr, data );
: \! ]0 \, H- l  S                }
' K* @5 ]6 n% ~. |& l        }
) f, e0 N) N' X; D$ A! R# d$ \' `        if( exsound_select & 0x20 ) {
; C# A( F- n$ _                fme7.Write( addr, data );
* u) g7 w8 T7 d8 M, R5 [$ t        }
0 ?* V# q6 F" P$ C" b}1 a# n" r8 s5 F% i
. h2 s2 Q7 k$ Y# c, {& w. g
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )) p  W* C# T5 W4 b! k- Q" C
{
1 B4 |$ _: n/ oINT        nBits = Config.sound.nBits;
* k8 b8 v1 ^% [7 R4 {3 }+ WDWORD        dwLength = dwSize / (nBits/8);
& ~, ^1 `- f- I; L3 `4 Y3 x1 `INT        output;9 R) c8 u& f) L
QUEUEDATA q;, F" W; Q% f1 m& `+ \
DWORD        writetime;
2 X' t: ~3 Y; J" r& c- {  m; w& D" a  C: o# E. K5 }" ]! d% g& [' [. W
LPSHORT        pSoundBuf = m_SoundBuffer;0 j' p2 J0 Y2 g+ K  Y/ q5 [. a4 q  Q
INT        nCcount = 0;
% v* L  \+ g& q, x# @
9 P7 s8 l/ e, E6 U' WINT        nFilterType = Config.sound.nFilterType;! Y- H' g7 ?7 g2 ^' Z+ I

- c: M$ G2 C* D. e. B5 P4 B' f        if( !Config.sound.bEnable ) {
2 p6 I# S/ k/ o/ g" B; s                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );9 v9 V1 K7 b$ d- e8 J; n6 _
                return;
/ ]: w6 P% `; p2 r        }6 @  i  K; m4 q4 v! V' u' m

* }! I4 O$ ]! x& b        // Volume setup
/ o7 J8 B' C  P( _        //  0:Master
! }% g$ q% j  k9 I. m- w        //  1:Rectangle 1
" j3 P" s# f  u, i& [        //  2:Rectangle 2
% r4 d. B' h! s: d- O2 t        //  3:Triangle
  U, i  x# z* {0 e. I        //  4:Noise' a: |; z% C; A
        //  5:DPCM! l* i$ ~5 C% A( d7 O
        //  6:VRC65 O: O6 u6 r) l8 w6 \0 H2 b8 Q
        //  7:VRC7' z) ^4 g! _+ ?' E) X: y$ B  E
        //  8:FDS- b/ o! y  t( x% n7 G
        //  9:MMC5# ^, m$ M, b$ Q  Z  ~( z
        // 10:N106
( A, l7 ~( Q0 c( |% a        // 11:FME7: [1 `# E% h) g6 J& o
        INT        vol[24];" _2 p! S0 {( N# v. {
        BOOL*        bMute = m_bMute;
3 ]; E- B$ [# p% H" G1 o# H        SHORT*        nVolume = Config.sound.nVolume;
6 P2 S, b  r% b3 y" L3 m& v, o: {' g. c! k) [* ]
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;& i2 h7 y4 \  v% E3 q
: v, ^8 v4 I* B% H
        // Internal
, |5 o0 ]9 Y: S' |        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
( @6 V5 I6 W6 U7 j. I# c        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
1 E4 T. f! d' e" J        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;4 Q* w) N6 _3 y% d  p) ]- O
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
" @9 z% h- k  W. ^7 q/ N* s        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
2 K! J, y- f9 o% Z% C3 i5 G4 u6 h0 T, m
        // VRC6
2 S6 i8 D5 b: x4 N3 y% d        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
# v0 f! D1 d( V/ t; C9 ~        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
3 i: ]7 P5 f( Y& F. ]4 Y        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
0 e" D7 o6 {* x9 M- ]5 u
( h. h& b+ C" \) C        // VRC7
% Y, h9 u" u7 _7 S! F        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;, Z; Z6 j; r! l  t4 W( H3 ~
- ?. I: P( |! F- i
        // FDS
4 h6 U2 o/ c$ c# u        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;0 \7 k# |0 W' c
* Z6 g" _: Z4 w0 W7 G7 M
        // MMC5+ E  v+ a0 j' }5 G  i# Q
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;- u! A4 A7 q3 S, ]) Z* C& n2 \# m
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
1 M! ]  N  R2 k9 u6 {- _        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;. j) ~- o2 Y' m+ \" d. c
/ T. z$ {. ], }; W5 @1 R
        // N106! A2 ]$ z$ X! U
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;6 e, ^) j$ G9 c$ m, @) W7 }/ U! L  |: Z
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 J5 z6 ~! m; |; r" |3 K! t
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;# g7 @+ O  |) Y! l
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ t, {% u* C; ]. O        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" s  `9 i# _6 V6 |9 ?# `        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 R. n4 F# L, E2 `
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
( v) K' E! N2 m! [        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;, g" r* {& w# _

" V. u; ]! T& V% f# b$ p6 W        // FME71 l, A9 L! S0 E* x4 N
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;$ N# q. ^2 I" ^4 z# M3 f
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;+ i" @6 Q0 O5 r/ Y1 o
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
: J/ U6 _( X$ j  h0 |* D# S' \0 L9 @
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;) Q# v& j7 W4 n5 T- D) D# _
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;, d0 i; k+ S+ u( r6 ?, Q/ n! Z! k
4 \& @3 v' w; u# ^" e! e* t
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟- w' M8 u+ H6 Q. k( a1 s) o% d
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
+ q- n% j3 y7 F4 L; D                QueueFlush();9 @. U: @: L. j& n) k* j
        }
# |2 S% V5 f. E  {. I5 H4 N$ H
; ~0 U0 }( B- O        while( dwLength-- ) {& u  E0 q0 P; T5 u( b( b. N& D/ X
                writetime = (DWORD)elapsed_time;6 j/ B- V4 M* X. x3 X# H$ m

: ~8 p2 k; Z$ t: ~$ C, y7 W                while( GetQueue( writetime, q ) ) {
% K% g# \  Q6 Z) x9 G& J                        WriteProcess( q.addr, q.data );
7 X( ^, b6 h% @% j6 a( I  ^2 }. a% e                }; C; q9 a" R& a: ?6 u
. o8 d! D' f( G6 x# ^
                while( GetExQueue( writetime, q ) ) {
6 D& n% F3 Y% c: ]                        WriteExProcess( q.addr, q.data );
( h. b- m2 \) `  ^: v                }4 d2 G% N' g, h$ n

; D: m1 m5 Z) Q8 i. ]+ ?2 Z                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
4 _) O3 R; s% Y( K, K2 L: ^" T, \% S                output = 0;
" Z6 x7 S. U. m* `6 Q                output += internal.Process( 0 )*vol[0];4 h6 O- Q1 {% s* T
                output += internal.Process( 1 )*vol[1];
* E# P3 ~: U+ U* ~# k& N) p                output += internal.Process( 2 )*vol[2];6 }8 C. s* E2 z. V* p
                output += internal.Process( 3 )*vol[3];) W9 T$ d& _) m: I$ G
                output += internal.Process( 4 )*vol[4];3 R7 f6 ~( n" E0 y
; b+ Z' k& V* n9 M* \5 }5 `. V
                if( exsound_select & 0x01 ) {
; n9 \! Z, X& b                        output += vrc6.Process( 0 )*vol[5];, `# F# X, `* x! P' ^* p3 p) O
                        output += vrc6.Process( 1 )*vol[6];
: |% m5 r  p4 G  Z                        output += vrc6.Process( 2 )*vol[7];, ~  a; s2 j+ p2 `
                }
5 S. n$ p4 w: x9 C8 e' d* Z                if( exsound_select & 0x02 ) {4 ]# L0 c6 P% ^7 K* H4 c- b
                        output += vrc7.Process( 0 )*vol[8];
5 n: i/ s. D+ t; g0 @                }
* D3 J% W% _* e5 t' o4 O                if( exsound_select & 0x04 ) {
, o# B2 [: m2 V) H1 P* T                        output += fds.Process( 0 )*vol[9];
) y1 F  o& F: Q  d% z4 Y! f* w# [                }
; Q# _7 R; v2 C; C3 ^) ?/ s7 i" C                if( exsound_select & 0x08 ) {8 H0 G7 \$ O* j  |/ O
                        output += mmc5.Process( 0 )*vol[10];
; t6 [6 }% h5 H: j) O                        output += mmc5.Process( 1 )*vol[11];
6 q6 n5 B  ^2 \' y, d& I8 S                        output += mmc5.Process( 2 )*vol[12];
! o/ `& M. g/ {2 z3 M& a- C, g                }: k3 e/ ]/ d8 O+ c: J3 X
                if( exsound_select & 0x10 ) {
8 Y  n, u* n+ l4 n! E- K3 M7 m9 x' w                        output += n106.Process( 0 )*vol[13];. p# C6 y" n7 v& c
                        output += n106.Process( 1 )*vol[14];
: L. o4 k- }3 S# I. [6 c                        output += n106.Process( 2 )*vol[15];7 n( H; ^* m. J) d1 T
                        output += n106.Process( 3 )*vol[16];
3 d( B  @. r! H- v6 [1 d! S- |                        output += n106.Process( 4 )*vol[17];/ V- j, R6 W2 s: r
                        output += n106.Process( 5 )*vol[18];
3 Q' d& I8 j* I! }0 k; t                        output += n106.Process( 6 )*vol[19];2 }5 X8 _4 x! N- T* k
                        output += n106.Process( 7 )*vol[20];+ \) l" i+ l( Q5 s# G7 D
                }
$ [: p% B$ n1 y" h% _7 f                if( exsound_select & 0x20 ) {
8 q5 j3 m& J; W2 H7 F2 z4 e6 B8 a+ @% `                        fme7.Process( 3 );        // Envelope & Noise4 \/ d9 [9 R: ?
                        output += fme7.Process( 0 )*vol[21];: b3 V1 W. O. q1 R+ c3 P/ s2 I
                        output += fme7.Process( 1 )*vol[22];
7 A: A3 g, o" _                        output += fme7.Process( 2 )*vol[23];  i9 [" J, ?, d( ]# _
                }* X" U# ?" B. x, ~, A( c

) I! n/ T# ?. I                output >>= 8;
! q5 s) X8 s' X, {3 |  b
8 f1 E1 C; m0 `* ^! D                if( nFilterType == 1 ) {. D/ M. u4 `2 `* x# v
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple); i5 a/ N. D" ]4 M' T* s& V
                        output = (lowpass_filter[0]+output)/2;4 g! d* c, F0 A1 d0 W
                        lowpass_filter[0] = output;
0 ~. I, Z' M" N) _7 Z0 x                } else if( nFilterType == 2 ) {! T, Q+ k& E- N" ?; p+ H
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)! J/ V. m- {1 B# q8 V7 R' k6 ^
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;5 I+ N+ j* X& r) N
                        lowpass_filter[1] = lowpass_filter[0];) `# Z( C' ]* l1 C9 }' Z
                        lowpass_filter[0] = output;
. A3 D( R8 T7 v0 F  F( j                } else if( nFilterType == 3 ) {
  c6 l, Q: ]  }* R. X                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)- ~: u* u" c* w# j5 Z7 m) |
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;( \) |2 ]/ _. U+ a2 d% q; A2 [
                        lowpass_filter[2] = lowpass_filter[1];6 x8 P+ E5 p9 H* e6 ]
                        lowpass_filter[1] = lowpass_filter[0];
! y* i; R1 R, [' i7 V* S- N                        lowpass_filter[0] = output;
$ s2 q9 [, h1 r  x# i                } else if( nFilterType == 4 ) {
+ ^* R3 k0 i$ b- }, Z                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)/ |' Z4 J$ t9 {8 C0 y7 n
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
( G; b8 K' t9 g, r# _2 j                        lowpass_filter[1] = lowpass_filter[0];. L2 x/ D5 O0 O: z. j! F) X/ I
                        lowpass_filter[0] = output;' o- }- J5 v8 q4 W7 f
                }5 V- q5 h/ ~1 X

5 V2 C% K# F1 \/ R& v3 z5 B#if        0
& o( x% W! t- U" b8 R% _0 ^) Z                // DC惉暘偺僇僢僩
4 ^# H9 }3 O1 t. ^; y                {
1 d# M0 C3 E6 o                static double ave = 0.0, max=0.0, min=0.0;
9 t; `! C6 V3 M' _& |% p/ g                double delta;
% \1 h, }% r# r) D1 n                delta = (max-min)/32768.0;6 J. }& ?( e! o
                max -= delta;
4 z: d8 a( t, R  j! z' S                min += delta;( p: _% ?2 K# z, P+ R$ f: S
                if( output > max ) max = output;
. J' t& R) h& G                if( output < min ) min = output;
4 `3 b! {3 O2 R                ave -= ave/1024.0;. h6 o1 n7 d% }& _( k$ V
                ave += (max+min)/2048.0;
  y' M' a7 I( e                output -= (INT)ave;
; T4 j; C' ~7 m" t                }! V8 O$ k( l9 j8 w7 O
#endif/ |, @* z- R$ J2 g" p
#if        1
9 p4 u( q; Q/ g                // DC惉暘偺僇僢僩(HPF TEST)
% q# |) d1 c' p$ u1 [9 q                {
+ e" p+ h, @( q//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);) J- l2 H9 n. }5 N1 z
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
, q# F& [  ^0 `- i3 G                double        cutoff = cutofftemp/(double)Config.sound.nRate;
% g$ ~! J' F8 P. k) r6 w. R                static        double        tmp = 0.0;- a* m& Q6 ^5 ~
                double        in, out;$ @0 c7 g8 ?8 U& c/ G% M. t! Q

% A+ j" X: m' H1 H: F* X8 M8 s                in = (double)output;
# G& `. X% V% S  f5 d- c4 _/ Z2 S' E                out = (in - tmp);
# f8 g; r0 V5 T( Q9 y# L                tmp = tmp + cutoff * out;
7 i* {; c1 d; J6 R4 p4 A& W
$ ?2 y/ b1 [* T- f' A                output = (INT)out;
( ?* Q( `7 ]& C7 L                }
8 s' R  B7 W$ i$ g8 _#endif
; ~4 W" c6 c6 l1 J, h#if        0
3 N0 `- M7 A5 F$ `+ |. U& C                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
' ]5 m! w, B* J6 L1 f9 J4 L                {6 l4 d, C3 T2 N( ~+ V6 U
                INT        diff = abs(output-last_data);7 i: G0 k! w5 }& L( j4 f3 p0 u
                if( diff > 0x4000 ) {
* D# n; u* P5 \4 H                        output /= 4;1 W! ]9 I+ I6 S; [( B/ D+ _
                } else " j- i5 J$ H, T
                if( diff > 0x3000 ) {
7 r, f9 X  U. x4 j/ U- F4 s7 }                        output /= 3;
5 D$ [, [% J0 q- ?5 [                } else
( b  E5 ^2 W4 A% s  T( O4 _                if( diff > 0x2000 ) {. H6 `# z' U3 D' L
                        output /= 2;
: B3 v* }6 F3 j- J                }
3 s8 ^; K) X" y$ {% W                last_data = output;
! L6 \. q' w5 U: m7 t$ ?7 Q# J                }; Y$ P& p) n) I6 h! N
#endif
+ S$ x2 H& x7 g7 I6 U% |                // Limit1 C4 U; N8 x0 T# W. I1 r7 M
                if( output > 0x7FFF ) {
! G1 h  S4 w% J, Q                        output = 0x7FFF;/ K+ f2 I4 r5 Q5 U6 q6 [( r( i
                } else if( output < -0x8000 ) {# n, n5 a5 p$ G1 e7 @# r( ~
                        output = -0x8000;1 K* Y) p3 ^. b/ \4 i
                }
: I! n; R8 }$ j* N) X% G* d. p4 K/ \
8 I& a. e& q0 A0 j                if( nBits != 8 ) {& b% D8 a& _( F- W
                        *(SHORT*)lpBuffer = (SHORT)output;
- }8 G- |9 c4 K5 L8 D! y3 e5 N                        lpBuffer += sizeof(SHORT);
1 _. L9 q! O% U+ n/ T+ u" f% q                } else {
0 V! a8 X1 k* y. g& j2 c% o                        *lpBuffer++ = (output>>8)^0x80;# Z9 D/ x# N$ r% s; Y! e0 Y& ?' `
                }
& _% k. o8 i# i" G+ q( z' e$ }- T. f7 n& [/ E3 X
                if( nCcount < 0x0100 )
$ Z5 _+ j4 Z( y: m  k2 p                        pSoundBuf[nCcount++] = (SHORT)output;
* ~" G$ G! R/ R/ v+ j2 ?/ K
4 j# I1 t% N; q1 w. H6 z//                elapsedtime += cycle_rate;2 U/ M! Y  V, h
                elapsed_time += cycle_rate;
' h" M, m, Z3 s        }0 o; c1 [% G( V1 C

9 l4 l# _/ Q! ~#if        1
# k6 c" ^6 J4 m        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {' j7 Z  C3 _2 J8 A" F* K5 R
                elapsed_time = nes->cpu->GetTotalCycles();) ~! l) d, ~* b# {6 p* `; p) G, L# B
        }! O# M" V% C4 f4 Z+ a/ s
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {! _) ^7 {+ S3 ?+ v' ~2 z
                elapsed_time = nes->cpu->GetTotalCycles();
" @/ s5 w% h! \1 K        }
) @0 L3 e0 x0 E9 f#else
7 F. U$ w7 O0 q        elapsed_time = nes->cpu->GetTotalCycles();
7 D& g% r/ A$ r/ W; X2 ^#endif
* K( @3 H+ ~9 u2 w, C8 @8 o3 |}' J2 H) j* h: S0 O  b: J

2 _& C  a3 w* O/ U. _& g// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)7 _; X8 {, a3 }% R
INT        APU::GetChannelFrequency( INT no )2 D3 g5 D) e0 f& O/ }6 B
{
: v0 H0 u) T  V0 }5 e" z        if( !m_bMute[0] )
2 j0 T. h& }7 s, u3 n# V$ c) x                return        0;1 H& i- r' L# Z% `4 h, N) \! P  M
# ?  r# x5 X" B
        // Internal. [# d- |% h3 q& L8 o& m' v; j
        if( no < 5 ) {5 B2 O9 ]0 ~! h' g, q8 D; s
                return        m_bMute[no+1]?internal.GetFreq( no ):0;6 Y" Q- t8 v" Q% K
        }
7 u6 B: B1 d  Q4 j9 n- K1 z! ~, M        // VRC6
# R8 _  c& |$ d" V. C        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
' v) f* \0 a6 u% }2 r                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
) H! x. l  [/ S5 K5 I5 ?; G* H        }
2 s% |: o0 Y$ R/ d  }/ M- B        // FDS
+ l7 H! r; w6 p) E& \3 p        if( (exsound_select & 0x04) && no == 0x300 ) {! m6 f! w3 j* {; y
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
8 o, w2 D7 p( E$ a        }9 P% P- g0 F& H5 P  K
        // MMC5
# \+ @  O4 u+ D        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {/ E+ X: Q( D- U" h. [
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;/ w) x/ }6 q4 q! J  D" Y# W
        }
" u9 J4 ]" F' i/ a6 x2 c0 Z! K5 i' g        // N106. O$ i- i3 [. U
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {" R7 f( T( g6 r- o1 B( t1 l* c
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;0 U7 n; n3 \  J9 x: ]
        }
6 |) p& e' F8 J5 d        // FME7  J( \5 q# W1 B& N, m
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {" c+ G* i% u# L  i' [  d+ W2 ]
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;- {  R: M0 Y* w: w! b4 M
        }
5 {- j3 h& `+ N8 x' ]  T$ R        // VRC7' P1 @  c. F, @) Q
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {( D2 |; F3 v0 V! R$ q8 q! S
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;- L( U7 J% `( ^/ B8 j
        }
, k( K7 F+ f! H        return        0;
9 [! C5 X8 M. X3 T2 @}6 A) q$ Q( S- Q0 Y
1 C- f! s8 Q) S/ @: A/ ?- B
// State Save/Load: G7 b) {$ _% m7 L7 A* C
void        APU::SaveState( LPBYTE p )
: D9 b6 `6 x9 l/ d* U: W. B{# V5 E# n# A5 c6 e# @) I: h
#ifdef        _DEBUG
  [- z3 r* V2 f$ D, H; XLPBYTE        pold = p;
8 h8 S/ g! ?: e3 \% D' U#endif
$ U* n" s6 j9 R/ n( g: Z) O/ l4 {$ v4 G) D. Q6 }/ i
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞4 V  ]6 u6 f: G; V# S. c* f
        QueueFlush();
" k0 f, J# g3 {7 r: ]( I! ~
) X) b) H6 n, @4 D/ ~        internal.SaveState( p );
' Z) f( O3 }& J7 a# ^" u2 }        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
" v+ D$ J; c; m' P8 I* j: N6 B, B
- T& k; q7 S* [* A        // VRC6
9 D( g1 B& `4 q        if( exsound_select & 0x01 ) {/ Y0 f; r2 A+ l  O; S
                vrc6.SaveState( p );
, ^7 @  ]& R9 l                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding" t% z8 P2 n" T, ~2 z* l6 C
        }) @$ w1 F. O, [
        // VRC7 (not support)+ ^9 B6 V/ X+ x9 T% g/ `' ^4 T
        if( exsound_select & 0x02 ) {! i% x: Y" I$ ^& k0 x8 G
                vrc7.SaveState( p );! p# I: p0 E' }/ N+ l! I
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding- X- `0 e: E& _: v8 ~0 w4 _4 L
        }8 j. \3 ]# N& }& ?, d4 w/ E9 n/ _
        // FDS" f7 E4 u1 G2 _( J  S& G3 d4 p
        if( exsound_select & 0x04 ) {9 m; X& ~+ E. Q# X% L, W6 u4 t% v
                fds.SaveState( p );
2 T0 R# I0 O. v2 {5 q( T' k                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding9 o9 S7 R; W# A  K
        }
9 P4 r5 J/ o0 d        // MMC5
7 [- G0 S8 \+ t        if( exsound_select & 0x08 ) {! h' E# |) C/ Z7 X
                mmc5.SaveState( p );: M" a0 R, H  D9 o" C5 I+ P3 e6 P9 S
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding# a8 P% ~/ {1 m/ ^: V
        }& r7 S3 t3 m! V3 i5 J! C2 a& y
        // N106
/ R$ ^% `$ @1 G0 w+ t6 ^1 l        if( exsound_select & 0x10 ) {2 \5 I, C8 x1 W
                n106.SaveState( p );
) c; I- z% ?) b( q                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
8 u, g" t5 L0 r# x! p$ F* L        }
" T0 w+ m+ Q  L. o# ~8 R        // FME7  m" \9 v1 g. [1 A: S* ?
        if( exsound_select & 0x20 ) {
" k9 E+ @, \& A  Z* w- j                fme7.SaveState( p );
6 q5 E. o3 {1 f2 Z  ?2 t3 ?1 K0 K                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
% e* k6 F! v- ?1 ]        }
( U" u# B' ?. K7 a6 j3 T! a: c& Z) I- a# c5 g
#ifdef        _DEBUG( ]" @( ^* x2 _$ g0 J( k
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );0 q$ W0 z% h. i/ \
#endif& |/ y; c6 z7 z" z/ I
}7 E; i6 ~/ o$ X" O& L) h

9 d- M- T+ X% M! _. O/ Z, hvoid        APU::LoadState( LPBYTE p )
$ ~6 w! f- h2 M8 `& n0 u! `7 ~{
+ y% B) S0 w7 i& S2 t        // 帪娫幉傪摨婜偝偣傞堊偵徚偡* E) b) H7 v, K5 \4 [1 t
        QueueClear();
3 P7 N/ X6 D1 @2 F( H8 R" H, M  N. M
        internal.LoadState( p );
' j! q: ~6 A5 r9 @, x        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding7 [! z( ], Y( A, r& s' y, y
2 Z3 |1 t. N( u1 @- t
        // VRC6! z. s1 r7 a. {6 [5 a' O  Y
        if( exsound_select & 0x01 ) {6 c* m; V' ~: f0 M4 h
                vrc6.LoadState( p );% M, i% F7 Y) z( x. i
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
1 H3 p9 I: D% N0 S! Y2 p        }5 A9 q# o* I3 ?" M: k0 |( ~- V" c
        // VRC7 (not support)
  Z! N; s* N0 U* Z1 t( A$ P( x% t6 ]        if( exsound_select & 0x02 ) {
% i3 `$ f1 V; ~3 @8 S. n  i                vrc7.LoadState( p );1 F) B5 x- W5 \0 \. ?5 ~) V' s
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
5 k) L6 a' {4 n' H* M        }
( X* P; V/ V( g1 a1 m        // FDS
9 k. c, C9 W8 q        if( exsound_select & 0x04 ) {. i+ O: n. s8 O
                fds.LoadState( p );
$ [+ U  n' b  l3 y$ `) N                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
$ @' [  y1 s. w! e. c: J        }' }. J* m4 T. X2 _- I1 n
        // MMC56 E& G7 _; j: [- Y
        if( exsound_select & 0x08 ) {4 W$ y" ~, C. y* _+ b' P& P  @2 }
                mmc5.LoadState( p );
* m7 E* j- O& l% a# {2 i                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding( [4 {+ e6 ^* E2 c7 H
        }
( ?/ s! ^7 w4 Y% I9 a7 K  j& L        // N1069 S* \+ C0 w4 J, a- I6 Q# a" |% n; ^
        if( exsound_select & 0x10 ) {
6 k; Q. a% V, c; b8 o2 I9 b5 H( d                n106.LoadState( p );9 B' N% o3 U( N# A
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding, l9 |. g1 w9 |7 c
        }3 C' ~" i# ]  X
        // FME7
9 \! C0 i( E# _        if( exsound_select & 0x20 ) {
5 Y2 @4 p# `" h8 E- f                fme7.LoadState( p );
; I  {% I1 b! ^                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
% u. P4 P7 ]" q! C3 Y: h+ m8 `( Z        }9 m9 P. K; Z2 q" f4 P9 B
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
9 |* a+ _8 p! r可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。6 Z! l0 A5 r- x
感激不尽~~

  C3 D$ ~% }3 p* t恩 我對模擬器不是很有研究,
/ o1 X7 M! @# ~5 {雖然要了解源碼內容,可能不是很困難,
8 l' `' {$ R) H3 y8 {* }不過還是要花時間,個人目前蠻忙碌的。
! b1 T* i& {: W" F/ r( n% c+ @2 X+ s
( p  _: H  |9 V# U( I& T給你一個朋友的MSN,你可以跟他討論看看,# ?8 e1 x+ G  i+ ~; Z
他本身是程式設計師,也對FC模擬器很有興趣。
- G" ]; K. g3 Z
9 v) a; j4 O! B* n/ DMSN我就PM到你的信箱了。& r4 t- @' e: {: ?1 i( z' q

+ p% R8 z! G3 t3 U4 s希望你能有所得。

该用户从未签到

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

签到天数: 80 天

[LV.6]常住居民II

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

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表 2 g& h3 O4 N4 E  H) r( B
呵…… 谢过团长大人~~
8 n# C( e+ B: q' T/ ?( d" M

& }  P2 k& d0 v* H4 E' v& N哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
% Q6 i) R3 ]" w团长的朋友都是神,那团长就是神的boss。

/ S2 i& U& L3 L# I9 y哈 不敢當,我只是個平凡人,
$ s' Z$ Y* b" M! z, }要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
: s+ }  k6 J: QZYH
' d# V& g: i2 _1 E, G7 vQQ:414734306/ K7 w  y8 J2 T+ N! T
Mail:zyh-01@126.com
8 I% F' [6 r2 r, s, b4 P: X% V' B) a, D. W6 @7 N: k
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
* ~+ C2 W7 W. X- v6 H+ v' l# X再次对团长大人和悠悠哥的无私帮助表示感谢~~
1 w7 ?  M7 R& \
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-16 23:37 , Processed in 1.101563 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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