OSDev.org

The Place to Start for Operating System Developers
It is currently Wed Apr 17, 2024 7:03 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 14 posts ] 
Author Message
 Post subject: VGA screen doesn't fill
PostPosted: Sat Oct 31, 2020 10:49 am 
Offline

Joined: Mon Nov 25, 2019 1:05 pm
Posts: 15
Location: Italy
Hello everyone!
I've set the video mode 12 (640x480x8) with GRUB as follows:

Code:
MBALIGN  equ  1 << 0            ; align loaded modules on page boundaries
MEMINFO  equ  1 << 1            ; provide memory map
VIDINFO  equ 1 << 2
FLAGS    equ  MBALIGN | MEMINFO | VIDINFO ; this is the Multiboot 'flag' field
MAGIC    equ  0x1BADB002        ; 'magic number' lets bootloader find the header
CHECKSUM equ -(MAGIC + FLAGS)   ; checksum of above, to prove we are multiboot


section .multiboot
align 4
   dd MAGIC
   dd FLAGS
   dd CHECKSUM

  dd 0,0,0,0,0
  dd 0
  dd 640, 480, 8

section .bss
align 16
stack_bottom:
resb 16384 ; 16 KiB
stack_top:

; The linker script specifies _start as the entry point to the kernel and the
; bootloader will jump to this position once the kernel has been loaded. It
; doesn't make sense to return from this function as the bootloader is gone.
; Declare _start as a function symbol with the given symbol size.
section .text
global _start:function (_start.end - _start)
_start:
  mov esp, stack_top
  cli
  push ebx
  extern kmain
  call kmain

   cli
.hang:   hlt
   jmp .hang
.end:


I've made some functions to printing pixel on the screen:
Code:
void putpixel(int color, int x , int y) {
  unsigned int *pixel = (unsigned int*) 0xA0000 + y * 640 + x;
  *pixel = color;
}

void cls_graph() {
  for (int r = 0; r < 480; r++) {
    for (int c = 0; c < 640; c++) {
      putpixel (BLUE, c, r);
    }
  }
}


Note: "BLUE" corresponds to "1".

but my screen became like this photo:
Image

I've tried also with an unsigned char* framebuffer, and the screen became like this:
Image

Then, with an uint16_t framebuffer:
Image

What am I doing wrong?


Top
 Profile  
 
 Post subject: Re: VGA screen doesn't fill
PostPosted: Sat Oct 31, 2020 11:03 am 
Offline
Member
Member

Joined: Fri Nov 22, 2019 5:46 am
Posts: 590
In mode 0x12 the bits are organized in planes.
https://wiki.osdev.org/VGA_Hardware#Mem ... hics_modes


Top
 Profile  
 
 Post subject: Re: VGA screen doesn't fill
PostPosted: Sat Oct 31, 2020 4:21 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5137
maurotram wrote:
I've set the video mode 12 (640x480x8) with GRUB as follows:

VGA mode 12h is 640x480x4.

maurotram wrote:
What am I doing wrong?

You are making assumptions about the frame buffer that are incorrect. You must use the multiboot information structure to determine the address, size, and pixel format of the frame buffer.


Top
 Profile  
 
 Post subject: Re: VGA screen doesn't fill
PostPosted: Sat Oct 31, 2020 4:24 pm 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
Hi,

maurotram wrote:
Hello everyone!
I've set the video mode 12 (640x480x8) with GRUB
There's no such thing. Either you use mode 12 (which is 640x480x4bit or 640x480x16colors), or you use a VESA mode 640x480x8bit (or 640x480x256colors). For the first (4 bit, 16 colors) see the link PeterX provided, as it does use planes. For the second (8 bit, 256 colors), you'll have an unsigned char* buffer, but with palette indices. That means you set up 256 individual colors with RGB values in the VGA DAC registers, and you write the index into the buffer. Therefore index 1 could be green or red. Either way, you can't use direct blue channel. For that, you'll need VESA 640x480x15bit or 640x480x16bit hi-color mode, where the RGB channels are encoded as 1-5-5-5 (most significant bit being zero) or 5-6-5 respectively. But I'd suggest to use 640x480x32bit at least, where each pixel encoded as unsigned int, and each channel is one byte (the most significant byte being zero).

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: VGA screen doesn't fill
PostPosted: Sat Oct 31, 2020 5:21 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5137
bzt wrote:
That means you set up 256 individual colors with RGB values in the VGA DAC registers,

You can't assume that any video mode will be register-compatible with VGA. You must either use the palette information provided in the Multiboot information structure or request and use VBE information to determine if the video mode supports VGA register access.


Top
 Profile  
 
 Post subject: Re: VGA screen doesn't fill
PostPosted: Sun Nov 01, 2020 6:21 am 
Offline
Member
Member

Joined: Tue Feb 18, 2020 3:29 pm
Posts: 1071
Or you can have GRUB set up a VBE mode and avoid all that legacy stuff :D .

_________________
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg


Top
 Profile  
 
 Post subject: Re: VGA screen doesn't fill
PostPosted: Sun Nov 01, 2020 7:35 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
Octocontrabass wrote:
You can't assume that any video mode will be register-compatible with VGA.
Normally that's true, however with palette modes you can always be sure that you'll be able to use the palette DAC registers. Those modes have fixed mode codes too, 100h-110h or something. (Nobody uses palette modes these days, and VGA registers (DAC, CRTC etc.) are usually unsupported for true color modes.)

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: VGA screen doesn't fill
PostPosted: Sun Nov 01, 2020 10:49 am 
Offline

Joined: Mon Nov 25, 2019 1:05 pm
Posts: 15
Location: Italy
Thanks for replies.
I've decided to use VBE mode 800x600x16. I've set this in my bootsector as follows:
Code:
mov ax, 0  ;segment 0
mov es, ax
mov di, 0x1000  ;offset 1000
mov ax, 0x4F01  ;get VBE mode information block
mov cx, 0x4114  ;graphic mode 800x600 16 bpp
int 0x10  ;load informations

;set VESA video mode
mov ax, 0x4F02  ;set VBE graphic mode
mov bx, 0x4114  ;graphic mode 800x600 16bpp
int 0x10  ;start BIOS interrupt


My code for setting up VESA:
Code:
void read_vesa_info(void) {
  uint32_t *vesablockd = (uint32_t *) 0x1000;  //position of Vesa Mode Info Block loaded by bootloader dword read
  uint16_t *vesablockw = (uint16_t *) 0x1000;  //position of Vesa Mode Info Block loaded by bootloader word read
  uint8_t *vesablockb = (uint8_t *) 0x1000;  //position of Vesa Mode Info Block loaded by bootloader byte read
  vesa_lfb=vesablockd[10];  //Linear Frame Buffer position
  vesa_x=vesablockw[9];
  vesa_y=vesablockw[10];
  vesa_bpp=vesablockb[23];
}
//putpixel function
void pixel(int line, int column, uint16_t color) {
    uint16_t *pixel = (uint16_t*) vesa_lfb + line * vesa_x + column;  //start of frame buffer
    pixel = color;
}


I'm sure that this functions work, because I've tried to draw a line and it has worked. But when I try to draw the letter 'A' that is stored in an array, nothing is being printed!!

Code:
static const int a_ch[128] = {
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,1,0,0,0,0,
0,0,1,1,1,0,0,0,
0,1,1,0,1,1,0,0,
1,1,0,0,0,1,1,0,
1,1,0,0,0,1,1,0,
1,1,1,1,1,1,1,0,
1,1,0,0,0,1,1,0,
1,1,0,0,0,1,1,0,
1,1,0,0,0,1,1,0,
1,1,0,0,0,1,1,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
};

//zeros are blacks, ones are white
for (int r = line; r < line + 16; r++) {
        for (int c = column; c < column + 8; c++) {
          if (a_ch[index] == 0) pixel(r, c, WHITE);
          if (a_ch[index] == 1) pixel(r, c, BLACK);
          index++;
        }
      }
      col+=8;




This function would read the array and fill the pixels, but it doesn't. What am I doing wrong?

P.S. WHITE = 0xFFFF and BLACK = 0x0000, remember that the screen is filled WHITE.
P.P.S. the code for printing the letter A is in a function, where column and line are set to 10.


Top
 Profile  
 
 Post subject: Re: VGA screen doesn't fill
PostPosted: Sun Nov 01, 2020 11:25 am 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
maurotram wrote:
This function would read the array and fill the pixels, but it doesn't. What am I doing wrong?
We don't know because that's not enough information. Try to print all vesa properties (fb address, width, pitch, height).

However using a function like this is a very bad idea, so is storing one byte per pixel in the font. The problem with the former is that it unnecessarily calculates screen offset for every pixel, and with the latter that it uses enormous amount of RAM. A font for 65536 UNICODE characters would require 8 megabytes of memory. Using bitmaps requires 1/8th. Take a look at PC Screen Font on the wiki. It has an example code (still not optimal, but lightyears better than your current implementation). Another advantage that you can use already existing PSF font files, no need to create large C arrays. Or if even that's too much coding for you, then just include the Scalable Screen Font library (standalone header file, no linking required) and use ssfn_putc(), which does exactly what your function supposed to do, displays one glyph.

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: VGA screen doesn't fill
PostPosted: Sun Nov 01, 2020 11:37 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5137
bzt wrote:
with palette modes you can always be sure that you'll be able to use the palette DAC registers. Those modes have fixed mode codes too, 100h-110h or something.

Both of these statements are false. You must check the VBE mode information for VGA-compatible register access, and VBE 2+ does not have fixed mode numbers (I own one PC that uses those "fixed" mode numbers for incompatible modes).


Top
 Profile  
 
 Post subject: Re: VGA screen doesn't fill
PostPosted: Sun Nov 01, 2020 2:17 pm 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
Octocontrabass wrote:
Both of these statements are false. You must check the VBE mode information for VGA-compatible register access,
Nope, I'm not wrong. How do you supposed to set the palette for palette modes without VGA compatible registers? All 256 color VBE modes are guaranteed to have VBE info block offset 0Ah capabilities flags bit 0 "DAC-registers" to be set. For hi-color and true-color modes which use packed pixels the DAC registers aren't needed in the first place (so it doesn't matter if those modes support VGA-compatible DAC registers or not).

Octocontrabass wrote:
VBE 2+ does not have fixed mode numbers (I own one PC that uses those "fixed" mode numbers for incompatible modes).
Both the VESA spec and RBIL contradicts you. Furthermore, vendor specific modes are very rarely use 256 colors, they are mostly hi-color or true-color, and since VBE 1.2+ it is not possible to specify palette mode with non-fixed mode code (the VBE struct contains packed pixel masks and offsets for the channels at offset 1Fh which makes only sense with non-palette modes).

However this doesn't matter at all, because as I've said nobody uses palette modes any more. With packed pixels you don't need a DAC, period.

Cheers,
bzt


Last edited by bzt on Sun Nov 01, 2020 2:26 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: VGA screen doesn't fill
PostPosted: Sun Nov 01, 2020 2:24 pm 
Offline
Member
Member

Joined: Tue Feb 18, 2020 3:29 pm
Posts: 1071
@bzt and @Octocontrabass: Stop fighting about VGA! The OP is now satisfied. You two have fought about VGA before. Just except your differences and go on with life. P. S....
klange wrote:
StudlyCaps wrote:
Not to cause any more drama, but if there's going to be a change in moderation policy, please can you describe less ambiguously what the undesirable behaviour is?

There is no change in policy here, more just a reminder of what has been in the rules for years: "No flaming. No obscenities. Don't provoke fights or participate in fights started by others."

Generally, the forum has been a positive environment and it is rare that we have users who disobey these rules to a degree where action needs to be taken, but there have been a few instances in the past.

Personally, I would prefer that all of my moderation time be invested in the removal of spam rather than breaking up fights and deciding on punitive measures for otherwise productive contributors who have chosen a hill to die on.

klange wrote:
Following on Octocontrabass's comment... I was also added to the moderation team entirely to fight spam, though I do have access to the moderation controls so I can take punitive measures where necessary. It is clear to me that a handful of our members have exhibited some undesirable behavior on the forums in the last year or so, and they should know who they are. I will keep this brief: Knock it off, or I will take matters into my own hands.

Now will you stop?

_________________
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg


Top
 Profile  
 
 Post subject: Re: VGA screen doesn't fill
PostPosted: Sun Nov 01, 2020 2:31 pm 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
nexos wrote:
Now will you stop?
Please leave me out of this, I did nothing wrong, it wasn't me who started the bad vibe! Thanks! For me this conversation is over, btw. as the OP is satisfied.

Cheers,
bzt


Top
 Profile  
 
 Post subject: Re: VGA screen doesn't fill
PostPosted: Sun Nov 01, 2020 2:35 pm 
Offline
Member
Member

Joined: Tue Feb 18, 2020 3:29 pm
Posts: 1071
bzt wrote:
Please leave me out of this, I did nothing wrong

Forum rules wrote:
Don't provoke fights or participate in fights started by others.

_________________
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: SemrushBot [Bot] and 304 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group