EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
, Z0 r2 S; f! A$ \. B1 y& x  {/ E楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~0 D' W4 g$ q3 [4 @; [
这里有相应的模拟器源码,就当送给大侠了~~/ W4 v! G/ W$ b, j1 ?- b
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 % w" Z1 r& j2 x/ Z4 S  ]
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
9 g, g: S5 J3 O2 G% d% W楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
+ k: r  ?- y( u这里有相应的模拟器源码,就当送给大侠 ...

3 t! V' h# R7 {& |聲音部分(Audoi Process Unit = APU):& p4 X- q( [2 [2 V1 {- x" Q) p
.\NES\APU.cpp* O' l  V. ]0 p; D2 y2 h
.\NES\APU.h8 @1 u9 V! S2 ~& w
5 `" }8 \* `% m
+ p% \1 y0 D* }
影像處理部份(Picture Processing Unit = PPU):
; d. ?% H& g0 ?+ l3 s. H.\NES\PPU.cpp
$ h4 r* c- X: ^) U; S1 I.\NES\PPU.h- h5 @  R4 S; G1 j* `
2 _) ?6 O9 X4 {( b3 r& Y1 s
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:+ ]. g" N2 k% H4 c" ?) r8 J
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
: O- |+ h+ @6 i" g; m; R& b" `//////////////////////////////////////////////////////////////////////////
, g" z& b1 {# B3 V//                                                                      //
. a6 \/ n0 ?# C; V% z7 V  `//      NES APU core                                                    //
( @  g1 A  G# Q& K# ^) H//                                                           Norix      //
6 @. @& L* f' O1 O9 u3 }//                                               written     2002/06/27 //
& l7 S+ x# S. c/ S0 b//                                               last modify ----/--/-- //
& |/ M: l) a( m  V# g, L//////////////////////////////////////////////////////////////////////////% m1 Q/ W, X) `! o4 g
#include "DebugOut.h"$ [% X* z+ o. o' Y* r
#include "App.h"0 ~& h# ~- u4 }4 ]. A5 {  _$ [  r
#include "Config.h"" e" g: H& A+ N1 S$ \  @

$ X: `/ \  U0 o#include "nes.h"
8 p; p6 u4 ~" u7 a0 @) S( O#include "mmu.h"1 l+ U. n9 m, D" K5 ^
#include "cpu.h"
1 C5 T! d0 `* m$ b3 X3 `6 ^0 w, A#include "ppu.h"2 f6 Y, H# T+ R7 R) v: ^# P+ x
#include "rom.h"
2 z" i+ }" Y* a* h0 ^#include "apu.h"8 ~- `" q; ], V
! F3 Q4 s! X. L& a4 E! ]
// Volume adjust; ~( N- _% P/ |
// Internal sounds
: {- Y. B2 M4 z! C0 W#define        RECTANGLE_VOL        (0x0F0)% n$ [- u5 \3 E' t
#define        TRIANGLE_VOL        (0x130)
3 V- ?8 p4 ?2 _* e% Q! J- r- h#define        NOISE_VOL        (0x0C0)
. b9 _9 @: L( b9 S' Z, ~4 j#define        DPCM_VOL        (0x0F0)* W6 z. {( b7 a7 s* a! `
// Extra sounds8 {. h' _! |' u6 M
#define        VRC6_VOL        (0x0F0)+ {+ I/ F  s9 H( S+ b6 \0 S
#define        VRC7_VOL        (0x130)
" Y7 s- R/ k" }3 ?) M#define        FDS_VOL                (0x0F0)
8 _5 S' W. E7 S1 m#define        MMC5_VOL        (0x0F0)
9 V+ w. ^; _) R% p#define        N106_VOL        (0x088)0 B: B' ~% L* ~/ n; u, H' S
#define        FME7_VOL        (0x130)
* L* D0 m7 S. k8 p( f" f8 J( X0 y
5 l8 z( W' r& P! zAPU::APU( NES* parent )
$ I" s* Y0 o& y( Q{0 t, S) C/ l2 _. |/ f
        exsound_select = 0;8 i( n, J2 M2 H; u' m
. \) |$ N8 C5 P( i
        nes = parent;
! s0 [: n3 V" J9 u+ J& X        internal.SetParent( parent );
" x& _7 a) C! I5 m) l7 M
' y" h6 l$ l+ O. w4 u5 j        last_data = last_diff = 0;
# }; m" W* ~  @' G1 [# s, P4 [
% l! j% Y- f+ t" L, j8 Q! g. m% C        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );' c+ I# T0 b$ t* j! Y8 s1 V

2 U3 J, m/ Y  v) }        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );- H/ G% z- D- c6 A. u/ f
        ZEROMEMORY( &queue, sizeof(queue) );; a# r6 ?. d7 Q7 {4 Z* |# V7 m
        ZEROMEMORY( &exqueue, sizeof(exqueue) );6 t0 `) W" G, T3 |, s/ `0 G* E
# L; ?# q/ n. z( i
        for( INT i = 0; i < 16; i++ ) {9 I* ^7 A5 V; f1 h
                m_bMute = TRUE;
# E0 ^. ~% ]. w' v$ R+ C        }# e% H2 w0 H* m, m
}
% P2 u# q7 z/ W' B1 G" ?' M" N% ]; Y0 v3 @
APU::~APU()
* B3 [' S5 ~& M& k2 j% r( r5 ?{
$ Z( u, r) W. z4 {2 N( R" x}2 q1 Z% @; ]% j* {3 G2 D
8 n  y9 ^+ l6 g4 K( E
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
" Z4 X& Y, H8 [5 u, T' N/ N{
7 @* f" O; B5 D2 y. |7 ?        queue.data[queue.wrptr].time = writetime;
8 L$ S/ J6 o, B3 k$ B/ d4 j        queue.data[queue.wrptr].addr = addr;7 q5 ]5 s, j5 p
        queue.data[queue.wrptr].data = data;1 P2 z+ J4 ^6 h) f7 ~
        queue.wrptr++;& X2 [* G  {6 N% ]9 @: N
        queue.wrptr&=QUEUE_LENGTH-1;
& ?1 L8 R, @$ v/ R1 V) D% F        if( queue.wrptr == queue.rdptr ) {
0 ~* F+ r) z9 _( N* l0 B, m5 o' S! S8 V. M                DEBUGOUT( "queue overflow.\n" );! W( B0 Q$ J, k4 R4 w3 a
        }
. c5 r, k& r/ k) O  F( |1 s}
% j8 k4 V. x$ v' M5 m1 {) n
* F8 o8 V6 o! o& \BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )5 q2 Z" C& ?" j% M+ f
{
6 Z2 S2 g( B0 f  l        if( queue.wrptr == queue.rdptr ) {
8 N' _, i5 Y/ o$ l7 u% ?                return        FALSE;6 c5 b, M- ~) p! t4 O0 t# h4 L" d0 @
        }4 ~8 k8 D' @6 P
        if( queue.data[queue.rdptr].time <= writetime ) {
! X& y% J& w, K  J2 X6 I' M4 [                ret = queue.data[queue.rdptr];
( K9 H6 Q+ W& b4 \) Y) \                queue.rdptr++;* `: t% n$ }* X2 }
                queue.rdptr&=QUEUE_LENGTH-1;
" D7 U" C" G' K- R/ p/ i" F                return        TRUE;% c$ @2 X# z# m5 h, ~$ T1 j. L
        }
1 \$ \/ q8 x' E* R7 _        return        FALSE;5 {3 x3 Q2 S( l8 }+ W1 Z
}
/ E, K9 w. u  y0 H. |' J5 M' y' E3 R8 K" _' v4 |; I8 H
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
2 I( u8 L/ [* d, B3 z% N; ~{! q& G% _6 d, H/ x. m4 J, x2 u6 _1 [
        exqueue.data[exqueue.wrptr].time = writetime;
# b: z9 P3 ?/ y( L5 C/ s4 v        exqueue.data[exqueue.wrptr].addr = addr;) `' f4 A% g5 ~& g+ e( I6 B) k. E
        exqueue.data[exqueue.wrptr].data = data;) k; P* [; E+ Z6 n: J  A5 C
        exqueue.wrptr++;
. b4 j) E$ C; w4 ^/ l- Y        exqueue.wrptr&=QUEUE_LENGTH-1;/ Z1 ?+ S( O' l8 A
        if( exqueue.wrptr == exqueue.rdptr ) {% i/ @5 a; V$ g
                DEBUGOUT( "exqueue overflow.\n" );7 E/ |0 C  Y: A
        }9 _' p& T0 j( |: k. I* l3 l; A5 _% L
}
/ w+ D+ g& \3 W6 I0 v+ i2 e
9 k" @( u5 E1 Q+ |3 z) G* P/ yBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
* B) _9 r' \, K5 w; O{
4 `; g' Z, o& J1 M; d1 }        if( exqueue.wrptr == exqueue.rdptr ) {( ?6 l& x+ @( |- [" a
                return        FALSE;
' M' X3 M; [) M  Z5 L        }9 e+ y1 p; ?+ [. O& ~% v
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
! W3 o- D+ i4 Q* D                ret = exqueue.data[exqueue.rdptr];, }8 w7 R5 v- l3 l! O" Q- i
                exqueue.rdptr++;1 C: I) z/ v* x: J, s) R" h
                exqueue.rdptr&=QUEUE_LENGTH-1;  e1 s1 R  `2 O
                return        TRUE;% m9 a! v4 p- U( l, g* A( G
        }
3 }9 R; W3 d' y# I        return        FALSE;, J6 C7 o( u0 y
}
8 ?, j8 x" R( i8 [; Z5 m" A9 _& _
( c# t4 f$ U3 `$ Tvoid        APU::QueueClear()* T. S, v) M& f8 [
{6 Z: r3 Y; J" Y
        ZEROMEMORY( &queue, sizeof(queue) );
/ t2 o4 |; X+ ]# L& `# ^        ZEROMEMORY( &exqueue, sizeof(exqueue) );
1 }# i6 P' ~' Q5 j' [7 l! y}3 G6 A9 A- Y. V. t, F) h

; s; Y/ w- n9 a- b0 t: r/ c$ Y" j, Zvoid        APU::QueueFlush()
) P3 A- A1 z6 v6 S: m+ S{/ ]1 a+ G/ ?0 Z6 M
        while( queue.wrptr != queue.rdptr ) {8 d1 h# ]6 i" I% c  W4 [$ g3 c7 o
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
- D- d- {2 l! k7 Q2 I                queue.rdptr++;
8 x# h9 F( c6 [* K( B                queue.rdptr&=QUEUE_LENGTH-1;0 n$ W" L/ n' x# B  z1 A( C7 g
        }
9 @7 r. C+ }; V3 T& l% ]4 z1 D+ m- m1 U
        while( exqueue.wrptr != exqueue.rdptr ) {
# o. F  Z& D; C3 p: a5 d! l5 T                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );# e% ]& X. x: J
                exqueue.rdptr++;+ [& w9 R  g& T, i
                exqueue.rdptr&=QUEUE_LENGTH-1;) s. D' o: W8 {7 _8 P, Y
        }
( M! o$ c& z- o( I- F}( C. v3 W) D& [; Q7 b. S0 u2 I; ?
, I8 |( z9 u" m% l: J, X; d
void        APU::SoundSetup()
8 [7 g! D- C! m' g. z5 m3 R+ L{
2 Z6 }+ A) S# A9 f  K" O5 r        FLOAT        fClock = nes->nescfg->CpuClock;  z" X: {+ v  H3 Z9 y
        INT        nRate = (INT)Config.sound.nRate;
6 f+ P" `( R! d8 m" B        internal.Setup( fClock, nRate );
& {# E& D( ]( P/ \        vrc6.Setup( fClock, nRate );
9 b8 P" t" i1 i1 A        vrc7.Setup( fClock, nRate );$ a# X" l/ g, Z  s  Q1 M- @- C
        mmc5.Setup( fClock, nRate );
# n3 l7 @7 r) Y5 N        fds.Setup ( fClock, nRate );) V. ^( {# R5 y( ^0 l6 Y  M# w5 V6 X
        n106.Setup( fClock, nRate );; i4 D- l9 H  g, d2 Q; x
        fme7.Setup( fClock, nRate );
% g# c. P) M6 i- h}! P- G1 x1 e8 i  j' W
: B* v3 z( y4 X& Y# ?$ L7 ?
void        APU::Reset()
2 g8 W. O3 e- u% ^( i' u{% E' c% B6 I& Z: p$ W2 x  z
        ZEROMEMORY( &queue, sizeof(queue) );
8 o- [9 d$ o; @% d+ l* ]9 e        ZEROMEMORY( &exqueue, sizeof(exqueue) );! I1 w; e5 F6 {! g4 l! B" Z$ ?# L
+ c- X3 G- e) U- p
        elapsed_time = 0;
. \9 t4 Y$ ]5 F5 l& g6 X, }2 H# X7 F" S. n" }. j9 H( K2 E
        FLOAT        fClock = nes->nescfg->CpuClock;
5 u' w# ^7 t  Y' i* g5 o; J5 t        INT        nRate = (INT)Config.sound.nRate;3 |  a7 ?; O+ K$ t4 M9 b! e, @% D
        internal.Reset( fClock, nRate );
1 H$ V6 Z- u9 R" {7 H        vrc6.Reset( fClock, nRate );
- _* K( L  H8 e6 F& @" Q+ k        vrc7.Reset( fClock, nRate );
! \6 O7 V. |0 ~7 i( L        mmc5.Reset( fClock, nRate );! u& v1 B+ u/ U/ ~* t( g
        fds.Reset ( fClock, nRate );
: E5 Z6 A2 \0 s9 \* I        n106.Reset( fClock, nRate );' h! e" Q$ Z' H$ r4 Y7 L7 W! F
        fme7.Reset( fClock, nRate );
; [6 L8 L7 e6 g; w6 ~" }1 i6 B2 t0 E
2 W& d8 `0 e/ \4 D        SoundSetup();
" {' F7 }( P1 r3 w- z}1 x  G9 l0 N4 ?7 r/ v! ]4 T4 P4 i* e: G

/ [2 D* y+ q0 U; ?( A& M- s* Nvoid        APU::SelectExSound( BYTE data ): D' N& k' O$ u0 W* i; H# i; z4 I
{& I3 e  c, p  Y5 M
        exsound_select = data;, z" z9 P' @2 t9 b
}
, a; M% ^% |4 Z- S2 i
; V( |; Y% L5 J1 s& CBYTE        APU::Read( WORD addr )9 ^: _  a5 ]7 Y3 i8 o" E" G, w
{% ?* G8 G( d- i: P6 g( p
        return        internal.SyncRead( addr );
; U% k' M. N7 }( [}
9 P5 Q. X+ {) {- w) e' \/ D# ^/ [/ c! q  q
void        APU::Write( WORD addr, BYTE data )" b  K% {! G& {1 E5 D; u" C4 j
{
( `, B5 _" C* A. ?1 L: J        // $4018偼VirtuaNES屌桳億乕僩
# V" _/ }9 N8 \- j        if( addr >= 0x4000 && addr <= 0x401F ) {
4 Z- H, J) n/ ^! K) r) e                internal.SyncWrite( addr, data );; k! m3 X7 z1 R" `8 M
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );$ p0 o, F. h7 Z# @
        }5 P0 v7 }- c2 i3 b
}
( F6 n* P. _8 t1 F" T* V/ i3 N! l8 m" i
BYTE        APU::ExRead( WORD addr )
6 Y) J$ J2 x: f" v- m$ d{
& p# |0 n: Q$ V- p' }& cBYTE        data = 0;
6 g" A& ^7 b: ]$ @; ]% P& X' E' `: A# J9 V0 Q. c* h6 N/ w
        if( exsound_select & 0x10 ) {
" |6 l9 d4 k! i' K( w3 N                if( addr == 0x4800 ) {
  D" E, g% `( p7 W0 d                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );  O- c& v$ t% h* {  [
                }
" c7 R/ v% j& [5 @        }! b/ [9 {( V2 d& b& `9 Z" ~
        if( exsound_select & 0x04 ) {8 n! e0 ~5 P1 k5 o/ L. q$ z4 q+ p
                if( addr >= 0x4040 && addr < 0x4100 ) {
6 ]0 g, q( n2 Q3 S# q9 }) k5 D! k                        data = fds.SyncRead( addr );
$ W1 j% u) L" t: y$ Y; l3 A; q+ q' h                }
. v  n: x. I* b, b9 }        }
3 z; ~; ]. }. b, Q) n7 w        if( exsound_select & 0x08 ) {" Q$ |* c: z1 U# e# v2 {! c
                if( addr >= 0x5000 && addr <= 0x5015 ) {
9 @" |) _% B- }5 B8 M, H                        data = mmc5.SyncRead( addr );
. E3 j0 @1 o' _" E. w3 I. j% ^                }0 P8 l8 z6 n( ?; b
        }% \- g# Q% B" t0 _

5 ]+ c: J0 z/ K2 U2 D! C' k, V, Y* U        return        data;) Z& K9 L5 r, R, q. `- }
}
, ]5 Z% a5 p6 w, a1 m" z
& S  b  \  ~2 ]" Bvoid        APU::ExWrite( WORD addr, BYTE data ); _4 \  A  M7 s- r* ]
{
9 R4 r$ L/ l7 l* h+ s, d0 g) R- j        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
0 T5 v. j, X. r% ?0 [- }& c: F/ i/ ]- ~& c
        if( exsound_select & 0x04 ) {
  ]; d; \4 p) i- @1 h7 F0 x/ ?                if( addr >= 0x4040 && addr < 0x4100 ) {
+ s; H2 r" u1 [& k! V8 L3 \# {                        fds.SyncWrite( addr, data );
7 [$ J* }" ], N% O4 l- a                }; @6 k0 L2 y  H% G7 x7 Q  a; H
        }% e, g0 Q* q: z# W

( ~$ P, V, d3 O; `        if( exsound_select & 0x08 ) {, o5 T# I3 F8 z; v! B; a
                if( addr >= 0x5000 && addr <= 0x5015 ) {
- M% ]8 i, G/ E" l) w                        mmc5.SyncWrite( addr, data );
$ O1 ]2 L+ M( j% j* \3 X                }
8 v/ D- f: f& ]; W9 j+ C        }+ r2 {! I( D0 E* M$ Q+ k, q: S7 I! U
}7 D) ~9 y7 W& w; O. V# X

1 C' m9 d7 P* i# Fvoid        APU::Sync()$ ^+ |, r, F# O9 E( n" O' {( n
{
: n' Y. ~: m+ f! ^}
( t% S' @* N( J) _* {/ z. Z( Q# m! e9 @  s. x5 l
void        APU::SyncDPCM( INT cycles )
! |! G, {. r& P, ^9 I{$ \8 Z3 L) x  W$ b+ l
        internal.Sync( cycles );
1 C0 k- I, c7 r' I1 |: ]- J% W, X. f4 [
        if( exsound_select & 0x04 ) {
4 p. E+ p$ l) r4 L                fds.Sync( cycles );
' Y# M% K8 Z$ B/ k% K- ~8 Y        }
" M& M9 f6 I$ [: ?9 ~        if( exsound_select & 0x08 ) {' O" b5 u( ?2 m  _8 C$ N3 ~
                mmc5.Sync( cycles );
5 o! d: C. n: O( c. i  U7 f5 O        }6 o8 E+ R9 }! P* x
}
3 K9 D' n3 B: C/ Y& g. n: [: X: E- x0 `
void        APU::WriteProcess( WORD addr, BYTE data )- c+ r5 U9 j# `9 s$ x
{( f# l: P/ a' O8 D: g. z2 Z, u* q
        // $4018偼VirtuaNES屌桳億乕僩
2 Z9 k) m3 k/ m$ @        if( addr >= 0x4000 && addr <= 0x401F ) {: R2 n- C/ y3 n6 U/ x! I
                internal.Write( addr, data );3 q9 k0 p5 Q- ?) ~4 I  T" _
        }5 c: Q( `3 `- k! i4 ?; O( h
}
" [/ R0 d; N; p
0 b) T3 V5 \' A  @( o( z  Rvoid        APU::WriteExProcess( WORD addr, BYTE data )
/ U8 ^' r4 |/ b+ E{
9 ]6 l6 L1 {, g& M& R0 y5 ^: H  b9 z        if( exsound_select & 0x01 ) {
$ Y8 @, P* i9 x+ J                vrc6.Write( addr, data );
! o1 N. s# g3 @- I! J        }6 v# C# U$ a0 L) X' w
        if( exsound_select & 0x02 ) {
/ r8 g2 S) k% o. j( ^; A4 `" }! }                vrc7.Write( addr, data );$ K$ T, R2 {5 s" J$ |7 L# X
        }
4 S8 p; E1 f' o( }  e4 z        if( exsound_select & 0x04 ) {- w) E: @; \8 H! ?
                fds.Write( addr, data );  K) M1 B9 b1 A* l& j1 u/ B
        }1 q% k) r) U) y$ W$ m! b2 a
        if( exsound_select & 0x08 ) {1 t; D& J* |9 M. G* k1 T, c
                mmc5.Write( addr, data );$ p& `! n/ ^- E- T; l  s3 Q
        }# c+ C, U% f2 _+ P
        if( exsound_select & 0x10 ) {" \- i, ^2 f* e9 V* W* E
                if( addr == 0x0000 ) {
1 c3 {! j, {, b5 P; e                        BYTE        dummy = n106.Read( addr );, U; z) s3 m  Q% n" I9 r+ w' u
                } else {- ?) F6 |' L' F  W
                        n106.Write( addr, data );
: k4 L" [  J3 {/ K                }
5 z  d1 a6 m6 I! p5 T& y        }
, u+ X% Z9 V. N- e        if( exsound_select & 0x20 ) {8 S& v: h. f$ M7 i: H0 j1 s+ r% j
                fme7.Write( addr, data );
7 c# y/ @3 ]' N& R        }4 a. {+ r$ ~  K* f  M( v) f
}
& M2 \8 y8 P6 O! r1 Y
' z! o2 O/ f7 {, r' T, G9 y, Cvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
  k7 C" q) w# `/ E5 T0 {7 _/ L{3 @" z# G6 h) t
INT        nBits = Config.sound.nBits;) Y5 p& t+ ~$ _' x/ X: Y' j
DWORD        dwLength = dwSize / (nBits/8);: L9 O) I  E  K$ h) v! P/ E+ U
INT        output;8 |8 B! `. }/ D. u4 _
QUEUEDATA q;
) W4 [; D: z  Y+ I0 k5 E8 f9 f& WDWORD        writetime;
2 j9 G4 O; m! _5 j8 E. S
5 X$ \8 Q- J9 W; n' z4 oLPSHORT        pSoundBuf = m_SoundBuffer;
# H/ D. W3 |6 \# w, o1 _INT        nCcount = 0;9 z3 b1 k: }* ]1 _0 \: n$ d- A
2 m- M  L  {3 @0 M
INT        nFilterType = Config.sound.nFilterType;
8 ~6 {' d# J4 z# n+ l4 j" |0 R- S/ b9 n5 o) d& ]$ @/ P7 ?
        if( !Config.sound.bEnable ) {
  {/ ~2 {7 Y+ f0 U6 y                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );% T6 R- N, K3 o: Y  ?, N
                return;) I- m0 f3 `1 r+ a8 M9 j& c1 z
        }$ h6 q: w3 q7 L; e" R  P9 e
, l, {) d9 a/ Y) [
        // Volume setup9 G5 f) v' f' l% a, f/ B- f
        //  0:Master
% h2 {0 I' s$ m+ F# h% g        //  1:Rectangle 1
8 ^$ B) }  Y" Y% O! _8 t        //  2:Rectangle 27 \7 G. `; y- N+ m; B. x$ n
        //  3:Triangle5 X, k2 c  w+ c. P3 L
        //  4:Noise  F$ b  {  R# O2 Q8 Y) B! s! A
        //  5:DPCM4 _- {. r& U* X
        //  6:VRC6( j/ V7 b  q( x: T* z
        //  7:VRC7
# u  o: W( |$ m* i        //  8:FDS
1 v. c- m: }0 I- M7 H        //  9:MMC55 I! O8 Z+ I/ [5 S& U! y  ^
        // 10:N106
, O1 n$ j  n/ U2 `( U* v5 {        // 11:FME7
+ u: s1 s3 O: U  i5 M        INT        vol[24];
1 I7 [0 e0 j* l, V        BOOL*        bMute = m_bMute;9 A1 I/ n) L$ @0 V. T
        SHORT*        nVolume = Config.sound.nVolume;
1 Q8 E/ T. {# G" F! ]6 M
- h6 ^6 j- K8 J# b- l+ A, t" C. i+ S9 `        INT        nMasterVolume = bMute[0]?nVolume[0]:0;" X& q- U* \1 K8 p, H: l# l& @
5 z) _! u/ }6 a, w. s5 A! C2 f* ], }
        // Internal) c* z* b# E! p: L! t1 {$ E! u
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;1 A; w- w4 }  H1 R
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;! [, a; q! R- a9 G% T
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;2 X% X( u, j) l, S  T
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;4 t$ |' R" s- i" A# U6 b
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;2 Y; o: u9 z" `9 b6 X* P
! k. ?9 f) K" o9 e$ d
        // VRC6
) S: `, J: y/ ~3 v/ O        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
# F. ]( e- E# N        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;7 V9 f) K. k3 B; L7 W! S* S: x9 m
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
) J" e& }0 u5 B3 V& x/ b" }; b$ r0 \1 z
9 Q$ u/ w1 i3 l* {8 b        // VRC75 l/ s5 ~8 W1 f  i5 O
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
0 S. I3 R5 l  z! Z& m/ G# c2 b
/ y" m4 @7 e% s" ~8 }4 U        // FDS7 N! r/ O2 f# z: D" p
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
! j: }2 R" O* v9 g9 e% Z, r. ~: [
3 K- c" s! a! \( A* F7 c        // MMC5
! U4 k8 E5 e/ |+ s; _9 O        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
& h9 y* L9 C7 v& {0 o4 ^/ S" Y5 A        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;* ^8 Y0 @1 }! f* R  f! X# t
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
% W# P- C0 f. k% X1 N! W' S
9 W( f( j2 F- E" r( H) L. J- @: T2 ]        // N106
- X7 O  O/ \# e7 S+ j3 e- U, U        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
# c; K7 j* J$ o5 ?! s- P3 y0 U        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ f# U# ?& z. t4 C; j& C/ x        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- v3 `- a. p( ^* k# H$ \& Y- G# y. Y        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 z, p! @5 X' O% l/ i  ~4 h( E' G& H
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;4 U+ j5 G+ m; u) ?# A7 r$ ~2 j& K
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ O5 O7 h5 M) d- D" j
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ K* v- e3 k8 g+ r4 M        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 J+ n" N$ T, H; d  _8 y- _
, J+ {9 n, J* e' B. Z2 p        // FME7# L2 L" h. N$ q9 _
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;6 s3 F1 a/ w' `
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;  A+ U. @" V! K- `" \8 \
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;; G1 T0 P5 ?# h6 K" }. X1 K" W
6 w% w5 }+ u1 p+ K9 u$ n
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
8 p; O7 E4 b" Z5 `" h( t0 F        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;; u: G- _2 y* ~% p6 U) Y7 z
* z9 j8 i3 `. f  o
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟7 E6 M  l8 E. w: \# e
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {, {, s, g9 |. r: w/ I
                QueueFlush();3 j) I! c) B0 d9 o+ U; k. k
        }
1 ?! B3 H- T  N! R* Y) ~3 x% x7 w' m5 Y( v% S
        while( dwLength-- ) {4 s5 A/ o* h* R; \2 L3 W& ^! W
                writetime = (DWORD)elapsed_time;
& Z' `+ d3 j# Z
! L9 s# H3 ?( h) s4 w                while( GetQueue( writetime, q ) ) {) d& M& h" N- v' P  M3 S
                        WriteProcess( q.addr, q.data );
8 T* h& J+ l3 @, H* d9 U+ [3 u                }
9 r! u2 z. x* c; M
2 j0 a9 M, d& k. u# `+ t- g                while( GetExQueue( writetime, q ) ) {
2 s: U# v2 M) P                        WriteExProcess( q.addr, q.data );
  j( @7 q+ N2 `0 b; _  @6 ]9 |                }
) z' C: r# ^" E1 ^* J2 W$ v9 F/ K; P7 r  e
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
( m7 X" Y4 p) x6 s% ~& [/ Q  s. B                output = 0;
) V$ A, p, }, ~1 R( D                output += internal.Process( 0 )*vol[0];" A* r9 A- ]. a# i# O
                output += internal.Process( 1 )*vol[1];" @" C  J. a( c
                output += internal.Process( 2 )*vol[2];# O/ N$ T1 I4 w9 g. R' m
                output += internal.Process( 3 )*vol[3];7 U( j  L' o$ P- s
                output += internal.Process( 4 )*vol[4];- ?: m2 I/ K* a

5 _$ P& [# x0 b: d" c7 F                if( exsound_select & 0x01 ) {
# h0 c& y; {0 W1 ~3 w                        output += vrc6.Process( 0 )*vol[5];$ g* }; e2 p) p% `7 W5 X. Z+ |" F
                        output += vrc6.Process( 1 )*vol[6];3 C( O4 Y, q' Q3 @, P
                        output += vrc6.Process( 2 )*vol[7];
9 x+ x1 j) E6 r; J                }$ J, X+ I* `$ l" b7 d1 ?2 t+ D
                if( exsound_select & 0x02 ) {
* j( u  r+ U8 a' P2 l                        output += vrc7.Process( 0 )*vol[8];
2 v0 f) \! K  w" I6 t3 Z* b                }
# B& ]/ H* ^0 g8 o                if( exsound_select & 0x04 ) {9 B! J/ _  {" q' i
                        output += fds.Process( 0 )*vol[9];. X1 y1 f2 Z7 g4 G
                }. t5 e, }. O: }4 _( i: s
                if( exsound_select & 0x08 ) {
$ o1 r& Z  v, J* b                        output += mmc5.Process( 0 )*vol[10];( ~2 r7 l" a, `0 j5 }& `4 `& R& d
                        output += mmc5.Process( 1 )*vol[11];
5 R* I* c% F: T0 \. x) i8 O6 _5 q( x                        output += mmc5.Process( 2 )*vol[12];
) T+ H- m! g. e# G                }9 m6 @$ p6 U3 S3 F
                if( exsound_select & 0x10 ) {
  j! i) H4 o$ o* _                        output += n106.Process( 0 )*vol[13];6 z# d0 ?" z1 B3 I
                        output += n106.Process( 1 )*vol[14];
2 h2 T9 v) P8 [  X% j% K* ]                        output += n106.Process( 2 )*vol[15];6 m- [, \* q0 `3 x# m2 g
                        output += n106.Process( 3 )*vol[16];
) D& s  M* Q; Q$ v+ M) x                        output += n106.Process( 4 )*vol[17];
! M  e. ]: u% l) r3 n0 c                        output += n106.Process( 5 )*vol[18];& X' _+ b( d; ~' y3 q! z( n" r! ?! P
                        output += n106.Process( 6 )*vol[19];( S* I& i7 m' E
                        output += n106.Process( 7 )*vol[20];, Q6 t& S, r) J4 h0 p
                }& |: H: W! L* }1 V9 ?
                if( exsound_select & 0x20 ) {
) S8 y( U$ r. l  w% ]  \                        fme7.Process( 3 );        // Envelope & Noise9 U/ x2 m8 r5 c# {; s- k. Q$ w
                        output += fme7.Process( 0 )*vol[21];! S' O; \0 e" A: q& ]# L7 L, A4 d
                        output += fme7.Process( 1 )*vol[22];
- S9 H; v! R+ ^8 R                        output += fme7.Process( 2 )*vol[23];) g4 ^) V4 C: C0 o
                }
* Q3 c  C# t3 m# {& Z* `8 F, H: o: q# \# Q1 j9 |4 r, o
                output >>= 8;
$ T3 U% H" |# x8 b
0 _" P" R2 M/ v2 q. @$ Z                if( nFilterType == 1 ) {$ I" J, b5 h5 _$ g" B  R4 O
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple): H( b  ~5 V, E: Y; n  f. R
                        output = (lowpass_filter[0]+output)/2;
/ v. o8 Y3 D+ h                        lowpass_filter[0] = output;0 i; i0 R% l" b  Q' T) o
                } else if( nFilterType == 2 ) {
7 ?- ~9 s+ {! d" M! ^. k, H                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)8 I, R# K5 M8 I0 P  @, c9 @
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
9 w7 h6 ]' T5 ?" |                        lowpass_filter[1] = lowpass_filter[0];
7 H" }! n! b0 L                        lowpass_filter[0] = output;7 n1 f: ~) O6 A, m
                } else if( nFilterType == 3 ) {
/ S7 l' t* n. i: r                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)# s+ l) ~, z4 l1 K/ n
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;$ i7 [9 I% y; q0 o8 n& j4 |7 f
                        lowpass_filter[2] = lowpass_filter[1];6 d/ x1 p. @1 g5 _" G- |9 D3 D) A  D9 m
                        lowpass_filter[1] = lowpass_filter[0];
# b8 V2 }8 {# G                        lowpass_filter[0] = output;
* t" E: v& }$ S! S4 h0 b3 h                } else if( nFilterType == 4 ) {
9 A0 P. P/ m5 Y1 ?7 z                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
4 ^3 p+ n. i9 K: W* I7 S  A                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
) K% G; ^0 G0 y1 I# l2 o                        lowpass_filter[1] = lowpass_filter[0];
4 _* I; \: Y0 S, y% F                        lowpass_filter[0] = output;
: p/ D$ a5 X" x4 ?                }
( _5 g7 ~0 i/ G8 H2 B2 |6 c
  I5 U! O9 J" y: c# x" ^#if        0
- Z5 @; h! t% A6 s  F                // DC惉暘偺僇僢僩
7 c, u. h0 w5 w6 Y                {4 i' t  D7 p( C! b
                static double ave = 0.0, max=0.0, min=0.0;
6 H" D; n  Q" J. E3 i! v( C                double delta;8 u9 X* M5 d/ d3 \9 I* [& Z' g' ]* M
                delta = (max-min)/32768.0;
' m" F) e9 p) c% J( ^3 x                max -= delta;
$ v; _8 P. L* z" ^                min += delta;
: z. u, Q# ]% L                if( output > max ) max = output;) a9 ~' l* z+ B( @
                if( output < min ) min = output;% z4 e" }% b8 n4 O( R7 c
                ave -= ave/1024.0;6 c5 ^; h5 K4 z4 y% u  J) D0 y
                ave += (max+min)/2048.0;
, `+ }( h/ y- R1 X+ K; q& e% g3 G# M                output -= (INT)ave;  |2 y3 J! F: A" v; [
                }
, t" `. D" O+ D+ F& J  W#endif2 K4 t  A) p6 h3 t; E  G8 A
#if        1
% o% B. g/ i# r- l0 p+ v  @                // DC惉暘偺僇僢僩(HPF TEST)
& R7 O; Y- F; ~2 `2 u1 I                {
# O" y- q6 L, d- L8 b//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);$ A; |6 ^( ~5 F+ @6 ]
                static        double        cutofftemp = (2.0*3.141592653579*40.0);& p  v4 J: x2 k9 P* o
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
* _" P& q# w4 K/ g                static        double        tmp = 0.0;) L, J( F' i! x- j" A- q3 E
                double        in, out;& A/ Y+ h& P/ k0 F0 m6 L

  j( S# m+ Y/ ^: R2 B7 G* ?                in = (double)output;# t% U2 D8 e" c- V# E& n9 e
                out = (in - tmp);
% M5 L9 ?+ k# h. `                tmp = tmp + cutoff * out;4 s5 [1 {- V6 h6 M4 `# O

4 y. D- G. g: _6 }                output = (INT)out;
* g+ t: F7 x/ x                }6 Y* C$ j0 t/ i
#endif# v" T, T$ \; R9 Z: ~
#if        0
) c7 V6 h' Y3 l5 P6 T+ v/ D/ m2 y                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
' E, q2 Y. z8 q( w: L! w/ z                {
' O9 r8 Z$ |$ r. N7 M                INT        diff = abs(output-last_data);0 T  n/ m+ O9 o# c
                if( diff > 0x4000 ) {
0 i6 o( l5 P# W! }2 l                        output /= 4;
. w8 J& U7 N- O9 X" b# H                } else 5 z$ o: N3 Y. f- l* D- f
                if( diff > 0x3000 ) {
. ?" r1 p) Z; x% I                        output /= 3;
* o9 B! Z  ~1 g* O4 A+ D0 {' b1 P) T- d                } else) u7 U8 k; ~! F3 Q/ n+ W
                if( diff > 0x2000 ) {. `. \9 j8 c% `6 Z+ x9 b; B
                        output /= 2;4 w- f$ b8 B6 \' \9 A8 S% f
                }8 h$ z& {$ A$ l5 ]8 u8 G
                last_data = output;6 x0 R$ I$ m& H* L; V
                }
4 p  X. w/ e/ m1 a8 ^) g#endif
  ?9 T3 O  \- r; r& Z                // Limit
% v: j+ A& s0 b( E- W) t. D                if( output > 0x7FFF ) {
6 b6 Q" ^" A. A: {& Z7 d, v8 `                        output = 0x7FFF;
% r: f6 G, O% K6 a" {4 F                } else if( output < -0x8000 ) {
" N6 |  t% B4 S                        output = -0x8000;1 j2 C9 i( Z% P
                }' v3 H# S$ V. h
; h6 v) O8 b: @
                if( nBits != 8 ) {/ g& s5 G3 _! z& C
                        *(SHORT*)lpBuffer = (SHORT)output;
7 _! Y& O  U4 J$ @                        lpBuffer += sizeof(SHORT);4 U6 s* h2 U! a6 h
                } else {
2 L& f, W7 ?9 O  Q' h( I                        *lpBuffer++ = (output>>8)^0x80;
: L4 g, I& z. O* x                }
. ]  _  g  @2 d" W; ]2 g4 W/ r& \5 s7 R; q- I/ j1 u6 v
                if( nCcount < 0x0100 )+ ?0 v# L3 a2 d7 W
                        pSoundBuf[nCcount++] = (SHORT)output;
% {; w$ x* `8 n& [. r# g8 i: L' \5 i5 h" E) V( M- M
//                elapsedtime += cycle_rate;
" c& T) ?1 k! y; x5 ~$ `                elapsed_time += cycle_rate;( q1 |; {5 K# c9 G
        }! k0 W" K+ T( a& a' U7 r

+ i. o# ?1 L/ ^$ D4 W#if        1
7 R+ O. U3 S* g! ~& p9 {$ i        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
! A. [- M+ Q1 t                elapsed_time = nes->cpu->GetTotalCycles();2 z* l4 g! ]" }1 B7 U# R
        }
- s9 j( B2 v& S' U; p: Q        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
4 i* u2 g: V2 [2 T/ G                elapsed_time = nes->cpu->GetTotalCycles();
7 X8 u+ j0 e2 T0 f6 a, O+ u3 \: K        }2 _3 ~3 T+ ^; {2 X
#else
+ O- e4 C; d; ?' E: f! W  T        elapsed_time = nes->cpu->GetTotalCycles();
2 |1 D8 U0 P  }8 s* N% W( n0 c( D#endif  B: L6 c0 y1 M) V/ |
}
; ^  \) v. }5 V6 m3 `
$ t' x+ H1 _' J; J- W7 q// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
5 M1 f" a; @0 o3 J! [1 aINT        APU::GetChannelFrequency( INT no )2 K; |! u: m- X# i' P
{  Z6 r1 _' p, H8 c( M  e/ K  T
        if( !m_bMute[0] )- N9 |3 }& @; D( W8 M) m7 ~
                return        0;
7 q% ?) L$ L! `. b0 h4 d: v
' _5 V2 g, w+ I+ s5 h* e. u        // Internal6 v; Q3 X' P" ^, V
        if( no < 5 ) {
+ G0 z9 H8 V5 ^( H                return        m_bMute[no+1]?internal.GetFreq( no ):0;
5 e+ e2 G7 @  {        }) O8 E; c- w$ T9 {3 O/ ]/ `
        // VRC65 d6 B! w1 }, l1 U& r! @7 o1 p. }
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {$ V5 i! }* O" L7 {: f& T6 S
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;. U1 j* U. [' v$ \2 c1 Y
        }
0 i/ j. c1 J/ |. D5 B! q9 m        // FDS
2 O( e6 H, x7 }% o( Q        if( (exsound_select & 0x04) && no == 0x300 ) {
. _- |. }" A3 ?2 F/ A& V. r% C                return        m_bMute[6]?fds.GetFreq( 0 ):0;
1 Q/ y) `2 E' R" X        }
7 j5 d. [+ ?/ k( l3 L' P        // MMC5
, b" z# x8 Y0 H/ i% W( U' r        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {7 T/ e/ Q! h9 y
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;' t4 ?6 u7 [; l
        }
3 O) G! D) M" l" ]        // N106
- Y7 s! i$ _0 m# ^8 Y3 m        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
3 d. d2 N, w: y                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
* P- ]* U7 s5 i. Y; H        }
" n3 H4 H2 N7 R        // FME7: p5 \2 G( m$ L  h: Q: Z$ d+ x0 ]
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
. ^9 u9 c+ `$ v. z8 H( c" r                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;; \7 D* \3 l2 b; i
        }
# M% u6 V$ i: U: F8 X/ F: r        // VRC71 w+ ~# U: {+ A9 g8 S
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
! F/ m8 z; {; a0 G$ @5 v                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
' n/ q3 }+ Z7 I( Y( z        }
  F9 w* |& p- h( V: v        return        0;0 b  @) j7 w. R4 v
}# T: [4 T6 C3 [- q5 U* h# z

- g% p0 o0 }1 {( q, u4 T9 X7 ^! |8 [// State Save/Load7 B7 P* S3 n) l2 y
void        APU::SaveState( LPBYTE p )
4 b% m/ b( Y; k7 C{- T, X3 k7 w8 m% O0 r0 d0 j
#ifdef        _DEBUG' {0 J2 |2 Z- G+ s2 U# Q; ?
LPBYTE        pold = p;
6 n0 H1 g) R% r3 C+ C#endif* }7 ~- o* `4 C
+ v+ O9 O2 ^" u% n8 T) b
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
8 B% j$ k5 W2 W, i7 X        QueueFlush();6 Y$ U( j6 S; W, I& e
* l. |# a' T- ]/ G$ p- C* j
        internal.SaveState( p );$ x- O" H6 A6 G1 f
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding7 q6 Y4 a  X* T3 F
8 h. ^, @  x: g! }3 U) X" q2 B
        // VRC6
3 X  B  B% C& n% s+ F& d) {        if( exsound_select & 0x01 ) {' G+ [3 j8 \8 v' r  V
                vrc6.SaveState( p );
5 b3 s0 @; d7 |' K                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
1 ]6 [: \8 k2 h+ r' T        }
0 q9 a5 B' _+ @3 B7 P        // VRC7 (not support)( x) a+ \1 K5 Y
        if( exsound_select & 0x02 ) {
+ @4 M2 o0 ~8 x. a/ ^# G                vrc7.SaveState( p );* ^$ N) R- x4 M8 j
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
6 T) M) T, |6 Z1 Q' f! N        }" K9 n/ ~5 [5 Q/ c3 [& q9 h- @3 y
        // FDS
2 X& G1 J% q2 }" r0 B+ B        if( exsound_select & 0x04 ) {$ m; ]& `' ^0 d' |" A/ [
                fds.SaveState( p );4 e/ r3 S$ R: Q% L) h
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding* ~6 m9 a- r/ G; E
        }
; I( c( M* X* N/ y( W, M; k2 @7 }9 B        // MMC5# K0 k8 d$ b* p- H- |" Z1 K; _
        if( exsound_select & 0x08 ) {
: _( I% N$ o" ]' z/ l                mmc5.SaveState( p );
! H) [3 j9 t' B+ L" u6 m                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
' d9 R" ^( |& `7 M, Q  ^, c1 m        }
( M' m# W# U2 M, w$ w  N; ^8 R        // N106
7 s) c; Q9 u9 |        if( exsound_select & 0x10 ) {
) t* \* {8 U5 N                n106.SaveState( p );/ U/ ~+ f. e" w5 J
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
7 W+ f" b6 A$ R% n7 N7 l, `        }: j4 R! ?! G8 b* d* z; N
        // FME7
( r9 ?' l9 S. _1 g7 {        if( exsound_select & 0x20 ) {
. g) Q. [/ z- ~& N" n7 E. @! A2 J4 I                fme7.SaveState( p );
. A, A- h" S4 x' u$ @1 I                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
# t+ }+ G* j3 a- D1 h2 S        }
4 a) Y1 Y2 [- O9 u" N/ y
5 W% A" Z- _4 g6 T) F+ ]#ifdef        _DEBUG7 q7 _, [8 G9 W; z, X/ M8 f# `
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );1 X5 `1 b9 g7 o% @3 p8 ^& y. z! p7 w
#endif
' G& f: Z( G3 ]8 F}
# G  a0 @  N6 o7 G) `/ f9 u* J5 }0 `1 U. e( x
void        APU::LoadState( LPBYTE p )
( y9 R% Z( o  H1 \$ `8 k1 }7 i{+ E  X: P: |3 g3 a$ q
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
! Y) {9 B. ]& |! f& A1 P- v' w        QueueClear();! x4 K: v7 Q4 c( f
" B  \1 [- b  o7 s( }0 m
        internal.LoadState( p );8 A, m5 \. @  {" h' m- A
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
; _# l, s. B7 ~$ x0 ^- W- Z8 o% c7 _8 \3 n, l
        // VRC6% e6 M+ q0 _/ X6 y# Y7 c4 k
        if( exsound_select & 0x01 ) {
9 v; j" P/ p) C6 a$ t$ E                vrc6.LoadState( p );
6 c" P6 [/ ?* Q: H6 C6 K                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
9 \/ N" J* Z. M% L8 ?9 _        }
% N4 n! h" y( O" `( p  Q        // VRC7 (not support)
7 m& I, E" e0 j3 |- m- g0 T        if( exsound_select & 0x02 ) {9 t: y, Y* ^# m4 c" |/ J4 L( K* k
                vrc7.LoadState( p );& [" r0 y  ~5 L' |
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
; K* D4 ?2 k) |" d- p        }- I- ~, I/ [0 j
        // FDS
: u- J- J- v& ?) l2 s        if( exsound_select & 0x04 ) {! l, Y+ ^- d( S* {0 z0 F
                fds.LoadState( p );
( A6 Q+ B8 ]; N- _# s/ y* L                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding. W2 T" E1 N; l8 ?2 h& D2 i" m
        }
) G# p& {. v8 e+ g        // MMC5$ [; ]6 d; s" w
        if( exsound_select & 0x08 ) {
/ B% A% n3 J/ W' Z  B& Y0 s: I                mmc5.LoadState( p );
5 q1 \! t/ V% ]3 H                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
7 n0 k$ y( i9 b$ I        }0 I2 P0 L* m0 x* B
        // N106
0 P9 Y1 V0 g5 l, D6 D* Z5 c        if( exsound_select & 0x10 ) {
1 E, V" i% O3 d  j% @6 @2 ^& m                n106.LoadState( p );( y' ~( G6 ^; x: b1 N: |
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
' q5 o3 M! `0 v! }4 Q4 \! r/ ]        }  t' r# b1 o: F  \! ^8 T% |
        // FME7$ f/ x1 |& L+ r  i" X
        if( exsound_select & 0x20 ) {
* f2 U, v4 u1 P7 B                fme7.LoadState( p );) z5 A) t0 h6 d* f2 a  X% p$ I
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding  B% e% S) _; i5 o* x" F
        }' P$ n3 @) U6 H7 Y  W& l
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
& ~, o4 |8 ^( o' ^9 R# E. a8 F* a2 W可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。* ?7 R' S3 I  W$ r3 P; ]7 }
感激不尽~~
5 Z' g3 l2 P) }- I4 G
恩 我對模擬器不是很有研究,
" N1 v2 [2 M0 i$ Z" b雖然要了解源碼內容,可能不是很困難,
+ d: s( q3 R4 q" \, |+ `不過還是要花時間,個人目前蠻忙碌的。/ R$ `1 ]0 f; y) C" B& |0 U) D

! ]) B7 O1 _  T: t! y2 F5 Y給你一個朋友的MSN,你可以跟他討論看看,
& D! w% _. ^9 J' `他本身是程式設計師,也對FC模擬器很有興趣。6 k2 J/ w7 k6 @2 m3 `5 T
+ N/ D5 w: P( D8 X
MSN我就PM到你的信箱了。, Z+ C, |+ L6 }9 q- F
  x1 G$ `% _9 Y
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
7 @1 |7 p  m9 s' g0 g# C呵…… 谢过团长大人~~
! K# N5 H$ p: ?3 C
  |! L3 @: V! [- F5 S/ U) w* \
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 9 D/ `/ _9 u  D5 `8 N
团长的朋友都是神,那团长就是神的boss。
( l+ r* B! ?! ?# {9 v/ x
哈 不敢當,我只是個平凡人,+ }! R' G+ F6 B, j! O6 u
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙7 C, b9 W0 X' A) [8 A
ZYH
6 Q5 q. d. @, S; [! Z6 V/ |! |* jQQ:414734306
7 o( ^, G9 `/ F; ~% W2 v& lMail:zyh-01@126.com. M; A  @, {5 D
! I  P; }% P2 n* r
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 9 }8 B" H, n' h7 s( d& ]$ ?) Q
再次对团长大人和悠悠哥的无私帮助表示感谢~~

+ u! q3 ]4 Q$ Z4 V$ D6 H不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-11-28 07:38 , Processed in 1.079102 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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