Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4973 right-hear 1
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
2
/* Copyright (c) 1995 DJ Delorie.  Permission granted to use for any
3
   purpose, provided this copyright remains attached and unmodified.
4
 
5
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
6
   IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
7
   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
8
 
9
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
10
º		Far Pointer Simulation Functions			º
11
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
12
 
13
This file attempts to make up for the lack of a "far" keyword in GCC.
14
Although it doesn't provide access to far call APIs (like Windows), it
15
does allow you to do far pointer data access without the overhead of
16
movedata() or dosmemget/dosmemput().
17
 
18
You should *always* include this file when using these functions and
19
compile with optimization enabled.  They don't exist as normal functions
20
in any library, and they compile down to only a few opcodes when used
21
this way.  They are almost as fast as native pointer operations, and
22
about as fast as far pointers can get.
23
 
24
If you don't use optimization, this file becomes prototypes for
25
farptr.c, which generates real functions for these when not optimizing.
26
When optimizing, farptr.c compiles to nothing.
27
 
28
There are two types of functions here - standalone and invariant.  The
29
standalone functions take a selector and offset.  These are used when
30
you need only a few accesses, time isn't critical, or you don't know
31
what's in the %fs register.  The invariant ones don't take a selector,
32
they only take an offset.  These are used inside loops and in
33
time-critical accesses where the selector doesn't change.  To specify
34
the selector, use the farsetsel() function.  That selector is used for
35
all farns*() functions until changed.  You can use _fargetsel() if you
36
want to temporary change the selector with _farsetsel() and restore
37
it afterwards.
38
 
39
The farpoke* and farpeek* take selectors.
40
 
41
The farnspoke* and farnspeek* don't (note the `ns' for `no selector').
42
 
43
Warning: These routines all use the %fs register for their accesses.
44
GCC normally uses only %ds and %es, and libc functions (movedata,
45
dosmemget, dosmemput) use %gs.  Still, you should be careful about
46
assumptions concerning whether or not the value you put in %fs will be
47
preserved across calls to other functions.  If you guess wrong, your
48
program will crash.  Better safe than sorry.
49
 
50
*/
51
 
52
#ifndef __dj_include_sys_farptr_h_
53
#define __dj_include_sys_farptr_h_
54
 
55
#ifdef __cplusplus
56
extern "C" {
57
#endif
58
 
59
#ifndef __dj_ENFORCE_ANSI_FREESTANDING
60
 
61
#ifndef __STRICT_ANSI__
62
 
63
#ifndef _POSIX_SOURCE
64
 
65
void _farpokeb(unsigned short, unsigned long, unsigned char);
66
void _farpokew(unsigned short, unsigned long, unsigned short);
67
void _farpokel(unsigned short, unsigned long, unsigned long);
68
unsigned char _farpeekb(unsigned short, unsigned long);
69
unsigned short _farpeekw(unsigned short, unsigned long);
70
unsigned long _farpeekl(unsigned short, unsigned long);
71
void _farsetsel(unsigned short);
72
unsigned short _fargetsel(void);
73
void _farnspokeb(unsigned long, unsigned char);
74
void _farnspokew(unsigned long, unsigned short);
75
void _farnspokel(unsigned long, unsigned long);
76
unsigned char _farnspeekb(unsigned long);
77
unsigned short _farnspeekw(unsigned long);
78
unsigned long _farnspeekl(unsigned long);
79
 
80
extern __inline__ void
81
_farpokeb(unsigned short selector,
82
	 unsigned long offset,
83
	 unsigned char value)
84
{
85
  __asm__ __volatile__ ("movw %w0,%%fs\n"
86
      "	.byte 0x64 \n"
87
      "	movb %b1,(%k2)"
88
      :
89
      : "rm" (selector), "qi" (value), "r" (offset));
90
}
91
 
92
extern __inline__ void
93
_farpokew(unsigned short selector,
94
	 unsigned long offset,
95
	 unsigned short value)
96
{
97
  __asm__ __volatile__ ("movw %w0,%%fs \n"
98
      "	.byte 0x64 \n"
99
      "	movw %w1,(%k2)"
100
      :
101
      : "rm" (selector), "ri" (value), "r" (offset));
102
}
103
 
104
extern __inline__ void
105
_farpokel(unsigned short selector,
106
	 unsigned long offset,
107
	 unsigned long value)
108
{
109
  __asm__ __volatile__ ("movw %w0,%%fs \n"
110
      "	.byte 0x64 \n"
111
      "	movl %k1,(%k2)"
112
      :
113
      : "rm" (selector), "ri" (value), "r" (offset));
114
}
115
 
116
extern __inline__ unsigned char
117
_farpeekb(unsigned short selector,
118
	 unsigned long offset)
119
{
120
  unsigned char result;
121
  __asm__ __volatile__ ("movw %w1,%%fs \n"
122
      "	.byte 0x64 \n"
123
      "	movb (%k2),%b0"
124
      : "=q" (result)
125
      : "rm" (selector), "r" (offset));
126
  return result;
127
}
128
 
129
extern __inline__ unsigned short
130
_farpeekw(unsigned short selector,
131
	 unsigned long offset)
132
{
133
  unsigned short result;
134
  __asm__ __volatile__ ("movw %w1, %%fs \n"
135
      "	.byte 0x64 \n"
136
      "	movw (%k2),%w0 \n"
137
      : "=r" (result)
138
      : "rm" (selector), "r" (offset));
139
  return result;
140
}
141
 
142
extern __inline__ unsigned long
143
_farpeekl(unsigned short selector,
144
	 unsigned long offset)
145
{
146
  unsigned long result;
147
  __asm__ __volatile__ ("movw %w1,%%fs\n"
148
      "	.byte 0x64\n"
149
      "	movl (%k2),%k0"
150
      : "=r" (result)
151
      : "rm" (selector), "r" (offset));
152
  return result;
153
}
154
 
155
extern __inline__ void
156
_farsetsel(unsigned short selector)
157
{
158
  __asm__ __volatile__ ("movw %w0,%%fs"
159
      :
160
      : "rm" (selector));
161
}
162
 
163
extern __inline__ unsigned short
164
_fargetsel(void)
165
{
166
  unsigned short selector;
167
  __asm__ __volatile__ ("movw %%fs,%w0 \n"
168
      : "=r" (selector)
169
      : );
170
  return selector;
171
}
172
 
173
extern __inline__ void
174
_farnspokeb(unsigned long offset,
175
	 unsigned char value)
176
{
177
  __asm__ __volatile__ (".byte 0x64\n"
178
      "	movb %b0,(%k1)"
179
      :
180
      : "qi" (value), "r" (offset));
181
}
182
 
183
extern __inline__ void
184
_farnspokew(unsigned long offset,
185
	 unsigned short value)
186
{
187
  __asm__ __volatile__ (".byte 0x64\n"
188
      "	movw %w0,(%k1)"
189
      :
190
      : "ri" (value), "r" (offset));
191
}
192
 
193
extern __inline__ void
194
_farnspokel(unsigned long offset,
195
	 unsigned long value)
196
{
197
  __asm__ __volatile__ (".byte 0x64\n"
198
      "	movl %k0,(%k1)"
199
      :
200
      : "ri" (value), "r" (offset));
201
}
202
 
203
extern __inline__ unsigned char
204
_farnspeekb(unsigned long offset)
205
{
206
  unsigned char result;
207
  __asm__ __volatile__ (".byte 0x64\n"
208
      "	movb (%k1),%b0"
209
      : "=q" (result)
210
      : "r" (offset));
211
  return result;
212
}
213
 
214
extern __inline__ unsigned short
215
_farnspeekw(unsigned long offset)
216
{
217
  unsigned short result;
218
  __asm__ __volatile__ (".byte 0x64\n"
219
      "	movw (%k1),%w0"
220
      : "=r" (result)
221
      : "r" (offset));
222
  return result;
223
}
224
 
225
extern __inline__ unsigned long
226
_farnspeekl(unsigned long offset)
227
{
228
  unsigned long result;
229
  __asm__ __volatile__ (".byte 0x64\n"
230
      "	movl (%k1),%k0"
231
      : "=r" (result)
232
      : "r" (offset));
233
  return result;
234
}
235
 
236
#endif /* !_POSIX_SOURCE */
237
#endif /* !__STRICT_ANSI__ */
238
#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
239
 
240
#ifndef __dj_ENFORCE_FUNCTION_CALLS
241
#endif /* !__dj_ENFORCE_FUNCTION_CALLS */
242
 
243
#ifdef __cplusplus
244
}
245
#endif
246
 
247
#endif /* !__dj_include_sys_farptr_h_ */