EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
/ j8 W' w7 Y3 N楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
; R8 D, L, g2 M, U这里有相应的模拟器源码,就当送给大侠了~~0 Q" o  q1 D' i, o
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 & W( l$ \; C, r' m% o; c$ [
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
" {1 R1 Q# h$ d楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
9 y# T( \+ B+ J6 I  \7 g这里有相应的模拟器源码,就当送给大侠 ...
7 l3 L: U$ s5 h/ u, N2 b
聲音部分(Audoi Process Unit = APU):% r% ^; |3 n) y
.\NES\APU.cpp7 D; G' S. a0 s4 M  [$ V- s; E
.\NES\APU.h# O, z+ k' c2 B3 u
& |" [( D! \$ O
; L: q- [1 B  \6 M
影像處理部份(Picture Processing Unit = PPU):3 G# |+ @7 u# j0 e$ t6 \" c
.\NES\PPU.cpp
& a- P& I0 V' p" S- h( P.\NES\PPU.h
2 m$ g2 o; Y( f( F) D2 o/ O
6 @9 j. @# Y6 m2 n: t4 e  n+ g% c) O如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:) F& w: Z- F4 ~5 g! A
(由于很多专用术语和算法机理都不明白,所以看不大懂……)2 j! |6 X( |; o+ {& v8 U
//////////////////////////////////////////////////////////////////////////
$ z7 |  f6 I+ l( t$ ]3 y//                                                                      //
. D3 J4 l8 P# ~+ H//      NES APU core                                                    //
+ O5 x" J* n- X9 ^5 M' b  b. [# q//                                                           Norix      //6 e8 t; k" E$ A# }! Y  `3 i. {' N
//                                               written     2002/06/27 //) {+ M$ N( N( v* [5 P  M  U
//                                               last modify ----/--/-- //
( V! P3 n3 w2 c  x  O0 W; p//////////////////////////////////////////////////////////////////////////( \2 V8 a# Z! ]! w. N
#include "DebugOut.h"
6 I) b4 A6 z5 v4 L8 C#include "App.h"
" t- w) E9 L1 ~- c# A6 y) l#include "Config.h"1 B. i# K0 Z4 J0 r& k. G# {
! ?* G7 E3 v, Y% f2 s, O% g
#include "nes.h"- T9 ?/ \; ~4 R0 X
#include "mmu.h"
9 Q7 H5 b% a$ v/ ^6 R; o6 d* H2 J#include "cpu.h"8 F+ v% l( r: r
#include "ppu.h"
0 |3 r, I9 g$ p# p#include "rom.h"
) s8 I3 y* L7 b' R8 }#include "apu.h"
" b6 ^4 ]5 _6 A& j- [1 R- @) \, ~* i6 W4 L  y4 e) G! x( t
// Volume adjust: z( `1 t( D+ A5 B. v) }
// Internal sounds
) E1 w2 g( u* M. s#define        RECTANGLE_VOL        (0x0F0)
1 k% m( t2 ~- [/ U, H9 `* @#define        TRIANGLE_VOL        (0x130)
0 U" n) P- ^. [$ K7 r% \' o  r1 H#define        NOISE_VOL        (0x0C0)
4 k/ M% D. _" A( G#define        DPCM_VOL        (0x0F0)* w0 |7 h  {; Z/ i* U5 c4 v
// Extra sounds
" g- J4 X% j, c& J% w#define        VRC6_VOL        (0x0F0)
  k) d; ~' u& O" Z* h#define        VRC7_VOL        (0x130)" x  u4 b/ p$ P+ d, m! L
#define        FDS_VOL                (0x0F0)+ a. w, ^$ ]5 w0 m( [! s  w# U
#define        MMC5_VOL        (0x0F0)
9 S5 o2 L  Q, t6 o( e& S* o+ ^#define        N106_VOL        (0x088)( N0 }4 p1 B: v- n
#define        FME7_VOL        (0x130)
4 i/ G* V' Y- y* g/ N5 ]5 e. g) X+ o6 Z( Q9 Q: {# [- C% G
APU::APU( NES* parent )5 X0 |( M4 O! _% p$ Y
{4 s$ \% y  x) a( D! q! B
        exsound_select = 0;
: z& f  H* |& n# Y9 h9 x
; B* T0 F* f, m1 i& t6 U; m0 b        nes = parent;
, Z! D, }: K; y" Q: M        internal.SetParent( parent );9 L" [8 U2 P& |. _' y6 F3 x# J/ e  [

7 t- k* q+ W7 W/ N2 o) v: u1 ?/ }3 k        last_data = last_diff = 0;
6 ]4 {4 o# v* e/ e/ L' T9 d
' q6 f4 c: R+ Y        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
' u. H2 L) ?3 y4 v, l
! O  o0 H; r$ X& b3 X        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
7 p+ @8 J( M% P" \        ZEROMEMORY( &queue, sizeof(queue) );5 j3 z! J( @$ C& ?# b+ a8 b
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
) G6 a4 `$ o, J6 V
1 u, @/ ~! N) k/ J" X4 V( I        for( INT i = 0; i < 16; i++ ) {
' H; M: ?! c" i4 \                m_bMute = TRUE;0 L# l5 s( @5 t$ j
        }
4 {1 H  h8 f; l" r}5 ^" l& P. s2 \' t, z  E* c

" N7 K( u/ u4 c* ?APU::~APU()
5 T+ u, u2 B$ f. e4 |{9 D$ ?5 `/ w- T, U$ `. J; S2 \8 v2 O# t
}
: f, q" N4 M, t  c; q$ L" q3 Y% J* r+ C. p
void        APU::SetQueue( INT writetime, WORD addr, BYTE data ); j" ~7 Y$ R  m) Q
{& S2 Q& \2 B9 Y3 A
        queue.data[queue.wrptr].time = writetime;5 O4 |- i4 `& p1 m4 I1 \! r, R
        queue.data[queue.wrptr].addr = addr;2 m4 e: A9 V! R6 o! Z7 F/ n( L- [; r! s
        queue.data[queue.wrptr].data = data;! q. f2 G- b5 ]$ \# x, G
        queue.wrptr++;
, E) F+ i5 Z2 I* Z        queue.wrptr&=QUEUE_LENGTH-1;! t; x  Z6 D; P+ `: c  }, j% M; _
        if( queue.wrptr == queue.rdptr ) {
) A, k7 F5 C: v# c! S  d                DEBUGOUT( "queue overflow.\n" );
" z$ n! e/ {! n( J! r        }
6 G+ `. w5 B% @0 [}
6 j# o! `7 D4 X: T) L, a( A2 N. k6 }- o' U, v! ?
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )" Q9 a9 ^" o! Q8 D/ `. ]+ J
{% i7 X. d( Q: D' }0 P7 Q
        if( queue.wrptr == queue.rdptr ) {
/ L" i) r8 F2 `                return        FALSE;& Y' U4 I* C' l/ n# e" m
        }4 J( G, O, x- K1 O
        if( queue.data[queue.rdptr].time <= writetime ) {3 D# V& B: C9 u8 n9 y+ d# W7 d
                ret = queue.data[queue.rdptr];) r* Q" k% l+ B9 V3 G4 p0 \
                queue.rdptr++;1 v/ I8 v- T- x$ k+ t5 I* f
                queue.rdptr&=QUEUE_LENGTH-1;2 Q& B4 R7 v) C; Z9 q' n
                return        TRUE;- O# w8 U. ?" l' z! R" d
        }+ M* D6 |. F4 ~$ f; ?  i4 f
        return        FALSE;
- }: A, f1 J1 R' P2 {5 z}
% O0 j9 [6 p" j1 f  e, B: ]4 e
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )7 a6 |( h0 t' x; ?/ k; J
{
& y5 f1 W8 b1 X7 o1 y5 \+ w# X" e  x$ W        exqueue.data[exqueue.wrptr].time = writetime;
0 I; P: p% D6 d& v. _3 \: W        exqueue.data[exqueue.wrptr].addr = addr;
: ]# U: D0 D1 e: z        exqueue.data[exqueue.wrptr].data = data;5 r8 i( @: J$ B% ]9 m
        exqueue.wrptr++;
( q: Y* Z6 h9 P, X        exqueue.wrptr&=QUEUE_LENGTH-1;
& o- L/ K* z  t4 R. [        if( exqueue.wrptr == exqueue.rdptr ) {
. Z6 N/ @6 h& z9 q$ s                DEBUGOUT( "exqueue overflow.\n" );
' H# _- X2 H$ P        }
: D# Q7 Y. K8 Z, I, _1 G}
( S2 V4 b- b( V( g; x4 d% G; M% J: j3 |
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
5 o$ L- V+ g5 ^: U1 N{
$ `: \  `! Q3 \6 }        if( exqueue.wrptr == exqueue.rdptr ) {+ F" s; n+ U. f! i6 z& h3 A
                return        FALSE;
! y4 y$ X: J& t& k. {! L        }
& Q7 O8 a0 L: ?' P5 }        if( exqueue.data[exqueue.rdptr].time <= writetime ) {7 u9 [9 b) c. T; D, [5 N
                ret = exqueue.data[exqueue.rdptr];
. k; V5 L: G9 e# s; e                exqueue.rdptr++;& X4 c  t" @/ Z5 ~# ~
                exqueue.rdptr&=QUEUE_LENGTH-1;, i! F3 P2 q2 n
                return        TRUE;
0 Q: P) Y) a; M) W  r" n4 j        }. ?3 f' [! s9 c# q
        return        FALSE;+ v6 x/ ?  y. D# o1 W1 d# n
}2 V7 Y6 n2 g+ p- W, `
- ^/ R8 J  Y7 z4 y
void        APU::QueueClear()
# W) v4 y; [  W( ~5 y7 D{: V2 ?5 K1 ~2 Z6 b1 e0 L! `
        ZEROMEMORY( &queue, sizeof(queue) );& O. r$ q9 F* l0 A. f$ f, J# z
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
/ W9 P. \! `, |- j}' U. b9 y) {8 W" B
) _/ n/ U1 n- W) ^6 l3 L4 d8 `
void        APU::QueueFlush()
1 m/ j' ?5 r* U* h# k{+ b) X5 D3 s' _: L! s6 h
        while( queue.wrptr != queue.rdptr ) {8 Z  U) c8 Z# B4 N
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );4 A/ i. p; E: H
                queue.rdptr++;
1 T8 K! @+ B- l4 q7 u* M" o                queue.rdptr&=QUEUE_LENGTH-1;
0 s  ~9 T1 T( N$ U/ l% M# M/ N        }
$ H  a' Q: q. h; G" T6 o6 v" F4 H& A" f) }4 i% ^
        while( exqueue.wrptr != exqueue.rdptr ) {, l+ E. H. K  C! X
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );1 h1 d4 f% d) o% @5 L; M  `
                exqueue.rdptr++;
' ~; Z. t; d1 f* Z! S! P% J: N                exqueue.rdptr&=QUEUE_LENGTH-1;
) K2 C! Q( M9 R" ^* e; X- U        }8 P' W1 V4 i# _( K% ~7 a
}
: m0 e. z! M/ P% D$ I4 ]7 S- |/ Q" }
void        APU::SoundSetup()
% P% T5 Y1 N* ?2 Q% {{+ T$ ~/ P. V# @9 {
        FLOAT        fClock = nes->nescfg->CpuClock;) C8 E. `! }0 X2 b  N5 B
        INT        nRate = (INT)Config.sound.nRate;% H( k1 z+ {7 P0 t2 f
        internal.Setup( fClock, nRate );& t8 m" E- S9 ?; w6 ?& r
        vrc6.Setup( fClock, nRate );8 ~- F0 q5 m; G) ]( Y
        vrc7.Setup( fClock, nRate );9 _+ ~4 _/ _4 n$ L$ n& `
        mmc5.Setup( fClock, nRate );) u3 G9 m& l( w
        fds.Setup ( fClock, nRate );
  ?& ]# x: ]; ^6 M. B        n106.Setup( fClock, nRate );
7 {* ?+ _+ O5 a2 e        fme7.Setup( fClock, nRate );
, S& D$ S/ g5 T3 ]}: S, N1 u1 R1 ]' p. B
; M6 d  \& H& c
void        APU::Reset()
1 \8 u$ f. D& a% j, k% p( N& {& A% q{
( V' P9 e3 y6 w  i        ZEROMEMORY( &queue, sizeof(queue) );0 t- q. Z% I% s6 F0 G( b$ b
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
1 r9 w; I# S! u+ W
" I  k' c/ T4 l- l( e        elapsed_time = 0;
: O; X  B2 z+ H7 U6 m
1 }" D5 g/ c2 S0 Z$ N& L        FLOAT        fClock = nes->nescfg->CpuClock;
8 Y( J4 [" J; g( |5 T        INT        nRate = (INT)Config.sound.nRate;
2 q) A; J  U5 u$ r" r2 }* X& @        internal.Reset( fClock, nRate );
! n2 A1 S5 p' ]3 Q; I        vrc6.Reset( fClock, nRate );! S- i1 g( [/ {
        vrc7.Reset( fClock, nRate );- M: ^# J* t! T0 o* L% v, {
        mmc5.Reset( fClock, nRate );) S; [* c* S# u
        fds.Reset ( fClock, nRate );! c& n2 ]  |: S. Y. T" R
        n106.Reset( fClock, nRate );
/ I3 }" }1 _1 f5 `2 p( P7 m; S+ a        fme7.Reset( fClock, nRate );
) m3 \+ c* e' ]$ [, w- x& y+ ?2 W6 G. a8 B3 T4 R+ \
        SoundSetup();! w+ {( t. E, M- S; u4 a
}
" U, b) f& V$ @( X# A3 B7 l' Q$ |4 d3 h
void        APU::SelectExSound( BYTE data )
% l) S- A& |2 i6 Q, M: }{' @) ]. W0 D7 E" @) w
        exsound_select = data;- u5 n; U; V$ f+ p( h9 }
}
+ P+ o1 F) l* H0 I
" Y- X; s9 C) q  L" g1 YBYTE        APU::Read( WORD addr )
* B) G) ?8 u2 T{
. `2 k& G# H: ^& q' [        return        internal.SyncRead( addr );0 d3 Y' u, J5 W  v  p: Z& e
}9 ?( I# r+ {, j# g) O( m: W" Q

# U4 I. ]8 O, N* i6 O$ cvoid        APU::Write( WORD addr, BYTE data ), U1 t, b- l4 x1 a; K/ C8 a3 m8 C
{
! r* G! L1 U3 I$ V, ?5 ?        // $4018偼VirtuaNES屌桳億乕僩  l6 L3 a+ G& |5 A; C5 G4 B5 s' I
        if( addr >= 0x4000 && addr <= 0x401F ) {
0 O1 @5 i9 _8 P; B) V* l, S4 O6 }                internal.SyncWrite( addr, data );
  y8 h5 W' h- x                SetQueue( nes->cpu->GetTotalCycles(), addr, data );! N+ E1 F& L' G
        }
( d% C: i- v3 M: N# K2 |}
4 w: t: T7 X5 Y) X  [2 J! J( D% X  ^$ K9 k+ }' `
BYTE        APU::ExRead( WORD addr )! K4 Z0 |0 V: g& x% {
{5 v8 O/ B0 h! c3 l/ n+ S
BYTE        data = 0;
$ v3 m" J) J" ^# u: g5 Z
3 K" M" e& z0 G4 `2 o6 E        if( exsound_select & 0x10 ) {
) }: ], g3 \% p1 N# f* c1 |                if( addr == 0x4800 ) {
$ _7 i" y2 P. i& c                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );: A# y: r/ }# A
                }7 f$ U: c. F5 W& U% ?& p) d
        }& A0 I# v6 \. D' Y
        if( exsound_select & 0x04 ) {
; y5 X2 b1 y& M$ t  W* ?# s                if( addr >= 0x4040 && addr < 0x4100 ) {: M+ p2 i0 i2 D( m
                        data = fds.SyncRead( addr );
2 e+ A9 O5 }% t5 m5 z# z5 m                }. J" I# `% l: w& s* V2 n! v* r" c
        }
# r! w1 ]1 y# g2 v        if( exsound_select & 0x08 ) {( r9 ?/ {+ C( _7 ?  }+ `) }
                if( addr >= 0x5000 && addr <= 0x5015 ) {
$ I1 ]2 B7 @+ Q5 \                        data = mmc5.SyncRead( addr );
- c& H! F( q3 e9 c/ ?; z3 R                }
5 S. C1 Z) m" l5 G        }
- |/ Y' U0 m* ?' u- l
4 ~9 w( }# D. w1 n# y( z8 z8 e        return        data;
/ k0 z( z( g9 @3 U}
/ T; n2 [3 L9 k
  z' z2 e' ^( W0 w  R! r- h) ^) e9 Evoid        APU::ExWrite( WORD addr, BYTE data )
* S* B. A( C% L( J" A{
6 `( {% j; R7 M7 e: x6 R        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );+ A  W: s2 c" G

3 d( v4 I! ~/ I# R        if( exsound_select & 0x04 ) {
! x+ V# z- Z3 I4 W' Z                if( addr >= 0x4040 && addr < 0x4100 ) {8 g9 `, j" z9 p! l1 s; L2 M
                        fds.SyncWrite( addr, data );
, g, q4 K8 e2 j( h1 B9 j6 P                }8 h* [; k) Q! e! \2 g! E2 }- _
        }
$ T! Q  K' m' m( g( C/ O$ q! f, _4 r$ Q9 {8 W
        if( exsound_select & 0x08 ) {: b) _) F+ r- j' ^/ E
                if( addr >= 0x5000 && addr <= 0x5015 ) {
! X" m2 D! ]) S- A/ Q( H$ y" v3 o$ P                        mmc5.SyncWrite( addr, data );
; G7 K% M' S* \, F                }2 u0 ^9 Y4 K! C& C5 N
        }7 l8 q# o* g  ]9 }# w0 X
}
$ u, {7 h' ]) a! c- L  M& T0 g! f) |5 A
void        APU::Sync()7 z. k9 K5 V& m, W* ?  L7 ]
{
8 C3 j( e) J0 ~' H7 |}4 K6 L7 k" G9 m$ m$ C% j

+ H6 Q, d) W3 G! j; ~/ N; R/ I" nvoid        APU::SyncDPCM( INT cycles ). h+ M4 i4 H2 t4 K; [1 D
{# t8 S9 \$ A9 t: d! o
        internal.Sync( cycles );
' w: `% x8 N: W/ M
* n6 s- [# j+ n. d- e5 f8 H        if( exsound_select & 0x04 ) {2 F, p, l2 t5 ^* l3 g, z* o
                fds.Sync( cycles );  l7 y5 [1 ]" V. U, w- A
        }; e* C8 c$ V7 e7 ]: a5 W/ X
        if( exsound_select & 0x08 ) {8 k1 n) k4 x! V; }3 J
                mmc5.Sync( cycles );6 N( V0 ?; n, C/ \2 B
        }" T7 g$ J& i) m8 \7 R, n
}
6 A+ v& v) I# S# I& l2 {. \# S% G  L
void        APU::WriteProcess( WORD addr, BYTE data )  t6 {( m6 C* W1 X) T2 x( {& a) w
{( n; w+ x5 K1 @9 w' m) M
        // $4018偼VirtuaNES屌桳億乕僩
4 q: S3 C0 T/ W, T7 U! P( D        if( addr >= 0x4000 && addr <= 0x401F ) {
8 T8 {6 a+ {  R6 c8 x' j; M                internal.Write( addr, data );4 d9 i: `: X9 s; \) k) X/ y2 p& l/ d& ?
        }9 W5 H8 Z8 k5 G8 b/ M
}
$ ]% E  ?5 T8 @2 R
4 E( L& O- P# E+ Y' k" Fvoid        APU::WriteExProcess( WORD addr, BYTE data )
# B0 v# z. C6 R; `) L0 _5 l{
- C( D. j- E1 @% ^        if( exsound_select & 0x01 ) {& @, w& f1 p, N5 M( h/ G) w
                vrc6.Write( addr, data );4 ]- y6 g4 i) d7 C5 ~
        }) u/ [, v% W  ^" B
        if( exsound_select & 0x02 ) {
. q( X# Q7 o9 F% \. b                vrc7.Write( addr, data );0 l, e( ?  \* z1 t  E2 O; c
        }$ I* j: ?' H" v& `2 n0 p4 W
        if( exsound_select & 0x04 ) {
/ E9 U' ?7 e  g5 J                fds.Write( addr, data );
& I6 h$ {- S; c! E6 `        }
+ A/ ]) J& ]4 B$ S        if( exsound_select & 0x08 ) {
5 V* }8 d3 p  I                mmc5.Write( addr, data );
# A+ u/ N: J/ [. z/ V        }) @0 P# y  u1 F+ p6 W6 z# Q
        if( exsound_select & 0x10 ) {
. F$ O- j% Y3 t' b                if( addr == 0x0000 ) {
# z9 }& `( E. J/ ~                        BYTE        dummy = n106.Read( addr );  s: _4 l, s% b9 Y' J1 t
                } else {4 X+ F/ G, B0 h% n5 G. r
                        n106.Write( addr, data );
- q4 i. t1 f! l                }% B6 Z0 k# p  X* D
        }
# `- e! I7 J$ w: y3 r7 R# w, v        if( exsound_select & 0x20 ) {% z; u9 b4 L8 a8 B1 a" A
                fme7.Write( addr, data );
* o1 r3 r& c' t" G" w$ J5 _$ O, n3 o        }. u. P2 |3 f6 S2 O
}3 s) m& Z  B. b

& S! T8 M2 V+ g% S' C! r/ M3 {void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )3 }" V9 x: v, f2 ?8 T& \+ L8 K
{+ ^; s0 \  C8 ?. m# i  ]
INT        nBits = Config.sound.nBits;
5 r6 B7 m+ Y: L% TDWORD        dwLength = dwSize / (nBits/8);0 }4 @6 S; l" G$ n& r* P# ]
INT        output;
1 W5 K5 c3 N) J- k1 z! ?QUEUEDATA q;
! T7 u6 C4 v/ Q% Y. ?- jDWORD        writetime;3 X9 j  @9 |3 U5 N! h% x' q

/ M# \$ N% j0 H  eLPSHORT        pSoundBuf = m_SoundBuffer;1 W  j. l, U' c# P" \" B
INT        nCcount = 0;, G& z# ~! \: e% g( k
: B8 V, @* D1 v0 u9 d0 h
INT        nFilterType = Config.sound.nFilterType;
9 c- t3 {& {' a# s, H  h* {& w& k2 N) }2 i. Z, _; i& s1 ^
        if( !Config.sound.bEnable ) {
2 g, S5 U5 N0 _- v                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );" _" D0 `1 W( m' F# h4 m
                return;
% i3 `" V: R' @/ X" J) T        }2 B; Q4 X0 X/ d  J( ?) E' O

) r1 j. ^9 D+ N9 i9 S# S+ {# ^        // Volume setup2 w8 C, j6 m. `2 ?
        //  0:Master
/ k' V7 u5 W+ f$ m        //  1:Rectangle 1
+ b. l! e8 q5 |% J, s- V1 H        //  2:Rectangle 2
# U7 e9 v: I' `" W/ ~- C        //  3:Triangle$ F- {1 d5 z- }) u5 B: v$ I7 Q) k: j
        //  4:Noise
! l  s  @! i/ e& h% o& x9 Y. W- z        //  5:DPCM
( ^( w0 `% `) _: p        //  6:VRC6
9 L- F% X2 m% ^9 Y% E6 ?        //  7:VRC7
. t# E; D$ K, c  l/ d5 c        //  8:FDS
; X  Z5 v# v2 N' d        //  9:MMC5- M/ j8 x$ C8 b
        // 10:N1065 b/ d4 k* p" J& L6 L' D
        // 11:FME7
4 m! M2 R/ o; @6 @        INT        vol[24];; e! s( h! Z! C& o5 H
        BOOL*        bMute = m_bMute;; t+ T! v* x) _/ D2 g, g- s
        SHORT*        nVolume = Config.sound.nVolume;6 [( Y0 k# [2 R: ?
2 l% W5 G3 U( I0 d; B: t' H6 l
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;2 I& ]5 Y! ?, v" x: \. ?- p
4 L) Y" e- {2 M  e' Z: q
        // Internal# L3 |$ {- B: H; \5 P# p1 ]
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
: n  O, I9 S: I; i" t, f$ f        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;) I+ Z. }+ Y/ S5 X5 X
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
' B; u- J* c  V# b4 {! c9 a        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;5 d' Q: D2 F+ i% ]' y( a
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;4 ]6 d" r: E; b9 y. N9 {
$ K7 G. D& b4 ^- X: Y
        // VRC6
8 ]5 W0 U+ o+ L5 r! W        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;) X% g1 S; Y; X' C# e4 R" r2 a
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
7 P, `* A, r0 F, o& S7 F        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
( e9 D' ?6 U6 G0 J1 a8 i' @, D" D7 H/ ~! y' T; u. K) p8 _0 [  {% h
        // VRC7
5 W* g# v9 e# c' i        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;! N% H& e0 I& D& R
" O8 \  @+ c; l. @3 H% V8 Q2 F. h
        // FDS
" F5 I/ X3 ?5 h! P/ C        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
" a  [9 C6 `: U
, v9 Z& t, K0 {9 e1 k        // MMC5
2 O" N8 W7 L' ?2 `        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;( t( J5 F: c0 D$ G% H6 O( I
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;4 W  v$ T& |2 F0 J" Z2 K
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
  l2 _. Z% _* r+ a& I# q6 X
# {" h7 @1 z* S, h+ O9 V% K        // N106
5 p3 K0 `4 b8 L4 a. c9 p2 |; g5 `        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;3 J' y6 M4 D2 S) ?7 q
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
# i. q& ]6 V7 O/ N$ w7 x+ m        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
! A! t9 r. m8 H, t9 Q; E        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ }7 t: N: V' j: t
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
; m( Z  k8 m$ }6 T8 {        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;6 _7 E" o1 }% [( e0 T% V# d2 l2 Y
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& v; F( T; u; g' ~# |; Q        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 h4 Q3 Y+ N# b8 X$ J. p, T% U
/ c  B5 H# m6 H1 @
        // FME79 L+ f6 N: ]+ S
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;' t7 R8 ^: G1 n; |2 ?% V0 m
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
4 b4 u3 \/ ~8 a- u: r        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;4 g% B6 f" t( Y) A1 Z6 F+ S+ b# T. ?

) p; l, [; M+ |& K, J//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;$ d# u. l2 |- K+ R' N; n
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;) g8 ~' o/ I* Q( t! _1 }: Z/ h7 Q

  z/ q' T* g: n4 j; P/ ^8 _        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟  U& N5 f0 u; i, J% I& a7 D" O
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {( g& b# y3 H% S) {( H1 s' [( i
                QueueFlush();
. ~* ^3 w2 K; }+ v* W        }
6 a  w  j4 D% P4 f3 R# J  x) F2 K+ a; h/ b
        while( dwLength-- ) {9 ^/ r- x5 }& S9 m5 ^+ Z
                writetime = (DWORD)elapsed_time;
& p; C1 D" O: i0 f+ D7 ^& b# K( x' N, h3 Z  g4 l! y6 _4 r! L0 T- U/ W
                while( GetQueue( writetime, q ) ) {# m" e9 Z' m- w7 c
                        WriteProcess( q.addr, q.data );
9 U' J" H, |) y6 @$ `                }0 C7 L) F# F1 d  ^. V' Q2 e

* f, b  y) |3 w$ Z                while( GetExQueue( writetime, q ) ) {
: Q3 D5 p7 [" q' Q                        WriteExProcess( q.addr, q.data );
: g! g" l- F2 j* A7 F                }
, ^/ w( X( |/ j" [) ~+ U9 t( Q& L% d( ?- Q4 E- F7 J' l. t9 H
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7& h) y9 L: r$ T# I) I6 @+ z: v
                output = 0;( `: h% P" }8 ]" y& [  f
                output += internal.Process( 0 )*vol[0];
2 m3 Q) [$ p+ C# a$ X+ s. M                output += internal.Process( 1 )*vol[1];
; e3 s  T' n0 W- V; V  _4 N# v                output += internal.Process( 2 )*vol[2];
# Y/ n! {' Q" U& e* m                output += internal.Process( 3 )*vol[3];
, r6 h& [. `9 U                output += internal.Process( 4 )*vol[4];
, d" @3 S' N, l4 m7 T0 j* p, G' |  T# Y& \7 M
                if( exsound_select & 0x01 ) {4 i% }1 p% R0 Z( U( Y
                        output += vrc6.Process( 0 )*vol[5];
  n( C0 _1 a( F  ^% D                        output += vrc6.Process( 1 )*vol[6];
0 ]( y: ~4 C# A: h9 r7 ?9 c                        output += vrc6.Process( 2 )*vol[7];$ m2 y, H/ M7 h  W; b- s9 }
                }1 D# U& f9 u& H9 b
                if( exsound_select & 0x02 ) {6 H' X5 x# y2 |% x+ f
                        output += vrc7.Process( 0 )*vol[8];
' B1 \) a8 c5 S3 p* M& u2 ?                }0 l. E+ Z5 h, O; }( S1 w+ w
                if( exsound_select & 0x04 ) {; X1 V& L: U3 ]
                        output += fds.Process( 0 )*vol[9];, v1 ^9 f% g! U+ ]: c5 n3 _
                }& s& [6 C% x; C6 j. j: I& f, \
                if( exsound_select & 0x08 ) {& Y1 `- X% g# `2 B. R& B
                        output += mmc5.Process( 0 )*vol[10];9 @9 `' Z- `" N9 x& H) W* n  f
                        output += mmc5.Process( 1 )*vol[11];1 ?5 ~4 ?" t& e& U# X* e
                        output += mmc5.Process( 2 )*vol[12];
: l3 w6 H6 a3 Z) |) J8 _                }* Q% p. s; O+ D6 W
                if( exsound_select & 0x10 ) {
7 ]! n% V2 R6 @* H                        output += n106.Process( 0 )*vol[13];
8 Y! f0 s* K- b+ b& g& Z                        output += n106.Process( 1 )*vol[14];& [/ B; t4 ^1 R9 T. u
                        output += n106.Process( 2 )*vol[15];
( O3 X7 e% G- m: C0 P  Z3 Q4 R3 s- d                        output += n106.Process( 3 )*vol[16];
9 p, Z, x/ \) _- V& L                        output += n106.Process( 4 )*vol[17];
! Y5 z1 O" ?/ F/ b                        output += n106.Process( 5 )*vol[18];% d1 A5 R" _& W# z
                        output += n106.Process( 6 )*vol[19];1 a! ?" t' |! P
                        output += n106.Process( 7 )*vol[20];" f9 U% f' y. i% l9 F' Y5 t) F, G
                }, q) C8 K2 |5 e( T$ A( I2 l
                if( exsound_select & 0x20 ) {) k( P$ o( W' l, @
                        fme7.Process( 3 );        // Envelope & Noise) i: d. B3 [0 [& Z3 i
                        output += fme7.Process( 0 )*vol[21];
$ I: y3 }2 @( A6 e, S: O) X                        output += fme7.Process( 1 )*vol[22];
, h( [1 a2 I; A9 a  \                        output += fme7.Process( 2 )*vol[23];
+ f* {' C2 \# i9 I! y                }
7 d8 u9 }: w# o) P  p) n! O3 Q9 g; S! I4 M
                output >>= 8;
( O/ n+ M4 E9 {# ]7 h- ^6 w& Y2 U. Q4 N# @" ^
                if( nFilterType == 1 ) {6 Z! R8 t- u( Q9 H
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
/ `" Z" H9 D% u' V* F6 N                        output = (lowpass_filter[0]+output)/2;
. r' {6 _6 d% E1 O' S  w                        lowpass_filter[0] = output;5 d# w8 f+ j. C# K% W
                } else if( nFilterType == 2 ) {6 y2 ?- W  K# ?8 ?+ Y0 g+ c$ j0 c
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
. e, d; e( |/ u' @: Q                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
$ N! O; }+ `! @3 P" l# Q                        lowpass_filter[1] = lowpass_filter[0];7 u1 I  s$ X9 A  b0 B& F
                        lowpass_filter[0] = output;
7 E; h, c1 y  i" Q  o  v                } else if( nFilterType == 3 ) {8 L* [" {8 u  L
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)/ h0 g" z2 w4 Q8 x3 A7 p+ }
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;2 ]! k* n) T4 Z: S( h
                        lowpass_filter[2] = lowpass_filter[1];+ Y7 [  f: h1 W5 Q! y
                        lowpass_filter[1] = lowpass_filter[0];
+ b& ?" ~9 M+ V4 j$ C; b                        lowpass_filter[0] = output;
  ^6 S, C' i: n& A                } else if( nFilterType == 4 ) {# C8 I+ S4 M8 \& g1 m
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
9 t2 Y, v# U; b- G7 c                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;. e3 i5 r# l- E" V; W, ?) @) }
                        lowpass_filter[1] = lowpass_filter[0];
. n3 c2 G5 z5 N, B9 T! Y                        lowpass_filter[0] = output;
9 R2 P8 z' x. Z                }
9 z0 U% S3 o" \3 C/ k0 O* e& o; o5 Z2 B* T. J
#if        0
$ A4 d# y2 e& b7 K* |7 M8 m* p                // DC惉暘偺僇僢僩
. ^0 D0 |. Q: D: G9 `2 b! ^                {, C% s/ a1 A9 b
                static double ave = 0.0, max=0.0, min=0.0;
3 M6 d5 m+ J% E" h  B, I2 R                double delta;3 V8 ~- l0 I# t& G4 E+ o
                delta = (max-min)/32768.0;
) o& U* b3 [" f4 v7 k3 G5 z                max -= delta;
. z! j: r1 ~/ V. \0 S: n' v                min += delta;/ s, @8 I, z- G" I9 W9 g; o4 G1 _
                if( output > max ) max = output;: Y2 Y/ P8 i5 b+ z  f6 n0 f: s
                if( output < min ) min = output;
- k4 f: o3 T: U6 |, o                ave -= ave/1024.0;+ k' k1 r+ \7 k. ^8 W. N9 e# z
                ave += (max+min)/2048.0;5 T5 L$ v5 V" X6 N9 q
                output -= (INT)ave;
8 P/ \- n$ O5 @: k                }; z! k  E8 `) Y/ H  w2 q+ H
#endif
& T9 Z8 V  A9 |, U#if        1. U0 C9 ?* Z6 ^- I7 g
                // DC惉暘偺僇僢僩(HPF TEST)
3 Z3 \' S2 g9 a# G, E                {8 t( j; _. C+ |. L' \
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);5 U1 d/ W$ }, e7 V6 {
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
0 E  @1 V' W# }+ r                double        cutoff = cutofftemp/(double)Config.sound.nRate;8 w. y' K6 D/ l# R
                static        double        tmp = 0.0;% R1 V1 R3 }( h) U& Y" f
                double        in, out;: m) |( u6 d4 z  O/ l1 K% D$ n/ O7 [
( v! {9 g1 p% \% W
                in = (double)output;6 C+ x9 m3 G% N2 R
                out = (in - tmp);
: Q* n+ i# x- e) q                tmp = tmp + cutoff * out;" B- w$ z0 `- m: x9 M
4 z" u; G% ~" h7 ]( _7 c1 N# D
                output = (INT)out;
- f! n1 {- K% ~                }+ _, m0 `. Z6 h: b+ r  y$ p1 }
#endif
" F( h  y2 {+ q7 ]+ g0 a  z#if        07 p) ~. v8 i" ]% S% [, ?
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)/ Q* x* g3 y& d. j; J4 L' Z6 Q
                {) }; V* @" t# p4 t
                INT        diff = abs(output-last_data);5 s, d+ W# U. M- o# ?( @" Q
                if( diff > 0x4000 ) {
7 f3 Q3 K: W1 c6 R# j, V) D/ s: R                        output /= 4;# A/ X3 W- w7 r5 g! ]# O
                } else , @0 b, V4 N7 C/ X9 F& O
                if( diff > 0x3000 ) {
1 P: A% L  L8 R2 d                        output /= 3;5 O% V" I+ g# ^6 _. h. W: e
                } else' r4 `4 H& W* o9 u- X7 A) M; r, W
                if( diff > 0x2000 ) {
+ S$ ^3 d) W# r* i0 X& W                        output /= 2;" ^8 w  [* r; i6 w
                }
; ?3 P3 t4 r% _' A                last_data = output;0 X/ q9 S; |0 r$ H; K
                }
5 {) u0 o5 b5 k( r#endif
- C1 e1 i) n  v1 O- {                // Limit
0 L) h7 B/ P* o& ?                if( output > 0x7FFF ) {
/ d; s, u4 A$ Y- W( y                        output = 0x7FFF;
2 r! b& k3 d0 C# r' I5 s                } else if( output < -0x8000 ) {# H& s: a% H' o: d( l
                        output = -0x8000;/ u1 D" R: i' f2 Y
                }
/ ~' T7 \" i+ j: l- Z+ w* T' K  W
                if( nBits != 8 ) {- l0 q- a. a2 b" ^
                        *(SHORT*)lpBuffer = (SHORT)output;  J; a& p, D  Y! G1 @
                        lpBuffer += sizeof(SHORT);
( ^6 l- I$ `9 J* q6 C                } else {
6 t5 e1 C* B$ M5 E- F6 y                        *lpBuffer++ = (output>>8)^0x80;5 K/ ]% l) \: [7 q& n
                }* E2 t1 O& u. L! ~

0 I) `: k) r) C# `& k8 r5 H7 a# H                if( nCcount < 0x0100 )! q+ a6 ]4 [2 P4 s, \0 s+ i
                        pSoundBuf[nCcount++] = (SHORT)output;! D* [7 A  X3 j8 M9 J( U
( _! ]# C6 J. ]& U
//                elapsedtime += cycle_rate;- @* B: x% N  X; b7 F: F/ b
                elapsed_time += cycle_rate;# S9 Q2 r% y' g5 K4 L/ q
        }
7 h" b$ {9 I/ {+ L5 M
- Q2 Q6 e  W0 n2 E#if        1
/ j- W3 @( r* c: I2 Y& m. A        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {" G: `- y4 q0 d5 z, t
                elapsed_time = nes->cpu->GetTotalCycles();2 {6 {7 R) X& U. x/ }
        }
* b; g) ]' t  H3 W) P        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
; p8 T# T  l% R$ Z' M+ K6 q* a                elapsed_time = nes->cpu->GetTotalCycles();. i" ?5 D+ ^( b1 k4 ?: O1 N% P
        }
& R9 H+ X  D4 U#else9 B4 D) Y6 L2 y- x# e% g: l4 |
        elapsed_time = nes->cpu->GetTotalCycles();
* U1 |3 g0 [; {, {' V2 ?. O2 h#endif
8 @9 M9 E$ \' L' s5 p. Q}
6 G# ]2 p3 o+ T& n
9 r  m, C7 q' [: o8 C// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
, l" E# W4 w* PINT        APU::GetChannelFrequency( INT no )
+ _2 A7 ^, d% G' I% V: p, _+ t, t{! |0 v3 }0 w% b& V
        if( !m_bMute[0] )
8 Q+ j2 M' P9 H) [8 L' t( a& m                return        0;4 Q8 n) F$ ~' k0 `4 z' T/ l

) ^% R' [6 y, @2 P/ `1 i        // Internal
; }6 I4 Y4 g: _1 X% H        if( no < 5 ) {  o0 R3 ]& _0 ^
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
- ?( |$ g+ s2 ~, s1 S        }1 `4 h0 _$ Z9 |3 c* }% e6 G
        // VRC6, f. C/ }+ ~5 I
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
5 Y. t2 r, `3 ~" _7 {                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
( `0 I& c3 F% a& Z8 Q; p6 d: h        }
6 Q2 |2 F! ]- {        // FDS
2 D6 C/ T* [: |$ Y3 W/ F' x; V: \3 h        if( (exsound_select & 0x04) && no == 0x300 ) {
6 e) Y7 `$ R" k* s; y; c8 w- a                return        m_bMute[6]?fds.GetFreq( 0 ):0;
" ]% C& Q& I2 `" F, E# U! _        }
& b( J6 D' d6 Q  ~6 P' A- S. |        // MMC5# P1 j4 W' r9 D% Q, |- K; L& x
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {' c3 }$ ^: P! y
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
5 \0 }, s; g9 U2 n. |5 ^% |' ~0 b        }# _+ x6 d$ p) U8 `* a* I( q" f
        // N106) o& ~  C$ \1 Z! {6 A& z
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {4 t: {) s% }/ a( ?2 @/ k2 v1 M) a
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
, d( U, ], C- }) n7 Y        }
1 f; Q4 @8 d$ I- i        // FME7
. T0 z. \8 @! `) B8 |% h        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {3 e( X7 ?5 Z# S+ z/ A- t* ~9 E
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
2 l* j2 x7 {5 G. j' D9 n7 a7 d        }
! ^8 P2 Z  x/ p; Y: a        // VRC7. r: H7 x. h! Z4 Z7 i) Z. f
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
( h2 S+ t# d# w1 k% j; n. n& [' T                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
6 Y, u- k/ s7 A$ t! L" Z        }
+ N& G5 c* s1 s        return        0;3 b: s) p2 d3 c
}
; K2 F: p7 M0 h8 q  K: _# q0 W, h! {" j) t/ a3 m
// State Save/Load3 Y8 b  B) K# C6 z# q
void        APU::SaveState( LPBYTE p )* @% R  d& V* Q+ D4 J/ `
{! q2 v% ~& C6 [# q$ g: i4 Y
#ifdef        _DEBUG  `9 e# c: ^- @( F6 T, C. C
LPBYTE        pold = p;
4 G$ j+ p6 Q5 \) x" P3 h, a#endif1 l* F8 Y4 ?) e$ ^* p) f5 k
2 T$ n' q& i. \# V/ I* c. u
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞# |7 g+ K! u7 E- j0 \- ?
        QueueFlush();: e, O* n) r/ |6 p. ?
6 A+ W) N2 S8 S
        internal.SaveState( p );0 N9 J0 x# E7 ^) _) d
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding. P7 u6 z+ H& s8 K- h0 E

9 v9 J. B" g+ G        // VRC63 Y, C/ l5 d: F: h. l0 j
        if( exsound_select & 0x01 ) {
: f0 Q$ L; p1 F2 y" \                vrc6.SaveState( p );( X6 V) C) r. E' u& [- V' S
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
( t. y4 L, z0 W4 i        }
9 d/ S' S7 o+ g! p        // VRC7 (not support)0 }  ?! g0 M" |& {
        if( exsound_select & 0x02 ) {
* Q0 R. w2 p9 e9 J4 ]                vrc7.SaveState( p );0 F% Q% S6 ]: n% l( }
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
7 U2 h) e* R4 S" d' g        }
- h/ ~1 l+ {) O9 R+ p+ E) V6 X        // FDS
, O/ U5 g' W. j. @8 M4 h        if( exsound_select & 0x04 ) {
( A$ ?& X1 P1 E: `- u( k                fds.SaveState( p );: W: I& ?9 V3 c& @( x
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
; e7 t% M4 K0 a- N. a( P1 I        }: v6 c* A3 F7 {) d0 Z  A& ]9 X1 C
        // MMC53 ]; w( S, d, y3 o7 A( K* q( D* \+ {
        if( exsound_select & 0x08 ) {- ]9 A. e( v& h+ Y4 c, W( k" |
                mmc5.SaveState( p );# A9 C2 W1 B/ E* l+ ^
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding/ I0 M# N0 t1 a) G0 o
        }
- c, Y: H9 ^, D! f" X        // N106! X, K! R; D% B8 ^3 _0 O+ F
        if( exsound_select & 0x10 ) {
. E6 _" C+ Q8 c7 s' o/ \- a* P                n106.SaveState( p );/ H: j6 I8 S- P9 e
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding" m# t0 J0 |- X; j4 ~. d
        }
  k8 a/ E: F& t1 P; Y, B. N" e        // FME70 L/ a2 N7 H' i8 x$ |# ^
        if( exsound_select & 0x20 ) {. t1 |( k3 s/ ~
                fme7.SaveState( p );
: E0 Q- T& X% {3 |                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding; y* J- |3 K# p4 w, m) s
        }6 ]0 @0 @8 `1 ?" ~

9 z7 r: k  U$ B$ N& a#ifdef        _DEBUG- Q- e1 G) b- M9 u- E
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );. C' \, g8 I: e: b! a5 L+ N) E
#endif
( @# D/ A) H( ^( _  E1 L8 v1 e}- S4 t; M  J  |6 ]0 |

- k/ Q+ r5 o  }+ tvoid        APU::LoadState( LPBYTE p )
0 \; D4 K3 {3 b5 f& A{
$ D# Z3 j! B- o* W; L        // 帪娫幉傪摨婜偝偣傞堊偵徚偡% y$ z! u: Z) a8 J
        QueueClear();
* w0 m2 {$ R/ T/ g  ^5 ^+ R- Y2 h0 C5 L2 S9 }6 k2 q
        internal.LoadState( p );) e9 P& l: @! [: a, b, c3 L
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding8 d' `8 E  b& D4 f, o
" _; n, o$ t/ F, Y
        // VRC6
) T! T) z. b. s8 x6 D2 L% y        if( exsound_select & 0x01 ) {
/ J  W. Q$ Q: P' x* Z8 z7 }                vrc6.LoadState( p );
2 {0 k: n$ R! x9 m: x+ n' U3 R1 O                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding% B7 e  \( M- ^, l7 W; G
        }' b* Z4 x' |7 L5 R
        // VRC7 (not support)# i) |% {1 @! F6 y3 |
        if( exsound_select & 0x02 ) {
3 E" t, k7 c  ^                vrc7.LoadState( p );* q, |" z/ z2 P) u5 w
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
: ?/ Z" s; S1 S* E        }3 M, \' {8 Q" _3 P9 n# y
        // FDS
, N; ?5 F7 n; b- B        if( exsound_select & 0x04 ) {
5 Q  f; k- B1 Y, H1 p                fds.LoadState( p );
- \3 B, a, u, ]) J                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
4 \% u, {# x$ J: t+ C. W        }
- f* i' |) J3 Q9 i        // MMC5! y7 _' `; x+ y; S
        if( exsound_select & 0x08 ) {
& M. E$ i, x( [; K                mmc5.LoadState( p );- D3 A( `9 g: ^. H! l. Y: c
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
) S1 S9 o2 k1 n( t        }
: [& B+ X; e" W  X, X# n0 h' p* @4 U' A        // N1063 ]: q' U9 v7 [! h7 P1 I
        if( exsound_select & 0x10 ) {& |4 L0 r4 G( ?9 I6 W0 ]* f& E
                n106.LoadState( p );
3 h$ W3 e. l  |/ ?; a+ {                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding4 d, R- O. [1 I; J& s
        }
2 U+ a( Z/ x: t' O; X! ]        // FME7  H& u6 ~; S9 N. B: v
        if( exsound_select & 0x20 ) {" \* S* n0 i# \& m4 z5 P% F. L
                fme7.LoadState( p );0 `6 q# l& I+ h  K
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
  W( z) ^7 v$ P- J( }; ]        }
8 f& u$ D, @0 _/ l6 M+ ?}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
) H; K1 j* T/ _0 B' }0 T, v可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
8 h% @! n# n" _; b: J) Q7 A' e感激不尽~~

% B6 M, o9 ~5 e恩 我對模擬器不是很有研究,
" j4 U" G7 i) }9 [! I& l雖然要了解源碼內容,可能不是很困難,- ~6 q, A" G6 z* v
不過還是要花時間,個人目前蠻忙碌的。
9 z# X( E4 S# E; V% r& c
6 ?( B8 |  c0 p( E2 X% O給你一個朋友的MSN,你可以跟他討論看看,
; O6 U2 K$ ?! [1 X  W# C% c他本身是程式設計師,也對FC模擬器很有興趣。
+ x& e* k, {# _; z# ~( G- `5 k0 k3 }' C& m/ B/ {
MSN我就PM到你的信箱了。
; w# T2 _8 B9 g6 R* f2 O9 }* d- O% b( ?4 t+ ?
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 7 W" T4 M9 h% v) O( m: A
呵…… 谢过团长大人~~

# R0 @# e/ r% R2 b' w2 a7 g; j& o
  ~3 b6 F: m& M哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
+ o9 D: [* ?8 t+ [+ N  e. T团长的朋友都是神,那团长就是神的boss。

# g+ x9 X9 p3 f, A哈 不敢當,我只是個平凡人,; S, T; W1 x, |% N. l$ \8 k4 A5 h1 {
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙& _: B5 V! B3 P% w; u+ L
ZYH
! Q' c0 [& \# C/ s5 sQQ:414734306
3 t! E8 ]2 V) e+ ^& Y8 xMail:zyh-01@126.com* F9 e: L4 N1 j& g

1 t; h$ ^( E# o% `9 E他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
8 {3 o9 T! M. K再次对团长大人和悠悠哥的无私帮助表示感谢~~

3 v" J; C/ c* T7 p  `不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-11 08:12 , Processed in 1.100586 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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