Parar loop com entrada de caractere

1. Parar loop com entrada de caractere

Douglas Jovenil Castilhos dos Santos
Schnapps

(usa Debian)

Enviado em 09/07/2017 - 01:11h

Boa noite a todos
Estou com uma dúvida na programação de assembly, estou fazendo um programa para ser rodado no mic 8086, onde o mesmo deve acionar uma matrix de leds 7x5, o programa está praticamente pronto, porém estou encontrando problemas para finalizar, dentro da label "sequencia" o programa printa na tela informações, manda o mic ligar e desligar os leds, chama a subrotina de delay, e faz uma comparação com 20h, caso o meu contador esteja em 20h, ele reinicia.
A minha dúvida em si é esta na sub rotina chamada para_led, que possui os seguintes comandos:

mov dl,0ffh
mov ah,6h
int 21h

Este comando pelo o que entendi faz que seja lido os caracteres inseridos no teclado dentro de um loop e o mesmo caractere é inserido dentro do registrador DL, e logo após a chamada dessa subrotina é feito uma comparação com para ver se o caractere inserido é 's', no caso é o caractere que gostaria que finalizasse o ciclo, porém caso seja apertado qualquer tecla antes, o programa roda o ciclo a quantidade x de caracteres foram pressionados antes de encontrar a letra 's'.
Por exemplo, se eu digitar, "1,2,3,4,5,s", o programa ira rodar 5 vezes e depois voltar para o menu principal quando encontrar o 's', eu gostaria de saber se alguém pode me ajudar com alguma informação para que caso seja apertado n teclas e logo em seguida 's' o programa finalize o ciclo sem que seja executadas n vezes antes de encontrar o 's'.
Já tentei limpar o buffer após a comparação com o caractere 's' (isto está no programa abaixo), porém o que acontece é que, por exemplo, no primeiro ciclo eu aperte 5 vezes qualquer tecla e depois o 's' e nos ciclos restantes eu não pressione nenhuma tecla, o programa executará o loop 5 vezes e irá parar, mas caso eu aperte as mesmas 5 teclas no primeiro ciclo e depois o 's', e no segundo ciclo eu aperte 's', o programa finaliza no segundo ciclo.
Enfim é difícil de explicar por texto, portanto estou colocando o programa logo abaixo, e provavelmente o cabeçalho do programa irá aparecer desconfigurado, já que estou usando um caractere especial que quando coloquei aqui foi trocado por "?", qualquer coisa só pedir.
Agradeço desde já.

PILHA SEGMENT; Come?o da pilha 
PILHA ENDS; Fim da pilha

DADOS SEGMENT; Come?o dos dados
min DB 00
segn DB 00
cent DB 00
coluna_ativa DB 00

TMP1 DB '0.5 seg$'
TMP2 DB '1.0 seg$'
TMP3 DB '1.5 seg$'
TMP4 DB '2.0 seg$'
MSG1 DB ' ?????????????????????????????????????????????????????????????????????????????',0AH,0DH
DB ' ? PISCA LEDS ? ',0AH,0DH
DB ' ?????????????????????????????????????????????????????????????????????????????',0AH,0DH
DB ' ',0AH,0DH
DB ' ',0AH,0DH
DB ' ???????????????????? ',0AH,0DH
DB ' ? A ? 0.5 segundos ? ',0AH,0DH
DB ' ? B ? 1.0 segundos ? ',0AH,0DH
DB ' ? C ? 1.5 segundos ? ',0AH,0DH
DB ' ? D ? 2.0 segundos ? ',0AH,0DH
DB ' ? S ? Parar Ciclo ? ',0AH,0DH
DB ' ? P ? Sair ? ',0AH,0DH
DB ' ????????????????????', 0AH,0DH
DB ' ',0AH,0DH
DB ' ',0AH,0DH
DB ' ??????????????????????????????? ',0AH,0DH
DB ' ? Tempo Selecionado ? ? ',0AH,0DH
DB ' ? Coluna Ativa ? ? ',0AH,0DH
DB ' ???????????????????????????????', 0AH,0DH
DB ' ',0AH,0DH
DB ' ',0AH,0DH
DB ' Insira um comando: ','$'



DADOS ENDS; Fim dos dados

CODIGO SEGMENT; Come?o do programa
ASSUME CS:CODIGO, DS:DADOS, SS:PILHA

delay:
push ax
push bx
push cx
push dx
mov ah,2ch; ler o tempo corrente
int 21h; CH=horas, CL=minutos, DH=segundos, DL=cent?simos
mov al, min
mov bh, segn
mov bl, cent
;somar o tempo corrente com o tempo de delay
mov ah,ch; horas
add al,cl; minutos
add bh,dh; segundos
add bl,dl; cent?simos
;corre??o de cent?simos, segundos, minutos e horas
cmp bl,100; o n?mero de cent?simos <100
jb secs
sub bl,100
inc bh
secs:
cmp bh,60; o n?mero de seg <60
jb mins
sub bh,60
inc al
mins:
cmp al,60; o n?mero de min <60
jb hrs
sub bh,60
inc ah
hrs:
cmp ah,24; o n?mero de horas <24
jne check
sub ah, ah
; esperar o valor de pausa
check:
push ax;
mov ah,2ch; ler o tempo real de novo
int 21h
pop ax
cmp cx,ax; comparar horas e minutos
ja quit
jb check
cmp dx,bx; comparar segundos e cent?simos
jb check
quit:
pop dx
pop cx
pop bx
pop ax
ret

limpa_tela:
MOV AH, 6h ; configura INT10 para scroll window up
MOV AL, 0h ; numero de linhas a limpar -> 0h = todas
MOV CH, 0h ; primeira linha
MOV CL, 0h ; primeira coluna
MOV DH, 24 ; ultima linha
MOV DL, 79 ; ultima coluna
MOV BH, 0AH ; Fundo Preto com letra verde ;
INT 10h
RET

tela:
MOV DX, OFFSET MSG1;
MOV AH, 9H; Registrador AH recebe o servi?o 9h do DOS para mostrar string
int 21h;
RET

posiciona_tela:
mov AH,2h; Posicionar o cursor
MOV BH,0H; Pagina zero
MOV DH,0H; Linha
MOV DL,0H; Coluna
int 10h ; Servi?o
ret

entrada:
MOV AH,01H; Servi?o para entrada de caracter
INT 21H;
AND AX,00FFH; m?scara para separar AL
ret

posiciona_tempo:
mov AH,2h; Posicionar o cursor
MOV BH,0H; Pagina zero
MOV DH,10H; Linha
MOV DL,2FH; Coluna
int 10h ; Servi?o
ret

posiciona_coluna:
push ax;
push bx
push dx;
mov AH,2h; Posicionar o cursor
MOV BH,0H; Pagina zero
MOV DH,11H; Linha
MOV DL,32H; Coluna
int 10h ; Servi?o
pop dx;
pop bx;
pop ax;
ret

zera_opcao:
mov ax,1h
mov dx, 300h
mov coluna_ativa,31h;
ret

printa_coluna:
push ax;
push dx;
mov dl,coluna_ativa;
mov ah,02h;
int 21h
pop dx;
pop ax;
ret

desliga_led:
push ax;
mov ax, 0h
out dx, ax
pop ax;
ret

move_led:
shl ax,1;
inc coluna_ativa;
cmp ax,20h;
ret

para_led:
push dx;
mov Dl, 0ffh
mov ah,6
int 21h
pop dx;
cmp al, 's'
ret

zera_ciclo:
mov ax,1
mov dx,300h;
mov coluna_ativa,31h;
ret

posiciona_cursor:
push ax;
push bx
push dx;
mov AH,2h; Posicionar o cursor
MOV BH,0H; Pagina zero
MOV DH,15H; Linha
MOV DL,33H; Coluna
int 10h ; Servi?o
pop dx;
pop bx;
pop ax;
ret

finaliza_ok:
MOV AH, 4CH;
INT 21H; chamada do DOS
ret

INICIO:
MOV AX, DADOS; OBRIGAT?RIO
MOV DS, AX; OBRIGAT?RIO
MOV AX,PILHA;
MOV SS,AX;
mov DX, 303h
mov AL, 80h
out DX,AL
start:
call limpa_tela;
call posiciona_tela
call tela;
call entrada;

CMP AX,'p';
je finaliza

cmp ax,'a';
jb start;
cmp ax,'d';
jg start;

push ax
call entrada;
cmp ax,0dh;
jne start;
pop ax;

CMP AX,'a';
je meio;
CMP AX,'b';
je um;
CMP AX,'c';
je um_meio;
CMP AX,'d';
je dois

finaliza:
mov ah,01h;
int 21h;
cmp al,0dh;
je finaliza_ok;
jmp start;

meio:
call posiciona_tempo;
mov ah,09h;
mov dx, OFFSET TMP1
int 21h;
call zera_opcao;
mov segn,0;
mov cent,50;
jmp sequencia;

um:
call posiciona_tempo;
mov ah,09h;
mov dx, OFFSET TMP2
int 21h;
call zera_opcao;
mov segn,1
mov cent,0;
jmp sequencia;

um_meio:
call posiciona_tempo;
mov ah,09h;
mov dx, OFFSET TMP3
int 21h;
call zera_opcao;
mov segn,1;
mov cent,50;
jmp sequencia;

dois:
call posiciona_tempo;
mov ah,09h;
mov dx, OFFSET TMP4
int 21h;
call zera_opcao;
mov segn,2;
mov cent,0;

sequencia:
call posiciona_coluna;
call printa_coluna
call posiciona_cursor;
out dx, ax
call delay;
call desliga_led;
call move_led;
jne sequencia;
call para_led;
je fim_ciclo
mov ah,0ch;
int 21h;
call zera_ciclo;
jmp sequencia;

fim_ciclo:
jmp start;

CODIGO ENDS; Fim do programa
END INICIO; Fim da rotina inicio



  






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts