.model tiny
.code
org 100h
begin: jmp setup
number1 dw 100
number2 dw 100
number9 dw 100
number10 dw 100
count1 dw 200
count5 dw 200
;=============
setup:
mov AX,11h
int 10h
back:
MOV AH,0CH
MOV AL,3
;====================GV
mov CX, number1 ;начальная коордната Х
mov DX, number2 ;начальная коордната Y
label_1:
inc cx ; Х=Х+1
int 10h ; вывести пиксель
cmp cx, count1 ; цикл 200 раз
jle label_1 ; goto label_1
key_loop:
mov ah,7 ;ждем символ с клавы
int 21h
cmp al,27 ; нажали Esc?
je quit ; да, выход
test al,al ;провнрка на 0 начало
jnz key_loop ;если да не выходим, ждем другую клавишу
int 21h
cmp al,50h ;сравнение со стрелкой вниз
je key_down ;переход в обработчик
cmp al,48h ;сравнение со стрелкой вверх
je key_up ;переход в обработчик
MOV AH,0CH
MOV AL,0
;==================================================
black proc ; закрас
mov CX, number9 ;начальная коордната Х
mov DX, number10 ;начальная коордната Y
label_5:
inc cx ; Х=Х+1
int 10h ; вывести пиксель
cmp cx, count5 ; цикл 200 раз
jle label_5 ; goto label_1
black endp
;==================================================
key_up:
call black
dec number2 ;строка
dec number10 ;строка
jmp back
key_down:
call black
inc number2 ;строка
inc number10 ;строка
jmp back
quit:
mov ax,0003h ; востановить текстовый режим
int 10h
RET
end begin
Управление квадратом по экрану
================================================== ===
Логика программы:
1. Переменные с инициализацией.
2. Установка видеорежима
3. *Команда вывода точки в цикле (прорисовываю квадрат)
4. ловлю нажатие клавиши (key_loop) и переход в обработчик:
если ESC, quit
если вниз, key_down
если вверх, key_up
если влево, key_left
если вправо, key_right
если влево-вверх, key_home
если вправо-вверх, key_pgup
если влево-вниз, key_end
если враво-вниз, key_pgdn
(далее см. 6 пункт)
5. *Циклический вывод точки (прорисовываю квадрат по новым
координатам полученным из обработчика) и переход
в 4 пункт
6. В обработчике выводится черный квадрат поверх синего, для
закраски, изменяются переменные, прорисовывающие квадрат и
переход на 5 пункт.
*Пункт 3 для начального положения квадрата на экране.
*Пункт 5 для прорисовки квадрата по новым переменным.
================================================== ===
Посмотрите, пожалуйста, если Вам не трудно.
Я бы никогда не додумался писать программы в ворде ;-)
Спасибо брат. Как сказать по другому, незнаю.
решил сделать по минимуму, пока.
Отрезок. При начале работы вычерчивается отрезок. Нажимаю вврех или вниз, отрезок пропадает и прога виснет. Не реагирует на клавиши.
Код:
Похоже действительно нужно что-то сохранять, где ошибка, не могу найти. Может очистку экрана делать, перед рисованием отрезка?
В моей роге всё просто. Читай названия меток и комментарии.
Цитата:
Ты забыл сделать возврат из процедуры.
В вызове call black?
так там не надо. это же вызов подпрограммы. после её работы, сохраненный адрес следущей строки берется из стека и работа идет с этого адреса.
В обработчике клавиши key_up/key_down?
я поставил jmp back.
Цитата:
В моей роге всё просто. Читай названия меток и комментарии
я не разобрался. там множественные goto и множественные сохранения в стеке :(
Цитата:
так там не надо. это же вызов подпрограммы. после её работы, сохраненный адрес следущей строки берется из стека и работа идет с этого адреса.
Прямо сам и берётся? Процессоры пока не научились читать мысли программиста и требуют для работы прямых команд. Для выборки из стека адреса и перехода по нему используется команда RET (RETN, RETF).
Цитата:
там множественные goto
А я думал, что на асемблере писал... ;-)
Откомментировал исходник получше. Если что непонятно, задавай конкретные вопросы, а не "множественные гото", можно в аську, чтобы форум не засорять.
Код:
max_x = 1023 ;
max_y = 767 ; Размер экрана в используемом видеорежиме
; RRRRRGGGGGGBBBBB
color = 0100011111111111b ; Цвет прямоугольника
start_x = max_x/2 ; \
start_y = max_y/2 ; -- Начальные координаты прямоугольника
sx = 30 ; \
sy = 50 ; -- Удвоенные размеры прямоугольника
ideal
model tiny
codeseg
p386
org 100h
start:
mov ax,4f02h ; Установка режима
mov bx,117h ; 1024x768 2 байта на точку
int 10h
cmp ax,4fh ; Функция поддерживается?
jne error
mov ax,0a000h ; Сегментный адрес окна видеопамяти
mov es,ax
;-------------- ------- ------------------------
dec sp
dec sp
redraw:
inc sp
inc sp
; Здесь выведем линейку по краю экрана
mov ax,0f000h ; Цвет
xor bx,bx ; X=0
xor dx,dx ; Y=0
ruler:
mov cx,dx
line:
call pixel
inc bx
call pixel
inc bx
cmp bx,32
je step
shr cx,1
jnc line
step:
xor bx,bx
inc dx
cmp dx,max_y
jne ruler
;-------------- ------- ------------------------
mov dx,start_y ; Начальные
mov bx,start_x ; координаты
mov ax,color ; и цвет
keyscan:
push ax
mov ah,0 ; Ждём нажатия
int 16h ; клавиши
;---------------------------
cmp ah,48h ; Стрелка вверх
je up_arrow
cmp ah,50h ; Стрелка вниз
je down_arrow
cmp ah,4bh ; Стрелка влево
je left_arrow
cmp ah,4dh ; Стрелка вправо
je right_arrow
cmp ah,47h ; HOME
je home
cmp ah,49h ; PgUp
je PgUp
cmp ah,4fh ; End
je EndA
cmp ah,51h ; PgDn
je PgDn
cmp ah,1 ; ESC
je exit
cmp ah,1ch ; Ввод
je redraw
pop ax
jmp keyscan
up_arrow:
pop ax ; Цвет
cmp dx,sy ; Край экрана
je keyscan ; Край экрана - сначала
call clear ; Чёрный квадрат
dec dx ; Переместить вверх
call square ; Цветной квадрат
jmp keyscan ; Сначала
down_arrow:
pop ax
cmp dx,max_y-sy
je keyscan
call clear
inc dx
call square
jmp keyscan
left_arrow:
pop ax
cmp bx,sx
je keyscan
call clear
dec bx
call square
jmp keyscan
right_arrow:
pop ax
cmp bx,max_x-sx
je keyscan
call clear
inc bx
call square
jmp keyscan
home:
pop ax
cmp bx,sx
jz keyscan
cmp dx,sy
jz keyscan
call clear
dec dx
dec bx
call square
jmp keyscan
PgUp:
pop ax
cmp bx,max_x-sx
je keyscan
cmp dx,sy
jz keyscan
call clear
dec dx
inc bx
call square
jmp keyscan
EndA:
pop ax
cmp bx,sx
je keyscan
cmp dx,max_y-sy
je keyscan
call clear
inc dx
dec bx
call square
jmp keyscan
PgDn:
pop ax
cmp bx,max_x-sx
je keyscan
cmp dx,max_y-sy
je keyscan
call clear
inc bx
inc dx
call square
jmp keyscan
exit:
pop ax
error:
mov ax,3 ; Текстовый режим
int 10h
ret ; Выход
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
proc clear near ; Рисует чёрный квадрат
; BX=x ; DX=y ; ES=VideoRAMsegm
push ax
xor ax,ax ; Чёрный цвет
call square ; Нарисовать
pop ax
ret
endp clear
;-------------- ------- ------------------------
proc square near
; AX=colour BX=x ; DX=y ; ES=VideoRAMsegm
push bx dx
mov si,bx
mov di,dx
add si,sx+1 ;
add di,sy+1 ; Конец квадрата
sub bx,sx ;\
sub dx,sy ; > Начало квадрата
mov cx,bx ;/
or ax,ax ; Закраска чёрным?
jnz row
call waitvsync ; Да - Ждать обратного хода луча
row:
call pixel
inc bx ; X+1
cmp bx,si
jne row ; Вывод строчки прямоугольника
mov bx,cx ; X=X0
inc dx ; Y+1 - след. строка
cmp dx,di
jne row
pop dx bx
ret
endp square
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
proc pixel near ; Вывод точки
; AX=colour(ch=0?) ; BX=x ; DX=y ; ES=VideoRAMsegm
push ax bx dx
push ax ; Цвет
push bx ; x
push dx ; y
; 1024*2 => 32 строки в окне
shr dx,5 ; dx/32
cmp dx,[bank] ; Текущее окно видеопамяти
je win_ok
mov [bank],dx
mov ax,4f05h ; Сделать текущим окно в DX
xor bx,bx
int 10h
win_ok:
pop ax ; Y
and ax,11111b ; y%32 - координата в окне
shl ax,11 ; Y*2048
pop bx ; X
shl bx,1 ; X*2 бита на точку
add bx,ax ; коорд. в окне
pop ax ; цвет
mov [es:bx],ax ; Записать точку
pop dx bx ax
ret
bank dw 0
endp pixel
;-------------- ------- ------------------------
proc waitvsync near ; Ожидание обратного хода луча
push ax
push dx
mov dx,03dah ;регистр статуса VGA
@@wait1:
in al,dx
and al,08h ;выделяем бит вертикальной синхронизации
jnz @@wait1
@@wait2:
in al,dx
and al,08h ;выделяем бит вертикальной синхронизации
jz @@wait2
pop dx
pop ax
ret
endp waitvsync
end start
max_y = 767 ; Размер экрана в используемом видеорежиме
; RRRRRGGGGGGBBBBB
color = 0100011111111111b ; Цвет прямоугольника
start_x = max_x/2 ; \
start_y = max_y/2 ; -- Начальные координаты прямоугольника
sx = 30 ; \
sy = 50 ; -- Удвоенные размеры прямоугольника
ideal
model tiny
codeseg
p386
org 100h
start:
mov ax,4f02h ; Установка режима
mov bx,117h ; 1024x768 2 байта на точку
int 10h
cmp ax,4fh ; Функция поддерживается?
jne error
mov ax,0a000h ; Сегментный адрес окна видеопамяти
mov es,ax
;-------------- ------- ------------------------
dec sp
dec sp
redraw:
inc sp
inc sp
; Здесь выведем линейку по краю экрана
mov ax,0f000h ; Цвет
xor bx,bx ; X=0
xor dx,dx ; Y=0
ruler:
mov cx,dx
line:
call pixel
inc bx
call pixel
inc bx
cmp bx,32
je step
shr cx,1
jnc line
step:
xor bx,bx
inc dx
cmp dx,max_y
jne ruler
;-------------- ------- ------------------------
mov dx,start_y ; Начальные
mov bx,start_x ; координаты
mov ax,color ; и цвет
keyscan:
push ax
mov ah,0 ; Ждём нажатия
int 16h ; клавиши
;---------------------------
cmp ah,48h ; Стрелка вверх
je up_arrow
cmp ah,50h ; Стрелка вниз
je down_arrow
cmp ah,4bh ; Стрелка влево
je left_arrow
cmp ah,4dh ; Стрелка вправо
je right_arrow
cmp ah,47h ; HOME
je home
cmp ah,49h ; PgUp
je PgUp
cmp ah,4fh ; End
je EndA
cmp ah,51h ; PgDn
je PgDn
cmp ah,1 ; ESC
je exit
cmp ah,1ch ; Ввод
je redraw
pop ax
jmp keyscan
up_arrow:
pop ax ; Цвет
cmp dx,sy ; Край экрана
je keyscan ; Край экрана - сначала
call clear ; Чёрный квадрат
dec dx ; Переместить вверх
call square ; Цветной квадрат
jmp keyscan ; Сначала
down_arrow:
pop ax
cmp dx,max_y-sy
je keyscan
call clear
inc dx
call square
jmp keyscan
left_arrow:
pop ax
cmp bx,sx
je keyscan
call clear
dec bx
call square
jmp keyscan
right_arrow:
pop ax
cmp bx,max_x-sx
je keyscan
call clear
inc bx
call square
jmp keyscan
home:
pop ax
cmp bx,sx
jz keyscan
cmp dx,sy
jz keyscan
call clear
dec dx
dec bx
call square
jmp keyscan
PgUp:
pop ax
cmp bx,max_x-sx
je keyscan
cmp dx,sy
jz keyscan
call clear
dec dx
inc bx
call square
jmp keyscan
EndA:
pop ax
cmp bx,sx
je keyscan
cmp dx,max_y-sy
je keyscan
call clear
inc dx
dec bx
call square
jmp keyscan
PgDn:
pop ax
cmp bx,max_x-sx
je keyscan
cmp dx,max_y-sy
je keyscan
call clear
inc bx
inc dx
call square
jmp keyscan
exit:
pop ax
error:
mov ax,3 ; Текстовый режим
int 10h
ret ; Выход
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
proc clear near ; Рисует чёрный квадрат
; BX=x ; DX=y ; ES=VideoRAMsegm
push ax
xor ax,ax ; Чёрный цвет
call square ; Нарисовать
pop ax
ret
endp clear
;-------------- ------- ------------------------
proc square near
; AX=colour BX=x ; DX=y ; ES=VideoRAMsegm
push bx dx
mov si,bx
mov di,dx
add si,sx+1 ;
add di,sy+1 ; Конец квадрата
sub bx,sx ;\
sub dx,sy ; > Начало квадрата
mov cx,bx ;/
or ax,ax ; Закраска чёрным?
jnz row
call waitvsync ; Да - Ждать обратного хода луча
row:
call pixel
inc bx ; X+1
cmp bx,si
jne row ; Вывод строчки прямоугольника
mov bx,cx ; X=X0
inc dx ; Y+1 - след. строка
cmp dx,di
jne row
pop dx bx
ret
endp square
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
proc pixel near ; Вывод точки
; AX=colour(ch=0?) ; BX=x ; DX=y ; ES=VideoRAMsegm
push ax bx dx
push ax ; Цвет
push bx ; x
push dx ; y
; 1024*2 => 32 строки в окне
shr dx,5 ; dx/32
cmp dx,[bank] ; Текущее окно видеопамяти
je win_ok
mov [bank],dx
mov ax,4f05h ; Сделать текущим окно в DX
xor bx,bx
int 10h
win_ok:
pop ax ; Y
and ax,11111b ; y%32 - координата в окне
shl ax,11 ; Y*2048
pop bx ; X
shl bx,1 ; X*2 бита на точку
add bx,ax ; коорд. в окне
pop ax ; цвет
mov [es:bx],ax ; Записать точку
pop dx bx ax
ret
bank dw 0
endp pixel
;-------------- ------- ------------------------
proc waitvsync near ; Ожидание обратного хода луча
push ax
push dx
mov dx,03dah ;регистр статуса VGA
@@wait1:
in al,dx
and al,08h ;выделяем бит вертикальной синхронизации
jnz @@wait1
@@wait2:
in al,dx
and al,08h ;выделяем бит вертикальной синхронизации
jz @@wait2
pop dx
pop ax
ret
endp waitvsync
end start
black proc
ret
black endp
все рано не получается, ну как сделать... то..?
:(
Ещё один совет. Давай переменным более осмысленные названия, чем number1, number2 и т.п., иначе на следующий день будешь долго разбираться в своей же программе, да и в процессе написания будут сложности с пониманием того, что где лежит.
чтоб работало, нужно ставить jz, правда прога слетает, если нажать что-то кроме ESC, up, down.
Почему слетает? Потому что не выходит из графического режима перед выходом.
je - это та же самая команда, что и jz.
я в WinAsm 2.0 пишу. Может по этому?