设为首页收藏本站

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

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

  [复制链接]

该用户从未签到

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

该用户从未签到

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

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
& D% s& E  {- q( ]- s. ^- L楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
. Z# ]) v  m. d8 D4 {% |4 A这里有相应的模拟器源码,就当送给大侠了~~
! P( ]2 V8 y9 E- \% z) q: Uhttp://kenkao.qupan.com/5096520.html
回复

使用道具 举报

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
- y4 \* x6 q, m能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。; `% [5 v4 r3 P2 y- l2 K
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
( n1 p+ {* {. N/ I6 x+ b这里有相应的模拟器源码,就当送给大侠 ...

( N4 j! l- W/ S4 C聲音部分(Audoi Process Unit = APU):
/ d* T! Q8 b+ Q( I$ @5 l  C7 w.\NES\APU.cpp
# M7 B+ _3 y' Q. a9 O.\NES\APU.h+ q! b: s8 e2 }. P! L- I/ y

6 e% p5 {3 ~1 ?: W! y8 B7 R% e) |5 J* D: C2 j
影像處理部份(Picture Processing Unit = PPU):
8 D7 b$ z" e: o5 V.\NES\PPU.cpp: c1 [! l- V( z# M% ^9 [5 H8 ~) Z
.\NES\PPU.h
" V3 u( z; \4 V1 h: l2 K, h  t
' I" ~  J8 w6 L9 `如果原碼用C跟ASM混搭也不錯
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:8 H5 C! W+ K. O2 o( o3 f" v) U
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
6 o: ]% Y5 J) V& ]( b//////////////////////////////////////////////////////////////////////////
$ ~4 j- Y, j+ A1 `# p1 t( @//                                                                      //
' c, X" w) g9 \4 x- e  |1 `//      NES APU core                                                    //9 o3 I. n+ @+ \) O/ x/ `" O0 D
//                                                           Norix      //
/ S6 c! {* u# q' L, R1 o5 H& D3 _3 H' A0 B//                                               written     2002/06/27 //! r5 o% `; X6 W3 E' Y
//                                               last modify ----/--/-- //
8 G$ R$ V1 e1 t2 V2 i0 R//////////////////////////////////////////////////////////////////////////7 ?" H# |7 E/ S; `8 `0 m
#include "DebugOut.h"
: a0 ]$ @0 j8 Y1 {5 q* j* g) h#include "App.h"
# ^) [- i9 J; n6 N% d  r% \& Q. {2 G#include "Config.h"
' ?% T4 m: y  j' j0 t, }" F3 s& S5 D
#include "nes.h"
" c& L! U, y" m% m0 f1 c#include "mmu.h"
2 |. W  o) ?6 K1 E2 T#include "cpu.h"
- f  F+ b" |# p& j& B8 D5 i: O) J4 O#include "ppu.h"  |- d  Q3 Z1 q; \( J% T  J6 K
#include "rom.h"! q8 ?+ @  ?; M) C% C$ b% @& g
#include "apu.h": s# O8 l+ E2 u( H) I+ P. q. g; i
9 V/ I. D! D4 g2 Y! H% ^. d, O
// Volume adjust
- R$ o% m$ r( @$ S// Internal sounds
6 `+ }, I4 f7 G#define        RECTANGLE_VOL        (0x0F0)# g. u  ~0 `' O2 ?7 t; _. X! A
#define        TRIANGLE_VOL        (0x130)
; {% T1 k3 g  q$ L. ^#define        NOISE_VOL        (0x0C0)+ U( i; f0 c- v3 y0 t
#define        DPCM_VOL        (0x0F0)* O2 @1 |: o9 [( w' ~: P; C' @. L" T
// Extra sounds
, P( F+ S7 P  V2 P#define        VRC6_VOL        (0x0F0)
" S% ?/ p, E7 ?! u( w#define        VRC7_VOL        (0x130)
3 M# I9 O- h' ^+ n( I! N) U#define        FDS_VOL                (0x0F0)
+ t( a6 G$ X3 a+ F#define        MMC5_VOL        (0x0F0)* F1 `% v( E  T# W  ]( |
#define        N106_VOL        (0x088)2 I% Z" ]8 h2 a3 G  m: _+ f
#define        FME7_VOL        (0x130)9 j" p, b$ g9 A8 @* F

0 }! s, p% m: h8 MAPU::APU( NES* parent )( W/ t3 C% T! q5 ^+ U) ^
{& r; ~+ ~; s% g& B+ O1 i
        exsound_select = 0;
2 `. Z1 C" k9 p3 \0 w/ \
9 H9 S% T7 ]" o+ u1 j1 u        nes = parent;/ f- _/ Z; h1 }- [6 H" w
        internal.SetParent( parent );
- u0 }0 W& S3 j7 V% y- q5 n& v: j# r5 ^7 @0 h( z  c! z
        last_data = last_diff = 0;
0 K. C) y5 g6 r. N2 ?: L# J3 h6 c" x. P. P1 C
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );' b) L+ V8 m5 b6 q7 H9 [+ E

8 k  E* p. }2 P! t3 m9 q% D% [        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
8 j7 y. t6 b/ @# X) y; I0 H        ZEROMEMORY( &queue, sizeof(queue) );4 }" j% p# g/ n# v$ k8 b
        ZEROMEMORY( &exqueue, sizeof(exqueue) );4 Q9 x7 c  `" o0 S- Z. r+ j
& [+ m9 l4 U! i8 E  d5 M. [% v
        for( INT i = 0; i < 16; i++ ) {, {% R; ~& Y( Y
                m_bMute = TRUE;
3 R2 E7 \: l7 W0 {, S        }
5 P$ P6 b$ G4 u/ z) w  f}
+ y9 ^  d, l( Y9 @8 g5 ?
2 z; o" i$ C' _- D; @  T' qAPU::~APU()
" d5 d( t6 v& x! H/ t0 n" `{/ t7 e" }" Q4 h
}& Z( n- {1 E& C- c* E

9 t6 W" a) X  A; p* Mvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )
: ]1 \, V* `( C6 F{
8 G3 Q3 G+ U9 K- Z3 V' ]5 W: @        queue.data[queue.wrptr].time = writetime;
( F; i) x0 D3 f0 ~' {* ~  z        queue.data[queue.wrptr].addr = addr;
* F& [" ?/ A! j! o, J        queue.data[queue.wrptr].data = data;* G* ?3 Y/ W* u. L2 \$ _1 t
        queue.wrptr++;9 C2 W! D8 ]( ^: T  u
        queue.wrptr&=QUEUE_LENGTH-1;- i5 j: F& W( m
        if( queue.wrptr == queue.rdptr ) {9 `. h! ~' q6 k. h! _# s2 ^. Q+ u) W
                DEBUGOUT( "queue overflow.\n" );
( I& [' {% I0 A+ d& j& W, \        }
$ ~& T3 p# B$ H$ y}
' b+ Z' i2 r4 d" h0 }; L% O' `
( \: N% h4 M* F& N  K# lBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )% ^' l2 Y; G* s* R2 Q  U% O
{4 `# s- P2 \+ i# v6 P! R2 m5 ]! m$ r
        if( queue.wrptr == queue.rdptr ) {* ]* |8 X" [" _0 O9 Y
                return        FALSE;+ \& J3 f3 f! q* F
        }: F& |$ ?; W3 Y9 P2 I& I# V; z
        if( queue.data[queue.rdptr].time <= writetime ) {
: o4 ~- T# G- b/ g                ret = queue.data[queue.rdptr];; V# D0 h; j; u9 |
                queue.rdptr++;- f% ^6 I# u2 {6 h
                queue.rdptr&=QUEUE_LENGTH-1;
" E: {) L8 e& D' U* k3 z& D                return        TRUE;
) X5 h$ {* `, R; j  l8 p; m        }3 d8 \9 [- u0 T0 c( [& J' {% d
        return        FALSE;) c* w, w" n$ W+ Z: w+ K
}  h* x$ z  x* w  @% f

, ?1 {$ \% q8 w9 U5 Vvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )/ o0 |% {" W$ j$ z
{( k1 K9 m. X$ g$ O
        exqueue.data[exqueue.wrptr].time = writetime;
) {; H1 J6 o$ F. A3 ~! v, g        exqueue.data[exqueue.wrptr].addr = addr;4 s7 }* G8 n# e, H0 o- g
        exqueue.data[exqueue.wrptr].data = data;9 V- R; d6 b+ t) {: w- Y
        exqueue.wrptr++;; Y% U4 T/ H. y; j, n* _! c
        exqueue.wrptr&=QUEUE_LENGTH-1;
9 T: ?6 p' }: R. L        if( exqueue.wrptr == exqueue.rdptr ) {% m( k" A2 e2 r" i
                DEBUGOUT( "exqueue overflow.\n" );
2 N1 i3 `- q2 L) e( a        }
: x+ C  ~5 Q$ o0 z5 x9 _9 W}
  Y- d. {  e' G  ^5 L1 S0 |% r- `2 H0 g
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
# F5 x: r: K+ P' p4 m6 w& m. D6 [3 b{2 @: V2 j. x- A5 l4 p$ n8 J
        if( exqueue.wrptr == exqueue.rdptr ) {
6 ], _, ?: I+ A* A" P0 B$ {! \                return        FALSE;
8 ^8 s0 u% y& h: j9 ~        }0 Z, }* n! o$ H  A: N" ?( D
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {3 B3 v0 s( z9 E$ N
                ret = exqueue.data[exqueue.rdptr];& G4 u3 P! @. f% q
                exqueue.rdptr++;- U% A/ _7 s* J
                exqueue.rdptr&=QUEUE_LENGTH-1;
5 v9 t) l( y9 O                return        TRUE;
7 `# O" {. S9 ]9 Y        }4 L- [7 B, j4 B# w9 g
        return        FALSE;
* l# _: `6 f0 W, ^}- Q1 f3 D% y) S# R
: q' X' }2 U- f1 S3 w( W4 Q& c
void        APU::QueueClear()
. k6 |* S: c0 o6 {6 v{
) X" r! P; Y: D8 ?2 Z        ZEROMEMORY( &queue, sizeof(queue) );3 H2 k) A* m, c1 ]8 P1 ^
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
% N( o# n" e9 D}
( A! E% _  y+ V% k# o7 C
& N" k" k# ?% q  [* O4 evoid        APU::QueueFlush()
0 g* E5 R6 }% z/ m' H5 E{
8 g8 U8 W% r8 u$ f+ U        while( queue.wrptr != queue.rdptr ) {
& V/ S' V6 l; a( G7 l3 y                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );: t! c' z- @+ \. A9 E+ Q
                queue.rdptr++;
( `- R' u' U1 p" _                queue.rdptr&=QUEUE_LENGTH-1;% `  K& S: p6 U4 u# k+ v0 Q
        }
0 p* T) [" `9 Y& w- i: V, C# f+ w% ?) u$ D1 e7 M/ a' A
        while( exqueue.wrptr != exqueue.rdptr ) {9 Q) Y/ ?1 y! _3 O( l$ e1 F3 J
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );; |- {" e8 ~; s! p$ `- ^) {6 z) p
                exqueue.rdptr++;, D3 v9 ?  h* R, ~0 [3 p
                exqueue.rdptr&=QUEUE_LENGTH-1;0 _8 h  O9 }. ~0 C* {! y
        }
% h3 H) c& {3 b7 I}
- K1 ?( I# n& e/ ?- a
: p  o5 o% C* x2 N$ a1 Fvoid        APU::SoundSetup()0 S5 m, s5 S  ^
{
) T1 g: ?2 u  f3 g2 H* g        FLOAT        fClock = nes->nescfg->CpuClock;
* x1 ]) s0 m& K( d" J        INT        nRate = (INT)Config.sound.nRate;
, ?' c8 U3 `# ]& I0 I2 J        internal.Setup( fClock, nRate );
' V9 L) F- Q5 e        vrc6.Setup( fClock, nRate );
) S6 ?* ~5 G8 \) Z" D        vrc7.Setup( fClock, nRate );
. s9 A+ }8 I" }& j( I        mmc5.Setup( fClock, nRate );; F6 u- s& t! Z' Z+ i
        fds.Setup ( fClock, nRate );
) \8 h7 t6 [# u# t1 j  @% k! |        n106.Setup( fClock, nRate );$ t; g7 q5 D) Q+ Z3 D4 s1 M# R) w
        fme7.Setup( fClock, nRate );7 O% v( o/ h4 ]2 D6 I
}/ T& Q  b2 z7 K+ m

2 U* a' m2 v) C2 r: S6 Qvoid        APU::Reset()( U& x! z/ z# @) o/ d) b: u) K
{5 R$ D, g  f$ G! u) @
        ZEROMEMORY( &queue, sizeof(queue) );0 z) p3 U% y$ w5 m
        ZEROMEMORY( &exqueue, sizeof(exqueue) );9 g/ a( z! p9 R' q9 d# Q

9 W, o* t9 _! N1 g/ k5 y        elapsed_time = 0;
) t6 A" W/ O% T4 f; U9 Q4 N! U0 s* U- }) p/ k
        FLOAT        fClock = nes->nescfg->CpuClock;1 P" _0 T' c) R2 U6 a
        INT        nRate = (INT)Config.sound.nRate;
7 q7 Q0 Q# j" l1 h* m$ _: ~; J4 b        internal.Reset( fClock, nRate );+ O9 r8 H% x' w2 \( n2 H
        vrc6.Reset( fClock, nRate );
  d8 o. e, d" V' b        vrc7.Reset( fClock, nRate );& o7 o/ v9 ~5 ?# E2 u
        mmc5.Reset( fClock, nRate );: {+ g+ a9 g0 J& E8 ]9 {" }+ Y7 a
        fds.Reset ( fClock, nRate );" ]8 s6 s8 M0 n
        n106.Reset( fClock, nRate );
# H! N( U/ ]8 ]. a# J: k        fme7.Reset( fClock, nRate );2 Z& k: `2 t6 j8 `' x. M

8 D1 S% I7 j% ^        SoundSetup();
7 D/ Y2 m, c& r9 f}4 Y- C: M' ?' E. l9 I
1 |: u% m2 e6 _, r
void        APU::SelectExSound( BYTE data ), p: h) Q: _- w6 F
{
- {& i$ g/ B* W        exsound_select = data;
  h8 x" G% j* q}
% H$ {% Z8 b/ z# l4 Y. A
2 U5 Q$ t" A3 k9 Y& e! A+ d- PBYTE        APU::Read( WORD addr )
; u" F5 h& p/ O3 R{
) B3 q8 L7 M1 V6 W        return        internal.SyncRead( addr );6 W! |. B5 ~& P0 z& g# y) J% v
}
. b) v7 n% l  u* g  }
  [* F- C+ N0 {3 ]# Zvoid        APU::Write( WORD addr, BYTE data )
3 N% k6 A( s2 Z7 E{
; p! T. u7 s: B: {7 S8 g        // $4018偼VirtuaNES屌桳億乕僩$ Z# W4 q# x$ v8 P0 F: U
        if( addr >= 0x4000 && addr <= 0x401F ) {
7 E1 Y6 c/ M1 W0 D9 i( J7 ^  e* O                internal.SyncWrite( addr, data );# t9 s: Q6 {9 l- e% T
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
# u6 m  T) p. v: t6 V/ p        }  T4 @; V; O2 d/ r2 w( z
}$ O+ ]; w# S5 Y8 {3 `- U

0 y& |- D+ S# V6 JBYTE        APU::ExRead( WORD addr )
! d: X$ }, V9 |! q{, t3 f! ~- J1 ]5 m
BYTE        data = 0;5 o9 t1 Z8 Z. W0 H9 i

7 S9 m; E( }! i: T; I7 r0 Q        if( exsound_select & 0x10 ) {5 p0 B) u8 @1 V
                if( addr == 0x4800 ) {
' e. W7 f- m. G: Z. t5 i                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );' ]% y4 f/ k' f. [/ k" n- I9 m
                }, @* a) K; t" J& c0 t2 P) J+ b
        }- c" f' Y7 A3 N! A
        if( exsound_select & 0x04 ) {# `5 g, i9 }# k8 {" ?9 l1 |
                if( addr >= 0x4040 && addr < 0x4100 ) {* L* T" K8 S' B" n$ \* h
                        data = fds.SyncRead( addr );; x  z& ?" c  x+ s5 t& _4 L: f: s
                }
; c4 y4 Z$ `# W( V* o        }# [. v4 @/ V1 Q
        if( exsound_select & 0x08 ) {2 S: t/ r- M1 |
                if( addr >= 0x5000 && addr <= 0x5015 ) {! f5 H7 \% @% L' t- b
                        data = mmc5.SyncRead( addr );2 ^, Y- P3 J+ `3 _# z8 X2 b2 {
                }* h/ V: t: H+ x1 p7 C
        }' @" `! [6 s7 {$ y0 x
, C. J2 v) `! `3 X3 N0 |! o0 p; S
        return        data;
( b, M3 {) ]5 f4 I! e}! v% `$ B" S, Y. U% n

+ F' x2 t3 y  O# L" E' Gvoid        APU::ExWrite( WORD addr, BYTE data )
5 |$ b1 y& G3 D" Q8 V* }{
- X% O1 _/ ^( J& c4 ~8 l& C, Y        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );5 J) Q7 f; M8 v" O
! M; S( I( ]( l$ Q' B* I* u- |
        if( exsound_select & 0x04 ) {2 G5 d2 G, k: T8 E; Y" g
                if( addr >= 0x4040 && addr < 0x4100 ) {: K! h8 w& A% p2 ~! A9 r
                        fds.SyncWrite( addr, data );/ i0 \9 w& a  [# P; M9 k$ L
                }
, ~+ L/ j: |* s        }
+ H& d% U9 b! j' F3 w
; H6 A: \. q- a1 Q) W+ D5 k) U        if( exsound_select & 0x08 ) {% y: ^5 w  G+ |0 A- I
                if( addr >= 0x5000 && addr <= 0x5015 ) {* v2 [* j1 l$ H/ p. w
                        mmc5.SyncWrite( addr, data );; q' j+ W- Q. ?0 B7 J& |) j  D
                }" S( c( @. H0 n' U+ u9 `
        }3 @+ b; H2 T& j4 o0 q
}
! J2 g) W7 [, o
0 W  j0 P9 n0 Z+ `6 _2 Nvoid        APU::Sync()
* Q/ |; ?2 o! N- P& @3 t" G{
* A) h0 V. k# c* k}
9 d8 J8 F+ G2 m0 z+ z6 `% u( _( f2 w9 p/ P
void        APU::SyncDPCM( INT cycles )0 Q: g5 @) `1 F6 s/ X# Z! v
{8 Y0 ]8 ~" x" t7 X/ @: [, B( F" }
        internal.Sync( cycles );
/ |% x. Q4 f7 V
- P1 S# a9 W' I6 W$ F0 c  q        if( exsound_select & 0x04 ) {
8 L/ k( h0 T5 M% a9 l% G                fds.Sync( cycles );; Q5 s* q& S; n$ S
        }
: V, q% Z( P1 R/ h) j( A! C& H        if( exsound_select & 0x08 ) {2 [: Y! i9 p, x: h  B, M# w) n
                mmc5.Sync( cycles );
2 s) o( Y1 j* `: x        }" ?. L% l+ T, v5 R
}
: v; f8 J2 `' O) g* e5 h: D
8 n- K$ b) X; t6 e/ _2 }0 Nvoid        APU::WriteProcess( WORD addr, BYTE data ); f% g  B8 \& K0 z# r
{
7 W" d: h" R( E( V: h        // $4018偼VirtuaNES屌桳億乕僩8 k& ^6 k. n' U
        if( addr >= 0x4000 && addr <= 0x401F ) {
3 ?# \# H. Z, _$ `                internal.Write( addr, data );
. l9 A+ y0 [9 o& G! z: C- n        }( n, k  o, F: f$ d/ e1 c0 E
}) h( k( P2 {* g& T; L& b' U
# _* l( Y2 k" W" s
void        APU::WriteExProcess( WORD addr, BYTE data )
) X+ X! d. z/ N$ l* y+ y{; G* C" r2 _- q3 m+ Z$ k- c
        if( exsound_select & 0x01 ) {
) g0 e. Y  Z# r0 V                vrc6.Write( addr, data );
* L9 P$ G# K7 [+ c, x        }
7 L+ v/ B4 @% `: z% H        if( exsound_select & 0x02 ) {% E' a& G# I7 @6 a1 Z3 `% z
                vrc7.Write( addr, data );
/ A+ K7 O, D* Z        }7 X1 A, L$ h2 c' i( E  @2 y
        if( exsound_select & 0x04 ) {
& I  w$ Q$ W* h7 H" n                fds.Write( addr, data );
& z1 E7 w' q9 a# O; p        }
+ S8 Y. q0 w  y9 S9 b        if( exsound_select & 0x08 ) {. S3 r4 H: D+ c0 s* k
                mmc5.Write( addr, data );
) B+ ]) O! Z0 H  P" f% d        }$ I/ {& G! ]8 |
        if( exsound_select & 0x10 ) {
9 E0 Z3 H* P; c0 @) V5 J3 D                if( addr == 0x0000 ) {
) c  L0 G) M/ b7 F% o& Y: k+ m: @                        BYTE        dummy = n106.Read( addr );/ o# Q; Z( |! B6 l. G3 d: \
                } else {
( [. ?8 n6 @# b; r9 `9 F0 C% U8 i; l                        n106.Write( addr, data );
1 A+ y) }0 w* u, M0 W                }
, s3 R. J1 J( E, Z4 _        }2 q5 F1 X! J. f5 G0 w9 B
        if( exsound_select & 0x20 ) {
' \. S8 y# o, h% B. |/ |* @/ [2 |                fme7.Write( addr, data );
9 `- O8 N8 v- s9 H5 w: V        }4 r1 ]9 k& L3 w3 Q7 N) Y3 J
}
) r! c' V" F1 q* Y: p  P/ r& ~5 B+ `9 Y8 ]; B: T( L
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
4 D7 {+ m* D5 o3 G{
# E5 c0 m7 s( w( E5 P# {( vINT        nBits = Config.sound.nBits;
; W: ^& n1 Q; ^  h- {) R2 \DWORD        dwLength = dwSize / (nBits/8);5 p4 M  i4 T1 m) _) t% k. y
INT        output;
4 F, J$ t( p& e% MQUEUEDATA q;% ]  m# x$ g  w4 e2 K) B, b
DWORD        writetime;
7 |, p7 m3 e% P( a0 ^
+ \% G1 R4 }5 C) h0 j/ V& rLPSHORT        pSoundBuf = m_SoundBuffer;9 E( q5 J; @  a# T7 i5 k( m
INT        nCcount = 0;
- Z1 |- T2 c. l/ I; I
8 k8 v0 i2 k. N% Q. cINT        nFilterType = Config.sound.nFilterType;! i( v% P3 B* `% M

5 c# d# b, Q0 b        if( !Config.sound.bEnable ) {4 E  [( S8 y2 u2 f# y
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );: G7 ]/ p/ g& E7 V2 t5 m0 R$ f" Q
                return;
" t: L5 w# q7 f+ ^5 c3 ^' e7 y        }0 P0 M. T) \) c" k5 I1 T
9 H5 K( L0 c  E( a" H
        // Volume setup5 M( q3 E8 G1 b7 Q% U( U* c
        //  0:Master, H" W) f3 G* x/ o+ l  H
        //  1:Rectangle 1
5 o# `( I$ o  B, A3 p# O4 A        //  2:Rectangle 2
& h! p! S3 n" v        //  3:Triangle$ ^  L+ B) S' `" U
        //  4:Noise: }) i4 f0 |' n( g& x
        //  5:DPCM
2 S7 {- S/ L& @$ p$ Q4 l        //  6:VRC6$ E7 M3 W1 r$ R
        //  7:VRC7
6 Z0 D4 J3 B) G, ^7 V& c        //  8:FDS$ W8 k9 G( ~# Y  _
        //  9:MMC58 e# k  _, s9 \- v6 W6 Z6 B
        // 10:N106
/ i" `) q# Y; _2 O        // 11:FME7
9 @* e9 B6 [/ d        INT        vol[24];
: K( F4 U- _: k$ y        BOOL*        bMute = m_bMute;, H' y& M: h8 d8 c5 Y! c1 O1 A' f
        SHORT*        nVolume = Config.sound.nVolume;
5 N- a, u. u+ L% `0 b% U& k
" C# t5 w# Z+ C( ?$ p        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
5 E8 h* N' w/ r6 A  {+ g  d
' S9 @+ p% v3 v; g6 r2 g        // Internal* D$ K* s" i8 p6 E  b
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;6 \' [: L# ?, k( Q7 Y
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
3 P" q# `6 h8 V9 F7 H        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
$ {" v! P' D" t7 G+ z- A        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;0 P2 B- }, d0 F5 i$ S
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
, E9 l$ e3 a& f2 j& @; F, Y. r* K0 d6 D( P' F0 }
        // VRC6
7 }8 s5 \/ c5 T5 Q! s+ Z        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
0 W% i) c. k( K        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;' K0 A0 U2 R. ~7 D, q6 J
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;- l$ y3 O6 F) z! W& h( p
1 t  J2 d5 D2 E0 G" k
        // VRC7
9 X/ f5 `5 d* I! e! f        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;9 ^7 F: t! i- K5 F& Z7 Y4 c8 }3 `0 G
; _( D1 |5 s/ [. Q$ g) K
        // FDS
) U. [! L! `; `8 B        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;/ k% D! \) l. D7 ?( C- Q) l
8 q7 z7 ^- X' C: J, ?
        // MMC5' P8 r( G4 o' \) T1 Q3 I
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
! w; ?' {2 x8 q$ q& J1 S% c        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
7 |( ^! d9 o  U6 Z# \2 d        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;5 m  L7 t$ [* ^! ^" k( `  y
9 I$ ^1 J) r) r0 W7 s% X9 r3 |
        // N106
3 _: ], z0 I  L( s        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
  s* q" @7 f% q2 O/ w        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;1 X$ ~4 `/ X# S5 Y& F; j$ H
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& d' [' Y' Z& O5 s7 a: v9 Q        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
) [5 H/ m5 p0 I1 j6 g; B7 p4 [        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
8 j: }3 \$ k+ h' C5 b$ C        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
8 d7 _* D4 q8 F# P  ?        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 q0 q* o$ T! z9 J3 D* l1 h
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: S" v3 z8 P& U# [6 M2 x3 W- o- e' p1 D
        // FME7
# A- Q0 ?0 c/ U6 z* R        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;5 `. @1 u# o! ^% E; H- W
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;6 K# {+ s1 B5 j4 I
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
- F! z) ^$ M/ Q) C: N# J
# _; i. |+ U! i9 k$ e//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;& Q5 g  X( c5 [- m+ ~6 p% C; F5 X
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
* X, `7 b/ s5 [5 {$ D1 [
8 }, Z- h% U" D6 o% S3 Q6 t! R5 F        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟6 M3 ]/ _# k" v3 L1 ]* N
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
1 W" r; b# r9 l9 u: ?                QueueFlush();
) @4 F* M: Q- j7 N3 y) Y8 V        }  w& \& H# N# \2 T1 a) J% d' R& G
5 G: k& j8 z; a( G  D* F
        while( dwLength-- ) {
7 }6 C2 ~% _! ]0 e2 w1 [                writetime = (DWORD)elapsed_time;. V. b: q- P; w  \5 M6 z  w
' y$ I8 C% B' g3 Z2 S, B
                while( GetQueue( writetime, q ) ) {
& e- [% y5 D& j+ i: A                        WriteProcess( q.addr, q.data );9 Y* e; B: K& K  m# r
                }$ ]- ?5 C5 H# S' ^- P/ k
- V% p0 c( Z1 o3 J: P% s
                while( GetExQueue( writetime, q ) ) {
, R. H. Z) g/ {$ R, x4 j3 y                        WriteExProcess( q.addr, q.data );" d: K* ~: i$ j, i
                }
8 ~0 O+ Z' C9 M1 k; l( Z' @7 U* H% D/ n) `
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7( G4 g3 M: q7 t7 F, }- Q3 t8 t
                output = 0;, r) I! T/ M5 X$ U
                output += internal.Process( 0 )*vol[0];
' f2 N9 M' p4 p! h: }' _+ b- @                output += internal.Process( 1 )*vol[1];
0 W3 D6 V2 n9 U* ~9 P                output += internal.Process( 2 )*vol[2];* W' k' r; t# `+ T& s. _$ `
                output += internal.Process( 3 )*vol[3];9 N& _# Q; q) M! B( r& {1 D
                output += internal.Process( 4 )*vol[4];
% B7 M. B7 Y# r  a5 e& Z2 v
/ i: }% z. m& L# }# U                if( exsound_select & 0x01 ) {6 E6 d) o; g7 E  }# w. E! K7 R- \
                        output += vrc6.Process( 0 )*vol[5];
+ s# _1 e" ]7 n: \! z0 F/ Q2 v                        output += vrc6.Process( 1 )*vol[6];
( @$ Z. c# e: T0 I! m! Y- v6 G                        output += vrc6.Process( 2 )*vol[7];/ J* F, C7 m8 f2 d4 u% u7 b
                }! N( v2 m1 N- R7 T4 y9 R
                if( exsound_select & 0x02 ) {2 \6 i' E) M+ i  ~
                        output += vrc7.Process( 0 )*vol[8];
# Q. `# V0 U2 ^1 R% f* h* O% V                }
% {& Q/ A/ J5 q1 S: p: |+ ?! ~* f; F                if( exsound_select & 0x04 ) {
( w: {# x9 D* ]7 E0 w                        output += fds.Process( 0 )*vol[9];
" V' ^8 d4 W6 _) }                }
# ^, M+ W6 k$ j* Y4 [$ i9 g* W                if( exsound_select & 0x08 ) {9 A5 y7 d# P1 @* H3 I" X) Y
                        output += mmc5.Process( 0 )*vol[10];3 ~4 e& \3 p' K6 l8 k
                        output += mmc5.Process( 1 )*vol[11];* w; p( Y- H) e! ?$ c% n
                        output += mmc5.Process( 2 )*vol[12];( K9 Y, `0 X! e/ Y
                }$ Z6 y4 R/ x, p0 b+ t
                if( exsound_select & 0x10 ) {
, G! n% ?7 |) d. i                        output += n106.Process( 0 )*vol[13];" K4 @& L& I( c; J+ O! u
                        output += n106.Process( 1 )*vol[14];+ m* ?( ~: S8 ?6 O( a  N# z
                        output += n106.Process( 2 )*vol[15];  h( G2 n1 }+ a/ ^- U/ j( m
                        output += n106.Process( 3 )*vol[16];! w+ H& E) d* T5 @( M; u
                        output += n106.Process( 4 )*vol[17];% E, w* Y. M) W
                        output += n106.Process( 5 )*vol[18];
4 R" ~, @) D' c' }0 B                        output += n106.Process( 6 )*vol[19];
: t# X7 R7 Z4 _  A                        output += n106.Process( 7 )*vol[20];$ u& O+ ^& a( B0 \* \0 Y3 d
                }; ?2 `! v& E# w- q0 `! t. n; Q& ]
                if( exsound_select & 0x20 ) {9 W1 l* L; E2 E( G# A/ v
                        fme7.Process( 3 );        // Envelope & Noise! T  N/ }4 d3 l- I) t- W) ^
                        output += fme7.Process( 0 )*vol[21];
8 h5 p6 h+ |0 c" M. `; `9 K" G                        output += fme7.Process( 1 )*vol[22];3 C! @8 ~3 {% x% }0 \! v
                        output += fme7.Process( 2 )*vol[23];; L( H! L  E, g$ R+ a6 z, C4 X
                }. s/ q+ D2 l9 [

6 J4 `( ?7 E% E                output >>= 8;
- R, O$ q( S5 W* `2 I& C$ l$ P/ K  R$ ]' K# A3 j
                if( nFilterType == 1 ) {, @' _) {# \+ Z
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)7 t2 |: C( |4 k" n, |
                        output = (lowpass_filter[0]+output)/2;( s# g+ g, W2 l1 o7 [
                        lowpass_filter[0] = output;
, b3 [: ], V' J' y- @                } else if( nFilterType == 2 ) {2 M0 \; [  q3 P: B/ _' ?3 c) w! Z& r
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)$ }7 x9 H8 k- z
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
/ m  ], E" F% |. y* j  I$ [2 E) J                        lowpass_filter[1] = lowpass_filter[0];
  Y' ^" R- K% }0 p& [                        lowpass_filter[0] = output;+ P6 ~0 v1 R0 S. U2 V
                } else if( nFilterType == 3 ) {
7 `5 ]) d: O# S                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
! @- ~% y+ P9 E2 `% m* b                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;  B( K. m7 u* K* @2 L* j  s
                        lowpass_filter[2] = lowpass_filter[1];
0 M9 u. ]! d8 y                        lowpass_filter[1] = lowpass_filter[0];
6 @1 r$ W, }8 l0 X* V$ Q) R! Y. s                        lowpass_filter[0] = output;4 J' Z# J4 ]# h! K2 g
                } else if( nFilterType == 4 ) {/ n/ W/ V" ~0 A) D* c
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)4 X3 }( `% I1 {+ G, _& Q  h" j
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;& n6 Z7 G3 B2 r' R9 _6 k
                        lowpass_filter[1] = lowpass_filter[0];' K/ g, Q, D' |0 l  g
                        lowpass_filter[0] = output;
! z) e. K1 ]; F9 S, l. R                }
+ z* x7 {" C- ?$ u7 `9 Q# p! }/ S  W$ N6 ]4 T4 _
#if        0
- a& L$ ?1 Q  a; h' @                // DC惉暘偺僇僢僩
; T* W  {( Z  }( [$ P                {; r' @4 Q1 L* F$ d8 _1 k
                static double ave = 0.0, max=0.0, min=0.0;; T4 }" A# u' I
                double delta;
4 c6 |. s  i0 A% ]' Z                delta = (max-min)/32768.0;
5 q, E1 D) \' i                max -= delta;/ c% l) g* c$ z0 ]& f+ S
                min += delta;0 ?0 X/ K+ V' g4 d0 ?
                if( output > max ) max = output;
' U% a) A+ c: g5 o  Z! n                if( output < min ) min = output;
  O5 w8 y; F* ]& S                ave -= ave/1024.0;/ R" S! R0 d. ]1 X: o' L
                ave += (max+min)/2048.0;
. n3 G+ `  z. H" U1 I! p                output -= (INT)ave;) I2 ^  W2 \' A$ N7 a# ]: D' i( d
                }
9 Q7 J# A# o2 ], r" d1 ^6 V#endif0 T" K1 i' {" \, M' p  Q4 N6 ?
#if        17 z9 B2 G/ F6 ?+ B3 A$ b2 `
                // DC惉暘偺僇僢僩(HPF TEST)
) z/ w6 ?1 [; ], h" Y8 @                {
0 L+ [% J) |3 j2 h4 G5 V; ^- `//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
9 Q& i) [  p4 S                static        double        cutofftemp = (2.0*3.141592653579*40.0);$ |/ q/ B- {& O2 a  j+ a
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
% y& h2 _* J3 F: y; K% e8 x6 X# v7 v                static        double        tmp = 0.0;
* i- x6 [9 w0 y( B8 I6 L                double        in, out;8 c0 G; V" s- E4 N
2 u5 [+ ^8 t: r& U- j
                in = (double)output;/ P2 u! b' M) \4 ]
                out = (in - tmp);
& r. k1 h9 g' c; }4 [! h                tmp = tmp + cutoff * out;& C. A6 _, H! o" s. l  j1 B7 c
! p' f& O2 {* p
                output = (INT)out;& t* b9 X3 @. o: _
                }$ e1 R, y( o& |+ y1 @0 b
#endif$ \! F+ V+ f" b$ v
#if        0
/ _/ H3 N7 S; y5 ^! b                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)) a3 H6 g5 H. [$ [4 ?0 ^2 N, P3 G1 L
                {
; ~9 _2 x- K0 Q7 [& w( ?$ Y- w                INT        diff = abs(output-last_data);0 m3 }. H5 N( e* L: r# K7 a
                if( diff > 0x4000 ) {5 e4 C2 t8 i0 L8 k
                        output /= 4;
# U; E6 X  V  f; ?: k                } else
0 _) j( U; @. \4 `6 g7 ]                if( diff > 0x3000 ) {
9 z' \2 T0 C& K$ T. z( r                        output /= 3;0 `6 b- z( o1 K8 b9 y! A
                } else
/ C' k! n$ g. P6 K. b                if( diff > 0x2000 ) {
5 ]% S# P/ _6 Y& |                        output /= 2;
0 e$ ]8 W/ v" K$ }                }
8 F' v. @1 X  z$ h: ^& }! [                last_data = output;, [5 `- w% x3 m6 q) N! D/ l9 @
                }, C6 H1 A9 C/ X
#endif
8 [. R( f9 \; v# C0 w# u                // Limit
& d- c) G9 Z. V1 f. S$ l3 L# e* A                if( output > 0x7FFF ) {# X* k  R) [1 d/ a) p% J2 y! f- a3 H
                        output = 0x7FFF;
+ y( C% d9 w* x" R- F) x3 o                } else if( output < -0x8000 ) {
  R* n2 F+ g0 N; g1 l                        output = -0x8000;
9 O* W* S5 u5 `' Q+ X                }
) [# y4 K* U7 v
. t) s2 ^# D/ W+ H9 ]' m                if( nBits != 8 ) {( [  n6 C' b* k, L
                        *(SHORT*)lpBuffer = (SHORT)output;
$ @6 P  v: U; W2 B9 i' u                        lpBuffer += sizeof(SHORT);9 [6 @, _, W; U1 Z5 F1 a
                } else {
* p, g; _, b3 j$ P                        *lpBuffer++ = (output>>8)^0x80;, x. d9 }+ ]7 Q, R) h
                }$ |! _( e" S! p  O' J

, z% R. T. J8 S8 o$ X0 X4 a  {                if( nCcount < 0x0100 )
( l, {  K% s9 |& \# F                        pSoundBuf[nCcount++] = (SHORT)output;( h8 S0 N7 k9 P
0 ]$ B$ A9 \1 p3 E7 z, R8 y
//                elapsedtime += cycle_rate;
0 S) C4 y# e9 P6 _                elapsed_time += cycle_rate;0 ]$ N6 o/ {! t8 o' L
        }
- W2 X% I( o; B# T; }/ b/ _3 m6 v4 Y: u8 j9 B- J; |  G/ u! W( M
#if        1% X3 U: |: C+ H/ u2 l( v! l; r, j
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {" g+ |$ m8 z0 W3 a0 O
                elapsed_time = nes->cpu->GetTotalCycles();7 J4 B: F# r4 ~! m( t& ^
        }1 ~0 [" _  x# j4 _
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {! K9 {" Z- z. O
                elapsed_time = nes->cpu->GetTotalCycles();" C) C# v" w6 y/ ?/ P' H3 @" X
        }
' `$ u8 s0 ?+ C7 r2 R  \# N0 S- {! \#else0 x# K" ]+ G% m2 Q  C
        elapsed_time = nes->cpu->GetTotalCycles();- w8 Q! Y% }2 n) A3 ?# M/ J0 I1 l3 F
#endif
! i" w5 v7 W9 ~! q3 ]' H4 q}
* S% q0 F$ N6 I8 J: c: M
1 {, A0 ~4 \) O" q6 a5 k6 E// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
; n3 x( _. p! oINT        APU::GetChannelFrequency( INT no )
5 l# q0 |$ R- {* ^0 a; o" E{5 i- J- L" V: o( x# t$ k7 L. V
        if( !m_bMute[0] )/ a; D% Z2 v4 K% d$ M
                return        0;- k9 }& M; A( Q2 p  D% y! g$ r
4 w) F" H0 f$ o$ X! S
        // Internal
9 I! t- x$ b2 M5 E; I+ ]        if( no < 5 ) {9 s8 X1 @0 w9 [) {% a, Y
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
) O& S$ P" Q) X% i2 S; R" ]        }6 X8 \0 Q1 b; t! K$ Y5 w
        // VRC63 q8 N, s* [4 [# ^7 g. y2 I
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
: G9 N9 j3 M5 H! p( ?$ ~' d* W                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;5 Y! Q7 B3 o5 _4 w
        }
0 \3 S* @3 u1 }        // FDS
$ `' ^& L- g. A$ ]2 o7 R4 t        if( (exsound_select & 0x04) && no == 0x300 ) {
+ S, K; o; t" ^  G9 E                return        m_bMute[6]?fds.GetFreq( 0 ):0;2 n7 d$ o/ J: j! ?
        }
8 ^5 v  g; g  P% @1 f1 l& I* J        // MMC52 I6 y0 D3 J3 G3 O& U, n- S+ }
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {+ L9 v* V% k1 t# A6 `5 g
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;! s  U1 D% g2 M( b& D
        }, X; l7 O- ]# F
        // N106# u. G' I% ~/ Q! \9 V0 H
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {! L2 W' g" n) S0 N3 B: y& d4 t
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
" U6 u' g1 D! U  W        }
9 ?) s! s$ P# r1 n( c6 ^        // FME7/ t- Q3 L; o) B* M3 g, x6 \, }
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {  w9 f7 W0 H) Q1 q- O/ e' z" {( d' z. q
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
; G1 ~# W3 [) y/ q. ?        }
0 I1 I& _) ?2 }* _1 J& n        // VRC7$ U" @: R/ r5 N
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
, N# }, W9 Z3 x. t* A0 |# g                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
" |2 }: E/ b' x2 P/ J8 z8 h8 O+ x8 c        }. z& `' B9 a7 ~. ^' ~( c; C
        return        0;
) Z" Z; T9 l) |- e7 e' t8 l9 @) C}
5 M" G) |% R. H+ j2 t6 ]7 H5 w( m- H
// State Save/Load% U. r( u5 |; e2 \8 r7 y, F- L6 {
void        APU::SaveState( LPBYTE p )
5 U2 j4 m- A. a{
3 T' E3 I8 t; B4 r2 g#ifdef        _DEBUG( F9 K+ P$ o5 f1 D! U
LPBYTE        pold = p;" c, a! j3 S7 y" h
#endif
1 d" e* m2 G, \. H
. v$ o1 ]2 m: Y$ k0 {        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞  a! D; R0 M. ~7 x9 T' v
        QueueFlush();3 p, Y( M( G: e. ?
# G' |; V5 Q/ e) y7 e
        internal.SaveState( p );  P& o( Z2 f) h& O. p
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
; `4 M3 M$ w5 i+ X: O3 T( [
8 p8 l0 o2 u# w$ {        // VRC6
" x2 K8 |7 E4 V) z8 P, m! B& @        if( exsound_select & 0x01 ) {3 x  Z2 _! G- t1 Y
                vrc6.SaveState( p );
  P5 ?6 |: m4 V: J* ~: m                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
4 E7 S+ v" ]* I, @        }
& |$ M5 ?, K+ `# F! d: }6 c4 K$ ^9 j        // VRC7 (not support)3 @. i' J8 T/ m" Y. v8 F' G% W
        if( exsound_select & 0x02 ) {2 H" I# z' j% M9 v( T+ c
                vrc7.SaveState( p );: u- i+ t$ {$ c
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
6 j! o; e. g  W, @" d' @' q        }# P' f- v9 w3 w7 T
        // FDS
$ q' M5 z- R# T, l9 [        if( exsound_select & 0x04 ) {, ?" U# H; `9 ]- t$ c5 E; E, X: f
                fds.SaveState( p );
5 O; Z) W+ y+ q7 _+ t                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding. ^9 U  x0 F9 C7 m
        }; f! i- f4 ^) H5 r9 {2 B% [$ T: Q7 R
        // MMC5+ c# m6 j2 w5 l) x( m+ k. W
        if( exsound_select & 0x08 ) {
) l1 c3 d9 x( B                mmc5.SaveState( p );* M4 O( \6 }- g6 `
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding, O. `6 d8 i  y: t& Z6 W. F$ E
        }
( L5 d/ l" H: j5 a& g        // N106
+ N6 E8 t+ M1 e2 k        if( exsound_select & 0x10 ) {2 t4 \1 J8 [! V9 R7 A  k- F
                n106.SaveState( p );4 a) z7 s$ {8 u/ i' i
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
. _) s4 ?$ \7 U% v        }
5 ?( W; V! _" O% W  _  ^0 t" ^        // FME7
; A( C$ p; z6 H# L, x3 p5 h        if( exsound_select & 0x20 ) {
  Y0 S/ K* {; V. F+ I                fme7.SaveState( p );
& l7 f5 _% [+ h0 e3 o# j$ e( O8 p4 y+ o                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
- z- G0 f" X/ C        }
: \* O9 p3 z9 e3 f
, _6 L8 l  e$ P( D/ {#ifdef        _DEBUG
+ f) P1 Z7 I( x6 dDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );& O2 x5 J4 v1 Z' V
#endif% U: q9 D$ E2 _
}$ F' v+ T2 ~$ ^( v! ^
4 ]- x3 S9 {' M6 J- j& L% I( R
void        APU::LoadState( LPBYTE p )
% s4 m# Y2 j/ A* R  T{2 L! T$ s3 C: m4 j, q6 c4 Z
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡) r' l1 a+ J6 n, Z# K# Q% R
        QueueClear();4 s5 ?. _; u/ {7 X' v" k

# m& X9 U0 \' F7 W5 k5 E4 c; a$ S, E        internal.LoadState( p );
  p4 ^- q+ O- ]8 S- p, a        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding8 |, s$ V* \, n! ~( @* T# A7 p! }% K

- x3 m& Z8 Q7 Q        // VRC64 O0 L: h6 Z2 b' X/ j2 p& b
        if( exsound_select & 0x01 ) {0 g* s# \/ h1 O5 V; {6 |  ?& R
                vrc6.LoadState( p );
1 x( C! W9 y, e8 x                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
% m2 Y5 F* u( _/ o$ f2 B        }  A7 j4 V9 {0 j, H! g  l4 h
        // VRC7 (not support)
" x3 H- c) w. T        if( exsound_select & 0x02 ) {  `5 Q9 ~5 U9 q
                vrc7.LoadState( p );% A% P5 J6 z* }* O) O/ g' k6 ]
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding0 W% t/ V- u1 t
        }
# E' d; s* T: s8 S        // FDS
  o, J$ ]- \/ @, e: f        if( exsound_select & 0x04 ) {
  _& w% w/ L6 D$ E0 p                fds.LoadState( p );
$ V: b. Q, V1 f) w6 w                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding, {. V7 z! i/ [$ J
        }4 v/ y% D. q' y6 @
        // MMC5
5 S! ^0 W* _' m        if( exsound_select & 0x08 ) {, ~6 x  R5 ]/ O# v# }  G, Z
                mmc5.LoadState( p );
9 q4 H6 H- A% ], D% y& ^3 w                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
7 G* U; B' z" {4 S& y- A        }
+ R2 P* X& G; q4 ^        // N106
' \/ s: C+ |4 z2 @  Y        if( exsound_select & 0x10 ) {) z$ X$ o5 W( M4 Z; H; U7 b3 i. f
                n106.LoadState( p );
1 L0 W, q9 j7 I8 [3 E                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding6 G+ [* A+ N9 N: R0 ^
        }4 Y. x( _8 t$ L2 N; q
        // FME7
: K1 G, V8 l* g) Q        if( exsound_select & 0x20 ) {
, L# D9 W( C- H: n& u                fme7.LoadState( p );: w2 H, ^" H( m* q
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding$ I$ M3 f9 F. T5 h6 c# P: c% P
        }+ e6 Y. c1 d; d) W9 @6 ?# y
}
回复

使用道具 举报

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 0 P' `  W; R* C! S
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。; _. G+ G& g6 P6 M+ c
感激不尽~~
* E9 r0 @7 o: l1 d9 N: ]# Z
恩 我對模擬器不是很有研究,
+ T2 `4 C& W7 I5 N雖然要了解源碼內容,可能不是很困難,
$ P7 M$ }, G+ H! l6 E4 S不過還是要花時間,個人目前蠻忙碌的。! m- v; L4 F& c( t

! p, c; \% K0 X- W) I' x給你一個朋友的MSN,你可以跟他討論看看,
' `. \' p( W" e. Q7 ?0 W9 u+ C他本身是程式設計師,也對FC模擬器很有興趣。
* S6 q! j& F7 `6 F
+ L2 s, s6 F( T. IMSN我就PM到你的信箱了。
' l8 t( D/ c# G2 ~  Y; l$ w
1 S( M: @- o/ A, @希望你能有所得。
回复

使用道具 举报

该用户从未签到

 楼主| 发表于 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 发表
  W$ K+ H1 l$ G8 |7 K3 G: x$ O呵…… 谢过团长大人~~

4 x+ D6 C1 ?9 m- n4 t
: Q( v0 q3 h. X" \- o8 C哈 不客氣,算是順便幫他找個伴,大家可以一起玩。
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 * h( H' m" {) z3 J7 m4 b. N/ B
团长的朋友都是神,那团长就是神的boss。

: \* K2 o' S7 `; ~1 Z哈 不敢當,我只是個平凡人,1 g; P6 U" r4 k% N' S5 L
要吃飯喝水,光吸空氣是不會飽的。。。。 :)
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
# k' Q3 U% w1 I. Y* `9 X" rZYH( M/ m0 L  I4 A0 a" c
QQ:414734306
  e% F) j/ c& a; }  N" Y$ U/ G, yMail:zyh-01@126.com
  e$ @) X3 y, e/ Z6 \0 i# L3 ]1 E' i: U% `6 n
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
( ^6 E! }+ ?& D) b# m; c1 y再次对团长大人和悠悠哥的无私帮助表示感谢~~
, I9 C6 y7 K  g, f9 Z
不客氣  ^_^
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-8-5 09:32

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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