This is farptr.h in view mode; [Download] [Up]
/* Copyright (c) 1994 DJ Delorie. Donated to the public domain. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º Far Pointer Simulation Functions º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ This file attempts to make up for the lack of a "far" keyword in GCC. Although it doesn't provide access to far call APIs (like Windows), it does allow you to do far pointer data access without the overhead of movedata() or dosmemget/dosmemput(). You should *always* include this file when using these functions and compile with optimization enabled. They don't exist as normal functions in any library, and they compile down to only a few opcodes when used this way. They are almost as fast as native pointer operations, and about as fast as far pointers can get. If you don't use optimization, this file becomes prototypes for farptr.c, which generates real functions for these when not optimizing. When optimizing, farptr.c compiles to nothing. There are two types of functions here - standalone and invariant. The standalone functions take a selector and offset. These are used when you need only a few accesses, time isn't critical, or you don't know what's in the %fs register. The invariant ones don't take a selector, they only take an offset. These are used inside loops and in time-critical accesses where the selector doesn't change. To specify the selector, use the farsetsel() function. That selector is used for all farns*() functions until changed. The farpoke* and farpeek* take selectors. The farnspoke* and farnspeek* don't (note the `ns' for `no selector'). Warning: These routines all use the %fs register for their accesses. GCC normally uses only %ds and %es, and libc functions (movedata, dosmemget, dosmemput) use %gs. Still, you should be careful about assumptions concerning whether or not the value you put in %fs will be preserved across calls to other functions. If you guess wrong, your program will crash. Better safe than sorry. Note: There are two places where asm constraints are casted. One (farpokeb) is because signed char won't fit in unsigned char's range when arguments are constants, the other (farpeekb) gets compiled to (for example) %eax, but gas puts in opcodes for (for example) %al instead. Both are workarounds for errors that gcc emits (but I don't know why). */ #ifndef _FAR_POINTER_H_ #define _FAR_POINTER_H_ extern inline void _farpokeb(unsigned short selector, unsigned long offset, unsigned char value) { asm("movw %0,%%fs" : : "r" (selector)); asm(".byte 0x64\n" " movb %0,(%1)" : : "r" ((unsigned char)value), "r" (offset)); } extern inline void _farpokew(unsigned short selector, unsigned long offset, unsigned short value) { asm("movw %0,%%fs" : : "r" (selector)); asm(".byte 0x64\n" " movw %0,(%1)" : : "r" (value), "r" (offset)); } extern inline void _farpokel(unsigned short selector, unsigned long offset, unsigned long value) { asm("movw %0,%%fs" : : "r" (selector)); asm(".byte 0x64\n" " movl %0,(%1)" : : "r" (value), "r" (offset)); } extern inline unsigned char _farpeekb(unsigned short selector, unsigned long offset) { unsigned char result; asm("movw %0,%%fs" : : "r" (selector)); asm(".byte 0x64\n" " movb (%1),%0" : "=r" ((int)result) : "r" (offset)); return result; } extern inline unsigned short _farpeekw(unsigned short selector, unsigned long offset) { unsigned short result; asm("movw %0,%%fs" : : "r" (selector)); asm(".byte 0x64\n" " movw (%1),%0" : "=r" (result) : "r" (offset)); return result; } extern inline unsigned long _farpeekl(unsigned short selector, unsigned long offset) { unsigned long result; asm("movw %0,%%fs" : : "r" (selector)); asm(".byte 0x64\n" " movl (%1),%0" : "=r" (result) : "r" (offset)); return result; } extern inline void _farsetsel(unsigned short selector) { asm("movw %0,%%fs" : : "r" (selector)); } extern inline unsigned char _farnspokeb(unsigned long offset, unsigned char value) { asm(".byte 0x64\n" " movb %0,(%1)" : : "r" (value), "r" (offset)); } extern inline unsigned char _farnspokew(unsigned long offset, unsigned short value) { asm(".byte 0x64\n" " movw %0,(%1)" : : "r" (value), "r" (offset)); } extern inline unsigned char _farnspokel(unsigned long offset, unsigned long value) { asm(".byte 0x64\n" " movl %0,(%1)" : : "r" (value), "r" (offset)); } extern inline unsigned char _farnspeekb(unsigned long offset) { unsigned char result; asm(".byte 0x64\n" " movb (%1),%0" : "=r" (result) : "r" (offset)); return result; } extern inline unsigned short _farnspeekw(unsigned long offset) { unsigned short result; asm(".byte 0x64\n" " movw (%1),%0" : "=r" (result) : "r" (offset)); return result; } extern inline unsigned long _farnspeekl(unsigned long offset) { unsigned long result; asm(".byte 0x64\n" " movl (%1),%0" : "=r" (result) : "r" (offset)); return result; } #endif /* _FAR_POINTER_H_ */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.