Você está na página 1de 3

CCE MC1000

Navegao
Pgina inicial
BASIC

Sistema >

Leitura de teclado

Cdigos de erro
Nmeros de ponto
flutuante
USR
Emuladores
Hardware
Clone

O BASIC do MC1000 no tinha a funo INKEY$, existente em outros microcomputadores, que verifica se h alguma tecla pressionada no momento e retorna o caracter correspondente, ou uma cadeia vazia ("") se no houver nenhuma tecla pressionada. Essa funo imprescindvel para jogos de ao.
Mas mesmo que tivesse, o MC1000 tem uma caracterstica que um grande obstculo programao de jogos de ao em BASIC: o interpretador BASIC fica paralisado enquanto alguma tecla estiver pressionada! :-O
De todo modo, existe uma varivel do sistema que armazena o cdigo ASCII da ltima tecla pressionada: o endereo 283 (KEY0).
No a mesma coisa que um INKEY$, j que, por exemplo, no se pode saber se a pessoa apertou a mesma tecla mais de uma vez... mas pelo menos melhor que a instruo INPUT! -)

Mods
Perifricos

Programinha-brinde: Move um caracter "#" pela tela usando as teclas <W> (cima), <S> (baixo), <A> (esquerda) e <D> (direita).

Porta de expanso
Projetos
Histria
Personalidades
Questionrio
Links
Manual do BASIC
Outras linguagens
C (SDCC)

10 HOME
20 C = 15:L = 7
30 T$ = CHR$ (PEEK (283))
40 CC = (C + ABS (T$ = "D") - ABS (T$ = "A"))
50 LL = (L + ABS (T$ = "S") - ABS (T$ = "W"))
60 PRINT CHR$ (27);"="; CHR$ (L); CHR$ (C +
70 PRINT CHR$ (27);"="; CHR$ (LL); CHR$ (CC
80 POKE 910,0
90 C = CC : L = LL
100 GOTO 30

AND 31
AND 15
32);" ";
+ 32);"#"; CHR$ (8);

Sistema
Bugs
Caracteres de
controle

Soluo para permitir que a execuo do BASIC continue mesmo com uma tecla pressionada

Cassete

(Desenvolvida por Ensjo em 19 de outubro de 2011.)

Infraestrutura para
jogos
Leitura de
teclado
Portas
Posicionamento do
cursor

O MC1000 tem trs rotinas na ROM relacionadas com a leitura do teclado: SKEY?,KEY? e KEY.
SKEY? verifica se alguma tecla est sendo pressionada no momento.
KEY? chama SKEY? para checar se uma mesma tecla est sendo pressionada durante 7ms.
KEY chama KEY? e, se uma tecla for pressionada, espera at que ela seja liberada.
A causa do MC1000 travar quando uma tecla pressionada um CALL KEY no endereo $DDDC, em meio interpretao do programa BASIC:

Teclado
Variveis do
sistema
Software
Proteo contra
acesso ao
cdigo-fonte
Trivialidades
Vdeo
Conjunto de
caracteres

...
DD5A
DD5D
DD5E
DD61
...
DDDC
DDDF
DDE1
...

call KEY?
or a
call nz, $dddc
...

; Alguma tecla pressionada?

call KEY
cp $13
jp nz, $de0b

; Captura a tecla e espera ser liberada.


; CTRL+S?
; (etc.)

; Sim: capturar e tratar.

A ideia dar um jeito de impedir que essa chamada seja feita.

Cores
Modos de vdeo
Sitemap
Atividade recente
no site

A rotina KEY? chama a rotina SKEY?, que por sua vez chama dois hooksem RAM:
O primeiro hook (JOB, no endereo $0120) est livre. Ele tem apenas uma instruo RET ($C9) do Z80.
O segundo hook (JOBM, no endereo $0130) por padro est associado rotina de piscamento do cursor.

Proprietrios do
site

Vamos ento usar o hook JOB. Quando ele atingido a partir da instruo CALL KEY? no endereo $DD5A, a pilha do Z80 contm:

Giovanni Nunes

SP
$85 $C385, endereo para retorno a SKEY? ao final da execuo do hook.
SP+1 $C3
SP+2 ?? Valor de BC salvo com PUSH em SKEY?.
SP+3 ??
SP+4 ?? Valor de DE salvo com PUSH em SKEY?.
SP+5 ??
SP+6 ?? Valor de HL salvo com PUSH em SKEY?.
SP+7 ??
SP+8 $53 $C353, endereo para retorno a KEY? ao final da execuo de SKEY?.
SP+9 $C3
SP+10 ?? Valor de BC salvo com PUSH em KEY?
SP+11 ??
SP+12 ?? Valor de DE salvo com PUSH em KEY?
SP+13 ??
SP+14 $5D $DD5D, endereo para retorno ao interpretador BASIC ao final da execuo de KEY?.
SP+15 $DD

Emerson Jos Silveira da


Costa
0

O que vamos fazer examinar o contedo de SP+14 e SP+15 e ver se temos l o endereo $DD5D. Se for este o caso, sabemos que estamos no ponto "problemtico" da ROM, perto da rotina que vai "congelar" o BASIC at a liberao da tecla pressionada. Ento vamos modificar o contedo de SP+8 e SP+9 para que o controle
no volte para KEY? ao final de SKEY?, mas v para uma rotina prpria que vai decidir o que fazer. Se o usurio no estiver pressionando tecla nenhuma, o controle dever retornar para $DD61. Se o usurio estiver apertando alguma tecla, colocamos seu cdigo no registrador A e chamamos a rotina $DDDF (pulando a
famigerada instruo CALL KEY) antes de retornar o controle para $DD61.
A rotina foi projetada para ser POKEada em uma linha REM, que deve ser a primeira do programa (vide abaixo).

key0:
job:
resto:
teclap:

equ
equ
equ
equ

$011b
$0120
$dd61
$dddf

org $03da
init:
; Direciona o hook JOB (chamado em SKEY?) para a rotina "checa".
ld hl,checa

ld (job+1),hl
ld a,$c3
ld (job),a
ret
checa:
; Verifica se estamos em meio ao CALL KEY? feito em #DD5A.
push ix
ld ix,$ffff ; Estas duas linhas substituem ld ix,$0000.
inc ix
; No pode haver byte $00 na linha REM.
add ix,sp
ld a,$5d
cp (ix+16)
jr nz,sai
ld a,$dd
cp (ix+17)
jr nz,sai
; Sim: Modifica a pilha do Z80 para que, ao final da
; rotina SKEY?, o controle no volte para KEY?, mas
; para nossa rotina personalizada "desvia".
push hl
ld hl,desvia
ld (ix+10),l
ld (ix+11),h
pop hl
sai:
pop ix
ret
desvia:
; Restaura pilha e registradores como estariam
; ao final da execuo de KEY?, e desvia
; para os pontos apropriados do interpretador
; BASIC, evitando o CALL KEY em #DDDC.
pop bc ; Desempilha valores empilhados por KEY?
pop de
inc sp ; Descarta o ponto de retorno original.
inc sp
ld (key0+2),a ; FUNCIONALIDADE ADICIONAL:
; Salva em KEY0 + 2 a informao sobre se
; uma tecla foi pressionada (#FF) ou no (#00).
or a
ld a,(key0)
; Copia cdigo da tecla em KEY0 + 1.
ld (key0+1),a ; ( algo que a rotina KEY? faz.)
call nz,teclap ;
;
;
jp resto
;

Se tecla pressionada, chama rotina


de tratamento situada logo depois a problemtica
instruo CALL KEY.
Retorna para o interpretador BASIC.

Eis abaixo o incio de um programa em BASIC. As linhas de 1 a 6 "instalam" o programa acima em uma linha REM, que deve ser a primeira do programa e ter 70 caracteres. A linha 7 ativa o programa.

0
1
2
3
4
5
6
7

REM --------10--------20--------30--------40--------50--------60--------70
DATA 33,230,3,34,33,1
DATA 62,195,50,32,1,201,221,229,221,33,255,255,221,35,221,57
DATA 62,93,221,190,16,32,18,62,221,221,190,17,32,11,229,33
DATA 12,4,221,117,10,221,116,11,225,221,225,201,193,209,51,51
DATA 50,29,1,183,58,27,1,50,28,1,196,223,221,195,97,221
FOR I = 0 TO 69: READ B: POKE 986 + I,B: NEXT I
CALL 986

As linhas de 1 a 6 podem at ser apagadas depois da primeira execuo, pois ento o programa em cdigo de mquina j estar instalado na linha REM.
Pode-se tambm apenas digitar a linha 0 com 70 caracteres e a instruo CALL 986, e adicionar o programa em cdigo de mquina manualmente via DEBUG:

03DA
03E0
03F0
0400
0410

21
3E
3E
0C
32

E6
C3
5D
04
1D

03
32
DD
DD
01

22
20
BE
75
B7

21
01
10
0A
3A

01
C9
20
DD
1B

DD
12
74
01

E5
3E
0B
32

DD
DD
E1
1C

21
DD
DD
01

FF
BE
E1
C4

FF
11
C9
DF

DD
20
C1
DD

23
0B
D1
C3

DD
E5
33
61

39
21
33
DD

Uma funcionalidade adicional desta rotina salvar na posio de memria KEY0+2 ($011D / 285) a indicao sobre se uma tecla est sendo pressionada ou no. Se no estiver, PEEK(285) retorna 0; se estiver, retorna 255.
Agora a funo INKEY$ dos outros micros pode ser implementada assim:

I$ = "": IF PEEK (285) THEN I$ =

CHR$ ( PEEK (283))

Vamos reescrever o programa no incio desta pgina. Digita as linhas 0 a 7 e acrescenta:

...
10 HOME
20 C = 15:L = 7
30 T$ = "": IF PEEK (285) THEN T$ = CHR$ ( PEEK (283))
40 CC = (C + ABS (T$ = "D") - ABS (T$ = "A")) AND 31
50 LL = (L + ABS (T$ = "S") - ABS (T$ = "W")) AND 15
60 PRINT CHR$ (27);"="; CHR$ (L); CHR$ (C + 32);" ";
70 PRINT CHR$ (27);"="; CHR$ (LL); CHR$ (CC + 32);"#"; CHR$ (8);
80 POKE 910,0
90 C = CC : L = LL
100 GOTO 30

Executa ambos os programas e sente a diferena.


(Nova verso desenvolvida em 2 de julho de 2015.)
Esta uma verso da rotina para se localizar na parte alta da VRAM, na rea de 256 bytes que o MC1000 reserva para o usurio no final da RAM.

key0:
keysw:
resto:
teclap:

equ
equ
equ
equ

$011b
$012e
$dd61
$dddf

; Para ativar: Configurar hook JOB ($0120) com um jump para "checa".
.org $3f00
checa:
; Verifica se estamos em meio ao CALL KEY? feito em #DD5A.
ld hl,+14
add hl,sp
ld a,(hl)
cp $5d
ret nz
inc hl
ld a,(hl)
cp $dd
ret nz
; Sim: Modifica a pilha do Z80 para que, ao final da
; rotina SKEY?, o controle no volte para KEY?, mas
; para nossa rotina personalizada "desvia".
ld hl,+8
add hl,sp
ld de,desvia
ld (hl),e
inc hl
ld (hl),d
ret
desvia:
; Restaura pilha e registradores como estariam
; ao final da execuo de KEY?, e desvia
; para os pontos apropriados do interpretador
; BASIC, evitando o CALL KEY em #DDDC.
pop bc ; Desempilha valores empilhados por KEY?
pop de
inc sp ; Descarta o ponto de retorno original.
inc sp
ld (key0+2),a ; FUNCIONALIDADE ADICIONAL:
; Registra em KEY0+2 a informao sobre se
; uma tecla foi pressionada (#FF) ou no (#00).
or a
ld a,(key0)
; Copia cdigo da tecla em KEY0 + 1.
ld (key0+1),a ; ( algo que a rotina KEY? faz.)
call nz,teclap ;
;
;
jp resto
;

Se tecla pressionada, chama rotina


de tratamento situada logo depois a problemtica
instruo CALL KEY.
Retorna para o interpretador BASIC.

Eis um programa BASIC que insere a rotina na memria e o ativa:

1
2

RESTORE 2:A0 = PEEK (914) + 256 * PEEK (915) + 1:A1 = A0 + 18:A2 = A0 + 24: POKE 288,201: FOR A = A0 TO A0 + 43: READ B: POKE A,B: NEXT : POKE A1,A2 AND 255: POKE A1 + 1,A2 / 256: POKE 289,A0 AND 255: POKE 290,A0 / 256: POKE 288,195
DATA 33,14,,57,126,254,93,192,35,126,254,221,192,33,8,,57,17,24,63,115,35,114,201,193,209,51,51,50,29,1,183,58,27,1,50,28,1,196,223,221,195,97,221

A varivel A0 calcula o incio da rea do usurio no topo da RAM, que varia conforme a memria do micro (por padro, $3F00 / 16128 nas mquinas com 16KiB, e $BF00 / 48896 nas mquinas com 64KiB) e tambm pode ser redefinido pela instruo CLEAR.
Alternativamente, pode-se inserir a rotina em uma primeira linha REM do programa BASIC com 44 caracteres, substituindo o clculo de A0 por A0 =

0
1
2

PEEK (841) + 256 *

PEEK (842) + 5:

REM --------10--------20--------30--------40--44
RESTORE 2:A0 = PEEK (841) + 256 * PEEK (842) + 5:A1 = A0 + 18:A2 = A0 + 24: POKE 288,201: FOR A = A0 TO A0 + 43: READ B: POKE A,B: NEXT : POKE A1,A2 AND 255: POKE A1 + 1,A2 / 256: POKE 289,A0 AND 255: POKE 290,A0 / 256: POKE 288,195
DATA 33,14,,57,126,254,93,192,35,126,254,221,192,33,8,,57,17,24,63,115,35,114,201,193,209,51,51,50,29,1,183,58,27,1,50,28,1,196,223,221,195,97,221

Fazer login | Atividade recente no site | Denunciar abuso | Imprimir pgina | Tecnologia Google Sites