Mode 12h Graphics Programming

Posted on 2000-02-29
Last Modified: 2012-08-14
Alright, there's something fishy about my mode 12h routines

I know that you must set a color and poke the bytes that you wish to colorize with a 8-bit raster . . . . so the 4th pixel would be poked like so:

push 0A000h
pop es
xor di, di
mov ax, 00010000b   <---- 4th byte = 4th pixel in the offset
mov [es:di], ax

BUT, when I try to make pixels in the same byte a different color, they will dissappear . . . . for instance

mov ax, 00001000b  <------- make the 5th pixel a different color
or [es:di], ax

If anyone can help me out IN ANY PROGRAMMING LANGUAGE, that'd be great!
Question by:c6burns
  • 9
  • 5
LVL 22

Expert Comment

ID: 2571189
That code is not trying to make two pixels a difference color.  it is just setting the 5th pixel and clearing all the others.

To set the 4th and 5th pixels you would do

mov ax, 00011000b

LVL 22

Expert Comment

ID: 2571204
Opps,  I'm wrong the in 2nd example you do use an OR instruction.  Which is what I was about to suggest.

Well the other issue I can thing of is you said that this is for mode 12h, but that is a 4 bit per pixel mode (16 color)  So the value


sets the first pixel to 1, whatever that is and the next three to 0 (black).  (AX holds 2 bytes or 4 pixels in this mode, but your 00010000b constant only specifyes the first two pixels, the next two you left as 0.

Author Comment

ID: 2573613
Well, I don't know whether you are correct and I just don't quite understand or . . . . .

I REALLY want an answer to this so . . . (quick code)

mov ax, 12h
int 10h            <----first I set mode 12h

out 3C6h, 4    <-----this sets the color to red
                                (4 is red, 1 is blue . . . etc.)

mov [A000:0], 10101010 <-- sets every other pixel to red

This sets the first eight pixels because each pixel is only a bit . . . apparently . . my major problem is that I can't get previously set color to remain once I try to poke new ones to the same byte . . . such as this:

out 3C6h, 1 <-----blue!
or [A000:0], 01010101 <---set blue pixels

This should set the pixels between the reds to blue BUT it's not working . . .it either sets the new pixels to blue and erases the red . . . or it sets all the pixels to blue . . . . if anyone can e-mail me a successful C++, Pascal, or ASM source code putpixel function, and give me an answer, I will award all the points!

VMware Disaster Recovery and Data Protection

In this expert guide, you’ll learn about the components of a Modern Data Center. You will use cases for the value-added capabilities of Veeam®, including combining backup and replication for VMware disaster recovery and using replication for data center migration.

LVL 22

Expert Comment

ID: 2573706
>> This sets the first eight pixels because each
>> pixel is only a bit . . . apparently
No they are not.  I mode 12h there are 16 colors.  Taht means each pixel is 4 bits.  i.e. you have two pixels per byte.
LVL 22

Expert Comment

ID: 2573763
; BX - X coordinate 0-639;
; CX - Y coordinate 0-479
; DL - Color 0-15;
; ES - video segment.

   PUSH DX ; Save color.
   MOV AX,640 ; Get row length.
   MUL CX ; Calculate offfset (times 2) to row.
   ADD BX,AX ; Calculate offset (times two) to pixel
   POP DX ; Restore color.
   SHR BX,1 ; Divide by 2.
   MOV AL,BYTE PTR [ES:BX] ; Get pixel
   JC XXX ; if high pixel branch around.
   AND AL,0F0h ; Clear low pixel.
   OR AL,DL ; Set low pixel.

   AND AL,0Fh ; Clear high pixel.
   SHL DL,4 ; Shift to high nibble.
   OR AL,DL ; Set high pixel.

   MOV BYTE PTR [ES:BX],AL ; Set pixel

Author Comment

ID: 2574092
I want to beleive you . . . . that sounds absolutely correct
Poking 2 nibble-colors at once would give you a byte, and make a helluva lotta sense to me. That's the way mode 13h works . . . . . however, I'm wondering if you've linked your own example to test if it works. The concept is that the screenlength is 640 (divided by two because 2 pixels are poked at once), and you simply set the nibbles from 0-Fh depending on the color you want . . . . ever noticed that the color will ALWAYS be Fh or 15?

Also, if you tried to poke color 15 you might notice that it produces a bar of white . . . . that's because color 15 is:

00001111b  <--- each pixel is set with a bit only!
10101010b  <---try poking that as your color

I was told that to set the color, you have to write it the the port at 3C9h - - - - outportb(0x3C9, 4) <---- red
  Perhaps there is more than one way to write to mode 12h, but I can't get your example to work. All I want is a working putpixel routine for mode 12h!
  If I'm still wrong and just ignorant of my own stupidity you can e-mail me at  
  Send me a copy of sourcecode in C++ and if it works you will be blessed for millions and millions of years!
LVL 22

Expert Comment

ID: 2574189
You are obviously not working in mode 12h.  

How many colors do you want and what dimensions do you want?
LVL 22

Expert Comment

ID: 2574216
here is a table of the most widely used modes

                         Table of Video Modes
  Mode     Type        Resolution      Adapter(s)      Colors       Address
  00h     Text          40 x 25      All but MDA       16 gray       B8000
  01h     Text          40 x 25      All but MDA   16 fore/8 back    B8000
  02h     Text          80 x 25      All but MDA       16 gray       B8000
  03h     Text          80 x 25      All but MDA   16 fore/8 back    B8000
  04h   Graphics       320 x 200     All but MDA         4           B8000
  05h   Graphics       320 x 200     All but MDA       4 gray        B8000
  06h   Graphics       640 x 200     All but MDA         2           B8000
  07h     Text          80 x 25        MDA,EGA          b/w          B0000
  08h   Graphics       160 x 200        PCjr            16           B0000
  09h   Graphics       320 x 200        PCjr            16           B0000
  0Ah   Graphics       640 x 200        PCjr             4           B0000
  0Bh   Reserved    (internal to EGA)
  0Ch   Reserved    (internal to EGA)
  0Dh   Graphics       320 x 200        EGA             16           A0000
  0Eh   Graphics       640 x 200        EGA             16           A0000
  0Fh   Graphics       640 x 350        EGA             b/w          A0000
  10h   Graphics       640 x 350        EGA             16           A0000
  11h   Graphics       640 x 480        MCGA,VGA        2            A000
  12h   Graphics       640 x 480        VGA             16           A000
  13h   Graphics       320 x 200        MCGA,VGA        16           A000

Note the entry for 12h is for 16 colors.  its hard to store 16 different values in a single bit.  So you can't store a single pixel in a single bit.

Author Comment

ID: 2574357
Alright . . . I am already giving you the benefit of the doubt . . . . I have tried to run your program . . . have you tried to run it?

And of course I'm working in mode 12h

mov ax, 12h
int 10h            <---if this is wrong, please do me a favour and hurt me!!

I'm NOT saying that a bit could ever be anything but 1 or 0 . . this is obvious . . . what I'm saying is that the video memory does not contain the color of the pixel! THAT IS MODE 13h!!!!! I know that mode well!!!!!!

outportb(0x3C6, color) <---this is how you set your desired color
pokeb(0xA000,0,0xFF) <-- this pokes a line of 8 pixels in the desired color

Don't beleive me? Go check before you put another comment here!
If you have actual experience in programming mode 12h and can show me a routine in C++ (or anything) that WORKS then please do so. We are so far off topic from my previous question that I feel no answer will ever be forthcoming!    

Now, if you have a routine that works, and doesn't encounter the problem mine does in my original posting   . . . please e-mail it to me or post it, and you will get the points.


If you haven't tested your own routines . . . . DO NOT RESPOND!

LVL 22

Expert Comment

ID: 2576312
I see this is a bit plane mode.

Which read and write mode are you using?  

Do you have "PC System Programming" by Michael Tischer?
LVL 22

Accepted Solution

nietod earned 200 total points
ID: 2576363
; AX - row
; BX - column
; CH - color.
    MOV AL,8

    MOV AX,205h
    OUT  DX,AX

   MOV AX,3

    MOV AL,ES:[BX]
    MOV ES:[BX],CH

   MOV AX,0FF08H
   MOV AX,5
   MOV AH,3


; AX - row
; BX - column
; ES:BX - -> pixel
; CL - bit position.
; AH - bitmask for combining with other pixels
; DX
   MOV DX,80
   SHR BX,3
   MOV AX,0A00H
   AND CL,7
   XOR CL,7
   MOV AH,1

Author Comment

ID: 2577002
That is absolutely perfect . . . . I don't quite understand the procedure with each of the OUTs . . . . it's definately a video standard

Anyway . . . this is as good as it gets, I can't ask you for anymore than that

Author Comment

ID: 2577007
I can easily translate this to C or Pascal

Thank you very much . . . you are definately an expert
LVL 22

Expert Comment

ID: 2577185
you would be best to get the book i mentioned.  VGA graphics are very complex (ridiculoesly)  The book will help.


Featured Post

Optimizing Cloud Backup for Low Bandwidth

With cloud storage prices going down a growing number of SMBs start to use it for backup storage. Unfortunately, business data volume rarely fits the average Internet speed. This article provides an overview of main Internet speed challenges and reveals backup best practices.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Converting to C# also VS2015 5 128
C++ standard library based binary archive format 6 98
convert char array to number in c 5 85
GUI: DIalog Stacking and Popping in MS C++ 4 76
Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

832 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question