use crate::device; use crate::ui; pub const MEMPAK_SIZE: usize = 0x8000; const MPK_PAGE_SIZE: usize = 256; pub fn format_mempak(device: &mut device::Device) { if device.ui.storage.saves.mempak.data.len() < MEMPAK_SIZE * 4 { device .ui .storage .saves .mempak .data .resize(MEMPAK_SIZE * 4, 0); let page_0: [u8; MPK_PAGE_SIZE] = [ /* Label area */ 0x81, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* Main ID area */ 0xff, 0xff, 0xff, 0xff, 0x05, 0x1a, 0x5f, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0x66, 0x25, 0x99, 0xcd, /* Unused */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ID area backup #1 */ 0xff, 0xff, 0xff, 0xff, 0x05, 0x1a, 0x5f, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0x66, 0x25, 0x99, 0xcd, /* ID area backup #2 */ 0xff, 0xff, 0xff, 0xff, 0x05, 0x1a, 0x5f, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0x66, 0x25, 0x99, 0xcd, /* Unused */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ID area backup #3 */ 0xff, 0xff, 0xff, 0xff, 0x05, 0x1a, 0x5f, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0x66, 0x25, 0x99, 0xcd, /* Unused */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]; for i in 0..4 { let offset = i * MEMPAK_SIZE; if device.ui.storage.saves.mempak.data[offset..offset + MEMPAK_SIZE] != [0; MEMPAK_SIZE] { // don't overwrite existing data continue; } /* Fill Page 0 with pre-initialized content */ device.ui.storage.saves.mempak.data[offset..offset + MPK_PAGE_SIZE] .copy_from_slice(&page_0); /* Fill INODE page 1 and update it's checkum */ let start_page = 5; for i in MPK_PAGE_SIZE..2 * start_page { device.ui.storage.saves.mempak.data[offset + i] = 0; } for i in (MPK_PAGE_SIZE + 2 * start_page..2 * MPK_PAGE_SIZE).step_by(2) { device.ui.storage.saves.mempak.data[offset + i] = 0x00; device.ui.storage.saves.mempak.data[offset + i + 1] = 0x03; } device.ui.storage.saves.mempak.data[offset + (MPK_PAGE_SIZE + 1)] = 0x71; /* Page 2 is identical to page 1 */ let page1 = offset + MPK_PAGE_SIZE; let page2 = offset + 2 * MPK_PAGE_SIZE; let page1data = device.ui.storage.saves.mempak.data[page1..page1 + MPK_PAGE_SIZE].to_vec(); device.ui.storage.saves.mempak.data[page2..page2 + MPK_PAGE_SIZE] .copy_from_slice(&page1data); /* Remaining pages DIR+DATA (3...) are initialized with 0x00 */ for i in 3 * MPK_PAGE_SIZE..MEMPAK_SIZE - 3 * MPK_PAGE_SIZE { device.ui.storage.saves.mempak.data[offset + i] = 0; } } } } pub fn read(device: &mut device::Device, channel: usize, address: u16, data: usize, size: usize) { if (address as usize) < MEMPAK_SIZE { let offset = (channel * MEMPAK_SIZE) + address as usize; device.pif.ram[data..data + size] .copy_from_slice(&device.ui.storage.saves.mempak.data[offset..offset + size]) } else { for i in 0..size { device.pif.ram[data + i] = 0; } } } pub fn write(device: &mut device::Device, channel: usize, address: u16, data: usize, size: usize) { if (address as usize) < MEMPAK_SIZE { let offset = (channel * MEMPAK_SIZE) + address as usize; device.ui.storage.saves.mempak.data[offset..offset + size] .copy_from_slice(&device.pif.ram[data..data + size]); ui::storage::schedule_save(device, ui::storage::SaveTypes::Mempak); } }