Host/Target Commands
During startup, runtime, and shutdown, both the Host (Pocket) and Target (Core) need the ability to issue and respond to commands.
Commands are handled over the BRIDGE bus, and the 0xF8xxxxxx
region in its address space is reserved.
There are effectively two separate command/response systems. Host can send commands and poll for a response and Target can send commands and wait for a response.
Host/Target Command Memory Map
Base address: 0xF8000000
Implementation of the command system register space can be done either with a couple block rams and a softcore CPU/state machine or just a handful of fabric registers and a FSM.
Commands may require additional parameter data. The target will provide pointers to where it wants the host to write this data when sending a command. The same goes for response data and finally again in both directions Host > Target and Target > Host.
The second and third columns denote whether the register can be read or written by the (H)ost or (T)arget.
0x00R: H, T
W: H, T
Host (Pocket > Core) command/status.
Stage 1
[31:16] 0x434D 'CM'
[15: 0] command word
Pocket writes here to execute a command. Just before, Pocket checks 0x4 to see where it should write any additional parameters, if applicable.
Stage 2
[31:16] 0x4255 'BU'
[15: 0] busy status
Core traps the write and updates the status. Pocket sees this flag and knows it's in progress. Status/progress information may be encoded in the lower 16 bits, such as a percentage.
Stage3
[31:16] 0x4F4B 'OK'
[15: 0] result code
Core updates with result code. Exact result code depends on the command. Additional data must be encoded in a response format.
0x4
R: H
W: T
Host (Pocket > Core) parameter data pointer.
[31:0]
Address to put applicable parameter data. May be within this bram, or anywhere in the bridge address space. Must have enough room for the longest parameter list.
0x8
R: H
W: T
Host (Pocket > Core) response data pointer.
[31:0]
Address to put applicable response data. May be within this bram, or anywhere in the bridge address space. Pocket will read this address to find where to read a command response from the core.
0x1000R: H, T
W: H, T
Target (Core > Pocket) command/status.
Stage 1
[31:16] 0x636D 'cm'
[15: 0] command word
Core writes here to request command execution. Pocket polls and sees flag set
Stage 2
[31:16] 0x6275 'bu'
[15: 0] busy status
Pocket starts execution, updating status. Core watches this flag for progress. Status/progress information may be encoded in the lower 16 bits, such as a percentage.
Stage3
[31:16] 0x6F6B 'ok'
[15: 0] result code
Pocket updates with result code. Additional data must be encoded in a response format.
0x1004
R: H
W: T
Target (Core > Pocket) parameter data pointer. [31:0]
Address to put applicable parameter data. May be within this bram, or anywhere in the bridge address space. Must have enough room for the longest parameter list.
0x1008
R: H
W: T
Target (Core > Pocket) response data pointer. [31:0]
Address to put applicable response data. May be within this bram, or anywhere in the bridge address space. Must have enough room for the longest parameter list.
0x2000-0x20FF
R: H, T
W: H, T
Data slot size table. Word0: [15:0]
ID of the data slot Word1: [31:0]
Size of the data slot. Zero if the slot is not used. Repeat these 8 bytes for all 32 possible slots. When core is loaded, Pocket will write the filesize as loaded. Core may update the value during setup, idle, or run. Pocket will read the value back during a flush operation and update the filesize on SD if it changed.
0x2380-0x238B
R: H
W: -
Build date and version information.
APF has a Tcl script to populate this area of the bram on compile to include the build date/time, as well as a 32bit randomized ID to identify the build.
[31:0] Build Date in BCD, e.g. 0x20220531 (2022-May-31)
[31:0] Build Time in BCD, e.g. 0x00231159 (23:11:59)
[31:0] Build Unique ID
Dataslot ID / Size Table
Part of the address space is reserved for a 32-entry table. In the example implementations this is a small block ram.
Each item contains two 32-bit words describing the 16-bit ID of that data slot corresponding to the Core Definition JSON, and the size in bytes of that slot.
While the core runs it may read this table to know how large of an asset was loaded, or in the case of a nonvolatile data slot (save file), it may write a revised size in case it changed.
Host Command List
0x0000
Request Status
Parameters: 0
Response: 0
Result Codes:
0x00
: Undefined0x01
: booting (Core clocks/FSM starting, PLL initialization)0x02
: setup (Pocket loads assets, core may request dataslot reads)0x03
: idle (held in reset, not executing)0x04
: running
0x0010
Reset Enter
Parameters: 0
Response: 0
Result Codes: -
0x0011
Reset Exit
Parameters: 0
Response: 0
Result Codes: -
0x0080
Data slot request read
Parameters: 1
[15:0]
Slot id (0-65535)
Response: 0
Result Codes:
0
: ready to read1
: not allowed ever2
: check later
0x0082
Data slot request write
Parameters: 2
[15:0]
Slot id (0-65535)[31:0]
Expected size in bytes
Response: 0
Result Codes:
0
: ready to write1
: not allowed ever2
: check later
0x008A
Data slot update
Parameters: 2
[15:0]
Slot id (0-65535)[31:0]
Expected size in bytes
Response: 0
Result Codes: 0
0x008F
Data slot access all complete
Parameters: 0
Response: 0
Result Codes:
0
: ok
0x0090
Real-time Clock Data
Parameters: 3
[31:0]
Unsigned uint32_t of seconds elapsed since the epoch of 1970.[31:0]
BCD of current date - example0x20221031
[31:0]
BCD of current time - example0x00235959
Response: 0
Pocket sends this command during core boot once, with the current time. It is not continuously sent/updated.
0x00A0
Savestate: Start/Query
Parameters: 1
[0]
Request start. If not set, simply gives the below result without creating the state.
Response: 3
[0]
Set if savestate can be/was created[31:0]
Address of savestate blob when ready.[31:0]
Size of savestate blob when ready.
Result Codes:
0
: ok, no operation1
: busy creating blob2
: done, blob is ready3
: error, failed
0x00A4
Savestate: Load/Query
Parameters: 1
[0]
Request load. If not set, simply gives the below result without loading the state.
Response: 3
[0]
Set if savestate can be/was loaded[31:0]
Address of where savestate blob should be written.[31:0]
Maximum size of savestate blob to be written.
Result Codes:
0
: ok, no operation1
: busy creating blob2
: done, blob is ready3
: error, failed
0x00B0
OS Notify: Menu State
Parameters: 1
[0]
If set, user is in the OS menus and the core has lost focus.
Response: 0
Result Codes:
Pocket sends this command during core operation as the user enters and exits the menu. To maintain compatibility, the command may be ignored by the core.
Target Command List
0x0140
Ready to run.
Parameters: 0
Response: 0
Result Codes: -
0x0180
Data slot read.
Parameters: 4
[15:0]
Slot id (0-65535).
[31:0]
Slot offset
[31:0]
BRIDGE address
[31:0]
Length
Response: 0
Result Codes:
0
: all bytes read ok1
: slot not defined2
: error or out of range. If length is0xFFFFFFFF
, the length will be sized to maximum legal value
0x0184
Data slot write.
Parameters: 4
[15:0]
Slot id (0-65535).
[31:0]
Slot offset
[31:0]
BRIDGE address
[31:0]
Length
Response: 0
Result Codes:
0
: all bytes written ok1
: slot not defined2
: error or out of range. If length is0xFFFFFFFF
, the length will be sized to maximum legal value
0x0188
Data slot flush
Parameters: 1
[15:0]
Slot id (0-65535)
Response: 0
Result Codes:
0
: all bytes written ok1
: slot not defined
0x0190
Get filename of data slot
Parameters: 2
[15:0]
Slot id (0-65535)
[31:0]
Pointer to get_dataslot_file_t
struct
Response: 0
Struct written by Host before command completion
Result Codes:
0
: ok1
: slot not defined
0x0192
Open new file into data slot
Parameters: 2
[15:0]
Slot id (0-65535)
[31:0]
Pointer to get_dataslot_file_t
struct
Response: 0
Struct read by Host on command start
Result Codes:
0
: opened ok1
: created and opened ok (no error)2
: slot not defined3
: file not found4
: malformed path5
: general error
Target Command Structs
get_dataslot_file_t
Byte Offset: 0x0
Length: 256
Name: Full path including filename
Null-terminated string of the path and file selected for a given slot.
For example, the filename could include additional subdirectories: /Assets/abcd/common/directory1/data.bin
open_dataslot_file_t
Byte Offset: 0x0
Length: 256
Name: Full path including filename
Null-terminated string of the full path and file. The file can be in the Assets folder or the Saves folder, in any of the platforms supported by the core (if the data slot was not marked as core-specific).
For example, a data slot not marked as “core-specific”, belonging to the “abcd” platform, with the relative path directory1/data.bin
would be: /Assets/abcd/common/directory1/data.bin
If the core also supported the “xyz” platform, the following would also be valid: /Saves/xyz/common/directory1/save.bin
Byte Offset: 0x100
Length: 4
Name: Operation flags
Bit 0: Create if it doesn’t exist (slot must not be read-only).
Bit 1: Resize/truncate the file (slot must not be read-only).
Bits 2-31: Reserved, must be 0.
Byte Offset: 0x104
Length: 4
Name: Desired file size
Size to resize/truncate the file to, if flagged.
Target slot read/write commands are provided to allow working with much larger files - up to 4GByte in size. They should be used with data slots marked with deferload
set. In this case, APF will not load the file itself, but will still update the Dataslot ID/Size table with the file size.
Additionally, if the data slot is marked with the “User Reloadable” bit set in its Parameters Bitmap, APF will allow choosing a new file in the Interact menu, like any other. However, APF will handle this differently - instead of sending [0082 Data slot request write]
and then [008F Data slot access all complete]
, APF will only send [008A Data slot updated]
and update the Dataslot ID/Size table with the new information.
A core can retrieve the full path information for a file currently loaded in a data slot via the [0190 Get filename of data slot]
command. The core should supply a pointer to where APF will write the resulting filename. A core could use this path and filename information to request additional files by using [0192 Open new file into data slot]
. New files can also be created, or resized. Only assets or saves may be opened, and within platform folders that are supported in core.json
. A data slot must not be marked as read-only for a file to be modified. Once opened, the data slot can be read/written using other Target commands.