Page 1 of 1

Strange Graphics problem !

Posted: Wed Apr 15, 2009 9:50 am
by schwin
I am running this code :

Code: Select all

#include <kernel.h>

#define   VGA_AC_INDEX          0x3C0
#define   VGA_AC_WRITE          0x3C0
#define   VGA_AC_READ           0x3C1
#define   VGA_MISC_WRITE        0x3C2
#define   VGA_SEQ_INDEX         0x3C4
#define   VGA_SEQ_DATA          0x3C5
#define   VGA_DAC_READ_INDEX    0x3C7
#define   VGA_DAC_WRITE_INDEX   0x3C8
#define   VGA_DAC_DATA          0x3C9
#define   VGA_MISC_READ         0x3CC
#define   VGA_GC_INDEX          0x3CE
#define   VGA_GC_DATA           0x3CF
#define   VGA_CRTC_INDEX        0x3D4      /* 0x3B4 */
#define   VGA_CRTC_DATA         0x3D5      /* 0x3B5 */
#define   VGA_INSTAT_READ       0x3DA
#define   VGA_NUM_SEQ_REGS      5
#define   VGA_NUM_CRTC_REGS     25
#define   VGA_NUM_GC_REGS       9
#define   VGA_NUM_AC_REGS       21
#define   VGA_NUM_REGS         (1+VGA_NUM_SEQ_REGS+VGA_NUM_CRTC_REGS+VGA_NUM_GC_REGS+VGA_NUM_AC_REGS)

//the vga identifiers
unsigned int VGA_width;
unsigned int VGA_height;
unsigned int VGA_bpp;
unsigned char *VGA_address;

void VGA_init(int width, int height, int bpp);
void write_registers(unsigned char *regs);

void vga_mode()
{
	VGA_init(640,480,16);
}

/*
 * Create Register Array
 */

unsigned char g_640x480x16[] =
{
/* MISC */
	0xE3,
/* SEQ */
      0x03, 0x01, 0x0F, 0x00, 0x02,

/* CRTC */
	0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E,
	0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0xEA, 0x0C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3,
	0xFF,
/* GC -> 4th is Function Set and 8th Bit Set 
         6th is Mode Select default Read0 write2*/
	0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x05, 0x0F,
	0xFF,
/* AC */
	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
	0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x2D,
	0x01, 0x0F, 0x0F, 0xC0, 0x00
};

void write_registers(unsigned char *regs){
   unsigned i;

   /* write MISCELLANEOUS reg */
   outportb(VGA_MISC_WRITE, *regs);
   regs++;
   /* write SEQUENCER regs */
   for(i = 0; i < VGA_NUM_SEQ_REGS; i++)
   {
      outportb(VGA_SEQ_INDEX, i);
      outportb(VGA_SEQ_DATA, *regs);
      regs++;
   }
    	
   /* unlock CRTC registers */
   outportb(VGA_CRTC_INDEX, 0x03);
   outportb(VGA_CRTC_DATA, inportb(VGA_CRTC_DATA) | 0x80);
   outportb(VGA_CRTC_INDEX, 0x11);
   outportb(VGA_CRTC_DATA, inportb(VGA_CRTC_DATA) & ~0x80);
   /* make sure they remain unlocked */
   regs[0x03] |= 0x80;
   regs[0x11] &= ~0x80;
   /* write CRTC regs */
   for(i = 0; i < VGA_NUM_CRTC_REGS; i++)
   {
      outportb(VGA_CRTC_INDEX, i);
      outportb(VGA_CRTC_DATA, *regs);
      regs++;
   }
   /* write GRAPHICS CONTROLLER regs */
   for(i = 0; i < VGA_NUM_GC_REGS; i++)
   {
      outportb(VGA_GC_INDEX, i);
      outportb(VGA_GC_DATA, *regs);
      regs++;
   }
   /* write ATTRIBUTE CONTROLLER regs */
   for(i = 0; i < VGA_NUM_AC_REGS; i++)
   {
      (void)inportb(VGA_INSTAT_READ);
      outportb(VGA_AC_INDEX, i);
      outportb(VGA_AC_WRITE, *regs);
      regs++;
   }
   
   /* lock 16-color palette and unblank display */
   (void)inportb(VGA_INSTAT_READ);
   outportb(VGA_AC_INDEX, 0x20);

}

/*
 * Clears the VGA screen
 */
void VGA_clear_screen(){
   unsigned int x=0;
   unsigned int y=0;

   for(y=0; y<VGA_height; y++){
      for(x=0; x<VGA_width; x++){
	   // Address 0xA0000 is (0,0)
         VGA_address[(VGA_width/8)*y+(int)(x/8)]=0x00;
      }
   }	
}

void VGA_init(int width, int height, int bpp){
   //setup the vga struct
   VGA_width=(unsigned int)width;
   VGA_height=(unsigned int)height;
   VGA_bpp=bpp; // Bit per pixel 
   VGA_address=0xA0000; 

   write_registers(g_640x480x16);

   //clears the screen
   VGA_clear_screen();
} 
It runs perfectly fine in Bochs and gives me a nice black screen. But when I run it on Virtualbox its giving a blurred garbage colored screen, similar to then one that appears when text mode doesnt properly switch to Graphics Mode. I am required to run this thing on Virtualbox, as the real machine I need to run my future code is configured(Hardware) according to VirtualBox configurations.

Can someone give me a direction on whats going wrong in the initializations that I am doing for the VGA Registers ?

Thanks

Re: Strange Graphics problem !

Posted: Wed Apr 15, 2009 11:57 am
by Firestryke31
Step 1: use

Code: Select all

 tags so that we can more easily read it. Using the tags will preserve code indentation.

Another thing you might want to try is figuring out why you're outputting those values to those ports. It's long and tedious, but it'll help you figure out why it's not working yourself, and change it to get other modes whenever you want.

Re: Strange Graphics problem !

Posted: Wed Apr 15, 2009 3:32 pm
by Combuster
hmm... GC[5] = 0x02

Who thought using write mode 2 by default was a good idea :shock:

Also, several emulators are known to have bad VGA support. In fact, I know of none that works perfectly. Given that I have not tried VirtualBox yet...

Re: Strange Graphics problem !

Posted: Thu Apr 16, 2009 4:45 am
by jal
Combuster wrote:Also, several emulators are known to have bad VGA support. In fact, I know of none that works perfectly.
DOSBox CVS with vgaonly works pretty accurately, but then, DOSBox is not for OS development :)


JAL

Re: Strange Graphics problem !

Posted: Thu Apr 16, 2009 8:52 am
by Combuster
DOSBox CVS with vgaonly works pretty accurately
I recall DOSBox having some minor problems with the truecolor VGA graphics those demos used... But yes, concerning graphics dosbox is good if not the best emu. (OSDev related: VirtualPC is a good second.)

Re: Strange Graphics problem !

Posted: Thu Apr 16, 2009 9:24 am
by jal
Combuster wrote:I recall DOSBox having some minor problems with the truecolor VGA graphics those demos used...
These problems might even be fixed. Lately there has been a lot of development effort in getting all the quirky VGA stuff used in demos to work.


JAL

Re: Strange Graphics problem !

Posted: Thu Apr 16, 2009 7:32 pm
by schwin
Thank you combuster for editing my post into a more readable format, and I will definitely use the

Code: Select all

 tag next time I post a question on the forum. 

I agree the emulators do not have as good a support for VGA as real hardware, but I tried running the piece of code i've posted on real hardware and it doesnt work and it gives the same output on VirtualBox. strangely the code runs well on Bochs, and the irony is that the real machine that I tried running the code is [b]almost[/b] similar to the configuration of Bochs emulator. 

Not able to figure out which VGA register initialization is causing this. I'll try using the GC->5 default value instead of 02. 

Is their no simpler way of switching to graphics 640X480 mode other than this crude method that I'm trying? Ofcourse, not the interrupt one, because my OS is in protected mode.

Re: Strange Graphics problem !

Posted: Fri Apr 17, 2009 2:18 am
by jal
schwin wrote:strangely the code runs well on Bochs
This is not that strange, as Bochs is really lenient as to what it accepts. Almost any attempt on setting anything will succeed.
Is their no simpler way of switching to graphics 640X480 mode other than this crude method that I'm trying? Ofcourse, not the interrupt one, because my OS is in protected mode.
There have been quite some topics on this forum that address this issue, including links to off-site contents describing how to do this. Unfortunately, I have little time at the moment, so I cannot provide a link. Search the forum and use Google, is all I can recommend.

EDIT: Ok, couldn't resist a quick search myself, and you should be emberassed :)

Topic on this forum with much info: http://forum.osdev.org/viewtopic.php?f=1&t=17230
Site mentioned by Dex in that topic: http://bos.asmhackers.net/docs/vga_without_bios/
Some other similar stuff: http://files.osdev.org/mirrors/geezer/o ... cs/modes.c


JAL

Re: Strange Graphics problem !

Posted: Fri Apr 17, 2009 2:48 am
by Combuster
schwin wrote:Is their no simpler way of switching to graphics 640X480 mode other than this crude method that I'm trying? Ofcourse, not the interrupt one, because my OS is in protected mode.
For VGA programming, there's little else to do than to pump an (at runtime) defined state to the VGA registers. Although, you don't need to touch several registers your code is using to just change video mode. In the end, your code, and my (working) code is fundamentally the same. There's probably some issue with the actual register contents you are using.

Speaking of which, I'm going to overlay my register file over yours, to see where it has differences.

CRTC
1) You set the EVRA bit, which has no effect because 1) on the VGA its forced on, 2) write protect on the CRTC registers is still enabled.

Sequencer
2) Seq[0] and Seq[3] are not in my file (Seq[0] is implicitly altered by the write to Seq[1], Seq[3] has to do with text mode)
3) Seq[2] = 0x08; (matter of choice) seq[4] = 0x06 (You select odd/even mode (your bug most likely!), I select planar mode)
4) There's no synchronous reset around the clock change

GC
5) The write mode, as mentioned. Start with write mode 0 until you got that, only then try something else

AC
6) I do not access the EGA palette AC[0..15]. Rumour has it that it isn't supported on all VGA clones and that it does other things. The defaults are correct.
7) AC[0x11] = 0 - overscan should be black, rather than white
8) AC[0x13] = 0 - you are writing undefined bits in the pixel pan register.


Well, maybe its good to know that geezer's dumps are buggy - If you have problems you might want to check the register files at VGA Hardware