KallistiOS git master
Independent SDK for the Sega Dreamcast
Loading...
Searching...
No Matches
maple.h
Go to the documentation of this file.
1/* KallistiOS ##version##
2
3 dc/maple.h
4 Copyright (C) 2002 Megan Potter
5 Copyright (C) 2015 Lawrence Sebald
6
7 This new driver's design is based loosely on the LinuxDC maple
8 bus driver.
9*/
10
11/** \file dc/maple.h
12 \brief Maple Bus driver interface.
13 \ingroup maple
14
15 This file provides support for accessing the Maple bus on the Dreamcast.
16 Maple is the bus that all of your controllers and memory cards and the like
17 connect to, so this is one of those types of things that are quite important
18 to know how to use.
19
20 Each peripheral device registers their driver within this system, and can be
21 accessed through the functions here. Most of the drivers have their own
22 functionality that is implemented in their header files, as well.
23
24 \author Megan Potter
25 \author Lawrence Sebald
26
27 \see dc/maple/controller.h
28 \see dc/maple/dreameye.h
29 \see dc/maple/keyboard.h
30 \see dc/maple/mouse.h
31 \see dc/maple/purupuru.h
32 \see dc/maple/sip.h
33 \see dc/maple/vmu.h
34*/
35
36#ifndef __DC_MAPLE_H
37#define __DC_MAPLE_H
38
39#include <kos/cdefs.h>
40__BEGIN_DECLS
41
42#include <stdbool.h>
43#include <stdint.h>
44#include <arch/types.h>
45#include <sys/queue.h>
46
47/** \defgroup maple Maple Bus
48 \brief Driver for the Dreamcast's Maple Peripheral Bus
49 \ingroup peripherals
50*/
51
52/** \brief Enable Maple DMA debugging.
53 \ingroup maple
54
55 Changing this to a 1 will add massive amounts of processing time to the
56 maple system in general, but it can help in verifying DMA errors. In
57 general, for most purposes this should stay disabled.
58*/
59#define MAPLE_DMA_DEBUG 0
60
61/** \brief Enable Maple IRQ debugging.
62 \ingroup maple
63
64 Changing this to a 1 will turn on intra-interrupt debugging messages, which
65 may cause issues if you're using dcload rather than a raw serial debug
66 terminal. You probably will never have a good reason to enable this, so keep
67 it disabled for normal use.
68*/
69#define MAPLE_IRQ_DEBUG 0
70
71/** \defgroup maple_regs Registers
72 \brief Addresses for various maple registers
73 \ingroup maple
74
75 These are various registers related to the Maple Bus. In general, you
76 probably won't ever need to mess with these directly.
77
78 @{
79*/
80#define MAPLE_BASE 0xa05f6c00 /**< \brief Maple register base */
81#define MAPLE_DMAADDR (MAPLE_BASE+0x04) /**< \brief DMA address register */
82#define MAPLE_RESET2 (MAPLE_BASE+0x10) /**< \brief Reset register #2 */
83#define MAPLE_ENABLE (MAPLE_BASE+0x14) /**< \brief Enable register */
84#define MAPLE_STATE (MAPLE_BASE+0x18) /**< \brief Status register */
85#define MAPLE_SPEED (MAPLE_BASE+0x80) /**< \brief Speed register */
86#define MAPLE_RESET1 (MAPLE_BASE+0x8c) /**< \brief Reset register #1 */
87/** @} */
88
89/** \defgroup maple_reg_values Register Values
90 \brief Values for various maple registers
91 \ingroup maple
92
93 These are the values that are written to registers to get them to do their
94 thing.
95
96 @{
97*/
98#define MAPLE_RESET2_MAGIC 0 /**< \brief 2nd reset value */
99#define MAPLE_ENABLE_ENABLED 1 /**< \brief Enable Maple */
100#define MAPLE_ENABLE_DISABLED 0 /**< \brief Disable Maple */
101#define MAPLE_STATE_IDLE 0 /**< \brief Idle state */
102#define MAPLE_STATE_DMA 1 /**< \brief DMA in-progress */
103#define MAPLE_SPEED_2MBPS 0 /**< \brief 2Mbps bus speed */
104#define MAPLE_SPEED_TIMEOUT(n) ((n) << 16) /**< \brief Bus timeout macro */
105
106#ifndef _arch_sub_naomi
107#define MAPLE_RESET1_MAGIC 0x6155404f /**< \brief First reset value */
108#else
109#define MAPLE_RESET1_MAGIC 0x6155405f
110#endif
111
112/** @} */
113
114/** \defgroup maple_cmds Commands and Responses
115 \brief Maple command and response values
116 \ingroup maple
117
118 These are all either commands or responses to commands sent to or from Maple
119 in normal operation.
120
121 @{
122*/
123#define MAPLE_RESPONSE_FILEERR -5 /**< \brief File error */
124#define MAPLE_RESPONSE_AGAIN -4 /**< \brief Try again later */
125#define MAPLE_RESPONSE_BADCMD -3 /**< \brief Bad command sent */
126#define MAPLE_RESPONSE_BADFUNC -2 /**< \brief Bad function code */
127#define MAPLE_RESPONSE_NONE -1 /**< \brief No response */
128#define MAPLE_COMMAND_DEVINFO 1 /**< \brief Device info request */
129#define MAPLE_COMMAND_ALLINFO 2 /**< \brief All info request */
130#define MAPLE_COMMAND_RESET 3 /**< \brief Reset device request */
131#define MAPLE_COMMAND_KILL 4 /**< \brief Kill device request */
132#define MAPLE_RESPONSE_DEVINFO 5 /**< \brief Device info response */
133#define MAPLE_RESPONSE_ALLINFO 6 /**< \brief All info response */
134#define MAPLE_RESPONSE_OK 7 /**< \brief Command completed ok */
135#define MAPLE_RESPONSE_DATATRF 8 /**< \brief Data transfer */
136#define MAPLE_COMMAND_GETCOND 9 /**< \brief Get condition request */
137#define MAPLE_COMMAND_GETMINFO 10 /**< \brief Get memory information */
138#define MAPLE_COMMAND_BREAD 11 /**< \brief Block read */
139#define MAPLE_COMMAND_BWRITE 12 /**< \brief Block write */
140#define MAPLE_COMMAND_BSYNC 13 /**< \brief Block sync */
141#define MAPLE_COMMAND_SETCOND 14 /**< \brief Set condition request */
142#define MAPLE_COMMAND_MICCONTROL 15 /**< \brief Microphone control */
143#define MAPLE_COMMAND_CAMCONTROL 17 /**< \brief Camera control */
144/** @} */
145
146/** \defgroup maple_functions Function Codes
147 \brief Values of maple "function" codes
148 \ingroup maple
149
150 This is the list of maple device types (function codes). Each device must
151 have at least one function to actually do anything.
152
153 @{
154*/
155
156/* Function codes; most sources claim that these numbers are little
157 endian, and for all I know, they might be; but since it's a bitmask
158 it doesn't really make much different. We'll just reverse our constants
159 from the "big-endian" version. */
160#define MAPLE_FUNC_PURUPURU 0x00010000 /**< \brief Jump pack */
161#define MAPLE_FUNC_MOUSE 0x00020000 /**< \brief Mouse */
162#define MAPLE_FUNC_CAMERA 0x00080000 /**< \brief Camera (Dreameye) */
163#define MAPLE_FUNC_CONTROLLER 0x01000000 /**< \brief Controller */
164#define MAPLE_FUNC_MEMCARD 0x02000000 /**< \brief Memory card */
165#define MAPLE_FUNC_LCD 0x04000000 /**< \brief LCD screen */
166#define MAPLE_FUNC_CLOCK 0x08000000 /**< \brief Clock */
167#define MAPLE_FUNC_MICROPHONE 0x10000000 /**< \brief Microphone */
168#define MAPLE_FUNC_ARGUN 0x20000000 /**< \brief AR gun? */
169#define MAPLE_FUNC_KEYBOARD 0x40000000 /**< \brief Keyboard */
170#define MAPLE_FUNC_LIGHTGUN 0x80000000 /**< \brief Lightgun */
171/** @} */
172
173/* \cond */
174/* Pre-define list/queue types */
175struct maple_frame;
176TAILQ_HEAD(maple_frame_queue, maple_frame);
177
178struct maple_driver;
179LIST_HEAD(maple_driver_list, maple_driver);
180
181struct maple_state_str;
182/* \endcond */
183
184/** \brief Maple frame to be queued for transport.
185 \ingroup maple
186
187 Internal representation of a frame to be queued up for sending.
188
189 \headerfile dc/maple.h
190*/
191typedef struct maple_frame {
192 /** \brief Send queue handle. NOT A FUNCTION! */
193 TAILQ_ENTRY(maple_frame) frameq;
194
195 int cmd; /**< \brief Command (see \ref maple_cmds) */
196 int dst_port; /**< \brief Destination port */
197 int dst_unit; /**< \brief Destination unit */
198 int length; /**< \brief Data transfer length in 32-bit words */
199 volatile int state; /**< \brief Has this frame been sent / responded to? */
200 volatile int queued; /**< \brief Are we on the queue? */
201
202 uint32_t *send_buf; /**< \brief The data which will be sent (if any) */
203 uint8_t *recv_buf; /**< \brief Points into recv_buf_arr, but 32-byte aligned */
204
205 struct maple_device *dev; /**< \brief Does this belong to a device? */
206
207 void (*callback)(struct maple_state_str *, struct maple_frame *); /**< \brief Response callback */
208
209#if MAPLE_DMA_DEBUG
210 uint8_t recv_buf_arr[1024 + 1024 + 32]; /**< \brief Response receive area */
211#else
212 uint8_t recv_buf_arr[1024 + 32]; /**< \brief Response receive area */
213#endif
215
216/** \defgroup maple_frame_states Frame States
217 \brief States for a maple frame
218 \ingroup maple
219 @{
220*/
221#define MAPLE_FRAME_VACANT 0 /**< \brief Ready to be used */
222#define MAPLE_FRAME_UNSENT 1 /**< \brief Ready to be sent */
223#define MAPLE_FRAME_SENT 2 /**< \brief Frame has been sent, but no response yet */
224#define MAPLE_FRAME_RESPONDED 3 /**< \brief Frame has a response */
225/** @} */
226
227/** \brief Maple device info structure.
228 \ingroup maple
229
230 This structure is used by the hardware to deliver the response to the device
231 info request.
232
233 \note product_name and product_license are not guaranteed to be NUL terminated.
234
235 \headerfile dc/maple.h
236*/
237typedef struct maple_devinfo {
238 uint32_t functions; /**< \brief Function codes supported */
239 uint32_t function_data[3]; /**< \brief Additional data per function */
240 uint8_t area_code; /**< \brief Region code */
241 uint8_t connector_direction; /**< \brief 0: UP (most controllers), 1: DOWN (lightgun, microphones) */
242 char product_name[30] __attribute__ ((nonstring)); /**< \brief Name of device */
243 char product_license[60] __attribute__ ((nonstring)); /**< \brief License statement */
244 uint16_t standby_power; /**< \brief Power consumption (standby) */
245 uint16_t max_power; /**< \brief Power consumption (max) */
247
248/** \brief Maple response frame structure.
249 \ingroup maple
250
251 This structure is used to deliver the actual response to a request placed.
252 The data field is where all the interesting stuff will be.
253
254 \headerfile dc/maple.h
255*/
256typedef struct maple_response {
257 int8_t response; /**< \brief Response */
258 uint8_t dst_addr; /**< \brief Destination address */
259 uint8_t src_addr; /**< \brief Source address */
260 uint8_t data_len; /**< \brief Data length (in 32-bit words) */
261 uint8_t data[]; /**< \brief Data (if any) */
263
264/** \brief One maple device.
265 \ingroup maple
266
267 Note that we duplicate the port/unit info which is normally somewhat
268 implicit so that we can pass around a pointer to a particular device struct.
269
270 \headerfile dc/maple.h
271*/
272typedef struct maple_device {
273 /* Public */
274 bool valid; /**< \brief Is this a valid device? */
275 int port; /**< \brief Maple bus port connected to */
276 int unit; /**< \brief Unit number, off of the port */
277 maple_devinfo_t info; /**< \brief Device info struct */
278
279 /* Private */
280 maple_frame_t frame; /**< \brief One rx/tx frame */
281 struct maple_driver *drv; /**< \brief Driver which handles this device */
282
283 uint8_t probe_mask; /**< \brief Mask of sub-devices left to probe */
284 uint8_t dev_mask; /**< \brief Device-present mask for unit 0's */
285
286 volatile uint8_t status_valid; /**< \brief Have we got our first status update? */
287
288 void *status; /**< \brief Status buffer (for pollable devices) */
290
291#define MAPLE_PORT_COUNT 4 /**< \brief Number of ports on the bus */
292#define MAPLE_UNIT_COUNT 6 /**< \brief Max number of units per port */
293
294/** \brief Internal representation of a Maple port.
295 \ingroup maple
296
297 Each maple port can contain up to 6 devices, the first one of which is
298 always the port itself.
299
300 \headerfile dc/maple.h
301*/
302typedef struct maple_port {
303 int port; /**< \brief Port ID */
304 maple_device_t *units[MAPLE_UNIT_COUNT]; /**< \brief Pointers to active units */
306
307/** \brief A maple device driver.
308 \ingroup maple
309
310 Anything which is added to this list is capable of handling one or more
311 maple device types. When a device of the given type is connected (includes
312 startup "connection"), the driver is invoked. This same process happens for
313 disconnection, response receipt, and on a periodic interval (for normal
314 updates).
315
316 \headerfile dc/maple.h
317*/
318typedef struct maple_driver {
319 /** \brief Driver list handle. NOT A FUNCTION! */
320 LIST_ENTRY(maple_driver) drv_list;
321
322 uint32_t functions; /**< \brief One or more MAPLE_FUNCs ORed together */
323 const char *name; /**< \brief The driver name */
324
325 size_t status_size;/**< \brief The size of the status buffer */
326
327 /* Callbacks, to be filled in by the driver */
328
329 /** \brief Periodic polling callback.
330
331 This callback will be called to update the status of connected devices
332 periodically.
333
334 \param drv This structure for the driver.
335 */
336 void (*periodic)(struct maple_driver *drv);
337
338 /** \brief Device attached callback.
339
340 This callback will be called when a new device of this driver is
341 connected to the system.
342
343 \param drv This structure for the driver.
344 \param dev The device that was connected.
345 \return 0 on success, <0 on error.
346 */
347 int (*attach)(struct maple_driver *drv, maple_device_t *dev);
348
349 /** \brief Device detached callback.
350
351 This callback will be called when a device of this driver is disconnected
352 from the system.
353
354 \param drv This structure for the driver.
355 \param dev The device that was detached.
356 */
357 void (*detach)(struct maple_driver *drv, maple_device_t *dev);
358
359 /** \brief User-specified device attached callback.
360
361 This callback will be called when a new device of this driver is
362 connected to the system. It should be set by applications using
363 maple_attach_callback().
364
365 \param dev The device that was connected.
366 \return 0 on success, <0 on error.
367 */
368 void (*user_attach)(maple_device_t *dev);
369
370 /** \brief User-specified device detached callback.
371
372 This callback will be called when a new device of this driver is
373 connected to the system. It should be set by applications using
374 maple_detach_callback().
375
376 \param dev The device that was connected.
377 \return 0 on success, <0 on error.
378 */
379 void (*user_detach)(maple_device_t *dev);
381
382/** \brief Maple state structure.
383 \ingroup maple
384
385 We put everything in here to keep from polluting the global namespace too
386 much.
387
388 \headerfile dc/maple.h
389*/
390typedef struct maple_state_str {
391 /** \brief Maple device driver list. Do not manipulate directly! */
392 struct maple_driver_list driver_list;
393
394 /** \brief Maple frame submission queue. Do not manipulate directly! */
395 struct maple_frame_queue frame_queue;
396
397 /** \brief Maple device info structure */
399
400 /** \brief DMA interrupt counter */
401 volatile int dma_cntr;
402
403 /** \brief VBlank interrupt counter */
404 volatile int vbl_cntr;
405
406 /** \brief DMA send buffer */
407 uint8_t *dma_buffer;
408
409 /** \brief Is a DMA running now? */
410 volatile int dma_in_progress;
411
412 /** \brief Next port that will be auto-detected */
414
415 /** \brief Mask of ports that completed the initial scan */
416 volatile uint8_t scan_ready_mask;
417
418 /** \brief Our vblank handler handle */
420
421 /** \brief The port to read for lightgun status, if any. */
423
424 /** \brief The horizontal position of the lightgun signal. */
425 int gun_x;
426
427 /** \brief The vertical position of the lightgun signal. */
428 int gun_y;
430
431/** \brief Maple DMA buffer size.
432 \ingroup maple
433
434 Increase if you do a _LOT_ of maple stuff on every periodic interrupt.
435*/
436#define MAPLE_DMA_SIZE 16384
437
438/* Maple memory read/write functions; these are just hooks in case
439 we need to do something else later */
440/** \brief Maple memory read macro.
441 \ingroup maple
442 */
443#define maple_read(A) ( *((volatile uint32_t*)(A)) )
444
445/** \brief Maple memory write macro.
446 \ingroup maple
447 */
448#define maple_write(A, V) ( *((volatile uint32_t*)(A)) = (V) )
449
450/** \defgroup maple_func_rvs Return Values
451 \brief Return codes from maple access functions
452 \ingroup maple
453 @{
454*/
455#define MAPLE_EOK 0 /**< \brief No error */
456#define MAPLE_EFAIL -1 /**< \brief Command failed */
457#define MAPLE_EAGAIN -2 /**< \brief Try again later */
458#define MAPLE_EINVALID -3 /**< \brief Invalid command */
459#define MAPLE_ENOTSUPP -4 /**< \brief Command not supported by device */
460#define MAPLE_ETIMEOUT -5 /**< \brief Command timed out */
461/** @} */
462
463/**************************************************************************/
464/* maple_globals.c */
465
466/** \cond Global state info.
467
468 Do not manipulate this state yourself, as it will likely break things if you
469 do so.
470*/
471extern maple_state_t maple_state;
472/** \endcond */
473
474/**************************************************************************/
475/* maple_utils.c */
476
477/** \brief Enable the Maple bus.
478 \ingroup maple
479
480 This will be done for you automatically at init time, and there's probably
481 not many reasons to be doing this during runtime.
482*/
484
485/** \brief Disable the Maple bus.
486 \ingroup maple
487
488 There's really not many good reasons to be mucking with this at runtime.
489*/
491
492/** \brief Start a Maple DMA.
493 \ingroup maple
494
495 This stuff will all be handled internally, so there's probably no reason to
496 be doing this yourself.
497*/
499
500/** \brief Stop a Maple DMA.
501 \ingroup maple
502
503 This stuff will all be handled internally, so there's probably no reason to
504 be doing this yourself.
505*/
506void maple_dma_stop(void);
507
508/** \brief Is a Maple DMA in progress?
509 \ingroup maple
510
511 \return Non-zero if a DMA is in progress.
512*/
514
515/** \brief Set the Maple DMA address.
516 \ingroup maple
517
518 Once again, you should not muck around with this in your programs.
519*/
520void maple_dma_addr(void *ptr);
521
522/** \brief Return a "maple address" for a port, unit pair.
523 \ingroup maple
524
525 \param port The port to build the address for.
526 \param unit The unit to build the address for.
527 \return The Maple address of the pair.
528*/
529uint8_t maple_addr(int port, int unit);
530
531/** \brief Decompose a "maple address" into a port, unit pair.
532 \ingroup maple
533
534 \warning
535 This function will not work with multi-cast addresses!
536
537 \param addr The input address.
538 \param port Output space for the port of the address.
539 \param unit Output space for the unit of the address.
540*/
541void maple_raddr(uint8_t addr, int * port, int * unit);
542
543/** \brief Return a string with the capabilities of a given function code.
544 \ingroup maple
545
546 This function is not re-entrant, and thus NOT THREAD SAFE.
547
548 \param functions The list of function codes.
549 \return A string containing the capabilities.
550*/
551const char * maple_pcaps(uint32_t functions);
552
553/** \brief Return a string representing the maple response code.
554 \ingroup maple
555
556 \param response The response code returned from the function.
557 \return A string containing a textual representation of the
558 response code.
559*/
560const char * maple_perror(int response);
561
562/** \brief Determine if a given device is valid.
563 \ingroup maple
564
565 \param p The port to check.
566 \param u The unit to check.
567 \return Non-zero if the device is valid.
568*/
569int maple_dev_valid(int p, int u);
570
571/** \brief Enable light gun mode for this frame.
572 \ingroup maple
573
574 This function enables light gun processing for the current frame of data.
575 Light gun mode will automatically be disabled when the data comes back for
576 this frame.
577
578 \param port The port to enable light gun mode on.
579 \return MAPLE_EOK on success, MAPLE_EFAIL on error.
580*/
581int maple_gun_enable(int port);
582
583/** \brief Disable light gun mode.
584 \ingroup maple
585
586 There is probably very little reason to call this function. Light gun mode
587 is ordinarily disabled and is automatically disabled after the data has been
588 read from the device. The only reason to call this function is if you call
589 the maple_gun_enable() function, and then change your mind during the same
590 frame.
591*/
593
594/** \brief Read the light gun position values.
595 \ingroup maple
596
597 This function fetches the gun position values from the video hardware and
598 returns them via the parameters. These values are not normalized before
599 returning.
600
601 \param x Storage for the horizontal position of the gun.
602 \param y Storage for the vertical position of the gun.
603
604 \note The values returned from this function are the raw H and V counter
605 values from the video hardware where the gun registered its
606 position. The values, however, need a bit of massaging before they
607 correspond nicely to screen values. The y value is particularly odd
608 in interlaced modes due to the fact that you really have half as
609 many physical lines on the screen as you might expect.
610*/
611void maple_gun_read_pos(int *x, int *y);
612
613/* Debugging help */
614
615/** \brief Setup a sentinel for debugging DMA issues.
616 \ingroup maple
617
618 \param buffer The buffer to add the sentinel to.
619 \param bufsize The size of the data in the buffer.
620*/
621void maple_sentinel_setup(void * buffer, int bufsize);
622
623/** \brief Verify the presence of the sentine.
624 \ingroup maple
625
626 \param bufname A string to recognize the buffer by.
627 \param buffer The buffer to check.
628 \param bufsize The size of the buffer.
629*/
630void maple_sentinel_verify(const char * bufname, void * buffer, int bufsize);
631
632/**************************************************************************/
633/* maple_queue.c */
634
635/** \brief Send all queued frames.
636 \ingroup maple
637 */
639
640/** \brief Submit a frame for queueing.
641 \ingroup maple
642
643 This will generally be called inside the periodic interrupt; however, if you
644 need to do something asynchronously (e.g., VMU access) then it might cause
645 some problems. In this case, the function will automatically do locking by
646 disabling interrupts temporarily. In any case, the callback will be done
647 inside an IRQ context.
648
649 \param frame The frame to queue up.
650 \retval 0 On success.
651 \retval -1 If the frame is already queued.
652*/
654
655/** \brief Remove a used frame from the queue.
656 \ingroup maple
657
658 This will be done automatically when the frame is consumed.
659
660 \param frame The frame to remove from the queue.
661 \retval 0 On success.
662 \retval -1 If the frame is not queued.
663*/
665
666/** \brief Initialize a new frame to prepare it to be placed on the queue.
667 \ingroup maple
668
669 You should call this before you fill in the frame data.
670
671 \param frame The frame to initialize.
672*/
674
675/** \brief Try to lock a frame so that someone else can't use it in the
676 mean time.
677 \ingroup maple
678
679 \retval 0 On success.
680 \retval -1 If the frame is already locked.
681*/
683
684/** \brief Lock a frame so that someone else can't use it in the mean time.
685 This function is not safe to use in interrupt context.
686 \ingroup maple
687
688 \retval 0 On success. No error code defined.
689*/
691
692/** \brief Unlock a frame.
693 \ingroup maple
694 */
696
697/**************************************************************************/
698/* maple_driver.c */
699
700/** \brief Register a maple device driver.
701 \ingroup maple
702
703 This should be done before calling maple_init().
704
705 \retval 0 On success (no error conditions defined).
706*/
708
709/** \brief Unregister a maple device driver.
710 \ingroup maple
711
712 \retval 0 On success (no error conditions defined).
713*/
715
716/** \brief Attach a maple device to a driver, if possible.
717 \ingroup maple
718
719 \param det The detection frame.
720 \retval 1 Couldn't allocate buffers.
721 \retval 0 On success.
722 \retval -1 If no driver is available.
723*/
725
726/** \brief Detach an attached maple device.
727 \ingroup maple
728
729 \param p The port of the device to detach.
730 \param u The unit of the device to detach.
731 \retval 0 On success.
732 \retval -1 If the device wasn't valid.
733*/
734int maple_driver_detach(int p, int u);
735
736/** \brief For each device which the given driver controls, call the callback.
737 \ingroup maple
738
739 \param drv The driver to loop through devices of.
740 \param callback The function to call. The parameter is the device
741 that it is being called on. It should return 0 on
742 success, and <0 on failure.
743 \retval 0 On success.
744 \retval -1 If any callbacks return <0.
745*/
747
748/** \brief Maple attach callback type.
749 \ingroup maple
750
751 Functions of this type can be set with maple_attach_callback() to respond
752 automatically to the attachment of a maple device that supports specified
753 functions.
754*/
756
757/** \brief Set an automatic maple attach callback.
758 \ingroup maple
759
760 This function sets a callback function to be called when the specified
761 maple device that supports functions has been attached.
762
763 \param functions The functions maple device must support. Set to
764 0 to support all maple devices.
765 \param cb The callback to call when the maple is attached.
766*/
768
769/** \brief Maple detach callback type.
770 \ingroup maple
771
772 Functions of this type can be set with maple_detach_callback() to respond
773 automatically to the detachment of a maple device that supports specified
774 functions.
775*/
777
778/** \brief Set an automatic maple detach callback.
779 \ingroup maple
780
781 This function sets a callback function to be called when the specified
782 maple device that supports functions has been detached.
783
784 \param functions The functions maple device must support. Set to
785 0 to support all maple devices.
786 \param cb The callback to call when the maple is detached.
787*/
789
790/**************************************************************************/
791/* maple_irq.c */
792
793/** \brief Called on every VBL (~60fps).
794 \ingroup maple
795
796 \param code The ASIC event code.
797 \param data The user pointer associated with this callback.
798*/
799void maple_vbl_irq_hnd(uint32_t code, void *data);
800
801/** \brief Called after a Maple DMA send / receive pair completes.
802 \ingroup maple
803
804 \param code The ASIC event code.
805 \param data The user pointer associated with this callback.
806*/
807void maple_dma_irq_hnd(uint32_t code, void *data);
808
809/**************************************************************************/
810/* maple_enum.c */
811
812/** \brief Return the number of connected devices.
813 \ingroup maple
814
815 \return The number of devices connected.
816*/
818
819/** \brief Get a raw device info struct for the given device.
820 \ingroup maple
821
822 \param p The port to look up.
823 \param u The unit to look up.
824 \return The device at that address, or NULL if no device is
825 there.
826*/
828
829/** \brief Get the Nth device of the requested type (where N is zero-indexed).
830 \ingroup maple
831
832 \param n The index to look up.
833 \param func The function code to look for.
834 \return The device found, if any. NULL otherwise.
835*/
837
838/** \brief Return the Nth device that is of the requested type and supports the
839 list of capabilities given.
840 \ingroup maple
841
842 Note, this only currently makes sense for controllers, since some devices
843 don't necessarily use the function data in the same manner that controllers
844 do (and controllers are the only devices where we have a list of what all
845 the bits mean at the moment).
846
847 \param n The index to look up.
848 \param func The function code to look for.
849 \param cap Capabilities bits to look for.
850 \return The device found, if any. NULL otherwise.
851*/
852maple_device_t *maple_enum_type_ex(int n, uint32_t func, uint32_t cap);
853
854/** \brief Get the status struct for the requested maple device.
855 \ingroup maple
856
857 This function will wait until the status is valid before returning.
858 You should cast to the appropriate type you're expecting.
859
860 \param dev The device to look up.
861 \return The device's status.
862*/
864
865/**************************************************************************/
866/* maple_init.c */
867
868/** \brief Initialize Maple.
869 \ingroup maple
870 */
871void maple_init(void);
872
873/** \brief Shutdown Maple.
874 \ingroup maple
875 */
876void maple_shutdown(void);
877
878/** \brief Wait for the initial bus scan to complete.
879 \ingroup maple
880 */
882
883/**************************************************************************/
884/* Convenience macros */
885
886/* A "foreach" loop to scan all maple devices of a given type. It is used
887 like this:
888
889 MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)
890 if(st->buttons & CONT_START)
891 return -1;
892 MAPLE_FOREACH_END()
893
894 The peripheral index can be obtained with __i, and the raw device struct
895 with __dev. The code inside the loop is guaranteed to be inside a block
896 (i.e., { code })
897 */
898
899/** \brief Begin a foreach loop over Maple devices.
900 \ingroup maple
901
902 This macro (along with the MAPLE_FOREACH_END() one) implements a simple
903 foreach-style loop over the given type of devices. Essentially, it grabs the
904 status of the device, and leaves it to you to figure out what to do with it.
905
906 The most common use of this would be to look for input on any controller.
907
908 \param TYPE The function code of devices to look at.
909 \param VARTYPE The type to cast the return value of
910 maple_dev_status() to.
911 \param VAR The name of the result of maple_dev_status().
912*/
913#define MAPLE_FOREACH_BEGIN(TYPE, VARTYPE, VAR) \
914 do { \
915 maple_device_t * __dev; \
916 VARTYPE * VAR; \
917 int __i; \
918 \
919 __i = 0; \
920 while( (__dev = maple_enum_type(__i, TYPE)) ) { \
921 VAR = (VARTYPE *)maple_dev_status(__dev); \
922 do {
923
924/** \brief End a foreach loop over Maple devices.
925 \ingroup maple
926
927 Each MAPLE_FOREACH_BEGIN() must be paired with one of these after the loop
928 body.
929*/
930#define MAPLE_FOREACH_END() \
931 } while(0); \
932 __i++; \
933 } \
934 } while(0);
935
936__END_DECLS
937
938#endif /* __DC_MAPLE_H */
static struct @69 data[BARRIER_COUNT]
Various common macros used throughout the codebase.
int maple_driver_unreg(maple_driver_t *driver)
Unregister a maple device driver.
int maple_driver_attach(maple_frame_t *det)
Attach a maple device to a driver, if possible.
void(* maple_detach_callback_t)(maple_device_t *dev)
Maple detach callback type.
Definition maple.h:776
int maple_gun_enable(int port)
Enable light gun mode for this frame.
void maple_dma_start(void)
Start a Maple DMA.
void maple_dma_addr(void *ptr)
Set the Maple DMA address.
void maple_gun_read_pos(int *x, int *y)
Read the light gun position values.
maple_device_t * maple_enum_type(int n, uint32_t func)
Get the Nth device of the requested type (where N is zero-indexed).
int maple_driver_detach(int p, int u)
Detach an attached maple device.
uint8_t maple_addr(int port, int unit)
Return a "maple address" for a port, unit pair.
void maple_detach_callback(uint32_t functions, maple_detach_callback_t cb)
Set an automatic maple detach callback.
const char * maple_perror(int response)
Return a string representing the maple response code.
void maple_wait_scan(void)
Wait for the initial bus scan to complete.
void maple_frame_init(maple_frame_t *frame)
Initialize a new frame to prepare it to be placed on the queue.
void maple_shutdown(void)
Shutdown Maple.
void maple_attach_callback(uint32_t functions, maple_attach_callback_t cb)
Set an automatic maple attach callback.
int maple_frame_lock(maple_frame_t *frame)
Lock a frame so that someone else can't use it in the mean time.
int maple_frame_trylock(maple_frame_t *frame)
Try to lock a frame so that someone else can't use it in the mean time.
int maple_driver_reg(maple_driver_t *driver)
Register a maple device driver.
int maple_dev_valid(int p, int u)
Determine if a given device is valid.
int maple_enum_count(void)
Return the number of connected devices.
void maple_init(void)
Initialize Maple.
void maple_sentinel_setup(void *buffer, int bufsize)
Setup a sentinel for debugging DMA issues.
maple_device_t * maple_enum_type_ex(int n, uint32_t func, uint32_t cap)
Return the Nth device that is of the requested type and supports the list of capabilities given.
void(* maple_attach_callback_t)(maple_device_t *dev)
Maple attach callback type.
Definition maple.h:755
void maple_vbl_irq_hnd(uint32_t code, void *data)
Called on every VBL (~60fps).
void maple_sentinel_verify(const char *bufname, void *buffer, int bufsize)
Verify the presence of the sentine.
void maple_gun_disable(void)
Disable light gun mode.
void maple_bus_disable(void)
Disable the Maple bus.
int maple_queue_frame(maple_frame_t *frame)
Submit a frame for queueing.
const char * maple_pcaps(uint32_t functions)
Return a string with the capabilities of a given function code.
void maple_dma_stop(void)
Stop a Maple DMA.
void maple_frame_unlock(maple_frame_t *frame)
Unlock a frame.
void maple_bus_enable(void)
Enable the Maple bus.
void maple_queue_flush(void)
Send all queued frames.
maple_device_t * maple_enum_dev(int p, int u)
Get a raw device info struct for the given device.
void maple_dma_irq_hnd(uint32_t code, void *data)
Called after a Maple DMA send / receive pair completes.
void maple_raddr(uint8_t addr, int *port, int *unit)
Decompose a "maple address" into a port, unit pair.
int maple_dma_in_progress(void)
Is a Maple DMA in progress?
void * maple_dev_status(maple_device_t *dev)
Get the status struct for the requested maple device.
int maple_driver_foreach(maple_driver_t *drv, int(*callback)(maple_device_t *))
For each device which the given driver controls, call the callback.
int maple_queue_remove(maple_frame_t *frame)
Remove a used frame from the queue.
typedef LIST_HEAD(nmmgr_list, nmmgr_handler) nmmgr_list_t
Name handler list type.
typedef TAILQ_HEAD(http_state_list, http_state)
Definition httpd.c:24
#define MAPLE_PORT_COUNT
Number of ports on the bus.
Definition maple.h:291
#define MAPLE_UNIT_COUNT
Max number of units per port.
Definition maple.h:292
static char buffer[256]
Definition porthelper.c:11
static GLint y
Definition scissor.c:38
static GLint x
Definition scissor.c:38
__noinline void func(void)
Definition stacktrace.c:13
One maple device.
Definition maple.h:272
void * status
Status buffer (for pollable devices)
Definition maple.h:288
int unit
Unit number, off of the port.
Definition maple.h:276
uint8_t dev_mask
Device-present mask for unit 0's.
Definition maple.h:284
maple_devinfo_t info
Device info struct.
Definition maple.h:277
maple_frame_t frame
One rx/tx frame.
Definition maple.h:280
uint8_t probe_mask
Mask of sub-devices left to probe.
Definition maple.h:283
volatile uint8_t status_valid
Have we got our first status update?
Definition maple.h:286
int port
Maple bus port connected to.
Definition maple.h:275
bool valid
Is this a valid device?
Definition maple.h:274
struct maple_driver * drv
Driver which handles this device.
Definition maple.h:281
Maple device info structure.
Definition maple.h:237
uint32_t functions
Function codes supported.
Definition maple.h:238
uint8_t area_code
Region code.
Definition maple.h:240
uint16_t max_power
Power consumption (max)
Definition maple.h:245
uint8_t connector_direction
0: UP (most controllers), 1: DOWN (lightgun, microphones)
Definition maple.h:241
uint16_t standby_power
Power consumption (standby)
Definition maple.h:244
A maple device driver.
Definition maple.h:318
LIST_ENTRY(maple_driver) drv_list
Driver list handle.
const char * name
The driver name.
Definition maple.h:323
uint32_t functions
One or more MAPLE_FUNCs ORed together.
Definition maple.h:322
size_t status_size
The size of the status buffer.
Definition maple.h:325
Maple frame to be queued for transport.
Definition maple.h:191
uint8_t * recv_buf
Points into recv_buf_arr, but 32-byte aligned.
Definition maple.h:203
uint32_t * send_buf
The data which will be sent (if any)
Definition maple.h:202
volatile int queued
Are we on the queue?
Definition maple.h:200
int cmd
Command (see Commands and Responses)
Definition maple.h:195
int dst_port
Destination port.
Definition maple.h:196
struct maple_device * dev
Does this belong to a device?
Definition maple.h:205
int dst_unit
Destination unit.
Definition maple.h:197
TAILQ_ENTRY(maple_frame) frameq
Send queue handle.
int length
Data transfer length in 32-bit words.
Definition maple.h:198
volatile int state
Has this frame been sent / responded to?
Definition maple.h:199
Internal representation of a Maple port.
Definition maple.h:302
int port
Port ID.
Definition maple.h:303
Maple response frame structure.
Definition maple.h:256
uint8_t data_len
Data length (in 32-bit words)
Definition maple.h:260
int8_t response
Response.
Definition maple.h:257
uint8_t dst_addr
Destination address.
Definition maple.h:258
uint8_t src_addr
Source address.
Definition maple.h:259
Maple state structure.
Definition maple.h:390
volatile int dma_in_progress
Is a DMA running now?
Definition maple.h:410
int vbl_handle
Our vblank handler handle.
Definition maple.h:419
volatile int dma_cntr
DMA interrupt counter.
Definition maple.h:401
volatile int vbl_cntr
VBlank interrupt counter.
Definition maple.h:404
int gun_x
The horizontal position of the lightgun signal.
Definition maple.h:425
volatile uint8_t scan_ready_mask
Mask of ports that completed the initial scan.
Definition maple.h:416
int gun_y
The vertical position of the lightgun signal.
Definition maple.h:428
uint8_t detect_port_next
Next port that will be auto-detected.
Definition maple.h:413
uint8_t * dma_buffer
DMA send buffer.
Definition maple.h:407
int gun_port
The port to read for lightgun status, if any.
Definition maple.h:422
Common integer types.