VGA screen doesn't fill

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.
Post Reply
maurotram
Posts: 15
Joined: Mon Nov 25, 2019 1:05 pm
Location: Italy

VGA screen doesn't fill

Post by maurotram »

Hello everyone!
I've set the video mode 12 (640x480x8) with GRUB as follows:

Code: Select all

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: Select all

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?
PeterX
Member
Member
Posts: 590
Joined: Fri Nov 22, 2019 5:46 am

Re: VGA screen doesn't fill

Post by PeterX »

In mode 0x12 the bits are organized in planes.
https://wiki.osdev.org/VGA_Hardware#Mem ... hics_modes
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: VGA screen doesn't fill

Post by Octocontrabass »

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.
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: VGA screen doesn't fill

Post by bzt »

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
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: VGA screen doesn't fill

Post by Octocontrabass »

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.
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: VGA screen doesn't fill

Post by nexos »

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
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: VGA screen doesn't fill

Post by bzt »

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
maurotram
Posts: 15
Joined: Mon Nov 25, 2019 1:05 pm
Location: Italy

Re: VGA screen doesn't fill

Post by maurotram »

Thanks for replies.
I've decided to use VBE mode 800x600x16. I've set this in my bootsector as follows:

Code: Select all

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: Select all

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: Select all

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.
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: VGA screen doesn't fill

Post by bzt »

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
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: VGA screen doesn't fill

Post by Octocontrabass »

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).
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: VGA screen doesn't fill

Post by bzt »

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.
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: VGA screen doesn't fill

Post by nexos »

@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
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: VGA screen doesn't fill

Post by bzt »

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
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: VGA screen doesn't fill

Post by nexos »

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
Post Reply