-
Notifications
You must be signed in to change notification settings - Fork 5
/
SDI_interrupt.h
154 lines (123 loc) · 5.85 KB
/
SDI_interrupt.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#ifndef SDI_INTERRUPT_H
#define SDI_INTERRUPT_H
/* Includeheader
Name: SDI_interrupt.h
Versionstring: $VER: SDI_interrupt.h 1.1 (25.04.2006)
Author: Guido Mersmann
Distribution: PD
Project page: https://github.com/adtools/SDI
Description: defines to hide compiler specific interrupt and
handler stuff
1.0 17.05.05 : inspired by the SDI_#?.h files made by Jens Langner
and Dirk Stöcker I created files to handle interrupt
and handler functions in an API compatible way.
1.1 25.04.06 : fixed MakeInterrupt() and MakeHandler() macro. (geit)
*/
/*
** This is PD (Public Domain). This means you can do with it whatever you want
** without any restrictions. I only ask you to tell me improvements, so I may
** fix the main line of this files as well.
**
** To keep confusion level low: When changing this file, please note it in
** above history list and indicate that the change was not made by myself
** (e.g. add your name or nick name).
**
** Find the latest version of this file at:
** https://github.com/adtools/SDI
**
** Guido Mersmann <[email protected]>
**
*/
#include "SDI_compiler.h"
/*
** The INTERRUPTPROTO macro is for creating interrupts functions and the
** HANDLERPROTO macro is for handler type setup like used by the
** input.device.
**
** The usage is simular to the DISPATCHERPROTO macro provided by SDI_hook.h.
**
** It gets the function name as argument. To supply this function for use by
** an interrupt structure or handler argument, use the ENTRY macro, which also
** gets the function name as argument. There is also a MakeInterrupt and a
** MakeHandler macro for easy structure setup.
**
** Example:
**
** We create a handler function for the input.device.
**
** HANDLERPROTO( handlerfunc, ULONG, struct InputEvent *inputevent, APTR userdata)
** {
** ... Modify/parse input stream here
** ...
** return( (ULONG) inputevent );
** }
** MakeHandler( handlerstruct, handlerfunc, "TestHandler", &our_user_data);
**
** As you can see usage is as simple as using SDI hooks. To create interrupt
** use INTERRUPTPROTO and MakeInterrupt. Internally both macros are identically.
**
** There are also functions to create more specific interrupt and handler
** structures. By default type is NT_INTERRUPT and priority is 0.
**
** MakeHandlerType - additional argument for type
** MakeHandlerPri - additional argument for pri
** MakeHandlerTypePri - additional arguments for type and pri
**
**
** Notes: Since the interrupt structure is used for handlers and also foreign
** handlers are using this structure I keeped the arguments definition
** on the user side.
**
*/
#ifdef __MORPHOS__
#ifndef SDI_TRAP_LIB /* avoid defining this twice */
#include <proto/alib.h>
#include <emul/emulregs.h>
#define SDI_TRAP_LIB 0xFF00 /* SDI prefix to reduce conflicts */
struct SDI_EmulLibEntry
{
UWORD Trap;
UWORD pad;
APTR Func;
};
#endif
#define INTERRUPTPROTO(name, ret, obj, data) \
SAVEDS ASM ret name( obj, data); \
static ret Trampoline_##name(void) {return name(( obj) REG_A0, \
(data) REG_A1);} \
static const struct SDI_EmulLibEntry Gate_##name = {SDI_TRAP_LIB, 0, \
(APTR) Trampoline_##name}; \
SAVEDS ASM ret name( obj, data)
#define HANDLERPROTO(name, ret, obj, data) \
SAVEDS ASM ret name( obj, data); \
static ret Trampoline_##name(void) {return name(( obj) REG_A0, \
(data) REG_A1);} \
static const struct SDI_EmulLibEntry Gate_##name = {SDI_TRAP_LIB, 0, \
(APTR) Trampoline_##name}; \
SAVEDS ASM ret name( obj, data)
#define ENTRY(func) (APTR)&Gate_##func
#else
#define INTERRUPTPROTO(name, ret, obj, data) \
SAVEDS ASM ret name(REG(a0, obj), REG(a1, data))
#define HANDLERPROTO(name, ret, obj, data) \
SAVEDS ASM ret name(REG(a0, obj), REG(a1, data))
#define ENTRY(func) (APTR)func
#endif /* __MORPHOS__ */
/* some structure creating macros for easy and more specific usage */
#define MakeInterrupt( name, func, title, isdata ) \
static struct Interrupt name = {{ NULL, NULL, NT_INTERRUPT, 0, (STRPTR) title}, (APTR) isdata, (void (*)()) ENTRY(func) }
#define MakeInterruptPri( name, func, title, isdata, pri ) \
static struct Interrupt name = {{ NULL, NULL, NT_INTERRUPT, pri, (STRPTR) title}, (APTR) isdata, (void (*)()) ENTRY(func) }
#define MakeInterruptType( name, func, title, isdata, type ) \
static struct Interrupt name = {{ NULL, NULL, type, 0, (STRPTR) title}, (APTR) isdata, (void (*)()) ENTRY(func) }
#define MakeInterruptTypePri( name, func, title, isdata, type, pri ) \
static struct Interrupt name = {{ NULL, NULL, type, pri, (STRPTR) title}, (APTR) isdata, (void (*)()) ENTRY(func) }
#define MakeHandler( name, func, title, isdata ) \
static struct Interrupt name = {{ NULL, NULL, NT_INTERRUPT, 0, (STRPTR) title}, (APTR) isdata, (void (*)()) ENTRY(func) }
#define MakeHandlerPri( name, func, title, isdata, pri ) \
static struct Interrupt name = {{ NULL, NULL, NT_INTERRUPT, pri, (STRPTR) title}, (APTR) isdata, (void (*)()) ENTRY(func) }
#define MakeHandlerType( name, func, title, isdata, type ) \
static struct Interrupt name = {{ NULL, NULL, type, 0, (STRPTR) title}, (APTR) isdata, (void (*)()) ENTRY(func) }
#define MakeHandlerTypePri( name, func, title, isdata, type, pri ) \
static struct Interrupt name = {{ NULL, NULL, type, pri, (STRPTR) title}, (APTR) isdata, (void (*)()) ENTRY(func) }
#endif /* SDI_INTERRUPT_H */