Screen Black after initilize VESA MODE

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Locked
cianos
Posts: 4
Joined: Tue May 10, 2011 11:27 am

Screen Black after initilize VESA MODE

Post by cianos »

After calling (video_main) is activated in the VBE VESA MODE (VESA_MODE_824) in bochs.
The screen goes black, interrupts work, but nothing prints screen.Does anyone know what's wrong.

kernel partial-based CakeOS / SOmBra
-------------------------------------vga.c / vga.h---------------

Code: Select all

#include <nucleo.h>


unsigned char vga_320x200x256[] =
{
/* MISC */
	0x63,
/* SEQ */
	0x03, 0x01, 0x0F, 0x00, 0x0E,
/* CRTC */
	0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F,
	0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x9C, 0x0E, 0x8F, 0x28,	0x40, 0x96, 0xB9, 0xA3,
	0xFF,
/* GC */
	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
	0xFF,
/* AC */
	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
	0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
	0x41, 0x00, 0x0F, 0x00,	0x00
};

///extern
int graphical_mode;

unsigned long g_wd, g_ht, g_bpp;
unsigned g_planes, g_pixels;
unsigned fb_seg;
uint16_t	* vga_mem = (uint16_t *)0xA0000;

unsigned int* double_buffer;
unsigned char* double_buffer_256;

static void setup_vesa_mode(unsigned short width, unsigned short height, unsigned short depth);

static void g_flip(unsigned int *source, unsigned int count)
{
    memcpy((unsigned char*)vga_mem, (unsigned char*)source, count);
}

/*static void g_partial_flip(unsigned int *source, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
{
     for(int i=0; i <= h; i++)
          memcpy((unsigned char*)vga_mem+(((y*g_wd)+x)+(i*g_wd)), (unsigned char*)source+(((y*g_wd)+x)+(i*g_wd)), w);
}*/


static unsigned get_fb_seg()
{
	unsigned seg;

	outportb(VGA_GC_INDEX, 6);
	seg = inportb(VGA_GC_DATA);
	seg >>= 2;
	seg &= 3;
	switch(seg)
	{
	case 0:
	case 1:
		seg = 0xA000;
		break;
	case 2:
		seg = 0xB000;
		vga_mem = (uint16_t	*)0xB0000;
		break;
	case 3:
		seg = 0xB800;
		vga_mem = (uint16_t	*)0xB8000;
		break;
	}
	return seg;
}

static void vsync()
{
      /* wait until any previous retrace has ended */
      do {
      } while (inportb(0x3DA) & 8);

      /* wait until a new retrace has just begun */
      do {
      } while (!(inportb(0x3DA) & 8));
}

void vga_set_color(int color, int red, int green, int blue)
{
      vsync();
      outportb(0x3C8, color);
      outportb(0x3C9, red);
      outportb(0x3C9, green);
      outportb(0x3C9, blue);
}

void refresh_screen_32bpp()
{
     vsync();
     g_flip(double_buffer,(g_wd*g_ht*4));
}

/*void refresh_32bpp(unsigned int x, unsigned int y, unsigned int w, unsigned int h)
{
     vsync();
     g_partial_flip(double_buffer, x, y, w, h);
}*/

void refresh_screen_256()
{
     vsync();
     g_flip((unsigned int*)double_buffer_256,(g_wd*g_ht*(g_bpp/8)));
}

/*void refresh_256(unsigned int x, unsigned int y, unsigned int w, unsigned int h)
{
     vsync();
     g_partial_flip((unsigned int)double_buffer_256, x, y, w, h);
}*/

static void vpokeb(unsigned off, unsigned val)
{
	pokeb(fb_seg, off, val);
}

static unsigned vpeekl(unsigned off)
{
	return peekl(fb_seg, off);
}

void plot_pixel(unsigned x,unsigned y, unsigned c, unsigned width, unsigned int* buffer)
{
     buffer[(width * y + x)] = c;
}

void write_buffer(unsigned x, unsigned y, unsigned width, unsigned height, unsigned int* buffer)
{
	unsigned j, h;
	for(j=y; j<y + height; j++)
          for(h=x; h<x + width; h++)
               g_write_pixel(h,j,buffer[((j-y)*width)+(h-x)]);
}

void put_buffer(unsigned x, unsigned y, unsigned width, unsigned height, unsigned int* buffer)
{
	unsigned j, h;
    for( j=y; j<y + height; j++)
          for( h=x; h<x + width; h++){
               g_put_pixel(h,j,buffer[((j-y)*width)+(h-x)]);
          }
}

void put_pixel_32bpp(unsigned x,unsigned y, unsigned c)
{
    vga_mem[(g_wd * y + x)] = c;
}

void write_pixel_32bpp(unsigned x,unsigned y, unsigned c)
{
    double_buffer[g_wd * y + x] = c;
}

unsigned int read_pixel_32bpp(int x,int y)
{
    int offset = g_wd * y + x;
    return vga_mem[offset];
}

void put_pixel_256(unsigned x, unsigned y, unsigned c)
{
    if(x < 0 || x > (unsigned)g_wd) return;
	if(y < 0 || y > (unsigned)g_ht) return;

	vpokeb((g_wd * y + x), c);
}

void write_pixel_256(unsigned x, unsigned y, unsigned c)
{
	if(x < 0 || x > (unsigned)g_wd) return;
	if(y < 0 || y > (unsigned)g_ht) return;

    double_buffer_256[g_wd*y+x] = c;
}


unsigned int read_pixel_256(int x, int y)
{
	int offset = y * g_wd + x;
	return vpeekl(offset);
}

static void write_regs(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);
}

void set_vga_mode(int mode)
{
    switch(mode)
    {
    case VGA_MODE_13h:
         graphical_mode = 1;
	     write_regs(VGA_320_200_256);
	     g_wd = 320;
	     g_ht = 200;
	     g_bpp = 16;
	     g_planes = 1;
	     g_pixels = 8;
	     g_put_pixel = put_pixel_256;
	     g_write_pixel = write_pixel_256;
	     g_read_pixel = read_pixel_256;
	     refresh_screen = refresh_screen_256;
	     //refresh = refresh_256;
	     fb_seg = get_fb_seg();
    break;
    case VESA_MODE_809:
         graphical_mode = 2;
   	     g_wd = 600;
	     g_ht = 480;
	     g_bpp = 32;
	     setup_vesa_mode(600, 480, 32);
	     g_planes = 1;
	     g_pixels = 8;
	     g_put_pixel = put_pixel_32bpp;
	     g_write_pixel = write_pixel_32bpp;
	     g_read_pixel = read_pixel_32bpp;
	     refresh_screen = refresh_screen_32bpp;
	     //refresh = refresh_32bpp;
    break;
    case VESA_MODE_824:
         graphical_mode = 2;
   	     g_wd = 1024;
	     g_ht = 768;
	     g_bpp = 32;
	     setup_vesa_mode(1024, 768, 32);
	     g_planes = 1;
	     g_pixels = 8;
	     g_put_pixel = put_pixel_32bpp;
	     g_write_pixel = write_pixel_32bpp;
	     g_read_pixel = read_pixel_32bpp;
	     refresh_screen = refresh_screen_32bpp;
	     //refresh = refresh_32bpp;
	     //g_displaybmp = displaybmp_256;
    break;
	default:
           //Unspecified mode supplied
    break;
    }

    if(graphical_mode == 2){
         //Create the double buffer
         double_buffer = (unsigned int*)malloc((g_wd*g_ht)*4);
         memset((unsigned char*)double_buffer,0,g_wd*g_ht*(g_bpp/8));
    }else{
         double_buffer_256 = (unsigned char*)malloc(g_wd*g_ht*(g_bpp/8));
         memset(double_buffer_256,0,g_wd*g_ht*(g_bpp/8));}

    /* Clear to black */
    //draw_rect(0,0,g_wd,g_ht,0x00000000);
    draw_rect(0,0,g_wd,g_ht,0xFFFFFFFF);

    return;
}

static void setup_vesa_mode(unsigned short width, unsigned short height, unsigned short depth)
{
     //soon to be some fancy hardwear detection and
     //therefore driver loading.
     //for now we will assume bochs/qemu
     vga_mem = (uint16_t*)0;

     bochs_vbe_set_mode(width,height,depth);

     while(vga_mem == 0) __asm__ __volatile__ ("nop");
     memset((unsigned char*)vga_mem,0,g_wd*g_ht*(g_bpp/8));
}

/////////////////////////////////////////////////////
void setcolour(int x, int y, int r, int g, int b);

void setcolour(int x, int y, int r, int g, int b)
{
   unsigned int colour1, colour2, colour3=0;

   if (r > 255) r = 255; if (r < 0) r = 0;
   if (g > 255) g = 255; if (g < 0) g = 0;
   if (b > 255) b = 255; if (b < 0) b = 0;

   //Shift the RGB bits and assign them to
   //a 32 bit word.
   colour1 = r << 16;
   colour2 = g << 8;
   colour3 = b;
   //Now they're in the correct position, combine
   //them using OR's
   colour1 |= colour2;
   colour1 |= colour3;
   printf(" 0x%x (%x %x %x) ",colour1,r,g,b);
   return;
}


void draw_rect(int x, int y, int w, int h, int c)
{
	unsigned j, i;
     for(j=y; j < (y+h); j++)
          for(i=x; i < (x+w); i++)
               g_write_pixel(i,j,c);

     refresh_screen();
}
void plot_rect(int x, int y, int w, int h, int c, unsigned width, unsigned int  * buffer)
{
	unsigned j, i;
	for(j=y; j < (y+h); j++)
          for( i=x; i < (x+w); i++)
               plot_pixel(i,j,c, width, buffer);
}


void setpal(int color, char r, char g, char b)
{
  __asm__ ("out %%al,%%dx\n"::"a" (color),"d" (0x3C8));
   // Send color
  __asm__ ("out %%al,%%dx\n"::"a" (r),"d" (0x3C9));
  __asm__ ("out %%al,%%dx\n"::"a" (g),"d" (0x3C9));
  __asm__ ("out %%al,%%dx\n"::"a" (b),"d" (0x3C9));


}


void setpalette256()
{
   int j = 0;
   for (j= 0; j < 64; j++)
     setpal(j, j, 0,0);

   for (j= 0; j < 64; j++)
     setpal(j+64, 0,j,0);

   for (j= 0; j < 32; j++)
     setpal(j+128, 0,0,j*2);
   for (j= 32; j < 64; j++)
     setpal(j+128, 0,0,64-2*(j-32));

   for (j= 0; j < 64; j++)
     setpal(j+192, j, j,j);
}


void putpixel(int x,int y, int color) {
  vga_mem[x+320*y]=color;
}


#ifndef _GUI_VGA_REGS_H
#define _GUI_VGA_REGS_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
/*			COLOR emulation		MONO emulation */
#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)

#define VGA_320_200_256 vga_320x200x256


#endif


//---------------------- VIDEO_VGA.CPP-----------------

void video_vga_off()
{
    bochs_vbe_exit_mode();
}
extern char GetKeyPress();

//Colours
#define WINDOW_COLOUR_BORDER 0x00397D02

#define WINDOW_COLOUR_TOPBAR 0x0083F52C
#define WINDOW_COLOUR_FOCUS_TOPBAR 0x007FFF00
#define WINDOW_COLOUR_TOPBAR_TEXT 0x00397D02

#define WINDOW_COLOUR_BACKGROUND 0x00C5E3BF

void video_1();
void video_main()
{


	///uintptr_t 	addr = 0xA0000L;//0xB8000L;

	//vga_mem  = (uint16_t *)(addr - kvirt_to_phys);

    printf("Initialising VGA mode...\n");
    //set_task_priority(PRIO_HIGH);

     //We disable interrupts to speed up the process of switching modes
    disable();
     //Set up the VGA mode

//    char * videomem=(char *)0xE0000000;

    set_vga_mode(VESA_MODE_824);

    video_1();

    enable();

}

/*unsigned char * font ;

 void drawchar ( unsigned char c , int x , int y , int fgcolor , int bgcolor )
 {
	 int cx , cy ;
	 int mask [ 8 ] = { 1 , 2 , 4 , 8 , 16 , 32 , 64 , 128 } ;
	 unsigned char * gylph = font + ( int ) c * 16 ;

	 for ( cy = 0 ; cy < 16 ; cy ++ ) {
		 for ( cx = 0 ; cx < 8 ; cx ++ ) {
			 putpixel ( glyph [ cy ] & mask [ cx ] ? fgcolor : bgcolor , x + cx , y + cy - 12 ) ;
		 }
	 }
 } */

void video_1()
{
	///setpalette256();


	draw_rect(10, 10, 800,600, WINDOW_COLOUR_FOCUS_TOPBAR);

	int height = 300, width = 250;
	unsigned int * data = (unsigned int *) malloc(  (width*height)*(g_bpp/8) );


	plot_rect(0,10,width-100,height-100,WINDOW_COLOUR_FOCUS_TOPBAR,width, (unsigned int *)data);

	//update_screen_TESTE(data);
	refresh_screen();


}

extern "C" Sub init_vga()
{
    video_main();
}
Last edited by cianos on Wed Dec 12, 2012 5:59 pm, edited 1 time in total.
User avatar
Griwes
Member
Member
Posts: 374
Joined: Sat Jul 30, 2011 10:07 am
Libera.chat IRC: Griwes
Location: Wrocław/Racibórz, Poland
Contact:

Re: Screen Black after initilize VESA MODE

Post by Griwes »

Do you seriously think anyone will debug the code for you?
Reaver Project :: Repository :: Ohloh project page
<klange> This is a horror story about what happens when you need a hammer and all you have is the skulls of the damned.
<drake1> as long as the lock is read and modified by atomic operations
User avatar
Kazinsal
Member
Member
Posts: 559
Joined: Wed Jul 13, 2011 7:38 pm
Libera.chat IRC: Kazinsal
Location: Vancouver
Contact:

Re: Screen Black after initilize VESA MODE

Post by Kazinsal »

I can't read that. Use code tags.
Griwes wrote:Do you seriously think anyone will debug the code for you?
Presumably they do. I think they may be in error.
cianos
Posts: 4
Joined: Tue May 10, 2011 11:27 am

Re: Screen Black after initilize VESA MODE

Post by cianos »

Griwes wrote:Do you seriously think anyone will debug the code for you?
Sorry! But I need help.
I wonder if anyone has gone through this problem or have any solution to this problem.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Screen Black after initilize VESA MODE

Post by Brendan »

Hi,

I took a quick look.

For the code that was posted:
  • about 50% needs to be deleted (e.g. diddling with VGA IO ports without knowing if the video card is capable of being 100% VGA compatible at the hardware level, and without knowing if the video card is currently configured for "VGA compatible").
  • about 90% is irrelevant for the problem
  • the 10% that is relevant is just code that calls functions that call functions and a "memcpy()"
  • one of the main pieces that would be relevant (the code for "bochs_vbe_set_mode()") wasn't in the post.
In addition; it seems "unfocused". Either it's meant to be generic code that uses VBE during boot and shouldn't have VGA specific things or Bochs specific things; or it's a generic video driver that uses virtual8086 mode or emulation and VBE that shouldn't have VGA specific things or Bochs specific things; or it's a native video driver that should only have code for a specific video card (and not VGA and Bochs and VBE all at the same time).

In addition; there seems to be some major misunderstanding of how video display memory works in high resolution modes. For 1024*768*32-bpp modes there is a minimum of 1024*768*4 bytes (or 3 MiB) of display memory being used. This is much larger than the old/legacy 64 KiB display memory window from 0x000A0000 to 0x000AFFFF. It's like trying to put a whale into a small gold-fish bowl and not even realising that the whale might not fit.

Analysing all this information, I conclude that someone who knows enough to have written low-level VGA IO port molestation (that seems like it might be valid when used in the correct context) is not someone that wouldn't realise that high resolution video modes are very different; and therefore it's likely that the person who glued all this together didn't write most of it and doesn't understand most of it.

Basically, without actually seeing most of the relevant code, I declare that I have found the problem. The problem was cut & paste.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
cianos
Posts: 4
Joined: Tue May 10, 2011 11:27 am

Re: Screen Black after initilize VESA MODE

Post by cianos »

:shock:
Part of the 90% kernel did in his own hand. But in relation to the ATA drives VGA and had to try several codes because the concept is not yet not clear.After solve the problems they encounter codes will do it again.

A final version.Well I think we should learn from mistakes.

I will analyze the code and try to create specific drive. But I wonder how I do it. I can not find clear references where I can study.If anyone has advise! Thank you. :mrgreen:


--- Desculpe meu inglês, sou brasileiro, e meu inglês é ruim, ---- :D
cianos
Posts: 4
Joined: Tue May 10, 2011 11:27 am

Re: Screen Black after initilize VESA MODE

Post by cianos »

bochsvbe.c

Code: Select all

extern unsigned fb_seg;
extern uint16_t	* vga_mem;

/*
 * This driver is for Plex86/Bochs VBE graphics card (c) Luke Mitchell
 * It will run on plex86 cards, as well as VirtualBox, Qemu and Bochs
 */

static void SetVideoMode(unsigned short width, unsigned short height, unsigned short depth);
static void ExitVideoMode();
static void WriteCommand(unsigned short index, unsigned short value);

void bochs_vbe_set_mode(unsigned short width, unsigned short height, unsigned short depth)
{
    fb_seg = 0xE0000000;
    vga_mem = (uint16_t	*)0xE0000000;
    SetVideoMode(width,height,depth);
}

void bochs_vbe_exit_mode()
{
     ExitVideoMode();
}

static void SetVideoMode(unsigned short width, unsigned short height, unsigned short depth)
{
   WriteCommand(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);
   WriteCommand(VBE_DISPI_INDEX_XRES, width);
   WriteCommand(VBE_DISPI_INDEX_YRES, height);
   WriteCommand(VBE_DISPI_INDEX_BPP, depth);
   WriteCommand(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED );
   //outportb(0x3c0, 0x20);
}

static void ExitVideoMode()
{
   WriteCommand(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);

}

void outw(unsigned short port, unsigned short value)
{
    __asm__ __volatile__ ( "outw %w0, %1" : : "a" (value), "id" (port) );
}

unsigned short inpw(unsigned short port)
{
   unsigned short ret;
   __asm__ __volatile__  ("inw %1,%0":"=a"(ret):"Nd"(port));
   return ret;
}

static void WriteCommand(unsigned short index, unsigned short value)
{
   outw(VBE_DISPI_IOPORT_INDEX, index);
   outw(VBE_DISPI_IOPORT_DATA, value);
}
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Screen Black after initilize VESA MODE

Post by Combuster »

Dumping code is not quite a question... Especially when it's once again copied and pasted.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Screen Black after initilize VESA MODE

Post by bluemoon »

cianos wrote:

Code: Select all

void bochs_vbe_set_mode(unsigned short width, unsigned short height, unsigned short depth)
{
    fb_seg = 0xE0000000;
    vga_mem = (uint16_t	*)0xE0000000;
    SetVideoMode(width,height,depth);
}
1. The LFB is not necessary at E0000000. You should get it from PCI configuration space.
Furthermore, that address would be physical, you may need to mmap it if you use paging.

2. I'm not sure what you want to do with uint16_t* vga_mem, some code used it to read/write 32-bit pixel, while some other code treat it as text memory.
Locked