EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。/ k( Z8 z4 `% F$ H
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
, o# Q( \3 ^# \; u- N6 U这里有相应的模拟器源码,就当送给大侠了~~' N% ?8 l5 n2 U! Y4 N3 Z  Z
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 ) A1 J: w1 Z8 ]! U
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
0 j! @( ?: U6 }3 X" I( A! y6 N8 r楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
# d7 Z/ Q  F& W* X8 N9 F这里有相应的模拟器源码,就当送给大侠 ...
- b' w9 I' D9 j+ K2 [
聲音部分(Audoi Process Unit = APU):  c# w: T) s; ]
.\NES\APU.cpp
; ^2 f1 T+ v: [.\NES\APU.h9 h2 }. q  e/ Y, W7 w

1 T" G/ W! L& ]0 _
& d% Z. j* b9 G  a3 R2 G影像處理部份(Picture Processing Unit = PPU):9 n. p" T( J, x' c
.\NES\PPU.cpp
# ], ]- B( h4 A! M5 g.\NES\PPU.h9 h- a4 k. N4 @$ y

# \+ f) Y6 [% J: b3 j如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:4 o) @! a7 X- Z$ N; |: f& r. j% T
(由于很多专用术语和算法机理都不明白,所以看不大懂……)$ ?; b. c- z) R/ W& T- y
//////////////////////////////////////////////////////////////////////////& W( |5 J/ R6 j2 }
//                                                                      //
  h8 a0 a7 v. d1 r6 o: X, `//      NES APU core                                                    //8 ~4 B( T% A  `3 v) t9 l  J
//                                                           Norix      //
; w/ R, j# Y: [) \+ l4 R7 a//                                               written     2002/06/27 //# H" \# g: X# b2 ]! D6 [1 W
//                                               last modify ----/--/-- //
& Y, W8 X* W6 h, p//////////////////////////////////////////////////////////////////////////
  m* n. `% S& \- t6 j8 g0 u#include "DebugOut.h"
- i- w- C- {; b' K1 c#include "App.h"$ ?5 f! O) T! J) t
#include "Config.h"1 Q3 N$ I2 x/ R1 T

+ t# b3 x$ {: ^$ d: m& |5 C* i#include "nes.h"
# w+ y3 f( {/ [0 p#include "mmu.h"
6 [4 v# J! Z5 o- B7 K#include "cpu.h"3 _6 K0 a" ~* D7 a" c9 D
#include "ppu.h"
7 Z2 K) F! t: l* h! `#include "rom.h"
6 \1 F( d5 [$ m7 y; M4 b  L#include "apu.h"- \1 t7 F1 l4 j! n

7 c2 [0 r. f/ q$ [/ \4 _1 I// Volume adjust* }$ S0 f' p$ K; H% x3 y$ P8 d
// Internal sounds
, o  m) J7 O; I2 b+ k#define        RECTANGLE_VOL        (0x0F0)
' Q5 |  a$ _. E. g$ |#define        TRIANGLE_VOL        (0x130), ^+ u0 P$ h& q
#define        NOISE_VOL        (0x0C0)
; v3 M7 O  ~2 u. G8 K  K0 H, W#define        DPCM_VOL        (0x0F0)! H9 Q: }/ _! ^+ I! V0 K4 ^. a
// Extra sounds5 U% q2 {( H/ q( `
#define        VRC6_VOL        (0x0F0)3 p, ~' a& X- h
#define        VRC7_VOL        (0x130)
( c' H) |) m9 g. M# m5 O& ?#define        FDS_VOL                (0x0F0)
+ h; _, ]3 Z% Z7 F$ H' X#define        MMC5_VOL        (0x0F0)
- t% i& h, h) K  X6 A; E; _#define        N106_VOL        (0x088)
6 {, s2 x8 d9 l( ^4 {+ E/ E#define        FME7_VOL        (0x130)
* C8 B. U. y0 w  R) B: b( K
& }3 U9 [; X- i2 E% D2 f7 \APU::APU( NES* parent ); q3 T6 _0 S" r" a6 M$ E% V
{; F' [9 M' T! K% H6 `) G
        exsound_select = 0;" Y4 R/ j8 h" f" T

8 ?* e) u1 @- n$ I4 v        nes = parent;- s' q$ F7 V% X8 v
        internal.SetParent( parent );
/ A& d; Q+ I9 P. S  r$ s: ?9 A4 T# r; }. V$ c7 N
        last_data = last_diff = 0;( A% k5 x! B$ g. H0 U) N6 d, o

: U) x: A' D  B: S6 O& ?* L        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );& P4 f+ k1 }. D- R6 M# m7 K

  r- k* ]& E+ Q. O' p        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );) [/ C1 Z. ^; y- T' E
        ZEROMEMORY( &queue, sizeof(queue) );
  t8 j# W; t8 U9 b; b        ZEROMEMORY( &exqueue, sizeof(exqueue) );
2 b4 V* L. s# Y  O
1 W8 Q# H8 d$ k! C& D        for( INT i = 0; i < 16; i++ ) {) h& V1 s% h6 K1 h5 f. V
                m_bMute = TRUE;4 u  u  _; ]. z! n
        }
* w/ L2 r) I. V1 F" o}" w+ {4 d+ m; M

3 Q- E+ N2 U7 D! J; uAPU::~APU(): B" ?! f! h1 B
{
: W8 g) [) ~7 d/ y}1 |: @: Y& g7 [% y, s3 {
0 c6 I1 `. S6 R0 a4 V
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
7 [9 s* f8 {" A% k" q{: W+ \" R" c) @; W6 j  q0 d
        queue.data[queue.wrptr].time = writetime;
5 Y! L, x0 ]2 f' c        queue.data[queue.wrptr].addr = addr;
$ E* j; _6 D( s1 V; y. V6 `        queue.data[queue.wrptr].data = data;5 ~5 u$ B# b0 [. g7 a9 B4 o! ]* L
        queue.wrptr++;# s" R$ X" I9 {9 X* j
        queue.wrptr&=QUEUE_LENGTH-1;
7 K7 F2 {, [, i# T. r" l        if( queue.wrptr == queue.rdptr ) {
! ^7 B( e4 u* Q( e1 b5 B: h1 N. K2 K                DEBUGOUT( "queue overflow.\n" );
6 z- O- h' I* q        }
% x) T8 m) g5 D$ [$ Z}  k' l( i$ o4 M) |! a  x

! {/ t# a/ M  q0 I: }( tBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
' Q: X$ H* W+ I{$ T, ~/ y  x1 F" l7 _; e- W
        if( queue.wrptr == queue.rdptr ) {
6 S1 J' M# `  m% m                return        FALSE;- u5 _3 ]6 N* J5 A" d$ N( r& W
        }# y% A! v0 {  O/ D
        if( queue.data[queue.rdptr].time <= writetime ) {1 w0 j, G4 b  C% [
                ret = queue.data[queue.rdptr];
9 L3 Z% p# U( F' ?4 ]. q                queue.rdptr++;
: W& e7 d- b; s9 _& c                queue.rdptr&=QUEUE_LENGTH-1;
' {' S" x" c5 `" S5 S* ]8 G; [* d) C                return        TRUE;: }$ x  h& \9 `0 M4 _
        }( i% j+ v- R! k$ o5 F/ F. u
        return        FALSE;6 F2 ]  P# X! @6 ]7 C) e
}% F. v  H/ }( o: @
/ }7 a3 s% Z* k4 V9 |' K
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )0 C" ?$ M% L* Y' o) ^& d& e
{6 d* r+ _9 X7 Q1 r9 @
        exqueue.data[exqueue.wrptr].time = writetime;
7 K, h/ [1 o+ E2 _' r& Z        exqueue.data[exqueue.wrptr].addr = addr;
7 b0 T0 L9 y, X% h9 H' x        exqueue.data[exqueue.wrptr].data = data;
1 _# I- N+ a  [3 [: ^        exqueue.wrptr++;4 w; W: ?& l- D- v# J9 T& _+ T
        exqueue.wrptr&=QUEUE_LENGTH-1;
- K# i8 i# T5 d- @1 q$ P1 T' `        if( exqueue.wrptr == exqueue.rdptr ) {, m: U1 l) z6 Q! ]9 I. h- s5 `
                DEBUGOUT( "exqueue overflow.\n" );
7 M! n& L9 X2 g8 N        }# \! P# n! m8 J$ ?7 `% Y  }
}) i7 Y$ P- J9 S% S& ?" `; I, U, T" l
- v3 i1 r% p% J7 I& r( ~& w
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
, _# \; ^7 J; Q{
  a# k2 i, L7 V1 Z1 [1 E        if( exqueue.wrptr == exqueue.rdptr ) {. J5 O9 d3 F# M, T3 d, J
                return        FALSE;
( Q! m! ~7 m3 Y. B% `1 g        }8 G1 _! t# ~1 o+ r2 G
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {. n8 W5 u) i+ B6 Q' y* U  ~1 U
                ret = exqueue.data[exqueue.rdptr];
8 D) ~4 ~' `$ E$ L                exqueue.rdptr++;9 d' `: Y8 R; t* o
                exqueue.rdptr&=QUEUE_LENGTH-1;
9 ]) N$ S) l. e) P/ h7 t# u                return        TRUE;
6 _+ `; X$ ], {        }2 k7 d8 T5 i" o. S
        return        FALSE;9 J$ l8 K. H% M
}: c+ E: L+ ]% M1 r: W5 S! s
5 Q( N% E  _+ p. l
void        APU::QueueClear()
! u* n! {  g  r9 i% v( U{( B4 o9 |+ ~3 T  b8 W
        ZEROMEMORY( &queue, sizeof(queue) );
2 g3 c7 _* z0 t% t5 W" h8 z8 ~        ZEROMEMORY( &exqueue, sizeof(exqueue) );
3 |8 n. l' c0 C1 E/ L}
, b0 r. n: ~9 i% ~, e* K
* y. K2 e8 ?$ k" k8 y: K! Dvoid        APU::QueueFlush()
! r3 g2 S% j& n. e{& k5 C/ d2 f; U+ n7 y
        while( queue.wrptr != queue.rdptr ) {
) `) G4 L$ B0 {' S: I                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
( Y4 [/ L! R3 t! Y2 ~# P- b                queue.rdptr++;6 ~7 i. [( O, k# I1 s
                queue.rdptr&=QUEUE_LENGTH-1;
$ S9 {9 g) h( _0 x0 U        }
( ~3 _' W8 {; }* w  r
1 t8 g7 Z: k; q1 K) U        while( exqueue.wrptr != exqueue.rdptr ) {+ x3 Z$ f, Y# c3 ^  k% K) H
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
# w; e* z# G  `, m+ L( y& g                exqueue.rdptr++;
1 ^5 r: [+ E9 i9 |                exqueue.rdptr&=QUEUE_LENGTH-1;
/ ~$ {% o& ~4 E5 y) E) z$ D        }
, V/ m1 X4 p" q7 e, U4 L" c% k}
7 l- U; w/ Z4 J- f, {* N: A, O- j0 w% t
void        APU::SoundSetup()( G' ?& n$ s4 g2 T) ?9 N5 n
{' l. x( O& X9 O, t+ f
        FLOAT        fClock = nes->nescfg->CpuClock;& @3 [9 ?0 o1 ]0 f2 P5 Z3 ~& M
        INT        nRate = (INT)Config.sound.nRate;
1 |' J; {/ b1 o, D        internal.Setup( fClock, nRate );& G" r. m4 C3 f( b/ ~
        vrc6.Setup( fClock, nRate );
' ^3 d1 o  a- a4 A, e2 L2 J        vrc7.Setup( fClock, nRate );
; o& `( K! n% ~! V1 [        mmc5.Setup( fClock, nRate );
) t# B( D/ j7 u5 s9 B/ `2 C* N! J) F        fds.Setup ( fClock, nRate );
1 a+ H$ D8 n' l        n106.Setup( fClock, nRate );
) E: q2 z3 e6 z. x, G; Q        fme7.Setup( fClock, nRate );, V" X0 W+ C' h- P% s) z
}. C5 G- t4 K* j  z3 j8 o5 u+ G
1 H% j/ B9 O1 r2 n0 \, G) \" Q
void        APU::Reset()$ t$ ]( g$ L* o- l
{
) h- g. i( L8 d: I$ B        ZEROMEMORY( &queue, sizeof(queue) );5 [6 P+ d# a% q! I  Q
        ZEROMEMORY( &exqueue, sizeof(exqueue) );5 x, H8 I) R, O$ I

6 v5 |- V* Y8 b# h        elapsed_time = 0;
  t5 F; [: v, {2 l% s
- i8 s3 F3 b* i$ t! G! N4 G" L, ^$ L) S3 K        FLOAT        fClock = nes->nescfg->CpuClock;
; T% {, f7 H; @7 _        INT        nRate = (INT)Config.sound.nRate;9 e! T: k3 g/ o) E. O( U
        internal.Reset( fClock, nRate );7 I/ L0 j& \# V  Q
        vrc6.Reset( fClock, nRate );3 z+ D7 K& r1 u9 z, N1 n/ `
        vrc7.Reset( fClock, nRate );
" `# c$ ^/ ?0 I7 L, P2 W# c        mmc5.Reset( fClock, nRate );& y7 f8 x) L. [9 p+ E& v! R
        fds.Reset ( fClock, nRate );
. X5 s# n8 b0 y7 J- S1 @3 D. T        n106.Reset( fClock, nRate );
, V  o* X3 x$ M/ X- m- G5 w# F5 }* R        fme7.Reset( fClock, nRate );
5 J& S6 y. g* P# m. u4 V+ b! `; {' J& \( c! L4 `  b' d
        SoundSetup();
1 E& U: Q) g! E}
7 L( s  i- I' ^5 ~9 P0 p- H; p
; P. @. W9 k4 G6 J: @! z- M+ D, Ivoid        APU::SelectExSound( BYTE data )  a9 m& J1 \5 w! J( }
{3 J8 i1 z% a* U7 z; {
        exsound_select = data;( `0 {  ?/ s" R" ^! R
}1 U6 o! y8 _$ Z% f

* a" _5 s+ C; T4 BBYTE        APU::Read( WORD addr ). e' O, ^6 O% C) a$ t. c  S9 {* I% ?
{
7 l4 d3 m# I  x/ G8 q# t" b        return        internal.SyncRead( addr );" h1 |* r) F1 p3 N" j1 z
}2 ?3 }# L4 Z8 a5 ^# t  C. ]" Z
7 W1 B+ g4 k7 i' W7 b
void        APU::Write( WORD addr, BYTE data )' c& J+ ^9 Y. Y0 f) t/ C, H
{
- e- U4 h  J0 R5 P        // $4018偼VirtuaNES屌桳億乕僩$ {- k" x, a( \2 u
        if( addr >= 0x4000 && addr <= 0x401F ) {
& S5 y- R6 I" w, q' ]1 B' V( v                internal.SyncWrite( addr, data );
5 u1 d: k$ B/ j4 r6 E& ]                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
) ^6 m) {: f  V* n        }1 {2 y1 L2 u/ n& B
}
  O- m  T; k! ^, |& ?( ]( B, H  o+ ?
BYTE        APU::ExRead( WORD addr )
( ~5 f' A! H" Z, a{
5 K5 D9 k  L: b3 N/ }' _( ]BYTE        data = 0;' y  H7 u; V. D0 _3 X
8 m* p' O. ~$ N- k, L
        if( exsound_select & 0x10 ) {
( D* O9 ?7 ]0 g1 H                if( addr == 0x4800 ) {
8 E; f" ]! \& J( d* J                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );2 ~5 l4 ]. z5 n3 t# w; e
                }
  K. W) d* c) b! f, y* ?/ A        }
: v. U$ C% X" N5 H4 J        if( exsound_select & 0x04 ) {6 p" O9 M- I2 z# r1 [/ [
                if( addr >= 0x4040 && addr < 0x4100 ) {
3 H( O7 o7 N+ \2 q2 }2 X                        data = fds.SyncRead( addr );
9 X2 S  ?4 x1 X% K7 N2 Z                }3 V9 M  T1 u8 l) J2 t- f
        }
. w3 {) V- x1 ?' ?        if( exsound_select & 0x08 ) {1 l, g' t* Y# a# ~1 F& e
                if( addr >= 0x5000 && addr <= 0x5015 ) {
! v* E! N, R$ @- \6 w, q0 ~                        data = mmc5.SyncRead( addr );+ R3 W/ v8 V* Y' `7 U
                }
5 {2 N! x' Z9 R' D        }
( O9 `5 t3 K0 E" }; g! [5 J
6 B. Q! i, E" G! I, a        return        data;
% L) N- Q. _( A, v/ Q}4 q1 ~# a9 M! N' J8 M# V
% {( J% y2 Z4 j7 B  d( [9 G
void        APU::ExWrite( WORD addr, BYTE data )
2 A- n1 ?6 ?2 w9 U/ q, x{9 U$ }6 y! P. a$ D! x5 G/ y
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );: l$ A) p+ s& B8 ~6 I

8 K; f/ ^0 e' I. i! F        if( exsound_select & 0x04 ) {
- t# u2 H' m) p; X                if( addr >= 0x4040 && addr < 0x4100 ) {# r4 x9 n3 V, `4 k) a. W8 ]
                        fds.SyncWrite( addr, data );
4 \! x) v- }4 E4 S  ~' j( T                }/ G8 Y' m: I* [1 C3 g
        }1 \: _) `: h4 i

/ f  ~/ q; ]! ~* B        if( exsound_select & 0x08 ) {
6 Z0 _" h# t) N% z                if( addr >= 0x5000 && addr <= 0x5015 ) {8 _. D# Q, Y9 ^
                        mmc5.SyncWrite( addr, data );! l- T% s. C1 m4 a1 J
                }% h* q7 J  [( s5 H; f
        }
: u+ P1 _. C+ M7 p: y5 _% Z  ]}
+ q7 j, ~* A2 C1 k: m& q/ c
0 X, P3 ?6 e) Gvoid        APU::Sync()2 M' n( v1 X8 B
{
; w/ P8 }6 A+ w% `- d; W7 w. U}# n/ t. l0 h* K  l- q: |
0 W. a# Z' f7 C/ V$ C+ M4 U4 I
void        APU::SyncDPCM( INT cycles )
9 B' i% U9 m: g( _, b6 d{
, F4 j& N8 A# D$ T        internal.Sync( cycles );
& A4 `# @2 z9 Z4 i" G! a( X1 O1 v  X* v* r' l* Z
        if( exsound_select & 0x04 ) {( U5 O- t4 G5 b
                fds.Sync( cycles );& F. P2 m8 D% V1 s
        }0 P) F+ v7 P4 q7 ?3 V+ l( N1 i
        if( exsound_select & 0x08 ) {" d  ^& M( w5 w- x& {
                mmc5.Sync( cycles );
2 v1 H) ~0 W3 X  X8 M4 K- `* W        }, R# R. A7 l0 V3 G0 a8 c
}) P3 N8 I0 ~7 }. T5 n; S/ p
4 v& h8 _4 U  p: Z# G. r
void        APU::WriteProcess( WORD addr, BYTE data )
) B3 X) _6 r, L2 t& ~- D{# ?  F) p/ P0 A9 |$ Y
        // $4018偼VirtuaNES屌桳億乕僩
; |6 j8 c* G- q8 B5 a        if( addr >= 0x4000 && addr <= 0x401F ) {
. U. j7 H3 V) i  u/ X0 k                internal.Write( addr, data );2 a; h  g) t8 i# J0 w7 p# ?: a( x9 S
        }; t1 X2 N* y- Y% |0 q
}  G$ c& x3 ~+ s" k7 b! q
& A+ O8 f* O4 P3 A3 W- g
void        APU::WriteExProcess( WORD addr, BYTE data )8 a8 b! V/ ?" }3 f3 m  J5 B6 t2 w0 h' E
{6 O% ~2 B8 D1 Z. o
        if( exsound_select & 0x01 ) {7 f) |: u$ D  }6 w
                vrc6.Write( addr, data );
3 m, B4 z; h7 A7 Y7 c" A        }
% a5 q. m% [! O) Q9 W) w        if( exsound_select & 0x02 ) {7 R5 B7 B! h7 ]( J9 A4 b
                vrc7.Write( addr, data );. [) s. O8 m) |/ h" h0 m
        }
5 G$ }$ Q2 j% _7 |        if( exsound_select & 0x04 ) {
( D- I1 G. f% W6 N2 x                fds.Write( addr, data );3 w# H/ m( e2 O( _. t( }* Q( e
        }& {: ^* Z$ ]* T
        if( exsound_select & 0x08 ) {
( t; C" Y3 s* U/ P) m2 {  z' ^                mmc5.Write( addr, data );7 r9 D0 H7 a# h' Y9 R
        }
7 M" e  b( {8 i% q  C        if( exsound_select & 0x10 ) {5 e' D) P- _& V0 @- l
                if( addr == 0x0000 ) {  z. w! w' p7 M" {0 @
                        BYTE        dummy = n106.Read( addr );  U/ y( L7 x# U% b# w  z4 X
                } else {
( N' B* a0 q7 e% Z$ i                        n106.Write( addr, data );
3 b+ f  b: R6 ]                }
6 n! N$ Q5 B* x$ j! O8 L+ \        }
# @% `6 F. @* b        if( exsound_select & 0x20 ) {+ F; _5 X' {# L( d. c) G
                fme7.Write( addr, data );, a: w9 P( n# M" z2 L8 h: n: l
        }9 U* L$ {1 c: r( w4 B8 \
}
. |1 j8 e& e- {
/ H& |  B5 u: j9 ivoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )1 L; f2 S7 J& c* m& ~: W
{( B. W' X# A, C4 `1 X
INT        nBits = Config.sound.nBits;2 c3 |/ B) p5 ^5 h: j
DWORD        dwLength = dwSize / (nBits/8);9 i1 K- s+ n7 s; D, X" [1 u( G* k; B
INT        output;
9 Q" ?' M& f! a$ u" K# K+ k, FQUEUEDATA q;
" p6 [% k% A# P6 k: W, C4 K* _DWORD        writetime;
8 z( g( M1 k- ]7 m% N
* G/ ^9 E9 q$ L0 ^" P1 k4 _LPSHORT        pSoundBuf = m_SoundBuffer;& Q+ I# s% B2 J8 g3 a. A
INT        nCcount = 0;
7 _0 Q( M- t  E4 H3 M  _3 c% C; F2 i4 F9 G+ j
INT        nFilterType = Config.sound.nFilterType;: @; j' j7 b- s  P1 H) S! M8 a

; c/ M" A4 n1 ^0 |8 W        if( !Config.sound.bEnable ) {; s& k, ~0 [" E1 }8 F
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );$ i, n- Y: _: B- z- d6 U7 P, D
                return;$ h( K: G4 _# B# t: X# n$ k
        }
2 X. q$ z* o) L( d$ x- G) a( a6 n7 e4 n% c1 Z
        // Volume setup
5 W1 s7 ~' S) J! U' l1 E9 R2 ?        //  0:Master
' O$ {! I5 D' o' C8 P; r2 d        //  1:Rectangle 1
! t' a$ e- L" A& H4 W        //  2:Rectangle 2
9 w2 r& d: p6 ?0 B+ e# x! m- v        //  3:Triangle
, X  A+ V) r' e# L' O        //  4:Noise
: t" K! |0 `- o& k- O& B& ]6 l        //  5:DPCM# K4 u* S: ?. C2 n. k- Y7 C
        //  6:VRC65 r& F4 a, l! j5 X6 p0 x. P0 g
        //  7:VRC7
8 h9 _6 i$ w6 {( T" i( N3 K        //  8:FDS: r% Z* m5 ]3 D: Q
        //  9:MMC5
7 a$ e8 ^4 Q0 h$ G        // 10:N1063 w' u% ]2 l; G5 }) e6 `: [1 V
        // 11:FME75 {5 C6 B6 k; U) Z# M2 t3 m+ V
        INT        vol[24];1 Q0 ~" _( j2 B1 h
        BOOL*        bMute = m_bMute;
' B. O( @; m7 T& F+ U6 t        SHORT*        nVolume = Config.sound.nVolume;' H& x/ B& Z7 j2 I: b4 `1 l  q* p
3 ^' X" u4 H5 F( H0 A* c3 O! A' D
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;: P1 k  S# R% R( T$ U! Q1 T
* y, C* x/ o$ ]/ Q/ L
        // Internal8 _% F8 Q( ?9 X: \7 S' Z8 A
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
9 B" b5 d/ M% h        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
: z: o% ~" m) C        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
& b& f8 R, I" R! e        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;" X" f+ k8 E% Z, E! s1 K
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
2 i8 ?( Y1 F, e; _4 K# q6 K/ X
        // VRC6
6 r% Y3 C* g3 B: c% [! O        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;% z1 G. B" F) ~0 X
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
1 d1 y! f) ~( n" F3 U* ^        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
: C# R. ], t; `6 z1 Z
( e6 a  R/ \. |3 ?- G5 x        // VRC7; h- F. n! Y/ P# I: R# R
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
( t/ h8 H& B# M: p, n! _) k5 j4 I  W  p
        // FDS" y7 a" r9 e3 ?+ |! z, P  J
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;$ L" s3 F$ K$ F+ k
& h( U3 g0 K; e/ ]8 c
        // MMC5+ C! B9 e' }/ d! I7 Y  m' `3 s2 T7 u
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;& p$ H9 Z% @( K, _* k
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;, E+ T+ B  ^: M+ }
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
: Z; r4 h+ r6 `3 K" D5 h9 A' L. n) t: }* N' g& B6 e
        // N106
2 C) B  z1 W+ ]. v+ d  {4 P        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;& g4 h* \9 t8 M3 [7 @
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;. e/ Q1 c# ?1 d' e! Y% J* S. A% {1 H
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ v2 T( g/ x' a. r+ \
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, B9 e. g# C$ _+ d' \) Q- I% ?        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 x2 d! Q: {' d$ R% m        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. I$ G" W# _2 i( w6 P0 a* G        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
( r1 u2 {. P8 f0 z  m        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;) ?: G  Q& m1 N' y9 y1 I
5 o, ~8 K; x( W1 O
        // FME7! m8 E6 Y" Q6 \9 @
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
; _6 y0 U8 G. w9 W* v* F        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
% V6 E( Q: X. K0 K( w) \1 [' m6 m        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
5 W- k* z/ M& ?* `0 u/ c, Q6 f5 V* P- s
5 T' j( @) F) S& l//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
$ s1 P2 {  Q/ L; Y; D; ?7 _        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;" s, |! U3 T2 w
+ m/ K+ ~$ e" f0 ]- q! I  I) Z
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
6 ?9 \7 ]3 d% [2 k% H  }        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
3 A' v! [4 k7 }                QueueFlush();+ e  V+ Z, B: ]7 C4 ?
        }
! Y+ n3 A$ \% J5 F( z* l; v* w+ G6 m- x, G7 ]* @  ]  _
        while( dwLength-- ) {+ S  Q3 K1 L1 c3 _& Z
                writetime = (DWORD)elapsed_time;
4 \9 U/ \) D# C' M; k" m7 \6 H; w' Q, q9 z0 n  u5 R4 l' ?( {
                while( GetQueue( writetime, q ) ) {
) Z. p, D  y9 o% K                        WriteProcess( q.addr, q.data );1 V  g2 H' a7 {0 R; s+ Z
                }* R$ [' c0 p/ c! |  K0 b; J# v$ ]
6 h" Z  L1 X# ^
                while( GetExQueue( writetime, q ) ) {
- S" T' u" W$ w( i                        WriteExProcess( q.addr, q.data );5 ~* u1 [  P, ^7 e2 U$ {" k
                }! H' u1 v0 c2 b2 p

# a2 p  N1 w8 }8 _* O1 D                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
* w) p' v) C( ?6 g) m5 w; N                output = 0;
  i# r  a9 H& H  \5 e9 X8 Y2 L                output += internal.Process( 0 )*vol[0];' m* q" o$ k2 S9 ?- J  O: V
                output += internal.Process( 1 )*vol[1];
) w( \' k5 y: J5 G# @: y/ g: W' {" t                output += internal.Process( 2 )*vol[2];! u2 e5 n1 b8 J) c6 C" k
                output += internal.Process( 3 )*vol[3];
8 }5 `: }4 u- F" |0 n. P1 A                output += internal.Process( 4 )*vol[4];* Q/ j9 d6 r" U7 u. Y
5 S- x, _" R% D& N3 J
                if( exsound_select & 0x01 ) {( V: u" t) A) E% C# `& H
                        output += vrc6.Process( 0 )*vol[5];
9 t8 a- J: v' I) ~& F                        output += vrc6.Process( 1 )*vol[6];
4 p4 i! r, l2 x. H7 x" {% G+ |                        output += vrc6.Process( 2 )*vol[7];
* l. e4 X6 h1 O6 \1 w                }
7 B8 C0 z* p: @) n4 x3 x                if( exsound_select & 0x02 ) {$ G# t, ]4 E9 j  F9 a6 U  E
                        output += vrc7.Process( 0 )*vol[8];
0 W. Y9 w/ d2 Z4 n0 f                }
! ]- c6 _$ K2 {: a/ ]9 t1 V; _                if( exsound_select & 0x04 ) {
5 x8 ?9 V) A4 h+ c/ T( w, C4 D                        output += fds.Process( 0 )*vol[9];
* F' w9 g3 O, \  i" D9 y1 n                }4 ]* Y' y, z" U& M2 {! l
                if( exsound_select & 0x08 ) {' U; ^/ k! B6 q4 m
                        output += mmc5.Process( 0 )*vol[10];
$ G7 C7 B/ b) a9 S                        output += mmc5.Process( 1 )*vol[11];" s% Z0 Y; p( m( `" n( v# S
                        output += mmc5.Process( 2 )*vol[12];
5 o4 R6 e- l3 N9 z; x% Z' {                }
8 q9 ^9 T) o; ^9 L9 o                if( exsound_select & 0x10 ) {
1 `$ P8 o% k' U* b5 j4 D& d                        output += n106.Process( 0 )*vol[13];) \6 Q5 H$ A' q1 M' ]1 a
                        output += n106.Process( 1 )*vol[14];* b, Y# {; J) H6 O
                        output += n106.Process( 2 )*vol[15];
* s3 e8 ]) U2 r# L                        output += n106.Process( 3 )*vol[16];
, x) ~( I4 l7 y& U8 N: b: F( `                        output += n106.Process( 4 )*vol[17];
7 P. Z$ y1 x; L& {0 n                        output += n106.Process( 5 )*vol[18];) |+ V* X1 J; i: y6 V8 S3 q
                        output += n106.Process( 6 )*vol[19];
" V- W) l* @- D+ Y                        output += n106.Process( 7 )*vol[20];
' o2 Q# Q( h: ~0 X/ D                }# X( J/ t5 J- k7 r
                if( exsound_select & 0x20 ) {' r3 N" q7 x+ {' i0 L
                        fme7.Process( 3 );        // Envelope & Noise
1 e+ h1 J* i) S: @                        output += fme7.Process( 0 )*vol[21];5 ]: \" T( G% P' ?# d, h
                        output += fme7.Process( 1 )*vol[22];
5 m2 ?, c# r1 ]2 k% c0 l. k8 ~                        output += fme7.Process( 2 )*vol[23];- R" g' p; e, Y% g' H
                }# z( _: Z6 B& R% Q
2 g6 a+ W0 O5 r
                output >>= 8;2 r5 v6 q5 c1 ?$ D' {1 K, j
3 X+ y  {( v- T6 m8 T% `( ~4 u; _
                if( nFilterType == 1 ) {2 i1 \9 M3 J6 _' c8 N
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)( w" K2 V( @0 p7 `* ?
                        output = (lowpass_filter[0]+output)/2;
* F# d+ o  M2 Q9 q- K( P                        lowpass_filter[0] = output;! D" t* C+ R+ t
                } else if( nFilterType == 2 ) {$ S& _; b8 L7 r( _+ C+ L, N# b
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)2 m4 H" R# C* B7 k& n. i# V8 v
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
9 o( W; y$ }( ]5 V                        lowpass_filter[1] = lowpass_filter[0];3 a* ^. Z. k8 X
                        lowpass_filter[0] = output;2 y2 `4 z$ e# A; W0 l1 ^" o
                } else if( nFilterType == 3 ) {
8 A3 X8 H* _& P6 A8 x6 u& ~                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
1 `0 Q- ]4 j* n. g                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;9 H0 K' p1 `; f& j' c4 O4 L
                        lowpass_filter[2] = lowpass_filter[1];) C! |0 u: V! S) f) O( l
                        lowpass_filter[1] = lowpass_filter[0];3 x$ A; s/ U- m1 d% k+ M) F
                        lowpass_filter[0] = output;
/ {* t* B" {1 }: Y! q. \5 {) ?                } else if( nFilterType == 4 ) {
) ^4 |$ S( q9 J+ c, `                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
% q+ b4 i# p! x                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
! X8 I5 k7 k, \: X" r( D                        lowpass_filter[1] = lowpass_filter[0];( c. x& B4 U0 i2 ?
                        lowpass_filter[0] = output;
5 M. r1 z# J, N% ?$ f                }( o# ]2 u' i, K" y' n! |, o# k; [
- P1 \; p8 @' `$ T
#if        0
: Z% Z  a$ B/ z6 O* H                // DC惉暘偺僇僢僩
" F8 \( Q% A4 U# F  A' u: c                {+ N# @4 i- r! ?5 S1 s( S
                static double ave = 0.0, max=0.0, min=0.0;
  T! ~; P7 z' f) _                double delta;& d3 F7 z9 i9 O. Z
                delta = (max-min)/32768.0;
! h8 q0 k, b9 l5 t- c: ]6 r" E                max -= delta;
+ J9 i+ K- s$ Q( Q# H' ^                min += delta;8 E& u: E1 n6 T! p# B, @
                if( output > max ) max = output;
" f% }( r5 a9 U, k! l                if( output < min ) min = output;4 G% B7 x# o9 M* Y( C8 `6 L2 e3 G
                ave -= ave/1024.0;
2 M" Q: C& L" C( d" R0 @                ave += (max+min)/2048.0;
+ c5 l# I( U+ z! A8 r3 m                output -= (INT)ave;! H5 Q3 A. K( W3 r  C" x
                }
$ b3 J6 F0 n; y# H4 w, m' ~9 A; x#endif/ Z  E" F  a% B; x( I3 s
#if        1: \- I; N& f( K0 B
                // DC惉暘偺僇僢僩(HPF TEST)
  H& u2 t# O+ `  {8 X) M+ v2 N5 T1 S                {
* J6 m2 R# T3 x6 b. S  Y//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);/ C7 D3 }; ]) K# d; U) t
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
" f! j2 D  {3 g% p% y: j                double        cutoff = cutofftemp/(double)Config.sound.nRate;
' R+ `% F) M, b' n. d: v                static        double        tmp = 0.0;8 p+ B7 c4 c4 s" _9 D. ~5 a
                double        in, out;; z* \0 Q6 a! l; Z6 `0 _
. ]) Q3 v7 p% c% ]
                in = (double)output;
) U3 D( x- N! d/ I/ @- Y& H                out = (in - tmp);
. |  r/ j% W7 [: }                tmp = tmp + cutoff * out;2 C! u& F+ P+ V( M" h. g

$ @% ~+ T& r) Q. ^                output = (INT)out;
7 g4 J* ^2 n9 u( B                }' I' p% l0 @, T; V. K* a5 r! Q
#endif3 o- b2 K% Q5 h! _
#if        0
4 @% W5 K% L7 u# o6 g8 z; H                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)/ X1 ^! n: q- ]
                {  R( S. @: O3 ^, p5 \2 v
                INT        diff = abs(output-last_data);
/ U; J4 m5 T7 S% X- G# n                if( diff > 0x4000 ) {% q2 ~6 S2 e  _9 n0 d& b( S7 M, u7 ~
                        output /= 4;
# a( d- O+ _: `$ k( F# z: J. U                } else ; u) S% P' ?  H1 i+ e/ }/ g
                if( diff > 0x3000 ) {/ ^" l- p- p6 L* n/ Z, J
                        output /= 3;
6 E8 j' P  m; v, Z                } else
; W; B' q+ o4 C+ R0 b+ b                if( diff > 0x2000 ) {0 V' S5 x! G( ^$ D
                        output /= 2;7 U2 H! o. w) o( n7 s
                }
- t. z6 g* N. p+ h                last_data = output;
+ h, e1 e6 n8 ^4 y                }
2 T) w) z) @" z) T+ `7 ~) X#endif
  s6 \) Y0 W8 u                // Limit
" e4 d. t! ?7 J& `" {0 P3 u* w+ @                if( output > 0x7FFF ) {
" S9 r# l" X8 p9 }8 q& z' l                        output = 0x7FFF;/ C* e3 J0 |$ h+ U
                } else if( output < -0x8000 ) {- B& B) T/ S1 |& ^4 n. G; F, J
                        output = -0x8000;
: n7 j5 i5 T/ N. |; M  D. V9 s- I                }
; Y! r/ n/ N: f1 N) w  `, y8 V' F. \% k3 _- I9 \& q
                if( nBits != 8 ) {4 D; q- B# a+ f, M  G' W0 @
                        *(SHORT*)lpBuffer = (SHORT)output;1 J4 x' \4 d8 q7 ]7 U0 q9 I% n: K
                        lpBuffer += sizeof(SHORT);1 K1 v& v) P5 K  v, G% m
                } else {+ u# A: p; R: q6 f( ]
                        *lpBuffer++ = (output>>8)^0x80;
4 z0 r2 t% J" E3 P4 N                }
& P, S( C' x5 P' _; T8 g7 P6 `
' q0 {  t# x5 P6 i7 T3 G- t                if( nCcount < 0x0100 )
% t8 S9 g% M+ o' T) T' G0 [                        pSoundBuf[nCcount++] = (SHORT)output;! h, q' N  Z; `' d' t) p

" d# u, S$ `. `% p5 N' h3 ], I/ a//                elapsedtime += cycle_rate;
) Z# `+ N) H3 b% K* M                elapsed_time += cycle_rate;
# }; \1 ]1 @" r* d# E1 P        }& Z) q4 r- d+ ]4 d5 V# H$ w' `. U
& m9 c* ~, N# O$ i
#if        1
- W3 s. P" P1 d& l" s! O8 C& X3 N        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
; o4 w+ x4 G$ c1 ^8 I2 E                elapsed_time = nes->cpu->GetTotalCycles();" X& V# v2 y! K# e$ e# X* {
        }6 Y+ t$ r/ q: m% c! S+ Z
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {: v: q! k6 t$ L. Q0 i: ^' K0 s
                elapsed_time = nes->cpu->GetTotalCycles();. Q. j3 ~* r1 c7 |- @* X( B6 L
        }# Y- W! M1 i6 [6 U# s
#else
$ U* z! f' Y+ J5 x        elapsed_time = nes->cpu->GetTotalCycles();- y0 _! _3 K* k) ^: R- G% m4 w
#endif0 Y! o/ }& A' R7 y
}' h7 i. O+ Y( C! u
! B& }) ]3 Y4 {  F" C' W
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
/ U3 P4 @) U; S8 H) u7 e7 iINT        APU::GetChannelFrequency( INT no )2 b7 r) y# {0 z4 A
{0 Y, c! u8 |" S  \& W3 }( |
        if( !m_bMute[0] )
% b- t- X3 K& B6 R                return        0;, s/ }0 v* k( z

  Y/ Q- `: {3 c" @$ d1 t        // Internal
9 ]" [1 h* R9 V! H2 Z) h        if( no < 5 ) {, r& ~& Q" f2 A. q5 j  e# O% N
                return        m_bMute[no+1]?internal.GetFreq( no ):0;" I1 a+ \9 Q# d8 ]- P) b  F
        }$ v8 Q! x# Z- [! a9 S
        // VRC6
$ e7 R5 i8 f  {: B3 b        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {" w$ w, ?4 G! Q0 d
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;1 t0 w' z/ |5 o! j3 C- B
        }9 X1 s) M' g; A$ G
        // FDS( o' ^$ Z4 i' x) u
        if( (exsound_select & 0x04) && no == 0x300 ) {
* e6 D$ b  ]0 m% n( u7 Y                return        m_bMute[6]?fds.GetFreq( 0 ):0;$ K' _9 M2 V2 F7 r# F' e% E
        }
$ `5 m, R5 ^! Z  {8 o) K        // MMC50 a. D0 N- C& P# }1 d! F
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
% {( @. l, @5 j- m( ?7 B. n/ c) J                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
. C1 ^" G5 p5 f" ^' H5 S: T6 C        }6 m  ~7 T0 s8 j, V! z+ X
        // N106: |2 |1 l- N- R* b* {) C5 L
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {9 b, J' P$ i  c$ N  L4 h
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;: P0 N. T2 A! w* ~! H6 G
        }
4 z  ^) r  _0 w; T2 u2 O        // FME7
, b( g5 K( n0 [0 w, p3 e        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {9 M; ?& z. \3 j$ Y9 ]5 y4 P
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;8 y, D, x9 p6 Q- K0 ?: C# X" k
        }0 F; u& w  V. ^0 ^: T  t% k
        // VRC7& @8 E- N: {8 `; R
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
) [  \1 U8 t- v# {) E2 V                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;5 u7 e" B3 i: L, J3 J
        }9 i! k. ~; }+ L3 U: _$ H3 z
        return        0;
  k9 H2 z1 h* r0 J8 @}/ f; s2 e6 B2 J
( z/ ?. v7 v% n
// State Save/Load
! l0 o0 T8 H# i: |0 ], u) _void        APU::SaveState( LPBYTE p )
5 x5 I8 Q7 [# R& @8 O{% H* F, Z' h& B& A% A
#ifdef        _DEBUG
1 i! x& [; U% P3 ?8 `LPBYTE        pold = p;
! W% M' m( n1 u: d#endif4 e1 @* A- L9 R* S, ^" b+ S
1 R1 a$ S0 G5 |* c/ O+ b. U
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞$ h1 B; \' w. p4 L5 m! T
        QueueFlush();
- f5 L( C! R# h; X/ K9 x) m
; l% C% m1 T* ]- J9 z        internal.SaveState( p );8 `! {% G* j; A. R
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding8 l% y, l$ p9 Z- c9 ?. ^

  P4 ~4 J- a# n7 n1 q1 b        // VRC67 V5 ]# Z/ n; U0 V/ }
        if( exsound_select & 0x01 ) {3 ?% Y! }4 c+ k0 C0 e( d
                vrc6.SaveState( p );: J* ^! l0 y6 N4 n9 h8 z
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding4 G& ^* I5 y$ k1 }0 v* ^
        }; }$ s. A! |$ I: u3 S$ u
        // VRC7 (not support)- m6 Y; s1 s1 y& D' a, f3 C/ \
        if( exsound_select & 0x02 ) {$ h6 O. m6 ^0 D! m5 ~
                vrc7.SaveState( p );
1 [, n, w/ C) c+ w/ l                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding, T6 s) P8 I: E- c" k
        }& T+ J& s; }/ C5 W: s2 L  Z: M
        // FDS! B% S3 E& A, o; E
        if( exsound_select & 0x04 ) {* h/ p8 S+ y. _5 Z, W
                fds.SaveState( p );
3 |2 [( |' E% t  P                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding# E9 z4 G) s; @9 c! s* d
        }
8 H: J7 I4 Z8 J, ^6 b        // MMC5' z9 r0 Z0 J) g) p
        if( exsound_select & 0x08 ) {  r" {# f( u% a2 q: h: S
                mmc5.SaveState( p );# H" C$ b5 }" {. n7 q
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding* L; {# U# J/ H8 u, v
        }
9 s# r/ B( ~; A        // N106
$ q: s) i" Q' d3 j# ]        if( exsound_select & 0x10 ) {" \# E; v/ W& L* Z
                n106.SaveState( p );
0 F# _9 U1 X+ e9 \+ `                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
9 U5 L/ x9 z8 {2 b' w+ Y' k        }
5 Y3 z5 i4 k8 Y# _; d$ w, f' M% E        // FME7
& Q, V; Q7 E0 V# {( d# y/ E        if( exsound_select & 0x20 ) {: J) G. f. k7 o( r: r
                fme7.SaveState( p );4 Z$ I* A' Z2 C
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
1 o! O) S8 n# Y2 B/ [! N        }7 [0 O: x  I# @5 N4 s+ \' q  C* k
/ {% }5 K: Y' t8 K4 ^
#ifdef        _DEBUG$ Z2 c/ f( j8 `" C! }/ B" h; |* }: o2 j
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
$ l2 L: V% H4 C$ Q' \/ U9 K( h6 [#endif3 D  d' `1 ]* e( S# S
}) L* M! @2 Y7 W: S8 @' Y  a3 I

: ~6 K) K6 R* A. l" A2 avoid        APU::LoadState( LPBYTE p )
4 _' o2 d5 y3 T4 R9 k{
: D9 e' Y" E6 t9 e6 a        // 帪娫幉傪摨婜偝偣傞堊偵徚偡/ e7 }. R6 S& x, M# }9 x
        QueueClear();
! ^" {$ y! Y1 v2 B
; y+ g, h: y; a        internal.LoadState( p );
0 h9 h' B  P0 F6 M        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding) T' T* p$ }5 U3 G

5 ?( v, b' K0 O& B& T0 U        // VRC6
7 V. ~( L' N& S4 z$ _; H! G        if( exsound_select & 0x01 ) {+ d% U2 j3 N1 e; c* H3 J
                vrc6.LoadState( p );2 r% x6 }( H+ I2 `7 w$ J$ B2 U1 j
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding. z  H3 l. G3 b; s5 J, L
        }
" H' X; O3 |+ W" `0 J  d        // VRC7 (not support)
4 b* O% i2 h) u& b$ E$ n, r        if( exsound_select & 0x02 ) {
; g+ w' h, ?5 k* S                vrc7.LoadState( p );! D: M9 v0 l4 S4 c/ L1 w9 R7 x
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
+ M& R; \6 R% G8 c        }8 F. e) c, ^* C( I. f8 w0 ~
        // FDS, E; `9 ]  w5 Q
        if( exsound_select & 0x04 ) {! U, b( J4 V* l/ G. }* W5 r4 _
                fds.LoadState( p );
  F" [/ y% q* z0 F) b! C6 [- C: X7 v                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
7 n2 a+ ^) s+ j' x9 m' ?1 _% t: X        }
4 Z+ s& O% t( [  H2 Q% F$ K        // MMC5+ ~4 L$ y& r- Y7 X( k6 j1 X0 j
        if( exsound_select & 0x08 ) {3 v* m# D) j6 Z. @
                mmc5.LoadState( p );& C6 {% f4 ~6 P  h1 W
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding( U* L. W/ s0 \( w  S
        }
0 N$ y6 K+ T. i/ h6 i; Q        // N106
% G4 k6 r9 z% z) ~1 b! N        if( exsound_select & 0x10 ) {
/ ~) |) g: b5 K' U2 H0 I# D% ~                n106.LoadState( p );
2 a% [  |: s/ e8 D                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding5 I9 W2 H  Z" Q" A$ J% u# d8 S
        }9 K% J9 q5 F, r# ?+ ?
        // FME7* T  E# l  Y, A- d1 V
        if( exsound_select & 0x20 ) {4 g) P! ~# d/ m. E2 G5 @
                fme7.LoadState( p );
4 g% Q7 @4 D. W% h. o' j& q                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
# D0 i( N3 a1 [) ^& F/ |6 U4 B        }! p8 @9 K& T. m! P
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
, z* o% m' p! s+ U. j1 h5 g" _5 w可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
2 o5 g! B7 [* Q" d感激不尽~~

# l6 v9 v% v* B6 W$ e0 j恩 我對模擬器不是很有研究,
- C6 \. E9 o3 u" `. k0 R  }; x雖然要了解源碼內容,可能不是很困難,
/ t  |4 ~& \4 Q7 [" F不過還是要花時間,個人目前蠻忙碌的。, o  d' n$ m7 _" Z0 c4 L

! U9 q" \3 F1 z, y! i$ ^; g給你一個朋友的MSN,你可以跟他討論看看,' N4 g: `9 H# S- K
他本身是程式設計師,也對FC模擬器很有興趣。- ?' s' F0 [1 {+ v# ?+ {- E

; A3 e9 m; a& C2 f4 ^  mMSN我就PM到你的信箱了。
. i- H. C4 H$ l  |1 M: g% j& Y' ~% h' f4 w$ p8 W9 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 发表 / _# M$ Z4 @$ T  T
呵…… 谢过团长大人~~

* V- D- }: J7 [5 f; M6 c
) s# n$ l- E8 Y$ K2 s) G- v+ _哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 0 D$ }  p9 B* U8 E2 E. L
团长的朋友都是神,那团长就是神的boss。
- [$ f5 Y9 p/ B# t
哈 不敢當,我只是個平凡人,% }9 m# x9 u5 N- t) T# b8 v
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙) h9 F$ n9 B, U/ N; |% L
ZYH
9 \6 |# c0 i' l) Q4 J8 N: Y' a0 g, TQQ:414734306( S* {' J! K9 K# Z. L
Mail:zyh-01@126.com
% P. y& s4 _5 s% K
& J2 [5 s  T+ C5 }他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 9 N: W1 w' D+ J" E2 G0 P* T3 y
再次对团长大人和悠悠哥的无私帮助表示感谢~~

7 [9 |( B5 X% j) w* j不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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