Search code examples
arraysassemblyemu8086

Printing an array but specific values highlighted {emu8086}


I want to print this array but also highlight specific characters from said array. This is my code:

include 'emu8086.inc'
.data
animales1   db 'BUBRPQYFODFZXIQ'
            db 'MSVDJVQDTLOEATF'
            db 'RCZPIFYGAZLPMFN'
            db 'LVWKFFBKDXHFIUW'
            db 'AOSEFQEMOOTGQUR'
            db 'ELLWTGNJJKAJISJ'
            db 'OVCOXLUEQTSDDSP'
            db 'UEAEMTNYOLVYMGI'
            db 'ORREPOMJZGYPHAI'
            db 'IFTLCBJFVOYHLUB'
            db 'WTOWZQFRAXQRLMR'
            db 'KGNYIIHHHKFUKIJ'
            db 'XMLSACGMVXEYSIT'
            db 'TSOESQVSEQRFNPU'
            db 'ODDQMDFWRGETDLY'

lenguajes2  db 'SLKFMBCULKVYUIM'
            db 'TWCDQFYIVIKUXKB'
            db 'GNIWEQBOSYEMDTJ'
            db 'WDHFZZPUIEDERYQ'
            db 'KMTGTKAKROMUSUV'
            db 'BELBLLTUVJQHCRW'
            db 'UPLUBYJKNUXORLF'
            db 'SGMAOOEENBOGIWR'
            db 'JVSTLPTEGPPNPJW'
            db 'YINCASSEMBLYTTU'
            db 'CHWTIOIWORDZDRV'
            db 'BRZCNRAVRWAMUNU'
            db 'KOMCOUKNGQEPQVS'
            db 'XXRXJUJUBEXVGGA'
            db 'MNKJQKZAACVCLDW'
            
char db 'a'
flag db 0
;Pez= 12,27,42
;Ave= 76,92,108 
            
indx db 5,11,26,41,45 dup (' ')
.stack
.code
.start up
mov ax,0000h  
mov bx,0000h
mov cx,0000h
mov dx,0000h
lea si, animales1
;call valueInArray
call printArrays




printArrays proc


mov bx,0000h
printArray:
mov dx,0000h
mov ah, 02h
mov dl,byte ptr[si+bx]
call valueinArray
cmp flag,1
jz printSpecial
int 21h
mov dl, 20h
int 21h
add bx, 1
add cl, 1
cmp cl,15
jz nextRow
jnz printArray


nextRow:
call nwLine
add ch,1
mov cl, 00h
cmp ch,15
jz finproc
jnz printArray

printSpecial:


lea di,char
mov byte ptr[di],dl
push ax
push bx
push cx
push dx

mov bp, offset char
mov dh,00h
mov al, 1
mov bh, 0
mov bl, 1111_0000b
mov cx, 1; calculate message size. 
mov dx,0000h
mov ah, 13h
int 10h
mov dl, 20h
mov ah, 02h
int 21h
pop dx
pop cx
pop bx
pop ax
add bx, 1
add cl, 1
cmp cl,15
jz nextRow
jnz printArray

finproc:

ret
printArrays endp

nwLine PROC
MOV AH,02h
MOV DX,0Ah; imprime asscii 10 (nueva linea)
INT 21h
MOV DX,0Dh; imprime asscii 13 (retorno de carro)
INT 21h
RET
nwLine ENDP

valueInArray proc

mov flag, 0
mov di,0001h
iterar:
mov dh, indx[di]
cmp dh,20h
jz finvalueproc
cmp bl,dh
jz found
add di,1
jmp iterar
found:
mov flag,1
jmp finvalueproc:



finvalueproc:
ret
valueInArray endp 

exit:
end

As you can see, the array 'indx' have the positions of the chars (The first number is the effective lenght of said array) that I want to highlight so I check if bx is in the position of said character to print it highlighted. I have two problems at the moment, the first one is the highlighted characters are printing in a kinda random position and that messes up the rest, but I think I know why the position of the highlighted character that prints is wrong, because the interrupt that I use uses dh and dl as positioners but I do not know how to make it so it continues the flow of the rest. The second problem is that the character that prints is wrong, if you run it and check the variable char, it has an 'Z' but it prints a 'T'. I really need help. Pretty please. :(


Solution

  • indx db 5,11,26,41,45 dup (' ')
    

    It could be that this line is not what you think it is!
    Reading your explanation I think you really meant:

    indx db 5, 11, 26, 41, 45, ' '
    

    That is the length of the array which is 5, then followed by 4 offsets to the highlighted characters and 1 space character as a list terminator.


    the first one is the highlighted characters are printing in a kinda random position and that messes up the rest, but I think I know why the position of the highlighted character that prints is wrong, because the interrupt that I use uses dh and dl as positioners but I do not know how to make it so it continues the flow of the rest.

    Because your code to output the highlighted character uses mov dx,0000h, the BIOS function 13h places the character in the upperleft corner of the screen and the other, 'normal' characters will continue from there.

    All you have to do is to ask BIOS where the cursor is at that moment using function 03h:

    Replace

    mov cx, 1; calculate message size. 
    mov dx,0000h
    mov ah, 13h
    int 10h
    

    by

     mov  ah, 03h   ; BIOS.GetCursorAndConfiguration
     int  10h       ; -> CX DX
     mov  cx, 1     ; message size
     mov  ah, 13h   ; BIOS.WriteString
     int  10h
    

    Function 13h fetches from ES:BP. Did you setup the ES segment register?


    The second problem is that the character that prints is wrong, if you run it and check the variable char, it has an 'Z' but it prints a 'T'.

    Probably resolving the first problem will also resolve the second one.


    There's a better, less convoluted way to output your highlighted character.

    printSpecial:
     push ax
     push bx
     push cx
     mov  cx, 1      ; ReplicationCount
     mov  bx, 00F0h  ; DisplayPage 0, Attribute BlackOnBrightWhite (11110000b)
     mov  al, dl     ; Character
     mov  ah, 09h    ; BIOS.WriteCharacterAndAttribute
     int  10h
     mov  ah, 0Eh    ; BIOS.TeletypeCharacter
     int  10h
     pop  cx
     pop  bx
     pop  ax
     ...
    

    Function 09h will write your character with the colors that you need, and then function 0Eh will advance the cursor normally.