Último mensaje de la página anterior:
Este es el código, pero como hay una parte con caracteres que solo se ven bien en los Atari, lo vuelvo a adjuntar comprimido, no sea que haya problemas con el copia y pega.El funcionamiento es, detallado:
- al principio, salta a la etiqueta start, donde se hacen las operaciones de inicialización e instalación:
- guardar el valor anterior del byte en $484 (conterm)
- si existe la jarra de galletas, miramos a ver si ya estábamos instalados de una ejecución anterior. Si es así, salimos.
- si no estábamos de antes, ponemos una galleta ACT2
- luego miramos el número de versión de la ROM. Si es menor que 1.2, salimos
- si es una TOS 1.2 o superior, saltamos a la subrutina conversion
- en ella, lo primero que hacemos es preguntarle al TOS dónde están las (3) tablas de conversión scan -> ascii
- luego viene un bucle en que se recorre la información de la tabla (de conversión de caracteres). El proceso que se sigue es:
- se lee el primer byte, que representa el carácter que hará de "muerta"; y lo buscamos por la tabla de conversión (es decir: estamos buscando qué tecla física es la que tiene dibujado ese carácter). Primero lo buscamos en la tabla unshift (teclado en posición normal) y si no lo encuentra, en la tabla shift (teclado con al menos un shift pulsado) (ahora no recuerdo por qué solo busco por los primeros 60 caracteres de cada tabla)
- si hemos sido capaces de encontrar la tecla, guardamos ese código de scan en la propia tabla de conversión, en lugar del primer byte leído antes (para reutilizar espacio, claro)
- en el caso extremo de que no encontremos esa tecla, cabe un último recurso: usar la tecla * como tecla "muerta"
- todo esto se hace para que el programa de acentos sea completamente independiente del idioma/disposición del teclado
- una vez terminada la conversión de teclas a códigos scan, preguntamos al TOS dónde está el búfer del teclado, dirección donde se almacena el estado de las teclas shift y la base de los vectores de rutinas del sistema, para instalar nuestra propia rutina "acentos" delante de la que se ejecuta cuando se pulsa una tecla
- finalmente, salimos del programa, informando al SO que deje residente (en memoria) nuestro programa (mejor dicho: el programa está preparado para dejar residente solo la parte que se necesita)
- la rutina "acentos" residente hace lo siguiente:
- primero vemos la posición de la cola del búfer del teclado
- luego ejecutamos la rutina original del sistema operativo
- al regresar, comprobamos si el búfer ha cambiado o no
- si hubo un cambio, y el programa de acentos está activado, vamos al búfer del teclado y vemos qué se ha pulsado
- si no hubo cambios, podría ser debido a que el usuario pulso las teclas shift, así que comprobamos si está pulsada la combinación Alternate+Shift+Shift, y en ese caso des/activamos el programa
- si fue la tecla Alternate, salimos de la rutina, pero recordando qué tecla se ha pulsado
- si es una tecla normal, leemos su código de scan. Si además está pulsada una tecla shift, le sumamos 0x80
- recorremos la tabla de conversión, buscando por el carácter que se pulso antes que la tecla actual
- si no lo encontramos, salimos y, otra vez, guardamos esa tecla para después. Todo esto es para detectar la pulsación de las teclas "muertas"
- si encontramos el scan, es que era una tecla muerta. Ahora tenemos que buscar si el carácter actualmente pulsado está en la lista de conversión
- si encontramos una coincidencia, sacamos de la tabla el siguiente carácter
- ahora viene lo curioso: ponemos un Backspace en el búfer del teclado, y a continuación, el nuevo carácter. Esto hace que se emitan esos dos caracteres a la aplicación en la que está el usuario. Esto tiene el efecto visual de borrar el carácter de la tecla muerta y presentar el nuevo carácter (creo que era así, hablo de memoria)
- finalmente, desactivamos (por si acaso) el modo repetición (es el que ocurre cuando dejamos una tecla pulsada un cierto tiempo)
Como se puede ver, hay algunas cosas que se pueden sacar si solo vamos a manejar un teclado español. La rutina de conversión no es necesaria, porque solo vamos a tener una disposición del teclado (salvo que el usuario SÍ quiera una disposición del teclado distinta).
Y... ahora que veo el código, con 23 años de diferencia... creo que podría dejarlo un poco más óptimo y claro. Al menos, más decente
Código: Seleccionar todo
*
* Acentos. v1.2
* Joaqu¡n Ferrero.
*
* Versi¢n Fecha
* v1.0 Agosto 1993
* v1.1 Octubre 1993. Ver si funciona en Tos 1.4. NO VA EN STE!!!
* v1.2 Junio 1994. Quitar shifts para aumentar compatibilidad.
*
* Queda residente, colocando una galleta ACT2
*
opt o3+
opt ow3+
opt o4+
opt o5+
opt o6+
opt e-
opt a+
COMMENT HEAD=7 Todos los atributos
output accent.prg
COOKIE EQU ACT2
include "d:devpacatari_st.s"
start1 bra start
acentos movem.l d5-d7/a5,-(sp)
movea.l buffer_key,a5 Buffer del teclado
MOVE 8(A5),d6 Posici¢n de cola anterior
movea.l anterior_key,A0 Ejecutar anterior rutina
movem.l d6/a5,-(sp) v1.1
JSR (A0)
movem.l (sp)+,d6/a5 v1.1
MOVEA.L kshift,A0 kstate
MOVE.B (A0),D0
move 8(a5),d7 posicion
cmp d6,d7 šHubo entrada?
beq ver_cambio No
TST activado šEstamos activados?
BEQ no_key No, acabar
MOVEA.L (A5),A0 buffer de teclas
MOVE.L 0(A0,d7),D6 Leer entrada
BTST #3,D0 šSe puls¢ alternate?
BEQ.S no_alt
MOVE.L D6,D5 Extraer c¢digo scan
SWAP D5
CMPI.B #$78,D5 L¡mite superior de comparaci¢n
BCS.S .ac_1
SUBI.B #$76,D5
.ac_1 MOVE.B D0,D1 kstate
ANDI.B #3,D1 šSe puls¢ shift?
BEQ.S no_shft
ORI.B #$80,D5 scan |= 0x80
no_shft lea tabla(pc),A1 Tabla
move ant_key,d1 Car cter a buscar
while move.b (a1)+,d0
BEQ.S no_alt šFin de tabla?
CMP.B D5,d0 šEs el car cter que buscamos?
BEQ.S si_char
.lp tst.b (a1)+ buscar fin de cadena
BNE.S .lp
BRA.S while seguir con otra cadena
si_no ADDQ.W #1,A1
si_char move.b (a1)+,d0 Car cter entrado posiblemente
BEQ.S no_alt no encontrado, acabar
CMP.B d1,D0 šEs el mismo que el entrado?
BNE.S si_no no, seguir buscando
MOVE.B (A1),D6 Nuevo car cter
BCLR #$1B,D6 Quitar alternate
BCLR #$18,D6 Quitar shifts (v1.2)
BCLR #$19,D6
move.l #$E0008,0(a0,d7) Poner Backspace
ADDQ.W #4,D7 Siguiente posici¢n
CMP.W 4(A5),D7 šLlegamos al final?
BLT.S no_lim
MOVEQ #0,D7 Empezar buffer de nuevo
no_lim cmp 6(A5),d7 šLlegamos a la cabeza?
BEQ.S no_alt
MOVE.W D7,8(A5) Nueva cola
MOVE.L D6,0(A0,D7) Nueva entrada
MOVE.B $484.w,ant_484 Salvar estado del 484
BCLR #1,$484.w Quitar modo repetici¢n
no_alt MOVE D6,ant_key Guardar c¢digo ascii
no_key movem.l (sp)+,d5-d7/a5
rts
ver_cambio:
MOVE.B ant_484,D1 Recuperar estado de repetici¢n
ANDI.B #2,D1
OR.B D1,$484.w
CMP.B #$B,D0 Se puls¢ Alt+shift+shift
BNE.S no_key
not activado
bra.s no_key
tabla
dc.b ",C?c?",0
dc.b ".Aa?.úøù",0
dc.b "^a?e?i?o?u?",0
dc.b "`A¶a?e?io?u?",0
dc.b "_+ñ<ó=ð>òaŠo§",0
dc.b " ºEa e?i¡o¢u£",0
dc.b "~A·N¥Oža°n€o±=÷iß",0
dc.b "/O²PŒc?o³3á2«4¬Sì",0
dc.b "-:öL?Y<©>ªA?Oµa?oŽ",0
dc.b ": ¹A?O?U?a?e?i?o?uy?",0
dc.b 8,"!?š<®>¯{ô}õiÀIÁcœC»RûrŸT¿nü2ý3þ_ÿ"
dc.b "aàbáGâdëDzékÂlÄmæxèXîpãPïsåSätçfíF?oêA¶",0
dc.b "* ",0,0
even
ant_484 DC.B 0
ant_key dc.w 0
activado:
DC.W -1 Inicialmente activado
even
kshift DC.L 0
buffer_key:
DC.L 0
anterior_key
DC.L 0
DC.B "____"
DC.B "JF94"
DC.B "2006"
DC.L -1
DC.L 0
fin_acentos:
start move.l 4(sp),a5 Basepage
LEA $100-32(A5),A7 Poner pila al fin l de comandos
Super
MOVEA.L $4F2.W,A6 Inicio del S.O.
MOVE.B $484.W,ant_484 Iniciar valores
moveq #0,d7 Flag de instalaci¢n
move.l _p_cookies.w,d0 Jarra de galletas
beq.s no_jar
movea.l d0,a0
.loop_g movem.l (a0)+,d0-d1 Leer galletas
tst.l d0
beq.s poner Se encontr¢ el final, poner nueva
cmp.l #COOKIE,d0 šEst ya puesto?
bne.s .loop_g No, seguir buscando
bra.s ya_pues
poner subq.l #8,a0 Volver atr s un momento
move.l #COOKIE,(a0)+ Identificador
move.l a5,(a0)+ Poner basepage
movem.l d0-d1,(a0) Recuperar anterior galleta
no_jar moveq #1,d7 S¡ se instal¢
ya_pues User
tst d7 šSe instal¢?
beq.s acabar No
MOVEA.L 8(A6),A6 Verdadero inicio del s.o.
CMPI.W #$102,2(A6) Testear n£mero de versi¢n
BCC.S si_tos Es igual o mayor
acabar Cconws_p txt_no_instal(pc)
Pterm0 Salir inmediatamente
si_tos bsr.s conversion Conversi¢n de las tablas
MOVE.L $24(A6),kshift Direcci¢n de shifts state
Iorec #1 Hallar buffer del teclado
MOVE.L D0,buffer_key
Kbdvbase Base de vectores rutinas del sistema
MOVEA.L D0,A5
MOVE.L $20(A5),anterior_key Anterior rutina del sistema
.lp TAS $24(A5) Esperar fin de transmisi¢n
BNE.S .lp
LEA acentos(PC),A0 Instalar rutina propia
MOVE.L A0,$20(A5)
clr.b $24(a5)
Cconws_p txt_si_instal(pc) S¡ se instal¢
Ptermres #fin_acentos+$100-acentos,#0 Quedar residente
conversion:
MOVEQ #-1,D0
Keytbl d0,d0,d0 Hallar tablas de conversi¢n scan->ascii
lea tabla(pc),A2 Inicio de tabla
MOVEA.L D0,A0 Inicio de apuntadores
MOVE.B (A2),D2 Primer car cter a convertir
loop_c MOVEA.L (A0),A1 Apuntador a tabla unshift
CLR.W D3 Contador
BSR.S Buscar
BPL.S si_conv
MOVE.W #$80,D3 Probar con la tabla shift
MOVEA.L 4(A0),A1
BSR.S Buscar
BPL.S si_conv
BSR.S Arreglo No, hacer chapuza con el car cter *
MOVE.B #$FF,D3 Desconectar esa cadena
si_conv MOVE.B D3,(A2) El nuevo car cter (scan)
.loop1 TST.B (A2)+ Buscar final de cadena
BNE.S .loop1
MOVE.B (A2),D2 Siguiente car cter
BNE.S loop_c
RTS
Buscar MOVEQ #$3C,D1 N£mero m ximo de intentos de b£squeda
.lp_b ADDQ.W #1,D3
CMP.B (A1)+,D2
DBEQ D1,.lp_b
SUBQ.W #1,D3
TST.W D1
RTS
Arreglo MOVE.L A2,-(A7) Copiar cadena a cadena *
lea tabla(pc),A1 Inicio de tabla
.lp_a CMPI.B #*,(A1)+ Buscar *
BNE.S .lp_a
ADDQ.L #1,A2
.lp_a1 MOVE.B (A2)+,(A1)+ Copiar el resto de la cadena
BNE.S .lp_a1
CLR.B (A1) Poner segundo 0, indicador final tabla
MOVEA.L (A7)+,A2
RTS
data
txt_no_instal:
dc.b CR,LF,"Acentos v1.2 no instalado",CR,LF,0
txt_si_instal:
dc.b CR,LF,"Acentos v1.2 instalado."
dc.b CR,LF,"Joaqu¡n Ferrero. Junio 1994",CR,LF,0
end