I'm trying to get my head around programming real mode MS-DOS in C. Using some old books on game programming as a starting point. The source code in the book is written for Microsoft C, but I'm trying to get it to compile under OpenWatcom v2. I've run into a problem early on, when trying to access a pointer to the start of VGA video memory.
#include <stdio.h>
#include <dos.h>
void Set_Video_Mode(int mode) {
union REGS inregs, outregs;
inregs.h.ah = 0;
inregs.h.al = (unsigned char) mode;
int86(0x10, &inregs, &outregs);
}
int main(void)
{
Set_Video_Mode(0x13);
//the following line throws an error, without it the code compiles and runs
char far *video_buffer = (char far *)0xA0000000L;
while (!kbhit()) { };
Set_Video_Mode(0x03);
return 0;
}
It's the far pointer assignment that throws the following errors:
VGA.C(33): Error! E1077: Missing '}'
VGA.C(33): Warning! W107: Missing return value for function 'main'
VGA.C(36): Error! E1099: Statement must be inside function. Probable cause: missing {
Which is kind of baffling, and seems like a macro definition gone wrong, or something...
When I try the code from the Wikipedia article on far pointers, with the same compiler:
#include <stdio.h>
int main() {
char far *p = (char far *)0x55550005;
char far *q = (char far *)0x53332225;
*p = 80;
(*p)++;
printf("%d", *q);
return 0;
}
It compiles.
The compile command is wcl -bcl=dos source.c
in both cases.
So I'm kind of stumped now, and can't seem to pinpoint the problem. I'm on the verge of throwing a few asterisks and brackets at random places to see if it sticks somewhere...
dos.h
in the problem example, maybe there is something in that file that break compilation? B) Your use ofL
at the end of the pointer value. Maybe this particular compiler does not know it? – Exsanguinewhile
line is superfluous. – Impearlchar far *video_buffer = NULL;
to check which part of the assignment causes a problem. – Frascofar
pointer was encoded in the compiler form, but the x86 segmented processors were limited to 20bits of addressing, with the segment register value shifted by 4 and added to the 16 bits address to form the 20 bits physical address. Maybe the address0xA0000000
is too large and has the MSB set. The VGA text memory starts at0xB8000
as far as I know, which is in the 20 bits addressing range. All the address used in the examples you posted are outside of the addressing range for a 16bits segmented processor. – Parahydrogenfar
pointers do exist in Watcom and they are encoded as 32 bit value with the segment in the upper 16 bit and the offset in the lower 16-bits. There is also a macroMK_FP
that can make a far pointer out of a segment and offset value. 0xA0000000 would be interpreted by the Watcom DOS compiler as 0xa000:0x0000 which is the EGA/VGA graphics area (64KiB). Mode 0x13 (the OP is apparently doing that) would be using that area as video ram. – ArightMK_FP
, defined indos.h
, so the physical address for the far pointer0xA0000000
is0xA0000
graphic memory of VGA. – Parahydrogen