KallistiOS git master
Independent SDK for the Sega Dreamcast
Loading...
Searching...
No Matches
asic.h
Go to the documentation of this file.
1/* KallistiOS ##version##
2
3 dc/asic.h
4 Copyright (C) 2001-2002 Megan Potter
5
6*/
7
8/** \file dc/asic.h
9 \brief Dreamcast ASIC event handling support.
10 \ingroup asic
11
12 This file provides definitions of the events that the ASIC (a part of the
13 PVR) in the Dreamcast can trigger as IRQs, and ways to set responders for
14 those events. Pretty much, this covers all IRQs that aren't generated
15 internally in the SH4 (SCIF and the SH4 DMAC can generate their own IRQs,
16 as well as the trapa instruction, and various exceptions -- those are not
17 dealt with here).
18
19 \author Megan Potter
20*/
21
22#ifndef __DC_ASIC_H
23#define __DC_ASIC_H
24
25#include <sys/cdefs.h>
26__BEGIN_DECLS
27
28#include <stdint.h>
29
30/** \defgroup asic Events
31 \brief Events pertaining to the DC's System ASIC
32 \ingroup system
33
34*/
35
36/* All event codes are two 8-bit integers; the top integer is the event code
37 register to look in to check the event (and to acknowledge it). The
38 register to check is 0xa05f6900+4*regnum. The bottom integer is the
39 bit index within that register. */
40
41/** \defgroup asic_events Event Codes
42 \brief Values for various Holly event codes
43 \ingroup asic
44 @{
45*/
46
47/** \defgroup asic_events_pvr PowerVR
48 \brief Event code values for PowerVR events
49 \ingroup asic_events
50
51 These are events that the PVR itself generates that can be hooked.
52 @{
53*/
54#define ASIC_EVT_PVR_RENDERDONE_VIDEO 0x0000 /**< \brief Video render stage completed */
55#define ASIC_EVT_PVR_RENDERDONE_ISP 0x0001 /**< \brief ISP render stage completed */
56#define ASIC_EVT_PVR_RENDERDONE_TSP 0x0002 /**< \brief TSP render stage completed */
57#define ASIC_EVT_PVR_VBLANK_BEGIN 0x0003 /**< \brief VBLANK begin interrupt */
58#define ASIC_EVT_PVR_VBLANK_END 0x0004 /**< \brief VBLANK end interrupt */
59#define ASIC_EVT_PVR_HBLANK_BEGIN 0x0005 /**< \brief HBLANK begin interrupt */
60
61#define ASIC_EVT_PVR_YUV_DONE 0x0006 /**< \brief YUV completed */
62#define ASIC_EVT_PVR_OPAQUEDONE 0x0007 /**< \brief Opaque list completed */
63#define ASIC_EVT_PVR_OPAQUEMODDONE 0x0008 /**< \brief Opaque modifiers completed */
64#define ASIC_EVT_PVR_TRANSDONE 0x0009 /**< \brief Transparent list completed */
65#define ASIC_EVT_PVR_TRANSMODDONE 0x000a /**< \brief Transparent modifiers completed */
66
67#define ASIC_EVT_PVR_DMA 0x000b /**< \brief PVR DMA complete */
68#define ASIC_EVT_TA_DMA 0x0013 /**< \brief TA DMA complete */
69#define ASIC_EVT_PVR_PTDONE 0x0015 /**< \brief Punch-thrus completed */
70
71#define ASIC_EVT_PVR_ISP_OUTOFMEM 0x0200 /**< \brief ISP out of memory */
72#define ASIC_EVT_PVR_STRIP_HALT 0x0201 /**< \brief Halt due to strip buffer error */
73#define ASIC_EVT_PVR_PARAM_OUTOFMEM 0x0202 /**< \brief Param out of memory */
74#define ASIC_EVT_PVR_OPB_OUTOFMEM 0x0203 /**< \brief OPB went past PVR_TA_OPB_END */
75#define ASIC_EVT_PVR_TA_INPUT_ERR 0x0204 /**< \brief Vertex input error */
76#define ASIC_EVT_PVR_TA_INPUT_OVERFLOW 0x0205 /**< \brief Vertex input overflowed queue */
77/** @} */
78
79/** \defgroup asic_events_gd GD-ROM Drive
80 \brief Event code values for GD-ROM events
81 \ingroup asic_events
82
83 These are events that the GD-ROM drive generates that can be hooked.
84 @{
85*/
86#define ASIC_EVT_GD_COMMAND 0x0100 /**< \brief GD-Rom Command Status */
87#define ASIC_EVT_GD_DMA 0x000e /**< \brief GD-Rom DMA complete */
88#define ASIC_EVT_GD_DMA_OVERRUN 0x020d /**< \brief GD-Rom DMA overrun */
89#define ASIC_EVT_GD_DMA_ILLADDR 0x020c /**< \brief GD-Rom DMA illegal address */
90/** @} */
91
92/** \defgroup asic_events_maple Maple
93 \brief Event code values for Maple events
94 \ingroup asic_events
95
96 These are events that Maple generates that can be hooked.
97 @{
98*/
99#define ASIC_EVT_MAPLE_DMA 0x000c /**< \brief Maple DMA complete */
100#define ASIC_EVT_MAPLE_ERROR 0x000d /**< \brief Maple error (?) */
101/** @} */
102
103/** \defgroup asic_events_spu AICA
104 \brief Event code values for AICA events
105 \ingroup asic_events
106
107 These are events that the SPU (AICA) generates that can be hooked.
108 @{
109*/
110#define ASIC_EVT_SPU_DMA 0x000f /**< \brief SPU (G2 channel 0) DMA complete */
111#define ASIC_EVT_SPU_IRQ 0x0101 /**< \brief SPU interrupt */
112/** @} */
113
114/** \defgroup asic_events_g2dma G2 Bus DMA
115 \brief Event code values for G2 Bus events
116 \ingroup asic_events
117
118 These are events that G2 bus DMA generates that can be hooked.
119 @{
120*/
121#define ASIC_EVT_G2_DMA0 0x000f /**< \brief G2 DMA channel 0 complete */
122#define ASIC_EVT_G2_DMA1 0x0010 /**< \brief G2 DMA channel 1 complete */
123#define ASIC_EVT_G2_DMA2 0x0011 /**< \brief G2 DMA channel 2 complete */
124#define ASIC_EVT_G2_DMA3 0x0012 /**< \brief G2 DMA channel 3 complete */
125/** @} */
126
127/** \defgroup asic_events_ext External Port
128 \brief Event code values for external port events
129 \ingroup asic_events
130
131 These are events that external devices generate that can be hooked.
132 @{
133*/
134#define ASIC_EVT_EXP_8BIT 0x0102 /**< \brief Modem / Lan Adapter */
135#define ASIC_EVT_EXP_PCI 0x0103 /**< \brief BBA IRQ */
136/** @} */
137
138/** @} */
139
140/** \defgroup asic_regs Registers
141 \brief Addresses for various ASIC eveng registers
142 \ingroup asic
143
144 These are the locations in memory where the ASIC registers sit.
145 @{
146*/
147#define ASIC_ACK_A 0xa05f6900 /**< \brief IRQD ACK register */
148#define ASIC_ACK_B 0xa05f6904 /**< \brief IRQB ACK register */
149#define ASIC_ACK_C 0xa05f6908 /**< \brief IRQ9 ACK register */
150
151#define ASIC_IRQD_A 0xa05f6910 /**< \brief IRQD first register */
152#define ASIC_IRQD_B 0xa05f6914 /**< \brief IRQD second register */
153#define ASIC_IRQD_C 0xa05f6918 /**< \brief IRQD third register */
154#define ASIC_IRQB_A 0xa05f6920 /**< \brief IRQB first register */
155#define ASIC_IRQB_B 0xa05f6924 /**< \brief IRQB second register */
156#define ASIC_IRQB_C 0xa05f6928 /**< \brief IRQB third register */
157#define ASIC_IRQ9_A 0xa05f6930 /**< \brief IRQ9 first register */
158#define ASIC_IRQ9_B 0xa05f6934 /**< \brief IRQ9 second register */
159#define ASIC_IRQ9_C 0xa05f6938 /**< \brief IRQ9 third register */
160/** @} */
161
162/** \defgroup asic_irq_lv IRQ Levels
163 \brief values for the various ASIC event IRQ levels
164 \ingroup asic
165
166 You can pick one at hook time, or don't choose anything and the default will
167 be used instead.
168 @{
169*/
170#define ASIC_IRQ9 0 /**< \brief IRQ level 9 */
171#define ASIC_IRQB 1 /**< \brief IRQ level B (11) */
172#define ASIC_IRQD 2 /**< \brief IRQ level D (13) */
173
174#define ASIC_IRQ_MAX 3 /**< \brief Don't take irqs from here up */
175#define ASIC_IRQ_DEFAULT ASIC_IRQ9 /**< \brief Pick an IRQ level for me! */
176/** @} */
177
178/** \brief ASIC event handler type.
179 \ingroup asic
180
181 Any event handlers registered must be of this type. These will be run in an
182 interrupt context, so don't try anything funny.
183
184 \param code The ASIC event code that generated this event.
185 \param data The user pointer that was passed to
186 \ref asic_evt_set_handler.
187 \see asic_events
188*/
189typedef void (*asic_evt_handler)(uint32_t code, void *data);
190
191/** \brief Set or remove an ASIC handler.
192 \ingroup asic
193
194 This function will register an event handler for a given event code, or if
195 the handler is NULL, unregister any that is currently registered.
196
197 \param code The ASIC event code to hook (see \ref asic_events).
198 \param handler The function to call when the event happens.
199 \param data A user pointer that will be passed to the callback.
200
201*/
202void asic_evt_set_handler(uint16_t code, asic_evt_handler handler, void *data);
203
204/** \brief Register a threaded handler with the given ASIC event.
205 \ingroup asic
206
207 This function will spawn a thread, that will sleep until notified when an
208 event happens. It will then call the handler. As the handler is not called
209 in an interrupt context, it can hold locks, and even sleep.
210
211 \param code The ASIC event code to hook (see \ref asic_events).
212 \param handler The function to call when the event happens.
213 \param data A user pointer that will be passed to the callback.
214 \param ack_and_mask An optional function that will be called by the real
215 interrupt handler, to acknowledge and mask the
216 interrupt, so that it won't trigger again while the
217 threaded handler is running.
218 \param unmask An optional function that will be called by the
219 thread after the handler function returned, to
220 re-enable the interrupt.
221*/
223 void *data,
224 void (*ack_and_mask)(uint16_t),
225 void (*unmask)(uint16_t));
226
227/** \brief Unregister any handler set to the given ASIC event.
228 \ingroup asic
229
230 \param code The ASIC event code to unhook (see
231 \ref asic_events).
232*/
233void asic_evt_remove_handler(uint16_t code);
234
235/** \brief Disable all ASIC events.
236 \ingroup asic
237
238 This function will disable hooks for every event that has been hooked. In
239 order to reinstate them, you must individually re-enable them. Not a very
240 good idea to be doing this normally.
241*/
243
244/** \brief Disable one ASIC event.
245 \ingroup asic
246
247 This function will disable the hook for a specified code that was registered
248 at the given IRQ level. Generally, you will never have to do this yourself
249 unless you're adding in some new functionality.
250
251 \param code The ASIC event code to unhook (see
252 \ref asic_events).
253 \param irqlevel The IRQ level it was hooked on (see
254 \ref asic_irq_lv).
255*/
256void asic_evt_disable(uint16_t code, uint8_t irqlevel);
257
258/** \brief Enable an ASIC event.
259 \ingroup asic
260
261 This function will enable the hook for a specified code and register it at
262 the given IRQ level. You should only register each event at a max of one
263 IRQ level (this will not check that for you), and this does not actually set
264 the hook function for the event, you must do that separately with
265 asic_evt_set_handler(). Generally, unless you're adding in new
266 functionality, you'll never have to do this.
267
268 \param code The ASIC event code to hook (see \ref asic_events).
269 \param irqlevel The IRQ level to hook on (see \ref asic_irq_lv).
270 */
271void asic_evt_enable(uint16_t code, uint8_t irqlevel);
272
273/** \cond Enable ASIC events */
274void asic_init(void);
275/* Shutdown ASIC events, disabling all hooks. */
276void asic_shutdown(void);
277/** \endcond */
278
279__END_DECLS
280
281#endif /* __DC_ASIC_H */
void asic_evt_enable(uint16_t code, uint8_t irqlevel)
Enable an ASIC event.
void asic_evt_disable(uint16_t code, uint8_t irqlevel)
Disable one ASIC event.
void(* asic_evt_handler)(uint32_t code, void *data)
ASIC event handler type.
Definition asic.h:189
int asic_evt_request_threaded_handler(uint16_t code, asic_evt_handler handler, void *data, void(*ack_and_mask)(uint16_t), void(*unmask)(uint16_t))
Register a threaded handler with the given ASIC event.
void asic_evt_set_handler(uint16_t code, asic_evt_handler handler, void *data)
Set or remove an ASIC handler.
void asic_evt_disable_all(void)
Disable all ASIC events.
void asic_evt_remove_handler(uint16_t code)
Unregister any handler set to the given ASIC event.