Volver menú revistas Volver página anterior

El Amiga Me Encanta ha conseguido el permiso por escrito de IDG Comunications España para ofrecer los artículos de la revista Amiga World España.


N° 14 - Octubre 1990
Los cuadernos del Ensamblador CAPITULO 1

NOTA: Las fotos con recuadro en azul pueden ser ampliadas para ver detalles. Situando el ratón encima de la foto durante unos instantes, podrás ver una pequeña descripción y lo que ocupa la ampliación.

Por F. Javier Rodríguez

Todo el mundo que
desee programar el
Amiga, debe saber las
estructuras a seguir
en la realización de
ciertas operaciones,
pero primero deberá
conocer
profundamente el
Ensamblador del
68000.

La programación en lenguaje Ensamblador ofrece un gran número de ventajas, así como pequeños inconvenientes. Las ventajas son un mejor conocimiento del ordenador mediante la programación a nivel hardware, una mayor velocidad en la ejecución de los programas así como mejores resultados. Por otro lado los inconvenientes son la gran cantidad de tiempo necesario para la elaboración de un programa, conseguir una buena documentación y que se trate de un lenguaje no estructurado como puede ser el caso del C.

Para poder realizar los listados en ensamblador es necesario poseer un buen MacroEnsamblador, el cual ofrece unas ventajas de programación al usuario suplementarias al propio lenguaje en cuestión. De esta forma se encuentra la posibilidad de poder incluir comentarios explicatorios en los listados 'fuentes' así como el manejo de números en notación decimal, hexadecimal y binario, además de la definición de etiquetas (igual que en los listados generados con el AmigaBasic). Otra de las ventajas que ofrecen los Macroensambladores es la realizaicón de Macros (todas estas características dentro del listado fuente).

Se puede definir una Macro como la realización de una rutina que en vez de repetirse constantemente a lo largo del listado, sólo se encuentre una vez en el código fuente. Haciendo las llamadas oportunas a la rutina, con los registros requeridos, cada vez que sea precisa su ejecución. Este y otro tipo de ayudas extras para el programador en Ensamblador serán explicadas con mayor profundidad a lo largo del curso.

Otro aspecto importante son los diferentes MacroEnsambladores que se pueden encontrar en el mercado, los cuales ofrecen una serie de diferencias entre sí concernientes al modo de utilizar las 'ventajas' anteriormente descritas. En cualquier caso si se realiza un programa cuyo listado sea estrictamente ensamblador, sin la utilización de macros u otras características especiales, la adaptación entre diferentes MacroEnsambladores no ofrecerá ningún tipo de problemas.

Los listados que aparecerán a lo largo del cursillo serán escritos con el MacroEnsamblador DevPac 2, siendo éste quizá el más cómodo de utilizar; pues desde el editor se puede acceder al ensamblador, al debuger o ejecutar el programa creado. Además otra de las características es la rapidez con la que es ensamblado el código fuente (para más referencias sobre este MacroEnsamblador leer el Banco de Pruebas efectuado a este producto prublicado en el número 12).

Para finalizar esta introducción decir que a lo largo de los diferentes capítulos que compondrán este cursillo, aparecerá un glosario con los terminos técnicos empleados.


Estudiando los elementos del Amiga

Como se mencionó al comienzo, la programación en Ensamblador se realiza a nivel Hardware; es decir que se deben conocer todos los elementos sobre los que se puede ejercer control así como las características de los mismos. Sin el conocimiento de estos elementos sería muy difícil realizar una buena programación de los mismos.

Los componentes que se describirán a continuación se corresponden con los del A-500, siendo válidos también para los usurios del Amiga 2000 y el Amiga 1000.

- Procesador Motorola MC68000 de 16/32 bits, a una velocidad de 7,14 MHz.

- Dos interfces serial 8520.

- Tres Custom Chips de Commodore: Paula, Agnes y Denisse. Estos son los encargados del acceso directo a memoria DMA, control de video, gráficos y sonido.

- En cuanto a la memoria el Amiga 500 posee memoria base de 512K RAM asignada como memoria CHIP, así como 512K de ROM. El Amiga 2000 posee por el contrario 1Mb de memoria RAM, dividida en 512K como memoria CHIP y 512K como memoria Fast (en caso de poseer el nuevo Fat Agnus, toda la memoria será direccionada como memoria CHIP).

En cuanto a los interfaces con que vienen equipados los equipos se encuentran los siguientes:

- Puerto Paralelo de impresora.

- Interface RS-232 Serial.

- Conector de video RGB.

- Conector para video compuesto.

- Salida audio Stereo.

- Teclado.

- Conector para unidad externa de disco (compatible con el BUS Shugart).

- Dos conectores para periféricos de entrada, como puede ser un Joystick, Ratón o Paddle.

- Puerto de expansión para conectar sistemas de todo tipo (en caso del Amiga 2000 varios de los sistemas pueden conectarse a los diversos slots que este modelo tiene en su interior.

- La pantalla está compuesta por 625 líneas a una frecuencia de 50 Hz (PAL), soportando un máximo de 6 BitPlanes (planos gráficos), 4096 colores (HAM) y hasta 8 Sprites por línea de barrido.

A continuación se verán más detalladamente las características de los chips más importantes, ya que el conocimiento de éstos proporcionará una mayor compresión a la hora de programar nuestro Amiga en Ensamblador:

- El MC68000 como se dijo anteriormente trabaja a una velocidad de reloj de 7,14 MHz componiéndose de 64 pins o líneas, de las cuales cabe destacar las asignadas al BUS de datos (D0 a D15) y las asignadas al BUS de direcciones (A1 a A23). Con respecto al BUS de datos éste puede leer o escribir una palabra (16 bits/16 líneas) cada vez, mientras que si se trata de un Byte, éste ocupará solamente la mitad de las líneas; en el caso de que el dato sea un byte, el procesador determinará si es de lectura o de escritura dependiendo si ocupa las 8 líneas superiores o las 8 inferiores.

Con respecto al BUS de direcciones éste puede direccionar 16MB es decir 223 (el 2 signífica los dos estados diferentes que puede tener un Bit 0 ó 1 y 23 es el número e líneas), aunque en el caso del Amiga la memoria sólo se puede ampliar hasta 9MB. También hay que considerar el modo DMA de gestión de memoria mediante el cual se puede acceder directamente hasta 1MB de memoria accediendo por el Chip Agnus (si no se posee el nuevo Fat Agnus), esta cantidad se ve reducida a 512K). Dicha memoria recibe el nombre de memoria CHIP, siendo ésta la utilizada para operaciones gráficas así como de audio y de trabajo con periféricos; en resumen aquellos trabajos en los que interviene cualquiera de los Custom Chips.

El procesador también es el encargado de interpretar las señales externas recibidas a través, por ejemplo, de un controlador de disco duro; de este modo si las señales enviadas por el controlador hacia el procesador son las adecuadas, el direccionamiento de memoria pasará de ser controlado por el procesador a ser controlado mediante el sistema DMA.

Otras de las funciones específicas del procesador es el control de reset (mediante dos de sus líneas), por el cual el sistema será inicializado.

- Agnus (Agnus 8361) es uno de los tres chips especiales con los que el Amiga se encuentra equipado (llamados Custom Chips). Este se encarga principalmente de la gestión de memoria cuando se realiza en modo DMA ya que en su interior se encuentra toda la circuiteria de control, por lo que se encuentra directamente conectado con el BUS de direccionamiento. Agnus también es el encargado de generar el refresco de la memoria RAM, necesario en el tipo de Chips dinámicos.

La frecuencia con la que Agnus accede a la memoria es de 255 veces por cada línea de barrido, siendo esta la explicación de que también contega los contadores de posición vertical y horizontal de la línea de barrido, generando al mismo tiempo la señal necesaria para la sincronización de pantalla.

Agnus se encarga del acceso DMA por seis vías distintas, las cuales se encuentran con sus propios circuitos lógico (incluidos en Agnus); dichas causas son las operaciones con el Copper, audio, Sprites, Disco, Bitplane, Blitter (registro de control) y Blitter (registro de datos).

- Paula (Paula 8364) es otro de los llamados Custom Chips, pero su misión es muy distinta a la de Agnus. Este chip en concreto es el encargado de operaciones con los periféricos, los cuales a su vez deben trabajar con memoria CHIP (accedida mediante DMA); para ello Paula posee una línea especial DMAL, mediante la cual genera una señal que es enviada a Agnes cada vez que se hace necesaria la operación mediante DMA.

Además de las operaciones con los periféricos, Paula también es la encargada de gestionar todas las tareas, es decir puede controlar cualquiera de las cuarenta fuentes diferentes de interrupción que se pueden generar debido a diversas fuentes. Cada vez que una interrupcción se genera, la señal correspondiente es enviada al 68000 el cual procesa dichas señal asignándole un nivel. Los concoidos niveles de interrupción del 1 al 6 son generados por el 68000, pero mediante la debida programación de Paula el usuario puede permitir o prohibir cada uno de los 40 diferentes tipos de interrupción.

- Denisse (Denisse 8362) es el tercero y último de los Custom Chips. Este es el chip encargado de la parte gráfica, para ello recbe parte de la información de Agnes (sobre los Sprites) procesando posteriormente Denisse los registros referentes a códigos de color, prioridades y colisión.

Otra de las funciones de Denisse, que no tiene nada que ver con aspectos gráficos, es la de contador en X e Y para la posición del ratón.

- Otro de los elementos fundamentales son las dos CIAs 8520 (Complex Interface Adapter), los usuarios del C-64 recordarán algunos de los servicios que ésta prestaba al sistema. En el caso del Amiga, éstas son las encargadas de controlar los dos puertos paralelo de 8 bits, dos relojes de 16 bits, un puerto serie bidireccional y un controlador de 24 bits programable con función de alarma.

Los registros de control de ambas CIAs se ven reflejados en la memoria a partir de $BFE001 hasta $BFEF01 para la CIA-A y desde $BFD000 hasta $BFDF00) para la CIA-B. La CIA-A es la encargada de reflejar en uno de sus registros (concretamente el $BFEB01) el código de la tecla pulsada, con lo cual mediante la debida programación (en Ensamblador) el teclado puede ser leído sin la necesidad de Handlers ni ventanas; siendo más elegante en algunos tipos de programas.

Notación numérica, dimensión del dato y aritmética lógica

Normalmente en lenguajes como el Basic el programador utiliza la notación decimal es decir la normal, pero a la hora de programar en Ensamblador dicha notación es menos importante que la Hexadecimal o la binaria.

Antes de explicar los diferentes tipos de notación numérica, decir que la unidad mínima de información con la que trabaja un ordenador es el Bit, el cual sólo puede contener dos valores ó 1 ó 0 (encendido/apagado); la agrupación de 8 bits se denomina Byte, la de dieciseis bits o dos Bytes de denomina palabra (Word) y la de 32 bits o dos palabras se llamada DoblePalabra (Long). En los cursillos se hará referencia al tamaño de los datos mediante su notación inglesa.

Cuando el dato se tata de una Palabra, éstas pueden descomponerse en Byte bajo y Byte alto. El Byte bajo se corresponde con los 8 bits inferiores (0-7) y el byte alto con los 8 bits superiores (8-15); el mismo caso sucede con la DoblePalabra, la cual puede dividirse en palabra baja (16 bits inferiores) y palabra alta (16 bits superiores). Para una mayor comprensión decir que los bits se numeran de menor a mayor, comenzando el bit 0 por la derecha y acabando por la izquierda con el bit 15.

La notación Binaria está basada en la potenciación en base dos, así como en el tamaño del dato. Si la longitud del dato es un Byte, será posible representar los números del 0 al 255 (ambos inclusive) ya que esos son los valores que se pueden tomar desde 20 (con todos los bits a 0) hasta 27 + 26 + 25 + 24 + 23 + 22 + 21 21 + 20 = 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255 (con los 8 bits a 1). Por tanto si se desea realizar la conversión de un número binario a decimal tendría que proceder de la siguiente forma:

BIN = 00011101 = 16 + 8 + 4 + 1 = 29 en base decimal.

Como habrá observado sólo se suman los bites que se encuentran a 1; ésta es sin llugar a dudas la forma más rápida y sencilla de averiguar la equivalencia decinamal de un número binario. En caso de que la longitud del dato sea una Palabra, entonces se podría representar los números comprendidos entre 0 y 1024 (1K).

Por otro lado se encuentra la representación numérica en notación Hexadecimal, siendo ésta algo difícil de entender ya que se trata de una mezcla entre números y letras. La representación decimal se encuentra realizada en base 10, mientras que la Hexadecimal se encuentra representada en bae 15. La definición de los números se encuentra representada de 0 a 9 (para los 10 primeros números) y desde la A hasta la F para los números comprendidos del 10 al 15 (ambos inclusive).

El
Amiga 500
posee memoria
base de 512K
RAM asignada
como memoria CHIP.

En el caso de la notación decimal, ésta cambia de decena cada vez que la unidad llega a nueve; en el caso de la notación Hexadecinal el cambio de la decena se produce cada vez que la unidad llega a 15 (es decir F). De esta forma la representación del número 32 en cada una de las diveras notaciones sería como se indica a continuación:

Decimal = 32.
Binario = 00100000.
Hexadecimal = 20.

Para diferenciar la notación en la que se encuentra escrita la cifra, el ensamblador utiliza símbolos especiales, de esta forma si delante de la cifra se encuentra el símbolo '%' se tratará de un número binario, si se trata del símbolo '#$' querrá decir que es una cifra Hexadecimal y si no se encentra ningún símbolo antepuesto al número, entonces será un número decimal. Observe la sintaxis final de cada una de las diferentes notaciones:

Decimal = 15.
Binario = %00001111.
Hexadecimal = #$0F.

Como punto final veremos el método para realizar la conversión de un número binario al correspondiente en Hexadecimal. En primer lugar decir que el Byte puede ser dividido en dos partes llamada Nibble, las cuales se compone cada una de 4 Bits; una vez aclarado este punto pasaremos a explicar la conversión.

Para realizar la conversión es necesario tomar el Byte como dos partes es decir como dos Nibbles. Los cuatro bits superiores formarán las decenas del número Hexadecimal, y los cuatro bits inferiores (Nibble inferior) formarán las unidades del número.

Número Binario = %00111111.
NIbble superior = %0011.
Nibble inferior = %1111.

Ahora se calculará el equivalente de cada una de las partes, tomando las dos como Nibbles inferiores:

%0011 = 3.
%1111 = 15 = F.

Por tanto el número que corresponde en notación Hexadecimal es #$3F.

Una vez que ya vistas las diferentes formas de representar los números, seguiremos con un apartado muy importante; la aritmética lógica. En la programación Ensamblador la mayoría de las operaciones que se realizan son a nivel lógico, ya se trate de bits bytes palabras o doble palabra.

El dominio de la aritmética lógica es en cierto modo más importante que el conocimiento de todas las instrucciones que posee el 68000; ya que éstas pueden ser miradas en algún libro, sin embargo si no se posee un buen conocimiento de los operadores lógicos la tarea será muy dificultosa.

La lógica se encuentra estrechamente relacionada con los elementos binarios, ya que ésta se corresponde con el tipo de respuestas verdadero/falso. En la lógica binaria se asocia el concepto de verdadero a 1 y de falso a 0. El set de instrucciones del 68000 posee varias operaciones del tipo lógica, pero las tres fundamentales son el AND (y) OR (o) y NOT (no); de esta forma se pueden crear la tabla llamada de verdad lógica con el operando lógico OR:

En el caso de la operación NOT, ésta sólo tiene dos posibilidades ya que es la negación del elemento; de esta forma NOT 1 será igual a 0 y NOT 0 será 1 (complemento de 1 y complemento de 0 respectivamente).

La lógica en la programación como se dijo anteriormente, es de suma importante ya que en algunas partes del programa ésta puede realizar algún tipo de comparación entre dos elementos para decidir hacia qué rutina se debe bifurcar. De hecho en la mayoría de los programas se realizan comparaciones con la comprobación del ratón, la respuesta dada a un INPUT u otros elementos.

La lógica permite una mayor velocidad y sencillez en la realización de un programa, ya que con una buena estructura del mismo se evitarán partes de rutinas innecesarias.

Lógica
Falso OR Falso = Falso
Cierto OR Cierto = Cierto
Falso OR Cierto = Cierto
Cierto OR Cierto = Cierto

Binaria
0 OR 0 = 0
1 OR 1 = 1
0 OR 1 = 1
1 OR 0 = 1

Por otro lado mediante las instrucciones de carácter lógico se pueden realizar infinidad de ¡efectos especiales' con los gráficos generados por el Amiga, así como operaciones de relleno ('Fill'), máscaras, así como generar claves o encriptados de datos.

Para
diferenciar la
notación en la
que se
encuentra
escrita la cifra,
el ensamblador
utiliza símbolos
especiales.

En el próximo capítulo se verán las diferentes instrucciones además de las ya vistas, de carácter lógico, que incluye el set de instrucciones Ensamblador del 68000; así como sus modos de operación y características.

También se explicarán con detalle los distintos registros del procesador y de usuario, el concepto de Pila y de contador de programa, además de realizar una pequeña introducción dentro de la programación en Ensamblador con cortas rutinas explicatorias.

Para ello se comenzarán a ver algunas de las instrucciones Ensamblador (llamadas Mnemotécnicos) del Amiga más utilizadas y sencillas, así como modos de operación y registro afectados (conceptos éstos que también se explicarán).

Otra de las características que deberá explorar a fondo es el manejo del programa MacroEnsamblador que posea, ya que deberá conocer en profundidad todas las operaciones que con éste puede realizar y de ésta forma sacar el mayor partido posible al trabajo realizado con dicho paquete. Esto repercutirá en un menor esfuerzo a la hora de programar.


Volver menú revistas Volver página anterior