Capítulo 7 - Saltando y dando vueltas

Ahora vamos a divertirnos un poco con el lenguaje ensamblador de Atari. En este capítulo, aprenderá a imprimir mensajes en la pantalla, codificar y decodificar caracteres ATASCII (El código ASCII de Atari), y cómo realizar otros trucos en lenguaje ensamblador. Vamos a realizar estas hazañas usando técnicas avanzadas de programación en lenguaje ensamblador que no hemos tratado hasta ahora, junto con nuevas variantes de las técnicas que hemos visto en capítulos anteriores. Estas son algunas de las técnicas de programación que vamos a cubrir en este capítulo.


  • Uso de la directiva. BYTE del lenguaje ensamblador.
  • Incremento y decremento de los registros X e Y.
  • Uso en conjunto de las instrucciones de comparación y salto ("branch").
  • Uso avanzado de ciclos y saltos.
  • Escritura de instrucciones reubicables en lenguaje ensamblador.

Sin embargo, antes de empezar, haré un truco muy astuto. Voy a pedirle que escriba y guarde en un disco un programa que no le he presentado anteriormente. Es probable que no lo entienda, a menos que tenga experiencia previa en programación en lenguaje ensamblador. Le pido que escriba este programa porque contiene un par de rutinas que son necesarias para ejecutar otros dos programas que le presentaré y explicaré más adelante en este capítulo. El programa, que puede que no entienda, será explicado en detalle en el capítulo 12, "E/S y Usted".


Dos buenas razones


En este programa encontrará dos sofisticadas pero muy útiles subrutinas. Una de ellas es una rutina que abre la pantalla como dispositivo de salida y pone su Atari en modo de edición. Ya tendrá ese trabajo hecho la próxima vez que lo encuentre, en el capítulo "E/S y Usted". Así que espero que mire hacia el futuro y vea pastos más verdes en el último capítulo de este libro, y no se enoje demasiado conmigo por pedirle que escriba ahora este programa.


PROGRAMA PARA IMPRIMIR EN LA PANTALLA

10 ;
20 .TITLE "RUTINA PRNTSC"
30 .PAGE "RUTINAS PARA IMPRIMIR EN LA PANTALLA"
40 ;
50              *=$5000
60 ;
70 BUFLEN=23
80 ;
0100 EOL=$9B
0105 ;
0110 OPEN=$03
0120 OWRIT=$0B
0130 PUTCHR=$0B
0135 ;
0140 IOCB2=$20
0170 ICCOM=$342
0180 ICBAL=$344
0190 ICBAH=$345
0200 ICBLL=$348
0210 ICBLH=$349
0220 ICAX1=$34A
0230 ICAX2=$34B
0235 ;
0240 CIOV=$E456
0250 ;
0260 SCRNAM     .BYTE "E:",EOL
0270 ;
0280 OSCR       LDX #IOCB2 ; RUTINA PARA ABRIR LA
0300            LDA #OPEN ; PANTALLA
0310            STA ICCOM,X
0320 ;
0330            LDA #SCRNAM&255
0340            STA ICBAL,X
0350            LDA #SCRNAM/256
0360            STA ICBAH,X
0370            LDA #OWRIT
0380 ;
0390            STA ICAX1,X
0400            LDA #0
0410            STA ICAX2,X
0420            JSR CIOV
0430 ;
0440            LDA #PUTCHR
0450            STA ICCOM,X
0460 ;
0470            LDA #TXTBUF&255
0480            STA ICBAL,X
0490            LDA #TXTBUF/256
0500            STA ICBAH,X
0510            RTS 0520 ;
0530 PRNT
0540            LDX #IOCB2
0550            LDA #BUFLEN&255
0560            STA ICBLL,X
0570            LDA #BUFLEN/256
0580            STA ICBLH,X
0590            JSR CIOV
0600            RTS
0610 ;
0620 TXTBUF=*
0630 ;
0640            *=*+BUFLEN
0650 ;
0660 .END	

¡Ahora guárdelo!
Cuando haya escrito este programa, puede ensamblar su código objeto y guardarlo en un disco usando el nombre PRNTSC.OBJ. A continuación encontrará otro programa que me gustaría que escriba y ensamble. Es el único con el que vamos a trabajar el resto de este capítulo.


THE VISITOR

10 ;
20 ; EL VISITANTE 
30 ;
35 TXTBUF=$5041
40 OPNSCR=$5003
50 PRNTLN=$5031
70 ;
80          *=$600 
90 ;
0100 TEXT   .BYTE $4C,$4C,$45,$56,$41,$4D,$45,$20 
0110        .BYTE $43,$4F,$4E,$50,$20,$54,$55,$20 
0120        .BYTE $4C,$49,$44,$45,$52,$21 
0130 ;
0140 VIZTOR 
0150 ;
0160        LDX #0 
0170 LOOP   LDA TEXT,X 
0180        STA TXTBUF,X 
0190        INX 
0200        CPX #23 
0210        BNE LOOP 
0220        JSR OPNSCR 
0230        JSR PRNTLN 
0240 INFIN  JMP INFIN	

Este programa se llama (por razones que pronto descubrirá) The Visitor (El Visitante). Es un programa que está diseñado para imprimir un mensaje críptico en nuestra pantalla.


Ejecutando "The Visitor"


Cuando haya terminado de escribir The Visitor, puede ejecutarlo de inmediato. Sólo ensámblelo, y luego cargue el código objeto del programa PRNTSC en su computador. Entonces, puede ejecutar The Visitor, ya sea poniendo el computador en modo DEBUG y escribiendo G617, o entrando al modo DOS y ejecutándolo con un comando de DOS.


Cuando haya terminado de escribir el programa, no sería una mala idea guardarlo también en un disco. El nombre de archivo sugerido para el programa es VISITOR.SRC. Luego de que haya ejecutado y guardado su programa, sabrá exactamente lo que éste hace. Así que ahora podremos explicar cómo es que hizo lo que acaba de hacer. Empezaremos con una explicación de la Directiva. BYTE del lenguaje ensamblador, que verá desde la línea 100 a la 120.


https://www.atariware.cl/archivos/atariroots/ar19.jpg

La Directiva. BYTE


A la directiva. BYTE a veces se le llama pseudo código de operación, o pseudo-op, porque aparece en la columna de op-codes del listado de código fuente en lenguaje ensamblador. Pero en realidad no forma parte del conjunto de instrucciones del lenguaje ensamblador del 6502. En cambio, es una directiva especializada diseñada para ser usada en algunos ensambladores, pero no con todos. Por ejemplo,. BYTE funciona con en el ensamblador MAC/65 y con el Atari Assembler Editor, pero no funciona con el Atari Macro Assembler y Atari Program-Text Editor. Al escribir un programa con el Atari Macro Assembler y Atari Program-Text Editor, tiene que usar las letras DB en lugar de la directiva. BYTE. Otros pseudo códigos de operación también son distintos entre ensambladores. No hay estándares generales para la escritura de directivas, por lo que los pseudo códigos de operación diseñados para un ensamblador a menudo no funcionan en otro.


Lo que hace la directiva. BYTE


Cuando se utiliza la directiva. BYTE en un programa creado con el ensamblador MAC/65 o el Atari Assembler Editor, los bytes que vienen a continuación de la directiva son ensamblados en posiciones consecutivas de la memoria RAM. En el programa llamado "The Visitor", los bytes que vienen a continuación de la etiqueta TEXT corresponden al código ATASCII (código ASCII de Atari) de una serie de caracteres de texto.


Dando vueltas en el ciclo


Como explicamos en el capítulo 6, los registros X e Y del chip 6502 pueden ser progresivamente incrementados o disminuídos dentro de los ciclos de un programa. En el programa The Visitor, el registro X es incrementado desde 0 hasta 23 dentro del ciclo en que se leen los caracteres de una cadena de texto. Los caracteres a ser leídos están escritos en código ATASCII en las líneas 100 y 120 del programa. En la línea 160, la orden LDX# 0 se utiliza para cargar un cero en el registro X. A continuación, en la línea 170, comienza el ciclo.


Incrementando el registro X


La primera instrucción dentro del ciclo es LDA TEXT, X. Cada vez que comienza el ciclo, esta instrucción usa el direccionamiento indexado para cargar el acumulador con el código ATASCII de un carácter. Luego, en la línea 180, se usa de nuevo el modo de direccionamiento indexado, esta vez para almacenar el carácter en un buffer de texto. Cuando termina el ciclo, todos los caracteres en el buffer de texto se imprimen en la pantalla. La primera vez que el programa The Visitor llegue a la línea 170, habrá un 0 en el registro X (Ya que se acaba de cargar en la línea anterior un 0 en el registro X). Así que la primera vez que el programa se encuentra con la orden LDA TEXT, X, carga el acumulador con el número hexadecimal $54 – lo que los programadores a veces llaman "el 0-avo byte" a continuación de la etiqueta TEXT. (Por cierto, no hay necesidad de poner un símbolo "#" delante del número $54, ya que los números que vienen a continuación de la directiva. BYTE siempre son interpretados como números literales por el ensamblador MAC/65 y por el Atari Assembler Editor).


Incrementando y decrementando los registros X e Y


Ahora vamos a pasar a la línea 190. El mnemónico que ve ahí – INX – significa "incrementar el registro X". Dado que el registro X contiene actualmente un 0, esta instrucción incrementará ahora ese 0 a 1. A continuación, en la línea 200, vemos la instrucción CPX #23. Esto significa "comparar el valor en el registro X con el número literal 23". La razón por la que queremos hacer esta comparación es para poder determinar si ya se han impreso 23 caracteres en la pantalla. Hay 23 caracteres en la cadena de texto que se está imprimiendo, y cuando se hayan impreso todos, necesitaremos imprimir un retorno de carro y terminar nuestro programa.


Comparación de valores en Lenguaje Ensamblador


Hay tres instrucciones de comparación en el lenguaje ensamblador del 6502: CMP, CPX, y CPY. CMP significa "Comparar con el valor que tiene el acumulador". Cuando se usa la instrucción CMP, seguido de un operando, el valor expresado por el operando se resta al valor que tiene el acumulador. Esta operación de resta no se realiza para determinar la diferencia exacta entre estos dos valores, sino simplemente para comprobar si son o no iguales, y si no son iguales, para determinar cuál es más grande que el otro. Si el valor del acumulador es igual al valor que se desea comprobar, se activa la bandera cero (Z) del registro de estado del procesador §. Si el valor en el acumulador no es igual al valor que se desea comprobar, la bandera Z quedará desactivada.
Si el valor en el acumulador es menor que el valor a comprobar, entonces la bandera de acarreo © del registro P será desactivada. Y si el valor en el acumulador es mayor o igual al valor a comprobar, entonces la bandera Z se activará y la bandera de acarreo también. CPX y CPY trabajan de la misma manera que CMP, solo que se utilizan para comparar valores con el contenido de los registros X e Y. Producen los mismos efectos que CMP sobre las banderas del registro de estado P.


Uso en conjunto de las instrucciones de comparación y de salto


Las tres instrucciones de comparación del lenguaje ensamblador de Atari se suelen utilizar en conjunto con otras ocho instrucciones – las ocho instrucciones de salto condicional que se mencionaron en el capítulo 6. El programa de ejemplo que hemos denominado The Visitor contiene una instrucción de salto condicional en la línea 210. Esa instrucción es BNE LOOP, que significa "salte a la instrucción cuya etiqueta es LOOP sólo si la bandera cero (del registro de estado del procesador) está activa". Esta instrucción usa una convención un poco confusa del chip 6502. En el registro de estado del procesador 6502, la bandera cero se activa (es igual a 1) si el resultado de la operación que se acaba de realizar es 0, y se desactiva (es igual a 0) si el resultado de la operación que se acaba de realizar es distinto de cero.


En realidad no importa


Todo esto es muy académico, sin embargo, en lo que al resultado de la orden BNE LOOP se refiere. Cuando el computador se encuentre con la línea 210, seguirá saltando de vuelta a la línea 170 (la línea con la etiqueta LOOP), siempre y cuando el valor del registro X no haya disminuído hasta llegar a cero. Una vez que el valor del registro X haya disminuído hasta llegar a cero, la instrucción BNE LOOP en la línea 210 será ignorada, y el programa pasará a la línea 220, que es la línea siguiente. En la línea 220, el programa salta a la subrutina OPNSCR – que actualmente reside en RAM a partir de la dirección de memoria $5041, siempre y cuando el código objeto, tanto de PRNTSC como el de VISITOR, hayan sido cargados en su computador y estén listos para ser ejecutados.


Instrucciones de salto condicional


Como señalamos en el capítulo anterior, en el lenguaje ensamblador del 6502 tenemos ocho instrucciones de salto condicional. Todas comienzan con la letra B, y se les conoce también como instrucciones de direccionamiento relativo o de bifurcación. A continuación se presentan estas 8 instrucciones y su significado:


BCC – “Branch if Carry flag is Clear": Salte sólo si la bandera de acarreo © del registro de estado del procesador § está desactivada. (Si la bandera de acarreo está activada, la operación no tendrá ningún efecto).


BCS – “Branch if Carry flag is Set": Salte sólo si la bandera de acarreo © del registro de estado del procesador § está activada. (Si la bandera de acarreo está desactivada, la operación no tendrá ningún efecto).


BEQ – “Branch if EQual to zero": Salte sólo si el resultado de una operación es igual a cero (Si la bandera cero (Z) fue activada como resultado de una operación).


BMI – “Branch on MInus": Salte sólo si el resultado de una operación es menor que cero (Si la bandera de negativo (N) fue activada como resultado de una operación).


BNE – “Branch if Not Equal to zero": Salte sólo si el resultado de una operación es distinto de cero (Si la bandera de cero (Z) fue desactivada como resultado de una operación).


BPL – “Branch on PLus": Salte sólo si el resultado de una operación es mayor que cero (Si la bandera de negativo (N) fue desactivada como resultado de una operación).


BVC – “Branch if oVerflow flag is Clear": Salte sólo si la bandera de desbordamiento (V) fue desactivada como resultado de una operación.


BVS – “Branch if oVerflow flag is Set": Salte sólo si la bandera de desbordamiento (V) fue activada como resultado de una operación.


Cómo se utilizan las Instrucciones de salto condicional


El método habitual para utilizar una instrucción de salto condicional en el lenguaje ensamblador del 6502 consiste en cargar el registro X o Y con un cero o algún otro valor, y luego cargar en el registro A (o algún otro registro de la memoria) un valor a ser comparado. Una vez comparado, se usa una instrucción de salto condicional para decirle al computador cuál bandera del registro P se debe consultar, y qué hacer si dicha comprobación resulta exitosa o no. Todo esto suena muy complicado, y lo es. Pero una vez que entienda el concepto general de salto condicional, podrá utilizar una tabla simple para escribir instrucciones de salto condicional. Aquí le presento una tabla de este tipo.


PARA COMPROBAR SI :HAGA ESTO :Y LUEGO ESTO OTRO :
A = VALORCMP #VALORBEQ
A <> VALORCMP #VALORBNE
A >= VALORCMP #VALORBCS
A > VALORCMP #VALORBEQ y luego BCS
A < VALORCMP #VALORBCC
A = [DIRECC]CMP $DIRECCBEQ
A <> [DIRECC]CMP $DIRECCBNE
A >= [DIRECC]CMP $DIRECCBCS
A > [DIRECC]CMP $DIRECCBEQ y luego BCS
A < [DIRECC]CMP $DIRECCBCC
X = VALORCPX #VALORBEQ
X <> VALORCPX #VALORBNE
X >= VALORCPX #VALORBCS
X > VALORCPX #VALORBEQ y luego BCS
X < VALORCPX #VALORBCC
X = [DIRECC]CPX $DIRECCBEQ
X <> [DIRECC]CPX $DIRECCBNE
X >= [DIRECC]CPX $DIRECCBCS
X > [DIRECC]CPX $DIRECCBEQ y luego BCS
X < [DIRECC]CPX $DIRECCBCC
Y = VALORCPY #VALORBEQ
Y <> VALORCPY #VALORBNE
Y >= VALORCPY #VALORBCS
Y > VALORCPY #VALORBEQ y luego BCS
Y < VALORCPY #VALORBCC
Y = [DIRECC]CPY $DIRECCBEQ
Y <> [DIRECC]CPY $DIRECCBNE
Y >= [DIRECC]CPY $DIRECCBCS
Y > [DIRECC]CPY $DIRECCBEQ y luego BCS
Y < [DIRECC]CPY $DIRECCBCC

Ciclos en el Lenguaje Ensamblador


En el lenguaje ensamblador del 6502, las instrucciones de comparación y de salto condicional generalmente se utilizan juntas. En el programa de ejemplo llamado The Visitor, la instrucción de comparación CPX y la instrucción de salto BNE se usan juntas en un ciclo controlado por el incremento de un valor en el registro X. Cada vez que el programa pasa por este ciclo, el valor en el registro X es incrementado o disminuido progresivamente. Y cada vez que el programa llega a la línea 200, el valor en el registro X es comparado con el número literal 23. Cuando se llega a ese número, el ciclo termina. El programa por lo tanto seguirá volviendo a la línea 170 hasta que se hayan impreso 23 caracteres en la pantalla. Luego, en las líneas 220 y 230, se abre la pantalla de su computador – limpiándola en el proceso – y se imprime la cadena que se ha transferido en el buffer de texto. Por último, en la línea 240, el programa entrará en lo que se conoce como un bucle de ciclo infinito – saltando una y otra vez a la misma instrucción JMP, sin hacer nada más hasta que se pulsa la tecla BREAK o de alguna otra manera se detiene el programa.


¿Por qué utilizar un buffer?


Antes de pasar a nuestro siguiente tema – mejorar el programa The Visitor – vale la pena responder a una pregunta que se le puede o no haber ocurrido. La pregunta es: ¿Por qué se debe utilizar un buffer de texto? ¿Por qué no imprimir el texto en las líneas de la 100 a 120 directamente en la pantalla, sin tener que primero moverlo a un buffer y luego sacarlo del mismo?
He aquí la respuesta a esa pregunta: El texto de un buffer puede ser cargado de muchas maneras: por medio de un teclado o un módem telefónico, por ejemplo, o con datos entregados directamente por un programa. Y una vez que una cadena de texto está en el buffer, puede ser eliminado de la memoria de diferentes maneras. Otra de las ventajas de un buffer de texto es que puede ser cargado en la memoria RAM, tomar nota de su dirección, y usarlo a partir de entonces cuando lo necesite. Un buffer puede servir como un repositorio central para cadenas texto, al que luego se podrá acceder con gran facilidad y de muchas maneras.


https://www.atariware.cl/archivos/atariroots/ar20.jpg

Mejorando el Programa The Visitor


Ahora estamos listos para hacer algunas mejoras al programa llamado "The Visitor". No es que el programa no funcione, de hecho lo hace, pero tiene ciertas limitaciones. Y algunas de esas limitaciones podrían ser mejoradas fácilmente – como se ha hecho en este nuevo programa, al que he llamado Response.


Response es similar a The Visitor – pero es, como pronto veremos, significativamente mejor en varios aspectos:


RESPONSE

10  ;
20  ; RESPUESTA
30  ;
40  TXTBUF=$5041
50  OPNSCR=$5031
60  PRNTLN=$5031
70  ;
80  EOL=$9b
90  ;
100        *=$650
110 ;
120 TEXT   .BYTE "YO SOY vuestro líder, tonto!",EOL
130 ;
140 RSPONS
150 ;
160        LDX #0
170 LOOP
180        LDA TEXT, X
190        STA TXTBUF, X
200        CMP #$9B
210        BEQ FINI
220        INX
230        JMP LOOP
240 FINI
250        JSR OPNSCR
260        JSR PRNTLN
270 INFIN
280        JMP INFIN	

Si desea ejecutar el programa Response – y espero que lo quiera hacer – puede digitarlo en la memoria de su computador en este momento. Puesto que llama a las mismas subrutinas que su predecesor, puede ensamblarlo y ejecutarlo tan pronto como lo haya digitado, siempre y cuando todavía tenga el programa PRNTSC cargado en la memoria RAM.


Para ejecutar el programa Response, puede llamar a su programa de depuración y usar el comando G, o ir al modo DOS y utilizar el comando de DOS apropiado. Sea cual sea el modo que decida utilizar, será capaz de ejecutar el programa usando la dirección de ejecución $066B, siempre y cuando lo haya digitado y ensamblado de acuerdo con las sugerencias que he proporcionado. Sin embargo, incluso si usted ha seguido las instrucciones, aun así encontraremos un pequeño problema. Sólo los primeros 23 caracteres de la cadena "YO SOY vuestro líder, tonto!" se mostrarán en la pantalla del computador. Esto porque el buffer de texto que hemos creado en el programa PRNTSC tiene sólo 23 caracteres de longitud.
Este error es fácil de remediar. Pero antes de solucionarlo, tal vez sea una buena idea guardar Response en un disco, tanto en sus versiones código fuente y código objeto. Los nombres de archivo sugeridos para el programa son RESPONSE.SRC y RESPONSE.OBJ.


Arreglando el programa PRNTSC


Ahora estamos listos para alargar el buffer de texto utilizado en el programa PRNTSC, por lo que se imprimirá su mensaje completo en la pantalla del computador. Para alargar el buffer de impresión, ponga su ensamblador en modo de edición y cargue el código fuente del programa en la memoria de su computador. Luego cambie la línea 70 de BUFLEN = 23 a BUFLEN = 40. Cuando haya hecho este cambio, puede guardar el código fuente modificado bajo el nombre de archivo PRNTSC.SR2, ensamblarlo, y guardar el código objeto con el nombre de PRNTSC.OB2 (para distinguirlo de PRNTSC.SRC y PRNTSC.OBJ, los programas originales de PRNTSC).


Cuando haya guardado sus programas PRNTSC.SR2 y PRNTSC.OB2, puede volver a cargar el programa Response y ejecutarlo con PRNTSC.OB2 en lugar de PRNTSC.OBJ. Esta vez debería ver la cadena completa que el programa Response presenta en la pantalla de video, pero lamentablemente, ahora se dará cuenta de que otra cosa anda mal. A continuación de la línea "YO SOY vuestro líder, tonto!" verá una línea de pequeños corazones. ¿Cómo llegaron allí? Responderé a esa pregunta en un momento. Pero primero, echemos un vistazo a algunas de las diferencias entre el programa que se llama The Visitor y el que se llama Response.


Una rutina mejor


Desde un punto de vista técnico, el programa Response es mejor que The Visitor – por varias razones. La diferencia más obvia entre ambos programas es la forma en que manejan las cadenas de texto. En el programa llamado The Visitor, se utilizó una cadena de texto compuesta de código ATASCII. En Response, usamos un string compuesto de caracteres literales. Eso hizo que el programa sea mucho más fácil de escribir, y también mucho más fácil de leer.


Otra diferencia importante entre nuestro último programa y su predecesor es la forma en que se escribió el bucle. En el programa llamado The Visitor, el ciclo cuenta el número de caracteres que se han impreso en la pantalla, y termina cuando el conteo llega a 23. Ahora bien, este es un sistema perfectamente correcto – para imprimir cadenas de texto que tienen 23 caracteres de longitud. Desafortunadamente, no es tan apropiado para imprimir cadenas de otras longitudes. Por lo que no es una rutina muy versátil para imprimir caracteres en la pantalla.


Comprobando un Retorno de Carro


El programa Response es mucho más versátil que The Visitor, ya que puede imprimir cadenas de casi cualquier longitud en una pantalla. Esto porque no hace un seguimiento del número de caracteres que se han impreso en la pantalla. En vez de eso, cada vez que el programa encuentra un carácter, comprueba para ver si su valor es $9B – el código ATASCII del retorno de carro, o el carácter de final de línea (EOL). Si el carácter es no es un EOL, el computador lo imprime en la pantalla y pasa al siguiente carácter en la cadena. Si el carácter es un EOL, se imprime en la pantalla y la rutina termina. Y eso es todo – excepto por esos corazones un poco molestos que nos encontramos cuando ejecutamos el programa Response. Ahora vamos a echar otro vistazo a los corazones, y veremos qué podemos hacer al respecto.


https://www.atariware.cl/archivos/atariroots/ar21.jpg

Una Cadena de Corazones


Los corazones están allí porque el buffer de texto que hemos creado para nuestro mensaje de los programas Visitor y Response tiene ahora 40 caracteres de largo – más largo que cualquiera de nuestros mensajes. Y la parte sobrante del buffer está rellena con ceros, tal como generalmente están las posiciones de memoria vacías de un computador. ¿Entonces por qué los corazones? Bueno, en el código de caracteres ATASCII que utiliza su Atari, un cero no equivale a un espacio; en cambio, equivale a un carácter gráfico con forma de corazón. El código ASCII para el espacio es $20, o 32 en la notación decimal. Basta con mirar la cadena de caracteres ASCII en los programas Visitor y Response, y verá que los espacios en el mensaje "LLEVAME CON TU LIDER!" son de hecho representados por el valor $20.


Es posible, por supuesto, imprimir los mensajes en la pantalla de su Atari sin cadenas de corazones a continuación. Lo que tiene que hacer para evitar que aparezcan estos corazones es limpiar su buffer de texto – o, más exactamente, rellenarlo con espacios – antes de que se ejecute el programa.


Limpieza del Buffer de Texto


He aquí una rutina corta que limpiará un buffer de texto – o cualquier otro bloque de memoria – y lo rellenará con espacios, ceros, o cualquier otro valor que usted elija. Mediante la incorporación de esta rutina en nuestros programas The Visitor y Response, puede reemplazar los ceros de sus mensaje que aparecerá en pantalla por espacios ASCII, y hacer que los espacios aparezcan como tales en la pantalla de su computador, en vez de corazones. A medida que siga trabajando con el lenguaje ensamblador, encontrará que las rutinas de borrado de memoria como ésta pueden ser muy útiles en muchos tipos de programas. Procesadores de texto, programas de telecomunicaciones, y muchos tipos de paquetes de software hacen uso extensivo de rutinas que limpian los valores en los bloques de memoria y los reemplazan por otros valores.


PROGRAMA PARA LIMPIAR UN BLOQUE DE MEMORIA

1300 FILL
1310        LDA #FILLCH
1320        LDA #BUFLEN
1330 START
1340        DEX
1350        STA TXTBUF,X
1360        BNE START
1370        RTS	

Este programa es muy sencillo. Usa el direccionamiento indirecto y una cuenta atrás sobre el registro X, para llenar cada dirección de memoria en un buffer de texto (TXTBUF) con un carácter de relleno (FILLCH) determinado. Luego, el programa termina. Esta rutina funciona con cualquier carácter de relleno de 8 bits, y con cualquier longitud de buffer (BUFLEN) de hasta 255 caracteres. Más adelante en este libro encontrará algunas rutinas de 16 bits que pueden rellenar con valores bloques más extensos de memoria RAM. Puede utilizar esta rutina, integrándola en sus programas The Visitor y Response. Agreguémosla a estos dos programas ahora, comenzando con The Visitor. Con su ensamblador en modo de edición, cárguelo desde el disco y agréguele las siguientes líneas:

55   BUFLEN=40
60   FILLCH=$20
150        JSR FILL
1300 FILL
1310       LDA #FILLCH
1320       LDA #BUFLEN
1330 START
1340       DEX
1350       STA TXTBUF,X
1360       BNE START
1370       RTS	

Cuando estos cambios se hayan hecho, su programa VISITOR.SRC debería tener el siguiente aspecto:


THE VISITOR

10   ;
20   ; EL VISITANTE
30   ;
35   TXTBUF=$5041
40   OPNSCR=$5003
50   PRNTLN=$5031
55   BUFLEN=40
60   FILLCH=$20
70   ;
80         *=$600
90   ;
0100 TEXT  .BYTE $4C,$4C,$45,$56,$41,$4D,$45,$20
0110       .BYTE $43,$4F,$4E,$50,$20,$54,$55,$20
0120       .BYTE $4C,$49,$44,$45,$52,$21
0130 ;
0140 VIZTOR
0150       JSR FILL
0160       LDX #0
0170 LOOP  LDA TEXT,X
0180       STA TXTBUF,X
0190       INX 
0200       CPX #23
0210       BNE LOOP
0220       JSR OPNSCR
0230       JSR PRNTLN
0240 INFIN JMP INFIN
1300 FILL
1310       LDA #FILLCH
1320       LDX #BUFLEN
1330 START
1340       DEX
1350       STA TXTBUF,X
1360       BNE START
1370       RTS	

Cuando su programa se vea así, puede guardar en un disco su versión mejorada. Entonces puede hacer exactamente los mismos cambios en su programa Response, y guardarlo también. Cuando haya terminado con el programa Response, debería verse así:


RESPONSE

10   ;
20   ; RESPUESTA
30   ;
40   TXTBUF=$5041
50   OPNSCR=$5031
60    PRNTLN=$5031
65   BUFLEN=40
70   FILLCH=$20
75   ;
80   EOL=$9b
90   ;
100          *=$650
110  ;
120  TEXT    .BYTE "YO SOY vuestro líder, tonto!",EOL
130  ;
140  RSPONS
150  ;
160          LDX #0
170  LOOP
180          LDA TEXT, X
190          STA TXTBUF, X
200          CMP #$9B
210          BEQ FINI
220          INX
230          JMP LOOP
240  FINI
250          JSR OPNSCR
260          JSR PRNTLN
270  INFIN
280          JMP INFIN
1300 FILL
1310         LDA #FILLCH
1320         LDX #BUFLEN
1330 START
1340         DEX
1350         STA TXTBUF,X
1360         BNE START
1370         RTS	

Haciéndolo


Cuando haya guardado de manera segura en un disco ambos programas mejorados – tanto en sus versiones código fuente como código objeto – podrá ejecutarlos y verá que todos nuestros problemas con nuestro buffer de texto se habrán resuelto. Y eso nos lleva a nuestro próximo capítulo, en el que aprenderá a llamar a rutinas de lenguaje ensamblador desde programas en BASIC.