naomi: better error handling when loading a gdrom
x64 and arm64 dynarecs: Support 64-bit immediate readm (ninjaslt)
This commit is contained in:
parent
927298f353
commit
871260cfcf
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue