设为首页收藏本站

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

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

  [复制链接]

该用户从未签到

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

该用户从未签到

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

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
  h' A" v, I* C$ m+ t/ s楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
2 {; I0 ^' D, X; ]4 K这里有相应的模拟器源码,就当送给大侠了~~+ }0 @0 g7 ~" M! K2 R
http://kenkao.qupan.com/5096520.html
回复

使用道具 举报

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
: A( V3 ]' B4 g; {能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
' c! `  i3 q' F- ?8 \2 m/ J: v楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
3 @# t+ a  t9 n这里有相应的模拟器源码,就当送给大侠 ...
7 p" i: Z* _3 Q( X
聲音部分(Audoi Process Unit = APU):, `8 i& S5 A: i4 r' O
.\NES\APU.cpp0 c( [0 s7 v$ `* M5 P2 L. y
.\NES\APU.h) X: _5 g# H* j2 z, Z
7 Z: M8 \) o" Y6 }( B

  [$ h. g. \7 L. c+ r5 Z0 `8 c2 \影像處理部份(Picture Processing Unit = PPU):# {8 s+ i( ?* N! E- a
.\NES\PPU.cpp
7 x" T6 o" e: G* ?. B.\NES\PPU.h9 L0 e, `/ E  o

2 M( ?" u  K( K2 I. D如果原碼用C跟ASM混搭也不錯
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
; k- q3 ~$ ~. ~7 g0 u7 ~6 U(由于很多专用术语和算法机理都不明白,所以看不大懂……): }3 _$ D7 z4 v( J, m
//////////////////////////////////////////////////////////////////////////
- e+ V3 Y" ^) B# @/ t) @//                                                                      //
+ ?0 b0 E! S  L; ^' y& {5 [//      NES APU core                                                    //6 c6 m9 R5 ?% r7 X, m0 l5 t+ w
//                                                           Norix      //: J/ w( ~! l* X4 s1 h  a9 J
//                                               written     2002/06/27 //
" t6 U$ z  X6 {  e7 h//                                               last modify ----/--/-- //
+ h3 |4 L3 k- B) E9 i//////////////////////////////////////////////////////////////////////////
( J& C- N1 q9 ?#include "DebugOut.h"
& U1 g, l5 p& W2 S! r#include "App.h"
7 H+ V. L4 t& n4 s( \#include "Config.h"
- I9 B! R' p6 ^' K. }. c7 I  P( N9 H' i) b' u) \
#include "nes.h"
# K3 v7 z3 j9 g5 v$ w#include "mmu.h"( q! a6 Y0 X- l' m
#include "cpu.h"
8 N3 s% f6 |) ]2 N#include "ppu.h") e3 T$ A& S- p1 c0 N3 [
#include "rom.h"$ V4 @' q# `& C+ @; N
#include "apu.h"( U3 l) O7 v. o- H2 k1 s( y
; f# k* Z% x. g
// Volume adjust1 A( R6 l2 I+ Z; {
// Internal sounds
  k  q& \2 e& _, O/ V#define        RECTANGLE_VOL        (0x0F0)9 c3 b2 Z8 }& `+ ?7 u
#define        TRIANGLE_VOL        (0x130)
/ R5 ]4 j; b1 l" x4 m7 W' e#define        NOISE_VOL        (0x0C0); P9 a% t" ?$ D0 D/ e
#define        DPCM_VOL        (0x0F0)
+ N' M3 V# q2 I// Extra sounds
6 [0 I1 }0 Q% H3 G#define        VRC6_VOL        (0x0F0)
* \+ _' A5 W" s#define        VRC7_VOL        (0x130)
9 t& Z# T% w, \" b#define        FDS_VOL                (0x0F0)
* ^- x9 B& y  w: _1 ^3 {" @#define        MMC5_VOL        (0x0F0)
0 l  V; g- a  ~/ X4 b#define        N106_VOL        (0x088)
3 F8 L! A+ _' S' |#define        FME7_VOL        (0x130)+ O% t, B1 T$ i! k
( q2 ~* O, \1 t# F/ I) t& T; R
APU::APU( NES* parent )0 J- J# m1 v( H/ h2 P
{
; b4 a+ q$ l, ?, g3 R$ _4 V  v        exsound_select = 0;: N3 G  @- q) I! F- R  }

/ C$ n) i  `9 t* r. ^; ~        nes = parent;
- M7 F9 A2 `7 Q- k3 o' Q' z: A        internal.SetParent( parent );6 ]4 {; p. |' p" u# f# ^

2 R7 p1 j6 o6 E        last_data = last_diff = 0;  o3 M0 g, Q. `% V$ x: X

) n; r  b7 y8 t5 s- t" P! T5 c        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );( s+ ]. z- R; b0 G
1 m4 R/ a7 d, Y: y$ S
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );; y1 B+ q0 w/ P/ J1 D; u) H9 e8 N# G. F
        ZEROMEMORY( &queue, sizeof(queue) );' M" e; p' H# Q0 S
        ZEROMEMORY( &exqueue, sizeof(exqueue) );+ d  Q# t- X; K. p& l

) d0 a2 q$ }+ b        for( INT i = 0; i < 16; i++ ) {
. [3 `6 M8 [  C; V! U, I                m_bMute = TRUE;
3 A( z4 K- c( g2 ~        }% M* K$ I/ P! I' ?$ E" F# v
}
" e7 w6 ], T7 \* A3 ^) w5 ]
3 E3 U1 G3 \! l$ WAPU::~APU()2 }' m) B  E& g) C5 u7 n; D: N
{1 Y2 r( R9 V$ N) @8 W, ^) X8 ?
}3 F3 k$ ^6 P8 |; `0 x- v
- B8 ~6 B2 @6 v2 f3 b4 d
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
* \3 [, B( l% S% R{* E: N; b1 l8 g- y* o
        queue.data[queue.wrptr].time = writetime;
! p5 a1 @  t4 C% {$ _* S  D% i) h) z$ x) {        queue.data[queue.wrptr].addr = addr;
' M8 ?5 J1 u. e2 m        queue.data[queue.wrptr].data = data;
) U3 g' n9 c+ W1 V1 Z& q        queue.wrptr++;
* f& s8 x( f+ k  I* E8 d; X- K1 ]& \        queue.wrptr&=QUEUE_LENGTH-1;
/ x5 r$ j4 y- e  u$ L        if( queue.wrptr == queue.rdptr ) {$ Q& i. }( {& a4 A
                DEBUGOUT( "queue overflow.\n" );
3 o1 E5 w, G5 O        }
1 ]# |7 S$ G; ^}. N! o9 Q2 s' j  G7 q8 q* E/ {
8 G$ ]/ M6 @! T$ u+ J$ B4 y' a
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
. t7 F% T3 }3 `) w" x{
: Y" b- c7 {; B- N8 B8 x- U5 {        if( queue.wrptr == queue.rdptr ) {
- Z( j3 a3 \: n3 v" K! z5 l                return        FALSE;
, Q( R4 |0 m/ W6 X- i        }
- n$ G+ S  v3 H7 J0 M1 O4 B        if( queue.data[queue.rdptr].time <= writetime ) {
. N, K+ [! ]9 |- `9 R7 O9 c9 e4 K9 Z                ret = queue.data[queue.rdptr];
/ S9 J  V# Z) ^0 f! `/ ~; p                queue.rdptr++;/ @7 e/ Y, _  I. f
                queue.rdptr&=QUEUE_LENGTH-1;6 d9 C. {0 Q/ q3 F0 T) x9 S
                return        TRUE;0 D4 {5 ?0 m/ K0 k, t" X
        }/ M/ o0 K3 [( p$ y
        return        FALSE;8 P- D) R" q2 t+ N0 q
}1 e. K  s  }! r0 u
$ D7 K( \' T' H: j" o% b' F
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )- }3 l! ]- r6 v2 W; X' E& l, t
{$ o9 Q7 F" K% F4 X( J9 V
        exqueue.data[exqueue.wrptr].time = writetime;
: n" N+ u+ L0 F' l0 C        exqueue.data[exqueue.wrptr].addr = addr;% C7 U" _1 k# B4 C
        exqueue.data[exqueue.wrptr].data = data;
" d: Y. U" F2 `. n        exqueue.wrptr++;
/ k" ]: H" H( H) U  j$ _: q" |% }+ C9 `        exqueue.wrptr&=QUEUE_LENGTH-1;
7 O4 _6 K, n* M5 G. _7 [  F        if( exqueue.wrptr == exqueue.rdptr ) {) ?" Y: m7 A1 _- i$ _
                DEBUGOUT( "exqueue overflow.\n" );) {3 G; a! z3 M8 g! [7 N
        }# f2 m$ C  M- ^
}1 [. m) K8 Z  y- c2 v

- b8 `! c2 [9 a% |% Q8 Z: ^8 v  HBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )+ e  Q/ l" \5 v+ d6 W
{
3 U5 G- g1 V* ^: r9 l        if( exqueue.wrptr == exqueue.rdptr ) {: Z! v+ M  @& x- c; w
                return        FALSE;
2 W8 @+ F4 u$ {        }$ ?  t1 p5 L2 L6 M$ J; g' ?
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
3 ]% @- m' l# A! G0 x' y8 x                ret = exqueue.data[exqueue.rdptr];- Z7 `- T& b" @' J
                exqueue.rdptr++;
. t  T0 z: H8 E* F% T                exqueue.rdptr&=QUEUE_LENGTH-1;
: g0 U$ v! T' U! R  R7 y                return        TRUE;
1 t9 G6 k* o1 Z4 }9 ~        }! d7 s0 X# E* T- v0 L
        return        FALSE;
3 o" J5 }7 Z' S2 L$ k, b" b}$ L5 L7 R" F+ D) z) ]
/ v' G. C3 j, }4 O: c
void        APU::QueueClear()
: ^, @9 [6 l2 h( g{! p' `) V) J% J, N
        ZEROMEMORY( &queue, sizeof(queue) );# K4 g4 R: T5 a
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
% e- A) y9 O" q1 U  c! s}- `( v* |. @9 C& I2 \; o1 l

3 b: l; {6 s0 }2 z* y( f3 o6 P4 hvoid        APU::QueueFlush(). ^2 I7 l: X) A
{
4 V; c9 z5 u+ b8 I        while( queue.wrptr != queue.rdptr ) {" I/ W% X0 f) B8 E. [# P+ `' L7 Y8 w
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
6 U; L  |2 Y( ~9 J/ ?( ^                queue.rdptr++;
! T+ ?: O5 Q6 p/ H                queue.rdptr&=QUEUE_LENGTH-1;, m/ K+ ^8 _! D% P  b+ j
        }! F: {# @- f8 U( U+ d

5 V8 N2 L) k8 A1 G/ N        while( exqueue.wrptr != exqueue.rdptr ) {5 {, @. [* u5 N& H8 i# ?
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
% k  \  s0 D- [! y9 |! j8 ]# j                exqueue.rdptr++;1 @) u) n- D3 y: T
                exqueue.rdptr&=QUEUE_LENGTH-1;& k  o1 A; j( \6 Z8 h
        }
" @5 c: o" T4 l! O/ l}- P+ P7 ~. }- |2 \

, w3 d) }8 R% X2 k* \& A' Yvoid        APU::SoundSetup()
3 C1 [: K9 ^" {8 L{" P% i! O5 X- C. g0 u! z
        FLOAT        fClock = nes->nescfg->CpuClock;( l5 Z! w- w+ ?
        INT        nRate = (INT)Config.sound.nRate;4 M; S4 Q0 b5 G7 _, ^, p3 r5 P4 C
        internal.Setup( fClock, nRate );6 H0 o9 ^  G) M, [- ^
        vrc6.Setup( fClock, nRate );
1 E; V% c0 E2 T        vrc7.Setup( fClock, nRate );- m# @4 b/ e8 ?
        mmc5.Setup( fClock, nRate );
2 P4 y  y! w; I3 S2 A7 _: q! A/ c% p        fds.Setup ( fClock, nRate );- F- u' M+ v( g( |+ \+ I
        n106.Setup( fClock, nRate );" y! A! K  z  x
        fme7.Setup( fClock, nRate );
# {, f3 P6 c1 ]1 S) D# l; J}
) R; U6 R; _! T7 R* d( N) \& k8 j/ Y, z8 u2 j8 N0 ?! A
void        APU::Reset()
) Y) ]7 y$ k% h" P0 z3 y& s{; q2 p% h) C* C; w0 B1 ~
        ZEROMEMORY( &queue, sizeof(queue) );" F! k1 V! k# l2 ?
        ZEROMEMORY( &exqueue, sizeof(exqueue) );# o# p9 {. D( M/ P

) f1 r4 e. v- L/ Q9 l8 R        elapsed_time = 0;3 h7 ?$ D; _! T) S0 A
/ h4 Z. [, j# c# [% n: v! `4 @
        FLOAT        fClock = nes->nescfg->CpuClock;  I& E. f2 O$ D) g; q
        INT        nRate = (INT)Config.sound.nRate;3 {) j' J; }" j8 ]2 O1 Q9 Q
        internal.Reset( fClock, nRate );
9 |8 T* m8 \( r. k" ~. q' J  N% U0 R( @        vrc6.Reset( fClock, nRate );
) O/ I) X( r4 p" s. e3 r        vrc7.Reset( fClock, nRate );0 P4 t$ T' @/ o& E3 Y7 w1 V
        mmc5.Reset( fClock, nRate );# y/ R, W- z  R( m4 s
        fds.Reset ( fClock, nRate );1 ]) C- g0 w4 \" w" b
        n106.Reset( fClock, nRate );  ^  }8 g  u. ~% Q9 u7 T: N$ S4 ]
        fme7.Reset( fClock, nRate );
8 h$ g/ i  R# z0 w- Z, [- _
7 ^& w) r/ l+ P# f/ u9 P# {        SoundSetup();
& P" h/ X3 i* r! h7 Y}% k. u4 e$ M0 H) W. d; L# S7 A

, m7 X" t7 n  f* h+ r0 |void        APU::SelectExSound( BYTE data )
* a/ |, ?: d: h! b( ^+ V{
- g3 G  q6 ~$ c8 _2 |        exsound_select = data;$ v; p# F8 B. l) t& j* V1 _5 m0 P( D5 g
}
6 L1 z- q3 S5 x7 u
$ ^3 S0 _- \- H$ K+ c' i- A7 f* lBYTE        APU::Read( WORD addr )* D3 y" R4 c4 y5 [% o7 {6 T
{
) Q: C8 {7 D9 Q  S3 U2 D1 r7 g% `1 M        return        internal.SyncRead( addr );+ o. e  X* m0 R) M
}7 w% m+ x$ ?0 h8 T) }) u
; }' W+ P8 y! U  ]) [; H
void        APU::Write( WORD addr, BYTE data )
. Q3 F2 B; ^9 W/ z. r! P{  ]. ^0 t* @$ l
        // $4018偼VirtuaNES屌桳億乕僩
+ Y5 X+ u. J" I; ^8 V        if( addr >= 0x4000 && addr <= 0x401F ) {
8 ^6 }/ c/ L! L3 K6 A                internal.SyncWrite( addr, data );
* |% A% {: G9 A2 M) _                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
% A. I3 h/ J* K( N+ I8 L4 q, C- b) d        }
8 ], n0 H  K& l4 E8 T; _& M}# J( R* k/ I6 Q+ O, R8 U8 o7 Y

- [" s  r5 j  g$ VBYTE        APU::ExRead( WORD addr )
+ w& G- @4 S4 M{. `: i/ S, }  e8 p
BYTE        data = 0;
/ ?. Z$ |5 w+ @  L& G4 h
6 `2 s1 p1 f5 n3 p        if( exsound_select & 0x10 ) {
% w$ p) A+ {$ g; w                if( addr == 0x4800 ) {* f# {( S. j: E/ N5 W
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
" N2 _- O) I6 Y                }
3 s2 V) e3 `/ P        }/ o0 H4 X0 Q- F( C
        if( exsound_select & 0x04 ) {
- P( ?3 r3 s. N4 i                if( addr >= 0x4040 && addr < 0x4100 ) {4 K- R1 I+ [+ Y
                        data = fds.SyncRead( addr );
2 P) l5 `% u' m- z                }6 W$ g* a- c+ X8 w, @* F
        }
" l$ g2 G$ i0 j8 b0 A        if( exsound_select & 0x08 ) {
+ d) f) c# z( H; Z( P7 a) ~                if( addr >= 0x5000 && addr <= 0x5015 ) {
5 e4 D( i9 Q2 w; ?                        data = mmc5.SyncRead( addr );- ^8 |; N$ w  b# p  b. y. y2 p
                }
: P% [$ O  Z7 L        }+ T# x4 |: d7 Q) Q5 l5 i! {
/ Z" B% t$ N7 O# u4 {
        return        data;9 }* i; k" g, e9 T" a+ \9 T" a
}# }1 q! n9 D2 v1 O- E" V4 d7 I  S! [
* V# C1 h. q9 v) d+ Y
void        APU::ExWrite( WORD addr, BYTE data )9 A2 J. v4 ]3 b3 z- O
{4 R1 L" r9 w# Z/ I
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
' B, z9 }4 k( F2 C
/ `' Y% p( _" U5 h. K- L( n        if( exsound_select & 0x04 ) {3 c. M' r, h$ h
                if( addr >= 0x4040 && addr < 0x4100 ) {  d5 L! C, ~# J; I) X% a0 D
                        fds.SyncWrite( addr, data );
# f# u" _8 A% q& I# E; b2 }                }; S8 j1 ]7 e" q+ D4 o$ o
        }+ h0 m7 B* S- R. o7 a

( j, c4 }# h$ V3 w! x& p" b        if( exsound_select & 0x08 ) {
- l0 j2 q4 Y, g                if( addr >= 0x5000 && addr <= 0x5015 ) {
5 s  [+ Q) D: ^4 S" L                        mmc5.SyncWrite( addr, data );$ c; N, ]0 L$ a
                }
' t1 G! |. h6 c/ _2 F& `/ P        }
6 ]' H" T. S: W  B6 Q}  A) ?) t3 W; h( _9 E8 c2 ]
0 O0 e; C) o3 }
void        APU::Sync()) Q, P1 f' F1 a" D' `
{9 A4 p/ Q' T8 B( m) n4 Y" i9 M' u
}9 I6 V8 j+ Q5 ?7 u0 y' i  U

5 M' H9 K! E: R% k4 z2 h) Evoid        APU::SyncDPCM( INT cycles )
( ~% s8 d$ M! M9 ~9 L2 }# I3 W{# w: {$ V4 K: b! W, A' X
        internal.Sync( cycles );+ W8 M' x  `5 j# S; r$ [' k  u

) _  s. D9 L0 l) n& E        if( exsound_select & 0x04 ) {
5 K6 ?% f3 m5 R  p6 A9 ~' E                fds.Sync( cycles );1 O* o2 |! R6 ^& O
        }7 h1 b* c0 q5 U  u  h2 ^; @
        if( exsound_select & 0x08 ) {. O% q  g( }* ^: n" F9 A, m  Y
                mmc5.Sync( cycles );
8 E+ |4 ~* \$ e( b" M        }. F2 ~! c- l5 q% k, x
}2 \. A4 E! `0 z' p/ ^  [6 X
2 M6 f4 N4 x: B+ k) Y
void        APU::WriteProcess( WORD addr, BYTE data ): Y. P! @8 ^( ~8 J; x
{
: i  b) h4 N4 F        // $4018偼VirtuaNES屌桳億乕僩* ], G2 h) ?: r( i7 F
        if( addr >= 0x4000 && addr <= 0x401F ) {
' k$ R: K8 q4 p+ a! e0 a                internal.Write( addr, data );2 v& j$ b; v" v/ c
        }8 h7 s6 C2 H: ^4 l/ [
}
2 G) t, W; L# ?- y9 W+ H) u. P6 f& o8 g1 e  l
void        APU::WriteExProcess( WORD addr, BYTE data )
, b, m/ f3 }: x2 D{
( V: K4 z( T% A$ F' }        if( exsound_select & 0x01 ) {6 t) [5 _+ ^* f- O2 v% i2 w+ W' x' S
                vrc6.Write( addr, data );
" w& k; H" ^7 p6 ~8 g7 f        }
3 Z% u+ _/ k/ h% b        if( exsound_select & 0x02 ) {
# \, C8 E7 l- @& ]4 p6 q                vrc7.Write( addr, data );
2 ]% e; l# o4 z8 A9 Y- w        }0 v8 D0 e! }0 d
        if( exsound_select & 0x04 ) {3 e" F! S: {# S* u5 Y2 y
                fds.Write( addr, data );
$ S' u0 ^! j' x& E; ]        }; v+ q/ X. l1 H- o/ I6 u& `/ _7 u% R
        if( exsound_select & 0x08 ) {
+ ]3 W* V! t! j( L+ J- _1 d                mmc5.Write( addr, data );
; g' `8 {1 D2 x8 [) H/ V; r- U5 t        }( y$ |% k+ Z" Q' U$ q- w
        if( exsound_select & 0x10 ) {: K. \# S: j" x/ r! \0 q! p' W/ b9 S7 U7 F
                if( addr == 0x0000 ) {
. ~" \4 |6 Z( L1 T3 I$ ~5 c3 y5 \                        BYTE        dummy = n106.Read( addr );+ L& r8 C: w) e7 T2 I( J
                } else {& W" ~/ P' x4 n" j$ Q4 s# M
                        n106.Write( addr, data );: A  P9 b9 N. ^
                }
1 b& j5 V+ N  r6 k6 a4 f- q) S9 j! M        }; p7 O- w3 K" Y5 t5 k) t6 ^
        if( exsound_select & 0x20 ) {
) G: ~: t/ o. G: y3 ?7 S) M                fme7.Write( addr, data );1 o$ r; m( s+ s- u' m
        }
% t9 L$ K5 ~. C- F- s+ D6 l2 y}7 }3 J7 A9 c; ]/ g) ]

$ W4 B% N. l$ G+ f' |/ Bvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
* `+ W( F4 s3 T  ?3 c{# o" H1 x. T$ T6 M- Y  k
INT        nBits = Config.sound.nBits;
! N' B) N, o( b. W4 E, _DWORD        dwLength = dwSize / (nBits/8);
. l5 _: i% L$ n( [# iINT        output;: h: b& b0 E# p2 L& B
QUEUEDATA q;9 s* e9 _4 b6 q: g8 n" }. t; \3 A
DWORD        writetime;
: Q1 q: x3 V0 b: c; E  ~
( u9 l& F' c& C' W! Y( C3 QLPSHORT        pSoundBuf = m_SoundBuffer;
6 t, r; v1 z! e  `* g4 uINT        nCcount = 0;
2 a% ^& J( @5 x$ S$ A, Q! U3 X! ^4 `3 |
INT        nFilterType = Config.sound.nFilterType;
: [/ M  s4 S& |, s' I9 L) k# E) s' _& ~: j
        if( !Config.sound.bEnable ) {
  X; H7 m( G4 ?                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
% p: c; R' X% D0 Q, C! u" w                return;
, a1 o/ x0 V; E; K- n        }
# J2 i# u6 r% [& O3 ^( H1 W7 k
        // Volume setup. G. \! Y  b, H. O* `+ Z1 X
        //  0:Master
5 O" A2 Y  Q* E4 P. a        //  1:Rectangle 1) @* b0 j- z# \/ m
        //  2:Rectangle 2
. a  \/ F( B9 [! L5 h        //  3:Triangle
' a: L) {6 m; u$ Z        //  4:Noise
' n" N! n9 E$ @8 n# A2 I/ g4 p5 C        //  5:DPCM; ], ?8 }8 f# b& r3 k
        //  6:VRC6
& w8 L! R! E' E* w/ R- l        //  7:VRC7
: j/ v2 C4 M$ Y# L; |        //  8:FDS& b8 E8 g- }) g3 R
        //  9:MMC5
1 t* |+ }) X# S0 q        // 10:N106# \# J/ d4 P9 P4 J" i
        // 11:FME7
, Z3 z, j7 [1 i+ G# X, T        INT        vol[24];- @5 @) I+ n3 `" _% y$ |- a2 q  b6 |
        BOOL*        bMute = m_bMute;
. i8 }$ i; W3 c. G! v        SHORT*        nVolume = Config.sound.nVolume;3 {5 |9 y$ Y/ h) `( g
/ @0 X' X1 V( r- h( E
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;! d4 D. w! j) k
, y6 t3 D% n/ h6 N
        // Internal5 F8 t9 q, U2 i+ \4 S
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;" {! w9 q1 [! P' \7 d, W4 W
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;% ~1 A' b+ b4 P+ @
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;4 y3 v& j) b$ Z$ }& {' i
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;8 p! l2 t/ X/ f' J( }8 j
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;* R; x% ?; G( M( r
6 F/ r' R; }: j5 l* G
        // VRC6
: P/ u2 N9 k& e; x* t0 n7 f        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;- s/ m: I$ v" M, z; a
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;# j* T  Q3 J7 q1 T+ c2 r! F" W
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
+ A. b& |6 j2 g% D2 n, ?4 ^. \, _0 q$ S
        // VRC78 y  {4 K. g/ |( O
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
- \8 R3 b6 e' v1 ^' }7 I  S" p: j0 ]- b6 P% K
        // FDS, W' K# d4 I6 ~( D  u
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;! x1 f. \" k% }! V" G. y1 m

# C: K6 i/ z- H7 D& R' d        // MMC5
- o, H$ Z4 I# g( K8 y, @+ Z- f% C        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;3 V( E) T" y% ?" y1 g% }- H% A
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;% b! J  r# Z* g3 V* z4 x
        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
% P. `9 u' g& y! S
2 j7 Y' m) r, r7 }" Z        // N106
# r) {5 i- F' g( ]" T6 [        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- @5 ~5 {& R- j1 M$ |# U        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- h1 u  P2 C: K0 c, O* P( q* d4 e7 \        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; U& O+ F& h. o  W/ U" T# |
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;6 [1 P% P& D4 N0 t
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 S6 B& Z) R! e
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
. V6 N1 ?* }$ s+ y: d        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
# h( `1 _# d! }, \7 {- O& {: b* B        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;% O6 }3 Z1 w, ^5 b# I7 V
  e7 w  i7 M4 F4 M2 B
        // FME7
; p# {7 R  Y$ y! G8 K4 J        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
% ~, q; g6 u7 l# f0 ]# ^9 o        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
  H1 I: H" o% R1 \        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;6 V- H! C# ~- X. U6 R

; ?5 X+ t: E' H9 o  h# A//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;  ?7 o$ [; u* D- I: w8 R( g
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;* o& P& R' @, V$ ?& s8 j* ?7 U. i
/ C$ W- c6 K8 m9 D
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
8 i7 m8 m  M" R( `% d" f        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
7 q  b- H+ q" t! g+ ?                QueueFlush();9 M% ~- ?) n8 G9 g
        }  W$ q6 g3 c2 o

* V8 c3 v5 `- f. `0 l        while( dwLength-- ) {
/ l- q, @0 ^* a! k$ Z3 v                writetime = (DWORD)elapsed_time;' {( S& W& d$ H
3 p3 M! J, @, c2 E8 i
                while( GetQueue( writetime, q ) ) {8 U' b9 n5 A) @
                        WriteProcess( q.addr, q.data );! _$ p9 @7 Z2 k2 r, f& l
                }
) H8 X7 q# K5 G1 z$ Q
/ U' F/ D7 R: D  X' `. \                while( GetExQueue( writetime, q ) ) {' b( x9 {! o) I. r' K3 V
                        WriteExProcess( q.addr, q.data );9 w. F4 A4 P+ D& x. |0 w$ Z! d: ~- F
                }! u1 E: l4 j) Q$ p3 j! p

5 R: e3 P. x! S" O7 |                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME70 T, q* W% X/ w: g  X
                output = 0;
1 T# V: \4 S1 a6 t8 Y                output += internal.Process( 0 )*vol[0];# m3 B5 O5 s" d' N9 i2 P" U8 R! t4 H
                output += internal.Process( 1 )*vol[1];8 C9 v1 ^, S( m
                output += internal.Process( 2 )*vol[2];
2 u5 o# g" P) l4 _                output += internal.Process( 3 )*vol[3];
  v1 d. i6 |5 h3 m                output += internal.Process( 4 )*vol[4];& u8 x% b7 u/ J" m: t3 j
& M+ [6 c; J, C' |& u1 U
                if( exsound_select & 0x01 ) {5 _" ~! s: Y' Q0 P# M
                        output += vrc6.Process( 0 )*vol[5];0 D3 H4 o3 _- U: P
                        output += vrc6.Process( 1 )*vol[6];- T. `5 i' l0 m3 }( u  Q, r
                        output += vrc6.Process( 2 )*vol[7];
4 P: F0 L; e& E2 T! W# m& `# s4 P                }2 R$ ?3 ^" X; U) U1 v
                if( exsound_select & 0x02 ) {
9 v3 Q  {5 i* q+ m' Q3 D% @                        output += vrc7.Process( 0 )*vol[8];
3 b8 _; t: z' ]' x" b. u5 H                }) m4 B$ G" x' V
                if( exsound_select & 0x04 ) {; s( A+ O' ?8 j8 X3 }# W
                        output += fds.Process( 0 )*vol[9];
/ _: w4 s; X5 |& h: j# A1 H                }
9 h; C" _9 C5 c2 A3 C                if( exsound_select & 0x08 ) {4 v1 h" M# E) z$ {7 t8 o* c2 l
                        output += mmc5.Process( 0 )*vol[10];
, B' b, A9 e- R* y' n2 r7 k5 g& a                        output += mmc5.Process( 1 )*vol[11];1 S. t& D2 [2 L  M
                        output += mmc5.Process( 2 )*vol[12];
/ N# y4 ]8 o* U4 [                }: a/ z; j, e) J" @7 x
                if( exsound_select & 0x10 ) {  [1 Q+ h$ [6 V, q% i
                        output += n106.Process( 0 )*vol[13];
5 a2 N4 g0 L4 }                        output += n106.Process( 1 )*vol[14];; U, p+ U/ `' i
                        output += n106.Process( 2 )*vol[15];
1 L. g4 N# x# k                        output += n106.Process( 3 )*vol[16];
+ a1 d/ S9 V2 M, z                        output += n106.Process( 4 )*vol[17];$ Y. L  n2 q4 m9 r) e
                        output += n106.Process( 5 )*vol[18];" D% g# j1 d+ `. `- @3 g
                        output += n106.Process( 6 )*vol[19];0 y5 }0 M  E, f9 N. u5 `+ Z* O& M- B
                        output += n106.Process( 7 )*vol[20];
8 G( p# ^* T2 {. Y) M7 j                }
. @. E: Y% ^) v, V& f" H1 }+ ~! G                if( exsound_select & 0x20 ) {
2 }+ z* R$ ~8 K1 C                        fme7.Process( 3 );        // Envelope & Noise8 c" L  |/ J$ z# `( j- ~* U% D
                        output += fme7.Process( 0 )*vol[21];% O% n0 b! \' B8 k1 }
                        output += fme7.Process( 1 )*vol[22];. _9 ~) e- j' C% y! G! a- u9 D/ K
                        output += fme7.Process( 2 )*vol[23];
" ?, H5 m0 f6 F2 q2 i& z                }
7 Z# T& e6 H" H2 p  s& o" n* ]
5 W0 P, o1 l# O5 W+ z8 ^8 K8 A                output >>= 8;7 Q, t, N6 q' R+ p$ d# c
  Q. P) b9 u6 e# c6 y: u$ y
                if( nFilterType == 1 ) {
$ }1 X& N$ w8 U. a3 N7 v  S1 Q                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
! d5 C  u4 a) d; j                        output = (lowpass_filter[0]+output)/2;' Z4 b" l6 E0 l0 \% e2 ~
                        lowpass_filter[0] = output;
( L+ t4 v; Q- }! D$ B                } else if( nFilterType == 2 ) {
$ C; v# A& v! f3 Z- ~                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)! Q/ o* b+ g$ {+ B! |% L
                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
$ ]) z' z; P) C8 Z! _4 @# Q                        lowpass_filter[1] = lowpass_filter[0];
6 W  ]3 |3 E% \  ?& c8 j+ R                        lowpass_filter[0] = output;) H' ^. q  k% H6 K% M3 o4 j1 o
                } else if( nFilterType == 3 ) {
8 R5 m5 w1 w2 z1 q4 \+ P, A                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)8 z2 u/ N, X' T$ G! b
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
6 X8 R1 R( A" c0 y7 u                        lowpass_filter[2] = lowpass_filter[1];
# Z# t; i7 h) K5 [                        lowpass_filter[1] = lowpass_filter[0];2 R3 {( t" a9 Z8 N) I+ p  M; ]
                        lowpass_filter[0] = output;
9 o- B* C. L. w1 |; z: }# |                } else if( nFilterType == 4 ) {
* f6 U7 D+ x3 X, Y                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
% n. R, k3 u  X3 K                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;8 }* n/ p: ~9 K
                        lowpass_filter[1] = lowpass_filter[0];# B, Z8 M' y1 I7 [
                        lowpass_filter[0] = output;' z' m& ?# s, q8 H  D& Y$ U
                }
2 Z% K/ y  e8 E& e1 K" e, Z0 T
#if        0
' l' F0 G# b, R% Z! D                // DC惉暘偺僇僢僩
, {! D8 ]4 F) @                {; g% K0 I3 q! j: g$ s; e
                static double ave = 0.0, max=0.0, min=0.0;
6 E& e; |# l( @                double delta;; j  `6 }( M" \- w- j# h
                delta = (max-min)/32768.0;- T6 s- ~3 I$ k8 u$ Y, Y3 B9 {
                max -= delta;6 e" g- O5 s& g% [  J+ {9 \
                min += delta;
; H/ j6 A# h+ q3 D7 U4 j                if( output > max ) max = output;7 N, j: e* t9 r: r
                if( output < min ) min = output;* A: A1 m& r% [4 @+ `) x
                ave -= ave/1024.0;
  P% C% V9 L, A  K# N/ ~  ?                ave += (max+min)/2048.0;& ]3 }7 f! S' I+ p! C0 @
                output -= (INT)ave;. f9 ?+ l: j" k# T: Z# w7 V1 a
                }
% g! C% X! T& U/ y- F+ r#endif" F$ _. f( X& I& y' h( }2 c# Z
#if        1
4 N2 c& b) ~1 o0 t4 A4 v3 i0 |                // DC惉暘偺僇僢僩(HPF TEST)
" ~+ l( y+ g! H& V8 u  w* ?                {$ p6 O7 v: i: H/ M1 I
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);' l8 e/ T& k9 q4 j
                static        double        cutofftemp = (2.0*3.141592653579*40.0);) [) G" l& L. m# u! ^) c
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
2 Q5 g0 \3 v4 s5 d5 X4 z0 f: y                static        double        tmp = 0.0;
8 m$ j+ i% w. N4 C1 U; b                double        in, out;
/ v6 |; k) h6 e# f" p+ h) E2 y, i% |* D% {! f7 {2 ?1 e
                in = (double)output;7 R1 `7 ], l2 A6 L7 f
                out = (in - tmp);
& u) D) P2 L$ G# R% A                tmp = tmp + cutoff * out;! s4 O0 B( L4 h" m7 H3 Z

! ?! m3 n0 q! J3 v4 [                output = (INT)out;
( y, g7 f/ z# o0 d                }
* d8 i$ \. y. c# f+ ]/ ]#endif* ^+ ]0 s* I' U5 l$ g( D% {
#if        01 ^8 |$ c' ~6 x* H
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
% o- v" C3 p4 e, F7 }7 u; ]                {9 u( J$ I3 ]. }- Q, Z, j  }* i. S
                INT        diff = abs(output-last_data);# X8 o! n6 B5 s: R" S  L
                if( diff > 0x4000 ) {0 Y$ L* `5 J  u4 ]: s9 s& S
                        output /= 4;: h5 l$ _2 A4 m9 u6 s4 N
                } else ( ]+ V( Y4 y' D2 h
                if( diff > 0x3000 ) {9 b" j2 r. n# I& U
                        output /= 3;& n) H$ j) u& w8 L3 r$ v
                } else
/ r+ v( c" t- k/ A: M' ]2 _                if( diff > 0x2000 ) {
; z' x  k6 N# O, V3 i- F                        output /= 2;3 S/ f1 j' a* |" J! r
                }
, C0 ]/ X6 C. U3 L6 j                last_data = output;4 J* `/ ]* z6 r8 o- {, @
                }
: l& f# l# [3 U2 O6 j#endif8 D/ c5 r6 i1 H4 F, H( G
                // Limit
! l% q: C  G7 d  {! L* i; {% J                if( output > 0x7FFF ) {
; H5 W0 h& l, [5 n& Q; A1 Q                        output = 0x7FFF;
/ B' k. n( m6 n, C                } else if( output < -0x8000 ) {
5 v6 e8 r* `% o2 j9 \" Q& R                        output = -0x8000;
& K8 k) `$ ^: x, i3 K: N7 z                }
( e. n+ u6 ]* j% f% C( i
; ]: ]0 v) |' s2 y. q4 n6 F                if( nBits != 8 ) {! K. ?" [6 W- |. J" ?! f: o
                        *(SHORT*)lpBuffer = (SHORT)output;( Q( i6 k/ f  S" D1 P
                        lpBuffer += sizeof(SHORT);8 F3 D$ \% {. w5 T5 l
                } else {2 J, w" ~( J( L% K, P5 c6 {
                        *lpBuffer++ = (output>>8)^0x80;5 }; B6 d5 r, o
                }
% T) k) W/ W! j% q3 r2 M
2 l& [2 |9 A2 A* N                if( nCcount < 0x0100 ): t. l! d/ g' T, B; G9 Q5 N# f
                        pSoundBuf[nCcount++] = (SHORT)output;
7 J! B* A$ j& k0 X2 G! Y- U) `9 t
/ N& a8 ]/ l' f  L" n: S3 {- w/ ~//                elapsedtime += cycle_rate;
9 p& ]8 @. `- c5 J6 {& `; {, G                elapsed_time += cycle_rate;* {; ~0 I6 V$ o9 B' E6 Z- Q8 |% N1 a
        }/ H; p; y  `1 \- \

) g' R& p2 Z  W3 c9 a#if        1
8 t1 x* G' [* `, a        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {- _2 V8 b- B$ B; z- h  H( u
                elapsed_time = nes->cpu->GetTotalCycles();7 v- J, d  p) L) F: f4 o& P
        }1 t% A: {/ k1 b1 B, {; P
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {. R3 c* C4 z# S  A
                elapsed_time = nes->cpu->GetTotalCycles();
# o/ B) \) w! j! u" M$ t4 ]  S        }
  J& Q( X  l" [: ]6 ?# ?" D0 q. O#else
% ]$ ]- ~0 U6 s* r        elapsed_time = nes->cpu->GetTotalCycles();2 X# Q* L0 @- g' C# H+ I9 o- {3 }% U
#endif
# \% {) J. |$ G- N: {. i& U1 X}# ~: q9 `6 g" U9 F- L
; T  M# ~) B4 j- W* R
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)6 p8 P! g5 o! `7 o  y0 }$ d
INT        APU::GetChannelFrequency( INT no )
% \. }9 z, k2 K5 J# ?- P{4 O# R! y4 m) l8 q9 u- s! {
        if( !m_bMute[0] )7 j5 ?0 C4 E8 O+ N; E5 I7 x! y
                return        0;
/ D( s# f$ ~6 o+ Y" h2 H2 R6 Y
4 s$ t" j" U- K: T3 U$ c& D. E        // Internal
/ g' V/ s% R- i- |! C        if( no < 5 ) {. z' A  U, q6 b0 L, {
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
* O2 c) W. Z! W6 L% ~        }* E; e# w1 |2 L! b3 l) d8 w9 c
        // VRC6% ]' W! S8 I+ w4 N0 W
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {! b& h4 `: {% C( M8 _% q9 [
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
+ q& j7 q1 k2 O& z: A        }
9 J- s, L  k+ u        // FDS8 H# X, t, p, C- E; B7 F% z* v
        if( (exsound_select & 0x04) && no == 0x300 ) {
& O% s/ o6 U+ B4 @' t3 ?                return        m_bMute[6]?fds.GetFreq( 0 ):0;
0 P5 L, L, A6 a2 {' R        }
( g* Y- q# d* _; d7 `9 X        // MMC5% S# k* d, Y; [8 X0 [# X9 W: D# a( i
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {8 T" \) O  z+ x8 @- M6 M& S2 S
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;, G7 o. `" J3 P4 f3 D1 d% C7 M
        }
4 ~% G, ^  ?5 X7 i! J% v        // N106
/ Q6 x0 b+ b, z7 _1 I8 V8 G& }        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
1 x9 ?/ ^" C7 O  Q                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
5 f% t2 p1 M' }& l        }  ~0 u. y* H' f& O
        // FME72 @- A, ~7 s7 q& q6 q$ T# g
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {6 x5 f! z; y5 l7 i2 G" P+ u, \
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
- u' N, m9 D; n        }2 Z' F; W9 D- l+ p! G: Z) T! u$ j
        // VRC76 r. ?2 @) M4 M  \* J( B8 f$ X! @
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
! `% w- ~) f/ M6 N8 x                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;: d  Z, _: ?4 t: k
        }' ~: I, J' y! m& [2 L, {' S: f
        return        0;
* B8 ^" m9 y0 O}. o5 Y. J& K3 S

7 L: D; ?  H8 m// State Save/Load- v0 _- z0 L' N4 ^: R# w
void        APU::SaveState( LPBYTE p )
/ g5 i+ I- D  ^- l2 I9 \{
. T5 H- l" N3 _8 s+ I#ifdef        _DEBUG
2 z4 r, }1 u  \3 @9 ELPBYTE        pold = p;
3 h- ?6 n* r: D( \3 m0 x: ~' c9 a#endif% J- d  y% @9 o4 d
, I7 S8 i& S) O, \
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞4 _+ B3 u/ G  S( D
        QueueFlush();+ v' t" v  ~( p" j8 G! n  u
) p6 r8 X4 U6 p9 q
        internal.SaveState( p );% `3 z2 R4 i/ F2 Q& U; s
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
2 M% X7 s- V& h: S' k5 g7 `, V6 R2 w2 I7 ~4 T+ o% ?4 G
        // VRC6/ `7 `1 c7 ^: n2 s% ?) Z$ w
        if( exsound_select & 0x01 ) {
  m6 X! y2 p2 a: t' s0 J                vrc6.SaveState( p );
9 ]3 s& O4 S$ V                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding6 u# ^' O$ G% S
        }! ]0 M- Y# f" C, J9 Z) K; I
        // VRC7 (not support)
* ]+ z. g, o3 o        if( exsound_select & 0x02 ) {
& K% d& A6 m5 F; X- [4 B  h6 b; X                vrc7.SaveState( p );5 n8 E4 u6 L" z8 c' i$ H1 {; Y
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
+ c! A- `( u& q* u1 o8 Y! F        }. E0 t1 ~0 n& H+ e, p5 C) o
        // FDS7 s9 x- G0 H( ^& X- A  d
        if( exsound_select & 0x04 ) {
( w  f5 b; Z9 x' k' _6 m* b; m                fds.SaveState( p );
% z) f+ }+ [) M2 q' k  P; }$ f                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding/ }# Y. ^$ {9 Y: O- w
        }8 h* q: ~* d- j
        // MMC5
% C% _; S3 y9 B) j0 z        if( exsound_select & 0x08 ) {# M6 i: o) y' u& p1 N& _+ g
                mmc5.SaveState( p );7 D0 d( U+ t) U  ^  V+ _0 j
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
/ [: d1 s0 o( C5 H5 c4 r1 O        }
7 @! d% t5 V$ N7 j3 ^2 T        // N106
; e+ P5 V4 s! e# c* ~4 c        if( exsound_select & 0x10 ) {: u$ g" w4 r! [0 L5 C
                n106.SaveState( p );
0 W. X; X0 v5 Z/ G$ c( k                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
& {2 M4 K! |9 H. Q$ [2 ?( B        }" Q  A2 C0 z* E1 S; c) i
        // FME7
/ ~4 c1 Y$ ~7 y9 Q/ B5 A3 k        if( exsound_select & 0x20 ) {' |- ~* d) M. N& L6 z
                fme7.SaveState( p );
9 L$ v8 [2 R% i# I1 b& m- ^                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
- f( i* l$ @0 J        }
4 t' D, k4 a3 M" i7 q
/ e; z: @  h' y( L; `* E& V#ifdef        _DEBUG9 q8 d% o+ i5 e
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
4 a) L/ `# \" K. m% B7 y( ]#endif3 {$ Y$ \) I0 s- F# q8 |& b
}; u, \6 ]1 m% T4 d- Y3 m! D

9 o/ H. u7 D  r: Y" Z% v( S8 fvoid        APU::LoadState( LPBYTE p )3 i  g# @( r/ y/ B, k) a
{
5 ~3 r/ B1 q% Y$ ]        // 帪娫幉傪摨婜偝偣傞堊偵徚偡7 ]3 P' p1 t! D/ i
        QueueClear();
: X' i  j  g/ }; }+ O6 w- E4 P# Q& K# S# L4 O  q
        internal.LoadState( p );
, ?/ f! Z4 ^+ ]0 l9 n8 A0 t4 D        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding9 n# q/ A6 k4 r: U9 w; {# |9 w
' r9 g; Q. C) M: c  p: i0 B
        // VRC60 h, _' @) t3 Z0 ~0 A
        if( exsound_select & 0x01 ) {
, q1 v: L5 Q0 p5 `( p7 q                vrc6.LoadState( p );  ?$ l) }# a' m# U
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
7 w( H3 W& @/ N9 o7 g        }
2 O  Q1 A4 g, K6 ?        // VRC7 (not support)
$ e" r; Z, G9 J        if( exsound_select & 0x02 ) {6 m# f4 R1 I2 Z! J8 C; e
                vrc7.LoadState( p );! f7 K  u& t# x2 d5 f0 M9 `& F
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding$ g. q' U% i, `2 N4 ^: w
        }& o, G% K7 I8 t  U) s3 C* p
        // FDS
) H2 C% v3 H5 \$ R        if( exsound_select & 0x04 ) {; }2 b6 G# u; e
                fds.LoadState( p );
: I$ h/ N+ n9 o* S1 ~                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
  A/ @  G' c( |  N9 M8 W- c        }
- K, J: m6 N: [) K1 d& ], d' i        // MMC5
8 g( {! W8 q: R& {' Z- d8 ~        if( exsound_select & 0x08 ) {% g7 s/ _  H# d7 c( F3 i3 e
                mmc5.LoadState( p );
: V2 o- ~: v/ h+ z8 ?! w5 o                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding% s8 j4 m! g& c& G  s
        }
1 E0 F- P! \% u* M1 H  I# C        // N106
7 X) o  x. [1 y) g% l: t( |! w        if( exsound_select & 0x10 ) {9 k! W& Z& B2 A$ |- }
                n106.LoadState( p );( d! `* Y4 v$ H$ [$ A, z
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
* {3 j: w- \1 o3 c        }
3 T9 S# S( i& G7 _- y/ G6 W        // FME7% T$ ~& c8 `% ?" _: [+ u
        if( exsound_select & 0x20 ) {$ A! x4 k9 V; u" C  U! P8 i' O
                fme7.LoadState( p );
% I& R3 I' h+ o' \; W5 y/ d, P                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
" b( H5 g  @; D        }
; m# z% \7 g$ `8 h  H( w}
回复

使用道具 举报

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
8 D! L5 L2 U9 Y% @! V" ~可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。& B. w* d1 j: ]6 n0 Y
感激不尽~~

& r' q' a4 g5 t& E2 k. g恩 我對模擬器不是很有研究,
$ l! ^+ o* a  b* R雖然要了解源碼內容,可能不是很困難,
$ C- y+ {' P' c$ e$ ^不過還是要花時間,個人目前蠻忙碌的。
  D2 M1 f7 s# r: \  |* L7 z! N- I* F2 v2 h" [+ L" g
給你一個朋友的MSN,你可以跟他討論看看,  n2 F: Z# H6 b: Y! v+ c, n% r1 g3 F
他本身是程式設計師,也對FC模擬器很有興趣。
: B! r) }2 M- J: \& T- l1 }9 n0 R+ g; |# ]; t+ J( d: z4 C
MSN我就PM到你的信箱了。
* c6 i9 B7 P- Y4 c8 a6 N% l9 Y. T. H  }* N
希望你能有所得。
回复

使用道具 举报

该用户从未签到

 楼主| 发表于 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 发表 ! ^& z1 `% @3 u0 u0 c
呵…… 谢过团长大人~~
# p, u4 s) o( g* E/ j

9 g* @0 `9 M' D1 P& |) j& W哈 不客氣,算是順便幫他找個伴,大家可以一起玩。
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
) }0 c) o6 P$ X4 Y团长的朋友都是神,那团长就是神的boss。
8 [2 T, S# w+ @3 \
哈 不敢當,我只是個平凡人,% j! Y0 h% ?0 V
要吃飯喝水,光吸空氣是不會飽的。。。。 :)
回复

使用道具 举报

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙0 h- z+ w: T' R" h
ZYH
( ]$ ~  B% w. V$ F* n! h* NQQ:414734306
7 @$ Q( w# p1 p( \( w, ^Mail:zyh-01@126.com
5 n: {( a  x' @9 l4 Y; q6 n# G6 D+ a) |& d/ f4 y
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的
回复

使用道具 举报

该用户从未签到

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

使用道具 举报

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 % Z5 h1 C4 A3 k* u/ k! }
再次对团长大人和悠悠哥的无私帮助表示感谢~~

9 E; `- ^1 ]' E5 o" f不客氣  ^_^
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-4-6 18:09

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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