The Maple Bus connects the Dreamcast with the controllers, memory cards, and other
peripherals. The bus uses a symmetrical serial protocol, described below.
The actual wire protocol is described on another
page, since it is only of interrest to people building their own
peripherals.
Messages are sent on the Maple Bus encapsulated in frames. A frame consists of one
or more 32bit binary words. The first word is the frame header, and contains the
command number, sender and recipient information, and the number of additional words in
the frame. These additional words (if any) follows directly after the frame header, and
contains parameters for the command. The frame header and numeric parameters are in big endian byte order. Fields of complex structures transfered (such as the deviceinfo and the cond structures) can be
both big endian and little endian. Refer to the description of the actual structure for more info.
Frame header:
31-24 | 23-16 | 15-8 | 7-0 |
Command / Response code |
Recipient address |
Sender address |
Number of additional words in frame |
|
The command/response code is one of a set of numeric codes listed in the
Commands section below. Positive codes are commands and success responses.
Negative codes are error responses.
The addresses of the sender of the frame and the intended recipient are given in the address
format described under Address format below.
The number of additional words field indicate the number of parameter/data words that follow
the header. If it is zero, the header is the only word in the frame.
The Dreamcast has four Maple Bus ports. On each of these ports, there are up to 7 addressable
units. The Dreamcast itself is always present. There may also be a peripheral (controller,
keyboard, etc.) connected to the port. To this peripheral, there may be connected up to 5
sub-peripherals (memory cards, microphones, etc.). The address format specifies the port
and the unit like this:
7-6 | 5 | 4 | 3 | 2 | 1 | 0 |
Port number |
Main peripheral |
Sub-periph. 5 |
Sub-periph. 4 |
Sub-periph. 3 |
Sub-periph. 2 |
Sub-periph. 1 |
|
The port number is given as a two-bit integer (0 being port A, and 3 port D), and the unit as
a bit-field. The address of the Dreamcast port itself is obtained when none of bits 0-5 are set. When a main peripheral identifies itself in the response
to a command, it sets the sub-peripheral bit for each sub-peripheral that is
connected in addition to bit 5.
There are many different types of peripherals performing different kinds of functions, and
a single peripheral can implement multiple such functions. For example, a VMS
can function as a memory card, as an LCD screen, and as a clock device. Some Maple Bus
commands have different semantics depending on what kind of peripheral they are targeted at.
Because of this, they may take a function code that lets you specify what particular function
you had in mind. For example, when issuing a block write command to a VMS, the function
code selects whether the data should be written to the LCD screen or to the flash memory.
Available function codes:
Code | Function |
$001 |
Controller |
$002 |
Memory card |
$004 |
LCD display |
$008 |
Clock |
$010 |
Microphone |
$020 |
AR-gun |
$040 |
Keyboard |
$080 |
Light gun |
$100 |
Puru-Puru pack |
$200 |
Mouse |
|
Code | Meaning | Parameters | Expected result |
1 |
Request device information |
none |
5 |
2 |
Request extended device information |
none |
6 |
3 |
Reset device |
none |
7 |
4 |
Shutdown device |
none |
7 |
5 |
Device information (response) |
deviceinfo... |
- |
6 |
Extended device information (response) |
deviceinfo..., versionstring |
- |
7 |
Command acknowledge (response) |
none |
- |
8 |
Data transfer (response) |
transfer... |
- |
9 |
Get condition |
func |
8 |
10 |
Get memory information |
func, pt<<24 |
8 |
11 |
Block read |
func, (pt<<24)|(phase<<16)|block |
8 |
12 |
Block write |
func, (pt<<24)|(phase<<16)|block, data... |
7 |
14 |
Set condition |
func, cond... |
7 |
-1 |
No response (set by Maple hardware, rest of frame header not valid) |
none |
- |
-2 |
Function code unsupported (response) |
none |
- |
-3 |
Unknown command (response) |
none |
- |
-4 |
Command needs to be sent again (response) |
none |
- |
-5 |
File error (response) |
error |
- |
|
Explanation of parameters:
- func
- A Function code for the type of access you want to do.
- transfer
- Parameters dependant on the actual command sent. For command 9 (get condition), they are func, cond..., for command 11 (block read), they are func, (pt<<24)|(phase<<16)|block, data...
- cond
- Current condition for a particular function. The actual contents vary with the different functions.
- pt
- Partition number. Should be 0 for VMS:s.
- phase
- Sequence number for piecewise block access
- block
- Block number. Use 0 for LCD screens.
- error
- A bit-field of errors that occured during memory access:
Code | Error |
$01 |
Invalid partition number |
$02 |
Phase error |
$04 |
Invalid block number |
$08 |
Write error |
$10 |
Invalid length (use 192 bytes for LCD writes, 128 bytes for flash writes) |
$20 |
Bad CRC |
|
- deviceinfo...
- A structure (28 words in total) describing the peripheral:
int32 func ; function codes supported by this peripheral (or:ed together) (big endian)
int32[3] function_data ; additional info for the supported function codes (3 max) (big endian)
int8 area_code ; regional code of peripheral
int8 connector_direction (?) ; physical orientation of bus connection
char[30] product_name ; name of peripheral
char[60] product_license ; license statement
int16 standby_power ; standby power consumption (little endian)
int16 max_power ; maximum power consumption (little endian)
The function_data array in the deviceinfo structure above
contain additional device information for the different functions supported
by a device. Since the array contains three elements, there can be information
about up to three functions at the same time. No device should implement more
than three simultaneous functions, or this array will not be enough.
To find the correct entry in the array that corresponds to a particular
function, it is necessary to study exactly which bits are set in the
func field. The most significant bit set corresponds to
the function for which there is information in functions_data[0].
So if a device implements the functions "Memory card" and "Keyboard" (but no
other functions), the first element in the array is "Keyboard" information,
the second is "Memory card" information, and the third is unused.
The actual interpretation of the 32-bit words depend on the corresponding
function code.
Maple Bus communication is done by a single DMA channel. The DMA controller
will send any number of requests, and store the respective responses
in memory (the hardware will wait a configurable amount of time for the
response).
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
Address |
|
|
Set this register to point to your DMA buffer before starting DMA. The address
must be aligned to a 32-byte boundary, and should contain the physical address. So 8C000000 becomes 0C000000. The buffer pointed to by this register should contain one or more transfer descriptors, see below.
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
ENA |
|
Set the ENA bit to 1 to start Maple DMA. When the DMA is completed, ENA
will return to a 0.
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Timeout |
|
Speed |
|
|
The Timeout controls how long the DMA hardware will wait for the response from
a unit. Speed should always be set to 0 (2Mbps).
The transfer descriptors consist of two header words, and a Maple Bus packet
consisting of 1-256 words of data. The header is organized as follows
(little endian):
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
LAST |
|
PORT |
|
GUN |
|
LENGTH |
|
Result address |
|
|
If the LAST bit is set, this is the last transfer descriptor. Othewise, the
next transfer descriptor is located right after the packet data. The packet
data, which consists of LENGTH+1 words, will be sent on controller port
PORT, from whence the response will be expected. The response is stored
at the Result address. If no response is received before the timeout, a word
with all bits set (FFFFFFFF) is written at the Result address. Exactly how
much data is stored at the Result address depends on the response packet
received, but the maximum size of a Maple Bus packet is 256 words (1024 bytes),
so it's adviced to allocate this amount of memory for the result buffer.
If the GUN bit is set, no data is sent or received (the result address is
not present either). Instead the bus enters GUN mode, where it will
monitor controller port PORT for the remainder of the frame. If a light
gun signal is recieved during this time, the raster position will be
latched into register A05F80C4. A Transfer Descriptor with the
GUN bit set should also have the LAST bit set.
Dreamcast Programming by Marcus Comstedt
Last modified: Sun Feb 4 22:36:46 MET 2001