· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› управление с клавиатуры

Посл.отвђт Сообщенiе


Дата: Мар 13, 2004 16:09:43

Вот написал программу, управление символом с клавиатуры.
Можно ли процедуру Move организовать по другому?, а то меня например пугает обилие меток(еще с паскаля их не использовал) и переходов в ней, но по другому придумать не смог. Это первая программа "не c книги" по этому не судите строго.
CSEG segment
assume cs:CSEG,ds:CSEG,es:CSEG,ss:CSEG
org 100h
begin:
mov atr,2
mov space,0
call check_Video
mp:
call wait_key
cmp al,27
je end_p

mov kk,ah
call move
jmp mp
end_p:
int 20h
;
move proc

cmp kk,3bh
jne l0
call Check_video
jmp end_p2

l0:
cmp kk,2ch
jne l1
not space
jmp end_p2

l1:
cmp kk,48h
jne l2

cmp space,0ffh
jne l11

mov atr,0
call out_c
mov atr,2
l11:
dec c_str
jmp out_c

;идем вниз
l2:
cmp kk,50h
jne l3

cmp space,0ffh
jne l22

mov atr,0
call out_c
mov atr,2
l22:
inc c_str
jmp out_c

;идем влево
l3:
cmp kk,4bh
jne l4

cmp space,0ffh
jne l33

mov atr,0
call out_c
mov atr,2
l33:
dec c_stt
jmp out_c

;идем вправо
l4:
cmp kk,4dh
jne end_p2

cmp space,0ffh
jne l44

mov atr,0
call out_c
mov atr,2
l44:
inc c_stt
jmp out_c

out_c:
call set_cursor_pos
call Out_char
end_p2:
ret
move endp

; Проверяем на текстовый режим монитора и на текущую видео страницу
Check_video proc
; mov ah,0Fh
; int 10h
; cmp al,3 ;Текущий режим монитора текстовый?
; je Ok_video
mov ax,3 ;Если нет - делаем текстовый
int 10h
;Ok_video:
cmp bh,0 ;Нулевая страница?
jz Ok_page
mov ax,0500h ;Если нет - делаем нулевую текущей
int 10h
Ok_page:
mov c_str,12
mov c_stt,40
call set_cursor_pos
ret
Check_video endp
; --- Wait_key ---
set_cursor_pos proc
mov ah,02
mov bh,0
mov dh,c_str
mov dl,c_stt
int 10h
ret
set_cursor_pos endp

Wait_key proc
mov ah,10h
int 16h
ret
Wait_key endp

; --- Out_char ---
Out_char proc
push cx
push ax
push es
; push ax

mov ah,09h
mov bh,0
mov al,0Fh
mov bl,atr
mov cx,1
int 10h

pop es
pop ax
pop cx
ret
Out_char endp

;объявляем переменную для кода расширенной клавиши
kk db 0h
c_str db 0h
c_stt db 0h
atr db 0h
space db 0h
CSEG ends
end Begin


Дата: Мар 14, 2004 02:56:09

Если это МАСМ, используй локальные метки типа
  jmp @f ; вперёд на @@
@@:
  jmp @b ; назад на @@

или условные конструкции:
  .if eax==5
  .endif

может тогда обилие меток не будет так сильно смущать:-)


Дата: Мар 14, 2004 03:48:15

_Ti_

al - код клавиши
mov dl,col
mov dh,row

dec dh
cmp al,up
jz .move
inc dh

inc dh
cmp al,down
jz .move
dec dh

dec dl
cmp al,left
jz .move
inc dl

inc dl
cmp al,right
jz .move
dec dl

;здесь проверяем остальные клавиши

.move: ;в dh:dl у нас новая строка/столбец

cmp dh,maxrow;не вышли ли мы за пределы экрана
jae .nodraw
cmp dl,maxcol
jae .nodraw

xchg row,dh
xchg col,dl

здесь стираем(если нужно) символ в старой позиции

mov dl,col
mov dh,row

cmp space,255
jnz .nodraw

а здесь рисуем в новой

.nodraw:


Дата: Мар 14, 2004 04:18:43 · Поправил: _Ti_

Значит от использовния меток никуда не уйдешь,
просто можно свести их количество к минимуму.
Использую TASM.
Black_mirror
cmp dh,maxrow;не вышли ли мы за пределы экрана
jae .nodraw
cmp dl,maxcol
jae .nodraw

это как я понимаю проверка на правую и нижнии границы экрана ?


Дата: Мар 14, 2004 05:10:32

_Ti_
В данном случае безусловно рулит пример Black_mirror

Но в общем, в игрушках делают примерно так:
.data
key_table:
dw VK_LEFT, offset proc.LEFT
dw VK_RIGHT, offset proc.RIGHT
.....
dw 0

.code
process_key:	;;   al - код клавиши
	mov dx, offset key_table
@@:	cmp byte [edx], 0	;;  таблица закончилась?
	jz  end
	cmp byte [edx], al
	lea edx, [edx+4]	;;  прибавляем 4, не меняя флаги
	jnz @b		;;  не та клавиша, проверяем следующую
	call [edx-2]	;;  вызываем обработчик клавиши (адрес в таблице)
end:


ЗЫ
IMHO, IF/ELSE - не самый лучший вариант для асма, они кажутся проще, но это очень обманчиво.


Дата: Мар 14, 2004 05:11:40

_Ti_
Если нужно проверить условие вида 0<=ax<N, можно обойтись всего одним сравнением: cmp ax,N. А при переходе считать, что число у нас было беззнаковое: jae(jb) label(или ja(jbe) если <=). Хотя БИОС вроде строки и столбцы нумерует с 1(с 0 на мой взгляд нумеровать удобнее), поэтому на 0 придется проверять отдельно.


Дата: Мар 14, 2004 05:58:21

S_T_A_S_
Сложновато немножко, но суть понял, такой код действительно получше будет.
Black_mirror
спасиб.

вместо al, может быть и ah? так как код стрелок в нем.


Дата: Мар 14, 2004 07:26:33

_Ti_
Это на будущее ;-) Тут есть еще приимущество - можно менять кнопки в процессе работы программы.


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.047