EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?
1 p' B5 ?1 X! k& w- Z0 F/ B: t( O5 UPS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。, Q2 v3 X. F$ A% p: h1 S1 A
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~' C1 u5 H5 L7 g, v  q
这里有相应的模拟器源码,就当送给大侠了~~
) m3 p3 r% G/ {, ]1 Nhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
1 `1 {6 l( Y$ i( \/ L能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
$ k2 w5 |: }% m楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
, [2 y; v5 Z+ @这里有相应的模拟器源码,就当送给大侠 ...

  e) i3 e; G: N聲音部分(Audoi Process Unit = APU):7 c2 s4 \( T0 y) R' C7 ^+ j" b
.\NES\APU.cpp
( @  ~  F5 u6 H* n) g& }.\NES\APU.h  q6 J' o" K% B2 `7 s* l

3 P" s- _7 X+ z" j& c$ N$ z( l5 j% S+ z' J: i+ ^
影像處理部份(Picture Processing Unit = PPU):$ B8 ?3 [0 t3 e" Z' G# {2 o: x
.\NES\PPU.cpp0 `* x5 J2 z+ w1 O0 |
.\NES\PPU.h
" q, q' s5 k7 [+ ~. l( c
! a! |6 K. Q- o; @8 B如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
, E1 A1 F+ U$ `4 I; g$ g$ _(由于很多专用术语和算法机理都不明白,所以看不大懂……)' G$ L9 k$ k7 d5 g8 T' b
//////////////////////////////////////////////////////////////////////////8 k$ B" u* M6 A
//                                                                      //
3 V* M- ~& H+ i+ I3 `//      NES APU core                                                    //
' I3 I+ Z, m- Y& O7 H; H//                                                           Norix      //
/ V' u% o" S3 v' s//                                               written     2002/06/27 //
9 s& d4 ]- h! f# [//                                               last modify ----/--/-- //
' B3 `* `4 P9 e7 `% c//////////////////////////////////////////////////////////////////////////
/ b+ k; p+ ^: l. [/ Y#include "DebugOut.h"4 v# }% ]5 ^. \  m9 ]% _$ S
#include "App.h"
" X% X, c8 L  @# D7 x#include "Config.h"6 t% r( ?5 ^& \6 ~4 b' d2 L' H
/ `1 d$ p  I  a6 y0 B/ T
#include "nes.h"
: t4 N( Y" k" P' W3 v' y: i7 j#include "mmu.h"+ W- v' y* D+ c% A# i
#include "cpu.h"
* ^! _6 |1 I/ S8 L  B6 j% _  `#include "ppu.h"
+ |) a8 ~+ X$ `  ~$ Q# p* P#include "rom.h"
( R) y* o7 |' ?# d% L#include "apu.h"
9 w$ B% K6 y5 e0 q! V$ g$ D9 A$ Y9 Q4 G- [* c' U% d" K
// Volume adjust
4 Y' K& N8 r4 h/ ]1 Y! D// Internal sounds1 g! o  d1 [" W( W5 Z+ e: W+ {0 [
#define        RECTANGLE_VOL        (0x0F0)
4 b2 i/ J( R- N0 b/ w3 H#define        TRIANGLE_VOL        (0x130)% k3 J8 [) m- g' \4 }. l6 N: @
#define        NOISE_VOL        (0x0C0)  f6 B3 ^+ i; @: q
#define        DPCM_VOL        (0x0F0)
' a1 @* V0 \& [// Extra sounds
" h; g; C5 K4 d#define        VRC6_VOL        (0x0F0)
6 U, C5 |2 D% |6 u#define        VRC7_VOL        (0x130), [- B1 B. i/ ?) f* J
#define        FDS_VOL                (0x0F0)
! r6 B3 y$ M  G& q+ x# j5 C#define        MMC5_VOL        (0x0F0)
0 r) ?( t% M3 t0 v' u#define        N106_VOL        (0x088)
8 F6 e- u$ T! N# ~# q#define        FME7_VOL        (0x130)" f! @+ N& ^9 X) ^, H" m- l

# t' s# M3 |' ]APU::APU( NES* parent )* ?( s$ x) K  w4 E0 E( T, m
{" K( O$ F* z. y
        exsound_select = 0;) `1 z; v5 a. t; d8 H

9 W. w9 f; @- k" }5 N7 y9 n! x        nes = parent;
5 A7 [. Q- r$ V: R        internal.SetParent( parent );
' j. o' X. r# u( Y4 m+ T9 ]8 C5 r+ W0 s! T9 t! U
        last_data = last_diff = 0;
9 c% Z/ b" w  `7 _' Y7 f7 @" I4 _
7 i. p" z. x" g6 ?# S) C        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
+ n1 }, B" T! t) `2 P2 J4 n0 B/ B  N) W7 `5 l( b  p
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
1 t: c% |* ~+ V; g! R1 u' s! u        ZEROMEMORY( &queue, sizeof(queue) );7 X5 l2 y) ~9 ^' U' S4 s
        ZEROMEMORY( &exqueue, sizeof(exqueue) );- l0 g7 S" J4 \( q6 @" r5 V

- A- e! `( R9 o; g8 T/ Y4 Y        for( INT i = 0; i < 16; i++ ) {
$ D% z. X' @( z3 J+ [                m_bMute = TRUE;
% J* H  @0 a+ E6 Z        }9 I4 R" Q( y' T6 O+ j' B
}
: \6 ]$ X4 w' v  V& A3 {# D+ V  E- f/ O6 g* N
APU::~APU()
, Q5 V  q3 A# D. E$ o7 n1 z  m! ^{6 R' O- d* _* G) d8 A( E7 P
}  ?! T3 P; }, m9 L

" `$ I' y" a( t7 Ovoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )& z6 F6 q4 q6 C5 U9 z0 \' N
{2 j! ?- ~1 n1 K% W6 v% U
        queue.data[queue.wrptr].time = writetime;+ s) O5 D( V+ }2 l4 A
        queue.data[queue.wrptr].addr = addr;
, y% A' p$ N: [1 H% t4 B        queue.data[queue.wrptr].data = data;4 y' y; b0 }  T! ?
        queue.wrptr++;8 }$ P" ~, z+ l- Y
        queue.wrptr&=QUEUE_LENGTH-1;
2 \, a& z6 a. r        if( queue.wrptr == queue.rdptr ) {+ v+ S2 N6 {4 i5 N4 K8 o$ Y
                DEBUGOUT( "queue overflow.\n" );
3 `1 m& w3 M. `' ]* j/ L2 B4 a4 b        }; m6 {+ E# U0 p7 p3 z% {
}" p4 v/ }/ @4 R( C# J1 p7 |
; ^+ X1 h+ d& F5 A4 \2 D5 R+ T" u1 ~
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
6 V9 i/ B6 `( X: P$ H4 G{
' H6 W4 F; |. D0 p8 E        if( queue.wrptr == queue.rdptr ) {* q4 ]% p: l# H+ t9 z' a
                return        FALSE;
8 T; ~$ g3 U8 |6 u        }8 A# Q% O* t( ?9 E3 P
        if( queue.data[queue.rdptr].time <= writetime ) {$ u0 {4 Z# p. ?+ j
                ret = queue.data[queue.rdptr];
* W, p- X7 N4 c# r# p, d                queue.rdptr++;
$ ~, Q% n$ Z) ~3 U                queue.rdptr&=QUEUE_LENGTH-1;
! b0 x5 b- n; A' g                return        TRUE;
, f1 H8 Q! K3 P& P/ t5 M        }% C5 P* G$ m% d: j
        return        FALSE;* \* V* n6 b  O% P6 \
}
9 Q, Z! D* j( X$ ^. W
  U6 v. n* Q7 v8 `' m6 B4 V4 Z7 p0 m! ^6 qvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
& m! s  U, b' n: p+ h9 a{
' y3 \$ _; C0 c- E9 ~9 o* H        exqueue.data[exqueue.wrptr].time = writetime;
" ^* j8 g3 x5 n        exqueue.data[exqueue.wrptr].addr = addr;
" [# l1 E& t& d9 T2 e  m. n        exqueue.data[exqueue.wrptr].data = data;  C, m8 ~8 {3 O( I% \8 v/ w
        exqueue.wrptr++;! Z6 [2 F+ U7 [6 p* C1 w
        exqueue.wrptr&=QUEUE_LENGTH-1;! O$ ?+ S+ H+ d. |8 H
        if( exqueue.wrptr == exqueue.rdptr ) {% g0 C1 C3 J- g" n! D* g
                DEBUGOUT( "exqueue overflow.\n" );
/ g3 z" b0 ~  R9 m. y        }
7 `* \- U+ I) x) i  a8 e}# [) F+ N2 R, @9 `' H6 E
" V7 ]9 R& q1 S
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
: A" M) N4 m( J7 Y{9 y+ J' L% t/ G* T. d2 q
        if( exqueue.wrptr == exqueue.rdptr ) {
1 c+ e) ^1 Y5 R8 h6 N" Y' @                return        FALSE;& Z4 v& A1 Q& Q& c3 ~9 G
        }
8 ?/ E( {% U$ v4 H: }" `7 N" W        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
: l# Z+ E6 Y9 H3 D( [                ret = exqueue.data[exqueue.rdptr];, n& g  @$ A$ e% f2 Y
                exqueue.rdptr++;
; i: b/ X- x/ _# q/ f; f. R                exqueue.rdptr&=QUEUE_LENGTH-1;6 ~& |* Z) M( Y4 m
                return        TRUE;: I  {- q- r# t$ O2 B% k' R8 U
        }
2 E1 ^' _) w9 Q; n        return        FALSE;
, V; w' D* D" [1 d. ~, a}; e$ M' @$ x5 S" e8 [2 l4 {4 w

0 Q9 R. A0 I- z; S# _. lvoid        APU::QueueClear()
4 Z2 ^% }* v: S( q; `1 N" b0 j{5 {2 R! V% U! }9 @
        ZEROMEMORY( &queue, sizeof(queue) );
2 [$ ?% Q; {* j& ~. Y/ d        ZEROMEMORY( &exqueue, sizeof(exqueue) );" Y5 p# {5 L9 j4 S3 t0 p
}2 O& |( E/ D( {
! T: [% h/ E4 `
void        APU::QueueFlush()
. o7 B2 Q- u' K* T{8 _, q: H+ ]( f, O7 m
        while( queue.wrptr != queue.rdptr ) {" F3 u4 w% E0 Y3 P5 q9 `
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
# _/ I* J3 q5 ~4 x9 B                queue.rdptr++;
+ u  \6 X5 ~1 d- R. W                queue.rdptr&=QUEUE_LENGTH-1;$ G0 J; {) D: q/ d: I
        }9 E  Z5 c! x/ R, V; I, I* L; k9 ~

% v3 e- L2 c8 J+ y+ h1 \0 P8 G        while( exqueue.wrptr != exqueue.rdptr ) {
7 p+ {( j0 O; W, D' |& ]+ l                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );4 ]" n0 s( z, C' U3 x
                exqueue.rdptr++;, K+ V4 R1 ^9 Z9 o5 }; B9 ], r
                exqueue.rdptr&=QUEUE_LENGTH-1;
  O- _9 l! ?3 x6 v- j8 U        }
( R7 a7 d4 g6 g# f}
, `6 d5 r2 t' }0 \* g* f3 }( |% z2 N) {7 \, L+ Q
void        APU::SoundSetup()
! x, b) g! ?$ D2 p! h- d{
( u; k* u9 D- H1 m        FLOAT        fClock = nes->nescfg->CpuClock;2 C) f1 n2 f/ b/ v
        INT        nRate = (INT)Config.sound.nRate;
; d& T8 ]1 M0 s0 G( j1 b; M+ o        internal.Setup( fClock, nRate );* _5 m6 t* S) ~, e
        vrc6.Setup( fClock, nRate );9 L) X  q' Z: ]8 S  p( C9 K
        vrc7.Setup( fClock, nRate );+ Y9 M% v& _8 p/ E6 U" `
        mmc5.Setup( fClock, nRate );
! I2 N! k  H1 |. z: V& z7 K1 {        fds.Setup ( fClock, nRate );+ H  F) ?3 q3 Y4 I! l
        n106.Setup( fClock, nRate );
/ O/ M) J# |& a8 ^; U# X        fme7.Setup( fClock, nRate );
8 I& Q# n/ s- P  W}* }) q: l8 L# g2 }2 P2 Y- R

& o9 A/ q% G2 \void        APU::Reset()" @) p8 b9 o* W6 ?* e
{. X- _. S* A( |" B" u  f
        ZEROMEMORY( &queue, sizeof(queue) );" F* q. n/ ?; X$ ^! r7 z9 x3 [# i
        ZEROMEMORY( &exqueue, sizeof(exqueue) );2 b( F  g3 |9 a0 w- D, }( l
+ ]9 \: l6 f0 |; D# R- C# a- W
        elapsed_time = 0;4 u  C! X/ {' S0 {  X

; ^0 X: F5 F' w, f4 t$ X/ q2 p        FLOAT        fClock = nes->nescfg->CpuClock;1 G  _1 |/ ]/ z! u
        INT        nRate = (INT)Config.sound.nRate;
& Z  K1 ^, y' Z$ W! R2 P$ \        internal.Reset( fClock, nRate );
% V, M; Q2 c# o& V! d! m0 N        vrc6.Reset( fClock, nRate );
6 `- W- O8 o/ S4 t1 B        vrc7.Reset( fClock, nRate );
" b# Z: U( h3 J2 ^6 s6 p$ B        mmc5.Reset( fClock, nRate );; d6 L5 @" m  c3 g
        fds.Reset ( fClock, nRate );
# Y- V- Y) m" }8 G$ x8 _        n106.Reset( fClock, nRate );6 a9 u  W/ V8 X( y0 Q9 Z0 R: l
        fme7.Reset( fClock, nRate );
! _! \4 V& q7 s6 d) }% m
$ J+ d/ i) e" A0 F+ u+ @" S2 F+ a        SoundSetup();
( A0 Q6 w7 q& e: r. b* p}
! T+ i- f+ @# `/ }( S8 S& i
$ ?8 ^/ D4 J! ]; t* ~3 H2 tvoid        APU::SelectExSound( BYTE data )9 H- o/ g' G  G, J. ?8 h) u* j
{
) t; ]$ N7 |( W( p        exsound_select = data;
% c1 O: |/ ^( P; ~0 p. }  N0 a8 Z8 x}( l* Q' g0 B! F0 j  A3 W

" @0 G/ |" G6 c7 mBYTE        APU::Read( WORD addr )
. A! V, k4 s( j7 B% s( y{# O: f3 _$ @+ K% n  z
        return        internal.SyncRead( addr );# P8 N0 U; n! u" m/ J
}
# }4 J3 j6 S- P. I0 A' y' o% H: W1 d: v
void        APU::Write( WORD addr, BYTE data )
) w; e& H( _6 \  U* w{
2 Y7 O. ]9 S* |1 T        // $4018偼VirtuaNES屌桳億乕僩: k# ]1 }% F6 |  A
        if( addr >= 0x4000 && addr <= 0x401F ) {; B! ~9 Q2 B* I
                internal.SyncWrite( addr, data );4 X. y4 G$ W5 E7 M
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
3 `, G1 }0 y: N  s3 x- |        }
/ I/ v7 p: X1 n}
; O1 s9 F4 @2 S, w& E" U2 g8 D; x$ O# U# v
! \& a3 [# p( t# rBYTE        APU::ExRead( WORD addr )
0 S: p' {+ \* ]8 P" O6 \- z2 J{( m" U7 L" w4 L7 {: j
BYTE        data = 0;
+ y8 v( l- U3 l  v: e2 X  {/ o/ _$ W! W
        if( exsound_select & 0x10 ) {
1 r8 W8 y4 @$ b- X$ {                if( addr == 0x4800 ) {: U- O: ^+ V/ N2 n1 r' T, s  f
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );' |# {1 Q: ^: A; U
                }, D: b+ G( z: c, N
        }
3 q9 F- o) ]* v6 w$ B        if( exsound_select & 0x04 ) {
  D8 Y' k' \5 E! f$ n4 Z                if( addr >= 0x4040 && addr < 0x4100 ) {6 l, t9 O/ E5 O) _  p8 h
                        data = fds.SyncRead( addr );: g1 D0 n: A$ b: W% _& K# p
                }
( l! F7 H' i- W( Z* X- [        }
& {5 o& I( ^# r4 s) F2 t% P        if( exsound_select & 0x08 ) {
' s+ y: c2 \8 n9 N$ B                if( addr >= 0x5000 && addr <= 0x5015 ) {8 o0 V2 {2 _5 K
                        data = mmc5.SyncRead( addr );
, ?$ U$ k- H# m6 e( L/ E                }- B$ x: K+ H( s0 |) n
        }
. T; U3 q$ Q- j; l* }( ~
% b) a# }+ n7 i2 g        return        data;
. Y  y3 [: I$ A8 ]}3 Q! {) b6 f" c9 @/ I

" u$ V' c( G, Mvoid        APU::ExWrite( WORD addr, BYTE data )
) I+ v. [; _0 M6 r7 M{
  j' A& A" h4 ^1 U. R. K/ H        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
& R0 [8 b' C1 u3 R
0 P+ L) g5 b& F; t/ K        if( exsound_select & 0x04 ) {
1 {+ K& Q# E: M  d                if( addr >= 0x4040 && addr < 0x4100 ) {2 M. A' {8 \! g  g
                        fds.SyncWrite( addr, data );
/ Z. z7 F' s( N8 m2 p                }! A) _5 W; c4 r! [5 N1 E" i$ ^& w
        }; K1 |( M( e5 H2 h. K0 g+ z6 ]
$ S1 A; [0 C. V% f, ?' m
        if( exsound_select & 0x08 ) {0 O6 W, K4 u$ _7 l
                if( addr >= 0x5000 && addr <= 0x5015 ) {
- q0 j& X/ V- L0 X4 {8 P# y3 p1 y                        mmc5.SyncWrite( addr, data );
% Q. [8 b* M$ O) N                }+ V/ Q: `) F) L- g5 H2 x/ f/ C: W* B6 s
        }
1 `: f- @% T" P' L' u}
) s  [& p2 L- U* R  {2 n! I% X3 p" W+ @! J. Q. Q/ T: X
void        APU::Sync()
8 M" J& @0 w# _" o1 X{3 L! R& y1 H/ j; M
}+ E; _8 Y; }* y4 K* J

. K0 Q4 f0 u8 S# F' P) L( @void        APU::SyncDPCM( INT cycles )
& I+ Z' e: u! s* t{# `5 j" K" k2 x/ Q( k+ A/ ^" {
        internal.Sync( cycles );/ x# v4 y" y5 b  s% b7 W& b

$ [' @6 B8 w8 q5 l$ }* \        if( exsound_select & 0x04 ) {& H* y( i( c  ~& j3 [2 p$ X7 o  r
                fds.Sync( cycles );0 g7 s/ r% F/ f. i
        }
4 C! e5 ^' j. c; e! q; P* g) @        if( exsound_select & 0x08 ) {- g; p& ~& Y8 E* m
                mmc5.Sync( cycles );3 r* `7 m5 [; z' q4 B
        }
6 w" W0 S3 X& Y}
" t. I6 w) L: b4 _7 p' Q) Y  X) I/ s0 y6 F9 J. a
void        APU::WriteProcess( WORD addr, BYTE data )* d0 r  f# j) S1 X" ^
{; R) n: f+ s; M5 O6 s! C1 H
        // $4018偼VirtuaNES屌桳億乕僩4 [( a/ S/ L8 M7 p3 L& `
        if( addr >= 0x4000 && addr <= 0x401F ) {
6 r! k  k2 H/ E+ e5 S3 v6 i& t. }8 |                internal.Write( addr, data );
. i( D! r4 y/ @8 x+ S5 K        }
% P; z2 d2 v- C' |3 i}
& v. P) k. c  f; T$ X: s2 Z, e! L
9 B& _: z: I6 }* o1 _  Yvoid        APU::WriteExProcess( WORD addr, BYTE data )
5 z- q/ F6 ]" X, d- n) S{: L0 P* y, |- p2 i
        if( exsound_select & 0x01 ) {
: R% J) h( ?" f                vrc6.Write( addr, data );
0 b/ `- G( f) R: U6 ^! l        }5 K) S1 `7 b9 G6 c7 D$ X5 c( N
        if( exsound_select & 0x02 ) {/ M7 Z+ h, ^- @" u% g& D
                vrc7.Write( addr, data );
4 t" B; ~% v9 q9 Q" [        }
" i; L5 `) Y* Z/ n' ^. {        if( exsound_select & 0x04 ) {
" X% M4 G4 y  c! F2 g                fds.Write( addr, data );+ \0 ^! t$ S* o' M" }7 I8 R
        }
( ?7 Y8 M+ |0 p+ Q- Z6 b) _        if( exsound_select & 0x08 ) {0 e: B6 M! c9 B: g2 @6 W$ t$ w7 P: w
                mmc5.Write( addr, data );8 R; ]8 Z$ a' N2 J
        }) h  ~' u8 {. U8 q, v+ X: {
        if( exsound_select & 0x10 ) {
1 X3 C& c2 @! n0 D* U                if( addr == 0x0000 ) {9 h1 t- ~5 ], w& o
                        BYTE        dummy = n106.Read( addr );- ?: X9 v4 V, l. M) I
                } else {* Z6 G& O5 R( C6 ?
                        n106.Write( addr, data );: ~9 ?: n6 ~1 n1 S0 h* j
                }
9 j/ Q7 \! Z2 x+ e1 o        }$ z) S4 p$ E- R
        if( exsound_select & 0x20 ) {
+ |* m5 Y) [$ ?" A                fme7.Write( addr, data );
7 l$ M$ G) u' \; [' ?8 g2 F        }9 N" I: y; m+ r/ m2 N  [
}
. E0 A9 b. ]- C! @8 J! ~0 z6 n  Y' g  ^- s
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )6 s( \  T/ T" z& X8 [6 e
{
2 p- }" c) `  q9 vINT        nBits = Config.sound.nBits;
7 w' X3 b* n$ R/ i( V! K3 fDWORD        dwLength = dwSize / (nBits/8);3 [. y: {1 u  G( ?
INT        output;9 o0 Q! o5 |: j
QUEUEDATA q;
! S+ Z8 A, T/ X9 c7 w# W% S/ \DWORD        writetime;% F* ?' c" F) s/ @* \& G

. n  ]+ ^! \' [- t' z1 CLPSHORT        pSoundBuf = m_SoundBuffer;
8 `* T; t4 Z! K6 V; f% qINT        nCcount = 0;7 A; A  W/ f  [1 F7 G3 O. D( [9 w

. ~0 S. w1 N0 V6 V# ?9 lINT        nFilterType = Config.sound.nFilterType;
  N4 }! H& D' R+ a5 ~( O
' ?- W: Z1 c2 p7 H: F        if( !Config.sound.bEnable ) {
0 R/ H6 P9 F/ I( {& P2 e: Z! K                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
# O! L( c* x. n0 g  O9 ~( d                return;
4 T1 o6 Q& X5 V3 P+ i) t2 p        }7 |  D' m. X, D: C" H/ o2 N
9 M1 t# ^( Q# n. [
        // Volume setup
0 W% A. [) U8 J% h+ @; l) v        //  0:Master
, V: N) m% h5 _9 {- F9 c        //  1:Rectangle 1. d+ ^, i. g# K) {
        //  2:Rectangle 2% t5 i, j  |7 B  N0 _+ Z' a
        //  3:Triangle
9 z# J0 Q' ?3 X% q8 V/ ^/ i        //  4:Noise& s) q5 B: D* O" H' T, j( P+ l% B
        //  5:DPCM2 l( y8 ^5 W0 r; [. n
        //  6:VRC6
- k9 {1 y6 ]: I7 k' v7 E        //  7:VRC7* F% C' o1 H" a* w9 M+ H
        //  8:FDS* l! ^  c4 R2 |( E) d+ W( N
        //  9:MMC5& D7 O, A2 j+ U1 ]% Z
        // 10:N106
7 G7 ^! f, W2 q5 C, z% @  v        // 11:FME70 Y1 j6 X# v- k  J
        INT        vol[24];( |2 z! p* ?+ T$ e0 D/ S  M1 P. P
        BOOL*        bMute = m_bMute;7 j% ?* p1 k& u$ n2 I9 [: G9 v
        SHORT*        nVolume = Config.sound.nVolume;
! j) O0 i2 k# L
+ p7 m, K* c6 I" U# p) d1 Z        INT        nMasterVolume = bMute[0]?nVolume[0]:0;2 T0 x5 g0 C8 p
: L6 V# T" e) X! c
        // Internal
3 j5 R0 e) J7 H) i, E        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;: d6 c$ X6 M  ~0 G! E6 g) c
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
7 K* U+ Q7 i% b- r& V        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
" D, ?; K% h2 h. V        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
* K2 H- H+ X: x        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
; N" p, V7 N4 D9 @9 n# G. k4 ~7 c$ R, N; R* f8 c
        // VRC6; B! u1 |+ l8 ^6 j- N% ?
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;5 Q6 K1 \) z) t! N; H. y
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
6 E; F, ]4 a5 k6 T6 V& Z# E+ S        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
7 A8 z8 H, N" s3 C: a, I$ Z' [7 n, z) p3 Q. a! k" r
        // VRC7. _& r( _; c0 g/ R" r; h# k
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
4 W4 ~) Y% U9 k3 S  _* I  n! z& M" L
  X. ~+ Q* G- R+ y$ j3 W! b- u        // FDS& K0 Z% B/ G, f, B# O- j- D) O
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
5 y1 m+ F' g% f1 R
5 S1 H& f/ B/ q; D        // MMC5
! ~( L  P8 {; ?* W( |0 z        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;; ~: Z9 H" z* E. R) F
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
6 d7 a6 i# `: `        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
( C: O" }" x4 p
& l; }* [* E* {) `+ t        // N1063 i5 O) `2 R( y# l0 Z
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;) c$ h$ n5 v$ ~( y4 P- g
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;) ^: F: F, ~5 [8 I7 l# ]; l7 U
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, f% t, C+ _  |- `& I        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
/ J& F+ v# s, n: ^8 p5 \        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
* ^  d( \* z- m5 [! s) ~- X% C        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
  j+ C* s! k7 o; e& u        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
1 c' B8 ]% W- P        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
4 V+ _' Q/ o0 l
7 b& E. z( J; j# T+ I3 n4 A        // FME7! f% u5 P) c7 g1 C. _# b- Y
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;& t" _; J0 L& i6 |
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;( C- s' l3 g& M" K
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;. |& Z3 l1 C1 m# D4 i

8 d  E2 s. x3 R//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
) x6 T& y- b2 }' X, q( W8 n        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
" C0 C: N5 s$ U3 c# h6 b( T; S4 R
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
/ z8 C) A5 t" Z" v" s+ S; F        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
+ e7 ^  r; [3 }! I1 Z                QueueFlush();+ ?- A* Y" a6 b
        }
  i& p) I' I* F2 S% M$ k- f/ s7 H8 V* P
        while( dwLength-- ) {; ?. j( E7 o' a0 W: Y' H
                writetime = (DWORD)elapsed_time;$ O  W4 F! e$ @/ a% F

  N4 J' @' F0 Q; V# ]7 R                while( GetQueue( writetime, q ) ) {. K# l: F5 F# }' a0 Z
                        WriteProcess( q.addr, q.data );8 d: D( t3 A$ Q: x$ w  `' @
                }
" e$ e$ D" d* ]! E+ g4 n9 Z* s) G8 f/ i4 B! W
                while( GetExQueue( writetime, q ) ) {
' g. Q, C) W! i3 w1 t- w6 c& k7 ~                        WriteExProcess( q.addr, q.data );" b! U9 @4 o" v/ @& N
                }, E$ \  ^1 ]% ~- L" w; y

' S# p& q' j+ d2 X" b                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7/ d9 c! q' u# q8 F- B
                output = 0;
; I" Y, k& ], F7 J$ Q4 a0 l                output += internal.Process( 0 )*vol[0];
/ _, T! K2 E# x/ ]# L                output += internal.Process( 1 )*vol[1];1 _/ r% a" K' k" R# P
                output += internal.Process( 2 )*vol[2];
3 f# Z' m! Z' i4 U, p3 ^                output += internal.Process( 3 )*vol[3];" \, k8 B* |, I' }% c) p/ t7 \
                output += internal.Process( 4 )*vol[4];+ B, n% _2 l9 a& y6 C( P. Z  M. V

8 K) D! a! L+ U+ [                if( exsound_select & 0x01 ) {
0 `& Q: Z4 @- b9 L2 r' [5 W                        output += vrc6.Process( 0 )*vol[5];
, e' r/ x3 y1 l3 d                        output += vrc6.Process( 1 )*vol[6];2 H. l# T1 q: w$ y0 F/ N' x
                        output += vrc6.Process( 2 )*vol[7];
  U: l7 V* D! o7 E* a, M                }5 G1 }! S$ B% F
                if( exsound_select & 0x02 ) {7 S% ~8 |  }! m7 m1 m
                        output += vrc7.Process( 0 )*vol[8];
3 T4 e8 }- k  d# t/ P$ Z                }
, d& u9 n" O+ |% ^9 C7 R                if( exsound_select & 0x04 ) {% O* a' s- s6 D
                        output += fds.Process( 0 )*vol[9];  j  c& i- e5 {# z1 {( M5 J
                }
7 t" y/ R  R# s; x. A; m, C0 G; _                if( exsound_select & 0x08 ) {' D, u$ C; ^0 c- _. {) p6 Z
                        output += mmc5.Process( 0 )*vol[10];
  G3 E: T/ y5 R0 i2 h9 j                        output += mmc5.Process( 1 )*vol[11];
9 z. A( g, M8 E& }                        output += mmc5.Process( 2 )*vol[12];$ s! I& Z3 k4 `9 {
                }4 ?# C8 R) }; F- P' a: B
                if( exsound_select & 0x10 ) {5 Y! e- q5 x1 L
                        output += n106.Process( 0 )*vol[13];' j, u5 O  c) Q' {$ B
                        output += n106.Process( 1 )*vol[14];+ c! K& S0 d3 h* ^5 G
                        output += n106.Process( 2 )*vol[15];
+ c0 q5 p, u( v                        output += n106.Process( 3 )*vol[16];
6 O! i) B% S) F3 T8 m* g/ H                        output += n106.Process( 4 )*vol[17];5 l/ \6 E; e3 r# U6 }9 M6 I
                        output += n106.Process( 5 )*vol[18];/ _) C; g3 c' J/ m4 ~& r4 E" E
                        output += n106.Process( 6 )*vol[19];& u8 O1 K1 t* x) m, v
                        output += n106.Process( 7 )*vol[20];
. u2 n9 ]3 \- q5 ?0 g. B. G$ A                }
( \* ]& y- I, `                if( exsound_select & 0x20 ) {  Y. w8 y( D( I& e+ Z
                        fme7.Process( 3 );        // Envelope & Noise/ Q& D/ W3 ]& x4 m
                        output += fme7.Process( 0 )*vol[21];
$ |2 y7 J# m1 m- U+ }! O                        output += fme7.Process( 1 )*vol[22];
+ |- I4 \: h5 r& u, s: [9 A                        output += fme7.Process( 2 )*vol[23];
5 E0 D) L6 Q9 y0 U! m. h                }
1 A3 C8 r+ e% r3 N! z3 l8 M: S8 ^* }8 N5 u( q/ Y
                output >>= 8;
$ Q, \. R& v: |4 |% ~; l
( Z8 @% J$ {( A% E7 O                if( nFilterType == 1 ) {
' Z# h( Y7 k, b6 ]- D                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)' ]/ T5 r  z$ [9 W
                        output = (lowpass_filter[0]+output)/2;
4 X9 l, y8 P4 K                        lowpass_filter[0] = output;5 X6 w0 |; N% {4 d/ ]: `
                } else if( nFilterType == 2 ) {$ ^% U! D: N0 d% k
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)( L$ \" r+ A+ v* f6 g/ N, H- t
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
9 D# ^) \" n, U- z: m* G* P                        lowpass_filter[1] = lowpass_filter[0];* U& Z' Y! X( l( W$ m
                        lowpass_filter[0] = output;- I' E# P/ ~; H0 t+ I
                } else if( nFilterType == 3 ) {$ ?! m4 K4 Y/ r) j
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)5 N2 a) m# `* x$ I5 a  |! V
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;  K9 C/ ^6 o) {. Z
                        lowpass_filter[2] = lowpass_filter[1];
# e: d2 l! |. J. F4 l. O3 r; ?                        lowpass_filter[1] = lowpass_filter[0];
& s, \) d' Y- A0 D3 S, a                        lowpass_filter[0] = output;5 ]# B1 @2 m9 C7 k7 w7 \
                } else if( nFilterType == 4 ) {
: |6 B# N2 ]  y& S" a8 U6 D; }                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)1 L' {/ Y1 X$ w1 V; c
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
5 G) S2 Y- P+ c! K9 J* @+ \( x                        lowpass_filter[1] = lowpass_filter[0];1 q3 \- V: {8 E" {$ v5 B& T
                        lowpass_filter[0] = output;+ |8 l6 L/ ~& s" [, N
                }
/ b$ M/ w+ t( l7 `* s* u' ]4 Q  U9 A) [. k0 r% v( `
#if        0' F; \9 t7 x) u
                // DC惉暘偺僇僢僩
; A2 x) _4 h6 \4 f, T5 z# w                {
, \8 ~/ E' s, @7 y! \/ d                static double ave = 0.0, max=0.0, min=0.0;
: a- g: z/ ^& G( C& w2 P) z. R                double delta;
( A2 r5 {4 F& r* R  S                delta = (max-min)/32768.0;$ e: r. \* [& O6 g( C
                max -= delta;
' R9 `2 T* j/ Q: _( j' c                min += delta;& q+ m: G( d# ^
                if( output > max ) max = output;5 T4 O; l6 z7 k' G
                if( output < min ) min = output;
+ d' v% @; X. T# K* h! H                ave -= ave/1024.0;
2 m$ V6 p5 q% X- u* s                ave += (max+min)/2048.0;8 l! W% A& b2 O3 z
                output -= (INT)ave;; v1 q- P: L7 F  @/ N! }
                }+ G3 h4 v5 _. `
#endif+ A5 G7 ?! F; ?% x" R
#if        1! |$ {# q, G- f. j0 k3 y# Q
                // DC惉暘偺僇僢僩(HPF TEST)- H# R; j+ Q0 n$ V$ R' u8 q
                {$ W. w) r- p/ j
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);$ j7 `) y0 v2 Z+ y: a
                static        double        cutofftemp = (2.0*3.141592653579*40.0);' L4 {. L5 C9 j. m' ?1 \6 ~# j
                double        cutoff = cutofftemp/(double)Config.sound.nRate;! W. X9 t0 ~) D$ N' l! I5 X
                static        double        tmp = 0.0;7 @5 D' ~$ c  G/ \4 P# t4 d  u& j
                double        in, out;1 Z  n- W0 m, ~0 c# v4 g8 X$ m
- }/ _  V. B# c; R
                in = (double)output;
) h: U& j$ e; Z. B! u                out = (in - tmp);
4 D3 m3 a' i. p+ q& _/ z                tmp = tmp + cutoff * out;
* a; B5 H4 _; {2 M7 r2 w
* Z- F8 \: H8 A$ A1 ]& X/ K                output = (INT)out;' A/ S* H( x9 r4 X
                }& J: C. r/ E0 f4 e% |+ _- n
#endif
& G, Q; c/ q  `2 ]' t#if        0
) v& W+ J! W+ v3 T                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
) q5 @( Y( e  @' _& k0 {                {4 D  b& l* X$ c) J/ W
                INT        diff = abs(output-last_data);! |7 k/ A$ L; X% ?! q( N8 P
                if( diff > 0x4000 ) {
1 L% E, L+ J( E* g, r2 O                        output /= 4;
3 P6 i1 ~& b6 Y; E                } else
8 f; H# l3 X9 c6 K                if( diff > 0x3000 ) {
' F  o0 z2 C* M. ~& V) ?  \, k                        output /= 3;5 @: t+ d/ w  c4 s9 I( x- D
                } else! c( ]  X! d+ V/ D! ^
                if( diff > 0x2000 ) {* x6 u; ]+ h& K* Z, \
                        output /= 2;! m/ C! k4 S7 U; j6 u, ~
                }1 `, @1 n! V5 u( S  H5 _9 p
                last_data = output;
+ I0 m9 r) ?* q. G1 L. f& H6 d                }4 {: O+ s6 \- |# g: ]4 Z/ |- S
#endif  |. [$ `8 Z) F
                // Limit
8 q8 \$ |% h1 x9 O% q9 `                if( output > 0x7FFF ) {
3 {) M  U' a8 n0 X5 S& D" W                        output = 0x7FFF;
* k& Y$ n# E3 i7 E% L1 z                } else if( output < -0x8000 ) {5 [# L$ H' Z8 _# x- j  G
                        output = -0x8000;
! K( t) ~# N- L, T  D; E- h6 s                }. c9 m% `+ N5 H  p4 }* r* q6 i

( I) i! r) p! ~9 Q$ q                if( nBits != 8 ) {
( y# y. T6 w5 p) H                        *(SHORT*)lpBuffer = (SHORT)output;
. n- h# G: s3 [8 y                        lpBuffer += sizeof(SHORT);
2 |- r7 f+ M& J* j! e                } else {( l$ b  s# C6 [" d
                        *lpBuffer++ = (output>>8)^0x80;. B2 q  _, S7 a$ \% o
                }
5 u* ]; i( {$ e% h7 `3 l5 v8 @1 p' j$ i
                if( nCcount < 0x0100 )9 b& |7 @" C9 T; `) K
                        pSoundBuf[nCcount++] = (SHORT)output;
5 r& e5 o- d, a' N4 Q5 l+ B
' f1 B6 r( L8 _; f5 G//                elapsedtime += cycle_rate;5 y% g& N% R4 O6 n' d
                elapsed_time += cycle_rate;
4 k( O2 t: P- g5 C/ w4 H        }
* X- Z" I3 q+ u  S0 Y9 I& f
6 ^/ t, Z3 k- A& o4 f#if        13 I0 Z2 c5 M$ ^8 K8 S% x; Y( A" r
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {' c( Z' Q+ ]- {. v% E
                elapsed_time = nes->cpu->GetTotalCycles();; K* e! B; _, P) O% A
        }
9 ^' A& Q1 h5 Y6 ~- i7 z' U. [        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {  ]* K7 ~2 n- u! ]$ [7 T  R
                elapsed_time = nes->cpu->GetTotalCycles();
) x; a2 ~. N6 E6 h* q9 U9 i; r        }
, N6 U6 e( m: K! e#else: e+ I9 ?8 C" J
        elapsed_time = nes->cpu->GetTotalCycles();9 g3 Y+ Y- D4 l- i, P0 X' j* |
#endif
+ y( X5 z7 u+ z) A# P}
# W8 ~( k3 x5 o/ K" Q  u# V% v+ S
; j5 T3 {! W- l4 M// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
/ H8 o/ A" m5 S+ G2 e) ^2 ~8 O, @INT        APU::GetChannelFrequency( INT no )
3 B# ^: [/ Z: m{7 ]: Q5 w$ U1 {) N
        if( !m_bMute[0] )& ]$ `4 t- z3 k, m; z
                return        0;
8 [: ^: Q' }) U" ?: X
% J9 A% p4 ~" h# }) R2 b* L2 Y        // Internal5 q# U. D! h7 _3 [* ?
        if( no < 5 ) {! k( p8 v% s" j9 C) e. a4 d, Y# K- ~
                return        m_bMute[no+1]?internal.GetFreq( no ):0;! x2 d4 D9 t1 G6 p
        }! _2 B8 Z/ e, C& l4 l* x
        // VRC6
. L- s& h7 r# v+ |' z        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
0 x4 M7 ?$ J, \: n6 b. g                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
9 \3 U( y  c- a  H% @# T; b        }
3 p0 ~1 k! t3 Q        // FDS
, k- r* H# t4 S) L$ }6 f  [        if( (exsound_select & 0x04) && no == 0x300 ) {
; }4 ]/ a2 U) m: _( U4 B                return        m_bMute[6]?fds.GetFreq( 0 ):0;
+ e4 Z! w% \! z        }
/ c4 D8 E' g5 A3 E% y        // MMC5' C) i2 N3 I( K" I2 d
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {% m8 ]5 @/ I" l' K) ^
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;" }. l3 e9 U& `! T
        }6 X/ D4 H8 n* r7 t0 H, @
        // N106& l; l9 p2 Q% w: p4 [
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {! G3 P+ r" o) o  E* a& V
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
; f8 r0 B2 R' ~        }9 h1 z/ r3 v& H- j
        // FME7
. X& z. ]; v3 k! \! Q: z$ X        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
4 }/ \5 F- E4 N& W% \7 J                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
6 ^$ n' g+ {/ y$ a2 @0 W! _        }8 w# [9 o: E0 n7 A6 F
        // VRC78 Q9 _* S% h3 h! y$ t; U7 r; ~
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
' M/ A. F2 c: w5 _# N7 d                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;! |! \' _0 l& G5 a+ i5 [: [
        }
) |1 W: V! H$ [        return        0;8 s) M( _, A5 n: L
}2 o# Z, A6 W' \/ x4 V

8 f, c# |* |4 B* x# h) P// State Save/Load
/ c! K& ^9 h/ O5 f8 Lvoid        APU::SaveState( LPBYTE p )6 Z& r$ c2 j1 p9 o/ D. A
{
$ l( W: w! S' \% ]#ifdef        _DEBUG
* E5 \7 ^4 z" u. [2 P. Q1 FLPBYTE        pold = p;+ f! o6 K1 m" p# y
#endif
4 W# }- ]7 q" W0 n
: a9 s5 j, C' S& w9 d8 q        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
9 r2 \8 ]3 H1 d        QueueFlush();
* M) z( U2 Z) ]) W* Z, e
/ S5 E2 M, C5 N8 n  F        internal.SaveState( p );
# c; Q" i8 f! R        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding! Z. N$ R- L+ |5 R
$ c" P) b9 d! e
        // VRC6
2 x, e' L8 ^6 b: I        if( exsound_select & 0x01 ) {
  U+ Q. R7 _* a. A                vrc6.SaveState( p );
' F  _# n8 f5 J# o8 a                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding: w6 Q2 S4 f+ F5 r( O9 t3 U( Y
        }3 k/ Y$ ]6 I( T2 X
        // VRC7 (not support)
" b4 X- s* }' a( Z; U3 q2 _% |, J5 d        if( exsound_select & 0x02 ) {& Y( ~2 G6 e# u4 m/ W% ~& K, `
                vrc7.SaveState( p );; t( b; q2 H; M5 T% `
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding0 Y1 ~+ e* W% i) R$ n
        }
) S3 p+ b0 _) l8 `  G2 h% A        // FDS
5 I7 N6 Z, L' p2 r6 c        if( exsound_select & 0x04 ) {
, a, d/ z6 T4 o+ B4 u3 r                fds.SaveState( p );
: _: [" w. M& m. h                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding& y; f* d+ f( i0 Y* G* R8 S/ S8 W
        }+ V1 X- s2 D- d
        // MMC50 ~' y6 k) Z; L! S% L& H
        if( exsound_select & 0x08 ) {
" T! V# e0 S3 ?' [( R: W                mmc5.SaveState( p );& @, E( n4 Q" O3 g1 b7 `
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding* m. s6 p0 I; [( p& j" Q( i8 k( j* A
        }
# N2 u2 T6 d8 ]! [5 y+ ~. K. Y        // N106
+ M0 }, x9 c  ]( ^        if( exsound_select & 0x10 ) {% s, u: u6 R. f! l! J5 P# w
                n106.SaveState( p );/ D; [2 ^8 W- T; c& u  T/ b. s+ `( B/ d
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding- ^% j7 V$ w& W$ N7 N( A! ?% ^
        }
3 ^% Z; A! H3 H  g& `9 C+ T! l. i        // FME7& M$ _' Q7 H8 e2 S( m* \
        if( exsound_select & 0x20 ) {1 J! @# q6 |8 g! D- f
                fme7.SaveState( p );$ K2 R( _2 ]3 d8 b  X
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
  U# H7 T' o7 M' c: s% }        }, z+ x) q1 b7 R8 P% @

$ E4 M( Z( C9 O; `8 e" I4 M! |#ifdef        _DEBUG3 u; k1 Z/ a" o2 X
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );# d& z4 ?+ p' q3 ?! |8 c
#endif4 ]7 ]  [+ `% F) A& ]' y
}
; k; a4 K7 ?9 K2 _* y# l8 K
7 ~9 }) i2 W3 p0 T& W' H9 a$ Zvoid        APU::LoadState( LPBYTE p )
7 m! k2 |3 _$ e! Y{: `3 V1 g: [7 ?. c* f9 ]- p
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
5 \: V8 X+ \0 v* q6 a! a; x# z        QueueClear();/ q" r' Y0 R- `

- L' |% Z+ B- C% l& y5 _  K- c        internal.LoadState( p );1 I" U" i0 ]/ W  S3 J7 S
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
' f  K" t  C$ a" l  \6 \1 C  B$ {5 ^9 L3 `. ]2 t* V" [
        // VRC6. d& q% X, M7 g+ r+ B4 Q4 e
        if( exsound_select & 0x01 ) {1 b: l0 J: p; ^/ n5 }
                vrc6.LoadState( p );: O' I9 J1 v( n* S2 \; ?+ i! x
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
8 C0 ?' W/ S9 ]- b        }
. a8 U; P9 o* r5 H" G        // VRC7 (not support)5 k* F; }6 V6 E5 s* V
        if( exsound_select & 0x02 ) {
4 P: T% B; c; c$ k$ T                vrc7.LoadState( p );
% D' o  Q& k; R4 K' p% M                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
6 ]$ [8 `, J) }, y        }- F+ ^( V, P% o% n& N: }$ F2 r& p' e
        // FDS
# `6 j; V9 Z9 T0 ], K! y        if( exsound_select & 0x04 ) {4 e; c) n, U5 ?: b# n
                fds.LoadState( p );
4 ?" O# U, e5 O8 ~9 N* A7 ?                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding5 G8 t1 j, e7 e0 D, e5 ~
        }
* ~! r& J( Y0 h        // MMC5
& Y- G3 s( V$ B        if( exsound_select & 0x08 ) {; H, Y* s+ S  r3 x+ M
                mmc5.LoadState( p );
- Z7 l( k' m: `1 X3 }                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
1 M6 ]; Z7 r' t- w) s! a0 X        }4 L3 F* }7 F2 _5 @
        // N1069 k/ S' V+ u" R, q" G
        if( exsound_select & 0x10 ) {
( Q; |5 x3 x" c                n106.LoadState( p );
( o8 W7 D2 r9 g2 R$ W                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
" i0 e# h8 j+ Q        }
+ \# l. i; B. W        // FME72 Y: ?% h& r, D. z1 F2 a
        if( exsound_select & 0x20 ) {
/ O& G# m& V; f/ @- n                fme7.LoadState( p );4 z% C) w$ t! Y
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
% F7 c/ [4 O6 j0 c        }  J. @( j, `& M5 t% Q. y
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
8 v/ n4 K7 v2 l3 s- [* _可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
+ s4 q+ q& R+ g7 u. S( F感激不尽~~

6 Q% _" T( O1 u8 l- M恩 我對模擬器不是很有研究,
; ^( e1 @% A6 A7 R, T雖然要了解源碼內容,可能不是很困難,$ ^8 D" X- U) h4 V6 ]( d
不過還是要花時間,個人目前蠻忙碌的。, W7 E6 R9 W) l5 h

# U, S& u7 J5 `# e4 u4 [( c: c& s5 J給你一個朋友的MSN,你可以跟他討論看看,
0 Q( M, o: y9 f- B$ z他本身是程式設計師,也對FC模擬器很有興趣。
8 @8 y  {( a9 _( \9 ^( L+ e
  ~, ]* {6 W- G  m- I/ {MSN我就PM到你的信箱了。
7 {) Q5 @! y) ^. @7 Q" ^  ]* W6 |4 a6 Q9 D: [" z
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
% f1 T0 B2 f" r7 o" i6 ?3 t, _1 ?呵…… 谢过团长大人~~
# X, _1 D7 `- d6 l( G
* i; \+ v2 ^; M) ]  J0 H; p/ k
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 / j; y0 N+ s# |. Y* Y& p* K3 W" a
团长的朋友都是神,那团长就是神的boss。
# m+ d( J: K1 f5 ]9 \# [
哈 不敢當,我只是個平凡人,
2 i3 T( [% x1 Q, a/ Y" T; B* Q要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙2 z- [4 l9 a4 @# g1 N
ZYH
$ Q6 c- N/ Y: k! H# hQQ:414734306! l2 r% x7 r# U2 U6 `5 r9 N2 b
Mail:zyh-01@126.com2 b/ Q/ K. a+ ^- K1 n: Y

% A. L- I  ~6 N9 u+ W7 Y他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
5 K# z$ @4 x- x7 H! z再次对团长大人和悠悠哥的无私帮助表示感谢~~

4 m$ ]+ z" u' e& y* r7 m) W不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-1 07:49 , Processed in 1.088867 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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