Date: Mon, 20 May 1996 18:01:14 -0700 (PDT) From: Samuel Vincent To: djgpp AT delorie DOT com, watcom353 AT aol DOT com Subject: Re: graphics In-Reply-To: <4nnen5$5k1@newsbf02.news.aol.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII 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 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. ( ) -Sam