Proyecto para Software de Base

El objetivo del proyecto es el de escribir un ensamblador y un cargador simples para el microprocesador 6502 de 8 bits. El ensamblador se irá construyendo en diversas etapas. Cada etapa estará especificada en esta página y tendrá una fecha de entrega. La evaluación de la etapa se hará en base a que lo entregado satisfaga exactamente las especificaciones requeridas, es decir, ni más ni menos. Finalmente, cada una de las etapas tendrá un valor que será anunciado junto con la especificación.

Primera etapa: Convertidor de archivo binario a formato objeto hexadecimal : 10 puntos : 23 de febrero de 2007.

Deberán escribir un programa llamado bintohex.c o bintohex.cpp o bintohex.java que transforme un archivo binario en un archivo de código objeto. El código objeto tiene dos tipos de registros: el registro de datos y el registro de fin. El registro de datos tiene el siguiente formato: su primer caracter es una 'D', los siguientes cuatro caracteres son la dirección de inicio del código objeto en este registro escritos en hexadecimal, los siguientes dos caracteres son la longitud L en bytes del código objeto de este registro escritos en hexadecimal (los valores válidos son de 0x01 a 0xFF), los siguientes 2L caracteres son el código objeto en este registro, dos caracteres por byte y escritos en hexadecimal y termina con un caracter de nueva lí­nea '\n'. El registro de fin tiene el siguiente formato: su primer caracter es una 'F', los siguientes cuatro caracteres son el número total de bytes almacenados en todos los registros de datos y termina con un caracter de nueva lí­nea '\n'. El programa bintohex deberá recibir dos parámetros en la lí­nea de instrucciones: fuente y destino (en ese orden), donde fuente es el nombre de un archivo binario existente y destino es el nombre del archivo donde se escribirá el archivo en hexadecimal. Además, podrá recibir un tercer parámetro opcional desplazamiento (que será la dirección de inicio del primer byte del archivo fuente y cuyo valor por omisión será 0x0000) y un cuarto parámetro opcional longitud (cuyo valor por omisión es 0x20). El desplazamiento y la longitud podrán aparecer escritos en binario, cuaternario, octal, decimal o hexadecimal en los formatos descritos en la tarea 1. Si no se dan dos parámetros el programa deberá imprimir en stderr el mensaje "uso: bintohex fuente destino [desplazamiento] [longitud]" y terminar. Si el archivo fuente no existe deberá imprimir en stderr el mensaje "error: el archivo fuente no existe" y terminar. Si el archivo destino no se puede crear deberá imprimir en stderr el mensaje "error: el archivo destino no se puede crear" y terminar. Si el desplazamiento no está en el rango 0x0000 a 0xFFFF o está en formato equivocado deberá imprimir en stderr el mensaje "error: desplazamiento ilegal" y terminar. Si la longitud no está en el rango 0x01 a 0xff o está en formato equivocado deberá imprimir en stderr el mensaje "error: longitud ilegal" y terminar. Si no ocurrió ninguno de estos errores, entonces su programa deberá comenzar a leer bytes del archivo fuente  y a escribir registros de datos en el archivo destino. Cada registro de datos debe ser tan largo como sea posible según el valor de longitud (es decir, sólo el último registro de datos puede medir menos que longitud). Al terminar de leer los datos de fuente se deberá escribir un registro de fin de archivo en destino. Si ocurrió algún error al escribir al archivo destino se deberá imprimir en stderr el mensaje "error: no se puede escribir en destino" y terminar. Si todo salió bien, el programa deberá terminar sin emitir ningún mensaje. Ejemplo: Supongamos que quieren ejecutar el programa bintohex con el archivo fuente entrada.txt, el archivo destino salida.txt, el desplazamiento 0x1000 (en hexadecimal) y la longitud 0d10 (en decimal) entonces la lí­nea de instrucción deberá ser bintohex entrada.txt salida.txt 0x1000 0d10 después de lo cual el archivo destino deberá contener salida.txt. Nota 1: Para ver cómo se le pueden enviar parámetros a un programa en la lí­nea de instrucciones consulte la sección 5.10 del libro El lenguaje de programación C (Segunda edición) de Kernighan y Ritchie. Aquí­ hay un ejemplo. Nota 2: Si las direcciones llegaran a sobrepasar el valor 0xFFFF entonces continuarán en la dirección 0x0000. De la misma forma, el número almacenado en el registro de fin se deberá guardar módulo 65536.

Segunda etapa: Ensamblador simple de un paso : 10 puntos : 9 de marzo de 2007.

Deberán escribir un programa llamado unpaso.c o unpaso.cpp o unpaso.java que lea un código fuente en ensamblador y escriba el código objeto correspondiente. En esta etapa del proyecto sólo se considerarán los modos de direccionamiento inmediato, página cero, absoluto, acumulador e implícito del 6502 (los cuales están abreviados como IMM, Z.PAGE, ABS, ACCUM e IMPLIED en la tabla de nemónicos del 6502). El programa unpaso recibirá dos parámetros fuente y objeto en la línea de instrucción, donde fuente es el nombre del archivo de texto que contiene el código fuente y objeto es el nombre del archivo de texto donde se escribirá el código objeto. El código fuente consistirá de una sucesión de líneas de texto y terminará con el fin de archivo. Cada línea de texto podrá (1) estar en blanco (los caracteres definidos por isspace), (2) contener además de blancos un nemónico, (3) contener además de blancos un nemónico separado por blancos de su parámetro numérico, (4) contener además de blancos la directiva INI separada por blancos de su parámetro numérico, (5) contener además de blancos la directiva COM separada por blancos de su parámetro alfanumérico, (6) contener además de blancos la directiva FIN. Los nemónicos se obtendrán de los mostrados en la 6502 PDF wall chart de la siguiente manera:
Los nemónicos deberán estar contenidos en una tabla de dispersión como la de la tarea 2. Los parámetros numéricos podrán aparecer escritos en binario, cuaternario, octal, decimal o hexadecimal como en los formatos descritos en la tarea 1. Observe que algunos nemónicos tomarán un parámetro de 8 bits (direccionamientos inmediato y página cero) mientras que otros tomarán un parámetro de 16 bits (direccionamiento absoluto). En este último caso primero se almacenan los 8 bits bajos y luego los 8 bits altos. El parámetro de la directiva INI es la dirección de la siguiente instrucción en el código fuente por lo que es de 16 bits. Si la primera instrucción del código fuente no va precedida de una directiva INI se debe suponer que tiene la dirección 0. El parámetro de la directiva COM es un comentario y por lo tanto deberá de ser ignorado. La directiva FIN indica que el código fuente ha terminado y que las siguientes líneas deben de ser ignoradas. Su programa deberá detectar los siguientes tipos de errores, los cuales deberá señalar en el error estándar (stderr) junto con el número de la línea fuente donde ocurren: (1) instrucción desconocida, (2) falta parámetro, (3) sobra parámetro, (4) parámetro fuera de rango, (5) parámetro sin instrucción y (6) formato desconocido de parámetro. Su programa deberá terminar en cuanto se lea la directiva FIN o se detecte el fin de archivo o el primer error. Las líneas que contienen nemónicos y que no contienen errores generarán código objeto. Cada registro de datos del código objeto será tan largo como sea posible pero nunca deberá tener una longitud mayor a 0x20 (que era el valor por omisión en la primera etapa del proyecto). Cuando se detecte un error se deberá imprimir en stderr la cadena "ERROR: ", seguida del número de línea donde ocurrió el error y seguida de una de las cadenas " INSTRUCCION", " FALTA", " SOBRA", " RANGO", " PARAMETRO" o " FORMATO" según el tipo de error. Abajo encontrará un ejemplo del funcionamiento de este programa.

Código fuente
Código objeto
Error estandar
 COM dir=0000
LDA  0x123
INI 0x1000
 LDAI  0d12
LDAI 0b0
COM Otra vez CAMBIA
INI 0x2000
LDAZ 0b010101
FIN
Esto ya NO lo lee
D000003ad2301
D100004a90ca900
D200002a515
F0009


LLL 0x123
LDA
BRK 0d12
LDAI 0d300
0x123
LDA 123

ERROR: 1 INSTRUCCION
ERROR: 2 FALTA
ERROR: 3 SOBRA
ERROR: 4 RANGO
ERROR: 5 PARAMETRO
ERROR: 6 FORMATO

Tercera etapa: Ensamblador de un paso con etiquetas : 10 puntos : 23 de marzo de 2007.

Deberán escribir un programa llamado etiqueta.c o etiqueta.cpp o etiqueta.java que lea un código fuente en ensamblador y escriba el código objeto correspondiente. En esta etapa del proyecto se deberán considerar los modos de direccionamiento indexado e indirecto del 6502 (los cuales están abreviados como Z.PAGE,X, ABS,X, ABS,Y, (IND,X), (IND),Y, Z.PAGE,Y e INDIRECT en la tabla de nemónicos del 6502) además de los modos ya considerados en la segunda etapa. El programa etiqueta recibirá dos parámetros fuente y objeto en la línea de instrucción, donde fuente es el nombre del archivo de texto que contiene el código fuente y objeto es el nombre del archivo de texto donde se escribirá el código objeto. El código fuente consistirá de una sucesión de líneas de texto y terminará con el fin de archivo. Cada línea de texto podrá (1) estar en blanco (los caracteres definidos por isspace), (2) contener además de blancos un nemónico, (3) contener además de blancos un nemónico separado por blancos de su parámetro numérico, (4) contener además de blancos la directiva DATO seguida de sus parámetros numéricos separados por blancos, (5) en los tres casos anteriores podrá contener una etiqueta antes del nemónico o directiva separada por blancos, (6) contener además de blancos la directiva INI separada por blancos de su parámetro numérico, (7) contener además de blancos la directiva COM separada por blancos de su parámetro alfanumérico, (8) contener además de blancos una etiqueta separada por blancos de la directiva DEF separada por blancos de un parámetro numérico, (9) contener además de blancos la directiva FIN. Los nemónicos se obtendrán de los mostrados en la 6502 PDF wall chart de la siguiente manera:
Los nemónicos deberán estar contenidos en una tabla de dispersión como la de la tarea 2. Los parámetros numéricos podrán ser etiquetas definidas previamente (ya sea en una línea que contiene un nemónico o alguna de las directivas DATO o DEF) o aparecer escritos en binario, cuaternario, octal, decimal o hexadecimal como en los formatos descritos en la tarea 1. Note que los nemónicos y las directivas van en mayúsculas pero las etiquetas van en minúsculas. Observe que algunos nemónicos tomarán un parámetro de 8 bits (direccionamientos inmediato, página cero, indexado por X indirecto e indirecto indexado por Y) mientras que otros tomarán un parámetro de 16 bits (direccionamientos absoluto e indirecto). En este último caso primero se almacenan los 8 bits bajos y luego los 8 bits altos. El primer parámetro numérico (de 8 bits) de la directiva DATO es el número de bytes que se colocarán en el código objeto y su valor indica cuántos parámetros numéricos adicionales (de 8 bits) tiene la directiva y que deberán colocarse en el código objeto en ese orden. El parámetro numérico de la directiva DEF es el valor que se le asignará a la etiqueta a su izquierda. Además de los errores detectados en la segunda etapa del proyecto, se deberán detectar los siguientes tipos de errores: (7) si una etiqueta aparece dos veces en el lado izquierdo de una línea se está redefiniendo un símbolo, (8) si una etiqueta que no ha sido definida previamente aparece como parámetro numérico entonces es un símbolo no definido. Su programa deberá terminar en cuanto se lea la directiva FIN o se detecte el fin de archivo o el primer error. Las líneas que contienen nemónicos o la directiva DATO y que no contienen errores generarán código objeto. Cada registro de datos del código objeto será tan largo como sea posible pero nunca deberá tener una longitud mayor a 0x20 (que era el valor por omisión en la primera etapa del proyecto). Cuando se detecte un error se deberá imprimir en stderr la cadena "ERROR: ", seguida del número de línea donde ocurrió el error y seguida de una de las cadenas " INSTRUCCION", " FALTA", " SOBRA", " RANGO", " PARAMETRO", " FORMATO", " CONOCIDO" o " DESCONOCIDO" según el tipo de error. Nota: Puede suponer que las etiquetas miden un máximo de 8 caracteres.

Cuarta etapa: Ensamblador de dos pasos : 20 puntos : 4 de abril de 2007.

Deberán escribir un programa llamado dospasos.c o dospasos.cpp o dospasos.java que lea un código fuente en ensamblador y escriba el código objeto correspondiente. En esta etapa del proyecto se deberán considerar el modo de direccionamiento relativo del 6502 (abreviado como REL en la tabla de nemónicos del 6502) además de los modos ya considerados en la tercera etapa. El programa dospasos recibirá dos parámetros fuente y objeto en la línea de instrucción, donde fuente es el nombre del archivo de texto que contiene el código fuente y objeto es el nombre del archivo de texto donde se escribirá el código objeto. El código fuente consistirá de una sucesión de líneas de texto y terminará con el fin de archivo. Cada línea de texto podrá ser como en los 9 casos de la tercera etapa del proyecto o bien (10) contener además de blancos la directiva RES separada por blancos de un parámetro numérico. La directiva RES puede estar separada por blancos de una etiqueta. Los nemónicos de las instrucciones relativas se tomarán sin cambios de los mostrados en la 6502 PDF wall chart. Los nemónicos deberán estar contenidos en una tabla de dispersión como la de la tarea 2. Los parámetros numéricos podrán ser etiquetas (referencias hacia adelante o hacia atrás o definidas con alguna de las directivas DATO o DEF) o aparecer escritos en binario, cuaternario, octal, decimal o hexadecimal como en los formatos descritos en la tarea 1. Las instrucciones de direccionamiento relativo tomarán un parámetro de 16 bits pero sólo generarán en el código objeto una dirección relativa de 8 bits con signo (en complemento a 2) calculada de la siguiente forma: se calcula la resta (parámetro de 16 bits) menos (contador de localidades actual + 2) y ese valor debe de estar en el rango -128 a 127. El parámetro numérico de la directiva RES es un número de 16 bits que se le sumará al valor actual del contador de localidades, por lo que el efecto de esta directiva es el de reservar la cantidad especificada de bytes. Observe que esta directiva no genera código objeto: el registro de texto actual debe terminar de procesarse y comenzarse uno nuevo a partir de la nueva dirección recién calculada. Respecto a las etiquetas, el último tipo de error cambia a (8) si una etiqueta que no ha sido definida en ninguna parte del código fuente aparece como parámetro numérico entonces es un símbolo no definido. Su programa deberá terminar en cuanto se lea la directiva FIN o se detecte el fin de archivo o el primer error. Las líneas que contienen nemónicos o la directiva DATO y que no contienen errores generarán código objeto. Cada registro de datos del código objeto será tan largo como sea posible pero nunca deberá tener una longitud mayor a 0x20 (que era el valor por omisión en la primera etapa del proyecto). Cuando se detecte un error se deberá imprimir en stderr la cadena "ERROR: ", seguida del número de línea donde ocurrió el error y seguida de una de las cadenas " INSTRUCCION", " FALTA", " SOBRA", " RANGO", " PARAMETRO", " FORMATO", " CONOCIDO" o " DESCONOCIDO" según el tipo de error.