Архивировано

Эта тема находится в архиве и закрыта для публикации сообщений.

Eringus

Asm

Рекомендованные сообщения

Возникла такая проблема, собственно начал писать программу, использующую графику, использую прерывание 10h биоса

Рисовать и делать приметивы научился, только вот незадача, если я создаю функцию к примеру рисования квадрата, использую ее с переменными значениями, в цикле к примеру координаты верхнего угла квадрата меняется от (100,100) до (100, 200), естесно нечего не работает, так вот интересует как очистить экран без инициализации граф режима заново

Мне как бы нужно чтоб этот квадрат летал по экрану

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Возникла такая проблема, собственно начал писать программу, использующую графику, использую прерывание 10h биоса
Замечательно. Ой, давненько я не брал в руки шашек программировал на сабже :rolleyes: . Интересно, кому сейчас это может быть нужно? :D
Рисовать и делать приметивы научился,
С этого места подробнее плз, а то насколько я знаю BIOS не содержит функций для рисования примитивов
только вот незадача, если я создаю функцию к примеру рисования квадрата, использую ее с переменными значениями, в цикле к примеру координаты верхнего угла квадрата меняется от (100,100) до (100, 200), естесно нечего не работает,
Давай подробнее, что значит "не работает"? Квадраты не рисуются? Тогда смотри функцию, что рисует квадрат.
так вот интересует как очистить экран без инициализации граф режима заново
Заполнить видеопамять нулями. В BIOS нет такой функции.
Мне как бы нужно чтоб этот квадрат летал по экрану
Вот с этого и надо начинать. Я бы на твоем месте не очищал весь экран, а очищал область, занятую квадратом, или (что несколько медленнее, но тоже работает), рисовал бы на старом месте квадрат фоновым цветом (таким образом "убирая" его с экрана), а потом в новом месте рисовал бы квадрат уже тем цветом, который нужен.

ЗЫ. Где-то дома у меня валяются исходники всяких эффектов на сабже. Любо-дорого посмотреть. 2-3 килобайтная программка, а эффекты такие, что Media Player со своими "кольцами дыма" и прочей туфтой нервно курит в сторонке. Умели же люди раньше писать :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

.186

.model small

.stack 100

.data

max dw ?

min dw ?

tmp dw ?

.code

 

;Процедура запуска графического режима

on_graph proc near

mov ax,11h

int 10h

ret

endp

 

;Процедура рисование часов по координатам заложенным в регистрах dx,cx

draw proc near

mov ah,0ch

mov al,3

;Рисуем часы

verh:

inc cx

int 10h

cmp cx,max

jne verh

pravo:

inc dx

int 10h

cmp dx,max

jne pravo

nis:

dec cx

int 10h

cmp cx,min

jne nis

levo:

dec dx

int 10h

cmp dx,min

jne levo

push cx

push dx

;Рисуем деления часов

ret

endp

 

 

start:

mov ax,@Data

mov ds,ax

call on_graph

mov dx,100;координаты

mov cx,100;тоже координаты

mov max,dx

add max,100

mov min,cx

call draw

mov ah,08h

int 21h

mov ah,4ch

int 21h

end start

Собсно рисование квадрата

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ну нормальный с виду код. Оно конечно рисовать попиксельно через BIOS - изврат натуральный, но для обучения программированию пойдет. Сначала научишься через BIOS рисовать, потом начнешь писать в видеопамять (или не начнешь - сдашь куросовую и забудешь ASM как кошмарный сон). Единственное, что углядел - это возможное нарушение стека

jne levo

push cx

push dx

;Рисуем деления часов

ret

endp

Но надеюсь, что ты просто не весь код привел и в конце процедуры из стека все покладеное туда достается. Далее, перед выходом из программы неплохо было бы восстанавливать видеорежим обратно. Не плохо бы тот, который был до запуска программы (узнать можно функцией 0Fh), но если лениво, тупо устанавливай видеорежим 3 (текст 80x25 цветной) - в большинстве случаев он до запуска программы именно такой.

 

Кстати, в инете вычитал, что "очищать" экран можно прокруткой вверх или вниз (функции 06 и 07). Соответственно прокручиваешь на большее количество строк, чем помещается на экране, и экран у тебя чистый. Изврат конечно (сам никогда так не делал), но для обучения пойдет.

 

Ну и собственно что именно не работает? Квадрат рисуется? К сожалению у меня нет ассемблера под рукой, чтобы все это посмотреть в действии. Если не рисуется - посмотри значения цвета в al, когда рисуешь квадрат. Странный ты видеорежим выбрал - 11, он вроде монохромный, поэтому по идее цвета там должны быть 0 или 1, а ты вдруг 3 ему говоришь рисовать. С другой стороны когда начнешь (если начнешь) рисовать прямой записью в видеопамять, то монохромные режимы будут проще: с 16-цветными режимами вообще мрак, и, главное, никому уже не нужно, поэтому нечего даже засирать себе мозг этой ненужной информацией. Совет: используй режим 13h - наиболее простой для программирования (с одной стороны) и больше всего цветов (с другой). Ну а когда будешь организовывать цикл (чтобы квадрат летал), не забудь о задержках, потому как при скорости современных компов он 200 раз этот квадрат нарисует так, что ты и моргнуть не успеешь (в промежутке между двумя обновлениями экрана). Как это сделать подумай. Можно через чтение таймера (курить область данных BIOS), можно тупо через нажатия клавиш int 016h (если возиться лень).

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Не, рисутся то все рисуется, вроде написал процедуру для очистки области экрана, т.е. как бы передаю координаты верхнего левого угла квадрата, беру по Х -1 и цвет беру черный, далее прогоняю до элемента как бы Х+100+1(100 ширина квадрата +1 пиксель), после завершения, получаю линию черный, собственно тем цветом какой и фон(на данный момент квадрат рисуется белым) далее увеличиваю У на 1 и делаю тоже самое что делал, сегодня буду тестить, изврат конечно, если кому будет интересно, то могу потом выложить эти процедуры

По поводу прокрутки экрана, это я знаю, просто меня смущает 1 факт, этот квадрат должен будет двигатся, и если он дистигает границы экрана ударятся и лететь обратно, боюсь если сдвигать вниз на н-ое колличество строк возникнут траблы потом

P.S.Асм сам давно изучал, делаю курсач человеку (5 курс),

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Не, рисутся то все рисуется, вроде написал процедуру для очистки области экрана, т.е. как бы передаю координаты верхнего левого угла квадрата, беру по Х -1 и цвет беру черный, далее прогоняю до элемента как бы Х+100+1(100 ширина квадрата +1 пиксель), после завершения, получаю линию черный, собственно тем цветом какой и фон(на данный момент квадрат рисуется белым) далее увеличиваю У на 1 и делаю тоже самое что делал, сегодня буду тестить, изврат конечно
Конечно :fool: Попробуй что ли

cls	PROC NEAR
push ax
push cx
push di
push es
mov ax, 0A000h
mov es,ax
xor ax,ax
mov di,ax
mov cx, 32768
rep stosw
pop es
pop di
pop cx
pop ax
ret
cls ENDP

Только я тебе этого не говорил :read: .

По поводу прокрутки экрана, это я знаю, просто меня смущает 1 факт, этот квадрат должен будет двигатся, и если он дистигает границы экрана ударятся и лететь обратно, боюсь если сдвигать вниз на н-ое колличество строк возникнут траблы потом
Не возникнут. Прокрутка используется не для передвижения квадрата на новую позицию, а для очистки экрана. Ты прокручиваешь экран на 25 (или сколько там строк помещается), и экран оказывается чистым. После этого рисуешь квадрат там, где он должен оказаться (с учетом всех передвижений, отражений и всего остального). Проверки естественно придется писать самому. Ну или попробуй ту процедуру, что я привел, вдруг поможет (как я говорил ассемблера под рукой нет, все пишу из головы и по памяти)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

clrscr proc near

mov ah,0ch

mov al,0

mov bx,X

mov temp1,bx

mov bx,Y

mov temp2,bx

dec temp1

dec temp2

mov cx,temp1

mov dx,temp2

int 10h

pic:

inc temp1

mov bx,temp1

mov cx,bx

mov bx,temp2

mov dx,bx

int 10h

mov bx,X

add bx,101

cmp temp1,bx

jne pic

mov bx,X

mov temp1,bx

dec temp1

inc temp2

mov bx,Y

add bx,101

cmp temp2,bx

jne pic

ret

endp

Вот мое, очищает область экрана, +-1 пиксель от квадрата, все робит

Теперь последнее что меня интересует, это как воводить в графику цифры, т.е. как получить данные о времени с биоса я знаю, а вот есть ли функция вывода на экран строки или хотя бы 1-ого числа

Все разобарлся каквыводить, осталась 1 пробелма, как перевести число 12 к примеру на экран

Идея такая

читать пока не будет 9, естесна в другой регистр прибавлять автоматичеси значения начиная от 0 код символа 30h того будет 31h и т.д.

как только значения станет больше 9 перенести код символа 1 в переменную hours1 и читать дальше в переменную hours2 начиная с 0

Т.е. в результате должно получится (к примеру число 11) hours1=31h hours2=31h и выводить их друг за другом

Может есть какой нить более простой вариант, подскажите плиз, а то с реализацие своего алгоритма бьюсь уже 2 часа, невыходит

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Все разобарлся каквыводить, осталась 1 пробелма, как перевести число 12 к примеру на экран.
В любом учебнике по ассемблеру есть такое упражнение: написать процедуру для преобразования числа (в ax) в строку. Вариантов множество. Надо только напрячь мозг. Правда писать придется самому: в BIOS таких функций нет. В свое время писал процедуру перевода числа в строку в любой системе счисления (от 2 до 16).
Идея такая читать пока не будет 9, естесна в другой регистр прибавлять автоматичеси значения начиная от 0 код символа 30h того будет 31h и т.д. как только значения станет больше 9 перенести код символа 1 в переменную hours1 и читать дальше в переменную hours2 начиная с 0

Т.е. в результате должно получится (к примеру число 11) hours1=31h hours2=31h и выводить их друг за другом

Может есть какой нить более простой вариант, подскажите плиз, а то с реализацие своего алгоритма бьюсь уже 2 часа, невыходит

Нет. Более простого нет. То, что ты пытаешься сделать, называется BCD-арифметика. В ассемблере даже специальные команды для этого есть (AAA и AAD, если я правильно помню). Числа бывают упакованные и неупакованные. Более простые в обращении неупакованные. Их недостаток - работают только до 99. Я такими вещами не пользовался - сразу написал процедуру по переводу обычных чисел в строку. Подсказка: число итеративно делится на 10 и остаток от деления (который команда DIV помещает в dx) кладется во временный буфер. Когда делить больше нечего (частное от последнего деления равно 0) буфер выводится на экран в обратном порядке (прибавляя каждый раз к числу в буфере 030h для получения ASCII-кода соответствующей цифры). Правда пишется такая программа не за 2 часа, а немного дольше. Но для реального программирования на асме настолько часто употребимая, что с лихвой окупает потраченное время. Ну, это конечно если потом будет что-то реально писать. Если конечно для одного курсача, тогда...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Это ппц, за такой код норм асемблерщики меня бы побили, но не суть, сделал преобразование и вывод времени, работает, вот процедура

set_tim proc near

mov ah,2ch

int 21h

push cx

;ch -часы cl:минуты

cmp ch,10

jge bolshe

jmp menshe

bolshe:

sub ch,10

cmp ch,10

jge bolshe2

jmp menshe2

menshe:

add ch,30h

mov h1,ch

jmp vivod

menshe2:

mov h1,31h

add ch,30h

mov h2,ch

mov flag,0

jmp vivod

bolshe2:

sub ch,10

mov flag,0

mov h1,32h

add ch,30h

mov h2,ch

jmp vivod

vivod:

cmp flag,0

jne one

jmp two

one:

mov ah,09h

mov bh,0

mov al,h1

mov cx,1

mov bl,3

int 10h

jmp minuts

two:

mov ah,09h

mov bh,0

mov al,h1

mov cx,1

mov bl,3

int 10h

 

mov ah,02h

mov bh,0

mov dh,0

mov dl,1

int 10h

 

mov ah,09h

mov bh,0

mov al,h2

mov cx,1

mov bl,3

int 10h

jmp minuts

minuts:

pop cx

cmp cl,10

jge l

jmp vi

l:

sub cl,10

inc shet

cmp cl,10

jge l

jmp vi

vi:

cmp shet,0

jne g

jmp k

g:

mov flag1,0

add shet,30h

mov bl,shet

mov m1,bl

add cl,30h

mov m2,cl

jmp vivo

k:

add cl,30h

mov m1,cl

jmp vivo

vivo:

mov ah,02h

mov bh,0

mov dh,0

mov dl,2

int 10h

 

mov ah,09h

mov bh,0

mov al,3ah

mov cx,1

mov bl,3

int 10h

 

 

cmp flag1,0

jne one_min

jmp h

h:

mov ah,02h

mov bh,0

mov dh,0

mov dl,3

int 10h

 

 

mov ah,09h

mov bh,0

mov al,m1

mov cx,1

mov bl,3

int 10h

 

mov ah,02h

mov bh,0

mov dh,0

mov dl,4

int 10h

 

mov ah,09h

mov bh,0

mov al,m2

mov cx,1

mov bl,3

int 10h

jmp fin

 

one_min:

mov ah,02h

mov bh,0

mov dh,0

mov dl,3

int 10h

 

mov ah,09h

mov bh,0

mov al,m1

mov cx,1

mov bl,3

int 10h

jmp fin

fin:

ret

endp

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах