[comp.lang.c] Absolute addressing in Turbo-C

BREEBAAR%HLERUL5.BITNET@wiscvm.wisc.EDU (08/12/87)

I am currently working on an IBM AT with a Professional Graphics Display,
and am trying to rewrite my Turbo Pascal routines for communicating with
the PG-Adaptor in C, a language in which I have some programming
experience, but am no expert in.
I have to use absolute addressing, because of various buffers and variables
that both the PGA and I need to access. To illustrate, some of the original
Turbo Pascal declarations:

  VAR  outBuffer : ARRAY [0..255] OF BYTE ABSOLUTE $C000:$6000;
       outHead   : BYTE ABSOLUTE $C000:$6300;
       outTail   : BYTE ABSOLUTE $C000:$6301;

My problem ofcourse is: how do I do this in C? (I am using Turbo-C,
but have no manual (yet).)
Firstly I would like to know if Turbo-C has something equivalent to the
'ABSOLUTE' keyword. Probably not.
So secondly, I'd like the proper C solution to this.
I have some vague ideas myself, involving the assigning of values to pointers
but am at a loss at how to implement them, especially with IBM addresses
being 20 bits long etc. etc.
Can anyone out there help me?
Thanx.

Leo Breebaart (BREEBAART@HLERUL5.BITNET)
University of Leiden
The Netherlands

ralf@nl.cs.cmu.edu (Ralf Brown) (08/14/87)

In article <8766@brl-adm.ARPA> BREEBAAR%HLERUL5.BITNET@wiscvm.wisc.EDU writes:
>I have to use absolute addressing, because of various buffers and variables
>that both the PGA and I need to access. To illustrate, some of the original
>Turbo Pascal declarations:
>
>  VAR  outBuffer : ARRAY [0..255] OF BYTE ABSOLUTE $C000:$6000;
>       outHead   : BYTE ABSOLUTE $C000:$6300;
>       outTail   : BYTE ABSOLUTE $C000:$6301;
>
>My problem ofcourse is: how do I do this in C? (I am using Turbo-C,
>but have no manual (yet).)
>Firstly I would like to know if Turbo-C has something equivalent to the
>'ABSOLUTE' keyword. Probably not.
>So secondly, I'd like the proper C solution to this.
>
>Leo Breebaart (BREEBAART@HLERUL5.BITNET)
>University of Leiden
>The Netherlands

The proper way to do this in C is to declare the type of the buffer, and then
declare a pointer variable pointing to that type.  The first thing to do before
using the pointer variable is to assign it the address you need your buffers
etc at.  In Turbo C, the proper function is 

	pointer = MK_FP( seg, ofs )

-- 
-=-=-=-=-=-=-=-= {harvard,seismo,ucbvax}!b.gp.cs.cmu.edu!ralf =-=-=-=-=-=-=-=-
ARPAnet: RALF@B.GP.CS.CMU.EDU            BITnet: RALF%B.GP.CS.CMU.EDU@CMUCCVMA
AT&Tnet: (412) 268-3053 (school)         FIDOnet: Ralf Brown at 129/31
	        DISCLAIMER?  Who ever said I claimed anything? 
"I do not fear computers.  I fear the lack of them..." -- Isaac Asimov

Wax.OsbuSouth@Xerox.COM (08/19/87)

If you assume that "long int" and "far *" are the same size, you could probably do:
	union {
		far unsigned char (*ptr)[]; /* or just "far unsigned char *ptr" */
		long int outBufferAddress;
		} outBuffer;
	...
	outBuffer.outBufferAddress = 0XC0006000L;
	...
	*outBuffer.ptr = ...
	... = *outBuffer.ptr

Allan Wax
Wax.OSBUSouth@Xerox.COM

bpm@psueclb.BITNET (08/22/87)

>[I] am trying to rewrite my Turbo Pascal routines for communicating with
>the PG-Adaptor in C, a language in which I have some programming
>experience, but am no expert in.
>I have to use absolute addressing, because of various buffers and variables
>that both the PGA and I need to access. To illustrate, some of the original
>Turbo Pascal declarations:
>
>  VAR  outBuffer : ARRAY [0..255] OF BYTE ABSOLUTE $C000:$6000;
>       outHead   : BYTE ABSOLUTE $C000:$6300;
>       outTail   : BYTE ABSOLUTE $C000:$6301;
>

To declare an absolute pointer in Turbo C, use the "far" adjective.
For example, the equivalent to the above is:

        char far outBuffer[256] = 0xC0006000;
        char far *outHead = 0xC0006300;
        char far *outTail = 0xC0006301;

--whiffle
     

BREEBAAR%HLERUL5.BITNET@wiscvm.wisc.EDU (09/03/87)

My sincere thanks to all the kind people who took time to answer my question
about absolute adressing in Turbo-C.
For those interested, the -for me- handiest way to say Turbo Pascal's

VAR  outHead : BYTE ABOLUTE $C000:$C300;        in C is:

#define outHead ( *(unsigned char far *)0xC000C300L )

Of course I had not realized at first that 'BYTE' should be translated as
'unsigned char', instead of just 'char', to get the range 0..255; and it took
me half an hour to discover this. Well, I *said* I was no expert.
But I feel somewhat comforted when I realize that of the thirteen people who
responded, only *one* pointed it out.

I also have another question. It's probably a very old one, but please bear in
mind that I have no local C-gurus to consult, and that reference books never
seem to say anything definite about the subject (at least the ones I've read,
don't, and I just *can't* afford K&R; why is that book so horribly expensive?).

It's this: Just WHY is it in C 'better' to write: *(a+n) instead of: a[n],
where 'a' is an array of something? And how much 'better' is it?
I remember reading on this list some time back that this does not extend to
arrays of more than one dimension. Why? Just because the expressions will
get too complex?

Hope you will help me with this too.

Leo Breebaart (BREEBAAR@HLERUL5.BITNET)
Univ. of Leiden
The Netherlands

guy%gorodish@Sun.COM (Guy Harris) (09/03/87)

> It's this: Just WHY is it in C 'better' to write: *(a+n) instead of: a[n],
> where 'a' is an array of something? And how much 'better' is it?

It isn't any "better"; in fact, it's exactly the same.  "a[n]" is defined as
"*(a+n)".

The only ways in which one would be "better" would either be that one is
somehow stylistically, or that one generates better code.  Different people
have different preferences in style, and different compilers may well not
always generate better code for the same version (our compiler generates the
same code for both of them), so it's not clear there is a single style that
could be considered "better" in any objective sense.

> I remember reading on this list some time back that this does not extend to
> arrays of more than one dimension. Why? Just because the expressions will
> get too complex?

No, this extends quite well to arrays of more than one dimension: "a[i][j]" is
(a[i])[j], and thus is *((*(a+i)) + j).  There may be some confusion because
"*(a+i)" is an array-valued expression, and K&R doesn't discuss this notion;
however, ANSI C does - array-valued expressions, in most contexts, are
converted to pointer-valued expressions whose value is a pointer to the first
element of the array.  This is the obvious generalization of the K&R rule that
the name of an array, in most contexts, is converted to a pointer to the first
member of that array; this generalization is implemented by our C compiler, and
probably by most if not all other PCC-based compilers and most likely by many
other compilers as well.
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com

gwyn@brl-smoke.ARPA (Doug Gwyn ) (09/04/87)

In article <9140@brl-adm.ARPA> BREEBAAR%HLERUL5.BITNET@wiscvm.wisc.EDU writes:
>It's this: Just WHY is it in C 'better' to write: *(a+n) instead of: a[n],
>where 'a' is an array of something? And how much 'better' is it?

It's NOT "better".  It's not particularly worse, either, although if
a is declared as an array (rather than a pointer) the a[n] form is
generally better style.

bright@dataio.Data-IO.COM (Walter Bright) (09/04/87)

In article <9140@brl-adm.ARPA> BREEBAAR%HLERUL5.BITNET@wiscvm.wisc.EDU writes:
#It's this: Just WHY is it in C 'better' to write: *(a+n) instead of: a[n],
#where 'a' is an array of something? And how much 'better' is it?
#I remember reading on this list some time back that this does not extend to
#arrays of more than one dimension. Why? Just because the expressions will
#get too complex?

*(a+n) and a[n] are exactly equivalent expressions. Neither is better as
far as the compiler is concerned. As a programming style issue, however:
	*(a+n)	should be used when a is a pointer
	a[n]	should be used when a is an array
This makes the code a little more readable.

In fact, I would have enforced this in the language if I had designed it.
This would have eliminated the 'pointer-array equivalence' kludge and
all its associated kludges and confusion in the language.