Why isn't the text colored when using the 0Eh 10h interrupt?

折月煮酒 提交于 2019-11-29 17:57:48

I was able to print with color by using the 09 for the 10h interrupt, instead of 0E. You do, however, have to change the cursor position after each character to use this method. Here is the working code.

     BITS 16

start:
    mov ax, 07C0h           ; Set up 4K stack space after this bootloader
    add ax, 288             ; (4096 + 512) / 16 bytes per paragraph
    mov ss, ax
    mov sp, 4096

    mov ax, 07C0h           ; Set data segment to where we're loaded
    mov ds, ax


    mov si, text_string     ; Put string position into SI
    call print_string       ; Call our string-printing routine

    jmp $                   ; Jump here - infinite loop!


    text_string db 'Hello World!', 0


print_string:                   ; Routine: output string in SI to screen


 .repeat:
    mov ah, 09h             ; int 10h 'print char' function
    mov bh, 0x00
    mov bl, 0x03
    mov cx, 01h
    lodsb                   ; Get character from string
    cmp al, 0
    je .done                ; If char is zero, end of string
    int 10h                 ; Otherwise, print it
    mov bh, 00h
    mov ah, 03h
    int 10h
    mov ah, 02h
    mov bh, 00h
    inc dl
    int 10h
    jmp .repeat

 .done:
    ret


    times 510-($-$$) db 0   ; Pad remainder of boot sector with 0s
    dw 0xAA55               ; The standard PC boot signature

I think a better idea than the one marked as accepted is to use function 13h of interrupt 10h. This function is supposed to send entire strings to the screen, along with attributes (colors). There are four modes of operation for this function, specified in the AL register.

AL=00h: Assign all characters the attribute in BL; do not update the cursor position.
AL=01h: Assign all characters the attribute in BL; update the cursor position.
AL=02h: Use attributes in string; do not update the cursor position.
AL=03h: Use attributes in string; update the cursor position.

So you can either use the same attribute (colors) for the entire string by specifying the attribute in BL for modes 00h or 01h, or intermingle the attributes in the string itself to print each character with a different attribute.

The only drawback I see with this approach is that you have to know the length of the string upfront (to put it into CX), since this function doesn't work with null-terminated strings.
But, on the other hand, storing a one-byte length of the string preceding its characters instead of the null character after its characters could have some benefits: You don't need to traverse the entire string to know its length; and a one-byte length won't take any more place than the null terminator. Even a two-byte length is not much a waste. You can load a two-byte length directly into CX. You can do the same with a one-byte length, too, but make sure to clear out the CH afterwards.

Having the ability attribute each character of the string alone also could be useful sometimes.

Other registers are as usual:
BH is the page number.
DX is where to start the string on the screen: DH:DL = Y:X
ES:BP points to the first character of the string in memory.

If you use the teletype modes (01h or 03h), ASCII control characters are properly interpreted instead of being printed as symbols. They also update the cursor position to the end of the string.

To make it work continuously, you can use the function AH=03h to get the cursor position. It is made so that it loads the cursor position to the DH:DL, so it can be used afterwards directly in the subsequent call to AH=13h to print the string from that position. Here's how I do it:

# Get cursor position.
getcur:        mov   $0x03, %ah         # Get cursor position into DH:DL = Y:X.
               int   $0x10              # Video BIOS interrupt.
               ret                      # Return to the caller.

# Print string with attributes.
# `putsa` expects attributes in `BL`.
# `puts` uses the default attributes (silver on black).
# Both expect a pointer to the string in `ES:SI`.
# The string should start with a 2-byte length information.
puts:          mov   $0x07,   %bl       # Default attribute: silver on black.
putsa:         call  getcur             # Get cursor position into DH:DL.
               mov   (%si),   %cx       # Length of the string into `CX`.
               mov   %si,     %bp       # Prepare the pointer:
               add   $2,      %bp       # Skip the 2-byte length word.
               mov   $0,      %bh       # Use page #0.
               mov   $0x1301, %ax       # Print string and update cursor.
               int   $0x10              # Video BIOS interrupt.
               ret                      # Return to the caller.

Calling (assuming the ES is properly set):

               # Print a string with attributes.
               lea   msgHello, %si      # String to print (after 2-byte length)
               mov   $0x0C,    %bl      # Attributes: light red on black.
               call  putsa

               # Print it one more time with different attributes.
               # Note we don't have to set the pointer: it's already set.
               mov   $0x0C,    %bl      # Attributes: yellow on black.
               call  putsa

The data section:

msgHello:     .word 13                  # Length of the string.
              .ascii "Hello, World!"    # The string itself.

Oh, and service is available only for XTs dated 01/19/1986 and later, ATs, EGAs, and PC Convertibles. But I guess it won't pose any problem, unless you're dealing with a serious piece of old junk ;-J

attila
;make to use mov ah,0eh

bits 16

org 0x7c00


jmp basla

; clear screen with colour you want

basla:

  ;pencere boyutu 80x25 karakter

  mov ah,06h
  mov al,00h
  mov bh,0ach ; ah zemin rengi,ch karakter rengi
  mov cx,00h ;silmeye pencerenin sol ustunden basla
  mov dx,184fh ;18h(24.satir) ve 4fh(79.sutun)a kadar sil.
  int 10h

;then print your program

  mov di,isim ;dizinin ilk adresini di kutuk yazmacina ata
  call yazbas  ; alt program cagriliyor

  mov di,isim2 ;ikinci dizinin adresi ataniyor
  call yazbas  ;ayni alt program cagriliyor

  jmp $ ;sonsuz dongu

yazbas:

   mov ah,0eh

   mov al,[di]
   int 10h
   inc di
   or al,al
   jz bitti
   jmp yazbas

bitti:

ret

isim db "attila oguz",0

isim2 db "isletim duzenegine giris",0

times 510-($-$$) db 0

dw 0xaa55   

For to change the cursor position:

text_string db 'Hello World!', 0
text_len = ($-text_string)-1

    mov ah,3
    xor bh,bh
    int 10h
    add dh,text_len
    cmp dh,79
    jb short P1
    sub dh,79
    inc dl
P1: mov ah,2
    int 10h

RBIL->inter61a.zip->INTERRUP.A

--------V-1002-------------------------------
INT 10 - VIDEO - SET CURSOR POSITION
AH = 02h
BH = page number
    0-3 in modes 2&3
    0-7 in modes 0&1
    0 in graphics modes
DH = row (00h is top)
DL = column (00h is left)
Return: nothing
SeeAlso: AH=03h,AH=05h,INT 60/DI=030Bh,MEM 0040h:0050h
--------V-1003-------------------------------
INT 10 - VIDEO - GET CURSOR POSITION AND SIZE
AH = 03h
BH = page number
    0-3 in modes 2&3
    0-7 in modes 0&1
    0 in graphics modes
Return: AX = 0000h (Phoenix BIOS)
CH = start scan line
CL = end scan line
DH = row (00h is top)
DL = column (00h is left)
Notes:  a separate cursor is maintained for each of up to 8 display pages
many ROM BIOSes incorrectly return the default size for a color display
  (start 06h, end 07h) when a monochrome display is attached
With PhysTechSoft's PTS ROM-DOS the BH value is ignored on entry.
SeeAlso: AH=01h,AH=02h,AH=12h/BL=34h,MEM 0040h:0050h,MEM 0040h:0060h

I like it more to write directly into the segmentaddress of 0B800h.

    mov ah,3   ; calculating the target offset address from the cursor position
    xor bh,bh
    int 10h

    xor cx,cx
    add dl,dl  ; column
    mov cl,dl

    xor ax,ax
    mov al,dh  ; row
    mov bx,160
    mul bx

    add ax,cx
    mov di,ax

    mov ax,0B800h
    mov es,ax
    mov si,text_string
    mov cx,text_len
    mov ah,3  ; color
    cld
RP: lodsb     ; get byte from DS:SI
    stosw     ; store word in ES:DI
    loop RP

Not tested, but i hope no mistakes slept in.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!