Subversion Repositories shark

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 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
#ifdef __cplusplus
55
extern "C" {
56
#endif
57
 
58
#ifndef __dj_ENFORCE_ANSI_FREESTANDING
59
 
60
#ifndef __STRICT_ANSI__
61
 
62
#ifndef _POSIX_SOURCE
63
 
64
void _farpokeb(unsigned short, unsigned long, unsigned char);
65
void _farpokew(unsigned short, unsigned long, unsigned short);
66
void _farpokel(unsigned short, unsigned long, unsigned long);
67
unsigned char _farpeekb(unsigned short, unsigned long);
68
unsigned short _farpeekw(unsigned short, unsigned long);
69
unsigned long _farpeekl(unsigned short, unsigned long);
70
void _farsetsel(unsigned short);
71
unsigned short _fargetsel(void);
72
void _farnspokeb(unsigned long, unsigned char);
73
void _farnspokew(unsigned long, unsigned short);
74
void _farnspokel(unsigned long, unsigned long);
75
unsigned char _farnspeekb(unsigned long);
76
unsigned short _farnspeekw(unsigned long);
77
unsigned long _farnspeekl(unsigned long);
78
 
79
extern __inline__ void
80
_farpokeb(unsigned short selector,
81
         unsigned long offset,
82
         unsigned char value)
83
{
84
  __asm__ __volatile__ ("movw %w0,%%fs\n"
85
      " .byte 0x64 \n"
86
      " movb %b1,%%fs:(%k2)"
87
      :
88
      : "rm" (selector), "qi" (value), "r" (offset));
89
}
90
 
91
extern __inline__ void
92
_farpokew(unsigned short selector,
93
         unsigned long offset,
94
         unsigned short value)
95
{
96
  __asm__ __volatile__ ("movw %w0,%%fs \n"
97
      " .byte 0x64 \n"
98
      " movw %w1,(%k2)"
99
      :
100
      : "rm" (selector), "ri" (value), "r" (offset));
101
}
102
 
103
extern __inline__ void
104
_farpokel(unsigned short selector,
105
         unsigned long offset,
106
         unsigned long value)
107
{
108
  __asm__ __volatile__ ("movw %w0,%%fs \n"
109
      " .byte 0x64 \n"
110
      " movl %k1,(%k2)"
111
      :
112
      : "rm" (selector), "ri" (value), "r" (offset));
113
}
114
 
115
extern __inline__ unsigned char
116
_farpeekb(unsigned short selector,
117
         unsigned long offset)
118
{
119
  unsigned char result;
120
  __asm__ __volatile__ ("movw %w1,%%fs \n"
121
      " .byte 0x64 \n"
122
      " movb (%k2),%b0"
123
      : "=q" (result)
124
      : "rm" (selector), "r" (offset));
125
  return result;
126
}
127
 
128
extern __inline__ unsigned short
129
_farpeekw(unsigned short selector,
130
         unsigned long offset)
131
{
132
  unsigned short result;
133
  __asm__ __volatile__ ("movw %w1, %%fs \n"
134
      " .byte 0x64 \n"
135
      " movw (%k2),%w0 \n"
136
      : "=r" (result)
137
      : "rm" (selector), "r" (offset));
138
  return result;
139
}
140
 
141
extern __inline__ unsigned long
142
_farpeekl(unsigned short selector,
143
         unsigned long offset)
144
{
145
  unsigned long result;
146
  __asm__ __volatile__ ("movw %w1,%%fs\n"
147
      " .byte 0x64\n"
148
      " movl (%k2),%k0"
149
      : "=r" (result)
150
      : "rm" (selector), "r" (offset));
151
  return result;
152
}
153
 
154
extern __inline__ void
155
_farsetsel(unsigned short selector)
156
{
157
  __asm__ __volatile__ ("movw %w0,%%fs"
158
      :
159
      : "rm" (selector));
160
}
161
 
162
extern __inline__ unsigned short
163
_fargetsel(void)
164
{
165
  unsigned short selector;
166
  __asm__ __volatile__ ("movw %%fs,%w0 \n"
167
      : "=r" (selector)
168
      : );
169
  return selector;
170
}
171
 
172
extern __inline__ void
173
_farnspokeb(unsigned long offset,
174
         unsigned char value)
175
{
176
  __asm__ __volatile__ (".byte 0x64\n"
177
      " movb %b0,(%k1)"
178
      :
179
      : "qi" (value), "r" (offset));
180
}
181
 
182
extern __inline__ void
183
_farnspokew(unsigned long offset,
184
         unsigned short value)
185
{
186
  __asm__ __volatile__ (".byte 0x64\n"
187
      " movw %w0,(%k1)"
188
      :
189
      : "ri" (value), "r" (offset));
190
}
191
 
192
extern __inline__ void
193
_farnspokel(unsigned long offset,
194
         unsigned long value)
195
{
196
  __asm__ __volatile__ (".byte 0x64\n"
197
      " movl %k0,(%k1)"
198
      :
199
      : "ri" (value), "r" (offset));
200
}
201
 
202
extern __inline__ unsigned char
203
_farnspeekb(unsigned long offset)
204
{
205
  unsigned char result;
206
  __asm__ __volatile__ (".byte 0x64\n"
207
      " movb (%k1),%b0"
208
      : "=q" (result)
209
      : "r" (offset));
210
  return result;
211
}
212
 
213
extern __inline__ unsigned short
214
_farnspeekw(unsigned long offset)
215
{
216
  unsigned short result;
217
  __asm__ __volatile__ (".byte 0x64\n"
218
      " movw (%k1),%w0"
219
      : "=r" (result)
220
      : "r" (offset));
221
  return result;
222
}
223
 
224
extern __inline__ unsigned long
225
_farnspeekl(unsigned long offset)
226
{
227
  unsigned long result;
228
  __asm__ __volatile__ (".byte 0x64\n"
229
      " movl (%k1),%k0"
230
      : "=r" (result)
231
      : "r" (offset));
232
  return result;
233
}
234
 
235
#endif /* !_POSIX_SOURCE */
236
#endif /* !__STRICT_ANSI__ */
237
#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
238
 
239
#ifndef __dj_ENFORCE_FUNCTION_CALLS
240
#endif /* !__dj_ENFORCE_FUNCTION_CALLS */
241
 
242
#ifdef __cplusplus
243
}
244
#endif
245
 
246
#endif /* !__dj_include_sys_farptr_h_ */