making pointers from integers (in machine dependent code)
Chris Torek
torek at elf.ee.lbl.gov
Fri Mar 29 07:08:09 AEST 1991
In article <1991Mar28.190320.10724 at cbnewsj.att.com> asd at cbnewsj.att.com
(Adam S. Denton) writes:
>... consider the following code, which is ubiquitous
>in MSDOS: (my apologies for including platform-specific code here)
>
> void far *p;
> ...
> p = (void far *) 0xFFFFE000;
>
>when IMHO the proper abstraction should be
>
> void far *p;
> ...
> p = MK_FP(0xFFFFu, 0xE000u);
Actually, I have no idea what (if anything) might be at FFFF:E000,
but to consider another example---screens---a `better' way to write
this is something like:
union screendata {
short sd_xc; /* extended character */
struct {
char sd_ch; /* character */
char sd_attr; /* attribute */
} sd_un;
};
#define SCREENSEG 0xe800 /* or whatever */
#define SCREENBASE ((union screendata far *)MK_FP(SCREENSEG, 0))
or even just
#define SCREENBASE ((union screendata far *)0xe8000000)
or whatever. The point is to hide the fact that this is an `absolute
address', and the way it is built, as much as possible, and to use a
meaningful symbol rather than a magic number. That way when the next
instance of the system has the screen at a different address, you need
only change one `define' and maybe add some initialization code:
extern union screendata far *screenbase;
#define SCREENBASE screenbase
All of this should be used only to build the lowest level abstraction
(a `screen' would then become something you could print to, say) on
which you build the next level (windows, perhaps).
--
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
Berkeley, CA Domain: torek at ee.lbl.gov
More information about the Comp.lang.c
mailing list