Deepak C
Deepak C

Reputation: 29

How to change text background color in x86-16 assembly using BIOS int 10h

I am working on a "Pong game", and everytime a player scores, I clear the screen by filling it with a desired color and drawing the players and the ball again. Here is the code I use to clear the screen:

mov ah,06h  ;clear screen instruction
mov al,00h  ;number of lines to scroll
mov bh,2    ;display attribute - colors
mov ch,0    ;start row
mov cl,0    ;start col
mov dh,24d  ;end of row
mov dl,79d  ;end of col
int 10h     ;BIOS interrupt

The problem is that I am also printing the scores on the screen. Here's the code I use to set up the text color:

mov ah,09        ; FUNCTION 9
mov bx,0004      ; PAGE 0, COLOR 4
int 10h          ; INTERRUPT 10 -> BIOS

And here's how I load the text:

mov ah,02h
    mov dh,2    ;row
    mov dl,16    ;column
    int 10h

    mov si, FirstPlayerScore
    call printf
    ret

    printf:
    lodsb
    cmp al, 0
    je finish
    mov ah, 0eh
    int 10h
    jmp printf

    finish:
    ret

That's the result. I would like to change the scores' background color to green, not black. By searching a bit I found out I could do something like:

MOV BL,1EH ; Background = Blue, Foreground = Yellow

But it does not solve the problem. I would appreaciate any hints or answers.

Upvotes: 2

Views: 1649

Answers (1)

Sep Roland
Sep Roland

Reputation: 39166

You didn't specify the video mode that you are working in, but judging by the screenshot and the numerical data you have in your code snippets, I conclude that you are playing pong on the 80x25 16-color text screen.
The BIOS function that you say you use "to setup the text color", does not do that at all! The BIOS.WriteCharacterAndAttribute function 09h writes both a character and a color attribute (foreground and background) to the screen. So that's ideal for your purpose except that this function does not advance the cursor. But you can do that easily yourself. The below simplified code assumes that the string belongs to just one row on the screen, a thing that is most probable in your program.

    mov  dx, 0210h  ; DH is Row=2, DL is Column=16
    mov  si, FirstPlayerScore
    call printf
    ...

; IN (dx,si) OUT () MOD (ax,bx,cx,dx,si)
printf:
    mov  cx, 1      ; ReplicationCount=1
    mov  bx, 0024h  ; BH is DisplayPage=0, BL is ColorAttribute=24h (RedOnGreen)
    jmp  .b
.a: mov  ah, 02h    ; BIOS.SetCursorPosition
    int  10h
    lodsb
    mov  ah, 09h    ; BIOS.WriteCharacterAndAttribute
    int  10h
    inc  dl         ; Next column
.b: cmp  byte [si], 0
    jne  .a
    ret

A more general approach to the matter allows outputting strings that can span several rows on the screen and even allows scrolling of the screen. I have provided such a code in a Q/A I wrote some time ago Displaying characters with DOS or BIOS. I encourage you to read all of it and especially study the code snippet labeled WriteStringWithAttributeTVM. TVM stands for Text Video Mode.

Upvotes: 4

Related Questions