|
libjoybus
Joybus implementation for 32-bit MCUs
|
N64 pak implementation which emulates a Controller Pak, the battery backed save memory that plugs into a controller. More...
Data Structures | |
| struct | joybus_target_n64_pak_controller |
| N64 Controller Pak pak. More... | |
Macros | |
| #define | JOYBUS_TARGET_N64_PAK_CONTROLLER(pak) |
| Macro to cast from a generic N64 pak to a controller pak. | |
Typedefs | |
| typedef int(* | joybus_target_n64_pak_controller_read_cb) (struct joybus_target_n64_pak_controller *pak, uint8_t bank, uint16_t addr, uint8_t buf[JOYBUS_N64_PAK_BLOCK_SIZE]) |
| Callback type for reading a block of a bank. | |
| typedef int(* | joybus_target_n64_pak_controller_write_cb) (struct joybus_target_n64_pak_controller *pak, uint8_t bank, uint16_t addr, const uint8_t buf[JOYBUS_N64_PAK_BLOCK_SIZE]) |
| Callback type for writing a block of a bank. | |
| typedef void(* | joybus_target_n64_pak_controller_select_cb) (struct joybus_target_n64_pak_controller *pak, uint8_t bank) |
| Callback type for bank select events. | |
| typedef void(* | joybus_target_n64_pak_controller_written_cb) (struct joybus_target_n64_pak_controller *pak, uint8_t bank, uint16_t addr) |
| Callback type for block written events, fired after storage has taken a write. | |
Functions | |
| void | joybus_target_n64_pak_controller_init (struct joybus_target_n64_pak_controller *pak, uint8_t banks) |
| Initialize a controller pak. | |
| void | joybus_target_n64_pak_controller_set_storage (struct joybus_target_n64_pak_controller *pak, joybus_target_n64_pak_controller_read_cb read, joybus_target_n64_pak_controller_write_cb write, void *user_data) |
| Set the storage behind the pak. | |
| void | joybus_target_n64_pak_controller_set_memory (struct joybus_target_n64_pak_controller *pak, uint8_t *memory) |
| Back the pak with memory, banks x JOYBUS_N64_PAK_BANK_SIZE bytes owned by the caller. | |
| void | joybus_target_n64_pak_controller_set_select_cb (struct joybus_target_n64_pak_controller *pak, joybus_target_n64_pak_controller_select_cb callback) |
| Set the bank select callback for the controller pak. | |
| void | joybus_target_n64_pak_controller_set_written_cb (struct joybus_target_n64_pak_controller *pak, joybus_target_n64_pak_controller_written_cb callback) |
| Set the block written callback for the controller pak. | |
N64 pak implementation which emulates a Controller Pak, the battery backed save memory that plugs into a controller.
The pak behaviour lives here, and the storage behind it is a pair of block callbacks, or a buffer for the simple case.
An original pak is one 32 KB bank, which a console formats and mounts on its own. Larger third party paks hold several banks and present one at a time, switched by a write to the probe area at 0x8000. A banked pak from this target must be formatted with joybus_n64_pak_fs_format() before use. A select past the last bank is ignored, which keeps an accessory probe from moving the bank but also stops a console counting the banks of a blank pak.
A write to an ID block that names another bank count is refused with a transfer error, so the pak cannot be reformatted to a different shape.
| #define JOYBUS_TARGET_N64_PAK_CONTROLLER | ( | pak | ) |
Macro to cast from a generic N64 pak to a controller pak.
| typedef int(* joybus_target_n64_pak_controller_read_cb) (struct joybus_target_n64_pak_controller *pak, uint8_t bank, uint16_t addr, uint8_t buf[JOYBUS_N64_PAK_BLOCK_SIZE]) |
Callback type for reading a block of a bank.
Runs in interrupt context, on the response critical path, so it must return quickly. Mark the implementation with JOYBUS_RAM_FUNC.
| pak | the controller pak being read from |
| bank | the bank the console has selected |
| addr | block-aligned address within the bank, below 0x8000 |
| buf | destination buffer, exactly 32 bytes |
| typedef void(* joybus_target_n64_pak_controller_select_cb) (struct joybus_target_n64_pak_controller *pak, uint8_t bank) |
Callback type for bank select events.
Runs in interrupt context, so it must return quickly.
| pak | the controller pak |
| bank | the bank now selected |
| typedef int(* joybus_target_n64_pak_controller_write_cb) (struct joybus_target_n64_pak_controller *pak, uint8_t bank, uint16_t addr, const uint8_t buf[JOYBUS_N64_PAK_BLOCK_SIZE]) |
Callback type for writing a block of a bank.
The console retries a declined write with the same block, so storage must not act on one it declines. Runs in interrupt context, on the response critical path, so it must return quickly. Mark the implementation with JOYBUS_RAM_FUNC.
| pak | the controller pak being written to |
| bank | the bank the console has selected |
| addr | block-aligned address within the bank, below 0x8000 |
| buf | source buffer, exactly 32 bytes |
| typedef void(* joybus_target_n64_pak_controller_written_cb) (struct joybus_target_n64_pak_controller *pak, uint8_t bank, uint16_t addr) |
Callback type for block written events, fired after storage has taken a write.
Runs in interrupt context, so it must return quickly.
| pak | the controller pak |
| bank | the bank written |
| addr | block-aligned address within the bank |
| void joybus_target_n64_pak_controller_init | ( | struct joybus_target_n64_pak_controller * | pak, |
| uint8_t | banks ) |
Initialize a controller pak.
The pak answers busy until storage is set with joybus_target_n64_pak_controller_set_storage() or joybus_target_n64_pak_controller_set_memory().
| pak | the controller pak to initialize |
| banks | how many banks it presents, 1 to JOYBUS_N64_PAK_FS_MAX_BANKS, not checked here |
| void joybus_target_n64_pak_controller_set_memory | ( | struct joybus_target_n64_pak_controller * | pak, |
| uint8_t * | memory ) |
Back the pak with memory, banks x JOYBUS_N64_PAK_BANK_SIZE bytes owned by the caller.
The buffer is read and written in place, so persisting it is up to the caller, which the written callback helps with. A fresh buffer needs a filesystem before a console will mount it, see joybus_n64_pak_fs_format(). A console can format a one bank pak itself, a banked pak it cannot.
| pak | the controller pak |
| memory | the banks, back to back |
| void joybus_target_n64_pak_controller_set_select_cb | ( | struct joybus_target_n64_pak_controller * | pak, |
| joybus_target_n64_pak_controller_select_cb | callback ) |
Set the bank select callback for the controller pak.
Storage that keeps only some banks close at hand can start fetching the new one here rather than at its first read.
NOTE: Select callbacks are called from interrupt context, do not perform any blocking operations within the callback.
| pak | the controller pak to set the callback for |
| callback | the callback function |
| void joybus_target_n64_pak_controller_set_storage | ( | struct joybus_target_n64_pak_controller * | pak, |
| joybus_target_n64_pak_controller_read_cb | read, | ||
| joybus_target_n64_pak_controller_write_cb | write, | ||
| void * | user_data ) |
Set the storage behind the pak.
For a pak that cannot be held in memory, such as one of many banks kept in flash. The callbacks may answer busy while a bank is fetched, which the console retries.
| pak | the controller pak |
| read | callback that reads a block of a bank |
| write | callback that writes a block of a bank |
| user_data | pointer handed back to the callbacks through pak->user_data |
| void joybus_target_n64_pak_controller_set_written_cb | ( | struct joybus_target_n64_pak_controller * | pak, |
| joybus_target_n64_pak_controller_written_cb | callback ) |
Set the block written callback for the controller pak.
NOTE: Written callbacks are called from interrupt context, do not perform any blocking operations within the callback.
| pak | the controller pak to set the callback for |
| callback | the callback function |