EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。2 A  m3 i* G/ X
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
, o% p7 G9 t! g0 ?/ X8 e( U! ]% K这里有相应的模拟器源码,就当送给大侠了~~
; ^1 n# l+ }9 l: I5 Mhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
- a( m# f* v5 L% D3 h3 w" B. ?能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。; @* J" y( U8 n2 U
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
: H0 c' b% Q4 c$ I4 G, s% ~4 w. j这里有相应的模拟器源码,就当送给大侠 ...
' v" |+ O" S3 i3 C; ]
聲音部分(Audoi Process Unit = APU):% A( r( @4 J/ \; p3 Z
.\NES\APU.cpp
6 b$ ?$ `# T& v.\NES\APU.h: y8 R! w) B: @
3 k7 {6 q) \$ \0 J0 x5 a0 I. I

/ v& W- ?! X& e  Q影像處理部份(Picture Processing Unit = PPU):% i7 U8 X7 I$ U' U
.\NES\PPU.cpp
: p# e. d( M9 {/ v% @.\NES\PPU.h
( F4 H! E  k4 D8 Z2 V) v$ r! ~+ a  @; T/ ^: d8 V
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
& L" b, l8 g$ M0 P- g# ?3 }(由于很多专用术语和算法机理都不明白,所以看不大懂……)9 a' b) ^! S3 E5 H+ {- Z) z& s
//////////////////////////////////////////////////////////////////////////0 I; i6 n( T& u1 L$ a& v# D
//                                                                      //
; ?' o5 e$ ?" c. b/ F' y//      NES APU core                                                    //
6 [% W- ]3 J) _# v9 p2 ^# @" d, q//                                                           Norix      //! `6 V+ K; Z! V& @: X
//                                               written     2002/06/27 //
, J# Y+ ?: R) }* _) p1 {8 x//                                               last modify ----/--/-- //5 \2 p& S4 m5 I2 K
//////////////////////////////////////////////////////////////////////////
8 r- X6 O6 N' z9 M9 d4 V#include "DebugOut.h"
- s  s# K  J% ]8 G6 r#include "App.h"
# {& M$ A4 D3 I; C5 @/ N; z, A#include "Config.h"0 f! ?* [: S  A1 h8 f4 Y

. J8 I2 v: O/ l#include "nes.h"1 d8 `# T/ {, l# e$ l
#include "mmu.h"
, G8 u# Z9 p8 o1 C* p1 M#include "cpu.h"* M. Z& x7 O/ _. W
#include "ppu.h"
* w" o, r! ~# e3 z0 [+ G8 r2 ]#include "rom.h"
9 o0 E( L2 r" b. y6 q0 r) g- t#include "apu.h"+ D$ K4 @! ?/ l. s% z( l) O* G( w
8 @% c4 v3 f% ~6 r& D( j
// Volume adjust* y7 |* O9 S+ X$ R# x
// Internal sounds3 N7 y2 z4 D# ]# P6 Q% ~, l/ V, |
#define        RECTANGLE_VOL        (0x0F0)
( k" Q* b9 U4 ?: F. p#define        TRIANGLE_VOL        (0x130)
6 j" g' L0 c) Z#define        NOISE_VOL        (0x0C0)
% M  i9 L1 i  l#define        DPCM_VOL        (0x0F0)
, }3 S- Q; I) U9 t: p. a// Extra sounds- e! [' ]0 n- m
#define        VRC6_VOL        (0x0F0)
* n/ p, T8 E' V6 f$ G#define        VRC7_VOL        (0x130)
8 c- H/ P$ h6 g$ ~& a( J#define        FDS_VOL                (0x0F0)
- @' m. V6 t2 V- x9 P#define        MMC5_VOL        (0x0F0)5 e: }8 N  [: A" m. Z0 \
#define        N106_VOL        (0x088)& @, b- [9 T% w. z) z: F* n& Z
#define        FME7_VOL        (0x130)
  r. E# ~( d* k. ]' K: @
7 _' w* W* R) S9 q1 V. NAPU::APU( NES* parent )6 Y6 B, }, t6 v3 j( ?8 m) t9 A
{; K" D- z! O! T
        exsound_select = 0;
2 U" {  e) E" S+ }& @+ v" Y+ f, n, K) \
        nes = parent;0 P9 @3 j( r: I, {- [: W& Y
        internal.SetParent( parent );
# E; ]4 G" ~8 I* t) r8 B! i, i; R3 x" g5 v: P
        last_data = last_diff = 0;
6 v2 j  J$ i7 b7 w# {7 L
; m2 k( u8 K0 g2 q0 `9 Z        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );0 B2 x# b- p" X1 @$ |
. |" p0 E- S. d1 N8 q
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
3 U! X$ X$ e# w# [1 g- o        ZEROMEMORY( &queue, sizeof(queue) );/ E" c( M  C; {
        ZEROMEMORY( &exqueue, sizeof(exqueue) );0 }2 R$ V! n- H. O" t% \
8 e; `" C. I5 j
        for( INT i = 0; i < 16; i++ ) {' g# _1 R: r/ i" s' Q4 ]/ L; d
                m_bMute = TRUE;
% j5 M6 v, I, D" g. T        }
5 H  ~5 D5 x7 j* L; J}
6 p- z  }  m( E0 f$ P8 b
6 M# ^) X; f% `6 U3 Y& AAPU::~APU()
9 B% z# D6 F8 Z" A7 N6 A{! j; ^7 a6 ?! L, S
}) ~' |$ X4 _! @0 o- W& R/ w

' D9 P/ U" p6 Z  \/ Fvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )  g! I- c* p& H( K* N
{
1 `" a4 r& H8 i# N: P: }- b5 ^        queue.data[queue.wrptr].time = writetime;
9 P# X8 D! y* x9 q: \* [/ O/ ?        queue.data[queue.wrptr].addr = addr;1 l6 ^' @1 k" g. D
        queue.data[queue.wrptr].data = data;5 `. E  c2 ~) f: W* ]
        queue.wrptr++;
$ J. i% X3 d  e2 c! E$ E  Q3 B% h3 m        queue.wrptr&=QUEUE_LENGTH-1;
4 g( S4 k8 {( @3 F8 x        if( queue.wrptr == queue.rdptr ) {; _; @! E) J- l/ T
                DEBUGOUT( "queue overflow.\n" );" y0 N" j+ Y; u
        }9 E+ R" P3 C* K7 j
}3 j- A: Y  B* X! {4 n: Y
, L( s9 d5 n4 e1 B4 U. o
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
* _" b+ E# S4 C{# t* L3 X6 y" b9 N$ k! l
        if( queue.wrptr == queue.rdptr ) {6 ?% G* a5 Z0 C! P) g5 H! \6 z4 j
                return        FALSE;2 w2 G, G8 {$ e& B- l; ]; M
        }
( G9 W% U% ^  [' k, S* o  C        if( queue.data[queue.rdptr].time <= writetime ) {& A& B, s% w6 i8 _* v8 B* L
                ret = queue.data[queue.rdptr];
# {% M9 D! G5 O( C                queue.rdptr++;2 P' |; B8 @7 s3 N: V% C0 [
                queue.rdptr&=QUEUE_LENGTH-1;
' V9 X- ?8 J7 d% `                return        TRUE;
7 ]) P, f# x% A3 z        }
( @) |7 g. ^# U% l9 }" F( ?% c        return        FALSE;7 B  x2 v$ L5 f1 b
}
) @. t$ A3 d: z4 X# g; P- V6 S! r) f. L
2 |: e0 ~" Z, l- Yvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
* b6 Y) d+ y0 |, E{
0 f# N# _( v# G" j" \4 p        exqueue.data[exqueue.wrptr].time = writetime;
8 N7 @& Y7 V, J" c* {% J        exqueue.data[exqueue.wrptr].addr = addr;/ U  [4 b! Q8 l" ]
        exqueue.data[exqueue.wrptr].data = data;
* P2 K2 {3 U% _        exqueue.wrptr++;' s' i8 i& m: d3 R& {
        exqueue.wrptr&=QUEUE_LENGTH-1;
3 S$ d, t6 i5 R' E, G- K" U# U# r        if( exqueue.wrptr == exqueue.rdptr ) {: h6 M8 W; O. e4 d2 T# r
                DEBUGOUT( "exqueue overflow.\n" );2 v4 V. H1 n6 W& y+ K4 L
        }
1 y! D  y7 l' i% Z# z6 ?}8 r1 P: b6 J/ T) q5 W  ]

- C( p# j# M+ I3 f) W2 kBOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )" k1 B9 K, H8 l( {9 {
{, a$ d6 y. I& {: q& m. Z5 y
        if( exqueue.wrptr == exqueue.rdptr ) {
2 W. E; l! S% D$ p                return        FALSE;1 H* U* \, _# I7 z: n, l7 Y% c
        }) o! U# Q) g3 O4 Z
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {) r5 ]8 b4 y, O7 |7 O
                ret = exqueue.data[exqueue.rdptr];
4 v7 N" ^4 W6 t1 s& p                exqueue.rdptr++;
  ^% c) B8 C" ^9 p: d6 K7 C                exqueue.rdptr&=QUEUE_LENGTH-1;
! k! n0 j1 g4 O& r9 i' ?- Z1 u4 {                return        TRUE;6 u# w; D# U( R( y2 V- g/ m  _
        }
5 V9 t: _$ T) p) |        return        FALSE;6 T7 h' r- a+ }( G, x
}
9 `$ o  u, Y) ~
- p4 W  i+ w* i) [- evoid        APU::QueueClear()
( k2 Y1 d8 n: X{1 K" l. G9 r: u" [$ n: k. z' z
        ZEROMEMORY( &queue, sizeof(queue) );
! }; B# r6 V" q2 A        ZEROMEMORY( &exqueue, sizeof(exqueue) );- L5 T. e4 I7 R8 [
}
+ I6 f2 J* |* z  R0 p- i
. Q, @4 m/ V3 E" S8 e4 i/ _/ ]void        APU::QueueFlush()% m5 I: g+ ^" T! k8 D
{# x7 y  J. n, Y  H
        while( queue.wrptr != queue.rdptr ) {
: |! B+ I/ a4 B5 j                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
# a( f+ a. b& D                queue.rdptr++;$ t! \/ U) y! }( n
                queue.rdptr&=QUEUE_LENGTH-1;
& K# n+ ~7 J1 M3 m        }4 l2 _( U* N6 W

7 Z1 H8 M4 a1 |        while( exqueue.wrptr != exqueue.rdptr ) {
$ `) w; U& N8 c2 B3 O1 C4 g                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );. I5 J+ J9 H) d$ I4 G
                exqueue.rdptr++;) D: Z  e4 o4 y* E
                exqueue.rdptr&=QUEUE_LENGTH-1;: h9 B+ ^+ c9 [
        }
; q* j. ~" Z& B1 w9 ]}7 k$ ?" Q/ I5 o/ [; J

3 d% o# |0 r( hvoid        APU::SoundSetup(). @9 x+ ~4 U0 I* V
{
* T- Q: Y5 q" b, ^        FLOAT        fClock = nes->nescfg->CpuClock;
5 a9 n  _- f4 L5 q2 d. d( V! x        INT        nRate = (INT)Config.sound.nRate;0 k. N6 {& U( Q2 g
        internal.Setup( fClock, nRate );$ d8 E5 r' s5 E
        vrc6.Setup( fClock, nRate );/ {4 X/ v) U- R4 z# o/ }2 T
        vrc7.Setup( fClock, nRate );' v! Z/ @( H) B! s/ G
        mmc5.Setup( fClock, nRate );
% u0 s; j" D+ `7 c% q        fds.Setup ( fClock, nRate );
' m# b: u3 b. K        n106.Setup( fClock, nRate );% d& V( t+ w; g. D5 u4 v9 C
        fme7.Setup( fClock, nRate );
, c: a+ v0 G# |2 s3 M}" l. t' x2 [: r. X  X( b7 X

7 H+ u0 W3 V  K8 ~0 nvoid        APU::Reset()
% u- k) X7 G* w5 L3 b3 L( k9 N* O/ S- o{
7 G. S" p) F8 \# Y. G# h8 f: E        ZEROMEMORY( &queue, sizeof(queue) );5 C, k; c& ^6 h
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
- ^8 @8 V& f- V' U% }' M* I, G7 s4 y8 t1 v4 U$ K
        elapsed_time = 0;
# D, ]1 r9 {$ D% n
0 y$ \! A& {: y' ?        FLOAT        fClock = nes->nescfg->CpuClock;
: t4 o- T5 E& ?) E        INT        nRate = (INT)Config.sound.nRate;& ^/ u9 E8 A; F3 @0 |2 J+ k
        internal.Reset( fClock, nRate );
" p4 N8 g$ A, X        vrc6.Reset( fClock, nRate );
# ~) d$ O! {' X, P* y        vrc7.Reset( fClock, nRate );
( `* K" X- U+ B4 u& |        mmc5.Reset( fClock, nRate );
, f: e  J/ L4 D8 ]# M1 ?        fds.Reset ( fClock, nRate );
: j) m8 V. j* g% m+ d3 G0 C        n106.Reset( fClock, nRate );
: S$ C8 Z/ ?: o: w3 i) ~        fme7.Reset( fClock, nRate );
  x) p9 ^% S9 F/ T) X2 ?' ?. z
4 ^- l5 V9 [& m' J, L1 r8 \        SoundSetup();
% ~, l1 c) W' O5 E}
/ {! ~& ~* |8 c; p' p4 U) Z- L" Z* [* x" B3 [. U
void        APU::SelectExSound( BYTE data )
) y( J0 C4 ]6 N{
2 X5 m0 W/ ^3 d" C; ~* x        exsound_select = data;$ c& ?9 U+ K; N+ s  H
}+ K2 j$ _# m$ X3 ^/ A) |% n
; M# e- ^1 J) i: u, s$ D
BYTE        APU::Read( WORD addr )
- F. i& j% B# r, c; A4 }6 U{
; f9 m' @% G9 M; \        return        internal.SyncRead( addr );
0 P/ z6 t4 s0 G5 e}
& ]: |& d' H4 ~6 Q9 ^! [/ u) @
1 ^) ~$ M! F# ?$ Y5 P4 Lvoid        APU::Write( WORD addr, BYTE data )
0 ]: q0 a2 }# x1 X4 ?  S8 r{, Y( v. T8 n) ]) r
        // $4018偼VirtuaNES屌桳億乕僩
9 ^3 k( h9 b1 l* E/ C& s        if( addr >= 0x4000 && addr <= 0x401F ) {
' l2 E, Y1 T. o4 t' X) w4 v                internal.SyncWrite( addr, data );$ P2 O0 h  w- b0 H' K
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );/ p1 Z5 f: W! Z! I7 B5 a1 y$ j" x
        }6 g7 d, q7 ?/ W' o* X3 g
}8 n; j3 g3 y7 H3 }
1 e( z/ F5 u: i5 h7 z2 `: a
BYTE        APU::ExRead( WORD addr )
& H; v4 b; N: M) J* X{6 E4 M1 z: n: D7 `6 B* ^
BYTE        data = 0;
( H3 X. }  Z. E3 y0 D3 \+ V& p/ c# g7 u3 G6 c7 e
        if( exsound_select & 0x10 ) {! @8 ^+ A; k, ~. l2 u
                if( addr == 0x4800 ) {8 ^# Y! \$ S, O
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );! h9 @( ^4 b1 ]' B5 }
                }
. g8 T0 d! p* o. k; X6 |3 p& g: ?        }
* D. N' k! T& b        if( exsound_select & 0x04 ) {
5 F( F) M) |2 z/ g7 ]; p  j                if( addr >= 0x4040 && addr < 0x4100 ) {0 M, D3 P+ f! ?. w6 W: Y1 o
                        data = fds.SyncRead( addr );2 H% t$ L5 r. a  o0 x) g* l4 }0 Q
                }
+ m/ {( k0 ?3 k" ?6 }( j: d# R        }* T, [9 Z' c1 O. i' U+ c- r9 E
        if( exsound_select & 0x08 ) {: s( ~" q2 g9 @+ L2 `9 w
                if( addr >= 0x5000 && addr <= 0x5015 ) {
1 h7 T+ P5 w" T. l                        data = mmc5.SyncRead( addr );% F& j5 w2 O# Z
                }
8 |+ m$ A0 x  W) e0 h- y* }        }* @( @# y, g, y
9 x+ ]+ q- _+ C& I$ E$ e
        return        data;0 I% P6 `7 X% p+ d6 v, V9 D! _
}
' H" K+ k4 I3 o3 I2 e. G1 C' H; T/ d# m
void        APU::ExWrite( WORD addr, BYTE data )/ T. h+ R: W9 g7 p* Y
{
, e  L- X, ^3 k4 S, P% _4 @        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );' k9 g  k. a9 J
2 i2 u& W$ P) W5 c) g% T/ m
        if( exsound_select & 0x04 ) {
% t, U  R: _8 Q5 T  e                if( addr >= 0x4040 && addr < 0x4100 ) {
2 F+ s. Y# T% K  G9 _                        fds.SyncWrite( addr, data );3 A2 r2 n" f& }6 g
                }" e& l2 {2 ~# O- y6 Z. k
        }
( R, @8 c" d  F' m, T2 P2 H! \& S. z3 Q" p8 x. {
        if( exsound_select & 0x08 ) {( ^# Y$ y0 B7 ~0 [+ O# b
                if( addr >= 0x5000 && addr <= 0x5015 ) {
4 X3 y& r8 E) I; a                        mmc5.SyncWrite( addr, data );
9 p- J/ h. D+ b& ~                }
) s; C! S# ]6 r1 L* n        }
, S# u+ q; u; d}
" d# x# ~$ @" L6 R5 ?/ G1 j9 Y  g* u- ]( T& w
void        APU::Sync()- S. ~3 k( ]7 g0 j0 W+ w
{
' j) @7 U' ^7 j  y}, y; k% V3 L$ e; p; @/ M

4 e. j4 F3 r- [void        APU::SyncDPCM( INT cycles )
4 A1 N% M) u9 H6 g6 \$ ~6 i{2 b2 h8 q: w2 @- X
        internal.Sync( cycles );
/ ]" g+ f5 m: d, A- o# y/ h6 v+ u" k# a; g( K1 W4 z# u, l( _
        if( exsound_select & 0x04 ) {: ?7 b8 A! ^$ b% g* Y; {$ A
                fds.Sync( cycles );
9 X4 B" Z, q4 c        }3 f: g/ h% F' d! w, x- ]
        if( exsound_select & 0x08 ) {! m; C5 ?; N2 }% g: W5 I0 P
                mmc5.Sync( cycles );& D0 M! _  j  ~9 O3 g7 r
        }
2 n4 G7 p, F, z( I- \}
4 q, H/ u; Z+ s- r: x  [( r" ?3 U8 k2 Z
void        APU::WriteProcess( WORD addr, BYTE data )
2 t$ B- W! S2 j" q( Z) B{. q0 q5 }3 y* j: X
        // $4018偼VirtuaNES屌桳億乕僩
2 H# ^! j6 [/ G& O% U9 a        if( addr >= 0x4000 && addr <= 0x401F ) {  l/ Z9 e3 E/ B7 g4 b8 W4 f
                internal.Write( addr, data );
% p$ w- u" d0 f) R        }3 S2 Y! Y2 ~: p0 B
}$ S/ X4 r) k5 E: n- P5 k7 Q

) V9 P! l) n, k4 i2 @# F% e/ hvoid        APU::WriteExProcess( WORD addr, BYTE data )' C8 L( v+ [5 Z  T
{
% b/ V* y7 B9 Z% l2 e        if( exsound_select & 0x01 ) {5 B" C3 |- l9 k( d- t5 n0 J' @
                vrc6.Write( addr, data );
1 R, K% r2 A. {% J3 p* H        }1 J9 i8 Z$ l! r
        if( exsound_select & 0x02 ) {: p2 D8 |. u+ b5 g
                vrc7.Write( addr, data );7 O+ U" s" j$ Y9 Y7 W, ?- m
        }* g3 P+ V3 I/ ~' `
        if( exsound_select & 0x04 ) {$ W2 g# h7 ]) ~- E6 z# m
                fds.Write( addr, data );; p* Z; n; _! q( X" [3 R" A% p
        }: r5 H0 D, r" s0 N3 J
        if( exsound_select & 0x08 ) {9 {& E& d, g- V) o
                mmc5.Write( addr, data );
1 k, ^+ O: H* \; X        }
0 }, G( K0 D1 s) G' D& {        if( exsound_select & 0x10 ) {; u8 A6 P3 s: O
                if( addr == 0x0000 ) {' a6 h4 A5 g& g8 J
                        BYTE        dummy = n106.Read( addr );1 x: _/ N6 e8 ^; ~6 s0 d# o
                } else {
8 d5 W  h; J# t8 g4 A                        n106.Write( addr, data );$ O$ z0 v* j$ x1 w# T& V3 v( p
                }
4 Z4 Z$ A6 D' u* r  ^0 n: ^+ w* R        }
! `) G* X5 h' |! p5 I- B% ^! u- Z        if( exsound_select & 0x20 ) {( e6 \2 c/ \# u1 K
                fme7.Write( addr, data );
7 k, E6 F, t) q8 A2 E- g+ }5 f        }
- K3 l" t9 Y# A; B}& `# X9 n) J$ ^5 V9 X2 J5 ~9 b" x
0 _+ W! V. A3 S: @# W$ W' ~8 ^
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )/ H: A2 A% k! L- R% i
{: f$ E/ x; u+ K6 J1 b4 j. a
INT        nBits = Config.sound.nBits;, P* M) s. k1 ]( i4 j/ S
DWORD        dwLength = dwSize / (nBits/8);
  j/ `, ~) D- ^/ IINT        output;
& c& _$ O+ B( s1 kQUEUEDATA q;
9 E0 D) M1 f- C% N! t; ^DWORD        writetime;' t/ s$ o. g6 r/ m
4 \  {8 _9 I* I3 L  b0 T
LPSHORT        pSoundBuf = m_SoundBuffer;& E! S& d. e+ h- P  [: H# O( c
INT        nCcount = 0;
9 [3 S, M" |! f: n2 |
3 I' H  D3 z! A% T: ^INT        nFilterType = Config.sound.nFilterType;8 y0 z' S  n& W, {) M- E0 e
/ z" X0 D" M1 x$ f* K
        if( !Config.sound.bEnable ) {# b- i4 v( o  i& u2 W& e
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );1 Y' a, {  J; }7 M6 I2 o6 F' \0 f
                return;
9 ~8 ?) Y$ x0 r5 ?3 d% Z        }! D7 V% R6 o' q3 X. m
4 V, i8 J0 y4 l
        // Volume setup
7 U0 p2 c" ]: j, S5 f7 e/ w4 n        //  0:Master2 k5 r# W$ f: a
        //  1:Rectangle 1" @2 [& [; R. C% l. s; _* {" D: E
        //  2:Rectangle 2/ C9 p9 c0 K( q( _
        //  3:Triangle8 E* [; l1 m5 N
        //  4:Noise/ Z$ x4 E5 v; l
        //  5:DPCM
: ]$ `: e2 S  S5 U4 j+ C$ c        //  6:VRC6# ?5 O6 |) ^8 \0 ~' d) W: W/ Z0 D+ @1 E
        //  7:VRC7. H% u- }* [& S+ N
        //  8:FDS
, G' b% V3 r8 `        //  9:MMC5* r8 B+ x2 C& W, }
        // 10:N106  f+ O' t2 R. a8 J
        // 11:FME7
5 N3 o& t: s7 {        INT        vol[24];, ^7 ]) W$ |5 e. Y: C8 s  t! ?
        BOOL*        bMute = m_bMute;
, k8 K) O8 u2 ~2 ^6 G3 I        SHORT*        nVolume = Config.sound.nVolume;
1 d9 i) ^7 v0 l
/ j& c6 T" H1 j        INT        nMasterVolume = bMute[0]?nVolume[0]:0;( _3 g( [4 ]" O: ~
: o7 j3 n3 H3 ]6 R  a
        // Internal
4 E# C. N% F  v8 D5 x9 j        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;3 H  \5 P2 O4 \: |
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;7 [2 R) V% P. D3 E3 u# I( B
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;
2 H! Z5 w' Q4 H; {        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;/ v8 z6 \, u2 n$ o2 f/ o+ [( x3 r
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;6 Z. x2 N9 F6 H5 E+ \' l5 n

, d  L2 ~% i9 X% z$ w        // VRC6
9 a6 ]- Y: z8 o1 ]9 M- j' p        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
0 L, l' b0 k* L6 v& a8 v        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;/ N# W9 y4 e! [' b- W' ?4 G
        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
" X$ K$ E3 ^) w/ ~( r5 `6 m  {$ [* p6 o  x# N8 x2 m
        // VRC78 F5 a' {; g" e, |1 h
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;
9 E) A) F  Q! x5 K% V) Z
4 t) ~+ w. V" G0 d& Y0 x( ^        // FDS% s+ r; e. V7 U' a+ Z
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
# F/ s4 c: T+ |
2 ]1 G& S4 h4 x* H; y1 ~! O+ O        // MMC5
9 |0 x* N, b2 t' C0 c        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
. ?( x- `$ h6 g' D$ ]8 M        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
9 s( M5 S& I$ A5 H1 ?" T        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;6 i+ B+ V( b2 }0 P$ t3 D

5 n  Z; t/ t/ r$ O, N6 a        // N106
/ K& B' }. _" d2 H* Y        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;" T9 a  O& Z" i( ~8 p: v
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;$ Z0 }( y5 e2 T& S
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
/ l7 ~# i* q3 R0 p0 y: u        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;( O- e/ B+ N: Z, R: b6 r6 m$ ]
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
( i; r3 g7 l  s6 ~; E) k        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
5 {% p; k" ^4 v1 F  N$ ]        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;4 Q3 k! j& I9 |% ^( j8 |
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;* T. ]; X1 V5 o. `
" _6 I! l* q- Q9 E& T; c
        // FME7- t$ r! y  D7 ?
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
. P# w2 b" D/ w$ ?        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
$ n' v9 s' I5 Z8 ?; _        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
$ D7 V2 c% u: l. O0 J* D; [0 Q# v- y& [6 O
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
7 o3 G- V; \+ |: s5 v1 a7 [: i$ K2 ]        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
$ ^) O' r( y' j0 F: d
6 r" i+ a) k. I) U4 @) a        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
1 N. ~1 X% _; ^; f5 L        if( elapsed_time > nes->cpu->GetTotalCycles() ) {
0 |3 ^/ X% V$ N  {. S. [+ e6 D: D                QueueFlush();0 U( z/ c$ ?3 {2 l
        }$ a) C; }/ V$ n) u9 D5 B
  R) c" h9 k0 a. t. A
        while( dwLength-- ) {
7 t2 g/ P7 _/ k0 |( Z4 ^                writetime = (DWORD)elapsed_time;
4 a9 ], K7 `. K
0 p. Y/ ?, W# p+ v5 q+ T5 m                while( GetQueue( writetime, q ) ) {
4 w3 r! c/ Y& m  O$ O* o1 s6 M                        WriteProcess( q.addr, q.data );
/ ^/ M8 S' M) W7 c5 |! W8 ?                }
9 E. \' ~7 ^: o5 M' I
" B; ~% q: B2 G3 H* x/ T3 Y' k( f                while( GetExQueue( writetime, q ) ) {
1 N$ j- b3 K0 j2 y3 W+ W                        WriteExProcess( q.addr, q.data );+ k  i3 m; J) J
                }
+ I4 `; X' S3 b  M& O1 \: x+ C  g1 Y0 `0 w, e
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7! z7 W; W5 z( s3 Q& B7 `/ q+ O1 R
                output = 0;) n- @& g* M# |
                output += internal.Process( 0 )*vol[0];
2 _# w8 e0 ?2 G: S" b! v% p+ R                output += internal.Process( 1 )*vol[1];
: K; w' w* _' a( |5 V+ t                output += internal.Process( 2 )*vol[2];
/ [7 _9 y  b9 t6 Z: h9 ^) d! U                output += internal.Process( 3 )*vol[3];
0 i$ r$ M9 U# V& N$ j4 P                output += internal.Process( 4 )*vol[4];
! V# @/ ]& C- q; [' ]0 s# M5 R5 {9 G
                if( exsound_select & 0x01 ) {; J% P+ R3 ?* |# Y% L
                        output += vrc6.Process( 0 )*vol[5];
% `: W5 M- n8 B; k' g+ T* g- f                        output += vrc6.Process( 1 )*vol[6];: |: z5 T/ P5 \
                        output += vrc6.Process( 2 )*vol[7];8 e9 D8 U3 L& G3 o" h
                }
9 I5 X! }) i6 j& S0 N  w0 d! h                if( exsound_select & 0x02 ) {
" o  c( q( o* q1 }1 J                        output += vrc7.Process( 0 )*vol[8];/ E- H. r4 T0 U) F
                }# w: T7 {5 w" w
                if( exsound_select & 0x04 ) {
* z' j) Q# l/ S$ V. o                        output += fds.Process( 0 )*vol[9];
  G: S+ D  r9 z1 A+ H                }; y/ W$ ~2 }+ ]4 ^+ ]
                if( exsound_select & 0x08 ) {
7 |) y' r& x( l2 h0 Y                        output += mmc5.Process( 0 )*vol[10];
7 B6 i6 |9 v7 x; |+ K                        output += mmc5.Process( 1 )*vol[11];/ P8 Y; U3 O4 x' R, f4 A
                        output += mmc5.Process( 2 )*vol[12];
' B6 J1 k, j# l4 E& o                }" ^8 p5 c1 s# O, v
                if( exsound_select & 0x10 ) {
3 \! ~' ~% u4 v# b- H                        output += n106.Process( 0 )*vol[13];$ ^8 O  v0 c/ F. F, u& `
                        output += n106.Process( 1 )*vol[14];& q8 \1 q' O: r) d- t
                        output += n106.Process( 2 )*vol[15];1 M+ W' v+ [( ^0 [: u( Y
                        output += n106.Process( 3 )*vol[16];
$ W2 b/ `% L+ k( Y' H) q                        output += n106.Process( 4 )*vol[17];
/ x( ]* h- }! T6 ]                        output += n106.Process( 5 )*vol[18];) C( j" w+ f% t  [- {$ D
                        output += n106.Process( 6 )*vol[19];1 U. {% }' I' ?2 x% t. Z! g$ w: g
                        output += n106.Process( 7 )*vol[20];
7 v2 {8 {! n+ r& J4 [, h, l                }7 J7 t/ U0 g: `" H
                if( exsound_select & 0x20 ) {$ Y* r% r7 D- R5 J) a: F
                        fme7.Process( 3 );        // Envelope & Noise
2 v0 c! ]/ j$ C3 c                        output += fme7.Process( 0 )*vol[21];, e5 J% U2 S; D# X& T  C
                        output += fme7.Process( 1 )*vol[22];1 }% j; q; @+ h1 K5 K  N1 Z
                        output += fme7.Process( 2 )*vol[23];
$ X9 k* H4 g/ R' e" F( K- \7 L, O                }6 v4 P: d# N2 B% N# `0 T( a: g
" A0 _5 A" H; K" x
                output >>= 8;
" w" b; y* C2 \) ?. }4 z& A) l' U3 ~1 o
                if( nFilterType == 1 ) {( q# L. s7 z! c( v$ c; L
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
$ h; c, M7 k; B# n/ h7 `% V                        output = (lowpass_filter[0]+output)/2;3 _  n. w1 r! c
                        lowpass_filter[0] = output;+ ~+ |2 I5 W# [  c4 ?! q
                } else if( nFilterType == 2 ) {
/ E  X4 U$ {$ i' Z) a                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
4 V9 H; ^' B  l: G( D5 k3 K. D                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
  Q9 o" n: B' N0 H! I8 i7 h% }                        lowpass_filter[1] = lowpass_filter[0];
, ]7 _/ P( G. Q: R                        lowpass_filter[0] = output;- o" x4 {) g0 L8 ^+ s; |' [; W* q
                } else if( nFilterType == 3 ) {
0 V1 Y4 f* L3 h: c6 b# P5 o                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)2 L8 l; l2 U- f4 \3 ~$ T
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;( W  [4 X, A( [+ D
                        lowpass_filter[2] = lowpass_filter[1];
  p4 P$ L& F8 E                        lowpass_filter[1] = lowpass_filter[0];# Y% X, b- h4 J! s& D4 P1 v/ I
                        lowpass_filter[0] = output;
7 R6 T! x; q# F                } else if( nFilterType == 4 ) {* r' n/ S+ t9 U% L. j) q' ~1 ]
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)6 U4 a6 C9 i7 e8 w9 t$ n+ J
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;; ?3 I, A! \; i& ]) r
                        lowpass_filter[1] = lowpass_filter[0];4 g& o* B" p* D# h4 I! `
                        lowpass_filter[0] = output;
& Q0 ?5 h3 B4 S: B  O5 C/ ]                }! b. g7 t5 {; o
3 a" K, h" x: M
#if        0
; V, @' T# k3 t                // DC惉暘偺僇僢僩
1 x- B  Y, l0 b4 s% z( U                {" J0 Q7 }+ \$ ^$ N) J( l
                static double ave = 0.0, max=0.0, min=0.0;
) k) g- a- `: E8 t5 s! B% w) o& I                double delta;# g+ s$ u6 {0 T5 ?$ A( M
                delta = (max-min)/32768.0;3 r5 ^& x& l8 R/ M& l
                max -= delta;
' z( l: Y, Q& n# n* n  I8 H+ w. ^                min += delta;
; f( D1 ]9 K  o                if( output > max ) max = output;
4 E0 h- [7 Q& _7 f# E5 J$ g$ z                if( output < min ) min = output;* V6 B# R- `5 u' l, e8 ^& a
                ave -= ave/1024.0;
5 ?2 l# K- ^2 o9 w6 a3 l7 ?0 I6 |                ave += (max+min)/2048.0;) |/ c) e; ~1 j! z+ A1 n* ^
                output -= (INT)ave;
  A, H. F! v1 d# a* g1 {                }
, i6 A) X0 V% T: \0 B#endif
0 x2 @# T8 n$ _; t#if        1
( @, m) G# X3 x4 m0 y+ P                // DC惉暘偺僇僢僩(HPF TEST)) l* e' n: o: v$ H: n
                {* k% G) q9 {% u. v  p3 p
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);0 ^- Z2 e) t- l0 {- D6 A
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
1 d4 ~; ?. c0 q- f- G" O9 b* F                double        cutoff = cutofftemp/(double)Config.sound.nRate;: k1 W$ f2 S' ~" O3 B% E! o
                static        double        tmp = 0.0;: `& \5 e6 U8 H  U7 s3 S& s
                double        in, out;# B& O; F/ t8 ^1 k' x; ?
) S8 g% N9 |$ L
                in = (double)output;4 s* _$ g7 `0 V$ ?4 [) K$ g/ a
                out = (in - tmp);
! D) W( S6 Z6 `! }! ~" u4 P                tmp = tmp + cutoff * out;
8 W& P3 K+ W1 U5 k) e+ i$ [+ `
" r- t3 f! G. w' v* D1 |: ]7 f                output = (INT)out;
2 @" Y# T  r% x7 n( q                }
, M6 p, A$ n# Z: }#endif
/ i. W  g5 M" }! r& E0 k" E+ M  J/ A#if        0
1 |5 w, d2 |* |3 f$ z3 i7 q0 R                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)4 E0 S# ]% {' [% a, ^: U! v
                {
, E8 H$ I  _5 e8 Z2 v                INT        diff = abs(output-last_data);
  f/ O, n4 v4 g2 y                if( diff > 0x4000 ) {- z  v+ [0 _$ w6 B. @
                        output /= 4;5 R* Q2 N6 Q8 w# F* s
                } else 8 {5 y! U. V7 @7 l7 u2 x1 p/ u) z
                if( diff > 0x3000 ) {0 |) g# f* S4 c5 H; ~/ K
                        output /= 3;
# C; D% @9 m$ p. N5 i                } else7 Q& {6 s0 [3 v& p! R
                if( diff > 0x2000 ) {
8 u5 |% X9 o  V# l& U- {                        output /= 2;
2 U3 F1 r+ s  u  m                }0 x) g5 k, p7 H, N* w
                last_data = output;
, @/ v' ^; q+ P* q; w5 f7 F                }, o+ l4 x7 l2 E  ^8 q, V; v
#endif
  L4 h) z4 N/ l                // Limit
& I4 H+ s  |9 C, w3 P$ A% s                if( output > 0x7FFF ) {2 [: A! a5 p. z6 a% ], M
                        output = 0x7FFF;
5 [/ X9 k4 J& j5 a" h                } else if( output < -0x8000 ) {- H6 x9 h4 k7 R$ a, P1 y
                        output = -0x8000;5 x% [4 y, H7 V% M% o0 f
                }
6 Z. Y  g0 p( K% i0 P" d3 `
( A& A; [# O5 a                if( nBits != 8 ) {
6 t5 I! C8 ?& v" f; S; l                        *(SHORT*)lpBuffer = (SHORT)output;
  ?2 B. Y$ y9 x" d, N                        lpBuffer += sizeof(SHORT);# ^" W3 {$ w! n" H% d
                } else {
8 X# I) W; z( c0 `                        *lpBuffer++ = (output>>8)^0x80;
3 p5 }5 n7 H2 a4 i8 g                }
  R7 |* H) ?, ?9 W8 c8 E  I& ~# p8 h) F, I
                if( nCcount < 0x0100 )
1 o$ ?! `$ |8 c6 I  ]% ^" p                        pSoundBuf[nCcount++] = (SHORT)output;6 Q! g8 w& V( a( o/ P

& o4 y4 l# q7 \' u8 m) H8 v//                elapsedtime += cycle_rate;8 E  {  h9 C7 G2 L7 i# v! e
                elapsed_time += cycle_rate;
6 p; t. S* n) z: [        }! P; ^; m5 [: D: c7 H+ O
$ @* H0 d& g! v$ P/ A- ]7 c
#if        1- Q( {2 [* o6 j' x% X$ T% o2 G
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {- p; u' z* i' y+ Q7 Y
                elapsed_time = nes->cpu->GetTotalCycles();
7 K, Y- g8 K+ e$ f( F        }& u) o3 P2 O2 U* \, U+ x
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {2 g+ O# H# m1 e7 |# S
                elapsed_time = nes->cpu->GetTotalCycles();
6 s2 `9 `" z0 y5 x  T: y( G- {' Y3 Q        }
2 d$ A& T6 n! X: L  m# I8 ~#else7 p3 K) k: d; o0 a) A
        elapsed_time = nes->cpu->GetTotalCycles();
% Q* [, z) R3 f  `' H8 O3 j#endif
$ V3 a: Q, Y) s  X}
" S! `, P, z7 G3 R9 H9 v, d2 e6 r0 d% G6 s% ?- g- H! A# f
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)4 m  R! U# A7 j. j, d
INT        APU::GetChannelFrequency( INT no )
* ~0 N* O) \- s/ z7 b  l{( q# A6 i+ q8 \/ G4 t
        if( !m_bMute[0] )$ I3 u2 q0 e5 a) G( P9 ]7 g7 `; I
                return        0;' E. c9 b8 y- H& V

6 ^; X3 C3 Z2 h        // Internal
# L) a4 l' \/ [. Y) W        if( no < 5 ) {
1 b7 s: F( I  ~" Y% B9 r' z                return        m_bMute[no+1]?internal.GetFreq( no ):0;$ h" A) }  W1 g& S' P! o
        }" G. ]. `& O! T0 j# I  J7 l
        // VRC6% p& G3 o- n$ R; |8 h: \
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
  a9 X, j9 ^8 U6 Q% Z" u7 ^) X% D5 H                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;3 e) N- z5 g( o9 {+ `
        }
+ E- o6 G3 w' s2 F; q* c9 X, ?/ ?        // FDS
* k& w0 q% q3 g6 O        if( (exsound_select & 0x04) && no == 0x300 ) {, r: }0 d3 Y9 ^: b" R5 o! s
                return        m_bMute[6]?fds.GetFreq( 0 ):0;
% {( x: `% ~  n6 E        }7 s4 J5 B5 V* U. F
        // MMC59 u$ L( G1 Y! E3 \- H/ E
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
( Z$ ~6 ]0 w" w. h) \* a' d                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;7 v+ W; {5 Q  q  A, K
        }; o5 E: ^" F, e( M) p
        // N106
1 @: ^! f( k4 E( o        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {: w, h% i9 h$ h  M& j
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
5 S# b8 v; ^3 r% g+ n        }+ H/ r7 m4 ?) I) }0 b
        // FME77 Z1 {( s: N8 [& K% {! Q1 E  X  Z. G
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {% x: D4 e8 D5 z5 ]* |
                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;6 W1 x; L# R. Z7 L
        }
6 o% H: l! j5 M' i- ]        // VRC7
8 m. Q8 @& a" L! R0 v/ p        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {% n3 H- d$ h7 s- \
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;, B5 R, C! t& d) t1 _$ F+ e
        }) E9 t: ~7 v$ m. n8 k( C
        return        0;
( u& v4 n  Q: U; n. G0 Z0 ?& P& R}8 n- E+ t9 O  p0 K
* ~) e9 W* Q% D- y! a  z+ Q
// State Save/Load4 H: H; t) _  m8 ?, P6 `
void        APU::SaveState( LPBYTE p )
- q; L8 {' o# n: W: E# |{
- c* o4 V6 M- T& x4 m  d  S$ _#ifdef        _DEBUG( j" g- b5 G: ?# C* a& d+ [
LPBYTE        pold = p;
& E1 V. F  b& l7 B7 e$ l9 G  R8 C; \5 I#endif" e! u: B' ^# H2 H- Q
* {2 c4 o2 q0 u. p
        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
' p, A  _4 U3 [! Y4 [% s: H        QueueFlush();% O' K) B8 T. I/ h
- B9 V; I, X& _/ C
        internal.SaveState( p );
) u1 Z: b" L- [! z; T: D6 }' @        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
2 o7 A0 \) ]0 P5 z7 g/ w4 ?# D. F
( G% x- J( L( q2 |* u        // VRC6, H% F0 e/ g: ~
        if( exsound_select & 0x01 ) {/ z8 {+ D9 P7 ]/ `) M9 Q; I$ _
                vrc6.SaveState( p );
) N2 Q! y5 K" b: e! |  ^# c9 H( i                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding& e+ ?- F7 Z9 k4 K. c
        }  H7 H: h! w5 [( y4 U
        // VRC7 (not support)% p- U7 d* L  M2 B" J# O3 l; G
        if( exsound_select & 0x02 ) {
9 O+ Q& G* s6 ]1 z; b5 T: l0 [# \. R                vrc7.SaveState( p );/ a" ]/ e  u! q. T
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
* w$ A6 \* @" A+ K        }
1 O" F# @, R( D0 d6 I/ F        // FDS
+ z. q* M  i( b$ t# |: ?        if( exsound_select & 0x04 ) {
! L& o0 I, u1 ?4 j                fds.SaveState( p );
- U- B- s9 d8 b( N- S                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
% `4 P* @# f3 ?+ z$ q; K        }. T! H) |+ i8 l% T1 y" J
        // MMC56 [4 p4 m1 V3 U
        if( exsound_select & 0x08 ) {- c; B( @( m- ?7 q( W
                mmc5.SaveState( p );
- s. o, K# @; O                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding/ b& b8 w6 F# u4 L! Y2 m- _' v
        }
! E# ~3 z" S9 z( q) R        // N1068 G! a* A" T# j" v, ^& M- Z: x( v
        if( exsound_select & 0x10 ) {
7 n; W: t, |# Q7 j. a/ U+ W                n106.SaveState( p );" j$ P" X+ ?  E; o& N8 Q: `
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding, ^* R- P- c  E5 K6 D6 z" g- l! R1 W
        }9 D: O. |/ j& c+ n2 P0 S1 s
        // FME7
  A- ]% B! s7 A+ u# i        if( exsound_select & 0x20 ) {# S2 ^/ u* I. k7 n( a
                fme7.SaveState( p );
" W5 N* Y! O- B% f& {0 b2 j                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding" C& `8 |/ B: P- @
        }
; L) P5 b) Y6 B$ H
  z0 w% X, n" ]#ifdef        _DEBUG  @; D3 a- _1 r& h6 F
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );7 D2 h: h( Y/ [; V0 l4 C  W: `
#endif
8 s1 Q0 P7 T7 N# Y( v}) A) O- u( [7 D7 g6 M$ \  r
$ E" t& T0 v/ M+ J9 }
void        APU::LoadState( LPBYTE p )* G/ c7 {0 x; [1 D7 T* H  f5 k; g
{
/ A0 A8 @2 S0 ^) ^, `* E        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
! ~  o2 h: k+ Z        QueueClear();9 D% E0 u5 ?8 R& ?3 y
4 l! i( c- B. y, O( e! [
        internal.LoadState( p );
# [, d# D! m! a* Y  N2 L8 i        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding5 \+ j% _) c: Z  [* i8 W4 h
/ p+ K  n; G4 D0 A/ c
        // VRC6
: s% @2 h8 b0 _$ }        if( exsound_select & 0x01 ) {1 k1 Y3 j, u/ W; r/ @
                vrc6.LoadState( p );$ e$ |7 o! f* O( Y. Z
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
* l  a9 {% Y/ m8 I' f* ~        }6 v% M& i7 b1 I3 R/ g
        // VRC7 (not support): [9 r# B& L) h; G" W' y
        if( exsound_select & 0x02 ) {
0 L9 H$ N" a  r3 R' y, _                vrc7.LoadState( p );
+ ]& \* z3 a/ g                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding5 C  t. y6 i$ F( C
        }
# K/ l9 s1 }9 z2 o$ W        // FDS
8 E# q( k8 ?9 d" ~- v( x        if( exsound_select & 0x04 ) {
4 {* k. t2 r2 b- Q- }                fds.LoadState( p );5 N# ?+ o* p5 P
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding; Z3 ~/ m1 J# D; V
        }
4 G9 p, a7 N" }) e' l        // MMC5
# T6 V8 z6 |5 G& F1 ]        if( exsound_select & 0x08 ) {
, e! d. M% g* G0 a! t) n                mmc5.LoadState( p );9 t( _3 M- b( J$ }9 }& @
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
1 ^( \% n# L; Z; o* L        }
2 n" l3 f. O, M5 X0 G+ l        // N1064 L/ Q& v8 q7 {
        if( exsound_select & 0x10 ) {# }3 \& Q. O' |* D9 M1 L$ Y* j
                n106.LoadState( p );% X3 |# A  P: L+ D
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
0 s  B) e* ^) ^9 P. L, t+ q        }
- k; w$ [0 Q4 f        // FME76 e0 C- q$ Y3 \8 ~, V4 J- G
        if( exsound_select & 0x20 ) {
: _$ M6 q0 `# J                fme7.LoadState( p );6 z% k, P& |  ~1 V' V$ ?
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
6 C/ [. a1 d7 y, g" h4 R, B$ Z0 e        }. w" k/ Y9 |( ?. V/ b# I
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 ' |) o* n; s, i0 u3 f% g
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
; I# L& c& @8 U% I! H2 v$ v; r感激不尽~~
+ J- D% o4 y3 ?. u
恩 我對模擬器不是很有研究,
! I5 x% U* V" x6 h8 H# Y& P雖然要了解源碼內容,可能不是很困難,' D+ F( Q; H& T( \$ I  T6 `  p
不過還是要花時間,個人目前蠻忙碌的。. l# D8 R5 q% y* q; x, |! ?

6 ?6 R; [/ z3 @; e/ U2 d給你一個朋友的MSN,你可以跟他討論看看,
. K7 d: j; M' q他本身是程式設計師,也對FC模擬器很有興趣。
; |5 R9 g6 [0 r
) L) n" ^, x$ c% w3 f" s4 d( bMSN我就PM到你的信箱了。
, Q( [. r5 R2 w1 X+ B1 c; X" W, x* g# r' T3 N
希望你能有所得。

该用户从未签到

 楼主| 发表于 2009-11-9 13:23:59 | 显示全部楼层
呵…… 谢过团长大人~~

签到天数: 80 天

[LV.6]常住居民II

发表于 2009-11-9 16:02:29 | 显示全部楼层
团长的朋友都是神,那团长就是神的boss。

该用户从未签到

发表于 2009-11-20 13:13:25 | 显示全部楼层
原帖由 独孤残云 于 2009-11-9 13:23 发表
$ n; z$ T' [: \8 q/ i/ c3 V呵…… 谢过团长大人~~

- p5 W' D# y& x, `" ~: g7 ~+ F$ E, v5 H2 Y
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
( [1 V0 _4 i/ N2 A团长的朋友都是神,那团长就是神的boss。
9 }+ F2 @( d' K- R% r5 z9 Y. R; l2 X
哈 不敢當,我只是個平凡人,+ `7 j7 R# @5 t# s9 i
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙1 m. v4 O' z+ k: [2 a
ZYH
1 D! f$ X+ i- ~/ m0 G* ?$ iQQ:414734306
/ n8 W5 g; o2 _9 VMail:zyh-01@126.com
3 ~; J; o' Y3 ]- s6 x% c4 Z! ^. G2 Y' ^2 V
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 $ L7 X8 _, g. ]3 X( g* }( i& f
再次对团长大人和悠悠哥的无私帮助表示感谢~~

+ k5 l! r# T" b不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-27 15:17 , Processed in 1.086914 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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