EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
4 f0 w3 e, S% @) `楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~% s" G& ]7 t9 q* k: s3 N8 V* y( c
这里有相应的模拟器源码,就当送给大侠了~~7 z$ @5 }" E/ t: L: f
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 0 `/ o# P7 U  y+ N5 ~6 T( Z
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。4 L' `. t0 D; l
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
7 s% G6 Y0 a/ W这里有相应的模拟器源码,就当送给大侠 ...

! K; E; }  e0 Q8 Q聲音部分(Audoi Process Unit = APU):
6 S- C  ?8 x' `8 I.\NES\APU.cpp
6 `6 A: ^8 ?* {4 E) L2 e.\NES\APU.h
" ]" p6 i5 T. Q
7 q8 h$ q4 o! B* d! _9 z$ D6 X9 `* B; a' ]9 l6 v' T
影像處理部份(Picture Processing Unit = PPU):0 ]( }) x, N7 q$ _- u. {
.\NES\PPU.cpp& Q; i* s- z: ?+ s/ r
.\NES\PPU.h6 E) F/ F  s& d, j
+ {2 p6 b! \' \1 ^& ?1 g& a
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
* _% H3 g' {+ I3 a/ l, M(由于很多专用术语和算法机理都不明白,所以看不大懂……). ]$ s" P4 F. L2 [' c1 D
//////////////////////////////////////////////////////////////////////////+ p2 G( u/ L2 d- s
//                                                                      //
5 s1 r) i" y, }4 }//      NES APU core                                                    //
' B7 O& D6 A+ t& ?//                                                           Norix      /// M2 M  C1 i, w6 j; a4 M
//                                               written     2002/06/27 //
: e& [) g+ s) y& g8 s( Q7 i//                                               last modify ----/--/-- //! [! K6 }  w0 ~6 \8 n
//////////////////////////////////////////////////////////////////////////
$ D8 ?/ C# e4 a" V#include "DebugOut.h"
5 J0 ^8 Y% E' ~5 |#include "App.h"* c$ T4 z" D& J# ?: \) R$ V
#include "Config.h"7 X" S7 g+ V/ N& {) W; i  B

( w# Q( y+ t. L8 D#include "nes.h". ?, S( V, A' ^
#include "mmu.h"
4 v. u* b$ a) L  \. F& J#include "cpu.h"
9 h2 o1 [2 K% }) f#include "ppu.h"" y- Y) L: u8 ?5 i. x2 v
#include "rom.h", Q. Q  u- y, D
#include "apu.h"
6 a" M; b5 r0 L7 p: {! A3 ~2 Z
2 _0 x. s5 @& _" B$ d// Volume adjust( G2 c1 U, W$ Y# t1 q( {
// Internal sounds4 B" j) `2 u# r1 n3 j+ J4 u* w; F* Q
#define        RECTANGLE_VOL        (0x0F0)& P6 d8 [$ F1 y- Z
#define        TRIANGLE_VOL        (0x130)
9 O) b5 s  o6 N: C#define        NOISE_VOL        (0x0C0)
  z# S% h+ o" {+ s7 t; T8 ~6 G  J#define        DPCM_VOL        (0x0F0)
3 E$ Q1 R: [! L; g// Extra sounds
) ^, i" l% ?0 N) _! E0 b8 v#define        VRC6_VOL        (0x0F0)
* |+ h/ v1 q2 p0 i( M2 n" w#define        VRC7_VOL        (0x130)
% b* |& R1 V5 Q5 ?8 L( n* J) C#define        FDS_VOL                (0x0F0)7 D) d; l4 g0 s  [6 Q
#define        MMC5_VOL        (0x0F0)
- T( R2 I! A8 a9 f8 T#define        N106_VOL        (0x088)- X. M9 f# }2 P- W
#define        FME7_VOL        (0x130)
' z5 D! Q3 }, D
0 l. O4 b" b  O$ u$ b6 ?& C: y7 mAPU::APU( NES* parent )( q3 W) o5 t/ D* ^& U8 Q; |
{
5 l8 _9 o% ~9 @% n. E: q/ v        exsound_select = 0;9 P$ f9 d! B% [+ Z( }3 h8 ]  O/ L% y

  ]2 @. D. |% ]4 C  s        nes = parent;
6 V6 `* \3 p4 v! c9 q, ]8 ]. c        internal.SetParent( parent );
) i, `/ I, m, C6 Y9 G9 a* h4 ~7 b' D8 b
        last_data = last_diff = 0;
1 L, F( j  o4 `  n9 f: N
6 ^( O( `) q5 w1 z4 R% E        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );3 h' G: @2 B  ]- u9 R4 B
# y7 }5 i5 {  i/ U
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );, @4 L+ O9 A" E. S6 j
        ZEROMEMORY( &queue, sizeof(queue) );  Q6 s! C" A; c: C
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
8 B1 O$ V7 H1 E/ z( N* p
9 a0 C! s4 n3 F/ ]& L8 N/ [; U        for( INT i = 0; i < 16; i++ ) {
& `* |$ ~( k7 \2 Y' `% N                m_bMute = TRUE;. j: x& m' p$ H  k  i
        }
4 i0 ]- o3 d5 e, I$ C}
/ H* p7 t! S: R( U' k2 n: h* {3 T% f- \8 d3 R
APU::~APU()
3 X4 \' s$ q# f; T% V{
+ m5 i+ q4 W6 }& r, r}
! p/ ]* ]( E' g( ~4 c2 i2 o/ O. L  c; Q* [# H- N# W( v6 w
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )" |6 S+ {4 I+ y; x; M  p- Z$ H- T5 q
{0 T  H2 w" E- K6 ~$ l3 h9 o, m, y
        queue.data[queue.wrptr].time = writetime;) I0 ^9 p! O% I, F2 o
        queue.data[queue.wrptr].addr = addr;
6 S1 l. }/ o# v+ j- J1 v/ x1 q        queue.data[queue.wrptr].data = data;/ V+ n1 t$ O8 F: \: y2 A
        queue.wrptr++;
3 |$ t5 _" B! _" i9 A) ]        queue.wrptr&=QUEUE_LENGTH-1;2 w9 C1 V; |6 U; M0 Y( h7 F
        if( queue.wrptr == queue.rdptr ) {/ P- X/ O6 H$ k( q6 T
                DEBUGOUT( "queue overflow.\n" );" W% Z/ j' D; B4 Z# F
        }3 I/ x/ S5 O7 b: T% M6 t" g
}0 H4 X& y0 t! Z% F, ~% N: v

6 n( a7 l* Y) ^" s: }3 c' L3 TBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
8 l. O) M% F, {! E# g' ^' l{7 r. p' ]) v/ c1 g3 h+ Z
        if( queue.wrptr == queue.rdptr ) {
/ }1 Y# T3 R0 }$ k                return        FALSE;( k% `- J5 W2 ^% G; Q
        }
; M/ N. K+ f8 g4 P$ K        if( queue.data[queue.rdptr].time <= writetime ) {
9 O' V9 ]' s& j& e' S5 B# {                ret = queue.data[queue.rdptr];
8 p7 `5 v# q  P3 g9 A, [5 _                queue.rdptr++;# v. l* E/ o, s# s. T
                queue.rdptr&=QUEUE_LENGTH-1;
/ x; |4 ]( P% w& v0 ^! h( p                return        TRUE;& O( N! `# Z. K* s6 r7 I5 c8 z% `) C
        }6 e; b. h1 b( U) F" X
        return        FALSE;. X  N  X& X* `4 C
}3 @) k1 c' X9 Z# k: ~
* C& p9 j' L5 L% x
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )* Y, V  l: E. ?' d: p
{
- u, k( n, J3 O) y' O+ v0 N& W        exqueue.data[exqueue.wrptr].time = writetime;
5 h/ |( S( [( U% z/ O        exqueue.data[exqueue.wrptr].addr = addr;) G4 M6 S" r0 o/ A
        exqueue.data[exqueue.wrptr].data = data;1 O. C7 Z3 m6 a4 G  G
        exqueue.wrptr++;
4 J7 `$ t- }  G! s: O* C( ?! ]% U. b        exqueue.wrptr&=QUEUE_LENGTH-1;3 }5 v6 S, z9 R8 B3 E
        if( exqueue.wrptr == exqueue.rdptr ) {8 e9 M1 M4 p  ]. \  e8 p, i
                DEBUGOUT( "exqueue overflow.\n" );. D4 g: I, A$ O" Q( U
        }) f6 j& N4 L- R" n! g
}
- ]! n) b% p6 }2 L" B$ y: g# a; ~" L# B2 G( k7 A3 s
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )& c5 Z, }2 n; W: R( e9 |
{! q* q2 m8 w- a7 }; I! e
        if( exqueue.wrptr == exqueue.rdptr ) {
* P! U! Z! A  z- Q. f1 K& t) ^                return        FALSE;
9 B4 _" W9 `0 x* _* S        }
- j. V0 ?+ O" D- K# Y; J        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
+ l, U8 j6 B9 N6 p+ m                ret = exqueue.data[exqueue.rdptr];
: m9 f+ |4 Q$ C* M" l                exqueue.rdptr++;! M) Y8 V1 k% {( y
                exqueue.rdptr&=QUEUE_LENGTH-1;
& a7 _7 Y6 w0 S( V( U. V4 G3 B  a                return        TRUE;! T( b! m7 _5 u; g8 J
        }
+ i! T: l, J  q/ R( @, B7 }3 z        return        FALSE;& r3 @% m3 f# i+ D
}
$ F9 B) I/ C: s0 U: [2 x
/ I+ d3 L# h3 vvoid        APU::QueueClear()
+ X% n* k. W4 n; n) \+ z{
4 ]( P) X( [) t3 d8 i& P        ZEROMEMORY( &queue, sizeof(queue) );+ `1 }4 p( h/ A' E$ V8 }
        ZEROMEMORY( &exqueue, sizeof(exqueue) );- R0 A1 \  `! ?6 `+ e1 k
}- \) z. t% o& c

7 H' I8 y: w1 Q% O' ]void        APU::QueueFlush()
8 U) V1 ]/ U. B" b. r) z8 X{1 j0 _) `; D* l- v" G1 v
        while( queue.wrptr != queue.rdptr ) {# u2 C6 {5 g: A( ~8 g% f, v3 B
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );9 v7 y# V7 r  F1 q. S
                queue.rdptr++;$ S* t) G, M6 T6 i- X8 I8 z$ f
                queue.rdptr&=QUEUE_LENGTH-1;
, U( j. `" v% P, f% R6 e        }
/ Z- ^4 \& ^, l6 |/ \% {" s' u3 Y. B/ W! Q1 a2 d
        while( exqueue.wrptr != exqueue.rdptr ) {
1 \1 q# J. I5 K1 S/ g                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );. W+ {+ o% h: x7 h1 m) o8 i' R( f
                exqueue.rdptr++;
0 x- n  b" {: _                exqueue.rdptr&=QUEUE_LENGTH-1;$ B' u$ g' @6 Z8 }2 t: R
        }
$ c* Q; @3 X2 q. N) m( e$ z}
: s& g& w6 G" h% z( J
+ |. F1 n; R" H" p0 {) k; Uvoid        APU::SoundSetup(): g7 i- I) A2 k6 N. l' t0 Q
{
9 X" H( N8 V0 f8 G        FLOAT        fClock = nes->nescfg->CpuClock;% K$ @( \5 H! l& H" V7 y
        INT        nRate = (INT)Config.sound.nRate;
  r, O( R/ ]  \( v2 u+ ?        internal.Setup( fClock, nRate );* L( o, N: k4 u. s# S  ^. L% Y
        vrc6.Setup( fClock, nRate );$ k: O: a9 D; T0 w5 h9 U
        vrc7.Setup( fClock, nRate );" A& C" }5 D2 S# S+ S% V2 V
        mmc5.Setup( fClock, nRate );, m. b/ Y5 l% s% ]" f
        fds.Setup ( fClock, nRate );
+ B/ C" [3 Z3 G0 i! ]        n106.Setup( fClock, nRate );) S3 ^2 F0 L" [" J$ M5 x+ m
        fme7.Setup( fClock, nRate );
1 e4 q2 W5 j  ?3 r8 h}
* I* a: k. G9 X$ i' e# P2 C' k# h+ i' b6 A9 y2 |- L- v7 }
void        APU::Reset()' r( C# c- S7 Y4 d" p
{9 g: ?- K( P' H2 z
        ZEROMEMORY( &queue, sizeof(queue) );
/ f3 s4 z: b0 l7 y7 r# e8 }8 X! j- ?        ZEROMEMORY( &exqueue, sizeof(exqueue) );
' @1 I# B8 ]2 _' S
* M6 B( S+ j# g        elapsed_time = 0;# g8 \" d+ O7 C

- K8 s% l7 y) k: U9 ^0 x        FLOAT        fClock = nes->nescfg->CpuClock;! \6 C( o: b2 B1 m. s
        INT        nRate = (INT)Config.sound.nRate;7 H. ^4 Z) U3 F7 a) T
        internal.Reset( fClock, nRate );
( E+ ^9 F8 p8 k) w8 ]        vrc6.Reset( fClock, nRate );
) F3 y- X0 Z$ h        vrc7.Reset( fClock, nRate );
6 T1 S0 g7 D- B2 s, y- ?( u        mmc5.Reset( fClock, nRate );
5 W2 L7 `' O  ]3 a; V, [        fds.Reset ( fClock, nRate );; _/ E  i5 q$ b" \( V8 X' t
        n106.Reset( fClock, nRate );+ _( h+ p7 \; u. e  U. j
        fme7.Reset( fClock, nRate );
* m+ _* f$ i- k
+ i8 {; C# X: d4 U: U        SoundSetup();  t% y, v# u( z4 f
}6 _, g- n3 ]. E
: J5 P4 Q0 m7 q) [- R0 q
void        APU::SelectExSound( BYTE data )
7 k- W3 g$ p) k9 {{5 Z6 r1 U6 K! n6 E
        exsound_select = data;
" ]6 \# W; y& R4 D}
: L6 Q, L4 |' i' p; P, d4 \: i6 z1 i& X" H
BYTE        APU::Read( WORD addr )8 s7 X+ Q8 ]( f: ^* E/ |
{- s6 k+ m9 W: n5 W
        return        internal.SyncRead( addr );
5 Z* j- E5 o5 v5 F3 d}' z9 }( D" S2 o% ^
5 ^' `( @! q6 U3 h7 m
void        APU::Write( WORD addr, BYTE data )2 U; \& q4 a" G
{8 z! }$ b! i  t2 ]
        // $4018偼VirtuaNES屌桳億乕僩
1 _0 y+ W4 T6 L7 O: ]# J        if( addr >= 0x4000 && addr <= 0x401F ) {
4 ?  @' g! r0 a) }                internal.SyncWrite( addr, data );0 B+ |8 d* V# x  E0 `% j5 Q9 D& v
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );) V! H( y' s8 w6 I5 a2 x+ b
        }
/ [- C* f$ r- W}
/ i5 C5 K3 i8 Y$ F% k
! |. B6 L: {. k4 N2 @! PBYTE        APU::ExRead( WORD addr )
( V; b; ]( a$ H& _% g  Z{( r4 _+ r  V1 ]# ?
BYTE        data = 0;
  i8 F; E8 \) l4 Z; G4 e0 J7 |- d) E
% I! a1 C* W# A0 t        if( exsound_select & 0x10 ) {
' Y% {- b" s( F( q8 }                if( addr == 0x4800 ) {( k6 t/ o" V! x* n4 W' u
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );4 Z/ h4 a- t) a1 Z
                }9 s, z5 @; S: ]$ x
        }
4 M4 x) Z' ]: ~) Z% a        if( exsound_select & 0x04 ) {
4 G' r# e6 q- a! }) q; C                if( addr >= 0x4040 && addr < 0x4100 ) {! w) J8 u& X/ Y, w& h
                        data = fds.SyncRead( addr );
  @, I5 U; m5 O$ x                }
) i' j8 @/ r& W' R        }& _3 m8 @! Z" S' |' ~
        if( exsound_select & 0x08 ) {
( H0 A6 x! S+ i9 n8 L1 S/ S9 A                if( addr >= 0x5000 && addr <= 0x5015 ) {
9 {$ v$ f% b9 C5 s: o9 {! ~                        data = mmc5.SyncRead( addr );
2 a& _; ?, W8 p; Y- ?$ P                }. f& g8 B9 ?9 j8 l0 L) d
        }4 X$ V$ P* V" P

- @; ?1 V- b& i+ L7 \' V        return        data;
3 f( `0 s4 _0 I6 C- a$ @! E  c}
$ P- ~2 Y/ `- J
5 ?1 I' x5 ^# j5 Cvoid        APU::ExWrite( WORD addr, BYTE data )
) w. w4 @- V9 i- e; z{
' ]4 P# f; L: @* ^2 X; K1 i( C        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
- S# c  W) Q  T5 K1 ?0 m# B$ [
3 n/ g/ u& {- c; `- B8 d+ F: s% t        if( exsound_select & 0x04 ) {8 w; r4 Z% V) {. J9 C; @6 u
                if( addr >= 0x4040 && addr < 0x4100 ) {: A. h; k4 Y+ R5 a
                        fds.SyncWrite( addr, data );4 ~; M$ _! S/ D+ K; C; r' L" P
                }" T3 l+ k! s' i
        }
8 x3 H) s3 v6 C) L
" Q, ~. L9 h3 d" _        if( exsound_select & 0x08 ) {
5 _0 j- j/ Y" A2 A: D. b& T                if( addr >= 0x5000 && addr <= 0x5015 ) {
# Z! V) W) h' f5 u2 Q8 h" q                        mmc5.SyncWrite( addr, data );- Q0 M( H4 G0 X3 }( }
                }
- }. Q% Z! j3 y0 q. F0 L        }2 ^  H8 R" Q1 W) V) M& f- p. L# v5 H
}, J4 Z8 P% |1 W; z
5 j5 i1 h; V$ V. n' r
void        APU::Sync()
0 z$ }! x9 q: h' F4 R$ |# G9 J8 [{
$ q, e/ ~0 d' t' y}4 }! ], D% ?& O

' ?8 Y: b8 s9 Z4 `0 n5 O" m8 [void        APU::SyncDPCM( INT cycles )
# n2 I+ d+ B4 J) ?{9 w$ w7 E7 {8 R
        internal.Sync( cycles );( p4 W1 X  ~( @4 B1 t. c7 O
' l6 h8 Y7 T) @7 t
        if( exsound_select & 0x04 ) {% V. R) h9 u  @! Y
                fds.Sync( cycles );% ]9 b, R6 I" r" ]- d! }9 |
        }
* o8 a/ ]6 K: P" M7 U9 b        if( exsound_select & 0x08 ) {' v( o$ [: w" u. V
                mmc5.Sync( cycles );
. z% o/ e" M* X, B/ w: B+ G        }, v8 c- Y- p# y- O: x# V7 G' H
}
; S, Q. s$ o4 v
) l( i& k% n4 A  j/ t2 ?6 mvoid        APU::WriteProcess( WORD addr, BYTE data )" V% Z9 K1 N* h+ x, B
{- v* P& X; Y2 r  p# @7 h
        // $4018偼VirtuaNES屌桳億乕僩
, q" V( K" o: f. G/ N- r        if( addr >= 0x4000 && addr <= 0x401F ) {; [2 f3 v- B: u( }% h% I0 K) `
                internal.Write( addr, data );: b" {! g, V: V5 w: J  u
        }
# n' e* _6 n  d1 U' f' U# r}* p9 c# A2 a. f. j) K$ B
- n. F( @- j/ g0 h) V3 ]
void        APU::WriteExProcess( WORD addr, BYTE data )
2 l# y7 U8 o& q{# I' U. E0 j* M
        if( exsound_select & 0x01 ) {
6 n( C% S* `5 I4 N8 Y                vrc6.Write( addr, data );
! s, A9 M! ^5 M) S7 ~# A. {7 V9 W        }& m( K! |: _" |1 q; f3 D& y
        if( exsound_select & 0x02 ) {$ C+ o: X1 I3 i  x( W0 w/ R/ U1 R2 w
                vrc7.Write( addr, data );. ]& \# |9 q* F& E& g
        }
- `( r1 I2 N' n& C/ Y4 g        if( exsound_select & 0x04 ) {
+ N+ o3 c' b: s' s2 b1 p                fds.Write( addr, data );3 i$ c: {4 C) }# d5 _, y
        }, F4 w& ]- c, N# u% X
        if( exsound_select & 0x08 ) {% p' k. {% p1 h; n) I% a' L  D
                mmc5.Write( addr, data );
5 b& S% B% H0 g  q2 J& K' x0 X+ M+ x        }0 C' O, T2 p; L- t3 p# r: c7 q$ V: _* `
        if( exsound_select & 0x10 ) {$ j3 s' D2 m& O3 [1 M8 m& T
                if( addr == 0x0000 ) {
- g, P8 Z) Y* l2 _: p# y1 a                        BYTE        dummy = n106.Read( addr );
: w: H1 g5 d8 d/ I                } else {# d9 J) r9 ~1 W  V
                        n106.Write( addr, data );# o! d$ O4 v1 W: F
                }0 E3 d/ J3 Y7 b' ?0 S: r
        }* B. N' g/ A, V1 l
        if( exsound_select & 0x20 ) {' W$ D& r  S# _& H. V) ]
                fme7.Write( addr, data );
$ @9 i. }7 i$ A* r. b        }
9 r' H. o3 k  s6 p, I" U  c6 v. j9 f}
' S3 f9 L; f! g. ]! [  c( I2 H$ i1 X% q
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
. m3 j* j+ J; ^) B1 T{
! x" o3 b: m% a' N" xINT        nBits = Config.sound.nBits;+ D& V6 _& R5 L; n
DWORD        dwLength = dwSize / (nBits/8);
: b' U4 n' ]5 dINT        output;9 J. b  g- ~+ L- x
QUEUEDATA q;- o. P; V4 \5 @& e7 k. {
DWORD        writetime;- D% h& W1 Z/ l2 \5 u. n
. O* |* g$ \6 Y' n: q
LPSHORT        pSoundBuf = m_SoundBuffer;
5 z. {/ m" N: y. S# `& NINT        nCcount = 0;
1 X4 V0 H+ R& s* E3 N2 q/ w7 Q1 w  ~) g, G8 r# b
INT        nFilterType = Config.sound.nFilterType;8 V* \2 N! \$ l+ b$ A1 X
2 E, P" |4 y7 ~% s! |: R1 m1 j/ r
        if( !Config.sound.bEnable ) {: j2 y. e& s7 J3 c" T
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );1 ~& Q/ ~2 a- A2 p. J: V
                return;
8 K  I1 n2 w. J& f, h% o        }
' c( Y! {& y+ b
8 b# e. Y; N5 u( {1 E' ~        // Volume setup
6 v7 K# o  ~8 g- F- a" l        //  0:Master
1 p: P" A! X$ g  O' Z, g        //  1:Rectangle 1' K9 X: t* m( c3 }" p
        //  2:Rectangle 2. H* z0 }9 v3 p, e# L9 L; s
        //  3:Triangle
2 ?- S% N7 u- T( E5 n7 e  G0 q- \        //  4:Noise
* G, D, |3 j4 v0 \" b# L0 R        //  5:DPCM2 O; H& e% T$ |& @7 |
        //  6:VRC6! q& Y6 J& R, X% u4 z/ d
        //  7:VRC7
5 u7 F) L3 E: s        //  8:FDS
; O, c9 k( a0 n: {        //  9:MMC5
4 z1 O; g5 w' ?- j9 X        // 10:N106
6 R+ C- T3 V6 o4 i: `4 t( O! j        // 11:FME7, i# B5 V8 ]0 q, P
        INT        vol[24];
/ l! y4 i. Q3 Z        BOOL*        bMute = m_bMute;
! H) j0 z$ o, U4 D% i( @  v        SHORT*        nVolume = Config.sound.nVolume;3 |; \" y/ D8 E  ]$ B0 A
8 `' C5 S5 m4 H# v7 }
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;( N, X* H( `+ n! C* l8 T- W
. h' F1 K  s$ w) F; [5 Q- P; F
        // Internal
: ^& s/ ]& o* m        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
  R/ @9 n+ t' X        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
$ G3 v; l+ \- G- x        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;( g9 M) X6 v5 k/ K( T) i/ |
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;; D1 }# w: L! y" h
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
$ e0 M; v" t+ d. W  U  G+ D5 a9 k5 c& E9 n* o! y
        // VRC67 d- k+ Y/ }1 {1 X" K+ D9 Y
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
+ g# @6 w, q1 w        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
' p2 e. a; G" W1 b        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
* D" I( b& C1 r, }" `
5 G' W2 J+ W( ?. B- i8 X        // VRC77 r( b- W+ g. {1 }
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;% d& {, u; P, B+ q& L1 X% f6 X6 u
! k1 e* c; g2 T3 W+ P" o
        // FDS1 A4 j  H9 H$ L" n  l2 r& _
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
0 W3 A" u2 u" ?7 r: E1 l- I5 H$ K5 _" e% i+ K- X
        // MMC5
. f- E0 A/ E5 g  @4 `6 i" V        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;) k, O  H" [# ~& j
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
& g, j. G2 `+ F: `+ J) U( P        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
/ Q( F3 U1 a' j# P, Y3 F
" c- S' S* O  v2 `2 q% [* i8 B        // N106% s9 T3 [( m0 G: b5 J! U2 w8 x
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
3 a: s6 o- m* r0 J3 T. X. s        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
/ D& y+ O. f* a        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
) ]' v3 N; {0 a& t        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
! t7 n  A9 L4 h+ S  [; u7 S$ b        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
% W) c5 ~1 \) d$ Z; |! e! e5 [5 c        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;2 P( ~0 d+ C& C
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;7 S( o$ |: H7 A1 T
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;7 ^' f/ W' w' B7 s
5 k2 }4 t/ @9 N2 v9 `& _  B
        // FME7
% R1 }0 E/ h  i8 H7 A        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
, d9 V/ }  U. b6 [% w: L5 ?8 \        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
$ z) H$ s+ G- A* S9 q. |        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;# m/ D, r- M: e

$ w1 J9 h" @% l5 a. V9 d//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;& {7 O" g5 x8 T3 d
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
0 M+ g& T+ L8 g
1 V! g* W: T, q. {8 V        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟2 ?* A9 v* M8 E! f( r$ F4 C" _
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {, X" P# |5 }' a5 P7 W5 |  d6 r
                QueueFlush();
" Z: S: h# T! ^. m$ ~' Q7 D        }4 w5 A) O. `, R& \" [8 ^) E2 U, W
. C; Z+ T+ g# _2 L* {
        while( dwLength-- ) {
0 h8 E6 D$ U- }( w9 Y7 G: W" e  J                writetime = (DWORD)elapsed_time;9 q  C' y3 g$ T& [9 K: H
8 ~" l- R4 D3 A  T  \
                while( GetQueue( writetime, q ) ) {. e. b8 J5 z/ q2 q8 p; N9 p3 [
                        WriteProcess( q.addr, q.data );# c: w9 p4 d7 V% {5 s
                }
+ F, Z0 M  B& q; M& k' I
8 [% [  `( t' t9 d6 W+ h1 U                while( GetExQueue( writetime, q ) ) {- X( h# t7 o; R) q/ V: q( F
                        WriteExProcess( q.addr, q.data );
% [6 o, Y' c5 q) l9 G/ H1 b                }
9 ]4 r& P/ f4 V3 i" v0 X/ ^) f" s1 U- _
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7  L2 N4 Y4 {* P' J; T/ s6 o" a6 X
                output = 0;) _6 |: l! y. F+ v" n+ w
                output += internal.Process( 0 )*vol[0];6 M0 c  n" C8 `4 |" Z
                output += internal.Process( 1 )*vol[1];
6 y' s- v  E! C' F. t' v                output += internal.Process( 2 )*vol[2];
& Y8 k4 k7 G# z+ y% k/ c: h. A" k                output += internal.Process( 3 )*vol[3];: B# Q/ v1 Z" L
                output += internal.Process( 4 )*vol[4];0 D* |! Y! o9 ?& ^! F: f
+ i  x+ N- K8 m' ~# w( d$ c* ~
                if( exsound_select & 0x01 ) {
9 H; @7 U  |8 i# _( S; n                        output += vrc6.Process( 0 )*vol[5];
2 ]: b& [. e* G4 {! Q                        output += vrc6.Process( 1 )*vol[6];9 j6 J$ [9 V4 o* _% D
                        output += vrc6.Process( 2 )*vol[7];3 J+ i& O7 [( c7 F1 B& x/ Q
                }
) E0 R3 I  Q0 z, F0 |( R! z                if( exsound_select & 0x02 ) {
! \8 x5 m- ]' D: d" R6 z& d9 l                        output += vrc7.Process( 0 )*vol[8];) F# \9 `1 X# M& ?2 d: G) {( k
                }: q/ I( Q8 S5 A! V: j* ]
                if( exsound_select & 0x04 ) {$ H! h. p* G$ R* S- J
                        output += fds.Process( 0 )*vol[9];
! `. [$ x' o9 _& j2 [                }
; F) Y5 r5 f7 f" U' \; ?                if( exsound_select & 0x08 ) {: J" F) s' }/ b9 x
                        output += mmc5.Process( 0 )*vol[10];4 u, a9 }; [1 G* j: j* t
                        output += mmc5.Process( 1 )*vol[11];
9 x  m, o5 c8 R. K; @                        output += mmc5.Process( 2 )*vol[12];* J( t! ^& T& I3 O" g& l4 K9 L) _
                }
* e' l. T7 D6 l5 V                if( exsound_select & 0x10 ) {( D8 e2 B2 X4 Y8 f
                        output += n106.Process( 0 )*vol[13];* C" C* z) d: @
                        output += n106.Process( 1 )*vol[14];0 g, |0 ?8 m$ Z( H7 Q( Y. l
                        output += n106.Process( 2 )*vol[15];" N5 w1 N1 Z' x! N- b, t  Z2 o
                        output += n106.Process( 3 )*vol[16];
1 ~% G5 q6 _+ g. h4 F                        output += n106.Process( 4 )*vol[17];" v! |( |8 T6 H3 ?+ |/ Q0 u
                        output += n106.Process( 5 )*vol[18];/ v8 V  c* W: z% L; \7 V% v, k
                        output += n106.Process( 6 )*vol[19];
8 S: R; ^. q& Y0 v                        output += n106.Process( 7 )*vol[20];. r  v; H8 i0 T# [+ G; W' O
                }
* }% T6 K- n* q9 x3 M6 m& \) L+ o, |3 Y4 r                if( exsound_select & 0x20 ) {
& P1 t3 _8 _: s/ _! P+ A                        fme7.Process( 3 );        // Envelope & Noise
" p( E5 U0 ^* n                        output += fme7.Process( 0 )*vol[21];
: `& [5 ]/ N1 G+ @! g+ ^. K                        output += fme7.Process( 1 )*vol[22];
5 o/ X& O. m( ~                        output += fme7.Process( 2 )*vol[23];- R4 a1 w& S% P( f. z6 Q8 t
                }
/ p8 g; Q4 v! {, T( t6 J! C7 b- m) V3 p! \+ H
                output >>= 8;- F; S. d, p- o# B
. ?; \4 ?, \: h
                if( nFilterType == 1 ) {  E4 R, N+ N5 D% j* \
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
! e, @% S( n5 j; z                        output = (lowpass_filter[0]+output)/2;5 l- c5 D' E- I4 R8 E9 H+ @
                        lowpass_filter[0] = output;& F2 a- b& D, t1 E
                } else if( nFilterType == 2 ) {- C+ ]& m4 ]7 T
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
; a& I  n# o$ f' e  O" v4 Z# ^  S" X$ ^6 q                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
) W( B$ C! k' ~" z& k5 `3 w                        lowpass_filter[1] = lowpass_filter[0];
, }/ ^! d6 S+ s" S9 k" X" G. ~                        lowpass_filter[0] = output;# `8 F8 c2 C) d
                } else if( nFilterType == 3 ) {, }# w' W: A4 O
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)4 G' [' h, C+ N- {- u/ b/ E
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;6 }+ m1 N6 K9 F7 b. K( C) P! i- E
                        lowpass_filter[2] = lowpass_filter[1];
2 K" `& K6 M" |# b9 S- ]                        lowpass_filter[1] = lowpass_filter[0];
+ m; Y" ^$ x/ h& [7 A                        lowpass_filter[0] = output;
, z0 r% ?* E, I0 t% x) P) h* ~2 t' V                } else if( nFilterType == 4 ) {
  d4 H  c- v4 ?( q) }$ P3 H( T                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
5 E9 q! n2 D0 V- d; f' e                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
5 t/ m- N0 z* T) m4 P% u                        lowpass_filter[1] = lowpass_filter[0];
' |, c2 C- |3 K+ g* t                        lowpass_filter[0] = output;
0 Z# \8 z7 Q: S                }
& P+ N7 Y4 t9 W: Z9 ^- V) o9 M0 E! h  p4 c
#if        04 q; o5 f) F1 T; e3 A2 l8 U' w$ V
                // DC惉暘偺僇僢僩* Z, X- E$ @7 N" G% `9 x5 H2 L
                {
# T; h7 V8 r: g( R' b                static double ave = 0.0, max=0.0, min=0.0;/ A* J; F5 A) ~
                double delta;
: G  l, b5 c% @- X6 T# r                delta = (max-min)/32768.0;' D; I5 c  Y; U5 e3 r. b# {6 Y
                max -= delta;
2 d6 S. x% h- V! d                min += delta;
; T$ J. X" h7 F! |. ~, \( Y( ~& E                if( output > max ) max = output;
0 d" v/ e7 @; E' J& A                if( output < min ) min = output;( R# N8 w9 [+ e  {6 d
                ave -= ave/1024.0;" b9 w8 F2 B; f6 G
                ave += (max+min)/2048.0;8 t. {3 @0 t8 z6 H
                output -= (INT)ave;% r. p9 ]" K% W. [$ p
                }( N% v  Y$ G& h: O, V+ Y
#endif' ]% s& a: K, l7 }: i
#if        17 b5 i( k0 d& p5 @
                // DC惉暘偺僇僢僩(HPF TEST)4 n/ S' N4 i( c- S
                {) X' _! m7 ]& F4 t8 C" Y
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);7 S$ Q) G! F6 @1 N( ?: Y3 |  R
                static        double        cutofftemp = (2.0*3.141592653579*40.0);' s; m1 n7 R8 ~
                double        cutoff = cutofftemp/(double)Config.sound.nRate;. a% a/ H- a0 _) P9 ?1 Y
                static        double        tmp = 0.0;) h4 C- f6 C9 Z5 ~* f- k
                double        in, out;  J$ K. _! ?6 p' G  A. I0 h
# |8 b1 A" a, j2 j
                in = (double)output;
' b( e0 D+ e$ R# \! U                out = (in - tmp);/ b5 C" q- ?9 j/ Y7 m0 V: g1 l: C
                tmp = tmp + cutoff * out;6 Q0 t) t. M$ p- [' F+ P0 d* y
) d" V0 r" L: I) y8 {. s/ `' M8 s
                output = (INT)out;8 A) H1 W' K- w; d+ J: h) G/ g
                }
0 e$ W7 u  V+ [& [#endif
, S* w' m3 h# x0 d#if        0
7 l6 E5 L# L* \% u, l9 G                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)) w3 W1 V8 a6 r5 R0 b0 z
                {5 f: Q5 v4 l, P  U( M
                INT        diff = abs(output-last_data);( o2 g' ]) `, }0 {
                if( diff > 0x4000 ) {) r- y4 a- J/ r$ J. P( j/ o  h/ L9 M
                        output /= 4;
+ i: l9 J! h) n: Z0 N                } else $ N3 G; T4 e7 C1 T& n
                if( diff > 0x3000 ) {9 D; O6 f# N8 J  n9 N$ _
                        output /= 3;
( B" j& L7 L3 U3 W5 }5 C; }                } else4 j: }, g% B1 F
                if( diff > 0x2000 ) {9 {# @4 [' N/ H- N; O% Q5 Q
                        output /= 2;
  U: c+ Y: a$ M- H                }
# T6 I% u( ], S# o, e% O" ^; O, c                last_data = output;- \9 f/ L+ g' ~9 ?5 ~: R) K1 {
                }
6 ?% ]; J2 R4 S6 C* X; {+ h#endif5 O9 g1 t) H# y5 t
                // Limit. n0 \0 D4 g0 V# y
                if( output > 0x7FFF ) {
8 }: C, G+ n9 p  b/ f0 K1 u                        output = 0x7FFF;$ J- r) B7 z5 e! y9 d% d
                } else if( output < -0x8000 ) {) Q4 J& `& `2 L4 f+ i
                        output = -0x8000;1 H3 s1 K8 O7 j8 C7 a; p
                }
+ L0 B- ~' y! K# R+ B4 H1 D7 l0 m# L! h( H1 E' Z0 A
                if( nBits != 8 ) {$ \) [9 d" S- G. g# j8 n
                        *(SHORT*)lpBuffer = (SHORT)output;
" r7 `% \5 z2 }                        lpBuffer += sizeof(SHORT);
1 M3 f9 t& M; h7 u7 y, B2 Y                } else {& S2 H' _  |4 ~1 F
                        *lpBuffer++ = (output>>8)^0x80;! i# a$ W( w( T7 k5 G1 R9 I; {
                }" J% S: n1 f; Y% U

2 g$ b0 p+ Q9 a                if( nCcount < 0x0100 )
7 e) v* f: i$ A) E. [                        pSoundBuf[nCcount++] = (SHORT)output;
7 o% K' s, c! R- E, S* q; ^: Y% Z
0 I5 D( q: s, t) F% N( W" R//                elapsedtime += cycle_rate;) Z8 I0 ^$ W  D
                elapsed_time += cycle_rate;
: s' P+ W; @5 Y* f        }
8 R' ^0 O1 N3 E3 B, q3 K9 d8 G* B$ {" {  L4 g+ Z' b/ p
#if        1: u5 H* t# h( c: B/ {+ Z3 z# x8 E
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {+ H: r$ P: |  B8 `2 k+ f
                elapsed_time = nes->cpu->GetTotalCycles();" {. v$ k( Y* q% D
        }- n+ U, }% Y1 D7 l/ }
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {0 A3 A. Y# w2 I: Q, k
                elapsed_time = nes->cpu->GetTotalCycles();
) v" a3 Q; B, n        }
1 C" r& v0 l8 x6 J& G% r" ]#else
* ^5 g3 x; [) D        elapsed_time = nes->cpu->GetTotalCycles();
7 ]0 D/ g( W) V#endif
% n. h5 D- T+ Q- I; `}- x+ e4 e, s5 X3 i% H

5 J) p+ h, ]% d' A3 h9 k4 W// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
7 R) b4 W" S2 }  `, gINT        APU::GetChannelFrequency( INT no ); V$ J  M  x* L* {0 W
{
" I( ^$ p! f& D) ~        if( !m_bMute[0] ), Y- _0 a/ L# s
                return        0;: E% J) ~2 o* B4 A* `2 G
6 m, @* ]0 R  s) h( S% ?7 _
        // Internal
: I% q/ \+ i, g' I' _* \        if( no < 5 ) {9 Y( n* _; s  B. N; r2 y8 @
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
4 @' b& a$ O5 P3 N0 a( [" _        }
6 Y2 i& k, w# n" C( ~5 c3 ^        // VRC6/ k1 R! F# O% M/ r
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {# D, t5 N3 v! l0 w1 P# y, l4 t
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
1 r4 G, q4 Q- r& X# q* x$ M        }* G/ H( ^1 a0 F$ [) s
        // FDS( C* ]# l' l, u. D
        if( (exsound_select & 0x04) && no == 0x300 ) {1 |9 a. J; w, D4 ~
                return        m_bMute[6]?fds.GetFreq( 0 ):0;# R2 g  W( `9 z) |' _2 b' d
        }: k1 r0 [# V# a6 {" f
        // MMC5( O$ Q  I+ N3 U/ t5 r
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {) g. L- D# L9 R, f. s' i
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
0 {5 m+ K$ g: |5 \8 b9 `        }( d( a7 t2 g( a! R5 `5 D( X
        // N106. t( s6 c# p4 J! I/ R' l5 N) w
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {2 y# l5 \* Z" v
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;! K/ N. a9 b3 F5 n: C+ j6 d
        }
0 w. g0 ]5 f; L; z$ `' e        // FME7
) r( W, ]8 y' L) }4 e: f1 x. O        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {$ D: b2 P% U8 e9 `) C- `7 p
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
3 v& j0 p& Y7 C, X% R+ C* v        }% O; G7 b7 ?4 `/ \
        // VRC7
$ j) x5 d+ T, ]1 H. J6 F& P        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {* a- g: ]- p/ g
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;/ g: O- W" o" M+ `: p' X
        }" b" N) o/ ]+ g3 M+ @
        return        0;
7 f+ c, e* Y. s) r}; T9 {9 J" K# P0 A

3 Y9 V7 O- ~6 d# A// State Save/Load8 U8 i$ J6 u. _; `0 @6 g
void        APU::SaveState( LPBYTE p )
1 X9 E7 T+ s' |$ v, @{
& y. K. U; `- q8 Z$ f# q#ifdef        _DEBUG; M. S3 d! Q* q. ^
LPBYTE        pold = p;5 h# O  z5 P: B! s8 C
#endif
8 k3 \8 O- m) Y: |1 I4 }* S3 h: k# T$ e: G- D$ ~
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞4 ?/ @7 Y3 w3 k# f; O: I
        QueueFlush();
9 m' S3 j3 L- K& y! B/ n+ v. S# d0 T' ]& k( P2 U: i* L7 @4 d
        internal.SaveState( p );
* S! m, l. V4 u! j5 ~# ]. T+ U& H( C! a        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding* W, `  x; U) a; h' T

& A3 u# }* x+ g6 c: w$ u9 T' x+ J6 M5 L        // VRC6; Z) y) s- O6 z1 y; H/ ~' @
        if( exsound_select & 0x01 ) {
: E& `; q; o" g3 Z) U                vrc6.SaveState( p );- X' Z: u$ [/ i# d
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding/ h4 i7 e8 n3 a2 l& i" Z
        }9 e; m0 r3 t4 T! G8 |4 ?
        // VRC7 (not support)
8 \4 @/ ^# d5 S& ?        if( exsound_select & 0x02 ) {
# g1 f# z3 G% g% I: u+ e                vrc7.SaveState( p );
, W# _" Q% l: W/ U4 C                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding. J: o: A% |) `  {" M5 i5 D
        }( O/ \+ s) f8 o% M
        // FDS
( F/ O5 G/ Y) U6 e' b/ @        if( exsound_select & 0x04 ) {+ f9 {. h1 `, U. s! A$ D
                fds.SaveState( p );! Z5 ?& |& C/ N# v0 H( b8 t1 O
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding- v5 M+ h+ p0 F' W  q
        }
6 O0 s& b. L* u# ?# W- H        // MMC55 X0 J+ n. |: U
        if( exsound_select & 0x08 ) {
, T0 h9 X4 `4 z7 c/ a$ w4 r* D                mmc5.SaveState( p );
, g8 p+ L! f. X$ k5 J+ ?" f* k                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
2 |( D/ ?& V( C1 ]' G        }
4 H; K0 d& [/ {6 k% Q0 j        // N106
' ^5 K; x& r7 t- a& c+ A8 [( [        if( exsound_select & 0x10 ) {5 r4 `+ j  @' c2 }
                n106.SaveState( p );2 r- `+ P  n5 s; h7 n' b, U( f
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
+ k3 T, h5 U0 F        }
! H/ C- ~& a! v# ?        // FME7. e$ |& i3 F0 y( `* }
        if( exsound_select & 0x20 ) {
  g4 w/ G( U; r8 h% N+ P                fme7.SaveState( p );- E8 c* N' B0 m* B; j7 i
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding8 k7 H5 Q8 n8 w
        }( G  B0 w# T) s- K, V/ T8 v

% Y3 A& b3 L# m: f' S# u6 K#ifdef        _DEBUG) \# |: Q8 N; o& f6 b$ e
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
- O) K, `# \: W7 w) s8 _6 ]0 Q( Y2 F#endif2 \, c/ J  u$ S
}
6 }) y+ [4 @5 x: @  G9 \. n. w$ d2 o& N! x. L" p, {
void        APU::LoadState( LPBYTE p ): M' F2 N, l2 w0 F
{
9 O% A7 b' J; I        // 帪娫幉傪摨婜偝偣傞堊偵徚偡% ?1 @. q& N6 s2 e
        QueueClear();
! z" ~1 q" s' `# Z0 k
! K. _2 T" }' Q        internal.LoadState( p );4 `& e2 w) V3 ^& M
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding' Z9 r2 n" q+ k4 M/ b7 U  T

" @9 J8 }8 q+ \5 f. m        // VRC6/ t. Y, X2 q. o+ M5 n; c
        if( exsound_select & 0x01 ) {$ h$ E1 C* A- Q6 {5 k) G: y
                vrc6.LoadState( p );4 X+ q; V# v% ]& t
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding; Y  U' h2 w0 y( }
        }8 j/ G" X9 v! {- r; i3 H
        // VRC7 (not support)' i) n$ W6 k; ^: D' }8 b
        if( exsound_select & 0x02 ) {3 p/ {, ]/ D" W: N
                vrc7.LoadState( p );! t- j4 S6 W) M% O9 C
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
7 z* L  l, m; c. \4 B2 `& `0 i        }3 r+ y7 E: y5 W- r1 S* z
        // FDS& B$ w  t* B2 K: `& D. N. i' J5 O4 T
        if( exsound_select & 0x04 ) {! ^, `# i: F! \
                fds.LoadState( p );7 J& i; y: V. L: @1 ^. [
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
( H. u2 ]1 W3 ~+ i; u4 L9 j        }
) u( p( e1 X4 |        // MMC5# z) N' M0 ^4 N* t5 J& O7 P3 `
        if( exsound_select & 0x08 ) {3 I& s1 ^6 ^0 C' A  m/ M3 z. K$ D* f
                mmc5.LoadState( p );9 M2 j9 U, ^% h, k$ L
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
7 B$ R4 e' ~7 C  f        }
& r, |5 g/ E5 W; }4 S6 E        // N106
" A8 f! G7 C. o& e1 p% [. y        if( exsound_select & 0x10 ) {9 G4 O8 Z' n8 K2 t5 L
                n106.LoadState( p );  J0 i; |! v% M: U
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding# o( c+ s+ V) A* T
        }8 f6 J  f: n' x$ ?; c0 }
        // FME7) o! e9 ~9 F' g( K7 J. {. v  x, E. X
        if( exsound_select & 0x20 ) {
) N! @$ ?2 ^" g7 J6 S" E# t" p                fme7.LoadState( p );1 {* ~- k) ~8 G$ C5 e8 o% T
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding& j) c. i% r3 _# n  K( C' Z4 y% W
        }
) S) U; s( ]$ K: [# l}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
3 x; Q, u$ E( N) K7 E1 ~/ G. _7 A可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
4 e! [7 m2 Q$ H感激不尽~~
0 V' c8 U) o4 d* L
恩 我對模擬器不是很有研究,# K, R" L7 |' l' Q" i! z
雖然要了解源碼內容,可能不是很困難,
; |& R; {# @8 c* ~5 z不過還是要花時間,個人目前蠻忙碌的。0 W& R7 |% B- X& R) u2 l

5 w! i, Z& I) }& b- m& d: d給你一個朋友的MSN,你可以跟他討論看看,9 S2 U  R( a4 ^
他本身是程式設計師,也對FC模擬器很有興趣。/ N' C1 l* M' T. j+ W' o: T2 [

1 \: R  f# H+ _5 Z' oMSN我就PM到你的信箱了。
# A2 C$ C$ o4 X3 G2 G( G' R; O5 A# m
% J* ]6 [( s5 d5 @! Z  o! ^希望你能有所得。

该用户从未签到

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

签到天数: 80 天

[LV.6]常住居民II

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

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表 7 _9 D8 ?" c/ ^
呵…… 谢过团长大人~~

" b% {( S6 A" n
- Z2 J6 f, X4 [! X- H- O3 t/ S哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 0 I+ J4 L. t1 O% d: i9 P2 w& n6 h
团长的朋友都是神,那团长就是神的boss。

( z  S6 I# x1 s+ d3 R. y  u哈 不敢當,我只是個平凡人,% r/ T) h; O" N# c4 q: Z4 ~
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙+ `7 Y& m' ]5 y8 ~
ZYH
. h2 {/ |' ]. t" }5 tQQ:414734306
1 G4 i" F% |# w) m* L; J5 G0 NMail:zyh-01@126.com
) _( c1 v' |0 N( U" u3 J; T6 B+ j6 e9 c- f
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
1 ^0 a/ W# W& E4 q" n. a7 Q. i1 r再次对团长大人和悠悠哥的无私帮助表示感谢~~
6 j. m5 \" Z. o
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-2-5 19:35 , Processed in 1.108399 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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