reios: fix flashrom write

Fixed language selection that was being ignored (also w/ bios)
This commit is contained in:
Flyinghead 2019-07-31 17:59:53 +02:00
parent 5913a8f11e
commit 55f76d02c0
4 changed files with 131 additions and 67 deletions

View File

@ -23,19 +23,19 @@ struct MemChip
}
virtual ~MemChip() { delete[] data; }
virtual u8 Read8(u32 addr)
u8 Read8(u32 addr)
{
return data[addr&mask];
return data[addr & mask];
}
u32 Read(u32 addr,u32 sz)
{
addr&=mask;
addr &= mask;
u32 rv=0;
u32 rv = 0;
for (u32 i=0;i<sz;i++)
rv|=Read8(addr+i)<<(i*8);
for (u32 i = 0; i < sz; i++)
rv |= Read8(addr + i) << (i * 8);
return rv;
}
@ -250,36 +250,6 @@ struct DCFlashChip : MemChip
state = FS_Normal;
}
virtual u8 Read8(u32 addr) override
{
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
{
switch (addr)
{
case 0x1A002:
case 0x1A0A2:
if (settings.dreamcast.region <= 2)
return '0' + settings.dreamcast.region;
break;
case 0x1A003:
case 0x1A0A3:
if (settings.dreamcast.language <= 5)
return '0' + settings.dreamcast.language;
break;
case 0x1A004:
case 0x1A0A4:
if (settings.dreamcast.broadcast <= 3)
return '0' + settings.dreamcast.broadcast;
break;
}
}
u32 rv=MemChip::Read8(addr);
return rv;
}
void Write(u32 addr,u32 val,u32 sz) override
{
if (sz != 1)
@ -492,6 +462,61 @@ struct DCFlashChip : MemChip
}
}
void Validate()
{
// validate partition 0 (factory settings)
bool valid = true;
char sysinfo[16];
for (int i = 0; i < sizeof(sysinfo); i++)
sysinfo[i] = Read8(0x1a000 + i);
valid = valid && memcmp(&sysinfo[5], "Dreamcast ", 11) == 0;
for (int i = 0; i < sizeof(sysinfo); i++)
sysinfo[i] = Read8(0x1a0a0 + i);
valid = valid && memcmp(&sysinfo[5], "Dreamcast ", 11) == 0;
if (!valid)
{
INFO_LOG(FLASHROM, "DCFlashChip::Validate resetting FLASH_PT_FACTORY");
memcpy(sysinfo, "00000Dreamcast ", sizeof(sysinfo));
erase_partition(FLASH_PT_FACTORY);
memcpy(data + 0x1a000, sysinfo, sizeof(sysinfo));
memcpy(data + 0x1a0a0, sysinfo, sizeof(sysinfo));
}
// validate partition 1 (reserved)
erase_partition(FLASH_PT_RESERVED);
// validate partition 2 (user settings, block allocated)
if (!validate_header(FLASH_PT_USER))
{
INFO_LOG(FLASHROM, "DCFlashChip::Validate resetting FLASH_PT_USER");
erase_partition(FLASH_PT_USER);
write_header(FLASH_PT_USER);
}
// validate partition 3 (game settings, block allocated)
if (!validate_header(FLASH_PT_GAME))
{
INFO_LOG(FLASHROM, "DCFlashChip::Validate resetting FLASH_PT_GAME");
erase_partition(FLASH_PT_GAME);
write_header(FLASH_PT_GAME);
}
// validate partition 4 (unknown, block allocated)
if (!validate_header(FLASH_PT_UNKNOWN))
{
INFO_LOG(FLASHROM, "DCFlashChip::Validate resetting FLASH_PT_UNKNOWN");
erase_partition(FLASH_PT_UNKNOWN);
write_header(FLASH_PT_UNKNOWN);
}
}
private:
int crc_block(struct flash_user_block *block)
{
@ -570,6 +595,14 @@ private:
return 1;
}
int validate_header(u32 part_id)
{
int offset, size;
GetPartitionInfo(part_id, &offset, &size);
return validate_header(offset, part_id);
}
int alloc_block(u32 offset, u32 size)
{
u8 bitmap[FLASH_BLOCK_SIZE];
@ -655,4 +688,26 @@ private:
REICAST_USA(&this->data[write_protect_size], size - write_protect_size);
return true;
}
void erase_partition(u32 part_id)
{
int offset, size;
GetPartitionInfo(part_id, &offset, &size);
memset(data + offset, 0xFF, size);
}
void write_header(int part_id)
{
int offset, size;
GetPartitionInfo(part_id, &offset, &size);
struct flash_header_block header;
memset(&header, 0xff, sizeof(header));
memcpy(header.magic, FLASH_MAGIC_COOKIE, sizeof(header.magic));
header.part_id = part_id;
header.version = 0;
write_physical_block(offset, 0, &header);
}
};

View File

@ -74,20 +74,30 @@ bool LoadRomFiles(const string& root)
else
rc = sys_nvmem->Load(get_game_save_prefix() + ".nvmem");
if (!rc)
{
if (nvmemOptional())
{
INFO_LOG(FLASHROM, "flash/nvmem is missing, will create new file...");
}
else
{
msgboxf("Unable to find flash/nvmem in %s. Exiting...", MBX_ICONERROR, root.c_str());
return false;
}
}
INFO_LOG(FLASHROM, "flash/nvmem is missing, will create new file...");
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
{
static_cast<DCFlashChip*>(sys_nvmem)->Validate();
// overwrite factory flash settings
if (settings.dreamcast.region <= 2)
{
sys_nvmem->data[0x1a002] = '0' + settings.dreamcast.region;
sys_nvmem->data[0x1a0a2] = '0' + settings.dreamcast.region;
}
if (settings.dreamcast.language <= 5)
{
sys_nvmem->data[0x1a003] = '0' + settings.dreamcast.language;
sys_nvmem->data[0x1a0a3] = '0' + settings.dreamcast.language;
}
if (settings.dreamcast.broadcast <= 3)
{
sys_nvmem->data[0x1a004] = '0' + settings.dreamcast.broadcast;
sys_nvmem->data[0x1a0a4] = '0' + settings.dreamcast.broadcast;
}
// overwrite user settings
struct flash_syscfg_block syscfg;
int res = static_cast<DCFlashChip*>(sys_nvmem)->ReadBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg);

View File

@ -140,7 +140,6 @@ void GD_HLE_Command(u32 cc, u32 prm)
break;
case GDCC_GETSES:
debugf("GDROM: GETSES CC:%X PRM:%X", cc, prm);
GDROM_HLE_ReadSES(prm);
break;
@ -153,7 +152,6 @@ void GD_HLE_Command(u32 cc, u32 prm)
break;
case GDCC_DMAREAD:
debugf("GDROM: CMD DMAREAD CC:%X PRM:%X", cc, prm);
GDROM_HLE_ReadDMA(prm);
break;
@ -194,7 +192,6 @@ void GD_HLE_Command(u32 cc, u32 prm)
break;
case GDCC_GETSCD:
debugf("GDROM: GETSCD CC:%X PRM:%X",cc,prm);
GDCC_HLE_GETSCD(prm);
break;
@ -318,7 +315,7 @@ void gdrom_hle_op()
switch(r[7]) // COMMAND CODE
{
case GDROM_SEND_COMMAND: // SEND GDROM COMMAND RET: - if failed + req id
debugf("GDROM: HLE SEND COMMAND CC:%X param ptr: %X", r[4], r[5]);
//debugf("GDROM: HLE SEND COMMAND CC:%X param ptr: %X", r[4], r[5]);
memset(bios_result, 0, sizeof(bios_result));
LastCommandId = r[0] = NextCommandId++; // Request Id
GD_HLE_Command(r[4], r[5]);
@ -337,7 +334,7 @@ void gdrom_hle_op()
{
r[0] = 2; // Finished
}
debugf("GDROM: HLE CHECK COMMAND REQID:%X param ptr: %X -> %X", r[4], r[5], r[0]);
//debugf("GDROM: HLE CHECK COMMAND REQID:%X param ptr: %X -> %X", r[4], r[5], r[0]);
LastCommandId = 0xFFFFFFFF; // INVALIDATE CHECK CMD
WriteMem32(r[5], bios_result[0]);
WriteMem32(r[5] + 4, bios_result[1]);

View File

@ -259,16 +259,12 @@ static void reios_sys_flashrom() {
case 0: // FLASHROM_INFO
{
/*
r4 = partition number(0 - 4)
r5 = pointer to two 32 bit integers to receive the result.
The first will be the offset of the partition start, in bytes from the start of the flashrom.
The second will be the size of the partition, in bytes.
#define FLASHROM_PT_SYSTEM 0 /< \brief Factory settings (read-only, 8K)
#define FLASHROM_PT_RESERVED 1 /< \brief reserved (all 0s, 8K)
#define FLASHROM_PT_BLOCK_1 2 /< \brief Block allocated (16K)
#define FLASHROM_PT_SETTINGS 3 /< \brief Game settings (block allocated, 32K)
#define FLASHROM_PT_BLOCK_2 4 /< \brief Block allocated (64K)
r4 = partition number(0 - 4)
r5 = pointer to two 32 bit integers to receive the result.
The first will be the offset of the partition start, in bytes from the start of the flashrom.
The second will be the size of the partition, in bytes.
returns:
r0 = 0 if partition found, -1 if error or not found
*/
u32 part = Sh4cntx.r[4];
@ -291,9 +287,11 @@ static void reios_sys_flashrom() {
case 1: //FLASHROM_READ
{
/*
r4 = read start position, in bytes from the start of the flashrom
r5 = pointer to destination buffer
r6 = number of bytes to read
r4 = read start position, in bytes from the start of the flashrom
r5 = pointer to destination buffer
r6 = number of bytes to read
returns:
r0 = number of bytes read
*/
u32 offset = Sh4cntx.r[4];
u32 dest = Sh4cntx.r[5];
@ -314,6 +312,8 @@ static void reios_sys_flashrom() {
r4 = write start position, in bytes from the start of the flashrom
r5 = pointer to source buffer
r6 = number of bytes to write
returns:
r0 = number of bytes written
*/
u32 offs = Sh4cntx.r[4];
@ -323,14 +323,16 @@ static void reios_sys_flashrom() {
debugf("reios_sys_flashrom: FLASHROM_WRITE offs %x src %08x size %x", offs, src, size);
u8* pSrc = GetMemPtr(src, size);
for (int i = 0; i < size; i++) {
for (int i = 0; i < size; i++)
flashrom->data[offs + i] &= pSrc[i];
}
Sh4cntx.r[0] = size;
}
break;
case 3: //FLASHROM_DELETE
{
// offset of partition to delete
u32 offset = Sh4cntx.r[4];
debugf("reios_sys_flashrom: FLASHROM_DELETE offs %x", offset);