Mail Archives: djgpp/1996/05/20/21:01:25
On 19 May 1996, Watcom353 wrote:
> I use int 10h to set the video mode like this:
>
> union REGS regs;
> regs.w.ax=mode;
> int386(0x10,®s,®s);
>
> That works fine. (I know this because when I use printf, the letters are
> really big)
> But I can't get a pixel on the screen. I've tried
> unsigned char *scr=0xa000;
> with many different amounts of 0s after the a. But I always get a GPF.
> How can I write to the screen. (Any suggestions for setting the mode
> without bios would also be appreciated)
Have you read the faq? Hmmmmmmmmmm.
Anyway.. here's your layout of memory.. (i dont wanna just repeat the faq)
[..........][..................][........]
The first area would be your dos memory and any other memory before
the area DJGPP uses for itself. The middle would be the area in which
your DJGPP program is running. The last would be anything left over, not
allocated.
Now, The very first byte of memory in the DJGPP area would be addressable by
char *buf = 0; (Well, that won't work because there's null pointer
protection, but that doesnt matter right now.)
A variable declared as such:
char *buf = 0xa000 or char *buf = 0xa0000
Would address the 0xa000'th or 0xa0000'th byte of memory within the DJGPP
address space. (Once again, this address space starts with the first
byte being at location 0.)
So what you are doing is attempting to write a byte of data to the
0xa0000'th byte location from the beginning of your DJGPP program.
More than likely, this address is out of bounds of your allocation
address space, your allocated segment. This would cause a violation of
memory segmentation, otherwise known as a Segmentation Violation, or Seg
Fault.
What you probably mean to do is address the 0xa0000'th byte of memory
starting from the beginning of system memory, in the dos memory segment.
That would be where your video display memory is mapped if you have a VGA
card. To do this, you must tell the system you want to access memory in
a segment which is different from the default. This is the job of far
pointers. You can use the functions (macros, etc...) in <sys/farptr.h>
to access a different segment, or you can do it yourself using assembly.
A very basic explanation of it iswould be the following. You save the
segment registers you are going to modify somewhere, possibly on the
stack. You then load the registers with the value corresponding to the
segment you want. (You can look in the info pages for something with the
substring of conventional_memory_selector in it. The info you need will
be there.) You then use a segment override to tell the processor to use
that segment when addressing memory in the following instruction, (which
would probably be a mov of some sort.)
There is also another method involving near pointers and the disabling of
memory protection, but I won't go into that here. The method I outlined
above isn't any slower than this near pointer method as it requires only
a segment register load and a segment override for 1 copy of memory.
You could copy 64k to the screen (the size of the video ram mapped at
0xa0000) with only one segment load, override, and restore.
Also, the near pointer method is dangerous when used without a thourough
understanding. It is also dependant on the operating system and dpmi
provider you are using. Not all systems will even allow the memory
protection to be disabled, which is a requirement for this dangerous
method. If you need this method, you should look in the info pages and
figure out how to do it yourself. You will learn as you go and will
probably be much safer with your newfound knowledge.
Anyhow, I suggest using the first method. It is much more portable (I
guarantee it to always work) and there are already macros and functions
defined for its use. ( <sys/farptr.h> )
-Sam
- Raw text -