EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
8 ^% w5 m3 q0 B" S楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~- J& a2 Z% S8 J
这里有相应的模拟器源码,就当送给大侠了~~
+ x% y+ U. {1 n) w1 chttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
8 w6 e8 J7 W: v" I7 \4 r1 U0 h能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
0 w# A# _. _0 D( R" Z% l: _( I: d楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
+ U1 y7 b" e% k+ [9 ?: m0 |' ^5 p6 @这里有相应的模拟器源码,就当送给大侠 ...
4 x( `" Q" K9 @" l1 L
聲音部分(Audoi Process Unit = APU):
0 ~( U7 I' _7 H0 \# _/ I! v.\NES\APU.cpp
* d  Z- p4 G  W. w.\NES\APU.h$ z# P2 W* a5 ?2 u, ~

+ v* Z1 C) \# {. V1 }5 l  D' t8 r
$ k1 N, G6 V6 r0 R1 s! h2 O影像處理部份(Picture Processing Unit = PPU):" j5 a& j! {. J( ]& @
.\NES\PPU.cpp+ H& f- w# v; K. F, f
.\NES\PPU.h
2 D  y, p7 E4 n- S5 L' L) @3 U* @9 r' N2 C
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:, w% ?0 z5 c" H8 {+ S
(由于很多专用术语和算法机理都不明白,所以看不大懂……)" x( g  P; N- Q2 E9 g- q1 ?) _
//////////////////////////////////////////////////////////////////////////
3 J6 y5 `# h0 p- A//                                                                      //( [, M7 ^5 [- f( o9 h, b8 R
//      NES APU core                                                    //5 U5 i1 {, @- t4 k8 K
//                                                           Norix      //
% w- j& L0 O6 P  T//                                               written     2002/06/27 //
0 Z$ r% [  J: M  C. L) o+ I; y//                                               last modify ----/--/-- //
6 e! P7 U& e6 E  [( z; ~; g//////////////////////////////////////////////////////////////////////////: h3 l# V& t( f
#include "DebugOut.h"
3 F3 R, g( `- ~5 ]2 {, V#include "App.h"9 j% Z* `8 T, `4 g, L
#include "Config.h": a+ i7 V) u4 Y# W4 E: }' q6 T9 Z
$ x% P2 V+ g2 L0 G: F/ T/ U
#include "nes.h"# Q6 E. D1 t4 Y- p! c( x5 B
#include "mmu.h"
2 y8 \7 g6 C; K; [#include "cpu.h"1 D2 Y+ ]  z7 A$ N3 V/ o
#include "ppu.h"% f, K$ N) I) |3 e' N% s* }0 V
#include "rom.h"
5 ~+ |0 y' Z8 }8 k#include "apu.h"  t+ a( E/ ]" q. e

- J7 d! ^3 d" V& x4 i// Volume adjust
/ U) l3 `, [0 \// Internal sounds& D( N5 o' B6 g* ?
#define        RECTANGLE_VOL        (0x0F0)
0 @- O9 P# ]' x3 b4 ]# b& {! n#define        TRIANGLE_VOL        (0x130)
$ q1 l! e. I2 }' Y2 N#define        NOISE_VOL        (0x0C0)
0 @5 I0 \: c) p2 I#define        DPCM_VOL        (0x0F0)
6 S& t/ u8 n- g' g- v5 _( j// Extra sounds8 X" @! y( s7 D1 c2 G( @- e
#define        VRC6_VOL        (0x0F0). u# C" h( U) @2 B7 }
#define        VRC7_VOL        (0x130)3 h5 K) B8 Y) p" Q7 n  I8 @/ N
#define        FDS_VOL                (0x0F0)- d' p+ n- R$ j* y  t1 `1 S: w. t: ?
#define        MMC5_VOL        (0x0F0)
- i$ \6 V7 e8 p+ J#define        N106_VOL        (0x088)6 W/ u, ~- C! Y
#define        FME7_VOL        (0x130)/ V) E9 U1 j* b1 Z" m

/ E) Y* l- E4 v+ R% K) B- aAPU::APU( NES* parent )* s- o% |" w, g
{/ r* S* K# j) g  {( ?4 i; M
        exsound_select = 0;/ K' j8 b2 a7 d. M( D0 M
5 j8 x5 ?8 k8 W* ~) [+ H
        nes = parent;
9 r1 O( Y7 ]# {( Y0 e        internal.SetParent( parent );
' A, S7 G% e1 _9 F; S9 Y, a/ r; s, U
        last_data = last_diff = 0;
- w7 S( q2 A0 X; P- E, ?) M! W$ Y
% P) q1 ^* g% B1 R( t+ m9 G/ O        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
% V- J9 {2 r1 f% b2 y" ~% P+ Q) H
6 F1 c  {$ p7 ], x+ O        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
" Q$ |7 J3 b3 B* S% U& g6 O        ZEROMEMORY( &queue, sizeof(queue) );
2 H( i9 a! m: X: F& z5 A1 T: V        ZEROMEMORY( &exqueue, sizeof(exqueue) );
; M( l6 B3 {5 i4 q' ?3 q3 `, G% V3 N
        for( INT i = 0; i < 16; i++ ) {8 ]) K" T  M. c& J9 u1 z" I( c7 f
                m_bMute = TRUE;$ x' t3 b& \# K4 c
        }
3 s4 T. T/ R% o4 d}, |+ w5 x" s4 Y0 M
5 ]% O8 U" e2 A& r/ `( X/ ?
APU::~APU()
6 R, W6 ^+ c: @{5 h9 P$ r# G* H8 i% m
}
3 A0 B; H+ F! z9 Q9 p
0 T* F: N) q: W* P7 Tvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )8 k, X9 i. {; u8 ~% c2 D2 p
{1 Y$ f, ]. y: O( r9 a- o: l/ p
        queue.data[queue.wrptr].time = writetime;3 o* N9 O$ u8 Y0 q$ m' k5 G
        queue.data[queue.wrptr].addr = addr;
* i5 |9 f( _, w' Y4 {        queue.data[queue.wrptr].data = data;
6 x; k) \7 e1 n. {9 n1 I        queue.wrptr++;
6 D4 b+ Z+ `( }5 H2 |        queue.wrptr&=QUEUE_LENGTH-1;! u+ C3 |  ]; e. V
        if( queue.wrptr == queue.rdptr ) {7 B3 n3 `6 _+ @7 r' y8 E8 z' Y
                DEBUGOUT( "queue overflow.\n" );3 F- E& w8 I$ K; k, n# |2 J' @" ~) }
        }# Z& b7 X3 j4 J( Z" s. w1 w9 X
}" d3 @4 ?4 B" L1 r1 L5 a

% o' i! ~: W* HBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )+ N8 U$ Z  m  t; g6 {! i
{5 l' S" o( h9 e% r
        if( queue.wrptr == queue.rdptr ) {
* s& m2 u7 u' }                return        FALSE;
8 B9 m% S' O! n# p2 {! O* ~        }
& |" r4 f" {. L' i) O- S$ t        if( queue.data[queue.rdptr].time <= writetime ) {
, `2 }- ^/ k, `" r. u  _. y: {                ret = queue.data[queue.rdptr];0 c7 X- i3 N& Q1 C& a) `
                queue.rdptr++;
' `  n* S6 e0 D: b3 k                queue.rdptr&=QUEUE_LENGTH-1;8 u/ u# |- I1 `
                return        TRUE;) R0 |8 `" y( e  n- Y1 @) p& M
        }8 d0 L( m1 r6 F" ^
        return        FALSE;: k9 f' _! ^7 ^$ v
}
  m9 n! t( E& L. j8 c& Y( H, W+ C5 K- n5 e
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
+ N; {$ f& s$ x# J8 K{
) t+ x  c' o, g# A4 z/ B        exqueue.data[exqueue.wrptr].time = writetime;- G3 j9 }" h4 C( k
        exqueue.data[exqueue.wrptr].addr = addr;& a- L- f9 R7 M
        exqueue.data[exqueue.wrptr].data = data;) _( K- `) ]) Z. K7 r
        exqueue.wrptr++;
5 h( Q. n& @* q7 |        exqueue.wrptr&=QUEUE_LENGTH-1;
, M+ K8 s" ]- q% y2 b( {        if( exqueue.wrptr == exqueue.rdptr ) {
( o$ t" c; f' c) R  d5 P                DEBUGOUT( "exqueue overflow.\n" );- y( N8 s5 H. e
        }$ g  n5 c  l/ V$ M( \+ g
}) D. f8 _: A- O2 @" T

' @9 ~2 _7 {$ l2 K- p, e& y, ABOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )- M0 n6 n  m3 F$ E7 Z8 ]9 y2 i3 p; M
{
8 g- r. [, G3 N        if( exqueue.wrptr == exqueue.rdptr ) {
6 {' H4 q& E( {+ d) [                return        FALSE;
6 b/ v; F1 r( |  {) x6 s# M8 I( S        }
' O/ O2 X" B5 V: O  ~/ k7 B        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
- n" e8 b8 J( t# p0 ~                ret = exqueue.data[exqueue.rdptr];! F! Z+ y2 Q9 O8 x& t7 U) }
                exqueue.rdptr++;
+ S$ T6 D" U8 a5 s  d" q; n: }                exqueue.rdptr&=QUEUE_LENGTH-1;; C- M' a) M- P" u- v
                return        TRUE;
/ C4 E2 S' x1 D- `; `% l( H        }5 w- f! K! x* z$ l  ~' w
        return        FALSE;
# p7 R0 s. i# f$ t}4 m3 r. p7 r, z  k. e# P

& w! p8 ^, h8 M: E3 vvoid        APU::QueueClear()
0 [3 O0 a$ D) V" {{
9 k" g! K( B" p+ r; x* g        ZEROMEMORY( &queue, sizeof(queue) );
' q3 l" \. Q0 L        ZEROMEMORY( &exqueue, sizeof(exqueue) );
% x5 H0 t4 t9 Q7 B}
) @# f' V/ m8 C7 {, i
+ q6 _+ R6 J, i/ [. Pvoid        APU::QueueFlush()
! z/ Z( J% x) i) b! H" N{
+ Q; f, {. l( {8 Z        while( queue.wrptr != queue.rdptr ) {3 \/ c$ J" B/ D7 @* H
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
( t: _5 g, [) ]3 t* s% \1 V                queue.rdptr++;1 s8 V7 j; c6 d
                queue.rdptr&=QUEUE_LENGTH-1;( Z2 x" D& u$ W# W, e
        }
2 N( d: ]3 ~' }9 H( x9 e" P
+ |& P3 ^' E( J8 a, r* {- q        while( exqueue.wrptr != exqueue.rdptr ) {1 H! k5 i6 T- R
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );3 U$ R: N) k! F/ \
                exqueue.rdptr++;
9 [2 z6 Y% T9 O" I& C                exqueue.rdptr&=QUEUE_LENGTH-1;  A. J$ q% i5 G, ]" c$ @
        }
3 v- h/ H# C0 n4 w. C+ z}0 [( t4 c5 G, ~$ c. \% R9 D

/ ]8 L3 o2 S% F# B! ^9 \! dvoid        APU::SoundSetup()3 e: p0 {/ |% j) r
{
/ }- H% }/ U- L$ `# b        FLOAT        fClock = nes->nescfg->CpuClock;
" w8 A0 ]0 `: |/ y/ W1 D, m* L        INT        nRate = (INT)Config.sound.nRate;
. Q: H, I; _0 P! T. V        internal.Setup( fClock, nRate );" U  n  {  V  D" T$ T2 ^3 W' D
        vrc6.Setup( fClock, nRate );
% I8 M$ {/ S' S4 q1 e- ?' ~) w        vrc7.Setup( fClock, nRate );* I. ?9 ?; ~; I8 ^) j+ @, L! r4 b
        mmc5.Setup( fClock, nRate );) E& }: ^* h# ~( h) J7 j3 E
        fds.Setup ( fClock, nRate );6 F5 S& C7 m- u! v$ |9 A
        n106.Setup( fClock, nRate );$ M: m6 B1 t" O; _" R! r$ Y, H* ~8 x
        fme7.Setup( fClock, nRate );
" _; k) y# i, u; o4 W4 K1 M: J  b}
& e! X) x$ F8 U5 m9 l: A6 {" H
" @6 e8 Q( J- }$ jvoid        APU::Reset()6 h: m+ U4 p7 }4 z, b3 v& ?
{3 `2 l% [1 u' f. p; A! P
        ZEROMEMORY( &queue, sizeof(queue) );9 p3 X; M. p* s- o" D8 P
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
) r  N2 O. j" v1 @' V7 u+ m- j! h
4 X& c  e) z0 V, G% K        elapsed_time = 0;
/ Z( {" l, p- q! J- ^1 R6 O* P' S- z; t& P; ]# \
        FLOAT        fClock = nes->nescfg->CpuClock;
- K: \* p) U+ A1 P; h        INT        nRate = (INT)Config.sound.nRate;8 ~7 O9 q# L" \& ?9 m
        internal.Reset( fClock, nRate );4 l0 `( v! s4 {. K1 I/ i
        vrc6.Reset( fClock, nRate );! t9 f2 O, K/ ^" X
        vrc7.Reset( fClock, nRate );
/ N8 ^% e9 _( {+ y! f        mmc5.Reset( fClock, nRate );
& r' d- x" O1 m0 Y1 G4 T; E2 o        fds.Reset ( fClock, nRate );. ]& A# i* X5 l# y
        n106.Reset( fClock, nRate );
7 U8 }; y2 O0 X0 x        fme7.Reset( fClock, nRate );
* n) ?: i6 r: a; g  u/ b; o9 b6 |* w8 \+ s0 J& }6 }4 S4 V# E
        SoundSetup();% J' b, ]9 f3 Q5 u2 t, n, x. b
}# D! F8 G# }4 _% O3 N% H$ Z5 u, H4 [

3 m+ z2 A5 i$ A! Jvoid        APU::SelectExSound( BYTE data )
* b6 Q- J7 i6 w* |% D# N8 |{
" l: {0 u: ~. X  l) b        exsound_select = data;
4 o& M* l# H1 q4 K! N$ M, i}
+ _- L' A) W3 i3 _% g2 b6 R8 H/ z7 c2 l! v4 X$ q- }5 w* f
BYTE        APU::Read( WORD addr )" Z  [7 g( K4 c7 R. ~7 p# ^
{& b; M1 S: v7 z% B7 b
        return        internal.SyncRead( addr );+ I' c) S& n- [- M( o
}
; i1 G* e' v$ y7 Z
( e# y/ @( l/ P* C; }void        APU::Write( WORD addr, BYTE data ), ~; v- H$ t! n
{
' O8 E7 n0 G" C9 W        // $4018偼VirtuaNES屌桳億乕僩
+ M4 Q6 h3 A0 F8 K$ S3 P        if( addr >= 0x4000 && addr <= 0x401F ) {0 s  T6 B% H  R9 f' c* I& z
                internal.SyncWrite( addr, data );' H/ b: S( y; X$ S, Y( K" B: X
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );, p! ?6 O$ ^4 E( }4 p
        }- [4 @) W* t4 q. X" {" q7 {
}" a5 Q3 o0 a* Q% P
/ _3 _! W( k  Y  \6 \
BYTE        APU::ExRead( WORD addr )
5 S! _; ~. _9 k; _* I{$ Y8 c+ K) G7 l- Q5 k
BYTE        data = 0;& K$ o; S& H" Q
8 \# b! K/ h# I$ i$ z7 }! B
        if( exsound_select & 0x10 ) {* T- |& I( W0 A# M2 `. }) `+ h
                if( addr == 0x4800 ) {  i( t# k( a# [/ g
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );1 ?2 M' K! B7 j9 i
                }
: h% {5 s7 Q6 T& l: J& S        }
/ S* `- i) A6 O- T        if( exsound_select & 0x04 ) {' M- M6 y$ p! |7 j8 d
                if( addr >= 0x4040 && addr < 0x4100 ) {3 u- h5 J4 U5 ?- e
                        data = fds.SyncRead( addr );
2 {: c# z5 g. x, D6 A3 n                }* v! K# C5 c" ~& `+ s
        }
* g. h1 j/ {- h        if( exsound_select & 0x08 ) {
8 d: E% ~6 W$ A6 m                if( addr >= 0x5000 && addr <= 0x5015 ) {
" r2 k( m3 r  Q& n+ R/ ^" t                        data = mmc5.SyncRead( addr );
$ |) N) G3 [; M! H  R! B                }
8 A" ^4 m, e: P6 B* J% v) P% R        }
% }- S9 D/ x5 r, c6 G% M* Q5 l. p8 H# ]& n! i5 D& l
        return        data;
) n  ^; O1 ]) F# i4 J' W$ [9 F5 l; Q}! h) A: G6 r6 r6 r
3 O0 s6 t- b3 ?
void        APU::ExWrite( WORD addr, BYTE data )
* ^+ B7 C( w4 L/ n1 w{  k0 m, \- @0 q2 e* P; O4 e) y/ s
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );, G7 F+ g# z0 J
- V3 I2 {3 X/ R
        if( exsound_select & 0x04 ) {
3 }9 v. R) _! I+ A$ O+ z                if( addr >= 0x4040 && addr < 0x4100 ) {4 k- ?/ `& D% ]1 \
                        fds.SyncWrite( addr, data );
5 h( K* j/ q2 L( A                }, R/ P% ~9 E% N' n+ }/ e
        }
2 d6 Z+ t. X0 S4 b- K# e" \- E8 U; x3 M" R. Q6 Y. k
        if( exsound_select & 0x08 ) {$ `7 h: ?( j0 }
                if( addr >= 0x5000 && addr <= 0x5015 ) {( M) M# i$ U9 V# P$ _
                        mmc5.SyncWrite( addr, data );
, r- E8 `9 f4 @! P                }
4 m; F# _* U) |/ j& j9 R        }. f# f/ O, e: L" x% m0 }& B
}
# F+ ^; q1 {1 d) V" R* n9 v* D0 ]& `7 F
void        APU::Sync()
) \- s" ?7 K/ |# i  V  E: f/ x, p{
" R; ]4 ~) s8 @2 Q  f0 j% h}
: X/ s% X9 ]$ M: f" i+ H8 q( z
void        APU::SyncDPCM( INT cycles )4 O4 S) a. }, N$ W
{
0 S, M) p6 ~0 i! u* E        internal.Sync( cycles );
" A5 I  N5 h& w7 ^
- w6 J* l7 |, G1 T* {4 ?        if( exsound_select & 0x04 ) {
9 q& g9 C7 h0 |' {                fds.Sync( cycles );
: q3 G$ G1 E) f' b  m        }
  [% d: W" F1 I" k& ~        if( exsound_select & 0x08 ) {& z$ C7 ^3 K) H9 ^( n( ]
                mmc5.Sync( cycles );
; g) n# v% @- c$ W! p, m        }
. E; A, W9 q- z2 L}! W; u- Y$ M* T1 b2 w

1 ^) g! {" j9 u# y+ r* Lvoid        APU::WriteProcess( WORD addr, BYTE data )2 r5 ]% ^) k* }* f1 H
{1 Z  W  S" u4 t# X$ b
        // $4018偼VirtuaNES屌桳億乕僩
6 F! A3 o( e% D# ], N" {* X        if( addr >= 0x4000 && addr <= 0x401F ) {1 W+ E% y! W8 r. m  c& T9 N$ x+ O+ C
                internal.Write( addr, data );, u( K) B, n& L% k
        }; U8 I7 f4 l  F) W7 C+ v
}
1 `" D( A4 M' H8 t) i* Y! J/ e9 D, w7 C' Y8 j3 V
void        APU::WriteExProcess( WORD addr, BYTE data )
8 G( r7 a+ H3 ^- b6 c* G3 ]! H{7 C! A+ ^, p" }
        if( exsound_select & 0x01 ) {1 `( b, _) i( Q8 ]* i
                vrc6.Write( addr, data );1 p: i" j9 C& j4 Z! A& p- C# w
        }
, h* }# p2 H, d8 F  T& V        if( exsound_select & 0x02 ) {
7 W/ T( S7 K% H                vrc7.Write( addr, data );2 C8 Z( S/ @+ u/ I: U: T
        }
9 v4 b# b- ~$ l, s, a8 Z* C        if( exsound_select & 0x04 ) {
$ y0 o1 \5 I! Q. z0 E                fds.Write( addr, data );: W) @' P5 ]( Z9 j# x
        }' u+ g. x. b/ Y
        if( exsound_select & 0x08 ) {6 W$ A3 E( Z4 P( R- _9 b
                mmc5.Write( addr, data );, g" P2 z  L5 k! [' S9 w
        }, X2 ^% U. T" |/ O& O
        if( exsound_select & 0x10 ) {7 \7 a( w8 k1 }$ l% x
                if( addr == 0x0000 ) {/ r, c: o# A4 T. y! `4 A% m! x
                        BYTE        dummy = n106.Read( addr );
; t& ]* ^  U6 |- \                } else {, k) r9 [4 c3 |9 ^2 X
                        n106.Write( addr, data );
5 O# H  a0 v; W: j, _                }$ z- _# s8 j5 e, C; ]. G7 U
        }8 |+ J7 I  i0 a0 P+ a
        if( exsound_select & 0x20 ) {
0 X. E3 x9 M2 Z3 N2 A+ C) T                fme7.Write( addr, data );
- N" F* O  _0 U1 r4 W        }
& `8 o0 k- x" l" x$ e}
" B* Z4 q; A2 @' \  h# N- `6 `' ]$ b9 P& d
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )0 r# j1 H% X. Y8 t/ K- e9 a6 H
{
" h! d5 t5 [/ l! iINT        nBits = Config.sound.nBits;3 k' h7 @$ y$ t; u; t. t* J: V
DWORD        dwLength = dwSize / (nBits/8);# |5 R1 J. _* j" d4 h4 B3 A. `
INT        output;
; q* p- m% y5 zQUEUEDATA q;
0 u2 E3 M! w$ |0 f  A$ a7 pDWORD        writetime;
, `2 K' p8 ~2 q, s
& ~; b% s9 c6 b8 w& U1 ^LPSHORT        pSoundBuf = m_SoundBuffer;$ ?7 f( ^- b- \" N* a
INT        nCcount = 0;
/ Q. Z( k1 j1 E( v/ u
  [9 L# @# [8 n6 R+ EINT        nFilterType = Config.sound.nFilterType;# K2 l; P6 P4 D* A$ e
+ V5 }5 f- z2 ]# v8 e- ^
        if( !Config.sound.bEnable ) {* e$ ]* a( ?) [0 y0 ]
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );: o7 W8 U2 N; K8 {0 Y5 o. \
                return;
9 r  ~7 `5 M1 J# _2 k        }# s# J. y  |+ h* s& F, k/ L
8 y0 W) M0 \1 m6 y
        // Volume setup. v+ @9 a. y  L- O; ~8 {
        //  0:Master
, Y3 J$ S' j" S, E8 u7 G( l        //  1:Rectangle 1
, d  Y7 t1 r; s) D; Y" M( S        //  2:Rectangle 2
9 B' I( `0 q4 r- o+ s/ w" ~        //  3:Triangle  V! H1 B6 ^$ J
        //  4:Noise( w4 j# E( g2 C; {* v6 t  E
        //  5:DPCM
. j2 K% K' E* b& Q# U. u        //  6:VRC64 ^0 S7 M& ^6 H, y9 a- R
        //  7:VRC7
! B6 m3 ]8 O% J5 a: u# T        //  8:FDS* S, s! G& J4 \8 ^
        //  9:MMC5
8 _/ a. U5 `7 u( Z1 R: [        // 10:N1065 ]2 I! W; ]* I8 D2 x' f( \, v. I/ l2 U
        // 11:FME7
: |1 j3 N$ H: b; A. B8 y  l4 ?5 E        INT        vol[24];
3 a3 L3 \' u3 n" B, K        BOOL*        bMute = m_bMute;* `% M' y$ W1 B2 L% J) o+ U
        SHORT*        nVolume = Config.sound.nVolume;; T; G0 S& A$ Z& D  P( p, x
* ~- C$ r4 X+ d
        INT        nMasterVolume = bMute[0]?nVolume[0]:0;0 x* n7 S) S+ o- q: X% u
9 s( I+ I; f+ \; O9 W+ G
        // Internal5 x' U+ P2 Z5 Y2 X
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;8 c2 B( w: Z; R4 i
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;4 ?5 X6 R* p0 I# d
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;1 ?6 X3 \# `' O9 m( B
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;
$ Q3 z* \5 f) R8 c0 z7 I2 A        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
! ^$ k4 g# S. r5 }" G+ c4 f" @9 u+ Y9 ~+ x  n1 Q) w
        // VRC6
6 H  C: y" G0 |3 B8 `2 Z        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
; W) ?, a' x; {- b        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
/ c% b; L* Z8 S0 W- l        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
1 r6 p8 @& `# ?1 z9 z: x
; D1 l* o/ x$ Q4 E. B, u        // VRC7
# R* l- W! F+ s# X& j) @        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;" K+ H5 J4 W  y) |. H" f

+ |6 j9 p  e& x* I" n4 m' Y( {        // FDS! N% u1 _% F# c+ P5 ?! L; v3 J
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;$ B3 ~/ o5 a( E( z7 O1 G3 b1 J

2 Q+ X3 g( Z" \" G0 ^        // MMC5: s; h: ^+ F& G$ p
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
9 Y: R' _7 j) w- |' i        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
9 m8 i- X; x8 k+ K0 F6 d; Y' N        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
' s( r6 Q( F& j( r* @( ]0 t8 [3 v) v+ f' v- L6 Q1 x6 n
        // N106
1 l% c: C. c, I( T" C. Z6 _% h. p        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;9 ]& d6 T& w: ^9 G
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
' O  N+ F1 c8 l, E8 A% ^        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 u' i, Y2 K7 l& o! I! n        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& W; M% u9 P' m        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
9 S/ p+ D* p' S8 X  i7 e        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;( N* h6 w: P/ X  i
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;: q7 n5 |8 ~& {0 z7 E# H
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;7 z# N+ x; p* `: t) c/ g: G

, y) L! s* K' H        // FME7# V3 s8 A- K/ d
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
4 H. r7 u5 X# ^6 I8 X        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;% E+ ?/ r; n0 `
        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
2 o) V" s  F. X) V6 ?4 k  Y# f) U' A
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
1 s( U9 ^0 i+ I& r, v        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;" P3 g/ H; H0 b1 v
) M/ g: ?% ?  b6 L
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟2 _% z6 T$ ]8 U: n! b# j1 H
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {, q, i1 q. B; ]  y2 j$ q3 [
                QueueFlush();4 V1 {: e7 h: ~) j, Q; N- N
        }- Z6 Z  i8 w2 J3 Y1 Z4 J
2 e. w* k2 _* A3 x  ]
        while( dwLength-- ) {/ c4 k! C. o- c: h9 l! W
                writetime = (DWORD)elapsed_time;
0 o+ c4 u+ D* Y4 {- M# Q. \2 b8 A9 u6 M$ u
                while( GetQueue( writetime, q ) ) {$ q* D0 P( S/ i4 M
                        WriteProcess( q.addr, q.data );
5 n( T  ]0 D( z4 \' Z                }8 |' C4 G! G( U% k+ n$ v

. \$ g$ W4 H7 Y* d6 r9 q                while( GetExQueue( writetime, q ) ) {
  H7 n2 ?! B4 ^                        WriteExProcess( q.addr, q.data );: y7 p9 O* J. v0 O
                }, ]0 e+ ~2 I1 H- H0 U; ]" W' Q7 |" E
+ v/ h0 o$ ~! |: K; R
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
! j4 L: L: v* A                output = 0;4 ~6 w7 b  j* C
                output += internal.Process( 0 )*vol[0];. `* \% h8 V" M* A7 `
                output += internal.Process( 1 )*vol[1];3 n! c; r6 H* C1 b7 ?: _
                output += internal.Process( 2 )*vol[2];& _6 x& W- o+ Q; C* t
                output += internal.Process( 3 )*vol[3];) f: T6 ]2 R6 G
                output += internal.Process( 4 )*vol[4];; W# u  i. D) }. U" ~2 S2 L: p

4 x& b! J% O* ~+ X                if( exsound_select & 0x01 ) {
* D- M3 u, N" M$ b6 a                        output += vrc6.Process( 0 )*vol[5];; n! h) R) A- m3 }6 E( d
                        output += vrc6.Process( 1 )*vol[6];
% q$ C) c: w/ z$ |3 B                        output += vrc6.Process( 2 )*vol[7];
5 {% \$ E8 O. L" g( r) a7 F                }$ {9 W3 d2 J, `# ~# l
                if( exsound_select & 0x02 ) {
% l( @# ~# V( ]* X3 K, [                        output += vrc7.Process( 0 )*vol[8];
9 a8 O% J, S! j. y/ n/ Q- h8 X1 M                }/ N5 W9 E9 g! r8 i4 Z8 ]% a) F
                if( exsound_select & 0x04 ) {. b8 M$ s# |% }' Z% P9 B
                        output += fds.Process( 0 )*vol[9];: h. O: z1 T/ S) }7 e: x( `( Q) K
                }$ A8 H6 q9 f! O) [, n4 B! Z
                if( exsound_select & 0x08 ) {2 y- @; V, Y0 s8 T
                        output += mmc5.Process( 0 )*vol[10];
- s1 V9 I/ b1 f# x7 G& W                        output += mmc5.Process( 1 )*vol[11];
9 j  y$ i: h2 E# Y" j6 X/ \                        output += mmc5.Process( 2 )*vol[12];
4 d, V" M0 Z- @                }6 r- F, }$ K4 ^: G. z6 }5 b
                if( exsound_select & 0x10 ) {
7 x, F0 I$ j4 B                        output += n106.Process( 0 )*vol[13];* D* j% ]5 T- W- u6 W
                        output += n106.Process( 1 )*vol[14];0 h+ v, N2 x9 x. }. _$ E! k7 J
                        output += n106.Process( 2 )*vol[15];
, j4 d- ~4 X: l; f" n                        output += n106.Process( 3 )*vol[16];
0 T# g, k3 L8 z7 v6 t                        output += n106.Process( 4 )*vol[17];$ @/ ]! _7 a8 R2 J) p9 v
                        output += n106.Process( 5 )*vol[18];
# n$ k4 R* s% z9 Y, J! S                        output += n106.Process( 6 )*vol[19];
1 m6 O( g; b: [, ], ]& Y                        output += n106.Process( 7 )*vol[20];& K& C" ]3 K5 J9 p5 N  g7 l  h
                }) Y; W- f, {# C5 W
                if( exsound_select & 0x20 ) {- ^8 ?' n! u/ i) M
                        fme7.Process( 3 );        // Envelope & Noise
( x& f' {& ~  c                        output += fme7.Process( 0 )*vol[21];7 G6 G9 a9 w& ^( `- t) V% Z# w
                        output += fme7.Process( 1 )*vol[22];
) N% o& E0 E1 o" v  |3 v+ G* v                        output += fme7.Process( 2 )*vol[23];6 G( \: {# |6 m8 y1 N! Y+ b$ G+ D
                }& L5 g4 @0 V! G: |

4 \+ B' Z$ m+ k+ C                output >>= 8;
5 S  k! B& S! K- t
2 B6 ?  \7 P, q6 D0 M, c+ L                if( nFilterType == 1 ) {
+ i, D7 J2 N4 a/ D6 I% f) P                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple); x' f& F' c9 P  I- [, T
                        output = (lowpass_filter[0]+output)/2;
7 g" X! @1 O! @                        lowpass_filter[0] = output;
  g  K! u3 _$ P! s# _                } else if( nFilterType == 2 ) {# q$ i, r% e9 g" G. r
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
8 R, A9 b, J( V& B7 s* j                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;2 P) d6 R7 P0 x3 P7 ^5 ]2 ~
                        lowpass_filter[1] = lowpass_filter[0];
6 \  O+ Q& }8 E) _, |                        lowpass_filter[0] = output;
' H0 z# H0 T7 w/ f! k                } else if( nFilterType == 3 ) {4 j" O  U- X4 v5 z( x0 R& g
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)% z1 o# D4 U8 D+ v6 o7 d
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;. l: Z* l3 u, u) r$ x# v! x; x
                        lowpass_filter[2] = lowpass_filter[1];' v# k5 L9 U& h- C' g* H0 v# N
                        lowpass_filter[1] = lowpass_filter[0];6 l) N/ h$ r4 A" z0 V2 S% g2 X
                        lowpass_filter[0] = output;- N5 ^: B* i& h% `' ?
                } else if( nFilterType == 4 ) {+ E3 [$ y6 `) P  D# t
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
6 P& f7 t8 [, O                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
' A$ }$ i4 i5 ^8 V                        lowpass_filter[1] = lowpass_filter[0];0 j7 W/ ?/ _# b# }+ ^
                        lowpass_filter[0] = output;1 \' y: W- {2 \, U2 e2 J+ Z, ?; H1 T
                }
) Y) Z2 E/ z3 ~6 U+ z# l( \% x2 G0 [3 v  W! j1 P
#if        0
0 x  B. S8 W* M" }                // DC惉暘偺僇僢僩1 D4 o, p0 C3 t# ~  j0 F- i' n5 E
                {7 c. {9 ~; t$ C( W8 S
                static double ave = 0.0, max=0.0, min=0.0;9 N) _2 y4 H+ _4 \) c0 J! {
                double delta;
7 u% z& y2 R: ]+ q* L                delta = (max-min)/32768.0;
" ]5 p! ?7 g* s0 a" [( ?: N! j                max -= delta;
& k9 G0 N; Z1 U( |- s1 ~8 B                min += delta;* ]) y, I' S0 @. Y9 ?- y
                if( output > max ) max = output;2 C7 |, L# B- C. Q% J
                if( output < min ) min = output;
* G- y% Z1 k1 m                ave -= ave/1024.0;
6 P" I" B" R, B; [: J4 @* j- p                ave += (max+min)/2048.0;
7 v8 z) b4 n/ U1 d' k                output -= (INT)ave;
( R# t: z6 U( k$ C% V& C                }
. y( _! c# Y8 k2 d- v# m7 H+ M$ H$ F#endif
$ M% O# a8 k9 j. I6 |) `3 B4 m. {% L6 `#if        1
( x! n2 v+ l- T3 t6 `& D/ d                // DC惉暘偺僇僢僩(HPF TEST)) v7 `. k) e* u. I* y- ?5 g9 x
                {* R+ x4 E0 H* k6 t* |( V
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);' c, v: Y2 C( T3 i$ i/ {1 t
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
! O! u( E  i, W" h( J8 r; d                double        cutoff = cutofftemp/(double)Config.sound.nRate;0 \7 Q1 C" K. z4 d$ E$ U
                static        double        tmp = 0.0;
& M3 W' T: t4 k7 k( x3 O3 p7 x                double        in, out;$ L$ ~/ B0 j3 E- l
& `, S6 M1 g- b! Y! [
                in = (double)output;
1 N7 B7 @) i/ g                out = (in - tmp);
; P& @2 l4 J  p; P& n; |                tmp = tmp + cutoff * out;
" D' R3 v! f. I7 p0 V3 J3 m# Y7 i% D. O4 p1 T& f/ {
                output = (INT)out;8 F$ o) ^: H6 a8 _: n4 e" S( Z
                }
' o0 I0 L; I5 l7 c. c#endif/ I- g: S# g! {, i1 m+ a
#if        0' d' _: p7 f. Y' O
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)! M8 i2 k8 ^1 h3 J$ \* `0 d
                {
- i( o# Q- z5 h' p* y9 ^+ Z! f, Q                INT        diff = abs(output-last_data);
0 x. i6 A5 ]  q9 Y3 P1 o                if( diff > 0x4000 ) {
3 L; o! _+ e5 P0 p& u' n; g                        output /= 4;
* I" ]. p8 M$ w' ~5 v* R0 x4 F- \                } else ) D% w8 t  m* ^: p
                if( diff > 0x3000 ) {
/ H) \7 r; b4 Z' X  D+ }+ [                        output /= 3;+ K" m3 ]( U% W/ @
                } else
+ X1 e4 T. `; G8 n5 [                if( diff > 0x2000 ) {( e3 ~6 b- L/ a) t7 H6 t
                        output /= 2;7 M: R6 ]! L! f( [+ Q" n; {3 c
                }
- ]* }8 T# N0 o0 R5 S                last_data = output;
$ ^1 k, d6 ^$ K7 b7 ~                }9 S! {2 b. ^/ E1 n! p3 U3 g
#endif
  q+ g1 r4 R# v* B                // Limit
# P; F5 }' {. j$ a7 H2 @                if( output > 0x7FFF ) {4 l& S, A$ ]( Q( {2 }
                        output = 0x7FFF;
" E' c+ g5 o! @1 l# j# p* a# Q( p                } else if( output < -0x8000 ) {
. c1 K" ^" ]8 n9 G+ ?) I                        output = -0x8000;
' B' _- z5 f( |! K' S# `$ @9 l                }
, q  c4 E5 Q: u& X: p: |
3 J! z9 E. B6 Q0 \, g2 t! Z3 m7 P                if( nBits != 8 ) {( }$ l, ]- G4 Q
                        *(SHORT*)lpBuffer = (SHORT)output;
8 c* N( L+ c8 K4 s1 R7 t; s                        lpBuffer += sizeof(SHORT);
2 u/ i& M% w6 o                } else {' t7 F% o, L+ j" s" r
                        *lpBuffer++ = (output>>8)^0x80;
7 Y4 }; g9 Q3 ^: ~                }
9 }8 s0 s$ B. Y4 g7 W! V$ d0 J# G1 a5 v0 X, y% p
                if( nCcount < 0x0100 )
" u& N& o5 s: Q. K; T" S                        pSoundBuf[nCcount++] = (SHORT)output;5 l, _7 I8 l  J# H

( e  J) R$ A, d8 V; J; K" q//                elapsedtime += cycle_rate;
8 E9 n6 R9 n1 T                elapsed_time += cycle_rate;
; B4 z0 f5 o/ E& L        }( F1 Y" e( a8 W% h* p% p0 A5 {; \

3 d! j; D8 e/ _$ g. a! u#if        14 z# U! Q. t* F4 y' K
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {1 K; u5 b- N( P3 K; I$ C* t- ]( R
                elapsed_time = nes->cpu->GetTotalCycles();; ?! c; S, W9 x5 S$ Z  l
        }
% r* j, a: F6 N4 L        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {6 }2 Y& _2 Q$ f3 e
                elapsed_time = nes->cpu->GetTotalCycles();
6 |( u9 F/ A' ?" @2 Y" t8 L$ V        }
- x$ J* t6 @% k/ G7 L9 Y7 E, r#else: `; p: m! L7 v) ?8 w. O( C
        elapsed_time = nes->cpu->GetTotalCycles();. T" C8 K: B  U9 A
#endif
6 Z: G' G7 W. m}$ t6 w7 g8 X1 k9 x
5 u3 h" }/ J# Q; P" Z! P- h8 B: ?
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)
7 E- v% R7 w* G" ^) n1 w# |INT        APU::GetChannelFrequency( INT no )1 i( F' P% D8 \3 l
{2 J' ~! N6 x9 l: [/ ~/ W+ i2 h4 ]) T: x
        if( !m_bMute[0] )* q! u! h" b% H8 a% o! P
                return        0;$ h7 v# G- q# w. A3 u
: r, w4 B9 p# W/ ~4 Y: s1 G
        // Internal
1 p& w7 \. j, g+ b        if( no < 5 ) {- {: Z5 J9 W! i$ x
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
# V, D) o: o7 q2 _/ t  W3 H7 O6 Z        }
9 O/ M4 y2 a( Q2 v; ^+ V        // VRC6
) {/ Z% `$ L0 ]& u        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
, D! d! F3 q( s5 M3 r" @' m                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;
4 Q/ A" W1 v1 b% y3 u$ [        }" A$ A5 n* y6 e& s4 [, V% b
        // FDS- |* C$ R& U6 O  D# d( N& b
        if( (exsound_select & 0x04) && no == 0x300 ) {
4 p* x& e" G* C/ {, G% y: }                return        m_bMute[6]?fds.GetFreq( 0 ):0;
+ f$ t- D- [/ F        }
4 b) X/ F) ]! X6 y        // MMC5
8 ?, O! S. I$ o& R        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {- B' R! Z. `* m6 g" i( {
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
8 l6 @& r" B, m# Y4 M8 L$ ]        }. w8 m: D* n/ \; V) y5 M
        // N106
% j4 Q) t) H4 A1 n; y  s        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
2 t8 [7 U" A# s  l; v, S4 \                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
' U) n. z% Y- T( ^        }
( [- q# u1 V5 N& r  Q9 P        // FME7
1 ^2 e& Y# J/ K" B" M        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
% |  G, n' C! O! o6 `- |0 {1 W& y                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;! X) e& }& `( w. T4 r- |) N
        }( U9 S9 m1 u" ~4 P+ }
        // VRC70 h, i" g) |0 i" F. U. X3 C6 n
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {
% `" j7 z3 S, j4 C- ^) Y                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
. I/ N7 ~; _2 Y$ ^& [* \* Y        }
0 T9 f1 s' p( ^+ I. [        return        0;$ B7 g4 R( @5 A% D8 g$ d6 f
}- A4 ?7 Q! C- p# c- f5 Y: x

2 `# V& `, B2 e3 t+ e& t// State Save/Load
- l& t5 v  x' J0 I6 l& V2 {/ Hvoid        APU::SaveState( LPBYTE p )
/ T, ~6 x; c& {6 P6 e+ S4 h{7 V9 F  a; i) M+ `3 @/ D
#ifdef        _DEBUG2 b0 a$ x7 K& b  s5 x6 Z
LPBYTE        pold = p;
5 E* E# C/ z9 i/ g#endif+ U$ B+ \5 p& z& S1 B
9 J* i. M8 y# y- h; Q' A: M; N. T4 l
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
9 \: U& i1 [6 v  c- U: t        QueueFlush();
7 [, X& }- ]; M! B3 N9 f% D1 e
7 Q: \, q& u* y- [4 a        internal.SaveState( p );9 p3 Q9 D! R- t4 X* b1 B9 Y: L
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding% ^0 ?: C) @; [* Y$ D( L
- R1 [+ i+ U5 q6 U4 w3 Z
        // VRC6
( R0 Q, c" Y8 n  x        if( exsound_select & 0x01 ) {) a; [" q- u2 r0 s( J% L
                vrc6.SaveState( p );
) H! v# @) {  n- s# u0 I                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding# e. w" V1 X& X, h, Q" \, ]
        }
( a1 Q9 q7 W! U9 @7 F        // VRC7 (not support)
0 c4 h; c7 d$ `! z        if( exsound_select & 0x02 ) {4 Q" {$ O% z* ]$ b
                vrc7.SaveState( p );( A. ]2 Q3 w; L) F) d
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding1 U* X9 u! C% {# j/ E
        }
& |' N+ `  P; @& U        // FDS$ F$ u' W' m+ J, f4 T: H2 j
        if( exsound_select & 0x04 ) {. D9 g$ I+ }: G1 M0 [, l) S* ]
                fds.SaveState( p );+ H1 G4 W7 h* z8 G& z
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
4 {5 B% b) k* Z        }
. q' u4 L7 U1 Z& O        // MMC5  B& ]5 c8 b' B
        if( exsound_select & 0x08 ) {
; S- i% O( p' x' k5 J& b8 z5 x                mmc5.SaveState( p );! C0 b5 w7 g6 p* c9 e
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
, u9 b5 Y% Q# M* R( Q% t4 S9 h        }( @1 h+ V+ G' }; x
        // N1064 e% O9 N' l4 @  l' u( n9 Q# z
        if( exsound_select & 0x10 ) {
2 P/ t' p/ p3 `( j) B- o5 |7 m1 [* z                n106.SaveState( p );- O1 Q2 z# p5 v7 K1 D/ m
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding$ J- p/ l  M% S3 t+ z) o0 H
        }0 z' C9 E; J  u( t' s& ?" w
        // FME77 J! C; h0 a2 ~. |$ I! B1 A9 V4 \
        if( exsound_select & 0x20 ) {
8 P( w* B2 y# T' M                fme7.SaveState( p );% W, H+ S! F) n/ }$ N& `7 h8 j$ I! m
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding' J$ E& E0 K7 U& u7 J; J4 [( a7 z
        }
9 E' N9 M6 J/ O8 t# z& u, z; L, G
) s& h+ I# Q, ^( H#ifdef        _DEBUG
0 Z' t8 k* T8 I, u, CDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );2 ~2 H" H+ g0 ]7 m: G
#endif
. q; ~$ e8 T% I. S0 n}
. F; P, @2 I  M9 o+ H. u1 n0 s
9 O7 k9 W! m6 O8 i& hvoid        APU::LoadState( LPBYTE p )
) t4 @9 ^6 s% u) i* R{4 W' K) \" `8 n. {) [
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
% l7 o+ Q+ O0 l8 t+ v5 a        QueueClear();
7 W/ F1 U7 k  ?1 J* ?; t# C) G. s' X- c5 _
        internal.LoadState( p );  o- l! h, `& _: O& b
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
) L8 C/ |# \8 {5 t# `
9 M8 Q5 I8 F7 u        // VRC6
; V+ m  J) S% [! X2 A6 h        if( exsound_select & 0x01 ) {* F6 `1 `) Q9 [
                vrc6.LoadState( p );
0 k9 T+ ]# w2 y. B5 N                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding0 d5 S" X7 }* b  A, H
        }
8 s4 R' m# K+ y$ I" e$ S        // VRC7 (not support)* Y2 p* W( ?$ _/ }& H
        if( exsound_select & 0x02 ) {
7 f0 `& }: ?9 }: N8 `+ f                vrc7.LoadState( p );5 Y/ v# w9 j, F) u2 d* M4 [
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
% i( I) s- a5 ~& a" B        }
2 q1 t, g% {8 V7 @% p        // FDS
1 i( @, N: A0 x        if( exsound_select & 0x04 ) {
1 }/ t# O5 z" [/ ?" R) T/ l9 b                fds.LoadState( p );
2 j0 _, I4 E: Q$ N; x  `                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
0 g9 l. ]; o3 g# O" V        }* c1 U3 V- x- m* i0 E
        // MMC5+ A+ d9 @% b5 N( I4 f) }% h0 O
        if( exsound_select & 0x08 ) {
1 E0 F" `4 F, {& ~$ }+ |2 T' d, n+ h                mmc5.LoadState( p );
& V# R" A, g' D                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding; _, [$ W9 `% D5 I$ X/ g2 Q
        }1 N7 D% N8 J+ Z' `$ G: n8 r+ e3 K
        // N106
% j3 P# o* u+ p- k" b# O: j0 J( P        if( exsound_select & 0x10 ) {5 j; P% A% w& S' b
                n106.LoadState( p );
9 v+ o$ q$ ^$ n- Y# a7 _" t( j7 c9 y                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
8 j, m# J- W! e        }
3 i# X0 @2 q2 A4 N! q! ?        // FME79 b( I. m# o# p3 W9 S4 ~
        if( exsound_select & 0x20 ) {
' ~1 S* |0 }! m- x+ Q* y9 n7 B                fme7.LoadState( p );: E+ A: m: g# i" E) t3 H4 B
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
  E! c- V! n) `9 Q% E+ x/ p        }
  L% z) t+ y& ?}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
# t! E/ p9 r0 e9 T- Y! [9 j. I可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。# F# ?0 G9 x7 P- a5 O) ]' E2 M; m/ w
感激不尽~~
  f6 g* P  z0 R7 I; n
恩 我對模擬器不是很有研究,9 ?6 d3 }1 F: b
雖然要了解源碼內容,可能不是很困難,6 z7 T: t% k5 K2 O" `1 D
不過還是要花時間,個人目前蠻忙碌的。- [. c# ^' S$ ^3 y5 u( w1 r6 o4 _( K
9 ?* d. I1 }8 c
給你一個朋友的MSN,你可以跟他討論看看,4 n; @. ~) x- e2 N' ~1 r7 d' R
他本身是程式設計師,也對FC模擬器很有興趣。! X6 H9 [* p( G  d0 O' i! o# V! D
) h. \1 d, K' {! U: A# r$ R6 I
MSN我就PM到你的信箱了。
! V; H+ h; K2 c% ~
7 h& e8 d" d5 M, e: z1 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 发表
! e+ ~1 z2 [# U呵…… 谢过团长大人~~
- G: _) N. v6 a# n# |% ?

7 V% q; m! ?0 Y+ e' m- f1 {哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
$ p# C4 d7 o+ b+ b- I团长的朋友都是神,那团长就是神的boss。
% i& w0 ~; n1 g  v# H
哈 不敢當,我只是個平凡人,; r" }, x1 D) {; P
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
  \$ B6 J' X$ @" s; Q. ~# Z! XZYH
8 _4 M1 ~. }; JQQ:414734306
" R5 X$ w6 j& g3 A: tMail:zyh-01@126.com
: k. g' L  G+ y" H, h" t$ o1 c9 V9 C1 U( ]
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 : O6 U* U1 N3 a
再次对团长大人和悠悠哥的无私帮助表示感谢~~
% C  e8 t+ H$ T. G. x6 _7 E, \3 }
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-4 12:33 , Processed in 1.109375 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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