more virtualjaguar cleanup, fix various bugs, have the DSP run more in sync with the CPU/GPU (makes Zoop boot, Doom is much less laggy, various missing sound issues are no longer present)
This commit is contained in:
parent
2e5c62f632
commit
71f2676ad8
Binary file not shown.
|
@ -1,15 +1,14 @@
|
|||
#include "jaguar.h"
|
||||
#include "file.h"
|
||||
#include "rom.h"
|
||||
#include "settings.h"
|
||||
#include "memory.h"
|
||||
#include "tom.h"
|
||||
#include "gpu.h"
|
||||
#include "dsp.h"
|
||||
#include "dac.h"
|
||||
#include "joystick.h"
|
||||
#include "m68000/m68kinterface.h"
|
||||
|
||||
#include "blip_buf.h"
|
||||
|
||||
#include <emulibc.h>
|
||||
#include <waterboxcore.h>
|
||||
|
||||
|
@ -34,22 +33,11 @@ struct BizSettings
|
|||
u8 useFastBlitter;
|
||||
};
|
||||
|
||||
void SoundCallback(u16 * buffer, int length);
|
||||
static u16* soundBuf;
|
||||
static blip_t* blipL;
|
||||
static blip_t* blipR;
|
||||
static s16 latchL, latchR;
|
||||
|
||||
static void InitCommon(BizSettings* bizSettings)
|
||||
{
|
||||
vjs.hardwareTypeNTSC = bizSettings->hardwareTypeNTSC;
|
||||
vjs.useJaguarBIOS = bizSettings->useJaguarBIOS;
|
||||
vjs.useFastBlitter = bizSettings->useFastBlitter;
|
||||
soundBuf = alloc_invisible<u16>(2048);
|
||||
blipL = blip_new(1024);
|
||||
blipR = blip_new(1024);
|
||||
blip_set_rates(blipL, 48000, 44100);
|
||||
blip_set_rates(blipR, 48000, 44100);
|
||||
JaguarInit();
|
||||
}
|
||||
|
||||
|
@ -57,9 +45,9 @@ EXPORT bool Init(BizSettings* bizSettings, u8* boot, u8* rom, u32 sz)
|
|||
{
|
||||
InitCommon(bizSettings);
|
||||
|
||||
if (!JaguarLoadFile(rom, sz))
|
||||
if (!JaguarLoadROM(rom, sz))
|
||||
{
|
||||
if (!AlpineLoadFile(rom, sz))
|
||||
if (!AlpineLoadROM(rom, sz))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -68,7 +56,7 @@ EXPORT bool Init(BizSettings* bizSettings, u8* boot, u8* rom, u32 sz)
|
|||
}
|
||||
else
|
||||
{
|
||||
vjs.hardwareTypeAlpine = ParseFileType(rom, sz) == JST_ALPINE;
|
||||
vjs.hardwareTypeAlpine = ParseROMType(rom, sz) == JST_ALPINE;
|
||||
}
|
||||
|
||||
SET32(jaguarMainRAM, 0, 0x00200000);
|
||||
|
@ -93,7 +81,7 @@ EXPORT void InitWithCd(BizSettings* bizSettings, u8* boot, u8* memtrack)
|
|||
InitCommon(bizSettings);
|
||||
if (memtrack)
|
||||
{
|
||||
JaguarLoadFile(memtrack, 0x20000);
|
||||
JaguarLoadROM(memtrack, 0x20000);
|
||||
}
|
||||
vjs.hardwareTypeAlpine = false;
|
||||
|
||||
|
@ -153,6 +141,7 @@ extern u8 gpu_ram_8[0x1000];
|
|||
extern u8 dsp_ram_8[0x2000];
|
||||
extern u8 cdRam[0x100];
|
||||
extern u8 blitter_ram[0x100];
|
||||
extern u8 tomRam8[0x4000];
|
||||
extern u8 jerry_ram_8[0x10000];
|
||||
static u8 unmapped;
|
||||
|
||||
|
@ -166,11 +155,11 @@ static inline u8* GetSysBusPtr(u64 address)
|
|||
case 0x800000 ... 0xDFFEFF: return &jaguarMainROM[address - 0x800000];
|
||||
case 0xDFFF00 ... 0xDFFFFF: return &cdRam[address & 0xFF];
|
||||
case 0xE00000 ... 0xE3FFFF: return &jagMemSpace[address];
|
||||
case 0xF00000 ... 0xF021FF: return &TOMGetRamPointer()[address & 0x3FFF];
|
||||
case 0xF00000 ... 0xF021FF: return &tomRam8[address & 0x3FFF];
|
||||
case 0xF02200 ... 0xF0229F: return &blitter_ram[address & 0xFF];
|
||||
case 0xF022A0 ... 0xF02FFF: return &TOMGetRamPointer()[address & 0x3FFF];
|
||||
case 0xF022A0 ... 0xF02FFF: return &tomRam8[address & 0x3FFF];
|
||||
case 0xF03000 ... 0xF03FFF: return &gpu_ram_8[address & 0xFFF];
|
||||
case 0xF04000 ... 0xF0FFFF: return &TOMGetRamPointer()[address & 0x3FFF];
|
||||
case 0xF04000 ... 0xF0FFFF: return &tomRam8[address & 0x3FFF];
|
||||
case 0xF10000 ... 0xF1AFFF: return &jerry_ram_8[address & 0xFFFF];
|
||||
case 0xF1B000 ... 0xF1CFFF: return &dsp_ram_8[address - 0xF1B000];
|
||||
case 0xF1D000 ... 0xF1FFFF: return &jerry_ram_8[address & 0xFFFF];
|
||||
|
@ -228,9 +217,9 @@ EXPORT void GetMemoryAreas(MemoryArea* m)
|
|||
m[3].Size = sizeof(dsp_ram_8);
|
||||
m[3].Flags = MEMORYAREA_FLAGS_WORDSIZE2 | MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_YUGEENDIAN;
|
||||
|
||||
m[4].Data = TOMGetRamPointer();
|
||||
m[4].Data = tomRam8;
|
||||
m[4].Name = "TOM RAM";
|
||||
m[4].Size = 0x4000;
|
||||
m[4].Size = sizeof(tomRam8);
|
||||
m[4].Flags = MEMORYAREA_FLAGS_WORDSIZE2 | MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_YUGEENDIAN;
|
||||
|
||||
m[5].Data = jerry_ram_8;
|
||||
|
@ -261,56 +250,32 @@ EXPORT void GetMemoryAreas(MemoryArea* m)
|
|||
|
||||
struct MyFrameInfo : public FrameInfo
|
||||
{
|
||||
u32 player1, player2;
|
||||
bool reset;
|
||||
u32 Player1, Player2;
|
||||
bool Reset;
|
||||
};
|
||||
|
||||
bool lagged;
|
||||
|
||||
EXPORT void FrameAdvance(MyFrameInfo* f)
|
||||
{
|
||||
if (f->reset)
|
||||
if (f->Reset)
|
||||
{
|
||||
JaguarReset();
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < 21; i++)
|
||||
{
|
||||
joypad0Buttons[i] = (f->player1 >> i) & 1;
|
||||
joypad1Buttons[i] = (f->player2 >> i) & 1;
|
||||
joypad0Buttons[i] = (f->Player1 >> i) & 1;
|
||||
joypad1Buttons[i] = (f->Player2 >> i) & 1;
|
||||
}
|
||||
|
||||
lagged = true;
|
||||
JaguarExecuteNew();
|
||||
DACResetBuffer(f->SoundBuffer);
|
||||
|
||||
JaguarAdvance();
|
||||
|
||||
TOMBlit(f->VideoBuffer, f->Width, f->Height);
|
||||
|
||||
u32 samples = 48000 / (vjs.hardwareTypeNTSC ? 60 : 50);
|
||||
SoundCallback(soundBuf, samples * 4);
|
||||
s16* sb = reinterpret_cast<s16*>(soundBuf);
|
||||
for (u32 i = 0; i < samples; i++)
|
||||
{
|
||||
s16 l = *sb++;
|
||||
if (latchL != l)
|
||||
{
|
||||
blip_add_delta(blipL, i, latchL - l);
|
||||
latchL = l;
|
||||
}
|
||||
|
||||
s16 r = *sb++;
|
||||
if (latchR != r)
|
||||
{
|
||||
blip_add_delta(blipR, i, latchR - r);
|
||||
latchR = r;
|
||||
}
|
||||
}
|
||||
|
||||
blip_end_frame(blipL, samples);
|
||||
blip_end_frame(blipR, samples);
|
||||
|
||||
f->Samples = blip_samples_avail(blipL);
|
||||
blip_read_samples(blipL, f->SoundBuffer + 0, f->Samples, 1);
|
||||
blip_read_samples(blipR, f->SoundBuffer + 1, f->Samples, 1);
|
||||
|
||||
f->Samples = DACResetBuffer(NULL);
|
||||
f->Lagged = lagged;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,344 +0,0 @@
|
|||
/* blip_buf 1.1.0. http://www.slack.net/~ant/ */
|
||||
|
||||
#include "blip_buf.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Library Copyright (C) 2003-2009 Shay Green. This library is free software;
|
||||
you can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#if defined (BLARGG_TEST) && BLARGG_TEST
|
||||
#include "blargg_test.h"
|
||||
#endif
|
||||
|
||||
/* Equivalent to ULONG_MAX >= 0xFFFFFFFF00000000.
|
||||
Avoids constants that don't fit in 32 bits. */
|
||||
#if ULONG_MAX/0xFFFFFFFF > 0xFFFFFFFF
|
||||
typedef unsigned long fixed_t;
|
||||
enum { pre_shift = 32 };
|
||||
|
||||
#elif defined(ULLONG_MAX)
|
||||
typedef unsigned long long fixed_t;
|
||||
enum { pre_shift = 32 };
|
||||
|
||||
#else
|
||||
typedef unsigned fixed_t;
|
||||
enum { pre_shift = 0 };
|
||||
|
||||
#endif
|
||||
|
||||
enum { time_bits = pre_shift + 20 };
|
||||
|
||||
static fixed_t const time_unit = (fixed_t) 1 << time_bits;
|
||||
|
||||
enum { bass_shift = 9 }; /* affects high-pass filter breakpoint frequency */
|
||||
enum { end_frame_extra = 2 }; /* allows deltas slightly after frame length */
|
||||
|
||||
enum { half_width = 8 };
|
||||
enum { buf_extra = half_width*2 + end_frame_extra };
|
||||
enum { phase_bits = 5 };
|
||||
enum { phase_count = 1 << phase_bits };
|
||||
enum { delta_bits = 15 };
|
||||
enum { delta_unit = 1 << delta_bits };
|
||||
enum { frac_bits = time_bits - pre_shift };
|
||||
|
||||
/* We could eliminate avail and encode whole samples in offset, but that would
|
||||
limit the total buffered samples to blip_max_frame. That could only be
|
||||
increased by decreasing time_bits, which would reduce resample ratio accuracy.
|
||||
*/
|
||||
|
||||
/** Sample buffer that resamples to output rate and accumulates samples
|
||||
until they're read out */
|
||||
struct blip_t
|
||||
{
|
||||
fixed_t factor;
|
||||
fixed_t offset;
|
||||
int avail;
|
||||
int size;
|
||||
int integrator;
|
||||
};
|
||||
|
||||
typedef int buf_t;
|
||||
|
||||
/* probably not totally portable */
|
||||
#define SAMPLES( buf ) ((buf_t*) ((buf) + 1))
|
||||
|
||||
/* Arithmetic (sign-preserving) right shift */
|
||||
#define ARITH_SHIFT( n, shift ) \
|
||||
((n) >> (shift))
|
||||
|
||||
enum { max_sample = +32767 };
|
||||
enum { min_sample = -32768 };
|
||||
|
||||
#define CLAMP( n ) \
|
||||
{\
|
||||
if ( (short) n != n )\
|
||||
n = ARITH_SHIFT( n, 16 ) ^ max_sample;\
|
||||
}
|
||||
|
||||
static void check_assumptions( void )
|
||||
{
|
||||
int n;
|
||||
|
||||
#if INT_MAX < 0x7FFFFFFF || UINT_MAX < 0xFFFFFFFF
|
||||
#error "int must be at least 32 bits"
|
||||
#endif
|
||||
|
||||
assert( (-3 >> 1) == -2 ); /* right shift must preserve sign */
|
||||
|
||||
n = max_sample * 2;
|
||||
CLAMP( n );
|
||||
assert( n == max_sample );
|
||||
|
||||
n = min_sample * 2;
|
||||
CLAMP( n );
|
||||
assert( n == min_sample );
|
||||
|
||||
assert( blip_max_ratio <= time_unit );
|
||||
assert( blip_max_frame <= (fixed_t) -1 >> time_bits );
|
||||
}
|
||||
|
||||
blip_t* blip_new( int size )
|
||||
{
|
||||
blip_t* m;
|
||||
assert( size >= 0 );
|
||||
|
||||
m = (blip_t*) malloc( sizeof *m + (size + buf_extra) * sizeof (buf_t) );
|
||||
if ( m )
|
||||
{
|
||||
m->factor = time_unit / blip_max_ratio;
|
||||
m->size = size;
|
||||
blip_clear( m );
|
||||
check_assumptions();
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
void blip_delete( blip_t* m )
|
||||
{
|
||||
if ( m != NULL )
|
||||
{
|
||||
/* Clear fields in case user tries to use after freeing */
|
||||
memset( m, 0, sizeof *m );
|
||||
free( m );
|
||||
}
|
||||
}
|
||||
|
||||
void blip_set_rates( blip_t* m, double clock_rate, double sample_rate )
|
||||
{
|
||||
double factor = time_unit * sample_rate / clock_rate;
|
||||
m->factor = (fixed_t) factor;
|
||||
|
||||
/* Fails if clock_rate exceeds maximum, relative to sample_rate */
|
||||
assert( 0 <= factor - m->factor && factor - m->factor < 1 );
|
||||
|
||||
/* Avoid requiring math.h. Equivalent to
|
||||
m->factor = (int) ceil( factor ) */
|
||||
if ( m->factor < factor )
|
||||
m->factor++;
|
||||
|
||||
/* At this point, factor is most likely rounded up, but could still
|
||||
have been rounded down in the floating-point calculation. */
|
||||
}
|
||||
|
||||
void blip_clear( blip_t* m )
|
||||
{
|
||||
/* We could set offset to 0, factor/2, or factor-1. 0 is suitable if
|
||||
factor is rounded up. factor-1 is suitable if factor is rounded down.
|
||||
Since we don't know rounding direction, factor/2 accommodates either,
|
||||
with the slight loss of showing an error in half the time. Since for
|
||||
a 64-bit factor this is years, the halving isn't a problem. */
|
||||
|
||||
m->offset = m->factor / 2;
|
||||
m->avail = 0;
|
||||
m->integrator = 0;
|
||||
memset( SAMPLES( m ), 0, (m->size + buf_extra) * sizeof (buf_t) );
|
||||
}
|
||||
|
||||
int blip_clocks_needed( const blip_t* m, int samples )
|
||||
{
|
||||
fixed_t needed;
|
||||
|
||||
/* Fails if buffer can't hold that many more samples */
|
||||
assert( samples >= 0 && m->avail + samples <= m->size );
|
||||
|
||||
needed = (fixed_t) samples * time_unit;
|
||||
if ( needed < m->offset )
|
||||
return 0;
|
||||
|
||||
return (needed - m->offset + m->factor - 1) / m->factor;
|
||||
}
|
||||
|
||||
void blip_end_frame( blip_t* m, unsigned t )
|
||||
{
|
||||
fixed_t off = t * m->factor + m->offset;
|
||||
m->avail += off >> time_bits;
|
||||
m->offset = off & (time_unit - 1);
|
||||
|
||||
/* Fails if buffer size was exceeded */
|
||||
assert( m->avail <= m->size );
|
||||
}
|
||||
|
||||
int blip_samples_avail( const blip_t* m )
|
||||
{
|
||||
return m->avail;
|
||||
}
|
||||
|
||||
static void remove_samples( blip_t* m, int count )
|
||||
{
|
||||
buf_t* buf = SAMPLES( m );
|
||||
int remain = m->avail + buf_extra - count;
|
||||
m->avail -= count;
|
||||
|
||||
memmove( &buf [0], &buf [count], remain * sizeof buf [0] );
|
||||
memset( &buf [remain], 0, count * sizeof buf [0] );
|
||||
}
|
||||
|
||||
int blip_read_samples( blip_t* m, short out [], int count, int stereo )
|
||||
{
|
||||
assert( count >= 0 );
|
||||
|
||||
if ( count > m->avail )
|
||||
count = m->avail;
|
||||
|
||||
if ( count )
|
||||
{
|
||||
int const step = stereo ? 2 : 1;
|
||||
buf_t const* in = SAMPLES( m );
|
||||
buf_t const* end = in + count;
|
||||
int sum = m->integrator;
|
||||
do
|
||||
{
|
||||
/* Eliminate fraction */
|
||||
int s = ARITH_SHIFT( sum, delta_bits );
|
||||
|
||||
sum += *in++;
|
||||
|
||||
CLAMP( s );
|
||||
|
||||
*out = s;
|
||||
out += step;
|
||||
|
||||
/* High-pass filter */
|
||||
sum -= s << (delta_bits - bass_shift);
|
||||
}
|
||||
while ( in != end );
|
||||
m->integrator = sum;
|
||||
|
||||
remove_samples( m, count );
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Things that didn't help performance on x86:
|
||||
__attribute__((aligned(128)))
|
||||
#define short int
|
||||
restrict
|
||||
*/
|
||||
|
||||
/* Sinc_Generator( 0.9, 0.55, 4.5 ) */
|
||||
static short const bl_step [phase_count + 1] [half_width] =
|
||||
{
|
||||
{ 43, -115, 350, -488, 1136, -914, 5861,21022},
|
||||
{ 44, -118, 348, -473, 1076, -799, 5274,21001},
|
||||
{ 45, -121, 344, -454, 1011, -677, 4706,20936},
|
||||
{ 46, -122, 336, -431, 942, -549, 4156,20829},
|
||||
{ 47, -123, 327, -404, 868, -418, 3629,20679},
|
||||
{ 47, -122, 316, -375, 792, -285, 3124,20488},
|
||||
{ 47, -120, 303, -344, 714, -151, 2644,20256},
|
||||
{ 46, -117, 289, -310, 634, -17, 2188,19985},
|
||||
{ 46, -114, 273, -275, 553, 117, 1758,19675},
|
||||
{ 44, -108, 255, -237, 471, 247, 1356,19327},
|
||||
{ 43, -103, 237, -199, 390, 373, 981,18944},
|
||||
{ 42, -98, 218, -160, 310, 495, 633,18527},
|
||||
{ 40, -91, 198, -121, 231, 611, 314,18078},
|
||||
{ 38, -84, 178, -81, 153, 722, 22,17599},
|
||||
{ 36, -76, 157, -43, 80, 824, -241,17092},
|
||||
{ 34, -68, 135, -3, 8, 919, -476,16558},
|
||||
{ 32, -61, 115, 34, -60, 1006, -683,16001},
|
||||
{ 29, -52, 94, 70, -123, 1083, -862,15422},
|
||||
{ 27, -44, 73, 106, -184, 1152,-1015,14824},
|
||||
{ 25, -36, 53, 139, -239, 1211,-1142,14210},
|
||||
{ 22, -27, 34, 170, -290, 1261,-1244,13582},
|
||||
{ 20, -20, 16, 199, -335, 1301,-1322,12942},
|
||||
{ 18, -12, -3, 226, -375, 1331,-1376,12293},
|
||||
{ 15, -4, -19, 250, -410, 1351,-1408,11638},
|
||||
{ 13, 3, -35, 272, -439, 1361,-1419,10979},
|
||||
{ 11, 9, -49, 292, -464, 1362,-1410,10319},
|
||||
{ 9, 16, -63, 309, -483, 1354,-1383, 9660},
|
||||
{ 7, 22, -75, 322, -496, 1337,-1339, 9005},
|
||||
{ 6, 26, -85, 333, -504, 1312,-1280, 8355},
|
||||
{ 4, 31, -94, 341, -507, 1278,-1205, 7713},
|
||||
{ 3, 35, -102, 347, -506, 1238,-1119, 7082},
|
||||
{ 1, 40, -110, 350, -499, 1190,-1021, 6464},
|
||||
{ 0, 43, -115, 350, -488, 1136, -914, 5861}
|
||||
};
|
||||
|
||||
/* Shifting by pre_shift allows calculation using unsigned int rather than
|
||||
possibly-wider fixed_t. On 32-bit platforms, this is likely more efficient.
|
||||
And by having pre_shift 32, a 32-bit platform can easily do the shift by
|
||||
simply ignoring the low half. */
|
||||
|
||||
void blip_add_delta( blip_t* m, unsigned time, int delta )
|
||||
{
|
||||
unsigned fixed = (unsigned) ((time * m->factor + m->offset) >> pre_shift);
|
||||
buf_t* out = SAMPLES( m ) + m->avail + (fixed >> frac_bits);
|
||||
|
||||
int const phase_shift = frac_bits - phase_bits;
|
||||
int phase = fixed >> phase_shift & (phase_count - 1);
|
||||
short const* in = bl_step [phase];
|
||||
short const* rev = bl_step [phase_count - phase];
|
||||
|
||||
int interp = fixed >> (phase_shift - delta_bits) & (delta_unit - 1);
|
||||
int delta2 = (delta * interp) >> delta_bits;
|
||||
delta -= delta2;
|
||||
|
||||
/* Fails if buffer size was exceeded */
|
||||
assert( out <= &SAMPLES( m ) [m->size + end_frame_extra] );
|
||||
|
||||
out [0] += in[0]*delta + in[half_width+0]*delta2;
|
||||
out [1] += in[1]*delta + in[half_width+1]*delta2;
|
||||
out [2] += in[2]*delta + in[half_width+2]*delta2;
|
||||
out [3] += in[3]*delta + in[half_width+3]*delta2;
|
||||
out [4] += in[4]*delta + in[half_width+4]*delta2;
|
||||
out [5] += in[5]*delta + in[half_width+5]*delta2;
|
||||
out [6] += in[6]*delta + in[half_width+6]*delta2;
|
||||
out [7] += in[7]*delta + in[half_width+7]*delta2;
|
||||
|
||||
in = rev;
|
||||
out [ 8] += in[7]*delta + in[7-half_width]*delta2;
|
||||
out [ 9] += in[6]*delta + in[6-half_width]*delta2;
|
||||
out [10] += in[5]*delta + in[5-half_width]*delta2;
|
||||
out [11] += in[4]*delta + in[4-half_width]*delta2;
|
||||
out [12] += in[3]*delta + in[3-half_width]*delta2;
|
||||
out [13] += in[2]*delta + in[2-half_width]*delta2;
|
||||
out [14] += in[1]*delta + in[1-half_width]*delta2;
|
||||
out [15] += in[0]*delta + in[0-half_width]*delta2;
|
||||
}
|
||||
|
||||
void blip_add_delta_fast( blip_t* m, unsigned time, int delta )
|
||||
{
|
||||
unsigned fixed = (unsigned) ((time * m->factor + m->offset) >> pre_shift);
|
||||
buf_t* out = SAMPLES( m ) + m->avail + (fixed >> frac_bits);
|
||||
|
||||
int interp = fixed >> (frac_bits - delta_bits) & (delta_unit - 1);
|
||||
int delta2 = delta * interp;
|
||||
|
||||
/* Fails if buffer size was exceeded */
|
||||
assert( out <= &SAMPLES( m ) [m->size + end_frame_extra] );
|
||||
|
||||
out [7] += delta * delta_unit - delta2;
|
||||
out [8] += delta2;
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
/** \file
|
||||
Sample buffer that resamples from input clock rate to output sample rate */
|
||||
|
||||
/* blip_buf 1.1.0 */
|
||||
#ifndef BLIP_BUF_H
|
||||
#define BLIP_BUF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** First parameter of most functions is blip_t*, or const blip_t* if nothing
|
||||
is changed. */
|
||||
typedef struct blip_t blip_t;
|
||||
|
||||
/** Creates new buffer that can hold at most sample_count samples. Sets rates
|
||||
so that there are blip_max_ratio clocks per sample. Returns pointer to new
|
||||
buffer, or NULL if insufficient memory. */
|
||||
blip_t* blip_new( int sample_count );
|
||||
|
||||
/** Sets approximate input clock rate and output sample rate. For every
|
||||
clock_rate input clocks, approximately sample_rate samples are generated. */
|
||||
void blip_set_rates( blip_t*, double clock_rate, double sample_rate );
|
||||
|
||||
enum { /** Maximum clock_rate/sample_rate ratio. For a given sample_rate,
|
||||
clock_rate must not be greater than sample_rate*blip_max_ratio. */
|
||||
blip_max_ratio = 1 << 20 };
|
||||
|
||||
/** Clears entire buffer. Afterwards, blip_samples_avail() == 0. */
|
||||
void blip_clear( blip_t* );
|
||||
|
||||
/** Adds positive/negative delta into buffer at specified clock time. */
|
||||
void blip_add_delta( blip_t*, unsigned int clock_time, int delta );
|
||||
|
||||
/** Same as blip_add_delta(), but uses faster, lower-quality synthesis. */
|
||||
void blip_add_delta_fast( blip_t*, unsigned int clock_time, int delta );
|
||||
|
||||
/** Length of time frame, in clocks, needed to make sample_count additional
|
||||
samples available. */
|
||||
int blip_clocks_needed( const blip_t*, int sample_count );
|
||||
|
||||
enum { /** Maximum number of samples that can be generated from one time frame. */
|
||||
blip_max_frame = 4000 };
|
||||
|
||||
/** Makes input clocks before clock_duration available for reading as output
|
||||
samples. Also begins new time frame at clock_duration, so that clock time 0 in
|
||||
the new time frame specifies the same clock as clock_duration in the old time
|
||||
frame specified. Deltas can have been added slightly past clock_duration (up to
|
||||
however many clocks there are in two output samples). */
|
||||
void blip_end_frame( blip_t*, unsigned int clock_duration );
|
||||
|
||||
/** Number of buffered samples available for reading. */
|
||||
int blip_samples_avail( const blip_t* );
|
||||
|
||||
/** Reads and removes at most 'count' samples and writes them to 'out'. If
|
||||
'stereo' is true, writes output to every other element of 'out', allowing easy
|
||||
interleaving of two buffers into a stereo sample stream. Outputs 16-bit signed
|
||||
samples. Returns number of samples actually read. */
|
||||
int blip_read_samples( blip_t*, short out [], int count, int stereo );
|
||||
|
||||
/** Frees buffer. No effect if NULL is passed. */
|
||||
void blip_delete( blip_t* );
|
||||
|
||||
|
||||
/* Deprecated */
|
||||
typedef blip_t blip_buffer_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
uint8_t blitter_ram[0x100];
|
||||
|
||||
void BlitterMidsummer2(void);
|
||||
static void BlitterMidsummer2(void);
|
||||
|
||||
#define REG(A) (((uint32_t)blitter_ram[(A)] << 24) | ((uint32_t)blitter_ram[(A)+1] << 16) \
|
||||
| ((uint32_t)blitter_ram[(A)+2] << 8) | (uint32_t)blitter_ram[(A)+3])
|
||||
|
@ -286,7 +286,7 @@ static int32_t a1_clip_x, a1_clip_y;
|
|||
//
|
||||
// Generic blit handler
|
||||
//
|
||||
void blitter_generic(uint32_t cmd)
|
||||
static void blitter_generic(uint32_t cmd)
|
||||
{
|
||||
uint32_t srcdata, srczdata, dstdata, dstzdata, writedata, inhibit;
|
||||
uint32_t bppSrc = (DSTA2 ? 1 << ((REG(A1_FLAGS) >> 3) & 0x07) : 1 << ((REG(A2_FLAGS) >> 3) & 0x07));
|
||||
|
@ -654,7 +654,7 @@ void blitter_generic(uint32_t cmd)
|
|||
WREG(A2_PIXEL, (a2_y & 0xFFFF0000) | ((a2_x >> 16) & 0xFFFF));
|
||||
}
|
||||
|
||||
void blitter_blit(uint32_t cmd)
|
||||
static void blitter_blit(uint32_t cmd)
|
||||
{
|
||||
uint32_t pitchValue[4] = { 0, 1, 3, 2 };
|
||||
colour_index = 0;
|
||||
|
@ -831,10 +831,6 @@ void BlitterReset(void)
|
|||
memset(blitter_ram, 0x00, 0xA0);
|
||||
}
|
||||
|
||||
void BlitterDone(void)
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t BlitterReadByte(uint32_t offset, uint32_t who)
|
||||
{
|
||||
offset &= 0xFF;
|
||||
|
@ -958,34 +954,33 @@ void BlitterWriteLong(uint32_t offset, uint32_t data, uint32_t who)
|
|||
BlitterWriteWord(offset + 2, data & 0xFFFF, who);
|
||||
}
|
||||
|
||||
void ADDRGEN(uint32_t &, uint32_t &, bool, bool,
|
||||
static void ADDRGEN(uint32_t &, uint32_t &, bool, bool,
|
||||
uint16_t, uint16_t, uint32_t, uint8_t, uint8_t, uint8_t, uint8_t,
|
||||
uint16_t, uint16_t, uint32_t, uint8_t, uint8_t, uint8_t, uint8_t);
|
||||
void ADDARRAY(uint16_t * addq, uint8_t daddasel, uint8_t daddbsel, uint8_t daddmode,
|
||||
static void ADDARRAY(uint16_t * addq, uint8_t daddasel, uint8_t daddbsel, uint8_t daddmode,
|
||||
uint64_t dstd, uint32_t iinc, uint8_t initcin[], uint64_t initinc, uint16_t initpix,
|
||||
uint32_t istep, uint64_t patd, uint64_t srcd, uint64_t srcz1, uint64_t srcz2,
|
||||
uint32_t zinc, uint32_t zstep);
|
||||
void ADD16SAT(uint16_t &r, uint8_t &co, uint16_t a, uint16_t b, uint8_t cin, bool sat, bool eightbit, bool hicinh);
|
||||
void ADDAMUX(int16_t &adda_x, int16_t &adda_y, uint8_t addasel, int16_t a1_step_x, int16_t a1_step_y,
|
||||
static void ADD16SAT(uint16_t &r, uint8_t &co, uint16_t a, uint16_t b, uint8_t cin, bool sat, bool eightbit, bool hicinh);
|
||||
static void ADDAMUX(int16_t &adda_x, int16_t &adda_y, uint8_t addasel, int16_t a1_step_x, int16_t a1_step_y,
|
||||
int16_t a1_stepf_x, int16_t a1_stepf_y, int16_t a2_step_x, int16_t a2_step_y,
|
||||
int16_t a1_inc_x, int16_t a1_inc_y, int16_t a1_incf_x, int16_t a1_incf_y, uint8_t adda_xconst,
|
||||
bool adda_yconst, bool addareg, bool suba_x, bool suba_y);
|
||||
void ADDBMUX(int16_t &addb_x, int16_t &addb_y, uint8_t addbsel, int16_t a1_x, int16_t a1_y,
|
||||
static void ADDBMUX(int16_t &addb_x, int16_t &addb_y, uint8_t addbsel, int16_t a1_x, int16_t a1_y,
|
||||
int16_t a2_x, int16_t a2_y, int16_t a1_frac_x, int16_t a1_frac_y);
|
||||
void DATAMUX(int16_t &data_x, int16_t &data_y, uint32_t gpu_din, int16_t addq_x, int16_t addq_y, bool addqsel);
|
||||
void ADDRADD(int16_t &addq_x, int16_t &addq_y, bool a1fracldi,
|
||||
static void ADDRADD(int16_t &addq_x, int16_t &addq_y, bool a1fracldi,
|
||||
uint16_t adda_x, uint16_t adda_y, uint16_t addb_x, uint16_t addb_y, uint8_t modx, bool suba_x, bool suba_y);
|
||||
void DATA(uint64_t &wdata, uint8_t &dcomp, uint8_t &zcomp, bool &nowrite,
|
||||
static void DATA(uint64_t &wdata, uint8_t &dcomp, uint8_t &zcomp, bool &nowrite,
|
||||
bool big_pix, bool cmpdst, uint8_t daddasel, uint8_t daddbsel, uint8_t daddmode, bool daddq_sel, uint8_t data_sel,
|
||||
uint8_t dbinh, uint8_t dend, uint8_t dstart, uint64_t dstd, uint32_t iinc, uint8_t lfu_func, uint64_t &patd, bool patdadd,
|
||||
bool phrase_mode, uint64_t srcd, bool srcdread, bool srczread, bool srcz2add, uint8_t zmode,
|
||||
bool bcompen, bool bkgwren, bool dcompen, uint8_t icount, uint8_t pixsize,
|
||||
uint64_t &srcz, uint64_t dstz, uint32_t zinc);
|
||||
void COMP_CTRL(uint8_t &dbinh, bool &nowrite,
|
||||
static void COMP_CTRL(uint8_t &dbinh, bool &nowrite,
|
||||
bool bcompen, bool big_pix, bool bkgwren, uint8_t dcomp, bool dcompen, uint8_t icount,
|
||||
uint8_t pixsize, bool phrase_mode, uint8_t srcd, uint8_t zcomp);
|
||||
|
||||
void BlitterMidsummer2(void)
|
||||
static void BlitterMidsummer2(void)
|
||||
{
|
||||
uint32_t cmd = GET32(blitter_ram, COMMAND);
|
||||
|
||||
|
@ -1742,7 +1737,7 @@ void BlitterMidsummer2(void)
|
|||
SET16(blitter_ram, A2_PIXEL + 0, a2_y);
|
||||
}
|
||||
|
||||
void ADDRGEN(uint32_t &address, uint32_t &pixa, bool gena2, bool zaddr,
|
||||
static void ADDRGEN(uint32_t &address, uint32_t &pixa, bool gena2, bool zaddr,
|
||||
uint16_t a1_x, uint16_t a1_y, uint32_t a1_base, uint8_t a1_pitch, uint8_t a1_pixsize, uint8_t a1_width, uint8_t a1_zoffset,
|
||||
uint16_t a2_x, uint16_t a2_y, uint32_t a2_base, uint8_t a2_pitch, uint8_t a2_pixsize, uint8_t a2_width, uint8_t a2_zoffset)
|
||||
{
|
||||
|
@ -1774,7 +1769,7 @@ void ADDRGEN(uint32_t &address, uint32_t &pixa, bool gena2, bool zaddr,
|
|||
pixa &= 0x07;
|
||||
}
|
||||
|
||||
void ADDARRAY(uint16_t * addq, uint8_t daddasel, uint8_t daddbsel, uint8_t daddmode,
|
||||
static void ADDARRAY(uint16_t * addq, uint8_t daddasel, uint8_t daddbsel, uint8_t daddmode,
|
||||
uint64_t dstd, uint32_t iinc, uint8_t initcin[], uint64_t initinc, uint16_t initpix,
|
||||
uint32_t istep, uint64_t patd, uint64_t srcd, uint64_t srcz1, uint64_t srcz2,
|
||||
uint32_t zinc, uint32_t zstep)
|
||||
|
@ -1848,7 +1843,7 @@ void ADDARRAY(uint16_t * addq, uint8_t daddasel, uint8_t daddbsel, uint8_t daddm
|
|||
ADD16SAT(addq[i], co[i], adda[i], addb[i], cin[i], sat, eightbit, hicinh);
|
||||
}
|
||||
|
||||
void ADD16SAT(uint16_t &r, uint8_t &co, uint16_t a, uint16_t b, uint8_t cin, bool sat, bool eightbit, bool hicinh)
|
||||
static void ADD16SAT(uint16_t &r, uint8_t &co, uint16_t a, uint16_t b, uint8_t cin, bool sat, bool eightbit, bool hicinh)
|
||||
{
|
||||
uint8_t carry[4];
|
||||
uint32_t qt = (a & 0xFF) + (b & 0xFF) + cin;
|
||||
|
@ -1899,7 +1894,7 @@ suba_x, suba_y complement the X and Y values
|
|||
|
||||
*/
|
||||
|
||||
void ADDAMUX(int16_t &adda_x, int16_t &adda_y, uint8_t addasel, int16_t a1_step_x, int16_t a1_step_y,
|
||||
static void ADDAMUX(int16_t &adda_x, int16_t &adda_y, uint8_t addasel, int16_t a1_step_x, int16_t a1_step_y,
|
||||
int16_t a1_stepf_x, int16_t a1_stepf_y, int16_t a2_step_x, int16_t a2_step_y,
|
||||
int16_t a1_inc_x, int16_t a1_inc_y, int16_t a1_incf_x, int16_t a1_incf_y, uint8_t adda_xconst,
|
||||
bool adda_yconst, bool addareg, bool suba_x, bool suba_y)
|
||||
|
@ -1928,7 +1923,7 @@ pointers, or the A1 fractional part. It can also be zero, so that the step
|
|||
registers load directly into the pointers.
|
||||
*/
|
||||
|
||||
void ADDBMUX(int16_t &addb_x, int16_t &addb_y, uint8_t addbsel, int16_t a1_x, int16_t a1_y,
|
||||
static void ADDBMUX(int16_t &addb_x, int16_t &addb_y, uint8_t addbsel, int16_t a1_x, int16_t a1_y,
|
||||
int16_t a2_x, int16_t a2_y, int16_t a1_frac_x, int16_t a1_frac_y)
|
||||
{
|
||||
int16_t xterm[4], yterm[4];
|
||||
|
@ -1938,17 +1933,6 @@ void ADDBMUX(int16_t &addb_x, int16_t &addb_y, uint8_t addbsel, int16_t a1_x, in
|
|||
addb_y = yterm[addbsel & 0x03];
|
||||
}
|
||||
|
||||
/** DATAMUX - Address local data bus selection ******************
|
||||
|
||||
Select between the adder output and the input data bus
|
||||
*/
|
||||
|
||||
void DATAMUX(int16_t &data_x, int16_t &data_y, uint32_t gpu_din, int16_t addq_x, int16_t addq_y, bool addqsel)
|
||||
{
|
||||
data_x = (addqsel ? addq_x : (int16_t)(gpu_din & 0xFFFF));
|
||||
data_y = (addqsel ? addq_y : (int16_t)(gpu_din >> 16));
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
addradd
|
||||
29/11/90
|
||||
|
@ -1969,7 +1953,7 @@ modx[0..2] take values
|
|||
|
||||
******************************************************************/
|
||||
|
||||
void ADDRADD(int16_t &addq_x, int16_t &addq_y, bool a1fracldi,
|
||||
static void ADDRADD(int16_t &addq_x, int16_t &addq_y, bool a1fracldi,
|
||||
uint16_t adda_x, uint16_t adda_y, uint16_t addb_x, uint16_t addb_y, uint8_t modx, bool suba_x, bool suba_y)
|
||||
{
|
||||
static uint16_t co_x = 0, co_y = 0;
|
||||
|
@ -1985,7 +1969,7 @@ void ADDRADD(int16_t &addq_x, int16_t &addq_y, bool a1fracldi,
|
|||
addq_y = addqt_y & 0xFFFF;
|
||||
}
|
||||
|
||||
void DATA(uint64_t &wdata, uint8_t &dcomp, uint8_t &zcomp, bool &nowrite,
|
||||
static void DATA(uint64_t &wdata, uint8_t &dcomp, uint8_t &zcomp, bool &nowrite,
|
||||
bool big_pix, bool cmpdst, uint8_t daddasel, uint8_t daddbsel, uint8_t daddmode, bool daddq_sel, uint8_t data_sel,
|
||||
uint8_t dbinh, uint8_t dend, uint8_t dstart, uint64_t dstd, uint32_t iinc, uint8_t lfu_func, uint64_t &patd, bool patdadd,
|
||||
bool phrase_mode, uint64_t srcd, bool srcdread, bool srczread, bool srcz2add, uint8_t zmode,
|
||||
|
@ -2184,7 +2168,7 @@ performed. The is taken care of within the zed comparator by
|
|||
pipe-lining the comparator inputs where appropriate.
|
||||
*/
|
||||
|
||||
void COMP_CTRL(uint8_t &dbinh, bool &nowrite,
|
||||
static void COMP_CTRL(uint8_t &dbinh, bool &nowrite,
|
||||
bool bcompen, bool big_pix, bool bkgwren, uint8_t dcomp, bool dcompen, uint8_t icount,
|
||||
uint8_t pixsize, bool phrase_mode, uint8_t srcd, uint8_t zcomp)
|
||||
{
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
void BlitterInit(void);
|
||||
void BlitterReset(void);
|
||||
void BlitterDone(void);
|
||||
|
||||
uint8_t BlitterReadByte(uint32_t, uint32_t who = UNKNOWN);
|
||||
uint16_t BlitterReadWord(uint32_t, uint32_t who = UNKNOWN);
|
||||
|
@ -18,7 +17,4 @@ void BlitterWriteByte(uint32_t, uint8_t, uint32_t who = UNKNOWN);
|
|||
void BlitterWriteWord(uint32_t, uint16_t, uint32_t who = UNKNOWN);
|
||||
void BlitterWriteLong(uint32_t, uint32_t, uint32_t who = UNKNOWN);
|
||||
|
||||
uint32_t blitter_reg_read(uint32_t offset);
|
||||
void blitter_reg_write(uint32_t offset, uint32_t data);
|
||||
|
||||
#endif // __BLITTER_H__
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "dac.h"
|
||||
#include "dsp.h"
|
||||
#include "event.h"
|
||||
#include "settings.h"
|
||||
#include "m68000/m68kinterface.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -20,11 +21,17 @@
|
|||
|
||||
#define TOC_BASE_ADDR 0x2C00
|
||||
|
||||
// arbitrary number, but something is needed here
|
||||
// too short, and games FMVs misbehave (Space Ace is entirely FMVs!!!)
|
||||
// too long, and games will time out on CD reads
|
||||
// NTSC and PAL probably shouldn't have different timings here...
|
||||
#define CD_DELAY_USECS (vjs.hardwareTypeNTSC ? 270 : 280)
|
||||
|
||||
static bool cd_setup;
|
||||
static bool cd_initm;
|
||||
static bool cd_muted;
|
||||
static bool cd_paused;
|
||||
bool cd_jerry;
|
||||
static bool cd_jerry;
|
||||
static uint8_t cd_mode;
|
||||
static uint8_t cd_osamp;
|
||||
|
||||
|
@ -232,10 +239,6 @@ void CDHLEReset(void)
|
|||
}
|
||||
}
|
||||
|
||||
void CDHLEDone(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void RefillCDBuf()
|
||||
{
|
||||
memmove(&cd_buf2352[0], &cd_buf2352[cd_buf_pos], cd_buf_rm);
|
||||
|
@ -267,10 +270,10 @@ static void CDHLECallback(void)
|
|||
{
|
||||
if (cd_is_reading)
|
||||
{
|
||||
if (!GPURunning())
|
||||
if (!GPUIsRunning())
|
||||
fprintf(stderr, "CDHLECallback called with GPU inactive\n");
|
||||
|
||||
if (GPURunning() && !cd_paused)
|
||||
if (GPUIsRunning() && !cd_paused)
|
||||
{
|
||||
if (cd_buf_rm < 64)
|
||||
{
|
||||
|
@ -299,7 +302,7 @@ static void CDHLECallback(void)
|
|||
//GPUSetIRQLine(GPUIRQ_DSP, ASSERT_LINE);
|
||||
}
|
||||
|
||||
SetCallbackTime(CDHLECallback, 285 >> (cd_mode & 1));
|
||||
SetCallbackTime(CDHLECallback, CD_DELAY_USECS >> (cd_mode & 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,7 +340,7 @@ static void ResetCallback(void)
|
|||
RemoveCallback(CDHLECallback);
|
||||
if (!cd_jerry)
|
||||
{
|
||||
SetCallbackTime(CDHLECallback, 285 >> (cd_mode & 1));
|
||||
SetCallbackTime(CDHLECallback, CD_DELAY_USECS >> (cd_mode & 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
void CDHLEInit(void);
|
||||
void CDHLEReset(void);
|
||||
void CDHLEDone(void);
|
||||
|
||||
void CDHLEHook(uint32_t which);
|
||||
bool CDHLEJerryCallback(void);
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
//
|
||||
// OS agnostic CDROM interface functions
|
||||
//
|
||||
// by James Hammons
|
||||
// (C) 2010 Underground Software
|
||||
//
|
||||
// JLH = James Hammons <jlhamm@acm.org>
|
||||
//
|
||||
// Who When What
|
||||
// --- ---------- ------------------------------------------------------------
|
||||
// JLH 01/16/2010 Created this log ;-)
|
||||
//
|
||||
|
||||
#include "cdintf.h"
|
||||
|
||||
bool CDIntfInit(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void CDIntfDone(void)
|
||||
{
|
||||
}
|
||||
|
||||
bool CDIntfReadBlock(uint32_t sector, uint8_t * buffer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t CDIntfGetSessionInfo(uint32_t session, uint32_t offset)
|
||||
{
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
uint8_t CDIntfGetTrackInfo(uint32_t track, uint32_t offset)
|
||||
{
|
||||
return 0xFF;
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
//
|
||||
// CDINTF.H: OS agnostic CDROM access funcions
|
||||
//
|
||||
// by James Hammons
|
||||
//
|
||||
|
||||
#ifndef __CDINTF_H__
|
||||
#define __CDINTF_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
bool CDIntfInit(void);
|
||||
void CDIntfDone(void);
|
||||
bool CDIntfReadBlock(uint32_t, uint8_t *);
|
||||
uint8_t CDIntfGetSessionInfo(uint32_t, uint32_t);
|
||||
uint8_t CDIntfGetTrackInfo(uint32_t, uint32_t);
|
||||
|
||||
#endif // __CDINTF_H__
|
|
@ -16,7 +16,6 @@
|
|||
#include "cdrom.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "cdintf.h"
|
||||
#include "dac.h"
|
||||
|
||||
// Private function prototypes
|
||||
|
@ -37,34 +36,16 @@ static uint16_t CDROMBusRead(void);
|
|||
#define UNKNOWN BUTCH + 0x2C // Seems to be some sort of I2S interface
|
||||
|
||||
uint8_t cdRam[0x100];
|
||||
static uint16_t cdCmd = 0, cdPtr = 0;
|
||||
static bool haveCDGoodness;
|
||||
static uint32_t min, sec, frm, block;
|
||||
static uint8_t cdBuf[2352 + 96];
|
||||
static uint32_t cdBufPtr = 2352;
|
||||
|
||||
void CDROMInit(void)
|
||||
{
|
||||
haveCDGoodness = CDIntfInit();
|
||||
}
|
||||
|
||||
void CDROMReset(void)
|
||||
{
|
||||
memset(cdRam, 0x00, 0x100);
|
||||
cdCmd = 0;
|
||||
memset(cdRam, 0x00, sizeof(cdRam));
|
||||
}
|
||||
|
||||
void CDROMDone(void)
|
||||
{
|
||||
CDIntfDone();
|
||||
}
|
||||
|
||||
//
|
||||
// This approach is probably wrong, but let's do it for now.
|
||||
// What's needed is a complete overhaul of the interrupt system so that
|
||||
// interrupts are handled as they're generated--instead of the current
|
||||
// scheme where they're handled on scanline boundaries.
|
||||
//
|
||||
void BUTCHExec(uint32_t cycles)
|
||||
{
|
||||
}
|
||||
|
@ -78,7 +59,7 @@ uint8_t CDROMReadByte(uint32_t offset, uint32_t who)
|
|||
return cdRam[offset & 0xFF];
|
||||
}
|
||||
|
||||
static uint8_t trackNum = 1, minTrack, maxTrack;
|
||||
static uint8_t minTrack, maxTrack;
|
||||
|
||||
uint16_t CDROMReadWord(uint32_t offset, uint32_t who)
|
||||
{
|
||||
|
@ -86,103 +67,10 @@ uint16_t CDROMReadWord(uint32_t offset, uint32_t who)
|
|||
|
||||
uint16_t data = 0x0000;
|
||||
|
||||
if (offset == BUTCH)
|
||||
data = 0x0000;
|
||||
else if (offset == BUTCH + 2)
|
||||
data = (haveCDGoodness ? cdRam[BUTCH + 3] << 8 : 0x0000);
|
||||
else if (offset == DS_DATA && haveCDGoodness)
|
||||
{
|
||||
if ((cdCmd & 0xFF00) == 0x0100)
|
||||
{
|
||||
cdPtr++;
|
||||
switch (cdPtr)
|
||||
{
|
||||
case 1:
|
||||
data = 0x0000;
|
||||
break;
|
||||
case 2:
|
||||
data = 0x0100;
|
||||
break;
|
||||
case 3:
|
||||
data = 0x0200;
|
||||
break;
|
||||
case 4:
|
||||
data = 0x0300;
|
||||
break;
|
||||
case 5:
|
||||
data = 0x0400;
|
||||
}
|
||||
}
|
||||
else if ((cdCmd & 0xFF00) == 0x0200)
|
||||
{
|
||||
data = 0x0400;
|
||||
}
|
||||
else if ((cdCmd & 0xFF00) == 0x0300)
|
||||
{
|
||||
data = CDIntfGetSessionInfo(cdCmd & 0xFF, cdPtr);
|
||||
if (data == 0xFF)
|
||||
{
|
||||
data = 0x0400;
|
||||
}
|
||||
else
|
||||
{
|
||||
data |= (0x20 | cdPtr++) << 8;
|
||||
}
|
||||
}
|
||||
else if ((cdCmd & 0xFF00) == 0x1000 || (cdCmd & 0xFF00) == 0x1100 || (cdCmd & 0xFF00) == 0x1200)
|
||||
data = 0x0100;
|
||||
else if ((cdCmd & 0xFF00) == 0x1400)
|
||||
{
|
||||
if (trackNum > maxTrack)
|
||||
{
|
||||
data = 0x400;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cdPtr < 0x62)
|
||||
data = (cdPtr << 8) | trackNum;
|
||||
else if (cdPtr < 0x65)
|
||||
data = (cdPtr << 8) | CDIntfGetTrackInfo(trackNum, (cdPtr - 2) & 0x0F);
|
||||
|
||||
cdPtr++;
|
||||
if (cdPtr == 0x65)
|
||||
cdPtr = 0x60, trackNum++;
|
||||
}
|
||||
}
|
||||
else if ((cdCmd & 0xFF00) == 0x1500)
|
||||
{
|
||||
data = cdCmd | 0x0200;
|
||||
}
|
||||
else if ((cdCmd & 0xFF00) == 0x1800)
|
||||
{
|
||||
data = cdCmd;
|
||||
}
|
||||
else if ((cdCmd & 0xFF00) == 0x5400)
|
||||
{
|
||||
data = cdCmd | 0x00;
|
||||
}
|
||||
else if ((cdCmd & 0xFF00) == 0x7000)
|
||||
{
|
||||
data = cdCmd;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = 0x0400;
|
||||
}
|
||||
}
|
||||
else if (offset == DS_DATA && !haveCDGoodness)
|
||||
data = 0x0400;
|
||||
else if (offset >= FIFO_DATA && offset <= FIFO_DATA + 3)
|
||||
{
|
||||
}
|
||||
else if (offset >= FIFO_DATA + 4 && offset <= FIFO_DATA + 7)
|
||||
{
|
||||
}
|
||||
else
|
||||
data = GET16(cdRam, offset);
|
||||
|
||||
if (offset == UNKNOWN + 2)
|
||||
data = CDROMBusRead();
|
||||
else if (offset < FIFO_DATA || offset > FIFO_DATA + 7)
|
||||
data = GET16(cdRam, offset);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -198,52 +86,6 @@ void CDROMWriteWord(uint32_t offset, uint16_t data, uint32_t who)
|
|||
offset &= 0xFF;
|
||||
SET16(cdRam, offset, data);
|
||||
|
||||
if (offset == DS_DATA)
|
||||
{
|
||||
cdCmd = data;
|
||||
if ((data & 0xFF00) == 0x0200)
|
||||
{
|
||||
cdPtr = 0;
|
||||
}
|
||||
else if ((data & 0xFF00) == 0x0300)
|
||||
{
|
||||
cdPtr = 0;
|
||||
}
|
||||
else if ((data & 0xFF00) == 0x1000)
|
||||
{
|
||||
min = data & 0x00FF;
|
||||
}
|
||||
else if ((data & 0xFF00) == 0x1100)
|
||||
{
|
||||
sec = data & 0x00FF;
|
||||
}
|
||||
else if ((data & 0xFF00) == 0x1200)
|
||||
{
|
||||
frm = data & 0x00FF;
|
||||
block = (((min * 60) + sec) * 75) + frm;
|
||||
cdBufPtr = 2352;
|
||||
}
|
||||
else if ((data & 0xFF00) == 0x1400)
|
||||
{
|
||||
cdPtr = 0x60,
|
||||
minTrack = CDIntfGetSessionInfo(data & 0xFF, 0),
|
||||
maxTrack = CDIntfGetSessionInfo(data & 0xFF, 1);
|
||||
trackNum = minTrack;
|
||||
}
|
||||
else if ((data & 0xFF00) == 0x1500)
|
||||
{
|
||||
}
|
||||
else if ((data & 0xFF00) == 0x1800)
|
||||
{
|
||||
}
|
||||
else if ((data & 0xFF00) == 0x5400)
|
||||
{
|
||||
}
|
||||
else if ((data & 0xFF00) == 0x7000)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (offset == UNKNOWN + 2)
|
||||
CDROMBusWrite(data);
|
||||
}
|
||||
|
@ -257,9 +99,8 @@ static ButchState currentState = ST_INIT;
|
|||
static uint16_t counter = 0;
|
||||
static bool cmdTx = false;
|
||||
static uint16_t busCmd;
|
||||
static uint16_t rxData, txData;
|
||||
static uint16_t rxData;
|
||||
static uint16_t rxDataBit;
|
||||
static bool firstTime = false;
|
||||
|
||||
static void CDROMBusWrite(uint16_t data)
|
||||
{
|
||||
|
@ -304,14 +145,10 @@ static void CDROMBusWrite(uint16_t data)
|
|||
rxData = 0x0001;
|
||||
|
||||
counter = 0;
|
||||
firstTime = true;
|
||||
txData = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
txData = (txData << 1) | ((data & 0x04) >> 2);
|
||||
|
||||
rxDataBit = (rxData & 0x8000) >> 12;
|
||||
rxData <<= 1;
|
||||
counter++;
|
||||
|
@ -330,60 +167,3 @@ static uint16_t CDROMBusRead(void)
|
|||
{
|
||||
return rxDataBit;
|
||||
}
|
||||
|
||||
static uint8_t cdBuf2[2532 + 96], cdBuf3[2532 + 96];
|
||||
|
||||
uint16_t GetWordFromButchSSI(uint32_t offset, uint32_t who)
|
||||
{
|
||||
bool go = ((offset & 0x0F) == 0x0A || (offset & 0x0F) == 0x0E ? true : false);
|
||||
|
||||
if (!go)
|
||||
return 0x000;
|
||||
|
||||
cdBufPtr += 2;
|
||||
|
||||
if (cdBufPtr >= 2352)
|
||||
{
|
||||
CDIntfReadBlock(block - 150, cdBuf2);
|
||||
CDIntfReadBlock(block - 149, cdBuf3);
|
||||
for(int i=0; i<2352-4; i+=4)
|
||||
{
|
||||
cdBuf[i+0] = cdBuf2[i+4];
|
||||
cdBuf[i+1] = cdBuf2[i+5];
|
||||
cdBuf[i+2] = cdBuf2[i+2];
|
||||
cdBuf[i+3] = cdBuf2[i+3];
|
||||
}
|
||||
cdBuf[2348] = cdBuf3[0];
|
||||
cdBuf[2349] = cdBuf3[1];
|
||||
cdBuf[2350] = cdBuf2[2350];
|
||||
cdBuf[2351] = cdBuf2[2351];
|
||||
|
||||
block++, cdBufPtr = 0;
|
||||
}
|
||||
|
||||
return (cdBuf[cdBufPtr + 1] << 8) | cdBuf[cdBufPtr + 0];
|
||||
}
|
||||
|
||||
bool ButchIsReadyToSend(void)
|
||||
{
|
||||
return (cdRam[I2CNTRL + 3] & 0x02 ? true : false);
|
||||
}
|
||||
|
||||
void SetSSIWordsXmittedFromButch(void)
|
||||
{
|
||||
cdBufPtr += 4;
|
||||
|
||||
if (cdBufPtr >= 2352)
|
||||
{
|
||||
CDIntfReadBlock(block, cdBuf2);
|
||||
CDIntfReadBlock(block + 1, cdBuf3);
|
||||
memcpy(cdBuf, cdBuf2 + 2, 2350);
|
||||
cdBuf[2350] = cdBuf3[0];
|
||||
cdBuf[2351] = cdBuf3[1];
|
||||
|
||||
block++, cdBufPtr = 0;
|
||||
}
|
||||
|
||||
lrxd = (cdBuf[cdBufPtr + 3] << 8) | cdBuf[cdBufPtr + 2],
|
||||
rrxd = (cdBuf[cdBufPtr + 1] << 8) | cdBuf[cdBufPtr + 0];
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
void CDROMInit(void);
|
||||
void CDROMReset(void);
|
||||
void CDROMDone(void);
|
||||
|
||||
void BUTCHExec(uint32_t cycles);
|
||||
|
||||
|
@ -18,8 +17,4 @@ uint16_t CDROMReadWord(uint32_t offset, uint32_t who = UNKNOWN);
|
|||
void CDROMWriteByte(uint32_t offset, uint8_t data, uint32_t who = UNKNOWN);
|
||||
void CDROMWriteWord(uint32_t offset, uint16_t data, uint32_t who = UNKNOWN);
|
||||
|
||||
bool ButchIsReadyToSend(void);
|
||||
uint16_t GetWordFromButchSSI(uint32_t offset, uint32_t who = UNKNOWN);
|
||||
void SetSSIWordsXmittedFromButch(void);
|
||||
|
||||
#endif // __CDROM_H__
|
||||
|
|
|
@ -15,47 +15,47 @@
|
|||
|
||||
#include "crc32.h"
|
||||
|
||||
static unsigned long crctable[256] =
|
||||
static const uint32_t crctable[256] =
|
||||
{
|
||||
0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
|
||||
0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
|
||||
0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
|
||||
0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
|
||||
0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L, 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
|
||||
0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L, 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
|
||||
0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L, 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
|
||||
0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L, 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
|
||||
0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL, 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
|
||||
0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L, 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
|
||||
0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL, 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
|
||||
0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL, 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
|
||||
0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L, 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
|
||||
0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
|
||||
0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L, 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
|
||||
0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L, 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
|
||||
0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL, 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
|
||||
0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L, 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
|
||||
0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
|
||||
0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL, 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
|
||||
0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L, 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
|
||||
0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L, 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
|
||||
0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L, 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
|
||||
0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
|
||||
0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL, 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
|
||||
0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L, 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
|
||||
0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL, 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
|
||||
0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL, 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
|
||||
0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
|
||||
0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L, 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
|
||||
0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
|
||||
0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L, 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
||||
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
|
||||
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
|
||||
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
|
||||
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
|
||||
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
|
||||
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
||||
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
|
||||
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
|
||||
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
|
||||
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
|
||||
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
|
||||
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
|
||||
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
||||
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
|
||||
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
|
||||
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
|
||||
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
|
||||
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
|
||||
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
|
||||
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
||||
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
|
||||
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
|
||||
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
|
||||
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
|
||||
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
|
||||
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
|
||||
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
||||
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
|
||||
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
||||
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
|
||||
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
|
||||
};
|
||||
|
||||
int crc32_calcCheckSum(unsigned char * data, unsigned int length)
|
||||
uint32_t crc32_calcCheckSum(uint8_t * data, uint32_t length)
|
||||
{
|
||||
unsigned long crc = 0xFFFFFFFF;
|
||||
uint32_t crc = 0xFFFFFFFF;
|
||||
|
||||
for(unsigned int i=0; i<length; i++)
|
||||
for(uint32_t i=0; i<length; i++)
|
||||
crc = crctable[(crc ^ *data++) & 0xFF] ^ (crc >> 8);
|
||||
|
||||
return crc ^ 0xFFFFFFFF;
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#ifndef __CRC32_H__
|
||||
#define __CRC32_H__
|
||||
|
||||
int crc32_calcCheckSum(unsigned char * data, unsigned int length);
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t crc32_calcCheckSum(uint8_t * data, uint32_t length);
|
||||
|
||||
#endif // __CRC32_H__
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//
|
||||
// Red Color Values for CrY<->RGB Color Conversion
|
||||
//
|
||||
uint8_t redcv[16][16] = {
|
||||
static const uint8_t redcv[16][16] = {
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
// ----------------------------------------------------------------------
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // 0
|
||||
|
@ -25,7 +25,7 @@ uint8_t redcv[16][16] = {
|
|||
//
|
||||
// Green Color Values for CrY<->RGB Color Conversion
|
||||
//
|
||||
uint8_t greencv[16][16] = {
|
||||
static const uint8_t greencv[16][16] = {
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
// ----------------------------------------------------------------------
|
||||
{ 0, 17, 34, 51,68, 85, 102,119,136,153,170,187,204,221,238,255}, // 0
|
||||
|
@ -49,7 +49,7 @@ uint8_t greencv[16][16] = {
|
|||
//
|
||||
// Blue Color Values for CrY<->RGB Color Conversion
|
||||
//
|
||||
uint8_t bluecv[16][16] = {
|
||||
static const uint8_t bluecv[16][16] = {
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
// ----------------------------------------------------------------------
|
||||
{ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255}, // 0
|
||||
|
|
|
@ -14,32 +14,6 @@
|
|||
// JLH 04/30/2012 Changed SDL audio handler to run JERRY
|
||||
//
|
||||
|
||||
// Need to set up defaults that the BIOS sets for the SSI here in DACInit()... !!! FIX !!!
|
||||
// or something like that... Seems like it already does, but it doesn't seem to
|
||||
// work correctly...! Perhaps just need to set up SSI stuff so BUTCH doesn't get
|
||||
// confused...
|
||||
|
||||
// After testing on a real Jaguar, it seems clear that the I2S interrupt drives
|
||||
// the audio subsystem. So while you can drive the audio at a *slower* rate than
|
||||
// set by SCLK, you can't drive it any *faster*. Also note, that if the I2S
|
||||
// interrupt is not enabled/running on the DSP, then there is no audio. Also,
|
||||
// audio can be muted by clearing bit 8 of JOYSTICK (JOY1).
|
||||
//
|
||||
// Approach: We can run the DSP in the host system's audio IRQ, by running the
|
||||
// DSP for the alloted time (depending on the host buffer size & sample rate)
|
||||
// by simply reading the L/R_I2S (L/RTXD) registers at regular intervals. We
|
||||
// would also have to time the I2S/TIMER0/TIMER1 interrupts in the DSP as well.
|
||||
// This way, we can run the host audio IRQ at, say, 48 KHz and not have to care
|
||||
// so much about SCLK and running a separate buffer and all the attendant
|
||||
// garbage that comes with that awful approach.
|
||||
//
|
||||
// There would still be potential gotchas, as the SCLK can theoretically drive
|
||||
// the I2S at 26590906 / 2 (for SCLK == 0) = 13.3 MHz which corresponds to an
|
||||
// audio rate 416 KHz (dividing the I2S rate by 32, for 16-bit stereo). It
|
||||
// seems doubtful that anything useful could come of such a high rate, and we
|
||||
// can probably safely ignore any such ridiculously high audio rates. It won't
|
||||
// sound the same as on a real Jaguar, but who cares? :-)
|
||||
|
||||
#include "dac.h"
|
||||
|
||||
#include "cdrom.h"
|
||||
|
@ -50,8 +24,7 @@
|
|||
#include "m68000/m68kinterface.h"
|
||||
#include "settings.h"
|
||||
|
||||
#define BUFFER_SIZE 0x10000 // Make the DAC buffers 64K x 16 bits
|
||||
#define DAC_AUDIO_RATE 48000 // Set the audio rate to 48 KHz
|
||||
#define DAC_AUDIO_RATE 44100.0 // Set the audio rate to 44.1 KHz
|
||||
|
||||
// Jaguar memory locations
|
||||
|
||||
|
@ -62,15 +35,18 @@
|
|||
#define SCLK 0xF1A150
|
||||
#define SMODE 0xF1A154
|
||||
|
||||
// Private function prototypes
|
||||
static uint16_t * sampleBuffer;
|
||||
static uint32_t bufferIndex;
|
||||
static uint32_t maxSamples;
|
||||
extern bool audioEnabled;
|
||||
|
||||
void DSPSampleCallback(void);
|
||||
static void DSPSampleCallback(void);
|
||||
|
||||
void DACInit(void)
|
||||
{
|
||||
ltxd = lrxd = 0;
|
||||
|
||||
sclk = 19;
|
||||
maxSamples = 2048; // bleh
|
||||
DACReset();
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -78,81 +54,31 @@ void DACInit(void)
|
|||
//
|
||||
void DACReset(void)
|
||||
{
|
||||
ltxd = lrxd = 0;
|
||||
ltxd = rtxd = 0;
|
||||
RemoveCallback(DSPSampleCallback);
|
||||
SetCallbackTime(DSPSampleCallback, 1000000.0 / DAC_AUDIO_RATE);
|
||||
}
|
||||
|
||||
void DACDone(void)
|
||||
// Call this every frame with your buffer or NULL
|
||||
// Returns amount of samples last outputted
|
||||
uint32_t DACResetBuffer(void * buffer)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Approach: Run the DSP for however many cycles needed to correspond to whatever sample rate
|
||||
// we've set the audio to run at. So, e.g., if we run it at 48 KHz, then we would run the DSP
|
||||
// for however much time it takes to fill the buffer. So with a 2K buffer, this would correspond
|
||||
// to running the DSP for 0.042666... seconds. At 26590906 Hz, this would correspond to
|
||||
// running the DSP for 1134545 cycles. You would then sample the L/RTXD registers every
|
||||
// 1134545 / 2048 = 554 cycles to fill the buffer. You would also have to manage interrupt
|
||||
// timing as well (generating them at the proper times), but that shouldn't be too difficult...
|
||||
// If the DSP isn't running, then fill the buffer with L/RTXD and exit.
|
||||
|
||||
//
|
||||
// Callback routine to fill audio buffer
|
||||
//
|
||||
// Note: The samples are packed in the buffer in 16 bit left/16 bit right pairs.
|
||||
// Also, length is the length of the buffer in BYTES
|
||||
//
|
||||
|
||||
static uint16_t * sampleBuffer;
|
||||
static int bufferIndex = 0;
|
||||
static int numberOfSamples = 0;
|
||||
static bool bufferDone = false;
|
||||
|
||||
void SoundCallback(uint16_t * buffer, int length)
|
||||
{
|
||||
// 1st, check to see if the DSP is running. If not, fill the buffer with L/RXTD and exit.
|
||||
|
||||
if (!DSPIsRunning())
|
||||
{
|
||||
for(int i=0; i<(length/2); i+=2)
|
||||
{
|
||||
buffer[i + 0] = ltxd;
|
||||
buffer[i + 1] = rtxd;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sampleBuffer = (uint16_t*)buffer;
|
||||
uint32_t ret = bufferIndex / 2;
|
||||
bufferIndex = 0;
|
||||
sampleBuffer = buffer;
|
||||
|
||||
numberOfSamples = length / 2;
|
||||
bufferDone = false;
|
||||
|
||||
SetCallbackTime(DSPSampleCallback, 1000000.0 / (double)DAC_AUDIO_RATE, EVENT_JERRY);
|
||||
|
||||
do
|
||||
{
|
||||
double timeToNextEvent = GetTimeToNextEvent(EVENT_JERRY);
|
||||
DSPExec(USEC_TO_RISC_CYCLES(timeToNextEvent));
|
||||
HandleNextEvent(EVENT_JERRY);
|
||||
}
|
||||
while (!bufferDone);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void DSPSampleCallback(void)
|
||||
static void DSPSampleCallback(void)
|
||||
{
|
||||
sampleBuffer[bufferIndex + 0] = ltxd;
|
||||
sampleBuffer[bufferIndex + 1] = rtxd;
|
||||
bufferIndex += 2;
|
||||
|
||||
if (bufferIndex == numberOfSamples)
|
||||
if (bufferIndex != maxSamples)
|
||||
{
|
||||
bufferDone = true;
|
||||
return;
|
||||
sampleBuffer[bufferIndex + 0] = audioEnabled ? ltxd : 0;
|
||||
sampleBuffer[bufferIndex + 1] = audioEnabled ? rtxd : 0;
|
||||
bufferIndex += 2;
|
||||
}
|
||||
|
||||
SetCallbackTime(DSPSampleCallback, 1000000.0 / (double)DAC_AUDIO_RATE, EVENT_JERRY);
|
||||
SetCallbackTime(DSPSampleCallback, 1000000.0 / DAC_AUDIO_RATE);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
void DACInit(void);
|
||||
void DACReset(void);
|
||||
void DACDone(void);
|
||||
uint32_t DACResetBuffer(void * buffer);
|
||||
|
||||
// DAC memory access
|
||||
|
||||
|
|
|
@ -176,7 +176,7 @@ static uint32_t dsp_flags;
|
|||
static uint32_t dsp_matrix_control;
|
||||
static uint32_t dsp_pointer_to_matrix;
|
||||
static uint32_t dsp_data_organization;
|
||||
uint32_t dsp_control;
|
||||
static uint32_t dsp_control;
|
||||
static uint32_t dsp_div_control;
|
||||
static uint8_t dsp_flag_z, dsp_flag_n, dsp_flag_c;
|
||||
static uint32_t * dsp_reg = NULL, * dsp_alternate_reg = NULL;
|
||||
|
@ -194,7 +194,7 @@ static uint8_t branch_condition_table[32 * 8];
|
|||
static uint16_t mirror_table[65536];
|
||||
uint8_t dsp_ram_8[0x2000];
|
||||
|
||||
void dsp_build_branch_condition_table(void)
|
||||
static void dsp_build_branch_condition_table(void)
|
||||
{
|
||||
for(int i=0; i<65536; i++)
|
||||
{
|
||||
|
@ -231,6 +231,64 @@ void dsp_build_branch_condition_table(void)
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Update the DSP register file pointers depending on REGPAGE bit
|
||||
//
|
||||
static void DSPUpdateRegisterBanks(void)
|
||||
{
|
||||
int bank = (dsp_flags & REGPAGE);
|
||||
|
||||
if (dsp_flags & IMASK)
|
||||
bank = 0;
|
||||
|
||||
if (bank)
|
||||
dsp_reg = dsp_reg_bank_1, dsp_alternate_reg = dsp_reg_bank_0;
|
||||
else
|
||||
dsp_reg = dsp_reg_bank_0, dsp_alternate_reg = dsp_reg_bank_1;
|
||||
}
|
||||
|
||||
//
|
||||
// Check for and handle any asserted DSP IRQs
|
||||
//
|
||||
static void DSPHandleIRQs(void)
|
||||
{
|
||||
if (dsp_flags & IMASK)
|
||||
return;
|
||||
|
||||
uint32_t bits = ((dsp_control >> 10) & 0x20) | ((dsp_control >> 6) & 0x1F),
|
||||
mask = ((dsp_flags >> 11) & 0x20) | ((dsp_flags >> 4) & 0x1F);
|
||||
|
||||
bits &= mask;
|
||||
|
||||
if (!bits)
|
||||
return;
|
||||
|
||||
int which = 0;
|
||||
if (bits & 0x01)
|
||||
which = 0;
|
||||
if (bits & 0x02)
|
||||
which = 1;
|
||||
if (bits & 0x04)
|
||||
which = 2;
|
||||
if (bits & 0x08)
|
||||
which = 3;
|
||||
if (bits & 0x10)
|
||||
which = 4;
|
||||
if (bits & 0x20)
|
||||
which = 5;
|
||||
|
||||
dsp_flags |= IMASK;
|
||||
|
||||
DSPUpdateRegisterBanks();
|
||||
|
||||
dsp_reg[31] -= 4;
|
||||
dsp_reg[30] = dsp_pc - 2;
|
||||
|
||||
DSPWriteLong(dsp_reg[31], dsp_reg[30], DSP);
|
||||
|
||||
dsp_pc = dsp_reg[30] = DSP_WORK_RAM_BASE + (which * 0x10);
|
||||
}
|
||||
|
||||
uint8_t DSPReadByte(uint32_t offset, uint32_t who)
|
||||
{
|
||||
if (offset >= DSP_WORK_RAM_BASE && offset <= (DSP_WORK_RAM_BASE + 0x1FFF))
|
||||
|
@ -460,64 +518,6 @@ void DSPWriteLong(uint32_t offset, uint32_t data, uint32_t who)
|
|||
JaguarWriteLong(offset, data, who);
|
||||
}
|
||||
|
||||
//
|
||||
// Update the DSP register file pointers depending on REGPAGE bit
|
||||
//
|
||||
void DSPUpdateRegisterBanks(void)
|
||||
{
|
||||
int bank = (dsp_flags & REGPAGE);
|
||||
|
||||
if (dsp_flags & IMASK)
|
||||
bank = 0;
|
||||
|
||||
if (bank)
|
||||
dsp_reg = dsp_reg_bank_1, dsp_alternate_reg = dsp_reg_bank_0;
|
||||
else
|
||||
dsp_reg = dsp_reg_bank_0, dsp_alternate_reg = dsp_reg_bank_1;
|
||||
}
|
||||
|
||||
//
|
||||
// Check for and handle any asserted DSP IRQs
|
||||
//
|
||||
void DSPHandleIRQsNP(void)
|
||||
{
|
||||
if (dsp_flags & IMASK)
|
||||
return;
|
||||
|
||||
uint32_t bits = ((dsp_control >> 10) & 0x20) | ((dsp_control >> 6) & 0x1F),
|
||||
mask = ((dsp_flags >> 11) & 0x20) | ((dsp_flags >> 4) & 0x1F);
|
||||
|
||||
bits &= mask;
|
||||
|
||||
if (!bits)
|
||||
return;
|
||||
|
||||
int which = 0;
|
||||
if (bits & 0x01)
|
||||
which = 0;
|
||||
if (bits & 0x02)
|
||||
which = 1;
|
||||
if (bits & 0x04)
|
||||
which = 2;
|
||||
if (bits & 0x08)
|
||||
which = 3;
|
||||
if (bits & 0x10)
|
||||
which = 4;
|
||||
if (bits & 0x20)
|
||||
which = 5;
|
||||
|
||||
dsp_flags |= IMASK;
|
||||
|
||||
DSPUpdateRegisterBanks();
|
||||
|
||||
dsp_reg[31] -= 4;
|
||||
dsp_reg[30] = dsp_pc - 2;
|
||||
|
||||
DSPWriteLong(dsp_reg[31], dsp_reg[30], DSP);
|
||||
|
||||
dsp_pc = dsp_reg[30] = DSP_WORK_RAM_BASE + (which * 0x10);
|
||||
}
|
||||
|
||||
//
|
||||
// Set the specified DSP IRQ line to a given state
|
||||
//
|
||||
|
@ -529,7 +529,7 @@ void DSPSetIRQLine(int irqline, int state)
|
|||
if (state)
|
||||
{
|
||||
dsp_control |= mask;
|
||||
DSPHandleIRQsNP();
|
||||
DSPHandleIRQs();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -570,10 +570,6 @@ void DSPReset(void)
|
|||
*((uint32_t *)(&dsp_ram_8[i])) = rand();
|
||||
}
|
||||
|
||||
void DSPDone(void)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// DSP execution core
|
||||
//
|
||||
|
@ -585,7 +581,7 @@ void DSPExec(int32_t cycles)
|
|||
|
||||
if (IMASKCleared && !dsp_inhibit_interrupt)
|
||||
{
|
||||
DSPHandleIRQsNP();
|
||||
DSPHandleIRQs();
|
||||
IMASKCleared = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
void DSPInit(void);
|
||||
void DSPReset(void);
|
||||
void DSPExec(int32_t);
|
||||
void DSPDone(void);
|
||||
void DSPUpdateRegisterBanks(void);
|
||||
void DSPSetIRQLine(int irqline, int state);
|
||||
uint8_t DSPReadByte(uint32_t offset, uint32_t who = UNKNOWN);
|
||||
uint16_t DSPReadWord(uint32_t offset, uint32_t who = UNKNOWN);
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
uint16_t eeprom_ram[64];
|
||||
bool eeprom_dirty;
|
||||
|
||||
static void EEPROMSave(void);
|
||||
static void eeprom_set_di(uint32_t state);
|
||||
static void eeprom_set_cs(uint32_t state);
|
||||
static uint32_t eeprom_get_do(void);
|
||||
|
@ -52,15 +51,6 @@ void EepromReset(void)
|
|||
{
|
||||
}
|
||||
|
||||
void EepromDone(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void EEPROMSave(void)
|
||||
{
|
||||
eeprom_dirty = true;
|
||||
}
|
||||
|
||||
uint8_t EepromReadByte(uint32_t offset)
|
||||
{
|
||||
switch (offset)
|
||||
|
@ -164,7 +154,7 @@ static void eeprom_set_di(uint32_t data)
|
|||
for(int i=0; i<64; i++)
|
||||
eeprom_ram[i] = jerry_ee_data;
|
||||
|
||||
EEPROMSave();
|
||||
eeprom_dirty = true;
|
||||
}
|
||||
|
||||
jerry_ee_state = EE_STATE_BUSY;
|
||||
|
@ -198,7 +188,7 @@ static void eeprom_set_di(uint32_t data)
|
|||
if (jerry_writes_enabled)
|
||||
{
|
||||
eeprom_ram[jerry_ee_address_data] = jerry_ee_data;
|
||||
EEPROMSave();
|
||||
eeprom_dirty = true;
|
||||
}
|
||||
|
||||
jerry_ee_state = EE_STATE_BUSY;
|
||||
|
@ -269,7 +259,6 @@ static void eeprom_set_cs(uint32_t)
|
|||
jerry_writes_enabled = 1;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t eeprom_get_do(void)
|
||||
{
|
||||
uint16_t data = 1;
|
||||
|
@ -296,4 +285,3 @@ static uint32_t eeprom_get_do(void)
|
|||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
void EepromInit(void);
|
||||
void EepromReset(void);
|
||||
void EepromDone(void);
|
||||
|
||||
uint8_t EepromReadByte(uint32_t offset);
|
||||
uint16_t EepromReadWord(uint32_t offset);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <stdint.h>
|
||||
#include <float.h>
|
||||
|
||||
#define EVENT_LIST_SIZE 32
|
||||
#define EVENT_LIST_SIZE 64
|
||||
|
||||
// Now, a bit of weirdness: It seems that the number of lines displayed on the screen
|
||||
// makes the effective refresh rate either 30 or 25 Hz!
|
||||
|
@ -40,15 +40,12 @@
|
|||
struct Event
|
||||
{
|
||||
bool valid;
|
||||
int eventType;
|
||||
double eventTime;
|
||||
void (* timerCallback)(void);
|
||||
};
|
||||
|
||||
static Event eventList[EVENT_LIST_SIZE];
|
||||
static Event eventListJERRY[EVENT_LIST_SIZE];
|
||||
static uint32_t nextEvent;
|
||||
static uint32_t nextEventJERRY;
|
||||
static uint32_t numberOfEvents;
|
||||
|
||||
void InitializeEventList(void)
|
||||
|
@ -56,44 +53,23 @@ void InitializeEventList(void)
|
|||
for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
|
||||
{
|
||||
eventList[i].valid = false;
|
||||
eventListJERRY[i].valid = false;
|
||||
}
|
||||
|
||||
numberOfEvents = 0;
|
||||
}
|
||||
|
||||
void SetCallbackTime(void (* callback)(void), double time, int type)
|
||||
void SetCallbackTime(void (* callback)(void), double time)
|
||||
{
|
||||
if (type == EVENT_MAIN)
|
||||
for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
|
||||
{
|
||||
for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
|
||||
if (!eventList[i].valid)
|
||||
{
|
||||
if (!eventList[i].valid)
|
||||
{
|
||||
eventList[i].timerCallback = callback;
|
||||
eventList[i].eventTime = time;
|
||||
eventList[i].eventType = type;
|
||||
eventList[i].valid = true;
|
||||
numberOfEvents++;
|
||||
eventList[i].timerCallback = callback;
|
||||
eventList[i].eventTime = time;
|
||||
eventList[i].valid = true;
|
||||
numberOfEvents++;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
|
||||
{
|
||||
if (!eventListJERRY[i].valid)
|
||||
{
|
||||
eventListJERRY[i].timerCallback = callback;
|
||||
eventListJERRY[i].eventTime = time;
|
||||
eventListJERRY[i].eventType = type;
|
||||
eventListJERRY[i].valid = true;
|
||||
numberOfEvents++;
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,33 +83,6 @@ void RemoveCallback(void (* callback)(void))
|
|||
eventList[i].valid = false;
|
||||
numberOfEvents--;
|
||||
|
||||
return;
|
||||
}
|
||||
else if (eventListJERRY[i].valid && eventListJERRY[i].timerCallback == callback)
|
||||
{
|
||||
eventListJERRY[i].valid = false;
|
||||
numberOfEvents--;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AdjustCallbackTime(void (* callback)(void), double time)
|
||||
{
|
||||
for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
|
||||
{
|
||||
if (eventList[i].valid && eventList[i].timerCallback == callback)
|
||||
{
|
||||
eventList[i].eventTime = time;
|
||||
|
||||
return;
|
||||
}
|
||||
else if (eventListJERRY[i].valid && eventListJERRY[i].timerCallback == callback)
|
||||
{
|
||||
eventListJERRY[i].eventTime = time;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -143,74 +92,36 @@ void AdjustCallbackTime(void (* callback)(void), double time)
|
|||
// Since our list is unordered WRT time, we have to search it to find the next event
|
||||
// Returns time to next event & sets nextEvent to that event
|
||||
//
|
||||
double GetTimeToNextEvent(int type)
|
||||
double GetTimeToNextEvent()
|
||||
{
|
||||
if (type == EVENT_MAIN)
|
||||
double time = DBL_MAX;
|
||||
nextEvent = EVENT_LIST_SIZE;
|
||||
|
||||
for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
|
||||
{
|
||||
double time = DBL_MAX;
|
||||
nextEvent = EVENT_LIST_SIZE;
|
||||
|
||||
for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
|
||||
if (eventList[i].valid && (eventList[i].eventTime < time))
|
||||
{
|
||||
if (eventList[i].valid && (eventList[i].eventTime < time))
|
||||
{
|
||||
time = eventList[i].eventTime;
|
||||
nextEvent = i;
|
||||
}
|
||||
time = eventList[i].eventTime;
|
||||
nextEvent = i;
|
||||
}
|
||||
|
||||
assert(nextEvent != EVENT_LIST_SIZE);
|
||||
return time;
|
||||
}
|
||||
else
|
||||
{
|
||||
double time = DBL_MAX;
|
||||
nextEventJERRY = EVENT_LIST_SIZE;
|
||||
|
||||
for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
|
||||
{
|
||||
if (eventListJERRY[i].valid && (eventListJERRY[i].eventTime < time))
|
||||
{
|
||||
time = eventListJERRY[i].eventTime;
|
||||
nextEventJERRY = i;
|
||||
}
|
||||
}
|
||||
|
||||
assert(nextEventJERRY != EVENT_LIST_SIZE);
|
||||
return time;
|
||||
}
|
||||
assert(nextEvent != EVENT_LIST_SIZE);
|
||||
return time;
|
||||
}
|
||||
|
||||
void HandleNextEvent(int type)
|
||||
void HandleNextEvent()
|
||||
{
|
||||
if (type == EVENT_MAIN)
|
||||
double elapsedTime = eventList[nextEvent].eventTime;
|
||||
void (* event)(void) = eventList[nextEvent].timerCallback;
|
||||
|
||||
for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
|
||||
{
|
||||
double elapsedTime = eventList[nextEvent].eventTime;
|
||||
void (* event)(void) = eventList[nextEvent].timerCallback;
|
||||
|
||||
for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
|
||||
{
|
||||
eventList[i].eventTime -= elapsedTime;
|
||||
}
|
||||
|
||||
eventList[nextEvent].valid = false;
|
||||
numberOfEvents--;
|
||||
|
||||
(*event)();
|
||||
eventList[i].eventTime -= elapsedTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
double elapsedTime = eventListJERRY[nextEventJERRY].eventTime;
|
||||
void (* event)(void) = eventListJERRY[nextEventJERRY].timerCallback;
|
||||
|
||||
for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
|
||||
{
|
||||
eventListJERRY[i].eventTime -= elapsedTime;
|
||||
}
|
||||
eventList[nextEvent].valid = false;
|
||||
numberOfEvents--;
|
||||
|
||||
eventListJERRY[nextEventJERRY].valid = false;
|
||||
numberOfEvents--;
|
||||
|
||||
(*event)();
|
||||
}
|
||||
(*event)();
|
||||
}
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
#ifndef __EVENT_H__
|
||||
#define __EVENT_H__
|
||||
|
||||
enum { EVENT_MAIN, EVENT_JERRY };
|
||||
|
||||
//NTSC Timings...
|
||||
#define RISC_CYCLE_IN_USEC 0.03760684198
|
||||
#define M68K_CYCLE_IN_USEC (RISC_CYCLE_IN_USEC * 2)
|
||||
|
@ -23,10 +21,9 @@ enum { EVENT_MAIN, EVENT_JERRY };
|
|||
#define USEC_TO_M68K_CYCLES(u) (uint32_t)(((u) / (vjs.hardwareTypeNTSC ? M68K_CYCLE_IN_USEC : M68K_CYCLE_PAL_IN_USEC)) + 0.5)
|
||||
|
||||
void InitializeEventList(void);
|
||||
void SetCallbackTime(void (* callback)(void), double time, int type = EVENT_MAIN);
|
||||
void SetCallbackTime(void (* callback)(void), double time);
|
||||
void RemoveCallback(void (* callback)(void));
|
||||
void AdjustCallbackTime(void (* callback)(void), double time);
|
||||
double GetTimeToNextEvent(int type = EVENT_MAIN);
|
||||
void HandleNextEvent(int type = EVENT_MAIN);
|
||||
double GetTimeToNextEvent(void);
|
||||
void HandleNextEvent(void);
|
||||
|
||||
#endif // __EVENT_H__
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
//
|
||||
// FILE.H
|
||||
//
|
||||
// File support
|
||||
//
|
||||
|
||||
#ifndef __FILE_H__
|
||||
#define __FILE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum FileType { FT_SOFTWARE=0, FT_EEPROM, FT_LABEL, FT_BOXART, FT_OVERLAY };
|
||||
// JST = Jaguar Software Type
|
||||
enum { JST_NONE = 0, JST_ROM, JST_ALPINE, JST_ABS_TYPE1, JST_ABS_TYPE2, JST_JAGSERVER, JST_WTFOMGBBQ };
|
||||
|
||||
bool JaguarLoadFile(uint8_t * buffer, uint32_t size);
|
||||
bool AlpineLoadFile(uint8_t * buffer, uint32_t size);
|
||||
uint32_t ParseFileType(uint8_t * buffer, uint32_t size);
|
||||
|
||||
#endif // __FILE_H__
|
|
@ -59,12 +59,6 @@
|
|||
#define REGPAGE 0x4000
|
||||
#define DMAEN 0x8000
|
||||
|
||||
// External global variables
|
||||
|
||||
// Private function prototypes
|
||||
|
||||
void GPUUpdateRegisterBanks(void);
|
||||
|
||||
static void gpu_opcode_add(void);
|
||||
static void gpu_opcode_addc(void);
|
||||
static void gpu_opcode_addq(void);
|
||||
|
@ -189,11 +183,6 @@ static uint32_t gpu_inhibit_interrupt;
|
|||
|
||||
static uint8_t branch_condition_table[32 * 8];
|
||||
|
||||
bool GPURunning(void)
|
||||
{
|
||||
return GPU_RUNNING;
|
||||
}
|
||||
|
||||
void build_branch_condition_table(void)
|
||||
{
|
||||
for(int i=0; i<8; i++)
|
||||
|
@ -219,6 +208,54 @@ void build_branch_condition_table(void)
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Change register banks if necessary
|
||||
//
|
||||
static void GPUUpdateRegisterBanks(void)
|
||||
{
|
||||
int bank = (gpu_flags & REGPAGE);
|
||||
|
||||
if (gpu_flags & IMASK)
|
||||
bank = 0;
|
||||
|
||||
if (bank)
|
||||
gpu_reg = gpu_reg_bank_1, gpu_alternate_reg = gpu_reg_bank_0;
|
||||
else
|
||||
gpu_reg = gpu_reg_bank_0, gpu_alternate_reg = gpu_reg_bank_1;
|
||||
}
|
||||
|
||||
static void GPUHandleIRQs(void)
|
||||
{
|
||||
if (gpu_flags & IMASK)
|
||||
return;
|
||||
|
||||
uint32_t bits = (gpu_control >> 6) & 0x1F, mask = (gpu_flags >> 4) & 0x1F;
|
||||
|
||||
bits &= mask;
|
||||
if (!bits)
|
||||
return;
|
||||
|
||||
uint32_t which = 0;
|
||||
if (bits & 0x01)
|
||||
which = 0;
|
||||
if (bits & 0x02)
|
||||
which = 1;
|
||||
if (bits & 0x04)
|
||||
which = 2;
|
||||
if (bits & 0x08)
|
||||
which = 3;
|
||||
if (bits & 0x10)
|
||||
which = 4;
|
||||
|
||||
gpu_flags |= IMASK;
|
||||
GPUUpdateRegisterBanks();
|
||||
|
||||
gpu_reg[31] -= 4;
|
||||
GPUWriteLong(gpu_reg[31], gpu_pc - 2, GPU);
|
||||
|
||||
gpu_pc = gpu_reg[30] = GPU_WORK_RAM_BASE + (which * 0x10);
|
||||
}
|
||||
|
||||
//
|
||||
// GPU byte access (read)
|
||||
//
|
||||
|
@ -480,54 +517,6 @@ void GPUWriteLong(uint32_t offset, uint32_t data, uint32_t who)
|
|||
JaguarWriteLong(offset, data, who);
|
||||
}
|
||||
|
||||
//
|
||||
// Change register banks if necessary
|
||||
//
|
||||
void GPUUpdateRegisterBanks(void)
|
||||
{
|
||||
int bank = (gpu_flags & REGPAGE);
|
||||
|
||||
if (gpu_flags & IMASK)
|
||||
bank = 0;
|
||||
|
||||
if (bank)
|
||||
gpu_reg = gpu_reg_bank_1, gpu_alternate_reg = gpu_reg_bank_0;
|
||||
else
|
||||
gpu_reg = gpu_reg_bank_0, gpu_alternate_reg = gpu_reg_bank_1;
|
||||
}
|
||||
|
||||
void GPUHandleIRQs(void)
|
||||
{
|
||||
if (gpu_flags & IMASK)
|
||||
return;
|
||||
|
||||
uint32_t bits = (gpu_control >> 6) & 0x1F, mask = (gpu_flags >> 4) & 0x1F;
|
||||
|
||||
bits &= mask;
|
||||
if (!bits)
|
||||
return;
|
||||
|
||||
uint32_t which = 0;
|
||||
if (bits & 0x01)
|
||||
which = 0;
|
||||
if (bits & 0x02)
|
||||
which = 1;
|
||||
if (bits & 0x04)
|
||||
which = 2;
|
||||
if (bits & 0x08)
|
||||
which = 3;
|
||||
if (bits & 0x10)
|
||||
which = 4;
|
||||
|
||||
gpu_flags |= IMASK;
|
||||
GPUUpdateRegisterBanks();
|
||||
|
||||
gpu_reg[31] -= 4;
|
||||
GPUWriteLong(gpu_reg[31], gpu_pc - 2, GPU);
|
||||
|
||||
gpu_pc = gpu_reg[30] = GPU_WORK_RAM_BASE + (which * 0x10);
|
||||
}
|
||||
|
||||
void GPUSetIRQLine(int irqline, int state)
|
||||
{
|
||||
uint32_t mask = 0x0040 << irqline;
|
||||
|
@ -540,10 +529,14 @@ void GPUSetIRQLine(int irqline, int state)
|
|||
}
|
||||
}
|
||||
|
||||
bool GPUIsRunning(void)
|
||||
{
|
||||
return GPU_RUNNING;
|
||||
}
|
||||
|
||||
void GPUInit(void)
|
||||
{
|
||||
build_branch_condition_table();
|
||||
|
||||
GPUReset();
|
||||
}
|
||||
|
||||
|
@ -575,10 +568,6 @@ void GPUReset(void)
|
|||
*((uint32_t *)(&gpu_ram_8[i])) = rand();
|
||||
}
|
||||
|
||||
void GPUDone(void)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Main GPU execution core
|
||||
//
|
||||
|
|
|
@ -13,9 +13,6 @@
|
|||
void GPUInit(void);
|
||||
void GPUReset(void);
|
||||
void GPUExec(int32_t);
|
||||
void GPUDone(void);
|
||||
void GPUUpdateRegisterBanks(void);
|
||||
void GPUHandleIRQs(void);
|
||||
void GPUSetIRQLine(int irqline, int state);
|
||||
|
||||
uint8_t GPUReadByte(uint32_t offset, uint32_t who = UNKNOWN);
|
||||
|
@ -25,7 +22,7 @@ void GPUWriteByte(uint32_t offset, uint8_t data, uint32_t who = UNKNOWN);
|
|||
void GPUWriteWord(uint32_t offset, uint16_t data, uint32_t who = UNKNOWN);
|
||||
void GPUWriteLong(uint32_t offset, uint32_t data, uint32_t who = UNKNOWN);
|
||||
|
||||
bool GPURunning(void);
|
||||
bool GPUIsRunning(void);
|
||||
|
||||
// GPU interrupt numbers (from $F00100, bits 4-8)
|
||||
|
||||
|
|
|
@ -443,22 +443,12 @@ void JaguarReset(void)
|
|||
SetCallbackTime(HalflineCallback, (vjs.hardwareTypeNTSC ? 31.777777777 : 32.0));
|
||||
}
|
||||
|
||||
void JaguarDone(void)
|
||||
{
|
||||
CDHLEDone();
|
||||
CDROMDone();
|
||||
GPUDone();
|
||||
DSPDone();
|
||||
TOMDone();
|
||||
JERRYDone();
|
||||
}
|
||||
|
||||
//
|
||||
// New Jaguar execution stack
|
||||
// Jaguar execution stack
|
||||
// This executes 1 frame's worth of code.
|
||||
//
|
||||
bool frameDone;
|
||||
void JaguarExecuteNew(void)
|
||||
void JaguarAdvance(void)
|
||||
{
|
||||
frameDone = false;
|
||||
TOMStartFrame();
|
||||
|
@ -468,8 +458,8 @@ void JaguarExecuteNew(void)
|
|||
double timeToNextEvent = GetTimeToNextEvent();
|
||||
|
||||
m68k_execute(USEC_TO_M68K_CYCLES(timeToNextEvent));
|
||||
|
||||
GPUExec(USEC_TO_RISC_CYCLES(timeToNextEvent));
|
||||
DSPExec(USEC_TO_RISC_CYCLES(timeToNextEvent));
|
||||
|
||||
HandleNextEvent();
|
||||
}
|
||||
|
@ -522,11 +512,10 @@ void HalflineCallback(void)
|
|||
m68k_set_irq(2);
|
||||
}
|
||||
|
||||
TOMExecHalfline(vc, true);
|
||||
TOMExecHalfline(vc);
|
||||
|
||||
if ((vc & 0x7FF) == 0)
|
||||
{
|
||||
JoystickExec();
|
||||
frameDone = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
void JaguarInit(void);
|
||||
void JaguarReset(void);
|
||||
void JaguarDone(void);
|
||||
|
||||
uint8_t JaguarReadByte(uint32_t offset, uint32_t who = UNKNOWN);
|
||||
uint16_t JaguarReadWord(uint32_t offset, uint32_t who = UNKNOWN);
|
||||
|
@ -15,7 +14,7 @@ void JaguarWriteByte(uint32_t offset, uint8_t data, uint32_t who = UNKNOWN);
|
|||
void JaguarWriteWord(uint32_t offset, uint16_t data, uint32_t who = UNKNOWN);
|
||||
void JaguarWriteLong(uint32_t offset, uint32_t data, uint32_t who = UNKNOWN);
|
||||
|
||||
void JaguarExecuteNew(void);
|
||||
void JaguarAdvance(void);
|
||||
|
||||
// Exports from JAGUAR.CPP
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "wavetable.h"
|
||||
#include "cdhle.h"
|
||||
|
||||
/*static*/ uint8_t jerry_ram_8[0x10000];
|
||||
uint8_t jerry_ram_8[0x10000];
|
||||
|
||||
// JERRY Registers (write, offset from $F10000)
|
||||
#define JPIT1 0x00
|
||||
|
@ -46,8 +46,6 @@
|
|||
#define SCLK 0xA150
|
||||
#define SMODE 0xA154
|
||||
|
||||
uint8_t analog_x, analog_y;
|
||||
|
||||
static uint32_t JERRYPIT1Prescaler;
|
||||
static uint32_t JERRYPIT1Divider;
|
||||
static uint32_t JERRYPIT2Prescaler;
|
||||
|
@ -56,22 +54,17 @@ static int32_t jerry_timer_1_counter;
|
|||
static int32_t jerry_timer_2_counter;
|
||||
|
||||
int32_t JERRYI2SInterruptTimer = -1;
|
||||
uint32_t jerryI2SCycles;
|
||||
uint32_t jerryIntPending;
|
||||
static uint32_t jerryI2SCycles;
|
||||
|
||||
static uint16_t jerryInterruptMask = 0;
|
||||
static uint16_t jerryPendingInterrupt = 0;
|
||||
|
||||
// Private function prototypes
|
||||
|
||||
void JERRYResetPIT1(void);
|
||||
void JERRYResetPIT2(void);
|
||||
void JERRYResetI2S(void);
|
||||
|
||||
void JERRYPIT1Callback(void);
|
||||
void JERRYPIT2Callback(void);
|
||||
void JERRYI2SCallback(void);
|
||||
static void JERRYResetPIT1(void);
|
||||
static void JERRYResetPIT2(void);
|
||||
static void JERRYResetI2S(void);
|
||||
|
||||
static void JERRYPIT1Callback(void);
|
||||
static void JERRYPIT2Callback(void);
|
||||
|
||||
void JERRYResetI2S(void)
|
||||
{
|
||||
|
@ -86,7 +79,7 @@ void JERRYResetPIT1(void)
|
|||
if (JERRYPIT1Prescaler | JERRYPIT1Divider)
|
||||
{
|
||||
double usecs = (float)(JERRYPIT1Prescaler + 1) * (float)(JERRYPIT1Divider + 1) * RISC_CYCLE_IN_USEC;
|
||||
SetCallbackTime(JERRYPIT1Callback, usecs, EVENT_JERRY);
|
||||
SetCallbackTime(JERRYPIT1Callback, usecs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,7 +90,7 @@ void JERRYResetPIT2(void)
|
|||
if (JERRYPIT1Prescaler | JERRYPIT1Divider)
|
||||
{
|
||||
double usecs = (float)(JERRYPIT2Prescaler + 1) * (float)(JERRYPIT2Divider + 1) * RISC_CYCLE_IN_USEC;
|
||||
SetCallbackTime(JERRYPIT2Callback, usecs, EVENT_JERRY);
|
||||
SetCallbackTime(JERRYPIT2Callback, usecs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,7 +132,7 @@ void JERRYI2SCallback(void)
|
|||
{
|
||||
DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE);
|
||||
double usecs = (float)jerryI2SCycles * (vjs.hardwareTypeNTSC ? RISC_CYCLE_IN_USEC : RISC_CYCLE_PAL_IN_USEC);
|
||||
SetCallbackTime(JERRYI2SCallback, usecs, EVENT_JERRY);
|
||||
SetCallbackTime(JERRYI2SCallback, usecs);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -147,7 +140,7 @@ void JERRYI2SCallback(void)
|
|||
{
|
||||
DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE);
|
||||
}
|
||||
SetCallbackTime(JERRYI2SCallback, 22.675737, EVENT_JERRY);
|
||||
SetCallbackTime(JERRYI2SCallback, 22.675737);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,14 +180,6 @@ void JERRYReset(void)
|
|||
DACReset();
|
||||
}
|
||||
|
||||
void JERRYDone(void)
|
||||
{
|
||||
JoystickDone();
|
||||
DACDone();
|
||||
EepromDone();
|
||||
MTDone();
|
||||
}
|
||||
|
||||
bool JERRYIRQEnabled(int irq)
|
||||
{
|
||||
return jerryInterruptMask & irq;
|
||||
|
@ -262,8 +247,6 @@ uint16_t JERRYReadWord(uint32_t offset, uint32_t who)
|
|||
//
|
||||
void JERRYWriteByte(uint32_t offset, uint8_t data, uint32_t who)
|
||||
{
|
||||
jerry_ram_8[offset & 0xFFFF] = data;
|
||||
|
||||
if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE + 0x20))
|
||||
{
|
||||
DSPWriteByte(offset, data, who);
|
||||
|
@ -294,6 +277,11 @@ void JERRYWriteByte(uint32_t offset, uint8_t data, uint32_t who)
|
|||
{
|
||||
EepromWriteByte(offset, data);
|
||||
}
|
||||
|
||||
if (offset >= 0xF1D000 && offset <= 0xF1DFFF)
|
||||
return;
|
||||
|
||||
jerry_ram_8[offset & 0xFFFF] = data;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -301,9 +289,6 @@ void JERRYWriteByte(uint32_t offset, uint8_t data, uint32_t who)
|
|||
//
|
||||
void JERRYWriteWord(uint32_t offset, uint16_t data, uint32_t who)
|
||||
{
|
||||
jerry_ram_8[(offset+0) & 0xFFFF] = (data >> 8) & 0xFF;
|
||||
jerry_ram_8[(offset+1) & 0xFFFF] = data & 0xFF;
|
||||
|
||||
if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE + 0x20))
|
||||
{
|
||||
DSPWriteWord(offset, data, who);
|
||||
|
@ -335,6 +320,7 @@ void JERRYWriteWord(uint32_t offset, uint16_t data, uint32_t who)
|
|||
case 6:
|
||||
JERRYPIT2Divider = data;
|
||||
JERRYResetPIT2();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (offset >= 0xF10020 && offset <= 0xF10022)
|
||||
|
@ -351,16 +337,10 @@ void JERRYWriteWord(uint32_t offset, uint16_t data, uint32_t who)
|
|||
{
|
||||
EepromWriteWord(offset, data);
|
||||
}
|
||||
}
|
||||
|
||||
int JERRYGetPIT1Frequency(void)
|
||||
{
|
||||
int systemClockFrequency = (vjs.hardwareTypeNTSC ? RISC_CLOCK_RATE_NTSC : RISC_CLOCK_RATE_PAL);
|
||||
return systemClockFrequency / ((JERRYPIT1Prescaler + 1) * (JERRYPIT1Divider + 1));
|
||||
}
|
||||
if (offset >= 0xF1D000 && offset <= 0xF1DFFF)
|
||||
return;
|
||||
|
||||
int JERRYGetPIT2Frequency(void)
|
||||
{
|
||||
int systemClockFrequency = (vjs.hardwareTypeNTSC ? RISC_CLOCK_RATE_NTSC : RISC_CLOCK_RATE_PAL);
|
||||
return systemClockFrequency / ((JERRYPIT2Prescaler + 1) * (JERRYPIT2Divider + 1));
|
||||
jerry_ram_8[(offset+0) & 0xFFFF] = (data >> 8) & 0xFF;
|
||||
jerry_ram_8[(offset+1) & 0xFFFF] = data & 0xFF;
|
||||
}
|
||||
|
|
|
@ -9,28 +9,18 @@
|
|||
|
||||
void JERRYInit(void);
|
||||
void JERRYReset(void);
|
||||
void JERRYDone(void);
|
||||
|
||||
uint8_t JERRYReadByte(uint32_t offset, uint32_t who = UNKNOWN);
|
||||
uint16_t JERRYReadWord(uint32_t offset, uint32_t who = UNKNOWN);
|
||||
void JERRYWriteByte(uint32_t offset, uint8_t data, uint32_t who = UNKNOWN);
|
||||
void JERRYWriteWord(uint32_t offset, uint16_t data, uint32_t who = UNKNOWN);
|
||||
|
||||
void JERRYExecPIT(uint32_t cycles);
|
||||
void JERRYI2SExec(uint32_t cycles);
|
||||
|
||||
int JERRYGetPIT1Frequency(void);
|
||||
int JERRYGetPIT2Frequency(void);
|
||||
|
||||
// 68000 Interrupt bit positions (enabled at $F10020)
|
||||
|
||||
enum { IRQ2_EXTERNAL=0x01, IRQ2_DSP=0x02, IRQ2_TIMER1=0x04, IRQ2_TIMER2=0x08, IRQ2_ASI=0x10, IRQ2_SSI=0x20 };
|
||||
|
||||
bool JERRYIRQEnabled(int irq);
|
||||
void JERRYSetPendingIRQ(int irq);
|
||||
|
||||
// This should stay inside this file, but it's here for now...
|
||||
// Need to set up an interface function so that this can go back
|
||||
void JERRYI2SCallback(void);
|
||||
|
||||
// External variables
|
||||
|
|
|
@ -19,12 +19,11 @@
|
|||
#include "jaguar.h"
|
||||
#include "settings.h"
|
||||
|
||||
// Global vars
|
||||
|
||||
static uint8_t joystick_ram[4];
|
||||
uint8_t joypad0Buttons[21];
|
||||
uint8_t joypad1Buttons[21];
|
||||
static bool joysticksEnabled;
|
||||
bool audioEnabled;
|
||||
|
||||
extern bool lagged;
|
||||
|
||||
|
@ -33,20 +32,13 @@ void JoystickInit(void)
|
|||
JoystickReset();
|
||||
}
|
||||
|
||||
void JoystickExec(void)
|
||||
{
|
||||
}
|
||||
|
||||
void JoystickReset(void)
|
||||
{
|
||||
memset(joystick_ram, 0x00, 4);
|
||||
memset(joypad0Buttons, 0, 21);
|
||||
memset(joypad1Buttons, 0, 21);
|
||||
joysticksEnabled = false;
|
||||
}
|
||||
|
||||
void JoystickDone(void)
|
||||
{
|
||||
audioEnabled = false;
|
||||
}
|
||||
|
||||
uint16_t JoystickReadWord(uint32_t offset)
|
||||
|
@ -140,6 +132,7 @@ void JoystickWriteWord(uint32_t offset, uint16_t data)
|
|||
|
||||
if (offset == 0)
|
||||
{
|
||||
joysticksEnabled = (data & 0x8000 ? true : false);
|
||||
audioEnabled = data & 0x0100;
|
||||
joysticksEnabled = data & 0x8000;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,10 +33,8 @@ BUTTON_PAUSE = 20, BUTTON_LAST = 20 };
|
|||
|
||||
void JoystickInit(void);
|
||||
void JoystickReset(void);
|
||||
void JoystickDone(void);
|
||||
void JoystickWriteWord(uint32_t, uint16_t);
|
||||
uint16_t JoystickReadWord(uint32_t);
|
||||
void JoystickExec(void);
|
||||
|
||||
extern uint8_t joypad0Buttons[];
|
||||
extern uint8_t joypad1Buttons[];
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "readcpu.h"
|
||||
|
||||
int nr_cpuop_funcs;
|
||||
struct instr table68k[65536];
|
||||
|
||||
const struct mnemolookup lookuptab[] = {
|
||||
{ i_ILLG, "ILLEGAL" },
|
||||
|
@ -150,10 +151,6 @@ const struct mnemolookup lookuptab[] = {
|
|||
{ i_ILLG, "" },
|
||||
};
|
||||
|
||||
|
||||
struct instr * table68k;
|
||||
|
||||
|
||||
STATIC_INLINE amodes mode_from_str(const char * str)
|
||||
{
|
||||
if (strncmp (str, "Dreg", 4) == 0) return Dreg;
|
||||
|
@ -173,7 +170,6 @@ STATIC_INLINE amodes mode_from_str(const char * str)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
STATIC_INLINE amodes mode_from_mr(int mode, int reg)
|
||||
{
|
||||
switch (mode)
|
||||
|
@ -203,7 +199,6 @@ STATIC_INLINE amodes mode_from_mr(int mode, int reg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void build_insn(int insn)
|
||||
{
|
||||
int find = -1;
|
||||
|
@ -220,14 +215,14 @@ static void build_insn(int insn)
|
|||
{
|
||||
switch (id.flaginfo[j].flagset)
|
||||
{
|
||||
case fa_unset: break;
|
||||
case fa_isjmp: isjmp = 1; break;
|
||||
case fa_isbranch: isjmp = 1; break;
|
||||
case fa_zero: flagdead |= 1 << j; break;
|
||||
case fa_one: flagdead |= 1 << j; break;
|
||||
case fa_dontcare: flagdead |= 1 << j; break;
|
||||
case fa_unknown: isjmp = 1; flagdead = -1; goto out1;
|
||||
case fa_set: flagdead |= 1 << j; break;
|
||||
case fa_unset: break;
|
||||
case fa_isjmp: isjmp = 1; break;
|
||||
case fa_isbranch: isjmp = 1; break;
|
||||
case fa_zero: flagdead |= 1 << j; break;
|
||||
case fa_one: flagdead |= 1 << j; break;
|
||||
case fa_dontcare: flagdead |= 1 << j; break;
|
||||
case fa_unknown: isjmp = 1; flagdead = -1; goto out1;
|
||||
case fa_set: flagdead |= 1 << j; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,11 +231,11 @@ out1:
|
|||
{
|
||||
switch (id.flaginfo[j].flaguse)
|
||||
{
|
||||
case fu_unused: break;
|
||||
case fu_isjmp: isjmp = 1; flaglive |= 1 << j; break;
|
||||
case fu_maybecc: isjmp = 1; flaglive |= 1 << j; break;
|
||||
case fu_unknown: isjmp = 1; flaglive |= 1 << j; break;
|
||||
case fu_used: flaglive |= 1 << j; break;
|
||||
case fu_unused: break;
|
||||
case fu_isjmp: isjmp = 1; flaglive |= 1 << j; break;
|
||||
case fu_maybecc: isjmp = 1; flaglive |= 1 << j; break;
|
||||
case fu_unknown: isjmp = 1; flaglive |= 1 << j; break;
|
||||
case fu_used: flaglive |= 1 << j; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -318,19 +313,19 @@ out1:
|
|||
|
||||
switch (opcstr[pos])
|
||||
{
|
||||
case 'B': sz = sz_byte; break;
|
||||
case 'W': sz = sz_word; break;
|
||||
case 'L': sz = sz_long; break;
|
||||
case 'z':
|
||||
switch (bitval[bitz])
|
||||
{
|
||||
case 0: sz = sz_byte; break;
|
||||
case 1: sz = sz_word; break;
|
||||
case 2: sz = sz_long; break;
|
||||
case 'B': sz = sz_byte; break;
|
||||
case 'W': sz = sz_word; break;
|
||||
case 'L': sz = sz_long; break;
|
||||
case 'z':
|
||||
switch (bitval[bitz])
|
||||
{
|
||||
case 0: sz = sz_byte; break;
|
||||
case 1: sz = sz_word; break;
|
||||
case 2: sz = sz_long; break;
|
||||
default: abort();
|
||||
}
|
||||
break;
|
||||
default: abort();
|
||||
}
|
||||
break;
|
||||
default: abort();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -342,9 +337,9 @@ out1:
|
|||
find = -1;
|
||||
switch (bitval[bitf])
|
||||
{
|
||||
case 0: mnemonic[mnp] = 'R'; break;
|
||||
case 1: mnemonic[mnp] = 'L'; break;
|
||||
default: abort();
|
||||
case 0: mnemonic[mnp] = 'R'; break;
|
||||
case 1: mnemonic[mnp] = 'L'; break;
|
||||
default: abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -365,252 +360,252 @@ out1:
|
|||
usesrc = 1;
|
||||
switch (opcstr[pos++])
|
||||
{
|
||||
case 'D':
|
||||
srcmode = Dreg;
|
||||
case 'D':
|
||||
srcmode = Dreg;
|
||||
|
||||
switch (opcstr[pos++])
|
||||
{
|
||||
case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
|
||||
case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
|
||||
default: abort();
|
||||
}
|
||||
|
||||
break;
|
||||
case 'A':
|
||||
srcmode = Areg;
|
||||
|
||||
switch (opcstr[pos++])
|
||||
{
|
||||
case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
|
||||
case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
|
||||
default: abort();
|
||||
}
|
||||
|
||||
switch (opcstr[pos])
|
||||
{
|
||||
case 'p': srcmode = Apdi; pos++; break;
|
||||
case 'P': srcmode = Aipi; pos++; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
srcmode = absl;
|
||||
break;
|
||||
case '#':
|
||||
switch (opcstr[pos++])
|
||||
{
|
||||
case 'z': srcmode = imm; break;
|
||||
case '0': srcmode = imm0; break;
|
||||
case '1': srcmode = imm1; break;
|
||||
case '2': srcmode = imm2; break;
|
||||
case 'i':
|
||||
srcmode = immi; srcreg = (int32_t)(int8_t)bitval[biti];
|
||||
|
||||
if (CPU_EMU_SIZE < 4)
|
||||
switch (opcstr[pos++])
|
||||
{
|
||||
srctype = 1;
|
||||
srcgather = 1;
|
||||
srcpos = bitpos[biti];
|
||||
case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
|
||||
case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
|
||||
default: abort();
|
||||
}
|
||||
|
||||
break;
|
||||
case 'j':
|
||||
srcmode = immi; srcreg = bitval[bitj];
|
||||
case 'A':
|
||||
srcmode = Areg;
|
||||
|
||||
if (CPU_EMU_SIZE < 3)
|
||||
switch (opcstr[pos++])
|
||||
{
|
||||
srcgather = 1;
|
||||
srctype = 3;
|
||||
srcpos = bitpos[bitj];
|
||||
case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
|
||||
case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
|
||||
default: abort();
|
||||
}
|
||||
|
||||
switch (opcstr[pos])
|
||||
{
|
||||
case 'p': srcmode = Apdi; pos++; break;
|
||||
case 'P': srcmode = Aipi; pos++; break;
|
||||
}
|
||||
break;
|
||||
case 'J':
|
||||
srcmode = immi; srcreg = bitval[bitJ];
|
||||
|
||||
if (CPU_EMU_SIZE < 5)
|
||||
{
|
||||
srcgather = 1;
|
||||
srctype = 2;
|
||||
srcpos = bitpos[bitJ];
|
||||
}
|
||||
|
||||
case 'L':
|
||||
srcmode = absl;
|
||||
break;
|
||||
case 'k':
|
||||
srcmode = immi; srcreg = bitval[bitk];
|
||||
|
||||
if (CPU_EMU_SIZE < 3)
|
||||
case '#':
|
||||
switch (opcstr[pos++])
|
||||
{
|
||||
srcgather = 1;
|
||||
srctype = 4;
|
||||
srcpos = bitpos[bitk];
|
||||
}
|
||||
case 'z': srcmode = imm; break;
|
||||
case '0': srcmode = imm0; break;
|
||||
case '1': srcmode = imm1; break;
|
||||
case '2': srcmode = imm2; break;
|
||||
case 'i':
|
||||
srcmode = immi; srcreg = (int32_t)(int8_t)bitval[biti];
|
||||
|
||||
break;
|
||||
case 'K':
|
||||
srcmode = immi; srcreg = bitval[bitK];
|
||||
|
||||
if (CPU_EMU_SIZE < 5)
|
||||
{
|
||||
srcgather = 1;
|
||||
srctype = 5;
|
||||
srcpos = bitpos[bitK];
|
||||
}
|
||||
|
||||
break;
|
||||
case 'p':
|
||||
srcmode = immi; srcreg = bitval[bitK];
|
||||
|
||||
if (CPU_EMU_SIZE < 5)
|
||||
{
|
||||
srcgather = 1;
|
||||
srctype = 7;
|
||||
srcpos = bitpos[bitp];
|
||||
}
|
||||
|
||||
break;
|
||||
default: abort();
|
||||
}
|
||||
|
||||
break;
|
||||
case 'd':
|
||||
srcreg = bitval[bitD];
|
||||
srcmode = mode_from_mr(bitval[bitd],bitval[bitD]);
|
||||
|
||||
if (srcmode == am_illg)
|
||||
continue;
|
||||
|
||||
if (CPU_EMU_SIZE < 2
|
||||
&& (srcmode == Areg || srcmode == Dreg || srcmode == Aind
|
||||
|| srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
|
||||
|| srcmode == Apdi))
|
||||
{
|
||||
srcgather = 1;
|
||||
srcpos = bitpos[bitD];
|
||||
}
|
||||
|
||||
if (opcstr[pos] == '[')
|
||||
{
|
||||
pos++;
|
||||
|
||||
if (opcstr[pos] == '!')
|
||||
{
|
||||
do
|
||||
{
|
||||
pos++;
|
||||
|
||||
if (mode_from_str(opcstr + pos) == srcmode)
|
||||
goto nomatch;
|
||||
|
||||
pos += 4;
|
||||
}
|
||||
while (opcstr[pos] == ',');
|
||||
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (opcstr[pos + 4] == '-')
|
||||
{
|
||||
if (mode_from_str(opcstr + pos) == srcmode)
|
||||
srcmode = mode_from_str(opcstr + pos + 5);
|
||||
else
|
||||
goto nomatch;
|
||||
|
||||
pos += 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(mode_from_str(opcstr + pos) != srcmode)
|
||||
if (CPU_EMU_SIZE < 4)
|
||||
{
|
||||
pos += 4;
|
||||
|
||||
if (opcstr[pos] == ']')
|
||||
goto nomatch;
|
||||
|
||||
pos++;
|
||||
srctype = 1;
|
||||
srcgather = 1;
|
||||
srcpos = bitpos[biti];
|
||||
}
|
||||
|
||||
while(opcstr[pos] != ']')
|
||||
pos++;
|
||||
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
case 'j':
|
||||
srcmode = immi; srcreg = bitval[bitj];
|
||||
|
||||
if (CPU_EMU_SIZE < 3)
|
||||
{
|
||||
srcgather = 1;
|
||||
srctype = 3;
|
||||
srcpos = bitpos[bitj];
|
||||
}
|
||||
|
||||
break;
|
||||
case 'J':
|
||||
srcmode = immi; srcreg = bitval[bitJ];
|
||||
|
||||
if (CPU_EMU_SIZE < 5)
|
||||
{
|
||||
srcgather = 1;
|
||||
srctype = 2;
|
||||
srcpos = bitpos[bitJ];
|
||||
}
|
||||
|
||||
break;
|
||||
case 'k':
|
||||
srcmode = immi; srcreg = bitval[bitk];
|
||||
|
||||
if (CPU_EMU_SIZE < 3)
|
||||
{
|
||||
srcgather = 1;
|
||||
srctype = 4;
|
||||
srcpos = bitpos[bitk];
|
||||
}
|
||||
|
||||
break;
|
||||
case 'K':
|
||||
srcmode = immi; srcreg = bitval[bitK];
|
||||
|
||||
if (CPU_EMU_SIZE < 5)
|
||||
{
|
||||
srcgather = 1;
|
||||
srctype = 5;
|
||||
srcpos = bitpos[bitK];
|
||||
}
|
||||
|
||||
break;
|
||||
case 'p':
|
||||
srcmode = immi; srcreg = bitval[bitK];
|
||||
|
||||
if (CPU_EMU_SIZE < 5)
|
||||
{
|
||||
srcgather = 1;
|
||||
srctype = 7;
|
||||
srcpos = bitpos[bitp];
|
||||
}
|
||||
|
||||
break;
|
||||
default: abort();
|
||||
}
|
||||
}
|
||||
|
||||
if (srcmode == imm || srcmode == PC16 || srcmode == PC8r)
|
||||
goto nomatch;
|
||||
break;
|
||||
case 'd':
|
||||
srcreg = bitval[bitD];
|
||||
srcmode = mode_from_mr(bitval[bitd],bitval[bitD]);
|
||||
|
||||
break;
|
||||
case 's':
|
||||
srcreg = bitval[bitS];
|
||||
srcmode = mode_from_mr(bitval[bits],bitval[bitS]);
|
||||
if (srcmode == am_illg)
|
||||
continue;
|
||||
|
||||
if (srcmode == am_illg)
|
||||
continue;
|
||||
|
||||
if (CPU_EMU_SIZE < 2
|
||||
&& (srcmode == Areg || srcmode == Dreg || srcmode == Aind
|
||||
|| srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
|
||||
|| srcmode == Apdi))
|
||||
{
|
||||
srcgather = 1;
|
||||
srcpos = bitpos[bitS];
|
||||
}
|
||||
|
||||
if (opcstr[pos] == '[')
|
||||
{
|
||||
pos++;
|
||||
|
||||
if (opcstr[pos] == '!')
|
||||
if (CPU_EMU_SIZE < 2
|
||||
&& (srcmode == Areg || srcmode == Dreg || srcmode == Aind
|
||||
|| srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
|
||||
|| srcmode == Apdi))
|
||||
{
|
||||
do
|
||||
{
|
||||
pos++;
|
||||
|
||||
if (mode_from_str(opcstr + pos) == srcmode)
|
||||
goto nomatch;
|
||||
|
||||
pos += 4;
|
||||
}
|
||||
while (opcstr[pos] == ',');
|
||||
srcgather = 1;
|
||||
srcpos = bitpos[bitD];
|
||||
}
|
||||
|
||||
if (opcstr[pos] == '[')
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (opcstr[pos + 4] == '-')
|
||||
{
|
||||
if (mode_from_str(opcstr + pos) == srcmode)
|
||||
srcmode = mode_from_str(opcstr + pos + 5);
|
||||
else
|
||||
goto nomatch;
|
||||
|
||||
pos += 10;
|
||||
if (opcstr[pos] == '!')
|
||||
{
|
||||
do
|
||||
{
|
||||
pos++;
|
||||
|
||||
if (mode_from_str(opcstr + pos) == srcmode)
|
||||
goto nomatch;
|
||||
|
||||
pos += 4;
|
||||
}
|
||||
while (opcstr[pos] == ',');
|
||||
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(mode_from_str(opcstr+pos) != srcmode)
|
||||
if (opcstr[pos + 4] == '-')
|
||||
{
|
||||
pos += 4;
|
||||
|
||||
if (opcstr[pos] == ']')
|
||||
if (mode_from_str(opcstr + pos) == srcmode)
|
||||
srcmode = mode_from_str(opcstr + pos + 5);
|
||||
else
|
||||
goto nomatch;
|
||||
|
||||
pos++;
|
||||
pos += 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(mode_from_str(opcstr + pos) != srcmode)
|
||||
{
|
||||
pos += 4;
|
||||
|
||||
if (opcstr[pos] == ']')
|
||||
goto nomatch;
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
while(opcstr[pos] != ']')
|
||||
pos++;
|
||||
|
||||
while(opcstr[pos] != ']')
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (srcmode == imm || srcmode == PC16 || srcmode == PC8r)
|
||||
goto nomatch;
|
||||
|
||||
break;
|
||||
case 's':
|
||||
srcreg = bitval[bitS];
|
||||
srcmode = mode_from_mr(bitval[bits],bitval[bitS]);
|
||||
|
||||
if (srcmode == am_illg)
|
||||
continue;
|
||||
|
||||
if (CPU_EMU_SIZE < 2
|
||||
&& (srcmode == Areg || srcmode == Dreg || srcmode == Aind
|
||||
|| srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
|
||||
|| srcmode == Apdi))
|
||||
{
|
||||
srcgather = 1;
|
||||
srcpos = bitpos[bitS];
|
||||
}
|
||||
|
||||
if (opcstr[pos] == '[')
|
||||
{
|
||||
pos++;
|
||||
|
||||
if (opcstr[pos] == '!')
|
||||
{
|
||||
do
|
||||
{
|
||||
pos++;
|
||||
|
||||
if (mode_from_str(opcstr + pos) == srcmode)
|
||||
goto nomatch;
|
||||
|
||||
pos += 4;
|
||||
}
|
||||
while (opcstr[pos] == ',');
|
||||
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (opcstr[pos + 4] == '-')
|
||||
{
|
||||
if (mode_from_str(opcstr + pos) == srcmode)
|
||||
srcmode = mode_from_str(opcstr + pos + 5);
|
||||
else
|
||||
goto nomatch;
|
||||
|
||||
pos += 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(mode_from_str(opcstr+pos) != srcmode)
|
||||
{
|
||||
pos += 4;
|
||||
|
||||
if (opcstr[pos] == ']')
|
||||
goto nomatch;
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
while(opcstr[pos] != ']')
|
||||
pos++;
|
||||
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: abort();
|
||||
break;
|
||||
default: abort();
|
||||
}
|
||||
|
||||
if (srcmode != Areg && srcmode != Dreg && srcmode != Aind
|
||||
|
@ -632,196 +627,196 @@ out1:
|
|||
|
||||
switch (opcstr[pos++])
|
||||
{
|
||||
case 'D':
|
||||
destmode = Dreg;
|
||||
case 'D':
|
||||
destmode = Dreg;
|
||||
|
||||
switch (opcstr[pos++])
|
||||
{
|
||||
case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
|
||||
case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
|
||||
default: abort();
|
||||
}
|
||||
switch (opcstr[pos++])
|
||||
{
|
||||
case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
|
||||
case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
|
||||
default: abort();
|
||||
}
|
||||
|
||||
if (dstpos < 0 || dstpos >= 32)
|
||||
abort();
|
||||
if (dstpos < 0 || dstpos >= 32)
|
||||
abort();
|
||||
|
||||
break;
|
||||
case 'A':
|
||||
destmode = Areg;
|
||||
break;
|
||||
case 'A':
|
||||
destmode = Areg;
|
||||
|
||||
switch (opcstr[pos++])
|
||||
{
|
||||
case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
|
||||
case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
|
||||
case 'x': destreg = 0; dstgather = 0; dstpos = 0; break;
|
||||
default: abort();
|
||||
}
|
||||
switch (opcstr[pos++])
|
||||
{
|
||||
case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
|
||||
case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
|
||||
case 'x': destreg = 0; dstgather = 0; dstpos = 0; break;
|
||||
default: abort();
|
||||
}
|
||||
|
||||
if (dstpos < 0 || dstpos >= 32)
|
||||
abort();
|
||||
if (dstpos < 0 || dstpos >= 32)
|
||||
abort();
|
||||
|
||||
switch (opcstr[pos])
|
||||
{
|
||||
case 'p': destmode = Apdi; pos++; break;
|
||||
case 'P': destmode = Aipi; pos++; break;
|
||||
}
|
||||
switch (opcstr[pos])
|
||||
{
|
||||
case 'p': destmode = Apdi; pos++; break;
|
||||
case 'P': destmode = Aipi; pos++; break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 'L':
|
||||
destmode = absl;
|
||||
break;
|
||||
case '#':
|
||||
switch (opcstr[pos++])
|
||||
{
|
||||
case 'z': destmode = imm; break;
|
||||
case '0': destmode = imm0; break;
|
||||
case '1': destmode = imm1; break;
|
||||
case '2': destmode = imm2; break;
|
||||
case 'i': destmode = immi; destreg = (int32_t)(int8_t)bitval[biti]; break;
|
||||
case 'j': destmode = immi; destreg = bitval[bitj]; break;
|
||||
case 'J': destmode = immi; destreg = bitval[bitJ]; break;
|
||||
case 'k': destmode = immi; destreg = bitval[bitk]; break;
|
||||
case 'K': destmode = immi; destreg = bitval[bitK]; break;
|
||||
default: abort();
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
destreg = bitval[bitD];
|
||||
destmode = mode_from_mr(bitval[bitd],bitval[bitD]);
|
||||
break;
|
||||
case 'L':
|
||||
destmode = absl;
|
||||
break;
|
||||
case '#':
|
||||
switch (opcstr[pos++])
|
||||
{
|
||||
case 'z': destmode = imm; break;
|
||||
case '0': destmode = imm0; break;
|
||||
case '1': destmode = imm1; break;
|
||||
case '2': destmode = imm2; break;
|
||||
case 'i': destmode = immi; destreg = (int32_t)(int8_t)bitval[biti]; break;
|
||||
case 'j': destmode = immi; destreg = bitval[bitj]; break;
|
||||
case 'J': destmode = immi; destreg = bitval[bitJ]; break;
|
||||
case 'k': destmode = immi; destreg = bitval[bitk]; break;
|
||||
case 'K': destmode = immi; destreg = bitval[bitK]; break;
|
||||
default: abort();
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
destreg = bitval[bitD];
|
||||
destmode = mode_from_mr(bitval[bitd],bitval[bitD]);
|
||||
|
||||
if (destmode == am_illg)
|
||||
if (destmode == am_illg)
|
||||
continue;
|
||||
|
||||
if (CPU_EMU_SIZE < 1
|
||||
&& (destmode == Areg || destmode == Dreg || destmode == Aind
|
||||
|| destmode == Ad16 || destmode == Ad8r || destmode == Aipi
|
||||
|| destmode == Apdi))
|
||||
{
|
||||
dstgather = 1;
|
||||
dstpos = bitpos[bitD];
|
||||
}
|
||||
|
||||
if (opcstr[pos] == '[')
|
||||
{
|
||||
pos++;
|
||||
|
||||
if (opcstr[pos] == '!')
|
||||
{
|
||||
do
|
||||
{
|
||||
pos++;
|
||||
|
||||
if (mode_from_str(opcstr + pos) == destmode)
|
||||
goto nomatch;
|
||||
|
||||
pos += 4;
|
||||
}
|
||||
while (opcstr[pos] == ',');
|
||||
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (opcstr[pos+4] == '-')
|
||||
{
|
||||
if (mode_from_str(opcstr + pos) == destmode)
|
||||
destmode = mode_from_str(opcstr + pos + 5);
|
||||
else
|
||||
goto nomatch;
|
||||
|
||||
pos += 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(mode_from_str(opcstr + pos) != destmode)
|
||||
{
|
||||
pos += 4;
|
||||
|
||||
if (opcstr[pos] == ']')
|
||||
goto nomatch;
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
while(opcstr[pos] != ']')
|
||||
pos++;
|
||||
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (destmode == imm || destmode == PC16 || destmode == PC8r)
|
||||
goto nomatch;
|
||||
|
||||
break;
|
||||
case 's':
|
||||
destreg = bitval[bitS];
|
||||
destmode = mode_from_mr(bitval[bits], bitval[bitS]);
|
||||
|
||||
if (destmode == am_illg)
|
||||
continue;
|
||||
|
||||
if (CPU_EMU_SIZE < 1
|
||||
&& (destmode == Areg || destmode == Dreg || destmode == Aind
|
||||
|| destmode == Ad16 || destmode == Ad8r || destmode == Aipi
|
||||
|| destmode == Apdi))
|
||||
{
|
||||
dstgather = 1;
|
||||
dstpos = bitpos[bitD];
|
||||
}
|
||||
|
||||
if (opcstr[pos] == '[')
|
||||
{
|
||||
pos++;
|
||||
|
||||
if (opcstr[pos] == '!')
|
||||
if (CPU_EMU_SIZE < 1
|
||||
&& (destmode == Areg || destmode == Dreg || destmode == Aind
|
||||
|| destmode == Ad16 || destmode == Ad8r || destmode == Aipi
|
||||
|| destmode == Apdi))
|
||||
{
|
||||
do
|
||||
{
|
||||
pos++;
|
||||
|
||||
if (mode_from_str(opcstr + pos) == destmode)
|
||||
goto nomatch;
|
||||
|
||||
pos += 4;
|
||||
}
|
||||
while (opcstr[pos] == ',');
|
||||
|
||||
pos++;
|
||||
dstgather = 1;
|
||||
dstpos = bitpos[bitS];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (opcstr[pos+4] == '-')
|
||||
{
|
||||
if (mode_from_str(opcstr + pos) == destmode)
|
||||
destmode = mode_from_str(opcstr + pos + 5);
|
||||
else
|
||||
goto nomatch;
|
||||
|
||||
pos += 10;
|
||||
if (opcstr[pos] == '[')
|
||||
{
|
||||
pos++;
|
||||
|
||||
if (opcstr[pos] == '!')
|
||||
{
|
||||
do
|
||||
{
|
||||
pos++;
|
||||
|
||||
if (mode_from_str(opcstr + pos) == destmode)
|
||||
goto nomatch;
|
||||
|
||||
pos += 4;
|
||||
}
|
||||
while (opcstr[pos] == ',');
|
||||
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(mode_from_str(opcstr + pos) != destmode)
|
||||
if (opcstr[pos+4] == '-')
|
||||
{
|
||||
pos += 4;
|
||||
|
||||
if (opcstr[pos] == ']')
|
||||
if (mode_from_str(opcstr + pos) == destmode)
|
||||
destmode = mode_from_str(opcstr + pos + 5);
|
||||
else
|
||||
goto nomatch;
|
||||
|
||||
pos++;
|
||||
pos += 10;
|
||||
}
|
||||
|
||||
while(opcstr[pos] != ']')
|
||||
pos++;
|
||||
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (destmode == imm || destmode == PC16 || destmode == PC8r)
|
||||
goto nomatch;
|
||||
|
||||
break;
|
||||
case 's':
|
||||
destreg = bitval[bitS];
|
||||
destmode = mode_from_mr(bitval[bits], bitval[bitS]);
|
||||
|
||||
if (destmode == am_illg)
|
||||
continue;
|
||||
if (CPU_EMU_SIZE < 1
|
||||
&& (destmode == Areg || destmode == Dreg || destmode == Aind
|
||||
|| destmode == Ad16 || destmode == Ad8r || destmode == Aipi
|
||||
|| destmode == Apdi))
|
||||
{
|
||||
dstgather = 1;
|
||||
dstpos = bitpos[bitS];
|
||||
}
|
||||
|
||||
if (opcstr[pos] == '[')
|
||||
{
|
||||
pos++;
|
||||
|
||||
if (opcstr[pos] == '!')
|
||||
{
|
||||
do
|
||||
{
|
||||
pos++;
|
||||
|
||||
if (mode_from_str(opcstr + pos) == destmode)
|
||||
goto nomatch;
|
||||
|
||||
pos += 4;
|
||||
}
|
||||
while (opcstr[pos] == ',');
|
||||
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (opcstr[pos+4] == '-')
|
||||
{
|
||||
if (mode_from_str(opcstr + pos) == destmode)
|
||||
destmode = mode_from_str(opcstr + pos + 5);
|
||||
else
|
||||
goto nomatch;
|
||||
|
||||
pos += 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (mode_from_str(opcstr + pos) != destmode)
|
||||
{
|
||||
pos += 4;
|
||||
while (mode_from_str(opcstr + pos) != destmode)
|
||||
{
|
||||
pos += 4;
|
||||
|
||||
if (opcstr[pos] == ']')
|
||||
goto nomatch;
|
||||
if (opcstr[pos] == ']')
|
||||
goto nomatch;
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
while (opcstr[pos] != ']')
|
||||
pos++;
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
while (opcstr[pos] != ']')
|
||||
pos++;
|
||||
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: abort();
|
||||
break;
|
||||
default: abort();
|
||||
}
|
||||
|
||||
if (destmode != Areg && destmode != Dreg && destmode != Aind
|
||||
|
@ -890,7 +885,6 @@ nomatch:
|
|||
void read_table68k(void)
|
||||
{
|
||||
int i;
|
||||
table68k = (struct instr *)malloc(65536 * sizeof(struct instr));
|
||||
|
||||
for(i=0; i<65536; i++)
|
||||
{
|
||||
|
@ -920,24 +914,24 @@ static void handle_merges(long int opcode)
|
|||
{
|
||||
switch (table68k[opcode].stype)
|
||||
{
|
||||
case 0:
|
||||
smsk = 7; sbitdst = 8; break;
|
||||
case 1:
|
||||
smsk = 255; sbitdst = 256; break;
|
||||
case 2:
|
||||
smsk = 15; sbitdst = 16; break;
|
||||
case 3:
|
||||
smsk = 7; sbitdst = 8; break;
|
||||
case 4:
|
||||
smsk = 7; sbitdst = 8; break;
|
||||
case 5:
|
||||
smsk = 63; sbitdst = 64; break;
|
||||
case 7:
|
||||
smsk = 3; sbitdst = 4; break;
|
||||
default:
|
||||
smsk = 0; sbitdst = 0;
|
||||
abort();
|
||||
break;
|
||||
case 0:
|
||||
smsk = 7; sbitdst = 8; break;
|
||||
case 1:
|
||||
smsk = 255; sbitdst = 256; break;
|
||||
case 2:
|
||||
smsk = 15; sbitdst = 16; break;
|
||||
case 3:
|
||||
smsk = 7; sbitdst = 8; break;
|
||||
case 4:
|
||||
smsk = 7; sbitdst = 8; break;
|
||||
case 5:
|
||||
smsk = 63; sbitdst = 64; break;
|
||||
case 7:
|
||||
smsk = 3; sbitdst = 4; break;
|
||||
default:
|
||||
smsk = 0; sbitdst = 0;
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
|
||||
smsk <<= table68k[opcode].spos;
|
||||
|
|
|
@ -87,7 +87,7 @@ struct instr_def {
|
|||
extern const struct instr_def defs68k[];
|
||||
extern int n_defs68k;
|
||||
|
||||
extern struct instr {
|
||||
struct instr {
|
||||
long int handler;
|
||||
unsigned char dreg;
|
||||
unsigned char sreg;
|
||||
|
@ -108,7 +108,9 @@ extern struct instr {
|
|||
unsigned int clev:3;
|
||||
unsigned int isjmp:1;
|
||||
unsigned int unused2:4;
|
||||
} *table68k;
|
||||
};
|
||||
|
||||
extern struct instr table68k[];
|
||||
|
||||
extern void read_table68k(void);
|
||||
extern void do_merges(void);
|
||||
|
|
|
@ -31,23 +31,22 @@ enum { MT_IDLE, MT_PHASE1, MT_PHASE2 };
|
|||
|
||||
uint8_t mtMem[0x20000];
|
||||
bool mtDirty;
|
||||
uint8_t mtCommand = MT_NONE;
|
||||
uint8_t mtState = MT_IDLE;
|
||||
static uint8_t mtCommand;
|
||||
static uint8_t mtState;
|
||||
|
||||
void MTStateMachine(uint8_t reg, uint16_t data);
|
||||
static void MTStateMachine(uint8_t reg, uint16_t data);
|
||||
|
||||
void MTInit(void)
|
||||
{
|
||||
memset(mtMem, 0xFF, 0x20000);
|
||||
mtDirty = false;
|
||||
MTReset();
|
||||
}
|
||||
|
||||
void MTReset(void)
|
||||
{
|
||||
}
|
||||
|
||||
void MTDone(void)
|
||||
{
|
||||
mtCommand = MT_NONE;
|
||||
mtState = MT_IDLE;
|
||||
}
|
||||
|
||||
uint16_t MTReadWord(uint32_t addr)
|
||||
|
@ -115,7 +114,7 @@ void MTWriteLong(uint32_t addr, uint32_t data)
|
|||
MTWriteWord(addr + 2, data >> 16);
|
||||
}
|
||||
|
||||
void MTStateMachine(uint8_t reg, uint16_t data)
|
||||
static void MTStateMachine(uint8_t reg, uint16_t data)
|
||||
{
|
||||
switch (mtState)
|
||||
{
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
void MTInit(void);
|
||||
void MTReset(void);
|
||||
void MTDone(void);
|
||||
|
||||
uint16_t MTReadWord(uint32_t addr);
|
||||
uint32_t MTReadLong(uint32_t addr);
|
||||
|
|
|
@ -38,12 +38,8 @@
|
|||
#define CONDITION_OP_FLAG_SET 3
|
||||
#define CONDITION_SECOND_HALF_LINE 4
|
||||
|
||||
// Private function prototypes
|
||||
|
||||
void OPProcessFixedBitmap(uint64_t p0, uint64_t p1, bool render);
|
||||
void OPProcessScaledBitmap(uint64_t p0, uint64_t p1, uint64_t p2, bool render);
|
||||
void OPDiscoverObjects(uint32_t address);
|
||||
uint64_t OPLoadPhrase(uint32_t offset);
|
||||
static void OPProcessFixedBitmap(uint64_t p0, uint64_t p1);
|
||||
static void OPProcessScaledBitmap(uint64_t p0, uint64_t p1, uint64_t p2);
|
||||
|
||||
// Local global variables
|
||||
|
||||
|
@ -108,13 +104,7 @@ void OPReset(void)
|
|||
static uint32_t object[8192];
|
||||
static uint32_t numberOfObjects;
|
||||
|
||||
void OPDone(void)
|
||||
{
|
||||
numberOfObjects = 0;
|
||||
OPDiscoverObjects(OPGetListPointer());
|
||||
}
|
||||
|
||||
bool OPObjectExists(uint32_t address)
|
||||
static bool OPObjectExists(uint32_t address)
|
||||
{
|
||||
for(uint32_t i=0; i<numberOfObjects; i++)
|
||||
{
|
||||
|
@ -125,7 +115,7 @@ bool OPObjectExists(uint32_t address)
|
|||
return false;
|
||||
}
|
||||
|
||||
void OPDiscoverObjects(uint32_t address)
|
||||
static void OPDiscoverObjects(uint32_t address)
|
||||
{
|
||||
uint8_t objectType = 0;
|
||||
|
||||
|
@ -152,23 +142,17 @@ void OPDiscoverObjects(uint32_t address)
|
|||
while (objectType != 4);
|
||||
}
|
||||
|
||||
uint32_t OPGetListPointer(void)
|
||||
static uint32_t OPGetListPointer(void)
|
||||
{
|
||||
return GET16(tomRam8, 0x20) | (GET16(tomRam8, 0x22) << 16);
|
||||
}
|
||||
|
||||
uint32_t OPGetStatusRegister(void)
|
||||
static uint32_t OPGetStatusRegister(void)
|
||||
{
|
||||
return GET16(tomRam8, 0x26);
|
||||
}
|
||||
|
||||
void OPSetStatusRegister(uint32_t data)
|
||||
{
|
||||
tomRam8[0x26] = (data & 0x0000FF00) >> 8;
|
||||
tomRam8[0x27] |= (data & 0xFE);
|
||||
}
|
||||
|
||||
void OPSetCurrentObject(uint64_t object)
|
||||
static void OPSetCurrentObject(uint64_t object)
|
||||
{
|
||||
tomRam8[0x17] = object & 0xFF; object >>= 8;
|
||||
tomRam8[0x16] = object & 0xFF; object >>= 8;
|
||||
|
@ -181,14 +165,13 @@ void OPSetCurrentObject(uint64_t object)
|
|||
tomRam8[0x10] = object & 0xFF;
|
||||
}
|
||||
|
||||
|
||||
uint64_t OPLoadPhrase(uint32_t offset)
|
||||
static uint64_t OPLoadPhrase(uint32_t offset)
|
||||
{
|
||||
offset &= ~0x07;
|
||||
return ((uint64_t)JaguarReadLong(offset, OP) << 32) | (uint64_t)JaguarReadLong(offset+4, OP);
|
||||
}
|
||||
|
||||
void OPStorePhrase(uint32_t offset, uint64_t p)
|
||||
static void OPStorePhrase(uint32_t offset, uint64_t p)
|
||||
{
|
||||
offset &= ~0x07;
|
||||
JaguarWriteLong(offset, p >> 32, OP);
|
||||
|
@ -198,7 +181,7 @@ void OPStorePhrase(uint32_t offset, uint64_t p)
|
|||
//
|
||||
// Object Processor main routine
|
||||
//
|
||||
void OPProcessList(int halfline, bool render)
|
||||
void OPProcessList(int halfline)
|
||||
{
|
||||
halfline &= 0x7FF;
|
||||
|
||||
|
@ -222,7 +205,7 @@ void OPProcessList(int halfline, bool render)
|
|||
if (halfline >= ypos && height > 0)
|
||||
{
|
||||
uint64_t p1 = OPLoadPhrase(oldOPP | 0x08);
|
||||
OPProcessFixedBitmap(p0, p1, render);
|
||||
OPProcessFixedBitmap(p0, p1);
|
||||
|
||||
height--;
|
||||
|
||||
|
@ -253,7 +236,7 @@ void OPProcessList(int halfline, bool render)
|
|||
{
|
||||
uint64_t p1 = OPLoadPhrase(oldOPP | 0x08);
|
||||
uint64_t p2 = OPLoadPhrase(oldOPP | 0x10);
|
||||
OPProcessScaledBitmap(p0, p1, p2, render);
|
||||
OPProcessScaledBitmap(p0, p1, p2);
|
||||
|
||||
uint16_t remainder = (p2 >> 16) & 0xFF;
|
||||
uint8_t vscale = p2 >> 8;
|
||||
|
@ -357,7 +340,7 @@ void OPProcessList(int halfline, bool render)
|
|||
//
|
||||
// Store fixed size bitmap in line buffer
|
||||
//
|
||||
void OPProcessFixedBitmap(uint64_t p0, uint64_t p1, bool render)
|
||||
static void OPProcessFixedBitmap(uint64_t p0, uint64_t p1)
|
||||
{
|
||||
uint8_t depth = (p1 >> 12) & 0x07;
|
||||
int32_t xpos = ((int16_t)((p1 << 4) & 0xFFFF)) >> 4;
|
||||
|
@ -375,14 +358,13 @@ void OPProcessFixedBitmap(uint64_t p0, uint64_t p1, bool render)
|
|||
uint32_t pitch = (p1 >> 15) & 0x07;
|
||||
pitch <<= 3;
|
||||
|
||||
uint8_t * tomRam8 = TOMGetRamPointer();
|
||||
uint8_t * paletteRAM = &tomRam8[0x400];
|
||||
uint16_t * paletteRAM16 = (uint16_t *)paletteRAM;
|
||||
|
||||
if (iwidth == 0)
|
||||
iwidth = 1;
|
||||
|
||||
if (!render || iwidth == 0)
|
||||
if (iwidth == 0)
|
||||
return;
|
||||
|
||||
int32_t startPos = xpos, endPos = xpos +
|
||||
|
@ -620,7 +602,7 @@ void OPProcessFixedBitmap(uint64_t p0, uint64_t p1, bool render)
|
|||
//
|
||||
// Store scaled bitmap in line buffer
|
||||
//
|
||||
void OPProcessScaledBitmap(uint64_t p0, uint64_t p1, uint64_t p2, bool render)
|
||||
static void OPProcessScaledBitmap(uint64_t p0, uint64_t p1, uint64_t p2)
|
||||
{
|
||||
uint8_t depth = (p1 >> 12) & 0x07;
|
||||
int32_t xpos = ((int16_t)((p1 << 4) & 0xFFFF)) >> 4;
|
||||
|
@ -636,7 +618,6 @@ void OPProcessScaledBitmap(uint64_t p0, uint64_t p1, uint64_t p2, bool render)
|
|||
uint8_t index = (p1 >> 37) & 0xFE;
|
||||
uint32_t pitch = (p1 >> 15) & 0x07;
|
||||
|
||||
uint8_t * tomRam8 = TOMGetRamPointer();
|
||||
uint8_t * paletteRAM = &tomRam8[0x400];
|
||||
uint16_t * paletteRAM16 = (uint16_t *)paletteRAM;
|
||||
|
||||
|
@ -645,7 +626,7 @@ void OPProcessScaledBitmap(uint64_t p0, uint64_t p1, uint64_t p2, bool render)
|
|||
int32_t scaledWidthInPixels = (iwidth * phraseWidthToPixels[depth] * hscale) >> 5;
|
||||
uint32_t scaledPhrasePixels = (phraseWidthToPixels[depth] * hscale) >> 5;
|
||||
|
||||
if (!render || iwidth == 0 || hscale == 0)
|
||||
if (iwidth == 0 || hscale == 0)
|
||||
return;
|
||||
|
||||
int32_t startPos = xpos, endPos = xpos +
|
||||
|
|
|
@ -11,21 +11,11 @@ void OPInit(void);
|
|||
void OPReset(void);
|
||||
void OPDone(void);
|
||||
|
||||
uint64_t OPLoadPhrase(uint32_t offset);
|
||||
|
||||
void OPProcessList(int scanline, bool render);
|
||||
uint32_t OPGetListPointer(void);
|
||||
void OPSetStatusRegister(uint32_t data);
|
||||
uint32_t OPGetStatusRegister(void);
|
||||
void OPSetCurrentObject(uint64_t object);
|
||||
void OPProcessList(int scanline);
|
||||
|
||||
#define OPFLAG_RELEASE 8 // Bus release bit
|
||||
#define OPFLAG_TRANS 4 // Transparency bit
|
||||
#define OPFLAG_RMW 2 // Read-Modify-Write bit
|
||||
#define OPFLAG_REFLECT 1 // Horizontal mirror bit
|
||||
|
||||
// Exported variables
|
||||
|
||||
extern uint8_t objectp_running;
|
||||
|
||||
#endif // __OBJECTP_H__
|
||||
|
|
|
@ -202,14 +202,20 @@ RISC_OPCODE(store_r14_indexed)
|
|||
{
|
||||
uint32_t address = risc_reg[14] + (risc_convert_zero[IMM_1] << 2);
|
||||
ALERT_UNALIGNED_LONG(address);
|
||||
RISCWriteLong(address & 0xFFFFFFFC, RN, RISC);
|
||||
if (IS_RISC_RAM(address))
|
||||
RISCWriteLong(address & 0xFFFFFFFC, RN, RISC);
|
||||
else
|
||||
RISCWriteLong(address, RN, RISC);
|
||||
}
|
||||
|
||||
RISC_OPCODE(store_r15_indexed)
|
||||
{
|
||||
uint32_t address = risc_reg[15] + (risc_convert_zero[IMM_1] << 2);
|
||||
ALERT_UNALIGNED_LONG(address);
|
||||
RISCWriteLong(address & 0xFFFFFFFC, RN, RISC);
|
||||
if (IS_RISC_RAM(address))
|
||||
RISCWriteLong(address & 0xFFFFFFFC, RN, RISC);
|
||||
else
|
||||
RISCWriteLong(address, RN, RISC);
|
||||
}
|
||||
|
||||
RISC_OPCODE(load_r14_ri)
|
||||
|
@ -230,14 +236,20 @@ RISC_OPCODE(store_r14_ri)
|
|||
{
|
||||
uint32_t address = risc_reg[14] + RM;
|
||||
ALERT_UNALIGNED_LONG(address);
|
||||
RISCWriteLong(address & 0xFFFFFFFC, RN, RISC);
|
||||
if (IS_RISC_RAM(address))
|
||||
RISCWriteLong(address & 0xFFFFFFFC, RN, RISC);
|
||||
else
|
||||
RISCWriteLong(address, RN, RISC);
|
||||
}
|
||||
|
||||
RISC_OPCODE(store_r15_ri)
|
||||
{
|
||||
uint32_t address = risc_reg[15] + RM;
|
||||
ALERT_UNALIGNED_LONG(address);
|
||||
RISCWriteLong(address & 0xFFFFFFFC, RN, RISC);
|
||||
if (IS_RISC_RAM(address))
|
||||
RISCWriteLong(address & 0xFFFFFFFC, RN, RISC);
|
||||
else
|
||||
RISCWriteLong(address, RN, RISC);
|
||||
}
|
||||
|
||||
RISC_OPCODE(nop)
|
||||
|
@ -259,13 +271,16 @@ RISC_OPCODE(storew)
|
|||
if (IS_RISC_RAM(RM))
|
||||
RISCWriteLong(RM & 0xFFFFFFFC, RN, RISC);
|
||||
else
|
||||
JaguarWriteWord(RM & 0xFFFFFFFE, RN, RISC);
|
||||
JaguarWriteWord(RM, RN, RISC);
|
||||
}
|
||||
|
||||
RISC_OPCODE(store)
|
||||
{
|
||||
ALERT_UNALIGNED_LONG(RM);
|
||||
RISCWriteLong(RM & 0xFFFFFFFC, RN, RISC);
|
||||
if (IS_RISC_RAM(RM))
|
||||
RISCWriteLong(RM & 0xFFFFFFFC, RN, RISC);
|
||||
else
|
||||
RISCWriteLong(RM, RN, RISC);
|
||||
}
|
||||
|
||||
RISC_OPCODE(loadb)
|
||||
|
@ -283,7 +298,7 @@ RISC_OPCODE(loadw)
|
|||
if (IS_RISC_RAM(RM))
|
||||
RN = RISCReadLong(RM & 0xFFFFFFFC, RISC);
|
||||
else
|
||||
RN = JaguarReadWord(RM & 0xFFFFFFFE, RISC);
|
||||
RN = JaguarReadWord(RM, RISC);
|
||||
}
|
||||
|
||||
RISC_OPCODE(load)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//
|
||||
// FILE.CPP
|
||||
// ROM.CPP
|
||||
//
|
||||
// File support
|
||||
// ROM support
|
||||
// by James Hammons
|
||||
// (C) 2010 Underground Software
|
||||
//
|
||||
|
@ -15,7 +15,7 @@
|
|||
// JLH 06/01/2012 Added function to check ZIP file CRCs against file DB
|
||||
//
|
||||
|
||||
#include "file.h"
|
||||
#include "rom.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
@ -24,7 +24,7 @@
|
|||
#include "jaguar.h"
|
||||
#include "memory.h"
|
||||
|
||||
bool JaguarLoadFile(uint8_t * buffer, uint32_t size)
|
||||
bool JaguarLoadROM(uint8_t * buffer, uint32_t size)
|
||||
{
|
||||
jaguarROMSize = size;
|
||||
|
||||
|
@ -32,7 +32,7 @@ bool JaguarLoadFile(uint8_t * buffer, uint32_t size)
|
|||
|
||||
EepromInit();
|
||||
jaguarRunAddress = 0x802000;
|
||||
int fileType = ParseFileType(buffer, jaguarROMSize);
|
||||
int fileType = ParseROMType(buffer, jaguarROMSize);
|
||||
jaguarCartInserted = false;
|
||||
|
||||
if (fileType == JST_ROM)
|
||||
|
@ -92,7 +92,7 @@ bool JaguarLoadFile(uint8_t * buffer, uint32_t size)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool AlpineLoadFile(uint8_t * buffer, uint32_t size)
|
||||
bool AlpineLoadROM(uint8_t * buffer, uint32_t size)
|
||||
{
|
||||
jaguarROMSize = size;
|
||||
|
||||
|
@ -110,7 +110,7 @@ bool AlpineLoadFile(uint8_t * buffer, uint32_t size)
|
|||
return true;
|
||||
}
|
||||
|
||||
uint32_t ParseFileType(uint8_t * buffer, uint32_t size)
|
||||
uint32_t ParseROMType(uint8_t * buffer, uint32_t size)
|
||||
{
|
||||
if (buffer[0] == 0x60 && buffer[1] == 0x1B)
|
||||
return JST_ABS_TYPE1;
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// ROM.H
|
||||
//
|
||||
// ROM support
|
||||
//
|
||||
|
||||
#ifndef __ROM_H__
|
||||
#define __ROM_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// JST = Jaguar Software Type
|
||||
enum { JST_NONE = 0, JST_ROM, JST_ALPINE, JST_ABS_TYPE1, JST_ABS_TYPE2, JST_JAGSERVER, JST_WTFOMGBBQ };
|
||||
|
||||
bool JaguarLoadROM(uint8_t * buffer, uint32_t size);
|
||||
bool AlpineLoadROM(uint8_t * buffer, uint32_t size);
|
||||
uint32_t ParseROMType(uint8_t * buffer, uint32_t size);
|
||||
|
||||
#endif // __ROM_H__
|
|
@ -79,11 +79,11 @@
|
|||
#define BOTTOM_VISIBLE_VC_PAL 579
|
||||
|
||||
uint8_t tomRam8[0x4000];
|
||||
uint32_t tomWidth, tomHeight;
|
||||
uint32_t tomTimerPrescaler;
|
||||
uint32_t tomTimerDivider;
|
||||
int32_t tomTimerCounter;
|
||||
uint16_t tom_jerry_int_pending, tom_timer_int_pending, tom_object_int_pending,
|
||||
static uint32_t tomWidth, tomHeight;
|
||||
static uint32_t tomTimerPrescaler;
|
||||
static uint32_t tomTimerDivider;
|
||||
static int32_t tomTimerCounter;
|
||||
static uint16_t tom_jerry_int_pending, tom_timer_int_pending, tom_object_int_pending,
|
||||
tom_gpu_int_pending, tom_video_int_pending;
|
||||
|
||||
static uint32_t * scanlines[256];
|
||||
|
@ -91,15 +91,13 @@ static uint32_t scanlineWidths[256];
|
|||
|
||||
typedef void (render_xxx_scanline_fn)(uint32_t *);
|
||||
|
||||
// Private function prototypes
|
||||
static void tom_render_16bpp_cry_scanline(uint32_t * backbuffer);
|
||||
static void tom_render_24bpp_scanline(uint32_t * backbuffer);
|
||||
static void tom_render_16bpp_direct_scanline(uint32_t * backbuffer);
|
||||
static void tom_render_16bpp_rgb_scanline(uint32_t * backbuffer);
|
||||
static void tom_render_16bpp_cry_rgb_mix_scanline(uint32_t * backbuffer);
|
||||
|
||||
void tom_render_16bpp_cry_scanline(uint32_t * backbuffer);
|
||||
void tom_render_24bpp_scanline(uint32_t * backbuffer);
|
||||
void tom_render_16bpp_direct_scanline(uint32_t * backbuffer);
|
||||
void tom_render_16bpp_rgb_scanline(uint32_t * backbuffer);
|
||||
void tom_render_16bpp_cry_rgb_mix_scanline(uint32_t * backbuffer);
|
||||
|
||||
render_xxx_scanline_fn * scanline_render[] =
|
||||
static render_xxx_scanline_fn * scanline_render[] =
|
||||
{
|
||||
tom_render_16bpp_cry_scanline,
|
||||
tom_render_24bpp_scanline,
|
||||
|
@ -111,11 +109,13 @@ render_xxx_scanline_fn * scanline_render[] =
|
|||
tom_render_16bpp_rgb_scanline
|
||||
};
|
||||
|
||||
static void TOMResetPIT(void);
|
||||
|
||||
static uint32_t RGB16ToRGB32[0x10000];
|
||||
static uint32_t CRY16ToRGB32[0x10000];
|
||||
static uint32_t MIX16ToRGB32[0x10000];
|
||||
|
||||
void TOMFillLookupTables(void)
|
||||
static void TOMFillLookupTables(void)
|
||||
{
|
||||
for(uint32_t i=0; i<0x10000; i++)
|
||||
RGB16ToRGB32[i] =
|
||||
|
@ -138,12 +138,7 @@ void TOMFillLookupTables(void)
|
|||
}
|
||||
}
|
||||
|
||||
void TOMSetPendingJERRYInt(void)
|
||||
{
|
||||
tom_jerry_int_pending = 1;
|
||||
}
|
||||
|
||||
void TOMSetPendingTimerInt(void)
|
||||
static void TOMSetPendingTimerInt(void)
|
||||
{
|
||||
tom_timer_int_pending = 1;
|
||||
}
|
||||
|
@ -163,32 +158,17 @@ void TOMSetPendingVideoInt(void)
|
|||
tom_video_int_pending = 1;
|
||||
}
|
||||
|
||||
uint8_t * TOMGetRamPointer(void)
|
||||
{
|
||||
return tomRam8;
|
||||
}
|
||||
|
||||
uint8_t TOMGetVideoMode(void)
|
||||
static uint8_t TOMGetVideoMode(void)
|
||||
{
|
||||
uint16_t vmode = GET16(tomRam8, VMODE);
|
||||
return ((vmode & VARMOD) >> 6) | ((vmode & MODE) >> 1);
|
||||
}
|
||||
|
||||
uint16_t TOMGetVDB(void)
|
||||
{
|
||||
return GET16(tomRam8, VDB);
|
||||
}
|
||||
|
||||
uint16_t TOMGetHC(void)
|
||||
{
|
||||
return GET16(tomRam8, HC);
|
||||
}
|
||||
|
||||
uint16_t TOMGetVP(void)
|
||||
{
|
||||
return GET16(tomRam8, VP);
|
||||
}
|
||||
|
||||
uint16_t TOMGetMEMCON1(void)
|
||||
{
|
||||
return GET16(tomRam8, MEMCON1);
|
||||
|
@ -197,7 +177,7 @@ uint16_t TOMGetMEMCON1(void)
|
|||
//
|
||||
// 16 BPP CRY/RGB mixed mode rendering
|
||||
//
|
||||
void tom_render_16bpp_cry_rgb_mix_scanline(uint32_t * backbuffer)
|
||||
static void tom_render_16bpp_cry_rgb_mix_scanline(uint32_t * backbuffer)
|
||||
{
|
||||
uint16_t width = tomWidth;
|
||||
uint8_t * current_line_buffer = (uint8_t *)&tomRam8[0x1800];
|
||||
|
@ -232,7 +212,7 @@ void tom_render_16bpp_cry_rgb_mix_scanline(uint32_t * backbuffer)
|
|||
//
|
||||
// 16 BPP CRY mode rendering
|
||||
//
|
||||
void tom_render_16bpp_cry_scanline(uint32_t * backbuffer)
|
||||
static void tom_render_16bpp_cry_scanline(uint32_t * backbuffer)
|
||||
{
|
||||
uint16_t width = tomWidth;
|
||||
uint8_t * current_line_buffer = (uint8_t *)&tomRam8[0x1800];
|
||||
|
@ -267,7 +247,7 @@ void tom_render_16bpp_cry_scanline(uint32_t * backbuffer)
|
|||
//
|
||||
// 24 BPP mode rendering
|
||||
//
|
||||
void tom_render_24bpp_scanline(uint32_t * backbuffer)
|
||||
static void tom_render_24bpp_scanline(uint32_t * backbuffer)
|
||||
{
|
||||
uint16_t width = tomWidth;
|
||||
uint8_t * current_line_buffer = (uint8_t *)&tomRam8[0x1800];
|
||||
|
@ -304,7 +284,7 @@ void tom_render_24bpp_scanline(uint32_t * backbuffer)
|
|||
//
|
||||
// 16 BPP direct mode rendering
|
||||
//
|
||||
void tom_render_16bpp_direct_scanline(uint32_t * backbuffer)
|
||||
static void tom_render_16bpp_direct_scanline(uint32_t * backbuffer)
|
||||
{
|
||||
uint16_t width = tomWidth;
|
||||
uint8_t * current_line_buffer = (uint8_t *)&tomRam8[0x1800];
|
||||
|
@ -321,7 +301,7 @@ void tom_render_16bpp_direct_scanline(uint32_t * backbuffer)
|
|||
//
|
||||
// 16 BPP RGB mode rendering
|
||||
//
|
||||
void tom_render_16bpp_rgb_scanline(uint32_t * backbuffer)
|
||||
static void tom_render_16bpp_rgb_scanline(uint32_t * backbuffer)
|
||||
{
|
||||
uint16_t width = tomWidth;
|
||||
uint8_t * current_line_buffer = (uint8_t *)&tomRam8[0x1800];
|
||||
|
@ -356,7 +336,7 @@ void tom_render_16bpp_rgb_scanline(uint32_t * backbuffer)
|
|||
//
|
||||
// Process a single halfline
|
||||
//
|
||||
void TOMExecHalfline(uint16_t halfline, bool render)
|
||||
void TOMExecHalfline(uint16_t halfline)
|
||||
{
|
||||
uint16_t field2 = halfline & 0x0800;
|
||||
halfline &= 0x07FF;
|
||||
|
@ -373,17 +353,14 @@ void TOMExecHalfline(uint16_t halfline, bool render)
|
|||
|
||||
if ((halfline >= startingHalfline) && (halfline < endingHalfline))
|
||||
{
|
||||
if (render)
|
||||
{
|
||||
uint8_t * current_line_buffer = (uint8_t *)&tomRam8[0x1800];
|
||||
uint8_t bgHI = tomRam8[BG], bgLO = tomRam8[BG + 1];
|
||||
uint8_t * current_line_buffer = (uint8_t *)&tomRam8[0x1800];
|
||||
uint8_t bgHI = tomRam8[BG], bgLO = tomRam8[BG + 1];
|
||||
|
||||
if (GET16(tomRam8, VMODE) & BGEN)
|
||||
for(uint32_t i=0; i<720; i++)
|
||||
*current_line_buffer++ = bgHI, *current_line_buffer++ = bgLO;
|
||||
if (GET16(tomRam8, VMODE) & BGEN)
|
||||
for(uint32_t i=0; i<720; i++)
|
||||
*current_line_buffer++ = bgHI, *current_line_buffer++ = bgLO;
|
||||
|
||||
OPProcessList(halfline, render);
|
||||
}
|
||||
OPProcessList(halfline);
|
||||
}
|
||||
else
|
||||
inActiveDisplayArea = false;
|
||||
|
@ -424,7 +401,7 @@ void TOMInit(void)
|
|||
{
|
||||
for (uint32_t i = 0; i < 256; i++)
|
||||
{
|
||||
scanlines[i] = alloc_invisible<uint32_t>(LCM_SCREEN_WIDTH);
|
||||
scanlines[i] = alloc_invisible<uint32_t>(MAX_SCREEN_WIDTH);
|
||||
}
|
||||
|
||||
TOMFillLookupTables();
|
||||
|
@ -433,19 +410,13 @@ void TOMInit(void)
|
|||
TOMReset();
|
||||
}
|
||||
|
||||
void TOMDone(void)
|
||||
{
|
||||
OPDone();
|
||||
BlitterDone();
|
||||
}
|
||||
|
||||
uint32_t TOMGetVideoModeWidth(void)
|
||||
static uint32_t TOMGetVideoModeWidth(void)
|
||||
{
|
||||
uint16_t pwidth = ((GET16(tomRam8, VMODE) & PWIDTH) >> 9) + 1;
|
||||
return LCM_SCREEN_WIDTH / pwidth;
|
||||
return MAX_SCREEN_WIDTH / pwidth;
|
||||
}
|
||||
|
||||
uint32_t TOMGetVideoModeHeight(void)
|
||||
static uint32_t TOMGetVideoModeHeight(void)
|
||||
{
|
||||
return (vjs.hardwareTypeNTSC ? 240 : 256);
|
||||
}
|
||||
|
@ -561,6 +532,23 @@ uint16_t TOMReadWord(uint32_t offset, uint32_t who)
|
|||
return (TOMReadByte(offset, who) << 8) | TOMReadByte(offset + 1, who);
|
||||
}
|
||||
|
||||
#define MASK(x) 0xFF00 >> (24 - x), 0xFF
|
||||
static const uint8_t videoRegMasks[22]
|
||||
{
|
||||
MASK(12), // 0x28 VMODE 11 - 0
|
||||
MASK(16), // 0x2A BORDH 15 - 0
|
||||
MASK(16), // 0x2C BORDL 15 - 0
|
||||
MASK(10), // 0x2E HP 9 - 0
|
||||
MASK(11), // 0x30 HBB 10 - 0
|
||||
MASK(11), // 0x32 HBE 10 - 0
|
||||
MASK(11), // 0x34 HS 10 - 0
|
||||
MASK(11), // 0x36 HVE 10 - 0
|
||||
MASK(11), // 0x38 HDB1 10 - 0
|
||||
MASK(11), // 0x3A HDB2 10 - 0
|
||||
MASK(11), // 0x3C HDE 10 - 0
|
||||
};
|
||||
#undef MASK
|
||||
|
||||
//
|
||||
// TOM byte access (write)
|
||||
//
|
||||
|
@ -572,8 +560,6 @@ void TOMWriteByte(uint32_t offset, uint8_t data, uint32_t who)
|
|||
if ((offset < 0xF00000) || (offset > 0xF03FFF))
|
||||
return;
|
||||
|
||||
tomRam8[offset & 0x3FFF] = data;
|
||||
|
||||
if ((offset >= GPU_CONTROL_RAM_BASE) && (offset < GPU_CONTROL_RAM_BASE+0x20))
|
||||
{
|
||||
GPUWriteByte(offset, data, who);
|
||||
|
@ -595,7 +581,6 @@ void TOMWriteByte(uint32_t offset, uint8_t data, uint32_t who)
|
|||
{
|
||||
tomTimerPrescaler = (tomTimerPrescaler & 0xFF00) | data;
|
||||
TOMResetPIT();
|
||||
return;
|
||||
}
|
||||
else if (offset == 0xF00052)
|
||||
{
|
||||
|
@ -611,7 +596,17 @@ void TOMWriteByte(uint32_t offset, uint8_t data, uint32_t who)
|
|||
{
|
||||
offset &= 0x5FF;
|
||||
tomRam8[offset] = data, tomRam8[offset + 0x200] = data;
|
||||
return;
|
||||
}
|
||||
|
||||
offset &= 0x3FFF;
|
||||
|
||||
if (offset == 0x54)
|
||||
data &= 0x03;
|
||||
else if (offset >= 0x28 && offset <= 0x3D)
|
||||
data &= videoRegMasks[offset - 0x28];
|
||||
|
||||
tomRam8[offset] = data;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -625,30 +620,23 @@ void TOMWriteWord(uint32_t offset, uint16_t data, uint32_t who)
|
|||
if ((offset < 0xF00000) || (offset > 0xF03FFF))
|
||||
return;
|
||||
|
||||
tomRam8[(offset + 0) & 0x3FFF] = data >> 8;
|
||||
tomRam8[(offset + 1) & 0x3FFF] = data & 0xFF;
|
||||
|
||||
if ((offset >= GPU_CONTROL_RAM_BASE) && (offset < GPU_CONTROL_RAM_BASE+0x20))
|
||||
{
|
||||
GPUWriteWord(offset, data, who);
|
||||
return;
|
||||
}
|
||||
else if ((offset >= GPU_WORK_RAM_BASE) && (offset < GPU_WORK_RAM_BASE+0x1000))
|
||||
{
|
||||
GPUWriteWord(offset, data, who);
|
||||
return;
|
||||
}
|
||||
else if (offset == 0xF00050)
|
||||
{
|
||||
tomTimerPrescaler = data;
|
||||
TOMResetPIT();
|
||||
return;
|
||||
}
|
||||
else if (offset == 0xF00052)
|
||||
{
|
||||
tomTimerDivider = data;
|
||||
TOMResetPIT();
|
||||
return;
|
||||
}
|
||||
else if (offset == 0xF000E0)
|
||||
{
|
||||
|
@ -666,21 +654,24 @@ void TOMWriteWord(uint32_t offset, uint16_t data, uint32_t who)
|
|||
else if ((offset >= 0xF02200) && (offset <= 0xF0229F))
|
||||
{
|
||||
BlitterWriteWord(offset, data, who);
|
||||
return;
|
||||
}
|
||||
else if (offset >= 0xF00400 && offset <= 0xF007FE)
|
||||
{
|
||||
offset &= 0x5FF;
|
||||
SET16(tomRam8, offset, data);
|
||||
SET16(tomRam8, offset + 0x200, data);
|
||||
return;
|
||||
}
|
||||
|
||||
offset &= 0x3FFF;
|
||||
|
||||
if (offset >= 0x30 && offset <= 0x4E)
|
||||
data &= 0x07FF;
|
||||
if (offset == 0x2E || offset == 0x36 || offset == 0x54)
|
||||
if (offset == 0x54)
|
||||
data &= 0x03FF;
|
||||
else if (offset >= 0x28 && offset <= 0x3C)
|
||||
data &= (videoRegMasks[offset - 0x28] << 8) | videoRegMasks[offset - 0x27];
|
||||
|
||||
tomRam8[(offset + 0) & 0x3FFF] = data >> 8;
|
||||
tomRam8[(offset + 1) & 0x3FFF] = data & 0xFF;
|
||||
|
||||
if ((offset >= 0x28) && (offset <= 0x4F))
|
||||
{
|
||||
|
@ -698,9 +689,9 @@ int TOMIRQEnabled(int irq)
|
|||
return tomRam8[INT1 + 1] & (1 << irq);
|
||||
}
|
||||
|
||||
void TOMPITCallback(void);
|
||||
static void TOMPITCallback(void);
|
||||
|
||||
void TOMResetPIT(void)
|
||||
static void TOMResetPIT(void)
|
||||
{
|
||||
RemoveCallback(TOMPITCallback);
|
||||
|
||||
|
@ -711,26 +702,7 @@ void TOMResetPIT(void)
|
|||
}
|
||||
}
|
||||
|
||||
void TOMExecPIT(uint32_t cycles)
|
||||
{
|
||||
if (tomTimerPrescaler)
|
||||
{
|
||||
tomTimerCounter -= cycles;
|
||||
|
||||
if (tomTimerCounter <= 0)
|
||||
{
|
||||
TOMSetPendingTimerInt();
|
||||
GPUSetIRQLine(GPUIRQ_TIMER, ASSERT_LINE);
|
||||
|
||||
if (TOMIRQEnabled(IRQ_TIMER))
|
||||
m68k_set_irq(2);
|
||||
|
||||
TOMResetPIT();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TOMPITCallback(void)
|
||||
static void TOMPITCallback(void)
|
||||
{
|
||||
TOMSetPendingTimerInt();
|
||||
GPUSetIRQLine(GPUIRQ_TIMER, ASSERT_LINE);
|
||||
|
@ -748,17 +720,16 @@ void TOMStartFrame(void)
|
|||
|
||||
void TOMBlit(uint32_t * videoBuffer, int32_t & width, int32_t & height)
|
||||
{
|
||||
uint32_t lines = vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL;
|
||||
uint32_t const lines = vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL;
|
||||
uint32_t targetWidth = scanlineWidths[0];
|
||||
bool multiWidth = false;
|
||||
|
||||
for (uint32_t i = 1; i < lines; i++)
|
||||
{
|
||||
if (targetWidth < scanlineWidths[i])
|
||||
{
|
||||
targetWidth = scanlineWidths[i];
|
||||
multiWidth = true;
|
||||
}
|
||||
uint32_t const w = scanlineWidths[i];
|
||||
multiWidth |= targetWidth != w;
|
||||
if (targetWidth < w)
|
||||
targetWidth = w;
|
||||
}
|
||||
|
||||
if (!targetWidth) // skip rendering this I guess?
|
||||
|
@ -768,21 +739,21 @@ void TOMBlit(uint32_t * videoBuffer, int32_t & width, int32_t & height)
|
|||
return;
|
||||
}
|
||||
|
||||
if (__builtin_expect(multiWidth, false))
|
||||
if (multiWidth)
|
||||
{
|
||||
for (uint32_t i = 0; i < lines; i++)
|
||||
{
|
||||
uint32_t const w = scanlineWidths[i];
|
||||
if (__builtin_expect(LCM_SCREEN_WIDTH == w, false))
|
||||
if (__builtin_expect(MAX_SCREEN_WIDTH == w, false))
|
||||
{
|
||||
memcpy(videoBuffer, scanlines[i], LCM_SCREEN_WIDTH * sizeof(uint32_t));
|
||||
videoBuffer += LCM_SCREEN_WIDTH;
|
||||
memcpy(videoBuffer, scanlines[i], MAX_SCREEN_WIDTH * sizeof(uint32_t));
|
||||
videoBuffer += MAX_SCREEN_WIDTH;
|
||||
}
|
||||
else if (__builtin_expect(w > 0, true))
|
||||
{
|
||||
uint32_t wf = LCM_SCREEN_WIDTH / w;
|
||||
uint32_t const wf = MAX_SCREEN_WIDTH / w;
|
||||
uint32_t * src = scanlines[i];
|
||||
uint32_t * dstNext = videoBuffer + LCM_SCREEN_WIDTH;
|
||||
uint32_t const * const dstNext = videoBuffer + MAX_SCREEN_WIDTH;
|
||||
for (uint32_t x = 0; x < w; x++)
|
||||
{
|
||||
for (uint32_t n = 0; n < wf; n++)
|
||||
|
@ -794,7 +765,7 @@ void TOMBlit(uint32_t * videoBuffer, int32_t & width, int32_t & height)
|
|||
}
|
||||
else
|
||||
{
|
||||
videoBuffer += LCM_SCREEN_WIDTH; // skip rendering this line
|
||||
videoBuffer += MAX_SCREEN_WIDTH; // skip rendering this line
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -807,6 +778,6 @@ void TOMBlit(uint32_t * videoBuffer, int32_t & width, int32_t & height)
|
|||
}
|
||||
}
|
||||
|
||||
width = multiWidth ? LCM_SCREEN_WIDTH : targetWidth;
|
||||
width = multiWidth ? MAX_SCREEN_WIDTH : targetWidth;
|
||||
height = lines;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#define VIRTUAL_SCREEN_HEIGHT_NTSC 240
|
||||
#define VIRTUAL_SCREEN_HEIGHT_PAL 256
|
||||
|
||||
#define LCM_SCREEN_WIDTH (VIRTUAL_SCREEN_WIDTH * 4)
|
||||
#define MAX_SCREEN_WIDTH (VIRTUAL_SCREEN_WIDTH * 4)
|
||||
|
||||
// 68000 Interrupt bit positions (enabled at $F000E0)
|
||||
|
||||
|
@ -24,47 +24,24 @@ enum { IRQ_VIDEO = 0, IRQ_GPU, IRQ_OPFLAG, IRQ_TIMER, IRQ_DSP };
|
|||
|
||||
void TOMInit(void);
|
||||
void TOMReset(void);
|
||||
void TOMDone(void);
|
||||
|
||||
uint8_t TOMReadByte(uint32_t offset, uint32_t who = UNKNOWN);
|
||||
uint16_t TOMReadWord(uint32_t offset, uint32_t who = UNKNOWN);
|
||||
void TOMWriteByte(uint32_t offset, uint8_t data, uint32_t who = UNKNOWN);
|
||||
void TOMWriteWord(uint32_t offset, uint16_t data, uint32_t who = UNKNOWN);
|
||||
|
||||
void TOMExecHalfline(uint16_t halfline, bool render);
|
||||
uint32_t TOMGetVideoModeWidth(void);
|
||||
uint32_t TOMGetVideoModeHeight(void);
|
||||
uint8_t TOMGetVideoMode(void);
|
||||
uint8_t * TOMGetRamPointer(void);
|
||||
uint16_t TOMGetHDB(void);
|
||||
uint16_t TOMGetVDB(void);
|
||||
void TOMExecHalfline(uint16_t halfline);
|
||||
uint16_t TOMGetHC(void);
|
||||
uint16_t TOMGetVP(void);
|
||||
uint16_t TOMGetMEMCON1(void);
|
||||
void TOMDumpIORegistersToLog(void);
|
||||
|
||||
|
||||
int TOMIRQEnabled(int irq);
|
||||
uint16_t TOMIRQControlReg(void);
|
||||
void TOMSetIRQLatch(int irq, int enabled);
|
||||
void TOMExecPIT(uint32_t cycles);
|
||||
void TOMSetPendingJERRYInt(void);
|
||||
void TOMSetPendingTimerInt(void);
|
||||
void TOMSetPendingObjectInt(void);
|
||||
void TOMSetPendingGPUInt(void);
|
||||
void TOMSetPendingVideoInt(void);
|
||||
void TOMResetPIT(void);
|
||||
|
||||
void TOMStartFrame(void);
|
||||
void TOMBlit(uint32_t * framebuffer, int32_t & width, int32_t & height);
|
||||
|
||||
// Exported variables
|
||||
|
||||
extern uint32_t tomWidth;
|
||||
extern uint32_t tomHeight;
|
||||
extern uint8_t tomRam8[];
|
||||
extern uint32_t tomTimerPrescaler;
|
||||
extern uint32_t tomTimerDivider;
|
||||
extern int32_t tomTimerCounter;
|
||||
|
||||
#endif // __TOM_H__
|
||||
|
|
Loading…
Reference in New Issue