16 colors for background in MCGA BIOS text mode (AL = 03h)
Asked Answered
T

2

6

MCGA supports 4-bits color depth, that is 16 colors. But when I try to print all of these colors, I get only first 8 of them and the rest 8 simply duplicate them as on the pic below. Can it be that I'm doing something wrong here or it is all because of DOSBox?

trying to get all the 16 colors

The code (MASM, under DOSBox 0.74):

TITLE   PROGRAM193
;----------------------------------------------------------
        .MODEL      SMALL
        .STACK      64
        .DATA           
;----------------------------------------------------------
        .CODE
MAIN    PROC    FAR
    MOV     AX, @DATA
    MOV     DS, AX

    MOV     AX, 0600h    ;AH = 06h (scroll up window)
    ; black (0)
    MOV     BH, 0Fh      ;0 (black) background, F (white) text
    MOV     CX, 0000h    ;upper line, left column
    MOV     DX, 004Fh    ;finishing line, right column
    INT     10h

    ; blue (1)
    MOV     BH, 1Fh
    MOV     CX, 0100h
    MOV     DX, 014Fh
    INT     10h

    ; green (2)
    MOV     BH, 2Fh
    MOV     CX, 0200h
    MOV     DX, 024Fh
    INT     10h

    ; cyan (3)
    MOV     BH, 3Fh
    MOV     CX, 0300h
    MOV     DX, 034Fh
    INT     10h

    ; red (4)
    MOV     BH, 4Fh
    MOV     CX, 0400h
    MOV     DX, 044Fh
    INT     10h

    ; magenta (5)
    MOV     BH, 5Fh
    MOV     CX, 0500h
    MOV     DX, 054Fh
    INT     10h

    ; brown (6)
    MOV     BH, 6Fh
    MOV     CX, 0600h
    MOV     DX, 064Fh
    INT     10h

    ; light gray (7)
    MOV     BH, 7Fh
    MOV     CX, 0700h
    MOV     DX, 074Fh
    INT     10h

    ;  -------------------------------
    ; | The problem starts up here... |
    ;  -------------------------------
    ; dark gray (8)
    MOV     BH, 8Fh
    MOV     CX, 0800h
    MOV     DX, 084Fh
    INT     10h

    ; light blue (9)
    MOV     BH, 9Fh
    MOV     CX, 0900h
    MOV     DX, 094Fh
    INT     10h

    ; light green (A)
    MOV     BH, 0AFh
    MOV     CX, 0A00h
    MOV     DX, 0A4Fh
    INT     10h

    ; light cyan (B)
    MOV     BH, 0BFh
    MOV     CX, 0B00h
    MOV     DX, 0B4Fh
    INT     10h

    ; light red (C)
    MOV     BH, 0CFh
    MOV     CX, 0C00h
    MOV     DX, 0C4Fh
    INT     10h

    ; light magenta (D)
    MOV     BH, 0DFh
    MOV     CX, 0D00h
    MOV     DX, 0D4Fh
    INT     10h

    ; yellow (E)
    MOV     BH, 0EFh                        
    MOV     CX, 0E00h
    MOV     DX, 0E4Fh
    INT     10h

    ; white (F)
    MOV     BH, 0F1h
    MOV     CX, 0F00h
    MOV     DX, 0F4Fh
    INT     10h

    MOV     AX, 4C00h
    INT         21h                         
MAIN    ENDP
        END     MAIN
Tamandua answered 1/3, 2015 at 5:15 Comment(4)
Since you seem interested in this kind of old techy asm programming, a good rule of thumb is that Dosbox is pretty much always right. There are obviously cases where it partially fails to emulate the old OS 100%, but anything on this level works really well.Neldanelia
I wasn't putting it down because it was old, I was addressing your question "or it is all because of DOSBox". If you go forward with programming under Dosbox, it will help greatly to know that it's pretty much perfect -- any weird behavior is how DOS worked. This way you'll know what to Google to find a solution!Neldanelia
@Blindy, got it! That was written somewhere like "The machine is always right", and that's seems to be true. Thank you for that mention.Tamandua
More or less, it's about trust in your tools. It's relatively easy to make the VC++6 compiler crash with valid code for example, so your trust level in it is pretty low. Making GCC or the newer versions of VC++ crash though is extremely difficult -- you can trust their output. This is the case with Dosbox too!Neldanelia
T
8

By default, there are 16 colors for text and only 8 colors for background.

There is a way to get all the 16 colors for background, which requires turning off the "blinking attribute".

Here is how it can be done:

MAIN    PROC    FAR
    MOV     AX, @DATA
    MOV     DS, AX


    ; turn-off blinking attribute
    MOV     AX, 1003h       
    MOV     BL, 00
    INT     10h


    MOV     AX, 0600h    ;AH = 06h (scroll up window)
    ; black (0)
    MOV     BH, 0Fh      ;0 (black) background, F (white) text
    MOV     CX, 0000h    ;upper line, left column
    MOV     DX, 004Fh    ;finishing line, right column
    INT     10h

    ; the rest of the magic...

The result is shown below:

enter image description here

Tamandua answered 1/3, 2015 at 17:16 Comment(2)
I'll refer you to Ralf Brown's interrupt list in HTML (as near to "official" as you're going to get) and you'll find that this method only applies to some systems and EGA and VGA - not CGA as requested.Derose
@Magoo, according to an interrupt instruction that a found on suggested site, Int 10/AH=0Fh, i got register AX = 5003, BX = 0000. There are also return descriptions: AH = number of character columns. AL = display mode. BH = active page. I looked here (columbia.edu/~em36/wpdos/videomodes.txt) for values of video mode and found out that the current video mode is 03h = T (text) 80x25 8x16 (pixel box) 640x400 16 (colors) 8 (pages) MCGA (CGA predecessor and VGA successor) (system). At least, all is right, as I see. But I still may be wrong, i don't exclude this.Tamandua
D
3

Ooh - ancient technology indeed!

16 colours are available in the foreground, but only 8 for the background. The top bit was used for blink, and was sometimes not implemented.

Derose answered 1/3, 2015 at 5:28 Comment(4)
@user3144770, suggested an edit but Magoo didn't approve it. Now i'll post the answer so other people will be able to see how to solve it.Tamandua
@YulianKhlevnoy : Not correct. The edit was rejected by others, not by me.Derose
@Magoo, sorry. That user, who rejected that edit, is very bad person. But i'll leave my answer 'cause it took a little time to post it. I added answered you about "CGA, VGA and EGA", if you have something to say, I suggest to create a chat gallery room to continue figuring out the truth :)Tamandua
@YulianKhlevnoy it's pretty borderline, you shouldn't really edit other people's answers to add information that wasn't there in the first place, only to clarify or correct. The correct way to go is to post your own answer if you figured it out yourself, and then accept it, which is what you did.Neldanelia

© 2022 - 2024 — McMap. All rights reserved.