Dreamcast Programming - Maple Bus Maple Bus 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. Frame structure 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 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 -----Cmd/resp code----- -------Recipient------- --------Sender--------- ---Additional words---- 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. Address format 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 M S5 S4 S3 S2 S1 | | | | | | | | | | | +--> Sub-peripheral 1 | | | | +-----> Sub-peripheral 2 | | | +--------> Sub-peripheral 3 | | +-----------> Sub-peripheral 4 | +--------------> Sub-peripheral 5 +-----------------> Main peripheral 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. Function codes 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 Commands 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) -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 -6 LCDERR (according to NetBSD) 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: $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) Function data 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. Hardware registers 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). A05F6C04 - DMA pointer 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. A05F6C18 - DMA enabled 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. A05F6C80 - Timing control 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). Transfer Descriptor 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.