libjoybus
Joybus implementation for 32-bit MCUs
Loading...
Searching...
No Matches
N64 Controller Pak

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.

Detailed Description

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.

Macro Definition Documentation

◆ JOYBUS_TARGET_N64_PAK_CONTROLLER

#define JOYBUS_TARGET_N64_PAK_CONTROLLER ( pak)
Value:
N64 Controller Pak pak.
Definition n64_pak_controller.h:93

Macro to cast from a generic N64 pak to a controller pak.

Typedef Documentation

◆ joybus_target_n64_pak_controller_read_cb

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.

Parameters
pakthe controller pak being read from
bankthe bank the console has selected
addrblock-aligned address within the bank, below 0x8000
bufdestination buffer, exactly 32 bytes
Returns
0 on success, -JOYBUS_ERR_BUSY to have the console retry, another negative joybus_error on failure

◆ joybus_target_n64_pak_controller_select_cb

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.

Parameters
pakthe controller pak
bankthe bank now selected

◆ joybus_target_n64_pak_controller_write_cb

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.

Parameters
pakthe controller pak being written to
bankthe bank the console has selected
addrblock-aligned address within the bank, below 0x8000
bufsource buffer, exactly 32 bytes
Returns
0 on success, -JOYBUS_ERR_BUSY to have the console retry, another negative joybus_error on failure

◆ joybus_target_n64_pak_controller_written_cb

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.

Parameters
pakthe controller pak
bankthe bank written
addrblock-aligned address within the bank

Function Documentation

◆ joybus_target_n64_pak_controller_init()

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().

Parameters
pakthe controller pak to initialize
bankshow many banks it presents, 1 to JOYBUS_N64_PAK_FS_MAX_BANKS, not checked here

◆ joybus_target_n64_pak_controller_set_memory()

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.

Parameters
pakthe controller pak
memorythe banks, back to back

◆ joybus_target_n64_pak_controller_set_select_cb()

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.

Parameters
pakthe controller pak to set the callback for
callbackthe callback function

◆ joybus_target_n64_pak_controller_set_storage()

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.

Parameters
pakthe controller pak
readcallback that reads a block of a bank
writecallback that writes a block of a bank
user_datapointer handed back to the callbacks through pak->user_data

◆ joybus_target_n64_pak_controller_set_written_cb()

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.

Parameters
pakthe controller pak to set the callback for
callbackthe callback function