[comp.lang.c] C equiv. of Pascal "absolute" type?

dr@skivs.UUCP (David Robins) (03/04/89)

On the IBM, at least, I have seen a Pascal example where an variable
of array type is then set : buffer_1 : array_type absolute $6000:0000.
This sets the buffer to start at the absolute address given.  This is
done to allow a DMA buffer to start on a page boundary, and allow
saving to a file.

Is there an equivalent in C, or a way to set such an absolute location?
-- 
David Robins, M.D.  (ophthalmologist / electronics engineer)
The Smith-Kettlewell Institute of Visual Science,  ***  net:  uunet!skivs!dr
2232 Webster St, San Francisco CA 94115            ***  415/561-1705 (voice) 
The opinions expressed herein do not reflect the opinion of the Institute!

scs@adam.pika.mit.edu (Steve Summit) (03/05/89)

In article <2811@skivs.UUCP> dr@skivs.UUCP (David Robins) writes:
>On the IBM, at least, I have seen a Pascal example where an variable
>of array type is then set : buffer_1 : array_type absolute $6000:0000.
>This sets the buffer to start at the absolute address given.  This is
>done to allow a DMA buffer to start on a page boundary...
>Is there an equivalent in C, or a way to set such an absolute location?

There are several answers, depending on exactly what you are
trying to accomplish.

If all you need is page alignment, you can enforce it yourself,
with the following sort of gory pointer arithmetic:

	unsigned int *bufptr;
	bufptr = (unsigned int *)malloc(bufsize * sizeof(unsigned int) + 17);
	while((unsigned long int)bufptr % 16 != 0)
		bufptr = (unsigned int *)((char *)bufptr + 1);

I used code like this when talking to a DMA A/D converter: the
conversion buffer I handed it could be anywhere, but it had to be
aligned on a page boundary.

If you need to access a specific memory location, and you know
somehow that it is outside the area normally used by programs,
and therefore won't collide, you can set up an explicitly
initialized pointer:

	unsigned char far *videomemory = (unsigned char far *)0xb8000000L;

This might be used for memory-mapped I/O registers or bitmapped
graphics.

(These first two examples declare pointers, not arrays, but you
can, as always, pretend that they are arrays, i.e. access the
first "array" with bufptr[i] or something.)

Finally, you can declare the array (in C) externally:

	extern unsigned int a[];

and define it in an assembly language file, which usually gives
you complete control over allocation and alignment, with as much
flexibility as your assembler and linker allow.

Obviously, all of these techniques are extremely system-specific
and nonportable.

                                            Steve Summit
                                            scs@adam.pika.mit.edu

P.S. for nitpickers:  The code fragments presented here are typed
in from memory; please excuse any typos.  The slop factor of 17
in the first example is overly conservative; I was too lazy to
prove whether 15 or 16 would be sufficient.