Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

SVGA pixel question

Status
Not open for further replies.

adholioshake

Programmer
Feb 9, 2003
136
Hi everyone.

I have started some simple graphics routines in assembly for SVGA resolution. The code I have written for a simple line is shown below. I am using an interrupt to set the pixel. However, this is very slow! Does anyone know how to access the graphics memory area directly for SVGA? (I don't know the base address for SVGA). Any help would be appriciated. :)
Adonai
Code:
code segment
  assume cs:code
  org 100h

program:
  jmp start
  ; data area...
  xpos dw 100
  ypos dw 100
   len dw 100
   col db 4
   dir db 0

start:
; set svga mode...
  mov ax,4f02h
  mov bx,0101h
  int 10h

; draw a line...
  call line

; wait for keypress...
  mov ah,00h
  int 16h

; set text mode
  mov ax,0003h
  int 10h

; terminate.
  mov ax,4c00h
  int 21h

; Line routine
line:
  mov cx,len
  xor di,di
lp1:
  push cx
  mov ah,0ch
  mov bx,0001h
  mov al,col
  mov cx,xpos
  mov dx,ypos
  cmp dir,00h
  je xl1
yl1:
  add dx,di
  jmp drawl
xl1:
  add cx,di
drawl:
  int 10h
  inc di
  pop cx
  loop lp1
  ret

ends
end program
 
sure do :)

THE SEGMENT FOR VIDEO MEMORY is 0a000H.

CX=X
DX=Y

mov AX,0A000h
mov ES,AX
;Calculate Pixel Address = ((Y*BPL)+X)
mov DI,CX
mov AX,DX
mov CX,320;bytes per line
mul CX
add DI,AX
;Write Pixel
mov [byte ptr ES:DI],40;Red

This will only work if you are in 320x200 because
320x200 is exactly 64K, and the video memory 'window'
which you can write to is only 64k.

To Get To the rest of the screen, you have to do whats
called bank switching. INT 10h,4F05h is the easiest,
but it also uses BIOS. And you already know that is slow :)

Now that you have the code to plot a pixel, I would suggest searching for VESA documentation. There is a function
you can call which will give you a far pointer to the on card hardware version of the 4F05h call. This is much faster
than the INT call, but I dont have enough room here to explain Everything for you :)

See what you can do now, and come back if you are still stumped.

DataC

DataC5155

"...NO FATE..."
 
There are two completely separate issues here.

(1) VESA graphics. Yes, you can access high-resolution screens using VESA, if your user has it installed, and then you need to think about memory banking. But it still won't get you round basic VGA graphics, because all that VESA does for you is allows you to enter high resolution sVGA modes (beyond 640*480 dots etc), and allows you to memory bank to see the memory needed for these modes. It doesn't do anything about how the VGA card handles your memory accesses.

(2) VGA graphics. The VGA card is a large and complex thing. The code datac5 wrote above only applies to 256-colour modes, where 1 byte = 1 pixel, and that is the reason that it is stuck with 320*200 pixel graphics. You can happily write up to 640*480 if you use 16 colour graphics, and you don't need memory banking to do it. It's VGA standard using the 64K addressed memory from 0A000h. But the way it works is that each row of 8 pixels is accessed as a single byte, 1 bit per pixel. Obviously you need 4 bits to encode 16 colours, so the 4 bits are situated on 4 different "planes" of memory, and which you access depends on ports in the VGA card. This may look like a disadvantage, but actually it vastly improves the speed of access. A single write can set 8 pixels to the colour you want, leaving the rest either black, or unchanged, according to how you've set the card up!
(incidentally, you can "cheat" and use these planes to increase the resolution of 256 colour graphics way beyond 320*200. This is the basis of the Mode X stuff people write about).

My advice: GET MICHAEL ABRASH's graphics book "big black book". It has all the details, though in my opinion not the clearest explanation ever. But the fullest and most filled with examples that really work.

Yes, you are absolutely right, the bios graphics interrupt is gruesomely slow. If you start writing stuff using the VGA card directly, you'll be shocked by the change.

 
Hi lionelhill.

Do you know where I can get ABRASH's graphics book from ?
Some of his examples could be really helpful...

Thanks, Adonai.
 
I don't think you'll find it, the place where I downloaded it (PDF of scanned images, a few hundred megs) had disappeared when I checked it recently. The book itself is out of print, so you'll have to search for a second hand copy.

About VESA, you can download the VESA BIOS Extension Specifcation at
Regards,
Bert Vingerhoets
vingerhoetsbert@hotmail.com
Don't worry what people think about you. They're too busy wondering what you think about them.
 
sorry, then maybe search around for VGA card generalities. I can e-mail odd bits of code if that would help, but really without a basic view of the VGA card's data flow, the code on its own will make little sense...
 
Most of Michael Abrash's books have gone out of print.
I did manage to get the Zen of Graphics Programming that he wrote. The dude sure knows a lot about low-level graphics!
He helped design the Quake 3d engines, and more recently optimized the Xbox (or so I have read...).

Thanx everyone for the info.

Adonai
 
I know that if you use VESA there's an interrupt you can call to get the base address for the SVGA memory... last I remember, though, I tried it out when I was doing dos 32bit protected mode assembler, and found that the memory mapping scheme for even a simple 800x600 16bit was DIFFICULT to work with.

You have to manage the pallette as well as switching banks when you get to different quadrants of the screen... it's a mess :)

--------
It is an honor to recieve an honest reply. (Prov 24:26)
 
Hi Adonai,

I am also trying to write to the video memory for the SVGA (640X480 256 colors) video chip. I know the base address is 0xA0000. I have initialized the mode to be 0x101 and wrote assembly (32-bit) code to draw pixels:

movb $0x4f,%ah
movb $0x02,%al
movb $0x01,%bh /* mov mode 0101h into BX reg. */
movb $0x01,%bl
int $0x10 /* Call BIOS Int 0x10 */

/* Set the DAC palette width to 8 bits per primary color */

movb $0x4F, %ah /* DAC Palette Format function (AX = 4F08h) */
movb $0x08, %al
movb $0x00, %bl /* Set DAC Palette Format */
movb $0x08, %bh /* Desired bits of color per primary = 8 */
int $0x10


movb 0x0F, %ah /* Gets and saves current video mode*/
int $0x10
push %ax

movb 0x013, %ax /*Turn on mode 13 graphics*/
int $0x10

movb 0xA000, %ax /* The segment address of video memory */
movb %ax, %es /* Set ES to point to the video segment */
movb 0, %bx /* Beginning offset to BX */
movb 4, %al /* AL contains red */
movb $0x0A, %cx /* Coordinate args */
movb $0x0A, %dx
int $0x10

pop %ax /* Restore original graphics mode */
movb 0, %ah
int $0x10

movb 0x4c00, %ax /* Exit program */
int $0x12

This piece of code does not work. I don't know what I am doing wrong. I am hoping I have the correct mode (0x101h). Also I have picked up assembly after a long time. Any help from you would be highly appreciated.

Regards,
shashi
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top