EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。. T% W. L7 I) p, E/ ~/ f( {" B
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~: N  }# M: V  d' b6 G$ B- G* I
这里有相应的模拟器源码,就当送给大侠了~~, q3 z3 j( |7 u& W& K) a; s
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 ; u$ _0 U6 T  ]9 @# L
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。0 P* L, H: Z8 e1 y5 b
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
7 k( S6 a  R  ^* g. W6 M这里有相应的模拟器源码,就当送给大侠 ...

) G( _7 a! o1 r聲音部分(Audoi Process Unit = APU):) D/ S* Q! x1 J8 t, Y5 [
.\NES\APU.cpp
8 h5 @3 `8 Z* |6 o$ @+ W0 A.\NES\APU.h
: Q' {' E8 ?4 e3 F, O- Q6 Y+ Q" Z) Y) A: k

2 H* S/ P, R( p( D5 W/ f影像處理部份(Picture Processing Unit = PPU):/ W; ?9 j' s) k% }+ {# N
.\NES\PPU.cpp
! r5 S7 W+ [. [3 [$ I( U' z.\NES\PPU.h& [! c7 V8 a7 W7 U! `
8 \/ |2 j8 {# m2 _% a
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
, a$ W% b8 m) {8 y4 `; c(由于很多专用术语和算法机理都不明白,所以看不大懂……)8 S1 C; E0 j, y2 y! A9 R
//////////////////////////////////////////////////////////////////////////
/ V2 ?  m7 D) l* I" x//                                                                      //4 ?+ C) f* Y  D. s7 s/ m  s
//      NES APU core                                                    //
; C7 k6 |7 C$ a7 ]//                                                           Norix      //! b' t  i+ @! w0 ?: ~
//                                               written     2002/06/27 //
5 M# ]/ u) I4 f% }- }5 \- B4 b- `//                                               last modify ----/--/-- //
! O0 A1 a6 z- G: w' m2 M$ F% _//////////////////////////////////////////////////////////////////////////: r5 s/ y4 ?8 B3 V
#include "DebugOut.h"! y7 v' C; r# Y% R* S3 k8 A' n
#include "App.h"
0 J+ c  |- m8 ^: B! ?- U2 V#include "Config.h"0 C# Z( D( a" {: D

# ]. V6 d- ^# O" v) R5 k#include "nes.h"
: z: ]2 R7 g. c# ~$ H4 `1 x8 N#include "mmu.h"
) ]& O% L- q: c( G4 \0 n- q4 `#include "cpu.h"
6 s, f: q) z2 |, D  V* W! D#include "ppu.h"+ T5 W% h0 l) Z5 T% r0 Q
#include "rom.h"
/ y+ e+ M8 N: X( R4 n' A#include "apu.h"
& a8 p* p! g  b! {/ A- D: F/ {  m% U; l( n$ e$ V; S
// Volume adjust! n& k. a2 }# J; C6 s
// Internal sounds
. I# w, a2 z. [% a% w( I& q#define        RECTANGLE_VOL        (0x0F0)
5 `3 l9 `: |1 j1 ]#define        TRIANGLE_VOL        (0x130)
8 l! f, i; R  t0 [* L1 `  j) m#define        NOISE_VOL        (0x0C0)
4 P/ F- {1 n7 p* N#define        DPCM_VOL        (0x0F0)
8 i* u- `5 f6 p" W) S// Extra sounds
9 t( _9 U: {! s$ l! M" a9 [#define        VRC6_VOL        (0x0F0)
$ Z, K+ j0 F( a9 {#define        VRC7_VOL        (0x130)
# c' C# p8 Q6 \( t#define        FDS_VOL                (0x0F0)
- Z8 \  v/ u2 B$ _8 p: W$ ^#define        MMC5_VOL        (0x0F0)
- V7 J" s& C$ Q  Q% S5 L; K#define        N106_VOL        (0x088)
( z% Q* `% L/ _  j#define        FME7_VOL        (0x130)9 u3 h7 J( i! H+ z
) X# E' D4 Y* n4 x
APU::APU( NES* parent )
% N( b8 a. h1 K+ p" `2 j{
0 S3 d0 u0 \, ~: ^8 H) }" O7 w        exsound_select = 0;% K1 R) J6 d  j. x6 O

0 L% t9 ^* P1 @6 N2 i; A        nes = parent;
! q1 V  ^7 f! @1 y        internal.SetParent( parent );+ \, j( Y! _3 z  w9 k
& L+ J) e4 @* j: ~* }
        last_data = last_diff = 0;$ v: R8 B5 w. a0 _) E
* `' q" X, K$ i
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );' i* G, U1 [7 C% ^. t
% r0 p& h, g7 y2 f3 a( ?/ C2 _
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );6 |" y5 n4 ]/ X6 u) ?6 }7 \5 l2 x
        ZEROMEMORY( &queue, sizeof(queue) );- u% N4 A6 u3 C5 Z; J: L  v; r) h
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
* A' i0 e. T: B* _% K3 b) E3 \6 |  t: E0 A7 q
        for( INT i = 0; i < 16; i++ ) {
7 g2 e1 j# q, Q% W! b                m_bMute = TRUE;
4 q& T; h0 P2 _1 t: Q& c+ Z        }2 C; k$ G1 D6 O5 {4 C
}
  X0 F: z" J$ e) C8 r4 A+ M4 y' e1 W, i3 d7 S& U; {$ r4 F
APU::~APU()8 e" p% k) ?& l" e; w, m
{
; C% E1 ]. G' c/ v9 V}, S) a. k% z) U' Y
9 S# C& Q; U' R1 a2 W5 Q& Z
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
. ~8 W! ?: ]- ?- h7 x# K{
, h- v7 O2 x$ S        queue.data[queue.wrptr].time = writetime;1 ^  M9 U! E: u3 f' |8 e
        queue.data[queue.wrptr].addr = addr;
9 j$ z2 |; L! W% u' J# X8 i: i7 q        queue.data[queue.wrptr].data = data;# O; S! a$ t4 ^0 }3 U
        queue.wrptr++;
2 r# J7 ]0 v* O) J( a        queue.wrptr&=QUEUE_LENGTH-1;" i. e5 J- K- C" c8 E- o9 y- r/ u
        if( queue.wrptr == queue.rdptr ) {
$ v6 \; }4 u4 O, f1 k- r                DEBUGOUT( "queue overflow.\n" );# Q7 N5 T" ~8 f* M
        }
7 A+ A: s% ^9 n' }3 A& Y, ?}8 R8 V# s7 T' l
- ^8 ^% {8 I) z
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )/ Q5 Y, m7 ~. u' D# n
{
# ~. T9 M6 r  c( P/ n        if( queue.wrptr == queue.rdptr ) {
6 r. i; a; A7 `5 Y! f9 J                return        FALSE;
9 N; Q% q- D8 ]& h% a9 n7 @( E        }, z- J7 o$ u# M; `8 L
        if( queue.data[queue.rdptr].time <= writetime ) {! _! G( C( r' f  a! X
                ret = queue.data[queue.rdptr];
+ E/ q3 D6 d. b! L# h                queue.rdptr++;3 n* r( N2 H$ i6 A% A4 c7 ~
                queue.rdptr&=QUEUE_LENGTH-1;, d9 c: O* q: z3 {9 h" ^
                return        TRUE;1 ~6 P& I/ E8 J- ^
        }
) ?& Y: L" b: e+ T        return        FALSE;
3 K' t, I$ P' _4 M}
- i0 C' P. V4 z" o) p0 D0 Z# M% b3 x! ]" L7 s; G
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
$ L7 A; \& a! J% H  J{6 j5 u7 Z$ ^# _
        exqueue.data[exqueue.wrptr].time = writetime;* g  Y+ G5 X, s" W) O
        exqueue.data[exqueue.wrptr].addr = addr;
) r3 q4 A" n9 d( Y  Z  W        exqueue.data[exqueue.wrptr].data = data;
! b& A  N" f1 ~- S  ~  c        exqueue.wrptr++;2 a# i" v0 }, }  {3 ~2 P
        exqueue.wrptr&=QUEUE_LENGTH-1;
& b+ b0 }. M# v( q5 L9 M% T        if( exqueue.wrptr == exqueue.rdptr ) {4 R( W0 V$ _" Q" P
                DEBUGOUT( "exqueue overflow.\n" );" i$ V9 G, K- r
        }
' T% R; O# x1 T% y2 u% C}
& w8 |2 [6 e3 y" }/ _2 B
* `# O" I5 b7 a" e) X' dBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
8 ?; r  f1 l4 E! o$ }{
" T/ r3 K  X2 o% K* ]1 D        if( exqueue.wrptr == exqueue.rdptr ) {* V  R& D9 {: P/ Z
                return        FALSE;9 t1 m1 W% |" H# A( Q8 A' l5 U: b# J
        }
2 }6 m2 G6 T2 N# r+ |        if( exqueue.data[exqueue.rdptr].time <= writetime ) {" ~( K( e+ e6 H. Y
                ret = exqueue.data[exqueue.rdptr];
8 x4 _6 ^$ U# @/ k- S* U; p$ w  ~6 H2 b                exqueue.rdptr++;
+ P. G: v# N+ J                exqueue.rdptr&=QUEUE_LENGTH-1;1 @1 v: B2 o4 W
                return        TRUE;
" e$ T, l, M4 Y1 R0 R        }
% ~7 K" x4 I/ B9 V" i        return        FALSE;8 n; H0 I/ \" {5 V* o
}
2 z4 E' E# c. y3 \2 l" Q% `: \6 a: n$ P1 j: T; c
void        APU::QueueClear()
* K6 O. j* ?) A% ^  B; q+ z& Q& x{5 O, \! D1 [) R) s- d
        ZEROMEMORY( &queue, sizeof(queue) );
! q1 S8 Z* M& X  r, B3 B) N1 u. U$ O        ZEROMEMORY( &exqueue, sizeof(exqueue) );
) M4 L  Q& R* A; s1 d8 B) [5 B% q; Z}. a) e  l2 c& G$ T6 h5 y4 ^7 r

. t1 f( u5 E  e- a4 b, \void        APU::QueueFlush()
/ H/ P) l8 R1 Z+ I: r{
/ U2 Z, L; J5 X. A( n/ ^. S        while( queue.wrptr != queue.rdptr ) {8 H: ?2 w% c6 l$ }/ g, T6 f
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );/ _! |6 F6 p* M2 F. w" X
                queue.rdptr++;
2 ^4 U2 {6 d# u/ g                queue.rdptr&=QUEUE_LENGTH-1;: r  E. J5 S/ f9 {0 c: j/ t
        }, v# v' h/ D0 {& a7 h. @

1 Q; R) G6 _) y7 Z+ g1 h0 f: Q7 D        while( exqueue.wrptr != exqueue.rdptr ) {
) ^+ L3 @+ `( |; ^3 @& \8 Y                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
4 v9 O1 v" M; e' l0 R                exqueue.rdptr++;
! p4 `  x7 h; Z/ Z9 F                exqueue.rdptr&=QUEUE_LENGTH-1;
: b0 t7 b8 [6 H, _. E        }3 i" l' F! C) ?* v- X
}
" W8 x% x9 L! D, H! z7 O
' U9 v) i2 `, Svoid        APU::SoundSetup()6 S  F; m% d' V* c
{
6 U- t* B/ Q/ u        FLOAT        fClock = nes->nescfg->CpuClock;
2 b3 I2 |7 X: @3 O) X2 Y4 W5 {        INT        nRate = (INT)Config.sound.nRate;
  v/ |7 `* g% y6 U        internal.Setup( fClock, nRate );5 c& P+ ~* |8 z' m. l
        vrc6.Setup( fClock, nRate );
( ?3 p# j6 R9 \2 I& v+ j' |        vrc7.Setup( fClock, nRate );( C! j+ d# A4 S6 y7 t" |$ F: q
        mmc5.Setup( fClock, nRate );2 n) e- U0 ]; |+ J
        fds.Setup ( fClock, nRate );- e9 }0 k5 y, K, D; q% o6 n! Q: K
        n106.Setup( fClock, nRate );# d! E; Y9 }9 A2 U3 l
        fme7.Setup( fClock, nRate );2 E# c8 c# s2 P% Z/ B6 [" ~
}
- y& d# Z9 Z* F* s
& p# }7 ?& J% S7 y; N" @2 a" d' Tvoid        APU::Reset()
! p' l( N4 N  ]5 ^' i2 E5 [& t{
* p! C7 J+ q/ q$ e; f" G6 L0 D        ZEROMEMORY( &queue, sizeof(queue) );
5 G0 o- w/ I& s% h' G        ZEROMEMORY( &exqueue, sizeof(exqueue) );- ~- B, o' t! j2 N9 \( [

( @$ Q  |1 J) r# w        elapsed_time = 0;
5 v" o0 d% |8 i: l! c/ F+ I0 p) Y- D2 z+ D$ o! R4 \
        FLOAT        fClock = nes->nescfg->CpuClock;4 \/ D* d) H5 v- K9 V6 s# ~7 b
        INT        nRate = (INT)Config.sound.nRate;, k' _7 _: \9 L$ [; o
        internal.Reset( fClock, nRate );) `* n7 j0 A! U" K' w% ?: I
        vrc6.Reset( fClock, nRate );7 e0 s5 J; r& }! }1 K) }
        vrc7.Reset( fClock, nRate );
4 V6 O6 Q9 x. ^        mmc5.Reset( fClock, nRate );7 R- M' [9 C) N2 ]
        fds.Reset ( fClock, nRate );
# X4 x% T4 r# o& U, J1 ]( ?: G        n106.Reset( fClock, nRate );# A& ^' e. q  x9 b1 S
        fme7.Reset( fClock, nRate );; S& a7 m! I. s+ X
! f! K4 A, a1 r! I2 K- |9 d6 H
        SoundSetup();
3 f7 c. `% N( q3 N; t}9 D- a5 G2 W& v, v7 g( z

6 l4 u8 M; u( q8 e5 P- Vvoid        APU::SelectExSound( BYTE data )! U% e2 ]& @9 ]: H& {% I
{
( H5 h# I" C) X0 @' h        exsound_select = data;
0 A# W8 ~) k! l2 \3 n  i}
; h3 e' ?6 x/ }& [" G' j: [( t0 E9 P
BYTE        APU::Read( WORD addr )
8 h: C+ x% D" q+ _{
- f& Q0 F7 S; d* G1 M8 f- P, p        return        internal.SyncRead( addr );: R* G* r0 V8 n! k
}
: `( j) U1 x; i# O
6 Z* Q" Q+ ^! z, J+ Y3 S8 u4 Nvoid        APU::Write( WORD addr, BYTE data )$ o7 [$ K9 G0 F& m2 [2 t$ g
{
& y* l, ^+ {( L1 W        // $4018偼VirtuaNES屌桳億乕僩
( d$ T: _  O6 m5 S        if( addr >= 0x4000 && addr <= 0x401F ) {' b! n5 \/ K+ ?* e  L
                internal.SyncWrite( addr, data );
7 k3 C) h8 R) M* \- ~                SetQueue( nes->cpu->GetTotalCycles(), addr, data );/ M; ]& }3 Y$ w
        }4 Q4 p8 j0 J0 n
}5 @" }  o( c8 Y1 {1 u
  Q3 M: K  P7 \- \4 A) l2 o; X9 k
BYTE        APU::ExRead( WORD addr )# J7 b0 v4 o: X' {# N
{
6 g! w4 B  t1 g" ZBYTE        data = 0;4 R0 D+ E  U& y: |+ u

1 _/ w/ t, w. P/ |        if( exsound_select & 0x10 ) {
, W8 j9 z4 {/ a# |                if( addr == 0x4800 ) {- Z8 L4 J6 |/ K3 ?7 t% s0 n4 n  U
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
0 c# x$ m3 G* f# x8 I                }* k; @  J% Q1 L  G$ Z( M4 [5 m
        }" v9 a* Q* V  `
        if( exsound_select & 0x04 ) {: t8 j3 a3 L. [/ U3 G0 t
                if( addr >= 0x4040 && addr < 0x4100 ) {1 ]0 p( b/ ]  O: g# H
                        data = fds.SyncRead( addr );# W6 s. C" I9 a! Q' u0 }
                }/ Z! P. V; H% F
        }
% K4 ]/ S, v+ `& U        if( exsound_select & 0x08 ) {
! C7 I. p3 W0 X                if( addr >= 0x5000 && addr <= 0x5015 ) {
. {4 k0 d$ ]9 x; o! P                        data = mmc5.SyncRead( addr );
1 |, a" y/ x- u                }
1 t$ ?: u$ N, f! a) [0 y        }$ i9 e2 h  z: [2 o; F# I" y/ X2 y

. v3 F/ H" {& p6 a        return        data;- ?8 e8 w! T8 |/ e
}0 l" t0 N6 }: g7 e2 W

# F2 h; O9 p/ qvoid        APU::ExWrite( WORD addr, BYTE data )( H* I* S2 E) G0 O- N
{
! b0 r! q8 Q' O. F' _        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );& \6 z+ w( M4 {: q: ~! [
& r: p  W* m7 E5 G
        if( exsound_select & 0x04 ) {
3 v* o+ |. C. i# @                if( addr >= 0x4040 && addr < 0x4100 ) {: o/ ]" Y/ W: e' X5 i7 }; o
                        fds.SyncWrite( addr, data );
, L0 I' ^6 ^. n* q  [! l. Q; r                }
0 W" d) R' U; F3 Z5 D        }
$ g5 A* m9 E4 T# [4 p6 G7 p% k. ^8 m( x  |, s, J' a
        if( exsound_select & 0x08 ) {
, M0 ~5 X/ s' @& Y                if( addr >= 0x5000 && addr <= 0x5015 ) {
# `" |, V3 w( n                        mmc5.SyncWrite( addr, data );
- K4 B% c; g- u0 G" z6 Z                }
  R$ N+ D# o. |' g) M. P        }
0 S: o! S0 P+ ?  {8 I}
$ E. L# k7 L  f+ [! t- V1 x, j' l) l5 `
void        APU::Sync()0 B! J5 b* j; O& F9 ?4 `' V
{1 K: \( K* n. h
}
- s; y) _7 p+ {% ^9 A5 o& |" t) a6 |$ q; A" ~1 V( v
void        APU::SyncDPCM( INT cycles )8 J+ B" n3 Z% K% V
{/ J! a6 G& S; K- o7 t
        internal.Sync( cycles );
/ c+ q% k! v# j( S6 b0 N7 l0 w- a, Z0 v# W  N
        if( exsound_select & 0x04 ) {
$ a0 ~% D+ `# x                fds.Sync( cycles );
* n/ z5 U5 i8 ?" b- J        }
( K6 ]' X2 R# m! k1 c; I' B- P2 k        if( exsound_select & 0x08 ) {
& H- h, M, g# |$ B) E                mmc5.Sync( cycles );
7 k$ K4 `- }: [& u! r2 d% s+ \        }* F" n/ l7 ?* [- |3 |
}+ o: f) n, M# g8 d, c
# I8 c3 X( H/ ]* O, g7 M9 @% ?0 J
void        APU::WriteProcess( WORD addr, BYTE data )
6 C+ x) d) O( D% _# l6 o. a{
: Q: E* [7 {( }2 o$ N1 H" u        // $4018偼VirtuaNES屌桳億乕僩
$ o! Y" y7 L: |% U8 q        if( addr >= 0x4000 && addr <= 0x401F ) {
+ `3 J7 S  [4 _4 l! N  N                internal.Write( addr, data );  g& F1 a5 [- e' B# `7 f' i7 R8 G9 I
        }
, p' U" S# w/ z% V- f" e- A& H% O( s" s}( @% ~: O8 k0 ^. G1 Z* _
9 z, A$ Y" M+ W# D  T
void        APU::WriteExProcess( WORD addr, BYTE data )
3 v$ I  }# d& K2 b4 g+ [( y{- }' _2 M! ]  Z; r! |+ F
        if( exsound_select & 0x01 ) {
& s8 V/ ^& [5 c+ M                vrc6.Write( addr, data );
$ `/ _' M& L9 G        }4 R5 U8 f8 m6 e% f" n7 w  p
        if( exsound_select & 0x02 ) {6 D& Z6 z2 x  {6 `8 D1 X/ I
                vrc7.Write( addr, data );
* C- D8 o, f3 o0 A2 G' g% o2 N/ E. b' c        }
5 J2 L7 d( V" V/ o7 l        if( exsound_select & 0x04 ) {
4 x* E* s# ^+ F8 ^6 o                fds.Write( addr, data );) r, E( H8 \+ W! [
        }
" ?( w* O. j. G' n        if( exsound_select & 0x08 ) {
! _# \5 d! q% f# N! a                mmc5.Write( addr, data );5 y, T* J- s+ C. g  m/ n8 y- G7 Y
        }& @0 Q/ h. Z# L' H; M, U( k
        if( exsound_select & 0x10 ) {
. |8 f  N7 s( h  \3 h                if( addr == 0x0000 ) {
- i  }! ?+ W- b  K) s2 N; Z* o+ Q7 V                        BYTE        dummy = n106.Read( addr );
+ M: k) l  h3 E6 _9 T2 J                } else {
7 ?$ q$ B6 a) O/ J. \! w( H                        n106.Write( addr, data );1 G. Y/ C' ^7 i( x
                }. S$ v) W9 Z  @6 T" D
        }& z0 J$ B, }' o2 E$ W4 m8 ?
        if( exsound_select & 0x20 ) {9 f( {3 `5 f9 d# Q2 c9 B% j
                fme7.Write( addr, data );
+ x, _1 a2 K, S5 s        }
9 ~' M3 I; m# N. a3 Y}
# N0 a* K4 s+ P* C9 p
' Y/ Y  L6 M1 \void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )# D4 Q$ q& @! z
{
, E5 {! N0 G4 T+ QINT        nBits = Config.sound.nBits;
9 x+ E2 `4 b8 mDWORD        dwLength = dwSize / (nBits/8);
; L- O+ J! g) n9 c+ IINT        output;' K4 U0 ?9 ^* T+ B" x- T" F! s
QUEUEDATA q;
0 t- S! d9 g/ Y0 cDWORD        writetime;
$ ^5 J8 q* x7 n) r
8 A2 t( M! G  T8 mLPSHORT        pSoundBuf = m_SoundBuffer;) G0 Z8 U8 y1 _
INT        nCcount = 0;
9 E6 ~% W0 }( R. H# _
8 ]% t: W7 y- s$ y. Z) p+ DINT        nFilterType = Config.sound.nFilterType;9 K. W4 d% J1 Y- J, `
2 a- d) V0 o% U3 l% X" Q
        if( !Config.sound.bEnable ) {! v5 F; N) g- h  {2 j
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
* t8 ?9 C3 ~% T/ K( G                return;
# `0 j) _# n. x        }
) T, X  U2 ?4 \0 L, j2 i: e0 _; w5 W& D9 x: q; V$ B4 k. l
        // Volume setup4 a2 ]5 Y9 Z# }0 b' X3 [1 l
        //  0:Master
+ }6 ~: [; X4 `8 y. B/ O! Y3 m6 J        //  1:Rectangle 15 }, h. \% {- f/ E9 p8 O$ P
        //  2:Rectangle 2
4 L% N- K9 k/ @- R/ |& I$ |* p, j        //  3:Triangle
/ S0 C9 h: W6 r7 [& z7 {        //  4:Noise; `. O3 O$ b" T9 @2 E1 t
        //  5:DPCM% q& z4 B3 G' l
        //  6:VRC6: N1 ?& [+ |" u1 I( ^
        //  7:VRC7
) y" U  a/ q$ o1 p/ |4 O  z: B        //  8:FDS
! n! m, d1 w! T        //  9:MMC5
2 q: b( F4 A' K: x: j        // 10:N106
4 i+ ^2 B" C- E2 e% B2 n        // 11:FME7% Z3 F* _2 O' `. d. I
        INT        vol[24];
1 R9 Z) W  ?- Z0 ?& c0 `        BOOL*        bMute = m_bMute;/ t6 M+ K: c- i8 Y* g
        SHORT*        nVolume = Config.sound.nVolume;8 Y+ s4 ?; ^( K# r
- ]0 k3 p  ]+ o* X0 P! r# M& ]
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
, a% Q! B/ j8 y% _, W5 s  i5 }4 b9 I5 M5 E: z# o8 J( z/ R# p" x. f
        // Internal; n- H& s# W$ l1 U) l" c
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
9 Q0 m& ^$ O7 R' Y/ X, r1 }        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
6 {: [% q- I' f5 |+ u+ x8 [        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;" A$ y* R, n; |4 Y) t
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;' z1 u; T# T4 }- M% x$ `
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;' ]8 a7 \& k7 g8 Z0 S
! T' J7 t9 u$ e6 k% |6 R, L" o
        // VRC69 J0 @5 z; x2 P0 R! M
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
" L7 G2 q# Y2 f5 n8 W        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
4 D$ W) \; e* l/ G+ f6 F        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
5 \% I( V, R; F9 [3 S7 L2 h: v' }
; o& i! R. w+ d% F- }) d        // VRC73 l2 `6 j* n# F# @6 T, v7 ^1 V
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
; e% n% E! a8 {% P
% ?3 W8 v  k! J! e/ n1 d        // FDS
# M+ R' |7 I! a        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
% b$ y4 _5 v" J4 _
- b* U1 ]$ w0 X" v        // MMC5( h  M6 _' K/ n
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
% Q$ I8 P% e0 c: y( `8 ~        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
: ^. n" w1 s. ^4 Y        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
+ y  G$ e+ q& K5 t! P: b0 h# W- A' ]5 w' `2 x. `
        // N106
0 W8 s2 k, I: N) `! ]8 o# O4 e        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
4 H, j! z1 N8 ^5 H" @5 N6 G        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
$ l9 @( i5 P4 ~$ _- D6 _  |        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;# x; m2 c( B7 V  Y6 w
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. x( \' e. ^; M& e& t2 Y* |9 B        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ f5 w% ?1 ]3 G" o+ E
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
% D) j- w$ M+ }* i3 E7 e( \/ S        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
3 `$ y6 ~) c& R( Y        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
! u. i; {/ X% e& ]8 V% k1 N; @) G: m8 N5 `# Y" R
        // FME7
# M; e- Z$ Q6 F        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
; W* |* D- x9 J9 B  N        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
4 i" \0 M# t6 \7 z) \8 Y        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;, ^( s/ }0 Z7 c) t

0 T2 N% |' O0 p0 n/ Z* q5 E6 {& H//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
2 ]; G" I" E# I6 W& i, v5 m9 u        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
. e# ~1 g$ m& I  M: b3 O, m$ N9 c& y
" Q. Q7 Z9 j5 A$ L6 _1 W' h        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
* \' X% K4 O$ J5 x- L        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
: k0 c/ H4 w1 v& m& K6 u                QueueFlush();( p, t" j1 h+ }5 x: r( |) B
        }, T9 [; x( l8 q  O3 ~
5 t8 q$ v! g8 {; h
        while( dwLength-- ) {
2 M5 r/ l4 W, z  ]9 q/ e                writetime = (DWORD)elapsed_time;, a" H  ~8 i( x% K8 q$ o

2 E8 D6 f5 f7 a- R6 M1 M+ y$ y; q( {                while( GetQueue( writetime, q ) ) {
0 j! Z% Z4 G! j: L3 [. C9 o! ?8 g3 p                        WriteProcess( q.addr, q.data );
! u2 a- ~- T' |                }' e6 r/ P- H4 S+ V0 d5 e; d# ]

# ~( J2 V- T6 M! y7 P                while( GetExQueue( writetime, q ) ) {! `" d. K5 a* C3 X$ L2 B/ u0 V- H9 }
                        WriteExProcess( q.addr, q.data );6 c8 M: r! E4 j; M, |  [7 L7 {: Q
                }3 ^. g& ~: L+ _! v% k) j5 k- J( @2 Z

& Y' l) U: ^1 H% V* x4 s4 R8 L/ ~                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7& |* N% N" e0 ~
                output = 0;
3 ]; A6 X% ?% c                output += internal.Process( 0 )*vol[0];; t* \8 y# d5 w0 X, L; k3 W
                output += internal.Process( 1 )*vol[1];
2 A' t' e6 L7 O1 \                output += internal.Process( 2 )*vol[2];
1 H& ~- a& W3 {0 ~" }                output += internal.Process( 3 )*vol[3];
# w' y4 G  o, t$ H  g                output += internal.Process( 4 )*vol[4];
6 x& ^3 a& h" D) A/ S9 c
. k( V* q7 u/ y: j$ C9 i; D; ]                if( exsound_select & 0x01 ) {. E: a7 u& o5 A8 j; a
                        output += vrc6.Process( 0 )*vol[5];
$ P. A4 Q0 J6 y( W7 `                        output += vrc6.Process( 1 )*vol[6];+ G; a2 s& J+ S0 B
                        output += vrc6.Process( 2 )*vol[7];
  M, V; x# {4 z8 B. c                }
: T+ ]$ J. P6 A6 h6 u2 C5 Z2 g; I                if( exsound_select & 0x02 ) {1 B9 [$ @1 O! x8 e6 n6 B
                        output += vrc7.Process( 0 )*vol[8];) Y. s. u( ]( a6 G- K" q) }9 n
                }. V5 a" q+ ]; w5 t# T4 V
                if( exsound_select & 0x04 ) {
% P* x# V9 a% }; m5 P; V/ m9 S                        output += fds.Process( 0 )*vol[9];  g+ l/ {) M( U( P3 q$ ]9 s7 D( `
                }
0 f4 u3 M& D+ Z& X                if( exsound_select & 0x08 ) {0 e$ J& H; W- Z5 m
                        output += mmc5.Process( 0 )*vol[10];0 U- T( k* E1 b0 l6 H
                        output += mmc5.Process( 1 )*vol[11];+ X5 {7 j6 O6 p' v, e4 K
                        output += mmc5.Process( 2 )*vol[12];
1 p$ y& B: u) n- o$ I" }% k                }: R" G, I' [. ?5 n6 P) b! c, p4 G
                if( exsound_select & 0x10 ) {" @1 z2 E% \( M& ]) a/ G8 s4 A
                        output += n106.Process( 0 )*vol[13];* {4 v$ J  f& _2 X+ p$ c+ n
                        output += n106.Process( 1 )*vol[14];) P- ~# ]* E% s+ i5 N+ C0 `
                        output += n106.Process( 2 )*vol[15];1 s9 R- Z2 H" F5 G) |7 |
                        output += n106.Process( 3 )*vol[16];
% M6 V: c0 C: d2 q4 \( }- H                        output += n106.Process( 4 )*vol[17];
9 p5 a* t# [% V! R2 G                        output += n106.Process( 5 )*vol[18];; g" J: h! B9 v1 d! a7 F" E
                        output += n106.Process( 6 )*vol[19];
( `. Z& J! J9 \! i0 ?5 Z                        output += n106.Process( 7 )*vol[20];1 B: h6 f; b5 ?
                }: Q) i( N/ u( S6 X% r6 @6 O3 p
                if( exsound_select & 0x20 ) {
9 A7 n9 A3 w7 v% P. A$ v9 q                        fme7.Process( 3 );        // Envelope & Noise: ?6 V2 i, p- }
                        output += fme7.Process( 0 )*vol[21];6 n! ?- V! C6 S! b# D1 J6 S/ F
                        output += fme7.Process( 1 )*vol[22];8 N( f) I2 e" i9 S3 T8 \
                        output += fme7.Process( 2 )*vol[23];6 q, E+ T1 \! V, R3 o9 @# v
                }7 H2 V4 X. w5 t
2 p( H0 H6 D8 V( v
                output >>= 8;' Q8 r+ @4 q2 S: ~9 ~
( N! m1 ^/ r9 |) N9 B: w
                if( nFilterType == 1 ) {6 d9 O: S3 W  q7 ?2 L' F% A( ^  Q2 L; g, o
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)! M) B8 d0 `; F6 T# F( M  k0 k
                        output = (lowpass_filter[0]+output)/2;
1 y2 n; A8 U; a* _                        lowpass_filter[0] = output;/ B3 ]( Y9 c6 S4 w! d! o: _- i
                } else if( nFilterType == 2 ) {
8 d% f; c! _+ m0 v                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
9 x" |" q1 j  {                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
, A4 E- x7 K4 ?6 J                        lowpass_filter[1] = lowpass_filter[0];% g6 [7 h4 N, z- @0 D
                        lowpass_filter[0] = output;1 A' e2 a- R( n' c+ T, I
                } else if( nFilterType == 3 ) {
* g( w! l3 s' E8 [3 R  K                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
- [" S- ?$ d' j7 a" x2 x* {                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;* _- O) u( p, `; F5 O8 N8 e
                        lowpass_filter[2] = lowpass_filter[1];" j* V( O7 _+ }+ h2 a
                        lowpass_filter[1] = lowpass_filter[0];
" ~* w1 r6 F4 d6 U& U( C" L                        lowpass_filter[0] = output;
% U2 m  n' p' b& M' v) e* R                } else if( nFilterType == 4 ) {
9 W! X! D, Y1 i  E1 k+ m/ f; S                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)3 I6 X0 N6 H, n+ @( e6 n9 ]
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;. B7 X( W2 d" \
                        lowpass_filter[1] = lowpass_filter[0];
% Q3 y  P+ K- I$ e- H6 V                        lowpass_filter[0] = output;
2 W  ?- R& H8 U5 F4 @2 r                }
6 n. y; a+ E' @. p
+ k' \  s# z! c$ u' a' `1 n( d1 j; x#if        0
0 A& \" e/ _9 g! r0 g  q6 C                // DC惉暘偺僇僢僩% h2 Q# ]4 u/ v  z6 D2 U
                {
' o$ {) G# X) W+ B5 q                static double ave = 0.0, max=0.0, min=0.0;
! |: ~4 n+ W6 |7 G                double delta;% K; ^9 Q/ l/ J- l
                delta = (max-min)/32768.0;
  V) T7 `0 n* ]2 P                max -= delta;' t/ m/ y2 L6 y! J8 b% L# ~7 z
                min += delta;
; I, z; n/ O$ y9 a4 C: ?0 ^                if( output > max ) max = output;& h! X! O" I3 ?: b- j, P
                if( output < min ) min = output;
: t  R; A  _1 u) _6 g  L# r                ave -= ave/1024.0;
  X4 V- ^. J' P& I; @* ^! r- c                ave += (max+min)/2048.0;
* ^. c5 i, C4 A1 k" W2 W% F                output -= (INT)ave;
/ Y; }- O8 {# h! V/ ^- t                }  O6 y8 q2 u5 J' q. r! e+ D, z: [" |
#endif+ y0 u" m5 }) }
#if        1
# }7 ]/ |. D9 `7 i9 e- _                // DC惉暘偺僇僢僩(HPF TEST)4 P4 V8 J; K) C
                {& @" J6 ^' H' U* k- W! [# l5 J8 @
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
8 O$ S$ r: f" x0 a2 C8 V                static        double        cutofftemp = (2.0*3.141592653579*40.0);) F+ n1 ]$ _  t% b/ O
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
! C' {5 v4 s9 A$ X( ^                static        double        tmp = 0.0;' Y$ {( ~/ U; V3 h0 w" U# }
                double        in, out;$ H! _  Y" |+ d% p+ x9 s% [+ I5 x

6 G3 E) @) B0 I, |4 l                in = (double)output;
0 ^7 A: f. `8 R- X' k                out = (in - tmp);
5 ]/ I1 Q6 `! ^" w                tmp = tmp + cutoff * out;3 d: p; ], [- l

* H" y6 E9 O1 \7 X+ D! F; h                output = (INT)out;$ V$ j8 @# A/ f  X5 w; a2 E
                }  R1 C- n) ~' a2 q
#endif
! f# \& o( r0 `" w8 g8 I#if        0
7 [8 B  w$ g) k- z! U8 i                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)4 d# Q; s6 w4 |, p3 Q
                {. \) V4 E; @8 {7 ?, V  C/ L
                INT        diff = abs(output-last_data);
( N4 u9 ^0 ~* a# c                if( diff > 0x4000 ) {) h% _$ T6 c4 A6 e6 l+ q
                        output /= 4;
* z. b5 N2 {1 P2 F/ f                } else / a/ s! l6 y' X/ w/ a* @
                if( diff > 0x3000 ) {
9 _+ `9 m. U7 m: l! K$ e                        output /= 3;5 x5 x% N* g2 j6 ]' y( I
                } else( J! g; Z+ p( i. h) A$ |
                if( diff > 0x2000 ) {
! ]9 c  \8 K0 t! k! {                        output /= 2;
  d, g! a, a, G& p8 G                }* d0 x: p% N4 q+ ~( ]) @7 R
                last_data = output;" T$ L3 O' R9 o& e) j6 |; W
                }
, T6 l& v  a' z- _3 J) {#endif) l' q% ~% h# u; m' }
                // Limit* J* Q: L6 C% }2 R# ~+ h* C
                if( output > 0x7FFF ) {% P/ ^% L. S3 ?" M+ r
                        output = 0x7FFF;
4 X; g1 G% x" Y  N9 d                } else if( output < -0x8000 ) {
/ L4 v+ r. R& y( l                        output = -0x8000;: |) G9 }* L& ~8 l1 z6 e% \0 N
                }6 r# M' Z4 T1 k/ K" X% V

5 z$ R; q: k2 ?7 e6 d) [! r                if( nBits != 8 ) {
! e/ s. Q$ q: w1 X, Q) X                        *(SHORT*)lpBuffer = (SHORT)output;
; N1 X! g: {  z/ z' u, }8 U" D3 l/ L                        lpBuffer += sizeof(SHORT);
" r$ W3 `5 c/ l; [/ q+ V" g                } else {& P9 r* Q, k# Y' e( J# O
                        *lpBuffer++ = (output>>8)^0x80;
* C& E! ]( Y( p) U                }4 F" x- c: b5 w% m) h# d3 H
  g4 G% K; l! \+ R; g
                if( nCcount < 0x0100 )
  l+ J, I( z+ f) J- L                        pSoundBuf[nCcount++] = (SHORT)output;
6 J; L! V( W2 Q) L- k' O
  ~. i' L4 R4 X0 }* @$ S//                elapsedtime += cycle_rate;
+ G' c% `7 M3 y6 [                elapsed_time += cycle_rate;
# a. Q( E' o( ~; k        }4 z) n# O+ |4 I1 E
$ P$ c4 [) \4 `  _
#if        1; h7 A  d5 W, O  d( [( F3 G" L
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
1 l9 u% H/ N0 V- m* v                elapsed_time = nes->cpu->GetTotalCycles();
4 y* U/ y) E; G( u$ M        }' V/ P3 x3 w7 g8 M
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {( Q  @2 \8 ^/ E/ P/ Q& N5 P
                elapsed_time = nes->cpu->GetTotalCycles();
( a3 E' C7 X# R" A' ~: F: w1 P- {        }( F" k  G( N/ H6 [. m! O: `$ Y
#else6 C4 ~& ]# r0 b- H" I( V/ L
        elapsed_time = nes->cpu->GetTotalCycles();
' x# P) ^5 L# U, w9 J#endif
. Q6 i- O2 f+ y0 @}1 _; I3 ~7 [& E4 b+ I( g

. q7 H4 C; i, M( P9 h// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
' n. J: ?; G* a9 ~INT        APU::GetChannelFrequency( INT no )3 ~! O9 C1 |+ m+ E% T- L0 h
{/ y6 j# ?  z" t( Q2 h- ]
        if( !m_bMute[0] )& w! s' N8 D2 U
                return        0;5 L  h* V6 a' p+ Z5 ]" S

  ]& b$ J( }" q! W4 W6 B        // Internal8 F4 O! G) ^- e9 ^
        if( no < 5 ) {
' W  q$ H- a9 H6 b0 j& K) p9 F; `3 Z                return        m_bMute[no+1]?internal.GetFreq( no ):0;. [5 j) g9 [1 ~/ U, E
        }
* @0 O7 d. Z; U; p# k        // VRC61 o9 ~5 j- S8 b- r# C8 t* W
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {: f/ x) c! J; k" u3 C! o
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
+ W) |( ?4 }9 X8 ~- ^        }
' o. g  l% V# U( ~        // FDS4 G- |/ _- z9 _1 Z3 G
        if( (exsound_select & 0x04) && no == 0x300 ) {
& V9 V+ g, B% p' A$ K0 m, [4 o                return        m_bMute[6]?fds.GetFreq( 0 ):0;
' \& a, x) h* s+ B+ w% A        }
. n6 F: Q! P: l        // MMC5
6 {- y. v1 ]3 o9 v        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {5 g: a; L: A$ C  |9 W4 R
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;" V! d* u3 T1 I# t# g4 C+ j
        }/ p( }" r- w6 }7 q' |2 Z
        // N106! M( {% d2 A7 D0 @7 c1 Z" r# o
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {# C3 j, o: Y& J) o. f9 ?! s
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;8 E$ `' l7 \$ P9 b9 m
        }
9 S' c3 G0 h- k  Q& K1 V: H# ~- n        // FME78 [# z2 r* e4 \! l
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
6 b. @. a& P7 \7 x" {$ w                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
# n$ [- w( U2 K  [        }8 s1 u; N( v3 B2 b1 ~, F
        // VRC7; l1 @! Q9 A5 T2 Z. ]6 f% s: h8 M
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {6 Q' M* b' i5 M' T: m
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;' T/ u0 z) [$ e  d
        }( J" r, T) s% S3 N- H
        return        0;
( B6 o( w* r/ P# O/ ?}, o% |% v1 i( N
" {4 N6 `: \. b2 [
// State Save/Load
0 u! Y( |( [# V8 }- n, b- lvoid        APU::SaveState( LPBYTE p )3 Q6 z7 o6 Z1 C( }1 r  `1 \+ z# Z' O
{
1 h; I& D* S+ u& Y. ]7 s#ifdef        _DEBUG5 y+ U2 N; ?- U8 i2 t
LPBYTE        pold = p;+ ]- U6 f- a2 _7 @. w
#endif0 ^+ {% a! O2 x

: X5 i" d& B0 w, F        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞+ g6 j- q" `; s" i0 K6 N) o
        QueueFlush();: ^, d+ h) b9 i6 Y* b  U$ p6 C7 ]
, S/ O2 q2 A, z5 E- k* i1 e
        internal.SaveState( p );
1 W) `+ [7 o( P, Z1 v        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding; e* o7 g4 A7 [6 v6 ~& G

$ M. v, Q# C* ^" v! L1 s) L, o3 `  G        // VRC6
2 F5 ~" T- {2 A  J$ j) H& W        if( exsound_select & 0x01 ) {. _7 A% l- w; Q9 W" x
                vrc6.SaveState( p );" m% L1 ^; I5 [' |5 ]7 _
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding# R1 d. y  Z* {; N# r, M( _
        }
  S4 b- _  D, f/ _; W! P, F        // VRC7 (not support)
  Z4 \5 A; ^; K* S        if( exsound_select & 0x02 ) {
" q0 Y. a& I8 q2 _/ W  Y                vrc7.SaveState( p );6 w( d! T" p+ a6 B
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding; l* L/ j' y+ V" d# w
        }
7 I, @+ G  g' L3 `        // FDS2 z3 A( C% A5 k/ P& I3 T' Z4 `$ X9 [2 ]
        if( exsound_select & 0x04 ) {
+ l8 R( e( g) [                fds.SaveState( p );  [: L2 f" O, @! G* A; L: Q
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
+ A5 o, f5 x: C. j9 p% ~        }
, L+ Y2 }' m- q! d: r        // MMC5+ Y4 _( O0 a' S$ X
        if( exsound_select & 0x08 ) {
, ?' a1 L+ b1 w+ G9 e4 f- n                mmc5.SaveState( p );
4 U' `& t& p& ?! N' Q+ a                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
+ d/ Y% K, y- a# H        }. O! I- {' z0 z7 {0 C# X
        // N106
' n- C2 s) z8 F$ E/ `  p3 a        if( exsound_select & 0x10 ) {3 C1 m4 Z1 n5 s: T& I
                n106.SaveState( p );  _; a$ `+ o" q2 }; P
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
! F  f' T; E! Y$ @5 N  S        }  Y8 O& I# v8 c" A$ c
        // FME7. Z, ?* u; R- S: v/ y. q# r1 h$ \
        if( exsound_select & 0x20 ) {: F# h! ^/ d/ p0 u: F
                fme7.SaveState( p );( v' _5 N/ O, V7 o* Q3 R) j4 `) N3 }
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding6 p6 {  o9 k# [6 w3 z# f& n! n- q
        }
" y, W) U8 o3 }5 Y2 P9 d$ K9 o3 W  T5 C/ u' {% w
#ifdef        _DEBUG$ r5 ^& H' q. F0 L: W! L* o5 j
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
* S0 o' I; [2 q#endif. b0 T! Q1 D5 j. E% {' C
}
7 ^$ X" a/ i0 {1 |+ T# {7 M, z3 M! U% N% i! ^  p8 a9 ?
void        APU::LoadState( LPBYTE p )
. M/ q* T$ x6 Y" a  M& m, |8 N{2 R7 r! P' m- o: A0 H  }; N/ p
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
+ x$ R5 P' I+ ~9 O        QueueClear();
4 O) p' b8 |1 k" q4 I4 f& Q- |2 {
+ [5 V# V5 D( O        internal.LoadState( p );
0 g+ }0 j  c% L; E" _) d        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding$ l4 `" A( d: L

; O7 t! e# B+ k3 {4 D! _        // VRC6
- |! h: Q' v: Z( G' y        if( exsound_select & 0x01 ) {& y! Y1 h/ y- R, ], x- u+ w8 p
                vrc6.LoadState( p );
8 q" T$ w5 L6 u$ C, a% i- ?                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
5 k8 h, g- U& {+ i3 ^3 I        }0 ]1 q* m, t$ j1 i% z# X) W
        // VRC7 (not support)
4 H- a: \+ Z3 d7 ^; T# A& r        if( exsound_select & 0x02 ) {
0 p) s8 L1 v8 f# k0 G                vrc7.LoadState( p );# K' f) [& ~3 n5 t6 p" p& u
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding' R# [' D) P7 o$ Y3 {
        }+ J  l+ x, b, c2 X* O/ {" K, M. m
        // FDS
4 z9 ~3 @7 V+ K# ~* w1 a        if( exsound_select & 0x04 ) {
# k# d4 a" z0 I' o. W1 J# {                fds.LoadState( p );
- _' G. K. `& v$ y6 C* J' i0 P                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding: ~* H. D+ c- y" l( y
        }
7 c4 i& @, K3 y. _8 f* z        // MMC5
3 l6 t9 \- g4 c# _        if( exsound_select & 0x08 ) {
# a. b9 l% F% w                mmc5.LoadState( p );3 b6 T2 H  _8 Z1 Q3 H
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
9 w- O, u) O0 L1 I. d/ t        }6 ~- G1 e1 S5 |& B) T" L. ]
        // N106% J$ P6 k5 b6 G4 g: i" n/ A
        if( exsound_select & 0x10 ) {
/ v5 l9 a  v; P; H                n106.LoadState( p );  }, c- O' j' E9 H8 V3 r  ^" P
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
9 K$ ?* R# O- @. o* t        }
& L2 f! V6 D& o        // FME7
# p. n. J0 V# K2 S0 E        if( exsound_select & 0x20 ) {" W) k& R0 W* r9 q2 w1 m
                fme7.LoadState( p );5 C$ R5 E5 _! K! c  V- C/ Y
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding; \! I* E# J4 @1 C
        }7 P$ ]# r" N5 G6 n& S
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 4 [, i: o! o' Z5 p3 T8 k
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。2 y! v0 Z" \" n8 c
感激不尽~~

( D+ N. j% V4 `8 \% ]9 R恩 我對模擬器不是很有研究,8 y, ~2 n0 E; d6 H  l  ?
雖然要了解源碼內容,可能不是很困難,! T) P: B* x$ c6 @9 j* L; B
不過還是要花時間,個人目前蠻忙碌的。
' S5 a' I& X5 T/ r; y9 i6 b, y
! J) X6 D  Z; E+ |6 N給你一個朋友的MSN,你可以跟他討論看看,( R3 c1 i8 w# t2 g/ `3 }# c
他本身是程式設計師,也對FC模擬器很有興趣。
- r6 |: G& S- ]6 i" u
6 p% L" m# g9 ]$ X; c) W- x& ^* Z* xMSN我就PM到你的信箱了。2 _. @; J  x/ m6 n3 m4 B
" W* O% ?' i) {: s' |/ w
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 6 K. V- G+ N9 E; U
呵…… 谢过团长大人~~

! u& V2 T% Y+ v. x/ A/ @' f; @  E* O2 V0 b# y
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 # p% n2 }; g  ~' N+ u& @: |8 _" _3 [
团长的朋友都是神,那团长就是神的boss。
+ r9 h7 Y( l% O; }
哈 不敢當,我只是個平凡人,
6 n- k# H! m1 i$ M* K) a要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
2 [- ^3 y' }) `. eZYH" E  C0 p2 x5 K- K9 T& l
QQ:414734306
3 s$ r/ N  ^" B& R0 XMail:zyh-01@126.com
6 F# m. n; e* D# S' l9 a& }; Q& C. N( y. Z( ?/ c. ~! X
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 $ ~- A# r/ e. k' d
再次对团长大人和悠悠哥的无私帮助表示感谢~~

+ M8 P! x$ H! N: _; A不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-9 10:08 , Processed in 1.103516 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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