Ola214
Ola214

Reputation: 11

Change background color of string

I have a problem in NASM. I want to change the background colour, but only for one string.

These are my macros:

%macro SetBackGroundColour 0
    mov dx, 0
    mov bh, 0
    mov ah, 0x2
    int 0x10
    mov cx, 2000 
    mov bh, 0
    mov bl, 0x21 
    mov al, 0x20 
    mov ah, 0x9
    int 0x10     
%endmacro

%macro printOnTheScreen 1
    xor dx,dx 
    mov ah, 09h 
    mov dx, %1 
    int 21h 
    xor dx, dx
%endmacro

I tried other changes, but nothing worked.

Upvotes: 1

Views: 1584

Answers (3)

Sep Roland
Sep Roland

Reputation: 39166

If you output via DOS (you're using DOS.PrintString function 09h), you loose the ability to produce color. Luckily BIOS does support colorful text. Read all about the available DOS and BIOS text output functions in Displaying characters with DOS or BIOS.
For the text video mode, you can use the WriteStringWithAttributeTVM code that expects DS:SI to point at your zero-terminated text and BL to contain the attribute to use (specifying the foreground color in the low nibble and the background color in the high nibble). Just like the DOS.PrintString function 09h, it will expand tabs.

; IN (bl,ds:si) OUT ()
WriteStringWithAttributeTVM:
      pusha
      mov     bh, 0           ; Display page 0
      jmp     .d
.a:   cmp     al, 9
      je      .Tab
      cmp     al, 13
      ja      .b
      mov     cx, 1101_1010_0111_1111b
      bt      cx, ax
      jnc     .c              ; {7,8,10,13} don't need the color
.b:   mov     cx, 1
      mov     ah, 09h         ; BIOS.WriteCharacterAndAttribute
      int     10h
.c:   mov     ah, 0Eh         ; BIOS.Teletype
      int     10h
.d:   lodsb
      test    al, al
      jnz     .a
      popa
      ret
.Tab: mov     cx, 1           ; Start displaying colored space(s)
      mov     ax, 0920h       ; BIOS.WriteCharacterAndAttribute
      int     10h
      mov     ah, 0Eh         ; BIOS.Teletype
      int     10h
      mov     ah, 03h         ; BIOS.GetCursor
      int     10h             ; -> CX DX
      test    dl, 7
      jnz     .Tab            ; Column not yet multiple of 8
      jmp     .d

There is an additional BIOS function that can display a string in color but it will not expand tabs like the DOS.PrintString function 09h does. This is also the solution in one of the other answers but over there it contains an error. A further drawback is that you need to know the length of the string beforehand and that it requires the weird ES:BP pointer. The only nice thing about it, is that you can specify the column and row in the call...

; IN (bl,cx,dx,bp) OUT ()
;  BL Attribute eg. 1Fh is BrightWhiteOnBlue
;  CX Length of the string
;  DL Column
;  DH Row
;  BP Offset address of the string
WriteString:
      push    ax
      push    bx
      push    es
      mov     ax, ds          ; DS:BP --> ES:BP
      mov     es, ax
      mov     bh, 0           ; Display page 0
      mov     ax, 1301h       ; BIOS.WriteString
      int     10h
      pop     es
      pop     bx      
      pop     ax
      ret

About mov ax, 1301h : Because the WriteMode in AL is set to 1, the attribute is taken from the BL register AND the cursor gets updated (just like the DOS.PrintString function 09h would have done).

Upvotes: 0

admin
admin

Reputation: 3

You can display that string, and change the color, display another string. For example this code change background color to blue, foreground color to white, and then change background color to black, foreground color to white:

    mov cx, 2000 
    mov bh, 0
    mov bl, 0x1F 
    mov al, 0x20
    mov ah, 0x9
    int 0x10

    ;display string here

    mov cx, 2000 
    mov bh, 0
    mov bl, 0x0F 
    mov al, 0x20
    mov ah, 0x9
    int 0x10

    ;display string here

Note: That code wasn't clear the screen at beginning.

Upvotes: -1

Next is a procedure in (almost) NASM to display string with color, notice how parameters are set before the CALL :

SECTION .data

text:  db  "Just some text"  ;LENGTH = 14.
color: db 181          
x:     db 0
y:     db 0

SECTION .text

global main
main:

  mov  bp, text ;STRING TO DISPLAY.
  mov  cx, 14          ;STRING LENGTH.
  mov  [x], byte 50    
  mov  [y], byte 20
  call color_string

;FINISH PROGRAM.
  mov  ax,4c00h
  int  21h

;----------------------------------------------     
;PARAMETERS : BP = OFFSET OF STRING TO DISPLAY.  
;             CX = STRING LENGTH.
;             COLOR = VARIABLE WITH COLOR (0..255).
;             X,Y   = VARIABLES WITH COORDINATES.

color_string:

  mov  ax, ds
  mov  es, ax         ;ES SEGMENT MUST POINT TO DATA SEGMENT.
  mov  ah, 13h        ;SERVICE TO DISPLAY STRING WITH COLOR.
  mov  bh, 0          ;PAGE (ALWAYS ZERO).
  mov  bl, color
  mov  dl, x          ;X (SCREEN COORDINATE). 
  mov  dh, y          ;Y (SCREEN COORDINATE). 
  int  10h           ;BIOS SCREEN SERVICES.  

  ret

The code to set cursor position is this :

mov  ah, 2  ;SERVICE TO SET CURSOR POSITION.
mov  bh, 0  ;PAGE NUMBER (ALWAYS ZERO).
mov  dl, x  ;X COORDINATE 0..79.
mov  dh, y  ;Y COORDINATE 0..24.
int  10h    ;BIOS VIDEO SERVICES.

Upvotes: 1

Related Questions