Mail Archives: djgpp/1998/10/02/21:27:57
On 1 Oct 98 at 18:24, Miles F. Bintz Ii wrote:
> > > Well, what do I do with a selector? I don't want to use the near/far ptr
> > > hacks.
> >
> > Why not? farptr is very fast, as the FAQ describes.
> >
>
> The whole concept of near and far doesn't exist in protected mode.
Of course the concept exists -- it's just not used for all the same
things. "near" = "in the default segment for whatever
operation you're doing". "far" = "in any segment". The
default segment could be CS, DS, ES or SS, depending upon the
exact operation. DS, ES and SS are all the same for gcc
programs, and CS is the same but slightly different (because
it's a code segment IIRC).
Since you want to access memory outside your DS, you need to
use a segment override, having loaded the desired selector into
some segment register. This is exactly what `_far*' do --
they're inlined inline assembler functions which set a segment
register (normally FS), then do a read or write, overridden
using that segment.
If you're doing repeated reads/writes to the same area then
you can optimise it by only setting the register once. This is
what the `_farsetsel' function is for. Then you can use the
`_farns*' variants to do the reading and writing without
resetting the segment register.
> I get
> the feeling that this is not the *proper* way to do it. Not to mention,
> it *is* called a "hack"...
The `_far*' functions are not really a hack IMHO. The nearptr
hack is nasty though (again IMHO).
> Is there any way that I can map that memory into part of my data
> segment?
I don't know, unless you use the nearptr hack (which
effectively does this).
> And in fact, the FAQ says this method is slow... but then later goes on to
> say that 'experience says.... its not that bad'. But recommends using
> nearptr hack if I need that additional speed.
The nearptr hack extends your data segment's limit to cover the
whole of the memory space. Some OSes won't let this happen, so
it won't work in all environments. But, it will allow you to
use a normal C pointer to access your memory.
I wouldn't describe the far pointer functions as slow. If you
use them properly (i.e. optimise the segment loads out of tight
loops, as I mentioned above) then the only speed loss compared
to normal pointer writes is in the segment override. If you're
writing your own assembly code you can use DS instead of FS and
dispense with the segment overrides. Don't forget to put it
back afterwards though.
> > You need to understand that there's no way for you to access that address
> > without using the selector with nearptr or farptr, since that address is
> > not mapped into your DS selector.
> >
> > > I would like to be able to say
> > >
> > > char *myptr = 0xda000000
> > > myptr[0] = 0xab;
> >
> > This is exactly what nearptr allows you to do. So what's the problem?
> >
>
> Near pointer takes away protection.
Use the `_far*' functions then.
> As it turns out, I've decided that the far ptr hack will suffice to
> read/write small pieces of data. For my "performance sensitive"
> reads/writes I will probably use a section of memory in DS and use the
> movedata function to get it out to the correct memspace. Do you know any
> of the details on movedata? Does this use DMA? How is the performance of
> this function when moving large blocks of data?
`movedata' is as fast as `memcpy' for large blocks of data --
i.e. very fast. It basically sets DS:ESI to point to the
source selector and offset, ES:EDI to point to the destination,
ECX to an appropriate count, then does a mixture of `movsb' and
`movsl' instructions to copy the data as efficiently as
possible.
If you need details about anything in the djgpp library you can
always check the source code.
--
george DOT foot AT merton DOT oxford DOT ac DOT uk
- Raw text -