short i;
unsigned short *blah_ptr = (unsigned short *) 0x46c;
i = *blah_ptr;
This doesn't seem to work -- I get 0 every time. Any other ideas?
It should work -- Page 0 is mapped to physical page 0.
What operating system?
---------------------------------------------------------
Terry Colligan, President ter...@tenberry.com
Tenberry Software, Inc. http://www.tenberry.com
*InstantC C interpreter / incremental compiler:
More reliable C code developed in half the time!
*DOS/16M, DOS/4GW and DOS/4G DOS extenders:
No memory limits in DOS!
in...@tenberry.com---phone(508)653-6006---fax(508)655-2753
>I need to access low memory under DOS4GW, specifically the address
>0x46c (the timer counter). I have tried the following:
>
> short i;
> unsigned short *blah_ptr = (unsigned short *) 0x46c;
> i = *blah_ptr;
>
>This doesn't seem to work -- I get 0 every time. Any other ideas?
>
The fallowing seg16:off16 formila will work with any conversion
between 16-bit real-mode pointers and Watcom's 32-bit linear ones.
unsigned short *blah_ptr = (unsigned short *)(seg16 << 4) + off16;
Where seg16 and off16 are the segment and offsets in real-mode you
want to convert.
Hope this helps.
//===========================================================
// Tony Toole - tto...@vis.bc.ca.stop.spam
// Author of idllPower. (Watcom 32-bit DLL support under DOS!)
// x2ftp.oulu.fi/pub/msdos/programming/watcom/idp302ev.zip
// (to make my e-mail valid, remove '.stop.spam')
//===========================================================
Don't see how it can. When applied to a segment of 0x40 and an offset of
0x6c, this formula will produce a result of 0x46c, which is exactly what the
original poster used. There is something mysterious here. I have used code
exactly like the original, with no problems.
How about unsigned short *blah_ptr = (unsigned short *) 0x46cL; /* =
0X0000046C */
This accesses location 0 relative to the start of your data segment. I
don't know how DOS4GW works, and I don't know what operating system
you're running. However, I've had experiences with Borland's stuff under
different OSes, and know of several things that could prevent it from
working.
1) Even though your program is a flat model program, its flat address
space might not coincide with the linear 4GByte address space. Borland's
DPMI runs flat model programs at some offset, so location DS:0 isn't
really linear address zero.
2) Your program may run in an environment in which that particular
location is out of the valid range for the data segment. Under Windows
95, Borland compiled programs are given expand-down data segments that
limit their accesses to addresses way up close to 0xFFFFFFFF.
3) The segment register may give you access to the full 4GByte linear
address space, but paging may be used to map the low addresses into
regular RAM, so that you don't clobber important DOS and BIOS stuff.
I'd call the makers of DOS4GW to find out which of these is the case.
--
Ciao,
Paul D. DeRocco
>I need to access low memory under DOS4GW, specifically the address
>0x46c (the timer counter). I have tried the following:
>
> short i;
> unsigned short *blah_ptr = (unsigned short *) 0x46c;
^^^^ ^^^^
> i = *blah_ptr;
>
>This doesn't seem to work -- I get 0 every time. Any other ideas?
>
This works for me:
unsigned long *ptr = (unsigned long *)0x46c;
unsigned long * volatile ptr = (unsigned long *)0x46c;
if you are counting on it changing as part of a loop condition.
This only works for extenders like DOS/4GW which map the first 1Meg to
selector 0.
Rod McLeod
Century Data Systems.
rmc...@unitouch.demon.co.uk
But that's not possible in protected mode, because the hardware insists
upon treating selector 0 (and I believe selectors 1..7) as null
selectors. They are the only selectors you can successfully load into
segment registers without causing a GPF, but not actually access memory
without causing a GPF.
I use the following:
int dpmi_seg2sel(unsigned short seg);
#pragma aux dpmi_seg2sel \
parm [bx] value [eax] modify exact [eax] = \
"mov AX,02h" \
"int 31h" \
"rcr EAX,1" \
"rcl AX,1" ;
#ifdef __386__
#ifdef __DOS4G__
#define get_bios_tick() (*(volatile unsigned long *)0x46CL)
#else
#define get_bios_tick() \
(*(volatile unsigned long far *)MK_FP(dpmi_seg2sel(0x40),0x6C))
#endif
#else
#define get_bios_tick() (*(volatile unsigned long far *)0x0040006CL)
#endif
Hope this helps!
The code is possible with DOS/4GW, but I wasn't thinking when I made
the last statment. With the default DS with DOS/4GW, DS:0 is linear
address 0.
This is not a general solution, some extenders have a default selector
to the first 1MB (eg Phar Lap 386), others you need to allocate and
map a selector to real memory yourself.
> >>I need to access low memory under DOS4GW, specifically the address
> >>0x46c (the timer counter). I have tried the following:
> >>
> >> short i;
> >> unsigned short *blah_ptr = (unsigned short *) 0x46c;
> >> i = *blah_ptr;
> >>
> >>This doesn't seem to work -- I get 0 every time. Any other ideas?
> >>
> >
That should work, but anyway, try making your pointer 'volatile'
which should be anyway,
volatile unsigned short *blah_ptr = (unsigned short *) 0x46c;
(this will force the compiler to actually read from the pointer each time
it is used, instead of 'optimizing' it to a constant value.)
Hope that helps,
Bernardo Reino <uc...@cclx1.unican.es>
NO I did not. You have snipped everything that I did write.
Please be more careful with your attributions!
Ian
>d...@pobox.com wrote:
>>
>> I need to access low memory under DOS4GW, specifically the address
>> 0x46c (the timer counter). I have tried the following:
>>
>> short i;
>> unsigned short *blah_ptr = (unsigned short *) 0x46c;
>> i = *blah_ptr;
>>
>> This doesn't seem to work -- I get 0 every time. Any other ideas?
In a private email, d...@pobox.com said that this code now works!
He had some other error confusing things.
>This accesses location 0 relative to the start of your data segment. I
>don't know how DOS4GW works, and I don't know what operating system
>you're running. However, I've had experiences with Borland's stuff under
>different OSes, and know of several things that could prevent it from
>working.
DOS/4GW always (well, almost always! ;-) sets the first megabyte
of linear address to be the first megabyte of the virtual machine
that you are in -- so all your DOS real-mode addresses are
guaranteed to work with the expected hex addresses (video at
0xa0000, not 0xa0000000).
>1) Even though your program is a flat model program, its flat address
>space might not coincide with the linear 4GByte address space. Borland's
>DPMI runs flat model programs at some offset, so location DS:0 isn't
>really linear address zero.
DOS/4GW guarantees that DS:0 is linear zero.
>2) Your program may run in an environment in which that particular
>location is out of the valid range for the data segment. Under Windows
>95, Borland compiled programs are given expand-down data segments that
>limit their accesses to addresses way up close to 0xFFFFFFFF.
There will always be a 0x46c! ;-)
>3) The segment register may give you access to the full 4GByte linear
>address space, but paging may be used to map the low addresses into
>regular RAM, so that you don't clobber important DOS and BIOS stuff.
Nope, we map the first megabyte of your address space into the DOS/
Bios/Video first megabyte of DOS's linear space, one for one.
>I'd call the makers of DOS4GW to find out which of these is the case.
As I said, the originator of this problem now says the code is
working as he originally posted it, and as we guarantee that it
will...
Hope this helps...
---------------------------------------------------------
Terry Colligan, President ter...@tenberry.com
Tenberry Software, Inc. http://www.tenberry.com
*InstantC C interpreter / incremental compiler:
More reliable C code developed in half the time!
*DOS/16M, DOS/4GW and DOS/4G DOS extenders:
No memory limits in DOS!
in...@tenberry.com phone:(508)653-6006 fax:(508)655-2753
>Rod McLeod wrote:
>>
>> This works for me:
>>
>> unsigned long *ptr = (unsigned long *)0x46c;
>>
>> unsigned long * volatile ptr = (unsigned long *)0x46c;
>>
>> if you are counting on it changing as part of a loop condition.
>>
>> This only works for extenders like DOS/4GW which map the first 1Meg to
>> selector 0.
Actually, it's not to selector zero, but rather linear address 0.
>But that's not possible in protected mode, because the hardware insists
>upon treating selector 0 (and I believe selectors 1..7) as null
>selectors. They are the only selectors you can successfully load into
>segment registers without causing a GPF, but not actually access memory
>without causing a GPF.
Paul is absolutely correct here -- selector 0 has nothing to do with
the address 0x46c, at least in a 32-bit DOS/4GW program
>
>Ciao,
>Paul D. DeRocco