mirror of
https://github.com/Lorenzooone/Pokemon-Gen3-to-Gen-X.git
synced 2026-03-21 17:24:39 -05:00
Improve worst case saving speeds
This commit is contained in:
parent
2a3bd9b97f
commit
c3ee0e7ed9
160
source/save.c
160
source/save.c
|
|
@ -31,14 +31,15 @@
|
|||
#define BANK_LIMIT (NUM_BANKS * BANK_SIZE)
|
||||
#endif
|
||||
|
||||
uintptr_t bank_check(uintptr_t);
|
||||
static uintptr_t bank_check(uintptr_t);
|
||||
static size_t sanitize_save_size(uintptr_t, size_t);
|
||||
static u8 read_direct_single_byte_save(uintptr_t);
|
||||
static void write_direct_single_byte_save(uintptr_t, u8);
|
||||
|
||||
u8 current_bank;
|
||||
u8 is_macronix;
|
||||
|
||||
IWRAM_CODE void init_bank(){
|
||||
IWRAM_CODE void init_bank() {
|
||||
REG_WAITCNT &= NON_SRAM_MASK;
|
||||
REG_WAITCNT |= SRAM_READING_VALID_WAITCYCLES;
|
||||
current_bank = NUM_BANKS;
|
||||
|
|
@ -54,7 +55,7 @@ IWRAM_CODE void init_bank(){
|
|||
#endif
|
||||
}
|
||||
|
||||
IWRAM_CODE uintptr_t bank_check(uintptr_t address){
|
||||
IWRAM_CODE uintptr_t bank_check(uintptr_t address) {
|
||||
address %= (NUM_BANKS * BANK_SIZE);
|
||||
#if IS_FLASH
|
||||
u8 bank = address / BANK_SIZE;
|
||||
|
|
@ -114,103 +115,110 @@ IWRAM_CODE void write_direct_single_byte_save(uintptr_t address, u8 data) {
|
|||
}
|
||||
}
|
||||
|
||||
IWRAM_CODE u8 read_byte_save(uintptr_t address){
|
||||
IWRAM_CODE u8 read_byte_save(uintptr_t address) {
|
||||
address = bank_check(address);
|
||||
return read_direct_single_byte_save(address);
|
||||
}
|
||||
|
||||
IWRAM_CODE void write_byte_save(uintptr_t address, u8 data){
|
||||
IWRAM_CODE u16 read_short_save(uintptr_t address) {
|
||||
u16 data_out = 0;
|
||||
copy_save_to_ram(address, (u8*)&data_out, sizeof(u16));
|
||||
return data_out;
|
||||
}
|
||||
|
||||
IWRAM_CODE u32 read_int_save(uintptr_t address) {
|
||||
u32 data_out = 0;
|
||||
copy_save_to_ram(address, (u8*)&data_out, sizeof(u32));
|
||||
return data_out;
|
||||
}
|
||||
|
||||
IWRAM_CODE void write_byte_save(uintptr_t address, u8 data) {
|
||||
address = bank_check(address);
|
||||
write_direct_single_byte_save(address, data);
|
||||
}
|
||||
|
||||
IWRAM_CODE u32 read_int_save(uintptr_t address){
|
||||
IWRAM_CODE void write_short_save(uintptr_t address, u16 data) {
|
||||
u16 data_in = data;
|
||||
copy_ram_to_save((u8*)&data_in, address, sizeof(u16));
|
||||
}
|
||||
|
||||
IWRAM_CODE void write_int_save(uintptr_t address, u32 data) {
|
||||
u32 data_in = data;
|
||||
copy_ram_to_save((u8*)&data_in, address, sizeof(u32));
|
||||
}
|
||||
|
||||
IWRAM_CODE size_t sanitize_save_size(uintptr_t address, size_t size) {
|
||||
address %= NUM_BANKS * BANK_SIZE;
|
||||
if((address + size) > (NUM_BANKS * BANK_SIZE))
|
||||
size = (NUM_BANKS * BANK_SIZE) - address;
|
||||
return size;
|
||||
}
|
||||
|
||||
IWRAM_CODE void copy_save_to_ram(uintptr_t address, u8* destination, size_t size) {
|
||||
// Sanitize size
|
||||
size = sanitize_save_size(address, size);
|
||||
|
||||
address = bank_check(address);
|
||||
u32 data_out = 0;
|
||||
if((address + sizeof(u32)) > BANK_LIMIT) {
|
||||
for(size_t i = 0; i < sizeof(u32); i++)
|
||||
data_out += read_byte_save(address + i) << (i*8);
|
||||
}
|
||||
else {
|
||||
for(size_t i = 0; i < sizeof(u32); i++)
|
||||
data_out += read_direct_single_byte_save(address + i) << (i*8);
|
||||
}
|
||||
return data_out;
|
||||
}
|
||||
size_t num_banks = (address + size + BANK_SIZE - 1) / BANK_SIZE;
|
||||
for(size_t n = 0; n < num_banks; n++) {
|
||||
size_t inner_size = size;
|
||||
if(n != (num_banks - 1))
|
||||
inner_size = BANK_SIZE - address;
|
||||
|
||||
IWRAM_CODE u16 read_short_save(uintptr_t address){
|
||||
address = bank_check(address);
|
||||
u16 data_out = 0;
|
||||
if((address + sizeof(u16)) > BANK_LIMIT) {
|
||||
for(size_t i = 0; i < sizeof(u16); i++)
|
||||
data_out += read_byte_save(address + i) << (i*8);
|
||||
}
|
||||
else {
|
||||
for(size_t i = 0; i < sizeof(u16); i++)
|
||||
data_out += read_direct_single_byte_save(address + i) << (i*8);
|
||||
}
|
||||
return data_out;
|
||||
}
|
||||
for(size_t i = 0; i < inner_size; i++)
|
||||
destination[i] = read_direct_single_byte_save(address + i);
|
||||
|
||||
IWRAM_CODE void write_int_save(uintptr_t address, u32 data){
|
||||
address = bank_check(address);
|
||||
if((address + sizeof(u32)) > BANK_LIMIT) {
|
||||
for(size_t i = 0; i < sizeof(u32); i++)
|
||||
write_byte_save(address + i, (data >> (i*8)) & 0xFF);
|
||||
}
|
||||
else {
|
||||
for(size_t i = 0; i < sizeof(u32); i++)
|
||||
write_direct_single_byte_save(address + i, (data >> (i*8)) & 0xFF);
|
||||
if(n != (num_banks - 1)) {
|
||||
address = bank_check(address + inner_size);
|
||||
destination += inner_size;
|
||||
size -= inner_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IWRAM_CODE void write_short_save(uintptr_t address, u16 data){
|
||||
address = bank_check(address);
|
||||
if((address + sizeof(u16)) > BANK_LIMIT) {
|
||||
for(size_t i = 0; i < sizeof(u16); i++)
|
||||
write_byte_save(address + i, (data >> (i*8)) & 0xFF);
|
||||
}
|
||||
else {
|
||||
for(size_t i = 0; i < sizeof(u16); i++)
|
||||
write_direct_single_byte_save(address + i, (data >> (i*8)) & 0xFF);
|
||||
}
|
||||
}
|
||||
IWRAM_CODE void copy_ram_to_save(u8* base_address, uintptr_t save_address, size_t size) {
|
||||
// Sanitize size
|
||||
size = sanitize_save_size(save_address, size);
|
||||
|
||||
IWRAM_CODE void copy_save_to_ram(uintptr_t base_address, u8* new_address, size_t size){
|
||||
base_address = bank_check(base_address);
|
||||
if((base_address + size) > BANK_LIMIT) {
|
||||
for(size_t i = 0; i < size; i++)
|
||||
new_address[i] = read_byte_save(base_address + i);
|
||||
}
|
||||
else {
|
||||
for(size_t i = 0; i < size; i++)
|
||||
new_address[i] = read_direct_single_byte_save(base_address + i);
|
||||
}
|
||||
}
|
||||
|
||||
IWRAM_CODE void copy_ram_to_save(u8* base_address, uintptr_t save_address, size_t size){
|
||||
save_address = bank_check(save_address);
|
||||
if((save_address + size) > BANK_LIMIT) {
|
||||
for(size_t i = 0; i < size; i++)
|
||||
write_byte_save(save_address + i, base_address[i]);
|
||||
}
|
||||
else {
|
||||
for(size_t i = 0; i < size; i++)
|
||||
size_t num_banks = (save_address + size + BANK_SIZE - 1) / BANK_SIZE;
|
||||
for(size_t n = 0; n < num_banks; n++) {
|
||||
size_t inner_size = size;
|
||||
if(n != (num_banks - 1))
|
||||
inner_size = BANK_SIZE - save_address;
|
||||
|
||||
for(size_t i = 0; i < inner_size; i++)
|
||||
write_direct_single_byte_save(save_address + i, base_address[i]);
|
||||
|
||||
if(n != (num_banks - 1)) {
|
||||
save_address = bank_check(save_address + inner_size);
|
||||
base_address += inner_size;
|
||||
size -= inner_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IWRAM_CODE u8 is_save_correct(u8* base_address, uintptr_t save_address, size_t size) {
|
||||
// Sanitize size
|
||||
size = sanitize_save_size(save_address, size);
|
||||
|
||||
save_address = bank_check(save_address);
|
||||
if((save_address + size) > BANK_LIMIT) {
|
||||
for(size_t i = 0; i < size; i++)
|
||||
if(read_byte_save(save_address + i) != base_address[i])
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
for(size_t i = 0; i < size; i++)
|
||||
size_t num_banks = (save_address + size + BANK_SIZE - 1) / BANK_SIZE;
|
||||
for(size_t n = 0; n < num_banks; n++) {
|
||||
size_t inner_size = size;
|
||||
if(n != (num_banks - 1))
|
||||
inner_size = BANK_SIZE - save_address;
|
||||
|
||||
for(size_t i = 0; i < inner_size; i++)
|
||||
if(read_direct_single_byte_save(save_address + i) != base_address[i])
|
||||
return 0;
|
||||
|
||||
if(n != (num_banks - 1)) {
|
||||
save_address = bank_check(save_address + inner_size);
|
||||
base_address += inner_size;
|
||||
size -= inner_size;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user