EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
2 u# c9 ~' n. Z! V# E% Z楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
8 k5 i& S, u2 H, r这里有相应的模拟器源码,就当送给大侠了~~  v& M% x5 E& P( i! ?. _
http://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表   h0 n& }. o/ C+ @2 ]! h
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。6 Q5 O/ o9 ]* G3 M/ O* J+ `" J. {
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
. ?, m- Y2 O# U3 L& d% l这里有相应的模拟器源码,就当送给大侠 ...

' e# b8 l, ~/ r$ X聲音部分(Audoi Process Unit = APU):! P( D; }6 a, ]2 {
.\NES\APU.cpp/ b, E3 @" o8 F3 j% @; [$ }
.\NES\APU.h5 h. \- j7 W- T; i+ Z0 i

7 i* \. c; M6 \. V+ B3 {
3 B$ G; G4 Q- \- Y  h. ~" o影像處理部份(Picture Processing Unit = PPU):
8 o" `( L+ ?* K& {7 i# Q* ?.\NES\PPU.cpp/ S" J; G+ ]( ^% W) V
.\NES\PPU.h7 E+ @( k  `$ }" L: H" ^

4 t9 I# L! J1 F如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:# j5 F. `7 _7 \% T+ z# o
(由于很多专用术语和算法机理都不明白,所以看不大懂……)6 L" l2 g% W" s) C
//////////////////////////////////////////////////////////////////////////( G& L; N2 M' w% O) p
//                                                                      //0 H8 ?( U* {# x! r* I
//      NES APU core                                                    //" T7 b4 d* N. n1 {+ i% a
//                                                           Norix      //
7 I2 e. O1 {7 P( M//                                               written     2002/06/27 //# y9 Q, R3 N& }9 ^2 l3 J
//                                               last modify ----/--/-- //5 N0 Z  A/ v. k) s
//////////////////////////////////////////////////////////////////////////
" I. n# P& u; ^#include "DebugOut.h"
, Q" D2 \. p$ c! ?8 d#include "App.h"
9 \& a8 S' i, R* P  ^#include "Config.h"
  ^3 r2 V1 O5 }
9 l) T4 S* k) `. m" s#include "nes.h"
3 B" \$ ~6 d; N. w; {#include "mmu.h"
! t/ H2 B8 p9 z/ ?#include "cpu.h"2 `, a1 c6 i2 H7 V. l
#include "ppu.h"
. P1 g8 P6 ]) ~) p6 h# c% P#include "rom.h"
. w4 u6 ^2 i$ w) b#include "apu.h"
# s- L+ O0 {( O9 D% N/ M" B+ @
1 [9 n2 C" d% ^& M) |; G// Volume adjust7 f1 J1 u0 r% R0 s( ?
// Internal sounds( I% P+ S# q  D
#define        RECTANGLE_VOL        (0x0F0)
( ?3 _  m" |3 y+ }( }5 M#define        TRIANGLE_VOL        (0x130)
: P8 A; P3 i4 k#define        NOISE_VOL        (0x0C0)4 \1 L! V( K( a$ A) n( z
#define        DPCM_VOL        (0x0F0)8 a5 M7 y1 h/ {: l0 X
// Extra sounds$ O& C* x& n1 B+ {9 i* H: ]
#define        VRC6_VOL        (0x0F0)
3 J: S. k  |: F+ ~#define        VRC7_VOL        (0x130)# T' f. Q% V; h+ C! F# f% ]4 @
#define        FDS_VOL                (0x0F0)
, ~! h& s  z$ m# x  [2 b3 e#define        MMC5_VOL        (0x0F0)
  D# L! A; ^" M+ Z5 F#define        N106_VOL        (0x088)
! J: I: B* Q3 }2 s& \1 e7 `#define        FME7_VOL        (0x130)
, j# I* q; r1 P+ P: c
& l; Y7 Z1 S3 ]8 QAPU::APU( NES* parent )
" X) ~2 A: j+ K2 J$ ~8 Y{7 _1 M. q# r& ?: ]% M
        exsound_select = 0;5 o! [- \6 U$ F5 n" C& n
- N4 ]) f# S( K; Y4 I7 I1 K
        nes = parent;( n6 M- e. z, o3 L+ T# t$ A0 x; y
        internal.SetParent( parent );
/ J- w0 m4 J$ T: i' K; R6 e) t' f
        last_data = last_diff = 0;; C; j( R# ]2 n( v$ N: @1 U/ s
3 e2 O! h  t- I. {
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
# v6 V4 l( @$ T* m! h5 s8 ]
7 n5 ?& C3 T0 w4 i8 L        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
  [2 k- u. G( m) ]        ZEROMEMORY( &queue, sizeof(queue) );  e) Q* s- H$ \# R* `* S
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
0 K' R/ I! Z3 \( p6 T. z. |) m& n: G3 `( I- a  n
        for( INT i = 0; i < 16; i++ ) {3 n0 o( G0 n" i4 @- _( o  X  b8 F1 }
                m_bMute = TRUE;0 |+ c: v% W1 \( G
        }  Q4 q8 q: W+ D0 x' c- C& u! b
}" c( H7 ]0 }, G6 S

9 z1 Z; ^' f! J! N/ jAPU::~APU()- V" ]9 X  G( A5 \$ t
{
5 [' Y; \8 P! ?}% k8 n" U# L) E2 E6 A8 B6 n6 z$ C
# X! w' b2 [! a+ a2 f2 u6 s
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
! P9 Z2 Z; L' O8 {' q; m9 M{
$ d+ d4 [/ U6 ~0 {+ C% U* a        queue.data[queue.wrptr].time = writetime;
( M1 b. C7 L( G7 g        queue.data[queue.wrptr].addr = addr;
7 W( R! E/ j" \) g# y0 A& p        queue.data[queue.wrptr].data = data;
$ C; ?$ E0 R& N0 r9 c4 P) h- w) _        queue.wrptr++;2 F( X" M; u0 z( }! i1 D/ B
        queue.wrptr&=QUEUE_LENGTH-1;# N; n' n; z- b: F! \" q
        if( queue.wrptr == queue.rdptr ) {
4 G7 u* E2 F; o. ~                DEBUGOUT( "queue overflow.\n" );3 T1 s" E8 L3 v6 I
        }+ p, Z# @$ @/ i
}5 f1 P) U! V# g0 _1 T

$ B; ~+ W1 b9 _+ i+ o, H3 P6 s& eBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
# m+ A) h8 n' f1 u5 @" y  Y{
9 o4 O9 Y; C; ^        if( queue.wrptr == queue.rdptr ) {. Y# {$ k9 l1 e3 K$ @; Q5 X8 O5 l  a
                return        FALSE;
% |3 D, T" y- k0 P2 K        }
$ F4 O9 N# O) A: @; T* K        if( queue.data[queue.rdptr].time <= writetime ) {
$ |: V" m# ?, H3 T; B7 |# s9 L                ret = queue.data[queue.rdptr];, l9 u# s6 g  I5 P
                queue.rdptr++;
; o! q; b/ w- m; L                queue.rdptr&=QUEUE_LENGTH-1;
6 F$ k$ x8 W/ u* X, i                return        TRUE;
* z" u' `) |; k, _, G3 w        }1 D% _* S: s* P
        return        FALSE;
9 ~! k) R; S4 ?0 L}( D6 r6 q: b9 t' v

0 e" K1 k- q, ?5 b# Tvoid        APU::SetExQueue( INT writetime, WORD addr, BYTE data )
8 ^6 ~+ ^( ?0 x1 ?8 v{
! s5 \$ N2 v4 I. D6 {/ T3 a        exqueue.data[exqueue.wrptr].time = writetime;8 T- V+ l9 k9 c( S  \7 }! i
        exqueue.data[exqueue.wrptr].addr = addr;
+ T' \' A" M" _! G/ n1 h" d        exqueue.data[exqueue.wrptr].data = data;
; W. u. B( X; P8 e. R0 K4 s        exqueue.wrptr++;
% B$ f) _1 }$ W% [1 M        exqueue.wrptr&=QUEUE_LENGTH-1;! v, ~) w+ r$ y0 l5 [6 k7 p
        if( exqueue.wrptr == exqueue.rdptr ) {3 l& I# i( @3 W1 l' }0 ~
                DEBUGOUT( "exqueue overflow.\n" );# o0 F2 `/ V  J3 w% O
        }
+ L$ n  n# N8 r1 h}- r! O0 f% s+ N9 n; ^
5 |' b6 _* X2 O6 D  R
BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )5 X9 U4 r3 |& e+ F
{
2 X- K3 @9 s9 `5 G6 e- T* k        if( exqueue.wrptr == exqueue.rdptr ) {4 j7 i4 d8 Z* X
                return        FALSE;
) Q9 ?- P7 F& X  s, |5 Z0 K/ s8 Z        }( e& Q# T' Z2 `0 x; ^/ H6 M
        if( exqueue.data[exqueue.rdptr].time <= writetime ) {- O7 g5 B+ m( D% S1 r* H$ @+ W  P
                ret = exqueue.data[exqueue.rdptr];
! x" |' E- A8 P8 \+ I6 y& {                exqueue.rdptr++;0 t' F! k; G5 o' t" I: l4 i6 z
                exqueue.rdptr&=QUEUE_LENGTH-1;
5 R% z! w4 }; T# \" v3 x                return        TRUE;! u- F8 D' L. L" @# X5 [
        }
4 a5 Y( e* h2 m$ O  v% F        return        FALSE;( F; k+ I, A) k% s, K
}
( h  K! V* L) _4 [8 v, h# j+ o0 V
void        APU::QueueClear()
/ u& r5 c3 {5 c{7 `* A, U/ O3 C) S, e3 K- x
        ZEROMEMORY( &queue, sizeof(queue) );
/ z' u- v  B8 D  i* ?0 J        ZEROMEMORY( &exqueue, sizeof(exqueue) );2 V. e3 U2 W2 }% a1 I. z; X# g
}2 x( L: o8 {6 |" W: X

- Z9 H9 y8 }& M) F3 X  Rvoid        APU::QueueFlush()
: X' R6 Z% Z6 k$ W! L0 @{' k# b" K/ Q% F" o3 y9 d. B- }
        while( queue.wrptr != queue.rdptr ) {
, `3 v- y" B) z, B$ K4 k) T                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );% f( q% O! o& R6 C! l
                queue.rdptr++;
8 P1 \4 q% l* L                queue.rdptr&=QUEUE_LENGTH-1;: P% L; O- H% i& i- f" }2 k
        }: e% Z' l) _  @3 x( l) I
" H# T& o9 x, F4 k, p
        while( exqueue.wrptr != exqueue.rdptr ) {" s8 l& w3 e% i
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
0 i2 ~/ J& t( A3 U% d, \3 b8 j                exqueue.rdptr++;
; h+ u) A) _- y, M) u# h                exqueue.rdptr&=QUEUE_LENGTH-1;/ F$ p6 Q' d; C$ r& Y" X
        }0 ^$ B8 P4 _  E( y% Y
}
$ ?) A$ w5 r& n+ s5 ?1 s- O, K# F
void        APU::SoundSetup()3 M4 ~+ x# @" X4 j
{2 [. t3 ]/ I) R, R7 _, `' I; T6 u( Z
        FLOAT        fClock = nes->nescfg->CpuClock;
& n- ~  N; E$ x+ U  l  z        INT        nRate = (INT)Config.sound.nRate;
: A. {! x2 T0 f1 Z5 C        internal.Setup( fClock, nRate );1 `5 t  c/ ?( F0 \; S0 a
        vrc6.Setup( fClock, nRate );
( y7 Z- f4 Y( ^. d( b8 K! }2 s        vrc7.Setup( fClock, nRate );% z1 i9 l, Z, f
        mmc5.Setup( fClock, nRate );2 |% ^2 h, y2 C, d+ q9 y* o3 {
        fds.Setup ( fClock, nRate );9 Q9 P1 [& y4 n/ H5 R& s0 S
        n106.Setup( fClock, nRate );
! ]& T$ w( X2 m5 z        fme7.Setup( fClock, nRate );
0 X; l4 ^( \; q+ q6 X! _}
" G( W: V  y1 H% {$ x2 }
8 H# n8 S' S7 o# |9 lvoid        APU::Reset()
6 t( d7 e* l4 r; t6 H{
5 m9 Z8 e! |& K2 h! w. l% A        ZEROMEMORY( &queue, sizeof(queue) );( `0 X2 Z! g9 `8 u- d3 c- u7 D
        ZEROMEMORY( &exqueue, sizeof(exqueue) );# Y$ c9 C, [$ H# l- C0 @8 V  c
# s* _8 W) @/ r+ L" R
        elapsed_time = 0;
' d9 k; C" F% p7 Z
! X! _( q1 {$ _' m2 D& o5 ~        FLOAT        fClock = nes->nescfg->CpuClock;
7 r2 [% H4 n; y% d7 R+ A        INT        nRate = (INT)Config.sound.nRate;
1 U2 w2 f9 W, u9 g! U        internal.Reset( fClock, nRate );
, H' S  D6 g. n" Z        vrc6.Reset( fClock, nRate );
- M7 @( S* ?6 o9 x) P        vrc7.Reset( fClock, nRate );+ J- G" k5 p' w7 y
        mmc5.Reset( fClock, nRate );
% R1 x/ J% R7 s" Z% D1 J        fds.Reset ( fClock, nRate );' @/ n' k/ |% k1 H5 ]6 @( x9 j3 [
        n106.Reset( fClock, nRate );
' U- d  d3 {9 M0 V- g) v4 H        fme7.Reset( fClock, nRate );
: E8 M2 u: p3 {" a+ `, Q9 V$ Z" q) @9 a
( P# e  G6 R9 d$ ?$ L$ `5 y7 s# [  C* w1 J        SoundSetup();
9 i* o6 J% P0 @( X; H. _7 T6 r}
2 u8 f% s$ [0 e) Z  Y
; N' ~1 A1 [8 }) D+ P) V3 m" Pvoid        APU::SelectExSound( BYTE data )
- X' j, O6 t1 m{
! S* t; A9 M. i5 q3 j, U; _; k        exsound_select = data;
# M5 t; a9 W  `& W}; d# p) j0 ^; z/ _
# f8 U9 ^0 ~1 |
BYTE        APU::Read( WORD addr )8 `$ I7 `) L$ {- x) M1 [
{
. p! \& h2 z/ j( |- ^: G# C9 @        return        internal.SyncRead( addr );4 {/ B' s, o: m! l
}9 V: J% S- X. U6 L. Y

7 o; n5 s! `8 _6 [' T; ~: pvoid        APU::Write( WORD addr, BYTE data )& |5 T9 Q; {7 Z2 m
{
; p& ^7 {3 w* x/ ^  A5 J# G        // $4018偼VirtuaNES屌桳億乕僩) r1 U, J. x! {5 e) _
        if( addr >= 0x4000 && addr <= 0x401F ) {3 y, N4 {1 Z' q  y8 D" W/ a6 B
                internal.SyncWrite( addr, data );7 t; b3 y! `0 c7 K& i
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );  t9 G  w; ~, o- ~! E. X! c
        }
; r8 z6 p' e7 U9 C6 }1 S7 q- G}2 ^0 ]! Z  V1 U2 ^
- ^1 l1 G( _/ M" s$ o- Y! ~' h  ~  _
BYTE        APU::ExRead( WORD addr )
  p, \- S6 C" l0 B2 B4 C8 ^& M{/ j3 m' a* e  p9 b8 T
BYTE        data = 0;
- S- w! ]/ C" P$ c: D% I3 c% y) ~9 x) P5 z4 {
        if( exsound_select & 0x10 ) {# f' |; u/ t* l& P" _1 U
                if( addr == 0x4800 ) {( E: T  w# G  e' j1 _& x: ^! v  p
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
9 \  J5 D/ M; k                }
; U% R6 J/ S% q0 K        }3 \0 y: B8 A5 w$ J3 |$ O
        if( exsound_select & 0x04 ) {
- F. t5 M3 I- f4 V* a! y                if( addr >= 0x4040 && addr < 0x4100 ) {7 M- D1 X3 P' J0 q% _1 k" ?: e, @3 H
                        data = fds.SyncRead( addr );" \2 h$ C' \7 J8 \; Q
                }' `+ L, k9 B1 l* B2 k5 |
        }
9 g6 }6 A1 Y0 e$ ]- X        if( exsound_select & 0x08 ) {
. r! b& i$ r7 }% C+ i                if( addr >= 0x5000 && addr <= 0x5015 ) {( d9 D7 z& d3 a5 [) F+ C6 r
                        data = mmc5.SyncRead( addr );, ~$ i* m3 M6 J* x8 h# O
                }
5 q# ?! K) Q$ {* t' V        }
  K1 U8 g- m8 o$ X
- H2 B; N8 W! z3 v        return        data;- V! z6 S: a- a- H2 m
}& L  e* O- _4 n* k% o, @& S. Y

: H% k1 r" b, O/ a0 C; _void        APU::ExWrite( WORD addr, BYTE data )( O( J( R, i5 {* {! T1 O
{
+ y4 H  C5 e9 I        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );
- E1 _8 [+ p& V/ E
' c: t1 d6 i) U0 K        if( exsound_select & 0x04 ) {& D4 t7 ?# r9 B
                if( addr >= 0x4040 && addr < 0x4100 ) {
& r2 W9 f6 z$ s% [5 X( t& p                        fds.SyncWrite( addr, data );+ o% w+ ^5 d% {: Y6 M2 i
                }- |' J" w/ x1 ?# M
        }
1 p. E# X: C7 ]5 _  [# x- s+ a4 T6 f# w4 }" t) p2 A' P
        if( exsound_select & 0x08 ) {* w7 K: Q; |0 H4 V( ]3 h" y
                if( addr >= 0x5000 && addr <= 0x5015 ) {1 w6 A; {3 T6 [  l% {& P
                        mmc5.SyncWrite( addr, data );; K! }0 l. Y( r9 N9 t2 R0 ^1 h) X' o
                }
7 p6 \# @2 L( F4 Y        }
! n; o% Q% \5 n2 j2 W3 _) b. m3 G}) q6 L9 n* g7 c; T2 Y5 [
6 U* H) {. a# L7 E# y
void        APU::Sync()/ l( }7 a  h# N! O$ b5 c
{
4 A: m' i% T7 B* q1 H}
" Z0 T) D! {. _& ]3 O% |0 o) V7 i; P, q
void        APU::SyncDPCM( INT cycles )
; L3 D9 K2 ]7 u) j# u0 x; \' f: P) V{3 @" M5 n9 o; @+ {$ p0 }" A
        internal.Sync( cycles );
- U6 W5 R8 b0 \  Q+ l6 H& |7 H1 i6 N7 ~/ M
        if( exsound_select & 0x04 ) {; ]# T/ z5 s/ G5 J' a
                fds.Sync( cycles );. g( z6 C9 Y8 }( `# Z6 R
        }
1 E; m  U9 K& G. F7 g        if( exsound_select & 0x08 ) {; {9 _0 X9 A3 t; e% a! L& i# |& C
                mmc5.Sync( cycles );/ {7 G4 t1 Z" Q4 w& _# H. H
        }  F- |: }7 \7 c  S2 ~
}; K" E, B! M. U! H; K5 M" K4 l( t
( |1 q' S) ^( `0 D  L
void        APU::WriteProcess( WORD addr, BYTE data )5 n0 {. x) t/ t" f2 E7 S
{) [* e. @- p4 v* t+ _
        // $4018偼VirtuaNES屌桳億乕僩+ ]$ f" T; V2 x  Q: I
        if( addr >= 0x4000 && addr <= 0x401F ) {
1 X- d- `8 |. T7 R2 \' b, Y                internal.Write( addr, data );1 d2 s. {( R0 b- w
        }& f0 a( l- {$ t8 U: f  w
}$ v7 E/ w6 Z1 J& b6 L

  A6 Y: H# T% fvoid        APU::WriteExProcess( WORD addr, BYTE data )
/ C$ f- g0 U+ S; l2 O; Q6 K! K{, G- O  B' F4 V! }8 v
        if( exsound_select & 0x01 ) {  _. A/ {( ^& f" {" @2 p
                vrc6.Write( addr, data );; O% w  P( ^# ]! k" b
        }7 E7 _5 I5 c: @, g$ ~
        if( exsound_select & 0x02 ) {
8 d, b8 D; l4 N( C: |) N$ E! m/ D                vrc7.Write( addr, data );" G3 |- W2 ]+ m
        }
1 S7 X2 o5 f$ w# A) b) g% R5 V        if( exsound_select & 0x04 ) {, D8 h, U  e- T& M+ m
                fds.Write( addr, data );
; K9 Y: T: X4 [! ?/ r! i        }
, D4 K% C% b/ t        if( exsound_select & 0x08 ) {. b) W, B7 {% n: o9 k& |+ R
                mmc5.Write( addr, data );
& b% j! M  v" ~, `. r4 K% p: T: g        }7 L& [4 A+ }! J% o6 C
        if( exsound_select & 0x10 ) {0 a1 [% N2 }9 p
                if( addr == 0x0000 ) {7 M% \/ B/ j1 v5 I
                        BYTE        dummy = n106.Read( addr );
. s& L7 t8 B$ ^9 o) R                } else {. c3 {" Q% c8 ?: k2 U
                        n106.Write( addr, data );# n0 v7 p( |. Z4 p$ ~" J8 |1 a4 G
                }. X6 b- z! v' M
        }4 G% f; m) M* o2 S7 l5 a' G
        if( exsound_select & 0x20 ) {
3 s5 R7 H; P) O8 ^9 |                fme7.Write( addr, data );/ N9 C6 N$ e) [# }/ d
        }
3 S9 Z- K, C. R. R8 U. U}' _# A. q& u0 P3 q
( B. s* M) x% e! t0 l* f% r& Q2 H
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
! f1 u; [) u, \" D5 j{" x" ]# b  u) L5 y5 a6 d& y! W
INT        nBits = Config.sound.nBits;4 E0 D; v  I. N& e# R
DWORD        dwLength = dwSize / (nBits/8);
* c  L6 g* c( N! \0 pINT        output;1 K$ q& w, _$ D: D8 `8 v2 l/ R
QUEUEDATA q;
. h" U# S: q; A, I+ k. J1 cDWORD        writetime;5 \/ }5 S: X9 N
3 o' a: ~7 g& T4 Q3 u
LPSHORT        pSoundBuf = m_SoundBuffer;
: c/ M+ y: _3 s& E  mINT        nCcount = 0;
( e4 u" m4 K4 y4 \# F
/ @7 e$ Y0 O' m2 t# b7 hINT        nFilterType = Config.sound.nFilterType;: ]" {- ?7 K! d' q1 L7 P
# F- h7 W$ Y1 J( t  A
        if( !Config.sound.bEnable ) {
% V" ]% {8 q' n) y% ~2 z                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
& }/ O# ^3 s$ d; S                return;
9 V: v: S- D% h" {/ a  f8 S* c; A        }
; Q7 X8 q7 M1 ^  Q/ ?1 b/ ?- ?# K
8 Y6 r5 S2 y+ Z4 Y5 X        // Volume setup% a# X$ j& r5 {5 s9 f" U  B: D
        //  0:Master
6 n5 v- b. ^/ x2 r: ~        //  1:Rectangle 1
! R5 o* ~9 k4 k+ U3 {3 D        //  2:Rectangle 2
* M- b+ A8 Z( ~0 i4 Q7 H        //  3:Triangle
6 h) ?2 K9 {! F9 j; I2 A6 Z        //  4:Noise
4 e* K: E7 u" `( t- ?' o# h        //  5:DPCM
  `# \8 U% }5 ]# z, a7 X. s$ C        //  6:VRC65 K2 R+ G+ Q4 O3 O
        //  7:VRC7
5 X/ x. ^* o, i( f3 w$ }  n9 P        //  8:FDS
' x* {$ x- c5 B% q        //  9:MMC5
7 i* x6 w- t% w( m* w$ Y8 B1 e        // 10:N106$ T7 f3 `( @1 b5 w& U* h
        // 11:FME7
: e4 ]8 B, O3 A4 H0 q, U' V        INT        vol[24];
0 H" r9 U, d# K* ^% F        BOOL*        bMute = m_bMute;' i; l8 Z  S( o" U; D
        SHORT*        nVolume = Config.sound.nVolume;
" p9 N$ P$ n4 I2 H2 w& M- w
2 L  @- L2 U% X        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
" ^' g' c7 \5 \+ j7 f* Y
) R; D$ k  Y: e2 b* u/ n4 W. l        // Internal
5 `% `& x% V! m; l: |        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
7 Y2 G9 V) I5 o% `2 }+ X: U        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;! [- J  I6 a7 z3 e! U8 H# J% d
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;: w1 A* k6 b& l
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;( B: [- {+ G: z3 D
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
8 ^* Z# ?3 W+ Q: I/ p! F$ v/ ~3 @2 G: D
        // VRC6# G- Y1 D* @0 n  ~9 M
        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;( B& g7 W+ r8 M2 x
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
- i8 D, n% [- ]7 }        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;: |. o$ Z, Q2 n$ L' t1 R+ e2 p4 P
) Q6 d6 e! x( r2 {9 M: [
        // VRC7
3 G) h' C9 p1 M' j. P& m        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;! R8 d) z: W- A
( M+ O# t" U+ p# d  J
        // FDS4 Q0 j' m" c3 S1 B5 L& D6 k
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
( F" @( ?1 Z1 d4 v" `5 M9 G% A/ o3 _+ I
        // MMC5+ `, a) f% f' j  L' |* A
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
8 J5 q: {  X6 k2 h2 Q* e        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
# `" [, p' ^1 q3 D8 X6 `1 I        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
$ s$ b* H, ^$ T" t1 ~% o' ?1 R7 n0 A) w0 q
        // N106
1 d. Z3 c( ^# A2 L- w9 l        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
, u' ?! r) a/ h( B, `9 n        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
0 O& U  t( d  f1 ~& P4 U        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;8 m" o, {; b$ d$ H# }/ d
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;* J" ~0 V, ?$ |  \" C8 ~, w! g5 N
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;# o" G" u9 i  W# B
        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;' D0 P+ ^! c: M. m
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
1 g; j! ~, v  t! O7 H; E        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;) b% K. x2 n' H( ?# Q- T

2 h7 @; ]+ u- I" m- P0 B6 |        // FME7
+ {0 z. T* f2 n) g* H        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;7 l' P1 R) q% K
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
( g% J. s% o& B- K4 X        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
& S( B, q8 t' V* ]! t& X
4 S! h. M. [5 U, A  N3 _//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
/ k" s: n) X+ d, F, H7 \- @        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
5 x  O- j3 L: k1 Q' k8 Q8 _! c- V4 n
        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
' ?, q# s  |+ p        if( elapsed_time > nes->cpu->GetTotalCycles() ) {+ t2 u3 U. c; g8 p8 p
                QueueFlush();
# [, `& w1 @) k2 g% \8 c- s        }
  Y7 Y7 N. W" T2 a2 z. e; y! J
4 n4 X  c( ?+ O$ a# L0 h7 H        while( dwLength-- ) {
- {  M8 m9 E  V                writetime = (DWORD)elapsed_time;$ h( K$ A! i1 i3 i9 E& C

1 l- Z  x! X6 u  W; g# F% U+ |                while( GetQueue( writetime, q ) ) {
& Y& [2 x4 K2 p, H! W2 m                        WriteProcess( q.addr, q.data );
- Z1 {6 a- I8 h$ \" g& N                }
8 A% B( h' L+ e/ c* C+ k$ t2 w
. }8 P+ p" |  F0 J6 X: x                while( GetExQueue( writetime, q ) ) {$ f; C- C. K  g/ c2 _2 S: \& q
                        WriteExProcess( q.addr, q.data );
  e  \0 f3 b  O  W" I( l- {, A                }
% P5 R6 [  M3 h- G2 S* e' m" b1 m2 E% ^5 Y/ ~
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7; C: v, Z+ \, @6 }6 o
                output = 0;  Q2 R- c. g' I
                output += internal.Process( 0 )*vol[0];( f" d) f* c" C, E2 g+ l5 K9 h& y
                output += internal.Process( 1 )*vol[1];, }" V5 U6 F- T0 {
                output += internal.Process( 2 )*vol[2];
2 e& Q$ G2 z, O* v( \: I/ L9 a+ p2 ^                output += internal.Process( 3 )*vol[3];7 A6 c: `6 B1 \  s* g" F' v1 W
                output += internal.Process( 4 )*vol[4];$ o9 q, r4 L4 F6 L
' \8 {: E) I+ X7 Q0 |- B9 @
                if( exsound_select & 0x01 ) {. B* o+ o$ Y( B1 x
                        output += vrc6.Process( 0 )*vol[5];
; X2 L4 G# W: a                        output += vrc6.Process( 1 )*vol[6];
9 x6 o3 `: r6 O. j                        output += vrc6.Process( 2 )*vol[7];" p6 l* d5 P) q7 Y" G- K7 g7 f
                }3 s" d4 N, S* B
                if( exsound_select & 0x02 ) {. }! B' M: w- b7 s  |, z7 n
                        output += vrc7.Process( 0 )*vol[8];
! f$ o  N# N9 U+ T0 S, ^+ |6 T                }! T  T0 U+ A) u' x
                if( exsound_select & 0x04 ) {
3 ?2 M2 b; K! j: F: {8 I                        output += fds.Process( 0 )*vol[9];
$ n) a! @+ `5 k8 {# P. t                }# t; B* ]: L2 A  O4 N
                if( exsound_select & 0x08 ) {
' p2 k+ O( K) T4 J7 Q- i                        output += mmc5.Process( 0 )*vol[10];
* @# q2 B% \/ {4 j/ S                        output += mmc5.Process( 1 )*vol[11];
0 @1 n! k5 M4 \' p6 z7 h* i                        output += mmc5.Process( 2 )*vol[12];
  h  g6 s% K9 `* T* T  ]# a                }
! y: K3 L1 Y% L: G+ o                if( exsound_select & 0x10 ) {
4 X+ [0 r( B0 e4 D                        output += n106.Process( 0 )*vol[13];
! j. g! l& I# e/ Q! b: F! ^# u                        output += n106.Process( 1 )*vol[14];
" I/ |8 R- \) U                        output += n106.Process( 2 )*vol[15];
6 P9 |1 y7 X4 p. c) [- X, W. f                        output += n106.Process( 3 )*vol[16];$ Z4 s) O$ p9 a4 c% Q0 `
                        output += n106.Process( 4 )*vol[17];
3 b/ Z2 O# j) s; P5 j                        output += n106.Process( 5 )*vol[18];, _. f  n! c) C7 ]+ u
                        output += n106.Process( 6 )*vol[19];
/ z; B$ `2 s8 Z% a                        output += n106.Process( 7 )*vol[20];
4 b1 _# y: _6 O: C) K                }
  h- ?/ G$ }# ?. B4 b, A                if( exsound_select & 0x20 ) {; A& T  H" d; J2 n7 G( T5 r# ?
                        fme7.Process( 3 );        // Envelope & Noise& ^( @7 s; H$ I8 k$ `; R
                        output += fme7.Process( 0 )*vol[21];
3 i( {1 p" z0 q                        output += fme7.Process( 1 )*vol[22];
3 g* {( U  i. Q' a                        output += fme7.Process( 2 )*vol[23];
# ?  }: c1 D- L' K                }
) X0 l/ b  J1 u$ I% j; [: s1 v
! r1 w# e  |: O                output >>= 8;
4 m  l' r) h& u! ~: V
: M2 Y% y8 ]4 T/ H                if( nFilterType == 1 ) {
) Y# Q; K: X8 r4 i* g( x& b                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)% O6 \  v! o/ |  e1 v
                        output = (lowpass_filter[0]+output)/2;
( O5 O* T8 i- m3 E- x) w                        lowpass_filter[0] = output;- }) _: m: n: d1 [( r% k- E
                } else if( nFilterType == 2 ) {8 P1 w/ y9 M* J
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
9 x7 q" H- J! T8 e% W! m' t5 `                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
- @3 Q8 J+ L2 U# _! g- R9 ~                        lowpass_filter[1] = lowpass_filter[0];9 @- S; q: {3 Z# \) B  Y. S
                        lowpass_filter[0] = output;, ]6 b5 [' Y2 }5 {1 U
                } else if( nFilterType == 3 ) {
  p- n1 T" C/ I2 \7 [                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
, {2 N+ h( x4 {                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
& J2 m" z5 o! ~- x  D( _                        lowpass_filter[2] = lowpass_filter[1];
( F8 ]3 B0 G* A$ q6 G9 o8 f5 r. z                        lowpass_filter[1] = lowpass_filter[0];& d! ^$ J) P- [+ t
                        lowpass_filter[0] = output;
9 L* w4 X8 V& {0 M                } else if( nFilterType == 4 ) {
+ J8 T2 V/ ~: b2 y2 P/ a6 ^                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)- y, Q0 G4 C5 N; E( H+ K
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
7 P, {& ^, B8 r7 a/ t- q- J9 }2 S                        lowpass_filter[1] = lowpass_filter[0];
" L' z# E$ `& o1 H) e                        lowpass_filter[0] = output;/ Q/ v/ z- X" O' g4 X
                }8 R( N3 ?9 S3 n9 ?5 G5 [
% c9 H$ w/ x$ u5 ~, O1 w3 N# B# B: |
#if        0
8 `/ S. _  R. Q. Q8 g9 F* Q9 {                // DC惉暘偺僇僢僩
) i' o' |4 j# m$ O# a/ U& S                {
. t6 u% ^) [9 k/ z5 [* B5 P& }                static double ave = 0.0, max=0.0, min=0.0;- f$ z/ O3 C; Q8 ?
                double delta;; p7 [$ _3 y2 a+ P
                delta = (max-min)/32768.0;8 C# _! l* Z. V# {; \% g# X5 L
                max -= delta;2 @- z; Y) |6 y. q% x% Q
                min += delta;* R! C- m. H; S
                if( output > max ) max = output;1 \* j; g3 J" O. z9 ^) C
                if( output < min ) min = output;
& s& J; @" E# r2 s                ave -= ave/1024.0;
- o, U& P3 v0 F$ ?                ave += (max+min)/2048.0;
  |! i# W( h  W8 [$ ]0 P                output -= (INT)ave;( \/ E' k* j) e+ f2 P8 Q
                }- A" [! c/ p7 u$ X3 s7 @
#endif! A+ K9 O1 U3 A! ~- _. e, m
#if        1
) _1 Y3 u6 E3 L& C$ ^6 d: r& H+ j                // DC惉暘偺僇僢僩(HPF TEST)
$ Y0 k& O% q7 e; E& A( l: x                {
, z7 c3 y. J% P* Q//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);+ p1 ~, m( l3 w3 @( Y
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
1 C2 H8 N  Y: c. l6 R5 G                double        cutoff = cutofftemp/(double)Config.sound.nRate;
* C, M' p" ?5 e1 v$ T. W2 }: s+ F                static        double        tmp = 0.0;
# T4 a% J  r$ L) ]) s( v5 K                double        in, out;, t8 o; o# H% c8 D8 Y7 W
1 H& X3 J" G4 \& k6 Z- K
                in = (double)output;
% X% D) N% @1 }                out = (in - tmp);  u1 k: K$ t0 {
                tmp = tmp + cutoff * out;4 ^# L% o; \  n' F7 L' l

" M( i3 n8 \' m" P, C( \6 U                output = (INT)out;2 o7 b: p; m7 G9 ?* l
                }& {; _: h* h! b6 C% R6 B% C
#endif* u# N& h% o5 K5 z. B+ J
#if        08 j: ^! t9 F1 X/ E
                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)0 s  v3 m; U5 G4 M% Z
                {' ?# [6 t) }5 H( ]
                INT        diff = abs(output-last_data);
5 m, S0 R1 |7 X                if( diff > 0x4000 ) {5 p; @2 C& H3 D' [1 X# O0 o' m
                        output /= 4;6 {& ?" n8 f& p% q- s
                } else / [. S" R  R/ Z" |) e' Q+ n. ^8 ?
                if( diff > 0x3000 ) {8 T% T% z- H1 H9 K/ g! P
                        output /= 3;
6 W& C' R1 h# T: ^                } else
2 I& H, w( m$ U+ @* b                if( diff > 0x2000 ) {: T, G5 J; N( N) F5 c3 K4 A
                        output /= 2;  m6 z* V" E; r0 m; H& V( x$ Y! h+ V. i
                }
" y2 |+ R' W0 ~* X% D# R5 Y: Z                last_data = output;
& Z$ b2 U: S9 v% T                }
) L3 t; y1 M8 q$ N8 S, @#endif
* l4 H( G4 |4 B                // Limit
/ U, \2 }( [! n- @" `$ u                if( output > 0x7FFF ) {
; s* I) k- s) C. u- z5 B5 C                        output = 0x7FFF;
+ K" {7 R; T) c# U- ~5 j; K0 }                } else if( output < -0x8000 ) {; v7 {9 ^* K! \+ v) J
                        output = -0x8000;
, E( u. h0 J) e1 ?. Y; M                }& a. p" h: |! E* N2 u
) U+ _% e# y* t9 ], x9 C+ r
                if( nBits != 8 ) {& I/ N  x2 w( i: B. I2 W4 V
                        *(SHORT*)lpBuffer = (SHORT)output;; X. `5 H/ x! h  W
                        lpBuffer += sizeof(SHORT);
! K( h! L6 a7 _                } else {/ P* a+ Y* {/ C( a" G; E1 N0 i7 ?
                        *lpBuffer++ = (output>>8)^0x80;
: r+ m& [" A+ u# x                }* w6 x4 D/ g) z8 B

0 b: K; b9 D0 Z- K; [                if( nCcount < 0x0100 )* V9 I; s4 F  t! f. b
                        pSoundBuf[nCcount++] = (SHORT)output;
+ N* N1 x- G  m& T/ \- x! P& U) w+ n- Q$ W
//                elapsedtime += cycle_rate;3 k2 Z9 J5 ~# J) e3 ^* S
                elapsed_time += cycle_rate;
) U; }4 ?6 U7 x. c$ z! h( a6 _        }& x9 r) D) X3 j

# ^" v! L3 e3 w8 C* A#if        1* V! x. w1 J) i/ I2 m  A, J
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {+ G' v6 D( n) J# ~$ Q/ q6 ^( ^" W
                elapsed_time = nes->cpu->GetTotalCycles();: U! [& @/ D9 |- o6 h- ?8 @5 A
        }
" R6 `2 h/ g. I4 l        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {6 F( [! n; D. }5 q! h, V
                elapsed_time = nes->cpu->GetTotalCycles();: ~/ u: z% A* j: a  F0 q! B5 E
        }5 d; h6 r9 g9 ]( i0 c: @) v
#else
  `; V: o! ]. o: \3 \1 Y: z        elapsed_time = nes->cpu->GetTotalCycles();
( }; v- u; `6 X, H#endif% e7 l/ S9 x& x2 A* D: p
}: k& A# N0 f8 ]: _  y1 u7 S
" x' u7 ?; K8 x6 c
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)4 K1 v8 x1 A; R0 l( e
INT        APU::GetChannelFrequency( INT no )
3 f8 b9 i6 V9 A0 u3 Q{
7 Q: {" l1 D/ X' V4 t6 V7 N        if( !m_bMute[0] )
/ T, L' U! r# ^                return        0;
/ G- A) Y. z' y) }
( C; a( x. V3 C7 H5 r( b        // Internal( a, }  H0 C, u3 t2 p  R
        if( no < 5 ) {
8 f+ F- [+ x& y$ \9 Z) ]                return        m_bMute[no+1]?internal.GetFreq( no ):0;( P* a, @( K5 B! V
        }
5 D( {! K/ g+ ^1 B        // VRC6
* H( @7 N, z% b# }  v        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {( y5 T4 I: [- Q+ C# H6 a9 N
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;. R2 S: ^, }- Q4 ?1 }
        }
% K& m  f0 l" T$ _  G/ P        // FDS+ }% K3 b# ^0 A% n+ C
        if( (exsound_select & 0x04) && no == 0x300 ) {
# C$ O* s0 [( n6 B- U2 ?1 z                return        m_bMute[6]?fds.GetFreq( 0 ):0;( f4 o! K; Q- [: I8 j
        }& c$ L4 O1 j4 C1 W: ]9 u& f
        // MMC5  {3 |& ~1 Q+ j# l
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
" _8 \9 I9 Z  A" c. C- r/ s9 g                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;
2 v" q4 n. k! J" _        }- t! ?/ q! g  N8 T
        // N106( L/ B6 c4 I/ o) Y* g. u) k2 M
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {' `" d2 ]/ _) P- ~7 L5 D
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
8 c. e" R3 s1 j# M* P8 q! `* \        }
" N* {3 R# w# i1 g4 A0 I4 w5 P        // FME7
! N; Q# w' u( m$ \7 K        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
' ]( ~: F) I; d+ `: o- |' X3 n9 W                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;0 M* }) |8 Y# f4 d& ?+ k* ^8 ~% [
        }
1 e, |  L* h* d1 B8 t        // VRC7, e2 b6 f5 N& c+ h
        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {( p  m" v: h4 l4 d" i
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
& l$ I8 f% K. Q& m. V0 V3 G        }8 V# B) w* n8 r" h. G/ G7 ]
        return        0;/ z5 ^) U, ^& c' X- p
}
1 B; r  K, v  {) M( U$ b" o6 O7 h7 X4 K1 F
// State Save/Load/ I- u9 {5 p( o) ^
void        APU::SaveState( LPBYTE p )
( K/ [  x5 \; Z* V& ^: m/ Y6 `{5 ?" M2 H2 O# ~% M2 ^
#ifdef        _DEBUG
8 a: q4 n5 b1 J2 kLPBYTE        pold = p;* G9 [5 a+ ?$ q9 ]* L
#endif
: i4 k$ P; G% B: C. W: G8 J* o9 C
! D% g3 e9 f8 V# r9 t# K: S% B& b        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞5 n' N' z2 K! Z( [, j* w) f
        QueueFlush();
* w+ @$ Q. U# [4 V( p2 r5 P. I3 ~! J1 g- S# q+ `1 D
        internal.SaveState( p );, ^, T# l; h2 V5 \& V  W5 D9 X
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
/ f: ?1 e! c- O# M. Y2 P2 J3 A" l% d4 G5 O
        // VRC6
# q; F% }: I2 M1 g; B7 Y( Q: V        if( exsound_select & 0x01 ) {5 D# D9 A. [! I. a+ P8 |5 q
                vrc6.SaveState( p );
+ i+ j! x1 |: o6 K' \                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding: @6 J0 F) e8 g
        }- j; C+ ^% p2 m. _& k
        // VRC7 (not support)
* i7 b$ ]8 V% @- h* k6 P, }        if( exsound_select & 0x02 ) {
! r; i" g7 K, X+ |                vrc7.SaveState( p );& c/ t& |+ _& j+ S
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
& @# s3 }5 u  ^! \        }% X$ J5 {* |9 n, E7 J! l# W% O
        // FDS: d" @3 G" p# H" K0 C
        if( exsound_select & 0x04 ) {! |+ T) {* ^' V2 D+ D1 ?
                fds.SaveState( p );
! r  @# M5 i! x) Y- s: h0 T+ `                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
. L1 Y: |3 i9 p& T) p8 X. b) I6 b        }. o8 Z1 b, C0 P  H
        // MMC5
, s2 r/ q( H. l        if( exsound_select & 0x08 ) {* f# w! v- Z4 |0 U
                mmc5.SaveState( p );! l: p: X( n7 z
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
  r2 u, Y- v: A        }
. F6 A8 X: y" t. V) c( n# n        // N106
, H- u& `6 Y7 W2 i0 d7 X+ s2 Z7 Q; t" _        if( exsound_select & 0x10 ) {* N; D' @4 m( T" }& w
                n106.SaveState( p );9 j' o/ R( Z2 w' o$ H
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
0 c/ A& r) p. L1 I1 ]- W        }
) G" {3 p/ X9 @$ V, ?6 y7 l        // FME75 b4 H# A5 f+ {+ ^% O
        if( exsound_select & 0x20 ) {
+ ]/ o, e* |0 r) r+ e                fme7.SaveState( p );
; ]% Z6 W; Z$ C; p5 t8 W: w                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding- M. A) g9 q( M  l
        }# T$ G$ s- I: i( x" l* R0 J$ `
5 D) J1 ?! Y. L5 [" V3 M! a
#ifdef        _DEBUG
3 Q+ ^3 l9 m  X; nDEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
1 Q4 n% t. K- g. ^#endif! I! i3 @5 e, F& P2 P* h8 |
}
: Q+ V" R& \* N6 W6 p1 W0 h" l2 D1 F2 j: P* F) a; s+ [
void        APU::LoadState( LPBYTE p )' y. Q3 Y( E0 t: N, K* X
{
  n# Q( p8 }, R6 |* b        // 帪娫幉傪摨婜偝偣傞堊偵徚偡" ?) P' ^, @) u) w1 R- }
        QueueClear();, j( Z' }$ O. s8 k. h

$ N9 a0 s! }7 \/ W, u# E        internal.LoadState( p );7 P3 y+ P$ x# U; u" i
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
- F, `7 ]4 |5 f( d) h- M/ f3 Z, k/ H' p* N
        // VRC6
( t3 d" R- k1 d6 u        if( exsound_select & 0x01 ) {$ v: c2 J4 d7 E; {5 \
                vrc6.LoadState( p );
3 ^0 A3 h* v  b* h, H8 }$ U                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
! c1 t  c* f7 b        }8 h8 o  z) q# e. X$ R/ E
        // VRC7 (not support)% K- q6 Y, C; I: q) J% x+ ~% x8 N
        if( exsound_select & 0x02 ) {" P7 T. O! V% D, j4 @
                vrc7.LoadState( p );
& p4 r- H, u, f                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
) x0 ^3 e! O) c9 @* S        }+ d+ @4 {, r' P+ U) F- [
        // FDS' K6 @+ k2 C" G. p
        if( exsound_select & 0x04 ) {1 K) J" h3 Y0 e% R
                fds.LoadState( p );
4 M9 p4 m$ g& L0 a$ \                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
" c, g4 t. D4 d& \/ `& p* G        }! i* I8 R. U& ?" ^0 K7 q
        // MMC58 k! k3 A" \3 J0 B% O) R
        if( exsound_select & 0x08 ) {2 f* w$ r$ N" _  S  K
                mmc5.LoadState( p );
& d0 I$ j& A4 B7 r7 R4 h- d+ m4 \                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
- n7 F' \" ^9 n        }
+ y$ n" M+ v0 j1 Q5 O  g- ^        // N106
* p1 Q" d+ f2 Z! `# ]6 m) d        if( exsound_select & 0x10 ) {
/ P6 X4 t0 I+ u  _( Z                n106.LoadState( p );
* I, e. `, C5 q; k                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding5 {; d7 O1 p) p; K) n* h7 t
        }# V8 F; O0 j/ Y$ J, u5 L2 ?- W& D) ~
        // FME7" T" \/ Z2 W' w$ h2 v
        if( exsound_select & 0x20 ) {
9 j. P# c. x# x% T                fme7.LoadState( p );: ^2 u5 R) J" D0 D0 C  c: \% K
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding: g/ R  g4 j7 M
        }& m+ ~, S2 O5 s1 h( G  b/ i
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表
& E5 q  \! c2 t! E可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。: }( x. @; S, R  l  b: n
感激不尽~~
+ M/ v7 H4 y: n5 [6 x
恩 我對模擬器不是很有研究,
, Z! y$ ?3 a* |6 E3 t0 ^1 q; r雖然要了解源碼內容,可能不是很困難,
% ~/ g! w5 |" ~不過還是要花時間,個人目前蠻忙碌的。
: [' I; ~! X, I, e; ^
3 M7 x  T5 Y$ u; A給你一個朋友的MSN,你可以跟他討論看看,
1 U, _- Q) I# i2 W1 f: o0 B他本身是程式設計師,也對FC模擬器很有興趣。
& z" }: L' a  s" y# H$ V1 U/ L2 a
MSN我就PM到你的信箱了。) E& _1 {6 n6 P6 Q0 l
  S: Y8 v9 ?6 P3 [* n  s/ b
希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
9 p, F; o/ k# f呵…… 谢过团长大人~~

6 I$ _7 f0 ?" |# p6 e! S1 q0 \+ d
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
, _0 G& g" a) r! [团长的朋友都是神,那团长就是神的boss。

- N- J% f/ [% c* _! R哈 不敢當,我只是個平凡人,
; y# e7 z$ T' b3 N6 V# s5 A要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙
# B3 c, \  y, T7 EZYH: ^% k0 B( L  f
QQ:414734306+ u2 ?$ m$ F2 D9 L" g& r
Mail:zyh-01@126.com
9 T4 I. y4 ~' S# U# Q2 J" v7 g* }/ O$ H: v, K4 b
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 ( {7 r: e% k% j! a; i1 i
再次对团长大人和悠悠哥的无私帮助表示感谢~~
$ W- m& k$ x2 _4 R# X* q
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-10 17:25 , Processed in 1.094726 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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