savestate: save sq_remap, save aw cart state, fix lr aw format

save AW cart state
save sq_remap used for mini-mmu with store queues
allow loading lr aw savestate. upgrade to v11
aica: saturate EG register
savestate: save current TA data
texcache: fix race condition when deleting a texture
handle 1x1 YUV tex as 565
This commit is contained in:
Flyinghead 2020-07-06 16:28:09 +02:00
parent 42cb880538
commit fee28194fb
9 changed files with 229 additions and 187 deletions

View File

@ -46,7 +46,7 @@ extern bool fast_forward_mode;
//Sound generation, mixin, and channel regs emulation
//x.15
s32 volume_lut[16];
static s32 volume_lut[16];
//255 -> mute
//Converts Send levels to TL-compatible values (DISDL, etc)
static const u32 SendLevel[16] =
@ -54,7 +54,7 @@ static const u32 SendLevel[16] =
255, 14 << 3, 13 << 3, 12 << 3, 11 << 3, 10 << 3, 9 << 3, 8 << 3,
7 << 3, 6 << 3, 5 << 3, 4 << 3, 3 << 3, 2 << 3, 1 << 3, 0 << 3
};
s32 tl_lut[256 + 768]; //xx.15 format. >=255 is muted
static s32 tl_lut[256 + 768]; //xx.15 format. >=255 is muted
//in ms :)
static const double AEG_Attack_Time[64] =
@ -91,9 +91,9 @@ static int PLFO_Scales[8][256];
#define AEG_ATTACK_SHIFT 16
//Steps per sample
u32 AEG_ATT_SPS[64];
u32 AEG_DSR_SPS[64];
u32 FEG_SPS[64];
static u32 AEG_ATT_SPS[64];
static u32 AEG_DSR_SPS[64];
static u32 FEG_SPS[64];
static const char* stream_names[]=
{
@ -126,14 +126,12 @@ static const s32 qtable[32] = {
0x1C00,0x1D00,0x1E00,0x1F00
};
//Remove the fractional part , with rounding ;) -- does not need an extra bit
#define well(a,bits) (((a) + ((1<<(bits-1))))>>bits)
//Remove the fractional part by chopping..
#define FPChop(a,bits) ((a)>>bits)
#define FPChop(a, bits) ((a) >> (bits))
#define FPs FPChop
//Fixed point mul w/ rounding :)
#define FPMul(a,b,bits) (FPs(a*b,bits))
#define FPMul(a, b, bits) FPs((a) * (b), bits)
#define VOLPAN(value,vol,pan,outl,outr) \
{\
@ -151,7 +149,6 @@ static const s32 qtable[32] = {
(outr)+=temp;\
}\
}
s16 pl=0,pr=0;
DSP_OUT_VOL_REG* dsp_out_vol;
@ -317,13 +314,12 @@ enum _EG_state
struct ChannelEx;
//make these DYNACALL ? they were fastcall before ..
void (* STREAM_STEP_LUT[5][2][2])(ChannelEx* ch);
void (* STREAM_INITAL_STEP_LUT[5])(ChannelEx* ch);
void (* AEG_STEP_LUT[4])(ChannelEx* ch);
void (* FEG_STEP_LUT[4])(ChannelEx* ch);
void (* ALFOWS_CALC[4])(ChannelEx* ch);
void (* PLFOWS_CALC[4])(ChannelEx* ch);
static void (* STREAM_STEP_LUT[5][2][2])(ChannelEx* ch);
static void (* STREAM_INITAL_STEP_LUT[5])(ChannelEx* ch);
static void (* AEG_STEP_LUT[4])(ChannelEx* ch);
static void (* FEG_STEP_LUT[4])(ChannelEx* ch);
static void (* ALFOWS_CALC[4])(ChannelEx* ch);
static void (* PLFOWS_CALC[4])(ChannelEx* ch);
struct ChannelEx
{
@ -532,7 +528,10 @@ struct ChannelEx
Step(oLeft, oRight, oDsp);
*VolMix.DSPOut+=oDsp;
*VolMix.DSPOut += oDsp;
if (oLeft + oRight == 0 && !settings.aica.DSPEnabled)
oLeft = oRight = oDsp >> 4;
mixl+=oLeft;
mixr+=oRight;
}
@ -540,10 +539,9 @@ struct ChannelEx
__forceinline static void StepAll(SampleType& mixl, SampleType& mixr)
{
for (int i = 0; i < 64; i++)
{
Chans[i].Step(mixl, mixr);
}
}
void SetAegState(_EG_state newstate)
{
StepAEG=AEG_STEP_LUT[newstate];
@ -566,54 +564,46 @@ struct ChannelEx
void KEY_ON()
{
if (AEG.state==EG_Release)
{
//if it was off then turn it on !
enable();
if (AEG.state != EG_Release)
return;
// reset AEG
SetAegState(EG_Attack);
AEG.SetValue(0x280); // start value taken from HT
//if it was off then turn it on !
enable();
//reset FEG
SetFegState(EG_Attack);
//set values and crap
// reset AEG
SetAegState(EG_Attack);
AEG.SetValue(0x280); // start value taken from HT
//reset FEG
SetFegState(EG_Attack);
//set values and crap
//Reset sampling state
CA=0;
step.full=0;
//Reset sampling state
CA=0;
step.full=0;
loop.looped=false;
adpcm.Reset(this);
loop.looped=false;
StepStreamInitial(this);
key_printf("[%d] KEY_ON %s @ %f Hz, loop %d - AEG AR %d DC1R %d DC2V %d DC2R %d RR %d - KRS %d OCT %d FNS %d - PFLOS %d PFLOWS %d",
ChannelNumber, stream_names[ccd->PCMS], (44100.0 * update_rate) / 1024, ccd->LPCTL,
ccd->AR, ccd->D1R, ccd->DL << 5, ccd->D2R, ccd->RR,
ccd->KRS, ccd->OCT, ccd->FNS >> 9,
ccd->PLFOS, ccd->PLFOWS);
}
else
{
//ignore ?
}
adpcm.Reset(this);
StepStreamInitial(this);
key_printf("[%d] KEY_ON %s @ %f Hz, loop %d - AEG AR %d DC1R %d DC2V %d DC2R %d RR %d - KRS %d OCT %d FNS %d - PFLOS %d PFLOWS %d",
ChannelNumber, stream_names[ccd->PCMS], (44100.0 * update_rate) / 1024, ccd->LPCTL,
ccd->AR, ccd->D1R, ccd->DL << 5, ccd->D2R, ccd->RR,
ccd->KRS, ccd->OCT, ccd->FNS >> 9,
ccd->PLFOS, ccd->PLFOWS);
}
void KEY_OFF()
{
if (AEG.state!=EG_Release)
{
key_printf("[%d] KEY_OFF -> Release", ChannelNumber);
SetAegState(EG_Release);
SetFegState(EG_Release);
//switch to release state
}
else
{
//ignore ?
}
if (AEG.state == EG_Release)
return;
key_printf("[%d] KEY_OFF -> Release", ChannelNumber);
SetAegState(EG_Release);
SetFegState(EG_Release);
}
//PCMS,SSCTL,LPCTL,LPSLNK
void UpdateStreamStep()
{
@ -906,19 +896,13 @@ __forceinline void StepDecodeSample(ChannelEx* ch,u32 CA)
break;
case 0:
{
//s16* ptr=(s16*)&aica_ram[(addr&~1)+(CA<<1)];
s0 = sptr16[CA];
s1 = sptr16[next_addr];
}
s0 = sptr16[CA];
s1 = sptr16[next_addr];
break;
case 1:
{
//s8* ptr=(s8*)&aica_ram[addr+(CA)];
s0 = sptr8[CA] << 8;
s1 = sptr8[next_addr] << 8;
}
s0 = sptr8[CA] << 8;
s1 = sptr8[next_addr] << 8;
break;
case 2:
@ -1007,11 +991,16 @@ void StreamStep(ChannelEx* ch)
if (ca_t >= ch->loop.LEA)
{
ch->loop.looped = 1;
CA = ch->loop.LSA;
if (LPCTL == 0)
{
CA = 0;
ch->disable();
}
else
{
CA = ch->loop.LSA;
key_printf("[%d]LPCTL : Looping LSA %x LEA %x", ch->ChannelNumber, ch->loop.LSA, ch->loop.LEA);
}
}
ch->CA=CA;
@ -1167,13 +1156,10 @@ void FegStep(ChannelEx* ch)
delta = maxd;
ch->FEG.value -= delta;
}
else
else if (ch->FEG.state < EG_Decay2)
{
if (ch->FEG.state < EG_Decay2)
{
feg_printf("[%d]FEG_step : Switching to next state: %d Freq %x", ch->ChannelNumber, (int)ch->FEG.state + 1, target >> EG_STEP_BITS);
ch->SetFegState((_EG_state)((int)ch->FEG.state + 1));
}
feg_printf("[%d]FEG_step : Switching to next state: %d Freq %x", ch->ChannelNumber, (int)ch->FEG.state + 1, target >> EG_STEP_BITS);
ch->SetFegState((_EG_state)((int)ch->FEG.state + 1));
}
}
@ -1274,9 +1260,7 @@ void sgc_Init()
}
for (int i = 0; i < 256; i++)
{
tl_lut[i]=(s32)((1<<15)/pow(2.0,i/16.0));
}
//tl entries 256 to 1023 are 0
for (int i=256;i<1024;i++)
@ -1297,9 +1281,7 @@ void sgc_Init()
{
float limit = PLFOS_Scale[s];
for (int i = -128; i < 128; i++)
{
PLFO_Scales[s][i + 128] = (u32)((1 << 10) * powf(2.0f, limit * i / 128.0f / 1200.0f));
}
}
dsp_init();
@ -1321,18 +1303,21 @@ void ReadCommonReg(u32 reg,bool byte)
{
case 0x2808:
case 0x2809:
CommonData->MIEMP=1;
CommonData->MOEMP=1;
CommonData->MIEMP = 1;
CommonData->MOEMP = 1;
CommonData->MIOVF = 0;
CommonData->MIFUL = 0;
CommonData->MOFUL = 0;
break;
case 0x2810: //LP & misc
case 0x2811: //LP & misc
case 0x2810: // EG, SGC, LP
case 0x2811:
{
u32 chan=CommonData->MSLC;
CommonData->LP=Chans[chan].loop.looped;
verify(CommonData->AFSEL == 0);
CommonData->EG=Chans[chan].AEG.GetValue(); //AEG is only 10 bits, FEG is 13 bits
s32 aeg = Chans[chan].AEG.GetValue();
CommonData->EG = aeg << 3 | (aeg & 1 ? 7 : 0); //AEG is only 10 bits, FEG is 13 bits
CommonData->SGC=Chans[chan].AEG.state;
if (! (byte && reg==0x2810))
@ -1343,7 +1328,7 @@ void ReadCommonReg(u32 reg,bool byte)
case 0x2815: //CA
{
u32 chan=CommonData->MSLC;
CommonData->CA = Chans[chan].CA /*& (~1023)*/; //mmnn??
CommonData->CA = Chans[chan].CA;
//printf("[%d] CA read %d\n",chan,Chans[chan].CA);
}
break;
@ -1385,10 +1370,8 @@ void AICA_Sample32()
sg++;
if (0==(oLeft+oRight))
{
oLeft=oRight=oDsp;
}
if (oLeft + oRight == 0)
oLeft = oRight = oDsp;
mxlr[i*2+0] += oLeft;
mxlr[i*2+1] += oRight;
@ -1471,9 +1454,6 @@ void AICA_Sample32()
clip16(mixl);
clip16(mixr);
pl=mixl;
pr=mixr;
if (!fast_forward_mode && !settings.aica.NoSound)
WriteSample(mixr,mixl);
}
@ -1522,15 +1502,11 @@ void AICA_Sample()
dsp_step();
for (int i=0;i<16;i++)
{
VOLPAN(*(s16*)&DSPData->EFREG[i], dsp_out_vol[i].EFSDL, dsp_out_vol[i].EFPAN, mixl, mixr);
}
}
if (fast_forward_mode || settings.aica.NoSound)
{
return;
}
if (fast_forward_mode || settings.aica.NoSound)
return;
//Mono !
if (CommonData->Mono)
@ -1567,9 +1543,6 @@ void AICA_Sample()
clip16(mixl);
clip16(mixr);
pl=mixl;
pr=mixr;
WriteSample(mixr,mixl);
}
@ -1614,6 +1587,7 @@ bool channel_unserialize(void **data, unsigned int *total_size, serialize_versio
int i = 0 ;
int addr = 0 ;
u32 dum;
bool old_format = ver < V7 && ver != VCUR_LIBRETRO;
for ( i = 0 ; i < 64 ; i++)
{
@ -1622,20 +1596,20 @@ bool channel_unserialize(void **data, unsigned int *total_size, serialize_versio
REICAST_US(Chans[i].CA) ;
REICAST_US(Chans[i].step) ;
if (ver < V7 && ver != V9_LIBRETRO)
if (old_format)
REICAST_US(dum); // Chans[i].update_rate
Chans[i].UpdatePitch();
REICAST_US(Chans[i].s0) ;
REICAST_US(Chans[i].s1) ;
REICAST_US(Chans[i].loop.looped);
if (ver < V7 && ver != V9_LIBRETRO)
if (old_format)
{
REICAST_US(dum); // Chans[i].loop.LSA
REICAST_US(dum); // Chans[i].loop.LEA
}
Chans[i].UpdateLoop();
REICAST_US(Chans[i].adpcm.last_quant) ;
if (ver >= V7 || ver == V9_LIBRETRO)
if (!old_format)
{
REICAST_US(Chans[i].adpcm.loopstart_quant);
REICAST_US(Chans[i].adpcm.loopstart_prev_sample);
@ -1648,21 +1622,21 @@ bool channel_unserialize(void **data, unsigned int *total_size, serialize_versio
Chans[i].adpcm.loopstart_prev_sample = 0;
}
REICAST_US(Chans[i].noise_state) ;
if (ver < V7 && ver != V9_LIBRETRO)
if (old_format)
{
REICAST_US(dum); // Chans[i].VolMix.DLAtt
REICAST_US(dum); // Chans[i].VolMix.DRAtt
REICAST_US(dum); // Chans[i].VolMix.DSPAtt
}
Chans[i].UpdateAtts();
if (ver < V7 && ver != V9_LIBRETRO)
if (old_format)
REICAST_US(dum); // Chans[i].VolMix.DSPOut
Chans[i].UpdateDSPMIX();
REICAST_US(Chans[i].AEG.val) ;
REICAST_US(Chans[i].AEG.state) ;
Chans[i].SetAegState(Chans[i].AEG.state);
if (ver < V7 && ver != V9_LIBRETRO)
if (old_format)
{
REICAST_US(dum); // Chans[i].AEG.AttackRate
REICAST_US(dum); // Chans[i].AEG.Decay1Rate
@ -1673,7 +1647,7 @@ bool channel_unserialize(void **data, unsigned int *total_size, serialize_versio
Chans[i].UpdateAEG();
REICAST_US(Chans[i].FEG.value);
REICAST_US(Chans[i].FEG.state);
if (ver >= V7 || ver == V9_LIBRETRO)
if (!old_format)
{
REICAST_US(Chans[i].FEG.prev1);
REICAST_US(Chans[i].FEG.prev2);
@ -1685,7 +1659,7 @@ bool channel_unserialize(void **data, unsigned int *total_size, serialize_versio
}
Chans[i].SetFegState(Chans[i].FEG.state);
Chans[i].UpdateFEG();
if (ver < V7 && ver != V9_LIBRETRO)
if (old_format)
{
u8 dumu8;
REICAST_US(dumu8); // Chans[i].step_stream_lut1
@ -1695,10 +1669,10 @@ bool channel_unserialize(void **data, unsigned int *total_size, serialize_versio
Chans[i].UpdateStreamStep();
REICAST_US(Chans[i].lfo.counter) ;
if (ver < V7 && ver != V9_LIBRETRO)
if (old_format)
REICAST_US(dum); // Chans[i].lfo.start_value
REICAST_US(Chans[i].lfo.state) ;
if (ver < V7 && ver != V9_LIBRETRO)
if (old_format)
{
u8 dumu8;
REICAST_US(dumu8); // Chans[i].lfo.alfo
@ -1710,7 +1684,7 @@ bool channel_unserialize(void **data, unsigned int *total_size, serialize_versio
}
Chans[i].UpdateLFO();
REICAST_US(Chans[i].enabled) ;
if (ver < V7 && ver != V9_LIBRETRO)
if (old_format)
REICAST_US(dum); // Chans[i].ChannelNumber
}

View File

@ -390,7 +390,7 @@ void *AWCartridge::GetDmaPtr(u32 &limit)
{
limit = std::min(std::min(limit, (u32)32), dma_limit - dma_offset);
u32 offset = dma_offset / 2;
for (int i = 0; i < limit / 2; i++)
for (u32 i = 0; i < limit / 2; i++)
decrypted_buf[i] = decrypt16(offset + i);
// printf("AWCART Decrypted data @ %08x:\n", dma_offset);
@ -423,3 +423,28 @@ std::string AWCartridge::GetGameId()
return game_id;
}
void AWCartridge::Serialize(void **data, unsigned int *total_size)
{
REICAST_S(mpr_offset);
REICAST_S(mpr_bank);
REICAST_S(epr_offset);
REICAST_S(mpr_file_offset);
REICAST_S(mpr_record_index);
REICAST_S(mpr_first_file_index);
REICAST_S(dma_offset);
REICAST_S(dma_limit);
Cartridge::Serialize(data, total_size);
}
void AWCartridge::Unserialize(void **data, unsigned int *total_size)
{
REICAST_US(mpr_offset);
REICAST_US(mpr_bank);
REICAST_US(epr_offset);
REICAST_US(mpr_file_offset);
REICAST_US(mpr_record_index);
REICAST_US(mpr_first_file_index);
REICAST_US(dma_offset);
REICAST_US(dma_limit);
Cartridge::Unserialize(data, total_size);
}

View File

@ -28,6 +28,8 @@ public:
virtual std::string GetGameId() override;
void SetKey(u32 key) override;
virtual void Serialize(void **data, unsigned int *total_size) override;
virtual void Unserialize(void **data, unsigned int *total_size) override;
private:
virtual void device_reset();

View File

@ -241,10 +241,7 @@ TA_context* tactx_Find(u32 addr, bool allocnew)
return rv;
}
else
{
return 0;
}
return 0;
}
TA_context* tactx_Pop(u32 addr)
@ -285,3 +282,31 @@ void tactx_Term()
ctx_pool.clear();
mtx_pool.unlock();
}
const u32 NULL_CONTEXT = ~0u;
void SerializeTAContext(void **data, unsigned int *total_size)
{
if (ta_ctx == nullptr)
{
REICAST_S(NULL_CONTEXT);
return;
}
REICAST_S(ta_ctx->Address);
const u32 taSize = ta_tad.thd_data - ta_tad.thd_root;
REICAST_S(taSize);
REICAST_SA(ta_tad.thd_root, taSize);
}
void UnserializeTAContext(void **data, unsigned int *total_size)
{
u32 address;
REICAST_US(address);
if (address == NULL_CONTEXT)
return;
SetCurrentTARC(address);
u32 size;
REICAST_US(size);
REICAST_USA(ta_tad.thd_root, size);
ta_tad.thd_data = ta_tad.thd_root + size;
}

View File

@ -275,3 +275,5 @@ void VDecEnd();
void FillBGP(TA_context* ctx);
bool UsingAutoSort(int pass_number);
bool rend_framePending();
void SerializeTAContext(void **data, unsigned int *total_size);
void UnserializeTAContext(void **data, unsigned int *total_size);

View File

@ -5,6 +5,7 @@
TLB_Entry UTLB[64];
TLB_Entry ITLB[4];
u32 ITLB_LRU_USE[64];
//SQ fast remap , mainly hackish , assumes 1MB pages
//max 64MB can be remapped on SQ
@ -117,7 +118,6 @@ const u32 ITLB_LRU_AND[4] =
0x3E,//x1x1x0
0x3F,//xx1x11
};
u32 ITLB_LRU_USE[64];
#ifndef FAST_MMU
//sync mem mapping to mmu , suspend compiled blocks if needed.entry is a UTLB entry # , -1 is for full sync

View File

@ -129,7 +129,7 @@ void palette_update()
pal_hash_256[i] = XXH32(&PALETTE_RAM[i << 8], 256 * 4, 7);
}
std::vector<vram_block*> VramLocks[VRAM_SIZE_MAX / PAGE_SIZE];
static std::vector<vram_block*> VramLocks[VRAM_SIZE_MAX / PAGE_SIZE];
VArray2 vram; // vram 32-64b
//List functions
@ -142,12 +142,10 @@ void vramlock_list_remove(vram_block* block)
for (u32 i = base; i <= end; i++)
{
std::vector<vram_block*>& list = VramLocks[i];
for (size_t j = 0; j < list.size(); j++)
for (auto& lock : list)
{
if (list[j] == block)
{
list[j] = nullptr;
}
if (lock == block)
lock = nullptr;
}
}
}
@ -218,18 +216,17 @@ bool VramLockedWriteOffset(size_t offset)
{
std::lock_guard<std::mutex> lock(vramlist_lock);
for (size_t i = 0; i < list.size(); i++)
for (auto& lock : list)
{
if (list[i] != nullptr)
if (lock != nullptr)
{
libPvr_LockedBlockWrite(list[i], (u32)offset);
libPvr_LockedBlockWrite(lock, (u32)offset);
if (list[i] != nullptr)
if (lock != nullptr)
{
ERROR_LOG(PVR, "Error : pvr is supposed to remove lock");
die("Invalid state");
}
}
}
list.clear();
@ -250,13 +247,7 @@ bool VramLockedWrite(u8* address)
//unlocks mem
//also frees the handle
void libCore_vramlock_Unlock_block(vram_block* block)
{
std::lock_guard<std::mutex> lock(vramlist_lock);
libCore_vramlock_Unlock_block_wb(block);
}
void libCore_vramlock_Unlock_block_wb(vram_block* block)
static void libCore_vramlock_Unlock_block_wb(vram_block* block)
{
if (mmu_enabled())
vmem32_unprotect_vram(block->start, block->len);
@ -264,6 +255,12 @@ void libCore_vramlock_Unlock_block_wb(vram_block* block)
free(block);
}
void libCore_vramlock_Unlock_block(vram_block* block)
{
std::lock_guard<std::mutex> lock(vramlist_lock);
libCore_vramlock_Unlock_block_wb(block);
}
#ifndef TARGET_NO_OPENMP
static inline int getThreadCount()
{
@ -400,8 +397,12 @@ bool BaseTextureCacheData::Delete()
return false;
if (lock_block)
libCore_vramlock_Unlock_block(lock_block);
lock_block = nullptr;
{
std::lock_guard<std::mutex> lock(vramlist_lock);
if (lock_block)
libCore_vramlock_Unlock_block_wb(lock_block);
lock_block = nullptr;
}
delete[] custom_image_data;
@ -440,9 +441,11 @@ void BaseTextureCacheData::Create()
WARN_LOG(RENDERER, "Warning: planar texture with VQ set (invalid)");
//Planar textures support stride selection, mostly used for non power of 2 textures (videos)
int stride = w;
int stride = 0;
if (tcw.StrideSel)
stride = (TEXT_CONTROL & 31) * 32;
if (stride == 0)
stride = w;
//Call the format specific conversion code
texconv = tex->PL;
@ -590,7 +593,11 @@ void BaseTextureCacheData::Update()
}
else
vram_addr = sa_tex + OtherMipPoint[i] * tex->bpp / 8;
texconv32(&pb32, (u8*)&vram[vram_addr], 1 << i, 1 << i);
if (tcw.PixelFmt == PixelYUV && i == 0)
// Special case for YUV at 1x1 LoD
format[Pixel565].TW32(&pb32, &vram[vram_addr], 1, 1);
else
texconv32(&pb32, &vram[vram_addr], 1 << i, 1 << i);
}
pb32.set_mipmap(0);
}
@ -663,7 +670,8 @@ void BaseTextureCacheData::Update()
h = original_h;
//lock the texture to detect changes in it
lock_block = libCore_vramlock_Lock(sa_tex,sa+size-1,this);
if (lock_block == nullptr)
lock_block = libCore_vramlock_Lock(sa_tex,sa+size-1,this);
UploadToGPU(upscaled_w, upscaled_h, (u8*)temp_tex_buffer, mipmapped, mipmapped);
if (settings.rend.DumpTextures)

View File

@ -169,6 +169,7 @@ extern int rtc_schid;
//./core/hw/sh4/modules/serial.o
extern SCIF_SCFSR2_type SCIF_SCFSR2;
extern SCIF_SCSCR2_type SCIF_SCSCR2;
//./core/hw/sh4/modules/bsc.o
extern BSC_PDTRA_type BSC_PDTRA;
@ -188,11 +189,8 @@ extern u32 CCN_QACR_TR[2];
//./core/hw/sh4/modules/mmu.o
extern TLB_Entry UTLB[64];
extern TLB_Entry ITLB[4];
#if defined(NO_MMU)
extern u32 sq_remap[64];
#else
static u32 ITLB_LRU_USE[64];
#endif
//./core/imgread/common.o
extern u32 NullDriveDiscType;
@ -277,7 +275,7 @@ bool dc_serialize(void **data, unsigned int *total_size)
{
int i = 0;
serialize_version_enum version = V10;
serialize_version_enum version = V11;
*total_size = 0 ;
@ -381,6 +379,8 @@ bool dc_serialize(void **data, unsigned int *total_size)
REICAST_S(ta_fsm[2048]);
REICAST_S(ta_fsm_cl);
SerializeTAContext(data, total_size);
REICAST_SA(vram.data, vram.size);
REICAST_SA(OnChipRAM.data(), OnChipRAM_SIZE);
@ -474,6 +474,7 @@ bool dc_serialize(void **data, unsigned int *total_size)
#endif
REICAST_S(SCIF_SCFSR2);
REICAST_S(SCIF_SCSCR2);
REICAST_S(BSC_PDTRA);
REICAST_SA(tmu_shift,3);
@ -485,13 +486,10 @@ bool dc_serialize(void **data, unsigned int *total_size)
REICAST_SA(CCN_QACR_TR,2);
REICAST_SA(UTLB,64);
REICAST_SA(ITLB,4);
#if defined(NO_MMU)
REICAST_SA(sq_remap,64);
#else
REICAST_SA(ITLB_LRU_USE,64);
#endif
REICAST_S(UTLB);
REICAST_S(ITLB);
REICAST_S(sq_remap);
REICAST_S(ITLB_LRU_USE);
REICAST_S(NullDriveDiscType);
REICAST_SA(q_subchannel,96);
@ -519,7 +517,6 @@ bool dc_serialize(void **data, unsigned int *total_size)
REICAST_S(reg_dimm_parameterl);
REICAST_S(reg_dimm_parameterh);
REICAST_S(reg_dimm_status);
REICAST_SKIP(1); // NaomiDataRead
REICAST_S(settings.dreamcast.broadcast);
REICAST_S(settings.dreamcast.cable);
@ -566,29 +563,35 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size)
REICAST_USA(aica_reg,0x8000);
channel_unserialize(data, total_size, V9_LIBRETRO);
channel_unserialize(data, total_size, VCUR_LIBRETRO);
REICAST_USA(cdda_sector,CDDA_SIZE);
REICAST_US(cdda_index);
register_unserialize(sb_regs, data, total_size, V9_LIBRETRO) ;
register_unserialize(sb_regs, data, total_size, VCUR_LIBRETRO) ;
REICAST_US(SB_ISTNRM);
REICAST_US(SB_FFST_rc);
REICAST_US(SB_FFST);
if (settings.platform.system == DC_PLATFORM_NAOMI)
{
REICAST_US(sys_nvmem->size); // Naomi
REICAST_US(sys_nvmem->size);
REICAST_US(sys_nvmem->mask);
REICAST_USA(sys_nvmem->data, sys_nvmem->size);
}
else if (settings.platform.system == DC_PLATFORM_ATOMISWAVE)
{
REICAST_US(sys_rom->size);
REICAST_US(sys_rom->mask);
REICAST_USA(sys_rom->data, sys_rom->size);
}
else
{
REICAST_US(i);
REICAST_US(i);
}
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
if (settings.platform.system != DC_PLATFORM_NAOMI)
{
REICAST_US(sys_nvmem->size);
REICAST_US(sys_nvmem->mask);
@ -656,20 +659,22 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size)
REICAST_US(ta_fsm_cl);
pal_needs_update = true;
UnserializeTAContext(data, total_size);
REICAST_USA(vram.data, vram.size);
REICAST_USA(OnChipRAM.data(), OnChipRAM_SIZE);
register_unserialize(CCN, data, total_size, V9_LIBRETRO) ;
register_unserialize(UBC, data, total_size, V9_LIBRETRO) ;
register_unserialize(BSC, data, total_size, V9_LIBRETRO) ;
register_unserialize(DMAC, data, total_size, V9_LIBRETRO) ;
register_unserialize(CPG, data, total_size, V9_LIBRETRO) ;
register_unserialize(RTC, data, total_size, V9_LIBRETRO) ;
register_unserialize(INTC, data, total_size, V9_LIBRETRO) ;
register_unserialize(TMU, data, total_size, V9_LIBRETRO) ;
register_unserialize(SCI, data, total_size, V9_LIBRETRO) ;
register_unserialize(SCIF, data, total_size, V9_LIBRETRO) ;
register_unserialize(CCN, data, total_size, VCUR_LIBRETRO) ;
register_unserialize(UBC, data, total_size, VCUR_LIBRETRO) ;
register_unserialize(BSC, data, total_size, VCUR_LIBRETRO) ;
register_unserialize(DMAC, data, total_size, VCUR_LIBRETRO) ;
register_unserialize(CPG, data, total_size, VCUR_LIBRETRO) ;
register_unserialize(RTC, data, total_size, VCUR_LIBRETRO) ;
register_unserialize(INTC, data, total_size, VCUR_LIBRETRO) ;
register_unserialize(TMU, data, total_size, VCUR_LIBRETRO) ;
register_unserialize(SCI, data, total_size, VCUR_LIBRETRO) ;
register_unserialize(SCIF, data, total_size, VCUR_LIBRETRO) ;
icache.Reset(true);
ocache.Reset(true);
@ -744,6 +749,7 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size)
#endif
REICAST_US(SCIF_SCFSR2);
REICAST_US(SCIF_SCSCR2);
REICAST_US(BSC_PDTRA);
REICAST_USA(tmu_shift,3);
@ -755,14 +761,11 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size)
REICAST_USA(CCN_QACR_TR,2);
REICAST_USA(UTLB, 64);
REICAST_USA(ITLB, 4);
REICAST_US(UTLB);
REICAST_US(ITLB);
REICAST_US(sq_remap);
REICAST_US(ITLB_LRU_USE);
#if defined(NO_MMU)
REICAST_USA(sq_remap,64);
#else
REICAST_USA(ITLB_LRU_USE,64);
#endif
REICAST_US(NullDriveDiscType);
REICAST_USA(q_subchannel,96);
@ -823,7 +826,7 @@ bool dc_unserialize(void **data, unsigned int *total_size)
*total_size = 0 ;
REICAST_US(version) ;
if (version == V9_LIBRETRO)
if (version == VCUR_LIBRETRO)
return dc_unserialize_libretro(data, total_size);
if (version != V4 && version < V5)
{
@ -983,6 +986,8 @@ bool dc_unserialize(void **data, unsigned int *total_size)
REICAST_SKIP(4);
REICAST_SKIP(4);
}
if (version >= V11)
UnserializeTAContext(data, total_size);
REICAST_USA(vram.data, vram.size);
pal_needs_update = true;
@ -1102,6 +1107,8 @@ bool dc_unserialize(void **data, unsigned int *total_size)
REICAST_US(dum_bool); // SCIF_SCFRDR2
REICAST_US(i); // SCIF_SCFDR2
}
else if (version >= V11)
REICAST_US(SCIF_SCSCR2);
REICAST_US(BSC_PDTRA);
REICAST_USA(tmu_shift,3);
@ -1115,11 +1122,9 @@ bool dc_unserialize(void **data, unsigned int *total_size)
REICAST_USA(UTLB,64);
REICAST_USA(ITLB,4);
#if defined(NO_MMU)
REICAST_USA(sq_remap,64);
#else
if (version >= 11)
REICAST_USA(sq_remap,64);
REICAST_USA(ITLB_LRU_USE,64);
#endif
REICAST_US(NullDriveDiscType);
REICAST_USA(q_subchannel,96);
@ -1152,7 +1157,8 @@ bool dc_unserialize(void **data, unsigned int *total_size)
REICAST_US(reg_dimm_parameterl);
REICAST_US(reg_dimm_parameterh);
REICAST_US(reg_dimm_status);
REICAST_SKIP(1); // NaomiDataRead
if (version < V11)
REICAST_SKIP(1); // NaomiDataRead
if (version < V5)
{
@ -1178,8 +1184,11 @@ bool dc_unserialize(void **data, unsigned int *total_size)
REICAST_SKIP(4);
}
REICAST_US(settings.dreamcast.broadcast);
verify(settings.dreamcast.broadcast <= 4);
REICAST_US(settings.dreamcast.cable);
verify(settings.dreamcast.cable <= 3);
REICAST_US(settings.dreamcast.region);
verify(settings.dreamcast.region <= 3);
if (CurrentCartridge != NULL)
CurrentCartridge->Unserialize(data, total_size);

View File

@ -155,7 +155,6 @@ struct vram_block
//******************************************************
void libCore_vramlock_Unlock_block (vram_block* block);
void libCore_vramlock_Unlock_block_wb (vram_block* block);
vram_block* libCore_vramlock_Lock(u32 start_offset,u32 end_offset,void* userdata);
@ -595,11 +594,8 @@ enum serialize_version_enum {
V2,
V3,
V4,
V5_LIBRETRO_UNSUPPORTED,
V6_LIBRETRO_UNSUPPORTED,
V7_LIBRETRO_UNSUPPORTED,
V8_LIBRETRO_UNSUPPORTED,
V9_LIBRETRO,
V11_LIBRETRO = 10,
VCUR_LIBRETRO = V11_LIBRETRO,
V5 = 800,
V6 = 801,
@ -607,4 +603,5 @@ enum serialize_version_enum {
V8 = 803,
V9 = 804,
V10 = 805,
V11 = 806,
} ;