maniacsilversmith
maniacsilversmith

Reputation: 33

x86 Strange printing after console has been scrolled

I have the following function:

printRows proc
    mov cx, 25
    printRowsLoop:  
        mov si, 0
        printSingleRowLoop:

            mov ah, 3  ;save current cursor position  at dx (dh:dl)
            int 10h

            push dx ;keep the position for later

            mov ah, 2
            mov dl, '&'   
            int 21h      ; print '&' char in the current curser position

            pop dx   ; restore dx

            add dl, 5 ; increase the column of it with a const number (so it would look like a square)
            mov ah, 2
            int 10h

            inc si
            cmp si, 3 ; print 3 '&' in each row
            jne printSingleRowLoop 

        mov dl, 13     ; result of these 3 groups of commands should be 2 new lines
        mov ah, 2
        int 21h

        mov dl, 10
        ;mov ah, 2 ; ah is alredy 2
        int 21h

        ;mov dl, 10 ; dl is already 10
        ;mov ah,2  ; ah is already 2
        int 21h

        loop printRowsLoop  ; print (cx) lines 
    ret

printRows endp

the output of it should be what is seen in the this screenshot - and this is the output of it (at least in the begginig)

but, after the "good" output filled the console (when it needed to "scroll") it doesn't longer print those spaces between each '&', instead it just prints each of them in a new line as can be seen here.

What might cause such strange behaviour? What am I doing wrong? How should I fix this?

I am using emu8086.

Upvotes: 3

Views: 111

Answers (3)

Xiobiq
Xiobiq

Reputation: 400

You should print the carriage return (13 ascii code) last.

I have also included Fifoernik's tips in my answer.

printRows proc
mov cx, 25
printRowsLoop:  
    mov si, 0
    printSingleRowLoop:

        push cx
        mov bh, 0
        mov ah, 3  ;save current cursor position  at dx (dh:dl)
        int 10h  
        pop cx


        push dx ;keep the position for later

        mov ah, 2
        mov dl, '&'   
        int 21h      ; print '&' char in the current curser position

        pop dx   ; restore dx

        mov bh, 0
        add dl, 5 ; increase the column of it with a const number (so it would look like a square)
        mov ah, 2
        int 10h

        inc si
        cmp si, 3 ; print 3 '&' in each row
        jne printSingleRowLoop 


        mov dl, 10
        ;mov ah, 2 ; ah is alredy 2
        int 21h

        ;mov dl, 10 ; dl is already 10
        ;mov ah,2  ; ah is already 2
        int 21h

        mov dl, 13    ; <<<<<<<<<<<<<<<<<<<<< print the carriage return last!
        ;mov ah, 2 ; ah is already 2 
        int 21h  

    loop printRowsLoop  ; print (cx) lines 
ret

printRows endp

No need for an extra space character:)

Upvotes: 4

The problem is the way you are inserting the line breaks. What you do is to display char 13, 10, 10. The solution is to display a blank space after the line breaks (13, 10, 10, ' ') :

mov dl, ' '
mov ah, 2
int 21h

To align the first line, we will have to display another space at the beginning:

printRows proc
    mov ah, 2    ;<=============================================
    mov dl, ' '  ;<=============================================
    int 21h      ;<=============================================

    mov cx, 25
    printRowsLoop:  
        mov si, 0
        printSingleRowLoop:

            mov ah, 3  ;save current cursor position  at dx (dh:dl)
            int 10h

            push dx ;keep the position for later

            mov ah, 2
            mov dl, '&'   
            int 21h      ; print '&' char in the current curser position

            pop dx   ; restore dx

            add dl, 5 ; increase the column of it with a const number (so it would look like a square)
            mov ah, 2
            int 10h

            inc si
            cmp si, 3 ; print 3 '&' in each row
            jne printSingleRowLoop 

        mov dl, 13     ; result of these 3 groups of commands should be 2 new lines
        mov ah, 2
        int 21h

        mov dl, 10
        ;mov ah, 2 ; ah is alredy 2
        int 21h

        ;mov dl, 10 ; dl is already 10
        ;mov ah,2  ; ah is already 2
        int 21h

        mov dl, ' ' ;<=============================================
        mov ah, 2   ;<=============================================
        int 21h     ;<=============================================

        loop printRowsLoop  ; print (cx) lines 
    ret

printRows endp

Upvotes: 0

Fifoernik
Fifoernik

Reputation: 9899

Your code has some problems:

  • The BIOS cursor functions require the BH argument to be specified. It represents the display page. Best set it at zero.

  • The BIOS GetCursor call will destroy the CX register that you need for your loop control. You don't actually need the values returned in CX so just PUSH/POP it.

Use this:

...
push cx
mov bh, 0  ;display page 0
mov ah, 3  ;save current cursor position  at dx (dh:dl)
int 10h    ;GetCursor
pop cx
...
mov bh, 0  ;display page 0
mov ah, 2
int 10h    ;SetCursor
...

Normally these corrections would not solve the issue of scrolling but emu8086 is a program with a lot of problems. You might get lucky!

Upvotes: 2

Related Questions