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