EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。5 C( r6 X+ Z6 r2 T
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
! C! o& o, w0 K# `这里有相应的模拟器源码,就当送给大侠了~~8 k1 v  P. \" F' i8 ^
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 ! u5 R% x5 g+ S1 E) I5 ~4 i0 ^8 b
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。! ]% @$ ~$ O, q4 u  _5 J" n
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
. e; ?1 ]5 R( T( I8 U这里有相应的模拟器源码,就当送给大侠 ...

8 m3 T5 b& B  U3 V8 O$ V8 d: V聲音部分(Audoi Process Unit = APU):+ z$ h8 G4 F8 S; u& g
.\NES\APU.cpp) a2 D# S0 V: z) n/ A1 H7 Z
.\NES\APU.h
0 l( u8 G9 }' n4 ?6 `  q6 W9 N: @, i

1 C0 }- P8 e2 V7 ]2 A影像處理部份(Picture Processing Unit = PPU):
1 Z9 I& f  b+ S% Q8 _8 U  f4 C) y.\NES\PPU.cpp
3 S+ k9 A8 ]6 e3 m6 N.\NES\PPU.h# e+ f+ |% c. \! X& c- d+ i$ o: G

; l" m( M+ H- D2 S如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:! q# n+ n8 b5 e
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
8 b" _5 i9 C0 Q( y' Z7 L//////////////////////////////////////////////////////////////////////////$ F) K1 S+ B6 y4 P/ b* t; G1 p7 `9 v
//                                                                      //
8 c1 n+ m- Q4 W7 h6 t* @) C# n( J2 b//      NES APU core                                                    //
# t) c9 n5 {7 j* ~: O//                                                           Norix      //
: a1 f# b! Y2 a& k$ P//                                               written     2002/06/27 //  p+ h7 D: X) v
//                                               last modify ----/--/-- //
/ x# K" X/ Z0 O# v6 G6 v& t, o//////////////////////////////////////////////////////////////////////////. T9 Q2 P4 i- V7 C' Q* ~
#include "DebugOut.h"
+ A1 k8 k9 C8 r& i" n9 x#include "App.h") [. E7 {; W: R
#include "Config.h"( ^$ j, p$ p. \% T& D

1 ^2 B9 E! [' f4 x- c#include "nes.h"
4 W+ W! Y; S: m2 k: M) S8 E2 W0 M#include "mmu.h"' a. d/ ]" L# y$ Z+ y& f! z
#include "cpu.h"
# Y. C. l  a. E" _1 L2 {; u#include "ppu.h"
* S9 r: _( I& C: Z3 Q#include "rom.h"
- [) N1 B  U6 K#include "apu.h"1 ~& J7 a& T: [. O
/ ?- d* U. {$ O1 e2 F
// Volume adjust, r- n/ _3 a" w- A# l
// Internal sounds, U8 D, x3 N0 I1 |% U, v4 Z
#define        RECTANGLE_VOL        (0x0F0)
3 A" r' F$ s$ Q7 B& e" I#define        TRIANGLE_VOL        (0x130)
8 x2 n  m) ~  ?, k- i#define        NOISE_VOL        (0x0C0)
8 M  q4 N- s6 `#define        DPCM_VOL        (0x0F0)* w5 p8 X/ _! _# z/ W
// Extra sounds6 X( P( ?/ O# D7 c3 V% D+ @
#define        VRC6_VOL        (0x0F0)7 }! i7 U' M% n! q: d
#define        VRC7_VOL        (0x130)' c/ W& T/ p- V& l9 C
#define        FDS_VOL                (0x0F0)8 H- P8 X. z- k! g
#define        MMC5_VOL        (0x0F0)8 D9 l8 D4 ?$ C" |" e
#define        N106_VOL        (0x088)
# _6 T3 |  s; F9 H" Y#define        FME7_VOL        (0x130)
) Z) f- g* @0 n
* u7 v1 U! i; O4 r9 W8 ?APU::APU( NES* parent )
; Q% s; J* v( |# m{
4 s' s1 z. l* t0 V        exsound_select = 0;
# n4 H' a3 o6 [! y, [: |% Q4 j% f. Z8 n8 k- x7 s8 z8 U
        nes = parent;6 }7 i6 |1 i7 B/ Y! N6 n3 B( d
        internal.SetParent( parent );, w; Y* |) n1 k0 O; ]

2 {6 N( J( _; R' S' M        last_data = last_diff = 0;
3 a, P* ]# I2 n* h. @( p1 R, r5 {: {: A
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
' ~1 G/ U  d  ]6 m4 \5 t# r
" l- h6 x7 S( Q4 w6 @/ ?' H        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );# b+ X, f% i9 D, W) C
        ZEROMEMORY( &queue, sizeof(queue) );
; T+ v* A0 d( K        ZEROMEMORY( &exqueue, sizeof(exqueue) );9 c$ F+ L* o8 C1 \- y/ b0 \6 V! C

  B1 B- I! s& Z# o        for( INT i = 0; i < 16; i++ ) {
: U4 F; ~7 W6 |5 b0 s                m_bMute = TRUE;4 H  e4 E; f8 k
        }
  [* I! i8 j' N}
! o: [$ @. a5 r+ z. O
/ w, U# W* B+ LAPU::~APU()1 I5 o* I) D$ F5 T9 K3 k+ k
{
5 p/ e% M7 j7 \# ~# ~2 Y3 _$ }7 y}2 a$ E6 c; I) R/ i% Z
2 }# P) _6 [" N
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
& ^; K% \# ]5 ]% o  }( W+ t{
. J1 |" [, b# [        queue.data[queue.wrptr].time = writetime;
0 {# s: E$ J" w( a5 I: p        queue.data[queue.wrptr].addr = addr;( a' U9 N' S" B9 K
        queue.data[queue.wrptr].data = data;/ J' t6 T+ t+ \
        queue.wrptr++;2 R  P) N5 v% A; ?  o5 E( f
        queue.wrptr&=QUEUE_LENGTH-1;
) f( q% [" i: e5 s2 D/ t# c        if( queue.wrptr == queue.rdptr ) {
: h/ F2 ]  B" B- m                DEBUGOUT( "queue overflow.\n" );% A* }. E  f! J; |/ i1 r% v
        }
# ]# U- ~' `2 v}" W# O' T3 H# a
& \6 r/ a' Q( }  a* s
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret ), Y/ A% @6 [  T0 z/ I0 ?% v- z
{& L) i. h5 J# b/ {
        if( queue.wrptr == queue.rdptr ) {+ ~) s3 Y; Q/ o. M+ s0 r
                return        FALSE;
1 p* O  H1 J3 c, ^5 e        }- ^. d5 V$ J" t' e
        if( queue.data[queue.rdptr].time <= writetime ) {
1 P2 b4 ]; N5 @& F, B; \                ret = queue.data[queue.rdptr];
" G# f6 l* b" |5 A                queue.rdptr++;6 Q: P( {/ S. ~. M8 s
                queue.rdptr&=QUEUE_LENGTH-1;5 z) p0 p) Y+ T* L
                return        TRUE;& [  ^2 P$ l6 o: U7 r- h7 l
        }
1 Q4 M: E3 ~, T' u( m        return        FALSE;- `) n* `$ w+ l4 h
}
  U9 L' c4 b! x) ]% e) H
/ S0 h5 X/ A. ~( l7 W9 Bvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )7 L# Q7 d" T# K# n
{" l  m4 F8 w5 t1 i* H' m
        exqueue.data[exqueue.wrptr].time = writetime;  ~+ G# w& w  m4 R) O
        exqueue.data[exqueue.wrptr].addr = addr;
2 f6 n9 y4 O! }+ D1 v4 I        exqueue.data[exqueue.wrptr].data = data;; n* L: N% Y/ Z2 p" c# b
        exqueue.wrptr++;0 ]1 Y: w, d) b& j# d- w# G* U4 }% G
        exqueue.wrptr&=QUEUE_LENGTH-1;
/ i& p9 W: G- t3 H+ M) N5 C        if( exqueue.wrptr == exqueue.rdptr ) {4 d( p  S1 I, _% ^
                DEBUGOUT( "exqueue overflow.\n" );
3 ]9 y& Z& V1 c/ \: f' r0 s        }7 [1 x; K9 I  k9 }1 `  _
}
! P0 J. r' h0 A  D2 F
2 u3 h$ B. ~8 ], R* l* @' y$ {# ?  JBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )8 ~: H" z9 ?0 @& L! ^6 m
{' m+ K/ K6 m& w% X& Y4 O  Z
        if( exqueue.wrptr == exqueue.rdptr ) {
2 f5 o7 Z1 z; A$ N7 o% @* X7 U, o$ C* q                return        FALSE;* B! U- x0 ]7 I% p8 ?* l3 Z
        }
8 n) O9 T9 O* G9 K9 r- ^        if( exqueue.data[exqueue.rdptr].time <= writetime ) {3 N$ W  b, S, _& B; ~- R
                ret = exqueue.data[exqueue.rdptr];# g9 g+ P6 ~# s7 H" s3 |2 x* ?- T
                exqueue.rdptr++;& Y3 M2 z  u" w9 n8 d0 Y& k' A
                exqueue.rdptr&=QUEUE_LENGTH-1;% ]* A7 b7 P+ M* k  S6 P
                return        TRUE;* }( M2 ]6 t9 y! B3 j  q" D4 c
        }
( i. @1 K9 c( {        return        FALSE;
8 S; ?% n/ j7 }+ {3 x5 M9 V$ Q% J}  \; Z! f2 B5 p; ]

  \' Z( Q' C% [, ~$ I$ Hvoid        APU::QueueClear()
* L+ Z, [, R% c2 X{
  a! D( t# \) U# N$ f        ZEROMEMORY( &queue, sizeof(queue) );
5 K8 v# ^, ^2 Q8 G4 R# b        ZEROMEMORY( &exqueue, sizeof(exqueue) );
9 E$ \6 {3 m/ K' F}! Q5 A2 D3 ^  Y1 n; O$ `5 {0 n
/ a$ E; m6 H+ o5 l6 l# T9 u
void        APU::QueueFlush()0 |0 t5 X5 A3 M* A" V' I: L
{& K0 g. n5 p- k  A: o
        while( queue.wrptr != queue.rdptr ) {$ w- E5 P: W* q" s
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
; a6 ^  b2 R% a: r                queue.rdptr++;
( z! a. v2 D' k7 n/ _                queue.rdptr&=QUEUE_LENGTH-1;
/ h+ H, \9 [  @        }% U2 n" k1 M' `. p( {4 w1 s5 ]
4 Y* N$ b1 y+ x% b$ ?# i: p1 ]1 Y
        while( exqueue.wrptr != exqueue.rdptr ) {
+ ?* e5 s4 j# [( ^" `& R                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );! K" H0 u# d; J+ D$ C/ a/ m
                exqueue.rdptr++;
6 N- j0 T4 [( I( h2 G- u                exqueue.rdptr&=QUEUE_LENGTH-1;. X0 f( \7 b; [, W1 V1 I
        }
, A0 e; ?, r& [}
7 D+ U" a* ~2 ~9 o0 U' J" _
1 F# Q& y7 {& g$ h: @0 t; B" Svoid        APU::SoundSetup()( a* s  t- `- e* B  n
{
5 B4 V" i. q3 C; U* e1 b        FLOAT        fClock = nes->nescfg->CpuClock;
6 B, b0 k, D; F/ Q9 w        INT        nRate = (INT)Config.sound.nRate;
, V: ~0 \! u4 D9 B  }$ w# O        internal.Setup( fClock, nRate );1 N3 X0 ^! S& l' U1 c
        vrc6.Setup( fClock, nRate );( j& l1 N8 |1 }' X
        vrc7.Setup( fClock, nRate );8 N3 A+ g2 ?3 f8 O- g2 {0 {* M
        mmc5.Setup( fClock, nRate );4 X8 A& p9 r  P" H4 o
        fds.Setup ( fClock, nRate );+ u# y; H' h+ H; G- g! _0 p
        n106.Setup( fClock, nRate );& l* _0 S$ m7 h1 j# p9 u3 K
        fme7.Setup( fClock, nRate );% _: C- K* i# _, d; s- ~
}- y' K% ^8 c+ m( u' _2 O

1 v) K' D; {0 c9 Nvoid        APU::Reset()
3 `4 c: g3 ]$ V% s( A{
* L; _- V7 N) x        ZEROMEMORY( &queue, sizeof(queue) );
3 k2 D/ q5 }3 i) |1 R# J        ZEROMEMORY( &exqueue, sizeof(exqueue) );
, c4 |" z* b6 ^* o! y
1 |$ `) _: P/ R- ?8 k        elapsed_time = 0;
" _* m/ ~6 M. i
2 H) d: v/ x8 A7 h        FLOAT        fClock = nes->nescfg->CpuClock;! `  O4 I) k; U- B6 s
        INT        nRate = (INT)Config.sound.nRate;
; r+ l; O; P0 V5 \        internal.Reset( fClock, nRate );
# z, e$ n' Z( h& L        vrc6.Reset( fClock, nRate );. X8 k  ^% y; `7 _
        vrc7.Reset( fClock, nRate );
* O7 r! S; ^: ^- s. `/ q  E        mmc5.Reset( fClock, nRate );7 U. e5 a& t( D
        fds.Reset ( fClock, nRate );4 |8 _: N) N; G4 f4 ]
        n106.Reset( fClock, nRate );( j" Q  F+ S+ e( v
        fme7.Reset( fClock, nRate );
9 _. Y5 _' a5 w# W8 G- d
. K0 W3 @9 h6 ?1 v( H/ l2 A        SoundSetup();& O% }) T" j9 B' U& o, ?" Y3 l
}- g- x8 t' y. M3 l. Z1 W
5 _- v: t# I4 t) d4 j, J2 Z% O
void        APU::SelectExSound( BYTE data )% g5 Q  o" P  E, O
{
1 f# o: s) R, h9 k. a& F. j        exsound_select = data;
/ E7 d( L9 |  z$ F! E}
& g4 m! k9 v, V* A) x  R+ h& J7 U$ j1 G. t
BYTE        APU::Read( WORD addr )- A' c% g: w2 [+ N6 h
{
; ?' H  ]% Q1 W( @! r1 i+ R+ n        return        internal.SyncRead( addr );# l0 k) J: I6 i; e1 h
}: S$ }2 W5 `; \9 D

; l9 @4 p- S( E- b" Xvoid        APU::Write( WORD addr, BYTE data )
! \' m2 `; Y( ]$ l{' F* \' S, \7 Q$ u
        // $4018偼VirtuaNES屌桳億乕僩; N2 T/ h" L: |" H( B
        if( addr >= 0x4000 && addr <= 0x401F ) {  S1 u( Q6 m, v
                internal.SyncWrite( addr, data );
/ ]; X: C, }- Z' g  }( C" N; _                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
+ Z* F# H+ c0 ~  q  C; P. J        }
+ e% }) f! K: Q* y}
2 j6 X: @+ ?2 ?' S
' l) `" L: R9 c" Q3 qBYTE        APU::ExRead( WORD addr )
* G; a% ?! k3 }% |% c1 F- l0 M{0 b' c, U" s. J# `8 k
BYTE        data = 0;9 }  ?0 o8 z5 R7 f
+ ]" u9 ^/ Y- r
        if( exsound_select & 0x10 ) {1 r% J% ]; _8 o% G
                if( addr == 0x4800 ) {2 H( s3 `8 B+ J4 p
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
( G$ Y2 ]. }  Y- e0 }4 {                }
+ m  S7 }2 @0 e2 J4 c        }, @  l. F" g: K: C
        if( exsound_select & 0x04 ) {
" V$ v% E( M  y6 V* K                if( addr >= 0x4040 && addr < 0x4100 ) {: w3 K# K8 C7 ^  L3 }# a6 I
                        data = fds.SyncRead( addr );8 d5 L) J7 A% }
                }1 s) I4 d& c+ C' V6 h
        }4 F& p3 f( C3 u, A% k! n% i
        if( exsound_select & 0x08 ) {
( \( N; V; y) K9 W( |                if( addr >= 0x5000 && addr <= 0x5015 ) {
; T. U; q4 G. O6 ^1 B: d( w                        data = mmc5.SyncRead( addr );/ T, H, f- k, U
                }$ ]- Z9 m4 |; N! j: E" [7 E# d2 S7 ?
        }/ z- h0 `1 h, j0 g/ @
" h) T, W: d0 r5 m
        return        data;
3 L9 l. R2 L. G! h}1 Z% p4 @- U4 p& N

: w, c. d; s) S' `9 Bvoid        APU::ExWrite( WORD addr, BYTE data ); P, _4 G$ y% ^( D7 k' a+ z3 @3 N
{
3 I" N$ |8 \6 }1 P        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
, \( U7 W2 S0 V9 b, K6 R% z- O2 Z) l# ^8 A7 G% `5 S/ Z( N2 E2 E! X
        if( exsound_select & 0x04 ) {
: ~6 O* U& `7 ?. H9 c- a+ C                if( addr >= 0x4040 && addr < 0x4100 ) {- O, A7 d8 J  X( W; O
                        fds.SyncWrite( addr, data );1 T  H- S3 i/ ~
                }# O6 w" B5 i; [6 P
        }3 u" I7 N# p9 w

# h' f( @9 I- U7 ]        if( exsound_select & 0x08 ) {, F2 @$ q; [. p+ I
                if( addr >= 0x5000 && addr <= 0x5015 ) {$ ~; o3 @7 m3 B% ?
                        mmc5.SyncWrite( addr, data );
$ X6 a9 _+ e4 S/ X- E" O+ t* j                }
9 r* x! R0 D# f2 T0 H- b4 r        }  K$ G7 _3 n) m* `9 X- x0 }% C7 s
}
  r- {# I' i: A8 M2 o, [7 Z6 r2 Q+ _% G- X$ }6 @" u
void        APU::Sync()$ Z2 i( m* y0 J' r
{( q! e# R, l" l' M# Z$ e
}' a; O9 i/ d( t7 o+ ~' M
1 t" R5 m( y4 N( X
void        APU::SyncDPCM( INT cycles )+ b* A, v2 U+ [" F
{- H4 |5 ?7 [) C
        internal.Sync( cycles );
8 F8 V( s: H2 z
2 K2 O4 o& m2 t' k        if( exsound_select & 0x04 ) {3 L- W+ I9 ]' m5 m
                fds.Sync( cycles );% p3 P3 W* D- T7 U  k( }; }- p
        }$ ~9 R  @) ]: }3 p! e8 C
        if( exsound_select & 0x08 ) {
1 }* X) y2 s- f) W                mmc5.Sync( cycles );8 `" A  M3 @. f) o+ K$ S  ^; X
        }
  |1 C" [: O7 |7 }}
5 h7 l# H0 s9 z( |8 g
/ R9 n: |* y' S) s& Vvoid        APU::WriteProcess( WORD addr, BYTE data )2 G4 A8 p# K3 G( H$ n9 ~" m$ G
{
* P" e' Y& A2 l- Y" V- h% d        // $4018偼VirtuaNES屌桳億乕僩) y+ Y& w3 d2 s+ y
        if( addr >= 0x4000 && addr <= 0x401F ) {3 U" v4 m) D. Y$ O. F
                internal.Write( addr, data );
3 E. E5 ~8 }' t( Q& S  G& U8 s) B        }: k- w/ A7 O' j/ |0 G
}
% k5 _  g) y3 t( t' O7 h( l( l2 G; ?- J% d# G# l4 W, g
void        APU::WriteExProcess( WORD addr, BYTE data )& y) z. ?$ l1 I3 q  i9 _% Z
{
. s, O3 w2 `! |6 H* b4 w        if( exsound_select & 0x01 ) {
7 Q/ I1 u( X$ ~0 f                vrc6.Write( addr, data );
* k3 i0 m. I$ k: u4 D0 H        }
# d+ A( P  D, x: G5 C# D; U        if( exsound_select & 0x02 ) {
& g# p$ k3 \9 `& H. T% u0 I                vrc7.Write( addr, data );0 `% i8 G: F) ?! F; V$ b
        }3 {5 I/ q. t) w5 H
        if( exsound_select & 0x04 ) {1 Z8 U, |1 q+ V' _
                fds.Write( addr, data );
# \6 z- [. ~0 S( p# ?0 ?        }
7 E" K8 O  K* C# }6 n) P        if( exsound_select & 0x08 ) {! T& W9 [' [- E" t6 A: ~
                mmc5.Write( addr, data );
8 Z5 m' W3 U0 ?2 p/ V0 l7 z; z        }/ b+ Y1 }! l' L& x/ Z
        if( exsound_select & 0x10 ) {
9 V" p1 V+ I' w5 F% Y8 _8 B                if( addr == 0x0000 ) {
1 X- H! h/ S+ M* R                        BYTE        dummy = n106.Read( addr );
- m2 i* `$ ]( B5 j4 N' ^* d                } else {3 Q# K4 p- Y% ?. K& H. f5 s
                        n106.Write( addr, data );
2 K2 W  r! D0 Z0 O& r, R! T" u                }
- T6 n7 @7 T- g  g- }( {4 ]        }: }2 Y" K/ \& g' r5 f( E, r
        if( exsound_select & 0x20 ) {
/ p2 e0 I/ l0 a) d' t                fme7.Write( addr, data );6 I# M7 a8 R" `/ y
        }
' f% ~7 H) p3 Q% q$ h; E, ]}
, B* I6 n, t" I# Z
4 E" ^" n9 h9 wvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
( j2 q6 ?1 i" Z% M3 `{
& w1 [8 X5 T' m6 O2 KINT        nBits = Config.sound.nBits;$ l6 A8 q- S$ b" r
DWORD        dwLength = dwSize / (nBits/8);
* n; x2 `2 u! L& L1 FINT        output;
: D0 R  K9 h) w& D$ s* y) n+ {QUEUEDATA q;" ?2 T4 `) D! }/ `
DWORD        writetime;) ~  l5 O, A! U/ ~
9 C, }$ q2 ?* @# t" o$ _
LPSHORT        pSoundBuf = m_SoundBuffer;9 m' o" w( m+ M5 O( J0 c* {* p
INT        nCcount = 0;
) W8 K4 R. V) _- \1 }* {# Y) F& y( o9 R1 V5 A
INT        nFilterType = Config.sound.nFilterType;
; |! ^9 b4 {- O2 S
9 O% d9 U& t; H2 x  E2 j/ q, Z& ^        if( !Config.sound.bEnable ) {
  G- k" ^, @7 y# {+ C- y7 Y                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );% a7 Y) b% [) P( h2 }; t8 {
                return;( h2 r; W: \& _" x% h
        }% D- h8 @- _; X- O

# R- f9 Y5 R2 l+ X- ?        // Volume setup
9 V# b: h' u4 |9 _/ U9 m- o        //  0:Master6 b( K" ~# [2 Y+ [/ @, x. L7 N
        //  1:Rectangle 1
7 K- {& T! O# `" v        //  2:Rectangle 24 }) F( l9 d8 i
        //  3:Triangle
7 i" [  F7 l1 e# E: s        //  4:Noise: y# j. |/ w0 S# @0 ~8 `% ?! e' t1 Q9 m# _
        //  5:DPCM
5 w, l) S6 B) `/ d! _! h$ o        //  6:VRC6$ h5 c. a" @5 L) U
        //  7:VRC7
8 H8 I1 X" `8 h        //  8:FDS
: b  @* h3 A& f! [        //  9:MMC5
) j  ?: L& ^+ L- h        // 10:N106, Y8 M- `8 ?! R# q+ S
        // 11:FME7- c- ^9 |: r1 P7 {' S0 {& N, s3 d
        INT        vol[24];
7 H' \- ~+ E) {# S5 M        BOOL*        bMute = m_bMute;
5 v3 f, n4 m7 D        SHORT*        nVolume = Config.sound.nVolume;
: k/ X2 a% r8 x- `  E; e% ?, w" {& Q
2 S3 Z& @( u9 e        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
/ ~- ]* h/ i! U8 d; y% g' |% y- C0 I1 e7 d( b) Z4 B* I5 P& t
        // Internal4 D3 z% H, f( [- ^( y
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;! H3 R! y1 R. ~7 W! Y( y: A) T
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;$ z/ Z% E$ J- D: M
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;4 j4 X; p! s$ b! |
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;+ u- e4 K* W+ ]2 M+ q  @
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
. x' H3 M8 {  q6 W2 ^$ d* w9 ^! Q, u
        // VRC6! c0 b" N+ o5 i3 l
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;% @  R: K( q' Q) w7 |# h" V, ~% t
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;" L, T5 X1 Z; q3 W: S  e. S
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;1 B. V) b* H2 D9 Z) T) Q; W/ g

+ I# _( |+ C8 h2 H( M        // VRC7
- N. T. L5 t! }: ?+ Y        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;4 w, b- D: d2 t
( N6 N' C: R) T# f
        // FDS) V5 s. c5 \5 N/ \" D$ k
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
  M% b! H% F& @( j% v- U9 [' V, ~5 d( C/ {7 a
        // MMC5+ |* m! j8 b5 S  n. [1 x( o( u
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;# t3 N/ M% v0 T' A: k$ m: z  d
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;+ K7 O& U( H0 ~  E% V$ Z; ]- {
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
% V9 h$ R9 \' [
; t- r5 [) ^% @, O! X        // N106( J1 d2 ?1 @* U
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
# V8 e( q& H& I# C1 F7 s        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;) O$ b$ S* Q1 ~# Q; g
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; N9 Q; R- z: O( w
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
* s/ Q5 @7 {; b3 j        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;) h7 z0 z- s& O6 o! n, z" F
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
/ P: p8 G! F1 r        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;. N! ^& b- n& k, v: y& q
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;5 B" d9 K: I6 o4 h9 ]
# ]8 q, V! ]$ H+ e. d& n
        // FME7
  z( O! f6 V& Z/ g& R5 T7 s        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
8 q: Q+ l5 b3 m3 V        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
" t" h9 n  q7 u. o/ f! }+ k6 I        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;1 i/ x6 o; c, N- L  f  ]) n/ t
4 r8 k0 [# G& d8 g1 \) L8 ?$ `3 C
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;1 U. d  o( h; e- F( X
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
8 C0 d7 r6 c  N, k3 T* q, Y, h" f' R' w1 X; A+ P5 U
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟$ w/ S# D$ v8 e* ~" v* a  Y4 \/ ^
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {1 B" T% {2 p- _* [
                QueueFlush();3 o- ?( `. c/ e; L9 x
        }8 R2 g0 I$ t; p$ p1 C, G
1 K" k  R" @& l3 {+ [
        while( dwLength-- ) {3 V# P' V4 W6 |7 x2 u# R" W. d
                writetime = (DWORD)elapsed_time;! Q6 `# y" e5 v) r' _5 D
, q4 ]. b' F# E7 d
                while( GetQueue( writetime, q ) ) {, f7 V4 T/ H, p' o. C4 O( l5 D
                        WriteProcess( q.addr, q.data );  |2 K+ b& ]  K4 f
                }
# R0 f1 s) f0 w! g, L1 o
. p5 w2 `1 s7 M* p0 F+ f                while( GetExQueue( writetime, q ) ) {$ t/ G) E( g- V- i
                        WriteExProcess( q.addr, q.data );  U2 W) Q; C! j9 Z; w
                }
! {) b9 m4 u/ |) r; c0 L
4 \/ y' V$ L- v% \                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7& g$ l; n. C9 k  y1 L, @5 Y, L) Z
                output = 0;/ Z1 C) ]! i# j9 |4 ^6 m
                output += internal.Process( 0 )*vol[0];
5 z! Z7 g4 z. y: ]' X+ O                output += internal.Process( 1 )*vol[1];
' x9 N" R1 [5 ^4 v  Z. R                output += internal.Process( 2 )*vol[2];3 ^7 t3 ]+ E  R# A$ j8 e2 Z
                output += internal.Process( 3 )*vol[3];# d! q( }4 B% \5 h& e
                output += internal.Process( 4 )*vol[4];0 T+ v, C- q* c5 t) L5 h
5 |" _: `( l4 Q
                if( exsound_select & 0x01 ) {
5 T5 p3 z% Y, U, m0 y& K8 V                        output += vrc6.Process( 0 )*vol[5];
. Q1 ^: z' |/ H/ W. x8 ~                        output += vrc6.Process( 1 )*vol[6];
' k9 @- k3 V2 _) ?                        output += vrc6.Process( 2 )*vol[7];
0 z  K- S/ K) m: `# L$ M                }
  D+ o( M7 J- K1 X) K% i/ q- r                if( exsound_select & 0x02 ) {" X4 s8 p8 q6 K: F
                        output += vrc7.Process( 0 )*vol[8];
" c* q1 v7 P: B9 [% T( W1 _                }& n5 l' L0 X- b% X) l
                if( exsound_select & 0x04 ) {
4 c6 b8 e& k( r" Y                        output += fds.Process( 0 )*vol[9];6 @( m7 \* `% [7 O6 v. j$ g
                }
( a, Y# }6 Y  ^0 d( g/ z                if( exsound_select & 0x08 ) {  H. s4 P. E2 A2 u" T9 h3 S1 K
                        output += mmc5.Process( 0 )*vol[10];
: b$ e7 p% s$ x3 R' F6 C0 t- a8 @                        output += mmc5.Process( 1 )*vol[11];
' A6 Z. R+ g' a                        output += mmc5.Process( 2 )*vol[12];
/ |% b" J3 ]: {! a) ?                }  e& s9 Q' B& g# s
                if( exsound_select & 0x10 ) {
) j! U* y7 V. A1 @( G6 q                        output += n106.Process( 0 )*vol[13];/ M& U$ O/ j0 a
                        output += n106.Process( 1 )*vol[14];7 w; ]! }7 w: A% }6 v3 |$ a
                        output += n106.Process( 2 )*vol[15];- F5 H, O7 H- a1 p
                        output += n106.Process( 3 )*vol[16];4 k8 z9 k; l  Y  M% @. H- k
                        output += n106.Process( 4 )*vol[17];
) f% t8 W  J1 B* y, C& g; {                        output += n106.Process( 5 )*vol[18];
1 `) [! ~/ T7 B. c# L3 G8 O! ?                        output += n106.Process( 6 )*vol[19];% m: v8 j* P9 e
                        output += n106.Process( 7 )*vol[20];2 z1 H' C: r6 Z) c- o: t/ n& i, m! }
                }
/ u% }! `) |+ Z8 t& d5 q0 I) G                if( exsound_select & 0x20 ) {
+ {4 M" b8 D! R1 `                        fme7.Process( 3 );        // Envelope & Noise4 Y) h7 a+ M( O$ r" O! b
                        output += fme7.Process( 0 )*vol[21];6 Y" H7 I1 [1 U9 t* B7 T
                        output += fme7.Process( 1 )*vol[22];; X7 l  a; t$ B# T" \8 t
                        output += fme7.Process( 2 )*vol[23];
* a6 c0 t' I! x" R- P                }. Q, M, k: S% c1 T- h9 W: p5 h
% N- [* h! [+ d6 Q: L
                output >>= 8;
' t5 f3 D. E, K3 i2 C& U( c0 n; C, K# X- [: x' I
                if( nFilterType == 1 ) {( |* Z5 s) S2 Q4 A6 g5 ~+ Z, q
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)3 }( w4 ~* \& L" Z! G* Z
                        output = (lowpass_filter[0]+output)/2;
& V/ ]2 {. Q; \1 D+ e, T                        lowpass_filter[0] = output;
# u) K% H5 U5 W                } else if( nFilterType == 2 ) {
& z7 L5 K4 K$ s5 U( B# @                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)! |/ c; d5 C( U( y7 ]' U2 j' N
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
  A; u# |  O7 G, w' s                        lowpass_filter[1] = lowpass_filter[0];
, d: ~- v4 N4 b9 x9 d                        lowpass_filter[0] = output;
" W' m- Z  d2 E4 C8 c: G2 O% p                } else if( nFilterType == 3 ) {; A, _/ C2 w+ x4 a' F
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2), _: @4 Q7 I( M& U) d
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
3 d4 c5 E! n! t3 N+ }$ \                        lowpass_filter[2] = lowpass_filter[1];
! L% X' k4 a/ V4 S8 Q, C! _" c                        lowpass_filter[1] = lowpass_filter[0];
' Q! j" {5 f- f                        lowpass_filter[0] = output;
7 A' \" _7 a- A/ t/ }2 j$ Q                } else if( nFilterType == 4 ) {$ M$ s- B" X1 V7 |% [$ |: V7 X
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
. }5 I/ c, p4 C                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;) `+ [" _& `" Z  @4 d1 y) _
                        lowpass_filter[1] = lowpass_filter[0];- ]2 @) I# Q2 n
                        lowpass_filter[0] = output;
) s3 }8 g% ^% N2 V5 l                }4 P2 g2 H: G0 q
, ^7 e" \5 }- Y" t) ?/ E
#if        0
* g5 p  B5 Y* ~9 @, L$ l                // DC惉暘偺僇僢僩0 @' n) C+ |( U$ L" ~1 J& G
                {) X5 |+ i6 S2 D6 u
                static double ave = 0.0, max=0.0, min=0.0;
8 D4 ]+ c. F) u6 ^8 r; |& h                double delta;
4 a% y; @1 l& A* ]                delta = (max-min)/32768.0;
" F4 X! O( {. l: s  F4 V- w                max -= delta;
2 H! i* T5 _/ I5 W/ p6 Q                min += delta;, N" O; x' q+ R2 V( |
                if( output > max ) max = output;, k3 d* ^8 }: Z/ t" n
                if( output < min ) min = output;
2 n8 W  ]% ^5 `                ave -= ave/1024.0;. C- u7 Z. y1 C2 z# f9 [
                ave += (max+min)/2048.0;6 c  c3 l5 \- r2 p2 A( I
                output -= (INT)ave;
' I8 q2 w! V# b1 |4 R                }
: o* j1 I$ N# b9 N/ x% N#endif1 k! D5 I8 @2 {, r
#if        1
6 ?, q: ^. f* }+ v: _9 w; N                // DC惉暘偺僇僢僩(HPF TEST): m; Z1 }. E8 s+ z5 Y
                {
- d- i3 h* Z5 l: `//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);( q- T# ^. i2 p$ g
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
* {/ k- O& m. c3 i1 A& v                double        cutoff = cutofftemp/(double)Config.sound.nRate;
  w; F: f9 y: @8 f9 b                static        double        tmp = 0.0;
0 j9 ^( Y, ]/ y8 S$ S( H" a                double        in, out;
! Q3 N0 F4 B$ S0 `" h  d+ K2 y
4 c" S5 h0 v) k# B) p* z) M8 N                in = (double)output;
+ b9 h4 [7 X8 S$ G                out = (in - tmp);
; H: @, T( y: M+ h* `3 q                tmp = tmp + cutoff * out;7 w4 i$ Y( Z  L
; i- |+ t3 g% H/ B
                output = (INT)out;
$ _3 `. S+ `/ [! j$ C/ x5 }                }
( N+ T6 Q5 H% R* D9 I5 ?8 r#endif
* W- U6 {' F6 o6 Y#if        0$ t' O% ?2 {, W  X& |' u
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)+ R0 X1 A( f$ @; N1 }  w7 J; [* m
                {
8 {2 f+ T% ]1 }8 a                INT        diff = abs(output-last_data);
! H( y# k4 {; C  O. `' E+ _& T  H                if( diff > 0x4000 ) {
2 t4 G# d! d  _; m+ y7 k                        output /= 4;
( C; L- n$ z& g2 ^: j9 Q                } else . K2 J0 a' V1 G  D4 U1 Y
                if( diff > 0x3000 ) {
1 j) y7 N9 }6 L7 d. D/ r                        output /= 3;) l, m; r( M% W0 s- e2 \& S
                } else% ]/ I5 P3 q+ M8 X, Z0 Q% Y% Y
                if( diff > 0x2000 ) {
2 y8 G* ~9 F. {$ _! I3 ^9 J# x  y                        output /= 2;8 F, \! w! K" e8 [9 V; Z9 M; o
                }, q. V& a1 d8 S4 ?+ K( C4 s% S
                last_data = output;! {# Z  C# r" ?/ Y6 ^1 g8 ^" D0 r
                }  [# M4 k) K% j" \3 C' e% }
#endif! F  s/ V1 y; N% N3 [- x
                // Limit
& a4 O/ j: E, i3 K# B% p1 w* p4 l                if( output > 0x7FFF ) {
& j) b8 m! f+ E8 M5 J4 S                        output = 0x7FFF;7 y: M+ C$ @" j/ P' h; {) c  f
                } else if( output < -0x8000 ) {
1 V, C9 D3 E: ~: N7 `6 l                        output = -0x8000;7 Z' R" P' W* R9 q. b+ d. K
                }
8 H1 G& c2 U! s( A4 E$ X' w- ~# ?, U4 _1 n
                if( nBits != 8 ) {
9 G# W- U1 S1 P1 ?  a* y                        *(SHORT*)lpBuffer = (SHORT)output;
4 w7 I. R- `" w$ H* n" {                        lpBuffer += sizeof(SHORT);
( h# r1 Y3 K, w6 h- B, G                } else {
! G+ v' h3 s9 a. i( K                        *lpBuffer++ = (output>>8)^0x80;. E4 K% p3 G; N2 ?8 d" s
                }
! C0 @# R3 [1 \9 N2 q3 t; B: H# @  S1 a4 ]6 V6 ?
                if( nCcount < 0x0100 )
, a4 g7 h" Q7 F) m6 W8 e                        pSoundBuf[nCcount++] = (SHORT)output;
5 L6 z2 I% Y+ M) M1 V/ y1 }1 i. Y# @/ t6 v8 E
//                elapsedtime += cycle_rate;& T1 D1 a1 d7 ]' v/ @
                elapsed_time += cycle_rate;$ Z( t: q8 M! t" ]/ y' r: Z6 _
        }" q3 i( X7 [6 U, A8 L& u5 |. B

7 s! }! X( J2 Q2 U6 Y' g! v9 A& P#if        1' U7 y+ b- |* A8 ]
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {/ Q/ }2 Y5 D3 G8 F4 \" A
                elapsed_time = nes->cpu->GetTotalCycles();7 H7 R0 c0 t3 d4 n, _1 g! P
        }' c5 w/ ^" K; ^+ `; b* p1 E
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
9 i7 P( c5 W- w% s, w3 l                elapsed_time = nes->cpu->GetTotalCycles();& n( e/ e" z: J$ q
        }
& P- W9 I; W+ D$ a" v#else
# v3 t# g' d3 D; ^+ O$ ~        elapsed_time = nes->cpu->GetTotalCycles();! r) C7 i. P1 E! q
#endif8 ]* m. i& |: R8 o3 V7 {9 P& w' m
}$ h' X1 L; ~4 ^7 J

/ B6 }2 q$ q" ]% j8 V4 t7 p// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)" a& L& Q4 G* b" d: F0 u! L
INT        APU::GetChannelFrequency( INT no )" F( v) n  s- ?$ ?, O
{
; S  E  P) Z1 ?/ Z9 L/ ^0 K6 u        if( !m_bMute[0] )
' @+ a" Y: C6 _( |                return        0;
* B. V% B3 k" m5 U! {; ~1 ~9 f( V" _2 U- u! |2 D
        // Internal
: G9 l& K! R3 I; \/ l, S        if( no < 5 ) {
0 f; l5 v% i& o: t8 V                return        m_bMute[no+1]?internal.GetFreq( no ):0;: x$ Y9 b- j( p9 T. j5 Y' A
        }
/ h. t7 k2 \( b: d/ B        // VRC6  M8 n% K& `( \8 H9 }' m& Z/ Y
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
& c! U* \% U' r8 m                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;5 I$ F5 W) r2 O" v1 ^
        }4 R3 s& l- I$ H! G8 [6 l, `
        // FDS
) _. ?8 y, }; g% c! {* ]9 E        if( (exsound_select & 0x04) && no == 0x300 ) {
' N; A: ]  y7 j; T# I                return        m_bMute[6]?fds.GetFreq( 0 ):0;
/ T" O. l6 p$ ^4 J        }
' j+ w3 [* x, p' t6 \$ x        // MMC5
- E" f0 I8 [  C4 x# S0 Y; D2 G        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
# v% i% ~" H4 M% `5 T) @                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;2 Y# |! n7 F9 |$ ~7 U6 H6 S
        }
5 h- A( f" {9 F4 a1 ^& F, u        // N106- p+ ]% b2 M/ {! F6 k
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {: m# \# p" J; g' G
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;1 p; K! w! K5 l5 k+ n5 `
        }. H' ?9 R7 @- \
        // FME7
% A- s& u4 y  m2 i- n8 ]        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {* }0 g* i# }* w9 P7 y9 I) s
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;' Y/ s1 d; A, b1 e% ]) Q
        }1 j- C; E+ H3 W2 e; @& C. M- |# \
        // VRC7
2 |, B0 e; a+ L) i8 ?) D        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {) I0 @& h* h; R7 M  `
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
9 j  F0 g: p& E" p1 z$ P) ?& X        }( K% s8 F. `% t  i. d8 f2 n
        return        0;
$ V2 c, ]* A" s! c}9 P" |, b+ B% D5 @4 U6 C

1 D. W" d( V0 @2 g// State Save/Load* i- f3 T7 o$ R! {7 U6 P5 D
void        APU::SaveState( LPBYTE p )8 \( r( t& v/ [0 N( d" f
{
, I( M  S: i) D1 t0 }) }( Q#ifdef        _DEBUG
3 Y4 G$ k7 M& }3 v. B4 nLPBYTE        pold = p;
2 ~6 J% X; }$ C- [#endif9 k) `6 d$ ]9 a- l4 Q+ h

/ j) z( x+ ]' }- S  E! w! |' ]' G9 f        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
  P" N6 j$ C- L: s8 F, C        QueueFlush();, s# U* o; z! `* o) u! z

7 Z% }' ?9 d6 ]        internal.SaveState( p );& t- C& y! a" z+ D1 _7 E5 ~" @' P
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
' N! r4 @6 q- W  |7 [6 h
9 @6 r) y$ N( |; j( z2 f4 H* e        // VRC6
& H0 z3 \2 T: [& h7 s        if( exsound_select & 0x01 ) {: U4 O) M2 _4 I0 m* q% B' h9 W
                vrc6.SaveState( p );
0 Q4 t8 `% d. F& ~                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
6 I# g$ f6 o9 g$ u        }: e7 N0 \' `$ w# \$ W3 C" ]
        // VRC7 (not support)/ v5 g  P* C6 v
        if( exsound_select & 0x02 ) {
+ u0 u+ |+ \' [2 n3 J. C/ q                vrc7.SaveState( p );
$ ~( E1 o0 C4 H                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding% C9 W. v3 I3 C3 s  L  E/ x/ t
        }* }( y( m+ w" _: j$ J3 Q, {
        // FDS+ U" j7 L) I5 t
        if( exsound_select & 0x04 ) {4 y1 h( G2 @9 R  n, w
                fds.SaveState( p );! h( p1 C3 i; e; ~% o4 `( x
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding+ j; a' D2 V, _
        }
4 b9 ?, j, \& _9 I/ f        // MMC53 \; i$ i, E& S5 U1 Y/ f
        if( exsound_select & 0x08 ) {$ E% a. X* ~7 ^5 V1 H
                mmc5.SaveState( p );
. R, ]: |% U3 x                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
; U' H  Q5 Y. F3 _: z        }5 h7 K: |, \1 k& O. f5 |
        // N106
; s! o) }% O* l6 k5 A        if( exsound_select & 0x10 ) {
8 R0 U# d. v; H; N                n106.SaveState( p );
! J) `/ O2 d% ^* V; b7 l                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
6 s5 K8 K( i2 ?; j        }
" @# s  y! d3 P4 A4 P        // FME7
  `4 i5 M. j  ?5 n) N        if( exsound_select & 0x20 ) {
; o6 i" L, _* _: w. y! @, ?" W                fme7.SaveState( p );' Y% J& n' y8 T+ j+ _" ~6 y
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
3 W1 N! M0 n) _) z: l4 x* O0 `        }
0 i1 e- r5 K. X8 j' y* Z( }* Z$ h! m. \- ^6 J- \
#ifdef        _DEBUG
+ h' L( Z$ ^) V( ^" j  I; QDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
/ U, ]2 |( ^0 G6 `4 c6 y2 R' _#endif
# z1 h! f8 r7 o}
- [7 K/ `, Y' l+ _! [2 ]6 f
$ g3 e% m3 H0 ~: l8 lvoid        APU::LoadState( LPBYTE p )
% ^& R8 o$ g7 N$ Y2 r+ I{
3 \/ j" h8 O+ V, z5 e        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
8 P8 T: L7 ~1 H  ^$ L1 a        QueueClear();1 n" a: j! S( {
6 A$ i8 F" r4 X+ J
        internal.LoadState( p );, u% u1 P% U# f( w) Z
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
$ G" w+ n4 G3 O
9 U  m% w5 e3 u0 F. i        // VRC6
/ h4 E$ |3 o( e        if( exsound_select & 0x01 ) {
8 @6 o. R% m) q& C. f" }                vrc6.LoadState( p );
" S7 ?5 p0 v" J                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
  x* _/ \/ b( v5 U/ T$ I  m0 E% i. E        }
1 A! q1 i% Z+ o# ], `; l        // VRC7 (not support)
5 N( r# r- m( r1 z# z" `        if( exsound_select & 0x02 ) {
+ l$ c  k' T4 F0 e: p+ J                vrc7.LoadState( p );9 y$ V" P8 `0 E6 A
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
. p% k" [- N+ k, P2 W        }
( O0 f+ j6 F4 t! u! h$ q        // FDS
$ Q3 ~9 U- }9 T' t5 n, b# q  R        if( exsound_select & 0x04 ) {$ r! ~! Y8 N, w" \
                fds.LoadState( p );( u( ?. L/ c# `3 e; a
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding0 {! e- T* I$ s& f
        }
! u3 d. h+ r7 u        // MMC5
9 }& t3 f  R% Z  w$ w, C        if( exsound_select & 0x08 ) {) J' E4 ]0 \  f: I
                mmc5.LoadState( p );1 Q* U0 @9 G# p1 l
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding# A& e) O" I% `
        }& y5 Q& t3 D* |( a& c1 Z
        // N106- I5 n0 [% b7 z
        if( exsound_select & 0x10 ) {. g' k0 X% c2 w; p" e
                n106.LoadState( p );
  e$ A- U" y, g4 A1 @: ?& o                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
9 j# s/ R" D4 S  S1 _        }: V/ A/ `5 |' q
        // FME77 `8 _9 [& v( g$ ~% Y
        if( exsound_select & 0x20 ) {
+ e" G* O3 w9 F1 P' ^3 |( t                fme7.LoadState( p );) E% b3 B1 F; U% F
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding; Q0 `' E- G5 Z0 U; ]7 C
        }
. J5 Q% j/ Y! K' {}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
  b+ e2 a0 J" {! e' @. ?可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。0 i2 c  I2 o1 T5 {; @
感激不尽~~

; y+ C- H$ [/ g' J5 \- D+ b8 j$ g恩 我對模擬器不是很有研究,4 Q4 T: n# ~& V6 \4 V9 u
雖然要了解源碼內容,可能不是很困難,
0 A4 N) H( H- a不過還是要花時間,個人目前蠻忙碌的。* ~3 C; p# H4 U+ A+ d* `1 q9 w! h; p
: G7 e! L9 K% E" J1 B1 x
給你一個朋友的MSN,你可以跟他討論看看,
; U  c+ B! y) }% Y4 L+ f, M. f他本身是程式設計師,也對FC模擬器很有興趣。
+ y. l% U8 w2 B; V- L0 G7 o  l$ o& L. r- s+ t7 l$ P
MSN我就PM到你的信箱了。4 e5 h9 i- z& |$ g- c

* r/ x* \$ J" ]1 t希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 ! w9 A1 o2 {/ r, u: f; [8 n
呵…… 谢过团长大人~~
; ]. n2 c3 o5 W& a- X% \) {4 w- r

0 ]" Y# w& @- ?! z1 g哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表   J0 x; i# }  Z8 u4 c# u  B8 R
团长的朋友都是神,那团长就是神的boss。

! S: T9 \1 o3 `6 a哈 不敢當,我只是個平凡人,( v# ]- l; F1 e3 E: K% K2 w
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙0 ^5 K5 L6 {2 E6 ]! u
ZYH  ]3 \! m! y$ _- e
QQ:414734306$ ?% m) D, U* V* P6 w- E
Mail:zyh-01@126.com# A# c4 U) o# d
8 ^2 i: B4 n" E0 C  h9 s) a
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
1 ]/ \& C# t1 S! f. x再次对团长大人和悠悠哥的无私帮助表示感谢~~

. m( z% L! i- c: Q4 k) m不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-7 08:19 , Processed in 1.088867 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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