Page 3 of 3

Re:Using framebuffer to build GUI

Posted: Tue Jun 22, 2004 10:23 am
by amirsadig
respect for quicly solution, which is very simple.

Re:Using framebuffer to build GUI

Posted: Thu Jul 01, 2004 11:41 am
by SANiK

Code: Select all

//#include "halfix/plugindev.h"

//Typedefs
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned int dword;

typedef signed char sbyte;
typedef signed short sword;
typedef signed int sdword;

//Defines
#define SUCCESS 1
#define FAILURE 0
#define NULL    (void*)0

//Utils
byte strncmp(byte *a_string1, byte *a_string2, dword a_len)
{
  dword _count=0;
  
  while(_count<a_len)
  {
    if(a_string1[_count] != a_string2[_count])
    {
      return FAILURE;
    }
    _count++;
  }
  
  return SUCCESS;
}

//DEBUG.inc variables
word *pdebug;
byte debug_x;
byte debug_y;
byte debug_color;

//DEBUG.inc functions
byte debug_init()
{
  debug_color=0x7;
  debug_x=0;
  debug_y=0;
  pdebug=(word*)0xB8000;
  
  return SUCCESS;
}

void debug_clear()
{
  dword _count=0;
  
  while(_count<(80*25))
  {
    pdebug[_count]=(byte)' ' | (debug_color<<8);
    
    _count++;
  }
  
  debug_x=0;
  debug_y=0;
}

void debug_next()
{
  if(debug_y>=25)
  {
    debug_clear();
  }
  else
  {
    debug_x=0;
    debug_y++;
  }
}

void debug_write(byte *a_string)
{
  dword _count=0;
  
  while(a_string[_count]!='\0')
  {
    if(debug_x >= 80)
    {
      debug_x=0;
      
      if(debug_y>=25)
      {
        debug_clear();
      }
      else
      {
        debug_y++;
      }
    }
    
    pdebug[debug_y*80+debug_x]=(byte)a_string[_count] | (debug_color<<8);
    
    debug_x++;
    _count++;
  }
}

//VESA.inc structures
//Note, gotten from VESA.org docs, not my structs
typedef struct VESA_PMID
{
  byte pmid[4];        //PM Info Block Signature
  dword entry;         //Offset of PM entry point within BIOS
  dword PMInitialize;  //Offset of PM initialization entry point
  dword BIOSDataSel;   //Selector to BIOS data area emulation block
  dword A0000Sel;      //Selector to access A0000h physical mem
  dword B0000Sel;      //Selector to access B0000h physical mem
  dword B8000Sel;      //Selector to access B8000h physical mem
  dword CodeSegSel;    //Selector to access code segment as data
  byte InProtectMode; //Set to 1 when in protected mode
  byte Checksum;       //Checksum byte for structure
} VESA_PMID;

//VESA.inc variables
VESA_PMID *pvesa_pmid=NULL;
//byte *pbiosdatasel=NULL;

//VESA.inc functions
byte vesa_crc(VESA_PMID *a_pmid)
{
  byte *_pvesacrc=(byte*)a_pmid;
  byte _CRC=0;
  word _total=sizeof(VESA_PMID);
  
  while(_total>0)
  {
    _CRC+=*_pvesacrc;
    _pvesacrc++;  //Prev9999: pointer bug fixed
    
    _total--;
  }
  
  if(_CRC != 0)
  {
    return FAILURE;
  }  
  else
  {
    return SUCCESS;
  }
}

byte vesa_init()
{
  byte *_pvideo=(byte*)0xC0000;
  dword _size=0;
  dword _count=0;
  
  if((_pvideo[0] != 0x55) || (_pvideo[1] != 0xAA))
  {
    debug_write("Failed to find VIDEO ID 1"); debug_next();
    
    return FAILURE;
  }
  
  debug_write("Found VIDEO ID 1"); debug_next();
  
  _size=_pvideo[2]*512;
  
  vesa_init_continue:
  while(_count<_size)
  {
    if(strncmp("PMID", _pvideo, 4) == SUCCESS)
    {
      debug_write("Found VIDEO ID 2"); debug_next();
      
      //Here it really begins
      pvesa_pmid=(VESA_PMID*)0xC0000+_count;
      
      //Attempt the VESA checksum
      if(vesa_crc((VESA_PMID*)pvesa_pmid) == FAILURE)
      {
        debug_write("VIDEO ID 2 was a false alarm"); debug_next();
        debug_write("Or, the programmer screwed up"); debug_next();
        debug_write("Continuing the search..."); debug_next();
        
        _count++; //Prevents the same PMID being found
        
        continue;
      }

      debug_write("VIDEO ID 2 was verified, and all systems GO"); debug_next();
      
      //vesa_setup((VESA_PMID*)pvesa_pmid);
      
      return SUCCESS;
    }
    
    *_pvideo++;
    _count++;
  }
  
  debug_write("Failed to find VIDEO ID 2"); debug_next();
  debug_write("Might you be on VMWare or Bochs?"); debug_next();
  debug_write("Also, this only works on newer vesa cards"); debug_next();
}

//MAIN.c functions
void main()
{
  debug_init();
  vesa_init();
  
  debug_write("Please turn off your PC now");
  debug_next();
}

Sometimes, rebooting is illogical just to switch a video mode.
VESA Pmode doesn't support text modes, but I have a VGA plugin to deal with that. It's pretty sweet though how one can zoom in/out out of modes without rebooting.

And stop using VMware or Bochs to test things 24/7.
I have one PC, and I reboot it to test my works. I am sick of these people believing, "Oh, geeh, if it don't work in VMWare, it won't work on anything else."
I also wonder how many of you really bought VMWare.

Re:Using framebuffer to build GUI

Posted: Thu Jul 01, 2004 12:58 pm
by Curufir
And stop using VMware or Bochs to test things 24/7.
I have one PC, and I reboot it to test my works. I am sick of these people believing, "Oh, geeh, if it don't work in VMWare, it won't work on anything else."
I'd agree with the general sentiment (Don't trust the emulator to be perfect), but a lot of people with only one PC don't like constantly rebooting on every little change (Me included), because it breaks up the coding process. I tend to use Qemu/Bochs as a quick check while I'm hacking away on a piece of code and then run through on real hardware at the end of the day to verify.

Just a pity I turned my test machine into router :(.

Re:Using framebuffer to build GUI

Posted: Thu Jul 01, 2004 11:18 pm
by Brendan
Hi,
Curufir wrote: I'd agree with the general sentiment (Don't trust the emulator to be perfect), but a lot of people with only one PC don't like constantly rebooting on every little change (Me included), because it breaks up the coding process. I tend to use Qemu/Bochs as a quick check while I'm hacking away on a piece of code and then run through on real hardware at the end of the day to verify.
I'd also agree with the general sentiment, but I'd go even further. Don't trust the emulator/s, and don't trust a single PC - especially if you're doing something unusual with the hardware.

For example, I wrote a PS/2 driver that allows 2 keyboards to be plugged in (instead of the usual keyboard & mouse). Bochs behaved differently to all PC's, and out of 10 PC's there where 4 main differences with how the 8042 (or "compatible") chip behaved. My driver wouldn't have worked on a lot of computers if I relied on just one real PC.

Cheers,

Brendan

Re:Using framebuffer to build GUI

Posted: Fri Jul 02, 2004 2:13 pm
by SANiK
BTW, I hope you guys know the formula which is to read 0xC0000 and to check the first two bytes to be 0xAA55
If so, you read the 3rd byte * 512 = size of video rom.
Why I say this? Linux had a bug in it this whole time that cut the BIOS off at 32 kb. If you card is greater than 32kb, update your video drivers which also contain a fix to this bug. I also hear the they fixed this bug not log ago in the kernel. So, update your kernel if you want.

Also, it has been found that VBE3 cards existed in 1999 adding more support to PMID. Truth is, if a card is a 3D card (chances are lower with Voodoo cards), chances are that it has support for protected mode entry. So, A LOT of cards support this nowadays.