naomi: better error handling when loading a gdrom

x64 and arm64 dynarecs: Support 64-bit immediate readm (ninjaslt)
This commit is contained in:
Flyinghead 2019-06-26 19:06:30 +02:00
parent 927298f353
commit 871260cfcf
5 changed files with 134 additions and 52 deletions

View File

@ -507,7 +507,8 @@ void GDCartridge::device_start()
if (gdrom == NULL)
gdrom = OpenDisc((gdrom_path + ".gdi").c_str());
if (gdrom == NULL)
return;
throw NaomiCartException("Naomi GDROM: Cannot open " + gdrom_path + ".chd or " + gdrom_path + ".gdi");
// primary volume descriptor
// read frame 0xb06e (frame=sector+150)
// dimm board firmware starts straight from this frame
@ -564,6 +565,7 @@ void GDCartridge::device_start()
u32 file_rounded_size = (file_size + 2047) & -2048;
for (dimm_data_size = 4096; dimm_data_size < file_rounded_size; dimm_data_size <<= 1);
dimm_data = (u8 *)malloc(dimm_data_size);
verify(dimm_data != NULL);
if (dimm_data_size != file_rounded_size)
memset(dimm_data + file_rounded_size, 0, dimm_data_size - file_rounded_size);
@ -583,7 +585,7 @@ void GDCartridge::device_start()
delete gdrom;
if (!dimm_data)
printf("Naomi GDROM: Could not find the file to decrypt.\n");
throw NaomiCartException("Naomi GDROM: Could not find the file to decrypt.");
}
}
@ -593,6 +595,8 @@ void GDCartridge::device_reset()
}
void *GDCartridge::GetDmaPtr(u32 &size)
{
if (dimm_data == NULL)
return NULL;
dimm_cur_address = DmaOffset & (dimm_data_size-1);
size = min(size, dimm_data_size - dimm_cur_address);
return dimm_data + dimm_cur_address;
@ -607,6 +611,11 @@ void GDCartridge::AdvancePtr(u32 size)
bool GDCartridge::Read(u32 offset, u32 size, void *dst)
{
if (dimm_data == NULL)
{
*(u32 *)dst = 0;
return true;
}
u32 addr = offset & (dimm_data_size-1);
memcpy(dst, &dimm_data[addr], min(size, dimm_data_size - addr));
return true;

View File

@ -331,7 +331,12 @@ static bool naomi_cart_LoadZip(char *filename)
if (parent_archive != NULL)
delete parent_archive;
CurrentCartridge->Init();
try {
CurrentCartridge->Init();
} catch (NaomiCartException& e) {
printf("%s\n", e.reason.c_str());
return false;
}
strcpy(naomi_game_id, CurrentCartridge->GetGameId().c_str());
printf("NAOMI GAME ID [%s]\n", naomi_game_id);
@ -604,6 +609,7 @@ void naomi_cart_Close()
delete[] RomCacheMap;
RomCacheMap = NULL;
}
bios_loaded = false;
}
bool naomi_cart_SelectFile()

View File

@ -78,6 +78,14 @@ private:
u8 naomi_cart_ram[64 * 1024];
};
class NaomiCartException
{
public:
NaomiCartException(std::string reason) : reason(reason) {}
std::string reason;
};
bool naomi_cart_SelectFile();
void naomi_cart_Close();

View File

@ -1639,18 +1639,28 @@ private:
return false;
u32 paddr;
u32 rv;
if (size == 2)
switch (size)
{
case 1:
rv = mmu_data_translation<MMU_TT_DREAD, u8>(addr, paddr);
break;
case 2:
rv = mmu_data_translation<MMU_TT_DREAD, u16>(addr, paddr);
else if (size == 4)
break;
case 4:
case 8:
rv = mmu_data_translation<MMU_TT_DREAD, u32>(addr, paddr);
else
break;
default:
die("Invalid immediate size");
break;
}
if (rv != MMU_ERROR_NONE)
return false;
addr = paddr;
}
bool isram = false;
void* ptr = _vmem_read_const(addr, isram, size);
void* ptr = _vmem_read_const(addr, isram, size > 4 ? 4 : size);
if (isram)
{
@ -1712,35 +1722,50 @@ private:
else
{
// Not RAM
Mov(w0, addr);
switch(size)
if (size == 8)
{
case 1:
verify(!regalloc.IsAllocAny(op.rd));
// Need to call the handler twice
Mov(w0, addr);
GenCallRuntime((void (*)())ptr);
Sxtb(w0, w0);
break;
Str(w0, sh4_context_mem_operand(op.rd.reg_ptr()));
case 2:
Mov(w0, addr + 4);
GenCallRuntime((void (*)())ptr);
Sxth(w0, w0);
break;
case 4:
GenCallRuntime((void (*)())ptr);
break;
case 8:
die("SZ_64F not supported");
break;
Str(w0, sh4_context_mem_operand((u8*)op.rd.reg_ptr() + 4));
}
if (regalloc.IsAllocg(op.rd))
Mov(regalloc.MapRegister(op.rd), w0);
else
{
verify(regalloc.IsAllocf(op.rd));
Fmov(regalloc.MapVRegister(op.rd), w0);
Mov(w0, addr);
switch(size)
{
case 1:
GenCallRuntime((void (*)())ptr);
Sxtb(w0, w0);
break;
case 2:
GenCallRuntime((void (*)())ptr);
Sxth(w0, w0);
break;
case 4:
GenCallRuntime((void (*)())ptr);
break;
default:
die("Invalid size");
break;
}
if (regalloc.IsAllocg(op.rd))
Mov(regalloc.MapRegister(op.rd), w0);
else
{
verify(regalloc.IsAllocf(op.rd));
Fmov(regalloc.MapVRegister(op.rd), w0);
}
}
}
@ -1848,13 +1873,16 @@ private:
case 8:
rv = mmu_data_translation<MMU_TT_DWRITE, u32>(addr, paddr);
break;
default:
die("Invalid immediate size");
break;
}
if (rv != MMU_ERROR_NONE)
return false;
addr = paddr;
}
bool isram = false;
void* ptr = _vmem_write_const(addr, isram, size);
void* ptr = _vmem_write_const(addr, isram, size > 4 ? 4 : size);
Register reg2;
if (op.rs2.is_imm())

View File

@ -1517,19 +1517,29 @@ private:
u32 paddr;
u32 rv;
if (size == 2)
switch (size)
{
case 1:
rv = mmu_data_translation<MMU_TT_DREAD, u8>(addr, paddr);
break;
case 2:
rv = mmu_data_translation<MMU_TT_DREAD, u16>(addr, paddr);
else if (size == 4)
break;
case 4:
case 8:
rv = mmu_data_translation<MMU_TT_DREAD, u32>(addr, paddr);
else
break;
default:
die("Invalid immediate size");
break;
}
if (rv != MMU_ERROR_NONE)
return false;
addr = paddr;
}
bool isram = false;
void* ptr = _vmem_read_const(addr, isram, size);
void* ptr = _vmem_read_const(addr, isram, size > 4 ? 4 : size);
if (isram)
{
@ -1597,29 +1607,47 @@ private:
else
{
// Not RAM: the returned pointer is a memory handler
mov(call_regs[0], addr);
switch(size)
if (size == 8)
{
case 1:
GenCall((void (*)())ptr);
movsx(eax, al);
break;
verify(!regalloc.IsAllocAny(op.rd));
case 2:
// Need to call the handler twice
mov(call_regs[0], addr);
GenCall((void (*)())ptr);
movsx(eax, ax);
break;
mov(rcx, (size_t)op.rd.reg_ptr());
mov(dword[rcx], eax);
case 4:
mov(call_regs[0], addr + 4);
GenCall((void (*)())ptr);
break;
default:
die("Invalid immediate size");
break;
mov(rcx, (size_t)op.rd.reg_ptr() + 4);
mov(dword[rcx], eax);
}
else
{
mov(call_regs[0], addr);
switch(size)
{
case 1:
GenCall((void (*)())ptr);
movsx(eax, al);
break;
case 2:
GenCall((void (*)())ptr);
movsx(eax, ax);
break;
case 4:
GenCall((void (*)())ptr);
break;
default:
die("Invalid immediate size");
break;
}
host_reg_to_shil_param(op.rd, eax);
}
host_reg_to_shil_param(op.rd, eax);
}
return true;
@ -1651,6 +1679,9 @@ private:
case 8:
rv = mmu_data_translation<MMU_TT_DWRITE, u32>(addr, paddr);
break;
default:
die("Invalid immediate size");
break;
}
if (rv != MMU_ERROR_NONE)
return false;
@ -1658,7 +1689,7 @@ private:
addr = paddr;
}
bool isram = false;
void* ptr = _vmem_write_const(addr, isram, size);
void* ptr = _vmem_write_const(addr, isram, size > 4 ? 4 : size);
if (isram)
{