EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。& u/ _# y' [- L# @
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~0 G0 w( i. m0 x
这里有相应的模拟器源码,就当送给大侠了~~: g; j, i3 k5 H6 V1 T2 h" l/ b( X6 @  i
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 . [& a& P8 u3 J4 K7 Z2 U! F
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。4 a' T1 h) ^6 n& h' f0 H; f
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~2 |# S  P3 }' e
这里有相应的模拟器源码,就当送给大侠 ...

6 {1 a, u" T5 r8 j4 g聲音部分(Audoi Process Unit = APU):- I  o4 k" v8 N0 V
.\NES\APU.cpp
. ^5 [- b! T& a" T+ K.\NES\APU.h7 W( r1 Z! N5 [1 q& S& k' H# ^

- e  r4 V4 c2 \, I6 q% C6 n. l# F; O1 g5 ~9 K
影像處理部份(Picture Processing Unit = PPU):
0 Y+ Z3 m8 g8 r! H$ l2 e9 r.\NES\PPU.cpp* x7 s/ F! A5 j8 }1 _
.\NES\PPU.h
% G! P1 D0 D) n: a! I6 P6 _% h3 h
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:4 s; w0 I( ?! n9 F2 }; M
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
6 x* r- Y  `7 ~5 [2 f//////////////////////////////////////////////////////////////////////////
# U& L/ S( N5 ^8 [: ]+ d//                                                                      //
6 {7 I( k* h& c% M% M//      NES APU core                                                    //+ T7 ]2 e) x, |) \% K6 T
//                                                           Norix      //7 L) K  \0 e: i
//                                               written     2002/06/27 //
% p" B0 j) U; e- ~5 W2 r8 Q//                                               last modify ----/--/-- //2 T( h) I- X- J$ G# R4 b
//////////////////////////////////////////////////////////////////////////2 O2 B9 n( |' i& E) ?' i
#include "DebugOut.h"
: {! W( Z# p# B4 F, I7 {" v* V2 p: G0 ~#include "App.h"
) u; \& s# c9 f+ l( y#include "Config.h"/ n) t6 }, ^9 G) C* i3 r9 R: J; j0 C

" C# v6 J% J. S% B% z#include "nes.h") f) D9 A: O8 T7 L
#include "mmu.h"% _9 Y  r; w: M- ~( M& U! V
#include "cpu.h"
! e! ~  c3 k, ^/ b% C; d$ b#include "ppu.h"4 f! K9 D+ _7 C) z2 |
#include "rom.h"9 W% B/ ]2 Q; W6 M4 H
#include "apu.h"# q$ b7 p9 q" F. v
# P) x+ `& i$ ?- g
// Volume adjust
, f' m: D1 G% |& M: x3 I$ ?% |/ \// Internal sounds( X5 j2 a8 J" U( [
#define        RECTANGLE_VOL        (0x0F0)5 @+ [# j" h0 Z
#define        TRIANGLE_VOL        (0x130). }2 k& r6 e6 o
#define        NOISE_VOL        (0x0C0)
8 I" D$ j& M! {4 O2 {' k#define        DPCM_VOL        (0x0F0)
! |0 m, g; e) G8 O' s// Extra sounds9 ?1 u$ l6 l3 p/ j) [" V, \5 B
#define        VRC6_VOL        (0x0F0)
9 x$ r0 x; w) J4 a0 ~, N0 |#define        VRC7_VOL        (0x130)0 C% S/ W( @" i7 |
#define        FDS_VOL                (0x0F0)
" P6 a) K; C+ F7 u8 ~4 D#define        MMC5_VOL        (0x0F0)& N. B3 r0 s! }$ h
#define        N106_VOL        (0x088)) }% v: h: C6 s+ ?' N% {
#define        FME7_VOL        (0x130)# r2 [8 ]& ?- W/ V
, H; {, ~8 \* p  Z. ?, D* a7 a
APU::APU( NES* parent )
7 J4 D) O$ G! `9 }{- b' s- c5 {) D7 u
        exsound_select = 0;
2 J9 |. t* `5 `# ^
% M7 Q9 \  C# s        nes = parent;
/ n8 @. t0 ?; T        internal.SetParent( parent );0 c$ }$ A) e1 W  J" A2 L: ^9 Z

9 H) L9 _- Q  c* d2 f0 `$ V! L        last_data = last_diff = 0;
" C; N: [# Z2 K! e
1 V4 o( p* X! o/ f! l5 j        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );9 ]4 y( F- G4 ~4 S+ X

4 z4 a3 Y9 `" |/ y        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );" }) @$ p3 p( ~1 D( e3 i7 B! `# j
        ZEROMEMORY( &queue, sizeof(queue) );
5 X+ M9 K5 W( H6 W4 H: h$ T        ZEROMEMORY( &exqueue, sizeof(exqueue) );
& K9 U- ?1 f: B( M3 M$ ~/ u' S% y) o. |  Q
        for( INT i = 0; i < 16; i++ ) {
5 p, v# {; |7 T. r- Q) d$ e6 j                m_bMute = TRUE;. [) K: m( ~" V9 U% s
        }* ]; t. |9 |) K, J  r4 P& O$ {3 a9 X  Z; q
}
3 _1 C1 d: m) Z/ s! \% ?
3 C- h5 c: e% nAPU::~APU()
" |4 w7 S8 ~/ U% M$ }" O{3 _8 ]/ v: f6 K' Q( W4 w8 O6 e
}* R* D. F9 x8 E( H- ~# A
; J& y; H, t7 M; {( r5 s
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )7 K6 M  }1 M- J% G' F
{( v7 a+ [. @) y& o' x9 ^9 X2 m) H4 ?6 T
        queue.data[queue.wrptr].time = writetime;4 |9 e9 e- k' J; p, Z6 u& a7 ?
        queue.data[queue.wrptr].addr = addr;
1 [. \+ T2 a' y        queue.data[queue.wrptr].data = data;* y8 @9 x) {6 a3 [8 v
        queue.wrptr++;, d3 c- U1 a+ e0 @: g: X7 _
        queue.wrptr&=QUEUE_LENGTH-1;
; z5 ?  m0 Z( Y5 a) O3 Q  \! |        if( queue.wrptr == queue.rdptr ) {
: D9 Y5 P  P# y& ~2 d                DEBUGOUT( "queue overflow.\n" );2 C7 w9 S. ~. y6 }2 V
        }
3 v& C- P/ ]3 F4 |}
  `0 w, x% s6 u( e4 N, C- T" M) z' g) N1 L; s
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )1 H3 E6 U; ~' {* ?3 f8 J
{/ [* Q+ d2 \/ @/ D/ |7 h' W& X4 ^# N
        if( queue.wrptr == queue.rdptr ) {7 D& x2 p7 H+ Y2 @) ^  ]: N# E' i) F
                return        FALSE;
& K1 ]9 a8 }! K        }* Q1 N$ t7 x) y9 o% y
        if( queue.data[queue.rdptr].time <= writetime ) {% r! P  y. ^- x! V
                ret = queue.data[queue.rdptr];9 E# n7 K& f0 `0 h( ]0 d# r
                queue.rdptr++;
9 X: E0 S5 X6 h* }5 M, n( N                queue.rdptr&=QUEUE_LENGTH-1;* m9 O6 y  Q  U+ T7 g8 R
                return        TRUE;2 Y2 g: S: ^" S& y2 R. g
        }* z! X1 f, s% S* [2 O: ?3 R
        return        FALSE;
+ x$ R: M1 c) f4 K+ P% T}
7 `/ n- z" S" [3 h: Z
- O$ H. U0 F* B& u) `5 v, vvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
; ]0 k, w1 n& G' C- s7 o, c{" S* m. v9 M5 z$ W5 {( \0 v- x" ?
        exqueue.data[exqueue.wrptr].time = writetime;
' F" a( O0 j0 y        exqueue.data[exqueue.wrptr].addr = addr;& x. w# I# N" w" \5 f' l+ m
        exqueue.data[exqueue.wrptr].data = data;
* D- {% q/ W1 i, o* Q& R7 [        exqueue.wrptr++;
# S1 G. u9 n) I3 }        exqueue.wrptr&=QUEUE_LENGTH-1;% W2 o7 }$ r! G- x& ^% L
        if( exqueue.wrptr == exqueue.rdptr ) {
  |) A) J# D# u) t                DEBUGOUT( "exqueue overflow.\n" );
9 ?3 k: e# a/ F: O; u        }
) c/ T* p6 ^9 a( g# o! o+ g' n+ D}
- \7 \2 E1 Y9 y& l% o1 t% z/ K- O: F& t
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )9 U! d& [% {: J2 x) z* t9 z7 g
{. _4 s6 ~. c7 x' e& f
        if( exqueue.wrptr == exqueue.rdptr ) {9 v% V4 j! \$ h
                return        FALSE;
5 J) q" w; ]. @1 l        }* v" a8 @4 q' w; h
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {. m2 ]' U* L3 X$ B
                ret = exqueue.data[exqueue.rdptr];
; v9 `& o* b+ V9 N( w. x                exqueue.rdptr++;
% L; W& J2 ?( y$ q                exqueue.rdptr&=QUEUE_LENGTH-1;
9 Q( i5 }- ~" |                return        TRUE;
" z& A/ W4 L! b        }
, |7 a; Q5 Z& e5 k  m        return        FALSE;1 F: H1 \% |3 D# Q- L$ x5 S! ^
}
) Z4 Y4 G4 c, e& }; i4 s
6 k+ v8 J, Y" v. Fvoid        APU::QueueClear()
$ w4 Q' l7 }; E0 p1 U" s* p  S5 @{  ]: W5 \0 |9 m& u5 X9 t+ }: l$ [
        ZEROMEMORY( &queue, sizeof(queue) );8 x% m( Z4 z- U. ~$ E8 H0 T7 }
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
9 Z1 j9 Q; a8 z) y7 g}; X: e" U9 G) a" e

5 x0 E  a1 K1 P/ p" fvoid        APU::QueueFlush()6 y  ^& l7 S( r0 z* L3 [: e
{  }5 `: @6 s% C. I' ?
        while( queue.wrptr != queue.rdptr ) {% b8 N; i% \, Q* Z0 W+ i
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );* V! q# `$ d  V, Z  S; O
                queue.rdptr++;
. O" n+ |; K, D0 I$ F" f: y" S+ V3 ]                queue.rdptr&=QUEUE_LENGTH-1;7 D6 \; k5 m% {( |8 Q
        }+ L+ j. N7 p0 z$ K( A
% m2 q4 k$ q, v5 I
        while( exqueue.wrptr != exqueue.rdptr ) {4 R4 t/ j- z2 E6 a' Z
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
, a! d' O) ]& |. F* Y* V                exqueue.rdptr++;
% i8 v8 @# G# d; ?5 Q9 |% `                exqueue.rdptr&=QUEUE_LENGTH-1;
! M9 D7 v9 K  e6 m$ x        }" R5 a+ x# g8 ]4 F, h
}' s# n) h& v5 M9 [. k: X9 D5 N' e
/ i; i6 t/ ^; Q  s
void        APU::SoundSetup(), b, m7 d0 p4 S7 W7 L, \2 z0 M1 {: V
{
: h0 `3 |& A' `4 Z6 n" f        FLOAT        fClock = nes->nescfg->CpuClock;
$ N7 k5 w8 X( P9 H        INT        nRate = (INT)Config.sound.nRate;, H6 g" v# n* P
        internal.Setup( fClock, nRate );7 N3 V5 j3 U6 {6 D* Y7 r
        vrc6.Setup( fClock, nRate );( _' C+ _, N9 U: Z* U5 J
        vrc7.Setup( fClock, nRate );0 K) H+ R3 ~, Q. K; B$ V% [
        mmc5.Setup( fClock, nRate );
6 Z8 s8 P& o) z% k1 V5 r' q% W        fds.Setup ( fClock, nRate );
( Q0 P+ l5 e6 O/ ^" S9 ]( C5 V        n106.Setup( fClock, nRate );/ z5 ?$ f0 _+ h- {6 r, E
        fme7.Setup( fClock, nRate );
, W: I, ^" R+ U9 `+ F- t}8 g- y! R+ K& g5 W! P

5 A" c/ C( y4 l( l4 tvoid        APU::Reset()" A. j8 J! u8 @
{
3 s+ P& z2 J) X        ZEROMEMORY( &queue, sizeof(queue) );
% h' H% v+ o" F1 k        ZEROMEMORY( &exqueue, sizeof(exqueue) );) d: \& O8 y" Y' g# E) E1 k

% {' [# m& Y5 F: W2 {        elapsed_time = 0;6 D/ ^7 b6 }4 |/ d! M6 @! h9 K

7 u: R* J6 H- e        FLOAT        fClock = nes->nescfg->CpuClock;7 t0 n$ s/ Q2 C
        INT        nRate = (INT)Config.sound.nRate;# O$ y) \0 \( }9 E& P( a
        internal.Reset( fClock, nRate );7 \# n' u3 P# D$ s" j
        vrc6.Reset( fClock, nRate );
+ w& s; m* a  e; Q! e/ D; T) x6 t        vrc7.Reset( fClock, nRate );, }4 Z  j. ^/ v* z
        mmc5.Reset( fClock, nRate );4 }# j' m, f  p9 M% j
        fds.Reset ( fClock, nRate );* M4 i+ h4 D6 _4 g$ `) f1 \
        n106.Reset( fClock, nRate );7 O6 ]( D& N/ U2 b4 W8 c2 D
        fme7.Reset( fClock, nRate );) D, `# j/ M. o4 R; A
8 l$ Y) b5 W. j5 n2 N! X+ x* K
        SoundSetup();
, J: X9 b4 {) ^: W+ k! r}0 G3 [1 K2 R4 u

4 p1 ~+ @+ }4 M# hvoid        APU::SelectExSound( BYTE data )2 C. H9 N+ F' I2 g/ F
{0 u" r0 D  y  y* `" I9 b
        exsound_select = data;
  N) v- k& n( N& Q/ `2 H' C! q- ?}
+ A0 _! a; ^9 J" B3 |
: N$ T( t: q; ^+ \/ s2 I8 M; TBYTE        APU::Read( WORD addr )' c/ l! P# ~3 L. @$ n' ^
{; H3 C9 w  J  O0 ], p
        return        internal.SyncRead( addr );* J' Z0 U! y/ R; B# n, M, n6 N
}. i4 E$ M7 f0 i

5 s, X8 D2 h% T" a/ evoid        APU::Write( WORD addr, BYTE data )
' B% r0 U% b& {' }& K3 g: i{
$ |! u& q" l5 t8 w        // $4018偼VirtuaNES屌桳億乕僩' u3 h* G: b3 k* `5 U- }1 x. O( A
        if( addr >= 0x4000 && addr <= 0x401F ) {
8 ]! F2 N6 g2 r4 z                internal.SyncWrite( addr, data );
9 x, c; f  N- p& B                SetQueue( nes->cpu->GetTotalCycles(), addr, data );& n/ N1 M( H4 |1 D+ M" }" P
        }9 w$ R( n9 I6 e
}
$ _# Z2 Q7 S, i1 u# L/ P5 T4 G- \$ d$ @
BYTE        APU::ExRead( WORD addr )
- X- `: K6 h, V2 l/ E$ t, H% o, C{
- r- M( l6 S9 L4 p$ |! r  sBYTE        data = 0;6 ]1 B+ i+ }0 ~7 p, ~* ^

1 A0 Q7 a! D, t6 o9 o, g. f% _        if( exsound_select & 0x10 ) {% a4 j  [& t8 n' @
                if( addr == 0x4800 ) {
5 b; r6 u( n! |& C                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
( _5 M% B4 m  B6 R                }
& C0 a" u+ t9 w. ?/ b2 C5 A+ h, w        }
$ \( `: p) _4 d        if( exsound_select & 0x04 ) {/ V7 W" I' Y$ v8 u
                if( addr >= 0x4040 && addr < 0x4100 ) {, I3 ?% y! j. F' r0 W6 _
                        data = fds.SyncRead( addr );
! E4 b8 n) |& D8 j% H3 v                }- ?. ~) F2 ]" H# F
        }% I8 ?. e) j) C! h
        if( exsound_select & 0x08 ) {
3 l' j: d& r2 [                if( addr >= 0x5000 && addr <= 0x5015 ) {: W0 }" J6 {# P4 j! I- u
                        data = mmc5.SyncRead( addr );
$ G& J4 w. S+ I+ F$ h                }
+ z5 O0 F: q0 h9 }) Z$ S        }# S5 n/ C! |, p* C! T) R8 b

" |& H, O' w2 ]# a# C* {+ Y        return        data;
8 v3 a& }. V$ @9 {7 ~# ?+ y# ~' Q}
+ S: \& l- C0 s$ N1 ]( g7 ?( u( A% ^- |, |- c
void        APU::ExWrite( WORD addr, BYTE data ). i- T% y$ `7 u% g
{
1 h& ?' y, _  ^+ \        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
- h3 Z& @0 q, v. f1 C/ ?
8 P- r8 x+ p2 w, c5 s        if( exsound_select & 0x04 ) {
" s0 c- z/ C$ {  v                if( addr >= 0x4040 && addr < 0x4100 ) {
5 ^# M8 H4 }. f3 s. S                        fds.SyncWrite( addr, data );
# L1 m/ J+ D: S8 W$ E1 O. |3 s                }
& Y% w0 X5 L2 m5 z4 w( r+ ]8 K        }$ G- c, b, i$ t+ |8 x; C+ ?
" \* O, c3 w2 b0 ~7 x* a( I
        if( exsound_select & 0x08 ) {
* S* A  z; i2 Y# t" o                if( addr >= 0x5000 && addr <= 0x5015 ) {( ~8 L2 s0 E5 h) P: u
                        mmc5.SyncWrite( addr, data );9 t: w3 T4 |2 u! q: g
                }4 z3 K- P9 [- Q& j7 W2 v- a
        }
9 [! i% {- r# e1 C' {2 D) Z$ m$ s}3 Q" c+ R, r- U  {( j3 c, X, u; V* G, a
! w1 h* Q! e8 Z$ O$ t. ~- k
void        APU::Sync()
  J1 }1 s: \1 V{
9 k1 i! Q# s7 a  s}
( }" {2 i! b+ e/ D
  H# c) O" S5 [$ h8 Z* svoid        APU::SyncDPCM( INT cycles )
5 J) x! F9 x" Q{
: P. k0 X! C6 |. T        internal.Sync( cycles );4 R1 C6 J! M% o# W7 D
; C' H* Q) V! p% O8 h
        if( exsound_select & 0x04 ) {
4 f3 I3 K) A. O' {                fds.Sync( cycles );+ m. \( [/ J1 w5 |+ X
        }1 G: X* }$ R! n. c% b8 I
        if( exsound_select & 0x08 ) {
/ ~" U0 h0 v! k: ?                mmc5.Sync( cycles );$ F* G% ?" ?' t! p- g: S
        }" G' C' y% T  D+ s
}: g* `  ?7 Z; g3 z4 v
6 V& e9 O) N: B3 I' o
void        APU::WriteProcess( WORD addr, BYTE data )
; O( _: G8 C6 x# M$ E/ u{$ w; b# G1 p* J# i
        // $4018偼VirtuaNES屌桳億乕僩6 G; i2 I( D7 a; X" w) ~$ m
        if( addr >= 0x4000 && addr <= 0x401F ) {
6 x! C$ x  T0 N6 s0 ?2 J% X                internal.Write( addr, data );
4 |- F# L, o$ E2 P1 z% X        }
& i! V9 {) @: u1 U- Y% [}
. N. _% S4 `( `( [. n2 z' m8 C1 a# ?9 v- [6 D
void        APU::WriteExProcess( WORD addr, BYTE data )
4 J$ D: e2 i9 W4 ^: T. F. B{
# _5 _& G6 C6 H7 W        if( exsound_select & 0x01 ) {2 `& a( a, X% q9 E, Z4 w1 r" R2 P
                vrc6.Write( addr, data );6 ?# ?8 N2 e6 {& B; S( l. |- H" m
        }" ?3 c4 W  U  v9 y2 _" {
        if( exsound_select & 0x02 ) {' Y7 U& I% ^) f! t' ]/ f
                vrc7.Write( addr, data );) F( m% x  y1 o
        }+ J4 n# ~% T7 M/ H1 g
        if( exsound_select & 0x04 ) {# T  m1 N0 V& S
                fds.Write( addr, data );) Q6 d, G+ z2 ~# Q$ h8 }; u* ]
        }
9 ~2 O4 \: s. c" F5 f; C- I1 U8 u- O        if( exsound_select & 0x08 ) {4 L4 B/ S1 `7 W$ V* d
                mmc5.Write( addr, data );
' }) S/ ^& y& x  v        }
& c- j, |( @# N6 w: y) p        if( exsound_select & 0x10 ) {
3 I. B" A- _& Q+ c% U                if( addr == 0x0000 ) {2 k/ A% y9 ]6 w! N
                        BYTE        dummy = n106.Read( addr );
* |  Z1 V3 h3 {" I: ^                } else {' q$ F5 m9 e2 N- V* I) P5 d" w
                        n106.Write( addr, data );
8 N2 F1 T; [- O8 T$ v2 T                }: ^, j  s. s" f' w" M
        }- ?7 R/ x2 R1 J# ?
        if( exsound_select & 0x20 ) {
* m8 ?& g9 I5 ?( m                fme7.Write( addr, data );
/ H2 N7 G" E; y! q6 _+ Y        }
. H3 Y- j/ M- T4 j: t, K* K}
" K+ ]' X6 S  {' p8 K' {9 u: D/ R1 n% o$ V3 i6 r9 h
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize ). U$ b# H/ P, H+ \5 r% H0 N
{: y4 P* G# X; Y
INT        nBits = Config.sound.nBits;
+ b' s. e& [8 l5 S# x$ m+ z, HDWORD        dwLength = dwSize / (nBits/8);
$ ^# w) h: o& F5 \6 D7 t" E7 iINT        output;: {7 Q2 @+ [/ r& [' ^' V7 Z) o
QUEUEDATA q;
7 I  P3 K! j$ g: A6 O( b8 oDWORD        writetime;
- ?6 V% k% f, B+ v0 Z- i+ y1 g5 L
LPSHORT        pSoundBuf = m_SoundBuffer;0 A% W- `; r& z& s; e/ ]8 J
INT        nCcount = 0;
1 X# F; k( j6 Q; ?. `# U. m* M9 P
INT        nFilterType = Config.sound.nFilterType;8 ?* \( ]9 P& w
, K# Y. D( m; A: [
        if( !Config.sound.bEnable ) {; c2 F6 j3 w3 C
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );7 f9 r1 b+ q% V
                return;
3 h/ v) {  b7 r; R        }
/ E0 B! a. n* G+ C3 b
! C, }+ f2 y7 M/ K% D$ H  B        // Volume setup
; @$ i! K% V  @- m' F- v        //  0:Master
5 M, {0 j) u) i& d  A        //  1:Rectangle 1
# @4 t' e4 n, ~: f        //  2:Rectangle 2
: D7 [6 A; d9 j) {        //  3:Triangle
8 z5 F- A% I# s* ]1 W+ u        //  4:Noise
! ^) J7 R% ?, Z! u# d+ i& s        //  5:DPCM. `8 [  p; e. q' C: _) k% p0 R
        //  6:VRC6; @7 O* _5 v% Z1 f. A, o
        //  7:VRC7
; d' [+ g/ U; @1 l        //  8:FDS
6 z* a/ Y; S2 d5 M' e' ~        //  9:MMC5
0 c$ }9 b! }4 {" e        // 10:N106
  O$ _0 `) X4 H) M( A4 i4 ]4 _3 U        // 11:FME7
" i8 p2 _. L1 t( {+ u        INT        vol[24];
6 u( p" u* z2 [3 ]9 ~3 G, J        BOOL*        bMute = m_bMute;9 ~1 B, P, C7 l9 b
        SHORT*        nVolume = Config.sound.nVolume;
% m: s$ d  R4 q- |  D* J* R% `
. g1 Z/ r3 R, G8 J; @        INT        nMasterVolume = bMute[0]?nVolume[0]:0;5 |+ W& C$ L: T3 [

' B8 V9 C4 x- w" G( n% Z        // Internal
( H4 m2 ]4 d+ u9 R$ H        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
$ J6 H+ ~% p, a7 _' F& B1 G$ T+ w        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;, |, V: a, A# d6 F
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
" F, Z# t! p9 I+ q$ W  x        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
3 K% ^2 F2 f; l2 S5 [1 g' i        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;2 x1 H& f3 K3 B6 ?# _
3 N/ J( W& J* ]2 N
        // VRC6
" N: w/ W/ @7 H: q: g        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;6 s" B9 A- }5 E  G: f! v0 S
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
" W% m1 m# k3 ^% Y* o# R        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
& L0 e  R2 I) N! J! {
) U. d4 Q9 ?8 C, d        // VRC7
. j3 A- A  y9 @5 k1 e. Z        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;  P7 ?( |/ [* \2 X0 k8 V# X" {

. `3 E( M9 S' P8 P) m        // FDS# l( u0 _- H' y! F% K' }
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
) o5 F) S; X$ `6 K% N! m, E, ?7 t
        // MMC5
& o* }# w" P' }0 s2 S  I        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
! }& T8 W& i. n  o        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
8 H" k8 ~* H2 ]        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
- s  ?. w" o+ V. x5 ]: ?' j4 p# a
  X8 t/ E1 J: w( E9 a        // N106
$ q/ _) N5 A7 [4 B( ^# X0 _& X        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
) h5 Z  L+ {& ]" l) T2 U& _6 W        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;1 g- v: \8 k, a
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ q, x% f# q$ H. h' }& K# e" C        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;/ v; B. l! [* a
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;7 L0 ~) c# k- ~6 ?6 Q% K4 u
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, j/ g+ q  q. B1 y* \        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
/ ~( q' W5 C. e        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;# a2 z& E8 w7 F6 t) ~  [

) ^- R+ n' y  C- R& q        // FME7
) p9 w$ o" ~0 y) H4 Y        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;# v* Q# _  P. w0 O& e8 f  _
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
& p9 k7 W" \, D4 r% J9 j6 s        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
. |8 ~+ e8 v4 A+ }! `0 J
- _" B+ u& P" r//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
% P; l$ D7 U  q' o. G, p8 S        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;8 E/ K+ W" @4 ?+ m8 h
" N( d& L# c$ s2 j
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟9 @$ |, c) J3 _  L0 z
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
! t) y  M" j' V* n, ~# i" j                QueueFlush();
( Q& V- n7 a; [        }! s$ M3 ?) _# n( Z  P- O& }, L3 `

" `9 L$ q* i4 y0 ?, o$ ~. x        while( dwLength-- ) {
3 B" ~7 I. N2 f1 r! U3 C$ P/ [                writetime = (DWORD)elapsed_time;' e" G6 u9 i/ }2 `) h

+ V- O/ t' S# d% |5 u5 d% ?                while( GetQueue( writetime, q ) ) {
, I4 J4 Z% X( ^4 e9 r5 V8 h2 {! _                        WriteProcess( q.addr, q.data );
0 a8 G  U. C3 Y1 ~  `                }( M- o. Q0 g" ?/ b
& N* I  S, B/ M5 b8 z3 z( S2 N7 y
                while( GetExQueue( writetime, q ) ) {, E' @, V' o  c+ u9 b
                        WriteExProcess( q.addr, q.data );
+ H6 g  A4 P, ~2 p( t. s                }6 Z" k1 `- |8 a7 W+ d1 U! q

7 ]2 S2 W; y. Z& L+ g/ V+ K                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
: ]) X3 X' K# R+ y                output = 0;" W4 T9 r5 I2 c$ \6 {$ X
                output += internal.Process( 0 )*vol[0];6 l" F# u/ x8 J7 S- W7 d9 Z- B
                output += internal.Process( 1 )*vol[1];
) g4 z& i$ d8 E                output += internal.Process( 2 )*vol[2];: u# R! O' j/ a) \% ]7 r6 k
                output += internal.Process( 3 )*vol[3];
$ V) o; s( a: j# z7 u                output += internal.Process( 4 )*vol[4];
( O  _$ L8 Y. U) E$ J+ g# d& X) u
                if( exsound_select & 0x01 ) {: b( v5 e% `, J9 w6 A5 V
                        output += vrc6.Process( 0 )*vol[5];
6 f( N( l5 n* V5 _; t6 L                        output += vrc6.Process( 1 )*vol[6];
0 g$ a, P3 _% Z7 O( }7 H                        output += vrc6.Process( 2 )*vol[7];
, q. m, |% n  m# G! }                }
# [* U9 [3 x3 A  I8 @                if( exsound_select & 0x02 ) {
, b# f& {5 `# V  u                        output += vrc7.Process( 0 )*vol[8];) v1 J, Y" d& u* k0 ^4 }/ h3 k
                }/ L' v. |$ Z- P! g; `- Q' ?
                if( exsound_select & 0x04 ) {
! ~8 t" G2 [0 |& T; v' c                        output += fds.Process( 0 )*vol[9];
7 A- l3 l- r$ ]6 k" E% W                }, ?$ t2 e+ a! }6 Y) f( u: x, [
                if( exsound_select & 0x08 ) {
8 i+ Q1 E+ F! |, {+ S/ i                        output += mmc5.Process( 0 )*vol[10];
8 N9 A- }1 L) G- Z7 d2 e* Y4 n                        output += mmc5.Process( 1 )*vol[11];8 p! p2 X& H1 x' B7 S% \: Q
                        output += mmc5.Process( 2 )*vol[12];$ ~" c3 y( I* u6 X
                }
; }: F5 m. ?  L. |% Y! m: Q% {4 k                if( exsound_select & 0x10 ) {
; r, |- O7 l9 s% |9 F: u) b) V$ U4 U- P                        output += n106.Process( 0 )*vol[13];* M2 B/ W/ V( |" y. {( t
                        output += n106.Process( 1 )*vol[14];: F0 i* n+ m3 ?; R4 W- n# A
                        output += n106.Process( 2 )*vol[15];
, N4 G% B- N- a                        output += n106.Process( 3 )*vol[16];
: Q, r. W# n& A% |$ H* r: j/ A  f                        output += n106.Process( 4 )*vol[17];
4 e; U5 j% i3 }4 J9 f* E                        output += n106.Process( 5 )*vol[18];/ P2 A4 L: f* ]( [# s( R( f
                        output += n106.Process( 6 )*vol[19];. q/ B' ^6 X, C
                        output += n106.Process( 7 )*vol[20];
5 @" j3 G3 f" g& a) q                }
% A: h& r8 ]. }& N1 ~, O/ [                if( exsound_select & 0x20 ) {7 ?) C# Q9 O) J4 e# s( {+ p! K8 t
                        fme7.Process( 3 );        // Envelope & Noise- |' K1 t- g) k+ g
                        output += fme7.Process( 0 )*vol[21];1 w6 F4 W& s0 L% G7 @$ T
                        output += fme7.Process( 1 )*vol[22];4 I* k+ v$ Z# p$ ]: b- C
                        output += fme7.Process( 2 )*vol[23];+ Q1 m7 k' ?( Q: h
                }( o  O6 F: X# c
0 d& g6 T9 k7 n* a4 E# I) i0 \( o
                output >>= 8;
; n+ R1 R0 W3 U2 [4 x% m: `$ u1 e3 P5 r. a0 a
                if( nFilterType == 1 ) {  q  t0 X, ]$ R: Z$ B
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
2 k2 G0 ^' e4 ?+ D0 h                        output = (lowpass_filter[0]+output)/2;
4 @7 _4 O5 E6 y0 B9 S; q3 O) v                        lowpass_filter[0] = output;
  e8 U. y) G& \' l                } else if( nFilterType == 2 ) {
0 i9 f2 B- x( ]8 p$ ]7 m/ ^. k9 N                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
$ }! e, B, e& s2 G$ q/ _& ]* h" q- T3 m                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;: d. E+ y; i4 A" y( l- ~2 l- H% L
                        lowpass_filter[1] = lowpass_filter[0];
# J1 _$ ^8 O& M% U( \0 a7 M  w                        lowpass_filter[0] = output;
- T6 [- l- @* I5 C" L                } else if( nFilterType == 3 ) {
" x4 P; T9 x! G3 T" J                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2): k$ y; R" J, \+ A
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
1 M, o2 Y8 l, u! e' @                        lowpass_filter[2] = lowpass_filter[1];1 a2 x( ?% v* s' q3 e1 Y- v* l
                        lowpass_filter[1] = lowpass_filter[0];
9 w  H, f) h) |  k                        lowpass_filter[0] = output;
7 ~3 U. P9 ~' `9 N; S" |                } else if( nFilterType == 4 ) {! `9 l/ V8 D0 x  H$ G6 z  r
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
. K* P6 V: F) t  r; L$ P                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;4 Q; U! q; D4 q0 \6 m$ x& A
                        lowpass_filter[1] = lowpass_filter[0];
5 D' V, A" `( o9 s3 y+ ?1 e                        lowpass_filter[0] = output;5 P  q( p4 m5 O+ a* e
                }3 j% w# G; j& {8 Q7 V4 {7 _
6 ^+ L. O3 b7 c6 o9 Y9 h9 H, ^9 U
#if        0
: z) B5 x) ]7 F0 W& l5 C1 S$ w. b                // DC惉暘偺僇僢僩2 h) n7 ]- H" x6 H: U( M4 S" U
                {
% F+ o, n' L1 O4 R                static double ave = 0.0, max=0.0, min=0.0;) P5 q. H2 Z& M1 E  h- m$ @
                double delta;6 e0 @  M2 e4 O  N4 H
                delta = (max-min)/32768.0;1 x& l- m, f* E* k9 w' V8 ?) L. s
                max -= delta;9 U3 U7 w" S, J' a
                min += delta;
  C- z( n# q/ z& G5 M                if( output > max ) max = output;! K7 ~5 D3 t; |
                if( output < min ) min = output;3 s) S# J4 b1 P) c4 |! M, A
                ave -= ave/1024.0;
- o5 U& d: b& M" S8 j3 s$ ^                ave += (max+min)/2048.0;9 ~3 U# Y  k0 I5 k
                output -= (INT)ave;
% d$ z+ M8 u# e) Z* W                }
: N7 o8 p! S3 n: f  ^$ o+ [1 ^#endif2 g5 a, ^' c; P8 u
#if        1. R& o' d3 ^1 z! j
                // DC惉暘偺僇僢僩(HPF TEST)
  N; @( V* U0 \* |4 r4 Z                {( m" h+ l6 h0 C
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);0 B" a; f( }& X" B1 M
                static        double        cutofftemp = (2.0*3.141592653579*40.0);+ T* b! Y7 P8 Q- y- h4 ?
                double        cutoff = cutofftemp/(double)Config.sound.nRate;5 @' q' \4 E6 }# l
                static        double        tmp = 0.0;. m2 u( |% E" z1 b- Y, |* W
                double        in, out;3 y5 T3 [2 n1 X# `9 b

: X9 I7 d. Q. g; g8 _                in = (double)output;
% @# d/ t  S8 W6 \6 A                out = (in - tmp);
6 T! e# Y8 z7 O1 o" n! q                tmp = tmp + cutoff * out;" B2 O, l0 {1 E4 L4 e7 j" V

1 Z6 ~! f- X% I& i& ~                output = (INT)out;
/ Q% u2 a# l6 v: _8 w                }# {1 U& P, H- H8 @
#endif
" |/ P: J( u, b8 n& k#if        0
) S3 u" P* D/ }/ n) G& u1 D  J                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
; v+ @: h  f; J! f0 C+ k                {: v- N0 u; a' c8 h& z
                INT        diff = abs(output-last_data);
8 [" z4 }: U5 z: H' v$ K9 p, r                if( diff > 0x4000 ) {" T7 x: G4 x. G9 y7 Y( m
                        output /= 4;
  @: u- P3 C9 G                } else
" ^" J) S# D* t$ D5 e& r                if( diff > 0x3000 ) {
! m) a2 E) l! Z* l- r  K                        output /= 3;
" k) u% K" F# Y' Y                } else3 F. Q1 g6 A3 }* h( o* H
                if( diff > 0x2000 ) {
  y8 N) D5 W( d, j3 l' t/ }                        output /= 2;
% Q$ f, s6 X" w9 D8 Z2 i, {                }5 s$ h: p6 w! r6 R
                last_data = output;  g5 T# s* z" o
                }
( `2 h$ M0 R! s#endif
3 i" \6 \& N6 ]5 B8 v                // Limit' W9 q9 C# z. @( Q2 D3 u/ f
                if( output > 0x7FFF ) {4 c4 N; G: ?# {
                        output = 0x7FFF;& H; J0 h4 H, Z6 B8 Z
                } else if( output < -0x8000 ) {
! n: x4 r3 s4 c  I                        output = -0x8000;
. e4 {3 I, Z; j# L4 V8 q; q& C                }
& |3 n! P9 |* M& O4 G/ k3 C+ A. i6 ?- ]1 Y1 O
                if( nBits != 8 ) {" g3 a; C+ o$ H6 E
                        *(SHORT*)lpBuffer = (SHORT)output;- @6 m, J* }" y
                        lpBuffer += sizeof(SHORT);/ I5 |/ M7 _- C) q/ z( I
                } else {
: p" u& O. y# H4 D                        *lpBuffer++ = (output>>8)^0x80;
) B) E4 M8 U* }" O                }
8 \5 n2 ?$ C4 H" d9 V7 V  y, X( c/ _! [* Z; O
                if( nCcount < 0x0100 )
  I7 b% V% q, P. J' T( I/ G1 s                        pSoundBuf[nCcount++] = (SHORT)output;; a$ O3 \! f2 u" u( \, v
0 x  E1 e& Z% s: m( R5 M- L! Z3 v( {( |
//                elapsedtime += cycle_rate;! O& p' u6 h# X9 n2 O
                elapsed_time += cycle_rate;, S% D0 K3 }9 {' H+ M: P
        }% j2 Q  i9 o; q( s, l$ M

. a3 A& u- Z: i  S7 s& o  u5 I5 I#if        1+ ?5 Y9 `) M* M' Y6 A
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
' M- e2 A$ |# k9 D; v/ o                elapsed_time = nes->cpu->GetTotalCycles();8 _7 _) ^; N: k( I2 E& z
        }/ m; V: _9 k  z3 J
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {% R  @" Y7 a5 y4 Z2 u! c, P! X4 {
                elapsed_time = nes->cpu->GetTotalCycles();. g: N3 D0 ~! h* p  W
        }2 R% ^$ a) Q# {3 C7 T
#else
) r) I) ^4 a# e# k        elapsed_time = nes->cpu->GetTotalCycles();
1 B: [( h7 e& g% O8 X6 m: M#endif
( P& Y  J; Y6 H& t8 _0 l}8 H0 X5 }3 y: m& b9 E

" r$ V; U9 L' d1 Q$ G' e$ S// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)) m2 ^* C5 W4 V# \
INT        APU::GetChannelFrequency( INT no ): X2 Q$ S2 g+ |' @( a
{
  z5 t: w& K* Y& B* Q2 e        if( !m_bMute[0] )
5 G- P( K7 {! x! G1 b                return        0;8 E+ ?3 @, l1 ]  z: [1 V! X6 S7 c; d

/ `$ O) F) K' D: N5 P, j        // Internal$ R6 {# N" i- P: z2 N
        if( no < 5 ) {
" _5 `3 `! }  ?/ I, Z9 U; H1 q+ W( N& P                return        m_bMute[no+1]?internal.GetFreq( no ):0;. ]3 l* w- u( y- G
        }3 [) _4 @* U# ~# y" l
        // VRC6
% h* b7 u- l: H4 X% c        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {6 u: P5 y' W( K8 s
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;, R! h. n! f$ ^1 _7 Y
        }
0 }, R5 R! u+ I- v: \! \        // FDS
+ ~6 y4 W+ Q; t6 s        if( (exsound_select & 0x04) && no == 0x300 ) {6 v4 i/ j4 v) i$ q
                return        m_bMute[6]?fds.GetFreq( 0 ):0;# @- L9 {7 ]6 D& E: j$ x
        }4 C! t5 y7 |0 p& r: ^# Y
        // MMC5; n: n3 L0 \" @) ]
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
; `, z: l( _" o+ }" Q$ U                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;* C9 }% u. Y5 h, }0 g4 Q
        }
7 O9 J" i& \* B  ^6 p        // N106
4 [: s3 t+ a4 V2 c1 i9 d        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {# b4 w  @6 a# V) A; j- j
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;0 ~1 |% B) Q1 u5 ]6 l- v
        }
% b2 _6 w& V' Z" ^( u1 V$ [6 f+ }        // FME7
6 V5 J% `( }  Q' M        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
/ J/ ~" w. D3 o7 N9 v! m                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;$ Z& a! G  d$ W* O
        }9 e" W6 P; {1 u& X! C
        // VRC7- [- g! f, j# V( Y7 e  b4 @
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {3 ?# c% |% i( i4 p# y7 I
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;3 S/ [3 x) x9 f  g9 m: U& x
        }
+ J3 i  b7 j) q. Q0 Q; x        return        0;" r2 {( Y0 q1 @* W$ O
}
" ^5 b0 U' }* Y7 M* [. a
1 Q6 ^+ y7 b3 J% G// State Save/Load' \2 r( b+ |5 a9 p
void        APU::SaveState( LPBYTE p )
) m% b+ r3 ?3 G  J; ?, P{$ |% H4 v' u0 j7 C3 {/ I3 `, H2 s' Z
#ifdef        _DEBUG8 E6 n8 ]2 j0 p5 I$ [# C: i7 q
LPBYTE        pold = p;
+ \- K; i$ z8 T& v+ X0 @1 E/ A#endif3 [( C3 [/ n6 M8 F

6 b! @6 u) _) O$ L, U+ [, J        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
1 Q4 W  h, Y+ i2 ^6 C        QueueFlush();5 G6 ^0 u% a' E  ^& T* l

7 I' o) H- o( n( U        internal.SaveState( p );7 J6 ]* J1 M8 k( _4 \
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding0 n  Q5 n" M: G
% X; S* T. ~- @" r# _  @
        // VRC6
8 D3 v$ {- F( n9 z        if( exsound_select & 0x01 ) {
0 h, r) x+ n3 s                vrc6.SaveState( p );
# P& X* A# N+ \+ s( {                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding5 F# y+ J- r! e4 |8 p8 E
        }# t" O2 K. ]+ x: c: Y3 c
        // VRC7 (not support)
6 w8 A5 i( Y* A9 @' M        if( exsound_select & 0x02 ) {% r/ x, `4 R5 j8 Q9 _% |
                vrc7.SaveState( p );
( ?3 s2 E1 q. h  x) k) c                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding0 s0 _' I  P, t. v8 l
        }) c2 ~" i1 _1 X6 I+ A" H3 X! i5 h' [
        // FDS
5 N, r9 C. a/ E7 \( M        if( exsound_select & 0x04 ) {3 O0 o# s& {+ [$ _
                fds.SaveState( p );  `8 K0 }1 D8 Z# y" a8 W
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
% F7 m1 Z8 H2 h. J        }" i# v& [8 f/ R+ V7 q7 z7 e( z+ D
        // MMC5/ _' ]2 L& E6 L/ @% Q8 l
        if( exsound_select & 0x08 ) {
, a, P& F% ?/ O+ z. n                mmc5.SaveState( p );
- H; d3 M! _$ Q9 v4 d  R                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding, `* @3 p( A! M+ g% h1 {; r
        }/ O" T% S" ^, |! q$ ?% e1 H
        // N106# l2 `/ J( b6 x1 s- O
        if( exsound_select & 0x10 ) {) G$ s' c2 d( H" q! {
                n106.SaveState( p );
# F0 p: N. g5 I, I; l: R& a, ~                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding" Y& P5 `3 m( H
        }
: Z* Z% l3 M6 }# p: h4 l6 t1 J* |        // FME7( r$ S# k- l0 G; R" ~7 u( q2 o
        if( exsound_select & 0x20 ) {+ D) R0 z4 X+ h, y7 E" f( J
                fme7.SaveState( p );
& m) l5 t$ q6 [1 ?* T" S' H$ n                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding6 Y$ l% {, b; t6 s4 r
        }
* W0 d2 V/ K/ Q2 B' q$ y8 S# s6 B
9 K8 s6 `; A0 k" A5 r9 \3 C#ifdef        _DEBUG
  h$ M: g7 f. d7 qDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
) ?# m% Y1 L. h3 x9 K& L#endif2 \8 y7 I! r, ~  J& Z+ V- M
}
2 u$ y: }& O/ R: {1 R
8 C& [( O! T) Nvoid        APU::LoadState( LPBYTE p )
, N* w/ J# y) Q! B  `) R( z{
$ Z, h: Y- l9 G1 l        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
+ Q) y9 _6 E* \0 U* ~1 s/ J  ?. b        QueueClear();0 y5 K% k4 Y: l9 {1 E  O) p/ y

6 M9 v- u# N9 u* Y3 H3 n. x7 w        internal.LoadState( p );
/ f* F% K' @6 c0 |6 u        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
6 Z+ ~# B* X3 A$ Z( S; Q. U9 q) Y, q
        // VRC6' a( j+ X" f+ m& L
        if( exsound_select & 0x01 ) {
  m; J8 e6 G/ V* u( O: w                vrc6.LoadState( p );5 C! L1 b  u* T6 Y
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
; T5 p! N; A( i        }
4 U; L$ @0 t5 ]: h3 F' c7 T        // VRC7 (not support)# C1 l6 E( d  u- o- P6 m2 @
        if( exsound_select & 0x02 ) {1 k, g6 K& h. k) P' L2 n
                vrc7.LoadState( p );
0 [4 l2 K" _. I: }                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding% t% h7 x! R( Q; c; E* ~  ?! R
        }1 m" ?9 v/ W. o  y5 p/ ]
        // FDS) C" t8 A0 Y* F/ u/ @
        if( exsound_select & 0x04 ) {4 \8 j4 J$ @  M8 u
                fds.LoadState( p );3 t2 z* G3 l7 B, w. ?
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding5 R0 w0 H) d' p& i: U
        }2 q1 |* e4 r: L8 P* H4 v
        // MMC5# U& \+ R5 d( b; ~! E) e% ~; ?! a4 O
        if( exsound_select & 0x08 ) {
' t! d' W; S& s3 G. `, L- H! Q                mmc5.LoadState( p );
7 p" ~7 x( e5 B                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding" B/ L9 s* z' H# L8 `
        }. E+ S6 E1 [; b% W+ O0 f) T
        // N1069 L" w- o* R0 Y+ \- A- w
        if( exsound_select & 0x10 ) {
7 [$ Y  V* A" {$ K% |) v                n106.LoadState( p );
% ?) M% o$ D% [* a                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
& T" k" l2 j' D" v- T; e' z) T        }$ u# @$ X  ^8 [$ E4 _- w
        // FME7
$ `5 X( n! w% C4 h        if( exsound_select & 0x20 ) {
' ^; G7 p, p! U2 ^                fme7.LoadState( p );
5 w* {0 J+ f0 _& ]9 T                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding4 b9 M+ q- M4 q9 ^% m0 J
        }1 n6 s# N& {6 G) l
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 5 f- Z) B1 Z4 K$ M% T9 R# m
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。: d' s, J/ k' H* r1 ?5 Q( b
感激不尽~~

- e6 {* Q5 M* R2 s& p恩 我對模擬器不是很有研究,) {+ O4 D, H( v! C
雖然要了解源碼內容,可能不是很困難,$ E" c6 y! I9 W0 k5 h5 ^, j
不過還是要花時間,個人目前蠻忙碌的。" ^; z9 w* D6 [' o) I4 d- Z6 N
& ^% ~+ }# A6 S/ i; U! M8 F/ L
給你一個朋友的MSN,你可以跟他討論看看,
: ?; Q* `! T3 g/ [4 ~# ^他本身是程式設計師,也對FC模擬器很有興趣。
  G  z$ L" F% n' s
! D1 n  D: d: \MSN我就PM到你的信箱了。
/ ^$ L) d' P& n; n+ f8 O8 N! @( _4 F9 e4 S! D/ g
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
, R6 V1 |! o# P$ W! W4 ?; ?- h呵…… 谢过团长大人~~

7 O! ?7 W( b2 u0 H# n
2 R0 W, w! L+ O& L( r3 g哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 # G" ]. f) j5 j* V
团长的朋友都是神,那团长就是神的boss。
/ z& z- S& V7 d. s
哈 不敢當,我只是個平凡人,0 T* P( O, r7 \
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙# m/ \. ^5 u; U& {/ O
ZYH
4 j+ n: U# S3 EQQ:4147343062 Q% z6 ]8 e& @! ]
Mail:zyh-01@126.com6 V2 `9 N! K8 |

9 w5 v. G% o3 `9 R# i他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
' L% b' T4 {5 ^再次对团长大人和悠悠哥的无私帮助表示感谢~~
) h& O6 x. ~$ V5 o- N# v' q
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-2-10 10:46 , Processed in 1.086914 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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