I'm trying to make some code that directly interfaces with the VGA card(in real mode), I know the ports(0x3c6, 0x3c7, 0x3c8, 0x3c9) I need to use to output data on the screen. My code is this:

mov ax, 0
out 0x3c8, ax ;plot pixel at location 0
mov ax, 4
out 0x3c9, ax ;output color index 4 to screen

First off this code doesn't work, second, I get warnings during assembling (with nasm) it.
The warnings are all the same this:
"warning: unsigned byte value exceeds bounds", I can't seem to fix this what may be wrong?


Ports:
0x3c6 = palette mask port
0x3c7 = Read port
0x3c8 = Write port
0x3c9 = Data port

Recommended Answers

All 15 Replies

use a register for destination

mov ax,0
mov di,03c8H
mov word ptr [di],ax

use a register for destination

mov ax,0
mov di,03c8H
mov word ptr [di],ax

I tried that two different ways which both failed the first was:

mov ax, 0
	mov di, 0x3c8
	out [di], ax
	mov ax, 4
	mov di, 0x3c9
	out [di], ax

The error I got for this was:
"error: invalid combination of opcode and operands"
which was what I always get if I try to store the port number for a in, out instruction then use it. Also I don't get why you have to put di in brackets("[]"). Ports arn't memory locations(there for you don't need a pointer), are they?


The other one was exactly what you gave me:

mov ax, 0
	mov di, 0x3c8
	out word ptr [di], ax
	mov ax, 4
	mov di, 0x3c9
	out word ptr [di], ax

For this I got the error:
"error: comma, colon or end of line expected"
I don't really know what this error is meaning.

So sorry -- I was thinking of mov not out.

Are you writing inline code in a C program? I see you are using 0x3c8, which is C styly way or writing a hexidecimal number, instead of 03c8H, which is assembly way of writing it.

What C compiler are you using? out istruction is not valid with any 32-bit compiler but ok with 16-bit compilers such as Turbo C.

So sorry -- I was thinking of mov not out.

Are you writing inline code in a C program? I see you are using 0x3c8, which is C styly way or writing a hexidecimal number, instead of 03c8H, which is assembly way of writing it.

What C compiler are you using? out istruction is not valid with any 32-bit compiler but ok with 16-bit compilers such as Turbo C.

I am using nasm with 16-bit code. Nasm does except hex as 0x3c8 or 3c8h, I just per fur the first.

The out instruction outputs just one byte -- such as al. In the code you originally posted change out ax to out al

The out instruction outputs just one byte -- such as al. In the code you originally posted change out ax to out al

O ok, also do I have to put brackets("[]") on a register if it has a port number in it?

I tried it and here is my code:

mov ah, 4
	out 0x3c8, ah ;plot pixel at position 4 in array
	out 0x3c9, ah ;plot pixel with color number 4

And I get an error of:
"error: invalid combination of opcode and operands"

Read the documentation carefully. You manage to violate practically all restrictions for the out instruction:

out	Output (write) to port
  Syntax:	out	op, AL
  		out	op, AX
  op: 8-bit immediate or DX
  Action: If source is AL, write byte in AL to 8-bit port op.
          If source is AX, write word in AX to 16-bit port op.
  Flags Affected: None

1. You may not output ah. Only ax and al are valid
2. You may not have a 16-bit immediate as the port number.

So,

mov dx, 0x3c8
    mov al, 4
    out dx, al

Read the documentation carefully. You manage to violate practically all restrictions for the out instruction:

out	Output (write) to port
  Syntax:	out	op, AL
  		out	op, AX
  op: 8-bit immediate or DX
  Action: If source is AL, write byte in AL to 8-bit port op.
          If source is AX, write word in AX to 16-bit port op.
  Flags Affected: None

1. You may not output ah. Only ax and al are valid
2. You may not have a 16-bit immediate as the port number.

So,

mov dx, 0x3c8
    mov al, 4
    out dx, al

I tried it like that and it did not get any errors, but still seems to not work.
Can you possibly see what's wrong:

mov ax, 0x13
	int 0x10
	mov al, 4
	mov dx, 0x03c8
	out dx, al
	mov dx, 0x03c9
	out dx, al

Also were did you get the info on the out instruction could I possibly have the link?

Now that you got rid of errors, it's time to read more on VGA. Writing 4 to the port 3c8 sets the internal pointer to the 4th palette entry. Successive write of 4 to the port 0x3c9 sets the Red value of that entry to 4. You probably want two more writes to the same port to complete the entry with Green and Blue values.

If you want to see something on the screen, read here for example. And again, read the documentation carefully. VGA is a very unfriendly piece of silicon.

Now that you got rid of errors, it's time to read more on VGA. Writing 4 to the port 3c8 sets the internal pointer to the 4th palette entry. Successive write of 4 to the port 0x3c9 sets the Red value of that entry to 4. You probably want two more writes to the same port to complete the entry with Green and Blue values.

If you want to see something on the screen, read here for example. And again, read the documentation carefully. VGA is a very unfriendly piece of silicon.

I have a questions about VGA when I put a number in 0x3c8 for a point to start in the video memory does that correspond to the pixel data in bytes, or does it point to the pixel's data location. I realize my question my be confusing so what I am asking is something like this:

VGA data(r = red data, g = green data, b = blue data):
rgbrgbrgbrgbrgbrgbrgbrgbrgbrgbrgb - when I put a 10 into 0x3c8 does it point to the 10th set of rgb values (the pixels memory) or does it point to the 10th byte (a portion of the pixels data)?
If it points to the 10th set it would point to the 31st byte in the data or 10th pixel's red value.
If it points to the 10th byte then it would point to the 4th pixel's green value.

First and foremost: 0x3c8 has nothing to do with the video memory. It sets a pointer into a palette memory.
The value you put there is a palette entry number. A value 10 would make it point to 10'th entry. You may say is a 30'th byte; however the palette is not byte addressable, so counting bytes there makes little sense.
Yet again, it does not point to any pixel.

First and foremost: 0x3c8 has nothing to do with the video memory. It sets a pointer into a palette memory.
The value you put there is a palette entry number. A value 10 would make it point to 10'th entry. You may say is a 30'th byte; however the palette is not byte addressable, so counting bytes there makes little sense.
Yet again, it does not point to any pixel.

Ok, so what does the video memory get placed in the pallet memory?
Also If I were to do:

mov al, 4
out 0x3c8, al
mov al, 255
out 0x3c9, al

Shouldn't this display a red pixel at position 4 (or pixel 4). :-/
And from your last post I assume the answer to my other question was the number you put in 0x3c8 directly corresponds to the pixel number?

> Ok, so what does the video memory get placed in the pallet memory?

Please please please read the VGA spec.

> Shouldn't this display a red pixel at position 4

No. It sets the Red component of a fourth palette entry to 255. It does not display anything. To display something you need to move some data to the video memory. How to do it exactly depends on the selected mode. In some modes the value written to the video memory is an index to a palette: the pixel containing X is of color described by the palette entry number X.

Consider the following:

mov al, 4        ; Select entry 4
    mov dx, 0x3c8
    out dx, al

    mov dx, 0x3c9    ; Prepare to write components
    mov al, 255      ; Red
    out dx, al
    mov al, 0        ; Green
    out dx, al
    mov al, 0        ; Blue
    out dx, al

This sets the entry 4 to a pure red. Whenever you write 4 into a video memory, the corresponding pixel would have that color.

> Ok, so what does the video memory get placed in the pallet memory?

Please please please read the VGA spec.

> Shouldn't this display a red pixel at position 4

No. It sets the Red component of a fourth palette entry to 255. It does not display anything. To display something you need to move some data to the video memory. How to do it exactly depends on the selected mode. In some modes the value written to the video memory is an index to a palette: the pixel containing X is of color described by the palette entry number X.

Consider the following:

mov al, 4        ; Select entry 4
    mov dx, 0x3c8
    out dx, al

    mov dx, 0x3c9    ; Prepare to write components
    mov al, 255      ; Red
    out dx, al
    mov al, 0        ; Green
    out dx, al
    mov al, 0        ; Blue
    out dx, al

This sets the entry 4 to a pure red. Whenever you write 4 into a video memory, the corresponding pixel would have that color.

I assumed that not writing the green and blue values they would be 0, apparently this is not the case. Also is seems to me that the VGA knows when data is imputed into it's registers and automatically increments the pointer to the next byte for red, green, or blue and does not apply the changes until it gets all rgb values.

O I see I was trying to do the wrong thing this is to set the VGA color palette. I was trying to write to the screen through the VGA registers. Sorry, I found a tutorial on this but it was apparently not what I wanted. Do you happen to know how to change the pointer to video memory and how to change the resolution using the VGA's registers (not BIOS or DOS functions)?

Thanks for all your help.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.