mirror of
https://github.com/dborth/snes9xgx.git
synced 2024-11-30 14:34:22 +01:00
upstream changes. change sound defaults
This commit is contained in:
parent
723010768b
commit
4e752fceb8
@ -450,11 +450,12 @@ DefaultSettings ()
|
|||||||
Settings.HDMATimingHack = 100;
|
Settings.HDMATimingHack = 100;
|
||||||
|
|
||||||
// Sound defaults. On Wii this is 32Khz/16bit/Stereo
|
// Sound defaults. On Wii this is 32Khz/16bit/Stereo
|
||||||
|
Settings.SoundSync = true;
|
||||||
Settings.SixteenBitSound = true;
|
Settings.SixteenBitSound = true;
|
||||||
Settings.Stereo = true;
|
Settings.Stereo = true;
|
||||||
Settings.ReverseStereo = true;
|
Settings.ReverseStereo = true;
|
||||||
Settings.SoundPlaybackRate = 32000;
|
Settings.SoundPlaybackRate = 32000;
|
||||||
Settings.SoundInputRate = 31950;
|
Settings.SoundInputRate = 32000;
|
||||||
|
|
||||||
// Graphics
|
// Graphics
|
||||||
Settings.Transparency = true;
|
Settings.Transparency = true;
|
||||||
|
@ -180,15 +180,17 @@
|
|||||||
#include "apu.h"
|
#include "apu.h"
|
||||||
#include "snapshot.h"
|
#include "snapshot.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "resampler.h"
|
#include "linear_resampler.h"
|
||||||
|
#include "hermite_resampler.h"
|
||||||
|
|
||||||
#define APU_DEFAULT_INPUT_RATE 32000
|
#define APU_DEFAULT_INPUT_RATE 32000
|
||||||
#define APU_MINIMUM_SAMPLE_COUNT 512
|
#define APU_MINIMUM_SAMPLE_COUNT 512
|
||||||
#define APU_MINIMUM_SAMPLE_BLOCK 128
|
#define APU_MINIMUM_SAMPLE_BLOCK 128
|
||||||
#define APU_NUMERATOR_NTSC 5632
|
#define APU_NUMERATOR_NTSC 15664
|
||||||
#define APU_DENOMINATOR_NTSC 118125
|
#define APU_DENOMINATOR_NTSC 328125
|
||||||
#define APU_NUMERATOR_PAL 102400
|
#define APU_NUMERATOR_PAL 34176
|
||||||
#define APU_DENOMINATOR_PAL 2128137
|
#define APU_DENOMINATOR_PAL 709379
|
||||||
|
#define APU_DEFAULT_RESAMPLER HermiteResampler
|
||||||
|
|
||||||
SNES_SPC *spc_core = NULL;
|
SNES_SPC *spc_core = NULL;
|
||||||
|
|
||||||
@ -224,8 +226,12 @@ namespace spc
|
|||||||
static int32 reference_time;
|
static int32 reference_time;
|
||||||
static uint32 remainder;
|
static uint32 remainder;
|
||||||
|
|
||||||
static const int32 timing_hack_numerator = SNES_SPC::tempo_unit;
|
static const int timing_hack_numerator = SNES_SPC::tempo_unit;
|
||||||
static int32 timing_hack_denominator = SNES_SPC::tempo_unit;
|
static int timing_hack_denominator = SNES_SPC::tempo_unit;
|
||||||
|
/* Set these to NTSC for now. Will change to PAL in S9xAPUTimingSetSpeedup
|
||||||
|
if necessary on game load. */
|
||||||
|
static uint32 ratio_numerator = APU_NUMERATOR_NTSC;
|
||||||
|
static uint32 ratio_denominator = APU_DENOMINATOR_NTSC;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EightBitize (uint8 *, int);
|
static void EightBitize (uint8 *, int);
|
||||||
@ -445,7 +451,7 @@ bool8 S9xInitSound (int buffer_ms, int lag_ms)
|
|||||||
arguments. Use 2x in the resampler for buffer leveling with SoundSync */
|
arguments. Use 2x in the resampler for buffer leveling with SoundSync */
|
||||||
if (!spc::resampler)
|
if (!spc::resampler)
|
||||||
{
|
{
|
||||||
spc::resampler = new Resampler(spc::buffer_size >> (Settings.SoundSync ? 0 : 1));
|
spc::resampler = new APU_DEFAULT_RESAMPLER(spc::buffer_size >> (Settings.SoundSync ? 0 : 1));
|
||||||
if (!spc::resampler)
|
if (!spc::resampler)
|
||||||
{
|
{
|
||||||
delete[] spc::landing_buffer;
|
delete[] spc::landing_buffer;
|
||||||
@ -534,22 +540,14 @@ void S9xDeinitAPU (void)
|
|||||||
|
|
||||||
static inline int S9xAPUGetClock (int32 cpucycles)
|
static inline int S9xAPUGetClock (int32 cpucycles)
|
||||||
{
|
{
|
||||||
if (Settings.PAL)
|
return (spc::ratio_numerator * (cpucycles - spc::reference_time) + spc::remainder) /
|
||||||
return ((int) floor(((double) APU_NUMERATOR_PAL * spc::timing_hack_numerator * (cpucycles - spc::reference_time) + spc::remainder) /
|
spc::ratio_denominator;
|
||||||
((double) APU_DENOMINATOR_PAL * spc::timing_hack_denominator)));
|
|
||||||
else
|
|
||||||
return (APU_NUMERATOR_NTSC * spc::timing_hack_numerator * (cpucycles - spc::reference_time) + spc::remainder) /
|
|
||||||
(APU_DENOMINATOR_NTSC * spc::timing_hack_denominator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int S9xAPUGetClockRemainder (int32 cpucycles)
|
static inline int S9xAPUGetClockRemainder (int32 cpucycles)
|
||||||
{
|
{
|
||||||
if (Settings.PAL)
|
return (spc::ratio_numerator * (cpucycles - spc::reference_time) + spc::remainder) %
|
||||||
return ((int) fmod (((double) APU_NUMERATOR_PAL * spc::timing_hack_numerator * (cpucycles - spc::reference_time) + spc::remainder),
|
spc::ratio_denominator;
|
||||||
((double) APU_DENOMINATOR_PAL * spc::timing_hack_denominator)));
|
|
||||||
else
|
|
||||||
return (APU_NUMERATOR_NTSC * spc::timing_hack_numerator * (cpucycles - spc::reference_time) + spc::remainder) %
|
|
||||||
(APU_DENOMINATOR_NTSC * spc::timing_hack_denominator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 S9xAPUReadPort (int port)
|
uint8 S9xAPUReadPort (int port)
|
||||||
@ -590,9 +588,12 @@ void S9xAPUTimingSetSpeedup (int ticks)
|
|||||||
if (ticks != 0)
|
if (ticks != 0)
|
||||||
printf("APU speedup hack: %d\n", ticks);
|
printf("APU speedup hack: %d\n", ticks);
|
||||||
|
|
||||||
spc_core->set_tempo(SNES_SPC::tempo_unit - ticks);
|
|
||||||
|
|
||||||
spc::timing_hack_denominator = SNES_SPC::tempo_unit - ticks;
|
spc::timing_hack_denominator = SNES_SPC::tempo_unit - ticks;
|
||||||
|
spc_core->set_tempo(spc::timing_hack_denominator);
|
||||||
|
|
||||||
|
spc::ratio_numerator = Settings.PAL ? APU_NUMERATOR_PAL : APU_NUMERATOR_NTSC;
|
||||||
|
spc::ratio_denominator = Settings.PAL ? APU_DENOMINATOR_PAL : APU_DENOMINATOR_NTSC;
|
||||||
|
spc::ratio_denominator = spc::ratio_denominator * spc::timing_hack_denominator / spc::timing_hack_numerator;
|
||||||
|
|
||||||
UpdatePlaybackRate();
|
UpdatePlaybackRate();
|
||||||
}
|
}
|
||||||
|
144
source/snes9x/apu/hermite_resampler.h
Normal file
144
source/snes9x/apu/hermite_resampler.h
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/* Simple resampler based on bsnes's ruby audio library */
|
||||||
|
|
||||||
|
#ifndef __HERMITE_RESAMPLER_H
|
||||||
|
#define __HERMITE_RESAMPLER_H
|
||||||
|
|
||||||
|
#include "resampler.h"
|
||||||
|
|
||||||
|
#undef CLAMP
|
||||||
|
#undef SHORT_CLAMP
|
||||||
|
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
|
||||||
|
#define SHORT_CLAMP(n) ((short) CLAMP((n), -32768, 32767))
|
||||||
|
|
||||||
|
class HermiteResampler : public Resampler
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
double r_step;
|
||||||
|
double r_frac;
|
||||||
|
int r_left[4], r_right[4];
|
||||||
|
|
||||||
|
double
|
||||||
|
hermite (double mu1, double a, double b, double c, double d)
|
||||||
|
{
|
||||||
|
const double tension = 0.0; //-1 = low, 0 = normal, 1 = high
|
||||||
|
const double bias = 0.0; //-1 = left, 0 = even, 1 = right
|
||||||
|
|
||||||
|
double mu2, mu3, m0, m1, a0, a1, a2, a3;
|
||||||
|
|
||||||
|
mu2 = mu1 * mu1;
|
||||||
|
mu3 = mu2 * mu1;
|
||||||
|
|
||||||
|
m0 = (b - a) * (1 + bias) * (1 - tension) / 2;
|
||||||
|
m0 += (c - b) * (1 - bias) * (1 - tension) / 2;
|
||||||
|
m1 = (c - b) * (1 + bias) * (1 - tension) / 2;
|
||||||
|
m1 += (d - c) * (1 - bias) * (1 - tension) / 2;
|
||||||
|
|
||||||
|
a0 = +2 * mu3 - 3 * mu2 + 1;
|
||||||
|
a1 = mu3 - 2 * mu2 + mu1;
|
||||||
|
a2 = mu3 - mu2;
|
||||||
|
a3 = -2 * mu3 + 3 * mu2;
|
||||||
|
|
||||||
|
return (a0 * b) + (a1 * m0) + (a2 * m1) + (a3 * c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
HermiteResampler (int num_samples) : Resampler (num_samples)
|
||||||
|
{
|
||||||
|
clear ();
|
||||||
|
}
|
||||||
|
|
||||||
|
~HermiteResampler ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
time_ratio (double ratio)
|
||||||
|
{
|
||||||
|
r_step = ratio;
|
||||||
|
clear ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clear (void)
|
||||||
|
{
|
||||||
|
ring_buffer::clear ();
|
||||||
|
r_frac = 1.0;
|
||||||
|
r_left [0] = r_left [1] = r_left [2] = r_left [3] = 0;
|
||||||
|
r_right[0] = r_right[1] = r_right[2] = r_right[3] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
read (short *data, int num_samples)
|
||||||
|
{
|
||||||
|
int i_position = start >> 1;
|
||||||
|
short *internal_buffer = (short *) buffer;
|
||||||
|
int o_position = 0;
|
||||||
|
int consumed = 0;
|
||||||
|
|
||||||
|
while (o_position < num_samples && consumed < buffer_size)
|
||||||
|
{
|
||||||
|
int s_left = internal_buffer[i_position];
|
||||||
|
int s_right = internal_buffer[i_position + 1];
|
||||||
|
int max_samples = buffer_size >> 1;
|
||||||
|
const double margin_of_error = 1.0e-10;
|
||||||
|
|
||||||
|
if (fabs(r_step - 1.0) < margin_of_error)
|
||||||
|
{
|
||||||
|
data[o_position] = (short) s_left;
|
||||||
|
data[o_position + 1] = (short) s_right;
|
||||||
|
|
||||||
|
o_position += 2;
|
||||||
|
i_position += 2;
|
||||||
|
if (i_position >= max_samples)
|
||||||
|
i_position -= max_samples;
|
||||||
|
consumed += 2;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (r_frac <= 1.0 && o_position < num_samples)
|
||||||
|
{
|
||||||
|
data[o_position] = SHORT_CLAMP (hermite (r_frac, r_left [0], r_left [1], r_left [2], r_left [3]));
|
||||||
|
data[o_position + 1] = SHORT_CLAMP (hermite (r_frac, r_right[0], r_right[1], r_right[2], r_right[3]));
|
||||||
|
|
||||||
|
o_position += 2;
|
||||||
|
|
||||||
|
r_frac += r_step;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r_frac > 1.0)
|
||||||
|
{
|
||||||
|
r_left [0] = r_left [1];
|
||||||
|
r_left [1] = r_left [2];
|
||||||
|
r_left [2] = r_left [3];
|
||||||
|
r_left [3] = s_left;
|
||||||
|
|
||||||
|
r_right[0] = r_right[1];
|
||||||
|
r_right[1] = r_right[2];
|
||||||
|
r_right[2] = r_right[3];
|
||||||
|
r_right[3] = s_right;
|
||||||
|
|
||||||
|
r_frac -= 1.0;
|
||||||
|
|
||||||
|
i_position += 2;
|
||||||
|
if (i_position >= max_samples)
|
||||||
|
i_position -= max_samples;
|
||||||
|
consumed += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size -= consumed << 1;
|
||||||
|
start += consumed << 1;
|
||||||
|
if (start >= buffer_size)
|
||||||
|
start -= buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int
|
||||||
|
avail (void)
|
||||||
|
{
|
||||||
|
return (int) floor (((size >> 2) - r_frac) / r_step) * 2;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __HERMITE_RESAMPLER_H */
|
File diff suppressed because it is too large
Load Diff
115
source/snes9x/apu/linear_resampler.h
Normal file
115
source/snes9x/apu/linear_resampler.h
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/* Simple fixed-point linear resampler by BearOso*/
|
||||||
|
|
||||||
|
#ifndef __LINEAR_RESAMPLER_H
|
||||||
|
#define __LINEAR_RESAMPLER_H
|
||||||
|
|
||||||
|
#include "resampler.h"
|
||||||
|
#include "snes9x.h"
|
||||||
|
|
||||||
|
static const int f_prec = 15;
|
||||||
|
static const uint32 f__one = (1 << f_prec);
|
||||||
|
|
||||||
|
#define lerp(t, a, b) (((((b) - (a)) * (t)) >> f_prec) + (a))
|
||||||
|
|
||||||
|
class LinearResampler : public Resampler
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
uint32 f__r_step;
|
||||||
|
uint32 f__inv_r_step;
|
||||||
|
uint32 f__r_frac;
|
||||||
|
int r_left, r_right;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LinearResampler (int num_samples) : Resampler (num_samples)
|
||||||
|
{
|
||||||
|
f__r_frac = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
~LinearResampler ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
time_ratio (double ratio)
|
||||||
|
{
|
||||||
|
if (ratio == 0.0)
|
||||||
|
ratio = 1.0;
|
||||||
|
f__r_step = (uint32) (ratio * f__one);
|
||||||
|
f__inv_r_step = (uint32) (f__one / ratio);
|
||||||
|
clear ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clear (void)
|
||||||
|
{
|
||||||
|
ring_buffer::clear ();
|
||||||
|
f__r_frac = 0;
|
||||||
|
r_left = 0;
|
||||||
|
r_right = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
read (short *data, int num_samples)
|
||||||
|
{
|
||||||
|
int i_position = start >> 1;
|
||||||
|
short *internal_buffer = (short *) buffer;
|
||||||
|
int o_position = 0;
|
||||||
|
int consumed = 0;
|
||||||
|
int max_samples = (buffer_size >> 1);
|
||||||
|
|
||||||
|
while (o_position < num_samples && consumed < buffer_size)
|
||||||
|
{
|
||||||
|
if (f__r_step == f__one)
|
||||||
|
{
|
||||||
|
data[o_position] = internal_buffer[i_position];
|
||||||
|
data[o_position + 1] = internal_buffer[i_position + 1];
|
||||||
|
|
||||||
|
o_position += 2;
|
||||||
|
i_position += 2;
|
||||||
|
if (i_position >= max_samples)
|
||||||
|
i_position -= max_samples;
|
||||||
|
consumed += 2;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (f__r_frac <= f__one && o_position < num_samples)
|
||||||
|
{
|
||||||
|
data[o_position] = lerp (f__r_frac,
|
||||||
|
r_left,
|
||||||
|
internal_buffer[i_position]);
|
||||||
|
data[o_position + 1] = lerp (f__r_frac,
|
||||||
|
r_right,
|
||||||
|
internal_buffer[i_position + 1]);
|
||||||
|
|
||||||
|
o_position += 2;
|
||||||
|
|
||||||
|
f__r_frac += f__r_step;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f__r_frac > f__one)
|
||||||
|
{
|
||||||
|
f__r_frac -= f__one;
|
||||||
|
r_left = internal_buffer[i_position];
|
||||||
|
r_right = internal_buffer[i_position + 1];
|
||||||
|
i_position += 2;
|
||||||
|
if (i_position >= max_samples)
|
||||||
|
i_position -= max_samples;
|
||||||
|
consumed += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size -= consumed << 1;
|
||||||
|
start += consumed << 1;
|
||||||
|
if (start >= buffer_size)
|
||||||
|
start -= buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int
|
||||||
|
avail (void)
|
||||||
|
{
|
||||||
|
return (((size >> 2) * f__inv_r_step) - ((f__r_frac * f__inv_r_step) >> f_prec)) >> (f_prec - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __LINEAR_RESAMPLER_H */
|
@ -5,158 +5,56 @@
|
|||||||
|
|
||||||
#include "ring_buffer.h"
|
#include "ring_buffer.h"
|
||||||
|
|
||||||
#undef MIN
|
|
||||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
|
||||||
|
|
||||||
#undef CLAMP
|
|
||||||
#undef short_clamp
|
|
||||||
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
|
|
||||||
#define short_clamp(n) ((short) CLAMP((n), -32768, 32767))
|
|
||||||
|
|
||||||
class Resampler : public ring_buffer
|
class Resampler : public ring_buffer
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
|
|
||||||
double r_step;
|
|
||||||
double r_frac;
|
|
||||||
int r_left[4], r_right[4];
|
|
||||||
|
|
||||||
double
|
|
||||||
hermite (double mu1, double a, double b, double c, double d)
|
|
||||||
{
|
|
||||||
const double tension = 0.0; //-1 = low, 0 = normal, 1 = high
|
|
||||||
const double bias = 0.0; //-1 = left, 0 = even, 1 = right
|
|
||||||
|
|
||||||
double mu2, mu3, m0, m1, a0, a1, a2, a3;
|
|
||||||
|
|
||||||
mu2 = mu1 * mu1;
|
|
||||||
mu3 = mu2 * mu1;
|
|
||||||
|
|
||||||
m0 = (b - a) * (1 + bias) * (1 - tension) / 2;
|
|
||||||
m0 += (c - b) * (1 - bias) * (1 - tension) / 2;
|
|
||||||
m1 = (c - b) * (1 + bias) * (1 - tension) / 2;
|
|
||||||
m1 += (d - c) * (1 - bias) * (1 - tension) / 2;
|
|
||||||
|
|
||||||
a0 = +2 * mu3 - 3 * mu2 + 1;
|
|
||||||
a1 = mu3 - 2 * mu2 + mu1;
|
|
||||||
a2 = mu3 - mu2;
|
|
||||||
a3 = -2 * mu3 + 3 * mu2;
|
|
||||||
|
|
||||||
return (a0 * b) + (a1 * m0) + (a2 * m1) + (a3 * c);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
virtual void clear (void) = 0;
|
||||||
|
virtual void time_ratio (double) = 0;
|
||||||
|
virtual void read (short *, int) = 0;
|
||||||
|
virtual int avail (void) = 0;
|
||||||
|
|
||||||
Resampler (int num_samples) : ring_buffer (num_samples << 1)
|
Resampler (int num_samples) : ring_buffer (num_samples << 1)
|
||||||
{
|
{
|
||||||
r_frac = 0.0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~Resampler ()
|
~Resampler ()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
inline bool
|
||||||
time_ratio (double ratio)
|
|
||||||
{
|
|
||||||
r_step = ratio;
|
|
||||||
clear ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
clear (void)
|
|
||||||
{
|
|
||||||
ring_buffer::clear ();
|
|
||||||
r_frac = 0;
|
|
||||||
r_left [0] = r_left [1] = r_left [2] = r_left [3] = 0;
|
|
||||||
r_right[0] = r_right[1] = r_right[2] = r_right[3] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
read (short *data, int num_samples)
|
|
||||||
{
|
|
||||||
int i_position = start >> 1;
|
|
||||||
short *internal_buffer = (short *) buffer;
|
|
||||||
int o_position = 0;
|
|
||||||
int consumed = 0;
|
|
||||||
|
|
||||||
while (o_position < num_samples && consumed < buffer_size)
|
|
||||||
{
|
|
||||||
int s_left = internal_buffer[i_position];
|
|
||||||
int s_right = internal_buffer[i_position + 1];
|
|
||||||
const double margin_of_error = 1.0e-10;
|
|
||||||
|
|
||||||
if (fabs(r_step - 1.0) < margin_of_error)
|
|
||||||
{
|
|
||||||
data[o_position] = (short) s_left;
|
|
||||||
data[o_position + 1] = (short) s_right;
|
|
||||||
|
|
||||||
o_position += 2;
|
|
||||||
i_position = (i_position + 2) % (buffer_size >> 1);
|
|
||||||
consumed += 2;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
r_left [0] = r_left [1];
|
|
||||||
r_left [1] = r_left [2];
|
|
||||||
r_left [2] = r_left [3];
|
|
||||||
r_left [3] = s_left;
|
|
||||||
|
|
||||||
r_right[0] = r_right[1];
|
|
||||||
r_right[1] = r_right[2];
|
|
||||||
r_right[2] = r_right[3];
|
|
||||||
r_right[3] = s_right;
|
|
||||||
|
|
||||||
while (r_frac <= 1.0 && o_position < num_samples)
|
|
||||||
{
|
|
||||||
data[o_position] = short_clamp (hermite (r_frac, r_left [0], r_left [1], r_left [2], r_left [3]));
|
|
||||||
data[o_position + 1] = short_clamp (hermite (r_frac, r_right[0], r_right[1], r_right[2], r_right[3]));
|
|
||||||
|
|
||||||
o_position += 2;
|
|
||||||
|
|
||||||
r_frac += r_step;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r_frac > 1.0)
|
|
||||||
{
|
|
||||||
r_frac -= 1.0;
|
|
||||||
i_position = (i_position + 2) % (buffer_size >> 1);
|
|
||||||
consumed += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size -= consumed << 1;
|
|
||||||
start = (start + (consumed << 1)) % buffer_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
push (short *src, int num_samples)
|
push (short *src, int num_samples)
|
||||||
{
|
{
|
||||||
if (max_write () < num_samples)
|
if (max_write () < num_samples)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ring_buffer::push ((unsigned char *) src, num_samples << 1);
|
!num_samples || ring_buffer::push ((unsigned char *) src, num_samples << 1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
inline int
|
||||||
|
space_empty (void)
|
||||||
|
{
|
||||||
|
return buffer_size - size;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int
|
||||||
|
space_filled (void)
|
||||||
|
{
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int
|
||||||
max_write (void)
|
max_write (void)
|
||||||
{
|
{
|
||||||
return space_empty () >> 1;
|
return space_empty () >> 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
inline void
|
||||||
resize (int num_samples)
|
resize (int num_samples)
|
||||||
{
|
{
|
||||||
ring_buffer::resize (num_samples << 1);
|
ring_buffer::resize (num_samples << 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
avail (void)
|
|
||||||
{
|
|
||||||
return (int) floor (((size >> 2) - r_frac) / r_step) * 2;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __RESAMPLER_H */
|
#endif /* __RESAMPLER_H */
|
||||||
|
@ -207,22 +207,6 @@ static void S9xResetCPU (void)
|
|||||||
|
|
||||||
static void S9xSoftResetCPU (void)
|
static void S9xSoftResetCPU (void)
|
||||||
{
|
{
|
||||||
Registers.PBPC = 0;
|
|
||||||
Registers.PB = 0;
|
|
||||||
Registers.PCw = S9xGetWord(0xfffc);
|
|
||||||
OpenBus = Registers.PCh;
|
|
||||||
Registers.D.W = 0;
|
|
||||||
Registers.DB = 0;
|
|
||||||
Registers.SH = 1;
|
|
||||||
Registers.SL -= 3;
|
|
||||||
Registers.XH = 0;
|
|
||||||
Registers.YH = 0;
|
|
||||||
|
|
||||||
ICPU.ShiftedPB = 0;
|
|
||||||
ICPU.ShiftedDB = 0;
|
|
||||||
SetFlags(MemoryFlag | IndexFlag | IRQ | Emulation);
|
|
||||||
ClearFlags(Decimal);
|
|
||||||
|
|
||||||
CPU.Cycles = 182; // Or 188. This is the cycle count just after the jump to the Reset Vector.
|
CPU.Cycles = 182; // Or 188. This is the cycle count just after the jump to the Reset Vector.
|
||||||
CPU.PrevCycles = -1;
|
CPU.PrevCycles = -1;
|
||||||
CPU.V_Counter = 0;
|
CPU.V_Counter = 0;
|
||||||
@ -248,6 +232,22 @@ static void S9xSoftResetCPU (void)
|
|||||||
CPU.AutoSaveTimer = 0;
|
CPU.AutoSaveTimer = 0;
|
||||||
CPU.SRAMModified = FALSE;
|
CPU.SRAMModified = FALSE;
|
||||||
|
|
||||||
|
Registers.PBPC = 0;
|
||||||
|
Registers.PB = 0;
|
||||||
|
Registers.PCw = S9xGetWord(0xfffc);
|
||||||
|
OpenBus = Registers.PCh;
|
||||||
|
Registers.D.W = 0;
|
||||||
|
Registers.DB = 0;
|
||||||
|
Registers.SH = 1;
|
||||||
|
Registers.SL -= 3;
|
||||||
|
Registers.XH = 0;
|
||||||
|
Registers.YH = 0;
|
||||||
|
|
||||||
|
ICPU.ShiftedPB = 0;
|
||||||
|
ICPU.ShiftedDB = 0;
|
||||||
|
SetFlags(MemoryFlag | IndexFlag | IRQ | Emulation);
|
||||||
|
ClearFlags(Decimal);
|
||||||
|
|
||||||
Timings.InterlaceField = FALSE;
|
Timings.InterlaceField = FALSE;
|
||||||
Timings.H_Max = Timings.H_Max_Master;
|
Timings.H_Max = Timings.H_Max_Master;
|
||||||
Timings.V_Max = Timings.V_Max_Master;
|
Timings.V_Max = Timings.V_Max_Master;
|
||||||
|
@ -307,8 +307,10 @@ void S9xMainLoop (void)
|
|||||||
if (SA1.Executing)
|
if (SA1.Executing)
|
||||||
S9xSA1MainLoop();
|
S9xSA1MainLoop();
|
||||||
|
|
||||||
|
#if (S9X_ACCURACY_LEVEL <= 2)
|
||||||
while (CPU.Cycles >= CPU.NextEvent)
|
while (CPU.Cycles >= CPU.NextEvent)
|
||||||
S9xDoHEventProcessing();
|
S9xDoHEventProcessing();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
S9xPackStatus();
|
S9xPackStatus();
|
||||||
@ -355,10 +357,29 @@ void S9xClearIRQ (uint32 source)
|
|||||||
|
|
||||||
void S9xDoHEventProcessing (void)
|
void S9xDoHEventProcessing (void)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUGGER
|
||||||
|
static char eventname[13][32] =
|
||||||
|
{
|
||||||
|
"",
|
||||||
|
"HC_HBLANK_START_EVENT",
|
||||||
|
"HC_IRQ_1_3_EVENT ",
|
||||||
|
"HC_HDMA_START_EVENT ",
|
||||||
|
"HC_IRQ_3_5_EVENT ",
|
||||||
|
"HC_HCOUNTER_MAX_EVENT",
|
||||||
|
"HC_IRQ_5_7_EVENT ",
|
||||||
|
"HC_HDMA_INIT_EVENT ",
|
||||||
|
"HC_IRQ_7_9_EVENT ",
|
||||||
|
"HC_RENDER_EVENT ",
|
||||||
|
"HC_IRQ_9_A_EVENT ",
|
||||||
|
"HC_WRAM_REFRESH_EVENT",
|
||||||
|
"HC_IRQ_A_1_EVENT "
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUGGER
|
#ifdef DEBUGGER
|
||||||
if (Settings.TraceHCEvent)
|
if (Settings.TraceHCEvent)
|
||||||
S9xTraceFormattedMessage("--- HC event processing (%02d) expected HC:%04d executed HC:%04d",
|
S9xTraceFormattedMessage("--- HC event processing (%s) expected HC:%04d executed HC:%04d",
|
||||||
CPU.WhichEvent, CPU.NextEvent, CPU.Cycles);
|
eventname[CPU.WhichEvent], CPU.NextEvent, CPU.Cycles);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CPU_SHUTDOWN
|
#ifdef CPU_SHUTDOWN
|
||||||
@ -366,13 +387,16 @@ void S9xDoHEventProcessing (void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (CPU.WhichEvent)
|
switch (CPU.WhichEvent)
|
||||||
{
|
{
|
||||||
case HC_HBLANK_START_EVENT:
|
case HC_HBLANK_START_EVENT:
|
||||||
S9xCheckMissingHTimerPosition(Timings.HBlankStart);
|
S9xCheckMissingHTimerPosition(Timings.HBlankStart);
|
||||||
|
S9xReschedule();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HC_HDMA_START_EVENT:
|
case HC_HDMA_START_EVENT:
|
||||||
|
S9xCheckMissingHTimerPosition(Timings.HDMAStart);
|
||||||
|
S9xReschedule();
|
||||||
|
|
||||||
if (PPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight)
|
if (PPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight)
|
||||||
{
|
{
|
||||||
#ifdef DEBUGGER
|
#ifdef DEBUGGER
|
||||||
@ -381,8 +405,6 @@ void S9xDoHEventProcessing (void)
|
|||||||
PPU.HDMA = S9xDoHDMA(PPU.HDMA);
|
PPU.HDMA = S9xDoHDMA(PPU.HDMA);
|
||||||
}
|
}
|
||||||
|
|
||||||
S9xCheckMissingHTimerPosition(Timings.HDMAStart);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HC_HCOUNTER_MAX_EVENT:
|
case HC_HCOUNTER_MAX_EVENT:
|
||||||
@ -470,7 +492,7 @@ void S9xDoHEventProcessing (void)
|
|||||||
missing.dma_this_frame = 0;
|
missing.dma_this_frame = 0;
|
||||||
#endif
|
#endif
|
||||||
IPPU.MaxBrightness = PPU.Brightness;
|
IPPU.MaxBrightness = PPU.Brightness;
|
||||||
PPU.ForcedBlanking = (Memory.FillRAM [0x2100] >> 7) & 1;
|
PPU.ForcedBlanking = (Memory.FillRAM[0x2100] >> 7) & 1;
|
||||||
|
|
||||||
if (!PPU.ForcedBlanking)
|
if (!PPU.ForcedBlanking)
|
||||||
{
|
{
|
||||||
@ -511,14 +533,21 @@ void S9xDoHEventProcessing (void)
|
|||||||
S9xStartScreenRefresh();
|
S9xStartScreenRefresh();
|
||||||
|
|
||||||
CPU.NextEvent = -1;
|
CPU.NextEvent = -1;
|
||||||
|
S9xReschedule();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HC_HDMA_INIT_EVENT:
|
case HC_HDMA_INIT_EVENT:
|
||||||
if (CPU.V_Counter == 0)
|
|
||||||
S9xStartHDMA();
|
|
||||||
|
|
||||||
S9xCheckMissingHTimerPosition(Timings.HDMAInit);
|
S9xCheckMissingHTimerPosition(Timings.HDMAInit);
|
||||||
|
S9xReschedule();
|
||||||
|
|
||||||
|
if (CPU.V_Counter == 0)
|
||||||
|
{
|
||||||
|
#ifdef DEBUGGER
|
||||||
|
S9xTraceFormattedMessage("*** HDMA Init HC:%04d, Channel:%02x", CPU.Cycles, PPU.HDMA);
|
||||||
|
#endif
|
||||||
|
S9xStartHDMA();
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -527,6 +556,7 @@ void S9xDoHEventProcessing (void)
|
|||||||
RenderLine((uint8) (CPU.V_Counter - FIRST_VISIBLE_LINE));
|
RenderLine((uint8) (CPU.V_Counter - FIRST_VISIBLE_LINE));
|
||||||
|
|
||||||
S9xCheckMissingHTimerPosition(Timings.RenderPos);
|
S9xCheckMissingHTimerPosition(Timings.RenderPos);
|
||||||
|
S9xReschedule();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -534,10 +564,12 @@ void S9xDoHEventProcessing (void)
|
|||||||
#ifdef DEBUGGER
|
#ifdef DEBUGGER
|
||||||
S9xTraceFormattedMessage("*** WRAM Refresh HC:%04d", CPU.Cycles);
|
S9xTraceFormattedMessage("*** WRAM Refresh HC:%04d", CPU.Cycles);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
S9xCheckMissingHTimerHalt(Timings.WRAMRefreshPos, SNES_WRAM_REFRESH_CYCLES);
|
S9xCheckMissingHTimerHalt(Timings.WRAMRefreshPos, SNES_WRAM_REFRESH_CYCLES);
|
||||||
CPU.Cycles += SNES_WRAM_REFRESH_CYCLES;
|
CPU.Cycles += SNES_WRAM_REFRESH_CYCLES;
|
||||||
|
|
||||||
S9xCheckMissingHTimerPosition(Timings.WRAMRefreshPos);
|
S9xCheckMissingHTimerPosition(Timings.WRAMRefreshPos);
|
||||||
|
S9xReschedule();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -553,13 +585,13 @@ void S9xDoHEventProcessing (void)
|
|||||||
if (PPU.VTimerEnabled && (CPU.V_Counter == PPU.VTimerPosition))
|
if (PPU.VTimerEnabled && (CPU.V_Counter == PPU.VTimerPosition))
|
||||||
S9xSetIRQ(PPU_IRQ_SOURCE);
|
S9xSetIRQ(PPU_IRQ_SOURCE);
|
||||||
|
|
||||||
|
S9xReschedule();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
S9xReschedule();
|
|
||||||
|
|
||||||
#ifdef DEBUGGER
|
#ifdef DEBUGGER
|
||||||
if (Settings.TraceHCEvent)
|
if (Settings.TraceHCEvent)
|
||||||
S9xTraceFormattedMessage("--- HC event rescheduled (%02d) expected HC:%04d", CPU.WhichEvent, CPU.NextEvent);
|
S9xTraceFormattedMessage("--- HC event rescheduled (%s) expected HC:%04d current HC:%04d",
|
||||||
|
eventname[CPU.WhichEvent], CPU.NextEvent, CPU.Cycles);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,11 @@
|
|||||||
#ifdef SA1_OPCODES
|
#ifdef SA1_OPCODES
|
||||||
#define AddCycles(n) { }
|
#define AddCycles(n) { }
|
||||||
#else
|
#else
|
||||||
#define AddCycles(n) CPU.Cycles += n
|
#if (S9X_ACCURACY_LEVEL >= 3)
|
||||||
|
#define AddCycles(n) { CPU.Cycles += (n); while (CPU.Cycles >= CPU.NextEvent) S9xDoHEventProcessing(); }
|
||||||
|
#else
|
||||||
|
#define AddCycles(n) { CPU.Cycles += (n); }
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "cpuaddr.h"
|
#include "cpuaddr.h"
|
||||||
|
@ -185,6 +185,8 @@
|
|||||||
#include "missing.h"
|
#include "missing.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ADD_CYCLES(n) CPU.Cycles += (n)
|
||||||
|
|
||||||
extern uint8 *HDMAMemPointers[8];
|
extern uint8 *HDMAMemPointers[8];
|
||||||
extern int HDMA_ModeByteCounts[8];
|
extern int HDMA_ModeByteCounts[8];
|
||||||
extern SPC7110 s7emu;
|
extern SPC7110 s7emu;
|
||||||
@ -199,7 +201,7 @@ static inline bool8 addCyclesInDMA (uint8 dma_channel)
|
|||||||
{
|
{
|
||||||
// Add 8 cycles per byte, sync APU, and do HC related events.
|
// Add 8 cycles per byte, sync APU, and do HC related events.
|
||||||
// If HDMA was done in S9xDoHEventProcessing(), check if it used the same channel as DMA.
|
// If HDMA was done in S9xDoHEventProcessing(), check if it used the same channel as DMA.
|
||||||
CPU.Cycles += SLOW_ONE_CYCLE;
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
while (CPU.Cycles >= CPU.NextEvent)
|
while (CPU.Cycles >= CPU.NextEvent)
|
||||||
S9xDoHEventProcessing();
|
S9xDoHEventProcessing();
|
||||||
|
|
||||||
@ -245,7 +247,7 @@ bool8 S9xDoDMA (uint8 Channel)
|
|||||||
c = 0x10000;
|
c = 0x10000;
|
||||||
|
|
||||||
// 8 cycles per channel
|
// 8 cycles per channel
|
||||||
CPU.Cycles += SLOW_ONE_CYCLE;
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
// 8 cycles per byte
|
// 8 cycles per byte
|
||||||
while (c)
|
while (c)
|
||||||
{
|
{
|
||||||
@ -510,7 +512,7 @@ bool8 S9xDoDMA (uint8 Channel)
|
|||||||
uint8 Work;
|
uint8 Work;
|
||||||
|
|
||||||
// 8 cycles per channel
|
// 8 cycles per channel
|
||||||
CPU.Cycles += SLOW_ONE_CYCLE;
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
|
|
||||||
if (!d->ReverseTransfer)
|
if (!d->ReverseTransfer)
|
||||||
{
|
{
|
||||||
@ -1315,7 +1317,7 @@ static inline bool8 HDMAReadLineCount (int d)
|
|||||||
uint8 line;
|
uint8 line;
|
||||||
|
|
||||||
line = S9xGetByte((DMA[d].ABank << 16) + DMA[d].Address);
|
line = S9xGetByte((DMA[d].ABank << 16) + DMA[d].Address);
|
||||||
CPU.Cycles += SLOW_ONE_CYCLE;
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
|
|
||||||
if (!line)
|
if (!line)
|
||||||
{
|
{
|
||||||
@ -1327,10 +1329,10 @@ static inline bool8 HDMAReadLineCount (int d)
|
|||||||
if (PPU.HDMA & (0xfe << d))
|
if (PPU.HDMA & (0xfe << d))
|
||||||
{
|
{
|
||||||
DMA[d].Address++;
|
DMA[d].Address++;
|
||||||
CPU.Cycles += SLOW_ONE_CYCLE * 2;
|
ADD_CYCLES(SLOW_ONE_CYCLE << 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
CPU.Cycles += SLOW_ONE_CYCLE;
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
|
|
||||||
DMA[d].IndirectAddress = S9xGetWord((DMA[d].ABank << 16) + DMA[d].Address);
|
DMA[d].IndirectAddress = S9xGetWord((DMA[d].ABank << 16) + DMA[d].Address);
|
||||||
DMA[d].Address++;
|
DMA[d].Address++;
|
||||||
@ -1358,7 +1360,7 @@ static inline bool8 HDMAReadLineCount (int d)
|
|||||||
|
|
||||||
if (DMA[d].HDMAIndirectAddressing)
|
if (DMA[d].HDMAIndirectAddressing)
|
||||||
{
|
{
|
||||||
CPU.Cycles += SLOW_ONE_CYCLE << 1;
|
ADD_CYCLES(SLOW_ONE_CYCLE << 1);
|
||||||
DMA[d].IndirectAddress = S9xGetWord((DMA[d].ABank << 16) + DMA[d].Address);
|
DMA[d].IndirectAddress = S9xGetWord((DMA[d].ABank << 16) + DMA[d].Address);
|
||||||
DMA[d].Address += 2;
|
DMA[d].Address += 2;
|
||||||
HDMAMemPointers[d] = S9xGetMemPointer((DMA[d].IndirectBank << 16) + DMA[d].IndirectAddress);
|
HDMAMemPointers[d] = S9xGetMemPointer((DMA[d].IndirectBank << 16) + DMA[d].IndirectAddress);
|
||||||
@ -1390,7 +1392,7 @@ void S9xStartHDMA (void)
|
|||||||
|
|
||||||
// XXX: Not quite right...
|
// XXX: Not quite right...
|
||||||
if (PPU.HDMA != 0)
|
if (PPU.HDMA != 0)
|
||||||
CPU.Cycles += Timings.DMACPUSync;
|
ADD_CYCLES(Timings.DMACPUSync);
|
||||||
|
|
||||||
for (uint8 i = 0; i < 8; i++)
|
for (uint8 i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
@ -1433,7 +1435,7 @@ uint8 S9xDoHDMA (uint8 byte)
|
|||||||
tmpch = CPU.CurrentDMAorHDMAChannel;
|
tmpch = CPU.CurrentDMAorHDMAChannel;
|
||||||
|
|
||||||
// XXX: Not quite right...
|
// XXX: Not quite right...
|
||||||
CPU.Cycles += Timings.DMACPUSync;
|
ADD_CYCLES(Timings.DMACPUSync);
|
||||||
|
|
||||||
for (uint8 mask = 1; mask; mask <<= 1, p++, d++)
|
for (uint8 mask = 1; mask; mask <<= 1, p++, d++)
|
||||||
{
|
{
|
||||||
@ -1498,46 +1500,57 @@ uint8 S9xDoHDMA (uint8 byte)
|
|||||||
switch (p->TransferMode)
|
switch (p->TransferMode)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
CPU.Cycles += SLOW_ONE_CYCLE;
|
|
||||||
DOBYTE(IAddr, 0);
|
DOBYTE(IAddr, 0);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
CPU.Cycles += 4 * SLOW_ONE_CYCLE;
|
|
||||||
DOBYTE(IAddr + 0, 0);
|
DOBYTE(IAddr + 0, 0);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 1, 1);
|
DOBYTE(IAddr + 1, 1);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 2, 0);
|
DOBYTE(IAddr + 2, 0);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 3, 1);
|
DOBYTE(IAddr + 3, 1);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
CPU.Cycles += 2 * SLOW_ONE_CYCLE;
|
|
||||||
DOBYTE(IAddr + 0, 0);
|
DOBYTE(IAddr + 0, 0);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 1, 1);
|
DOBYTE(IAddr + 1, 1);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
case 6:
|
case 6:
|
||||||
CPU.Cycles += 2 * SLOW_ONE_CYCLE;
|
|
||||||
DOBYTE(IAddr + 0, 0);
|
DOBYTE(IAddr + 0, 0);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 1, 0);
|
DOBYTE(IAddr + 1, 0);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
case 7:
|
case 7:
|
||||||
CPU.Cycles += 4 * SLOW_ONE_CYCLE;
|
|
||||||
DOBYTE(IAddr + 0, 0);
|
DOBYTE(IAddr + 0, 0);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 1, 0);
|
DOBYTE(IAddr + 1, 0);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 2, 1);
|
DOBYTE(IAddr + 2, 1);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 3, 1);
|
DOBYTE(IAddr + 3, 1);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
CPU.Cycles += 4 * SLOW_ONE_CYCLE;
|
|
||||||
DOBYTE(IAddr + 0, 0);
|
DOBYTE(IAddr + 0, 0);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 1, 1);
|
DOBYTE(IAddr + 1, 1);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 2, 2);
|
DOBYTE(IAddr + 2, 2);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 3, 3);
|
DOBYTE(IAddr + 3, 3);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1556,44 +1569,53 @@ uint8 S9xDoHDMA (uint8 byte)
|
|||||||
switch (p->TransferMode)
|
switch (p->TransferMode)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
CPU.Cycles += SLOW_ONE_CYCLE;
|
|
||||||
S9xSetPPU(S9xGetByte(Addr), 0x2100 + p->BAddress);
|
S9xSetPPU(S9xGetByte(Addr), 0x2100 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
CPU.Cycles += 2 * SLOW_ONE_CYCLE;
|
|
||||||
S9xSetPPU(S9xGetByte(Addr + 0), 0x2100 + p->BAddress);
|
S9xSetPPU(S9xGetByte(Addr + 0), 0x2100 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
S9xSetPPU(S9xGetByte(Addr + 1), 0x2101 + p->BAddress);
|
S9xSetPPU(S9xGetByte(Addr + 1), 0x2101 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
Addr += 2;
|
Addr += 2;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case 1:
|
case 1:
|
||||||
CPU.Cycles += 2 * SLOW_ONE_CYCLE;
|
|
||||||
S9xSetPPU(S9xGetByte(Addr + 0), 0x2100 + p->BAddress);
|
S9xSetPPU(S9xGetByte(Addr + 0), 0x2100 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
S9xSetPPU(S9xGetByte(Addr + 1), 0x2101 + p->BAddress);
|
S9xSetPPU(S9xGetByte(Addr + 1), 0x2101 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
case 6:
|
case 6:
|
||||||
CPU.Cycles += 2 * SLOW_ONE_CYCLE;
|
|
||||||
S9xSetPPU(S9xGetByte(Addr + 0), 0x2100 + p->BAddress);
|
S9xSetPPU(S9xGetByte(Addr + 0), 0x2100 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
S9xSetPPU(S9xGetByte(Addr + 1), 0x2100 + p->BAddress);
|
S9xSetPPU(S9xGetByte(Addr + 1), 0x2100 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
case 7:
|
case 7:
|
||||||
CPU.Cycles += 4 * SLOW_ONE_CYCLE;
|
|
||||||
S9xSetPPU(S9xGetByte(Addr + 0), 0x2100 + p->BAddress);
|
S9xSetPPU(S9xGetByte(Addr + 0), 0x2100 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
S9xSetPPU(S9xGetByte(Addr + 1), 0x2100 + p->BAddress);
|
S9xSetPPU(S9xGetByte(Addr + 1), 0x2100 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
S9xSetPPU(S9xGetByte(Addr + 2), 0x2101 + p->BAddress);
|
S9xSetPPU(S9xGetByte(Addr + 2), 0x2101 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
S9xSetPPU(S9xGetByte(Addr + 3), 0x2101 + p->BAddress);
|
S9xSetPPU(S9xGetByte(Addr + 3), 0x2101 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
CPU.Cycles += 4 * SLOW_ONE_CYCLE;
|
|
||||||
S9xSetPPU(S9xGetByte(Addr + 0), 0x2100 + p->BAddress);
|
S9xSetPPU(S9xGetByte(Addr + 0), 0x2100 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
S9xSetPPU(S9xGetByte(Addr + 1), 0x2101 + p->BAddress);
|
S9xSetPPU(S9xGetByte(Addr + 1), 0x2101 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
S9xSetPPU(S9xGetByte(Addr + 2), 0x2102 + p->BAddress);
|
S9xSetPPU(S9xGetByte(Addr + 2), 0x2102 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
S9xSetPPU(S9xGetByte(Addr + 3), 0x2103 + p->BAddress);
|
S9xSetPPU(S9xGetByte(Addr + 3), 0x2103 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1603,47 +1625,56 @@ uint8 S9xDoHDMA (uint8 byte)
|
|||||||
switch (p->TransferMode)
|
switch (p->TransferMode)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
CPU.Cycles += SLOW_ONE_CYCLE;
|
|
||||||
S9xSetPPU(*HDMAMemPointers[d]++, 0x2100 + p->BAddress);
|
S9xSetPPU(*HDMAMemPointers[d]++, 0x2100 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
CPU.Cycles += 2 * SLOW_ONE_CYCLE;
|
|
||||||
S9xSetPPU(*(HDMAMemPointers[d] + 0), 0x2100 + p->BAddress);
|
S9xSetPPU(*(HDMAMemPointers[d] + 0), 0x2100 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
S9xSetPPU(*(HDMAMemPointers[d] + 1), 0x2101 + p->BAddress);
|
S9xSetPPU(*(HDMAMemPointers[d] + 1), 0x2101 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
HDMAMemPointers[d] += 2;
|
HDMAMemPointers[d] += 2;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case 1:
|
case 1:
|
||||||
CPU.Cycles += 2 * SLOW_ONE_CYCLE;
|
|
||||||
S9xSetPPU(*(HDMAMemPointers[d] + 0), 0x2100 + p->BAddress);
|
S9xSetPPU(*(HDMAMemPointers[d] + 0), 0x2100 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
S9xSetPPU(*(HDMAMemPointers[d] + 1), 0x2101 + p->BAddress);
|
S9xSetPPU(*(HDMAMemPointers[d] + 1), 0x2101 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
HDMAMemPointers[d] += 2;
|
HDMAMemPointers[d] += 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
case 6:
|
case 6:
|
||||||
CPU.Cycles += 2 * SLOW_ONE_CYCLE;
|
|
||||||
S9xSetPPU(*(HDMAMemPointers[d] + 0), 0x2100 + p->BAddress);
|
S9xSetPPU(*(HDMAMemPointers[d] + 0), 0x2100 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
S9xSetPPU(*(HDMAMemPointers[d] + 1), 0x2100 + p->BAddress);
|
S9xSetPPU(*(HDMAMemPointers[d] + 1), 0x2100 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
HDMAMemPointers[d] += 2;
|
HDMAMemPointers[d] += 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
case 7:
|
case 7:
|
||||||
CPU.Cycles += 4 * SLOW_ONE_CYCLE;
|
|
||||||
S9xSetPPU(*(HDMAMemPointers[d] + 0), 0x2100 + p->BAddress);
|
S9xSetPPU(*(HDMAMemPointers[d] + 0), 0x2100 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
S9xSetPPU(*(HDMAMemPointers[d] + 1), 0x2100 + p->BAddress);
|
S9xSetPPU(*(HDMAMemPointers[d] + 1), 0x2100 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
S9xSetPPU(*(HDMAMemPointers[d] + 2), 0x2101 + p->BAddress);
|
S9xSetPPU(*(HDMAMemPointers[d] + 2), 0x2101 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
S9xSetPPU(*(HDMAMemPointers[d] + 3), 0x2101 + p->BAddress);
|
S9xSetPPU(*(HDMAMemPointers[d] + 3), 0x2101 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
HDMAMemPointers[d] += 4;
|
HDMAMemPointers[d] += 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
CPU.Cycles += 4 * SLOW_ONE_CYCLE;
|
|
||||||
S9xSetPPU(*(HDMAMemPointers[d] + 0), 0x2100 + p->BAddress);
|
S9xSetPPU(*(HDMAMemPointers[d] + 0), 0x2100 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
S9xSetPPU(*(HDMAMemPointers[d] + 1), 0x2101 + p->BAddress);
|
S9xSetPPU(*(HDMAMemPointers[d] + 1), 0x2101 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
S9xSetPPU(*(HDMAMemPointers[d] + 2), 0x2102 + p->BAddress);
|
S9xSetPPU(*(HDMAMemPointers[d] + 2), 0x2102 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
S9xSetPPU(*(HDMAMemPointers[d] + 3), 0x2103 + p->BAddress);
|
S9xSetPPU(*(HDMAMemPointers[d] + 3), 0x2103 + p->BAddress);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
HDMAMemPointers[d] += 4;
|
HDMAMemPointers[d] += 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1665,46 +1696,57 @@ uint8 S9xDoHDMA (uint8 byte)
|
|||||||
switch (p->TransferMode)
|
switch (p->TransferMode)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
CPU.Cycles += SLOW_ONE_CYCLE;
|
|
||||||
DOBYTE(IAddr, 0);
|
DOBYTE(IAddr, 0);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
CPU.Cycles += 4 * SLOW_ONE_CYCLE;
|
|
||||||
DOBYTE(IAddr + 0, 0);
|
DOBYTE(IAddr + 0, 0);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 1, 1);
|
DOBYTE(IAddr + 1, 1);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 2, 0);
|
DOBYTE(IAddr + 2, 0);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 3, 1);
|
DOBYTE(IAddr + 3, 1);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
CPU.Cycles += 2 * SLOW_ONE_CYCLE;
|
|
||||||
DOBYTE(IAddr + 0, 0);
|
DOBYTE(IAddr + 0, 0);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 1, 1);
|
DOBYTE(IAddr + 1, 1);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
case 6:
|
case 6:
|
||||||
CPU.Cycles += 2 * SLOW_ONE_CYCLE;
|
|
||||||
DOBYTE(IAddr + 0, 0);
|
DOBYTE(IAddr + 0, 0);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 1, 0);
|
DOBYTE(IAddr + 1, 0);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
case 7:
|
case 7:
|
||||||
CPU.Cycles += 4 * SLOW_ONE_CYCLE;
|
|
||||||
DOBYTE(IAddr + 0, 0);
|
DOBYTE(IAddr + 0, 0);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 1, 0);
|
DOBYTE(IAddr + 1, 0);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 2, 1);
|
DOBYTE(IAddr + 2, 1);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 3, 1);
|
DOBYTE(IAddr + 3, 1);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
CPU.Cycles += 4 * SLOW_ONE_CYCLE;
|
|
||||||
DOBYTE(IAddr + 0, 0);
|
DOBYTE(IAddr + 0, 0);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 1, 1);
|
DOBYTE(IAddr + 1, 1);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 2, 2);
|
DOBYTE(IAddr + 2, 2);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
DOBYTE(IAddr + 3, 3);
|
DOBYTE(IAddr + 3, 3);
|
||||||
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1730,7 +1772,7 @@ uint8 S9xDoHDMA (uint8 byte)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
CPU.Cycles += SLOW_ONE_CYCLE;
|
ADD_CYCLES(SLOW_ONE_CYCLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,15 +187,63 @@
|
|||||||
#include "seta.h"
|
#include "seta.h"
|
||||||
#include "bsx.h"
|
#include "bsx.h"
|
||||||
|
|
||||||
|
#if (S9X_ACCURACY_LEVEL >= 2)
|
||||||
|
|
||||||
|
#define addCyclesInMemoryAccess \
|
||||||
|
if (!CPU.InDMAorHDMA) \
|
||||||
|
{ \
|
||||||
|
CPU.Cycles += speed; \
|
||||||
|
while (CPU.Cycles >= CPU.NextEvent) \
|
||||||
|
S9xDoHEventProcessing(); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define addCyclesInMemoryAccess_x2 \
|
||||||
|
if (!CPU.InDMAorHDMA) \
|
||||||
|
{ \
|
||||||
|
CPU.Cycles += speed << 1; \
|
||||||
|
while (CPU.Cycles >= CPU.NextEvent) \
|
||||||
|
S9xDoHEventProcessing(); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define addCyclesInMemoryAccess \
|
||||||
|
if (!CPU.InDMAorHDMA) \
|
||||||
|
CPU.Cycles += speed;
|
||||||
|
|
||||||
|
#define addCyclesInMemoryAccess_x2 \
|
||||||
|
if (!CPU.InDMAorHDMA) \
|
||||||
|
CPU.Cycles += speed << 1;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
extern uint8 OpenBus;
|
extern uint8 OpenBus;
|
||||||
|
|
||||||
|
static inline int32 memory_speed (uint32 address)
|
||||||
|
{
|
||||||
|
if (address & 0x408000)
|
||||||
|
{
|
||||||
|
if (address & 0x800000)
|
||||||
|
return (CPU.FastROMSpeed);
|
||||||
|
|
||||||
|
return (SLOW_ONE_CYCLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((address + 0x6000) & 0x4000)
|
||||||
|
return (SLOW_ONE_CYCLE);
|
||||||
|
|
||||||
|
if ((address - 0x4000) & 0x7e00)
|
||||||
|
return (ONE_CYCLE);
|
||||||
|
|
||||||
|
return (TWO_CYCLES);
|
||||||
|
}
|
||||||
|
|
||||||
inline uint8 S9xGetByte (uint32 Address)
|
inline uint8 S9xGetByte (uint32 Address)
|
||||||
{
|
{
|
||||||
int block;
|
int block = (Address & 0xffffff) >> MEMMAP_SHIFT;
|
||||||
uint8 *GetAddress = Memory.Map[block = ((Address & 0xffffff) >> MEMMAP_SHIFT)];
|
uint8 *GetAddress = Memory.Map[block];
|
||||||
|
int32 speed = memory_speed(Address);
|
||||||
if (!CPU.InDMAorHDMA)
|
uint8 byte;
|
||||||
CPU.Cycles += Memory.MemorySpeed[block];
|
|
||||||
|
|
||||||
if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
|
if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||||
{
|
{
|
||||||
@ -203,18 +251,25 @@ inline uint8 S9xGetByte (uint32 Address)
|
|||||||
if (Memory.BlockIsRAM[block])
|
if (Memory.BlockIsRAM[block])
|
||||||
CPU.WaitAddress = CPU.PBPCAtOpcodeStart;
|
CPU.WaitAddress = CPU.PBPCAtOpcodeStart;
|
||||||
#endif
|
#endif
|
||||||
return (*(GetAddress + (Address & 0xffff)));
|
byte = *(GetAddress + (Address & 0xffff));
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ((pint) GetAddress)
|
switch ((pint) GetAddress)
|
||||||
{
|
{
|
||||||
case CMemory::MAP_CPU:
|
case CMemory::MAP_CPU:
|
||||||
return (S9xGetCPU(Address & 0xffff));
|
byte = S9xGetCPU(Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (byte);
|
||||||
|
|
||||||
case CMemory::MAP_PPU:
|
case CMemory::MAP_PPU:
|
||||||
if (CPU.InDMAorHDMA && (Address & 0xff00) == 0x2100)
|
if (CPU.InDMAorHDMA && (Address & 0xff00) == 0x2100)
|
||||||
return (OpenBus);
|
return (OpenBus);
|
||||||
return (S9xGetPPU(Address & 0xffff));
|
|
||||||
|
byte = S9xGetPPU(Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (byte);
|
||||||
|
|
||||||
case CMemory::MAP_LOROM_SRAM:
|
case CMemory::MAP_LOROM_SRAM:
|
||||||
case CMemory::MAP_SA1RAM:
|
case CMemory::MAP_SA1RAM:
|
||||||
@ -222,45 +277,71 @@ inline uint8 S9xGetByte (uint32 Address)
|
|||||||
// Address & 0xff0000 : bank
|
// Address & 0xff0000 : bank
|
||||||
// bank >> 1 | offset : SRAM address, unbound
|
// bank >> 1 | offset : SRAM address, unbound
|
||||||
// unbound & SRAMMask : SRAM offset
|
// unbound & SRAMMask : SRAM offset
|
||||||
return (*(Memory.SRAM + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask)));
|
byte = *(Memory.SRAM + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask));
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (byte);
|
||||||
|
|
||||||
case CMemory::MAP_LOROM_SRAM_B:
|
case CMemory::MAP_LOROM_SRAM_B:
|
||||||
return (*(Multi.sramB + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Multi.sramMaskB)));
|
byte = *(Multi.sramB + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Multi.sramMaskB));
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (byte);
|
||||||
|
|
||||||
case CMemory::MAP_HIROM_SRAM:
|
case CMemory::MAP_HIROM_SRAM:
|
||||||
case CMemory::MAP_RONLY_SRAM:
|
case CMemory::MAP_RONLY_SRAM:
|
||||||
return (*(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask)));
|
byte = *(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask));
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (byte);
|
||||||
|
|
||||||
case CMemory::MAP_BWRAM:
|
case CMemory::MAP_BWRAM:
|
||||||
return (*(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)));
|
byte = *(Memory.BWRAM + ((Address & 0x7fff) - 0x6000));
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (byte);
|
||||||
|
|
||||||
case CMemory::MAP_DSP:
|
case CMemory::MAP_DSP:
|
||||||
return (S9xGetDSP(Address & 0xffff));
|
byte = S9xGetDSP(Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (byte);
|
||||||
|
|
||||||
case CMemory::MAP_SPC7110_ROM:
|
case CMemory::MAP_SPC7110_ROM:
|
||||||
return (S9xGetSPC7110Byte(Address));
|
byte = S9xGetSPC7110Byte(Address);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (byte);
|
||||||
|
|
||||||
case CMemory::MAP_SPC7110_DRAM:
|
case CMemory::MAP_SPC7110_DRAM:
|
||||||
return (S9xGetSPC7110(0x4800));
|
byte = S9xGetSPC7110(0x4800);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (byte);
|
||||||
|
|
||||||
case CMemory::MAP_C4:
|
case CMemory::MAP_C4:
|
||||||
return (S9xGetC4(Address & 0xffff));
|
byte = S9xGetC4(Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (byte);
|
||||||
|
|
||||||
case CMemory::MAP_OBC_RAM:
|
case CMemory::MAP_OBC_RAM:
|
||||||
return (S9xGetOBC1(Address & 0xffff));
|
byte = S9xGetOBC1(Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (byte);
|
||||||
|
|
||||||
case CMemory::MAP_SETA_DSP:
|
case CMemory::MAP_SETA_DSP:
|
||||||
return (S9xGetSetaDSP(Address));
|
byte = S9xGetSetaDSP(Address);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (byte);
|
||||||
|
|
||||||
case CMemory::MAP_SETA_RISC:
|
case CMemory::MAP_SETA_RISC:
|
||||||
return (S9xGetST018(Address));
|
byte = S9xGetST018(Address);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (byte);
|
||||||
|
|
||||||
case CMemory::MAP_BSX:
|
case CMemory::MAP_BSX:
|
||||||
return (S9xGetBSX(Address));
|
byte = S9xGetBSX(Address);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (byte);
|
||||||
|
|
||||||
case CMemory::MAP_NONE:
|
case CMemory::MAP_NONE:
|
||||||
default:
|
default:
|
||||||
return (OpenBus);
|
byte = OpenBus;
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (byte);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,11 +372,10 @@ inline uint16 S9xGetWord (uint32 Address, enum s9xwrap_t w = WRAP_NONE)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int block;
|
int block = (Address & 0xffffff) >> MEMMAP_SHIFT;
|
||||||
uint8 *GetAddress = Memory.Map[block = ((Address & 0xffffff) >> MEMMAP_SHIFT)];
|
uint8 *GetAddress = Memory.Map[block];
|
||||||
|
int32 speed = memory_speed(Address);
|
||||||
if (!CPU.InDMAorHDMA)
|
uint16 word;
|
||||||
CPU.Cycles += (Memory.MemorySpeed[block] << 1);
|
|
||||||
|
|
||||||
if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
|
if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||||
{
|
{
|
||||||
@ -303,13 +383,19 @@ inline uint16 S9xGetWord (uint32 Address, enum s9xwrap_t w = WRAP_NONE)
|
|||||||
if (Memory.BlockIsRAM[block])
|
if (Memory.BlockIsRAM[block])
|
||||||
CPU.WaitAddress = CPU.PBPCAtOpcodeStart;
|
CPU.WaitAddress = CPU.PBPCAtOpcodeStart;
|
||||||
#endif
|
#endif
|
||||||
return (READ_WORD(GetAddress + (Address & 0xffff)));
|
word = READ_WORD(GetAddress + (Address & 0xffff));
|
||||||
|
addCyclesInMemoryAccess_x2;
|
||||||
|
return (word);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ((pint) GetAddress)
|
switch ((pint) GetAddress)
|
||||||
{
|
{
|
||||||
case CMemory::MAP_CPU:
|
case CMemory::MAP_CPU:
|
||||||
return (S9xGetCPU(Address & 0xffff) | (S9xGetCPU((Address + 1) & 0xffff) << 8));
|
word = S9xGetCPU(Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
word |= S9xGetCPU((Address + 1) & 0xffff) << 8;
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (word);
|
||||||
|
|
||||||
case CMemory::MAP_PPU:
|
case CMemory::MAP_PPU:
|
||||||
if (CPU.InDMAorHDMA)
|
if (CPU.InDMAorHDMA)
|
||||||
@ -318,61 +404,107 @@ inline uint16 S9xGetWord (uint32 Address, enum s9xwrap_t w = WRAP_NONE)
|
|||||||
return (OpenBus | (S9xGetByte(Address + 1) << 8));
|
return (OpenBus | (S9xGetByte(Address + 1) << 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (S9xGetPPU(Address & 0xffff) | (S9xGetPPU((Address + 1) & 0xffff) << 8));
|
word = S9xGetPPU(Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
word |= S9xGetPPU((Address + 1) & 0xffff) << 8;
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (word);
|
||||||
|
|
||||||
case CMemory::MAP_LOROM_SRAM:
|
case CMemory::MAP_LOROM_SRAM:
|
||||||
case CMemory::MAP_SA1RAM:
|
case CMemory::MAP_SA1RAM:
|
||||||
if (Memory.SRAMMask >= MEMMAP_MASK)
|
if (Memory.SRAMMask >= MEMMAP_MASK)
|
||||||
return (READ_WORD(Memory.SRAM + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask)));
|
word = READ_WORD(Memory.SRAM + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask));
|
||||||
else
|
else
|
||||||
return ((*(Memory.SRAM + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask))) |
|
word = (*(Memory.SRAM + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask))) |
|
||||||
((*(Memory.SRAM + (((((Address + 1) & 0xff0000) >> 1) | ((Address + 1) & 0x7fff)) & Memory.SRAMMask))) << 8));
|
((*(Memory.SRAM + (((((Address + 1) & 0xff0000) >> 1) | ((Address + 1) & 0x7fff)) & Memory.SRAMMask))) << 8);
|
||||||
|
addCyclesInMemoryAccess_x2;
|
||||||
|
return (word);
|
||||||
|
|
||||||
case CMemory::MAP_LOROM_SRAM_B:
|
case CMemory::MAP_LOROM_SRAM_B:
|
||||||
if (Multi.sramMaskB >= MEMMAP_MASK)
|
if (Multi.sramMaskB >= MEMMAP_MASK)
|
||||||
return (READ_WORD(Multi.sramB + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Multi.sramMaskB)));
|
word = READ_WORD(Multi.sramB + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Multi.sramMaskB));
|
||||||
else
|
else
|
||||||
return ((*(Multi.sramB + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Multi.sramMaskB))) |
|
word = (*(Multi.sramB + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Multi.sramMaskB))) |
|
||||||
((*(Multi.sramB + (((((Address + 1) & 0xff0000) >> 1) | ((Address + 1) & 0x7fff)) & Multi.sramMaskB))) << 8));
|
((*(Multi.sramB + (((((Address + 1) & 0xff0000) >> 1) | ((Address + 1) & 0x7fff)) & Multi.sramMaskB))) << 8);
|
||||||
|
addCyclesInMemoryAccess_x2;
|
||||||
|
return (word);
|
||||||
|
|
||||||
case CMemory::MAP_HIROM_SRAM:
|
case CMemory::MAP_HIROM_SRAM:
|
||||||
case CMemory::MAP_RONLY_SRAM:
|
case CMemory::MAP_RONLY_SRAM:
|
||||||
if (Memory.SRAMMask >= MEMMAP_MASK)
|
if (Memory.SRAMMask >= MEMMAP_MASK)
|
||||||
return (READ_WORD(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask)));
|
word = READ_WORD(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask));
|
||||||
else
|
else
|
||||||
return ((*(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask)) |
|
word = (*(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask)) |
|
||||||
(*(Memory.SRAM + ((((Address + 1) & 0x7fff) - 0x6000 + (((Address + 1) & 0xf0000) >> 3)) & Memory.SRAMMask)) << 8)));
|
(*(Memory.SRAM + ((((Address + 1) & 0x7fff) - 0x6000 + (((Address + 1) & 0xf0000) >> 3)) & Memory.SRAMMask)) << 8));
|
||||||
|
addCyclesInMemoryAccess_x2;
|
||||||
|
return (word);
|
||||||
|
|
||||||
case CMemory::MAP_BWRAM:
|
case CMemory::MAP_BWRAM:
|
||||||
return (READ_WORD(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)));
|
word = READ_WORD(Memory.BWRAM + ((Address & 0x7fff) - 0x6000));
|
||||||
|
addCyclesInMemoryAccess_x2;
|
||||||
|
return (word);
|
||||||
|
|
||||||
case CMemory::MAP_DSP:
|
case CMemory::MAP_DSP:
|
||||||
return (S9xGetDSP(Address & 0xffff) | (S9xGetDSP((Address + 1) & 0xffff) << 8));
|
word = S9xGetDSP(Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
word |= S9xGetDSP((Address + 1) & 0xffff) << 8;
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (word);
|
||||||
|
|
||||||
case CMemory::MAP_SPC7110_ROM:
|
case CMemory::MAP_SPC7110_ROM:
|
||||||
return (S9xGetSPC7110Byte(Address) | (S9xGetSPC7110Byte(Address + 1) << 8));
|
word = S9xGetSPC7110Byte(Address);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
word |= S9xGetSPC7110Byte(Address + 1) << 8;
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (word);
|
||||||
|
|
||||||
case CMemory::MAP_SPC7110_DRAM:
|
case CMemory::MAP_SPC7110_DRAM:
|
||||||
return (S9xGetSPC7110(0x4800) | (S9xGetSPC7110(0x4800) << 8));
|
word = S9xGetSPC7110(0x4800);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
word |= S9xGetSPC7110(0x4800) << 8;
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (word);
|
||||||
|
|
||||||
case CMemory::MAP_C4:
|
case CMemory::MAP_C4:
|
||||||
return (S9xGetC4(Address & 0xffff) | (S9xGetC4((Address + 1) & 0xffff) << 8));
|
word = S9xGetC4(Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
word |= S9xGetC4((Address + 1) & 0xffff) << 8;
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (word);
|
||||||
|
|
||||||
case CMemory::MAP_OBC_RAM:
|
case CMemory::MAP_OBC_RAM:
|
||||||
return (S9xGetOBC1(Address & 0xffff) | (S9xGetOBC1((Address + 1) & 0xffff) << 8));
|
word = S9xGetOBC1(Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
word |= S9xGetOBC1((Address + 1) & 0xffff) << 8;
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (word);
|
||||||
|
|
||||||
case CMemory::MAP_SETA_DSP:
|
case CMemory::MAP_SETA_DSP:
|
||||||
return (S9xGetSetaDSP(Address) | (S9xGetSetaDSP(Address + 1) << 8));
|
word = S9xGetSetaDSP(Address);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
word |= S9xGetSetaDSP(Address + 1) << 8;
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (word);
|
||||||
|
|
||||||
case CMemory::MAP_SETA_RISC:
|
case CMemory::MAP_SETA_RISC:
|
||||||
return (S9xGetST018(Address) | (S9xGetST018(Address + 1) << 8));
|
word = S9xGetST018(Address);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
word |= S9xGetST018(Address + 1) << 8;
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (word);
|
||||||
|
|
||||||
case CMemory::MAP_BSX:
|
case CMemory::MAP_BSX:
|
||||||
return (S9xGetBSX(Address) | (S9xGetBSX(Address + 1) << 8));
|
word = S9xGetBSX(Address);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
word |= S9xGetBSX(Address + 1) << 8;
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return (word);
|
||||||
|
|
||||||
case CMemory::MAP_NONE:
|
case CMemory::MAP_NONE:
|
||||||
default:
|
default:
|
||||||
return (OpenBus | (OpenBus << 8));
|
word = OpenBus | (OpenBus << 8);
|
||||||
|
addCyclesInMemoryAccess_x2;
|
||||||
|
return (word);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,17 +514,16 @@ inline void S9xSetByte (uint8 Byte, uint32 Address)
|
|||||||
CPU.WaitAddress = 0xffffffff;
|
CPU.WaitAddress = 0xffffffff;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int block;
|
int block = (Address & 0xffffff) >> MEMMAP_SHIFT;
|
||||||
uint8 *SetAddress = Memory.WriteMap[block = ((Address & 0xffffff) >> MEMMAP_SHIFT)];
|
uint8 *SetAddress = Memory.WriteMap[block];
|
||||||
|
int32 speed = memory_speed(Address);
|
||||||
if (!CPU.InDMAorHDMA)
|
|
||||||
CPU.Cycles += Memory.MemorySpeed[block];
|
|
||||||
|
|
||||||
if (SetAddress >= (uint8 *) CMemory::MAP_LAST)
|
if (SetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||||
{
|
{
|
||||||
#ifdef CPU_SHUTDOWN
|
#ifdef CPU_SHUTDOWN
|
||||||
SetAddress += (Address & 0xffff);
|
SetAddress += (Address & 0xffff);
|
||||||
*SetAddress = Byte;
|
*SetAddress = Byte;
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
|
||||||
if (Settings.SA1)
|
if (Settings.SA1)
|
||||||
{
|
{
|
||||||
@ -404,6 +535,7 @@ inline void S9xSetByte (uint8 Byte, uint32 Address)
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
*(SetAddress + (Address & 0xffff)) = Byte;
|
*(SetAddress + (Address & 0xffff)) = Byte;
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -412,12 +544,15 @@ inline void S9xSetByte (uint8 Byte, uint32 Address)
|
|||||||
{
|
{
|
||||||
case CMemory::MAP_CPU:
|
case CMemory::MAP_CPU:
|
||||||
S9xSetCPU(Byte, Address & 0xffff);
|
S9xSetCPU(Byte, Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMemory::MAP_PPU:
|
case CMemory::MAP_PPU:
|
||||||
if (CPU.InDMAorHDMA && (Address & 0xff00) == 0x2100)
|
if (CPU.InDMAorHDMA && (Address & 0xff00) == 0x2100)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
S9xSetPPU(Byte, Address & 0xffff);
|
S9xSetPPU(Byte, Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMemory::MAP_LOROM_SRAM:
|
case CMemory::MAP_LOROM_SRAM:
|
||||||
@ -427,6 +562,7 @@ inline void S9xSetByte (uint8 Byte, uint32 Address)
|
|||||||
CPU.SRAMModified = TRUE;
|
CPU.SRAMModified = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMemory::MAP_LOROM_SRAM_B:
|
case CMemory::MAP_LOROM_SRAM_B:
|
||||||
@ -436,6 +572,7 @@ inline void S9xSetByte (uint8 Byte, uint32 Address)
|
|||||||
CPU.SRAMModified = TRUE;
|
CPU.SRAMModified = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMemory::MAP_HIROM_SRAM:
|
case CMemory::MAP_HIROM_SRAM:
|
||||||
@ -445,44 +582,54 @@ inline void S9xSetByte (uint8 Byte, uint32 Address)
|
|||||||
CPU.SRAMModified = TRUE;
|
CPU.SRAMModified = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMemory::MAP_BWRAM:
|
case CMemory::MAP_BWRAM:
|
||||||
*(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) = Byte;
|
*(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) = Byte;
|
||||||
CPU.SRAMModified = TRUE;
|
CPU.SRAMModified = TRUE;
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMemory::MAP_SA1RAM:
|
case CMemory::MAP_SA1RAM:
|
||||||
*(Memory.SRAM + (Address & 0xffff)) = Byte;
|
*(Memory.SRAM + (Address & 0xffff)) = Byte;
|
||||||
SA1.Executing = !SA1.Waiting;
|
SA1.Executing = !SA1.Waiting;
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMemory::MAP_DSP:
|
case CMemory::MAP_DSP:
|
||||||
S9xSetDSP(Byte, Address & 0xffff);
|
S9xSetDSP(Byte, Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMemory::MAP_C4:
|
case CMemory::MAP_C4:
|
||||||
S9xSetC4(Byte, Address & 0xffff);
|
S9xSetC4(Byte, Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMemory::MAP_OBC_RAM:
|
case CMemory::MAP_OBC_RAM:
|
||||||
S9xSetOBC1(Byte, Address & 0xffff);
|
S9xSetOBC1(Byte, Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMemory::MAP_SETA_DSP:
|
case CMemory::MAP_SETA_DSP:
|
||||||
S9xSetSetaDSP(Byte, Address);
|
S9xSetSetaDSP(Byte, Address);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMemory::MAP_SETA_RISC:
|
case CMemory::MAP_SETA_RISC:
|
||||||
S9xSetST018(Byte, Address);
|
S9xSetST018(Byte, Address);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMemory::MAP_BSX:
|
case CMemory::MAP_BSX:
|
||||||
S9xSetBSX(Byte, Address);
|
S9xSetBSX(Byte, Address);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMemory::MAP_NONE:
|
case CMemory::MAP_NONE:
|
||||||
default:
|
default:
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -527,17 +674,16 @@ inline void S9xSetWord (uint16 Word, uint32 Address, enum s9xwrap_t w = WRAP_NON
|
|||||||
CPU.WaitAddress = 0xffffffff;
|
CPU.WaitAddress = 0xffffffff;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int block;
|
int block = (Address & 0xffffff) >> MEMMAP_SHIFT;
|
||||||
uint8 *SetAddress = Memory.WriteMap[block = ((Address & 0xffffff) >> MEMMAP_SHIFT)];
|
uint8 *SetAddress = Memory.WriteMap[block];
|
||||||
|
int32 speed = memory_speed(Address);
|
||||||
if (!CPU.InDMAorHDMA)
|
|
||||||
CPU.Cycles += (Memory.MemorySpeed[block] << 1);
|
|
||||||
|
|
||||||
if (SetAddress >= (uint8 *) CMemory::MAP_LAST)
|
if (SetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||||
{
|
{
|
||||||
#ifdef CPU_SHUTDOWN
|
#ifdef CPU_SHUTDOWN
|
||||||
SetAddress += (Address & 0xffff);
|
SetAddress += (Address & 0xffff);
|
||||||
WRITE_WORD(SetAddress, Word);
|
WRITE_WORD(SetAddress, Word);
|
||||||
|
addCyclesInMemoryAccess_x2;
|
||||||
|
|
||||||
if (Settings.SA1)
|
if (Settings.SA1)
|
||||||
{
|
{
|
||||||
@ -549,6 +695,7 @@ inline void S9xSetWord (uint16 Word, uint32 Address, enum s9xwrap_t w = WRAP_NON
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
WRITE_WORD(SetAddress + (Address & 0xffff), Word);
|
WRITE_WORD(SetAddress + (Address & 0xffff), Word);
|
||||||
|
addCyclesInMemoryAccess_x2;
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -559,16 +706,20 @@ inline void S9xSetWord (uint16 Word, uint32 Address, enum s9xwrap_t w = WRAP_NON
|
|||||||
if (o)
|
if (o)
|
||||||
{
|
{
|
||||||
S9xSetCPU(Word >> 8, (Address + 1) & 0xffff);
|
S9xSetCPU(Word >> 8, (Address + 1) & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
S9xSetCPU((uint8) Word, Address & 0xffff);
|
S9xSetCPU((uint8) Word, Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
S9xSetCPU((uint8) Word, Address & 0xffff);
|
S9xSetCPU((uint8) Word, Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
S9xSetCPU(Word >> 8, (Address + 1) & 0xffff);
|
S9xSetCPU(Word >> 8, (Address + 1) & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
case CMemory::MAP_PPU:
|
case CMemory::MAP_PPU:
|
||||||
if (CPU.InDMAorHDMA)
|
if (CPU.InDMAorHDMA)
|
||||||
{
|
{
|
||||||
@ -582,16 +733,20 @@ inline void S9xSetWord (uint16 Word, uint32 Address, enum s9xwrap_t w = WRAP_NON
|
|||||||
if (o)
|
if (o)
|
||||||
{
|
{
|
||||||
S9xSetPPU(Word >> 8, (Address + 1) & 0xffff);
|
S9xSetPPU(Word >> 8, (Address + 1) & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
S9xSetPPU((uint8) Word, Address & 0xffff);
|
S9xSetPPU((uint8) Word, Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
S9xSetPPU((uint8) Word, Address & 0xffff);
|
S9xSetPPU((uint8) Word, Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
S9xSetPPU(Word >> 8, (Address + 1) & 0xffff);
|
S9xSetPPU(Word >> 8, (Address + 1) & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
case CMemory::MAP_LOROM_SRAM:
|
case CMemory::MAP_LOROM_SRAM:
|
||||||
if (Memory.SRAMMask)
|
if (Memory.SRAMMask)
|
||||||
{
|
{
|
||||||
@ -606,6 +761,7 @@ inline void S9xSetWord (uint16 Word, uint32 Address, enum s9xwrap_t w = WRAP_NON
|
|||||||
CPU.SRAMModified = TRUE;
|
CPU.SRAMModified = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addCyclesInMemoryAccess_x2;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMemory::MAP_LOROM_SRAM_B:
|
case CMemory::MAP_LOROM_SRAM_B:
|
||||||
@ -622,6 +778,7 @@ inline void S9xSetWord (uint16 Word, uint32 Address, enum s9xwrap_t w = WRAP_NON
|
|||||||
CPU.SRAMModified = TRUE;
|
CPU.SRAMModified = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addCyclesInMemoryAccess_x2;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMemory::MAP_HIROM_SRAM:
|
case CMemory::MAP_HIROM_SRAM:
|
||||||
@ -638,104 +795,132 @@ inline void S9xSetWord (uint16 Word, uint32 Address, enum s9xwrap_t w = WRAP_NON
|
|||||||
CPU.SRAMModified = TRUE;
|
CPU.SRAMModified = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addCyclesInMemoryAccess_x2;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMemory::MAP_BWRAM:
|
case CMemory::MAP_BWRAM:
|
||||||
WRITE_WORD(Memory.BWRAM + ((Address & 0x7fff) - 0x6000), Word);
|
WRITE_WORD(Memory.BWRAM + ((Address & 0x7fff) - 0x6000), Word);
|
||||||
CPU.SRAMModified = TRUE;
|
CPU.SRAMModified = TRUE;
|
||||||
|
addCyclesInMemoryAccess_x2;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMemory::MAP_SA1RAM:
|
case CMemory::MAP_SA1RAM:
|
||||||
WRITE_WORD(Memory.SRAM + (Address & 0xffff), Word);
|
WRITE_WORD(Memory.SRAM + (Address & 0xffff), Word);
|
||||||
SA1.Executing = !SA1.Waiting;
|
SA1.Executing = !SA1.Waiting;
|
||||||
|
addCyclesInMemoryAccess_x2;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CMemory::MAP_DSP:
|
case CMemory::MAP_DSP:
|
||||||
if (o)
|
if (o)
|
||||||
{
|
{
|
||||||
S9xSetDSP(Word >> 8, (Address + 1) & 0xffff);
|
S9xSetDSP(Word >> 8, (Address + 1) & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
S9xSetDSP((uint8) Word, Address & 0xffff);
|
S9xSetDSP((uint8) Word, Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
S9xSetDSP((uint8) Word, Address & 0xffff);
|
S9xSetDSP((uint8) Word, Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
S9xSetDSP(Word >> 8, (Address + 1) & 0xffff);
|
S9xSetDSP(Word >> 8, (Address + 1) & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
case CMemory::MAP_C4:
|
case CMemory::MAP_C4:
|
||||||
if (o)
|
if (o)
|
||||||
{
|
{
|
||||||
S9xSetC4(Word >> 8, (Address + 1) & 0xffff);
|
S9xSetC4(Word >> 8, (Address + 1) & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
S9xSetC4((uint8) Word, Address & 0xffff);
|
S9xSetC4((uint8) Word, Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
S9xSetC4((uint8) Word, Address & 0xffff);
|
S9xSetC4((uint8) Word, Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
S9xSetC4(Word >> 8, (Address + 1) & 0xffff);
|
S9xSetC4(Word >> 8, (Address + 1) & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
case CMemory::MAP_OBC_RAM:
|
case CMemory::MAP_OBC_RAM:
|
||||||
if (o)
|
if (o)
|
||||||
{
|
{
|
||||||
S9xSetOBC1(Word >> 8, (Address + 1) & 0xffff);
|
S9xSetOBC1(Word >> 8, (Address + 1) & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
S9xSetOBC1((uint8) Word, Address & 0xffff);
|
S9xSetOBC1((uint8) Word, Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
S9xSetOBC1((uint8) Word, Address & 0xffff);
|
S9xSetOBC1((uint8) Word, Address & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
S9xSetOBC1(Word >> 8, (Address + 1) & 0xffff);
|
S9xSetOBC1(Word >> 8, (Address + 1) & 0xffff);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
case CMemory::MAP_SETA_DSP:
|
case CMemory::MAP_SETA_DSP:
|
||||||
if (o)
|
if (o)
|
||||||
{
|
{
|
||||||
S9xSetSetaDSP(Word >> 8, Address + 1);
|
S9xSetSetaDSP(Word >> 8, Address + 1);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
S9xSetSetaDSP((uint8) Word, Address);
|
S9xSetSetaDSP((uint8) Word, Address);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
S9xSetSetaDSP((uint8) Word, Address);
|
S9xSetSetaDSP((uint8) Word, Address);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
S9xSetSetaDSP(Word >> 8, Address + 1);
|
S9xSetSetaDSP(Word >> 8, Address + 1);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
case CMemory::MAP_SETA_RISC:
|
case CMemory::MAP_SETA_RISC:
|
||||||
if (o)
|
if (o)
|
||||||
{
|
{
|
||||||
S9xSetST018(Word >> 8, Address + 1);
|
S9xSetST018(Word >> 8, Address + 1);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
S9xSetST018((uint8) Word, Address);
|
S9xSetST018((uint8) Word, Address);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
S9xSetST018((uint8) Word, Address);
|
S9xSetST018((uint8) Word, Address);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
S9xSetST018(Word >> 8, Address + 1);
|
S9xSetST018(Word >> 8, Address + 1);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
case CMemory::MAP_BSX:
|
case CMemory::MAP_BSX:
|
||||||
if (o)
|
if (o)
|
||||||
{
|
{
|
||||||
S9xSetBSX(Word >> 8, Address + 1);
|
S9xSetBSX(Word >> 8, Address + 1);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
S9xSetBSX((uint8) Word, Address);
|
S9xSetBSX((uint8) Word, Address);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
S9xSetBSX((uint8) Word, Address);
|
S9xSetBSX((uint8) Word, Address);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
S9xSetBSX(Word >> 8, Address + 1);
|
S9xSetBSX(Word >> 8, Address + 1);
|
||||||
|
addCyclesInMemoryAccess;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
case CMemory::MAP_NONE:
|
case CMemory::MAP_NONE:
|
||||||
default:
|
default:
|
||||||
|
addCyclesInMemoryAccess_x2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -748,7 +933,7 @@ inline void S9xSetPCBase (uint32 Address)
|
|||||||
int block;
|
int block;
|
||||||
uint8 *GetAddress = Memory.Map[block = ((Address & 0xffffff) >> MEMMAP_SHIFT)];
|
uint8 *GetAddress = Memory.Map[block = ((Address & 0xffffff) >> MEMMAP_SHIFT)];
|
||||||
|
|
||||||
CPU.MemSpeed = Memory.MemorySpeed[block];
|
CPU.MemSpeed = memory_speed(Address);
|
||||||
CPU.MemSpeedx2 = CPU.MemSpeed << 1;
|
CPU.MemSpeedx2 = CPU.MemSpeed << 1;
|
||||||
|
|
||||||
if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
|
if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||||
|
@ -2632,9 +2632,6 @@ void CMemory::InitROM (void)
|
|||||||
Timings.NMIDMADelay = 24;
|
Timings.NMIDMADelay = 24;
|
||||||
Timings.IRQPendCount = 0;
|
Timings.IRQPendCount = 0;
|
||||||
|
|
||||||
CPU.FastROMSpeed = 0;
|
|
||||||
ResetSpeedMap();
|
|
||||||
|
|
||||||
IPPU.TotalEmulatedFrames = 0;
|
IPPU.TotalEmulatedFrames = 0;
|
||||||
|
|
||||||
//// Hack games
|
//// Hack games
|
||||||
@ -2676,36 +2673,6 @@ void CMemory::InitROM (void)
|
|||||||
S9xVerifyControllers();
|
S9xVerifyControllers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMemory::FixROMSpeed (void)
|
|
||||||
{
|
|
||||||
if (CPU.FastROMSpeed == 0)
|
|
||||||
CPU.FastROMSpeed = SLOW_ONE_CYCLE;
|
|
||||||
|
|
||||||
// [80-bf]:[8000-ffff], [c0-ff]:[0000-ffff]
|
|
||||||
for (int c = 0x800; c < 0x1000; c++)
|
|
||||||
{
|
|
||||||
if (c & 0x8 || c & 0x400)
|
|
||||||
MemorySpeed[c] = (uint8) CPU.FastROMSpeed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMemory::ResetSpeedMap (void)
|
|
||||||
{
|
|
||||||
memset(MemorySpeed, SLOW_ONE_CYCLE, 0x1000);
|
|
||||||
|
|
||||||
// Fast - [00-3f|80-bf]:[2000-3fff|4200-5fff]
|
|
||||||
// XSlow - [00-3f|80-bf]:[4000-41ff] see also S9xGet/SetCPU()
|
|
||||||
for (int i = 0; i < 0x400; i += 0x10)
|
|
||||||
{
|
|
||||||
MemorySpeed[i + 2] = MemorySpeed[0x800 + i + 2] = ONE_CYCLE;
|
|
||||||
MemorySpeed[i + 3] = MemorySpeed[0x800 + i + 3] = ONE_CYCLE;
|
|
||||||
MemorySpeed[i + 4] = MemorySpeed[0x800 + i + 4] = ONE_CYCLE;
|
|
||||||
MemorySpeed[i + 5] = MemorySpeed[0x800 + i + 5] = ONE_CYCLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
FixROMSpeed();
|
|
||||||
}
|
|
||||||
|
|
||||||
// memory map
|
// memory map
|
||||||
|
|
||||||
uint32 CMemory::map_mirror (uint32 size, uint32 pos)
|
uint32 CMemory::map_mirror (uint32 size, uint32 pos)
|
||||||
@ -3617,37 +3584,6 @@ void CMemory::ApplyROMFixes (void)
|
|||||||
Timings.HDMAStart = SNES_HDMA_START_HC + Settings.HDMATimingHack - 100;
|
Timings.HDMAStart = SNES_HDMA_START_HC + Settings.HDMATimingHack - 100;
|
||||||
Timings.HBlankStart = SNES_HBLANK_START_HC + Timings.HDMAStart - SNES_HDMA_START_HC;
|
Timings.HBlankStart = SNES_HBLANK_START_HC + Timings.HDMAStart - SNES_HDMA_START_HC;
|
||||||
|
|
||||||
if (!Settings.DisableGameSpecificHacks)
|
|
||||||
{
|
|
||||||
// The HC counter (CPU.Cycles for snes9x) passes over the WRAM refresh point (HC~536)
|
|
||||||
// while preparing to jump to the IRQ vector address.
|
|
||||||
// That is to say, the WRAM refresh point is passed over in S9xOpcode_IRQ().
|
|
||||||
// Then, HDMA starts just after $210e is half updated, and it causes the flicker of the ground.
|
|
||||||
// IRQ timing is bad? HDMA timing is bad? else?
|
|
||||||
if (match_na("GUNDAMW ENDLESSDUEL")) // Shin Kidou Senki Gundam W - Endless Duel
|
|
||||||
{
|
|
||||||
Timings.HDMAStart -= 10;
|
|
||||||
Timings.HBlankStart -= 10;
|
|
||||||
printf("HDMA timing hack: %d\n", Timings.HDMAStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Due to Snes9x's very inaccurate timings,
|
|
||||||
// HDMA transfer to $210D-$2114 between the first and second writings to the same addresses.
|
|
||||||
if (match_na("POWER RANGERS FIGHT")) // Mighty Morphin Power Rangers - The Fighting Edition
|
|
||||||
{
|
|
||||||
Timings.HDMAStart -= 10;
|
|
||||||
Timings.HBlankStart -= 10;
|
|
||||||
printf("HDMA timing hack: %d\n", Timings.HDMAStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match_na("SFX SUPERBUTOUDEN2")) // Dragon Ball Z - Super Butouden 2
|
|
||||||
{
|
|
||||||
Timings.HDMAStart += 20;
|
|
||||||
Timings.HBlankStart += 20;
|
|
||||||
printf("HDMA timing hack: %d\n", Timings.HDMAStart);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Settings.DisableGameSpecificHacks)
|
if (!Settings.DisableGameSpecificHacks)
|
||||||
{
|
{
|
||||||
// The delay to sync CPU and DMA which Snes9x cannot emulate.
|
// The delay to sync CPU and DMA which Snes9x cannot emulate.
|
||||||
@ -3678,6 +3614,12 @@ void CMemory::ApplyROMFixes (void)
|
|||||||
Timings.IRQPendCount = 2;
|
Timings.IRQPendCount = 2;
|
||||||
printf("IRQ count hack: %d\n", Timings.IRQPendCount);
|
printf("IRQ count hack: %d\n", Timings.IRQPendCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (match_na("BATTLE BLAZE"))
|
||||||
|
{
|
||||||
|
Timings.IRQPendCount = 1;
|
||||||
|
printf("IRQ count hack: %d\n", Timings.IRQPendCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Settings.DisableGameSpecificHacks)
|
if (!Settings.DisableGameSpecificHacks)
|
||||||
|
@ -242,7 +242,6 @@ struct CMemory
|
|||||||
uint8 *WriteMap[MEMMAP_NUM_BLOCKS];
|
uint8 *WriteMap[MEMMAP_NUM_BLOCKS];
|
||||||
uint8 BlockIsRAM[MEMMAP_NUM_BLOCKS];
|
uint8 BlockIsRAM[MEMMAP_NUM_BLOCKS];
|
||||||
uint8 BlockIsROM[MEMMAP_NUM_BLOCKS];
|
uint8 BlockIsROM[MEMMAP_NUM_BLOCKS];
|
||||||
uint8 MemorySpeed[MEMMAP_NUM_BLOCKS];
|
|
||||||
uint8 ExtendedFormat;
|
uint8 ExtendedFormat;
|
||||||
|
|
||||||
char ROMFilename[PATH_MAX + 1];
|
char ROMFilename[PATH_MAX + 1];
|
||||||
@ -290,8 +289,6 @@ struct CMemory
|
|||||||
char * SafeANK (const char *);
|
char * SafeANK (const char *);
|
||||||
void ParseSNESHeader (uint8 *);
|
void ParseSNESHeader (uint8 *);
|
||||||
void InitROM (void);
|
void InitROM (void);
|
||||||
void FixROMSpeed (void);
|
|
||||||
void ResetSpeedMap (void);
|
|
||||||
|
|
||||||
uint32 map_mirror (uint32, uint32);
|
uint32 map_mirror (uint32, uint32);
|
||||||
void map_lorom (uint32, uint32, uint32, uint32, uint32);
|
void map_lorom (uint32, uint32, uint32, uint32, uint32);
|
||||||
|
@ -1565,8 +1565,6 @@ void S9xSetCPU (uint8 Byte, uint16 Address)
|
|||||||
{
|
{
|
||||||
if (Address < 0x4200)
|
if (Address < 0x4200)
|
||||||
{
|
{
|
||||||
CPU.Cycles += ONE_CYCLE; // XSlow
|
|
||||||
|
|
||||||
switch (Address)
|
switch (Address)
|
||||||
{
|
{
|
||||||
case 0x4016: // JOYSER0
|
case 0x4016: // JOYSER0
|
||||||
@ -1851,8 +1849,6 @@ void S9xSetCPU (uint8 Byte, uint16 Address)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
CPU.FastROMSpeed = SLOW_ONE_CYCLE;
|
CPU.FastROMSpeed = SLOW_ONE_CYCLE;
|
||||||
|
|
||||||
Memory.FixROMSpeed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -1911,8 +1907,6 @@ uint8 S9xGetCPU (uint16 Address)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CPU.Cycles += ONE_CYCLE; // XSlow
|
|
||||||
|
|
||||||
switch (Address)
|
switch (Address)
|
||||||
{
|
{
|
||||||
case 0x4016: // JOYSER0
|
case 0x4016: // JOYSER0
|
||||||
|
@ -788,13 +788,41 @@ static void S9xSA1CharConv2 (void)
|
|||||||
uint32 offset = (SA1.in_char_dma & 7) ? 0 : 1;
|
uint32 offset = (SA1.in_char_dma & 7) ? 0 : 1;
|
||||||
int depth = (Memory.FillRAM[0x2231] & 3) == 0 ? 8 : (Memory.FillRAM[0x2231] & 3) == 1 ? 4 : 2;
|
int depth = (Memory.FillRAM[0x2231] & 3) == 0 ? 8 : (Memory.FillRAM[0x2231] & 3) == 1 ? 4 : 2;
|
||||||
int bytes_per_char = 8 * depth;
|
int bytes_per_char = 8 * depth;
|
||||||
uint8 *p = &Memory.FillRAM[0x3000] + dest + offset * bytes_per_char;
|
uint8 *p = &Memory.FillRAM[0x3000] + (dest & 0x7ff) + offset * bytes_per_char;
|
||||||
uint8 *q = &Memory.ROM[CMemory::MAX_ROM_SIZE - 0x10000] + offset * 64;
|
uint8 *q = &Memory.ROM[CMemory::MAX_ROM_SIZE - 0x10000] + offset * 64;
|
||||||
|
|
||||||
switch (depth)
|
switch (depth)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
|
for (int l = 0; l < 8; l++, q += 8)
|
||||||
|
{
|
||||||
|
for (int b = 0; b < 8; b++)
|
||||||
|
{
|
||||||
|
uint8 r = *(q + b);
|
||||||
|
*(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1);
|
||||||
|
*(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
p += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
|
for (int l = 0; l < 8; l++, q += 8)
|
||||||
|
{
|
||||||
|
for (int b = 0; b < 8; b++)
|
||||||
|
{
|
||||||
|
uint8 r = *(q + b);
|
||||||
|
*(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1);
|
||||||
|
*(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1);
|
||||||
|
*(p + 16) = (*(p + 16) << 1) | ((r >> 2) & 1);
|
||||||
|
*(p + 17) = (*(p + 17) << 1) | ((r >> 3) & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
p += 2;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8:
|
case 8:
|
||||||
|
@ -209,7 +209,7 @@ bool8 S9xDoScreenshot (int width, int height)
|
|||||||
if (!png_ptr)
|
if (!png_ptr)
|
||||||
{
|
{
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
unlink(fname);
|
remove(fname);
|
||||||
S9xMessage(S9X_ERROR, 0, "Failed to take screenshot.");
|
S9xMessage(S9X_ERROR, 0, "Failed to take screenshot.");
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
@ -219,7 +219,7 @@ bool8 S9xDoScreenshot (int width, int height)
|
|||||||
{
|
{
|
||||||
png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
|
png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
unlink(fname);
|
remove(fname);
|
||||||
S9xMessage(S9X_ERROR, 0, "Failed to take screenshot.");
|
S9xMessage(S9X_ERROR, 0, "Failed to take screenshot.");
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
@ -228,7 +228,7 @@ bool8 S9xDoScreenshot (int width, int height)
|
|||||||
{
|
{
|
||||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
unlink(fname);
|
remove(fname);
|
||||||
S9xMessage(S9X_ERROR, 0, "Failed to take screenshot.");
|
S9xMessage(S9X_ERROR, 0, "Failed to take screenshot.");
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
@ -1692,7 +1692,6 @@ int S9xUnfreezeFromStream (STREAM stream)
|
|||||||
S9xSetPCBase(Registers.PBPC);
|
S9xSetPCBase(Registers.PBPC);
|
||||||
S9xUnpackStatus();
|
S9xUnpackStatus();
|
||||||
S9xFixCycles();
|
S9xFixCycles();
|
||||||
Memory.FixROMSpeed();
|
|
||||||
|
|
||||||
for (int d = 0; d < 8; d++)
|
for (int d = 0; d < 8; d++)
|
||||||
DMA[d] = dma_snap.dma[d];
|
DMA[d] = dma_snap.dma[d];
|
||||||
|
@ -179,13 +179,15 @@
|
|||||||
#define _SNES9X_H_
|
#define _SNES9X_H_
|
||||||
|
|
||||||
#ifndef VERSION
|
#ifndef VERSION
|
||||||
#define VERSION "1.52"
|
#define VERSION "1.53"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
#include "65c816.h"
|
#include "65c816.h"
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
|
|
||||||
|
#define S9X_ACCURACY_LEVEL 3
|
||||||
|
|
||||||
#ifdef ZLIB
|
#ifdef ZLIB
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#define STREAM gzFile
|
#define STREAM gzFile
|
||||||
|
Loading…
Reference in New Issue
Block a user