Link to home
Start Free TrialLog in
Avatar of crystalfish0318
crystalfish0318

asked on

Having problem with "'far' is an obsolete keyword"!!!!!

Here's my code:

#include <conio.h>
void main (void)
{
     int far *farptr;//Here's the far pointer
     char c;
     farptr = (int far *) 0xB8000000L;
     *farptr = 0x0700 | 'T'; //Stmt 1
     *(farptr + 1) = 0x0700 | 'U';
          //"Ox0700 |" will be explained soon.
     *(farptr + 2) = 0x0700 | 'V';
     *(farptr + 79) = 0x0700 | 'W';
     *(farptr + 80) = 0x0700 | 'X';
     *(farptr + 24 * 80) = 0x0700 | 'Y';
     *(farptr + 24 * 80 + 79) = 0x0700 | 'Z';
     getch();
          //Enter any key to continue
}


the error i got shows "error C4226: nonstandard extension used : 'far' is an obsolete keyword"

Can anyone help me to make this program run?
Thanks very much
Avatar of Kocil
Kocil

Compile that on DOS mode,
or use the old DOS based compiler. For example
Turbo C 2.x (free), Borland C++ 5.5 (free).
You may download them from Borland Museum.


The code you've posted writes to various points on the screen.  Unfortunately on Windows NT, 2K and XP it won't work.  It may possibly work on 9x and ME.  If you want cursor addressing etc, have a look at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/character_mode_applications.asp

It describes MS new character mode interface including colours and cursor addressing.
As far as 'far' pointer is concerned the answer is to just remove the word 'far'. It doesn't make sense on a 32 bit platform.

The 'far' keyword comes from the old DOS platform using 16 bit pointers and addresses. Of course, that gave you only 65536 different bytes to address or 64K. Which is far too little. The solution provided by intel was to add a number of 'segment' registers each of which is 16 bit and have a mode where a 16 bit address could be combined with a 16 bit segment into a 32 bit address. This 32 bit address was referred to as a 'far pointer'. Now you might think that with 32 bit addresses you could access 4Gb of data but in their lack of wisdom they thought that nobody would ever need taht much memory space so they made the 16 segment and 16 bit address combine like this:

segment * 16 + address

instead of the theoretically possible:

segment * 65536 + address.

here segment and address are both 16 bit values and range from 0 to 65535. This gives one headache with the far pointers, two different addresses can very well point to the same physical address:

0x12345 == 0x1234 * 16 + 0x0005 == 0x10000 + 0x2345
so using segment 0x1234 and address 0x0005 is the same location as segment 0x10000 and address 0x2345. In fact for every location there are 4096 different segment and address values that each point to that specific location. Well, taht was until the 'high area' was invented.

As machines developed and memory became cheaper and more compact they put more than one megabyte memory in the machines and the people at intel found a way that you can access above one megabyte:

Traditionally when doing the segment * 16 + address thing, the address had wrapped around in one megabyte or bit 20 on the address was ignored. Using high memory they let bit 20 be significant and so you could address above one megabyte:

0xffff:0x000f is address 0xfffff
0xffff:0x0010 is address 0x100000 instead of 0x00000
0xffff:0xffff is address 010ffef instead of 0x0ffef

This is the so-called A20 as you may have heard of in MS-DOS and BIOS. Also, the Loadhigh or devicehigh where commands provided by MS-DOS to load drivers and other code into the high area from 0x100000 to 0x10ffef.

Addresses above that address 0x10ffef was not available until the 32 bit architecture came with the 386, well I think the 286 also had partial support for 32 bit addresses not sure about that though. The 386 had it.

In 32 bit architecture every address is 32 bit and so there's no 'far' or 'near' pointers anywhere. You still have the segment registers but for one thing they mean something else in protected mode than what they did in the old Intel CPU and secondly, the Win32 system doesn't really use them much. When a program is loaded, DS, CS and SS and I think also ES and GS are all set to point to the same virtual memory space and so an address is an address. The only exception to this - I think - is that FS is set to point to the thread's local storage area. Not sure exactly how it works in details, never studied it much but I believe FS play a role in finding the thread local storage on a Win32 system.

In any case, the bottom line is: drop the far and you're fine as far as pointers go.

However, you have a more serious problem. You are attempting to access the area formerly known as B800:0000 which is the console character display.

Well, the bad news is that it doesn't work that way any more. On Win95 you can access that area and it still work but you shouldn't, you will step on Win95's toes and shouldn't do that.

On Win2000 or WinXP you can forget it, you are not allowed to touch that area.

Use the Console API in Win32 to manipulate the console for regular text output - manipulate background color, foreground color, cursor etc etc etc.

Check out

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/console_functions.asp

For details about the console functions.

Alf
>> ...you are not allowed to touch that area.

Why? That is such a pain...
One very good reason why it doesn't make sense to touch that area (B800:0000) is that is the fact that windows really never display it except during boot when your program isn't running anyway.

When you run a program in MS-DOS box in Win95 you might modify those addresses but you aren't really modifying them. The MS-DOS box runs in a virtual machine and the addresses of B800:0000 on that virtual machine might be used to modify screen, but they do not map to B8000 on the real physical ram. Windows trap when you try to read/write to that memory region and do some behind the scenes magic so that it appears to you that you modify the screen by modifying that memory but that's just because windows let you believe that.

However, in Win32 you are supposed to use the Win32 console API and not access memory anywhere so as far as I know that emulation is not possible in Win2K or WinXP.

I refer to the previously mentioned console functions for a full list of Win32 functions to manipulate the console. You can write characters to specified positions of a console or to the 'current position'. You can write only the character or only the attribute (forground and background color) or both. You can retrieve and set the current position (cursor) and you can get information about any selected area or read mouse input events from the console. You can create a console or you can attach yourself to an existing console.

Alf
ASKER CERTIFIED SOLUTION
Avatar of Salte
Salte

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of crystalfish0318

ASKER

Thank you very much for all of your helps. Although it's tough, but I think I can hand this kind of problem.

thanks again