; Redefinir teclas y ver el estado de las teclas elegidas "en el juego". ORG 33500 CALL CLS CALL Redefinir_Teclas CALL CLS CALL Wait_For_No_Key ; Esperar a que no haya teclas pulsadas ; Bucle del programa, lee nuestras teclas e imprime primero la ; "leyenda" de las teclas y luego el byte de estado de teclado: bucle: LD DE, 0 CALL CursorAt ; Nos vamos a (0,0) LD DE, msg_keys CALL PrintString ; Imprimimos mensaje "*<>^v" CALL Leer_Teclado_Empaquetado CALL PrintBin ; Imprimimos estado teclas (A) en binario JR bucle ; Repetir hasta reset ; Mensajes del programa msg_izq DEFB "Izquierda? ", _EOS msg_der DEFB "Derecha? ", _EOS msg_arriba DEFB "Arriba? ", _EOS msg_abajo DEFB "Abajo? ", _EOS msg_disp DEFB "Disparo? ", _EOS msg_keys DEFB " *<>^v", _CR, _EOS ; Teclas por defecto si no se redefine: O P Q A SPACE tecla_izq DEFB $1A tecla_der DEFB $22 tecla_arriba DEFB $25 tecla_abajo DEFB $26 tecla_disp DEFB $20 ;----------------------------------------------------------------------- ; Utiliza Find_Key para obtener una tecla válida. Se queda en un bucle ; de espera hasta que una sola tecla esté pulsada, y la devuelve en A. ; Además, imprime por pantalla el codigo ASCII de la tecla. ; ; ENTRADA: Nada ; SALIDA: A = scancode ; MODIFICA: Flags ;----------------------------------------------------------------------- Redefinir_Teclas: ; Los siguientes textos se podrian haber impreso tambien usando un bucle ; con INC DE (avanzar cadena) e INC HL (avanzar tecla a escribir) LD DE, msg_izq CALL PrintString ; Imprimir mensaje "Izquierda?" CALL Redefine_Key ; Esperar pulsacion (e imprimir ASCII) LD HL, tecla_izq ; Apuntamos HL a la variable tecla_izq LD (HL), A LD DE, msg_der ; Siguiente mensaje: "Derecha?" CALL PrintString CALL Redefine_Key ; Esperar pulsacion (e imprimir ASCII) LD HL, tecla_der LD (HL), A ; Guardamos tecla pulsada LD DE, msg_arriba ; Repetimos con ARRIBA CALL PrintString CALL Redefine_Key LD HL, tecla_arriba LD (HL), A LD DE, msg_abajo ; Repetimos con ABAJO CALL PrintString CALL Redefine_Key LD HL, tecla_abajo LD (HL), A LD DE, msg_disp ; Repetimos con DISPARO CALL PrintString CALL Redefine_Key LD HL, tecla_disp LD (HL), A RET ;----------------------------------------------------------------------- ; Utiliza Find_Key para obtener una tecla válida. Se queda en un bucle ; de espera hasta que una sola tecla esté pulsada, y la devuelve en A. ; Además, imprime por pantalla el codigo ASCII de la tecla. ; ; ENTRADA: Nada ; SALIDA: A = scancode ; MODIFICA: Flags ;----------------------------------------------------------------------- Redefine_Key: PUSH DE PUSH HL CALL Wait_For_No_Key wait_for_scan_loop: CALL Find_Key JR NZ, wait_for_scan_loop ; Mas de una tecla leida, repetir LD A, D CP $FF ; si A es $FF => ninguna tecla pulsada JR Z, wait_for_scan_loop ; Repetimos hasta que A != $FF LD H, D ; Nos hacemos copia de D en H CALL Scancode2Ascii ; Convertir D (scancode) en A (ASCII) CP 'e' ; ¿Es 'e'? Imprimir "ENTER" JR NZ, redef_key_NO_ENTER LD DE, redef_key_enter CALL PrintString JR redef_key_end ; Impreso texto, salimos redef_key_NO_ENTER: CP 's' ; ¿Es 's'? Imprimir "SPACE" JR NZ, redef_key_NO_SPACE LD DE, redef_key_space CALL PrintString JR redef_key_end redef_key_NO_SPACE: CP 'c' ; ¿Es 'c'? Imprimir "CS" JR NZ, redef_key_NO_CAPSSHIFT LD DE, redef_key_cs CALL PrintString JR redef_key_end redef_key_NO_CAPSSHIFT: CP 'y' ; ¿Es 'y'? Imprimir "SS" JR NZ, redef_key_NO_SYMBOLSHIFT LD DE, redef_key_ss CALL PrintString JR redef_key_end redef_key_NO_SYMBOLSHIFT: ; Si llegamos aqui no era tecla especial. RST 16 ; Ninguna tecla especial => Print ASCII LD A, D redef_key_end: LD A, H ; Recuperamos scancode CALL PrintCR ; Imprimir retorno de carro POP HL POP DE RET ; Volver con registros preservados redef_key_enter DB "ENTER", _EOS redef_key_space DB "SPACE", _EOS redef_key_ss DB "SS", _EOS redef_key_cs DB "CS", _EOS ;----------------------------------------------------------------------- ; Lee el estado de las teclas definidas en variables y almacena en A ; dicho estado (1=pulsada, 0=no pulsada). El byte está codificado así: ; ; ENTRADA: NADA (usa las variables tecla_*) ; Se podria modificar para recibir HL = direccion 1a tecla ; MODIFICA: A, HL y CarryFlag ; ; BITS 4 3 2 1 0 ; SIGNIFICADO FIRE LEFT RIGHT UP DOWN ;----------------------------------------------------------------------- Leer_Teclado_Empaquetado: PUSH DE LD D, 0 ; D = 0 LD HL, tecla_izq ; Apuntamos HL a la primera de las teclas (izq) LD A, (HL) ; leemos su valor CALL Check_Key JR C, tecl_izq_notpressed SET 3, D ; Si pulsada, ponemos bit 3 a 1. ; Usando A podríamos usar "OR %00001000" tecl_izq_notpressed: INC HL ; INC HL a siguiente tecla en memoria (der) LD A, (HL) ; leemos su valor CALL Check_Key JR C, tecl_der_notpressed SET 2, D ; Si pulsada, ponemos bit 2 a 1. tecl_der_notpressed: INC HL ; apuntamos HL a siguiente tecla (arriba) LD A, (HL) ; leemos su valor CALL Check_Key JR C, tecl_arr_notpressed SET 1, D ; Si pulsada, ponemos bit 1 a 1. tecl_arr_notpressed: INC HL ; apuntamos HL a siguiente tecla (abajo) LD A, (HL) ; leemos su valor CALL Check_Key JR C, tecl_aba_notpressed SET 0, D ; Si pulsada, ponemos bit 0 a 1. tecl_aba_notpressed: INC HL ; apuntamos HL a siguiente tecla (disparo) LD A, (HL) ; leemos su valorprimera CALL Check_Key JR C, tecl_fire_notpressed SET 4, D ; Si pulsada, ponemos bit 4 a 1. tecl_fire_notpressed: ; Podriamos añadir codigo para disparo 2 LD A, D POP DE RET ; Devolvemos en A el estado de las teclas ;----------------------------------------------------------------------- ; Chequea el teclado para detectar la pulsación de una tecla. ; Modifica A, H, DE y BC. ; Devuelve un código en el registro D que indica: ; ; Bits 0, 1 y 2 de "D": Semifila de teclas (puerto) detectada. ; Bits 3, 4 y 5 de "D": Tecla (posición) en esa semifila ; => (00TTTSSS) ; ; Así, el valor devuelto nos indica la semifila a leer y el bit a testear. ; ; El registro D valdrá 255 ($FF) si no hay ninguna tecla pulsada. ; ; Flags: ZF 0: Más de una tecla pulsada ; ZF 1: Tecla correctamente leída ;----------------------------------------------------------------------- Find_Key: LD DE, $FF2F ; Valor inicial "ninguna tecla" LD BC, $FEFE ; Puerto NXHALF: IN A, (C) CPL AND $1F JR Z, NPRESS ; Saltar si ninguna tecla pulsada INC D ; Comprobamos si hay más de 1 tecla pulsada RET NZ ; Si es así volver con Z a 0 LD H, A ; Cálculo del valor de la tecla LD A, E KLOOP: SUB 8 SRL H JR NC, KLOOP RET NZ ; Comprobar si más de una tecla pulsada LD D, A ; Guardar valor de tecla en D NPRESS: ; Comprobar el resto de semifilas DEC E RLC B JR C, NXHALF ; Repetimos escaneo para otra semifila CP A ; Ponemos flag a zero RET Z ; Volvemos ;----------------------------------------------------------------------- ; Chequea el estado de una tecla concreta, aquella de scancode ; codificado en A (como parametro de entrada). ; ; Entrada: A = scancode (00SSSTTT). ; Devuelve: CARRY FLAG = 0 -> Tecla pulsada ; CARRY FLAG = 1 y BC = 0 -> Tecla no pulsada ;----------------------------------------------------------------------- Check_Key: PUSH BC LD C, A ; Copia de A AND 7 INC A LD B, A ; B = 16 - (num. linea direccion) SRL C SRL C SRL C LD A, 5 SUB C LD C, A ; C = (semifila + 1) LD A, $FE CKHiFind: ; Calcular el octeto de mayor peso del puerto RRCA DJNZ CKHiFind IN A, ($FE) ; Leemos la semifila CKNXKey: RRA DEC C JR NZ, CKNXKey ; Ponemos el bit de tecla en el CF POP BC RET ;----------------------------------------------------------------------- ; Scancode2Ascii: convierte un scancode en un valor ASCII ; IN: D = scancode de la tecla a analizar ; OUT: A = Codigo ASCII de la tecla (0-9 y A-Z) ; minusculas: e = ENTER, s = SPACE, c = CAPSSHIFT e = SYMBOLSHIFT ;----------------------------------------------------------------------- Scancode2Ascii: PUSH HL PUSH BC LD HL, 0 LD BC, TABLA_Scancode2ASCII ADD HL, BC ; HL apunta al inicio de la tabla ; buscamos en la tabla un max de 40 veces por el codigo ; le sumamos 40 a HL, leemos el valor de (HL) y ret A SC2Ascii_1: LD A, (HL) ; leemos un byte de la tabla CP "1" ; Si es "1" fin de la rutina (porque en ; (la tabla habriamos llegado a los ASCIIs) JR Z, SC2Ascii_Exit ; (y es condicion de forzado de salida) INC HL ; incrementamos puntero de HL CP D ; comparamos si A==D (nuestro scancode) JR NZ, SC2Ascii_1 SC2Ascii_Found: LD BC, 39 ; Sumamos 39(+INC HL=40) para ir a la ADD HL, BC ; seccion de la tabla con el codigo ASCII LD A, (HL) ; leemos el codigo ASCII de esa tabla SC2Ascii_Exit: POP BC POP HL RET ; 40 scancodes seguidos de sus ASCIIs equivalentes TABLA_Scancode2ASCII: DEFB $24, $1C, $14, $0C, $04, $03, $0B, $13, $1B, $23 DEFB $25, $1D, $15, $0D, $05, $02, $0A, $12, $1A, $22 DEFB $26, $1E, $16, $0E, $06, $01, $09, $11, $19, $21 DEFB $27, $1F, $17, $0F, $07, $00, $08, $10, $18, $20 DEFB "1234567890QWERTYUIOPASDFGHJKLecZXCVBNMys" ;-- Incluir libreria de utilidades -- INCLUDE "utils.asm" END 33500