EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
, Y$ ]: e: U& D. K; Z5 V- j楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
" _$ {$ L' g/ d9 E8 Z& i9 }/ f这里有相应的模拟器源码,就当送给大侠了~~9 P5 C0 u1 ?2 r1 Z) Y' M( t
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表 + T9 u3 c; m. t/ i
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。. l7 |* D# V) [7 N* }& {
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
# _* C* g/ H3 {" U这里有相应的模拟器源码,就当送给大侠 ...

1 l; J2 v+ [6 E  e聲音部分(Audoi Process Unit = APU):. g/ |3 {) ?' s# |* n
.\NES\APU.cpp. K7 e  [6 b- N
.\NES\APU.h3 ^5 s6 S2 n' R; t

* ~- D8 m6 {$ U9 f# j: z( a) Y* |# v7 x- y( h! g; K, b
影像處理部份(Picture Processing Unit = PPU):4 \' A2 F! d% ^# U) p; T
.\NES\PPU.cpp
! X6 N) q4 a. J0 Y2 D: C.\NES\PPU.h
; `/ J- U0 Q/ A& y7 o2 t4 i0 r# c! _
- `9 J5 y0 y5 V; S1 f, @如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
4 Y6 d) M0 X) u: H. F(由于很多专用术语和算法机理都不明白,所以看不大懂……). T. i) Y. i5 n( w, R5 _
//////////////////////////////////////////////////////////////////////////
- F% D8 n( S  g//                                                                      //$ X- ^- V, S4 |- Q0 O- n
//      NES APU core                                                    //: _) m- z8 i2 L' c5 I0 d
//                                                           Norix      //
' t8 G5 t) ?% V$ }//                                               written     2002/06/27 //
4 u: @4 Q& h0 Z9 k2 m1 s, o% }/ {/ M//                                               last modify ----/--/-- //" P. d, |0 d4 `) S# x
//////////////////////////////////////////////////////////////////////////
0 B, W* Y3 D7 p8 D2 W#include "DebugOut.h"
" E( ]' P( V# ?8 M) h" q#include "App.h"
! ^6 i7 J0 D) z/ L#include "Config.h". F( N0 L; i& x2 M0 ^
/ v! [% ?% Z' K9 U& c. ?' V( }
#include "nes.h"
9 F6 b( M, U* a  }6 x#include "mmu.h"
, _% E' l/ t' @' L2 V5 A#include "cpu.h"
, S6 ]: n+ h9 J( h#include "ppu.h"
9 `+ v6 s1 h) n4 b6 W7 n, X  X#include "rom.h"
+ t4 m- V" _# \5 j# b4 ~#include "apu.h"
) V" I3 T. y: r' {0 `0 A, A" R: G
// Volume adjust
% H1 n7 ]- \4 X' @4 }// Internal sounds, A* H! D$ B- s& ]6 M
#define        RECTANGLE_VOL        (0x0F0)# ]2 S3 r, ~6 q& j( O$ b
#define        TRIANGLE_VOL        (0x130)
  m9 O( |+ g" v: J. F#define        NOISE_VOL        (0x0C0). J# J4 ~: A$ j. }. I- n
#define        DPCM_VOL        (0x0F0)* K  _7 b# G# h( d! l& {) K
// Extra sounds
0 U  k& H7 S8 o#define        VRC6_VOL        (0x0F0)7 W+ z! ]. `% F" X, ~
#define        VRC7_VOL        (0x130)
# y3 N; `8 s; R5 g0 S0 i7 h#define        FDS_VOL                (0x0F0)7 O8 u* F$ K# m6 C1 u/ U
#define        MMC5_VOL        (0x0F0)) X5 q4 h" w# l
#define        N106_VOL        (0x088)
% d5 ]& s6 y, t#define        FME7_VOL        (0x130)9 j- b# Y* ]% `0 }9 ]: @5 O; g
1 i  w9 N. w2 H9 M+ u8 x; D
APU::APU( NES* parent )9 F7 J7 E' O+ `8 G0 i
{
: k0 V. P  }  ?( i$ @        exsound_select = 0;
4 f1 |* _  z7 {3 P  l. K4 Z; v& H) S/ j7 v
        nes = parent;! w: C1 d* F; V1 R9 r) Z1 c" q( Q  m
        internal.SetParent( parent );0 f( c$ z0 b2 `( D
: G* a6 \' f4 ?( K  d, r0 w
        last_data = last_diff = 0;
4 W2 F3 z! O/ j0 C+ j$ C5 X! d$ b5 M
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );4 V4 M; w* X' Y- n' J
% m2 e# p6 Z2 g+ ]9 {$ y! P
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
; y+ F4 A8 p. o; _        ZEROMEMORY( &queue, sizeof(queue) );& S7 M. {' N7 n3 D( g' ]
        ZEROMEMORY( &exqueue, sizeof(exqueue) );; H  O9 G9 A2 T$ [6 X6 r

- Z/ k( E! u' o. K% e; P        for( INT i = 0; i < 16; i++ ) {1 i" P8 m: b5 k6 n4 n2 k7 F
                m_bMute = TRUE;
: t* R3 s- t2 U$ w/ s3 s6 \' m. g$ F, a        }
; T) G  k$ Y2 n/ x" e: P}
( s" O6 |$ U. C
# [% N3 S2 g/ [$ Y, g) \0 AAPU::~APU()
5 J. M3 \1 t4 m6 J: R{0 b" Z' I$ |& {9 r0 J9 L
}; ^8 ^0 A: V- ~+ o+ }4 ?+ l

1 Q1 ^6 T; I* ^# Q8 cvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )$ S6 d2 L3 ]' P# R& N
{. S% ^  S0 Q, z( b
        queue.data[queue.wrptr].time = writetime;
& z! c. P/ f8 }        queue.data[queue.wrptr].addr = addr;
; X7 @( s$ J" W7 G% \0 g, @% I        queue.data[queue.wrptr].data = data;- P# M( A4 h6 @. T" t2 i
        queue.wrptr++;! P/ ]- e  E7 y/ `
        queue.wrptr&=QUEUE_LENGTH-1;9 l' b" N) f0 |/ @5 m7 J* E* i
        if( queue.wrptr == queue.rdptr ) {" L% P2 w4 E. d8 M: G+ \9 ~' z
                DEBUGOUT( "queue overflow.\n" );
& w1 q, u$ B# [" Q3 R9 E$ F# L! B        }4 |" n1 ]7 d" d- J+ G) @$ G% v
}+ y6 m. J4 x7 N2 ?

) v# `$ r2 R9 ]# vBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )1 F3 x- ^8 t, }; `. `2 y
{
; C" ~7 ~& M) ]* s* T        if( queue.wrptr == queue.rdptr ) {& R+ g3 b$ R3 b4 E3 M6 V! D8 O
                return        FALSE;
& B! B# I: U2 w9 w+ h& Y; F; M8 x        }  _: E, a, O) s
        if( queue.data[queue.rdptr].time <= writetime ) {
8 L/ }! t; [: b  }4 x6 T/ Y                ret = queue.data[queue.rdptr];( n4 ]- E5 o7 y, v1 N
                queue.rdptr++;
5 m4 I/ b) x9 q* `2 U                queue.rdptr&=QUEUE_LENGTH-1;
; g) W" U' Q- C9 @8 E* S                return        TRUE;
9 Z2 M! ~' T' q0 `2 G; z- x        }
8 i3 D- E/ T, v  @% S        return        FALSE;
: ~/ D$ k0 P3 D+ ]: s}
  O8 X! I4 c7 e* h1 x6 P
* F+ u/ e$ T8 O% x9 B  Y4 lvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )) s4 }/ D0 n) H0 g0 v
{# G! y; y1 ]+ S% k* [. y
        exqueue.data[exqueue.wrptr].time = writetime;+ }1 Z( ~- \9 R& l1 d' F
        exqueue.data[exqueue.wrptr].addr = addr;/ F1 ^5 H% O+ W% g
        exqueue.data[exqueue.wrptr].data = data;4 J# o/ Y- V9 ?! [" u
        exqueue.wrptr++;
2 q0 ]  A5 x4 [# I6 J4 R        exqueue.wrptr&=QUEUE_LENGTH-1;* Q- j4 a* h& Y$ L/ {0 t( J* G
        if( exqueue.wrptr == exqueue.rdptr ) {
. [% y5 v: {( c                DEBUGOUT( "exqueue overflow.\n" );
& x6 J0 R) g* f0 r6 h        }
  I- x" U; I2 {; e1 N}
! s3 E9 H4 U' |6 P# w
* K2 w: e5 a, x3 G4 F- fBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )
5 }8 r) W1 y7 k; m+ C- s{. Z" K0 P! U+ b( b' d4 {: V
        if( exqueue.wrptr == exqueue.rdptr ) {- I" C% Y6 y4 r* j! e7 o
                return        FALSE;
# s  m2 |" [  d/ I        }, m' r! \6 \# Q. _
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {, ~) ^3 G: b( @
                ret = exqueue.data[exqueue.rdptr];2 y' O! j7 m. V. ?$ J
                exqueue.rdptr++;, R8 m  m! G# g4 d' x; Y& x
                exqueue.rdptr&=QUEUE_LENGTH-1;" |4 C$ ?4 Q; m* t2 ~
                return        TRUE;* t1 i  w) d6 h$ }
        }5 P% H4 i* y4 ^9 p. B4 n1 w/ p
        return        FALSE;
& e, u" y# I) j8 I4 v- \, k/ U}& [- C: Z2 @9 V4 w) L7 N" {

* z' m4 ^! B  r4 R5 F8 @" L! Q% S* f: M. Kvoid        APU::QueueClear()
% X7 X5 @2 z8 {{
1 ]0 Z, J$ w& ~6 W% F" l        ZEROMEMORY( &queue, sizeof(queue) );
3 r  ?1 L5 g; M7 s  V$ g4 O( X        ZEROMEMORY( &exqueue, sizeof(exqueue) );
( ^! w% c" g9 O& [( J}
6 S! e4 _. [2 Z2 Z3 y. _; I4 a: _) ?( D' j
void        APU::QueueFlush()
0 M0 X- ?: u2 d" [- W. _{
8 K, y& f7 y3 |0 M4 v6 c0 `9 i        while( queue.wrptr != queue.rdptr ) {
" g3 B  [+ Y! o$ b2 }+ m; X                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );) _; g4 N6 _' v7 y7 C. w
                queue.rdptr++;1 @8 K) N" [" u. z
                queue.rdptr&=QUEUE_LENGTH-1;8 b! W$ g% c. ^5 E6 r# V
        }
. k# W5 |( `7 {# ^0 C& X( ~1 k% `5 K) J  G# E% f+ s
        while( exqueue.wrptr != exqueue.rdptr ) {7 X' ^# Q! M8 F( F
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );3 m7 r( W, g& R
                exqueue.rdptr++;
, |) V$ q1 [9 v                exqueue.rdptr&=QUEUE_LENGTH-1;
5 a) |$ |; \1 o* F$ I        }
- H0 G. }8 c$ ]# p}  T. b% |* v) Y8 z  p9 K

* y* c3 s% x: X: N" K7 O( @5 @void        APU::SoundSetup()) q/ V" M- U9 T/ e4 p2 D
{
4 h8 C9 H. E; [0 G2 j- I; w        FLOAT        fClock = nes->nescfg->CpuClock;
: m4 f  M# h/ H  K        INT        nRate = (INT)Config.sound.nRate;
" o3 U4 V+ f% i1 i$ i" J! I        internal.Setup( fClock, nRate );+ {2 F* T" d5 b' W8 z4 W0 K" ]
        vrc6.Setup( fClock, nRate );
5 k/ c% A" Z; O* v9 i% X; G        vrc7.Setup( fClock, nRate );
+ O6 p0 p* K, C7 k2 K& y* L" g        mmc5.Setup( fClock, nRate );7 w& L: K6 |  ?" f+ c% S
        fds.Setup ( fClock, nRate );# J* w% H6 J* p/ N8 P
        n106.Setup( fClock, nRate );
) M0 c; C5 A9 ]- o        fme7.Setup( fClock, nRate );* w" v6 q1 R' O3 }
}- t/ Z& y" i  a% U/ _4 u0 @
8 f% E# p& E. M" o% s5 ?+ W
void        APU::Reset()8 _/ c9 N4 O6 D- J! Y$ N9 M" X
{
7 D3 R5 {+ n9 j" c7 r        ZEROMEMORY( &queue, sizeof(queue) );! u; d  X' P  c
        ZEROMEMORY( &exqueue, sizeof(exqueue) );$ T- a9 u( `  s/ N2 L$ `3 y
' ]$ J4 Z+ u& H5 _4 @& a0 R0 M
        elapsed_time = 0;
7 Y  x" a+ D( d8 T6 P0 w: O- g8 K
9 \" \6 X5 c6 t( z        FLOAT        fClock = nes->nescfg->CpuClock;
1 t! U' l3 p0 D' v- x        INT        nRate = (INT)Config.sound.nRate;  f2 J1 ?' K9 R) u
        internal.Reset( fClock, nRate );
" z: @- G& B; U* G5 A# ]        vrc6.Reset( fClock, nRate );( |5 _/ F9 J' {
        vrc7.Reset( fClock, nRate );. ?# P( i: F7 Q0 |3 o- _6 D& h
        mmc5.Reset( fClock, nRate );/ Y: {6 m, y* n9 k- j1 }) r/ X
        fds.Reset ( fClock, nRate );
  t+ n, s; L6 Z; u        n106.Reset( fClock, nRate );5 T- q5 n5 j& Y
        fme7.Reset( fClock, nRate );
& s& O$ K; b) J( O1 K- c9 X# p
# s: V% \, Z/ N$ ~! P- T, C        SoundSetup();/ D. C# A: U" H
}+ }3 |8 K3 }% N8 K4 M9 E
# Q6 r! g! {2 U& M
void        APU::SelectExSound( BYTE data )
4 R+ g  @  C# k9 R& J{
7 m/ @, o/ r  D, W9 ]        exsound_select = data;
. D& U7 a/ D2 l4 D; B& v1 }}
6 }" E5 k$ J# Y, F8 q. y; h
; Q4 o% {$ L% |6 iBYTE        APU::Read( WORD addr )
% g1 q5 U/ l/ U3 c, Z$ m{
  q& n+ ]; g8 b! t        return        internal.SyncRead( addr );/ |0 P& k/ [9 ^) W: m7 h; Q, O0 z
}
0 x9 z$ i1 n. U
3 J4 b+ l# p6 @void        APU::Write( WORD addr, BYTE data )! f. R/ n/ k3 k( L+ T1 K7 N9 C0 c
{5 |8 r4 H' t' ]1 D. J% g* F
        // $4018偼VirtuaNES屌桳億乕僩
5 W; C* x, ^( D2 ]# [        if( addr >= 0x4000 && addr <= 0x401F ) {
7 s4 I, g4 _) Q( O2 L                internal.SyncWrite( addr, data );
8 h. L# W" `( V4 R; B                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
2 v) m  F2 J& e  Z+ H# B        }
- [; ?, K/ B7 @. j}: G6 R/ \+ B' T  i7 {

0 _# S, z! j3 Z  {# y* w/ i! |BYTE        APU::ExRead( WORD addr )9 q6 }1 N% G- [2 M: u: [1 B+ k
{
- W' H  |) _: c7 J0 N, S3 DBYTE        data = 0;6 ?2 E% h$ p3 q' g

7 ?2 y& f2 R) {6 G3 C3 O        if( exsound_select & 0x10 ) {3 U( x* }: [% E5 e4 p
                if( addr == 0x4800 ) {
9 C/ L$ j# P5 m8 A1 R! b& O                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
8 o/ o$ B$ m7 f                }
$ O2 y- M( h8 q' G! F9 `; F        }' _3 }1 e! d1 ?* n6 a
        if( exsound_select & 0x04 ) {
/ ~3 {+ {/ @6 n                if( addr >= 0x4040 && addr < 0x4100 ) {- Q4 w. }! X$ \( {% H  N
                        data = fds.SyncRead( addr );8 E: N! u, |3 ~+ F
                }
$ u) M( ~: k2 A. k        }
# @; G! v) k$ }; R& _6 z* u        if( exsound_select & 0x08 ) {; Q( x& p  g1 [3 |; V+ q% s
                if( addr >= 0x5000 && addr <= 0x5015 ) {
7 ^4 n& Z( f' K* R) T! [7 c/ Z                        data = mmc5.SyncRead( addr );
% b# w) _1 T6 |7 W! a1 L3 m                }
- F: }, {1 S/ v        }
! Z6 b1 W1 q8 D9 i9 v4 X! n9 O+ b) I2 I, E
        return        data;
; k7 h* [/ W* p9 H# N( n) L. L$ i}) Z2 q! n& J! g7 n

/ G4 H9 [  V6 o) ]void        APU::ExWrite( WORD addr, BYTE data ), d6 l; |; c- w4 P, D' f: o
{; I( h" o  `7 _6 E* t9 u0 H9 }
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );# m- o% ~) p4 Z) G
  X$ [% b( h1 V4 i% E1 H
        if( exsound_select & 0x04 ) {5 f  g" \- m6 I- U  P% T5 s
                if( addr >= 0x4040 && addr < 0x4100 ) {
! A7 z% X) J0 a& b: \                        fds.SyncWrite( addr, data );
8 _5 X4 q5 l& `- |8 y/ S5 R+ k                }7 R) b6 K4 u; E, e: R
        }1 e  p; t8 D% ^9 r
* o& X, Y9 h' E9 H& _1 I- L
        if( exsound_select & 0x08 ) {
, T/ ~- h* u$ P5 C5 E                if( addr >= 0x5000 && addr <= 0x5015 ) {
7 p8 R/ }/ [% k3 m9 B                        mmc5.SyncWrite( addr, data );  S0 M* ?5 K5 u2 s% A1 w
                }
" ]* Q$ g$ j' m: x! H5 a& l        }
; p5 n: o  j! \. T}
. Z+ J! S& |1 z6 x$ r
4 Z  L& g( W9 Yvoid        APU::Sync()
1 D; E7 a9 H. [1 [) [{. r, N' C" P! I( C! F
}
1 ?5 J; [" g4 r$ ]) I0 [9 y" {+ V, C* \1 t4 d+ O6 d9 I7 U  r* k6 a; I
void        APU::SyncDPCM( INT cycles )
: A0 ~! `7 \2 b; V- v& x{4 k6 E  B2 Q. c( A/ T
        internal.Sync( cycles );2 Y8 Q* w3 i; O' C& ~. C7 x( N4 |  l  _

" A4 ~7 Y$ s9 C- L. d        if( exsound_select & 0x04 ) {( L( t( L5 t' F1 o% S' C) @
                fds.Sync( cycles );
" z% A7 w1 S/ l& ?6 ]        }
' ^7 T$ F6 p0 F; O        if( exsound_select & 0x08 ) {, }9 P  f1 t; g5 `
                mmc5.Sync( cycles );& m3 K7 W( P) ?4 k4 D' F
        }2 l+ I6 }6 ~/ A: i) a* U
}7 Y: u) T' \9 E$ ]7 |' n  b1 k
% B# C! w  n" z' }% }' j4 B% ]* o% `
void        APU::WriteProcess( WORD addr, BYTE data )2 Y- g/ ]5 b% k* \' d3 n
{
  f4 ]* ?! y, [5 e        // $4018偼VirtuaNES屌桳億乕僩- e9 B; b, f6 b: u
        if( addr >= 0x4000 && addr <= 0x401F ) {6 u' r5 w# w+ w
                internal.Write( addr, data );9 A' X; {8 x9 l5 Z0 G8 |
        }. Y0 C' w) e; o
}
; g' f; |) o5 C# m" N
( I0 g% a/ I- n: Z0 Fvoid        APU::WriteExProcess( WORD addr, BYTE data )  z1 C* X  W: g; h1 O5 q
{) f; ?; Y0 a6 q/ Y! n$ I- P
        if( exsound_select & 0x01 ) {
: F" b, j6 W: I                vrc6.Write( addr, data );: R! L7 V, J1 [$ W6 B- a
        }  x" {# u  t4 H2 C/ B: p
        if( exsound_select & 0x02 ) {( U" x# V1 o: m" y: \+ K8 G- B
                vrc7.Write( addr, data );
# o0 x/ E( A! h6 H7 L        }
% z; @. ~9 R7 ]  v) n7 {        if( exsound_select & 0x04 ) {
1 w/ O$ q* D9 \                fds.Write( addr, data );
7 D" w/ U+ v- z! w        }3 O% W1 a  ?. y3 D
        if( exsound_select & 0x08 ) {# |9 q# Q4 S6 S6 ^. N' U
                mmc5.Write( addr, data );# Q' |. c& E" t6 H0 E& F' R* H$ [
        }
! f4 ^$ Q% N' q5 b% z" T- W        if( exsound_select & 0x10 ) {
3 X! d  s1 z  I5 ?9 N9 d; Z                if( addr == 0x0000 ) {
+ o) g, j2 _: T5 C" x4 q                        BYTE        dummy = n106.Read( addr );# t' t* S) K& q
                } else {" u: D- _2 y1 W  L' N: P7 H
                        n106.Write( addr, data );
+ F9 E( D- W# O/ q4 D% T                }
+ a, q' i- c/ R5 B        }
* n0 ]" Y2 F, ^1 x3 v' i" ]" Y4 J        if( exsound_select & 0x20 ) {6 x4 S0 h0 ~" h
                fme7.Write( addr, data );+ I0 r8 `2 C8 G
        }
; ]! {# M! `  T$ ^}! o" p4 Y9 |( S5 Q! i+ ?

* t1 b6 A& l! X! v, N8 f- F$ xvoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
. x& L2 c3 L/ Y9 Z: F% M{" _4 y* G8 C9 @( Y- Y8 V  l
INT        nBits = Config.sound.nBits;
3 Z  |1 M8 K( T& l4 }DWORD        dwLength = dwSize / (nBits/8);% {) j6 A" p5 s( X4 Q3 l
INT        output;
; R4 A& U# y+ d+ ~  X. M) GQUEUEDATA q;
0 @1 P9 S. [& \0 y8 E! gDWORD        writetime;
  L# _  V3 }" l$ ^% O3 |! o
0 B; N& _2 X% F* z" `LPSHORT        pSoundBuf = m_SoundBuffer;! B7 ?( a, C0 T$ b: V
INT        nCcount = 0;
9 }/ h1 I& D9 t/ N( {
! c$ n# F) I5 s& h4 b, j1 a  G. MINT        nFilterType = Config.sound.nFilterType;9 N: \; n' V* ~5 ]# ]
" J  E% m3 b2 d" T6 s4 H
        if( !Config.sound.bEnable ) {$ S. I* g% E5 Y  y, \; Y
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );8 V, x, N. B! X+ y  E; K9 K) {
                return;
+ Q+ _$ J7 f, G0 \        }+ m4 m0 l  u) |) N6 b+ Q4 v
* V: E9 f/ I& G4 N
        // Volume setup, Y+ i. k/ w. H: ]
        //  0:Master
8 {' Z" x2 G* }5 F        //  1:Rectangle 1, p2 @4 t1 u5 t2 Y! h- t$ ]  I" ]7 U
        //  2:Rectangle 2# s3 w* B1 h7 L/ E1 h
        //  3:Triangle
# o6 z+ B/ b1 s0 A% O        //  4:Noise
% V! m2 T" a# z9 V* Q" j) y        //  5:DPCM
# M' r8 M3 G- {% i1 E5 v4 S3 H        //  6:VRC6
* h8 v5 h; s; L% Y        //  7:VRC7$ U" [: a. \) Q7 ]! T
        //  8:FDS* K0 q' c/ P; l) {& @
        //  9:MMC5
. W- H# Z! Z% @. A        // 10:N1063 h) F. D! ]3 u6 B1 e) X) b4 R0 h
        // 11:FME7
4 t: `) o. d4 V& {& A        INT        vol[24];4 L7 M9 e9 }9 ]8 g( F
        BOOL*        bMute = m_bMute;
% Y: A8 p9 a/ o$ D$ a        SHORT*        nVolume = Config.sound.nVolume;/ |; A! d9 {$ ?
! }" ]7 h% O* T( U
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
8 {" k9 M  t" R. B6 ~* [- _" ~: M& u, p
        // Internal5 s$ {9 ?# L; D, F
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
$ J; K6 V" _5 R$ A        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;9 J( X, k$ U& X8 ?8 V  W; f
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;5 Z/ J2 m- [. y3 p' \
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;* l- o; d% t; I6 S, L( v
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;3 ^4 e1 ]( c- U5 g

/ P. n1 T* X8 u) e- u3 n/ V) r        // VRC6, a# ]+ _  n. _% W- m
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
, p2 e6 G6 V7 x        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
- g5 p2 c! c( }. f* {        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
) j* A/ m8 W0 C( ^7 Q0 O$ R# |- q9 @' G
        // VRC7
* _7 m, O, n) d" f- H) r7 M        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;# R/ M% R! w$ C; o2 V
3 Q+ Z$ j; d0 J7 I. L" b# \1 ~
        // FDS) U) K6 O2 e- x# u% w9 {* q
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;! k: B: T5 G$ H

7 K/ w" Z3 F4 y& E+ i        // MMC5/ c) m6 T5 f8 Z9 b
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;2 l( X4 E3 O! B5 z. ^7 e, B6 P
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
  G' ?1 m2 a+ O! ]+ ?, t' M- ]        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;2 j# I, J' M6 L, I* x
/ u0 K& w% Y- b; R( X
        // N106
6 K) ~- L/ d- i/ z! o        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
' T7 {: B: e- o' G7 U4 T        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;6 }+ z$ z5 U2 G) v$ [
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;; b  Z& d# X+ a- ?# E$ J& u( @% K
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;! [5 p- w- }& s3 u) j' ?
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: \) S" _  [, [. u, n1 j& z2 S        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;- e+ \' b! a- A$ ?- L7 h% \2 X2 ~
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
% R! G7 V: k& _7 S- G        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& G9 z- G$ K7 i' H6 b0 i& B4 g" L& q! F+ l
        // FME7
" B3 m2 e% N0 a  g        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
. }! p' D" f! L! N  v        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
! t1 O! z" l% O* s' K1 d0 d        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;5 ]8 m9 b& j( b% L) V

( ~/ \2 R6 S2 f6 z- x8 R' q. j& X//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;; Y) y3 X+ z% i! i( r2 m
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
  L+ Q( T$ T( h' {9 T! J& S0 Z9 J! w/ G9 m
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟$ r/ y9 o: _3 @8 f1 B; Y- M5 v
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {: Q% Y( A0 i  F- E0 E7 d
                QueueFlush();, U8 `  R& \" Q  l5 C
        }7 G' `- z, i- T3 k6 S( ~, l
* R- N5 n- S$ A$ d! ^! s! b
        while( dwLength-- ) {( w, z9 z7 y0 b4 h3 ^' P* t
                writetime = (DWORD)elapsed_time;
. |& ~& w' \4 y1 I# H  [/ p* D4 |7 g6 S2 X+ Q. P
                while( GetQueue( writetime, q ) ) {
4 {: W( K" m6 o# e: o                        WriteProcess( q.addr, q.data );
4 S0 |" K; }5 C                }
# {# \. g6 d: l
% F( M# n0 @" B8 a' V: V                while( GetExQueue( writetime, q ) ) {
7 ^3 _. ]& K, W- F) v                        WriteExProcess( q.addr, q.data );8 {& p4 O' S8 J4 ~
                }5 l8 X* ?) e2 v9 H

5 K3 |) G0 I* H) o8 |0 ?) z. U                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
8 R5 R# M3 q; A1 X  k& K                output = 0;* _+ V$ S: x0 g
                output += internal.Process( 0 )*vol[0];
, b/ ^6 O# F. s, u* w                output += internal.Process( 1 )*vol[1];- z6 I7 k; I+ L4 l, a
                output += internal.Process( 2 )*vol[2];
  W3 X8 u9 d1 h                output += internal.Process( 3 )*vol[3];
  Y2 G5 H1 y" n+ D5 b" }1 p                output += internal.Process( 4 )*vol[4];! S9 e7 N* l/ V, `4 j

% l1 j& J% \+ }7 M* ~                if( exsound_select & 0x01 ) {/ {4 {9 w: G' a
                        output += vrc6.Process( 0 )*vol[5];+ @% q0 P* E4 U! ~' g
                        output += vrc6.Process( 1 )*vol[6];
( l* ?9 Y" ]. \( F# f! j$ _                        output += vrc6.Process( 2 )*vol[7];
, J7 m" [& g. c- }$ r2 v, n                }
8 K8 v+ Z# c9 c" U+ M                if( exsound_select & 0x02 ) {
( N3 |% z  _5 S3 p( q, w                        output += vrc7.Process( 0 )*vol[8];
9 B9 O' R2 ]' a                }
# v& K7 [$ @- p: i& ~# ^, D  j1 e                if( exsound_select & 0x04 ) {' ?$ K0 ?9 K& `) N5 ]
                        output += fds.Process( 0 )*vol[9];6 z% D1 O2 ^( {, v) ]! ?6 M
                }9 N# U, @0 U0 g" Q: g2 L% @7 [; N
                if( exsound_select & 0x08 ) {% L. e% r4 E: r( W' g! {  i, v1 [' Q
                        output += mmc5.Process( 0 )*vol[10];, Y6 u6 f  f: z& P* f4 e5 O
                        output += mmc5.Process( 1 )*vol[11];9 ~, ~8 u9 G. C' D
                        output += mmc5.Process( 2 )*vol[12];
& n7 o- d" p" z                }
+ c# X; B* O7 n9 Q. D                if( exsound_select & 0x10 ) {
+ O1 S( L) X; e8 q                        output += n106.Process( 0 )*vol[13];
5 G8 X7 L5 Q( m8 v; [                        output += n106.Process( 1 )*vol[14];
: Y1 P: h' |9 C) R& c                        output += n106.Process( 2 )*vol[15];6 z4 R# }( L' Y9 t
                        output += n106.Process( 3 )*vol[16];
  \' z0 Y/ g  \/ S+ N5 m! {                        output += n106.Process( 4 )*vol[17];) H6 C' J) t- P% O
                        output += n106.Process( 5 )*vol[18];
3 G# M" L2 A, W% b! i1 [                        output += n106.Process( 6 )*vol[19];
: K9 E2 b" B* N. J0 ^6 }                        output += n106.Process( 7 )*vol[20];. V4 ?: j1 Y* o2 B0 E* \/ u/ Z
                }$ J5 @: {  U/ a0 @# W( J
                if( exsound_select & 0x20 ) {
% Q; U- v. Y9 P4 \4 @2 ^                        fme7.Process( 3 );        // Envelope & Noise
0 a- t1 r. a: L                        output += fme7.Process( 0 )*vol[21];
" w1 n4 l) k$ S3 g4 p% X2 f                        output += fme7.Process( 1 )*vol[22];/ K" }$ \0 k* x* u1 i) A, |) r
                        output += fme7.Process( 2 )*vol[23];
% r0 V0 n- N4 @( L# e( E' `                }) q  H$ j- F! P9 ~  n, c

1 h0 M2 }- Q$ V                output >>= 8;. z  X' z$ C8 U; r) E5 K
8 `4 a. @. D' P- r- P; d, a5 K6 s
                if( nFilterType == 1 ) {
! T" R! v: I- Y5 v. v                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
8 @1 B, K3 Y1 h% W" A  `                        output = (lowpass_filter[0]+output)/2;
; ~: Z' t  k/ d2 X& n' d4 F0 y0 h                        lowpass_filter[0] = output;6 R' F& ?# W; w4 c% D0 ~, _: _
                } else if( nFilterType == 2 ) {+ I& b- R6 B! b; O
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
8 F  y6 [- j0 O5 d                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
" `3 G5 c+ Y4 `                        lowpass_filter[1] = lowpass_filter[0];7 e5 C& P9 e) H2 t& _2 B2 R
                        lowpass_filter[0] = output;
- y' [8 m" k! L" R+ s7 o                } else if( nFilterType == 3 ) {
2 z7 i, L% Q( w  H1 @' \- J( J                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
) G) l6 S7 e+ \+ t: k/ _                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;! C% A* v4 ^* m
                        lowpass_filter[2] = lowpass_filter[1];
0 h6 ]* q% R; V& @/ Y                        lowpass_filter[1] = lowpass_filter[0];( S3 f  @$ `' D
                        lowpass_filter[0] = output;7 c8 ]+ S2 o5 z+ K" a+ D
                } else if( nFilterType == 4 ) {* a( a& T3 P9 ^! d: {
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)! G! L( k) B7 }( K+ T" G/ Q
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;  I9 K/ ^/ r  `2 o7 [# M
                        lowpass_filter[1] = lowpass_filter[0];0 ~  c3 I" Z% q& P% B3 I( F  ]( _+ f
                        lowpass_filter[0] = output;: c7 |+ w. k' y
                }
+ E$ K( y+ o6 k4 A. Y$ Y& B0 i6 c  y! v! P9 L7 ~% _/ W6 q" \
#if        0/ ^2 U& N* t% ~# O
                // DC惉暘偺僇僢僩; H+ R7 G0 N7 {3 m) l+ S; A
                {' X  q0 n& l$ W% ~4 {8 F
                static double ave = 0.0, max=0.0, min=0.0;
( e# Q8 c$ i8 _" T                double delta;
: Y. C) y! ]. H5 l" V5 v                delta = (max-min)/32768.0;* ]) F, p- f: ?4 D) o7 F
                max -= delta;3 B! A2 G1 n4 }" |
                min += delta;: c/ K  X8 O! t
                if( output > max ) max = output;( d8 E. q+ Z3 l1 t6 h! B5 ^  D# [
                if( output < min ) min = output;
  \& H7 a, ]" n                ave -= ave/1024.0;0 n3 V3 n4 e( z
                ave += (max+min)/2048.0;
0 r$ ]5 x- t( S6 K                output -= (INT)ave;
7 `( M( a9 k9 d, N2 C  z                }
; i* z% x! d/ i#endif
4 V. Q9 T" a* r+ ^. S#if        1
' h4 B! u9 ]* \                // DC惉暘偺僇僢僩(HPF TEST)
) ~* ?3 a, i; a$ N- [- o& b                {
4 c* i+ n" ?, ?! F//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
5 m; V" w; }- n9 i, Y5 s  K8 F, L7 S& X4 F                static        double        cutofftemp = (2.0*3.141592653579*40.0);
) z+ _( W% P5 h                double        cutoff = cutofftemp/(double)Config.sound.nRate;4 x' v6 p" C& v  b  j4 F
                static        double        tmp = 0.0;& \# w* k: l; o% b& q: c9 G6 }
                double        in, out;
& r) _& D% g( v3 U9 |2 o: J3 k7 _. Y# V
                in = (double)output;# W$ j1 T# [. C* B5 Y1 W) P, n
                out = (in - tmp);% L! x6 ~5 I$ G) a
                tmp = tmp + cutoff * out;( d: o8 J$ [3 P0 N% F; r
; w$ I) @8 }0 ?6 ~
                output = (INT)out;' P. h6 _' u! z0 s6 b
                }% J! S, A* }$ \. c; `0 E
#endif6 L' L0 M" a9 v" N' j* T
#if        09 b0 S9 }, t/ W2 B/ s- n' N4 B' b
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)6 [# w; o; V5 C  O
                {
1 _% d( D5 }7 I  p) v                INT        diff = abs(output-last_data);
, }$ Y* b4 i* }& y: l: X, X& \9 y                if( diff > 0x4000 ) {
0 W3 r( f2 g, S* h                        output /= 4;9 r$ C2 `; h. b2 f" x5 T  t
                } else
0 Q8 L6 }% F% U$ u, M/ ]' H                if( diff > 0x3000 ) {
' \# C$ r; \( j* R- f8 v                        output /= 3;* T! r" w6 o2 N$ X
                } else
  }$ ]; R  J7 k7 [0 N                if( diff > 0x2000 ) {/ t! q( u" s- S& E3 P
                        output /= 2;
$ ?; }( ?5 j  H$ G' S                }8 u8 A) b$ _5 H5 Q8 ?( e5 Q
                last_data = output;
! u) d0 D0 V4 q6 z2 t                }, Z( ]2 ^8 F. v) m6 a8 ]( a7 s
#endif
5 y6 u9 J  ~1 b8 g                // Limit
4 ?3 @7 h. g! F! e                if( output > 0x7FFF ) {; g5 v. y3 X* }- r& E% A$ L
                        output = 0x7FFF;
+ l8 e: O+ ~6 H7 F                } else if( output < -0x8000 ) {
- f$ V% g) G, t+ H  E3 e6 D                        output = -0x8000;; j. U  F! `. Z. E5 e5 d0 q* w0 g8 ]
                }
1 S0 q8 }$ ^5 ]9 J# G2 |! R5 z$ D8 ]& N
                if( nBits != 8 ) {6 A5 p. J7 X7 G7 v- u2 U. w) n, g
                        *(SHORT*)lpBuffer = (SHORT)output;
# B1 v+ t( v' A                        lpBuffer += sizeof(SHORT);
( W0 I: [1 h# ]! m6 G                } else {
0 ?) K- s& F" e1 x7 t# |: M                        *lpBuffer++ = (output>>8)^0x80;
: e0 I2 N6 \$ j( H* S) I2 s2 k& ?                }
* X. L  D) M/ O( G; X6 Z% ^; |
3 Q) R2 z6 Z" Z6 n4 L" f& N                if( nCcount < 0x0100 )
5 o) n) B2 g" |" \# q1 v                        pSoundBuf[nCcount++] = (SHORT)output;. z7 ]; m: N4 F' f! _
6 G+ a- V7 b5 j2 @/ o, J
//                elapsedtime += cycle_rate;
% a' O  W# K3 J4 h& ~" l- u5 c' u                elapsed_time += cycle_rate;( [& k- b8 N1 a/ \! I. \
        }. k4 D7 b  d' r$ p4 y% B; E, ~+ }

. `/ g: q, b3 M#if        16 Y9 {0 @( j8 Z8 y  B
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {" J( W' z1 ?# g$ w5 M
                elapsed_time = nes->cpu->GetTotalCycles();9 [" d" ?" f1 `) v4 w( F' q
        }
# S. y  Y, G: o8 R" v+ J5 e        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {& k  R7 `1 c; W8 B/ C" i" {( x
                elapsed_time = nes->cpu->GetTotalCycles();
- J, e$ N6 [8 T, \7 _# c        }# G8 b- \4 x  C* C$ a/ o; G- a9 l3 I2 [" h
#else
+ v5 K9 Y$ H4 R* S( R2 B% n        elapsed_time = nes->cpu->GetTotalCycles();
- V* a$ \" d. [. m# ^" z  X#endif
# k  Q, L) T6 y9 C! I9 x' E}( f5 B) A# C6 D$ P

% A/ ?& ]; |# s6 W. r: _// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
9 X) N  y9 [7 e' ]9 Z2 {6 jINT        APU::GetChannelFrequency( INT no )
" T4 }9 W! |2 Q% h, }{
  z: M1 b. S2 G+ \* ?        if( !m_bMute[0] )7 K! M" U4 [- L. W5 v
                return        0;
! f( r# d9 j' {+ g# p/ j2 v/ t$ `
) J' Z8 J' {( f( E2 g; O# A/ V        // Internal5 [1 ^7 l- [+ u0 r( c
        if( no < 5 ) {
; c+ _5 b1 c0 o                return        m_bMute[no+1]?internal.GetFreq( no ):0;
5 G3 n2 l! Y( Y        }
6 N1 r7 g0 F5 u9 J        // VRC61 f( Y  e, L1 |2 U0 L, X# q/ f
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
! e+ Z0 r" }# |6 p" D6 z5 s8 g! H; s                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;* z8 ?, q! S% i6 O# @' |! t1 s
        }
4 Y2 W* X+ f  |: g% l& f7 q. H2 v        // FDS* ~6 x( O6 }% ]' F9 s7 L, q! ^5 g
        if( (exsound_select & 0x04) && no == 0x300 ) {
. G  g$ }5 G* e                return        m_bMute[6]?fds.GetFreq( 0 ):0;
4 @1 g+ c% @6 A/ S4 b: X        }, p6 F) O' j, R5 M
        // MMC5$ Z/ s% H2 w$ z9 @  w
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
- L5 r$ u4 }$ c% f                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
# L7 D" g" `6 b6 d0 K! s) Q: m) _        }
; B  v& h! }1 n$ ^3 M: m9 M* ?8 F        // N106& W6 @0 q1 F3 }, p, A
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {5 K7 s: h1 S* ?- h4 t: S6 @' v; c/ ^
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
$ m; t' _& s2 B        }
  k( y  X" l8 G5 q% A% r8 i/ m$ a) h        // FME7
$ G4 ?* V" s/ q+ C: D        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
3 L5 C% Y# S/ U& K9 H. \                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
9 u/ _  P) T$ d/ I! U2 w3 l        }
) p  T0 D: z) B! \: I% l0 ?5 v& c        // VRC7
% y+ R. w2 G$ G7 w, ~) u- V, q2 D        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {( ~3 s4 b8 v4 Q. ]. Z+ ~( U  k, }
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;( c  A& x. U! D9 N4 e
        }% Z" i$ o& Z1 y9 [
        return        0;
0 i; m1 r1 _9 ~( u% D1 u# R. }}
: _6 P% N9 B( V0 c, o1 f5 j# _4 e7 u
// State Save/Load& W; \0 k) _( L; X: z
void        APU::SaveState( LPBYTE p )' c8 x6 b2 \! \) t+ E3 j  C
{
. P" N0 q, ?3 ], X/ Y1 h5 J#ifdef        _DEBUG/ i5 z$ b  F( j3 T& c* Y$ A
LPBYTE        pold = p;6 V3 x8 G) k7 s# S
#endif$ Y! U. X  s  F( b9 ^$ `

, s& Y8 O; c. P        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞8 N9 h! D) D3 P; J# h# a& C
        QueueFlush();
8 e4 l$ i* v, a7 R. }( b0 `0 V( s1 t& ^) h5 l
        internal.SaveState( p );
: a+ }4 k, W& e, {        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
2 c1 V# j- O3 N; [4 }( Y
% K6 {8 ^5 H* K: z+ [$ T' S        // VRC6
/ s  v3 Z: B& x3 _' j: f8 d$ P        if( exsound_select & 0x01 ) {
) D9 v3 c& v6 n/ C                vrc6.SaveState( p );9 R% T; Q/ m3 m4 g' ]% u
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
( [4 {# h# {/ `6 y. a+ W        }
7 f, s' p+ y/ s, W$ F3 s% i4 d: F        // VRC7 (not support)
/ V# T9 I, \* }' q        if( exsound_select & 0x02 ) {. R* p2 a* X2 d6 _: L
                vrc7.SaveState( p );
2 ]" P7 x9 b! M( m/ Y) ]/ C                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
, N- R0 Y! i! I$ r5 j8 a# k        }% q' x2 r. K0 i% f* `
        // FDS
) E8 i) i/ Y( p! n: E. d1 F2 D        if( exsound_select & 0x04 ) {2 P% z1 \$ \9 K
                fds.SaveState( p );& ~. ^4 n3 ^& c  A% F% D$ Q  W
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding% H5 j; @# @- h9 ]+ n
        }
& t  K- k& I& |! O% ^- N% g. i        // MMC5' y3 J7 L9 A, ^- H( ]2 _
        if( exsound_select & 0x08 ) {
! V. a  \7 \" J- W5 G                mmc5.SaveState( p );
% k: [' F9 {' B: _$ Q8 P                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding5 g1 e5 [# g& i* {% R
        }
! w, T3 ^6 J9 r- y# L( c, k; f        // N106; k1 ^$ U1 ^+ j4 K) O
        if( exsound_select & 0x10 ) {
% U3 p8 K& r! L2 V* Q+ {7 @                n106.SaveState( p );
* M1 t% Y6 F7 L4 n0 @. C                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
7 Q; G  m6 a  X* |$ T3 o        }# P/ D, j. ]  t: U5 a
        // FME7
7 D2 C2 [: s1 M3 H* J2 ]3 A! G9 H! u        if( exsound_select & 0x20 ) {' a/ {& Q! l$ P" J
                fme7.SaveState( p );8 m" ^' J( Q0 H0 E" l! q
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
$ Y  u- F- s& P; D& W3 g        }! @" H, X( s, i
0 o- u* N! K- D2 z1 G/ b- Y
#ifdef        _DEBUG4 L( z* r9 \4 w& f- o6 K0 d( |
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
( \% q8 h: N* o7 u5 Z! B. C#endif
8 B- `+ u/ c* x2 n! J}% t' _% }4 r, l% \

4 Q: j. H$ o% e) t& Uvoid        APU::LoadState( LPBYTE p )0 J8 R- t0 {" Q9 W, S$ w; x
{
1 q9 }4 ?# V3 G4 N        // 帪娫幉傪摨婜偝偣傞堊偵徚偡: h3 X3 l4 ^: q6 @9 K! K1 N5 D1 k
        QueueClear();& F4 G( `; I& n% i; ^, Y
" C* Z- G1 Z6 L5 K" Q8 B
        internal.LoadState( p );9 ~9 Q, x! |) v2 V
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding' E6 `$ E- H5 ]

# N* n% {  H/ b; `0 C6 t# F7 D" @, t        // VRC6; ]7 ~( y! d) x- Y4 ~3 \
        if( exsound_select & 0x01 ) {
& h2 [2 m7 a& _                vrc6.LoadState( p );5 d% |9 }% f0 `
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding7 j7 I+ m7 C- \7 I7 [% O$ J( _
        }8 M# J% P# C- ^: t3 t
        // VRC7 (not support)1 w$ t& y' }9 r4 o# ^: m
        if( exsound_select & 0x02 ) {1 v% _- a, \* B7 X6 d
                vrc7.LoadState( p );
) R6 ^' [& I' x  ]                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
. u$ X: V7 b- B: H) {        }! o; L( `. I% `) {5 O4 ^- l
        // FDS0 R6 S3 N4 Q' A9 j
        if( exsound_select & 0x04 ) {2 H% ]1 x* ?' N5 C
                fds.LoadState( p );
% h+ J: k1 u9 Z                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
: R) Q5 S" h  B" R6 z        }
  f3 C- B: ]% o        // MMC5' B% y: Z* u0 ?1 z- v( |
        if( exsound_select & 0x08 ) {
; p& \; x0 W+ N& p                mmc5.LoadState( p );
6 s1 u$ t0 w( o3 T* Y3 J                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
, M% y  B" v& d# N  Z, j& T        }
; h& F# i9 G3 r7 X; U        // N106
  H! y1 Z3 {. a        if( exsound_select & 0x10 ) {5 E5 q% r$ V! U/ ~& |5 E
                n106.LoadState( p );
9 ^' d: w: l( N' b2 ~% N                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding, W7 p  {/ y, Y& M) t& e6 C
        }
) J% M. u& x  b' ^* E        // FME7
* x0 `' P9 C: v" p1 k( q8 Z        if( exsound_select & 0x20 ) {; A% k" e( W2 D- Y( I: B' [
                fme7.LoadState( p );/ P$ X/ u# c6 @) a9 |( U
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding. C/ u7 ^" U' B6 c
        }
( }* o# M+ v0 @( l7 X/ J}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 - q- R; C9 x. t! q+ j
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。9 Q% L5 z* K6 y3 }5 U, [
感激不尽~~

! y3 P# x* h9 D% \恩 我對模擬器不是很有研究,1 J5 p$ w! c3 R' j5 ]* I. A
雖然要了解源碼內容,可能不是很困難,
+ Z3 N/ g# J7 ~9 c3 r1 ]; @不過還是要花時間,個人目前蠻忙碌的。
" }# F. Z2 h; t* K9 k" A: B8 `1 d2 }4 f5 M, _1 }7 J
給你一個朋友的MSN,你可以跟他討論看看,
: Q7 ^% o7 ?/ H0 W. q: ?7 s+ ]他本身是程式設計師,也對FC模擬器很有興趣。, J( f$ q! L" S# A
- m0 x6 k* e% u3 R. j+ I. }" Q- I
MSN我就PM到你的信箱了。
2 e/ o) _; V, Y7 N8 v
. Y$ S9 j& E1 x& r希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 ) X2 ^! I) n0 }9 S
呵…… 谢过团长大人~~

4 U; {4 k3 u! `' w) L( q' n& r9 x5 i8 D8 I
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 ) e5 p0 z7 Q) r) `! u
团长的朋友都是神,那团长就是神的boss。

% k& x3 d6 K7 }1 u! M哈 不敢當,我只是個平凡人,  ]  @  d# K' g3 I, a1 M1 b
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙% L- r7 ^: [, Q7 |& y
ZYH
; }! M- l# I9 OQQ:414734306% Z6 a5 t4 `! R1 ?7 G! ^$ M9 C
Mail:zyh-01@126.com7 I) ?9 y% _8 k- Z8 Q

1 f  O) f2 W+ \! d) R他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表
" P& j  ]% m, h( J! D4 V再次对团长大人和悠悠哥的无私帮助表示感谢~~

9 z# f+ G5 E- E2 R% C" B4 R不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-21 05:28 , Processed in 1.079102 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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