TASM 1.4 - Changing background color without clear

2019-02-20 20:44发布

问题:

I'm using Tasm 1.4. I'm trying to change the color of the background and text without clearing the previous text, but it always ends up on clearing the previous text although the colors are changed.

For example:

mov ah,09h
lea dx,text1
int 21h             ;displays text1
mov ah,01h
int 21h             ;I input a character
mov ah,06h
mov bh,42h
mov cx,0000h
mov dx,184fh
int 10h             ;I use this to change the text and background color
mov ah,02h
mov bh,00h
mov dh,0ch
mov dl,20h
int 10h             ;along with this
mov ah,09h
lea dx,text2
int 21h             ;displays text2
mov ah,02h
mov dl,al
int 21h             ;displays the inputted character

Now what happens there is...

  • it displays text1
  • it asks for an input
  • I enter an input
  • it will display text2 followed by the inputted character, with the background color changed to red and the text color changed to green. But, text1 was cleared from the screen.

I should also say that text1 and text2 can definitely fit in the same screen.

So how do I get the same output but with text1 not being cleared from the screen?

回答1:

Just write to the video memory directly and be done with it. If you're in mode 03h, then you've got 80x25 chars on screen. Each char has 16bits associated with it. 8 bits for text/background colour and another 8 for the character displayed.

The character to display is the first byte and the attributes are the second byte. You can find a brief description of the memory organization and attribute bits here: http://www.shikadi.net/moddingwiki/B800_Text

Here's some code that will leave the text content unchanged and will just set the attribute byte for all text on an 80x25 screen. I use nasm these days, it's been 15 years since I last used tasm - I'm not sure if any of the syntax will need changing.

;********************************************************
; Sets the text-mode attributes for the whole 80x25 screen
; call  with AL = attribute (hi nibble = background, lo-nibble = foreground)
;********************************************************
setTextAttributes:
    push    es              ; save the seg register
    mov     cx, 80*25       ; # of chars to do
    mov     bx, 0xB800      ; segment of the screen memory for this video mode
    mov     es, bx
    xor     di, di          ; point to char data of screen-pos 0,0
.setTextAttributesLoop:
    inc     di              ; advance by 1 to point to the attribute, rather than the char
    stosb                   ; store our attribute byte to [es:di] and increment di. di now points to a character
    loop    .setTextAttributesLoop
    pop     es
    ret