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:
CasualPokePlayer 2022-10-02 06:48:14 -07:00
parent 2e5c62f632
commit 71f2676ad8
43 changed files with 881 additions and 1952 deletions

Binary file not shown.

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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)
{

View File

@ -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__

View File

@ -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));
}
}

View File

@ -5,7 +5,6 @@
void CDHLEInit(void);
void CDHLEReset(void);
void CDHLEDone(void);
void CDHLEHook(uint32_t which);
bool CDHLEJerryCallback(void);

View File

@ -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;
}

View File

@ -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__

View File

@ -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];
}

View File

@ -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__

View File

@ -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;

View File

@ -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__

View File

@ -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

View File

@ -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);
}
//

View File

@ -9,7 +9,7 @@
void DACInit(void);
void DACReset(void);
void DACDone(void);
uint32_t DACResetBuffer(void * buffer);
// DAC memory access

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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)();
}

View File

@ -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__

View File

@ -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__

View File

@ -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
//

View File

@ -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)

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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[];

View File

@ -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;

View File

@ -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);

View File

@ -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)
{

View File

@ -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);

View File

@ -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 +

View File

@ -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__

View File

@ -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)

View File

@ -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;

View File

@ -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__

View File

@ -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;
}

View File

@ -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__