3

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.

3 Answers3

4

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:)

Xiobiq
  • 400
  • 2
  • 7
  • 16
  • Your code has a few errors! Around the SetCursor call you wrote `push bx` and `pop dx`. Neither of these are needed and because of the mismatch just plain wrong. Please remove them. – Sep Roland Jun 05 '16 at 15:30
  • If your solution solves the issue of scrolling then *emu8086* must be a really, really, really bad program. – Sep Roland Jun 05 '16 at 15:33
  • I fixed those errors, thank you. I guess emu8086 really is a bad program (it has many many bugs). How would you solve this problem? – Xiobiq Jun 05 '16 at 16:58
2

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!

Fifoernik
  • 9,779
  • 1
  • 21
  • 27
  • I know that I should do it (and I do it in my real code), I just tried to post a minimal, complete, and verifiable example. Those fixes don't fix my problem. – maniacsilversmith Jun 02 '16 at 12:10
  • 2
    @maniacsilversmith: it sounds like your code is too minimal if you took out initialization of args that need to be initialized. Might want to update the question to code that avoids these problems, for clarity. – Peter Cordes Jun 04 '16 at 02:40
0

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
  • 1
    Is it really a problem that your code solves or is it a bug in emu8086 that your code "solve" (as a workaround)? I don't really need nor want such space in the beggining of each line. I don't get why would I need one, my original code seems correct to me. Can you explain please? – maniacsilversmith Jun 02 '16 at 23:16
  • @maniacsilversmith, it's the scrolling what confuses the cursor position. Sometimes a line break is not properly recognized until something is displayed. When the blank is displayed the cursor position is forced to be updated, so your code can properly "save" its new position (at the beginning of the loop). Displaying a blank is not a big change in your code, but it's the solution to your problem. – Jose Manuel Abarca Rodríguez Jun 03 '16 at 14:11
  • @maniacsilversmith, your loop displays the line breaks at the bottom, but "saves" the cursor position at the beginning, nothing is displayed in the middle. After the scrolling, displaying something becomes necessary. – Jose Manuel Abarca Rodríguez Jun 03 '16 at 16:30