EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。) ]0 ^1 w8 E( W+ m) O; w
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~/ j( a' h# M$ X- y; a' D: @
这里有相应的模拟器源码,就当送给大侠了~~
/ Q% E3 j, [, t, ohttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
- H6 b: y' W# i8 Q能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
; O4 b: V0 j6 H楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~
2 G# `* c" f# w' |, L这里有相应的模拟器源码,就当送给大侠 ...

6 L# ~& i) `; {! T+ i5 u聲音部分(Audoi Process Unit = APU):0 C( X, V. T2 n2 ]; {7 A
.\NES\APU.cpp! ]" C. S: g" V/ g
.\NES\APU.h5 l0 A1 ~0 U# y: v5 N: s1 P$ Y

( c% H! W& _! Z; \; u8 ]+ n
! U0 ?0 E* \2 r, |7 p" Y+ `' ?2 l影像處理部份(Picture Processing Unit = PPU):
. V% j/ N$ N% [; D" U.\NES\PPU.cpp% M4 P! S; E- d* e9 e+ t9 O2 F! G
.\NES\PPU.h
" C) n# t. k" L& X  r( a
' y! [$ k9 y7 J: k如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:+ c7 M3 E6 L1 k5 h0 l1 D
(由于很多专用术语和算法机理都不明白,所以看不大懂……)
! H. F7 s9 ~$ t//////////////////////////////////////////////////////////////////////////1 R2 d9 B, A4 l: D& H
//                                                                      //* I* g6 d4 d% i; J3 I& `% \
//      NES APU core                                                    //
2 J6 P7 N) l$ ^( R8 c5 z//                                                           Norix      //) f! y7 |' H* V9 V# y- t# Q
//                                               written     2002/06/27 //
1 @9 p! a  o$ P; f2 J//                                               last modify ----/--/-- //
" A. R1 H3 ^! g! o3 r& [& }//////////////////////////////////////////////////////////////////////////- H0 O  u# Z' y- P( E* `6 Y
#include "DebugOut.h"5 Q$ ]8 Y. a5 }9 C8 |
#include "App.h"9 k' z# M9 X" f8 o
#include "Config.h"
0 d0 D3 J. |$ i, y* d4 u
5 _9 X0 A1 A- w! W1 Y0 m#include "nes.h"% c0 N; ^; `) n/ f( O* Y- N% L" R
#include "mmu.h"* h' r: Q4 t7 q4 [3 V: H
#include "cpu.h": P. \2 z9 `$ B, F
#include "ppu.h"
1 Z) R6 i2 }4 d9 ]#include "rom.h"0 Z; g) y2 k. G
#include "apu.h"7 n8 w% F2 v8 T2 r1 T7 R( B) W

- }& Z$ O3 T5 [# [) `1 }// Volume adjust
5 @- U" w2 a! C- q' {8 d// Internal sounds
' E9 F% L: ]$ s# @2 }, A#define        RECTANGLE_VOL        (0x0F0)
7 H# ?8 p# ^+ v. y7 z5 Q#define        TRIANGLE_VOL        (0x130)
$ e1 f) }9 ~8 \% ^% Y#define        NOISE_VOL        (0x0C0)" F8 L5 a5 r# v' o
#define        DPCM_VOL        (0x0F0)
1 k6 q0 T5 G6 i7 r// Extra sounds8 F0 K6 t# A  n
#define        VRC6_VOL        (0x0F0)
3 E1 \% W: E: D, S' A9 t; `: b#define        VRC7_VOL        (0x130)6 {6 M1 [/ C+ V" c, f" M
#define        FDS_VOL                (0x0F0)( v$ w5 ~  l" ^4 Q
#define        MMC5_VOL        (0x0F0)
+ n' \" x: P/ x#define        N106_VOL        (0x088)
- @$ S( x' |6 _; ^#define        FME7_VOL        (0x130)2 I# Y: {; c+ L5 h

; x+ f; R) W  M/ o+ iAPU::APU( NES* parent )
3 E' _1 ]' M+ K* G. S% c{
/ U6 f- ^& F2 G        exsound_select = 0;
4 T; n/ z1 x* Q% z$ i' c
  `6 J" }- ?$ r7 ~; G( Z        nes = parent;
6 b' U4 `# Y# @4 e: s% s0 _        internal.SetParent( parent );  r  @% Z0 d. e* j5 ?% d

5 Z  q, k3 |7 g  g        last_data = last_diff = 0;7 a" m8 m* d7 q  F6 s. q

4 G3 s& u, D/ ], J/ j5 x        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );
2 l, m3 I% |" L9 |0 h& n  i$ B  s3 y5 N: `2 Z0 P9 y
        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
" f) W. M/ G" J1 ]  S        ZEROMEMORY( &queue, sizeof(queue) );3 |$ Y/ Z& x, M7 r& k' ?3 o
        ZEROMEMORY( &exqueue, sizeof(exqueue) );& V- T5 K- z1 D; ~8 r& q6 m
/ t# l2 i6 ]& v" h4 `) ?) k
        for( INT i = 0; i < 16; i++ ) {8 G* u/ ~1 D+ X2 p
                m_bMute = TRUE;0 ?& H, x4 n" ^) h4 K& s! w/ J
        }- i  z: U4 N0 a4 M! g3 Y
}
# N0 o. U7 r; }& V/ W  V5 b  t
" \( t3 O- y7 S7 aAPU::~APU()+ B* I) d  y. _. W7 ]
{
& H  e# [: B2 {: A}
( {$ O3 k3 |( M9 @) |  t
1 ~8 g) r' s$ f0 l6 qvoid        APU::SetQueue( INT writetime, WORD addr, BYTE data )& _! I/ p1 E0 v, r
{
$ s) S& }8 Y5 R& Y# D6 t        queue.data[queue.wrptr].time = writetime;0 B7 Q' n* ]4 @4 `
        queue.data[queue.wrptr].addr = addr;: T: W5 u. T! Y3 {
        queue.data[queue.wrptr].data = data;
% R4 N8 c$ D' n1 j. m) ~' u        queue.wrptr++;
. f3 S1 @% T* K1 H        queue.wrptr&=QUEUE_LENGTH-1;
6 ?2 w2 i2 g% O; b& N- R        if( queue.wrptr == queue.rdptr ) {
  o7 I' O: X9 W9 d0 E' N+ D                DEBUGOUT( "queue overflow.\n" );, L1 K2 x5 t+ ~
        }1 X* h+ d9 W, H2 J0 ~8 \9 e# Q1 ^
}
  R$ R5 |: T5 w& M; G& b# ~
7 a1 d: X9 |8 b. WBOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
" ~! z) u+ l  H5 s* e& \2 L{
$ Z+ A) y; h+ u        if( queue.wrptr == queue.rdptr ) {* R; @, X$ w8 u" Q
                return        FALSE;
5 `  \5 M1 N5 P+ e7 I6 N        }7 j7 [) R0 j- E( w8 Z$ c
        if( queue.data[queue.rdptr].time <= writetime ) {9 f. v+ u6 Y+ h' V  a
                ret = queue.data[queue.rdptr];$ f; u( w% ]. K, _1 b8 e% F
                queue.rdptr++;  n5 ?9 q1 G* J0 P. N
                queue.rdptr&=QUEUE_LENGTH-1;
; U0 Y9 s: P% P" O                return        TRUE;( M$ F6 F. S0 Z; O
        }: d! K! n* h) m
        return        FALSE;  `/ I8 ^' R: H7 m
}
: ?3 \: Z% l) |7 ^4 d/ \2 o4 t+ a$ d4 w
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )% i" j# w" P$ }4 D
{! ?6 H$ Y& l6 J- [* O4 }& X5 }: }
        exqueue.data[exqueue.wrptr].time = writetime;) q& A6 ~9 B/ G0 J
        exqueue.data[exqueue.wrptr].addr = addr;
) y7 E" X9 n; p$ S3 c4 N        exqueue.data[exqueue.wrptr].data = data;
- _7 e, Y" ]; e9 Y        exqueue.wrptr++;
4 D# ]% t: E  j        exqueue.wrptr&=QUEUE_LENGTH-1;
# X- {9 [. s/ p- Z        if( exqueue.wrptr == exqueue.rdptr ) {
( }* X! }5 z) \# q# {9 ]9 q                DEBUGOUT( "exqueue overflow.\n" );- B  |8 }9 H  ?8 E5 h- L6 T* [
        }
0 Z# S6 z, i" Y4 ^" W1 _( ^% J}" D2 D; r) O: J3 r/ n

5 h) a5 Y' L0 a3 u; |BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )# n7 B- n0 x$ ~+ K6 q
{
, Z1 ^) [5 X' j+ a# q        if( exqueue.wrptr == exqueue.rdptr ) {
4 y; g$ Y( F7 ]2 K5 u- h                return        FALSE;1 U/ _) p, L( {: T' F
        }
" Q& e6 c1 x: r' y        if( exqueue.data[exqueue.rdptr].time <= writetime ) {
* V- l. ]: r5 J, [9 z                ret = exqueue.data[exqueue.rdptr];
" F+ v2 O4 C  p/ i1 Q                exqueue.rdptr++;# [7 W' r; C. \! U0 m+ y- M7 b
                exqueue.rdptr&=QUEUE_LENGTH-1;( ^. Z9 }$ h( w: B2 L
                return        TRUE;
  C- c5 I9 ~+ d3 E- u0 z0 N5 f4 t9 n        }* t  f+ G4 r0 {1 r' @
        return        FALSE;
$ U- t; f& b" W! k  t+ A  B}2 n& a: ?! S6 e- w
' u/ v" ]5 {3 g6 \5 a: z) Z
void        APU::QueueClear()
& f& u3 g8 F: X* Z. S; w+ S{
* L7 d; O9 Q5 Y* y! n8 [8 ~        ZEROMEMORY( &queue, sizeof(queue) );
! k' {6 T( L! X8 r        ZEROMEMORY( &exqueue, sizeof(exqueue) );
) O, S4 W; ^4 V5 j}/ G0 D: M$ l' A  j0 \
4 b6 B# o  i  i# f/ V" ^
void        APU::QueueFlush()
3 d& f+ s, a, t5 d' g8 |$ @{$ U* V* A' ^. _! j4 D
        while( queue.wrptr != queue.rdptr ) {: }5 N0 q! z: F1 q6 y& ~
                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );
2 a# f$ H  [$ c/ t( R" ^- E. q                queue.rdptr++;
5 A4 S8 s" P6 b7 g: O, X                queue.rdptr&=QUEUE_LENGTH-1;& O: x& @5 d) w3 t
        }& F4 k! f7 X+ B) u

- [( }; B) j! c! W' f        while( exqueue.wrptr != exqueue.rdptr ) {
/ U' q0 t. x6 x0 c% Y: n* v/ r                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );' Q/ _8 g" \, w7 z# n: O# P/ b7 a
                exqueue.rdptr++;# g1 j5 X$ A) b
                exqueue.rdptr&=QUEUE_LENGTH-1;
& z# @8 C$ B0 o% U4 W" o        }3 K# @, |7 \- O' ^2 I
}
1 H' ?+ O0 ?% x2 I: e
6 i) g5 P( @7 x1 g8 Bvoid        APU::SoundSetup()
+ Y2 h- a- n/ d$ X' M' a{
9 p( ^* W3 r+ d3 W        FLOAT        fClock = nes->nescfg->CpuClock;1 v# K; [! P$ ^! Y) K
        INT        nRate = (INT)Config.sound.nRate;
  m2 `5 j9 A4 H) U- {        internal.Setup( fClock, nRate );: R. Y2 l5 h7 t; x
        vrc6.Setup( fClock, nRate );$ S2 B, g  ]* ^* K5 R+ T0 ?
        vrc7.Setup( fClock, nRate );" L+ o6 \1 D, Z  l; j
        mmc5.Setup( fClock, nRate );
% k8 o* \+ K% d( q        fds.Setup ( fClock, nRate );* b: L0 x* o$ H7 s3 h
        n106.Setup( fClock, nRate );
6 ?; I) {% O; m! E        fme7.Setup( fClock, nRate );
3 `1 E8 A  I1 p0 n}
% e; ~1 [7 L' Y3 j( u! _2 j
7 B! h" q/ j* G$ b, [void        APU::Reset()
1 P5 R- g3 Y5 Y& S6 A4 n{! R1 U3 m+ T( P0 |1 R+ K
        ZEROMEMORY( &queue, sizeof(queue) );
3 s8 t+ v# S$ _$ w. h9 B        ZEROMEMORY( &exqueue, sizeof(exqueue) );
0 d3 w8 `; [# p, A
: a& o' q- E2 S1 ~0 }) Y" {        elapsed_time = 0;
* ]4 v) S( D& p8 X. a, ]5 G0 y" c& _* c* R' I% {- {
        FLOAT        fClock = nes->nescfg->CpuClock;
* F8 a1 H: S' g' R( F  g3 s        INT        nRate = (INT)Config.sound.nRate;
) j2 m( B7 T9 P2 h. A  l        internal.Reset( fClock, nRate );% P! O/ U1 @* B  y* A" S
        vrc6.Reset( fClock, nRate );
3 W$ n8 X2 @5 ]! M. q- [2 ~2 N        vrc7.Reset( fClock, nRate );$ ^7 e, S7 s& @  v7 v& T3 w
        mmc5.Reset( fClock, nRate );, {) i( g" f$ [8 e' @" J% y! H9 \
        fds.Reset ( fClock, nRate );
3 Y$ o- _+ x- I        n106.Reset( fClock, nRate );" E( a5 w2 V- V4 j$ i3 {8 u
        fme7.Reset( fClock, nRate );9 ^5 T9 q# U& E# h; ?9 ?$ B* F7 q8 {

6 M; h' t6 d! _% c6 B9 g& R; ?        SoundSetup();! {$ w- c9 _( W, q- c
}- V0 D7 |, g* c/ X$ x4 g: g
. b; g; e9 s& f& c% g
void        APU::SelectExSound( BYTE data )
' L) e9 Z  a: k9 J. I& c0 L{4 B$ g, N2 ?' j5 j+ n
        exsound_select = data;" B, r6 H/ h3 j0 @
}
' e- ~/ T  O# O' ~) K( p* ^
. E& q! ]2 Z' Z! [! N5 j6 \BYTE        APU::Read( WORD addr )
+ g( E" X/ D7 x{5 V1 k. j- L9 B6 b8 b& Q" E
        return        internal.SyncRead( addr );4 }- R- M; l+ e6 A, N
}& P) a  X( e0 L: n6 z& a

  b. V: b8 A2 b5 _0 u  {void        APU::Write( WORD addr, BYTE data )6 X- ]- X+ i; Q8 `
{
$ g2 p, n3 {3 r2 V5 n  w" h8 A        // $4018偼VirtuaNES屌桳億乕僩$ a: Y: C; ~- k3 i$ }6 {( e
        if( addr >= 0x4000 && addr <= 0x401F ) {
* z- C) B, j2 p8 q# h- t, j                internal.SyncWrite( addr, data );0 Z1 u1 m( c# N+ m. L+ Y, T
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );: v- b' ?; }% V8 T5 ~- ]. z
        }1 O) ^+ ^& z0 w3 P0 m
}
4 e( h' g1 i+ g! s+ k; ~$ _+ T8 H
BYTE        APU::ExRead( WORD addr ): R' K7 V& |& e$ K* V; `: s# b" X
{1 p6 l; j" x+ c- @! s6 S5 k
BYTE        data = 0;6 t/ ^- I/ d) `9 c7 L
  X2 r' `4 v& T3 @
        if( exsound_select & 0x10 ) {
" W1 z9 F' ?* p+ o                if( addr == 0x4800 ) {0 w, Z; P3 {# [* q/ R
                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );
% `9 H0 R) a  Z: z3 L' R5 k                }
- t  s& u% r" v' r1 ~$ h: W/ l        }$ R. S- c- ~/ M2 P
        if( exsound_select & 0x04 ) {
: ]2 X" s$ n) Y# l                if( addr >= 0x4040 && addr < 0x4100 ) {
0 Q7 D( I& p& \- j/ g* v                        data = fds.SyncRead( addr );: W6 o) O3 ~% g6 o2 c
                }- I( F- z7 C$ a! i: Q
        }' v! P. Y2 R+ B+ d- ?2 @
        if( exsound_select & 0x08 ) {
) I4 _- h) P; `. W! w- c                if( addr >= 0x5000 && addr <= 0x5015 ) {1 w7 A& {" E$ ~) j, L! m: ~1 ]* y
                        data = mmc5.SyncRead( addr );
5 S3 |# q6 u% y- r. v3 k' i# m                }6 \2 l% f/ n- u& \
        }! P1 G& ~5 i0 ]' \3 J; b

% V* S) o! S( U8 c% z! W        return        data;
  E! E; P; f7 H2 t% z}6 D- b/ F- O0 V+ w4 y1 Q
+ D7 N* I( t5 p2 {
void        APU::ExWrite( WORD addr, BYTE data )' C% Z9 @8 j2 V7 U- b( C0 y. t
{* g# i. r' [0 Q* d8 E4 t
        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );) Y# a7 d$ W! Z7 L0 o( P" M
- w: s' s7 p' Q- l+ |5 V( ^
        if( exsound_select & 0x04 ) {% y9 h2 |7 k! {* }
                if( addr >= 0x4040 && addr < 0x4100 ) {3 I; u0 o' c* ]8 \. \; O
                        fds.SyncWrite( addr, data );' D/ D7 c. o. ~' m- _! q
                }
' W- N5 Z) S) ]4 u: ?- B        }
! T3 w. }  F/ U* W/ x8 P9 [6 V) i4 X* o3 T- U, u
        if( exsound_select & 0x08 ) {
6 N# h) n% {* k, q% [* O1 X* ]$ ?                if( addr >= 0x5000 && addr <= 0x5015 ) {" s+ d3 e" g5 p
                        mmc5.SyncWrite( addr, data );$ \4 I) ]6 _7 o+ d5 ]
                }4 s9 o0 O, p, C! N* |3 L
        }  o4 ]# p! {; H/ F2 @! q
}0 ^8 M! m' N: @; H

4 U" T, }- y' S; p: l7 M5 I; @void        APU::Sync()
2 ~  D* z8 z. Q6 k5 L+ L' J{
; r6 _( ~* z+ s! A}
2 X# O. Z' ^7 b8 f" B5 K. C( m  Q# h/ P
5 D" `8 E" N7 mvoid        APU::SyncDPCM( INT cycles )
  m0 X# n. D, F% w. M' p9 Y6 u* i{; R4 E& P% y: _
        internal.Sync( cycles );+ ?3 K5 d3 w7 p  l

2 a* q- C. x$ C6 |5 u9 v$ ~        if( exsound_select & 0x04 ) {
9 |( c( a) l( ?" D$ f* E8 }' `                fds.Sync( cycles );
4 h# o, S. B+ B4 r1 T        }, l6 K4 e! s" |( q# U# w; U/ Q
        if( exsound_select & 0x08 ) {
! N. n( P" b5 M                mmc5.Sync( cycles );
, i- x2 d' d3 v4 z        }
& o& O+ E: g( H; J4 G}
1 A8 y( n+ x5 b) p& g) _. S6 u$ L1 G% I$ ?* I
void        APU::WriteProcess( WORD addr, BYTE data )/ Z# b$ C1 q4 R9 c* T# l
{
1 Q7 e6 l8 ^/ t# @! ?: r        // $4018偼VirtuaNES屌桳億乕僩
2 G4 K5 ?0 y7 m        if( addr >= 0x4000 && addr <= 0x401F ) {) |9 {1 ]; V! j
                internal.Write( addr, data );$ z' P) {" q( G; E2 p( Y) x, {
        }
* g; a9 c3 n9 t' H}& i1 ~- d4 I, }9 \6 d) [7 p5 D
. D/ `! V, {6 @$ j3 `$ r% W, c
void        APU::WriteExProcess( WORD addr, BYTE data )" H" X, J8 S, i; q3 R% l" E! r
{
/ h0 s+ V; f; L3 @        if( exsound_select & 0x01 ) {" B8 q* ^- l+ S- X9 k" ^( f
                vrc6.Write( addr, data );
" V& V9 o/ K  H& p/ A0 Q6 G' u/ ~        }# h' W: M$ m2 {5 G, M
        if( exsound_select & 0x02 ) {
) E& {3 Z3 I: }( F                vrc7.Write( addr, data );
5 M6 @/ o: W! G4 }4 |! t+ R        }
* F) w# W, t" Z6 J8 Y" X+ i        if( exsound_select & 0x04 ) {1 l8 T5 I' W! I* r. V3 N& U
                fds.Write( addr, data );7 M4 ?* @; N, X9 E  _( D
        }
( @( G* u, U  p+ Q        if( exsound_select & 0x08 ) {$ Z+ X* @  Z, Q5 v
                mmc5.Write( addr, data );
" Z# w, D$ L8 e( b1 N: f% X% o        }
' E. l' ?; W2 ?3 z  G$ c  J- g        if( exsound_select & 0x10 ) {' R4 x+ C3 J: c8 d
                if( addr == 0x0000 ) {
+ D* v% m. h) }0 y! h2 u1 G' W                        BYTE        dummy = n106.Read( addr );5 G! j/ W4 k1 ?) J2 O* C; l
                } else {
& a% l7 v8 q$ z/ x/ [                        n106.Write( addr, data );2 Z% t3 M1 I+ B. e2 B* u
                }2 b" i4 n- u, L, {( G* G
        }4 \2 A; w0 C: m( w2 q; J
        if( exsound_select & 0x20 ) {! b7 z$ m% M7 u5 V
                fme7.Write( addr, data );
  S2 y$ [' F  `/ Q" p( f+ ^        }
( g  N4 S1 P4 P- Q}1 T( V2 a& _0 v( O

, A) x+ B! ^- {% l- i, ovoid        APU::Process( LPBYTE lpBuffer, DWORD dwSize )3 G2 p9 O. U8 r$ C7 h
{
( J1 \1 X; }. W8 uINT        nBits = Config.sound.nBits;8 a1 n7 a0 R: ]' t$ p: I! R2 [1 d
DWORD        dwLength = dwSize / (nBits/8);
0 e. l( B0 m( e; gINT        output;4 ~- q) i) S- i9 ]# H3 H
QUEUEDATA q;9 b1 L9 [" T9 g# @
DWORD        writetime;5 M$ q$ U& S$ }. V
( d& Z* p5 t5 o7 u6 K6 y# o# b: \
LPSHORT        pSoundBuf = m_SoundBuffer;
  o+ r9 Y9 F8 Q8 QINT        nCcount = 0;# R1 R" c, {$ [

; q/ k! [  M( F9 C; J8 R1 FINT        nFilterType = Config.sound.nFilterType;
" Q2 b# x. L, l! w0 W& X
1 H- @6 T+ ~7 I+ j# s        if( !Config.sound.bEnable ) {
$ K% v! r  `" c* t7 R) N                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );
2 E  A7 [8 h5 _) M- O' ^                return;: I! J2 @% t) C; u
        }
9 @  P% m  _  @  I) C
/ a$ O0 a" ^, Z+ o; H  x1 y        // Volume setup
; G. M! p! M/ {  ^, A1 ~8 J        //  0:Master1 S: Y! a5 g% {
        //  1:Rectangle 13 o2 t% }4 `6 k! j. M* c7 t; z
        //  2:Rectangle 2; n( a/ D; ~# x
        //  3:Triangle
# i" g7 P$ x# J- q; e. s- p1 I        //  4:Noise
; L, i$ l! o: p/ i9 C        //  5:DPCM
2 d% Y# |7 Z% u% C. k2 C+ Q/ L        //  6:VRC6: _! |% B  R3 |' C* l$ P" e
        //  7:VRC7* m1 J; q. a8 L; [* Y, B
        //  8:FDS
, D. Z" W2 {4 p1 y% T2 a$ G# a        //  9:MMC5% C: Z$ @. H( y& r' K9 _
        // 10:N106/ P1 i' T5 S2 N* q  @8 x9 }
        // 11:FME7
1 ?, t" h# W4 j, p        INT        vol[24];
; j; f& U5 U: F        BOOL*        bMute = m_bMute;
" b6 m5 c$ [7 t0 a+ J8 F        SHORT*        nVolume = Config.sound.nVolume;
# P- `0 ?! x* E$ o
* R/ A: N' M8 T  d        INT        nMasterVolume = bMute[0]?nVolume[0]:0;9 y- J& P, m7 P9 A4 K

* Z' R) Q- w5 l% g+ [+ @. ^2 G2 |7 B        // Internal
; K4 I+ e9 x- \6 Y9 M7 W5 F        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;
. c! _0 O& y0 H        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;
5 {% Q5 w: A+ d9 Q0 j' k        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;& d, K$ H9 B7 z1 q! g' A* Y* P
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;% y7 m8 L# @% c% ~, ^
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
) o5 O/ A7 X* w4 q* D8 e( G. o; W: d* C2 a; M3 ?
        // VRC6
2 j8 S( p7 v9 ?5 X  j* a/ g" f1 P; s# W        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
) |0 B4 }4 v  ]) {* a$ Z        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
3 j. g, t8 P5 V! V* ]/ S% E        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
( U9 O! n% o5 ?' M" w2 N/ {5 a
! D5 I# Y& ^5 o8 C        // VRC7
- C8 v4 f' o; a  {& {, ]* W        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;3 C' Z# P4 G% L" N  s1 g
2 V0 O- W% {- T/ F  d* L3 ^9 p' Q
        // FDS' v* K9 C0 r' t1 \; u
        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
& R3 u* L" f$ ^, Y/ K; N+ C  ]  Q3 r2 g: f- D
        // MMC5
+ v0 \& F& v! Z9 ], ?2 }        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
: L! l  f* S6 x3 [        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
7 ~( k& P3 b; ]6 Q; h        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
" g5 h% v  H$ V  N" S& L3 b, u# q9 ]% M/ ?4 {  B1 U
        // N1060 ?0 J* v- N; A5 D
        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;3 V' i4 ]# [2 e1 y) e
        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;: i3 {4 v0 D( W2 ~+ O
        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;+ \( M! e1 U" s. K: a
        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;, N/ w* {1 {% F
        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
& W2 k1 o4 [# m4 C4 i  [        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;: D3 P8 K/ `# A) O
        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;4 `" F+ R8 d5 W1 u
        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
% k1 t6 S% ^: ]& L! [2 u/ |& I
* G7 G0 J2 q# |9 D$ V        // FME7! L/ e3 A: q, S: i6 I7 u* R& i% J
        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
! S5 {6 m( k/ W( n# ]        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
6 J) F. E2 ~. z% W        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
* {3 e" Q" ^. p$ O2 q5 [. {
/ n( s: G$ H2 h' I% v/ T//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;1 L. i4 X4 H) [; s$ K! U( I
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
3 i' G$ n$ D0 b4 i; L& D7 s' y
/ q  X0 e3 {4 @        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟( w; M9 R- A3 B) P" M; s; h
        if( elapsed_time > nes->cpu->GetTotalCycles() ) {8 E( H, U. _1 b% X
                QueueFlush();
- d. ]/ g3 E$ G& o4 @2 J        }
7 a$ H* A) x  k
' ^, m# h9 d0 E" A        while( dwLength-- ) {0 @5 @: S  u  O' P) c8 A- b2 _
                writetime = (DWORD)elapsed_time;8 a, O, L3 [) @$ O  z' z

/ t8 s4 @: F8 d1 f4 u0 H                while( GetQueue( writetime, q ) ) {3 b" d* V2 J3 h7 D+ e
                        WriteProcess( q.addr, q.data );
7 b( f' n% ]+ O# y2 B                }
6 l# C8 C% T+ J' m1 p, q
* f4 S+ t* X9 o* S/ H, k6 f                while( GetExQueue( writetime, q ) ) {4 W+ {/ |# b& l8 N
                        WriteExProcess( q.addr, q.data );
+ Q5 G/ y; _$ o, ]' H8 w! Z: k  k                }# Q' W6 L2 k1 S7 X  s! J' ^& |- H

/ _$ H2 q4 Q) Q) g# T- q                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME76 ~& A# z- M# G2 g) B0 h. Z
                output = 0;
) [1 B. `8 ^& `( j) O                output += internal.Process( 0 )*vol[0];
! f+ \5 e' u8 y- x; [                output += internal.Process( 1 )*vol[1];0 g  r( P  P+ x% g
                output += internal.Process( 2 )*vol[2];
4 s& ^' O* M6 O4 t                output += internal.Process( 3 )*vol[3];# o, u  s! ~! f6 W  B
                output += internal.Process( 4 )*vol[4];3 Q9 b# F4 T9 {2 ]! ^- J5 @

+ Q- H8 C$ Y, w! R                if( exsound_select & 0x01 ) {
8 E0 |( S. o0 K0 M/ Q                        output += vrc6.Process( 0 )*vol[5];- s+ r5 B: _4 {
                        output += vrc6.Process( 1 )*vol[6];
; x3 y+ b' ^( ~  {% L4 ^5 N                        output += vrc6.Process( 2 )*vol[7];8 p4 v) I7 p( h
                }
- F5 ^. c/ [/ S! ]8 n                if( exsound_select & 0x02 ) {
$ W( g" l' b2 ^5 |; o+ D                        output += vrc7.Process( 0 )*vol[8];
) X1 V* L* I. C, ^/ G! c                }
$ n: a5 I6 H/ b9 f. T$ l7 T7 X. A                if( exsound_select & 0x04 ) {1 Y3 _" o0 H1 d$ d- r
                        output += fds.Process( 0 )*vol[9];8 a+ |2 C, G, l  n( `) g; [
                }
1 F6 h% }9 m' j8 y; w' L3 \                if( exsound_select & 0x08 ) {/ t+ j/ B! J' T4 u- \
                        output += mmc5.Process( 0 )*vol[10];. @5 ?, ]$ o- P4 H0 _5 n
                        output += mmc5.Process( 1 )*vol[11];
7 q3 R9 ?% }5 v' p0 [                        output += mmc5.Process( 2 )*vol[12];; P: \" x. [$ g# z! F% @2 S. b
                }, ]9 {, j; {7 {$ S
                if( exsound_select & 0x10 ) {
" R% r+ a. j; @! x, ?- {                        output += n106.Process( 0 )*vol[13];
) \; N, h5 h+ Z% Z% M  E" p                        output += n106.Process( 1 )*vol[14];
! i; P# m5 r. l                        output += n106.Process( 2 )*vol[15];# f0 F) d! k8 E' V% ~
                        output += n106.Process( 3 )*vol[16];
/ L' B5 i, n" o% E                        output += n106.Process( 4 )*vol[17];
/ F/ u. B' o" X* F. |2 t, S9 F7 l                        output += n106.Process( 5 )*vol[18];, ^- N, D* V3 N* ~& c% F; K% o7 y
                        output += n106.Process( 6 )*vol[19];
0 G3 N. i( G' K* k  f+ I% S                        output += n106.Process( 7 )*vol[20];
- F2 }+ s  j, n; L. Z                }# G/ t: }7 N) V7 w% D5 @' D1 Q
                if( exsound_select & 0x20 ) {* g: H$ U. u1 D8 O4 k
                        fme7.Process( 3 );        // Envelope & Noise
* j, Q5 ]5 Q+ z0 G8 _( O$ a1 m9 H                        output += fme7.Process( 0 )*vol[21];
6 C- ]9 Z2 D7 \. n. M: a                        output += fme7.Process( 1 )*vol[22];
( _/ Y3 b. h9 G) m4 o/ e                        output += fme7.Process( 2 )*vol[23];
9 Y8 N- K+ a6 t7 U# [; M                }3 g* Q7 O9 ^" ~  C) k' E) |1 i9 U

4 O) J8 |. |# c" ^$ T- B7 J4 O; q- Y                output >>= 8;
: M1 C" t6 W1 H  V, s5 I
$ d$ S0 F) `) N) @& |1 R                if( nFilterType == 1 ) {
0 q% A. `" u: ?2 N/ q- Z                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
$ T( |' \$ K/ m4 ^6 B$ X                        output = (lowpass_filter[0]+output)/2;$ v8 Z5 q/ a+ [
                        lowpass_filter[0] = output;/ R4 ~% b" T/ S
                } else if( nFilterType == 2 ) {
7 i/ \; a$ t" c1 V. G6 r- O' J! c! X2 n                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
! L/ B9 X5 d( u" L, a                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;8 z. {' Y; D4 B8 j5 [
                        lowpass_filter[1] = lowpass_filter[0];$ O, O' n6 ~7 N
                        lowpass_filter[0] = output;
6 p: E4 @, Q# V' ]                } else if( nFilterType == 3 ) {
. N) h, `" H7 o. y                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)
$ k: i9 _* K1 p2 z# Z; X                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;
; a/ Z: ^, Z5 Y# T1 R                        lowpass_filter[2] = lowpass_filter[1];/ U' @9 u7 H( f2 i9 h2 Z1 r, k
                        lowpass_filter[1] = lowpass_filter[0];" N1 x9 b4 q' i
                        lowpass_filter[0] = output;
, V$ a. E& f, ^; P                } else if( nFilterType == 4 ) {
5 A) T. h( `4 |) S) J8 @0 c                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)3 T5 x& `" k4 O& T
                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;
8 z7 w) |5 A3 b3 F, n                        lowpass_filter[1] = lowpass_filter[0];- Y" ]; E3 Y9 J) y8 ]  A
                        lowpass_filter[0] = output;
7 l. h" }- ]8 a7 B: w( g3 x9 K                }
; I0 b5 ?6 N7 Z8 P8 `4 f! [0 a% T: i  O; J  `' _9 g" H0 D, f. @# r: E
#if        0" \5 x/ H% _( p) _0 z1 `
                // DC惉暘偺僇僢僩$ p- o+ j8 F. C- }% X
                {
$ b) o& d% y" I: U                static double ave = 0.0, max=0.0, min=0.0;. m4 s& s# O; ?) n/ j5 E7 ~
                double delta;
. c3 }1 o2 h/ {% g6 [. r, \5 }                delta = (max-min)/32768.0;
  A% `9 g7 d. V* `1 }; _                max -= delta;' E$ i3 o2 M, a0 ]4 E" p
                min += delta;
2 J2 R' e: R. d5 Y                if( output > max ) max = output;
+ |) e2 T/ H) I                if( output < min ) min = output;' H/ x- G) N0 f
                ave -= ave/1024.0;
% o8 l4 Z# ^9 b/ l- R5 N                ave += (max+min)/2048.0;5 y3 ^" ]) v2 }
                output -= (INT)ave;& @5 t5 x, c* `
                }. i. B9 e, v1 p
#endif, h. B+ E) A0 v9 C. e/ {1 y
#if        1
' N, S, g, E( j. E- Y                // DC惉暘偺僇僢僩(HPF TEST)( k" }# @. `! o; t* w- I6 }4 V
                {
( |0 ^8 d7 I9 _) v//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);9 Z4 U! K- K+ Q$ _2 A
                static        double        cutofftemp = (2.0*3.141592653579*40.0);
' U" M1 Y. O. B3 E! f                double        cutoff = cutofftemp/(double)Config.sound.nRate;. J0 K* ]2 y% y" i3 m4 ]- L9 t+ S
                static        double        tmp = 0.0;- B% ^( Q' E! t! x# {
                double        in, out;+ _2 \& I; V  `" u9 @
  L" G6 l8 W. P) A( _) e
                in = (double)output;) U0 p2 f- M9 R5 Z7 I9 F7 Y; z
                out = (in - tmp);
2 d, r9 g2 D; g- A# d9 B& D& C                tmp = tmp + cutoff * out;7 V: y: q$ Q' F/ A1 p
& D+ l( W0 k# |. v1 ~5 v$ m" @
                output = (INT)out;
" r" f7 b% r3 G" g6 j                }
. Y$ _6 _. ~6 Y" W# S" _3 u#endif$ l, b% P; \( \
#if        0
3 \2 `0 s. l9 S2 E% r- X3 E                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
& s: S' E% w0 M; G                {3 P/ X$ z+ N9 M1 `; `! z* \' k
                INT        diff = abs(output-last_data);- f) k& P$ N  u: E) p( q* K4 V
                if( diff > 0x4000 ) {+ B! [6 ]- t* S
                        output /= 4;% Y5 v8 O( T! G  a' c( G0 A& d
                } else
% z4 F, J2 r, Z% h# E" O                if( diff > 0x3000 ) {4 _( U- S% z6 M. b) `% ]$ b
                        output /= 3;
3 J* X2 e% e: B3 I' M                } else
# z  k( f: s. Y) [                if( diff > 0x2000 ) {0 B" i4 z& Q3 ~3 r0 M6 N
                        output /= 2;* n# Z4 H' V* e# V
                }# H" ^5 e$ ]7 R+ x+ m
                last_data = output;
( C/ i, y/ n/ W9 p% J" S                }
; M- C" h+ G6 N#endif
6 n$ Z  D0 b3 r! p( g( Z7 F3 ~9 `                // Limit- v( p( |9 `: G/ P2 j0 J( G) r
                if( output > 0x7FFF ) {
0 \( {. [0 v8 ~1 V( G                        output = 0x7FFF;- }: i& k, N' Z9 E( T+ J
                } else if( output < -0x8000 ) {6 T- M* C* S' E) \% t0 J" h
                        output = -0x8000;$ z! t5 l, Z0 K" E
                }( _0 w. _. m* X! O
  G8 e8 @2 O2 Z* M4 x2 T
                if( nBits != 8 ) {. S, ~1 d* K7 t/ \2 p
                        *(SHORT*)lpBuffer = (SHORT)output;$ Y, m3 M4 L3 o% J- i
                        lpBuffer += sizeof(SHORT);
3 n- j9 ^/ [! e  V4 s! A                } else {
# h1 n8 b5 \* y3 N% Y                        *lpBuffer++ = (output>>8)^0x80;/ ]& ^  \7 j# w% `2 R; v% M1 X
                }" K1 e8 I1 X# _/ D/ g
: b4 P6 V9 ?1 _
                if( nCcount < 0x0100 )
/ v) m& P# `; K                        pSoundBuf[nCcount++] = (SHORT)output;3 q, Z" Y7 W2 O
" S: j5 w8 p+ H  E$ E( _
//                elapsedtime += cycle_rate;
  N; Q5 o) Q' U& [5 Q" `                elapsed_time += cycle_rate;* u% E) I1 M* I0 g( R% J4 p* `3 u
        }
* R, x$ Z1 c. h2 c" c
) E9 C  e3 {# `% M8 u#if        1# C0 H9 x4 |7 r- z2 u
        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
# D- C0 }( m, j0 o" v/ x+ G7 B                elapsed_time = nes->cpu->GetTotalCycles();0 H. R7 l3 `6 ^- q- |( G* s
        }
( o0 E2 k0 Z) g. e        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
9 H$ M( j6 r: p$ s/ e0 L) Y                elapsed_time = nes->cpu->GetTotalCycles();
' y/ a: L5 K; o& z% H& b        }
2 M0 ?/ r4 T9 J#else1 o& L; l9 a; A3 c) m( l0 N' O" W
        elapsed_time = nes->cpu->GetTotalCycles();
8 |$ {" n, ?4 M  G# q4 _6 |7 N% c#endif# R$ G. y6 H+ Q8 `
}
" _7 @+ o8 a; t5 k" r
" \3 y9 @5 Z" A6 m// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)4 o' s2 ^. h, R) p8 w
INT        APU::GetChannelFrequency( INT no )+ u1 N: Q  g  o8 g& U6 A' {
{
7 ]% i4 s8 o) C/ P' ?( ]) \' F        if( !m_bMute[0] )' a' C9 B# ^, U+ g
                return        0;
3 x6 N  j0 {# ]( W
8 q; k' \" Z5 H- b        // Internal) r0 D0 I/ O; j" Q6 s6 Q
        if( no < 5 ) {5 [, p# x- W: O
                return        m_bMute[no+1]?internal.GetFreq( no ):0;
4 ^3 `0 S9 C  M9 u        }2 `" Y7 x+ W/ L7 H) k
        // VRC6. T- D0 m2 N7 o9 E! B
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {1 y- S' F! }/ G* [0 p
                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;2 R% k3 [) A9 o0 @
        }
3 s/ z# x, D# D        // FDS
: V8 r+ r. ]! b3 T% c" i% f. n        if( (exsound_select & 0x04) && no == 0x300 ) {
  d- C7 i# s( A3 ~5 Y1 U                return        m_bMute[6]?fds.GetFreq( 0 ):0;
0 H& R  \( D& o! c        }& l* y2 r' D8 T& q( f
        // MMC5) x* T8 A6 ^: K) K1 Y" @% x/ R
        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {, g: j+ P% Z2 O7 g% T4 b
                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;/ i$ z' y0 I8 s
        }6 ~3 C4 ?, T# _0 m9 _, c5 w% G- T5 I
        // N106
- s" a4 \" M9 C9 ~" ^% a: N1 j        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {! q6 g+ b% l/ T6 F! e
                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;4 p$ L. U) h0 R; b% }
        }# ~; O. K( f6 Z6 y3 |: K8 V
        // FME77 y8 x; O5 O+ W  v% v" o, U7 X
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
# C( b2 Q# F0 x6 }* i                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
% `% T% c, |2 Q4 f& Q" f' t        }) Y% R% S  o5 u9 h
        // VRC7
( [  [  _! W% g! v, J) k        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {* n4 {1 V# G( L; }9 g. N. p
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;
* W! i4 p8 y: h  H8 t0 y& o        }" s3 H0 Z7 j% X! q6 \
        return        0;: A, t" \, L5 ?' M  M0 p8 b
}% C# k& d, ?/ g4 ]! o
2 O; J$ F& v+ k9 d- v0 j$ U
// State Save/Load
& S4 N0 t8 K, a3 J& zvoid        APU::SaveState( LPBYTE p )
  s, R8 o  }' c- Y2 Z6 j{
- ]1 h# n& M4 `+ {/ X#ifdef        _DEBUG
1 P& K1 C* O( i/ C7 ZLPBYTE        pold = p;$ @; p+ r" P) |  @( N
#endif. v, g! {7 d8 P1 G

4 c. [; M/ q5 @        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞
8 y) [6 I8 c. h! c( N9 U        QueueFlush();" H: [1 I+ C1 H8 m; m' i& o- J( U

1 C9 y' E  N5 [6 v        internal.SaveState( p );3 M0 g' S! y# R" m5 ?
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
  H! j6 }' I) \+ P  O) _
* f) s# F. c- {. s* J% X        // VRC6
$ x, T8 H: r2 w0 o1 A        if( exsound_select & 0x01 ) {  `! V' P" y1 ]9 h) B: p# T. l
                vrc6.SaveState( p );2 z' }3 \/ J& ^7 I5 V
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
. S; o: f( d* d: J3 p& u2 q; ^, p! @        }
" W. |4 E2 |8 a        // VRC7 (not support)# H5 A5 [: E9 G+ A! s
        if( exsound_select & 0x02 ) {7 c4 b: B" [7 K% C1 d5 C  z
                vrc7.SaveState( p );
+ E. z& O6 ?0 \' Y5 v. X" z: r                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding$ [9 P8 v- h: R6 O, _! D
        }
- P' g; c6 L; {        // FDS
/ [" G4 A0 I6 W$ ~! w) H6 c# K        if( exsound_select & 0x04 ) {4 q5 a! [) V0 y7 t
                fds.SaveState( p );! `; b9 |& O- h, ?$ l: s
                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding& S) F$ M4 ~2 P8 d: g
        }
2 G- }5 c) w$ |% x" {, x: S        // MMC5& t& I' E- A; Z4 P8 \2 h* R
        if( exsound_select & 0x08 ) {3 a9 f" K# s1 T6 L2 E# p& p. @3 y# m
                mmc5.SaveState( p );
  L7 s- C! @8 C# b5 R4 m                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
' D5 M  K3 K* W2 B% Q& f+ z: u3 k        }
: c8 P4 N/ V" r5 g+ g; a+ U- e, Y        // N106
; t) f( u. C: t& {& m        if( exsound_select & 0x10 ) {
, D" J* f* a& {. k9 C                n106.SaveState( p );! I8 L4 L1 z, A) x: k1 Q9 P
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding9 w& E+ D1 B* }
        }
# b8 ^' b( h6 r8 b' E9 m. H& V        // FME7) D6 @4 d# A7 S
        if( exsound_select & 0x20 ) {, k+ ]: m1 R) T
                fme7.SaveState( p );  E* ?9 V9 H1 D0 N9 E% [$ r8 I
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding, R/ ~' y, ~$ f9 f6 w6 h3 s8 i/ |
        }/ D& E5 V+ z# [3 y% ^# s
1 @+ p3 W1 f$ M0 h
#ifdef        _DEBUG) }* P7 J0 i9 T" K( A' A2 \% G
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );( U. t9 D9 H5 |3 e
#endif4 t% {7 R' l, x
}; ^0 C6 `" g, b, q! Q' P3 o

& W( B: t7 Z# j8 l% k+ _void        APU::LoadState( LPBYTE p )
$ I  w9 l1 B, U{! n' d. F2 _* E" o
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
- f. M3 u. n: m9 ~        QueueClear();
. F3 h: |8 _; C3 b- f* m: }8 |# h3 ?" Q0 L1 G1 w. @6 q. h
        internal.LoadState( p );: x0 z) H8 c7 h; F. E7 N. m0 B
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
. w' {5 w* ^/ \# Z8 }! M# Y* Z2 @! L: k7 F
        // VRC6
  C3 Z6 b" G& X# a% r9 Z" ]        if( exsound_select & 0x01 ) {1 v/ r, r; @/ H/ e, H
                vrc6.LoadState( p );
* C7 o1 _3 i- [3 O                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding7 j( L0 Z. S$ n9 F* N, ]0 ?
        }
2 t% D7 u( N6 x  T, e        // VRC7 (not support)# L+ u( V+ F7 E) \! `( u
        if( exsound_select & 0x02 ) {$ s* C5 A) V: d0 k7 G& h  W, f& m
                vrc7.LoadState( p );
5 E2 d/ A; x9 D) G5 B) u                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
. v" H' I. R4 f- ]' d- W0 @9 q        }! E3 W2 E1 Z; H6 s) c: `
        // FDS( ^- r' M$ y( X4 E% l
        if( exsound_select & 0x04 ) {
; k$ P8 S* F. E                fds.LoadState( p );
/ T  X, d0 x2 x9 U+ j, L' m1 o. y" s/ `                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding! g5 B' Q- t% w& q' ^, D
        }
$ `( X$ W  h( W4 O; L        // MMC5
8 ?* f0 P  z5 Q2 R  i        if( exsound_select & 0x08 ) {# G- Z3 M" P4 ~2 O, U/ T, P- n
                mmc5.LoadState( p );5 _0 A  y" ?" g) G) n+ }
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding
+ n( @. h* w! u$ c        }
) f; O; m: u5 ~( J        // N106$ j% Z' u# [; O& p' C# r. C" \
        if( exsound_select & 0x10 ) {# g( Z) x. B. k6 L! Z
                n106.LoadState( p );( B! Q# c4 K- B$ N
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding! M$ \, j  h, f+ D1 K
        }
. B. K; @$ l& j+ O/ K6 e9 n        // FME7
/ i4 \/ c+ I3 G- I- Z) x/ C        if( exsound_select & 0x20 ) {, ^# k: T& O* _- ?% ?/ k& q
                fme7.LoadState( p );
2 F4 D' B# g" d4 B1 w/ g7 _& `                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
& a. ]' k& b+ A" [, U! M        }# ]/ e  n. D/ W% }' H# F
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 : L+ r, ?" w  p& Q* r# |6 \1 p
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
$ E$ v2 P- |3 U: ~* Z" E感激不尽~~
. S" D' y4 X  w# S
恩 我對模擬器不是很有研究,
+ _- J& Q- h7 i$ K2 O3 J雖然要了解源碼內容,可能不是很困難,0 ~, K1 e% U3 I2 ~: [" J2 p, p& k
不過還是要花時間,個人目前蠻忙碌的。, U' k) _5 u8 m) q% s- q
) n- W2 I, E: `
給你一個朋友的MSN,你可以跟他討論看看,
  _1 M! M  Y6 U他本身是程式設計師,也對FC模擬器很有興趣。
, I+ f" |, j$ Z1 S" y. y4 U* C- j( q2 x* f8 f9 q
MSN我就PM到你的信箱了。
8 ?, I; X: l' g) k2 t6 a
" e  G  Q* d& \( P0 I希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表 , y$ F3 j* p" A2 g( @
呵…… 谢过团长大人~~

. {) m% m4 q- J! D# b) G, P( l8 q: y; l# ]( K: ?. O* K
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表 . ?; ]5 n; y7 A/ Y
团长的朋友都是神,那团长就是神的boss。

( o: c5 B2 p6 P1 N4 O/ W7 q哈 不敢當,我只是個平凡人,
4 V+ x1 _; G+ o/ ~要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙' T+ X5 T$ c/ x
ZYH# b" R8 l% k; O  [8 B
QQ:414734306& V/ X$ M/ g( F$ D; s$ R% A
Mail:zyh-01@126.com+ b3 \8 M8 @% F
' W0 ^7 |2 p$ n( X; O
他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 " l" _6 i+ f0 ]+ [. p5 j2 }
再次对团长大人和悠悠哥的无私帮助表示感谢~~

+ ~$ L) S5 ~- q9 H( S不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-30 00:10 , Processed in 1.085937 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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