设为首页收藏本站

EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。- `6 n8 s3 J8 I) d6 s
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~. n/ k! b! g& E: s
这里有相应的模拟器源码,就当送给大侠了~~  @5 ~4 o4 [8 E8 Z3 J) O
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
) m2 Q9 s8 S% T; d3 E能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
, t4 n4 |% W2 }# v楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~4 K" P- ~$ V/ E" H
这里有相应的模拟器源码,就当送给大侠 ...

: K0 W- f# ?$ g- Q6 z. r' L聲音部分(Audoi Process Unit = APU):* K4 l, T# D3 W. E- h- ~
.\NES\APU.cpp
& W7 K6 w. Z; ]% c.\NES\APU.h: X" q' K2 ?6 _: p
$ u; g( E% W& M, E+ J, s

* [/ ^( |+ p6 g/ u( O影像處理部份(Picture Processing Unit = PPU):9 f) V+ }# _. u1 [/ ?' ^; R( n
.\NES\PPU.cpp0 @, ^3 N; q& |6 l  a. h
.\NES\PPU.h
) }8 T8 j' _3 h" L
# L% s$ v3 Y2 l; F如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:; e; N8 M, g% {4 C6 E$ B) ?
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
$ B' y4 l+ J* Q1 p; b+ h//////////////////////////////////////////////////////////////////////////* a; _9 w4 N: q9 I3 P9 L( K& v
//                                                                      //
$ k1 X) d* u& c% }: d/ a+ e1 E* b) m//      NES APU core                                                    //- f3 t: Y8 @* r9 S0 G% C" A
//                                                           Norix      //
, m0 M" n) a9 m1 R% ?//                                               written     2002/06/27 //
: w; n7 P: f9 z/ P) D//                                               last modify ----/--/-- //- c+ g, a' |* G/ [4 }4 W8 w6 A
//////////////////////////////////////////////////////////////////////////0 t' @' f2 m4 K2 k$ ?. `
#include "DebugOut.h"2 Y4 p# R! `1 S- A/ v3 d: W
#include "App.h"* z: X- |$ e, {
#include "Config.h"
5 B6 T) x3 g8 S3 ~; N1 ^" W7 [1 |
#include "nes.h"
. {/ b2 U/ [9 U+ q& R4 K, C0 J7 g#include "mmu.h"! P6 `' ]4 b- w: ]
#include "cpu.h"& @3 J8 ^3 \7 u* h3 e' }5 @* y% K
#include "ppu.h"% l, ^7 I0 C9 `1 _# @7 W$ }/ Z+ h+ W
#include "rom.h"  X: L0 D. I2 g' Q" V5 C
#include "apu.h"' g9 b0 s" [8 R/ Z
' ^( a0 q( H) z" M
// Volume adjust
- D- t+ N  N, Q9 H, W, O// Internal sounds- b+ E2 M$ V) G* Q  C# m' @3 X
#define        RECTANGLE_VOL        (0x0F0): K4 Z9 b: X4 c# ^6 h) q
#define        TRIANGLE_VOL        (0x130)7 N5 s6 x/ }$ x7 O2 h/ P8 n
#define        NOISE_VOL        (0x0C0); l/ ?7 i! G4 N( d, A
#define        DPCM_VOL        (0x0F0)( `0 ]7 [3 n+ t/ ~
// Extra sounds
5 E+ P7 \  z( _& l1 ^#define        VRC6_VOL        (0x0F0)/ Q! v( f1 O( S+ D8 d; `
#define        VRC7_VOL        (0x130)
" A$ y5 h4 N# u! }  r4 _* q4 N#define        FDS_VOL                (0x0F0)1 ]# e! _( i  l( d1 b* `8 u
#define        MMC5_VOL        (0x0F0)+ p4 p5 L  g: f1 H9 X# U: y2 w
#define        N106_VOL        (0x088)! ^2 U& @9 C8 |& B, ~" W5 C" y, i2 T
#define        FME7_VOL        (0x130)8 t  U# z4 B( ^% a# `
) _1 M4 \6 Q. u
APU::APU( NES* parent )9 a' X  B3 B" o0 t% _
{
5 m: i9 t( U. E" r4 v, ]" u        exsound_select = 0;
8 |9 g+ `5 ?' @& d# f3 p7 w+ u5 C. j* z5 K! S
        nes = parent;4 O2 d* I6 g" K
        internal.SetParent( parent );  n; y: J  M0 t! C# c

( B" {; q+ k% w/ V3 w        last_data = last_diff = 0;
* q4 W, l6 ^% r; v1 R8 i3 Z- Z! Z' r
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
5 w0 J$ u& C3 s, S- Y8 U1 F- L' k+ c' ^2 u# q' Z
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
7 i' j. N7 e8 U0 Q        ZEROMEMORY( &queue, sizeof(queue) );
- |6 d- i" u6 ^& {) L( b6 a        ZEROMEMORY( &exqueue, sizeof(exqueue) );
- c9 {/ F0 [% p8 P! q7 p4 L. A* X- }
        for( INT i = 0; i < 16; i++ ) {5 Y9 x5 [& O1 ]& b  w9 m
                m_bMute = TRUE;
9 r' B" e( a8 s/ I( ]+ x        }
. F7 D" }! z, p# q% R}7 S: b* N- g, m5 v" r

5 b. B' v- B0 b/ sAPU::~APU()0 Q1 T% D) O" u- e- |6 o( ?9 z
{# C4 f) u- J* ^2 p: t7 ~
}0 G9 R$ K8 G8 U1 R$ J

; I% [6 r, _8 x7 m* ?void        APU::SetQueue( INT writetime, WORD addr, BYTE data ): M6 p7 L0 ?9 T0 G+ K2 R( f" C) ?
{1 x- x! J: F; E/ i# K% B' B. q
        queue.data[queue.wrptr].time = writetime;/ n3 i$ Q7 {" V; k' V2 j( v- ]/ |
        queue.data[queue.wrptr].addr = addr;1 R- N$ Y1 j) C; R% F5 Z  m7 f
        queue.data[queue.wrptr].data = data;+ f( U/ s, O% p7 W% B  C
        queue.wrptr++;
5 L" g$ f+ B1 M        queue.wrptr&=QUEUE_LENGTH-1;
# J) S/ k% B5 S* P/ {0 ^3 p6 P        if( queue.wrptr == queue.rdptr ) {0 k" {! M5 |/ q8 Z, n2 m# b. H: r
                DEBUGOUT( "queue overflow.\n" );' |: I  R! w- l* U) d( r& ]# t7 H
        }8 b: C$ b6 C  h9 |( Y
}
8 y# i; j3 r; m
" R4 F) @+ ~- H; V: N; F1 ]BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )0 i- k( j1 H. s+ M, G
{
3 d3 u, t* M+ x' P: h8 R        if( queue.wrptr == queue.rdptr ) {- ]. d/ R4 K4 w( R0 T" R
                return        FALSE;
. P1 G# A8 y& y) D# |2 c, Z& K        }$ s  f) A. c$ N) \$ @: j9 o
        if( queue.data[queue.rdptr].time <= writetime ) {1 ]: p( O' i6 z
                ret = queue.data[queue.rdptr];
2 X& P! B1 m: W+ Q                queue.rdptr++;
: p) G3 k: g! S0 @0 i3 j                queue.rdptr&=QUEUE_LENGTH-1;3 X5 v* e" ?3 j8 [! m4 Z- z5 V
                return        TRUE;
5 n. e. e9 P4 G# S! R+ z3 x        }4 e# A" q( U3 T& t
        return        FALSE;; C  N* l9 Y) W+ K
}6 f# L7 }- K: `  f

! a/ V9 K) |- X/ _. y, B1 A; zvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
" H5 k* T. J' X1 c  F1 u& \" E; D{
: q4 t2 T$ P9 H) Z2 X3 Z        exqueue.data[exqueue.wrptr].time = writetime;
% C8 C/ z- o% ^        exqueue.data[exqueue.wrptr].addr = addr;
. g8 a2 |& Z7 d' K        exqueue.data[exqueue.wrptr].data = data;
9 E4 ]% M4 U( Y& m; m5 L6 }7 U        exqueue.wrptr++;; v& b+ @4 ~0 O; f
        exqueue.wrptr&=QUEUE_LENGTH-1;
; a2 {# C/ ^2 l4 W' B; l        if( exqueue.wrptr == exqueue.rdptr ) {. y/ {# R. W4 S. q2 ], [) w/ g3 b
                DEBUGOUT( "exqueue overflow.\n" );
! K8 W4 ^8 g8 Z- t* r6 M( J        }: m4 B" L2 Q2 c0 q9 ?$ {
}: f, c7 d/ b6 n

; p# P, U  Z5 @3 GBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
8 l5 F8 Q& |5 ^$ l- e6 Q{
  s! R" H/ k3 }        if( exqueue.wrptr == exqueue.rdptr ) {3 l9 U2 D  t9 ]( B" J; k
                return        FALSE;
4 D0 Z  O' m; B. C' h! k. v        }
- g  H% Q- z0 p        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
, |) N) w) ?3 c3 m$ L9 n2 \! _4 Y                ret = exqueue.data[exqueue.rdptr];! l3 o) B4 P+ o3 S! z
                exqueue.rdptr++;
+ k8 x3 Y/ _8 Y+ w5 {7 _1 F                exqueue.rdptr&=QUEUE_LENGTH-1;
1 `1 r; R, c# {/ H. I                return        TRUE;, s- [% t* Q  _3 B
        }
# r7 V; Z; Q1 {/ O        return        FALSE;+ f* w" n6 R, F2 l! \) ]. P
}' g, I% Y4 q+ p$ Y0 F9 u

- }" y3 V1 n" x4 z* Qvoid        APU::QueueClear(). e2 n4 \. `! k+ \
{3 F& @* a2 e$ C& z
        ZEROMEMORY( &queue, sizeof(queue) );
9 c5 S2 z; j# y1 }  D        ZEROMEMORY( &exqueue, sizeof(exqueue) );! Z  a# s  e0 E* T  v) [& V
}
: q9 z6 Z  ?7 [6 }! @: D$ u) D" L# n  _$ q
void        APU::QueueFlush()
* y5 L# a" Y6 n: s  ^2 C{
+ Y" Q1 g# P* m        while( queue.wrptr != queue.rdptr ) {
" K8 ^4 B1 o# j- O/ H                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
+ L5 @/ e  g$ d" C/ l                queue.rdptr++;( T( R% u# o% D5 w/ n
                queue.rdptr&=QUEUE_LENGTH-1;! C/ z( _; t  u# V) v
        }7 @3 W. Q' h: x1 n% M2 j

, K. k% K; r; h7 O: D0 v6 K        while( exqueue.wrptr != exqueue.rdptr ) {. X$ V+ f0 R/ z, m: g
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
6 T# p" _7 t, U% N0 @+ Q                exqueue.rdptr++;
. G# l' \7 M6 Z' k                exqueue.rdptr&=QUEUE_LENGTH-1;2 ~' p* P- T: y0 f
        }# |* R9 I+ b5 r+ h; B+ G
}
1 p& [; f  o% M  f/ J. }
( ~! x  A- h; k* qvoid        APU::SoundSetup()% n: I2 @4 i8 M* U2 \
{
6 _6 m, a8 ?; X4 R        FLOAT        fClock = nes->nescfg->CpuClock;
! e. D9 n. x$ Y7 `; E9 x        INT        nRate = (INT)Config.sound.nRate;2 G2 D2 o. [4 _  R  ]# b
        internal.Setup( fClock, nRate );
+ F* N5 U5 l( `# u( X        vrc6.Setup( fClock, nRate );
4 _& h- k6 L  {" q        vrc7.Setup( fClock, nRate );% z9 a7 U* \) [+ g3 C" W
        mmc5.Setup( fClock, nRate );
- E* Y6 c' @* o: c3 G7 q9 G        fds.Setup ( fClock, nRate );
7 d, P0 R+ _, e6 B5 s0 o        n106.Setup( fClock, nRate );
: H" E" P9 C8 Z" h" a+ l1 v+ p6 Z        fme7.Setup( fClock, nRate );: a/ g: Q! O1 j% z
}
7 l) k) F. r2 S4 u
$ ~- y2 V# j& E! E5 u  h3 Avoid        APU::Reset()7 y1 O& i- H' k) O) }
{
! U& U& Q4 c) Y( e        ZEROMEMORY( &queue, sizeof(queue) );
: F) s4 z8 e5 p        ZEROMEMORY( &exqueue, sizeof(exqueue) );! |4 W3 q, w4 o! Q- m: n# ~5 w: o: g
" m0 Y( {* n- J/ H/ T; y' i
        elapsed_time = 0;
& Y/ _3 r" _9 |, Z- `% W) j/ L" H; X7 o, G: A
        FLOAT        fClock = nes->nescfg->CpuClock;6 w# ]# f0 N+ ^  d
        INT        nRate = (INT)Config.sound.nRate;8 z$ K9 }$ V: n
        internal.Reset( fClock, nRate );+ m3 [7 @8 t% P: I/ t" V; o
        vrc6.Reset( fClock, nRate );
8 Q! r! ], f: s8 D6 U+ u& j8 i# x        vrc7.Reset( fClock, nRate );
2 _$ Z( C7 c% j9 @% m0 \: {4 Q& F' A( G        mmc5.Reset( fClock, nRate );
# M' \& _3 M  Z6 u; Y/ j8 o; R) h        fds.Reset ( fClock, nRate );
7 k3 I2 n1 f  Q6 \. u        n106.Reset( fClock, nRate );) _/ ~! S+ a4 |
        fme7.Reset( fClock, nRate );
  `% S4 h3 B7 @) J  S% Y) }* @# E; T- ]/ x! `
        SoundSetup();: b4 i5 j9 J& c
}7 m1 ^2 o8 \" N- l
* q. k$ f, E  Z$ @2 k
void        APU::SelectExSound( BYTE data )
- v+ K0 t2 H: ^4 Q% r7 I  Y{
8 k: t6 y. q8 R* J' c        exsound_select = data;/ V6 a$ F' W; v& L1 I
}
% ^1 G4 @6 B% n$ R- p- Q
+ y+ G7 B; U6 F! H5 s$ Q; Q, X) WBYTE        APU::Read( WORD addr )
: V  d' R( p" j{
9 d( g) @+ ?, ~' F        return        internal.SyncRead( addr );* I" J2 B9 f) N9 R% a
}
9 A9 z2 S+ P0 C6 m3 ]; P5 F1 K
1 a: i, }' y! d" `" I# Kvoid        APU::Write( WORD addr, BYTE data )
$ J0 z, B- [& m6 @( n{
4 }- J$ v0 P' r  n. ]9 l( M        // $4018偼VirtuaNES屌桳億乕僩
6 S. l  {2 W% v$ C# Y+ t6 B        if( addr >= 0x4000 && addr <= 0x401F ) {
/ @+ E. O4 a. \4 B4 p. f                internal.SyncWrite( addr, data );
) L; I+ Z5 k& o3 z                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
: x& G3 ~" t; i: D" u+ p0 P3 H) t3 d: Y        }
. U/ G' d/ u+ W: U/ k- d}3 i6 ^& |3 h5 w$ E: r5 u( _5 T/ k
3 J: j9 M& c# A
BYTE        APU::ExRead( WORD addr )5 X- p) S4 c/ d: T8 ~
{
; K) ^( R0 ^# x5 BBYTE        data = 0;" {. c/ W" @5 w, i" B( u

! z$ S: O# H  i, o6 c' K/ p        if( exsound_select & 0x10 ) {
" A; L& C1 j" M! j5 z  L2 |5 N                if( addr == 0x4800 ) {* y4 ^' s  }( f
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
* @$ ~+ s2 @+ I& \3 w5 e                }
  K2 ]) `6 f5 D$ S- a! j        }) [, K2 ]* @8 S: T" ^+ f
        if( exsound_select & 0x04 ) {* f( c% @& S& w( v
                if( addr >= 0x4040 && addr < 0x4100 ) {
0 F) i4 e( L* ]                        data = fds.SyncRead( addr );
) M6 u7 N4 H- Y5 ]- U' z$ |                }
& A3 R' \: E; k7 Q' K1 f8 P4 F        }% Y2 ^& q2 G, w9 V4 @5 N* D% T
        if( exsound_select & 0x08 ) {
2 ~0 ^3 |& e5 r0 J! X' N                if( addr >= 0x5000 && addr <= 0x5015 ) {& f3 _/ t: w! X# S2 W- s1 [
                        data = mmc5.SyncRead( addr );
2 }- m  c8 Z& `2 g" g, \                }
2 m2 ]2 s5 k: O2 R/ p8 ~7 ?        }
& ?% D- _4 l: I  @; S0 C  }7 z
! n# ^& @: s0 S$ n7 X% V$ s0 y8 |        return        data;
) s3 J' u$ c5 l% {$ Q6 `9 m}
# k( z# |/ E' \2 F) |1 C6 |8 J, Q7 ~; F, `
void        APU::ExWrite( WORD addr, BYTE data )
+ p2 z7 a: j+ F8 q( Y& B8 K* n{
3 \2 D$ f  A+ ^+ ?6 u        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
* }  @/ O4 u. w( n0 h; D* E' m$ u, F
        if( exsound_select & 0x04 ) {" l5 k& ~* j/ |" c, _6 m* Q
                if( addr >= 0x4040 && addr < 0x4100 ) {0 A1 v8 j5 M8 x  B
                        fds.SyncWrite( addr, data );4 `1 G& P. [  p
                }4 z3 E: E! W% {% P  G: F
        }
# }1 }0 V7 q% V+ F  b: b! h, i( k& D8 C9 Z8 ^
        if( exsound_select & 0x08 ) {
* b  G7 F6 @& D* S) s* }                if( addr >= 0x5000 && addr <= 0x5015 ) {% `3 g* j( z& n; s4 Z) T& g" M
                        mmc5.SyncWrite( addr, data );
) e$ ~1 Y6 B7 J- @, d' h1 @. s                }3 l& P( c) [) d% j7 L
        }
; g# z7 l+ ~5 f7 d# M$ m3 t}  A$ b3 n4 x! ~9 |6 l' U! D/ C+ M, z

9 @- S: O* |* J# [void        APU::Sync()6 G6 [# r7 s8 q, \5 `$ [- V& j
{
, G( A! `' R9 p}
5 L* f% o8 @4 ?( n9 u  x! a3 y$ A& F9 D& H) W
void        APU::SyncDPCM( INT cycles )
  X/ A; X- l1 b$ M! ?{
( i% X" T& W. f        internal.Sync( cycles );
4 A- J) F, c6 z) v3 o  z2 ^* ^
8 o' X1 x$ X# X# |7 i        if( exsound_select & 0x04 ) {. t( `- h; Z5 t/ t
                fds.Sync( cycles );
5 }; J4 S& }1 {- [( j        }
5 E( t2 R! X# c2 `8 i        if( exsound_select & 0x08 ) {6 @" g" ^! l# Y" y6 A
                mmc5.Sync( cycles );# C1 n$ p) j3 v: [  g/ ~
        }
5 Z* p: A2 L. I. m' u1 s" A* i}
5 Z9 E5 G; u' C6 c/ r. |: H+ J7 D. p) J' }
void        APU::WriteProcess( WORD addr, BYTE data )* H0 c" Q8 V3 O4 t5 J2 ?5 o
{8 u3 H0 U" L. M+ m) t$ g5 I4 J3 [
        // $4018偼VirtuaNES屌桳億乕僩8 d- L$ J+ a% n3 ]8 Y! K( p
        if( addr >= 0x4000 && addr <= 0x401F ) {8 G% }" M+ R, d7 F7 g& `. m
                internal.Write( addr, data );
5 ?+ v0 ]1 Q0 P. E3 Z  ]6 J        }
, d8 r1 \) L% C& ], @- U6 u7 l}3 {9 `$ h3 [: d# M

0 L5 {7 Q- x; p0 {7 C* s) j& f' \5 `void        APU::WriteExProcess( WORD addr, BYTE data )7 l1 {* Y/ K' y8 u5 j& E
{% R% P+ E( X1 s& q' o( w
        if( exsound_select & 0x01 ) {1 k$ n& z) E! d  R$ G
                vrc6.Write( addr, data );
* A5 N  W& J. n+ @( J' z        }
. ~% r( h2 r. {  |- n1 @, _4 l3 [        if( exsound_select & 0x02 ) {0 h: }, R2 K" K1 z
                vrc7.Write( addr, data );
2 F: ]. f& Z5 h" K: w        }
3 [" c* g6 _" f' B        if( exsound_select & 0x04 ) {9 ?- e$ }, j7 u0 n/ n0 j9 y
                fds.Write( addr, data );/ S/ Y& Q4 m$ Y" t! F
        }
. u0 U+ t9 U+ s5 k+ N  q" S9 _        if( exsound_select & 0x08 ) {
4 m; {, G: f, k  f4 X0 J4 Q                mmc5.Write( addr, data );/ m5 a% W! B) L3 K. |$ M  }$ `
        }6 o/ a: k; X: R2 K
        if( exsound_select & 0x10 ) {4 F+ B7 N  J" p1 G! D
                if( addr == 0x0000 ) {
3 e. R) z. @0 W) f' p1 H                        BYTE        dummy = n106.Read( addr );% |5 H/ x' q+ w6 g5 q  F; h7 e8 s
                } else {
# R, l0 n9 T( w; d8 j                        n106.Write( addr, data );3 A0 B: P9 h: D1 q/ V) U/ P' _) \3 I+ L$ g
                }
8 W% U. G% H& |4 n5 k2 |        }, r$ n/ O: V8 i' v; }6 U& w0 @
        if( exsound_select & 0x20 ) {
1 Z" n) _$ Q% m. l                fme7.Write( addr, data );
$ ^8 R* U3 C' E" U        }
& q6 Q& d# G3 C# |( o, r}( q( L- g# K6 ]7 o, V  M$ |  u
; S+ Z  c4 u/ b+ o: k* I
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize ), B! B. _+ s3 m: e; h- u& p
{4 G7 r7 @7 }' k8 @
INT        nBits = Config.sound.nBits;3 w( c& r$ N& a
DWORD        dwLength = dwSize / (nBits/8);
8 D4 |- E, Y* j/ k0 D( [INT        output;3 b$ O) p) m- O! P: {9 g
QUEUEDATA q;
- F1 w3 N. o+ X$ a& x9 SDWORD        writetime;
  I" a+ |: `6 v: y9 A) X( Q, K2 i0 d+ N; q. T, A
LPSHORT        pSoundBuf = m_SoundBuffer;
0 Q) c( d0 Y; [" e3 t+ e7 aINT        nCcount = 0;
+ F, H+ T: C: m3 x% S$ U- Z5 v2 ], W) Z$ O7 h
INT        nFilterType = Config.sound.nFilterType;$ M% D1 p; |( o- o$ x7 ]: r
$ U6 X1 L+ E, i
        if( !Config.sound.bEnable ) {. `4 u5 T5 L7 M3 A( Q
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
) j3 O) o: W" c. o                return;
# v) y  x6 L8 e7 b8 s( S        }
! Z1 L. b+ T$ m: R5 u
% r+ P0 q5 O, a8 R$ d  [        // Volume setup. e( r0 r% Z& V& h7 `* {
        //  0:Master
& l# c: T2 p5 _4 D        //  1:Rectangle 1( {7 r* @. ]" n# D. V
        //  2:Rectangle 22 z" |! u3 {1 p. m0 E2 f: ]
        //  3:Triangle
  f* @( [$ M9 R* ^2 G4 }        //  4:Noise) x( I# ~0 O( G" q2 [# d# p2 q
        //  5:DPCM
+ J  p! b: i" Z        //  6:VRC6  r$ i" ?& I' @5 d0 J! z/ j
        //  7:VRC7' ~" w- Z9 E; X1 e0 }* \
        //  8:FDS
8 b: }3 m* r$ l1 i4 f* o        //  9:MMC5% M8 o+ t3 E! r* ]  F( ~5 x. u
        // 10:N106
9 ], |$ j: f4 Q# D        // 11:FME7- m' w7 X" g, F
        INT        vol[24];" y; r; F! P& A5 a0 A3 n% o0 F
        BOOL*        bMute = m_bMute;; m! ~; G* v3 R1 q" ?
        SHORT*        nVolume = Config.sound.nVolume;( ?0 A! q( t6 d7 c6 v
# V  G. W( S6 l, G
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
: X' K. _! B# G; M6 n1 M  ^* R
. J9 E( v4 H: Y2 v7 y3 y: X! i$ |        // Internal  g' Y% |5 v0 w
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
3 O0 K! `1 W; H+ I# ]( N        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
3 h; w# |- r( e& y1 E( u& X        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
( ~1 \2 X1 \" o. g% U# ^5 }2 f6 Q: H- ]        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;7 d$ @  \; \6 e0 @& c0 Y( ~: S
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;& `! {/ v. n3 p5 x: c

- Z- @: e+ Y4 ]6 Y0 i        // VRC6
/ R8 [+ p: b1 P  C' N        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
0 S7 J' Z# `+ i8 G5 D* d/ i        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;6 l4 H8 ?. o3 h0 K8 l) E- }
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
: O- a: A+ Z: k* n" @/ }) J: F; I0 k
        // VRC7
4 l' m& N5 e6 f* w" M* v8 j        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;' G8 K0 E% V0 Y0 F6 h/ h

; [/ l. Y* O# ]1 {: |        // FDS# T. |& U/ F% Q, h2 r
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;* \3 m# s: Z2 l6 n
  x( ?7 g  W% d/ m" t
        // MMC5
" V7 I! D' z4 F        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
" h/ m( k; ?. P        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
. C- X1 I9 L& @2 d: z: t" g' R        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
# p% q! W  L! p9 b- [9 ^$ n6 ?! U  R
        // N106
7 w  R  |: K* ^- @        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;7 {) v3 w+ F3 s5 G  R' Y4 B2 [
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 _; A# Q# B7 c" G
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
! |! v: P0 L+ ?* @; s# \        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ f$ A2 _5 Q: u
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ r5 K" L4 u# y; z9 {
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;# k1 u# H6 d; {$ v/ e+ X
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
6 ]/ [7 l* h8 v; Y+ X& ~        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 O' f* d+ g1 P, G# H7 }& Z( o# H; c6 I* S+ @7 |4 T
        // FME7
4 X2 L' m: a- [" u& Q) k# L        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
1 n! ^) b: X- k  U  j        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;1 z# q- f8 h6 q# I! [3 f8 P* }+ S9 c
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;% ^! A# S* L! Y; A5 K' p
5 k2 u4 p# f7 M# l: P3 D
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;* Z. \6 b% D! b7 |6 J2 \
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;3 ^; ?: }. K8 g
5 v) n, f6 m8 U- w6 @" f
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟: \! _; B' O+ l8 [: E8 S
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {6 S. Q5 O4 L+ Z3 D
                QueueFlush();
$ U# ]0 D: k1 m; m9 m$ ?" @        }
- b- L3 p% w' `0 J+ ?# v8 g
0 ~# J  m1 F7 k+ ?7 _' Q$ t/ l, t        while( dwLength-- ) {
, p5 j8 _0 h7 U( O! q( @                writetime = (DWORD)elapsed_time;
9 _9 G! p+ J) }0 R+ H8 f! i0 \, ?
4 H) L& D7 |5 d" K/ v                while( GetQueue( writetime, q ) ) {
5 X: i- Y/ G( u! @6 k2 B                        WriteProcess( q.addr, q.data );: v9 |: C, W# u
                }
" |: k  A  a. \0 q) L6 q9 |/ \, Q1 E9 o: J5 H+ n. B% ]/ n
                while( GetExQueue( writetime, q ) ) {
4 r# J  N2 ]9 G4 c+ X# a& q% }' l" Z                        WriteExProcess( q.addr, q.data );
$ j) j. U  O" }2 @3 j* f$ J                }1 ~* J  N. k3 |
4 p: f! W  i( x/ r* j
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7& f% V/ H8 \( p
                output = 0;
  t, t: Y) m: {' y6 q: C                output += internal.Process( 0 )*vol[0];8 V: U9 i3 E: ]! |( T  j- Q, D4 e: {& k
                output += internal.Process( 1 )*vol[1];
- d8 g6 h. b6 V4 q% M' Q                output += internal.Process( 2 )*vol[2];$ [# b& S3 V/ s% A
                output += internal.Process( 3 )*vol[3];
, V/ T7 k  h+ X4 j$ ]" Q; c8 e7 ~                output += internal.Process( 4 )*vol[4];
8 m) ?  B; H& G' T* L2 K. C! w- B* y; G
                if( exsound_select & 0x01 ) {
6 s3 S% A  u0 \) U7 U* E, k                        output += vrc6.Process( 0 )*vol[5];/ f  E2 h7 d6 ^+ D  o/ c
                        output += vrc6.Process( 1 )*vol[6];! X5 |; ?2 _2 u. j  a
                        output += vrc6.Process( 2 )*vol[7];
9 A' o- d8 o3 e' c# ~; I. ?                }9 `& `  K+ y  L( h; ]; B
                if( exsound_select & 0x02 ) {8 G2 w8 p7 U& G$ s0 m# v; M  ?& z
                        output += vrc7.Process( 0 )*vol[8];
4 c: R" G; T* }4 R- o9 |) J( J( c                }+ Q9 P* z9 A; f0 [, C$ n& j' F
                if( exsound_select & 0x04 ) {% i8 ~/ ^& D. ~" I, T( j
                        output += fds.Process( 0 )*vol[9];
5 p9 k, |! \/ X4 {; h# @7 k$ V                }
- K4 G9 v. l9 m0 y3 b7 ?                if( exsound_select & 0x08 ) {1 D8 r0 A$ D3 ~+ `) A
                        output += mmc5.Process( 0 )*vol[10];* i+ M5 z$ T3 j# ^
                        output += mmc5.Process( 1 )*vol[11];
% B- Z" b( m5 v$ a9 u+ T                        output += mmc5.Process( 2 )*vol[12];+ Y4 S8 P( ], B/ |
                }7 v7 q  U  |0 \. f4 _8 Q: c
                if( exsound_select & 0x10 ) {. F) X1 o: i( m% r) b' M8 b* v
                        output += n106.Process( 0 )*vol[13];/ q" L. @. ]! T3 @3 ~
                        output += n106.Process( 1 )*vol[14];* x: _& }' c; ^/ v2 n" M- e
                        output += n106.Process( 2 )*vol[15];& N. o$ [' u# R  P1 S  W
                        output += n106.Process( 3 )*vol[16];
8 J3 S1 Y3 R+ q% c/ j# D% U/ f                        output += n106.Process( 4 )*vol[17];
0 G+ F% _9 e  c  t& E                        output += n106.Process( 5 )*vol[18];
4 f: ]( d  y/ d3 E1 V                        output += n106.Process( 6 )*vol[19];1 P1 K, L. A4 d! c
                        output += n106.Process( 7 )*vol[20];
8 f& ~6 t* y- r$ Y5 D                }6 g+ Q! G( {$ o1 s' B$ a
                if( exsound_select & 0x20 ) {0 V1 j* I9 r. {! s- r
                        fme7.Process( 3 );        // Envelope & Noise
+ ?' p2 a& K; ]2 L* {                        output += fme7.Process( 0 )*vol[21];
6 F  f8 J& B/ K% Y' {4 [! i                        output += fme7.Process( 1 )*vol[22];7 p; u" I" t( f8 N
                        output += fme7.Process( 2 )*vol[23];3 ]9 A+ |9 o5 D3 c! b
                }
6 V3 ~( Q# e4 M2 k2 i: D7 b' g6 l' ^+ }& H  A1 U' J
                output >>= 8;1 e- \! Y- r: A% j

) f  [$ S7 b; _3 V* q                if( nFilterType == 1 ) {/ \: o- v  J6 g- i3 J
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)* j8 N" p7 q. z& m- |% W4 v
                        output = (lowpass_filter[0]+output)/2;
, m$ _1 ~/ V, c& w0 |                        lowpass_filter[0] = output;
  |- ^2 v9 a) w+ U                } else if( nFilterType == 2 ) {
2 I/ t( z( {, g" U                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
; a4 ~# I+ v  O% M                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
! E8 o5 v6 @" e# @/ Y                        lowpass_filter[1] = lowpass_filter[0];8 t& s/ D+ |  i3 G# g4 o" _' c
                        lowpass_filter[0] = output;
9 q9 Z; M0 k8 t# e" s' s- m8 `                } else if( nFilterType == 3 ) {. h. q7 q' ~8 c, m  P5 |
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
  p3 V; O1 H; n  A2 D                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
9 l  n! u) Q7 T$ U: G                        lowpass_filter[2] = lowpass_filter[1];
. I5 f: O# l7 I4 Y                        lowpass_filter[1] = lowpass_filter[0];
# h  G& l# Z* x, {# v% W9 _                        lowpass_filter[0] = output;
8 B$ S6 g; H: t& N                } else if( nFilterType == 4 ) {( Y: G1 L# L6 g  z8 l7 W
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)& Q/ o/ A5 i! d4 {
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;1 Y, N0 v2 F  I# r& Z5 P. i; x' k
                        lowpass_filter[1] = lowpass_filter[0];
* Z2 H" Y3 q+ J                        lowpass_filter[0] = output;& ?6 j) ]6 ~/ T* l' V5 T
                }3 `- Y3 f0 u- G% ^0 w, N2 L

! A: ^! P7 h% o/ \#if        0
4 J% b. W- f% ^- z                // DC惉暘偺僇僢僩
& r. ]  S/ r$ F                {! r" S9 G8 E5 X! E/ F6 h
                static double ave = 0.0, max=0.0, min=0.0;- Z  i) K: J& \
                double delta;
3 u3 j. P! \  [+ i                delta = (max-min)/32768.0;- H! y: C) i# j- A. A, @
                max -= delta;/ F- e: B" j0 A) Z5 |: l# _; V
                min += delta;
: X) q; R4 h7 S' P" D) h0 `                if( output > max ) max = output;
) m. d5 @* [0 E9 a                if( output < min ) min = output;
0 Y3 r4 r7 R& g9 N* z                ave -= ave/1024.0;) T) b2 ^2 m" ]; I/ B
                ave += (max+min)/2048.0;, a' u" l- K* Q, Z  ~! b
                output -= (INT)ave;  Q! T6 ~! H3 ~+ s; e' D
                }
/ ]! _8 U% O; s) k/ l#endif
  E+ U, _' w- a% B! R* m#if        1' N( x8 V2 I! I5 o3 }
                // DC惉暘偺僇僢僩(HPF TEST)7 V& b. f5 X5 f0 U' l
                {
# T6 L5 i( v7 `//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);; j* m- \- Y& z/ T3 h. V
                static        double        cutofftemp = (2.0*3.141592653579*40.0);$ Z- |$ U$ w- G" e
                double        cutoff = cutofftemp/(double)Config.sound.nRate;9 _& ^: J. a2 U+ W: j- ~6 ~) K; U
                static        double        tmp = 0.0;% p# a  e; M, z& X9 _6 J0 F
                double        in, out;
) B3 U* x7 ~: P0 I( p' l" c5 A) z  s
                in = (double)output;8 a- ?/ ^1 o" i) i: H& s; |3 k
                out = (in - tmp);1 \' _1 E1 I) Y
                tmp = tmp + cutoff * out;
$ I( s! ^8 D! \5 ?0 Q; P+ X/ S; L3 {* ^9 h; l# j8 s- @
                output = (INT)out;
8 F' V2 ~6 r9 m                }4 T2 M6 U  r7 K1 M3 q5 j
#endif! _9 {% a- W9 p
#if        0
! A" `* P& C" j% |                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)" _; ]0 A/ d0 u# [" c) R: u  Y, x
                {
- b% C( t, N; Q5 R8 n9 C) O8 b! T                INT        diff = abs(output-last_data);
* ?" D" ]/ }. _3 E" Y8 z) W                if( diff > 0x4000 ) {
/ m# O) O, P' P  o                        output /= 4;5 \9 D; u* f2 m1 c" H
                } else   ^4 h! P; \1 @; T
                if( diff > 0x3000 ) {! J6 n: S% C# n6 x, }( w
                        output /= 3;  u; \- O% B* N# _. f* H
                } else
* L: t. Z$ p, s1 ?                if( diff > 0x2000 ) {, {4 {4 C5 ^, _$ h3 \
                        output /= 2;/ K# |9 W& y/ \. C8 V! R5 s% O
                }! ?0 Y2 |1 ~  G
                last_data = output;3 C5 s7 S6 D  L0 p8 n1 }$ D
                }
  W, N* M1 o$ s2 x#endif0 y& B0 }- }4 G" t5 D+ q+ ]
                // Limit% ~6 I) q* I. x. U) e
                if( output > 0x7FFF ) {
6 g7 w+ b2 o$ F) ~3 N6 {                        output = 0x7FFF;7 h- C  j) W) Z; C% K0 V/ [' I
                } else if( output < -0x8000 ) {1 r, r$ A! h+ f% u1 y( j2 v
                        output = -0x8000;
! G7 Y5 ^: T- Y8 b9 V& R6 a                }3 W% M, t- [% I" v6 Y
0 g! _3 z# ?* ?" b
                if( nBits != 8 ) {
, B) R* F, J4 _+ j+ p+ N                        *(SHORT*)lpBuffer = (SHORT)output;
' r; u1 F  o! Q" ~                        lpBuffer += sizeof(SHORT);
  L1 P  M0 v& \9 Z: _4 c  {                } else {
- x7 A( a7 @0 ?! @$ a9 b: K! g1 U: J                        *lpBuffer++ = (output>>8)^0x80;
# [7 N# D( P- J/ P, r9 k                }
, n" J' Q; B9 z0 \& C0 Y  [' K1 K; t' D
                if( nCcount < 0x0100 )
+ p9 b% v& ^0 z) E& B* ~* o                        pSoundBuf[nCcount++] = (SHORT)output;0 s3 S) s$ X6 j# X  `
& L8 _( f% h1 z
//                elapsedtime += cycle_rate;& B9 k$ ~- y9 P4 s) o
                elapsed_time += cycle_rate;) u4 ^3 W& a6 L: f& e/ G! ?
        }0 n1 ?9 ~& p: m5 `* H3 h1 y

& {! N" B' X" ?2 [6 Z5 |8 _" y# d/ p6 ^#if        10 H! z6 `. j: \- G% f- M2 F* i
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {( \( P' g. y7 R0 t* R
                elapsed_time = nes->cpu->GetTotalCycles();: h1 s9 x$ P$ a  r5 P. I% M5 i' o
        }
# r" u+ t0 M4 `        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {" f: l/ }- r; G2 Z1 C
                elapsed_time = nes->cpu->GetTotalCycles();
1 s4 K+ j- f  A        }$ Y4 j2 a+ [3 r1 u1 |* t$ c2 n
#else2 E% a1 G0 e3 I- W. s. @% s
        elapsed_time = nes->cpu->GetTotalCycles();
. I. D- Y% L0 ]' f3 E#endif  G+ }0 F: a  _1 f' s5 G
}
6 i& {) S! F7 B2 Q& o
7 S: L: E  D( w( V// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
) p/ V; L5 \6 y# A2 `1 eINT        APU::GetChannelFrequency( INT no )$ s9 s8 l5 }4 G; w/ D0 x
{; R5 t9 P3 u# T# C' f4 T) R* f9 k4 p
        if( !m_bMute[0] )% D# x4 G1 `& u: i% c$ U
                return        0;
) z# W+ x- n4 H3 J/ e
5 r1 Y* j: T# e4 W5 F9 d2 y        // Internal- _+ w1 f% X" I  w4 K) d6 N
        if( no < 5 ) {  D2 P# L" @4 t
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
* j) L( c/ W) t' v! g        }6 C, A8 E3 p: b- U
        // VRC6% S2 N* \* \' j3 ~
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {8 o  Q0 V/ @2 P7 P7 I
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;5 n5 Y9 B6 F& f/ q
        }
9 E) m0 G, s" U1 K7 s7 i4 `" e6 N        // FDS
- f7 v- U7 s4 B& N        if( (exsound_select & 0x04) && no == 0x300 ) {7 X$ }, b9 p3 r0 X) O* w5 \
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
% u) x" R, _9 o+ w/ J. I" o        }
4 Q& M8 T/ J6 R$ t        // MMC53 X8 ?) s' ]: a  y6 Z
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {$ S2 h6 }6 Z% K# M! N, R8 X
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;  r2 z. O/ u0 X! o' ^
        }  I$ d- {& u! T& Q' Y
        // N106' X. V, b9 Y% W) @% `$ q
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
+ w8 e  P" }" I                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;: W2 j* f$ f) _
        }
, q+ R3 G9 \& X        // FME7
3 T% Z( N4 ]% }3 |& o        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {" h% m+ A% y/ N1 B
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;$ d/ r" w- A+ Q# |7 q9 ^/ k4 r* h
        }
( u; N# j$ l# h, o8 |$ g! S) _9 U        // VRC7
& ^6 f) h/ t( V* D# Z  V5 R        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {1 v+ t5 `8 ^! p8 F$ Z0 \
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;1 p$ q4 X+ q, }4 X
        }
: b2 e' G- v, U5 y& S7 ]        return        0;
4 G/ X' H# J+ x& H* f# o0 f}
7 A5 x1 C- K' Z8 d- v4 h( E# X
( S; E9 k9 E6 ^% U// State Save/Load
' n% [' n+ N) j  a8 S# P. O- kvoid        APU::SaveState( LPBYTE p )
9 y. z( r, a4 v8 N1 V- e  \{2 u: m) T# m. L& W: O: ]
#ifdef        _DEBUG7 J8 {, J* S, O  x; K- s
LPBYTE        pold = p;' u, `0 Z3 Z/ u4 I* k
#endif! a8 t" k! h( G. z0 W( N
. y% Y+ ?5 w  |* E
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
3 r+ c' [4 ?+ O9 ?$ c3 B        QueueFlush();) l8 w, M0 Y- G$ Z" _7 Q5 P
( a: X. j$ ]2 l& I6 i
        internal.SaveState( p );, q+ R# F% }) a5 @: U% e
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding7 n( f, F$ |6 d+ s

5 g9 W" x* }: s+ s' f: }( X- T        // VRC6
/ x! k: C2 f7 ]$ X5 a3 {9 C        if( exsound_select & 0x01 ) {
5 s" Q; P$ T* F; w: h% G# E                vrc6.SaveState( p );& f" V) _# O) m- {" K: u
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
# Y- z7 P5 `2 h  R# D. |6 B% ~" Y        }
1 {8 }3 b+ ~4 q2 m2 M8 E        // VRC7 (not support)
# k8 H! H4 J+ H0 a" V% p0 V        if( exsound_select & 0x02 ) {
+ A' m+ Q! m# y2 b# q6 i5 Q                vrc7.SaveState( p );4 A0 L7 O1 y5 ]9 G
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
0 M( U6 w$ ^, l4 E' \" e: V        }
+ ]3 w$ A6 I$ X        // FDS, k& d( y8 |  I+ }# H& Z
        if( exsound_select & 0x04 ) {+ N! p: z8 ^3 E
                fds.SaveState( p );
- `; F; U: m  l/ @' w4 m                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding, D3 x, D( P* V; l4 L. \
        }
: g' y; ]- y3 y5 S; x        // MMC5' _+ Y6 P4 P0 c2 x& J& Z: U
        if( exsound_select & 0x08 ) {
' h9 ]6 l5 W: ^+ k4 ?! ?2 _                mmc5.SaveState( p );  \( K& ]3 f$ ?1 V0 m2 n) j* b
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
, t0 \" v5 @+ I* E        }7 Q  c  }, |# f/ L1 O
        // N106" U# I* }  o9 ~" i5 |1 J
        if( exsound_select & 0x10 ) {
; y8 Q9 b  n- [3 j. m; E                n106.SaveState( p );& W, U5 D3 F2 ^3 s& ]" n
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding9 h1 W5 j1 t% i3 z
        }
& P7 ]% J! K5 w- e4 f        // FME7+ X3 x3 {$ {% G, F& g- x' p: O
        if( exsound_select & 0x20 ) {
5 N, Y8 t. j: I                fme7.SaveState( p );
5 r; O  g4 r2 h: a- O                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding! r% n2 z. n/ w& |# r* I% ~
        }. D2 ]& o# x0 y6 B
9 e. q) w* y2 ~" I* n9 E% B
#ifdef        _DEBUG4 E) j' j! P5 h$ d$ \
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
# v& m* j$ f+ i  E' L#endif
8 c0 Q2 J9 x( m' N}0 ?/ R$ O# S" w* w! D& q

* [$ z( {6 [3 P5 H* O7 ?% Q7 d! S4 Fvoid        APU::LoadState( LPBYTE p )! a: L/ ~$ V% O2 j; ?
{% B" M) {0 {+ Z0 o; _" f/ j
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
+ W& e/ l1 ^9 w        QueueClear();
! \( h& x/ `7 v9 K2 j+ N2 ^' {) r6 o, ?9 k1 T4 F) ~) W" h: }
        internal.LoadState( p );( h4 c3 @! E, S( u% F: G
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
* K; {/ u* F4 S0 j, g
& p* m1 v. ]0 O9 f# a        // VRC6/ l' y3 A: `; D
        if( exsound_select & 0x01 ) {1 \: P1 b) {6 q6 @% E- e, N
                vrc6.LoadState( p );" W6 T8 D8 }2 m- Q1 D& f
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
3 t' M. b8 T# j        }
# H  o5 B( ]& s) J4 ~        // VRC7 (not support), c8 x7 J. ], d3 A
        if( exsound_select & 0x02 ) {
+ W% O. k1 c+ }0 l( [: y                vrc7.LoadState( p );
* ^9 N5 k9 |( f9 {6 G                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding: L. S1 Y/ W; n3 C% w" F
        }+ U% i; d/ L+ F4 b0 X( R& r, P
        // FDS
# N/ U' g+ S' _- e& V        if( exsound_select & 0x04 ) {
% o& r7 v' I2 z, b0 M" J# l' [                fds.LoadState( p );6 W5 E7 L1 Y9 U6 Z3 B( E4 }+ b
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding1 x, s. D* Y7 S6 R3 N' H1 w
        }
! W8 |6 o6 p0 I0 V1 Z/ G        // MMC5* S- ~% ]5 N( I
        if( exsound_select & 0x08 ) {
/ e! d5 o' K. k0 z7 T6 M                mmc5.LoadState( p );# J: l0 X0 m1 {+ v- Z/ A. i
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding2 z8 u2 j2 a2 _2 B* a
        }
/ z* I0 U" d$ ]1 Y        // N106" u" ?; [/ D: D& B. f* D
        if( exsound_select & 0x10 ) {
- z2 M, O: s  V* l& G( @: y" d                n106.LoadState( p );3 H& ?0 O, H  Q8 S# S8 s
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding2 v5 p! K  v3 E8 C  j
        }* R. {5 h' ?6 E, L; a) q3 l4 I
        // FME7
% }* ~7 Q0 S% w2 W0 Z        if( exsound_select & 0x20 ) {, v' u* {- l0 M) v+ V/ R
                fme7.LoadState( p );5 \& }1 h8 ?$ o( ?; [& J
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
* V7 G+ v$ R; Y        }
$ R* |9 q8 X- p! w: Y3 U4 K, s}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 " |' i# D* Q3 L' t* d
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。" _1 ?! v* V! C$ f1 ]. m# ?
感激不尽~~

1 J& M; d+ W" _, |$ e恩 我對模擬器不是很有研究,! m6 x% E  T4 [7 X  l# r
雖然要了解源碼內容,可能不是很困難,$ ~- n# C, P- `) A% T1 |$ r
不過還是要花時間,個人目前蠻忙碌的。
% |0 o$ m& |8 P6 D2 R# i! j* {0 r6 X1 S  k: |, Z) S
給你一個朋友的MSN,你可以跟他討論看看,
) H" V' o( n3 a$ h1 ]' ?7 Y他本身是程式設計師,也對FC模擬器很有興趣。
  Q; v0 O/ R$ K2 c* ?9 a
0 M; L2 j  q  N2 M6 ]2 t3 ^4 [MSN我就PM到你的信箱了。
/ e9 V4 R) L; Y6 ~+ T
) l( g3 z5 ^, Z( A希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表   L, n' v, l, g+ G5 v% u* s1 G8 I9 y
呵…… 谢过团长大人~~
9 b: t% ]5 U! v; C) O/ C; T

: V: T: Q- J- Q8 b3 R" o哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 + i2 c7 u' i) S
团长的朋友都是神,那团长就是神的boss。
- v" g3 {$ [+ @0 S+ F' S
哈 不敢當,我只是個平凡人,# h1 L4 S# Z  I& ^# i( Y0 M9 Q" L
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
* x. \4 q5 O$ J1 k2 F! yZYH* R0 m; u/ k7 D, c: K5 x* z
QQ:414734306: \6 P" v5 R+ G' E: ^+ ]9 W
Mail:zyh-01@126.com5 o" M* N' H/ b
/ H. z; h# u, h
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 9 d! S$ y/ S; s  O
再次对团长大人和悠悠哥的无私帮助表示感谢~~

" e, s$ U* c- k2 _不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-2-28 05:03

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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