Home Upgrade Search Memberlist Extras Hacker Tools Award Goals Help Wiki Contact

Assembly 

[SOLVED]Directly access VGA(32 Bit NASM, Linux)

Anyone know how to directly access the VGA. I want to print hello world on the screen instead of in the terminal. Using 32 NASM for Linux.

NVM i found an article on it here ---> http://mattst88.com/programming/?page=APJ

This article will describe how to program VGA graphics Mode 13h using assembly
language. Mode 13h is the 320x200x256 graphics mode, and is fast and very
convenient from a programmer's perspective.

The video buffer begins at address A000:0000 and ends at address A000:F9FF.
This means the buffer is 64000 bytes long and that each pixel in mode 13h is
represented by one byte.

It is easy to set up mode 13h and the video buffer in assembly language:

mov ax,0013h ; Int 10 - Video BIOS Services
int 10h ; ah = 00 - Set Video Mode
; al = 13 - Mode 13h (320x200x256)

mov ax,0A000h ; point segment register es to A000h
mov es,ax ; we can now access the video buffer as
; offsets from register es

At the end of your program, you will probably want to restore the text mode.
Here's how:

mov ax,0003h ; Int 10 - Video BIOS Services
int 10h ; ah = 00 - Set Video Mode
; al = 03 - Mode 03h (80x25x16 text)

Accessing a specific pixel int the buffer is also very easy:

; bx = x coordinate
; ax = y coordinate
mul 320 ; multiply y coord by 320 to get row
add ax,bx ; add this with the x coord to get offset

mov cx,es:[ax] ; now pixel x,y can be accessed as es:[ax]

Hmm... That was easy, but that multiplication is slow and we should get rid of
it. That's easy to do too, simply by using bit shifting instead of multiplica-
tion. Shifting a number to the left is the same as multiplying by 2. We want to
multiply by 320, which is not a multiple of 2, but 320 = 256 + 64, and 256 and
64 are both even multiples of 2. So a faster way to access a pixel is:

; bx = x coordinate
; ax = y coordinate
mov cx,bx ; copy bx to cx, to save it temporatily
shl cx,8 ; shift left by 8, which is the same as
; multiplying by 2^8 = 256
shl bx,6 ; now shift left by 6, which is the same as
; multiplying by 2^6 = 64
add bx,cx ; now add those two together, whis is
; effectively multiplying by 320
add ax,bx ; finally add the x coord to this value
mov cx,es:[ax] ; now pixel x,y can be accessed as es:[ax]

Well, the code is a little bit longer and looks more complicated, but I can
guarantee it's much faster.

To plot colors, we use a color look-up table. This look-up table is a 768
(3x256) array. Each index of the table is really the offset index*3. The 3
bytes at each index hold the corresponding values (0-63) of the red, green,
and blue components. This gives a total of 262144 total possible colors.
However, since the table is only 256 elements big, only 256 different colors
are possible at a given time.

Changing the color palette is accomplished through the use of the I/O ports of
the VGA card:

Port 03C7h is the Palette Register Read port.
Port 03C8h is the Palette Register Write port
Port 03C9h is the Palette Data port

Here is how to change the color palette:

; ax = palette index
; bl = red component (0-63)
; cl = green component (0-63)
; dl = blue component (0-63)

mov dx,03C8h ; 03c8h = Palette Register Write port
out dx,ax ; choose index

mov dx,03C9h ; 03c8h = Palette Data port
out dx,al
mov bl,al ; set red value
out dx,al
mov cl,al ; set green value
out dx,al
mov dl,al ; set blue value

Thats all there is to it. Reading the color palette is similar:

; ax = palette index
; bl = red component (0-63)
; cl = green component (0-63)
; dl = blue component (0-63)

mov dx,03C7h ; 03c7h = Palette Register Read port
out dx,ax ; choose index

mov dx,03C9h ; 03c8h = Palette Data port
in al,dx
mov bl,al ; get red value
in al,dx
mov cl,al ; get green value
in al,dx
mov dl,al ; get blue value

Now all we need to know is how to plot a pixel of a certain color at a certain
location. Its very easy, given what we already know:

; bx = x coordinate
; ax = y coordinate
; dx = color (0-255)
mov cx,bx ; copy bx to cx, to save it temporatily
shl cx,8 ; shift left by 8, which is the same as
; multiplying by 2^8 = 256
shl bx,6 ; now shift left by 6, which is the same as
; multiplying by 2^6 = 64
add bx,cx ; now add those two together, whis is
; effectively multiplying by 320
add ax,bx ; finally add the x coord to this value
mov es:[ax],dx ; copy color dx into memory location
; thats all there is to it

Ok, we now know how to set up Mode 13h, set up the video buffer, plot a pixel,
and edit the color palette.

My next article will go on to show how to draw lines, utilize the vertical
retrace for smoother rendering, and anything else I can figure out by that
time...

I can do it without this part:

; al = 03 - Mode 03h (80x25x16 text)

Just got to keep other things into one Array makes it easier to understand/read. You should look over a russiancoding ;)


Possibly Related Threads...
Thread / Author Replies Views Last Post
[Assembly] by ToyBoyAug 1, 2021 06:20 PM 0 180 Aug 1, 2021 06:20 PM
Last Post: ToyBoy
[Assembly] by MordiciaMay 2, 2019 11:36 AM 0 307 May 2, 2019 11:36 AM
Last Post: Mordicia
[Assembly] by friiz1337Jan 27, 2019 03:27 PM 10 559 Jan 27, 2019 03:27 PM
Last Post: friiz1337