Горизонтальная прокрутка экрана - Assembler

Узнай цену своей работы

Формулировка задачи:

Всем здрасвуйте! Прошу помочь реализовать горизонтальную прокрутку экрана. Есть пример с вертикальной, но я не могу разобраться как делать горизонтальную... в интернете, толком ничего не написано, да и похожих програм нет... знаю что нужно использовать регистр горизонтального панорамирования 13h, но как это сделать не знаю... Вот программа вертикальной прокрутки экрана:
; Плавная прокрутка экрана по вертикали. Выход - клавиша Esc
;
        .model     tiny
        .code
        .186                        ; для push 0B400h
        org        100h             ; СОМ-программа
start:
        push       0B800h
        pop        es
        xor        si,si            ; ES:SI - начало видеопамяти
        mov        di,80*25*2       ; ES:DI - начало второй страницы видеопамяти
        mov        cx,di
        rep        movs es:any_label,es:any_label   ; скопировать первую
                                                    ; страницу во вторую
        mov        dx,03D4h         ; порт 03D4h: индекс CRT
screen_loop:                        ; цикл по экранам
        mov        cx,80*12*2       ; СХ = начальный адрес - адрес середины экрана
line_loop:                          ; цикл по строкам
        mov        al,0Ch           ; регистр 0Ch - старший байт начального адреса
        mov        ah,ch            ; байт данных - СН
        out        dx,ax            ; вывод в порты 03D4, 03D5
        inc        ax               ; регистр 0Dh - младший байт начального адреса
        mov        ah,cl            ; байт данных - CL
        out        dx,ax            ; вывод в порты 03D4, 03D5
 
        mov        bx,15            ; счетчик линий в строке
        sub        cx,80            ; переместить начальный адрес на начало
                                    ; предыдущей строки (так как это движение вниз)
pel_loop:                           ; цикл по линиям в строке
        call       wait_retrace     ; подождать обратного хода луча
 
        mov        al,8          ; регистр 08h - выбор номера линии в первой
                                 ; строке, с которой начинается вывод изображения
        mov        ah,bl         ; (номер линии из BL)
        out        dx,ax
 
        dec        bx               ; уменьшить число линий,
        jge        pel_loop         ; если больше или = нулю - строка еще не
                                    ; прокрутилась до конца и цикл по линиям
                                    ; продолжается
        in         al,60h           ; прочитать скан-код последнего символа,
        cmp        al,81h           ; если это 81h (отпускание клавиши Esc),
        jz         done             ; выйти из программы,
        cmp        cx,0             ; если еще не прокрутился целый экран,
        jge        line_loop        ; продолжить цикл по строкам,
        jmp        short screen_loop ; иначе: продолжить цикл по экранам
 
done:                               ; выход из программы
        mov        ax,8             ; записать в регистр CRT 08h
        out        dx,ax            ; байт 00 (никакого сдвига по вертикали),
        add        ax,4             ; а также 00 в регистр 0Ch
        out        dx,ax
        inc        ax               ; и 0Dh (начальный адрес совпадает
        out        dx,ax            ; с началом видеопамяти)
        mov ax, 4c00h
        int 21h
        ret
 
wait_retrace       proc    near
        push       dx
        mov        dx,03DAh
VRTL1:  in         al,dx            ; порт 03DAh - регистр ISR1
        test       al,8
        jnz        VRTL1            ; подождать конца текущего обратного хода луча,
VRTL2:  in         al,dx
        test       al,8
        jz         VRTL2            ; а теперь начала следующего
    pop dx
    ret
wait_retrace       endp
 
any_label  label   byte             ; метка для переопределения сегмента в movs
        end        start

Решение задачи: «Горизонтальная прокрутка экрана»

textual
Листинг программы
; Плавная прокрутка экрана по горизонтали. Выход - клавиша Esc
;
;DOS, TASM, COM-файл
;tasm.exe /m filename.asm
;tlink.exe /t /x filename.obj
;
.model tiny
.code
.386
org 100h             ; СОМ-программа
start:
    mov ax,0B800h
    push ax ax
    pop ds es
    mov si,80*2-2
    mov di,si
    std
m4:
    mov cx,80
m3:
push cx 
    mov cx,25
m2:
    lodsw
    mov bx,ax
push cx
    mov cx,79
m1:
    lodsw
    stosw
    loop m1
pop cx
    mov ax,bx
    stosw
    add si,160*2
    mov di,si
    in al,60h   ; прочитать скан-код последнего символа,
    cmp al,81h  ; если это 81h (отпускание клавиши Esc),
    jz exit     ; выйти из программы,
    loop m2
pop cx
    sub si,160*25
    mov di,si
    call wait
    loop m3
    jmp m4
exit:
    mov ax,4c00h
    int 21h
 
wait    proc    near
push ax cx dx si di
    mov ah,0
    int 1Ah
    add dx,2    ;18*3 задержка примерно на 3 секунды
    adc cx,0
    mov di,dx
    mov si,cx
DELAY:
    int 1Ah
    cmp cx,si
    ja EndDELAY
    cmp dx,di
    jb DELAY
EndDELAY:
pop di si dx cx ax
    ret
wait    endp
    end start

Объяснение кода листинга программы

  1. Переменные:
    • si (10) - счётчик горизонтальной позиции экрана
    • di (10) - счётчик вертикальной позиции экрана
    • cx (11) - счётчик количества символов в строке
    • bx (11) - временная переменная для хранения символа
    • ax (12) - используется в операциях с регистром ввода/вывода
  2. Команды:
    • mov (13) - используется для передачи данных между регистрами
    • push (13) / pop (13) - используются для работы со стеком
    • lodsb (14) - используется для чтения одного байта из памяти
    • stosb (14) - используется для записи одного байта в память
    • in (14) - используется для чтения данных из порта ввода/вывода
    • cmp (14) - используется для сравнения двух значений
    • jz (14) / jnz (14) - используются для перехода к определенному блоку кода
    • call (14) - используется для вызова подпрограммы
    • int (14) - используется для обращения к системным услугам DOS
    • ret (14) - используется для возврата из подпрограммы
    • adc (15) - используется для выполнения сложения с учетом переноса
  3. Процедуры:
    • wait (16) - процедура задержки
  4. Описание работы программы: Программа выполняет плавную прокрутку экрана по горизонтали. Она считывает скан-код последнего символа, и если это 81h (отпускание клавиши Esc), то выходит из программы. В противном случае, программа продолжает прокрутку. В процедуре wait используется задержка в 3 секунды для имитации плавности прокрутки.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

10   голосов , оценка 4.5 из 5
Похожие ответы