Home > Software design >  How to set cursor position and color of a pattern in assembly language?
How to set cursor position and color of a pattern in assembly language?

Time:07-21

I'm trying to set the cursor position and color of a specific pattern in assembly; specifically, the pattern is a parallelogram (once again, haha) and its color is red. I have already tried putting only the block of code for coloring at the start of the pattern, but by putting mov ch,100h yields the result that I am not looking for, what it prints are excess characters which destroyed the shape. The problem must be involving the CH register because I've used it for printing the parallelogram. One solution that I could think of is to loop the cursor start position and coloring as it prints the characters and increments the color register along with it. However, since the parallelogram uses the said register, I might have to store it in a variable. I would like to ask for your thoughts about it. I've done this is in a procedural way, and I am rather a new one for screen processing.

This is developed using TASM/TLINK with DOSBOX as an emulator. This specific parallelogram is part of a logo that I am trying to output in assembly.

Here is an excerpt of my code:

; ============================

LPARALLEL PROC 
    
    ; CLEAR ALL REGISTERS 
    xor cx,cx
    xor bx,bx
    xor ax,ax 

    mov ah,02h
    mov bh,00h
    mov dh,9
    mov dl,41
    int 10h
    
    mov ah,09h
    mov cx,10
    mov bl,74H
    mov dx,30h
    int 10h
    
    sub INPUTPL,30h
    
    mov cl,INPUTPL
    mov bh,INPUTPL 
    mov bl,0
    
    mov DIA,bh 
    mov LBLANK,bl 
    
    LP_SPACES:
    cmp LBLANK,0
    JE PRINT_CHL
    
    mov ah,02h
    mov dl,20h
    int 21h
    dec LBLANK 
    
    JMP LP_SPACES 
    
    PRINT_CHL:
    mov ah,02h
    mov dl,04h
    int 21h
    
    mov ah,02h
    mov dl,20h
    int 21h
    
    dec DIA 
    cmp DIA,0
    JNE PRINT_CHL 
    
    lea dx,LINE 
    mov ah,09h
    int 21h
    
    inc bh 
    mov DIA,bh
    dec DIA 
    dec bh 
    
    inc bl
    mov LBLANK,bl
    loop LP_SPACES
    
    RET 
    LPARALLEL ENDP 

; ============================

Thank you to those who will take their time to answer this question, sending all good wishes <3

CodePudding user response:

What did you expect here?

mov ah,09h
mov cx,10
mov bl,74H
mov dx,30h
int 10h

This code writes 10 RedOnWhite spaces on the screen. The mov dx,30h instruction has no effect, and the AL register happens to contain 0 and therefore BIOS outputs space characters.

Why so convoluted?

inc bh 
mov DIA,bh
dec DIA 
dec bh 

This code snippet is equivalent to just mov DIA,bh.

A quick optimization

dec DIA 
cmp DIA,0
JNE PRINT_CHL

You don't need that cmp DIA,0 instruction. The dec DIA instruction by itself sets the flags that you need in order to jump conditionally.


Since you want to color the output, it is best to use BIOS all the way. Write the colored character via the BIOS.WriteCharacterAndAttribute function 09h and have it followed by the BIOS.Teletype function 0Eh in order to advance the cursor.
Use a subroutine so the main loop stays readable.

; IN (al is ASCII, ah is ColorAttribute) OUT () MOD (ax,bx,cx)
PrintColoredCharacter:
    mov  cx, 1                 ; RepetitionCount
    mov  bh, 0                 ; DisplayPage
    mov  bl, ah                ; ColorAttribute
    mov  ah, 09h               ; BIOS.WriteCharacterAndAttribute
    int  10h
    mov  ah, 0Eh               ; BIOS.Teletype
    int  10h
    ret

You don't need the memory-based variables DIA and LBLANK to write this. There are more registers available to you. Simply put the NumberOfLeadingSpaces in the SI register, and the NumberOfDiamonds in the DI register.
For the leading spaces you probably don't care about the color. That's why I used the standard WhiteOnBlack in the below code:

    mov  al, INPUTPL           ; Byte-sized variable holding value 1 or more
    mov  ah, 0
    mov  di, ax                ; NumberOfDiamonds (dimension of the parallelogram)
    xor  si, si                ; NumberOfLeadingSpaces

MORE_LINES:
    push si                    ; (1)
    push di                    ; (2)

    test si, si
    jz   PRINT_CHL
LP_SPACES:
    mov  ax, 0720h             ; WhiteOnBlack space
    call PrintColoredCharacter ; -> (AX BX CX)
    dec  si
    jnz  LP_SPACES

PRINT_CHL:
    mov  ax, 7404h             ; RedOnWhite diamond
    call PrintColoredCharacter ; -> (AX BX CX)
    mov  ax, 7420h             ; RedOnWhite space
    call PrintColoredCharacter ; -> (AX BX CX)
    dec  di
    jnz  PRINT_CHL 

    lea  dx, LINE
    mov  ah, 09h
    int  21h
    
    pop  di                    ; (2)
    pop  si                    ; (1)
    inc  si                    ; NumberOfLeadingSpaces  
    cmp  si, di
    jb   MORE_LINES
  • Related