EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?
- q- f+ z( H% g. I( i2 y1 O  A' RPS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。9 }% ~0 W6 f  ~/ Q6 c
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~+ o$ e3 w; Y5 F3 {" r
这里有相应的模拟器源码,就当送给大侠了~~  m7 j1 ]  Z8 ?- I4 Q
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
) J. k( p( y* ~6 `能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
( S- H6 j0 g8 v3 L3 b& Q楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
7 u- t3 E7 Z7 I. D( f这里有相应的模拟器源码,就当送给大侠 ...

! t! G2 t  G5 J' j$ `聲音部分(Audoi Process Unit = APU):4 ~# p8 K2 `6 ^8 c
.\NES\APU.cpp- N3 A& v* z- D& X! ?
.\NES\APU.h
" B9 i$ Z/ |8 z. X, E& i
  b: G  u* v( k5 ?3 P( b; X, Z* _% q2 s! L: S
影像處理部份(Picture Processing Unit = PPU):/ k9 ]) Y2 l  f
.\NES\PPU.cpp
& q" k% ]8 S( z$ g6 s0 e.\NES\PPU.h% O: ]3 ~3 S. Q4 T+ q( D9 B

; V8 @7 i. z$ j2 r如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
) R# X' `2 B, D  D# Q(由于很多专用术语和算法机理都不明白,所以看不大懂……)
0 X/ P# H0 _) \1 O$ p4 Y' E- Z& z//////////////////////////////////////////////////////////////////////////6 d4 E- v6 _0 H& I
//                                                                      //
  r% I0 e" [  U' s//      NES APU core                                                    /// Q; a7 e7 R) I/ B
//                                                           Norix      //
9 N# x, e3 e- ?5 `6 V  }$ y//                                               written     2002/06/27 /// ~3 I& C! }7 i+ q: |
//                                               last modify ----/--/-- //
' e# l/ S8 }% j! |5 C//////////////////////////////////////////////////////////////////////////% _( T! M- j2 w& M2 W3 O
#include "DebugOut.h"- W9 x6 X& e0 ^! X0 ?
#include "App.h"2 R6 }4 h0 K# `
#include "Config.h"
; U* {7 [' K, c7 ^
( {* E+ d8 [* q$ C. n4 b9 l#include "nes.h": L; D3 R- N) O& M% u: ]
#include "mmu.h"1 b7 y. d0 j& q4 D3 [  e  n
#include "cpu.h"
! h6 W. _6 C, a% w1 ?7 S/ H& Q. ^: K& G#include "ppu.h"
- G7 j# m6 c5 O#include "rom.h"
+ u, C/ c" r  a* R) X" n& I5 r8 s#include "apu.h"5 v$ n" D1 P9 L# E9 I
9 A6 t$ H1 b: R" L+ ]
// Volume adjust
! s9 s* X* H9 e- |  I// Internal sounds
) X( d% S) r# Z0 Q" Y% ~#define        RECTANGLE_VOL        (0x0F0), X% J- ^, p. s$ c2 I
#define        TRIANGLE_VOL        (0x130)
; a1 L* d% {0 r  R" F( d- }4 N#define        NOISE_VOL        (0x0C0)
6 S2 d. y7 H1 d! O+ \: K/ o#define        DPCM_VOL        (0x0F0)# d* u" R3 @% y' p
// Extra sounds
! K: S' {3 O& h0 [" J0 D#define        VRC6_VOL        (0x0F0)  ]7 c7 l  W2 Y- ^
#define        VRC7_VOL        (0x130): F7 N# z5 Q! z! Y, H; Q
#define        FDS_VOL                (0x0F0)9 j( W/ P' v+ g/ a2 Y* m
#define        MMC5_VOL        (0x0F0). O+ W: Z, j8 j0 x# }1 S
#define        N106_VOL        (0x088)
: Q4 V+ L. J, t$ O* Z: c8 |1 T#define        FME7_VOL        (0x130)
% f* M. i6 F) I' T2 W5 M5 j
. K9 G; m+ u2 ~( SAPU::APU( NES* parent )) ^0 y+ g; a8 ^" x, m( `
{
) Z- W; L8 m- ^0 A9 x        exsound_select = 0;1 t0 w- b! A5 N0 T5 ~. ~' i8 x( H

1 [6 w1 x/ J& h( s        nes = parent;
; Y, Q# p* i& E* F; `- Y        internal.SetParent( parent );
# w! _: u" f# ]# i! @+ v% Z* E' K/ k- u2 D
        last_data = last_diff = 0;
+ n% M# i$ }8 H! w% b0 V! W1 ?
6 D  s3 Q& A" b# f  Y  E        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
% p6 t& W5 \9 w5 w  F" K' s: @
; g; F; c1 b) {8 H/ N6 R& W        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
% ]$ n% {* L$ B: O, `; a* C        ZEROMEMORY( &queue, sizeof(queue) );7 x  s) i6 a# B
        ZEROMEMORY( &exqueue, sizeof(exqueue) );8 c0 s. Z4 u- Q4 ^% F! n

* e  G' R1 M, d5 [        for( INT i = 0; i < 16; i++ ) {) s+ y- v1 G6 P1 x4 ^) ]  u$ A
                m_bMute = TRUE;
7 c; `% w5 u2 @8 N$ c        }
# z3 A7 f( ~! V}
1 v1 e' R* Y* \+ Z' O
" G/ |0 ?3 X* u1 H& ^* ?APU::~APU()
/ K' u+ f7 U0 n2 {, u{
9 B# c& y- [: d) o+ F. k}
: G2 Y! |( L! K2 v7 p: t( d- e: ~/ c& i7 o# \
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
4 \9 Z6 M7 f* v( A' O) o! ?! {{& Z. {. C1 V4 J3 |0 `, E) K8 W
        queue.data[queue.wrptr].time = writetime;
0 }; F' u/ ?; r        queue.data[queue.wrptr].addr = addr;* n. u3 ~) [$ _/ U7 a9 d3 w+ Z/ J
        queue.data[queue.wrptr].data = data;
( @1 c' t% _9 L        queue.wrptr++;
* W4 v9 t4 c+ r- n, t# a        queue.wrptr&=QUEUE_LENGTH-1;
/ g. I' ?2 R8 t! W$ G        if( queue.wrptr == queue.rdptr ) {. K, b- Q# z0 ~9 |; L
                DEBUGOUT( "queue overflow.\n" );; ]. ~+ \) W6 K
        }
1 N8 n% B, a6 n4 N}  P* `+ }- _: B6 K

" U0 `' ?- ]8 c- n& Z- B% V: o* [; h2 NBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )- B& f# f9 L+ g$ E! z8 \9 f2 e
{; D# M: N: ]5 Z6 ~0 G: ~
        if( queue.wrptr == queue.rdptr ) {& F" ~9 A8 p$ P6 Z" |6 d( t
                return        FALSE;
/ Z# C! C3 M& Y, F6 r# g3 o: v# T        }
7 A/ l% j) W7 h$ v4 \        if( queue.data[queue.rdptr].time <= writetime ) {
, @; J  m6 n* T; Q3 q- @                ret = queue.data[queue.rdptr];
( M  y" v/ Z0 `. A! v                queue.rdptr++;" C$ j: _& u$ L: D+ G
                queue.rdptr&=QUEUE_LENGTH-1;4 k: q' e+ ^1 h
                return        TRUE;
/ p' m. X  ?+ _7 q% T9 W! A        }
1 @/ j+ k7 S" W( ^$ [0 S        return        FALSE;
+ Y1 A$ w! f; Y6 i$ f* ^5 s* ]}
( F; E; V, M/ K$ [- p0 D
! |- S- F" k; @2 Jvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
; L2 v& R# n! n* H8 ]# l{: G! q' [9 p( _) d1 }& T
        exqueue.data[exqueue.wrptr].time = writetime;3 v" n# G3 i. M- O
        exqueue.data[exqueue.wrptr].addr = addr;
1 E# n! [1 ~0 h        exqueue.data[exqueue.wrptr].data = data;& Z3 X' M- V2 x0 C5 {9 E. R- L
        exqueue.wrptr++;
" D+ Q* p$ V0 Q* q2 R, U        exqueue.wrptr&=QUEUE_LENGTH-1;
" X7 r9 G- C! U* L* Q# H8 A- \        if( exqueue.wrptr == exqueue.rdptr ) {( J! I3 p5 g* x
                DEBUGOUT( "exqueue overflow.\n" );
4 N& M! `9 t- x* ~! w        }5 v( q# c7 z6 o1 s
}7 R4 l- }! ]( Q; Y3 Y8 R

1 k& I, ~  t/ TBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
; j/ @4 |3 t$ a9 ^$ z3 F* X{0 _- q# z! r6 }
        if( exqueue.wrptr == exqueue.rdptr ) {% ]' r1 U  \, `: k' F* }( s
                return        FALSE;1 {7 ^2 y3 v) q. E! Y6 _
        }
4 w& M1 m7 E5 L# x        if( exqueue.data[exqueue.rdptr].time <= writetime ) {/ L, R5 y' p  {6 q# U# x
                ret = exqueue.data[exqueue.rdptr];+ m) U+ K/ ~: G/ |, g* B
                exqueue.rdptr++;
- @5 [# _" G+ @1 c' h6 v, E                exqueue.rdptr&=QUEUE_LENGTH-1;% {+ ^2 u4 J# y  n- F6 t
                return        TRUE;! J0 m9 _$ E& A: T% a3 b
        }! A! g8 M* I# c
        return        FALSE;
7 c1 _: k- V8 t' x# C  e}
- E5 Q  u. w5 ~: R' v
' O* k' K; E0 v; h/ u0 ^0 Qvoid        APU::QueueClear()
( M2 {8 _2 a% Z: M# B' g( X{4 T4 C' U- d6 l3 g# l
        ZEROMEMORY( &queue, sizeof(queue) );( B+ N% f$ P7 Q: z7 Z$ _
        ZEROMEMORY( &exqueue, sizeof(exqueue) );0 J, ?4 b' t2 |; [
}
- c6 a& R; c! r6 G
" {+ M. ^/ l) I# r# Gvoid        APU::QueueFlush()' ]8 a# u1 n* i/ I4 g& R- p
{
1 e, v  _8 Y3 I1 ~+ ]. o        while( queue.wrptr != queue.rdptr ) {. c1 V, k( o6 I( b' c/ G/ [
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
6 y6 f* ]7 {& I/ a4 ?5 P                queue.rdptr++;
/ c1 m. r7 X8 T* D) e. P. Z                queue.rdptr&=QUEUE_LENGTH-1;( x+ a4 f# e7 @3 F3 k
        }3 P2 n# G3 p3 Q* D9 v" g
( r" u$ m$ f) O- {
        while( exqueue.wrptr != exqueue.rdptr ) {
6 v, O6 Q/ U1 K1 m: h% i                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );- N$ p  ^$ J7 U6 S" E" H
                exqueue.rdptr++;# }' P6 ~  B4 y" o5 ?) N
                exqueue.rdptr&=QUEUE_LENGTH-1;. |1 W% R: \& ?, l- t% l1 w, e: q
        }
' x) F2 ~* ]+ Y+ U. i+ A) {}
2 Z" R- f# w' K, [( n0 U" Q: W) ?0 K1 t. C+ T6 D1 |4 i# r6 ?9 J
void        APU::SoundSetup()! d9 X6 W. A5 \
{
7 k% b2 T1 W; e9 K6 a        FLOAT        fClock = nes->nescfg->CpuClock;
( E# A) G6 U: n1 A) s" f' G4 _# T        INT        nRate = (INT)Config.sound.nRate;) Y. K0 ?% X+ G- c1 ~
        internal.Setup( fClock, nRate );
/ `% }# Q+ d/ T  a- `        vrc6.Setup( fClock, nRate );5 M) m/ T! B7 c- y9 T4 t. M# n' E
        vrc7.Setup( fClock, nRate );5 H3 e( O7 e) S" j2 m' Q
        mmc5.Setup( fClock, nRate );3 I3 F" H# z$ I# ~: D5 H: [
        fds.Setup ( fClock, nRate );
, }6 ~/ {! p; L) }        n106.Setup( fClock, nRate );; C0 U+ Q8 m. V) l
        fme7.Setup( fClock, nRate );
; ]5 \$ {! s# @2 U- F' s}1 I$ b# R- y$ v

3 o0 h8 f  B5 U+ Q! o+ zvoid        APU::Reset()
7 o3 P9 B4 L9 x3 y8 U' A9 y5 u8 B, b{6 f, w; O: d, Y- `, x# @9 R5 B
        ZEROMEMORY( &queue, sizeof(queue) );  g6 ~8 u5 ^' m7 V8 H, |6 W2 l% Y
        ZEROMEMORY( &exqueue, sizeof(exqueue) );, f  d% [& T3 Z/ [

1 L2 |5 k3 g5 C4 k! F        elapsed_time = 0;
5 H4 z0 K/ g5 W
/ `' \6 _0 K. U% F* Y: P        FLOAT        fClock = nes->nescfg->CpuClock;) j) s+ H) Y+ }/ d0 N+ P! y
        INT        nRate = (INT)Config.sound.nRate;( U' t2 v) F: U
        internal.Reset( fClock, nRate );& L6 m" W. U1 i, z; u8 ]
        vrc6.Reset( fClock, nRate );
/ x( p. y" a! j, M. Y& g' B        vrc7.Reset( fClock, nRate );7 v+ C5 r. s! c/ `8 C# a
        mmc5.Reset( fClock, nRate );
- i; L* D0 \2 ^6 C0 n9 k. D8 i        fds.Reset ( fClock, nRate );% _" Z! r3 t5 y
        n106.Reset( fClock, nRate );; [9 I$ Q& s/ c0 ~; E2 o
        fme7.Reset( fClock, nRate );7 a# H5 _" Q- d6 B5 I" o
8 d' r8 `# X0 Y! k4 N# n3 E
        SoundSetup();2 m" K$ a) ]  |
}3 H" E7 ?5 f- I& s2 L

1 V5 Q; N- G! {% q' y( k: Zvoid        APU::SelectExSound( BYTE data )2 Z( A& h, L0 e) T5 ~: ]
{
, ?" F4 e3 F: T) B9 z8 K        exsound_select = data;; O: Z/ t# y) F+ |; D
}
) r1 h9 ?+ J. w( c! p' Q% P' |4 c3 L& p# f! Z
BYTE        APU::Read( WORD addr )1 d) ~$ e6 ]3 W, H5 R7 ~+ s2 y' X% T# ?
{
/ A$ o# c4 o+ f2 b2 I        return        internal.SyncRead( addr );7 u% T" s+ P& K& o5 d3 t) @
}
0 R5 e( B) U! Z3 y+ ]
: p/ m7 d) z  svoid        APU::Write( WORD addr, BYTE data )
# O' }: a! c- K# p! J# p9 ~: U3 E{
* E# B, b/ S: y0 g7 q        // $4018偼VirtuaNES屌桳億乕僩
, X9 E( q; C( [2 ]5 q        if( addr >= 0x4000 && addr <= 0x401F ) {
  Z8 d4 o& C2 V. a) j                internal.SyncWrite( addr, data );  S  Y6 t6 k( y+ _+ Z
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );, u' D, V. M7 V, j, Q. P. e  k5 x
        }
) O1 h" E5 C/ H! p9 u! }}
4 B5 W0 E3 G. Y) [' ^8 I' J$ J8 U1 d  F* W6 j
BYTE        APU::ExRead( WORD addr )
& E# h( k9 a# Q$ [( `. v! D{
& u( s8 {, M/ f+ E6 }) ~4 n0 I/ A8 i+ uBYTE        data = 0;
, w* Q0 z) Q9 P) U8 T7 j2 C1 B
6 d( j% X$ b' E+ Z7 K% m" w: d        if( exsound_select & 0x10 ) {/ O9 f! a" M! C! w' S6 e- G. C
                if( addr == 0x4800 ) {
; V# L: ]5 M6 N. t                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );2 g! f" k6 d& P2 c
                }
9 [6 M' t, d* @        }: `1 E' F# E+ \) u7 s+ _2 T
        if( exsound_select & 0x04 ) {( r" M" e$ X# D* ^7 _/ j2 y
                if( addr >= 0x4040 && addr < 0x4100 ) {
, Q! p$ v8 m# h# v4 h- K7 S  R                        data = fds.SyncRead( addr );2 y/ B+ l: `) u+ }; Y( D3 h' B
                }8 f' r: U% b2 F! {" f
        }! d4 q  w. {0 @. `
        if( exsound_select & 0x08 ) {- J  b% X8 h2 T* P' Y7 A
                if( addr >= 0x5000 && addr <= 0x5015 ) {
/ U# n* w# Q* X# V3 s) q  O1 f1 V                        data = mmc5.SyncRead( addr );
( c) g2 j! Z$ P7 G                }- A. f' U8 S3 C5 M6 M' l
        }/ D5 A6 a% Y( O7 Y5 M8 w% j: }0 |
3 M; m% i: Q- ~" K  c4 |+ s2 c+ ~
        return        data;% I$ Z3 M* M/ \; w1 [
}
1 r  ?$ \7 M7 S2 u7 P1 J/ L# }) c9 g" j& k. }
void        APU::ExWrite( WORD addr, BYTE data )
: |- W. a  Z$ b3 H; s1 G! |3 ~{
' ]' J4 w2 {0 W# b        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );3 s% P" I$ @- F1 {  @7 s0 k
/ j. N; n; n) v1 ]: w6 D8 j
        if( exsound_select & 0x04 ) {
6 V  {8 R$ u. }, b/ Y# \                if( addr >= 0x4040 && addr < 0x4100 ) {
" j: e: h3 ^  t6 Z2 p; u                        fds.SyncWrite( addr, data );! r/ i8 q# Q! ]! M( x1 B% k8 S
                }; z+ {6 N) V4 [% O( ^. ]3 ]
        }
% h/ E  t  Z. M, n& J% \) {5 S1 Q$ ?& R4 Q- |" D. H0 l
        if( exsound_select & 0x08 ) {4 Y2 K5 g. z+ A8 m' T. P
                if( addr >= 0x5000 && addr <= 0x5015 ) {
" d3 S- j, s% m; V                        mmc5.SyncWrite( addr, data );
3 O- s2 ?' h- ^                }
0 `" ]  Y2 U5 S: ]0 Z        }' M5 N  j* l" q5 I/ Y# G0 |
}- X" d- X7 Q3 w7 H0 h. [% b( s

# D" ~- s0 s: Q* n/ y7 `void        APU::Sync()6 p4 k$ x1 |, ]$ p- M# A
{( c3 H. }. h' n# q
}
$ _9 Y5 [+ s0 x! k  y8 N
/ b. a4 d/ g  x# Y* nvoid        APU::SyncDPCM( INT cycles )
" s( p; e: y% T4 h{
1 e' `4 {" y' _        internal.Sync( cycles );
) \/ _0 G' v  C  H- z/ B; r1 o$ f. ~* O/ i, I
        if( exsound_select & 0x04 ) {
+ ]7 ~7 V. W* `2 Y! O2 @' w                fds.Sync( cycles );6 `3 `# [/ h" V! T4 n
        }
- a6 |6 u& \) {        if( exsound_select & 0x08 ) {
$ s5 p) e3 H1 u1 p                mmc5.Sync( cycles );' `! h) L" Y& L8 j2 F
        }
& w+ p) Q; Z' Q# Y0 Y6 v- x}2 P' ^7 h9 ?5 H7 r/ p
6 T( |8 A& A# Y/ y( e
void        APU::WriteProcess( WORD addr, BYTE data )
# I8 h5 g# a% v# }  y{6 h/ U0 l: \8 [* O
        // $4018偼VirtuaNES屌桳億乕僩
6 ]# H4 ?7 b& W- _        if( addr >= 0x4000 && addr <= 0x401F ) {3 w* V! N! i; b- m. |# W2 w
                internal.Write( addr, data );
9 ?- l/ ^. W. e( K        }
& ~, |7 f2 i# a4 m6 ~$ }' o& Q}
! k* F5 i: P4 A5 X% o+ Q0 F0 t. w4 u! ]
void        APU::WriteExProcess( WORD addr, BYTE data ), t; ~2 |8 a! Q1 C# X
{. j5 W3 @( A! z7 v
        if( exsound_select & 0x01 ) {9 S) N& ?9 [+ N
                vrc6.Write( addr, data );- [8 {4 G1 t' q/ u, }, ]
        }
8 J# b' Y* a9 y        if( exsound_select & 0x02 ) {" t, o* a4 e9 S/ c1 v
                vrc7.Write( addr, data );; A( k* Q1 X  K9 v! X4 y8 G% z3 ^
        }
7 f# x) L2 T1 e5 C+ p9 r) u3 x  D; g        if( exsound_select & 0x04 ) {
  w. S! X; ~+ t1 \& S                fds.Write( addr, data );5 f( y/ z& W. G, g* m) s; u& y
        }
/ L7 a& u" X) n2 E3 I        if( exsound_select & 0x08 ) {
; i) d6 r5 S$ h5 v' A                mmc5.Write( addr, data );# l; M& d: U: u3 s. U
        }8 U4 S- m- s' P7 O0 w8 z
        if( exsound_select & 0x10 ) {* l5 S0 U& Y4 g; K' q- `8 D
                if( addr == 0x0000 ) {
9 x) _2 b6 n+ x/ b' Q5 d! K, B                        BYTE        dummy = n106.Read( addr );( p* o, ^, s6 i4 k$ @
                } else {
9 ~: g0 p- k0 x$ }1 Z1 a                        n106.Write( addr, data );
9 i# E) o" T; {  Y% `1 A2 B                }5 P0 \, q& t3 c+ {! x$ Q0 q
        }
2 O* v! R1 I+ k+ v: m        if( exsound_select & 0x20 ) {
5 L3 M  U3 u3 a; W                fme7.Write( addr, data );
9 d/ r8 v9 Q8 v  |        }
: x; T7 \/ V2 e( e( e}5 `  ~2 }! B- d; r
/ Z0 P+ h5 j/ i  z7 i
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )1 Z4 r" v3 y1 V8 I- u9 Z
{9 ~, ?) y. `' [
INT        nBits = Config.sound.nBits;$ r7 u! P# l/ Z0 [9 S5 j
DWORD        dwLength = dwSize / (nBits/8);
. a# l" m5 F) FINT        output;  D1 N! q- U, R0 S& o3 @
QUEUEDATA q;. ^1 S2 Z3 F' G3 h: F* o; B
DWORD        writetime;4 i7 Y8 |. N; k! r! l% ~7 V4 a

. Z! v8 m# r, w  V4 e4 ]LPSHORT        pSoundBuf = m_SoundBuffer;$ B0 k9 Y$ M2 r' v5 C( I
INT        nCcount = 0;
. Z3 L8 i2 x- S$ X: m' l; Q
) \9 R8 c* Z1 }INT        nFilterType = Config.sound.nFilterType;
; Y' s! M2 G* G- b- g7 s! Z3 [
        if( !Config.sound.bEnable ) {! ~8 k$ F" G1 {  ~0 W5 q: e) P
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
( C0 p$ Z4 Y" q9 ^* n                return;
9 e% V: X+ }2 Z0 ?        }
8 B1 E: X& Z' S7 r$ J
* H; X9 V0 `* E& m9 e7 Y        // Volume setup& u- M6 U9 P, @  s) y
        //  0:Master* ]. j1 t! ?& X" p
        //  1:Rectangle 1
( d' y8 |/ Y- T3 {, H4 _        //  2:Rectangle 2# D7 b/ v9 y9 W& y
        //  3:Triangle6 T; j( C7 b% a" s1 U5 l
        //  4:Noise( p) u4 i: q7 P# n+ ?# A4 N1 v( H
        //  5:DPCM
7 ^) F3 W, H! ]        //  6:VRC6% n+ L7 {3 T; j$ w
        //  7:VRC7
* t! D9 x& l/ l. W7 P; \        //  8:FDS
4 E4 Q5 V# f" C0 \1 e4 R6 o2 u        //  9:MMC5  @$ c% R( I0 X, B6 P
        // 10:N106
* M/ S! f0 a# [8 U1 u+ U        // 11:FME7
: T5 ]2 p) S" [        INT        vol[24];
. Y: O; i1 q. G! v- g- Y, J4 n; o        BOOL*        bMute = m_bMute;' r) e. _3 C: |+ O! u+ H7 v. \
        SHORT*        nVolume = Config.sound.nVolume;% N) [; ^4 t  G1 G7 ^

% s! {' H  m! x$ R1 \& L  D0 `- Y: U2 p        INT        nMasterVolume = bMute[0]?nVolume[0]:0;; p' o1 A* R  B. Y: Y
9 o' b# p& }: V
        // Internal
9 Z: w. a, K2 b) Q        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;1 Y) {- A/ U- x# N9 f" t
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
7 a. d- }9 N2 P1 ~6 Z  F        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;1 s' ]9 o5 e  n" L! y1 P6 h
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;: }* o! \6 P- J6 c! \4 Q9 Q
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
% k1 W+ I# X. ?3 }
& `  [* Q! ^5 H' [        // VRC6
) Z* F0 S# Z, Q7 H4 H( W        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
0 Q) q6 T7 M, b7 P5 k* j; `1 R2 s        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;6 |0 g4 a2 Y- e3 o7 v: J3 U+ e9 @
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
6 O2 _& x+ i& h- K4 t2 e$ p) L7 y; e+ {& b- I7 d# ]
        // VRC7
3 g: O1 Z5 i# ?9 K" N9 I2 s        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
: q- a: _# U  P. o9 v" ?6 L- ?) k* }; `$ |5 K. }' j
        // FDS
0 s- h( `2 n/ |! |: {' N; j        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
( ?+ t* C3 i  U5 _" i9 f7 I7 y. G' Q, X8 d: [% s
        // MMC5
; H, M1 p! a7 \! Z, d8 R        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
, J. ]# U- g! C5 i0 J; b1 a        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;0 A" m4 m% L# C) G) x& S8 v
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
- d; }6 [$ K: S- R6 H4 f; J2 R3 g5 n& y2 _
        // N1068 X/ k$ f, [. z: k2 H' M. n
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
1 b  K2 `' ^! Y! x        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;) [) O8 i$ W% ~# s6 g' t. C; _/ `
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;4 X( L  y! l, l
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. T9 O4 n3 X$ V- E- j! a        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
" P# c, J* w( s  p        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: e  Y! Q7 R& ]5 O3 Q% G( q        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
) W4 N* C! Q  Y        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 y# t* {& o+ q1 C3 P0 i/ J8 e6 {
& Q) m, T5 P* L/ u- o8 z        // FME7- M. o9 q5 z- Z4 i" |3 [6 ]
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
: @- F0 x, q5 V& @7 F$ Y! r        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;/ Q* Q% T4 K( Z+ ]
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
$ `* f# q! }/ A4 J8 Y: L% d8 a
0 u, G; F+ u( f, ~% v; E) H0 W, v//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
0 l  N" G8 ?6 @        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
' {; ^: B% P* x* |6 a
% D5 K, ~4 P4 S+ c8 D6 q        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
( j) M: L3 b4 b' z9 i6 A% P! v. X$ I        if( elapsed_time > nes->cpu->GetTotalCycles() ) {' t4 i7 }& O) R3 ^; z6 r
                QueueFlush();% ]5 @* H/ A& \/ V" W& O* j( Q7 F
        }% K8 I" y2 ]2 S& c- y0 z
0 R2 a0 k3 A  f: Z7 l* \( C
        while( dwLength-- ) {  G; M0 j( c4 n* t( {/ \% f
                writetime = (DWORD)elapsed_time;6 M& l+ A. K! P7 _: G1 T
/ q' l* u$ d1 }# x) }9 h. w, R2 t+ p
                while( GetQueue( writetime, q ) ) {3 p& K% M8 U" S4 W1 w& ^+ D
                        WriteProcess( q.addr, q.data );
( l) ]" n) b  l% b  y0 Q                }: Y9 s  W; L. N/ b8 {; c! g

8 e. x3 E. q# E6 ~6 C+ C2 T                while( GetExQueue( writetime, q ) ) {
  [9 M  Z( K: O2 J9 F3 Q% u  L                        WriteExProcess( q.addr, q.data );
2 u0 X6 O) A; ~1 N( K9 _2 W                }8 k7 J6 l' i+ |# T) m8 r1 [' d+ V

8 i5 t7 F% T8 m# l3 z2 r: h# x                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME72 _; j  e# ]- P. H4 y7 d' z
                output = 0;
( n9 H8 ]" I7 G& Q4 q                output += internal.Process( 0 )*vol[0];4 T4 M. v/ f: U2 b" V8 b) }
                output += internal.Process( 1 )*vol[1];
% _( z3 R" L7 u- F, A                output += internal.Process( 2 )*vol[2];3 v4 ~. |% f# @; r* ?+ Q/ c
                output += internal.Process( 3 )*vol[3];& T1 Y6 N# d- {" U0 y3 v
                output += internal.Process( 4 )*vol[4];
# t7 Y! V; P" L- B* k8 m# p4 J: u4 t
& H0 @5 W6 H6 M0 d                if( exsound_select & 0x01 ) {9 i  ^. o+ ?, j
                        output += vrc6.Process( 0 )*vol[5];
# }: S4 x6 }' m                        output += vrc6.Process( 1 )*vol[6];4 j4 j" u9 S8 ]/ z2 u1 a7 j/ s/ E
                        output += vrc6.Process( 2 )*vol[7];
& ^+ b( [8 H# C5 G                }+ j2 ?  D$ _  t+ u
                if( exsound_select & 0x02 ) {
2 k, J. ]( K  N2 {, @( ]5 @$ Z                        output += vrc7.Process( 0 )*vol[8];1 r% _# [) I; a
                }
1 b- S+ ^* ^0 a5 ]$ T/ ~7 o3 X                if( exsound_select & 0x04 ) {. M3 E" ~$ I$ i! N4 H+ F4 }% l1 q
                        output += fds.Process( 0 )*vol[9];
. e! ~* R% ?# n" e2 f4 g1 C                }! B7 Z( U3 i5 z
                if( exsound_select & 0x08 ) {; m3 o5 p2 k8 X, g  l
                        output += mmc5.Process( 0 )*vol[10];/ I. Z5 U4 I+ S8 l1 ~+ m5 C" `
                        output += mmc5.Process( 1 )*vol[11];4 v1 d; l0 O  f% Z9 G/ [
                        output += mmc5.Process( 2 )*vol[12];  B! `3 U& q6 D5 P* y# Z
                }
# P- B0 D+ y$ ?3 O  o                if( exsound_select & 0x10 ) {
# t3 [% I2 L4 s+ p' y7 `' A/ x                        output += n106.Process( 0 )*vol[13];" ~5 r' h( k6 c8 f2 ]
                        output += n106.Process( 1 )*vol[14];
2 S2 _: @( c* T) U                        output += n106.Process( 2 )*vol[15];
: F. d* R* b- O- [                        output += n106.Process( 3 )*vol[16];
5 n$ @! X7 L2 F2 n0 _( I/ O( s                        output += n106.Process( 4 )*vol[17];
/ S+ o6 n6 d3 I2 Z9 D# Y% r                        output += n106.Process( 5 )*vol[18];
- n& G+ B; i, `8 c: I5 L! L* S                        output += n106.Process( 6 )*vol[19];
3 t8 W) [1 K% L  c                        output += n106.Process( 7 )*vol[20];+ \+ F' x; x5 ^. B
                }0 s4 E' M" P" Y, q8 Y
                if( exsound_select & 0x20 ) {! I' P; }, C' C, ~. X+ Z3 d
                        fme7.Process( 3 );        // Envelope & Noise
6 I: O3 X2 l) n                        output += fme7.Process( 0 )*vol[21];0 J0 P$ n0 j* L9 y/ l
                        output += fme7.Process( 1 )*vol[22];8 I$ h! T: n; ~0 @; z
                        output += fme7.Process( 2 )*vol[23];" ]4 B' T( d% E: P& R" i- H
                }8 u5 Q$ h$ C# h# r5 d

7 \& |5 _% R  y4 p                output >>= 8;' Q2 e% q5 c- V2 [( a

' t# n3 W5 L/ `: ~                if( nFilterType == 1 ) {
, E6 z( n$ {9 M2 W                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
% S! u6 R$ y4 C3 A                        output = (lowpass_filter[0]+output)/2;
( ]3 {. _6 L6 Y3 f                        lowpass_filter[0] = output;7 y% ~4 b+ @9 @  T; I
                } else if( nFilterType == 2 ) {% Z, x+ ^* \! x+ w) f0 G
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
/ r8 B0 i$ S  w) l0 t' f! z) L) E                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;- s9 ?% v; W: I* j: f+ [0 I
                        lowpass_filter[1] = lowpass_filter[0];
( C( \( P* G: u  H2 S                        lowpass_filter[0] = output;6 G7 U2 f' M0 M8 s$ I4 t( E
                } else if( nFilterType == 3 ) {
8 C8 V$ A0 f' W/ y2 ]/ g) C; X8 {                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
$ @& b1 Q. a5 _7 U: @9 m                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
! y7 N( y, d, }8 H                        lowpass_filter[2] = lowpass_filter[1];' r2 j7 v# X, W. m9 L3 z
                        lowpass_filter[1] = lowpass_filter[0];. @: l4 z1 g$ j, l
                        lowpass_filter[0] = output;! P. s2 n. b, }* ]! y
                } else if( nFilterType == 4 ) {
! q$ m2 I% [+ q' w                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
9 e( k4 u; D9 \                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;  F8 l. X$ k8 s. M1 X& {6 w/ K
                        lowpass_filter[1] = lowpass_filter[0];+ |* ]9 s& b, S  D# `- m* Q% W
                        lowpass_filter[0] = output;
/ ~) x# _9 s4 c- z  q. l                }
$ C- @; \/ k' n) q' \/ P, e4 ~
0 ?' f# v' ]( d#if        0
8 S1 x& R' k  q4 {' u                // DC惉暘偺僇僢僩  _/ K; p) ?% t/ w  j! g
                {
3 S. E5 [* b6 a( ~0 s- F                static double ave = 0.0, max=0.0, min=0.0;
2 K6 `1 q, k7 p7 L. \  a5 h3 ]                double delta;
) w; ]( |8 o5 ~# ]  d                delta = (max-min)/32768.0;  x" a' q8 F% X3 f0 o# s, C& e
                max -= delta;4 p* _/ e  S* R1 `7 @( Z
                min += delta;/ g; ~# V/ B: F& m( n" u
                if( output > max ) max = output;4 I- ~( R! p& F& Y
                if( output < min ) min = output;3 l/ @# U% R9 S* T: B9 N( {
                ave -= ave/1024.0;  F4 |( o7 u+ u& N* Q+ m; f* u
                ave += (max+min)/2048.0;) y; G# c: v; B/ O9 q3 v; }0 n  |
                output -= (INT)ave;8 ~: i% q/ d3 g+ o5 G9 ~+ _
                }
/ v* D# L* \, {! _+ g/ g( h#endif
& C$ q* m$ |3 _, Y#if        1
) b& @+ A+ K, R' x1 v                // DC惉暘偺僇僢僩(HPF TEST)
8 v2 N, R; Z; Q0 @# ?7 R9 w                {$ Z' \8 ^  a- r* e* k- Q
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);2 u( e6 W% V. m# j3 n* K
                static        double        cutofftemp = (2.0*3.141592653579*40.0);, m: Q: T- p0 @1 o' B
                double        cutoff = cutofftemp/(double)Config.sound.nRate;; q1 P- Z0 e* `: D
                static        double        tmp = 0.0;) c7 ]: O& z, h5 u& c
                double        in, out;' y, s7 Q! H5 `* f* l8 z' B
3 n4 c" \3 t0 s+ c3 h7 g6 a. \
                in = (double)output;
; z  x: P( e3 I/ k1 {2 g                out = (in - tmp);! ?) ]% D8 Y, K& t4 d% E
                tmp = tmp + cutoff * out;
4 J$ L% ^1 l' r% Q- F, L
- H7 [* I" U# [" g8 ]0 b) M                output = (INT)out;! v- ^* ~8 J9 D1 o
                }* B# B& z0 ^& A, s3 q7 }* g
#endif
8 k! L" `/ [2 ]+ q#if        0/ \+ z8 s! T3 v+ z$ M  Z
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
6 I8 R8 P+ }4 Y5 q* N                {
% p5 C/ T+ l' P2 p                INT        diff = abs(output-last_data);4 n, J  W- ^6 j  `7 u& N( E/ ]
                if( diff > 0x4000 ) {+ r5 Q" y) Z  S
                        output /= 4;5 \5 C, S. y5 h( o% H  v7 M
                } else
5 S8 X+ r& Z! X) a3 ~% x                if( diff > 0x3000 ) {& ?7 z$ F9 R5 v& D4 }7 X
                        output /= 3;- I' I* q1 }4 y; N( G5 q% o
                } else$ U& g, E$ l, L- i2 E  G
                if( diff > 0x2000 ) {
- P2 ]4 c9 L( g3 e8 Y                        output /= 2;+ |( ~- V. E; C5 ]1 b# {% T
                }
" A+ q: j0 ]6 _. ]( W                last_data = output;
+ d2 z+ J9 m0 y( j) c9 W, y                }
# Z  A7 m% l! o) Q- K0 J1 V#endif
9 \( F, E5 ~- N  e' j                // Limit
8 D0 p: H2 ]: ?' w& P                if( output > 0x7FFF ) {
4 m( t" @7 ~" e) ~                        output = 0x7FFF;! P4 X0 v$ h2 r) H5 h+ K
                } else if( output < -0x8000 ) {
9 J1 c. }+ ~2 Q; y1 V                        output = -0x8000;. V4 o) Y  Y" ^/ D
                }
: J5 u+ Q( S) q6 A! {  _6 G2 M3 E2 z3 T2 g% R& x' B9 U& O; L
                if( nBits != 8 ) {
/ ~1 M, U6 {! Z                        *(SHORT*)lpBuffer = (SHORT)output;# A# v/ n/ B" t! [
                        lpBuffer += sizeof(SHORT);
' q# G" a# x: u) f( s+ V" F  L! }" v                } else {& A' I4 m: r3 O6 v7 @
                        *lpBuffer++ = (output>>8)^0x80;( p9 \# |, P7 F; a
                }. p/ b% l2 i2 u9 d% L/ k  s4 ^) g/ V# f
; B+ B7 k1 e5 y. Y7 d
                if( nCcount < 0x0100 )+ d( g3 N' e: y- n- I; X4 r- v
                        pSoundBuf[nCcount++] = (SHORT)output;" M/ _0 J0 x, A# B9 X
; @, W3 ~4 U4 M
//                elapsedtime += cycle_rate;
9 B& ]0 }9 n7 d- d! s5 l                elapsed_time += cycle_rate;
' _4 T. q3 z; p- c" q        }
: V4 f* K6 @8 s$ `8 c) b6 b0 t) K0 M* P. \6 t
#if        1
; {9 |% e3 W1 A) X5 y7 a        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
- u- b" X* i: {9 I+ P$ E                elapsed_time = nes->cpu->GetTotalCycles();7 g  J' V5 U5 y) T$ H3 b
        }
5 O& k2 [' B5 k7 _; L: L) q) M        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {5 V$ a5 e9 y3 i+ s2 H- M! ?
                elapsed_time = nes->cpu->GetTotalCycles();- @' Q. y2 C. b' ^
        }% l3 Y0 }* X; v8 o/ b. ~7 J
#else
7 m7 d# j9 }  L4 X" A2 M        elapsed_time = nes->cpu->GetTotalCycles();! i" g0 _0 t4 N3 d: @/ G! c
#endif# ?7 S) @7 y  M9 W8 i2 i
}
- g. N' m2 _6 e! W  T6 U
/ i& u7 N- }# ]2 q/ K% m" p7 b4 |// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
  `2 P$ R& s' A; Y; c+ K/ R# qINT        APU::GetChannelFrequency( INT no )! \" L2 j% l+ J- G
{
6 A! @, [% k' z: c        if( !m_bMute[0] )
! O8 D; T( p2 ^2 a                return        0;; j6 z% R; }# l+ }6 P  A
# j- |) X% A! k/ i
        // Internal0 N& r% x5 Z7 B' m; D
        if( no < 5 ) {
2 v; @* [; @: A) J9 l% O                return        m_bMute[no+1]?internal.GetFreq( no ):0;
8 y- }' O4 b$ S7 `/ ^' |; Z5 y0 i; o        }
& L# F- f/ S. \$ K9 W0 |        // VRC6
9 m2 |& f7 E' ]  D! [        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {" @- p7 R  |+ \, R, a7 k1 w6 R
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
, T" d  o& Z4 X! ^3 E; F        }
+ h' r" s3 S: L- J        // FDS7 M3 U) A7 G8 ?- L$ V
        if( (exsound_select & 0x04) && no == 0x300 ) {
/ L5 |. V3 m4 f9 n/ Y! y  `/ U0 Y                return        m_bMute[6]?fds.GetFreq( 0 ):0;
! i8 D2 l, X, S9 J3 N, n, F* Y        }
$ Q: M' s" U& g6 v, W        // MMC5% B" a* @7 N* W3 ?2 ]& ]/ w; [4 X+ H
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
% j0 q# O9 e$ l# I# d: Z                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
" |1 A1 V- A, U        }
! e) S" Y, f- ~( y+ I9 ^% }; x4 L        // N106
- Q. b& c% U7 h* T6 O' f* V        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {- Z6 W- W( a! t! H8 [$ [7 G
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
1 m7 ?2 v9 z0 \, X5 }        }
- _+ s: D! S$ e! T+ v! ^        // FME75 ]6 d1 @; T2 _! i$ U6 u
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {: @% V5 n6 w. |0 K' O
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;" m' o$ I0 C/ r+ k
        }8 ^, g9 p6 ~2 N6 p5 n: S( s
        // VRC7
( A3 q9 I, o  W/ n        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
8 ^$ a0 \& F& T: y: H. i                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
" r9 ~! ^! J: V% E5 R; J        }
% [* D9 y& H0 L! n3 Q! R1 i+ M3 C        return        0;
6 O6 Q1 r0 A+ y6 J7 @}
( j& \9 v# H8 n( l0 s3 L, p9 m% }
* u) l" r6 k; g6 w- a5 i# O2 ]  p) `// State Save/Load9 M+ h" \# @; q$ y. x  l
void        APU::SaveState( LPBYTE p )
6 u8 z3 p1 ~- \$ r4 ]- y9 B" E{
7 `5 w0 i( z; f* U4 B" k#ifdef        _DEBUG
' h8 u! e" ~0 d8 HLPBYTE        pold = p;  ]$ N: @) K$ W
#endif
: j" o  o2 K: ]& M9 b6 K; _7 j
: E- z! s7 m) e1 p8 O5 A# i0 l2 K        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞$ g+ e/ ?, r. G& h
        QueueFlush();
; g. \+ [* Q- x
- h+ i* E9 b" a# @. \2 k  Q/ R$ q        internal.SaveState( p );9 }9 B" M% ?9 i* [$ M$ r% f
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding8 V. E* x" K( Y8 S3 J& P

  _, s+ I) g. ]  R        // VRC66 ]# K9 p9 J, {: r8 p
        if( exsound_select & 0x01 ) {) K; m6 q- y* Q1 i
                vrc6.SaveState( p );
& d; j  R# E% K2 _                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding9 q7 C! R3 |* i, K' x  ]- |
        }
. D) y) Z( ]7 P  \+ u; a2 I, q% D9 }        // VRC7 (not support)+ W7 d' x# u. P! i' a2 j& I
        if( exsound_select & 0x02 ) {" m" o. U& _# U: _- B/ Q
                vrc7.SaveState( p );
# B1 |8 A7 K: U" x2 S                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
/ B" h- M0 U# w& d3 X( d  ]- y/ X$ k: X        }# \) i/ V, s1 `$ t
        // FDS/ _6 X# m# N" i: Y! `
        if( exsound_select & 0x04 ) {5 I8 U. D6 K& U+ g: M" x4 b
                fds.SaveState( p );
: ?( s/ Z6 _0 D5 }  f, {0 }+ e                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
+ L9 M) f+ {; \% x3 e. F% K        }; H) |7 m/ M9 j
        // MMC5. u# y( W( e8 \
        if( exsound_select & 0x08 ) {# }  |% z0 N. v
                mmc5.SaveState( p );1 |) k; X# Y: _& }( J, ]. S5 P
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
: y; r% w" @$ G' v" w7 _3 P        }7 C( X! D' N4 W. z9 M' ]
        // N106
: `7 @- q) k( C) o' C5 m. @        if( exsound_select & 0x10 ) {0 d. T: r1 h7 [7 a
                n106.SaveState( p );- A# c$ Z9 ~9 K! \2 Z' P. n) @
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding6 {% s( m8 x  ~. f* G1 C6 ?
        }$ E: K: m4 N/ W% t- d% g
        // FME70 v2 @) n* g( u/ r
        if( exsound_select & 0x20 ) {8 a8 n$ N' ?0 P0 V. Q6 w' x
                fme7.SaveState( p );* B* A: D- _8 y! s: p
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding4 V$ k6 ?; s) O& f
        }
- c4 w" _: i, L% Y! _$ p
7 ]/ ~! B6 {4 I. G#ifdef        _DEBUG# Z! ~) k  ^1 W: e* [
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );4 p" H* n. C5 w+ l# w% F; T
#endif
7 x5 R# Y6 ?  E/ B}  S$ b. t. h! c# ^5 w2 W

5 m" i1 q" R1 t2 x8 O+ E# Jvoid        APU::LoadState( LPBYTE p )
; h  b8 \! F, z{
4 {! U! Z# J; ^$ Q+ p: {        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
7 Q9 b6 a) z: q) Q! t! ]        QueueClear();
+ n, a( Z  b2 v6 l( A3 ^& j: V/ A% u
        internal.LoadState( p );, C% S+ _0 c; m- r
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding& N, j/ E! o1 j* c6 z( B2 e

0 w1 |7 T  i$ q* Z6 P9 j' X        // VRC6
, i2 x4 N* i# J) {: |        if( exsound_select & 0x01 ) {' ~/ K5 Q1 E) u: B. Q1 j6 f2 V
                vrc6.LoadState( p );
- w1 n& F5 v" J                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding5 I+ U: T. ^2 |3 [2 D, D! Z3 q
        }
7 K. t. E* A8 E0 x# E        // VRC7 (not support)1 r6 h/ y! y( `3 [- F
        if( exsound_select & 0x02 ) {, \4 h- ?0 J3 D3 A3 U/ J) w, |/ }
                vrc7.LoadState( p );. a/ m5 \3 }# i' y
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
- \# l+ ?  ?$ f1 F! L2 Z        }
8 w+ v9 a" M$ x" {        // FDS& j% x9 a" e* W6 K' k% w
        if( exsound_select & 0x04 ) {
2 g) n% ^4 q" X                fds.LoadState( p );
7 V1 a" R. q' ?* f                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding) r5 E1 _0 R/ k; U( K
        }
6 @+ N1 b' b7 r- x( q; i        // MMC5
0 D) i% E. y  W        if( exsound_select & 0x08 ) {
1 O% n: K9 ?" x6 [                mmc5.LoadState( p );; [! l" l( b( Y$ d+ @/ s& R8 t6 X
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
6 _6 B0 Y* i  w: @        }
+ k1 |& t. f! {& |4 w0 ~        // N106
' ^$ E  a" b. m! P        if( exsound_select & 0x10 ) {9 T1 A& B, y1 s- e6 {5 S8 e
                n106.LoadState( p );
$ K2 Z- N, {2 R& o# x                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding$ e2 {( P9 Z& z4 l8 H3 u, K8 ?
        }: e7 t0 {* B& `4 a+ U
        // FME7
4 U: e6 L: m: I: E        if( exsound_select & 0x20 ) {
: c  V9 w1 j# H$ x( W& ]3 _                fme7.LoadState( p );
* {+ s' [: J; m# _$ V                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding4 H* p  `+ W+ z+ F+ v+ L
        }
0 N  H3 P6 r0 L' Y}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
; M, v/ e8 k9 G$ C" C- p! r  |可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。5 ~) O+ S, M# Y: e* m& f4 b2 P+ k
感激不尽~~
& s* V6 `) ~4 f
恩 我對模擬器不是很有研究,
5 X/ f- I( a5 |3 K. T' Y( i雖然要了解源碼內容,可能不是很困難," |% v) W7 j& W+ f3 B- ^5 r: J
不過還是要花時間,個人目前蠻忙碌的。+ p' Y6 p3 M1 X
  }, X8 e+ `9 O( \. e
給你一個朋友的MSN,你可以跟他討論看看,
& f0 G7 h; [, I& J他本身是程式設計師,也對FC模擬器很有興趣。
% U$ P3 d1 a+ z2 Q, u& c# d3 `) K2 Q, h
MSN我就PM到你的信箱了。
& A% l2 C. I% n# [5 S8 v" z
$ @1 ^1 l: m/ a4 ^+ o/ l* @& m希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 2 F$ J9 ^& S5 J- b" k! \& F7 I
呵…… 谢过团长大人~~
: p* q/ [( \$ j! w
3 S8 X& r$ j# w9 Q
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
- H, Z# W7 r1 X; y& K" E团长的朋友都是神,那团长就是神的boss。

7 E8 g1 }/ l2 J+ A哈 不敢當,我只是個平凡人,
- S0 I7 B& ]/ o要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙& n% h- @5 c# ^( ^6 P& Y6 ]
ZYH
* h$ p2 a2 U# D8 T0 n  n9 ~QQ:4147343063 p; i: E6 R! ]+ _+ T% U
Mail:zyh-01@126.com
2 v! }6 T! o& B) F- s: q% r3 D4 I6 C) G% m
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
3 O# D3 j, ?7 p再次对团长大人和悠悠哥的无私帮助表示感谢~~
$ k3 i  v4 p& ]8 R4 X7 H
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-9 10:46 , Processed in 1.086915 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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