EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。$ l$ D  X$ U6 Y3 s8 h, o
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~  w7 S# ^7 F: M# r6 r, p' R
这里有相应的模拟器源码,就当送给大侠了~~
- S% \; p# c! n, i8 p; shttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 $ F6 t# |+ T9 ~1 _' W/ o" o9 E4 M3 P
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。. w% @( k  F% q. F
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~0 Z, o$ E1 {, f' Z& Q) V
这里有相应的模拟器源码,就当送给大侠 ...

4 V1 |- j; n- t聲音部分(Audoi Process Unit = APU):2 O' K2 r, M5 a7 t7 m9 ~' g
.\NES\APU.cpp
1 d/ a! U7 |+ Z" ~- i.\NES\APU.h9 I6 q: ?4 E) y2 N: x" c# [
3 t0 ^% t0 H( \) F' v+ ^7 p" J
9 j. M, k7 B! D$ X  z1 y
影像處理部份(Picture Processing Unit = PPU):* @- b7 O0 z2 M3 J+ [* \& @
.\NES\PPU.cpp* l. K8 V% j1 ]9 r& @$ z0 O
.\NES\PPU.h
0 m6 e4 ?; P/ K6 T8 i+ s2 m* b4 l/ ?* r; p) c; z  p
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
4 ~  c! a3 n' B7 F(由于很多专用术语和算法机理都不明白,所以看不大懂……)
9 T4 \' t/ N; ?" A//////////////////////////////////////////////////////////////////////////
$ S: _- W* a7 ?5 w! R7 i3 \//                                                                      //$ b! g4 n) t' x! T9 d
//      NES APU core                                                    //
; o( f5 I+ r0 l$ c- B//                                                           Norix      //5 v3 B4 Y8 D+ v' [
//                                               written     2002/06/27 //+ i5 h; k! Q& a. f3 A  ]0 S/ h+ Z, V
//                                               last modify ----/--/-- //6 _! p0 _& |& V1 P) c/ `
//////////////////////////////////////////////////////////////////////////1 I/ u, j0 |$ Y. y) Q
#include "DebugOut.h"
( ^+ G$ s! y: U#include "App.h"
1 H/ E# t+ A: U2 d#include "Config.h"
2 |+ e& U, T8 r  v1 ?; G+ H9 B" v
#include "nes.h"/ [% ]' {/ \, E
#include "mmu.h"
% _+ w5 ]' u2 q  y1 t  y#include "cpu.h"
: D$ H+ t+ w" e* l9 O; o#include "ppu.h"& T3 p- Y, k. `; C
#include "rom.h"2 ?& {: u+ K7 A3 u9 V$ [
#include "apu.h"
8 T6 p* k4 U" M+ d
* [! D! T0 C. \- w) s. D, S// Volume adjust
% e: v; F" {/ @# k1 G// Internal sounds
( M+ K9 d  k5 ]8 z#define        RECTANGLE_VOL        (0x0F0)
$ N. I  V2 C, J! k( x  k" V#define        TRIANGLE_VOL        (0x130)
: {  v2 D# w$ m2 ~( x#define        NOISE_VOL        (0x0C0)9 O, r6 w8 f9 @
#define        DPCM_VOL        (0x0F0)
; y& q; i1 a' X: S; \4 H1 G8 H: t// Extra sounds0 d. f3 R% d6 Y2 b; n
#define        VRC6_VOL        (0x0F0)$ b! {# a. L: T
#define        VRC7_VOL        (0x130)
0 m5 S+ j+ g7 f5 O2 Z  u1 Y) Q#define        FDS_VOL                (0x0F0)
. x$ v4 \- o% G6 Q- Q' S6 k#define        MMC5_VOL        (0x0F0)
9 Q. S; c5 G0 a; p0 |#define        N106_VOL        (0x088)' m1 T7 i- m# t2 ?) y. s/ g! \# f
#define        FME7_VOL        (0x130)5 e7 E% I) a/ c8 a, Y

7 o* C% z4 T' W( DAPU::APU( NES* parent )
( k1 x! f# ^' i! h3 w2 e5 z{0 x7 \" E$ E3 n
        exsound_select = 0;
4 T! E8 Q) ]8 h$ H2 v9 K3 C& E3 n& @2 B
        nes = parent;, M" f8 U! l! q  @& g
        internal.SetParent( parent );& ^- w: a& \# ^5 V
" L. U' q/ ^  x! ?- k' c+ D- l
        last_data = last_diff = 0;# r7 Q* |' |& C

" H8 d# Z! U& F7 ~( ?  r        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );9 [7 f- T* |) H8 T% j9 C- I6 i
& L+ [- h( X# N  Z1 g0 d
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );8 n* }) R8 A# j
        ZEROMEMORY( &queue, sizeof(queue) );' B" U: f5 ^) [
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
2 O6 d2 j- j7 e- B/ G0 F
7 H( P3 }# a7 @, a% @        for( INT i = 0; i < 16; i++ ) {
( |$ E2 L" {$ J9 D& @- h2 ^4 g                m_bMute = TRUE;
2 U' g* H/ A' v0 K: r! H# T+ O9 G        }" ]) ^3 }0 s, S+ P) f* e7 |" d2 ^7 s  m
}' ~, D# g4 ]3 f- t( R
6 S! a4 O( N! {4 r2 l, M
APU::~APU()
2 p# c" n8 X( R+ B{
) x1 p$ Z, S( W8 t}& _' e# j& ]1 |6 {0 H
* `: `: \3 N6 r3 {% P3 S; K
void        APU::SetQueue( INT writetime, WORD addr, BYTE data ), s' }7 j3 A5 v4 I! I8 A
{
) I0 q# C: d' |  q& H        queue.data[queue.wrptr].time = writetime;
2 N6 o9 _6 A1 E8 l6 R0 b        queue.data[queue.wrptr].addr = addr;
; m1 x- X) ~% V2 u        queue.data[queue.wrptr].data = data;
7 N' I+ q% J/ @! m        queue.wrptr++;. b8 ?5 h* v& D3 w
        queue.wrptr&=QUEUE_LENGTH-1;3 D7 Q8 V4 c/ u+ J, c% r+ w
        if( queue.wrptr == queue.rdptr ) {
0 E) j! A( f3 K0 r                DEBUGOUT( "queue overflow.\n" );
; c. C. r5 Z7 J: q        }- G$ ^' ]; ]5 @. S! U% b
}
6 ]; C1 D2 @/ a. y, U; L# ]6 h+ h1 ^/ O
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )  o  @: e! p1 N% D7 i: l
{0 h4 F) k# P" g! s( a( \
        if( queue.wrptr == queue.rdptr ) {( u/ P9 g, S: _0 |. Y
                return        FALSE;
* X4 B3 ~( W* g        }
& X$ t2 l2 K5 g0 M, _        if( queue.data[queue.rdptr].time <= writetime ) {
5 v9 m7 D2 i  S' P7 P4 m+ E" J8 z                ret = queue.data[queue.rdptr];: w2 ?$ M( k1 c
                queue.rdptr++;( U, D9 E/ T: Y! h0 q, P
                queue.rdptr&=QUEUE_LENGTH-1;, F) _; y( |  G/ ]: d; J( s( C
                return        TRUE;
+ ~$ @- k/ ~, t; q        }
% a" _& t" O7 w! v        return        FALSE;  \! q0 ?# M' n: `, ^( r
}$ K0 `" J, |! ~6 }* ?; _

# @* |" Y) V% h8 g" P1 svoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
+ n- z+ l% q1 Y{
2 j# y( W0 B/ z) e3 ]6 A        exqueue.data[exqueue.wrptr].time = writetime;- C. T) i3 O' l* O* {8 p
        exqueue.data[exqueue.wrptr].addr = addr;- t" e) ~& U4 b3 B5 u6 _0 q/ C
        exqueue.data[exqueue.wrptr].data = data;- g$ a# ^5 y  _' {* ^. }1 m  Q( r
        exqueue.wrptr++;! Z+ j5 X6 u! d
        exqueue.wrptr&=QUEUE_LENGTH-1;0 \9 D" d3 g2 s
        if( exqueue.wrptr == exqueue.rdptr ) {( T* y4 D9 g* Z! p- `- m) B
                DEBUGOUT( "exqueue overflow.\n" );
8 E9 P3 `) m0 r        }! g/ [, L  w) v4 ~. Q5 p
}  Q' m% h2 I6 l! b( X

4 n6 p2 W4 A$ z8 G' d* g1 BBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
  e6 e9 }9 w% Z5 C5 }& w4 X) W- u/ t{8 ]8 d$ S0 m* F9 l' a
        if( exqueue.wrptr == exqueue.rdptr ) {
" B8 Y+ W/ O& a# v& e. m9 ]                return        FALSE;
" ?7 {4 y$ l) N        }: ]. \/ v) K/ v, T
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {) F' W+ ]1 b7 Q; Y
                ret = exqueue.data[exqueue.rdptr];
  i& a! i- b3 M1 ~; Z' @$ ^                exqueue.rdptr++;  \  e, U* v& j+ v7 }
                exqueue.rdptr&=QUEUE_LENGTH-1;& v& v& \6 T# v- K' \- x
                return        TRUE;6 z4 [" X! s5 R2 U4 M, h/ u$ b
        }4 R( U; r- [; P" o5 e5 |5 [
        return        FALSE;6 |3 D7 s+ S6 W
}9 Z" Q( U( P" D1 u4 y

4 \6 T# H6 I- Evoid        APU::QueueClear()/ i3 E9 ^9 \( U, z) q5 y. b
{" I+ G2 W0 ?% b2 Y; z# Y: S; ?7 S( H$ u
        ZEROMEMORY( &queue, sizeof(queue) );1 L* s; r0 c8 m5 `+ p" D
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
* p- a6 j2 c+ X' K5 g( B}
5 e4 }, g, n- \* s) \4 i: r6 T# \+ t3 }6 v
void        APU::QueueFlush()
0 I$ D/ y4 T$ J{" L, ^0 o; Q5 S2 Z  N0 x+ @9 v
        while( queue.wrptr != queue.rdptr ) {
( H, A' @$ k' A8 }4 ?                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );% g* H$ \, j9 w: q0 S& ~
                queue.rdptr++;
' ~+ U0 f- H' p9 X2 Q8 \                queue.rdptr&=QUEUE_LENGTH-1;: T8 ^/ B+ i' n& w. Q' p+ I* ?! A3 w9 _
        }
3 }  d/ C6 W: t1 R5 `5 d5 H8 b9 {% b. z! ^# e
        while( exqueue.wrptr != exqueue.rdptr ) {# R9 t7 Q) o. o5 J
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
9 u9 r- }8 g6 b9 I4 Z* R                exqueue.rdptr++;9 D" q/ B( T3 l7 N
                exqueue.rdptr&=QUEUE_LENGTH-1;) I/ U" {- c: v2 B1 g
        }  H% Q2 Q7 v5 g; ]/ N3 w- I
}
% s0 _( E5 s* v% P) {/ @  w
4 O. A  {# M$ g) o5 h5 ?void        APU::SoundSetup()
% z5 B; K; G& O8 v# s0 `1 Y{1 X4 V( m4 v+ G( J
        FLOAT        fClock = nes->nescfg->CpuClock;
2 a( G) V, J" V4 N& ~& I        INT        nRate = (INT)Config.sound.nRate;
7 X/ d6 h  t( {6 V7 a" c        internal.Setup( fClock, nRate );2 \) `% z" P2 x/ q0 Z4 _$ B) I
        vrc6.Setup( fClock, nRate );4 o; @* p  R  K* }2 n
        vrc7.Setup( fClock, nRate );) _2 \' r) _) k# Z
        mmc5.Setup( fClock, nRate );; a$ j7 s9 A0 j$ ~
        fds.Setup ( fClock, nRate );8 N& F  P% s8 H9 i8 P
        n106.Setup( fClock, nRate );: U  h  Y& g8 L# t
        fme7.Setup( fClock, nRate );
4 c" e+ b" G5 S}
2 k2 B( K0 P) g7 J9 U; _1 c0 ^, i7 P) ?
void        APU::Reset()
& _. B5 N: Q3 Z* S7 V{4 e" y1 h( e1 \% i! M3 p6 D* |' J
        ZEROMEMORY( &queue, sizeof(queue) );' Z; l( k3 x0 H  {& |
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
8 q$ g( l# K9 G  h
9 e. W& c" h! ?: u        elapsed_time = 0;& B6 R1 c8 D* J4 b% u9 Z

! s% W! ?4 b2 x        FLOAT        fClock = nes->nescfg->CpuClock;
, {( U% K: v( F0 h$ {4 T  \+ `        INT        nRate = (INT)Config.sound.nRate;
* j5 s7 O+ x2 Z1 X" i: [        internal.Reset( fClock, nRate );! ~8 z! I' o# a8 }' o# _1 ~
        vrc6.Reset( fClock, nRate );
+ \+ k- R4 h) y/ s        vrc7.Reset( fClock, nRate );- m' H: o6 n7 {, j  f: z
        mmc5.Reset( fClock, nRate );2 l5 L, x% c9 i8 x0 E' R
        fds.Reset ( fClock, nRate );8 v# Y# e" Z; D2 e5 W3 {
        n106.Reset( fClock, nRate );
1 G+ M0 P$ C# A7 E6 x        fme7.Reset( fClock, nRate );
5 O5 U! Z# [5 y8 a& r
5 C, k( j$ Q+ J        SoundSetup();
# e6 t, {9 ]7 H. c) B  k' i}' T) s$ Q8 |; J8 U" A8 H

7 t0 D. l# J# ?9 M; s: Avoid        APU::SelectExSound( BYTE data )& |' p% V; t& Z) F
{
# z* g. F, c. s0 o! f! M. P        exsound_select = data;
1 b3 R0 ?& B4 P3 Q0 l3 y}" b; _$ G! f9 U7 I

: y, d; d# `8 j6 o) ~3 NBYTE        APU::Read( WORD addr )
3 r  T8 n' ]6 _{
8 k8 W5 K1 ?6 l; _; U  N        return        internal.SyncRead( addr );
# r$ y5 L8 U  r, @7 A}
8 L( X1 j$ x6 H
5 l( }, R, T' ]# O8 Tvoid        APU::Write( WORD addr, BYTE data )* s$ Y9 \- R/ Q9 K
{7 y$ S/ c8 g1 W% s! R
        // $4018偼VirtuaNES屌桳億乕僩
' k8 Y( I% S" O        if( addr >= 0x4000 && addr <= 0x401F ) {& ~* t9 I6 K- z
                internal.SyncWrite( addr, data );6 |  S- o( L* n
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );3 I% q& v9 {& I
        }. b0 g0 k8 h3 I4 B1 m" z" m
}
3 f2 e" e! I, W5 I7 b/ A1 l. c( V9 k: m% i0 k% [
BYTE        APU::ExRead( WORD addr )! G  X- B1 c# |1 J" i" t3 U
{1 e- V5 e8 t# B) Q: [
BYTE        data = 0;) T) n( H! c) ]2 M. T7 a

+ `: b) z8 E) f7 u8 ~        if( exsound_select & 0x10 ) {6 p& G+ B, C  @3 b) D& f; M9 Y
                if( addr == 0x4800 ) {
: k) X5 O7 \2 @3 i1 S7 p. b3 A7 p                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
8 z9 r* {2 S% A) O                }
* I5 D! f1 U) w, |/ ~  S3 C$ e        }
0 d( ]! Y4 ]/ e( G& ]& l% I7 ?        if( exsound_select & 0x04 ) {
- W" b. D1 U' H+ C* u2 M: M                if( addr >= 0x4040 && addr < 0x4100 ) {
5 U  d$ }2 d4 }' L5 e! r& s5 z9 @                        data = fds.SyncRead( addr );
9 F5 |5 d9 f% ^                }
" |4 ]" @& z5 {8 \  T! i        }
5 h$ h3 h3 F! B4 c2 l& ?        if( exsound_select & 0x08 ) {1 n& K. K- [! f" L' Y
                if( addr >= 0x5000 && addr <= 0x5015 ) {
5 p9 o2 C$ t! X! s; G                        data = mmc5.SyncRead( addr );; O' B5 c$ b' `) g5 N
                }5 L& |7 ~# ]1 A3 [3 y
        }
9 g( F1 g) f- m7 k% q
; o) i/ r8 P3 r; ~+ h        return        data;
; D, U/ r0 f) I' ]6 B. D* l; E" d}
8 X+ s" P1 u) `8 T8 r# A7 ^) q, }, u3 ^$ R
void        APU::ExWrite( WORD addr, BYTE data )1 x3 k6 j* E* k' B4 L
{
6 R5 i( Z7 S- ?        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
2 o0 V3 U' p2 O& H0 z0 \+ I! R+ u: b
4 O+ Y" z. h! t. P        if( exsound_select & 0x04 ) {
6 _* H; I: e% S. T                if( addr >= 0x4040 && addr < 0x4100 ) {
5 r- R+ |  k, i) o                        fds.SyncWrite( addr, data );
* }5 V: {- m+ ~                }
, a) c/ B$ c& i( P, [, a! `3 b. n1 e        }
; e0 h* E6 R/ j8 ]
. s0 V6 X  T) T! x8 \& S; d' Z        if( exsound_select & 0x08 ) {* s3 {* H# D: o$ @9 N
                if( addr >= 0x5000 && addr <= 0x5015 ) {0 L* a. o9 R, c# w: ^5 v+ i
                        mmc5.SyncWrite( addr, data );
6 E( S! I0 i5 F0 h5 G                }, S& D3 W  D; m& z3 ~
        }
, o$ r: ~9 @# z$ L}& {: Q, Q- D; _& t
6 |9 m, U! F5 z; Q2 ~% M% n
void        APU::Sync(), D) k# k4 y: M7 D. j( C
{
& Q6 k' ]# f4 ]1 w' @3 N; m( e$ d}
' ^  I9 j6 B! S: \) p% ~( b4 q: b5 u
void        APU::SyncDPCM( INT cycles )
  s, V8 V" }' Y* y& \8 ~  ^- E{6 V# ~7 }7 |; Z: l, v3 r
        internal.Sync( cycles );  i/ z. y( K  p) n5 Z
1 J) U0 p/ ?1 \4 {7 {' e- X
        if( exsound_select & 0x04 ) {
; j+ l0 S/ l* }" }) Q                fds.Sync( cycles );6 s+ h& |9 U) G9 }9 N. t
        }
+ J) w% j% o. I; E  Q: h  T        if( exsound_select & 0x08 ) {
' o* n" d* ]' R4 m8 b6 d3 o. E( N3 i                mmc5.Sync( cycles );4 X  \7 z" _% m% n0 N
        }% R( K& ^! b. H( c% ]/ t
}
% F3 |3 P  r1 W  i% e
# i/ [9 R: D' n0 J+ `void        APU::WriteProcess( WORD addr, BYTE data ): ]' _$ M# B% C- ]! ^
{, H3 V& @" a' @" V+ M- j) o6 d
        // $4018偼VirtuaNES屌桳億乕僩1 `) N9 r6 k# @8 |& ~, g) w, e
        if( addr >= 0x4000 && addr <= 0x401F ) {/ C4 d6 }) G# r3 L; O  V4 z
                internal.Write( addr, data );) A1 f( ]/ Y+ K& c9 s7 J' h: P4 K
        }
  D4 K+ i/ q, Y7 c4 O}  t( R; H1 `& V7 d, Y. O# O+ Z8 D

5 H0 o9 ?! w8 A. W! Y) Jvoid        APU::WriteExProcess( WORD addr, BYTE data )
# C& ]5 v% s1 E$ E0 S- x0 E& O$ a* d{
$ C9 i4 c6 n3 f' E, s        if( exsound_select & 0x01 ) {
3 X! G! O8 {/ W5 v5 V                vrc6.Write( addr, data );
3 V( Y2 j' B3 r8 l) }1 M        }
/ G. _- P1 E! J5 A        if( exsound_select & 0x02 ) {9 o' ]! x. e8 u" E
                vrc7.Write( addr, data );
6 \; O+ \7 m5 j        }1 Z+ _0 y0 A( N* H; P% \+ F
        if( exsound_select & 0x04 ) {
* }/ h, O. v8 T4 x/ x1 r                fds.Write( addr, data );
8 Q/ v0 ]# E: A$ A5 m        }& [( [. t6 P: k2 h" a6 s# C+ n# k2 J
        if( exsound_select & 0x08 ) {& v" f! v; {) G  _% B
                mmc5.Write( addr, data );
" R% `0 D& Q8 i$ ]! }, V3 D# b        }2 m1 F4 m0 U/ _( v+ ]% K
        if( exsound_select & 0x10 ) {
4 T/ \' r" V. i/ I7 @                if( addr == 0x0000 ) {
! _& J2 |4 d) ?* w+ P  a' B/ _                        BYTE        dummy = n106.Read( addr );2 i- V' `1 V/ o) d
                } else {) g0 Y; k+ \, a1 l9 D. W3 `* ]
                        n106.Write( addr, data );4 z& h% ^( F* Y2 A! {
                }* u. Y/ y$ ]2 i, _" v
        }% g4 `" e* h# c8 V
        if( exsound_select & 0x20 ) {* o4 ~' C6 m. j6 Z
                fme7.Write( addr, data );" c. ~, t0 e% @# K( M
        }) N) J; S( l2 v* f* F
}/ @; ~/ e0 d; B

" _! R7 c- K7 L; a/ U& Dvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )# k$ r! m4 M( P) r, V( P- q5 u
{
7 V% M/ }% ]% L  ^& `INT        nBits = Config.sound.nBits;0 U+ E: H& X1 f- Y
DWORD        dwLength = dwSize / (nBits/8);  g  b* U5 F% G  D! G
INT        output;" A1 e5 h1 |- f+ ]. S" h
QUEUEDATA q;
& c9 v( |5 F' O: u: @  c1 YDWORD        writetime;6 R* l4 k. t  L. O; g. c4 q
7 Q7 x0 T7 P5 M, i% O% E: G. B
LPSHORT        pSoundBuf = m_SoundBuffer;, _0 ], u  O4 u2 `; L
INT        nCcount = 0;$ Q$ [) ^# z3 O4 S, N
& k- ], y. _- x' b2 w) u/ z; n  m
INT        nFilterType = Config.sound.nFilterType;) g$ u0 C$ @# o9 C* ?

7 t* A' k2 [* D/ V: T1 \) ~7 G        if( !Config.sound.bEnable ) {$ e. d$ h: `  f9 b
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );0 ~7 k% j; a% e& `
                return;2 ~" V. g5 }3 c% f7 ?# _3 v
        }' F! n& z! O: l/ F" X

5 f/ ]9 a* A$ ]0 v1 S5 p0 ?, H        // Volume setup
( I; R$ Y- n* X$ x% D        //  0:Master/ s6 m( J. G3 F- l0 l% N2 H) I
        //  1:Rectangle 1, n9 D8 n2 h( b$ ^
        //  2:Rectangle 2
; V1 [+ |1 P. q) f# P8 M5 {3 I        //  3:Triangle/ j% l& w% w% b' }9 v, W
        //  4:Noise$ m5 j- U2 R3 X8 V+ P" O
        //  5:DPCM
; ]) p& J' d2 n+ g  ]' p, ^        //  6:VRC6
* Z5 i6 C+ ^! ~( F/ v6 i4 N        //  7:VRC7
7 n8 @" ]; |, c$ a1 Z2 n6 K% M2 e        //  8:FDS
. z. ~4 a6 Q' q8 y+ o+ l) {        //  9:MMC5
* ]' s: ?. a, g# i4 O- l4 W# r        // 10:N1069 i" f1 b3 j7 f/ G% A* f
        // 11:FME7
& A6 P7 `3 o( N        INT        vol[24];
# Y: A: X6 q1 E, }        BOOL*        bMute = m_bMute;5 C  O. ]! N' E
        SHORT*        nVolume = Config.sound.nVolume;
- S3 I- Z6 h: M* x; g$ |
$ {, n  \7 S) {7 }; D6 S        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
2 _4 T/ ^! e: d! _0 Q+ y9 |0 S5 V4 K1 f& s
        // Internal3 c9 ]' I; t5 Y4 `. X" T
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;8 \2 f* d9 O& ~! P2 n
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
- c8 u3 t1 I3 v        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
! J4 u7 x. ]0 X        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;& s) m7 S% K) [8 l7 L5 ^
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
6 e& m- c3 R( D6 V- S+ ^5 V( d8 _# D* N- ?9 D, H
        // VRC6# c5 @" q" `9 h" [) t  x. W1 y
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
2 I% ?1 E% o; i        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
5 {+ ^- G: ]& i, [! J: [4 f        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
" C# p) n$ f# a# O  ~/ {/ l
  V' R0 Y7 O; K% l' t        // VRC7& N+ r9 g$ }, I/ l4 _
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
& _% b6 t& }( T) ]4 P6 \" E- N/ m+ C% k. c$ x- ~- v& f
        // FDS
' l1 X1 k/ L, j$ I        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;7 K& o. z; _! f6 Q5 i, E0 O/ I
) Y# I  `1 v/ M; C8 ~! l" v
        // MMC5
" F1 z; |4 M! l0 D        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;9 B5 f6 Q" L0 M0 \$ E' i6 a
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
$ {) w0 j/ d, ~- j; n4 B3 i4 i/ P' t. C, E        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
- w- c2 k- f3 u) d9 p# |8 i: _
, b, n/ Z5 c; A3 n6 m        // N1068 K- s) k4 {0 b9 p% V
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
  e1 Z& U$ e4 B- N; P        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
/ z& q  V" i2 G& M' \        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;6 P3 a, W6 s: l2 ^- k
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: z8 S* {- g7 ^( n( C        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
$ {9 S$ l2 {, o  o        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
4 X3 ]* v4 s! i& L* w        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, v3 Z9 E& M% Y0 r. Z! a1 }# ]        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; g: w& F. K- X+ Z8 g$ ~6 q& ]
4 W. n% l* x8 B2 W' q& H
        // FME7
5 t+ w3 g, U: J' B        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;9 A; o3 z, s" l9 [( g- ?; {+ Q
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
8 O" v8 U& Q8 S! F6 j        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;# f% |1 O$ n0 \5 ^$ ?, d

% ^6 m- I6 H& ?8 k, @: w) p' \//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;) v; J% h( P' K. J9 A" l
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
0 r* o/ _. l5 y3 A5 u
7 n, g0 y/ D- Q: H) v, {& V' n        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
/ O: q: s" a# n        if( elapsed_time > nes->cpu->GetTotalCycles() ) {* A" S/ E7 d+ x; {3 l9 \
                QueueFlush();
. ~: s# s  x0 e" m* w6 Q        }' S/ R. E* X; F/ e' Q+ F* V2 X

4 }* x1 j4 I9 @; ]+ e        while( dwLength-- ) {
, T! t; b5 V: l1 ^0 N                writetime = (DWORD)elapsed_time;
) I, w) ?. B/ g+ C/ p8 [( m) K* k
                while( GetQueue( writetime, q ) ) {
5 m1 [6 D. e) y# }                        WriteProcess( q.addr, q.data );, I5 M5 {5 a% C) e$ u, z8 h
                }9 k! ^) K) M( c7 e
( |( q, R+ \$ m
                while( GetExQueue( writetime, q ) ) {
6 A- s! i% [0 J8 `# w                        WriteExProcess( q.addr, q.data );
# M7 K/ P% j% @                }6 v- _8 p4 ~* `4 L
5 _1 a) K' B4 U8 r2 s
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
6 y; u' ]1 m7 k. r5 z+ h, `                output = 0;0 i. W5 V/ V, l2 x
                output += internal.Process( 0 )*vol[0];
5 a! b$ e5 {" \6 ~+ E                output += internal.Process( 1 )*vol[1];
6 e# u6 D: t$ \0 m1 [' i: p8 R! X+ J1 x                output += internal.Process( 2 )*vol[2];, W; I  @4 ?  Y7 L. E
                output += internal.Process( 3 )*vol[3];% R- V. A# s  R3 }
                output += internal.Process( 4 )*vol[4];
% E8 Q1 e! ~1 y2 t0 w0 [6 P! _# I2 }3 S" ^* d1 `
                if( exsound_select & 0x01 ) {; p4 d- w2 n& v. }+ c2 y$ u
                        output += vrc6.Process( 0 )*vol[5];
9 V: U0 U6 q8 [                        output += vrc6.Process( 1 )*vol[6];, y" G& B! r1 B! X. i
                        output += vrc6.Process( 2 )*vol[7];' I% D% u$ W! C/ _3 [
                }
" _# {3 c  W9 P. `2 z                if( exsound_select & 0x02 ) {
5 u( v6 e. \2 x/ M  n# g                        output += vrc7.Process( 0 )*vol[8];. T3 x: \2 Y+ v7 m
                }- p3 J3 o! b0 T
                if( exsound_select & 0x04 ) {
2 l* j$ F* {" i9 u. Q+ a- M                        output += fds.Process( 0 )*vol[9];4 X- u0 r- [/ f$ ^
                }; }) _9 V) ]. @+ J
                if( exsound_select & 0x08 ) {
0 r3 B6 F# f, D                        output += mmc5.Process( 0 )*vol[10];
2 F; ]# _0 x! f8 z0 B                        output += mmc5.Process( 1 )*vol[11];# G- y# ?9 H& k( T
                        output += mmc5.Process( 2 )*vol[12];0 b$ d% w, U, e6 ?- ~; d
                }
$ p" C( b& U7 B: G                if( exsound_select & 0x10 ) {
- n! b& S) ~( `                        output += n106.Process( 0 )*vol[13];
; p- \3 a: Z, U; H! j                        output += n106.Process( 1 )*vol[14];
) v& ?9 I) c$ W, D4 t5 H% C                        output += n106.Process( 2 )*vol[15];% P% T# o. U! @1 W$ |
                        output += n106.Process( 3 )*vol[16];, M' U  e8 L+ O/ d! l1 s8 u
                        output += n106.Process( 4 )*vol[17];
/ e# M( j1 i* n3 k. B                        output += n106.Process( 5 )*vol[18];- @! e* z+ r; V/ f" p( o0 @" y0 t
                        output += n106.Process( 6 )*vol[19];
2 @  s  j- U' j+ F$ P                        output += n106.Process( 7 )*vol[20];0 K, K- Y7 I; R; {: e
                }
' `- @% q6 j; j& p                if( exsound_select & 0x20 ) {5 g: R# {" L4 h  W5 p$ I9 y
                        fme7.Process( 3 );        // Envelope & Noise
7 o) M5 |9 ?" \4 x- Q                        output += fme7.Process( 0 )*vol[21];) r9 N! U3 t; |- j
                        output += fme7.Process( 1 )*vol[22];
( S: y! v" I4 m; d% |/ q8 y" U                        output += fme7.Process( 2 )*vol[23];
% Q: {, L# f$ Y0 a$ D4 G                }0 K$ Z" A' W0 T+ k

% g1 x: I' y. R" ~                output >>= 8;
% ]9 h& V2 N+ P% |2 E, P2 @* c
# ~) p/ ?- R. D9 y; t7 s& t                if( nFilterType == 1 ) {
) X3 M& t+ G' u, ^% s# Z. y                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)% E* ]0 d  }2 H
                        output = (lowpass_filter[0]+output)/2;/ ^* w9 E- O  c# x  d
                        lowpass_filter[0] = output;
- K9 [7 r  G, u$ X0 q- ~4 Y                } else if( nFilterType == 2 ) {
  ]. O: c: Y6 ~8 m- ?/ Y                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
7 R: V0 P. x2 g5 p                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;) g- K( P9 x1 l/ x! J3 O, {
                        lowpass_filter[1] = lowpass_filter[0];" f  V0 G8 P0 d. R+ h
                        lowpass_filter[0] = output;3 \8 ~& z/ |# B. X' K* V
                } else if( nFilterType == 3 ) {2 O5 f9 `. N5 D  }
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)8 Y' T/ C$ c5 ^6 Y
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
+ H* u- Y+ D1 ^- `8 q7 K- `: C+ Z                        lowpass_filter[2] = lowpass_filter[1];6 a' m9 ~+ t0 T, R" f' V- B
                        lowpass_filter[1] = lowpass_filter[0];
+ r5 a. u) x2 B7 a                        lowpass_filter[0] = output;
; B' Y4 ?# `- S' p$ [4 g  p+ U                } else if( nFilterType == 4 ) {
  b. R; ?  w, V2 v0 z0 m0 E% A2 p                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)2 ~8 p+ V! t( r9 t# ?# v& {0 s) @
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;/ I) m2 d  g# Y" X/ |
                        lowpass_filter[1] = lowpass_filter[0];; ^9 y: U4 z: ~( A, D2 B9 y
                        lowpass_filter[0] = output;. T3 r0 l. M2 I4 y/ e0 P8 t
                }8 z( A6 ?0 @  R) A
% a3 L. ^: \* T5 C
#if        03 H4 a* p. h" f" X, y
                // DC惉暘偺僇僢僩
* i5 E. h4 _+ V0 K5 `# I                {3 k- X/ |8 ^4 y# g- \7 T5 \
                static double ave = 0.0, max=0.0, min=0.0;
8 M+ g, s1 N/ G& m" |                double delta;- s0 e2 _1 P, l0 L7 Z8 `+ q
                delta = (max-min)/32768.0;
3 q# A2 l" O+ |, i, H$ [; @. C                max -= delta;3 h9 `) u8 j3 X; C3 ]- C
                min += delta;+ \+ k& s' w% d; t/ H
                if( output > max ) max = output;. g8 c0 D! D/ v- k4 F. g* H3 d% h+ T
                if( output < min ) min = output;4 h) X6 Z. h8 ?
                ave -= ave/1024.0;
" \1 l6 w: Q+ |                ave += (max+min)/2048.0;
% s3 I% |! g& }+ l9 L- b/ g                output -= (INT)ave;
1 V: u$ s3 h! A+ a! g5 g# C/ c2 D& c                }) m+ A2 t& g7 n
#endif! o+ q# v9 x" F, @6 _8 A
#if        1
2 e1 [6 Y3 T& R+ {) _                // DC惉暘偺僇僢僩(HPF TEST). U' I5 P3 t! t6 O, F& P
                {
- b2 [- _0 V* Y: u* I6 n) h9 Q' Z//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
. ?4 v$ M# G& A3 N6 O5 Z( @                static        double        cutofftemp = (2.0*3.141592653579*40.0);2 @9 ]% j0 a' e
                double        cutoff = cutofftemp/(double)Config.sound.nRate;
2 r! l1 k& {  N                static        double        tmp = 0.0;
! g6 k8 [( `( a, ~  \                double        in, out;9 B" N  \8 R% K& a8 D7 ?
5 U) }1 _! T0 y) @
                in = (double)output;
, D4 b4 M# s$ F  w                out = (in - tmp);
9 B+ j* X5 C( v' ?# N' X3 Y                tmp = tmp + cutoff * out;0 j; n+ N5 B# d! _! F

  [% K2 t" {3 O8 e9 s( @/ `. L                output = (INT)out;
( H0 \/ J7 @! i* S6 t  @                }
+ f4 c. [: Z& c" y#endif) ]* R4 k4 G5 \7 a
#if        0; @; z1 u% S3 z* s" P
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)9 A& Z) v2 O2 K& d4 S0 O' `0 o8 Z
                {
9 w- a! ?: E8 t                INT        diff = abs(output-last_data);
- n* v  g. h! Z$ t: [% @- P                if( diff > 0x4000 ) {
0 T( W% N! C1 c% w                        output /= 4;
) f5 Z' F( D! H5 V2 G6 k" G                } else 6 c! {4 Y+ i5 W( X5 V4 D
                if( diff > 0x3000 ) {
; F& q8 N! @: O) L4 l                        output /= 3;5 i5 ?" {$ }& o
                } else
: B6 U  L* R7 q$ b$ t0 q                if( diff > 0x2000 ) {
. x7 G% L( B  I( b                        output /= 2;) s0 j6 s7 u8 i: A
                }
& a+ i$ f6 z& j4 B                last_data = output;% P8 X1 ?  X- z+ `
                }
* V; n4 S+ P: J2 b  l$ r7 J#endif
( N0 P) Y% O3 e+ M7 U( h$ [                // Limit
0 A7 D9 I' q$ c) q. \; g, x! a6 B                if( output > 0x7FFF ) {
  R. k  R) d# Z9 e; Q& J0 v( F" p$ ]                        output = 0x7FFF;2 D! E( \. ^- I  k# \
                } else if( output < -0x8000 ) {! `5 I+ X5 G! t8 t4 F) e9 `
                        output = -0x8000;
( i" X, l  H8 |, `: Q                }- k& v  P# Q! J# O
- ~  s  s+ q2 d4 Q  A& l) C7 `1 E
                if( nBits != 8 ) {
* g( [" _. B3 R- B                        *(SHORT*)lpBuffer = (SHORT)output;& M6 G" F  Y+ F, g  f+ }- \7 H& _
                        lpBuffer += sizeof(SHORT);
3 `* L  _4 z3 y. O2 y8 N0 J8 F3 ?                } else {
) V0 ~/ D$ H4 c+ M- \5 o) B                        *lpBuffer++ = (output>>8)^0x80;
' |& s, b- }/ q+ B( h& i% }                }! P9 r" X, k' n
* `0 A9 H8 k3 }  Z+ {) F
                if( nCcount < 0x0100 )
! w" B' s7 V1 b% F, x& v: E                        pSoundBuf[nCcount++] = (SHORT)output;2 c3 _2 d: _; P! Y7 Y/ \1 s$ _
$ G3 j: j# \' ~6 ]7 s9 H8 [
//                elapsedtime += cycle_rate;) ]& y/ `* Z. N# \: e% X
                elapsed_time += cycle_rate;
, g' {' Q, L% N1 K$ I& |. d        }
# h0 c& ~  r) {" U* d$ j2 x9 Q& ]5 k% i$ @* R0 G2 {# R
#if        1# a& t8 |& K7 t2 O9 n0 M0 ]+ g
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
  {1 D$ B1 Q* n* Y: G1 p, x1 V                elapsed_time = nes->cpu->GetTotalCycles();
& d. [& x* f. C- k: G/ {        }' \, R1 [$ q+ T6 |- H% y: l! |
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {: X" ]5 \% j; q9 o- g7 z
                elapsed_time = nes->cpu->GetTotalCycles();9 X" f0 B* c. d# z" l" V9 C
        }
1 s& w2 t0 A# }# F# Y! Z#else& n; n  S: u. M$ ?  P
        elapsed_time = nes->cpu->GetTotalCycles();# J" [1 I" Z, ^9 A5 p  b1 \
#endif3 P" ?( V: R9 h7 J- X  K
}: G) ]% a0 H$ @" W7 Y$ Z
9 m" D0 ?6 G  q: I% v* ]9 K
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
" N% Y: f; X8 a" C7 RINT        APU::GetChannelFrequency( INT no )) }; _8 V5 B1 x: o9 @5 Z6 U# Q0 d
{
3 C0 Y; J0 e# ~- P        if( !m_bMute[0] )
0 j" \  F, a: W; F; }. `6 }+ M/ k$ I                return        0;0 x2 i! ~: X( ]7 w9 ?+ K
* h! t, ]) N: P" K" }5 ~' k& o
        // Internal
! c' t, D- z. l( ~3 L  U        if( no < 5 ) {' h2 l1 P9 k% P* t1 W+ {) p
                return        m_bMute[no+1]?internal.GetFreq( no ):0;* @# Q7 U  K7 T, I1 ~# P
        }
- F' l' D7 p+ A$ k1 C, {) x        // VRC68 R. ?- D) }  O" [
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
% ?$ M  d) i2 t; D3 K, e! C                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
1 v8 |6 M9 l; {/ a        }
; l2 x6 G, c! R- t+ t: X" Q        // FDS+ Y' |2 |4 @/ W+ `7 Y
        if( (exsound_select & 0x04) && no == 0x300 ) {
- h6 i) R' L( {- Y                return        m_bMute[6]?fds.GetFreq( 0 ):0;( g. q1 e; p) _8 L2 ]  Y
        }
$ U! F2 I, Y6 g8 X5 I8 I        // MMC55 I" j- w( W. S7 ^+ j" z
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {' H% w4 D: k4 v) ^
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
- p  L; {4 J1 j: O        }8 {3 j! S7 z8 O  A" X3 ]; D
        // N106( V2 d8 D0 X( c, T3 `/ A- Q) Y
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {; L% {5 \) I# L( P& g$ G
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;9 }: ~9 o- W: {) {5 M& L* A* W
        }0 A. Q3 Q; B$ C" e! P$ ^3 s
        // FME7
9 W* r: O2 F0 H5 J4 @7 N        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
) e# t( E! _- m  [3 D                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;4 ~8 d6 \4 z/ G' W3 q4 K! x
        }  K$ ?9 X* d$ s9 i5 n7 ~
        // VRC7
( D! S7 V. t* z( t* }: b        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
4 i2 ?2 ^( c! n2 l* w" K                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;* K8 Z- [' x2 h" _4 s2 A  H
        }
: Q$ c7 U6 [) A/ e+ X% X        return        0;
  G* B1 [- r! F& w; f# H; |% y# L}8 w: r" c4 S8 D* I

$ F% a' a) U# y- i// State Save/Load
8 p+ N  |9 b/ x4 N1 Y* }void        APU::SaveState( LPBYTE p )
/ W; ?/ D' t: B+ H9 H: Q{
7 ?) j% B" H' n4 y, U0 Q6 S#ifdef        _DEBUG
1 q9 s" [: W% ]4 VLPBYTE        pold = p;% t+ |$ P: x( B( n* c- r" D1 ?
#endif3 n5 T& n2 C- X

  b" U+ ?' j8 m" l        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞- ~! K4 o0 G( ]& z! a
        QueueFlush();5 M$ x  w! S( A$ c; g1 t' [3 Y

3 F  u- y' }/ U3 e+ U7 H, R        internal.SaveState( p );: s. N! }7 ^( q! {7 ]  s
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding2 U0 S$ x( P0 ?9 t5 e, F5 m& j

/ S- m7 x% b" T  ^% \        // VRC6- G# S3 }5 g# V1 l/ Q/ z2 Q( |6 b
        if( exsound_select & 0x01 ) {
' U! w) v& Q5 ~                vrc6.SaveState( p );- Y& e( `( i/ x, G+ C. K4 n% v
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding$ X3 G2 A! d: a2 ?! P
        }
1 j* Q4 p( A8 G; e, R' ~- {        // VRC7 (not support)3 i" f( ~+ r% l
        if( exsound_select & 0x02 ) {
9 {# E) l# P& b! o8 p9 H                vrc7.SaveState( p );: C5 u3 l( |9 e& Z: e6 a2 T
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding# v1 [8 R4 k) o, J
        }
9 \- j) l4 {, M7 W        // FDS
1 d4 _9 M5 H. e; H8 o% y: F        if( exsound_select & 0x04 ) {
2 g2 C, z; W9 N' |/ h                fds.SaveState( p );5 Q; {# W( M9 Q+ p. d# o" H
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding5 a! k( S) k5 O8 h$ @% E: g" z( J- t
        }+ v. ]6 o6 R; J6 n# B
        // MMC5
- k0 `3 H7 B. o+ H7 B+ h4 S0 `% _        if( exsound_select & 0x08 ) {
5 |9 G& y' J9 e2 K# w3 g3 [! k                mmc5.SaveState( p );9 V' `6 }& B% J
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
$ j7 t; g9 A! O8 C        }
) z' [. ]# q" `# f% z( y6 A- Z, ~- j        // N106, v* l7 @. m9 j- w
        if( exsound_select & 0x10 ) {1 U; m% s8 N5 y1 s2 K
                n106.SaveState( p );
* _7 n! S& a0 u; L9 W# e. g& [2 V                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
8 P* G4 e* R0 e% S/ G! l1 {        }' V/ o0 h  x7 a0 @2 c1 t7 z! U
        // FME7
1 v( [# W. @, ^/ W/ O2 w        if( exsound_select & 0x20 ) {
& B# k5 z) [# E; U- ?/ x                fme7.SaveState( p );
9 t/ \6 ?3 O2 z3 O                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding3 e6 Z5 B5 U1 C9 ^/ s( h
        }
* ^1 c+ e: o* p
' H  C- G9 s3 x* E+ s2 I1 ~8 e5 p1 w#ifdef        _DEBUG
( i* _) d- b/ f7 JDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
7 j2 l' F2 i$ [, Q1 C#endif$ ]' o* R1 ^$ i0 F# \3 Z
}
1 g+ {* J9 q4 u/ d- `& T! p' t: `1 c8 A" Y2 U, X! A/ [0 p/ W) W
void        APU::LoadState( LPBYTE p )# S" D2 t1 [- p( F" W- A# Q* i
{! v4 {- Y5 _8 y8 V; T' Q- I4 W
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡4 p- b" V$ Z% a; c
        QueueClear();
/ ]% Q$ Z3 }- g% f! ]" |6 B5 x: j( b: ?  P% n- ]
        internal.LoadState( p );
' n; k/ }: x* |. S+ M9 I        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
3 u3 h+ O* c- G. U7 I) t4 a
6 x& L5 s7 p1 H2 R* M7 o) J        // VRC6
# C) c1 W0 v! @2 P8 o        if( exsound_select & 0x01 ) {! n6 y3 F- n3 Q" L0 _  z
                vrc6.LoadState( p );
  g' I8 y7 i, `! D* G9 e! M" g+ H5 e                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
7 ]. G7 ^7 e5 ]9 l0 G        }
# {' z2 g$ M% {        // VRC7 (not support)# N  Q; ]" a: N" S: K- Y
        if( exsound_select & 0x02 ) {! U3 r; W: r& J  H% u
                vrc7.LoadState( p );
/ x0 v1 u! C$ G, I* \$ N$ T. u                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
/ A: Y2 \1 b! f9 p# ?4 l        }
" Y4 ^+ d2 V* @" V( Y        // FDS0 b6 r' K$ F* u  D$ u8 v
        if( exsound_select & 0x04 ) {5 n+ ?4 \; A4 Q/ d3 s' Y
                fds.LoadState( p );
% h( o2 x4 w* n, T                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
# r' m' F; B' T3 k+ k7 W, t* J        }$ c# Y: e6 E7 q8 f! _' P
        // MMC5
$ B" k" q6 z7 U6 |3 D" }' Z        if( exsound_select & 0x08 ) {
: r0 @5 f! l+ \* @1 g9 G* ?1 f                mmc5.LoadState( p );
; d8 D8 d( j$ x0 F: I                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding! W/ }6 @. \+ N, m- d" R
        }
4 M: E" z, m  P0 R8 w$ P$ j# s        // N1066 f0 o. f4 _' u$ D, v" Q
        if( exsound_select & 0x10 ) {) n: [$ T/ N+ X8 k
                n106.LoadState( p );- E% @6 q( V. w- m; F- r+ [
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
# g, r9 b- J: k        }
6 t7 D. T" @) L- m( M        // FME7
, I7 J0 D/ O: U3 i4 ]        if( exsound_select & 0x20 ) {" r& q0 }  L6 |& Q7 H( \
                fme7.LoadState( p );$ q+ n( Z" h1 u6 Q
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
; }. R& C, v/ Z. {- _        }5 e2 I8 v% g; I' D" o
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 2 s1 a5 b' n$ e: C( K
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。2 S3 e; f- y2 n  q5 g
感激不尽~~
% S, I( u( ]( P  J7 O' I% y
恩 我對模擬器不是很有研究,, ~2 c8 m5 J3 ^
雖然要了解源碼內容,可能不是很困難,
. S+ `0 c: r- I2 c不過還是要花時間,個人目前蠻忙碌的。  B. Y' K/ l/ ?+ L, w

; W# [1 b/ n2 q9 K* o& [給你一個朋友的MSN,你可以跟他討論看看,  K$ m, W3 B2 x
他本身是程式設計師,也對FC模擬器很有興趣。
- {$ L- T4 `# t2 y% g7 {- N( y/ i$ i% B: V1 i  N
MSN我就PM到你的信箱了。' L6 T* G# y; _7 _* j5 |4 V* a9 Q
$ S- g0 w- Y6 g$ {* ~3 V
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 / T, b6 ], p" B0 {2 k5 M
呵…… 谢过团长大人~~

; e" {9 l$ q) {0 [: K! e8 b6 e9 }* [* R9 O/ G( V
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 , q$ c; W3 Y) O6 e4 `" r0 v
团长的朋友都是神,那团长就是神的boss。

, c" Z* ]+ o/ }0 b哈 不敢當,我只是個平凡人,
! p5 |9 ?2 a1 [8 W8 X' f% L要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
7 x  f& p& `: J& _/ [8 m4 B8 OZYH4 h) z4 b1 I; ?% z; {+ Q; }% a9 m
QQ:414734306
  \! w' y8 `6 z$ {( T3 y7 JMail:zyh-01@126.com1 v+ v9 g0 l/ t
4 g+ R4 Z* `& O7 F4 i7 r/ [( c
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
7 v6 }# ~) C) p0 r/ U再次对团长大人和悠悠哥的无私帮助表示感谢~~
5 n2 N4 f: V6 W& r
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-22 17:01 , Processed in 1.095703 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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