libdragon
Data Structures | Files | Defines | Typedefs | Functions
Mempak Filesystem Routines
Controller Subsystem

Managed mempak interface. More...

Data Structures

struct  entry_structure
 Structure representing a save entry in a mempak. More...

Files

file  mempak.c
 

Mempak Filesystem Routine.


file  mempak.h
 

Mempak Filesystem Routines.


Defines

#define MEMPAK_BLOCK_SIZE   256
 Size in bytes of a Mempak block.

Typedefs

typedef struct entry_structure entry_structure_t
 Structure representing a save entry in a mempak.

Functions

int read_mempak_sector (int controller, int sector, uint8_t *sector_data)
 Read a sector from a mempak.
int write_mempak_sector (int controller, int sector, uint8_t *sector_data)
 Write a sector to a mempak.
static int __validate_header (uint8_t *sector)
 Check a mempak header for validity.
static uint8_t __get_toc_checksum (uint8_t *sector)
 Calculate the checksum over a TOC sector.
static int __validate_toc (uint8_t *sector)
 Check a mempak TOC sector for validity.
static char __n64_to_ascii (char c)
 Convert a N64 mempak character to ASCII.
static char __ascii_to_n64 (char c)
 Convert an ASCII character to a N64 mempak character.
static int __validate_region (uint8_t region)
 Check a region read from a mempak entry for validity.
static int __read_note (uint8_t *tnote, entry_structure_t *note)
 Parse a note structure from a TOC.
static int __write_note (entry_structure_t *note, uint8_t *out_note)
 Create a note structure for a mempak TOC.
static int __get_num_pages (uint8_t *sector, int inode)
 Return number of pages a note occupies.
static int __get_free_space (uint8_t *sector)
 Get number of free blocks on a mempak.
static int __get_note_block (uint8_t *sector, int inode, int block)
 Get the inode of the n'th block in a note.
static int __get_valid_toc (int controller)
 Retrieve the sector number of the first valid TOC found.
int validate_mempak (int controller)
 Return whether a mempak is valid.
int get_mempak_entry (int controller, int entry, entry_structure_t *entry_data)
 Read an entry on a mempak.
int get_mempak_free_space (int controller)
 Return the number of free blocks on a mempak.
int format_mempak (int controller)
 Format a mempak.
int read_mempak_entry_data (int controller, entry_structure_t *entry, uint8_t *data)
 Read the data associated with an entry on a mempak.
int write_mempak_entry_data (int controller, entry_structure_t *entry, uint8_t *data)
 Write associated data to a mempak entry.
int delete_mempak_entry (int controller, entry_structure_t *entry)
 Delete a mempak entry and associated data.

Inode values

#define BLOCK_EMPTY   0x03
 This block is empty.
#define BLOCK_LAST   0x01
 This is the last block in the note.
#define BLOCK_VALID_FIRST   0x05
 First valid block that can contain user data.
#define BLOCK_VALID_LAST   0x7F
 Last valid block that can contain user data.

Detailed Description

Managed mempak interface.

The mempak system is a subsystem of the Controller Subsystem. Before attempting to read from or write to a mempak, be sure you have initialized the controller system with controller_init and verified that you have a mempak in the correct controller using identify_accessory.

To read and write to the mempak in an organized way compatible with official software, first check that the mempak is valid using validate_mempak. If the mempack is invalid, it will need to be formatted using format_mempak. Once the mempak is considered valid, existing notes can be enumerated using get_mempak_entry. To read the data associated with a note, use read_mempak_entry_data. To write a new note to the mempak, use write_mempak_entry_data. Note that there is no append functionality so if a note is being updated, ensure you have deleted the old note first using delete_mempak_entry. Code should be careful to check how many blocks are free before writing using get_mempak_free_space.


Function Documentation

static char __ascii_to_n64 ( char  c) [static]

Convert an ASCII character to a N64 mempak character.

If the character passed in is one that the N64 mempak doesn't support, this function will default to a space.

Parameters:
[in]cAn ASCII character
Returns:
A N64 mempak character equivalent to the ASCII character passed in
static int __get_free_space ( uint8_t *  sector) [static]

Get number of free blocks on a mempak.

Parameters:
[in]sectorA valid TOC block to examine
Returns:
The number of free blocks
static int __get_note_block ( uint8_t *  sector,
int  inode,
int  block 
) [static]

Get the inode of the n'th block in a note.

Parameters:
[in]sectorA valid TOC sector
[in]inodeThe starting inode of the note
[in]blockThe block offset (starting from 0) to retrieve
Return values:
-2if there were free blocks in the file
-3if the filesystem was invalid
Returns:
The inode of the n'th block
static int __get_num_pages ( uint8_t *  sector,
int  inode 
) [static]

Return number of pages a note occupies.

Given a starting inode and a TOC sector, walk the linked list for a note and return the number of pages/blocks/sectors a note occupies.

Parameters:
[in]sectorA TOC sector
[in]inodeA starting inode
Return values:
-2The file contained free blocks
-3The filesystem was invalid
Returns:
The number of blocks in a note
static uint8_t __get_toc_checksum ( uint8_t *  sector) [static]

Calculate the checksum over a TOC sector.

Parameters:
[in]sectorA sector containing a TOC
Returns:
The 8 bit checksum over the TOC
static int __get_valid_toc ( int  controller) [static]

Retrieve the sector number of the first valid TOC found.

Parameters:
[in]controllerThe controller (0-3) to inspect for a valid TOC
Return values:
-2the mempak was not inserted or was bad
-3the mempak was unformatted or the header was invalid
1the first sector has a valid TOC
2the second sector has a valid TOC
static char __n64_to_ascii ( char  c) [static]

Convert a N64 mempak character to ASCII.

Parameters:
[in]cA character read from a mempak entry title
Returns:
ASCII equivalent of character read
static int __read_note ( uint8_t *  tnote,
entry_structure_t note 
) [static]

Parse a note structure from a TOC.

Given a note block read from a mempak TOC, parse and return a structure representing the data.

Parameters:
[in]tnote32 bytes read from a mempak TOC
[out]noteParsed note structure
Return values:
0note was parsed properly
-1parameters were invalid
-2note inode out of bounds
-3note region invalid
static int __validate_header ( uint8_t *  sector) [static]

Check a mempak header for validity.

Parameters:
[in]sectorA sector containing a mempak header
Return values:
0if the header is valid
-1if the header is invalid
static int __validate_region ( uint8_t  region) [static]

Check a region read from a mempak entry for validity.

Parameters:
[in]regionA region read from a mempak entry
Return values:
0if the region is valid
-1if the region is invalid
static int __validate_toc ( uint8_t *  sector) [static]

Check a mempak TOC sector for validity.

Parameters:
[in]sectorA sector containing a TOC
Return values:
0if the TOC is valid
-1if the TOC is invalid
static int __write_note ( entry_structure_t note,
uint8_t *  out_note 
) [static]

Create a note structure for a mempak TOC.

Given a valid note structure, format it for writing to a mempak TOC

Parameters:
[in]noteValid note structure to convert
[out]out_note32 bytes ready to be written to a mempak TOC
Return values:
0if the note was converted properly
-1if the parameters were invalid
int delete_mempak_entry ( int  controller,
entry_structure_t entry 
)

Delete a mempak entry and associated data.

Given a valid mempak entry fetched by get_mempak_entry, removes the entry and frees all associated blocks.

Parameters:
[in]controllerThe controller (0-3) to delete the note from
[in]entryThe entry structure that is to be deleted from the mempak
Return values:
0if the entry was deleted successfully
-1if the entry was invalid
-2if the mempak was bad or not present
int format_mempak ( int  controller)

Format a mempak.

Formats a mempak. Should only be done to wipe a mempak or to initialize the filesystem in case of a blank or corrupt mempak.

Parameters:
[in]controllerThe controller (0-3) to format the mempak on
Return values:
0if the mempak was formatted successfully
-2if the mempak was not present or couldn't be formatted
int get_mempak_entry ( int  controller,
int  entry,
entry_structure_t entry_data 
)

Read an entry on a mempak.

Given an entry index (0-15), return the entry as found on the mempak. If the entry is blank or invalid, the valid flag is cleared.

Parameters:
[in]controllerThe controller (0-3) from which the entry should be read
[in]entryThe entry index (0-15) to read
[out]entry_dataStructure containing information on the entry
Return values:
0if the entry was read successfully
-1if the entry is out of bounds or entry_data is null
-2if the mempak is bad or not present
int get_mempak_free_space ( int  controller)

Return the number of free blocks on a mempak.

Note that a block is identical in size to a sector. To calculate the number of bytes free, multiply the return of this function by MEMPAK_BLOCK_SIZE.

Parameters:
[in]controllerThe controller (0-3) to read the free space from
Returns:
The number of blocks free on the memory card or a negative number on failure
int read_mempak_entry_data ( int  controller,
entry_structure_t entry,
uint8_t *  data 
)

Read the data associated with an entry on a mempak.

Given a valid mempak entry fetched by get_mempak_entry, retrieves the contents of the entry. The calling function must ensure that enough room is available in the passed in buffer for the entire entry. The entry structure itself contains the number of blocks used to store the data which can be multiplied by MEMPAK_BLOCK_SIZE to calculate the size of the buffer needed.

Parameters:
[in]controllerThe controller (0-3) to read the entry data from
[in]entryThe entry structure associated with the data to be read. An entry structure can be fetched based on index using get_mempak_entry
[out]dataThe data associated with an entry
Return values:
0if the entry was successfully read
-1if input parameters were out of bounds or the entry was corrupted somehow
-2if the mempak was not present or bad
-3if the data couldn't be read
int read_mempak_sector ( int  controller,
int  sector,
uint8_t *  sector_data 
)

Read a sector from a mempak.

This will read a sector from a mempak. Sectors on mempaks are always 256 bytes in size.

Parameters:
[in]controllerThe controller (0-3) to read a sector from
[in]sectorThe sector (0-127) to read from
[out]sector_dataBuffer to place 256 read bytes of data
Return values:
0if reading was successful
-1if the sector was out of bounds or sector_data was null
-2if there was an error reading part of a sector
int validate_mempak ( int  controller)

Return whether a mempak is valid.

This function will return whether the mempak in a particular controller is formatted and valid.

Parameters:
[in]controllerThe controller (0-3) to validate
Return values:
0if the mempak is valid and ready to be used
-2if the mempak is not present or couldn't be read
-3if the mempak is bad or unformatted
int write_mempak_entry_data ( int  controller,
entry_structure_t entry,
uint8_t *  data 
)

Write associated data to a mempak entry.

Given a mempak entry structure with a valid region, name and block count, writes the entry and associated data to the mempak. This function will not overwrite any existing user data. To update an existing entry, use delete_mempak_entry followed by write_mempak_entry_data with the same entry structure.

Parameters:
[in]controllerThe controller (0-3) to write the entry and data to
[in]entryThe entry structure containing a region, name and block count
[in]dataThe associated data to write to to the created entry
Return values:
0if the entry was created and written successfully
-1if the parameters were invalid or the note has no length
-2if the mempak wasn't present or was bad
-3if there was an error writing to the mempak
-4if there wasn't enough space to store the note
-5if there is no room in the TOC to add a new entry
int write_mempak_sector ( int  controller,
int  sector,
uint8_t *  sector_data 
)

Write a sector to a mempak.

This will write a sector to a mempak. Sectors on mempaks are always 256 bytes in size.

Parameters:
[in]controllerThe controller (0-3) to write a sector to
[in]sectorThe sector (0-127) to write to
[out]sector_dataBuffer containing 256 bytes of data to write to sector
Return values:
0if writing was successful
-1if the sector was out of bounds or sector_data was null
-2if there was an error writing part of a sector
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines