[virtualjaguar] memtrack support, fix bug with event system, various cleanups

This commit is contained in:
CasualPokePlayer 2022-09-28 02:19:09 -07:00
parent 9fa38b8d78
commit 80cf3a0c48
8 changed files with 177 additions and 78 deletions

Binary file not shown.

View File

@ -88,9 +88,13 @@ EXPORT void SetCdCallbacks(void (*ctc)(void * dest), void (*cdrc)(int32_t lba, v
cd_read_callback = cdrc;
}
EXPORT void InitWithCd(BizSettings* bizSettings, u8* boot)
EXPORT void InitWithCd(BizSettings* bizSettings, u8* boot, u8* memtrack)
{
InitCommon(bizSettings);
if (memtrack)
{
JaguarLoadFile(memtrack, 0x20000);
}
vjs.hardwareTypeAlpine = false;
SET32(jaguarMainRAM, 0, 0x00200000);
@ -99,24 +103,50 @@ EXPORT void InitWithCd(BizSettings* bizSettings, u8* boot)
JaguarReset();
}
// standard cart eeprom
extern u16 eeprom_ram[64];
extern bool eeprom_dirty;
// memtrack ram (used for jagcd)
extern u8 mtMem[0x20000];
extern bool mtDirty;
static inline bool IsMemTrack()
{
return jaguarMainROMCRC32 == 0xFDF37F47;
}
EXPORT bool SaveRamIsDirty()
{
return eeprom_dirty;
return IsMemTrack() ? mtDirty : eeprom_dirty;
}
EXPORT void GetSaveRam(u8* dst)
{
memcpy(dst, eeprom_ram, sizeof(eeprom_ram));
eeprom_dirty = false;
if (IsMemTrack())
{
memcpy(dst, mtMem, sizeof(mtMem));
mtDirty = false;
}
else
{
memcpy(dst, eeprom_ram, sizeof(eeprom_ram));
eeprom_dirty = false;
}
}
EXPORT void PutSaveRam(u8* src)
{
memcpy(eeprom_ram, src, sizeof(eeprom_ram));
eeprom_dirty = false;
if (IsMemTrack())
{
memcpy(mtMem, src, sizeof(mtMem));
mtDirty = false;
}
else
{
memcpy(eeprom_ram, src, sizeof(eeprom_ram));
eeprom_dirty = false;
}
}
extern u8 gpu_ram_8[0x1000];
@ -173,10 +203,20 @@ EXPORT void GetMemoryAreas(MemoryArea* m)
m[0].Size = 0x200000;
m[0].Flags = MEMORYAREA_FLAGS_WORDSIZE2 | MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_YUGEENDIAN | MEMORYAREA_FLAGS_PRIMARY;
m[1].Data = eeprom_ram;
m[1].Name = "EEPROM";
m[1].Size = sizeof(eeprom_ram);
m[1].Flags = MEMORYAREA_FLAGS_WORDSIZE2 | MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_YUGEENDIAN | MEMORYAREA_FLAGS_SAVERAMMABLE;
if (IsMemTrack())
{
m[1].Data = mtMem;
m[1].Name = "MEMTRACK RAM";
m[1].Size = sizeof(mtMem);
m[1].Flags = MEMORYAREA_FLAGS_WORDSIZE2 | MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_YUGEENDIAN | MEMORYAREA_FLAGS_SAVERAMMABLE;
}
else
{
m[1].Data = jaguarCartInserted ? eeprom_ram : NULL;
m[1].Name = "EEPROM";
m[1].Size = sizeof(eeprom_ram);
m[1].Flags = MEMORYAREA_FLAGS_WORDSIZE2 | MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_YUGEENDIAN | MEMORYAREA_FLAGS_SAVERAMMABLE;
}
m[2].Data = gpu_ram_8;
m[2].Name = "GPU RAM";
@ -291,14 +331,11 @@ void (*ReadCallback)(u32) = 0;
void (*WriteCallback)(u32) = 0;
void (*ExecuteCallback)(u32) = 0;
EXPORT void SetMemoryCallback(u32 which, void (*callback)(u32))
EXPORT void SetMemoryCallbacks(void (*rcb)(u32), void (*wcb)(u32), void (*ecb)(u32))
{
switch (which)
{
case 0: ReadCallback = callback; break;
case 1: WriteCallback = callback; break;
case 2: ExecuteCallback = callback; break;
}
ReadCallback = rcb;
WriteCallback = wcb;
ExecuteCallback = ecb;
}
void (*CPUTraceCallback)(u32*) = 0;

View File

@ -3,6 +3,9 @@
#include "memory.h"
#include "jaguar.h"
#include "jerry.h"
#include "tom.h"
#include "dac.h"
#include "dsp.h"
#include "event.h"
#include "m68000/m68kinterface.h"
@ -21,6 +24,7 @@ static bool cd_setup;
static bool cd_initm;
static bool cd_muted;
static bool cd_paused;
bool cd_jerry;
static uint8_t cd_mode;
static uint8_t cd_osamp;
@ -144,9 +148,20 @@ void CDHLEReset(void)
cd_initm = false;
cd_muted = false;
cd_paused = false;
cd_jerry = false;
cd_mode = 0;
cd_osamp = 0;
cd_is_reading = false;
cd_read_orig_addr_start = 0;
cd_read_addr_start = 0;
cd_read_addr_end = 0;
cd_read_lba = 0;
memset(cd_buf2352, 0, sizeof(cd_buf2352));
cd_buf_pos = 0;
cd_buf_rm = 0;
cd_buf_circular_size = 0;
if (cd_read_callback)
{
// copy TOC to RAM
@ -208,6 +223,12 @@ void CDHLEReset(void)
SET32(jaguarMainRAM, 4, cd_boot_addr);
SET16(jaguarMainRAM, 0x3004, 0x0403); // BIOS VER
DACWriteByte(0xF1A153, 9); // set SCLK to 9
if (jaguarMainROMCRC32 == 0xFDF37F47)
{
TOMWriteWord(0xF00000, (TOMGetMEMCON1() & ~6u) | 4); // set ROM width to 32 bit
memcpy(&jaguarMainRAM[0x2400], &jaguarMainROM[0x6D60], 0x790); // copy memtrack "bios" to ram
}
}
}
@ -215,58 +236,35 @@ void CDHLEDone(void)
{
}
static void CDSendBlock(void)
static void RefillCDBuf()
{
if (cd_buf_rm < 64)
{
memmove(&cd_buf2352[0], &cd_buf2352[cd_buf_pos], cd_buf_rm);
cd_read_callback(cd_read_lba++, &cd_buf2352[cd_buf_rm]);
memmove(&cd_buf2352[0], &cd_buf2352[cd_buf_pos], cd_buf_rm);
cd_read_callback(cd_read_lba++, &cd_buf2352[cd_buf_rm]);
// hack to force word alignment
if (cd_word_alignment)
// hack to force word alignment
if (cd_word_alignment)
{
uint8_t temp2352[2352];
cd_read_callback(cd_read_lba, temp2352);
memmove(&cd_buf2352[cd_buf_rm], &cd_buf2352[cd_buf_rm + cd_word_alignment], 2352 - cd_word_alignment);
memcpy(&cd_buf2352[cd_buf_rm + 2352 - cd_word_alignment], &temp2352[0], cd_word_alignment);
}
if (cd_byte_swapped)
{
uint16_t* cd16buf = (uint16_t*)&cd_buf2352[cd_buf_rm];
for (uint32_t i = 0; i < (2352 / 2); i++)
{
uint8_t temp2352[2352];
cd_read_callback(cd_read_lba, temp2352);
memmove(&cd_buf2352[cd_buf_rm], &cd_buf2352[cd_buf_rm + cd_word_alignment], 2352 - cd_word_alignment);
memcpy(&cd_buf2352[cd_buf_rm + 2352 - cd_word_alignment], &temp2352[0], cd_word_alignment);
cd16buf[i] = __builtin_bswap16(cd16buf[i]);
}
if (cd_byte_swapped)
{
uint16_t* cd16buf = (uint16_t*)&cd_buf2352[cd_buf_rm];
for (uint32_t i = 0; i < (2352 / 2); i++)
{
cd16buf[i] = __builtin_bswap16(cd16buf[i]);
}
}
cd_buf_pos = 0;
cd_buf_rm += 2352;
}
// send one block of data, one long at a time
for (uint32_t i = 0; i < 64; i += 4)
{
GPUWriteLong(cd_read_addr_start + i, GET32(cd_buf2352, cd_buf_pos + i), GPU);
}
cd_read_addr_start += 64;
cd_buf_pos += 64;
cd_buf_rm -= 64;
if (cd_read_addr_start >= cd_read_addr_end)
{
cd_is_reading = false;
}
else if (cd_buf_circular_size && (cd_read_addr_start - cd_read_orig_addr_start) >= cd_buf_circular_size)
{
cd_read_addr_start = cd_read_orig_addr_start;
}
cd_buf_pos = 0;
cd_buf_rm += 2352;
}
static void CDHLECallback(void)
{
RemoveCallback(CDHLECallback);
if (cd_is_reading)
{
if (!GPURunning())
@ -274,14 +272,69 @@ static void CDHLECallback(void)
if (GPURunning() && !cd_paused)
{
CDSendBlock();
if (cd_buf_rm < 64)
{
RefillCDBuf();
}
// send one block of data, one long at a time
for (uint32_t i = 0; i < 64; i += 4)
{
GPUWriteLong(cd_read_addr_start + i, GET32(cd_buf2352, cd_buf_pos + i), GPU);
}
cd_read_addr_start += 64;
cd_buf_pos += 64;
cd_buf_rm -= 64;
if (cd_read_addr_start >= cd_read_addr_end)
{
cd_is_reading = false;
}
else if (cd_buf_circular_size && (cd_read_addr_start - cd_read_orig_addr_start) >= cd_buf_circular_size)
{
cd_read_addr_start = cd_read_orig_addr_start;
}
//GPUSetIRQLine(GPUIRQ_DSP, ASSERT_LINE);
}
SetCallbackTime(CDHLECallback, 285 >> (cd_mode & 1));
}
}
static void LoadISRStub()
// called from JERRYI2SCallback
bool CDHLEJerryCallback(void)
{
if (!cd_is_reading || !cd_jerry || cd_paused)
{
return false;
}
if (cd_buf_rm < 4)
{
RefillCDBuf();
}
DACWriteWord(0xF1A14A, GET16(cd_buf2352, cd_buf_pos + 0));
DACWriteWord(0xF1A14E, GET16(cd_buf2352, cd_buf_pos + 2));
cd_buf_pos += 4;
cd_buf_rm -= 4;
return true;
}
static void ResetCallbacks(void)
{
RemoveCallback(CDHLECallback);
if (!cd_jerry)
{
SetCallbackTime(CDHLECallback, 285 >> (cd_mode & 1));
}
}
static void LoadISRStub(void)
{
uint32_t isrAddr = m68k_get_reg(NULL, M68K_REG_A0);
uint32_t addr = 0xF03010;
@ -373,7 +426,13 @@ static void CD_ack(void)
static void CD_jeri(void)
{
fprintf(stderr, "CD_jeri called %d!!!\n", m68k_get_reg(NULL, M68K_REG_D0) & 1);
bool njerry = m68k_get_reg(NULL, M68K_REG_D0) & 1;
if (cd_jerry ^ njerry)
{
fprintf(stderr, "changing jerry mode %d -> %d\n", cd_jerry, njerry);
cd_jerry = njerry;
ResetCallbacks();
}
}
static void CD_spin(void)
@ -514,8 +573,7 @@ static void CD_read(void)
cd_buf_pos = 0;
cd_buf_rm = bufRm;
cd_buf_circular_size = circBufSz ? (1 << circBufSz) : 0;
RemoveCallback(CDHLECallback);
SetCallbackTime(CDHLECallback, 285 >> (cd_mode & 1));
ResetCallbacks();
JERRYWriteWord(0xF10020, 0, M68K);
//GPUWriteLong(0xF02100, GPUReadLong(0xF02100, M68K) | 0x20, M68K);
break;
@ -536,8 +594,7 @@ static void CD_read(void)
cd_buf_pos = 0;
cd_buf_rm = 0;
cd_buf_circular_size = 0;
RemoveCallback(CDHLECallback);
SetCallbackTime(CDHLECallback, 285 >> (cd_mode & 1));
ResetCallbacks();
JERRYWriteWord(0xF10020, 0, M68K);
//GPUWriteLong(0xF02100, GPUReadLong(0xF02100, M68K) | 0x20, M68K);
}

View File

@ -8,5 +8,6 @@ void CDHLEReset(void);
void CDHLEDone(void);
void CDHLEHook(uint32_t which);
bool CDHLEJerryCallback(void);
#endif // __CDHLE_H__

View File

@ -69,10 +69,8 @@ void DSPSampleCallback(void);
void DACInit(void)
{
ltxd = lrxd = 0;
sclk = 19;
uint32_t riscClockRate = (vjs.hardwareTypeNTSC ? RISC_CLOCK_RATE_NTSC : RISC_CLOCK_RATE_PAL);
uint32_t cyclesPerSample = riscClockRate / DAC_AUDIO_RATE;
sclk = 19;
}
//

View File

@ -19,7 +19,9 @@
#include "event.h"
#include <assert.h>
#include <stdint.h>
#include <float.h>
#define EVENT_LIST_SIZE 32
@ -145,10 +147,10 @@ double GetTimeToNextEvent(int type)
{
if (type == EVENT_MAIN)
{
double time = eventList[0].eventTime;
nextEvent = 0;
double time = DBL_MAX;
nextEvent = EVENT_LIST_SIZE;
for(uint32_t i=1; i<EVENT_LIST_SIZE; i++)
for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
{
if (eventList[i].valid && (eventList[i].eventTime < time))
{
@ -157,14 +159,15 @@ double GetTimeToNextEvent(int type)
}
}
assert(nextEvent != EVENT_LIST_SIZE);
return time;
}
else
{
double time = eventListJERRY[0].eventTime;
nextEventJERRY = 0;
double time = DBL_MAX;
nextEventJERRY = EVENT_LIST_SIZE;
for(uint32_t i=1; i<EVENT_LIST_SIZE; i++)
for(uint32_t i=0; i<EVENT_LIST_SIZE; i++)
{
if (eventListJERRY[i].valid && (eventListJERRY[i].eventTime < time))
{
@ -173,6 +176,7 @@ double GetTimeToNextEvent(int type)
}
}
assert(nextEventJERRY != EVENT_LIST_SIZE);
return time;
}
}

View File

@ -27,6 +27,7 @@
#include "settings.h"
#include "tom.h"
#include "wavetable.h"
#include "cdhle.h"
/*static*/ uint8_t jerry_ram_8[0x10000];
@ -142,12 +143,10 @@ void JERRYI2SCallback(void)
}
else
{
if (ButchIsReadyToSend())
if (CDHLEJerryCallback())
{
SetSSIWordsXmittedFromButch();
DSPSetIRQLine(DSPIRQ_SSI, ASSERT_LINE);
}
SetCallbackTime(JERRYI2SCallback, 22.675737, EVENT_JERRY);
}
}

View File

@ -30,6 +30,7 @@ enum { MT_NONE, MT_PROD_ID, MT_RESET, MT_WRITE_ENABLE };
enum { MT_IDLE, MT_PHASE1, MT_PHASE2 };
uint8_t mtMem[0x20000];
bool mtDirty;
uint8_t mtCommand = MT_NONE;
uint8_t mtState = MT_IDLE;
@ -38,6 +39,7 @@ void MTStateMachine(uint8_t reg, uint16_t data);
void MTInit(void)
{
memset(mtMem, 0xFF, 0x20000);
mtDirty = false;
}
void MTReset(void)
@ -90,6 +92,7 @@ void MTWriteWord(uint32_t addr, uint16_t data)
if (mtCommand == MT_WRITE_ENABLE)
{
mtMem[(addr & 0x7FFFC) >> 2] = (uint8_t)(data & 0xFF);
mtDirty = true;
return;
}