EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。$ C9 Z2 Q* a( I
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~5 V0 ^8 m8 W  b1 O  `
这里有相应的模拟器源码,就当送给大侠了~~
+ i  v  o) h9 ^2 s" Chttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
8 O' Q% y& t7 b0 S能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。& s9 m% w6 e4 r) b0 i
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~8 `' f1 G- f5 T+ n5 n3 W
这里有相应的模拟器源码,就当送给大侠 ...
( L1 v1 p0 e# J% H' }% d6 Q
聲音部分(Audoi Process Unit = APU):
- x% w& V; m- [+ w' K.\NES\APU.cpp
1 \9 x& h; y  g( ^3 o8 c% m- \' V.\NES\APU.h, Y2 C; L0 Y- b" T' k& r! o

0 J7 h( d8 O  i; g/ Y
) c. z, y8 Z8 Y影像處理部份(Picture Processing Unit = PPU):- y$ ~& a3 p0 A+ Z8 @' W7 p
.\NES\PPU.cpp2 n" p  H: j, U" ], x6 [; ?# d
.\NES\PPU.h
& n8 a0 O6 ~* e4 z3 ^2 G; j
( Y8 a2 m; _' x# S3 l+ G7 B( R: h8 O如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
6 J  J- G9 z: w: S9 Q(由于很多专用术语和算法机理都不明白,所以看不大懂……)& d5 Q2 @! I/ g) [
//////////////////////////////////////////////////////////////////////////
/ ?. f6 e1 n, R9 ~: V+ w8 [//                                                                      //
7 ^. B6 \" l4 d9 m5 f( n  G# j//      NES APU core                                                    //; c0 e+ C: U% @2 e- j
//                                                           Norix      //
4 k! O1 R. R* u//                                               written     2002/06/27 /// B7 x1 O, {' H# [
//                                               last modify ----/--/-- //6 p1 i* x) [9 C4 {+ R7 H
//////////////////////////////////////////////////////////////////////////8 s" `' N1 _$ t! ^& Z& v: w
#include "DebugOut.h"1 \3 N1 j3 E5 P/ s. U" z) {8 Q
#include "App.h"
' t" `. ?3 \. _! f/ K+ o" y4 N& Y#include "Config.h"$ \) q3 {5 f. A& G, a3 {

9 B1 j/ Q/ {1 |* N) c' ?#include "nes.h"
0 y( S) W9 x4 u8 E- r#include "mmu.h"+ d8 X, c/ H, `& [. h# S
#include "cpu.h"8 R6 D+ ]( a: _9 a" Q' X1 B
#include "ppu.h"
* Z/ C. d. U# L1 |; j0 J3 y#include "rom.h"3 X5 A# e' z' o8 h, B, w! b0 }2 m
#include "apu.h"% x+ ~9 m2 P* Q; U: t
' u: T4 B9 k* G
// Volume adjust
& e: ?4 K' ?1 c. O) R3 Z* g// Internal sounds* S7 ~1 Y' v$ U* C* o$ y8 n
#define        RECTANGLE_VOL        (0x0F0)
  j1 j, L; m( L3 U. c#define        TRIANGLE_VOL        (0x130)
9 F4 b2 V7 `2 N& P6 I; [0 [- A) C#define        NOISE_VOL        (0x0C0)3 l: W7 |( D, C1 u, c9 p& F
#define        DPCM_VOL        (0x0F0)
5 z. N1 q5 X7 |// Extra sounds3 f( ?- Z; H7 c0 C) N$ I& F
#define        VRC6_VOL        (0x0F0)+ E; a  C' g4 h7 L! @. u
#define        VRC7_VOL        (0x130)
' `$ o, l9 Y/ m/ {#define        FDS_VOL                (0x0F0)% Y: p( s/ f8 M5 U* z* f
#define        MMC5_VOL        (0x0F0)
% _$ h$ L3 Z- N#define        N106_VOL        (0x088), R* Q; S( t; g- U* z/ L' X
#define        FME7_VOL        (0x130), J0 z- E( q+ l) u
" P7 U! [( O) P, }) i7 y) L9 I6 S
APU::APU( NES* parent ). l& W  A: l* U/ Y: W  ?) x
{
$ y2 a) M! v" {" l# R& M        exsound_select = 0;
/ W. {% f* a0 s' X0 I( t  L/ R3 x5 e/ H/ C
        nes = parent;4 c) t0 m! w/ k5 N/ l
        internal.SetParent( parent );
& `! C$ V  c% C" v5 h; i: Q
4 t# f" {% n* M+ U6 w& W2 b" {5 S        last_data = last_diff = 0;* R6 `" ^6 _* B3 Y$ K' U/ @
9 A. d; t; @$ W4 I( ?8 p
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );1 C6 p/ Y( \* g4 N

( O1 k9 N+ E9 `9 [  `- k- y$ _4 k        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );1 B# P6 |3 K! r% `) j) k2 y7 b$ u
        ZEROMEMORY( &queue, sizeof(queue) );
. T, H# C; ?0 Y/ L2 W        ZEROMEMORY( &exqueue, sizeof(exqueue) );
3 B, z0 Q& c* n
' u- {& d$ Y& f" j' d! u+ T/ Y        for( INT i = 0; i < 16; i++ ) {, G$ g- A1 g5 x' [$ l# @& _
                m_bMute = TRUE;
- J: c% T9 G& I5 b" M3 V/ }        }1 `5 r/ R& b- x, I- i) u
}# r* W9 i4 H1 j5 K7 u* G
4 ~% `& ^- t1 g6 ^: P  ?6 }
APU::~APU()
1 s  J1 L& U0 d$ Y( X{
6 Y/ D* y' l9 Q0 B5 [2 O9 e}: i( n9 q) v+ q: S

4 r8 @. Z# {6 S  P5 _, s/ r2 v2 Zvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )4 q9 e6 h. m! ^/ s- \" I
{
2 {( I2 D) O' O" i        queue.data[queue.wrptr].time = writetime;! e# U1 ~7 I2 c5 x3 |. w" q" @
        queue.data[queue.wrptr].addr = addr;
2 P5 P! I* p0 W& F6 ?/ A        queue.data[queue.wrptr].data = data;
; j1 T; y- @( B( G- G) v1 D( S1 M        queue.wrptr++;0 v: s  L# _" p$ t2 P0 K5 i
        queue.wrptr&=QUEUE_LENGTH-1;- a# O, G; w3 y4 K# P* A
        if( queue.wrptr == queue.rdptr ) {2 I0 f( O- _8 L8 r# g
                DEBUGOUT( "queue overflow.\n" );" w! a+ k; _1 V- M# l% O1 w
        }* N0 p0 M! I( b$ }
}
; j8 Y, g( Q0 r1 `: V
2 }; z8 c" K5 ~, S& sBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
# [& X+ i& p* e2 T% r6 r{! A$ F8 `. u( d+ p
        if( queue.wrptr == queue.rdptr ) {
5 n+ `- E" \. g5 O  d# q) R                return        FALSE;
9 e' a$ H5 A' i        }' ~; N  ^; W. [
        if( queue.data[queue.rdptr].time <= writetime ) {
5 o! l* U" |2 w5 j                ret = queue.data[queue.rdptr];9 l. B: P1 i+ p4 ^
                queue.rdptr++;/ x/ i3 `" ~4 w7 r
                queue.rdptr&=QUEUE_LENGTH-1;
5 y0 i9 ]# q  Q                return        TRUE;2 d! ]2 h4 {) Y; a5 n
        }
& t# E7 l: r  q/ {. w        return        FALSE;) R' b! ?5 W4 ?7 I; m1 a: {5 W3 b
}+ c. Y$ R. V( ~- B0 a! S+ c
/ Z* E) @+ C- N, ?/ r2 D% B
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
' [+ n1 `  [6 T( H6 \{7 r% m4 D' w. u1 V# F
        exqueue.data[exqueue.wrptr].time = writetime;
, ?' n& ~3 y% W        exqueue.data[exqueue.wrptr].addr = addr;; E- |: B& Y8 Z; Y" ]4 `
        exqueue.data[exqueue.wrptr].data = data;. r" f: K8 l% ^1 H8 L: ~- A/ J
        exqueue.wrptr++;
7 D+ f/ O% H- P. F7 \2 R' e        exqueue.wrptr&=QUEUE_LENGTH-1;, ]0 i5 J" R$ i
        if( exqueue.wrptr == exqueue.rdptr ) {
2 i, L3 m$ _1 D; O                DEBUGOUT( "exqueue overflow.\n" );# A: [! P1 ~: `. r
        }* E" {. Y( ?7 |+ z: L
}
7 M5 o# l0 Q& N! @) G3 [3 S& T/ x9 m$ i# s0 }7 l3 `/ S  ^
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
9 p3 x/ E9 t* X* S+ ]* p7 w( s$ t{4 a- t5 Z5 c% J; g
        if( exqueue.wrptr == exqueue.rdptr ) {- M6 W9 V. w: a1 J4 {
                return        FALSE;
" t( q) X; [  y- M        }
1 d6 {7 H  I2 F5 u+ R        if( exqueue.data[exqueue.rdptr].time <= writetime ) {0 u3 d& a! t6 W2 k9 D1 `# u
                ret = exqueue.data[exqueue.rdptr];
7 j8 B+ B, D5 g  }' R% I                exqueue.rdptr++;5 q" s( E/ ?8 d$ u+ a9 ~
                exqueue.rdptr&=QUEUE_LENGTH-1;% i( ]; ~! R1 i. G% R. w
                return        TRUE;
) K" C5 F( ~  d( ^. U1 }        }  Z2 f& f6 I# L: i' x1 b1 f9 R
        return        FALSE;
" P/ Z! r, n: Z+ Q9 q}
( D" P! w- E4 E" e# j1 k
' {4 w1 Q, B- @' g+ p( P4 x7 Lvoid        APU::QueueClear()! a; z/ h* t1 |2 f) [3 U
{
8 J- g  `4 z% w        ZEROMEMORY( &queue, sizeof(queue) );; y# C6 _! p. t
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
2 {3 }% z" `3 d) W, W7 ]. Y+ `- D}
( Y* F/ U! T7 L2 ?7 |3 t$ u  Z( T5 ]  f- O7 z9 S! `2 h: m
void        APU::QueueFlush()
9 d* e+ A4 I/ R/ M) P+ u2 n{8 _) H0 t1 {4 G8 Q
        while( queue.wrptr != queue.rdptr ) {% q! _6 N9 U+ s) ]# l) p& ]6 V
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );9 Z  {: ^, b) |9 s* v% b+ o! e  Q0 ~4 I
                queue.rdptr++;" m6 o5 ?$ a0 `# F
                queue.rdptr&=QUEUE_LENGTH-1;: W( A. V5 M. v) F
        }2 ?& n- H. I8 L) N. I. o

9 q: M" e! N$ }        while( exqueue.wrptr != exqueue.rdptr ) {' G4 z& {& f, G# X8 J% f. m8 |
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
( e; z) Q. Z8 f1 P; g( A0 z                exqueue.rdptr++;
$ e" \8 A5 J! F6 a  g1 U( k; |, N                exqueue.rdptr&=QUEUE_LENGTH-1;
0 {# Q% J! q" U        }
. m5 U3 a: S' r}  i; @7 r/ p  K; ]9 k% S
: N+ X$ i, `. y( `% }$ z
void        APU::SoundSetup()$ A3 V* t7 K3 }  v9 a9 L+ F
{7 Q+ y  M# Z/ e8 @; e: v7 x
        FLOAT        fClock = nes->nescfg->CpuClock;
% `% z3 \: ]( j9 i' V  I        INT        nRate = (INT)Config.sound.nRate;
! \( \( Y* R; {2 Q4 k  y        internal.Setup( fClock, nRate );& C3 `! T8 v! e  h% Y* ^# E" P
        vrc6.Setup( fClock, nRate );7 f4 b7 I8 L5 {* o  h# U( ]
        vrc7.Setup( fClock, nRate );
9 O" F; c2 L* x$ C5 v        mmc5.Setup( fClock, nRate );- @3 |. q- T: y* r0 H
        fds.Setup ( fClock, nRate );
+ A& ^  v  |8 \! w7 s        n106.Setup( fClock, nRate );
$ q) W2 e1 I" ]        fme7.Setup( fClock, nRate );; H* d! L5 A$ \# {
}
; y. Y" t% n5 J" R' w1 @, L" ]
# O% `, H6 o) Y0 {6 \1 ovoid        APU::Reset()
* ]  t9 M1 i( r{
, M6 F- {: S4 ]4 k1 a        ZEROMEMORY( &queue, sizeof(queue) );  O$ Q0 N: q( k( w0 h% l& _0 S
        ZEROMEMORY( &exqueue, sizeof(exqueue) );- O) `- }4 _7 k# g/ Q; T

$ y0 l! k( q: h; P% G8 c9 M2 x$ J        elapsed_time = 0;3 k& u" Z1 ?4 u. j
2 K4 K* M. W; r4 O- `
        FLOAT        fClock = nes->nescfg->CpuClock;  R- ^/ o2 b1 M1 }
        INT        nRate = (INT)Config.sound.nRate;
' T' N: s( t5 X) x/ i        internal.Reset( fClock, nRate );
3 [) i5 q: {- O. U8 ~5 B4 o        vrc6.Reset( fClock, nRate );
4 e6 U. G' M# j- ]) x5 J        vrc7.Reset( fClock, nRate );$ Y$ I- ^6 x9 D" }' o
        mmc5.Reset( fClock, nRate );
0 `: X3 ]! j1 l/ m; ]/ d        fds.Reset ( fClock, nRate );% O; x) `+ H) c6 S
        n106.Reset( fClock, nRate );
5 h9 {. n0 P$ V3 [        fme7.Reset( fClock, nRate );
( t9 l! B/ A5 i* j" ?
' ~# H7 i0 G( A" V2 Z9 S, D  [: j        SoundSetup();
0 C2 j) o+ |: _. N) T9 X/ e}0 d# ^' O/ R: n9 b
- H$ r: u4 Q( i$ M6 r5 f
void        APU::SelectExSound( BYTE data )
7 u' o0 w% J9 K: t/ v" g{
6 ]4 G4 n6 P& P        exsound_select = data;! D+ q- o5 J! j- y) }7 u' N
}& e# U, S8 F! R( |( j, B. X

% Q6 c$ S% t2 z& X6 n7 Z# s; aBYTE        APU::Read( WORD addr )- z8 b+ ~, M) [# H7 o
{0 x# H, ~) c+ l) N" Y$ u  ^. s  U5 Z
        return        internal.SyncRead( addr );, g# Q9 m) l. Q: |9 h
}
* U+ l, {+ N7 j) P. e" S4 g. i9 g# x% Z6 I; ?
void        APU::Write( WORD addr, BYTE data )
: n, n% p6 G  \. }{7 A5 i: Y* t! Y' V* A" q. q; E/ E; {/ N
        // $4018偼VirtuaNES屌桳億乕僩
2 @. J' E0 ^  ]( f7 x  V        if( addr >= 0x4000 && addr <= 0x401F ) {) e0 T- T. ^  Y' r1 v; o( ~, @% S. _
                internal.SyncWrite( addr, data );
8 G) ]9 G1 W* o. C9 d  W1 x                SetQueue( nes->cpu->GetTotalCycles(), addr, data );) n1 j) l# c( A4 V4 V6 n, z$ @# o
        }
/ z: b& g2 t- l4 y}
5 |7 j5 ~! F& P6 l$ ^$ y
$ o2 {- l. P1 t/ ~5 ^; X% \& dBYTE        APU::ExRead( WORD addr )
7 L: n: \( s  v. X% a- T+ O4 f# i{
' Z8 k6 R. f! Q5 k. Q$ qBYTE        data = 0;' h' V4 s4 r* s( |
. z$ N: w5 o' s9 z: n
        if( exsound_select & 0x10 ) {
& @" Q# a. O# d7 _  P                if( addr == 0x4800 ) {
8 u" i: x. _2 X0 j                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
( x) r1 w4 e, ]6 O0 q* m6 e                }
5 |" l+ q+ v5 K3 N6 S$ i        }- t+ s/ M2 ^" g8 {
        if( exsound_select & 0x04 ) {
% w2 D2 \8 R+ V, \$ ]/ S7 `% V                if( addr >= 0x4040 && addr < 0x4100 ) {. P9 b- m5 [' O! _7 U9 j
                        data = fds.SyncRead( addr );
" j2 ^8 \) R; ?% H3 Y3 v! ^6 i  w+ F                }
8 I% a! g/ R9 i        }7 X6 N7 c. W  l: Z+ R
        if( exsound_select & 0x08 ) {- c; B' u9 ~5 C" T' r
                if( addr >= 0x5000 && addr <= 0x5015 ) {
" A# \; [! b* L8 a# ?9 X                        data = mmc5.SyncRead( addr );+ m1 [$ c+ h7 X" @8 B4 }, w
                }6 S$ g0 p5 Z0 O
        }
. m9 K0 ?. e! I4 b) P9 f* h* R2 ~
        return        data;$ x! P( n6 \7 v
}( M% w. j9 }" T/ b6 p. s0 ~
) D9 [3 G1 @+ r: W$ m8 \
void        APU::ExWrite( WORD addr, BYTE data )" i8 c; B( e/ C; X0 X7 `; [
{
. F$ z; m! @  d" i        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );! f( B7 _; N0 ^% b: f" I. ]* n

( @, p: v. h8 W" z/ J. F/ i" B; K        if( exsound_select & 0x04 ) {
4 R/ n- _# I( D6 l; k                if( addr >= 0x4040 && addr < 0x4100 ) {
5 f- L9 x! e# o. a6 k* y! I                        fds.SyncWrite( addr, data );
4 O2 w4 q" Q& I( }6 ]8 h                }, H4 b& h1 ~& ?1 V; g
        }
+ F; [3 E* D2 q+ J* {# w
. }5 p( W( m& c  [$ K+ u        if( exsound_select & 0x08 ) {
; a4 f" c* [4 ^                if( addr >= 0x5000 && addr <= 0x5015 ) {! y3 j/ b& A" r8 j
                        mmc5.SyncWrite( addr, data );9 h+ a: z; r0 H4 l! b
                }
1 r3 n4 }# h! }1 R. r: x        }
" V& V7 k$ e, R/ I& [}
1 f8 l1 H) q/ y: N; s% }) k
* e+ {% |; Y7 ?! J" gvoid        APU::Sync()4 k7 y2 M& r! Y
{
. {4 e$ m/ z' L6 L* e& A6 Y}0 Z& z! w; l! N
+ R; K2 f" q- @4 |) W. W/ p
void        APU::SyncDPCM( INT cycles )5 F  b6 f% X; @# l
{! X& r( a& s5 k1 Y
        internal.Sync( cycles );1 R; ~0 G2 \' F3 m, N" o- o6 b
, z$ f) ^- N9 N6 j( E
        if( exsound_select & 0x04 ) {
* A6 y  ]/ w% t% k. I                fds.Sync( cycles );: P1 j5 Y0 D' T/ \
        }- `! G: c* B4 X2 `  l% @
        if( exsound_select & 0x08 ) {
8 |& m$ _6 q8 L5 D8 g" Y  n. X                mmc5.Sync( cycles );
7 W9 b0 D- P5 q1 e$ T        }8 V2 G& J% B) ^
}
6 M+ C6 d9 r9 p- `& c+ T
" P$ J% O; E, H2 i' L2 xvoid        APU::WriteProcess( WORD addr, BYTE data )
/ d- @7 ~- q' }7 b6 C7 {1 U{+ R: g- l# X; \! A
        // $4018偼VirtuaNES屌桳億乕僩/ X; F( w3 ^) u0 T7 n" o0 F
        if( addr >= 0x4000 && addr <= 0x401F ) {
5 C( j5 e3 l) w: u8 h$ K  i                internal.Write( addr, data );
2 G  j+ w6 X. e/ f        }. C2 k. u8 w9 M3 [: l$ R) N. u( Z! C
}# q0 ?8 y. F5 d8 [
' C/ O* o3 f' O0 @% v
void        APU::WriteExProcess( WORD addr, BYTE data )
9 m6 @  v& f  ]! b5 ?/ `& D{7 ]6 [2 n" q9 G8 I- q' M
        if( exsound_select & 0x01 ) {
+ p5 n; h) @0 E( h                vrc6.Write( addr, data );+ g4 m& b9 p' J) w0 R
        }
( i, }. s2 P3 }! c! x6 j7 g6 w& T+ Y8 Z        if( exsound_select & 0x02 ) {
& t' I1 i6 C8 B% n& e+ a                vrc7.Write( addr, data );* t+ i# Z9 y$ J% z; e0 K5 u( T
        }
) k7 I: p9 E& i, l* s$ h% C        if( exsound_select & 0x04 ) {! S5 R+ H& V1 g  l" E
                fds.Write( addr, data );
/ c" F0 a! a$ _        }7 W$ J3 y" ^$ B' `* ~. E: d
        if( exsound_select & 0x08 ) {
) A9 a' g" ?' {2 J& `                mmc5.Write( addr, data );  q7 H5 r' S- x2 S9 U! v" L
        }
1 D! x  \# l5 ~        if( exsound_select & 0x10 ) {
1 C1 l% g5 Y1 ]8 R                if( addr == 0x0000 ) {. {4 h  P: l+ h/ q" i* W  g
                        BYTE        dummy = n106.Read( addr );
* P* l" }5 _: f$ s9 y                } else {2 i1 ]7 ?/ E! I! W! C
                        n106.Write( addr, data );
$ J/ a1 ]. p# o$ X# s                }
0 D& a. z7 R# T/ g* k        }$ V& g: \& f+ D2 G3 v2 Q" T! B* `
        if( exsound_select & 0x20 ) {
# i2 m! J& {0 T7 O                fme7.Write( addr, data );! J, P! l; c7 g3 v% `3 i% G
        }' `6 g& z5 b9 Q+ Z3 T( x
}
- o5 B6 n/ @5 {* g/ V8 M) r" ~/ }
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
7 `. e* \, T+ Z9 m. Q{; b" w6 l* j/ L9 l
INT        nBits = Config.sound.nBits;# G( C/ \1 p6 ~! `2 n) }0 l. a1 \
DWORD        dwLength = dwSize / (nBits/8);. `+ |! v/ m9 s% i4 s9 R! T5 \2 I
INT        output;
7 N4 U  B3 @9 D7 L, XQUEUEDATA q;/ W+ b/ s. z4 {+ G
DWORD        writetime;
4 P8 p6 _4 B0 Q5 W% ^4 Y" S$ @/ V2 ~3 ~
LPSHORT        pSoundBuf = m_SoundBuffer;$ A6 D- D1 V7 D4 P, M! }5 W$ E
INT        nCcount = 0;
8 Q: L# E5 z! Z( ?$ R5 K6 I
+ k3 ~* N2 O( f; EINT        nFilterType = Config.sound.nFilterType;
) C: R* I1 ]/ P3 N7 U, s+ Z* x/ l( \9 f! k! w$ Q
        if( !Config.sound.bEnable ) {; i+ Z% X  y7 m% c; T- f
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );4 A  ~6 {; F! B$ i
                return;; Y" e; g4 D" D: U4 a4 l6 G
        }
/ H7 m. i  N' q1 \. K, C' c6 k; `" w& U0 h
        // Volume setup4 p1 ?: K4 h) t  X2 x
        //  0:Master
" N! r4 e4 ~- m' t        //  1:Rectangle 1
" L; @3 C  S' r: S/ l* `' f# h        //  2:Rectangle 2
; L$ I2 t* \$ i0 w8 h% F- O  E        //  3:Triangle$ t5 W8 t( ^9 H, |
        //  4:Noise$ e  w$ d  ?* P4 _2 }
        //  5:DPCM: C) a8 o) p" K' u1 {  P( G
        //  6:VRC6
% C& W7 C9 _& h9 J& H2 o7 M        //  7:VRC7- Q$ A7 X: [# e- K& Z$ |
        //  8:FDS5 O9 ?: ~/ _5 @' x9 ]+ D
        //  9:MMC5
; \" G" w& ?/ g- W" _. g5 L. e( [        // 10:N106
1 E" |0 m) _5 A$ |& b        // 11:FME7
) y* [) J  S9 _/ w- X$ Z5 J        INT        vol[24];0 z0 ~" G% W0 ?; ]6 y) U) g
        BOOL*        bMute = m_bMute;
2 D% b2 F! Y/ M/ l        SHORT*        nVolume = Config.sound.nVolume;
6 k$ w$ \+ {  q8 {" i6 y% _
7 }. D. c! X% u        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
: q! O) E* J. h2 O# N* j
9 `* J0 [+ d% v4 a3 U. U- F        // Internal
0 G0 z- V2 w) `1 n' N7 {        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;& t% U4 s' Q# r4 a/ g9 i0 g& `7 v
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
4 h' i6 {2 Z- z+ Z        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
0 |3 _; p8 O% u3 z0 r& e2 j! F3 `        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;9 [$ x/ k$ w& k# u( u
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;& q0 G, n0 V, e
. b* ~* U! r0 h3 @2 W7 X2 B
        // VRC6
! f: h( D, q" y        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;1 X, j+ ~" O8 Y, F3 {$ E
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
/ {5 U" `; ]) r3 |* o, q$ h        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
/ n* Q: B+ ?% M. S2 U  b8 v' f% w9 Z+ V7 z+ M0 ^9 b
        // VRC7' A8 }. Q) ?! o( T7 j" ~* C
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;0 M* e1 o5 B9 I0 ^0 g
: z6 @4 K$ _# J7 A& c$ ?
        // FDS/ |2 s/ z( M0 I9 ~6 j; J
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
* n. v( ]" z: d/ m5 e! k3 R+ q) z: |
        // MMC5  z- }9 e  z+ C& x1 d
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
  C6 g/ S( S: H% v4 k+ s6 D        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
8 ]4 p: s+ P' W        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
; `" B& r5 x5 g8 ]0 G
: x& r, G  O/ b/ m6 Y+ f& |        // N106
0 E+ ?. ]" n& M        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 b- O# h4 F- ^7 G# I5 U        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
$ T* m, z9 `. R4 H9 ]        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
2 [5 [2 e& `" t+ i5 M        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- k0 L' B3 P3 X: w        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
/ O1 B/ Q6 G' R1 F0 D        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;! G0 K( o( W' W# M3 X8 I7 I
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 T/ _- R0 M: T, Y0 Q& T: o' w" s
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
  ~9 p+ z$ B' K3 `; `
4 o* |; ?$ i, N* ^        // FME7( T. T, F5 b8 Y, r$ b
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
4 j& H6 c. N% e! e& r9 L2 h" `        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;: W; W4 D4 _4 j  Z( l& `2 k
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
' x! B# Q6 A# L& R3 v4 K4 q5 n
7 v! m, f- K  r0 p//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
! t1 E9 \9 p+ a+ L0 c* g        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;' M0 Z0 Q, E6 U1 Q4 N( j8 }
0 o4 J5 Q8 k" f& O9 j0 S
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
5 s/ z$ |( J6 i  F        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
& f- @" r* U0 g* Q" |, T                QueueFlush();; h% `3 i. p: y: ?& D& z
        }
+ e: Y/ O/ }. @) T; e6 u2 y
$ H% _: ^6 U. P* C        while( dwLength-- ) {
! ?$ z& L1 \4 q4 w2 x                writetime = (DWORD)elapsed_time;
* A# o6 \& y% L% u2 e! p& B" l" k! R- S7 ]# I( A5 ~; s
                while( GetQueue( writetime, q ) ) {
; Z! B6 E; s( m$ l! Z- }2 w5 M                        WriteProcess( q.addr, q.data );
, C7 ?) K) ]' r# R- M                }1 i3 c) }" {* B/ a0 H7 }* x
* Y5 u4 \; d- q  e" L
                while( GetExQueue( writetime, q ) ) {
- ?% O- V; v! K4 t3 T( \: s1 Z% J/ A                        WriteExProcess( q.addr, q.data );  M- t3 b! o2 A8 X6 h5 _7 n: i. }6 K$ ^
                }
; h8 T7 g8 }  |: U. u4 ^) L& D
1 b/ I$ U! w1 E8 M9 X3 i                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
  y# W- d) L3 Z                output = 0;
+ f! O3 u- ?6 V& u) y) j! b                output += internal.Process( 0 )*vol[0];
% S6 w  x7 r3 K% E8 j- [                output += internal.Process( 1 )*vol[1];
$ A( C$ m( m/ u/ [( [# z$ o                output += internal.Process( 2 )*vol[2];
" D  U) i& @/ f- Y/ v: c5 E                output += internal.Process( 3 )*vol[3];3 o: J" b( a6 x) j
                output += internal.Process( 4 )*vol[4];
9 p5 s. [, r  C% a+ {( U4 p: V' Z' r- c* r% n7 A/ |; C
                if( exsound_select & 0x01 ) {
7 }) J  Z& \1 u9 j- a& g7 L                        output += vrc6.Process( 0 )*vol[5];
. B# c* ^+ V6 Z; l, h  z* U                        output += vrc6.Process( 1 )*vol[6];2 o! K1 S4 L! n6 H0 w. g
                        output += vrc6.Process( 2 )*vol[7];
+ o, x1 `7 Q+ U3 o3 B0 W                }
) ~2 t( ~) \1 ?5 Q; Z( h5 k' l                if( exsound_select & 0x02 ) {
- Y( g8 X: T" e                        output += vrc7.Process( 0 )*vol[8];  g# g$ L: i( \' H" W5 ?1 K
                }/ m# Y/ o3 F7 y* Q+ d& y' z% P0 Z
                if( exsound_select & 0x04 ) {
+ a7 t/ y- v6 ^5 x' ^+ h% \                        output += fds.Process( 0 )*vol[9];% A+ b9 S+ b0 K
                }( |. E* p# K' J" @7 m# _
                if( exsound_select & 0x08 ) {4 r1 Q$ {( W& r/ N' i$ n
                        output += mmc5.Process( 0 )*vol[10];# m9 i  U* H4 g
                        output += mmc5.Process( 1 )*vol[11];: B) S$ L0 S' C4 O5 D  L
                        output += mmc5.Process( 2 )*vol[12];
# H5 [  u' r3 b( c, x! t                }9 V/ d5 ?/ d1 D
                if( exsound_select & 0x10 ) {
  x1 n, O2 c* m: |& L                        output += n106.Process( 0 )*vol[13];) Y! m/ S! A! n6 f& m
                        output += n106.Process( 1 )*vol[14];
- X$ @3 B' R7 _% |* l3 f                        output += n106.Process( 2 )*vol[15];
2 B. C+ m$ y$ t                        output += n106.Process( 3 )*vol[16];2 X8 j, Q! m% a  p) d0 J9 K
                        output += n106.Process( 4 )*vol[17];
% T& a" E/ S6 K2 H                        output += n106.Process( 5 )*vol[18];
& }! R/ A: n4 Q) x& ?                        output += n106.Process( 6 )*vol[19];
' Y5 H! p3 B; j                        output += n106.Process( 7 )*vol[20];
; u. @5 c0 g2 R0 ^                }2 }5 h! i7 r, c% u; h! |: S2 a+ v
                if( exsound_select & 0x20 ) {
: u: W8 L) r/ G                        fme7.Process( 3 );        // Envelope & Noise) L; K' J/ A1 \+ y. r
                        output += fme7.Process( 0 )*vol[21];
3 |& G- l. ?+ ?( j0 i                        output += fme7.Process( 1 )*vol[22];! R7 c( k. I. }3 D/ F1 X
                        output += fme7.Process( 2 )*vol[23];) c; Y& d9 _" N3 u
                }7 e$ s" f1 L/ ^
4 ^. s/ _3 W  w* _, h- x
                output >>= 8;
& J( D7 f7 ^% p1 E* b- a2 I6 W  p
: U" H7 _; C6 h& r( w                if( nFilterType == 1 ) {" G2 k1 E1 V2 Z! g% t" k
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple), T1 l; t; A  O! _+ k/ {) ~3 ^4 R
                        output = (lowpass_filter[0]+output)/2;0 ^/ |6 z' g" z0 r. q
                        lowpass_filter[0] = output;
1 S  ]7 U  l+ @/ v0 U                } else if( nFilterType == 2 ) {
- ]7 Q; w( B+ y$ c4 H& w                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
2 e% v* z5 v, C+ l                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;6 s5 t# o3 S+ ^8 n3 J
                        lowpass_filter[1] = lowpass_filter[0];5 I6 t/ e* B( U# {0 v1 _" p) C3 S
                        lowpass_filter[0] = output;
0 q& M/ s- l8 ]. F4 D' u+ c8 o                } else if( nFilterType == 3 ) {
9 Y+ ]7 Q2 N- b* G                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
% ?! X6 J( l9 P' c( |7 F  s                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;! q1 x3 `# M+ j! r8 i
                        lowpass_filter[2] = lowpass_filter[1];8 z; C( w& q% H1 O
                        lowpass_filter[1] = lowpass_filter[0];3 I# I! P% Z! S% d9 s, O. K1 Z6 e' A
                        lowpass_filter[0] = output;" e7 x2 I" }; W  E1 X6 Q
                } else if( nFilterType == 4 ) {  S& d; \/ T2 {# ]& h( S
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)1 ^+ I: _: O6 i' y
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;% b( G5 @2 e" U8 K' ^) r) [
                        lowpass_filter[1] = lowpass_filter[0];
# b/ n! l. R! r8 I* @" {                        lowpass_filter[0] = output;$ D) f) e) ?1 {& W
                }
8 k8 h( c* b, {7 X" @3 l
' `/ f# O; M5 ?3 l/ P: o. S6 n4 E#if        0/ x) c+ s2 o; U% G
                // DC惉暘偺僇僢僩
+ V7 g1 s! {+ R5 S  x8 x                {
5 N% f7 l5 Z: v' c) D1 U                static double ave = 0.0, max=0.0, min=0.0;8 h  b; R" b2 S( E
                double delta;" Z6 `  ]9 d$ }4 {7 f; j  k+ r0 |
                delta = (max-min)/32768.0;
2 S+ \) W1 W' F$ U                max -= delta;
' R6 Z' ^. Y- i: A                min += delta;: j. f0 c3 N" x# C7 b8 @
                if( output > max ) max = output;0 J, _! h4 @1 e2 m" L* J: q9 O
                if( output < min ) min = output;! v7 B- }9 m: V; d& |
                ave -= ave/1024.0;
9 d8 t  |& H0 ?+ A- v                ave += (max+min)/2048.0;7 K6 I5 Q& ]+ J
                output -= (INT)ave;
2 ^5 B1 m% @7 n/ j( b$ ^1 {5 J                }8 z) F/ `. P8 H: I2 U7 p/ w' f
#endif
) z# a" |  J  {9 L#if        19 F% R5 e5 I; ?1 p7 e& i6 ]3 {4 y9 l
                // DC惉暘偺僇僢僩(HPF TEST)
) A% \$ L5 [, l- g# `: M( k- A                {
5 Q* X( ?, a7 `) ~3 F//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
" _" @0 p; @- o                static        double        cutofftemp = (2.0*3.141592653579*40.0);
- u7 J, m  `2 J                double        cutoff = cutofftemp/(double)Config.sound.nRate;) Q7 C# S. f( W2 _
                static        double        tmp = 0.0;. I8 q. c8 a$ I9 F1 y: s
                double        in, out;
3 k* E- e& i& ^) f: G9 ]
% D% c! U0 s6 R9 M9 c+ O( a                in = (double)output;
6 R% k4 Q7 L/ t                out = (in - tmp);
- l8 W& j, m5 j+ {. _  _                tmp = tmp + cutoff * out;
$ y, _0 P1 y' o- j* w  W' G) c4 y: r4 d: ?' e) [
                output = (INT)out;% X  u4 H% y) Q7 x4 r8 |
                }
' T6 |4 e7 k' [& U% x1 y' R: d3 A0 L* }#endif) j& X2 W- K4 \5 M. k0 g$ G
#if        0
5 ~3 g$ M3 E9 t8 D                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)6 D; z5 _, _2 B: V2 S; @
                {& l! P( D: F9 b+ D3 f
                INT        diff = abs(output-last_data);
% b/ M1 d6 }5 t, S' E" M- Z                if( diff > 0x4000 ) {
3 J  y$ k8 m* }. K" |' F& ^                        output /= 4;, R* e" a5 {* C3 z# f
                } else ! K6 _1 j: v: C- R. V2 s& T# E+ O$ W
                if( diff > 0x3000 ) {
: B- `1 W' T9 C! l9 K7 r+ `                        output /= 3;  l# [( y9 L6 g- I" ]
                } else: B( d% d2 v7 L2 v  o
                if( diff > 0x2000 ) {
0 H/ Q# a* o/ W" O6 m                        output /= 2;
! k( D1 }" I% M2 G, y* }7 T                }. w* A# W4 G% S7 I5 Z
                last_data = output;; K: u# A1 Z, `8 ~' r
                }
" y! V) f' \8 X3 H; Y% f+ B#endif- c8 j0 }6 z' ~" H  N1 D2 E+ I
                // Limit
  n) {" v4 G; W  H0 C' Y                if( output > 0x7FFF ) {6 b' }% C+ W7 i: Y
                        output = 0x7FFF;! P' u; o, O: ?& Y6 b
                } else if( output < -0x8000 ) {
& U0 w! @" s2 ?1 y                        output = -0x8000;# _- j$ g$ }6 ^+ M: F' |$ c8 s, H
                }& ?5 s, u6 [9 k: l" g1 }
+ M8 I. s, X3 A- F  O! d: l
                if( nBits != 8 ) {; x3 R, w( G2 c( {2 d: G% p8 m
                        *(SHORT*)lpBuffer = (SHORT)output;$ t( _# R  H1 G0 a
                        lpBuffer += sizeof(SHORT);
! r7 x/ o* d# a                } else {+ ?2 T, I- B8 B8 `( }$ g1 t; @7 Y
                        *lpBuffer++ = (output>>8)^0x80;
" B8 r6 x* X3 }                }
) Z$ `8 I! [" g9 l( |7 w: g, I7 F( m' n! q( W
                if( nCcount < 0x0100 ). ~0 N* z9 m$ D* a+ b# ]" Z
                        pSoundBuf[nCcount++] = (SHORT)output;
( s5 v9 h! d2 H& d' O) b( r' T2 o$ e/ i/ |8 j# ^0 H
//                elapsedtime += cycle_rate;
' r( T/ S6 y( K% h! s9 m                elapsed_time += cycle_rate;
5 U/ `" N! I: m        }+ i8 i* d% c* ^6 Y- c3 n8 m
+ F3 a' f/ k2 ^  m4 K8 V- P
#if        1. \! R6 \$ [2 c
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {" V4 [5 ~4 v0 N8 L. c/ e
                elapsed_time = nes->cpu->GetTotalCycles();
1 M9 R. u; X' s" v' Y1 ^! S: c        }) {  V, X5 s6 X  `# Q
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
) q: I0 R" e( q0 O, Y+ M                elapsed_time = nes->cpu->GetTotalCycles();/ M/ J7 q9 c, f) `. S8 q- @/ `
        }
# v" t7 H: m/ U& J1 R7 q#else2 r+ g, Z7 v& s/ V+ W
        elapsed_time = nes->cpu->GetTotalCycles();
2 V8 n5 H+ q3 [& S8 l#endif
  r3 ~6 i, U. |+ ]* n+ M}
* F: H7 l% t* h$ J  p$ _/ K& c
$ }) X( ]/ C& y2 z/ D6 t// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
0 Q! F0 E! Q, ^; z1 d& w2 lINT        APU::GetChannelFrequency( INT no )/ b/ J$ T% g0 ?* k: S$ [
{
4 P- g3 q' H( t& [) U* z3 l        if( !m_bMute[0] ), ]: W# K9 V, S
                return        0;
) X$ T' l$ T  |8 `
9 @* b$ l0 \8 M, }        // Internal" D+ k! f: X+ t2 P7 y! x: `3 b* h
        if( no < 5 ) {* Q! F3 ^5 Y! o. ]5 t3 [/ L, p
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
$ u7 ^( w2 p$ ^- s8 Z5 }        }
7 ~% p4 b0 S& c2 ]        // VRC6
, P% f6 [& k. ]  h) K0 e/ `        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {+ o2 K( P2 S  \0 E
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
2 p% X. c& X( g, r. f        }
8 H: v3 n$ f4 V        // FDS, W  |! I3 x! c; q- r$ R; s3 _' N" N
        if( (exsound_select & 0x04) && no == 0x300 ) {
" Y3 F- I- g$ K& |8 P+ F0 l                return        m_bMute[6]?fds.GetFreq( 0 ):0;$ d- L: s- v+ L
        }, P0 C+ ^% j4 i$ I$ ?! c/ e
        // MMC52 L0 \4 v/ y7 |  m* n3 O2 F+ m
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {# f; w( M9 }; S3 ^$ p* |
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;1 b+ y" g1 Z+ e/ K
        }- y' n# H- h$ p1 z- ?+ M
        // N106- `+ o# k; n9 E2 |+ q# k- N- G
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {2 E4 U+ E; \  O) p
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
' Q6 _& K% C9 r, T1 [        }
6 ?5 b0 D+ h$ Q) V, S: J        // FME71 S6 H" t! a& g
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
2 i& u- K# u  ~! t                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;) Z6 P8 s0 e' X; C
        }
4 V. u6 Z5 o* a! n1 f6 |        // VRC7
1 h/ @; G) I* A; o+ L! J4 B        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {2 M7 Z" g$ L8 @) m7 Q0 z; L7 j
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
3 d% s8 l6 d0 }7 p3 \1 f8 s        }
% i/ i5 l/ c! V        return        0;, R+ a* k/ [: B4 b
}1 E# ]/ B" w, J# ?. U: c) a. p

7 |5 f  \. j9 `. }6 D3 Z* q// State Save/Load
7 r( z5 Y: D0 K2 U  v7 Kvoid        APU::SaveState( LPBYTE p )% g2 }4 q% `, I  o9 h+ j' c( T1 f. b
{
4 }6 h% }* J' g7 x) p4 u* P#ifdef        _DEBUG0 n/ |1 F2 w# |, ?5 ?! R# [$ O5 n
LPBYTE        pold = p;
; Y# X' ^' D* X) T* s1 S6 Y#endif
3 R! K6 B5 L3 G, v3 c
2 ~$ C9 {( n2 j1 z# J        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
/ t" U( Y/ \8 ?5 l: B        QueueFlush();' a1 g6 h9 O  `& O. t
1 @+ l# q1 ]* A/ ]2 ^
        internal.SaveState( p );
8 R" _8 O1 t1 ]! ^        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding" q7 n  D8 V" G& V

6 \+ N- s: C5 z! a" @7 W        // VRC6
1 w7 P7 A7 d0 q5 |6 i* x" W3 G1 m& r        if( exsound_select & 0x01 ) {
$ D- s; x" O' s3 }9 C5 O  o/ l                vrc6.SaveState( p );3 q; f. D  [, p/ A7 F) _: O
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding) ]4 P- g# M  l
        }
* Z5 E, N6 N! \! A        // VRC7 (not support)
) R9 ?, `7 L5 A; H8 O        if( exsound_select & 0x02 ) {" z* u; f! y- |) ~( t; ^  v
                vrc7.SaveState( p );
0 B7 t6 H8 G" P: L9 W                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
" k- I5 {8 B0 V$ N        }
+ ~' p9 V0 W/ n: V$ N( l        // FDS' D! [7 G6 R# z+ Q- Q$ _& ]5 \$ [
        if( exsound_select & 0x04 ) {. s" g2 n3 p1 s1 D+ R
                fds.SaveState( p );
4 E* ~1 E: T* y& f# k- ~! S- V+ s                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding4 B+ ^6 _$ h3 u& E& A7 S2 F! R
        }, W+ r& r, E: F# K& a
        // MMC5
- C) U( E4 D9 e# F' j        if( exsound_select & 0x08 ) {0 R! F1 }0 U7 p
                mmc5.SaveState( p );& I* a$ B- z/ ^. m4 v2 _3 K" i& R: J
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding# Q( H6 w  K' \$ g& }
        }
! C" w  u9 E* K3 S3 z8 D+ \9 v' B        // N106
3 j/ h  L1 \$ }' n3 n2 a- }3 h        if( exsound_select & 0x10 ) {  C0 z1 W3 }3 w$ S" M& r. j$ {
                n106.SaveState( p );
( p' s. d& p, |& ?/ E- V8 u6 l                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding9 d6 e' X4 l  h7 a: J% x9 N, K
        }
- z7 m4 ?1 J1 F6 [0 r        // FME7  V3 L* j# V2 ~/ i. Z# n4 l" {
        if( exsound_select & 0x20 ) {
9 m9 K' n  z, V5 G, J$ U2 E- o% U                fme7.SaveState( p );; t3 k$ }/ z; @
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
& J1 i& z3 O" d0 f* W0 K        }
) U/ {+ G9 r1 O: A3 F7 L+ a; p7 M1 Z7 r: o0 j6 Q* F
#ifdef        _DEBUG6 b& N9 {! s' g/ u9 N
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
+ b9 I" N3 U, S5 \- }$ l2 `0 K#endif; Q- _4 R+ A) i; T$ {; b( D
}+ f, k- |5 A  ~& l5 Y8 g
  w) ^7 |; J2 m* ^) n
void        APU::LoadState( LPBYTE p )
4 E; a8 Q* A8 \- a4 O) o- P{% R: p5 \& A: {! s( {  n2 C! ~6 a1 y9 Q
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡% d) Y" m. X0 L7 L5 }3 h/ P
        QueueClear();
6 P6 Y/ ^% i& y# ~& ^8 T% R; [! r2 g" Z. E* n7 J+ {' R9 P# F
        internal.LoadState( p );
) N) c5 a# A* S: n        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
' |/ X  A8 g6 o/ X# H
' {" r: J8 @& t$ O        // VRC6, @: a( @( a! ~+ w" t# t
        if( exsound_select & 0x01 ) {
; k. }' Z7 l+ q- u! x                vrc6.LoadState( p );
5 L% Y1 G5 V' d# ?9 q$ C                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
/ Y7 J% T/ v6 C0 F$ y+ X+ D        }
" c7 E; M/ G% h$ v3 `        // VRC7 (not support)* Q# x9 Y0 g4 d9 `/ p+ _9 C
        if( exsound_select & 0x02 ) {6 ]1 K0 c( n( X
                vrc7.LoadState( p );3 ]9 b' q  a  i; @$ i
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
. R. R, p4 h9 n: \6 Z% ^1 D* Q        }7 B  J$ |+ i" Y" w+ e% ]# X8 g1 F
        // FDS5 S8 g: Y) `0 Z
        if( exsound_select & 0x04 ) {
7 H8 g' m& v4 |3 C8 D' L- ~                fds.LoadState( p );: p$ Q" L3 }% Y& U6 g( J* q6 h& ]* r
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding# u( N+ W. {2 `8 U3 w7 O
        }/ F  T  J8 Z2 a" C
        // MMC5
* y, t2 G% [. |8 P7 T        if( exsound_select & 0x08 ) {
5 v- [5 [2 v2 E/ U: c. N; h+ ]                mmc5.LoadState( p );% l, ^7 C  F) T5 K5 m! H8 O; a
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding! h" ]: S, R+ ^+ ?  L3 Q8 K4 ^
        }
1 K7 U& {' X& B9 S        // N106
% c6 T$ i! B- T0 j% _. g        if( exsound_select & 0x10 ) {$ ^. ^* K* d# j- y: f  g: V; A* ~* V
                n106.LoadState( p );9 c# i/ ~/ `: [7 i. N
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
2 N8 v0 I+ P3 ^4 J8 K- t        }
5 G& @6 f# i6 e+ v% T1 D        // FME7! [( t- B+ A, {/ z3 I( n1 j
        if( exsound_select & 0x20 ) {2 f/ t9 P2 Y" ^4 V
                fme7.LoadState( p );
5 E" t! G1 M, m3 g% k/ R                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding3 ^  M7 B+ h! \$ z6 A8 U
        }
: _! w( l8 c% s5 X$ U}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
8 r/ t5 O( G! ~2 n可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
3 [+ o* f2 |8 C& y$ y6 g$ _1 p感激不尽~~
$ q$ L) y& c. k- h
恩 我對模擬器不是很有研究,
6 L5 |! r$ m# F雖然要了解源碼內容,可能不是很困難,
4 f" z5 ]# e8 v- g+ O不過還是要花時間,個人目前蠻忙碌的。
: C7 r# [8 I& \
: i' x/ E& b* z, N" O3 U2 z給你一個朋友的MSN,你可以跟他討論看看," z+ h& S( }1 a* G# K
他本身是程式設計師,也對FC模擬器很有興趣。
! `; G1 d0 T" Y3 B6 _
: M% c3 a2 u  }* u5 i0 g  {MSN我就PM到你的信箱了。
: C9 [8 u( n' @& x& {" v, M
/ H5 U( G/ w: l希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
. m; V) S. a: x; M8 d/ J" F1 y呵…… 谢过团长大人~~
/ C2 f* w4 E( e: v( n

, ~8 ?5 z9 K/ P$ R哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
9 t  l0 y( Z6 Y8 h团长的朋友都是神,那团长就是神的boss。

0 c" z0 ]( R3 K+ R( F% z# j哈 不敢當,我只是個平凡人,
9 j& R9 o; S. B5 X7 E! i7 ^- ?要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙7 Z8 x4 ?, ~2 \9 Z
ZYH
  ^' |/ w% R- }9 BQQ:414734306$ H8 n2 i& `/ ^; \, r
Mail:zyh-01@126.com
- D3 m6 y/ I' x' V7 M7 @2 \1 H' p6 [
1 h0 Y" T/ J/ w! l" h1 a# [. D, O) `他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 - a: _+ a8 W, ~+ `9 i
再次对团长大人和悠悠哥的无私帮助表示感谢~~

. `: N7 r( E, z  u不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-9-17 08:25 , Processed in 1.083984 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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