Горизонтальная прокрутка экрана - 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
Объяснение кода листинга программы
- Переменные:
- si (10) - счётчик горизонтальной позиции экрана
- di (10) - счётчик вертикальной позиции экрана
- cx (11) - счётчик количества символов в строке
- bx (11) - временная переменная для хранения символа
- ax (12) - используется в операциях с регистром ввода/вывода
- Команды:
- 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) - используется для выполнения сложения с учетом переноса
- Процедуры:
- wait (16) - процедура задержки
- Описание работы программы: Программа выполняет плавную прокрутку экрана по горизонтали. Она считывает скан-код последнего символа, и если это 81h (отпускание клавиши Esc), то выходит из программы. В противном случае, программа продолжает прокрутку. В процедуре wait используется задержка в 3 секунды для имитации плавности прокрутки.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д