EMU618社区

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

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

 关闭 [复制链接]

该用户从未签到

发表于 2009-11-2 22:45:57 | 显示全部楼层 |阅读模式
求助:模拟器源码中通过哪段代码控制Rom背景音乐的播放?, `9 D; S% E' G4 ^  E! z- X9 R
PS:看过一些模拟器的源码,大概都分为APU、PPU、NES那样几个版块。请大侠告知是哪个模块。感激不尽~~

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 09:56:34 | 显示全部楼层
能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。& u) l8 p7 ^: @' \. Q. j* m
楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~( h! f3 W: u& D/ x7 E8 a
这里有相应的模拟器源码,就当送给大侠了~~
% G  p4 j3 e) D, A5 }5 n1 rhttp://kenkao.qupan.com/5096520.html

该用户从未签到

发表于 2009-11-8 11:31:10 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 09:56 发表
* |9 ~/ J* v% U. P1 x4 q能否再详细一些呢?本人比较熟悉上层的编程思想,但对于NES的底层算法机制基本是彻头彻尾的外行。
/ d7 O' L; H9 X- Y5 R" @楼上的大侠可否帮我准确定位一下,是哪个.cpp文件中的哪个函数,感激不尽~~4 L6 ?/ h# i1 t0 C" n6 U
这里有相应的模拟器源码,就当送给大侠 ...

0 n4 N( q( K- ~4 m聲音部分(Audoi Process Unit = APU):
0 K/ h# D9 W+ ?/ j( p3 x4 B- c" X5 p.\NES\APU.cpp1 R) u# u% I$ L# _1 n* j
.\NES\APU.h+ f/ N' ?5 {/ F3 T4 j, e1 {

8 X& |, S& F1 D3 [. g0 \
3 @$ e4 Q9 U2 Q) o* z影像處理部份(Picture Processing Unit = PPU):
9 G# K3 G6 A4 V& t8 Y.\NES\PPU.cpp
. D5 O$ o. f/ V7 t.\NES\PPU.h
0 g/ M" ]: s$ K; q% v2 n% I$ h! V  V6 X5 t5 ~7 t( V0 c6 Y& d
如果原碼用C跟ASM混搭也不錯

该用户从未签到

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

该用户从未签到

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

该用户从未签到

 楼主| 发表于 2009-11-8 14:47:50 | 显示全部楼层
这是我手中源码Apu.cpp的内容,敬请赐教:
  H) r5 b* `/ D, g7 z4 S/ A; c(由于很多专用术语和算法机理都不明白,所以看不大懂……)7 K0 q, u  O8 y- e% ~
//////////////////////////////////////////////////////////////////////////; D! L( i- n  q# G. `8 g7 O. v( {
//                                                                      //  B* f; l$ y* t
//      NES APU core                                                    //) Y0 L) B% R& K
//                                                           Norix      //
  O& @- I. C% \. Z- W9 d4 n2 f( C//                                               written     2002/06/27 //; e% a5 t! |, R2 t' e1 t
//                                               last modify ----/--/-- //. u1 }* \' w/ e- \1 v* q
//////////////////////////////////////////////////////////////////////////  ^3 t3 n# p; S+ }
#include "DebugOut.h": I' z7 \7 y1 n/ g6 p; X& u. G: w
#include "App.h"  W% G. u( r8 F5 s6 ^% E% v
#include "Config.h"! D! w. r' P" Q, |
6 P* v/ S' a5 V6 l1 w1 g
#include "nes.h"
0 E: N' B% Q4 [#include "mmu.h"
- P( D4 N" `( ?) h#include "cpu.h"
, r! \6 @: U5 d5 r4 e6 o#include "ppu.h"* Q& }3 N/ H* p9 a
#include "rom.h"
+ t& a% v4 N' K#include "apu.h"
6 J7 c1 N4 y. Z- @+ h0 U- p' ^
: z& X5 d2 A; [) p# F! l// Volume adjust; p3 t' Q; S* p* R# P
// Internal sounds0 `0 s' B, Z/ r1 {
#define        RECTANGLE_VOL        (0x0F0)
9 o9 h% }6 r4 D$ ^: c#define        TRIANGLE_VOL        (0x130)
0 D  a; w. m) @" W: Z: ~$ N#define        NOISE_VOL        (0x0C0)+ M* H% I! j; _6 q4 p1 e
#define        DPCM_VOL        (0x0F0)
- s8 B+ R6 {) ?// Extra sounds
8 P0 U. E/ ~# K& j) e#define        VRC6_VOL        (0x0F0)
- {, @6 n! a7 ~8 T# `#define        VRC7_VOL        (0x130)
; k7 ~1 d/ k: ]+ g( E4 b#define        FDS_VOL                (0x0F0)
, |3 x* J0 p0 o; h% O3 x#define        MMC5_VOL        (0x0F0), Q) u6 \" N& B/ @4 t# s) P3 J3 w
#define        N106_VOL        (0x088)
! Y4 W& j( T; L3 N#define        FME7_VOL        (0x130)" l5 x1 M( n  J9 T  V  U: H

7 ?- O& \: @6 L6 P8 l0 q4 WAPU::APU( NES* parent )
3 Q3 F# l* s6 V( h% O6 F{
) |# u- G% D7 l        exsound_select = 0;
+ d0 H, i, U# `( {& i3 F0 O# f( \* g: l0 W
        nes = parent;5 v; `0 b6 s7 C5 k( @* j) }
        internal.SetParent( parent );; c- `9 Z& u1 Y0 H
, k9 I, o% M4 e0 ^6 f8 Z- U  O
        last_data = last_diff = 0;0 h, o  J# `$ ~& J5 [; \& {
) T* I4 X6 e3 X' c" G& q
        ZEROMEMORY( m_SoundBuffer, sizeof(m_SoundBuffer) );# o7 n- _# Y$ E# r: e

) f6 e- h6 O7 Z6 ~        ZEROMEMORY( lowpass_filter, sizeof(lowpass_filter) );
% {6 S# I0 H8 J        ZEROMEMORY( &queue, sizeof(queue) );
3 ]3 V$ K7 p1 Z' ^3 w        ZEROMEMORY( &exqueue, sizeof(exqueue) );* }3 Z/ Y) c( V
& @/ ?2 l: R. W! ]- g0 c
        for( INT i = 0; i < 16; i++ ) {0 C0 t5 S/ D4 W4 q7 x0 V# J
                m_bMute = TRUE;
3 I& R. {; `8 b# ~/ N* H        }
! p) I: n% Z2 j4 i# N$ e}& ~1 `& n+ V' p2 n; U. X' W, s
3 ~4 z6 Q( ]  q* x6 P/ `$ [! `
APU::~APU()! C/ O) _( I4 O2 N" I  X
{% f- r) K2 k! Z; M
}& I0 Y& S+ n+ m7 N
4 G( @9 e8 M. R8 C! @8 S
void        APU::SetQueue( INT writetime, WORD addr, BYTE data )
8 Z! Z( H) J4 A/ V; ?4 d{7 U2 O* l3 g+ T  C
        queue.data[queue.wrptr].time = writetime;! e3 b+ i. V0 \+ w
        queue.data[queue.wrptr].addr = addr;- h0 q! L: [, F4 I
        queue.data[queue.wrptr].data = data;
1 X, L) p! h7 t        queue.wrptr++;# _% R7 y: t; X* u+ M8 B
        queue.wrptr&=QUEUE_LENGTH-1;" r. t9 L, \1 A& g% y& \7 X
        if( queue.wrptr == queue.rdptr ) {
# e2 x) J9 G# e+ M                DEBUGOUT( "queue overflow.\n" );
3 s& z1 z4 i& U/ I        }& ~9 Z$ P; S: K3 s
}
' F9 W& @7 }6 D1 W0 D# {+ M+ z( g* N2 H9 T. H" N% c# h
BOOL        APU::GetQueue( INT writetime, QUEUEDATA& ret )
; S7 z: h* O1 K( W& s# \{( H' ?4 j" u  A( ]
        if( queue.wrptr == queue.rdptr ) {- t1 b1 G# f2 }( k
                return        FALSE;
9 {* G$ W5 j  d/ p9 l! K' C2 c        }2 i: u+ T- s  |( a
        if( queue.data[queue.rdptr].time <= writetime ) {, |6 c6 x0 {. s& R
                ret = queue.data[queue.rdptr];
3 L8 ^+ h$ ~5 e3 N7 Y$ Z                queue.rdptr++;- u- G2 a# Y9 L6 q
                queue.rdptr&=QUEUE_LENGTH-1;
; ]' B- R* C: Q7 P6 T& m$ a3 o8 e7 G                return        TRUE;/ b" i9 n+ V7 J
        }
6 h+ v9 j2 \7 G0 F& `. m; E        return        FALSE;
) @* Z6 n% d4 Y( ^}
# n! r4 n6 g- z$ h( W' u2 v: R, I. u+ Z
void        APU::SetExQueue( INT writetime, WORD addr, BYTE data )6 Y' f* Z% b' [* S' ?
{7 P! F* k& R, N/ r
        exqueue.data[exqueue.wrptr].time = writetime;- Z6 Q5 z& M: O* V8 D& g
        exqueue.data[exqueue.wrptr].addr = addr;" P: H3 x3 N. n  w5 _
        exqueue.data[exqueue.wrptr].data = data;
$ E5 N( o9 w5 e3 i8 T- D        exqueue.wrptr++;
& p( D1 W, e5 i) w* e- k- I+ {5 N        exqueue.wrptr&=QUEUE_LENGTH-1;- ^( y* B# C( s5 C2 c
        if( exqueue.wrptr == exqueue.rdptr ) {7 Y- V0 i9 k7 d' T* w. Q( I2 r
                DEBUGOUT( "exqueue overflow.\n" );
) ^* x/ O5 |$ y2 ~+ a" N5 ~        }) \( V- m8 y! g: q6 C3 \  c3 {
}0 R8 F: P/ l8 K( W

4 ?7 C4 U3 M9 t3 E. _BOOL        APU::GetExQueue( INT writetime, QUEUEDATA& ret )! J8 o8 q* p) w6 b7 I6 L* |
{8 v2 x- c  G9 ~$ o5 a5 J' U+ o9 `4 v0 p
        if( exqueue.wrptr == exqueue.rdptr ) {/ f! P0 f! b4 p8 d  c" r# ?
                return        FALSE;
4 }) H" V5 G# \! u        }
: L8 e' s9 n# h  U1 v1 v. K        if( exqueue.data[exqueue.rdptr].time <= writetime ) {# U( [  H' Y; F7 A. ?
                ret = exqueue.data[exqueue.rdptr];
; i3 f: ?/ L6 H8 A: j0 e5 z                exqueue.rdptr++;# Y2 X' P& g7 z+ V: u: \
                exqueue.rdptr&=QUEUE_LENGTH-1;; p1 @; j# z) @: P/ n) m
                return        TRUE;
8 W5 D; R, @7 k) d9 \8 D, N        }
, h  p/ m. `* d" R) O: y' {9 }, V' C        return        FALSE;
; I4 Y% T, ^% G. z5 W* z}) M  w% h2 ^% |/ z* F/ H: R
8 V# G3 A, p2 W( d
void        APU::QueueClear()* L0 ^( k$ b4 I. b
{
' |8 I5 l) g# G5 W- @7 K        ZEROMEMORY( &queue, sizeof(queue) );
% t8 q- Q0 x4 g5 F        ZEROMEMORY( &exqueue, sizeof(exqueue) );
3 K6 v3 ^: ~$ v% J}0 N8 `$ M- J* L2 R
$ X: K& b7 F3 F  f( o/ u
void        APU::QueueFlush()
: r: b+ C& K; E. l9 O4 B{
: x8 H- K: N* k4 @        while( queue.wrptr != queue.rdptr ) {
4 c/ q# Y1 w- B( k, u2 H+ A                WriteProcess( queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data );3 ?$ o& Z0 V3 ]' e+ X- y
                queue.rdptr++;4 E) m4 T  n( r
                queue.rdptr&=QUEUE_LENGTH-1;) D' p+ Z% B1 z4 m4 C
        }
; A8 d6 r4 `! \# h% ?7 C
8 n( p  U, r/ @" C. o/ C        while( exqueue.wrptr != exqueue.rdptr ) {% W" Q% Y0 w4 A# P1 ?
                WriteExProcess( exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data );
* A* Q, N* R" [  T* Z' u# e                exqueue.rdptr++;
8 N! p! I; j: `3 w5 V3 X9 d                exqueue.rdptr&=QUEUE_LENGTH-1;1 Y& F5 Y) g. ?) J6 h) c
        }
8 C" G8 I2 x" O  o# V}7 Z" l2 X! ~- F+ `: s2 q, @. h

& t! o# x' V. F4 b$ Cvoid        APU::SoundSetup()
. e3 d& W. Z! V" P{0 u+ X8 i+ q% b5 V% t$ m
        FLOAT        fClock = nes->nescfg->CpuClock;
& ^" G9 S  \/ t        INT        nRate = (INT)Config.sound.nRate;! N& P5 j6 R& F4 L  D
        internal.Setup( fClock, nRate );0 n; K( p! |: {$ i% }8 `- d
        vrc6.Setup( fClock, nRate );% [3 m! t; A$ |* Y1 V
        vrc7.Setup( fClock, nRate );
+ x4 x% q* x; O( _/ Y8 m! A0 r        mmc5.Setup( fClock, nRate );" |6 W+ R, s& N. w; s: T
        fds.Setup ( fClock, nRate );9 i/ M6 J  T8 D2 t/ t1 l$ p/ r) h
        n106.Setup( fClock, nRate );6 t( ]! R4 N  h9 O
        fme7.Setup( fClock, nRate );
0 b# C0 L: r# s1 j/ ~}; D. g" b& D  Y9 |+ o4 s( A. I

( ]& r" ]) O7 K9 Q+ g& |void        APU::Reset()
3 O+ V: t- y$ q  v4 |( d{
3 Q2 ?5 f3 W  `7 m        ZEROMEMORY( &queue, sizeof(queue) );( c5 M( q6 Q- k) k4 q
        ZEROMEMORY( &exqueue, sizeof(exqueue) );
; T% W; y/ Q* J# j8 k" ?5 K* c  }8 A0 T2 y
        elapsed_time = 0;# G# I  p1 l7 u: w, Y' [

) R2 n6 B6 p3 ]0 y        FLOAT        fClock = nes->nescfg->CpuClock;
6 s4 {; C& S. E* I# X" c        INT        nRate = (INT)Config.sound.nRate;1 w" a, N# F! w, p; @
        internal.Reset( fClock, nRate );8 P. b9 x* z0 E; e' @
        vrc6.Reset( fClock, nRate );
$ H  O$ \+ A1 [3 O: `! x' u. m        vrc7.Reset( fClock, nRate );
. h" b/ E4 a  Y, W        mmc5.Reset( fClock, nRate );
8 _% D# B' L, T! Y1 X% W0 o, m& N1 H/ h5 z        fds.Reset ( fClock, nRate );2 T8 a1 w8 Y4 s; {4 x
        n106.Reset( fClock, nRate );- v$ C; x( N( {7 ]# A5 J2 x
        fme7.Reset( fClock, nRate );3 ?( |3 W8 Y& M; E& R8 W" J+ R

% X3 h+ P' }  \' Q) M- }) E: l        SoundSetup();
! g7 a2 z: n% K}
% P, C* j1 \+ H, i8 ], w. M/ ]3 o2 `$ R  d/ M( Y1 j8 J; P* ~$ X7 H+ \5 b
void        APU::SelectExSound( BYTE data )8 v; h/ W( B4 Y; X0 G' |; ^
{/ {1 X/ U+ Z7 g" F1 ?' q
        exsound_select = data;
% E: f9 ^. ~; }1 J% ~2 l9 x8 Y# f}
' x$ h+ P- n( i" \' e! l3 {$ f9 T
9 D* d' z5 z8 e! _BYTE        APU::Read( WORD addr )
2 `; }6 S" ^6 e* D- [8 I6 ^{
+ s8 ^: q3 V5 W. Q        return        internal.SyncRead( addr );
$ U: {* [8 p% t8 X}% [) }. v: X1 E. J3 T& d8 h% R* e
5 b4 J& R2 w5 ~. t7 y
void        APU::Write( WORD addr, BYTE data )
# d% Z, k' v% R6 K{
3 K3 }* o$ D' o  e" ~/ o3 @6 G' c        // $4018偼VirtuaNES屌桳億乕僩
6 e9 J+ z1 G! S' C2 l8 b. d6 [& V        if( addr >= 0x4000 && addr <= 0x401F ) {& \; g: q) h3 `" k9 r* r' D0 _3 H
                internal.SyncWrite( addr, data );5 y' G$ r9 s: B  F9 z
                SetQueue( nes->cpu->GetTotalCycles(), addr, data );
! M: q$ y0 Y7 I: g- m4 m        }
  i  X5 k/ [; t/ @, `}+ w/ N' a, p* y( f4 v# Q& d- R. r

: r" j. r4 M- m* B8 y0 L6 j7 ?' qBYTE        APU::ExRead( WORD addr )
6 s* u; ]5 B" E$ o% D{( J" c! j, |( Q% B
BYTE        data = 0;
. \. X" W8 L: c8 I, L; L
9 A+ U& S- M- I! y9 G& E4 {        if( exsound_select & 0x10 ) {
7 {; e. v( Z5 e# v) h                if( addr == 0x4800 ) {
% D9 D1 f+ `% j, x                        SetExQueue( nes->cpu->GetTotalCycles(), 0, 0 );' a. |3 M) O% _& E: p5 Z$ F  Y9 E
                }
  b# w. J7 v. m        }
: @/ Q  `! b0 d  N& V2 C7 P- N        if( exsound_select & 0x04 ) {* y& ?4 ?) W* E
                if( addr >= 0x4040 && addr < 0x4100 ) {
0 K, o) i, W% U# f8 b/ y' d                        data = fds.SyncRead( addr );, y. |1 g, f4 k' i0 U  _- x% l
                }; n& i) u% X3 [$ w3 F, \* b. p9 z
        }
* c4 E3 w. k' T: P/ L        if( exsound_select & 0x08 ) {& v$ p4 i# X$ {2 z, |" f; W
                if( addr >= 0x5000 && addr <= 0x5015 ) {
; n1 \" I" |& I0 o8 Q                        data = mmc5.SyncRead( addr );5 A& Q6 {9 R- j
                }% B9 j3 n2 _6 a1 r  G3 v6 L
        }- F7 u. T( M2 q$ i6 K  z5 Q7 ]
. o9 X- f6 [9 y; L1 y
        return        data;
3 E" D$ J5 R5 H$ a9 Y# e9 Q}1 v0 Q& X+ K6 L9 k. g7 I4 ^" V* B

5 F" d. N7 o  r0 c9 ^( f, V( Mvoid        APU::ExWrite( WORD addr, BYTE data )# K' C* e. O7 H8 Y, M, p) W) d8 d
{
4 s3 O$ ^# }0 ^        SetExQueue( nes->cpu->GetTotalCycles(), addr, data );4 ]( h) g- d$ I1 `  T! ]$ I

4 \# ?" r5 N8 ?        if( exsound_select & 0x04 ) {
4 B  N! a' w% Z/ I8 E# t                if( addr >= 0x4040 && addr < 0x4100 ) {1 b+ @6 ^0 |) ^
                        fds.SyncWrite( addr, data );
* R0 I- t8 c& K                }& a1 s# Y0 P3 e2 j; ^
        }/ j- z! a/ G, D# A! O

1 k- c4 H+ m2 Y: X        if( exsound_select & 0x08 ) {
* O+ X9 f, ]8 U2 A                if( addr >= 0x5000 && addr <= 0x5015 ) {
! u* q! `$ X% }6 @& k+ V2 ]. [                        mmc5.SyncWrite( addr, data );* K' k- a1 f# u6 O  `- @- C4 K2 o
                }
! M( _4 O- V/ r" l, F        }; `; h% A% z4 U1 [
}0 Z* F* `: M: ^6 A

- Z( z$ S& F! d5 b; @* Kvoid        APU::Sync()
% s6 p* {. Y8 U  ]# {7 S# c, a8 `3 w{; |: q" \) H9 h% u7 c; D
}6 f( u0 i% E4 O

9 n$ x1 r5 P  e/ C7 x$ t: l1 {7 xvoid        APU::SyncDPCM( INT cycles )) ~0 `- {9 @. [" S7 |
{
! r6 W# o+ ]5 k/ D5 t3 M8 X        internal.Sync( cycles );. l: e0 L1 ]3 Y7 r7 U
! ~2 P+ j" v6 j1 \1 t; P; o  m
        if( exsound_select & 0x04 ) {
/ P/ {8 }/ {* s3 J. A                fds.Sync( cycles );) Z/ B) J& ]$ T" d7 e
        }5 F' ?+ e1 x. F- N5 ?: C2 D
        if( exsound_select & 0x08 ) {
. _# X' @9 l) e4 b6 ?                mmc5.Sync( cycles );& y' I# x5 X$ [
        }# R3 x! H# M# B( j
}- z# E( S! n+ c+ j0 S1 v) Z
* @5 E; f% \6 W* t/ Z* s, o' y
void        APU::WriteProcess( WORD addr, BYTE data )
- }; Y- Q1 m0 `/ b3 C" Z{# ]2 Z. v) y: F( F
        // $4018偼VirtuaNES屌桳億乕僩
, m# V4 d0 R- v$ N        if( addr >= 0x4000 && addr <= 0x401F ) {3 l8 {' ?& f$ i
                internal.Write( addr, data );
8 j+ ], E/ d! E) j' v        }
1 t! M! n7 G* F5 `& K* M) \% ]5 i  K}
, j  f# c6 p6 N( B  ^& u" [  P/ K, u) T
void        APU::WriteExProcess( WORD addr, BYTE data )5 K) U" R6 @$ P' ?7 `
{: Y! K- L2 G* k% @3 J- t
        if( exsound_select & 0x01 ) {% N1 V; n' l/ T. s  z
                vrc6.Write( addr, data );% _' S& q# l) Q3 J+ ^* Y
        }8 z9 G' |) v' f1 L8 C! |' T/ w
        if( exsound_select & 0x02 ) {
5 {2 T7 K7 w* L; F% f3 i                vrc7.Write( addr, data );
1 p# r- t! i4 |# f. _        }
0 _8 |1 `7 F  C! \4 W        if( exsound_select & 0x04 ) {* C/ _) O; b2 p# [+ K) F
                fds.Write( addr, data );/ i: [; f. o$ @- }* j9 l9 K, |. ]
        }
; p) w# L- x  ^% a* c1 O        if( exsound_select & 0x08 ) {
9 L& T5 G; x. \6 Y# E2 F. V                mmc5.Write( addr, data );
, x7 [# p0 S& g& k2 F        }8 F6 }  r7 k- n  j$ {5 U6 T
        if( exsound_select & 0x10 ) {# h1 [; F6 {( n8 @4 _( W8 e
                if( addr == 0x0000 ) {
9 E; e6 M" u2 V6 B7 M                        BYTE        dummy = n106.Read( addr );, I- A6 j* H% ?1 b# b) F7 |
                } else {
" u2 P; |: ^4 v# h5 U, i8 r( F1 H                        n106.Write( addr, data );" }; M# t* ^! _( b5 s0 A2 T$ }) D
                }
$ H. |% ^. [- @% @* n( [, V        }
9 |% x) I6 {- y: k7 K5 S        if( exsound_select & 0x20 ) {
' g+ u% g' h3 \$ m8 y, n  d' R$ I                fme7.Write( addr, data );
& |0 m' G9 k& B0 {+ X; u        }  a& ]8 ]/ v( a# z2 }
}3 f5 ?, Q- d) V! S+ H
" R, m  @  [! ], l' n1 Y$ e
void        APU::Process( LPBYTE lpBuffer, DWORD dwSize )
( V( l3 ^  u5 C{
9 _. k4 s! z% d5 p9 P  oINT        nBits = Config.sound.nBits;
0 Q8 `1 b9 c  Z' b2 [DWORD        dwLength = dwSize / (nBits/8);6 T! ^) d8 P: r' O+ s
INT        output;2 G2 `1 p3 w" M3 W
QUEUEDATA q;
$ X/ _: ~# T3 lDWORD        writetime;
; ?7 ^5 @  x4 m' ~( R* N# |0 H
4 Z" T9 L, K$ B) U: W- v7 C( {2 O* pLPSHORT        pSoundBuf = m_SoundBuffer;1 w) e7 _& Y6 h0 H6 _7 F' b6 l
INT        nCcount = 0;
$ @  b9 l" e! X, H1 f
+ D8 Y% K) W  U4 i6 \5 P9 SINT        nFilterType = Config.sound.nFilterType;
* ?+ n7 s3 D4 z+ h6 P; o: I, G1 [3 w0 I  r% b8 Z2 O
        if( !Config.sound.bEnable ) {- e) X5 U( c( M. m* @8 I1 }
                ::FillMemory( lpBuffer, dwSize, (BYTE)(Config.sound.nRate==8?128:0) );9 p- N( m7 [$ ?
                return;; Y9 ]2 f! p" o! j2 C
        }
7 M+ t) Q: e' [* d& O7 D( B/ h
        // Volume setup
$ g" k& O0 K- T+ e        //  0:Master4 W: ?7 v* }5 o8 x+ u: J- h
        //  1:Rectangle 1
: q; ?4 O# q8 u, ?5 P  D        //  2:Rectangle 25 B* }" I! V) k8 E
        //  3:Triangle
% o' C+ y/ _6 A* c1 {. _7 F        //  4:Noise
4 i9 \" J# G, F' m# S        //  5:DPCM
: o4 ]) ]0 J" ]0 S! g0 @# t1 U2 {, ~        //  6:VRC6. e- n' Q/ n. ~: i/ {3 d0 H
        //  7:VRC7
; N! q0 j* R$ b. P        //  8:FDS
: i: f) z1 U  X6 ]; g- m        //  9:MMC5
6 a! g' s9 P" }- ?3 k& _        // 10:N106
# _' I+ c9 w( T* \; ^) I        // 11:FME70 ~! J- a; O9 I
        INT        vol[24];
+ I) D: X9 N9 @6 q$ t- p. _        BOOL*        bMute = m_bMute;  H2 a2 z+ d2 b# Q' b
        SHORT*        nVolume = Config.sound.nVolume;" B& O( p- g, L" c& g

7 p- \7 G" l$ q) l' N; B        INT        nMasterVolume = bMute[0]?nVolume[0]:0;
$ a: P9 j/ B( }; }2 j3 R
3 C# l0 Z- \, t( K; R        // Internal: @/ K% k% O+ p: o
        vol[ 0] = bMute[1]?(RECTANGLE_VOL*nVolume[1]*nMasterVolume)/(100*100):0;9 s. \  Q" u: e0 e
        vol[ 1] = bMute[2]?(RECTANGLE_VOL*nVolume[2]*nMasterVolume)/(100*100):0;2 E: P# G! S, f% O
        vol[ 2] = bMute[3]?(TRIANGLE_VOL *nVolume[3]*nMasterVolume)/(100*100):0;5 ~0 g4 c# @1 F" f# [  ^4 N2 Q$ n
        vol[ 3] = bMute[4]?(NOISE_VOL    *nVolume[4]*nMasterVolume)/(100*100):0;) p* {+ k+ d  G
        vol[ 4] = bMute[5]?(DPCM_VOL     *nVolume[5]*nMasterVolume)/(100*100):0;
4 b' i5 v. j1 o! `0 k& N1 X- G8 S5 o6 x, T' E( k
        // VRC6
& x0 m" d- h7 c8 O0 l2 J  @5 N* o% c        vol[ 5] = bMute[6]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;' d5 v6 k( _' y' `7 @& z7 q
        vol[ 6] = bMute[7]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
& j. E! b1 g* N" ^( Y        vol[ 7] = bMute[8]?(VRC6_VOL*nVolume[6]*nMasterVolume)/(100*100):0;
+ x- u  R" b9 j# u" g* Y: ^# p/ B: R$ Y% b0 j
        // VRC73 j9 H- `) n, C% Z
        vol[ 8] = bMute[6]?(VRC7_VOL*nVolume[7]*nMasterVolume)/(100*100):0;4 q. A3 H+ P- Q0 O7 l2 w7 p1 L
# x' C4 S( A  A( t  K
        // FDS
5 q( K$ {/ L" ^5 I4 P  o: Y        vol[ 9] = bMute[6]?(FDS_VOL*nVolume[8]*nMasterVolume)/(100*100):0;
( v! e/ `7 y! a  t0 h3 I
. Y  v  x8 v1 k) T, P        // MMC5/ i" E" f" D$ U
        vol[10] = bMute[6]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;( U& N: d; X* Z) y+ N, p  ?+ p3 c- q
        vol[11] = bMute[7]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;
8 ~8 M# o4 G& U0 }        vol[12] = bMute[8]?(MMC5_VOL*nVolume[9]*nMasterVolume)/(100*100):0;" l3 Y3 Q0 W5 D* U4 a; N

5 f# X. s7 P2 |/ F% W. i$ p+ R        // N106
# ~4 u7 o- G0 D1 n8 B& e! x2 N& z- d        vol[13] = bMute[ 6]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
- x2 n- v; e- [3 J( h        vol[14] = bMute[ 7]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
8 \  x9 u7 d0 a# d( f, `) v4 \7 l        vol[15] = bMute[ 8]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
9 C! q6 N2 V& _" q" c        vol[16] = bMute[ 9]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
) h% r6 k0 p" |& r        vol[17] = bMute[10]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
: V# h( H2 n: U* S* j        vol[18] = bMute[11]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
7 K% `, O# g# e4 Q: l/ o1 Y% w        vol[19] = bMute[12]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
+ _3 x' g: h6 @* o- g+ O# s        vol[20] = bMute[13]?(N106_VOL*nVolume[10]*nMasterVolume)/(100*100):0;
4 G" z1 j9 Z& \* \# Q9 p; N; }" \4 P( s. m3 r
        // FME7
! Z1 i) I  j4 R        vol[21] = bMute[6]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;8 B* {7 }& v/ }# k. \
        vol[22] = bMute[7]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
/ @) l9 |0 t7 i        vol[23] = bMute[8]?(FME7_VOL*nVolume[11]*nMasterVolume)/(100*100):0;
0 _# a  d' e7 V. {- N6 m! d/ a9 c
//        double        cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;' B6 {5 m1 L% N4 E  C5 v: W* k
        double        cycle_rate = ((double)nes->nescfg->FrameCycles*60.0/12.0)/(double)Config.sound.nRate;
" g/ y8 K) c  s
# _* m0 M9 w2 ~        // CPU僒僀僋儖悢偑儖乕僾偟偰偟傑偭偨帪偺懳嶔張棟
0 B  C, c9 P3 _- c1 |1 u# ~7 T        if( elapsed_time > nes->cpu->GetTotalCycles() ) {. m: ^" R9 v# x+ o4 q
                QueueFlush();
; F/ q9 u: M; ~/ l        }
6 [; |- M) d' {! {* b4 G2 n$ \& d, c' V
        while( dwLength-- ) {
# ^# H& F7 D% d8 O9 V; u! @                writetime = (DWORD)elapsed_time;: G8 p, Z& p. [. Y4 S

0 v8 X' S: T$ ^- G                while( GetQueue( writetime, q ) ) {2 R3 o% y, M/ H& O* d2 f
                        WriteProcess( q.addr, q.data );
! ~3 b4 r8 O' y                }
8 z0 _( L7 C% k! H
& p/ }) ^/ L; t: K                while( GetExQueue( writetime, q ) ) {' K% P0 z, [) V  R1 {8 Z4 w
                        WriteExProcess( q.addr, q.data );
+ Q8 f6 v1 X4 a, \! {: b                }2 @' w4 f; q& j! S- ?. s( N
5 e8 B$ U0 W* |$ G
                // 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME75 j( Q# N% ^% q% x; A9 `# d
                output = 0;
; Z! f& w/ M0 {5 ]( _                output += internal.Process( 0 )*vol[0];
. B7 W8 j+ ~" g4 ]                output += internal.Process( 1 )*vol[1];  X* ^7 J: \0 m3 X3 `
                output += internal.Process( 2 )*vol[2];
" E. @' q. P! B3 k                output += internal.Process( 3 )*vol[3];
' W5 Q* ~4 V0 B8 c8 r- _                output += internal.Process( 4 )*vol[4];
0 b" D. y7 J; p. q; k8 f( q3 d( w1 N
                if( exsound_select & 0x01 ) {8 `# {; J) P* ~. g
                        output += vrc6.Process( 0 )*vol[5];
5 K# j# b6 N: m: \5 U. s, [                        output += vrc6.Process( 1 )*vol[6];! x; J4 C6 X) j. O
                        output += vrc6.Process( 2 )*vol[7];. s& W( B8 c# N' M( Z( h& @2 H0 {; J' D
                }
  K) t( o% m: ^/ m& x                if( exsound_select & 0x02 ) {
2 T+ V7 N2 I4 u% f                        output += vrc7.Process( 0 )*vol[8];- k1 p0 n9 K0 H6 z- w
                }5 r& t, N4 V7 t1 x- ^* Z" N" d* |% K
                if( exsound_select & 0x04 ) {7 h/ K% ~9 L9 T% c
                        output += fds.Process( 0 )*vol[9];
, b( E( ], [, O( u# r3 D% O                }
0 J9 Q/ D; Z" Y' j) Z/ A                if( exsound_select & 0x08 ) {+ T) r* ^/ l! [5 o
                        output += mmc5.Process( 0 )*vol[10];
" _$ [  I3 r4 y& D, R" j6 ]                        output += mmc5.Process( 1 )*vol[11];
6 r/ ]; A3 w- a4 q) E. k% z+ C                        output += mmc5.Process( 2 )*vol[12];9 C; C; P# k9 V1 O5 H, \
                }4 k1 |) p& P' Q: l+ {
                if( exsound_select & 0x10 ) {
2 }0 I, _/ @% G                        output += n106.Process( 0 )*vol[13];
! R- J* `5 w, e- N2 `                        output += n106.Process( 1 )*vol[14];
' C2 Z/ y* ^5 r/ J' L                        output += n106.Process( 2 )*vol[15];& I/ `. k* E5 w; [$ T, i: _; y
                        output += n106.Process( 3 )*vol[16];
# I* J: {0 Y$ T9 L, i! v                        output += n106.Process( 4 )*vol[17];
3 Z' o! o, N( f# j% I                        output += n106.Process( 5 )*vol[18];% G( Y" p) v5 s
                        output += n106.Process( 6 )*vol[19];- }9 Z2 H; ?* v9 T2 p* G% o
                        output += n106.Process( 7 )*vol[20];% Z' O8 ^8 c2 X1 N8 |& r
                }7 Y" U& U3 k! ]' G! P
                if( exsound_select & 0x20 ) {/ @3 B  n5 W# A9 W/ U# R1 W
                        fme7.Process( 3 );        // Envelope & Noise
8 f* J9 H! G5 K8 c                        output += fme7.Process( 0 )*vol[21];7 Z9 d4 ~# ~, `
                        output += fme7.Process( 1 )*vol[22];3 o& d* a2 s$ d. W& o' k' k0 o
                        output += fme7.Process( 2 )*vol[23];
! Q9 D: f! @* R1 H$ c) z( x                }
: t) Q0 n, u7 n8 `- \. g+ z! Y: N7 Y; r
                output >>= 8;
. H$ o! i* A3 z. G5 p3 v
) G- @& X- d1 U- I7 b+ N+ u                if( nFilterType == 1 ) {9 T" {! j' Y6 n5 C; k6 b
                        //儘乕僷僗僼傿儖僞乕TYPE 1(Simple)
- ~. }2 h  v" [+ Z3 n3 ^                        output = (lowpass_filter[0]+output)/2;3 }( i0 r: r( V3 e9 U: a8 }5 y8 Z
                        lowpass_filter[0] = output;
+ N! [: L! I6 S* k! d                } else if( nFilterType == 2 ) {- j& [$ u6 F: x
                        //儘乕僷僗僼傿儖僞乕TYPE 2(Weighted type 1)
6 `# N% ?5 [  P+ r                        output = (lowpass_filter[1]+lowpass_filter[0]+output)/3;
  J, H5 v2 d6 R0 J; Q4 C                        lowpass_filter[1] = lowpass_filter[0];
# Z! ~( x2 z! x  d* q' T# J! T                        lowpass_filter[0] = output;1 ]- f: s. e$ Y' F' v! Y; M
                } else if( nFilterType == 3 ) {0 C3 a9 a% j/ ^1 i" V
                        //儘乕僷僗僼傿儖僞乕TYPE 3(Weighted type 2)% G$ t' s# @- p& r! `
                        output = (lowpass_filter[2]+lowpass_filter[1]+lowpass_filter[0]+output)/4;- \1 \4 y- [. \
                        lowpass_filter[2] = lowpass_filter[1];
$ s4 \. y4 u0 j- S: k                        lowpass_filter[1] = lowpass_filter[0];
- m% L$ N8 s. R! W3 t                        lowpass_filter[0] = output;
( z! C/ R% _3 F5 w                } else if( nFilterType == 4 ) {% c" W: F: b) R
                        //儘乕僷僗僼傿儖僞乕TYPE 4(Weighted type 3)
8 H+ h5 S1 w' m* W0 A: g4 z                        output = (lowpass_filter[1]+lowpass_filter[0]*2+output)/4;( `1 @7 x0 k3 o: I
                        lowpass_filter[1] = lowpass_filter[0];- e, {: q( g% U' b1 d+ [
                        lowpass_filter[0] = output;$ k4 u1 V  W! M, B
                }
- V% q, G! P5 y; Q) y. t& _9 l" Y/ B5 d9 W* G8 o8 R# s
#if        0' [$ E9 v) q; f4 f% L; N
                // DC惉暘偺僇僢僩2 q, R/ O$ Y1 m% y! y) Y
                {
7 \8 ~. i; H) f                static double ave = 0.0, max=0.0, min=0.0;% ~: y1 v9 l) R' P; Y0 V" w, e" t
                double delta;$ j" m- P; ^* z% Y0 m
                delta = (max-min)/32768.0;
, _* B* N( F) e' p. o4 X                max -= delta;
. U% i" Y  @6 F1 o: k; |                min += delta;- ~4 {+ @3 I# i- b6 k1 Y& x
                if( output > max ) max = output;$ N) t" T+ }8 q2 {0 W& {0 H" D
                if( output < min ) min = output;" j" R1 }) k: i6 t
                ave -= ave/1024.0;( _4 Z4 w, O1 |* }
                ave += (max+min)/2048.0;% `) X. _% L6 x
                output -= (INT)ave;
# J, l; S4 K) h+ j  e4 P. z                }
3 h# o" I0 E3 }5 w0 i. P#endif
  U- t" U4 t  g% F$ C! U7 p#if        1
7 [$ G7 O$ Y) J0 P" U                // DC惉暘偺僇僢僩(HPF TEST)" b$ H- t3 d  C7 e" h6 l
                {$ {. S7 ^, [/ i5 i' G" t% a* u
//                static        double        cutoff = (2.0*3.141592653579*40.0/44100.0);
# O; E* K* C/ G/ N! ^/ e                static        double        cutofftemp = (2.0*3.141592653579*40.0);. `2 F. c* a; H/ f' d! s+ l1 X
                double        cutoff = cutofftemp/(double)Config.sound.nRate;5 l5 @  ]/ t0 `5 \* |
                static        double        tmp = 0.0;
$ b: R% R! {0 U9 e4 w                double        in, out;* q$ h8 [2 w9 ~
5 I' I2 c) q7 L" ^& H
                in = (double)output;7 L" N0 {/ [  v; g  U! p
                out = (in - tmp);
3 c( C# ?$ M0 b6 q' y9 ?                tmp = tmp + cutoff * out;; i) e/ J# g" \0 M1 |5 U* O
) f% f9 q4 y3 F$ S
                output = (INT)out;$ `# c9 L3 e5 z4 b2 D% p/ P; S, K( ?
                }
6 M- p8 V, I6 l7 M7 |5 ^#endif
7 F# @( S  g! A4 J$ d: b: F#if        0
: n9 h  Z- ?# g, W) \+ j                // 僗僷僀僋僲僀僘偺彍嫀(AGC TEST)
  C5 _+ k! v$ B9 u7 f6 ~                {
9 G1 Y9 d4 j$ ]# W                INT        diff = abs(output-last_data);
, T7 R% x0 F- K4 f6 V                if( diff > 0x4000 ) {
/ S$ ^: B1 y  ]$ z- D                        output /= 4;
2 H9 \/ |( s5 G' E+ R7 T                } else
  M  D4 O5 u5 I# v                if( diff > 0x3000 ) {( @8 n2 j$ j1 g9 w: C* f
                        output /= 3;: f3 U, r/ I* j; c/ \  T- L
                } else
1 t" O& c3 f8 c                if( diff > 0x2000 ) {
' @6 {8 }% \$ h) ?  v* |- U                        output /= 2;
; P) u( }5 J, _9 @+ _                }
2 k4 R7 U3 M; `0 Q  W8 y                last_data = output;
" h  t$ C& ]/ p* }                }
" B5 ^7 j. x  k8 A  m1 ~#endif
! p: l$ M* W* w7 J8 G  w# L& G' s                // Limit) n# \3 J& Z! N- N' A1 J7 u: M
                if( output > 0x7FFF ) {. S; r! {4 k, D0 Q2 f6 w% l
                        output = 0x7FFF;
% v2 \% X" g- G8 N! m6 S6 A                } else if( output < -0x8000 ) {& b4 p' I% b1 S% K8 ^
                        output = -0x8000;
) N' x( h. M, u' z. t" H                }8 {; {' }0 Y8 Z( C8 l/ N! B/ |

) l/ t6 l  H9 z' k  q+ s                if( nBits != 8 ) {
+ r- s3 R# {5 h                        *(SHORT*)lpBuffer = (SHORT)output;
  v& h5 ?/ E0 G                        lpBuffer += sizeof(SHORT);
9 D: h, s3 k2 ^% H5 U+ j2 S                } else {5 Z" ^6 R* s, {
                        *lpBuffer++ = (output>>8)^0x80;$ Y/ H" {" ]# p8 M6 o, d4 Y
                }
, L8 O! E! ?' s
% q; ?. k0 V+ \5 F; y) {2 S                if( nCcount < 0x0100 )/ V$ g$ t4 m7 c
                        pSoundBuf[nCcount++] = (SHORT)output;
$ L4 u8 _0 y0 U7 W" V9 X8 {4 s; u6 A  j1 \/ R$ e5 A' q  Q' O
//                elapsedtime += cycle_rate;' |9 |, {8 a6 L4 \- \7 t# K
                elapsed_time += cycle_rate;$ V5 R! ]2 H. F9 h# r/ i% q- K: I
        }
3 K  S3 @6 Z' j* _( f: v- U9 k% N- S  C, R
#if        1
: r! L: f, u+ e8 B+ V7 q( m, }2 V/ @        if( elapsed_time > ((nes->nescfg->FrameCycles/24)+nes->cpu->GetTotalCycles()) ) {
; T7 ]0 V# s# k6 ~+ x% K                elapsed_time = nes->cpu->GetTotalCycles();4 N) V5 b1 e& [+ c8 z. n7 p1 O
        }+ G) l3 S' Z  G1 E1 r: J( e" {# u
        if( (elapsed_time+(nes->nescfg->FrameCycles/6)) < nes->cpu->GetTotalCycles() ) {
6 ?7 y5 \* d! o                elapsed_time = nes->cpu->GetTotalCycles();
- U4 `# F+ C; r: h0 M2 L        }
! h7 c  Z4 ^2 B+ e#else& M8 `! @! b! \9 H( R. O$ @2 H
        elapsed_time = nes->cpu->GetTotalCycles();
7 G/ C) i) C: u* M5 j) W#endif7 s3 u; q* P7 j4 @
}6 r& m$ g7 k$ `
3 r6 ~5 ^+ k6 q  l" H
// 僠儍儞僱儖偺廃攇悢庢摼僒僽儖乕僠儞(NSF梡)1 I$ o& L" _6 _0 O5 p
INT        APU::GetChannelFrequency( INT no )
( D7 G7 }' S* u/ G3 h9 X8 m{+ [* [* m" E5 d$ g- M% z
        if( !m_bMute[0] )7 E) E6 Y  g2 x0 J1 E& u
                return        0;) a* Q% ^( w( Y

4 U/ `1 ?2 w4 [2 S7 O        // Internal
4 N) m# r  f4 G/ P, [1 B" C, ^5 y        if( no < 5 ) {5 _: Y6 K% n7 [( M# [
                return        m_bMute[no+1]?internal.GetFreq( no ):0;+ k( h! H2 b/ Z; f/ i
        }
$ n% i4 L! y- I7 T2 c        // VRC66 R* C3 k; y( n
        if( (exsound_select & 0x01) && no >= 0x0100 && no < 0x0103 ) {
7 c- L1 ?8 {1 \- c9 B& J/ d                return        m_bMute[6+(no&0x03)]?vrc6.GetFreq( no & 0x03 ):0;( e( ~, l& O! C; J6 s% c8 P
        }0 E' x/ [  p4 B" T
        // FDS
. {$ r9 u2 ]+ S9 R+ g, G        if( (exsound_select & 0x04) && no == 0x300 ) {
' m& v; V0 o8 M( b% p                return        m_bMute[6]?fds.GetFreq( 0 ):0;
9 E3 n" `' N7 p4 e6 j/ X* P5 H        }
/ _% ?# `+ U1 v$ c* H        // MMC5
& b6 {" [" _$ ^3 B# S        if( (exsound_select & 0x08) && no >= 0x0400 && no < 0x0402 ) {
2 R  O/ O; J& u) Y1 B9 {5 `                return        m_bMute[6+(no&0x03)]?mmc5.GetFreq( no & 0x03 ):0;4 O7 @8 F2 O# o0 @
        }' R% i* Z. u+ \
        // N106& e/ s& _/ D6 Q' Y+ v
        if( (exsound_select & 0x10) && no >= 0x0500 && no < 0x0508 ) {
9 N% Y( H+ I( m2 L                return        m_bMute[6+(no&0x07)]?n106.GetFreq( no & 0x07 ):0;
5 d$ e/ b8 b* Z0 s* V        }
; q8 {3 r; U, P- h5 j" R        // FME7/ W9 F% }8 A2 [6 F6 m. C% U
        if( (exsound_select & 0x20) && no >= 0x0600 && no < 0x0603 ) {
4 }( l9 X/ k5 k$ a1 J! y                return        m_bMute[6+(no&0x03)]?fme7.GetFreq( no & 0x03 ):0;
8 I; S+ C5 e/ l$ }7 ?- ^$ P' x        }6 I3 h9 i8 B+ Y8 B5 h& i
        // VRC7
( O8 l- C* T2 V7 C* x; K: x- {        if( (exsound_select & 0x02) && no >= 0x0700 && no < 0x0709 ) {2 I9 ~0 l/ E) g! V
                return        m_bMute[6]?vrc7.GetFreq(no&0x0F):0;# M( c' O5 r6 Q0 B: F, ~1 \+ ]/ I
        }
* C$ {7 J5 y$ Z# c. ^1 m        return        0;
: y0 e$ W" t' {- g}9 m6 v: H7 g% q

! ]/ g3 i. h$ h3 _) U// State Save/Load
" x; _' ^( x: k4 ^2 z9 B5 L2 u* b# Cvoid        APU::SaveState( LPBYTE p )
7 v  \; e; w7 p  l0 i( y( ^{2 y( f* y" N7 M3 K0 j
#ifdef        _DEBUG
' ?3 ~3 w0 s) z" }LPBYTE        pold = p;# |5 e4 M8 r2 d. c
#endif* L9 {, A' h8 O& N7 @1 D

. X4 j4 a/ Y/ l$ D* Z5 \$ Y        // 帪娫幉傪摨婜偝偣傞堊Flush偡傞% d1 x; u! N& T/ n
        QueueFlush();# e' H! t4 P) U, X4 G* e
1 A1 V: J; l) T' Z/ R7 Q  I1 x
        internal.SaveState( p );
3 x% w9 D4 J; [' p4 u        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding
  k" [0 L0 h7 p" W% P8 }  @% r3 H
        // VRC6' ]7 ]/ L! @1 i$ V  J9 N/ \0 A
        if( exsound_select & 0x01 ) {
) W5 S0 O+ S9 n  G0 @                vrc6.SaveState( p );& |. N* m, A4 o+ ~
                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding
8 `% B0 T7 ]# }+ U  ~        }) ]" V% `0 q* Z, _! b
        // VRC7 (not support)
( d5 X. r+ T) |+ u        if( exsound_select & 0x02 ) {# ]2 H3 Q. y3 [" X3 y4 }
                vrc7.SaveState( p );
2 d' t/ \" M0 @! [; P2 [" y8 O, f                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
: _6 q* F' A5 r        }; O3 Q9 ^- z/ ~) U. E' h& a
        // FDS
& Y( W# `# Q/ p        if( exsound_select & 0x04 ) {
7 z! s8 g- x' L" z                fds.SaveState( p );
$ g- c- ^0 M7 Z/ T% k+ M7 @2 D/ N                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding* v+ B* L6 r  U* v. h" z+ F
        }
3 j% g: u7 v. P        // MMC5
0 c0 H) ]0 g9 |  M8 b        if( exsound_select & 0x08 ) {
  D/ K- _5 w) ?& B0 b3 H                mmc5.SaveState( p );
1 l9 \" S3 C0 x, S/ [                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding" P1 d$ r/ H/ N# ?. B, |  Q: j3 G) F
        }& @2 _* U1 F/ Y1 r2 z: u: d
        // N106
) X2 ]" z8 y& a  I* \        if( exsound_select & 0x10 ) {- t3 U4 G' G: h7 ~( y/ t; C7 n0 @
                n106.SaveState( p );4 c" G* u# z/ x& p* B6 M" R" y! k
                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
- P$ U2 t, O+ y) J* N2 Y        }
' S% {8 ~$ P& M+ d& u5 q) ?        // FME7
' O& a' U. H% b& U2 h        if( exsound_select & 0x20 ) {
! Z0 A8 G3 p9 p3 t  B5 ~7 |- j                fme7.SaveState( p );! {# D; W0 ?$ V! }8 c& `
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding8 P+ a8 F8 m2 s0 t7 @$ k8 b  ]5 |
        }5 M- Q# m$ S/ N5 R9 m0 y( V% ?0 ^* \

6 }5 \% h4 U8 K% ?4 K#ifdef        _DEBUG5 }0 U8 B: D4 d
DEBUGOUT( "SAVE APU SIZE:%d\n", p-pold );
+ n: b. h) m9 C, o4 E#endif
6 [+ k8 g9 D8 f' ?, M3 S2 V}
, D" x. g$ ?8 ^6 z- }
: V8 _, [/ s+ L( ?9 O/ _6 x& lvoid        APU::LoadState( LPBYTE p ), {8 b3 X7 O$ o3 l/ {4 k0 U
{! W8 ^5 b& G7 ^/ e5 h$ X" q
        // 帪娫幉傪摨婜偝偣傞堊偵徚偡
5 t: j1 O: t5 G6 r4 T        QueueClear();* z- [7 f4 j* e

9 T$ a6 y* |) F4 l9 G9 n( L: F& O        internal.LoadState( p );/ d  j) \5 }" H7 G+ k& W' X. T
        p += (internal.GetStateSize()+15)&(~0x0F);        // Padding/ J" e4 Q' b, {/ [# Z+ w
4 W: b% |1 E& i0 W4 z9 m
        // VRC6) W8 B" l2 P, f$ V
        if( exsound_select & 0x01 ) {
1 P8 h! r! Y$ \. W& m9 M5 ~, O                vrc6.LoadState( p );
7 s. h9 ~  U+ H  r- f                p += (vrc6.GetStateSize()+15)&(~0x0F);        // Padding: {2 k+ ], W" f" P; I5 ?/ P
        }3 c$ ~# V, x4 l8 H* [
        // VRC7 (not support)
5 K3 H+ I  L  m# d! G: K# Q: S1 `        if( exsound_select & 0x02 ) {: h* g/ D! j! `5 n/ [/ Y
                vrc7.LoadState( p );* r* J7 o+ y  o7 [3 d
                p += (vrc7.GetStateSize()+15)&(~0x0F);        // Padding
: g- o5 u) i- _' q  c1 ^        }
7 {/ f) P- g: j% i        // FDS
5 Q# |, f3 ?: d# o$ ^8 Z+ P        if( exsound_select & 0x04 ) {
" }9 \; {6 @8 A& M9 T1 X$ W                fds.LoadState( p );
, \% Z' W$ M1 _2 Q% m% V                p += (fds.GetStateSize()+15)&(~0x0F);        // Padding
$ `- m9 I# u: V' I        }8 y5 d! k+ P6 j, U4 @+ J) o
        // MMC5- B7 U8 Q8 I8 o) Y9 Z5 V
        if( exsound_select & 0x08 ) {
& x, @, C1 L7 s- R9 S5 w                mmc5.LoadState( p );7 B! z' X* H$ ]# P5 g9 U: L3 U
                p += (mmc5.GetStateSize()+15)&(~0x0F);        // Padding' G+ F5 H, u! w/ I
        }& @* A" G+ j5 l2 C3 X. h/ i
        // N1067 ]+ W( E! ?$ `1 S
        if( exsound_select & 0x10 ) {
* Z  U9 h# V0 j. p5 `( B1 Q                n106.LoadState( p );
' R) i( p0 \) b; ~2 W                p += (n106.GetStateSize()+15)&(~0x0F);        // Padding
( n: P& r9 @0 w& D        }/ a2 ~: Z- W) S) l  E- x: v
        // FME7) q4 k4 h. B, c6 f' \' x; _
        if( exsound_select & 0x20 ) {
6 v/ t- \/ K6 e- H$ j9 ~6 \                fme7.LoadState( p );* Z: X+ j5 t* z
                p += (fme7.GetStateSize()+15)&(~0x0F);        // Padding
3 I. ~0 c+ p8 w" F        }8 a( U& _0 r7 K7 Q) ?" p
}

该用户从未签到

发表于 2009-11-8 17:25:37 | 显示全部楼层
原帖由 独孤残云 于 2009-11-8 14:38 发表 ' {, i, V6 |4 X* S* F: k& R$ g
可以的话,希望可以得到krizal团长大人或者哪位大侠的详细赐教,就是指Apu模块下这些函数的具体含义和作用。我对这些NES机制的算法很感兴趣。
: k2 U. b( B. N$ }3 I感激不尽~~
* A( D0 ~0 i# \/ z8 I. `* l
恩 我對模擬器不是很有研究,7 f) T' c4 X. w8 m2 b$ k
雖然要了解源碼內容,可能不是很困難,
/ y9 G2 t# m6 S& ]/ H( F- {5 [+ _" X不過還是要花時間,個人目前蠻忙碌的。6 O8 S4 p! g) k3 E. Z
# N% A' l$ [, Q; d' C# ]
給你一個朋友的MSN,你可以跟他討論看看,
. q1 k. U; ?7 J  F9 X他本身是程式設計師,也對FC模擬器很有興趣。
$ @$ J  z  n4 {+ n/ F5 k
8 _+ W7 J& Z( J' GMSN我就PM到你的信箱了。% q* S5 v* q7 Q) T7 _# U8 J

# `# |! h* w! o/ m0 \希望你能有所得。

该用户从未签到

 楼主| 发表于 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 发表
; P8 `8 z1 Q* X2 P' ?4 j呵…… 谢过团长大人~~
$ Q  c1 X$ w# K" h4 @: r2 P( |. }& h
+ x/ T6 V- v2 C- g5 P
哈 不客氣,算是順便幫他找個伴,大家可以一起玩。

该用户从未签到

发表于 2009-11-20 13:14:53 | 显示全部楼层
原帖由 李伟 于 2009-11-9 16:02 发表
/ p" I* C, y7 ]& S* d5 Z6 O团长的朋友都是神,那团长就是神的boss。

- G9 ]" L9 ?$ x# j" R3 N2 q哈 不敢當,我只是個平凡人,# w2 h5 [2 V6 |, V6 G1 U1 _6 e' ^5 C
要吃飯喝水,光吸空氣是不會飽的。。。。 :)

该用户从未签到

发表于 2009-11-20 13:32:35 | 显示全部楼层
FC模拟器的部分有个人可以帮你忙8 P6 K! n7 L6 ]" i/ @# {# _' Q6 H; u- E
ZYH. S5 D1 k4 J* i8 B
QQ:414734306" I; l! ]$ D7 \5 d8 o: @
Mail:zyh-01@126.com
, R( @, X& w) z7 v* \
& Q6 Z, W3 j; E. T4 ^4 ~他是ZYH Emulator这个模拟器的作者,只是他用的开发平台是VB,不过就6502的实现原理来说是一样的

该用户从未签到

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

该用户从未签到

发表于 2009-11-27 19:09:06 | 显示全部楼层
原帖由 独孤残云 于 2009-11-27 09:48 发表 , H1 a6 m' _; J3 G7 M2 h5 c
再次对团长大人和悠悠哥的无私帮助表示感谢~~
) x+ ~' v0 o& \- A  n* {# M
不客氣  ^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-12-1 19:52 , Processed in 1.070312 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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