设为首页收藏本站

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

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

  [复制链接]

该用户从未签到

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

该用户从未签到

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

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
  g: @" H7 W" `; \4 S$ O楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
; f0 y' ^1 X3 W! w8 s2 P这里有相应的模拟器源码,就当送给大侠了~~2 V3 g- z; i8 Z: U/ ~: l" }
http://kenkao.qupan.com/5096520.html
回复

使用道具 举报

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
8 r$ [2 b9 w# ?. a) e能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。  o2 v5 B7 H' D) x8 ]
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~$ H- q0 O; v2 ~- o% b1 ]8 G
这里有相应的模拟器源码,就当送给大侠 ...
1 q5 e1 _0 w9 `- L+ d* I
聲音部分(Audoi Process Unit = APU):/ ~3 `: Q( f' f+ C8 r
.\NES\APU.cpp
- Y& t0 u2 o. Q/ D. H: W4 `3 |4 S.\NES\APU.h
. l) Q$ W0 X$ [# P2 J
, c! J9 U& N4 F0 {2 `$ j+ P
, _; ?) j) S2 S影像處理部份(Picture Processing Unit = PPU):
6 x2 H9 \- @9 M7 [. `$ R.\NES\PPU.cpp
2 }! M# D* p  ~3 B! [+ {3 E.\NES\PPU.h
! n+ w! }% c! c* ~! \) z  A& G2 a# t3 W0 t4 u4 j3 U
如果原碼用C跟ASM混搭也不錯
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 14:38:21 | 显示全部楼层
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
; n- P, W! y- e6 _. V$ L$ p2 `感激不尽~~
回复

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
0 Q- ~5 F* W7 ]  Y  g(由于很多专用术语和算法机理都不明白,所以看不大懂……)
$ b8 r% z( ^9 }0 s  s//////////////////////////////////////////////////////////////////////////
5 ?9 i5 G4 S, j6 [! S4 G//                                                                      //
. O- ^) b" }0 x# J( A: f+ a//      NES APU core                                                    //
7 E6 b4 U6 f8 U" I//                                                           Norix      //
" j4 P. f! Q$ M& a% f- l//                                               written     2002/06/27 //
+ p7 R: @4 y$ F1 t//                                               last modify ----/--/-- //, e4 j: b6 G  e0 J' D
//////////////////////////////////////////////////////////////////////////  K8 w( G: G8 g7 }  n
#include "DebugOut.h"
3 h* B; G. l! I#include "App.h"2 f' R7 E( V6 a' Z0 H1 y5 ~
#include "Config.h"
: Q% H# m1 i# n+ ~' V  H7 m
2 v+ n' A+ I7 F. r2 \#include "nes.h"; ?9 n9 u! ~0 l: u3 e8 x
#include "mmu.h"
/ D+ o. u0 G% P#include "cpu.h"
% S& ?1 Q5 R" e#include "ppu.h"
( z3 n; P! V" t% \( ^#include "rom.h"& h0 A) @0 \7 |) m: U
#include "apu.h"6 q' e  p1 Q' W+ F! m

9 k4 b3 p/ g$ B! l4 G// Volume adjust
: d. G" n1 W( ]" L6 N; ]$ f// Internal sounds7 [0 k/ ]- ]+ d' I$ i& @, ^
#define        RECTANGLE_VOL        (0x0F0)( t5 J: z' h# \4 O
#define        TRIANGLE_VOL        (0x130)8 B/ K+ a( N7 o
#define        NOISE_VOL        (0x0C0)" d0 ~" w- o7 R& ]& |- E
#define        DPCM_VOL        (0x0F0)
# b2 b, p3 J) y: |* t8 {% y+ x8 l# f// Extra sounds0 y5 D4 @; @: J. f' V( p$ @$ J, Z
#define        VRC6_VOL        (0x0F0)# @( g" i+ S  Y& c
#define        VRC7_VOL        (0x130)2 q/ H# @6 E# ~
#define        FDS_VOL                (0x0F0)
# T- S; E) [  R; b7 l) U#define        MMC5_VOL        (0x0F0)/ o. \0 V9 z4 O, Q# i( m
#define        N106_VOL        (0x088)
, f9 M$ U  i' Z/ J! T#define        FME7_VOL        (0x130)
7 ]; [9 }" X. t6 W$ ^+ W  R, `- D6 C1 U9 h6 g3 @0 G; U3 N
APU::APU( NES* parent )
2 i" d) j  M* m* o{( j' Y7 P9 t4 l% @
        exsound_select = 0;8 _) t/ K: E3 H) ?" R9 ~/ `

/ U5 l- l) F4 V0 q2 c        nes = parent;; m) y. z  w( H
        internal.SetParent( parent );
2 N$ I0 [4 R- ^
- @# e& f+ A3 A" D( D. H        last_data = last_diff = 0;
  ?6 K/ t$ k( U" I" |' _$ w( X  o5 h9 |. `! g/ f
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
; W! z! H: C, M
1 s  U/ A1 V6 k% K2 V        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );$ l, j, s# L, n" V5 Q; |  s8 Y, @0 J
        ZEROMEMORY( &queue, sizeof(queue) );2 T, k: [6 C( L3 B0 S% }7 X. c
        ZEROMEMORY( &exqueue, sizeof(exqueue) );6 o; y: m$ `9 n, f  {

' z) U+ r5 w, j  d' E7 M        for( INT i = 0; i < 16; i++ ) {
* c8 L# Z6 i' l: _! C  ]                m_bMute = TRUE;$ V# w: o( u; ], c
        }
4 F, z# }+ p7 S3 i! y) e}
/ D) |$ V# j8 n0 [/ p+ [9 p' g/ s- g% {/ K! R
APU::~APU()
/ V+ W! \( c) K! W3 p3 j* R" w{  Q" V4 y3 B' C
}
0 w! N2 \9 t* a. e: M; L% p+ _5 Y0 }( X" D) @
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
6 [8 O. \2 X3 i# O9 u# L{
) F" X2 R9 ?5 G! I' u, e        queue.data[queue.wrptr].time = writetime;) T4 A2 O3 {8 _/ X
        queue.data[queue.wrptr].addr = addr;
+ D* f: x- F" O4 q        queue.data[queue.wrptr].data = data;
0 m: S. ?$ K/ h* F, Y7 K        queue.wrptr++;% [6 B* q1 f3 H# Q9 y1 n2 j
        queue.wrptr&=QUEUE_LENGTH-1;; d* A/ z  J, j9 R9 M5 ?
        if( queue.wrptr == queue.rdptr ) {# L7 D! Q& t5 e: |4 B- a1 L
                DEBUGOUT( "queue overflow.\n" );$ E3 g: L$ Z' N- ]
        }+ V+ e: u$ D! {, K+ s6 D. ?
}
9 c5 l$ t4 x6 N* N. p# q) }; V
( t% k6 y  I% A6 mBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
3 C3 ?. x6 D" e2 P3 S4 R$ k{7 D6 \3 i1 V! M7 b3 j3 D8 Y$ d
        if( queue.wrptr == queue.rdptr ) {
' `; _8 i4 T5 y                return        FALSE;, M0 @7 p7 ?2 P' V. H
        }
) P) Y5 c; {# G: w! G1 i7 F        if( queue.data[queue.rdptr].time <= writetime ) {
) `$ P- T, V9 Z& s1 H                ret = queue.data[queue.rdptr];
# u# ?' J! E. b0 [0 I4 J                queue.rdptr++;. j, M5 k8 y7 _& l( ]7 z7 r
                queue.rdptr&=QUEUE_LENGTH-1;/ @: ^# v; Y! h
                return        TRUE;
# o- Z8 j1 T- X        }
  l& M+ k5 |- v* l        return        FALSE;/ ^5 c8 S5 l) ~3 ]0 y" G" ~9 O2 m
}
8 o4 D. }) a. R) r! g0 N, N7 Q  u0 H, K& A. f8 d8 P
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
; k# T* ^5 M1 U- c{
3 |1 T  V7 H% n$ J' n        exqueue.data[exqueue.wrptr].time = writetime;
' C8 q: b5 H8 l$ D8 ~3 r. R        exqueue.data[exqueue.wrptr].addr = addr;
! O3 |" Z' f2 _3 ?        exqueue.data[exqueue.wrptr].data = data;3 j, D1 ~* g0 O$ K
        exqueue.wrptr++;% b( b/ i9 N, A' g& H
        exqueue.wrptr&=QUEUE_LENGTH-1;# j7 m2 V) R$ H6 `2 [
        if( exqueue.wrptr == exqueue.rdptr ) {
; v5 {4 F- S, B, ?( Y' l8 w$ \8 m                DEBUGOUT( "exqueue overflow.\n" );, v0 ?4 h! G( t1 C) d; @3 C! d
        }2 P3 T1 e1 x* s" A
}: p- }5 T3 p5 u7 B- q

+ R) i  l) c% v6 ]! EBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
8 g! H# j! _2 G5 H1 f5 v1 |{/ z2 J$ L: c( c& N% w: P6 K
        if( exqueue.wrptr == exqueue.rdptr ) {
$ D5 c; I0 _9 g( d                return        FALSE;
( Q: S1 s! M1 |7 ^        }
8 H; s9 d! M1 q: |        if( exqueue.data[exqueue.rdptr].time <= writetime ) {# }" E! `# R6 t% F  C( I3 S
                ret = exqueue.data[exqueue.rdptr];& f6 ^5 l8 O: _. {# B8 g' u
                exqueue.rdptr++;* [6 ?4 G: ?0 z/ t- V, t
                exqueue.rdptr&=QUEUE_LENGTH-1;0 G! {! T7 T/ q( Q
                return        TRUE;
5 \( R: T8 v3 {2 d4 d0 O        }& F- ?, C6 d( `4 h: [% X
        return        FALSE;5 V" l+ N1 u, y: G# ?& j* m* j. c# R
}2 b. m$ r- i0 w; c7 S' V/ S
7 t; c( ?/ ]' M
void        APU::QueueClear()1 [* x$ p5 y3 v0 I" H& x
{
/ O$ o; ~& F/ {1 G8 c        ZEROMEMORY( &queue, sizeof(queue) );( U# `9 _# Y# D6 X- U0 `
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
5 n1 i; C! l) S; `/ L4 w/ J}4 w, p0 w. f( P; v$ O

* `; T) G1 b2 \; x0 j7 L4 nvoid        APU::QueueFlush()
3 Q, o# f2 S' d* \{- W+ k  t  M* v* H3 `8 ]" M
        while( queue.wrptr != queue.rdptr ) {
6 P  R, R) e9 Z# n( b                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
+ @- |: ~2 S( ^! a* o                queue.rdptr++;& `' w6 A, f! N. Y9 C! [; _
                queue.rdptr&=QUEUE_LENGTH-1;
! ^6 H$ t7 P& |        }
- \! u' q9 i9 ?, v( m) X. p( g
8 ^; b) A5 w$ I8 k$ d        while( exqueue.wrptr != exqueue.rdptr ) {6 F& M9 {1 @) {& o; x* U) O6 T) p
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
2 F( `/ C. D/ x4 |  E5 H                exqueue.rdptr++;$ I: Z" ~0 @# w% Y
                exqueue.rdptr&=QUEUE_LENGTH-1;
7 w! V. y$ E+ T# J        }
- z; b: ~4 q* s7 N+ q}. a" o7 ^$ ]9 G, _

6 @5 H! j" e; avoid        APU::SoundSetup()
0 ^  B# n3 z! \' ?4 B{" u4 r2 U$ V# d: d/ c
        FLOAT        fClock = nes->nescfg->CpuClock;% ~" y# z* C; S9 ~0 _
        INT        nRate = (INT)Config.sound.nRate;3 y3 ]4 z8 i4 K! w" i( U
        internal.Setup( fClock, nRate );/ T1 ?, x- \; Z% Y% i1 s
        vrc6.Setup( fClock, nRate );
9 Q* |+ w6 \8 z, W/ ?        vrc7.Setup( fClock, nRate );! r& x; E' s* u- c' u
        mmc5.Setup( fClock, nRate );7 W& L. @& S6 r- q: F
        fds.Setup ( fClock, nRate );$ w* U/ P% W9 m, M/ [8 N  E; l
        n106.Setup( fClock, nRate );
4 @: y4 j1 K' S" p& Y# Y: U- E6 E! A        fme7.Setup( fClock, nRate );
0 |2 o( O5 r5 ^, E* C( Y}
0 @9 j' |; C. p& r% Z$ @6 s% E- e9 r
void        APU::Reset()+ t% u/ ~4 ]$ x0 e  V, L8 ]/ B
{5 ^# \# r2 r# F/ D6 j
        ZEROMEMORY( &queue, sizeof(queue) );) c! F7 M: f! D. Y7 p
        ZEROMEMORY( &exqueue, sizeof(exqueue) );& L  @  r( K" X2 d* I

% y. W* s# u: x$ r" e- {$ n        elapsed_time = 0;
. k; s& T/ m. w/ y* n$ h# l' H; N
, n2 ~7 m, Q/ \! M% y8 O/ o        FLOAT        fClock = nes->nescfg->CpuClock;1 d2 r0 E9 H3 `
        INT        nRate = (INT)Config.sound.nRate;) H# e% L, R! |9 z+ l
        internal.Reset( fClock, nRate );
$ u. d  Y1 B$ |- k- K  f        vrc6.Reset( fClock, nRate );
( ]- _7 Q/ t3 J        vrc7.Reset( fClock, nRate );, W3 V+ R# }+ o% W
        mmc5.Reset( fClock, nRate );
3 c- R4 ]9 ~; O0 ], a* k6 h1 @6 _        fds.Reset ( fClock, nRate );
7 d: l" o3 {3 L1 R$ g. G0 u) }0 N        n106.Reset( fClock, nRate );7 s: c! _' y4 z
        fme7.Reset( fClock, nRate );' t( R; T6 C: q* B

0 Y0 c- \; l8 b7 t( Z6 l' t        SoundSetup();6 r) G8 J# v5 @% f( K. s6 F+ ?* i$ L
}) B% f( s% l' O

$ f2 y7 O* C( |* f$ {$ K. Nvoid        APU::SelectExSound( BYTE data )# m/ T9 Q$ h) @. C& G! q, ^; X! l
{5 X8 d# j5 X1 P
        exsound_select = data;
2 p* H/ d$ C0 E  E( ~}
. I9 Y& p% h7 _: S9 F9 x  c6 O) t3 X4 E  ?" n& S
BYTE        APU::Read( WORD addr )
2 F! V3 T% C$ _0 D{7 V+ l. L6 N$ F' b& {
        return        internal.SyncRead( addr );
7 ?- k% E. ]; o/ d2 r2 k' X}
( L4 P/ K; W7 k& n3 m
# U( n8 R* N# I2 f7 h5 k  K* }void        APU::Write( WORD addr, BYTE data )
- U# q- N2 G+ G4 |7 w* ~+ ?{
# p9 N3 l) M! s" T        // $4018偼VirtuaNES屌桳億乕僩
( u# v" }  E5 `6 N$ f( N. U        if( addr >= 0x4000 && addr <= 0x401F ) {- p1 u9 L' f; o2 u0 N0 ^
                internal.SyncWrite( addr, data );8 M8 |1 v. k2 h1 c) J6 G" z
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );4 r$ I6 A0 ~7 D
        }8 T0 g; q& z, C( k, x
}
" P/ m" E( i9 ~5 g$ t2 ?" T2 ]8 j3 S
BYTE        APU::ExRead( WORD addr )" ~0 `+ d) m8 p4 w
{
( ^* R( u- [, ?  ^, IBYTE        data = 0;% n! W5 \4 k# G" t7 E. g! W) X
0 h5 j. u6 D5 @1 ~# v6 I( Y7 r
        if( exsound_select & 0x10 ) {; o: K$ _" V/ g0 g4 R
                if( addr == 0x4800 ) {, e$ E' [$ G3 b, o- e
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );; ]3 ?/ ^9 ]) w- m1 D) N9 n. i
                }
( S, [1 u% B8 l- _; a6 K        }5 t7 S, q& D  z; D+ x- x! B
        if( exsound_select & 0x04 ) {: u7 o. i3 H1 S7 o7 Q# M# @3 d
                if( addr >= 0x4040 && addr < 0x4100 ) {, Z- ?2 k& f  |* i' x# z+ g+ I% I
                        data = fds.SyncRead( addr );
/ Q+ ?2 b! m* {  X- v- g7 X9 _                }; `2 j) ?. i! q
        }7 ^0 e7 c/ D+ \+ Q
        if( exsound_select & 0x08 ) {
- A$ F9 r! `4 C! h                if( addr >= 0x5000 && addr <= 0x5015 ) {" W8 p9 X" \8 a/ V% _: O
                        data = mmc5.SyncRead( addr );
' F: K( F. `5 }* n8 f# [                }: S, w6 K! n$ _- |: I& {+ P! A$ W
        }/ H9 l% m/ b1 W: U% }
. B$ d' a, A* J3 n# e2 p5 d  W
        return        data;
+ A( N! u. I' j}' i* }3 W/ s' X# I

* {2 f; f% A' V2 n4 ]- fvoid        APU::ExWrite( WORD addr, BYTE data )
" ]8 s5 y9 J- Y$ _8 `! t* H{
% G7 W$ T; k# ~6 X9 I        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
1 T- y: o% _* W( g6 p' p
9 D9 _) M  i7 M$ z$ l# L7 x        if( exsound_select & 0x04 ) {
: S6 m) y" u/ t$ m; F& B                if( addr >= 0x4040 && addr < 0x4100 ) {3 }7 S5 s( n7 H( K% s
                        fds.SyncWrite( addr, data );% b  V; s& U4 J* H0 [
                }8 |( D9 v& t, @2 k+ g3 h5 _2 F
        }
9 [' [% d9 r& T0 W; |! _" E. g( u
) h) H* F' }% `" ]/ O  {$ h# i( J0 _        if( exsound_select & 0x08 ) {
: K+ |# N6 R9 @- s/ d; |' u" Y                if( addr >= 0x5000 && addr <= 0x5015 ) {
5 w- h" @" f# W* w5 A8 _- z$ q% I                        mmc5.SyncWrite( addr, data );
8 Z9 Y7 r. W" Y6 v6 i/ z                }( h" C5 }: q* D+ K. B
        }" J& w9 `6 q; H
}. k& O+ H9 S% T6 y3 d

- o: p# g" ~! v% @& J2 }void        APU::Sync()
* d# O/ K# A. S6 t( b/ u{
. e- [% G- C9 I$ y, y6 y0 M}1 {. s1 u+ g3 K

( F" {  `1 @/ N) m3 w; S5 Ovoid        APU::SyncDPCM( INT cycles )' G3 i& U+ K5 J8 s
{; M) I- q  K+ P# p
        internal.Sync( cycles );/ F& z/ L- T9 ~) L
& j; [# {, H4 B$ k
        if( exsound_select & 0x04 ) {, c$ R' y& g7 I7 |0 t' d+ ~! V5 j
                fds.Sync( cycles );
" T5 R! W( P2 b7 [/ L6 r+ Q" d        }9 G( Q9 h0 h& d; V  x
        if( exsound_select & 0x08 ) {  G% X7 z3 c; C. i( I
                mmc5.Sync( cycles );
) U1 M! Y5 J4 `( b2 L! G2 m( d        }( `- n& I3 [( p4 Y- W4 Z0 }: S* Y' V
}
: Z7 F) \3 d8 |; k/ ^4 j
4 E4 I! p6 B- p# b- N' U6 {void        APU::WriteProcess( WORD addr, BYTE data )
$ C& _! x8 p! b8 u{' L: k$ A8 k1 }, \0 v! g
        // $4018偼VirtuaNES屌桳億乕僩6 I. g$ o2 @* [9 C; {
        if( addr >= 0x4000 && addr <= 0x401F ) {
- ^* w9 b. S+ O- U$ g                internal.Write( addr, data );
( M# d" c6 I- x8 p  w- f        }
, Z  z1 Q" {, Q7 u3 _' u( G. ]}* X0 w! b. w( I, E5 m
2 @  v) M( z7 j/ E* f. x
void        APU::WriteExProcess( WORD addr, BYTE data )) L/ G3 X; e; A, e. H! t8 j" Y
{; L9 X- L/ q& G8 v- @/ A  B. [
        if( exsound_select & 0x01 ) {" H$ a3 h. S) @! H& e
                vrc6.Write( addr, data );
. g4 E, k3 K. O  `        }7 L$ H8 P3 Z5 r9 F6 G! ~# r
        if( exsound_select & 0x02 ) {, q% M, G7 S" g5 i/ R% r" t8 k
                vrc7.Write( addr, data );, r1 H; r3 r0 n
        }! D8 _5 L/ J3 I; G- G! {
        if( exsound_select & 0x04 ) {: q' v' t% L- a- h
                fds.Write( addr, data );& c. Z( _  {6 A+ Q0 ?
        }1 U6 g/ \7 X! m, I7 W& L
        if( exsound_select & 0x08 ) {
$ _; r. K; i' O6 V5 D; i/ x3 ~$ Z. O( K                mmc5.Write( addr, data );2 D( p1 H2 e$ t9 p6 j4 c& o& M
        }
1 i) S" o* O  z% ^& A8 B        if( exsound_select & 0x10 ) {0 c: P* \* p8 ~/ O7 x
                if( addr == 0x0000 ) {  X0 K# p, j' N# h4 z
                        BYTE        dummy = n106.Read( addr );7 E1 J1 ]( A7 V
                } else {
& p2 D- p! p6 k. G3 y                        n106.Write( addr, data );6 S5 G$ d2 W) L
                }
  v: S" h: `2 J# c3 L        }
# k  q( o1 t8 D: q% c; F! }' L( R0 p        if( exsound_select & 0x20 ) {' E* l, I7 \& d, x! Y
                fme7.Write( addr, data );* x+ D* ?' i. e$ F# t7 ~9 Q' Q( M6 m
        }
3 I- n) L9 Q% f}
- G; s1 e- T! D, E! m5 U
5 G: Y9 b! r' l2 J$ @; p& Tvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
$ h  g  G8 g) u* E{
  d2 J  J" R( k" {( D: @7 G4 oINT        nBits = Config.sound.nBits;
! O  S- {* y' z( ADWORD        dwLength = dwSize / (nBits/8);# A; P4 }8 D: {% B2 T7 h
INT        output;
4 m4 ~6 r% ~5 v. j, D2 EQUEUEDATA q;/ v* S4 S8 q" F5 d* Y5 M: i
DWORD        writetime;
- z/ Z8 g7 k  ~$ V  ?
! A4 O$ R5 o9 P% H' H. `LPSHORT        pSoundBuf = m_SoundBuffer;
% o- g/ r4 }5 b: F' l$ m# d. z$ iINT        nCcount = 0;
  U( S4 X+ u# m* u+ t
9 r/ u& g- W1 I' lINT        nFilterType = Config.sound.nFilterType;2 n/ L! V. T$ T) N0 M  ?# a
: }: k$ e' y$ n* y8 m% e; C  n
        if( !Config.sound.bEnable ) {) I0 I7 H1 d4 U" D, V- u4 j3 y
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
$ q5 t$ {4 a8 l5 X" T                return;3 {7 l/ |) r" A8 G- O) P; M( t
        }/ e( v. k8 |- F8 j1 T/ I# E# w
' W/ f" f! C* j! Z* p& t" k/ a
        // Volume setup5 ]9 p6 q: f# R3 Y
        //  0:Master* N6 t5 w) B# [7 s) S6 @
        //  1:Rectangle 1
- m2 J5 Y5 p4 @5 U! f        //  2:Rectangle 2
/ W9 `7 l' J0 n' q+ G' k0 O, O        //  3:Triangle
7 Q9 e( E& X2 [  S! E        //  4:Noise
' d4 i9 k" Y' f9 O5 E        //  5:DPCM1 A* {( c( ]8 m0 f' @& j
        //  6:VRC6
3 O  M6 `6 P9 t  }0 g- C        //  7:VRC7! m4 \8 y8 M5 s. ~
        //  8:FDS
' s/ e4 }  G; d9 u6 a: J        //  9:MMC5. J& e# K$ I# R. w
        // 10:N106% D% q; d# d: |6 [& @; Q
        // 11:FME7
( d  i* P7 U- W9 ]        INT        vol[24];/ V# c* i/ E+ F9 s1 e
        BOOL*        bMute = m_bMute;+ E' K7 X8 ^- ^1 J/ ]* D- G
        SHORT*        nVolume = Config.sound.nVolume;
8 W/ W( o4 [- W; n
6 P- R' p) D* u& a* ~) s; ]* i        INT        nMasterVolume = bMute[0]?nVolume[0]:0;  W" l: ?$ h* J

$ t% v( m9 ^/ ?        // Internal8 M9 X, C1 u0 H8 W8 \
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;6 w- X2 |7 k5 G9 w9 O
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
$ g! n- i( r  l        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
. @$ t' Y' g5 N) f! B        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;- _; V2 r9 {/ J+ J) y. d# a0 ]' c
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;" h9 }& _3 T: k% I( J

, ~2 F7 \7 }% U        // VRC64 ], P0 ]5 E' D2 [; W
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
0 `7 N, }6 n# l: _. h' C        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
7 ^# m& n2 @. A+ w  @  e        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
2 A2 N# }% Q4 f% |$ M/ u. l8 a3 I# i7 x, J$ O2 d5 m
        // VRC7
+ y0 f2 L. O! G  o        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;% a0 ^: K9 h' M* _

/ f0 P$ N/ M7 }% k' K: j        // FDS8 M, X# l. E( V
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;1 P1 }( J0 C7 G6 u4 X% s

6 G( C, q' _6 m% \$ v; G        // MMC5
+ w  D; a0 `/ M2 K4 R        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;! y+ R* w: C) N, [
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
5 B8 f" N7 ?- @7 p$ C        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;+ n/ K& h1 k4 L& u" Y9 D8 N

  Y- Q" n' R# y9 \  O9 N$ L. g        // N106. H3 b' M8 @5 |* J( H; q
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;1 E) \# M$ G1 a& B' y0 L6 _4 |0 k
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;" p& ]+ Y. y; B# S4 U5 h- H2 R
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
; L' B% y" S2 E/ r9 X        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: s. K8 z6 \, E! ]! ]5 B3 R- J        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;% I* T8 ]* f2 f; @! G9 N3 N2 V
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
# i& s" `/ Z7 C        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;: U" Y* H) f2 J% h
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;* A5 S- P! c9 a1 d- S
, h) i, Q3 Y/ ~# a
        // FME73 M2 a( Y% F# o/ w& q
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
! I1 {7 t  l" T7 F        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
1 p2 D/ _: F0 T+ U/ Z* K/ N9 K) e        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
$ Q: Q2 O1 h( F/ ]# K! V) i1 w
6 o! e% V' y$ i" r//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
) }4 N- y( e7 b+ z+ z        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;& W" J, N' @  H0 n6 U& [) K
, ^) [( k" O- A8 L0 Z/ l
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
9 |& Q! E9 L  s. \8 ?, d* U  U        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
) s/ }! `: |5 Q                QueueFlush();
4 M8 V1 m* M/ y$ k$ E4 k) G. t        }
& ?7 H3 y# D1 r4 h; k# ~1 D! v! V+ L: d4 O% v
        while( dwLength-- ) {
1 o7 ]6 l; G, |7 r+ t, |& T9 n/ Q  g                writetime = (DWORD)elapsed_time;$ W$ e* u" C7 \3 C9 s
5 O) V& Z  j' w% n' ?
                while( GetQueue( writetime, q ) ) {
, x" o3 a6 C3 n                        WriteProcess( q.addr, q.data );1 _7 Y& Y6 R5 Y. j4 y/ p2 b
                }2 D, T! u4 }( e, F* I# p1 p

: M* j4 `9 X* ]! \& E; E                while( GetExQueue( writetime, q ) ) {
4 q& R& v0 S) U" a1 `  j. E                        WriteExProcess( q.addr, q.data );
1 a/ i+ Y' v7 X0 |6 e                }% _3 C/ `: z" A9 E0 O+ t4 D
# l6 i, m3 E% I" }" R
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME72 q: H- }( d% X( {8 y
                output = 0;
  ^7 i; C3 ~' R3 E                output += internal.Process( 0 )*vol[0];
' Q& S' A6 F  E5 ]                output += internal.Process( 1 )*vol[1];' v! b2 v3 d# C
                output += internal.Process( 2 )*vol[2];
/ Q" s' J# z! A9 @) V- g" O                output += internal.Process( 3 )*vol[3];8 u% R; H# d3 ]: n& a
                output += internal.Process( 4 )*vol[4];
) Y) W! @0 ^5 C
* ]* r$ F* C% ]; u; ~2 f                if( exsound_select & 0x01 ) {! n- |' H3 Q) z5 ]! k% n- V
                        output += vrc6.Process( 0 )*vol[5];
3 @) S7 {4 \% Q$ m- D- ~                        output += vrc6.Process( 1 )*vol[6];
6 `( C, y' A4 R, a7 S                        output += vrc6.Process( 2 )*vol[7];
- {1 g1 |* V5 R! h" q# a  I                }
9 H  s% }7 w( M& P6 S) |                if( exsound_select & 0x02 ) {" Z8 r# s$ q3 L
                        output += vrc7.Process( 0 )*vol[8];
  q# f* C9 m1 F; Y% B* C                }
2 J0 U  _1 c- C; r& X' o/ F                if( exsound_select & 0x04 ) {( v( G* A% k; [9 Q, C* E
                        output += fds.Process( 0 )*vol[9];+ ^8 y. d+ Y9 q6 \% I6 u
                }7 v/ k$ P8 {' B  x9 F7 j/ K
                if( exsound_select & 0x08 ) {
: C8 y4 [6 |) B% u0 S                        output += mmc5.Process( 0 )*vol[10];
3 a8 Z; Q( l3 {# E                        output += mmc5.Process( 1 )*vol[11];* T$ E$ V; [6 G; r* E  R
                        output += mmc5.Process( 2 )*vol[12];
) H" h: G4 U* d- y" B  B9 h                }  r: x  y$ E: X0 Y; I3 q
                if( exsound_select & 0x10 ) {+ X  O- T  N  ~) K
                        output += n106.Process( 0 )*vol[13];
; Y7 g3 C1 ]$ r  a                        output += n106.Process( 1 )*vol[14];
$ {3 [& [7 N$ M8 ^- i+ Q2 a/ @, C! V                        output += n106.Process( 2 )*vol[15];5 k' a1 F5 ]9 `4 E5 x6 T1 h
                        output += n106.Process( 3 )*vol[16];1 L0 }7 {) |! R# |
                        output += n106.Process( 4 )*vol[17];
5 ]! _" N3 @' \8 i                        output += n106.Process( 5 )*vol[18];
1 G* \2 S8 X8 y, s                        output += n106.Process( 6 )*vol[19];
3 c3 u9 i$ c+ P" `" [, l; T                        output += n106.Process( 7 )*vol[20];0 Z. R  }) f, p; ~
                }
- I+ z, X& U6 P, D0 c8 N8 o                if( exsound_select & 0x20 ) {3 Z: ?4 p; G; g  i4 }& }  s' P* P" y
                        fme7.Process( 3 );        // Envelope & Noise
4 G  p* M7 _- E5 r; y                        output += fme7.Process( 0 )*vol[21];8 [5 c$ i/ n( E9 I
                        output += fme7.Process( 1 )*vol[22];4 k) `% k) t. x) C7 \! w3 U
                        output += fme7.Process( 2 )*vol[23];
( p0 Q4 s8 \; x# L* L6 g% f+ f                }4 m; M1 D' P& @/ M) t" H) w% G7 w

; {, Y3 I4 w3 a9 u* I/ m9 l1 |' w                output >>= 8;
! c8 p$ U- [. _$ s# O; m$ U
& _" N. D" D6 |! v6 I                if( nFilterType == 1 ) {/ n& V' u9 |2 q1 ]1 B4 p$ {% I* W
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
  D+ C/ u) o& \% P                        output = (lowpass_filter[0]+output)/2;
/ L; I# I( C8 s, W8 F, n- B1 M                        lowpass_filter[0] = output;
! }3 M3 l$ T+ V5 s, K                } else if( nFilterType == 2 ) {
8 P8 Y: \# I0 @+ Q, s# [9 T7 d                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
* n6 }5 _' b) S" H2 W5 R                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
, z) v  G' Z$ h- e0 S5 m! u                        lowpass_filter[1] = lowpass_filter[0];
2 M& h+ l" E" M6 W5 m7 |: D; m                        lowpass_filter[0] = output;
: s: L7 j2 @+ x: ]                } else if( nFilterType == 3 ) {0 ^0 d) z  V; u* Y; f7 [* T
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
; K8 f( n) l; |3 j5 a0 M3 D$ Y; N  D                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
3 _& O' n8 B0 a' i                        lowpass_filter[2] = lowpass_filter[1];
8 t, Z! z9 Y* |) }. R                        lowpass_filter[1] = lowpass_filter[0];
+ z3 g* y# h! ?' {; k, q9 ~                        lowpass_filter[0] = output;% I6 L; d5 ?2 U& A
                } else if( nFilterType == 4 ) {$ b$ |1 I! D, r0 Y6 d4 `" E
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)# f+ f0 d3 Z! w* J
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
( o: r" |0 X/ ?, j- r5 C3 A6 V) o                        lowpass_filter[1] = lowpass_filter[0];* e8 W! H: h& |8 b) O- I
                        lowpass_filter[0] = output;3 x3 R' |7 p% [' T
                }- V, m/ O4 Y8 t8 j

! N2 |3 l  e2 l/ u#if        07 _- Z  Q! _' z) q( p& w6 Y
                // DC惉暘偺僇僢僩
( b* A0 B; o" a* b+ |* K3 ]                {9 ^* m; F$ `* k' v% `
                static double ave = 0.0, max=0.0, min=0.0;
9 |% b" e/ d( C; C- ^6 Q                double delta;0 t, J: S3 h% c! b  Q7 z
                delta = (max-min)/32768.0;
4 a8 b/ H# i' f3 p; f8 @  u                max -= delta;
3 W! y( ^( ~* h; ^" C                min += delta;/ d* h" A2 f/ r5 @
                if( output > max ) max = output;$ m/ o' J' W( b1 _
                if( output < min ) min = output;+ N# {+ a8 ^0 o+ H6 S
                ave -= ave/1024.0;8 Q; |9 k4 o* X# ]7 H
                ave += (max+min)/2048.0;2 K, N' t7 v% Z0 b- b
                output -= (INT)ave;
" W" C( F0 n8 f6 A; b0 `. g# q                }
7 ?* ]: ^+ L* G" y6 g! p% E#endif; C" x+ j7 R& {: }# q/ U" S  q* A
#if        1
. J) `8 j) H/ e; B                // DC惉暘偺僇僢僩(HPF TEST)% U* P$ m( B+ a  C# s5 G# N
                {% l8 z) D% P' t& m+ }5 F1 |" P
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
4 }& L2 {# Q" b                static        double        cutofftemp = (2.0*3.141592653579*40.0);0 c; |- B6 i  O6 t0 [# M4 V* j
                double        cutoff = cutofftemp/(double)Config.sound.nRate;4 {# t7 v9 ~: E! ?
                static        double        tmp = 0.0;
; N! H6 S: B3 v3 R: J  s) g                double        in, out;
/ c, |* p/ Q2 v( ~$ \1 _# g: ?! u% q& j7 o( Y5 T6 j$ y  P
                in = (double)output;: V  y' d' f4 N+ n/ I) Y7 W
                out = (in - tmp);
; o& L* F. U0 I7 L  }# Q                tmp = tmp + cutoff * out;" @5 ]* C5 x' }; r" J

3 P8 @, s; w% }0 n- n+ m& O                output = (INT)out;+ m9 T  y  Y: q9 O3 G0 U+ d
                }1 T2 m' P2 |$ A* Q* f
#endif
* C, z7 U8 R: l. Z#if        0
! ]- k. J) o+ i1 v$ m                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
% [8 a7 G( f* s3 T                {7 H3 R" W# u" D
                INT        diff = abs(output-last_data);
- Q3 b! a' G4 Q/ f+ W4 h6 L  G2 W                if( diff > 0x4000 ) {) ~$ Q2 Q$ U5 v) N2 j) `! J7 R
                        output /= 4;0 V0 F/ p0 m1 W' }! C/ X) E
                } else
7 q3 w2 e1 _5 z. U% S% d                if( diff > 0x3000 ) {! w$ Q/ C, M8 I9 ^( S$ ?
                        output /= 3;
$ ?2 @) v0 P  t% g  F( h$ f                } else
; r1 k' ~3 i/ [" m/ w2 J                if( diff > 0x2000 ) {) m" j5 c: ~9 P9 U4 u! d- C
                        output /= 2;
# z. Z9 Z3 ]( Q) I, l. O                }% `, u$ X9 m; N4 Z
                last_data = output;
) P0 \) I/ Z8 v8 J# Z  J                }- H5 c6 V% c! [/ o5 |
#endif1 i  [8 r+ X" z7 m
                // Limit
. T% \$ o$ K8 m  ]$ N0 L                if( output > 0x7FFF ) {6 D& D2 A. U' C0 @
                        output = 0x7FFF;
+ s1 w/ Z, Y  ?) r* B( d8 p                } else if( output < -0x8000 ) {
  M8 p4 k7 A' H2 a3 R7 ]/ k, L! a                        output = -0x8000;
. V4 H5 `! d4 ^                }. q! i: B9 x4 t) T" `

9 f$ }, U- T: S0 F9 v                if( nBits != 8 ) {
& y1 p: g5 f( D' Y                        *(SHORT*)lpBuffer = (SHORT)output;/ K0 Q2 v% y- s  q) C
                        lpBuffer += sizeof(SHORT);
* n& g$ |. e& p9 z                } else {
$ O( p2 M  i) G$ G4 ~                        *lpBuffer++ = (output>>8)^0x80;
7 {/ M5 s" W7 s, }                }/ I# M/ t+ ~- }& j5 o+ J( H
" Y$ H  J& T- y4 L& q& N. @2 i
                if( nCcount < 0x0100 )
* Q% D7 d2 o' n" ~: u" I/ }                        pSoundBuf[nCcount++] = (SHORT)output;# M0 k, v" A- F$ \+ o
; x6 x' A+ C* ~% c. }- g
//                elapsedtime += cycle_rate;6 ~6 c8 T2 @* q: e7 H' @
                elapsed_time += cycle_rate;
& n: l4 O4 z5 R& J        }
1 ?5 Y$ _/ _. h" v4 |! I7 G5 P
* f8 }7 j/ B) a" n: _; E$ D" H#if        10 `, I) B4 ^1 s  y' B7 L
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {" f' v% a; g; h  O: g6 \5 ^9 ^
                elapsed_time = nes->cpu->GetTotalCycles();
* G; C  @  f: ]8 h4 ^4 U7 ~        }
6 K$ I2 ^( M! r3 n* q; Q- }% W        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
0 l, T( f* w) Z' {$ b: k                elapsed_time = nes->cpu->GetTotalCycles();
. _) C$ l; |: S9 j4 V( O2 x! E- F: n        }
( }! |+ Q7 \& [#else/ g7 O" E5 b5 J! ?5 y
        elapsed_time = nes->cpu->GetTotalCycles();- S  }% a/ i, I9 i: d! y$ ]
#endif- z: }5 Y) o+ ~2 d# c" g
}- h+ Z% i* H% b0 `

% L" j) H0 {2 p6 d6 [! i// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
: p+ Z  d0 ?3 x1 Y: Y. FINT        APU::GetChannelFrequency( INT no )
7 X4 d! B. ?( v0 D) Y: E. X4 T{
: I4 m6 B9 a# O7 S9 L        if( !m_bMute[0] )0 L9 S6 X; o( e& v  V7 r
                return        0;8 @" I" c! F% z2 l, W6 Q

& T$ R+ N* F( [" {        // Internal* X1 \) @5 D' s% {8 L
        if( no < 5 ) {
! e* y- p0 p5 n6 b' T( Z7 ~( b                return        m_bMute[no+1]?internal.GetFreq( no ):0;
- X: ?+ G% d! |4 H        }+ ?5 M* C0 Y; _8 `# ~
        // VRC61 V! m4 S* X. I. b7 t
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
# U0 C0 q# V* c9 ?                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
5 K, b( A( h# J, D        }" N+ _% m% T/ c) _' P
        // FDS
0 U8 g( w( j) Q; x$ s        if( (exsound_select & 0x04) && no == 0x300 ) {0 O  ]0 O7 `+ o/ W' d
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
! s* Q9 r: r" f7 \0 ?, g7 P7 [        }5 E, n$ \$ l% D+ _& l
        // MMC5/ ^; \% i2 F' I+ \- ?+ N
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
$ B5 \0 x+ [; |/ s9 c; e                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
9 B6 O0 K2 z/ D" T( p, B. R        }
. F5 r% ?! o% y3 y4 Z6 |, `- X( G        // N1061 R/ \, D% A$ ^; x, ?
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {3 `/ ^$ D: \# [
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;: y# ^: x- [4 W) M. L1 ?/ A, `5 }
        }
3 i* ~1 ]! m5 @$ z        // FME7! v/ |: S$ m8 U( t; w- ?9 M1 H
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {6 a# L) K. }6 t$ _9 i
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
: B+ D6 e. ]( g        }' X/ b! ~, i1 y* T7 X7 ^$ \" r
        // VRC79 Q1 f  s' [8 a3 \; N0 }; s; ]6 V
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {! L! t7 i1 I+ ^1 ?
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
# M$ N. i+ F; G1 o# Y        }- J1 Q- h( X- t) P, S6 O' F
        return        0;
4 E* z. J+ ]& q8 \}
0 B7 Z" ?6 }1 K: w& m1 m) t
1 G) [" L) C( [! b) h// State Save/Load! A4 ?8 U; y: |; B& l8 u
void        APU::SaveState( LPBYTE p )
2 F" y4 U6 T% n- ]; P{
& Y7 K  y! n8 l' \: r#ifdef        _DEBUG
6 b; e2 d% O6 [% h" VLPBYTE        pold = p;
5 d% X7 p( `2 K4 v5 `" O$ ~& j#endif( \5 h& [8 n! y* S
5 V& Q7 {& w* k2 ^& ^9 @
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
3 L  }3 V' [/ |, }; c7 G  _        QueueFlush();
2 }* r% d' t6 G0 k& H
$ Q; D3 ^$ h( @: F! }" I        internal.SaveState( p );
6 F6 ^, H2 ~( t        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
: U' X, L/ ~- Q' X: [3 [/ t
- g7 N$ b: m+ ~  L. P. R/ ]        // VRC6! i) @9 K& \! B4 s
        if( exsound_select & 0x01 ) {, F7 ]1 o# l# o
                vrc6.SaveState( p );
1 k: O6 c- b' K. u2 P                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
/ {! `9 }+ e- }- ~* j: W: x        }% e4 l: y$ q  ^6 I  a8 N
        // VRC7 (not support)
4 Z7 z: Q9 [; b& ]. l# W  k        if( exsound_select & 0x02 ) {* q- ^8 _" t+ t5 c+ I6 O6 B
                vrc7.SaveState( p );
' x: s( N$ k( Y; d; W  O                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
$ G# ?* Q% ]) r' \- M$ q& H        }
, x8 E! {* Q1 U. Z9 J+ G9 v+ X+ V        // FDS" O: o2 O5 z5 d& r8 c
        if( exsound_select & 0x04 ) {3 C7 w. ^* k1 N( ]5 a
                fds.SaveState( p );. w& ?2 ?# I6 R  N! ]
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding) p+ b% y2 P* u8 L4 n
        }
% ?0 H" v9 L( `) Y7 n        // MMC5* F, J; {* J# M" I( q
        if( exsound_select & 0x08 ) {
: n" b& H7 ?* }' Q6 A  ?0 H, y                mmc5.SaveState( p );
+ M' g2 a) M5 p                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
3 l% ]. u& a6 t# z; e. X        }
; m- T1 b+ T' g7 ]9 Q        // N106* A9 I1 v4 A9 T% ]8 r. W
        if( exsound_select & 0x10 ) {
' H0 @/ L( F$ n* Q                n106.SaveState( p );8 e' L2 i" j' _. s" \. Z
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
) b# Z6 Z  X6 K" B/ W1 [        }
3 b1 e0 |. `/ u7 C        // FME7
5 v' }; K6 o) E; }        if( exsound_select & 0x20 ) {+ F' _3 `  T! f; A8 u0 W/ ~! ~. c
                fme7.SaveState( p );$ @  Q% B- F% {, o- T5 c8 o9 O8 i
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding( R, S$ h$ a# _: f/ \
        }
' z( W# g( `7 M5 k6 @, K( g1 G8 V( k2 _
#ifdef        _DEBUG
. i2 ^$ |) G' V% g3 F( k+ b/ B; T- _DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
) ]# T3 i  i5 }#endif
. ?  V2 G; V) R7 w/ X}& Q; x6 `; N1 f4 x+ q, l$ l" j( X
' R: P: Y( G1 n) K9 d
void        APU::LoadState( LPBYTE p )
! R# \3 S1 m2 ~3 H. k+ W- D8 y{
  R# h9 q! ^6 \" ]4 c        // 帪娫幉傪摨婜偝偣傞堊偵徚偡* `" T0 u+ [1 i' Z' ?- v, F* I$ X
        QueueClear();
  }1 d4 d+ z/ N/ n& I% e8 q
2 N+ j5 s; C  P8 \        internal.LoadState( p );( Q6 P0 E) l: e# n# w/ N
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
9 d/ b1 l, i3 V; Q6 a  h# z# N. W$ s3 a
# P0 N( y% n+ g! M- W: j        // VRC6, i- a, [! P+ e' r
        if( exsound_select & 0x01 ) {
* a2 B! O0 t9 F- K                vrc6.LoadState( p );
  O: G7 a8 S( m( _4 M, i! i                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding: H2 O" `" P4 t9 v5 H
        }0 q, y. M) \- U+ d4 R
        // VRC7 (not support)
0 ]: r) S2 V/ r9 y# n# p% Y7 x3 i3 p        if( exsound_select & 0x02 ) {
5 F- W( d2 J( ~+ [6 _; \                vrc7.LoadState( p );
( X% B/ u8 P! B7 |0 j3 a                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
, \3 A  g; d. J; r        }
" u' V# {6 Z' L        // FDS" P, S8 Y' w2 X) U: b6 }+ W( w
        if( exsound_select & 0x04 ) {
1 \* f( @- _$ p0 ]; V& {. y                fds.LoadState( p );) u9 I: ?. R3 C5 O) a! l
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
0 @5 i' c* R% t* ~% G        }
9 _6 I2 s$ Q0 b  i5 _        // MMC5( n# c4 D) C5 W3 O+ w% v
        if( exsound_select & 0x08 ) {
  Z9 G- F9 k! H3 C8 R* Z$ w% z                mmc5.LoadState( p );
0 U# c1 j0 I* s4 E! V2 N                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding. V* R4 T" p& [/ m. R, ]
        }1 e( Y; e2 p+ P' J5 H
        // N106
7 _, D' v6 k" f( T/ I1 u$ K8 u! J        if( exsound_select & 0x10 ) {  D# O4 [0 S  x# x5 y
                n106.LoadState( p );
5 _# X7 n' p5 A* u# Y5 ~7 H0 s                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding7 O0 L8 S5 R2 B* c6 e" a3 q  N3 U
        }
( V, [$ t6 }4 V8 w  Q        // FME7! }4 B  Y; U2 N2 h
        if( exsound_select & 0x20 ) {" j0 ~/ d- u: P' t
                fme7.LoadState( p );
$ Y5 y+ V9 T2 g" y+ s                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
, m+ j2 R8 O! r  ]/ o) y        }
! h% m' e- `& b. Q8 r}
回复

使用道具 举报

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 0 t4 B, C: g8 _0 @; S
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。0 b( X: }5 |3 v  a# v" D' l3 D
感激不尽~~
4 ~! M9 ~' n# u" `
恩 我對模擬器不是很有研究,
6 _' n; b0 P+ o9 S$ a2 W' ^雖然要了解源碼內容,可能不是很困難,* [0 U8 f  j+ J3 X
不過還是要花時間,個人目前蠻忙碌的。
* _. j; v( Y+ U
$ S+ t" I2 P9 j- ~  a0 c7 s9 \" W給你一個朋友的MSN,你可以跟他討論看看,/ j+ ]. S5 e9 d  i8 U* `! p
他本身是程式設計師,也對FC模擬器很有興趣。
! x8 W: ^- s7 A
1 [0 W, S, K9 R0 J1 F0 M1 }MSN我就PM到你的信箱了。
+ }" d% B; k3 _% @3 t( h) u% M8 c. b/ f5 C7 y2 v
希望你能有所得。
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

签到天数: 82 天

[LV.6]常住居民II

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

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表
6 E/ v% ^7 o8 Y呵…… 谢过团长大人~~
, i1 r! d6 `1 c$ |2 W" ^7 i$ a; C( n
# N# Y$ F. H6 |: k
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 " v! d' D7 t  `1 a
团长的朋友都是神,那团长就是神的boss。

$ X0 Y& r  d9 \' @哈 不敢當,我只是個平凡人,
  f) \7 O6 c* u3 N" `9 i要吃飯喝水,光吸空氣是不會飽的。。。。 :)
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
4 X1 X0 d! l7 u1 m- eZYH
9 G9 x, s  t, z* wQQ:414734306
3 p7 Z9 `2 y7 Q0 r: l: EMail:zyh-01@126.com* D2 Z3 y% e. {' G) w# u4 K3 H
. t+ ?! @( L/ R9 b+ i
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
' T' l7 M5 U$ |' m  _2 t再次对团长大人和悠悠哥的无私帮助表示感谢~~
( O( ]1 p5 p, g0 t" v9 {7 v4 Z, a3 t
不客氣  ^_^
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-6-6 01:47

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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