Home | Forums | What's new | Resources | |
Algorithm Advice: Read Saturn Save without Malloc() |
slinga - Jun 15, 2023 |
slinga | Jun 15, 2023 | ||||
Still working on libslinga (GitHub - slinga-homebrew/libslinga: Sega Saturn sa...). I'm trying to think of an algorithm to read a Sega Saturn save file without the need for malloc(), large stack space, or a large global buffer. For Save Game Copier I used jo_malloc() to allocate a buffer to store the block ids. With libslinga I am not assuming I have access to malloc(). The official BUP library preallocated a large section of memory (4k bytes?) to use for this table. Additional information: - Save-Game-Copier/backends/sat.h at master · sling... - Save-Game-Copier/backends/sat.c at master · sling... - getSatBlocks() reads the block IDs into a dynamically allocated buffer. getSATSave() reads the save by walking the list of block IDs.
C:
*// -- to complicate matters, the block ids themselves can extend into multiple blocks. This makes computing the block count tricky* this is what makes parsing the SAT table tricky. In SGC I reduced the complexity by just reading the entire table into a dynamically allocated array and working with that. Assuming a maximum save of ~32k for internal memory -- by my calculations 29,548 byte save will take 510 blocks. 2 blocks are overhead. 512 blocks x 64 bytes per block = 32k. -- 510 blocks * 2 bytes each = 1020 bytes for the SAT table. Assuming a maximum save of 256k: - I need 4,521 blocks - 4,521 * 2 = 9,042 bytes for the sat table I'm trying to think of an algorithm to read the SAT blocks without having to allocate the SAT table. I think there might be something to reading the save backwards, but I haven't come up with an algorithm yet. I will also need the reverse to be able to write a save as well. I plan to think hard this weekend. |
slinga | Jun 23, 2023 | |||
I ended up going with a large (1024 bitmap). I checked in my code to GitHub - slinga-homebrew/libslinga: Sega Saturn sa.... The basic idea is each bit in the bitmap represents a block on the partition. g_SAT_bitmap[] is a large bitmap used to store free\busy blocks each bitmap represents a single block Internal memory - 0x8000 partition size - 0x40 block size - bytes needed = 0x8000 / 0x40 / 8 (bits per byte) = 0x40 (64) bytes 32 Mb Cartridge - 0x400000 partition size - 0x400 block size - bytes needed - 0x400000 / 0x400 / 8 (bits per byte_ = 0x200 (512) bytes Action Replay - 0x80000 partition size - 0x40 block size - bytes needed = 0x80000 / 0x40 / 8 (bits per byte) = 0x400 (1024) bytes This means we need a 1024 byte buffer to support the Action Replay. I can play around with #defs to reduce the size to 512 (or 64) depending on which devices are compiled in. |