Update to latest WIP
This commit is contained in:
parent
d1666860e0
commit
debd16c179
45
apu/apu.cpp
45
apu/apu.cpp
@ -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
apu/hermite_resampler.h
Normal file
144
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 */
|
115
apu/linear_resampler.h
Normal file
115
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 */
|
144
apu/resampler.h
144
apu/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 */
|
||||||
|
32
cpu.cpp
32
cpu.cpp
@ -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;
|
||||||
|
60
cpuexec.cpp
60
cpuexec.cpp
@ -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"
|
||||||
|
200
debug.cpp
200
debug.cpp
@ -317,6 +317,10 @@ static int AddrModes[256] =
|
|||||||
4, 11, 9, 20, 26, 7, 7, 13, 0, 16, 0, 0, 23, 15, 15, 18 // F
|
4, 11, 9, 20, 26, 7, 7, 13, 0, 16, 0, 0, 23, 15, 15, 18 // F
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static uint8 S9xDebugGetByte (uint32);
|
||||||
|
static uint16 S9xDebugGetWord (uint32);
|
||||||
|
static uint8 S9xDebugSA1GetByte (uint32);
|
||||||
|
static uint16 S9xDebugSA1GetWord (uint32);
|
||||||
static uint8 debug_cpu_op_print (char *, uint8, uint16);
|
static uint8 debug_cpu_op_print (char *, uint8, uint16);
|
||||||
static uint8 debug_sa1_op_print (char *, uint8, uint16);
|
static uint8 debug_sa1_op_print (char *, uint8, uint16);
|
||||||
static void debug_line_print (const char *);
|
static void debug_line_print (const char *);
|
||||||
@ -329,6 +333,107 @@ static void debug_whats_used (void);
|
|||||||
static void debug_whats_missing (void);
|
static void debug_whats_missing (void);
|
||||||
|
|
||||||
|
|
||||||
|
static uint8 S9xDebugGetByte (uint32 Address)
|
||||||
|
{
|
||||||
|
int block = (Address & 0xffffff) >> MEMMAP_SHIFT;
|
||||||
|
uint8 *GetAddress = Memory.Map[block];
|
||||||
|
uint8 byte = 0;
|
||||||
|
|
||||||
|
if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||||
|
{
|
||||||
|
byte = *(GetAddress + (Address & 0xffff));
|
||||||
|
return (byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ((pint) GetAddress)
|
||||||
|
{
|
||||||
|
case CMemory::MAP_LOROM_SRAM:
|
||||||
|
case CMemory::MAP_SA1RAM:
|
||||||
|
byte = *(Memory.SRAM + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask));
|
||||||
|
return (byte);
|
||||||
|
|
||||||
|
case CMemory::MAP_LOROM_SRAM_B:
|
||||||
|
byte = *(Multi.sramB + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Multi.sramMaskB));
|
||||||
|
return (byte);
|
||||||
|
|
||||||
|
case CMemory::MAP_HIROM_SRAM:
|
||||||
|
case CMemory::MAP_RONLY_SRAM:
|
||||||
|
byte = *(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask));
|
||||||
|
return (byte);
|
||||||
|
|
||||||
|
case CMemory::MAP_BWRAM:
|
||||||
|
byte = *(Memory.BWRAM + ((Address & 0x7fff) - 0x6000));
|
||||||
|
return (byte);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (byte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16 S9xDebugGetWord (uint32 Address)
|
||||||
|
{
|
||||||
|
uint16 word;
|
||||||
|
|
||||||
|
word = S9xDebugGetByte(Address);
|
||||||
|
word |= S9xDebugGetByte(Address + 1) << 8;
|
||||||
|
|
||||||
|
return (word);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8 S9xDebugSA1GetByte (uint32 Address)
|
||||||
|
{
|
||||||
|
int block = (Address & 0xffffff) >> MEMMAP_SHIFT;
|
||||||
|
uint8 *GetAddress = SA1.Map[block];
|
||||||
|
uint8 byte = 0;
|
||||||
|
|
||||||
|
if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||||
|
{
|
||||||
|
byte = *(GetAddress + (Address & 0xffff));
|
||||||
|
return (byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ((pint) GetAddress)
|
||||||
|
{
|
||||||
|
case CMemory::MAP_LOROM_SRAM:
|
||||||
|
case CMemory::MAP_SA1RAM:
|
||||||
|
byte = *(Memory.SRAM + (Address & 0xffff));
|
||||||
|
return (byte);
|
||||||
|
|
||||||
|
case CMemory::MAP_BWRAM:
|
||||||
|
byte = *(SA1.BWRAM + ((Address & 0x7fff) - 0x6000));
|
||||||
|
return (byte);
|
||||||
|
|
||||||
|
case CMemory::MAP_BWRAM_BITMAP:
|
||||||
|
Address -= 0x600000;
|
||||||
|
if (SA1.VirtualBitmapFormat == 2)
|
||||||
|
byte = (Memory.SRAM[(Address >> 2) & 0xffff] >> ((Address & 3) << 1)) & 3;
|
||||||
|
else
|
||||||
|
byte = (Memory.SRAM[(Address >> 1) & 0xffff] >> ((Address & 1) << 2)) & 15;
|
||||||
|
return (byte);
|
||||||
|
|
||||||
|
case CMemory::MAP_BWRAM_BITMAP2:
|
||||||
|
Address = (Address & 0xffff) - 0x6000;
|
||||||
|
if (SA1.VirtualBitmapFormat == 2)
|
||||||
|
byte = (SA1.BWRAM[(Address >> 2) & 0xffff] >> ((Address & 3) << 1)) & 3;
|
||||||
|
else
|
||||||
|
byte = (SA1.BWRAM[(Address >> 1) & 0xffff] >> ((Address & 1) << 2)) & 15;
|
||||||
|
return (byte);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (byte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16 S9xDebugSA1GetWord (uint32 Address)
|
||||||
|
{
|
||||||
|
uint16 word;
|
||||||
|
|
||||||
|
word = S9xDebugSA1GetByte(Address);
|
||||||
|
word |= S9xDebugSA1GetByte(Address + 1) << 8;
|
||||||
|
|
||||||
|
return (word);
|
||||||
|
}
|
||||||
|
|
||||||
static uint8 debug_cpu_op_print (char *Line, uint8 Bank, uint16 Address)
|
static uint8 debug_cpu_op_print (char *Line, uint8 Bank, uint16 Address)
|
||||||
{
|
{
|
||||||
uint8 S9xOpcode;
|
uint8 S9xOpcode;
|
||||||
@ -339,15 +444,12 @@ static uint8 debug_cpu_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
int8 SByte;
|
int8 SByte;
|
||||||
uint8 Size = 0;
|
uint8 Size = 0;
|
||||||
|
|
||||||
int32 Cycles = CPU.Cycles;
|
S9xOpcode = S9xDebugGetByte((Bank << 16) + Address);
|
||||||
uint32 WaitAddress = CPU.WaitAddress;
|
|
||||||
|
|
||||||
S9xOpcode = S9xGetByte((Bank << 16) + Address);
|
|
||||||
sprintf(Line, "$%02X:%04X %02X ", Bank, Address, S9xOpcode);
|
sprintf(Line, "$%02X:%04X %02X ", Bank, Address, S9xOpcode);
|
||||||
|
|
||||||
Operant[0] = S9xGetByte((Bank << 16) + Address + 1);
|
Operant[0] = S9xDebugGetByte((Bank << 16) + Address + 1);
|
||||||
Operant[1] = S9xGetByte((Bank << 16) + Address + 2);
|
Operant[1] = S9xDebugGetByte((Bank << 16) + Address + 2);
|
||||||
Operant[2] = S9xGetByte((Bank << 16) + Address + 3);
|
Operant[2] = S9xDebugGetByte((Bank << 16) + Address + 3);
|
||||||
|
|
||||||
switch (AddrModes[S9xOpcode])
|
switch (AddrModes[S9xOpcode])
|
||||||
{
|
{
|
||||||
@ -505,7 +607,7 @@ static uint8 debug_cpu_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Operant[0]);
|
Operant[0]);
|
||||||
Word = Operant[0];
|
Word = Operant[0];
|
||||||
Word += Registers.D.W;
|
Word += Registers.D.W;
|
||||||
Word = S9xGetWord(Word);
|
Word = S9xDebugGetWord(Word);
|
||||||
sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
|
sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
|
||||||
Size = 2;
|
Size = 2;
|
||||||
break;
|
break;
|
||||||
@ -520,7 +622,7 @@ static uint8 debug_cpu_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Word = Operant[0];
|
Word = Operant[0];
|
||||||
Word += Registers.D.W;
|
Word += Registers.D.W;
|
||||||
Word += Registers.X.W;
|
Word += Registers.X.W;
|
||||||
Word = S9xGetWord(Word);
|
Word = S9xDebugGetWord(Word);
|
||||||
sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
|
sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
|
||||||
Size = 2;
|
Size = 2;
|
||||||
break;
|
break;
|
||||||
@ -534,7 +636,7 @@ static uint8 debug_cpu_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Operant[0]);
|
Operant[0]);
|
||||||
Word = Operant[0];
|
Word = Operant[0];
|
||||||
Word += Registers.D.W;
|
Word += Registers.D.W;
|
||||||
Word = S9xGetWord(Word);
|
Word = S9xDebugGetWord(Word);
|
||||||
Word += Registers.Y.W;
|
Word += Registers.Y.W;
|
||||||
sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
|
sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
|
||||||
Size = 2;
|
Size = 2;
|
||||||
@ -549,8 +651,8 @@ static uint8 debug_cpu_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Operant[0]);
|
Operant[0]);
|
||||||
Word = Operant[0];
|
Word = Operant[0];
|
||||||
Word += Registers.D.W;
|
Word += Registers.D.W;
|
||||||
Byte = S9xGetByte(Word + 2);
|
Byte = S9xDebugGetByte(Word + 2);
|
||||||
Word = S9xGetWord(Word);
|
Word = S9xDebugGetWord(Word);
|
||||||
sprintf(Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
|
sprintf(Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
|
||||||
Size = 2;
|
Size = 2;
|
||||||
break;
|
break;
|
||||||
@ -564,8 +666,8 @@ static uint8 debug_cpu_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Operant[0]);
|
Operant[0]);
|
||||||
Word = Operant[0];
|
Word = Operant[0];
|
||||||
Word += Registers.D.W;
|
Word += Registers.D.W;
|
||||||
Byte = S9xGetByte(Word + 2);
|
Byte = S9xDebugGetByte(Word + 2);
|
||||||
Word = S9xGetWord(Word);
|
Word = S9xDebugGetWord(Word);
|
||||||
Word += Registers.Y.W;
|
Word += Registers.Y.W;
|
||||||
sprintf(Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
|
sprintf(Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
|
||||||
Size = 2;
|
Size = 2;
|
||||||
@ -670,7 +772,7 @@ static uint8 debug_cpu_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Operant[0]);
|
Operant[0]);
|
||||||
Word = Registers.S.W;
|
Word = Registers.S.W;
|
||||||
Word += Operant[0];
|
Word += Operant[0];
|
||||||
Word = S9xGetWord(Word);
|
Word = S9xDebugGetWord(Word);
|
||||||
Word += Registers.Y.W;
|
Word += Registers.Y.W;
|
||||||
sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
|
sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.DB, Word);
|
||||||
Size = 2;
|
Size = 2;
|
||||||
@ -686,7 +788,7 @@ static uint8 debug_cpu_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Operant[1],
|
Operant[1],
|
||||||
Operant[0]);
|
Operant[0]);
|
||||||
Word = (Operant[1] << 8) | Operant[0];
|
Word = (Operant[1] << 8) | Operant[0];
|
||||||
Word = S9xGetWord(Word);
|
Word = S9xDebugGetWord(Word);
|
||||||
sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.PB, Word);
|
sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.PB, Word);
|
||||||
Size = 3;
|
Size = 3;
|
||||||
break;
|
break;
|
||||||
@ -701,8 +803,8 @@ static uint8 debug_cpu_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Operant[1],
|
Operant[1],
|
||||||
Operant[0]);
|
Operant[0]);
|
||||||
Word = (Operant[1] << 8) | Operant[0];
|
Word = (Operant[1] << 8) | Operant[0];
|
||||||
Byte = S9xGetByte(Word + 2);
|
Byte = S9xDebugGetByte(Word + 2);
|
||||||
Word = S9xGetWord(Word);
|
Word = S9xDebugGetWord(Word);
|
||||||
sprintf(Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
|
sprintf(Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
|
||||||
Size = 3;
|
Size = 3;
|
||||||
break;
|
break;
|
||||||
@ -718,7 +820,7 @@ static uint8 debug_cpu_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Operant[0]);
|
Operant[0]);
|
||||||
Word = (Operant[1] << 8) | Operant[0];
|
Word = (Operant[1] << 8) | Operant[0];
|
||||||
Word += Registers.X.W;
|
Word += Registers.X.W;
|
||||||
Word = S9xGetWord(ICPU.ShiftedPB + Word);
|
Word = S9xDebugGetWord(ICPU.ShiftedPB + Word);
|
||||||
sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.PB, Word);
|
sprintf(Line, "%-32s[$%02X:%04X]", Line, Registers.PB, Word);
|
||||||
Size = 3;
|
Size = 3;
|
||||||
break;
|
break;
|
||||||
@ -764,7 +866,7 @@ static uint8 debug_cpu_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Operant[0]);
|
Operant[0]);
|
||||||
Word = Operant[0];
|
Word = Operant[0];
|
||||||
Word += Registers.D.W;
|
Word += Registers.D.W;
|
||||||
Word = S9xGetWord(Word);
|
Word = S9xDebugGetWord(Word);
|
||||||
sprintf(Line, "%-32s[$%04X]", Line, Word);
|
sprintf(Line, "%-32s[$%04X]", Line, Word);
|
||||||
Size = 2;
|
Size = 2;
|
||||||
break;
|
break;
|
||||||
@ -782,14 +884,11 @@ static uint8 debug_cpu_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
CheckIRQ() ? 'I' : 'i',
|
CheckIRQ() ? 'I' : 'i',
|
||||||
CheckZero() ? 'Z' : 'z',
|
CheckZero() ? 'Z' : 'z',
|
||||||
CheckCarry() ? 'C' : 'c',
|
CheckCarry() ? 'C' : 'c',
|
||||||
(long) Cycles,
|
(long) CPU.Cycles,
|
||||||
(long) CPU.V_Counter,
|
(long) CPU.V_Counter,
|
||||||
IPPU.FrameCount,
|
IPPU.FrameCount,
|
||||||
CPU.IRQActive);
|
CPU.IRQActive);
|
||||||
|
|
||||||
CPU.Cycles = Cycles;
|
|
||||||
CPU.WaitAddress = WaitAddress;
|
|
||||||
|
|
||||||
return (Size);
|
return (Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -803,12 +902,12 @@ static uint8 debug_sa1_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
int8 SByte;
|
int8 SByte;
|
||||||
uint8 Size = 0;
|
uint8 Size = 0;
|
||||||
|
|
||||||
S9xOpcode = S9xSA1GetByte((Bank << 16) + Address);
|
S9xOpcode = S9xDebugSA1GetByte((Bank << 16) + Address);
|
||||||
sprintf(Line, "$%02X:%04X %02X ", Bank, Address, S9xOpcode);
|
sprintf(Line, "$%02X:%04X %02X ", Bank, Address, S9xOpcode);
|
||||||
|
|
||||||
Operant[0] = S9xSA1GetByte((Bank << 16) + Address + 1);
|
Operant[0] = S9xDebugSA1GetByte((Bank << 16) + Address + 1);
|
||||||
Operant[1] = S9xSA1GetByte((Bank << 16) + Address + 2);
|
Operant[1] = S9xDebugSA1GetByte((Bank << 16) + Address + 2);
|
||||||
Operant[2] = S9xSA1GetByte((Bank << 16) + Address + 3);
|
Operant[2] = S9xDebugSA1GetByte((Bank << 16) + Address + 3);
|
||||||
|
|
||||||
switch (AddrModes[S9xOpcode])
|
switch (AddrModes[S9xOpcode])
|
||||||
{
|
{
|
||||||
@ -966,7 +1065,7 @@ static uint8 debug_sa1_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Operant[0]);
|
Operant[0]);
|
||||||
Word = Operant[0];
|
Word = Operant[0];
|
||||||
Word += SA1Registers.D.W;
|
Word += SA1Registers.D.W;
|
||||||
Word = S9xSA1GetWord(Word);
|
Word = S9xDebugSA1GetWord(Word);
|
||||||
sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
|
sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
|
||||||
Size = 2;
|
Size = 2;
|
||||||
break;
|
break;
|
||||||
@ -981,7 +1080,7 @@ static uint8 debug_sa1_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Word = Operant[0];
|
Word = Operant[0];
|
||||||
Word += SA1Registers.D.W;
|
Word += SA1Registers.D.W;
|
||||||
Word += SA1Registers.X.W;
|
Word += SA1Registers.X.W;
|
||||||
Word = S9xSA1GetWord(Word);
|
Word = S9xDebugSA1GetWord(Word);
|
||||||
sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
|
sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
|
||||||
Size = 2;
|
Size = 2;
|
||||||
break;
|
break;
|
||||||
@ -995,7 +1094,7 @@ static uint8 debug_sa1_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Operant[0]);
|
Operant[0]);
|
||||||
Word = Operant[0];
|
Word = Operant[0];
|
||||||
Word += SA1Registers.D.W;
|
Word += SA1Registers.D.W;
|
||||||
Word = S9xSA1GetWord(Word);
|
Word = S9xDebugSA1GetWord(Word);
|
||||||
Word += SA1Registers.Y.W;
|
Word += SA1Registers.Y.W;
|
||||||
sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
|
sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
|
||||||
Size = 2;
|
Size = 2;
|
||||||
@ -1010,8 +1109,8 @@ static uint8 debug_sa1_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Operant[0]);
|
Operant[0]);
|
||||||
Word = Operant[0];
|
Word = Operant[0];
|
||||||
Word += SA1Registers.D.W;
|
Word += SA1Registers.D.W;
|
||||||
Byte = S9xSA1GetByte(Word + 2);
|
Byte = S9xDebugSA1GetByte(Word + 2);
|
||||||
Word = S9xSA1GetWord(Word);
|
Word = S9xDebugSA1GetWord(Word);
|
||||||
sprintf(Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
|
sprintf(Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
|
||||||
Size = 2;
|
Size = 2;
|
||||||
break;
|
break;
|
||||||
@ -1025,8 +1124,8 @@ static uint8 debug_sa1_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Operant[0]);
|
Operant[0]);
|
||||||
Word = Operant[0];
|
Word = Operant[0];
|
||||||
Word += SA1Registers.D.W;
|
Word += SA1Registers.D.W;
|
||||||
Byte = S9xSA1GetByte(Word + 2);
|
Byte = S9xDebugSA1GetByte(Word + 2);
|
||||||
Word = S9xSA1GetWord(Word);
|
Word = S9xDebugSA1GetWord(Word);
|
||||||
Word += SA1Registers.Y.W;
|
Word += SA1Registers.Y.W;
|
||||||
sprintf(Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
|
sprintf(Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
|
||||||
Size = 2;
|
Size = 2;
|
||||||
@ -1131,7 +1230,7 @@ static uint8 debug_sa1_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Operant[0]);
|
Operant[0]);
|
||||||
Word = SA1Registers.S.W;
|
Word = SA1Registers.S.W;
|
||||||
Word += Operant[0];
|
Word += Operant[0];
|
||||||
Word = S9xSA1GetWord(Word);
|
Word = S9xDebugSA1GetWord(Word);
|
||||||
Word += SA1Registers.Y.W;
|
Word += SA1Registers.Y.W;
|
||||||
sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
|
sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.DB, Word);
|
||||||
Size = 2;
|
Size = 2;
|
||||||
@ -1147,7 +1246,7 @@ static uint8 debug_sa1_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Operant[1],
|
Operant[1],
|
||||||
Operant[0]);
|
Operant[0]);
|
||||||
Word = (Operant[1] << 8) | Operant[0];
|
Word = (Operant[1] << 8) | Operant[0];
|
||||||
Word = S9xSA1GetWord(Word);
|
Word = S9xDebugSA1GetWord(Word);
|
||||||
sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.PB, Word);
|
sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.PB, Word);
|
||||||
Size = 3;
|
Size = 3;
|
||||||
break;
|
break;
|
||||||
@ -1162,8 +1261,8 @@ static uint8 debug_sa1_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Operant[1],
|
Operant[1],
|
||||||
Operant[0]);
|
Operant[0]);
|
||||||
Word = (Operant[1] << 8) | Operant[0];
|
Word = (Operant[1] << 8) | Operant[0];
|
||||||
Byte = S9xSA1GetByte(Word + 2);
|
Byte = S9xDebugSA1GetByte(Word + 2);
|
||||||
Word = S9xSA1GetWord(Word);
|
Word = S9xDebugSA1GetWord(Word);
|
||||||
sprintf(Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
|
sprintf(Line, "%-32s[$%02X:%04X]", Line, Byte, Word);
|
||||||
Size = 3;
|
Size = 3;
|
||||||
break;
|
break;
|
||||||
@ -1179,7 +1278,7 @@ static uint8 debug_sa1_op_print (char *Line, uint8 Bank, uint16 Address)
|
|||||||
Operant[0]);
|
Operant[0]);
|
||||||
Word = (Operant[1] << 8) | Operant[0];
|
Word = (Operant[1] << 8) | Operant[0];
|
||||||
Word += SA1Registers.X.W;
|
Word += SA1Registers.X.W;
|
||||||
Word = S9xSA1GetWord(SA1.ShiftedPB + Word);
|
Word = S9xDebugSA1GetWord(SA1.ShiftedPB + Word);
|
||||||
sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.PB, Word);
|
sprintf(Line, "%-32s[$%02X:%04X]", Line, SA1Registers.PB, Word);
|
||||||
Size = 3;
|
Size = 3;
|
||||||
break;
|
break;
|
||||||
@ -1275,7 +1374,7 @@ static void debug_process_command (char *Line)
|
|||||||
if (fs)
|
if (fs)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < Count; i++)
|
for (int i = 0; i < Count; i++)
|
||||||
putc(S9xGetByte(Address + i), fs);
|
putc(S9xDebugGetByte(Address + i), fs);
|
||||||
fclose(fs);
|
fclose(fs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1292,17 +1391,17 @@ static void debug_process_command (char *Line)
|
|||||||
printf("Vectors:\n");
|
printf("Vectors:\n");
|
||||||
sprintf(string, " 8 Bit 16 Bit ");
|
sprintf(string, " 8 Bit 16 Bit ");
|
||||||
debug_line_print(string);
|
debug_line_print(string);
|
||||||
sprintf(string, "ABT $00:%04X|$00:%04X", S9xGetWord(0xFFF8), S9xGetWord(0xFFE8));
|
sprintf(string, "ABT $00:%04X|$00:%04X", S9xDebugGetWord(0xFFF8), S9xDebugGetWord(0xFFE8));
|
||||||
debug_line_print(string);
|
debug_line_print(string);
|
||||||
sprintf(string, "BRK $00:%04X|$00:%04X", S9xGetWord(0xFFFE), S9xGetWord(0xFFE6));
|
sprintf(string, "BRK $00:%04X|$00:%04X", S9xDebugGetWord(0xFFFE), S9xDebugGetWord(0xFFE6));
|
||||||
debug_line_print(string);
|
debug_line_print(string);
|
||||||
sprintf(string, "COP $00:%04X|$00:%04X", S9xGetWord(0xFFF4), S9xGetWord(0xFFE4));
|
sprintf(string, "COP $00:%04X|$00:%04X", S9xDebugGetWord(0xFFF4), S9xDebugGetWord(0xFFE4));
|
||||||
debug_line_print(string);
|
debug_line_print(string);
|
||||||
sprintf(string, "IRQ $00:%04X|$00:%04X", S9xGetWord(0xFFFE), S9xGetWord(0xFFEE));
|
sprintf(string, "IRQ $00:%04X|$00:%04X", S9xDebugGetWord(0xFFFE), S9xDebugGetWord(0xFFEE));
|
||||||
debug_line_print(string);
|
debug_line_print(string);
|
||||||
sprintf(string, "NMI $00:%04X|$00:%04X", S9xGetWord(0xFFFA), S9xGetWord(0xFFEA));
|
sprintf(string, "NMI $00:%04X|$00:%04X", S9xDebugGetWord(0xFFFA), S9xDebugGetWord(0xFFEA));
|
||||||
debug_line_print(string);
|
debug_line_print(string);
|
||||||
sprintf(string, "RES $00:%04X", S9xGetWord(0xFFFC));
|
sprintf(string, "RES $00:%04X", S9xDebugGetWord(0xFFFC));
|
||||||
debug_line_print(string);
|
debug_line_print(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1733,7 +1832,6 @@ static void debug_process_command (char *Line)
|
|||||||
int CLine;
|
int CLine;
|
||||||
int CByte;
|
int CByte;
|
||||||
uint8 MemoryByte;
|
uint8 MemoryByte;
|
||||||
int32 Cycles = CPU.Cycles;
|
|
||||||
|
|
||||||
if (Debug.Dump.Bank != 0 || Debug.Dump.Address != 0)
|
if (Debug.Dump.Bank != 0 || Debug.Dump.Address != 0)
|
||||||
{
|
{
|
||||||
@ -1756,7 +1854,7 @@ static void debug_process_command (char *Line)
|
|||||||
Address + CByte == 0x4210)
|
Address + CByte == 0x4210)
|
||||||
MemoryByte = 0;
|
MemoryByte = 0;
|
||||||
else
|
else
|
||||||
MemoryByte = S9xGetByte((Bank << 16) + Address + CByte);
|
MemoryByte = S9xDebugGetByte((Bank << 16) + Address + CByte);
|
||||||
|
|
||||||
sprintf(string, "%s %02X", string, MemoryByte);
|
sprintf(string, "%s %02X", string, MemoryByte);
|
||||||
}
|
}
|
||||||
@ -1772,7 +1870,7 @@ static void debug_process_command (char *Line)
|
|||||||
Address + CByte == 0x4210)
|
Address + CByte == 0x4210)
|
||||||
MemoryByte = 0;
|
MemoryByte = 0;
|
||||||
else
|
else
|
||||||
MemoryByte = S9xGetByte((Bank << 16) + Address + CByte);
|
MemoryByte = S9xDebugGetByte((Bank << 16) + Address + CByte);
|
||||||
|
|
||||||
if (MemoryByte < 32 || MemoryByte >= 127)
|
if (MemoryByte < 32 || MemoryByte >= 127)
|
||||||
MemoryByte = '?';
|
MemoryByte = '?';
|
||||||
@ -1787,8 +1885,6 @@ static void debug_process_command (char *Line)
|
|||||||
|
|
||||||
Debug.Dump.Bank = Bank;
|
Debug.Dump.Bank = Bank;
|
||||||
Debug.Dump.Address = Address;
|
Debug.Dump.Address = Address;
|
||||||
|
|
||||||
CPU.Cycles = Cycles;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*Line == 'q')
|
if (*Line == 'q')
|
||||||
|
110
dma.cpp
110
dma.cpp
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,11 +291,6 @@
|
|||||||
<p>
|
<p>
|
||||||
Called once a complete SNES screen has been rendered into the <code>GFX.Screen</code> memory buffer, now is your chance to copy the SNES rendered screen to the host computer's screen memory. The problem is that you have to cope with different sized SNES rendered screens: 256*224, 256*239, 512*224, 512*239, 512*448 and 512*478.
|
Called once a complete SNES screen has been rendered into the <code>GFX.Screen</code> memory buffer, now is your chance to copy the SNES rendered screen to the host computer's screen memory. The problem is that you have to cope with different sized SNES rendered screens: 256*224, 256*239, 512*224, 512*239, 512*448 and 512*478.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3><code>bool8 S9xContinueUpdate (int width, int height)</code></h3>
|
|
||||||
<p>
|
|
||||||
Similar to <code>S9xDeinitUpdate</code>, but in interlace mode (512*448 or 512*478) only. Called once an even frame has been rendered into the <code>GFX.Screen</code> memory buffer.
|
|
||||||
</p>
|
|
||||||
<h3><code>void S9xMessage (int type, int number, const char *message)</code></h3>
|
<h3><code>void S9xMessage (int type, int number, const char *message)</code></h3>
|
||||||
<p>
|
<p>
|
||||||
When Snes9x wants to display an error, information or warning message, it calls this function. Check in <code>messages.h</code> for the types and individual message numbers that Snes9x currently passes as parameters.<br>
|
When Snes9x wants to display an error, information or warning message, it calls this function. Check in <code>messages.h</code> for the types and individual message numbers that Snes9x currently passes as parameters.<br>
|
||||||
@ -384,7 +379,7 @@
|
|||||||
The sound generation rate on a SNES is directly proportional to the video output rate. Displays that synchronize with the vertical refresh but have a slightly lower refresh-rate than the emulated system can experience sound drop-outs. It may be beneficial to provide an option for users to configure <code>Settings.SoundInputRate</code> to suit their own systems. Setting <code>Settings.SoundInputRate</code> to a value that matches the actual output rate (i.e. 31977hz for 59.96hz) or lower will allow the users to eliminate crackling. A range of 31000hz to 33000hz should be inclusive enough for all displays. Use of this setting paired with the <code>S9xSyncSound</code> function can eliminate sound discontinuity.
|
The sound generation rate on a SNES is directly proportional to the video output rate. Displays that synchronize with the vertical refresh but have a slightly lower refresh-rate than the emulated system can experience sound drop-outs. It may be beneficial to provide an option for users to configure <code>Settings.SoundInputRate</code> to suit their own systems. Setting <code>Settings.SoundInputRate</code> to a value that matches the actual output rate (i.e. 31977hz for 59.96hz) or lower will allow the users to eliminate crackling. A range of 31000hz to 33000hz should be inclusive enough for all displays. Use of this setting paired with the <code>S9xSyncSound</code> function can eliminate sound discontinuity.
|
||||||
</p>
|
</p>
|
||||||
<div style="text-align:right; margin-top:3em">
|
<div style="text-align:right; margin-top:3em">
|
||||||
Updated most recently by: 2010/01/09 zones
|
Updated most recently by: 2009/12/20 zones
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
2
fxinst.h
2
fxinst.h
@ -371,7 +371,7 @@ struct FxRegs_s
|
|||||||
uint32 vCounter;
|
uint32 vCounter;
|
||||||
uint32 vInstCount;
|
uint32 vInstCount;
|
||||||
uint32 vSCBRDirty; // If SCBR is written, our cached screen pointers need updating
|
uint32 vSCBRDirty; // If SCBR is written, our cached screen pointers need updating
|
||||||
|
|
||||||
uint8 *avRegAddr; // To reference avReg in snapshot.cpp
|
uint8 *avRegAddr; // To reference avReg in snapshot.cpp
|
||||||
};
|
};
|
||||||
|
|
||||||
|
335
getset.h
335
getset.h
@ -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)
|
||||||
|
14
gfx.cpp
14
gfx.cpp
@ -2013,6 +2013,20 @@ static void DisplayStringFromBottom (const char *string, int linesFromBottom, in
|
|||||||
static void DisplayFrameRate (void)
|
static void DisplayFrameRate (void)
|
||||||
{
|
{
|
||||||
char string[10];
|
char string[10];
|
||||||
|
static uint32 lastFrameCount = 0, calcFps = 0;
|
||||||
|
static time_t lastTime = time(NULL);
|
||||||
|
|
||||||
|
time_t currTime = time(NULL);
|
||||||
|
if (lastTime != currTime) {
|
||||||
|
if (lastFrameCount < IPPU.TotalEmulatedFrames) {
|
||||||
|
calcFps = (IPPU.TotalEmulatedFrames - lastFrameCount) / (uint32)(currTime - lastTime);
|
||||||
|
}
|
||||||
|
lastTime = currTime;
|
||||||
|
lastFrameCount = IPPU.TotalEmulatedFrames;
|
||||||
|
}
|
||||||
|
sprintf(string, "%u fps", calcFps);
|
||||||
|
S9xDisplayString(string, 2, IPPU.RenderedScreenWidth - (font_width - 1) * strlen(string) - 1, false);
|
||||||
|
|
||||||
#ifdef DEBUGGER
|
#ifdef DEBUGGER
|
||||||
const int len = 8;
|
const int len = 8;
|
||||||
sprintf(string, "%02d/%02d %02d", (int) IPPU.DisplayedRenderedFrameCount, (int) Memory.ROMFramesPerSecond, (int) IPPU.FrameCount);
|
sprintf(string, "%02d/%02d %02d", (int) IPPU.DisplayedRenderedFrameCount, (int) Memory.ROMFramesPerSecond, (int) IPPU.FrameCount);
|
||||||
|
@ -20,37 +20,53 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|||||||
#define __PORTABLE_H
|
#define __PORTABLE_H
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef signed char INT8;
|
typedef int8_t INT8;
|
||||||
typedef unsigned char UINT8;
|
typedef uint8_t UINT8;
|
||||||
typedef short INT16;
|
typedef int16_t INT16;
|
||||||
typedef unsigned short UINT16;
|
typedef uint16_t UINT16;
|
||||||
typedef long INT32;
|
typedef int32_t INT32;
|
||||||
typedef unsigned long UINT32;
|
typedef uint32_t UINT32;
|
||||||
|
typedef int64_t INT64;
|
||||||
|
typedef uint64_t UINT64;
|
||||||
|
typedef uintptr_t UINT_PTR;
|
||||||
|
|
||||||
//Not correct, but should work for Snes9x
|
#else
|
||||||
typedef int INT64;
|
|
||||||
typedef unsigned int UINT64;
|
|
||||||
//typedef long long INT64;
|
|
||||||
//typedef unsigned long long UINT64;
|
|
||||||
|
|
||||||
typedef UINT8 BYTE;
|
typedef signed char INT8;
|
||||||
|
typedef unsigned char UINT8;
|
||||||
|
typedef short INT16;
|
||||||
|
typedef unsigned short UINT16;
|
||||||
|
typedef int INT32;
|
||||||
|
typedef unsigned int UINT32;
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
typedef __int64 INT64;
|
||||||
|
typedef unsigned __int64 UINT64;
|
||||||
|
#else
|
||||||
|
typedef long long INT64;
|
||||||
|
typedef unsigned long long UINT64;
|
||||||
|
#endif
|
||||||
|
typedef unsigned UINT_PTR;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef UINT8 BYTE;
|
||||||
typedef UINT16 WORD;
|
typedef UINT16 WORD;
|
||||||
typedef UINT32 DWORD;
|
typedef UINT32 DWORD;
|
||||||
|
|
||||||
typedef unsigned UINT_PTR;
|
|
||||||
|
|
||||||
typedef int BOOL;
|
typedef int BOOL;
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
|
|
||||||
#define HRESULT int
|
#define HRESULT int
|
||||||
#define S_OK 0
|
#define S_OK 0
|
||||||
#define E_INVALIDARG -1
|
#define E_INVALIDARG -1
|
||||||
#define E_OUTOFMEMORY -2
|
#define E_OUTOFMEMORY -2
|
||||||
#define E_FAIL -3
|
#define E_FAIL -3
|
||||||
#define E_INTERNAL_ERROR -4
|
#define E_INTERNAL_ERROR -4
|
||||||
#define E_INVALIDDATA -5
|
#define E_INVALIDDATA -5
|
||||||
|
|
||||||
template <class T> inline T MyMin(T a, T b) {
|
template <class T> inline T MyMin(T a, T b) {
|
||||||
return a < b ? a : b;
|
return a < b ? a : b;
|
||||||
@ -63,24 +79,24 @@ template <class T> inline T MyMax(T a, T b) {
|
|||||||
#define RETURN_IF_NOT_S_OK(x) { HRESULT __aResult_ = (x); if(__aResult_ != S_OK) return __aResult_; }
|
#define RETURN_IF_NOT_S_OK(x) { HRESULT __aResult_ = (x); if(__aResult_ != S_OK) return __aResult_; }
|
||||||
|
|
||||||
|
|
||||||
#define UINT_SIZE (4)
|
#define UINT_SIZE ((int)sizeof(unsigned int))
|
||||||
#define USHORT_SIZE (2)
|
#define USHORT_SIZE ((int)sizeof(unsigned short))
|
||||||
|
|
||||||
//Convert an array of 4 bytes back into an integer
|
//Convert an array of 4 bytes back into an integer
|
||||||
inline unsigned int charp_to_uint(const unsigned char buffer[UINT_SIZE])
|
inline UINT32 charp_to_uint(const UINT8 buffer[UINT_SIZE])
|
||||||
{
|
{
|
||||||
unsigned int num = (unsigned int)buffer[3];
|
UINT32 num = (UINT32)buffer[3];
|
||||||
num |= ((unsigned int)buffer[2]) << 8;
|
num |= ((UINT32)buffer[2]) << 8;
|
||||||
num |= ((unsigned int)buffer[1]) << 16;
|
num |= ((UINT32)buffer[1]) << 16;
|
||||||
num |= ((unsigned int)buffer[0]) << 24;
|
num |= ((UINT32)buffer[0]) << 24;
|
||||||
return(num);
|
return(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Convert an array of 2 bytes back into a short integer
|
//Convert an array of 2 bytes back into a short integer
|
||||||
inline unsigned short charp_to_ushort(const unsigned char buffer[USHORT_SIZE])
|
inline UINT16 charp_to_ushort(const UINT8 buffer[USHORT_SIZE])
|
||||||
{
|
{
|
||||||
unsigned short num = (unsigned short)buffer[1];
|
UINT16 num = (UINT16)buffer[1];
|
||||||
num |= ((unsigned short)buffer[0]) << 8;
|
num |= ((UINT16)buffer[0]) << 8;
|
||||||
return(num);
|
return(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,8 +64,9 @@ public:
|
|||||||
MoveBlockBackward();
|
MoveBlockBackward();
|
||||||
BYTE *p = m_Buffer + m_Pos;
|
BYTE *p = m_Buffer + m_Pos;
|
||||||
aDistance++;
|
aDistance++;
|
||||||
|
BYTE *p2 = p - aDistance;
|
||||||
for(UINT32 i = 0; i < aLen; i++)
|
for(UINT32 i = 0; i < aLen; i++)
|
||||||
p[i] = p[i - aDistance];
|
p[i] = p2[i];
|
||||||
m_Pos += aLen;
|
m_Pos += aLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
70
memmap.cpp
70
memmap.cpp
@ -2611,9 +2611,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
|
||||||
@ -2655,36 +2652,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)
|
||||||
@ -3596,37 +3563,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.
|
||||||
@ -3657,6 +3593,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)
|
||||||
|
3
memmap.h
3
memmap.h
@ -239,7 +239,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];
|
||||||
@ -287,8 +286,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);
|
||||||
|
@ -194,7 +194,7 @@
|
|||||||
#include "win32/wsnes9x.h"
|
#include "win32/wsnes9x.h"
|
||||||
|
|
||||||
#define ioctl ioctlsocket
|
#define ioctl ioctlsocket
|
||||||
#define close closesocket
|
#define close(h) if(h){closesocket(h);}
|
||||||
#define read(a,b,c) recv(a, b, c, 0)
|
#define read(a,b,c) recv(a, b, c, 0)
|
||||||
#define write(a,b,c) send(a, b, c, 0)
|
#define write(a,b,c) send(a, b, c, 0)
|
||||||
#else
|
#else
|
||||||
|
8
port.h
8
port.h
@ -224,11 +224,15 @@ typedef uint32_t uint32;
|
|||||||
typedef int64_t int64;
|
typedef int64_t int64;
|
||||||
typedef uint64_t uint64;
|
typedef uint64_t uint64;
|
||||||
#else // HAVE_STDINT_H
|
#else // HAVE_STDINT_H
|
||||||
|
#ifdef __WIN32__
|
||||||
|
typedef intptr_t pint;
|
||||||
|
#else // __WIN32__
|
||||||
#ifdef PTR_NOT_INT
|
#ifdef PTR_NOT_INT
|
||||||
typedef long pint;
|
typedef long pint;
|
||||||
#else
|
#else
|
||||||
typedef int pint;
|
typedef int pint;
|
||||||
#endif
|
#endif
|
||||||
|
#endif // __WIN32__
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
#ifdef __BORLANDC__
|
#ifdef __BORLANDC__
|
||||||
#include <systypes.h>
|
#include <systypes.h>
|
||||||
@ -300,6 +304,8 @@ void _makepath (char *, const char *, const char *, const char *, const char *);
|
|||||||
#define strncasecmp strnicmp
|
#define strncasecmp strnicmp
|
||||||
void WinDisplayStringFromBottom(const char *string, int linesFromBottom, int pixelsFromLeft, bool allowWrap);
|
void WinDisplayStringFromBottom(const char *string, int linesFromBottom, int pixelsFromLeft, bool allowWrap);
|
||||||
#define S9xDisplayString WinDisplayStringFromBottom
|
#define S9xDisplayString WinDisplayStringFromBottom
|
||||||
|
void SetInfoDlgColor(unsigned char, unsigned char, unsigned char);
|
||||||
|
#define SET_UI_COLOR(r,g,b) SetInfoDlgColor(r,g,b)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __DJGPP
|
#ifdef __DJGPP
|
||||||
@ -323,7 +329,7 @@ void WinDisplayStringFromBottom(const char *string, int linesFromBottom, int pix
|
|||||||
#define TITLE "Snes9x"
|
#define TITLE "Snes9x"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(__x86_64__) || defined(__alpha__) || defined(__MIPSEL__) || defined(_M_IX86)
|
#if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(__x86_64__) || defined(__alpha__) || defined(__MIPSEL__) || defined(_M_IX86) || defined(_M_X64)
|
||||||
#define LSB_FIRST
|
#define LSB_FIRST
|
||||||
#define FAST_LSB_WORD_ACCESS
|
#define FAST_LSB_WORD_ACCESS
|
||||||
#else
|
#else
|
||||||
|
6
ppu.cpp
6
ppu.cpp
@ -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
|
||||||
|
30
sa1.cpp
30
sa1.cpp
@ -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];
|
||||||
|
4
snes9x.h
4
snes9x.h
@ -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