diff --git a/Assets/dll/virtualjaguar.wbx.zst b/Assets/dll/virtualjaguar.wbx.zst index fe983b615d..2be905d702 100644 Binary files a/Assets/dll/virtualjaguar.wbx.zst and b/Assets/dll/virtualjaguar.wbx.zst differ diff --git a/waterbox/virtualjaguar/BizInterface.cpp b/waterbox/virtualjaguar/BizInterface.cpp index 34faefb30b..90a4ac5827 100644 --- a/waterbox/virtualjaguar/BizInterface.cpp +++ b/waterbox/virtualjaguar/BizInterface.cpp @@ -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 #include @@ -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(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(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; } diff --git a/waterbox/virtualjaguar/blip_buf.c b/waterbox/virtualjaguar/blip_buf.c deleted file mode 100644 index 362eede49a..0000000000 --- a/waterbox/virtualjaguar/blip_buf.c +++ /dev/null @@ -1,344 +0,0 @@ -/* blip_buf 1.1.0. http://www.slack.net/~ant/ */ - -#include "blip_buf.h" - -#include -#include -#include -#include - -/* 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; -} diff --git a/waterbox/virtualjaguar/blip_buf.h b/waterbox/virtualjaguar/blip_buf.h deleted file mode 100644 index 52703643c4..0000000000 --- a/waterbox/virtualjaguar/blip_buf.h +++ /dev/null @@ -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 diff --git a/waterbox/virtualjaguar/src/blitter.cpp b/waterbox/virtualjaguar/src/blitter.cpp index 4b22b51d59..0d8026d15b 100644 --- a/waterbox/virtualjaguar/src/blitter.cpp +++ b/waterbox/virtualjaguar/src/blitter.cpp @@ -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) { diff --git a/waterbox/virtualjaguar/src/blitter.h b/waterbox/virtualjaguar/src/blitter.h index 7ccc23da39..29b8c906ce 100644 --- a/waterbox/virtualjaguar/src/blitter.h +++ b/waterbox/virtualjaguar/src/blitter.h @@ -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__ diff --git a/waterbox/virtualjaguar/src/cdhle.cpp b/waterbox/virtualjaguar/src/cdhle.cpp index 4593ec8211..0028dd794d 100644 --- a/waterbox/virtualjaguar/src/cdhle.cpp +++ b/waterbox/virtualjaguar/src/cdhle.cpp @@ -7,6 +7,7 @@ #include "dac.h" #include "dsp.h" #include "event.h" +#include "settings.h" #include "m68000/m68kinterface.h" #include @@ -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)); } } diff --git a/waterbox/virtualjaguar/src/cdhle.h b/waterbox/virtualjaguar/src/cdhle.h index fea516e24b..55b5699f21 100644 --- a/waterbox/virtualjaguar/src/cdhle.h +++ b/waterbox/virtualjaguar/src/cdhle.h @@ -5,7 +5,6 @@ void CDHLEInit(void); void CDHLEReset(void); -void CDHLEDone(void); void CDHLEHook(uint32_t which); bool CDHLEJerryCallback(void); diff --git a/waterbox/virtualjaguar/src/cdintf.cpp b/waterbox/virtualjaguar/src/cdintf.cpp deleted file mode 100644 index 300eb5aa3d..0000000000 --- a/waterbox/virtualjaguar/src/cdintf.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// -// OS agnostic CDROM interface functions -// -// by James Hammons -// (C) 2010 Underground Software -// -// JLH = James Hammons -// -// 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; -} diff --git a/waterbox/virtualjaguar/src/cdintf.h b/waterbox/virtualjaguar/src/cdintf.h deleted file mode 100644 index ebce8fa929..0000000000 --- a/waterbox/virtualjaguar/src/cdintf.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// CDINTF.H: OS agnostic CDROM access funcions -// -// by James Hammons -// - -#ifndef __CDINTF_H__ -#define __CDINTF_H__ - -#include - -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__ diff --git a/waterbox/virtualjaguar/src/cdrom.cpp b/waterbox/virtualjaguar/src/cdrom.cpp index 625c8f9e87..a3019198ab 100644 --- a/waterbox/virtualjaguar/src/cdrom.cpp +++ b/waterbox/virtualjaguar/src/cdrom.cpp @@ -16,7 +16,6 @@ #include "cdrom.h" #include -#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]; -} diff --git a/waterbox/virtualjaguar/src/cdrom.h b/waterbox/virtualjaguar/src/cdrom.h index 6c0524d2a8..3e87bae686 100644 --- a/waterbox/virtualjaguar/src/cdrom.h +++ b/waterbox/virtualjaguar/src/cdrom.h @@ -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__ diff --git a/waterbox/virtualjaguar/src/crc32.cpp b/waterbox/virtualjaguar/src/crc32.cpp index 9544a1986c..99602f53d1 100644 --- a/waterbox/virtualjaguar/src/crc32.cpp +++ b/waterbox/virtualjaguar/src/crc32.cpp @@ -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> 8); return crc ^ 0xFFFFFFFF; diff --git a/waterbox/virtualjaguar/src/crc32.h b/waterbox/virtualjaguar/src/crc32.h index ceddd03f00..107c0d7c63 100644 --- a/waterbox/virtualjaguar/src/crc32.h +++ b/waterbox/virtualjaguar/src/crc32.h @@ -5,6 +5,8 @@ #ifndef __CRC32_H__ #define __CRC32_H__ -int crc32_calcCheckSum(unsigned char * data, unsigned int length); +#include + +uint32_t crc32_calcCheckSum(uint8_t * data, uint32_t length); #endif // __CRC32_H__ diff --git a/waterbox/virtualjaguar/src/cry2rgb.h b/waterbox/virtualjaguar/src/cry2rgb.h index 636b45d487..7b39c7659c 100644 --- a/waterbox/virtualjaguar/src/cry2rgb.h +++ b/waterbox/virtualjaguar/src/cry2rgb.h @@ -1,7 +1,7 @@ // // Red Color Values for CrY<->RGB Color Conversion // -uint8_t redcv[16][16] = { +static const uint8_t redcv[16][16] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F // ---------------------------------------------------------------------- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // 0 @@ -25,7 +25,7 @@ uint8_t redcv[16][16] = { // // Green Color Values for CrY<->RGB Color Conversion // -uint8_t greencv[16][16] = { +static const uint8_t greencv[16][16] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F // ---------------------------------------------------------------------- { 0, 17, 34, 51,68, 85, 102,119,136,153,170,187,204,221,238,255}, // 0 @@ -49,7 +49,7 @@ uint8_t greencv[16][16] = { // // Blue Color Values for CrY<->RGB Color Conversion // -uint8_t bluecv[16][16] = { +static const uint8_t bluecv[16][16] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F // ---------------------------------------------------------------------- { 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255}, // 0 diff --git a/waterbox/virtualjaguar/src/dac.cpp b/waterbox/virtualjaguar/src/dac.cpp index a868cf65cb..be27cbc20f 100644 --- a/waterbox/virtualjaguar/src/dac.cpp +++ b/waterbox/virtualjaguar/src/dac.cpp @@ -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); } // diff --git a/waterbox/virtualjaguar/src/dac.h b/waterbox/virtualjaguar/src/dac.h index 5515dcd665..122ca584ea 100644 --- a/waterbox/virtualjaguar/src/dac.h +++ b/waterbox/virtualjaguar/src/dac.h @@ -9,7 +9,7 @@ void DACInit(void); void DACReset(void); -void DACDone(void); +uint32_t DACResetBuffer(void * buffer); // DAC memory access diff --git a/waterbox/virtualjaguar/src/dsp.cpp b/waterbox/virtualjaguar/src/dsp.cpp index 0fdcab6ce2..48fdab51bb 100644 --- a/waterbox/virtualjaguar/src/dsp.cpp +++ b/waterbox/virtualjaguar/src/dsp.cpp @@ -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; } diff --git a/waterbox/virtualjaguar/src/dsp.h b/waterbox/virtualjaguar/src/dsp.h index 063cd95ddd..7a4ec3be5d 100644 --- a/waterbox/virtualjaguar/src/dsp.h +++ b/waterbox/virtualjaguar/src/dsp.h @@ -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); diff --git a/waterbox/virtualjaguar/src/eeprom.cpp b/waterbox/virtualjaguar/src/eeprom.cpp index 2854f5a4ec..8d1e35c066 100644 --- a/waterbox/virtualjaguar/src/eeprom.cpp +++ b/waterbox/virtualjaguar/src/eeprom.cpp @@ -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; } - diff --git a/waterbox/virtualjaguar/src/eeprom.h b/waterbox/virtualjaguar/src/eeprom.h index 0f89adee3e..89366d0873 100644 --- a/waterbox/virtualjaguar/src/eeprom.h +++ b/waterbox/virtualjaguar/src/eeprom.h @@ -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); diff --git a/waterbox/virtualjaguar/src/event.cpp b/waterbox/virtualjaguar/src/event.cpp index 2a25abe939..d4b338b79d 100644 --- a/waterbox/virtualjaguar/src/event.cpp +++ b/waterbox/virtualjaguar/src/event.cpp @@ -23,7 +23,7 @@ #include #include -#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 - -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__ diff --git a/waterbox/virtualjaguar/src/gpu.cpp b/waterbox/virtualjaguar/src/gpu.cpp index 91d882da7c..7373349897 100644 --- a/waterbox/virtualjaguar/src/gpu.cpp +++ b/waterbox/virtualjaguar/src/gpu.cpp @@ -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 // diff --git a/waterbox/virtualjaguar/src/gpu.h b/waterbox/virtualjaguar/src/gpu.h index 5c125805fe..193c8ac2c6 100644 --- a/waterbox/virtualjaguar/src/gpu.h +++ b/waterbox/virtualjaguar/src/gpu.h @@ -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) diff --git a/waterbox/virtualjaguar/src/jaguar.cpp b/waterbox/virtualjaguar/src/jaguar.cpp index 0a6c28009e..46c9795070 100644 --- a/waterbox/virtualjaguar/src/jaguar.cpp +++ b/waterbox/virtualjaguar/src/jaguar.cpp @@ -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; } diff --git a/waterbox/virtualjaguar/src/jaguar.h b/waterbox/virtualjaguar/src/jaguar.h index 8012cb4100..2f9613e6c6 100644 --- a/waterbox/virtualjaguar/src/jaguar.h +++ b/waterbox/virtualjaguar/src/jaguar.h @@ -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 diff --git a/waterbox/virtualjaguar/src/jerry.cpp b/waterbox/virtualjaguar/src/jerry.cpp index 3f1c78f99b..bd94ba8ec7 100644 --- a/waterbox/virtualjaguar/src/jerry.cpp +++ b/waterbox/virtualjaguar/src/jerry.cpp @@ -29,7 +29,7 @@ #include "wavetable.h" #include "cdhle.h" -/*static*/ uint8_t jerry_ram_8[0x10000]; +uint8_t jerry_ram_8[0x10000]; // JERRY Registers (write, offset from $F10000) #define JPIT1 0x00 @@ -46,8 +46,6 @@ #define SCLK 0xA150 #define SMODE 0xA154 -uint8_t analog_x, analog_y; - static uint32_t JERRYPIT1Prescaler; static uint32_t JERRYPIT1Divider; static uint32_t JERRYPIT2Prescaler; @@ -56,22 +54,17 @@ static int32_t jerry_timer_1_counter; static int32_t jerry_timer_2_counter; int32_t JERRYI2SInterruptTimer = -1; -uint32_t jerryI2SCycles; -uint32_t jerryIntPending; +static uint32_t jerryI2SCycles; static uint16_t jerryInterruptMask = 0; static uint16_t jerryPendingInterrupt = 0; -// Private function prototypes - -void JERRYResetPIT1(void); -void JERRYResetPIT2(void); -void JERRYResetI2S(void); - -void JERRYPIT1Callback(void); -void JERRYPIT2Callback(void); -void JERRYI2SCallback(void); +static void JERRYResetPIT1(void); +static void JERRYResetPIT2(void); +static void JERRYResetI2S(void); +static void JERRYPIT1Callback(void); +static void JERRYPIT2Callback(void); void JERRYResetI2S(void) { @@ -86,7 +79,7 @@ void JERRYResetPIT1(void) if (JERRYPIT1Prescaler | JERRYPIT1Divider) { double usecs = (float)(JERRYPIT1Prescaler + 1) * (float)(JERRYPIT1Divider + 1) * RISC_CYCLE_IN_USEC; - SetCallbackTime(JERRYPIT1Callback, usecs, EVENT_JERRY); + SetCallbackTime(JERRYPIT1Callback, usecs); } } @@ -97,7 +90,7 @@ void JERRYResetPIT2(void) if (JERRYPIT1Prescaler | JERRYPIT1Divider) { double usecs = (float)(JERRYPIT2Prescaler + 1) * (float)(JERRYPIT2Divider + 1) * RISC_CYCLE_IN_USEC; - SetCallbackTime(JERRYPIT2Callback, usecs, EVENT_JERRY); + SetCallbackTime(JERRYPIT2Callback, usecs); } } @@ -139,7 +132,7 @@ void JERRYI2SCallback(void) { DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE); double usecs = (float)jerryI2SCycles * (vjs.hardwareTypeNTSC ? RISC_CYCLE_IN_USEC : RISC_CYCLE_PAL_IN_USEC); - SetCallbackTime(JERRYI2SCallback, usecs, EVENT_JERRY); + SetCallbackTime(JERRYI2SCallback, usecs); } else { @@ -147,7 +140,7 @@ void JERRYI2SCallback(void) { DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE); } - SetCallbackTime(JERRYI2SCallback, 22.675737, EVENT_JERRY); + SetCallbackTime(JERRYI2SCallback, 22.675737); } } @@ -187,14 +180,6 @@ void JERRYReset(void) DACReset(); } -void JERRYDone(void) -{ - JoystickDone(); - DACDone(); - EepromDone(); - MTDone(); -} - bool JERRYIRQEnabled(int irq) { return jerryInterruptMask & irq; @@ -262,8 +247,6 @@ uint16_t JERRYReadWord(uint32_t offset, uint32_t who) // void JERRYWriteByte(uint32_t offset, uint8_t data, uint32_t who) { - jerry_ram_8[offset & 0xFFFF] = data; - if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE + 0x20)) { DSPWriteByte(offset, data, who); @@ -294,6 +277,11 @@ void JERRYWriteByte(uint32_t offset, uint8_t data, uint32_t who) { EepromWriteByte(offset, data); } + + if (offset >= 0xF1D000 && offset <= 0xF1DFFF) + return; + + jerry_ram_8[offset & 0xFFFF] = data; } // @@ -301,9 +289,6 @@ void JERRYWriteByte(uint32_t offset, uint8_t data, uint32_t who) // void JERRYWriteWord(uint32_t offset, uint16_t data, uint32_t who) { - jerry_ram_8[(offset+0) & 0xFFFF] = (data >> 8) & 0xFF; - jerry_ram_8[(offset+1) & 0xFFFF] = data & 0xFF; - if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE + 0x20)) { DSPWriteWord(offset, data, who); @@ -335,6 +320,7 @@ void JERRYWriteWord(uint32_t offset, uint16_t data, uint32_t who) case 6: JERRYPIT2Divider = data; JERRYResetPIT2(); + break; } } else if (offset >= 0xF10020 && offset <= 0xF10022) @@ -351,16 +337,10 @@ void JERRYWriteWord(uint32_t offset, uint16_t data, uint32_t who) { EepromWriteWord(offset, data); } -} -int JERRYGetPIT1Frequency(void) -{ - int systemClockFrequency = (vjs.hardwareTypeNTSC ? RISC_CLOCK_RATE_NTSC : RISC_CLOCK_RATE_PAL); - return systemClockFrequency / ((JERRYPIT1Prescaler + 1) * (JERRYPIT1Divider + 1)); -} + if (offset >= 0xF1D000 && offset <= 0xF1DFFF) + return; -int JERRYGetPIT2Frequency(void) -{ - int systemClockFrequency = (vjs.hardwareTypeNTSC ? RISC_CLOCK_RATE_NTSC : RISC_CLOCK_RATE_PAL); - return systemClockFrequency / ((JERRYPIT2Prescaler + 1) * (JERRYPIT2Divider + 1)); + jerry_ram_8[(offset+0) & 0xFFFF] = (data >> 8) & 0xFF; + jerry_ram_8[(offset+1) & 0xFFFF] = data & 0xFF; } diff --git a/waterbox/virtualjaguar/src/jerry.h b/waterbox/virtualjaguar/src/jerry.h index 2d9da9bf69..30dfad219b 100644 --- a/waterbox/virtualjaguar/src/jerry.h +++ b/waterbox/virtualjaguar/src/jerry.h @@ -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 diff --git a/waterbox/virtualjaguar/src/joystick.cpp b/waterbox/virtualjaguar/src/joystick.cpp index d2caf07e38..83fbbe6b6c 100644 --- a/waterbox/virtualjaguar/src/joystick.cpp +++ b/waterbox/virtualjaguar/src/joystick.cpp @@ -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; } } diff --git a/waterbox/virtualjaguar/src/joystick.h b/waterbox/virtualjaguar/src/joystick.h index de4fa62990..4e6b4c0984 100644 --- a/waterbox/virtualjaguar/src/joystick.h +++ b/waterbox/virtualjaguar/src/joystick.h @@ -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[]; diff --git a/waterbox/virtualjaguar/src/m68000/readcpu.c b/waterbox/virtualjaguar/src/m68000/readcpu.c index 4fb529dcfb..eb4e8a0a3c 100644 --- a/waterbox/virtualjaguar/src/m68000/readcpu.c +++ b/waterbox/virtualjaguar/src/m68000/readcpu.c @@ -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; diff --git a/waterbox/virtualjaguar/src/m68000/readcpu.h b/waterbox/virtualjaguar/src/m68000/readcpu.h index ff4b37d0df..8167683e7d 100644 --- a/waterbox/virtualjaguar/src/m68000/readcpu.h +++ b/waterbox/virtualjaguar/src/m68000/readcpu.h @@ -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); diff --git a/waterbox/virtualjaguar/src/memtrack.cpp b/waterbox/virtualjaguar/src/memtrack.cpp index affb1d9915..94cd9d8930 100644 --- a/waterbox/virtualjaguar/src/memtrack.cpp +++ b/waterbox/virtualjaguar/src/memtrack.cpp @@ -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) { diff --git a/waterbox/virtualjaguar/src/memtrack.h b/waterbox/virtualjaguar/src/memtrack.h index e4d4ab1376..a16b858965 100644 --- a/waterbox/virtualjaguar/src/memtrack.h +++ b/waterbox/virtualjaguar/src/memtrack.h @@ -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); diff --git a/waterbox/virtualjaguar/src/op.cpp b/waterbox/virtualjaguar/src/op.cpp index 09d2c48419..98ac9c44dd 100644 --- a/waterbox/virtualjaguar/src/op.cpp +++ b/waterbox/virtualjaguar/src/op.cpp @@ -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> 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 + diff --git a/waterbox/virtualjaguar/src/op.h b/waterbox/virtualjaguar/src/op.h index ad9040088b..416e129e4c 100644 --- a/waterbox/virtualjaguar/src/op.h +++ b/waterbox/virtualjaguar/src/op.h @@ -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__ diff --git a/waterbox/virtualjaguar/src/risc_opcodes.h b/waterbox/virtualjaguar/src/risc_opcodes.h index a429301ee4..8b1aceab7e 100644 --- a/waterbox/virtualjaguar/src/risc_opcodes.h +++ b/waterbox/virtualjaguar/src/risc_opcodes.h @@ -202,14 +202,20 @@ RISC_OPCODE(store_r14_indexed) { uint32_t address = risc_reg[14] + (risc_convert_zero[IMM_1] << 2); ALERT_UNALIGNED_LONG(address); - RISCWriteLong(address & 0xFFFFFFFC, RN, RISC); + if (IS_RISC_RAM(address)) + RISCWriteLong(address & 0xFFFFFFFC, RN, RISC); + else + RISCWriteLong(address, RN, RISC); } RISC_OPCODE(store_r15_indexed) { uint32_t address = risc_reg[15] + (risc_convert_zero[IMM_1] << 2); ALERT_UNALIGNED_LONG(address); - RISCWriteLong(address & 0xFFFFFFFC, RN, RISC); + if (IS_RISC_RAM(address)) + RISCWriteLong(address & 0xFFFFFFFC, RN, RISC); + else + RISCWriteLong(address, RN, RISC); } RISC_OPCODE(load_r14_ri) @@ -230,14 +236,20 @@ RISC_OPCODE(store_r14_ri) { uint32_t address = risc_reg[14] + RM; ALERT_UNALIGNED_LONG(address); - RISCWriteLong(address & 0xFFFFFFFC, RN, RISC); + if (IS_RISC_RAM(address)) + RISCWriteLong(address & 0xFFFFFFFC, RN, RISC); + else + RISCWriteLong(address, RN, RISC); } RISC_OPCODE(store_r15_ri) { uint32_t address = risc_reg[15] + RM; ALERT_UNALIGNED_LONG(address); - RISCWriteLong(address & 0xFFFFFFFC, RN, RISC); + if (IS_RISC_RAM(address)) + RISCWriteLong(address & 0xFFFFFFFC, RN, RISC); + else + RISCWriteLong(address, RN, RISC); } RISC_OPCODE(nop) @@ -259,13 +271,16 @@ RISC_OPCODE(storew) if (IS_RISC_RAM(RM)) RISCWriteLong(RM & 0xFFFFFFFC, RN, RISC); else - JaguarWriteWord(RM & 0xFFFFFFFE, RN, RISC); + JaguarWriteWord(RM, RN, RISC); } RISC_OPCODE(store) { ALERT_UNALIGNED_LONG(RM); - RISCWriteLong(RM & 0xFFFFFFFC, RN, RISC); + if (IS_RISC_RAM(RM)) + RISCWriteLong(RM & 0xFFFFFFFC, RN, RISC); + else + RISCWriteLong(RM, RN, RISC); } RISC_OPCODE(loadb) @@ -283,7 +298,7 @@ RISC_OPCODE(loadw) if (IS_RISC_RAM(RM)) RN = RISCReadLong(RM & 0xFFFFFFFC, RISC); else - RN = JaguarReadWord(RM & 0xFFFFFFFE, RISC); + RN = JaguarReadWord(RM, RISC); } RISC_OPCODE(load) diff --git a/waterbox/virtualjaguar/src/file.cpp b/waterbox/virtualjaguar/src/rom.cpp similarity index 92% rename from waterbox/virtualjaguar/src/file.cpp rename to waterbox/virtualjaguar/src/rom.cpp index 6e4a3e7fb2..558d53ae62 100644 --- a/waterbox/virtualjaguar/src/file.cpp +++ b/waterbox/virtualjaguar/src/rom.cpp @@ -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 #include @@ -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; diff --git a/waterbox/virtualjaguar/src/rom.h b/waterbox/virtualjaguar/src/rom.h new file mode 100644 index 0000000000..98e6b54479 --- /dev/null +++ b/waterbox/virtualjaguar/src/rom.h @@ -0,0 +1,19 @@ +// +// ROM.H +// +// ROM support +// + +#ifndef __ROM_H__ +#define __ROM_H__ + +#include + +// 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__ diff --git a/waterbox/virtualjaguar/src/tom.cpp b/waterbox/virtualjaguar/src/tom.cpp index 61edb80f1b..034073182f 100644 --- a/waterbox/virtualjaguar/src/tom.cpp +++ b/waterbox/virtualjaguar/src/tom.cpp @@ -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(LCM_SCREEN_WIDTH); + scanlines[i] = alloc_invisible(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; } diff --git a/waterbox/virtualjaguar/src/tom.h b/waterbox/virtualjaguar/src/tom.h index 149ae15338..11d02ab929 100644 --- a/waterbox/virtualjaguar/src/tom.h +++ b/waterbox/virtualjaguar/src/tom.h @@ -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__